This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 3.x development tree".
The branch, master has been updated via fe38a4b7c5a90f89a377209af6ffd19998102d5e (commit) via b7858a49d0c4cb2b0c68b5e941cc40939a47db74 (commit) via 26ab5a3c2b77858b1bb695b1e9c380d7b5082a3b (commit) via 7c977bb047224fb81c164267714b931dfc15ba86 (commit) via b977ba1f15476eae1fc0a637e415b7d1a045dda2 (commit) via 401c9acac5b9a5c505685096f85f768cae825e92 (commit) via e7a5bed3d672fca3f7042af072b0876bf8adc4c1 (commit) via 85a21f2751a8f1819e89f5f8f19b61d97bbbf71c (commit) via 161a772ff83ba0ac89b9487410d4cfd5c61a118c (commit) via 0b1b2cc268c75c3167bc55ce68d1569fd838419e (commit) via 5d5679bd75cd5e384772d0f4129919c4d0ee2288 (commit) via c703f12341b1d2d6c1f605d7199e548c0aae4af0 (commit) via a73dacebc30e2aa1d698ff98c0b066197403ffba (commit) via 35ff2f2b4747ee8f49f5b5c1c893d8d0876aed93 (commit) via e9601e77ba00769bdccd651c65a82cd5cd678201 (commit) via b63236cf64038e77b51f382beebc7bcba647b94e (commit) via 1f452deaaf79a0f4d2332ed7df7b00835ea01c4b (commit) via aea407d9ad4bbd5a1422f0b04eab280cb04da7a9 (commit) via aac4e9830e709b43d4b831791b248e0b008931b3 (commit) via 8d6aacf72578b143b169b926aa610c5961e38e38 (commit) via a9e614fcb6d22bc44ed546a8c0af3bd3d9652f4f (commit) via bdbc504dda9e441477d38d524ed96ffb896fbd38 (commit) via 942fcd72d2786acc120d29aa838f91de5806c9de (commit) via fc1e0b3f9ff3ba6bb7f42d05baec195e826562f7 (commit) via 127e403c391230c5c7521df817a96b2fa002ac34 (commit) via 976a11de6c049f30ac79846d33481959de9b0877 (commit) via ae1ca48d06edd3b327f4642468aea1fad49331f2 (commit) via bebe2200879adf63be619585a54201692ee4cd2f (commit) via 1bf02c8acc274939bbd92306472f728a8aa08703 (commit) via 21aee8f3e4f1035478607c9e936149c6c1f9d2ae (commit) via 03778dc104d64bd4aa24e428cc5abf302a8311cf (commit) via f3ebebfe015940cd0e7edadd4a51eb8f6cdc56d9 (commit) via 9f1e3542769ef2341c0894a0f2f4b3dec71c7bb7 (commit) via f37bf989c51a8d7da9e81f06584b57b528a678d5 (commit) via c3b2a3a442ee413fcd60b316ef5473a080e72dd1 (commit) via d9befb1f069508c627123644968371f53da65201 (commit) via 16936334406a4f0358f10ecaf9b2726a6bce07e0 (commit) via 75bd2cbf43561afc611be06c12b8b523637e7534 (commit) via 57226a8f5f4a9a55ba9a04a244a24bc8860280a1 (commit) via d7433b7e53a8b3df6fe40054e3ad9cfac3683b7c (commit) via 910997a08fd1023b44958d99da5bd82ea120e301 (commit) via 85e9e99085c700fe4a32ea59a32c0287a65dbbd7 (commit) via 94e0eb46449405853cf50faa51741b5532db9337 (commit) via 76023cc05a69562f9ef2861ebc972364fcc3bda9 (commit) via 4381818d4d698b73b45c6edc81f2c32db01e81ad (commit) via a024bc61ca1349e05cc5cbf857ccfd7fb5ef40c1 (commit) via 81af952ef2e894bbb96649d6000b5c851825e2ca (commit) via e260e2422ed6431585d8a223329e29f7eca15f11 (commit) via 9f8135c73519dc877097a01ce31ce410f38c3fdb (commit) via 430f1d02fa621cc885c2b70cefd6aef679167fb4 (commit) via bf2d899a7a1b4d58adf806b4e4ff277feffa5c4b (commit) via fb9738fe5642f09c3b250a364aa126728f52d95e (commit) via 2a790f511725486aa03c54acc694db70a44e5fe8 (commit) via 42ce981f9390c6b1076fa781af6336d712cc94fc (commit) via 5b54ea9f05d7519611f7399ba5c7aad2a4fa6b9d (commit) via d23e08294149059757b47c0cb5c7c6af0e50d51e (commit) via f9a74df45be14d3ec4a997afdfbd06a6c72287b5 (commit) via 9dfd48068d555720ead8b447eb6425dc84d7abf2 (commit) via 0d6bdf9bc1b46f7584f1f926e43b7bab97729298 (commit) via 1dc517d618ff8a3798ec3d4002b0e7bfc5b00ad4 (commit) via 55a50755fbf6fd6425b1087997f79a2d81163536 (commit) via 9070a9f41c2df70a4f0b8ccc5c9a8e60be04a6e0 (commit) via 525c09ea79b60d828e5a986ad54ffe18388edea4 (commit) via 5970f16f3f8250e8c95cc770e7eb115dad69e6dd (commit) via f46ca8944b14901fe44806f4bd93a15dc6d7785b (commit) via 5f50ae7beb36c4900ed12fdcee61e86307873593 (commit) via 1bc7f3ba3f1e1a1c0540dba22d038cb8fc7a0777 (commit) via 60d42395c1db3c38935df714111506462c065ae8 (commit) via 1f429f675850c6a37281fc8348a91b8b29cde097 (commit) via cabd7933b5087c1a95431963dfd9afcb38d83a3f (commit) via 34daba8691df8a675c8c5f1ec999496f1c44c97d (commit) via 2a9df94ecfb4d8cc2e15c788f3d8becdbe659d34 (commit) via 6e9d53126ca7bbfccf1831614a6069233401e1ba (commit) via 2c4841a58fde518b29dc10263a49f712c462f70b (commit) via e30dbe94a1f0526a8a087f890b396d96f6b3159e (commit) via 4a45d50985ffab1254f51485854556411da7c813 (commit) via 0dcec9e0831dc55894ebf7b5a7f5b6c11cd00749 (commit) via 678c819457f03f254611e0f863afd679c80af3c6 (commit) via 8d889dd021cf49550c377be0763f352bd6435a9e (commit) via c017f784e762a1bb0fa733319193b21e92bb5b6a (commit) via 237756286c6c5676486e5e8082ea23b2d52ef0ac (commit) via f5b416065b77b821c92b2ecd42241e38cfbc6249 (commit) via 892f578304a1c5a639143c47928b72854ddc70a7 (commit) via a3869d0f0d90c06d2910a77ae54729d37ce006d7 (commit) via ebc11a869eeaf8ea0b9c4af52924b286314ace35 (commit) via 68477864eba24cd9bf78160f42f2e6e8363a5ab9 (commit) via 2ee4ca99a19481d9cdbf7a25921c965db0d09709 (commit) via 8c1d1acbc70f23b5e5eeca6efb99c332139fc0a7 (commit) via fc65a79ef6bbe418433cbb17285ac8dd26fd3e22 (commit) via fb7def71724b5a0af976cff8111200a40ee364b3 (commit) via 66ded0eb6f3a66abc80efc45cb2461ece3275161 (commit) via 461f48a7c86f94fdd2f4108305d6e46c6c36ab3d (commit) via 6d098e9c4bd8f5a63ee0a8dd6f3e79f1aaee64ec (commit) via c1c8b40432f38e1beef7988f53250e63d2722d71 (commit) via 48234d2448557b427dfc8ac4d3cfce9630e23fee (commit) via 7b29fb2f2451954236e8fbc69bdbcb2cace626dd (commit) via b65c4912863b7ec9a3abb303dd2b2a5282d338ad (commit) via fae6703dcfd0fba4e4c953c08581e22f6658bb72 (commit) via 0bcd6c9992d11c45b91cd989fb44aafe6f1a7204 (commit) via 0eadabd07124e5562eeaba5ef1a0048f1b894dca (commit) via 14e6100b7838ef71caac0f748a71158a7c429039 (commit) via 60c92791279deecc04fc54cf68e06421b0cc0475 (commit) via cec39ce3b877d385093822e36452fe2edfdf10bd (commit) via 22285c944aabb20ff4c8ac596ca1537478dd9d9b (commit) via dac29d77336a26eb310da6cacbf0f211417e1b8c (commit) via ed0a9fda0db00b781e5bd2dc36b15208271b3857 (commit) via 241e0cfde0ead12c97ab8df4c94635e967ba3635 (commit) via d78ec79ab3f2c2243199bbb8f962cf3e80fe62e6 (commit) via ba3c15c901120c1cdb9523216680dd176863fca2 (commit) via 5587426c078a563572d4a078a61664d03b486cdf (commit) via 2116f967036c0c1f79c69a64b06d21aea0b19207 (commit) via 1d468e768f82a91628c94ce46abefd47bf09fc76 (commit) via d4e4e4b18e547c0db53b9b587d33ecc3b6f4f1de (commit) via 7557e9f24aafd5f0f2c433843cdc4b370052058c (commit) via ea140a2a01e21e120f6bfca42a1206d5ae020d6c (commit) via ffbb7ca2d499e95e0b211a768af50050fbe9da60 (commit) via 8a0917c35b082369ec572722f491e4c5489737f0 (commit) via a64c75a4300e2412ba22141cb26bf017f0fd44f9 (commit) via 0fa27ae910bf441478aff8b1eeb7b63ea6920e22 (commit) via 3b878b6f116bd7f25195f858d9cdf8bcebe7ecf2 (commit) via c588ad689b9a9c923525833618de2cb3be8a9a87 (commit) via d073964651030bad1bc1308fb1b14012962f45e5 (commit) via 32a01e650f49bca3ba97195eaffe616c330e06e2 (commit) via 9d7998925e9c4d5312db700290743e171f758f88 (commit) via 2d62f69d3dd0a37a8d5771ab50dfac3370416aed (commit) via 90cab50b2d37963aa47e547bb5fe384d7cdc6dc3 (commit) via ce85b8d93cf0c5549ec61d93c05b71bef3b16784 (commit) via 4327af914d52573f26cbbb042290b465fbd8df7a (commit) via 901bccc8929187c94187ee26b9e63b4a10f575ae (commit) via f464ef1e4437dbb8e056db9b68157b2e38ebe5dd (commit) via 84a43fb51c19b3a09c11b61937f8ec77fa40e033 (commit) via 470c9b835a13cce9934b8636a9cbef9f193666f7 (commit) via c8f03aea8fcf1eae7134c2da86a5502b3174086c (commit) via e1b6e1531489b61ae4bee2386e387c57537682a8 (commit) via c2df8053ef715f05b8a046a0f82cc56f5f669e01 (commit) via c60fff478975d21da1cc27fc995eea674807bc97 (commit) via 75216add761c0f7e055010f351fe0fc00d091e3b (commit) via 18db5d939bd7a3e1be4299f3fae3b4661aa37355 (commit) via 294f5bb0c451732883b20d43911182869bae6e7a (commit) via dc588ad3f91682346f1d308926327468f6f75630 (commit) via 2daaede6a682564d414725f781ab1255ed73a08c (commit) via 4f9dda45a472659446dfda842e61cf748eeedc4f (commit) via 722abfbca88e5686fdf4b794a2f18ade0c194473 (commit) via 51e30c0ae314a2d3d913fdb694e42681cd16043f (commit) via f4413fdffaabed46c4da766cf29f305c4249d7fe (commit) via 0b7a0ec77a21d4ea54676ba243d5da73f1f632f5 (commit) via 86f7e98fab829422f945886ab6915a5617763064 (commit) via 9e52f66d486c816a071a90ba48590d380b7c1353 (commit) via 7e9ae04a9676c05d876b9ca0559e0b720b9eb919 (commit) via b628bc33791e72925cab715a03a99f0a63336ca2 (commit) via 18ca76c18d58e4b8037a9d8e0631e1273f3a3b44 (commit) via a3c2fdf5442a940110006b34368651451ccf305b (commit) via c1e16ca66dd1f6627091f9919ae7ae0df2d59a0f (commit) via c7d282dcfd60b1151f2b515b191287bef0446ab8 (commit) via 1498748819f96cf68d3b6359f790d78e34b89f02 (commit) via cc0e4a4acb8c8b6bed60c2537a9d8fc23fb72413 (commit) via 33df142fd42a6a3be2825939e77dd08df7350346 (commit) via 6fdd3c6388f843690ff0992e1227871a64663af2 (commit) via 38a7b64b0a14b51325d51954bf7a3925dd675049 (commit) via 4c501a6f7310ca7124017bf7b4d328ce2d273eee (commit) via 597ba387ce190df24c7aab2bcf66841acc1deaf4 (commit) via 14c0f5dd3f78ff72c81d051b4f8bf9eb01b22885 (commit) via 2ea6a5944040fa7856511905b4b0e7aad0c76525 (commit) via bceb6c91c36c7bc66b58700cb66e35c5d40a2dd3 (commit) via 9f4ef23fd26d310da35ccf748f84aad750ed7c17 (commit) via 237315cac2d6e77ad77355836a1f7c066bb71c81 (commit) via 81e96b7c36786a33d681f1242feea6d671deb679 (commit) via 3aa03c472553671b9d632cbade209b0e49b1f052 (commit) via 54b6d563b879f07bbd159379a37f7d8e0f89394e (commit) via ad426e8e9b3c8f19a7513757744e0afb6f9a4e33 (commit) via ca8785f6e29ad1d6f2a76144ea6292ef144ef969 (commit) via f99a3eb0ee4a93426b63b5cd9b80719f481aac10 (commit) via e8e5f77f520b089d19c8e7d939a94bcd6b4db555 (commit) via 884726f22e1f0238c87d847dc582b5dbd8554580 (commit) via 69d64e398bc12ac7d36866aaed486f26a4f4fd40 (commit) via b2192287dae595193b3205c57a6e4e1072c77dc6 (commit) via 158674d8cf7776b89ca9c6598dc789ff0961b5a5 (commit) via b35b810e7fb4f09240ccb2f26352b7b9734f66eb (commit) via a1e59f82f033db242857321b15d156f440d0f5db (commit) via ccbe9281364f4dc12ac84f4253f666fed7821a04 (commit) via 4ad90dc6e24e79b3f9cf83ec48e26f59f6be9feb (commit) via c2c5d034e89031c37603ba241d3540e535e27d61 (commit) via 1181e91134d67824ea535456cc1b2de981896f92 (commit) via 23f61239fcddd7bb54974492a152d32f4b89dc33 (commit) via 4b1540f8961b9411f20b95955511e91d55d34c90 (commit) via 5cc75971dc8b104e8899b4bef47a9073615c1ac4 (commit) via 49b71a5618501e3446de0e7611eea308390d4db7 (commit) via 30780b8a7a91ae438e0671868cebd7cedc0cee1f (commit) via 7166fe8441a8de1bb12ecf1b0b00db65f47a74ed (commit) via cfdb379ee5dfe3221bb94517f163e42876720980 (commit) via 3d2c7b58086ab914b5ab29ea43a0856cff8360d1 (commit) via 8230d2b9169ca8af4043b07ad0dd37228dcc2593 (commit) via ecf0da53ea80435c5a2443f3281a51aa90247eea (commit) via 4f9627bf481d73afc518cbd8dc702d4b21acca80 (commit) via 476b15a5b98c778506bf3c32557ca4be5e6dfcfa (commit) via 1cf1b9ffbbaff60d80e523c2aab3a92db73b9b2d (commit) via 19a2bdb8300cf271ebeec311c62f9c1943b7d641 (commit) via a7d4b011fb99946915989057da09cd6b1b374a00 (commit) via 5803e462ec1176b33ad0310015c708ba4716d91f (commit) via 6e4585b7915a3ae63a836ed717d7db636e4bb860 (commit) via 26f1d2525525bb9104730118757481181543f1dc (commit) via fac43376241191fc29e1c2442c1f1e2a194b38bb (commit) via 19d5147c0d7c807323213190161dc9bc075cb95b (commit) via 303cd42616028d9faacf46248a1af84e1724c80a (commit) via 68ed541b4859489bdf5da9cf84140c58bee4b270 (commit) via cde35c12ec0fc71d707dfd32d5d84b74070193e8 (commit) via 8fbce299396c622a22f96e67a168913cdf1deb83 (commit) via a4700168d48cd6fcd0a3328654d95770be668727 (commit) via 75b075ab606fcaf559f7332fee92f74edf51a4d7 (commit) via d4f42b7b3d62a24df02772defc9667b9773bc8e4 (commit) via 6ec2e552ab197e64af15e32de75e2725489137ef (commit) via fe1ed6a4940da8508c51bd76123c56dfb77aef57 (commit) via f44d97d8b56362e526354e0ae35e763879d2739f (commit) via 9b953fc33747c442c3ceac5a840afc7e02ddcfb6 (commit) via 60603291972e6ad83dcd48d2ff7356bedd8646bb (commit) via b6d4e5722529dfa334793784c0aa2e9a0a55a4a9 (commit) via fd99b00c66f90bf6f9126c376d0c78d6698af83e (commit) via 26ca37e2ffb17b180d460cd4e37197922f46e441 (commit) via 7e774a27c69df36dafc00786370376fc78c18bfa (commit) via 2c1259eada84ab5c395d05c07abe621108081099 (commit) via 748010da512b8c088df5abe8c18286d75403a4ef (commit) via a9e524a114fedc04f791ade5390d67fd19549cef (commit) via 649f4e94393e1708a9355e3e65ad0fa6abb6753d (commit) via 4d057ce666af88a655929baf77f30dce50375eb8 (commit) via 9a53e5681eab5b4ad020ec340e35cb44ec2d3c52 (commit) via 4cce714849ca4c2f68314bf7aa70522fe766980b (commit) via b4e8e2fd85cd0839d15e49f7d79039bdaaf0835d (commit) via 018b711c7ba31d2b75b37d4e5322d28ace2dd601 (commit) via 7ce06e41cc2f7463033f49c5a438490970f62d09 (commit) via 8cb3c9a1a9c70694cbd43c724c367bb2c808bc04 (commit) via ec4c6d1fa395d019a31520d094f9cc1e1faebd5c (commit) via acba165f21f45bb0cd34b077147e3f4f0debe939 (commit) via 781388ec655a843c6c368487bef654473e3e555e (commit) via c2565943cec2b91275cb9b34d5e03482d4870ad4 (commit) via cd3207f7c3527468732f924a742ebd2a06996c30 (commit) via 9b41f0161592e78f202850fd7f3676304ef4632c (commit) via 410e399c982991c45ae4b1daaa9e679e3f60b9f5 (commit) via 5e08795846d0328d92f5ba16d35f8cc26afadf12 (commit) via 2f3072adc3bca66ca77e8182f3ab3e99882f28ac (commit) via 7422f961cec38f8d853fda396d3c80524483b5f0 (commit) via a95d2c4331bfcb483a8e5f417368c5b1e3430d8d (commit) via 9b2d1bdeb43108568430b35e32994f80408a3525 (commit) via 717626ea7056e4bc3d2b900e047abd5aeabc8ef3 (commit) via 6327ff5c90bb0416b66d7902a6065379d9ed58e5 (commit) via 717ba96071e21b79313b79dee7214e8c720d45b0 (commit) via ef88927e0701cf07d11ca7a724175beb19b18ebc (commit) via eba973e45b04d47abab024011f3e5a29f6937728 (commit) via cd25aed34787136d304ab33adbaa45ef94756628 (commit) via 3961710fad9c8e0cc23b00cdc889eaa89552700b (commit) via b534427f7bc775e9a1419030a0e6fba6ce463a95 (commit) via ac082136a8c3f3bcbd944a9d2c9964dbc693e5dd (commit) via 6a7d8ce82d50e6fa29ac7af8dd2e8c477b7e8117 (commit) via e45ebea0970d065df89d2aad89644cbbcea4b770 (commit) via 8d3c48bd116ed68c05319290578c8b6acc8bfea8 (commit) via d02dcfea36d154f93624c2d5a2778569322c784e (commit) via 535f062ea8729b350584793422f6c6b1b54e8f6c (commit) via d3799bb38e6aace72b689cb0c68afa10b4d43290 (commit) via e1d1dae58a3586973ddadc0991fac4c085a74b4b (commit) via ef6bbaf7c641c2b2b31a6402f4642d3b27c08510 (commit) via 0a82a148ca3feef3fc84f316a9246cce427ef5d7 (commit) via 99e90707cf2cd4ba7d9b563d009426e477114d82 (commit) via df6d38a95b1b260e6fc30c10a9d897bdd7bc2c28 (commit) via db562de1a8f28d7a98843866cabe5898d3f00083 (commit) via c63b1910f31bf7b3b69d8a4a3ee7b17066e8ad28 (commit) via 498182e85b7cf5644d5a56543cf31a77887b9a26 (commit) via 31d21d7a049a46bdcab44892ff5ac1f44964c191 (commit) via 525c766adabd8ec98769c6cc159b77946364d9a0 (commit) via c54d7b004b2a0417239bb290a1b1ad36ad8776eb (commit) via 842b51011ac8660d3bd3ceb9d5136eadf0eb03e5 (commit) via 24978601ff52f3b2a6551fe97be222a365e5e105 (commit) via 8159aa56ceadc5bcd6f9cfb2a5f37ecf7a7dd654 (commit) via 30cb2c66c4686c800748bb27e62661cc06004ee6 (commit) via a873f0b3512b1f0d673e5d5ea72f166f44795af3 (commit) via f47b3fcf6e03359463efdc3de02ad7f7196c3473 (commit) via 4861cb8539fe787d6957055666afbd9e1a872d02 (commit) via eddf5986f419fb186469c6b462ca0d6c27a21d5f (commit) via 11c61e233fbcf068e9ba918597d81bc047fbaf66 (commit) via 240e77475d2f1c2733b8043b2e833d9b20b55266 (commit) via 871f318c301a936e834054c49b4a8a6cca49c9fb (commit) via 10dc4c8b76bf5a9c96313b01d83ed86caea84243 (commit) via 5229d8063d835cadfe878006cc2f4770cc88642f (commit) via 5bd93380c7d2f1c4b9e3e93d9ceb94f99634712a (commit) via e350936dc8b2508faf77fd9d9d2a3ce6b8bdaf13 (commit) via 9578a7c41746730548befb69631f4da45ac3c658 (commit) via f0d6c1d8709c3c7b495cc1cd88e4303cbb893a88 (commit) via ea81dc52ce730d81ea3d505c5018913716f2beff (commit) via bf6b1956454db13f472c4f0f891f838b4d22a22b (commit) via 3a164556640d5b8f37542e9064ddc9532012ebef (commit) via f11938201edd6a3fb5a12706fbbab00bf8ff3792 (commit) via f379db63f7d03f369985fd936f814742ba07b22c (commit) via 7850a5cbf4fb523903750a77ece5f7d4bc165034 (commit) via 8ad0a97ae8e23d5a3c92a7b92d0c5f7a73170a19 (commit) via c38ab1cb4b8a00206987ece11b71f9bdc8d6ff53 (commit) via 53d528c1c158ffd8b804ad5f75af718eb1fb4660 (commit) via c1243c0fa72dc8675342f34f1d0b120cf2bad99c (commit) via 74c7ceb62e83783060f4a8365efc0587ff25dd6a (commit) via 79cd837f4b3ac8191b0bc88143aab2c88ac144b3 (commit) via c14dcd085d6d6939c514ed7a712ff1e7f14bf4aa (commit) via 20003b56dc818079d16d154db981baf2c7bddb82 (commit) via dff83f45bd2e625530b4364d49385424dbed1715 (commit) via 3e91aa00f6c0fad93896540fcd4b3e623302972b (commit) via 95d3e551c7d23d8d2a3c0033019d9b772ee31f68 (commit) via 186c2d61592faa586e678a6f9c67d4ec3bde1fc6 (commit) via 6d2512d4bff64a59896b43e4c9eb6572a8fa4ad3 (commit) via 40c6b5f010c68e428818ea166e703257e0beff55 (commit) via c4c82e621949cfaf86095309cb0ea7e7b0f33592 (commit) via a43ff0e8c22897658136ac4268357e9b557a90d5 (commit) via 41c38166f2719c990e93c67fb797d8923d463644 (commit) via 9af998a96f7e4a4c16c4e38fc248741654498d11 (commit) via 801ffdb7dc5317b0fac39857f0746e71d64d536d (commit) via 7595c7f77da4527a73cfd8da411673b223a8d121 (commit) via bf0a85d5a07d6052cd9749b853051a54042a96a3 (commit) via 56dbdbffefee9cc7533b8b786ca9a4eed6a7512e (commit) via 7140f08c116a96e6a532b354acafbc79e199c0d6 (commit) via 2767b51a95a345a2aaa35d4bf0971ac532141802 (commit) via fba493cecfc510cdb2a4cdda8bb4171286c3b69c (commit) via 683ab74070c3d0ed6394370f576091bc5436537d (commit) via e8bda3eb3504fd0c9e07af8cd99426249603e224 (commit) via 6765d3654bc5adc1bb72dd9cdc7350319b3aa542 (commit) via 988149181482874744a26ac7ec2fc5b16450cea5 (commit) via 6a4abde3d8b51f81d0983ae486009229842dbe4b (commit) via a2d0737191ac3b5e3ce7c7e8132c8144cd496aeb (commit) via b4fd54bc9e8e9785af5108534d1a6bdb2a0ba2a6 (commit) via 51673b9d6275d4033485bc8fd820fc6031f7f7ef (commit) via e460d6ed71bf41c98222b44d503a50f6a45540d6 (commit) via 94093c5cbd84e5560790a3cd897f41d0a6b7e193 (commit) via 8a346372e18753546662e0c3bcbfd8248eb7c2ac (commit) via fa44e2f58864ddb88b3dd6fdac540b63e9bda30e (commit) via c784f95fe686f5c41222a07221ab0104b7b4ee4f (commit) via 1e8a99d9d0004f335afb6763cf75a4b48ef8a318 (commit) via 32991121223bdb0c26a4b27678626423c35d1abb (commit) via b55e2b81d22a55ab9e71b8ba79861dcd265dcb52 (commit) via fafd7a277d724d06fe2999c42e8ca3c271821eb6 (commit) via 20c0eb22543a32f62ccc66878e1616fdb494831a (commit) via 8ebb7b5cb3cad369eecccaf4ed31d23a791d2b00 (commit) via 808707d743bd60aaf94113f381f8a91a96e2339f (commit) via 532f1984756637a9bd36a03852e4b525f3f268a2 (commit) via 9ebbb035716ee83955829e6e5a6689b2c2ceddf1 (commit) via 12227ac87c18d93d3a7d06026fcd3f6da5d172c3 (commit) via 66ac31c3027fbc8bd2eb0ab82b0633622ddb53a0 (commit) via 301a3ede509763405b2ffdc4a43fd56df6b5febd (commit) via 4eb8152c05aa8ffdacf26cbc7b15b3935e2fab4d (commit) via f9727f8b6be60b8d5cc829e724634431a4191b6b (commit) via de396a63b975de9c06f838b457093c573fea914e (commit) via b8e9f5907f468ea62b5afd2372596c1330a08024 (commit) via ff281aef0a31d16e69ddaa304f6f27af6213384c (commit) via 2e2abafcf06deca2c089307dba40dfcddf4e78dc (commit) via 974d3e9bfe034d305bf243fbcf0832145630ec88 (commit) via fa4c11b53281eba1bee90d298b9ff61dfb64992b (commit) via c6a74bfb134da0bc5198ec6027f55467032b09bd (commit) via 2f676e6e724a7fc25bf9fc28ba2623d38aa28520 (commit) via 957db558ea18b43cd4fec42250466cf3531ef569 (commit) via 73b430376403ab7bb36135b1ef6af0ded02839e0 (commit) via 615e15c66019847a32d5bf10c8b9e072c061917f (commit) via 6498acf0979c2929b83dc61b46b3b2b8d4f124e7 (commit) via 175c1868ad12192279fa606d040907b55e993ebc (commit) via 395b8b6dca917627b6ef83c7712763d3901b3610 (commit) via 49ff56a705405b9624d0979ac473599e4fe63e47 (commit) via 488a92f6a2bef34737d43fd16aa1501146119a20 (commit) via c6c5178b1595e7786b80ade5eb246e4b3e452c51 (commit) via 5d02988fe6a53787d358023034b8c7db457b5b47 (commit) via ab6e2138c0a72901cfde22bf062ffac817b9215c (commit) via 5faa8aeb76d3ff72db6acc6c55d67e7ce9037671 (commit) via 5de506b36333d65a2d00a5b0f07e104b6dca7a0c (commit) via 517b18949c4bf354a8052939ba9010f04e186d4c (commit) via b4f9e5b466648977fd7a5aa3545ae3e69bd1dd9c (commit) via 85263e145e4a43d08ad309e13c8335bb0212eca0 (commit) via 7bdbde5d6ec17a344e441c1f4def6fc088251467 (commit) via cd410c5e1d7ed6566c7054bae36cc7067fac7030 (commit) via 170e92a88c48a99115cd9dd6f0648d0539b703f2 (commit) via 1e2fe399491adbb961bbe2469a509d13e5321be8 (commit) via 725a8d680cdb5f13b7863aaea420ce974f9b6f78 (commit) via 86300324734c61423bdfab4e260dd455c0cd3c31 (commit) via 59f746bc82d646467268fa87733266cad0384f34 (commit) via 52a4c2a7c2188649f5f56eec93eba1b1b2a10a8e (commit) via 5b2dc186eac1e3f08d216ed469b73fed9a2e3da8 (commit) via 69424bea3dbccd16c9d56bd20988a301ea2d5245 (commit) via 02a14393bbab0d76fb2674b8125d5e6ee1fda8dc (commit) via 76a370ef2d6ec00b7cbac334813b1eeaa0cdebdb (commit) via 3d7a79a456091f5debd6f224ee13d6643db46261 (commit) via 1e42f23e9ab67ece15fa2cd89ee6bab6b93a4c04 (commit) via 4597537587f456cc41e6ddd90766373e3d1f9602 (commit) via 51a5e9803ce5916a2b7e416aa231102566003589 (commit) via 34072f4adcc3e0ca05a44c53082d30e5ee33b101 (commit) via 2e68b09cf4c2179754ab952385467abf74d459a4 (commit) via e8bb9c1a30166a215e1ba764864c57c663ea45b4 (commit) via 52ca4363fddc61923b6d845761e17486aea7e7b5 (commit) via 77467cbd79d8ec846401f0671c8093a385e92f8e (commit) via b6860f43b5917e72fdcc59b3abf35a97339a1d88 (commit) via 7c6295264045d3123a130e99c634722269a77aa7 (commit) via adb3e60c21d151b7cd71222d7b454b7f90260e69 (commit) via 49320819abbb61a5005dd099c9ee29b6798b71b2 (commit) via ef2efa5cbf83cc35c5219248efcbc3bee120ce99 (commit) via 4584e1dc7f31226c1a01c8baca2eb6731950375d (commit) via 967d400e6672246463047d588aa4250dcb114319 (commit) via 7c9c394301c9e6bee88976386413eb988c8b2121 (commit) via 6d943e2c6895eeafaba7a880549bf5cba0203458 (commit) via 2e96169e68ffbc3c2ef237d9b6cd58fde2d27028 (commit) via 855163fef43a3e851e203d454cacb5f216882bee (commit) via c62ea9c3e2ec0bb0d1bf1b06ef57fa6e2656860d (commit) via acb1eab6fe914ebd321d9f06ca6f5968c15c332c (commit) via 1add6595fc572eb1ebbef5ca140045915ebd7e4f (commit) via d6cb51e91c1de610e7db9cacc44cc22702c6a165 (commit) via 8cbe674bca476fd42010c96f2d27bda780325308 (commit) via 88e2b9dda615920a37aa64a62a9c0791e42b00ca (commit) via b50ceb454979ddb1e0a74b7174a6242abb7b9994 (commit) via 834bca8bf9ae74e3ee769436340e99dc660789e0 (commit) via 208941a6e242c54076f0b3c697b9a8144eb3f994 (commit) via c22db93eea10a2d3e73e55ec578956bbddca0a44 (commit) via 2cdf46f156ad9b39e6786591f725208a51241ab4 (commit) via 82d1ca6f41bd2a45517ee5b47c8ddd2cca07a446 (commit) via 139f6c50aa015de6b02cbce0752ffb5d3d0e3bf1 (commit) via 6a6d1330b2d0c1605def5a7f3e15db3c120f83e8 (commit) via 7c1eb87da56dcac9bd59bf3e26a92cfabe7898a9 (commit) via d2c208d6b41a93fa8ecaa9667dcaef08f66424e2 (commit) via 0b0e9b8691d248387ad806f28bdce3c6360561f8 (commit) via 823af39a88f37b3c68c31c7fb66b43e9634c2263 (commit) via a744c44477b6f15414edcc69d6588b32c67f989f (commit) via 2dedf87f8ce55f6e41f4bacb8d96ee4bf647a5b8 (commit) via 39c365ae88249b06953d6c4ccf18b5062bdb3c4e (commit) via 304c998ad03e6bcc388166c31a521f7bc4ea7a8d (commit) via 4a69e61f5e8aa99b2f71b98a36417a69cb2af46f (commit) via 547b54ef623339ef09785b1fb92e624e22d1850f (commit) via f844903021ecd9cf4de2c6e76176224d1740b65a (commit) via 3869516ac94a802aa73d768263a6bbd35d2809fc (commit) via 59da17e96722466cc305e823e0afd2fb12264eb0 (commit) via 3de0614c6e6e66d587de0335131d84aa592d8915 (commit) via d225ad95747e6375601fc9701dd3b08336931fc0 (commit) via a02d6c87e699c1b06863ef88105622c62f7d5355 (commit) via 0a9ec07d4b55cf1d9ea26950236aec7010c09849 (commit) via 564bb70d427f63b02d57c5a77853f73ffaf14708 (commit) via a28043014d599ed5117fa63be6b714696c14d1ce (commit) via f3978c255ca9f7e4a7f79108aab1489597b67208 (commit) via e56e3a8a5f3feb4e376fe4a19438038b3754ddd9 (commit) via 68b9ec1cbfdd1ce8c24b8ba40463ddeab2c000ec (commit) via 7ee03a3f145f0da9874a393a5123bbebf3c2f6b4 (commit) via 58c5fc13210353a151f8b2d3c62d19da140b10ab (commit) via 2a9f8dc8a10ce3d20d5a93d22d43f54764172dd2 (commit) via df92424c2dd240e6b0cbfe4991cf66d0cb5a225b (commit) via ed4173fe6f4958c8fdb6c25df1da903f678d9189 (commit) via 5b45f060fa9aa56ba63bcefc2ed44283a8071ca0 (commit) via c192dc6f86bfbd1327b893a8bc686f0c56a57555 (commit) via e385ce086654819cf6e16885c1187b4ab6a16c23 (commit) via d40b18e6c8bc9c4d58c59c0171bcc8bc766ee46f (commit) via b2ec3c8a437494d3238a29287d0a47d957d5ed2b (commit) via d54bdc5d92e6a02d0e073ea4511309c363e0654e (commit) via d8cb222621ec52d608e079ebcd2220b4a8131e55 (commit) via c7e47122ecd8633f5b5a22489f09bbb05d40b9f7 (commit) via c562c9d0c8748d7c79481787c8b707a7590c6a6d (commit) via 044cc66f8f0bd21b5ad61478dec54cf8cd2a0583 (commit) via bf952a7dfb5ed1548086e163d1aeac38a45fb9a4 (commit) via 8e7f124491c9aa4b97b9e3e462e30626df993646 (commit) via ae6648471f65d2f315a8e8ed7398a9fbc9e0a88a (commit) via 8a172fcbf1e99b16027348ccd3786f33bb7d0a90 (commit) via ffca338b42f2e140bc0b45e0c09ebb23ac078a10 (commit) via 60964b72a1835d14ece10fdffbff1643c0361b50 (commit) via a8e75deada83023b5e0dcd874beef73849019550 (commit) via cd461114de8791c7a36c9a2101971c3dd916f080 (commit) via 0c294e96541117716be9e7e07e4ff672e31941f3 (commit) via 61d84a7d012f7691e4caa4a1319049957175403e (commit) via 7c415e0dcd125554d8658375e2276c53ae999ae1 (commit) via 1091aa0925d4abca9eb7594814ab74fdf6459610 (commit) via e67445f39e39f4930114e65bdc5d428b9b87d9a2 (commit) via 7eb27ce63d2e6a8f13806d58f2b8ff70a27bfbbd (commit) via 0814e32f9b66978953f63ae1bf329a34db4cd8c7 (commit) via 74608533a1d51f9fbb9fab00ec35219754182e0d (commit) via d7291dc9c4c29acbf52778c88d7ff28ecf2c8b7a (commit) via 923cac1cd6fb4af1b5377152bef60de2f27c6b5d (commit) via a20300764fd737bb5df934ee3840a9a7a33f6a4c (commit) via 6123353700c3670b20765000efc09d9a614c788c (commit) via cfd06ca11d5bd845c45471b5dba492b592fa94b6 (commit) via 1ed95534cc36bfc34d3c36b69ea70d06040f33e9 (commit) via eee6cf94ab2dfaf527406f712da20c56b7237b88 (commit) via 582847181a50ac961a8e15ed6191a0538ff49e0c (commit) via d918082aa7c44d0fc68f55084ff25a9012bcdd23 (commit) via cc52c5238fc098a9707e6478e97c0e4152788d02 (commit) via eb73cf79d5bbb8884f5ba28de475cb302392ba09 (commit) via bbd0133f6024fc172d5b0c77a72196bedc864167 (commit) via 7ec4bf0a5c1eb5b69223bf1d67b0811ee26bd5e4 (commit) via a67932864864af3d5645aa05c7bb3ae37b144c33 (commit) via 2e9748cce70eb295816c24d95a91d396b1356b3f (commit) via 8678b451f67abdf99a6787782340de024ba568b0 (commit) via fe4dc0830a86d598e796c72c56ecd7ea3025d9e4 (commit) via 6d675cd3e69670241243167fa34f9dc352824505 (commit) via d1bddc8a40616cb131bddd14e4082a54372758ee (commit) via 8a273f62e2a4da270174786e1b42ac4fdab0ea45 (commit) via ad4c499fe604149c292be176afa7de8e322ca597 (commit) via dcc8d074f8b92000acacd2aab50ff15703cec3f0 (commit) via 40dbfb23b96b1f760dcce20d47470ecee76e5aac (commit) via fccb2aa5e80cd61ced314f5aae5d6911eec348fe (commit) via 4eac8931e84d98817932751a223630ab387908aa (commit) via c3cb5d3e2dc01dd6040a26a4c9225c14d9dcb1b9 (commit) via 52ac63ac0c4af58e9e76315f2f355c7a60a5d61e (commit) via 714e50f58272c73f0645cfa2b548c610ccca83f7 (commit) via ae5a840bd4e2e83644f8e34da11a9af578f9dad7 (commit) via 73e343980dc19894a7808521f130d33a3d23dee1 (commit) via b685bb18d197e0a8c1b047c4b34f00027d0e5c0e (commit) via fbd0b63053e2f1521a19663eaa6b7ff166719e88 (commit) via 0ab6a56e242730feb8eba7feccbf298e7c63d6e8 (commit) via 80032003821085852ff651dcced492b3183e0b51 (commit) via 7d4ff9534d7d46a8b5f7d7fc04626a28985c0551 (commit) via b771887db18261b91f55caddae8f418389671ff2 (commit) via 5c9f6e48e37bda9ad4f06fbfca0cb4de9a949215 (commit) via 02b6f3f0c6a473f1f807fb73f0c9496609c32a57 (commit) via 799d65adb97f2b29c5b92133cdd68969a9caf6c3 (commit) via b0b6cb34baaf55c65c5272aa4c569427db002802 (commit) via 3652add1883e4ddd9cc0c3296b38fc17d74d5eaa (commit) via 874469ef1ca182ce94de95c623e5c42a44ce841c (commit) via cce1a80b6cbbbeb47a4b1da31838f33f351f0896 (commit) via 06b38339eeadb1d4d3be5c65ba4be5fb3dc77408 (commit) via bfb883b31db19caf1bb9d445b26f1c56ed0d5cdc (commit) via 1484533c77ebd2f856c6b8ea211270e893501c1c (commit) via 8722fc732453ed2923993b353f02e9b4334712d1 (commit) via 0479385f25c7eae66697e5d88687759e469eeb5d (commit) via 7f0e16ed47fa94c0e7abb7736939704dc04233d4 (commit) via a2535313e56997922692e8b11716f7499ef51700 (commit) via 606a4845289b87595df744ab25808216f2866afb (commit) via 120ffbc565f88237e02d18e0d18e9e2df2fb7dd3 (commit) via 8b63a1947a73e64eb8c0e532a6fd5a9bd818a24a (commit) via 26064608eead6cac3a6d1d76e8a683d1b2e32442 (commit) via 494e3d7806429c35c9857f5eb8da89a817b2c5c5 (commit) via 20d904b86e36373e520ae9aa336d56592edc238a (commit) via dac1e99c0eaa69d4efde41c1679c208e774c00fd (commit) via 951459e8fe7a6e1c57a799fce84a26c4a089dcdd (commit) via d661f0d130cc7882b86c0fa59347c95168bed5c4 (commit) via dfb13c6f5e7ded6cb434606e291f67135c8b736e (commit) via 2c9f13c13e3f4e572daa5861e850f1ca297e97b7 (commit) via 015d4a75111ed91c10b6be7b9f9b6a85afbfded3 (commit) via 94ccae6bb3b265320d6375468e78d72fd07ecc48 (commit) via 34947337cad2df285ff627980dfa32e60729c6b8 (commit) via 9ad08da356714d627f12eaa843c587dcb1830c74 (commit) via 1fd12ad5614cf8918d0f359624c54395bd9bacdd (commit) via 8281db1085e47d4b4368937e97b0fabb595388b6 (commit) via a7905983625ef7410ba3b9ebb9fd368ecfce959f (commit) via e1f441dbc9f151c34b32fa3099bcf270695d651d (commit) via 9b3bc8007b2c1be9df9c4858183d8001e200921c (commit) via a50173a711793cda64be49863d3215415f29f1c4 (commit) via 7c6a4b60058d09d4bf4edff16808a8f5bc2f46cc (commit) via 882588278e284782327275813763283376b5a9f6 (commit) via 689311b650aae75a9b79fa0fc6c706ea4f17e523 (commit) via 4aedebb252f9f687724b31e0b8e7d90657df4140 (commit) via 914e4ae3fe2b8d81706c6eeb6d5ba95b50fd17fd (commit) via 9822cf6c14dbcc46aee1db3cb4a40924b58a9c65 (commit) via b8945ec8bc2c182bc483cbd5dfec80afd0156d3a (commit) via 34832a19638de1eaa8c0b9396c850fc08d545435 (commit) via 08a45a9f5d7c853bbf7a33418f58dcdfa48c37b0 (commit) via 566c67577a559ac84d3f694f550009336b6a5efe (commit) via 29ac8c51e7860e1d0cb560dfdcfa752b6dff87af (commit) via 68d04bc0168c64425370a5855d92780e39a5a58f (commit) via 32aeedbf57e93a3d37d8b096ad27a80feb96b71b (commit) via 2d940a9c4c5098b09f15f5b479ce0fa5f749a795 (commit) via 107ed6eeedb27f4fea8e9034e45f8518579122ef (commit) via daaaf465b8553b0397343d619b0a6749e84b804c (commit) via e9f9aed1118740247d2d59df657d7deab2f9da44 (commit) via 590ac020c54353463d307f52c7a7bacf3c8bbcec (commit) via 8058f4e3b237b79dcb7e47ff2f1000a3b5741963 (commit) via e3f1c924bdc4d57e1ff00ec4e2c490bb00ceeb3d (commit) via 932926c32b094c0fb7b811252dbd3d08ae3229cf (commit) via 87dda34c56cb1698e9dc6cb2a18b603ddf871c02 (commit) via b5c3b53a852c29c0eb90d0c9724404c490efd467 (commit) via 640451c1aed3908d544505d82066d3f2e1a1c688 (commit) via 9bc3cce05d9370908a28d52bfcbfdc8c96467bf7 (commit) via 2d99b768382f669c09ae204822d495f2a56e89eb (commit) via 9da1b3e5f96ba5c83e7a7eee90e10cccbb3511b7 (commit) via 45e22ad04e45e2f9c6b7954801f8b6515ee3ac6c (commit) via 5705a8adda8257384668e459784862f73a4edd68 (commit) via 7544685894fa697613c6c16d8df6cb9f9d12b612 (commit) via c96c272fe986cc4f8ead2eef31cbdbf7dd911ebe (commit) via 83e313a699911a0f5aae049ae7fecc5c446a847c (commit) via 2cbc40be14bce128a9f0a12f845b994103325be3 (commit) via e6855a9e69d0816bd7aed5ad16bb8e2f4ddbf900 (commit) via f518a817837f268a9227c0c1c3a3f0068c2329a6 (commit) via f07caf9e9e3fa73be880640be40bcb94fd038ce2 (commit) via db99d62f11e6f68d84fa60b8d411085d62130036 (commit) via 378c8f189a74a39693b50a6a04a0fd3934885bef (commit) via 59cdb5f181463dc6c403a03ec8d81650a39a9d8a (commit) via 19f2538dfcd68bf3aa77e1866ce30f9d2bf612fe (commit) via 019de8350512162ef6e02f6ffc2dd03312f766b6 (commit) via 5223858260ab1acdba59b804a491c0cccbca12d4 (commit) via 8504873f9e38b2a872c616d2b665f142277711c4 (commit) via 128f78cfe83d0735783b9aa4065bb2e657de50f9 (commit) via 0d6054530b08fe1bb7e900a8d08d15251f4a4146 (commit) via 0ba3cc3e9120e0e5478a06a2ed75e2c7032c218b (commit) via 32a1e8c6c677e8ac37d8ab1441fac2dd823cba45 (commit) via 6754adb5a810a081d7293537c1f04d70f0cb5927 (commit) via e54c133400d8386a2f1d7885be6fb4f7eabc51dd (commit) via 58f5690dd3226bba485eeebcda5d603b83152b63 (commit) via ab18c329d05ce1fcd8ea9a7e23a081588f0da668 (commit) via fba169947dc98385e52b2055e06ddcf10d403538 (commit) via 92c56f8834f5b111a79ebcc6eb5708df51386df4 (commit) via 4daac19ce0e4020eb2b70080d62e95a83e4c9748 (commit) via 59a1ef0dbade2a1844af4e05405d04d96cad0072 (commit) via f1fdd4d64380a2963e2d65aff3b659f0d7413b7c (commit) via fba656caa9edef69ecef7efbc6d01eab7187d2f2 (commit) via f9d4d62948c81a667bab2c3c7137b84357d19994 (commit) via 36871e5d8b4892f02aa63b8146c254cca9a513cf (commit) via 19a4b6e1df07f81bbd7bfce3312a43e2f06be6e0 (commit) via 8a3d26ab832e7196bfd2378f1422d058ed233ac3 (commit) via 070648a7bd3bb6ee14d9b23c2f128a6d05d890a4 (commit) via 593e8e3b233f4a6e0e9f9782c1971f665bf85c14 (commit) via b681c2524ce0e1551f3dfdc515b764a12f1490a3 (commit) via 99600f07bc5338f52633856d3c5120272405cb4b (commit) via f78f2ff5941ae65eb45506623409740e8aff5c60 (commit) via ce7ffd0d1dbbd0706d6deea78593af18bbb204ea (commit) via e020cabf4de05f2f5c57b1c3ff9ccd2f5611d681 (commit) via b6ca51785309dda9c79de5c72fedade9bb62d98c (commit) via a44c6c89403fd3d651b916c1cf9fbc5015621716 (commit) via ba4759311f183fd0031400af79a9637bda197d49 (commit) via 90bf84f475ea764428f160e1c32c16b558e42ffa (commit) via 15a38d153adc033b1246baa4bde25c73e7e1aa11 (commit) via 88f71b44bf1b2a30e068fb02348d0b9495634278 (commit) via a6dccbc048e01d655175a979d2ed06dcd7220abd (commit) via f7eb1e88a4e5ac80fab4cf3ed9f7fcd2e39d8503 (commit) via af478a823f0fa37e67b6388a93a3735da9e39422 (commit) via 6e0769d0a0a3c4ba8ee7e4f953570f5d505adde5 (commit) via 5970e4b21c86fd577dade914cf16e4a540a79001 (commit) via 3c36c336d71ad9fed752f4ecb8407f361d70173f (commit) via 15b43c6c0d475a5ad6245de810c923eb3ae7ce4e (commit) via 1a6b4d6f310fba4017118fa8c7dfba635fa1083f (commit) via 56888ac913ab34174558e17de3ac8aff00ad4a1a (commit) via e152ae41ba9fc29c5ebd2024208e272997faf216 (commit) via 5e23908c7bee660f8757101d6cae7a33f1767d37 (commit) via e5a0c5bcc77f38c0717ebab5a6d1d833a8e999a6 (commit) via b8e732f4e6693b24ea709377c6b08f32cbe7701c (commit) via 8aa1b4429f3d4b617b2dc3aacf0baad4c7b649db (commit) via 028a62ab1689d303fc4a90a2f4379cf48c7f562a (commit) via 91f5b0765f3e6b67733e4e025346d61e81d7a095 (commit) via 84a97a99b793cd72e16f557b0e845968bd29456a (commit) via 25ba07e22916118afef529b95272c430d0c56904 (commit) via 58c8a19734f513999e92c91eb07ec62a159938b2 (commit) via 6dec0566ad10d3e0924a788c4a9e77c6e1740823 (commit) via eef47701611badbcf5487b23a323e11f0d8989d0 (commit) via fa68012cb2a889bb0d44064bec9c7ebdf799d55e (commit) via 3eb86a2b09da48598adf28827458c06cb2a543fe (commit) via f5b9a090e9dd083538ae2bdf3b5920e12059e72a (commit) via 87c18628cb51e6cde0b85b6fb6c0f3593ac02f23 (commit) via 66c170e37a5229920b1da04c5acc860470941381 (commit) via 9bb99a82595eb3b34de1db00e1a643294b181d94 (commit) via e767635ab15582ea6f86027a88e72b3b44b47ccc (commit) via f31cce40fa274c66038c37ee3b5ceb1f71e36e2c (commit) via 1913f3ed8452836dfb5e5e4ffa9c086b5118dbcd (commit) via b968bc72ba65c7513b6c7a01916656761ad4ba70 (commit) via 6c8e4af34e35606f00ba5158cafe81a603008080 (commit) via 7d8ed742e3f512ad0233ff8fcd2402de5dabef19 (commit) via c3171bf330f64c450a2356c1b2580d79f4c13006 (commit) via 91d1aacfb8c9283cd46a65b91fb7da8178e1dc85 (commit) via fe6a09720870475872fea0599b274e3e0b3c6871 (commit) via bfb82b0995cfe65ca4bb7f7459f7d1a3b11689a5 (commit) via a9d112c3991f3ddbee825d572538b8c3dec5fbc8 (commit) via c36e4789f6cacf9d0df32a001a308141d4f89f84 (commit) via fc5f06dae0ff7447ede56ea43f131f46915d8496 (commit) via 20d414ed9d87810def0babd5c15b2500336185f1 (commit) via 93c1e71eac3167d848470a6f66ba69d7c6a2d857 (commit) via 54da28a8f82a5405c6f2144d42cfb4082b2728b4 (commit) via edd88eee3d6b2d7fccd72172fffff4875ca257f2 (commit) via e5ea083def927bd3b3fd82bbef8c811d82b116cd (commit) via 166a3088f7c38e793e9180466dcfc8e3702f14a5 (commit) via 85122efe1a04d70ecf0172f828d35a117d4bf69d (commit) via f6d9281dd759b92f86f97f52bc7b0b6f65e9e83f (commit) via ad6556c4f76d63fe39b7c43c1b76ba0301b53fc9 (commit) via 2b05a3ad41b9a65d7559a8f6a6ab43bb9f2ebe42 (commit) via a91543e184b8592e6367d8f19dbe842ee162dde7 (commit) via 58608bd46b0c6f2b6444c69f18cb4d06d8b551aa (commit) via cbd6ced695f31f80122ef5f2f291f3d13fcc4e2a (commit) via 6ffd650d6c23cabdbc80e773919d1a988436d358 (commit) via 456f92d2b8a38e81b22ca67faad02c8dc57e471c (commit) via e09f577dae1f5e31514cd8b95797190b60be9126 (commit) via bfbb4b802f705d95767c5bac83197c13ca5e9024 (commit) via 5a9455235f507510f76c69052fde55d874016c7b (commit) via 53c273e0041fb385a01d805ae2c155be08aa400c (commit) via 2abd844d80e4348fbc363456ec20abd499c50c05 (commit) via d04f1a38af4a73c803f4c903cd3b300e0d8d2c10 (commit) via d113b67abf6590c092628846d7632551c338209c (commit) via eec968d8574149b01e2af523fbf4d62c3c65ce44 (commit) via 9d4b355899b0cde2de6029dfc943d85af4ed1731 (commit) via 2cc3ec08167248ab80671f7f5c2ac12ee838d400 (commit) via b2d4af6cdbea929e83dc0542273b7a2e74d19c21 (commit) via 331006980d80615ec02fd71fd2060c5e1e5f0011 (commit) via 8ac49cd149b2f1b9c1109d1ec7ebc9e226608b1e (commit) via 4a150286a35067d7d31adb08644f8967e13b8bd3 (commit) via 68543fda163f39757f4dd9f870a239761fb0f780 (commit) via 88b867dfa5e436a418cae474dd01f81b63ebb814 (commit) via 6620ccf1b61f5ccc23022b0617bc9bbc3bc45985 (commit) via 798d27716e6ccf215e86093f0580d9fe1e5a89e3 (commit) via a904827c00b3b0695fa7aa3b323d19298ad5f7fb (commit) via c8336c879a25351a549252653df8a9b5e268ec92 (commit) via 990e0b8699b41a58979db715479be445b0939c66 (commit) via d39d12bbd541ca535485e4969aaa0cee71ee0ce9 (commit) via 914c26ed1e9646fe06d878db6eadd8f6a2f1974d (commit) via de54816b780dfed7d5e10159570db1892f4b3bf8 (commit) via fde62a2fe526baae56047bc9a6434c2ac80685f5 (commit) via 4ef1578ebaf2d8664f53d0140ba56f81b0a7f6b7 (commit) via eb84cec10e39a6e9314eac7a2e1a327169b67258 (commit) via 9efad0d0adc20e5471b19e989ebf5d10dd8e6630 (commit) via fd0be921f01f76b5bc4561af2bbe481c8a7e1ef1 (commit) via d221e0eea8e7ee9ba47d05e51571ceb5b2c31ffb (commit) via 8983c3ffd67ceb008a45187b64cf4ece7e33678a (commit) via 8c5a8e97666678f9b074ba0e6c55e08af9218819 (commit) via 30b44af50162d8457801dd452bd6a1e1ee967453 (commit) via aa2216ade4f472db95fd4958ae476da7fb893ebc (commit) via 72d2189b4dcf57bf524e598adcf1942d6822961e (commit) via 75a3e4fca7d48ea367e13dc0212a42be4e626cba (commit) via 3c77dffcf2ec4eab7ce8aedc7af38dc0439a9c52 (commit) via d88b81096635fcba6c6d6ed2447d0a97c9d74715 (commit) via f150d126f445d389736e212f47009048e8d90b0f (commit) via 8def02b46d80d80f937e83899fec0dd12798ea7a (commit) via ed8f7f835125968b897320d4d177623d7f8435d6 (commit) via 3c2a0374ce9745d7cd5bc00846a78c1bf2123021 (commit) via eb95597e0ddf6b1aa895daac48f030572b92d1d1 (commit) via 2a40e833d93b11a6900c7f5c44287f09ae1f8a0f (commit) via 4cfc2057ab276a23e1fcc79c9ed89952e6cea5d0 (commit) via 2fe99a07c0c0399becc527024db7eaa67b447460 (commit) via bffb3f3b9f542fbc9513a8c6b339c74a33d0f08a (commit) via b1713869ac73a56cc00f6a268beb09fe665d5fe3 (commit) via 1a9fda212a9ab9bf56fd1045097d9bd03880548e (commit) via f3c626598f8e0481ce9a77c87d61a8fc2a3446ef (commit) via dfe01258e94d96e3f6667827a7a3643d13006782 (commit) via a7c9743429e3fe0d9cdc06ee89936181356d3903 (commit) via 17c0ee8a7d5b9b1a96a90539aba10162ccc8eb7e (commit) via 889b82e7350bc4ac089a3e222b77c5de513cf4a1 (commit) via a4d6eeb3e4ba9317268d9e44e24b4ce9f7c7af35 (commit) via 69b4aebfe91fd53977639cb0508a378cf8b3d6a8 (commit) via 7cfd59ee6eda796d5a970e2ba16e3da1f1a1f2c1 (commit) via 6edb7ef6bef9e0c0fb7c6399a1ac303e809e3d8c (commit) via 9948bd8f9193ad8f7e8b402b5ecc28da61d669ae (commit) via cee183e8af613c5c7e5b84aa7386e43e5c444c06 (commit) via 7ab3aafef318bfcddb284955632d8dddb8032ea2 (commit) via d4b033a04e6b61aaf4294a0b5976815bfd0264c8 (commit) via f707eae8bd1359bbe906fc26dcaad2173b940759 (commit) via 4ad2bb39ca922e9e1a8d98f2b45da7fadf72685d (commit) via 48add3fde5b28bd64aca38a4975cc8a1202b525c (commit) via 79f35170560f63b622ca60ec932ab007bd60d598 (commit) via f6c2d5178a5ba1d1efb685c088f70608feea2809 (commit) via 166a6c21f203e9b044d77446423079ca162b126b (commit) from 4ae473ec803f797098302e46cc947e245516c2b3 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit fe38a4b7c5a90f89a377209af6ffd19998102d5e Merge: b7858a49d0c4cb2b0c68b5e941cc40939a47db74 7c977bb047224fb81c164267714b931dfc15ba86 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Mar 13 12:22:24 2010 +0100
Merge remote branch 'ms/master'
commit b7858a49d0c4cb2b0c68b5e941cc40939a47db74 Merge: 0b1b2cc268c75c3167bc55ce68d1569fd838419e 26ab5a3c2b77858b1bb695b1e9c380d7b5082a3b Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Mar 13 12:21:46 2010 +0100
Merge branch 'commandline'
Conflicts: naoki/__init__.py naoki/package.py
commit 26ab5a3c2b77858b1bb695b1e9c380d7b5082a3b Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Mar 13 12:16:51 2010 +0100
naoki: Some work on CLI.
This is not fully functionable, yet.
commit 7c977bb047224fb81c164267714b931dfc15ba86 Merge: b977ba1f15476eae1fc0a637e415b7d1a045dda2 e7a5bed3d672fca3f7042af072b0876bf8adc4c1 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Mar 13 10:45:55 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit b977ba1f15476eae1fc0a637e415b7d1a045dda2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Mar 13 10:43:49 2010 +0100
naoki: Fix for devpts on older kernels.
If the kernel is too old, there is no /dev/pts/ptmx node and so we need to create it on our own.
commit 401c9acac5b9a5c505685096f85f768cae825e92 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Mar 13 10:43:31 2010 +0100
dejagnu: Fix makefile.
commit e7a5bed3d672fca3f7042af072b0876bf8adc4c1 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Mar 12 15:44:21 2010 +0100
Add STAGE_TEST to serveral files.
commit 85a21f2751a8f1819e89f5f8f19b61d97bbbf71c Author: Schantl Stefan Stevee@ipfire.org Date: Fri Mar 12 15:14:30 2010 +0100
toolchain: Remove STAGE_TEST from Naoki-Makefiles.
commit 161a772ff83ba0ac89b9487410d4cfd5c61a118c Merge: 5d5679bd75cd5e384772d0f4129919c4d0ee2288 0b1b2cc268c75c3167bc55ce68d1569fd838419e Author: Schantl Stefan Stevee@ipfire.org Date: Fri Mar 12 14:53:45 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 0b1b2cc268c75c3167bc55ce68d1569fd838419e Merge: c703f12341b1d2d6c1f605d7199e548c0aae4af0 94e0eb46449405853cf50faa51741b5532db9337 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Mar 11 20:26:12 2010 +0100
Merge remote branch 'ms/dracut'
commit 5d5679bd75cd5e384772d0f4129919c4d0ee2288 Author: Schantl Stefan Stevee@ipfire.org Date: Thu Mar 11 16:43:42 2010 +0100
dejagnu: New package.
commit c703f12341b1d2d6c1f605d7199e548c0aae4af0 Author: Christian Kampka chris@emerge-life.de Date: Thu Mar 11 16:26:07 2010 +0100
naoki: Create LOGDIR if it is not available.
commit a73dacebc30e2aa1d698ff98c0b066197403ffba Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Mar 11 16:24:13 2010 +0100
naoki: Use toolchain gcc, only.
EXPERIMENTAL.
commit 35ff2f2b4747ee8f49f5b5c1c893d8d0876aed93 Merge: e9601e77ba00769bdccd651c65a82cd5cd678201 c703f12341b1d2d6c1f605d7199e548c0aae4af0 Author: Schantl Stefan Stevee@ipfire.org Date: Thu Mar 11 16:20:11 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit e9601e77ba00769bdccd651c65a82cd5cd678201 Author: Schantl Stefan Stevee@ipfire.org Date: Thu Mar 11 11:59:40 2010 +0100
toolchain: Add installation of tcl-private-headers.
They are needed to compile expect.
commit b63236cf64038e77b51f382beebc7bcba647b94e Author: Schantl Stefan Stevee@ipfire.org Date: Thu Mar 11 11:46:38 2010 +0100
toolchain: Add new perl patches.
commit 1f452deaaf79a0f4d2332ed7df7b00835ea01c4b Author: Schantl Stefan Stevee@ipfire.org Date: Thu Mar 11 11:28:50 2010 +0100
toolchain: Remove crappy patches from perl.
commit aea407d9ad4bbd5a1422f0b04eab280cb04da7a9 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Mar 11 11:13:14 2010 +0100
expect: Enables native language support.
commit aac4e9830e709b43d4b831791b248e0b008931b3 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Mar 11 11:01:57 2010 +0100
expect: Fix build and replace crappy patches.
commit 8d6aacf72578b143b169b926aa610c5961e38e38 Merge: fc1e0b3f9ff3ba6bb7f42d05baec195e826562f7 a9e614fcb6d22bc44ed546a8c0af3bd3d9652f4f Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Mar 11 10:34:36 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit a9e614fcb6d22bc44ed546a8c0af3bd3d9652f4f Merge: bdbc504dda9e441477d38d524ed96ffb896fbd38 976a11de6c049f30ac79846d33481959de9b0877 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Mar 10 23:04:03 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit bdbc504dda9e441477d38d524ed96ffb896fbd38 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Mar 10 23:03:37 2010 +0100
expect: New package.
commit 942fcd72d2786acc120d29aa838f91de5806c9de Author: Schantl Stefan Stevee@ipfire.org Date: Wed Mar 10 23:03:10 2010 +0100
toolchain: Add expect.
commit fc1e0b3f9ff3ba6bb7f42d05baec195e826562f7 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 17:32:31 2010 +0100
pomona: New package.
commit 127e403c391230c5c7521df817a96b2fa002ac34 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 16:55:23 2010 +0100
Remove rootfiles.
commit 976a11de6c049f30ac79846d33481959de9b0877 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 16:45:12 2010 +0100
gcc: Add patch for optimized linking.
The GNU hash style is claimed to be faster in the end.
commit ae1ca48d06edd3b327f4642468aea1fad49331f2 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 13:10:26 2010 +0100
grub: Update to 1.98.
Fixes issue #498.
commit bebe2200879adf63be619585a54201692ee4cd2f Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 12:29:51 2010 +0100
flex: Add a gcc compile fix so we are able to run the testsuite.
commit 1bf02c8acc274939bbd92306472f728a8aa08703 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 12:17:43 2010 +0100
perl: Update to 5.10.1.
commit 21aee8f3e4f1035478607c9e936149c6c1f9d2ae Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 12:17:11 2010 +0100
zlib: Update to 1.2.3.8.
Just a beta release but provides several bugfixes.
commit 03778dc104d64bd4aa24e428cc5abf302a8311cf Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 11:33:07 2010 +0100
bison: Fix config.h settings which are now located in lib/.
commit f3ebebfe015940cd0e7edadd4a51eb8f6cdc56d9 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 10:43:13 2010 +0100
Remove bunch of lfs/ files.
commit 9f1e3542769ef2341c0894a0f2f4b3dec71c7bb7 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Mar 10 10:43:00 2010 +0100
patch: Update to 2.6.1.
commit f37bf989c51a8d7da9e81f06584b57b528a678d5 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Mar 10 09:37:52 2010 +0100
tcl: Fix installation of private-headers.
These are needed by expect to build.
commit c3b2a3a442ee413fcd60b316ef5473a080e72dd1 Merge: d7433b7e53a8b3df6fe40054e3ad9cfac3683b7c d9befb1f069508c627123644968371f53da65201 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Mar 10 08:54:49 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit d9befb1f069508c627123644968371f53da65201 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Mar 9 23:00:40 2010 +0100
tcl: Some cleanups on files.
Move testsuite from toolchain stage to package stage.
commit 16936334406a4f0358f10ecaf9b2726a6bce07e0 Merge: 75bd2cbf43561afc611be06c12b8b523637e7534 57226a8f5f4a9a55ba9a04a244a24bc8860280a1 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Mar 9 22:55:38 2010 +0100
Merge commit 'farnsworth/naoki' into ms-master
commit 75bd2cbf43561afc611be06c12b8b523637e7534 Merge: 4381818d4d698b73b45c6edc81f2c32db01e81ad 910997a08fd1023b44958d99da5bd82ea120e301 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Mar 9 22:34:51 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 57226a8f5f4a9a55ba9a04a244a24bc8860280a1 Author: Pampel Stefan stefan.pampel@ipfire.org Date: Mon Mar 8 15:36:30 2010 +0100
pango: update to 1.27.1
commit d7433b7e53a8b3df6fe40054e3ad9cfac3683b7c Merge: 910997a08fd1023b44958d99da5bd82ea120e301 4381818d4d698b73b45c6edc81f2c32db01e81ad Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 8 13:17:40 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 910997a08fd1023b44958d99da5bd82ea120e301 Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 8 09:26:05 2010 +0100
toolchain: Add tcl.
commit 85e9e99085c700fe4a32ea59a32c0287a65dbbd7 Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 8 09:25:41 2010 +0100
tcl: New package.
commit 94e0eb46449405853cf50faa51741b5532db9337 Merge: 76023cc05a69562f9ef2861ebc972364fcc3bda9 4381818d4d698b73b45c6edc81f2c32db01e81ad Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Mar 7 23:19:25 2010 +0100
Merge branch 'ms-master' into dracut
commit 76023cc05a69562f9ef2861ebc972364fcc3bda9 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Mar 7 23:18:40 2010 +0100
dracut: New package.
commit 4381818d4d698b73b45c6edc81f2c32db01e81ad Merge: 6e9d53126ca7bbfccf1831614a6069233401e1ba a024bc61ca1349e05cc5cbf857ccfd7fb5ef40c1 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Mar 7 23:16:34 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit a024bc61ca1349e05cc5cbf857ccfd7fb5ef40c1 Author: Schantl Stefan Stevee@ipfire.org Date: Sun Mar 7 18:25:31 2010 +0100
toolchain: Remove old patch for coreutils.
commit 81af952ef2e894bbb96649d6000b5c851825e2ca Author: Schantl Stefan Stevee@ipfire.org Date: Sun Mar 7 18:25:02 2010 +0100
coreutils: Clean makefile.
commit e260e2422ed6431585d8a223329e29f7eca15f11 Author: Schantl Stefan Stevee@ipfire.org Date: Sun Mar 7 18:23:53 2010 +0100
readline: Update to version 6.1.
* Add upstream patches.
commit 9f8135c73519dc877097a01ce31ce410f38c3fdb Author: Schantl Stefan Stevee@ipfire.org Date: Sun Mar 7 18:21:54 2010 +0100
bash: Update to version 4.1.
* Remove old upstream patch for 4.0. * Add new upstream patches for 4.1.
commit 430f1d02fa621cc885c2b70cefd6aef679167fb4 Author: Schantl Stefan Stevee@ipfire.org Date: Sun Mar 7 16:46:31 2010 +0100
libsoup: Update to version 2.29.91.
commit bf2d899a7a1b4d58adf806b4e4ff277feffa5c4b Author: Schantl Stefan Stevee@ipfire.org Date: Sun Mar 7 14:18:03 2010 +0100
psmisc: Update to version 22.10.
commit fb9738fe5642f09c3b250a364aa126728f52d95e Author: Schantl Stefan Stevee@ipfire.org Date: Sun Mar 7 14:14:25 2010 +0100
glib2: Update to version 2.23.4.
commit 2a790f511725486aa03c54acc694db70a44e5fe8 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Mar 5 19:58:04 2010 +0100
coreutils: Add updated patch also to toolchain.
commit 42ce981f9390c6b1076fa781af6336d712cc94fc Author: Schantl Stefan Stevee@ipfire.org Date: Thu Mar 4 14:45:55 2010 +0100
coreutils: Fix layout of makefile.
* Drop overwriting STAGE_BUILD * Add patch for pam support * Had to add autoconf and automake as BUILD_DEPS again.
commit 5b54ea9f05d7519611f7399ba5c7aad2a4fa6b9d Author: Schantl Stefan Stevee@ipfire.org Date: Thu Mar 4 14:44:38 2010 +0100
automake: Update to version 1.11.1.
commit d23e08294149059757b47c0cb5c7c6af0e50d51e Author: Schantl Stefan Stevee@ipfire.org Date: Wed Mar 3 15:58:49 2010 +0100
coreutils: Fix makefile.
Removed some deps, they arnÂŽt needed anymore. Removed Stage for autoconf. Removed some whitespace.
commit f9a74df45be14d3ec4a997afdfbd06a6c72287b5 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Mar 3 15:57:07 2010 +0100
coreutils: Update to version 8.4.
commit 9dfd48068d555720ead8b447eb6425dc84d7abf2 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Mar 2 09:56:39 2010 +0100
util-linux-ng: Update to version 2.17.
commit 0d6bdf9bc1b46f7584f1f926e43b7bab97729298 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Mar 2 09:32:36 2010 +0100
Delete unneded lfs files.
commit 1dc517d618ff8a3798ec3d4002b0e7bfc5b00ad4 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Mar 2 09:30:57 2010 +0100
gupnp-igd: New package.
commit 55a50755fbf6fd6425b1087997f79a2d81163536 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Mar 2 09:27:06 2010 +0100
gupnp-av: New package.
commit 9070a9f41c2df70a4f0b8ccc5c9a8e60be04a6e0 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Mar 2 09:23:13 2010 +0100
gupnp: New package.
commit 525c09ea79b60d828e5a986ad54ffe18388edea4 Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 1 15:35:37 2010 +0100
file: Update to version 5.04.
commit 5970f16f3f8250e8c95cc770e7eb115dad69e6dd Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 1 15:28:09 2010 +0100
gzip: Update to version 1.4.
commit f46ca8944b14901fe44806f4bd93a15dc6d7785b Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 1 13:04:37 2010 +0100
Delete unneded lfs files.
commit 5f50ae7beb36c4900ed12fdcee61e86307873593 Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 1 13:04:02 2010 +0100
gssdp: New package.
commit 1bc7f3ba3f1e1a1c0540dba22d038cb8fc7a0777 Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 1 13:02:25 2010 +0100
libsoup: Clean makefile.
commit 60d42395c1db3c38935df714111506462c065ae8 Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 1 12:57:04 2010 +0100
libsoup: New package.
commit 1f429f675850c6a37281fc8348a91b8b29cde097 Author: Schantl Stefan Stevee@ipfire.org Date: Mon Mar 1 12:35:00 2010 +0100
pdns-recursor: Drop directory /etc/init.d.
commit cabd7933b5087c1a95431963dfd9afcb38d83a3f Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 28 11:59:04 2010 +0100
Delete a bunch of unneedet lfs files.
commit 34daba8691df8a675c8c5f1ec999496f1c44c97d Merge: 2a9df94ecfb4d8cc2e15c788f3d8becdbe659d34 2c4841a58fde518b29dc10263a49f712c462f70b Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 28 11:58:20 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 2a9df94ecfb4d8cc2e15c788f3d8becdbe659d34 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 28 11:57:46 2010 +0100
librpcsecgss: New package.
commit 6e9d53126ca7bbfccf1831614a6069233401e1ba Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Feb 27 19:47:06 2010 +0100
Remove bunch of lfs files.
commit 2c4841a58fde518b29dc10263a49f712c462f70b Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Feb 27 00:56:08 2010 +0100
QA: Add /etc/{init,rc}.d to list of unwanted dirs.
commit e30dbe94a1f0526a8a087f890b396d96f6b3159e Merge: 0dcec9e0831dc55894ebf7b5a7f5b6c11cd00749 4a45d50985ffab1254f51485854556411da7c813 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Feb 27 00:10:57 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 4a45d50985ffab1254f51485854556411da7c813 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 23:58:55 2010 +0100
lm-sensors: New package.
commit 0dcec9e0831dc55894ebf7b5a7f5b6c11cd00749 Merge: 678c819457f03f254611e0f863afd679c80af3c6 892f578304a1c5a639143c47928b72854ddc70a7 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:55:06 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 678c819457f03f254611e0f863afd679c80af3c6 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:54:38 2010 +0100
logrotate: New package.
commit 8d889dd021cf49550c377be0763f352bd6435a9e Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:38:42 2010 +0100
Remove bunch of old files.
commit c017f784e762a1bb0fa733319193b21e92bb5b6a Merge: 237756286c6c5676486e5e8082ea23b2d52ef0ac a3869d0f0d90c06d2910a77ae54729d37ce006d7 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:37:43 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 237756286c6c5676486e5e8082ea23b2d52ef0ac Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:36:41 2010 +0100
naoki: Moved compressor to tools/.
commit f5b416065b77b821c92b2ecd42241e38cfbc6249 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:36:10 2010 +0100
pakfire: New package.
commit 892f578304a1c5a639143c47928b72854ddc70a7 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 23:34:32 2010 +0100
lsof: New package.
commit a3869d0f0d90c06d2910a77ae54729d37ce006d7 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 23:25:49 2010 +0100
nss_ldap: New package.
commit ebc11a869eeaf8ea0b9c4af52924b286314ace35 Merge: 68477864eba24cd9bf78160f42f2e6e8363a5ab9 fc65a79ef6bbe418433cbb17285ac8dd26fd3e22 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:23:52 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 68477864eba24cd9bf78160f42f2e6e8363a5ab9 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:22:43 2010 +0100
First try of automatic fix of libtool rpath bug.
commit 2ee4ca99a19481d9cdbf7a25921c965db0d09709 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:22:29 2010 +0100
xen: New package.
commit 8c1d1acbc70f23b5e5eeca6efb99c332139fc0a7 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 23:21:56 2010 +0100
qemu: Use libsdl.
commit fc65a79ef6bbe418433cbb17285ac8dd26fd3e22 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 23:12:40 2010 +0100
pam_ldap: New package.
commit fb7def71724b5a0af976cff8111200a40ee364b3 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 23:07:45 2010 +0100
noip: New package.
commit 66ded0eb6f3a66abc80efc45cb2461ece3275161 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 23:00:16 2010 +0100
nmap: New package.
commit 461f48a7c86f94fdd2f4108305d6e46c6c36ab3d Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 22:59:22 2010 +0100
sdl: New package.
commit 6d098e9c4bd8f5a63ee0a8dd6f3e79f1aaee64ec Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 22:55:40 2010 +0100
Delete old initscripts.
commit c1c8b40432f38e1beef7988f53250e63d2722d71 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 22:27:36 2010 +0100
freeradius: New package.
commit 48234d2448557b427dfc8ac4d3cfce9630e23fee Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 22:10:58 2010 +0100
lighttpd: New package.
commit 7b29fb2f2451954236e8fbc69bdbcb2cace626dd Merge: b65c4912863b7ec9a3abb303dd2b2a5282d338ad 0bcd6c9992d11c45b91cd989fb44aafe6f1a7204 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 21:50:02 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit b65c4912863b7ec9a3abb303dd2b2a5282d338ad Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 21:49:40 2010 +0100
Remove a bunch of lfs files.
commit fae6703dcfd0fba4e4c953c08581e22f6658bb72 Merge: 0eadabd07124e5562eeaba5ef1a0048f1b894dca 14e6100b7838ef71caac0f748a71158a7c429039 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 21:44:00 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 0bcd6c9992d11c45b91cd989fb44aafe6f1a7204 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 21:40:03 2010 +0100
libart: New package.
commit 0eadabd07124e5562eeaba5ef1a0048f1b894dca Merge: 60c92791279deecc04fc54cf68e06421b0cc0475 22285c944aabb20ff4c8ac596ca1537478dd9d9b Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 21:34:15 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 14e6100b7838ef71caac0f748a71158a7c429039 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 21:32:48 2010 +0100
l7-protocols: New package.
commit 60c92791279deecc04fc54cf68e06421b0cc0475 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 21:31:10 2010 +0100
quagga: New package.
commit cec39ce3b877d385093822e36452fe2edfdf10bd Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 21:29:59 2010 +0100
hplip: Clean makefile.
commit 22285c944aabb20ff4c8ac596ca1537478dd9d9b Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 21:19:02 2010 +0100
hplip: New package.
commit dac29d77336a26eb310da6cacbf0f211417e1b8c Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 21:18:43 2010 +0100
libvirt: New package.
commit ed0a9fda0db00b781e5bd2dc36b15208271b3857 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 21:15:51 2010 +0100
sane: New package.
commit 241e0cfde0ead12c97ab8df4c94635e967ba3635 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 21:13:42 2010 +0100
reiser4progs: New package.
commit d78ec79ab3f2c2243199bbb8f962cf3e80fe62e6 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 21:13:22 2010 +0100
libaal: Move libs to /lib.
commit ba3c15c901120c1cdb9523216680dd176863fca2 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 20:55:57 2010 +0100
ldapvi: New package.
commit 5587426c078a563572d4a078a61664d03b486cdf Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 20:09:42 2010 +0100
gnupg2: New package.
commit 2116f967036c0c1f79c69a64b06d21aea0b19207 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 20:06:02 2010 +0100
libassuan: Add shared library support.
commit 1d468e768f82a91628c94ce46abefd47bf09fc76 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 19:17:18 2010 +0100
libdnet: New package.
commit d4e4e4b18e547c0db53b9b587d33ecc3b6f4f1de Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 19:08:48 2010 +0100
libtiff: New package.
commit 7557e9f24aafd5f0f2c433843cdc4b370052058c Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 18:14:29 2010 +0100
joe: Remove unneeded PKG_DEPS.
commit ea140a2a01e21e120f6bfca42a1206d5ae020d6c Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 18:13:04 2010 +0100
joe: New package.
commit ffbb7ca2d499e95e0b211a768af50050fbe9da60 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 17:45:59 2010 +0100
net-snmp: Clean Makefile.
commit 8a0917c35b082369ec572722f491e4c5489737f0 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 17:29:55 2010 +0100
net-snmp: New package.
I had to disable the perl modules, because they have an unsecure RPATH and there isnÂŽt a patch to solve this issure.
commit a64c75a4300e2412ba22141cb26bf017f0fd44f9 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 26 16:45:30 2010 +0100
fuse: Add patches from old buildsystem.
commit 0fa27ae910bf441478aff8b1eeb7b63ea6920e22 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 15:42:28 2010 +0100
gdb: Clean Makefile.
commit 3b878b6f116bd7f25195f858d9cdf8bcebe7ecf2 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 15:33:20 2010 +0100
libjpeg: New package.
commit c588ad689b9a9c923525833618de2cb3be8a9a87 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 14:33:29 2010 +0100
ghostscript: Remove unneeded PKG_DEPS.
commit d073964651030bad1bc1308fb1b14012962f45e5 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 14:26:40 2010 +0100
gdb: New package.
commit 32a01e650f49bca3ba97195eaffe616c330e06e2 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 13:19:03 2010 +0100
ghostscript: New package
commit 9d7998925e9c4d5312db700290743e171f758f88 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 12:55:49 2010 +0100
libksba: New package.
commit 2d62f69d3dd0a37a8d5771ab50dfac3370416aed Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 12:55:07 2010 +0100
libassuan: New package.
commit 90cab50b2d37963aa47e547bb5fe384d7cdc6dc3 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 12:25:08 2010 +0100
pinentry: New package.
commit ce85b8d93cf0c5549ec61d93c05b71bef3b16784 Author: Schantl Stefan Stevee@ipfire.org Date: Fri Feb 26 12:07:13 2010 +0100
flex: Fix layout of makefile.
commit 4327af914d52573f26cbbb042290b465fbd8df7a Merge: 901bccc8929187c94187ee26b9e63b4a10f575ae f464ef1e4437dbb8e056db9b68157b2e38ebe5dd Author: Schantl Stefan Stevee@ipfire.org Date: Thu Feb 25 22:43:16 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 901bccc8929187c94187ee26b9e63b4a10f575ae Author: Schantl Stefan Stevee@ipfire.org Date: Thu Feb 25 22:38:33 2010 +0100
fuse: New package.
commit f464ef1e4437dbb8e056db9b68157b2e38ebe5dd Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 22:14:16 2010 +0100
squid: Fix layout of makefile.
commit 84a43fb51c19b3a09c11b61937f8ec77fa40e033 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 22:13:58 2010 +0100
smartmontools: Fix layout of makefile.
commit 470c9b835a13cce9934b8636a9cbef9f193666f7 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 22:13:39 2010 +0100
radvd: Fix layout of makefile.
commit c8f03aea8fcf1eae7134c2da86a5502b3174086c Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 22:12:09 2010 +0100
qemu: Fix layout of makefile.
commit e1b6e1531489b61ae4bee2386e387c57537682a8 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 22:10:26 2010 +0100
nfs-utils: Fix layout of makefile.
commit c2df8053ef715f05b8a046a0f82cc56f5f669e01 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 20:14:40 2010 +0100
vsftpd: General fixes.
Fixed dependency lists. Fixed naming of pam file.
commit c60fff478975d21da1cc27fc995eea674807bc97 Merge: 75216add761c0f7e055010f351fe0fc00d091e3b dc588ad3f91682346f1d308926327468f6f75630 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 20:08:10 2010 +0100
Merge commit 'trikolon/naoki' into ms-master
commit 75216add761c0f7e055010f351fe0fc00d091e3b Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 20:02:05 2010 +0100
etherwake: Add a line that make will respect our CFLAGS.
commit 18db5d939bd7a3e1be4299f3fae3b4661aa37355 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 19:58:29 2010 +0100
directfb: Add some more dependencies.
This enables some more functionality.
commit 294f5bb0c451732883b20d43911182869bae6e7a Merge: 51e30c0ae314a2d3d913fdb694e42681cd16043f 722abfbca88e5686fdf4b794a2f18ade0c194473 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 25 19:41:26 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit dc588ad3f91682346f1d308926327468f6f75630 Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 24 13:09:53 2010 +0100
New naoki file: radvd.
commit 2daaede6a682564d414725f781ab1255ed73a08c Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 24 11:44:17 2010 +0100
New naoki file: qemu (with kvm).
commit 4f9dda45a472659446dfda842e61cf748eeedc4f Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 24 11:07:17 2010 +0100
New naoki file: squid.
commit 722abfbca88e5686fdf4b794a2f18ade0c194473 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 23 23:31:02 2010 +0100
ez-ipupdate: New package.
I had to convert the ez-ipupdate-3.0.11b8-pidfile.patch from ( -Np0 ) to fit with the default naoki patching process ( -Np1 ).
commit 51e30c0ae314a2d3d913fdb694e42681cd16043f Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 23 23:29:04 2010 +0100
openssl: Disabled issetguid.
Disabled a change which let openssl require the issetguid function which was removed from glibc recently.
commit f4413fdffaabed46c4da766cf29f305c4249d7fe Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 23 23:15:20 2010 +0100
etherwake: Remove unneeded PKG_BUILD_DEPS.
commit 0b7a0ec77a21d4ea54676ba243d5da73f1f632f5 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 23 23:13:17 2010 +0100
etherwake: New package.
I had to create a patch for installing ethwake, because /usr/bin/install doesnÂŽt exist in naoki.
commit 86f7e98fab829422f945886ab6915a5617763064 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 23 22:49:13 2010 +0100
directfb: New package.
commit 9e52f66d486c816a071a90ba48590d380b7c1353 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 23 16:44:15 2010 +0100
libaal: Remove empty PKG_DEPS.
commit 7e9ae04a9676c05d876b9ca0559e0b720b9eb919 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 23 15:40:01 2010 +0100
libaal: New package.
commit b628bc33791e72925cab715a03a99f0a63336ca2 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 23 15:27:38 2010 +0100
reiserfsprogs: New package.
commit 18ca76c18d58e4b8037a9d8e0631e1273f3a3b44 Author: Benjamin Schweikert trikolon@ipfire.org Date: Tue Feb 23 13:15:40 2010 +0100
New naoki file: smartmontools.
commit a3c2fdf5442a940110006b34368651451ccf305b Author: Benjamin Schweikert trikolon@ipfire.org Date: Mon Feb 22 19:08:34 2010 +0100
New naoki file: vsftpd.
commit c1e16ca66dd1f6627091f9919ae7ae0df2d59a0f Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 12:35:20 2010 +0100
libtool: Update to 2.2.6b.
Fixes issue #517.
commit c7d282dcfd60b1151f2b515b191287bef0446ab8 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 12:28:37 2010 +0100
patch: Update to 2.6.
We had to drop the mkstemp patch. Maybe we'll find a replacement.
Fixes issue #519.
commit 1498748819f96cf68d3b6359f790d78e34b89f02 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 12:27:39 2010 +0100
autoconf: Update to 2.65.
commit cc0e4a4acb8c8b6bed60c2537a9d8fc23fb72413 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 12:00:44 2010 +0100
glibc: Update res_randomid patch.
commit 33df142fd42a6a3be2825939e77dd08df7350346 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 11:59:07 2010 +0100
glibc: Update random mk*temp() patch.
commit 6fdd3c6388f843690ff0992e1227871a64663af2 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 11:56:02 2010 +0100
glibc: Remove resolve_response_length patch.
This was fixed upstream.
commit 38a7b64b0a14b51325d51954bf7a3925dd675049 Author: Benjamin Schweikert trikolon@ipfire.org Date: Mon Feb 22 11:54:48 2010 +0100
New naoki file: nfs-utils with support for NFSv3 and NFSv4. Portmap is not needed anymore.
commit 4c501a6f7310ca7124017bf7b4d328ce2d273eee Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 11:54:37 2010 +0100
glibc: Remove the issetugid patch.
It's not safer than get*id.
The Glibc issetugid() patch is no longer used. issetugid() could be preloaded from a user-defined library, just like getuid() or getgid(), so issetugid() doesn't have any benefit. In BSD, and Solaris, issetugid() is a kernel syscall and is safer. In Linux we should use __libc_enable_secure(), which is similar, but requires packages to be patched. All packages should be searched for the issetugid() function, and modified to use __libc_enable_secure() instead.
commit 597ba387ce190df24c7aab2bcf66841acc1deaf4 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 02:08:24 2010 +0100
gcc: Update to 4.4.3.
Fixes issue #505.
commit 14c0f5dd3f78ff72c81d051b4f8bf9eb01b22885 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 01:52:09 2010 +0100
mpfr: Update to 4.2.4.
Fixes issue #524.
commit 2ea6a5944040fa7856511905b4b0e7aad0c76525 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 01:49:30 2010 +0100
gmp: Update to 5.0.1.
Fixes issue #545.
commit bceb6c91c36c7bc66b58700cb66e35c5d40a2dd3 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 01:37:52 2010 +0100
glibc: Update to 2.11.1.
Fixes issue #503.
commit 9f4ef23fd26d310da35ccf748f84aad750ed7c17 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:57:33 2010 +0100
Remove src/web.
commit 237315cac2d6e77ad77355836a1f7c066bb71c81 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:56:19 2010 +0100
Remove initscripts of packages we no longer need.
commit 81e96b7c36786a33d681f1242feea6d671deb679 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:55:38 2010 +0100
ulogd2: Install initscript.
commit 3aa03c472553671b9d632cbade209b0e49b1f052 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:55:08 2010 +0100
syslog-ng: Install initscript.
commit 54b6d563b879f07bbd159379a37f7d8e0f89394e Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:54:43 2010 +0100
rstp: Install initscript.
commit ad426e8e9b3c8f19a7513757744e0afb6f9a4e33 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:54:12 2010 +0100
pdns-recursor: Install initscript.
commit ca8785f6e29ad1d6f2a76144ea6292ef144ef969 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:53:24 2010 +0100
openssh: Install initscript.
commit f99a3eb0ee4a93426b63b5cd9b80719f481aac10 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:52:49 2010 +0100
openlldp: Install initscript.
commit e8e5f77f520b089d19c8e7d939a94bcd6b4db555 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:52:22 2010 +0100
openldap: Install initscript.
commit 884726f22e1f0238c87d847dc582b5dbd8554580 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:51:42 2010 +0100
ntp: Install initscripts.
commit 69d64e398bc12ac7d36866aaed486f26a4f4fd40 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:51:18 2010 +0100
network: Install initscript.
commit b2192287dae595193b3205c57a6e4e1072c77dc6 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:50:26 2010 +0100
firewall: Install initscripts.
commit 158674d8cf7776b89ca9c6598dc789ff0961b5a5 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:49:55 2010 +0100
cups: Install initscript.
commit b35b810e7fb4f09240ccb2f26352b7b9734f66eb Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:48:44 2010 +0100
initscripts: Fix version field.
commit a1e59f82f033db242857321b15d156f440d0f5db Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:45:28 2010 +0100
Remove old initscripts.
commit ccbe9281364f4dc12ac84f4253f666fed7821a04 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:44:55 2010 +0100
initscripts: New package.
commit 4ad90dc6e24e79b3f9cf83ec48e26f59f6be9feb Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:44:13 2010 +0100
udev: Install console_init script.
commit c2c5d034e89031c37603ba241d3540e535e27d61 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:41:32 2010 +0100
naoki: Add functionality for init/ directory.
One can put files to that directory that they will get copied to the packages by the naoki magic.
commit 1181e91134d67824ea535456cc1b2de981896f92 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:14:14 2010 +0100
Remove two unused scripts.
commit 23f61239fcddd7bb54974492a152d32f4b89dc33 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 22 00:10:16 2010 +0100
naoki: Automatically byte-compile python files.
commit 4b1540f8961b9411f20b95955511e91d55d34c90 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 23:02:46 2010 +0100
Remove a bunch of lfs/ files.
commit 5cc75971dc8b104e8899b4bef47a9073615c1ac4 Merge: 7166fe8441a8de1bb12ecf1b0b00db65f47a74ed 49b71a5618501e3446de0e7611eea308390d4db7 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 23:00:10 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 49b71a5618501e3446de0e7611eea308390d4db7 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 22:59:23 2010 +0100
pyfire: New package.
commit 30780b8a7a91ae438e0671868cebd7cedc0cee1f Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 22:52:02 2010 +0100
python-setuptools: New package.
commit 7166fe8441a8de1bb12ecf1b0b00db65f47a74ed Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 22:51:30 2010 +0100
naoki: Keep libpython2.6.a.
commit cfdb379ee5dfe3221bb94517f163e42876720980 Merge: 8230d2b9169ca8af4043b07ad0dd37228dcc2593 3d2c7b58086ab914b5ab29ea43a0856cff8360d1 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 22:43:04 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 3d2c7b58086ab914b5ab29ea43a0856cff8360d1 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 22:38:58 2010 +0100
python-pyblock: New package.
commit 8230d2b9169ca8af4043b07ad0dd37228dcc2593 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 22:31:30 2010 +0100
naoki: Speedup dependency resolution.
commit ecf0da53ea80435c5a2443f3281a51aa90247eea Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 22:27:57 2010 +0100
python-tornado: New package.
commit 4f9627bf481d73afc518cbd8dc702d4b21acca80 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 22:21:39 2010 +0100
python-urlgrabber: New package.
commit 476b15a5b98c778506bf3c32557ca4be5e6dfcfa Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 22:14:04 2010 +0100
python-parted: Correct spelling of pkg-config.
commit 1cf1b9ffbbaff60d80e523c2aab3a92db73b9b2d Merge: 5803e462ec1176b33ad0310015c708ba4716d91f 19a2bdb8300cf271ebeec311c62f9c1943b7d641 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 22:11:15 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 19a2bdb8300cf271ebeec311c62f9c1943b7d641 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 22:10:21 2010 +0100
python-parted: New package.
commit a7d4b011fb99946915989057da09cd6b1b374a00 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 22:05:41 2010 +0100
parted: Update to 2.1.
python-parted has a dependency to parted 2.1.
I also add patches to fix security problems and add new features.
commit 5803e462ec1176b33ad0310015c708ba4716d91f Merge: 6e4585b7915a3ae63a836ed717d7db636e4bb860 748010da512b8c088df5abe8c18286d75403a4ef Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 22:05:28 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 6e4585b7915a3ae63a836ed717d7db636e4bb860 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 22:03:53 2010 +0100
sysvinit: Explicitely link libcrypt.
commit 26f1d2525525bb9104730118757481181543f1dc Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 22:03:24 2010 +0100
libgssglue: Cleanup makefile.
commit fac43376241191fc29e1c2442c1f1e2a194b38bb Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 22:03:10 2010 +0100
libevent: Cleanup makefile.
commit 19d5147c0d7c807323213190161dc9bc075cb95b Merge: cde35c12ec0fc71d707dfd32d5d84b74070193e8 303cd42616028d9faacf46248a1af84e1724c80a Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 21:49:11 2010 +0100
Merge commit 'trikolon/naoki' into ms-master
commit 303cd42616028d9faacf46248a1af84e1724c80a Author: Benjamin Schweikert trikolon@ipfire.org Date: Sun Feb 21 22:31:21 2010 +0100
New naoki file: libgssglue.
commit 68ed541b4859489bdf5da9cf84140c58bee4b270 Author: Benjamin Schweikert trikolon@ipfire.org Date: Sun Feb 21 22:12:26 2010 +0100
New naoki file: libevent.
commit cde35c12ec0fc71d707dfd32d5d84b74070193e8 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 21:47:11 2010 +0100
Remove pam.d installation from a number of packages.
commit 8fbce299396c622a22f96e67a168913cdf1deb83 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 21:43:59 2010 +0100
naoki: Add support for pam.d directory as well.
commit a4700168d48cd6fcd0a3328654d95770be668727 Merge: d4f42b7b3d62a24df02772defc9667b9773bc8e4 9b953fc33747c442c3ceac5a840afc7e02ddcfb6 Author: Benjamin Schweikert trikolon@ipfire.org Date: Sun Feb 21 21:40:58 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 75b075ab606fcaf559f7332fee92f74edf51a4d7 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 21:23:32 2010 +0100
naoki: Automatically install initscripts and pam files.
commit d4f42b7b3d62a24df02772defc9667b9773bc8e4 Merge: fe1ed6a4940da8508c51bd76123c56dfb77aef57 7e774a27c69df36dafc00786370376fc78c18bfa Author: Benjamin Schweikert trikolon@ipfire.org Date: Sun Feb 21 21:11:36 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 6ec2e552ab197e64af15e32de75e2725489137ef Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 21:04:02 2010 +0100
python-decorator: New package.
This is a dependency of python-parted.
commit fe1ed6a4940da8508c51bd76123c56dfb77aef57 Author: Benjamin Schweikert trikolon@ipfire.org Date: Sun Feb 21 20:58:23 2010 +0100
New naoki file: squashfs-tools.
commit f44d97d8b56362e526354e0ae35e763879d2739f Merge: 60603291972e6ad83dcd48d2ff7356bedd8646bb 9b953fc33747c442c3ceac5a840afc7e02ddcfb6 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 20:42:40 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 9b953fc33747c442c3ceac5a840afc7e02ddcfb6 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 20:41:36 2010 +0100
naoki: Fix configuration of nice level.
commit 60603291972e6ad83dcd48d2ff7356bedd8646bb Merge: fd99b00c66f90bf6f9126c376d0c78d6698af83e b6d4e5722529dfa334793784c0aa2e9a0a55a4a9 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 20:40:24 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit b6d4e5722529dfa334793784c0aa2e9a0a55a4a9 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 20:35:20 2010 +0100
Revert "naoki: Validate package directories."
This reverts commit 7e774a27c69df36dafc00786370376fc78c18bfa.
commit fd99b00c66f90bf6f9126c376d0c78d6698af83e Merge: 748010da512b8c088df5abe8c18286d75403a4ef 7e774a27c69df36dafc00786370376fc78c18bfa Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 20:29:05 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 26ca37e2ffb17b180d460cd4e37197922f46e441 Author: Benjamin Schweikert trikolon@ipfire.org Date: Sun Feb 21 20:02:51 2010 +0100
New file: sysvinit.
commit 7e774a27c69df36dafc00786370376fc78c18bfa Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 20:00:21 2010 +0100
naoki: Validate package directories.
They must contain a naoki makefile with correct extension, etc.
commit 2c1259eada84ab5c395d05c07abe621108081099 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 19:50:05 2010 +0100
naoki: Make nice level configureable.
commit 748010da512b8c088df5abe8c18286d75403a4ef Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 19:27:30 2010 +0100
pychecker: New package.
commit a9e524a114fedc04f791ade5390d67fd19549cef Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 19:18:16 2010 +0100
python-cryptsetup: Fix install flag.
commit 649f4e94393e1708a9355e3e65ad0fa6abb6753d Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 19:16:24 2010 +0100
python-IPy: Fix install flag.
commit 4d057ce666af88a655929baf77f30dce50375eb8 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 19:14:43 2010 +0100
python-netfilter_conntrack: Fix install flag.
commit 9a53e5681eab5b4ad020ec340e35cb44ec2d3c52 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 19:07:04 2010 +0100
Remove bunch of old lfs files.
commit 4cce714849ca4c2f68314bf7aa70522fe766980b Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 19:06:05 2010 +0100
naoki: Add STAGE_CONFIGURE_CMDS.
commit b4e8e2fd85cd0839d15e49f7d79039bdaaf0835d Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 18:49:35 2010 +0100
sysfsutils: Remove unnecessary lines.
commit 018b711c7ba31d2b75b37d4e5322d28ace2dd601 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 18:48:59 2010 +0100
strace: Remove unnecessary code.
commit 7ce06e41cc2f7463033f49c5a438490970f62d09 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 21 18:46:30 2010 +0100
xfsprogs: Fix package.
Remove rpath, fix whitespace.
commit 8cb3c9a1a9c70694cbd43c724c367bb2c808bc04 Author: Benjamin Schweikert trikolon@ipfire.org Date: Sun Feb 21 18:31:15 2010 +0100
New file: strace.
commit ec4c6d1fa395d019a31520d094f9cc1e1faebd5c Author: Benjamin Schweikert trikolon@ipfire.org Date: Sun Feb 21 18:22:32 2010 +0100
New file: sysfsutils.
commit acba165f21f45bb0cd34b077147e3f4f0debe939 Author: Benjamin Schweikert trikolon@ipfire.org Date: Sun Feb 21 18:02:30 2010 +0100
New naoki file: xfsprogs.
commit 781388ec655a843c6c368487bef654473e3e555e Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 17:58:49 2010 +0100
python-netfilter_conntrack: New package.
commit c2565943cec2b91275cb9b34d5e03482d4870ad4 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 17:52:53 2010 +0100
python-IPy: New package.
commit cd3207f7c3527468732f924a742ebd2a06996c30 Author: Stefan Schantl Stevee@ipfire.org Date: Sun Feb 21 17:40:24 2010 +0100
python-cryptsetup: New package.
commit 9b41f0161592e78f202850fd7f3676304ef4632c Merge: 7422f961cec38f8d853fda396d3c80524483b5f0 5e08795846d0328d92f5ba16d35f8cc26afadf12 Author: Stefan Schantl Stevee@ipfire.org Date: Fri Feb 19 19:00:00 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 410e399c982991c45ae4b1daaa9e679e3f60b9f5 Merge: 8d3c48bd116ed68c05319290578c8b6acc8bfea8 5e08795846d0328d92f5ba16d35f8cc26afadf12 Author: Benjamin Schweikert trikolon@ipfire.org Date: Fri Feb 19 18:54:49 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 5e08795846d0328d92f5ba16d35f8cc26afadf12 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 19 16:35:47 2010 +0100
mdadm: New package.
commit 2f3072adc3bca66ca77e8182f3ab3e99882f28ac Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 19 15:34:06 2010 +0100
hostapd: New package.
commit 7422f961cec38f8d853fda396d3c80524483b5f0 Merge: ef88927e0701cf07d11ca7a724175beb19b18ebc a95d2c4331bfcb483a8e5f417368c5b1e3430d8d Author: Stefan Schantl Stevee@ipfire.org Date: Fri Feb 19 13:17:53 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit a95d2c4331bfcb483a8e5f417368c5b1e3430d8d Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 18:03:56 2010 +0100
naoki: Add possibility to extend STAGE_BUILD.
commit 9b2d1bdeb43108568430b35e32994f80408a3525 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 18:03:36 2010 +0100
dosfstools: New package.
commit 717626ea7056e4bc3d2b900e047abd5aeabc8ef3 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 17:36:28 2010 +0100
dmraid: New package.
commit 6327ff5c90bb0416b66d7902a6065379d9ed58e5 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 17:04:40 2010 +0100
Remove bunch of old lfs/ files.
commit 717ba96071e21b79313b79dee7214e8c720d45b0 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 17:02:56 2010 +0100
ntp: New package.
commit ef88927e0701cf07d11ca7a724175beb19b18ebc Merge: df6d38a95b1b260e6fc30c10a9d897bdd7bc2c28 cd25aed34787136d304ab33adbaa45ef94756628 Author: Stefan Schantl Stevee@ipfire.org Date: Thu Feb 18 16:59:45 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit eba973e45b04d47abab024011f3e5a29f6937728 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 16:38:57 2010 +0100
wireless-tools: New package.
commit cd25aed34787136d304ab33adbaa45ef94756628 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 16:24:25 2010 +0100
QA: Check for /usr/var which should not be there.
commit 3961710fad9c8e0cc23b00cdc889eaa89552700b Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 16:24:07 2010 +0100
mc: New package.
commit b534427f7bc775e9a1419030a0e6fba6ce463a95 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 16:23:30 2010 +0100
samba: New package.
commit ac082136a8c3f3bcbd944a9d2c9964dbc693e5dd Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 15:54:11 2010 +0100
openvpn: New package.
commit 6a7d8ce82d50e6fa29ac7af8dd2e8c477b7e8117 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 15:42:53 2010 +0100
openlldp: New package.
commit e45ebea0970d065df89d2aad89644cbbcea4b770 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 15:26:03 2010 +0100
man-pages: New package.
commit 8d3c48bd116ed68c05319290578c8b6acc8bfea8 Merge: 535f062ea8729b350584793422f6c6b1b54e8f6c ef6bbaf7c641c2b2b31a6402f4642d3b27c08510 Author: Benjamin Schweikert trikolon@ipfire.org Date: Thu Feb 18 15:00:50 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit d02dcfea36d154f93624c2d5a2778569322c784e Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 14:56:03 2010 +0100
jwhois: New package.
commit 535f062ea8729b350584793422f6c6b1b54e8f6c Merge: 99e90707cf2cd4ba7d9b563d009426e477114d82 0a82a148ca3feef3fc84f316a9246cce427ef5d7 Author: Benjamin Schweikert trikolon@ipfire.org Date: Thu Feb 18 14:49:39 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit d3799bb38e6aace72b689cb0c68afa10b4d43290 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 14:16:37 2010 +0100
iw: New package.
commit e1d1dae58a3586973ddadc0991fac4c085a74b4b Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 14:16:23 2010 +0100
libnl: New package.
commit ef6bbaf7c641c2b2b31a6402f4642d3b27c08510 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 14:00:40 2010 +0100
toolchain: Remove old patches in binutils{,-static}.
commit 0a82a148ca3feef3fc84f316a9246cce427ef5d7 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 18 11:30:42 2010 +0100
expat: Move lib from /usr/lib to /lib.
commit 99e90707cf2cd4ba7d9b563d009426e477114d82 Merge: c38ab1cb4b8a00206987ece11b71f9bdc8d6ff53 db562de1a8f28d7a98843866cabe5898d3f00083 Author: Benjamin Schweikert trikolon@ipfire.org Date: Thu Feb 18 10:55:17 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit df6d38a95b1b260e6fc30c10a9d897bdd7bc2c28 Merge: 56dbdbffefee9cc7533b8b786ca9a4eed6a7512e db562de1a8f28d7a98843866cabe5898d3f00083 Author: Stefan Schantl Stevee@ipfire.org Date: Thu Feb 18 10:25:48 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit db562de1a8f28d7a98843866cabe5898d3f00083 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 23:02:30 2010 +0100
Remove a bunch of old lfs/ files.
commit c63b1910f31bf7b3b69d8a4a3ee7b17066e8ad28 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 22:53:44 2010 +0100
Fix libxyz.so links of cryptsetup-luks, libgcrypt and libgpg-error.
commit 498182e85b7cf5644d5a56543cf31a77887b9a26 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Feb 17 22:38:52 2010 +0100
libgcrypt: Fix library location.
commit 31d21d7a049a46bdcab44892ff5ac1f44964c191 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Feb 17 22:37:57 2010 +0100
libgpg-error: Fix library location.
commit 525c766adabd8ec98769c6cc159b77946364d9a0 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 22:30:37 2010 +0100
QA: Check files in /lib for linking to /usr/lib as well.
commit c54d7b004b2a0417239bb290a1b1ad36ad8776eb Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 22:25:42 2010 +0100
QA libs-location: Do not print error message when /lib is not existent.
commit 842b51011ac8660d3bd3ceb9d5136eadf0eb03e5 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 22:22:20 2010 +0100
flex: Remove whitespace.
commit 24978601ff52f3b2a6551fe97be222a365e5e105 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 22:22:03 2010 +0100
cryptsetup-luks: Remove whitespace.
commit 8159aa56ceadc5bcd6f9cfb2a5f37ecf7a7dd654 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 22:19:05 2010 +0100
popt: Remove libpopt.so in /lib.
commit 30cb2c66c4686c800748bb27e62661cc06004ee6 Merge: a873f0b3512b1f0d673e5d5ea72f166f44795af3 eddf5986f419fb186469c6b462ca0d6c27a21d5f Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 22:16:18 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit a873f0b3512b1f0d673e5d5ea72f166f44795af3 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 22:15:38 2010 +0100
cups: Cleanup makefile.
Add dependencies. Fix installation of files.
commit f47b3fcf6e03359463efdc3de02ad7f7196c3473 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:59:10 2010 +0100
bwm-ng: Remove PKG_DEPS field.
commit 4861cb8539fe787d6957055666afbd9e1a872d02 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:58:00 2010 +0100
btrfs-progs: Remove whitespace.
commit eddf5986f419fb186469c6b462ca0d6c27a21d5f Merge: 11c61e233fbcf068e9ba918597d81bc047fbaf66 10dc4c8b76bf5a9c96313b01d83ed86caea84243 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Feb 17 21:56:57 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 11c61e233fbcf068e9ba918597d81bc047fbaf66 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Feb 17 21:56:23 2010 +0100
cryptsetup-luks: New Package.
commit 240e77475d2f1c2733b8043b2e833d9b20b55266 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:56:02 2010 +0100
beep: Remove whitespace.
commit 871f318c301a936e834054c49b4a8a6cca49c9fb Merge: 10dc4c8b76bf5a9c96313b01d83ed86caea84243 c1243c0fa72dc8675342f34f1d0b120cf2bad99c Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:50:54 2010 +0100
Merge commit 'stevee/naoki' into ms-master
commit 10dc4c8b76bf5a9c96313b01d83ed86caea84243 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:50:06 2010 +0100
aiccu: Cleanup makefile.
Remove empty directories.
commit 5229d8063d835cadfe878006cc2f4770cc88642f Author: Schantl Stefan Stevee@ipfire.org Date: Wed Feb 17 21:43:38 2010 +0100
popt: Fix librarie place.
commit 5bd93380c7d2f1c4b9e3e93d9ceb94f99634712a Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:41:17 2010 +0100
avahi: Cleanup makefile.
commit e350936dc8b2508faf77fd9d9d2a3ce6b8bdaf13 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:32:09 2010 +0100
intltool: Cleanup makefile.
commit 9578a7c41746730548befb69631f4da45ac3c658 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:28:09 2010 +0100
hdparm: Fix installation of files.
commit f0d6c1d8709c3c7b495cc1cd88e4303cbb893a88 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:22:29 2010 +0100
libdaemon: Cleanup makefile.
commit ea81dc52ce730d81ea3d505c5018913716f2beff Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:20:08 2010 +0100
perl-xml-parser: Cleanup makefile.
Add a comment to remove that bad rpath.
commit bf6b1956454db13f472c4f0f891f838b4d22a22b Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:13:59 2010 +0100
python-dbus: Cleanup makefile.
Remove all that code. Fix dependency list.
commit 3a164556640d5b8f37542e9064ddc9532012ebef Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:12:01 2010 +0100
traceroute: Cleanup makefile.
Fix usage of CFLAGS. Fix installation.
commit f11938201edd6a3fb5a12706fbbab00bf8ff3792 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 21:07:33 2010 +0100
unzip: Fix usage of CFLAGS.
commit f379db63f7d03f369985fd936f814742ba07b22c Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 20:56:21 2010 +0100
unzip: Cleanup makefile.
Remove PKG_DEPS which is empty. Respect our 80 coloumns limit.
commit 7850a5cbf4fb523903750a77ece5f7d4bc165034 Merge: 8ad0a97ae8e23d5a3c92a7b92d0c5f7a73170a19 53d528c1c158ffd8b804ad5f75af718eb1fb4660 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 20:50:03 2010 +0100
Merge commit 'trikolon/naoki' into ms-master
commit 8ad0a97ae8e23d5a3c92a7b92d0c5f7a73170a19 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 17 20:48:03 2010 +0100
udev: Fix an absolute symlink.
commit c38ab1cb4b8a00206987ece11b71f9bdc8d6ff53 Merge: 53d528c1c158ffd8b804ad5f75af718eb1fb4660 dff83f45bd2e625530b4364d49385424dbed1715 Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 17 20:28:24 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 53d528c1c158ffd8b804ad5f75af718eb1fb4660 Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 17 20:26:00 2010 +0100
New naoki file: hdparm.
commit c1243c0fa72dc8675342f34f1d0b120cf2bad99c Author: Schantl Stefan Stevee@ipfire.org Date: Wed Feb 17 20:20:23 2010 +0100
cups: New Package.
commit 74c7ceb62e83783060f4a8365efc0587ff25dd6a Author: Schantl Stefan Stevee@ipfire.org Date: Wed Feb 17 19:32:25 2010 +0100
btrfs-progs: New Package.
commit 79cd837f4b3ac8191b0bc88143aab2c88ac144b3 Merge: 9af998a96f7e4a4c16c4e38fc248741654498d11 dff83f45bd2e625530b4364d49385424dbed1715 Author: Schantl Stefan Stevee@ipfire.org Date: Wed Feb 17 14:22:09 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit c14dcd085d6d6939c514ed7a712ff1e7f14bf4aa Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 17 13:39:11 2010 +0100
New naoki file: traceroute.
commit 20003b56dc818079d16d154db981baf2c7bddb82 Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 17 13:18:17 2010 +0100
New naoki file: unzip.
commit dff83f45bd2e625530b4364d49385424dbed1715 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 16 22:40:10 2010 +0100
libcap: Fix installation of libcap.so.
commit 3e91aa00f6c0fad93896540fcd4b3e623302972b Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 16 22:39:37 2010 +0100
python: Cannot delete expat.
commit 95d3e551c7d23d8d2a3c0033019d9b772ee31f68 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 16 22:00:23 2010 +0100
python: Update to 2.6.4.
commit 186c2d61592faa586e678a6f9c67d4ec3bde1fc6 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 16 21:31:41 2010 +0100
gdbm: New package.
commit 6d2512d4bff64a59896b43e4c9eb6572a8fa4ad3 Author: Benjamin Schweikert trikolon@ipfire.org Date: Tue Feb 16 13:56:34 2010 +0100
Fixed avahi.
commit 40c6b5f010c68e428818ea166e703257e0beff55 Author: Benjamin Schweikert trikolon@ipfire.org Date: Tue Feb 16 13:56:06 2010 +0100
New naoki file: python-dbus.
commit c4c82e621949cfaf86095309cb0ea7e7b0f33592 Author: Benjamin Schweikert trikolon@ipfire.org Date: Tue Feb 16 13:55:40 2010 +0100
Fixed libdaemon.
commit a43ff0e8c22897658136ac4268357e9b557a90d5 Author: Benjamin Schweikert trikolon@ipfire.org Date: Tue Feb 16 12:25:27 2010 +0100
New naoki file: intltool.
commit 41c38166f2719c990e93c67fb797d8923d463644 Author: Benjamin Schweikert trikolon@ipfire.org Date: Tue Feb 16 12:24:55 2010 +0100
Fixed perl-xml-parser.
commit 9af998a96f7e4a4c16c4e38fc248741654498d11 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 16 12:21:19 2010 +0100
beep: Fix install location of the man-page.
commit 801ffdb7dc5317b0fac39857f0746e71d64d536d Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 16 12:19:48 2010 +0100
bwm-ng: New package.
commit 7595c7f77da4527a73cfd8da411673b223a8d121 Author: Schantl Stefan Stevee@ipfire.org Date: Tue Feb 16 12:12:07 2010 +0100
beep: New package.
commit bf0a85d5a07d6052cd9749b853051a54042a96a3 Merge: 2767b51a95a345a2aaa35d4bf0971ac532141802 e8bda3eb3504fd0c9e07af8cd99426249603e224 Author: Benjamin Schweikert trikolon@ipfire.org Date: Tue Feb 16 07:34:06 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 56dbdbffefee9cc7533b8b786ca9a4eed6a7512e Merge: e8bda3eb3504fd0c9e07af8cd99426249603e224 683ab74070c3d0ed6394370f576091bc5436537d Author: Stefan Schantl Stevee@ipfire.org Date: Mon Feb 15 20:36:34 2010 +0100
Merge branch 'naoki' of ssh://git.ipfire.org/pub/git/people/stevee/ipfire-3.x into naoki
commit 7140f08c116a96e6a532b354acafbc79e199c0d6 Merge: 683ab74070c3d0ed6394370f576091bc5436537d e8bda3eb3504fd0c9e07af8cd99426249603e224 Author: Schantl Stefan Stevee@ipfire.org Date: Mon Feb 15 20:34:01 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 2767b51a95a345a2aaa35d4bf0971ac532141802 Author: Benjamin Schweikert trikolon@ipfire.org Date: Mon Feb 15 20:16:31 2010 +0100
New naoki file: avahi.
commit fba493cecfc510cdb2a4cdda8bb4171286c3b69c Author: Benjamin Schweikert trikolon@ipfire.org Date: Mon Feb 15 20:16:05 2010 +0100
New naoki file: perl-xml-parser
commit 683ab74070c3d0ed6394370f576091bc5436537d Author: Schantl Stefan Stevee@ipfire.org Date: Mon Feb 15 20:00:55 2010 +0100
toolchain: Add patch for building glibc with binutils 2.20.
commit e8bda3eb3504fd0c9e07af8cd99426249603e224 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 15 19:55:34 2010 +0100
lvm2: Fix installation of libraries.
commit 6765d3654bc5adc1bb72dd9cdc7350319b3aa542 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 15 19:55:03 2010 +0100
paxtest: Whitelist paxtest binaries.
They contain illegal stuff but this is needed for testing.
commit 988149181482874744a26ac7ec2fc5b16450cea5 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 15 19:53:52 2010 +0100
kernel: Remove two absolute symlinks that are not needed.
commit 6a4abde3d8b51f81d0983ae486009229842dbe4b Author: Benjamin Schweikert trikolon@ipfire.org Date: Mon Feb 15 19:20:29 2010 +0100
New naoki file: libdaemon.
commit a2d0737191ac3b5e3ce7c7e8132c8144cd496aeb Author: Benjamin Schweikert trikolon@ipfire.org Date: Mon Feb 15 19:12:05 2010 +0100
New naoki file: aiccu.
commit b4fd54bc9e8e9785af5108534d1a6bdb2a0ba2a6 Author: Schantl Stefan Stevee@ipfire.org Date: Mon Feb 15 17:28:19 2010 +0100
toolchain: Apply updated binutils patch.
The patches for the new version of binutils were missing in the toolchain sektion.
commit 51673b9d6275d4033485bc8fd820fc6031f7f7ef Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 15 13:34:51 2010 +0100
iptables: Some build fixes.
Fix linking of libxtables.so.
Fix an absolute symlink.
commit e460d6ed71bf41c98222b44d503a50f6a45540d6 Merge: fa44e2f58864ddb88b3dd6fdac540b63e9bda30e 94093c5cbd84e5560790a3cd897f41d0a6b7e193 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 23:49:08 2010 +0100
Merge remote branch 'ms/master'
commit 94093c5cbd84e5560790a3cd897f41d0a6b7e193 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 23:36:01 2010 +0100
glibc: Add patch to build with binutils 2.20 and higher.
commit 8a346372e18753546662e0c3bcbfd8248eb7c2ac Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 23:35:40 2010 +0100
glibc: Fix a very weird issue with rpath.
commit fa44e2f58864ddb88b3dd6fdac540b63e9bda30e Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 23:18:01 2010 +0100
rrdtool: Fix rpath in python module.
commit c784f95fe686f5c41222a07221ab0104b7b4ee4f Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 18:16:05 2010 +0100
binutils: Update patches.
commit 1e8a99d9d0004f335afb6763cf75a4b48ef8a318 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 18:15:37 2010 +0100
QA: Disable soname check.
Doesn't always work as expected.
commit 32991121223bdb0c26a4b27678626423c35d1abb Merge: b55e2b81d22a55ab9e71b8ba79861dcd265dcb52 e67445f39e39f4930114e65bdc5d428b9b87d9a2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 17:23:18 2010 +0100
Merge branch 'updates' into ms-master
commit b55e2b81d22a55ab9e71b8ba79861dcd265dcb52 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 16:37:07 2010 +0100
libnih: Fix installation of libs.
commit fafd7a277d724d06fe2999c42e8ca3c271821eb6 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 16:07:58 2010 +0100
QA: Fix libs-location check.
Was searching in the wrong directory.
commit 20c0eb22543a32f62ccc66878e1616fdb494831a Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 15:39:37 2010 +0100
QA: New check that points out missing libary links.
commit 8ebb7b5cb3cad369eecccaf4ed31d23a791d2b00 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 15:25:24 2010 +0100
QA: Check for absolute symlinks.
commit 808707d743bd60aaf94113f381f8a91a96e2339f Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 15:15:42 2010 +0100
QA: New checks for libraries.
Check for NEEDED and SONAME attribute and raise an exception if they are lacking.
commit 532f1984756637a9bd36a03852e4b525f3f268a2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 14 15:03:50 2010 +0100
QA: New check that finds bad rpaths.
commit 9ebbb035716ee83955829e6e5a6689b2c2ceddf1 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Feb 13 12:59:24 2010 +0100
grub: Install man pages in correct path.
commit 12227ac87c18d93d3a7d06026fcd3f6da5d172c3 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Feb 13 12:40:02 2010 +0100
QA: New check for executeable stacks.
Files with executable stacks will not work properly.
commit 66ac31c3027fbc8bd2eb0ab82b0633622ddb53a0 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 22:48:44 2010 +0100
Remove bunch of old files in lfs/.
commit 301a3ede509763405b2ffdc4a43fd56df6b5febd Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 22:43:39 2010 +0100
rrdtool: New package.
commit 4eb8152c05aa8ffdacf26cbc7b15b3935e2fab4d Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 22:43:28 2010 +0100
pango: New package.
commit f9727f8b6be60b8d5cc829e724634431a4191b6b Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 22:23:49 2010 +0100
cairo: New package.
commit de396a63b975de9c06f838b457093c573fea914e Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 22:21:52 2010 +0100
fontconfig: New package.
commit b8e9f5907f468ea62b5afd2372596c1330a08024 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 22:15:53 2010 +0100
freetype: New package.
commit ff281aef0a31d16e69ddaa304f6f27af6213384c Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 22:11:12 2010 +0100
pixman: New package.
commit 2e2abafcf06deca2c089307dba40dfcddf4e78dc Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 21:51:49 2010 +0100
libpng: New package.
commit 974d3e9bfe034d305bf243fbcf0832145630ec88 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 21:43:55 2010 +0100
pptp: New package.
commit fa4c11b53281eba1bee90d298b9ff61dfb64992b Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 20:38:16 2010 +0100
ppp: New package.
commit c6a74bfb134da0bc5198ec6027f55467032b09bd Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 01:33:59 2010 +0100
strongswan: New package.
commit 2f676e6e724a7fc25bf9fc28ba2623d38aa28520 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 01:33:38 2010 +0100
naoki: Create user "nobody" in chroot.
commit 957db558ea18b43cd4fec42250466cf3531ef569 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 01:00:01 2010 +0100
sudo: New package.
commit 73b430376403ab7bb36135b1ef6af0ded02839e0 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 00:59:36 2010 +0100
chroot: Link /bin/mv to the toolchain's one.
commit 615e15c66019847a32d5bf10c8b9e072c061917f Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 00:24:20 2010 +0100
acl: Enabled support for NFSv4 via libnfsidmap.
commit 6498acf0979c2929b83dc61b46b3b2b8d4f124e7 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 00:24:06 2010 +0100
libnfsidmap: New package.
commit 175c1868ad12192279fa606d040907b55e993ebc Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 12 00:23:05 2010 +0100
pakfire: Fix for packing unresolved symlinks.
commit 395b8b6dca917627b6ef83c7712763d3901b3610 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 16:24:56 2010 +0100
parted: New package.
commit 49ff56a705405b9624d0979ac473599e4fe63e47 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 16:24:41 2010 +0100
lvm2: New package.
commit 488a92f6a2bef34737d43fd16aa1501146119a20 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 14:24:41 2010 +0100
newt: New package.
commit c6c5178b1595e7786b80ade5eb246e4b3e452c51 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 13:56:27 2010 +0100
chroot: Link /bin/ln to toolchain.
commit 5d02988fe6a53787d358023034b8c7db457b5b47 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 13:56:10 2010 +0100
slang: New package.
commit ab6e2138c0a72901cfde22bf062ffac817b9215c Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 12:51:41 2010 +0100
ulogd2: New package.
commit 5faa8aeb76d3ff72db6acc6c55d67e7ce9037671 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 12:46:53 2010 +0100
pdns-recursor: New package.
commit 5de506b36333d65a2d00a5b0f07e104b6dca7a0c Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 12:22:54 2010 +0100
libnetfilter_queue: Move files from /lib to /usr/lib.
commit 517b18949c4bf354a8052939ba9010f04e186d4c Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 12:22:39 2010 +0100
libnetfilter_log: Move files from /lib to /usr/lib.
commit b4f9e5b466648977fd7a5aa3545ae3e69bd1dd9c Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 12:21:54 2010 +0100
libnetfilter_conntrack: Move files from /lib to /usr/lib.
commit 85263e145e4a43d08ad309e13c8335bb0212eca0 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 12:20:21 2010 +0100
libnfnetlink: Move files from /lib to /usr/lib.
commit 7bdbde5d6ec17a344e441c1f4def6fc088251467 Merge: 170e92a88c48a99115cd9dd6f0648d0539b703f2 cd410c5e1d7ed6566c7054bae36cc7067fac7030 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Feb 11 12:20:02 2010 +0100
Merge remote branch 'stevee/naoki'
Conflicts: pkgs/core/sqlite/sqlite.nm
commit cd410c5e1d7ed6566c7054bae36cc7067fac7030 Author: Stefan Schantl Stevee@ipfire.org Date: Wed Feb 10 17:39:25 2010 +0100
sqlite: New package.
commit 170e92a88c48a99115cd9dd6f0648d0539b703f2 Merge: 1e2fe399491adbb961bbe2469a509d13e5321be8 725a8d680cdb5f13b7863aaea420ce974f9b6f78 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 10 12:43:46 2010 +0100
Merge remote branch 'stevee/naoki'
commit 1e2fe399491adbb961bbe2469a509d13e5321be8 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 10 12:00:37 2010 +0100
lua: New package.
commit 725a8d680cdb5f13b7863aaea420ce974f9b6f78 Author: Stefan Schantl Stevee@ipfire.org Date: Tue Feb 9 22:55:16 2010 +0100
libnetfilter_queue: New package.
commit 86300324734c61423bdfab4e260dd455c0cd3c31 Author: Stefan Schantl Stevee@ipfire.org Date: Tue Feb 9 22:54:51 2010 +0100
libnetfilter_log: New package.
commit 59f746bc82d646467268fa87733266cad0384f34 Author: Stefan Schantl Stevee@ipfire.org Date: Tue Feb 9 22:54:21 2010 +0100
libnetlink_conntrack: New package.
commit 52a4c2a7c2188649f5f56eec93eba1b1b2a10a8e Author: Stefan Schantl Stevee@ipfire.org Date: Tue Feb 9 22:53:39 2010 +0100
libnfnetlink: New package.
commit 5b2dc186eac1e3f08d216ed469b73fed9a2e3da8 Author: Stefan Schantl Stevee@ipfire.org Date: Tue Feb 9 22:10:09 2010 +0100
upstart: Update to 0.6.5
New dependeny: libnih - code isnÂŽt shipped any more with upstart.
Release notes and changelog here: https://launchpad.net/upstart/0.6/0.6.5
commit 69424bea3dbccd16c9d56bd20988a301ea2d5245 Author: Stefan Schantl Stevee@ipfire.org Date: Tue Feb 9 22:07:49 2010 +0100
libnih: New package.
This is a dependeny of upstart now, because the libnih code isnÂŽt shipped with the upstart source any more.
commit 02a14393bbab0d76fb2674b8125d5e6ee1fda8dc Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 8 18:41:53 2010 +0100
naoki: Fix download url of tarballs.
commit 76a370ef2d6ec00b7cbac334813b1eeaa0cdebdb Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 8 18:36:11 2010 +0100
tcpdump: New package.
commit 3d7a79a456091f5debd6f224ee13d6643db46261 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 8 18:35:48 2010 +0100
libpcap: New package.
commit 1e42f23e9ab67ece15fa2cd89ee6bab6b93a4c04 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 8 18:03:26 2010 +0100
pdns: New package.
commit 4597537587f456cc41e6ddd90766373e3d1f9602 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 20:05:26 2010 +0100
sqlite: New package.
commit 51a5e9803ce5916a2b7e416aa231102566003589 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 19:50:28 2010 +0100
syslinux: New package.
commit 34072f4adcc3e0ca05a44c53082d30e5ee33b101 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 18:26:21 2010 +0100
iproute2: Fix dependencies.
commit 2e68b09cf4c2179754ab952385467abf74d459a4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 18:19:09 2010 +0100
nasm: Build without stack protector.
This is needed because nasm gets killed immediately by the stack smashing protector.
commit e8bb9c1a30166a215e1ba764864c57c663ea45b4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 17:29:11 2010 +0100
Remove bunch of old files in lfs/.
commit 52ca4363fddc61923b6d845761e17486aea7e7b5 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 17:18:48 2010 +0100
rstp: New package.
commit 77467cbd79d8ec846401f0671c8093a385e92f8e Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 17:04:23 2010 +0100
firewall: New package.
commit b6860f43b5917e72fdcc59b3abf35a97339a1d88 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 16:37:55 2010 +0100
network: New package.
commit 7c6295264045d3123a130e99c634722269a77aa7 Merge: 61d84a7d012f7691e4caa4a1319049957175403e adb3e60c21d151b7cd71222d7b454b7f90260e69 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 8 17:05:28 2010 +0100
Merge branch 'patches' into ms-master
commit adb3e60c21d151b7cd71222d7b454b7f90260e69 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 8 16:47:17 2010 +0100
iputils: Apply patches in specified order.
Remove buggy patch.
commit 49320819abbb61a5005dd099c9ee29b6798b71b2 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 8 16:46:42 2010 +0100
util-linux-ng: Remove old patches.
commit ef2efa5cbf83cc35c5219248efcbc3bee120ce99 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 8 16:45:50 2010 +0100
python: Remove gdbm patch.
commit 4584e1dc7f31226c1a01c8baca2eb6731950375d Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 8 16:20:34 2010 +0100
cyrus-sasl: Don't build with -jX.
commit 967d400e6672246463047d588aa4250dcb114319 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 22:08:09 2010 +0100
linux-atm: Rename patch with correct extension.
commit 7c9c394301c9e6bee88976386413eb988c8b2121 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 21:46:42 2010 +0100
zlib: Remove autotools patch which is already included in tarball.
commit 6d943e2c6895eeafaba7a880549bf5cba0203458 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 21:45:49 2010 +0100
ncurses: Remove old coverty fixes patch.
commit 2e96169e68ffbc3c2ef237d9b6cd58fde2d27028 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 21:44:40 2010 +0100
iptables: Remove all crappy patches.
commit 855163fef43a3e851e203d454cacb5f216882bee Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 21:42:22 2010 +0100
glibc: Disable sanitize-env patch.
commit c62ea9c3e2ec0bb0d1bf1b06ef57fa6e2656860d Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 21:41:51 2010 +0100
kernel-headers: Apply the same patches as in kernel.
commit acb1eab6fe914ebd321d9f06ca6f5968c15c332c Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 21:40:41 2010 +0100
toolchain: Remove all patches from bash.
They require the run of autoconf which fails.
commit 1add6595fc572eb1ebbef5ca140045915ebd7e4f Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 21:40:07 2010 +0100
binutils: Remove lazy bind patch.
Doesn't work.
commit d6cb51e91c1de610e7db9cacc44cc22702c6a165 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 21:36:25 2010 +0100
naoki: Don't download patches.
commit 8cbe674bca476fd42010c96f2d27bda780325308 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 18:15:46 2010 +0100
Revert "zlib: Copy patch files into repository."
This reverts commit 2dedf87f8ce55f6e41f4bacb8d96ee4bf647a5b8.
commit 88e2b9dda615920a37aa64a62a9c0791e42b00ca Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:53 2010 +0100
toolchain: Copy tar's patch files into repository.
commit b50ceb454979ddb1e0a74b7174a6242abb7b9994 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:52 2010 +0100
toolchain: Copy perl's patch files into repository.
commit 834bca8bf9ae74e3ee769436340e99dc660789e0 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:50 2010 +0100
toolchain: Copy patch's patch files into repository.
commit 208941a6e242c54076f0b3c697b9a8144eb3f994 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:49 2010 +0100
toolchain: Copy ncurses's patch files into repository.
commit c22db93eea10a2d3e73e55ec578956bbddca0a44 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:46 2010 +0100
toolchain: Copy gzip's patch files into repository.
commit 2cdf46f156ad9b39e6786591f725208a51241ab4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:45 2010 +0100
toolchain: Copy glibc's patch files into repository.
commit 82d1ca6f41bd2a45517ee5b47c8ddd2cca07a446 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:44 2010 +0100
toolchain: Copy gettext's patch files into repository.
commit 139f6c50aa015de6b02cbce0752ffb5d3d0e3bf1 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:44 2010 +0100
toolchain: Copy gcc-static's patch files into repository.
commit 6a6d1330b2d0c1605def5a7f3e15db3c120f83e8 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:43 2010 +0100
toolchain: Copy gcc's patch files into repository.
commit 7c1eb87da56dcac9bd59bf3e26a92cfabe7898a9 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:40 2010 +0100
toolchain: Copy diffutils's patch files into repository.
commit d2c208d6b41a93fa8ecaa9667dcaef08f66424e2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:39 2010 +0100
toolchain: Copy coreutils's patch files into repository.
commit 0b0e9b8691d248387ad806f28bdce3c6360561f8 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:38 2010 +0100
toolchain: Copy binutils-static's patch files into repository.
commit 823af39a88f37b3c68c31c7fb66b43e9634c2263 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:37 2010 +0100
toolchain: Copy binutils's patch files into repository.
commit a744c44477b6f15414edcc69d6588b32c67f989f Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:58:36 2010 +0100
toolchain: Copy bash's patch files into repository.
commit 2dedf87f8ce55f6e41f4bacb8d96ee4bf647a5b8 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:57:08 2010 +0100
zlib: Copy patch files into repository.
commit 39c365ae88249b06953d6c4ccf18b5062bdb3c4e Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:55:01 2010 +0100
zlib: Copy patch files into repository.
commit 304c998ad03e6bcc388166c31a521f7bc4ea7a8d Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:57 2010 +0100
vim: Copy patch files into repository.
commit 4a69e61f5e8aa99b2f71b98a36417a69cb2af46f Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:57 2010 +0100
util-linux-ng: Copy patch files into repository.
commit 547b54ef623339ef09785b1fb92e624e22d1850f Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:54 2010 +0100
tar: Copy patch files into repository.
commit f844903021ecd9cf4de2c6e76176224d1740b65a Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:52 2010 +0100
shadow: Copy patch files into repository.
commit 3869516ac94a802aa73d768263a6bbd35d2809fc Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:51 2010 +0100
readline: Copy patch files into repository.
commit 59da17e96722466cc305e823e0afd2fb12264eb0 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:50 2010 +0100
python: Copy patch files into repository.
commit 3de0614c6e6e66d587de0335131d84aa592d8915 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:48 2010 +0100
procps: Copy patch files into repository.
commit d225ad95747e6375601fc9701dd3b08336931fc0 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:46 2010 +0100
perl: Copy patch files into repository.
commit a02d6c87e699c1b06863ef88105622c62f7d5355 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:41 2010 +0100
patch: Copy patch files into repository.
commit 0a9ec07d4b55cf1d9ea26950236aec7010c09849 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:39 2010 +0100
pam: Copy patch files into repository.
commit 564bb70d427f63b02d57c5a77853f73ffaf14708 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:39 2010 +0100
openssl: Copy patch files into repository.
commit a28043014d599ed5117fa63be6b714696c14d1ce Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:37 2010 +0100
openldap: Copy patch files into repository.
commit f3978c255ca9f7e4a7f79108aab1489597b67208 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:37 2010 +0100
ncurses: Copy patch files into repository.
commit e56e3a8a5f3feb4e376fe4a19438038b3754ddd9 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:34 2010 +0100
module-init-tools: Copy patch files into repository.
commit 68b9ec1cbfdd1ce8c24b8ba40463ddeab2c000ec Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:28 2010 +0100
linux-atm: Copy patch files into repository.
commit 7ee03a3f145f0da9874a393a5123bbebf3c2f6b4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:21 2010 +0100
libcap: Copy patch files into repository.
commit 58c5fc13210353a151f8b2d3c62d19da140b10ab Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:18 2010 +0100
kernel: Copy patch files into repository.
commit 2a9f8dc8a10ce3d20d5a93d22d43f54764172dd2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:17 2010 +0100
kbd: Copy patch files into repository.
commit df92424c2dd240e6b0cbfe4991cf66d0cb5a225b Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:17 2010 +0100
iputils: Copy patch files into repository.
commit ed4173fe6f4958c8fdb6c25df1da903f678d9189 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:16 2010 +0100
iptables: Copy patch files into repository.
commit 5b45f060fa9aa56ba63bcefc2ed44283a8071ca0 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:15 2010 +0100
iproute2: Copy patch files into repository.
commit c192dc6f86bfbd1327b893a8bc686f0c56a57555 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:14 2010 +0100
gzip: Copy patch files into repository.
commit e385ce086654819cf6e16885c1187b4ab6a16c23 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:13 2010 +0100
grub: Copy patch files into repository.
commit d40b18e6c8bc9c4d58c59c0171bcc8bc766ee46f Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:12 2010 +0100
groff: Copy patch files into repository.
commit b2ec3c8a437494d3238a29287d0a47d957d5ed2b Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:08 2010 +0100
glibc: Copy patch files into repository.
commit d54bdc5d92e6a02d0e073ea4511309c363e0654e Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:07 2010 +0100
gettext: Copy patch files into repository.
commit d8cb222621ec52d608e079ebcd2220b4a8131e55 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:54:06 2010 +0100
gcc: Copy patch files into repository.
commit c7e47122ecd8633f5b5a22489f09bbb05d40b9f7 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:59 2010 +0100
diffutils: Copy patch files into repository.
commit c562c9d0c8748d7c79481787c8b707a7590c6a6d Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:56 2010 +0100
db: Copy patch files into repository.
commit 044cc66f8f0bd21b5ad61478dec54cf8cd2a0583 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:55 2010 +0100
cyrus-sasl: Copy patch files into repository.
commit bf952a7dfb5ed1548086e163d1aeac38a45fb9a4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:53 2010 +0100
coreutils: Copy patch files into repository.
commit 8e7f124491c9aa4b97b9e3e462e30626df993646 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:52 2010 +0100
ccache: Copy patch files into repository.
commit ae6648471f65d2f315a8e8ed7398a9fbc9e0a88a Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:51 2010 +0100
bzip2: Copy patch files into repository.
commit 8a172fcbf1e99b16027348ccd3786f33bb7d0a90 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:49 2010 +0100
boost: Copy patch files into repository.
commit ffca338b42f2e140bc0b45e0c09ebb23ac078a10 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:48 2010 +0100
binutils: Copy patch files into repository.
commit 60964b72a1835d14ece10fdffbff1643c0361b50 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:46 2010 +0100
bash: Copy patch files into repository.
commit a8e75deada83023b5e0dcd874beef73849019550 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:53:43 2010 +0100
acl: Copy patch files into repository.
commit cd461114de8791c7a36c9a2101971c3dd916f080 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 15:47:38 2010 +0100
naoki: Change handling of patches.
From now on, there will be a special directory where we put in our patches. All files with the *.patch extension will be applied to the sources. If you want to temporarily disable a patch you can easy rename it to something like "mypatch.patch.off".
commit 0c294e96541117716be9e7e07e4ff672e31941f3 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 14:29:22 2010 +0100
naoki: Rewrite of CLI.
commit 61d84a7d012f7691e4caa4a1319049957175403e Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 7 00:10:24 2010 +0100
syslog-ng: Fix dependencies.
commit 7c415e0dcd125554d8658375e2276c53ae999ae1 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Feb 6 23:50:17 2010 +0100
screen: Remove some mistakes from makefile.
- ncurses is runtime dependency. - STAGE_INSTALL_CMDS was used in a wrong way. - Installed a clean screenrc. - Renamed pam.d file to make it more clear why it lies around here.
commit 1091aa0925d4abca9eb7594814ab74fdf6459610 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Feb 6 23:42:07 2010 +0100
syslog-ng: Remove old configuration files.
commit e67445f39e39f4930114e65bdc5d428b9b87d9a2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Feb 6 23:38:56 2010 +0100
binutils: Updated binutils to 2.20.
commit 7eb27ce63d2e6a8f13806d58f2b8ff70a27bfbbd Author: Benjamin Schweikert trikolon@ipfire.org Date: Sat Feb 6 19:36:12 2010 +0100
Fixed a linking bug.
commit 0814e32f9b66978953f63ae1bf329a34db4cd8c7 Author: Benjamin Schweikert trikolon@ipfire.org Date: Sat Feb 6 19:35:41 2010 +0100
New naoki file: syslog-ng.
commit 74608533a1d51f9fbb9fab00ec35219754182e0d Author: Benjamin Schweikert trikolon@ipfire.org Date: Sat Feb 6 18:29:59 2010 +0100
New naoki file: screen.
commit d7291dc9c4c29acbf52778c88d7ff28ecf2c8b7a Author: Stefan Schantl Stevee@ipfire.org Date: Fri Feb 5 22:54:15 2010 +0100
dbus: Move libs from /usr/lib to /lib.
This is needed because of upstart makes use of dbus libs while installed in /sbin.
commit 923cac1cd6fb4af1b5377152bef60de2f27c6b5d Author: Stefan Schantl Stevee@ipfire.org Date: Fri Feb 5 22:53:19 2010 +0100
upstart: New package.
commit a20300764fd737bb5df934ee3840a9a7a33f6a4c Author: Stefan Schantl Stevee@ipfire.org Date: Fri Feb 5 21:57:05 2010 +0100
htop: New package.
commit 6123353700c3670b20765000efc09d9a614c788c Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 19:59:18 2010 +0100
naoki: Add multiple arches support.
This will allow us to compile ipfire on a 64bit host in a 32 bit architecture.
commit cfd06ca11d5bd845c45471b5dba492b592fa94b6 Merge: c3cb5d3e2dc01dd6040a26a4c9225c14d9dcb1b9 1ed95534cc36bfc34d3c36b69ea70d06040f33e9 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 18:17:47 2010 +0100
Merge remote branch 'ms/master'
commit 1ed95534cc36bfc34d3c36b69ea70d06040f33e9 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 18:06:01 2010 +0100
eventlog: New package.
commit eee6cf94ab2dfaf527406f712da20c56b7237b88 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 17:48:18 2010 +0100
br2684ctl: New package.
commit 582847181a50ac961a8e15ed6191a0538ff49e0c Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 17:29:29 2010 +0100
linux-atm: New package.
commit d918082aa7c44d0fc68f55084ff25a9012bcdd23 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 16:51:04 2010 +0100
bind: New package.
commit cc52c5238fc098a9707e6478e97c0e4152788d02 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 16:30:09 2010 +0100
dhcp: New package.
commit eb73cf79d5bbb8884f5ba28de475cb302392ba09 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 15:48:01 2010 +0100
gnutls: New package.
commit bbd0133f6024fc172d5b0c77a72196bedc864167 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 15:47:43 2010 +0100
iptables: New package.
commit 7ec4bf0a5c1eb5b69223bf1d67b0811ee26bd5e4 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 12:17:40 2010 +0100
openssl: Use gnutls library.
commit a67932864864af3d5645aa05c7bb3ae37b144c33 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 12:05:37 2010 +0100
nasm: Remove empty fields.
commit 2e9748cce70eb295816c24d95a91d396b1356b3f Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 12:05:19 2010 +0100
libgcrypt: New package.
commit 8678b451f67abdf99a6787782340de024ba568b0 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 12:00:08 2010 +0100
libgpg-error: New package.
commit fe4dc0830a86d598e796c72c56ecd7ea3025d9e4 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 11:54:47 2010 +0100
paxtest: New package.
commit 6d675cd3e69670241243167fa34f9dc352824505 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 11:49:07 2010 +0100
memtest86+: New package.
commit d1bddc8a40616cb131bddd14e4082a54372758ee Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Feb 5 11:03:36 2010 +0100
nasm: New package.
commit 8a273f62e2a4da270174786e1b42ac4fdab0ea45 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 3 19:34:08 2010 +0100
dvdrtools: Fix styling of makefile.
commit ad4c499fe604149c292be176afa7de8e322ca597 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 3 19:33:50 2010 +0100
dbus-glib: Fix styling of makefile.
commit dcc8d074f8b92000acacd2aab50ff15703cec3f0 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 3 19:33:14 2010 +0100
dbus-glib: Fix syntax error.
commit 40dbfb23b96b1f760dcce20d47470ecee76e5aac Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 3 17:38:17 2010 +0100
Fixed a dep.
commit fccb2aa5e80cd61ced314f5aae5d6911eec348fe Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 3 16:20:55 2010 +0100
New naoki file: dvdrtools.
commit 4eac8931e84d98817932751a223630ab387908aa Author: Benjamin Schweikert trikolon@ipfire.org Date: Wed Feb 3 14:13:50 2010 +0100
New naoki file: glib-dbus
commit c3cb5d3e2dc01dd6040a26a4c9225c14d9dcb1b9 Merge: fbd0b63053e2f1521a19663eaa6b7ff166719e88 52ac63ac0c4af58e9e76315f2f355c7a60a5d61e Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 2 23:03:57 2010 +0100
Merge remote branch 'ms/master'
commit 52ac63ac0c4af58e9e76315f2f355c7a60a5d61e Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 2 22:52:37 2010 +0100
vim: New package.
commit 714e50f58272c73f0645cfa2b548c610ccca83f7 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 2 22:31:48 2010 +0100
shadow: New package.
commit ae5a840bd4e2e83644f8e34da11a9af578f9dad7 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 2 22:12:39 2010 +0100
passwd: New package.
commit 73e343980dc19894a7808521f130d33a3d23dee1 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 2 22:12:25 2010 +0100
libuser: New package.
commit b685bb18d197e0a8c1b047c4b34f00027d0e5c0e Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Feb 2 22:12:09 2010 +0100
popt: New package.
commit fbd0b63053e2f1521a19663eaa6b7ff166719e88 Merge: 20d904b86e36373e520ae9aa336d56592edc238a 0ab6a56e242730feb8eba7feccbf298e7c63d6e8 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 23:12:03 2010 +0100
Merge remote branch 'ms/master'
commit 0ab6a56e242730feb8eba7feccbf298e7c63d6e8 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 23:02:02 2010 +0100
openssh: Forgot to add the pam file.
commit 80032003821085852ff651dcced492b3183e0b51 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 23:01:22 2010 +0100
openssl: Clean up the commands and add testsuite.
commit 7d4ff9534d7d46a8b5f7d7fc04626a28985c0551 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 22:54:18 2010 +0100
openssl: Add zlib as runtime dependency & bc for testsuite.
commit b771887db18261b91f55caddae8f418389671ff2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 22:52:29 2010 +0100
openssh: Fix installation of configuration.
commit 5c9f6e48e37bda9ad4f06fbfca0cb4de9a949215 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 22:51:54 2010 +0100
openssh: Runtime dependencies must not be in list of build deps.
commit 02b6f3f0c6a473f1f807fb73f0c9496609c32a57 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 22:51:05 2010 +0100
openldap: Fix installation of configuration.
commit 799d65adb97f2b29c5b92133cdd68969a9caf6c3 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 22:50:33 2010 +0100
openldap: Remove some whitespace.
commit b0b6cb34baaf55c65c5272aa4c569427db002802 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 22:47:16 2010 +0100
openldap: Fix dependency list.
commit 3652add1883e4ddd9cc0c3296b38fc17d74d5eaa Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 19:09:34 2010 +0100
nano: Fix dependencies.
ncurses is a runtime dependency. groff is needed at build time to create the html documentation.
commit 874469ef1ca182ce94de95c623e5c42a44ce841c Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 19:05:04 2010 +0100
libssh2: Remove and add whitespace.
commit cce1a80b6cbbbeb47a4b1da31838f33f351f0896 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 19:03:04 2010 +0100
libssh2: The given dependencies are runtime dependencies.
commit 06b38339eeadb1d4d3be5c65ba4be5fb3dc77408 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 19:01:43 2010 +0100
curl: Remove empty block.
commit bfb883b31db19caf1bb9d445b26f1c56ed0d5cdc Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 19:00:23 2010 +0100
curl: Comment out unplaced command.
This command had no effect in its former place. But there is no place where to put it. So we leave it commented out until we need it.
commit 1484533c77ebd2f856c6b8ea211270e893501c1c Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 18:59:08 2010 +0100
curl: Remove --prefix option.
--prefix is set by default and is not needed.
commit 8722fc732453ed2923993b353f02e9b4334712d1 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 18:47:13 2010 +0100
curl: Fix list of dependencies.
Don't add a package to both lists. Decide if the package has a runtime dependency or only needs a special tool on build time.
Additionally, in this case, pkg-config, libidn and zlib were missing.
commit 0479385f25c7eae66697e5d88687759e469eeb5d Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 18:46:05 2010 +0100
openssh: Move configuration files to right location.
commit 7f0e16ed47fa94c0e7abb7736939704dc04233d4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 18:45:23 2010 +0100
openldap: Move configuration files to right location.
commit a2535313e56997922692e8b11716f7499ef51700 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 18:44:04 2010 +0100
pth: Remove empty fields from makefile.
I like comments very much.
commit 606a4845289b87595df744ab25808216f2866afb Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 18:42:06 2010 +0100
naoki: Create /bin/rm in toolchain.
Some testsuites (openssl and openldap for example) have a static reference to /bin/rm that we link this to not create an unnecessary dependency to coreutils.
commit 120ffbc565f88237e02d18e0d18e9e2df2fb7dd3 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 31 18:41:45 2010 +0100
Remove .config-default.
commit 8b63a1947a73e64eb8c0e532a6fd5a9bd818a24a Author: trikolon trikolon@ipfire.org Date: Sun Jan 31 17:43:09 2010 +0100
New files: openssh, curl, pth, openldap, libssh2.
commit 26064608eead6cac3a6d1d76e8a683d1b2e32442 Merge: 494e3d7806429c35c9857f5eb8da89a817b2c5c5 dac1e99c0eaa69d4efde41c1679c208e774c00fd Author: trikolon trikolon@ipfire.org Date: Sun Jan 31 13:15:19 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 494e3d7806429c35c9857f5eb8da89a817b2c5c5 Merge: d661f0d130cc7882b86c0fa59347c95168bed5c4 dfb13c6f5e7ded6cb434606e291f67135c8b736e Author: trikolon trikolon@ipfire.org Date: Sat Jan 30 23:44:54 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 20d904b86e36373e520ae9aa336d56592edc238a Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 23:43:10 2010 +0100
Remove duplicate installation of urlgrabber.
commit dac1e99c0eaa69d4efde41c1679c208e774c00fd Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 23:41:08 2010 +0100
Remove files of packages that already have been ported to pkgs/.
commit 951459e8fe7a6e1c57a799fce84a26c4a089dcdd Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 23:28:50 2010 +0100
pciutils: Fix installation of man pages.
commit d661f0d130cc7882b86c0fa59347c95168bed5c4 Author: trikolon trikolon@ipfire.org Date: Sat Jan 30 23:19:07 2010 +0100
Libssh2 for naoki.
commit dfb13c6f5e7ded6cb434606e291f67135c8b736e Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 22:36:39 2010 +0100
mkinitramfs: New package.
commit 2c9f13c13e3f4e572daa5861e850f1ca297e97b7 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 22:29:13 2010 +0100
procps: New package.
commit 015d4a75111ed91c10b6be7b9f9b6a85afbfded3 Merge: 1fd12ad5614cf8918d0f359624c54395bd9bacdd e1f441dbc9f151c34b32fa3099bcf270695d651d Author: trikolon trikolon@ipfire.org Date: Sat Jan 30 22:21:22 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 94ccae6bb3b265320d6375468e78d72fd07ecc48 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 22:17:09 2010 +0100
psmisc: New package.
commit 34947337cad2df285ff627980dfa32e60729c6b8 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 22:15:19 2010 +0100
module-init-tools: Remove unneeded command.
commit 9ad08da356714d627f12eaa843c587dcb1830c74 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 22:01:05 2010 +0100
system-release: New package.
commit 1fd12ad5614cf8918d0f359624c54395bd9bacdd Merge: a7905983625ef7410ba3b9ebb9fd368ecfce959f 9b3bc8007b2c1be9df9c4858183d8001e200921c Author: trikolon trikolon@ipfire.org Date: Sat Jan 30 21:48:27 2010 +0100
Merge branch 'master' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 8281db1085e47d4b4368937e97b0fabb595388b6 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 21:43:46 2010 +0100
module-init-tools: New package.
commit a7905983625ef7410ba3b9ebb9fd368ecfce959f Author: trikolon trikolon@ipfire.org Date: Sat Jan 30 21:29:48 2010 +0100
Adding naoki file for the text editor nano.
commit e1f441dbc9f151c34b32fa3099bcf270695d651d Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 21:21:05 2010 +0100
naoki: Add ccache support.
commit 9b3bc8007b2c1be9df9c4858183d8001e200921c Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 20:28:39 2010 +0100
udev: New package.
commit a50173a711793cda64be49863d3215415f29f1c4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 20:28:24 2010 +0100
pciutils: New package.
commit 7c6a4b60058d09d4bf4edff16808a8f5bc2f46cc Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 20:28:14 2010 +0100
usbutils: New package.
commit 882588278e284782327275813763283376b5a9f6 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 20:27:58 2010 +0100
libusb-compat: New package.
commit 689311b650aae75a9b79fa0fc6c706ea4f17e523 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 20:27:47 2010 +0100
libusb: New package.
commit 4aedebb252f9f687724b31e0b8e7d90657df4140 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 20:27:24 2010 +0100
gobject-introspection: New package.
commit 914e4ae3fe2b8d81706c6eeb6d5ba95b50fd17fd Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 20:26:51 2010 +0100
gperf: New package.
commit 9822cf6c14dbcc46aee1db3cb4a40924b58a9c65 Merge: 32aeedbf57e93a3d37d8b096ad27a80feb96b71b b8945ec8bc2c182bc483cbd5dfec80afd0156d3a Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 14:24:00 2010 +0100
Merge branch 'naoki' into naoki2
commit b8945ec8bc2c182bc483cbd5dfec80afd0156d3a Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 14:19:12 2010 +0100
ncurses: Fix installation of man pages.
commit 34832a19638de1eaa8c0b9396c850fc08d545435 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 30 14:18:51 2010 +0100
make: Fix installation of man pages.
commit 08a45a9f5d7c853bbf7a33418f58dcdfa48c37b0 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Jan 29 20:07:22 2010 +0100
diffutils: Fix installation of man pages.
commit 566c67577a559ac84d3f694f550009336b6a5efe Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Jan 29 20:06:57 2010 +0100
ccache: Fix installation of man pages.
commit 29ac8c51e7860e1d0cb560dfdcfa752b6dff87af Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Jan 29 20:06:18 2010 +0100
bzip2: Fix installation of man pages.
commit 68d04bc0168c64425370a5855d92780e39a5a58f Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Jan 29 20:05:23 2010 +0100
expat: Fix installation of man pages.
commit 32aeedbf57e93a3d37d8b096ad27a80feb96b71b Merge: 4ae473ec803f797098302e46cc947e245516c2b3 2d940a9c4c5098b09f15f5b479ce0fa5f749a795 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Jan 29 15:12:26 2010 +0100
Merge branch 'naoki'
Conflicts: make.sh
commit 2d940a9c4c5098b09f15f5b479ce0fa5f749a795 Merge: 107ed6eeedb27f4fea8e9034e45f8518579122ef 590ac020c54353463d307f52c7a7bacf3c8bbcec Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Jan 29 15:06:49 2010 +0100
Merge branch 'naoki' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 107ed6eeedb27f4fea8e9034e45f8518579122ef Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Jan 29 15:04:32 2010 +0100
gcc: Fix installation of man pages.
commit daaaf465b8553b0397343d619b0a6749e84b804c Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Jan 29 15:03:03 2010 +0100
binutils: Fix installation of man pages.
commit e9f9aed1118740247d2d59df657d7deab2f9da44 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Jan 29 15:01:42 2010 +0100
naoki: Fix if /tools_xxxx already exists.
commit 590ac020c54353463d307f52c7a7bacf3c8bbcec Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Jan 28 13:53:53 2010 +0100
naoki: Allow definition of STAGE_INSTALL_CMDS.
commit 8058f4e3b237b79dcb7e47ff2f1000a3b5741963 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Jan 28 12:11:55 2010 +0100
bc: Fix installation of man pages.
commit e3f1c924bdc4d57e1ff00ec4e2c490bb00ceeb3d Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Jan 28 12:11:39 2010 +0100
cyrus-sasl: Fix installation of man pages.
commit 932926c32b094c0fb7b811252dbd3d08ae3229cf Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Jan 28 12:11:23 2010 +0100
acl: Fix installation of man pages.
commit 87dda34c56cb1698e9dc6cb2a18b603ddf871c02 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Jan 28 12:11:00 2010 +0100
flex: Fix installation of man pages.
commit b5c3b53a852c29c0eb90d0c9724404c490efd467 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 27 23:38:25 2010 +0100
toolchain: Add missing espf patch to gcc.
commit 640451c1aed3908d544505d82066d3f2e1a1c688 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 27 20:28:42 2010 +0100
QA: Add /lib/pkgconfig to list of forbidden directories.
commit 9bc3cce05d9370908a28d52bfcbfdc8c96467bf7 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 27 20:27:48 2010 +0100
libidn: Place this to /lib.
ping from core/iputils depends on it and will be installed to /bin.
commit 2d99b768382f669c09ae204822d495f2a56e89eb Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 27 15:49:14 2010 +0100
QA: Remove info files if they were installed to a wrong destination, too.
commit 9da1b3e5f96ba5c83e7a7eee90e10cccbb3511b7 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 27 15:46:42 2010 +0100
sed: Fix installation path of man pages.
commit 45e22ad04e45e2f9c6b7954801f8b6515ee3ac6c Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 27 15:33:41 2010 +0100
patch: Run autoreconf on build.
commit 5705a8adda8257384668e459784862f73a4edd68 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Jan 26 20:45:57 2010 +0100
QA: Check for directories that should not be there.
commit 7544685894fa697613c6c16d8df6cb9f9d12b612 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Jan 26 20:45:26 2010 +0100
QA: Check if there are files in /bin or /sbin that link to /usr/lib.
commit c96c272fe986cc4f8ead2eef31cbdbf7dd911ebe Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Jan 26 20:44:55 2010 +0100
QA: Remove info files that we do not provide in our packages.
commit 83e313a699911a0f5aae049ae7fecc5c446a847c Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Jan 26 20:44:04 2010 +0100
QA: Make use of the new logging function.
commit 2cbc40be14bce128a9f0a12f845b994103325be3 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Jan 26 20:43:39 2010 +0100
QA: New logging function.
commit e6855a9e69d0816bd7aed5ad16bb8e2f4ddbf900 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Jan 26 20:26:46 2010 +0100
naoki: Link /tools_XXX to actual directory if needed.
commit f518a817837f268a9227c0c1c3a3f0068c2329a6 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Jan 26 17:37:26 2010 +0100
naoki: Fix toolchain compression issue.
commit f07caf9e9e3fa73be880640be40bcb94fd038ce2 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Jan 25 00:36:17 2010 +0100
naoki: Split pkgs/Include into seperate files.
commit db99d62f11e6f68d84fa60b8d411085d62130036 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Jan 25 00:32:32 2010 +0100
naoki: Import exception classes.
commit 378c8f189a74a39693b50a6a04a0fd3934885bef Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Jan 25 00:05:29 2010 +0100
naoki: Fix max file size of logging to 10MB.
commit 59cdb5f181463dc6c403a03ec8d81650a39a9d8a Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:49:41 2010 +0100
naoki: New toolchain class.
Allows a more flexible way to handle this...
commit 19f2538dfcd68bf3aa77e1866ce30f9d2bf612fe Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:49:03 2010 +0100
Remove any cross build target lines.
commit 019de8350512162ef6e02f6ffc2dd03312f766b6 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:48:35 2010 +0100
sed: Add testsuite.
commit 5223858260ab1acdba59b804a491c0cccbca12d4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:48:12 2010 +0100
m4: Disable testsuite.
commit 8504873f9e38b2a872c616d2b665f142277711c4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:47:25 2010 +0100
pkg-config: Disable testsuite. Fails.
commit 128f78cfe83d0735783b9aa4065bb2e657de50f9 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:46:48 2010 +0100
toolchain: Compile gcc-static without any patch.
commit 0d6054530b08fe1bb7e900a8d08d15251f4a4146 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:46:08 2010 +0100
glibc: Disable testsuite.
commit 0ba3cc3e9120e0e5478a06a2ed75e2c7032c218b Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:44:44 2010 +0100
gcc: Fix build.
commit 32a1e8c6c677e8ac37d8ab1441fac2dd823cba45 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:42:05 2010 +0100
e2fsprogs: Add testsuite.
commit 6754adb5a810a081d7293537c1f04d70f0cb5927 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:40:34 2010 +0100
bison: Disable tests. Doesn't work.
commit e54c133400d8386a2f1d7885be6fb4f7eabc51dd Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 23:37:46 2010 +0100
bc: Needs flex for build.
commit 58f5690dd3226bba485eeebcda5d603b83152b63 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 22:02:33 2010 +0100
tar: Fix use of wrong compiler.
commit ab18c329d05ce1fcd8ea9a7e23a081588f0da668 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 24 22:02:01 2010 +0100
cpio: Needs automake to build.
commit fba169947dc98385e52b2055e06ddcf10d403538 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 20 00:29:39 2010 +0100
naoki: Add "HOME" to default environment.
commit 92c56f8834f5b111a79ebcc6eb5708df51386df4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 16 20:05:36 2010 +0100
zlib: Add testsuite.
commit 4daac19ce0e4020eb2b70080d62e95a83e4c9748 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 16 20:05:21 2010 +0100
mpfr: Add testsuite.
commit 59a1ef0dbade2a1844af4e05405d04d96cad0072 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 16 20:04:05 2010 +0100
gmp: Add testsuite.
commit f1fdd4d64380a2963e2d65aff3b659f0d7413b7c Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 16 20:02:24 2010 +0100
glibc: Buildfixes.
Configure right linker for tests. Works for x86_64 as well.
commit fba656caa9edef69ecef7efbc6d01eab7187d2f2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 16 18:41:28 2010 +0100
binutils: Buildfixes and add testsuite.
commit f9d4d62948c81a667bab2c3c7137b84357d19994 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 16 18:40:53 2010 +0100
toolchain: Enable hardening for gcc.
commit 36871e5d8b4892f02aa63b8146c254cca9a513cf Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Jan 11 21:26:16 2010 +0100
toolchain: Remove flex.
commit 19a4b6e1df07f81bbd7bfce3312a43e2f06be6e0 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Jan 11 17:33:57 2010 +0100
glibc: Don't run tests in toolchain.
commit 8a3d26ab832e7196bfd2378f1422d058ed233ac3 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Jan 11 17:33:09 2010 +0100
findutils: Fix "make install" command in toolchain.
findutils modified the host system.
commit 070648a7bd3bb6ee14d9b23c2f128a6d05d890a4 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 10 21:32:18 2010 +0100
toolchain: Remove e2fsprogs.
commit 593e8e3b233f4a6e0e9f9782c1971f665bf85c14 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 10 21:31:38 2010 +0100
toolchain: Add a script that checks a little bit of sanity.
commit b681c2524ce0e1551f3dfdc515b764a12f1490a3 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 10 16:25:30 2010 +0100
toolchain: Perl is not built with symlinked sources.
Didn't work as expected.
commit 99600f07bc5338f52633856d3c5120272405cb4b Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 10 15:52:24 2010 +0100
naoki: Create symlinks to tools that are needed in chroot.
If they are not already there, we need to symlink them to the toolchain tools.
commit f78f2ff5941ae65eb45506623409740e8aff5c60 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 10 15:52:06 2010 +0100
naoki: Remove whitespace.
commit ce7ffd0d1dbbd0706d6deea78593af18bbb204ea Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 10 15:40:04 2010 +0100
naoki: Print directory that we are in.
It is confusing if you get an error and do not know where.
commit e020cabf4de05f2f5c57b1c3ff9ccd2f5611d681 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Jan 10 15:38:31 2010 +0100
naoki: Remove a build environment before build if it is already there.
commit b6ca51785309dda9c79de5c72fedade9bb62d98c Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Jan 9 16:28:10 2010 +0100
naoki: Add toolchain features.
Fixes lot of things in the toolchain, etc. Adding testsuites.
commit a44c6c89403fd3d651b916c1cf9fbc5015621716 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 30 13:52:41 2009 +0100
naoki: Fix a line that crashes listing of groups.
commit ba4759311f183fd0031400af79a9637bda197d49 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 30 13:35:01 2009 +0100
.gitignore: Ignore python bytecode files.
commit 90bf84f475ea764428f160e1c32c16b558e42ffa Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 30 13:33:31 2009 +0100
naoki: Decompression of packages with older tar.
If the version of tar is too old to support xz compression, we use this workaround. This requires the xz binary being available.
commit 15a38d153adc033b1246baa4bde25c73e7e1aa11 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 30 12:43:04 2009 +0100
naoki: Fix a logging issue with python 2.4.
commit 88f71b44bf1b2a30e068fb02348d0b9495634278 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 30 12:41:18 2009 +0100
naoki: Replaced urlgrabber by an older release.
The newest release wasn't working properly with Python 2.4 (which is still used in CentOS).
commit a6dccbc048e01d655175a979d2ed06dcd7220abd Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Dec 29 18:00:27 2009 +0100
naoki: Initial import of python rewrite.
commit f7eb1e88a4e5ac80fab4cf3ed9f7fcd2e39d8503 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Dec 18 13:38:00 2009 +0100
naoki: Removed some unneeded function calls.
No functional changes.
commit af478a823f0fa37e67b6388a93a3735da9e39422 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Dec 14 20:26:22 2009 +0100
naoki: Some code cleanup.
No functional changes.
commit 6e0769d0a0a3c4ba8ee7e4f953570f5d505adde5 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Dec 14 19:31:14 2009 +0100
naoki: Add some caching functions to speed up meta data fetching.
commit 5970e4b21c86fd577dade914cf16e4a540a79001 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Dec 14 17:48:11 2009 +0100
kbd: Build requires autoconf.
commit 3c36c336d71ad9fed752f4ecb8407f361d70173f Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Dec 14 17:47:59 2009 +0100
grub: Build requires autoconf.
commit 15b43c6c0d475a5ad6245de810c923eb3ae7ce4e Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Dec 14 17:47:46 2009 +0100
bridge-utils: Build requires autoconf.
commit 1a6b4d6f310fba4017118fa8c7dfba635fa1083f Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Dec 14 17:47:19 2009 +0100
bash: Build requires autoconf.
commit 56888ac913ab34174558e17de3ac8aff00ad4a1a Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Dec 12 14:47:04 2009 +0100
pam: Fix build with flex.
commit e152ae41ba9fc29c5ebd2024208e272997faf216 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Dec 8 11:33:26 2009 +0100
naoki: If ${TOOLS_DIR} points to right directory.
commit 5e23908c7bee660f8757101d6cae7a33f1767d37 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Dec 8 11:33:04 2009 +0100
tar: Needs autoconf and automake to build.
commit e5a0c5bcc77f38c0717ebab5a6d1d833a8e999a6 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Dec 8 11:31:46 2009 +0100
make.sh: Add some more commands to make it easier.
./make.sh build <package> - Will build or rebuild one single package. ./make.sh all - Will generate the tree and build all packages.
commit b8e732f4e6693b24ea709377c6b08f32cbe7701c Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Dec 8 11:28:44 2009 +0100
QA: Keep libfl_pic.a.
commit 8aa1b4429f3d4b617b2dc3aacf0baad4c7b649db Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Dec 8 11:28:21 2009 +0100
Revert "flex: Provide a shared version of libfl in the package."
This reverts commit 25ba07e22916118afef529b95272c430d0c56904.
commit 028a62ab1689d303fc4a90a2f4379cf48c7f562a Merge: 25ba07e22916118afef529b95272c430d0c56904 91f5b0765f3e6b67733e4e025346d61e81d7a095 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Dec 8 11:25:37 2009 +0100
Merge branch 'naoki' of ssh://ms@git.ipfire.org/pub/git/people/ms/ipfire-3.x into naoki
commit 91f5b0765f3e6b67733e4e025346d61e81d7a095 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Dec 7 09:51:11 2009 +0100
New package: man-db.
commit 84a97a99b793cd72e16f557b0e845968bd29456a Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Dec 7 09:50:56 2009 +0100
New package: groff.
commit 25ba07e22916118afef529b95272c430d0c56904 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Dec 6 16:53:11 2009 +0100
flex: Provide a shared version of libfl in the package.
commit 58c8a19734f513999e92c91eb07ec62a159938b2 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Dec 6 15:52:06 2009 +0100
New package: vlan.
commit 6dec0566ad10d3e0924a788c4a9e77c6e1740823 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Dec 5 23:06:20 2009 +0100
gettext: Has a build dep to autoconf and automake.
commit eef47701611badbcf5487b23a323e11f0d8989d0 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Dec 5 19:33:21 2009 +0100
New package: dbus.
commit fa68012cb2a889bb0d44064bec9c7ebdf799d55e Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Dec 3 12:14:49 2009 +0100
Extensions on quality agent.
Add some more hooks for stripping bins, searching for unsafe files, etc.
commit 3eb86a2b09da48598adf28827458c06cb2a543fe Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Dec 3 10:15:56 2009 +0100
acl: Requires libtool to build.
commit f5b9a090e9dd083538ae2bdf3b5920e12059e72a Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 22:31:58 2009 +0100
New package: kbd.
commit 87c18628cb51e6cde0b85b6fb6c0f3593ac02f23 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 20:26:45 2009 +0100
gettext: No dep to "libxml2".
I think it should be "libxml".
commit 66c170e37a5229920b1da04c5acc860470941381 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 20:25:16 2009 +0100
New package: libxml2.
commit 9bb99a82595eb3b34de1db00e1a643294b181d94 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 19:53:34 2009 +0100
New package: iputils.
I remove ifenslave from this packe. We don't need it.
commit e767635ab15582ea6f86027a88e72b3b44b47ccc Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 19:53:10 2009 +0100
New package: libidn.
commit f31cce40fa274c66038c37ee3b5ceb1f71e36e2c Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 18:11:26 2009 +0100
New package: bridge-utils.
commit 1913f3ed8452836dfb5e5e4ffa9c086b5118dbcd Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 18:10:55 2009 +0100
Make some packages use the CONFIGURE_OPTIONS feature.
commit b968bc72ba65c7513b6c7a01916656761ad4ba70 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 18:00:38 2009 +0100
naoki: Add shortcut for more options to configure.
commit 6c8e4af34e35606f00ba5158cafe81a603008080 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 17:43:55 2009 +0100
New package: less.
commit 7d8ed742e3f512ad0233ff8fcd2402de5dabef19 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 17:36:57 2009 +0100
New package: which.
commit c3171bf330f64c450a2356c1b2580d79f4c13006 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 17:34:30 2009 +0100
python: Add "db" as dep.
commit 91d1aacfb8c9283cd46a65b91fb7da8178e1dc85 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 17:29:38 2009 +0100
New package: ebtables.
commit fe6a09720870475872fea0599b274e3e0b3c6871 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 17:28:59 2009 +0100
New package: lzo.
commit bfb82b0995cfe65ca4bb7f7459f7d1a3b11689a5 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 17:26:30 2009 +0100
Add a root account to chroot environment.
commit a9d112c3991f3ddbee825d572538b8c3dec5fbc8 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 16:56:30 2009 +0100
New package: iproute2.
commit c36e4789f6cacf9d0df32a001a308141d4f89f84 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 16:30:02 2009 +0100
New package: grub.
commit fc5f06dae0ff7447ede56ea43f131f46915d8496 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 16:21:52 2009 +0100
New package: cyrus-sasl.
commit 20d414ed9d87810def0babd5c15b2500336185f1 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 16:21:16 2009 +0100
New package: paxctl.
commit 93c1e71eac3167d848470a6f66ba69d7c6a2d857 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 16:08:09 2009 +0100
New package: openssl.
commit 54da28a8f82a5405c6f2144d42cfb4082b2728b4 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Dec 2 15:21:05 2009 +0100
New package: iana-etc.
commit edd88eee3d6b2d7fccd72172fffff4875ca257f2 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Dec 1 22:02:40 2009 +0100
New package: expat.
commit e5ea083def927bd3b3fd82bbef8c811d82b116cd Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Dec 1 21:16:49 2009 +0100
New package: boost.
commit 166a3088f7c38e793e9180466dcfc8e3702f14a5 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Nov 30 00:22:07 2009 +0100
New package: glib2.
commit 85122efe1a04d70ecf0172f828d35a117d4bf69d Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Nov 30 00:17:09 2009 +0100
New package: pcre.
commit f6d9281dd759b92f86f97f52bc7b0b6f65e9e83f Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Nov 30 00:16:53 2009 +0100
New package: db.
commit ad6556c4f76d63fe39b7c43c1b76ba0301b53fc9 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 29 23:23:26 2009 +0100
New package: bc.
commit 2b05a3ad41b9a65d7559a8f6a6ab43bb9f2ebe42 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 29 23:15:55 2009 +0100
gcc depends on gmp and mpfr.
commit a91543e184b8592e6367d8f19dbe842ee162dde7 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 29 23:15:39 2009 +0100
New package: mpfr.
commit 58608bd46b0c6f2b6444c69f18cb4d06d8b551aa Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 29 20:57:08 2009 +0100
New package: gmp.
commit cbd6ced695f31f80122ef5f2f291f3d13fcc4e2a Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 29 20:47:07 2009 +0100
binutils: Buildfix.
commit 6ffd650d6c23cabdbc80e773919d1a988436d358 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 29 20:44:28 2009 +0100
naoki: Libtool is no mandatory package.
commit 456f92d2b8a38e81b22ca67faad02c8dc57e471c Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 29 17:42:52 2009 +0100
Command to build all packages in a random order.
commit e09f577dae1f5e31514cd8b95797190b60be9126 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 29 17:24:48 2009 +0100
naoki: Massively speed up of dep resolvation.
commit bfbb4b802f705d95767c5bac83197c13ca5e9024 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 17:32:47 2009 +0100
New package: cracklib.
commit 5a9455235f507510f76c69052fde55d874016c7b Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 17:25:11 2009 +0100
ccache: Catch call of c++ as well.
commit 53c273e0041fb385a01d805ae2c155be08aa400c Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 17:24:37 2009 +0100
New package: python.
commit 2abd844d80e4348fbc363456ec20abd499c50c05 Merge: d04f1a38af4a73c803f4c903cd3b300e0d8d2c10 9d4b355899b0cde2de6029dfc943d85af4ed1731 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 16:24:51 2009 +0100
Merge commit 'ms/naoki' into naoki
commit d04f1a38af4a73c803f4c903cd3b300e0d8d2c10 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 16:21:36 2009 +0100
New package: pam.
commit d113b67abf6590c092628846d7632551c338209c Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 16:17:19 2009 +0100
findutils: Buildfixes.
commit eec968d8574149b01e2af523fbf4d62c3c65ce44 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 16:17:03 2009 +0100
coreutils: Buildfixes.
commit 9d4b355899b0cde2de6029dfc943d85af4ed1731 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 15:31:49 2009 +0100
naoki: Fix creation of /tools_xxx.
commit 2cc3ec08167248ab80671f7f5c2ac12ee838d400 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 15:31:24 2009 +0100
naoki: Fix downloading of patches.
commit b2d4af6cdbea929e83dc0542273b7a2e74d19c21 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 14:39:44 2009 +0100
kernel-headers: Remove awkward files .install and ..install.cmd.
commit 331006980d80615ec02fd71fd2060c5e1e5f0011 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 11:06:06 2009 +0100
Update .gitignore.
commit 8ac49cd149b2f1b9c1109d1ec7ebc9e226608b1e Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 11:04:32 2009 +0100
New package: pkg-config.
commit 4a150286a35067d7d31adb08644f8967e13b8bd3 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 11:03:48 2009 +0100
e2fsprogs: Add dependency "util-linux-ng".
commit 68543fda163f39757f4dd9f870a239761fb0f780 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 10:51:56 2009 +0100
kernel: Add patch to fix scsi.h.
commit 88b867dfa5e436a418cae474dd01f81b63ebb814 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 10:51:35 2009 +0100
New package: util-linux-ng.
commit 6620ccf1b61f5ccc23022b0617bc9bbc3bc45985 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 00:18:50 2009 +0100
New package: libtool.
commit 798d27716e6ccf215e86093f0580d9fe1e5a89e3 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 00:18:31 2009 +0100
New package: bison.
commit a904827c00b3b0695fa7aa3b323d19298ad5f7fb Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 00:18:11 2009 +0100
New package: readline.
commit c8336c879a25351a549252653df8a9b5e268ec92 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 00:09:07 2009 +0100
bash: Buildfixes.
commit 990e0b8699b41a58979db715479be445b0939c66 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 27 00:08:50 2009 +0100
kernel: Buildfixes.
commit d39d12bbd541ca535485e4969aaa0cee71ee0ce9 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 23:05:36 2009 +0100
pax-utils: Has got dep to "libcap".
commit 914c26ed1e9646fe06d878db6eadd8f6a2f1974d Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 23:04:22 2009 +0100
autoconf: Has runtime dep "m4".
commit de54816b780dfed7d5e10159570db1892f4b3bf8 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 22:40:55 2009 +0100
attr: Add build deps "libtool" and "make".
commit fde62a2fe526baae56047bc9a6434c2ac80685f5 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 22:40:33 2009 +0100
acl: Fix build and add dep "gettext".
commit 4ef1578ebaf2d8664f53d0140ba56f81b0a7f6b7 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 22:39:52 2009 +0100
gettext: Has got build dependency "m4".
commit eb84cec10e39a6e9314eac7a2e1a327169b67258 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 22:10:43 2009 +0100
naoki: Throw a warning when package is tried to be decompressed but was not built, yet.
commit 9efad0d0adc20e5471b19e989ebf5d10dd8e6630 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 22:09:48 2009 +0100
New package: ccache.
Plus: Integration to naoki.
commit fd0be921f01f76b5bc4561af2bbe481c8a7e1ef1 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 21:23:09 2009 +0100
Revert "naoki: Speed up make."
This reverts commit 3c77dffcf2ec4eab7ce8aedc7af38dc0439a9c52.
commit d221e0eea8e7ee9ba47d05e51571ceb5b2c31ffb Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 20:47:08 2009 +0100
naoki: Add libtool to mandatory packages.
commit 8983c3ffd67ceb008a45187b64cf4ece7e33678a Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 20:46:11 2009 +0100
naoki: Remove decompression message of dep package.
The extractor tool produces this message as well.
commit 8c5a8e97666678f9b074ba0e6c55e08af9218819 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 20:45:41 2009 +0100
naoki: Fix resolving of mandantory toolchain packages.
commit 30b44af50162d8457801dd452bd6a1e1ee967453 Author: Michael Tremer michael.tremer@ipfire.org Date: Thu Nov 26 20:44:19 2009 +0100
naoki: Fix mounting of directories.
commit aa2216ade4f472db95fd4958ae476da7fb893ebc Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Nov 25 23:12:04 2009 +0100
pkgs/Include: Make targets .PHONY.
commit 72d2189b4dcf57bf524e598adcf1942d6822961e Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Nov 25 23:08:54 2009 +0100
Change package files.
commit 75a3e4fca7d48ea367e13dc0212a42be4e626cba Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Nov 25 23:08:26 2009 +0100
naoki: Fix building of packages.
commit 3c77dffcf2ec4eab7ce8aedc7af38dc0439a9c52 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Nov 25 13:03:04 2009 +0100
naoki: Speed up make.
Don't load implicit rules to save memory and speed up the system.
commit d88b81096635fcba6c6d6ed2447d0a97c9d74715 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 23:06:16 2009 +0100
naoki: Packages that we depend on are properly extracted now.
commit f150d126f445d389736e212f47009048e8d90b0f Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 19:26:04 2009 +0100
naoki: Misc things.
A buildfix and some dependency things.
commit 8def02b46d80d80f937e83899fec0dd12798ea7a Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 19:25:37 2009 +0100
naoki: Changed dep resolving.
commit ed8f7f835125968b897320d4d177623d7f8435d6 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 18:27:14 2009 +0100
attr: Fix build.
commit 3c2a0374ce9745d7cd5bc00846a78c1bf2123021 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 18:19:15 2009 +0100
naoki: Make package list more verbose.
commit eb95597e0ddf6b1aa895daac48f030572b92d1d1 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 18:17:38 2009 +0100
naoki: Don't install full chroot when building toolchain.
commit 2a40e833d93b11a6900c7f5c44287f09ae1f8a0f Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 18:17:08 2009 +0100
naoki: Changes some paths.
commit 4cfc2057ab276a23e1fcc79c9ed89952e6cea5d0 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 18:16:40 2009 +0100
naoki: Fix toolchain builds.
commit 2fe99a07c0c0399becc527024db7eaa67b447460 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 18:15:16 2009 +0100
naoki: Changed paths and added group of mandatory packages.
commit bffb3f3b9f542fbc9513a8c6b339c74a33d0f08a Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Nov 22 18:11:03 2009 +0100
naoki: Fix building toolchain packages.
commit b1713869ac73a56cc00f6a268beb09fe665d5fe3 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Nov 21 17:09:19 2009 +0100
naoki: Fall back to toolchain if a command is not available.
commit 1a9fda212a9ab9bf56fd1045097d9bd03880548e Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 20 14:22:46 2009 +0100
gcc: Fix installation of /lib/cpp.
commit f3c626598f8e0481ce9a77c87d61a8fc2a3446ef Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 20 11:37:13 2009 +0100
naoki: Add some more files to toolchain.
Add files to provide DNS resolving and add /etc/fstab and /etc/mtab.
commit dfe01258e94d96e3f6667827a7a3643d13006782 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Nov 20 11:34:10 2009 +0100
QA: Add some additional libs that cannot be vanished.
commit a7c9743429e3fe0d9cdc06ee89936181356d3903 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Nov 17 23:56:36 2009 +0100
naoki: Config and Rules --> Include.
commit 17c0ee8a7d5b9b1a96a90539aba10162ccc8eb7e Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Nov 16 21:59:36 2009 +0100
naoki: Mixed things.
(Can't break this down to several commits.)
- Changed layout of the package files (slightly).
commit 889b82e7350bc4ac089a3e222b77c5de513cf4a1 Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Nov 16 21:57:43 2009 +0100
naoki: Rewrite of downloader.
This is just to handle more than one file at once. Has to be reworked soon.
commit a4d6eeb3e4ba9317268d9e44e24b4ce9f7c7af35 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Oct 31 19:39:15 2009 +0100
Add new package: libcap.
commit 69b4aebfe91fd53977639cb0508a378cf8b3d6a8 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Oct 31 19:38:49 2009 +0100
Some fixes on the packages.
Removed unused lines, etc.
commit 7cfd59ee6eda796d5a970e2ba16e3da1f1a1f2c1 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Oct 31 19:37:51 2009 +0100
naoki: Decompress already built packages.
commit 6edb7ef6bef9e0c0fb7c6399a1ac303e809e3d8c Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Oct 31 14:15:40 2009 +0100
naoki: Mix of changes.
(Wasn't able to break this down to several commits.)
* Added QA. * Fixed downloading. * Fixed logging.
commit 9948bd8f9193ad8f7e8b402b5ecc28da61d669ae Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Oct 31 12:27:08 2009 +0100
Added package "cpio".
commit cee183e8af613c5c7e5b84aa7386e43e5c444c06 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Oct 31 12:26:27 2009 +0100
naoki: Code cleanup. No functional changes.
commit 7ab3aafef318bfcddb284955632d8dddb8032ea2 Author: Michael Tremer michael.tremer@ipfire.org Date: Fri Oct 30 17:46:26 2009 +0100
naoki: Improve validation of a package.
commit d4b033a04e6b61aaf4294a0b5976815bfd0264c8 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Oct 28 21:56:40 2009 +0100
Add GNU Make Standard Library.
commit f707eae8bd1359bbe906fc26dcaad2173b940759 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Oct 28 21:55:27 2009 +0100
naoki: Log dependency information.
commit 4ad2bb39ca922e9e1a8d98f2b45da7fadf72685d Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Oct 28 21:53:15 2009 +0100
make: Had a dep to itself.
commit 48add3fde5b28bd64aca38a4975cc8a1202b525c Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Oct 28 21:18:35 2009 +0100
naoki: Development packages are no defaults.
commit 79f35170560f63b622ca60ec932ab007bd60d598 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Oct 28 21:13:58 2009 +0100
naoki: Fixes on chroot environment.
commit f6c2d5178a5ba1d1efb685c088f70608feea2809 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Oct 28 21:13:19 2009 +0100
Some general build fixes.
commit 166a6c21f203e9b044d77446423079ca162b126b Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Oct 27 16:24:34 2009 +0100
naoki: Initial checkin.
-----------------------------------------------------------------------
Summary of changes: .config-default | 139 - .gitignore | 9 +- config/architectures.conf | 44 + config/logging.ini | 83 + config/naoki.conf | 27 + lfs/Config | 262 - lfs/acl | 138 - lfs/adjust-toolchain | 95 - lfs/aiccu | 90 - lfs/attr | 119 - lfs/autoconf | 104 - lfs/automake | 103 - lfs/avahi | 108 - lfs/bash | 154 - lfs/berkeley | 99 - lfs/binutils | 157 - lfs/bison | 109 - lfs/bridge-utils | 95 - lfs/btrfs-progs | 92 - lfs/bwm-ng | 88 - lfs/bzip2 | 111 - lfs/ccache | 101 - lfs/coreutils | 139 - lfs/cryptsetup-luks | 94 - lfs/cups | 100 - lfs/curl | 109 - lfs/cyrus-sasl | 101 - lfs/dbus | 100 - lfs/dbus-glib | 96 - lfs/dhcp | 109 - lfs/diffutils | 110 - lfs/directfb | 111 - lfs/dmraid | 97 - lfs/dosfstools | 86 - lfs/dvdrtools | 92 - lfs/ebtables | 98 - lfs/etherwake | 86 - lfs/eventlog | 95 - lfs/expat | 97 - lfs/ez-ipupdate | 97 - lfs/file | 108 - lfs/firewall | 86 - lfs/flex | 116 - lfs/freetype | 101 - lfs/fuse | 100 - lfs/gawk | 111 - lfs/gcc | 263 - lfs/gdb | 93 - lfs/gettext | 122 - lfs/ghostscript | 106 - lfs/glib2 | 100 - lfs/glibc | 318 - lfs/gnupg2 | 94 - lfs/gnutls | 99 - lfs/gobject-introspection | 98 - lfs/gperf | 93 - lfs/grep | 110 - lfs/grub | 155 - lfs/gssdp | 89 - lfs/gupnp | 92 - lfs/gupnp-av | 91 - lfs/gupnp-igd | 90 - lfs/gupnp-media-server | 94 - lfs/gzip | 124 - lfs/hal | 102 - lfs/hal-info | 91 - lfs/hostapd | 89 - lfs/hplip | 93 - lfs/iana-etc | 86 - lfs/icecc | 95 - lfs/images-core | 1 - lfs/images-info | 1 - lfs/images-initramfs | 1 - lfs/images-overlays | 1 - lfs/initscripts | 101 - lfs/intltool | 91 - lfs/iproute2 | 91 - lfs/iptables | 128 - lfs/iputils | 133 - lfs/iw | 94 - lfs/joe | 90 - lfs/jwhois | 122 - lfs/kbd | 104 - lfs/l7-protocols | 87 - lfs/ldapvi | 93 - lfs/less | 95 - lfs/libaal | 91 - lfs/libart | 96 - lfs/libassuan | 95 - lfs/libbdevid | 86 - lfs/libcap2 | 93 - lfs/libdaemon | 94 - lfs/libdnet | 100 - lfs/libevent | 98 - lfs/libgcrypt | 94 - lfs/libgpg-error | 94 - lfs/libgssglue | 94 - lfs/libidn | 97 - lfs/libjpeg | 95 - lfs/libksba | 93 - lfs/libnetfilter_conntrack | 94 - lfs/libnetfilter_log | 95 - lfs/libnetfilter_queue | 95 - lfs/libnfnetlink | 94 - lfs/libnfsidmap | 93 - lfs/libnl | 97 - lfs/libpcap | 97 - lfs/libpng | 101 - lfs/librpcsecgss | 95 - lfs/libsoup | 92 - lfs/libssh2 | 92 - lfs/libtiff | 115 - lfs/libtool | 95 - lfs/libusb | 92 - lfs/libusb-compat | 93 - lfs/libuser | 97 - lfs/libvirt | 97 - lfs/libxml2 | 101 - lfs/libxslt | 100 - lfs/lighttpd | 108 - lfs/linux | 199 - lfs/linux-atm | 98 - lfs/linux-headers | 1 - lfs/lm-sensors | 88 - lfs/logrotate | 101 - lfs/lsof | 87 - lfs/lvm2 | 99 - lfs/lzo | 97 - lfs/make | 106 - lfs/man-db | 99 - lfs/man-pages | 84 - lfs/mc | 98 - lfs/mdadm | 94 - lfs/memtest86+ | 88 - lfs/mkinitramfs | 87 - lfs/module-init-tools | 103 - lfs/nano | 93 - lfs/nasm | 90 - lfs/ncurses | 142 - lfs/net-snmp | 111 - lfs/network | 95 - lfs/nfs-utils | 104 - lfs/nmap | 96 - lfs/noip | 87 - lfs/nss_ldap | 98 - lfs/ntp | 100 - lfs/openldap | 131 - lfs/openlldp | 92 - lfs/openssh | 105 - lfs/pakfire | 84 - lfs/pam_ldap | 93 - lfs/pango | 92 - lfs/parted | 101 - lfs/passwd | 93 - lfs/patch | 113 - lfs/pax-utils | 95 - lfs/paxctl | 86 - lfs/pciutils | 88 - lfs/pcre | 101 - lfs/pdns | 98 - lfs/pdns-recursor | 90 - lfs/perl | 150 - lfs/perl-xml-parser | 91 - lfs/pinentry | 96 - lfs/pixman | 100 - lfs/pkg-config | 90 - lfs/popt | 93 - lfs/portmap | 96 - lfs/ppp | 142 - lfs/pptp | 90 - lfs/procps | 89 - lfs/psmisc | 94 - lfs/pth | 96 - lfs/pychecker | 87 - lfs/pyfire | 84 - lfs/python-IPy | 90 - lfs/python-cracklib | 1 - lfs/python-cryptsetup | 87 - lfs/python-dbus | 94 - lfs/python-flup | 90 - lfs/python-netfilter_conntrack | 90 - lfs/python-parted | 90 - lfs/python-pyblock | 85 - lfs/python-setuptools | 96 - lfs/python-sqlite2 | 87 - lfs/python-tornado | 90 - lfs/python-urlgrabber | 89 - lfs/python-werkzeug | 86 - lfs/qemu | 98 - lfs/radvd | 94 - lfs/reiser4progs | 94 - lfs/reiserfsprogs | 91 - lfs/rrdtool | 100 - lfs/rstp | 91 - lfs/sane | 119 - lfs/screen | 96 - lfs/scripts | 100 - lfs/sed | 107 - lfs/shadow | 121 - lfs/slang | 99 - lfs/smartmontools | 94 - lfs/splashy | 115 - lfs/squashfs-tools | 86 - lfs/squid | 144 - lfs/stage2 | 123 - lfs/stage3 | 99 - lfs/stage5 | 80 - lfs/strace | 92 - lfs/strip | 95 - lfs/strongswan | 105 - lfs/sysfsutils | 91 - lfs/syslog-ng | 108 - lfs/system-release | 85 - lfs/sysvinit | 92 - lfs/tar | 123 - lfs/tcpdump | 95 - lfs/test-toolchain | 118 - lfs/texinfo | 105 - lfs/udev | 120 - lfs/ulogd2 | 106 - lfs/unzip | 93 - lfs/upstart | 113 - lfs/usb-key | 1 - lfs/usbutils | 92 - lfs/vala | 97 - lfs/vim | 104 - lfs/vlan | 84 - lfs/vsftpd | 115 - lfs/which | 89 - lfs/wireless-tools | 91 - lfs/xen | 103 - lfs/xfsprogs | 100 - lfs/xz | 114 - lfs/zlib | 117 - make.sh | 690 +- naoki/__init__.py | 151 + naoki/argparse.py | 2270 + naoki/chroot.py | 375 + naoki/constants.py | 136 + naoki/exception.py | 29 + naoki/logger.py | 54 + naoki/package.py | 449 + naoki/terminal.py | 46 + {tools => naoki}/urlgrabber/__init__.py | 0 {tools => naoki}/urlgrabber/byterange.py | 0 {tools => naoki}/urlgrabber/grabber.py | 0 {tools => naoki}/urlgrabber/keepalive.py | 0 {tools => naoki}/urlgrabber/mirror.py | 0 {tools => naoki}/urlgrabber/progress.py | 0 {tools => naoki}/urlgrabber/sslfactory.py | 0 naoki/util.py | 200 + pkgs/Constants | 81 + pkgs/Functions | 130 + src/rstp/bridge-stp => pkgs/Include | 10 +- pkgs/Targets | 50 + pkgs/__gmsl | 854 + lfs/webinterface => pkgs/core/acl/acl.nm | 83 +- pkgs/core/acl/patches/acl-2.2.47-build-1.patch | 36 + pkgs/core/acl/patches/acl-2.2.47-exitcode.patch | 27 + pkgs/core/acl/patches/acl-2.2.47-nfs4.patch | 3278 + pkgs/core/acl/patches/acl-2.2.47-params.patch | 154 + pkgs/core/acl/patches/acl-2.2.47-path_max.patch | 24 + pkgs/core/acl/patches/acl-2.2.47-segfault.patch | 11 + pkgs/core/acl/patches/acl-2.2.47-walk.patch.broken | 235 + src/pomona/pomona => pkgs/core/aiccu/aiccu.nm | 63 +- lfs/webinterface => pkgs/core/attr/attr.nm | 83 +- .../pomona => pkgs/core/autoconf/autoconf.nm | 46 +- .../rc.local => pkgs/core/automake/automake.nm | 31 +- lfs/stage1 => pkgs/core/avahi/avahi.nm | 90 +- lfs/fontconfig => pkgs/core/bash/bash.nm | 116 +- {src => pkgs/core}/bash/bashrc | 0 pkgs/core/bash/patches/bash-4.0-paths-1.patch | 30 + pkgs/core/bash/patches/bash-4.0-profile-1.patch | 12 + pkgs/core/bash/patches/bash-4.0-rng.patch | 149 + pkgs/core/bash/patches/bash-4.1-upstream-1.patch | 46 + pkgs/core/bash/patches/bash-4.1-upstream-2.patch | 63 + {src => pkgs/core}/bash/profile | 0 {src => pkgs/core/bash}/profile.d/extrapaths.sh | 0 {src => pkgs/core/bash}/profile.d/i18n.sh | 0 {src => pkgs/core/bash}/profile.d/umask.sh | 0 {src => pkgs/core}/bash/shells | 0 lfs/bc => pkgs/core/bc/bc.nm | 82 +- lfs/beep => pkgs/core/beep/beep.nm | 74 +- lfs/bind => pkgs/core/bind/bind.nm | 74 +- lfs/cairo => pkgs/core/binutils/binutils.nm | 98 +- .../patches/binutils-2.19.1-asprintf_fix.patch | 16 + .../patches/binutils-2.19.1-ld_makefile.patch | 54 + .../binutils/patches/binutils-2.20-pt_pax-1.patch | 411 + lfs/cairo => pkgs/core/bison/bison.nm | 89 +- lfs/boost => pkgs/core/boost/boost.nm | 98 +- .../core/boost/patches/boost-1.39.0-fs_gcc44.patch | 163 + .../patches/boost-1.39.0-function_template.patch | 15 + .../boost-1.39.0-unneccessary_iostreams.patch | 11 + .../patches/boost-1.39.0-version-override.patch | 36 + lfs/br2684ctl => pkgs/core/br2684ctl/br2684ctl.nm | 72 +- .../core/bridge-utils/bridge-utils.nm | 66 +- lfs/stage4 => pkgs/core/btrfs-progs/btrfs-progs.nm | 67 +- .../rc.local => pkgs/core/bwm-ng/bwm-ng.nm | 28 +- lfs/cairo => pkgs/core/bzip2/bzip2.nm | 93 +- .../bzip2/patches/bzip2-1.0.5-install_docs-1.patch | 42 + .../sysconfig/rc.local => pkgs/core/cairo/cairo.nm | 32 +- lfs/stage1 => pkgs/core/ccache/ccache.nm | 75 +- pkgs/core/ccache/patches/ccache-2.4.patch | 12 + lfs/paxtest => pkgs/core/coreutils/coreutils.nm | 93 +- {src => pkgs/core/coreutils}/pam.d/su | 0 {src => pkgs/core/coreutils}/pam.d/su-l | 0 .../patches/coreutils-7.6-uname_PIC-1.patch.off | 204 + .../coreutils/patches/coreutils-8.4-i18n.patch | 4044 + .../core/coreutils/patches/coreutils-8.4-pam.patch | 428 + .../core/coreutils}/profile.d/dircolors.sh | 0 lfs/cpio => pkgs/core/cpio/cpio.nm | 80 +- lfs/cracklib => pkgs/core/cracklib/cracklib.nm | 115 +- .../core/cryptsetup-luks/cryptsetup-luks.nm | 64 +- .../extras/cups.conf => pkgs/core/cups/cups.init | 0 src/pomona/pomona => pkgs/core/cups/cups.nm | 64 +- lfs/cairo => pkgs/core/curl/curl.nm | 105 +- .../core/cyrus-sasl/cyrus-sasl.nm | 76 +- .../patches/cyrus-sasl-2.1.23-bad-elif.patch | 21 + {src => pkgs/core}/cyrus-sasl/smtpd.conf | 0 lfs/stage4 => pkgs/core/db/db.nm | 76 +- .../db/patches/db-4.7.25-upstream_fixes-1.patch | 64 + .../pomona => pkgs/core/dbus-glib/dbus-glib.nm | 60 +- src/pomona/pomona => pkgs/core/dbus/dbus.nm | 65 +- .../extras => pkgs/core/dbus}/messagebus.conf | 0 src/pomona/pomona => pkgs/core/dejagnu/dejagnu.nm | 57 +- {src => pkgs/core}/dhcp/dhclient-script | 0 lfs/webinterface => pkgs/core/dhcp/dhcp.nm | 89 +- .../pomona => pkgs/core/diffutils/diffutils.nm | 46 +- .../patches/diffutils-2.8.1-hardened_tmp-1.patch | 31 + .../diffutils/patches/diffutils-2.8.1-i18n-1.patch | 802 + lfs/stage4 => pkgs/core/directfb/directfb.nm | 88 +- lfs/stage1 => pkgs/core/dmraid/dmraid.nm | 83 +- lfs/stage4 => pkgs/core/dosfstools/dosfstools.nm | 69 +- src/pomona/pomona => pkgs/core/dracut/dracut.nm | 64 +- .../core/dracut/patches/dracut-004-emergency.patch | 19 + pkgs/core/dracut/patches/dracut-004-firmware.patch | 19 + .../pomona => pkgs/core/dvdrtools/dvdrtools.nm | 57 +- lfs/e2fsprogs => pkgs/core/e2fsprogs/e2fsprogs.nm | 103 +- lfs/webinterface => pkgs/core/ebtables/ebtables.nm | 83 +- .../pomona => pkgs/core/etherwake/etherwake.nm | 62 +- .../etherwake/patches/etherwake-1.09-install.patch | 10 + .../pomona => pkgs/core/eventlog/eventlog.nm | 59 +- src/pomona/pomona => pkgs/core/expat/expat.nm | 60 +- lfs/stage4 => pkgs/core/expect/expect.nm | 80 +- .../core/expect/patches/expect-5.32.2-random.patch | 19 + .../expect/patches/expect-5.38.0-lib-spec.patch | 12 + .../core/expect/patches/expect-5.39.0-libdir.patch | 12 + .../expect-5.43.0-override_default_prefix.patch | 12 + .../expect/patches/expect-5.43.0-spawn-1.patch | 217 + .../patches/expect-5.43.0-tcl_8.5.8_fix-1.patch | 125 + .../core/ez-ipupdate/ez-ipupdate.nm | 33 +- .../patches/ez-ipupdate-3.0.11b8-10.patch | 8024 ++ .../patches/ez-ipupdate-3.0.11b8-pidfile.patch | 11 + lfs/stage4 => pkgs/core/file/file.nm | 74 +- lfs/findutils => pkgs/core/findutils/findutils.nm | 91 +- .../core/firewall/firewall.init | 0 .../pomona => pkgs/core/firewall/firewall.nm | 63 +- {src/firewall => pkgs/core/firewall/src}/firewall | 0 {src/firewall => pkgs/core/firewall/src}/functions | 0 .../core/firewall/src}/functions.commands | 0 .../core/firewall/src}/functions.config | 0 .../core/firewall/src}/functions.firewall | 0 .../core/firewall/src}/functions.ip | 0 .../core/firewall/src}/functions.iptables | 0 .../core/firewall/src}/functions.macros | 0 .../core/firewall/src}/functions.zones | 0 .../core/firewall/src}/macros/DHCP | 0 .../core/firewall/src}/macros/HTTP | 0 .../core/firewall/src}/macros/HTTPS | 0 .../firewall => pkgs/core/firewall/src}/macros/WWW | 0 .../firewall => pkgs/core/firewall/src}/zones.blue | 0 .../core/firewall/src}/zones.green | 0 .../core/firewall/src}/zones.orange | 0 {src/firewall => pkgs/core/firewall/src}/zones.red | 0 lfs/webinterface => pkgs/core/flex/flex.nm | 91 +- pkgs/core/flex/patches/flex-2.5.35-gcc44-1.patch | 24 + .../pomona => pkgs/core/fontconfig/fontconfig.nm | 57 +- .../core/freeradius/freeradius.init | 0 .../core/freeradius/freeradius.nm | 91 +- .../core/freeradius/freeradius.pam | 0 .../core/freeradius/logrotate/freeradius | 0 .../patches/freeradius-2.1.6-cert-config.patch | 68 + .../pomona => pkgs/core/freetype/freetype.nm | 61 +- src/pomona/pomona => pkgs/core/fuse/fuse.nm | 56 +- pkgs/core/fuse/patches/fuse-2.7.4-openfix.patch | 36 + pkgs/core/fuse/patches/fuse-2.7.4-udev_rules.patch | 5 + lfs/stage1 => pkgs/core/gawk/gawk.nm | 79 +- pkgs/core/gcc/gcc.nm | 129 + .../gcc/patches/gcc-4.4-optimize_linking.patch | 24 + pkgs/core/gcc/patches/gcc-4.4.1-asprintf_fix.patch | 16 + pkgs/core/gcc/patches/gcc-4.4.1-espf-1.patch | 504 + src/pomona/pomona => pkgs/core/gdb/gdb.nm | 55 +- src/pomona/pomona => pkgs/core/gdbm/gdbm.nm | 62 +- lfs/stage1 => pkgs/core/gettext/gettext.nm | 77 +- .../gettext/patches/gettext-0.17-automake-1.patch | 27 + .../gettext/patches/gettext-0.17-open-args-1.patch | 25 + .../gettext/patches/gettext-0.17-rpathFix.patch | 140 + .../core/ghostscript/ghostscript.nm | 89 +- {src/glib => pkgs/core/glib2}/glib2-locale.sh | 0 lfs/stage4 => pkgs/core/glib2/glib2.nm | 77 +- .../core/glibc/glibc-stack_chk_fail.c | 0 pkgs/core/glibc/glibc.nm | 233 + {src => pkgs/core}/glibc/ld.so.conf | 0 {src => pkgs/core}/glibc/nsswitch.conf | 0 .../glibc/patches/glibc-2.10.1-arc4random.patch | 541 + .../glibc-2.10.1-asprintf_reset2null-1.patch | 59 + ...libc-2.10.1-hardened-configure-picdefault.patch | 29 + .../glibc-2.10.1-hardened-inittls-nosysenter.patch | 273 + .../glibc-2.10.1-localedef_trampoline-1.patch | 64 + .../core/glibc/patches/glibc-2.10.1-pt_pax-1.patch | 40 + .../patches/glibc-2.10.1-sanitize_env.patch.off | 1062 + .../patches/glibc-2.10.1-strlcpy_strlcat-1.patch | 349 + .../patches/glibc-2.10.1-undefine-__i686.patch | 44 + .../glibc/patches/glibc-2.11.1-hardened-pie.patch | 38 + .../patches/glibc-2.11.1-mktemp_urandom.patch | 161 + .../glibc-2.11.1-owl-alt-res_randomid.patch | 317 + lfs/gmp => pkgs/core/gmp/gmp.nm | 73 +- src/pomona/pomona => pkgs/core/gnupg2/gnupg2.nm | 56 +- src/pomona/pomona => pkgs/core/gnutls/gnutls.nm | 56 +- .../gobject-introspection/gobject-introspection.nm | 55 +- src/pomona/pomona => pkgs/core/gperf/gperf.nm | 46 +- lfs/stage1 => pkgs/core/grep/grep.nm | 78 +- lfs/groff => pkgs/core/groff/groff.nm | 106 +- .../patches/groff-1.18.1.4-debian_fixes-1.patch |18983 +++++ {src/bootloader => pkgs/core/grub}/grub.conf | 0 lfs/webinterface => pkgs/core/grub/grub.nm | 93 +- {src/bootloader => pkgs/core/grub}/splash.xpm.gz | 0 .../sysconfig/rc.local => pkgs/core/gssdp/gssdp.nm | 31 +- .../rc.local => pkgs/core/gupnp-av/gupnp-av.nm | 34 +- .../rc.local => pkgs/core/gupnp-igd/gupnp-igd.nm | 33 +- src/pomona/pomona => pkgs/core/gupnp/gupnp.nm | 55 +- lfs/webinterface => pkgs/core/gzip/gzip.nm | 81 +- .../patches/gzip-1.3.13-cve-2006-4337_len.patch | 15 + .../gzip/patches/gzip-1.3.13-cve-2006-4338.patch | 33 + .../gzip/patches/gzip-1.3.13-openbsd-owl-tmp.patch | 47 + lfs/hdparm => pkgs/core/hdparm/hdparm.nm | 70 +- {src => pkgs/core}/hostapd/config | 0 lfs/stage4 => pkgs/core/hostapd/hostapd.nm | 75 +- src/pomona/pomona => pkgs/core/hplip/hplip.nm | 57 +- .../sysconfig/rc.local => pkgs/core/htop/htop.nm | 35 +- lfs/stage4 => pkgs/core/iana-etc/iana-etc.nm | 64 +- .../core => pkgs/core/initscripts}/functions | 0 .../core/initscripts/init}/checkfs.conf | 0 .../core/initscripts/init}/cleanfs.conf | 0 .../core/initscripts/init}/control-alt-delete.conf | 0 .../core/initscripts/init}/load-modules.conf | 0 .../core/initscripts/init}/loopback.conf | 0 .../init}/mount-kernel-filesystems.conf | 0 .../core/initscripts/init}/mountfs.conf | 0 .../core/initscripts/init}/serial.conf | 0 .../core/initscripts/init}/shutdown.conf | 0 .../core => pkgs/core/initscripts/init}/swap.conf | 0 .../core/initscripts/init}/sysctl.conf | 0 .../core => pkgs/core/initscripts/init}/tty1.conf | 0 .../core => pkgs/core/initscripts/init}/tty2.conf | 0 .../core => pkgs/core/initscripts/init}/tty3.conf | 0 .../core => pkgs/core/initscripts/init}/tty4.conf | 0 .../core => pkgs/core/initscripts/init}/udev.conf | 0 .../core/initscripts/init}/udevtrigger.conf | 0 .../core/initscripts/init}/welcome.conf | 0 lfs/stage4 => pkgs/core/initscripts/initscripts.nm | 75 +- {src => pkgs/core}/initscripts/src/Makefile | 0 {src => pkgs/core}/initscripts/src/console_check.c | 0 {src => pkgs/core}/initscripts/src/securetty.c | 0 {src => pkgs/core}/initscripts/sysconfig/clock | 0 .../core}/initscripts/sysconfig/createfiles | 0 {src => pkgs/core}/initscripts/sysconfig/modules | 0 {src => pkgs/core}/initscripts/sysconfig/network | 0 {src => pkgs/core}/initscripts/sysconfig/rc | 0 {src => pkgs/core}/initscripts/sysconfig/rc.local | 0 {src => pkgs/core}/initscripts/sysconfig/rc.site | 0 .../etc => pkgs/core/initscripts}/sysctl.conf | 0 .../pomona => pkgs/core/intltool/intltool.nm | 54 +- lfs/webinterface => pkgs/core/iproute2/iproute2.nm | 79 +- .../patches/iproute2-2.6.29-1-opt_flags.patch | 12 + pkgs/core/iptables/iptables.nm | 87 + pkgs/core/iputils/iputils.nm | 88 + .../patches/iputils-s20071127-addrcache.patch | 31 + .../iputils-s20071127-arping-infiniband.patch | 244 + .../patches/iputils-s20071127-arping_timeout.patch | 65 + .../iputils-s20071127-countermeasures.patch | 12 + .../iputils/patches/iputils-s20071127-idn.patch | 130 + .../patches/iputils-s20071127-open-max.patch | 30 + .../iputils/patches/iputils-s20071127-output.patch | 34 + .../patches/iputils-s20071127-ping-subint.patch | 12 + .../patches/iputils-s20071127-ping_cleanup.patch | 50 + .../iputils/patches/iputils-s20071127-rh.patch | 13 + .../patches/iputils-s20071127-traffic_class.patch | 14 + .../patches/iputils-s20071127-warnings.patch | 126 + src/pomona/pomona => pkgs/core/iw/iw.nm | 62 +- .../iw-0.9.17-default-install-to-PREFIX-sbin.patch | 42 + .../sysconfig/rc.local => pkgs/core/joe/joe.nm | 32 +- src/pomona/pomona => pkgs/core/jwhois/jwhois.nm | 63 +- pkgs/core/jwhois/patches/jwhois-4.0-conf.patch | 47 + .../jwhois/patches/jwhois-4.0-conf_update.patch | 482 + .../jwhois/patches/jwhois-4.0-conf_update2.patch | 90 + .../jwhois/patches/jwhois-4.0-conf_update3.patch | 61 + .../jwhois/patches/jwhois-4.0-conf_update4.patch | 168 + pkgs/core/jwhois/patches/jwhois-4.0-connect.patch | 58 + pkgs/core/jwhois/patches/jwhois-4.0-dotster.patch | 13 + pkgs/core/jwhois/patches/jwhois-4.0-enum.patch | 43 + pkgs/core/jwhois/patches/jwhois-4.0-fclose.patch | 12 + pkgs/core/jwhois/patches/jwhois-4.0-gi.patch | 12 + .../core/jwhois/patches/jwhois-4.0-ipv6match.patch | 15 + lfs/webinterface => pkgs/core/kbd/kbd.nm | 79 +- pkgs/core/kbd/patches/kbd-1.15.1-backspace-1.patch | 250 + pkgs/core/kernel-headers/kernel-headers.nm | 18 + pkgs/core/kernel-headers/patches | 1 + .../kernel.config => pkgs/core/kernel/config | 0 {src => pkgs/core}/kernel/ipfire_logo.ppm | 0 pkgs/core/kernel/kernel.nm | 110 + pkgs/core/kernel/patches/aufs2-2.6.31.1-1.patch |25456 +++++++ .../grsecurity-2.1.14-2.6.31.1-200910012153.patch |47055 ++++++++++++ .../linux-2.6.31.1-disable-compat_vdso-1.patch.off | 74 + .../patches/linux-2.6.31.1-scsi.h-fix-1.patch | 19 + .../core/kernel/patches/reiser4-for-2.6.31.1.patch |78369 ++++++++++++++++++++ pkgs/core/kernel/patches/routes-2.6.31.1-16.diff | 1333 + .../core/l7-protocols/l7-protocols.nm | 59 +- src/pomona/pomona => pkgs/core/ldapvi/ldapvi.nm | 61 +- src/pomona/pomona => pkgs/core/less/less.nm | 55 +- src/pomona/pomona => pkgs/core/libaal/libaal.nm | 58 +- .../rc.local => pkgs/core/libart/libart.nm | 31 +- .../libart_lgpl-2.3.19-upstream_fix-1.patch | 28 + .../pomona => pkgs/core/libassuan/libassuan.nm | 59 +- .../libassuan/patches/libassuan-1.0.5-ac.patch | 26 + .../libassuan/patches/libassuan-1.0.5-shared.patch | 59 + lfs/webinterface => pkgs/core/libcap/libcap.nm | 78 +- .../libcap/patches/libcap-2.16-headerfix.patch | 12 + .../rc.local => pkgs/core/libdaemon/libdaemon.nm | 32 +- src/pomona/pomona => pkgs/core/libdnet/libdnet.nm | 50 +- .../core/libdnet/patches/libdnet-1.12-shrext.patch | 327 + .../pomona => pkgs/core/libevent/libevent.nm | 57 +- .../pomona => pkgs/core/libgcrypt/libgcrypt.nm | 60 +- .../core/libgpg-error/libgpg-error.nm | 58 +- .../rc.local => pkgs/core/libgssglue/libgssglue.nm | 30 +- lfs/stage4 => pkgs/core/libidn/libidn.nm | 78 +- .../rc.local => pkgs/core/libjpeg/libjpeg.nm | 35 +- .../rc.local => pkgs/core/libksba/libksba.nm | 31 +- .../libnetfilter_conntrack.nm | 46 +- .../core/libnetfilter_log/libnetfilter_log.nm | 47 +- .../core/libnetfilter_queue/libnetfilter_queue.nm | 47 +- .../core/libnfnetlink/libnfnetlink.nm | 45 +- lfs/stage4 => pkgs/core/libnfsidmap/libnfsidmap.nm | 73 +- src/pomona/pomona => pkgs/core/libnih/libnih.nm | 61 +- src/pomona/pomona => pkgs/core/libnl/libnl.nm | 58 +- .../libnl/patches/libnl-1.1-include-limits-h.patch | 11 + .../libnl/patches/libnl-1.1-no-extern-inline.patch | 57 + .../core/libnl/patches/libnl-1.1-permissions.patch | 13 + lfs/stage4 => pkgs/core/libpcap/libpcap.nm | 75 +- src/pomona/pomona => pkgs/core/libpng/libpng.nm | 48 +- .../libpng/patches/libpng-1.2.39-pngconf.patch | 42 + .../core/librpcsecgss/librpcsecgss.nm | 34 +- src/pomona/pomona => pkgs/core/libsoup/libsoup.nm | 55 +- lfs/stage4 => pkgs/core/libssh2/libssh2.nm | 68 +- src/pomona/pomona => pkgs/core/libtiff/libtiff.nm | 54 +- src/pomona/pomona => pkgs/core/libtool/libtool.nm | 44 +- .../core/libusb-compat/libusb-compat.nm | 34 +- .../rc.local => pkgs/core/libusb/libusb.nm | 30 +- src/pomona/pomona => pkgs/core/libuser/libuser.nm | 61 +- src/pomona/pomona => pkgs/core/libvirt/libvirt.nm | 55 +- src/pomona/pomona => pkgs/core/libxml2/libxml2.nm | 51 +- {src => pkgs/core}/lighttpd/lighttpd.conf | 0 .../core/lighttpd/lighttpd.init | 0 lfs/webinterface => pkgs/core/lighttpd/lighttpd.nm | 91 +- .../pomona => pkgs/core/linux-atm/linux-atm.nm | 63 +- .../linux-atm/patches/linux-atm-2.4.1-gcc-4.patch | 161 + .../linux-atm/patches/linux-atm-2.4.1-nmu.patch | 98 + .../pomona => pkgs/core/lm-sensors/lm-sensors.nm | 61 +- .../core/logrotate/logrotate.nm | 88 +- .../logrotate/patches/logrotate-3.7.7-curdir.patch | 15 + .../patches/logrotate-3.7.7-toolarge.patch | 17 + src/pomona/pomona => pkgs/core/lsof/lsof.nm | 62 +- lfs/lua => pkgs/core/lua/lua.nm | 84 +- pkgs/core/lua/patches/lua-5.1.4-autotoolize.patch |43660 +++++++++++ lfs/webinterface => pkgs/core/lvm2/lvm2.nm | 91 +- src/pomona/pomona => pkgs/core/lzo/lzo.nm | 55 +- lfs/m4 => pkgs/core/m4/m4.nm | 83 +- src/pomona/pomona => pkgs/core/make/make.nm | 60 +- lfs/stage1 => pkgs/core/man-db/man-db.nm | 77 +- .../rc.local => pkgs/core/man-pages/man-pages.nm | 33 +- lfs/stage4 => pkgs/core/mc/mc.nm | 75 +- pkgs/core/mc/patches/mc-4.6.2-utf8.patch | 7017 ++ lfs/webinterface => pkgs/core/mdadm/mdadm.nm | 87 +- .../core/mdadm/patches/mdadm-3.0-devel2-warn.patch | 24 + .../pomona => pkgs/core/memtest86+/memtest86+.nm | 62 +- lfs/stage4 => pkgs/core/mkinitramfs/mkinitramfs.nm | 72 +- .../core/mkinitramfs/src}/functions | 0 .../core/mkinitramfs/src}/lsinitramfs | 0 .../core/mkinitramfs/src}/mkinitramfs | 0 .../core/mkinitramfs/src}/mkliveramfs | 0 .../module-init-tools/modprobe.d/blacklist.conf | 0 .../module-init-tools/modprobe.d/modprobe.conf | 0 .../core/module-init-tools/module-init-tools.nm | 76 +- .../patches/module-init-tools-3.7-nostatic-1.patch | 100 + lfs/mpfr => pkgs/core/mpfr/mpfr.nm | 75 +- lfs/stage4 => pkgs/core/nano/nano.nm | 69 +- src/pomona/pomona => pkgs/core/nasm/nasm.nm | 55 +- lfs/cairo => pkgs/core/ncurses/ncurses.nm | 92 +- lfs/stage4 => pkgs/core/net-snmp/net-snmp.nm | 85 +- .../network.conf => pkgs/core/network/network.init | 0 lfs/stage4 => pkgs/core/network/network.nm | 72 +- {src/network => pkgs/core/network/src}/functions | 0 .../core/network/src}/functions.ppp | 0 {src/network => pkgs/core/network/src}/hook-header | 0 .../network => pkgs/core/network/src}/hooks/README | 0 .../core/network/src}/hooks/bonding | 0 .../core/network/src}/hooks/ethernet | 0 .../core/network/src}/hooks/ipv4-dhcp | 0 .../core/network/src}/hooks/ipv4-static | 0 .../core/network/src}/hooks/ipv4-static-route | 0 {src/network => pkgs/core/network/src}/hooks/mtu | 0 {src/network => pkgs/core/network/src}/hooks/pppoe | 0 .../core/network/src}/hooks/pppoe.helper | 0 {src/network => pkgs/core/network/src}/hooks/stp | 0 {src/network => pkgs/core/network/src}/hooks/vlan | 0 {src/network => pkgs/core/network/src}/network | 0 .../core/network/src}/ppp/ip-updown | 0 {src/network => pkgs/core/network/src}/zone | 0 lfs/newt => pkgs/core/newt/newt.nm | 85 +- .../core/nfs-utils/nfs-utils.nm | 94 +- src/pomona/pomona => pkgs/core/nmap/nmap.nm | 57 +- pkgs/core/nmap/patches/nmap-5.00-mktemp.patch | 23 + src/pomona/pomona => pkgs/core/noip/noip.nm | 59 +- .../pomona => pkgs/core/nss_ldap/nss_ldap.nm | 63 +- {src => pkgs/core}/ntp/ntp.conf | 0 .../extras/ntp.conf => pkgs/core/ntp/ntp.init | 0 src/pomona/pomona => pkgs/core/ntp/ntp.nm | 63 +- .../core/openldap/openldap.init | 0 lfs/paxtest => pkgs/core/openldap/openldap.nm | 119 +- .../patches/openldap-2.4.17-disable_sys_err.patch | 17 + {src => pkgs/core}/openldap/slapd.conf | 0 .../core/openlldp/openlldp.init | 0 .../rc.local => pkgs/core/openlldp/openlldp.nm | 29 +- .../openssh.conf => pkgs/core/openssh/openssh.init | 0 lfs/stage1 => pkgs/core/openssh/openssh.nm | 78 +- src/pam.d/login => pkgs/core/openssh/sshd.pam | 0 {src => pkgs/core}/openssh/sshd_config | 0 {src => pkgs/core}/openssl/openssl.cnf | 0 lfs/openssl => pkgs/core/openssl/openssl.nm | 117 +- .../patches/openssl-0.9.8k-enginesdir.patch | 39 + .../patches/openssl-0.9.8k-fix_manpages-1.patch | 1888 + .../openssl/patches/openssl-0.9.8k-no-rpath.patch | 11 + lfs/openvpn => pkgs/core/openvpn/openvpn.nm | 88 +- src/pomona/pomona => pkgs/core/pakfire/pakfire.nm | 58 +- {src/pakfire => pkgs/core/pakfire/src}/Makefile | 1 + .../pakfire => pkgs/core/pakfire/src}/decompressor | 2 +- {src/pakfire => pkgs/core/pakfire/src}/functions | 0 {src/pakfire => pkgs/core/pakfire/src}/index | 0 {src/pakfire => pkgs/core/pakfire/src}/pakfire.in | 0 .../core/pakfire/src}/python/__init__.py | 0 .../pakfire => pkgs/core/pakfire/src}/python/db.py | 0 .../pakfire => pkgs/core/pakfire/src}/python/io.py | 0 .../core/pakfire/src}/python/package.py | 0 .../core/pakfire/src}/python/repo.py | 0 .../core/pakfire/src}/python/servers.py | 0 .../core/pakfire/src}/python/transactionset.py | 0 {src => pkgs/core}/pam/login.defs | 0 {src => pkgs/core/pam}/pam.d/other | 0 {src => pkgs/core/pam}/pam.d/system-auth | 0 lfs/pam => pkgs/core/pam/pam.nm | 108 +- {src => pkgs/core}/pam/pam_env.conf | 0 .../pam/patches/Linux-PAM-1.1.0-no-yywrap-1.patch | 28 + {src => pkgs/core}/pam/securetty | 0 .../pomona => pkgs/core/pam_ldap/pam_ldap.nm | 55 +- .../sysconfig/rc.local => pkgs/core/pango/pango.nm | 35 +- src/pomona/pomona => pkgs/core/parted/parted.nm | 46 +- ...1-blkid_topology_get_physical_sector_size.patch | 30 + ...parted-2.1-dasd-NULL-dereference-rh563419.patch | 26 + .../patches/parted-2.1-default-alignment.patch | 842 + .../parted-2.1-gpt-clobber-pmbr-rh563211.patch | 146 + .../parted-2.1-mem-leak-fixes-rh556012.patch | 158 + .../parted-2.1-needs_clobber-rh566181.patch | 30 + lfs/stage4 => pkgs/core/passwd/passwd.nm | 71 +- src/pomona/pomona => pkgs/core/patch/patch.nm | 59 +- .../patch/patches/patch-2.6.1-test_fix-1.patch | 28 + lfs/stage4 => pkgs/core/pax-utils/pax-utils.nm | 62 +- lfs/stage4 => pkgs/core/paxctl/paxctl.nm | 63 +- src/pomona/pomona => pkgs/core/paxtest/paxtest.nm | 62 +- .../pomona => pkgs/core/pciutils/pciutils.nm | 63 +- lfs/stage1 => pkgs/core/pcre/pcre.nm | 76 +- .../core/pdns-recursor/pdns-recursor.init | 0 .../core/pdns-recursor/pdns-recursor.nm | 59 +- .../pdns/patches/pdns-2.9.22-gcc44-fixes.patch | 11 + src/pomona/pomona => pkgs/core/pdns/pdns.nm | 60 +- .../core/perl-xml-parser/perl-xml-parser.nm | 61 +- pkgs/core/perl/patches/perl-5.10.1-utf8-1.patch | 167 + lfs/fontconfig => pkgs/core/perl/perl.nm | 104 +- .../pomona => pkgs/core/pinentry/pinentry.nm | 59 +- src/pomona/pomona => pkgs/core/pixman/pixman.nm | 60 +- .../pomona => pkgs/core/pkg-config/pkg-config.nm | 56 +- src/pomona/pomona => pkgs/core/pomona/pomona.nm | 70 +- {src/pomona => pkgs/core/pomona/src}/Makefile | 0 {src/pomona => pkgs/core/pomona/src}/Makefile.inc | 2 +- {src/pomona => pkgs/core/pomona/src}/autopart.py | 0 {src/pomona => pkgs/core/pomona/src}/backend.py | 0 {src/pomona => pkgs/core/pomona/src}/bootloader.py | 0 {src/pomona => pkgs/core/pomona/src}/console.py | 0 {src/pomona => pkgs/core/pomona/src}/constants.py | 0 {src/pomona => pkgs/core/pomona/src}/cryptodev.py | 0 {src/pomona => pkgs/core/pomona/src}/dispatch.py | 0 {src/pomona => pkgs/core/pomona/src}/dmraid.py | 0 {src/pomona => pkgs/core/pomona/src}/errors.py | 0 {src/pomona => pkgs/core/pomona/src}/exception.py | 0 {src/pomona => pkgs/core/pomona/src}/flags.py | 0 {src/pomona => pkgs/core/pomona/src}/fsset.py | 0 {src/pomona => pkgs/core/pomona/src}/installer.py | 0 {src/pomona => pkgs/core/pomona/src}/instdata.py | 0 {src/pomona => pkgs/core/pomona/src}/isys/Makefile | 1 + .../pomona => pkgs/core/pomona/src}/isys/devices.c | 0 .../pomona => pkgs/core/pomona/src}/isys/devices.h | 0 .../core/pomona/src}/isys/eddsupport.c | 0 .../core/pomona/src}/isys/eddsupport.h | 0 .../pomona => pkgs/core/pomona/src}/isys/ethtool.c | 0 {src/pomona => pkgs/core/pomona/src}/isys/imount.c | 0 {src/pomona => pkgs/core/pomona/src}/isys/imount.h | 0 {src/pomona => pkgs/core/pomona/src}/isys/isofs.c | 0 {src/pomona => pkgs/core/pomona/src}/isys/isys.c | 0 {src/pomona => pkgs/core/pomona/src}/isys/isys.h | 0 {src/pomona => pkgs/core/pomona/src}/isys/isys.py | 0 {src/pomona => pkgs/core/pomona/src}/isys/lang.c | 0 {src/pomona => pkgs/core/pomona/src}/isys/lang.h | 0 .../core/pomona/src}/isys/linkdetect.c | 0 {src/pomona => pkgs/core/pomona/src}/isys/net.h | 0 {src/pomona => pkgs/core/pomona/src}/isys/smp.c | 0 {src/pomona => pkgs/core/pomona/src}/isys/smp.h | 0 {src/pomona => pkgs/core/pomona/src}/isys/str.c | 0 {src/pomona => pkgs/core/pomona/src}/isys/str.h | 0 {src/pomona => pkgs/core/pomona/src}/isys/stubs.h | 0 .../core/pomona/src}/isys/sundries.h | 0 {src/pomona => pkgs/core/pomona/src}/isys/vio.c | 0 .../core/pomona/src}/isys/wireless.c | 0 .../core/pomona/src}/isys/wireless.h | 0 {src/pomona => pkgs/core/pomona/src}/iutil.py | 0 .../core/pomona/src}/keyboard_models.py | 0 {src/pomona => pkgs/core/pomona/src}/lang-table | 0 {src/pomona => pkgs/core/pomona/src}/lvm.py | 0 {src/pomona => pkgs/core/pomona/src}/network.py | 0 {src/pomona => pkgs/core/pomona/src}/packages.py | 0 .../core/pomona/src}/pakfireinstall.py | 0 {src/pomona => pkgs/core/pomona/src}/partErrors.py | 0 .../core/pomona/src}/partIntfHelpers.py | 0 .../core/pomona/src}/partRequests.py | 0 .../pomona => pkgs/core/pomona/src}/partedUtils.py | 0 .../core/pomona/src}/partitioning.py | 0 {src/pomona => pkgs/core/pomona/src}/partitions.py | 0 {src/pomona => pkgs/core/pomona/src}/po/Makefile | 0 {src/pomona => pkgs/core/pomona/src}/po/da.po | 0 {src/pomona => pkgs/core/pomona/src}/po/de.po | 0 {src/pomona => pkgs/core/pomona/src}/po/pomona.pot | 0 {src/pomona => pkgs/core/pomona/src}/pomona | 0 {src/pomona => pkgs/core/pomona/src}/pomona_log.py | 0 .../core/pomona/src}/pychecker-false-positives | 0 {src/pomona => pkgs/core/pomona/src}/raid.py | 0 .../core/pomona/src}/runpychecker.sh | 0 .../core/pomona/src}/scripts/getlangnames.py | 0 pkgs/core/pomona/src/storage_old/__init__.py | 1176 + pkgs/core/pomona/src/storage_old/deviceaction.py | 352 + .../pomona/src/storage_old/devicelibs/__init__.py | 0 .../pomona/src/storage_old/devicelibs/crypto.py | 109 + pkgs/core/pomona/src/storage_old/devicelibs/lvm.py | 115 + .../core/pomona/src/storage_old/devicelibs/swap.py | 85 + pkgs/core/pomona/src/storage_old/devices.py | 1698 + pkgs/core/pomona/src/storage_old/devicetree.py | 536 + pkgs/core/pomona/src/storage_old/errors.py | 107 + .../pomona/src/storage_old/formats/__init__.py | 318 + pkgs/core/pomona/src/storage_old/formats/fs.py | 929 + pkgs/core/pomona/src/storage_old/formats/luks.py | 187 + pkgs/core/pomona/src/storage_old/formats/lvmpv.py | 85 + pkgs/core/pomona/src/storage_old/formats/swap.py | 112 + pkgs/core/pomona/src/storage_old/partitioning.py | 1059 + pkgs/core/pomona/src/storage_old/udev.py | 305 + pkgs/core/pomona/src/storage_test.py | 5 + {src/pomona => pkgs/core/pomona/src}/timezone.py | 0 {src/pomona => pkgs/core/pomona/src}/tui.py | 0 .../core/pomona/src}/tui_bootloader.py | 0 .../core/pomona/src}/tui_complete.py | 0 .../pomona => pkgs/core/pomona/src}/tui_confirm.py | 0 .../core/pomona/src}/tui_keyboard.py | 0 .../core/pomona/src}/tui_language.py | 0 .../pomona => pkgs/core/pomona/src}/tui_network.py | 0 .../core/pomona/src}/tui_partition.py | 0 .../core/pomona/src}/tui_progress.py | 0 .../core/pomona/src}/tui_timezone.py | 0 .../core/pomona/src}/tui_userauth.py | 0 .../pomona => pkgs/core/pomona/src}/tui_welcome.py | 0 {src/pomona => pkgs/core/pomona/src}/users.py | 0 {src/pomona => pkgs/core/pomona/src}/zonetab.py | 0 src/pomona/pomona => pkgs/core/popt/popt.nm | 58 +- .../ppp/patches/ppp-2.4.4-bogus_dns_addr.patch | 104 + pkgs/core/ppp/patches/ppp-2.4.4-closelog.patch | 20 + pkgs/core/ppp/patches/ppp-2.4.4-dontwriteetc.patch | 59 + pkgs/core/ppp/patches/ppp-2.4.4-fix.patch | 139 + .../ppp/patches/ppp-2.4.4-ipv6-accept-remote.patch | 40 + pkgs/core/ppp/patches/ppp-2.4.4-libutil.patch | 86 + pkgs/core/ppp/patches/ppp-2.4.4-local.patch | 68 + pkgs/core/ppp/patches/ppp-2.4.4-new_speeds.patch | 34 + pkgs/core/ppp/patches/ppp-2.4.4-pie.patch | 24 + pkgs/core/ppp/patches/ppp-2.4.4-pppoatm-mtu.patch | 28 + pkgs/core/ppp/patches/ppp-2.4.4-response_len.patch | 12 + lfs/cairo => pkgs/core/ppp/ppp.nm | 103 +- src/pam.d/ppp => pkgs/core/ppp/ppp.pam | 0 src/pomona/pomona => pkgs/core/pptp/pptp.nm | 65 +- .../patches/procps-3.2.8-watch_unicode-2.patch | 148 + src/pomona/pomona => pkgs/core/procps/procps.nm | 60 +- src/pomona/pomona => pkgs/core/psmisc/psmisc.nm | 49 +- lfs/stage4 => pkgs/core/pth/pth.nm | 68 +- .../pomona => pkgs/core/pychecker/pychecker.nm | 59 +- src/pomona/pomona => pkgs/core/pyfire/pyfire.nm | 57 +- {src/pyfire => pkgs/core/pyfire/src}/Makefile | 0 {src/pyfire => pkgs/core/pyfire/src}/__init__.py | 0 {src/pyfire => pkgs/core/pyfire/src}/config.py | 0 {src/pyfire => pkgs/core/pyfire/src}/executil.py | 0 {src/pyfire => pkgs/core/pyfire/src}/hal.py | 0 {src/pyfire => pkgs/core/pyfire/src}/net.py | 0 {src/pyfire => pkgs/core/pyfire/src}/web.py | 0 .../pomona => pkgs/core/python-IPy/python-IPy.nm | 58 +- .../core/python-cryptsetup/python-cryptsetup.nm | 57 +- .../core/python-dbus/python-dbus.nm | 33 +- .../core/python-decorator/python-decorator.nm | 61 +- .../python-netfilter_conntrack.nm | 58 +- .../core/python-parted/python-parted.nm | 32 +- .../core/python-pyblock/python-pyblock.nm | 61 +- .../core/python-setuptools/python-setuptools.nm | 79 +- .../core/python-tornado/python-tornado.nm | 59 +- .../core/python-urlgrabber/python-urlgrabber.nm | 57 +- pkgs/core/python/patches/python-2.6-rpath.patch | 12 + .../patches/python-2.6-update-bsddb3-4.8.patch | 3446 + .../patches/python-2.6.2-with-system-expat.patch | 67 + lfs/python => pkgs/core/python/python.nm | 87 +- src/pomona/pomona => pkgs/core/qemu/qemu.nm | 65 +- lfs/quagga => pkgs/core/quagga/quagga.nm | 65 +- src/pomona/pomona => pkgs/core/radvd/radvd.nm | 62 +- {src/bash => pkgs/core/readline}/inputrc | 0 .../core/readline/patches/readline-6.1-shlib.patch | 41 + .../readline/patches/readline-6.1-upstream-1.patch | 59 + .../readline/patches/readline-6.1-upstream-2.patch | 45 + lfs/readline => pkgs/core/readline/readline.nm | 90 +- .../patches/reiser4progs-1.0.7-bad_elif.patch | 12 + .../reiser4progs/patches/reiser4progs-libaal.patch | 12 + .../patches/reiser4progs-makefile.patch | 8 + .../reiser4progs/patches/reiser4progs-opt.patch | 18 + .../core/reiser4progs/reiser4progs.nm | 89 +- .../core/reiserfsprogs/reiserfsprogs.nm | 56 +- lfs/webinterface => pkgs/core/rrdtool/rrdtool.nm | 94 +- {src => pkgs/core}/rstp/bridge-stp | 0 .../extras/rstp.conf => pkgs/core/rstp/rstp.init | 0 src/pomona/pomona => pkgs/core/rstp/rstp.nm | 62 +- lfs/samba => pkgs/core/samba/samba.nm | 91 +- pkgs/core/sane/patches/sane-1.0.20-lockdir.patch | 30 + pkgs/core/sane/patches/sane-1.0.20-pkgconfig.patch | 211 + pkgs/core/sane/patches/sane-1.0.20-rpath.patch | 69 + pkgs/core/sane/patches/sane-1.0.20-udev.patch | 75 + src/pomona/pomona => pkgs/core/sane/sane.nm | 63 +- lfs/webinterface => pkgs/core/screen/screen.nm | 78 +- src/pam.d/screen => pkgs/core/screen/screen.pam | 0 pkgs/core/screen/screenrc | 254 + .../sysconfig/rc.local => pkgs/core/sdl/sdl.nm | 33 +- lfs/stage1 => pkgs/core/sed/sed.nm | 81 +- .../shadow/patches/shadow-4.1.4.2-goodname.patch | 70 + .../shadow/patches/shadow-4.1.4.2-ipfire.patch | 75 + lfs/cairo => pkgs/core/shadow/shadow.nm | 101 +- pkgs/core/slang/patches/slang-2.1.4-makefile.patch | 111 + src/pomona/pomona => pkgs/core/slang/slang.nm | 56 +- .../core/smartmontools/smartmontools.nm | 60 +- lfs/sqlite => pkgs/core/sqlite/sqlite.nm | 79 +- .../core/squashfs-tools/squashfs-tools.nm | 70 +- pkgs/core/squid/squid.nm | 104 + src/pomona/pomona => pkgs/core/strace/strace.nm | 54 +- .../core/strongswan/strongswan.nm | 99 +- lfs/sudo => pkgs/core/sudo/sudo.nm | 97 +- .../freeradius-server => pkgs/core/sudo/sudo.pam | 4 +- {src => pkgs/core}/sudo/sudoers | 0 .../rc.local => pkgs/core/sysfsutils/sysfsutils.nm | 31 +- lfs/syslinux => pkgs/core/syslinux/syslinux.nm | 80 +- {src => pkgs/core}/syslog-ng/ids-block | 0 {src => pkgs/core}/syslog-ng/logextract | 0 {src => pkgs/core}/syslog-ng/syslog-ng.conf | 0 .../core/syslog-ng/syslog-ng.init | 0 .../core/syslog-ng/syslog-ng.nm | 92 +- .../core/system-release/system-release.nm | 76 +- .../pomona => pkgs/core/sysvinit/sysvinit.nm | 61 +- pkgs/core/tar/patches/tar-1.22-vfatTruncate.patch | 29 + pkgs/core/tar/patches/tar-1.22-xattrs-1.patch | 1454 + pkgs/core/tar/patches/tar-1.22-xattrs-conf-1.patch | 799 + lfs/webinterface => pkgs/core/tar/tar.nm | 92 +- pkgs/core/tcl/patches/tcl-8.5.8-autopath.patch | 53 + pkgs/core/tcl/patches/tcl-8.5.8-conf.patch | 26 + pkgs/core/tcl/patches/tcl-8.5.8-pic.patch | 12 + src/pomona/pomona => pkgs/core/tcl/tcl.nm | 69 +- .../tcpdump/patches/tcpdump-4.0.0-ipv6-build.patch | 16 + src/pomona/pomona => pkgs/core/tcpdump/tcpdump.nm | 54 +- lfs/stage4 => pkgs/core/texinfo/texinfo.nm | 73 +- .../core/traceroute/traceroute.nm | 77 +- {src/initscripts => pkgs/core}/udev/console_init | 0 .../udev => pkgs/core/udev/rules}/10-console.rules | 0 {src/udev => pkgs/core/udev/rules}/23-usb.rules | 0 {src/udev => pkgs/core/udev/rules}/55-ipfire.rules | 0 {src/udev => pkgs/core/udev/rules}/60-net.rules | 0 {src/udev => pkgs/core/udev/rules}/61-cdrom.rules | 0 lfs/webinterface => pkgs/core/udev/udev.nm | 83 +- {src/ulogd => pkgs/core/ulogd2}/sqlite3.table | 0 {src/ulogd => pkgs/core/ulogd2}/ulogd.conf | 0 .../ulogd.conf => pkgs/core/ulogd2/ulogd.init | 0 {src/ulogd => pkgs/core/ulogd2}/ulogd.logrotate | 0 lfs/stage4 => pkgs/core/ulogd2/ulogd2.nm | 73 +- lfs/stage4 => pkgs/core/unzip/unzip.nm | 75 +- lfs/webinterface => pkgs/core/upstart/upstart.nm | 98 +- .../rc.local => pkgs/core/usbutils/usbutils.nm | 35 +- {src => pkgs/core}/util-linux-ng/nologin.8 | 0 {src => pkgs/core}/util-linux-ng/nologin.c | 0 {src => pkgs/core/util-linux-ng}/pam.d/login | 0 .../core/util-linux-ng/util-linux-ng.nm | 120 +- pkgs/core/vim/patches/vim-7.2-fixes-4.patch | 5414 ++ pkgs/core/vim/patches/vim-7.2-mandir-1.patch | 82 + lfs/stage1 => pkgs/core/vim/vim.nm | 76 +- pkgs/core/vim/vimrc | 6 + lfs/stage4 => pkgs/core/vlan/vlan.nm | 67 +- pkgs/core/vsftpd/patches/1-vsftpd-build_ssl.patch | 13 + pkgs/core/vsftpd/patches/2-vsftpd-libs-3.patch | 13 + .../vsftpd/patches/3-vsftpd-pam_hostname-1.patch | 58 + .../vsftpd/patches/4-vsftpd-close-std-fds.patch | 14 + .../vsftpd/patches/5-vsftpd-configuration-1.patch | 416 + {src => pkgs/core}/vsftpd/vsftpd.conf | 0 lfs/webinterface => pkgs/core/vsftpd/vsftpd.nm | 77 +- src/pam.d/vsftpd => pkgs/core/vsftpd/vsftpd.pam | 0 {src => pkgs/core}/vsftpd/vsftpd.user_list | 0 .../sysconfig/rc.local => pkgs/core/which/which.nm | 29 +- .../patches/wireless_tools.29-makefile.patch | 27 + .../core/wireless-tools/wireless-tools.nm | 80 +- .../core/xen/patches/xen-3.4.0-co_assignment.patch | 22 + pkgs/core/xen/patches/xen-3.4.0-cpufreq.patch | 19 + pkgs/core/xen/patches/xend-config-3.4.0.patch | 99 + src/pomona/pomona => pkgs/core/xen/xen.nm | 63 +- lfs/cairo => pkgs/core/xfsprogs/xfsprogs.nm | 88 +- lfs/stage4 => pkgs/core/xz/xz.nm | 75 +- lfs/htop => pkgs/core/zlib/zlib.nm | 84 +- pkgs/gmsl | 89 + pkgs/toolchain/acl/acl.nm | 16 + pkgs/toolchain/attr/attr.nm | 24 + pkgs/toolchain/bash/bash.nm | 20 + pkgs/toolchain/binutils-static/binutils-static.nm | 19 + .../patches/binutils-2.19.1-lazy-1.patch.off | 61 + .../patches/binutils-2.20-pt_pax-1.patch | 411 + pkgs/toolchain/binutils/binutils.nm | 27 + .../patches/binutils-2.19.1-lazy-1.patch.off | 61 + .../binutils/patches/binutils-2.20-pt_pax-1.patch | 411 + pkgs/toolchain/bzip2/bzip2.nm | 14 + pkgs/toolchain/coreutils/coreutils.nm | 20 + .../patches/coreutils-7.6-uname_PIC-1.patch | 204 + .../coreutils/patches/coreutils-8.4-i18n.patch | 4044 + pkgs/toolchain/cpio/cpio.nm | 12 + pkgs/toolchain/diffutils/diffutils.nm | 12 + .../patches/diffutils-2.8.1-hardened_tmp-1.patch | 31 + .../diffutils/patches/diffutils-2.8.1-i18n-1.patch | 802 + pkgs/toolchain/expect/expect.nm | 23 + .../expect/patches/expect-5.32.2-random.patch | 19 + .../expect/patches/expect-5.38.0-lib-spec.patch | 12 + .../expect/patches/expect-5.39.0-libdir.patch | 12 + .../expect/patches/expect-5.43.0-spawn-1.patch | 217 + .../expect/patches/expect-5.43.0-tcl8.5.6.patch | 42 + .../expect/patches/expect-5.43.0-tcl8.5.patch | 22 + pkgs/toolchain/file/file.nm | 17 + pkgs/toolchain/findutils/findutils.nm | 17 + pkgs/toolchain/gawk/gawk.nm | 14 + pkgs/toolchain/gcc-static/gcc-static.nm | 54 + pkgs/toolchain/gcc/gcc.nm | 46 + pkgs/toolchain/gcc/include-append | 5 + .../gcc/patches/gcc-4.4-optimize_linking.patch | 24 + .../patches/gcc-4.4.1-branch-startfiles-1.patch | 26 + pkgs/toolchain/gcc/patches/gcc-4.4.1-espf-1.patch | 504 + pkgs/toolchain/gettext/gettext.nm | 18 + .../gettext/patches/gettext-0.17-automake-1.patch | 27 + pkgs/toolchain/glibc/glibc-stack_chk_fail.c | 1 + pkgs/toolchain/glibc/glibc.nm | 35 + .../glibc/patches/glibc-2.10.1-arc4random.patch | 541 + .../glibc-2.10.1-asprintf_reset2null-1.patch | 59 + ...libc-2.10.1-hardened-configure-picdefault.patch | 29 + .../glibc-2.10.1-hardened-inittls-nosysenter.patch | 273 + .../glibc/patches/glibc-2.10.1-issetugid-1.patch | 243 + .../glibc-2.10.1-localedef_trampoline-1.patch | 64 + .../patches/glibc-2.10.1-mktemp_urandom.patch.off | 162 + .../glibc/patches/glibc-2.10.1-pt_pax-1.patch | 40 + .../glibc/patches/glibc-2.10.1-res_randomid.patch | 339 + .../glibc-2.10.1-resolv_response_length.patch | 26 + .../patches/glibc-2.10.1-sanitize_env.patch.off | 1062 + .../patches/glibc-2.10.1-strlcpy_strlcat-1.patch | 349 + .../patches/glibc-2.10.1-undefine-__i686.patch | 44 + .../glibc/patches/glibc-2.11.1-hardened-pie.patch | 38 + pkgs/toolchain/grep/grep.nm | 14 + pkgs/toolchain/gzip/gzip.nm | 19 + .../patches/gzip-1.3.13-cve-2006-4337_len.patch | 15 + .../gzip/patches/gzip-1.3.13-cve-2006-4338.patch | 33 + .../gzip/patches/gzip-1.3.13-openbsd-owl-tmp.patch | 47 + pkgs/toolchain/kernel-headers/kernel-headers.nm | 10 + pkgs/toolchain/m4/m4.nm | 14 + pkgs/toolchain/make/make.nm | 12 + pkgs/toolchain/ncurses/ncurses.nm | 26 + pkgs/toolchain/patch/patch.nm | 16 + pkgs/toolchain/pax-utils/pax-utils.nm | 12 + .../perl/patches/perl-5.10.1-libc-1.patch | 31 + .../perl/patches/perl-5.10.1-utf8-1.patch | 167 + pkgs/toolchain/perl/perl.nm | 26 + pkgs/toolchain/sed/sed.nm | 13 + .../tar/patches/tar-1.22-vfatTruncate.patch | 29 + pkgs/toolchain/tar/patches/tar-1.22-xattrs-1.patch | 1454 + .../tar/patches/tar-1.22-xattrs-conf-1.patch | 799 + pkgs/toolchain/tar/tar.nm | 12 + .../toolchain/tcl/patches/tcl-8.5.8-autopath.patch | 53 + pkgs/toolchain/tcl/patches/tcl-8.5.8-conf.patch | 26 + pkgs/toolchain/tcl/patches/tcl-8.5.8-pic.patch | 12 + pkgs/toolchain/tcl/tcl.nm | 19 + pkgs/toolchain/texinfo/texinfo.nm | 12 + pkgs/toolchain/xz/xz.nm | 17 + src/initscripts/extras/collectd.conf | 8 - src/initscripts/extras/haldaemon.conf | 9 - src/initscripts/extras/splashy.conf | 15 - src/initscripts/extras/vsftpd.conf | 8 - src/pakfire/compressor | 164 - src/pakfire/compressor.d/01-qa-unsafe-files | 45 - src/pakfire/compressor.d/02-qa-static-libs | 29 - src/pakfire/compressor.d/03-qa-execstacks | 48 - src/pakfire/compressor.d/04-qa-rpath | 51 - src/pakfire/compressor.d/05-qa-textrels | 35 - src/pakfire/compressor.d/06-qa-shared-soname | 48 - src/pakfire/compressor.d/07-qa-shared-needed | 34 - src/pakfire/compressor.d/50-python | 30 - src/pakfire/compressor.d/99-strip-debug | 29 - src/pakfire/compressor.d/99-strip-unneeded | 29 - src/rootfiles/README | 39 - src/rootfiles/core/acl | 20 - src/rootfiles/core/aiccu | 6 - src/rootfiles/core/atom/grub | 31 - src/rootfiles/core/atom/linux | 1 - src/rootfiles/core/attr | 24 - src/rootfiles/core/autoconf | 63 - src/rootfiles/core/automake | 134 - src/rootfiles/core/avahi | 141 - src/rootfiles/core/bash | 40 - src/rootfiles/core/bc | 6 - src/rootfiles/core/beep | 1 - src/rootfiles/core/berkeley | 1971 - src/rootfiles/core/bind | 6 - src/rootfiles/core/binutils | 68 - src/rootfiles/core/bison | 89 - src/rootfiles/core/boost | 7445 -- src/rootfiles/core/br2684ctl | 1 - src/rootfiles/core/bridge-utils | 3 - src/rootfiles/core/btrfs-progs | 14 - src/rootfiles/core/bzip2 | 28 - src/rootfiles/core/cairo | 72 - src/rootfiles/core/core2duo/grub | 31 - src/rootfiles/core/core2duo/linux | 1 - src/rootfiles/core/coreutils | 317 - src/rootfiles/core/cpio | 24 - src/rootfiles/core/cracklib | 46 - src/rootfiles/core/cryptsetup-luks | 10 - src/rootfiles/core/curl | 72 - src/rootfiles/core/cyrus-sasl | 85 - src/rootfiles/core/dbus | 51 - src/rootfiles/core/dbus-glib | 36 - src/rootfiles/core/dev.p0 | 6 - src/rootfiles/core/dhcp | 46 - src/rootfiles/core/diffutils | 25 - src/rootfiles/core/directfb | 208 - src/rootfiles/core/dmraid | 15 - src/rootfiles/core/dosfstools | 7 - src/rootfiles/core/dvdrtools | 15 - src/rootfiles/core/e2fsprogs | 112 - src/rootfiles/core/ebtables | 29 - src/rootfiles/core/etherwake | 1 - src/rootfiles/core/eventlog | 8 - src/rootfiles/core/expat | 7 - src/rootfiles/core/ez-ipupdate | 1 - src/rootfiles/core/file | 9 - src/rootfiles/core/findutils | 57 - src/rootfiles/core/firewall | 21 - src/rootfiles/core/flex | 25 - src/rootfiles/core/fontconfig | 437 - src/rootfiles/core/freetype | 56 - src/rootfiles/core/fuse | 21 - src/rootfiles/core/gawk | 53 - src/rootfiles/core/gcc | 823 - src/rootfiles/core/geodelx/grub | 31 - src/rootfiles/core/gettext | 1650 - src/rootfiles/core/glib2 | 637 - src/rootfiles/core/glibc | 3177 - src/rootfiles/core/gmp | 15 - src/rootfiles/core/gnupg2 | 117 - src/rootfiles/core/gnutls | 583 - src/rootfiles/core/gobject-introspection | 115 - src/rootfiles/core/gperf | 4 - src/rootfiles/core/grep | 48 - src/rootfiles/core/groff | 510 - src/rootfiles/core/grub | 31 - src/rootfiles/core/gzip | 26 - src/rootfiles/core/hal | 177 - src/rootfiles/core/hal-info | 49 - src/rootfiles/core/hdparm | 2 - src/rootfiles/core/hostapd | 2 - src/rootfiles/core/i586/linux | 1 - src/rootfiles/core/i686/linux | 1775 - src/rootfiles/core/iana-etc | 2 - src/rootfiles/core/initscripts | 29 - src/rootfiles/core/intltool | 13 - src/rootfiles/core/iproute2 | 82 - src/rootfiles/core/iptables | 141 - src/rootfiles/core/iputils | 12 - src/rootfiles/core/iw | 2 - src/rootfiles/core/jwhois | 20 - src/rootfiles/core/kbd | 648 - src/rootfiles/core/l7-protocols | 302 - src/rootfiles/core/ldapvi | 7 - src/rootfiles/core/less | 6 - src/rootfiles/core/libaal | 29 - src/rootfiles/core/libart | 51 - src/rootfiles/core/libassuan | 6 - src/rootfiles/core/libbdevid | 17 - src/rootfiles/core/libcap2 | 36 - src/rootfiles/core/libdaemon | 12 - src/rootfiles/core/libdnet | 25 - src/rootfiles/core/libevent | 18 - src/rootfiles/core/libgcrypt | 10 - src/rootfiles/core/libgpg-error | 20 - src/rootfiles/core/libgssglue | 7 - src/rootfiles/core/libidn | 81 - src/rootfiles/core/libjpeg | 17 - src/rootfiles/core/libksba | 7 - src/rootfiles/core/libnetfilter_conntrack | 14 - src/rootfiles/core/libnetfilter_log | 11 - src/rootfiles/core/libnetfilter_queue | 11 - src/rootfiles/core/libnfnetlink | 8 - src/rootfiles/core/libnfsidmap | 15 - src/rootfiles/core/libnl | 59 - src/rootfiles/core/libpcap | 78 - src/rootfiles/core/libpng | 18 - src/rootfiles/core/librpcsecgss | 12 - src/rootfiles/core/libssh2 | 77 - src/rootfiles/core/libtiff | 236 - src/rootfiles/core/libtool | 68 - src/rootfiles/core/libusb | 6 - src/rootfiles/core/libusb-compat | 10 - src/rootfiles/core/libuser | 93 - src/rootfiles/core/libxml2 | 336 - src/rootfiles/core/libxslt | 150 - src/rootfiles/core/lighttpd | 43 - src/rootfiles/core/linux | 1930 - src/rootfiles/core/linux-atm | 49 - src/rootfiles/core/linux-headers | 748 - src/rootfiles/core/lm-sensors | 22 - src/rootfiles/core/logrotate | 4 - src/rootfiles/core/lsof | 1 - src/rootfiles/core/lua | 12 - src/rootfiles/core/lvm2 | 96 - src/rootfiles/core/lzo | 17 - src/rootfiles/core/m4 | 5 - src/rootfiles/core/make | 32 - src/rootfiles/core/man-db | 131 - src/rootfiles/core/man-pages | 2056 - src/rootfiles/core/mdadm | 7 - src/rootfiles/core/memtest86+ | 2 - src/rootfiles/core/mkinitramfs | 5 - src/rootfiles/core/module-init-tools | 19 - src/rootfiles/core/mpfr | 6 - src/rootfiles/core/nasm | 4 - src/rootfiles/core/ncurses | 3367 - src/rootfiles/core/network | 24 - src/rootfiles/core/newt | 74 - src/rootfiles/core/nfs-utils | 41 - src/rootfiles/core/noip | 1 - src/rootfiles/core/nss_ldap | 4 - src/rootfiles/core/ntp | 18 - src/rootfiles/core/openldap | 396 - src/rootfiles/core/openlldp | 2 - src/rootfiles/core/openssh | 41 - src/rootfiles/core/openssl | 113 - src/rootfiles/core/openvpn | 9 - src/rootfiles/core/pakfire | 25 - src/rootfiles/core/pam | 256 - src/rootfiles/core/pam_ldap | 3 - src/rootfiles/core/pango | 122 - src/rootfiles/core/parted | 21 - src/rootfiles/core/passwd | 73 - src/rootfiles/core/patch | 2 - src/rootfiles/core/pax-utils | 13 - src/rootfiles/core/paxctl | 2 - src/rootfiles/core/pciutils | 25 - src/rootfiles/core/pcre | 109 - src/rootfiles/core/pdns | 13 - src/rootfiles/core/pdns-recursor | 7 - src/rootfiles/core/perl | 2546 - src/rootfiles/core/perl-xml-parser | 46 - src/rootfiles/core/pinentry | 3 - src/rootfiles/core/pixman | 7 - src/rootfiles/core/pkg-config | 3 - src/rootfiles/core/popt | 36 - src/rootfiles/core/portmap | 6 - src/rootfiles/core/ppp | 50 - src/rootfiles/core/pptp | 4 - src/rootfiles/core/procps | 34 - src/rootfiles/core/psmisc | 28 - src/rootfiles/core/pth | 8 - src/rootfiles/core/pyfire | 19 - src/rootfiles/core/python | 2592 - src/rootfiles/core/python-IPy | 4 - src/rootfiles/core/python-cracklib | 1 - src/rootfiles/core/python-cryptsetup | 9 - src/rootfiles/core/python-dbus | 67 - src/rootfiles/core/python-flup | 67 - src/rootfiles/core/python-netfilter_conntrack | 30 - src/rootfiles/core/python-parted | 1 - src/rootfiles/core/python-pyblock | 14 - src/rootfiles/core/python-setuptools | 5 - src/rootfiles/core/python-sqlite2 | 46 - src/rootfiles/core/python-tornado | 44 - src/rootfiles/core/python-urlgrabber | 29 - src/rootfiles/core/python-werkzeug | 132 - src/rootfiles/core/radvd | 5 - src/rootfiles/core/readline | 20 - src/rootfiles/core/reiser4progs | 70 - src/rootfiles/core/reiserfsprogs | 12 - src/rootfiles/core/rrdtool | 132 - src/rootfiles/core/rstp | 6 - src/rootfiles/core/screen | 30 - src/rootfiles/core/scripts | 4 - src/rootfiles/core/sed | 40 - src/rootfiles/core/setuptools | 113 - src/rootfiles/core/shadow | 395 - src/rootfiles/core/slang | 117 - src/rootfiles/core/smartmontools | 22 - src/rootfiles/core/splashy | 43 - src/rootfiles/core/sqlite | 7 - src/rootfiles/core/squashfs-tools | 2 - src/rootfiles/core/stage2 | 99 - src/rootfiles/core/stage3 | 10 - src/rootfiles/core/strongswan | 73 - src/rootfiles/core/sudo | 10 - src/rootfiles/core/sysfsutils | 12 - src/rootfiles/core/syslinux | 168 - src/rootfiles/core/syslog-ng | 8 - src/rootfiles/core/system-release | 3 - src/rootfiles/core/sysvinit | 13 - src/rootfiles/core/tar | 40 - src/rootfiles/core/texinfo | 52 - src/rootfiles/core/udev | 176 - src/rootfiles/core/ulogd2 | 26 - src/rootfiles/core/unzip | 10 - src/rootfiles/core/upstart | 35 - src/rootfiles/core/usbutils | 8 - src/rootfiles/core/util-linux-ng | 215 - src/rootfiles/core/via-c3/grub | 1 - src/rootfiles/core/via-c7/grub | 31 - src/rootfiles/core/via-c7/linux | 1 - src/rootfiles/core/vim | 1450 - src/rootfiles/core/vlan | 1 - src/rootfiles/core/webinterface | 20 - src/rootfiles/core/werkzeug | 138 - src/rootfiles/core/which | 3 - src/rootfiles/core/wireless-tools | 20 - src/rootfiles/core/xfsprogs | 46 - src/rootfiles/core/xz | 42 - src/rootfiles/core/zlib | 5 - src/rootfiles/debug/gdb | 18 - src/rootfiles/debug/pax-utils | 13 - src/rootfiles/debug/paxtest | 39 - src/rootfiles/debug/pychecker | 55 - src/rootfiles/debug/strace | 3 - src/rootfiles/extras/bwm-ng | 2 - src/rootfiles/extras/cups | 894 - src/rootfiles/extras/freeradius | 542 - src/rootfiles/extras/ghostscript | 607 - src/rootfiles/extras/gssdp | 28 - src/rootfiles/extras/gupnp | 66 - src/rootfiles/extras/gupnp-av | 42 - src/rootfiles/extras/gupnp-igd | 23 - src/rootfiles/extras/hplip | 553 - src/rootfiles/extras/htop | 5 - src/rootfiles/extras/joe | 75 - src/rootfiles/extras/libvirt | 176 - src/rootfiles/extras/mc | 167 - src/rootfiles/extras/nano | 57 - src/rootfiles/extras/net-snmp | 574 - src/rootfiles/extras/nmap | 107 - src/rootfiles/extras/qemu | 57 - src/rootfiles/extras/qemu-kvm-devel | 57 - src/rootfiles/extras/quagga | 83 - src/rootfiles/extras/samba | 696 - src/rootfiles/extras/sane | 538 - src/rootfiles/extras/squid | 1228 - src/rootfiles/extras/tcpdump | 3 - src/rootfiles/extras/traceroute | 3 - src/rootfiles/extras/vsftpd | 7 - src/rootfiles/extras/xen | 7 - src/scripts/parallelismflags | 48 - src/scripts/py-compile | 76 - src/scripts/setddns.pl | 625 - src/web/cgi-bin/template.py | 36 - src/web/images/icons/computer.png | Bin 3066 -> 0 bytes src/web/images/icons/ipfire.png | Bin 5389 -> 0 bytes src/web/images/icons/keyboard.png | Bin 2339 -> 0 bytes src/web/images/icons/network.png | Bin 2733 -> 0 bytes src/web/images/icons/printer.png | Bin 1361 -> 0 bytes src/web/images/icons/wireless.png | Bin 2599 -> 0 bytes src/web/images/n1.gif | Bin 1014 -> 0 bytes src/web/images/n2.gif | Bin 449 -> 0 bytes src/web/images/n3.gif | Bin 155 -> 0 bytes src/web/images/n4.gif | Bin 155 -> 0 bytes src/web/images/n5.gif | Bin 72 -> 0 bytes src/web/images/n6.gif | Bin 70 -> 0 bytes src/web/images/spacer.gif | Bin 43 -> 0 bytes src/web/style.css | 450 - tools/common-constants | 29 + tools/common-include | 16 + tools/common-package-functions | 493 + tools/common-ui-functions | 118 + tools/compressor | 227 + {src/pakfire => tools}/decompressor | 4 +- tools/downloader | 157 +- {src/scripts => tools}/extractor | 0 tools/naoki | 139 + tools/naoki-constants | 35 + tools/naoki-functions | 344 + tools/naoki-include | 18 + tools/patch | 12 + tools/py-compile | 48 + tools/quality-agent | 11 + tools/quality-agent.d/001-include-files | 12 + tools/quality-agent.d/001-remove-info-files | 14 + tools/quality-agent.d/001-remove-static-libs | 21 + tools/quality-agent.d/001-unsafe-files | 26 + tools/quality-agent.d/002-bad-symlinks | 19 + tools/quality-agent.d/003-libs-location | 20 + tools/quality-agent.d/050-execstacks | 33 + tools/quality-agent.d/050-libs-needed | 18 + tools/quality-agent.d/050-libs-soname | 31 + tools/quality-agent.d/050-root-links-to-usr | 18 + tools/quality-agent.d/050-rpaths | 34 + tools/quality-agent.d/050-textrels | 20 + tools/quality-agent.d/090-python-hardlinks | 17 + tools/quality-agent.d/090-remove-empty-dirs | 16 + tools/quality-agent.d/095-directory-layout | 25 + tools/quality-agent.d/099-strip | 20 + tools/quality-agent.d/qa-include | 10 + tools/toolchain | 63 + 1343 files changed, 301001 insertions(+), 85185 deletions(-) delete mode 100644 .config-default create mode 100644 config/architectures.conf create mode 100644 config/logging.ini create mode 100644 config/naoki.conf delete mode 100644 lfs/Config delete mode 100644 lfs/acl delete mode 100644 lfs/adjust-toolchain delete mode 100644 lfs/aiccu delete mode 100644 lfs/attr delete mode 100644 lfs/autoconf delete mode 100644 lfs/automake delete mode 100644 lfs/avahi delete mode 100644 lfs/bash delete mode 100644 lfs/berkeley delete mode 100644 lfs/binutils delete mode 100644 lfs/bison delete mode 100644 lfs/bridge-utils delete mode 100644 lfs/btrfs-progs delete mode 100644 lfs/bwm-ng delete mode 100644 lfs/bzip2 delete mode 100644 lfs/ccache delete mode 100644 lfs/coreutils delete mode 100644 lfs/cryptsetup-luks delete mode 100644 lfs/cups delete mode 100644 lfs/curl delete mode 100644 lfs/cyrus-sasl delete mode 100644 lfs/dbus delete mode 100644 lfs/dbus-glib delete mode 100644 lfs/dhcp delete mode 100644 lfs/diffutils delete mode 100644 lfs/directfb delete mode 100644 lfs/dmraid delete mode 100644 lfs/dosfstools delete mode 100644 lfs/dvdrtools delete mode 100644 lfs/ebtables delete mode 100644 lfs/etherwake delete mode 100644 lfs/eventlog delete mode 100644 lfs/expat delete mode 100644 lfs/ez-ipupdate delete mode 100644 lfs/file delete mode 100644 lfs/firewall delete mode 100644 lfs/flex delete mode 100644 lfs/freetype delete mode 100644 lfs/fuse delete mode 100644 lfs/gawk delete mode 100644 lfs/gcc delete mode 100644 lfs/gdb delete mode 100644 lfs/gettext delete mode 100644 lfs/ghostscript delete mode 100644 lfs/glib2 delete mode 100644 lfs/glibc delete mode 100644 lfs/gnupg2 delete mode 100644 lfs/gnutls delete mode 100644 lfs/gobject-introspection delete mode 100644 lfs/gperf delete mode 100644 lfs/grep delete mode 100644 lfs/grub delete mode 100644 lfs/gssdp delete mode 100644 lfs/gupnp delete mode 100644 lfs/gupnp-av delete mode 100644 lfs/gupnp-igd delete mode 100644 lfs/gupnp-media-server delete mode 100644 lfs/gzip delete mode 100644 lfs/hal delete mode 100644 lfs/hal-info delete mode 100644 lfs/hostapd delete mode 100644 lfs/hplip delete mode 100644 lfs/iana-etc delete mode 100644 lfs/icecc delete mode 120000 lfs/images-core delete mode 120000 lfs/images-info delete mode 120000 lfs/images-initramfs delete mode 120000 lfs/images-overlays delete mode 100644 lfs/initscripts delete mode 100644 lfs/intltool delete mode 100644 lfs/iproute2 delete mode 100644 lfs/iptables delete mode 100644 lfs/iputils delete mode 100644 lfs/iw delete mode 100644 lfs/joe delete mode 100644 lfs/jwhois delete mode 100644 lfs/kbd delete mode 100644 lfs/l7-protocols delete mode 100644 lfs/ldapvi delete mode 100644 lfs/less delete mode 100644 lfs/libaal delete mode 100644 lfs/libart delete mode 100644 lfs/libassuan delete mode 100644 lfs/libbdevid delete mode 100644 lfs/libcap2 delete mode 100644 lfs/libdaemon delete mode 100644 lfs/libdnet delete mode 100644 lfs/libevent delete mode 100644 lfs/libgcrypt delete mode 100644 lfs/libgpg-error delete mode 100644 lfs/libgssglue delete mode 100644 lfs/libidn delete mode 100644 lfs/libjpeg delete mode 100644 lfs/libksba delete mode 100644 lfs/libnetfilter_conntrack delete mode 100644 lfs/libnetfilter_log delete mode 100644 lfs/libnetfilter_queue delete mode 100644 lfs/libnfnetlink delete mode 100644 lfs/libnfsidmap delete mode 100644 lfs/libnl delete mode 100644 lfs/libpcap delete mode 100644 lfs/libpng delete mode 100644 lfs/librpcsecgss delete mode 100644 lfs/libsoup delete mode 100644 lfs/libssh2 delete mode 100644 lfs/libtiff delete mode 100644 lfs/libtool delete mode 100644 lfs/libusb delete mode 100644 lfs/libusb-compat delete mode 100644 lfs/libuser delete mode 100644 lfs/libvirt delete mode 100644 lfs/libxml2 delete mode 100644 lfs/libxslt delete mode 100644 lfs/lighttpd delete mode 100644 lfs/linux delete mode 100644 lfs/linux-atm delete mode 120000 lfs/linux-headers delete mode 100644 lfs/lm-sensors delete mode 100644 lfs/logrotate delete mode 100644 lfs/lsof delete mode 100644 lfs/lvm2 delete mode 100644 lfs/lzo delete mode 100644 lfs/make delete mode 100644 lfs/man-db delete mode 100644 lfs/man-pages delete mode 100644 lfs/mc delete mode 100644 lfs/mdadm delete mode 100644 lfs/memtest86+ delete mode 100644 lfs/mkinitramfs delete mode 100644 lfs/module-init-tools delete mode 100644 lfs/nano delete mode 100644 lfs/nasm delete mode 100644 lfs/ncurses delete mode 100644 lfs/net-snmp delete mode 100644 lfs/network delete mode 100644 lfs/nfs-utils delete mode 100644 lfs/nmap delete mode 100644 lfs/noip delete mode 100644 lfs/nss_ldap delete mode 100644 lfs/ntp delete mode 100644 lfs/openldap delete mode 100644 lfs/openlldp delete mode 100644 lfs/openssh delete mode 100644 lfs/pakfire delete mode 100644 lfs/pam_ldap delete mode 100644 lfs/pango delete mode 100644 lfs/parted delete mode 100644 lfs/passwd delete mode 100644 lfs/patch delete mode 100644 lfs/pax-utils delete mode 100644 lfs/paxctl delete mode 100644 lfs/pciutils delete mode 100644 lfs/pcre delete mode 100644 lfs/pdns delete mode 100644 lfs/pdns-recursor delete mode 100644 lfs/perl delete mode 100644 lfs/perl-xml-parser delete mode 100644 lfs/pinentry delete mode 100644 lfs/pixman delete mode 100644 lfs/pkg-config delete mode 100644 lfs/popt delete mode 100644 lfs/portmap delete mode 100644 lfs/ppp delete mode 100644 lfs/pptp delete mode 100644 lfs/procps delete mode 100644 lfs/psmisc delete mode 100644 lfs/pth delete mode 100644 lfs/pychecker delete mode 100644 lfs/pyfire delete mode 100644 lfs/python-IPy delete mode 120000 lfs/python-cracklib delete mode 100644 lfs/python-cryptsetup delete mode 100644 lfs/python-dbus delete mode 100644 lfs/python-flup delete mode 100644 lfs/python-netfilter_conntrack delete mode 100644 lfs/python-parted delete mode 100644 lfs/python-pyblock delete mode 100644 lfs/python-setuptools delete mode 100644 lfs/python-sqlite2 delete mode 100644 lfs/python-tornado delete mode 100644 lfs/python-urlgrabber delete mode 100644 lfs/python-werkzeug delete mode 100644 lfs/qemu delete mode 100644 lfs/radvd delete mode 100644 lfs/reiser4progs delete mode 100644 lfs/reiserfsprogs delete mode 100644 lfs/rrdtool delete mode 100644 lfs/rstp delete mode 100644 lfs/sane delete mode 100644 lfs/screen delete mode 100644 lfs/scripts delete mode 100644 lfs/sed delete mode 100644 lfs/shadow delete mode 100644 lfs/slang delete mode 100644 lfs/smartmontools delete mode 100644 lfs/splashy delete mode 100644 lfs/squashfs-tools delete mode 100644 lfs/squid delete mode 100644 lfs/stage2 delete mode 100644 lfs/stage3 delete mode 100644 lfs/stage5 delete mode 100644 lfs/strace delete mode 100644 lfs/strip delete mode 100644 lfs/strongswan delete mode 100644 lfs/sysfsutils delete mode 100644 lfs/syslog-ng delete mode 100644 lfs/system-release delete mode 100644 lfs/sysvinit delete mode 100644 lfs/tar delete mode 100644 lfs/tcpdump delete mode 100644 lfs/test-toolchain delete mode 100644 lfs/texinfo delete mode 100644 lfs/udev delete mode 100644 lfs/ulogd2 delete mode 100644 lfs/unzip delete mode 100644 lfs/upstart delete mode 120000 lfs/usb-key delete mode 100644 lfs/usbutils delete mode 100644 lfs/vala delete mode 100644 lfs/vim delete mode 100644 lfs/vlan delete mode 100644 lfs/vsftpd delete mode 100644 lfs/which delete mode 100644 lfs/wireless-tools delete mode 100644 lfs/xen delete mode 100644 lfs/xfsprogs delete mode 100644 lfs/xz delete mode 100644 lfs/zlib create mode 100644 naoki/__init__.py create mode 100644 naoki/argparse.py create mode 100644 naoki/chroot.py create mode 100644 naoki/constants.py create mode 100644 naoki/exception.py create mode 100644 naoki/logger.py create mode 100644 naoki/package.py create mode 100644 naoki/terminal.py rename {tools => naoki}/urlgrabber/__init__.py (100%) rename {tools => naoki}/urlgrabber/byterange.py (100%) rename {tools => naoki}/urlgrabber/grabber.py (100%) rename {tools => naoki}/urlgrabber/keepalive.py (100%) rename {tools => naoki}/urlgrabber/mirror.py (100%) rename {tools => naoki}/urlgrabber/progress.py (100%) rename {tools => naoki}/urlgrabber/sslfactory.py (100%) create mode 100644 naoki/util.py create mode 100644 pkgs/Constants create mode 100644 pkgs/Functions copy src/rstp/bridge-stp => pkgs/Include (93%) create mode 100644 pkgs/Targets create mode 100644 pkgs/__gmsl copy lfs/webinterface => pkgs/core/acl/acl.nm (59%) create mode 100644 pkgs/core/acl/patches/acl-2.2.47-build-1.patch create mode 100644 pkgs/core/acl/patches/acl-2.2.47-exitcode.patch create mode 100644 pkgs/core/acl/patches/acl-2.2.47-nfs4.patch create mode 100644 pkgs/core/acl/patches/acl-2.2.47-params.patch create mode 100644 pkgs/core/acl/patches/acl-2.2.47-path_max.patch create mode 100644 pkgs/core/acl/patches/acl-2.2.47-segfault.patch create mode 100644 pkgs/core/acl/patches/acl-2.2.47-walk.patch.broken copy src/pomona/pomona => pkgs/core/aiccu/aiccu.nm (65%) copy lfs/webinterface => pkgs/core/attr/attr.nm (63%) copy src/pomona/pomona => pkgs/core/autoconf/autoconf.nm (67%) copy src/initscripts/sysconfig/rc.local => pkgs/core/automake/automake.nm (70%) copy lfs/stage1 => pkgs/core/avahi/avahi.nm (58%) copy lfs/fontconfig => pkgs/core/bash/bash.nm (51%) rename {src => pkgs/core}/bash/bashrc (100%) create mode 100644 pkgs/core/bash/patches/bash-4.0-paths-1.patch create mode 100644 pkgs/core/bash/patches/bash-4.0-profile-1.patch create mode 100644 pkgs/core/bash/patches/bash-4.0-rng.patch create mode 100644 pkgs/core/bash/patches/bash-4.1-upstream-1.patch create mode 100644 pkgs/core/bash/patches/bash-4.1-upstream-2.patch rename {src => pkgs/core}/bash/profile (100%) rename {src => pkgs/core/bash}/profile.d/extrapaths.sh (100%) rename {src => pkgs/core/bash}/profile.d/i18n.sh (100%) rename {src => pkgs/core/bash}/profile.d/umask.sh (100%) rename {src => pkgs/core}/bash/shells (100%) rename lfs/bc => pkgs/core/bc/bc.nm (65%) rename lfs/beep => pkgs/core/beep/beep.nm (62%) rename lfs/bind => pkgs/core/bind/bind.nm (64%) copy lfs/cairo => pkgs/core/binutils/binutils.nm (56%) create mode 100644 pkgs/core/binutils/patches/binutils-2.19.1-asprintf_fix.patch create mode 100644 pkgs/core/binutils/patches/binutils-2.19.1-ld_makefile.patch create mode 100644 pkgs/core/binutils/patches/binutils-2.20-pt_pax-1.patch copy lfs/cairo => pkgs/core/bison/bison.nm (63%) rename lfs/boost => pkgs/core/boost/boost.nm (59%) create mode 100644 pkgs/core/boost/patches/boost-1.39.0-fs_gcc44.patch create mode 100644 pkgs/core/boost/patches/boost-1.39.0-function_template.patch create mode 100644 pkgs/core/boost/patches/boost-1.39.0-unneccessary_iostreams.patch create mode 100644 pkgs/core/boost/patches/boost-1.39.0-version-override.patch rename lfs/br2684ctl => pkgs/core/br2684ctl/br2684ctl.nm (60%) copy lfs/stage4 => pkgs/core/bridge-utils/bridge-utils.nm (68%) copy lfs/stage4 => pkgs/core/btrfs-progs/btrfs-progs.nm (68%) copy src/initscripts/sysconfig/rc.local => pkgs/core/bwm-ng/bwm-ng.nm (73%) copy lfs/cairo => pkgs/core/bzip2/bzip2.nm (58%) create mode 100644 pkgs/core/bzip2/patches/bzip2-1.0.5-install_docs-1.patch copy src/initscripts/sysconfig/rc.local => pkgs/core/cairo/cairo.nm (70%) copy lfs/stage1 => pkgs/core/ccache/ccache.nm (65%) create mode 100644 pkgs/core/ccache/patches/ccache-2.4.patch copy lfs/paxtest => pkgs/core/coreutils/coreutils.nm (51%) rename {src => pkgs/core/coreutils}/pam.d/su (100%) rename {src => pkgs/core/coreutils}/pam.d/su-l (100%) create mode 100644 pkgs/core/coreutils/patches/coreutils-7.6-uname_PIC-1.patch.off create mode 100644 pkgs/core/coreutils/patches/coreutils-8.4-i18n.patch create mode 100644 pkgs/core/coreutils/patches/coreutils-8.4-pam.patch rename {src => pkgs/core/coreutils}/profile.d/dircolors.sh (100%) rename lfs/cpio => pkgs/core/cpio/cpio.nm (65%) rename lfs/cracklib => pkgs/core/cracklib/cracklib.nm (56%) copy src/pomona/pomona => pkgs/core/cryptsetup-luks/cryptsetup-luks.nm (61%) rename src/initscripts/extras/cups.conf => pkgs/core/cups/cups.init (100%) copy src/pomona/pomona => pkgs/core/cups/cups.nm (62%) copy lfs/cairo => pkgs/core/curl/curl.nm (60%) copy lfs/webinterface => pkgs/core/cyrus-sasl/cyrus-sasl.nm (64%) create mode 100644 pkgs/core/cyrus-sasl/patches/cyrus-sasl-2.1.23-bad-elif.patch rename {src => pkgs/core}/cyrus-sasl/smtpd.conf (100%) copy lfs/stage4 => pkgs/core/db/db.nm (66%) create mode 100644 pkgs/core/db/patches/db-4.7.25-upstream_fixes-1.patch copy src/pomona/pomona => pkgs/core/dbus-glib/dbus-glib.nm (67%) copy src/pomona/pomona => pkgs/core/dbus/dbus.nm (63%) rename {src/initscripts/extras => pkgs/core/dbus}/messagebus.conf (100%) copy src/pomona/pomona => pkgs/core/dejagnu/dejagnu.nm (67%) rename {src => pkgs/core}/dhcp/dhclient-script (100%) copy lfs/webinterface => pkgs/core/dhcp/dhcp.nm (57%) copy src/pomona/pomona => pkgs/core/diffutils/diffutils.nm (67%) create mode 100644 pkgs/core/diffutils/patches/diffutils-2.8.1-hardened_tmp-1.patch create mode 100644 pkgs/core/diffutils/patches/diffutils-2.8.1-i18n-1.patch copy lfs/stage4 => pkgs/core/directfb/directfb.nm (59%) copy lfs/stage1 => pkgs/core/dmraid/dmraid.nm (58%) copy lfs/stage4 => pkgs/core/dosfstools/dosfstools.nm (68%) copy src/pomona/pomona => pkgs/core/dracut/dracut.nm (64%) create mode 100644 pkgs/core/dracut/patches/dracut-004-emergency.patch create mode 100644 pkgs/core/dracut/patches/dracut-004-firmware.patch copy src/pomona/pomona => pkgs/core/dvdrtools/dvdrtools.nm (67%) rename lfs/e2fsprogs => pkgs/core/e2fsprogs/e2fsprogs.nm (64%) copy lfs/webinterface => pkgs/core/ebtables/ebtables.nm (63%) copy src/pomona/pomona => pkgs/core/etherwake/etherwake.nm (65%) create mode 100644 pkgs/core/etherwake/patches/etherwake-1.09-install.patch copy src/pomona/pomona => pkgs/core/eventlog/eventlog.nm (65%) copy src/pomona/pomona => pkgs/core/expat/expat.nm (61%) copy lfs/stage4 => pkgs/core/expect/expect.nm (58%) create mode 100644 pkgs/core/expect/patches/expect-5.32.2-random.patch create mode 100644 pkgs/core/expect/patches/expect-5.38.0-lib-spec.patch create mode 100644 pkgs/core/expect/patches/expect-5.39.0-libdir.patch create mode 100644 pkgs/core/expect/patches/expect-5.43.0-override_default_prefix.patch create mode 100644 pkgs/core/expect/patches/expect-5.43.0-spawn-1.patch create mode 100644 pkgs/core/expect/patches/expect-5.43.0-tcl_8.5.8_fix-1.patch copy src/initscripts/sysconfig/rc.local => pkgs/core/ez-ipupdate/ez-ipupdate.nm (69%) create mode 100644 pkgs/core/ez-ipupdate/patches/ez-ipupdate-3.0.11b8-10.patch create mode 100644 pkgs/core/ez-ipupdate/patches/ez-ipupdate-3.0.11b8-pidfile.patch copy lfs/stage4 => pkgs/core/file/file.nm (68%) rename lfs/findutils => pkgs/core/findutils/findutils.nm (64%) rename src/initscripts/extras/firewall.conf => pkgs/core/firewall/firewall.init (100%) copy src/pomona/pomona => pkgs/core/firewall/firewall.nm (64%) rename {src/firewall => pkgs/core/firewall/src}/firewall (100%) rename {src/firewall => pkgs/core/firewall/src}/functions (100%) rename {src/firewall => pkgs/core/firewall/src}/functions.commands (100%) rename {src/firewall => pkgs/core/firewall/src}/functions.config (100%) rename {src/firewall => pkgs/core/firewall/src}/functions.firewall (100%) rename {src/firewall => pkgs/core/firewall/src}/functions.ip (100%) rename {src/firewall => pkgs/core/firewall/src}/functions.iptables (100%) rename {src/firewall => pkgs/core/firewall/src}/functions.macros (100%) rename {src/firewall => pkgs/core/firewall/src}/functions.zones (100%) rename {src/firewall => pkgs/core/firewall/src}/macros/DHCP (100%) rename {src/firewall => pkgs/core/firewall/src}/macros/HTTP (100%) rename {src/firewall => pkgs/core/firewall/src}/macros/HTTPS (100%) rename {src/firewall => pkgs/core/firewall/src}/macros/WWW (100%) rename {src/firewall => pkgs/core/firewall/src}/zones.blue (100%) rename {src/firewall => pkgs/core/firewall/src}/zones.green (100%) rename {src/firewall => pkgs/core/firewall/src}/zones.orange (100%) rename {src/firewall => pkgs/core/firewall/src}/zones.red (100%) copy lfs/webinterface => pkgs/core/flex/flex.nm (57%) create mode 100644 pkgs/core/flex/patches/flex-2.5.35-gcc44-1.patch copy src/pomona/pomona => pkgs/core/fontconfig/fontconfig.nm (67%) rename src/initscripts/extras/freeradius.conf => pkgs/core/freeradius/freeradius.init (100%) rename lfs/freeradius => pkgs/core/freeradius/freeradius.nm (60%) copy src/pam.d/freeradius-server => pkgs/core/freeradius/freeradius.pam (100%) copy src/logrotate/freeradius-server => pkgs/core/freeradius/logrotate/freeradius (100%) create mode 100644 pkgs/core/freeradius/patches/freeradius-2.1.6-cert-config.patch copy src/pomona/pomona => pkgs/core/freetype/freetype.nm (63%) copy src/pomona/pomona => pkgs/core/fuse/fuse.nm (67%) create mode 100644 pkgs/core/fuse/patches/fuse-2.7.4-openfix.patch create mode 100644 pkgs/core/fuse/patches/fuse-2.7.4-udev_rules.patch copy lfs/stage1 => pkgs/core/gawk/gawk.nm (64%) create mode 100644 pkgs/core/gcc/gcc.nm create mode 100644 pkgs/core/gcc/patches/gcc-4.4-optimize_linking.patch create mode 100644 pkgs/core/gcc/patches/gcc-4.4.1-asprintf_fix.patch create mode 100644 pkgs/core/gcc/patches/gcc-4.4.1-espf-1.patch copy src/pomona/pomona => pkgs/core/gdb/gdb.nm (67%) copy src/pomona/pomona => pkgs/core/gdbm/gdbm.nm (62%) copy lfs/stage1 => pkgs/core/gettext/gettext.nm (58%) create mode 100644 pkgs/core/gettext/patches/gettext-0.17-automake-1.patch create mode 100644 pkgs/core/gettext/patches/gettext-0.17-open-args-1.patch create mode 100644 pkgs/core/gettext/patches/gettext-0.17-rpathFix.patch copy lfs/webinterface => pkgs/core/ghostscript/ghostscript.nm (57%) rename {src/glib => pkgs/core/glib2}/glib2-locale.sh (100%) copy lfs/stage4 => pkgs/core/glib2/glib2.nm (59%) rename src/glibc/glibc-2.10.1-stack_chk_fail.c => pkgs/core/glibc/glibc-stack_chk_fail.c (100%) create mode 100644 pkgs/core/glibc/glibc.nm rename {src => pkgs/core}/glibc/ld.so.conf (100%) rename {src => pkgs/core}/glibc/nsswitch.conf (100%) create mode 100644 pkgs/core/glibc/patches/glibc-2.10.1-arc4random.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.10.1-asprintf_reset2null-1.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.10.1-hardened-configure-picdefault.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.10.1-hardened-inittls-nosysenter.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.10.1-localedef_trampoline-1.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.10.1-pt_pax-1.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.10.1-sanitize_env.patch.off create mode 100644 pkgs/core/glibc/patches/glibc-2.10.1-strlcpy_strlcat-1.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.10.1-undefine-__i686.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.11.1-hardened-pie.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.11.1-mktemp_urandom.patch create mode 100644 pkgs/core/glibc/patches/glibc-2.11.1-owl-alt-res_randomid.patch rename lfs/gmp => pkgs/core/gmp/gmp.nm (68%) copy src/pomona/pomona => pkgs/core/gnupg2/gnupg2.nm (65%) copy src/pomona/pomona => pkgs/core/gnutls/gnutls.nm (67%) copy src/pomona/pomona => pkgs/core/gobject-introspection/gobject-introspection.nm (66%) copy src/pomona/pomona => pkgs/core/gperf/gperf.nm (67%) copy lfs/stage1 => pkgs/core/grep/grep.nm (64%) rename lfs/groff => pkgs/core/groff/groff.nm (59%) create mode 100644 pkgs/core/groff/patches/groff-1.18.1.4-debian_fixes-1.patch rename {src/bootloader => pkgs/core/grub}/grub.conf (100%) copy lfs/webinterface => pkgs/core/grub/grub.nm (57%) rename {src/bootloader => pkgs/core/grub}/splash.xpm.gz (100%) copy src/initscripts/sysconfig/rc.local => pkgs/core/gssdp/gssdp.nm (71%) copy src/initscripts/sysconfig/rc.local => pkgs/core/gupnp-av/gupnp-av.nm (70%) copy src/initscripts/sysconfig/rc.local => pkgs/core/gupnp-igd/gupnp-igd.nm (70%) copy src/pomona/pomona => pkgs/core/gupnp/gupnp.nm (67%) copy lfs/webinterface => pkgs/core/gzip/gzip.nm (64%) create mode 100644 pkgs/core/gzip/patches/gzip-1.3.13-cve-2006-4337_len.patch create mode 100644 pkgs/core/gzip/patches/gzip-1.3.13-cve-2006-4338.patch create mode 100644 pkgs/core/gzip/patches/gzip-1.3.13-openbsd-owl-tmp.patch rename lfs/hdparm => pkgs/core/hdparm/hdparm.nm (65%) rename {src => pkgs/core}/hostapd/config (100%) copy lfs/stage4 => pkgs/core/hostapd/hostapd.nm (61%) copy src/pomona/pomona => pkgs/core/hplip/hplip.nm (64%) copy src/initscripts/sysconfig/rc.local => pkgs/core/htop/htop.nm (69%) copy lfs/stage4 => pkgs/core/iana-etc/iana-etc.nm (68%) rename {src/initscripts/core => pkgs/core/initscripts}/functions (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/checkfs.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/cleanfs.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/control-alt-delete.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/load-modules.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/loopback.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/mount-kernel-filesystems.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/mountfs.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/serial.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/shutdown.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/swap.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/sysctl.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/tty1.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/tty2.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/tty3.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/tty4.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/udev.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/udevtrigger.conf (100%) rename {src/initscripts/core => pkgs/core/initscripts/init}/welcome.conf (100%) copy lfs/stage4 => pkgs/core/initscripts/initscripts.nm (59%) rename {src => pkgs/core}/initscripts/src/Makefile (100%) rename {src => pkgs/core}/initscripts/src/console_check.c (100%) rename {src => pkgs/core}/initscripts/src/securetty.c (100%) rename {src => pkgs/core}/initscripts/sysconfig/clock (100%) rename {src => pkgs/core}/initscripts/sysconfig/createfiles (100%) rename {src => pkgs/core}/initscripts/sysconfig/modules (100%) rename {src => pkgs/core}/initscripts/sysconfig/network (100%) rename {src => pkgs/core}/initscripts/sysconfig/rc (100%) copy {src => pkgs/core}/initscripts/sysconfig/rc.local (100%) rename {src => pkgs/core}/initscripts/sysconfig/rc.site (100%) rename {src/initscripts/etc => pkgs/core/initscripts}/sysctl.conf (100%) copy src/pomona/pomona => pkgs/core/intltool/intltool.nm (67%) copy lfs/webinterface => pkgs/core/iproute2/iproute2.nm (64%) create mode 100644 pkgs/core/iproute2/patches/iproute2-2.6.29-1-opt_flags.patch create mode 100644 pkgs/core/iptables/iptables.nm create mode 100644 pkgs/core/iputils/iputils.nm create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-addrcache.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-arping-infiniband.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-arping_timeout.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-countermeasures.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-idn.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-open-max.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-output.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-ping-subint.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-ping_cleanup.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-rh.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-traffic_class.patch create mode 100644 pkgs/core/iputils/patches/iputils-s20071127-warnings.patch copy src/pomona/pomona => pkgs/core/iw/iw.nm (63%) create mode 100644 pkgs/core/iw/patches/iw-0.9.17-default-install-to-PREFIX-sbin.patch copy src/initscripts/sysconfig/rc.local => pkgs/core/joe/joe.nm (70%) copy src/pomona/pomona => pkgs/core/jwhois/jwhois.nm (61%) create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-conf.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-conf_update.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-conf_update2.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-conf_update3.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-conf_update4.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-connect.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-dotster.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-enum.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-fclose.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-gi.patch create mode 100644 pkgs/core/jwhois/patches/jwhois-4.0-ipv6match.patch copy lfs/webinterface => pkgs/core/kbd/kbd.nm (61%) create mode 100644 pkgs/core/kbd/patches/kbd-1.15.1-backspace-1.patch create mode 100644 pkgs/core/kernel-headers/kernel-headers.nm create mode 120000 pkgs/core/kernel-headers/patches rename src/kernel/kernel.config => pkgs/core/kernel/config (100%) rename {src => pkgs/core}/kernel/ipfire_logo.ppm (100%) create mode 100644 pkgs/core/kernel/kernel.nm create mode 100644 pkgs/core/kernel/patches/aufs2-2.6.31.1-1.patch create mode 100644 pkgs/core/kernel/patches/grsecurity-2.1.14-2.6.31.1-200910012153.patch create mode 100644 pkgs/core/kernel/patches/linux-2.6.31.1-disable-compat_vdso-1.patch.off create mode 100644 pkgs/core/kernel/patches/linux-2.6.31.1-scsi.h-fix-1.patch create mode 100644 pkgs/core/kernel/patches/reiser4-for-2.6.31.1.patch create mode 100644 pkgs/core/kernel/patches/routes-2.6.31.1-16.diff copy src/pomona/pomona => pkgs/core/l7-protocols/l7-protocols.nm (66%) copy src/pomona/pomona => pkgs/core/ldapvi/ldapvi.nm (64%) copy src/pomona/pomona => pkgs/core/less/less.nm (66%) copy src/pomona/pomona => pkgs/core/libaal/libaal.nm (65%) copy src/initscripts/sysconfig/rc.local => pkgs/core/libart/libart.nm (70%) create mode 100644 pkgs/core/libart/patches/libart_lgpl-2.3.19-upstream_fix-1.patch copy src/pomona/pomona => pkgs/core/libassuan/libassuan.nm (64%) create mode 100644 pkgs/core/libassuan/patches/libassuan-1.0.5-ac.patch create mode 100644 pkgs/core/libassuan/patches/libassuan-1.0.5-shared.patch copy lfs/webinterface => pkgs/core/libcap/libcap.nm (64%) create mode 100644 pkgs/core/libcap/patches/libcap-2.16-headerfix.patch copy src/initscripts/sysconfig/rc.local => pkgs/core/libdaemon/libdaemon.nm (70%) copy src/pomona/pomona => pkgs/core/libdnet/libdnet.nm (65%) create mode 100644 pkgs/core/libdnet/patches/libdnet-1.12-shrext.patch copy src/pomona/pomona => pkgs/core/libevent/libevent.nm (63%) copy src/pomona/pomona => pkgs/core/libgcrypt/libgcrypt.nm (67%) copy src/pomona/pomona => pkgs/core/libgpg-error/libgpg-error.nm (66%) copy src/initscripts/sysconfig/rc.local => pkgs/core/libgssglue/libgssglue.nm (68%) copy lfs/stage4 => pkgs/core/libidn/libidn.nm (59%) copy src/initscripts/sysconfig/rc.local => pkgs/core/libjpeg/libjpeg.nm (68%) copy src/initscripts/sysconfig/rc.local => pkgs/core/libksba/libksba.nm (72%) copy src/pomona/pomona => pkgs/core/libnetfilter_conntrack/libnetfilter_conntrack.nm (67%) copy src/pomona/pomona => pkgs/core/libnetfilter_log/libnetfilter_log.nm (67%) copy src/pomona/pomona => pkgs/core/libnetfilter_queue/libnetfilter_queue.nm (67%) copy src/pomona/pomona => pkgs/core/libnfnetlink/libnfnetlink.nm (67%) copy lfs/stage4 => pkgs/core/libnfsidmap/libnfsidmap.nm (59%) copy src/pomona/pomona => pkgs/core/libnih/libnih.nm (64%) copy src/pomona/pomona => pkgs/core/libnl/libnl.nm (66%) create mode 100644 pkgs/core/libnl/patches/libnl-1.1-include-limits-h.patch create mode 100644 pkgs/core/libnl/patches/libnl-1.1-no-extern-inline.patch create mode 100644 pkgs/core/libnl/patches/libnl-1.1-permissions.patch copy lfs/stage4 => pkgs/core/libpcap/libpcap.nm (58%) copy src/pomona/pomona => pkgs/core/libpng/libpng.nm (67%) create mode 100644 pkgs/core/libpng/patches/libpng-1.2.39-pngconf.patch copy src/initscripts/sysconfig/rc.local => pkgs/core/librpcsecgss/librpcsecgss.nm (69%) copy src/pomona/pomona => pkgs/core/libsoup/libsoup.nm (67%) copy lfs/stage4 => pkgs/core/libssh2/libssh2.nm (68%) copy src/pomona/pomona => pkgs/core/libtiff/libtiff.nm (67%) copy src/pomona/pomona => pkgs/core/libtool/libtool.nm (67%) copy src/initscripts/sysconfig/rc.local => pkgs/core/libusb-compat/libusb-compat.nm (69%) copy src/initscripts/sysconfig/rc.local => pkgs/core/libusb/libusb.nm (71%) copy src/pomona/pomona => pkgs/core/libuser/libuser.nm (63%) copy src/pomona/pomona => pkgs/core/libvirt/libvirt.nm (67%) copy src/pomona/pomona => pkgs/core/libxml2/libxml2.nm (62%) rename {src => pkgs/core}/lighttpd/lighttpd.conf (100%) rename src/initscripts/extras/lighttpd.conf => pkgs/core/lighttpd/lighttpd.init (100%) copy lfs/webinterface => pkgs/core/lighttpd/lighttpd.nm (55%) copy src/pomona/pomona => pkgs/core/linux-atm/linux-atm.nm (67%) create mode 100644 pkgs/core/linux-atm/patches/linux-atm-2.4.1-gcc-4.patch create mode 100644 pkgs/core/linux-atm/patches/linux-atm-2.4.1-nmu.patch copy src/pomona/pomona => pkgs/core/lm-sensors/lm-sensors.nm (65%) copy lfs/webinterface => pkgs/core/logrotate/logrotate.nm (57%) create mode 100644 pkgs/core/logrotate/patches/logrotate-3.7.7-curdir.patch create mode 100644 pkgs/core/logrotate/patches/logrotate-3.7.7-toolarge.patch copy src/pomona/pomona => pkgs/core/lsof/lsof.nm (64%) rename lfs/lua => pkgs/core/lua/lua.nm (62%) create mode 100644 pkgs/core/lua/patches/lua-5.1.4-autotoolize.patch copy lfs/webinterface => pkgs/core/lvm2/lvm2.nm (57%) copy src/pomona/pomona => pkgs/core/lzo/lzo.nm (66%) rename lfs/m4 => pkgs/core/m4/m4.nm (65%) copy src/pomona/pomona => pkgs/core/make/make.nm (63%) copy lfs/stage1 => pkgs/core/man-db/man-db.nm (64%) copy src/initscripts/sysconfig/rc.local => pkgs/core/man-pages/man-pages.nm (68%) copy lfs/stage4 => pkgs/core/mc/mc.nm (61%) create mode 100644 pkgs/core/mc/patches/mc-4.6.2-utf8.patch copy lfs/webinterface => pkgs/core/mdadm/mdadm.nm (57%) create mode 100644 pkgs/core/mdadm/patches/mdadm-3.0-devel2-warn.patch copy src/pomona/pomona => pkgs/core/memtest86+/memtest86+.nm (63%) copy lfs/stage4 => pkgs/core/mkinitramfs/mkinitramfs.nm (67%) rename {src/mkinitramfs => pkgs/core/mkinitramfs/src}/functions (100%) rename {src/mkinitramfs => pkgs/core/mkinitramfs/src}/lsinitramfs (100%) rename {src/mkinitramfs => pkgs/core/mkinitramfs/src}/mkinitramfs (100%) rename {src/mkinitramfs => pkgs/core/mkinitramfs/src}/mkliveramfs (100%) rename {src => pkgs/core}/module-init-tools/modprobe.d/blacklist.conf (100%) rename {src => pkgs/core}/module-init-tools/modprobe.d/modprobe.conf (100%) copy lfs/stage4 => pkgs/core/module-init-tools/module-init-tools.nm (59%) create mode 100644 pkgs/core/module-init-tools/patches/module-init-tools-3.7-nostatic-1.patch rename lfs/mpfr => pkgs/core/mpfr/mpfr.nm (67%) copy lfs/stage4 => pkgs/core/nano/nano.nm (68%) copy src/pomona/pomona => pkgs/core/nasm/nasm.nm (67%) copy lfs/cairo => pkgs/core/ncurses/ncurses.nm (59%) copy lfs/stage4 => pkgs/core/net-snmp/net-snmp.nm (59%) rename src/initscripts/extras/network.conf => pkgs/core/network/network.init (100%) copy lfs/stage4 => pkgs/core/network/network.nm (61%) rename {src/network => pkgs/core/network/src}/functions (100%) rename {src/network => pkgs/core/network/src}/functions.ppp (100%) rename {src/network => pkgs/core/network/src}/hook-header (100%) rename {src/network => pkgs/core/network/src}/hooks/README (100%) rename {src/network => pkgs/core/network/src}/hooks/bonding (100%) rename {src/network => pkgs/core/network/src}/hooks/ethernet (100%) rename {src/network => pkgs/core/network/src}/hooks/ipv4-dhcp (100%) rename {src/network => pkgs/core/network/src}/hooks/ipv4-static (100%) rename {src/network => pkgs/core/network/src}/hooks/ipv4-static-route (100%) rename {src/network => pkgs/core/network/src}/hooks/mtu (100%) rename {src/network => pkgs/core/network/src}/hooks/pppoe (100%) rename {src/network => pkgs/core/network/src}/hooks/pppoe.helper (100%) rename {src/network => pkgs/core/network/src}/hooks/stp (100%) rename {src/network => pkgs/core/network/src}/hooks/vlan (100%) rename {src/network => pkgs/core/network/src}/network (100%) rename {src/network => pkgs/core/network/src}/ppp/ip-updown (100%) rename {src/network => pkgs/core/network/src}/zone (100%) rename lfs/newt => pkgs/core/newt/newt.nm (58%) copy lfs/webinterface => pkgs/core/nfs-utils/nfs-utils.nm (57%) copy src/pomona/pomona => pkgs/core/nmap/nmap.nm (65%) create mode 100644 pkgs/core/nmap/patches/nmap-5.00-mktemp.patch copy src/pomona/pomona => pkgs/core/noip/noip.nm (65%) copy src/pomona/pomona => pkgs/core/nss_ldap/nss_ldap.nm (63%) rename {src => pkgs/core}/ntp/ntp.conf (100%) rename src/initscripts/extras/ntp.conf => pkgs/core/ntp/ntp.init (100%) copy src/pomona/pomona => pkgs/core/ntp/ntp.nm (65%) rename src/initscripts/extras/openldap.conf => pkgs/core/openldap/openldap.init (100%) rename lfs/paxtest => pkgs/core/openldap/openldap.nm (53%) create mode 100644 pkgs/core/openldap/patches/openldap-2.4.17-disable_sys_err.patch rename {src => pkgs/core}/openldap/slapd.conf (100%) rename src/initscripts/extras/openlldp.conf => pkgs/core/openlldp/openlldp.init (100%) copy src/initscripts/sysconfig/rc.local => pkgs/core/openlldp/openlldp.nm (70%) rename src/initscripts/extras/openssh.conf => pkgs/core/openssh/openssh.init (100%) copy lfs/stage1 => pkgs/core/openssh/openssh.nm (64%) copy src/pam.d/login => pkgs/core/openssh/sshd.pam (100%) rename {src => pkgs/core}/openssh/sshd_config (100%) rename {src => pkgs/core}/openssl/openssl.cnf (100%) rename lfs/openssl => pkgs/core/openssl/openssl.nm (58%) create mode 100644 pkgs/core/openssl/patches/openssl-0.9.8k-enginesdir.patch create mode 100644 pkgs/core/openssl/patches/openssl-0.9.8k-fix_manpages-1.patch create mode 100644 pkgs/core/openssl/patches/openssl-0.9.8k-no-rpath.patch rename lfs/openvpn => pkgs/core/openvpn/openvpn.nm (59%) copy src/pomona/pomona => pkgs/core/pakfire/pakfire.nm (67%) rename {src/pakfire => pkgs/core/pakfire/src}/Makefile (94%) copy {src/pakfire => pkgs/core/pakfire/src}/decompressor (97%) rename {src/pakfire => pkgs/core/pakfire/src}/functions (100%) rename {src/pakfire => pkgs/core/pakfire/src}/index (100%) rename {src/pakfire => pkgs/core/pakfire/src}/pakfire.in (100%) rename {src/pakfire => pkgs/core/pakfire/src}/python/__init__.py (100%) rename {src/pakfire => pkgs/core/pakfire/src}/python/db.py (100%) rename {src/pakfire => pkgs/core/pakfire/src}/python/io.py (100%) rename {src/pakfire => pkgs/core/pakfire/src}/python/package.py (100%) rename {src/pakfire => pkgs/core/pakfire/src}/python/repo.py (100%) rename {src/pakfire => pkgs/core/pakfire/src}/python/servers.py (100%) rename {src/pakfire => pkgs/core/pakfire/src}/python/transactionset.py (100%) rename {src => pkgs/core}/pam/login.defs (100%) rename {src => pkgs/core/pam}/pam.d/other (100%) rename {src => pkgs/core/pam}/pam.d/system-auth (100%) rename lfs/pam => pkgs/core/pam/pam.nm (56%) rename {src => pkgs/core}/pam/pam_env.conf (100%) create mode 100644 pkgs/core/pam/patches/Linux-PAM-1.1.0-no-yywrap-1.patch rename {src => pkgs/core}/pam/securetty (100%) copy src/pomona/pomona => pkgs/core/pam_ldap/pam_ldap.nm (67%) copy src/initscripts/sysconfig/rc.local => pkgs/core/pango/pango.nm (68%) copy src/pomona/pomona => pkgs/core/parted/parted.nm (67%) create mode 100644 pkgs/core/parted/patches/parted-2.1-blkid_topology_get_physical_sector_size.patch create mode 100644 pkgs/core/parted/patches/parted-2.1-dasd-NULL-dereference-rh563419.patch create mode 100644 pkgs/core/parted/patches/parted-2.1-default-alignment.patch create mode 100644 pkgs/core/parted/patches/parted-2.1-gpt-clobber-pmbr-rh563211.patch create mode 100644 pkgs/core/parted/patches/parted-2.1-mem-leak-fixes-rh556012.patch create mode 100644 pkgs/core/parted/patches/parted-2.1-needs_clobber-rh566181.patch copy lfs/stage4 => pkgs/core/passwd/passwd.nm (68%) copy src/pomona/pomona => pkgs/core/patch/patch.nm (65%) create mode 100644 pkgs/core/patch/patches/patch-2.6.1-test_fix-1.patch copy lfs/stage4 => pkgs/core/pax-utils/pax-utils.nm (68%) copy lfs/stage4 => pkgs/core/paxctl/paxctl.nm (68%) copy src/pomona/pomona => pkgs/core/paxtest/paxtest.nm (65%) copy src/pomona/pomona => pkgs/core/pciutils/pciutils.nm (62%) copy lfs/stage1 => pkgs/core/pcre/pcre.nm (64%) rename src/initscripts/extras/pdns-recursor.conf => pkgs/core/pdns-recursor/pdns-recursor.init (100%) copy src/pomona/pomona => pkgs/core/pdns-recursor/pdns-recursor.nm (66%) create mode 100644 pkgs/core/pdns/patches/pdns-2.9.22-gcc44-fixes.patch copy src/pomona/pomona => pkgs/core/pdns/pdns.nm (64%) copy src/pomona/pomona => pkgs/core/perl-xml-parser/perl-xml-parser.nm (65%) create mode 100644 pkgs/core/perl/patches/perl-5.10.1-utf8-1.patch rename lfs/fontconfig => pkgs/core/perl/perl.nm (55%) copy src/pomona/pomona => pkgs/core/pinentry/pinentry.nm (64%) copy src/pomona/pomona => pkgs/core/pixman/pixman.nm (67%) copy src/pomona/pomona => pkgs/core/pkg-config/pkg-config.nm (67%) copy src/pomona/pomona => pkgs/core/pomona/pomona.nm (64%) rename {src/pomona => pkgs/core/pomona/src}/Makefile (100%) rename {src/pomona => pkgs/core/pomona/src}/Makefile.inc (98%) rename {src/pomona => pkgs/core/pomona/src}/autopart.py (100%) rename {src/pomona => pkgs/core/pomona/src}/backend.py (100%) rename {src/pomona => pkgs/core/pomona/src}/bootloader.py (100%) rename {src/pomona => pkgs/core/pomona/src}/console.py (100%) rename {src/pomona => pkgs/core/pomona/src}/constants.py (100%) rename {src/pomona => pkgs/core/pomona/src}/cryptodev.py (100%) rename {src/pomona => pkgs/core/pomona/src}/dispatch.py (100%) rename {src/pomona => pkgs/core/pomona/src}/dmraid.py (100%) rename {src/pomona => pkgs/core/pomona/src}/errors.py (100%) rename {src/pomona => pkgs/core/pomona/src}/exception.py (100%) rename {src/pomona => pkgs/core/pomona/src}/flags.py (100%) rename {src/pomona => pkgs/core/pomona/src}/fsset.py (100%) rename {src/pomona => pkgs/core/pomona/src}/installer.py (100%) rename {src/pomona => pkgs/core/pomona/src}/instdata.py (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/Makefile (99%) rename {src/pomona => pkgs/core/pomona/src}/isys/devices.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/devices.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/eddsupport.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/eddsupport.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/ethtool.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/imount.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/imount.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/isofs.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/isys.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/isys.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/isys.py (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/lang.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/lang.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/linkdetect.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/net.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/smp.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/smp.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/str.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/str.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/stubs.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/sundries.h (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/vio.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/wireless.c (100%) rename {src/pomona => pkgs/core/pomona/src}/isys/wireless.h (100%) rename {src/pomona => pkgs/core/pomona/src}/iutil.py (100%) rename {src/pomona => pkgs/core/pomona/src}/keyboard_models.py (100%) rename {src/pomona => pkgs/core/pomona/src}/lang-table (100%) rename {src/pomona => pkgs/core/pomona/src}/lvm.py (100%) rename {src/pomona => pkgs/core/pomona/src}/network.py (100%) rename {src/pomona => pkgs/core/pomona/src}/packages.py (100%) rename {src/pomona => pkgs/core/pomona/src}/pakfireinstall.py (100%) rename {src/pomona => pkgs/core/pomona/src}/partErrors.py (100%) rename {src/pomona => pkgs/core/pomona/src}/partIntfHelpers.py (100%) rename {src/pomona => pkgs/core/pomona/src}/partRequests.py (100%) rename {src/pomona => pkgs/core/pomona/src}/partedUtils.py (100%) rename {src/pomona => pkgs/core/pomona/src}/partitioning.py (100%) rename {src/pomona => pkgs/core/pomona/src}/partitions.py (100%) rename {src/pomona => pkgs/core/pomona/src}/po/Makefile (100%) rename {src/pomona => pkgs/core/pomona/src}/po/da.po (100%) rename {src/pomona => pkgs/core/pomona/src}/po/de.po (100%) rename {src/pomona => pkgs/core/pomona/src}/po/pomona.pot (100%) copy {src/pomona => pkgs/core/pomona/src}/pomona (100%) rename {src/pomona => pkgs/core/pomona/src}/pomona_log.py (100%) rename {src/pomona => pkgs/core/pomona/src}/pychecker-false-positives (100%) rename {src/pomona => pkgs/core/pomona/src}/raid.py (100%) rename {src/pomona => pkgs/core/pomona/src}/runpychecker.sh (100%) rename {src/pomona => pkgs/core/pomona/src}/scripts/getlangnames.py (100%) create mode 100644 pkgs/core/pomona/src/storage_old/__init__.py create mode 100644 pkgs/core/pomona/src/storage_old/deviceaction.py copy src/vsftpd/vsftpd.user_list => pkgs/core/pomona/src/storage_old/devicelibs/__init__.py (100%) create mode 100644 pkgs/core/pomona/src/storage_old/devicelibs/crypto.py create mode 100644 pkgs/core/pomona/src/storage_old/devicelibs/lvm.py create mode 100644 pkgs/core/pomona/src/storage_old/devicelibs/swap.py create mode 100644 pkgs/core/pomona/src/storage_old/devices.py create mode 100644 pkgs/core/pomona/src/storage_old/devicetree.py create mode 100644 pkgs/core/pomona/src/storage_old/errors.py create mode 100644 pkgs/core/pomona/src/storage_old/formats/__init__.py create mode 100644 pkgs/core/pomona/src/storage_old/formats/fs.py create mode 100644 pkgs/core/pomona/src/storage_old/formats/luks.py create mode 100644 pkgs/core/pomona/src/storage_old/formats/lvmpv.py create mode 100644 pkgs/core/pomona/src/storage_old/formats/swap.py create mode 100644 pkgs/core/pomona/src/storage_old/partitioning.py create mode 100644 pkgs/core/pomona/src/storage_old/udev.py create mode 100755 pkgs/core/pomona/src/storage_test.py rename {src/pomona => pkgs/core/pomona/src}/timezone.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_bootloader.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_complete.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_confirm.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_keyboard.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_language.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_network.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_partition.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_progress.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_timezone.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_userauth.py (100%) rename {src/pomona => pkgs/core/pomona/src}/tui_welcome.py (100%) rename {src/pomona => pkgs/core/pomona/src}/users.py (100%) rename {src/pomona => pkgs/core/pomona/src}/zonetab.py (100%) copy src/pomona/pomona => pkgs/core/popt/popt.nm (66%) create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-bogus_dns_addr.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-closelog.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-dontwriteetc.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-fix.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-ipv6-accept-remote.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-libutil.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-local.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-new_speeds.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-pie.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-pppoatm-mtu.patch create mode 100644 pkgs/core/ppp/patches/ppp-2.4.4-response_len.patch copy lfs/cairo => pkgs/core/ppp/ppp.nm (55%) rename src/pam.d/ppp => pkgs/core/ppp/ppp.pam (100%) copy src/pomona/pomona => pkgs/core/pptp/pptp.nm (64%) create mode 100644 pkgs/core/procps/patches/procps-3.2.8-watch_unicode-2.patch copy src/pomona/pomona => pkgs/core/procps/procps.nm (66%) copy src/pomona/pomona => pkgs/core/psmisc/psmisc.nm (65%) copy lfs/stage4 => pkgs/core/pth/pth.nm (68%) copy src/pomona/pomona => pkgs/core/pychecker/pychecker.nm (67%) copy src/pomona/pomona => pkgs/core/pyfire/pyfire.nm (67%) rename {src/pyfire => pkgs/core/pyfire/src}/Makefile (100%) rename {src/pyfire => pkgs/core/pyfire/src}/__init__.py (100%) rename {src/pyfire => pkgs/core/pyfire/src}/config.py (100%) rename {src/pyfire => pkgs/core/pyfire/src}/executil.py (100%) rename {src/pyfire => pkgs/core/pyfire/src}/hal.py (100%) rename {src/pyfire => pkgs/core/pyfire/src}/net.py (100%) rename {src/pyfire => pkgs/core/pyfire/src}/web.py (100%) copy src/pomona/pomona => pkgs/core/python-IPy/python-IPy.nm (65%) copy src/pomona/pomona => pkgs/core/python-cryptsetup/python-cryptsetup.nm (67%) copy src/initscripts/sysconfig/rc.local => pkgs/core/python-dbus/python-dbus.nm (71%) copy src/pomona/pomona => pkgs/core/python-decorator/python-decorator.nm (63%) copy src/pomona/pomona => pkgs/core/python-netfilter_conntrack/python-netfilter_conntrack.nm (66%) copy src/initscripts/sysconfig/rc.local => pkgs/core/python-parted/python-parted.nm (70%) copy src/pomona/pomona => pkgs/core/python-pyblock/python-pyblock.nm (66%) copy lfs/webinterface => pkgs/core/python-setuptools/python-setuptools.nm (57%) copy src/pomona/pomona => pkgs/core/python-tornado/python-tornado.nm (66%) copy src/pomona/pomona => pkgs/core/python-urlgrabber/python-urlgrabber.nm (67%) create mode 100644 pkgs/core/python/patches/python-2.6-rpath.patch create mode 100644 pkgs/core/python/patches/python-2.6-update-bsddb3-4.8.patch create mode 100644 pkgs/core/python/patches/python-2.6.2-with-system-expat.patch rename lfs/python => pkgs/core/python/python.nm (63%) copy src/pomona/pomona => pkgs/core/qemu/qemu.nm (63%) rename lfs/quagga => pkgs/core/quagga/quagga.nm (66%) copy src/pomona/pomona => pkgs/core/radvd/radvd.nm (62%) rename {src/bash => pkgs/core/readline}/inputrc (100%) create mode 100644 pkgs/core/readline/patches/readline-6.1-shlib.patch create mode 100644 pkgs/core/readline/patches/readline-6.1-upstream-1.patch create mode 100644 pkgs/core/readline/patches/readline-6.1-upstream-2.patch rename lfs/readline => pkgs/core/readline/readline.nm (56%) create mode 100644 pkgs/core/reiser4progs/patches/reiser4progs-1.0.7-bad_elif.patch create mode 100644 pkgs/core/reiser4progs/patches/reiser4progs-libaal.patch create mode 100644 pkgs/core/reiser4progs/patches/reiser4progs-makefile.patch create mode 100644 pkgs/core/reiser4progs/patches/reiser4progs-opt.patch copy lfs/webinterface => pkgs/core/reiser4progs/reiser4progs.nm (57%) copy src/pomona/pomona => pkgs/core/reiserfsprogs/reiserfsprogs.nm (67%) copy lfs/webinterface => pkgs/core/rrdtool/rrdtool.nm (57%) rename {src => pkgs/core}/rstp/bridge-stp (100%) rename src/initscripts/extras/rstp.conf => pkgs/core/rstp/rstp.init (100%) copy src/pomona/pomona => pkgs/core/rstp/rstp.nm (65%) rename lfs/samba => pkgs/core/samba/samba.nm (61%) create mode 100644 pkgs/core/sane/patches/sane-1.0.20-lockdir.patch create mode 100644 pkgs/core/sane/patches/sane-1.0.20-pkgconfig.patch create mode 100644 pkgs/core/sane/patches/sane-1.0.20-rpath.patch create mode 100644 pkgs/core/sane/patches/sane-1.0.20-udev.patch copy src/pomona/pomona => pkgs/core/sane/sane.nm (62%) copy lfs/webinterface => pkgs/core/screen/screen.nm (64%) copy src/pam.d/screen => pkgs/core/screen/screen.pam (100%) create mode 100644 pkgs/core/screen/screenrc copy src/initscripts/sysconfig/rc.local => pkgs/core/sdl/sdl.nm (68%) copy lfs/stage1 => pkgs/core/sed/sed.nm (65%) create mode 100644 pkgs/core/shadow/patches/shadow-4.1.4.2-goodname.patch create mode 100644 pkgs/core/shadow/patches/shadow-4.1.4.2-ipfire.patch copy lfs/cairo => pkgs/core/shadow/shadow.nm (59%) create mode 100644 pkgs/core/slang/patches/slang-2.1.4-makefile.patch copy src/pomona/pomona => pkgs/core/slang/slang.nm (67%) copy src/pomona/pomona => pkgs/core/smartmontools/smartmontools.nm (64%) rename lfs/sqlite => pkgs/core/sqlite/sqlite.nm (60%) copy lfs/stage4 => pkgs/core/squashfs-tools/squashfs-tools.nm (67%) create mode 100644 pkgs/core/squid/squid.nm copy src/pomona/pomona => pkgs/core/strace/strace.nm (67%) copy lfs/webinterface => pkgs/core/strongswan/strongswan.nm (57%) rename lfs/sudo => pkgs/core/sudo/sudo.nm (57%) copy src/pam.d/freeradius-server => pkgs/core/sudo/sudo.pam (58%) rename {src => pkgs/core}/sudo/sudoers (100%) copy src/initscripts/sysconfig/rc.local => pkgs/core/sysfsutils/sysfsutils.nm (70%) rename lfs/syslinux => pkgs/core/syslinux/syslinux.nm (60%) rename {src => pkgs/core}/syslog-ng/ids-block (100%) rename {src => pkgs/core}/syslog-ng/logextract (100%) rename {src => pkgs/core}/syslog-ng/syslog-ng.conf (100%) rename src/initscripts/extras/syslog-ng.conf => pkgs/core/syslog-ng/syslog-ng.init (100%) copy lfs/webinterface => pkgs/core/syslog-ng/syslog-ng.nm (61%) copy lfs/webinterface => pkgs/core/system-release/system-release.nm (64%) copy src/pomona/pomona => pkgs/core/sysvinit/sysvinit.nm (64%) create mode 100644 pkgs/core/tar/patches/tar-1.22-vfatTruncate.patch create mode 100644 pkgs/core/tar/patches/tar-1.22-xattrs-1.patch create mode 100644 pkgs/core/tar/patches/tar-1.22-xattrs-conf-1.patch copy lfs/webinterface => pkgs/core/tar/tar.nm (64%) create mode 100644 pkgs/core/tcl/patches/tcl-8.5.8-autopath.patch create mode 100644 pkgs/core/tcl/patches/tcl-8.5.8-conf.patch create mode 100644 pkgs/core/tcl/patches/tcl-8.5.8-pic.patch copy src/pomona/pomona => pkgs/core/tcl/tcl.nm (62%) create mode 100644 pkgs/core/tcpdump/patches/tcpdump-4.0.0-ipv6-build.patch copy src/pomona/pomona => pkgs/core/tcpdump/tcpdump.nm (67%) copy lfs/stage4 => pkgs/core/texinfo/texinfo.nm (66%) rename lfs/traceroute => pkgs/core/traceroute/traceroute.nm (64%) rename {src/initscripts => pkgs/core}/udev/console_init (100%) rename {src/udev => pkgs/core/udev/rules}/10-console.rules (100%) rename {src/udev => pkgs/core/udev/rules}/23-usb.rules (100%) rename {src/udev => pkgs/core/udev/rules}/55-ipfire.rules (100%) rename {src/udev => pkgs/core/udev/rules}/60-net.rules (100%) rename {src/udev => pkgs/core/udev/rules}/61-cdrom.rules (100%) copy lfs/webinterface => pkgs/core/udev/udev.nm (56%) rename {src/ulogd => pkgs/core/ulogd2}/sqlite3.table (100%) rename {src/ulogd => pkgs/core/ulogd2}/ulogd.conf (100%) rename src/initscripts/extras/ulogd.conf => pkgs/core/ulogd2/ulogd.init (100%) rename {src/ulogd => pkgs/core/ulogd2}/ulogd.logrotate (100%) copy lfs/stage4 => pkgs/core/ulogd2/ulogd2.nm (59%) copy lfs/stage4 => pkgs/core/unzip/unzip.nm (59%) copy lfs/webinterface => pkgs/core/upstart/upstart.nm (57%) copy src/initscripts/sysconfig/rc.local => pkgs/core/usbutils/usbutils.nm (69%) rename {src => pkgs/core}/util-linux-ng/nologin.8 (100%) rename {src => pkgs/core}/util-linux-ng/nologin.c (100%) rename {src => pkgs/core/util-linux-ng}/pam.d/login (100%) rename lfs/util-linux-ng => pkgs/core/util-linux-ng/util-linux-ng.nm (54%) create mode 100644 pkgs/core/vim/patches/vim-7.2-fixes-4.patch create mode 100644 pkgs/core/vim/patches/vim-7.2-mandir-1.patch copy lfs/stage1 => pkgs/core/vim/vim.nm (65%) create mode 100644 pkgs/core/vim/vimrc copy lfs/stage4 => pkgs/core/vlan/vlan.nm (68%) create mode 100644 pkgs/core/vsftpd/patches/1-vsftpd-build_ssl.patch create mode 100644 pkgs/core/vsftpd/patches/2-vsftpd-libs-3.patch create mode 100644 pkgs/core/vsftpd/patches/3-vsftpd-pam_hostname-1.patch create mode 100644 pkgs/core/vsftpd/patches/4-vsftpd-close-std-fds.patch create mode 100644 pkgs/core/vsftpd/patches/5-vsftpd-configuration-1.patch copy {src => pkgs/core}/vsftpd/vsftpd.conf (100%) rename lfs/webinterface => pkgs/core/vsftpd/vsftpd.nm (64%) copy src/pam.d/vsftpd => pkgs/core/vsftpd/vsftpd.pam (100%) copy {src => pkgs/core}/vsftpd/vsftpd.user_list (100%) rename src/initscripts/sysconfig/rc.local => pkgs/core/which/which.nm (71%) create mode 100644 pkgs/core/wireless-tools/patches/wireless_tools.29-makefile.patch rename lfs/stage1 => pkgs/core/wireless-tools/wireless-tools.nm (58%) create mode 100644 pkgs/core/xen/patches/xen-3.4.0-co_assignment.patch create mode 100644 pkgs/core/xen/patches/xen-3.4.0-cpufreq.patch create mode 100644 pkgs/core/xen/patches/xend-config-3.4.0.patch rename src/pomona/pomona => pkgs/core/xen/xen.nm (65%) rename lfs/cairo => pkgs/core/xfsprogs/xfsprogs.nm (63%) rename lfs/stage4 => pkgs/core/xz/xz.nm (65%) rename lfs/htop => pkgs/core/zlib/zlib.nm (64%) create mode 100644 pkgs/gmsl create mode 100644 pkgs/toolchain/acl/acl.nm create mode 100644 pkgs/toolchain/attr/attr.nm create mode 100644 pkgs/toolchain/bash/bash.nm create mode 100644 pkgs/toolchain/binutils-static/binutils-static.nm create mode 100644 pkgs/toolchain/binutils-static/patches/binutils-2.19.1-lazy-1.patch.off create mode 100644 pkgs/toolchain/binutils-static/patches/binutils-2.20-pt_pax-1.patch create mode 100644 pkgs/toolchain/binutils/binutils.nm create mode 100644 pkgs/toolchain/binutils/patches/binutils-2.19.1-lazy-1.patch.off create mode 100644 pkgs/toolchain/binutils/patches/binutils-2.20-pt_pax-1.patch create mode 100644 pkgs/toolchain/bzip2/bzip2.nm create mode 100644 pkgs/toolchain/coreutils/coreutils.nm create mode 100644 pkgs/toolchain/coreutils/patches/coreutils-7.6-uname_PIC-1.patch create mode 100644 pkgs/toolchain/coreutils/patches/coreutils-8.4-i18n.patch create mode 100644 pkgs/toolchain/cpio/cpio.nm create mode 100644 pkgs/toolchain/diffutils/diffutils.nm create mode 100644 pkgs/toolchain/diffutils/patches/diffutils-2.8.1-hardened_tmp-1.patch create mode 100644 pkgs/toolchain/diffutils/patches/diffutils-2.8.1-i18n-1.patch create mode 100644 pkgs/toolchain/expect/expect.nm create mode 100644 pkgs/toolchain/expect/patches/expect-5.32.2-random.patch create mode 100644 pkgs/toolchain/expect/patches/expect-5.38.0-lib-spec.patch create mode 100644 pkgs/toolchain/expect/patches/expect-5.39.0-libdir.patch create mode 100644 pkgs/toolchain/expect/patches/expect-5.43.0-spawn-1.patch create mode 100644 pkgs/toolchain/expect/patches/expect-5.43.0-tcl8.5.6.patch create mode 100644 pkgs/toolchain/expect/patches/expect-5.43.0-tcl8.5.patch create mode 100644 pkgs/toolchain/file/file.nm create mode 100644 pkgs/toolchain/findutils/findutils.nm create mode 100644 pkgs/toolchain/gawk/gawk.nm create mode 100644 pkgs/toolchain/gcc-static/gcc-static.nm create mode 100644 pkgs/toolchain/gcc/gcc.nm create mode 100644 pkgs/toolchain/gcc/include-append create mode 100644 pkgs/toolchain/gcc/patches/gcc-4.4-optimize_linking.patch create mode 100644 pkgs/toolchain/gcc/patches/gcc-4.4.1-branch-startfiles-1.patch create mode 100644 pkgs/toolchain/gcc/patches/gcc-4.4.1-espf-1.patch create mode 100644 pkgs/toolchain/gettext/gettext.nm create mode 100644 pkgs/toolchain/gettext/patches/gettext-0.17-automake-1.patch create mode 120000 pkgs/toolchain/glibc/glibc-stack_chk_fail.c create mode 100644 pkgs/toolchain/glibc/glibc.nm create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-arc4random.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-asprintf_reset2null-1.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-hardened-configure-picdefault.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-hardened-inittls-nosysenter.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-issetugid-1.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-localedef_trampoline-1.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-mktemp_urandom.patch.off create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-pt_pax-1.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-res_randomid.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-resolv_response_length.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-sanitize_env.patch.off create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-strlcpy_strlcat-1.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.10.1-undefine-__i686.patch create mode 100644 pkgs/toolchain/glibc/patches/glibc-2.11.1-hardened-pie.patch create mode 100644 pkgs/toolchain/grep/grep.nm create mode 100644 pkgs/toolchain/gzip/gzip.nm create mode 100644 pkgs/toolchain/gzip/patches/gzip-1.3.13-cve-2006-4337_len.patch create mode 100644 pkgs/toolchain/gzip/patches/gzip-1.3.13-cve-2006-4338.patch create mode 100644 pkgs/toolchain/gzip/patches/gzip-1.3.13-openbsd-owl-tmp.patch create mode 100644 pkgs/toolchain/kernel-headers/kernel-headers.nm create mode 100644 pkgs/toolchain/m4/m4.nm create mode 100644 pkgs/toolchain/make/make.nm create mode 100644 pkgs/toolchain/ncurses/ncurses.nm create mode 100644 pkgs/toolchain/patch/patch.nm create mode 100644 pkgs/toolchain/pax-utils/pax-utils.nm create mode 100644 pkgs/toolchain/perl/patches/perl-5.10.1-libc-1.patch create mode 100644 pkgs/toolchain/perl/patches/perl-5.10.1-utf8-1.patch create mode 100644 pkgs/toolchain/perl/perl.nm create mode 100644 pkgs/toolchain/sed/sed.nm create mode 100644 pkgs/toolchain/tar/patches/tar-1.22-vfatTruncate.patch create mode 100644 pkgs/toolchain/tar/patches/tar-1.22-xattrs-1.patch create mode 100644 pkgs/toolchain/tar/patches/tar-1.22-xattrs-conf-1.patch create mode 100644 pkgs/toolchain/tar/tar.nm create mode 100644 pkgs/toolchain/tcl/patches/tcl-8.5.8-autopath.patch create mode 100644 pkgs/toolchain/tcl/patches/tcl-8.5.8-conf.patch create mode 100644 pkgs/toolchain/tcl/patches/tcl-8.5.8-pic.patch create mode 100644 pkgs/toolchain/tcl/tcl.nm create mode 100644 pkgs/toolchain/texinfo/texinfo.nm create mode 100644 pkgs/toolchain/xz/xz.nm delete mode 100644 src/initscripts/extras/collectd.conf delete mode 100644 src/initscripts/extras/haldaemon.conf delete mode 100644 src/initscripts/extras/splashy.conf delete mode 100644 src/initscripts/extras/vsftpd.conf delete mode 100755 src/pakfire/compressor delete mode 100755 src/pakfire/compressor.d/01-qa-unsafe-files delete mode 100755 src/pakfire/compressor.d/02-qa-static-libs delete mode 100755 src/pakfire/compressor.d/03-qa-execstacks delete mode 100755 src/pakfire/compressor.d/04-qa-rpath delete mode 100755 src/pakfire/compressor.d/05-qa-textrels delete mode 100755 src/pakfire/compressor.d/06-qa-shared-soname delete mode 100755 src/pakfire/compressor.d/07-qa-shared-needed delete mode 100755 src/pakfire/compressor.d/50-python delete mode 100755 src/pakfire/compressor.d/99-strip-debug delete mode 100755 src/pakfire/compressor.d/99-strip-unneeded delete mode 100644 src/rootfiles/README delete mode 100644 src/rootfiles/core/acl delete mode 100644 src/rootfiles/core/aiccu delete mode 100644 src/rootfiles/core/atom/grub delete mode 120000 src/rootfiles/core/atom/linux delete mode 100644 src/rootfiles/core/attr delete mode 100644 src/rootfiles/core/autoconf delete mode 100644 src/rootfiles/core/automake delete mode 100644 src/rootfiles/core/avahi delete mode 100644 src/rootfiles/core/bash delete mode 100644 src/rootfiles/core/bc delete mode 100644 src/rootfiles/core/beep delete mode 100644 src/rootfiles/core/berkeley delete mode 100644 src/rootfiles/core/bind delete mode 100644 src/rootfiles/core/binutils delete mode 100644 src/rootfiles/core/bison delete mode 100644 src/rootfiles/core/boost delete mode 100644 src/rootfiles/core/br2684ctl delete mode 100644 src/rootfiles/core/bridge-utils delete mode 100644 src/rootfiles/core/btrfs-progs delete mode 100644 src/rootfiles/core/bzip2 delete mode 100644 src/rootfiles/core/cairo delete mode 100644 src/rootfiles/core/core2duo/grub delete mode 120000 src/rootfiles/core/core2duo/linux delete mode 100644 src/rootfiles/core/coreutils delete mode 100644 src/rootfiles/core/cpio delete mode 100644 src/rootfiles/core/cracklib delete mode 100644 src/rootfiles/core/cryptsetup-luks delete mode 100644 src/rootfiles/core/curl delete mode 100644 src/rootfiles/core/cyrus-sasl delete mode 100644 src/rootfiles/core/dbus delete mode 100644 src/rootfiles/core/dbus-glib delete mode 100644 src/rootfiles/core/dev.p0 delete mode 100644 src/rootfiles/core/dhcp delete mode 100644 src/rootfiles/core/diffutils delete mode 100644 src/rootfiles/core/directfb delete mode 100644 src/rootfiles/core/dmraid delete mode 100644 src/rootfiles/core/dosfstools delete mode 100644 src/rootfiles/core/dvdrtools delete mode 100644 src/rootfiles/core/e2fsprogs delete mode 100644 src/rootfiles/core/ebtables delete mode 100644 src/rootfiles/core/etherwake delete mode 100644 src/rootfiles/core/eventlog delete mode 100644 src/rootfiles/core/expat delete mode 100644 src/rootfiles/core/ez-ipupdate delete mode 100644 src/rootfiles/core/file delete mode 100644 src/rootfiles/core/findutils delete mode 100644 src/rootfiles/core/firewall delete mode 100644 src/rootfiles/core/flex delete mode 100644 src/rootfiles/core/fontconfig delete mode 100644 src/rootfiles/core/freetype delete mode 100644 src/rootfiles/core/fuse delete mode 100644 src/rootfiles/core/gawk delete mode 100644 src/rootfiles/core/gcc delete mode 100644 src/rootfiles/core/geodelx/grub delete mode 100644 src/rootfiles/core/gettext delete mode 100644 src/rootfiles/core/glib2 delete mode 100644 src/rootfiles/core/glibc delete mode 100644 src/rootfiles/core/gmp delete mode 100644 src/rootfiles/core/gnupg2 delete mode 100644 src/rootfiles/core/gnutls delete mode 100644 src/rootfiles/core/gobject-introspection delete mode 100644 src/rootfiles/core/gperf delete mode 100644 src/rootfiles/core/grep delete mode 100644 src/rootfiles/core/groff delete mode 100644 src/rootfiles/core/grub delete mode 100644 src/rootfiles/core/gzip delete mode 100644 src/rootfiles/core/hal delete mode 100644 src/rootfiles/core/hal-info delete mode 100644 src/rootfiles/core/hdparm delete mode 100644 src/rootfiles/core/hostapd delete mode 120000 src/rootfiles/core/i586/linux delete mode 100644 src/rootfiles/core/i686/linux delete mode 100644 src/rootfiles/core/iana-etc delete mode 100644 src/rootfiles/core/initscripts delete mode 100644 src/rootfiles/core/intltool delete mode 100644 src/rootfiles/core/iproute2 delete mode 100644 src/rootfiles/core/iptables delete mode 100644 src/rootfiles/core/iputils delete mode 100644 src/rootfiles/core/iw delete mode 100644 src/rootfiles/core/jwhois delete mode 100644 src/rootfiles/core/kbd delete mode 100644 src/rootfiles/core/l7-protocols delete mode 100644 src/rootfiles/core/ldapvi delete mode 100644 src/rootfiles/core/less delete mode 100644 src/rootfiles/core/libaal delete mode 100644 src/rootfiles/core/libart delete mode 100644 src/rootfiles/core/libassuan delete mode 100644 src/rootfiles/core/libbdevid delete mode 100644 src/rootfiles/core/libcap2 delete mode 100644 src/rootfiles/core/libdaemon delete mode 100644 src/rootfiles/core/libdnet delete mode 100644 src/rootfiles/core/libevent delete mode 100644 src/rootfiles/core/libgcrypt delete mode 100644 src/rootfiles/core/libgpg-error delete mode 100644 src/rootfiles/core/libgssglue delete mode 100644 src/rootfiles/core/libidn delete mode 100644 src/rootfiles/core/libjpeg delete mode 100644 src/rootfiles/core/libksba delete mode 100644 src/rootfiles/core/libnetfilter_conntrack delete mode 100644 src/rootfiles/core/libnetfilter_log delete mode 100644 src/rootfiles/core/libnetfilter_queue delete mode 100644 src/rootfiles/core/libnfnetlink delete mode 100644 src/rootfiles/core/libnfsidmap delete mode 100644 src/rootfiles/core/libnl delete mode 100644 src/rootfiles/core/libpcap delete mode 100644 src/rootfiles/core/libpng delete mode 100644 src/rootfiles/core/librpcsecgss delete mode 100644 src/rootfiles/core/libssh2 delete mode 100644 src/rootfiles/core/libtiff delete mode 100644 src/rootfiles/core/libtool delete mode 100644 src/rootfiles/core/libusb delete mode 100644 src/rootfiles/core/libusb-compat delete mode 100644 src/rootfiles/core/libuser delete mode 100644 src/rootfiles/core/libxml2 delete mode 100644 src/rootfiles/core/libxslt delete mode 100644 src/rootfiles/core/lighttpd delete mode 100644 src/rootfiles/core/linux delete mode 100644 src/rootfiles/core/linux-atm delete mode 100644 src/rootfiles/core/linux-headers delete mode 100644 src/rootfiles/core/lm-sensors delete mode 100644 src/rootfiles/core/logrotate delete mode 100644 src/rootfiles/core/lsof delete mode 100644 src/rootfiles/core/lua delete mode 100644 src/rootfiles/core/lvm2 delete mode 100644 src/rootfiles/core/lzo delete mode 100644 src/rootfiles/core/m4 delete mode 100644 src/rootfiles/core/make delete mode 100644 src/rootfiles/core/man-db delete mode 100644 src/rootfiles/core/man-pages delete mode 100644 src/rootfiles/core/mdadm delete mode 100644 src/rootfiles/core/memtest86+ delete mode 100644 src/rootfiles/core/mkinitramfs delete mode 100644 src/rootfiles/core/module-init-tools delete mode 100644 src/rootfiles/core/mpfr delete mode 100644 src/rootfiles/core/nasm delete mode 100644 src/rootfiles/core/ncurses delete mode 100644 src/rootfiles/core/network delete mode 100644 src/rootfiles/core/newt delete mode 100644 src/rootfiles/core/nfs-utils delete mode 100644 src/rootfiles/core/noip delete mode 100644 src/rootfiles/core/nss_ldap delete mode 100644 src/rootfiles/core/ntp delete mode 100644 src/rootfiles/core/openldap delete mode 100644 src/rootfiles/core/openlldp delete mode 100644 src/rootfiles/core/openssh delete mode 100644 src/rootfiles/core/openssl delete mode 100644 src/rootfiles/core/openvpn delete mode 100644 src/rootfiles/core/pakfire delete mode 100644 src/rootfiles/core/pam delete mode 100644 src/rootfiles/core/pam_ldap delete mode 100644 src/rootfiles/core/pango delete mode 100644 src/rootfiles/core/parted delete mode 100644 src/rootfiles/core/passwd delete mode 100644 src/rootfiles/core/patch delete mode 100644 src/rootfiles/core/pax-utils delete mode 100644 src/rootfiles/core/paxctl delete mode 100644 src/rootfiles/core/pciutils delete mode 100644 src/rootfiles/core/pcre delete mode 100644 src/rootfiles/core/pdns delete mode 100644 src/rootfiles/core/pdns-recursor delete mode 100644 src/rootfiles/core/perl delete mode 100644 src/rootfiles/core/perl-xml-parser delete mode 100644 src/rootfiles/core/pinentry delete mode 100644 src/rootfiles/core/pixman delete mode 100644 src/rootfiles/core/pkg-config delete mode 100644 src/rootfiles/core/popt delete mode 100644 src/rootfiles/core/portmap delete mode 100644 src/rootfiles/core/ppp delete mode 100644 src/rootfiles/core/pptp delete mode 100644 src/rootfiles/core/procps delete mode 100644 src/rootfiles/core/psmisc delete mode 100644 src/rootfiles/core/pth delete mode 100644 src/rootfiles/core/pyfire delete mode 100644 src/rootfiles/core/python delete mode 100644 src/rootfiles/core/python-IPy delete mode 100644 src/rootfiles/core/python-cracklib delete mode 100644 src/rootfiles/core/python-cryptsetup delete mode 100644 src/rootfiles/core/python-dbus delete mode 100644 src/rootfiles/core/python-flup delete mode 100644 src/rootfiles/core/python-netfilter_conntrack delete mode 100644 src/rootfiles/core/python-parted delete mode 100644 src/rootfiles/core/python-pyblock delete mode 100644 src/rootfiles/core/python-setuptools delete mode 100644 src/rootfiles/core/python-sqlite2 delete mode 100644 src/rootfiles/core/python-tornado delete mode 100644 src/rootfiles/core/python-urlgrabber delete mode 100644 src/rootfiles/core/python-werkzeug delete mode 100644 src/rootfiles/core/radvd delete mode 100644 src/rootfiles/core/readline delete mode 100644 src/rootfiles/core/reiser4progs delete mode 100644 src/rootfiles/core/reiserfsprogs delete mode 100644 src/rootfiles/core/rrdtool delete mode 100644 src/rootfiles/core/rstp delete mode 100644 src/rootfiles/core/screen delete mode 100644 src/rootfiles/core/scripts delete mode 100644 src/rootfiles/core/sed delete mode 100644 src/rootfiles/core/setuptools delete mode 100644 src/rootfiles/core/shadow delete mode 100644 src/rootfiles/core/slang delete mode 100644 src/rootfiles/core/smartmontools delete mode 100644 src/rootfiles/core/splashy delete mode 100644 src/rootfiles/core/sqlite delete mode 100644 src/rootfiles/core/squashfs-tools delete mode 100644 src/rootfiles/core/stage2 delete mode 100644 src/rootfiles/core/stage3 delete mode 100644 src/rootfiles/core/strongswan delete mode 100644 src/rootfiles/core/sudo delete mode 100644 src/rootfiles/core/sysfsutils delete mode 100644 src/rootfiles/core/syslinux delete mode 100644 src/rootfiles/core/syslog-ng delete mode 100644 src/rootfiles/core/system-release delete mode 100644 src/rootfiles/core/sysvinit delete mode 100644 src/rootfiles/core/tar delete mode 100644 src/rootfiles/core/texinfo delete mode 100644 src/rootfiles/core/udev delete mode 100644 src/rootfiles/core/ulogd2 delete mode 100644 src/rootfiles/core/unzip delete mode 100644 src/rootfiles/core/upstart delete mode 100644 src/rootfiles/core/usbutils delete mode 100644 src/rootfiles/core/util-linux-ng delete mode 120000 src/rootfiles/core/via-c3/grub delete mode 100644 src/rootfiles/core/via-c7/grub delete mode 120000 src/rootfiles/core/via-c7/linux delete mode 100644 src/rootfiles/core/vim delete mode 100644 src/rootfiles/core/vlan delete mode 100644 src/rootfiles/core/webinterface delete mode 100644 src/rootfiles/core/werkzeug delete mode 100644 src/rootfiles/core/which delete mode 100644 src/rootfiles/core/wireless-tools delete mode 100644 src/rootfiles/core/xfsprogs delete mode 100644 src/rootfiles/core/xz delete mode 100644 src/rootfiles/core/zlib delete mode 100644 src/rootfiles/debug/gdb delete mode 100644 src/rootfiles/debug/pax-utils delete mode 100644 src/rootfiles/debug/paxtest delete mode 100644 src/rootfiles/debug/pychecker delete mode 100644 src/rootfiles/debug/strace delete mode 100644 src/rootfiles/extras/bwm-ng delete mode 100644 src/rootfiles/extras/cups delete mode 100644 src/rootfiles/extras/freeradius delete mode 100644 src/rootfiles/extras/ghostscript delete mode 100644 src/rootfiles/extras/gssdp delete mode 100644 src/rootfiles/extras/gupnp delete mode 100644 src/rootfiles/extras/gupnp-av delete mode 100644 src/rootfiles/extras/gupnp-igd delete mode 100644 src/rootfiles/extras/hplip delete mode 100644 src/rootfiles/extras/htop delete mode 100644 src/rootfiles/extras/joe delete mode 100644 src/rootfiles/extras/libvirt delete mode 100644 src/rootfiles/extras/mc delete mode 100644 src/rootfiles/extras/nano delete mode 100644 src/rootfiles/extras/net-snmp delete mode 100644 src/rootfiles/extras/nmap delete mode 100644 src/rootfiles/extras/qemu delete mode 100644 src/rootfiles/extras/qemu-kvm-devel delete mode 100644 src/rootfiles/extras/quagga delete mode 100644 src/rootfiles/extras/samba delete mode 100644 src/rootfiles/extras/sane delete mode 100644 src/rootfiles/extras/squid delete mode 100644 src/rootfiles/extras/tcpdump delete mode 100644 src/rootfiles/extras/traceroute delete mode 100644 src/rootfiles/extras/vsftpd delete mode 100644 src/rootfiles/extras/xen delete mode 100755 src/scripts/parallelismflags delete mode 100644 src/scripts/py-compile delete mode 100644 src/scripts/setddns.pl delete mode 100644 src/web/cgi-bin/template.py delete mode 100644 src/web/images/icons/computer.png delete mode 100644 src/web/images/icons/ipfire.png delete mode 100644 src/web/images/icons/keyboard.png delete mode 100644 src/web/images/icons/network.png delete mode 100644 src/web/images/icons/printer.png delete mode 100644 src/web/images/icons/wireless.png delete mode 100644 src/web/images/n1.gif delete mode 100644 src/web/images/n2.gif delete mode 100644 src/web/images/n3.gif delete mode 100644 src/web/images/n4.gif delete mode 100644 src/web/images/n5.gif delete mode 100644 src/web/images/n6.gif delete mode 100644 src/web/images/spacer.gif delete mode 100644 src/web/style.css create mode 100644 tools/common-constants create mode 100644 tools/common-include create mode 100644 tools/common-package-functions create mode 100644 tools/common-ui-functions create mode 100755 tools/compressor rename {src/pakfire => tools}/decompressor (95%) mode change 100644 => 100755 tools/downloader rename {src/scripts => tools}/extractor (100%) mode change 100644 => 100755 create mode 100755 tools/naoki create mode 100644 tools/naoki-constants create mode 100644 tools/naoki-functions create mode 100644 tools/naoki-include create mode 100755 tools/patch create mode 100755 tools/py-compile create mode 100755 tools/quality-agent create mode 100755 tools/quality-agent.d/001-include-files create mode 100755 tools/quality-agent.d/001-remove-info-files create mode 100755 tools/quality-agent.d/001-remove-static-libs create mode 100755 tools/quality-agent.d/001-unsafe-files create mode 100755 tools/quality-agent.d/002-bad-symlinks create mode 100755 tools/quality-agent.d/003-libs-location create mode 100755 tools/quality-agent.d/050-execstacks create mode 100755 tools/quality-agent.d/050-libs-needed create mode 100644 tools/quality-agent.d/050-libs-soname create mode 100755 tools/quality-agent.d/050-root-links-to-usr create mode 100755 tools/quality-agent.d/050-rpaths create mode 100755 tools/quality-agent.d/050-textrels create mode 100755 tools/quality-agent.d/090-python-hardlinks create mode 100755 tools/quality-agent.d/090-remove-empty-dirs create mode 100755 tools/quality-agent.d/095-directory-layout create mode 100755 tools/quality-agent.d/099-strip create mode 100644 tools/quality-agent.d/qa-include create mode 100755 tools/toolchain
Difference in files: diff --git a/.config-default b/.config-default deleted file mode 100644 index c98238c..0000000 --- a/.config-default +++ /dev/null @@ -1,139 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### -# This is a sample config. Copy this file to .config and adjust the values # -# below to your own needs. # -############################################################################### - -############################################################################### -# User authentication # -############################################################################### -# This is the name of the login on the master system. If you are not a ipfire # -# developer, you can request an account by the team. You will need this to # -# push to git, upload source and down-/upload toolchains. # -############################################################################### - -#IPFIRE_USER= - -############################################################################### -# UUID # -############################################################################### -# This ID is for uniquely identify a build host. # -############################################################################### - -#UUID=@UUID@ - -############################################################################### -# Target Architecture # -############################################################################### -# TARGET is one out of i686|i586|i486|atom330|core2duo|via-c7|via-c3|geodelx. # -# This is the target architecture you specify for the system that is built. # -# Default is i686. # -# ALLOWED_TARGETS is a setting for cron builds only. By default it includes # -# all targets the host can build (./make.sh check targets). # -# So, if you want to build only some of them, define them in ALLOWED_TARGETS. # -############################################################################### - -#TARGET=i686 -#ALLOWED_TARGETS="i686 i586 atom330" # Just an example - -############################################################################### -# Embedded Build # -############################################################################### -# Set this to "1" to make a build for embedded systems. # -# This will use some other configurations, leave out the installer and # -# generate images for flash cards. # -# Default is 0 (=off). # -############################################################################### - -#EMB=0 - -############################################################################### -# Addons + Debugging tools # -############################################################################### -# These switches let the user say if the build should do the addons or not. # -# One can also set if the system should build the debugging tools. # -# Purpose is to save build time. # -# BUILD_EXTRAS is enabled by default. To disable set it to zero. # -# BUILD_DEBUG is disabled by default. To enable set it to one. # -############################################################################### - -#BUILD_EXTRAS=1 -#BUILD_DEBUG=0 - -############################################################################### -# Niceness # -############################################################################### -# NICE is the value that indicates the priority to the process it runs with. # -# The higher the niceness the less is the priority of the whole task. # -# Default is 10. # -############################################################################### - -#NICE=10 - -############################################################################### -# Parallelism # -############################################################################### -# If you have got more than one processor you can advice make to run more # -# than one job a time. You also may want to adjust this when using distcc. # -# Default is count of cpus twice + 1. (-jN) # -# Possible options: # -# -j [N] : N is the number of the parallel jobs. # -# -l N : Specify the max. load avg. for the system. # -# Read more: http://www.gnu.org/software/automake/manual/make/Parallel.html # -############################################################################### - -#PARALLELISMFLAGS=-j3 - -############################################################################### -# Icecream Config # -############################################################################### -# ICECC_PORT: Allows the definition of an other port than the default one. # -# If you change this, you need to restart the local icecream daemon. # -# Default is tcp/10245. "0" disables the start of the icecream daemon. # -# # -# ICECC_SCHEDULER: The hostname of the central server, called scheduler. # -############################################################################### - -#ICECC_PORT=10245 -#ICECC_JOBS=4 -#ICECC_SCHEDULER="minerva.ipfire.org" -#ICECC_PREFERRED_HOST="..." - -############################################################################### -# Ccache Config # -############################################################################### -# You may disable the ccache. Set CCACHE=off to do this. # -# THIS IS NOT RECOMMENDED AND ONLY FOR TESTING PURPOSES. # -############################################################################### - -#CCACHE=on - -############################################################################### -# Mail # -############################################################################### -# When the batch build has finished it will send an email. # -# Here are some self-explaining options. # -############################################################################### - -#MAIL_SERVER= -#MAIL_USER= -#MAIL_PASS= -#MAIL_FROM="build@ipfire.org" -#MAIL_TO="developers@ipfire.org" diff --git a/.gitignore b/.gitignore index 18cdbb7..ac3bb8e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,15 @@ /.build_spy* /.config -/.failed -/.running -/build_* +/build /cache /ccache -/distcc /doc/ChangeLog /doc/packages-list.txt -/log_* -/packages_* +/logs /tmp /vm /*.diff /*.iso /*.tar.gz +*.py[co] *~ diff --git a/config/architectures.conf b/config/architectures.conf new file mode 100644 index 0000000..0cf691f --- /dev/null +++ b/config/architectures.conf @@ -0,0 +1,44 @@ + +[i686] + +machine = i686 +personality = linux32 + +cflags = -O2 -fomit-frame-pointer -pipe + + +[i586] + +machine = i586 +personality = linux32 + +cflags = -O2 -fomit-frame-pointer -pipe + + +[i486] + +machine = i486 +personality = linux32 + +cflags = -O2 -fomit-frame-pointer -pipe + + +[alix] + +; While i586 works fine on a Geode LX, i486 should be a more performant choice +; right now due to the way Geode LX CPU pipeline ans scheduling works. glibc +; i586 assembler optimized routines are measureably slower than the i486 ones on +; a Geode LX. +machine = i486 +personality = linux32 + +cflags = -Os -march=geode -fno-align-jumps -fno-align-functions -fno-align-labels -fno-align-loops -fomit-frame-pointer -pipe +cxxflags = %(cflags)s + + +[x86_64] + +machine = x86_64 +personality = linux64 + +cflags = -O2 -fomit-frame-pointer -pipe diff --git a/config/logging.ini b/config/logging.ini new file mode 100644 index 0000000..20c2e38 --- /dev/null +++ b/config/logging.ini @@ -0,0 +1,83 @@ +[formatters] +keys: detailed,simple,unadorned,state + +[handlers] +keys: simple_console,detailed_console,unadorned_console,simple_console_warnings_only + +[loggers] +keys: root,build,state,naoki + +[formatter_state] +format: %(asctime)s - %(message)s + +[formatter_unadorned] +format: %(message)s + +[formatter_simple] +format: %(levelname)s: %(message)s + +;useful for debugging: +[formatter_detailed] +format: %(levelname)s %(filename)s:%(lineno)d: %(message)s + +[handler_unadorned_console] +class: StreamHandler +args: [] +formatter: unadorned +level: INFO + +[handler_simple_console] +class: StreamHandler +args: [] +formatter: simple +level: INFO + +[handler_simple_console_warnings_only] +class: StreamHandler +args: [] +formatter: simple +level: WARNING + +[handler_detailed_console] +class: StreamHandler +args: [] +formatter: detailed +level: WARNING + +; usually dont want to set a level for loggers +; this way all handlers get all messages, and messages can be filtered +; at the handler level +; +; all these loggers default to a console output handler +; +[logger_root] +level: NOTSET +handlers: simple_console + +; naoki logger normally has no output +; catches stuff like naoki.trace_decorator and naoki.util +; dont normally want to propagate to root logger, either +[logger_naoki] +level: NOTSET +handlers: +qualname: naoki +propagate: 1 + +[logger_state] +level: NOTSET +; unadorned_console only outputs INFO or above +handlers: unadorned_console +qualname: naoki.Root.state +propagate: 0 + +[logger_build] +level: NOTSET +handlers: simple_console_warnings_only +qualname: naoki.Root.build +propagate: 0 + +; the following is a list naoki logger qualnames used within the code: +; +; qualname: naoki.util +; qualname: naoki.uid +; qualname: naoki.trace_decorator diff --git a/config/naoki.conf b/config/naoki.conf new file mode 100644 index 0000000..f39182f --- /dev/null +++ b/config/naoki.conf @@ -0,0 +1,27 @@ + +[architecture] + +config = config/architectures.conf + +arch = i686 + +[distro] + +; Name of the distribution we build. +name = IPFire +sname = ipfire + +; Major version number +epoch = 3 + +; Minor version string +version = %(epoch)s.0-prealpha2 + +; A descriptive slogan +slogan = "Gluttony" + + +[toolchain] + +; Counter of toolchain version +version = 0 diff --git a/lfs/Config b/lfs/Config deleted file mode 100644 index 5f578d3..0000000 --- a/lfs/Config +++ /dev/null @@ -1,262 +0,0 @@ -############################################################################### -# LFSMake # -# by Rod Roark rod@sunsetsystems.com # -# # -# Copyright (C) 2002 Rod Roark # -# # -# See http://www.lfsmake.org/ for the most current standard version. # -# # -# These Makefiles are made available under the terms of the Artistic License, # -# found at http://www.opensource.org/licenses/artistic-license.html. # -############################################################################### - -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -# URLs that are common sources of downloads. If you're having trouble with -# a site you should change its URL to that of a suitable mirror site. -# -URL_IPFIRE = http://source.ipfire.org/download -URL_TOOLCHAIN = source.ipfire.org:/pub/source/toolchains -URL_SOURCE = source.ipfire.org:/pub/source/source-3.x -URL_TARGET = source.ipfire.org:/srv/anonftp/pub/nightly-builds - -# For most packages tarballs are unpacked here and then deleted after -# installation. -# -DIR_SRC = $(LFS)/usr/src - -# Files are downloaded into DIR_TMP and then moved to DIR_DL, to avoid -# messes with partially retrieved files. DIR_DL is where we will -# save all the files that are downloaded. DIR_INFO contains the -# file lists of installed packages. -# -DIR_DL = $(LFS_BASEDIR)/cache/tarballs -DIR_CONF = $(LFS_BASEDIR)/config -DIR_INFO = $(LFS_BASEDIR)/log_$(TARGET) -DIR_LFS = $(LFS_BASEDIR)/lfs -DIR_TOOLS = $(LFS_BASEDIR)/tools -DIR_TMP = /tmp -DIR_PATCHES = $(DIR_DL)/../patches -DIR_CONFIG = $(DIR_CONF) -DIR_SOURCE = $(DIR_SRC)/src -DIR_PKG = $(LFS_BASEDIR)/lfs -DIR_TARGET = $(LFS_BASEDIR)/target -DIR_PACKAGES= /packages - -VPATH = $(DIR_DL):$(DIR_PATCHES) - -INITSCRIPT = $(PKG_NAME) - -CONFIGURE_ARCH = \ - --build=$(IFS_TARGET) \ - --host=$(IFS_TARGET) - -DEFAULT_PACKAGE = $(DIR_PACKAGES)/$(LFS_FILE)-$(PKG_VER)-$(SNAME)$(PKG_REL).$(TARGET).ipk -DEVEL_PACKAGE = $(DIR_PACKAGES)/$(LFS_FILE)-devel-$(PKG_VER)-$(SNAME)$(PKG_REL).$(TARGET).ipk -#ifeq "$(shell grep ^D $(DO_FIND_ROOTFILE))" "" -# PACKAGES = $(DEFAULT_PACKAGE) -#else -# PACKAGES = $(DEFAULT_PACKAGE) $(DEVEL_PACKAGE) -#endif -PACKAGES = $(DEFAULT_PACKAGE) - -IMAGE_FILE = $(IMAGES_DIR)/$(SNAME)-$(VERSION).sfs - -LFS_FILE = $(firstword $(MAKEFILE_LIST)) - -############################################################################### -# Common Macro Definitions -############################################################################### - -DO_LOAD = DIR_TMP=$(DIR_TMP) DIR_DL=$(DIR_DL) DIR_PATCHES=$(DIR_PATCHES) \ - python $(DIR_TOOLS)/downloader $(URL_IPFIRE)/$@ -LOAD = $(DO_LOAD) # To be compatible to the current build system. - -EXTRACTOR = bash $(DIR_SOURCE)/scripts/extractor - -INSTALL_CONFIG = sed \ - -e "s/@NAME@/$(NAME)/g" \ - -e "s/@SNAME@/$(SNAME)/g" \ - -e "s/@VERSION@/$(VERSION)/g" \ - -e "s/@SLOGAN@/$(SLOGAN)/g" \ - -e "s/@DATE@/$(shell date '+%Y%m%d')/g" \ - -e "s/@IMAGENAME@/$(IMAGENAME)/g" - -INSTALL_INITSCRIPT = echo "Installing initscript "$(INITSCRIPT)" -> /etc/init"; \ - install -m 644 $(DIR_SOURCE)/initscripts/extras/$(INITSCRIPT).conf /etc/init/ - -PYTHON_COMPILE = find /usr/lib/python*/ -name *.py | xargs /usr/bin/py-compile -PYTHON_EXTRACT_EGG = $(DIR_SOURCE)/scripts/py-extract-egg - -DO_FIND_ROOTFILE = $$(find $(DIR_SOURCE)/rootfiles/{core,extras,debug}/{$(TARGET),} -type f \ - -maxdepth 1 -name "$(LFS_FILE)" 2>/dev/null | head -n1) - -define DO_PKG_INFO - @## ALPHABETICAL ORDER ## - @echo "local PKG_BUILD_DEPS="$(BUILD_DEPS)"" - @echo "local PKG_CORE="$(CORE)"" - @echo "local PKG_DEBUG="$(DEBUG)"" - @echo "local PKG_DEPS="$(DEPS)"" - @echo "local PKG_DESC="$(value LONG_DESC)"" - @echo "local PKG_EXTRA="$(EXTRA)"" - @echo "local PKG_FILES="$(objects)"" - @echo "local PKG_GROUP="$(GROUP)"" - @echo "local PKG_LICENSE="$(LICENSE)"" - @echo "local PKG_MAINTAINER="$(MAINTAINER)"" - @echo "local PKG_NAME="$$(basename $(LFS_FILE))"" - @echo "local PKG_PACKAGES="$(PACKAGES)"" - @echo "local PKG_VER="$(PKG_VER)"" - @echo "local PKG_REL="$(PKG_REL)"" - @echo "local PKG_SHORT="$(value SHORT_DESC)"" - @echo "local PKG_URL="$(URL)"" -endef - -define DO_PACKAGE - if [ "$(CORE)" = "yes" -o "$(EXTRA)" = "yes" ]; then \ - if [ -z "$(DO_FIND_ROOTFILE)" ]; then \ - touch $@_no_rootfile; \ - exit 0; \ - fi; \ - NAME=$(NAME) \ - SNAME=$(SNAME) \ - VERSION=$(VERSION) \ - KVER=$(KVER) \ - TARGET=$(TARGET) \ - MACHINE=$(MACHINE) \ - IFS_TARGET=$(IFS_TARGET) \ - \ - PKG_BUILD_DEPS="$(BUILD_DEPS)" \ - PKG_CORE="$(CORE)" \ - PKG_DEBUG="$(DEBUG)" \ - PKG_DEPS="$(DEPS)" \ - PKG_EXTRA="$(EXTRA)" \ - PKG_GROUP="$(GROUP)" \ - PKG_LICENSE="$(LICENSE)" \ - PKG_MAINTAINER="$(MAINTAINER)" \ - PKG_NAME="$(LFS_FILE)" \ - PKG_VER="$(PKG_VER)" \ - PKG_REL="$(PKG_REL)" \ - PKG_SHORT="$(value SHORT_DESC)" \ - PKG_URL="$(URL)" \ - \ - CONTROL_PREIN="$(value CONTROL_PREIN)" \ - CONTROL_PREUN="$(value CONTROL_POSTUN)" \ - CONTROL_POSTIN="$(value CONTROL_POSTIN)" \ - CONTROL_POSTUN="$(value CONTROL_POSTUN)" \ - \ - QUALITY_AGENT_WHITELIST_EXECSTACK="$(value QUALITY_AGENT_WHITELIST_EXECSTACK)" \ - QUALITY_AGENT_WHITELIST_RPATH="$(value QUALITY_AGENT_WHITELIST_RPATH)" \ - QUALITY_AGENT_WHITELIST_SONAME="$(value QUALITY_AGENT_WHITELIST_SONAME)" \ - \ - $(DIR_SOURCE)/pakfire/compressor --rootfile=$(DO_FIND_ROOTFILE) $@; \ - fi -endef - -# For each package we create a list of files that it installed under -# log/<OBJECT> name. Modified files are not identified -# -define FIND_FILES - cd $(LFS)/ && $(TOOLS_DIR)/bin/find -mount \ - -not -path '.$(TOOLS_DIR)*' -not -path './tmp*' -not -path './usr/src*' \ - -not -path './dev*' -not -path './proc*' -not -path './sys*' \ - -not -path '.$(INSTALLER_DIR)*' -not -path './packages*' -endef - -# This is common starting logic for builds. -# -ifneq "$(STAGE)" "toolchain" -define PREBUILD - echo "### STARTING INSTALL #################################################" - echo "# Application: $(THISAPP)" - echo "# Description: $(SHORT_DESC)" - echo "######################################################################" - echo "# Saving file list..." - # Remove package if exists - for package in $(PACKAGES); do \ - rm -f $(DIR_PACKAGES)/$$package 2>/dev/null; \ - done - if [ ! -f $(DIR_SRC)/lsalr ]; then $(FIND_FILES) > $(DIR_SRC)/lsalr; fi -endef -else -define PREBUILD - echo "### STARTING INSTALL #################################################" - echo "# Application: $(THISAPP)" - echo "# Description: $(SHORT_DESC)" - echo "######################################################################" -endef -endif - -# Common end-of-installation logic for Stage 2 and beyond. -# -ifneq "$(STAGE)" "toolchain" -define POSTBUILD - echo "### INSTALL DONE #####################################################" - echo "# Application: $(THISAPP)" - echo "# Saving file list to $(OBJECT)..." - @$(FIND_FILES) > $(DIR_SRC)/lsalrnew - @diff $(DIR_SRC)/lsalr $(DIR_SRC)/lsalrnew | grep '^> ' | sed 's+^> ./++' | sort > $(OBJECT)_diff - @mv -f $(DIR_SRC)/lsalrnew $(DIR_SRC)/lsalr - # compare roofile (same name as lfs script) with the list of installed files - # special cases - # - if the corresponding rootfile is not found, touch $(OBJECT)_missing_rootfile - # - on a partial rebuild without a new file inside TARGET_diff, just touch TARGET - # $(OBJECT)_diff : result of the diff - # ROOTFILE : reference of include/exclude files - # $(OBJECT)_rootfile : ROOTFILE with KVER replacement - # $(OBJECT) : log result with {commented|include|added} files - if [ -s "$(OBJECT)_diff" ]; then \ - LFS_SCRIPT="$(firstword $(MAKEFILE_LIST))"; \ - if [ "x$(PASS)" != "x" ]; then LFS_SCRIPT="$$LFS_SCRIPT.p$(PASS)"; fi; \ - ROOTFILE=$$(find $(DIR_SOURCE)/rootfiles/{core,extras,debug}/{$(TARGET),} -maxdepth 1 -type f -name $$LFS_SCRIPT 2>/dev/null | head -1); \ - if [ "$$ROOTFILE" = "" ]; then \ - touch $(OBJECT)_missing_rootfile; \ - ROOTFILE=$(OBJECT)_missing_rootfile ; \ - echo "error $$LFS_SCRIPT not found in $(DIR_SOURCE)/rootfiles"; \ - fi; \ - sed -e "s@KVER@$(KVER)@g" \ - -e "s@IFS_TARGET@$(IFS_TARGET)@g" \ - -e "s@^/@@g" -e "s@^#/@#@g" \ - $$ROOTFILE > $(OBJECT)_rootfile; \ - echo 'open (F,"$(OBJECT)_rootfile"); \ - while (<F>) { $$allfile{$$_} = "x" };close (F); \ - while (<>) { \ - if ( defined ($$allfile{"#$$_"}) ) {print "#$$_"} \ - elsif ( defined ($$allfile{$$_}) ) {print $$_} \ - else {print "+$$_"} \ - }; \ - ' > /tmp/perl.pl; \ - perl /tmp/perl.pl < $(OBJECT)_diff \ - | sed -e "s@$(KVER)@KVER@g" -e "s@$(IFS_TARGET)@IFS_TARGET@g" > $(OBJECT); \ - rm -f $(OBJECT)_rootfile; \ - else \ - touch $(OBJECT); \ - fi - @rm -f $(OBJECT)_diff - echo "######################################################################" -endef -else -define POSTBUILD - echo "### INSTALL DONE #####################################################" - echo "# Application: $(THISAPP)" - echo "######################################################################" - touch $(OBJECT) -endef -endif diff --git a/lfs/acl b/lfs/acl deleted file mode 100644 index 8ac1c58..0000000 --- a/lfs/acl +++ /dev/null @@ -1,138 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = acl -PKG_VER = 2.2.47 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = attr - -URL = http://oss.sgi.com/projects/xfs/ -LICENSE = GPLv2+ -SHORT_DESC = Access control list utilities. - -define LONG_DESC - This package contains the getfacl and setfacl utilities needed for \ - manipulating access control lists. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-build-1.patch \ - $(THISAPP)-nfs4.patch \ - $(THISAPP)-params.patch \ - $(THISAPP)-path_max.patch \ - $(THISAPP)-segfault.patch \ - $(THISAPP)-walk.patch \ - $(THISAPP)-exitcode.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-build-1.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-exitcode.patch - -ifneq "$(STAGE)" "toolchain" - # This patch adds NFS4 Support - #cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-nfs4.patch -endif - - # This patch adds new short parameters - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-params.patch - - # This patch fixes the usage of long UTF-8 filenames - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-path_max.patch - - # This patch fixes the segfault when using only "--" as parameter - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-segfault.patch - - # This patch makes the order consistent - #cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-walk.patch - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make LIBTOOL="libtool --tag=CC" #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install install-dev install-lib -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/bin \ - --disable-static - cd $(DIR_APP) && make LIBTOOL="libtool --tag=CC" #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - install -v -m0755 $(DIR_APP)/libacl/.libs/libacl.so.1.1.0 /lib - ln -vsf libacl.so.1.1.0 /lib/libacl.so.1 - ln -vsf ../../lib/libacl.so.1 /usr/lib/libacl.so - -mkdir -pv /usr/include/{acl,sys} - cp -vf $(DIR_APP)/include/libacl.h /usr/include/acl/ - cp -vf $(DIR_APP)/include/acl.h /usr/include/sys/ -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/adjust-toolchain b/lfs/adjust-toolchain deleted file mode 100644 index d4ff5a4..0000000 --- a/lfs/adjust-toolchain +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = adjust-toolchain -PKG_VER = -PKG_REL = -1 - -THISAPP = $(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = This script does some tweaks on the build system. - -define LONG_DESC - This script does some tweaks on the build system. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - -ifeq "$(STAGE)" "toolchain" - $(IFS_TARGET)-gcc -dumpspecs | sed \ - -e 's@$(LINKER)@$(TOOLS_DIR)&@g' \ - > $$(dirname $$($(IFS_TARGET)-gcc -print-libgcc-file-name))/specs -endif - -ifeq "$(STAGE)" "base" - cp -fv $(TOOLS_DIR)/bin/{ld-new,ld} - - gcc -dumpspecs | sed \ - -e "/^*link:$$/{n;s,$$, -L/usr/lib,}" \ - -e 's@$(TOOLS_DIR)$(LINKER)@$(LINKER)@g' \ - -e '/^*cpp:$$/{n;s,$$, -isystem /usr/include,}' \ - > $$(dirname $$(gcc --print-libgcc-file-name))/myspecs -endif - - @$(POSTBUILD) diff --git a/lfs/aiccu b/lfs/aiccu deleted file mode 100644 index 2697fae..0000000 --- a/lfs/aiccu +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = aiccu -PKG_VER = 20070115 -PKG_REL = 0 - -THISAPP = $(PKG_NAME) -DL_FILE = $(THISAPP)-$(PKG_VER).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Daemons -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = gnutls - -URL = http://www.sixxs.net/tools/aiccu/ -LICENSE = BSD -SHORT_DESC = Automatic IPv6 Connectivity Client Utility for SixXS tunnels. - -define LONG_DESC - This client automatically gives one IPv6 connectivity without having \ - to manually configure interfaces etc. One does need a SixXS account \ - and at least a tunnel. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && make RPM_OPT_FLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /etc/init.d/aiccu - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/attr b/lfs/attr deleted file mode 100644 index 44df4a7..0000000 --- a/lfs/attr +++ /dev/null @@ -1,119 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = attr -PKG_VER = 2.4.43 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://oss.sgi.com/projects/xfs/ -LICENSE = GPLv2+ LGPLv2+ -SHORT_DESC = Tools for extended attribute support. - -define LONG_DESC - A set of tools for manipulating extended attributes on filesystem \ - objects. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --enable-shared - cd $(DIR_APP) && make LIBTOOL="libtool --tag=CC" #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - install -v -m0755 $(DIR_APP)/libattr/.libs/libattr.so.1.1.0 $(TOOLS_DIR)/lib - ln -vsf libattr.so.1.1.0 $(TOOLS_DIR)/lib/libattr.so.1 - ln -vsf libattr.so.1.1.0 $(TOOLS_DIR)/lib/libattr.so - install -v -d $(TOOLS_DIR)/include/attr - cp -vf $(DIR_APP)/include/{attributes.h,error_context.h,libattr.h,xattr.h} \ - $(TOOLS_DIR)/include/attr/ -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/bin \ - --enable-shared - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - install -v -m0755 $(DIR_APP)/libattr/.libs/libattr.so.1.1.0 /lib - ln -vsf libattr.so.1.1.0 /lib/libattr.so.1 - ln -vsf ../../lib/libattr.so.1 /usr/lib/libattr.so - install -v -d /usr/include/attr - cp -vf $(DIR_APP)/include/{attributes.h,error_context.h,libattr.h,xattr.h} \ - /usr/include/attr/ -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/autoconf b/lfs/autoconf deleted file mode 100644 index b7655e4..0000000 --- a/lfs/autoconf +++ /dev/null @@ -1,104 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = autoconf -PKG_VER = 2.64 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/autoconf/ -LICENSE = GPLv2+ -SHORT_DESC = A GNU tool for automatically configuring source code. - -define LONG_DESC - GNU's Autoconf is a tool for configuring source code and Makefiles. \ - Using Autoconf, programmers can create portable and configurable \ - packages, since the person building the package is allowed to \ - specify various configuration options. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/automake b/lfs/automake deleted file mode 100644 index 6f16203..0000000 --- a/lfs/automake +++ /dev/null @@ -1,103 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = automake -PKG_VER = 1.11 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = autoconf - -URL = http://www.gnu.org/software/automake/ -LICENSE = GPLv2+ -SHORT_DESC = A GNU tool for automatically configuring source code. - -define LONG_DESC - Automake is a tool for automatically generating Makefile.in \ - files compliant with the GNU Coding Standards. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/avahi b/lfs/avahi deleted file mode 100644 index bda988f..0000000 --- a/lfs/avahi +++ /dev/null @@ -1,108 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = avahi -PKG_VER = 0.6.25 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Zeroconf -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = dbus dbus-glib libdaemon python-dbus - -URL = http://avahi.org/ -LICENSE = LGPLv2 -SHORT_DESC = Local network service discovery. - -define LONG_DESC - Avahi is a system which facilitates service discovery on \ - a local network -- this means that you can plug your laptop or \ - computer into a network and instantly be able to view other people who \ - you can chat with, find printers to print to or find files being \ - shared. This kind of technology is already found in MacOS X (branded \ - 'Rendezvous', 'Bonjour' and sometimes 'ZeroConf') and is very \ - convenient. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --localstatedir=/var \ - --disable-static \ - --with-distro=none \ - --disable-gdbm \ - --disable-qt3 \ - --disable-qt4 \ - --disable-gtk \ - --disable-pygtk \ - --disable-mono - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libavahi*.la - - $(PYTHON_COMPILE) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/bash b/lfs/bash deleted file mode 100644 index fd74dfb..0000000 --- a/lfs/bash +++ /dev/null @@ -1,154 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = bash -PKG_VER = 4.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Tools -CORE = yes -EXTRA = no -DEBUG = no -ifneq "$(STAGE)" "toolchain" - DEPS = readline -endif - -URL = http://www.gnu.org/software/bash/ -LICENSE = GPLv2+ -SHORT_DESC = Bash is short for born again shell. - -define LONG_DESC - Bash is the shell, or command language interpreter, that will appear in \ - the GNU operating system. Bash is an sh-compatible shell that incorporates \ - useful features from the Korn shell (ksh) and C shell (csh). It is intended \ - to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-rng.patch \ - $(THISAPP)-fixes-1.patch \ - $(THISAPP)-paths-1.patch \ - $(THISAPP)-profile-1.patch \ -# $(THISAPP)-arc4random-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # This patch fixes various reportded issures. It is the latest posted - # patch from linuxfromscratch.org. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-fixes-1.patch - - # This patch modifies Bash to use /dev/urandom (settable with - # --with-randomdev=) for $RANDOM, instead of getpid() and gettimeofday(). - # The test is "( echo $RANDOM; ( echo $RANDOM ); ( echo $RANDOM ) )": - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-rng.patch - - # Some more patches. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-paths-1.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-profile-1.patch - - # Bash uses the RTLD_LAZY option when loading libraries. We want to use - # RTLD_NOW (it is defined from <dlfcn.h>: - cd $(DIR_APP) && sed -e "s/filename, RTLD_LAZY/filename, RTLD_NOW/" \ - -i builtins/enable.def - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ac_cv_func_working_mktime=yes \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --without-bash-malloc - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - ln -sf bash $(TOOLS_DIR)/bin/sh - - # Without the following lines, stage2 will not work - if [ ! -e $(LFS)/bin/bash ]; then \ - install -d $(LFS)/bin && \ - ln -sf $(TOOLS_DIR)/bin/bash $(LFS)/bin && \ - ln -sf bash $(LFS)/bin/sh; \ - fi -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && sed -i "s|htmldir = @htmldir@|htmldir = /usr/share/doc/$(THISAPP)|" \ - Makefile.in -# cd $(DIR_APP) && patch -Np1 < $(DIR_PATCHES)/$(THISAPP)-arc4random-1.patch - cd $(DIR_APP) && autoconf --force - cd $(DIR_APP) && \ - ac_cv_func_working_mktime=yes \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/bin \ - --without-bash-malloc \ - --with-installed-readline - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - # Bash startup files - cp -avf $(DIR_SOURCE)/bash/{bashrc,inputrc,profile,shells} /etc - - # /etc/profile.d - -mkdir -pv /etc/profile.d - cp -vf $(DIR_SOURCE)/profile.d/{extrapaths,i18n,readline,umask}.sh \ - /etc/profile.d -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/bc b/lfs/bc deleted file mode 100644 index 3e4aad4..0000000 --- a/lfs/bc +++ /dev/null @@ -1,108 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = bc -PKG_VER = 1.06 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/bc/ -LICENSE = GPLv2+ -SHORT_DESC = bc is an arbitrary precision numeric processing language. - -define LONG_DESC - bc is a language that supports arbitrary precision numbers with \ - interactive execution of statements. There are some similarities in the \ - syntax to the C programming language. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "$(SNAME)" - cd $(DIR_APP) && sed -i '/PROTO.*readline/d' bc/scan.l - cd $(DIR_APP) && sed -i '/flex -I8/s/8//' configure - cd $(DIR_APP) && sed -i '/stdlib/a #include <string.h>' lib/number.c - cd $(DIR_APP) && sed -i 's/program.*save/static &/' bc/load.c - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --with-readline - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/beep b/lfs/beep deleted file mode 100644 index 3ab74e0..0000000 --- a/lfs/beep +++ /dev/null @@ -1,89 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = beep -PKG_VER = 1.2.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.johnath.com/beep/ -LICENSE = GPLv2+ -SHORT_DESC = Beep the PC speaker any number of ways. - -define LONG_DESC - Beep allows the user to control the PC speaker with precision, \ - allowing different sounds to indicate different events. While it \ - can be run quite happily on the commandline, it's intended place \ - of residence is within shell/perl scripts, notifying the user when \ - something interesting occurs. Of course, it has no notion of \ - what's interesting, but it's real good at that notifying part. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && install -m 0755 beep /usr/bin - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/berkeley b/lfs/berkeley deleted file mode 100644 index d5e5ac1..0000000 --- a/lfs/berkeley +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = db -PKG_VER = 4.7.25 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.oracle.com/technology/products/berkeley-db/ -LICENSE = Proprietary -SHORT_DESC = Berkeley DB is a library that provides an embedded database. - -define LONG_DESC - Berkeley DB (BDB) is a computer software library that provides \ - a high-performance embedded database. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-upstream_fixes-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-upstream_fixes-1.patch - cd $(DIR_APP)/build_unix && \ - CC=gcc \ - ../dist/configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-compat185 \ - --enable-cxx \ - --disable-static - cd $(DIR_APP)/build_unix && make $(PARALLELISMFLAGS) - cd $(DIR_APP)/build_unix && make docdir=/usr/share/doc/$(THISAPP) install - chown -Rv root:root /usr/share/doc/$(THISAPP) - - rm -vf /usr/lib/libdb{,_cxx}-4.7.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/bind b/lfs/bind deleted file mode 100644 index 2b22035..0000000 --- a/lfs/bind +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = bind -PKG_VER = 9.4.1-P1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = openssl - -URL = http://www.isc.org/products/BIND/ -LICENSE = Proprietary -SHORT_DESC = BIND provides tools for the DNS. - -define LONG_DESC - BIND (Berkeley Internet Name Domain or named) is the most commonly used \ - DNS server on the Internet, especially on Unix-like systems. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make -C lib/dns #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make -C lib/isc #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make -C lib/bind9 #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make -C lib/isccfg #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make -C lib/lwres #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make -C bin/dig #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make -C bin/dig install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/binutils b/lfs/binutils deleted file mode 100644 index 6349d11..0000000 --- a/lfs/binutils +++ /dev/null @@ -1,157 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = binutils -PKG_VER = 2.19.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -ifeq "$(STAGE)" "toolchain" - OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP)-pass$(PASS) -else - OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) -endif - -MAINTAINER = -GROUP = Development/Tools -CORE = yes -EXTRA = no -DEBUG = no - -# Host system provides zlib. -ifneq "$(STAGE)" "toolchain" - DEPS = zlib -endif - -URL = http://www.gnu.org/software/binutils/ -LICENSE = GPLv2+ -SHORT_DESC = The GNU Binutils are a collection of binary tools. - -define LONG_DESC - The GNU Binary Utilities, or binutils, is a collection of programming \ - tools for the manipulation of object code in various object file formats. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-ld_makefile.patch \ - $(THISAPP)-pt_pax-1.patch \ - $(THISAPP)-lazy-1.patch \ - $(THISAPP)-asprintf_fix.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - @rm -rf $(DIR_SRC)/binutils-build - -mkdir -v $(DIR_SRC)/binutils-build - - # Add PT_PaX header marking support. These markings are using by the PaX - # kernel, and Pax-utils, to identify which programs need things like executable - # stack, etc. Without this patch the PaX kernel must use legacy mode, and this - # patch is greatly preferable: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-pt_pax-1.patch - -ifeq "$(STAGE)" "toolchain" -ifeq "$(PASS)" "1" - cd $(DIR_SRC)/binutils-build && \ - CC="gcc -B/usr/bin/" \ - ../$(THISAPP)/configure \ - $(CONFIGURE_ARCH) \ - --target=$(IFS_TARGET) \ - --prefix=$(TOOLS_DIR) \ - --disable-nls \ - --disable-werror - cd $(DIR_SRC)/binutils-build && make tooldir=$(TOOLS_DIR) $(PARALLELISMFLAGS) - cd $(DIR_SRC)/binutils-build && make tooldir=$(TOOLS_DIR) install -endif - -ifeq "$(PASS)" "2" - # Binutils libiberty has the same identical bug GCC has: - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-asprintf_fix.patch - - cd $(DIR_SRC)/binutils-build && \ - ../$(THISAPP)/configure \ - $(CONFIGURE_ARCH) \ - --target=$(IFS_TARGET) \ - --prefix=$(TOOLS_DIR) \ - --with-lib-path=$(TOOLS_DIR)/lib \ - --disable-nls \ - --enable-shared \ - --disable-werror - cd $(DIR_SRC)/binutils-build && make tooldir=$(TOOLS_DIR) $(PARALLELISMFLAGS) - cd $(DIR_SRC)/binutils-build && make tooldir=$(TOOLS_DIR) install - - cd $(DIR_SRC)/binutils-build && make -C ld clean - cd $(DIR_SRC)/binutils-build && make -C ld LIB_PATH=/lib:/usr/lib - cd $(DIR_SRC)/binutils-build && cp -v ld/.libs/ld-new $(TOOLS_DIR)/bin -endif -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-asprintf_fix.patch - cd $(DIR_SRC)/binutils-build && \ - CC="gcc -specs=$$(dirname $$(gcc --print-libgcc-file-name))/myspecs -B/usr/lib/ -B/usr/bin/" \ - ../$(THISAPP)/configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-shared \ - --disable-nls \ - --disable-werror \ - --disable-static - cd $(DIR_SRC)/binutils-build && make tooldir=/usr $(PARALLELISMFLAGS) - cd $(DIR_SRC)/binutils-build && make tooldir=/usr install - - cp -fv ../$(THISAPP)/include/libiberty.h /usr/include - rm -vf /usr/lib/libiberty.a /usr/lib/lib{bfd,opcodes}.la -endif - - @rm -rf $(DIR_APP) $(DIR_SRC)/binutils-build - @$(POSTBUILD) diff --git a/lfs/bison b/lfs/bison deleted file mode 100644 index c8aec43..0000000 --- a/lfs/bison +++ /dev/null @@ -1,109 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = bison -PKG_VER = 2.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/bison/ -LICENSE = GPLv2+ -SHORT_DESC = GNU Bison is a parser generator. - -define LONG_DESC - Bison is a general-purpose parser generator that converts an annotated \ - context-free grammar into an LALR(1) or GLR parser for that grammar. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && echo '#define YYENABLE_NLS 1' >> config.h - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cd $(DIR_APP)/lib/ && \ - gcc -shared -Wl,-soname,liby.so.2.4 -o liby.so.2.4 -fPIC main.o yyerror.o - rm -fv /usr/lib/liby.a - cd $(DIR_APP)/lib/ && install -v liby.so.2.4 /usr/lib/liby.so.2.4 - ln -vsf liby.so.2.4 /usr/lib/liby.so -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/boost b/lfs/boost deleted file mode 100644 index 64fea2b..0000000 --- a/lfs/boost +++ /dev/null @@ -1,134 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = boost -PKG_VER = 1.39.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(PKG_NAME)_$(subst .,_,$(PKG_VER)).tar.bz2 -DIR_APP = $(DIR_SRC)/$(PKG_NAME)_$(subst .,_,$(PKG_VER)) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.boost.org/ -LICENSE = Boost -SHORT_DESC = The Boost C++ Libraries. - -define LONG_DESC - Boost provides free peer-reviewed portable C++ source libraries. The \ - emphasis is on libraries which work well with the C++ Standard \ - Library, in the hopes of establishing "existing practice" for \ - extensions and providing reference implementations so that the Boost \ - libraries are suitable for eventual standardization. (Some of the \ - libraries have already been proposed for inclusion in the C++ \ - Standards Committee's upcoming C++ Standard Library Technical Report.) -endef - -export BOOST_ROOT=$(DIR_APP) -BUILD_FLAGS = -d2 --layout=system variant=release threading=single,multi \ - debug-symbols=on link=shared runtime-link=shared -SONAMEVERSION = 5 - -CFLAGS += -fno-strict-aliasing - -PARALLELISMFLAGS := $(shell $(DIR_SOURCE)/scripts/parallelismflags --max=8 $(PARALLELISMFLAGS)) - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-version-override.patch \ - $(THISAPP)-unneccessary_iostreams.patch \ - $(THISAPP)-function_template.patch \ - $(THISAPP)-fs_gcc44.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - # Let bjam use our own cflags - cd $(DIR_APP) && sed -e "s/-O3/$(CFLAGS)/g" -i tools/build/v2/tools/gcc.jam - - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-version-override.patch - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-unneccessary_iostreams.patch - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-function_template.patch - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-fs_gcc44.patch - - # build jam - cd $(DIR_APP)/tools/jam/src && ./build.sh - - # build libs - cd $(DIR_APP) && ./bootstrap.sh \ - --with-toolset=gcc \ - --with-icu - - cd $(DIR_APP) && \ - ./bjam $(BUILD_FLAGS) $(PARALLELISMFLAGS) stage - - # install libs - cd $(DIR_APP) && for i in $$(find stage -type f -name "*.so"); do \ - install -v -p -m 755 $$i /usr/lib/$$(basename $$i).$(PKG_VER); \ - ln -svf $$(basename $$i).$(PKG_VER) /usr/lib/$$(basename $$i).$(SONAMEVERSION); \ - ln -svf $$(basename $$i).$(SONAMEVERSION) /usr/lib/$$(basename $$i); \ - done - - # install includes - cd $(DIR_APP) && find boost -type d | while read a; do \ - mkdir -pv /usr/include/$$a; \ - find $$a -mindepth 1 -maxdepth 1 -type f | \ - xargs -r install -v -m 644 -p -t /usr/include/$$a; \ - done - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/br2684ctl b/lfs/br2684ctl deleted file mode 100644 index 021a9f2..0000000 --- a/lfs/br2684ctl +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = br2684ctl -PKG_VER = ipfire-1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://cvs.linux-atm.sourceforge.net/viewcvs.py/linux-atm/linux-atm/src/br26... -LICENSE = GPLv2+ -SHORT_DESC = Utilities for configuring an ATM/ethernet bridge. - -define LONG_DESC - Utility for configuring RFC 2684 ATM/Ethernet bridging \ - ATM bridging is a way to extend Ethernet over an ATM network and is \ - mainly used for DSL connections. This package contains the user space \ - utility needed to configure the kernel driver. \ - This package is needed if you own an USB DSL modem and your connection \ - uses one of these protocols: RFC 1483 bridged (RFC 2684 bridged), \ - PPP over Ethernet (PPPoE). -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && gcc $(CFLAGS) -latm br2684ctl.c -o br2684ctl - cd $(DIR_APP) && install -v -m 755 br2684ctl /usr/bin/br2684ctl - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/bridge-utils b/lfs/bridge-utils deleted file mode 100644 index 7a97a43..0000000 --- a/lfs/bridge-utils +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = bridge-utils -PKG_VER = 1.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://bridge.sourceforge.net/ -LICENSE = GPLv2+ -SHORT_DESC = Utilities for configuring the linux ethernet bridge. - -define LONG_DESC - This package contains utilities for configuring the linux ethernet \ - bridge. The linux ethernet bridge can be used for connecting multiple \ - ethernet devices together. The connecting is fully transparent: hosts \ - connected to one ethernet device see hosts connected to the other \ - ethernet devices directly. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && autoconf - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sbindir=/sbin - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/libbridge.a - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/btrfs-progs b/lfs/btrfs-progs deleted file mode 100644 index 33e6ea0..0000000 --- a/lfs/btrfs-progs +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = btrfs-progs -PKG_VER = 0.19 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://btrfs.wiki.kernel.org/index.php/Main_Page -LICENSE = GPLv2 -SHORT_DESC = Userspace programs for btrfs. - -define LONG_DESC - The btrfs-progs package provides all the userpsace programs needed to create, \ - check, modify and correct any inconsistencies in the btrfs filesystem. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-fix-labels.patch \ - $(THISAPP)-build-everything.patch \ - $(THISAPP)-valgrind.patch - - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-fix-labels.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-build-everything.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-valgrind.patch - cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) - cd $(DIR_APP) && make bindir=/sbin mandir=/usr/share install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/bwm-ng b/lfs/bwm-ng deleted file mode 100644 index be4c1c1..0000000 --- a/lfs/bwm-ng +++ /dev/null @@ -1,88 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = bwm-ng -PKG_VER = 0.6 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Statistics -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gropp.org/?id=projects&sub=bwm-ng -LICENSE = GPLv2+ -SHORT_DESC = A bandwidth monitor for the shell - -define LONG_DESC - bwm-ng diplays the traffic passing by on all interfaces. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/bzip2 b/lfs/bzip2 deleted file mode 100644 index 5ccc0af..0000000 --- a/lfs/bzip2 +++ /dev/null @@ -1,111 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = bzip2 -PKG_VER = 1.0.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Compression -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.bzip.org/ -LICENSE = GPLv2+ -SHORT_DESC = Bzip2 is a data compressor. - -define LONG_DESC - bzip2 is a freely available, patent free (see below), high-quality data \ - compressor that is an alternative to the GNU zip compressor. -endef - -CFLAGS += -fPIC - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-install_docs-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && sed -i 's@(ln -s -f )$$(PREFIX)/bin/@\1@' Makefile - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make PREFIX=$(TOOLS_DIR) install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-install_docs-1.patch - cd $(DIR_APP) && sed -e "s/$$(CC) -shared/& $(CFLAGS)/" -i Makefile-libbz2_so - cd $(DIR_APP) && make CFLAGS="$(CFLAGS) -D_FILE_OFFSET_BITS=64" -f Makefile-libbz2_so - cd $(DIR_APP) && make clean - cd $(DIR_APP) && make CFLAGS="$(CFLAGS) -D_FILE_OFFSET_BITS=64" $(PARALLELISMFLAGS) - cd $(DIR_APP) && make PREFIX=/usr install - - cd $(DIR_APP) && cp -v bzip2-shared /bin/bzip2 - cd $(DIR_APP) && cp -av libbz2.so* /lib - ln -sfv ../../lib/libbz2.so.1.0 /usr/lib/libbz2.so - rm -fv /usr/bin/{bunzip2,bzcat,bzip2} - ln -sfv bzip2 /bin/bunzip2 - ln -sfv bzip2 /bin/bzcat - rm -vf /usr/lib/libbz2.a -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/cairo b/lfs/cairo deleted file mode 100644 index fa4f273..0000000 --- a/lfs/cairo +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = cairo -PKG_VER = 1.8.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Graphics -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://cairographics.org -LICENSE = LGPLv2 MPLv1.1 -SHORT_DESC = A 2D graphics library. - -define LONG_DESC - Cairo is a 2D graphics library designed to provide high-quality display \ - and print output. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libcairo.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/ccache b/lfs/ccache deleted file mode 100644 index 78fbad0..0000000 --- a/lfs/ccache +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = ccache -PKG_VER = 2.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP)-pass$(PASS) - -MAINTAINER = -GROUP = Development/Compilers -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://ccache.samba.org/ -LICENSE = GPLv2+ -SHORT_DESC = C/C++ compiler cache. - -define LONG_DESC - ccache is a compiler cache. It acts as a caching pre-processor to \ - C/C++ compilers, using the -E compiler switch and a hash to detect \ - when a compilation can be satisfied from cache. This often results in \ - a 5 to 10 times speedup in common compilations. -endef - -PREFIX = $(TOOLS_DIR)/usr -CFLAGS := $(subst -fPIC,,$(CFLAGS)) -static - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP).patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -p0 < $(DIR_PATCHES)/$(THISAPP).patch - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(PREFIX) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - for i in gcc g++ cc; do \ - ln -sf ccache $(PREFIX)/bin/$${i}; \ - ln -sf ccache $(PREFIX)/bin/$(IFS_TARGET)-$${i}; \ - done - $(PREFIX)/bin/ccache -z - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/coreutils b/lfs/coreutils deleted file mode 100644 index 4f26028..0000000 --- a/lfs/coreutils +++ /dev/null @@ -1,139 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = coreutils -PKG_VER = 7.6 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = - -# Don't check deps at toolchain build -ifneq "$(STAGE)" "toolchain" - DEPS = acl attr libcap2 ncurses pam shadow util-linux-ng -endif - -URL = http://www.gnu.org/software/coreutils/ -LICENSE = GPLv3+ -SHORT_DESC = A set of basic GNU tools commonly used in shell scripts. - -define LONG_DESC - These are the GNU core utilities. This package is the combination of \ - the old GNU fileutils, sh-utils, and textutils packages. -endef - -CFLAGS += -D_GNU_SOURCE=1 -fno-strict-aliasing - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-uname_PIC-1.patch \ - $(THISAPP)-i18n-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-i18n-1.patch - #cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-uname_PIC-1.patch - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - gl_cv_func_printf_directive_n=no \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --enable-install-program=hostname - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - cd $(DIR_APP) && cp -v src/su $(TOOLS_DIR)/bin/su-tools -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - gl_cv_func_printf_directive_n=no \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-largefile \ - --enable-install-program=arch,hostname,su \ - --enable-no-install-program=kill,uptime - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) \ - CPPFLAGS="-DUSE_PAM" su_LDFLAGS="-pie -lpam -lpam_misc" - cd $(DIR_APP) && make install - - mv -v /usr/bin/{cat,chgrp,chmod,chown,cp,date,dd,df,echo} /bin - mv -v /usr/bin/{false,hostname,ln,ls,mkdir,mknod,mv,pwd,readlink,rm} /bin - mv -v /usr/bin/{rmdir,stty,sync,touch,true,uname} /bin - mv -v /usr/bin/chroot /usr/sbin - mv -v /usr/bin/{head,sleep,nice} /bin - - cd $(DIR_APP) && install -m 4755 src/su /bin - - # Dump /etc/dircolors. - dircolors -p > /etc/dircolors - -mkdir -pv /etc/profile.d - cp -vf $(DIR_SOURCE)/profile.d/dircolors.sh /etc/profile.d - - # PAM - cp -vf $(DIR_SOURCE)/pam.d/su{,-l} /etc/pam.d -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/cpio b/lfs/cpio deleted file mode 100644 index cefbfdc..0000000 --- a/lfs/cpio +++ /dev/null @@ -1,110 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = cpio -PKG_VER = 2.10 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Packaging -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/cpio/ -LICENSE = GPLv3+ -SHORT_DESC = A GNU archiving program. - -define LONG_DESC - GNU cpio copies files into or out of a cpio or tar archive. Archives \ - are files which contain a collection of other files plus information \ - about them, such as their file name, owner, timestamps, and access \ - permissions. The archive can be another file on the disk, a magnetic \ - tape, or a pipe. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && autoreconf --force - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && autoreconf --force - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH)\ - --prefix=/usr \ - --bindir=/bin \ - --libexecdir=/tmp \ - --with-rmt=/usr/sbin/rmt - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/cracklib b/lfs/cracklib deleted file mode 100644 index ec077ca..0000000 --- a/lfs/cracklib +++ /dev/null @@ -1,125 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = cracklib -PKG_VER = 2.8.12 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Security/Password -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://sourceforge.net/projects/cracklib/ -LICENSE = GPLv2 -SHORT_DESC = A password-checking library. - -define LONG_DESC - CrackLib tests passwords to determine whether they match certain \ - security-oriented characteristics, with the purpose of stopping users \ - from choosing passwords that are easy to guess. CrackLib performs \ - several tests on passwords: it tries to generate words from a username \ - and gecos entry and checks those words against the password; it checks \ - for simplistic patterns in passwords; and it checks for the password \ - in a dictionary. -endef - -ifeq "$(LFS_FILE)" "python-cracklib" - DEPS = python - SHORT_DESC = Python-bindings for cracklib. - LONG_DESC = A python module to use safe passwords. -endif - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - cracklib-words-20080507.gz - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static \ - --with-default-dict=/lib/cracklib/pw_dict - -ifeq "$(LFS_FILE)" "python-cracklib" - cd $(DIR_APP)/python && make $(PARALLELISMFLAGS) - cd $(DIR_APP)/python && make install - rm -vf /usr/lib/python2.6/site-packages/cracklibmodule.la -else - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - -rm -rf /usr/share/dict - cd $(DIR_APP) && make install - mv -v /usr/lib/libcrack.so.2* /lib - ln -v -sf ../../lib/libcrack.so.2.8.0 /usr/lib/libcrack.so - rm -vf /usr/lib/libcrack.la - - install -v -m644 -D $(DIR_DL)/cracklib-words-20080507.gz \ - /usr/share/dict/cracklib-words.gz - gunzip -v /usr/share/dict/cracklib-words.gz - ln -v -s cracklib-words /usr/share/dict/words - install -v -m755 -d /lib/cracklib - echo -ne "$(NAME)\n$(SNAME)\n" >> /usr/share/dict/cracklib-extra-words - create-cracklib-dict /usr/share/dict/cracklib-words \ - /usr/share/dict/cracklib-extra-words -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/cryptsetup-luks b/lfs/cryptsetup-luks deleted file mode 100644 index 2fea8dd..0000000 --- a/lfs/cryptsetup-luks +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = cryptsetup-luks -PKG_VER = 1.0.6 -PKG_REL = 0 - -THISAPP = cryptsetup-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = e2fsprogs libgcrypt libgpg-error lvm2 popt - -URL = http://cryptsetup.googlecode.com/ -LICENSE = GPLv2+ -SHORT_DESC = A utility for setting up encrypted filesystems. - -define LONG_DESC - This package contains cryptsetup, a utility for setting up \ - encrypted filesystems using Device Mapper and the dm-crypt target. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sbindir=/sbin \ - --libdir=/lib \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -rvf /lib/cryptsetup{,.la,.so} - ln -svf ../../lib/libcryptsetup.so.0.0.0 /usr/lib/libcryptsetup.so - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/cups b/lfs/cups deleted file mode 100644 index 3d82ca7..0000000 --- a/lfs/cups +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = cups -PKG_VER = 1.4.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(PKG_NAME)-$(PKG_VER)-source.tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Printing -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = cyrus-sasl ghostscript libjpeg libtiff openldap - -URL = http://cups.org/software.php -LICENSE = GPLv2+ -SHORT_DESC = The common UNIX printing system. - -define LONG_DESC - CUPS is the standards-based, open source printing system developed \ - by Apple Inc. for Mac OS® X and other UNIX®-like operating systems. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --localstatedir=/var \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - # Remove sysvinit scripts - rm -vfr /etc/init.d/cups /etc/rc*.d - - cp -fv $(DIR_SRC)/$(THISAPP)/conf/cupsd.conf /etc/cups/ - - $(INSTALL_INITSCRIPT) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/curl b/lfs/curl deleted file mode 100644 index 29fa7e8..0000000 --- a/lfs/curl +++ /dev/null @@ -1,109 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = curl -PKG_VER = 7.19.6 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Internet -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = pkg-config -DEPS = libssh2 openssl openldap - -URL = http://curl.haxx.se/ -LICENSE = MIT -SHORT_DESC = A utility for getting files from remote servers (FTP, HTTP, and others). - -define LONG_DESC - cURL is a tool for getting files from HTTP, FTP, FILE, LDAP, LDAPS, \ - DICT, TELNET and TFTP servers, using any of the supported protocols. \ - cURL is designed to work without user interaction or any kind of \ - interactivity. cURL offers many useful capabilities, like proxy support, \ - user authentication, FTP upload, HTTP post, and file transfer resume. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - CPPFLAGS="-DHAVE_PK11_CREATEGENERICOBJECT" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static \ - --with-ca-bundle=/etc/pki/tls/certs/ca-bundle.crt \ - --with-libidn \ - --with-libssh2 \ - --with-nss \ - --enable-ldaps \ - --enable-ipv6 - - # Remove bogus rpath - cd $(DIR_APP) && sed -i \ - -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ - -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libcurl.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/cyrus-sasl b/lfs/cyrus-sasl deleted file mode 100644 index 486eaa4..0000000 --- a/lfs/cyrus-sasl +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = cyrus-sasl -PKG_VER = 2.1.23 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = openssl pam - -URL = http://asg.web.cmu.edu/sasl/sasl-library.html -LICENSE = BSD -SHORT_DESC = The Cyrus SASL library. - -define LONG_DESC - The cyrus-sasl package contains the Cyrus implementation of SASL. \ - SASL is the Simple Authentication and Security Layer, a method for \ - adding authentication support to connection-based protocols. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-bad-elif.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-bad-elif.patch - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --with-dbpath=/var/lib/sasl/sasldb2 \ - --with-saslauthd=/var/run/saslauthd - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libsasl2.la /usr/lib/sasl2/*.la - - install -v -m700 -d /var/lib/sasl /var/run/saslauthd - cp -vf $(DIR_SOURCE)/cyrus-sasl/smtpd.conf /usr/lib/sasl2/ - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/dbus b/lfs/dbus deleted file mode 100644 index 24b9bb5..0000000 --- a/lfs/dbus +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = dbus -PKG_VER = 1.2.16 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Daemons -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = expat - -URL = http://www.freedesktop.org/software/dbus/ -LICENSE = GPLv2+ AFL -SHORT_DESC = D-BUS message bus. - -define LONG_DESC - D-BUS is a system for sending messages between applications. It is \ - used both for the system-wide message bus service, and as a \ - per-user-login-session messaging facility. -endef - -INITSCRIPT = messagebus - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --localstatedir=/var \ - --libexecdir=/usr/lib \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - $(INSTALL_INITSCRIPT) - - rm -vf /usr/lib/libdbus-1.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/dbus-glib b/lfs/dbus-glib deleted file mode 100644 index 3ed9e6a..0000000 --- a/lfs/dbus-glib +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = dbus-glib -PKG_VER = 0.82 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = dbus glib2 expat - -URL = http://www.freedesktop.org/software/dbus/ -LICENSE = GPLv2+ AFL -SHORT_DESC = GLib bindings for D-Bus. - -define LONG_DESC - D-Bus add-on library to integrate the standard D-Bus library with \ - the GLib thread abstraction and main loop. -endef - -CFLAGS += -fno-strict-aliasing -fPIC - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --libexecdir=/usr/lib - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libdbus-glib-1.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/dhcp b/lfs/dhcp deleted file mode 100644 index 6547a4d..0000000 --- a/lfs/dhcp +++ /dev/null @@ -1,109 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = dhcp -PKG_VER = 4.1.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Daemons -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://isc.org/products/DHCP/ -LICENSE = ISC -SHORT_DESC = Dynamic host configuration protocol software. - -define LONG_DESC - DHCP (Dynamic Host Configuration Protocol) is a protocol which allows \ - individual devices on an IP network to get their own network \ - configuration information (IP address, subnetmask, broadcast address, \ - etc.) from a DHCP server. The overall purpose of DHCP is to make it \ - easier to administer a large network. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # Doesn't compile with ipv6 at the moment - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --disable-dhcpv6 \ - --with-srv-lease-file=/var/lib/dhcpd/dhcpd.leases \ - --with-cli-lease-file=/var/lib/dhclient/dhclient.leases \ - --with-srv-pid-file=/var/run/dhcpd.pid \ - --with-cli-pid-file=/var/run/dhclient.pid \ - --with-relay-pid-file=/var/run/dhcrelay.pid \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - # Move the client to /sbin, create dirs - # and remove the default config. - mv -v /usr/sbin/dhclient /sbin - rm -vf /etc/dhclient.conf - -mkdir -pv /var/lib/dhclient - install -v -m 755 $(DIR_SOURCE)/$(PKG_NAME)/dhclient-script /sbin/dhclient-script - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/diffutils b/lfs/diffutils deleted file mode 100644 index 0838516..0000000 --- a/lfs/diffutils +++ /dev/null @@ -1,110 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = diffutils -PKG_VER = 2.8.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/diffutils/diffutils.html -LICENSE = GPLv2+ -SHORT_DESC = A GNU collection of diff utilities. - -define LONG_DESC - Diffutils includes four utilities: diff, cmp, diff3 and sdiff. Diff \ - compares two files and shows the differences, line by line. The cmp \ - command shows the offset and line numbers where two files differ, or \ - cmp can show the characters that differ between the two files. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-i18n-1.patch \ - $(THISAPP)-hardened_tmp-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-hardened_tmp-1.patch - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-i18n-1.patch - cd $(DIR_APP) && touch man/diff.1 - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/directfb b/lfs/directfb deleted file mode 100644 index 68d320c..0000000 --- a/lfs/directfb +++ /dev/null @@ -1,111 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = DirectFB -PKG_VER = 1.4.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Graphics -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.directfb.org/ -LICENSE = LGPLv2+ -SHORT_DESC = Graphics abstraction library for the Linux Framebuffer Device. - -define LONG_DESC - DirectFB is a thin library that provides hardware graphics acceleration, \ - input device handling and abstraction, integrated windowing system with \ - support for translucent windows and multiple display layers on top of the \ - Linux Framebuffer Device. -endef - -ifneq "$(TARGET)" "i686" -ifneq "$(TARGET)" "i586" -ifneq "$(TARGET)" "i486" - CONFIGURE_ARGS = --disable-mmx --disable-sse -endif -endif -endif - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-x11 \ - --enable-sdl \ - --enable-video4linux2 \ - --enable-libv412 \ - --enable-zlib \ - $(CONFIGURE_ARGS) - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libdirect{,fb}.la /usr/lib/libfusion.la - find /usr/lib/directfb*/ -name "*.la" -exec rm -vf {} ; - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/dmraid b/lfs/dmraid deleted file mode 100644 index 3413468..0000000 --- a/lfs/dmraid +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = dmraid -PKG_VER = 1.0.0.rc15 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(PKG_NAME)/$(PKG_VER) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = lvm2 - -URL = http://people.redhat.com/heinzm/sw/dmraid -LICENSE = GPLv2+ -SHORT_DESC = Device-mapper RAID tool and library. - -define LONG_DESC - DMRAID supports RAID device discovery, RAID set activation, creation, \ - removal, rebuild and display of properties for ATARAID/DDF1 metadata on \ - Linux >= 2.4 using device-mapper. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sbindir=/sbin \ - --libdir=/lib \ - --disable-static \ - --disable-static_link - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make -C lib libdmraid.so #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cd $(DIR_APP) && install -v -m 755 lib/libdmraid.so /lib/libdmraid.so.$(PKG_VER) - ln -svf libdmraid.so.$(PKG_VER) /lib/libdmraid.so - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/dosfstools b/lfs/dosfstools deleted file mode 100644 index 18137fe..0000000 --- a/lfs/dosfstools +++ /dev/null @@ -1,86 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = dosfstools -PKG_VER = 3.0.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.daniel-baumann.ch/software/dosfstools/ -LICENSE = GPLv3+ -SHORT_DESC = Utilities for making and checking MS-DOS FAT filesystems on Linux. - -define LONG_DESC - The dosfstools package includes the mkdosfs and dosfsck utilities, \ - which respectively make and check MS-DOS FAT filesystems on hard \ - drives or on floppies. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install-bin PREFIX=/usr SBINDIR=/sbin - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/dvdrtools b/lfs/dvdrtools deleted file mode 100644 index 7c4d685..0000000 --- a/lfs/dvdrtools +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = dvdrtools -PKG_VER = 0.2.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://savannah.nongnu.org/projects/dvdrtools/ -LICENSE = GPLv2+ -SHORT_DESC = A set of command line programs that allows to record media. - -define LONG_DESC - dvdrtools is a fork of cdrtools/cdrecord with support for writing to DVDs. \ - While its primary purpose is writing data DVDs, it includes basic support \ - for mastering video DVDs. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - CFLAGS=$$(sed "s/-O2/-O0/g" <<<$$CFLAGS) \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/e2fsprogs b/lfs/e2fsprogs deleted file mode 100644 index 7767eb8..0000000 --- a/lfs/e2fsprogs +++ /dev/null @@ -1,133 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = e2fsprogs -PKG_VER = 1.41.8 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://e2fsprogs.sourceforge.net/ -LICENSE = GPLv2 -SHORT_DESC = Utilities for managing the second and third extended (ext2/ext3) filesystems. - -define LONG_DESC - The e2fsprogs package contains a number of utilities for creating, \ - checking, modifying, and correcting any inconsistencies in second \ - and third extended (ext2/ext3) filesystems. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -mkdir $(DIR_APP)/build - - # Fix DT_TEXTREL in e2fsprogs libraries. --disable-shared and - # --with-pic are not options in E2fsprogs: - cd $(DIR_APP) && \ - find lib/ -name Makefile.in -exec sed -i "s/$$(ALL_CFLAGS)/& -fPIC/" {} ; - - # At run time libblkid looks for the BLKID_DEBUG environment variable to - # enable debbugging, with getenv(3). Some suid-root programs use libblkid, - # such as mount(1). e2fsprogs includes a safe_getenv() function, which calls - # __secure_getenv() from libc. __secure_getenv will restrict some environment - # variables if the user is suid or sgid. So, this command replaces getenv() - # with safe_getenv(): - cd $(DIR_APP) && sed \ - -e "s/getenv("BLKID_DEBUG")/safe_getenv("BLKID_DEBUG")/" \ - -i lib/blkid/cache.c - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP)/build && \ - ../configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --enable-elf-shlibs - cd $(DIR_APP)/build && make $(PARALLELISMFLAGS) - cd $(DIR_APP)/build && make install-libs -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP)/build && \ - LDFLAGS=-lblkid \ - ../configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --with-root-prefix="" \ - --enable-elf-shlibs \ - --disable-libblkid \ - --disable-fsck \ - --disable-uuidd \ - --disable-libuuid - cd $(DIR_APP)/build && make $(PARALLELISMFLAGS) - cd $(DIR_APP)/build && make install - cd $(DIR_APP)/build && make install-libs - ln -svf ../../lib/libcom_err.so.2 /usr/lib/libcom_err.so - ln -svf ../../lib/libe2p.so.2 /usr/lib/libe2p.so - ln -svf ../../lib/libext2fs.so.2 /usr/lib/libext2fs.so - ln -svf ../../lib/libss.so.2 /usr/lib/libss.so - ln -svf ../../lib/libuuid.so.1 /usr/lib/libuuid.so -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/ebtables b/lfs/ebtables deleted file mode 100644 index 8e10270..0000000 --- a/lfs/ebtables +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = ebtables -PKG_VER = v2.0.9-1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://ebtables.sourceforge.net/ -LICENSE = GPLv2+ -SHORT_DESC = Ethernet Bridge frame table administration tool. - -define LONG_DESC - Ethernet bridge tables is a firewalling tool to transparently filter network \ - traffic passing a bridge. The filtering possibilities are limited to link \ - layer filtering and some basic filtering on higher network layers. -endef - -CFLAGS += -fno-stack-protector - -define QUALITY_AGENT_WHITELIST_RPATH - /sbin/ebtables-restore \ - /sbin/ebtables -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" BINDIR="/sbin" LIBDIR="/lib/ebtables" \ - MANDIR="/usr/share/man" $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install DESTDIR="/" BINDIR="/sbin" LIBDIR="/lib/ebtables" \ - MANDIR="/usr/share/man" INITDIR="/etc/init.d" - - rm -vf /etc/init.d/ebtables - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/etherwake b/lfs/etherwake deleted file mode 100644 index b9efa70..0000000 --- a/lfs/etherwake +++ /dev/null @@ -1,86 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = etherwake -PKG_VER = 1.09 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = Can wake up sleeping PCs by WOL. - -define LONG_DESC - A little tool to send magic Wake-on-LAN packets You can wake up WOL \ - compliant Computers which have been powered down to sleep mode or start \ - WOL compliant Computers with a BIOS feature. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/eventlog b/lfs/eventlog deleted file mode 100644 index a76ad21..0000000 --- a/lfs/eventlog +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = eventlog -PKG_VER = 0.2.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.balabit.com/ -LICENSE = GPLv2+ -SHORT_DESC = Eventlog is an API for syslog-ng. - -define LONG_DESC - A new API to format and send structured log messages. It supports multiple \ - message representations (plain, XML attributes and XML tags) and multiple \ - output methods (local syslogd). -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - mv -v /usr/lib/libevtlog.so.0* /lib - ln -svf ../../lib/libevtlog.so.0.* /usr/lib/libevtlog.so - rm -vf /usr/lib/libevtlog.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/expat b/lfs/expat deleted file mode 100644 index 84cdf64..0000000 --- a/lfs/expat +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = expat -PKG_VER = 2.0.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.libexpat.org/ -LICENSE = MIT -SHORT_DESC = An XML parser library. - -define LONG_DESC - This is expat, the C library for parsing XML, written by James Clark. Expat \ - is a stream oriented XML parser. This means that you register handlers with \ - the parser prior to starting the parse. These handlers are called when the \ - parser discovers the associated structures in the document being parsed. A \ - start tag is an example of the kind of structures for which you may \ - register handlers. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libexpat.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/ez-ipupdate b/lfs/ez-ipupdate deleted file mode 100644 index 6b052e1..0000000 --- a/lfs/ez-ipupdate +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = ez-ipupdate -PKG_VER = 3.0.11b8 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://bridge.sourceforge.net/ -LICENSE = GPLv2+ -SHORT_DESC = Utilities for configuring the linux ethernet bridge. - -define LONG_DESC - This package contains utilities for configuring the linux ethernet \ - bridge. The linux ethernet bridge can be used for connecting multiple \ - ethernet devices together. The connecting is fully transparent: hosts \ - connected to one ethernet device see hosts connected to the other \ - ethernet devices directly. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-10.patch \ - $(THISAPP)-pidfile.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np0 < $(DIR_PATCHES)/$(THISAPP)-pidfile.patch - cd $(DIR_APP) && patch -Np1 < $(DIR_PATCHES)/$(THISAPP)-10.patch - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && chmod -v 755 missing - cd $(DIR_APP) && make $(MAKETUNING) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/file b/lfs/file deleted file mode 100644 index 6e75fa1..0000000 --- a/lfs/file +++ /dev/null @@ -1,108 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = file -PKG_VER = 5.03 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.darwinsys.com/file/ -LICENSE = BSD -SHORT_DESC = A utility for determining file types. - -define LONG_DESC - The file command is used to identify a particular file according to the \ - type of data contained by the file. File can identify many different \ - file types, including ELF binaries, system libraries, RPM packages, and \ - different graphics formats. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libmagic.la -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/findutils b/lfs/findutils deleted file mode 100644 index cb17777..0000000 --- a/lfs/findutils +++ /dev/null @@ -1,111 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = findutils -PKG_VER = 4.4.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/findutils/ -LICENSE = GPLv3+ -SHORT_DESC = The GNU versions of find utilities (find and xargs). - -define LONG_DESC - The findutils package contains programs which will help you locate \ - files on your system. The find utility searches through a hierarchy \ - of directories looking for files which match a certain set of criteria \ - (such as a filename pattern). The xargs utility builds and executes \ - command lines from standard input arguments (usually lists of file \ - names generated by the find command). -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --libexecdir=$(TOOLS_DIR)/lib/findutils - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libexecdir=/usr/lib/findutils \ - --localstatedir=/var/lib/locate - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - mv -v /usr/bin/find /bin - sed -i -e 's/find:=$${BINDIR}/find:=/bin/' /usr/bin/updatedb -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/firewall b/lfs/firewall deleted file mode 100644 index 7039b31..0000000 --- a/lfs/firewall +++ /dev/null @@ -1,86 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = firewall -PKG_VER = -PKG_REL = 0 - -THISAPP = $(PKG_NAME) -DIR_APP = $(DIR_SOURCE)/$(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Michael Tremer michael.tremer@ipfire.org -GROUP = Networking/Firewall -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.ipfire.org/ -LICENSE = GPL3+ -SHORT_DESC = The IPFire Firewall Engine. - -define LONG_DESC - This script installs IPFire's firewall. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - -mkdir -pv /usr/{lib,share}/firewall - for i in $(DIR_APP)/{functions,zones}*; do \ - install -m 644 -v $$i /usr/lib/firewall; \ - done - cp -avf $(DIR_APP)/macros /usr/share/firewall/ - install -m 755 -v $(DIR_APP)/firewall /usr/bin - $(INSTALL_INITSCRIPT) - @$(POSTBUILD) diff --git a/lfs/flex b/lfs/flex deleted file mode 100644 index c7c1bdc..0000000 --- a/lfs/flex +++ /dev/null @@ -1,116 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = flex -PKG_VER = 2.5.35 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = m4 - -URL = http://flex.sourceforge.net/ -LICENSE = BSD -SHORT_DESC = A tool for creating scanners (text pattern recognizers). - -define LONG_DESC - The flex program generates scanners. Scanners are programs which can \ - recognize lexical patterns in text. Flex takes pairs of regular \ - expressions and C code as input and generates a C source file as \ - output. The output file is compiled and linked with a library to \ - produce an executable. The executable searches through its input for \ - occurrences of the regular expressions. When a match is found, it \ - executes the corresponding C code. Flex was designed to work with \ - both Yacc and Bison, and is used by many programs as part of their \ - build process. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - echo "#!/bin/sh" > /usr/bin/lex - echo "exec /usr/bin/flex -l "$$@"" >> /usr/bin/lex - chmod 755 /usr/bin/lex -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/fontconfig b/lfs/fontconfig deleted file mode 100644 index 113604c..0000000 --- a/lfs/fontconfig +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = fontconfig -PKG_VER = 2.7.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Graphics -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = freetype libxml2 - -URL = http://fontconfig.org/ -LICENSE = MIT -SHORT_DESC = Font configuration and customization library. - -define LONG_DESC - Fontconfig is designed to locate fonts within the \ - system and select them according to requirements specified by \ - applications. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --localstatedir=/var \ - --disable-static \ - --enable-libxml2 - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libfontconfig.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/freeradius b/lfs/freeradius deleted file mode 100644 index e4e6fa5..0000000 --- a/lfs/freeradius +++ /dev/null @@ -1,124 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = freeradius-server -PKG_VER = 2.1.6 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Daemons -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.freeradius.org/ -LICENSE = GPLv2+ and LGPLv2+ -SHORT_DESC = High-performance and highly configurable free RADIUS server. - -define LONG_DESC - The FreeRADIUS Server Project is a high performance and highly \ - configurable GPL'd free RADIUS server. \ - FreeRADIUS is an Internet authentication daemon, which implements \ - the RADIUS protocol, as defined in RFC 2865. It allows \ - Network Access Servers to perform authentication for dial-up users. -endef - -define QUALITY_AGENT_WHITELIST_RPATH - /usr/bin/ra* \ - /usr/lib/freeradius/* -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --libdir=/usr/lib/freeradius \ - --localstatedir=/var \ - --with-system-libtool \ - --with-threads \ - --with-thread-pool \ - --disable-ltdl-install \ - --with-gnu-ld \ - --without-rlm_eap_ikev2 \ - --without-rlm_sql_iodbc \ - --without-rlm_sql_firebird \ - --without-rlm_sql_db2 \ - --without-rlm_sql_oracle - - cd $(DIR_APP) && make LIBTOOL="libtool --tag=CC" #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - # Removing all static libraries and unneeded/broken stuff - rm -rf /usr/lib/freeradius/*.la /usr/lib/freeradius/rlm_perl-$(PKG_VER).so - - # PAM - cp -vf $(DIR_SOURCE)/pam.d/$(PKG_NAME) /etc/pam.d/ - - # Logrotate - cp -vf $(DIR_SRC)/src/logrotate/$(PKG_NAME) /etc/logrotate.d/ - - # Initscript - cp -vf $(DIR_SRC)/src/initscripts/extras/freeradius.conf /etc/init/ - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/freetype b/lfs/freetype deleted file mode 100644 index f8eac0f..0000000 --- a/lfs/freetype +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = freetype -PKG_VER = 2.3.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Graphics -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.freetype.org/ -LICENSE = FTL GPLv2+ -SHORT_DESC = A free and portable font rendering engine. - -define LONG_DESC - The FreeType engine is a free and portable font rendering \ - engine, developed to provide advanced font support for a variety of \ - platforms and environments. FreeType is a library which can open and \ - manages font files as well as efficiently load, hint and render \ - individual glyphs. FreeType is not a font server or a complete \ - text-rendering library. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - sed -i -r -e 's:.*(#.*BYTE.*) .*:\1:' \ - -e 's:.*(#.*SUBPIX.*) .*:\1:' \ - include/freetype/config/ftoption.h - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libfreetype.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/fuse b/lfs/fuse deleted file mode 100644 index ab9e406..0000000 --- a/lfs/fuse +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = fuse -PKG_VER = 2.7.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://fuse.sf.net/ -LICENSE = GPL+ -SHORT_DESC = File System in Userspace (FUSE) utilities. - -define LONG_DESC - With FUSE it is possible to implement a fully functional \ - filesystem in a userspace program. This package contains the \ - FUSE userspace tools to mount a FUSE filesystem. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - fuse-2.7.4-openfix.patch \ - fuse-2.7.4.-udev_rules.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-kernel-module \ - --disable-static -# cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/fuse-2.7.4-openfix.patch -# cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/fuse-2.7.4.-udev_rules.patch - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/lib{fuse,ulockmgr}.la \ - /etc/init.d/fuse - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gawk b/lfs/gawk deleted file mode 100644 index 011f856..0000000 --- a/lfs/gawk +++ /dev/null @@ -1,111 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gawk -PKG_VER = 3.1.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/gawk/gawk.html -LICENSE = GPLv3+ -SHORT_DESC = The GNU version of the awk text processing utility. - -define LONG_DESC - The gawk package contains the GNU version of awk, a text processing \ - utility. Awk interprets a special-purpose programming language to do \ - quick and easy text pattern matching and reformatting jobs. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ac_cv_func_working_mktime=yes \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --libexecdir=$(TOOLS_DIR)/lib - cd $(DIR_APP) && echo "#define HAVE_LANGINFO_CODESET 1" >> config.h - cd $(DIR_APP) && echo "#define HAVE_LC_MESSAGES 1" >> config.h - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ac_cv_func_working_mktime=yes \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libexecdir=/usr/lib - cd $(DIR_APP) && echo "#define HAVE_LANGINFO_CODESET 1" >> config.h - cd $(DIR_APP) && echo "#define HAVE_LC_MESSAGES 1" >> config.h - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gcc b/lfs/gcc deleted file mode 100644 index 2823f22..0000000 --- a/lfs/gcc +++ /dev/null @@ -1,263 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gcc -PKG_VER = 4.4.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -ifeq "$(STAGE)" "base" - OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) -else - OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP)-pass$(PASS) -endif - -MAINTAINER = -GROUP = Development/Compilers -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://gcc.gnu.org/ -LICENSE = GPLv3+ and GPLv2+ with exceptions -SHORT_DESC = Various compilers (C, C++, Objective-C, Java, ...). - -define LONG_DESC - The gcc package contains the GNU Compiler Collection. \ - You'll need this package in order to compile C code. -endef - -CFLAGS = -D__USE_XOPEN2K8 -pipe -CXXFLAGS = - -GMP = $(shell grep ^PKG_VER $(DIR_LFS)/gmp | awk '{ print $$3 }') -MPFR = $(shell grep ^PKG_VER $(DIR_LFS)/mpfr | awk '{ print $$3 }') - -ifneq "$(STAGE)" "base" -ifeq "$(MACHINE)" "i586" - CONFIGURE_ARGS = --disable-decimal-float -endif -endif - -ifeq "$(MACHINE)" "x86_64" - CONFIGURE_ARGS = --without-cloog --without-ppl --disable-multilib -endif - -ifneq "$(MACHINE)" "x86_64" - CONFIG_CPU = --with-cpu=$(MACHINE) --with-arch=$(MACHINE) -endif - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - gmp-$(GMP).tar.bz2 mpfr-$(MPFR).tar.bz2 \ - $(THISAPP)-espf-1.patch \ - $(THISAPP)-branch-startfiles-1.patch \ - $(THISAPP)-asprintf_fix.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) $(DIR_SRC)/gcc-build && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -mkdir -v $(DIR_SRC)/gcc-build - - # First, unpack gmp and mpfr. - # We use the build-"magic" of the gcc build system that we compile libgmp and - # libmpfr right (with -fPIC and so on). - cd $(DIR_APP) && $(EXTRACTOR) $(DIR_DL)/gmp-$(GMP).tar.bz2 - cd $(DIR_APP) && ln -svf gmp-* gmp - cd $(DIR_APP) && $(EXTRACTOR) $(DIR_DL)/mpfr-$(MPFR).tar.bz2 - cd $(DIR_APP) && ln -svf mpfr-* mpfr - - # Remove unneeded features that will save some compile time - rm -rf $(DIR_APP)/lib{gfortran,java,objc} \ - $(DIR_APP)/gcc/{fortran,java,objc,objcp} - - # Branding gcc - cd $(DIR_APP) && sed -e "s:PKGVERSION:"(GCC for $(NAME)-${VERSION}) ":" \ - -i gcc/version.c - -ifeq "$(STAGE)" "toolchain" -ifeq "$(PASS)" "1" - ## Enable -fPIC by default - cd $(DIR_APP) && sed 's/^(#define CC1_SPEC.*)(")$$/\1 %{fno-pic|fpic|fPIC:;:-fPIC}\2/' \ - -i gcc/config/i386/linux.h - cd $(DIR_APP) && sed 's/^(#define CC1_SPEC.*)(")$$/\1 %{fno-pic|fpic|fPIC:;:-fPIC}\2/' \ - -i gcc/config/i386/x86-64.h - - # libssp has no use with new versions of Glibc. Glibc completely replaces all - # functions in libssp, linking to libssp will cause conflicts with libc, so - # libssp is a waste of space... so --disable-libssp. - - cd $(DIR_SRC)/gcc-build && \ - CC="gcc -B/usr/bin/" \ - ../$(THISAPP)/configure \ - $(CONFIGURE_ARCH) \ - --target=$(IFS_TARGET) \ - $(CONFIG_CPU) \ - --prefix=$(TOOLS_DIR) \ - --with-local-prefix=$(TOOLS_DIR) \ - --libexecdir=$(TOOLS_DIR)/lib \ - --enable-languages=c \ - --enable-shared \ - --disable-nls \ - --disable-libssp \ - --disable-werror \ - --disable-static \ - $(CONFIGURE_ARGS) - - cd $(DIR_SRC)/gcc-build && make $(PARALLELISMFLAGS) - cd $(DIR_SRC)/gcc-build && make install - - ln -fvs gcc $(TOOLS_DIR)/bin/cc -endif - -ifeq "$(PASS)" "2" - # Enable hardening by default: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-espf-1.patch - - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-branch-startfiles-1.patch - - # This patch fixes a conflict between libiberty's asprintf() and Glibc's, when - # -D_FORTIFY_SOURCE=2 is used: - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-asprintf_fix.patch - - cd $(DIR_APP) && sed 's@./fixinc.sh@-c true@' -i gcc/Makefile.in - cd $(DIR_APP) && sed 's/^XCFLAGS =$$/& -fomit-frame-pointer/' -i gcc/Makefile.in - cd $(DIR_APP) && \ - for file in $$(find gcc/config -name linux64.h -o -name linux.h); do \ - cp -uv $$file{,.orig}; \ - sed -e 's@/lib(64)?(32)?/ld@$(TOOLS_DIR)&@g' \ - -e 's@/usr@$(TOOLS_DIR)@g' $$file.orig > $$file; \ - echo -e "\n#undef STANDARD_INCLUDE_DIR\n#define STANDARD_INCLUDE_DIR 0" >> $$file; \ - touch $$file.orig; \ - done - -ifeq "$(MACHINE)" "x86_64" - # Remove multilib options and searchpath (/lib... /usr/lib...) - cd $(DIR_APP) && echo "" > gcc/config/i386/t-linux64 - ## Enable -fPIC by default (why i have to do this again ???) - cd $(DIR_APP) && sed 's/^(#define CC1_SPEC.*)(")$$/\1 %{fno-pic|fpic|fPIC:;:-fPIC}\2/' \ - -i gcc/config/i386/x86-64.h -endif - - # Libgomp uses -Werror regardless of --disable-werror, and this will cause a - # build failure when -D_FORTIFY_SOURCE=2 causes build time warnings: - cd $(DIR_APP) && sed -e "s/-Werror//" -i libgomp/configure - - # We need to do another bootstrap, so that everything in $(TOOLS_DIR) is hardened. - cd $(DIR_SRC)/gcc-build && \ - ../$(THISAPP)/configure \ - $(CONFIGURE_ARCH) \ - --target=$(IFS_TARGET) \ - $(CONFIG_CPU) \ - --prefix=$(TOOLS_DIR) \ - --with-local-prefix=$(TOOLS_DIR) \ - --libexecdir=$(TOOLS_DIR)/lib \ - --enable-espf \ - --enable-clocale=gnu \ - --enable-shared \ - --enable-threads=posix \ - --enable-__cxa_atexit \ - --enable-languages=c,c++ \ - --disable-libstdcxx-pch \ - --disable-bootstrap \ - --disable-werror \ - --disable-libssp \ - --disable-nls \ - --disable-static \ - $(CONFIGURE_ARGS) - cd $(DIR_SRC)/gcc-build && make $(PARALLELISMFLAGS) - cd $(DIR_SRC)/gcc-build && make install -endif -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-espf-1.patch - - cd $(DIR_APP) && sed -i 's/install_to_$$(INSTALL_DEST) //' libiberty/Makefile.in - cd $(DIR_APP) && sed -i 's/^XCFLAGS =$$/& -fomit-frame-pointer/' gcc/Makefile.in - cd $(DIR_APP) && sed -i 's@./fixinc.sh@-c true@' gcc/Makefile.in - - # Libgomp uses -Werror regardless of --disable-werror, and this will cause a - # build failure when -D_FORTIFY_SOURCE=2 causes build time warnings: - cd $(DIR_APP) && sed -e "s/-Werror//" -i libgomp/configure - - cd $(DIR_SRC)/gcc-build && \ - ../$(THISAPP)/configure \ - $(CONFIGURE_ARCH) \ - --target=$(IFS_TARGET) \ - $(CONFIG_CPU) \ - --prefix=/usr \ - --libexecdir=/usr/lib \ - --enable-espf \ - --enable-shared \ - --enable-threads=posix \ - --enable-__cxa_atexit \ - --enable-clocale=gnu \ - --enable-languages=c,c++ \ - --disable-bootstrap \ - --disable-werror \ - --disable-libssp \ - --disable-static \ - $(CONFIGURE_ARGS) - - cd $(DIR_SRC)/gcc-build && make $(PARALLELISMFLAGS) - cd $(DIR_SRC)/gcc-build && make install - - rm -vf /usr/lib/lib{ffi,gomp,mudflap{,th},stdc++,supc++}.la - - ln -sfv ../usr/bin/cpp /lib - ln -sfv gcc /usr/bin/cc -endif - - @rm -rf $(DIR_APP) $(DIR_SRC)/gcc-build - @$(POSTBUILD) diff --git a/lfs/gdb b/lfs/gdb deleted file mode 100644 index 888e9f1..0000000 --- a/lfs/gdb +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gdb -PKG_VER = 6.8 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Debuggers -CORE = yes -EXTRA = no -DEBUG = yes -BUILD_DEPS = -DEPS = - -URL = http://gnu.org/software/gdb/ -LICENSE = GPLv3+ -SHORT_DESC = A GNU source-level debugger for C, C++, Java and other languages. - -define LONG_DESC - GDB, the GNU debugger, allows you to debug programs written in C, C++, \ - Java, and other languages, by executing them in a controlled fashion \ - and printing their data. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-werror \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gettext b/lfs/gettext deleted file mode 100644 index f94154b..0000000 --- a/lfs/gettext +++ /dev/null @@ -1,122 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gettext -PKG_VER = 0.17 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = #bison - -URL = http://www.gnu.org/software/gettext/ -LICENSE = GPLv3 LGPL2+ -SHORT_DESC = GNU libraries and utilities for producing multi-lingual messages. - -define LONG_DESC - The GNU gettext package provides a set of tools and documentation for \ - producing multi-lingual messages in programs. Tools include a set of \ - conventions about how programs should be written to support message \ - catalogs, a directory and file naming organization for the message \ - catalogs, a runtime library which supports the retrieval of translated \ - messages, and stand-alone programs for handling the translatable and \ - the already translated strings. Gettext provides an easy to use \ - library and tools for creating, using, and modifying natural language \ - catalogs and is a powerful and simple method for internationalizing \ - programs. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-open-args.patch \ - $(THISAPP)-rpathFix.patch \ - $(THISAPP)-automake-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-open-args.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-rpathFix.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-automake-1.patch - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP)/gettext-tools && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --disable-shared - cd $(DIR_APP)/gettext-tools && make -C gnulib-lib - cd $(DIR_APP)/gettext-tools && make -C src msgfmt - cd $(DIR_APP)/gettext-tools && cp -v src/msgfmt $(TOOLS_DIR)/bin -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/lib{asprintf,gettext{lib,po,src}}.la -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/ghostscript b/lfs/ghostscript deleted file mode 100644 index 5c556e5..0000000 --- a/lfs/ghostscript +++ /dev/null @@ -1,106 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = ghostscript -PKG_VER = 8.70 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Printing -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://ghostscript.com/releases/ -LICENSE = GPL -SHORT_DESC = An interpreter for the PostScript language and for PDF. - -define LONG_DESC -Ghostscript is a package of software that provides:\ -\ -* An interpreter for the PostScript (TM) language, with the ability to \ - convert PostScript language files to many raster formats, view them \ - on displays, and print them on printers that don't have PostScript \ - language capability built in; \ -* An interpreter for Portable Document Format (PDF) files, with the \ - same abilities; \ -* The ability to convert PostScript language files to PDF (with some \ - limitations) and vice versa; and \ -* A set of C procedures (the Ghostscript library) that implement the \ - graphics and filtering (data compression / decompression \ - / conversion) capabilities that appear as primitive operations in \ - the PostScript language and in PDF. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --without-omni - - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - chown -v root:root /usr/share/ghostscript/8.70/Resource/Font/* - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/glib2 b/lfs/glib2 deleted file mode 100644 index 7326f15..0000000 --- a/lfs/glib2 +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = glib -PKG_VER = 2.22.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = pkg-config -DEPS = pcre - -URL = http://www.gtk.org -LICENSE = LGPLv2+ -SHORT_DESC = A library of handy utility functions. - -define LONG_DESC - GLib is the low-level core library that forms the basis \ - for projects such as GTK+ and GNOME. It provides data structure \ - handling for C, portability wrappers, and interfaces for such runtime \ - functionality as an event loop, threads, dynamic loading, and an \ - object system. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --with-pcre=system - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cd $(DIR_APP) && ./mkinstalldirs /lib - cd /usr/lib && for name in glib gobject gmodule gthread gio; do \ - mv -v lib$${name}-2.0.so.* ../../lib; \ - ln -svf ../../lib/lib$${name}-2.0.so.*.* lib$${name}-2.0.so; \ - rm -vf /usr/lib/lib$${name}-2.0.la; \ - done - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/glib2-locale.sh /etc/profile.d/ - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/glibc b/lfs/glibc deleted file mode 100644 index 20fa682..0000000 --- a/lfs/glibc +++ /dev/null @@ -1,318 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = glibc -PKG_VER = 2.10.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://sources.redhat.com/glibc/ -LICENSE = GPLv2+ LGPLv2+ -SHORT_DESC = The GNU libc libraries. - -define LONG_DESC - The glibc package contains standard libraries which are used by \ - multiple programs on the system. In order to save disk space and \ - memory, as well as to make upgrading easier, common system code is \ - kept in one place and shared between programs. This particular package \ - contains the most important sets of shared libraries: the standard C \ - library and the standard math library. Without these two libraries, a \ - Linux system will not function. -endef - -CFLAGS = -O2 -fomit-frame-pointer -pipe -DPIC -fno-strict-aliasing \ - -mno-tls-direct-seg-refs -D_FORTIFY_SOURCE=2 -fstack-protector-all -CXXFLAGS = $(CFLAGS) - -OPTIMIZED_KERNEL = 2.6.18 - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-pt_pax-1.patch \ - $(THISAPP)-strlcpy_strlcat-1.patch \ - $(THISAPP)-asprintf_reset2null-1.patch \ - $(THISAPP)-issetugid-1.patch \ - $(THISAPP)-localedef_trampoline-1.patch \ - $(THISAPP)-sanitize_env.patch \ - $(THISAPP)-mktemp_urandom.patch \ - $(THISAPP)-res_randomid.patch \ - $(THISAPP)-resolv_response_length.patch \ - $(THISAPP)-undefine-__i686.patch \ - $(THISAPP)-arc4random.patch \ - $(THISAPP)-hardened-configure-picdefault.patch \ - $(THISAPP)-hardened-inittls-nosysenter.patch \ - $(THISAPP)-hardened-pie.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) $(DIR_SRC)/glibc-build && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - @mkdir $(DIR_SRC)/glibc-build - - # In the vi_VN.TCVN locale, bash enters an infinite loop at startup. It is - # unknown whether this is a bash bug or a Glibc problem. Disable - # installation of this locale in order to avoid the problem. - cd $(DIR_APP) && sed -i '/vi_VN.TCVN/d' localedata/SUPPORTED - - # The ldd shell script contains Bash-specific syntax. Change its default - # program interpreter to /bin/bash in case another /bin/sh is installed. - cd $(DIR_APP) && sed -i 's|@BASH@|/bin/bash|' elf/ldd.bash.in - - # The next patch modifies the localedef program so it does not use GCC - # Trampoline code (http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html), - # which relies on an executable stack to run. Without this patch the localedef - # program will be killed if it is run on a kernel with PaX memory protection. - # See http://pax.grsecurity.net/docs/pageexec.txt and - # http://pax.grsecurity.net/docs/segmexec.txt for more information: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-localedef_trampoline-1.patch - - # Support for PT_PaX markings: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-pt_pax-1.patch - - # The asprintf(3) and vasprintf(3) functions are GNU extentions, not defined - # by C or Posix standards. In Glibc these functions leave (char **strp) undefined - # after an error. This patch resets (char **strp) to NULL after an error, for - # sanity. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-asprintf_reset2null-1.patch - - # This patch adds the issetugid() function, which is a front-end to the - # __libc_enable_secure() dynamic linker private function. This function - # reports whether the program is running with matching real and effective - # ID's, or not, to determine whether the program is running with set-uid or - # set-gid privileges. Many packages will search for issetugid() and use it if - # found, such as Ncurses. This is safer than allowing each program to - # determine privileges itself because it is tested at a lower level which is - # not manipulatable by the user. Apply this patch with the following command: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-issetugid-1.patch - - # This patch resticts the environment, particularly with setuid programs: - #cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-sanitize_env.patch - - # This patch adds the strlcpy and strlcat functions and manual pages to Glibc. - # A paper written about these functions is available here: - # http://www.courtesan.com/todd/papers/strlcpy.html. The Glibc project has - # refused to add these functions, and that mail tread starts here: - # http://sources.redhat.com/ml/libc-alpha/2000-08/msg00052.html. Linus Torvalds - # has added a similar function to the Linux kernel, and that mail thread is - # here: http://lwn.net/Articles/33814/. The strlcpy() and strlcat() functions - # are replacements for strncpy() and strncat(). The controversy of these - # functions is that strlcpy() and strlcat() copy the source data to the - # destination buffer until the destination is full, and discards the rest of - # the data if there is any. This means that these functions will never - # overflow. The basis for the Glibc team's refusal to add these functions is - # that they silently hide programing errors, and they have a higher performance - # hit than strncpy() and strncat(). These functions should not be needed in a - # perfect world, but were invented to deal with the real world. Many packages - # will use these functions if they are found, such as Perl and many BLFS - # packages. These functions do reduce buffer overflows, and so they are - # recommended. After installing this patch no other effort is needed to use it. - # Packages will use autotools to detect whether they are available or not: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-strlcpy_strlcat-1.patch - - # The patch modifies __gen_tempname(), used by the mk*temp()/tmpnam() family - # of functions, to use /dev/urandom instead of hp-timing, gettimeofday(), or - # getpid(): - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-mktemp_urandom.patch - - # The res_randomid() function is a pseudo-random number generator, using - # getpid() for entropy. See: http://www.openbsd.org/advisories/res_random.txt - # for the vulnerability. This patch uses /dev/urandom instead: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-res_randomid.patch - - # This patch does a check on the buffer size of res_* functions: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-resolv_response_length.patch - - # We don't install pt_chown(1) on the final system, so why install it to - # $(TOOLS_DIR): - cd $(DIR_APP) && sed -e "/^install.*pt_chown/d" -i login/Makefile - - # ldconfig is statically linked, so don't build it PIC: - cd $(DIR_APP) && sed "s/CFLAGS-ldconfig.c =/& -fno-PIC -fno-PIE/" \ - -i elf/Makefile - - # Build nscd with -fstack-protector-all, instead of -fstack-protector: - cd $(DIR_APP) && sed -e "s/fstack-protector/&-all/" -i nscd/Makefile - - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-arc4random.patch - - # We don't need to set -march=i?86 in confparams because GCC was built with - # --with-arch=i?86. -ifeq "$(MACHINE)" "i686" - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-undefine-__i686.patch -endif - - # Some hardening patches - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-hardened-pie.patch - cd $(DIR_APP) && patch -Np0 -i \ - $(DIR_PATCHES)/$(THISAPP)-hardened-configure-picdefault.patch - cd $(DIR_APP) && patch -Np0 -i \ - $(DIR_PATCHES)/$(THISAPP)-hardened-inittls-nosysenter.patch - - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/$(THISAPP)-stack_chk_fail.c \ - $(DIR_APP)/debug/stack_chk_fail.c - - # --sbindir=$(TOOLS_DIR)/bin does not work... anyone want to fix this? - # We don't need Glibc's sbin programs, but still. - - # --enable-stackguard-randomization could be added here, but this is primarily - # for attacks by local users, and we shouldn't have those in the rebooted - # system. Adding this will empty the /dev/random entropy pool (via - # /dev/urandom), unless the system is running a Random Number Gathering Daemon - # (rngd). This version of Glibc uses high precision timing with SSP, so the - # canary value changes at run-time. This is not as good as /dev/urandom, but - # it's better than nothing and has very good performance. - -ifeq "$(STAGE)" "toolchain" - # Glibc uses a hard coded path for /etc/ld.so.preload. To keep Glibc from - # preloading libraries from the host machine perform the following command: - cd $(DIR_APP) && sed -e "s@/etc/ld.so.preload@$(TOOLS_DIR)@" -i elf/rtld.c - -mkdir -v $(TOOLS_DIR)/etc - touch $(TOOLS_DIR)/etc/ld.so.conf - - cd $(DIR_SRC)/glibc-build && \ - CFLAGS= \ - CXXFLAGS= \ - ../$(THISAPP)/configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --libexecdir=$(TOOLS_DIR)/lib/$(PKG_NAME) \ - --with-headers=$(TOOLS_DIR)/include \ - --with-binutils=$(TOOLS_DIR)/bin \ - --disable-profile \ - --enable-add-ons \ - --enable-kernel=$(OPTIMIZED_KERNEL) \ - --without-selinux \ - --without-gd \ - --enable-bind-now \ - --enable-stackguard-randomization -endif - -ifeq "$(STAGE)" "base" - if [ ! -e /bin/pwd ]; then ln -sfn $(TOOLS_DIR)/bin/pwd /bin/pwd; fi - cd $(DIR_APP) && sed 's/-nostdlib/& -fno-stack-protector/g' -i.orig configure - cd $(DIR_APP) && sed -i 's|libs -o|libs -L/usr/lib -Wl,-dynamic-linker=$(LINKER) -o|' \ - scripts/test-installation.pl - touch /etc/ld.so.conf - - cd $(DIR_SRC)/glibc-build && \ - CFLAGS= \ - CXXFLAGS= \ - ../$(THISAPP)/configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libexecdir=/usr/lib/glibc \ - --disable-profile \ - --enable-add-ons \ - --enable-kernel=$(OPTIMIZED_KERNEL) \ - --without-selinux \ - --disable-werror \ - --enable-bind-now \ - --enable-stackguard-randomization \ - --with-stack-protector=all \ - --enable-omitfp -endif - - # Our GCC is already passing -fPIC, and that's all we want for the libraries. - # LDFLAGS.so is appended to so we don't build shared libraries with - # DT_TEXTREL (and to tell us if something goes wrong). For now we only build - # the libraries, not the programs: - echo "build-programs=no" \ - >> $(DIR_SRC)/glibc-build/configparms - cd $(DIR_SRC)/glibc-build && make PARALLELMFLAGS=$(PARALLELISMFLAGS) \ - CFLAGS="-O2 -DPIC -fno-stack-protector -U_FORTIFY_SOURCE" \ - CXXFLAGS="-O2 -DPIC -fno-stack-protector -U_FORTIFY_SOURCE" - - # Then build the programs with hardening, so everything possible in - # $(TOOLS_DIR) is hardened: - echo "CFLAGS = $(CFLAGS)" > $(DIR_SRC)/glibc-build/configparms - echo "CXXFLAGS = $(CXXFLAGS)" >> $(DIR_SRC)/glibc-build/configparms - cd $(DIR_SRC)/glibc-build && make PARALLELMFLAGS=$(PARALLELISMFLAGS) \ - CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" - cd $(DIR_SRC)/glibc-build && make install - -ifeq "$(STAGE)" "base" - install -vd /usr/lib/static/ - mv -v /usr/lib/{libbsd-compat,libg,libieee,libmcheck}.a /usr/lib/static/ - mv -v /usr/lib/{libBrokenLocale,libanl,libcrypt}.a /usr/lib/static/ - mv -v /usr/lib/{libm,libnsl,libpthread,libresolv}.a /usr/lib/static/ - mv -v /usr/lib/{librpcsvc,librt,libutil}.a /usr/lib/static/ - - rm -vf {/usr,}/lib/*_g.a - - # Locales - -mkdir -pv /usr/lib/locale - # This would install all locales that are supported, but we do only - # install a minimal set of them - #cd $(DIR_SRC)/glibc-build && make localedata/install-locales - cd $(DIR_SRC)/glibc-build && localedef -i de_DE -f UTF-8 de_DE.UTF-8 - cd $(DIR_SRC)/glibc-build && localedef -i en_US -f UTF-8 en_US.UTF-8 - cd $(DIR_SRC)/glibc-build && localedef -i da_DK -f UTF-8 da_DK.UTF-8 - - # Timezone - cp -v --remove-destination /usr/share/zoneinfo/GMT /etc/localtime - - # Configuration - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/{ld.so.conf,nsswitch.conf} /etc - - if [ -h /bin/pwd ]; then rm -f /bin/pwd; fi -endif - - @rm -rf $(DIR_APP) $(DIR_SRC)/glibc-build - @$(POSTBUILD) diff --git a/lfs/gmp b/lfs/gmp deleted file mode 100644 index c24d0c1..0000000 --- a/lfs/gmp +++ /dev/null @@ -1,106 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gmp -PKG_VER = 4.3.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://gmplib.org/ -LICENSE = LGPLv3+ -SHORT_DESC = A GNU arbitrary precision library. - -define LONG_DESC - The gmp package contains GNU MP, a library for arbitrary precision \ - arithmetic, signed integers operations, rational numbers and floating \ - point numbers. GNU MP is designed for speed, for both small and very \ - large operands. GNU MP is fast because it uses fullwords as the basic \ - arithmetic type, it uses fast algorithms, it carefully optimizes \ - assembly code for many CPUs' most common inner loops, and it generally \ - emphasizes speed over simplicity/elegance in its operations. -endef - -ifeq "$(MACHINE)" "x86_64" - ABI = 64 -else - ABI = 32 -endif -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && ABI=$(ABI) \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-cxx \ - --enable-mpbsd \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libgmp{,xx}.la /usr/lib/libmp.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gnupg2 b/lfs/gnupg2 deleted file mode 100644 index 488f8d4..0000000 --- a/lfs/gnupg2 +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gnupg -PKG_VER = 2.0.12 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Security/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = curl libassuan libgcrypt libksba pinentry pth - -URL = http://www.gnupg.org/ -LICENSE = GPLv3+ -SHORT_DESC = Utility for secure communication and data storage. - -define LONG_DESC - The GnuPG 2 package is GNU's tool for secure communication and data \ - storage. It can be used to encrypt data and to create digital signatures. \ - It includes an advanced key management facility and is compliant with the \ - proposed OpenPGP Internet standard as described in RFC2440 and the S/MIME \ - standard as described by several RFCs. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - @rm -rf /home/nobody/.gnupg /root/.gnupg - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libexecdir=/usr/lib/gnupg2 - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gnutls b/lfs/gnutls deleted file mode 100644 index 2846981..0000000 --- a/lfs/gnutls +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gnutls -PKG_VER = 2.8.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libgcrypt - -URL = http://www.gnu.org/software/gnutls/ -LICENSE = LGPLv2.1+ -SHORT_DESC = A general-purpose cryptography library. - -define LONG_DESC - GnuTLS is a project that aims to develop a library which provides \ - a secure layer, over a reliable transport layer. Currently the \ - GnuTLS library implements the proposed standards by the IETF's \ - TLS working group. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static \ - --with-included-libcfg \ - --disable-srp-authentication \ - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -fv /usr/lib/libgnutls*.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gobject-introspection b/lfs/gobject-introspection deleted file mode 100644 index 61dba59..0000000 --- a/lfs/gobject-introspection +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gobject-introspection -PKG_VER = 0.6.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://live.gnome.org/GObjectIntrospection -LICENSE = GPLv2+, LGPLv2+, MIT -SHORT_DESC = Introspection system for GObject-based libraries. - -define LONG_DESC - GObject Introspection can scan C header and source files in order \ - to generate introspection "typelib" files. It also provides an API to \ - examine typelib files, useful for creating language bindings among \ - other things. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sbindir=/sbin \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - # Removing static libraries - rm -rf /usr/lib/gobject-introspection/giscanner/*.la - rm -rf /usr/lib/libgirepository-*.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gperf b/lfs/gperf deleted file mode 100644 index f22c826..0000000 --- a/lfs/gperf +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gperf -PKG_VER = 3.0.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Tools -CORE = yes -EXTRA = no -DEBUG = no -DEPS = -BUILD_DEPS = - -URL = http://www.gnu.org/software/gperf/ -LICENSE = GPLv2+ -SHORT_DESC = A perfect hash function generator. - -define LONG_DESC - Gperf is a perfect hash function generator written in C++. Simply \ - stated, a perfect hash function is a hash function and a data \ - structure that allows recognition of a key word in a set of words \ - using exactly one probe into the data structure. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/grep b/lfs/grep deleted file mode 100644 index e783f09..0000000 --- a/lfs/grep +++ /dev/null @@ -1,110 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = grep -PKG_VER = 2.5.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - - -MAINTAINER = -GROUP = Applications/Text -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/grep/ -LICENSE = GPLv3+ -SHORT_DESC = A pattern matching utilities. - -define LONG_DESC - The GNU versions of commonly used grep utilities. Grep searches through \ - textual input for lines which contain a match to a specified pattern and then \ - prints the matching lines. GNU's grep utilities include grep, egrep and fgrep. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - # --without-included-regex makes Grep use libc for regex. This gets rid of - # some compiler warnings, and I can't imagine why it's unsafe. - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --disable-perl-regexp \ - --without-included-regex - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/bin \ - --without-included-regex - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/groff b/lfs/groff deleted file mode 100644 index 5ca9c0d..0000000 --- a/lfs/groff +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = groff -PKG_VER = 1.18.1.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Text -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://groff.ffii.org/ -LICENSE = GPLv2 and GFDL -SHORT_DESC = A document formatting system. - -define LONG_DESC - Groff is a document formatting system. Groff takes standard text and \ - formatting commands as input and produces formatted output. The \ - created documents can be shown on a display or printed on a printer. \ - Groff's formatting commands allow you to specify font type and size, \ - bold type, italic type, the number and size of columns on a page, and \ - more. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-debian_fixes-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-debian_fixes-1.patch - cd $(DIR_APP) && sed -i -e 's/2010/002D/' -e 's/2212/002D/' \ - -e 's/2018/0060/' -e 's/2019/0027/' font/devutf8/R.proto - cd $(DIR_APP) && PAGE=A4 \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-multibyte - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - ln -sv eqn /usr/bin/geqn - ln -sv tbl /usr/bin/gtbl - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/grub b/lfs/grub deleted file mode 100644 index 2da93b4..0000000 --- a/lfs/grub +++ /dev/null @@ -1,155 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = grub -PKG_VER = 0.97 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Boot -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/grub/ -LICENSE = GPLv2+ -SHORT_DESC = Grand Unified Boot Loader. - -define LONG_DESC - GRUB (Grand Unified Boot Loader) is an experimental boot loader \ - capable of booting into most free operating systems - Linux, FreeBSD, \ - NetBSD, GNU Mach, and others as well as most commercial operating \ - systems. -endef - -define QUALITY_AGENT_WHITELIST_EXECSTACK - /usr/sbin/grub -endef - -CFLAGS = -Os -g -fno-strict-aliasing -fno-stack-protector -fno-pic -fno-pie -nopie -CXXFLAGS = - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - grub-0.94-i2o.patch \ - grub-0.95-moreraid.patch \ - grub-0.93-special-device-names.patch \ - grub-0.95-splash-error-term.patch \ - grub-0.95-xpmjunk.patch \ - grub-0.93-graphics-bootterm.patch \ - grub-0.91-splashimagehelp.patch \ - grub-0.95-graphics.patch \ - $(THISAPP)-disk_geometry-1.patch \ - grub-0.93-configfile.patch \ - $(THISAPP)-256byte_inode-1.patch \ - grub-0.94-installcopyonly.patch \ - $(THISAPP)-install.in.patch \ - $(THISAPP)-ext4-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-disk_geometry-1.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.95-graphics.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.91-splashimagehelp.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.93-graphics-bootterm.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.95-xpmjunk.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.95-splash-error-term.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.93-special-device-names.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.95-moreraid.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.94-i2o.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.93-configfile.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-256byte_inode-1.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-install.in.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/grub-0.94-installcopyonly.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-ext4-1.patch - - cd $(DIR_APP) && autoconf - - cd $(DIR_APP) && \ - grub_cv_prog_objcopy_absolute=yes \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - - cd $(DIR_APP) && make -j $(PRALLELISMFLAGS) - cd $(DIR_APP) && make install - - sed -e "s/pkgdatadir/pkglibdir/g" -i /usr/sbin/grub-install - - mkdir -vp /boot/grub - - for i in $(DIR_SOURCE)/bootloader/{grub.conf,splash.xpm.gz}; do \ - [ -f $$i ] && cp -vf $$i /boot/grub; \ - done - -ifeq "$(EMB)" "1" - # Enable serial console on embedded build - sed -e "s/^#serial/serial/" \ - -e "s/@SERIAL@/console=ttyS0,9600n8/g" \ - -i /boot/grub/grub.conf -else - # Remove the placeholder @SERIAL@ on non-embedded build - sed -e "s/@SERIAL@//g" \ - -i /boot/grub/grub.conf -endif - - # Grub uses anonymous mapping and will be killed by PaX. - # The following command changes Grub's PaX flags: - paxctl -spme /usr/sbin/grub - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gssdp b/lfs/gssdp deleted file mode 100644 index eacbc0f..0000000 --- a/lfs/gssdp +++ /dev/null @@ -1,89 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gssdp -PKG_VER = 0.7.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = libsoup -DEPS = libsoup glib2 - -URL = http://www.gupnp.org -LICENSE = LGPL -SHORT_DESC = GSSDP implements resource discovery and announcement over SSDP. - -define LONG_DESC - GSSDP implements resource discovery and announcement over SSDP. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gupnp b/lfs/gupnp deleted file mode 100644 index aa7e2ac..0000000 --- a/lfs/gupnp +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gupnp -PKG_VER = 0.13.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = libsoup glib2 gssdp libxml2 -DEPS = libsoup glib2 gssdp libxml2 - -URL = http://www.gupnp.org -LICENSE = LGPL -SHORT_DESC = upnp Framework - -define LONG_DESC - GUPnP is an object-oriented open source framework for creating UPnP\ - devices and control points, written in C using GObject and libsoup.\ - The GUPnP API is intended to be easy to use, efficient and flexible. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --without-gnome - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gupnp-av b/lfs/gupnp-av deleted file mode 100644 index 743e85a..0000000 --- a/lfs/gupnp-av +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gupnp-av -PKG_VER = 0.5.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = gssdp gupnp - -URL = http://www.gupnp.org -LICENSE = LGPL -SHORT_DESC = gupnp audio/video helpers - -define LONG_DESC - GUPnP-AV is a collection of helpers for building AV (audio/video) \ - applications using GUPnP. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --without-gnome - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gupnp-igd b/lfs/gupnp-igd deleted file mode 100644 index 70c9eb8..0000000 --- a/lfs/gupnp-igd +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gupnp-igd -PKG_VER = 0.1.3 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = libsoup gssdp gupnp - -URL = http://www.gupnp.org -LICENSE = LGPL -SHORT_DESC = gupnp - Internet Gateway device implementation (Microsoft) - -define LONG_DESC - This is a library to handle Internet Gateway Device port mappings. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --without-gnome - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gupnp-media-server b/lfs/gupnp-media-server deleted file mode 100644 index 3096d51..0000000 --- a/lfs/gupnp-media-server +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gupnp-media-server -PKG_VER = 0.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = gssdp gupnp gupnp-av libowl-av libgconf - -################ -##### TODO ##### cannot resolve dependency to libgconf :-( -################ - -URL = http://www.gupnp.org -LICENSE = LGPL -SHORT_DESC = gupnp-media-server - -define LONG_DESC - This is a reference implementation of the MediaRenderer version 1 \ - device type, written in Vala. libowl-av is used for rendering. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/gzip b/lfs/gzip deleted file mode 100644 index 4e7992f..0000000 --- a/lfs/gzip +++ /dev/null @@ -1,124 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = gzip -PKG_VER = 1.3.13 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Compression -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gzip.org/ -LICENSE = GPLv2 -SHORT_DESC = The GNU data compression program. - -define LONG_DESC - The gzip package contains the popular GNU gzip data compression \ - program. Gzipped files have a .gz extension. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-openbsd-owl-tmp.patch \ - $(THISAPP)-cve-2006-4337_len.patch \ - $(THISAPP)-cve-2006-4338.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # This patch modifies 'znew' so we don't use temporary files: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-openbsd-owl-tmp.patch - - # Fix CVE 2006-4337 - # (http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-4337) and - # CVE 2006-4338 (http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-4338), - # against malformed gzip files: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-cve-2006-4337_len.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-cve-2006-4338.patch - -ifeq "$(STAGE)" "toolchain" - # NO_ASM is for textrels. - cd $(DIR_APP) && \ - DEFS=NO_ASM \ - CPPFLAGS="-DHAVE_LSTAT" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - # NO_ASM is for textrels. - cd $(DIR_APP) && \ - DEFS=NO_ASM \ - CPPFLAGS="-DHAVE_LSTAT" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/bin - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - mv -v /bin/{gzexe,uncompress,zcmp,zdiff,zegrep} /usr/bin - mv -v /bin/{zfgrep,zforce,zgrep,zless,zmore,znew} /usr/bin -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/hal b/lfs/hal deleted file mode 100644 index ae9aa20..0000000 --- a/lfs/hal +++ /dev/null @@ -1,102 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = hal -PKG_VER = 0.5.13 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Daemons -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = dbus-glib parted pciutils perl-xml-parser python usbutils - -URL = http://www.freedesktop.org/Software/hal -LICENSE = AFL or GPLv2 -SHORT_DESC = Hardware Abstraction Layer. - -define LONG_DESC - HAL is daemon for collection and maintaining information from several \ - sources about the hardware on the system. -endef - -INITSCRIPT = haldaemon - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --libexecdir=/usr/lib/hal \ - --localstatedir=/var \ - --with-udev-prefix=/etc \ - --disable-policy-kit \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libhal{,-storage}.la - - -mv -v /etc/udev/rules.d/90-hal.rules /lib/udev/rules.d/ - $(INSTALL_INITSCRIPT) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/hal-info b/lfs/hal-info deleted file mode 100644 index 56d84bf..0000000 --- a/lfs/hal-info +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = hal-info -PKG_VER = 20081219 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = hal - -URL = http://www.freedesktop.org/Software/hal/ -LICENSE = AFL or GPLv2 -SHORT_DESC = Device information files for HAL. - -define LONG_DESC - The hal-info package contains various device information files (also \ - known as .fdi files) for the hal package. -endef -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --libexecdir=/usr/lib/hal \ - --localstatedir=/var - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/hdparm b/lfs/hdparm deleted file mode 100644 index bdc2bb2..0000000 --- a/lfs/hdparm +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = hdparm -PKG_VER = 9.22 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Hardware -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://sourceforge.net/projects/hdparm/ -LICENSE = BSD -SHORT_DESC = A utility for displaying and/or setting hard disk parameters. - -define LONG_DESC - Hdparm is a useful system utility for setting (E)IDE hard drive \ - parameters. For example, hdparm can be used to tweak hard drive \ - performance and to spin down hard drives for power conservation. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && sed -i -e "s/-O2/$(CFLAGS)/g" Makefile - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make binprefix=/usr/ install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/hostapd b/lfs/hostapd deleted file mode 100644 index 86252e8..0000000 --- a/lfs/hostapd +++ /dev/null @@ -1,89 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = hostapd -PKG_VER = 0.6.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = libnl -DEPS = - -URL = http://hostap.epitest.fi/hostapd/ -LICENSE = GPLv2+ -SHORT_DESC = User space daemon to create Wifi Access points. - -define LONG_DESC - Hostapd is a user space daemon for access point and authentication \ - servers. It implements IEEE 802.11 access point management, IEEE \ - 802.1X/WPA/WPA2/EAP Authenticators, RADIUS client, EAP server, and \ - RADIUS authentication server. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP)/hostapd && cp $(DIR_SRC)/src/hostapd/config ./.config - cd $(DIR_APP)/hostapd && sed -e "s@/usr/local@/usr@g" -i Makefile - cd $(DIR_APP)/hostapd && make $(PARALLELISMFLAGS) - cd $(DIR_APP)/hostapd && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/hplip b/lfs/hplip deleted file mode 100644 index 07938da..0000000 --- a/lfs/hplip +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = hplip -PKG_VER = 3.9.8 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Printing -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://hplipopensource.com/hplip-web/index.html -LICENSE = GPLv2+ -SHORT_DESC = HP Printer/Scanner Library (full version) - -define LONG_DESC - HPLIP (Hewlett-Packard Linux Imaging & Printing) is an HP-developed \ - solution for printing, scanning, and faxing with HP inkjet and laser based \ - printers in Linux. The HPLIP project provides printing support for 1,924 \ - printer models. \ - This is the full version including printer/scanner support. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/htop b/lfs/htop deleted file mode 100644 index ea890a3..0000000 --- a/lfs/htop +++ /dev/null @@ -1,89 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = htop -PKG_VER = 0.8.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://htop.sourceforge.net/ -LICENSE = GPL+ -SHORT_DESC = Interactive process viewer. - -define LONG_DESC - htop is an interactive text-mode process viewer for Linux, similar to \ - top(1). -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/iana-etc b/lfs/iana-etc deleted file mode 100644 index 40092ba..0000000 --- a/lfs/iana-etc +++ /dev/null @@ -1,86 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = iana-etc -PKG_VER = 2.30 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.iana.org/ -LICENSE = -SHORT_DESC = The Internet Assigned Numbers Authority. - -define LONG_DESC - The Internet Assigned Numbers Authority (IANA) is responsible for the \ - global coordination of the DNS Root, IP addressing, and other Internet \ - protocol resources. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/icecc b/lfs/icecc deleted file mode 100644 index 76c93d0..0000000 --- a/lfs/icecc +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = icecream -PKG_VER = 0.9.4.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Compilers -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = e2fsprogs -DEPS = - -URL = http://git.ipfire.org/?p=thirdparty/icecream.git;a=summary -LICENSE = GPLv2+ -SHORT_DESC = A distributed C/C++ compiler based on distcc. - -define LONG_DESC - A distributed C/C++ compiler with a central server (called scheduler) \ - that gets out the best server of the pool. Icecc is based on distcc. -endef - -PREFIX = $(TOOLS_DIR)/usr -CFLAGS := $(subst -fPIC,,$(CFLAGS)) -static -CXXFLAGS := $(subst -fPIC,,$(CXXFLAGS)) -static - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - CFLAGS="$(CFLAGS)" \ - CXXFLAGS="$(CXXFLAGS)" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(PREFIX) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/images-core b/lfs/images-core deleted file mode 120000 index 5e798fa..0000000 --- a/lfs/images-core +++ /dev/null @@ -1 +0,0 @@ -images \ No newline at end of file diff --git a/lfs/images-info b/lfs/images-info deleted file mode 120000 index 5e798fa..0000000 --- a/lfs/images-info +++ /dev/null @@ -1 +0,0 @@ -images \ No newline at end of file diff --git a/lfs/images-initramfs b/lfs/images-initramfs deleted file mode 120000 index 5e798fa..0000000 --- a/lfs/images-initramfs +++ /dev/null @@ -1 +0,0 @@ -images \ No newline at end of file diff --git a/lfs/images-overlays b/lfs/images-overlays deleted file mode 120000 index 5e798fa..0000000 --- a/lfs/images-overlays +++ /dev/null @@ -1 +0,0 @@ -images \ No newline at end of file diff --git a/lfs/initscripts b/lfs/initscripts deleted file mode 100644 index 73d9b85..0000000 --- a/lfs/initscripts +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = initscripts -PKG_VER = -PKG_REL = 0 - -THISAPP = $(PKG_NAME) -DIR_APP = $(DIR_SOURCE)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Boot -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = coreutils e2fsprogs module-init-tools procps sysvinit system-release \ - upstart util-linux-ng - -URL = -LICENSE = GPLv2+ -SHORT_DESC = The set of scripts that initalize the system. - -define LONG_DESC - The initscripts package contains the basic system scripts used to boot \ - your system and shut the system down cleanly. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - cd $(DIR_APP)/src && make clean - - cd $(DIR_APP)/src && make $(PARALLELISMFLAGS) - cd $(DIR_APP)/src && make install - - install -d -m 755 /etc/init - install -d -m 755 /etc/sysconfig - - for i in $(DIR_APP)/core/*; do \ - install -v -m 644 $$i /etc/init/; \ - done - - for i in $(DIR_SRC)/src/initscripts/sysconfig/*; do \ - install -v -m 644 $$i /etc/sysconfig/; \ - done - chmod -v 755 /etc/sysconfig/rc.local - - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/etc/sysctl.conf /etc - - cd $(DIR_APP)/src && make clean - @$(POSTBUILD) diff --git a/lfs/intltool b/lfs/intltool deleted file mode 100644 index 88e7b12..0000000 --- a/lfs/intltool +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = intltool -PKG_VER = 0.40.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Localization/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = gettext perl-xml-parser - -URL = http://www.gnome.org/ -LICENSE = GPLv2 with exceptions -SHORT_DESC = Utility for internationalizing various kinds of data files. - -define LONG_DESC - This tool automatically extracts translatable strings from oaf, glade, \ - bonobo ui, nautilus theme, .desktop, and other data files and puts \ - them in the po files. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/iproute2 b/lfs/iproute2 deleted file mode 100644 index 64727d7..0000000 --- a/lfs/iproute2 +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = iproute2 -PKG_VER = 2.6.29-1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = bison flex - -URL = http://www.linuxfoundation.org/en/Net:Iproute2 -LICENSE = GPLv2+ -SHORT_DESC = Advanced IP routing and network device configuration tools. - -define LONG_DESC - The iproute package contains networking utilities (ip and rtmon, for \ - example) which are designed to use the advanced networking \ - capabilities of the Linux 2.4.x and 2.6.x kernel. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-opt_flags.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np2 -i $(DIR_PATCHES)/$(THISAPP)-opt_flags.patch - cd $(DIR_APP) && sed -i -e "s@DESTDIR=.*@DESTDIR=@" \ - -e "s@/share/@/usr/share/@g" Makefile - cd $(DIR_APP) && make OPT_FLAGS="$(CFLAGS)" #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cd $(DIR_APP) && mv -v /sbin/arpd /usr/sbin - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/iptables b/lfs/iptables deleted file mode 100644 index 795c5f1..0000000 --- a/lfs/iptables +++ /dev/null @@ -1,128 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = iptables -PKG_VER = 1.4.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.netfilter.org/ -LICENSE = GPL+ -SHORT_DESC = Tools for managing Linux kernel packet filtering capabilities. - -define LONG_DESC - The iptables utility controls the network packet filtering code in the \ - Linux kernel. If you need to set up firewalls and/or IP masquerading, \ - you should install this package. -endef - -define QUALITY_AGENT_WHITELIST_SONAME - /lib/xtables/* -endef - -CFLAGS += -fno-strict-aliasing - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) #$(THISAPP)-imq-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - #cd $(DIR_APP) && patch -Np1 < $(DIR_PATCHES)/$(THISAPP)-imq-1.patch - - # Make more space for target name on output. - cd $(DIR_APP) && sed -e "s/%-9s/%-18s/g" -i ip{,6}tables.c - - cd $(DIR_APP) && ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/bin \ - --sbindir=/sbin \ - --libdir=/lib \ - --libexecdir=/lib \ - --sysconfdir=/etc \ - --mandir=/usr/share/man \ - --with-kernel=/usr \ - --with-kbuild=/usr \ - --with-ksource=/usr \ - --enable-devel \ - --enable-libipq - - # Remove rpath - cd $(DIR_APP) && sed -i libtool \ - -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ - -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /lib/lib{iptc,xtables,ip4tc,ip6tc}.la - - # install ip*tables.h header files - cd $(DIR_APP) && install -v -m 644 include/ip{,6}tables.h /usr/include - cd $(DIR_APP) && install -v -d /usr/include/iptables - cd $(DIR_APP) && install -v -m 644 include/iptables/internal.h /usr/include/iptables/ - cd $(DIR_APP) && install -v -d /usr/include/libiptc - cd $(DIR_APP) && install -v -m 644 include/libiptc/*.h /usr/include/libiptc - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/iputils b/lfs/iputils deleted file mode 100644 index 8e90ce7..0000000 --- a/lfs/iputils +++ /dev/null @@ -1,133 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = iputils -PKG_VER = s20071127 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.skbuff.net/iputils -LICENSE = BSD -SHORT_DESC = Network monitoring tools including ping. - -define LONG_DESC - The iputils package contains basic utilities for monitoring a network, \ - including ping. The ping command sends a series of ICMP protocol \ - ECHO_REQUEST packets to a specified network host to discover whether \ - the target machine is alive and receiving network traffic. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - ifenslave-20090202.tar.gz \ - $(THISAPP)-addrcache.patch \ - $(THISAPP)-arping-infiniband.patch \ - $(THISAPP)-arping_timeout.patch \ - $(THISAPP)-countermeasures.patch \ - $(THISAPP)-idn.patch \ - $(THISAPP)-open-max.patch \ - $(THISAPP)-output.patch \ - $(THISAPP)-ping-subint.patch \ - $(THISAPP)-ping_cleanup.patch \ - $(THISAPP)-rh.patch \ - $(THISAPP)-traffic_class.patch \ - $(THISAPP)-warnings.patch \ - iputils-ifenslave-20090202.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && $(EXTRACTOR) $(DIR_DL)/ifenslave-20090202.tar.gz - - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-addrcache.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-arping-infiniband.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-arping_timeout.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-countermeasures.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-idn.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-open-max.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-ping-subint.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-ping_cleanup.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-rh.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-traffic_class.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-warnings.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-output.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/iputils-ifenslave-20090202.patch - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && gcc -Wall $(CLFAGS) ifenslave.c -o ifenslave - - cd $(DIR_APP) && install -cp clockdiff /usr/sbin/ - cd $(DIR_APP) && install -cp arping /sbin/ - cd $(DIR_APP) && install -cp ifenslave /sbin/ - cd $(DIR_APP) && install -cp ping /bin/ - cd $(DIR_APP) && install -cp rdisc /sbin/ - cd $(DIR_APP) && install -cp ping6 /bin/ - cd $(DIR_APP) && install -cp tracepath /bin/ - cd $(DIR_APP) && install -cp tracepath6 /bin/ - ln -svf ../../sbin/arping /usr/sbin/arping - ln -svf ../../bin/ping6 /usr/sbin/ - ln -svf ../../bin/tracepath /usr/sbin/ - ln -svf ../../bin/tracepath6 /usr/sbin/ - - setcap cap_net_admin=ep /bin/ping - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/iw b/lfs/iw deleted file mode 100644 index 110377e..0000000 --- a/lfs/iw +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = iw -PKG_VER = 0.9.17 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libnl - -URL = http://www.linuxwireless.org/en/users/Documentation/iw -LICENSE = BSD -SHORT_DESC = A nl80211 based wireless configuration tool. - -define LONG_DESC - iw is a new nl80211 based CLI configuration utility for wireless \ - devices. Currently you can only use this utility to configure devices \ - which use a mac80211 driver as these are the new drivers being written \ - - only because most new wireless devices being sold are now SoftMAC. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-default-install-to-PREFIX-sbin.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) $$ patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-default-install-to-PREFIX-sbin.patch - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - mv -v /usr/bin/iw /sbin/ - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/joe b/lfs/joe deleted file mode 100644 index 9a2bc64..0000000 --- a/lfs/joe +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = joe -PKG_VER = 3.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Editors -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://joe-editor.sourceforge.net/ -LICENSE = GPLv2+ -SHORT_DESC = A small text editor similar to wordstar in matter of usage. - -define LONG_DESC - Joe is a small and friendly text editor which provides the look \ - and feel of the good old wordstar. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/jwhois b/lfs/jwhois deleted file mode 100644 index 600ea35..0000000 --- a/lfs/jwhois +++ /dev/null @@ -1,122 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = jwhois -PKG_VER = 4.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Internet -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/jwhois/ -LICENSE = GPLv3 -SHORT_DESC = Internet whois/nicname client. - -define LONG_DESC - A whois client that accepts both traditional and finger-style queries. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-conf.patch \ - $(THISAPP)-conf_update.patch \ - $(THISAPP)-conf_update2.patch \ - $(THISAPP)-conf_update3.patch \ - $(THISAPP)-conf_update4.patch \ - $(THISAPP)-connect.patch \ - $(THISAPP)-dotster.patch \ - $(THISAPP)-enum.patch \ - $(THISAPP)-fclose.patch \ - $(THISAPP)-gi.patch \ - $(THISAPP)-ipv6match.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # This patch fixes an IPv4 connection problem. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-connect.patch - - # This patch fixes IPv6-matching. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-ipv6match.patch - - # This patch adds support for enum domains to jwhois. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-enum.patch - - # This patch adds a fclose. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-fclose.patch - - # These patches are modifying domains or whois servers inside the jwhois config file. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-conf.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-gi.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-conf_update.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-conf_update2.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-dotster.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-conf_update3.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-conf_update4.patch - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/kbd b/lfs/kbd deleted file mode 100644 index a283e20..0000000 --- a/lfs/kbd +++ /dev/null @@ -1,104 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = kbd -PKG_VER = 1.15.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://ftp.altlinux.org/pub/people/legion/kbd -LICENSE = GPLv2+ -SHORT_DESC = Tools for configuring the console (keyboard, virtual terminals, etc.). - -define LONG_DESC - The kbd package contains tools for managing a Linux \ - system's console's behavior, including the keyboard, the screen \ - fonts, the virtual terminals and font files. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) $(THISAPP)-backspace-1.patch \ - kbd-latarcyrheb-16-fixed.tar.bz2 \ - kbd-latsun-fonts.tar.bz2 - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-backspace-1.patch - - # Adding our own fonts - cd $(DIR_APP) && $(EXTRACTOR) $(DIR_DL)/kbd-latsun-fonts.tar.bz2 - cd $(DIR_APP) && $(EXTRACTOR) $(DIR_DL)/kbd-latarcyrheb-16-fixed.tar.bz2 - - cd $(DIR_APP) && autoreconf --force --install - - cd $(DIR_APP) && sed -i "s/ifdef OPTIONAL_PROGS/ifeq ($$(OPTIONAL_PROGS),yes)/" man/Makefile.in - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --datadir=/lib/kbd - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - mv -v /usr/bin/{kbd_mode,loadkeys,openvt,setfont} /bin - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/l7-protocols b/lfs/l7-protocols deleted file mode 100644 index 4f24115..0000000 --- a/lfs/l7-protocols +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = l7-protocols -PKG_VER = 2007-11-22 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Firewall -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://l7-filter.sourceforge.net/ -LICENSE = GPLv2+ -SHORT_DESC = Application Layer Packet Classifier for Linux. - -define LONG_DESC - L7-filter is a classifier for Linux's Netfilter that identifies packets \ - based on application layer data. It can classify packets as Kazaa, HTTP, \ - Jabber, Citrix, Bittorrent, FTP, Gnucleus, eDonkey2000, etc., regardless \ - of port. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -mkdir -p /etc/l7-protocols - cp -Rfv $(DIR_APP)/* /etc/l7-protocols - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/ldapvi b/lfs/ldapvi deleted file mode 100644 index 1fed999..0000000 --- a/lfs/ldapvi +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = ldapvi -PKG_VER = 1.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Editors -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = pkg-config -DEPS = glib2 libxslt ncurses openldap openssl popt readline - -URL = http://www.lichteblau.com/ldapvi/ -LICENSE = GPLv2+ -SHORT_DESC = An interactive LDAP client. - -define LONG_DESC - ldapvi is an interactive LDAP client for Unix terminals. Using it, you can \ - update LDAP entries with a text editor, which is the same as vi. Think of \ - it as vipw(1) for LDAP. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && for i in $$(find . -name "*.[ch]"); do \ - sed -e "s/getline/_&/g" -i $$i; done - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/less b/lfs/less deleted file mode 100644 index 1c91abe..0000000 --- a/lfs/less +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = less -PKG_VER = 436 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Text -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = pcre - -URL = http://www.greenwoodsoftware.com/less/ -LICENSE = GPLv3+ -SHORT_DESC = A text file browser similar to more, but better. - -define LONG_DESC - The less utility is a text file browser that resembles more, but has \ - more capabilities. Less allows you to move backwards in the file as \ - well as forwards. Since less doesn't have to read the entire input file \ - before it starts, less starts up more quickly than text editors (for \ - example, vi). -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --with-secure \ - --with-regex=pcre - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libaal b/lfs/libaal deleted file mode 100644 index 9341c03..0000000 --- a/lfs/libaal +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libaal -PKG_VER = 1.0.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.me.kernel.org/pub/linux/utils/fs/reiser4/libaal/ -LICENSE = GPLv2+ -SHORT_DESC = Reiser4's application abstraction library. - -define LONG_DESC - This library is part of the Reiser4's filesystem support tools. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libaal{,-minimal}.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libart b/lfs/libart deleted file mode 100644 index 6f01934..0000000 --- a/lfs/libart +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libart_lgpl -PKG_VER = 2.3.19 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Graphics -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnome.org -LICENSE = LGPLv2+ -SHORT_DESC = Library of graphics routines used by libgnomecanvas. - -define LONG_DESC - Graphics routines used by the GnomeCanvas widget and some other \ - applications. libart renders vector paths and the like. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-upstream_fix-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-upstream_fix-1.patch - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libart_lgpl_2.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libassuan b/lfs/libassuan deleted file mode 100644 index 43473a9..0000000 --- a/lfs/libassuan +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libassuan -PKG_VER = 1.0.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = pth - -URL = http://www.gnupg.org/ -LICENSE = LGPLv2+ -SHORT_DESC = GnuPG IPC library. - -define LONG_DESC - The Libassuan package contains an IPC library used by some of the other \ - GnuPG related packages. Libassuan's primary use is to allow a client to \ - interact with a non-persistent server. Libassuan is not, however, limited \ - to use with GnuPG servers and clients. It was designed to be flexible \ - enough to meet the demands of many transaction based environments with \ - non-persistent servers. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libbdevid b/lfs/libbdevid deleted file mode 100644 index 95b2053..0000000 --- a/lfs/libbdevid +++ /dev/null @@ -1,86 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libbdevid -PKG_VER = ipfire-1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/bdevid - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = e2fsprogs lvm2 parted util-linux-ng - -URL = http://git.fedorahosted.org/git/?p=mkinitrd;a=summary -LICENSE = GPLv2+ -SHORT_DESC = A library that detects raid devices. - -define LONG_DESC - A library that detects raid devices. -endef - -VERSION = 0.1 -CFLAGS += -fPIC - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libcap2 b/lfs/libcap2 deleted file mode 100644 index 490a7ba..0000000 --- a/lfs/libcap2 +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libcap -PKG_VER = 2.16 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = attr pam - -URL = http://ftp.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/ -LICENSE = LGPL2+ -SHORT_DESC = Library for getting and setting POSIX.1e capabilities. - -define LONG_DESC - libcap is a library for getting and setting POSIX.1e (formerly POSIX 6) \ - draft 15 capabilities. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-headerfix.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-headerfix.patch - cd $(DIR_APP) && sed -e "s@<stdlib.h>@&\n#include <asm/types.h>@g" \ - -i progs/capsh.c - cd $(DIR_APP) && sed 's/--static//' -i.orig progs/Makefile - cd $(DIR_APP) && make $(PARALLELISMFLAGS) COPTFLAG="$(CFLAGS)" - cd $(DIR_APP) && make install - - rm -vf /lib/libcap.a - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libdaemon b/lfs/libdaemon deleted file mode 100644 index 5d1d01a..0000000 --- a/lfs/libdaemon +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libdaemon -PKG_VER = 0.13 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://0pointer.de/lennart/projects/libdaemon/ -LICENSE = LGPLv2+ -SHORT_DESC = Library for writing UNIX daemons. - -define LONG_DESC - libdaemon is a lightweight C library which eases the writing of UNIX daemons. -endef - -CFLAGS += -fPIC - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libdaemon.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libdnet b/lfs/libdnet deleted file mode 100644 index bd56298..0000000 --- a/lfs/libdnet +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libdnet -PKG_VER = 1.12 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tgz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://code.google.com/p/libdnet/ -LICENSE = BSD -SHORT_DESC = Simple portable interface to lowlevel networking routines. - -define LONG_DESC - libdnet provides a simplified, portable interface to several \ - low-level networking routines, including network address \ - manipulation, kernel arp(4) cache and route(4) table lookup and \ - manipulation, network firewalling (IP filter, ipfw, ipchains, \ - pf, ...), network interface lookup and manipulation, raw IP \ - packet and Ethernet frame, and data transmission. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-shrext.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # Patch for inconsistent shrext variable - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-shrext.patch - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sbindir=/sbin \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libevent b/lfs/libevent deleted file mode 100644 index 22dc96e..0000000 --- a/lfs/libevent +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libevent -PKG_VER = 1.4.10 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP)-stable.tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP)-stable - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://monkey.org/~provos/libevent/ -LICENSE = BSD -SHORT_DESC = Abstract asynchronous event notification library. - -define LONG_DESC - The libevent API provides a mechanism to execute a callback \ - function when a specific event occurs on a file descriptor or \ - after a timeout has been reached. libevent is meant to replace \ - the asynchronous event loop found in event driven network \ - servers. An application just needs to call event_dispatch() and \ - can then add or remove events dynamically without having to \ - change the event loop. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libevent{,_core,_extra}.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libgcrypt b/lfs/libgcrypt deleted file mode 100644 index 68565cd..0000000 --- a/lfs/libgcrypt +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libgcrypt -PKG_VER = 1.4.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libgpg-error - -URL = http://www.gnupg.org/ -LICENSE = LGPLv2.1+ -SHORT_DESC = A general-purpose cryptography library. - -define LONG_DESC - Libgcrypt is a general purpose crypto library based on the code used \ - in GNU Privacy Guard. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static \ - --enable-noexecstack - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libgcrypt.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libgpg-error b/lfs/libgpg-error deleted file mode 100644 index 5cb1950..0000000 --- a/lfs/libgpg-error +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libgpg-error -PKG_VER = 1.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnupg.org/ -LICENSE = LGPLv2+ -SHORT_DESC = Library for error values used by GnuPG components. - -define LONG_DESC - This is a library that defines common error values for all GnuPG \ - components. Among these are GPG, GPGSM, GPGME, GPG-Agent, libgcrypt, \ - pinentry, SmartCard Daemon and possibly more in the future. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libgpg-error.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libgssglue b/lfs/libgssglue deleted file mode 100644 index 263abcc..0000000 --- a/lfs/libgssglue +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libgssglue -PKG_VER = 0.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.citi.umich.edu/projects/nfsv4/linux/libgssglue/ -LICENSE = BSD -SHORT_DESC = This library exports a gssapi interface. - -define LONG_DESC - This library exports a gssapi interface, but doesn't implement any \ - gssapi mechanisms itself; instead it calls gssapi routines in other \ - libraries, depending on the mechanism. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libgssglue.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libidn b/lfs/libidn deleted file mode 100644 index 5f44d4b..0000000 --- a/lfs/libidn +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libidn -PKG_VER = 0.6.14 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/libidn/ -LICENSE = LGPLv2+ GPLv3+ -SHORT_DESC = Internationalized Domain Name support library. - -define LONG_DESC - GNU Libidn is an implementation of the Stringprep, Punycode and \ - IDNA specifications defined by the IETF Internationalized Domain \ - Names (IDN) working group, used for internationalized domain \ - names. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - #sed -e 's/include_next/include/g' -i /usr/include/idn-int.h - - rm -vf /usr/lib/libidn.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libjpeg b/lfs/libjpeg deleted file mode 100644 index 457fb1a..0000000 --- a/lfs/libjpeg +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libjpeg -PKG_VER = 7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = jpegsrc.v$(PKG_VER).tar.gz -DIR_APP = $(DIR_SRC)/jpeg-$(PKG_VER) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.ijg.org/ -LICENSE = IJG -SHORT_DESC = A library for manipulating JPEG image format files. - -define LONG_DESC - The libjpeg package contains a library of functions for manipulating \ - JPEG images, as well as simple client programs for accessing the \ - libjpeg functions. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static \ - --enable-shared - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libjpeg.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libksba b/lfs/libksba deleted file mode 100644 index 48346c2..0000000 --- a/lfs/libksba +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libksba -PKG_VER = 1.0.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libgpg-error - -URL = http://www.gnupg.org/ -LICENSE = GPLv3 -SHORT_DESC = X.509 Library. - -define LONG_DESC - KSBA is a library designed to build software based on the X.509 and \ - CMS protocols. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libksba.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libnetfilter_conntrack b/lfs/libnetfilter_conntrack deleted file mode 100644 index 18da80e..0000000 --- a/lfs/libnetfilter_conntrack +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libnetfilter_conntrack -PKG_VER = 0.0.100 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.netfilter.org/projects/libnetfilter_conntrack/downloads.html -LICENSE = GPL -SHORT_DESC = libnetfilter_conntrack is a userspace library. - -define LONG_DESC - libnetfilter_conntrack is a library that allows user-space \ - programs to interface the kernel connection tracking table of \ - the netfilter subsystem in the Linux kernel. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libnetfilter_conntrack.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libnetfilter_log b/lfs/libnetfilter_log deleted file mode 100644 index e3ec656..0000000 --- a/lfs/libnetfilter_log +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libnetfilter_log -PKG_VER = 0.0.16 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.netfilter.org/projects/libnetfilter_log/downloads.html -LICENSE = GPL -SHORT_DESC = The libnetfilter_log userspace library. - -define LONG_DESC - libnetfilter_log is a software library to interface with the \ - nfnetlink_log mechanism in Linux 2.6.14 and later. The library \ - enables programs to receive and process packets logged by the \ - Linux packet filter (iptables). -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libnetfilter_log{,_libipulog}.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libnetfilter_queue b/lfs/libnetfilter_queue deleted file mode 100644 index 26bf69a..0000000 --- a/lfs/libnetfilter_queue +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libnetfilter_queue -PKG_VER = 0.0.17 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.netfilter.org/projects/libnetfilter_queue/downloads.html -LICENSE = GPL -SHORT_DESC = The libnetfilter_queue userspace library. - -define LONG_DESC - libnetfilter_queue is a userspace library that provides an API \ - for manipulating packets that have been queued by the kernel \ - packet filter. It is is part of a system that deprecates the old \ - ip_queue/libipq mechanism. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libnetfilter_queue{,_libipq}.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libnfnetlink b/lfs/libnfnetlink deleted file mode 100644 index 79ba25e..0000000 --- a/lfs/libnfnetlink +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libnfnetlink -PKG_VER = 1.0.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no - -URL = http://www.netfilter.org/projects/libnfnetlink/downloads.html -LICENSE = GPL -SHORT_DESC = A low-level library for netfilter. - -define LONG_DESC - libnfnetlink is a low-level userspace library for \ - nfnetlink-based communication between the kernel-side netfilter \ - and the user-space world. It is therefore the fundamental layer \ - for all other nfnetlink-enabled user-space programs interfacing \ - with the netfilter subsystem of the Linux kernel. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libnfnetlink.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libnfsidmap b/lfs/libnfsidmap deleted file mode 100644 index e0b497a..0000000 --- a/lfs/libnfsidmap +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libnfsidmap -PKG_VER = 0.21 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.citi.umich.edu/projects/nfsv4/linux/libnfsidmap/ -LICENSE = BSD -SHORT_DESC = Library to help mapping id's, mainly for NFSv4. - -define LONG_DESC - libnfsidmap provides functions to map between NFSv4 names \ - (which are of the form user@domain) and local uid's and gid's. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libnfsidmap*.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libnl b/lfs/libnl deleted file mode 100644 index 59e41a3..0000000 --- a/lfs/libnl +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libnl -PKG_VER = 1.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://people.suug.ch/~tgr/libnl/ -LICENSE = LGPLv2 -SHORT_DESC = Convenience library for kernel netlink sockets. - -define LONG_DESC - This package contains a convenience library to simplify using the \ - Linux kernel's netlink sockets interface for network manipulation. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-permissions.patch \ - $(THISAPP)-include-limits-h.patch \ - $(THISAPP)-no-extern-inline.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-permissions.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-include-limits-h.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-no-extern-inline.patch - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libpcap b/lfs/libpcap deleted file mode 100644 index 8711685..0000000 --- a/lfs/libpcap +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libpcap -PKG_VER = 1.0.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no - -URL = http://www.tcpdump.org/ -LICENSE = BSD with advertising -SHORT_DESC = A system-independent interface for user-level packet capture. - -define LONG_DESC - Libpcap provides a portable framework for low-level network \ - monitoring. Libpcap can provide network statistics collection, \ - security monitoring and network debugging. Since almost every \ - system vendor provides a different interface for packet capture, \ - the libpcap authors created this system-independent API to ease in \ - porting and to alleviate the need for several system-dependent \ - packet capture modules in each application. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make shared $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install install-shared-so - ln -svf libpcap.so.1.0.0 /usr/lib/libpcap.so.1.0 - ln -svf libpcap.so.1.0 /usr/lib/libpcap.so.1 - ln -svf libpcap.so.1 /usr/lib/libpcap.so - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libpng b/lfs/libpng deleted file mode 100644 index bb03e7a..0000000 --- a/lfs/libpng +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libpng -PKG_VER = 1.2.39 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.libpng.org/pub/png/ -LICENSE = zlib -SHORT_DESC = A library of functions for manipulating PNG image format files. - -define LONG_DESC - The libpng package contains a library of functions for creating and \ - manipulating PNG (Portable Network Graphics) image format files. \ - PNG is a bit-mapped graphics format similar to the GIF format. PNG \ - was created to replace the GIF format, since GIF uses a patented \ - data compression algorithm. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-pngconf.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - #This patch adds new CFLAGS for compiling. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-pngconf.patch - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libpng{,12}.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/librpcsecgss b/lfs/librpcsecgss deleted file mode 100644 index 71bc11e..0000000 --- a/lfs/librpcsecgss +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = librpcsecgss -PKG_VER = 0.18 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.citi.umich.edu/projects/nfsv4/linux/librpcsecgss/ -LICENSE = BSD -SHORT_DESC = A Library for secure rpc communication. - -define LONG_DESC - rpcsecgss allows secure rpc communication using the rpcsec_gss \ - protocol. -endef - -CFLAGS += -fPIC - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/librpcsecgss.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libsoup b/lfs/libsoup deleted file mode 100644 index de6cafa..0000000 --- a/lfs/libsoup +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libsoup -PKG_VER = 2.28.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = glib2 - -URL = http://www.linuxfromscratch.org/blfs/view/6.3/basicnet/libsoup.html -LICENSE = GPL -SHORT_DESC = HTTP client/server library for GNOME - -define LONG_DESC - libsoup is an HTTP client/server library for GNOME. It uses GObjects \ - and the glib main loop, to integrate well with GNOME applications, \ - and also has a synchronous API, for use in threaded applications. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --without-gnome - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libssh2 b/lfs/libssh2 deleted file mode 100644 index 0681232..0000000 --- a/lfs/libssh2 +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libssh2 -PKG_VER = 1.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = openssl zlib - -URL = http://www.libssh2.org/ -LICENSE = BSD -SHORT_DESC = A library implementing the SSH2 protocol. - -define LONG_DESC - libssh2 is a library implementing the SSH2 protocol as defined by \ - Internet Drafts: SECSH-TRANS(22), SECSH-USERAUTH(25), \ - SECSH-CONNECTION(23), SECSH-ARCH(20), SECSH-FILEXFER(06)*, \ - SECSH-DHGEX(04), and SECSH-NUMBERS(10). -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libtiff b/lfs/libtiff deleted file mode 100644 index 3ff8cd5..0000000 --- a/lfs/libtiff +++ /dev/null @@ -1,115 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libtiff -PKG_VER = 3.9.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = tiff-$(PKG_VER).tar.gz -DIR_APP = $(DIR_SRC)/tiff-$(PKG_VER) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = libjpeg - -URL = http://www.libtiff.org/ -LICENSE = libtiff ( own ) -SHORT_DESC = Library of functions for manipulating TIFF format image files. - -define LONG_DESC - The libtiff package contains a library of functions for manipulating \ - TIFF (Tagged Image File Format) image format files. TIFF is a widely \ - used file format for bitmapped images. TIFF files usually end in the \ - .tif extension and they are often quite large. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) -# $(THISAPP)-CVE-2006-2193.patch \ -# $(THISAPP)-ormandy.patch \ -# $(THISAPP)-lzw-bugs.patch \ -# $(THISAPP)-tiffsplit-overflow.patch \ -# $(THISAPP)-mantypo.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - #These patches are fixing bufferoverflows. -# cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-CVE-2006-2193.patch -# cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-tiffsplit-overflow.patch - - #This patch fixes several vulnerabilities. -# cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-ormandy.patch - - #This patch fixes LZW decoding vulnerabilities (CVE-2008-2327) -# cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-lzw-bugs.patch - - #This patch fixes CVE-2006-2193, tiff2pdf buffer overflow (#194362) - #and fix typo in man page for tiffset (#186297) -# cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-mantypo.patch - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libtiff{,xx}.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libtool b/lfs/libtool deleted file mode 100644 index d8bfdb0..0000000 --- a/lfs/libtool +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libtool -PKG_VER = 2.2.6a -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(PKG_NAME)-2.2.6 - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/libtool/ -LICENSE = GPLv2+ and LGPLv2+ and GFDL -SHORT_DESC = Runtime libraries for GNU Libtool Dynamic Module Loader. - -define LONG_DESC - GNU Libtool is a set of shell scripts which automatically \ - configure UNIX and UNIX-like systems to generically build \ - shared libraries. Libtool provides a consistent, portable \ - interface which simplifies the process of using shared libraries. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install : $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects) : - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libltdl.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libusb b/lfs/libusb deleted file mode 100644 index 2aa2d5c..0000000 --- a/lfs/libusb +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libusb -PKG_VER = 1.0.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://sourceforge.net/projects/libusb/ -LICENSE = LGPLv2+ -SHORT_DESC = A library which allows userspace access to USB devices. - -define LONG_DESC - This package provides a way for applications to access USB devices. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libusb-1.0.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libusb-compat b/lfs/libusb-compat deleted file mode 100644 index 89e1c00..0000000 --- a/lfs/libusb-compat +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libusb -PKG_VER = 0.1.12 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libusb - -URL = http://sourceforge.net/projects/libusb/ -LICENSE = LGPLv2+ -SHORT_DESC = A library which allows userspace access to USB devices. - -define LONG_DESC - This package provides a way for applications to access USB devices. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-build-docs \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libusb{,pp}.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libuser b/lfs/libuser deleted file mode 100644 index 5463903..0000000 --- a/lfs/libuser +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libuser -PKG_VER = 0.56.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = https://fedorahosted.org/libuser/ -LICENSE = LGPLv2+ -SHORT_DESC = A user and group account administration library. - -define LONG_DESC - The libuser library implements a standardized interface for \ - manipulating and administering user and group accounts. The \ - library uses pluggable back-ends to interface to its data sources. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --with-ldap - cd $(DIR_APP) && sed -e "s/^SUBDIRS = .*/SUBDIRS = po/" -i Makefile - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libuser.la /usr/lib/libuser/*.la \ - /usr/lib/python*/site-packages/libusermodule.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libvirt b/lfs/libvirt deleted file mode 100644 index 3c7a68b..0000000 --- a/lfs/libvirt +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libvirt -PKG_VER = 0.7.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Virtualization -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = gnutls - -URL = http://www.libvirt.org/ -LICENSE = LGPLv2.1+ -SHORT_DESC = A library for controlling VMs. - -define LONG_DESC - A toolkit to interact with the virtualization capabilities of recent \ - versions of Linux. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static \ - --with-xen=no \ - --with-qemu - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libvirt.la \ - /usr/lib/python*/site-packages/libvirtmod.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libxml2 b/lfs/libxml2 deleted file mode 100644 index 9767b94..0000000 --- a/lfs/libxml2 +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libxml2 -PKG_VER = 2.7.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://xmlsoft.org/ -LICENSE = MIT -SHORT_DESC = Library providing XML and HTML support. - -define LONG_DESC - This library allows to manipulate XML files. It includes support \ - to read, modify and write XML and HTML files. There is DTDs support \ - this includes parsing and validation even with complex DtDs, either \ - at parse time or later once the document has been modified. The output \ - can be a simple SAX stream or and in-memory DOM like representations. \ - In this case one can use the built-in XPath and XPointer implementation \ - to select subnodes or ranges. A flexible Input/Output mechanism is \ - available, with existing HTTP and FTP modules and combined to an URI \ - library. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - $(PYTHON_COMPILE) - - rm -vf /usr/lib/libxml2.la /usr/lib/python*/site-packages/libxml2mod.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/libxslt b/lfs/libxslt deleted file mode 100644 index 6ea5025..0000000 --- a/lfs/libxslt +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = libxslt -PKG_VER = 1.1.24 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libxml2 python - -URL = http://xmlsoft.org/XSLT/ -LICENSE = MIT -SHORT_DESC = Library providing the Gnome XSLT engine. - -define LONG_DESC - This C library allows to transform XML files into other XML files \ - (or HTML, text, ...) using the standard XSLT stylesheet transformation \ - mechanism. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-CVE-2008-2935.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # This Patch fixes CVE-2008-2935 - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-CVE-2008-2935.patch - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - $(PYTHON_COMPILE) - - rm -vf /usr/lib/lib{,e}xslt.la /usr/lib/python*/site-packages/libxsltmod.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/lighttpd b/lfs/lighttpd deleted file mode 100644 index fe04481..0000000 --- a/lfs/lighttpd +++ /dev/null @@ -1,108 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = lighttpd -PKG_VER = 1.4.23 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Michael Tremer michael.tremer@ipfire.org -GROUP = Networking/Webservers -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = bzip2 openssl pcre zlib - -URL = http://www.lighttpd.net/ -LICENSE = BSD -SHORT_DESC = Lightning fast webserver with light system requirements. - -define LONG_DESC - Secure, fast, compliant and very flexible web-server which has been optimized \ - for high-performance environments. It has a very low memory footprint compared \ - to other webservers and takes care of cpu-load. Its advanced feature-set \ - (FastCGI, CGI, Auth, Output-Compression, URL-Rewriting and many more) make \ - it the perfect webserver-software for every server that is suffering load \ - problems. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libdir=/usr/lib/$(PKG_NAME) \ - --with-ldap \ - --with-openssl=/usr/include - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/lighttpd/*.la - - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/$(PKG_NAME).conf \ - /etc/$(PKG_NAME).conf - -mkdir -p /var/log/$(PKG_NAME) - touch /var/log/$(PKG_NAME)/{access,error}.log - chown nobody.nobody -R /var/log/$(PKG_NAME) - -mkdir -pv /var/cache/lighttpd/compress - chown nobody.nobody -Rv /var/cache/lighttpd/ - - $(INSTALL_INITSCRIPT) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/linux b/lfs/linux deleted file mode 100644 index 4ad3977..0000000 --- a/lfs/linux +++ /dev/null @@ -1,199 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = linux -PKG_VER = 2.6.31.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -ifeq "$(LFS_FILE)" "linux-headers" - CORE = no -else - CORE = yes -endif -EXTRA = no -DEBUG = no -BUILD_DEPS = xz -DEPS = - -URL = http://www.kernel.org/ -LICENSE = GPLv2 -SHORT_DESC = The Linux kernel. - -define LONG_DESC - The kernel package contains the Linux kernel (vmlinuz), the core of any \ - Linux operating system. The kernel handles the basic functions \ - of the operating system: memory allocation, process allocation, device \ - input and output, etc. -endef - -CFLAGS = -CXXFLAGS = - -LOCALVERSION = -ipfire1 -FULLVER= $(PKG_VER)$(LOCALVERSION) - -# Patches -AUFS_PATCH = aufs2-$(PKG_VER)-1.patch -GRSEC_PATCH = grsecurity-2.1.14-$(PKG_VER)-200910012153.patch -#OCF_PATCH = ocf-linux-26-20080917.patch -REISER4_PATCH = reiser4-for-$(PKG_VER).patch -ROUTES_PATCH = routes-$(PKG_VER)-16.diff # Taken from http://www.ssi.bg/~ja/#routes - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(AUFS_PATCH) \ - $(OCF_PATCH) \ - $(REISER4_PATCH) \ - $(GRSEC_PATCH) \ - $(THISAPP)-disable-compat_vdso-1.patch \ - $(ROUTES_PATCH) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && echo "$(LOCALVERSION)" > localversion-ipfire - - ### Aufs2 - # - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(AUFS_PATCH) - - ### OCF - # - #cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(OCF_PATCH) - #cd $(DIR_APP) && echo "source "crypto/ocf/Kconfig"" >> crypto/Kconfig - - ### Reiser4 - # - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(REISER4_PATCH) - - ### Routes - # - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(ROUTES_PATCH) - - ### GrSecurity - # - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(GRSEC_PATCH) - rm -f $(DIR_APP)/localversion-grsec - - #cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-disable-compat_vdso-1.patch - - cd $(DIR_APP) && sed -e "s/^HOSTCFLAGS.*=.*/& -fPIC/g" -i Makefile - -ifeq "$(STAGE)" "toolchain" - install -dv $(TOOLS_DIR)/include - cd $(DIR_APP) && make mrproper - cd $(DIR_APP) && make ARCH=x86 headers_check - cd $(DIR_APP) && make ARCH=x86 INSTALL_HDR_PATH=dest headers_install - cd $(DIR_APP) && cp -rv dest/include/* $(TOOLS_DIR)/include -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && make mrproper - cd $(DIR_APP) && make ARCH=x86 headers_check - cd $(DIR_APP) && make ARCH=x86 INSTALL_HDR_PATH=dest headers_install - cd $(DIR_APP) && cp -rv dest/include/* /usr/include -endif - -ifeq "$(STAGE)" "ipfire" - cd $(DIR_APP) && make mrproper - - # Select right optimization for the linux kernel. - if [ "$(TARGET)" == "i486" ]; then \ - sed -e "s/^CONFIG_M686=y/# CONFIG_686 is not set/" \ - -e "s/^# CONFIG_M486 is not set/CONFIG_M486=y/" \ - < $(DIR_SOURCE)/kernel/kernel.config > $(DIR_APP)/.config; \ - elif [ "$(TARGET)" == "i586" ]; then \ - sed -e "s/^CONFIG_M686=y/# CONFIG_686 is not set/" \ - -e "s/^# CONFIG_M586TSC is not set/CONFIG_M586TSC=y/" \ - < $(DIR_SOURCE)/kernel/kernel.config > $(DIR_APP)/.config; \ - elif [ "$(TARGET)" == "via-c7" ]; then \ - sed -e "s/^CONFIG_M686=y/# CONFIG_686 is not set/" \ - -e "s/^# CONFIG_MVIAC7 is not set/CONFIG_MVIAC7=y/" \ - < $(DIR_SOURCE)/kernel/kernel.config > $(DIR_APP)/.config; \ - elif [ "$(TARGET)" == "via-c3" ]; then \ - sed -e "s/^CONFIG_M686=y/# CONFIG_686 is not set/" \ - -e "s/^# CONFIG_MVIAC3_2 is not set/CONFIG_MVIAC3_2=y/" \ - < $(DIR_SOURCE)/kernel/kernel.config > $(DIR_APP)/.config; \ - else \ - cp -f $(DIR_SOURCE)/kernel/kernel.config $(DIR_APP)/.config; \ - fi - - cd $(DIR_APP) && yes "" | make oldconfig - - cd $(DIR_APP) && cp -vf $(DIR_SOURCE)/kernel/$(SNAME)_logo.ppm \ - drivers/video/logo/logo_linux_clut224.ppm - - cd $(DIR_APP) && make CC="gcc -nopie" $(PARALLELISMFLAGS) - cd $(DIR_APP) && make modules_install - - cd $(DIR_APP) && cp -v arch/x86/boot/bzImage /boot/$(SNAME)kernel-$(FULLVER) - cd $(DIR_APP) && cp -v System.map /boot/System.map-$(FULLVER) - - ln -svf $(SNAME)kernel-$(FULLVER) /boot/$(SNAME)kernel - ln -svf System.map-$(FULLVER) /boot/System.map - - # keep the source code in $(DIR_SRC)/$(PKG_NAME)-$(FULLVER) - cp -fal $(DIR_APP) $(DIR_SRC)/$(PKG_NAME)-$(FULLVER) - - rm -vf /lib/modules/$(KVER)/{build,source} - ln -svf $(DIR_SRC)/$(PKG_NAME)-$(FULLVER) /lib/modules/$(KVER)/build - ln -svf $(DIR_SRC)/$(PKG_NAME)-$(FULLVER) /lib/modules/$(KVER)/source - -mkdir -pv /lib/modules/$(KVER)/extra -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/linux-atm b/lfs/linux-atm deleted file mode 100644 index 2644d3f..0000000 --- a/lfs/linux-atm +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = linux-atm -PKG_VER = 2.4.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Daemons -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://linux-atm.sourceforge.net/ -LICENSE = BSD and GPLv2 and GPLv2+ and LGPLv2+ and MIT -SHORT_DESC = Tools to support ATM networking under Linux - -define LONG_DESC - This package contains header files and libraries for development \ - using theLinux ATM API. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-gcc-4.patch \ - $(THISAPP)-nmu.diff - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 < $(DIR_PATCHES)/$(THISAPP)-gcc-4.patch - cd $(DIR_APP) && patch -Np1 < $(DIR_PATCHES)/$(THISAPP)-nmu.diff - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libatm.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/linux-headers b/lfs/linux-headers deleted file mode 120000 index 9c52cb3..0000000 --- a/lfs/linux-headers +++ /dev/null @@ -1 +0,0 @@ -linux \ No newline at end of file diff --git a/lfs/lm-sensors b/lfs/lm-sensors deleted file mode 100644 index 7113703..0000000 --- a/lfs/lm-sensors +++ /dev/null @@ -1,88 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = lm_sensors -PKG_VER = 3.0.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Statistics -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.lm-sensors.org/ -LICENSE = GPLv2+ -SHORT_DESC = Hardware monitoring tools. - -define LONG_DESC - The lm_sensors package includes a collection of modules for general SMBus \ - access and hardware monitoring. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && sed -e "s/^PREFIX\ :=\ .*/PREFIX=/usr/g" \ - -e "s/^MACHINE\ :=\ .*/MACHINE=$(MACHINE)/g" -i Makefile - cd $(DIR_APP) && make $(PARALLELISMFLAGS) EXLDFLAGS= - cd $(DIR_APP) && make install - rm -vf /usr/lib/libsensors.a - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/logrotate b/lfs/logrotate deleted file mode 100644 index f32492b..0000000 --- a/lfs/logrotate +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = logrotate -PKG_VER = 3.7.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = https://fedorahosted.org/releases/l/o/logrotate/ -LICENSE = GPL+ -SHORT_DESC = Rotates, compresses, removes and mails system log files. - -define LONG_DESC - The logrotate utility is designed to simplify the administration of \ - log files on a system which generates a lot of log files. Logrotate \ - allows for the automatic rotation compression, removal and mailing of \ - log files. Logrotate can be set to handle a log file daily, weekly, \ - monthly or when the log file gets to a certain size. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-toolarge.patch \ - $(THISAPP)-curdir.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # This patch fixes a problem with too large files. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-toolarge.patch - - # This patch fixes a prblem with the current directory. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-curdir.patch - - cd $(DIR_APP) && make RPM_OPT_FLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - touch /var/lib/logrotate.status - - # Creating directory for config files - mkdir /etc/logrotate.d - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/lsof b/lfs/lsof deleted file mode 100644 index d532e04..0000000 --- a/lfs/lsof +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = lsof -PKG_VER = 4.82 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(PKG_NAME)_$(PKG_VER)_src.tar.gz -DIR_APP = $(DIR_SRC)/$(PKG_NAME)_$(PKG_VER)_src - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Debuggers -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof -LICENSE = zlib -SHORT_DESC = A utility which lists open files on a Linux/UNIX system. - -define LONG_DESC - Lsof stands for LiSt Open Files, and it does just that: \ - it lists information about files that are open by the \ - processes running on a system. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && ./Configure linux -n - cd $(DIR_APP) && make DEBUG="$(CFLAGS)" $(PARALLELISMFLAGS) - cd $(DIR_APP) && install -m 4750 -o root -g nobody lsof /usr/bin - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/lua b/lfs/lua deleted file mode 100644 index 8616851..0000000 --- a/lfs/lua +++ /dev/null @@ -1,109 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = lua -PKG_VER = 5.1.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Languages -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = ncurses readline - -URL = http://www.lua.org/ -LICENSE = MIT -SHORT_DESC = Powerful light-weight programming language. - -define LONG_DESC - Lua is a powerful light-weight programming language designed for \ - extending applications. Lua is also frequently used as a \ - general-purpose, stand-alone language. Lua is free software. \ - Lua combines simple procedural syntax with powerful data description \ - constructs based on associative arrays and extensible semantics. Lua \ - is dynamically typed, interpreted from bytecodes, and has automatic \ - memory management with garbage collection, making it ideal for \ - configuration, scripting, and rapid prototyping. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-autotoolize.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-autotoolize.patch - cd $(DIR_APP) && chmod u+x autogen.sh config.guess config.sub configure \ - depcomp install-sh missing - cd $(DIR_APP) && autoconf - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --with-readline \ - #--disable-static - cd $(DIR_APP) && sed -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ - -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' -i libtool - # hack so that only /usr/bin/lua gets linked with readline as it is the - # only one which needs this and otherwise we get License troubles - cd $(DIR_APP) && make $(PARALLELISMFLAGS) LIBS="-ldl" luac_LDADD="liblua.la -lm -ldl" - # also remove readline from lua.pc - cd $(DIR_APP) && sed -i 's/-lreadline -lncurses //g' etc/lua.pc - cd $(DIR_APP) && make install - rm -vf /usr/lib/liblua.{,l}a - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/lvm2 b/lfs/lvm2 deleted file mode 100644 index 682a367..0000000 --- a/lfs/lvm2 +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = LVM2 -PKG_VER = 2.02.54 -PKG_REL = 0 - -THISAPP = $(PKG_NAME).$(PKG_VER) -DL_FILE = $(THISAPP).tgz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = module-init-tools ncurses readline - -URL = http://sources.redhat.com/lvm2/ -LICENSE = GPLv2 -SHORT_DESC = Userland logical volume management tools. - -define LONG_DESC - LVM2 includes all of the support for handling read/write operations on \ - physical volumes (hard disks, RAID-Systems, magneto optical, etc., \ - multiple devices (MD), see mdadd(8) or even loop devices, see \ - losetup(8)), creating volume groups (kind of virtual disks) from one \ - or more physical volumes and creating one or more logical volumes \ - (kind of logical partitions) in volume groups. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/bin \ - --sbindir=/sbin \ - --exec-prefix=/ \ - --libdir=/lib \ - --disable-static \ - --enable-pkgconfig - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/lzo b/lfs/lzo deleted file mode 100644 index cee79c4..0000000 --- a/lfs/lzo +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = lzo -PKG_VER = 2.03 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Compression -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = zlib - -URL = http://www.oberhumer.com/opensource/lzo/ -LICENSE = GPLv2+ -SHORT_DESC = Data compression library with very fast (de)compression. - -define LONG_DESC - LZO is a portable lossless data compression library written in ANSI C. \ - It offers pretty fast compression and very fast decompression. \ - Decompression requires no memory. In addition there are slower \ - compression levels achieving a quite competitive compression ratio \ - while still decompressing at this very high speed. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-shared \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/liblzo2.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/m4 b/lfs/m4 deleted file mode 100644 index bc59aa4..0000000 --- a/lfs/m4 +++ /dev/null @@ -1,112 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = m4 -PKG_VER = 1.4.11 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Text -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/m4/ -LICENSE = GPLv3+ -SHORT_DESC = The GNU macro processor. - -define LONG_DESC - A GNU implementation of the traditional UNIX macro processor. M4 is \ - useful for writing text files which can be logically parsed, and is \ - used by many programs as part of their build process. M4 has \ - built-in functions for including files, running shell commands, \ - doing arithmetic, etc. The autoconf program needs m4 for generating \ - configure scripts, but not for running configure scripts. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - # We need -D_GNU_SOURCE because this version of M4 has a bug in gnulib (or - # possibly autoconf) that doesn't recognise that we have asprintf() in libc. - cd $(DIR_APP) && \ - CPPFLAGS="-D_GNU_SOURCE" \ - gl_cv_func_printf_directive_n=no \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - CPPFLAGS="-D_GNU_SOURCE" \ - gl_cv_func_printf_directive_n=no \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/make b/lfs/make deleted file mode 100644 index 81239ab..0000000 --- a/lfs/make +++ /dev/null @@ -1,106 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = make -PKG_VER = 3.81 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Tools -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/make/ -LICENSE = GPLv2+ -SHORT_DESC = A GNU tool which simplifies the build process for users. - -define LONG_DESC - A GNU tool for controlling the generation of executables and other \ - non-source files of a program from the program's source files. Make \ - allows users to build and install packages without any significant \ - knowledge about the details of the build process. The details about \ - how the program should be built are provided for make in the program's \ - makefile. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/man-db b/lfs/man-db deleted file mode 100644 index 401b089..0000000 --- a/lfs/man-db +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = man-db -PKG_VER = 2.5.6 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Documentation -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://bzr.savannah.gnu.org/r/man-db/ -LICENSE = GPL -SHORT_DESC = man-db is an on-line manual database. - -define LONG_DESC - man-db is an implementation of the standard Unix documentation \ - system accessed using the man command. It uses a Berkeley DB database \ - in place of the traditional flat-text whatis databases. man-db is \ - used by several popular GNU/Linux distributions. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && sed -i -e '%\t/usr/man%d' -e '%\t/usr/local/man%d' src/man_db.conf.in - cd $(DIR_APP) && CC="gcc -std=gnu99 -fgnu89-inline" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libexecdir=/usr/lib \ - --sysconfdir=/etc \ - --disable-setuid \ - --with-browser=/usr/bin/lynx \ - --with-col=/usr/bin/col \ - --with-vgrind=/usr/bin/vgrind \ - --with-grap=/usr/bin/grap - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/man-pages b/lfs/man-pages deleted file mode 100644 index 56219f6..0000000 --- a/lfs/man-pages +++ /dev/null @@ -1,84 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = man-pages -PKG_VER = 3.23 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Documentation -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.kernel.org/pub/linux/docs/manpages/ -LICENSE = GPLv2+ and GPL+ and BSD and MIT and Copyright only and IEEE -SHORT_DESC = Man (manual) pages from the Linux Documentation Project. - -define LONG_DESC - A large collection of man pages (documentation) from the Linux \ - Documentation Project (LDP). -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/mc b/lfs/mc deleted file mode 100644 index 6ced616..0000000 --- a/lfs/mc +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = mc -PKG_VER = 4.6.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = e2fsprogs glib2 slang - -URL = http://www.ibiblio.org/mc/ -LICENSE = GPLv2+ -SHORT_DESC = User-friendly text console file manager and visual shell. - -define LONG_DESC - Midnight Commander is a visual shell much like a file manager, only \ - with many more features. It is a text mode application, but it also \ - includes mouse support. Midnight Commander's best features are its \ - ability to FTP, view tar and zip files, and to poke into RPMs for \ - specific files. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-utf8.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-utf8.patch - cd $(DIR_APP) && AUTOPOINT=true autoreconf -f -v -i - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libexecdir=/usr/lib \ - --enable-charset - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - chmod 1755 /usr/lib/mc/cons.saver - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/mdadm b/lfs/mdadm deleted file mode 100644 index f3ea5fb..0000000 --- a/lfs/mdadm +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = mdadm -PKG_VER = 3.0-devel2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.kernel.org/pub/linux/utils/raid/mdadm/ -LICENSE = GPLv2+ -SHORT_DESC = The mdadm program controls Linux md devices (software RAID arrays). - -define LONG_DESC - The mdadm program is used to create, manage, and monitor Linux MD (software \ - RAID) devices. As such, it provides similar functionality to the raidtools \ - package. However, mdadm is a single program, and it can perform \ - almost all functions without a configuration file, though a configuration \ - file can be used to help with some common tasks. -endef - -CFLAGS += -fno-strict-aliasing - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-warn.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-warn.patch - cd $(DIR_APP) && make $(PARALLELISMFLAGS) CXFLAGS="$(CFLAGS)" \ - SYSCONFDIR="/etc" MDASSEMBLE_AUTO=1 - cd $(DIR_APP) && make install BINDIR=/sbin - -mkdir -p -m 700 /var/run/mdadm - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/memtest86+ b/lfs/memtest86+ deleted file mode 100644 index e509a56..0000000 --- a/lfs/memtest86+ +++ /dev/null @@ -1,88 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = memtest86+ -PKG_VER = 4.00 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.memtest.org/ -LICENSE = GPLv2 -SHORT_DESC = Stand-alone memory tester for x86 and x86-64 computers. - -define LONG_DESC - Memtest86+ is a thorough stand-alone memory test for x86 and x86-64 \ - architecture computers. BIOS based memory tests are only a quick \ - check and often miss many of the failures that are detected by \ - Memtest86+. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) CC="gcc -fno-PIE -fno-stack-protector" - -mkdir -p /usr/lib/memtest86+ - cd $(DIR_APP) && cp -f memtest.bin /usr/lib/memtest86+ - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/mkinitramfs b/lfs/mkinitramfs deleted file mode 100644 index 01ee9a4..0000000 --- a/lfs/mkinitramfs +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = mkinitramfs -PKG_VER = ipfire -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DIR_APP = $(DIR_SOURCE)/$(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Boot -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://tools.assembla.com/mkinitramfs -LICENSE = GPL -SHORT_DESC = A tool to create initramfs images. - -define LONG_DESC - mkinitramfs is intended to create the ultimate initramfs image. It's \ - designed to boot from any media (SATA, PATA, SCSI, USB, CD-ROM, etc.) \ - without any changes being made to your disk. However, it is very \ - simple (about 400 lines of code). -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - install -m 755 $(DIR_APP)/lsinitramfs /sbin/lsinitramfs - install -m 755 $(DIR_APP)/mkinitramfs /sbin/mkinitramfs - install -m 755 $(DIR_APP)/mkliveramfs /sbin/mkliveramfs - -mkdir -pv /usr/lib/mkinitramfs - install -m 644 $(DIR_APP)/functions /usr/lib/mkinitramfs/functions - @$(POSTBUILD) diff --git a/lfs/module-init-tools b/lfs/module-init-tools deleted file mode 100644 index 34cf4d0..0000000 --- a/lfs/module-init-tools +++ /dev/null @@ -1,103 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = module-init-tools -PKG_VER = 3.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://ftp.kernel.org/pub/linux/utils/kernel/module-init-tools/ -LICENSE = GPLv2+ -SHORT_DESC = Kernel module management utilities. - -define LONG_DESC - The module-init-tools package includes various programs needed \ - for automatic loading and unloading of modules under 2.6 and \ - later kernels, as well as other module management programs. \ - Device drivers and filesystems are two examples of loaded and \ - unloaded modules. -endef - -CFLAGS += -DCONFIG_NO_BACKWARDS_COMPAT=1 - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-nostatic-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-nostatic-1.patch - cd $(DIR_APP) && autoreconf --force - cd $(DIR_APP) && \ - DOCBOOKTOMAN=true \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/ \ - --mandir=/usr/share/man \ - --enable-zlib-dynamic - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make INSTALL=install install - rm -vf /sbin/insmod.static - -mkdir -pv /etc/modprobe.d - cp -av $(DIR_SOURCE)/$(PKG_NAME)/modprobe.d/* /etc/modprobe.d/ - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/mpfr b/lfs/mpfr deleted file mode 100644 index 46c67de..0000000 --- a/lfs/mpfr +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = mpfr -PKG_VER = 2.4.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GRPUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.mpfr.org/ -LICENSE = LGPLv2+ and GPLv2+ and GFDL -SHORT_DESC = A C library for multiple-precision floating-point computations. - -define LONG_DESC - The MPFR library is a C library for multiple-precision floating-point \ - computations with "correct rounding". The MPFR is efficient and \ - also has a well-defined semantics. It copies the good ideas from the \ - ANSI/IEEE-754 standard for double-precision floating-point arithmetic \ - (53-bit mantissa). MPFR is based on the GMP multiple-precision \ - library. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - mpfr_cv_working_tls=yes \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-thread-safe \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libmpfr.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/nano b/lfs/nano deleted file mode 100644 index b12226a..0000000 --- a/lfs/nano +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = nano -PKG_VER = 2.0.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Editors -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = slang - -URL = http://www.nano-editor.org/ -LICENSE = GPLv2+ -SHORT_DESC = A small text editor. - -define LONG_DESC - GNU nano is a small and friendly text editor. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc/nano \ - --enable-color \ - --enable-multibuffer \ - --enable-nanorc - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cd $(DIR_APP) && install -v -m644 -D doc/nanorc.sample /etc/nano/nanorc.sample - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/nasm b/lfs/nasm deleted file mode 100644 index 9121da2..0000000 --- a/lfs/nasm +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = nasm -PKG_VER = 2.02 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Languages -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = perl - -URL = http://nasm.sourceforge.net/ -LICENSE = LGPLv2+ -SHORT_DESC = A portable x86 assembler which uses Intel-like syntax. - -define LONG_DESC - NASM is the Netwide Assembler, a free portable assembler for the \ - Intel 80x86 microprocessor series, using primarily the traditional \ - Intel instruction mnemonics and syntax. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/ncurses b/lfs/ncurses deleted file mode 100644 index 161fb22..0000000 --- a/lfs/ncurses +++ /dev/null @@ -1,142 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = ncurses -PKG_VER = 5.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://invisible-island.net/ncurses/ncurses.html -LICENSE = MIT -SHORT_DESC = Ncurses support utilities. - -define LONG_DESC - The curses library routines are a terminal-independent method of \ - updating character screens with reasonable optimization. The ncurses \ - (new curses) library is a freely distributable replacement for the \ - discontinued 4.4 BSD classic curses library. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-coverity_fixes-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # We need wide character support for the Linux kernel menuconfig. - # --enable-symlinks installs the 'tic' program as a symbolic link (why not). - # --disable-root-environ restricts some environment variables, like TERMINFO, - # when running as root, so it can not be customized (why not). - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --with-shared \ - --without-debug \ - --without-ada \ - --enable-overwrite \ - --enable-widec \ - --without-cxx-binding \ - --enable-symlinks \ - --disable-root-environ \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - for lib in curses ncurses form panel menu; do \ - rm -vf $(TOOLS_DIR)/lib/lib$${lib}.so ; \ - echo "INPUT(-l$${lib}w)" >$(TOOLS_DIR)/lib/lib$${lib}.so ; \ - done -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --with-shared \ - --without-debug \ - --enable-widec \ - --disable-static \ - --enable-symlinks \ - --disable-root-environ - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - mv -v /usr/lib/libncursesw.so.5* /lib - ln -sfv ../../lib/libncursesw.so.5 /usr/lib/libncursesw.so - for lib in curses ncurses form panel menu; do \ - rm -vf /usr/lib/lib$${lib}.so ; \ - echo "INPUT(-l$${lib}w)" >/usr/lib/lib$${lib}.so ; \ - done - - rm -vf /usr/lib/libcursesw.so - echo "INPUT(-lncursesw)" >/usr/lib/libcursesw.so - ln -sfv libncurses.so /usr/lib/libcurses.so -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/net-snmp b/lfs/net-snmp deleted file mode 100644 index 9d131cc..0000000 --- a/lfs/net-snmp +++ /dev/null @@ -1,111 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = net-snmp -PKG_VER = 5.4.2.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Daemons -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = perl - -URL = http://net-snmp.sourceforge.net/download.html -LICENSE = BSD -SHORT_DESC = Simple Network Management Protocol Daemon - -define LONG_DESC - Simple Network Management Protocol (SNMP) is a widely used protocol \ - for monitoring the health and welfare of network equipment (eg. routers), \ - computer equipment and even devices like UPSs. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --libdir=/usr/lib \ - --with-default-snmp-version=2 \ - --with-sys-contact=root@ \ - --with-sys-location=localhost \ - --with-logfile=/var/log/snmpd.log \ - --with-persistent-directory=/var/net-snmp \ - --disable-embedded-perl \ - --disable-static - - cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - #Cleanup - rm -fv /usr/lib/libnetsnmp.la - rm -fv /usr/lib/libnetsnmpagent.la - rm -fv /usr/lib/libnetsnmpmibs.la - rm -fv /usr/lib/libnetsnmphelpers.la - rm -fv /usr/lib/libnetsnmptrapd.la - - # Install config - install -v -m644 $(DIR_SRC)/net-snmp-5.4.2.1/python/netsnmp/tests/snmpd.conf /etc/snmpd.conf - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/network b/lfs/network deleted file mode 100644 index 2de83c5..0000000 --- a/lfs/network +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = network -PKG_VER = -PKG_REL = 0 - -THISAPP = $(PKG_NAME) -DIR_APP = $(DIR_SOURCE)/$(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Michael Tremer michael.tremer@ipfire.org -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = dhcp iproute2 ppp sqlite vlan - -URL = http://www.ipfire.org/ -LICENSE = GPL3+ -SHORT_DESC = The IPFire Networking Scripts. - -define LONG_DESC - This script installs the IPFire Networking Scripts. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - - -mkdir -pv /etc/ppp - -mkdir -pv /lib/network - -mkdir -pv /sbin - -mkdir -pv /var/log/network - - install -m 755 -v $(DIR_APP)/network /sbin - - cp -rfv $(DIR_APP)/{hooks,hook-header,functions*,zone} /lib/network/ - - install -m 755 -v $(DIR_APP)/ppp/ip-updown /etc/ppp - ln -svf ip-updown /etc/ppp/ip-up - ln -svf ip-updown /etc/ppp/ip-down - - $(INSTALL_INITSCRIPT) - - @$(POSTBUILD) diff --git a/lfs/newt b/lfs/newt deleted file mode 100644 index 6c737d6..0000000 --- a/lfs/newt +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = newt -PKG_VER = 0.52.10 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = https://fedorahosted.org/releases/n/e/newt/ -LICENSE = LGPLv2 -SHORT_DESC = A library for text mode user interfaces. - -define LONG_DESC - Newt is a programming library for color text mode, widget based user \ - interfaces. Newt can be used to add stacked windows, entry widgets, \ - checkboxes, radio buttons, labels, plain text fields, scrollbars, \ - etc., to text mode user interfaces. This package also contains the \ - shared library needed by programs built with newt, as well as a \ - /usr/bin/dialog replacement called whiptail. Newt is based on the \ - slang library. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --without-gpm-support \ - --without-tcl \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - $(PYTHON_COMPILE) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/nfs-utils b/lfs/nfs-utils deleted file mode 100644 index 820c685..0000000 --- a/lfs/nfs-utils +++ /dev/null @@ -1,104 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = nfs-utils -PKG_VER = 1.1.6 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = portmap libevent libnfsidmap libgssglue #librpcsecgss - -URL = ftp://nfs.sourceforge.net/ -LICENSE = MIT and GPLv2 and GPLv2+ -SHORT_DESC = NFS utilities and supporting clients and daemons for the NFS server - -define LONG_DESC - The nfs-utils package provides a daemon for the kernel NFS server \ - and related tools, which provides a much higher level of performance \ - than the traditional Linux NFS server used by most users. This \ - package also contains the showmount program. Showmount queries the \ - mount daemon on a remote host for information about the NFS server \ - on the remote host. For example, showmount can display the clients \ - which are mounted on that host. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - nfs-utils-1.1.6-exp-subtree-warn-off.patch \ - nfs-utils-1.1.6-statdpath.patch \ - nfs-utils-1.1.6-smnotify-path.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --without-tcp-wrappers \ - --disable-gss \ - --disable-static - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/nfs-utils-1.1.6-statdpath.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/nfs-utils-1.1.6-smnotify-path.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/nfs-utils-1.1.6-exp-subtree-warn-off.patch - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/nmap b/lfs/nmap deleted file mode 100644 index 8b24fa6..0000000 --- a/lfs/nmap +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = nmap -PKG_VER = 5.00 -PKG_REL = 1 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Sniffer -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = libdnet libpcap lua openssl pcre - -URL = http://nmap.org/ -LICENSE = GPLv2+ -SHORT_DESC = Network exploration tool and security scanner. - -define LONG_DESC - Nmap is a utility for network exploration or security auditing. \ - It supports ping scanning, many port scanning techniques, and \ - TCP/IP fingerprinting. Nmap also offers flexible target and port \ - specification, decoy scanning, determination of TCP sequence \ - predictability characteristics, reverse-identd scanning, and more. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-mktemp.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-mktemp.patch - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --without-nmapfe \ - --without-zenmap - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/noip b/lfs/noip deleted file mode 100644 index 2a4eaf9..0000000 --- a/lfs/noip +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = noip -PKG_VER = 2.1.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Daemons -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.no-ip.com/ -LICENSE = GPLv2+ -SHORT_DESC = A dynamic DNS update client. - -define LONG_DESC - Keep your current IP address in sync with your No-IP host or domain \ - with this Dynamic Update Client (DUC). The client continually checks \ - for IP address changes in the background and automatically updates \ - the DNS at No-IP whenever it changes. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) PREFIX=/usr CONFDIR=/etc - cd $(DIR_APP) && cp noip2 /usr/bin/noip2 - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/nss_ldap b/lfs/nss_ldap deleted file mode 100644 index 416f352..0000000 --- a/lfs/nss_ldap +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = nss_ldap -PKG_VER = 262 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = LGPLv2+ -URL = http://www.padl.com/ -SHORT_DESC = NSS library and PAM module for LDAP. - -define LONG_DESC - This package includes two LDAP access clients: nss_ldap and \ - pam_ldap. Nss_ldap is a set of C library extensions that allow \ - X.500 and LDAP directory servers to be used as a primary source \ - of aliases, ethers, groups, hosts, networks, protocol, users, \ - RPCs, services, and shadow passwords. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --mandir=/usr/share/man \ - --with-ldap=openldap \ - --enable-schema-mapping - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - mv -vf /usr/lib/libnss_ldap.so.* /usr/lib/libnss_ldap.so - - @rm -rf $(DIR_APP) /etc/nsswitch.ldap - @$(POSTBUILD) diff --git a/lfs/ntp b/lfs/ntp deleted file mode 100644 index b931acd..0000000 --- a/lfs/ntp +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = ntp -PKG_VER = 4.2.4p7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = openssl - -LICENSE = MIT, BSD and GPLv2 -URL = http://www.ntp.org/ -SHORT_DESC = The NTP daemon and utilities. - -define LONG_DESC - The Network Time Protocol (NTP) is used to synchronize a computer's \ - time with another reference time source. This package includes ntpd \ - and utilities used to query and configure the ntpd daemon. -endef - -CFLAGS += -DMOD_NANO - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --with-binsubdir=sbin - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - $(INSTALL_CONFIG) $(DIR_SOURCE)/$(PKG_NAME)/ntp.conf \ - > /etc/ntp.conf - - $(INSTALL_INITSCRIPT) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/openldap b/lfs/openldap deleted file mode 100644 index 6e43b5c..0000000 --- a/lfs/openldap +++ /dev/null @@ -1,131 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = openldap -PKG_VER = 2.4.17 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tgz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Daemons -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = berkeley cyrus-sasl openssl pth - -LICENSE = OpenLDAP -URL = http://www.openldap.org/ -SHORT_DESC = LDAP support libraries - -define LONG_DESC - OpenLDAP is an open source suite of LDAP (Lightweight Directory Access \ - Protocol) applications and development tools. LDAP is a set of \ - protocols for accessing directory services over the Internet, similar \ - to the way DNS information is propagated over the Internet. The \ - openldap package contains configuration files, libraries, and \ - documentation for OpenLDAP. -endef - -CFLAGS += -D_GNU_SOURCE -D_REENTRANT - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-disable_sys_err.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-disable_sys_err.patch - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libexecdir=/usr/lib \ - --sysconfdir=/etc \ - --localstatedir=/var \ - --with-threads=posix \ - --disable-debug \ - --disable-perl \ - --enable-dynamic \ - --enable-crypt \ - --enable-modules \ - --enable-rlookups \ - --enable-backends=mod \ - --enable-overlays=mod \ - --enable-sql=no \ - --enable-ndb=no \ - --disable-static - - cd $(DIR_APP) && make depend - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - mv -v /usr/lib/slapd /usr/sbin/slapd - rm -rvf /var/openldap-data /usr/lib/openldap/*.la - - for LINK in lber ldap ldap_r; do \ - chmod -v 0755 /usr/lib/$$(readlink /usr/lib/lib$${LINK}.so); \ - rm -vf /usr/lib/lib$${LINK}.la; \ - done - - # Install configuration - $(INSTALL_INITSCRIPT) - $(INSTALL_CONFIG) $(DIR_SOURCE)/$(PKG_NAME)/slapd.conf \ - > /etc/$(PKG_NAME)/slapd.conf - - -mkdir -pv /var/lib/ldap - chmod 700 -Rv /var/lib/ldap - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/openlldp b/lfs/openlldp deleted file mode 100644 index c93df8b..0000000 --- a/lfs/openlldp +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = openlldp -PKG_VER = 0.3alpha -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://openlldp.sourceforge.net/ -LICENSE = GPL -SHORT_DESC = Utilities for the Link Layer Discovery Protocol. - -define LONG_DESC - The OpenLLDP project aims to provide a comprehensive implementation of \ - the IEEE standard 802.1AB Link Layer Discovery Protocol. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - $(INSTALL_INITSCRIPT) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/openssh b/lfs/openssh deleted file mode 100644 index d989517..0000000 --- a/lfs/openssh +++ /dev/null @@ -1,105 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = openssh -PKG_VER = 5.3p1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Internet -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = openssl pam - -LICENSE = BSD -URL = http://www.openssh.com/portable.html -SHORT_DESC = An open source implementation of SSH protocol versions 1 and 2. - -define LONG_DESC - SH (Secure SHell) is a program for logging into and executing \ - commands on a remote machine. SSH is intended to replace rlogin and \ - rsh, and to provide secure encrypted communications between two \ - untrusted hosts over an insecure network. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - install -v -m700 -d /var/lib/sshd - chown -v root:sys /var/lib/sshd - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc/ssh \ - --datadir=/usr/share/sshd \ - --libexecdir=/usr/lib/openssh \ - --with-md5-passwords \ - --with-privsep-path=/var/lib/sshd \ - --with-pam - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - sed 's@d/login@d/sshd@g' /etc/pam.d/login > /etc/pam.d/sshd - chmod 644 /etc/pam.d/sshd - - @$(INSTALL_INITSCRIPT) - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/sshd_config /etc/ssh/sshd_config - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/openssl b/lfs/openssl deleted file mode 100644 index 7d0fc60..0000000 --- a/lfs/openssl +++ /dev/null @@ -1,153 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = openssl -PKG_VER = 0.9.8k -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = OpenSSL -URL = http://www.openssl.org/ -SHORT_DESC = A general purpose cryptography library with TLS implementation. - -define LONG_DESC - The OpenSSL toolkit provides support for secure communications between \ - machines. OpenSSL includes a certificate management tool and shared \ - libraries which provide various cryptographic algorithms and protocols. -endef - -ifneq "$(MACHINE)" "i686" - SSL_ARCH = no-asm 386 # 386 implies no-sse2 -endif - -# These arches do support sse2. -ifneq "$(TARGET)" "via-c7" -ifneq "$(TARGET)" "atom" -ifneq "$(TARGET)" "core2duo" - SSL_ARCH += no-sse2 -endif -endif -endif - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-fix_manpages-1.patch \ - $(THISAPP)-enginesdir.patch \ - $(THISAPP)-no-rpath.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-fix_manpages-1.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-enginesdir.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-no-rpath.patch - - cd $(DIR_APP) && sed -i -e 's/-O3 -fomit-frame-pointer/$(CFLAGS)/' Configure - - cd $(DIR_APP) && sed -e 's/__OpenBSD__/__linux__/' -e 's/arandom/urandom/' \ - -i.orig crypto/rand/randfile.c - - cd $(DIR_APP) && sed 's/__OpenBSD__/__linux__/' -i.orig crypto/uid.c - cd $(DIR_APP) && sed -e 's/__OpenBSD__/__linux__/' -i crypto/rand/rand_unix.c - - cd $(DIR_APP) && find crypto/ -name Makefile -exec \ - sed 's/^ASFLAGS=/&-Wa,--noexecstack /' -i.orig {} ; - - cd $(DIR_APP) && \ - ./Configure \ - --prefix=/usr \ - --openssldir=/etc/pki/tls \ - --enginesdir=/usr/lib/openssl/engines \ - linux-elf $(SSL_ARCH) \ - shared \ - zlib-dynamic \ - enable-camellia \ - enable-seed \ - enable-tlsext \ - enable-rfc3779 \ - no-idea \ - no-mdc2 \ - no-rc5 \ - no-ec \ - no-ecdh \ - no-ecdsa \ - -DSSL_FORBID_ENULL - - # Build. - cd $(DIR_APP) && make all build-shared #$(PARALLELISMFLAGS) - - # Generate hashes for the included certs. - cd $(DIR_APP) && make rehash build-shared - - cd $(DIR_APP) && make install build-shared - cd $(DIR_APP) && cp -v -r certs /etc/pki/tls - - mv -v /usr/lib/{libcrypto,libssl}.a /usr/lib/static - install -d /usr/lib/openssl - mv -v /usr/lib/engines /usr/lib/openssl - - -mkdir -m700 /etc/pki/CA - -mkdir -m700 /etc/pki/CA/private - - install -m 0644 $(DIR_SOURCE)/$(PKG_NAME)/openssl.cnf /etc/pki/tls - - @rm -rf $(DIR_APP) /etc/pki/tls/man - @$(POSTBUILD) diff --git a/lfs/openvpn b/lfs/openvpn deleted file mode 100644 index a9fabbe..0000000 --- a/lfs/openvpn +++ /dev/null @@ -1,106 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = openvpn -PKG_VER = 2.1_rc20 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/VPN -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = iproute2 lzo openssl - -URL = http://openvpn.net/ -LICENSE = GPLv2 -SHORT_DESC = A full-featured SSL VPN solution. - -define LONG_DESC - OpenVPN is a robust and highly flexible tunneling application that uses all \ - of the encryption, authentication, and certification features of the \ - OpenSSL library to securely tunnel IP networks over a single UDP or TCP \ - port. It can use the Marcus Franz Xaver Johannes Oberhumer's LZO library \ - for compression. -endef - -PLUGINS = auth-pam down-root - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-pthread \ - --enable-password-save \ - --enable-iproute2 - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && for plugin in $(PLUGINS); do \ - make -C plugin/$$plugin; \ - done - cd $(DIR_APP) && make install - mkdir -p /usr/lib/$(PKG_NAME)/plugin/lib - cd $(DIR_APP) && for plugin in $(PLUGINS); do \ - install -m 0755 plugin/$$plugin/openvpn-$$plugin.so \ - /usr/lib/$(PKG_NAME)/plugin/lib/openvpn-$$plugin.so; \ - done - -mkdir -p /var/run/$(PKG_NAME) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pakfire b/lfs/pakfire deleted file mode 100644 index 1ebbd55..0000000 --- a/lfs/pakfire +++ /dev/null @@ -1,84 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pakfire -PKG_VER = 0.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DIR_APP = $(DIR_SOURCE)/$(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Michael Tremer michael.tremer@ipfire.org -GROUP = System/Packaging -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = cpio xz python python-sqlite2 python-urlgrabber system-release - -URL = http://www.ipfire.org/ -LICENSE = GPLv3+ -SHORT_DESC = Package installer/updater. - -define LONG_DESC - Pakfire optains package lists from the mirrors and can install and update \ - packages. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - cd $(DIR_APP) && make VERSION="$(PKG_VER)" $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cd $(DIR_APP) && make clean - $(PYTHON_COMPILE) - @$(POSTBUILD) diff --git a/lfs/pam b/lfs/pam deleted file mode 100644 index 880e8ab..0000000 --- a/lfs/pam +++ /dev/null @@ -1,117 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = Linux-PAM -PKG_VER = 1.1.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = bison flex -DEPS = cracklib - -LICENSE = BSD and GPLv2+ and BSD with advertising -URL = http://www.us.kernel.org/pub/linux/libs/pam/index.html -SHORT_DESC = An extensible library which provides authentication for applications. - -define LONG_DESC - PAM (Pluggable Authentication Modules) is a system security tool that \ - allows system administrators to set authentication policy without \ - having to recompile programs that handle authentication. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --libdir=/lib \ - --sbindir=/lib/security \ - --enable-securedir=/lib/security \ - --docdir=/usr/share/doc/Linux-PAM-$(PKG_VER) \ - --enable-read-both-confs - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - chmod -v 4755 /lib/security/unix_chkpwd - mv -v /lib/security/pam_tally /sbin - - rm -vf /lib/libpam{,c,_misc}.la /lib/security/*.la - - if [ -L /lib/libpam.so ]; then \ - for LINK in libpam{,c,_misc}.so; do \ - ln -v -sf ../../lib/$$(readlink /lib/$${LINK}) /usr/lib/$${LINK} && \ - rm -v /lib/$${LINK}; \ - done; \ - fi - - useradd -D -b /home - sed -i 's/yes/no/' /etc/default/useradd - install -v -m644 $(DIR_SOURCE)/pam/pam_env.conf /etc/security/pam_env.conf - cp -vf $(DIR_SOURCE)/pam/{login.defs,securetty} /etc - - install -v -d -m755 /etc/pam.d - cp -vf $(DIR_SOURCE)/pam.d/{other,system-auth} /etc/pam.d/ - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pam_ldap b/lfs/pam_ldap deleted file mode 100644 index c948b8b..0000000 --- a/lfs/pam_ldap +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pam_ldap -PKG_VER = 184 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = openldap - -LICENSE = GPL and LGPL -URL = http://www.padl.com/OSS/pam_ldap.html -SHORT_DESC = A pam/ldap module that supports password changes. - -define LONG_DESC - The pam_ldap module provides the means for Solaris and Linux servers \ - and workstations to authenticate against LDAP directories, and to \ - change their passwords in the directory. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --libdir=/lib \ - --mandir=/usr/share/man - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pango b/lfs/pango deleted file mode 100644 index 1038252..0000000 --- a/lfs/pango +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pango -PKG_VER = 1.22.3 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = LGPLv2+ -URL = http://www.pango.org/ -SHORT_DESC = System for layout and rendering of internationalized text. - -define LONG_DESC - Pango is a library for laying out and rendering of text, with an \ - emphasis on internationalization. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/libpango{,cairo,ft2}-1.0.la /usr/lib/pango/1.6.0/modules/*.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/parted b/lfs/parted deleted file mode 100644 index f0b77a4..0000000 --- a/lfs/parted +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = parted -PKG_VER = 1.9.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libtool - -LICENSE = GPLv3+ -URL = http://www.gnu.org/software/parted -SHORT_DESC = The GNU disk partition manipulation program. - -define LONG_DESC - The GNU Parted program allows you to create, destroy, resize, move, \ - and copy hard disk partitions. Parted can be used for creating space \ - for new operating systems, reorganizing disk usage, and copying data \ - to new hard disks. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) - @cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --without-readline \ - --disable-nls \ - --disable-Werror \ - --disable-dependency-tracking \ - --disable-debug \ - --with-gnu-ld \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/libparted.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/passwd b/lfs/passwd deleted file mode 100644 index e629cd0..0000000 --- a/lfs/passwd +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = passwd -PKG_VER = 0.76 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = glib2 libuser pam - -URL = http://fedorahosted.org/passwd -LICENSE = BSD -SHORT_DESC = An utility for setting or changing passwords using PAM. - -define LONG_DESC - This package contains a system utility (passwd) which sets \ - or changes passwords, using PAM (Pluggable Authentication \ - Modules) library. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --without-selinux \ - --without-audit \ - --disable-static - cd $(DIR_APP) && make DEBUG= RPM_OPT_FLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/patch b/lfs/patch deleted file mode 100644 index 4b64d18..0000000 --- a/lfs/patch +++ /dev/null @@ -1,113 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = patch -PKG_VER = 2.5.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = GPLv2+ -URL = http://www.gnu.org/software/patch/patch.html -SHORT_DESC = Utility for modifying/upgrading files. - -define LONG_DESC - The patch program applies diff files to originals. The diff \ - command is used to compare an original to a changed file.\ - Diff lists the changes made to the file. A person who has \ - the original file can then use the patch command with the \ - diff file to add the changes to their original file. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-mkstemp-1.patch \ - $(THISAPP)-fixes-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # Some fixes: - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-fixes-1.patch - - # Get rid of mktemp(3): - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-mkstemp-1.patch - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pax-utils b/lfs/pax-utils deleted file mode 100644 index c8a1dde..0000000 --- a/lfs/pax-utils +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pax-utils -PKG_VER = 0.1.19 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Security/Tools -CORE = yes -EXTRA = no -DEBUG = no # But it gets packaged on debug builds. -BUILD_DEPS = -ifeq "$(STAGE)" "base" - DEPS = libcap2 -endif - -URL = http://www.gentoo.org/proj/en/hardened/pax-utils.xml -LICENSE = GPLv2+ -SHORT_DESC = Utilities for checking PaX features. - -define LONG_DESC - This package contains several utilities for checking PaX features. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && make scanelf CFLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) - cd $(DIR_APP) && install -m 755 -v scanelf $(TOOLS_DIR)/bin/scanelf -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" USE_CAP=yes $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/paxctl b/lfs/paxctl deleted file mode 100644 index 296dbd0..0000000 --- a/lfs/paxctl +++ /dev/null @@ -1,86 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = paxctl -PKG_VER = 0.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = GPL v2 -URL = http://pax.grsecurity.net/ -SHORT_DESC = Application to control PaX flags. - -define LONG_DESC - paxctl may be used to control PaX flags on a per-binary basis. PaX \ - is a set of kernel security patches to enhance a system's security. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && sed -e "s/^CFLAGS.*/CFLAGS=$(CFLAGS)/" -i Makefile - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/paxtest b/lfs/paxtest deleted file mode 100644 index ea2bacf..0000000 --- a/lfs/paxtest +++ /dev/null @@ -1,89 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = paxtest -PKG_VER = 0.9.7-pre4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Security/Tools -CORE = yes -EXTRA = no -DEBUG = yes -BUILD_DEPS = -DEPS = - -URL = http://pax.grsecurity.org/ -LICENSE = GPLv2+ -SHORT_DESC = Utilities for testing PaX configuration. - -define LONG_DESC - This package contains several files for checking the PaX configuration \ - and checks if it all works correctly. -endef - -define QUALITY_AGENT_WHITELIST_EXECSTACK - /usr/lib/paxtest -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make -f Makefile.generic RUNDIR=/usr/lib/paxtest - cd $(DIR_APP) && make -f Makefile.generic install DESTDIR=/ RUNDIR=/usr/lib/paxtest BINDIR=/usr/bin - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pciutils b/lfs/pciutils deleted file mode 100644 index 55cee0f..0000000 --- a/lfs/pciutils +++ /dev/null @@ -1,88 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pciutils -PKG_VER = 3.1.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://atrey.karlin.mff.cuni.cz/~mj/pciutils.shtml -LICENSE = GPLv2+ -SHORT_DESC = PCI bus related utilities. - -define LONG_DESC - The pciutils package contains various utilities for inspecting \ - and setting devices connected to the PCI bus. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make SHARED=yes OPT=$(CLFLAGS) PREFIX=/usr ZLIB=no $(PARALLELISMFLAGS) - cd $(DIR_APP) && make SHARED=yes PREFIX=/usr install - install -v -m 755 -d /usr/include/pci - cd $(DIR_APP) && install -v -m 644 lib/*.h /usr/include/pci - ln -svf libpci.so.3 /usr/lib/libpci.so - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pcre b/lfs/pcre deleted file mode 100644 index b49811c..0000000 --- a/lfs/pcre +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pcre -PKG_VER = 7.9 -PKG_REl = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = bzip2 zlib - -LICENSE = BSD -URL = http://www.pcre.org/ -SHORT_DESC = Perl-compatible regular expression library - -define LONG_DESC - Perl-compatible regular expression library. PCRE has its own native \ - API, but a set of "wrapper" functions that are based on the POSIX \ - API are also supplied in the library libpcreposix. -endef - -CFLAGS += -fPIC - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --docdir=/usr/share/doc/pcre-$(PKG_VER) \ - --enable-utf8 \ - --enable-pcregrep-libz \ - --enable-pcregrep-libbz2 \ - --enable-unicode-properties \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - mv -v /usr/lib/libpcre.so.* /lib/ - ln -v -sf ../../lib/libpcre.so.0 /usr/lib/libpcre.so - rm -vf /usr/lib/libpcre{,cpp,posix}.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pdns b/lfs/pdns deleted file mode 100644 index df8dc1a..0000000 --- a/lfs/pdns +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pdns -PKG_VER = 2.9.22 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/DNS -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = boost openldap sqlite - -URL = http://powerdns.com/ -LICENSE = GPLv2 -SHORT_DESC = A modern, advanced and high performance authoritative-only nameserver. - -define LONG_DESC - The PowerDNS Nameserver is a modern, advanced and high performance \ - authoritative-only nameserver. It is written from scratch and conforms \ - to all relevant DNS standards documents. \ - Furthermore, PowerDNS interfaces with almost any database. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-gcc44-fixes.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-gcc44-fixes.patch - cd $(DIR_APP) && CPPFLAGS="-DLDAP_DEPRECATED" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc/pdns \ - --disable-static \ - --with-modules="" \ - --with-dynmodules="pipe geo ldap gsqlite3" - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/lib{geo,gsqlite3,ldap,pipe}backend.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pdns-recursor b/lfs/pdns-recursor deleted file mode 100644 index 7320664..0000000 --- a/lfs/pdns-recursor +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pdns-recursor -PKG_VER = 3.1.7.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/DNS -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = lua boost - -URL = http://powerdns.com/ -LICENSE = GPLv2 -SHORT_DESC = A modern, advanced and high performance recursing nameserver. - -define LONG_DESC - PowerDNS Recursor is a non authoritative/recursing DNS server. Use this \ - package if you need a dns cache for your network. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && LUA=1 LUA_CPPFLAGS_CONFIG= LUA_LIBS_CONFIG=-llua \ - make OPTFLAGS= PROFILEFLAGS=-fprofile-use #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - $(INSTALL_INITSCRIPT) - rm -vf /etc/init.d/pdns-recursor - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/perl b/lfs/perl deleted file mode 100644 index 02f789b..0000000 --- a/lfs/perl +++ /dev/null @@ -1,150 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = perl -PKG_VER = 5.10.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Languages -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = GPL+ or Artistic and GPLv2+ or Artistic -URL = http://www.perl.org/ -SHORT_DESC = Practical Extraction and Report Language. - -define LONG_DESC - Perl is a high-level programming language with roots in C, sed, awk \ - and shell scripting. Perl is good at handling processes and files, \ - and is especially good at handling text. Perl's hallmarks are \ - practicality and efficiency. While it is used to do a lot of \ - different things, Perl's most common applications are system \ - administration utilities and web programming. A large proportion of \ - the CGI scripts on the web are written in Perl. You need the perl \ - package installed on your system so that your system can handle Perl \ -scripts. -endef - -define QUALITY_AGENT_WHITELIST_RPATH - /usr/lib/perl5/*/auto/DB_File/DB_File.so \ - /usr/lib/perl5/*/auto/Time/HiRes/HiRes.so \ - /usr/lib/perl5/*/auto/Compress/Raw/Zlib/Zlib.so -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-page-1.patch \ - $(THISAPP)-security_fix-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_SRC)/perl* && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -mkdir -v $(DIR_SRC)/perl-build - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-page-1.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-security_fix-1.patch - cd $(DIR_APP) && sed -i 's/command /command[ -]/' makedepend.SH - - # -Dlibc, locincpth, loclibpth, glibpth, and usrinc, are equivilent to the LFS - # Perl libc patch. - - # ./Configure is used instead of ./configure.gnu because it supports builds - # from an object directory. -Dmksymlinks is also used, to support read-only - # sources. -d -e are added to accept all defaults, otherwise ./Configure will - # be interactive. - cd $(DIR_SRC)/perl-build && \ - $(DIR_APP)/Configure \ - -Dcc=$(IFS_TARGET)-gcc \ - -Dprefix=$(TOOLS_DIR) \ - -Dlibc=$(shell ls $(TOOLS_DIR)/lib/libc-*.so) \ - -Ulocincpth \ - -Uloclibpth \ - -Dglibpth="$(TOOLS_DIR)/lib" \ - -Dusrinc="$(TOOLS_DIR)/include" \ - -Dmksymlinks \ - -d -e - cd $(DIR_SRC)/perl-build && make #$(PARALLELISMFLAGS) - cd $(DIR_SRC)/perl-build && make LNS="cp" install -endif - -ifeq "$(STAGE)" "base" - echo "127.0.0.1 localhost $(hostname)" > /etc/hosts - - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-page-1.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-security_fix-1.patch - - cd $(DIR_APP) && sed -i 's/command /command[ -]/' makedepend.SH - - cd $(DIR_APP) && sed -i -e "s|BUILD_ZLIB\s*= True|BUILD_ZLIB = False|" \ - -e "s|INCLUDE\s*= ./zlib-src|INCLUDE = /usr/include|" \ - -e "s|LIB\s*= ./zlib-src|LIB = /usr/lib|" \ - ext/Compress/Raw/Zlib/config.in - - cd $(DIR_APP) && ./configure.gnu --prefix=/usr \ - -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 \ - -Dpager="/usr/bin/less -isR" - - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -f /etc/hosts -endif - - @rm -rf $(DIR_SRC)/perl* - @$(POSTBUILD) diff --git a/lfs/perl-xml-parser b/lfs/perl-xml-parser deleted file mode 100644 index 965f99d..0000000 --- a/lfs/perl-xml-parser +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = XML-Parser -PKG_VER = 2.34 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = perl - -LICENSE = GPL+ or Artistic -URL = http://search.cpan.org/dist/XML-Parser/ -SHORT_DESC = Perl module for parsing XML files. - -define LONG_DESC - This module provides ways to parse XML documents. It is built on \ - top of XML::Parser::Expat, which is a lower level interface to \ - James Clark's expat library. -endef - -define QUALITY_AGENT_WHITELIST_RPATH - /usr/lib/perl5/site_perl/*/auto/XML/Parser/Expat/Expat.so -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && perl Makefile.PL - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pinentry b/lfs/pinentry deleted file mode 100644 index 79ae3eb..0000000 --- a/lfs/pinentry +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pinentry -PKG_VER = 0.7.6 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libgpg-error - -URL = http://www.gnupg.org/ -LICENSE = GPLv2 -SHORT_DESC = Collection of simple PIN or passphrase entry dialogs. - -define LONG_DESC - Pinentry is a collection of simple PIN or passphrase entry dialogs which \ - utilize the Assuan protocol as described by the aegypten project; see \ - http://www.gnupg.org/aegypten/ for details. This package contains the \ - curses (text) based version of the PIN entry dialog. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-pin-entry-curses \ - --enable-fallback-curses \ - --disable-pinentry-gtk \ - --disable-pinentry-gtk2 \ - --disable-pinentry-qt - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pixman b/lfs/pixman deleted file mode 100644 index fe5a378..0000000 --- a/lfs/pixman +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pixman -PKG_VER = 0.15.18 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = MIT -URL = http://xorg.freedesktop.org/archive/individual/lib/ -SHORT_DESC = Pixel manipulation library. - -define LONG_DESC - Pixman is a pixel manipulation library for X and cairo. -endef - -CONFIGURE_ARGS = --disable-mmx --disable-sse2 - -ifeq "$(TARGET)" "via-c7" - CONFIGURE_ARGS = --enable-mmx #--enable-sse2 -endif -ifeq "$(TARGET)" "atom" - CONFIGURE_ARGS = --enable-mmx --enable-sse2 -endif - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static \ - $(CONFIGURE_ARGS) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/libpixman-1.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pkg-config b/lfs/pkg-config deleted file mode 100644 index 86598b2..0000000 --- a/lfs/pkg-config +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pkg-config -PKG_VER = 0.22 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Tools -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = GPLv2+ -URL = http://pkgconfig.freedesktop.org/ -SHORT_DESC = A tool for determining compilation options. - -define LONG_DESC - The pkgconfig tool determines compilation options. For each required \ - library, it reads the configuration file and outputs the necessary \ - compiler and linker flags. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/popt b/lfs/popt deleted file mode 100644 index 9703c32..0000000 --- a/lfs/popt +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = popt -PKG_VER = 1.15 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = gettext - -LICENSE = MIT -URL = http://www.rpm5.org/ -SHORT_DESC = C library for parsing command line parameters. - -define LONG_DESC - Popt is a C library for parsing command line parameters. Popt was \ - heavily influenced by the getopt() and getopt_long() functions, but \ - it improves on them by allowing more powerful argument expansion. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - #cd $(DIR_APP) && sed -i -e "/*origOptString ==/c 0)" popt.c - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/libpopt.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/portmap b/lfs/portmap deleted file mode 100644 index 3595bad..0000000 --- a/lfs/portmap +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = portmap -PKG_VER = 6.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)_$(PKG_VER) -DL_FILE = $(THISAPP).tgz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://neil.brown.name/portmap/ -LICENSE = BSD 3 - Clause -SHORT_DESC = DARPA port to RPC program number mapper. - -define LONG_DESC - Portmap is a server that converts RPC program numbers into \ - DARPA protocol port numbers. It must be running in order to \ - make RPC calls. When an RPC server is started, it will tell \ - portmap what port number it is listening to, and what RPC \ - program numbers it is prepared to serve. When a client \ - wishes to make an RPC call to a given program number, it \ - will first contact portmap on the server machine to determine \ - the port number where RPC packets should be sent. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - portmap-6.0-tcpd.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # Patch to allow compile without tcp-wrappers - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/portmap-6.0-tcpd.patch - - cd $(DIR_APP) && make NO_TCP_WRAPPER=NO $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/ppp b/lfs/ppp deleted file mode 100644 index c5ba41c..0000000 --- a/lfs/ppp +++ /dev/null @@ -1,142 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = ppp -PKG_VER = 2.4.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Daemons -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libpcap linux-atm - -LICENSE = BSD and LGPLv2+ and GPLv2+ and Public Domain -URL = ftp://ftp.samba.org/pub/ppp/ -SHORT_DESC = The PPP (Point-to-Point Protocol) daemon. - -define LONG_DESC - The ppp package contains the PPP (Point-to-Point Protocol) daemon and \ - documentation for PPP support. The PPP protocol provides a method for \ - transmitting datagrams over serial point-to-point links. PPP is \ - usually used to dial in to an ISP or other organization over a modem \ - and phone line. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-libutil.patch \ - $(THISAPP)-pie.patch \ - $(THISAPP)-fix.patch \ - $(THISAPP)-ipv6-accept-remote.patch \ - $(THISAPP)-pppoatm-mtu.patch \ - $(THISAPP)-local.patch \ - $(THISAPP)-dontwriteetc.patch \ - $(THISAPP)-closelog.patch \ - $(THISAPP)-response_len.patch \ - $(THISAPP)-new_speeds.patch \ - $(THISAPP)-bogus_dns_addr.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # This patch removes logwtmp in libutil, because glibc also provides that. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-libutil.patch - cd $(DIR_APP) && sed -e "s/^LIBS =/LIBS=-lutil/" -i pppd/Makefile.linux - - # This patch adds pie chat to ppp. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-pie.patch - - # Add ipv6cp-accept-remote to allow DSL to work with demand dial and native IPv6 - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-ipv6-accept-remote.patch - - # This patch removes local from the path of ppp and all used binaries. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-local.patch - - # Some more patches, but the name of each should tell what it's doing. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-fix.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-dontwriteetc.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-pppoatm-mtu.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-closelog.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-bogus_dns_addr.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-new_speeds.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-response_len.patch - - cd $(DIR_APP) && sed -e "s@^RUNDIR .*@RUNDIR = /var/run/ppp@" \ - -e "s@^LOGDIR .*@LOGDIR = /var/log/ppp@" \ - -i linux/Makefile.top - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - - cd $(DIR_APP) && make CC="gcc $(CFLAGS)" HAVE_INET6=yes USE_PAM=y $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -rfv /etc/ppp/plugins - - -mkdir -pv /etc/ppp - touch /etc/ppp/secrets - chmod -v 600 /etc/ppp/secrets - ln -svf secrets /etc/ppp/pap-secrets - ln -svf secrets /etc/ppp/chap-secrets - - cp -vf $(DIR_SOURCE)/pam.d/$(PKG_NAME) /etc/pam.d/ - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pptp b/lfs/pptp deleted file mode 100644 index 8f761c5..0000000 --- a/lfs/pptp +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pptp -PKG_VER = 1.7.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Dialin -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = iproute2 ppp - -URL = http://pptpclient.sourceforge.net/ -LICENSE = GPLv2+ -SHORT_DESC = Point-to-Point Tunneling Protocol (PPTP) Client. - -define LONG_DESC - Client for the proprietary Microsoft Point-to-Point Tunneling \ - Protocol, PPTP. Allows connection to a PPTP based VPN as used \ - by employers and some cable and ADSL service providers. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-ip-path.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-ip-path.patch - cd $(DIR_APP) && sed -i -e "s/install -o root -m 555 pptp/install -m 755 pptp/" Makefile - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /etc/ppp/options.pptp - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/procps b/lfs/procps deleted file mode 100644 index 10cbdeb..0000000 --- a/lfs/procps +++ /dev/null @@ -1,89 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = procps -PKG_VER = 3.2.8 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = GPLv2+ and LGPLv2+ -URL = http://procps.sourceforge.net/ -SHORT_DESC = System and process monitoring utilities. - -define LONG_DESC - The procps package contains a set of system utilities that provide \ - system information. Procps includes ps, free, skill, pkill, pgrep, \ - snice, tload, top, uptime, vmstat, w, watch and pdwx. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-watch_unicode-2.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-watch_unicode-2.patch - cd $(DIR_APP) && make SHARED=1 CFLAGS="$(CFLAGS)" \ - W_SHOWFROM=-DW_SHOWFROM $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/psmisc b/lfs/psmisc deleted file mode 100644 index 0f00854..0000000 --- a/lfs/psmisc +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = psmisc -PKG_VER = 22.8 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -LICENSE = GPLv2+ -URL = http://sourceforge.net/projects/psmisc -SHORT_DESC = Utilities for managing processes on your system. - -define LONG_DESC - The psmisc package contains utilities for managing processes on your \ - system: pstree, killall and fuser. The pstree command displays a \ - tree structure of all of the running processes on your system. The \ - killall command sends a specified signal (SIGTERM if nothing is \ - specified) to processes identified by name. The fuser command \ - identifies the PIDs of processes that are using specified files or \ - filesystems. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pth b/lfs/pth deleted file mode 100644 index 909b1ba..0000000 --- a/lfs/pth +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pth -PKG_VER = 2.0.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/pth/ -LICENSE = GPLv3+ -SHORT_DESC = GNU Pth - The GNU Portable Threads. - -define LONG_DESC - The Pth package contains a very portable POSIX/ANSI-C based library for \ - Unix platforms which provides non-preemptive priority-based scheduling for \ - multiple threads of execution (multithreading) inside event-driven \ - applications. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - # Don't add the --enable-pthread parameter to the configure command below - # else you will overwrite the pthread library and interface header - # installed by the Glibc package. - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/libpth.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pychecker b/lfs/pychecker deleted file mode 100644 index 7d463d0..0000000 --- a/lfs/pychecker +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pychecker -PKG_VER = 0.8.17 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Debuggers -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://pychecker.sourceforge.net -LICENSE = BSD -SHORT_DESC = A python source code checking tool. - -define LONG_DESC - PyChecker is a python source code checking tool to help you find \ - common bugs. It is meant to find problems that are typically caught by \ - a compiler. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && python setup.py build - cd $(DIR_APP) && python setup.py install - $(PYTHON_COMPILE) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/pyfire b/lfs/pyfire deleted file mode 100644 index e1277a9..0000000 --- a/lfs/pyfire +++ /dev/null @@ -1,84 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pyfire -PKG_VER = 0.99.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DIR_APP = $(DIR_SOURCE)/$(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -DEPS = python-dbus hal -BUILD_DEPS = - -LICENSE = GPLv3+ -URL = http://www.ipfire.org -SHORT_DESC = A python library for easy functions. - -define LONG_DESC - Pyfire is a library which offers a lot of easy to use functions. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - - cd $(DIR_APP) && make install - cd $(DIR_APP) && make clean - - $(PYTHON_COMPILE) - @$(POSTBUILD) diff --git a/lfs/python b/lfs/python deleted file mode 100644 index 508379e..0000000 --- a/lfs/python +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = Python -PKG_VER = 2.6.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Languages -CORE = yes -EXTRA = no -DEBUG = no -DEPS = -BUILD_DEPS = - -LICENSE = Python -URL = http://www.python.org -SHORT_DESC = An interpreted, interactive, object-oriented programming language. - -define LONG_DESC - Python is an interpreted, interactive, object-oriented programming \ - language often compared to Tcl, Perl, Scheme or Java. Python includes \ - modules, classes, exceptions, very high level dynamic data types and \ - dynamic typing. Python supports interfaces to many system calls and \ - libraries, as well as to various windowing systems. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && OPT="$(CFLAGS)" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-shared - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -rf /usr/lib/python*/test/ - $(PYTHON_COMPILE) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-IPy b/lfs/python-IPy deleted file mode 100644 index e60f1a1..0000000 --- a/lfs/python-IPy +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = IPy -PKG_VER = 0.62 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -DEPS = python -BUILD_DEPS = - -LICENSE = BSD -URL = http://software.inl.fr/trac/trac.cgi/wiki/IPy -SHORT_DESC = Python module for handling IPv4 and IPv6 Addresses and Networks. - -define LONG_DESC - IPy is a Python module for handling IPv4 and IPv6 Addresses and \ - Networks in a fashion similar to perl's Net::IP and friends. The IP \ - class allows a comfortable parsing and handling for most notations \ - in use for IPv4 and IPv6 Addresses and Networks. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && python setup.py install - - $(PYTHON_COMPILE) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-cracklib b/lfs/python-cracklib deleted file mode 120000 index 741275a..0000000 --- a/lfs/python-cracklib +++ /dev/null @@ -1 +0,0 @@ -cracklib \ No newline at end of file diff --git a/lfs/python-cryptsetup b/lfs/python-cryptsetup deleted file mode 100644 index 86b1b48..0000000 --- a/lfs/python-cryptsetup +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = python-cryptsetup -PKG_VER = 0.0.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = cryptsetup-luks python - -URL = http://msivak.fedorapeople.org/pycryptsetup -LICENSE = GPLv2+ -SHORT_DESC = Python bindings for cryptsetup. - -define LONG_DESC - A python module to ease the manipulation with LUKS devices. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && python setup.py build - cd $(DIR_APP) && python setup.py install -O1 --skip-build - - $(PYTHON_COMPILE) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-dbus b/lfs/python-dbus deleted file mode 100644 index d187aad..0000000 --- a/lfs/python-dbus +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = dbus-python -PKG_VER = 0.82.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -DEPS = dbus-glib python -BUILD_DEPS = - -LICENSE = MIT -URL = http://www.freedesktop.org/software/dbus/ -SHORT_DESC = D-Bus Python Bindings. - -define LONG_DESC - D-Bus python bindings for use with python programs. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/python2.6/site-packages/_dbus_{,glib_}bindings.la - $(PYTHON_COMPILE) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-flup b/lfs/python-flup deleted file mode 100644 index 61b6ab9..0000000 --- a/lfs/python-flup +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = flup -PKG_VER = 1.0.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Michael Tremer michael.tremer@ipfire.org -GROUP = Development/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = python python-setuptools - -URL = http://trac.saddi.com/flup -LICENSE = BSD -SHORT_DESC = Random assortment of WSGI servers for python. - -define LONG_DESC - This package contains classes to create WSGI servers in python, \ - e.g. fastcgi. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && python setup.py build - cd $(DIR_APP) && python setup.py install --skip-build - - $(PYTHON_EXTRACT_EGG) /usr/lib/python*/site-packages/$(PKG_NAME)*.egg - $(PYTHON_COMPILE) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-netfilter_conntrack b/lfs/python-netfilter_conntrack deleted file mode 100644 index cddc25b..0000000 --- a/lfs/python-netfilter_conntrack +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pynetfilter_conntrack -PKG_VER = 0.4.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -DEPS = libnetfilter_conntrack python -BUILD_DEPS = - -LICENSE = -URL = http://software.inl.fr/trac/wiki/pynetfilter_conntrack -SHORT_DESC = Python binding of libnetfilter_conntrack. - -define LONG_DESC - This python library is based on libnetfilter_conntrack, which lets \ - you manipulate conntrack objects. In other words, \ - pynetfilter_conntrack lets you deal with Netfilter's stateful \ - inspection objects from the Python world. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && python setup.py install - - $(PYTHON_COMPILE) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-parted b/lfs/python-parted deleted file mode 100644 index 9bab84b..0000000 --- a/lfs/python-parted +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pyparted -PKG_VER = 1.8.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -DEPS = parted python -BUILD_DEPS = - -LICENSE = GPLv2+ -URL = http://fedorahosted.org/pyparted -SHORT_DESC = Python module for GNU parted. - -define LONG_DESC - Python module for the parted library. It is used for manipulating \ - partition tables. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && PYTHONHOME=/usr \ - make all install \ - libdir=/usr/lib/python2.6/site-packages - - $(PYTHON_COMPILE) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-pyblock b/lfs/python-pyblock deleted file mode 100644 index 0d5dad8..0000000 --- a/lfs/python-pyblock +++ /dev/null @@ -1,85 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pyblock -PKG_VER = 0.42 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = dmraid lvm2 python python-parted - -URL = http://git.fedorahosted.org/git/?p=pyblock.git;a=summary -LICENSE = GPLv2 or GPLv3 -SHORT_DESC = Python modules for dealing with block devices. - -define LONG_DESC - The pyblock contains Python modules for dealing with block devices. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && sed -e "s/-Werror//g" -i Makefile - cd $(DIR_APP) && make install USESELINUX=0 - $(PYTHON_COMPILE) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-setuptools b/lfs/python-setuptools deleted file mode 100644 index 4a146aa..0000000 --- a/lfs/python-setuptools +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = setuptools -PKG_VER = 0.6c9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Michael Tremer michael.tremer@ipfire.org -GROUP = Development/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = python - -URL = http://pypi.python.org/pypi/setuptools -LICENSE = Python or ZPLv2.0 -SHORT_DESC = Easily build and distribute Python packages. - -define LONG_DESC - Setuptools is a collection of enhancements to the Python distutils \ - that allow you to more easily build and distribute Python packages, \ - especially ones that have dependencies on other packages. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # Scripts seem to have a wrong hashbang - cd $(DIR_APP) && find . -name "*.py" | xargs sed -i "1s@^#!python@#!/usr/bin/python@" - - cd $(DIR_APP) && CFLAGS="$(CFLAGS)" python setup.py build - cd $(DIR_APP) && python setup.py install -O1 --skip-build - - $(PYTHON_EXTRACT_EGG) /usr/lib/python*/site-packages/$(PKG_NAME)*.egg - $(PYTHON_COMPILE) - - rm -vf /usr/lib/python*/site-packages/setuptools/*.exe - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-sqlite2 b/lfs/python-sqlite2 deleted file mode 100644 index 7b897bd..0000000 --- a/lfs/python-sqlite2 +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = pysqlite -PKG_VER = 2.5.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Databases -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = python sqlite - -URL = http://pysqlite.org/ -LICENSE = zlib libpng -SHORT_DESC = DB-API 2.0 interface for SQLite 3.x. - -define LONG_DESC - pysqlite is an interface to the SQLite 3.x embedded relational database \ - engine. It is almost fully compliant with the Python database API version \ - 2.0 also exposes the unique features of SQLite. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && sed -i -e "//usr/include/d" -e "//usr/lib/d" setup.cfg - cd $(DIR_APP) && CFLAGS="$(CFLAGS)" python setup.py build - cd $(DIR_APP) && python setup.py install -O1 --skip-build - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-tornado b/lfs/python-tornado deleted file mode 100644 index 3dcc387..0000000 --- a/lfs/python-tornado +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = tornado -PKG_VER = 0.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Michael Tremer michael.tremer@ipfire.org -GROUP = Development/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = python - -URL = http://www.tornadoweb.org/ -LICENSE = Apache2.0 -SHORT_DESC = A python based non-blocking web server. - -define LONG_DESC - The framework is distinct from most mainstream web server frameworks \ - (and certainly most Python frameworks) because it is non-blocking \ - and reasonably fast. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && python setup.py build - cd $(DIR_APP) && python setup.py install --skip-build - - $(PYTHON_COMPILE) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-urlgrabber b/lfs/python-urlgrabber deleted file mode 100644 index effb167..0000000 --- a/lfs/python-urlgrabber +++ /dev/null @@ -1,89 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = urlgrabber -PKG_VER = 3.1.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = python - -URL = http://urlgrabber.baseurl.org/ -LICENSE = LGPLv2+ -SHORT_DESC = A high-level cross-protocol url-grabber. - -define LONG_DESC - A high-level cross-protocol url-grabber for python supporting HTTP, \ - FTP and file locations. Features include keepalive, byte ranges, \ - throttling, authentication, proxies and more. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && python setup.py install - - $(PYTHON_COMPILE) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/python-werkzeug b/lfs/python-werkzeug deleted file mode 100644 index f629f7c..0000000 --- a/lfs/python-werkzeug +++ /dev/null @@ -1,86 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = werkzeug -PKG_VER = 0.5.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Michael Tremer michael.tremer@ipfire.org -GROUP = Development/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = python - -URL = http://werkzeug.pocoo.org/ -LICENSE = BSD -SHORT_DESC = The Swiss Army knife of Python web development. - -define LONG_DESC - Werkzeug started as simple collection of various utilities for WSGI \ - applications and has become one of the most advanced WSGI utility \ - modules. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && CFLAGS="$(CFLAGS)" python setup.py build - cd $(DIR_APP) && python setup.py install -O1 --skip-build - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/qemu b/lfs/qemu deleted file mode 100644 index cd234b0..0000000 --- a/lfs/qemu +++ /dev/null @@ -1,98 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = qemu-kvm-devel -PKG_VER = 88 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Virtualization -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.xen.org/ -LICENSE = GPLv2+ -SHORT_DESC = QEMU is a generic and open source machine emulator and virtualizer. - -define LONG_DESC - QEMU is a processor emulator that relies on dynamic binary translation \ - to achieve a reasonable speed while being easy to port on new host CPU \ - architectures. -endef - -define QUALITY_AGENT_WHITELIST_EXECSTACK - /usr/share/qemu/openbios* -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - --prefix=/usr \ - --disable-kvm \ - --disable-strip \ - --disable-xen - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/quagga b/lfs/quagga deleted file mode 100644 index 670e32f..0000000 --- a/lfs/quagga +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = quagga -PKG_VER = 0.99.11 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Routing -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = pam - -URL = http://www.quagga.net/ -LICENSE = GPLv2+ -SHORT_DESC = Quagga is a rounting daemon. - -define LONG_DESC - Quagga is a free software that manages TCP/IP based routing \ - protocol. It takes multi-server and multi-thread approach to resolve \ - the current complexity of the Internet. \ - Quagga supports BGP4, BGP4+, OSPFv2, OSPFv3, RIPv1, RIPv2, and RIPng. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - # ac_cv_have_decl_TCP_MD5SIG=no was set to work around a bug - cd $(DIR_APP) && \ - ac_cv_have_decl_TCP_MD5SIG=no \ - ac_cv_func_working_mktime=yes \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc/quagga \ - --disable-static \ - --enable-netlink \ - --with-libpam \ - --enable-ipv6 - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/radvd b/lfs/radvd deleted file mode 100644 index a6f0864..0000000 --- a/lfs/radvd +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = radvd -PKG_VER = 1.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Daemons -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = flex - -URL = http://www.litech.org/radvd/ -LICENSE = BSD with advertising -SHORT_DESC = A Router Advertisement daemon. - -define LONG_DESC - radvd is the router advertisement daemon for IPv6. It listens to \ - router solicitations and sends router advertisements as described \ - in Neighbor Discovery for IP Version 6. With these \ - advertisements hosts can automatically configure their addresses and \ - some other parameters. They also can choose a default router based \ - on these advertisements. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --with-pidfile=/var/run/radvd/radvd.pid - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/readline b/lfs/readline deleted file mode 100644 index 5a75ddf..0000000 --- a/lfs/readline +++ /dev/null @@ -1,103 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = readline -PKG_VER = 6.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = ftp://ftp.gnu.org/gnu/readline/ -LICENSE = GPLv3+ -SHORT_DESC = A library for editing typed command lines. - -define LONG_DESC - The Readline library provides a set of functions that allow users to \ - edit command lines. Both Emacs and vi editing modes are available. \ - The Readline library includes additional functions for maintaining a \ - list of previously-entered command lines for recalling or editing \ - those lines, and for performing csh-like history expansion on \ - previous commands. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-shlib-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-shlib-1.patch - #cd $(DIR_APP) && sed -i '/MV.*old/d' Makefile.in - #cd $(DIR_APP) && sed -i '/{OLDSUFF}/c:' support/shlib-install - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libdir=/lib \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) SHLIB_LIBS=-lncurses - cd $(DIR_APP) && make install - - rm -fv /lib/lib{readline,history}.so - ln -sfv ../../lib/libreadline.so.6 /usr/lib/libreadline.so - ln -sfv ../../lib/libhistory.so.6 /usr/lib/libhistory.so - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/reiser4progs b/lfs/reiser4progs deleted file mode 100644 index 0ec3499..0000000 --- a/lfs/reiser4progs +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = reiser4progs -PKG_VER = 1.0.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.kernel.org/pub/linux/utils/fs/reiser4/reiser4progs/ -LICENSE = GPL -SHORT_DESC = Administration utilities for the Reiser4 filesystem. - -define LONG_DESC - The filesystem utilities for the reiser4 filesystem, including: \ - fsck.reiser4, measurefs.reiser4, mkfs.reiser4 and resizefs.reiser4. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-bad_elif.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-bad_elif.patch - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sbindir=/sbin \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/lib{reiser4{,-minimal},repair}.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/reiserfsprogs b/lfs/reiserfsprogs deleted file mode 100644 index ff966a8..0000000 --- a/lfs/reiserfsprogs +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = reiserfsprogs -PKG_VER = 3.6.21 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.kernel.org/pub/linux/utils/fs/reiserfs/ -LICENSE = GPL -SHORT_DESC = Tools for ReiserFS filesystems. - -define LONG_DESC - This package contains utilities to create, check, resize, and \ - debug ReiserFS filesystems. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sbindir=/sbin - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - ln -svf reiserfsck /sbin/fsck.reiserfs - ln -svf mkreiserfs /sbin/mkfs.reiserfs - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/rrdtool b/lfs/rrdtool deleted file mode 100644 index f8ec6e8..0000000 --- a/lfs/rrdtool +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = rrdtool -PKG_VER = 1.3.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Databases -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = gettext groff libxml2 libtool - -URL = http://oss.oetiker.ch/rrdtool/ -LICENSE = GPLv2+ with exceptions -SHORT_DESC = Round Robin Database Tool to store and display time-series data. - -define LONG_DESC - RRD is the Acronym for Round Robin Database. RRD is a system to \ - store and display time-series data. It stores the data in a \ - very compact way that will not expand over time, and it presents \ - useful graphs by processing the data to enforce a certain data \ - density. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-rrdcgi \ - --disable-perl \ - --disable-tcl \ - --disable-ruby \ - --disable-static \ - --enable-python \ - --enable-latin2 - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/librrd{,_th}.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/rstp b/lfs/rstp deleted file mode 100644 index c5795c7..0000000 --- a/lfs/rstp +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = rstp -PKG_VER = 0.21 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://git.ipfire.org/?p=thirdparty/rstp.git;a=summary -LICENSE = GPLv2+ -SHORT_DESC = Rapid Spanning Tree Protocol for Linux Ethernet bridge. - -define LONG_DESC - Rapid Spanning Tree Protocol for Linux Ethernet bridge. -endef - -CFLAGS += -fno-strict-aliasing - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && sed -e "s/^CFLAGS = .*/& $(CFLAGS)/g" -i Makefile - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - install -v -m 755 $(DIR_SOURCE)/$(PKG_NAME)/bridge-stp /sbin/bridge-stp - $(INSTALL_INITSCRIPT) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/samba b/lfs/samba deleted file mode 100644 index 1dd7a50..0000000 --- a/lfs/samba +++ /dev/null @@ -1,127 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = samba -PKG_VER = 3.3.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Christian Schmidt christian.schmidt@ipfire.org -GROUP = Networking/Daemons -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = gawk ncurses libcap2 openldap openssl pam popt readline # cups - -URL = http://www.samba.org/ -LICENSE = GPLv3+ and LGPLv3+ -SHORT_DESC = Server and Client software to interoperate with Windows machines. - -define LONG_DESC - Samba is the suite of programs by which a lot of PC-related machines \ - share files, printers, and other information (such as lists of \ - available files and printers). The Windows NT, OS/2, and Linux \ - operating systems support this natively, and add-on packages can \ - enable the same thing for DOS, Windows, VMS, UNIX of all kinds, MVS, \ - and more. This package provides an SMB/CIFS server that can be used to \ - provide network services to SMB/CIFS clients. \ - Samba uses NetBIOS over TCP/IP (NetBT) protocols and does NOT \ - need the NetBEUI (Microsoft Raw NetBIOS frame) protocol. -endef - -CFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -DLDAP_DEPRECATED - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP)/source && sh autogen.sh - cd $(DIR_APP)/source && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --with-lockdir=/var/lib/samba \ - --with-piddir=/var/run \ - --with-mandir=/usr/share/man \ - --with-privatedir=/var/lib/samba/private \ - --with-logfilebase=/var/log/samba \ - --with-modulesdir=/usr/lib/samba \ - --with-configdir=/etc/samba \ - --with-pammodulesdir=/lib/security \ - --with-swatdir=/usr/share/swat \ - --with-automount \ - --with-libsmbclient \ - --with-libsmbsharemodes \ - --with-pam \ - --with-pam_smbpass \ - --with-quotas \ - --with-sendfile-support \ - --with-syslog \ - --with-utmp \ - --with-winbind \ - --with-shared-modules=idmap_ad,idmap_rid,idmap_adex,idmap_hash - cd $(DIR_APP)/source && make pch all \ - nsswitch/libnss_wins.so modules $(PARALLELISMFLAGS) - cd $(DIR_APP)/source && make install - - cd $(DIR_APP) && install -m 755 source/nsswitch/libnss_winbind.so /lib/libnss_winbind.so.2 - ln -sf ../../lib/libnss_winbind.so.2 /usr/lib/libnss_winbind.so - cd $(DIR_APP) && install -m 755 source/nsswitch/libnss_wins.so /lib/libnss_wins.so.2 - ln -sf ../../lib/libnss_wins.so.2 /usr/lib/libnss_wins.so - -mkdir -pv /etc/samba - echo "127.0.0.1 localhost" > /etc/samba/lmhosts - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/sane b/lfs/sane deleted file mode 100644 index 34b8e0f..0000000 --- a/lfs/sane +++ /dev/null @@ -1,119 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = sane -PKG_VER = 1.0.20 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(PKG_NAME)-backends-$(PKG_VER).tar.gz -DIR_APP = $(DIR_SRC)/$(PKG_NAME)-backends-$(PKG_VER) -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Application/Imaging -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = libtiff - -URL = ftp://ftp2.sane-project.org/pub/sane/sane-backends-1.0.20 -LICENSE = GPLv2+ -SHORT_DESC = SANE - Scanner Access Now Easy. - -define LONG_DESC - sane-backends - includes: backends (scanner drivers), \ - command-line-frontend (scanimage), network scanning daemon \ - (saned) and SANE-API documentation. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - -ifeq "$(KMOD)" "1" - cd $(DIR_APP)/doc/plustek && cp -vf Makefile.kernel26 \ - $(DIR_APP)/backend/Makefile -ifeq "$(SMP)" "1" - cd $(DIR_APP)/backend && make -C /lib/modules/$(KVER)-ipfire-smp/build/ \ - SUBDIRS=$(DIR_APP)/backend modules - cd $(DIR_APP)/backend && install -m 644 pt_drv.ko \ - /lib/modules/$(KVER)-ipfire-smp/kernel/drivers/parport/ -else - cd $(DIR_APP)/backend && make -C /lib/modules/$(KVER)-ipfire/build/ \ - SUBDIRS=$(DIR_APP)/backend modules - cd $(DIR_APP)/backend && install -m 644 pt_drv.ko \ - /lib/modules/$(KVER)-ipfire/kernel/drivers/parport/ -endif -else - cd $(DIR_APP) && ./configure --prefix=/usr --sysconfdir=/etc \ - --disable-ipv6 \ - --enable-parport-directio - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - chmod 4755 /usr/bin/scanimage - install -v -m 644 $(DIR_SRC)/sane-backends-1.0.20/include/sane/* \ - /usr/include/sane -endif - - rm -vf /usr/lib/libsane.la - rm -vf /usr/lib/sane/*.la - rm -vf /usr/share/doc/sane-1.0.20/README.solaris - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/screen b/lfs/screen deleted file mode 100644 index 7c6f4de..0000000 --- a/lfs/screen +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = screen -PKG_VER = 4.0.3 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/screen -LICENSE = GPLv2+ -SHORT_DESC = A screen manager that supports multiple logins on one terminal. - -define LONG_DESC - The screen utility allows you to have multiple logins on just one \ - terminal. Screen is useful for users who telnet into a machine or \ - are connected via a dumb terminal, but want to use more than just \ - one login. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --with-socket-dir=/var/run/screen \ - --with-sys-screenrc=/etc/screenrc - cd $(DIR_APP) && sed -i -e "s%/usr/local/etc/screenrc%/etc/screenrc%" {etc,doc}/* - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cd $(DIR_APP) && install -m 644 etc/etcscreenrc /etc/screenrc - cp -vf $(DIR_SOURCE)/pam.d/$(PKG_NAME) /etc/pam.d/ - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/scripts b/lfs/scripts deleted file mode 100644 index 3da3a5d..0000000 --- a/lfs/scripts +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = scripts -PKG_VER = -PKG_REL = -1 - -THISAPP = $(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = This script installs some important scripts to the system. - -define LONG_DESC - This script installs some important scripts to the system. -endef - -BIN = readhash -SBIN = -USR_BIN = py-compile setddns.pl vpn-watch -USR_SBIN = - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - - for i in $(BIN); do \ - install -m 755 $(DIR_SOURCE)/scripts/$$i /bin/$$i; \ - done - - for i in $(SBIN); do \ - install -m 755 $(DIR_SOURCE)/scripts/$$i /sbin/$$i; \ - done - - for i in $(USR_BIN); do \ - install -m 755 $(DIR_SOURCE)/scripts/$$i /usr/bin/$$i; \ - done - - #for i in $(USR_SBIN); do \ - # install -m 755 $(DIR_SOURCE)/scripts/$$i /usr/sbin/$$i; \ - #done - - @$(POSTBUILD) diff --git a/lfs/sed b/lfs/sed deleted file mode 100644 index bde70db..0000000 --- a/lfs/sed +++ /dev/null @@ -1,107 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = sed -PKG_VER = 4.1.5 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Text -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://sed.sourceforge.net/ -LICENSE = GPLv2+ -SHORT_DESC = A GNU stream text editor. - -define LONG_DESC - The sed (Stream EDitor) editor is a stream or batch (non-interactive) \ - editor. Sed takes text as input, performs an operation or set of \ - operations on the text and outputs the modified text. The operations \ - that sed performs (substitutions, deletions, insertions, etc.) can be \ - specified in a script file or from the command line. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --without-included-regex -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/bin \ - --enable-html \ - --without-included-regex -endif - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/shadow b/lfs/shadow deleted file mode 100644 index 2194859..0000000 --- a/lfs/shadow +++ /dev/null @@ -1,121 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = shadow -PKG_VER = 4.1.4.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/ -LICENSE = GPLv2+ -SHORT_DESC = Utilities to deal with user accounts. - -define LONG_DESC - The shadow-utils package includes the necessary programs \ - for converting UNIX password files to the shadow password \ - format, plus programs for managing user and group accounts. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-ipfire.patch \ - $(THISAPP)-goodname.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # Modification of the user and shell permissions - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-ipfire.patch - - # Username check for umlaute - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-goodname.patch - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --enable-shadowgrp \ - --with-sha-crypt \ - --without-selinux \ - --without-libcrack \ - --without-libpam \ - --disable-static - - # Do not build these files: - cd $(DIR_APP) && \ - for i in chfn chgpasswd chpasswd chsh expiry gpasswd groups login \ - logoutd nologin passwd su; do \ - sed -i "s/$$i$$(EXEEXT)//" src/Makefile; \ - find man -name Makefile -exec sed -i "s/$$i.1/ /" {} ;; \ - done - cd $(DIR_APP) && sed -i src/Makefile \ - -e "s/^suidbins.*/# &/" -e "s/^suidubins.*/# &/" - - # Do not install korean and zh man pages - cd $(DIR_APP) && sed -i -e 's/ ko//' -e 's/ zh_CN zh_TW//' man/Makefile - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/slang b/lfs/slang deleted file mode 100644 index 4795464..0000000 --- a/lfs/slang +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = slang -PKG_VER = 2.1.4 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = pcre - -URL = http://www.jedsoft.org/slang/ -LICENSE = GPLv2+ -SHORT_DESC = Shared library for the S-Lang extension language. - -define LONG_DESC - S-Lang is an interpreted language and a programming library. \ - The S-Lang language was designed so that it can be easily embedded \ - into a program to provide the program with a powerful extension \ - language. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-makefile.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-makefile.patch - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --disable-static - - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install_doc_dir=/usr/share/doc/slang-$(PKG_VER) \ - SLSH_DOC_DIR=/usr/share/doc/slang-$(PKG_VER)/slsh install-all - chmod -v 755 /usr/lib/libslang.so.$(PKG_VER) /usr/lib/slang/v2/modules/*.so - $(PYTHON_COMPILE) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/smartmontools b/lfs/smartmontools deleted file mode 100644 index 72324f7..0000000 --- a/lfs/smartmontools +++ /dev/null @@ -1,94 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = smartmontools -PKG_VER = 5.37 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Statistics -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://smartmontools.sourceforge.net/ -LICENSE = GPLv2 -SHORT_DESC = A set of tools that watches HDD S.M.A.R.T status. - -define LONG_DESC - The smartmontools package contains two utility programs (smartctl \ - and smartd) to control and monitor storage systems using the \ - Self-Monitoring, Analysis and Reporting Technology System (SMART) \ - built into most modern ATA and SCSI harddisks. In many cases, \ - these utilities will provide advanced warning of disk degradation \ - and failure. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --with-initscriptdir=$(DIR_APP)/tmp - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/splashy b/lfs/splashy deleted file mode 100644 index db33bb5..0000000 --- a/lfs/splashy +++ /dev/null @@ -1,115 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = splashy -PKG_VER = 0.3.13 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Boot -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://splashy.alioth.debian.org/ -LICENSE = GPL -SHORT_DESC = A program for a nice boot splash. - -define LONG_DESC - Splashy is a boot splash program that doesn't require patching \ - the Linux kernel. It paints graphic images directly to framebuffers \ - using libdirectfb. -endef - -define QUALITY_AGENT_WHITELIST_RPATH - /sbin/splashy -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/ \ - --libdir=/lib \ - --sbindir=/sbin \ - --sysconfdir=/etc \ - --includedir=/usr/include \ - --datarootdir=/usr/share \ - --mandir=/usr/share/man - cd $(DIR_APP) && sed -e "s/-Werror//g" -i src/Makefile - cd $(DIR_APP) && echo "#undef ENABLE_NLS" >> config.h - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - # Install our own theme - -mkdir -pv /usr/share/splashy/themes/$(SNAME) - cp -vf $(DIR_SOURCE)/bootsplash/* /usr/share/splashy/themes/$(SNAME)/ - splashy_config --set-theme $(SNAME) - - rm -rvf /etc/{console-tools,default/splashy,lsb-base-logging.sh} \ - /usr/share/initramfs-tools /lib/libsplashy{,cnf}.la \ - /etc/init.d/splashy - - $(INSTALL_INITSCRIPT) - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/sqlite b/lfs/sqlite deleted file mode 100644 index 0c1218c..0000000 --- a/lfs/sqlite +++ /dev/null @@ -1,96 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = sqlite -PKG_VER = 3.5.2 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Databases -LICENSE = PublicDomain -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.sqlite.org/download.html -SHORT_DESC = A small an versative Database, that uses simple text files. - -define LONG_DESC - SQLite is a in-process library that implements a self-contained, \ - serverless, zero-configuration, transactional SQL database engine. \ - The code for SQLite is in the public domain and is thus free for \ - use for any purpose, commercial or private. SQLite is currently \ - found in more applications than we can count, including several \ - high-profile projects. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -mkdir $(DIR_SRC)/sqlite-build - cd $(DIR_SRC)/sqlite-build && \ - $(DIR_APP)/configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-tcl \ - --disable-static - cd $(DIR_SRC)/sqlite-build && make $(PARALLELISMFLAGS) - cd $(DIR_SRC)/sqlite-build && make install - rm -vf /usr/lib/libsqlite3.la - @rm -rf $(DIR_APP) $(DIR_SRC)/sqlite-build - @$(POSTBUILD) diff --git a/lfs/squashfs-tools b/lfs/squashfs-tools deleted file mode 100644 index 03250c3..0000000 --- a/lfs/squashfs-tools +++ /dev/null @@ -1,86 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = squashfs-tools -PKG_VER = 4.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = squashfs$(PKG_VER).tar.gz -DIR_APP = $(DIR_SRC)/squashfs$(PKG_VER)/$(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://squashfs.sf.net/ -LICENSE = GPLv2+ -SHORT_DESC = Utility for the creation of squashfs filesystems. - -define LONG_DESC - Squashfs is a highly compressed read-only filesystem for Linux. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && sed -e "s/^CFLAGS := /& $(CFLAGS) /" -i Makefile - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && install -m 755 mksquashfs /usr/sbin - cd $(DIR_APP) && install -m 755 unsquashfs /usr/sbin - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/squid b/lfs/squid deleted file mode 100644 index 6259e8a..0000000 --- a/lfs/squid +++ /dev/null @@ -1,144 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = squid -PKG_VER = 3.0.STABLE18 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Christian Schmidt christian.schmidt@ipfire.org -GROUP = Networking/Daemons -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.squid-cache.org/ -LICENSE = GPLv2+ -SHORT_DESC = The Squid proxy caching server. - -define LONG_DESC - Squid is a high-performance proxy caching server for Web clients, \ - supporting FTP, gopher, and HTTP data objects. Unlike traditional \ - caching software, Squid handles all requests in a single, \ - non-blocking, I/O-driven process. Squid keeps meta data and especially \ - hot objects cached in RAM, caches DNS lookups, supports non-blocking \ - DNS lookups, and implements negative caching of failed requests. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --datadir=/usr/lib/squid \ - --libexecdir=/usr/lib/squid \ - --localstatedir=/var \ - --sysconfdir=/etc/squid \ - --enable-storeio="aufs,diskd,ufs,null" \ - --enable-removal-policies="heap,lru" \ - --enable-icmp \ - --enable-delay-pools \ - --disable-esi \ - --disable-icap-client \ - --enable-useragent-log \ - --enable-referrer-log \ - --disable-wccp \ - --disable-wccpv2 \ - --enable-kill-parent-hack \ - --enable-snmp \ - --enable-arp-acl \ - --enable-htcp \ - --enable-ssl \ - --enable-forw-via-db \ - --disable-cache-digests \ - --enable-poll \ - --enable-select \ - --disable-kqueue \ - --enable-epoll \ - --enable-http-violations \ - --enable-linux-netfilter \ - --disable-ident-lookups \ - --enable-internal-dns \ - --enable-auth=basic,ntlm \ - --enable-basic-auth-helpers="LDAP,MSNT,multi-domain-NTLM,PAM,NCSA,SMB,squid_radius_auth" \ - --enable-ntlm-auth-helpers="SMB" \ - --enable-ntlm-fail-open \ - --enable-unlinkd \ - \ - --with-pthreads \ - --with-aio \ - --with-dl \ - --with-large-files - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /etc/squid/errors - ln -svf /usr/lib/squid/errors/English /etc/squid/errors - - -mkdir -pv /var/log/cache /var/log/squid - touch /var/log/squid/access.log - chown -Rv squid:squid /var/log/squid /var/log/cache - - chown squid:squid /var/log/squid - ln -svf /usr/lib/squid /usr/lib/squid/auth - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/stage1 b/lfs/stage1 deleted file mode 100644 index 38b8c97..0000000 --- a/lfs/stage1 +++ /dev/null @@ -1,83 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = stage1 -PKG_VER = -PKG_REL = -1 - -THISAPP = $(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = This script initializes stage 1. - -define LONG_DESC - This script initializes stage 1. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - -mkdir -p $(TOOLS_DIR)/usr/bin -ifeq "$(MACHINE)" "x86_64" - #Link lib64 to lib on 64bit target - ln -sf ./lib $(TOOLS_DIR)/lib64 -endif - @$(POSTBUILD) diff --git a/lfs/stage2 b/lfs/stage2 deleted file mode 100644 index 7fbee1b..0000000 --- a/lfs/stage2 +++ /dev/null @@ -1,123 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = stage2 -PKG_VER = -PKG_REL = -1 - -THISAPP = $(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = This script initializes stage 2. - -define LONG_DESC - This script initializes stage 2. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - - # Create directories - -mkdir -pv /{bin,boot,etc/{grsec,opt,sysconfig},home,lib,mnt,opt} - -mkdir -pv /{media/{floppy,cdrom},sbin,srv,var} - -install -dv -m 0750 /root - -install -dv -m 1777 /tmp /var/tmp - -mkdir -pv /usr/{,local/}{bin,include,lib,sbin,src} - -mkdir -pv /usr/{,local/}share/{doc,info,locale,man} - -mkdir -v /usr/{,local/}share/{misc,terminfo,zoneinfo} - -mkdir -pv /usr/{,local/}share/man/man{1..8} - -for dir in /usr /usr/local; do \ - ln -sfv share/{man,doc,info} $$dir; \ - done - -mkdir -pv /var/{lock/subsys,log,mail,run,spool} - -mkdir -pv /var/{opt,cache,lib/{misc,locate},local} - -mkdir -pv /etc/init{,.d} - -mkdir -pv /{etc,lib}/udev/rules.d - - # Creating an empty mtab - touch /etc/mtab - - # Config files - for i in $$(find $(DIR_SRC)/config/etc/ -type f); do \ - cp -vf $$i /etc; \ - done - for i in $$(find $(DIR_CONFIG)/root/ -type f); do \ - cp -vf $$i /root; \ - done - for i in $$(find $(DIR_SOURCE)/grsecurity/ -type f); do \ - cp -vf $$i /etc/grsec; \ - done - - touch /var/run/utmp /var/log/{btmp,lastlog,wtmp} - #chgrp -v utmp /var/run/utmp /var/log/lastlog - chmod -v 664 /var/run/utmp /var/log/lastlog - - # Nobody user - -mkdir -p /home/nobody - chown -R nobody:nobody /home/nobody - -ifeq "$(MACHINE)" "x86_64" - # Link lib64 to lib for 64bit target - ln -sf lib /lib64 - ln -sf lib /usr/lib64 -endif - @$(POSTBUILD) diff --git a/lfs/stage3 b/lfs/stage3 deleted file mode 100644 index dddde1b..0000000 --- a/lfs/stage3 +++ /dev/null @@ -1,99 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = stage3 -PKG_VER = -PKG_REL = -1 - -THISAPP = $(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = This script initializes stage 3. - -define LONG_DESC - This script initializes stage 3. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - - # Create all directories - for i in auth ca certs crls networking; do \ - mkdir -p $(CONFIG_ROOT)/$$i; \ - done - - # Touch empty files - for i in auth/users certs/index.txt; do \ - touch $(CONFIG_ROOT)/$$i; \ - done - - # Oneliner configfiles - echo "01" > $(CONFIG_ROOT)/certs/serial - - # Networking - ln -svf $(CONFIG_ROOT)/networking /etc/sysconfig/networking - - # Configroot permissions - chown -R nobody:nobody $(CONFIG_ROOT) - chown root:root $(CONFIG_ROOT) - - @$(POSTBUILD) diff --git a/lfs/stage4 b/lfs/stage4 deleted file mode 100644 index db28802..0000000 --- a/lfs/stage4 +++ /dev/null @@ -1,79 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = stage4 -PKG_VER = -PKG_REL = -1 - -THISAPP = $(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = This script initializes stage 4. - -define LONG_DESC - This script initializes stage 4. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - - @$(POSTBUILD) diff --git a/lfs/stage5 b/lfs/stage5 deleted file mode 100644 index 8da8713..0000000 --- a/lfs/stage5 +++ /dev/null @@ -1,80 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = stage5 -PKG_VER = -PKG_REL = -1 - -THISAPP = $(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = This script initializes stage 5. - -define LONG_DESC - This script initializes stage 5. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - -mkdir -pv $(INSTALLER_DIR)/{etc,sbin,usr/lib} - cp -avf $(DIR_SOURCE)/install/* $(INSTALLER_DIR) - @$(POSTBUILD) diff --git a/lfs/strace b/lfs/strace deleted file mode 100644 index 7f11747..0000000 --- a/lfs/strace +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = strace -PKG_VER = 4.5.18 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Development/Debuggers -CORE = no -EXTRA = yes -DEBUG = yes -BUILD_DEPS = -DEPS = - -URL = http://sourceforge.net/projects/strace/ -LICENSE = BSD -SHORT_DESC = Tracks and displays system calls associated with a running process. - -define LONG_DESC - The strace program intercepts and records the system calls called and \ - received by a running process. Strace can print a record of each \ - system call, its arguments and its return value. Strace is useful \ - for diagnosing problems and debugging, as well as for instructional \ - purposes. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/strip b/lfs/strip deleted file mode 100644 index 66eedb4..0000000 --- a/lfs/strip +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = strip -PKG_VER = -PKG_REL = -1 - -THISAPP = $(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = This script strips the toolchain. - -define LONG_DESC - This script strips the toolchain. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - ## Strip debugging symbols - for f in $$(find $(TOOLS_DIR)/ -type f ( -perm -0100 -or -perm -0010 -or -perm -0001 ) -exec file {} ; | \ - grep -v ' shared object,' | \ - sed -n -e 's/^(.*):[ ]*ELF.*, not stripped/\1/p'); do \ - strip --strip-debug "$$f" || :; \ - done - - ## Strip unneeded symbols - for f in $$(find $(TOOLS_DIR)/ -type f -a -exec file {} ; | \ - grep ' shared object,' | \ - sed -n -e 's/^(.*):[ ]*ELF.*, not stripped/\1/p'); do \ - strip --strip-unneeded "$$f"; \ - done - - -rm -rf $(TOOLS_DIR)/{,share/}{info,man} \ - $(TOOLS_DIR)/usr/{share,man,info} \ - $(TOOLS_DIR)/share/locale/* \ - $(TOOLS_DIR)/var - chown -R root:root $(LFS)$(TOOLS_DIR) diff --git a/lfs/strongswan b/lfs/strongswan deleted file mode 100644 index edc604c..0000000 --- a/lfs/strongswan +++ /dev/null @@ -1,105 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = strongswan -PKG_VER = 4.3.3 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/VPN -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.strongswan.org/ -LICENSE = GPL -SHORT_DESC = IPsec and IKEv1 implementation for Linux 2.4 and 2.6 kernels. - -define LONG_DESC - StrongSwan is a complete IPsec and IKEv1 implementation for \ - Linux 2.4 and 2.6 kernels. It also fully supports the new IKEv2 \ - protocol with Linux 2.6 kernels. It interoperates in both IKEv1 \ - and IKEv2 mode with most other IPsec-based VPN products. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-gcc44-inline-fix.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # Patch for gcc4.4.x - cd $(DIR_APP) && patch -Np1 -i \ - $(DIR_PATCHES)/$(THISAPP)-gcc44-inline-fix.patch - - cd $(DIR_APP) && for i in $$(find . -name "*.[ch]"); do \ - sed -e "s/getline/_&/g" -i $$i; done - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --libexecdir=/usr/lib \ - --with-user=nobody \ - --disable-static - cd $(DIR_APP) && make #$(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/libstrongswan.la /usr/lib/ipsec/plugins/*.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/sudo b/lfs/sudo deleted file mode 100644 index 555808a..0000000 --- a/lfs/sudo +++ /dev/null @@ -1,105 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = sudo -PKG_VER = 1.7.2p1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = pam vim - -URL = http://bridge.sourceforge.net/ -LICENSE = BSD -SHORT_DESC = Allows restricted root access for specified users. - -define LONG_DESC - Sudo (superuser do) allows a system administrator to give certain \ - users (or groups of users) the ability to run some (or all) commands \ - as root while logging all commands and arguments. Sudo operates on a \ - per-command basis. It is not a replacement for the shell. Features \ - include: the ability to restrict what commands a user may run on a \ - per-host basis, copious logging of each command (providing a clear \ - audit trail of who did what), a configurable timeout of the sudo \ - command, and the ability to use the same configuration file (sudoers) \ - on many different machines. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libexecdir=/usr/lib \ - --enable-noargs-shell \ - --with-ignore-dot \ - --with-all-insults \ - --enable-shell-sets-home \ - --disable-root-sudo \ - --with-logfac=auth - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/sudoers /etc/sudoers - sed 's@/su@/sudo@g' /etc/pam.d/su > /etc/pam.d/sudo - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/sysfsutils b/lfs/sysfsutils deleted file mode 100644 index 457ac2a..0000000 --- a/lfs/sysfsutils +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = sysfsutils -PKG_VER = 2.1.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://sourceforge.net/projects/linux-diag/ -LICENSE = GPLv2 -SHORT_DESC = Utilities for interfacing with sysfs. - -define LONG_DESC - This package's purpose is to provide a set of utilities for interfacing \ - with sysfs. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/libsysfs.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/syslinux b/lfs/syslinux deleted file mode 100644 index a67d374..0000000 --- a/lfs/syslinux +++ /dev/null @@ -1,90 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = syslinux -PKG_VER = 3.80 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Boot -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://syslinux.zytor.com/ -LICENSE = GPLv2+ -SHORT_DESC = Simple kernel loader which boots from a FAT filesystem. - -define LONG_DESC - SYSLINUX is a suite of bootloaders, currently supporting DOS FAT \ - filesystems, Linux ext2/ext3 filesystems (EXTLINUX), PXE network boots \ - (PXELINUX), or ISO 9660 CD-ROMs (ISOLINUX). It also includes a tool, \ - MEMDISK, which loads legacy operating systems from these media. -endef - -CFLAGS = -Werror -Wno-unused -finline-limit=2000 - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make clean - cd $(DIR_APP) && make $(PARALLELISMFLAGS) install \ - CC="gcc -std=gnu99 -fgnu89-inline -fno-pic -fno-pie -nopie" - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/syslog-ng b/lfs/syslog-ng deleted file mode 100644 index 0c8e2b9..0000000 --- a/lfs/syslog-ng +++ /dev/null @@ -1,108 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = syslog-ng -PKG_VER = 2.1.3 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = eventlog glib2 - -URL = http://www.balabit.com/network-security/syslog-ng/ -LICENSE = GPLv2+ -SHORT_DESC = Syslog-ng is a daemon that handles the logging stuff. - -define LONG_DESC - The syslog-ng application can operate in server or agent mode, and - \ - apart from UDP - supports the reliable TCP and the encrypted TLS protocols. \ - That way syslog-ng can be used to create flexible and reliable logging \ - infrastructure even in heterogeneous environments. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sbindir=/sbin \ - --libexecdir=/usr/lib \ - --sysconfdir=/etc/syslog-ng \ - --enable-dynamic-linking \ - --disable-sql \ - --disable-pcre \ - --with-pidfile-dir=/var/run \ - --disable-ssl - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - -mkdir -pv /etc/$(PKG_NAME) - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/$(PKG_NAME).conf \ - /etc/$(PKG_NAME)/$(PKG_NAME).conf - install -v -m 755 $(DIR_SOURCE)/$(PKG_NAME)/ids-block \ - /usr/sbin/ids-block - - $(INSTALL_INITSCRIPT) - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/system-release b/lfs/system-release deleted file mode 100644 index fd7f4f7..0000000 --- a/lfs/system-release +++ /dev/null @@ -1,85 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = system-release -PKG_VER = $(VERSION) -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Michael Tremer michael.tremer@ipfire.org -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.ipfire.org -LICENSE = -SHORT_DESC = IPFire release files. - -define LONG_DESC - IPFire release files such as pakfire configs and various /etc/ files that \ - define the release. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - echo "$(NAME) v$(VERSION) for $(MACHINE) - $(SLOGAN) (\l)" > /etc/issue - echo "===============================" >> /etc/issue - echo "\n running on \s \r \m" >> /etc/issue - - echo "$(NAME) Release $(VERSION) ($(SLOGAN))" > /etc/$(SNAME)-release - ln -svf $(SNAME)-release /etc/system-release - @$(POSTBUILD) diff --git a/lfs/sysvinit b/lfs/sysvinit deleted file mode 100644 index fa1e4dc..0000000 --- a/lfs/sysvinit +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = sysvinit -PKG_VER = 2.86 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = https://alioth.debian.org/projects/pkg-sysvinit/ -LICENSE = GPLv2+ -SHORT_DESC = Programs which control basic system processes. - -define LONG_DESC - The sysvinit package contains a group of processes that control \ - the very basic functions of your system. -endef - -CFLAGS += -D_GNU_SOURCE - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-remove-utils-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-remove-utils-1.patch - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) -C src CFLAGS="$(CFLAGS)" - cd $(DIR_APP) && make -C src install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/tar b/lfs/tar deleted file mode 100644 index eefcdc7..0000000 --- a/lfs/tar +++ /dev/null @@ -1,123 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = tar -PKG_VER = 1.22 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Packaging -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = acl attr - -URL = http://www.gnu.org/software/tar/ -LICENSE = GPLv3+ -SHORT_DESC = A GNU file archiving program. - -define LONG_DESC - The GNU tar program saves many files together in one archive \ - and can restore individual files (or all of the files) from \ - that archive. Tar can also be used to add supplemental files \ - to an archive and to update or list files in the archive. Tar \ - includes multivolume support,automatic archive \ - compression/decompression, the ability to perform remote archives, \ - and the ability to perform incremental and full backups. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-vfatTruncate.patch \ - $(THISAPP)-xattrs-1.patch \ - $(THISAPP)-xattrs-conf-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # Fix extracting sparse files to a filesystem like vfat, when ftruncate - # may fail to grow the size of a file - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-vfatTruncate.patch - - # Add support for ACLs in the tarballs. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-xattrs-1.patch - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-xattrs-conf-1.patch - -ifeq "$(STAGE)" "toolchain" - # Normally the 'rmt' programs goes in sbin/. - cd $(DIR_APP) && LDFLAGS="-z muldefs" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --libexecdir=$(TOOLS_DIR)/bin - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - CC="gcc -std=gnu99 -fgnu89-inline" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/bin \ - --libexecdir=/usr/sbin - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/tcpdump b/lfs/tcpdump deleted file mode 100644 index 578d927..0000000 --- a/lfs/tcpdump +++ /dev/null @@ -1,95 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = tcpdump -PKG_VER = 4.0.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Sniffer -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = libpcap openssl - -URL = http://www.tcpdump.org/ -LICENSE = BSD with advertising -SHORT_DESC = A network traffic monitoring tool. - -define LONG_DESC - Tcpdump is a command-line tool for monitoring network traffic. \ - Tcpdump can capture and display the packet headers on a particular \ - network interface or on all interfaces. Tcpdump can display all of \ - the packet headers, or just the ones that match particular criteria. -endef - -CFLAGS += -O2 -fno-strict-aliasing - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-ipv6-build.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np0 -i $(DIR_PATCHES)/$(THISAPP)-ipv6-build.patch - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/test-toolchain b/lfs/test-toolchain deleted file mode 100644 index 994865a..0000000 --- a/lfs/test-toolchain +++ /dev/null @@ -1,118 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = test-toolchain -PKG_VER = -PKG_REL = -1 - -THISAPP = $(PKG_NAME) - -ifeq "$(STAGE)" "toolchain" - OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP)-pass$(PASS) -else - OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) -endif - -MAINTAINER = -GROUP = -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = -SHORT_DESC = This script does some sanity checks on the toolchain. - -define LONG_DESC - This script does some sanity checks on the toolchain. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - -ifeq "$(STAGE)" "toolchain" -ifeq "$(PASS)" "1" - cd $(DIR_TMP) && \ - echo 'main(){}' | $(IFS_TARGET)-gcc -B $(TOOLS_DIR)/lib/ -x c - -lrt - cd $(DIR_TMP) && readelf -l a.out | grep ": $(TOOLS_DIR)" -endif - -ifeq "$(PASS)" "2" - # Sanity check - ensure host not being searched for libs - cd $(DIR_TMP) && \ - echo 'main(){}' | cc -x c -lbogus -v -Wl,--verbose - &> foo || : - cd $(DIR_TMP) && if grep "^attempt to open /usr" foo; then \ - echo Oops; exit 1; \ - fi -endif -endif - -ifeq "$(STAGE)" "base" - # Sanity checks. - cd $(DIR_TMP) && \ - echo 'main(){}' | cc -x c -specs=$$(dirname $$(gcc --print-libgcc-file-name))/myspecs \ - -B/usr/lib/ -B/usr/bin/ -Wl,--verbose - -lrt &> foo - # 1. dynamic linker - cd $(DIR_TMP) && readelf -l a.out | grep ": /lib" - - # 2. start files - cd $(DIR_TMP) && grep " /usr/lib/Scrt1.o succ" foo - - # 3. libc - cd $(DIR_TMP) && grep " /lib.*libc.so.6 succ" foo - - # 4. deps found from DT_NEEDED - cd $(DIR_TMP) && grep "^found.*at /lib.*/libpth" foo -endif - - @$(POSTBUILD) diff --git a/lfs/texinfo b/lfs/texinfo deleted file mode 100644 index 6264ec7..0000000 --- a/lfs/texinfo +++ /dev/null @@ -1,105 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = texinfo -PKG_VER = 4.13a -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(PKG_NAME)-4.13 - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Publishing -CORE = no -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gnu.org/software/texinfo/ -LICENSE = GPLv3 -SHORT_DESC = Tools needed to create Texinfo format documentation files. - -define LONG_DESC - Texinfo is a documentation system that can produce both online \ - information and printed output from a single source file. The GNU \ - Project uses the Texinfo file format for most of its documentation. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - LDFLAGS="-lncursesw" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - LDFLAGS="-lncursesw" \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/traceroute b/lfs/traceroute deleted file mode 100644 index 2a6bae0..0000000 --- a/lfs/traceroute +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = traceroute -PKG_VER = 2.0.12 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Internet -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://traceroute.sourceforge.net/ -LICENSE = GPLv2+ -SHORT_DESC = Traces the route taken by packets over an IPv4/IPv6 network. - -define LONG_DESC - The traceroute utility displays the route used by IP packets \ - on their way to a specified network (or Internet) host. \ - Traceroute displays the IP number and host name (if possible) \ - of the machines along the route taken by the packets. \ - Traceroute is used as a network debugging tool. If you're \ - having network connectivity problems, traceroute will show you \ - where the trouble is coming from along the route. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make $(PARALLELISMFLAGS) CFLAGS="$(CFLAGS)" LDFLAGS="" - cd $(DIR_APP) && make install prefix=/usr - chmod u-s /usr/bin/traceroute - ln -svf traceroute /usr/bin/traceroute6 - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/udev b/lfs/udev deleted file mode 100644 index 1c1e41d..0000000 --- a/lfs/udev +++ /dev/null @@ -1,120 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = udev -PKG_VER = 147 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = util-linux-ng gobject-introspection - -URL = ftp://ftp.kernel.org/pub/linux/utils/kernel/hotplug/ -LICENSE = GPLv2+ -SHORT_DESC = A userspace implementation of devfs. - -define LONG_DESC - The udev package contains an implementation \ - of devfs in userspace using sysfs and netlink. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - -rm -rf /lib/udev/devices - install -dv /lib/{firmware,udev/devices/{pts,shm}} - -mknod -m0600 /lib/udev/devices/console c 5 1 - -mknod -m0666 /lib/udev/devices/null c 1 3 - -mknod -m0600 /lib/udev/devices/kmsg c 1 11 - ln -sfv /proc/self/fd /lib/udev/devices/fd - ln -sfv /proc/self/fd/0 /lib/udev/devices/stdin - ln -sfv /proc/self/fd/1 /lib/udev/devices/stdout - ln -sfv /proc/self/fd/2 /lib/udev/devices/stderr - ln -sfv /proc/kcore /lib/udev/devices/core - - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --exec-prefix="" \ - --sbindir=/sbin \ - --sysconfdir=/etc \ - --with-libdir-name=/lib \ - --libexecdir=/lib/udev \ - --with-rootlibdir=/lib \ - --enable-introspection \ - --disable-rpath - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - install -m644 -v $(DIR_SOURCE)/$(PKG_NAME)/*.rules /lib/udev/rules.d/ - - for i in $(DIR_SOURCE)/initscripts/udev/*; do \ - install -m 755 -v $$i /lib/udev/$$(basename $$i); \ - done - - rm -vf /lib/libgudev-1.0.la - rm -vf /lib/libudev.la - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/ulogd2 b/lfs/ulogd2 deleted file mode 100644 index e25685b..0000000 --- a/lfs/ulogd2 +++ /dev/null @@ -1,106 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = ulogd -PKG_VER = 2.0.0beta3 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Statistics -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = sqlite - -URL = http://netfilter.org/projects/ulogd/index.html -LICENSE = GPLv2 -SHORT_DESC = The userspace logging daemon for netfilter. - -define LONG_DESC - This package contains utilities for configuring the linux ethernet \ - bridge. The linux ethernet bridge can be used for connecting multiple \ - ethernet devices together. The connecting is fully transparent: hosts \ - connected to one ethernet device see hosts connected to the other \ - ethernet devices directly. -endef - -INITSCRIPT = ulogd - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - #cd $(DIR_APP) && ./autogen.sh - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/ulogd.conf /etc/ulogd.conf - - $(INSTALL_INITSCRIPT) - - -mkdir -pv /var/log/ulogd - rm -vf /var/log/ulogd/ulogd.db - sqlite3 -echo /var/log/ulogd/ulogd.db < $(DIR_SOURCE)/$(PKG_NAME)/sqlite3.table - - rm -vf /usr/lib/ulogd/*.la - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/unzip b/lfs/unzip deleted file mode 100644 index 0917828..0000000 --- a/lfs/unzip +++ /dev/null @@ -1,93 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = unzip -PKG_VER = 5.52 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(PKG_NAME)$(subst .,,$(PKG_VER)).tgz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Archiving -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = ftp://ftp.info-zip.org/pub/infozip/src/ -LICENSE = BSD -SHORT_DESC = A utility for unpacking zip files. - -define LONG_DESC - The unzip utility is used to list, test, or extract files from a zip \ - archive. Zip archives are commonly found on MS-DOS systems. The zip \ - utility, included in the zip package, creates zip archives. Zip and \ - unzip are both compatible with archives created by PKWARE(R)'s PKZIP \ - for MS-DOS, but the programs' options and default behaviors do differ \ - in some respects. -endef - -CFLAGS += -D_LARGEFILE64_SOURCE - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && ln -svf unix/Makefile Makefile - cd $(DIR_APP) && make linux_noasm LF2="" CFLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install prefix=/usr MANDIR=/usr/share/man/man1 \ - INSTALL="cp -p" LF2="" - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/upstart b/lfs/upstart deleted file mode 100644 index e537b10..0000000 --- a/lfs/upstart +++ /dev/null @@ -1,113 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = upstart -PKG_VER = 0.6.3 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Stefan Schantl stefan.schantl@ipfire.org -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -DEPS = -BUILD_DEPS = gettext dbus - -URL = http://upstart.ubuntu.com/ -LICENSE = GPLv2+ -SHORT_DESC = An event-driven init system. - -define LONG_DESC - Upstart is an event-based replacement for the /sbin/init daemon \ - which handles starting of tasks and services during boot, \ - stopping them during shutdown and supervising them while the \ - system is running. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && \ - ./configure \ - --prefix=/usr \ - --sbindir=/sbin \ - --sysconfdir=/etc \ - --libdir=/lib - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - # These binaries are for the compatiblity mode, so we donŽt need them - rm -vf /sbin/poweroff - rm -vf /sbin/restart - rm -vf /sbin/runlevel - rm -vf /sbin/shutdown - rm -vf /sbin/telinit - - # These config files are for the compatiblity mode, so we donŽt need them - rm -vf /etc/init/control-alt-delete.conf - rm -vf /etc/init/rc-sysinit.conf - rm -vf /etc/init/rc.conf - rm -vf /etc/init/rcS.conf - - # Make shutdown/reboot comfortable. - -mkdir -pv /etc/profile.d - cp -vf $(DIR_SOURCE)/profile.d/upstart.sh /etc/profile.d - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/usb-key b/lfs/usb-key deleted file mode 120000 index 5e798fa..0000000 --- a/lfs/usb-key +++ /dev/null @@ -1 +0,0 @@ -images \ No newline at end of file diff --git a/lfs/usbutils b/lfs/usbutils deleted file mode 100644 index e4e9dbe..0000000 --- a/lfs/usbutils +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = usbutils -PKG_VER = 0.86 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -BUILD_DEPS = -DEPS = libusb - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Tools -CORE = yes -EXTRA = no -DEBUG = no - -URL = http://www.linux-usb.org/ -LICENSE = GPLv2 -SHORT_DESC = Tool to provide and enhance USB support in Linux. - -define LONG_DESC - A set of tools to configure list USB Devices. -endef - - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -fv /usr/share/usb.ids.gz - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/util-linux-ng b/lfs/util-linux-ng deleted file mode 100644 index aea7ab3..0000000 --- a/lfs/util-linux-ng +++ /dev/null @@ -1,141 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = util-linux-ng -PKG_VER = 2.16.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Base -CORE = yes -EXTRA = no -DEBUG = no -DEPS = -BUILD_DEPS = - -LICENSE = GPLv2 and GPLv2+ and BSD with advertising and Public Domain -URL = ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng -SHORT_DESC = A collection of basic system utilities. - -define LONG_DESC - The util-linux-ng package contains a large variety of low-level system \ - utilities that are necessary for a Linux system to function. Among \ - others, Util-linux contains the fdisk configuration tool and the login \ - program. -endef - -ifneq "$(STAGE)" "toolchain" - DEPS = ncurses pam zlib -else - DEPS = ncurses zlib -endif - -CFLAGS += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - cd $(DIR_APP) && sed -e 's@etc/adjtime@var/lib/hwclock/adjtime@g' \ - -i $$(grep -rl '/etc/adjtime' .) - mkdir -pv /var/lib/hwclock - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --bindir=/bin \ - --sbindir=/sbin \ - --disable-wall \ - --enable-arch \ - --enable-kill \ - --enable-login-utils \ - --enable-partx \ - --enable-write \ - --with-fsprobe=builtin \ - --disable-makeinstall-chown \ - --disable-static - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - rm -vf /usr/lib/libblkid.la - rm -vf /usr/lib/libuuid.la - - # Build nologin - cd $(DIR_APP) && gcc $(CFLAGS) -o nologin $(DIR_SOURCE)/$(PKG_NAME)/nologin.c - cd $(DIR_APP) && install -m 755 nologin /sbin - install -m 644 $(DIR_SOURCE)/$(PKG_NAME)/nologin.8 /usr/share/man/man8 - - ln -svf ../../sbin/hwclock /usr/sbin/hwclock - ln -svf hwclock /sbin/clock - ln -sf ../../bin/kill /usr/bin/kill - - touch /var/log/lastlog - - # Remove deprecated commands - rm -rfv /sbin/{fsck,mkfs}.{bfs,minix} \ - /usr/share/man/man*/{fsck,mkfs}.{bfs,minix}* - - # PAM - cp -vf $(DIR_SOURCE)/pam.d/login /etc/pam.d/ - - chmod -v -s /bin/mount - setcap CAP_DAC_OVERRIDE,CAP_SYS_ADMIN=ep /bin/mount - chmod -v -s /bin/umount - setcap CAP_DAC_OVERRIDE,CAP_SYS_ADMIN=ep /bin/umount - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/vala b/lfs/vala deleted file mode 100644 index 21dfb29..0000000 --- a/lfs/vala +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = vala -PKG_VER = 0.7.7 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = glib2 - -################ -##### TODO ##### perhaps needed for gupnp-media-server, otherwise delete -##### WIP ##### it after testing/verify. -################ - -URL = http://www.gupnp.org -LICENSE = LGPL -SHORT_DESC = Compiler for the GObject type system - -define LONG_DESC - Vala is a new programming language that aims to bring modern \ - programming language features to GNOME developers without imposing \ - any additional runtime requirements and without using a different \ - ABI compared to applications and libraries written in C. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/vim b/lfs/vim deleted file mode 100644 index 1e107e6..0000000 --- a/lfs/vim +++ /dev/null @@ -1,104 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = vim -PKG_VER = 7.2 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.bz2 -DIR_APP = $(DIR_SRC)/$(PKG_NAME)72 - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -CORE = yes -EXTRA = no -DEBUG = no - -MAINTAINER = -GROUP = Applications/Editors -BUILD_DEPS = -DEPS = - -URL = -LICENSE = PublicDomain/Charityware -SHORT_DESC = Very feature- and powerful editor. - -define LONG_DESC - Vim is a highly configurable text editor built to enable efficient \ - text editing. It is an improved version of the vi editor \ - distributed with most UNIX systems. -endef - - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-fixes-4.patch \ - $(THISAPP)-mandir-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 < $(DIR_PATCHES)/$(THISAPP)-fixes-4.patch - cd $(DIR_APP) && patch -Np1 < $(DIR_PATCHES)/$(THISAPP)-mandir-1.patch - cd $(DIR_APP) && echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --enable-multibyte - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - ln -sfv vim /usr/bin/vi - echo "set nocompatible" > /etc/vimrc - echo "set backspace=2" >> /etc/vimrc - echo "syntax on" >> /etc/vimrc - echo -e "if (&term == "iterm") || (&term == "putty")" >> /etc/vimrc - echo "set background=dark" >> /etc/vimrc - echo "endif" >> /etc/vimrc - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/vlan b/lfs/vlan deleted file mode 100644 index aafde27..0000000 --- a/lfs/vlan +++ /dev/null @@ -1,84 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = vlan -PKG_VER = 1.9 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(PKG_NAME) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Tools -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.candelatech.com/~greear/vlan.html -LICENSE = GPLv2+ -SHORT_DESC = Linux 802.1q VLAN configuration utility. - -define LONG_DESC - The vconfig program configures and adjusts 802.1q VLAN parameters. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && make purge vconfig - cd $(DIR_APP) && install -c -p -m 0755 vconfig /sbin - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/vsftpd b/lfs/vsftpd deleted file mode 100644 index 7be91fd..0000000 --- a/lfs/vsftpd +++ /dev/null @@ -1,115 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = vsftpd -PKG_VER = 2.2.1 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Daemons -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = openssl pam - -URL = ftp://vsftpd.beasts.org/users/cevans/ -LICENSE = GPLv2 with exceptions -SHORT_DESC = Very Secure Ftp Daemon. - -define LONG_DESC - vsftpd is a Very Secure FTP daemon. It was written completely \ - from scratch. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-libs-3.patch \ - $(THISAPP)-pam_hostname-1.patch \ - $(THISAPP)-build_ssl.patch \ - $(THISAPP)-close-std-fds.patch \ - $(THISAPP)-configuration-1.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # This patch enables the SSL feature of vsftpd. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-build_ssl.patch - - # This patch modifies the detection of the needed libs. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-libs-3.patch - - # This patch adds the pam_hostname feature to vsftpd. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-pam_hostname-1.patch - - # This patch modifies the close of running standalone vsftpd. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-close-std-fds.patch - - # This patch modifies the default configuration file. - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-configuration-1.patch - - cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) - - cd $(DIR_APP) && install -v -m 755 vsftpd /usr/sbin/vsftpd - cd $(DIR_APP) && install -v -m 644 vsftpd.8 /usr/share/man/man8 - cd $(DIR_APP) && install -v -m 644 vsftpd.conf.5 /usr/share/man/man5 - - # Install config - -mkdir -pv /etc/$(PKG_NAME) - cp -vf $(DIR_SOURCE)/$(PKG_NAME)/$(PKG_NAME).{conf,user_list} /etc/$(PKG_NAME) - cp -vf $(DIR_SOURCE)/pam.d/$(PKG_NAME) /etc/pam.d/ - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/webinterface b/lfs/webinterface deleted file mode 100644 index cfb8fff..0000000 --- a/lfs/webinterface +++ /dev/null @@ -1,84 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = webinterface -PKG_VER = ipfire -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DIR_APP = $(DIR_SOURCE)/web - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Webinterface -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = -LICENSE = Own -SHORT_DESC = The webinterface of IPFire. - -define LONG_DESC - The webinterface lets the user easily do configuration of the whole \ - system with just a few clicks. Some say it is one of the key features \ - of IPFire. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - -mkdir -p /srv/www/$(SNAME) - cd $(DIR_APP) && cp -av * /srv/www/$(SNAME)/ - chown nobody.nobody -R /srv/www/$(SNAME) - @$(POSTBUILD) diff --git a/lfs/which b/lfs/which deleted file mode 100644 index 408cd0f..0000000 --- a/lfs/which +++ /dev/null @@ -1,89 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = which -PKG_VER = 2.20 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/System -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = readline - -URL = http://www.xs4all.nl/~carlo17/which/ -LICENSE = GPLv3 -SHORT_DESC = Displays where a particular program in your path is located. - -define LONG_DESC - The which command shows the full pathname of a specified program, if \ - the specified program is in your PATH. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/wireless-tools b/lfs/wireless-tools deleted file mode 100644 index a22dd7d..0000000 --- a/lfs/wireless-tools +++ /dev/null @@ -1,91 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = wireless_tools -PKG_VER = 29 -PKG_REL = 0 - -THISAPP = $(PKG_NAME).$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Networking/Wireless -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html -LICENSE = GPL+ -SHORT_DESC = Wireless ethernet configuration tools. - -define LONG_DESC - This package contain the Wireless tools, used to manipulate \ - the Wireless Extensions. The Wireless Extension is an interface \ - allowing you to set Wireless LAN specific parameters and get the \ - specific stats for wireless networking equipment. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-makefile.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-makefile.patch - cd $(DIR_APP) && make $(PARALLELISMFLAGS) BUILD_SHARED=1 FORCE_WEXT_VERSION=16 OPT_FLAGS="$(CFLAGS)" - cd $(DIR_APP) && make install PREFIX=/usr INSTALL_DIR=/sbin INSTALL_LIB=/lib - rm -vf /lib/libiw.{a,so} - ln -svf ../../lib/libiw.so.$(PKG_VER) /usr/lib/libiw.so - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/xen b/lfs/xen deleted file mode 100644 index d2d2af2..0000000 --- a/lfs/xen +++ /dev/null @@ -1,103 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = xen -PKG_VER = 3.4.0 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP)-2.tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = Ben Schweikert ben.schweikert@ipfire.org -GROUP = Applications/Virtualization -CORE = no -EXTRA = yes -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.xen.org/ -LICENSE = GPLv2+ -SHORT_DESC = The Xen hypervisor. - -define LONG_DESC - The Xen hypervisor, the powerful open source industry standard \ - for virtualization, offers a powerful, efficient, and secure \ - feature set for virtualization. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-co_assignment.patch \ - $(THISAPP)-cpufreq.patch \ - xend-config-3.4.0.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - - # remove this ugly co_assignment error - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-co_assignment.patch - - # removes cpu freq bug. cpu stays at lowest freq - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-cpufreq.patch - - # adjust config file of the daemon - cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/xend-config-3.4.0.patch - - cd $(DIR_APP) && make xen $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install-xen - - # sometimes the auto directory is not created - -mkdir -pv /etc/xen/auto - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/xfsprogs b/lfs/xfsprogs deleted file mode 100644 index 0aa4fb5..0000000 --- a/lfs/xfsprogs +++ /dev/null @@ -1,100 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = xfsprogs -PKG_VER = 2.10.2 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP)-1.tar.bz2 -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Filesystems -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = libtool gettext - -URL = http://oss.sgi.com/projects/xfs/ -LICENSE = GPL+ and LGPLv2+ -SHORT_DESC = Utilities for managing the XFS filesystem. - -define LONG_DESC - A set of commands to use the XFS filesystem, including mkfs.xfs. -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-parallel-build.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects) : - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np2 -i $(DIR_PATCHES)/$(THISAPP)-parallel-build.patch - # XXX We compile xfsprogs STATIC at the moment because there is a bug with - # installation of the shared libs (may be it is libtool's fault). - cd $(DIR_APP) && DEBUG=-DNDEBUG \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --bindir=/sbin \ - --sbindir=/sbin \ - --libdir=/lib \ - --libexecdir=/usr/lib \ - --enable-shared=no - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install #install-dev - #chmod -v 755 /lib/libhandle.so* - #rm -f /lib/libhandle.{a,la,so} - #ln -svf ../../lib/libhandle.so.1 /usr/lib/libhandle.so - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/xz b/lfs/xz deleted file mode 100644 index 1d8f5bf..0000000 --- a/lfs/xz +++ /dev/null @@ -1,114 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = xz -PKG_VER = 4.999.8beta -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP).tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = Applications/Compression -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://tukaani.org/xz/ -LICENSE = GPLv2+ -SHORT_DESC = LZMA Utils. - -define LONG_DESC - LZMA provides very high compression ratio and fast decompression. The \ - core of the LZMA utils is Igor Pavlov's LZMA SDK containing the actual \ - LZMA encoder/decoder. LZMA utils add a few scripts which provide \ - gzip-like command line interface and a couple of other LZMA related \ - tools. -endef - -define QUALITY_AGENT_WHITELIST_RPATH - /usr/bin/xz \ - /usr/bin/lzmadec \ - /usr/bin/xzdec -endef - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "$(SNAME)" - cd $(DIR_APP) && \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - rm -vf /usr/lib/liblzma.la -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/lfs/zlib b/lfs/zlib deleted file mode 100644 index d9ef0b6..0000000 --- a/lfs/zlib +++ /dev/null @@ -1,117 +0,0 @@ -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### - -############################################################################### -# Definitions -############################################################################### - -include Config - -PKG_NAME = zlib -PKG_VER = 1.2.3 -PKG_REL = 0 - -THISAPP = $(PKG_NAME)-$(PKG_VER) -DL_FILE = $(THISAPP)-autotools-1.tar.gz -DIR_APP = $(DIR_SRC)/$(THISAPP) - -OBJECT = $(DIR_INFO)/$(STAGE_ORDER)_$(STAGE)/$(THISAPP) - -MAINTAINER = -GROUP = System/Libraries -CORE = yes -EXTRA = no -DEBUG = no -BUILD_DEPS = -DEPS = - -URL = http://www.gzip.org/zlib/ -LICENSE = zlib -SHORT_DESC = The zlib compression and decompression library. - -define LONG_DESC - Zlib is a general-purpose, patent-free, lossless data compression \ - library which is used by many different programs. -endef - -CFLAGS += -fPIC -DPIC - -############################################################################### -# Top-level Rules -############################################################################### - -objects = $(DL_FILE) \ - $(THISAPP)-autotools.patch - -download: $(objects) - -info: - $(DO_PKG_INFO) - -install: $(OBJECT) - -packages: $(PACKAGES) - -$(PACKAGES): $(OBJECT) - @$(DO_PACKAGE) - -$(objects): - @$(LOAD) - -############################################################################### -# Installation Details -############################################################################### - -$(OBJECT): $(objects) - @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && $(EXTRACTOR) $(DIR_DL)/$(DL_FILE) - #cd $(DIR_APP) && patch -Np1 -i $(DIR_PATCHES)/$(THISAPP)-autotools.patch - #cd $(DIR_APP) && autoreconf --install - -ifeq "$(STAGE)" "toolchain" - cd $(DIR_APP) && sed -e "s/^AC_PROG_CXX$$//g" -i configure.ac - cd $(DIR_APP) && autoreconf --install - cd $(DIR_APP) && \ - ac_cv_func_working_mktime=yes \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=$(TOOLS_DIR) \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install -endif - -ifeq "$(STAGE)" "base" - cd $(DIR_APP) && \ - ac_cv_func_working_mktime=yes \ - ./configure \ - $(CONFIGURE_ARCH) \ - --prefix=/usr \ - --libdir=/lib \ - --disable-static - cd $(DIR_APP) && make $(PARALLELISMFLAGS) - cd $(DIR_APP) && make install - cd $(DIR_APP) && cp -pfv zconf.h zlib.h /usr/include - rm -v /lib/libz.{la,so} - ln -sfv ../../lib/libz.so.$(PKG_VER) /usr/lib/libz.so -endif - - @rm -rf $(DIR_APP) - @$(POSTBUILD) diff --git a/make.sh b/make.sh index c5dca76..c8c1823 100755 --- a/make.sh +++ b/make.sh @@ -1,545 +1,145 @@ -#!/bin/bash -############################################################################### -# # -# IPFire.org - A linux based firewall # -# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see http://www.gnu.org/licenses/. # -# # -############################################################################### -# - -NAME="IPFire" # Software name -SNAME="ipfire" # Short name -VERSION="3.0-prealpha2" # Version number -TOOLCHAINVERSION="${VERSION}-13" # Toolchain -SLOGAN="Gluttony" # Software slogan - -# Include funtions -. tools/make-include - - -################################################################################ -# This builds the entire stage "toolchain" # -################################################################################ -toolchain_build() { - - ORG_PATH=$PATH - export PATH=${TOOLS_DIR}/usr/bin:${TOOLS_DIR}/usr/sbin:${TOOLS_DIR}/bin:${TOOLS_DIR}/sbin:$PATH - STAGE_ORDER=01 - STAGE=toolchain - - LOGFILE="$BASEDIR/log_${TARGET}/_build.${STAGE_ORDER}-toolchain.log" - export LOGFILE - - build_spy stage ${STAGE} - - # We can't skip packages in toolchain stage - SAVE_SKIP_PACKAGE_LIST=$SKIP_PACKAGE_LIST - SKIP_PACKAGE_LIST= - - icecc_disable - - toolchain_make stage1 - toolchain_make ccache PASS=1 - toolchain_make binutils PASS=1 - toolchain_make gcc PASS=1 - toolchain_make linux-headers - toolchain_make glibc - toolchain_make adjust-toolchain - toolchain_make test-toolchain PASS=1 - toolchain_make zlib - toolchain_make gcc PASS=2 - toolchain_make binutils PASS=2 - toolchain_make test-toolchain PASS=2 - toolchain_make ncurses - toolchain_make attr - toolchain_make acl - toolchain_make bash - toolchain_make bzip2 - toolchain_make coreutils - toolchain_make cpio - toolchain_make diffutils - toolchain_make e2fsprogs - toolchain_make icecc - icecc_enable - icecc_use toolchain # Use the fresh gcc - toolchain_make ccache PASS=2 - toolchain_make file - toolchain_make findutils - toolchain_make gawk - toolchain_make gettext - toolchain_make grep - toolchain_make gzip - toolchain_make m4 - toolchain_make make - toolchain_make patch - toolchain_make pax-utils - toolchain_make perl - toolchain_make sed - toolchain_make tar - toolchain_make texinfo - toolchain_make flex - toolchain_make bc - toolchain_make xz - toolchain_make autoconf - toolchain_make automake - toolchain_make strip - - export PATH=$ORG_PATH SKIP_PACKAGE_LIST=$SAVE_SKIP_PACKAGE_LIST - unset SAVE_SKIP_PACKAGE_LIST -} - -################################################################################ -# This builds the entire stage "base" # -################################################################################ -base_build() { - - PATH=${TOOLS_DIR}/usr/bin:/bin:/usr/bin:/sbin:/usr/sbin:$TOOLS_DIR/bin - STAGE_ORDER=02 - STAGE=base - - LOGFILE="$BASEDIR/log_${TARGET}/_build.${STAGE_ORDER}-base.log" - export LOGFILE - - build_spy stage ${STAGE} - - # Start distributed compiling with toolchain - iceccd_start - icecc_use toolchain - - ipfire_make stage2 - ipfire_make scripts - ipfire_make system-release - ipfire_make linux-headers - ipfire_make man-pages - ipfire_make glibc - ipfire_make adjust-toolchain - ipfire_make test-toolchain - ipfire_make zlib - ipfire_make binutils - ipfire_make gcc - - # Change to self-built gcc - icecc_use base - - ipfire_make make - ipfire_make libtool - ipfire_make gettext - ipfire_make pkg-config - ipfire_make berkeley - ipfire_make sed - ipfire_make iana-etc - ipfire_make m4 - ipfire_make bison - ipfire_make flex - ipfire_make ncurses - ipfire_make shadow - ipfire_make cracklib - ipfire_make pam - ipfire_make attr - ipfire_make acl - ipfire_make libcap2 - ipfire_make util-linux-ng - ipfire_make e2fsprogs - ipfire_make coreutils - ipfire_make procps - ipfire_make perl - ipfire_make readline - ipfire_make libidn - ipfire_make bzip2 - ipfire_make pcre - ipfire_make paxctl - ipfire_make autoconf - ipfire_make automake - ipfire_make bash - ipfire_make cpio - ipfire_make diffutils - ipfire_make eventlog - ipfire_make file - ipfire_make findutils - ipfire_make gmp - ipfire_make grub - ipfire_make gawk - ipfire_make glib2 -# ipfire_make vala - ipfire_make grep - ipfire_make groff - ipfire_make gzip - ipfire_make iputils - ipfire_make iproute2 - ipfire_make kbd - ipfire_make less - ipfire_make man-db - ipfire_make module-init-tools - ipfire_make mpfr - ipfire_make patch - ipfire_make pax-utils - ipfire_make psmisc - ipfire_make syslog-ng - ipfire_make sysvinit - ipfire_make tar - ipfire_make texinfo - ipfire_make vim -} - -################################################################################ -# This builds the entire stage "ipfire" # -################################################################################ -ipfire_build() { - PATH=${TOOLS_DIR}/usr/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/${MACHINE_REAL}-linux/bin - STAGE_ORDER=03 - STAGE=ipfire - - LOGFILE="$BASEDIR/log_${TARGET}/_build.${STAGE_ORDER}-ipfire.log" - export LOGFILE - - build_spy stage ${STAGE} - - ### Building the configuration dirs and files - # - ipfire_make stage3 - ipfire_make xz - ipfire_make unzip - - ipfire_make linux - - ### Building some general stuff - # STAGE 1 - ipfire_make libdaemon - ipfire_make expat - ipfire_make dbus - ipfire_make dbus-glib - ipfire_make upstart - ipfire_make initscripts - ipfire_make openssl - ipfire_make pth - ipfire_make libassuan - ipfire_make libgpg-error - ipfire_make libgcrypt - ipfire_make gnutls - ipfire_make perl-xml-parser - ipfire_make intltool - ipfire_make python - ipfire_make python-cracklib - ipfire_make python-dbus - ipfire_make python-setuptools - ipfire_make python-urlgrabber - ipfire_make python-IPy - ipfire_make libxml2 - ipfire_make libxslt - ipfire_make popt - ipfire_make libusb - ipfire_make libusb-compat # Can be removed if usbutils supports libusb-1.0 - ipfire_make bc - ipfire_make boost - ipfire_make lua - - ### Building some network stuff - # - ipfire_make libpcap - ipfire_make linux-atm - ipfire_make ppp - ipfire_make pptp - ipfire_make dhcp - ipfire_make iptables - ipfire_make libnfnetlink - ipfire_make libnetfilter_queue - ipfire_make libnetfilter_conntrack - ipfire_make libnetfilter_log - ipfire_make python-netfilter_conntrack - ipfire_make l7-protocols - ipfire_make bridge-utils - ipfire_make vlan - ipfire_make bind - ipfire_make jwhois - ipfire_make avahi - ipfire_make libssh2 - ipfire_make libdnet - ipfire_make rstp - ipfire_make ebtables - ipfire_make openlldp - ipfire_make radvd - ipfire_make aiccu - ipfire_make libnl - ipfire_make iw - - ### Building some general stuff - # STAGE 2 - ipfire_make libksba - ipfire_make slang - ipfire_make newt - ipfire_make cyrus-sasl - ipfire_make openldap - ipfire_make pam_ldap - ipfire_make nss_ldap - ipfire_make ldapvi - ipfire_make sqlite - ipfire_make python-sqlite2 - ipfire_make curl - ipfire_make pinentry - ipfire_make gnupg2 - ipfire_make sudo - ipfire_make libjpeg - ipfire_make libpng - ipfire_make libtiff - ipfire_make libart - ipfire_make libsoup - ipfire_make gssdp - ipfire_make gupnp -# ipfire_make gupnp-tools - ipfire_make gupnp-av - ipfire_make gupnp-igd -# ipfire_make gconf -# ipfire_make gupnp-media-server - ipfire_make freetype - ipfire_make fontconfig - ipfire_make pixman - ipfire_make cairo - ipfire_make pango - ipfire_make lzo - ipfire_make lsof - ipfire_make br2684ctl - ipfire_make etherwake - ipfire_make beep - ipfire_make libuser - ipfire_make passwd - ipfire_make directfb - ipfire_make pdns - ipfire_make pdns-recursor - ipfire_make libevent - ipfire_make libnfsidmap - ipfire_make libgssglue - ipfire_make librpcsecgss - ipfire_make gperf - - ### Building vpn stuff - # - ipfire_make strongswan - ipfire_make openvpn - - ### Building filesystem stuff - # - ipfire_make btrfs-progs - ipfire_make reiserfsprogs - ipfire_make libaal - ipfire_make reiser4progs - ipfire_make xfsprogs - ipfire_make sysfsutils - ipfire_make squashfs-tools - ipfire_make dosfstools - ipfire_make lvm2 - ipfire_make mdadm - ipfire_make dmraid - ipfire_make cryptsetup-luks - ipfire_make python-cryptsetup - ipfire_make fuse - - ### Building hardware utils - # - ipfire_make pciutils - ipfire_make usbutils - ipfire_make hdparm - ipfire_make smartmontools - ipfire_make lm-sensors - ipfire_make parted - ipfire_make hal - ipfire_make hal-info - ipfire_make gobject-introspection - ipfire_make udev - - ### Building some important tools - # - ipfire_make ulogd2 - ipfire_make which - ipfire_make screen - ipfire_make rrdtool - ipfire_make ntp - ipfire_make openssh - ipfire_make ez-ipupdate - ipfire_make noip - ipfire_make lighttpd - ipfire_make webinterface - ipfire_make logrotate - #ipfire_make logwatch - ipfire_make dvdrtools - ipfire_make python-parted - ipfire_make python-pyblock - ipfire_make libbdevid - ipfire_make memtest86+ - ipfire_make quagga - #ipfire_make mISDN - ipfire_make wireless-tools - - ipfire_make python-werkzeug - ipfire_make python-flup - ipfire_make python-tornado - ipfire_make pyfire - ipfire_make network - ipfire_make firewall - ipfire_make pakfire -} - -################################################################################ -# This builds the entire stage "misc" # -################################################################################ -misc_build() { - - PATH=${TOOLS_DIR}/usr/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/${MACHINE_REAL}-linux/bin - STAGE_ORDER=04 - STAGE=misc - - LOGFILE="$BASEDIR/log_${TARGET}/_build.${STAGE_ORDER}-misc.log" - export LOGFILE - - build_spy stage ${STAGE} - - ipfire_make stage4 - - ### Console tools - # - ipfire_make mc - ipfire_make traceroute - ipfire_make nmap - #ipfire_make rsync - ipfire_make tcpdump - ipfire_make htop - ipfire_make nano - ipfire_make joe - - ### Servers - # - ipfire_make squid - ipfire_make samba - - ### Assembler - # - ipfire_make nasm - ipfire_make syslinux - - ipfire_make mkinitramfs - ipfire_make splashy - - ipfire_make vsftpd - - ## NTFS - #ipfire_make ntfs-3g - # - ## Net tools - ipfire_make net-snmp - ipfire_make bwm-ng - - ### These will become addons as usual but will be integrated later - # - #ipfire_make snort - #ipfire_make oinkmaster - ipfire_make ghostscript - ipfire_make cups - ipfire_make sane - ipfire_make hplip - #ipfire_make postfix - #ipfire_make fetchmail - #ipfire_make clamav - #ipfire_make alsa - ipfire_make portmap - ipfire_make nfs-utils - ipfire_make freeradius - ipfire_make hostapd - - ### Debugging - # - ipfire_make paxtest - ipfire_make gdb - ipfire_make strace - ipfire_make pychecker - - ### Virtualization - # - ipfire_make xen - ipfire_make qemu - ipfire_make libvirt -} - -################################################################################ -# This builds the entire stage "installer" # -################################################################################ -installer_build() { - - PATH=${TOOLS_DIR}/usr/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/${MACHINE_REAL}-linux/bin - STAGE_ORDER=05 - STAGE=installer - - LOGFILE="$BASEDIR/log_${TARGET}/_build.${STAGE_ORDER}-installer.log" - export LOGFILE - - build_spy stage ${STAGE} - - ipfire_make stage5 - ipfire_make pomona -} - -################################################################################ -# This builds the entire stage "packages" # -################################################################################ -packages_build() { - - PATH=${TOOLS_DIR}/usr/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/${MACHINE_REAL}-linux/bin - STAGE_ORDER=06 - STAGE=packages - - LOGFILE="$BASEDIR/log_${TARGET}/_build.${STAGE_ORDER}-packages.log" - export LOGFILE - - build_spy stage ${STAGE} - - # Generate ChangeLog - git_log - - # Generate packages list - echo -n "Generating packages list" - pkg_list_packages > $BASEDIR/doc/packages-list.txt - beautify message DONE - - if [ ${EMB} -eq 0 ]; then - ipfire_make images-core - ipfire_make images-info - ipfire_make images-initramfs - ipfire_make images-overlays - ipfire_make pxe - ipfire_make cdrom - - if check_loop; then - : #ipfire_make usb-key - else - echo -n "Can't build usb-key images on this machine" - beautify message WARN - fi - mv $LFS/$IMAGES_DIR/{*.iso,*.tar.gz,*.img.gz} $BASEDIR >>$LOGFILE 2>&1 - else - if check_loop; then - # We put here the code that is done when - # we do an embedded build - : - fi - fi - - # Cleanup - stdumount - rm -rf $LFS/tmp/* - - cd $PWD -} - -# See what we're supposed to do -. $BASEDIR/tools/make-interactive +#!/usr/bin/python + +import sys +try: + import argparse +except ImportError: + import naoki.argparse as argparse + +import naoki + +arches = naoki.arches +config = naoki.config + +# silence Python 2.6 buggy warnings about Exception.message +if sys.version_info[:2] == (2, 6): + import warnings + warnings.filterwarnings( + action="ignore", + message="BaseException.message has been deprecated as of Python 2.6", + category=DeprecationWarning) + +# Command line parsing +parser = argparse.ArgumentParser( + description = "Command to control the naoki buildsystem" +) + +parser.add_argument("-q", "--quiet", action="store_true", help="run in silent mode") +parser.add_argument("-d", "--debug", action="store_true", help="run in debug mode") +parser.add_argument("-a", "--arch", default=arches.default["name"], help="set architecture") +subparsers = parser.add_subparsers(help="sub-command help") + +# Build command +parser_build = subparsers.add_parser("build", help="build command") +parser_build.set_defaults(action="build") +parser_build.add_argument("package", nargs="+", help="package name") + + +# Toolchain command +parser_toolchain = subparsers.add_parser("toolchain", help="toolchain command") +parser_toolchain.set_defaults(action="toolchain") +subparsers_toolchain = parser_toolchain.add_subparsers(help="sub-command help") + + # toolchain build +parser_toolchain_build = subparsers_toolchain.add_parser("build", help="build toolchain") +parser_toolchain_build.set_defaults(subaction="build") + + # toolchain build +parser_toolchain_download = subparsers_toolchain.add_parser("download", help="download toolchain") +parser_toolchain_download.set_defaults(subaction="download") + + +# Package command +parser_package = subparsers.add_parser("package", help="package command") +parser_package.set_defaults(action="package") +subparsers_package = parser_package.add_subparsers(help="sub-command help") + + # package info [-l, --long] +parser_package_info = subparsers_package.add_parser("info", help="show package information") +parser_package_info.set_defaults(subaction="info") +parser_package_info.add_argument("-l", "--long", action="store_true", help="print in long format") +parser_package_info.add_argument("--machine", action="store_true", help="output in machine readable format") +parser_package_info.add_argument("--wiki", action="store_true", help="output in wiki format") +parser_package_info.add_argument("package", nargs="+", help="package name") + + # package tree +parser_package_tree = subparsers_package.add_parser("tree", help="show package tree") +parser_package_tree.set_defaults(subaction="tree") + + # package list [-l, --long] +parser_package_list = subparsers_package.add_parser("list", help="show package list") +parser_package_list.set_defaults(subaction="list") +parser_package_list.add_argument("-l", "--long", action="store_true", help="print list in long format") + + # package groups +parser_package_groups = subparsers_package.add_parser("groups", help="show package groups") +parser_package_groups.set_defaults(subaction="groups") +parser_package_groups.add_argument("--wiki", action="store_true", help="output in wiki format") + + +# Source command +parser_source = subparsers.add_parser("source", help="source command") +parser_source.set_defaults(action="source") +subparsers_source = parser_source.add_subparsers(help="sub-command help") + + # source download +parser_source_download = subparsers_source.add_parser("download", help="download source tarballs") +parser_source_download.set_defaults(subaction="download") +parser_source_download.add_argument("package", nargs="*", help="package name") + + # source upload +parser_source_upload = subparsers_source.add_parser("upload", help="upload source tarballs") +parser_source_upload.set_defaults(subaction="upload") +parser_source_upload.add_argument("package", nargs="*", help="package name") + + # source clean +parser_source_clean = subparsers_source.add_parser("clean", help="cleanup unused source tarballs") +parser_source_clean.set_defaults(subaction="clean") + + +# Check command +parser_check = subparsers.add_parser("check", help="check command") +parser_check.set_defaults(action="check") +subparsers_check = parser_check.add_subparsers(help="sub-command help") + + # check host +parser_check_host = subparsers_check.add_parser("host", help="check if host fulfills requirements") +parser_check_host.set_defaults(subaction="host") + + +# Batch command +parser_batch = subparsers.add_parser("batch", help="batch command") +parser_batch.set_defaults(action="batch") +subparsers_batch = parser_batch.add_subparsers(help="sub-command help") + + # batch cron +parser_batch_cron = subparsers_batch.add_parser("cron", help="gets called by a cron daemon") +parser_batch_cron.set_defaults(subaction="cron") + + +# parse the command line +args = parser.parse_args() + +if args.debug: + print "Command line arguments:", args + +# Set default arch +arches.set(args.arch) + +kwargs = {} +for key, val in args._get_kwargs(): + kwargs[key] = val + +try: + n = naoki.Naoki() + n(**kwargs) + exitStatus = 0 + +except (SystemExit,): + raise + +except (KeyboardInterrupt,): + exitStatus = 7 + n.log.error("Exiting on user interrupt, <CTRL>-C") + +sys.exit(exitStatus) diff --git a/naoki/__init__.py b/naoki/__init__.py new file mode 100644 index 0000000..212f81f --- /dev/null +++ b/naoki/__init__.py @@ -0,0 +1,151 @@ +#!/usr/bin/python + +import ConfigParser +import curses +import logging +import logging.config +import logging.handlers +import os.path +import sys +import time + +import logger +import package +import util + +from constants import * + +# fix for python 2.4 logging module bug: +logging.raiseExceptions = 0 + +class Naoki(object): + def __init__(self): + self.setup_logging() + + self.log.debug("Successfully initialized naoki instance") + for k, v in config.items(): + self.log.debug(" %s: %s" % (k, v)) + + def setup_logging(self): + self.log = logging.getLogger() + + log_ini = config["log_config_file"] + if os.path.exists(log_ini): + logging.config.fileConfig(log_ini) + + if sys.stderr.isatty(): + curses.setupterm() + self.log.handlers[0].setFormatter(logger._ColorLogFormatter()) + + if config["quiet"]: + self.log.handlers[0].setLevel(logging.WARNING) + else: + self.log.handlers[0].setLevel(logging.INFO) + + if not os.path.isdir(LOGDIR): + os.makedirs(LOGDIR) + fh = logging.handlers.RotatingFileHandler(config["log_file"], + maxBytes=10*1024**2, backupCount=6) + fh.setFormatter(logging.Formatter("[%(levelname)s] %(message)s")) + fh.setLevel(logging.NOTSET) + self.log.addHandler(fh) + + def __call__(self, action, **kwargs): + if action == "build": + self.call_build(kwargs.get("package")) + + elif action == "toolchain": + self.call_toolchain(kwargs.get("subaction"), kwargs.get("arch")) + + elif action == "package": + self.call_package(kwargs.pop("subaction"), **kwargs) + + def call_toolchain(self, subaction, arch): + tc = chroot.Toolchain(arch) + + if subaction == "build": + tc.build() + + elif subaction == "download": + tc.download() + + def call_build(self, packages): + force = True + + if packages == ["all"]: + force = False + packages = package.list() + else: + packages = [package.find(p) for p in packages] + for p in packages: + if not p: packages.remove(p) + + self._build(packages, force=force) + + def call_package(self, subaction, **kwargs): + if subaction == "list": + for pkg in self.packages: + print pkg.info_line(long=kwargs["long"]) + + elif subaction == "info": + packages = [package.find(pkg) for pkg in kwargs.get("package")] + packages.sort() + + if kwargs["wiki"]: + for pkg in packages: + print pkg.info_wiki() + return + + delimiter = "----------------------------------------------------\n" + + print delimiter.join([pkg.info(long=kwargs["long"]) for pkg in packages]) + + elif subaction == "tree": + print package.deptree(self.packages) + + elif subaction == "groups": + groups = package.groups() + + if kwargs["wiki"]: + print "====== All available groups of packages ======" + for group in groups: + print group.wiki_headline() + for pkg in group.packages: + print pkg.info_wiki(long=False) + + return + + print "\n".join(package.group_names()) + + def _build(self, packages, force=False): + requeue = [] + packages = package.depsort(packages) + while packages: + # Get first package that is to be done + build = chroot.Environment(packages.pop(0)) + + if not build.toolchain.exists: + self.log.error("You need to build or download a toolchain first.") + return + + if build.package.isBuilt: + if not force: + self.log.info("Skipping already built package %s..." % build.package.name) + continue + self.log.warn("Package is already built. Will overwrite.") + + if not build.package.canBuild: + self.log.warn("Cannot build package %s." % build.package.name) + if not self.packages: + self.log.error("Blah") + return + self.log.warn("Requeueing. %s" % build.package.name) + self.packages.append(build.package) + continue + + self.log.info("Building %s..." % build.package.name) + build.build() + + @property + def packages(self): + return package.list() diff --git a/naoki/argparse.py b/naoki/argparse.py new file mode 100644 index 0000000..ce1adb9 --- /dev/null +++ b/naoki/argparse.py @@ -0,0 +1,2270 @@ +# -*- coding: utf-8 -*- + +# Copyright © 2006-2009 Steven J. Bethard steven.bethard@gmail.com. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Command-line parsing library + +This module is an optparse-inspired command-line parsing library that: + + - handles both optional and positional arguments + - produces highly informative usage messages + - supports parsers that dispatch to sub-parsers + +The following is a simple usage example that sums integers from the +command-line and writes the result to a file:: + + parser = argparse.ArgumentParser( + description='sum the integers at the command line') + parser.add_argument( + 'integers', metavar='int', nargs='+', type=int, + help='an integer to be summed') + parser.add_argument( + '--log', default=sys.stdout, type=argparse.FileType('w'), + help='the file where the sum should be written') + args = parser.parse_args() + args.log.write('%s' % sum(args.integers)) + args.log.close() + +The module contains the following public classes: + + - ArgumentParser -- The main entry point for command-line parsing. As the + example above shows, the add_argument() method is used to populate + the parser with actions for optional and positional arguments. Then + the parse_args() method is invoked to convert the args at the + command-line into an object with attributes. + + - ArgumentError -- The exception raised by ArgumentParser objects when + there are errors with the parser's actions. Errors raised while + parsing the command-line are caught by ArgumentParser and emitted + as command-line messages. + + - FileType -- A factory for defining types of files to be created. As the + example above shows, instances of FileType are typically passed as + the type= argument of add_argument() calls. + + - Action -- The base class for parser actions. Typically actions are + selected by passing strings like 'store_true' or 'append_const' to + the action= argument of add_argument(). However, for greater + customization of ArgumentParser actions, subclasses of Action may + be defined and passed as the action= argument. + + - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter, + ArgumentDefaultsHelpFormatter -- Formatter classes which + may be passed as the formatter_class= argument to the + ArgumentParser constructor. HelpFormatter is the default, + RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser + not to change the formatting for help text, and + ArgumentDefaultsHelpFormatter adds information about argument defaults + to the help. + +All other classes in this module are considered implementation details. +(Also note that HelpFormatter and RawDescriptionHelpFormatter are only +considered public as object names -- the API of the formatter objects is +still considered an implementation detail.) +""" + +__version__ = '1.0.1' +__all__ = [ + 'ArgumentParser', + 'ArgumentError', + 'Namespace', + 'Action', + 'FileType', + 'HelpFormatter', + 'RawDescriptionHelpFormatter', + 'RawTextHelpFormatter' + 'ArgumentDefaultsHelpFormatter', +] + + +import copy as _copy +import os as _os +import re as _re +import sys as _sys +import textwrap as _textwrap + +from gettext import gettext as _ + +try: + _set = set +except NameError: + from sets import Set as _set + +try: + _basestring = basestring +except NameError: + _basestring = str + +try: + _sorted = sorted +except NameError: + + def _sorted(iterable, reverse=False): + result = list(iterable) + result.sort() + if reverse: + result.reverse() + return result + +# silence Python 2.6 buggy warnings about Exception.message +if _sys.version_info[:2] == (2, 6): + import warnings + warnings.filterwarnings( + action='ignore', + message='BaseException.message has been deprecated as of Python 2.6', + category=DeprecationWarning, + module='argparse') + + +SUPPRESS = '==SUPPRESS==' + +OPTIONAL = '?' +ZERO_OR_MORE = '*' +ONE_OR_MORE = '+' +PARSER = '==PARSER==' + +# ============================= +# Utility functions and classes +# ============================= + +class _AttributeHolder(object): + """Abstract base class that provides __repr__. + + The __repr__ method returns a string in the format:: + ClassName(attr=name, attr=name, ...) + The attributes are determined either by a class-level attribute, + '_kwarg_names', or by inspecting the instance __dict__. + """ + + def __repr__(self): + type_name = type(self).__name__ + arg_strings = [] + for arg in self._get_args(): + arg_strings.append(repr(arg)) + for name, value in self._get_kwargs(): + arg_strings.append('%s=%r' % (name, value)) + return '%s(%s)' % (type_name, ', '.join(arg_strings)) + + def _get_kwargs(self): + return _sorted(self.__dict__.items()) + + def _get_args(self): + return [] + + +def _ensure_value(namespace, name, value): + if getattr(namespace, name, None) is None: + setattr(namespace, name, value) + return getattr(namespace, name) + + +# =============== +# Formatting Help +# =============== + +class HelpFormatter(object): + """Formatter for generating usage messages and argument help strings. + + Only the name of this class is considered a public API. All the methods + provided by the class are considered an implementation detail. + """ + + def __init__(self, + prog, + indent_increment=2, + max_help_position=24, + width=None): + + # default setting for width + if width is None: + try: + width = int(_os.environ['COLUMNS']) + except (KeyError, ValueError): + width = 80 + width -= 2 + + self._prog = prog + self._indent_increment = indent_increment + self._max_help_position = max_help_position + self._width = width + + self._current_indent = 0 + self._level = 0 + self._action_max_length = 0 + + self._root_section = self._Section(self, None) + self._current_section = self._root_section + + self._whitespace_matcher = _re.compile(r'\s+') + self._long_break_matcher = _re.compile(r'\n\n\n+') + + # =============================== + # Section and indentation methods + # =============================== + def _indent(self): + self._current_indent += self._indent_increment + self._level += 1 + + def _dedent(self): + self._current_indent -= self._indent_increment + assert self._current_indent >= 0, 'Indent decreased below 0.' + self._level -= 1 + + class _Section(object): + + def __init__(self, formatter, parent, heading=None): + self.formatter = formatter + self.parent = parent + self.heading = heading + self.items = [] + + def format_help(self): + # format the indented section + if self.parent is not None: + self.formatter._indent() + join = self.formatter._join_parts + for func, args in self.items: + func(*args) + item_help = join([func(*args) for func, args in self.items]) + if self.parent is not None: + self.formatter._dedent() + + # return nothing if the section was empty + if not item_help: + return '' + + # add the heading if the section was non-empty + if self.heading is not SUPPRESS and self.heading is not None: + current_indent = self.formatter._current_indent + heading = '%*s%s:\n' % (current_indent, '', self.heading) + else: + heading = '' + + # join the section-initial newline, the heading and the help + return join(['\n', heading, item_help, '\n']) + + def _add_item(self, func, args): + self._current_section.items.append((func, args)) + + # ======================== + # Message building methods + # ======================== + def start_section(self, heading): + self._indent() + section = self._Section(self, self._current_section, heading) + self._add_item(section.format_help, []) + self._current_section = section + + def end_section(self): + self._current_section = self._current_section.parent + self._dedent() + + def add_text(self, text): + if text is not SUPPRESS and text is not None: + self._add_item(self._format_text, [text]) + + def add_usage(self, usage, actions, groups, prefix=None): + if usage is not SUPPRESS: + args = usage, actions, groups, prefix + self._add_item(self._format_usage, args) + + def add_argument(self, action): + if action.help is not SUPPRESS: + + # find all invocations + get_invocation = self._format_action_invocation + invocations = [get_invocation(action)] + for subaction in self._iter_indented_subactions(action): + invocations.append(get_invocation(subaction)) + + # update the maximum item length + invocation_length = max([len(s) for s in invocations]) + action_length = invocation_length + self._current_indent + self._action_max_length = max(self._action_max_length, + action_length) + + # add the item to the list + self._add_item(self._format_action, [action]) + + def add_arguments(self, actions): + for action in actions: + self.add_argument(action) + + # ======================= + # Help-formatting methods + # ======================= + def format_help(self): + help = self._root_section.format_help() + if help: + help = self._long_break_matcher.sub('\n\n', help) + help = help.strip('\n') + '\n' + return help + + def _join_parts(self, part_strings): + return ''.join([part + for part in part_strings + if part and part is not SUPPRESS]) + + def _format_usage(self, usage, actions, groups, prefix): + if prefix is None: + prefix = _('usage: ') + + # if usage is specified, use that + if usage is not None: + usage = usage % dict(prog=self._prog) + + # if no optionals or positionals are available, usage is just prog + elif usage is None and not actions: + usage = '%(prog)s' % dict(prog=self._prog) + + # if optionals and positionals are available, calculate usage + elif usage is None: + prog = '%(prog)s' % dict(prog=self._prog) + + # split optionals from positionals + optionals = [] + positionals = [] + for action in actions: + if action.option_strings: + optionals.append(action) + else: + positionals.append(action) + + # build full usage string + format = self._format_actions_usage + action_usage = format(optionals + positionals, groups) + usage = ' '.join([s for s in [prog, action_usage] if s]) + + # wrap the usage parts if it's too long + text_width = self._width - self._current_indent + if len(prefix) + len(usage) > text_width: + + # break usage into wrappable parts + part_regexp = r'(.*?)+|[.*?]+|\S+' + opt_usage = format(optionals, groups) + pos_usage = format(positionals, groups) + opt_parts = _re.findall(part_regexp, opt_usage) + pos_parts = _re.findall(part_regexp, pos_usage) + assert ' '.join(opt_parts) == opt_usage + assert ' '.join(pos_parts) == pos_usage + + # helper for wrapping lines + def get_lines(parts, indent, prefix=None): + lines = [] + line = [] + if prefix is not None: + line_len = len(prefix) - 1 + else: + line_len = len(indent) - 1 + for part in parts: + if line_len + 1 + len(part) > text_width: + lines.append(indent + ' '.join(line)) + line = [] + line_len = len(indent) - 1 + line.append(part) + line_len += len(part) + 1 + if line: + lines.append(indent + ' '.join(line)) + if prefix is not None: + lines[0] = lines[0][len(indent):] + return lines + + # if prog is short, follow it with optionals or positionals + if len(prefix) + len(prog) <= 0.75 * text_width: + indent = ' ' * (len(prefix) + len(prog) + 1) + if opt_parts: + lines = get_lines([prog] + opt_parts, indent, prefix) + lines.extend(get_lines(pos_parts, indent)) + elif pos_parts: + lines = get_lines([prog] + pos_parts, indent, prefix) + else: + lines = [prog] + + # if prog is long, put it on its own line + else: + indent = ' ' * len(prefix) + parts = opt_parts + pos_parts + lines = get_lines(parts, indent) + if len(lines) > 1: + lines = [] + lines.extend(get_lines(opt_parts, indent)) + lines.extend(get_lines(pos_parts, indent)) + lines = [prog] + lines + + # join lines into usage + usage = '\n'.join(lines) + + # prefix with 'usage:' + return '%s%s\n\n' % (prefix, usage) + + def _format_actions_usage(self, actions, groups): + # find group indices and identify actions in groups + group_actions = _set() + inserts = {} + for group in groups: + try: + start = actions.index(group._group_actions[0]) + except ValueError: + continue + else: + end = start + len(group._group_actions) + if actions[start:end] == group._group_actions: + for action in group._group_actions: + group_actions.add(action) + if not group.required: + inserts[start] = '[' + inserts[end] = ']' + else: + inserts[start] = '(' + inserts[end] = ')' + for i in range(start + 1, end): + inserts[i] = '|' + + # collect all actions format strings + parts = [] + for i, action in enumerate(actions): + + # suppressed arguments are marked with None + # remove | separators for suppressed arguments + if action.help is SUPPRESS: + parts.append(None) + if inserts.get(i) == '|': + inserts.pop(i) + elif inserts.get(i + 1) == '|': + inserts.pop(i + 1) + + # produce all arg strings + elif not action.option_strings: + part = self._format_args(action, action.dest) + + # if it's in a group, strip the outer [] + if action in group_actions: + if part[0] == '[' and part[-1] == ']': + part = part[1:-1] + + # add the action string to the list + parts.append(part) + + # produce the first way to invoke the option in brackets + else: + option_string = action.option_strings[0] + + # if the Optional doesn't take a value, format is: + # -s or --long + if action.nargs == 0: + part = '%s' % option_string + + # if the Optional takes a value, format is: + # -s ARGS or --long ARGS + else: + default = action.dest.upper() + args_string = self._format_args(action, default) + part = '%s %s' % (option_string, args_string) + + # make it look optional if it's not required or in a group + if not action.required and action not in group_actions: + part = '[%s]' % part + + # add the action string to the list + parts.append(part) + + # insert things at the necessary indices + for i in _sorted(inserts, reverse=True): + parts[i:i] = [inserts[i]] + + # join all the action items with spaces + text = ' '.join([item for item in parts if item is not None]) + + # clean up separators for mutually exclusive groups + open = r'[[(]' + close = r'[])]' + text = _re.sub(r'(%s) ' % open, r'\1', text) + text = _re.sub(r' (%s)' % close, r'\1', text) + text = _re.sub(r'%s *%s' % (open, close), r'', text) + text = _re.sub(r'(([^|]*))', r'\1', text) + text = text.strip() + + # return the text + return text + + def _format_text(self, text): + text_width = self._width - self._current_indent + indent = ' ' * self._current_indent + return self._fill_text(text, text_width, indent) + '\n\n' + + def _format_action(self, action): + # determine the required width and the entry label + help_position = min(self._action_max_length + 2, + self._max_help_position) + help_width = self._width - help_position + action_width = help_position - self._current_indent - 2 + action_header = self._format_action_invocation(action) + + # ho nelp; start on same line and add a final newline + if not action.help: + tup = self._current_indent, '', action_header + action_header = '%*s%s\n' % tup + + # short action name; start on the same line and pad two spaces + elif len(action_header) <= action_width: + tup = self._current_indent, '', action_width, action_header + action_header = '%*s%-*s ' % tup + indent_first = 0 + + # long action name; start on the next line + else: + tup = self._current_indent, '', action_header + action_header = '%*s%s\n' % tup + indent_first = help_position + + # collect the pieces of the action help + parts = [action_header] + + # if there was help for the action, add lines of help text + if action.help: + help_text = self._expand_help(action) + help_lines = self._split_lines(help_text, help_width) + parts.append('%*s%s\n' % (indent_first, '', help_lines[0])) + for line in help_lines[1:]: + parts.append('%*s%s\n' % (help_position, '', line)) + + # or add a newline if the description doesn't end with one + elif not action_header.endswith('\n'): + parts.append('\n') + + # if there are any sub-actions, add their help as well + for subaction in self._iter_indented_subactions(action): + parts.append(self._format_action(subaction)) + + # return a single string + return self._join_parts(parts) + + def _format_action_invocation(self, action): + if not action.option_strings: + metavar, = self._metavar_formatter(action, action.dest)(1) + return metavar + + else: + parts = [] + + # if the Optional doesn't take a value, format is: + # -s, --long + if action.nargs == 0: + parts.extend(action.option_strings) + + # if the Optional takes a value, format is: + # -s ARGS, --long ARGS + else: + default = action.dest.upper() + args_string = self._format_args(action, default) + for option_string in action.option_strings: + parts.append('%s %s' % (option_string, args_string)) + + return ', '.join(parts) + + def _metavar_formatter(self, action, default_metavar): + if action.metavar is not None: + result = action.metavar + elif action.choices is not None: + choice_strs = [str(choice) for choice in action.choices] + result = '{%s}' % ','.join(choice_strs) + else: + result = default_metavar + + def format(tuple_size): + if isinstance(result, tuple): + return result + else: + return (result, ) * tuple_size + return format + + def _format_args(self, action, default_metavar): + get_metavar = self._metavar_formatter(action, default_metavar) + if action.nargs is None: + result = '%s' % get_metavar(1) + elif action.nargs == OPTIONAL: + result = '[%s]' % get_metavar(1) + elif action.nargs == ZERO_OR_MORE: + result = '[%s [%s ...]]' % get_metavar(2) + elif action.nargs == ONE_OR_MORE: + result = '%s [%s ...]' % get_metavar(2) + elif action.nargs is PARSER: + result = '%s ...' % get_metavar(1) + else: + formats = ['%s' for _ in range(action.nargs)] + result = ' '.join(formats) % get_metavar(action.nargs) + return result + + def _expand_help(self, action): + params = dict(vars(action), prog=self._prog) + for name in list(params): + if params[name] is SUPPRESS: + del params[name] + if params.get('choices') is not None: + choices_str = ', '.join([str(c) for c in params['choices']]) + params['choices'] = choices_str + return self._get_help_string(action) % params + + def _iter_indented_subactions(self, action): + try: + get_subactions = action._get_subactions + except AttributeError: + pass + else: + self._indent() + for subaction in get_subactions(): + yield subaction + self._dedent() + + def _split_lines(self, text, width): + text = self._whitespace_matcher.sub(' ', text).strip() + return _textwrap.wrap(text, width) + + def _fill_text(self, text, width, indent): + text = self._whitespace_matcher.sub(' ', text).strip() + return _textwrap.fill(text, width, initial_indent=indent, + subsequent_indent=indent) + + def _get_help_string(self, action): + return action.help + + +class RawDescriptionHelpFormatter(HelpFormatter): + """Help message formatter which retains any formatting in descriptions. + + Only the name of this class is considered a public API. All the methods + provided by the class are considered an implementation detail. + """ + + def _fill_text(self, text, width, indent): + return ''.join([indent + line for line in text.splitlines(True)]) + + +class RawTextHelpFormatter(RawDescriptionHelpFormatter): + """Help message formatter which retains formatting of all help text. + + Only the name of this class is considered a public API. All the methods + provided by the class are considered an implementation detail. + """ + + def _split_lines(self, text, width): + return text.splitlines() + + +class ArgumentDefaultsHelpFormatter(HelpFormatter): + """Help message formatter which adds default values to argument help. + + Only the name of this class is considered a public API. All the methods + provided by the class are considered an implementation detail. + """ + + def _get_help_string(self, action): + help = action.help + if '%(default)' not in action.help: + if action.default is not SUPPRESS: + defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] + if action.option_strings or action.nargs in defaulting_nargs: + help += ' (default: %(default)s)' + return help + + +# ===================== +# Options and Arguments +# ===================== + +def _get_action_name(argument): + if argument is None: + return None + elif argument.option_strings: + return '/'.join(argument.option_strings) + elif argument.metavar not in (None, SUPPRESS): + return argument.metavar + elif argument.dest not in (None, SUPPRESS): + return argument.dest + else: + return None + + +class ArgumentError(Exception): + """An error from creating or using an argument (optional or positional). + + The string value of this exception is the message, augmented with + information about the argument that caused it. + """ + + def __init__(self, argument, message): + self.argument_name = _get_action_name(argument) + self.message = message + + def __str__(self): + if self.argument_name is None: + format = '%(message)s' + else: + format = 'argument %(argument_name)s: %(message)s' + return format % dict(message=self.message, + argument_name=self.argument_name) + +# ============== +# Action classes +# ============== + +class Action(_AttributeHolder): + """Information about how to convert command line strings to Python objects. + + Action objects are used by an ArgumentParser to represent the information + needed to parse a single argument from one or more strings from the + command line. The keyword arguments to the Action constructor are also + all attributes of Action instances. + + Keyword Arguments: + + - option_strings -- A list of command-line option strings which + should be associated with this action. + + - dest -- The name of the attribute to hold the created object(s) + + - nargs -- The number of command-line arguments that should be + consumed. By default, one argument will be consumed and a single + value will be produced. Other values include: + - N (an integer) consumes N arguments (and produces a list) + - '?' consumes zero or one arguments + - '*' consumes zero or more arguments (and produces a list) + - '+' consumes one or more arguments (and produces a list) + Note that the difference between the default and nargs=1 is that + with the default, a single value will be produced, while with + nargs=1, a list containing a single value will be produced. + + - const -- The value to be produced if the option is specified and the + option uses an action that takes no values. + + - default -- The value to be produced if the option is not specified. + + - type -- The type which the command-line arguments should be converted + to, should be one of 'string', 'int', 'float', 'complex' or a + callable object that accepts a single string argument. If None, + 'string' is assumed. + + - choices -- A container of values that should be allowed. If not None, + after a command-line argument has been converted to the appropriate + type, an exception will be raised if it is not a member of this + collection. + + - required -- True if the action must always be specified at the + command line. This is only meaningful for optional command-line + arguments. + + - help -- The help string describing the argument. + + - metavar -- The name to be used for the option's argument with the + help string. If None, the 'dest' value will be used as the name. + """ + + def __init__(self, + option_strings, + dest, + nargs=None, + const=None, + default=None, + type=None, + choices=None, + required=False, + help=None, + metavar=None): + self.option_strings = option_strings + self.dest = dest + self.nargs = nargs + self.const = const + self.default = default + self.type = type + self.choices = choices + self.required = required + self.help = help + self.metavar = metavar + + def _get_kwargs(self): + names = [ + 'option_strings', + 'dest', + 'nargs', + 'const', + 'default', + 'type', + 'choices', + 'help', + 'metavar', + ] + return [(name, getattr(self, name)) for name in names] + + def __call__(self, parser, namespace, values, option_string=None): + raise NotImplementedError(_('.__call__() not defined')) + + +class _StoreAction(Action): + + def __init__(self, + option_strings, + dest, + nargs=None, + const=None, + default=None, + type=None, + choices=None, + required=False, + help=None, + metavar=None): + if nargs == 0: + raise ValueError('nargs for store actions must be > 0; if you ' + 'have nothing to store, actions such as store ' + 'true or store const may be more appropriate') + if const is not None and nargs != OPTIONAL: + raise ValueError('nargs must be %r to supply const' % OPTIONAL) + super(_StoreAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=nargs, + const=const, + default=default, + type=type, + choices=choices, + required=required, + help=help, + metavar=metavar) + + def __call__(self, parser, namespace, values, option_string=None): + setattr(namespace, self.dest, values) + + +class _StoreConstAction(Action): + + def __init__(self, + option_strings, + dest, + const, + default=None, + required=False, + help=None, + metavar=None): + super(_StoreConstAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=0, + const=const, + default=default, + required=required, + help=help) + + def __call__(self, parser, namespace, values, option_string=None): + setattr(namespace, self.dest, self.const) + + +class _StoreTrueAction(_StoreConstAction): + + def __init__(self, + option_strings, + dest, + default=False, + required=False, + help=None): + super(_StoreTrueAction, self).__init__( + option_strings=option_strings, + dest=dest, + const=True, + default=default, + required=required, + help=help) + + +class _StoreFalseAction(_StoreConstAction): + + def __init__(self, + option_strings, + dest, + default=True, + required=False, + help=None): + super(_StoreFalseAction, self).__init__( + option_strings=option_strings, + dest=dest, + const=False, + default=default, + required=required, + help=help) + + +class _AppendAction(Action): + + def __init__(self, + option_strings, + dest, + nargs=None, + const=None, + default=None, + type=None, + choices=None, + required=False, + help=None, + metavar=None): + if nargs == 0: + raise ValueError('nargs for append actions must be > 0; if arg ' + 'strings are not supplying the value to append, ' + 'the append const action may be more appropriate') + if const is not None and nargs != OPTIONAL: + raise ValueError('nargs must be %r to supply const' % OPTIONAL) + super(_AppendAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=nargs, + const=const, + default=default, + type=type, + choices=choices, + required=required, + help=help, + metavar=metavar) + + def __call__(self, parser, namespace, values, option_string=None): + items = _copy.copy(_ensure_value(namespace, self.dest, [])) + items.append(values) + setattr(namespace, self.dest, items) + + +class _AppendConstAction(Action): + + def __init__(self, + option_strings, + dest, + const, + default=None, + required=False, + help=None, + metavar=None): + super(_AppendConstAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=0, + const=const, + default=default, + required=required, + help=help, + metavar=metavar) + + def __call__(self, parser, namespace, values, option_string=None): + items = _copy.copy(_ensure_value(namespace, self.dest, [])) + items.append(self.const) + setattr(namespace, self.dest, items) + + +class _CountAction(Action): + + def __init__(self, + option_strings, + dest, + default=None, + required=False, + help=None): + super(_CountAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=0, + default=default, + required=required, + help=help) + + def __call__(self, parser, namespace, values, option_string=None): + new_count = _ensure_value(namespace, self.dest, 0) + 1 + setattr(namespace, self.dest, new_count) + + +class _HelpAction(Action): + + def __init__(self, + option_strings, + dest=SUPPRESS, + default=SUPPRESS, + help=None): + super(_HelpAction, self).__init__( + option_strings=option_strings, + dest=dest, + default=default, + nargs=0, + help=help) + + def __call__(self, parser, namespace, values, option_string=None): + parser.print_help() + parser.exit() + + +class _VersionAction(Action): + + def __init__(self, + option_strings, + dest=SUPPRESS, + default=SUPPRESS, + help=None): + super(_VersionAction, self).__init__( + option_strings=option_strings, + dest=dest, + default=default, + nargs=0, + help=help) + + def __call__(self, parser, namespace, values, option_string=None): + parser.print_version() + parser.exit() + + +class _SubParsersAction(Action): + + class _ChoicesPseudoAction(Action): + + def __init__(self, name, help): + sup = super(_SubParsersAction._ChoicesPseudoAction, self) + sup.__init__(option_strings=[], dest=name, help=help) + + def __init__(self, + option_strings, + prog, + parser_class, + dest=SUPPRESS, + help=None, + metavar=None): + + self._prog_prefix = prog + self._parser_class = parser_class + self._name_parser_map = {} + self._choices_actions = [] + + super(_SubParsersAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=PARSER, + choices=self._name_parser_map, + help=help, + metavar=metavar) + + def add_parser(self, name, **kwargs): + # set prog from the existing prefix + if kwargs.get('prog') is None: + kwargs['prog'] = '%s %s' % (self._prog_prefix, name) + + # create a pseudo-action to hold the choice help + if 'help' in kwargs: + help = kwargs.pop('help') + choice_action = self._ChoicesPseudoAction(name, help) + self._choices_actions.append(choice_action) + + # create the parser and add it to the map + parser = self._parser_class(**kwargs) + self._name_parser_map[name] = parser + return parser + + def _get_subactions(self): + return self._choices_actions + + def __call__(self, parser, namespace, values, option_string=None): + parser_name = values[0] + arg_strings = values[1:] + + # set the parser name if requested + if self.dest is not SUPPRESS: + setattr(namespace, self.dest, parser_name) + + # select the parser + try: + parser = self._name_parser_map[parser_name] + except KeyError: + tup = parser_name, ', '.join(self._name_parser_map) + msg = _('unknown parser %r (choices: %s)' % tup) + raise ArgumentError(self, msg) + + # parse all the remaining options into the namespace + parser.parse_args(arg_strings, namespace) + + +# ============== +# Type classes +# ============== + +class FileType(object): + """Factory for creating file object types + + Instances of FileType are typically passed as type= arguments to the + ArgumentParser add_argument() method. + + Keyword Arguments: + - mode -- A string indicating how the file is to be opened. Accepts the + same values as the builtin open() function. + - bufsize -- The file's desired buffer size. Accepts the same values as + the builtin open() function. + """ + + def __init__(self, mode='r', bufsize=None): + self._mode = mode + self._bufsize = bufsize + + def __call__(self, string): + # the special argument "-" means sys.std{in,out} + if string == '-': + if 'r' in self._mode: + return _sys.stdin + elif 'w' in self._mode: + return _sys.stdout + else: + msg = _('argument "-" with mode %r' % self._mode) + raise ValueError(msg) + + # all other arguments are used as file names + if self._bufsize: + return open(string, self._mode, self._bufsize) + else: + return open(string, self._mode) + + def __repr__(self): + args = [self._mode, self._bufsize] + args_str = ', '.join([repr(arg) for arg in args if arg is not None]) + return '%s(%s)' % (type(self).__name__, args_str) + +# =========================== +# Optional and Positional Parsing +# =========================== + +class Namespace(_AttributeHolder): + """Simple object for storing attributes. + + Implements equality by attribute names and values, and provides a simple + string representation. + """ + + def __init__(self, **kwargs): + for name in kwargs: + setattr(self, name, kwargs[name]) + + def __eq__(self, other): + return vars(self) == vars(other) + + def __ne__(self, other): + return not (self == other) + + +class _ActionsContainer(object): + + def __init__(self, + description, + prefix_chars, + argument_default, + conflict_handler): + super(_ActionsContainer, self).__init__() + + self.description = description + self.argument_default = argument_default + self.prefix_chars = prefix_chars + self.conflict_handler = conflict_handler + + # set up registries + self._registries = {} + + # register actions + self.register('action', None, _StoreAction) + self.register('action', 'store', _StoreAction) + self.register('action', 'store_const', _StoreConstAction) + self.register('action', 'store_true', _StoreTrueAction) + self.register('action', 'store_false', _StoreFalseAction) + self.register('action', 'append', _AppendAction) + self.register('action', 'append_const', _AppendConstAction) + self.register('action', 'count', _CountAction) + self.register('action', 'help', _HelpAction) + self.register('action', 'version', _VersionAction) + self.register('action', 'parsers', _SubParsersAction) + + # raise an exception if the conflict handler is invalid + self._get_handler() + + # action storage + self._actions = [] + self._option_string_actions = {} + + # groups + self._action_groups = [] + self._mutually_exclusive_groups = [] + + # defaults storage + self._defaults = {} + + # determines whether an "option" looks like a negative number + self._negative_number_matcher = _re.compile(r'^-\d+|-\d*.\d+$') + + # whether or not there are any optionals that look like negative + # numbers -- uses a list so it can be shared and edited + self._has_negative_number_optionals = [] + + # ==================== + # Registration methods + # ==================== + def register(self, registry_name, value, object): + registry = self._registries.setdefault(registry_name, {}) + registry[value] = object + + def _registry_get(self, registry_name, value, default=None): + return self._registries[registry_name].get(value, default) + + # ================================== + # Namespace default settings methods + # ================================== + def set_defaults(self, **kwargs): + self._defaults.update(kwargs) + + # if these defaults match any existing arguments, replace + # the previous default on the object with the new one + for action in self._actions: + if action.dest in kwargs: + action.default = kwargs[action.dest] + + # ======================= + # Adding argument actions + # ======================= + def add_argument(self, *args, **kwargs): + """ + add_argument(dest, ..., name=value, ...) + add_argument(option_string, option_string, ..., name=value, ...) + """ + + # if no positional args are supplied or only one is supplied and + # it doesn't look like an option string, parse a positional + # argument + chars = self.prefix_chars + if not args or len(args) == 1 and args[0][0] not in chars: + kwargs = self._get_positional_kwargs(*args, **kwargs) + + # otherwise, we're adding an optional argument + else: + kwargs = self._get_optional_kwargs(*args, **kwargs) + + # if no default was supplied, use the parser-level default + if 'default' not in kwargs: + dest = kwargs['dest'] + if dest in self._defaults: + kwargs['default'] = self._defaults[dest] + elif self.argument_default is not None: + kwargs['default'] = self.argument_default + + # create the action object, and add it to the parser + action_class = self._pop_action_class(kwargs) + action = action_class(**kwargs) + return self._add_action(action) + + def add_argument_group(self, *args, **kwargs): + group = _ArgumentGroup(self, *args, **kwargs) + self._action_groups.append(group) + return group + + def add_mutually_exclusive_group(self, **kwargs): + group = _MutuallyExclusiveGroup(self, **kwargs) + self._mutually_exclusive_groups.append(group) + return group + + def _add_action(self, action): + # resolve any conflicts + self._check_conflict(action) + + # add to actions list + self._actions.append(action) + action.container = self + + # index the action by any option strings it has + for option_string in action.option_strings: + self._option_string_actions[option_string] = action + + # set the flag if any option strings look like negative numbers + for option_string in action.option_strings: + if self._negative_number_matcher.match(option_string): + if not self._has_negative_number_optionals: + self._has_negative_number_optionals.append(True) + + # return the created action + return action + + def _remove_action(self, action): + self._actions.remove(action) + + def _add_container_actions(self, container): + # collect groups by titles + title_group_map = {} + for group in self._action_groups: + if group.title in title_group_map: + msg = _('cannot merge actions - two groups are named %r') + raise ValueError(msg % (group.title)) + title_group_map[group.title] = group + + # map each action to its group + group_map = {} + for group in container._action_groups: + + # if a group with the title exists, use that, otherwise + # create a new group matching the container's group + if group.title not in title_group_map: + title_group_map[group.title] = self.add_argument_group( + title=group.title, + description=group.description, + conflict_handler=group.conflict_handler) + + # map the actions to their new group + for action in group._group_actions: + group_map[action] = title_group_map[group.title] + + # add container's mutually exclusive groups + # NOTE: if add_mutually_exclusive_group ever gains title= and + # description= then this code will need to be expanded as above + for group in container._mutually_exclusive_groups: + mutex_group = self.add_mutually_exclusive_group( + required=group.required) + + # map the actions to their new mutex group + for action in group._group_actions: + group_map[action] = mutex_group + + # add all actions to this container or their group + for action in container._actions: + group_map.get(action, self)._add_action(action) + + def _get_positional_kwargs(self, dest, **kwargs): + # make sure required is not specified + if 'required' in kwargs: + msg = _("'required' is an invalid argument for positionals") + raise TypeError(msg) + + # mark positional arguments as required if at least one is + # always required + if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]: + kwargs['required'] = True + if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs: + kwargs['required'] = True + + # return the keyword arguments with no option strings + return dict(kwargs, dest=dest, option_strings=[]) + + def _get_optional_kwargs(self, *args, **kwargs): + # determine short and long option strings + option_strings = [] + long_option_strings = [] + for option_string in args: + # error on one-or-fewer-character option strings + if len(option_string) < 2: + msg = _('invalid option string %r: ' + 'must be at least two characters long') + raise ValueError(msg % option_string) + + # error on strings that don't start with an appropriate prefix + if not option_string[0] in self.prefix_chars: + msg = _('invalid option string %r: ' + 'must start with a character %r') + tup = option_string, self.prefix_chars + raise ValueError(msg % tup) + + # error on strings that are all prefix characters + if not (_set(option_string) - _set(self.prefix_chars)): + msg = _('invalid option string %r: ' + 'must contain characters other than %r') + tup = option_string, self.prefix_chars + raise ValueError(msg % tup) + + # strings starting with two prefix characters are long options + option_strings.append(option_string) + if option_string[0] in self.prefix_chars: + if option_string[1] in self.prefix_chars: + long_option_strings.append(option_string) + + # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x' + dest = kwargs.pop('dest', None) + if dest is None: + if long_option_strings: + dest_option_string = long_option_strings[0] + else: + dest_option_string = option_strings[0] + dest = dest_option_string.lstrip(self.prefix_chars) + dest = dest.replace('-', '_') + + # return the updated keyword arguments + return dict(kwargs, dest=dest, option_strings=option_strings) + + def _pop_action_class(self, kwargs, default=None): + action = kwargs.pop('action', default) + return self._registry_get('action', action, action) + + def _get_handler(self): + # determine function from conflict handler string + handler_func_name = '_handle_conflict_%s' % self.conflict_handler + try: + return getattr(self, handler_func_name) + except AttributeError: + msg = _('invalid conflict_resolution value: %r') + raise ValueError(msg % self.conflict_handler) + + def _check_conflict(self, action): + + # find all options that conflict with this option + confl_optionals = [] + for option_string in action.option_strings: + if option_string in self._option_string_actions: + confl_optional = self._option_string_actions[option_string] + confl_optionals.append((option_string, confl_optional)) + + # resolve any conflicts + if confl_optionals: + conflict_handler = self._get_handler() + conflict_handler(action, confl_optionals) + + def _handle_conflict_error(self, action, conflicting_actions): + message = _('conflicting option string(s): %s') + conflict_string = ', '.join([option_string + for option_string, action + in conflicting_actions]) + raise ArgumentError(action, message % conflict_string) + + def _handle_conflict_resolve(self, action, conflicting_actions): + + # remove all conflicting options + for option_string, action in conflicting_actions: + + # remove the conflicting option + action.option_strings.remove(option_string) + self._option_string_actions.pop(option_string, None) + + # if the option now has no option string, remove it from the + # container holding it + if not action.option_strings: + action.container._remove_action(action) + + +class _ArgumentGroup(_ActionsContainer): + + def __init__(self, container, title=None, description=None, **kwargs): + # add any missing keyword arguments by checking the container + update = kwargs.setdefault + update('conflict_handler', container.conflict_handler) + update('prefix_chars', container.prefix_chars) + update('argument_default', container.argument_default) + super_init = super(_ArgumentGroup, self).__init__ + super_init(description=description, **kwargs) + + # group attributes + self.title = title + self._group_actions = [] + + # share most attributes with the container + self._registries = container._registries + self._actions = container._actions + self._option_string_actions = container._option_string_actions + self._defaults = container._defaults + self._has_negative_number_optionals = \ + container._has_negative_number_optionals + + def _add_action(self, action): + action = super(_ArgumentGroup, self)._add_action(action) + self._group_actions.append(action) + return action + + def _remove_action(self, action): + super(_ArgumentGroup, self)._remove_action(action) + self._group_actions.remove(action) + + +class _MutuallyExclusiveGroup(_ArgumentGroup): + + def __init__(self, container, required=False): + super(_MutuallyExclusiveGroup, self).__init__(container) + self.required = required + self._container = container + + def _add_action(self, action): + if action.required: + msg = _('mutually exclusive arguments must be optional') + raise ValueError(msg) + action = self._container._add_action(action) + self._group_actions.append(action) + return action + + def _remove_action(self, action): + self._container._remove_action(action) + self._group_actions.remove(action) + + +class ArgumentParser(_AttributeHolder, _ActionsContainer): + """Object for parsing command line strings into Python objects. + + Keyword Arguments: + - prog -- The name of the program (default: sys.argv[0]) + - usage -- A usage message (default: auto-generated from arguments) + - description -- A description of what the program does + - epilog -- Text following the argument descriptions + - version -- Add a -v/--version option with the given version string + - parents -- Parsers whose arguments should be copied into this one + - formatter_class -- HelpFormatter class for printing help messages + - prefix_chars -- Characters that prefix optional arguments + - fromfile_prefix_chars -- Characters that prefix files containing + additional arguments + - argument_default -- The default value for all arguments + - conflict_handler -- String indicating how to handle conflicts + - add_help -- Add a -h/-help option + """ + + def __init__(self, + prog=None, + usage=None, + description=None, + epilog=None, + version=None, + parents=[], + formatter_class=HelpFormatter, + prefix_chars='-', + fromfile_prefix_chars=None, + argument_default=None, + conflict_handler='error', + add_help=True): + + superinit = super(ArgumentParser, self).__init__ + superinit(description=description, + prefix_chars=prefix_chars, + argument_default=argument_default, + conflict_handler=conflict_handler) + + # default setting for prog + if prog is None: + prog = _os.path.basename(_sys.argv[0]) + + self.prog = prog + self.usage = usage + self.epilog = epilog + self.version = version + self.formatter_class = formatter_class + self.fromfile_prefix_chars = fromfile_prefix_chars + self.add_help = add_help + + add_group = self.add_argument_group + self._positionals = add_group(_('positional arguments')) + self._optionals = add_group(_('optional arguments')) + self._subparsers = None + + # register types + def identity(string): + return string + self.register('type', None, identity) + + # add help and version arguments if necessary + # (using explicit default to override global argument_default) + if self.add_help: + self.add_argument( + '-h', '--help', action='help', default=SUPPRESS, + help=_('show this help message and exit')) + if self.version: + self.add_argument( + '-v', '--version', action='version', default=SUPPRESS, + help=_("show program's version number and exit")) + + # add parent arguments and defaults + for parent in parents: + self._add_container_actions(parent) + try: + defaults = parent._defaults + except AttributeError: + pass + else: + self._defaults.update(defaults) + + # ======================= + # Pretty __repr__ methods + # ======================= + def _get_kwargs(self): + names = [ + 'prog', + 'usage', + 'description', + 'version', + 'formatter_class', + 'conflict_handler', + 'add_help', + ] + return [(name, getattr(self, name)) for name in names] + + # ================================== + # Optional/Positional adding methods + # ================================== + def add_subparsers(self, **kwargs): + if self._subparsers is not None: + self.error(_('cannot have multiple subparser arguments')) + + # add the parser class to the arguments if it's not present + kwargs.setdefault('parser_class', type(self)) + + if 'title' in kwargs or 'description' in kwargs: + title = _(kwargs.pop('title', 'subcommands')) + description = _(kwargs.pop('description', None)) + self._subparsers = self.add_argument_group(title, description) + else: + self._subparsers = self._positionals + + # prog defaults to the usage message of this parser, skipping + # optional arguments and with no "usage:" prefix + if kwargs.get('prog') is None: + formatter = self._get_formatter() + positionals = self._get_positional_actions() + groups = self._mutually_exclusive_groups + formatter.add_usage(self.usage, positionals, groups, '') + kwargs['prog'] = formatter.format_help().strip() + + # create the parsers action and add it to the positionals list + parsers_class = self._pop_action_class(kwargs, 'parsers') + action = parsers_class(option_strings=[], **kwargs) + self._subparsers._add_action(action) + + # return the created parsers action + return action + + def _add_action(self, action): + if action.option_strings: + self._optionals._add_action(action) + else: + self._positionals._add_action(action) + return action + + def _get_optional_actions(self): + return [action + for action in self._actions + if action.option_strings] + + def _get_positional_actions(self): + return [action + for action in self._actions + if not action.option_strings] + + # ===================================== + # Command line argument parsing methods + # ===================================== + def parse_args(self, args=None, namespace=None): + args, argv = self.parse_known_args(args, namespace) + if argv: + msg = _('unrecognized arguments: %s') + self.error(msg % ' '.join(argv)) + return args + + def parse_known_args(self, args=None, namespace=None): + # args default to the system args + if args is None: + args = _sys.argv[1:] + + # default Namespace built from parser defaults + if namespace is None: + namespace = Namespace() + + # add any action defaults that aren't present + for action in self._actions: + if action.dest is not SUPPRESS: + if not hasattr(namespace, action.dest): + if action.default is not SUPPRESS: + default = action.default + if isinstance(action.default, _basestring): + default = self._get_value(action, default) + setattr(namespace, action.dest, default) + + # add any parser defaults that aren't present + for dest in self._defaults: + if not hasattr(namespace, dest): + setattr(namespace, dest, self._defaults[dest]) + + # parse the arguments and exit if there are any errors + try: + return self._parse_known_args(args, namespace) + except ArgumentError: + err = _sys.exc_info()[1] + self.error(str(err)) + + def _parse_known_args(self, arg_strings, namespace): + # replace arg strings that are file references + if self.fromfile_prefix_chars is not None: + arg_strings = self._read_args_from_files(arg_strings) + + # map all mutually exclusive arguments to the other arguments + # they can't occur with + action_conflicts = {} + for mutex_group in self._mutually_exclusive_groups: + group_actions = mutex_group._group_actions + for i, mutex_action in enumerate(mutex_group._group_actions): + conflicts = action_conflicts.setdefault(mutex_action, []) + conflicts.extend(group_actions[:i]) + conflicts.extend(group_actions[i + 1:]) + + # find all option indices, and determine the arg_string_pattern + # which has an 'O' if there is an option at an index, + # an 'A' if there is an argument, or a '-' if there is a '--' + option_string_indices = {} + arg_string_pattern_parts = [] + arg_strings_iter = iter(arg_strings) + for i, arg_string in enumerate(arg_strings_iter): + + # all args after -- are non-options + if arg_string == '--': + arg_string_pattern_parts.append('-') + for arg_string in arg_strings_iter: + arg_string_pattern_parts.append('A') + + # otherwise, add the arg to the arg strings + # and note the index if it was an option + else: + option_tuple = self._parse_optional(arg_string) + if option_tuple is None: + pattern = 'A' + else: + option_string_indices[i] = option_tuple + pattern = 'O' + arg_string_pattern_parts.append(pattern) + + # join the pieces together to form the pattern + arg_strings_pattern = ''.join(arg_string_pattern_parts) + + # converts arg strings to the appropriate and then takes the action + seen_actions = _set() + seen_non_default_actions = _set() + + def take_action(action, argument_strings, option_string=None): + seen_actions.add(action) + argument_values = self._get_values(action, argument_strings) + + # error if this argument is not allowed with other previously + # seen arguments, assuming that actions that use the default + # value don't really count as "present" + if argument_values is not action.default: + seen_non_default_actions.add(action) + for conflict_action in action_conflicts.get(action, []): + if conflict_action in seen_non_default_actions: + msg = _('not allowed with argument %s') + action_name = _get_action_name(conflict_action) + raise ArgumentError(action, msg % action_name) + + # take the action if we didn't receive a SUPPRESS value + # (e.g. from a default) + if argument_values is not SUPPRESS: + action(self, namespace, argument_values, option_string) + + # function to convert arg_strings into an optional action + def consume_optional(start_index): + + # get the optional identified at this index + option_tuple = option_string_indices[start_index] + action, option_string, explicit_arg = option_tuple + + # identify additional optionals in the same arg string + # (e.g. -xyz is the same as -x -y -z if no args are required) + match_argument = self._match_argument + action_tuples = [] + while True: + + # if we found no optional action, skip it + if action is None: + extras.append(arg_strings[start_index]) + return start_index + 1 + + # if there is an explicit argument, try to match the + # optional's string arguments to only this + if explicit_arg is not None: + arg_count = match_argument(action, 'A') + + # if the action is a single-dash option and takes no + # arguments, try to parse more single-dash options out + # of the tail of the option string + chars = self.prefix_chars + if arg_count == 0 and option_string[1] not in chars: + action_tuples.append((action, [], option_string)) + for char in self.prefix_chars: + option_string = char + explicit_arg[0] + explicit_arg = explicit_arg[1:] or None + optionals_map = self._option_string_actions + if option_string in optionals_map: + action = optionals_map[option_string] + break + else: + msg = _('ignored explicit argument %r') + raise ArgumentError(action, msg % explicit_arg) + + # if the action expect exactly one argument, we've + # successfully matched the option; exit the loop + elif arg_count == 1: + stop = start_index + 1 + args = [explicit_arg] + action_tuples.append((action, args, option_string)) + break + + # error if a double-dash option did not use the + # explicit argument + else: + msg = _('ignored explicit argument %r') + raise ArgumentError(action, msg % explicit_arg) + + # if there is no explicit argument, try to match the + # optional's string arguments with the following strings + # if successful, exit the loop + else: + start = start_index + 1 + selected_patterns = arg_strings_pattern[start:] + arg_count = match_argument(action, selected_patterns) + stop = start + arg_count + args = arg_strings[start:stop] + action_tuples.append((action, args, option_string)) + break + + # add the Optional to the list and return the index at which + # the Optional's string args stopped + assert action_tuples + for action, args, option_string in action_tuples: + take_action(action, args, option_string) + return stop + + # the list of Positionals left to be parsed; this is modified + # by consume_positionals() + positionals = self._get_positional_actions() + + # function to convert arg_strings into positional actions + def consume_positionals(start_index): + # match as many Positionals as possible + match_partial = self._match_arguments_partial + selected_pattern = arg_strings_pattern[start_index:] + arg_counts = match_partial(positionals, selected_pattern) + + # slice off the appropriate arg strings for each Positional + # and add the Positional and its args to the list + for action, arg_count in zip(positionals, arg_counts): + args = arg_strings[start_index: start_index + arg_count] + start_index += arg_count + take_action(action, args) + + # slice off the Positionals that we just parsed and return the + # index at which the Positionals' string args stopped + positionals[:] = positionals[len(arg_counts):] + return start_index + + # consume Positionals and Optionals alternately, until we have + # passed the last option string + extras = [] + start_index = 0 + if option_string_indices: + max_option_string_index = max(option_string_indices) + else: + max_option_string_index = -1 + while start_index <= max_option_string_index: + + # consume any Positionals preceding the next option + next_option_string_index = min([ + index + for index in option_string_indices + if index >= start_index]) + if start_index != next_option_string_index: + positionals_end_index = consume_positionals(start_index) + + # only try to parse the next optional if we didn't consume + # the option string during the positionals parsing + if positionals_end_index > start_index: + start_index = positionals_end_index + continue + else: + start_index = positionals_end_index + + # if we consumed all the positionals we could and we're not + # at the index of an option string, there were extra arguments + if start_index not in option_string_indices: + strings = arg_strings[start_index:next_option_string_index] + extras.extend(strings) + start_index = next_option_string_index + + # consume the next optional and any arguments for it + start_index = consume_optional(start_index) + + # consume any positionals following the last Optional + stop_index = consume_positionals(start_index) + + # if we didn't consume all the argument strings, there were extras + extras.extend(arg_strings[stop_index:]) + + # if we didn't use all the Positional objects, there were too few + # arg strings supplied. + if positionals: + self.error(_('too few arguments')) + + # make sure all required actions were present + for action in self._actions: + if action.required: + if action not in seen_actions: + name = _get_action_name(action) + self.error(_('argument %s is required') % name) + + # make sure all required groups had one option present + for group in self._mutually_exclusive_groups: + if group.required: + for action in group._group_actions: + if action in seen_non_default_actions: + break + + # if no actions were used, report the error + else: + names = [_get_action_name(action) + for action in group._group_actions + if action.help is not SUPPRESS] + msg = _('one of the arguments %s is required') + self.error(msg % ' '.join(names)) + + # return the updated namespace and the extra arguments + return namespace, extras + + def _read_args_from_files(self, arg_strings): + # expand arguments referencing files + new_arg_strings = [] + for arg_string in arg_strings: + + # for regular arguments, just add them back into the list + if arg_string[0] not in self.fromfile_prefix_chars: + new_arg_strings.append(arg_string) + + # replace arguments referencing files with the file content + else: + try: + args_file = open(arg_string[1:]) + try: + arg_strings = args_file.read().splitlines() + arg_strings = self._read_args_from_files(arg_strings) + new_arg_strings.extend(arg_strings) + finally: + args_file.close() + except IOError: + err = _sys.exc_info()[1] + self.error(str(err)) + + # return the modified argument list + return new_arg_strings + + def _match_argument(self, action, arg_strings_pattern): + # match the pattern for this action to the arg strings + nargs_pattern = self._get_nargs_pattern(action) + match = _re.match(nargs_pattern, arg_strings_pattern) + + # raise an exception if we weren't able to find a match + if match is None: + nargs_errors = { + None: _('expected one argument'), + OPTIONAL: _('expected at most one argument'), + ONE_OR_MORE: _('expected at least one argument'), + } + default = _('expected %s argument(s)') % action.nargs + msg = nargs_errors.get(action.nargs, default) + raise ArgumentError(action, msg) + + # return the number of arguments matched + return len(match.group(1)) + + def _match_arguments_partial(self, actions, arg_strings_pattern): + # progressively shorten the actions list by slicing off the + # final actions until we find a match + result = [] + for i in range(len(actions), 0, -1): + actions_slice = actions[:i] + pattern = ''.join([self._get_nargs_pattern(action) + for action in actions_slice]) + match = _re.match(pattern, arg_strings_pattern) + if match is not None: + result.extend([len(string) for string in match.groups()]) + break + + # return the list of arg string counts + return result + + def _parse_optional(self, arg_string): + # if it's an empty string, it was meant to be a positional + if not arg_string: + return None + + # if it doesn't start with a prefix, it was meant to be positional + if not arg_string[0] in self.prefix_chars: + return None + + # if it's just dashes, it was meant to be positional + if not arg_string.strip('-'): + return None + + # if the option string is present in the parser, return the action + if arg_string in self._option_string_actions: + action = self._option_string_actions[arg_string] + return action, arg_string, None + + # search through all possible prefixes of the option string + # and all actions in the parser for possible interpretations + option_tuples = self._get_option_tuples(arg_string) + + # if multiple actions match, the option string was ambiguous + if len(option_tuples) > 1: + options = ', '.join([option_string + for action, option_string, explicit_arg in option_tuples]) + tup = arg_string, options + self.error(_('ambiguous option: %s could match %s') % tup) + + # if exactly one action matched, this segmentation is good, + # so return the parsed action + elif len(option_tuples) == 1: + option_tuple, = option_tuples + return option_tuple + + # if it was not found as an option, but it looks like a negative + # number, it was meant to be positional + # unless there are negative-number-like options + if self._negative_number_matcher.match(arg_string): + if not self._has_negative_number_optionals: + return None + + # if it contains a space, it was meant to be a positional + if ' ' in arg_string: + return None + + # it was meant to be an optional but there is no such option + # in this parser (though it might be a valid option in a subparser) + return None, arg_string, None + + def _get_option_tuples(self, option_string): + result = [] + + # option strings starting with two prefix characters are only + # split at the '=' + chars = self.prefix_chars + if option_string[0] in chars and option_string[1] in chars: + if '=' in option_string: + option_prefix, explicit_arg = option_string.split('=', 1) + else: + option_prefix = option_string + explicit_arg = None + for option_string in self._option_string_actions: + if option_string.startswith(option_prefix): + action = self._option_string_actions[option_string] + tup = action, option_string, explicit_arg + result.append(tup) + + # single character options can be concatenated with their arguments + # but multiple character options always have to have their argument + # separate + elif option_string[0] in chars and option_string[1] not in chars: + option_prefix = option_string + explicit_arg = None + short_option_prefix = option_string[:2] + short_explicit_arg = option_string[2:] + + for option_string in self._option_string_actions: + if option_string == short_option_prefix: + action = self._option_string_actions[option_string] + tup = action, option_string, short_explicit_arg + result.append(tup) + elif option_string.startswith(option_prefix): + action = self._option_string_actions[option_string] + tup = action, option_string, explicit_arg + result.append(tup) + + # shouldn't ever get here + else: + self.error(_('unexpected option string: %s') % option_string) + + # return the collected option tuples + return result + + def _get_nargs_pattern(self, action): + # in all examples below, we have to allow for '--' args + # which are represented as '-' in the pattern + nargs = action.nargs + + # the default (None) is assumed to be a single argument + if nargs is None: + nargs_pattern = '(-*A-*)' + + # allow zero or one arguments + elif nargs == OPTIONAL: + nargs_pattern = '(-*A?-*)' + + # allow zero or more arguments + elif nargs == ZERO_OR_MORE: + nargs_pattern = '(-*[A-]*)' + + # allow one or more arguments + elif nargs == ONE_OR_MORE: + nargs_pattern = '(-*A[A-]*)' + + # allow one argument followed by any number of options or arguments + elif nargs is PARSER: + nargs_pattern = '(-*A[-AO]*)' + + # all others should be integers + else: + nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs) + + # if this is an optional action, -- is not allowed + if action.option_strings: + nargs_pattern = nargs_pattern.replace('-*', '') + nargs_pattern = nargs_pattern.replace('-', '') + + # return the pattern + return nargs_pattern + + # ======================== + # Value conversion methods + # ======================== + def _get_values(self, action, arg_strings): + # for everything but PARSER args, strip out '--' + if action.nargs is not PARSER: + arg_strings = [s for s in arg_strings if s != '--'] + + # optional argument produces a default when not present + if not arg_strings and action.nargs == OPTIONAL: + if action.option_strings: + value = action.const + else: + value = action.default + if isinstance(value, _basestring): + value = self._get_value(action, value) + self._check_value(action, value) + + # when nargs='*' on a positional, if there were no command-line + # args, use the default if it is anything other than None + elif (not arg_strings and action.nargs == ZERO_OR_MORE and + not action.option_strings): + if action.default is not None: + value = action.default + else: + value = arg_strings + self._check_value(action, value) + + # single argument or optional argument produces a single value + elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]: + arg_string, = arg_strings + value = self._get_value(action, arg_string) + self._check_value(action, value) + + # PARSER arguments convert all values, but check only the first + elif action.nargs is PARSER: + value = [self._get_value(action, v) for v in arg_strings] + self._check_value(action, value[0]) + + # all other types of nargs produce a list + else: + value = [self._get_value(action, v) for v in arg_strings] + for v in value: + self._check_value(action, v) + + # return the converted value + return value + + def _get_value(self, action, arg_string): + type_func = self._registry_get('type', action.type, action.type) + if not hasattr(type_func, '__call__'): + if not hasattr(type_func, '__bases__'): # classic classes + msg = _('%r is not callable') + raise ArgumentError(action, msg % type_func) + + # convert the value to the appropriate type + try: + result = type_func(arg_string) + + # TypeErrors or ValueErrors indicate errors + except (TypeError, ValueError): + name = getattr(action.type, '__name__', repr(action.type)) + msg = _('invalid %s value: %r') + raise ArgumentError(action, msg % (name, arg_string)) + + # return the converted value + return result + + def _check_value(self, action, value): + # converted value must be one of the choices (if specified) + if action.choices is not None and value not in action.choices: + tup = value, ', '.join(map(repr, action.choices)) + msg = _('invalid choice: %r (choose from %s)') % tup + raise ArgumentError(action, msg) + + # ======================= + # Help-formatting methods + # ======================= + def format_usage(self): + formatter = self._get_formatter() + formatter.add_usage(self.usage, self._actions, + self._mutually_exclusive_groups) + return formatter.format_help() + + def format_help(self): + formatter = self._get_formatter() + + # usage + formatter.add_usage(self.usage, self._actions, + self._mutually_exclusive_groups) + + # description + formatter.add_text(self.description) + + # positionals, optionals and user-defined groups + for action_group in self._action_groups: + formatter.start_section(action_group.title) + formatter.add_text(action_group.description) + formatter.add_arguments(action_group._group_actions) + formatter.end_section() + + # epilog + formatter.add_text(self.epilog) + + # determine help from format above + return formatter.format_help() + + def format_version(self): + formatter = self._get_formatter() + formatter.add_text(self.version) + return formatter.format_help() + + def _get_formatter(self): + return self.formatter_class(prog=self.prog) + + # ===================== + # Help-printing methods + # ===================== + def print_usage(self, file=None): + self._print_message(self.format_usage(), file) + + def print_help(self, file=None): + self._print_message(self.format_help(), file) + + def print_version(self, file=None): + self._print_message(self.format_version(), file) + + def _print_message(self, message, file=None): + if message: + if file is None: + file = _sys.stderr + file.write(message) + + # =============== + # Exiting methods + # =============== + def exit(self, status=0, message=None): + if message: + _sys.stderr.write(message) + _sys.exit(status) + + def error(self, message): + """error(message: string) + + Prints a usage message incorporating the message to stderr and + exits. + + If you override this in a subclass, it should not return -- it + should either exit or raise an exception. + """ + self.print_usage(_sys.stderr) + self.exit(2, _('%s: error: %s\n') % (self.prog, message)) diff --git a/naoki/chroot.py b/naoki/chroot.py new file mode 100644 index 0000000..0feda24 --- /dev/null +++ b/naoki/chroot.py @@ -0,0 +1,375 @@ +#!/usr/bin/python + +import grp +import logging +import os +import random +import stat + +import package +import util +from constants import * +from exception import * +from logger import getLog + +class Environment(object): + def __init__(self, package): + self.package = package + + self.arch = arches.current + self.config = config + + self.toolchain = Toolchain(self.arch["name"]) + + # mount/umount + self.umountCmds = [ + "umount -n %s" % self.chrootPath("proc"), + "umount -n %s" % self.chrootPath("sys"), + "umount -n %s" % self.chrootPath("usr", "src", "cache"), + "umount -n %s" % self.chrootPath("usr", "src", "ccache"), + "umount -n %s" % self.chrootPath("usr", "src", "packages"), + "umount -n %s" % self.chrootPath("usr", "src", "pkgs"), + "umount -n %s" % self.chrootPath("usr", "src", "src"), + "umount -n %s" % self.chrootPath("usr", "src", "tools"), + ] + self.mountCmds = [ + "mount -n -t proc naoki_chroot_proc %s" % self.chrootPath("proc"), + "mount -n -t sysfs naoki_chroot_sysfs %s" % self.chrootPath("sys"), + "mount -n --bind %s %s" % (os.path.join(CACHEDIR), self.chrootPath("usr", "src", "cache")), + "mount -n --bind %s %s" % (os.path.join(CCACHEDIR), self.chrootPath("usr", "src", "ccache")), + "mount -n --bind %s %s" % (os.path.join(PACKAGESDIR), self.chrootPath("usr", "src", "packages")), + "mount -n --bind %s %s" % (os.path.join(PKGSDIR), self.chrootPath("usr", "src", "pkgs")), + "mount -n --bind %s %s" % (os.path.join(BASEDIR, "src"), self.chrootPath("usr", "src", "src")), + "mount -n --bind %s %s" % (os.path.join(TOOLSDIR), self.chrootPath("usr", "src", "tools")), + ] + + self.buildroot = "buildroot.%d" % random.randint(0, 1024) + self.log = None + self.__initialized = False + + def init(self): + if self.__initialized: + return + self._init() + self.__initialized = True + + def _init(self): + self._setupLogging() + + self.log.info("Setting up environment %s..." % self.chrootPath()) + + if os.path.exists(self.chrootPath()): + self.clean() + + # create dirs + dirs = ( + CACHEDIR, + PACKAGESDIR, + self.chrootPath(self.buildroot), + self.chrootPath("bin"), + self.chrootPath("etc"), + self.chrootPath("proc"), + self.chrootPath("root"), + self.chrootPath("sbin"), + self.chrootPath("sys"), + self.chrootPath("tmp"), + self.chrootPath("tools_%s" % self.arch["name"]), + self.chrootPath("usr/src/cache"), + self.chrootPath("usr/src/ccache"), + self.chrootPath("usr/src/packages"), + self.chrootPath("usr/src/pkgs"), + self.chrootPath("usr/src/src"), + self.chrootPath("usr/src/tools"), + self.chrootPath("var/tmp"), + ) + for item in dirs: + util.mkdir(item) + + # touch files + files = ( + "etc/fstab", + "etc/mtab", + ) + for item in files: + util.touch(self.chrootPath(item)) + + self._setupDev() + self._setupUsers() + + self.toolchain.extract(self.chrootPath()) + + self.extractAll() + + self.toolchain.adjust(self.chrootPath()) + + def clean(self): + util.rm(self.chrootPath()) + + def make(self, target): + file = "/usr/src%s" % self.package.filename[len(BASEDIR):] + + return self.doChroot("make -C %s -f %s %s" % \ + (os.path.dirname(file), file, target), shell=True) + + def doChroot(self, command, shell=True, *args, **kwargs): + ret = None + try: + # XXX Should be globally defined + env = config.environment.copy() + env.update({ + "HOME" : "/root", + "BASEDIR" : "/usr/src", + "PKGROOT" : "/usr/src/pkgs", + "TOOLS_DIR" : "/tools_%s" % self.arch["name"], + "TARGET" : "%s-ipfire-linux-gnu" % self.arch["machine"], + "TARGET_MACHINE" : self.arch["machine"], + "PATH" : "/sbin:/bin:/usr/sbin:/usr/bin:/tools_%(arch)s/sbin:/tools_%(arch)s/bin" \ + % { "arch" : self.arch["name"], }, + "BUILDROOT" : "/%s" % self.buildroot, + "CHROOT" : "1", + }) + + if os.path.exists(self.chrootPath("usr", "ccache")): + env.update({ + "PATH" : "/usr/ccache/bin:%s" % env["PATH"], + "CCACHE_DIR" : "/usr/src/ccache", + }) + + if kwargs.has_key("env"): + env.update(kwargs.pop("env")) + + self._mountall() + + if not kwargs.has_key("chrootPath"): + kwargs["chrootPath"] = self.chrootPath() + + ret = util.do(command, personality=self.arch["personality"], + shell=shell, env=env, logger=self.log, *args, **kwargs) + + finally: + self._umountall() + + return ret + + def chrootPath(self, *args): + return os.path.join(BUILDDIR, "environments", self.package.id, *args) + + def _setupLogging(self): + logfile = os.path.join(LOGDIR, self.package.id, "build.log") + if not os.path.exists(os.path.dirname(logfile)): + util.mkdir(os.path.dirname(logfile)) + self.log = logging.getLogger(self.package.id) + fh = logging.FileHandler(logfile) + fh.setFormatter(logging.Formatter("[%(levelname)s] %(message)s")) + fh.setLevel(logging.NOTSET) + self.log.addHandler(fh) + + def _setupDev(self): + # files in /dev + util.rm(self.chrootPath("dev")) + util.mkdir(self.chrootPath("dev", "pts")) + util.mkdir(self.chrootPath("dev", "shm")) + prevMask = os.umask(0000) + for i in ( + (stat.S_IFCHR | 0666, os.makedev(1, 3), "dev/null"), + (stat.S_IFCHR | 0666, os.makedev(1, 7), "dev/full"), + (stat.S_IFCHR | 0666, os.makedev(1, 5), "dev/zero"), + (stat.S_IFCHR | 0666, os.makedev(1, 8), "dev/random"), + (stat.S_IFCHR | 0444, os.makedev(1, 9), "dev/urandom"), + (stat.S_IFCHR | 0666, os.makedev(5, 0), "dev/tty"), + (stat.S_IFCHR | 0600, os.makedev(5, 1), "dev/console") + ): + # create node + os.mknod(self.chrootPath(i[2]), i[0], i[1]) + + os.symlink("/proc/self/fd/0", self.chrootPath("dev", "stdin")) + os.symlink("/proc/self/fd/1", self.chrootPath("dev", "stdout")) + os.symlink("/proc/self/fd/2", self.chrootPath("dev", "stderr")) + os.umask(prevMask) + + # mount/umount + for devUnmtCmd in ( + "umount -n %s" % self.chrootPath("dev", "pts"), + "umount -n %s" % self.chrootPath("dev", "shm")): + if devUnmtCmd not in self.umountCmds: + self.umountCmds.append(devUnmtCmd) + + mountopt = "gid=%d,mode=0620,ptmxmode=0666" % grp.getgrnam("tty").gr_gid + if os.uname()[2] >= "2.6.29": + mountopt += ",newinstance" + + for devMntCmd in ( + "mount -n -t devpts -o %s naoki_chroot_devpts %s" % (mountopt, self.chrootPath("dev", "pts")), + "mount -n -t tmpfs naoki_chroot_shmfs %s" % self.chrootPath("dev", "shm")): + if devMntCmd not in self.mountCmds: + self.mountCmds.append(devMntCmd) + + def _checkDev(self): + if os.path.exists(self.chrootPath("dev", "pts", "ptmx")): + os.symlink("/dev/pts/ptmx", self.chrootPath("dev", "ptmx")) + else: + os.mknod(self.chrootPath("dev", "ptmx"), stat.S_IFCHR | 0666, os.makedev(5, 2)) + os.chmod(self.chrootPath("dev", "ptmx"), 666) + + def _setupUsers(self): + ## XXX Could be done better + self.log.debug("Creating users") + f = open("/etc/passwd") + g = open(self.chrootPath("etc", "passwd"), "w") + for line in f.readlines(): + if line.startswith("root") or line.startswith("nobody"): + g.write("%s" % line) + g.close() + f.close() + + f = open("/etc/group") + g = open(self.chrootPath("etc", "group"), "w") + for line in f.readlines(): + if line.startswith("root") or line.startswith("nobody"): + g.write("%s" % line) + g.close() + f.close() + + def _mountall(self): + """mount 'normal' fs like /dev/ /proc/ /sys""" + for cmd in self.mountCmds: + util.do(cmd, shell=True) + self._checkDev() + + def _umountall(self): + """umount all mounted chroot fs.""" + for cmd in self.umountCmds: + util.do(cmd, raiseExc=0, shell=True) + + def extractAll(self): + packages = self.package.deps + self.package.build_deps + for pkg in config["mandatory_packages"]: + pkg = package.find(pkg) + if not pkg in packages: + packages.append(pkg) + + packages = package.depsolve(packages, recursive=True) + + for pkg in packages: + pkg.extract(self.chrootPath()) + + def build(self): + self.package.download() + self.init() + + try: + self.make("package") + except Error: + if config["cleanup_on_failure"]: + self.clean() + raise + + if config["cleanup_on_success"]: + self.clean() + + +class Toolchain(object): + def __init__(self, arch): + util.mkdir(TOOLCHAINSDIR) + + self.arch = arches[arch] + + # Create a filename object + self.filename = "toolchain-%s.%s.tar.gz" % \ + (self.arch["name"], config["toolchain_version"],) + + # Store the path including the filename + self.path = os.path.join(TOOLCHAINSDIR, self.filename) + + self.build_dir = os.path.join(BUILDDIR, "toolchains", + "tools_%s.%s" % (self.arch["name"], config["toolchain_version"])) + + self.log = getLog() + + @property + def exists(self): + return os.path.exists(self.path) + + def download(self): + self.log.info("Downloading toolchain...") + pass + + def cmd(self, args=[]): + cmd = "%s" % os.path.join(TOOLSDIR, "toolchain") + if args: + cmd += " " + cmd += " ".join(args) + util.do(cmd, cwd=self.build_dir, shell=True, + env={ "TOOLS_DIR" : self.build_dir }) + + # TODO: + # - logging + def make(self, pkg, target): + env = config.environment.copy() + env.update({ + "BASEDIR" : BASEDIR, + "PATH" : "/tools_%(arch)s/sbin:/tools_%(arch)s/bin:%(path)s" % \ + { "arch" : self.arch["name"], "path" : os.environ["PATH"], }, + "PKGROOT" : PKGSDIR, + "ROOT" : self.build_dir, + "TARGET" : "%s-ipfire-linux-gnu" % self.arch["machine"], + "TARGET_MACHINE" : self.arch["machine"], + "TOOLCHAIN" : "1", + "TOOLS_DIR" : "/tools_%s" % self.arch["name"], + + "CFLAGS" : self.arch["cflags"], + "CXXFLAGS" : self.arch["cxxflags"], + }) + + command = "make -C %s -f %s %s" % \ + (os.path.dirname(pkg.filename), pkg.filename, target) + + return util.do(command, shell=True, env=env, personality=self.arch["personality"]) + + def build_package(self, pkg): + self.log.info("Building %s..." % pkg.name) + + source_dir = os.path.join(self.build_dir, "usr/src") + + util.rm(source_dir) + util.mkdir(source_dir) + + self.checkLink() + + return self.make(pkg, "package") + + def compress(self): + self.cmd(["compress", self.path, self.build_dir]) + + def extract(self, path): + self.cmd(["extract", self.path, os.path.join(path, "tools_%s" % self.arch["name"])]) + + def adjust(self, path): + self.cmd(["adjust", path]) + + def build(self): + self.log.info("Building toolchain...") + + packages = package.depsort(package.list(toolchain=True)) + for pkg in packages: + if pkg.isBuilt: + continue + self.build_package(pkg) + self.compress() + + def checkLink(self): + link = "/tools_%s" % self.arch["name"] + destination = os.path.abspath(self.build_dir) + + if not os.path.islink(link): + # File is not a link. Remove it... + util.rm(link) + + else: + # If link points to correct destination we break up + if os.path.abspath(os.readlink(link)) == destination: + return + os.unlink(link) + + + os.symlink(destination, link) diff --git a/naoki/constants.py b/naoki/constants.py new file mode 100644 index 0000000..0a27688 --- /dev/null +++ b/naoki/constants.py @@ -0,0 +1,136 @@ +#!/usr/bin/python + +import ConfigParser +import os + +BASEDIR = os.getcwd() + +BUILDDIR = os.path.join(BASEDIR, "build") +CACHEDIR = os.path.join(BASEDIR, "cache") +CCACHEDIR = os.path.join(BASEDIR, "ccache") +CONFIGDIR = os.path.join(BASEDIR, "config") +LOGDIR = os.path.join(BASEDIR, "logs") +PKGSDIR = os.path.join(BASEDIR, "pkgs") +PACKAGESDIR = os.path.join(BUILDDIR, "packages") +TOOLSDIR = os.path.join(BASEDIR, "tools") + +TARBALLDIR = os.path.join(CACHEDIR, "tarballs") +TOOLCHAINSDIR = os.path.join(CACHEDIR, "toolchains") +PATCHESDIR = os.path.join(CACHEDIR, "patches") + +CONFIGFILE = os.path.join(CONFIGDIR, "naoki.conf") + +class Config(object): + _items = { + "toolchain" : False, + "mandatory_packages" : [ + "core/ccache", + "core/glibc", + ], + "nice_level" : 0, + # + # Cleanup settings + "cleanup_on_failure" : False, + "cleanup_on_success" : True, + # + # CLI variables + "quiet" : False, + # + # Distro items + "distro_name" : "unknown", + "distro_sname" : "unknown", + "distro_epoch" : "unknown", + "distro_version" : "unknown", + "distro_slogan" : "unknown", + # + # Downloads + "download_tarball_url" : "http://source.ipfire.org/source-3.x/%(file)s", + # + # Logging + "log_config_file" : os.path.join(CONFIGDIR, "logging.ini"), + "log_file" : os.path.join(LOGDIR, "naoki.log"), + } + + def __init__(self): + self.read([CONFIGFILE, os.path.join(BASEDIR, ".config")]) + + def read(self, files): + parser = ConfigParser.ConfigParser() + parser.read(files) + + config = {} + for key, val in parser.items(ConfigParser.DEFAULTSECT): + config[key] = val + + for section in parser.sections(): + for key, val in parser.items(section): + config["%s_%s" % (section, key)] = val + + self._items.update(config) + + def items(self): + return self._items.items() + + def __getitem__(self, item): + return self._items[item] + + def __setitem__(self, item, value): + self._items[item] = value + + @property + def environment(self): + return { + "HOME" : os.environ.get("HOME", "/root"), + "TERM" : os.environ["TERM"], + "PS1" : os.environ.get("PS1", "\u:\w$ "), + # + "DISTRO_NAME" : self["distro_name"], + "DISTRO_SNAME" : self["distro_sname"], + "DISTRO_EPOCH" : self["distro_epoch"], + "DISTRO_VERSION" : self["distro_version"], + "DISTRO_SLOGAN" : self["distro_slogan"], + # + "CFLAGS" : "-O2 -fomit-frame-pointer", + "PARALLELISMFLAGS" : "-j6", + } + + +class Architectures(object): + def __init__(self, configfile): + parser = ConfigParser.ConfigParser() + parser.read(configfile) + + arches = {} + for arch in parser.sections(): + arches[arch] = { "name" : arch } + for key, val in parser.items(arch): + arches[arch][key] = val + + self._arches = arches + self.__current = None + + def set(self, arch): + self.__current = arch + + @property + def all(self): + return self._arches + + @property + def default(self): + return self._arches.get("i686") + + @property + def current(self): + if not self.__current: + return self.default + return self._arches[self.__current] + + def __getitem__(self, key): + return self._arches[key] + + +# Create a globally useable instance of the configuration +config = Config() + +arches = Architectures(config["architecture_config"]) diff --git a/naoki/exception.py b/naoki/exception.py new file mode 100644 index 0000000..d0c661f --- /dev/null +++ b/naoki/exception.py @@ -0,0 +1,29 @@ +#!/usr/bin/python + +class Error(Exception): + "base class for our errors." + def __init__(self, msg, status=None): + Exception.__init__(self) + self.msg = msg + self.resultcode = 1 + if status is not None: + self.resultcode = status + + def __str__(self): + return self.msg + + +class BuildRootLocked(Error): + "build root in use by another process." + def __init__(self, msg): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 60 + + +class commandTimeoutExpired(Error): + def __init__(self, msg): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 10 + diff --git a/naoki/logger.py b/naoki/logger.py new file mode 100644 index 0000000..a73f5da --- /dev/null +++ b/naoki/logger.py @@ -0,0 +1,54 @@ +#!/usr/bin/python + +import curses +import logging +import sys +import time + +# defaults to module verbose log +# does a late binding on log. Forwards all attributes to logger. +# works around problem where reconfiguring the logging module means loggers +# configured before reconfig dont output. +class getLog(object): + def __init__(self, name=None, prefix="", *args, **kargs): + if name is None: + frame = sys._getframe(1) + name = frame.f_globals["__name__"] + + self.name = prefix + name + + def __getattr__(self, name): + logger = logging.getLogger(self.name) + return getattr(logger, name) + + +# Borrowed from tornado +class _ColorLogFormatter(logging.Formatter): + def __init__(self, *args, **kwargs): + logging.Formatter.__init__(self, *args, **kwargs) + fg_color = curses.tigetstr("setaf") or curses.tigetstr("setf") or "" + self._colors = { + logging.DEBUG: curses.tparm(fg_color, 4), # Blue + logging.INFO: curses.tparm(fg_color, 2), # Green + logging.WARNING: curses.tparm(fg_color, 3), # Yellow + logging.ERROR: curses.tparm(fg_color, 1), # Red + } + self._normal = curses.tigetstr("sgr0") + + def format(self, record): + try: + record.message = record.getMessage() + except Exception, e: + record.message = "Bad message (%r): %r" % (e, record.__dict__) + record.asctime = time.strftime( + "%H:%M:%S", self.converter(record.created)) + prefix = '[%(levelname)7s | %(asctime)s]' % \ + record.__dict__ + color = self._colors.get(record.levelno, self._normal) + formatted = color + prefix + self._normal + " " + record.message + if record.exc_info: + if not record.exc_text: + record.exc_text = self.formatException(record.exc_info) + if record.exc_text: + formatted = formatted.rstrip() + "\n" + record.exc_text + return formatted.replace("\n", "\n ") diff --git a/naoki/package.py b/naoki/package.py new file mode 100644 index 0000000..5c250ea --- /dev/null +++ b/naoki/package.py @@ -0,0 +1,449 @@ +#!/usr/bin/python + +import os +import sys +import urlgrabber +import urlgrabber.progress + +import chroot +import terminal +import util + +from constants import * +from logger import getLog + +def list(toolchain=False): + pkgs = [] + for dir in os.listdir(PKGSDIR): + if not os.path.isdir(os.path.join(PKGSDIR, dir)): + continue + + # If we work in toolchain mode we don't return the other + # packages and if we are not, we don't return the toolchain packages. + if toolchain: + if dir != "toolchain": + continue + else: + if dir == "toolchain": + continue + + for package in os.listdir(os.path.join(PKGSDIR, dir)): + package = os.path.join(dir, package) + pkgs.append(Package(package)) + + pkgs.sort() + return pkgs + +def find(s, toolchain=False): + if not s: + return + + p = Package(s) + if p in list(toolchain): + return p + + for package in list(toolchain): + if os.path.basename(package.name) == s: + return package + +def groups(): + return [Group(name) for name in group_names()] + +def group_names(): + groups = [] + for package in list(): + group = package.group + if not group in groups: + groups.append(group) + groups.sort() + return groups + +def download(file, type): + if not file: + return + + dirs = { + "tarball" : TARBALLDIR, + } + filepath = os.path.join(dirs[type], file) + if os.path.exists(filepath): + return + + g = urlgrabber.grabber.URLGrabber( + user_agent = "%sSourceGrabber/%s" % (config["distro_name"], config["distro_version"],), + progress_obj = urlgrabber.progress.TextMeter(), + text = "Downloading %s..." % file, + ) + gobj = g.urlopen(config["download_%s_url" % type] % { "file" : file }) + + # XXX Need to check SHA1 sum here + + for dir in dirs.values(): + util.mkdir(dir) + + fobj = open(filepath, "w") + fobj.write(gobj.read()) + fobj.close() + gobj.close() + +def depsolve(packages, recursive=False): + deps = [] + for package in packages: + if not package: + continue + if package: + deps.append(package) + + if not recursive or not deps: + return deps + + while True: + length = len(deps) + for dep in deps[:]: + deps.extend(dep.deps) + + new_deps = [] + for dep in deps: + if not dep in new_deps: + new_deps.append(dep) + + deps = new_deps + + if length == len(deps): + break + + deps.sort() + return deps + +def deptree(packages): + ret = [packages] + + while True: + next = [] + stage = ret[-1][:] + for package in stage[:]: + for dep in package.getAllDeps(recursive=False): + if dep in ret[-1]: + stage.remove(package) + next.append(package) + break + + ret[-1] = stage + if next: + ret.append(next) + continue + + break + + return ret + +def depsort(packages): + ret = [] + for l1 in deptree(packages): + ret.extend(l1) + return ret + +class Package(object): + info_str = """\ +Name : %(name)s +Version : %(version)s +Release : %(release)s +Group : %(group)s + +%(summary)s + +Description : +%(description)s + +Maintainer : %(maintainer)s +License : %(license)s + +Built? : %(isBuilt)s +Can build? : %(canBuild)s + +Files : +%(objects)s + +Patches : +%(patches)s +""" + + info_wiki_str = """\ +====== %(name)s ====== +| **Version:** | %(version)s | +| **Release:** | %(release)s | +| **Group:** | %(group)s | +| **License:** | %(license)s | +| **Maintainer:** | %(maintainer)s | +| **Dependencies:** | %(deps)s | +| **Build dependencies:** | %(build_deps)s | +| %(summary)s || +| **Website:** | %(url)s | +""" + + def __init__(self, name): + self._name = name + + self.config = config + self.__fetch_data = None + + self._getAllDeps = None + + def __repr__(self): + return "<Package %s>" % self.name + + def __cmp__(self, other): + return cmp(self.name, other.name) + + def fetch(self, key=None): + return self.__fetch()[key] + + def __fetch(self): + if not self.__fetch_data: + env = os.environ.copy() + env.update(config.environment) + env["PKGROOT"] = PKGSDIR + output = util.do("make -f %s" % self.filename, shell=True, + cwd=os.path.join(PKGSDIR, self.name), returnOutput=1, env=env) + + ret = {} + for line in output.splitlines(): + a = line.split("=", 1) + if not len(a) == 2: continue + key, val = a + ret[key] = val.strip(""") + + ret["FINGERPRINT"] = self.fingerprint + self.__fetch_data = ret + + return self.__fetch_data + + def download(self): + for object in self.objects: + download(object, type="tarball") + + @property + def fingerprint(self): + return str(os.stat(self.filename).st_mtime) + + @property + def filename(self): + return os.path.join(PKGSDIR, self.name, os.path.basename(self.name)) + ".nm" + + @property + def name(self): + return self._name + + @property + def version(self): + return self.fetch("PKG_VER") + + @property + def release(self): + return self.fetch("PKG_REL") + + @property + def summary(self): + return self.fetch("PKG_SUMMARY") + + @property + def description(self): + return self.fetch("PKG_DESCRIPTION") + + @property + def group(self): + return self.fetch("PKG_GROUP") + + @property + def packages(self): + return self.fetch("PKG_PACKAGES") + + @property + def package_files(self): + return sorted(self.fetch("PKG_PACKAGES_FILES").split(" ")) + + @property + def objects(self): + objects = [] + for object in sorted(self.fetch("PKG_OBJECTS").split(" ")): + if not object in self.patches: + objects.append(object) + return objects + + @property + def patches(self): + return sorted(self.fetch("PKG_PATCHES").split(" ")) + + @property + def maintainer(self): + return self.fetch("PKG_MAINTAINER") + + @property + def deps(self): + return self.getDeps() + + def getDeps(self, recursive=False): + deps = [] + for package in self.fetch("PKG_DEPENDENCIES").split(" "): + package = find(package) + if package: + deps.append(package) + return depsolve(deps, recursive) + + def getAllDeps(self, recursive=True): + if self.toolchain: + return depsolve(self.toolchain_deps, recursive) + + if not self._getAllDeps: + self._getAllDeps = depsolve(self.deps + self.build_deps, recursive) + + return self._getAllDeps + + @property + def build_deps(self): + deps = [] + for package in self.fetch("PKG_BUILD_DEPENDENCIES").split(" "): + package = find(package) + if package: + deps.append(package) + + deps.sort() + return deps + + @property + def toolchain_deps(self): + deps = [] + for package in self.fetch("PKG_TOOLCHAIN_DEPENDENCIES").split(" "): + package = find(package, toolchain=True) + if package: + deps.append(package) + + deps.sort() + return deps + + @property + def url(self): + return self.fetch("PKG_URL") + + @property + def id(self): + return "%s-%s-%s" % (self.name, self.version, self.release) + + @property + def license(self): + return self.fetch("PKG_LICENSE") + + @property + def __info(self): + return { + "name" : self.name, + "version" : self.version, + "release" : self.release, + "summary" : self.summary, + "description" : self.description, + "maintainer" : self.maintainer, + "objects" : self.objects, + "patches" : self.patches, + "group" : self.group, + "license" : self.license, + "isBuilt" : self.isBuilt, + "canBuild" : self.canBuild, + "url" : self.url, + } + + def info(self, long=False): + return self.info_str % self.__info + + def info_line(self, long=False): + if long: + s = "%-30s | %-15s | %s" % \ + (self.name, "%s-%s" % (self.version, self.release), self.summary) + + # Cut if text gets too long + columns = terminal.get_columns() + if len(s) >= columns: + s = s[:columns - 3] + "..." + + return s + + else: + return self.name + + def info_wiki(self, long=True): + if not long: + return " * [[.package:%(name)s|%(name)s]] - %(summary)s" % \ + { "name" : self.name, "summary" : self.summary, } + + __info = self.__info + __info.update({ + "deps" : "NOT IMPLEMENTED YET", + "build_deps" : "NOT IMPLEMENTED YET", + }) + + return self.info_wiki_str % __info + + @property + def isBuilt(self): + if self.toolchain: + return os.path.exists(self.toolchain_file) + + for item in self.package_files: + if not os.path.exists(os.path.join(PACKAGESDIR, item)): + return False + return True + + @property + def canBuild(self): + if self.toolchain: + for dep in self.toolchain_deps: + if not dep.isBuilt: + return False + return True + + deps = self.deps + self.build_deps + for dep in deps: + if not dep.isBuilt: + return False + + return True + + def extract(self, dest): + files = [os.path.join(PACKAGESDIR, file) for file in self.package_files] + if not files: + return + + getLog().debug("Extracting %s..." % self.name) + util.do("%s --root=%s %s" % (os.path.join(TOOLSDIR, "decompressor"), + dest, " ".join(files)), shell=True) + + @property + def toolchain(self): + if self.name.startswith("toolchain"): + return True + return False + + @property + def toolchain_file(self): + return os.path.join(TOOLCHAINSDIR, "tools_i686", "built", self.id) + + +class Group(object): + def __init__(self, name): + self.name = name + + self.__packages = [] + + def wiki_headline(self): + return "===== %s =====" % self.name + + @property + def packages(self): + if not self.__packages: + for pkg in list(): + if not pkg.group == self.name: + continue + self.__packages.append(pkg) + + self.__packages.sort() + + return self.__packages diff --git a/naoki/terminal.py b/naoki/terminal.py new file mode 100644 index 0000000..49a5985 --- /dev/null +++ b/naoki/terminal.py @@ -0,0 +1,46 @@ +#!/usr/bin/python + +import fcntl +import os +import struct +import termios + +DEFAULT_COLUMNS = 80 +DEFAULT_LINES = 25 + +def get_size(): + """ + returns the size of the terminal + + tupel: lines, columns + """ + def ioctl_GWINSZ(fd): + try: + cr = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234")) + except: + return None + + return cr + + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + + if not cr: + try: + cr = (os.environ['LINES'], os.environ['COLUMNS']) + except: + cr = (DEFAULT_LINES, DEFAULT_COLUMNS) + + return int(cr[1]), int(cr[0]) + +def get_lines(): + return get_size()[0] + +def get_columns(): + return get_size()[1] diff --git a/naoki/urlgrabber/__init__.py b/naoki/urlgrabber/__init__.py new file mode 100644 index 0000000..7bcd9d5 --- /dev/null +++ b/naoki/urlgrabber/__init__.py @@ -0,0 +1,53 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Copyright 2002-2006 Michael D. Stenner, Ryan Tomayko + +# $Id: __init__.py,v 1.20 2006/09/22 00:58:55 mstenner Exp $ + +"""A high-level cross-protocol url-grabber. + +Using urlgrabber, data can be fetched in three basic ways: + + urlgrab(url) copy the file to the local filesystem + urlopen(url) open the remote file and return a file object + (like urllib2.urlopen) + urlread(url) return the contents of the file as a string + +When using these functions (or methods), urlgrabber supports the +following features: + + * identical behavior for http://, ftp://, and file:// urls + * http keepalive - faster downloads of many files by using + only a single connection + * byte ranges - fetch only a portion of the file + * reget - for a urlgrab, resume a partial download + * progress meters - the ability to report download progress + automatically, even when using urlopen! + * throttling - restrict bandwidth usage + * retries - automatically retry a download if it fails. The + number of retries and failure types are configurable. + * authenticated server access for http and ftp + * proxy support - support for authenticated http and ftp proxies + * mirror groups - treat a list of mirrors as a single source, + automatically switching mirrors if there is a failure. +""" + +__version__ = '3.1.0' +__date__ = '2006/09/21' +__author__ = 'Michael D. Stenner mstenner@linux.duke.edu, ' \ + 'Ryan Tomayko rtomayko@naeblis.cx' +__url__ = 'http://linux.duke.edu/projects/urlgrabber/' + +from grabber import urlgrab, urlopen, urlread diff --git a/naoki/urlgrabber/byterange.py b/naoki/urlgrabber/byterange.py new file mode 100644 index 0000000..001b4e3 --- /dev/null +++ b/naoki/urlgrabber/byterange.py @@ -0,0 +1,463 @@ +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, +# Boston, MA 02111-1307 USA + +# This file is part of urlgrabber, a high-level cross-protocol url-grabber +# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko + +# $Id: byterange.py,v 1.12 2006/07/20 20:15:58 mstenner Exp $ + +import os +import stat +import urllib +import urllib2 +import rfc822 + +DEBUG = None + +try: + from cStringIO import StringIO +except ImportError, msg: + from StringIO import StringIO + +class RangeError(IOError): + """Error raised when an unsatisfiable range is requested.""" + pass + +class HTTPRangeHandler(urllib2.BaseHandler): + """Handler that enables HTTP Range headers. + + This was extremely simple. The Range header is a HTTP feature to + begin with so all this class does is tell urllib2 that the + "206 Partial Content" reponse from the HTTP server is what we + expected. + + Example: + import urllib2 + import byterange + + range_handler = range.HTTPRangeHandler() + opener = urllib2.build_opener(range_handler) + + # install it + urllib2.install_opener(opener) + + # create Request and set Range header + req = urllib2.Request('http://www.python.org/') + req.header['Range'] = 'bytes=30-50' + f = urllib2.urlopen(req) + """ + + def http_error_206(self, req, fp, code, msg, hdrs): + # 206 Partial Content Response + r = urllib.addinfourl(fp, hdrs, req.get_full_url()) + r.code = code + r.msg = msg + return r + + def http_error_416(self, req, fp, code, msg, hdrs): + # HTTP's Range Not Satisfiable error + raise RangeError('Requested Range Not Satisfiable') + +class HTTPSRangeHandler(HTTPRangeHandler): + """ Range Header support for HTTPS. """ + + def https_error_206(self, req, fp, code, msg, hdrs): + return self.http_error_206(req, fp, code, msg, hdrs) + + def https_error_416(self, req, fp, code, msg, hdrs): + self.https_error_416(req, fp, code, msg, hdrs) + +class RangeableFileObject: + """File object wrapper to enable raw range handling. + This was implemented primarilary for handling range + specifications for file:// urls. This object effectively makes + a file object look like it consists only of a range of bytes in + the stream. + + Examples: + # expose 10 bytes, starting at byte position 20, from + # /etc/aliases. + >>> fo = RangeableFileObject(file('/etc/passwd', 'r'), (20,30)) + # seek seeks within the range (to position 23 in this case) + >>> fo.seek(3) + # tell tells where your at _within the range_ (position 3 in + # this case) + >>> fo.tell() + # read EOFs if an attempt is made to read past the last + # byte in the range. the following will return only 7 bytes. + >>> fo.read(30) + """ + + def __init__(self, fo, rangetup): + """Create a RangeableFileObject. + fo -- a file like object. only the read() method need be + supported but supporting an optimized seek() is + preferable. + rangetup -- a (firstbyte,lastbyte) tuple specifying the range + to work over. + The file object provided is assumed to be at byte offset 0. + """ + self.fo = fo + (self.firstbyte, self.lastbyte) = range_tuple_normalize(rangetup) + self.realpos = 0 + self._do_seek(self.firstbyte) + + def __getattr__(self, name): + """This effectively allows us to wrap at the instance level. + Any attribute not found in _this_ object will be searched for + in self.fo. This includes methods.""" + if hasattr(self.fo, name): + return getattr(self.fo, name) + raise AttributeError, name + + def tell(self): + """Return the position within the range. + This is different from fo.seek in that position 0 is the + first byte position of the range tuple. For example, if + this object was created with a range tuple of (500,899), + tell() will return 0 when at byte position 500 of the file. + """ + return (self.realpos - self.firstbyte) + + def seek(self,offset,whence=0): + """Seek within the byte range. + Positioning is identical to that described under tell(). + """ + assert whence in (0, 1, 2) + if whence == 0: # absolute seek + realoffset = self.firstbyte + offset + elif whence == 1: # relative seek + realoffset = self.realpos + offset + elif whence == 2: # absolute from end of file + # XXX: are we raising the right Error here? + raise IOError('seek from end of file not supported.') + + # do not allow seek past lastbyte in range + if self.lastbyte and (realoffset >= self.lastbyte): + realoffset = self.lastbyte + + self._do_seek(realoffset - self.realpos) + + def read(self, size=-1): + """Read within the range. + This method will limit the size read based on the range. + """ + size = self._calc_read_size(size) + rslt = self.fo.read(size) + self.realpos += len(rslt) + return rslt + + def readline(self, size=-1): + """Read lines within the range. + This method will limit the size read based on the range. + """ + size = self._calc_read_size(size) + rslt = self.fo.readline(size) + self.realpos += len(rslt) + return rslt + + def _calc_read_size(self, size): + """Handles calculating the amount of data to read based on + the range. + """ + if self.lastbyte: + if size > -1: + if ((self.realpos + size) >= self.lastbyte): + size = (self.lastbyte - self.realpos) + else: + size = (self.lastbyte - self.realpos) + return size + + def _do_seek(self,offset): + """Seek based on whether wrapped object supports seek(). + offset is relative to the current position (self.realpos). + """ + assert offset >= 0 + if not hasattr(self.fo, 'seek'): + self._poor_mans_seek(offset) + else: + self.fo.seek(self.realpos + offset) + self.realpos+= offset + + def _poor_mans_seek(self,offset): + """Seek by calling the wrapped file objects read() method. + This is used for file like objects that do not have native + seek support. The wrapped objects read() method is called + to manually seek to the desired position. + offset -- read this number of bytes from the wrapped + file object. + raise RangeError if we encounter EOF before reaching the + specified offset. + """ + pos = 0 + bufsize = 1024 + while pos < offset: + if (pos + bufsize) > offset: + bufsize = offset - pos + buf = self.fo.read(bufsize) + if len(buf) != bufsize: + raise RangeError('Requested Range Not Satisfiable') + pos+= bufsize + +class FileRangeHandler(urllib2.FileHandler): + """FileHandler subclass that adds Range support. + This class handles Range headers exactly like an HTTP + server would. + """ + def open_local_file(self, req): + import mimetypes + import mimetools + host = req.get_host() + file = req.get_selector() + localfile = urllib.url2pathname(file) + stats = os.stat(localfile) + size = stats[stat.ST_SIZE] + modified = rfc822.formatdate(stats[stat.ST_MTIME]) + mtype = mimetypes.guess_type(file)[0] + if host: + host, port = urllib.splitport(host) + if port or socket.gethostbyname(host) not in self.get_names(): + raise urllib2.URLError('file not on local host') + fo = open(localfile,'rb') + brange = req.headers.get('Range',None) + brange = range_header_to_tuple(brange) + assert brange != () + if brange: + (fb,lb) = brange + if lb == '': lb = size + if fb < 0 or fb > size or lb > size: + raise RangeError('Requested Range Not Satisfiable') + size = (lb - fb) + fo = RangeableFileObject(fo, (fb,lb)) + headers = mimetools.Message(StringIO( + 'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' % + (mtype or 'text/plain', size, modified))) + return urllib.addinfourl(fo, headers, 'file:'+file) + + +# FTP Range Support +# Unfortunately, a large amount of base FTP code had to be copied +# from urllib and urllib2 in order to insert the FTP REST command. +# Code modifications for range support have been commented as +# follows: +# -- range support modifications start/end here + +from urllib import splitport, splituser, splitpasswd, splitattr, \ + unquote, addclosehook, addinfourl +import ftplib +import socket +import sys +import ftplib +import mimetypes +import mimetools + +class FTPRangeHandler(urllib2.FTPHandler): + def ftp_open(self, req): + host = req.get_host() + if not host: + raise IOError, ('ftp error', 'no host given') + host, port = splitport(host) + if port is None: + port = ftplib.FTP_PORT + + # username/password handling + user, host = splituser(host) + if user: + user, passwd = splitpasswd(user) + else: + passwd = None + host = unquote(host) + user = unquote(user or '') + passwd = unquote(passwd or '') + + try: + host = socket.gethostbyname(host) + except socket.error, msg: + raise urllib2.URLError(msg) + path, attrs = splitattr(req.get_selector()) + dirs = path.split('/') + dirs = map(unquote, dirs) + dirs, file = dirs[:-1], dirs[-1] + if dirs and not dirs[0]: + dirs = dirs[1:] + try: + fw = self.connect_ftp(user, passwd, host, port, dirs) + type = file and 'I' or 'D' + for attr in attrs: + attr, value = splitattr(attr) + if attr.lower() == 'type' and \ + value in ('a', 'A', 'i', 'I', 'd', 'D'): + type = value.upper() + + # -- range support modifications start here + rest = None + range_tup = range_header_to_tuple(req.headers.get('Range',None)) + assert range_tup != () + if range_tup: + (fb,lb) = range_tup + if fb > 0: rest = fb + # -- range support modifications end here + + fp, retrlen = fw.retrfile(file, type, rest) + + # -- range support modifications start here + if range_tup: + (fb,lb) = range_tup + if lb == '': + if retrlen is None or retrlen == 0: + raise RangeError('Requested Range Not Satisfiable due to unobtainable file length.') + lb = retrlen + retrlen = lb - fb + if retrlen < 0: + # beginning of range is larger than file + raise RangeError('Requested Range Not Satisfiable') + else: + retrlen = lb - fb + fp = RangeableFileObject(fp, (0,retrlen)) + # -- range support modifications end here + + headers = "" + mtype = mimetypes.guess_type(req.get_full_url())[0] + if mtype: + headers += "Content-Type: %s\n" % mtype + if retrlen is not None and retrlen >= 0: + headers += "Content-Length: %d\n" % retrlen + sf = StringIO(headers) + headers = mimetools.Message(sf) + return addinfourl(fp, headers, req.get_full_url()) + except ftplib.all_errors, msg: + raise IOError, ('ftp error', msg), sys.exc_info()[2] + + def connect_ftp(self, user, passwd, host, port, dirs): + fw = ftpwrapper(user, passwd, host, port, dirs) + return fw + +class ftpwrapper(urllib.ftpwrapper): + # range support note: + # this ftpwrapper code is copied directly from + # urllib. The only enhancement is to add the rest + # argument and pass it on to ftp.ntransfercmd + def retrfile(self, file, type, rest=None): + self.endtransfer() + if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1 + else: cmd = 'TYPE ' + type; isdir = 0 + try: + self.ftp.voidcmd(cmd) + except ftplib.all_errors: + self.init() + self.ftp.voidcmd(cmd) + conn = None + if file and not isdir: + # Use nlst to see if the file exists at all + try: + self.ftp.nlst(file) + except ftplib.error_perm, reason: + raise IOError, ('ftp error', reason), sys.exc_info()[2] + # Restore the transfer mode! + self.ftp.voidcmd(cmd) + # Try to retrieve as a file + try: + cmd = 'RETR ' + file + conn = self.ftp.ntransfercmd(cmd, rest) + except ftplib.error_perm, reason: + if str(reason)[:3] == '501': + # workaround for REST not supported error + fp, retrlen = self.retrfile(file, type) + fp = RangeableFileObject(fp, (rest,'')) + return (fp, retrlen) + elif str(reason)[:3] != '550': + raise IOError, ('ftp error', reason), sys.exc_info()[2] + if not conn: + # Set transfer mode to ASCII! + self.ftp.voidcmd('TYPE A') + # Try a directory listing + if file: cmd = 'LIST ' + file + else: cmd = 'LIST' + conn = self.ftp.ntransfercmd(cmd) + self.busy = 1 + # Pass back both a suitably decorated object and a retrieval length + return (addclosehook(conn[0].makefile('rb'), + self.endtransfer), conn[1]) + + +#################################################################### +# Range Tuple Functions +# XXX: These range tuple functions might go better in a class. + +_rangere = None +def range_header_to_tuple(range_header): + """Get a (firstbyte,lastbyte) tuple from a Range header value. + + Range headers have the form "bytes=<firstbyte>-<lastbyte>". This + function pulls the firstbyte and lastbyte values and returns + a (firstbyte,lastbyte) tuple. If lastbyte is not specified in + the header value, it is returned as an empty string in the + tuple. + + Return None if range_header is None + Return () if range_header does not conform to the range spec + pattern. + + """ + global _rangere + if range_header is None: return None + if _rangere is None: + import re + _rangere = re.compile(r'^bytes=(\d{1,})-(\d*)') + match = _rangere.match(range_header) + if match: + tup = range_tuple_normalize(match.group(1,2)) + if tup and tup[1]: + tup = (tup[0],tup[1]+1) + return tup + return () + +def range_tuple_to_header(range_tup): + """Convert a range tuple to a Range header value. + Return a string of the form "bytes=<firstbyte>-<lastbyte>" or None + if no range is needed. + """ + if range_tup is None: return None + range_tup = range_tuple_normalize(range_tup) + if range_tup: + if range_tup[1]: + range_tup = (range_tup[0],range_tup[1] - 1) + return 'bytes=%s-%s' % range_tup + +def range_tuple_normalize(range_tup): + """Normalize a (first_byte,last_byte) range tuple. + Return a tuple whose first element is guaranteed to be an int + and whose second element will be '' (meaning: the last byte) or + an int. Finally, return None if the normalized tuple == (0,'') + as that is equivelant to retrieving the entire file. + """ + if range_tup is None: return None + # handle first byte + fb = range_tup[0] + if fb in (None,''): fb = 0 + else: fb = int(fb) + # handle last byte + try: lb = range_tup[1] + except IndexError: lb = '' + else: + if lb is None: lb = '' + elif lb != '': lb = int(lb) + # check if range is over the entire file + if (fb,lb) == (0,''): return None + # check that the range is valid + if lb < fb: raise RangeError('Invalid byte range: %s-%s' % (fb,lb)) + return (fb,lb) + diff --git a/naoki/urlgrabber/grabber.py b/naoki/urlgrabber/grabber.py new file mode 100644 index 0000000..20e7899 --- /dev/null +++ b/naoki/urlgrabber/grabber.py @@ -0,0 +1,1477 @@ +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, +# Boston, MA 02111-1307 USA + +# This file is part of urlgrabber, a high-level cross-protocol url-grabber +# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko + +"""A high-level cross-protocol url-grabber. + +GENERAL ARGUMENTS (kwargs) + + Where possible, the module-level default is indicated, and legal + values are provided. + + copy_local = 0 [0|1] + + ignored except for file:// urls, in which case it specifies + whether urlgrab should still make a copy of the file, or simply + point to the existing copy. The module level default for this + option is 0. + + close_connection = 0 [0|1] + + tells URLGrabber to close the connection after a file has been + transfered. This is ignored unless the download happens with the + http keepalive handler (keepalive=1). Otherwise, the connection + is left open for further use. The module level default for this + option is 0 (keepalive connections will not be closed). + + keepalive = 1 [0|1] + + specifies whether keepalive should be used for HTTP/1.1 servers + that support it. The module level default for this option is 1 + (keepalive is enabled). + + progress_obj = None + + a class instance that supports the following methods: + po.start(filename, url, basename, length, text) + # length will be None if unknown + po.update(read) # read == bytes read so far + po.end() + + text = None + + specifies an alternativ text item in the beginning of the progress + bar line. If not given, the basename of the file is used. + + throttle = 1.0 + + a number - if it's an int, it's the bytes/second throttle limit. + If it's a float, it is first multiplied by bandwidth. If throttle + == 0, throttling is disabled. If None, the module-level default + (which can be set on default_grabber.throttle) is used. See + BANDWIDTH THROTTLING for more information. + + timeout = None + + a positive float expressing the number of seconds to wait for socket + operations. If the value is None or 0.0, socket operations will block + forever. Setting this option causes urlgrabber to call the settimeout + method on the Socket object used for the request. See the Python + documentation on settimeout for more information. + http://www.python.org/doc/current/lib/socket-objects.html + + bandwidth = 0 + + the nominal max bandwidth in bytes/second. If throttle is a float + and bandwidth == 0, throttling is disabled. If None, the + module-level default (which can be set on + default_grabber.bandwidth) is used. See BANDWIDTH THROTTLING for + more information. + + range = None + + a tuple of the form (first_byte, last_byte) describing a byte + range to retrieve. Either or both of the values may set to + None. If first_byte is None, byte offset 0 is assumed. If + last_byte is None, the last byte available is assumed. Note that + the range specification is python-like in that (0,10) will yeild + the first 10 bytes of the file. + + If set to None, no range will be used. + + reget = None [None|'simple'|'check_timestamp'] + + whether to attempt to reget a partially-downloaded file. Reget + only applies to .urlgrab and (obviously) only if there is a + partially downloaded file. Reget has two modes: + + 'simple' -- the local file will always be trusted. If there + are 100 bytes in the local file, then the download will always + begin 100 bytes into the requested file. + + 'check_timestamp' -- the timestamp of the server file will be + compared to the timestamp of the local file. ONLY if the + local file is newer than or the same age as the server file + will reget be used. If the server file is newer, or the + timestamp is not returned, the entire file will be fetched. + + NOTE: urlgrabber can do very little to verify that the partial + file on disk is identical to the beginning of the remote file. + You may want to either employ a custom "checkfunc" or simply avoid + using reget in situations where corruption is a concern. + + user_agent = 'urlgrabber/VERSION' + + a string, usually of the form 'AGENT/VERSION' that is provided to + HTTP servers in the User-agent header. The module level default + for this option is "urlgrabber/VERSION". + + http_headers = None + + a tuple of 2-tuples, each containing a header and value. These + will be used for http and https requests only. For example, you + can do + http_headers = (('Pragma', 'no-cache'),) + + ftp_headers = None + + this is just like http_headers, but will be used for ftp requests. + + proxies = None + + a dictionary that maps protocol schemes to proxy hosts. For + example, to use a proxy server on host "foo" port 3128 for http + and https URLs: + proxies={ 'http' : 'http://foo:3128', 'https' : 'http://foo:3128' } + note that proxy authentication information may be provided using + normal URL constructs: + proxies={ 'http' : 'http://user:host@foo:3128' } + Lastly, if proxies is None, the default environment settings will + be used. + + prefix = None + + a url prefix that will be prepended to all requested urls. For + example: + g = URLGrabber(prefix='http://foo.com/mirror/') + g.urlgrab('some/file.txt') + ## this will fetch 'http://foo.com/mirror/some/file.txt' + This option exists primarily to allow identical behavior to + MirrorGroup (and derived) instances. Note: a '/' will be inserted + if necessary, so you cannot specify a prefix that ends with a + partial file or directory name. + + opener = None + + Overrides the default urllib2.OpenerDirector provided to urllib2 + when making requests. This option exists so that the urllib2 + handler chain may be customized. Note that the range, reget, + proxy, and keepalive features require that custom handlers be + provided to urllib2 in order to function properly. If an opener + option is provided, no attempt is made by urlgrabber to ensure + chain integrity. You are responsible for ensuring that any + extension handlers are present if said features are required. + + data = None + + Only relevant for the HTTP family (and ignored for other + protocols), this allows HTTP POSTs. When the data kwarg is + present (and not None), an HTTP request will automatically become + a POST rather than GET. This is done by direct passthrough to + urllib2. If you use this, you may also want to set the + 'Content-length' and 'Content-type' headers with the http_headers + option. Note that python 2.2 handles the case of these + badly and if you do not use the proper case (shown here), your + values will be overridden with the defaults. + + +RETRY RELATED ARGUMENTS + + retry = None + + the number of times to retry the grab before bailing. If this is + zero, it will retry forever. This was intentional... really, it + was :). If this value is not supplied or is supplied but is None + retrying does not occur. + + retrycodes = [-1,2,4,5,6,7] + + a sequence of errorcodes (values of e.errno) for which it should + retry. See the doc on URLGrabError for more details on this. You + might consider modifying a copy of the default codes rather than + building yours from scratch so that if the list is extended in the + future (or one code is split into two) you can still enjoy the + benefits of the default list. You can do that with something like + this: + + retrycodes = urlgrabber.grabber.URLGrabberOptions().retrycodes + if 12 not in retrycodes: + retrycodes.append(12) + + checkfunc = None + + a function to do additional checks. This defaults to None, which + means no additional checking. The function should simply return + on a successful check. It should raise URLGrabError on an + unsuccessful check. Raising of any other exception will be + considered immediate failure and no retries will occur. + + If it raises URLGrabError, the error code will determine the retry + behavior. Negative error numbers are reserved for use by these + passed in functions, so you can use many negative numbers for + different types of failure. By default, -1 results in a retry, + but this can be customized with retrycodes. + + If you simply pass in a function, it will be given exactly one + argument: a CallbackObject instance with the .url attribute + defined and either .filename (for urlgrab) or .data (for urlread). + For urlgrab, .filename is the name of the local file. For + urlread, .data is the actual string data. If you need other + arguments passed to the callback (program state of some sort), you + can do so like this: + + checkfunc=(function, ('arg1', 2), {'kwarg': 3}) + + if the downloaded file has filename /tmp/stuff, then this will + result in this call (for urlgrab): + + function(obj, 'arg1', 2, kwarg=3) + # obj.filename = '/tmp/stuff' + # obj.url = 'http://foo.com/stuff' + + NOTE: both the "args" tuple and "kwargs" dict must be present if + you use this syntax, but either (or both) can be empty. + + failure_callback = None + + The callback that gets called during retries when an attempt to + fetch a file fails. The syntax for specifying the callback is + identical to checkfunc, except for the attributes defined in the + CallbackObject instance. The attributes for failure_callback are: + + exception = the raised exception + url = the url we're trying to fetch + tries = the number of tries so far (including this one) + retry = the value of the retry option + + The callback is present primarily to inform the calling program of + the failure, but if it raises an exception (including the one it's + passed) that exception will NOT be caught and will therefore cause + future retries to be aborted. + + The callback is called for EVERY failure, including the last one. + On the last try, the callback can raise an alternate exception, + but it cannot (without severe trickiness) prevent the exception + from being raised. + + interrupt_callback = None + + This callback is called if KeyboardInterrupt is received at any + point in the transfer. Basically, this callback can have three + impacts on the fetch process based on the way it exits: + + 1) raise no exception: the current fetch will be aborted, but + any further retries will still take place + + 2) raise a URLGrabError: if you're using a MirrorGroup, then + this will prompt a failover to the next mirror according to + the behavior of the MirrorGroup subclass. It is recommended + that you raise URLGrabError with code 15, 'user abort'. If + you are NOT using a MirrorGroup subclass, then this is the + same as (3). + + 3) raise some other exception (such as KeyboardInterrupt), which + will not be caught at either the grabber or mirror levels. + That is, it will be raised up all the way to the caller. + + This callback is very similar to failure_callback. They are + passed the same arguments, so you could use the same function for + both. + + urlparser = URLParser() + + The URLParser class handles pre-processing of URLs, including + auth-handling for user/pass encoded in http urls, file handing + (that is, filenames not sent as a URL), and URL quoting. If you + want to override any of this behavior, you can pass in a + replacement instance. See also the 'quote' option. + + quote = None + + Whether or not to quote the path portion of a url. + quote = 1 -> quote the URLs (they're not quoted yet) + quote = 0 -> do not quote them (they're already quoted) + quote = None -> guess what to do + + This option only affects proper urls like 'file:///etc/passwd'; it + does not affect 'raw' filenames like '/etc/passwd'. The latter + will always be quoted as they are converted to URLs. Also, only + the path part of a url is quoted. If you need more fine-grained + control, you should probably subclass URLParser and pass it in via + the 'urlparser' option. + +BANDWIDTH THROTTLING + + urlgrabber supports throttling via two values: throttle and + bandwidth Between the two, you can either specify and absolute + throttle threshold or specify a theshold as a fraction of maximum + available bandwidth. + + throttle is a number - if it's an int, it's the bytes/second + throttle limit. If it's a float, it is first multiplied by + bandwidth. If throttle == 0, throttling is disabled. If None, the + module-level default (which can be set with set_throttle) is used. + + bandwidth is the nominal max bandwidth in bytes/second. If throttle + is a float and bandwidth == 0, throttling is disabled. If None, the + module-level default (which can be set with set_bandwidth) is used. + + THROTTLING EXAMPLES: + + Lets say you have a 100 Mbps connection. This is (about) 10^8 bits + per second, or 12,500,000 Bytes per second. You have a number of + throttling options: + + *) set_bandwidth(12500000); set_throttle(0.5) # throttle is a float + + This will limit urlgrab to use half of your available bandwidth. + + *) set_throttle(6250000) # throttle is an int + + This will also limit urlgrab to use half of your available + bandwidth, regardless of what bandwidth is set to. + + *) set_throttle(6250000); set_throttle(1.0) # float + + Use half your bandwidth + + *) set_throttle(6250000); set_throttle(2.0) # float + + Use up to 12,500,000 Bytes per second (your nominal max bandwidth) + + *) set_throttle(6250000); set_throttle(0) # throttle = 0 + + Disable throttling - this is more efficient than a very large + throttle setting. + + *) set_throttle(0); set_throttle(1.0) # throttle is float, bandwidth = 0 + + Disable throttling - this is the default when the module is loaded. + + SUGGESTED AUTHOR IMPLEMENTATION (THROTTLING) + + While this is flexible, it's not extremely obvious to the user. I + suggest you implement a float throttle as a percent to make the + distinction between absolute and relative throttling very explicit. + + Also, you may want to convert the units to something more convenient + than bytes/second, such as kbps or kB/s, etc. + +""" + +# $Id: grabber.py,v 1.48 2006/09/22 00:58:05 mstenner Exp $ + +import os +import os.path +import sys +import urlparse +import rfc822 +import time +import string +import urllib +import urllib2 +from stat import * # S_* and ST_* + +######################################################################## +# MODULE INITIALIZATION +######################################################################## +try: + exec('from ' + (__name__.split('.'))[0] + ' import __version__') +except: + __version__ = '???' + +import sslfactory + +auth_handler = urllib2.HTTPBasicAuthHandler( \ + urllib2.HTTPPasswordMgrWithDefaultRealm()) + +try: + from i18n import _ +except ImportError, msg: + def _(st): return st + +try: + from httplib import HTTPException +except ImportError, msg: + HTTPException = None + +try: + # This is a convenient way to make keepalive optional. + # Just rename the module so it can't be imported. + import keepalive + from keepalive import HTTPHandler, HTTPSHandler + have_keepalive = True +except ImportError, msg: + have_keepalive = False + +try: + # add in range support conditionally too + import byterange + from byterange import HTTPRangeHandler, HTTPSRangeHandler, \ + FileRangeHandler, FTPRangeHandler, range_tuple_normalize, \ + range_tuple_to_header, RangeError +except ImportError, msg: + range_handlers = () + RangeError = None + have_range = 0 +else: + range_handlers = (HTTPRangeHandler(), HTTPSRangeHandler(), + FileRangeHandler(), FTPRangeHandler()) + have_range = 1 + + +# check whether socket timeout support is available (Python >= 2.3) +import socket +try: + TimeoutError = socket.timeout + have_socket_timeout = True +except AttributeError: + TimeoutError = None + have_socket_timeout = False + +######################################################################## +# functions for debugging output. These functions are here because they +# are also part of the module initialization. +DEBUG = None +def set_logger(DBOBJ): + """Set the DEBUG object. This is called by _init_default_logger when + the environment variable URLGRABBER_DEBUG is set, but can also be + called by a calling program. Basically, if the calling program uses + the logging module and would like to incorporate urlgrabber logging, + then it can do so this way. It's probably not necessary as most + internal logging is only for debugging purposes. + + The passed-in object should be a logging.Logger instance. It will + be pushed into the keepalive and byterange modules if they're + being used. The mirror module pulls this object in on import, so + you will need to manually push into it. In fact, you may find it + tidier to simply push your logging object (or objects) into each + of these modules independently. + """ + + global DEBUG + DEBUG = DBOBJ + if have_keepalive and keepalive.DEBUG is None: + keepalive.DEBUG = DBOBJ + if have_range and byterange.DEBUG is None: + byterange.DEBUG = DBOBJ + if sslfactory.DEBUG is None: + sslfactory.DEBUG = DBOBJ + +def _init_default_logger(): + '''Examines the environment variable URLGRABBER_DEBUG and creates + a logging object (logging.logger) based on the contents. It takes + the form + + URLGRABBER_DEBUG=level,filename + + where "level" can be either an integer or a log level from the + logging module (DEBUG, INFO, etc). If the integer is zero or + less, logging will be disabled. Filename is the filename where + logs will be sent. If it is "-", then stdout will be used. If + the filename is empty or missing, stderr will be used. If the + variable cannot be processed or the logging module cannot be + imported (python < 2.3) then logging will be disabled. Here are + some examples: + + URLGRABBER_DEBUG=1,debug.txt # log everything to debug.txt + URLGRABBER_DEBUG=WARNING,- # log warning and higher to stdout + URLGRABBER_DEBUG=INFO # log info and higher to stderr + + This funtion is called during module initialization. It is not + intended to be called from outside. The only reason it is a + function at all is to keep the module-level namespace tidy and to + collect the code into a nice block.''' + + try: + dbinfo = os.environ['URLGRABBER_DEBUG'].split(',') + import logging + level = logging._levelNames.get(dbinfo[0], int(dbinfo[0])) + if level < 1: raise ValueError() + + formatter = logging.Formatter('%(asctime)s %(message)s') + if len(dbinfo) > 1: filename = dbinfo[1] + else: filename = '' + if filename == '': handler = logging.StreamHandler(sys.stderr) + elif filename == '-': handler = logging.StreamHandler(sys.stdout) + else: handler = logging.FileHandler(filename) + handler.setFormatter(formatter) + DBOBJ = logging.getLogger('urlgrabber') + DBOBJ.addHandler(handler) + DBOBJ.setLevel(level) + except (KeyError, ImportError, ValueError): + DBOBJ = None + set_logger(DBOBJ) + +_init_default_logger() +######################################################################## +# END MODULE INITIALIZATION +######################################################################## + + + +class URLGrabError(IOError): + """ + URLGrabError error codes: + + URLGrabber error codes (0 -- 255) + 0 - everything looks good (you should never see this) + 1 - malformed url + 2 - local file doesn't exist + 3 - request for non-file local file (dir, etc) + 4 - IOError on fetch + 5 - OSError on fetch + 6 - no content length header when we expected one + 7 - HTTPException + 8 - Exceeded read limit (for urlread) + 9 - Requested byte range not satisfiable. + 10 - Byte range requested, but range support unavailable + 11 - Illegal reget mode + 12 - Socket timeout + 13 - malformed proxy url + 14 - HTTPError (includes .code and .exception attributes) + 15 - user abort + + MirrorGroup error codes (256 -- 511) + 256 - No more mirrors left to try + + Custom (non-builtin) classes derived from MirrorGroup (512 -- 767) + [ this range reserved for application-specific error codes ] + + Retry codes (< 0) + -1 - retry the download, unknown reason + + Note: to test which group a code is in, you can simply do integer + division by 256: e.errno / 256 + + Negative codes are reserved for use by functions passed in to + retrygrab with checkfunc. The value -1 is built in as a generic + retry code and is already included in the retrycodes list. + Therefore, you can create a custom check function that simply + returns -1 and the fetch will be re-tried. For more customized + retries, you can use other negative number and include them in + retry-codes. This is nice for outputting useful messages about + what failed. + + You can use these error codes like so: + try: urlgrab(url) + except URLGrabError, e: + if e.errno == 3: ... + # or + print e.strerror + # or simply + print e #### print '[Errno %i] %s' % (e.errno, e.strerror) + """ + pass + +class CallbackObject: + """Container for returned callback data. + + This is currently a dummy class into which urlgrabber can stuff + information for passing to callbacks. This way, the prototype for + all callbacks is the same, regardless of the data that will be + passed back. Any function that accepts a callback function as an + argument SHOULD document what it will define in this object. + + It is possible that this class will have some greater + functionality in the future. + """ + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + +def urlgrab(url, filename=None, **kwargs): + """grab the file at <url> and make a local copy at <filename> + If filename is none, the basename of the url is used. + urlgrab returns the filename of the local file, which may be different + from the passed-in filename if the copy_local kwarg == 0. + + See module documentation for a description of possible kwargs. + """ + return default_grabber.urlgrab(url, filename, **kwargs) + +def urlopen(url, **kwargs): + """open the url and return a file object + If a progress object or throttle specifications exist, then + a special file object will be returned that supports them. + The file object can be treated like any other file object. + + See module documentation for a description of possible kwargs. + """ + return default_grabber.urlopen(url, **kwargs) + +def urlread(url, limit=None, **kwargs): + """read the url into a string, up to 'limit' bytes + If the limit is exceeded, an exception will be thrown. Note that urlread + is NOT intended to be used as a way of saying "I want the first N bytes" + but rather 'read the whole file into memory, but don't use too much' + + See module documentation for a description of possible kwargs. + """ + return default_grabber.urlread(url, limit, **kwargs) + + +class URLParser: + """Process the URLs before passing them to urllib2. + + This class does several things: + + * add any prefix + * translate a "raw" file to a proper file: url + * handle any http or https auth that's encoded within the url + * quote the url + + Only the "parse" method is called directly, and it calls sub-methods. + + An instance of this class is held in the options object, which + means that it's easy to change the behavior by sub-classing and + passing the replacement in. It need only have a method like: + + url, parts = urlparser.parse(url, opts) + """ + + def parse(self, url, opts): + """parse the url and return the (modified) url and its parts + + Note: a raw file WILL be quoted when it's converted to a URL. + However, other urls (ones which come with a proper scheme) may + or may not be quoted according to opts.quote + + opts.quote = 1 --> quote it + opts.quote = 0 --> do not quote it + opts.quote = None --> guess + """ + quote = opts.quote + + if opts.prefix: + url = self.add_prefix(url, opts.prefix) + + parts = urlparse.urlparse(url) + (scheme, host, path, parm, query, frag) = parts + + if not scheme or (len(scheme) == 1 and scheme in string.letters): + # if a scheme isn't specified, we guess that it's "file:" + if url[0] not in '/\': url = os.path.abspath(url) + url = 'file:' + urllib.pathname2url(url) + parts = urlparse.urlparse(url) + quote = 0 # pathname2url quotes, so we won't do it again + + if scheme in ['http', 'https']: + parts = self.process_http(parts) + + if quote is None: + quote = self.guess_should_quote(parts) + if quote: + parts = self.quote(parts) + + url = urlparse.urlunparse(parts) + return url, parts + + def add_prefix(self, url, prefix): + if prefix[-1] == '/' or url[0] == '/': + url = prefix + url + else: + url = prefix + '/' + url + return url + + def process_http(self, parts): + (scheme, host, path, parm, query, frag) = parts + + if '@' in host and auth_handler: + try: + user_pass, host = host.split('@', 1) + if ':' in user_pass: + user, password = user_pass.split(':', 1) + except ValueError, e: + raise URLGrabError(1, _('Bad URL: %s') % url) + if DEBUG: DEBUG.info('adding HTTP auth: %s, %s', user, password) + auth_handler.add_password(None, host, user, password) + + return (scheme, host, path, parm, query, frag) + + def quote(self, parts): + """quote the URL + + This method quotes ONLY the path part. If you need to quote + other parts, you should override this and pass in your derived + class. The other alternative is to quote other parts before + passing into urlgrabber. + """ + (scheme, host, path, parm, query, frag) = parts + path = urllib.quote(path) + return (scheme, host, path, parm, query, frag) + + hexvals = '0123456789ABCDEF' + def guess_should_quote(self, parts): + """ + Guess whether we should quote a path. This amounts to + guessing whether it's already quoted. + + find ' ' -> 1 + find '%' -> 1 + find '%XX' -> 0 + else -> 1 + """ + (scheme, host, path, parm, query, frag) = parts + if ' ' in path: + return 1 + ind = string.find(path, '%') + if ind > -1: + while ind > -1: + if len(path) < ind+3: + return 1 + code = path[ind+1:ind+3].upper() + if code[0] not in self.hexvals or \ + code[1] not in self.hexvals: + return 1 + ind = string.find(path, '%', ind+1) + return 0 + return 1 + +class URLGrabberOptions: + """Class to ease kwargs handling.""" + + def __init__(self, delegate=None, **kwargs): + """Initialize URLGrabberOptions object. + Set default values for all options and then update options specified + in kwargs. + """ + self.delegate = delegate + if delegate is None: + self._set_defaults() + self._set_attributes(**kwargs) + + def __getattr__(self, name): + if self.delegate and hasattr(self.delegate, name): + return getattr(self.delegate, name) + raise AttributeError, name + + def raw_throttle(self): + """Calculate raw throttle value from throttle and bandwidth + values. + """ + if self.throttle <= 0: + return 0 + elif type(self.throttle) == type(0): + return float(self.throttle) + else: # throttle is a float + return self.bandwidth * self.throttle + + def derive(self, **kwargs): + """Create a derived URLGrabberOptions instance. + This method creates a new instance and overrides the + options specified in kwargs. + """ + return URLGrabberOptions(delegate=self, **kwargs) + + def _set_attributes(self, **kwargs): + """Update object attributes with those provided in kwargs.""" + self.__dict__.update(kwargs) + if have_range and kwargs.has_key('range'): + # normalize the supplied range value + self.range = range_tuple_normalize(self.range) + if not self.reget in [None, 'simple', 'check_timestamp']: + raise URLGrabError(11, _('Illegal reget mode: %s') \ + % (self.reget, )) + + def _set_defaults(self): + """Set all options to their default values. + When adding new options, make sure a default is + provided here. + """ + self.progress_obj = None + self.throttle = 1.0 + self.bandwidth = 0 + self.retry = None + self.retrycodes = [-1,2,4,5,6,7] + self.checkfunc = None + self.copy_local = 0 + self.close_connection = 0 + self.range = None + self.user_agent = 'urlgrabber/%s' % __version__ + self.keepalive = 1 + self.proxies = None + self.reget = None + self.failure_callback = None + self.interrupt_callback = None + self.prefix = None + self.opener = None + self.cache_openers = True + self.timeout = None + self.text = None + self.http_headers = None + self.ftp_headers = None + self.data = None + self.urlparser = URLParser() + self.quote = None + self.ssl_ca_cert = None + self.ssl_context = None + +class URLGrabber: + """Provides easy opening of URLs with a variety of options. + + All options are specified as kwargs. Options may be specified when + the class is created and may be overridden on a per request basis. + + New objects inherit default values from default_grabber. + """ + + def __init__(self, **kwargs): + self.opts = URLGrabberOptions(**kwargs) + + def _retry(self, opts, func, *args): + tries = 0 + while 1: + # there are only two ways out of this loop. The second has + # several "sub-ways" + # 1) via the return in the "try" block + # 2) by some exception being raised + # a) an excepton is raised that we don't "except" + # b) a callback raises ANY exception + # c) we're not retry-ing or have run out of retries + # d) the URLGrabError code is not in retrycodes + # beware of infinite loops :) + tries = tries + 1 + exception = None + retrycode = None + callback = None + if DEBUG: DEBUG.info('attempt %i/%s: %s', + tries, opts.retry, args[0]) + try: + r = apply(func, (opts,) + args, {}) + if DEBUG: DEBUG.info('success') + return r + except URLGrabError, e: + exception = e + callback = opts.failure_callback + retrycode = e.errno + except KeyboardInterrupt, e: + exception = e + callback = opts.interrupt_callback + + if DEBUG: DEBUG.info('exception: %s', exception) + if callback: + if DEBUG: DEBUG.info('calling callback: %s', callback) + cb_func, cb_args, cb_kwargs = self._make_callback(callback) + obj = CallbackObject(exception=exception, url=args[0], + tries=tries, retry=opts.retry) + cb_func(obj, *cb_args, **cb_kwargs) + + if (opts.retry is None) or (tries == opts.retry): + if DEBUG: DEBUG.info('retries exceeded, re-raising') + raise + + if (retrycode is not None) and (retrycode not in opts.retrycodes): + if DEBUG: DEBUG.info('retrycode (%i) not in list %s, re-raising', + retrycode, opts.retrycodes) + raise + + def urlopen(self, url, **kwargs): + """open the url and return a file object + If a progress object or throttle value specified when this + object was created, then a special file object will be + returned that supports them. The file object can be treated + like any other file object. + """ + opts = self.opts.derive(**kwargs) + (url,parts) = opts.urlparser.parse(url, opts) + def retryfunc(opts, url): + return URLGrabberFileObject(url, filename=None, opts=opts) + return self._retry(opts, retryfunc, url) + + def urlgrab(self, url, filename=None, **kwargs): + """grab the file at <url> and make a local copy at <filename> + If filename is none, the basename of the url is used. + urlgrab returns the filename of the local file, which may be + different from the passed-in filename if copy_local == 0. + """ + opts = self.opts.derive(**kwargs) + (url,parts) = opts.urlparser.parse(url, opts) + (scheme, host, path, parm, query, frag) = parts + if filename is None: + filename = os.path.basename( urllib.unquote(path) ) + if scheme == 'file' and not opts.copy_local: + # just return the name of the local file - don't make a + # copy currently + path = urllib.url2pathname(path) + if host: + path = os.path.normpath('//' + host + path) + if not os.path.exists(path): + raise URLGrabError(2, + _('Local file does not exist: %s') % (path, )) + elif not os.path.isfile(path): + raise URLGrabError(3, + _('Not a normal file: %s') % (path, )) + elif not opts.range: + return path + + def retryfunc(opts, url, filename): + fo = URLGrabberFileObject(url, filename, opts) + try: + fo._do_grab() + if not opts.checkfunc is None: + cb_func, cb_args, cb_kwargs = \ + self._make_callback(opts.checkfunc) + obj = CallbackObject() + obj.filename = filename + obj.url = url + apply(cb_func, (obj, )+cb_args, cb_kwargs) + finally: + fo.close() + return filename + + return self._retry(opts, retryfunc, url, filename) + + def urlread(self, url, limit=None, **kwargs): + """read the url into a string, up to 'limit' bytes + If the limit is exceeded, an exception will be thrown. Note + that urlread is NOT intended to be used as a way of saying + "I want the first N bytes" but rather 'read the whole file + into memory, but don't use too much' + """ + opts = self.opts.derive(**kwargs) + (url,parts) = opts.urlparser.parse(url, opts) + if limit is not None: + limit = limit + 1 + + def retryfunc(opts, url, limit): + fo = URLGrabberFileObject(url, filename=None, opts=opts) + s = '' + try: + # this is an unfortunate thing. Some file-like objects + # have a default "limit" of None, while the built-in (real) + # file objects have -1. They each break the other, so for + # now, we just force the default if necessary. + if limit is None: s = fo.read() + else: s = fo.read(limit) + + if not opts.checkfunc is None: + cb_func, cb_args, cb_kwargs = \ + self._make_callback(opts.checkfunc) + obj = CallbackObject() + obj.data = s + obj.url = url + apply(cb_func, (obj, )+cb_args, cb_kwargs) + finally: + fo.close() + return s + + s = self._retry(opts, retryfunc, url, limit) + if limit and len(s) > limit: + raise URLGrabError(8, + _('Exceeded limit (%i): %s') % (limit, url)) + return s + + def _make_callback(self, callback_obj): + if callable(callback_obj): + return callback_obj, (), {} + else: + return callback_obj + +# create the default URLGrabber used by urlXXX functions. +# NOTE: actual defaults are set in URLGrabberOptions +default_grabber = URLGrabber() + +class URLGrabberFileObject: + """This is a file-object wrapper that supports progress objects + and throttling. + + This exists to solve the following problem: lets say you want to + drop-in replace a normal open with urlopen. You want to use a + progress meter and/or throttling, but how do you do that without + rewriting your code? Answer: urlopen will return a wrapped file + object that does the progress meter and-or throttling internally. + """ + + def __init__(self, url, filename, opts): + self.url = url + self.filename = filename + self.opts = opts + self.fo = None + self._rbuf = '' + self._rbufsize = 1024*8 + self._ttime = time.time() + self._tsize = 0 + self._amount_read = 0 + self._opener = None + self._do_open() + + def __getattr__(self, name): + """This effectively allows us to wrap at the instance level. + Any attribute not found in _this_ object will be searched for + in self.fo. This includes methods.""" + if hasattr(self.fo, name): + return getattr(self.fo, name) + raise AttributeError, name + + def _get_opener(self): + """Build a urllib2 OpenerDirector based on request options.""" + if self.opts.opener: + return self.opts.opener + elif self._opener is None: + handlers = [] + need_keepalive_handler = (have_keepalive and self.opts.keepalive) + need_range_handler = (range_handlers and \ + (self.opts.range or self.opts.reget)) + # if you specify a ProxyHandler when creating the opener + # it _must_ come before all other handlers in the list or urllib2 + # chokes. + if self.opts.proxies: + handlers.append( CachedProxyHandler(self.opts.proxies) ) + + # ------------------------------------------------------- + # OK, these next few lines are a serious kludge to get + # around what I think is a bug in python 2.2's + # urllib2. The basic idea is that default handlers + # get applied first. If you override one (like a + # proxy handler), then the default gets pulled, but + # the replacement goes on the end. In the case of + # proxies, this means the normal handler picks it up + # first and the proxy isn't used. Now, this probably + # only happened with ftp or non-keepalive http, so not + # many folks saw it. The simple approach to fixing it + # is just to make sure you override the other + # conflicting defaults as well. I would LOVE to see + # these go way or be dealt with more elegantly. The + # problem isn't there after 2.2. -MDS 2005/02/24 + if not need_keepalive_handler: + handlers.append( urllib2.HTTPHandler() ) + if not need_range_handler: + handlers.append( urllib2.FTPHandler() ) + # ------------------------------------------------------- + + ssl_factory = sslfactory.get_factory(self.opts.ssl_ca_cert, + self.opts.ssl_context) + + if need_keepalive_handler: + handlers.append(HTTPHandler()) + handlers.append(HTTPSHandler(ssl_factory)) + if need_range_handler: + handlers.extend( range_handlers ) + handlers.append( auth_handler ) + if self.opts.cache_openers: + self._opener = CachedOpenerDirector(ssl_factory, *handlers) + else: + self._opener = ssl_factory.create_opener(*handlers) + # OK, I don't like to do this, but otherwise, we end up with + # TWO user-agent headers. + self._opener.addheaders = [] + return self._opener + + def _do_open(self): + opener = self._get_opener() + + req = urllib2.Request(self.url, self.opts.data) # build request object + self._add_headers(req) # add misc headers that we need + self._build_range(req) # take care of reget and byterange stuff + + fo, hdr = self._make_request(req, opener) + if self.reget_time and self.opts.reget == 'check_timestamp': + # do this if we have a local file with known timestamp AND + # we're in check_timestamp reget mode. + fetch_again = 0 + try: + modified_tuple = hdr.getdate_tz('last-modified') + modified_stamp = rfc822.mktime_tz(modified_tuple) + if modified_stamp > self.reget_time: fetch_again = 1 + except (TypeError,): + fetch_again = 1 + + if fetch_again: + # the server version is newer than the (incomplete) local + # version, so we should abandon the version we're getting + # and fetch the whole thing again. + fo.close() + self.opts.reget = None + del req.headers['Range'] + self._build_range(req) + fo, hdr = self._make_request(req, opener) + + (scheme, host, path, parm, query, frag) = urlparse.urlparse(self.url) + path = urllib.unquote(path) + if not (self.opts.progress_obj or self.opts.raw_throttle() \ + or self.opts.timeout): + # if we're not using the progress_obj, throttling, or timeout + # we can get a performance boost by going directly to + # the underlying fileobject for reads. + self.read = fo.read + if hasattr(fo, 'readline'): + self.readline = fo.readline + elif self.opts.progress_obj: + try: + length = int(hdr['Content-Length']) + length = length + self._amount_read # Account for regets + except (KeyError, ValueError, TypeError): + length = None + + self.opts.progress_obj.start(str(self.filename), + urllib.unquote(self.url), + os.path.basename(path), + length, text=self.opts.text) + self.opts.progress_obj.update(0) + (self.fo, self.hdr) = (fo, hdr) + + def _add_headers(self, req): + if self.opts.user_agent: + req.add_header('User-agent', self.opts.user_agent) + try: req_type = req.get_type() + except ValueError: req_type = None + if self.opts.http_headers and req_type in ('http', 'https'): + for h, v in self.opts.http_headers: + req.add_header(h, v) + if self.opts.ftp_headers and req_type == 'ftp': + for h, v in self.opts.ftp_headers: + req.add_header(h, v) + + def _build_range(self, req): + self.reget_time = None + self.append = 0 + reget_length = 0 + rt = None + if have_range and self.opts.reget and type(self.filename) == type(''): + # we have reget turned on and we're dumping to a file + try: + s = os.stat(self.filename) + except OSError: + pass + else: + self.reget_time = s[ST_MTIME] + reget_length = s[ST_SIZE] + + # Set initial length when regetting + self._amount_read = reget_length + + rt = reget_length, '' + self.append = 1 + + if self.opts.range: + if not have_range: + raise URLGrabError(10, _('Byte range requested but range '\ + 'support unavailable')) + rt = self.opts.range + if rt[0]: rt = (rt[0] + reget_length, rt[1]) + + if rt: + header = range_tuple_to_header(rt) + if header: req.add_header('Range', header) + + def _make_request(self, req, opener): + try: + if have_socket_timeout and self.opts.timeout: + old_to = socket.getdefaulttimeout() + socket.setdefaulttimeout(self.opts.timeout) + try: + fo = opener.open(req) + finally: + socket.setdefaulttimeout(old_to) + else: + fo = opener.open(req) + hdr = fo.info() + except ValueError, e: + raise URLGrabError(1, _('Bad URL: %s') % (e, )) + except RangeError, e: + raise URLGrabError(9, str(e)) + except urllib2.HTTPError, e: + new_e = URLGrabError(14, str(e)) + new_e.code = e.code + new_e.exception = e + raise new_e + except IOError, e: + if hasattr(e, 'reason') and have_socket_timeout and \ + isinstance(e.reason, TimeoutError): + raise URLGrabError(12, _('Timeout: %s') % (e, )) + else: + raise URLGrabError(4, _('IOError: %s') % (e, )) + except OSError, e: + raise URLGrabError(5, _('OSError: %s') % (e, )) + except HTTPException, e: + raise URLGrabError(7, _('HTTP Exception (%s): %s') % \ + (e.__class__.__name__, e)) + else: + return (fo, hdr) + + def _do_grab(self): + """dump the file to self.filename.""" + if self.append: new_fo = open(self.filename, 'ab') + else: new_fo = open(self.filename, 'wb') + bs = 1024*8 + size = 0 + + block = self.read(bs) + size = size + len(block) + while block: + new_fo.write(block) + block = self.read(bs) + size = size + len(block) + + new_fo.close() + try: + modified_tuple = self.hdr.getdate_tz('last-modified') + modified_stamp = rfc822.mktime_tz(modified_tuple) + os.utime(self.filename, (modified_stamp, modified_stamp)) + except (TypeError,), e: pass + + return size + + def _fill_buffer(self, amt=None): + """fill the buffer to contain at least 'amt' bytes by reading + from the underlying file object. If amt is None, then it will + read until it gets nothing more. It updates the progress meter + and throttles after every self._rbufsize bytes.""" + # the _rbuf test is only in this first 'if' for speed. It's not + # logically necessary + if self._rbuf and not amt is None: + L = len(self._rbuf) + if amt > L: + amt = amt - L + else: + return + + # if we've made it here, then we don't have enough in the buffer + # and we need to read more. + + buf = [self._rbuf] + bufsize = len(self._rbuf) + while amt is None or amt: + # first, delay if necessary for throttling reasons + if self.opts.raw_throttle(): + diff = self._tsize/self.opts.raw_throttle() - \ + (time.time() - self._ttime) + if diff > 0: time.sleep(diff) + self._ttime = time.time() + + # now read some data, up to self._rbufsize + if amt is None: readamount = self._rbufsize + else: readamount = min(amt, self._rbufsize) + try: + new = self.fo.read(readamount) + except socket.error, e: + raise URLGrabError(4, _('Socket Error: %s') % (e, )) + except TimeoutError, e: + raise URLGrabError(12, _('Timeout: %s') % (e, )) + except IOError, e: + raise URLGrabError(4, _('IOError: %s') %(e,)) + newsize = len(new) + if not newsize: break # no more to read + + if amt: amt = amt - newsize + buf.append(new) + bufsize = bufsize + newsize + self._tsize = newsize + self._amount_read = self._amount_read + newsize + if self.opts.progress_obj: + self.opts.progress_obj.update(self._amount_read) + + self._rbuf = string.join(buf, '') + return + + def read(self, amt=None): + self._fill_buffer(amt) + if amt is None: + s, self._rbuf = self._rbuf, '' + else: + s, self._rbuf = self._rbuf[:amt], self._rbuf[amt:] + return s + + def readline(self, limit=-1): + i = string.find(self._rbuf, '\n') + while i < 0 and not (0 < limit <= len(self._rbuf)): + L = len(self._rbuf) + self._fill_buffer(L + self._rbufsize) + if not len(self._rbuf) > L: break + i = string.find(self._rbuf, '\n', L) + + if i < 0: i = len(self._rbuf) + else: i = i+1 + if 0 <= limit < len(self._rbuf): i = limit + + s, self._rbuf = self._rbuf[:i], self._rbuf[i:] + return s + + def close(self): + if self.opts.progress_obj: + self.opts.progress_obj.end(self._amount_read) + self.fo.close() + if self.opts.close_connection: + try: self.fo.close_connection() + except: pass + +_handler_cache = [] +def CachedOpenerDirector(ssl_factory = None, *handlers): + for (cached_handlers, opener) in _handler_cache: + if cached_handlers == handlers: + for handler in opener.handlers: + handler.add_parent(opener) + return opener + if not ssl_factory: + ssl_factory = sslfactory.get_factory() + opener = ssl_factory.create_opener(*handlers) + _handler_cache.append( (handlers, opener) ) + return opener + +_proxy_cache = [] +def CachedProxyHandler(proxies): + for (pdict, handler) in _proxy_cache: + if pdict == proxies: + if DEBUG: DEBUG.debug('re-using proxy settings: %s', proxies) + break + else: + for k, v in proxies.items(): + utype, url = urllib.splittype(v) + host, other = urllib.splithost(url) + if (utype is None) or (host is None): + raise URLGrabError(13, _('Bad proxy URL: %s') % v) + + if DEBUG: DEBUG.info('creating new proxy handler: %s', proxies) + handler = urllib2.ProxyHandler(proxies) + _proxy_cache.append( (proxies, handler) ) + return handler + +##################################################################### +# DEPRECATED FUNCTIONS +def set_throttle(new_throttle): + """Deprecated. Use: default_grabber.throttle = new_throttle""" + default_grabber.throttle = new_throttle + +def set_bandwidth(new_bandwidth): + """Deprecated. Use: default_grabber.bandwidth = new_bandwidth""" + default_grabber.bandwidth = new_bandwidth + +def set_progress_obj(new_progress_obj): + """Deprecated. Use: default_grabber.progress_obj = new_progress_obj""" + default_grabber.progress_obj = new_progress_obj + +def set_user_agent(new_user_agent): + """Deprecated. Use: default_grabber.user_agent = new_user_agent""" + default_grabber.user_agent = new_user_agent + +def retrygrab(url, filename=None, copy_local=0, close_connection=0, + progress_obj=None, throttle=None, bandwidth=None, + numtries=3, retrycodes=[-1,2,4,5,6,7], checkfunc=None): + """Deprecated. Use: urlgrab() with the retry arg instead""" + kwargs = {'copy_local' : copy_local, + 'close_connection' : close_connection, + 'progress_obj' : progress_obj, + 'throttle' : throttle, + 'bandwidth' : bandwidth, + 'retry' : numtries, + 'retrycodes' : retrycodes, + 'checkfunc' : checkfunc + } + return urlgrab(url, filename, **kwargs) + + +##################################################################### +# TESTING +def _main_test(): + import sys + try: url, filename = sys.argv[1:3] + except ValueError: + print 'usage:', sys.argv[0], \ + '<url> <filename> [copy_local=0|1] [close_connection=0|1]' + sys.exit() + + kwargs = {} + for a in sys.argv[3:]: + k, v = string.split(a, '=', 1) + kwargs[k] = int(v) + + set_throttle(1.0) + set_bandwidth(32 * 1024) + print "throttle: %s, throttle bandwidth: %s B/s" % (default_grabber.throttle, + default_grabber.bandwidth) + + try: from progress import text_progress_meter + except ImportError, e: pass + else: kwargs['progress_obj'] = text_progress_meter() + + try: name = apply(urlgrab, (url, filename), kwargs) + except URLGrabError, e: print e + else: print 'LOCAL FILE:', name + + +def _retry_test(): + import sys + try: url, filename = sys.argv[1:3] + except ValueError: + print 'usage:', sys.argv[0], \ + '<url> <filename> [copy_local=0|1] [close_connection=0|1]' + sys.exit() + + kwargs = {} + for a in sys.argv[3:]: + k, v = string.split(a, '=', 1) + kwargs[k] = int(v) + + try: from progress import text_progress_meter + except ImportError, e: pass + else: kwargs['progress_obj'] = text_progress_meter() + + def cfunc(filename, hello, there='foo'): + print hello, there + import random + rnum = random.random() + if rnum < .5: + print 'forcing retry' + raise URLGrabError(-1, 'forcing retry') + if rnum < .75: + print 'forcing failure' + raise URLGrabError(-2, 'forcing immediate failure') + print 'success' + return + + kwargs['checkfunc'] = (cfunc, ('hello',), {'there':'there'}) + try: name = apply(retrygrab, (url, filename), kwargs) + except URLGrabError, e: print e + else: print 'LOCAL FILE:', name + +def _file_object_test(filename=None): + import random, cStringIO, sys + if filename is None: + filename = __file__ + print 'using file "%s" for comparisons' % filename + fo = open(filename) + s_input = fo.read() + fo.close() + + for testfunc in [_test_file_object_smallread, + _test_file_object_readall, + _test_file_object_readline, + _test_file_object_readlines]: + fo_input = cStringIO.StringIO(s_input) + fo_output = cStringIO.StringIO() + wrapper = URLGrabberFileObject(fo_input, None, 0) + print 'testing %-30s ' % testfunc.__name__, + testfunc(wrapper, fo_output) + s_output = fo_output.getvalue() + if s_output == s_input: print 'passed' + else: print 'FAILED' + +def _test_file_object_smallread(wrapper, fo_output): + while 1: + s = wrapper.read(23) + fo_output.write(s) + if not s: return + +def _test_file_object_readall(wrapper, fo_output): + s = wrapper.read() + fo_output.write(s) + +def _test_file_object_readline(wrapper, fo_output): + while 1: + s = wrapper.readline() + fo_output.write(s) + if not s: return + +def _test_file_object_readlines(wrapper, fo_output): + li = wrapper.readlines() + fo_output.write(string.join(li, '')) + +if __name__ == '__main__': + _main_test() + _retry_test() + _file_object_test('test') diff --git a/naoki/urlgrabber/keepalive.py b/naoki/urlgrabber/keepalive.py new file mode 100644 index 0000000..71393e2 --- /dev/null +++ b/naoki/urlgrabber/keepalive.py @@ -0,0 +1,617 @@ +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, +# Boston, MA 02111-1307 USA + +# This file is part of urlgrabber, a high-level cross-protocol url-grabber +# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko + +"""An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive. + +>>> import urllib2 +>>> from keepalive import HTTPHandler +>>> keepalive_handler = HTTPHandler() +>>> opener = urllib2.build_opener(keepalive_handler) +>>> urllib2.install_opener(opener) +>>> +>>> fo = urllib2.urlopen('http://www.python.org') + +If a connection to a given host is requested, and all of the existing +connections are still in use, another connection will be opened. If +the handler tries to use an existing connection but it fails in some +way, it will be closed and removed from the pool. + +To remove the handler, simply re-run build_opener with no arguments, and +install that opener. + +You can explicitly close connections by using the close_connection() +method of the returned file-like object (described below) or you can +use the handler methods: + + close_connection(host) + close_all() + open_connections() + +NOTE: using the close_connection and close_all methods of the handler +should be done with care when using multiple threads. + * there is nothing that prevents another thread from creating new + connections immediately after connections are closed + * no checks are done to prevent in-use connections from being closed + +>>> keepalive_handler.close_all() + +EXTRA ATTRIBUTES AND METHODS + + Upon a status of 200, the object returned has a few additional + attributes and methods, which should not be used if you want to + remain consistent with the normal urllib2-returned objects: + + close_connection() - close the connection to the host + readlines() - you know, readlines() + status - the return status (ie 404) + reason - english translation of status (ie 'File not found') + + If you want the best of both worlds, use this inside an + AttributeError-catching try: + + >>> try: status = fo.status + >>> except AttributeError: status = None + + Unfortunately, these are ONLY there if status == 200, so it's not + easy to distinguish between non-200 responses. The reason is that + urllib2 tries to do clever things with error codes 301, 302, 401, + and 407, and it wraps the object upon return. + + For python versions earlier than 2.4, you can avoid this fancy error + handling by setting the module-level global HANDLE_ERRORS to zero. + You see, prior to 2.4, it's the HTTP Handler's job to determine what + to handle specially, and what to just pass up. HANDLE_ERRORS == 0 + means "pass everything up". In python 2.4, however, this job no + longer belongs to the HTTP Handler and is now done by a NEW handler, + HTTPErrorProcessor. Here's the bottom line: + + python version < 2.4 + HANDLE_ERRORS == 1 (default) pass up 200, treat the rest as + errors + HANDLE_ERRORS == 0 pass everything up, error processing is + left to the calling code + python version >= 2.4 + HANDLE_ERRORS == 1 pass up 200, treat the rest as errors + HANDLE_ERRORS == 0 (default) pass everything up, let the + other handlers (specifically, + HTTPErrorProcessor) decide what to do + + In practice, setting the variable either way makes little difference + in python 2.4, so for the most consistent behavior across versions, + you probably just want to use the defaults, which will give you + exceptions on errors. + +""" + +# $Id: keepalive.py,v 1.16 2006/09/22 00:58:05 mstenner Exp $ + +import urllib2 +import httplib +import socket +import thread + +DEBUG = None + +import sslfactory + +import sys +if sys.version_info < (2, 4): HANDLE_ERRORS = 1 +else: HANDLE_ERRORS = 0 + +class ConnectionManager: + """ + The connection manager must be able to: + * keep track of all existing + """ + def __init__(self): + self._lock = thread.allocate_lock() + self._hostmap = {} # map hosts to a list of connections + self._connmap = {} # map connections to host + self._readymap = {} # map connection to ready state + + def add(self, host, connection, ready): + self._lock.acquire() + try: + if not self._hostmap.has_key(host): self._hostmap[host] = [] + self._hostmap[host].append(connection) + self._connmap[connection] = host + self._readymap[connection] = ready + finally: + self._lock.release() + + def remove(self, connection): + self._lock.acquire() + try: + try: + host = self._connmap[connection] + except KeyError: + pass + else: + del self._connmap[connection] + del self._readymap[connection] + self._hostmap[host].remove(connection) + if not self._hostmap[host]: del self._hostmap[host] + finally: + self._lock.release() + + def set_ready(self, connection, ready): + try: self._readymap[connection] = ready + except KeyError: pass + + def get_ready_conn(self, host): + conn = None + self._lock.acquire() + try: + if self._hostmap.has_key(host): + for c in self._hostmap[host]: + if self._readymap[c]: + self._readymap[c] = 0 + conn = c + break + finally: + self._lock.release() + return conn + + def get_all(self, host=None): + if host: + return list(self._hostmap.get(host, [])) + else: + return dict(self._hostmap) + +class KeepAliveHandler: + def __init__(self): + self._cm = ConnectionManager() + + #### Connection Management + def open_connections(self): + """return a list of connected hosts and the number of connections + to each. [('foo.com:80', 2), ('bar.org', 1)]""" + return [(host, len(li)) for (host, li) in self._cm.get_all().items()] + + def close_connection(self, host): + """close connection(s) to <host> + host is the host:port spec, as in 'www.cnn.com:8080' as passed in. + no error occurs if there is no connection to that host.""" + for h in self._cm.get_all(host): + self._cm.remove(h) + h.close() + + def close_all(self): + """close all open connections""" + for host, conns in self._cm.get_all().items(): + for h in conns: + self._cm.remove(h) + h.close() + + def _request_closed(self, request, host, connection): + """tells us that this request is now closed and the the + connection is ready for another request""" + self._cm.set_ready(connection, 1) + + def _remove_connection(self, host, connection, close=0): + if close: connection.close() + self._cm.remove(connection) + + #### Transaction Execution + def do_open(self, req): + host = req.get_host() + if not host: + raise urllib2.URLError('no host given') + + try: + h = self._cm.get_ready_conn(host) + while h: + r = self._reuse_connection(h, req, host) + + # if this response is non-None, then it worked and we're + # done. Break out, skipping the else block. + if r: break + + # connection is bad - possibly closed by server + # discard it and ask for the next free connection + h.close() + self._cm.remove(h) + h = self._cm.get_ready_conn(host) + else: + # no (working) free connections were found. Create a new one. + h = self._get_connection(host) + if DEBUG: DEBUG.info("creating new connection to %s (%d)", + host, id(h)) + self._cm.add(host, h, 0) + self._start_transaction(h, req) + r = h.getresponse() + except (socket.error, httplib.HTTPException), err: + raise urllib2.URLError(err) + + # if not a persistent connection, don't try to reuse it + if r.will_close: self._cm.remove(h) + + if DEBUG: DEBUG.info("STATUS: %s, %s", r.status, r.reason) + r._handler = self + r._host = host + r._url = req.get_full_url() + r._connection = h + r.code = r.status + r.headers = r.msg + r.msg = r.reason + + if r.status == 200 or not HANDLE_ERRORS: + return r + else: + return self.parent.error('http', req, r, + r.status, r.msg, r.headers) + + def _reuse_connection(self, h, req, host): + """start the transaction with a re-used connection + return a response object (r) upon success or None on failure. + This DOES not close or remove bad connections in cases where + it returns. However, if an unexpected exception occurs, it + will close and remove the connection before re-raising. + """ + try: + self._start_transaction(h, req) + r = h.getresponse() + # note: just because we got something back doesn't mean it + # worked. We'll check the version below, too. + except (socket.error, httplib.HTTPException): + r = None + except: + # adding this block just in case we've missed + # something we will still raise the exception, but + # lets try and close the connection and remove it + # first. We previously got into a nasty loop + # where an exception was uncaught, and so the + # connection stayed open. On the next try, the + # same exception was raised, etc. The tradeoff is + # that it's now possible this call will raise + # a DIFFERENT exception + if DEBUG: DEBUG.error("unexpected exception - closing " + \ + "connection to %s (%d)", host, id(h)) + self._cm.remove(h) + h.close() + raise + + if r is None or r.version == 9: + # httplib falls back to assuming HTTP 0.9 if it gets a + # bad header back. This is most likely to happen if + # the socket has been closed by the server since we + # last used the connection. + if DEBUG: DEBUG.info("failed to re-use connection to %s (%d)", + host, id(h)) + r = None + else: + if DEBUG: DEBUG.info("re-using connection to %s (%d)", host, id(h)) + + return r + + def _start_transaction(self, h, req): + try: + if req.has_data(): + data = req.get_data() + h.putrequest('POST', req.get_selector()) + if not req.headers.has_key('Content-type'): + h.putheader('Content-type', + 'application/x-www-form-urlencoded') + if not req.headers.has_key('Content-length'): + h.putheader('Content-length', '%d' % len(data)) + else: + h.putrequest('GET', req.get_selector()) + except (socket.error, httplib.HTTPException), err: + raise urllib2.URLError(err) + + for args in self.parent.addheaders: + h.putheader(*args) + for k, v in req.headers.items(): + h.putheader(k, v) + h.endheaders() + if req.has_data(): + h.send(data) + + def _get_connection(self, host): + return NotImplementedError + +class HTTPHandler(KeepAliveHandler, urllib2.HTTPHandler): + def __init__(self): + KeepAliveHandler.__init__(self) + + def http_open(self, req): + return self.do_open(req) + + def _get_connection(self, host): + return HTTPConnection(host) + +class HTTPSHandler(KeepAliveHandler, urllib2.HTTPSHandler): + def __init__(self, ssl_factory=None): + KeepAliveHandler.__init__(self) + if not ssl_factory: + ssl_factory = sslfactory.get_factory() + self._ssl_factory = ssl_factory + + def https_open(self, req): + return self.do_open(req) + + def _get_connection(self, host): + return self._ssl_factory.get_https_connection(host) + +class HTTPResponse(httplib.HTTPResponse): + # we need to subclass HTTPResponse in order to + # 1) add readline() and readlines() methods + # 2) add close_connection() methods + # 3) add info() and geturl() methods + + # in order to add readline(), read must be modified to deal with a + # buffer. example: readline must read a buffer and then spit back + # one line at a time. The only real alternative is to read one + # BYTE at a time (ick). Once something has been read, it can't be + # put back (ok, maybe it can, but that's even uglier than this), + # so if you THEN do a normal read, you must first take stuff from + # the buffer. + + # the read method wraps the original to accomodate buffering, + # although read() never adds to the buffer. + # Both readline and readlines have been stolen with almost no + # modification from socket.py + + + def __init__(self, sock, debuglevel=0, strict=0, method=None): + if method: # the httplib in python 2.3 uses the method arg + httplib.HTTPResponse.__init__(self, sock, debuglevel, method) + else: # 2.2 doesn't + httplib.HTTPResponse.__init__(self, sock, debuglevel) + self.fileno = sock.fileno + self.code = None + self._rbuf = '' + self._rbufsize = 8096 + self._handler = None # inserted by the handler later + self._host = None # (same) + self._url = None # (same) + self._connection = None # (same) + + _raw_read = httplib.HTTPResponse.read + + def close(self): + if self.fp: + self.fp.close() + self.fp = None + if self._handler: + self._handler._request_closed(self, self._host, + self._connection) + + def close_connection(self): + self._handler._remove_connection(self._host, self._connection, close=1) + self.close() + + def info(self): + return self.headers + + def geturl(self): + return self._url + + def read(self, amt=None): + # the _rbuf test is only in this first if for speed. It's not + # logically necessary + if self._rbuf and not amt is None: + L = len(self._rbuf) + if amt > L: + amt -= L + else: + s = self._rbuf[:amt] + self._rbuf = self._rbuf[amt:] + return s + + s = self._rbuf + self._raw_read(amt) + self._rbuf = '' + return s + + def readline(self, limit=-1): + data = "" + i = self._rbuf.find('\n') + while i < 0 and not (0 < limit <= len(self._rbuf)): + new = self._raw_read(self._rbufsize) + if not new: break + i = new.find('\n') + if i >= 0: i = i + len(self._rbuf) + self._rbuf = self._rbuf + new + if i < 0: i = len(self._rbuf) + else: i = i+1 + if 0 <= limit < len(self._rbuf): i = limit + data, self._rbuf = self._rbuf[:i], self._rbuf[i:] + return data + + def readlines(self, sizehint = 0): + total = 0 + list = [] + while 1: + line = self.readline() + if not line: break + list.append(line) + total += len(line) + if sizehint and total >= sizehint: + break + return list + + +class HTTPConnection(httplib.HTTPConnection): + # use the modified response class + response_class = HTTPResponse + +class HTTPSConnection(httplib.HTTPSConnection): + response_class = HTTPResponse + +######################################################################### +##### TEST FUNCTIONS +######################################################################### + +def error_handler(url): + global HANDLE_ERRORS + orig = HANDLE_ERRORS + keepalive_handler = HTTPHandler() + opener = urllib2.build_opener(keepalive_handler) + urllib2.install_opener(opener) + pos = {0: 'off', 1: 'on'} + for i in (0, 1): + print " fancy error handling %s (HANDLE_ERRORS = %i)" % (pos[i], i) + HANDLE_ERRORS = i + try: + fo = urllib2.urlopen(url) + foo = fo.read() + fo.close() + try: status, reason = fo.status, fo.reason + except AttributeError: status, reason = None, None + except IOError, e: + print " EXCEPTION: %s" % e + raise + else: + print " status = %s, reason = %s" % (status, reason) + HANDLE_ERRORS = orig + hosts = keepalive_handler.open_connections() + print "open connections:", hosts + keepalive_handler.close_all() + +def continuity(url): + import md5 + format = '%25s: %s' + + # first fetch the file with the normal http handler + opener = urllib2.build_opener() + urllib2.install_opener(opener) + fo = urllib2.urlopen(url) + foo = fo.read() + fo.close() + m = md5.new(foo) + print format % ('normal urllib', m.hexdigest()) + + # now install the keepalive handler and try again + opener = urllib2.build_opener(HTTPHandler()) + urllib2.install_opener(opener) + + fo = urllib2.urlopen(url) + foo = fo.read() + fo.close() + m = md5.new(foo) + print format % ('keepalive read', m.hexdigest()) + + fo = urllib2.urlopen(url) + foo = '' + while 1: + f = fo.readline() + if f: foo = foo + f + else: break + fo.close() + m = md5.new(foo) + print format % ('keepalive readline', m.hexdigest()) + +def comp(N, url): + print ' making %i connections to:\n %s' % (N, url) + + sys.stdout.write(' first using the normal urllib handlers') + # first use normal opener + opener = urllib2.build_opener() + urllib2.install_opener(opener) + t1 = fetch(N, url) + print ' TIME: %.3f s' % t1 + + sys.stdout.write(' now using the keepalive handler ') + # now install the keepalive handler and try again + opener = urllib2.build_opener(HTTPHandler()) + urllib2.install_opener(opener) + t2 = fetch(N, url) + print ' TIME: %.3f s' % t2 + print ' improvement factor: %.2f' % (t1/t2, ) + +def fetch(N, url, delay=0): + import time + lens = [] + starttime = time.time() + for i in range(N): + if delay and i > 0: time.sleep(delay) + fo = urllib2.urlopen(url) + foo = fo.read() + fo.close() + lens.append(len(foo)) + diff = time.time() - starttime + + j = 0 + for i in lens[1:]: + j = j + 1 + if not i == lens[0]: + print "WARNING: inconsistent length on read %i: %i" % (j, i) + + return diff + +def test_timeout(url): + global DEBUG + dbbackup = DEBUG + class FakeLogger: + def debug(self, msg, *args): print msg % args + info = warning = error = debug + DEBUG = FakeLogger() + print " fetching the file to establish a connection" + fo = urllib2.urlopen(url) + data1 = fo.read() + fo.close() + + i = 20 + print " waiting %i seconds for the server to close the connection" % i + while i > 0: + sys.stdout.write('\r %2i' % i) + sys.stdout.flush() + time.sleep(1) + i -= 1 + sys.stderr.write('\r') + + print " fetching the file a second time" + fo = urllib2.urlopen(url) + data2 = fo.read() + fo.close() + + if data1 == data2: + print ' data are identical' + else: + print ' ERROR: DATA DIFFER' + + DEBUG = dbbackup + + +def test(url, N=10): + print "checking error hander (do this on a non-200)" + try: error_handler(url) + except IOError, e: + print "exiting - exception will prevent further tests" + sys.exit() + print + print "performing continuity test (making sure stuff isn't corrupted)" + continuity(url) + print + print "performing speed comparison" + comp(N, url) + print + print "performing dropped-connection check" + test_timeout(url) + +if __name__ == '__main__': + import time + import sys + try: + N = int(sys.argv[1]) + url = sys.argv[2] + except: + print "%s <integer> <url>" % sys.argv[0] + else: + test(url, N) diff --git a/naoki/urlgrabber/mirror.py b/naoki/urlgrabber/mirror.py new file mode 100644 index 0000000..9664c6b --- /dev/null +++ b/naoki/urlgrabber/mirror.py @@ -0,0 +1,458 @@ +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, +# Boston, MA 02111-1307 USA + +# This file is part of urlgrabber, a high-level cross-protocol url-grabber +# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko + +"""Module for downloading files from a pool of mirrors + +DESCRIPTION + + This module provides support for downloading files from a pool of + mirrors with configurable failover policies. To a large extent, the + failover policy is chosen by using different classes derived from + the main class, MirrorGroup. + + Instances of MirrorGroup (and cousins) act very much like URLGrabber + instances in that they have urlread, urlgrab, and urlopen methods. + They can therefore, be used in very similar ways. + + from urlgrabber.grabber import URLGrabber + from urlgrabber.mirror import MirrorGroup + gr = URLGrabber() + mg = MirrorGroup(gr, ['http://foo.com/some/directory/', + 'http://bar.org/maybe/somewhere/else/', + 'ftp://baz.net/some/other/place/entirely/'] + mg.urlgrab('relative/path.zip') + + The assumption is that all mirrors are identical AFTER the base urls + specified, so that any mirror can be used to fetch any file. + +FAILOVER + + The failover mechanism is designed to be customized by subclassing + from MirrorGroup to change the details of the behavior. In general, + the classes maintain a master mirror list and a "current mirror" + index. When a download is initiated, a copy of this list and index + is created for that download only. The specific failover policy + depends on the class used, and so is documented in the class + documentation. Note that ANY behavior of the class can be + overridden, so any failover policy at all is possible (although + you may need to change the interface in extreme cases). + +CUSTOMIZATION + + Most customization of a MirrorGroup object is done at instantiation + time (or via subclassing). There are four major types of + customization: + + 1) Pass in a custom urlgrabber - The passed in urlgrabber will be + used (by default... see #2) for the grabs, so options to it + apply for the url-fetching + + 2) Custom mirror list - Mirror lists can simply be a list of + stings mirrors (as shown in the example above) but each can + also be a dict, allowing for more options. For example, the + first mirror in the list above could also have been: + + {'mirror': 'http://foo.com/some/directory/', + 'grabber': <a custom grabber to be used for this mirror>, + 'kwargs': { <a dict of arguments passed to the grabber> }} + + All mirrors are converted to this format internally. If + 'grabber' is omitted, the default grabber will be used. If + kwargs are omitted, then (duh) they will not be used. + + 3) Pass keyword arguments when instantiating the mirror group. + See, for example, the failure_callback argument. + + 4) Finally, any kwargs passed in for the specific file (to the + urlgrab method, for example) will be folded in. The options + passed into the grabber's urlXXX methods will override any + options specified in a custom mirror dict. + +""" + +# $Id: mirror.py,v 1.14 2006/02/22 18:26:46 mstenner Exp $ + +import random +import thread # needed for locking to make this threadsafe + +from grabber import URLGrabError, CallbackObject, DEBUG + +try: + from i18n import _ +except ImportError, msg: + def _(st): return st + +class GrabRequest: + """This is a dummy class used to hold information about the specific + request. For example, a single file. By maintaining this information + separately, we can accomplish two things: + + 1) make it a little easier to be threadsafe + 2) have request-specific parameters + """ + pass + +class MirrorGroup: + """Base Mirror class + + Instances of this class are built with a grabber object and a list + of mirrors. Then all calls to urlXXX should be passed relative urls. + The requested file will be searched for on the first mirror. If the + grabber raises an exception (possibly after some retries) then that + mirror will be removed from the list, and the next will be attempted. + If all mirrors are exhausted, then an exception will be raised. + + MirrorGroup has the following failover policy: + + * downloads begin with the first mirror + + * by default (see default_action below) a failure (after retries) + causes it to increment the local AND master indices. Also, + the current mirror is removed from the local list (but NOT the + master list - the mirror can potentially be used for other + files) + + * if the local list is ever exhausted, a URLGrabError will be + raised (errno=256, no more mirrors) + + OPTIONS + + In addition to the required arguments "grabber" and "mirrors", + MirrorGroup also takes the following optional arguments: + + default_action + + A dict that describes the actions to be taken upon failure + (after retries). default_action can contain any of the + following keys (shown here with their default values): + + default_action = {'increment': 1, + 'increment_master': 1, + 'remove': 1, + 'remove_master': 0, + 'fail': 0} + + In this context, 'increment' means "use the next mirror" and + 'remove' means "never use this mirror again". The two + 'master' values refer to the instance-level mirror list (used + for all files), whereas the non-master values refer to the + current download only. + + The 'fail' option will cause immediate failure by re-raising + the exception and no further attempts to get the current + download. + + This dict can be set at instantiation time, + mg = MirrorGroup(grabber, mirrors, default_action={'fail':1}) + at method-execution time (only applies to current fetch), + filename = mg.urlgrab(url, default_action={'increment': 0}) + or by returning an action dict from the failure_callback + return {'fail':0} + in increasing precedence. + + If all three of these were done, the net result would be: + {'increment': 0, # set in method + 'increment_master': 1, # class default + 'remove': 1, # class default + 'remove_master': 0, # class default + 'fail': 0} # set at instantiation, reset + # from callback + + failure_callback + + this is a callback that will be called when a mirror "fails", + meaning the grabber raises some URLGrabError. If this is a + tuple, it is interpreted to be of the form (cb, args, kwargs) + where cb is the actual callable object (function, method, + etc). Otherwise, it is assumed to be the callable object + itself. The callback will be passed a grabber.CallbackObject + instance along with args and kwargs (if present). The following + attributes are defined withing the instance: + + obj.exception = < exception that was raised > + obj.mirror = < the mirror that was tried > + obj.relative_url = < url relative to the mirror > + obj.url = < full url that failed > + # .url is just the combination of .mirror + # and .relative_url + + The failure callback can return an action dict, as described + above. + + Like default_action, the failure_callback can be set at + instantiation time or when the urlXXX method is called. In + the latter case, it applies only for that fetch. + + The callback can re-raise the exception quite easily. For + example, this is a perfectly adequate callback function: + + def callback(obj): raise obj.exception + + WARNING: do not save the exception object (or the + CallbackObject instance). As they contain stack frame + references, they can lead to circular references. + + Notes: + * The behavior can be customized by deriving and overriding the + 'CONFIGURATION METHODS' + * The 'grabber' instance is kept as a reference, not copied. + Therefore, the grabber instance can be modified externally + and changes will take effect immediately. + """ + + # notes on thread-safety: + + # A GrabRequest should never be shared by multiple threads because + # it's never saved inside the MG object and never returned outside it. + # therefore, it should be safe to access/modify grabrequest data + # without a lock. However, accessing the mirrors and _next attributes + # of the MG itself must be done when locked to prevent (for example) + # removal of the wrong mirror. + + ############################################################## + # CONFIGURATION METHODS - intended to be overridden to + # customize behavior + def __init__(self, grabber, mirrors, **kwargs): + """Initialize the MirrorGroup object. + + REQUIRED ARGUMENTS + + grabber - URLGrabber instance + mirrors - a list of mirrors + + OPTIONAL ARGUMENTS + + failure_callback - callback to be used when a mirror fails + default_action - dict of failure actions + + See the module-level and class level documentation for more + details. + """ + + # OVERRIDE IDEAS: + # shuffle the list to randomize order + self.grabber = grabber + self.mirrors = self._parse_mirrors(mirrors) + self._next = 0 + self._lock = thread.allocate_lock() + self.default_action = None + self._process_kwargs(kwargs) + + # if these values are found in **kwargs passed to one of the urlXXX + # methods, they will be stripped before getting passed on to the + # grabber + options = ['default_action', 'failure_callback'] + + def _process_kwargs(self, kwargs): + self.failure_callback = kwargs.get('failure_callback') + self.default_action = kwargs.get('default_action') + + def _parse_mirrors(self, mirrors): + parsed_mirrors = [] + for m in mirrors: + if type(m) == type(''): m = {'mirror': m} + parsed_mirrors.append(m) + return parsed_mirrors + + def _load_gr(self, gr): + # OVERRIDE IDEAS: + # shuffle gr list + self._lock.acquire() + gr.mirrors = list(self.mirrors) + gr._next = self._next + self._lock.release() + + def _get_mirror(self, gr): + # OVERRIDE IDEAS: + # return a random mirror so that multiple mirrors get used + # even without failures. + if not gr.mirrors: + raise URLGrabError(256, _('No more mirrors to try.')) + return gr.mirrors[gr._next] + + def _failure(self, gr, cb_obj): + # OVERRIDE IDEAS: + # inspect the error - remove=1 for 404, remove=2 for connection + # refused, etc. (this can also be done via + # the callback) + cb = gr.kw.get('failure_callback') or self.failure_callback + if cb: + if type(cb) == type( () ): + cb, args, kwargs = cb + else: + args, kwargs = (), {} + action = cb(cb_obj, *args, **kwargs) or {} + else: + action = {} + # XXXX - decide - there are two ways to do this + # the first is action-overriding as a whole - use the entire action + # or fall back on module level defaults + #action = action or gr.kw.get('default_action') or self.default_action + # the other is to fall through for each element in the action dict + a = dict(self.default_action or {}) + a.update(gr.kw.get('default_action', {})) + a.update(action) + action = a + self.increment_mirror(gr, action) + if action and action.get('fail', 0): raise + + def increment_mirror(self, gr, action={}): + """Tell the mirror object increment the mirror index + + This increments the mirror index, which amounts to telling the + mirror object to use a different mirror (for this and future + downloads). + + This is a SEMI-public method. It will be called internally, + and you may never need to call it. However, it is provided + (and is made public) so that the calling program can increment + the mirror choice for methods like urlopen. For example, with + urlopen, there's no good way for the mirror group to know that + an error occurs mid-download (it's already returned and given + you the file object). + + remove --- can have several values + 0 do not remove the mirror from the list + 1 remove the mirror for this download only + 2 remove the mirror permanently + + beware of remove=0 as it can lead to infinite loops + """ + badmirror = gr.mirrors[gr._next] + + self._lock.acquire() + try: + ind = self.mirrors.index(badmirror) + except ValueError: + pass + else: + if action.get('remove_master', 0): + del self.mirrors[ind] + elif self._next == ind and action.get('increment_master', 1): + self._next += 1 + if self._next >= len(self.mirrors): self._next = 0 + self._lock.release() + + if action.get('remove', 1): + del gr.mirrors[gr._next] + elif action.get('increment', 1): + gr._next += 1 + if gr._next >= len(gr.mirrors): gr._next = 0 + + if DEBUG: + grm = [m['mirror'] for m in gr.mirrors] + DEBUG.info('GR mirrors: [%s] %i', ' '.join(grm), gr._next) + selfm = [m['mirror'] for m in self.mirrors] + DEBUG.info('MAIN mirrors: [%s] %i', ' '.join(selfm), self._next) + + ##################################################################### + # NON-CONFIGURATION METHODS + # these methods are designed to be largely workhorse methods that + # are not intended to be overridden. That doesn't mean you can't; + # if you want to, feel free, but most things can be done by + # by overriding the configuration methods :) + + def _join_url(self, base_url, rel_url): + if base_url.endswith('/') or rel_url.startswith('/'): + return base_url + rel_url + else: + return base_url + '/' + rel_url + + def _mirror_try(self, func, url, kw): + gr = GrabRequest() + gr.func = func + gr.url = url + gr.kw = dict(kw) + self._load_gr(gr) + + for k in self.options: + try: del kw[k] + except KeyError: pass + + while 1: + mirrorchoice = self._get_mirror(gr) + fullurl = self._join_url(mirrorchoice['mirror'], gr.url) + kwargs = dict(mirrorchoice.get('kwargs', {})) + kwargs.update(kw) + grabber = mirrorchoice.get('grabber') or self.grabber + func_ref = getattr(grabber, func) + if DEBUG: DEBUG.info('MIRROR: trying %s -> %s', url, fullurl) + try: + return func_ref( *(fullurl,), **kwargs ) + except URLGrabError, e: + if DEBUG: DEBUG.info('MIRROR: failed') + obj = CallbackObject() + obj.exception = e + obj.mirror = mirrorchoice['mirror'] + obj.relative_url = gr.url + obj.url = fullurl + self._failure(gr, obj) + + def urlgrab(self, url, filename=None, **kwargs): + kw = dict(kwargs) + kw['filename'] = filename + func = 'urlgrab' + return self._mirror_try(func, url, kw) + + def urlopen(self, url, **kwargs): + kw = dict(kwargs) + func = 'urlopen' + return self._mirror_try(func, url, kw) + + def urlread(self, url, limit=None, **kwargs): + kw = dict(kwargs) + kw['limit'] = limit + func = 'urlread' + return self._mirror_try(func, url, kw) + + +class MGRandomStart(MirrorGroup): + """A mirror group that starts at a random mirror in the list. + + This behavior of this class is identical to MirrorGroup, except that + it starts at a random location in the mirror list. + """ + + def __init__(self, grabber, mirrors, **kwargs): + """Initialize the object + + The arguments for intialization are the same as for MirrorGroup + """ + MirrorGroup.__init__(self, grabber, mirrors, **kwargs) + self._next = random.randrange(len(mirrors)) + +class MGRandomOrder(MirrorGroup): + """A mirror group that uses mirrors in a random order. + + This behavior of this class is identical to MirrorGroup, except that + it uses the mirrors in a random order. Note that the order is set at + initialization time and fixed thereafter. That is, it does not pick a + random mirror after each failure. + """ + + def __init__(self, grabber, mirrors, **kwargs): + """Initialize the object + + The arguments for intialization are the same as for MirrorGroup + """ + MirrorGroup.__init__(self, grabber, mirrors, **kwargs) + random.shuffle(self.mirrors) + +if __name__ == '__main__': + pass diff --git a/naoki/urlgrabber/progress.py b/naoki/urlgrabber/progress.py new file mode 100644 index 0000000..02db524 --- /dev/null +++ b/naoki/urlgrabber/progress.py @@ -0,0 +1,530 @@ +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, +# Boston, MA 02111-1307 USA + +# This file is part of urlgrabber, a high-level cross-protocol url-grabber +# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko + +# $Id: progress.py,v 1.7 2005/08/19 21:59:07 mstenner Exp $ + +import sys +import time +import math +import thread + +class BaseMeter: + def __init__(self): + self.update_period = 0.3 # seconds + + self.filename = None + self.url = None + self.basename = None + self.text = None + self.size = None + self.start_time = None + self.last_amount_read = 0 + self.last_update_time = None + self.re = RateEstimator() + + def start(self, filename=None, url=None, basename=None, + size=None, now=None, text=None): + self.filename = filename + self.url = url + self.basename = basename + self.text = text + + #size = None ######### TESTING + self.size = size + if not size is None: self.fsize = format_number(size) + 'B' + + if now is None: now = time.time() + self.start_time = now + self.re.start(size, now) + self.last_amount_read = 0 + self.last_update_time = now + self._do_start(now) + + def _do_start(self, now=None): + pass + + def update(self, amount_read, now=None): + # for a real gui, you probably want to override and put a call + # to your mainloop iteration function here + if now is None: now = time.time() + if (now >= self.last_update_time + self.update_period) or \ + not self.last_update_time: + self.re.update(amount_read, now) + self.last_amount_read = amount_read + self.last_update_time = now + self._do_update(amount_read, now) + + def _do_update(self, amount_read, now=None): + pass + + def end(self, amount_read, now=None): + if now is None: now = time.time() + self.re.update(amount_read, now) + self.last_amount_read = amount_read + self.last_update_time = now + self._do_end(amount_read, now) + + def _do_end(self, amount_read, now=None): + pass + +class TextMeter(BaseMeter): + def __init__(self, fo=sys.stderr): + BaseMeter.__init__(self) + self.fo = fo + + def _do_update(self, amount_read, now=None): + etime = self.re.elapsed_time() + fetime = format_time(etime) + fread = format_number(amount_read) + #self.size = None + if self.text is not None: + text = self.text + else: + text = self.basename + if self.size is None: + out = '\r%-60.60s %5sB %s ' % \ + (text, fread, fetime) + else: + rtime = self.re.remaining_time() + frtime = format_time(rtime) + frac = self.re.fraction_read() + bar = '='*int(25 * frac) + + out = '\r%-25.25s %3i%% |%-25.25s| %5sB %8s ETA ' % \ + (text, frac*100, bar, fread, frtime) + + self.fo.write(out) + self.fo.flush() + + def _do_end(self, amount_read, now=None): + total_time = format_time(self.re.elapsed_time()) + total_size = format_number(amount_read) + if self.text is not None: + text = self.text + else: + text = self.basename + if self.size is None: + out = '\r%-60.60s %5sB %s ' % \ + (text, total_size, total_time) + else: + bar = '='*25 + out = '\r%-25.25s %3i%% |%-25.25s| %5sB %8s ' % \ + (text, 100, bar, total_size, total_time) + self.fo.write(out + '\n') + self.fo.flush() + +text_progress_meter = TextMeter + +class MultiFileHelper(BaseMeter): + def __init__(self, master): + BaseMeter.__init__(self) + self.master = master + + def _do_start(self, now): + self.master.start_meter(self, now) + + def _do_update(self, amount_read, now): + # elapsed time since last update + self.master.update_meter(self, now) + + def _do_end(self, amount_read, now): + self.ftotal_time = format_time(now - self.start_time) + self.ftotal_size = format_number(self.last_amount_read) + self.master.end_meter(self, now) + + def failure(self, message, now=None): + self.master.failure_meter(self, message, now) + + def message(self, message): + self.master.message_meter(self, message) + +class MultiFileMeter: + helperclass = MultiFileHelper + def __init__(self): + self.meters = [] + self.in_progress_meters = [] + self._lock = thread.allocate_lock() + self.update_period = 0.3 # seconds + + self.numfiles = None + self.finished_files = 0 + self.failed_files = 0 + self.open_files = 0 + self.total_size = None + self.failed_size = 0 + self.start_time = None + self.finished_file_size = 0 + self.last_update_time = None + self.re = RateEstimator() + + def start(self, numfiles=None, total_size=None, now=None): + if now is None: now = time.time() + self.numfiles = numfiles + self.finished_files = 0 + self.failed_files = 0 + self.open_files = 0 + self.total_size = total_size + self.failed_size = 0 + self.start_time = now + self.finished_file_size = 0 + self.last_update_time = now + self.re.start(total_size, now) + self._do_start(now) + + def _do_start(self, now): + pass + + def end(self, now=None): + if now is None: now = time.time() + self._do_end(now) + + def _do_end(self, now): + pass + + def lock(self): self._lock.acquire() + def unlock(self): self._lock.release() + + ########################################################### + # child meter creation and destruction + def newMeter(self): + newmeter = self.helperclass(self) + self.meters.append(newmeter) + return newmeter + + def removeMeter(self, meter): + self.meters.remove(meter) + + ########################################################### + # child functions - these should only be called by helpers + def start_meter(self, meter, now): + if not meter in self.meters: + raise ValueError('attempt to use orphaned meter') + self._lock.acquire() + try: + if not meter in self.in_progress_meters: + self.in_progress_meters.append(meter) + self.open_files += 1 + finally: + self._lock.release() + self._do_start_meter(meter, now) + + def _do_start_meter(self, meter, now): + pass + + def update_meter(self, meter, now): + if not meter in self.meters: + raise ValueError('attempt to use orphaned meter') + if (now >= self.last_update_time + self.update_period) or \ + not self.last_update_time: + self.re.update(self._amount_read(), now) + self.last_update_time = now + self._do_update_meter(meter, now) + + def _do_update_meter(self, meter, now): + pass + + def end_meter(self, meter, now): + if not meter in self.meters: + raise ValueError('attempt to use orphaned meter') + self._lock.acquire() + try: + try: self.in_progress_meters.remove(meter) + except ValueError: pass + self.open_files -= 1 + self.finished_files += 1 + self.finished_file_size += meter.last_amount_read + finally: + self._lock.release() + self._do_end_meter(meter, now) + + def _do_end_meter(self, meter, now): + pass + + def failure_meter(self, meter, message, now): + if not meter in self.meters: + raise ValueError('attempt to use orphaned meter') + self._lock.acquire() + try: + try: self.in_progress_meters.remove(meter) + except ValueError: pass + self.open_files -= 1 + self.failed_files += 1 + if meter.size and self.failed_size is not None: + self.failed_size += meter.size + else: + self.failed_size = None + finally: + self._lock.release() + self._do_failure_meter(meter, message, now) + + def _do_failure_meter(self, meter, message, now): + pass + + def message_meter(self, meter, message): + pass + + ######################################################## + # internal functions + def _amount_read(self): + tot = self.finished_file_size + for m in self.in_progress_meters: + tot += m.last_amount_read + return tot + + +class TextMultiFileMeter(MultiFileMeter): + def __init__(self, fo=sys.stderr): + self.fo = fo + MultiFileMeter.__init__(self) + + # files: ###/### ###% data: ######/###### ###% time: ##:##:##/##:##:## + def _do_update_meter(self, meter, now): + self._lock.acquire() + try: + format = "files: %3i/%-3i %3i%% data: %6.6s/%-6.6s %3i%% " \ + "time: %8.8s/%8.8s" + df = self.finished_files + tf = self.numfiles or 1 + pf = 100 * float(df)/tf + 0.49 + dd = self.re.last_amount_read + td = self.total_size + pd = 100 * (self.re.fraction_read() or 0) + 0.49 + dt = self.re.elapsed_time() + rt = self.re.remaining_time() + if rt is None: tt = None + else: tt = dt + rt + + fdd = format_number(dd) + 'B' + ftd = format_number(td) + 'B' + fdt = format_time(dt, 1) + ftt = format_time(tt, 1) + + out = '%-79.79s' % (format % (df, tf, pf, fdd, ftd, pd, fdt, ftt)) + self.fo.write('\r' + out) + self.fo.flush() + finally: + self._lock.release() + + def _do_end_meter(self, meter, now): + self._lock.acquire() + try: + format = "%-30.30s %6.6s %8.8s %9.9s" + fn = meter.basename + size = meter.last_amount_read + fsize = format_number(size) + 'B' + et = meter.re.elapsed_time() + fet = format_time(et, 1) + frate = format_number(size / et) + 'B/s' + + out = '%-79.79s' % (format % (fn, fsize, fet, frate)) + self.fo.write('\r' + out + '\n') + finally: + self._lock.release() + self._do_update_meter(meter, now) + + def _do_failure_meter(self, meter, message, now): + self._lock.acquire() + try: + format = "%-30.30s %6.6s %s" + fn = meter.basename + if type(message) in (type(''), type(u'')): + message = message.splitlines() + if not message: message = [''] + out = '%-79s' % (format % (fn, 'FAILED', message[0] or '')) + self.fo.write('\r' + out + '\n') + for m in message[1:]: self.fo.write(' ' + m + '\n') + self._lock.release() + finally: + self._do_update_meter(meter, now) + + def message_meter(self, meter, message): + self._lock.acquire() + try: + pass + finally: + self._lock.release() + + def _do_end(self, now): + self._do_update_meter(None, now) + self._lock.acquire() + try: + self.fo.write('\n') + self.fo.flush() + finally: + self._lock.release() + +###################################################################### +# support classes and functions + +class RateEstimator: + def __init__(self, timescale=5.0): + self.timescale = timescale + + def start(self, total=None, now=None): + if now is None: now = time.time() + self.total = total + self.start_time = now + self.last_update_time = now + self.last_amount_read = 0 + self.ave_rate = None + + def update(self, amount_read, now=None): + if now is None: now = time.time() + if amount_read == 0: + # if we just started this file, all bets are off + self.last_update_time = now + self.last_amount_read = 0 + self.ave_rate = None + return + + #print 'times', now, self.last_update_time + time_diff = now - self.last_update_time + read_diff = amount_read - self.last_amount_read + self.last_update_time = now + self.last_amount_read = amount_read + self.ave_rate = self._temporal_rolling_ave(\ + time_diff, read_diff, self.ave_rate, self.timescale) + #print 'results', time_diff, read_diff, self.ave_rate + + ##################################################################### + # result methods + def average_rate(self): + "get the average transfer rate (in bytes/second)" + return self.ave_rate + + def elapsed_time(self): + "the time between the start of the transfer and the most recent update" + return self.last_update_time - self.start_time + + def remaining_time(self): + "estimated time remaining" + if not self.ave_rate or not self.total: return None + return (self.total - self.last_amount_read) / self.ave_rate + + def fraction_read(self): + """the fraction of the data that has been read + (can be None for unknown transfer size)""" + if self.total is None: return None + elif self.total == 0: return 1.0 + else: return float(self.last_amount_read)/self.total + + ######################################################################### + # support methods + def _temporal_rolling_ave(self, time_diff, read_diff, last_ave, timescale): + """a temporal rolling average performs smooth averaging even when + updates come at irregular intervals. This is performed by scaling + the "epsilon" according to the time since the last update. + Specifically, epsilon = time_diff / timescale + + As a general rule, the average will take on a completely new value + after 'timescale' seconds.""" + epsilon = time_diff / timescale + if epsilon > 1: epsilon = 1.0 + return self._rolling_ave(time_diff, read_diff, last_ave, epsilon) + + def _rolling_ave(self, time_diff, read_diff, last_ave, epsilon): + """perform a "rolling average" iteration + a rolling average "folds" new data into an existing average with + some weight, epsilon. epsilon must be between 0.0 and 1.0 (inclusive) + a value of 0.0 means only the old value (initial value) counts, + and a value of 1.0 means only the newest value is considered.""" + + try: + recent_rate = read_diff / time_diff + except ZeroDivisionError: + recent_rate = None + if last_ave is None: return recent_rate + elif recent_rate is None: return last_ave + + # at this point, both last_ave and recent_rate are numbers + return epsilon * recent_rate + (1 - epsilon) * last_ave + + def _round_remaining_time(self, rt, start_time=15.0): + """round the remaining time, depending on its size + If rt is between n*start_time and (n+1)*start_time round downward + to the nearest multiple of n (for any counting number n). + If rt < start_time, round down to the nearest 1. + For example (for start_time = 15.0): + 2.7 -> 2.0 + 25.2 -> 25.0 + 26.4 -> 26.0 + 35.3 -> 34.0 + 63.6 -> 60.0 + """ + + if rt < 0: return 0.0 + shift = int(math.log(rt/start_time)/math.log(2)) + rt = int(rt) + if shift <= 0: return rt + return float(int(rt) >> shift << shift) + + +def format_time(seconds, use_hours=0): + if seconds is None or seconds < 0: + if use_hours: return '--:--:--' + else: return '--:--' + else: + seconds = int(seconds) + minutes = seconds / 60 + seconds = seconds % 60 + if use_hours: + hours = minutes / 60 + minutes = minutes % 60 + return '%02i:%02i:%02i' % (hours, minutes, seconds) + else: + return '%02i:%02i' % (minutes, seconds) + +def format_number(number, SI=0, space=' '): + """Turn numbers into human-readable metric-like numbers""" + symbols = ['', # (none) + 'k', # kilo + 'M', # mega + 'G', # giga + 'T', # tera + 'P', # peta + 'E', # exa + 'Z', # zetta + 'Y'] # yotta + + if SI: step = 1000.0 + else: step = 1024.0 + + thresh = 999 + depth = 0 + max_depth = len(symbols) - 1 + + # we want numbers between 0 and thresh, but don't exceed the length + # of our list. In that event, the formatting will be screwed up, + # but it'll still show the right number. + while number > thresh and depth < max_depth: + depth = depth + 1 + number = number / step + + if type(number) == type(1) or type(number) == type(1L): + # it's an int or a long, which means it didn't get divided, + # which means it's already short enough + format = '%i%s%s' + elif number < 9.95: + # must use 9.95 for proper sizing. For example, 9.99 will be + # rounded to 10.0 with the .1f format string (which is too long) + format = '%.1f%s%s' + else: + format = '%.0f%s%s' + + return(format % (float(number or 0), space, symbols[depth])) diff --git a/naoki/urlgrabber/sslfactory.py b/naoki/urlgrabber/sslfactory.py new file mode 100644 index 0000000..f7e6d3d --- /dev/null +++ b/naoki/urlgrabber/sslfactory.py @@ -0,0 +1,89 @@ +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, +# Boston, MA 02111-1307 USA + +# This file is part of urlgrabber, a high-level cross-protocol url-grabber + +import httplib +import urllib2 + +try: + from M2Crypto import SSL + from M2Crypto import httpslib + from M2Crypto import m2urllib2 + + have_m2crypto = True +except ImportError: + have_m2crypto = False + +DEBUG = None + +if have_m2crypto: + + class M2SSLFactory: + + def __init__(self, ssl_ca_cert, ssl_context): + self.ssl_context = self._get_ssl_context(ssl_ca_cert, ssl_context) + + def _get_ssl_context(self, ssl_ca_cert, ssl_context): + """ + Create an ssl context using the CA cert file or ssl context. + + The CA cert is used first if it was passed as an option. If not, + then the supplied ssl context is used. If no ssl context was supplied, + None is returned. + """ + if ssl_ca_cert: + context = SSL.Context() + context.load_verify_locations(ssl_ca_cert) + context.set_verify(SSL.verify_peer, -1) + return context + else: + return ssl_context + + def create_https_connection(self, host, response_class = None): + connection = httplib.HTTPSConnection(host, self.ssl_context) + if response_class: + connection.response_class = response_class + return connection + + def create_opener(self, *handlers): + return m2urllib2.build_opener(self.ssl_context, *handlers) + + +class SSLFactory: + + def create_https_connection(self, host, response_class = None): + connection = httplib.HTTPSConnection(host) + if response_class: + connection.response_class = response_class + return connection + + def create_opener(self, *handlers): + return urllib2.build_opener(*handlers) + + + +def get_factory(ssl_ca_cert = None, ssl_context = None): + """ Return an SSLFactory, based on if M2Crypto is available. """ + if have_m2crypto: + return M2SSLFactory(ssl_ca_cert, ssl_context) + else: + # Log here if someone provides the args but we don't use them. + if ssl_ca_cert or ssl_context: + if DEBUG: + DEBUG.warning("SSL arguments supplied, but M2Crypto is not available. " + "Using Python SSL.") + return SSLFactory() diff --git a/naoki/util.py b/naoki/util.py new file mode 100644 index 0000000..d0dcf55 --- /dev/null +++ b/naoki/util.py @@ -0,0 +1,200 @@ +#!/usr/bin/python + +import ctypes +import fcntl +import os +import select +import shutil +import subprocess +import sys +import time + +from constants import * +from exception import * +from logger import getLog + +_libc = ctypes.cdll.LoadLibrary(None) +_errno = ctypes.c_int.in_dll(_libc, "errno") +_libc.personality.argtypes = [ctypes.c_ulong] +_libc.personality.restype = ctypes.c_int +_libc.unshare.argtypes = [ctypes.c_int,] +_libc.unshare.restype = ctypes.c_int +CLONE_NEWNS = 0x00020000 + +# taken from sys/personality.h +PER_LINUX32=0x0008 +PER_LINUX=0x0000 +personality_defs = { + 'linux64': PER_LINUX, + 'linux32': PER_LINUX32, +} + +def touch(filename): + getLog().debug("touching file: %s" % filename) + f = open(filename, "w") + f.close() + +def mkdir(*args): + for dirName in args: + getLog().debug("ensuring that dir exists: %s" % dirName) + if not os.path.exists(dirName): + try: + getLog().debug("creating dir: %s" % dirName) + os.makedirs(dirName) + except OSError, e: + getLog().exception("Could not create dir %s. Error: %s" % (dirName, e)) + raise Error, "Could not create dir %s. Error: %s" % (dirName, e) + +def rm(path, *args, **kargs): + """version os shutil.rmtree that ignores no-such-file-or-directory errors, + and tries harder if it finds immutable files""" + tryAgain = 1 + failedFilename = None + getLog().debug("remove tree: %s" % path) + while tryAgain: + tryAgain = 0 + try: + shutil.rmtree(path, *args, **kargs) + except OSError, e: + if e.errno == 2: # no such file or directory + pass + elif e.errno==1 or e.errno==13: + tryAgain = 1 + if failedFilename == e.filename: + raise + failedFilename = e.filename + os.system("chattr -R -i %s" % path) + else: + raise + +def logOutput(fds, logger, returnOutput=1, start=0, timeout=0): + output="" + done = 0 + + # set all fds to nonblocking + for fd in fds: + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + if not fd.closed: + fcntl.fcntl(fd, fcntl.F_SETFL, flags| os.O_NONBLOCK) + + tail = "" + while not done: + if (time.time() - start)>timeout and timeout!=0: + done = 1 + break + + i_rdy,o_rdy,e_rdy = select.select(fds,[],[],1) + for s in i_rdy: + # slurp as much input as is ready + input = s.read() + if input == "": + done = 1 + break + if logger is not None: + lines = input.split("\n") + if tail: + lines[0] = tail + lines[0] + # we may not have all of the last line + tail = lines.pop() + for line in lines: + if line == '': continue + logger.debug(line) + for h in logger.handlers: + h.flush() + if returnOutput: + output += input + if tail and logger is not None: + logger.debug(tail) + return output + +# these are called in child process, so no logging +def condChroot(chrootPath): + if chrootPath is not None: + os.chdir(chrootPath) + os.chroot(chrootPath) + +def condChdir(cwd): + if cwd is not None: + os.chdir(cwd) + +def condPersonality(per=None): + if not per: + return + if personality_defs.get(per, None) is None: + return + res = _libc.personality(personality_defs[per]) + if res == -1: + raise OSError(_errno.value, os.strerror(_errno.value)) + +def do(command, shell=False, chrootPath=None, cwd=None, timeout=0, raiseExc=True, returnOutput=0, personality=None, *args, **kargs): + logger = kargs.get("logger", getLog()) + output = "" + start = time.time() + env = kargs.get("env", None) + preexec = ChildPreExec(personality, chrootPath, cwd) + + if config["nice_level"]: + command = "nice -n %s %s" % (config["nice_level"], command) + + try: + child = None + logger.debug("Executing command: %s" % command) + child = subprocess.Popen( + command, + shell=shell, + bufsize=0, close_fds=True, + stdin=open("/dev/null", "r"), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + preexec_fn = preexec, + env=env + ) + + # use select() to poll for output so we dont block + output = logOutput([child.stdout, child.stderr], + logger, returnOutput, start, timeout) + + except: + # kill children if they arent done + if child is not None and child.returncode is None: + os.killpg(child.pid, 9) + try: + if child is not None: + os.waitpid(child.pid, 0) + except: + pass + raise + + # wait until child is done, kill it if it passes timeout + niceExit=1 + while child.poll() is None: + if (time.time() - start)>timeout and timeout!=0: + niceExit=0 + os.killpg(child.pid, 15) + if (time.time() - start)>(timeout+1) and timeout!=0: + niceExit=0 + os.killpg(child.pid, 9) + + if not niceExit: + raise commandTimeoutExpired, ("Timeout(%s) expired for command:\n # %s\n%s" % (timeout, command, output)) + + logger.debug("Child returncode was: %s" % str(child.returncode)) + if raiseExc and child.returncode: + if returnOutput: + raise Error, ("Command failed: \n # %s\n%s" % (command, output), child.returncode) + else: + raise Error, ("Command failed. See logs for output.\n # %s" % (command,), child.returncode) + + return output + +class ChildPreExec(object): + def __init__(self, personality, chrootPath, cwd): + self.personality = personality + self.chrootPath = chrootPath + self.cwd = cwd + + def __call__(self, *args, **kargs): + os.setpgrp() + condPersonality(self.personality) + condChroot(self.chrootPath) + condChdir(self.cwd) diff --git a/pkgs/Constants b/pkgs/Constants new file mode 100644 index 0000000..47a9d63 --- /dev/null +++ b/pkgs/Constants @@ -0,0 +1,81 @@ + +############################################################################### +# +# Constant definitions of the naoki build system +# +############################################################################### + +ifeq "$(CHROOT)" "1" + BASEDIR = /usr/src +endif + +THISAPP = $(PKG_NAME)-$(PKG_VER) + +DIR_APP = $(DIR_SRC)/$(THISAPP) +DIR_DL = $(BASEDIR)/cache/tarballs +DIR_PATCHES = $(DIR_SOURCE)/patches +DIR_SRC = $(ROOT)/usr/src +DIR_TMP = /tmp +DIR_SOURCE = $(CURDIR) +DIR_PACKAGES = /usr/src/packages +DIR_TOOLS = $(BASEDIR)/tools +DIR_LOGS = $(BASEDIR)/logs + +BUILD_HOST ?= $(shell cat /proc/sys/kernel/hostname) + +VPATH = $(DIR_DL) + +PKG_OBJECTS = $(PKG_TARBALL) +PKG_PATCHES = $(foreach patch,$(wildcard $(DIR_SOURCE)/patches/*.patch),$(notdir $(patch))) +OBJECTS = $(PKG_OBJECTS) + +PKG_NAME_REAL = $(notdir $(CURDIR)) +PKG_PACKAGES = $(PKG_NAME_REAL) +PKG_PACKAGES_FILES = $(foreach package,$(PKG_PACKAGES),$(call DO_PACKAGE_FILENAME,$(package))) + +DO_PACKAGE_FILENAME = $(1)$(PKG_SUFFIX) +PKG_SUFFIX = -$(PKG_VER)-$(DISTRO_SNAME)$(DISTRO_EPOCH)-$(PKG_REL).ipk + +DO_EXTRACT = $(DIR_TOOLS)/extractor +DO_PATCHES = cd $(DIR_APP) && $(DIR_TOOLS)/patch $(foreach patch,$(PKG_PATCHES),$(DIR_PATCHES)/$(patch)) +DO_QUALITY_AGENT = $(DIR_TOOLS)/quality-agent + +PKG_DESCRIPTION_$(PKG_NAME_REAL)-devel = Development files of $(THISAPP). + +define PKG_FILES_$(PKG_NAME_REAL)-devel + /usr/include + */lib/*.so +endef + +PKG_BUILD_DEPS += glibc + +CONFIGURE_OPTIONS = --prefix=/usr + +ifeq "$(TARGET_MACHINE)" "x86_64" + LINKER = /lib64/ld-linux-x86-64.so.2 +else + LINKER = /lib/ld-linux.so.2 +endif + +STAGE_PACKAGE_TARGETS = $(call reverse,$(PKG_PACKAGES_FILES)) +ifeq "$(TOOLCHAIN)" "1" + STAGE_DONE = $(ROOT)/$(PKG_NAME_REAL) +else + STAGE_DONE = $(ROOT)/.done +endif + +PKG_INIT_FILES = $(wildcard *.init) +PKG_INIT_FILES += $(wildcard init/*.conf) +PKG_PAM_FILES = $(wildcard *.pam) +PKG_PAM_FILES += $(wildcard pam.d/*) + +export CFLAGS CXXFLAGS BUILD_HOST + +export PKG_NAME PKG_VER PKG_REL PKG_MAINTAINER PKG_GROUP PKG_URL PKG_LICENSE +export PKG_SUMMARY PKG_DESCRIPTION=$(strip $(PKG_DESCRIPTION)) +export PKG_DEPS PKG_BUILD_DEPS + +export CONTROL_PREIN CONTROL_PREUN CONTROL_POSTIN CONTROL_POSTUN + +export QUALITY_AGENT_WHITELIST_EXECSTACK QUALITY_AGENT_WHITELIST_RPATH +export QUALITY_AGENT_WHITELIST_SONAME diff --git a/pkgs/Functions b/pkgs/Functions new file mode 100644 index 0000000..9f8b7b1 --- /dev/null +++ b/pkgs/Functions @@ -0,0 +1,130 @@ + +############################################################################### +# +# Function definitions of the naoki build system +# +############################################################################### + +include $(PKGROOT)/gmsl + +define DO_FILELIST + @echo "# Filelist dump" + @cd $(BUILDROOT) && find -ls +endef + +define __INSTALL_INIT + -mkdir -pv $(BUILDROOT)/etc/init + cd $(DIR_APP) && cp -vf $(DIR_SOURCE)/$(1) $(BUILDROOT)/etc/init/$(subst .init,.conf,$(notdir $(1))) + +endef + +define DO_INSTALL_INIT + $(foreach file,$(PKG_INIT_FILES),$(call __INSTALL_INIT,$(file))) +endef + +define __INSTALL_PAM + -mkdir -pv $(BUILDROOT)/etc/pam.d + cd $(DIR_APP) && cp -vf $(DIR_SOURCE)/$(1) $(BUILDROOT)/etc/pam.d/$(subst .pam,,$(notdir $(1))) + +endef + +define DO_INSTALL_PAM + $(foreach file,$(PKG_PAM_FILES),$(call __INSTALL_PAM,$(file))) +endef + +define DO_PYTHON_COMPILE + @find $(BUILDROOT) -name "*.py" | xargs $(DIR_TOOLS)/py-compile +endef + +define DO_FIX_LIBTOOL + # remove rpath from libtool + @if [ -e "libtool" ]; then \ + sed -i libtool \ + -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ + -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g'; \ + fi +endef + +define DO_PREPARE + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Preparation started" + @echo "#####################################################################" + + $(STAGE_PREPARE) + + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Preparation finished" + @echo "#####################################################################" +endef + +define DO_BUILD + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Build started" + @echo "#####################################################################" + + $(STAGE_BUILD) + + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Build finished" + @echo "#####################################################################" +endef + +define DO_TEST + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Test started" + @echo "#####################################################################" + + $(STAGE_TEST) + + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Test finished" + @echo "#####################################################################" +endef + +define DO_INSTALL + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Install started" + @echo "#####################################################################" + + $(STAGE_INSTALL) + + $(DO_INSTALL_INIT) + $(DO_INSTALL_PAM) + + $(DO_PYTHON_COMPILE) + + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Install finished" + @echo "#####################################################################" + + $(if $(TOOLCHAIN),,$(DO_QUALITY_AGENT)) + + $(if $(TOOLCHAIN),,$(DO_FILELIST)) +endef + +define STAGE_PREPARE + $(if $(PKG_TARBALL),cd $(DIR_SRC) && $(DO_EXTRACT) $(DIR_DL)/$(PKG_TARBALL)) + + $(if $(PKG_PATCHES),$(DO_PATCHES)) + + $(STAGE_PREPARE_CMDS) + $(STAGE_PREPARE_CMDS2) +endef + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + $(CONFIGURE_OPTIONS) + + $(DO_FIX_LIBTOOL) + $(STAGE_CONFIGURE_CMDS) + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) + $(STAGE_BUILD_CMDS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install $(if $(TOOLCHAIN),,DESTDIR=$(BUILDROOT)) + + $(STAGE_INSTALL_CMDS) +endef diff --git a/pkgs/Include b/pkgs/Include new file mode 100644 index 0000000..50541e4 --- /dev/null +++ b/pkgs/Include @@ -0,0 +1,25 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +.SECONDEXPANSION: + +include $(PKGROOT)/Constants +include $(PKGROOT)/Functions +include $(PKGROOT)/Targets diff --git a/pkgs/Targets b/pkgs/Targets new file mode 100644 index 0000000..0f2314a --- /dev/null +++ b/pkgs/Targets @@ -0,0 +1,50 @@ + +############################################################################### +# +# Target definitions of the naoki build system +# +############################################################################### + +.PHONY: info +info: + @echo "PKG_BUILD_DEPENDENCIES="$(PKG_BUILD_DEPS)"" + @echo "PKG_DEPENDENCIES="$(PKG_DEPS)"" + @echo "PKG_DESCRIPTION="$(strip $(PKG_DESCRIPTION))"" + @echo "PKG_GROUP="$(PKG_GROUP)"" + @echo "PKG_LICENSE="$(PKG_LICENSE)"" + @echo "PKG_MAINTAINER="$(PKG_MAINTAINER)"" + @echo "PKG_NAME="$(PKG_NAME_REAL)"" + @echo "PKG_OBJECTS="$(strip $(OBJECTS))"" + @echo "PKG_PACKAGES="$(PKG_PACKAGES)"" + @echo "PKG_PACKAGES_FILES="$(PKG_PACKAGES_FILES)"" + @echo "PKG_PATCHES="$(PKG_PATCHES)"" + @echo "PKG_VER="$(PKG_VER)"" + @echo "PKG_REL="$(PKG_REL)"" + @echo "PKG_SUMMARY="$(strip $(PKG_SUMMARY))"" + @echo "PKG_URL="$(PKG_URL)"" + @echo "PKG_TOOLCHAIN_DEPENDENCIES="$(PKG_TOOLCHAIN_DEPS)"" + +$(OBJECTS): + @echo "Object file "$@" is required." >&2 + @exit 1 + +%.ipk: $(STAGE_DONE) + @echo "$(strip $(PKG_FILES_$(patsubst %$(PKG_SUFFIX),%,$@)))" \ + > $(DIR_TMP)/filelist_$(patsubst %$(PKG_SUFFIX),%,$@) + @$(DIR_TOOLS)/compressor $(DIR_PACKAGES)/$@ \ + --root=$(BUILDROOT) $(if $(PKG_FILES_$(patsubst %$(PKG_SUFFIX),%,$@)), \ + --regexes=$(DIR_TMP)/filelist_$(patsubst %$(PKG_SUFFIX),%,$@)) + +.PHONY: package +package: $(if $(TOOLCHAIN),$(STAGE_DONE),$$(STAGE_PACKAGE_TARGETS)) + +.PHONY: shell +shell: $(OBJECTS) + $(if $(STAGE_PREPARE),$(DO_PREPARE)) + +$(STAGE_DONE): $(OBJECTS) + $(if $(STAGE_PREPARE),$(DO_PREPARE)) + $(if $(STAGE_BUILD),$(DO_BUILD)) + $(if $(STAGE_TEST),$(DO_TEST)) + $(if $(STAGE_INSTALL),$(DO_INSTALL)) + @touch $@ diff --git a/pkgs/__gmsl b/pkgs/__gmsl new file mode 100644 index 0000000..596ff19 --- /dev/null +++ b/pkgs/__gmsl @@ -0,0 +1,854 @@ +# ---------------------------------------------------------------------------- +# +# GNU Make Standard Library (GMSL) +# +# A library of functions to be used with GNU Make's $(call) that +# provides functionality not available in standard GNU Make. +# +# Copyright (c) 2005-2007 John Graham-Cumming +# +# This file is part of GMSL +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# Neither the name of the John Graham-Cumming nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# ---------------------------------------------------------------------------- + +# This is the GNU Make Standard Library version number as a list with +# three items: major, minor, revision + +gmsl_version := 1 0 11 + +# Used to output warnings and error from the library, it's possible to +# disable any warnings or errors by overriding these definitions +# manually or by setting GMSL_NO_WARNINGS or GMSL_NO_ERRORS + +__gmsl_name := GNU Make Standard Library +__gmsl_warning = $(warning $(__gmsl_name): $1) +__gmsl_error = $(error $(__gmsl_name): $1) + +ifdef GMSL_NO_WARNINGS +__gmsl_warning := +endif +ifdef GMSL_NO_ERRORS +__gmsl_error := +endif + +# If GMSL_TRACE is enabled then calls to the library functions are +# traced to stdout using warning messages with their arguments + +ifdef GMSL_TRACE +__gmsl_tr1 = $(warning $0('$1')) +__gmsl_tr2 = $(warning $0('$1','$2')) +__gmsl_tr3 = $(warning $0('$1','$2','$3')) +else +__gmsl_tr1 := +__gmsl_tr2 := +__gmsl_tr3 := +endif + +# Figure out whether we have $(eval) or not (GNU Make 3.80 and above) +# if we do not then output a warning message, if we do then some +# functions will be enabled. + +__gmsl_have_eval := $(false) +__gmsl_ignore := $(eval __gmsl_have_eval := $(true)) + +# If this is being run with Electric Cloud's emake then warn that +# their $(eval) support is incomplete. + +ifdef ECLOUD_BUILD_ID +$(warning You are using Electric Cloud's emake which has incomplete $$(eval) support) +__gmsl_have_eval := $(false) +endif + +# See if we have $(lastword) (GNU Make 3.81 and above) + +__gmsl_have_lastword := $(lastword $(false) $(true)) + +# See if we have native or and and (GNU Make 3.81 and above) + +__gmsl_have_or := $(if $(filter-out undefined, \ + $(origin or)),$(call or,$(true),$(false))) +__gmsl_have_and := $(if $(filter-out undefined, \ + $(origin and)),$(call and,$(true),$(true))) + +ifneq ($(__gmsl_have_eval),$(true)) +$(call __gmsl_warning,GNU Make $(MAKE_VERSION) does not support $$$$(eval): some functions disabled) +endif + +# ---------------------------------------------------------------------------- +# Function: gmsl_compatible +# Arguments: List containing the desired library version number (maj min rev) +# Returns: $(true) if this version of the library is compatible +# with the requested version number, otherwise $(false) +# ---------------------------------------------------------------------------- +gmsl_compatible = $(strip \ + $(if $(call gt,$(word 1,$1),$(word 1,$(gmsl_version))), \ + $(false), \ + $(if $(call lt,$(word 1,$1),$(word 1,$(gmsl_version))), \ + $(true), \ + $(if $(call gt,$(word 2,$1),$(word 2,$(gmsl_version))), \ + $(false), \ + $(if $(call lt,$(word 2,$1),$(word 2,$(gmsl_version))), \ + $(true), \ + $(call lte,$(word 3,$1),$(word 3,$(gmsl_version)))))))) + +# ########################################################################### +# LOGICAL OPERATORS +# ########################################################################### + +# not is defined in gmsl + +# ---------------------------------------------------------------------------- +# Function: and +# Arguments: Two boolean values +# Returns: Returns $(true) if both of the booleans are true +# ---------------------------------------------------------------------------- +ifneq ($(__gmsl_have_and),$(true)) +and = $(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(false)) +endif + +# ---------------------------------------------------------------------------- +# Function: or +# Arguments: Two boolean values +# Returns: Returns $(true) if either of the booleans is true +# ---------------------------------------------------------------------------- +ifneq ($(__gmsl_have_or),$(true)) +or = $(__gmsl_tr2)$(if $1$2,$(true),$(false)) +endif + +# ---------------------------------------------------------------------------- +# Function: xor +# Arguments: Two boolean values +# Returns: Returns $(true) if exactly one of the booleans is true +# ---------------------------------------------------------------------------- +xor = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(if $2,$(true),$(false))) + +# ---------------------------------------------------------------------------- +# Function: nand +# Arguments: Two boolean values +# Returns: Returns value of 'not and' +# ---------------------------------------------------------------------------- +nand = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(true)) + +# ---------------------------------------------------------------------------- +# Function: nor +# Arguments: Two boolean values +# Returns: Returns value of 'not or' +# ---------------------------------------------------------------------------- +nor = $(__gmsl_tr2)$(if $1$2,$(false),$(true)) + +# ---------------------------------------------------------------------------- +# Function: xnor +# Arguments: Two boolean values +# Returns: Returns value of 'not xor' +# ---------------------------------------------------------------------------- +xnor =$(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(if $2,$(false),$(true))) + +# ########################################################################### +# LIST MANIPULATION FUNCTIONS +# ########################################################################### + +# ---------------------------------------------------------------------------- +# Function: first (same as LISP's car, or head) +# Arguments: 1: A list +# Returns: Returns the first element of a list +# ---------------------------------------------------------------------------- +first = $(__gmsl_tr1)$(firstword $1) + +# ---------------------------------------------------------------------------- +# Function: last +# Arguments: 1: A list +# Returns: Returns the last element of a list +# ---------------------------------------------------------------------------- +ifeq ($(__gmsl_have_lastword),$(true)) +last = $(__gmsl_tr1)$(lastword $1) +else +last = $(__gmsl_tr1)$(if $1,$(word $(words $1),$1)) +endif + +# ---------------------------------------------------------------------------- +# Function: rest (same as LISP's cdr, or tail) +# Arguments: 1: A list +# Returns: Returns the list with the first element removed +# ---------------------------------------------------------------------------- +rest = $(__gmsl_tr1)$(wordlist 2,$(words $1),$1) + +# ---------------------------------------------------------------------------- +# Function: chop +# Arguments: 1: A list +# Returns: Returns the list with the last element removed +# ---------------------------------------------------------------------------- +chop = $(__gmsl_tr1)$(wordlist 2,$(words $1),x $1) + +# ---------------------------------------------------------------------------- +# Function: map +# Arguments: 1: Name of function to $(call) for each element of list +# 2: List to iterate over calling the function in 1 +# Returns: The list after calling the function on each element +# ---------------------------------------------------------------------------- +map = $(__gmsl_tr2)$(strip $(foreach a,$2,$(call $1,$a))) + +# ---------------------------------------------------------------------------- +# Function: pairmap +# Arguments: 1: Name of function to $(call) for each pair of elements +# 2: List to iterate over calling the function in 1 +# 3: Second list to iterate over calling the function in 1 +# Returns: The list after calling the function on each pair of elements +# ---------------------------------------------------------------------------- +pairmap = $(strip $(__gmsl_tr3)\ + $(if $2$3,$(call $1,$(call first,$2),$(call first,$3)) \ + $(call pairmap,$1,$(call rest,$2),$(call rest,$3)))) + +# ---------------------------------------------------------------------------- +# Function: leq +# Arguments: 1: A list to compare against... +# 2: ...this list +# Returns: Returns $(true) if the two lists are identical +# ---------------------------------------------------------------------------- +leq = $(__gmsl_tr2)$(strip $(if $(call seq,$(words $1),$(words $2)), \ + $(call __gmsl_list_equal,$1,$2),$(false))) + +__gmsl_list_equal = $(if $(strip $1), \ + $(if $(call seq,$(call first,$1),$(call first,$2)), \ + $(call __gmsl_list_equal, \ + $(call rest,$1), \ + $(call rest,$2)), \ + $(false)), \ + $(true)) + +# ---------------------------------------------------------------------------- +# Function: lne +# Arguments: 1: A list to compare against... +# 2: ...this list +# Returns: Returns $(true) if the two lists are different +# ---------------------------------------------------------------------------- +lne = $(__gmsl_tr2)$(call not,$(call leq,$1,$2)) + +# ---------------------------------------------------------------------------- +# Function: reverse +# Arguments: 1: A list to reverse +# Returns: The list with its elements in reverse order +# ---------------------------------------------------------------------------- +reverse =$(__gmsl_tr1)$(strip $(if $1,$(call reverse,$(call rest,$1)) \ + $(call first,$1))) + +# ---------------------------------------------------------------------------- +# Function: uniq +# Arguments: 1: A list from which to remove repeated elements +# Returns: The list with duplicate elements removed without reordering +# ---------------------------------------------------------------------------- +uniq = $(strip $(__gmsl_tr1)$(if $1,$(call uniq,$(call chop,$1)) \ + $(if $(filter $(call last,$1),$(call chop,$1)),,$(call last,$1)))) + +# ---------------------------------------------------------------------------- +# Function: length +# Arguments: 1: A list +# Returns: The number of elements in the list +# ---------------------------------------------------------------------------- +length = $(__gmsl_tr1)$(words $1) + +# ########################################################################### +# STRING MANIPULATION FUNCTIONS +# ########################################################################### + +# Helper function that translates any GNU Make 'true' value (i.e. a +# non-empty string) to our $(true) + +__gmsl_make_bool = $(if $(strip $1),$(true),$(false)) + +# ---------------------------------------------------------------------------- +# Function: seq +# Arguments: 1: A string to compare against... +# 2: ...this string +# Returns: Returns $(true) if the two strings are identical +# ---------------------------------------------------------------------------- +seq = $(__gmsl_tr2)$(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),$(false),$(true)) + +# ---------------------------------------------------------------------------- +# Function: sne +# Arguments: 1: A string to compare against... +# 2: ...this string +# Returns: Returns $(true) if the two strings are not the same +# ---------------------------------------------------------------------------- +sne = $(__gmsl_tr2)$(call not,$(call seq,$1,$2)) + +# ---------------------------------------------------------------------------- +# Function: split +# Arguments: 1: The character to split on +# 2: A string to split +# Returns: Splits a string into a list separated by spaces at the split +# character in the first argument +# ---------------------------------------------------------------------------- +split = $(__gmsl_tr2)$(strip $(subst $1, ,$2)) + +# ---------------------------------------------------------------------------- +# Function: merge +# Arguments: 1: The character to put between fields +# 2: A list to merge into a string +# Returns: Merges a list into a single string, list elements are separated +# by the character in the first argument +# ---------------------------------------------------------------------------- +merge = $(__gmsl_tr2)$(strip $(if $2, \ + $(if $(call seq,1,$(words $2)), \ + $2,$(call first,$2)$1$(call merge,$1,$(call rest,$2))))) + +ifdef __gmsl_have_eval +# ---------------------------------------------------------------------------- +# Function: tr +# Arguments: 1: The list of characters to translate from +# 2: The list of characters to translate to +# 3: The text to translate +# Returns: Returns the text after translating characters +# ---------------------------------------------------------------------------- +tr = $(strip $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3) \ + $(eval __gmsl_t := $3) \ + $(foreach c, \ + $(join $(addsuffix :,$1),$2), \ + $(eval __gmsl_t := \ + $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)), \ + $(__gmsl_t))))$(__gmsl_t)) + +# Common character classes for use with the tr function. Each of +# these is actually a variable declaration and must be wrapped with +# $() or ${} to be used. + +[A-Z] := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z # +[a-z] := a b c d e f g h i j k l m n o p q r s t u v w x y z # +[0-9] := 0 1 2 3 4 5 6 7 8 9 # +[A-F] := A B C D E F # + +# ---------------------------------------------------------------------------- +# Function: uc +# Arguments: 1: Text to upper case +# Returns: Returns the text in upper case +# ---------------------------------------------------------------------------- +uc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([a-z]),$([A-Z]),$1) + +# ---------------------------------------------------------------------------- +# Function: lc +# Arguments: 1: Text to lower case +# Returns: Returns the text in lower case +# ---------------------------------------------------------------------------- +lc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([A-Z]),$([a-z]),$1) + +# ---------------------------------------------------------------------------- +# Function: strlen +# Arguments: 1: A string +# Returns: Returns the length of the string +# ---------------------------------------------------------------------------- +__gmsl_characters := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +__gmsl_characters += a b c d e f g h i j k l m n o p q r s t u v w x y z +__gmsl_characters += 0 1 2 3 4 5 6 7 8 9 +__gmsl_characters += ` ~ ! @ # $$ % ^ & * ( ) - _ = + +__gmsl_characters += { } [ ] \ : ; ' " < > , . / ? | + +# Aside: if you read the above you might think that the lower-case +# letter x is missing, and that that's an error. It is missing, but +# it's not an error. __gmsl_characters is used by the strlen +# function. strlen works by transforming every character and space +# into the letter x and then counting the x's. Since there's no need +# to transform x into x I omitted it. + +# This results in __gmsl_space containing just a space + +__gmsl_space := +__gmsl_space += + +strlen = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(eval __temp := $(subst $(__gmsl_space),x,$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,x,$(__temp))))$(eval __temp := $(subst x,x ,$(__temp)))$(words $(__temp))) + +# This results in __gmsl_newline containing just a newline + +define __gmsl_newline + + +endef + +# This results in __gmsl_tab containing a tab + +__gmsl_tab := # + +# ---------------------------------------------------------------------------- +# Function: substr +# Arguments: 1: A string +# 2: Start position (first character is 1) +# 3: End position (inclusive) +# Returns: A substring. +# Note: The string in $1 must not contain a § +# ---------------------------------------------------------------------------- + +substr = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(strip $(eval __temp := $$(subst $$(__gmsl_space),§ ,$$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,$$a$$(__gmsl_space),$(__temp))))$(eval __temp := $(wordlist $2,$3,$(__temp))))$(subst §,$(__gmsl_space),$(subst $(__gmsl_space),,$(__temp))) + +endif # __gmsl_have_eval + +# ########################################################################### +# SET MANIPULATION FUNCTIONS +# ########################################################################### + +# Sets are represented by sorted, deduplicated lists. To create a set +# from a list use set_create, or start with the empty_set and +# set_insert individual elements + +# This is the empty set +empty_set := + +# ---------------------------------------------------------------------------- +# Function: set_create +# Arguments: 1: A list of set elements +# Returns: Returns the newly created set +# ---------------------------------------------------------------------------- +set_create = $(__gmsl_tr1)$(sort $1) + +# ---------------------------------------------------------------------------- +# Function: set_insert +# Arguments: 1: A single element to add to a set +# 2: A set +# Returns: Returns the set with the element added +# ---------------------------------------------------------------------------- +set_insert = $(__gmsl_tr2)$(sort $1 $2) + +# ---------------------------------------------------------------------------- +# Function: set_remove +# Arguments: 1: A single element to remove from a set +# 2: A set +# Returns: Returns the set with the element removed +# ---------------------------------------------------------------------------- +set_remove = $(__gmsl_tr2)$(filter-out $1,$2) + +# ---------------------------------------------------------------------------- +# Function: set_is_member +# Arguments: 1: A single element +# 2: A set +# Returns: Returns $(true) if the element is in the set +# ---------------------------------------------------------------------------- +set_is_member = $(__gmsl_tr2)$(if $(filter $1,$2),$(true),$(false)) + +# ---------------------------------------------------------------------------- +# Function: set_union +# Arguments: 1: A set +# 2: Another set +# Returns: Returns the union of the two sets +# ---------------------------------------------------------------------------- +set_union = $(__gmsl_tr2)$(sort $1 $2) + +# ---------------------------------------------------------------------------- +# Function: set_intersection +# Arguments: 1: A set +# 2: Another set +# Returns: Returns the intersection of the two sets +# ---------------------------------------------------------------------------- +set_intersection = $(__gmsl_tr2)$(filter $1,$2) + +# ---------------------------------------------------------------------------- +# Function: set_is_subset +# Arguments: 1: A set +# 2: Another set +# Returns: Returns $(true) if the first set is a subset of the second +# ---------------------------------------------------------------------------- +set_is_subset = $(__gmsl_tr2)$(call set_equal,$(call set_intersection,$1,$2),$1) + +# ---------------------------------------------------------------------------- +# Function: set_equal +# Arguments: 1: A set +# 2: Another set +# Returns: Returns $(true) if the two sets are identical +# ---------------------------------------------------------------------------- +set_equal = $(__gmsl_tr2)$(call seq,$1,$2) + +# ########################################################################### +# ARITHMETIC LIBRARY +# ########################################################################### + +# Integers a represented by lists with the equivalent number of x's. +# For example the number 4 is x x x x. The maximum integer that the +# library can handle as _input_ is __gmsl_input_int which is defined +# here as 65536 + +__gmsl_sixteen := x x x x x x x x x x x x x x x x +__gmsl_input_int := $(foreach a,$(__gmsl_sixteen), \ + $(foreach b,$(__gmsl_sixteen), \ + $(foreach c,$(__gmsl_sixteen), \ + $(__gmsl_sixteen))))) + +# ---------------------------------------------------------------------------- +# Function: int_decode +# Arguments: 1: A number of x's representation +# Returns: Returns the integer for human consumption that is represented +# by the string of x's +# ---------------------------------------------------------------------------- +int_decode = $(__gmsl_tr1)$(words $1) + +# ---------------------------------------------------------------------------- +# Function: int_encode +# Arguments: 1: A number in human-readable integer form +# Returns: Returns the integer encoded as a string of x's +# ---------------------------------------------------------------------------- +int_encode = $(__gmsl_tr1)$(wordlist 1,$1,$(__gmsl_input_int)) + +# The arithmetic library functions come in two forms: one form of each +# function takes integers as arguments and the other form takes the +# encoded form (x's created by a call to int_encode). For example, +# there are two plus functions: +# +# plus Called with integer arguments and returns an integer +# int_plus Called with encoded arguments and returns an encoded result +# +# plus will be slower than int_plus because its arguments and result +# have to be translated between the x's format and integers. If doing +# a complex calculation use the int_* forms with a single encoding of +# inputs and single decoding of the output. For simple calculations +# the direct forms can be used. + +# Helper function used to wrap an int_* function into a function that +# takes a pair of integers, perhaps a function and returns an integer +# result +__gmsl_int_wrap = $(call int_decode,$(call $1,$(call int_encode,$2),$(call int_encode,$3))) +__gmsl_int_wrap1 = $(call int_decode,$(call $1,$(call int_encode,$2))) +__gmsl_int_wrap2 = $(call $1,$(call int_encode,$2),$(call int_encode,$3)) + +# ---------------------------------------------------------------------------- +# Function: int_plus +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the sum of the two numbers in x's representation +# ---------------------------------------------------------------------------- +int_plus = $(strip $(__gmsl_tr2)$1 $2) + +# ---------------------------------------------------------------------------- +# Function: plus (wrapped version of int_plus) +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the sum of the two integers +# ---------------------------------------------------------------------------- +plus = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_plus,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_subtract +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the difference of the two numbers in x's representation, +# or outputs an error on a numeric underflow +# ---------------------------------------------------------------------------- +int_subtract = $(strip $(__gmsl_tr2)$(if $(call int_gte,$1,$2), \ + $(filter-out xx,$(join $1,$2)), \ + $(call __gmsl_warning,Subtraction underflow))) + +# ---------------------------------------------------------------------------- +# Function: subtract (wrapped version of int_subtract) +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the difference of the two integers, +# or outputs an error on a numeric underflow +# ---------------------------------------------------------------------------- +subtract = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_subtract,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_multiply +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the product of the two numbers in x's representation +# ---------------------------------------------------------------------------- +int_multiply = $(strip $(__gmsl_tr2)$(foreach a,$1,$2)) + +# ---------------------------------------------------------------------------- +# Function: multiply (wrapped version of int_multiply) +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the product of the two integers +# ---------------------------------------------------------------------------- +multiply = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_multiply,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_divide +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the result of integer division of argument 1 divided +# by argument 2 in x's representation +# ---------------------------------------------------------------------------- +int_divide = $(__gmsl_tr2)$(strip $(if $2, \ + $(if $(call int_gte,$1,$2), \ + x $(call int_divide,$(call int_subtract,$1,$2),$2),), \ + $(call __gmsl_error,Division by zero))) + +# ---------------------------------------------------------------------------- +# Function: divide (wrapped version of int_divide) +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the integer division of the first argument by the second +# ---------------------------------------------------------------------------- +divide = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_divide,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_max, int_min +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the maximum or minimum of its arguments in x's +# representation +# ---------------------------------------------------------------------------- +int_max = $(__gmsl_tr2)$(subst xx,x,$(join $1,$2)) +int_min = $(__gmsl_tr2)$(subst xx,x,$(filter xx,$(join $1,$2))) + +# ---------------------------------------------------------------------------- +# Function: max, min +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the maximum or minimum of its integer arguments +# ---------------------------------------------------------------------------- +max = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_max,$1,$2) +min = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_min,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_gt, int_gte, int_lt, int_lte, int_eq, int_ne +# Arguments: Two x's representation numbers to be compared +# Returns: $(true) or $(false) +# +# int_gt First argument greater than second argument +# int_gte First argument greater than or equal to second argument +# int_lt First argument less than second argument +# int_lte First argument less than or equal to second argument +# int_eq First argument is numerically equal to the second argument +# int_ne First argument is not numerically equal to the second argument +# ---------------------------------------------------------------------------- +int_gt = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(filter-out $(words $2), \ + $(words $(call int_max,$1,$2)))) +int_gte = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(call int_gt,$1,$2)$(call int_eq,$1,$2)) +int_lt = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(filter-out $(words $1), \ + $(words $(call int_max,$1,$2)))) +int_lte = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(call int_lt,$1,$2)$(call int_eq,$1,$2)) +int_eq = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(filter $(words $1),$(words $2))) +int_ne = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(filter-out $(words $1),$(words $2))) + +# ---------------------------------------------------------------------------- +# Function: gt, gte, lt, lte, eq, ne +# Arguments: Two integers to be compared +# Returns: $(true) or $(false) +# +# gt First argument greater than second argument +# gte First argument greater than or equal to second argument +# lt First argument less than second argument +# lte First argument less than or equal to second argument +# eq First argument is numerically equal to the second argument +# ne First argument is not numerically equal to the second argument +# ---------------------------------------------------------------------------- +gt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gt,$1,$2) +gte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gte,$1,$2) +lt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lt,$1,$2) +lte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lte,$1,$2) +eq = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_eq,$1,$2) +ne = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_ne,$1,$2) + +# increment adds 1 to its argument, decrement subtracts 1. Note that +# decrement does not range check and hence will not underflow, but +# will incorrectly say that 0 - 1 = 0 + +# ---------------------------------------------------------------------------- +# Function: int_inc +# Arguments: 1: A number in x's representation +# Returns: The number incremented by 1 in x's representation +# ---------------------------------------------------------------------------- +int_inc = $(strip $(__gmsl_tr1)$1 x) + +# ---------------------------------------------------------------------------- +# Function: inc +# Arguments: 1: An integer +# Returns: The argument incremented by 1 +# ---------------------------------------------------------------------------- +inc = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_inc,$1) + +# ---------------------------------------------------------------------------- +# Function: int_dec +# Arguments: 1: A number in x's representation +# Returns: The number decremented by 1 in x's representation +# ---------------------------------------------------------------------------- +int_dec = $(__gmsl_tr1)$(strip $(if $(call sne,0,$(words $1)), \ + $(wordlist 2,$(words $1),$1), \ + $(call __gmsl_warning,Decrement underflow))) + +# ---------------------------------------------------------------------------- +# Function: dec +# Arguments: 1: An integer +# Returns: The argument decremented by 1 +# ---------------------------------------------------------------------------- +dec = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_dec,$1) + +# double doubles its argument, and halve halves it + +# ---------------------------------------------------------------------------- +# Function: int_double +# Arguments: 1: A number in x's representation +# Returns: The number doubled (i.e. * 2) and returned in x's representation +# ---------------------------------------------------------------------------- +int_double = $(strip $(__gmsl_tr1)$1 $1) + +# ---------------------------------------------------------------------------- +# Function: double +# Arguments: 1: An integer +# Returns: The integer times 2 +# ---------------------------------------------------------------------------- +double = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_double,$1) + +# ---------------------------------------------------------------------------- +# Function: int_halve +# Arguments: 1: A number in x's representation +# Returns: The number halved (i.e. / 2) and returned in x's representation +# ---------------------------------------------------------------------------- +int_halve = $(__gmsl_tr1)$(strip $(subst xx,x,$(filter-out xy x y, \ + $(join $1,$(foreach a,$1,y x))))) + +# ---------------------------------------------------------------------------- +# Function: halve +# Arguments: 1: An integer +# Returns: The integer divided by 2 +# ---------------------------------------------------------------------------- +halve = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_halve,$1) + +ifdef __gmsl_have_eval +# ########################################################################### +# ASSOCIATIVE ARRAYS +# ########################################################################### + +# ---------------------------------------------------------------------------- +# Function: set +# Arguments: 1: Name of associative array +# 2: The key value to associate +# 3: The value associated with the key +# Returns: None +# ---------------------------------------------------------------------------- +set = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(eval __gmsl_aa_$1_$2 = $3) + +# ---------------------------------------------------------------------------- +# Function: get +# Arguments: 1: Name of associative array +# 2: The key to retrieve +# Returns: The value stored in the array for that key +# ---------------------------------------------------------------------------- +get = $(strip $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(if $(filter-out undefined,$(origin __gmsl_aa_$1_$2)), \ + $(__gmsl_aa_$1_$2))) + +# ---------------------------------------------------------------------------- +# Function: keys +# Arguments: 1: Name of associative array +# Returns: Returns a list of all defined keys in the array +# ---------------------------------------------------------------------------- +keys = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(sort $(patsubst __gmsl_aa_$1_%,%, \ + $(filter __gmsl_aa_$1_%,$(.VARIABLES)))) + +# ---------------------------------------------------------------------------- +# Function: defined +# Arguments: 1: Name of associative array +# 2: The key to test +# Returns: Returns true if the key is defined (i.e. not empty) +# ---------------------------------------------------------------------------- +defined = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(call sne,$(call get,$1,$2),) + +endif # __gmsl_have_eval + +ifdef __gmsl_have_eval +# ########################################################################### +# NAMED STACKS +# ########################################################################### + +# ---------------------------------------------------------------------------- +# Function: push +# Arguments: 1: Name of stack +# 2: Value to push onto the top of the stack (must not contain +# a space) +# Returns: None +# ---------------------------------------------------------------------------- +push = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(eval __gmsl_stack_$1 := $2 $(if $(filter-out undefined,\ + $(origin __gmsl_stack_$1)),$(__gmsl_stack_$1))) + +# ---------------------------------------------------------------------------- +# Function: pop +# Arguments: 1: Name of stack +# Returns: Top element from the stack after removing it +# ---------------------------------------------------------------------------- +pop = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(if $(filter-out undefined,$(origin __gmsl_stack_$1)), \ + $(call first,$(__gmsl_stack_$1)) \ + $(eval __gmsl_stack_$1 := $(call rest,$(__gmsl_stack_$1))))) + +# ---------------------------------------------------------------------------- +# Function: peek +# Arguments: 1: Name of stack +# Returns: Top element from the stack without removing it +# ---------------------------------------------------------------------------- +peek = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call first,$(__gmsl_stack_$1)) + +# ---------------------------------------------------------------------------- +# Function: depth +# Arguments: 1: Name of stack +# Returns: Number of items on the stack +# ---------------------------------------------------------------------------- +depth = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(words $(__gmsl_stack_$1)) + +endif # __gmsl_have_eval + +# ########################################################################### +# DEBUGGING FACILITIES +# ########################################################################### + +# ---------------------------------------------------------------------------- +# Target: gmsl-print-% +# Arguments: The % should be replaced by the name of a variable that you +# wish to print out. +# Action: Echos the name of the variable that matches the % and its value. +# For example, 'make gmsl-print-SHELL' will output the value of +# the SHELL variable +# ---------------------------------------------------------------------------- +gmsl-print-%: ; @echo $* = $($*) + +# ---------------------------------------------------------------------------- +# Function: assert +# Arguments: 1: A boolean that must be true or the assertion will fail +# 2: The message to print with the assertion +# Returns: None +# ---------------------------------------------------------------------------- +assert = $(if $1,,$(call __gmsl_error,Assertion failure: $2)) + +# ---------------------------------------------------------------------------- +# Function: assert_exists +# Arguments: 1: Name of file that must exist, if it is missing an assertion +# will be generated +# Returns: None +# ---------------------------------------------------------------------------- +assert_exists = $(call assert,$(wildcard $1),file '$1' missing) + +# ---------------------------------------------------------------------------- +# Function: assert_no_dollar +# Arguments: 1: Name of a function being executd +# 2: Arguments to check +# Returns: None +# ---------------------------------------------------------------------------- +assert_no_dollar = $(call assert,$(call not,$(findstring $$,$2)),$1 called with a dollar sign in argument) diff --git a/pkgs/core/acl/acl.nm b/pkgs/core/acl/acl.nm new file mode 100644 index 0000000..f898461 --- /dev/null +++ b/pkgs/core/acl/acl.nm @@ -0,0 +1,71 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = acl +PKG_VER = 2.2.47 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://oss.sgi.com/projects/xfs/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Access control list utilities. + +PKG_PACKAGES += $(PKG_NAME_REAL)-devel + +define PKG_DESCRIPTION + This package contains the getfacl and setfacl utilities needed for \ + manipulating access control lists. +endef + +PKG_BUILD_DEPS+= gettext libtool +PKG_DEPS += attr libnfsidmap + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --bindir=/bin \ + --disable-static \ + --mandir=/usr/share/man + + cd $(DIR_APP) && make LIBTOOL="libtool --tag=CC" #$(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/{,usr/}lib $(BUILDROOT)/usr/include/{acl,sys} + install -v -m0755 $(DIR_APP)/libacl/.libs/libacl.so.1.2.0 $(BUILDROOT)/lib + ln -vsf libacl.so.1.2.0 $(BUILDROOT)/lib/libacl.so.1 + ln -vsf ../../lib/libacl.so.1 $(BUILDROOT)/usr/lib/libacl.so + cp -vf $(DIR_APP)/include/libacl.h $(BUILDROOT)/usr/include/acl/ + cp -vf $(DIR_APP)/include/acl.h $(BUILDROOT)/usr/include/sys/ +endef diff --git a/pkgs/core/acl/patches/acl-2.2.47-build-1.patch b/pkgs/core/acl/patches/acl-2.2.47-build-1.patch new file mode 100644 index 0000000..1605ee3 --- /dev/null +++ b/pkgs/core/acl/patches/acl-2.2.47-build-1.patch @@ -0,0 +1,36 @@ +--- acl-2.2.39/include/builddefs.in.build 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/include/builddefs.in 2006-07-05 12:34:05.000000000 -0400 +@@ -26,14 +26,14 @@ + PKG_VERSION = @pkg_version@ + PKG_PLATFORM = @pkg_platform@ + PKG_DISTRIBUTION= @pkg_distribution@ +-PKG_BIN_DIR = @bindir@ +-PKG_SBIN_DIR = @sbindir@ +-PKG_LIB_DIR = @libdir@@libdirsuffix@ +-PKG_DEVLIB_DIR = @libexecdir@@libdirsuffix@ +-PKG_INC_DIR = @includedir@ +-PKG_MAN_DIR = @mandir@ +-PKG_DOC_DIR = @datadir@/doc/@pkg_name@ +-PKG_LOCALE_DIR = @datadir@/locale ++PKG_BIN_DIR = $(DESTDIR)@bindir@ ++PKG_SBIN_DIR = $(DESTDIR)@sbindir@ ++PKG_LIB_DIR = $(DESTDIR)@libdir@@libdirsuffix@ ++PKG_DEVLIB_DIR = $(DESTDIR)@libexecdir@@libdirsuffix@ ++PKG_INC_DIR = $(DESTDIR)@includedir@ ++PKG_MAN_DIR = $(DESTDIR)@mandir@ ++PKG_DOC_DIR = $(DESTDIR)@datadir@/doc/@pkg_name@-@pkg_version@ ++PKG_LOCALE_DIR = $(DESTDIR)@datadir@/locale + + CC = @cc@ + AWK = @awk@ +--- acl-2.2.39/include/buildmacros.build 2006-07-05 12:32:07.000000000 -0400 ++++ acl-2.2.39/include/buildmacros 2006-07-05 12:32:07.000000000 -0400 +@@ -26,7 +26,7 @@ + $(LFILES:.l=.o) \ + $(YFILES:%.y=%.tab.o) + +-INSTALL = $(TOPDIR)/install-sh -o $(PKG_USER) -g $(PKG_GROUP) ++INSTALL = $(TOPDIR)/install-sh + + SHELL = /bin/sh + IMAGES_DIR = $(TOPDIR)/all-images diff --git a/pkgs/core/acl/patches/acl-2.2.47-exitcode.patch b/pkgs/core/acl/patches/acl-2.2.47-exitcode.patch new file mode 100644 index 0000000..0ba27b0 --- /dev/null +++ b/pkgs/core/acl/patches/acl-2.2.47-exitcode.patch @@ -0,0 +1,27 @@ +--- acl-2.2.45/setfacl/setfacl.c.old 2007-11-08 14:04:42.000000000 +0100 ++++ acl-2.2.45/setfacl/setfacl.c 2007-11-08 14:05:43.000000000 +0100 +@@ -144,7 +144,7 @@ restore( + if (error < 0) + goto fail; + if (error == 0) +- return 0; ++ return status; + + if (path_p == NULL) { + if (filename) { +@@ -158,6 +158,7 @@ restore( + "aborting\n"), + progname, backup_line); + } ++ status = 1; + goto getout; + } + +@@ -176,6 +177,7 @@ restore( + fprintf(stderr, _("%s: %s: %s in line %d\n"), + progname, xquote(filename), strerror(errno), + line); ++ status = 1; + goto getout; + } + diff --git a/pkgs/core/acl/patches/acl-2.2.47-nfs4.patch b/pkgs/core/acl/patches/acl-2.2.47-nfs4.patch new file mode 100644 index 0000000..c6314f5 --- /dev/null +++ b/pkgs/core/acl/patches/acl-2.2.47-nfs4.patch @@ -0,0 +1,3278 @@ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_get_who.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,103 @@ ++/* ++ * NFSv4 ACL Code ++ * Read the who value from the ace and return its type and optionally ++ * its value. ++ * ++ * Ace is a reference to the ace to extract the who value from. ++ * Type is a reference where the value of the whotype will be stored. ++ * Who is a double reference that should either be passed as NULL ++ * (and thus no who string will be returned) or as a pointer to a ++ * char* where the who string will be allocated. This string must be ++ * freed by the caller. ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "libacl_nfs4.h" ++ ++int acl_nfs4_get_who(struct nfs4_ace* ace, int* type, char** who) ++{ ++ int itype; ++ char* iwho = NULL; ++ int wholen; ++ ++ if(ace == NULL || ace->who == NULL) ++ goto inval_failed; ++ ++ itype = acl_nfs4_get_whotype(ace->who); ++ ++ if(type != NULL) { ++ *type = itype; ++ } ++ ++ ++ if(who == NULL) ++ return 0; ++ ++ switch(itype) ++ { ++ case NFS4_ACL_WHO_NAMED: ++ iwho = ace->who; ++ break; ++ case NFS4_ACL_WHO_OWNER: ++ iwho = NFS4_ACL_WHO_OWNER_STRING; ++ break; ++ case NFS4_ACL_WHO_GROUP: ++ iwho = NFS4_ACL_WHO_GROUP_STRING; ++ break; ++ case NFS4_ACL_WHO_EVERYONE: ++ iwho = NFS4_ACL_WHO_EVERYONE_STRING; ++ break; ++ default: ++ goto inval_failed; ++ } ++ ++ wholen = strlen(iwho); ++ if(wholen < 0) ++ goto inval_failed; ++ ++ (*who) = (char *) malloc(sizeof(char) * (wholen + 1)); ++ if((*who) == NULL) { ++ errno = ENOMEM; ++ goto failed; ++ } ++ ++ strcpy((*who), iwho); ++ ++ return 0; ++ ++inval_failed: ++ errno = EINVAL; ++ ++failed: ++ return -1; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_add_ace.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,83 @@ ++/* ++ * NFSv4 ACL Code ++ * Add an ace to the acl ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen <marius@umich.edu> ++ * J. Bruce Fields <bfields@umich.edu> ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * Jeff Sedlak <jsedlak@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "libacl_nfs4.h" ++ ++int ++acl_nfs4_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask, ++ int whotype, char* who) ++{ ++ struct nfs4_ace *ace; ++ int result; ++ ++ if(acl == NULL) ++ { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if ((ace = malloc(sizeof(*ace))) == NULL) ++ { ++ errno = ENOMEM; ++ return -1; ++ } ++ ++ ace->type = type; ++ ace->flag = flag; ++ ++ if( type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE ) ++ access_mask = access_mask & ~(NFS4_ACE_MASK_IGNORE); ++ ++ ++ /* Castrate delete_child if we aren't a directory */ ++ if (!acl->is_directory) ++ access_mask &= ~NFS4_ACE_DELETE_CHILD; ++ ++ ++ ace->access_mask = access_mask & NFS4_ACE_MASK_ALL; ++ ++ result = acl_nfs4_set_who(ace, whotype, who); ++ if(result < 0) ++ return -1; ++ ++ TAILQ_INSERT_TAIL(&acl->ace_head, ace, l_ace); ++ acl->naces++; ++ ++ return 0; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_get_whotype.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,60 @@ ++/* ++ * NFSv4 ACL Code ++ * Get the whotype of the who string passed ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen <marius@umich.edu> ++ * J. Bruce Fields <bfields@umich.edu> ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * Jeff Sedlak <jsedlak@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "libacl_nfs4.h" ++ ++inline int ++acl_nfs4_get_whotype(char *p) ++{ ++ if(0 == strcmp(p, NFS4_ACL_WHO_OWNER_STRING) && ++ strlen(p) == strlen(NFS4_ACL_WHO_OWNER_STRING)) { ++ return NFS4_ACL_WHO_OWNER; ++ } ++ if(0 == strcmp(p, NFS4_ACL_WHO_GROUP_STRING) && ++ strlen(p) == strlen(NFS4_ACL_WHO_GROUP_STRING)) { ++ return NFS4_ACL_WHO_GROUP; ++ } ++ if(0 == strcmp(p, NFS4_ACL_WHO_EVERYONE_STRING) && ++ strlen(p) == strlen(NFS4_ACL_WHO_EVERYONE_STRING)) { ++ return NFS4_ACL_WHO_EVERYONE; ++ } ++ ++ return NFS4_ACL_WHO_NAMED; ++} ++ ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_free.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (c) 2004 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen <marius@umich.edu> ++ * J. Bruce Fields <bfields@umich.edu> ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * Jeff Sedlak <jsedlak@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, the following disclaimer, and ++ * any and all other licensing or copyright notices included in ++ * any files in this distribution. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include "libacl_nfs4.h" ++ ++void ++acl_nfs4_free(struct nfs4_acl *acl) ++{ ++ struct nfs4_ace *ace; ++ ++ if (!acl) ++ return; ++ ++ while (!TAILQ_IS_EMPTY(acl->ace_head)) { ++ ace = (acl)->ace_head.tqh_first; ++ ++ TAILQ_REMOVE( &(acl->ace_head), ace, l_ace); ++ free(ace->who); ++ free(ace); ++ } ++ ++ free(acl); ++ ++ return; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_n4tp_acl_trans.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,439 @@ ++/* ++ * NFSv4 ACL Code ++ * Convert NFSv4 ACL to a POSIX ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include <acl/libacl.h> ++#include <nfsidmap.h> ++#include "libacl_nfs4.h" ++ ++ ++/* ++ * While processing the NFSv4 ACE, this maintains bitmasks representing ++ * which permission bits have been allowed and which denied to a given ++ * entity: */ ++struct posix_ace_state { ++ u_int32_t allow; ++ u_int32_t deny; ++}; ++ ++struct posix_user_ace_state { ++ uid_t uid; ++ struct posix_ace_state perms; ++}; ++ ++struct posix_ace_state_array { ++ int n; ++ struct posix_user_ace_state aces[]; ++}; ++ ++/* ++ * While processing the NFSv4 ACE, this maintains the partial permissions ++ * calculated so far: */ ++ ++struct posix_acl_state { ++ struct posix_ace_state owner; ++ struct posix_ace_state group; ++ struct posix_ace_state other; ++ struct posix_ace_state everyone; ++ struct posix_ace_state mask; /* Deny unused in this case */ ++ struct posix_ace_state_array *users; ++ struct posix_ace_state_array *groups; ++}; ++ ++static int ++init_state(struct posix_acl_state *state, int cnt) ++{ ++ int alloc; ++ ++ memset(state, 0, sizeof(struct posix_acl_state)); ++ /* ++ * In the worst case, each individual acl could be for a distinct ++ * named user or group, but we don't know which, so we allocate ++ * enough space for either: ++ */ ++ alloc = sizeof(struct posix_ace_state_array) ++ + cnt*sizeof(struct posix_user_ace_state); ++ state->users = calloc(1, alloc); ++ if (!state->users) ++ return -ENOMEM; ++ state->groups = calloc(1, alloc); ++ if (!state->groups) { ++ free(state->users); ++ return -ENOMEM; ++ } ++ return 0; ++} ++ ++static void ++free_state(struct posix_acl_state *state) { ++ free(state->users); ++ free(state->groups); ++} ++ ++static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate) ++{ ++ state->mask.allow |= astate->allow; ++} ++ ++/* ++ * We only map from NFSv4 to POSIX ACLs when getting ACLs, when we err on the ++ * side of permissiveness (so as not to make the file appear more secure than ++ * it really is), so the mode bit mapping below is optimistic. ++ */ ++static void ++set_mode_from_nfs4(acl_entry_t pace, u_int32_t perm, int is_dir) ++{ ++ u32 write_mode = NFS4_WRITE_MODE; ++ acl_permset_t perms; ++ ++ acl_get_permset(pace, &perms); ++ acl_clear_perms(perms); ++ if (is_dir) ++ write_mode |= NFS4_ACE_DELETE_CHILD; ++ if (perm & NFS4_READ_MODE) ++ acl_add_perm(perms, ACL_READ); ++ if (perm & write_mode) ++ acl_add_perm(perms, ACL_WRITE); ++ if (perm & NFS4_EXECUTE_MODE) ++ acl_add_perm(perms, ACL_EXECUTE); ++ acl_set_permset(pace, perms); ++} ++ ++/* XXX: add a "check allow" that can warn on e.g. allows of WRITE_ACL ++ * to non-owner? */ ++ ++/* XXX: replace error returns by errno sets all over. Ugh. */ ++ ++static acl_t ++posix_state_to_acl(struct posix_acl_state *state, int is_dir) ++{ ++ acl_entry_t pace; ++ acl_t pacl; ++ int nace; ++ int i, error = 0; ++ ++ if (state->users->n || state->groups->n) ++ nace = 4 + state->users->n + state->groups->n; ++ else ++ nace = 3; ++ pacl = acl_init(nace); ++ if (!pacl) ++ return NULL; ++ ++ error = acl_create_entry(&pacl, &pace); ++ if (error) ++ goto out_err; ++ acl_set_tag_type(pace, ACL_USER_OBJ); ++ set_mode_from_nfs4(pace, state->owner.allow, is_dir); ++ ++ for (i=0; i < state->users->n; i++) { ++ error = acl_create_entry(&pacl, &pace); ++ if (error) ++ goto out_err; ++ acl_set_tag_type(pace, ACL_USER); ++ set_mode_from_nfs4(pace, state->users->aces[i].perms.allow, ++ is_dir); ++ acl_set_qualifier(pace, &state->users->aces[i].uid); ++ add_to_mask(state, &state->users->aces[i].perms); ++ } ++ ++ error = acl_create_entry(&pacl, &pace); ++ if (error) ++ goto out_err; ++ acl_set_tag_type(pace, ACL_GROUP_OBJ); ++ set_mode_from_nfs4(pace, state->group.allow, is_dir); ++ add_to_mask(state, &state->group); ++ ++ for (i=0; i < state->groups->n; i++) { ++ error = acl_create_entry(&pacl, &pace); ++ if (error) ++ goto out_err; ++ acl_set_tag_type(pace, ACL_GROUP); ++ set_mode_from_nfs4(pace, state->groups->aces[i].perms.allow, ++ is_dir); ++ acl_set_qualifier(pace, &state->groups->aces[i].uid); ++ add_to_mask(state, &state->groups->aces[i].perms); ++ } ++ ++ if (nace > 3) { ++ error = acl_create_entry(&pacl, &pace); ++ if (error) ++ goto out_err; ++ acl_set_tag_type(pace, ACL_MASK); ++ set_mode_from_nfs4(pace, state->mask.allow, is_dir); ++ } ++ ++ error = acl_create_entry(&pacl, &pace); ++ if (error) ++ goto out_err; ++ acl_set_tag_type(pace, ACL_OTHER); ++ set_mode_from_nfs4(pace, state->other.allow, is_dir); ++ ++ return pacl; ++out_err: ++ acl_free(pacl); ++ return NULL; ++} ++ ++static inline void allow_bits(struct posix_ace_state *astate, u32 mask) ++{ ++ /* Allow all bits in the mask not already denied: */ ++ astate->allow |= mask & ~astate->deny; ++} ++ ++static inline void deny_bits(struct posix_ace_state *astate, u32 mask) ++{ ++ /* Deny all bits in the mask not already allowed: */ ++ astate->deny |= mask & ~astate->allow; ++} ++ ++static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid) ++{ ++ int i; ++ ++ for (i = 0; i < a->n; i++) ++ if (a->aces[i].uid == uid) ++ return i; ++ /* Not found: */ ++ a->n++; ++ a->aces[i].uid = uid; ++ a->aces[i].perms.allow = state->everyone.allow; ++ a->aces[i].perms.deny = state->everyone.deny; ++ ++ return i; ++} ++ ++static void deny_bits_array(struct posix_ace_state_array *a, u32 mask) ++{ ++ int i; ++ ++ for (i=0; i < a->n; i++) ++ deny_bits(&a->aces[i].perms, mask); ++} ++ ++static void allow_bits_array(struct posix_ace_state_array *a, u32 mask) ++{ ++ int i; ++ ++ for (i=0; i < a->n; i++) ++ allow_bits(&a->aces[i].perms, mask); ++} ++ ++static acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace) ++{ ++ int nfs4type; ++ int result; ++ ++ result = acl_nfs4_get_who(ace, &nfs4type, NULL); ++ if (result < 0) ++ return -1; ++ ++ switch (nfs4type) { ++ case NFS4_ACL_WHO_NAMED: ++ return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? ++ ACL_GROUP : ACL_USER); ++ case NFS4_ACL_WHO_OWNER: ++ return ACL_USER_OBJ; ++ case NFS4_ACL_WHO_GROUP: ++ return ACL_GROUP_OBJ; ++ case NFS4_ACL_WHO_EVERYONE: ++ return ACL_OTHER; ++ } ++ errno = EINVAL; ++ return -1; ++} ++ ++static int process_one_v4_ace(struct posix_acl_state *state, ++ struct nfs4_ace *ace) ++{ ++ u32 mask = ace->access_mask; ++ uid_t id; ++ int i; ++ ++ if (nfs4_init_name_mapping(NULL)) ++ return -1; ++ ++ switch (acl_n4tp_get_whotype(ace)) { ++ case ACL_USER_OBJ: ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { ++ allow_bits(&state->owner, mask); ++ } else { ++ deny_bits(&state->owner, mask); ++ } ++ break; ++ case ACL_USER: ++ if (nfs4_name_to_uid(ace->who, &id)) ++ return -1; ++ i = find_uid(state, state->users, id); ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { ++ allow_bits(&state->users->aces[i].perms, mask); ++ mask = state->users->aces[i].perms.allow; ++ allow_bits(&state->owner, mask); ++ } else { ++ deny_bits(&state->users->aces[i].perms, mask); ++ } ++ break; ++ case ACL_GROUP_OBJ: ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { ++ allow_bits(&state->group, mask); ++ mask = state->group.allow; ++ allow_bits(&state->owner, mask); ++ allow_bits(&state->everyone, mask); ++ allow_bits_array(state->users, mask); ++ allow_bits_array(state->groups, mask); ++ } else { ++ deny_bits(&state->group, mask); ++ } ++ break; ++ case ACL_GROUP: ++ if (nfs4_name_to_gid(ace->who, &id)) ++ return -1; ++ i = find_uid(state, state->groups, id); ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { ++ allow_bits(&state->groups->aces[i].perms, mask); ++ mask = state->groups->aces[i].perms.allow; ++ allow_bits(&state->owner, mask); ++ allow_bits(&state->group, mask); ++ allow_bits(&state->everyone, mask); ++ allow_bits_array(state->users, mask); ++ allow_bits_array(state->groups, mask); ++ } else { ++ deny_bits(&state->groups->aces[i].perms, mask); ++ } ++ break; ++ case ACL_OTHER: ++ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { ++ allow_bits(&state->owner, mask); ++ allow_bits(&state->group, mask); ++ allow_bits(&state->other, mask); ++ allow_bits(&state->everyone, mask); ++ allow_bits_array(state->users, mask); ++ allow_bits_array(state->groups, mask); ++ } else { ++ deny_bits(&state->owner, mask); ++ deny_bits(&state->group, mask); ++ deny_bits(&state->other, mask); ++ deny_bits(&state->everyone, mask); ++ deny_bits_array(state->users, mask); ++ deny_bits_array(state->groups, mask); ++ } ++ } ++ return 0; ++} ++ ++#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \ ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE) ++ ++/* Strip or keep inheritance aces depending on type of posix acl requested */ ++static void acl_nfs4_check_inheritance(struct nfs4_acl *acl, u32 iflags) ++{ ++ struct nfs4_ace * cur_ace; ++ struct nfs4_ace * temp_ace; ++ ++ cur_ace = acl->ace_head.tqh_first; ++ ++ while (cur_ace) { ++ /* get the next ace now in case we free the current ace */ ++ temp_ace = cur_ace; ++ cur_ace = cur_ace->l_ace.tqe_next; ++ ++ if (iflags & NFS4_ACL_REQUEST_DEFAULT) { ++ if (!(temp_ace->flag & FILE_OR_DIR_INHERIT)) ++ acl_nfs4_remove_ace(acl, temp_ace); ++ } else { ++ if (temp_ace->flag & NFS4_ACE_INHERIT_ONLY_ACE) ++ acl_nfs4_remove_ace(acl, temp_ace); ++ } ++ } ++} ++ ++acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype) ++{ ++ struct posix_acl_state state; ++ acl_t pacl; ++ struct nfs4_acl * temp_acl; ++ struct nfs4_ace * cur_ace; ++ int ret; ++ u32 iflags = NFS4_ACL_NOFLAGS; ++ ++ if (ptype == ACL_TYPE_DEFAULT) { ++ if (nacl_p->is_directory) ++ iflags |= NFS4_ACL_REQUEST_DEFAULT; ++ else { ++ errno = EINVAL; ++ return NULL; ++ } ++ } ++ ++ /* Copy so we can delete bits without borking the original */ ++ temp_acl = acl_nfs4_copy_acl(nacl_p); ++ if (temp_acl == NULL) ++ return NULL; ++ ++ acl_nfs4_check_inheritance(temp_acl, iflags); ++ ++ if (ptype == ACL_TYPE_DEFAULT && temp_acl->naces == 0) { ++ acl_nfs4_free(temp_acl); ++ return acl_init(0); ++ } ++ ++ ret = init_state(&state, temp_acl->naces); ++ if (ret) ++ goto free_failed; ++ ++ cur_ace = temp_acl->ace_head.tqh_first; ++ while (cur_ace) { ++ if (process_one_v4_ace(&state, cur_ace)) { ++ free_state(&state); ++ goto free_failed; ++ } ++ cur_ace = cur_ace->l_ace.tqe_next; ++ } ++ ++ acl_nfs4_free(temp_acl); ++ ++ pacl = posix_state_to_acl(&state, nacl_p->is_directory); ++ ++ free_state(&state); ++ ++ ret = acl_valid(pacl); ++ if (ret < 0) ++ goto free_failed; ++ ++ return pacl; ++ ++free_failed: ++ acl_nfs4_free(temp_acl); ++ return NULL; ++} +--- acl-2.2.39/libacl/acl_set_fd.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_set_fd.c 2007-08-22 12:02:13.000000000 -0400 +@@ -24,6 +24,11 @@ + #include "libacl.h" + #include "__acl_to_xattr.h" + ++#ifdef USE_NFSV4_TRANS ++ #include "libacl_nfs4.h" ++ #include <nfsidmap.h> ++#endif ++ + #include "byteorder.h" + #include "acl_ea.h" + +@@ -37,10 +42,42 @@ acl_set_fd(int fd, acl_t acl) + const char *name = ACL_EA_ACCESS; + size_t size; + int error; ++#ifdef USE_NFSV4_TRANS ++ int retval; ++ struct nfs4_acl * nacl; ++#endif + + if (!acl_obj_p) + return -1; ++ ++#ifdef USE_NFSV4_TRANS ++ retval = fgetxattr(fd, ACL_NFS4_XATTR, NULL, 0); ++ ++ if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) { ++ ext_acl_p = __acl_to_xattr(acl_obj_p, &size); ++ } else { ++ char domain[NFS4_MAX_DOMAIN_LEN]; ++ nfs4_init_name_mapping(NULL); ++ error = nfs4_get_default_domain(NULL, domain, sizeof(domain)); ++ if (error) ++ return -1; ++ nacl = acl_nfs4_new(0); ++ if (acl == NULL) { ++ errno = ENOMEM; ++ return -1; ++ } ++ error = acl_ptn4_acl_trans(acl, nacl, ACL_TYPE_ACCESS, 0, domain); ++ if (error) ++ return -1; ++ ++ size = acl_nfs4_xattr_pack(nacl, &ext_acl_p); ++ name = ACL_NFS4_XATTR; ++ acl_nfs4_free(nacl); ++ } ++#else + ext_acl_p = __acl_to_xattr(acl_obj_p, &size); ++#endif ++ + if (!ext_acl_p) + return -1; + error = fsetxattr(fd, name, (char *)ext_acl_p, size, 0); +--- acl-2.2.39/libacl/Makefile.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/Makefile 2007-08-22 12:02:13.000000000 -0400 +@@ -8,19 +8,35 @@ LTLDFLAGS += -Wl,--version-script,$(TOPD + include $(TOPDIR)/include/builddefs + + LTLIBRARY = libacl.la +-LTLIBS = -lattr $(LIBMISC) ++LTLIBS = -lattr -lnfsidmap $(LIBMISC) + LTDEPENDENCIES = $(LIBMISC) +-LT_CURRENT = 2 ++LT_CURRENT = 3 + LT_REVISION = 0 +-LT_AGE = 1 ++LT_AGE = 2 ++ ++CFILES = $(POSIX_CFILES) $(LIBACL_CFILES) $(LIBACL_NFS4_CFILES) \ ++ $(INTERNAL_CFILES) perm_copy_fd.c perm_copy_file.c + +-CFILES = $(POSIX_CFILES) $(LIBACL_CFILES) $(INTERNAL_CFILES) \ +- perm_copy_fd.c perm_copy_file.c + HFILES = libobj.h libacl.h byteorder.h __acl_from_xattr.h __acl_to_xattr.h \ +- perm_copy.h ++ perm_copy.h $(LIBACL_NFS4_HFILES) + + LCFLAGS = -include perm_copy.h + ++LIBACL_NFS4_CFILES = \ ++ acl_nfs4_get_who.c \ ++ acl_n4tp_acl_trans.c acl_nfs4_get_whotype.c \ ++ acl_nfs4_new.c \ ++ acl_nfs4_add_ace.c acl_nfs4_remove_ace.c \ ++ acl_nfs4_add_pair.c \ ++ acl_nfs4_copy_acl.c acl_nfs4_set_who.c \ ++ acl_nfs4_free.c acl_nfs4_xattr_load.c \ ++ acl_nfs4_xattr_pack.c acl_nfs4_xattr_size.c \ ++ acl_ptn4_acl_trans.c \ ++ acl_ptn4_get_mask.c __posix_acl_from_nfs4_xattr.c \ ++ ++ ++LIBACL_NFS4_HFILES = ../include/libacl_nfs4.h ../include/nfs4.h ++ + POSIX_CFILES = \ + acl_add_perm.c acl_calc_mask.c acl_clear_perms.c acl_copy_entry.c \ + acl_copy_ext.c acl_copy_int.c acl_create_entry.c acl_delete_def_file.c \ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_remove_ace.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,48 @@ ++/* ++ * NFSv4 ACL Code ++ * Remove an ace from an NFS4 ACL ++ * ++ * Copyright (c) 2004 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, the following disclaimer, and ++ * any and all other licensing or copyright notices included in ++ * any files in this distribution. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++#include "libacl_nfs4.h" ++ ++void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace) ++{ ++ TAILQ_REMOVE(&acl->ace_head, ace, l_ace); ++ free(ace->who); ++ free(ace); ++ acl->naces--; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_set_who.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,92 @@ ++/* ++ * NFSv4 ACL Code ++ * Write the who entry in the nfs4 ace. Who is a user supplied buffer ++ * containing a named who entry (null terminated string) if type is ++ * set to NFS4_ACL_WHO_NAMED. Otherwise, the who buffer is not used. ++ * The user supplied who buffer must be freed by the caller. ++ * ++ * This code allocates the who buffer used in the ace. This must be freed ++ * upon ace removal by the ace_remove or acl_free. ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "libacl_nfs4.h" ++ ++int acl_nfs4_set_who(struct nfs4_ace* ace, int type, char* who) ++{ ++ char* iwho = NULL; ++ int wholen; ++ ++ if(ace == NULL) ++ goto inval_failed; ++ ++ switch(type) ++ { ++ case NFS4_ACL_WHO_NAMED: ++ if(who == NULL) ++ goto inval_failed; ++ iwho = who; ++ break; ++ case NFS4_ACL_WHO_OWNER: ++ iwho = NFS4_ACL_WHO_OWNER_STRING; ++ break; ++ case NFS4_ACL_WHO_GROUP: ++ iwho = NFS4_ACL_WHO_GROUP_STRING; ++ break; ++ case NFS4_ACL_WHO_EVERYONE: ++ iwho = NFS4_ACL_WHO_EVERYONE_STRING; ++ break; ++ default: ++ goto inval_failed; ++ } ++ ++ wholen = strlen(iwho); ++ if(wholen < 1) ++ goto inval_failed; ++ ++ ace->who = (char *) malloc(sizeof(char) * (wholen + 1)); ++ if(ace->who == NULL) { ++ errno = ENOMEM; ++ goto failed; ++ } ++ ++ strcpy(ace->who, iwho); ++ ++ return 0; ++ ++inval_failed: ++ errno = EINVAL; ++ ++failed: ++ return -1; ++} ++ +--- acl-2.2.39/libacl/acl_set_file.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_set_file.c 2007-08-22 12:02:13.000000000 -0400 +@@ -26,9 +26,38 @@ + #include "libacl.h" + #include "__acl_to_xattr.h" + ++#ifdef USE_NFSV4_TRANS ++ #include "libacl_nfs4.h" ++ #include <nfsidmap.h> ++#endif ++ + #include "byteorder.h" + #include "acl_ea.h" + ++#ifdef USE_NFSV4_TRANS ++static struct nfs4_acl *get_nfs4_acl(const char *path_p, int is_dir) ++{ ++ struct nfs4_acl * acl = NULL; ++ ssize_t ret; ++ char *buf; ++ ++ ret = getxattr(path_p, ACL_NFS4_XATTR, NULL, 0); ++ if (ret < 0) ++ return NULL; ++ buf = malloc(ret); ++ if (buf == NULL) ++ return NULL; ++ ret = getxattr(path_p, ACL_NFS4_XATTR, buf, ret); ++ if (ret < 0) ++ goto out_free; ++ acl = acl_nfs4_xattr_load(buf, ret, is_dir); ++ ++out_free: ++ free(buf); ++ return acl; ++} ++ ++#endif + + /* 23.4.22 */ + int +@@ -39,9 +68,15 @@ acl_set_file(const char *path_p, acl_typ + const char *name; + size_t size; + int error; ++ struct stat st; ++#ifdef USE_NFSV4_TRANS ++ struct nfs4_acl * nacl; ++ int is_dir = NFS4_ACL_ISFILE; ++#endif + + if (!acl_obj_p) + return -1; ++ + switch (type) { + case ACL_TYPE_ACCESS: + name = ACL_EA_ACCESS; +@@ -54,8 +89,41 @@ acl_set_file(const char *path_p, acl_typ + return -1; + } + ++ ++#ifdef USE_NFSV4_TRANS ++ if (stat(path_p, &st) != 0) ++ return -1; ++ if (S_ISDIR(st.st_mode)) ++ is_dir = NFS4_ACL_ISDIR; ++ if (type == ACL_TYPE_DEFAULT && !is_dir) { ++ errno = EACCES; ++ return -1; ++ } ++ nacl = get_nfs4_acl(path_p, is_dir); ++ if (nacl == NULL && (errno == ENOATTR || errno == EOPNOTSUPP)) ++ ext_acl_p = __acl_to_xattr(acl_obj_p, &size); ++ else { ++ char domain[NFS4_MAX_DOMAIN_LEN]; ++ ++ nfs4_init_name_mapping(NULL); ++ error = nfs4_get_default_domain(NULL, domain, sizeof(domain)); ++ if (error) { ++ acl_nfs4_free(nacl); ++ return -1; ++ } ++ error = acl_ptn4_acl_trans(acl, nacl, type, is_dir, domain); ++ if (error) { ++ acl_nfs4_free(nacl); ++ return -1; ++ } ++ ++ size = acl_nfs4_xattr_pack(nacl, &ext_acl_p); ++ name = ACL_NFS4_XATTR; ++ acl_nfs4_free(nacl); ++ } ++#else ++ + if (type == ACL_TYPE_DEFAULT) { +- struct stat st; + + if (stat(path_p, &st) != 0) + return -1; +@@ -68,6 +136,8 @@ acl_set_file(const char *path_p, acl_typ + } + + ext_acl_p = __acl_to_xattr(acl_obj_p, &size); ++#endif ++ + if (!ext_acl_p) + return -1; + error = setxattr(path_p, name, (char *)ext_acl_p, size, 0); +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/__posix_acl_from_nfs4_xattr.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,60 @@ ++/* ++ * NFSv4 ACL Code ++ * Convert NFSv4 xattr values to a posix ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include <acl/libacl.h> ++#include "libacl_nfs4.h" ++ ++/* xattr_v is a char buffer filled with the nfsv4 xattr value. ++ * xattr_size should be the byte count of the length of the xattr_v ++ * data size. xattr_v may be larger than <xattr_size> bytes, but only ++ * the first <xattr_size> bytes will be read. <type> is the posix acl ++ * type requested. Currently either default, or access */ ++ ++acl_t __posix_acl_from_nfs4_xattr(char* xattr_v, ++ int xattr_size, acl_type_t ptype, u32 is_dir) ++{ ++ struct nfs4_acl * nfsacl = NULL; ++ acl_t pacl; ++ ++ nfsacl = acl_nfs4_xattr_load(xattr_v, xattr_size, is_dir); ++ if(nfsacl == NULL) { ++ return NULL; ++ } ++ ++ pacl = acl_n4tp_acl_trans(nfsacl, ptype); ++ ++ return pacl; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_xattr_load.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,191 @@ ++/* ++ * NFSv4 ACL Code ++ * Convert NFSv4 xattr values to a posix ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++ ++#include <acl/libacl.h> ++#include <netinet/in.h> ++#include "libacl_nfs4.h" ++ ++ ++struct nfs4_acl * acl_nfs4_xattr_load( ++ char * xattr_v, ++ int xattr_size, ++ u32 is_dir) ++{ ++ struct nfs4_acl * nacl_p; ++ char* bufp = xattr_v; ++ int bufs = xattr_size; ++ u32 ace_n; ++ u32 wholen; ++ char* who; ++ int d_ptr; ++ u32 num_aces; ++ ++ u32 type, flag, access_mask; ++ ++ if(xattr_size < sizeof(u32)) { ++ errno = EINVAL; ++ return NULL; ++ } ++ ++ if((nacl_p = acl_nfs4_new(is_dir)) == NULL) { ++ errno = ENOMEM; ++ return NULL; ++ } ++ ++ /* Grab the number of aces in the acl */ ++ num_aces = (u32)ntohl(*((u32*)(bufp))); ++ ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Got number of aces: %d\n", nacl_p->naces); ++#endif ++ ++ ++ d_ptr = sizeof(u32); ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ for(ace_n = 0; num_aces > ace_n ; ace_n++) ++ { ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Getting Ace #%d of %d\n", ace_n, num_aces); ++#endif ++ /* Get the acl type */ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ type = (u32)ntohl(*((u32*)bufp)); ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Type: %x\n", type); ++#endif ++ ++ d_ptr = sizeof(u32); ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Get the acl flag */ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ flag = (u32)ntohl(*((u32*)bufp)); ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Flag: %x\n", flag); ++#endif ++ ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Get the access mask */ ++ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ access_mask = (u32)ntohl(*((u32*)bufp)); ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Access Mask: %x\n", access_mask); ++#endif ++ ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Get the who string length*/ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ wholen = (u32)ntohl(*((u32*)bufp)); ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Wholen: %d\n", wholen); ++#endif ++ ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Get the who string */ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ who = (char *) malloc((wholen+1) * sizeof(char)); ++ if(who == NULL) ++ { ++ errno = ENOMEM; ++ goto bad_xattr_val; ++ } ++ ++ memcpy(who, bufp, wholen); ++ ++ who[wholen] = '\0'; ++ ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Who: %s\n", who); ++#endif ++ ++ d_ptr = ((wholen / sizeof(u32))*sizeof(u32)); ++ if(wholen % sizeof(u32) != 0) ++ d_ptr += sizeof(u32); ++ ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Make sure we aren't outside our domain */ ++ if(bufs < 0) { ++ free(who); ++ goto bad_xattr_val; ++ } ++ ++ if(acl_nfs4_add_ace(nacl_p, type, flag, access_mask, acl_nfs4_get_whotype(who), who) < 0) { ++ free(who); ++ goto bad_xattr_val; ++ } ++ ++ free(who); ++ } ++ ++ return nacl_p; ++ ++bad_xattr_val: ++ /* We bailed for some reason */ ++ acl_nfs4_free(nacl_p); ++ return NULL; ++} +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_xattr_pack.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,148 @@ ++/* ++ * NFSv4 ACL Code ++ * Pack an NFS4 ACL into an XDR encoded buffer. ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include <libacl_nfs4.h> ++#include <netinet/in.h> ++ ++int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp) ++{ ++ struct nfs4_ace * ace; ++ int buflen; ++ int rbuflen; ++ int num_aces; ++ int ace_num; ++ int wholen; ++ int result; ++ char* p; ++ char* who; ++ ++ if(acl == NULL || bufp == NULL) ++ { ++ errno = EINVAL; ++ goto failed; ++ } ++ ++ buflen = acl_nfs4_xattr_size(acl); ++ if(buflen < 0) ++ { ++ goto failed; ++ } ++ ++ *bufp = (char*) malloc(buflen); ++ if(*bufp == NULL) { ++ errno = ENOMEM; ++ goto failed; ++ } ++ ++ p = *bufp; ++ ++ num_aces = acl->naces; ++ ++ *((u32*)p) = htonl(num_aces); ++ ++ rbuflen = sizeof(u32); ++ p += sizeof(u32); ++ ++ ace = acl->ace_head.tqh_first; ++ ace_num = 1; ++ ++ while(1) ++ { ++ if(ace == NULL) ++ { ++ if(ace_num > num_aces) { ++ break; ++ } else { ++ errno = ENODATA; ++ goto failed; ++ } ++ } ++ ++ *((u32*)p) = htonl(ace->type); ++ p += sizeof(u32); ++ rbuflen += sizeof(u32); ++ ++ *((u32*)p) = htonl(ace->flag); ++ p += sizeof(u32); ++ rbuflen += sizeof(u32); ++ ++ *((u32*)p) = htonl(ace->access_mask); ++ p += sizeof(u32); ++ rbuflen += sizeof(u32); ++ ++ result = acl_nfs4_get_who(ace, NULL, &who); ++ if(result < 0) { ++ goto free_failed; ++ } ++ ++ wholen = strlen(who); ++ *((u32*)p) = htonl(wholen); ++ rbuflen += sizeof(u32); ++ ++ p += sizeof(u32); ++ ++ memcpy(p, who, wholen); ++ free(who); ++ ++ p += (wholen / NFS4_XDR_MOD) * NFS4_XDR_MOD; ++ if(wholen % NFS4_XDR_MOD) { ++ p += NFS4_XDR_MOD; ++ } ++ ++ rbuflen += (wholen / NFS4_XDR_MOD) * NFS4_XDR_MOD; ++ if(wholen % NFS4_XDR_MOD) { ++ rbuflen += NFS4_XDR_MOD; ++ } ++ ++ ace = ace->l_ace.tqe_next; ++ ace_num++; ++ } ++ ++ if (buflen != rbuflen) ++ { ++ goto free_failed; ++ } ++ return buflen; ++ ++free_failed: ++ free(*bufp); ++ *bufp = NULL; ++ ++failed: ++ return -1; ++} ++ ++ ++ +--- acl-2.2.39/libacl/acl_extended_file.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_extended_file.c 2007-08-22 12:02:13.000000000 -0400 +@@ -22,6 +22,7 @@ + #include <unistd.h> + #include <attr/xattr.h> + #include "libacl.h" ++#include "libacl_nfs4.h" + + #include "byteorder.h" + #include "acl_ea.h" +@@ -33,6 +34,34 @@ acl_extended_file(const char *path_p) + int base_size = sizeof(acl_ea_header) + 3 * sizeof(acl_ea_entry); + int retval; + ++ /* XXX: Ugh: what's the easiest way to do this, taking ++ * into account default acl's, and that length alone won't do this? ++ * Also I'm a little uncomfortable with the amount of #ifdef ++ * NFS4 stuff that's going on. We need a cleaner separation. */ ++#ifdef USE_NFSV4_TRANS ++ retval = getxattr(path_p, ACL_NFS4_XATTR, NULL, 0); ++ if (retval < 0 && errno != ENOATTR && errno != EOPNOTSUPP) ++ return -1; ++ if (retval >= 0) { ++ struct nfs4_acl *nfsacl; ++ char *ext_acl_p = alloca(retval); ++ if (!ext_acl_p) ++ return -1; ++ ++ retval = getxattr(path_p, ACL_NFS4_XATTR, ext_acl_p, retval); ++ if (retval == -1) ++ return -1; ++ ++ nfsacl = acl_nfs4_xattr_load(ext_acl_p, retval, NFS4_ACL_ISFILE); ++ if (nfsacl) { ++ int count = nfsacl->naces; ++ acl_nfs4_free(nfsacl); ++ return count > 6; ++ } ++ return 0; ++ } ++#endif ++ + retval = getxattr(path_p, ACL_EA_ACCESS, NULL, 0); + if (retval < 0 && errno != ENOATTR && errno != ENODATA) + return -1; +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_ptn4_acl_trans.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,509 @@ ++/* ++ * NFSv4 ACL Code ++ * Convert a posix ACL to an NFSv4 ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * J. Bruce Fields <bfields@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include <acl/libacl.h> ++#include <nfsidmap.h> ++#include "libacl_nfs4.h" ++ ++ ++#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \ ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE) ++#define NFS4_INHERITANCE_FLAGS (FILE_OR_DIR_INHERIT | NFS4_ACE_INHERIT_ONLY_ACE) ++ ++/* Plan: ++ * 1: if setting default, remove all purely inherited aces, and replace ++ * all dual-use aces by purely effective aces ++ * 2: if setting effective, remove all purely effective aces, and replace ++ * all dual-use aces by purely inherited ones ++ */ ++static void purge_aces(struct nfs4_acl *nacl, acl_type_t type) ++{ ++ struct nfs4_ace *p, *next; ++ ++ for (p = nacl->ace_head.tqh_first; p != NULL; p = next) { ++ next = p->l_ace.tqe_next; ++ ++ if (!(p->flag & FILE_OR_DIR_INHERIT)) { ++ /* purely effective */ ++ if (type == ACL_TYPE_ACCESS) ++ acl_nfs4_remove_ace(nacl, p); ++ } else if (p->flag & NFS4_ACE_INHERIT_ONLY_ACE) { ++ /* purely inherited */ ++ if (type == ACL_TYPE_DEFAULT) ++ acl_nfs4_remove_ace(nacl, p); ++ } else { ++ /* both effective and inherited */ ++ if (type == ACL_TYPE_DEFAULT) { ++ /* Change to purely effective */ ++ p->flag &= ~NFS4_INHERITANCE_FLAGS; ++ } else { /* ACL_TYPE_ACCESS */ ++ /* Change to purely inherited */ ++ p->flag |= NFS4_INHERITANCE_FLAGS; ++ } ++ } ++ ++ } ++} ++ ++int ++acl_ptn4_acl_trans(acl_t pacl, struct nfs4_acl *acl, acl_type_t type, u32 is_dir, char *nfs_domain) ++{ ++ int eflag; ++ u32 mask, mask_mask = 0; ++ int num_aces; ++ int result, result2; ++ u32 iflags = NFS4_ACL_NOFLAGS; ++ int allocated = 0; ++ ++ acl_entry_t pace_p; ++ acl_tag_t ace_type; ++ acl_permset_t perms; ++ ++ char who_buf_static[NFS4_ACL_WHO_BUFFER_LEN_GUESS]; ++ char *who_buf = NULL; ++ int who_buflen; ++ int who_buflen_static = NFS4_ACL_WHO_BUFFER_LEN_GUESS; ++ uid_t * uid_p; ++ gid_t * gid_p; ++ ++ eflag = 0; ++ ++ if (type == ACL_TYPE_DEFAULT) { ++ eflag = NFS4_INHERITANCE_FLAGS; ++ iflags |= NFS4_ACL_REQUEST_DEFAULT; ++ } ++ ++ purge_aces(acl, type); ++ ++ if (is_dir & NFS4_ACL_ISDIR) ++ iflags |= NFS4_ACL_ISDIR; ++ ++ ++ if (pacl == NULL || (acl_valid(pacl) < 0 || acl_entries(pacl) == 0)) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ /* Start Conversion */ ++ ++ /* 3 aces minimum (mode bits) */ ++ num_aces = acl_entries(pacl); ++ if (num_aces < 3) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ /* Get the mask entry */ ++ ++ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p); ++ if (result < 0) ++ goto out; ++ ++ while (result > 0 && mask_mask == 0) { ++ result = acl_get_tag_type(pace_p, &ace_type); ++ if (result < 0) ++ goto out; ++ ++ if (ace_type == ACL_MASK) { ++ result = acl_get_permset(pace_p, &perms); ++ if(result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask_mask, perms, iflags); ++ if(result < 0) ++ goto out; ++ ++ mask_mask = ~mask_mask; ++ } ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result < 0) ++ goto out; ++ } ++ ++ /* Get the file owner entry */ ++ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p); ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_tag_type(pace_p, &ace_type); ++ if (result < 0) ++ goto out; ++ ++ if (ace_type != ACL_USER_OBJ) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags | NFS4_ACL_OWNER); ++ if (result < 0) ++ goto out; ++ ++ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_OWNER, NULL); ++ ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result < 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ while (ace_type == ACL_USER && result > 0) { ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ uid_p = acl_get_qualifier(pace_p); ++ ++ who_buf = who_buf_static; ++ who_buflen = who_buflen_static; ++ ++ result = nfs4_init_name_mapping(NULL); ++ result = nfs4_uid_to_name(*uid_p, nfs_domain, who_buf, who_buflen); ++ ++ ++ while (result == -ENOBUFS) { ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ ++ /* Increase the size by a full buflen unit */ ++ who_buflen += who_buflen_static; ++ who_buf = malloc(who_buflen); ++ ++ if (who_buf == NULL) { ++ result = -ENOMEM; ++ break; ++ } ++ ++ result = nfs4_init_name_mapping(NULL); ++ result = nfs4_uid_to_name(*uid_p, nfs_domain, who_buf, who_buflen); ++ ++ } ++ acl_free(uid_p); ++ if (result < 0) { ++ errno = -result; ++ goto out; ++ } ++ ++ if (who_buf == NULL) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ eflag, mask_mask, NFS4_ACL_WHO_NAMED, who_buf); ++ if (result < 0) { ++ if(who_buf != who_buf_static) ++ free(who_buf); ++ goto out; ++ } ++ ++ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_NAMED, ++ who_buf); ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ } ++ ++ /* In the case of groups, we apply allow ACEs first, then deny ACEs, ++ * since a user can be in more than one group. */ ++ ++ /* allow ACEs */ ++ ++ if (num_aces > 3) { ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ if (ace_type != ACL_GROUP_OBJ) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask, ++ NFS4_ACL_WHO_GROUP, NULL); ++ ++ if (result < 0) ++ goto out; ++ } ++ ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, NFS4_ACL_WHO_GROUP, NULL); ++ ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ while (ace_type == ACL_GROUP && result > 0) { ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ gid_p = acl_get_qualifier(pace_p); ++ ++ who_buf = who_buf_static; ++ who_buflen = who_buflen_static; ++ ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen); ++ ++ ++ while (result == -ENOBUFS) { ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ ++ /* Increase the size by a full buflen unit */ ++ who_buflen += who_buflen_static; ++ who_buf = malloc(who_buflen); ++ ++ if (who_buf == NULL) { ++ result = -ENOMEM; ++ break; ++ } ++ ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen); ++ } ++ ++ acl_free(gid_p); ++ ++ if (result < 0) { ++ errno = -result; ++ goto out; ++ } ++ ++ if (who_buf == NULL) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask, ++ NFS4_ACL_WHO_NAMED, who_buf); ++ if (result < 0) { ++ if(who_buf != who_buf_static) ++ free(who_buf); ++ goto out; ++ } ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, ++ NFS4_ACL_WHO_NAMED, who_buf); ++ ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ ++ if (result < 0) ++ goto out; ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ } ++ ++ /* deny ACEs */ ++ ++ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ while (ace_type != ACL_GROUP_OBJ && result > 0) { ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if(result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if(result2 < 0) ++ goto out; ++ } ++ ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, ~mask, NFS4_ACL_WHO_GROUP, ++ NULL); ++ ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ while (ace_type == ACL_GROUP && result > 0) { ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ gid_p = acl_get_qualifier(pace_p); ++ ++ who_buf = who_buf_static; ++ who_buflen = who_buflen_static; ++ ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen); ++ ++ ++ while (result == -ENOBUFS) { ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ ++ /* Increase the size by a full buflen unit */ ++ who_buflen += who_buflen_static; ++ who_buf = malloc(who_buflen); ++ ++ if (who_buf == NULL) { ++ result = -ENOMEM; ++ break; ++ } ++ ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen); ++ } ++ ++ acl_free(gid_p); ++ ++ if (result < 0) { ++ errno = -result; ++ goto out; ++ } ++ ++ if (who_buf == NULL) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, ~mask, ++ NFS4_ACL_WHO_NAMED, who_buf); ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ } ++ ++ if (ace_type == ACL_MASK) { ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ } ++ ++ if (ace_type != ACL_OTHER) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_EVERYONE, NULL); ++ ++ return result; ++out: ++ if (allocated) ++ acl_nfs4_free(acl); ++ return -1; ++} +--- acl-2.2.39/libacl/acl_get_fd.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_get_fd.c 2007-08-22 12:02:13.000000000 -0400 +@@ -28,6 +28,10 @@ + #include "libacl.h" + #include "__acl_from_xattr.h" + ++#ifdef USE_NFSV4_TRANS ++ #include "libacl_nfs4.h" ++#endif ++ + #include "byteorder.h" + #include "acl_ea.h" + +@@ -38,31 +42,59 @@ acl_get_fd(int fd) + { + const size_t size_guess = acl_ea_size(16); + char *ext_acl_p = alloca(size_guess); ++ char *name = ACL_EA_ACCESS; + int retval; ++ int nfsv4acls; + + if (!ext_acl_p) + return NULL; +- retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p, size_guess); ++ ++#ifdef USE_NFSV4_TRANS ++ retval = fgetxattr(fd, ACL_NFS4_XATTR, ext_acl_p, size_guess); ++ if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) { ++ nfsv4acls = ACL_NFS4_NOT_USED; ++ retval = fgetxattr(fd, name, ext_acl_p, size_guess); ++ } else { ++ nfsv4acls = ACL_NFS4_USED; ++ name = ACL_NFS4_XATTR; ++ } ++#else ++ retval = fgetxattr(fd, name, ext_acl_p, size_guess); ++#endif ++ + if (retval == -1 && errno == ERANGE) { +- retval = fgetxattr(fd, ACL_EA_ACCESS, NULL, 0); ++ retval = fgetxattr(fd, name, NULL, 0); + if (retval > 0) { + ext_acl_p = alloca(retval); + if (!ext_acl_p) + return NULL; +- retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p,retval); ++ retval = fgetxattr(fd, name, ext_acl_p, retval); + } + } + if (retval > 0) { +- acl_t acl = __acl_from_xattr(ext_acl_p, retval); +- return acl; ++#ifdef USE_NFSV4_TRANS ++ if(nfsv4acls == ACL_NFS4_USED) { ++ acl_t acl = __posix_acl_from_nfs4_xattr(ext_acl_p, retval, ++ ACL_TYPE_ACCESS, NFS4_ACL_ISFILE); ++ ++ return acl; ++ } ++ else ++#endif ++ { ++ acl_t acl = __acl_from_xattr(ext_acl_p, retval); ++ return acl; ++ } + } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) { + struct stat st; + +- if (fstat(fd, &st) == 0) +- return acl_from_mode(st.st_mode); +- else ++ if (fstat(fd, &st) != 0) { + return NULL; +- } else ++ } ++ ++ return acl_from_mode(st.st_mode); ++ } else { + return NULL; ++ } + } + +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_xattr_size.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,91 @@ ++/* ++ * NFSv4 ACL Code ++ * Return the expected xattr XDR encoded size of the nfs acl. Used for ++ * figuring the size of the xattr buffer. ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include <libacl_nfs4.h> ++ ++int acl_nfs4_xattr_size(struct nfs4_acl * acl) ++{ ++ int size = 0; ++ struct nfs4_ace * ace; ++ int ace_num; ++ int num_aces; ++ ++ if(acl == NULL) { ++ errno = EINVAL; ++ goto failed; ++ } ++ ++ /* Space for number of aces */ ++ size += sizeof(u32); ++ ++ ace = acl->ace_head.tqh_first; ++ ace_num = 1; ++ ++ num_aces = acl->naces; ++ ++ while(1) ++ { ++ if(ace == NULL) { ++ if(ace_num > num_aces) { ++ break; ++ } else { ++ errno = ENODATA; ++ goto failed; ++ } ++ } ++ ++ /* space for type, flag, and mask */ ++ size += (3 * sizeof(u32)); ++ ++ /* space for strlen */ ++ size += sizeof(u32); ++ ++ /* space for the who string... xdr encoded */ ++ size += (strlen(ace->who) / NFS4_XDR_MOD) * NFS4_XDR_MOD * sizeof(char); ++ if(strlen(ace->who) % NFS4_XDR_MOD) { ++ size += NFS4_XDR_MOD; ++ } ++ ++ ace = ace->l_ace.tqe_next; ++ ace_num++; ++ } ++ ++ return size; ++ ++failed: ++ return -1; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_ptn4_get_mask.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,81 @@ ++/* ++ * NFSv4 ACL Code ++ * Translate POSIX permissions to an NFSv4 mask ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include <acl/libacl.h> ++#include <libacl_nfs4.h> ++ ++int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, int iflags) ++{ ++ int result; ++ ++ *mask = NFS4_ANYONE_MODE; ++ ++ if (perms == NULL) { ++ errno = EINVAL; ++ goto failed; ++ } ++ ++ if (iflags & NFS4_ACL_OWNER) ++ *mask |= NFS4_OWNER_MODE; ++ ++ result = acl_get_perm(perms, ACL_READ); ++ if (result < 0) ++ goto failed; ++ else if(result == 1) ++ *mask |= NFS4_READ_MODE; ++ ++ result = acl_get_perm(perms, ACL_WRITE); ++ if (result < 0) ++ goto failed; ++ else if (result == 1) { ++ *mask |= NFS4_WRITE_MODE; ++ if (iflags & NFS4_ACL_ISDIR) ++ *mask |= NFS4_ACE_DELETE_CHILD; ++ } ++ ++ result = acl_get_perm(perms, ACL_EXECUTE); ++ if (result < 0) ++ goto failed; ++ else if (result == 1) ++ *mask |= NFS4_EXECUTE_MODE; ++ ++ return 0; ++ ++failed: ++ return -1; ++} ++ ++ ++ +--- acl-2.2.39/libacl/acl_get_file.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_get_file.c 2007-08-22 12:02:13.000000000 -0400 +@@ -28,6 +28,10 @@ + #include "libacl.h" + #include "__acl_from_xattr.h" + ++#ifdef USE_NFSV4_TRANS ++ #include "libacl_nfs4.h" ++#endif ++ + #include "byteorder.h" + #include "acl_ea.h" + +@@ -40,6 +44,8 @@ acl_get_file(const char *path_p, acl_typ + char *ext_acl_p = alloca(size_guess); + const char *name; + int retval; ++ int nfsv4acls; ++ int iflags; + + switch(type) { + case ACL_TYPE_ACCESS: +@@ -55,8 +61,20 @@ acl_get_file(const char *path_p, acl_typ + + if (!ext_acl_p) + return NULL; ++#ifdef USE_NFSV4_TRANS ++ retval = getxattr(path_p, ACL_NFS4_XATTR, ext_acl_p, size_guess); ++ if((retval == -1) && (errno == ENOATTR || errno == EOPNOTSUPP)) { ++ nfsv4acls = ACL_NFS4_NOT_USED; ++ retval = getxattr(path_p, name, ext_acl_p, size_guess); ++ } else { ++ nfsv4acls = ACL_NFS4_USED; ++ name = ACL_NFS4_XATTR; ++ } ++#else + retval = getxattr(path_p, name, ext_acl_p, size_guess); +- if (retval == -1 && errno == ERANGE) { ++#endif ++ ++ if ((retval == -1) && (errno == ERANGE)) { + retval = getxattr(path_p, name, NULL, 0); + if (retval > 0) { + ext_acl_p = alloca(retval); +@@ -66,9 +84,29 @@ acl_get_file(const char *path_p, acl_typ + } + } + if (retval > 0) { +- acl_t acl = __acl_from_xattr(ext_acl_p, retval); +- return acl; +- } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) { ++#ifdef USE_NFSV4_TRANS ++ if(nfsv4acls == ACL_NFS4_USED) { ++ struct stat st; ++ ++ iflags = NFS4_ACL_ISFILE; ++ ++ if (stat(path_p, &st) != 0) ++ return NULL; ++ ++ if (S_ISDIR(st.st_mode)) ++ iflags = NFS4_ACL_ISDIR; ++ ++ acl_t acl = __posix_acl_from_nfs4_xattr(ext_acl_p, retval, type, ++ iflags); ++ return acl; ++ } ++ else ++#endif ++ { ++ acl_t acl = __acl_from_xattr(ext_acl_p, retval); ++ return acl; ++ } ++ } else if ((retval == 0) || (errno == ENOATTR) || (errno == ENODATA)) { + struct stat st; + + if (stat(path_p, &st) != 0) +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/libacl_nfs4.h 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,97 @@ ++#include <sys/types.h> ++#include <pwd.h> ++#include <grp.h> ++#include <sys/acl.h> ++#include <stdlib.h> ++#include <sys/queue.h> ++#include <nfs4.h> ++#include <sys/errno.h> ++#include <string.h> ++ ++/* mode bit translations: */ ++#define NFS4_READ_MODE NFS4_ACE_READ_DATA ++#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) ++#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE ++#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \ ++ NFS4_ACE_SYNCHRONIZE) ++#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) ++ ++#define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \ ++ | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS) ++/* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in ++ * general (should only be ignored on files). */ ++#define MASK_EQUAL(mask1, mask2) \ ++ (((mask1) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \ ++ ~NFS4_ACE_DELETE_CHILD) \ ++ == ((mask2) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \ ++ ~NFS4_ACE_DELETE_CHILD)) ++ ++/* Maximum length of the ace->who attribute */ ++#define NFS4_ACL_WHO_LENGTH_MAX 2048 ++#define NFS4_ACL_WHO_BUFFER_LEN_GUESS 255 ++ ++/* NFS4 acl xattr name */ ++#define ACL_NFS4_XATTR "system.nfs4_acl" ++ ++/* Macro for finding empty tailqs */ ++#define TAILQ_IS_EMPTY(head) (head.tqh_first == NULL) ++ ++/* Flags to pass certain properties around */ ++#define NFS4_ACL_NOFLAGS 0x00 ++#define NFS4_ACL_ISFILE 0x00 ++#define NFS4_ACL_ISDIR 0x01 ++#define NFS4_ACL_OWNER 0x02 ++#define NFS4_ACL_REQUEST_DEFAULT 0x04 ++#define NFS4_ACL_RAW 0x01 ++ ++#define NFS4_XDR_MOD 4 ++ ++typedef u_int32_t u32; ++ ++enum { ACL_NFS4_NOT_USED = 0, ++ ACL_NFS4_USED ++}; ++ ++struct ace_container { ++ struct nfs4_ace *ace; ++ TAILQ_ENTRY(ace_container) l_ace; ++}; ++ ++TAILQ_HEAD(ace_container_list_head, ace_container); ++ ++/**** Public functions ****/ ++ ++/** Manipulation functions **/ ++extern int acl_nfs4_add_ace(struct nfs4_acl *, u32, u32, u32, int, char*); ++extern int acl_nfs4_add_pair(struct nfs4_acl *, int, u32, int, char*); ++extern void acl_nfs4_free(struct nfs4_acl *); ++extern struct nfs4_acl *acl_nfs4_new(u32); ++extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*); ++extern struct nfs4_acl *acl_nfs4_copy_acl(struct nfs4_acl *); ++extern struct nfs4_acl *acl_nfs4_xattr_load(char *, int, u32); ++extern int acl_nfs4_xattr_pack(struct nfs4_acl *, char**); ++extern int acl_nfs4_xattr_size(struct nfs4_acl *); ++extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace); ++ ++/** Conversion functions **/ ++ ++/* nfs4 -> posix */ ++extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t); ++ ++/* posix -> nfs4 */ ++extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, ++ int iflags); ++extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*); ++ ++ ++/** Access Functions **/ ++extern inline int acl_nfs4_get_whotype(char*); ++extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**); ++ ++/**** Private(?) functions ****/ ++acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32); ++ ++/* These will change */ ++char * nfs4_get_who_from_uid(uid_t); ++char * nfs4_get_who_from_gid(gid_t); ++/* End change */ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_new.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,58 @@ ++/* ++ * Common NFSv4 ACL handling code. ++ * Create a new NFSv4 ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen <marius@umich.edu> ++ * J. Bruce Fields <bfields@umich.edu> ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * Jeff Sedlak <jsedlak@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++ ++ ++#include "libacl_nfs4.h" ++ ++struct nfs4_acl * ++acl_nfs4_new(u32 is_dir) ++{ ++ struct nfs4_acl *acl; ++ ++ if ((acl = malloc(sizeof(*acl))) == NULL) ++ return NULL; ++ ++ acl->naces = 0; ++ acl->is_directory = is_dir; ++ ++ TAILQ_INIT(&acl->ace_head); ++ ++ return acl; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_copy_acl.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,85 @@ ++/* ++ * NFSv4 ACL Code ++ * Deep copy an NFS4 ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "libacl_nfs4.h" ++ ++struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl * nacl) ++{ ++ struct nfs4_acl * new_acl; ++ struct nfs4_ace * ace; ++ u32 nace; ++ u32 num_aces; ++ int result; ++ ++ if(nacl == NULL) { ++ errno = EINVAL; ++ goto failed; ++ } ++ ++ num_aces = nacl->naces; ++ ++ new_acl = acl_nfs4_new(nacl->is_directory); ++ if(new_acl == NULL) ++ goto failed; ++ ++ ace = nacl->ace_head.tqh_first; ++ nace = 1; ++ ++ while(1) ++ { ++ if(ace == NULL) { ++ if(nace > num_aces) ++ break; ++ else ++ goto free_failed; ++ } ++ ++ result = acl_nfs4_add_ace(new_acl, ace->type, ace->flag, ++ ace->access_mask, acl_nfs4_get_whotype(ace->who), ace->who); ++ if(result < 0) ++ goto free_failed; ++ ++ ace = ace->l_ace.tqe_next; ++ nace++; ++ } ++ ++ return new_acl; ++ ++free_failed: ++ acl_nfs4_free(new_acl); ++ ++failed: ++ return NULL; ++} +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_add_pair.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,60 @@ ++/* ++ * Add a pair of aces to the acl. The ace masks are complements of each other ++ * This keeps us from walking off the end of the acl ++ * ++ * Copyright (c) 2004 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen <marius@umich.edu> ++ * J. Bruce Fields <bfields@umich.edu> ++ * Nathaniel Gallaher <ngallahe@umich.edu> ++ * Jeff Sedlak <jsedlak@umich.edu> ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, the following disclaimer, and ++ * any and all other licensing or copyright notices included in ++ * any files in this distribution. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of the University nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ++ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++ ++#include "libacl_nfs4.h" ++ ++int ++acl_nfs4_add_pair(struct nfs4_acl *acl, int eflag, u32 mask, int ownertype, ++ char* owner) ++{ ++ int error; ++ ++ error = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, ++ eflag, mask, ownertype, owner); ++ if (error < 0) ++ return error; ++ error = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ eflag, ~mask, ownertype, owner); ++ return error; ++} ++ ++ +--- acl-2.2.39/exports.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/exports 2007-08-22 12:02:13.000000000 -0400 +@@ -67,3 +67,33 @@ ACL_1.1 { + perm_copy_fd; + perm_copy_file; + } ACL_1.0; ++ ++ACL_1.2 { ++ global: ++ acl_nfs4_add_ace; ++ acl_nfs4_add_pair; ++ acl_nfs4_free; ++ acl_nfs4_new; ++ acl_nfs4_set_dir; ++ acl_nfs4_set_who; ++ acl_nfs4_copy_acl; ++ acl_nfs4_xattr_load; ++ acl_nfs4_xattr_pack; ++ acl_nfs4_xattr_size; ++ acl_nfs4_remove_ace; ++ ++ acl_n4tp_acl_trans; ++ ++ acl_ptn4_get_mask; ++ acl_ptn4_acl_trans; ++ ++ acl_nfs4_get_whotype; ++ acl_nfs4_get_who; ++ acl_nfs4_entries; ++ ++ local: ++ __posix_acl_from_nfs4_xattr; ++ nfs4_get_who_from_uid; ++ nfs4_get_who_from_gid; ++ ++} ACL_1.1; +--- acl-2.2.39/include/builddefs.in.orig 2007-08-22 11:59:37.000000000 -0400 ++++ acl-2.2.39/include/builddefs.in 2007-08-22 12:02:13.000000000 -0400 +@@ -65,7 +65,7 @@ endif + + GCFLAGS = $(OPTIMIZER) $(DEBUG) -funsigned-char -fno-strict-aliasing -Wall \ + -DVERSION="$(PKG_VERSION)" -DLOCALEDIR="$(PKG_LOCALE_DIR)" \ +- -DPACKAGE="$(PKG_NAME)" -I$(TOPDIR)/include ++ -DPACKAGE="$(PKG_NAME)" -I$(TOPDIR)/include -DUSE_NFSV4_TRANS + + # Global, Platform, Local CFLAGS + CFLAGS += $(GCFLAGS) $(PCFLAGS) $(LCFLAGS) +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/include/nfs4.h 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,397 @@ ++/* ++ * NFSv4 protocol definitions. ++ * ++ * Copyright (c) 2002 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Kendrick Smith <kmsmith@umich.edu> ++ * Andy Adamson <andros@umich.edu> ++ */ ++ ++#include<sys/types.h> ++#include<sys/queue.h> ++ ++#ifndef _LINUX_NFS4_H ++#define _LINUX_NFS4_H ++ ++#define NFS4_VERIFIER_SIZE 8 ++#define NFS4_FHSIZE 128 ++#define NFS4_MAXNAMLEN NAME_MAX ++ ++#define NFS4_ACCESS_READ 0x0001 ++#define NFS4_ACCESS_LOOKUP 0x0002 ++#define NFS4_ACCESS_MODIFY 0x0004 ++#define NFS4_ACCESS_EXTEND 0x0008 ++#define NFS4_ACCESS_DELETE 0x0010 ++#define NFS4_ACCESS_EXECUTE 0x0020 ++ ++#define NFS4_FH_PERISTENT 0x0000 ++#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001 ++#define NFS4_FH_VOLATILE_ANY 0x0002 ++#define NFS4_FH_VOL_MIGRATION 0x0004 ++#define NFS4_FH_VOL_RENAME 0x0008 ++ ++#define NFS4_OPEN_RESULT_CONFIRM 0x0002 ++ ++#define NFS4_SHARE_ACCESS_READ 0x0001 ++#define NFS4_SHARE_ACCESS_WRITE 0x0002 ++#define NFS4_SHARE_ACCESS_BOTH 0x0003 ++#define NFS4_SHARE_DENY_READ 0x0001 ++#define NFS4_SHARE_DENY_WRITE 0x0002 ++#define NFS4_SHARE_DENY_BOTH 0x0003 ++ ++#define NFS4_SET_TO_SERVER_TIME 0 ++#define NFS4_SET_TO_CLIENT_TIME 1 ++ ++#define NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE 0 ++#define NFS4_ACE_ACCESS_DENIED_ACE_TYPE 1 ++#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2 ++#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3 ++ ++#define ACL4_SUPPORT_ALLOW_ACL 0x01 ++#define ACL4_SUPPORT_DENY_ACL 0x02 ++#define ACL4_SUPPORT_AUDIT_ACL 0x04 ++#define ACL4_SUPPORT_ALARM_ACL 0x08 ++ ++#define NFS4_ACE_FILE_INHERIT_ACE 0x00000001 ++#define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002 ++#define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004 ++#define NFS4_ACE_INHERIT_ONLY_ACE 0x00000008 ++#define NFS4_ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010 ++#define NFS4_ACE_FAILED_ACCESS_ACE_FLAG 0x00000020 ++#define NFS4_ACE_IDENTIFIER_GROUP 0x00000040 ++#define NFS4_ACE_OWNER 0x00000080 ++#define NFS4_ACE_GROUP 0x00000100 ++#define NFS4_ACE_EVERYONE 0x00000200 ++ ++#define NFS4_ACE_READ_DATA 0x00000001 ++#define NFS4_ACE_LIST_DIRECTORY 0x00000001 ++#define NFS4_ACE_WRITE_DATA 0x00000002 ++#define NFS4_ACE_ADD_FILE 0x00000002 ++#define NFS4_ACE_APPEND_DATA 0x00000004 ++#define NFS4_ACE_ADD_SUBDIRECTORY 0x00000004 ++#define NFS4_ACE_READ_NAMED_ATTRS 0x00000008 ++#define NFS4_ACE_WRITE_NAMED_ATTRS 0x00000010 ++#define NFS4_ACE_EXECUTE 0x00000020 ++#define NFS4_ACE_DELETE_CHILD 0x00000040 ++#define NFS4_ACE_READ_ATTRIBUTES 0x00000080 ++#define NFS4_ACE_WRITE_ATTRIBUTES 0x00000100 ++#define NFS4_ACE_DELETE 0x00010000 ++#define NFS4_ACE_READ_ACL 0x00020000 ++#define NFS4_ACE_WRITE_ACL 0x00040000 ++#define NFS4_ACE_WRITE_OWNER 0x00080000 ++#define NFS4_ACE_SYNCHRONIZE 0x00100000 ++#define NFS4_ACE_GENERIC_READ 0x00120081 ++#define NFS4_ACE_GENERIC_WRITE 0x00160106 ++#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0 ++#define NFS4_ACE_MASK_ALL 0x001F01FF ++ ++enum nfs4_acl_whotype { ++ NFS4_ACL_WHO_NAMED = 0, ++ NFS4_ACL_WHO_OWNER, ++ NFS4_ACL_WHO_GROUP, ++ NFS4_ACL_WHO_EVERYONE, ++}; ++ ++#define NFS4_ACL_WHO_OWNER_STRING "OWNER@" ++#define NFS4_ACL_WHO_GROUP_STRING "GROUP@" ++#define NFS4_ACL_WHO_EVERYONE_STRING "EVERYONE@" ++ ++struct nfs4_ace { ++ u_int32_t type; ++ u_int32_t flag; ++ u_int32_t access_mask; ++ char* who; ++ TAILQ_ENTRY(nfs4_ace) l_ace; ++}; ++ ++TAILQ_HEAD(ace_list_head, nfs4_ace); ++ ++struct nfs4_acl { ++ u_int32_t naces; ++ u_int32_t is_directory; ++ struct ace_list_head ace_head; ++}; ++ ++typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; ++typedef struct { char data[16]; } nfs4_stateid; ++ ++enum nfs_opnum4 { ++ OP_ACCESS = 3, ++ OP_CLOSE = 4, ++ OP_COMMIT = 5, ++ OP_CREATE = 6, ++ OP_DELEGPURGE = 7, ++ OP_DELEGRETURN = 8, ++ OP_GETATTR = 9, ++ OP_GETFH = 10, ++ OP_LINK = 11, ++ OP_LOCK = 12, ++ OP_LOCKT = 13, ++ OP_LOCKU = 14, ++ OP_LOOKUP = 15, ++ OP_LOOKUPP = 16, ++ OP_NVERIFY = 17, ++ OP_OPEN = 18, ++ OP_OPENATTR = 19, ++ OP_OPEN_CONFIRM = 20, ++ OP_OPEN_DOWNGRADE = 21, ++ OP_PUTFH = 22, ++ OP_PUTPUBFH = 23, ++ OP_PUTROOTFH = 24, ++ OP_READ = 25, ++ OP_READDIR = 26, ++ OP_READLINK = 27, ++ OP_REMOVE = 28, ++ OP_RENAME = 29, ++ OP_RENEW = 30, ++ OP_RESTOREFH = 31, ++ OP_SAVEFH = 32, ++ OP_SECINFO = 33, ++ OP_SETATTR = 34, ++ OP_SETCLIENTID = 35, ++ OP_SETCLIENTID_CONFIRM = 36, ++ OP_VERIFY = 37, ++ OP_WRITE = 38, ++ OP_RELEASE_LOCKOWNER = 39, ++ OP_ILLEGAL = 10044, ++}; ++ ++enum nfsstat4 { ++ NFS4_OK = 0, ++ NFS4ERR_PERM = 1, ++ NFS4ERR_NOENT = 2, ++ NFS4ERR_IO = 5, ++ NFS4ERR_NXIO = 6, ++ NFS4ERR_ACCESS = 13, ++ NFS4ERR_EXIST = 17, ++ NFS4ERR_XDEV = 18, ++ /* Unused/reserved 19 */ ++ NFS4ERR_NOTDIR = 20, ++ NFS4ERR_ISDIR = 21, ++ NFS4ERR_INVAL = 22, ++ NFS4ERR_FBIG = 27, ++ NFS4ERR_NOSPC = 28, ++ NFS4ERR_ROFS = 30, ++ NFS4ERR_MLINK = 31, ++ NFS4ERR_NAMETOOLONG = 63, ++ NFS4ERR_NOTEMPTY = 66, ++ NFS4ERR_DQUOT = 69, ++ NFS4ERR_STALE = 70, ++ NFS4ERR_BADHANDLE = 10001, ++ NFS4ERR_BAD_COOKIE = 10003, ++ NFS4ERR_NOTSUPP = 10004, ++ NFS4ERR_TOOSMALL = 10005, ++ NFS4ERR_SERVERFAULT = 10006, ++ NFS4ERR_BADTYPE = 10007, ++ NFS4ERR_DELAY = 10008, ++ NFS4ERR_SAME = 10009, ++ NFS4ERR_DENIED = 10010, ++ NFS4ERR_EXPIRED = 10011, ++ NFS4ERR_LOCKED = 10012, ++ NFS4ERR_GRACE = 10013, ++ NFS4ERR_FHEXPIRED = 10014, ++ NFS4ERR_SHARE_DENIED = 10015, ++ NFS4ERR_WRONGSEC = 10016, ++ NFS4ERR_CLID_INUSE = 10017, ++ NFS4ERR_RESOURCE = 10018, ++ NFS4ERR_MOVED = 10019, ++ NFS4ERR_NOFILEHANDLE = 10020, ++ NFS4ERR_MINOR_VERS_MISMATCH = 10021, ++ NFS4ERR_STALE_CLIENTID = 10022, ++ NFS4ERR_STALE_STATEID = 10023, ++ NFS4ERR_OLD_STATEID = 10024, ++ NFS4ERR_BAD_STATEID = 10025, ++ NFS4ERR_BAD_SEQID = 10026, ++ NFS4ERR_NOT_SAME = 10027, ++ NFS4ERR_LOCK_RANGE = 10028, ++ NFS4ERR_SYMLINK = 10029, ++ NFS4ERR_RESTOREFH = 10030, ++ NFS4ERR_LEASE_MOVED = 10031, ++ NFS4ERR_ATTRNOTSUPP = 10032, ++ NFS4ERR_NO_GRACE = 10033, ++ NFS4ERR_RECLAIM_BAD = 10034, ++ NFS4ERR_RECLAIM_CONFLICT = 10035, ++ NFS4ERR_BADXDR = 10036, ++ NFS4ERR_LOCKS_HELD = 10037, ++ NFS4ERR_OPENMODE = 10038, ++ NFS4ERR_BADOWNER = 10039, ++ NFS4ERR_BADCHAR = 10040, ++ NFS4ERR_BADNAME = 10041, ++ NFS4ERR_BAD_RANGE = 10042, ++ NFS4ERR_LOCK_NOTSUPP = 10043, ++ NFS4ERR_OP_ILLEGAL = 10044, ++ NFS4ERR_DEADLOCK = 10045, ++ NFS4ERR_FILE_OPEN = 10046, ++ NFS4ERR_ADMIN_REVOKED = 10047, ++ NFS4ERR_CB_PATH_DOWN = 10048 ++}; ++ ++/* ++ * Note: NF4BAD is not actually part of the protocol; it is just used ++ * internally by nfsd. ++ */ ++enum nfs_ftype4 { ++ NF4BAD = 0, ++ NF4REG = 1, /* Regular File */ ++ NF4DIR = 2, /* Directory */ ++ NF4BLK = 3, /* Special File - block device */ ++ NF4CHR = 4, /* Special File - character device */ ++ NF4LNK = 5, /* Symbolic Link */ ++ NF4SOCK = 6, /* Special File - socket */ ++ NF4FIFO = 7, /* Special File - fifo */ ++ NF4ATTRDIR = 8, /* Attribute Directory */ ++ NF4NAMEDATTR = 9 /* Named Attribute */ ++}; ++ ++enum open_claim_type4 { ++ NFS4_OPEN_CLAIM_NULL = 0, ++ NFS4_OPEN_CLAIM_PREVIOUS = 1, ++ NFS4_OPEN_CLAIM_DELEGATE_CUR = 2, ++ NFS4_OPEN_CLAIM_DELEGATE_PREV = 3 ++}; ++ ++enum opentype4 { ++ NFS4_OPEN_NOCREATE = 0, ++ NFS4_OPEN_CREATE = 1 ++}; ++ ++enum createmode4 { ++ NFS4_CREATE_UNCHECKED = 0, ++ NFS4_CREATE_GUARDED = 1, ++ NFS4_CREATE_EXCLUSIVE = 2 ++}; ++ ++enum limit_by4 { ++ NFS4_LIMIT_SIZE = 1, ++ NFS4_LIMIT_BLOCKS = 2 ++}; ++ ++enum open_delegation_type4 { ++ NFS4_OPEN_DELEGATE_NONE = 0, ++ NFS4_OPEN_DELEGATE_READ = 1, ++ NFS4_OPEN_DELEGATE_WRITE = 2 ++}; ++ ++enum lock_type4 { ++ NFS4_UNLOCK_LT = 0, ++ NFS4_READ_LT = 1, ++ NFS4_WRITE_LT = 2, ++ NFS4_READW_LT = 3, ++ NFS4_WRITEW_LT = 4 ++}; ++ ++ ++/* Mandatory Attributes */ ++#define FATTR4_WORD0_SUPPORTED_ATTRS (1UL << 0) ++#define FATTR4_WORD0_TYPE (1UL << 1) ++#define FATTR4_WORD0_FH_EXPIRE_TYPE (1UL << 2) ++#define FATTR4_WORD0_CHANGE (1UL << 3) ++#define FATTR4_WORD0_SIZE (1UL << 4) ++#define FATTR4_WORD0_LINK_SUPPORT (1UL << 5) ++#define FATTR4_WORD0_SYMLINK_SUPPORT (1UL << 6) ++#define FATTR4_WORD0_NAMED_ATTR (1UL << 7) ++#define FATTR4_WORD0_FSID (1UL << 8) ++#define FATTR4_WORD0_UNIQUE_HANDLES (1UL << 9) ++#define FATTR4_WORD0_LEASE_TIME (1UL << 10) ++#define FATTR4_WORD0_RDATTR_ERROR (1UL << 11) ++ ++/* Recommended Attributes */ ++#define FATTR4_WORD0_ACL (1UL << 12) ++#define FATTR4_WORD0_ACLSUPPORT (1UL << 13) ++#define FATTR4_WORD0_ARCHIVE (1UL << 14) ++#define FATTR4_WORD0_CANSETTIME (1UL << 15) ++#define FATTR4_WORD0_CASE_INSENSITIVE (1UL << 16) ++#define FATTR4_WORD0_CASE_PRESERVING (1UL << 17) ++#define FATTR4_WORD0_CHOWN_RESTRICTED (1UL << 18) ++#define FATTR4_WORD0_FILEHANDLE (1UL << 19) ++#define FATTR4_WORD0_FILEID (1UL << 20) ++#define FATTR4_WORD0_FILES_AVAIL (1UL << 21) ++#define FATTR4_WORD0_FILES_FREE (1UL << 22) ++#define FATTR4_WORD0_FILES_TOTAL (1UL << 23) ++#define FATTR4_WORD0_FS_LOCATIONS (1UL << 24) ++#define FATTR4_WORD0_HIDDEN (1UL << 25) ++#define FATTR4_WORD0_HOMOGENEOUS (1UL << 26) ++#define FATTR4_WORD0_MAXFILESIZE (1UL << 27) ++#define FATTR4_WORD0_MAXLINK (1UL << 28) ++#define FATTR4_WORD0_MAXNAME (1UL << 29) ++#define FATTR4_WORD0_MAXREAD (1UL << 30) ++#define FATTR4_WORD0_MAXWRITE (1UL << 31) ++#define FATTR4_WORD1_MIMETYPE (1UL << 0) ++#define FATTR4_WORD1_MODE (1UL << 1) ++#define FATTR4_WORD1_NO_TRUNC (1UL << 2) ++#define FATTR4_WORD1_NUMLINKS (1UL << 3) ++#define FATTR4_WORD1_OWNER (1UL << 4) ++#define FATTR4_WORD1_OWNER_GROUP (1UL << 5) ++#define FATTR4_WORD1_QUOTA_HARD (1UL << 6) ++#define FATTR4_WORD1_QUOTA_SOFT (1UL << 7) ++#define FATTR4_WORD1_QUOTA_USED (1UL << 8) ++#define FATTR4_WORD1_RAWDEV (1UL << 9) ++#define FATTR4_WORD1_SPACE_AVAIL (1UL << 10) ++#define FATTR4_WORD1_SPACE_FREE (1UL << 11) ++#define FATTR4_WORD1_SPACE_TOTAL (1UL << 12) ++#define FATTR4_WORD1_SPACE_USED (1UL << 13) ++#define FATTR4_WORD1_SYSTEM (1UL << 14) ++#define FATTR4_WORD1_TIME_ACCESS (1UL << 15) ++#define FATTR4_WORD1_TIME_ACCESS_SET (1UL << 16) ++#define FATTR4_WORD1_TIME_BACKUP (1UL << 17) ++#define FATTR4_WORD1_TIME_CREATE (1UL << 18) ++#define FATTR4_WORD1_TIME_DELTA (1UL << 19) ++#define FATTR4_WORD1_TIME_METADATA (1UL << 20) ++#define FATTR4_WORD1_TIME_MODIFY (1UL << 21) ++#define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22) ++#define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23) ++ ++#define NFSPROC4_NULL 0 ++#define NFSPROC4_COMPOUND 1 ++#define NFS4_MINOR_VERSION 0 ++#define NFS4_DEBUG 1 ++ ++#ifdef __KERNEL__ ++ ++/* Index of predefined Linux client operations */ ++ ++enum { ++ NFSPROC4_CLNT_NULL = 0, /* Unused */ ++ NFSPROC4_CLNT_READ, ++ NFSPROC4_CLNT_WRITE, ++ NFSPROC4_CLNT_COMMIT, ++ NFSPROC4_CLNT_OPEN, ++ NFSPROC4_CLNT_OPEN_CONFIRM, ++ NFSPROC4_CLNT_OPEN_RECLAIM, ++ NFSPROC4_CLNT_OPEN_DOWNGRADE, ++ NFSPROC4_CLNT_CLOSE, ++ NFSPROC4_CLNT_SETATTR, ++ NFSPROC4_CLNT_FSINFO, ++ NFSPROC4_CLNT_RENEW, ++ NFSPROC4_CLNT_SETCLIENTID, ++ NFSPROC4_CLNT_SETCLIENTID_CONFIRM, ++ NFSPROC4_CLNT_LOCK, ++ NFSPROC4_CLNT_LOCKT, ++ NFSPROC4_CLNT_LOCKU, ++ NFSPROC4_CLNT_ACCESS, ++ NFSPROC4_CLNT_GETATTR, ++ NFSPROC4_CLNT_LOOKUP, ++ NFSPROC4_CLNT_LOOKUP_ROOT, ++ NFSPROC4_CLNT_REMOVE, ++ NFSPROC4_CLNT_RENAME, ++ NFSPROC4_CLNT_LINK, ++ NFSPROC4_CLNT_CREATE, ++ NFSPROC4_CLNT_PATHCONF, ++ NFSPROC4_CLNT_STATFS, ++ NFSPROC4_CLNT_READLINK, ++ NFSPROC4_CLNT_READDIR, ++ NFSPROC4_CLNT_SERVER_CAPS, ++ NFSPROC4_CLNT_DELEGRETURN, ++ NFSPROC4_CLNT_GETACL, ++ NFSPROC4_CLNT_SETACL, ++}; ++ ++#endif ++#endif ++ ++/* ++ * Local variables: ++ * c-basic-offset: 8 ++ * End: ++ */ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/include/libacl_nfs4.h 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,97 @@ ++#include <sys/types.h> ++#include <pwd.h> ++#include <grp.h> ++#include <sys/acl.h> ++#include <stdlib.h> ++#include <sys/queue.h> ++#include <nfs4.h> ++#include <sys/errno.h> ++#include <string.h> ++ ++/* mode bit translations: */ ++#define NFS4_READ_MODE NFS4_ACE_READ_DATA ++#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) ++#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE ++#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \ ++ NFS4_ACE_SYNCHRONIZE) ++#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) ++ ++#define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \ ++ | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS) ++/* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in ++ * general (should only be ignored on files). */ ++#define MASK_EQUAL(mask1, mask2) \ ++ (((mask1) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \ ++ ~NFS4_ACE_DELETE_CHILD) \ ++ == ((mask2) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \ ++ ~NFS4_ACE_DELETE_CHILD)) ++ ++/* Maximum length of the ace->who attribute */ ++#define NFS4_ACL_WHO_LENGTH_MAX 2048 ++#define NFS4_ACL_WHO_BUFFER_LEN_GUESS 255 ++ ++/* NFS4 acl xattr name */ ++#define ACL_NFS4_XATTR "system.nfs4_acl" ++ ++/* Macro for finding empty tailqs */ ++#define TAILQ_IS_EMPTY(head) (head.tqh_first == NULL) ++ ++/* Flags to pass certain properties around */ ++#define NFS4_ACL_NOFLAGS 0x00 ++#define NFS4_ACL_ISFILE 0x00 ++#define NFS4_ACL_ISDIR 0x01 ++#define NFS4_ACL_OWNER 0x02 ++#define NFS4_ACL_REQUEST_DEFAULT 0x04 ++#define NFS4_ACL_RAW 0x01 ++ ++#define NFS4_XDR_MOD 4 ++ ++typedef u_int32_t u32; ++ ++enum { ACL_NFS4_NOT_USED = 0, ++ ACL_NFS4_USED ++}; ++ ++struct ace_container { ++ struct nfs4_ace *ace; ++ TAILQ_ENTRY(ace_container) l_ace; ++}; ++ ++TAILQ_HEAD(ace_container_list_head, ace_container); ++ ++/**** Public functions ****/ ++ ++/** Manipulation functions **/ ++extern int acl_nfs4_add_ace(struct nfs4_acl *, u32, u32, u32, int, char*); ++extern int acl_nfs4_add_pair(struct nfs4_acl *, int, u32, int, char*); ++extern void acl_nfs4_free(struct nfs4_acl *); ++extern struct nfs4_acl *acl_nfs4_new(u32); ++extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*); ++extern struct nfs4_acl *acl_nfs4_copy_acl(struct nfs4_acl *); ++extern struct nfs4_acl *acl_nfs4_xattr_load(char *, int, u32); ++extern int acl_nfs4_xattr_pack(struct nfs4_acl *, char**); ++extern int acl_nfs4_xattr_size(struct nfs4_acl *); ++extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace); ++ ++/** Conversion functions **/ ++ ++/* nfs4 -> posix */ ++extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t); ++ ++/* posix -> nfs4 */ ++extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, ++ int iflags); ++extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*); ++ ++ ++/** Access Functions **/ ++extern inline int acl_nfs4_get_whotype(char*); ++extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**); ++ ++/**** Private(?) functions ****/ ++acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32); ++ ++/* These will change */ ++char * nfs4_get_who_from_uid(uid_t); ++char * nfs4_get_who_from_gid(gid_t); ++/* End change */ diff --git a/pkgs/core/acl/patches/acl-2.2.47-params.patch b/pkgs/core/acl/patches/acl-2.2.47-params.patch new file mode 100644 index 0000000..13ead33 --- /dev/null +++ b/pkgs/core/acl/patches/acl-2.2.47-params.patch @@ -0,0 +1,154 @@ +--- acl-2.2.47_old/getfacl/getfacl.c 2008-02-07 04:39:57.000000000 +0100 ++++ acl-2.2.47/getfacl/getfacl.c 2008-07-31 12:23:10.000000000 +0200 +@@ -43,7 +43,7 @@ + #define POSIXLY_CORRECT_STR "POSIXLY_CORRECT" + + #if !POSIXLY_CORRECT +-# define CMD_LINE_OPTIONS "dRLP" ++# define CMD_LINE_OPTIONS "aceEsRLPtpndvh" + #endif + #define POSIXLY_CMD_LINE_OPTIONS "d" + +@@ -555,23 +555,23 @@ void help(void) + #if !POSIXLY_CORRECT + } else { + printf(_( +-" --access display the file access control list only\n" ++" -a, --access display the file access control list only\n" + " -d, --default display the default access control list only\n" +-" --omit-header do not display the comment header\n" +-" --all-effective print all effective rights\n" +-" --no-effective print no effective rights\n" +-" --skip-base skip files that only have the base entries\n" ++" -c, --omit-header do not display the comment header\n" ++" -e, --all-effective print all effective rights\n" ++" -E, --no-effective print no effective rights\n" ++" -s, --skip-base skip files that only have the base entries\n" + " -R, --recursive recurse into subdirectories\n" + " -L, --logical logical walk, follow symbolic links\n" + " -P, --physical physical walk, do not follow symbolic links\n" +-" --tabular use tabular output format\n" +-" --numeric print numeric user/group identifiers\n" +-" --absolute-names don't strip leading '/' in pathnames\n")); ++" -t, --tabular use tabular output format\n" ++" -n, --numeric print numeric user/group identifiers\n" ++" -p, --absolute-names don't strip leading '/' in pathnames\n")); + } + #endif + printf(_( +-" --version print version and exit\n" +-" --help this help text\n")); ++" -v, --version print version and exit\n" ++" -h, --help this help text\n")); + } + + int main(int argc, char *argv[]) +--- acl-2.2.47_old/man/man1/getfacl.1 2008-02-07 04:39:57.000000000 +0100 ++++ acl-2.2.47/man/man1/getfacl.1 2008-07-31 11:23:45.000000000 +0200 +@@ -12,10 +12,10 @@ getfacl - get file access control lists + .SH SYNOPSIS + + .B getfacl +-[-dRLPvh] file ... ++[-aceEsRLPrpndvh] file ... + + .B getfacl +-[-dRLPvh] - ++[-aceEsRLPrpndvh] - + + .SH DESCRIPTION + For each file, getfacl displays the file name, owner, the group, +@@ -78,22 +78,22 @@ accessing the file mode. + + .SS OPTIONS + .TP 4 +-.I --access ++.I -a, --access + Display the file access control list. + .TP + .I -d, --default + Display the default access control list. + .TP +-.I --omit-header ++.I -c, --omit-header + Do not display the comment header (the first three lines of each file's output). + .TP +-.I --all-effective ++.I -e, --all-effective + Print all effective rights comments, even if identical to the rights defined by the ACL entry. + .TP +-.I --no-effective ++.I -E, --no-effective + Do not print effective rights comments. + .TP +-.I --skip-base ++.I -s, --skip-base + Skip files that only have the base ACL entries (owner, group, others). + .TP + .I -R, --recursive +@@ -109,17 +109,20 @@ Physical walk, do not follow symbolic li + link arguments. + Only effective in combination with -R. + .TP +-.I --tabular ++.I -t, --tabular + Use an alternative tabular output format. The ACL and the default ACL are displayed side by side. Permissions that are ineffective due to the ACL mask entry are displayed capitalized. The entry tag names for the ACL_USER_OBJ and ACL_GROUP_OBJ entries are also displayed in capital letters, which helps in spotting those entries. + .TP +-.I --absolute-names ++.I -p, --absolute-names + Do not strip leading slash characters (`/'). The default behavior is to + strip leading slash characters. + .TP +-.I --version ++.I -n, --numeric ++List numeric user and group IDs ++.TP ++.I -v, --version + Print the version of getfacl and exit. + .TP +-.I --help ++.I -h, --help + Print help explaining the command line options. + .TP + .I -- +--- acl-2.2.47_old/man/man1/setfacl.1 2008-02-07 04:39:57.000000000 +0100 ++++ acl-2.2.47/man/man1/setfacl.1 2008-07-31 13:53:29.000000000 +0200 +@@ -115,10 +115,10 @@ This also skips symbolic link arguments. + Only effective in combination with -R. + This option cannot be mixed with `--restore'. + .TP 4 +-.I --version ++.I -v, --version + Print the version of setfacl and exit. + .TP 4 +-.I --help ++.I -h, --help + Print help explaining the command line options. + .TP 4 + .I -- +--- acl-2.2.47_old/setfacl/setfacl.c 2008-07-31 11:23:18.000000000 +0200 ++++ acl-2.2.47/setfacl/setfacl.c 2008-07-31 12:23:13.000000000 +0200 +@@ -42,10 +42,10 @@ extern int do_set(const char *path_p, co + + /* '-' stands for `process non-option arguments in loop' */ + #if !POSIXLY_CORRECT +-# define CMD_LINE_OPTIONS "-:bkndm:M:x:X:RLP" ++# define CMD_LINE_OPTIONS "-:bkndvhm:M:x:X:RLP" + # define CMD_LINE_SPEC "[-bkndRLP] { -m|-M|-x|-X ... } file ..." + #endif +-#define POSIXLY_CMD_LINE_OPTIONS "-:bkndm:M:x:X:" ++#define POSIXLY_CMD_LINE_OPTIONS "-:bkndvhm:M:x:X:" + #define POSIXLY_CMD_LINE_SPEC "[-bknd] {-m|-M|-x|-X ... } file ..." + + struct option long_options[] = { +@@ -265,8 +265,8 @@ void help(void) + } + #endif + printf(_( +-" --version print version and exit\n" +-" --help this help text\n")); ++" -v, --version print version and exit\n" ++" -h, --help this help text\n")); + } + + \ No newline at end of file diff --git a/pkgs/core/acl/patches/acl-2.2.47-path_max.patch b/pkgs/core/acl/patches/acl-2.2.47-path_max.patch new file mode 100644 index 0000000..42f8524 --- /dev/null +++ b/pkgs/core/acl/patches/acl-2.2.47-path_max.patch @@ -0,0 +1,24 @@ +--- acl-2.2.39/setfacl/parse.c.path_max 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/setfacl/parse.c 2006-07-05 15:27:21.000000000 -0400 +@@ -24,6 +24,7 @@ + #include <stdlib.h> + #include <string.h> + #include <errno.h> ++#include <limits.h> + + #include <sys/types.h> + #include <sys/stat.h> +@@ -412,7 +413,12 @@ + gid_t *gid_p) + { + int c; +- char linebuf[1024]; ++ /* ++ Max PATH_MAX bytes even for UTF-8 path names and additional 9 ++ bytes for "# file: ".Not a good solution but for now it is the ++ best I can do without too much impact on the code. [tw] ++ */ ++ char linebuf[(4*PATH_MAX)+9]; + char *cp; + char *p; + int comments_read = 0; diff --git a/pkgs/core/acl/patches/acl-2.2.47-segfault.patch b/pkgs/core/acl/patches/acl-2.2.47-segfault.patch new file mode 100644 index 0000000..a90c37d --- /dev/null +++ b/pkgs/core/acl/patches/acl-2.2.47-segfault.patch @@ -0,0 +1,11 @@ +--- acl-2.2.45/setfacl/setfacl.c.segfault 2008-01-28 13:56:36.000000000 +0100 ++++ acl-2.2.45/setfacl/setfacl.c 2008-01-28 13:58:08.000000000 +0100 +@@ -679,6 +679,8 @@ int main(int argc, char *argv[]) + } + } + while (optind < argc) { ++ if(!seq) ++ goto synopsis; + if (seq_empty(seq)) + goto synopsis; + saw_files = 1; diff --git a/pkgs/core/acl/patches/acl-2.2.47-walk.patch.broken b/pkgs/core/acl/patches/acl-2.2.47-walk.patch.broken new file mode 100644 index 0000000..01194f6 --- /dev/null +++ b/pkgs/core/acl/patches/acl-2.2.47-walk.patch.broken @@ -0,0 +1,235 @@ +--- acl-2.2.39/getfacl/getfacl.c.walk 2006-06-20 08:51:25.000000000 +0200 ++++ acl-2.2.39/getfacl/getfacl.c 2007-03-21 10:52:07.000000000 +0100 +@@ -34,7 +34,6 @@ + #include <dirent.h> + #include <libgen.h> + #include <getopt.h> +-#include <ftw.h> + #include <locale.h> + #include "config.h" + #include "user_group.h" +@@ -70,9 +69,9 @@ + const char *progname; + const char *cmd_line_options; + +-int opt_recursive; /* recurse into sub-directories? */ +-int opt_walk_logical; /* always follow symbolic links */ +-int opt_walk_physical; /* never follow symbolic links */ ++int opt_recursive = 0; /* recurse into sub-directories? */ ++int opt_walk_logical = 0; /* always follow symbolic links */ ++int opt_walk_physical = 0; /* never follow symbolic links */ + int opt_print_acl = 0; + int opt_print_default_acl = 0; + int opt_strip_leading_slash = 1; +@@ -562,71 +561,140 @@ + + + static int __errors; +-int __do_print(const char *file, const struct stat *stat, +- int flag, struct FTW *ftw) ++ ++int walk_tree(const char *file) + { +- int saved_errno = errno; ++ static int level = 0; ++ static int link_count = 0; ++ DIR *dir; ++ struct dirent *entry; ++ struct stat buf; ++ char path[FILENAME_MAX]; ++ char path2[FILENAME_MAX]; ++ char path3[FILENAME_MAX]; ++ char *dir_name; ++ size_t len; ++ ssize_t slen; ++ int res; + + /* Process the target of a symbolic link, and traverse the link, + only if doing a logical walk, or if the symbolic link was + specified on the command line. Always skip symbolic links if + doing a physical walk. */ + +- if (S_ISLNK(stat->st_mode) && +- (opt_walk_physical || (ftw->level > 0 && !opt_walk_logical))) ++ len = strlen(file); ++ /* check for FILENAME_MAX */ ++ if (len >= FILENAME_MAX) { ++ fprintf(stderr, "%s: %s: %s\n", progname, xquote(file), ++ strerror(ENAMETOOLONG)); ++ __errors++; + return 0; ++ } ++ /* string ends with '/', remove it and restart */ ++ if (len > 1 && file[len-1] == '/') { ++ strncpy(path, file, len); ++ path[len-1] = '\0'; /* overwrite slash */ ++ return walk_tree(path); ++ } + +- if (do_print(file, stat)) +- __errors++; ++ if (level > 0 && !opt_recursive) ++ return 0; + +- if (flag == FTW_DNR && opt_recursive) { +- /* Item is a directory which can't be read. */ +- fprintf(stderr, "%s: %s: %s\n", +- progname, file, strerror(saved_errno)); ++ if (lstat(file, &buf) != 0) { ++ fprintf(stderr, "%s: %s: %s\n", progname, xquote(file), ++ strerror(errno)); ++ __errors++; + return 0; + } + +- /* We also get here in non-recursive mode. In that case, +- return something != 0 to abort nftw. */ ++ if (S_ISLNK(buf.st_mode)) { ++ /* physical means: no links at all */ ++ if (opt_walk_physical) ++ return 1; ++ ++ /* logical: show information or walk if points to directory ++ * also for symbolic link arguments on level 0 */ ++ if (opt_walk_logical || level == 0) { ++ /* copy and append terminating '\0' */ ++ strncpy(path2, file, len+1); ++ ++ /* get directory name */ ++ dir_name = dirname(path2); ++ ++ /* get link target */ ++ slen = readlink(file, path, FILENAME_MAX-1); ++ if (slen < 0) { ++ fprintf(stderr, "%s: %s: %s\n", progname, ++ xquote(file), strerror(errno)); ++ __errors++; ++ return 0; ++ } ++ path[slen] = '\0'; + +- if (!opt_recursive) +- return 1; ++ if (slen == 0 || path[0] == '/') { ++ /* absolute: ++ * copy and append terminating '\0' */ ++ strncpy(path3, path, slen+1); ++ } else ++ /* relative */ ++ snprintf(path3, FILENAME_MAX, "%s/%s", ++ dir_name, path); ++ ++ if (lstat(path3, &buf) != 0) { ++ fprintf(stderr, "%s: %s: %s\n", progname, ++ xquote(path), strerror(errno)); ++ __errors++; ++ return 0; ++ } + +- return 0; +-} ++ if ((S_ISDIR(buf.st_mode) && opt_recursive && ++ link_count < 1) || S_ISLNK(buf.st_mode)) { ++ /* walk directory or follow symlink on level ++ * 0 */ ++ link_count++; ++ res = walk_tree(path3); ++ link_count--; ++ if (res != 1) ++ return 0; ++ } else ++ if (do_print(path3, &buf)) ++ __errors++; + +-char *resolve_symlinks(const char *file) +-{ +- static char buffer[4096]; +- char *path = NULL; +- ssize_t len; +- +- len = readlink(file, buffer, sizeof(buffer)-1); +- if (len < 0) { +- if (errno == EINVAL) /* not a symlink, use given path */ +- path = (char *)file; +- } else { +- buffer[len+1] = '\0'; +- path = buffer; ++ return 1; ++ } + } +- return path; +-} +- +-int walk_tree(const char *file) +-{ +- const char *p; + +- __errors = 0; +- if ((p = resolve_symlinks(file)) == NULL) { +- fprintf(stderr, "%s: %s: %s\n", progname, +- xquote(file), strerror(errno)); +- __errors++; +- } else if (nftw(p, __do_print, 0, opt_walk_logical? 0 : FTW_PHYS) < 0) { +- fprintf(stderr, "%s: %s: %s\n", progname, xquote(file), +- strerror(errno)); ++ if (do_print(file, &buf)) + __errors++; ++ ++ /* it is a directory, walk */ ++ if (S_ISDIR(buf.st_mode)) { ++ dir = opendir(file); ++ if (!dir) { ++ fprintf(stderr, "%s: %s: %s\n", progname, ++ xquote(file), strerror(errno)); ++ __errors++; ++ return 0; ++ } ++ ++ level++; ++ while ((entry = readdir(dir)) != NULL) { ++ if (! strcmp(entry->d_name, ".") || ++ ! strcmp(entry->d_name, "..")) ++ continue; ++ ++ snprintf(path, FILENAME_MAX, "%s/%s", file, ++ entry->d_name); ++ ++ /* ignore result, walk every entry */ ++ res = walk_tree(path); ++ } ++ level--; ++ ++ closedir(dir); + } +- return __errors; ++ ++ return 1; + } + + int main(int argc, char *argv[]) +@@ -762,15 +830,22 @@ + if (*line == '\0') + continue; + +- had_errors += walk_tree(line); ++ /* ignore result of walk_tree, use __errors */ ++ __errors = 0; ++ walk_tree(line); ++ had_errors += __errors; + } + if (!feof(stdin)) { + fprintf(stderr, _("%s: Standard input: %s\n"), + progname, strerror(errno)); + had_errors++; + } +- } else +- had_errors += walk_tree(argv[optind]); ++ } else { ++ /* ignore result of walk_tree, use __errors */ ++ __errors = 0; ++ walk_tree(argv[optind]); ++ had_errors += __errors; ++ } + optind++; + } while (optind < argc); + diff --git a/pkgs/core/aiccu/aiccu.nm b/pkgs/core/aiccu/aiccu.nm new file mode 100644 index 0000000..c105fc1 --- /dev/null +++ b/pkgs/core/aiccu/aiccu.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = aiccu +PKG_VER = 20070115 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Daemons +PKG_URL = http://www.sixxs.net/tools/aiccu/ +PKG_LICENSE = BSD +PKG_SUMMARY = Automatic IPv6 Connectivity Client Utility for SixXS tunnels. + +PKG_DEPS += gnutls + +define PKG_DESCRIPTION + This client automatically gives one IPv6 connectivity without having \ + to manually configure interfaces etc. One does need a SixXS account \ + and at least a tunnel. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_PREPARE_CMDS + mv /usr/src/$(PKG_NAME) /usr/src/$(PKG_NAME)-$(PKG_VER) +endef + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) RPM_OPT_FLAGS="$(CFLAGS)" +endef + +define STAGE_INSTALL_CMDS + rm -rvf $(BUILDROOT)/{etc,usr/share} +endef diff --git a/pkgs/core/attr/attr.nm b/pkgs/core/attr/attr.nm new file mode 100644 index 0000000..3bace1f --- /dev/null +++ b/pkgs/core/attr/attr.nm @@ -0,0 +1,71 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = attr +PKG_VER = 2.4.43 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://oss.sgi.com/projects/xfs/ +PKG_LICENSE = GPLv2+ LGPLv2+ +PKG_SUMMARY = Tools for extended attribute support. + +PKG_PACKAGES += $(PKG_NAME_REAL)-devel +PKG_BUILD_DEPS+= gettext gzip libtool make sed + +define PKG_DESCRIPTION + A set of tools for manipulating extended attributes on filesystem \ + objects. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --bindir=/bin \ + --enable-shared + + cd $(DIR_APP) && make #$(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/{,usr/}lib + install -v -m0755 $(DIR_APP)/libattr/.libs/libattr.so.1.1.0 $(BUILDROOT)/lib + ln -vsf libattr.so.1.1.0 $(BUILDROOT)/lib/libattr.so.1 + ln -vsf ../../lib/libattr.so.1 $(BUILDROOT)/usr/lib/libattr.so + install -v -d $(BUILDROOT)/usr/include/attr + cp -vf $(DIR_APP)/include/{attributes.h,error_context.h,libattr.h,xattr.h} \ + $(BUILDROOT)/usr/include/attr/ +endef diff --git a/pkgs/core/autoconf/autoconf.nm b/pkgs/core/autoconf/autoconf.nm new file mode 100644 index 0000000..b87c6cb --- /dev/null +++ b/pkgs/core/autoconf/autoconf.nm @@ -0,0 +1,46 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = autoconf +PKG_VER = 2.65 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/autoconf/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A GNU tool for automatically configuring source code. + +PKG_DEPS += m4 perl + +define PKG_DESCRIPTION + GNU's Autoconf is a tool for configuring source code and Makefiles. \ + Using Autoconf, programmers can create portable and configurable \ + packages, since the person building the package is allowed to \ + specify various configuration options. +endef + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/automake/automake.nm b/pkgs/core/automake/automake.nm new file mode 100644 index 0000000..07bc644 --- /dev/null +++ b/pkgs/core/automake/automake.nm @@ -0,0 +1,44 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = automake +PKG_VER = 1.11.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/automake/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A GNU tool for automatically configuring source code. + +PKG_DEPS += autoconf perl + +define PKG_DESCRIPTION + Automake is a tool for automatically generating Makefile.in \ + files compliant with the GNU Coding Standards. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 diff --git a/pkgs/core/avahi/avahi.nm b/pkgs/core/avahi/avahi.nm new file mode 100644 index 0000000..3e4313b --- /dev/null +++ b/pkgs/core/avahi/avahi.nm @@ -0,0 +1,63 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = avahi +PKG_VER = 0.6.25 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Zeroconf +PKG_URL = http://avahi.org/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = Local network service discovery + +define PKG_DESCRIPTION + Avahi is a system which facilitates service discovery on \ + a local network -- this means that you can plug your laptop or \ + computer into a network and instantly be able to view other people who \ + you can chat with, find printers to print to or find files being \ + shared. This kind of technology is already found in MacOS X (branded \ + 'Rendezvous', 'Bonjour' and sometimes 'ZeroConf') and is very \ + convenient +endef + +PKG_BUILD_DEPS+= gettext intltool pkg-config +PKG_DEPS += dbus dbus-glib libdaemon python python-dbus perl-xml-parser + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --bindir=/bin \ + --mandir=/usr/share/man \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --with-distro=none \ + --disable-gdbm \ + --disable-qt3 \ + --disable-qt4 \ + --disable-gtk \ + --disable-pygtk \ + --disable-mono diff --git a/pkgs/core/bash/bash.nm b/pkgs/core/bash/bash.nm new file mode 100644 index 0000000..8bdb9b8 --- /dev/null +++ b/pkgs/core/bash/bash.nm @@ -0,0 +1,93 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = bash +PKG_VER = 4.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Tools +PKG_URL = http://www.gnu.org/software/bash/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Bash is short for born again shell. + +define PKG_DESCRIPTION + Bash is the shell, or command language interpreter, that will appear in \ + the GNU operating system. Bash is an sh-compatible shell that incorporates \ + useful features from the Korn shell (ksh) and C shell (csh). It is intended \ + to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard. +endef + +PKG_BUILD_DEPS+= autoconf automake bison +PKG_DEPS += readline + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_PREPARE_CMDS + # Bash uses the RTLD_LAZY option when loading libraries. We want to use + # RTLD_NOW (it is defined from <dlfcn.h>: + cd $(DIR_APP) && sed -e "s/filename, RTLD_LAZY/filename, RTLD_NOW/" \ + -i builtins/enable.def + + cd $(DIR_APP) && sed -i "s|htmldir = @htmldir@|htmldir = /usr/share/doc/$(THISAPP)|" \ + Makefile.in +endef + +define STAGE_BUILD + cd $(DIR_APP) && \ + ac_cv_func_working_mktime=yes \ + ./configure \ + --prefix=/usr \ + --bindir=/bin \ + --without-bash-malloc \ + --with-installed-readline + + # remove rpath from libtool + @if [ -e "libtool" ]; then \ + sed -i libtool \ + -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ + -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g'; \ + fi + + cd $(DIR_APP) && make #$(PARALLELISMFLAGS) +endef + +# Test hangs forever +#define STAGE_TEST +# cd $(DIR_APP) && make tests +#endef + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/{bin,etc/profile.d} + + # Bash startup files + cp -avf $(DIR_SOURCE)/{bashrc,profile,shells} $(BUILDROOT)/etc + + # /etc/profile.d + cp -vf $(DIR_SOURCE)/profile.d/* $(BUILDROOT)/etc/profile.d + + ln -svf bash $(BUILDROOT)/bin/sh +endef diff --git a/pkgs/core/bash/bashrc b/pkgs/core/bash/bashrc new file mode 100644 index 0000000..88c3aa2 --- /dev/null +++ b/pkgs/core/bash/bashrc @@ -0,0 +1,22 @@ +# Begin /etc/bashrc + +# System wide aliases and functions. + +# System wide environment variables and startup programs should go into +# /etc/profile. Personal environment variables and startup programs +# should go into ~/.bash_profile. Personal aliases and functions should +# go into ~/.bashrc + +# Provides a colored /bin/ls command. Used in conjunction with code in +# /etc/profile. + +alias ls='ls --color=auto' + +# Provides prompt for non-login shells, specifically shells started +# in the X environment. [Review the LFS archive thread titled +# PS1 Environment Variable for a great case study behind this script +# addendum.] + +export PS1="\033[0m[\033[1;33m\u\033[1;37m@\033[1;32m]\h \033[1;31m\w\033[0m]\$ " + +# End /etc/bashrc diff --git a/pkgs/core/bash/patches/bash-4.0-paths-1.patch b/pkgs/core/bash/patches/bash-4.0-paths-1.patch new file mode 100644 index 0000000..735a381 --- /dev/null +++ b/pkgs/core/bash/patches/bash-4.0-paths-1.patch @@ -0,0 +1,30 @@ +--- bash-3.0/config.h.in.paths 2004-07-21 21:08:31.000000000 +0100 ++++ bash-3.0/config.h.in 2004-07-28 09:16:27.257884999 +0100 +@@ -197,7 +197,7 @@ + + /* System paths */ + +-#define DEFAULT_MAIL_DIRECTORY "/usr/spool/mail" ++#define DEFAULT_MAIL_DIRECTORY "/var/spool/mail" + + /* Characteristics of the system's header files and libraries that affect + the compilation environment. */ +--- bash-3.0/config-top.h.paths 2003-08-05 15:36:12.000000000 +0100 ++++ bash-3.0/config-top.h 2004-07-28 09:36:27.117205637 +0100 +@@ -52,14 +52,14 @@ + /* The default value of the PATH variable. */ + #ifndef DEFAULT_PATH_VALUE + #define DEFAULT_PATH_VALUE \ +- "/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:." ++ "/usr/local/bin:/bin:/usr/bin" + #endif + + /* The value for PATH when invoking `command -p'. This is only used when + the Posix.2 confstr () function, or CS_PATH define are not present. */ + #ifndef STANDARD_UTILS_PATH + #define STANDARD_UTILS_PATH \ +- "/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc" ++ "/bin:/usr/bin:/usr/sbin:/sbin" + #endif + + /* Default primary and secondary prompt strings. */ diff --git a/pkgs/core/bash/patches/bash-4.0-profile-1.patch b/pkgs/core/bash/patches/bash-4.0-profile-1.patch new file mode 100644 index 0000000..ba3344b --- /dev/null +++ b/pkgs/core/bash/patches/bash-4.0-profile-1.patch @@ -0,0 +1,12 @@ +diff -up bash-3.2/config-top.h.profile bash-3.2/config-top.h +--- bash-3.2/config-top.h.profile 2008-07-17 13:35:39.000000000 +0200 ++++ bash-3.2/config-top.h 2008-07-17 13:42:18.000000000 +0200 +@@ -26,6 +26,8 @@ + what POSIX.2 specifies. */ + #define CONTINUE_AFTER_KILL_ERROR + ++#define NON_INTERACTIVE_LOGIN_SHELLS ++ + /* Define BREAK_COMPLAINS if you want the non-standard, but useful + error messages about `break' and `continue' out of context. */ + #define BREAK_COMPLAINS diff --git a/pkgs/core/bash/patches/bash-4.0-rng.patch b/pkgs/core/bash/patches/bash-4.0-rng.patch new file mode 100644 index 0000000..5534466 --- /dev/null +++ b/pkgs/core/bash/patches/bash-4.0-rng.patch @@ -0,0 +1,149 @@ +This patch is from: + http://cvs.fedoraproject.org/viewvc/devel/bash/bash-3.2-rng.patch + http://cvs.fedoraproject.org/viewvc/devel/bash/bash-3.2-344411.patch + +The second patch (bash-3.2-344411.patch) was integrated in bash-4.0, to provide +$RANDOM in sub shells. + +Use /dev/urandom for $RANDOM. This patch does not break the Korn shell +behaviour, where we can initialize $RANDOM ourselves and get the same results +each time. /dev/urandom is only opened when $RANDOM is called. + +I pulled out all the autoconf stuff. This patch depends on random(3) and +srandom(3) in libc, and /dev/urandom. getpid(3) and gettimeofday(3) are used +if /dev/urandom isn't available at run time (like in a chroot). + +Test case: +( echo $RANDOM; ( echo $RANDOM ); ( echo $RANDOM ) ) + +robert + +diff -Naur bash-4.0.orig/variables.c bash-4.0/variables.c +--- bash-4.0.orig/variables.c 2009-01-04 19:32:46.000000000 +0000 ++++ bash-4.0/variables.c 2009-02-22 20:15:50.000000000 +0000 +@@ -44,6 +44,12 @@ + #include "bashansi.h" + #include "bashintl.h" + ++#include <errno.h> ++#include "filecntl.h" ++#ifndef RANDOMDEV ++#define RANDOMDEV "/dev/urandom" ++#endif ++ + #include "shell.h" + #include "flags.h" + #include "execute_cmd.h" +@@ -188,7 +194,7 @@ + static SHELL_VAR *init_seconds_var __P((void)); + + static int brand __P((void)); +-static void sbrand __P((unsigned long)); /* set bash random number generator. */ ++static void sbrand __P((unsigned int)); /* set bash random number generator. */ + static void seedrand __P((void)); /* seed generator randomly */ + static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *)); + static SHELL_VAR *get_random __P((SHELL_VAR *)); +@@ -518,9 +524,6 @@ + } + #endif /* HISTORY */ + +- /* Seed the random number generator. */ +- seedrand (); +- + /* Handle some "special" variables that we may have inherited from a + parent shell. */ + if (interactive_shell) +@@ -1204,9 +1207,8 @@ + } + + /* The random number seed. You can change this by setting RANDOM. */ +-static unsigned long rseed = 1; + static int last_random_value; +-static int seeded_subshell = 0; ++static int seeded_subshell = -1; + + /* A linear congruential random number generator based on the example + one in the ANSI C standard. This one isn't very good, but a more +@@ -1216,44 +1218,36 @@ + static int + brand () + { +-#if 0 +- rseed = rseed * 1103515245 + 12345; +- return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */ +-#else +- /* From "Random number generators: good ones are hard to find", +- Park and Miller, Communications of the ACM, vol. 31, no. 10, +- October 1988, p. 1195. filtered through FreeBSD */ +- long h, l; +- +- if (rseed == 0) +- seedrand (); +- h = rseed / 127773; +- l = rseed % 127773; +- rseed = 16807 * l - 2836 * h; +-#if 0 +- if (rseed < 0) +- rseed += 0x7fffffff; +-#endif ++ unsigned int rseed; ++ rseed = random(); + return ((unsigned int)(rseed & 32767)); /* was % 32768 */ +-#endif + } + + /* Set the random number generator seed to SEED. */ + static void + sbrand (seed) +- unsigned long seed; ++ unsigned int seed; + { +- rseed = seed; ++ srandom((unsigned int)seed); + last_random_value = 0; + } + + static void + seedrand () + { +- struct timeval tv; +- +- gettimeofday (&tv, NULL); +- sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ()); ++ unsigned int seed; ++ int fd; ++ int rv; ++ if ((rv = fd = open (RANDOMDEV, O_RDONLY)) != -1) { ++ while ((rv = read(fd, &seed, sizeof(seed))) != sizeof(seed) && errno == EINTR); ++ close (fd); ++ } ++ if (rv != sizeof(seed)) { ++ struct timeval tv; ++ gettimeofday (&tv, NULL); ++ seed = (unsigned int)tv.tv_sec + (unsigned int)tv.tv_usec + getpid(); ++ } ++ sbrand (seed); + } + + static SHELL_VAR * +@@ -1263,9 +1257,8 @@ + arrayind_t unused; + char *key; + { +- sbrand (strtoul (value, (char **)NULL, 10)); +- if (subshell_environment) +- seeded_subshell = getpid (); ++ sbrand ((unsigned int)strtoul (value, (char **)NULL, 10)); ++ seeded_subshell = getpid (); + return (self); + } + +@@ -1276,7 +1269,7 @@ + + /* Reset for command and process substitution. */ + pid = getpid (); +- if (subshell_environment && seeded_subshell != pid) ++ if (seeded_subshell != pid) + { + seedrand (); + seeded_subshell = pid; diff --git a/pkgs/core/bash/patches/bash-4.1-upstream-1.patch b/pkgs/core/bash/patches/bash-4.1-upstream-1.patch new file mode 100644 index 0000000..6cb4314 --- /dev/null +++ b/pkgs/core/bash/patches/bash-4.1-upstream-1.patch @@ -0,0 +1,46 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 4.1 +Patch-ID: bash41-001 + +Bug-Reported-by: Yann Rouillard <yann@pleiades.fr.eu.org> +Bug-Reference-ID: <4B44A410.4070107@pleiades.fr.eu.org> +Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2010-01/msg00018.html + +Bug-Description: + +A prototype for vsnprintf was incorrect, and caused compilation failures +on systems that did not have a suitable vsnprintf, but had a declaration in +one of the system header files. + +*** bash-4.1-patched/builtins/printf.def 2009-11-20 15:31:23.000000000 -0500 +--- builtins/printf.def 2010-01-07 08:50:06.000000000 -0500 +*************** +*** 173,177 **** + + #if !HAVE_VSNPRINTF +! extern int vsnprintf __P((char *, size_t, const char *, ...)) __attribute__((__format__ (printf, 3, 4))); + #endif + +--- 173,177 ---- + + #if !HAVE_VSNPRINTF +! extern int vsnprintf __P((char *, size_t, const char *, va_list)) __attribute__((__format__ (printf, 3, 0))); + #endif + +*** bash-4.1-patched/patchlevel.h 2009-10-01 16:39:22.000000000 -0400 +--- patchlevel.h 2010-01-14 09:38:08.000000000 -0500 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 0 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 1 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/pkgs/core/bash/patches/bash-4.1-upstream-2.patch b/pkgs/core/bash/patches/bash-4.1-upstream-2.patch new file mode 100644 index 0000000..d74f806 --- /dev/null +++ b/pkgs/core/bash/patches/bash-4.1-upstream-2.patch @@ -0,0 +1,63 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 4.1 +Patch-ID: bash41-002 + +Bug-Reported-by: guillaume.outters@free.fr +Bug-Reference-ID: <20100105230441.70D171AA7F52@asterix.local> +Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2010-01/msg00017.html + +Bug-Description: + +Bash-4.1/Readline-6.1 introduced a hook function that allows applications +to rewrite or modify filenames read from the file system before comparing +them with a word to be completed. The converted filename, if it matches, +needs to be inserted into the line buffer, replacing the original contents. + +This fixes a completion bug on Mac OS X involving filenames containing +UTF-8 characters. + +*** bash-4.1-patched/lib/readline/complete.c 2009-11-29 18:39:30.000000000 -0500 +--- lib/readline/complete.c 2010-01-06 08:30:23.000000000 -0500 +*************** +*** 2139,2143 **** + if (filename_len == 0) + { +! if (_rl_match_hidden_files == 0 && HIDDEN_FILE (entry->d_name)) + continue; + +--- 2139,2143 ---- + if (filename_len == 0) + { +! if (_rl_match_hidden_files == 0 && HIDDEN_FILE (convfn)) + continue; + +*************** +*** 2220,2224 **** + } + +! strcpy (temp + dirlen, entry->d_name); + } + else +--- 2220,2224 ---- + } + +! strcpy (temp + dirlen, convfn); + } + else +*** bash-4.1-patched/patchlevel.h 2009-10-01 16:39:22.000000000 -0400 +--- patchlevel.h 2010-01-14 09:38:08.000000000 -0500 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 1 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 2 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/pkgs/core/bash/profile b/pkgs/core/bash/profile new file mode 100644 index 0000000..70ff901 --- /dev/null +++ b/pkgs/core/bash/profile @@ -0,0 +1,62 @@ +# Begin /etc/profile + +# System wide environment variables and startup programs. + +# System wide aliases and functions should go in /etc/bashrc. Personal +# environment variables and startup programs should go into +# ~/.bash_profile. Personal aliases and functions should go into +# ~/.bashrc. + +# Functions to help us manage paths. Second argument is the name of the +# path variable to be modified (default: PATH) +pathremove () { + local IFS=':' + local NEWPATH + local DIR + local PATHVARIABLE=${2:-PATH} + for DIR in ${!PATHVARIABLE} ; do + if [ "$DIR" != "$1" ] ; then + NEWPATH=${NEWPATH:+$NEWPATH:}$DIR + fi + done + export $PATHVARIABLE="$NEWPATH" +} + +pathprepend () { + pathremove $1 $2 + local PATHVARIABLE=${2:-PATH} + export $PATHVARIABLE="$1${!PATHVARIABLE:+:${!PATHVARIABLE}}" +} + +pathappend () { + pathremove $1 $2 + local PATHVARIABLE=${2:-PATH} + export $PATHVARIABLE="${!PATHVARIABLE:+${!PATHVARIABLE}:}$1" +} + + +# Set the initial path +export PATH=/bin:/usr/bin + +if [ $EUID -eq 0 ] ; then + pathappend /sbin:/usr/sbin + unset HISTFILE +fi + +# Setup some environment variables. +export HISTSIZE=1000 +export HISTIGNORE="&:[bf]g:exit" + +export PS1="[\u@\h \w]\$ " +#export PS1='\u@\h:\w$ ' + +for script in /etc/profile.d/*.sh ; do + if [ -r $script ] ; then + . $script + fi +done + +# Now to clean up +unset pathremove pathprepend pathappend + +# End /etc/profile diff --git a/pkgs/core/bash/profile.d/extrapaths.sh b/pkgs/core/bash/profile.d/extrapaths.sh new file mode 100644 index 0000000..bb8f720 --- /dev/null +++ b/pkgs/core/bash/profile.d/extrapaths.sh @@ -0,0 +1,15 @@ +if [ -d /usr/local/bin ]; then + pathprepend /usr/local/bin +fi +if [ -d /usr/local/sbin -a $EUID -eq 0 ]; then + pathprepend /usr/local/sbin +fi +for directory in $(find /opt/*/bin -type d 2>/dev/null); do + pathappend $directory +done +if [ -d ~/bin ]; then + pathprepend ~/bin +fi +#if [ $EUID -gt 99 ]; then +# pathappend . +#fi diff --git a/pkgs/core/bash/profile.d/i18n.sh b/pkgs/core/bash/profile.d/i18n.sh new file mode 100644 index 0000000..2f66e89 --- /dev/null +++ b/pkgs/core/bash/profile.d/i18n.sh @@ -0,0 +1,10 @@ +# Set up i18n variables + +if [ -f "/etc/sysconfig/console" ]; then + . /etc/sysconfig/console +else + LANG=en_US.UTF-8 +fi + +unset KEYMAP FONT UNICODE KEYMAP_CORRECTIONS LEGACY_CHARSET +export LANG diff --git a/pkgs/core/bash/profile.d/umask.sh b/pkgs/core/bash/profile.d/umask.sh new file mode 100644 index 0000000..9a3f824 --- /dev/null +++ b/pkgs/core/bash/profile.d/umask.sh @@ -0,0 +1,6 @@ +# By default we want the umask to get set. +if [ "$(id -gn)" = "$(id -un)" -a $EUID -gt 99 ] ; then + umask 002 +else + umask 022 +fi diff --git a/pkgs/core/bash/shells b/pkgs/core/bash/shells new file mode 100644 index 0000000..1805018 --- /dev/null +++ b/pkgs/core/bash/shells @@ -0,0 +1,7 @@ +# Begin /etc/shells + +/bin/sh +/bin/bash +/sbin/nologin + +# End /etc/shells diff --git a/pkgs/core/bc/bc.nm b/pkgs/core/bc/bc.nm new file mode 100644 index 0000000..ed3cc13 --- /dev/null +++ b/pkgs/core/bc/bc.nm @@ -0,0 +1,66 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = bc +PKG_VER = 1.06 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Tools +PKG_URL = http://www.gnu.org/software/bc/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = bc is an arbitrary precision numeric processing language. + +PKG_BUILD_DEPS+= flex + +define PKG_DESCRIPTION + bc is a language that supports arbitrary precision numbers with \ + interactive execution of statements. There are some similarities in the \ + syntax to the C programming language. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -i '/PROTO.*readline/d' bc/scan.l + cd $(DIR_APP) && sed -i '/flex -I8/s/8//' configure + cd $(DIR_APP) && sed -i '/stdlib/a #include <string.h>' lib/number.c + cd $(DIR_APP) && sed -i 's/program.*save/static &/' bc/load.c +endef + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --disable-static \ + --mandir=/usr/share/man + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef diff --git a/pkgs/core/beep/beep.nm b/pkgs/core/beep/beep.nm new file mode 100644 index 0000000..1688b46 --- /dev/null +++ b/pkgs/core/beep/beep.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = beep +PKG_VER = 1.2.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/System +PKG_URL = http://www.johnath.com/beep/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Beep the PC speaker any number of ways. + +define PKG_DESCRIPTION + Beep allows the user to control the PC speaker with precision, \ + allowing different sounds to indicate different events. While it \ + can be run quite happily on the commandline, it's intended place \ + of residence is within shell/perl scripts, notifying the user when \ + something interesting occurs. Of course, it has no notion of \ + what's interesting, but it's real good at that notifying part. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/usr/bin + -mkdir -pv $(BUILDROOT)/usr/share/man/man1 + cd $(DIR_APP) && install -m 0755 beep $(BUILDROOT)/usr/bin + cd $(DIR_APP) && cp beep.1.gz $(BUILDROOT)/usr/share/man/man1 +endef diff --git a/pkgs/core/bind/bind.nm b/pkgs/core/bind/bind.nm new file mode 100644 index 0000000..1c3109e --- /dev/null +++ b/pkgs/core/bind/bind.nm @@ -0,0 +1,62 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = bind +PKG_VER = 9.4.1-P1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://www.isc.org/products/BIND/ +PKG_LICENSE = Proprietary +PKG_SUMMARY = BIND provides tools for the DNS. + +PKG_DEPS += db openssl + +define PKG_DESCRIPTION + BIND (Berkeley Internet Name Domain or named) is the most commonly used \ + DNS server on the Internet, especially on Unix-like systems. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --mandir=/usr/share/man + + cd $(DIR_APP) && make -C lib/dns #$(PARALLELISMFLAGS) + cd $(DIR_APP) && make -C lib/isc #$(PARALLELISMFLAGS) + cd $(DIR_APP) && make -C lib/bind9 #$(PARALLELISMFLAGS) + cd $(DIR_APP) && make -C lib/isccfg #$(PARALLELISMFLAGS) + cd $(DIR_APP) && make -C lib/lwres #$(PARALLELISMFLAGS) + cd $(DIR_APP) && make -C bin/dig #$(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make -C bin/dig install DESTDIR=$(BUILDROOT) +endef diff --git a/pkgs/core/binutils/binutils.nm b/pkgs/core/binutils/binutils.nm new file mode 100644 index 0000000..a970694 --- /dev/null +++ b/pkgs/core/binutils/binutils.nm @@ -0,0 +1,83 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = binutils +PKG_VER = 2.20 +PKG_REL = 0 + +PKG_MAINTAINER = Michael Tremer <michael.tremer@ipfire.org> +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/binutils/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = The GNU Binutils are a collection of binary tools. + +define PKG_DESCRIPTION + The GNU Binary Utilities, or binutils, is a collection of programming \ + tools for the manipulation of object code in various object file formats. +endef + +PKG_BUILD_DEPS = glibc +PKG_DEPS += zlib + +PKG_TARBALL += $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + -mkdir -pv $(DIR_SRC)/binutils-build + + # Suppress the installation of an outdated standards.info file as a newer + # one is installed later on in the Autoconf instructions: + cd $(DIR_APP) && rm -fv etc/standards.info + cd $(DIR_APP) && sed -e '/^INFO/s/standards.info //' -i etc/Makefile.in +endef + +define STAGE_BUILD + cd $(DIR_SRC)/binutils-build && \ + ../$(THISAPP)/configure \ + --prefix=/usr \ + --mandir=/usr/share/man \ + --enable-shared \ + --disable-nls \ + --disable-werror \ + --disable-static + + cd $(DIR_SRC)/binutils-build && make tooldir=/usr $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + # Apply a sed substitution to prevent a testsuite error: + cd $(DIR_APP) && sed -i 's/getline/get_line/' libiberty/testsuite/test-demangle.c + cd $(DIR_SRC)/binutils-build && make check +endef + +define STAGE_INSTALL + cd $(DIR_SRC)/binutils-build && make tooldir=/usr install DESTDIR=$(BUILDROOT) + + cp -fv $(DIR_APP)/include/libiberty.h $(BUILDROOT)/usr/include +endef diff --git a/pkgs/core/binutils/patches/binutils-2.19.1-asprintf_fix.patch b/pkgs/core/binutils/patches/binutils-2.19.1-asprintf_fix.patch new file mode 100644 index 0000000..102ec2e --- /dev/null +++ b/pkgs/core/binutils/patches/binutils-2.19.1-asprintf_fix.patch @@ -0,0 +1,16 @@ +https://hardened.gentooexperimental.org/trac/secure/raw-attachment/ticket/33/libiberty.h-asprintf-glibc-2.8.patch + +--- a/include/libiberty.h.orig 2007-02-09 15:29:21.000000000 +0000 ++++ b/include/libiberty.h 2008-07-25 21:17:25.000000000 +0000 +@@ -554,8 +554,11 @@ + /* Like sprintf but provides a pointer to malloc'd storage, which must + be freed by the caller. */ + ++/* asprintf may be declared as a macro by glibc with __USE_FORTIFY_LEVEL. */ ++#ifndef asprintf + extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2; + #endif ++#endif + + #if !HAVE_DECL_VASPRINTF + /* Like vsprintf but provides a pointer to malloc'd storage, which diff --git a/pkgs/core/binutils/patches/binutils-2.19.1-ld_makefile.patch b/pkgs/core/binutils/patches/binutils-2.19.1-ld_makefile.patch new file mode 100644 index 0000000..4624f29 --- /dev/null +++ b/pkgs/core/binutils/patches/binutils-2.19.1-ld_makefile.patch @@ -0,0 +1,54 @@ +#!/bin/sh -e +## 001_ld_makefile_patch.dpatch +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: correct where ld scripts are installed +## DP: Author: Chris Chimelis <chris@debian.org> +## DP: Upstream status: N/A +## DP: Date: ?? + +if [ $# -ne 1 ]; then + echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" + exit 1 +fi + +[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts +patch_opts="${patch_opts:--f --no-backup-if-mismatch}" + +case "$1" in + -patch) patch $patch_opts -p1 < $0;; + -unpatch) patch $patch_opts -p1 -R < $0;; + *) + echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" + exit 1;; +esac + +exit 0 + +@DPATCH@ +Index: binutils-2.18/ld/Makefile.am +=================================================================== +--- binutils-2.18.orig/ld/Makefile.am 2007-06-28 09:19:34.837940280 +0200 ++++ binutils-2.18/ld/Makefile.am 2007-06-28 09:19:35.795794664 +0200 +@@ -18,7 +18,7 @@ + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + + EMUL = @EMUL@ + EMULATION_OFILES = @EMULATION_OFILES@ +Index: binutils-2.18/ld/Makefile.in +=================================================================== +--- binutils-2.18.orig/ld/Makefile.in 2007-06-28 09:19:34.844939216 +0200 ++++ binutils-2.18/ld/Makefile.in 2007-06-28 09:19:35.796794512 +0200 +@@ -287,7 +287,7 @@ + # We put the scripts in the directory $(scriptdir)/ldscripts. + # We can't put the scripts in $(datadir) because the SEARCH_DIR + # directives need to be different for native and cross linkers. +-scriptdir = $(tooldir)/lib ++scriptdir = $(libdir) + BASEDIR = $(srcdir)/.. + BFDDIR = $(BASEDIR)/bfd + INCDIR = $(BASEDIR)/include diff --git a/pkgs/core/binutils/patches/binutils-2.20-pt_pax-1.patch b/pkgs/core/binutils/patches/binutils-2.20-pt_pax-1.patch new file mode 100644 index 0000000..4eee0e6 --- /dev/null +++ b/pkgs/core/binutils/patches/binutils-2.20-pt_pax-1.patch @@ -0,0 +1,411 @@ +diff -Naur binutils-2.19.50.orig/bfd/elf-bfd.h binutils-2.19.50/bfd/elf-bfd.h +--- binutils-2.19.50.orig/bfd/elf-bfd.h 2008-08-20 23:28:58.000000000 +0000 ++++ binutils-2.19.50/bfd/elf-bfd.h 2008-10-05 02:03:46.000000000 +0000 +@@ -1526,6 +1526,9 @@ + /* Segment flags for the PT_GNU_STACK segment. */ + unsigned int stack_flags; + ++ /* Segment flags for the PT_PAX_FLAGS segment. */ ++ unsigned int pax_flags; ++ + /* Symbol version definitions in external objects. */ + Elf_Internal_Verdef *verdef; + +diff -Naur binutils-2.19.50.orig/bfd/elf.c binutils-2.19.50/bfd/elf.c +--- binutils-2.19.50.orig/bfd/elf.c 2008-10-03 09:40:48.000000000 +0000 ++++ binutils-2.19.50/bfd/elf.c 2008-10-05 02:03:46.000000000 +0000 +@@ -1136,6 +1136,7 @@ + case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break; + case PT_GNU_STACK: pt = "STACK"; break; + case PT_GNU_RELRO: pt = "RELRO"; break; ++ case PT_PAX_FLAGS: pt = "PAX_FLAGS"; break; + default: pt = NULL; break; + } + return pt; +@@ -2436,6 +2437,9 @@ + case PT_GNU_RELRO: + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "relro"); + ++ case PT_PAX_FLAGS: ++ return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "pax_flags"); ++ + default: + /* Check for any processor-specific program segment types. */ + bed = get_elf_backend_data (abfd); +@@ -3429,6 +3433,11 @@ + ++segs; + } + ++ { ++ /* We need a PT_PAX_FLAGS segment. */ ++ ++segs; ++ } ++ + for (s = abfd->sections; s != NULL; s = s->next) + { + if ((s->flags & SEC_LOAD) != 0 +@@ -4008,6 +4017,20 @@ + } + } + ++ { ++ amt = sizeof (struct elf_segment_map); ++ m = bfd_zalloc (abfd, amt); ++ if (m == NULL) ++ goto error_return; ++ m->next = NULL; ++ m->p_type = PT_PAX_FLAGS; ++ m->p_flags = elf_tdata (abfd)->pax_flags; ++ m->p_flags_valid = 1; ++ ++ *pm = m; ++ pm = &m->next; ++ } ++ + free (sections); + elf_tdata (abfd)->segment_map = mfirst; + } +@@ -5205,7 +5228,8 @@ + 6. PT_TLS segment includes only SHF_TLS sections. + 7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments. + 8. PT_DYNAMIC should not contain empty sections at the beginning +- (with the possible exception of .dynamic). */ ++ (with the possible exception of .dynamic). ++ 9. PT_PAX_FLAGS segments does not include any sections. */ + #define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed) \ + ((((segment->p_paddr \ + ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \ +@@ -5213,6 +5237,7 @@ + && (section->flags & SEC_ALLOC) != 0) \ + || IS_NOTE (segment, section)) \ + && segment->p_type != PT_GNU_STACK \ ++ && segment->p_type != PT_PAX_FLAGS \ + && (segment->p_type != PT_TLS \ + || (section->flags & SEC_THREAD_LOCAL)) \ + && (segment->p_type == PT_LOAD \ +diff -Naur binutils-2.19.50.orig/bfd/elflink.c binutils-2.19.50/bfd/elflink.c +--- binutils-2.19.50.orig/bfd/elflink.c 2008-10-03 09:40:48.000000000 +0000 ++++ binutils-2.19.50/bfd/elflink.c 2008-10-05 02:03:46.000000000 +0000 +@@ -5413,16 +5413,30 @@ + return TRUE; + + bed = get_elf_backend_data (output_bfd); ++ elf_tdata (output_bfd)->pax_flags = PF_NORANDEXEC; ++ ++ if (info->execheap) ++ elf_tdata (output_bfd)->pax_flags |= PF_NOMPROTECT; ++ else if (info->noexecheap) ++ elf_tdata (output_bfd)->pax_flags |= PF_MPROTECT; ++ + if (info->execstack) +- elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; ++ { ++ elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; ++ elf_tdata (output_bfd)->pax_flags |= PF_EMUTRAMP; ++ } + else if (info->noexecstack) +- elf_tdata (output_bfd)->stack_flags = PF_R | PF_W; ++ { ++ elf_tdata (output_bfd)->stack_flags = PF_R | PF_W; ++ elf_tdata (output_bfd)->pax_flags |= PF_NOEMUTRAMP; ++ } + else + { + bfd *inputobj; + asection *notesec = NULL; + int exec = 0; + ++ elf_tdata (output_bfd)->pax_flags |= PF_NOEMUTRAMP; + for (inputobj = info->input_bfds; + inputobj; + inputobj = inputobj->link_next) +@@ -5435,7 +5449,11 @@ + if (s) + { + if (s->flags & SEC_CODE) +- exec = PF_X; ++ { ++ elf_tdata (output_bfd)->pax_flags &= ~PF_NOEMUTRAMP; ++ elf_tdata (output_bfd)->pax_flags |= PF_EMUTRAMP; ++ exec = PF_X; ++ } + notesec = s; + } + else if (bed->default_execstack) +diff -Naur binutils-2.19.50.orig/binutils/readelf.c binutils-2.19.50/binutils/readelf.c +--- binutils-2.19.50.orig/binutils/readelf.c 2008-09-17 07:50:28.000000000 +0000 ++++ binutils-2.19.50/binutils/readelf.c 2008-10-05 02:03:46.000000000 +0000 +@@ -2505,6 +2505,7 @@ + return "GNU_EH_FRAME"; + case PT_GNU_STACK: return "GNU_STACK"; + case PT_GNU_RELRO: return "GNU_RELRO"; ++ case PT_PAX_FLAGS: return "PAX_FLAGS"; + + default: + if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC)) +diff -Naur binutils-2.19.50.orig/include/bfdlink.h binutils-2.19.50/include/bfdlink.h +--- binutils-2.19.50.orig/include/bfdlink.h 2008-08-17 03:12:50.000000000 +0000 ++++ binutils-2.19.50/include/bfdlink.h 2008-10-05 02:03:46.000000000 +0000 +@@ -319,6 +319,14 @@ + /* TRUE if PT_GNU_RELRO segment should be created. */ + unsigned int relro: 1; + ++ /* TRUE if PT_PAX_FLAGS segment should be created with PF_NOMPROTECT ++ flags. */ ++ unsigned int execheap: 1; ++ ++ /* TRUE if PT_PAX_FLAGS segment should be created with PF_MPROTECT ++ flags. */ ++ unsigned int noexecheap: 1; ++ + /* TRUE if we should warn when adding a DT_TEXTREL to a shared object. */ + unsigned int warn_shared_textrel: 1; + +diff -Naur binutils-2.19.50.orig/include/elf/common.h binutils-2.19.50/include/elf/common.h +--- binutils-2.19.50.orig/include/elf/common.h 2008-08-03 23:20:42.000000000 +0000 ++++ binutils-2.19.50/include/elf/common.h 2008-10-05 02:04:51.000000000 +0000 +@@ -360,6 +360,7 @@ + #define PT_SUNW_EH_FRAME PT_GNU_EH_FRAME /* Solaris uses the same value */ + #define PT_GNU_STACK (PT_LOOS + 0x474e551) /* Stack flags */ + #define PT_GNU_RELRO (PT_LOOS + 0x474e552) /* Read-only after relocation */ ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580) /* PaX flags */ + + /* Program segment permissions, in program header p_flags field. */ + +@@ -370,6 +371,21 @@ + #define PF_MASKOS 0x0FF00000 /* New value, Oct 4, 1999 Draft */ + #define PF_MASKPROC 0xF0000000 /* Processor-specific reserved bits */ + ++/* Flags to control PaX behavior. */ ++ ++#define PF_PAGEEXEC (1 << 4) /* Enable PAGEEXEC */ ++#define PF_NOPAGEEXEC (1 << 5) /* Disable PAGEEXEC */ ++#define PF_SEGMEXEC (1 << 6) /* Enable SEGMEXEC */ ++#define PF_NOSEGMEXEC (1 << 7) /* Disable SEGMEXEC */ ++#define PF_MPROTECT (1 << 8) /* Enable MPROTECT */ ++#define PF_NOMPROTECT (1 << 9) /* Disable MPROTECT */ ++#define PF_RANDEXEC (1 << 10) /* Enable RANDEXEC */ ++#define PF_NORANDEXEC (1 << 11) /* Disable RANDEXEC */ ++#define PF_EMUTRAMP (1 << 12) /* Enable EMUTRAMP */ ++#define PF_NOEMUTRAMP (1 << 13) /* Disable EMUTRAMP */ ++#define PF_RANDMMAP (1 << 14) /* Enable RANDMMAP */ ++#define PF_NORANDMMAP (1 << 15) /* Disable RANDMMAP */ ++ + /* Values for section header, sh_type field. */ + + #define SHT_NULL 0 /* Section header table entry unused */ +diff -Naur binutils-2.19.50.orig/ld/emultempl/elf32.em binutils-2.19.50/ld/emultempl/elf32.em +--- binutils-2.19.50.orig/ld/emultempl/elf32.em 2008-10-03 09:40:49.000000000 +0000 ++++ binutils-2.19.50/ld/emultempl/elf32.em 2008-10-05 02:03:46.000000000 +0000 +@@ -2123,6 +2123,16 @@ + link_info.noexecstack = TRUE; + link_info.execstack = FALSE; + } ++ else if (strcmp (optarg, "execheap") == 0) ++ { ++ link_info.execheap = TRUE; ++ link_info.noexecheap = FALSE; ++ } ++ else if (strcmp (optarg, "noexecheap") == 0) ++ { ++ link_info.noexecheap = TRUE; ++ link_info.execheap = FALSE; ++ } + EOF + + if test -n "$COMMONPAGESIZE"; then +@@ -2206,6 +2216,8 @@ + fprintf (file, _("\ + -z execstack Mark executable as requiring executable stack\n")); + fprintf (file, _("\ ++ -z execheap Mark executable as requiring executable heap\n")); ++ fprintf (file, _("\ + -z initfirst Mark DSO to be initialized first at runtime\n")); + fprintf (file, _("\ + -z interpose Mark object to interpose all DSOs but executable\n")); +@@ -2229,6 +2241,8 @@ + -z nodump Mark DSO not available to dldump\n")); + fprintf (file, _("\ + -z noexecstack Mark executable as not requiring executable stack\n")); ++ fprintf (file, _("\ ++ -z noexecheap Mark executable as not requiring executable heap\n")); + EOF + + if test -n "$COMMONPAGESIZE"; then +diff -Naur binutils-2.19.50.orig/ld/ldgram.y binutils-2.19.50/ld/ldgram.y +--- binutils-2.19.50.orig/ld/ldgram.y 2008-07-06 13:38:36.000000000 +0000 ++++ binutils-2.19.50/ld/ldgram.y 2008-10-05 02:03:46.000000000 +0000 +@@ -1112,6 +1112,8 @@ + $$ = exp_intop (0x6474e550); + else if (strcmp (s, "PT_GNU_STACK") == 0) + $$ = exp_intop (0x6474e551); ++ else if (strcmp (s, "PT_PAX_FLAGS") == 0) ++ $$ = exp_intop (0x65041580); + else + { + einfo (_("\ +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-elf/seg.d binutils-2.19.50/ld/testsuite/ld-elf/seg.d +--- binutils-2.19.50.orig/ld/testsuite/ld-elf/seg.d 2008-02-22 23:10:45.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-elf/seg.d 2008-10-05 02:03:46.000000000 +0000 +@@ -10,5 +10,6 @@ + #... + LOAD .* + LOAD 0x0*001000 0xf*fffff000 0xf*fffff000 0x0*1000 0x0*1000 .* ++ PAX_FLAGS 0x000000 0x00000000 0x00000000 0x00000 0x00000 0x4 + # FRV adds a PT_GNU_STACK header + #... +@@ -17,4 +18,5 @@ + # On MIPS, the first segment is for .reginfo. + #... + 0. reset boot ++ 02 + #pass +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-i386/hidden2.d binutils-2.19.50/ld/testsuite/ld-i386/hidden2.d +--- binutils-2.19.50.orig/ld/testsuite/ld-i386/hidden2.d 2008-03-16 22:26:23.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-i386/hidden2.d 2008-10-05 02:03:46.000000000 +0000 +@@ -8,6 +8,6 @@ + Disassembly of section .text: + + [a-f0-9]+ <bar>: +-[ ]*[a-f0-9]+: e8 cf fe ff ff call 0 <bar-0x[a-f0-9]+> ++[ ]*[a-f0-9]+: e8 af fe ff ff call 0 <bar-0x[a-f0-9]+> + [ ]*[a-f0-9]+: c3 ret + #pass +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsbin.rd binutils-2.19.50/ld/testsuite/ld-i386/tlsbin.rd +--- binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsbin.rd 2007-09-30 01:33:14.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-i386/tlsbin.rd 2008-10-05 02:03:46.000000000 +0000 +@@ -44,6 +44,7 @@ + LOAD.* + DYNAMIC.* + TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+a0 R +0x1000 ++ PAX_FLAGS +0x000000 0x00000000 0x00000000 0x00000 0x00000 +0x4 + + Section to Segment mapping: + Segment Sections... +@@ -53,6 +54,7 @@ + 03 +.tdata .dynamic .got .got.plt * + 04 +.dynamic * + 05 +.tdata .tbss * ++ 06 * + + Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 9 entries: + Offset +Info +Type +Sym.Value +Sym. Name +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsbindesc.rd binutils-2.19.50/ld/testsuite/ld-i386/tlsbindesc.rd +--- binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsbindesc.rd 2008-07-28 18:07:05.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-i386/tlsbindesc.rd 2008-10-05 02:03:46.000000000 +0000 +@@ -42,6 +42,7 @@ + LOAD.* + DYNAMIC.* + TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+a0 R +0x1000 ++ PAX_FLAGS +0x000000 0x00000000 0x00000000 0x00000 0x00000 +0x4 + + Section to Segment mapping: + Segment Sections... +@@ -51,6 +52,7 @@ + 03 +.tdata .dynamic .got .got.plt * + 04 +.dynamic * + 05 +.tdata .tbss * ++ 06 * + + Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 9 entries: + Offset +Info +Type +Sym.Value +Sym. Name +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsdesc.rd binutils-2.19.50/ld/testsuite/ld-i386/tlsdesc.rd +--- binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsdesc.rd 2007-09-30 01:33:14.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-i386/tlsdesc.rd 2008-10-05 02:03:46.000000000 +0000 +@@ -39,6 +39,7 @@ + LOAD.* + DYNAMIC.* + TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+80 R +0x1 ++ PAX_FLAGS +0x000000 0x00000000 0x00000000 0x00000 0x00000 +0x4 + + Section to Segment mapping: + Segment Sections... +@@ -46,6 +47,7 @@ + 01 +.tdata .dynamic .got .got.plt * + 02 +.dynamic * + 03 +.tdata .tbss * ++ 04 * + + Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 20 entries: + Offset +Info +Type +Sym.Value +Sym. Name +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsdesc.sd binutils-2.19.50/ld/testsuite/ld-i386/tlsdesc.sd +--- binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsdesc.sd 2006-10-17 13:41:48.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-i386/tlsdesc.sd 2008-10-05 02:03:46.000000000 +0000 +@@ -14,7 +14,7 @@ + [0-9a-f]+ 6c000000 b4ffffff 4c000000 68000000 .* + [0-9a-f]+ 50000000 70000000 00000000 bcffffff .* + Contents of section .got.plt: +- [0-9a-f]+ b0150000 00000000 00000000 00000000 .* ++ [0-9a-f]+ d0150000 00000000 00000000 00000000 .* + [0-9a-f]+ 20000000 00000000 60000000 00000000 .* + [0-9a-f]+ 00000000 00000000 00000000 00000000 .* + [0-9a-f]+ 40000000 +.* +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsgdesc.rd binutils-2.19.50/ld/testsuite/ld-i386/tlsgdesc.rd +--- binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsgdesc.rd 2007-09-30 01:33:14.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-i386/tlsgdesc.rd 2008-10-05 02:03:46.000000000 +0000 +@@ -36,12 +36,14 @@ + LOAD.* + LOAD.* + DYNAMIC.* ++ PAX_FLAGS +0x000000 0x00000000 0x00000000 0x00000 0x00000 +0x4 + + Section to Segment mapping: + Segment Sections... + 00 +.hash .dynsym .dynstr .rel.dyn .rel.plt .plt .text * + 01 +.dynamic .got .got.plt * + 02 +.dynamic * ++ 03 * + + Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 8 entries: + Offset +Info +Type +Sym.Value +Sym. Name +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsnopic.rd binutils-2.19.50/ld/testsuite/ld-i386/tlsnopic.rd +--- binutils-2.19.50.orig/ld/testsuite/ld-i386/tlsnopic.rd 2007-09-30 01:33:14.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-i386/tlsnopic.rd 2008-10-05 02:03:46.000000000 +0000 +@@ -37,6 +37,7 @@ + LOAD.* + DYNAMIC.* + TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+ 0x0+24 R +0x1 ++ PAX_FLAGS +0x000000 0x00000000 0x00000000 0x00000 0x00000 +0x4 + + Section to Segment mapping: + Segment Sections... +@@ -44,6 +45,7 @@ + 01 +.dynamic .got .got.plt * + 02 +.dynamic * + 03 +.tbss * ++ 04 * + + Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 20 entries: + Offset +Info +Type +Sym.Value +Sym. Name +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-i386/tlspic.rd binutils-2.19.50/ld/testsuite/ld-i386/tlspic.rd +--- binutils-2.19.50.orig/ld/testsuite/ld-i386/tlspic.rd 2007-09-30 01:33:14.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-i386/tlspic.rd 2008-10-05 02:03:46.000000000 +0000 +@@ -40,6 +40,7 @@ + LOAD.* + DYNAMIC.* + TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+80 R +0x1 ++ PAX_FLAGS +0x000000 0x00000000 0x00000000 0x00000 0x00000 +0x4 + + Section to Segment mapping: + Segment Sections... +@@ -47,6 +48,7 @@ + 01 +.tdata .dynamic .got .got.plt * + 02 +.dynamic * + 03 +.tdata .tbss * ++ 04 * + + Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 26 entries: + Offset +Info +Type +Sym.Value +Sym. Name +diff -Naur binutils-2.19.50.orig/ld/testsuite/ld-scripts/empty-aligned.d binutils-2.19.50/ld/testsuite/ld-scripts/empty-aligned.d +--- binutils-2.19.50.orig/ld/testsuite/ld-scripts/empty-aligned.d 2005-08-18 07:51:07.000000000 +0000 ++++ binutils-2.19.50/ld/testsuite/ld-scripts/empty-aligned.d 2008-10-05 02:03:46.000000000 +0000 +@@ -7,7 +7,9 @@ + Program Headers: + +Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg +Align + +LOAD +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ [RWE ]+ +0x[0-9a-f]+ ++ +PAX_FLAGS +0x000000 0x00000000 0x00000000 0x00000 0x00000 +0x4 + + Section to Segment mapping: + +Segment Sections... + +00 +.text ++ +01 + diff --git a/pkgs/core/bison/bison.nm b/pkgs/core/bison/bison.nm new file mode 100644 index 0000000..065442e --- /dev/null +++ b/pkgs/core/bison/bison.nm @@ -0,0 +1,72 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = bison +PKG_VER = 2.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/bison/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = GNU Bison is a parser generator. + +define PKG_DESCRIPTION + Bison is a general-purpose parser generator that converts an annotated \ + context-free grammar into an LALR(1) or GLR parser for that grammar. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr + + cd $(DIR_APP) && echo '#define YYENABLE_NLS 1' >> lib/config.h + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +# fails +#define STAGE_TEST +# cd $(DIR_APP) && make check +#endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/usr/lib + cd $(DIR_APP)/lib && gcc -shared -Wl,-soname,liby.so.$(PKG_VER) \ + -o liby.so.$(PKG_VER) $(CFLAGS) main.o yyerror.o + cd $(DIR_APP)/lib && install -v liby.so.$(PKG_VER) \ + $(BUILDROOT)/usr/lib/liby.so.$(PKG_VER) + ln -vsf liby.so.$(PKG_VER) $(BUILDROOT)/usr/lib/liby.so.2 + ln -vsf liby.so.2 $(BUILDROOT)/usr/lib/liby.so +endef diff --git a/pkgs/core/boost/boost.nm b/pkgs/core/boost/boost.nm new file mode 100644 index 0000000..f0d26ed --- /dev/null +++ b/pkgs/core/boost/boost.nm @@ -0,0 +1,100 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = boost +PKG_VER = 1.39.0 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.boost.org/ +PKG_LICENSE = Boost +PKG_SUMMARY = The Boost C++ Libraries. + +PKG_DEPS += python + +define PKG_DESCRIPTION + Boost provides free peer-reviewed portable C++ source libraries. The \ + emphasis is on libraries which work well with the C++ Standard \ + Library, in the hopes of establishing "existing practice" for \ + extensions and providing reference implementations so that the Boost \ + libraries are suitable for eventual standardization. (Some of the \ + libraries have already been proposed for inclusion in the C++ \ + Standards Committee's upcoming C++ Standard Library Technical Report.) +endef + +PKG_TARBALL = $(PKG_NAME)_$(subst .,_,$(PKG_VER)).tar.bz2 + +export BOOST_ROOT=$(DIR_APP) +BUILD_FLAGS = -d2 --layout=system variant=release threading=single,multi \ + debug-symbols=on link=shared runtime-link=shared +SONAMEVERSION = 5 + +CFLAGS += -fno-strict-aliasing + +PARALLELISMFLAGS := -j3 + +DIR_APP = $(DIR_SRC)/$(PKG_NAME)_$(subst .,_,$(PKG_VER)) + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + # Let bjam use our own cflags + cd $(DIR_APP) && sed -e "s/-O3/$(CFLAGS)/g" -i tools/build/v2/tools/gcc.jam +endef + +define STAGE_BUILD + # build jam + cd $(DIR_APP)/tools/jam/src && ./build.sh + + # build libs + cd $(DIR_APP) && ./bootstrap.sh \ + --with-toolset=gcc \ + --with-icu + + cd $(DIR_APP) && \ + ./bjam $(BUILD_FLAGS) $(PARALLELISMFLAGS) stage +endef + +define STAGE_INSTALL + # install libs + -mkdir -pv $(BUILDROOT)/usr/lib + cd $(DIR_APP) && for i in $$(find stage -type f -name "*.so"); do \ + install -v -p -m 755 $$i $(BUILDROOT)/usr/lib/$$(basename $$i).$(PKG_VER); \ + ln -svf $$(basename $$i).$(PKG_VER) $(BUILDROOT)/usr/lib/$$(basename $$i).$(SONAMEVERSION); \ + ln -svf $$(basename $$i).$(SONAMEVERSION) $(BUILDROOT)/usr/lib/$$(basename $$i); \ + done + + # install includes + -mkdir -pv $(BUILDROOT)/usr/include + cd $(DIR_APP) && find boost -type d | while read a; do \ + mkdir -pv $(BUILDROOT)/usr/include/$$a; \ + find $$a -mindepth 1 -maxdepth 1 -type f | \ + xargs -r install -v -m 644 -p -t $(BUILDROOT)/usr/include/$$a; \ + done +endef diff --git a/pkgs/core/boost/patches/boost-1.39.0-fs_gcc44.patch b/pkgs/core/boost/patches/boost-1.39.0-fs_gcc44.patch new file mode 100644 index 0000000..235a61e --- /dev/null +++ b/pkgs/core/boost/patches/boost-1.39.0-fs_gcc44.patch @@ -0,0 +1,163 @@ +Index: boost/filesystem/operations.hpp +=================================================================== +--- a/boost/filesystem/operations.hpp (revision 52859) ++++ b/boost/filesystem/operations.hpp (working copy) +@@ -659,9 +659,9 @@ + { return is_symlink<wpath>( ph ); } + + inline bool is_empty( const path & ph ) +- { return is_empty<path>( ph ); } ++ { return boost::filesystem::is_empty<path>( ph ); } + inline bool is_empty( const wpath & ph ) +- { return is_empty<wpath>( ph ); } ++ { return boost::filesystem::is_empty<wpath>( ph ); } + + inline bool equivalent( const path & ph1, const path & ph2 ) + { return equivalent<path>( ph1, ph2 ); } +Index: libs/filesystem/test/path_test.cpp +=================================================================== +--- a/libs/filesystem/test/path_test.cpp (revision 52859) ++++ b/libs/filesystem/test/path_test.cpp (working copy) +@@ -27,9 +27,8 @@ + + namespace fs = boost::filesystem; + using boost::filesystem::path; +-using boost::next; +-using boost::prior; + ++ + #include <boost/detail/lightweight_test.hpp> + + #define PATH_CHECK( a, b ) check( a, b, __LINE__ ) +@@ -480,18 +479,18 @@ + + itr_ck = "foo"; + BOOST_TEST( *itr_ck.begin() == std::string( "foo" ) ); +- BOOST_TEST( next( itr_ck.begin() ) == itr_ck.end() ); +- BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); +- BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); ++ BOOST_TEST( boost::next( itr_ck.begin() ) == itr_ck.end() ); ++ BOOST_TEST( *boost::prior( itr_ck.end() ) == std::string( "foo" ) ); ++ BOOST_TEST( boost::prior( itr_ck.end() ) == itr_ck.begin() ); + + itr_ck = path( "/foo" ); + BOOST_TEST( *itr_ck.begin() == std::string( "/" ) ); +- BOOST_TEST( *next( itr_ck.begin() ) == std::string( "foo" ) ); +- BOOST_TEST( next(next( itr_ck.begin() )) == itr_ck.end() ); +- BOOST_TEST( next( itr_ck.begin() ) == prior( itr_ck.end() ) ); +- BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); +- BOOST_TEST( *prior(prior( itr_ck.end() )) == std::string( "/" ) ); +- BOOST_TEST( prior(prior( itr_ck.end() )) == itr_ck.begin() ); ++ BOOST_TEST( *boost::next( itr_ck.begin() ) == std::string( "foo" ) ); ++ BOOST_TEST( boost::next(boost::next( itr_ck.begin() )) == itr_ck.end() ); ++ BOOST_TEST( boost::next( itr_ck.begin() ) == boost::prior( itr_ck.end() ) ); ++ BOOST_TEST( *boost::prior( itr_ck.end() ) == std::string( "foo" ) ); ++ BOOST_TEST( *boost::prior(boost::prior( itr_ck.end() )) == std::string( "/" ) ); ++ BOOST_TEST( boost::prior(boost::prior( itr_ck.end() )) == itr_ck.begin() ); + + itr_ck = "/foo/bar"; + itr = itr_ck.begin(); +@@ -1106,65 +1105,65 @@ + + itr_ck = path( "c:" ); + BOOST_TEST( *itr_ck.begin() == std::string( "c:" ) ); +- BOOST_TEST( next( itr_ck.begin() ) == itr_ck.end() ); +- BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); +- BOOST_TEST( *prior( itr_ck.end() ) == std::string( "c:" ) ); ++ BOOST_TEST( boost::next( itr_ck.begin() ) == itr_ck.end() ); ++ BOOST_TEST( boost::prior( itr_ck.end() ) == itr_ck.begin() ); ++ BOOST_TEST( *boost::prior( itr_ck.end() ) == std::string( "c:" ) ); + + itr_ck = path( "c:/" ); + BOOST_TEST( *itr_ck.begin() == std::string( "c:" ) ); +- BOOST_TEST( *next( itr_ck.begin() ) == std::string( "/" ) ); +- BOOST_TEST( next( next( itr_ck.begin() )) == itr_ck.end() ); +- BOOST_TEST( prior( prior( itr_ck.end() )) == itr_ck.begin() ); +- BOOST_TEST( *prior( itr_ck.end() ) == std::string( "/" ) ); +- BOOST_TEST( *prior( prior( itr_ck.end() )) == std::string( "c:" ) ); ++ BOOST_TEST( *boost::next( itr_ck.begin() ) == std::string( "/" ) ); ++ BOOST_TEST( boost::next( boost::next( itr_ck.begin() )) == itr_ck.end() ); ++ BOOST_TEST( boost::prior( boost::prior( itr_ck.end() )) == itr_ck.begin() ); ++ BOOST_TEST( *boost::prior( itr_ck.end() ) == std::string( "/" ) ); ++ BOOST_TEST( *boost::prior( boost::prior( itr_ck.end() )) == std::string( "c:" ) ); + + itr_ck = path( "c:foo" ); + BOOST_TEST( *itr_ck.begin() == std::string( "c:" ) ); +- BOOST_TEST( *next( itr_ck.begin() ) == std::string( "foo" ) ); +- BOOST_TEST( next(next( itr_ck.begin() )) == itr_ck.end() ); +- BOOST_TEST( prior(prior( itr_ck.end() )) == itr_ck.begin() ); +- BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); +- BOOST_TEST( *prior(prior( itr_ck.end() )) == std::string( "c:" ) ); ++ BOOST_TEST( *boost::next( itr_ck.begin() ) == std::string( "foo" ) ); ++ BOOST_TEST( boost::next(boost::next( itr_ck.begin() )) == itr_ck.end() ); ++ BOOST_TEST( boost::prior(boost::prior( itr_ck.end() )) == itr_ck.begin() ); ++ BOOST_TEST( *boost::prior( itr_ck.end() ) == std::string( "foo" ) ); ++ BOOST_TEST( *boost::prior(boost::prior( itr_ck.end() )) == std::string( "c:" ) ); + + itr_ck = path( "c:/foo" ); + BOOST_TEST( *itr_ck.begin() == std::string( "c:" ) ); +- BOOST_TEST( *next( itr_ck.begin() ) == std::string( "/" ) ); +- BOOST_TEST( *next( next( itr_ck.begin() )) == std::string( "foo" ) ); +- BOOST_TEST( next( next( next( itr_ck.begin() ))) == itr_ck.end() ); +- BOOST_TEST( prior( prior( prior( itr_ck.end() ))) == itr_ck.begin() ); +- BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); +- BOOST_TEST( *prior( prior( itr_ck.end() )) == std::string( "/" ) ); +- BOOST_TEST( *prior( prior( prior( itr_ck.end() ))) == std::string( "c:" ) ); ++ BOOST_TEST( *boost::next( itr_ck.begin() ) == std::string( "/" ) ); ++ BOOST_TEST( *boost::next( boost::next( itr_ck.begin() )) == std::string( "foo" ) ); ++ BOOST_TEST( boost::next( boost::next( boost::next( itr_ck.begin() ))) == itr_ck.end() ); ++ BOOST_TEST( boost::prior( boost::prior( boost::prior( itr_ck.end() ))) == itr_ck.begin() ); ++ BOOST_TEST( *boost::prior( itr_ck.end() ) == std::string( "foo" ) ); ++ BOOST_TEST( *boost::prior( boost::prior( itr_ck.end() )) == std::string( "/" ) ); ++ BOOST_TEST( *boost::prior( boost::prior( boost::prior( itr_ck.end() ))) == std::string( "c:" ) ); + + itr_ck = path( "//net" ); + BOOST_TEST( *itr_ck.begin() == std::string( "//net" ) ); +- BOOST_TEST( next( itr_ck.begin() ) == itr_ck.end() ); +- BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); +- BOOST_TEST( *prior( itr_ck.end() ) == std::string( "//net" ) ); ++ BOOST_TEST( boost::next( itr_ck.begin() ) == itr_ck.end() ); ++ BOOST_TEST( boost::prior( itr_ck.end() ) == itr_ck.begin() ); ++ BOOST_TEST( *boost::prior( itr_ck.end() ) == std::string( "//net" ) ); + + itr_ck = path( "//net/" ); + CHECK_EQUAL( *itr_ck.begin(), "//net" ); +- CHECK_EQUAL( *next( itr_ck.begin() ), "/" ); +- BOOST_TEST( next(next( itr_ck.begin() )) == itr_ck.end() ); +- BOOST_TEST( prior(prior( itr_ck.end() )) == itr_ck.begin() ); +- CHECK_EQUAL( *prior( itr_ck.end() ), "/" ); +- CHECK_EQUAL( *prior(prior( itr_ck.end() )), "//net" ); ++ CHECK_EQUAL( *boost::next( itr_ck.begin() ), "/" ); ++ BOOST_TEST( boost::next(boost::next( itr_ck.begin() )) == itr_ck.end() ); ++ BOOST_TEST( boost::prior(boost::prior( itr_ck.end() )) == itr_ck.begin() ); ++ CHECK_EQUAL( *boost::prior( itr_ck.end() ), "/" ); ++ CHECK_EQUAL( *boost::prior(boost::prior( itr_ck.end() )), "//net" ); + + itr_ck = path( "//net/foo" ); + BOOST_TEST( *itr_ck.begin() == std::string( "//net" ) ); +- BOOST_TEST( *next( itr_ck.begin() ) == std::string( "/" ) ); +- BOOST_TEST( *next(next( itr_ck.begin() )) == std::string( "foo" ) ); +- BOOST_TEST( next(next(next( itr_ck.begin() ))) == itr_ck.end() ); +- BOOST_TEST( prior(prior(prior( itr_ck.end() ))) == itr_ck.begin() ); +- BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); +- BOOST_TEST( *prior(prior( itr_ck.end() )) == std::string( "/" ) ); +- BOOST_TEST( *prior(prior(prior( itr_ck.end() ))) == std::string( "//net" ) ); ++ BOOST_TEST( *boost::next( itr_ck.begin() ) == std::string( "/" ) ); ++ BOOST_TEST( *boost::next(boost::next( itr_ck.begin() )) == std::string( "foo" ) ); ++ BOOST_TEST( boost::next(boost::next(boost::next( itr_ck.begin() ))) == itr_ck.end() ); ++ BOOST_TEST( boost::prior(boost::prior(boost::prior( itr_ck.end() ))) == itr_ck.begin() ); ++ BOOST_TEST( *boost::prior( itr_ck.end() ) == std::string( "foo" ) ); ++ BOOST_TEST( *boost::prior(boost::prior( itr_ck.end() )) == std::string( "/" ) ); ++ BOOST_TEST( *boost::prior(boost::prior(boost::prior( itr_ck.end() ))) == std::string( "//net" ) ); + + itr_ck = path( "prn:" ); + BOOST_TEST( *itr_ck.begin() == std::string( "prn:" ) ); +- BOOST_TEST( next( itr_ck.begin() ) == itr_ck.end() ); +- BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); +- BOOST_TEST( *prior( itr_ck.end() ) == std::string( "prn:" ) ); ++ BOOST_TEST( boost::next( itr_ck.begin() ) == itr_ck.end() ); ++ BOOST_TEST( boost::prior( itr_ck.end() ) == itr_ck.begin() ); ++ BOOST_TEST( *boost::prior( itr_ck.end() ) == std::string( "prn:" ) ); + } // Windows + + else diff --git a/pkgs/core/boost/patches/boost-1.39.0-function_template.patch b/pkgs/core/boost/patches/boost-1.39.0-function_template.patch new file mode 100644 index 0000000..892134f --- /dev/null +++ b/pkgs/core/boost/patches/boost-1.39.0-function_template.patch @@ -0,0 +1,15 @@ +diff -ru boost/function/function_template.hpp boost/function/function_template.hpp +--- a/boost/function/function_template.hpp 2009-05-10 10:31:29.000000000 +0100 ++++ b/boost/function/function_template.hpp 2009-05-10 10:49:46.000000000 +0100 +@@ -950,10 +950,10 @@ + f.vtable->manager(f.functor, this->functor, + boost::detail::function::move_functor_tag); + f.vtable = 0; +-#if !defined(BOOST_NO_EXCEPTIONS) + } else { + clear(); + } ++#if !defined(BOOST_NO_EXCEPTIONS) + } catch (...) { + vtable = 0; + throw; diff --git a/pkgs/core/boost/patches/boost-1.39.0-unneccessary_iostreams.patch b/pkgs/core/boost/patches/boost-1.39.0-unneccessary_iostreams.patch new file mode 100644 index 0000000..0fd590a --- /dev/null +++ b/pkgs/core/boost/patches/boost-1.39.0-unneccessary_iostreams.patch @@ -0,0 +1,11 @@ +diff -ru boost/spirit/home/classic/iterator/multi_pass.hpp boost/spirit/home/classic/iterator/multi_pass.hpp +--- a/boost/spirit/home/classic/iterator/multi_pass.hpp 2009-01-09 10:38:36.000000000 +0000 ++++ b/boost/spirit/home/classic/iterator/multi_pass.hpp 2009-01-09 10:39:41.000000000 +0000 +@@ -12,7 +12,6 @@ + #include <boost/throw_exception.hpp> + #include <deque> + #include <iterator> +-#include <iostream> + #include <algorithm> // for std::swap + #include <exception> // for std::exception + #include <boost/limits.hpp> diff --git a/pkgs/core/boost/patches/boost-1.39.0-version-override.patch b/pkgs/core/boost/patches/boost-1.39.0-version-override.patch new file mode 100644 index 0000000..0fe654c --- /dev/null +++ b/pkgs/core/boost/patches/boost-1.39.0-version-override.patch @@ -0,0 +1,36 @@ +*** a/Jamroot.orig 2009-05-06 12:46:31.000000000 -0700 +--- b/Jamroot 2009-05-06 18:18:17.000000000 -0700 +*************** rule tag ( name : type ? : property-set +*** 344,350 **** + else + { + local result = [ common.format-name +! <base> + -$(BUILD_ID) + : $(name) : $(type) : $(property-set) ] ; + +--- 344,350 ---- + else + { + local result = [ common.format-name +! <base> <threading> + -$(BUILD_ID) + : $(name) : $(type) : $(property-set) ] ; + +*************** rule tag ( name : type ? : property-set +*** 356,362 **** + # suffixes either. Pgi compilers can not accept library with version + # suffix. + if $(type) = SHARED_LIB && +! ( ! ( [ $(property-set).get <target-os> ] in windows cygwin darwin aix ) && + ! ( [ $(property-set).get <toolset> ] in pgi ) ) + { + result = $(result).$(BOOST_VERSION) ; +--- 356,362 ---- + # suffixes either. Pgi compilers can not accept library with version + # suffix. + if $(type) = SHARED_LIB && +! ( ! ( [ $(property-set).get <target-os> ] in windows cygwin darwin aix linux ) && + ! ( [ $(property-set).get <toolset> ] in pgi ) ) + { + result = $(result).$(BOOST_VERSION) ; diff --git a/pkgs/core/br2684ctl/br2684ctl.nm b/pkgs/core/br2684ctl/br2684ctl.nm new file mode 100644 index 0000000..81cb9c0 --- /dev/null +++ b/pkgs/core/br2684ctl/br2684ctl.nm @@ -0,0 +1,60 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = br2684ctl +PKG_VER = ipfire-1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://cvs.linux-atm.sourceforge.net/viewcvs.py/linux-atm/linux-atm/src/br2684/Attic/br2684ctl.8?rev=1.1.2.1&hideattic=0&only_with_tag=V2_5_0 +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Utilities for configuring an ATM/ethernet bridge. + +PKG_DEPS += linux-atm + +define PKG_DESCRIPTION + Utility for configuring RFC 2684 ATM/Ethernet bridging \ + ATM bridging is a way to extend Ethernet over an ATM network and is \ + mainly used for DSL connections. This package contains the user space \ + utility needed to configure the kernel driver. \ + This package is needed if you own an USB DSL modem and your connection \ + uses one of these protocols: RFC 1483 bridged (RFC 2684 bridged), \ + PPP over Ethernet (PPPoE). +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +DIR_APP = $(DIR_SRC)/br2684ctl + +define STAGE_BUILD + cd $(DIR_APP) && gcc $(CFLAGS) -latm br2684ctl.c -o br2684ctl +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/usr/bin + cd $(DIR_APP) && install -v -m 755 br2684ctl $(BUILDROOT)/usr/bin/br2684ctl +endef diff --git a/pkgs/core/bridge-utils/bridge-utils.nm b/pkgs/core/bridge-utils/bridge-utils.nm new file mode 100644 index 0000000..16555ee --- /dev/null +++ b/pkgs/core/bridge-utils/bridge-utils.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = bridge-utils +PKG_VER = 1.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://bridge.sourceforge.net/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Utilities for configuring the linux ethernet bridge. + +PKG_BUILD_DEPS+= autoconf automake + +define PKG_DESCRIPTION + This package contains utilities for configuring the linux ethernet \ + bridge. The linux ethernet bridge can be used for connecting multiple \ + ethernet devices together. The connecting is fully transparent: hosts \ + connected to one ethernet device see hosts connected to the other \ + ethernet devices directly. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --sbindir=/sbin + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && autoconf +endef diff --git a/pkgs/core/btrfs-progs/btrfs-progs.nm b/pkgs/core/btrfs-progs/btrfs-progs.nm new file mode 100644 index 0000000..cb3812d --- /dev/null +++ b/pkgs/core/btrfs-progs/btrfs-progs.nm @@ -0,0 +1,56 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = btrfs-progs +PKG_VER = 0.19 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://btrfs.wiki.kernel.org/index.php/Main_Page +PKG_LICENSE = GPLv2 +PKG_SUMMARY = Userspace programs for btrfs. + +PKG_BUILD_DEPS+= util-linux-ng + +define PKG_DESCRIPTION + The btrfs-progs package provides all the userpsace programs needed to create, \ + check, modify and correct any inconsistencies in the btrfs filesystem. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make bindir=$(BUILDROOT)/sbin mandir=$(BUILDROOT)/usr/share install +endef diff --git a/pkgs/core/bwm-ng/bwm-ng.nm b/pkgs/core/bwm-ng/bwm-ng.nm new file mode 100644 index 0000000..4ee3533 --- /dev/null +++ b/pkgs/core/bwm-ng/bwm-ng.nm @@ -0,0 +1,41 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = bwm-ng +PKG_VER = 0.6 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Statistics +PKG_URL = http://www.gropp.org/?id=projects&sub=bwm-ng +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A bandwidth monitor for the shell. + +define PKG_DESCRIPTION + bwm-ng diplays the traffic passing by on all interfaces. +endef + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/bzip2/bzip2.nm b/pkgs/core/bzip2/bzip2.nm new file mode 100644 index 0000000..d206936 --- /dev/null +++ b/pkgs/core/bzip2/bzip2.nm @@ -0,0 +1,78 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = bzip2 +PKG_VER = 1.0.5 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Compression +PKG_URL = http://www.bzip.org/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Bzip2 is a data compressor. + +PKG_PACKAGES += $(PKG_NAME_REAL)-devel + +define PKG_DESCRIPTION + bzip2 is a freely available, patent free (see below), high-quality data \ + compressor that is an alternative to the GNU zip compressor. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CFLAGS += -fPIC -D_FILE_OFFSET_BITS=64 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -i 's@(ln -s -f )$$(PREFIX)/bin/@\1@' Makefile + cd $(DIR_APP) && sed -e "s/$$(CC) -shared/& $(CFLAGS)/" -i Makefile-libbz2_so +endef + +define STAGE_BUILD + cd $(DIR_APP) && make -f Makefile-libbz2_so $(PARALLELISMFLAGS) + + cd $(DIR_APP) && make clean + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make PREFIX=$(BUILDROOT)/usr install + + -mkdir -pv $(BUILDROOT)/{bin,lib} + cd $(DIR_APP) && cp -v bzip2-shared $(BUILDROOT)/bin/bzip2 + cd $(DIR_APP) && cp -av libbz2.so* $(BUILDROOT)/lib + ln -sfv ../../lib/libbz2.so.1.0 $(BUILDROOT)/usr/lib/libbz2.so + rm -fv $(BUILDROOT)/usr/bin/{bunzip2,bzcat,bzip2} + ln -sfv bzip2 $(BUILDROOT)/bin/bunzip2 + ln -sfv bzip2 $(BUILDROOT)/bin/bzcat + rm -vf $(BUILDROOT)/usr/lib/libbz2.a + + -mkdir -pv $(BUIDLROOT)/usr/share + mv -vf $(BUILDROOT)/usr/man $(BUILDROOT)/usr/share/ +endef diff --git a/pkgs/core/bzip2/patches/bzip2-1.0.5-install_docs-1.patch b/pkgs/core/bzip2/patches/bzip2-1.0.5-install_docs-1.patch new file mode 100644 index 0000000..c3b0230 --- /dev/null +++ b/pkgs/core/bzip2/patches/bzip2-1.0.5-install_docs-1.patch @@ -0,0 +1,42 @@ +Submitted By: Matthew Burgess <matthew@linuxfromscratch.org> +Date: 2007-01-31 +Initial Package Version: 1.0.4 +Upstream Status: Not submitted +Origin: Randy McMurchy & Steve Crosby +Description: Installs pre-formatted documentation + +diff -Naur bzip2-1.0.4.orig/Makefile bzip2-1.0.4/Makefile +--- bzip2-1.0.4.orig/Makefile 2007-01-03 03:49:21.000000000 +0000 ++++ bzip2-1.0.4/Makefile 2007-01-26 20:00:01.000000000 +0000 +@@ -25,7 +25,7 @@ + + # Where you want it installed when you do 'make install' + PREFIX=/usr/local +- ++DOCDIR=share/doc/$(DISTNAME) + + OBJS= blocksort.o \ + huffman.o \ +@@ -74,6 +74,7 @@ + if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi + if ( test ! -d $(PREFIX)/man ) ; then mkdir -p $(PREFIX)/man ; fi + if ( test ! -d $(PREFIX)/man/man1 ) ; then mkdir -p $(PREFIX)/man/man1 ; fi ++ if ( test ! -d $(PREFIX)/$(DOCDIR) ) ; then mkdir -p $(PREFIX)/$(DOCDIR); fi + if ( test ! -d $(PREFIX)/include ) ; then mkdir -p $(PREFIX)/include ; fi + cp -f bzip2 $(PREFIX)/bin/bzip2 + cp -f bzip2 $(PREFIX)/bin/bunzip2 +@@ -107,6 +108,14 @@ + echo ".so man1/bzgrep.1" > $(PREFIX)/man/man1/bzfgrep.1 + echo ".so man1/bzmore.1" > $(PREFIX)/man/man1/bzless.1 + echo ".so man1/bzdiff.1" > $(PREFIX)/man/man1/bzcmp.1 ++ cp -f manual.html $(PREFIX)/$(DOCDIR) ++ cp -f manual.pdf $(PREFIX)/$(DOCDIR) ++ cp -f manual.ps $(PREFIX)/$(DOCDIR) ++ cp -f bzip2.txt $(PREFIX)/$(DOCDIR) ++ chmod a+r $(PREFIX)/$(DOCDIR)/manual.html ++ chmod a+r $(PREFIX)/$(DOCDIR)/manual.pdf ++ chmod a+r $(PREFIX)/$(DOCDIR)/manual.ps ++ chmod a+r $(PREFIX)/$(DOCDIR)/bzip2.txt + + clean: + rm -f *.o libbz2.a bzip2 bzip2recover \ diff --git a/pkgs/core/cairo/cairo.nm b/pkgs/core/cairo/cairo.nm new file mode 100644 index 0000000..473891e --- /dev/null +++ b/pkgs/core/cairo/cairo.nm @@ -0,0 +1,45 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = cairo +PKG_VER = 1.8.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Graphics +PKG_URL = http://cairographics.org +PKG_LICENSE = LGPLv2 MPLv1.1 +PKG_SUMMARY = A 2D graphics library. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += fontconfig freetype libpng pixman zlib + +define PKG_DESCRIPTION + Cairo is a 2D graphics library designed to provide high-quality display \ + and print output. +endef + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/ccache/ccache.nm b/pkgs/core/ccache/ccache.nm new file mode 100644 index 0000000..cce011b --- /dev/null +++ b/pkgs/core/ccache/ccache.nm @@ -0,0 +1,60 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = ccache +PKG_VER = 2.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Compilers +PKG_URL = http://ccache.samba.org/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = C/C++ compiler cache. + +define PKG_DESCRIPTION + ccache is a compiler cache. It acts as a caching pre-processor to \ + C/C++ compilers, using the -E compiler switch and a hash to detect \ + when a compilation can be satisfied from cache. This often results in \ + a 5 to 10 times speedup in common compilations. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --mandir=/usr/share + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + mkdir -pv $(BUILDROOT)/usr/ccache/bin + for i in gcc g++ cc c++; do \ + ln -svf ../../bin/ccache $(BUILDROOT)/usr/ccache/bin/$${i}; \ + ln -svf ../../bin/ccache $(BUILDROOT)/usr/ccache/bin/$(TARGET)-$${i}; \ + done +endef diff --git a/pkgs/core/ccache/patches/ccache-2.4.patch b/pkgs/core/ccache/patches/ccache-2.4.patch new file mode 100644 index 0000000..b2193c3 --- /dev/null +++ b/pkgs/core/ccache/patches/ccache-2.4.patch @@ -0,0 +1,12 @@ +--- a/ccache.c 2004-04-15 13:49:38.000000000 +0100 ++++ b/ccache.c 2004-04-15 17:47:59.000000000 +0100 +@@ -322,7 +322,9 @@ + failed(); + } + hash_int(st.st_size); ++#if 0 /* don't hash on the modification time */ + hash_int(st.st_mtime); ++#endif + + /* possibly hash the current working directory */ + if (getenv("CCACHE_HASHDIR")) { diff --git a/pkgs/core/coreutils/coreutils.nm b/pkgs/core/coreutils/coreutils.nm new file mode 100644 index 0000000..c4f3af5 --- /dev/null +++ b/pkgs/core/coreutils/coreutils.nm @@ -0,0 +1,78 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = coreutils +PKG_VER = 8.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://www.gnu.org/software/coreutils/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = A set of basic GNU tools commonly used in shell scripts. + +define PKG_DESCRIPTION + These are the GNU core utilities. This package is the combination of \ + the old GNU fileutils, sh-utils, and textutils packages. +endef + +PKG_BUILD_DEPS+= autoconf automake +PKG_DEPS += acl attr libcap ncurses pam shadow util-linux-ng + +PKG_TARBALL = $(THISAPP).tar.gz + +CFLAGS += -D_GNU_SOURCE=1 -fno-strict-aliasing + +CONFIGURE_OPTIONS += \ + --enable-pam \ + --enable-largefile \ + --enable-install-program=arch,hostname,su \ + --enable-no-install-program=kill,uptime + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && aclocal -I m4 + cd $(DIR_APP) && autoconf --force +endef + +# fails +#define STAGE_TEST +# cd $(DIR_APP) && make RUN_EXPENSIVE_TESTS=yes check +#endef + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/{bin,etc/profile.d,usr/sbin} + mv -v $(BUILDROOT)/usr/bin/{cat,chgrp,chmod,chown,cp,date,dd,df,echo} $(BUILDROOT)/bin + mv -v $(BUILDROOT)/usr/bin/{false,hostname,ln,ls,mkdir,mknod,mv,pwd,readlink,rm} $(BUILDROOT)/bin + mv -v $(BUILDROOT)/usr/bin/{rmdir,stty,sync,touch,true,uname} $(BUILDROOT)/bin + mv -v $(BUILDROOT)/usr/bin/chroot $(BUILDROOT)/usr/sbin + mv -v $(BUILDROOT)/usr/bin/{head,sleep,nice} $(BUILDROOT)/bin + + cd $(DIR_APP) && install -m 4755 src/su $(BUILDROOT)/bin + + # Dump /etc/dircolors. + dircolors -p > $(BUILDROOT)/etc/dircolors + cp -vf $(DIR_SOURCE)/profile.d/dircolors.sh $(BUILDROOT)/etc/profile.d +endef diff --git a/pkgs/core/coreutils/pam.d/su b/pkgs/core/coreutils/pam.d/su new file mode 100644 index 0000000..85e67a8 --- /dev/null +++ b/pkgs/core/coreutils/pam.d/su @@ -0,0 +1,12 @@ +#%PAM-1.0 +auth sufficient pam_rootok.so +# Uncomment the following line to implicitly trust users in the "wheel" group. +#auth sufficient pam_wheel.so trust use_uid +# Uncomment the following line to require a user to be in the "wheel" group. +#auth required pam_wheel.so use_uid +auth include system-auth +account sufficient pam_succeed_if.so uid = 0 use_uid quiet +account include system-auth +password include system-auth +session include system-auth +session optional pam_xauth.so diff --git a/pkgs/core/coreutils/pam.d/su-l b/pkgs/core/coreutils/pam.d/su-l new file mode 100644 index 0000000..656a139 --- /dev/null +++ b/pkgs/core/coreutils/pam.d/su-l @@ -0,0 +1,6 @@ +#%PAM-1.0 +auth include su +account include su +password include su +session optional pam_keyinit.so force revoke +session include su diff --git a/pkgs/core/coreutils/patches/coreutils-7.6-uname_PIC-1.patch.off b/pkgs/core/coreutils/patches/coreutils-7.6-uname_PIC-1.patch.off new file mode 100644 index 0000000..0ae413f --- /dev/null +++ b/pkgs/core/coreutils/patches/coreutils-7.6-uname_PIC-1.patch.off @@ -0,0 +1,204 @@ +Submitted By: Robert Connolly <robert@linuxfromscratch.org> (ashes) +Date: 2005-11-13 +Initial Package Version: 5.93 +Upstream Status: pending +Origin: Scot McPherson and Zack Winkles +Description: Fix the output of uname once and for all. This is the position independent +version. + + $ uname -m # This always worked. + i686 + $ uname -i # Used to report 'unknown'. + i386 + $ uname -p # Likewise. + athlon-4 + +Now 'uname -p' can be used by GCC's mtune/mcpu and march options. For example: + + CFLAGS="-march=$(uname -m) -mtune=$(uname -p)" + +diff -Naur coreutils-5.93.orig/src/uname.c coreutils-5.93/src/uname.c +--- coreutils-5.93.orig/src/uname.c 2005-09-15 19:57:04.000000000 +0000 ++++ coreutils-5.93/src/uname.c 2005-11-13 19:18:35.000000000 +0000 +@@ -29,6 +29,26 @@ + # include <sys/systeminfo.h> + #endif + ++#ifdef linux ++/* Thanks to the ffmpeg team for this PIC version of cpuid() */ ++#ifdef ARCH_X86_64 ++# define REG_b "rbx" ++# define REG_S "rsi" ++#else ++# define REG_b "ebx" ++# define REG_S "esi" ++#endif ++#define cpuid(index,eax,ebx,ecx,edx)\ ++ __asm __volatile\ ++ ("mov %%"REG_b", %%"REG_S"\n\t"\ ++ "cpuid\n\t"\ ++ "xchg %%"REG_b", %%"REG_S\ ++ : "=a" (eax), "=S" (ebx),\ ++ "=c" (ecx), "=d" (edx)\ ++ : "0" (index)); ++int has_sse( void ); ++#endif ++ + #if HAVE_SYS_SYSCTL_H + # if HAVE_SYS_PARAM_H + # include <sys/param.h> /* needed for OpenBSD 3.0 */ +@@ -256,6 +276,99 @@ + if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) + element = processor; + } ++#else ++ { ++ struct utsname u; ++ uname (&u); ++ element = u.machine; ++#ifdef linux ++/****************************************************************************** ++ * ++ * Hello, major hack. I shouldn't have to do this. struct utsname should ++ * have another element with this info in it. There's probably a struct ++ * somewhere that has this info, I just don't know where it is. ++ * ++ *****************************************************************************/ ++ ++ if( !strcmp( element, "i586" ) || !strcmp( element, "i686" ) ) { ++ int eax, ebx, ecx, edx, unused; ++ int model, family, sse; ++ ++ cpuid(0,unused,ebx,ecx,edx); ++ cpuid(1,eax,unused,unused,unused); ++ model = (eax >> 4) & 0xf; ++ family = (eax >> 8) & 0xf; ++ ++ switch(ebx) { ++ case 0x756e6547: // Intel ++ switch( family ) { ++ case 5: // Pentium ++ if( model <= 3 ) ++ element="pentium"; ++ if( model > 3 ) ++ element="pentium-mmx"; ++ break; ++ case 6: // PentiumPro - Pentium III ++ if( model == 1 ) // Pentium Pro ++ element="pentiumpro"; ++ if( ( model == 3 ) || ( model == 5 ) || ++ ( model == 6 ) ) // Pentium II ++ element="pentium2"; ++ if( ( model == 7 ) || ( model == 8 ) || ++ ( model == 10 ) || ( model == 11 ) ) // These are all Pentium III ++ element="pentium3"; ++ break; ++ case 15: // Pentium4 ++ if( model == 3 ) // Prescott ++ element="prescott"; ++ else ++ element="pentium4"; ++ break; ++ default: ++ break; ++ } // end switch( family ) ++ break; ++ case 0x68747541: // AMD ++ switch(family) { ++ case 5: ++ if( ( model == 0 ) || ( model == 1 ) || ++ ( model == 2 ) || ( model == 3 ) ) // K5 ++ element="i586"; ++ if( ( model == 6 ) || ( model == 7 ) ) // K6 ++ element="k6"; ++ if( model == 8 ) // K6-2 ++ element="k6-2"; ++ if( model == 9 ) // K6-3 ++ element="k6-3"; ++ break; ++ case 6: ++ if( model <= 4 ) ++ element="athlon"; ++ if( model > 4 ) { ++ sse = has_sse(); ++ if( sse == 0 ) ++ element="athlon"; ++ if( sse == 1 ) ++ element="athlon-4"; ++ } ++ break; ++ case 15: ++ element="athlon-4"; ++ break; ++ default: ++ break; ++ } // end switch( family ) ++ break; ++ case 0x69727943: // Cyrix ++ element="i386"; // who knows what cyrix supports, lets be safe ++ break; ++ default: ++ break; ++ } // end switch(ebx) ++ } ++ ++#endif ++ } + #endif + #ifdef UNAME_PROCESSOR + if (element == unknown) +@@ -293,7 +406,7 @@ + + if (toprint & PRINT_HARDWARE_PLATFORM) + { +- char const *element = unknown; ++ char *element = unknown; + #if HAVE_SYSINFO && defined SI_PLATFORM + { + static char hardware_platform[257]; +@@ -301,6 +414,15 @@ + hardware_platform, sizeof hardware_platform)) + element = hardware_platform; + } ++#else ++ { ++ struct utsname u; ++ uname (&u); ++ element = u.machine; ++ if (strlen (element) == 4 && element[0] == 'i' && element[2] == '8' ++ && element[3] == '6') ++ element[1] = '3'; ++ } + #endif + #ifdef UNAME_HARDWARE_PLATFORM + if (element == unknown) +@@ -323,3 +445,29 @@ + + exit (EXIT_SUCCESS); + } ++ ++#ifdef linux ++ ++/****************************************************************************** ++ * ++ * int has_sse( void ) ++ * Checks Athlon CPU's to see if they support SSE. ++ * ++ *****************************************************************************/ ++ ++int has_sse( void ) ++{ ++ unsigned long edx, unused; ++ int sse; ++ cpuid(1,unused,unused,unused,edx); ++ // I think, I need this tested on a Duron with SSE ++ // and one without it. ++ sse = edx & 0x2000000; ++ if( sse == 0 ) { ++ return 0; ++ } else { ++ return 1; ++ } ++ ++} ++#endif diff --git a/pkgs/core/coreutils/patches/coreutils-8.4-i18n.patch b/pkgs/core/coreutils/patches/coreutils-8.4-i18n.patch new file mode 100644 index 0000000..a8faefe --- /dev/null +++ b/pkgs/core/coreutils/patches/coreutils-8.4-i18n.patch @@ -0,0 +1,4044 @@ +diff -urNp coreutils-8.0-orig/lib/linebuffer.h coreutils-8.0/lib/linebuffer.h +--- coreutils-8.0-orig/lib/linebuffer.h 2009-10-06 10:59:48.000000000 +0200 ++++ coreutils-8.0/lib/linebuffer.h 2009-10-07 10:07:16.000000000 +0200 +@@ -21,6 +21,11 @@ + + # include <stdio.h> + ++/* Get mbstate_t. */ ++# if HAVE_WCHAR_H ++# include <wchar.h> ++# endif ++ + /* A `struct linebuffer' holds a line of text. */ + + struct linebuffer +@@ -28,6 +33,9 @@ struct linebuffer + size_t size; /* Allocated. */ + size_t length; /* Used. */ + char *buffer; ++# if HAVE_WCHAR_H ++ mbstate_t state; ++# endif + }; + + /* Initialize linebuffer LINEBUFFER for use. */ +diff -urNp coreutils-8.0-orig/src/cut.c coreutils-8.0/src/cut.c +--- coreutils-8.0-orig/src/cut.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/cut.c 2009-10-07 10:07:16.000000000 +0200 +@@ -28,6 +28,11 @@ + #include <assert.h> + #include <getopt.h> + #include <sys/types.h> ++ ++/* Get mbstate_t, mbrtowc(). */ ++#if HAVE_WCHAR_H ++# include <wchar.h> ++#endif + #include "system.h" + + #include "error.h" +@@ -36,6 +41,18 @@ + #include "quote.h" + #include "xstrndup.h" + ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC ++ installation; work around this configuration error. */ ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 ++# undef MB_LEN_MAX ++# define MB_LEN_MAX 16 ++#endif ++ ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ ++#if HAVE_MBRTOWC && defined mbstate_t ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) ++#endif ++ + /* The official name of this program (e.g., no `g' prefix). */ + #define PROGRAM_NAME "cut" + +@@ -71,6 +88,52 @@ + } \ + while (0) + ++/* Refill the buffer BUF to get a multibyte character. */ ++#define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ ++ do \ ++ { \ ++ if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ ++ { \ ++ memmove (BUF, BUFPOS, BUFLEN); \ ++ BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ ++ BUFPOS = BUF; \ ++ } \ ++ } \ ++ while (0) ++ ++/* Get wide character on BUFPOS. BUFPOS is not included after that. ++ If byte sequence is not valid as a character, CONVFAIL is 1. Otherwise 0. */ ++#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ ++ do \ ++ { \ ++ mbstate_t state_bak; \ ++ \ ++ if (BUFLEN < 1) \ ++ { \ ++ WC = WEOF; \ ++ break; \ ++ } \ ++ \ ++ /* Get a wide character. */ \ ++ CONVFAIL = 0; \ ++ state_bak = STATE; \ ++ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ ++ \ ++ switch (MBLENGTH) \ ++ { \ ++ case (size_t)-1: \ ++ case (size_t)-2: \ ++ CONVFAIL++; \ ++ STATE = state_bak; \ ++ /* Fall througn. */ \ ++ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ break; \ ++ } \ ++ } \ ++ while (0) ++ + struct range_pair + { + size_t lo; +@@ -89,7 +152,7 @@ static char *field_1_buffer; + /* The number of bytes allocated for FIELD_1_BUFFER. */ + static size_t field_1_bufsize; + +-/* The largest field or byte index used as an endpoint of a closed ++/* The largest byte, character or field index used as an endpoint of a closed + or degenerate range specification; this doesn't include the starting + index of right-open-ended ranges. For example, with either range spec + `2-5,9-', `2-3,5,9-' this variable would be set to 5. */ +@@ -101,10 +164,11 @@ static size_t eol_range_start; + + /* This is a bit vector. + In byte mode, which bytes to output. ++ In character mode, which characters to output. + In field mode, which DELIM-separated fields to output. +- Both bytes and fields are numbered starting with 1, ++ Bytes, characters and fields are numbered starting with 1, + so the zeroth bit of this array is unused. +- A field or byte K has been selected if ++ A byte, character or field K has been selected if + (K <= MAX_RANGE_ENDPOINT and is_printable_field(K)) + || (EOL_RANGE_START > 0 && K >= EOL_RANGE_START). */ + static unsigned char *printable_field; +@@ -113,15 +177,25 @@ enum operating_mode + { + undefined_mode, + +- /* Output characters that are in the given bytes. */ ++ /* Output bytes that are at the given positions. */ + byte_mode, + ++ /* Output characters that are at the given positions. */ ++ character_mode, ++ + /* Output the given delimeter-separated fields. */ + field_mode + }; + + static enum operating_mode operating_mode; + ++/* If nonzero, when in byte mode, don't split multibyte characters. */ ++static int byte_mode_character_aware; ++ ++/* If nonzero, the function for single byte locale is work ++ if this program runs on multibyte locale. */ ++static int force_singlebyte_mode; ++ + /* If true do not output lines containing no delimeter characters. + Otherwise, all such lines are printed. This option is valid only + with field mode. */ +@@ -133,6 +207,9 @@ static bool complement; + + /* The delimeter character for field mode. */ + static unsigned char delim; ++#if HAVE_WCHAR_H ++static wchar_t wcdelim; ++#endif + + /* True if the --output-delimiter=STRING option was specified. */ + static bool output_delimiter_specified; +@@ -206,7 +283,7 @@ Mandatory arguments to long options are + -f, --fields=LIST select only these fields; also print any line\n\ + that contains no delimiter character, unless\n\ + the -s option is specified\n\ +- -n (ignored)\n\ ++ -n with -b: don't split multibyte characters\n\ + "), stdout); + fputs (_("\ + --complement complement the set of selected bytes, characters\n\ +@@ -365,7 +442,7 @@ set_fields (const char *fieldstr) + in_digits = false; + /* Starting a range. */ + if (dash_found) +- FATAL_ERROR (_("invalid byte or field list")); ++ FATAL_ERROR (_("invalid byte, character or field list")); + dash_found = true; + fieldstr++; + +@@ -389,14 +466,16 @@ set_fields (const char *fieldstr) + if (!rhs_specified) + { + /* `n-'. From `initial' to end of line. */ +- eol_range_start = initial; ++ if (eol_range_start == 0 || ++ (eol_range_start != 0 && eol_range_start > initial)) ++ eol_range_start = initial; + field_found = true; + } + else + { + /* `m-n' or `-n' (1-n). */ + if (value < initial) +- FATAL_ERROR (_("invalid decreasing range")); ++ FATAL_ERROR (_("invalid byte, character or field list")); + + /* Is there already a range going to end of line? */ + if (eol_range_start != 0) +@@ -476,6 +555,9 @@ set_fields (const char *fieldstr) + if (operating_mode == byte_mode) + error (0, 0, + _("byte offset %s is too large"), quote (bad_num)); ++ else if (operating_mode == character_mode) ++ error (0, 0, ++ _("character offset %s is too large"), quote (bad_num)); + else + error (0, 0, + _("field number %s is too large"), quote (bad_num)); +@@ -486,7 +568,7 @@ set_fields (const char *fieldstr) + fieldstr++; + } + else +- FATAL_ERROR (_("invalid byte or field list")); ++ FATAL_ERROR (_("invalid byte, character or field list")); + } + + max_range_endpoint = 0; +@@ -579,6 +661,63 @@ cut_bytes (FILE *stream) + } + } + ++#if HAVE_MBRTOWC ++/* This function is in use for the following case. ++ ++ 1. Read from the stream STREAM, printing to standard output any selected ++ characters. ++ ++ 2. Read from stream STREAM, printing to standard output any selected bytes, ++ without splitting multibyte characters. */ ++ ++static void ++cut_characters_or_cut_bytes_no_split (FILE *stream) ++{ ++ int idx; /* number of bytes or characters in the line so far. */ ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen; /* The length of the byte sequence in buf. */ ++ wint_t wc; /* A gotten wide character. */ ++ size_t mblength; /* The byte size of a multibyte character which shows ++ as same character as WC. */ ++ mbstate_t state; /* State of the stream. */ ++ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ ++ idx = 0; ++ buflen = 0; ++ bufpos = buf; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); ++ ++ if (wc == WEOF) ++ { ++ if (idx > 0) ++ putchar ('\n'); ++ break; ++ } ++ else if (wc == L'\n') ++ { ++ putchar ('\n'); ++ idx = 0; ++ } ++ else ++ { ++ idx += (operating_mode == byte_mode) ? mblength : 1; ++ if (print_kth (idx, NULL)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ } ++ ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++} ++#endif ++ + /* Read from stream STREAM, printing to standard output any selected fields. */ + + static void +@@ -701,13 +840,192 @@ cut_fields (FILE *stream) + } + } + ++#if HAVE_MBRTOWC ++static void ++cut_fields_mb (FILE *stream) ++{ ++ int c; ++ unsigned int field_idx; ++ int found_any_selected_field; ++ int buffer_first_field; ++ int empty_input; ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen; /* The length of the byte sequence in buf. */ ++ wint_t wc = 0; /* A gotten wide character. */ ++ size_t mblength; /* The byte size of a multibyte character which shows ++ as same character as WC. */ ++ mbstate_t state; /* State of the stream. */ ++ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ ++ found_any_selected_field = 0; ++ field_idx = 1; ++ bufpos = buf; ++ buflen = 0; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ c = getc (stream); ++ empty_input = (c == EOF); ++ if (c != EOF) ++ ungetc (c, stream); ++ else ++ wc = WEOF; ++ ++ /* To support the semantics of the -s flag, we may have to buffer ++ all of the first field to determine whether it is `delimited.' ++ But that is unnecessary if all non-delimited lines must be printed ++ and the first field has been selected, or if non-delimited lines ++ must be suppressed and the first field has *not* been selected. ++ That is because a non-delimited line has exactly one field. */ ++ buffer_first_field = (suppress_non_delimited ^ !print_kth (1, NULL)); ++ ++ while (1) ++ { ++ if (field_idx == 1 && buffer_first_field) ++ { ++ int len = 0; ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); ++ ++ if (wc == WEOF) ++ break; ++ ++ field_1_buffer = xrealloc (field_1_buffer, len + mblength); ++ memcpy (field_1_buffer + len, bufpos, mblength); ++ len += mblength; ++ buflen -= mblength; ++ bufpos += mblength; ++ ++ if (!convfail && (wc == L'\n' || wc == wcdelim)) ++ break; ++ } ++ ++ if (wc == WEOF) ++ break; ++ ++ /* If the first field extends to the end of line (it is not ++ delimited) and we are printing all non-delimited lines, ++ print this one. */ ++ if (convfail || (!convfail && wc != wcdelim)) ++ { ++ if (suppress_non_delimited) ++ { ++ /* Empty. */ ++ } ++ else ++ { ++ fwrite (field_1_buffer, sizeof (char), len, stdout); ++ /* Make sure the output line is newline terminated. */ ++ if (convfail || (!convfail && wc != L'\n')) ++ putchar ('\n'); ++ } ++ continue; ++ } ++ ++ if (print_kth (1, NULL)) ++ { ++ /* Print the field, but not the trailing delimiter. */ ++ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); ++ found_any_selected_field = 1; ++ } ++ ++field_idx; ++ } ++ ++ if (wc != WEOF) ++ { ++ if (print_kth (field_idx, NULL)) ++ { ++ if (found_any_selected_field) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ found_any_selected_field = 1; ++ } ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); ++ ++ if (wc == WEOF) ++ break; ++ else if (!convfail && (wc == wcdelim || wc == L'\n')) ++ { ++ buflen -= mblength; ++ bufpos += mblength; ++ break; ++ } ++ ++ if (print_kth (field_idx, NULL)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++ } ++ ++ if ((!convfail || wc == L'\n') && buflen < 1) ++ wc = WEOF; ++ ++ if (!convfail && wc == wcdelim) ++ ++field_idx; ++ else if (wc == WEOF || (!convfail && wc == L'\n')) ++ { ++ if (found_any_selected_field ++ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) ++ putchar ('\n'); ++ if (wc == WEOF) ++ break; ++ field_idx = 1; ++ found_any_selected_field = 0; ++ } ++ } ++} ++#endif ++ + static void + cut_stream (FILE *stream) + { +- if (operating_mode == byte_mode) +- cut_bytes (stream); ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) ++ { ++ switch (operating_mode) ++ { ++ case byte_mode: ++ if (byte_mode_character_aware) ++ cut_characters_or_cut_bytes_no_split (stream); ++ else ++ cut_bytes (stream); ++ break; ++ ++ case character_mode: ++ cut_characters_or_cut_bytes_no_split (stream); ++ break; ++ ++ case field_mode: ++ cut_fields_mb (stream); ++ break; ++ ++ default: ++ abort (); ++ } ++ } + else +- cut_fields (stream); ++#endif ++ { ++ if (operating_mode == field_mode) ++ cut_fields (stream); ++ else ++ cut_bytes (stream); ++ } + } + + /* Process file FILE to standard output. +@@ -757,6 +1075,8 @@ main (int argc, char **argv) + bool ok; + bool delim_specified = false; + char *spec_list_string IF_LINT(= NULL); ++ char mbdelim[MB_LEN_MAX + 1]; ++ size_t delimlen = 0; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -779,7 +1099,6 @@ main (int argc, char **argv) + switch (optc) + { + case 'b': +- case 'c': + /* Build the byte list. */ + if (operating_mode != undefined_mode) + FATAL_ERROR (_("only one type of list may be specified")); +@@ -787,6 +1106,14 @@ main (int argc, char **argv) + spec_list_string = optarg; + break; + ++ case 'c': ++ /* Build the character list. */ ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = character_mode; ++ spec_list_string = optarg; ++ break; ++ + case 'f': + /* Build the field list. */ + if (operating_mode != undefined_mode) +@@ -798,10 +1125,35 @@ main (int argc, char **argv) + case 'd': + /* New delimiter. */ + /* Interpret -d '' to mean `use the NUL byte as the delimiter.' */ +- if (optarg[0] != '\0' && optarg[1] != '\0') +- FATAL_ERROR (_("the delimiter must be a single character")); +- delim = optarg[0]; +- delim_specified = true; ++ { ++#if HAVE_MBRTOWC ++ if(MB_CUR_MAX > 1) ++ { ++ mbstate_t state; ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); ++ ++ if (delimlen == (size_t)-1 || delimlen == (size_t)-2) ++ ++force_singlebyte_mode; ++ else ++ { ++ delimlen = (delimlen < 1) ? 1 : delimlen; ++ if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') ++ FATAL_ERROR (_("the delimiter must be a single character")); ++ memcpy (mbdelim, optarg, delimlen); ++ } ++ } ++ ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) ++#endif ++ { ++ if (optarg[0] != '\0' && optarg[1] != '\0') ++ FATAL_ERROR (_("the delimiter must be a single character")); ++ delim = (unsigned char) optarg[0]; ++ } ++ delim_specified = true; ++ } + break; + + case OUTPUT_DELIMITER_OPTION: +@@ -814,6 +1166,7 @@ main (int argc, char **argv) + break; + + case 'n': ++ byte_mode_character_aware = 1; + break; + + case 's': +@@ -836,7 +1189,7 @@ main (int argc, char **argv) + if (operating_mode == undefined_mode) + FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); + +- if (delim != '\0' && operating_mode != field_mode) ++ if (delim_specified && operating_mode != field_mode) + FATAL_ERROR (_("an input delimiter may be specified only\ + when operating on fields")); + +@@ -863,15 +1216,34 @@ main (int argc, char **argv) + } + + if (!delim_specified) +- delim = '\t'; ++ { ++ delim = '\t'; ++#ifdef HAVE_MBRTOWC ++ wcdelim = L'\t'; ++ mbdelim[0] = '\t'; ++ mbdelim[1] = '\0'; ++ delimlen = 1; ++#endif ++ } + + if (output_delimiter_string == NULL) + { +- static char dummy[2]; +- dummy[0] = delim; +- dummy[1] = '\0'; +- output_delimiter_string = dummy; +- output_delimiter_length = 1; ++#ifdef HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1 && !force_singlebyte_mode) ++ { ++ output_delimiter_string = xstrdup(mbdelim); ++ output_delimiter_length = delimlen; ++ } ++ ++ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) ++#endif ++ { ++ static char dummy[2]; ++ dummy[0] = delim; ++ dummy[1] = '\0'; ++ output_delimiter_string = dummy; ++ output_delimiter_length = 1; ++ } + } + + if (optind == argc) +diff -urNp coreutils-8.0-orig/src/expand.c coreutils-8.0/src/expand.c +--- coreutils-8.0-orig/src/expand.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/expand.c 2009-10-07 10:07:16.000000000 +0200 +@@ -37,11 +37,28 @@ + #include <stdio.h> + #include <getopt.h> + #include <sys/types.h> ++ ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ ++#if HAVE_WCHAR_H ++# include <wchar.h> ++#endif ++ + #include "system.h" + #include "error.h" + #include "quote.h" + #include "xstrndup.h" + ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC ++ installation; work around this configuration error. */ ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 ++# define MB_LEN_MAX 16 ++#endif ++ ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ ++#if HAVE_MBRTOWC && defined mbstate_t ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) ++#endif ++ + /* The official name of this program (e.g., no `g' prefix). */ + #define PROGRAM_NAME "expand" + +@@ -357,6 +374,142 @@ expand (void) + } + } + ++#if HAVE_MBRTOWC ++static void ++expand_multibyte (void) ++{ ++ FILE *fp; /* Input strem. */ ++ mbstate_t i_state; /* Current shift state of the input stream. */ ++ mbstate_t i_state_bak; /* Back up the I_STATE. */ ++ mbstate_t o_state; /* Current shift state of the output stream. */ ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ ++ wchar_t wc; /* A gotten wide character. */ ++ size_t mblength; /* The byte size of a multibyte character ++ which shows as same character as WC. */ ++ int tab_index = 0; /* Index in `tab_list' of next tabstop. */ ++ int column = 0; /* Column on screen of the next char. */ ++ int next_tab_column; /* Column the next tab stop is on. */ ++ int convert = 1; /* If nonzero, perform translations. */ ++ ++ fp = next_file ((FILE *) NULL); ++ if (fp == NULL) ++ return; ++ ++ memset (&o_state, '\0', sizeof(mbstate_t)); ++ memset (&i_state, '\0', sizeof(mbstate_t)); ++ ++ for (;;) ++ { ++ /* Refill the buffer BUF. */ ++ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) ++ { ++ memmove (buf, bufpos, buflen); ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); ++ bufpos = buf; ++ } ++ ++ /* No character is left in BUF. */ ++ if (buflen < 1) ++ { ++ fp = next_file (fp); ++ ++ if (fp == NULL) ++ break; /* No more files. */ ++ else ++ { ++ memset (&i_state, '\0', sizeof(mbstate_t)); ++ continue; ++ } ++ } ++ ++ /* Get a wide character. */ ++ i_state_bak = i_state; ++ mblength = mbrtowc (&wc, bufpos, buflen, &i_state); ++ ++ switch (mblength) ++ { ++ case (size_t)-1: /* illegal byte sequence. */ ++ case (size_t)-2: ++ mblength = 1; ++ i_state = i_state_bak; ++ if (convert) ++ { ++ ++column; ++ if (convert_entire_line == 0) ++ convert = 0; ++ } ++ putchar (*bufpos); ++ break; ++ ++ case 0: /* null. */ ++ mblength = 1; ++ if (convert && convert_entire_line == 0) ++ convert = 0; ++ putchar ('\0'); ++ break; ++ ++ default: ++ if (wc == L'\n') /* LF. */ ++ { ++ tab_index = 0; ++ column = 0; ++ convert = 1; ++ putchar ('\n'); ++ } ++ else if (wc == L'\t' && convert) /* Tab. */ ++ { ++ if (tab_size == 0) ++ { ++ /* Do not let tab_index == first_free_tab; ++ stop when it is 1 less. */ ++ while (tab_index < first_free_tab - 1 ++ && column >= tab_list[tab_index]) ++ tab_index++; ++ next_tab_column = tab_list[tab_index]; ++ if (tab_index < first_free_tab - 1) ++ tab_index++; ++ if (column >= next_tab_column) ++ next_tab_column = column + 1; ++ } ++ else ++ next_tab_column = column + tab_size - column % tab_size; ++ ++ while (column < next_tab_column) ++ { ++ putchar (' '); ++ ++column; ++ } ++ } ++ else /* Others. */ ++ { ++ if (convert) ++ { ++ if (wc == L'\b') ++ { ++ if (column > 0) ++ --column; ++ } ++ else ++ { ++ int width; /* The width of WC. */ ++ ++ width = wcwidth (wc); ++ column += (width > 0) ? width : 0; ++ if (convert_entire_line == 0) ++ convert = 0; ++ } ++ } ++ fwrite (bufpos, sizeof(char), mblength, stdout); ++ } ++ } ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++} ++#endif ++ + int + main (int argc, char **argv) + { +@@ -421,7 +574,12 @@ main (int argc, char **argv) + + file_list = (optind < argc ? &argv[optind] : stdin_argv); + +- expand (); ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ expand_multibyte (); ++ else ++#endif ++ expand (); + + if (have_read_stdin && fclose (stdin) != 0) + error (EXIT_FAILURE, errno, "-"); +diff -urNp coreutils-8.0-orig/src/fold.c coreutils-8.0/src/fold.c +--- coreutils-8.0-orig/src/fold.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/fold.c 2009-10-07 10:07:16.000000000 +0200 +@@ -22,11 +22,33 @@ + #include <getopt.h> + #include <sys/types.h> + ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ ++#if HAVE_WCHAR_H ++# include <wchar.h> ++#endif ++ ++/* Get iswprint(), iswblank(), wcwidth(). */ ++#if HAVE_WCTYPE_H ++# include <wctype.h> ++#endif ++ + #include "system.h" + #include "error.h" + #include "quote.h" + #include "xstrtol.h" + ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC ++ installation; work around this configuration error. */ ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 ++# undef MB_LEN_MAX ++# define MB_LEN_MAX 16 ++#endif ++ ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ ++#if HAVE_MBRTOWC && defined mbstate_t ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) ++#endif ++ + #define TAB_WIDTH 8 + + /* The official name of this program (e.g., no `g' prefix). */ +@@ -34,20 +56,41 @@ + + #define AUTHORS proper_name ("David MacKenzie") + ++#define FATAL_ERROR(Message) \ ++ do \ ++ { \ ++ error (0, 0, (Message)); \ ++ usage (2); \ ++ } \ ++ while (0) ++ ++enum operating_mode ++{ ++ /* Fold texts by columns that are at the given positions. */ ++ column_mode, ++ ++ /* Fold texts by bytes that are at the given positions. */ ++ byte_mode, ++ ++ /* Fold texts by characters that are at the given positions. */ ++ character_mode, ++}; ++ ++/* The argument shows current mode. (Default: column_mode) */ ++static enum operating_mode operating_mode; ++ + /* If nonzero, try to break on whitespace. */ + static bool break_spaces; + +-/* If nonzero, count bytes, not column positions. */ +-static bool count_bytes; +- + /* If nonzero, at least one of the files we read was standard input. */ + static bool have_read_stdin; + +-static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::"; ++static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; + + static struct option const longopts[] = + { + {"bytes", no_argument, NULL, 'b'}, ++ {"characters", no_argument, NULL, 'c'}, + {"spaces", no_argument, NULL, 's'}, + {"width", required_argument, NULL, 'w'}, + {GETOPT_HELP_OPTION_DECL}, +@@ -77,6 +120,7 @@ Mandatory arguments to long options are + "), stdout); + fputs (_("\ + -b, --bytes count bytes rather than columns\n\ ++ -c, --characters count characters rather than columns\n\ + -s, --spaces break at spaces\n\ + -w, --width=WIDTH use WIDTH columns instead of 80\n\ + "), stdout); +@@ -94,7 +138,7 @@ Mandatory arguments to long options are + static size_t + adjust_column (size_t column, char c) + { +- if (!count_bytes) ++ if (operating_mode != byte_mode) + { + if (c == '\b') + { +@@ -117,30 +161,14 @@ adjust_column (size_t column, char c) + to stdout, with maximum line length WIDTH. + Return true if successful. */ + +-static bool +-fold_file (char const *filename, size_t width) ++static void ++fold_text (FILE *istream, size_t width, int *saved_errno) + { +- FILE *istream; + int c; + size_t column = 0; /* Screen column where next char will go. */ + size_t offset_out = 0; /* Index in `line_out' for next char. */ + static char *line_out = NULL; + static size_t allocated_out = 0; +- int saved_errno; +- +- if (STREQ (filename, "-")) +- { +- istream = stdin; +- have_read_stdin = true; +- } +- else +- istream = fopen (filename, "r"); +- +- if (istream == NULL) +- { +- error (0, errno, "%s", filename); +- return false; +- } + + while ((c = getc (istream)) != EOF) + { +@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t + bool found_blank = false; + size_t logical_end = offset_out; + ++ /* If LINE_OUT has no wide character, ++ put a new wide character in LINE_OUT ++ if column is bigger than width. */ ++ if (offset_out == 0) ++ { ++ line_out[offset_out++] = c; ++ continue; ++ } ++ + /* Look for the last blank. */ + while (logical_end) + { +@@ -214,11 +251,222 @@ fold_file (char const *filename, size_t + line_out[offset_out++] = c; + } + +- saved_errno = errno; ++ *saved_errno = errno; + + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + ++} ++ ++#if HAVE_MBRTOWC ++static void ++fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) ++{ ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ ++ char *bufpos = NULL; /* Next read position of BUF. */ ++ wint_t wc; /* A gotten wide character. */ ++ size_t mblength; /* The byte size of a multibyte character which shows ++ as same character as WC. */ ++ mbstate_t state, state_bak; /* State of the stream. */ ++ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ ++ static char *line_out = NULL; ++ size_t offset_out = 0; /* Index in `line_out' for next char. */ ++ static size_t allocated_out = 0; ++ ++ int increment; ++ size_t column = 0; ++ ++ size_t last_blank_pos; ++ size_t last_blank_column; ++ int is_blank_seen; ++ int last_blank_increment = 0; ++ int is_bs_following_last_blank; ++ size_t bs_following_last_blank_num; ++ int is_cr_after_last_blank; ++ ++#define CLEAR_FLAGS \ ++ do \ ++ { \ ++ last_blank_pos = 0; \ ++ last_blank_column = 0; \ ++ is_blank_seen = 0; \ ++ is_bs_following_last_blank = 0; \ ++ bs_following_last_blank_num = 0; \ ++ is_cr_after_last_blank = 0; \ ++ } \ ++ while (0) ++ ++#define START_NEW_LINE \ ++ do \ ++ { \ ++ putchar ('\n'); \ ++ column = 0; \ ++ offset_out = 0; \ ++ CLEAR_FLAGS; \ ++ } \ ++ while (0) ++ ++ CLEAR_FLAGS; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ for (;; bufpos += mblength, buflen -= mblength) ++ { ++ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) ++ { ++ memmove (buf, bufpos, buflen); ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); ++ bufpos = buf; ++ } ++ ++ if (buflen < 1) ++ break; ++ ++ /* Get a wide character. */ ++ convfail = 0; ++ state_bak = state; ++ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); ++ ++ switch (mblength) ++ { ++ case (size_t)-1: ++ case (size_t)-2: ++ convfail++; ++ state = state_bak; ++ /* Fall through. */ ++ ++ case 0: ++ mblength = 1; ++ break; ++ } ++ ++rescan: ++ if (operating_mode == byte_mode) /* byte mode */ ++ increment = mblength; ++ else if (operating_mode == character_mode) /* character mode */ ++ increment = 1; ++ else /* column mode */ ++ { ++ if (convfail) ++ increment = 1; ++ else ++ { ++ switch (wc) ++ { ++ case L'\n': ++ fwrite (line_out, sizeof(char), offset_out, stdout); ++ START_NEW_LINE; ++ continue; ++ ++ case L'\b': ++ increment = (column > 0) ? -1 : 0; ++ break; ++ ++ case L'\r': ++ increment = -1 * column; ++ break; ++ ++ case L'\t': ++ increment = 8 - column % 8; ++ break; ++ ++ default: ++ increment = wcwidth (wc); ++ increment = (increment < 0) ? 0 : increment; ++ } ++ } ++ } ++ ++ if (column + increment > width && break_spaces && last_blank_pos) ++ { ++ fwrite (line_out, sizeof(char), last_blank_pos, stdout); ++ putchar ('\n'); ++ ++ offset_out = offset_out - last_blank_pos; ++ column = column - last_blank_column + ((is_cr_after_last_blank) ++ ? last_blank_increment : bs_following_last_blank_num); ++ memmove (line_out, line_out + last_blank_pos, offset_out); ++ CLEAR_FLAGS; ++ goto rescan; ++ } ++ ++ if (column + increment > width && column != 0) ++ { ++ fwrite (line_out, sizeof(char), offset_out, stdout); ++ START_NEW_LINE; ++ goto rescan; ++ } ++ ++ if (allocated_out < offset_out + mblength) ++ { ++ line_out = X2REALLOC (line_out, &allocated_out); ++ } ++ ++ memcpy (line_out + offset_out, bufpos, mblength); ++ offset_out += mblength; ++ column += increment; ++ ++ if (is_blank_seen && !convfail && wc == L'\r') ++ is_cr_after_last_blank = 1; ++ ++ if (is_bs_following_last_blank && !convfail && wc == L'\b') ++ ++bs_following_last_blank_num; ++ else ++ is_bs_following_last_blank = 0; ++ ++ if (break_spaces && !convfail && iswblank (wc)) ++ { ++ last_blank_pos = offset_out; ++ last_blank_column = column; ++ is_blank_seen = 1; ++ last_blank_increment = increment; ++ is_bs_following_last_blank = 1; ++ bs_following_last_blank_num = 0; ++ is_cr_after_last_blank = 0; ++ } ++ } ++ ++ *saved_errno = errno; ++ ++ if (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ ++} ++#endif ++ ++/* Fold file FILENAME, or standard input if FILENAME is "-", ++ to stdout, with maximum line length WIDTH. ++ Return 0 if successful, 1 if an error occurs. */ ++ ++static bool ++fold_file (char *filename, size_t width) ++{ ++ FILE *istream; ++ int saved_errno; ++ ++ if (STREQ (filename, "-")) ++ { ++ istream = stdin; ++ have_read_stdin = 1; ++ } ++ else ++ istream = fopen (filename, "r"); ++ ++ if (istream == NULL) ++ { ++ error (0, errno, "%s", filename); ++ return 1; ++ } ++ ++ /* Define how ISTREAM is being folded. */ ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ fold_multibyte_text (istream, width, &saved_errno); ++ else ++#endif ++ fold_text (istream, width, &saved_errno); ++ + if (ferror (istream)) + { + error (0, saved_errno, "%s", filename); +@@ -251,7 +499,8 @@ main (int argc, char **argv) + + atexit (close_stdout); + +- break_spaces = count_bytes = have_read_stdin = false; ++ operating_mode = column_mode; ++ break_spaces = have_read_stdin = false; + + while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) + { +@@ -260,7 +509,15 @@ main (int argc, char **argv) + switch (optc) + { + case 'b': /* Count bytes rather than columns. */ +- count_bytes = true; ++ if (operating_mode != column_mode) ++ FATAL_ERROR (_("only one way of folding may be specified")); ++ operating_mode = byte_mode; ++ break; ++ ++ case 'c': ++ if (operating_mode != column_mode) ++ FATAL_ERROR (_("only one way of folding may be specified")); ++ operating_mode = character_mode; + break; + + case 's': /* Break at word boundaries. */ +diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c +--- coreutils-8.0-orig/src/join.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/join.c 2009-10-07 10:07:16.000000000 +0200 +@@ -22,17 +22,31 @@ + #include <sys/types.h> + #include <getopt.h> + ++/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ ++#if HAVE_WCHAR_H ++# include <wchar.h> ++#endif ++ ++/* Get iswblank(), towupper. */ ++#if HAVE_WCTYPE_H ++# include <wctype.h> ++#endif ++ + #include "system.h" + #include "error.h" + #include "hard-locale.h" + #include "linebuffer.h" +-#include "memcasecmp.h" + #include "quote.h" + #include "stdio--.h" + #include "xmemcoll.h" + #include "xstrtol.h" + #include "argmatch.h" + ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ ++#if HAVE_MBRTOWC && defined mbstate_t ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) ++#endif ++ + /* The official name of this program (e.g., no `g' prefix). */ + #define PROGRAM_NAME "join" + +@@ -121,10 +135,12 @@ static struct outlist outlist_head; + /* Last element in `outlist', where a new element can be added. */ + static struct outlist *outlist_end = &outlist_head; + +-/* Tab character separating fields. If negative, fields are separated +- by any nonempty string of blanks, otherwise by exactly one +- tab character whose value (when cast to unsigned char) equals TAB. */ +-static int tab = -1; ++/* Tab character separating fields. If NULL, fields are separated ++ by any nonempty string of blanks. */ ++static char *tab = NULL; ++ ++/* The number of bytes used for tab. */ ++static size_t tablen = 0; + + /* If nonzero, check that the input is correctly ordered. */ + static enum +@@ -239,10 +255,11 @@ xfields (struct line *line) + if (ptr == lim) + return; + +- if (0 <= tab) ++ if (tab != NULL) + { ++ unsigned char t = tab[0]; + char *sep; +- for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1) ++ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) + extract_field (line, ptr, sep - ptr); + } + else +@@ -269,6 +286,148 @@ xfields (struct line *line) + extract_field (line, ptr, lim - ptr); + } + ++#if HAVE_MBRTOWC ++static void ++xfields_multibyte (struct line *line) ++{ ++ char *ptr = line->buf.buffer; ++ char const *lim = ptr + line->buf.length - 1; ++ wchar_t wc = 0; ++ size_t mblength = 1; ++ mbstate_t state, state_bak; ++ ++ memset (&state, 0, sizeof (mbstate_t)); ++ ++ if (ptr >= lim) ++ return; ++ ++ if (tab != NULL) ++ { ++ unsigned char t = tab[0]; ++ char *sep = ptr; ++ for (; ptr < lim; ptr = sep + mblength) ++ { ++ sep = ptr; ++ while (sep < lim) ++ { ++ state_bak = state; ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); ++ ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ mblength = 1; ++ state = state_bak; ++ } ++ mblength = (mblength < 1) ? 1 : mblength; ++ ++ if (mblength == tablen && !memcmp (sep, tab, mblength)) ++ break; ++ else ++ { ++ sep += mblength; ++ continue; ++ } ++ } ++ ++ if (sep >= lim) ++ break; ++ ++ extract_field (line, ptr, sep - ptr); ++ } ++ } ++ else ++ { ++ /* Skip leading blanks before the first field. */ ++ while(ptr < lim) ++ { ++ state_bak = state; ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); ++ ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ mblength = 1; ++ state = state_bak; ++ break; ++ } ++ mblength = (mblength < 1) ? 1 : mblength; ++ ++ if (!iswblank(wc)) ++ break; ++ ptr += mblength; ++ } ++ ++ do ++ { ++ char *sep; ++ state_bak = state; ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ mblength = 1; ++ state = state_bak; ++ break; ++ } ++ mblength = (mblength < 1) ? 1 : mblength; ++ ++ sep = ptr + mblength; ++ while (sep < lim) ++ { ++ state_bak = state; ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ mblength = 1; ++ state = state_bak; ++ break; ++ } ++ mblength = (mblength < 1) ? 1 : mblength; ++ ++ if (iswblank (wc)) ++ break; ++ ++ sep += mblength; ++ } ++ ++ extract_field (line, ptr, sep - ptr); ++ if (sep >= lim) ++ return; ++ ++ state_bak = state; ++ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ mblength = 1; ++ state = state_bak; ++ break; ++ } ++ mblength = (mblength < 1) ? 1 : mblength; ++ ++ ptr = sep + mblength; ++ while (ptr < lim) ++ { ++ state_bak = state; ++ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ mblength = 1; ++ state = state_bak; ++ break; ++ } ++ mblength = (mblength < 1) ? 1 : mblength; ++ ++ if (!iswblank (wc)) ++ break; ++ ++ ptr += mblength; ++ } ++ } ++ while (ptr < lim); ++ } ++ ++ extract_field (line, ptr, lim - ptr); ++} ++#endif ++ + static void + freeline (struct line *line) + { +@@ -287,56 +446,115 @@ keycmp (struct line const *line1, struct + size_t jf_1, size_t jf_2) + { + /* Start of field to compare in each file. */ +- char *beg1; +- char *beg2; +- +- size_t len1; +- size_t len2; /* Length of fields to compare. */ ++ char *beg[2]; ++ char *copy[2]; ++ size_t len[2]; /* Length of fields to compare. */ + int diff; ++ int i, j; + + if (jf_1 < line1->nfields) + { +- beg1 = line1->fields[jf_1].beg; +- len1 = line1->fields[jf_1].len; ++ beg[0] = line1->fields[jf_1].beg; ++ len[0] = line1->fields[jf_1].len; + } + else + { +- beg1 = NULL; +- len1 = 0; ++ beg[0] = NULL; ++ len[0] = 0; + } + + if (jf_2 < line2->nfields) + { +- beg2 = line2->fields[jf_2].beg; +- len2 = line2->fields[jf_2].len; ++ beg[1] = line2->fields[jf_2].beg; ++ len[1] = line2->fields[jf_2].len; + } + else + { +- beg2 = NULL; +- len2 = 0; ++ beg[1] = NULL; ++ len[1] = 0; + } + +- if (len1 == 0) +- return len2 == 0 ? 0 : -1; +- if (len2 == 0) ++ if (len[0] == 0) ++ return len[1] == 0 ? 0 : -1; ++ if (len[1] == 0) + return 1; + + if (ignore_case) + { +- /* FIXME: ignore_case does not work with NLS (in particular, +- with multibyte chars). */ +- diff = memcasecmp (beg1, beg2, MIN (len1, len2)); ++#ifdef HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ size_t mblength; ++ wchar_t wc, uwc; ++ mbstate_t state, state_bak; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ ++ for (i = 0; i < 2; i++) ++ { ++ copy[i] = alloca (len[i] + 1); ++ ++ for (j = 0; j < MIN (len[0], len[1]);) ++ { ++ state_bak = state; ++ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); ++ ++ switch (mblength) ++ { ++ case (size_t) -1: ++ case (size_t) -2: ++ state = state_bak; ++ /* Fall through */ ++ case 0: ++ mblength = 1; ++ break; ++ ++ default: ++ uwc = towupper (wc); ++ ++ if (uwc != wc) ++ { ++ mbstate_t state_wc; ++ ++ memset (&state_wc, '\0', sizeof (mbstate_t)); ++ wcrtomb (copy[i] + j, uwc, &state_wc); ++ } ++ else ++ memcpy (copy[i] + j, beg[i] + j, mblength); ++ } ++ j += mblength; ++ } ++ copy[i][j] = '\0'; ++ } ++ } ++ else ++#endif ++ { ++ for (i = 0; i < 2; i++) ++ { ++ copy[i] = alloca (len[i] + 1); ++ ++ for (j = 0; j < MIN (len[0], len[1]); j++) ++ copy[i][j] = toupper (beg[i][j]); ++ ++ copy[i][j] = '\0'; ++ } ++ } + } + else + { +- if (hard_LC_COLLATE) +- return xmemcoll (beg1, len1, beg2, len2); +- diff = memcmp (beg1, beg2, MIN (len1, len2)); ++ copy[0] = (unsigned char *) beg[0]; ++ copy[1] = (unsigned char *) beg[1]; + } + ++ if (hard_LC_COLLATE) ++ return xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); ++ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); ++ ++ + if (diff) + return diff; +- return len1 < len2 ? -1 : len1 != len2; ++ return len[0] - len[1]; + } + + /* Check that successive input lines PREV and CURRENT from input file +@@ -417,6 +635,11 @@ get_line (FILE *fp, struct line **linep, + return false; + } + ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ xfields_multibyte (line); ++ else ++#endif + xfields (line); + + if (prevline[which - 1]) +@@ -518,11 +741,18 @@ prfield (size_t n, struct line const *li + + /* Print the join of LINE1 and LINE2. */ + ++#define PUT_TAB_CHAR \ ++ do \ ++ { \ ++ (tab != NULL) ? \ ++ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ ++ } \ ++ while (0) ++ + static void + prjoin (struct line const *line1, struct line const *line2) + { + const struct outlist *outlist; +- char output_separator = tab < 0 ? ' ' : tab; + + outlist = outlist_head.next; + if (outlist) +@@ -557,7 +787,7 @@ prjoin (struct line const *line1, struct + o = o->next; + if (o == NULL) + break; +- putchar (output_separator); ++ PUT_TAB_CHAR; + } + putchar ('\n'); + } +@@ -575,23 +805,23 @@ prjoin (struct line const *line1, struct + prfield (join_field_1, line1); + for (i = 0; i < join_field_1 && i < line1->nfields; ++i) + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line1); + } + for (i = join_field_1 + 1; i < line1->nfields; ++i) + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line1); + } + + for (i = 0; i < join_field_2 && i < line2->nfields; ++i) + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line2); + } + for (i = join_field_2 + 1; i < line2->nfields; ++i) + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line2); + } + putchar ('\n'); +@@ -1022,20 +1252,41 @@ main (int argc, char **argv) + + case 't': + { +- unsigned char newtab = optarg[0]; +- if (! newtab) ++ char *newtab; ++ size_t newtablen; ++ if (! optarg[0]) + error (EXIT_FAILURE, 0, _("empty tab")); +- if (optarg[1]) ++ newtab = xstrdup (optarg); ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ mbstate_t state; ++ ++ memset (&state, 0, sizeof (mbstate_t)); ++ newtablen = mbrtowc (NULL, newtab, ++ strnlen (newtab, MB_LEN_MAX), ++ &state); ++ if (newtablen == (size_t) 0 ++ || newtablen == (size_t) -1 ++ || newtablen == (size_t) -2) ++ newtablen = 1; ++ } ++ else ++#endif ++ newtablen = 1; ++ ++ if (newtablen == 1 && newtab[1]) ++ { ++ if (STREQ (newtab, "\0")) ++ newtab[0] = '\0'; ++ } ++ if (tab != NULL && strcmp (tab, newtab)) + { +- if (STREQ (optarg, "\0")) +- newtab = '\0'; +- else +- error (EXIT_FAILURE, 0, _("multi-character tab %s"), +- quote (optarg)); ++ free (newtab); ++ error (EXIT_FAILURE, 0, _("incompatible tabs")); + } +- if (0 <= tab && tab != newtab) +- error (EXIT_FAILURE, 0, _("incompatible tabs")); + tab = newtab; ++ tablen = newtablen; + } + break; + +diff -urNp coreutils-8.0-orig/src/pr.c coreutils-8.0/src/pr.c +--- coreutils-8.0-orig/src/pr.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/pr.c 2009-10-07 10:07:16.000000000 +0200 +@@ -312,6 +312,32 @@ + + #include <getopt.h> + #include <sys/types.h> ++ ++/* Get MB_LEN_MAX. */ ++#include <limits.h> ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC ++ installation; work around this configuration error. */ ++#if !defined MB_LEN_MAX || MB_LEN_MAX == 1 ++# define MB_LEN_MAX 16 ++#endif ++ ++/* Get MB_CUR_MAX. */ ++#include <stdlib.h> ++ ++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ ++#if HAVE_WCHAR_H ++# include <wchar.h> ++#endif ++ ++/* Get iswprint(). -- for wcwidth(). */ ++#if HAVE_WCTYPE_H ++# include <wctype.h> ++#endif ++#if !defined iswprint && !HAVE_ISWPRINT ++# define iswprint(wc) 1 ++#endif ++ + #include "system.h" + #include "error.h" + #include "hard-locale.h" +@@ -322,6 +348,18 @@ + #include "strftime.h" + #include "xstrtol.h" + ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ ++#if HAVE_MBRTOWC && defined mbstate_t ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) ++#endif ++ ++#ifndef HAVE_DECL_WCWIDTH ++"this configure-time declaration test was not run" ++#endif ++#if !HAVE_DECL_WCWIDTH ++extern int wcwidth (); ++#endif ++ + /* The official name of this program (e.g., no `g' prefix). */ + #define PROGRAM_NAME "pr" + +@@ -414,7 +452,20 @@ struct COLUMN + + typedef struct COLUMN COLUMN; + +-static int char_to_clump (char c); ++/* Funtion pointers to switch functions for single byte locale or for ++ multibyte locale. If multibyte functions do not exist in your sysytem, ++ these pointers always point the function for single byte locale. */ ++static void (*print_char) (char c); ++static int (*char_to_clump) (char c); ++ ++/* Functions for single byte locale. */ ++static void print_char_single (char c); ++static int char_to_clump_single (char c); ++ ++/* Functions for multibyte locale. */ ++static void print_char_multi (char c); ++static int char_to_clump_multi (char c); ++ + static bool read_line (COLUMN *p); + static bool print_page (void); + static bool print_stored (COLUMN *p); +@@ -424,6 +475,7 @@ static void print_header (void); + static void pad_across_to (int position); + static void add_line_number (COLUMN *p); + static void getoptarg (char *arg, char switch_char, char *character, ++ int *character_length, int *character_width, + int *number); + void usage (int status); + static void print_files (int number_of_files, char **av); +@@ -438,7 +490,6 @@ static void store_char (char c); + static void pad_down (int lines); + static void read_rest_of_line (COLUMN *p); + static void skip_read (COLUMN *p, int column_number); +-static void print_char (char c); + static void cleanup (void); + static void print_sep_string (void); + static void separator_string (const char *optarg_S); +@@ -450,7 +501,7 @@ static COLUMN *column_vector; + we store the leftmost columns contiguously in buff. + To print a line from buff, get the index of the first character + from line_vector[i], and print up to line_vector[i + 1]. */ +-static char *buff; ++static unsigned char *buff; + + /* Index of the position in buff where the next character + will be stored. */ +@@ -554,7 +605,7 @@ static int chars_per_column; + static bool untabify_input = false; + + /* (-e) The input tab character. */ +-static char input_tab_char = '\t'; ++static char input_tab_char[MB_LEN_MAX] = "\t"; + + /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... + where the leftmost column is 1. */ +@@ -564,7 +615,10 @@ static int chars_per_input_tab = 8; + static bool tabify_output = false; + + /* (-i) The output tab character. */ +-static char output_tab_char = '\t'; ++static char output_tab_char[MB_LEN_MAX] = "\t"; ++ ++/* (-i) The byte length of output tab character. */ ++static int output_tab_char_length = 1; + + /* (-i) The width of the output tab. */ + static int chars_per_output_tab = 8; +@@ -638,7 +692,13 @@ static int power_10; + static bool numbered_lines = false; + + /* (-n) Character which follows each line number. */ +-static char number_separator = '\t'; ++static char number_separator[MB_LEN_MAX] = "\t"; ++ ++/* (-n) The byte length of the character which follows each line number. */ ++static int number_separator_length = 1; ++ ++/* (-n) The character width of the character which follows each line number. */ ++static int number_separator_width = 0; + + /* (-n) line counting starts with 1st line of input file (not with 1st + line of 1st page printed). */ +@@ -691,6 +751,7 @@ static bool use_col_separator = false; + -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ + static char *col_sep_string = (char *) ""; + static int col_sep_length = 0; ++static int col_sep_width = 0; + static char *column_separator = (char *) " "; + static char *line_separator = (char *) "\t"; + +@@ -847,6 +908,13 @@ separator_string (const char *optarg_S) + col_sep_length = (int) strlen (optarg_S); + col_sep_string = xmalloc (col_sep_length + 1); + strcpy (col_sep_string, optarg_S); ++ ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ col_sep_width = mbswidth (col_sep_string, 0); ++ else ++#endif ++ col_sep_width = col_sep_length; + } + + int +@@ -871,6 +939,21 @@ main (int argc, char **argv) + + atexit (close_stdout); + ++/* Define which functions are used, the ones for single byte locale or the ones ++ for multibyte locale. */ ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ print_char = print_char_multi; ++ char_to_clump = char_to_clump_multi; ++ } ++ else ++#endif ++ { ++ print_char = print_char_single; ++ char_to_clump = char_to_clump_single; ++ } ++ + n_files = 0; + file_names = (argc > 1 + ? xmalloc ((argc - 1) * sizeof (char *)) +@@ -947,8 +1030,12 @@ main (int argc, char **argv) + break; + case 'e': + if (optarg) +- getoptarg (optarg, 'e', &input_tab_char, +- &chars_per_input_tab); ++ { ++ int dummy_length, dummy_width; ++ ++ getoptarg (optarg, 'e', input_tab_char, &dummy_length, ++ &dummy_width, &chars_per_input_tab); ++ } + /* Could check tab width > 0. */ + untabify_input = true; + break; +@@ -961,8 +1048,12 @@ main (int argc, char **argv) + break; + case 'i': + if (optarg) +- getoptarg (optarg, 'i', &output_tab_char, +- &chars_per_output_tab); ++ { ++ int dummy_width; ++ ++ getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, ++ &dummy_width, &chars_per_output_tab); ++ } + /* Could check tab width > 0. */ + tabify_output = true; + break; +@@ -989,8 +1080,8 @@ main (int argc, char **argv) + case 'n': + numbered_lines = true; + if (optarg) +- getoptarg (optarg, 'n', &number_separator, +- &chars_per_number); ++ getoptarg (optarg, 'n', number_separator, &number_separator_length, ++ &number_separator_width, &chars_per_number); + break; + case 'N': + skip_count = false; +@@ -1029,7 +1120,7 @@ main (int argc, char **argv) + old_s = false; + /* Reset an additional input of -s, -S dominates -s */ + col_sep_string = bad_cast (""); +- col_sep_length = 0; ++ col_sep_length = col_sep_width = 0; + use_col_separator = true; + if (optarg) + separator_string (optarg); +@@ -1186,10 +1277,45 @@ main (int argc, char **argv) + a number. */ + + static void +-getoptarg (char *arg, char switch_char, char *character, int *number) ++getoptarg (char *arg, char switch_char, char *character, int *character_length, ++ int *character_width, int *number) + { + if (!ISDIGIT (*arg)) +- *character = *arg++; ++ { ++#ifdef HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) /* for multibyte locale. */ ++ { ++ wchar_t wc; ++ size_t mblength; ++ int width; ++ mbstate_t state = {'\0'}; ++ ++ mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); ++ ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ *character_length = 1; ++ *character_width = 1; ++ } ++ else ++ { ++ *character_length = (mblength < 1) ? 1 : mblength; ++ width = wcwidth (wc); ++ *character_width = (width < 0) ? 0 : width; ++ } ++ ++ strncpy (character, arg, *character_length); ++ arg += *character_length; ++ } ++ else /* for single byte locale. */ ++#endif ++ { ++ *character = *arg++; ++ *character_length = 1; ++ *character_width = 1; ++ } ++ } ++ + if (*arg) + { + long int tmp_long; +@@ -1248,7 +1374,7 @@ init_parameters (int number_of_files) + else + col_sep_string = column_separator; + +- col_sep_length = 1; ++ col_sep_length = col_sep_width = 1; + use_col_separator = true; + } + /* It's rather pointless to define a TAB separator with column +@@ -1279,11 +1405,11 @@ init_parameters (int number_of_files) + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ + + /* Estimate chars_per_text without any margin and keep it constant. */ +- if (number_separator == '\t') ++ if (number_separator[0] == '\t') + number_width = chars_per_number + + TAB_WIDTH (chars_per_default_tab, chars_per_number); + else +- number_width = chars_per_number + 1; ++ number_width = chars_per_number + number_separator_width; + + /* The number is part of the column width unless we are + printing files in parallel. */ +@@ -1298,7 +1424,7 @@ init_parameters (int number_of_files) + } + + chars_per_column = (chars_per_line - chars_used_by_number - +- (columns - 1) * col_sep_length) / columns; ++ (columns - 1) * col_sep_width) / columns; + + if (chars_per_column < 1) + error (EXIT_FAILURE, 0, _("page width too narrow")); +@@ -1423,7 +1549,7 @@ init_funcs (void) + + /* Enlarge p->start_position of first column to use the same form of + padding_not_printed with all columns. */ +- h = h + col_sep_length; ++ h = h + col_sep_width; + + /* This loop takes care of all but the rightmost column. */ + +@@ -1457,7 +1583,7 @@ init_funcs (void) + } + else + { +- h = h_next + col_sep_length; ++ h = h_next + col_sep_width; + h_next = h + chars_per_column; + } + } +@@ -1747,9 +1873,9 @@ static void + align_column (COLUMN *p) + { + padding_not_printed = p->start_position; +- if (padding_not_printed - col_sep_length > 0) ++ if (padding_not_printed - col_sep_width > 0) + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } + +@@ -2020,13 +2146,13 @@ store_char (char c) + /* May be too generous. */ + buff = X2REALLOC (buff, &buff_allocated); + } +- buff[buff_current++] = c; ++ buff[buff_current++] = (unsigned char) c; + } + + static void + add_line_number (COLUMN *p) + { +- int i; ++ int i, j; + char *s; + int left_cut; + +@@ -2049,22 +2175,24 @@ add_line_number (COLUMN *p) + /* Tabification is assumed for multiple columns, also for n-separators, + but `default n-separator = TAB' hasn't been given priority over + equal column_width also specified by POSIX. */ +- if (number_separator == '\t') ++ if (number_separator[0] == '\t') + { + i = number_width - chars_per_number; + while (i-- > 0) + (p->char_func) (' '); + } + else +- (p->char_func) (number_separator); ++ for (j = 0; j < number_separator_length; j++) ++ (p->char_func) (number_separator[j]); + } + else + /* To comply with POSIX, we avoid any expansion of default TAB + separator with a single column output. No column_width requirement + has to be considered. */ + { +- (p->char_func) (number_separator); +- if (number_separator == '\t') ++ for (j = 0; j < number_separator_length; j++) ++ (p->char_func) (number_separator[j]); ++ if (number_separator[0] == '\t') + output_position = POS_AFTER_TAB (chars_per_output_tab, + output_position); + } +@@ -2225,7 +2353,7 @@ print_white_space (void) + while (goal - h_old > 1 + && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) + { +- putchar (output_tab_char); ++ fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout); + h_old = h_new; + } + while (++h_old <= goal) +@@ -2245,6 +2373,7 @@ print_sep_string (void) + { + char *s; + int l = col_sep_length; ++ int not_space_flag; + + s = col_sep_string; + +@@ -2258,6 +2387,7 @@ print_sep_string (void) + { + for (; separators_not_printed > 0; --separators_not_printed) + { ++ not_space_flag = 0; + while (l-- > 0) + { + /* 3 types of sep_strings: spaces only, spaces and chars, +@@ -2271,12 +2401,15 @@ print_sep_string (void) + } + else + { ++ not_space_flag = 1; + if (spaces_not_printed > 0) + print_white_space (); + putchar (*s++); +- ++output_position; + } + } ++ if (not_space_flag) ++ output_position += col_sep_width; ++ + /* sep_string ends with some spaces */ + if (spaces_not_printed > 0) + print_white_space (); +@@ -2304,7 +2437,7 @@ print_clump (COLUMN *p, int n, char *clu + required number of tabs and spaces. */ + + static void +-print_char (char c) ++print_char_single (char c) + { + if (tabify_output) + { +@@ -2328,6 +2461,74 @@ print_char (char c) + putchar (c); + } + ++#ifdef HAVE_MBRTOWC ++static void ++print_char_multi (char c) ++{ ++ static size_t mbc_pos = 0; ++ static char mbc[MB_LEN_MAX] = {'\0'}; ++ static mbstate_t state = {'\0'}; ++ mbstate_t state_bak; ++ wchar_t wc; ++ size_t mblength; ++ int width; ++ ++ if (tabify_output) ++ { ++ state_bak = state; ++ mbc[mbc_pos++] = c; ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); ++ ++ while (mbc_pos > 0) ++ { ++ switch (mblength) ++ { ++ case (size_t)-2: ++ state = state_bak; ++ return; ++ ++ case (size_t)-1: ++ state = state_bak; ++ ++output_position; ++ putchar (mbc[0]); ++ memmove (mbc, mbc + 1, MB_CUR_MAX - 1); ++ --mbc_pos; ++ break; ++ ++ case 0: ++ mblength = 1; ++ ++ default: ++ if (wc == L' ') ++ { ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); ++ --mbc_pos; ++ ++spaces_not_printed; ++ return; ++ } ++ else if (spaces_not_printed > 0) ++ print_white_space (); ++ ++ /* Nonprintables are assumed to have width 0, except L'\b'. */ ++ if ((width = wcwidth (wc)) < 1) ++ { ++ if (wc == L'\b') ++ --output_position; ++ } ++ else ++ output_position += width; ++ ++ fwrite (mbc, sizeof(char), mblength, stdout); ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); ++ mbc_pos -= mblength; ++ } ++ } ++ return; ++ } ++ putchar (c); ++} ++#endif ++ + /* Skip to page PAGE before printing. + PAGE may be larger than total number of pages. */ + +@@ -2507,9 +2708,9 @@ read_line (COLUMN *p) + align_empty_cols = false; + } + +- if (padding_not_printed - col_sep_length > 0) ++ if (padding_not_printed - col_sep_width > 0) + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } + +@@ -2610,9 +2811,9 @@ print_stored (COLUMN *p) + } + } + +- if (padding_not_printed - col_sep_length > 0) ++ if (padding_not_printed - col_sep_width > 0) + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } + +@@ -2625,8 +2826,8 @@ print_stored (COLUMN *p) + if (spaces_not_printed == 0) + { + output_position = p->start_position + end_vector[line]; +- if (p->start_position - col_sep_length == chars_per_margin) +- output_position -= col_sep_length; ++ if (p->start_position - col_sep_width == chars_per_margin) ++ output_position -= col_sep_width; + } + + return true; +@@ -2645,7 +2846,7 @@ print_stored (COLUMN *p) + number of characters is 1.) */ + + static int +-char_to_clump (char c) ++char_to_clump_single (char c) + { + unsigned char uc = c; + char *s = clump_buff; +@@ -2655,10 +2856,10 @@ char_to_clump (char c) + int chars; + int chars_per_c = 8; + +- if (c == input_tab_char) ++ if (c == input_tab_char[0]) + chars_per_c = chars_per_input_tab; + +- if (c == input_tab_char || c == '\t') ++ if (c == input_tab_char[0] || c == '\t') + { + width = TAB_WIDTH (chars_per_c, input_position); + +@@ -2739,6 +2940,154 @@ char_to_clump (char c) + return chars; + } + ++#ifdef HAVE_MBRTOWC ++static int ++char_to_clump_multi (char c) ++{ ++ static size_t mbc_pos = 0; ++ static char mbc[MB_LEN_MAX] = {'\0'}; ++ static mbstate_t state = {'\0'}; ++ mbstate_t state_bak; ++ wchar_t wc; ++ size_t mblength; ++ int wc_width; ++ register char *s = clump_buff; ++ register int i, j; ++ char esc_buff[4]; ++ int width; ++ int chars; ++ int chars_per_c = 8; ++ ++ state_bak = state; ++ mbc[mbc_pos++] = c; ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); ++ ++ width = 0; ++ chars = 0; ++ while (mbc_pos > 0) ++ { ++ switch (mblength) ++ { ++ case (size_t)-2: ++ state = state_bak; ++ return 0; ++ ++ case (size_t)-1: ++ state = state_bak; ++ mblength = 1; ++ ++ if (use_esc_sequence || use_cntrl_prefix) ++ { ++ width = +4; ++ chars = +4; ++ *s++ = '\'; ++ sprintf (esc_buff, "%03o", mbc[0]); ++ for (i = 0; i <= 2; ++i) ++ *s++ = (int) esc_buff[i]; ++ } ++ else ++ { ++ width += 1; ++ chars += 1; ++ *s++ = mbc[0]; ++ } ++ break; ++ ++ case 0: ++ mblength = 1; ++ /* Fall through */ ++ ++ default: ++ if (memcmp (mbc, input_tab_char, mblength) == 0) ++ chars_per_c = chars_per_input_tab; ++ ++ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') ++ { ++ int width_inc; ++ ++ width_inc = TAB_WIDTH (chars_per_c, input_position); ++ width += width_inc; ++ ++ if (untabify_input) ++ { ++ for (i = width_inc; i; --i) ++ *s++ = ' '; ++ chars += width_inc; ++ } ++ else ++ { ++ for (i = 0; i < mblength; i++) ++ *s++ = mbc[i]; ++ chars += mblength; ++ } ++ } ++ else if ((wc_width = wcwidth (wc)) < 1) ++ { ++ if (use_esc_sequence) ++ { ++ for (i = 0; i < mblength; i++) ++ { ++ width += 4; ++ chars += 4; ++ *s++ = '\'; ++ sprintf (esc_buff, "%03o", c); ++ for (j = 0; j <= 2; ++j) ++ *s++ = (int) esc_buff[j]; ++ } ++ } ++ else if (use_cntrl_prefix) ++ { ++ if (wc < 0200) ++ { ++ width += 2; ++ chars += 2; ++ *s++ = '^'; ++ *s++ = wc ^ 0100; ++ } ++ else ++ { ++ for (i = 0; i < mblength; i++) ++ { ++ width += 4; ++ chars += 4; ++ *s++ = '\'; ++ sprintf (esc_buff, "%03o", c); ++ for (j = 0; j <= 2; ++j) ++ *s++ = (int) esc_buff[j]; ++ } ++ } ++ } ++ else if (wc == L'\b') ++ { ++ width += -1; ++ chars += 1; ++ *s++ = c; ++ } ++ else ++ { ++ width += 0; ++ chars += mblength; ++ for (i = 0; i < mblength; i++) ++ *s++ = mbc[i]; ++ } ++ } ++ else ++ { ++ width += wc_width; ++ chars += mblength; ++ for (i = 0; i < mblength; i++) ++ *s++ = mbc[i]; ++ } ++ } ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); ++ mbc_pos -= mblength; ++ } ++ ++ input_position += width; ++ return chars; ++} ++#endif ++ + /* We've just printed some files and need to clean up things before + looking for more options and printing the next batch of files. + +diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c +--- coreutils-8.0-orig/src/sort.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/sort.c 2009-10-07 10:07:16.000000000 +0200 +@@ -22,10 +22,19 @@ + + #include <config.h> + ++#include <assert.h> + #include <getopt.h> + #include <sys/types.h> + #include <sys/wait.h> + #include <signal.h> ++#if HAVE_WCHAR_H ++# include <wchar.h> ++#endif ++/* Get isw* functions. */ ++#if HAVE_WCTYPE_H ++# include <wctype.h> ++#endif ++ + #include "system.h" + #include "argmatch.h" + #include "error.h" +@@ -122,14 +131,38 @@ static int decimal_point; + /* Thousands separator; if -1, then there isn't one. */ + static int thousands_sep; + ++static int force_general_numcompare = 0; ++ + /* Nonzero if the corresponding locales are hard. */ + static bool hard_LC_COLLATE; +-#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET + static bool hard_LC_TIME; + #endif + + #define NONZERO(x) ((x) != 0) + ++/* get a multibyte character's byte length. */ ++#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ ++ do \ ++ { \ ++ wchar_t wc; \ ++ mbstate_t state_bak; \ ++ \ ++ state_bak = STATE; \ ++ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ ++ \ ++ switch (MBLENGTH) \ ++ { \ ++ case (size_t)-1: \ ++ case (size_t)-2: \ ++ STATE = state_bak; \ ++ /* Fall through. */ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ } \ ++ } \ ++ while (0) ++ + /* The kind of blanks for '-b' to skip in various options. */ + enum blanktype { bl_start, bl_end, bl_both }; + +@@ -268,13 +301,11 @@ static bool reverse; + they were read if all keys compare equal. */ + static bool stable; + +-/* If TAB has this value, blanks separate fields. */ +-enum { TAB_DEFAULT = CHAR_MAX + 1 }; +- +-/* Tab character separating fields. If TAB_DEFAULT, then fields are ++/* Tab character separating fields. If tab_length is 0, then fields are + separated by the empty string between a non-blank character and a blank + character. */ +-static int tab = TAB_DEFAULT; ++static char tab[MB_LEN_MAX + 1]; ++static size_t tab_length = 0; + + /* Flag to remove consecutive duplicate lines from the output. + Only the last of a sequence of equal lines will be output. */ +@@ -712,6 +743,44 @@ reap_some (void) + update_proc (pid); + } + ++/* Function pointers. */ ++static void ++(*inittables) (void); ++static char * ++(*begfield) (const struct line*, const struct keyfield *); ++static char * ++(*limfield) (const struct line*, const struct keyfield *); ++static int ++(*getmonth) (char const *, size_t); ++static int ++(*keycompare) (const struct line *, const struct line *); ++static int ++(*numcompare) (const char *, const char *); ++ ++/* Test for white space multibyte character. ++ Set LENGTH the byte length of investigated multibyte character. */ ++#if HAVE_MBRTOWC ++static int ++ismbblank (const char *str, size_t len, size_t *length) ++{ ++ size_t mblength; ++ wchar_t wc; ++ mbstate_t state; ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ mblength = mbrtowc (&wc, str, len, &state); ++ ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ *length = 1; ++ return 0; ++ } ++ ++ *length = (mblength < 1) ? 1 : mblength; ++ return iswblank (wc); ++} ++#endif ++ + /* Clean up any remaining temporary files. */ + + static void +@@ -1093,7 +1162,7 @@ zaptemp (const char *name) + free (node); + } + +-#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET + + static int + struct_month_cmp (const void *m1, const void *m2) +@@ -1108,7 +1177,7 @@ struct_month_cmp (const void *m1, const + /* Initialize the character class tables. */ + + static void +-inittables (void) ++inittables_uni (void) + { + size_t i; + +@@ -1120,7 +1189,7 @@ inittables (void) + fold_toupper[i] = toupper (i); + } + +-#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET + /* If we're not in the "C" locale, read different names for months. */ + if (hard_LC_TIME) + { +@@ -1202,6 +1271,64 @@ specify_nmerge (int oi, char c, char con + xstrtol_fatal (e, oi, c, long_options, s); + } + ++#if HAVE_MBRTOWC ++static void ++inittables_mb (void) ++{ ++ int i, j, k, l; ++ char *name, *s; ++ size_t s_len, mblength; ++ char mbc[MB_LEN_MAX]; ++ wchar_t wc, pwc; ++ mbstate_t state_mb, state_wc; ++ ++ for (i = 0; i < MONTHS_PER_YEAR; i++) ++ { ++ s = (char *) nl_langinfo (ABMON_1 + i); ++ s_len = strlen (s); ++ monthtab[i].name = name = (char *) xmalloc (s_len + 1); ++ monthtab[i].val = i + 1; ++ ++ memset (&state_mb, '\0', sizeof (mbstate_t)); ++ memset (&state_wc, '\0', sizeof (mbstate_t)); ++ ++ for (j = 0; j < s_len;) ++ { ++ if (!ismbblank (s + j, s_len - j, &mblength)) ++ break; ++ j += mblength; ++ } ++ ++ for (k = 0; j < s_len;) ++ { ++ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); ++ assert (mblength != (size_t)-1 && mblength != (size_t)-2); ++ if (mblength == 0) ++ break; ++ ++ pwc = towupper (wc); ++ if (pwc == wc) ++ { ++ memcpy (mbc, s + j, mblength); ++ j += mblength; ++ } ++ else ++ { ++ j += mblength; ++ mblength = wcrtomb (mbc, pwc, &state_wc); ++ assert (mblength != (size_t)0 && mblength != (size_t)-1); ++ } ++ ++ for (l = 0; l < mblength; l++) ++ name[k++] = mbc[l]; ++ } ++ name[k] = '\0'; ++ } ++ qsort ((void *) monthtab, MONTHS_PER_YEAR, ++ sizeof (struct month), struct_month_cmp); ++} ++#endif ++ + /* Specify the amount of main memory to use when sorting. */ + static void + specify_sort_size (int oi, char c, char const *s) +@@ -1412,7 +1539,7 @@ buffer_linelim (struct buffer const *buf + by KEY in LINE. */ + + static char * +-begfield (const struct line *line, const struct keyfield *key) ++begfield_uni (const struct line *line, const struct keyfield *key) + { + char *ptr = line->text, *lim = ptr + line->length - 1; + size_t sword = key->sword; +@@ -1421,10 +1548,10 @@ begfield (const struct line *line, const + /* The leading field separator itself is included in a field when -t + is absent. */ + +- if (tab != TAB_DEFAULT) ++ if (tab_length) + while (ptr < lim && sword--) + { +- while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) + ++ptr; + if (ptr < lim) + ++ptr; +@@ -1450,11 +1577,70 @@ begfield (const struct line *line, const + return ptr; + } + ++#if HAVE_MBRTOWC ++static char * ++begfield_mb (const struct line *line, const struct keyfield *key) ++{ ++ int i; ++ char *ptr = line->text, *lim = ptr + line->length - 1; ++ size_t sword = key->sword; ++ size_t schar = key->schar; ++ size_t mblength; ++ mbstate_t state; ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ if (tab_length) ++ while (ptr < lim && sword--) ++ { ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ } ++ else ++ while (ptr < lim && sword--) ++ { ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ } ++ ++ if (key->skipsblanks) ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ ++ for (i = 0; i < schar; i++) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ++ if (ptr + mblength > lim) ++ break; ++ else ++ ptr += mblength; ++ } ++ ++ return ptr; ++} ++#endif ++ + /* Return the limit of (a pointer to the first character after) the field + in LINE specified by KEY. */ + + static char * +-limfield (const struct line *line, const struct keyfield *key) ++limfield_uni (const struct line *line, const struct keyfield *key) + { + char *ptr = line->text, *lim = ptr + line->length - 1; + size_t eword = key->eword, echar = key->echar; +@@ -1469,10 +1655,10 @@ limfield (const struct line *line, const + `beginning' is the first character following the delimiting TAB. + Otherwise, leave PTR pointing at the first `blank' character after + the preceding field. */ +- if (tab != TAB_DEFAULT) ++ if (tab_length) + while (ptr < lim && eword--) + { +- while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) + ++ptr; + if (ptr < lim && (eword || echar)) + ++ptr; +@@ -1518,10 +1704,10 @@ limfield (const struct line *line, const + */ + + /* Make LIM point to the end of (one byte past) the current field. */ +- if (tab != TAB_DEFAULT) ++ if (tab_length) + { + char *newlim; +- newlim = memchr (ptr, tab, lim - ptr); ++ newlim = memchr (ptr, tab[0], lim - ptr); + if (newlim) + lim = newlim; + } +@@ -1552,6 +1738,113 @@ limfield (const struct line *line, const + return ptr; + } + ++#if HAVE_MBRTOWC ++static char * ++limfield_mb (const struct line *line, const struct keyfield *key) ++{ ++ char *ptr = line->text, *lim = ptr + line->length - 1; ++ size_t eword = key->eword, echar = key->echar; ++ int i; ++ size_t mblength; ++ mbstate_t state; ++ ++ if (echar == 0) ++ eword++; /* skip all of end field. */ ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ if (tab_length) ++ while (ptr < lim && eword--) ++ { ++ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ if (ptr < lim && (eword | echar)) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ } ++ else ++ while (ptr < lim && eword--) ++ { ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ } ++ ++ ++# ifdef POSIX_UNSPECIFIED ++ /* Make LIM point to the end of (one byte past) the current field. */ ++ if (tab_length) ++ { ++ char *newlim, *p; ++ ++ newlim = NULL; ++ for (p = ptr; p < lim;) ++ { ++ if (memcmp (p, tab, tab_length) == 0) ++ { ++ newlim = p; ++ break; ++ } ++ ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ p += mblength; ++ } ++ } ++ else ++ { ++ char *newlim; ++ newlim = ptr; ++ ++ while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) ++ newlim += mblength; ++ if (ptr < lim) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } ++ while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) ++ newlim += mblength; ++ lim = newlim; ++ } ++# endif ++ ++ if (echar != 0) ++ { ++ /* If we're skipping leading blanks, don't start counting characters ++ * until after skipping past any leading blanks. */ ++ if (key->skipsblanks) ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; ++ ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ ++ for (i = 0; i < echar; i++) ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ++ if (ptr + mblength > lim) ++ break; ++ else ++ ptr += mblength; ++ } ++ } ++ ++ return ptr; ++} ++#endif ++ + /* Fill BUF reading from FP, moving buf->left bytes from the end + of buf->buf to the beginning first. If EOF is reached and the + file wasn't terminated by a newline, supply one. Set up BUF's line +@@ -1634,8 +1927,24 @@ fillbuf (struct buffer *buf, FILE *fp, c + else + { + if (key->skipsblanks) +- while (blanks[to_uchar (*line_start)]) +- line_start++; ++ { ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ size_t mblength; ++ mbstate_t state; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ while (line_start < line->keylim && ++ ismbblank (line_start, ++ line->keylim - line_start, ++ &mblength)) ++ line_start += mblength; ++ } ++ else ++#endif ++ while (blanks[to_uchar (*line_start)]) ++ line_start++; ++ } + line->keybeg = line_start; + } + } +@@ -1673,7 +1982,7 @@ fillbuf (struct buffer *buf, FILE *fp, c + hideously fast. */ + + static int +-numcompare (const char *a, const char *b) ++numcompare_uni (const char *a, const char *b) + { + while (blanks[to_uchar (*a)]) + a++; +@@ -1782,6 +2091,25 @@ human_numcompare (const char *a, const c + : strnumcmp (a, b, decimal_point, thousands_sep)); + } + ++#if HAVE_MBRTOWC ++static int ++numcompare_mb (const char *a, const char *b) ++{ ++ size_t mblength, len; ++ len = strlen (a); /* okay for UTF-8 */ ++ while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) ++ { ++ a += mblength; ++ len -= mblength; ++ } ++ len = strlen (b); /* okay for UTF-8 */ ++ while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) ++ b += mblength; ++ ++ return strnumcmp (a, b, decimal_point, thousands_sep); ++} ++#endif /* HAV_EMBRTOWC */ ++ + static int + general_numcompare (const char *sa, const char *sb) + { +@@ -1815,7 +2143,7 @@ general_numcompare (const char *sa, cons + Return 0 if the name in S is not recognized. */ + + static int +-getmonth (char const *month, size_t len) ++getmonth_uni (char const *month, size_t len) + { + size_t lo = 0; + size_t hi = MONTHS_PER_YEAR; +@@ -1996,11 +2324,79 @@ compare_version (char *restrict texta, s + return diff; + } + ++#if HAVE_MBRTOWC ++static int ++getmonth_mb (const char *s, size_t len) ++{ ++ char *month; ++ register size_t i; ++ register int lo = 0, hi = MONTHS_PER_YEAR, result; ++ char *tmp; ++ size_t wclength, mblength; ++ const char **pp; ++ const wchar_t **wpp; ++ wchar_t *month_wcs; ++ mbstate_t state; ++ ++ while (len > 0 && ismbblank (s, len, &mblength)) ++ { ++ s += mblength; ++ len -= mblength; ++ } ++ ++ if (len == 0) ++ return 0; ++ ++ month = (char *) alloca (len + 1); ++ ++ tmp = (char *) alloca (len + 1); ++ memcpy (tmp, s, len); ++ tmp[len] = '\0'; ++ pp = (const char **)&tmp; ++ month_wcs = (wchar_t *) alloca ((len + 1) * sizeof (wchar_t)); ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ wclength = mbsrtowcs (month_wcs, pp, len + 1, &state); ++ assert (wclength != (size_t)-1 && *pp == NULL); ++ ++ for (i = 0; i < wclength; i++) ++ { ++ month_wcs[i] = towupper(month_wcs[i]); ++ if (iswblank (month_wcs[i])) ++ { ++ month_wcs[i] = L'\0'; ++ break; ++ } ++ } ++ ++ wpp = (const wchar_t **)&month_wcs; ++ ++ mblength = wcsrtombs (month, wpp, len + 1, &state); ++ assert (mblength != (-1) && *wpp == NULL); ++ ++ do ++ { ++ int ix = (lo + hi) / 2; ++ ++ if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) ++ hi = ix; ++ else ++ lo = ix; ++ } ++ while (hi - lo > 1); ++ ++ result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) ++ ? monthtab[lo].val : 0); ++ ++ return result; ++} ++#endif ++ + /* Compare two lines A and B trying every key in sequence until there + are no more keys or a difference is found. */ + + static int +-keycompare (const struct line *a, const struct line *b) ++keycompare_uni (const struct line *a, const struct line *b) + { + struct keyfield *key = keylist; + +@@ -2180,6 +2576,179 @@ keycompare (const struct line *a, const + return key->reverse ? -diff : diff; + } + ++#if HAVE_MBRTOWC ++static int ++keycompare_mb (const struct line *a, const struct line *b) ++{ ++ struct keyfield *key = keylist; ++ ++ /* For the first iteration only, the key positions have been ++ precomputed for us. */ ++ char *texta = a->keybeg; ++ char *textb = b->keybeg; ++ char *lima = a->keylim; ++ char *limb = b->keylim; ++ ++ size_t mblength_a, mblength_b; ++ wchar_t wc_a, wc_b; ++ mbstate_t state_a, state_b; ++ ++ int diff; ++ ++ memset (&state_a, '\0', sizeof(mbstate_t)); ++ memset (&state_b, '\0', sizeof(mbstate_t)); ++ ++ for (;;) ++ { ++ char const *translate = key->translate; ++ bool const *ignore = key->ignore; ++ ++ /* Find the lengths. */ ++ size_t lena = lima <= texta ? 0 : lima - texta; ++ size_t lenb = limb <= textb ? 0 : limb - textb; ++ ++ /* Actually compare the fields. */ ++ if (key->random) ++ diff = compare_random (texta, lena, textb, lenb); ++ else if (key->numeric | key->general_numeric | key->human_numeric) ++ { ++ char savea = *lima, saveb = *limb; ++ ++ *lima = *limb = '\0'; ++ diff = (key->numeric ? numcompare (texta, textb) ++ : key->general_numeric ? general_numcompare (texta, textb) ++ : human_numcompare (texta, textb, key)); ++ *lima = savea, *limb = saveb; ++ } ++ else if (key->version) ++ diff = compare_version (texta, lena, textb, lenb); ++ else if (key->month) ++ diff = getmonth (texta, lena) - getmonth (textb, lenb); ++ else ++ { ++ if (ignore || translate) ++ { ++ char *copy_a = (char *) alloca (lena + 1 + lenb + 1); ++ char *copy_b = copy_a + lena + 1; ++ size_t new_len_a, new_len_b; ++ size_t i, j; ++ ++ /* Ignore and/or translate chars before comparing. */ ++# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ ++ do \ ++ { \ ++ wchar_t uwc; \ ++ char mbc[MB_LEN_MAX]; \ ++ mbstate_t state_wc; \ ++ \ ++ for (NEW_LEN = i = 0; i < LEN;) \ ++ { \ ++ mbstate_t state_bak; \ ++ \ ++ state_bak = STATE; \ ++ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ ++ \ ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ ++ || MBLENGTH == 0) \ ++ { \ ++ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ ++ STATE = state_bak; \ ++ if (!ignore) \ ++ COPY[NEW_LEN++] = TEXT[i++]; \ ++ continue; \ ++ } \ ++ \ ++ if (ignore) \ ++ { \ ++ if ((ignore == nonprinting && !iswprint (WC)) \ ++ || (ignore == nondictionary \ ++ && !iswalnum (WC) && !iswblank (WC))) \ ++ { \ ++ i += MBLENGTH; \ ++ continue; \ ++ } \ ++ } \ ++ \ ++ if (translate) \ ++ { \ ++ \ ++ uwc = towupper(WC); \ ++ if (WC == uwc) \ ++ { \ ++ memcpy (mbc, TEXT + i, MBLENGTH); \ ++ i += MBLENGTH; \ ++ } \ ++ else \ ++ { \ ++ i += MBLENGTH; \ ++ WC = uwc; \ ++ memset (&state_wc, '\0', sizeof (mbstate_t)); \ ++ \ ++ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ ++ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ ++ } \ ++ \ ++ for (j = 0; j < MBLENGTH; j++) \ ++ COPY[NEW_LEN++] = mbc[j]; \ ++ } \ ++ else \ ++ for (j = 0; j < MBLENGTH; j++) \ ++ COPY[NEW_LEN++] = TEXT[i++]; \ ++ } \ ++ COPY[NEW_LEN] = '\0'; \ ++ } \ ++ while (0) ++ IGNORE_CHARS (new_len_a, lena, texta, copy_a, ++ wc_a, mblength_a, state_a); ++ IGNORE_CHARS (new_len_b, lenb, textb, copy_b, ++ wc_b, mblength_b, state_b); ++ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b); ++ } ++ else if (lena == 0) ++ diff = - NONZERO (lenb); ++ else if (lenb == 0) ++ goto greater; ++ else ++ diff = xmemcoll (texta, lena, textb, lenb); ++ } ++ ++ if (diff) ++ goto not_equal; ++ ++ key = key->next; ++ if (! key) ++ break; ++ ++ /* Find the beginning and limit of the next field. */ ++ if (key->eword != -1) ++ lima = limfield (a, key), limb = limfield (b, key); ++ else ++ lima = a->text + a->length - 1, limb = b->text + b->length - 1; ++ ++ if (key->sword != -1) ++ texta = begfield (a, key), textb = begfield (b, key); ++ else ++ { ++ texta = a->text, textb = b->text; ++ if (key->skipsblanks) ++ { ++ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) ++ texta += mblength_a; ++ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) ++ textb += mblength_b; ++ } ++ } ++ } ++ ++ return 0; ++ ++greater: ++ diff = 1; ++not_equal: ++ return key->reverse ? -diff : diff; ++} ++#endif ++ + /* Compare two lines A and B, returning negative, zero, or positive + depending on whether A compares less than, equal to, or greater than B. */ + +@@ -3178,7 +3747,7 @@ main (int argc, char **argv) + initialize_exit_failure (SORT_FAILURE); + + hard_LC_COLLATE = hard_locale (LC_COLLATE); +-#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET + hard_LC_TIME = hard_locale (LC_TIME); + #endif + +@@ -3199,6 +3768,27 @@ main (int argc, char **argv) + thousands_sep = -1; + } + ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ inittables = inittables_mb; ++ begfield = begfield_mb; ++ limfield = limfield_mb; ++ getmonth = getmonth_mb; ++ keycompare = keycompare_mb; ++ numcompare = numcompare_mb; ++ } ++ else ++#endif ++ { ++ inittables = inittables_uni; ++ begfield = begfield_uni; ++ limfield = limfield_uni; ++ getmonth = getmonth_uni; ++ keycompare = keycompare_uni; ++ numcompare = numcompare_uni; ++ } ++ + have_read_stdin = false; + inittables (); + +@@ -3459,13 +4049,35 @@ main (int argc, char **argv) + + case 't': + { +- char newtab = optarg[0]; +- if (! newtab) ++ char newtab[MB_LEN_MAX + 1]; ++ size_t newtab_length = 1; ++ strncpy (newtab, optarg, MB_LEN_MAX); ++ if (! newtab[0]) + error (SORT_FAILURE, 0, _("empty tab")); +- if (optarg[1]) ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ wchar_t wc; ++ mbstate_t state; ++ size_t i; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, ++ MB_LEN_MAX), ++ &state); ++ switch (newtab_length) ++ { ++ case (size_t) -1: ++ case (size_t) -2: ++ case 0: ++ newtab_length = 1; ++ } ++ } ++#endif ++ if (newtab_length == 1 && optarg[1]) + { + if (STREQ (optarg, "\0")) +- newtab = '\0'; ++ newtab[0] = '\0'; + else + { + /* Provoke with `sort -txx'. Complain about +@@ -3476,9 +4088,12 @@ main (int argc, char **argv) + quote (optarg)); + } + } +- if (tab != TAB_DEFAULT && tab != newtab) ++ if (tab_length ++ && (tab_length != newtab_length ++ || memcmp (tab, newtab, tab_length) != 0)) + error (SORT_FAILURE, 0, _("incompatible tabs")); +- tab = newtab; ++ memcpy (tab, newtab, newtab_length); ++ tab_length = newtab_length; + } + break; + +diff -urNp coreutils-8.0-orig/src/unexpand.c coreutils-8.0/src/unexpand.c +--- coreutils-8.0-orig/src/unexpand.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/unexpand.c 2009-10-07 10:07:16.000000000 +0200 +@@ -38,11 +38,28 @@ + #include <stdio.h> + #include <getopt.h> + #include <sys/types.h> ++ ++/* Get mbstate_t, mbrtowc(), wcwidth(). */ ++#if HAVE_WCHAR_H ++# include <wchar.h> ++#endif ++ + #include "system.h" + #include "error.h" + #include "quote.h" + #include "xstrndup.h" + ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC ++ installation; work around this configuration error. */ ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 ++# define MB_LEN_MAX 16 ++#endif ++ ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ ++#if HAVE_MBRTOWC && defined mbstate_t ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) ++#endif ++ + /* The official name of this program (e.g., no `g' prefix). */ + #define PROGRAM_NAME "unexpand" + +@@ -102,6 +119,208 @@ static struct option const longopts[] = + {NULL, 0, NULL, 0} + }; + ++static FILE *next_file (FILE *fp); ++ ++#if HAVE_MBRTOWC ++static void ++unexpand_multibyte (void) ++{ ++ FILE *fp; /* Input stream. */ ++ mbstate_t i_state; /* Current shift state of the input stream. */ ++ mbstate_t i_state_bak; /* Back up the I_STATE. */ ++ mbstate_t o_state; /* Current shift state of the output stream. */ ++ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ ++ char *bufpos; /* Next read position of BUF. */ ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ ++ wint_t wc; /* A gotten wide character. */ ++ size_t mblength; /* The byte size of a multibyte character ++ which shows as same character as WC. */ ++ ++ /* Index in `tab_list' of next tabstop: */ ++ int tab_index = 0; /* For calculating width of pending tabs. */ ++ int print_tab_index = 0; /* For printing as many tabs as possible. */ ++ unsigned int column = 0; /* Column on screen of next char. */ ++ int next_tab_column; /* Column the next tab stop is on. */ ++ int convert = 1; /* If nonzero, perform translations. */ ++ unsigned int pending = 0; /* Pending columns of blanks. */ ++ ++ fp = next_file ((FILE *) NULL); ++ if (fp == NULL) ++ return; ++ ++ memset (&o_state, '\0', sizeof(mbstate_t)); ++ memset (&i_state, '\0', sizeof(mbstate_t)); ++ ++ for (;;) ++ { ++ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) ++ { ++ memmove (buf, bufpos, buflen); ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); ++ bufpos = buf; ++ } ++ ++ /* Get a wide character. */ ++ if (buflen < 1) ++ { ++ mblength = 1; ++ wc = WEOF; ++ } ++ else ++ { ++ i_state_bak = i_state; ++ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state); ++ } ++ ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ i_state = i_state_bak; ++ wc = L'\0'; ++ } ++ ++ if (wc == L' ' && convert && column < INT_MAX) ++ { ++ ++pending; ++ ++column; ++ } ++ else if (wc == L'\t' && convert) ++ { ++ if (tab_size == 0) ++ { ++ /* Do not let tab_index == first_free_tab; ++ stop when it is 1 less. */ ++ while (tab_index < first_free_tab - 1 ++ && column >= tab_list[tab_index]) ++ tab_index++; ++ next_tab_column = tab_list[tab_index]; ++ if (tab_index < first_free_tab - 1) ++ tab_index++; ++ if (column >= next_tab_column) ++ { ++ convert = 0; /* Ran out of tab stops. */ ++ goto flush_pend_mb; ++ } ++ } ++ else ++ { ++ next_tab_column = column + tab_size - column % tab_size; ++ } ++ pending += next_tab_column - column; ++ column = next_tab_column; ++ } ++ else ++ { ++flush_pend_mb: ++ /* Flush pending spaces. Print as many tabs as possible, ++ then print the rest as spaces. */ ++ if (pending == 1) ++ { ++ putchar (' '); ++ pending = 0; ++ } ++ column -= pending; ++ while (pending > 0) ++ { ++ if (tab_size == 0) ++ { ++ /* Do not let print_tab_index == first_free_tab; ++ stop when it is 1 less. */ ++ while (print_tab_index < first_free_tab - 1 ++ && column >= tab_list[print_tab_index]) ++ print_tab_index++; ++ next_tab_column = tab_list[print_tab_index]; ++ if (print_tab_index < first_free_tab - 1) ++ print_tab_index++; ++ } ++ else ++ { ++ next_tab_column = ++ column + tab_size - column % tab_size; ++ } ++ if (next_tab_column - column <= pending) ++ { ++ putchar ('\t'); ++ pending -= next_tab_column - column; ++ column = next_tab_column; ++ } ++ else ++ { ++ --print_tab_index; ++ column += pending; ++ while (pending != 0) ++ { ++ putchar (' '); ++ pending--; ++ } ++ } ++ } ++ ++ if (wc == WEOF) ++ { ++ fp = next_file (fp); ++ if (fp == NULL) ++ break; /* No more files. */ ++ else ++ { ++ memset (&i_state, '\0', sizeof(mbstate_t)); ++ continue; ++ } ++ } ++ ++ if (mblength == (size_t)-1 || mblength == (size_t)-2) ++ { ++ if (convert) ++ { ++ ++column; ++ if (convert_entire_line == 0) ++ convert = 0; ++ } ++ mblength = 1; ++ putchar (buf[0]); ++ } ++ else if (mblength == 0) ++ { ++ if (convert && convert_entire_line == 0) ++ convert = 0; ++ mblength = 1; ++ putchar ('\0'); ++ } ++ else ++ { ++ if (convert) ++ { ++ if (wc == L'\b') ++ { ++ if (column > 0) ++ --column; ++ } ++ else ++ { ++ int width; /* The width of WC. */ ++ ++ width = wcwidth (wc); ++ column += (width > 0) ? width : 0; ++ if (convert_entire_line == 0) ++ convert = 0; ++ } ++ } ++ ++ if (wc == L'\n') ++ { ++ tab_index = print_tab_index = 0; ++ column = pending = 0; ++ convert = 1; ++ } ++ fwrite (bufpos, sizeof(char), mblength, stdout); ++ } ++ } ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++} ++#endif ++ ++ + void + usage (int status) + { +@@ -523,7 +742,12 @@ main (int argc, char **argv) + + file_list = (optind < argc ? &argv[optind] : stdin_argv); + +- unexpand (); ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ unexpand_multibyte (); ++ else ++#endif ++ unexpand (); + + if (have_read_stdin && fclose (stdin) != 0) + error (EXIT_FAILURE, errno, "-"); +diff -urNp coreutils-8.0-orig/src/uniq.c coreutils-8.0/src/uniq.c +--- coreutils-8.0-orig/src/uniq.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/uniq.c 2009-10-07 10:07:16.000000000 +0200 +@@ -22,6 +22,16 @@ + #include <getopt.h> + #include <sys/types.h> + ++/* Get mbstate_t, mbrtowc(). */ ++#if HAVE_WCHAR_H ++# include <wchar.h> ++#endif ++ ++/* Get isw* functions. */ ++#if HAVE_WCTYPE_H ++# include <wctype.h> ++#endif ++ + #include "system.h" + #include "argmatch.h" + #include "linebuffer.h" +@@ -31,7 +41,19 @@ + #include "stdio--.h" + #include "xmemcoll.h" + #include "xstrtol.h" +-#include "memcasecmp.h" ++#include "xmemcoll.h" ++ ++/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC ++ installation; work around this configuration error. */ ++#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 ++# define MB_LEN_MAX 16 ++#endif ++ ++/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ ++#if HAVE_MBRTOWC && defined mbstate_t ++# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) ++#endif ++ + + /* The official name of this program (e.g., no `g' prefix). */ + #define PROGRAM_NAME "uniq" +@@ -107,6 +129,10 @@ static enum delimit_method const delimit + /* Select whether/how to delimit groups of duplicate lines. */ + static enum delimit_method delimit_groups; + ++/* Function pointers. */ ++static char * ++(*find_field) (struct linebuffer *line); ++ + static struct option const longopts[] = + { + {"count", no_argument, NULL, 'c'}, +@@ -206,7 +232,7 @@ size_opt (char const *opt, char const *m + return a pointer to the beginning of the line's field to be compared. */ + + static char * +-find_field (struct linebuffer const *line) ++find_field_uni (struct linebuffer *line) + { + size_t count; + char const *lp = line->buffer; +@@ -227,6 +253,83 @@ find_field (struct linebuffer const *lin + return line->buffer + i; + } + ++#if HAVE_MBRTOWC ++ ++# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \ ++ do \ ++ { \ ++ mbstate_t state_bak; \ ++ \ ++ CONVFAIL = 0; \ ++ state_bak = *STATEP; \ ++ \ ++ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ ++ \ ++ switch (MBLENGTH) \ ++ { \ ++ case (size_t)-2: \ ++ case (size_t)-1: \ ++ *STATEP = state_bak; \ ++ CONVFAIL++; \ ++ /* Fall through */ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ } \ ++ } \ ++ while (0) ++ ++static char * ++find_field_multi (struct linebuffer *line) ++{ ++ size_t count; ++ char *lp = line->buffer; ++ size_t size = line->length - 1; ++ size_t pos; ++ size_t mblength; ++ wchar_t wc; ++ mbstate_t *statep; ++ int convfail; ++ ++ pos = 0; ++ statep = &(line->state); ++ ++ /* skip fields. */ ++ for (count = 0; count < skip_fields && pos < size; count++) ++ { ++ while (pos < size) ++ { ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); ++ ++ if (convfail || !iswblank (wc)) ++ { ++ pos += mblength; ++ break; ++ } ++ pos += mblength; ++ } ++ ++ while (pos < size) ++ { ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); ++ ++ if (!convfail && iswblank (wc)) ++ break; ++ ++ pos += mblength; ++ } ++ } ++ ++ /* skip fields. */ ++ for (count = 0; count < skip_chars && pos < size; count++) ++ { ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); ++ pos += mblength; ++ } ++ ++ return lp + pos; ++} ++#endif ++ + /* Return false if two strings OLD and NEW match, true if not. + OLD and NEW point not to the beginnings of the lines + but rather to the beginnings of the fields to compare. +@@ -235,6 +338,8 @@ find_field (struct linebuffer const *lin + static bool + different (char *old, char *new, size_t oldlen, size_t newlen) + { ++ char *copy_old, *copy_new; ++ + if (check_chars < oldlen) + oldlen = check_chars; + if (check_chars < newlen) +@@ -242,14 +347,92 @@ different (char *old, char *new, size_t + + if (ignore_case) + { +- /* FIXME: This should invoke strcoll somehow. */ +- return oldlen != newlen || memcasecmp (old, new, oldlen); ++ size_t i; ++ ++ copy_old = alloca (oldlen + 1); ++ copy_new = alloca (oldlen + 1); ++ ++ for (i = 0; i < oldlen; i++) ++ { ++ copy_old[i] = toupper (old[i]); ++ copy_new[i] = toupper (new[i]); ++ } + } +- else if (hard_LC_COLLATE) +- return xmemcoll (old, oldlen, new, newlen) != 0; + else +- return oldlen != newlen || memcmp (old, new, oldlen); ++ { ++ copy_old = (char *)old; ++ copy_new = (char *)new; ++ } ++ ++ return xmemcoll (copy_old, oldlen, copy_new, newlen); ++} ++ ++#if HAVE_MBRTOWC ++static int ++different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) ++{ ++ size_t i, j, chars; ++ const char *str[2]; ++ char *copy[2]; ++ size_t len[2]; ++ mbstate_t state[2]; ++ size_t mblength; ++ wchar_t wc, uwc; ++ mbstate_t state_bak; ++ ++ str[0] = old; ++ str[1] = new; ++ len[0] = oldlen; ++ len[1] = newlen; ++ state[0] = oldstate; ++ state[1] = newstate; ++ ++ for (i = 0; i < 2; i++) ++ { ++ copy[i] = alloca (len[i] + 1); ++ ++ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) ++ { ++ state_bak = state[i]; ++ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); ++ ++ switch (mblength) ++ { ++ case (size_t)-1: ++ case (size_t)-2: ++ state[i] = state_bak; ++ /* Fall through */ ++ case 0: ++ mblength = 1; ++ break; ++ ++ default: ++ if (ignore_case) ++ { ++ uwc = towupper (wc); ++ ++ if (uwc != wc) ++ { ++ mbstate_t state_wc; ++ ++ memset (&state_wc, '\0', sizeof(mbstate_t)); ++ wcrtomb (copy[i] + j, uwc, &state_wc); ++ } ++ else ++ memcpy (copy[i] + j, str[i] + j, mblength); ++ } ++ else ++ memcpy (copy[i] + j, str[i] + j, mblength); ++ } ++ j += mblength; ++ } ++ copy[i][j] = '\0'; ++ len[i] = j; ++ } ++ ++ return xmemcoll (copy[0], len[0], copy[1], len[1]); + } ++#endif + + /* Output the line in linebuffer LINE to standard output + provided that the switches say it should be output. +@@ -303,15 +486,43 @@ check_file (const char *infile, const ch + { + char *prevfield IF_LINT (= NULL); + size_t prevlen IF_LINT (= 0); ++#if HAVE_MBRTOWC ++ mbstate_t prevstate; ++ ++ memset (&prevstate, '\0', sizeof (mbstate_t)); ++#endif + + while (!feof (stdin)) + { + char *thisfield; + size_t thislen; ++#if HAVE_MBRTOWC ++ mbstate_t thisstate; ++#endif ++ + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) + break; + thisfield = find_field (thisline); + thislen = thisline->length - 1 - (thisfield - thisline->buffer); ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ thisstate = thisline->state; ++ ++ if (prevline->length == 0 || different_multi ++ (thisfield, prevfield, thislen, prevlen, thisstate, prevstate)) ++ { ++ fwrite (thisline->buffer, sizeof (char), ++ thisline->length, stdout); ++ ++ SWAP_LINES (prevline, thisline); ++ prevfield = thisfield; ++ prevlen = thislen; ++ prevstate = thisstate; ++ } ++ } ++ else ++#endif + if (prevline->length == 0 + || different (thisfield, prevfield, thislen, prevlen)) + { +@@ -330,17 +541,26 @@ check_file (const char *infile, const ch + size_t prevlen; + uintmax_t match_count = 0; + bool first_delimiter = true; ++#if HAVE_MBRTOWC ++ mbstate_t prevstate; ++#endif + + if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) + goto closefiles; + prevfield = find_field (prevline); + prevlen = prevline->length - 1 - (prevfield - prevline->buffer); ++#if HAVE_MBRTOWC ++ prevstate = prevline->state; ++#endif + + while (!feof (stdin)) + { + bool match; + char *thisfield; + size_t thislen; ++#if HAVE_MBRTOWC ++ mbstate_t thisstate; ++#endif + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) + { + if (ferror (stdin)) +@@ -349,6 +569,15 @@ check_file (const char *infile, const ch + } + thisfield = find_field (thisline); + thislen = thisline->length - 1 - (thisfield - thisline->buffer); ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ thisstate = thisline->state; ++ match = !different_multi (thisfield, prevfield, ++ thislen, prevlen, thisstate, prevstate); ++ } ++ else ++#endif + match = !different (thisfield, prevfield, thislen, prevlen); + match_count += match; + +@@ -381,6 +610,9 @@ check_file (const char *infile, const ch + SWAP_LINES (prevline, thisline); + prevfield = thisfield; + prevlen = thislen; ++#if HAVE_MBRTOWC ++ prevstate = thisstate; ++#endif + if (!match) + match_count = 0; + } +@@ -426,6 +658,19 @@ main (int argc, char **argv) + + atexit (close_stdout); + ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ find_field = find_field_multi; ++ } ++ else ++#endif ++ { ++ find_field = find_field_uni; ++ } ++ ++ ++ + skip_chars = 0; + skip_fields = 0; + check_chars = SIZE_MAX; +diff -urNp coreutils-8.0-orig/tests/Makefile.am coreutils-8.0/tests/Makefile.am +--- coreutils-8.0-orig/tests/Makefile.am 2009-09-29 16:25:44.000000000 +0200 ++++ coreutils-8.0/tests/Makefile.am 2009-10-07 10:07:16.000000000 +0200 +@@ -208,6 +208,7 @@ TESTS = \ + misc/sort-compress \ + misc/sort-continue \ + misc/sort-files0-from \ ++ misc/sort-mb-tests \ + misc/sort-merge \ + misc/sort-merge-fdlimit \ + misc/sort-rand \ +@@ -452,6 +453,10 @@ TESTS = \ + $(root_tests) + + pr_data = \ ++ misc/mb1.X \ ++ misc/mb1.I \ ++ misc/mb2.X \ ++ misc/mb2.I \ + pr/0F \ + pr/0FF \ + pr/0FFnt \ +diff -urNp coreutils-8.0-orig/tests/misc/cut coreutils-8.0/tests/misc/cut +--- coreutils-8.0-orig/tests/misc/cut 2009-09-21 14:29:33.000000000 +0200 ++++ coreutils-8.0/tests/misc/cut 2009-10-07 10:07:16.000000000 +0200 +@@ -26,7 +26,7 @@ use strict; + my $prog = 'cut'; + my $try = "Try `$prog --help' for more information.\n"; + my $from_1 = "$prog: fields and positions are numbered from 1\n$try"; +-my $inval = "$prog: invalid byte or field list\n$try"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; + my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; + + my @Tests = +@@ -141,7 +141,7 @@ my @Tests = + + # None of the following invalid ranges provoked an error up to coreutils-6.9. + ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, +- {ERR=>"$prog: invalid decreasing range\n$try"}], ++ {ERR=>"$prog: invalid byte, character or field list\n$try"}], + ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], + ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], + ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], +diff -urNp coreutils-8.0-orig/tests/misc/mb1.I coreutils-8.0/tests/misc/mb1.I +--- coreutils-8.0-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/mb1.I 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,4 @@ ++AppleïŒ 10 ++BananaïŒ 5 ++CitrusïŒ 20 ++CherryïŒ 30 +diff -urNp coreutils-8.0-orig/tests/misc/mb1.X coreutils-8.0/tests/misc/mb1.X +--- coreutils-8.0-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/mb1.X 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,4 @@ ++BananaïŒ 5 ++AppleïŒ 10 ++CitrusïŒ 20 ++CherryïŒ 30 +diff -urNp coreutils-8.0-orig/tests/misc/mb2.I coreutils-8.0/tests/misc/mb2.I +--- coreutils-8.0-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/mb2.I 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,4 @@ ++AppleïŒ ïŒ¡ïŒ¡10ïŒ ïŒ 20 ++BananaïŒ ïŒ¡ïŒ¡5ïŒ ïŒ 30 ++CitrusïŒ ïŒ¡ïŒ¡20ïŒ ïŒ 5 ++CherryïŒ ïŒ¡ïŒ¡30ïŒ ïŒ 10 +diff -urNp coreutils-8.0-orig/tests/misc/mb2.X coreutils-8.0/tests/misc/mb2.X +--- coreutils-8.0-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/mb2.X 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,4 @@ ++CitrusïŒ ïŒ¡ïŒ¡20ïŒ ïŒ 5 ++CherryïŒ ïŒ¡ïŒ¡30ïŒ ïŒ 10 ++AppleïŒ ïŒ¡ïŒ¡10ïŒ ïŒ 20 ++BananaïŒ ïŒ¡ïŒ¡5ïŒ ïŒ 30 +diff -urNp coreutils-8.0-orig/tests/misc/sort-mb-tests coreutils-8.0/tests/misc/sort-mb-tests +--- coreutils-8.0-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/sort-mb-tests 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,58 @@ ++#! /bin/sh ++case $# in ++ 0) xx='../src/sort';; ++ *) xx="$1";; ++esac ++test "$VERBOSE" && echo=echo || echo=: ++$echo testing program: $xx ++errors=0 ++test "$srcdir" || srcdir=. ++test "$VERBOSE" && $xx --version 2> /dev/null ++ ++export LC_ALL=en_US.UTF-8 ++locale -k LC_CTYPE 2>&1 | grep -q charmap.*UTF-8 || exit 77 ++errors=0 ++ ++$xx -t ïŒ -k2 -n misc/mb1.I > misc/mb1.O ++code=$? ++if test $code != 0; then ++ $echo "Test mb1 failed: $xx return code $code differs from expected value 0" 1>&2 ++ errors=`expr $errors + 1` ++else ++ cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1 ++ case $? in ++ 0) if test "$VERBOSE"; then $echo "passed mb1"; fi;; ++ 1) $echo "Test mb1 failed: files misc/mb1.O and $srcdir/misc/mb1.X differ" 1>&2 ++ (diff -c misc/mb1.O $srcdir/misc/mb1.X) 2> /dev/null ++ errors=`expr $errors + 1`;; ++ 2) $echo "Test mb1 may have failed." 1>&2 ++ $echo The command "cmp misc/mb1.O $srcdir/misc/mb1.X" failed. 1>&2 ++ errors=`expr $errors + 1`;; ++ esac ++fi ++ ++$xx -t ïŒ -k4 -n misc/mb2.I > misc/mb2.O ++code=$? ++if test $code != 0; then ++ $echo "Test mb2 failed: $xx return code $code differs from expected value 0" 1>&2 ++ errors=`expr $errors + 1` ++else ++ cmp misc/mb2.O $srcdir/misc/mb2.X > /dev/null 2>&1 ++ case $? in ++ 0) if test "$VERBOSE"; then $echo "passed mb2"; fi;; ++ 1) $echo "Test mb2 failed: files misc/mb2.O and $srcdir/misc/mb2.X differ" 1>&2 ++ (diff -c misc/mb2.O $srcdir/misc/mb2.X) 2> /dev/null ++ errors=`expr $errors + 1`;; ++ 2) $echo "Test mb2 may have failed." 1>&2 ++ $echo The command "cmp misc/mb2.O $srcdir/misc/mb2.X" failed. 1>&2 ++ errors=`expr $errors + 1`;; ++ esac ++fi ++ ++if test $errors = 0; then ++ $echo Passed all 113 tests. 1>&2 ++else ++ $echo Failed $errors tests. 1>&2 ++fi ++test $errors = 0 || errors=1 ++exit $errors diff --git a/pkgs/core/coreutils/patches/coreutils-8.4-pam.patch b/pkgs/core/coreutils/patches/coreutils-8.4-pam.patch new file mode 100644 index 0000000..e61908f --- /dev/null +++ b/pkgs/core/coreutils/patches/coreutils-8.4-pam.patch @@ -0,0 +1,428 @@ +diff -urNp coreutils-8.4-orig/configure.ac coreutils-8.4/configure.ac +--- coreutils-8.4-orig/configure.ac 2010-01-11 18:20:42.000000000 +0100 ++++ coreutils-8.4/configure.ac 2010-02-12 10:17:46.000000000 +0100 +@@ -126,6 +126,13 @@ if test "$gl_gcc_warnings" = yes; then + AC_SUBST([GNULIB_WARN_CFLAGS]) + fi + ++dnl Give the chance to enable PAM ++AC_ARG_ENABLE(pam, dnl ++[ --enable-pam Enable use of the PAM libraries], ++[AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) ++LIB_PAM="-ldl -lpam -lpam_misc" ++AC_SUBST(LIB_PAM)]) ++ + AC_FUNC_FORK + + optional_bin_progs= +diff -urNp coreutils-8.4-orig/doc/coreutils.texi coreutils-8.4/doc/coreutils.texi +--- coreutils-8.4-orig/doc/coreutils.texi 2010-01-03 18:06:20.000000000 +0100 ++++ coreutils-8.4/doc/coreutils.texi 2010-02-12 10:17:46.000000000 +0100 +@@ -15081,8 +15081,11 @@ to certain shells, etc.). + @findex syslog + @command{su} can optionally be compiled to use @code{syslog} to report + failed, and optionally successful, @command{su} attempts. (If the system +-supports @code{syslog}.) However, GNU @command{su} does not check if the +-user is a member of the @code{wheel} group; see below. ++supports @code{syslog}.) ++ ++This version of @command{su} has support for using PAM for ++authentication. You can edit @file{/etc/pam.d/su} to customize its ++behaviour. + + The program accepts the following options. Also see @ref{Common options}. + +@@ -15124,6 +15127,8 @@ environment variables except @env{TERM}, + @env{PATH} to a compiled-in default value. Change to @var{user}'s home + directory. Prepend @samp{-} to the shell's name, intended to make it + read its login startup file(s). ++Additionaly @env{DISPLAY} and @env{XAUTHORITY} environment variables ++are preserved as well for PAM functionality. + + @item -m + @itemx -p +@@ -15163,33 +15168,6 @@ Exit status: + the exit status of the subshell otherwise + @end display + +-@cindex wheel group, not supported +-@cindex group wheel, not supported +-@cindex fascism +-@subsection Why GNU @command{su} does not support the @samp{wheel} group +- +-(This section is by Richard Stallman.) +- +-@cindex Twenex +-@cindex MIT AI lab +-Sometimes a few of the users try to hold total power over all the +-rest. For example, in 1984, a few users at the MIT AI lab decided to +-seize power by changing the operator password on the Twenex system and +-keeping it secret from everyone else. (I was able to thwart this coup +-and give power back to the users by patching the kernel, but I +-wouldn't know how to do that in Unix.) +- +-However, occasionally the rulers do tell someone. Under the usual +-@command{su} mechanism, once someone learns the root password who +-sympathizes with the ordinary users, he or she can tell the rest. The +-``wheel group'' feature would make this impossible, and thus cement the +-power of the rulers. +- +-I'm on the side of the masses, not that of the rulers. If you are +-used to supporting the bosses and sysadmins in whatever they do, you +-might find this idea strange at first. +- +- + @node timeout invocation + @section @command{timeout}: Run a command with a time limit + +diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am +--- coreutils-8.4-orig/src/Makefile.am 2010-01-03 18:06:20.000000000 +0100 ++++ coreutils-8.4/src/Makefile.am 2010-02-12 10:17:46.000000000 +0100 +@@ -361,7 +361,7 @@ factor_LDADD += $(LIB_GMP) + uptime_LDADD += $(GETLOADAVG_LIBS) + + # for crypt +-su_LDADD += $(LIB_CRYPT) ++su_LDADD += $(LIB_CRYPT) @LIB_PAM@ + + # for various ACL functions + copy_LDADD += $(LIB_ACL) +diff -urNp coreutils-8.4-orig/src/su.c coreutils-8.4/src/su.c +--- coreutils-8.4-orig/src/su.c 2010-02-12 10:15:15.000000000 +0100 ++++ coreutils-8.4/src/su.c 2010-02-12 10:24:29.000000000 +0100 +@@ -37,6 +37,16 @@ + restricts who can su to UID 0 accounts. RMS considers that to + be fascist. + ++#ifdef USE_PAM ++ ++ Actually, with PAM, su has nothing to do with whether or not a ++ wheel group is enforced by su. RMS tries to restrict your access ++ to a su which implements the wheel group, but PAM considers that ++ to be fascist, and gives the user/sysadmin the opportunity to ++ enforce a wheel group by proper editing of /etc/pam.conf ++ ++#endif ++ + Compile-time options: + -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. + -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. +@@ -53,6 +63,15 @@ + #include <pwd.h> + #include <grp.h> + ++#ifdef USE_PAM ++# include <signal.h> ++# include <sys/wait.h> ++# include <sys/fsuid.h> ++# include <unistd.h> ++# include <security/pam_appl.h> ++# include <security/pam_misc.h> ++#endif /* USE_PAM */ ++ + #include "system.h" + #include "getpass.h" + +@@ -120,10 +139,17 @@ + /* The user to become if none is specified. */ + #define DEFAULT_USER "root" + ++#ifndef USE_PAM + char *crypt (char const *key, char const *salt); ++#endif + +-static void run_shell (char const *, char const *, char **, size_t) ++static void run_shell (char const *, char const *, char **, size_t, ++ const struct passwd *) ++#ifdef USE_PAM ++ ; ++#else + ATTRIBUTE_NORETURN; ++#endif + + /* If true, pass the `-f' option to the subshell. */ + static bool fast_startup; +@@ -209,7 +235,26 @@ log_su (struct passwd const *pw, bool su + } + #endif + ++#ifdef USE_PAM ++static pam_handle_t *pamh = NULL; ++static int retval; ++static struct pam_conv conv = { ++ misc_conv, ++ NULL ++}; ++ ++#define PAM_BAIL_P if (retval) { \ ++ pam_end(pamh, PAM_SUCCESS); \ ++ return 0; \ ++} ++#define PAM_BAIL_P_VOID if (retval) { \ ++ pam_end(pamh, PAM_SUCCESS); \ ++return; \ ++} ++#endif ++ + /* Ask the user for a password. ++ If PAM is in use, let PAM ask for the password if necessary. + Return true if the user gives the correct password for entry PW, + false if not. Return true without asking for a password if run by UID 0 + or if PW has an empty password. */ +@@ -217,6 +262,44 @@ log_su (struct passwd const *pw, bool su + static bool + correct_password (const struct passwd *pw) + { ++#ifdef USE_PAM ++ struct passwd *caller; ++ char *tty_name, *ttyn; ++ retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh); ++ PAM_BAIL_P; ++ ++ if (getuid() != 0 && !isatty(0)) { ++ fprintf(stderr, "standard in must be a tty\n"); ++ exit(1); ++ } ++ ++ caller = getpwuid(getuid()); ++ if(caller != NULL && caller->pw_name != NULL) { ++ retval = pam_set_item(pamh, PAM_RUSER, caller->pw_name); ++ PAM_BAIL_P; ++ } ++ ++ ttyn = ttyname(0); ++ if (ttyn) { ++ if (strncmp(ttyn, "/dev/", 5) == 0) ++ tty_name = ttyn+5; ++ else ++ tty_name = ttyn; ++ retval = pam_set_item(pamh, PAM_TTY, tty_name); ++ PAM_BAIL_P; ++ } ++ retval = pam_authenticate(pamh, 0); ++ PAM_BAIL_P; ++ retval = pam_acct_mgmt(pamh, 0); ++ if (retval == PAM_NEW_AUTHTOK_REQD) { ++ /* password has expired. Offer option to change it. */ ++ retval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); ++ PAM_BAIL_P; ++ } ++ PAM_BAIL_P; ++ /* must be authenticated if this point was reached */ ++ return 1; ++#else /* !USE_PAM */ + char *unencrypted, *encrypted, *correct; + #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP + /* Shadow passwd stuff for SVR3 and maybe other systems. */ +@@ -241,6 +324,7 @@ correct_password (const struct passwd *p + encrypted = crypt (unencrypted, correct); + memset (unencrypted, 0, strlen (unencrypted)); + return STREQ (encrypted, correct); ++#endif /* !USE_PAM */ + } + + /* Update `environ' for the new shell based on PW, with SHELL being +@@ -254,12 +338,18 @@ modify_environment (const struct passwd + /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. + Unset all other environment variables. */ + char const *term = getenv ("TERM"); ++ char const *display = getenv ("DISPLAY"); ++ char const *xauthority = getenv ("XAUTHORITY"); + if (term) + term = xstrdup (term); + environ = xmalloc ((6 + !!term) * sizeof (char *)); + environ[0] = NULL; + if (term) + xsetenv ("TERM", term); ++ if (display) ++ xsetenv ("DISPLAY", display); ++ if (xauthority) ++ xsetenv ("XAUTHORITY", xauthority); + xsetenv ("HOME", pw->pw_dir); + xsetenv ("SHELL", shell); + xsetenv ("USER", pw->pw_name); +@@ -292,8 +382,13 @@ change_identity (const struct passwd *pw + { + #ifdef HAVE_INITGROUPS + errno = 0; +- if (initgroups (pw->pw_name, pw->pw_gid) == -1) ++ if (initgroups (pw->pw_name, pw->pw_gid) == -1) { ++#ifdef USE_PAM ++ pam_close_session(pamh, 0); ++ pam_end(pamh, PAM_ABORT); ++#endif + error (EXIT_CANCELED, errno, _("cannot set groups")); ++ } + endgrent (); + #endif + if (setgid (pw->pw_gid)) +@@ -302,6 +397,31 @@ change_identity (const struct passwd *pw + error (EXIT_CANCELED, errno, _("cannot set user id")); + } + ++#ifdef USE_PAM ++static int caught=0; ++/* Signal handler for parent process later */ ++static void su_catch_sig(int sig) ++{ ++ ++caught; ++} ++ ++int ++pam_copyenv (pam_handle_t *pamh) ++{ ++ char **env; ++ ++ env = pam_getenvlist(pamh); ++ if(env) { ++ while(*env) { ++ if (putenv (*env)) ++ xalloc_die (); ++ env++; ++ } ++ } ++ return(0); ++} ++#endif ++ + /* Run SHELL, or DEFAULT_SHELL if SHELL is empty. + If COMMAND is nonzero, pass it to the shell with the -c option. + Pass ADDITIONAL_ARGS to the shell as more arguments; there +@@ -309,17 +429,49 @@ change_identity (const struct passwd *pw + + static void + run_shell (char const *shell, char const *command, char **additional_args, +- size_t n_additional_args) ++ size_t n_additional_args, const struct passwd *pw) + { + size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; + char const **args = xnmalloc (n_args, sizeof *args); + size_t argno = 1; ++#ifdef USE_PAM ++ int child; ++ sigset_t ourset; ++ int status; ++ ++ retval = pam_open_session(pamh,0); ++ if (retval != PAM_SUCCESS) { ++ fprintf (stderr, "could not open session\n"); ++ exit (1); ++ } ++ ++/* do this at the last possible moment, because environment variables may ++ be passed even in the session phase ++*/ ++ if(pam_copyenv(pamh) != PAM_SUCCESS) ++ fprintf (stderr, "error copying PAM environment\n"); ++ ++ /* Credentials should be set in the parent */ ++ if (pam_setcred(pamh, PAM_ESTABLISH_CRED) != PAM_SUCCESS) { ++ pam_close_session(pamh, 0); ++ fprintf(stderr, "could not set PAM credentials\n"); ++ exit(1); ++ } ++ ++ child = fork(); ++ if (child == 0) { /* child shell */ ++ change_identity (pw); ++ pam_end(pamh, 0); ++#endif + + if (simulate_login) + { + char *arg0; + char *shell_basename; + ++ if(chdir(pw->pw_dir)) ++ error(0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); ++ + shell_basename = last_component (shell); + arg0 = xmalloc (strlen (shell_basename) + 2); + arg0[0] = '-'; +@@ -344,6 +496,67 @@ run_shell (char const *shell, char const + error (0, errno, "%s", shell); + exit (exit_status); + } ++#ifdef USE_PAM ++ } else if (child == -1) { ++ fprintf(stderr, "can not fork user shell: %s", strerror(errno)); ++ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); ++ pam_close_session(pamh, 0); ++ pam_end(pamh, PAM_ABORT); ++ exit(1); ++ } ++ /* parent only */ ++ sigfillset(&ourset); ++ if (sigprocmask(SIG_BLOCK, &ourset, NULL)) { ++ fprintf(stderr, "%s: signal malfunction\n", PROGRAM_NAME); ++ caught = 1; ++ } ++ if (!caught) { ++ struct sigaction action; ++ action.sa_handler = su_catch_sig; ++ sigemptyset(&action.sa_mask); ++ action.sa_flags = 0; ++ sigemptyset(&ourset); ++ if (sigaddset(&ourset, SIGTERM) ++ || sigaddset(&ourset, SIGALRM) ++ || sigaction(SIGTERM, &action, NULL) ++ || sigprocmask(SIG_UNBLOCK, &ourset, NULL)) { ++ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); ++ caught = 1; ++ } ++ } ++ if (!caught) { ++ do { ++ int pid; ++ ++ pid = waitpid(-1, &status, WUNTRACED); ++ ++ if (((pid_t)-1 != pid) && (0 != WIFSTOPPED (status))) { ++ kill(getpid(), WSTOPSIG(status)); ++ /* once we get here, we must have resumed */ ++ kill(pid, SIGCONT); ++ } ++ } while (0 != WIFSTOPPED(status)); ++ } ++ ++ if (caught) { ++ fprintf(stderr, "\nSession terminated, killing shell..."); ++ kill (child, SIGTERM); ++ } ++ /* Not checking retval on this because we need to call close session */ ++ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); ++ retval = pam_close_session(pamh, 0); ++ PAM_BAIL_P_VOID; ++ retval = pam_end(pamh, PAM_SUCCESS); ++ PAM_BAIL_P_VOID; ++ if (caught) { ++ sleep(2); ++ kill(child, SIGKILL); ++ fprintf(stderr, " ...killed.\n"); ++ exit(-1); ++ } ++ exit ((0 != WIFEXITED (status)) ? WEXITSTATUS (status) ++ : WTERMSIG (status) + 128); ++#endif /* USE_PAM */ + } + + /* Return true if SHELL is a restricted shell (one not returned by +@@ -511,9 +724,9 @@ main (int argc, char **argv) + shell = xstrdup (shell ? shell : pw->pw_shell); + modify_environment (pw, shell); + ++#ifndef USE_PAM + change_identity (pw); +- if (simulate_login && chdir (pw->pw_dir) != 0) +- error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); ++#endif + + /* error() flushes stderr, but does not check for write failure. + Normally, we would catch this via our atexit() hook of +@@ -523,5 +736,5 @@ main (int argc, char **argv) + if (ferror (stderr)) + exit (EXIT_CANCELED); + +- run_shell (shell, command, argv + optind, MAX (0, argc - optind)); ++ run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); + } diff --git a/pkgs/core/coreutils/profile.d/dircolors.sh b/pkgs/core/coreutils/profile.d/dircolors.sh new file mode 100644 index 0000000..873d91b --- /dev/null +++ b/pkgs/core/coreutils/profile.d/dircolors.sh @@ -0,0 +1,9 @@ +# Setup for /bin/ls to support color, the alias is in /etc/bashrc. +if [ -f "/etc/dircolors" ] ; then + eval $(dircolors -b /etc/dircolors) + + if [ -f "$HOME/.dircolors" ] ; then + eval $(dircolors -b $HOME/.dircolors) + fi +fi +alias ls='ls --color=auto' diff --git a/pkgs/core/cpio/cpio.nm b/pkgs/core/cpio/cpio.nm new file mode 100644 index 0000000..7ecbe7e --- /dev/null +++ b/pkgs/core/cpio/cpio.nm @@ -0,0 +1,70 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = cpio +PKG_VER = 2.10 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Packaging +PKG_URL = http://www.gnu.org/software/cpio/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = A GNU archiving program. + +PKG_BUILD_DEPS+= autoconf automake + +define PKG_DESCRIPTION + GNU cpio copies files into or out of a cpio or tar archive. Archives \ + are files which contain a collection of other files plus information \ + about them, such as their file name, owner, timestamps, and access \ + permissions. The archive can be another file on the disk, a magnetic \ + tape, or a pipe. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && autoreconf --force +endef + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --bindir=/bin \ + --libexecdir=/tmp \ + --with-rmt=/usr/sbin/rmt + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + cd $(DIR_APP) && make check +endef diff --git a/pkgs/core/cracklib/cracklib.nm b/pkgs/core/cracklib/cracklib.nm new file mode 100644 index 0000000..940c94b --- /dev/null +++ b/pkgs/core/cracklib/cracklib.nm @@ -0,0 +1,88 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = cracklib +PKG_VER = 2.8.12 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Security/Password +PKG_URL = http://sourceforge.net/projects/cracklib/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = A password-checking library. + +PKG_DEPS += python + +define PKG_DESCRIPTION + CrackLib tests passwords to determine whether they match certain \ + security-oriented characteristics, with the purpose of stopping users \ + from choosing passwords that are easy to guess. CrackLib performs \ + several tests on passwords: it tries to generate words from a username \ + and gecos entry and checks those words against the password; it checks \ + for simplistic patterns in passwords; and it checks for the password \ + in a dictionary. +endef + +PKG_TARBALL = $(THISAPP).tar.gz +PKG_OBJECTS += cracklib-words-20080507.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --with-default-dict=/lib/cracklib/pw_dict \ + --with-python \ + --disable-static + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/{,usr/}lib + mv -v $(BUILDROOT)/usr/lib/libcrack.so.2* $(BUILDROOT)/lib + ln -vsf ../../lib/libcrack.so.2.8.0 $(BUILDROOT)/usr/lib/libcrack.so + + -mkdir -pv $(BUILDROOT)/usr/share/dict + install -v -m644 -D $(DIR_DL)/cracklib-words-20080507.gz \ + $(BUILDROOT)/usr/share/dict/cracklib-words.gz + gunzip -v $(BUILDROOT)/usr/share/dict/cracklib-words.gz + ln -v -s cracklib-words $(BUILDROOT)/usr/share/dict/words + echo -ne "$(DISTRO_NAME)\n$(DISTRO_SNAME)\n" >> \ + $(BUILDROOT)/usr/share/dict/cracklib-extra-words + + -mkdir -pv $(BUILDROOT)/lib/cracklib + cd $(DIR_APP) && util/cracklib-format \ + $(BUILDROOT)/usr/share/dict/cracklib-words \ + $(BUILDROOT)/usr/share/dict/cracklib-extra-words | \ + util/cracklib-packer \ + $(BUILDROOT)/lib/cracklib/pw_dict +endef diff --git a/pkgs/core/cryptsetup-luks/cryptsetup-luks.nm b/pkgs/core/cryptsetup-luks/cryptsetup-luks.nm new file mode 100644 index 0000000..854c5e6 --- /dev/null +++ b/pkgs/core/cryptsetup-luks/cryptsetup-luks.nm @@ -0,0 +1,58 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = cryptsetup-luks +PKG_VER = 1.1.0 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://cryptsetup.googlecode.com/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A utility for setting up encrypted filesystems. + +PKG_DEPS += e2fsprogs libgcrypt libgpg-error lvm2 popt + +define PKG_DESCRIPTION + This package contains cryptsetup, a utility for setting up \ + encrypted filesystems using Device Mapper and the dm-crypt target. +endef + +PKG_TARBALL = cryptsetup-$(PKG_VER).tar.bz2 + +DIR_APP = $(DIR_SRC)/cryptsetup-$(PKG_VER) + +CONFIGURE_OPTIONS += \ + --sbindir=/sbin \ + --libdir=/lib \ + --disable-static + +define STAGE_INSTALL_CMDS + rm -rvf $(BUILDROOT)/lib/cryptsetup{,.la,.so} + -mkdir -pv $(BUILDROOT)/usr/lib + mv -v $(BUILDROOT)/lib/pkgconfig $(BUILDROOT)/usr/lib/ + ln -svf ../../lib/libcryptsetup.so.1 $(BUILDROOT)/usr/lib/libcryptsetup.so +endef diff --git a/pkgs/core/cups/cups.init b/pkgs/core/cups/cups.init new file mode 100644 index 0000000..435ddbe --- /dev/null +++ b/pkgs/core/cups/cups.init @@ -0,0 +1,9 @@ +description "Common Unix Printing System" +author "IPFire Team" + +start on started network +stop on stopping network + +exec /usr/sbin/cupsd -c /etc/cupsd.conf +expect daemon +respawn diff --git a/pkgs/core/cups/cups.nm b/pkgs/core/cups/cups.nm new file mode 100644 index 0000000..54c0b93 --- /dev/null +++ b/pkgs/core/cups/cups.nm @@ -0,0 +1,58 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = cups +PKG_VER = 1.4.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Printing +PKG_URL = http://cups.org/software.php +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = The common UNIX printing system. + +PKG_DEPS += cyrus-sasl ghostscript libjpeg libpng libtiff openldap pam perl python zlib + +define PKG_DESCRIPTION + CUPS is the standards-based, open source printing system developed \ + by Apple Inc. for Mac OS® X and other UNIX®-like operating systems. +endef + +PKG_TARBALL = $(THISAPP)-source.tar.bz2 + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc \ + --localstatedir=/var + +define STAGE_INSTALL + cd $(DIR_APP) && make install BUILDROOT=$(BUILDROOT) + + # Remove sysvinit scripts + rm -vfr $(BUILDROOT)/etc/init.d/cups $(BUILDROOT)/etc/rc*.d + + -mkdir -pv $(BUILDROOT)/etc/cups + cp -vf $(DIR_APP)/conf/cupsd.conf $(BUILDROOT)/etc/cups/ +endef diff --git a/pkgs/core/curl/curl.nm b/pkgs/core/curl/curl.nm new file mode 100644 index 0000000..7b8a9a6 --- /dev/null +++ b/pkgs/core/curl/curl.nm @@ -0,0 +1,72 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = curl +PKG_VER = 7.19.7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Application/Internet +PKG_URL = http://www.curl.haxx.se/ +PKG_LICENSE = MIT +PKG_SUMMARY = A utility for getting files from remote servers (FTP, HTTP, and others). + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += libidn openldap libssh2 openssh openssl zlib + +define PKG_DESCRIPTION + cURL is a tool for getting files from HTTP, FTP, FILE, LDAP, LDAPS, \ + DICT, TELNET and TFTP servers, using any of the supported protocols. \ + cURL is designed to work without user interaction or any kind of \ + interactivity. cURL offers many useful capabilities, like proxy support, \ + user authentication, FTP upload, HTTP post, and file transfer resume. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### +CONFIGURE_OPTIONS += \ + --disable-static \ + --with-ca-bundle=/etc/pki/tls/certs/ca-bundle.crt \ + --with-libidn \ + --with-libssh2 \ + --with-nss \ + --enable-ldaps \ + --enable-ipv6 + +#define STAGE_PREPARE_CMDS +# # Remove bogus rpath +# cd $(DIR_APP) && sed -i \ +# -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ +# -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool +#endef + +# Doesn't work +#define STAGE_TEST +# cd $(DIR_APP) && make check +#endef diff --git a/pkgs/core/cyrus-sasl/cyrus-sasl.nm b/pkgs/core/cyrus-sasl/cyrus-sasl.nm new file mode 100644 index 0000000..7a950de --- /dev/null +++ b/pkgs/core/cyrus-sasl/cyrus-sasl.nm @@ -0,0 +1,64 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = cyrus-sasl +PKG_VER = 2.1.23 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://asg.web.cmu.edu/sasl/sasl-library.html +PKG_LICENSE = BSD +PKG_SUMMARY = The Cyrus SASL library. + +PKG_DEPS += db openssl pam + +define PKG_DESCRIPTION + The cyrus-sasl package contains the Cyrus implementation of SASL. \ + SASL is the Simple Authentication and Security Layer, a method for \ + adding authentication support to connection-based protocols. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --sysconfdir=/etc \ + --with-dbpath=/var/lib/sasl/sasldb2 \ + --with-saslauthd=/var/run/saslauthd \ + --mandir=/usr/share/man + +PARALLELISMFLAGS = +############################################################################### +# Installation Details +############################################################################### + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/usr/lib/sasl2 + cp -vf $(DIR_SOURCE)/smtpd.conf $(BUILDROOT)/usr/lib/sasl2/ + + install -v -m700 -d $(BUILDROOT)/var/lib/sasl $(BUILDROOT)/var/run/saslauthd +endef diff --git a/pkgs/core/cyrus-sasl/patches/cyrus-sasl-2.1.23-bad-elif.patch b/pkgs/core/cyrus-sasl/patches/cyrus-sasl-2.1.23-bad-elif.patch new file mode 100644 index 0000000..33550c4 --- /dev/null +++ b/pkgs/core/cyrus-sasl/patches/cyrus-sasl-2.1.23-bad-elif.patch @@ -0,0 +1,21 @@ +diff -up cyrus-sasl-2.1.22/plugins/digestmd5.c.elif cyrus-sasl-2.1.22/plugins/digestmd5.c +--- cyrus-sasl-2.1.22/plugins/digestmd5.c.elif 2009-01-23 09:40:31.000000000 +0100 ++++ cyrus-sasl-2.1.22/plugins/digestmd5.c 2009-02-06 15:20:15.000000000 +0100 +@@ -2743,7 +2743,7 @@ static sasl_server_plug_t digestmd5_serv + "DIGEST-MD5", /* mech_name */ + #ifdef WITH_RC4 + 128, /* max_ssf */ +-#elif WITH_DES ++#elif defined(WITH_DES) + 112, + #else + 1, +@@ -4071,7 +4071,7 @@ static sasl_client_plug_t digestmd5_clie + "DIGEST-MD5", + #ifdef WITH_RC4 /* mech_name */ + 128, /* max ssf */ +-#elif WITH_DES ++#elif defined(WITH_DES) + 112, + #else + 1, diff --git a/pkgs/core/cyrus-sasl/smtpd.conf b/pkgs/core/cyrus-sasl/smtpd.conf new file mode 100644 index 0000000..33c1f23 --- /dev/null +++ b/pkgs/core/cyrus-sasl/smtpd.conf @@ -0,0 +1,2 @@ +pwcheck_method: saslauthd +mech_list: PLAIN LOGIN diff --git a/pkgs/core/db/db.nm b/pkgs/core/db/db.nm new file mode 100644 index 0000000..749a007 --- /dev/null +++ b/pkgs/core/db/db.nm @@ -0,0 +1,63 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = db +PKG_VER = 4.7.25 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.oracle.com/technology/products/berkeley-db/ +PKG_LICENSE = Proprietary +PKG_SUMMARY = Berkeley DB is a library that provides an embedded database. + +define PKG_DESCRIPTION + Berkeley DB (BDB) is a computer software library that provides \ + a high-performance embedded database. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP)/build_unix && \ + CC=gcc \ + ../dist/configure \ + --prefix=/usr \ + --enable-compat185 \ + --enable-cxx \ + --disable-static + + cd $(DIR_APP)/build_unix && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP)/build_unix && make install DESTDIR=$(BUILDROOT) \ + docdir=$(BUILDROOT)/usr/share/doc/$(THISAPP) +endef diff --git a/pkgs/core/db/patches/db-4.7.25-upstream_fixes-1.patch b/pkgs/core/db/patches/db-4.7.25-upstream_fixes-1.patch new file mode 100644 index 0000000..a8de431 --- /dev/null +++ b/pkgs/core/db/patches/db-4.7.25-upstream_fixes-1.patch @@ -0,0 +1,64 @@ +Submitted By: DJ Lucas <dj_AT_linuxfromscratch_DOT_org> +Date: 2008-09-28 +Initial Package Version: 4.7.25 +Upstream Status: From Upstream +Origin: http://www.oracle.com/technology/products/berkeley-db/db/update/4.7.25/patch.4.7.25.1 +Description: Update to latest patch for 4.7.25 release (avoid improperly named + patches in LFS). + +diff -Naur db-4.7.25-orig/sequence/sequence.c db-4.7.25/sequence/sequence.c +--- db-4.7.25-orig/sequence/sequence.c 2008-05-05 15:25:09.000000000 -0500 ++++ db-4.7.25/sequence/sequence.c 2008-09-28 00:03:59.000000000 -0500 +@@ -187,7 +187,11 @@ + if ((ret = __db_get_flags(dbp, &tflags)) != 0) + goto err; + +- if (DB_IS_READONLY(dbp)) { ++ /* ++ * We can let replication clients open sequences, but must ++ * check later that they do not update them. ++ */ ++ if (F_ISSET(dbp, DB_AM_RDONLY)) { + ret = __db_rdonly(dbp->env, "DB_SEQUENCE->open"); + goto err; + } +@@ -244,6 +248,11 @@ + if ((ret != DB_NOTFOUND && ret != DB_KEYEMPTY) || + !LF_ISSET(DB_CREATE)) + goto err; ++ if (IS_REP_CLIENT(env) && ++ !F_ISSET(dbp, DB_AM_NOT_DURABLE)) { ++ ret = __db_rdonly(env, "DB_SEQUENCE->open"); ++ goto err; ++ } + ret = 0; + + rp = &seq->seq_record; +@@ -296,7 +305,12 @@ + */ + rp = seq->seq_data.data; + if (rp->seq_version == DB_SEQUENCE_OLDVER) { +-oldver: rp->seq_version = DB_SEQUENCE_VERSION; ++oldver: if (IS_REP_CLIENT(env) && ++ !F_ISSET(dbp, DB_AM_NOT_DURABLE)) { ++ ret = __db_rdonly(env, "DB_SEQUENCE->open"); ++ goto err; ++ } ++ rp->seq_version = DB_SEQUENCE_VERSION; + if (!F_ISSET(env, ENV_LITTLEENDIAN)) { + if (IS_DB_AUTO_COMMIT(dbp, txn)) { + if ((ret = +@@ -707,6 +721,13 @@ + + MUTEX_LOCK(env, seq->mtx_seq); + ++ if (handle_check && IS_REP_CLIENT(env) && ++ !F_ISSET(dbp, DB_AM_NOT_DURABLE)) { ++ ret = __db_rdonly(env, "DB_SEQUENCE->get"); ++ goto err; ++ } ++ ++ + if (rp->seq_min + delta > rp->seq_max) { + __db_errx(env, "Sequence overflow"); + ret = EINVAL; diff --git a/pkgs/core/dbus-glib/dbus-glib.nm b/pkgs/core/dbus-glib/dbus-glib.nm new file mode 100644 index 0000000..6489cbc --- /dev/null +++ b/pkgs/core/dbus-glib/dbus-glib.nm @@ -0,0 +1,54 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = dbus-glib +PKG_VER = 0.82 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.freedesktop.org/software/dbus/ +PKG_LICENSE = GPLv2+ AFL +PKG_SUMMARY = Glib bindings for D-Bus. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += dbus glib2 expat + +define PKG_DESCRIPTION + D-Bus add-on library to integrate the standard D-Bus library with \ + the GLib thread abstraction and main loop. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc \ + --libexecdir=/usr/lib \ + --mandir=/usr/share/man + +define STAGE_TEST + cd $(DIR_APP) && make check +endef diff --git a/pkgs/core/dbus/dbus.nm b/pkgs/core/dbus/dbus.nm new file mode 100644 index 0000000..cf0ea0b --- /dev/null +++ b/pkgs/core/dbus/dbus.nm @@ -0,0 +1,59 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = dbus +PKG_VER = 1.2.16 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Daemons +PKG_URL = http://www.freedesktop.org/software/dbus/ +PKG_LICENSE = GPLv2+ AFL +PKG_SUMMARY = D-BUS message bus. + +PKG_DEPS += expat + +define PKG_DESCRIPTION + D-BUS is a system for sending messages between applications. It is \ + used both for the system-wide message bus service, and as a \ + per-user-login-session messaging facility. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --libdir=/lib \ + --libexecdir=/lib + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/usr/lib + mv -v $(BUILDROOT)/lib/pkgconfig $(BUILDROOT)/usr/lib/ + + rm -vf $(BUILDROOT)/lib/libdbus-1.so + ln -svf ../../lib/libdbus-1.so.3 $(BUILDROOT)/usr/lib/libdbus-1.so +endef diff --git a/pkgs/core/dbus/messagebus.conf b/pkgs/core/dbus/messagebus.conf new file mode 100644 index 0000000..b8717c0 --- /dev/null +++ b/pkgs/core/dbus/messagebus.conf @@ -0,0 +1,15 @@ +description "Starts the message bus daemon" +author "IPFire Team" + +start on stopped mountfs +stop on starting shutdown + +exec /usr/bin/dbus-daemon --config-file=/etc/dbus-1/system.conf --nofork +respawn + +pre-start script + dbus-uuidgen --ensure >/dev/null + if [ ! -d /var/run/dbus ]; then + mkdir /var/run/dbus + fi +end script diff --git a/pkgs/core/dejagnu/dejagnu.nm b/pkgs/core/dejagnu/dejagnu.nm new file mode 100644 index 0000000..bab9434 --- /dev/null +++ b/pkgs/core/dejagnu/dejagnu.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = dejagnu +PKG_VER = 1.4.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/dejagnu/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A front end for testing other programs + +PKG_BUILD_DEPS+= bison +PKG_DEPS += expect tcl + +define PKG_DESCRIPTION + DejaGnu is an Expect/Tcl based framework for testing other programs. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --mandir=/usr/share/man + +define STAGE_INSTALL_CMDS + cd $(DIR_APP) && make -C doc DESTDIR=$(BUILDROOT) install-man +endef diff --git a/pkgs/core/dhcp/dhclient-script b/pkgs/core/dhcp/dhclient-script new file mode 100644 index 0000000..6991938 --- /dev/null +++ b/pkgs/core/dhcp/dhclient-script @@ -0,0 +1,590 @@ +#!/bin/bash +# +# dhclient-script: Network interface configuration script run by +# dhclient based on DHCP client communication +# +# Copyright (C) 2008 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): David Cantrell <dcantrell@redhat.com> +# +# ---------- +# This script is a rewrite/reworking on dhclient-script originally +# included as part of dhcp-970306: +# dhclient-script for Linux. Dan Halbert, March, 1997. +# Updated for Linux 2.[12] by Brian J. Murrell, January 1999. +# Modified by David Cantrell <dcantrell@redhat.com> for Fedora and RHEL +# ---------- +# + +PATH=/bin:/usr/bin:/sbin +SAVEDIR=/var/lib/dhclient + +LOGFACILITY="local7" +LOGLEVEL="notice" + +logmessage() { + msg="${1}" + logger -p ${LOGFACILITY}.${LOGLEVEL} -t "NET" "dhclient: ${msg}" +} + +save_previous() { + origfile="${1}" + savefile="${SAVEDIR}/${origfile##*/}.predhclient.${interface}" + + if [ ! -d ${SAVEDIR} ]; then + mkdir -p ${SAVEDIR} + fi + + if [ -e ${origfile} ]; then + mv ${origfile} ${savefile} + else + echo > ${savefile} + fi +} + +make_resolv_conf() { + [ "${PEERDNS}" = "no" ] && return + + if [ "${reason}" = "RENEW" ] && + [ "${new_domain_name}" = "${old_domain_name}" ] && + [ "${new_domain_name_servers}" = "${old_domain_name_servers}" ]; then + return + fi + + if [ -n "${new_domain_name}" ] || + [ -n "${new_domain_name_servers}" ] || + [ -n "${new_domain_search}" ]; then + save_previous /etc/resolv.conf + rscf="$(mktemp /tmp/XXXXXX)" + echo "; generated by /sbin/dhclient-script" > ${rscf} + + if [ -n "${SEARCH}" ]; then + echo "search ${SEARCH}" >> $rscf + else + if [ -n "${new_domain_search}" ]; then + echo "search ${new_domain_search//\032/ }" >> ${rscf} + elif [ -n "${new_domain_name}" ]; then + echo "search ${new_domain_name//\032/ }" >> ${rscf} + fi + fi + + if [ -n "${RES_OPTIONS}" ]; then + echo "options ${RES_OPTIONS}" >> ${rscf} + fi + + for nameserver in ${new_domain_name_servers} ; do + echo "nameserver ${nameserver}" >> ${rscf} + done + + change_resolv_conf ${rscf} + rm -f ${rscf} + fi +} + +exit_with_hooks() { + exit_status="${1}" + + if [ -x /etc/dhclient-exit-hooks ]; then + . /etc/dhclient-exit-hooks + fi + + exit ${exit_status} +} + +quad2num() { + if [ $# -eq 4 ]; then + let n="${1} << 24 | ${2} << 16 | ${3} << 8 | ${4}" + echo "${n}" + return 0 + else + echo "0" + return 1 + fi +} + +ip2num() { + IFS="." quad2num ${1} +} + +num2ip() { + let n="${1}" + let o1="(n >> 24) & 0xff" + let o2="(n >> 16) & 0xff" + let o3="(n >> 8) & 0xff" + let o4="n & 0xff" + echo "${o1}.${o2}.${o3}.${o4}" +} + +mask() { + ip="${1}" + m="${2}" + let ip="$(IFS="." ip2num ${ip})" + let m="$(IFS="." ip2num ${m})" + let n="ip & m" + num2ip ${n} +} + +class_bits() { + let ip=$(IFS='.' ip2num $1) + let bits=32 + let mask='255' + for ((i=0; i <= 3; i++, 'mask<<=8')); do + let v='ip&mask' + if [ "$v" -eq 0 ] ; then + let bits-=8 + else + break + fi + done + echo $bits +} + +is_router_reachable() { + # handle DHCP servers that give us a router not on our subnet + router="${1}" + routersubnet="$(mask ${router} ${new_subnet_mask})" + mysubnet="$(mask ${new_ip_address} ${new_subnet_mask})" + unreachable=0 + + if [ ! "${routersubnet}" = "${mysubnet}" ]; then + unreachable=1 + if arping -f -q -I ${interface} -w2 ${router}; then + ip route add ${router}/32 dev ${interface} + if [ $? -eq 0 ]; then + unreachable=0 + else + logmessage "failed to create host router for unreachable router ${router} not on subnet ${mysubnet}" + fi + else + unreachable=1 + logmessage "DHCP router ${router} is unreachable on DHCP subnet ${mysubnet} router subnet ${routersubnet}" + fi + fi + + return ${unreachable} +} + +add_default_gateway() { + router="${1}" + metric="" + + if [ $# -gt 1 ] && [ ${2} -gt 0 ]; then + metric="metric ${2}" + fi + + if is_router_reachable ${router} ; then + ip route replace default via ${router} dev ${interface} ${metric} + if [ $? -ne 0 ]; then + logmessage "failed to create default route: ${router} dev ${interface} ${metric}" + return 1 + else + return 0 + fi + fi + + return 1 +} + +dhconfig() { + if [ -n "${old_ip_address}" ] && [ -n "${alias_ip_address}" ] && + [ ! "${alias_ip_address}" = "${old_ip_address}" ]; then + # possible new alias, remove old alias first + ip -family inet addr del ${old_ip_address} dev ${interface}:0 + fi + + if [ -n "${old_ip_address}" ] && + [ ! "${old_ip_address}" = "${new_ip_address}" ]; then + # IP address changed. Bringing down the interface will delete all + # routes, and clear the ARP cache. + ip -family inet addr flush dev ${interface} >/dev/null 2>&1 + ip -family inet link set dev ${interface} down + fi + + if [ "${reason}" = "BOUND" ] || [ "${reason}" = "REBOOT" ] || + [ ! "${old_ip_address}" = "${new_ip_address}" ] || + [ ! "${old_subnet_mask}" = "${new_subnet_mask}" ] || + [ ! "${old_network_number}" = "${new_network_number}" ] || + [ ! "${old_broadcast_address}" = "${new_broadcast_address}" ] || + [ ! "${old_routers}" = "${new_routers}" ] || + [ ! "${old_interface_mtu}" = "${new_interface_mtu}" ]; then + ip -family inet addr add ${new_ip_address}/${new_prefix} broadcast ${new_broadcast_address} dev ${interface} + + if [ -n "${new_interface_mtu}" ]; then + ip link set ${interface} mtu ${new_interface_mtu} + fi + + if [ -x /etc/dhclient-${interface}-up-hooks ]; then + . /etc/dhclient-${interface}-up-hooks + elif [ -x /etc/dhclient-up-hooks ]; then + . /etc/dhclient-up-hooks + fi + + if [[ (( -z "${GATEWAYDEV}" ) || + ( "${GATEWAYDEV}" = "${interface}" )) && + (( -z "$GATEWAY" ) || + (( -n "$DHCLIENT_IGNORE_GATEWAY" ) && + ( "$DHCLIENT_IGNORE_GATEWAY" = [Yy]* ))) ]]; then + metric="${METRIC:-}" + let i="${METRIC:-0}" + default_routers=() + + for router in ${new_routers} ; do + added_router=- + + for r in ${default_routers[@]} ; do + if [ "${r}" = "${router}" ]; then + added_router=1 + fi + done + + if [ -z "${router}" ] || + [ "${added_router}" = "1" ] || + [ $(IFS=. ip2num ${router}) -le 0 ] || + [[ ( "${router}" = "${new_broadcast_address}" ) && + ( "${new_subnet_mask}" != "255.255.255.255" ) ]]; then + continue + fi + + default_routers=(${default_routers[@]} ${router}) + add_default_gateway ${router} ${metric} + let i=i+1 + metric=${i} + done + elif [[ (( -z "${GATEWAYDEV}" ) || + ( "${GATEWAYDEV}" = "${interface}" )) && + ( -n "${GATEWAY}" ) ]]; then + routersubnet=$(mask ${GATEWAY} ${new_subnet_mask}) + mysubnet=$(mask ${new_ip_address} ${new_subnet_mask}) + + if [ "${routersubnet}" = "${mysubnet}" ]; then + ip route replace default via ${GATEWAY} dev ${interface} + fi + fi + + # static routes + if [ -n "${new_static_routes}" ]; then + IFS=', |' static_routes=(${new_static_routes}) + route_targets=() + + for((i=0; i<${#static_routes[@]}; i+=2)); do + target=${static_routes[$i]} + gateway=${static_routes[$i+1]} + metric='' + + for t in ${route_targets[@]}; do + if [ ${t} = ${target} ]; then + if [ -z "${metric}" ]; then + metric=1 + else + ((metric=metric+1)) + fi + fi + done + + if [ -n "${metric}" ]; then + metric="metric ${metric}" + fi + + if is_router_reachable ${gateway}; then + ip route replace ${target}/$(class_bits ${target}) via ${gateway} dev ${interface} ${metric} + + if [ $? -ne 0 ]; then + logmessage "failed to create static route: ${target}/$(class_bits ${target}) via ${gateway} dev ${interface} ${metric}" + else + route_targets=(${route_targets[@]} ${target}) + fi + fi + done + fi + fi + + if [ ! "${new_ip_address}" = "${alias_ip_address}" ] && + [ -n "${alias_ip_address}" ]; then + ip -family inet addr flush dev ${interface}:0 >/dev/null 2>&1 + ip -family inet addr add ${alias_ip_address}/${alias_prefix} dev ${interface}:0 + ip route replace ${alias_ip_address}/32 dev ${interface}:0 + fi + + make_resolv_conf + + if [ -n "${new_host_name}" ] && need_hostname; then + hostname ${new_host_name} + fi + + if [ ! "${PEERNIS}" = "no" ]; then + if [ -n "${new_nis_domain}" ]; then + domainname "${new_nis_domain}" + save_previous /etc/yp.conf + let contents=0 + echo '# generated by /sbin/dhclient-script' > /etc/yp.conf + + if [ -n "${new_nis_servers}" ]; then + for i in ${new_nis_servers} ; do + echo "domain ${new_nis_domain} server ${i}" >> /etc/yp.conf + let contents=contents+1 + done + else + echo "domain ${new_nis_domain} broadcast" >> /etc/yp.conf + let contents=contents+1 + fi + + if [ ${contents} -gt 0 ]; then + if [ -x /etc/rc.d/init.d/ypbind ] && + [ -r /var/run/ypbind.pid ]; then + service ypbind restart >/dev/null 2>&1 + fi + fi + elif [ -n "${new_nis_servers}" ]; then + save_previous /etc/yp.conf + echo '# generated by /sbin/dhclient-script' > /etc/yp.conf + let contents=0 + + for i in ${new_nis_servers} ; do + echo "ypserver ${i}" >> /etc/yp.conf + let contents=contents+1 + done + + if [ $contents -gt 0 ]; then + if [ -x /etc/rc.d/init.d/ypbind ] && + [ -r /var/run/ypbind.pid ]; then + service ypbind restart >/dev/null 2>&1 + fi + fi + fi + fi + + if [ -n "${DHCP_TIME_OFFSET_SETS_TIMEZONE}" ] && + [[ "${DHCP_TIME_OFFSET_SETS_TIMEZONE}" = [yY1]* ]]; then + if [ -n "${new_time_offset}" ]; then + # DHCP option "time-offset" is requested by default and should be + # handled. The geographical zone abbreviation cannot be determined + # from the GMT offset, but the $ZONEINFO/Etc/GMT$offset file can be + # used - note: this disables DST. + ((z=new_time_offset/3600)) + ((hoursWest=$(printf '%+d' $z))) + + if (( $hoursWest < 0 )); then + # tzdata treats negative 'hours west' as positive 'gmtoff'! + ((hoursWest*=-1)) + fi + + tzfile=/usr/share/zoneinfo/Etc/GMT$(printf '%+d' ${hoursWest}) + if [ -e ${tzfile} ]; then + save_previous /etc/localtime + cp -fp ${tzfile} /etc/localtime + touch /etc/localtime + fi + fi + fi + + if [ ! "${PEERNTP}" = "no" ] && + [ -n "${new_ntp_servers}" ] && [ -e /etc/ntp.conf ]; then + save_previous /etc/ntp.conf + egrep -v '^server .* # added by /sbin/dhclient-script$'< ${SAVEDIR}/ntp.conf.predhclient.${interface} > /etc/ntp.conf + + for s in ${new_ntp_servers} ; do + echo "server ${s} # added by /sbin/dhclient-script" >> /etc/ntp.conf + done + + diff -q /etc/ntp.conf ${SAVEDIR}/ntp.conf.predhclient.${interface} >/dev/null 2>&1 + if [ $? -eq 1 ]; then + service ntpd condrestart >/dev/null 2>&1 + fi + fi +} + +get_prefix() { + ip="${1}" + nm="${2}" + + if [ -n "${ip}" -a -n "${nm}" ]; then + ipcalc -s -p ${ip} ${nm} | cut -d '=' -f 2 + fi +} + + +# +# ### MAIN +# + +if [ -x /etc/dhclient-enter-hooks ]; then + exit_status=0 + + # dhclient-enter-hooks can abort dhclient-script by setting + # the exit_status variable to a non-zero value + . /etc/dhclient-enter-hooks + if [ ${exit_status} -ne 0 ]; then + exit ${exit_status} + fi +fi + +if [ ! -r /etc/sysconfig/network-scripts/network-functions ]; then + echo "Missing /etc/sysconfig/network-scripts/network-functions, exiting." >&2 + exit 1 +fi + +if [ ! -r /etc/rc.d/init.d/functions ]; then + echo "Missing /etc/rc.d/init.d/functions, exiting." >&2 + exit 1 +fi + +. /etc/sysconfig/network-scripts/network-functions +. /etc/rc.d/init.d/functions + +if [ -f /etc/sysconfig/network ]; then + . /etc/sysconfig/network +fi + +if [ -f /etc/sysconfig/networking/network ]; then + . /etc/sysconfig/networking/network +fi + +CONFIG="/etc/sysconfig/network-scripts/ifcfg-${interface}" +need_config ${CONFIG} +source_config >/dev/null 2>&1 + +new_prefix="$(get_prefix ${new_ip_address} ${new_subnet_mask})" +old_prefix="$(get_prefix ${old_ip_address} ${new_subnet_mask})" +alias_prefix="$(get_prefix ${alias_ip_address} ${alias_subnet_mask})" + +case "${reason}" in + MEDIUM) + # Linux doesn't handle mediums (media) + exit_with_hooks 0 + ;; + + PREINIT) + if [ -n "${alias_ip_address}" ]; then + # Bring down alias interface, its routes will disappear too. + ip -family inet link set ${interface}:0 down + fi + + if [ "${keep_old_ip}" = "yes" ]; then + ip -family inet link set ${interface} up + else + ip -family inet addr flush dev ${interface} >/dev/null 2>&1 + ip -family inet link set ${interface} up + fi + + if [ -n "${DHCLIENT_DELAY}" ] && [ ${DHCLIENT_DELAY} -gt 0 ]; then + sleep ${DHCLIENT_DELAY} + fi + + exit_with_hooks 0 + ;; + + ARPCHECK|ARPSEND) + if [ -z "${new_ip_address}" ] || [ -z "${interface}" ] || + arping -q -f -c 2 -w 3 -D -I ${interface} ${new_ip_address}; then + exit_with_hooks 0 + else + exit_with_hooks 1 + fi + ;; + + BOUND|RENEW|REBIND|REBOOT) + dhconfig + exit_with_hooks 0 + ;; + + EXPIRE|FAIL|RELEASE|STOP) + # only restore config files if there are no other dhclient processes + # running (#306381) + any_other_clients="$(ps -eo pid,ppid,comm | grep dhclient | grep -v ${PPID})" + if [ -n "${any_other_clients}" ]; then + if [ -f ${SAVEDIR}/resolv.conf.predhclient.${interface} ]; then + change_resolv_conf ${SAVEDIR}/resolv.conf.predhclient.${interface} + rm -f ${SAVEDIR}/resolv.conf.predhclient.${interface} + fi + + if [ -n "${DHCP_TIME_OFFSET_SETS_TIMEZONE}" ] && + [[ "${DHCP_TIME_OFFSET_SETS_TIMEZONE}" = [yY1]* ]]; then + if [ -e ${SAVEDIR}/localtime.predhclient.${interface} ]; then + rm -f /etc/localtime + mv ${SAVEDIR}/localtime.predhclient.${interface} /etc/localtime + touch /etc/localtime + fi + fi + + if [ -f ${SAVEDIR}/ntp.conf.predhclient.${interface} ]; then + rm -f /etc/ntp.conf + mv -f ${SAVEDIR}/ntp.conf.predhclient.${interface} /etc/ntp.conf + service ntpd condrestart >/dev/null 2>&1 + fi + + if [ -f ${SAVEDIR}/yp.conf.predhclient.${interface} ]; then + rm -f /etc/yp.conf + mv -f ${SAVEDIR}/yp.conf.predhclient.${interface} /etc/yp.conf + if [ -x /etc/rc.d/init.d/ypbind ] && [ -r /var/run/ypbind.pid ]; then + service ypbind restart >/dev/null 2>&1 + fi + fi + fi + + if [ -x /etc/dhclient-${interface}-down-hooks ]; then + . /etc/dhclient-${interface}-down-hooks + elif [ -x /etc/dhclient-down-hooks ]; then + . /etc/dhclient-down-hooks + fi + + if [ -n "${alias_ip_address}" ]; then + # Turn off alias interface + ip -family inet link set ${interface}:0 down + fi + + if [ -n "${old_ip_address}" ]; then + # Shut down interface, which will delete routes and clear arp cache. + ip -family inet addr flush dev ${interface} >/dev/null 2>&1 + ip -family inet link set ${interface} down + fi + + if [ -n "${alias_ip_address}" ]; then + ip -family inet addr add ${alias_ip_address}/${alias_prefix} dev ${interface}:0 + ip -family inet route replace ${alias_ip_address}/32 ${interface}:0 + fi + + exit_with_hooks 0 + ;; + + TIMEOUT) + if [ -n "${new_routers}" ]; then + if [ -n "${alias_ip_address}" ]; then + ip -family inet addr flush dev ${interface}:0 >/dev/null 2>&1 + fi + + ip -family inet addr add ${new_ip_address}/${new_prefix} broadcast ${new_broadcast_address} dev ${interface} + set ${new_routers} + + if ping -q -c 1 -w 10 -I ${interface} ${1}; then + dhconfig + exit_with_hooks 0 + fi + + ip -family inet addr flush dev ${interface} >/dev/null 2>&1 + ip -family inet link set ${interface} down + exit_with_hooks 1 + else + exit_with_hooks 1 + fi + ;; + + *) + logmessage "unhandled state: ${reason}" + exit_with_hooks 1 + ;; +esac + +exit_with_hooks 0 diff --git a/pkgs/core/dhcp/dhcp.nm b/pkgs/core/dhcp/dhcp.nm new file mode 100644 index 0000000..0c85735 --- /dev/null +++ b/pkgs/core/dhcp/dhcp.nm @@ -0,0 +1,65 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = dhcp +PKG_VER = 4.1.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Daemons +PKG_URL = http://isc.org/products/DHCP/ +PKG_LICENSE = ISC +PKG_SUMMARY = Dynamic host configuration protocol software. + +define PKG_DESCRIPTION + DHCP (Dynamic Host Configuration Protocol) is a protocol which allows \ + individual devices on an IP network to get their own network \ + configuration information (IP address, subnetmask, broadcast address, \ + etc.) from a DHCP server. The overall purpose of DHCP is to make it \ + easier to administer a large network. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --sysconfdir=/etc \ + --with-srv-lease-file=/var/lib/dhcpd/dhcpd.leases \ + --with-cli-lease-file=/var/lib/dhclient/dhclient.leases \ + --with-srv-pid-file=/var/run/dhcpd.pid \ + --with-cli-pid-file=/var/run/dhclient.pid \ + --with-relay-pid-file=/var/run/dhcrelay.pid + +define STAGE_INSTALL_CMDS + rm -vf $(BUILDROOT)/etc/dhclient.conf + + # Move the client to /sbin, create dirs + # and remove the default config. + -mkdir -pv $(BUILDROOT)/sbin + mv -v $(BUILDROOT)/usr/sbin/dhclient $(BUILDROOT)/sbin/dhclient + + install -v -m 755 $(DIR_SOURCE)/dhclient-script \ + $(BUILDROOT)/sbin/dhclient-script + -mkdir -pv $(BUILDROOT)/var/lib/dhclient +endef diff --git a/pkgs/core/diffutils/diffutils.nm b/pkgs/core/diffutils/diffutils.nm new file mode 100644 index 0000000..3fec25c --- /dev/null +++ b/pkgs/core/diffutils/diffutils.nm @@ -0,0 +1,46 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = diffutils +PKG_VER = 2.8.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/diffutils/diffutils.html +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A GNU collection of diff utilities. + +define PKG_DESCRIPTION + Diffutils includes four utilities: diff, cmp, diff3 and sdiff. Diff \ + compares two files and shows the differences, line by line. The cmp \ + command shows the offset and line numbers where two files differ, or \ + cmp can show the characters that differ between the two files. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --mandir=/usr/share diff --git a/pkgs/core/diffutils/patches/diffutils-2.8.1-hardened_tmp-1.patch b/pkgs/core/diffutils/patches/diffutils-2.8.1-hardened_tmp-1.patch new file mode 100644 index 0000000..c335090 --- /dev/null +++ b/pkgs/core/diffutils/patches/diffutils-2.8.1-hardened_tmp-1.patch @@ -0,0 +1,31 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2006-10-09 +Initial Package Version: 2.8.7 +Upstream Status: Submitted - Partially accepted +Thread starts here: + http://sources.redhat.com/ml/bug-gnu-utils/2000-12/msg00163.html +Origin: ALT Linux / Openwall Owl Linux - diffutils-2.8.7-alt-tmp.diff +Description: This patch removes the more portable and less safe use of +tmpname(3), in preference of mkstemp(3). + +--- diffutils-2.8.7/src/sdiff.c.orig 2004-04-12 07:44:35 +0000 ++++ diffutils-2.8.7/src/sdiff.c 2005-05-17 12:58:44 +0000 +@@ -990,13 +990,13 @@ edit (struct line_filter *left, char con + int fd; + + if (tmpname) +- tmp = fopen (tmpname, "w"); +- else + { +- if ((fd = temporary_file ()) < 0) +- perror_fatal ("mkstemp"); +- tmp = fdopen (fd, "w"); ++ unlink (tmpname); ++ free (tmpname); + } ++ if ((fd = temporary_file ()) < 0) ++ perror_fatal ("mkstemp"); ++ tmp = fdopen (fd, "w"); + + if (! tmp) + perror_fatal (tmpname); diff --git a/pkgs/core/diffutils/patches/diffutils-2.8.1-i18n-1.patch b/pkgs/core/diffutils/patches/diffutils-2.8.1-i18n-1.patch new file mode 100644 index 0000000..488885b --- /dev/null +++ b/pkgs/core/diffutils/patches/diffutils-2.8.1-i18n-1.patch @@ -0,0 +1,802 @@ +Submitted by: Alexander E. Patrakov +Date: 2005-08-13 +Initial Package Version: 2.8.1 +Upstream Status: Unknown, but required for LSB >= 2.0 certification +Origin: RedHat +Description: Fixes treatment of whitespace in multibyte locales. + +--- diffutils-2.8.4/src/diff.c.i18n 2002-06-17 01:55:42.000000000 -0400 ++++ diffutils-2.8.4/src/diff.c 2002-11-16 18:41:37.000000000 -0500 +@@ -275,6 +275,13 @@ + re_set_syntax (RE_SYNTAX_GREP | RE_NO_POSIX_BACKTRACKING); + excluded = new_exclude (); + ++#ifdef HANDLE_MULTIBYTE ++ if (MB_CUR_MAX > 1) ++ lines_differ = lines_differ_multibyte; ++ else ++#endif ++ lines_differ = lines_differ_singlebyte; ++ + /* Decode the options. */ + + while ((c = getopt_long (argc, argv, shortopts, longopts, 0)) != -1) +--- diffutils-2.8.4/src/diff.h.i18n 2002-11-16 18:31:32.000000000 -0500 ++++ diffutils-2.8.4/src/diff.h 2002-11-16 18:48:58.000000000 -0500 +@@ -23,6 +23,19 @@ + #include "system.h" + #include <stdio.h> + ++/* For platform which support the ISO C amendement 1 functionality we ++ support user defined character classes. */ ++#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H ++/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ ++# include <wchar.h> ++# include <wctype.h> ++# if defined (HAVE_MBRTOWC) ++# define HANDLE_MULTIBYTE 1 ++# endif ++#endif ++ ++#define TAB_WIDTH 8 ++ + /* What kind of changes a hunk contains. */ + enum changes + { +@@ -350,7 +363,13 @@ + extern char const pr_program[]; + char *concat (char const *, char const *, char const *); + char *dir_file_pathname (char const *, char const *); +-bool lines_differ (char const *, char const *); ++ ++bool (*lines_differ) (char const *, char const *); ++bool lines_differ_singlebyte (char const *, char const *); ++#ifdef HANDLE_MULTIBYTE ++bool lines_differ_multibyte (char const *, char const *); ++#endif ++ + lin translate_line_number (struct file_data const *, lin); + struct change *find_change (struct change *); + struct change *find_reverse_change (struct change *); +--- diffutils-2.8.4/src/io.c.i18n 2002-06-11 02:06:32.000000000 -0400 ++++ diffutils-2.8.4/src/io.c 2002-11-16 18:57:30.000000000 -0500 +@@ -26,6 +26,7 @@ + #include <regex.h> + #include <setmode.h> + #include <xalloc.h> ++#include <assert.h> + + /* Rotate an unsigned value to the left. */ + #define ROL(v, n) ((v) << (n) | (v) >> (sizeof (v) * CHAR_BIT - (n))) +@@ -213,6 +214,28 @@ + + /* Split the file into lines, simultaneously computing the equivalence + class for each line. */ ++#ifdef HANDLE_MULTIBYTE ++# define MBC2WC(P, END, MBLENGTH, WC, STATE, CONVFAIL) \ ++do \ ++{ \ ++ mbstate_t state_bak = STATE; \ ++ \ ++ CONVFAIL = 0; \ ++ MBLENGTH = mbrtowc (&WC, P, END - (char const *)P, &STATE); \ ++ \ ++ switch (MBLENGTH) \ ++ { \ ++ case (size_t)-2: \ ++ case (size_t)-1: \ ++ STATE = state_bak; \ ++ ++CONVFAIL; \ ++ /* Fall through. */ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ } \ ++} \ ++while (0) ++#endif + + static void + find_and_hash_each_line (struct file_data *current) +@@ -239,12 +262,280 @@ + bool same_length_diff_contents_compare_anyway = + diff_length_compare_anyway | ignore_case; + ++#ifdef HANDLE_MULTIBYTE ++ wchar_t wc; ++ size_t mblength; ++ mbstate_t state; ++ int convfail; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++#endif ++ + while ((char const *) p < suffix_begin) + { + char const *ip = (char const *) p; + + h = 0; ++#ifdef HANDLE_MULTIBYTE ++ if (MB_CUR_MAX > 1) ++ { ++ wchar_t lo_wc; ++ char mbc[MB_LEN_MAX]; ++ mbstate_t state_wc; ++ ++ /* Hash this line until we find a newline. */ ++ switch (ignore_white_space) ++ { ++ case IGNORE_ALL_SPACE: ++ while (1) ++ { ++ if (*p == '\n') ++ { ++ ++p; ++ break; ++ } ++ ++ MBC2WC (p, suffix_begin, mblength, wc, state, convfail); ++ ++ if (convfail) ++ mbc[0] = *p++; ++ else if (!iswspace (wc)) ++ { ++ bool flag = 0; ++ ++ if (ignore_case) ++ { ++ lo_wc = towlower (wc); ++ if (lo_wc != wc) ++ { ++ flag = 1; ++ ++ p += mblength; ++ memset (&state_wc, '\0', sizeof(mbstate_t)); ++ mblength = wcrtomb (mbc, lo_wc, &state_wc); ++ ++ assert (mblength != (size_t)-1 && ++ mblength != (size_t)-2); ++ ++ mblength = (mblength < 1) ? 1 : mblength; ++ } ++ } ++ ++ if (!flag) ++ { ++ for (i = 0; i < mblength; i++) ++ mbc[i] = *p++; ++ } ++ } ++ else ++ { ++ p += mblength; ++ continue; ++ } ++ ++ for (i = 0; i < mblength; i++) ++ h = HASH (h, mbc[i]); ++ } ++ break; ++ ++ case IGNORE_SPACE_CHANGE: ++ while (1) ++ { ++ if (*p == '\n') ++ { ++ ++p; ++ break; ++ } + ++ MBC2WC (p, suffix_begin, mblength, wc, state, convfail); ++ ++ if (!convfail && iswspace (wc)) ++ { ++ while (1) ++ { ++ if (*p == '\n') ++ { ++ ++p; ++ goto hashing_done; ++ } ++ ++ p += mblength; ++ MBC2WC (p, suffix_begin, mblength, wc, state, convfail); ++ if (convfail || (!convfail && !iswspace (wc))) ++ break; ++ } ++ h = HASH (h, ' '); ++ } ++ ++ /* WC is now the first non-space. */ ++ if (convfail) ++ mbc[0] = *p++; ++ else ++ { ++ bool flag = 0; ++ ++ if (ignore_case) ++ { ++ lo_wc = towlower (wc); ++ if (lo_wc != wc) ++ { ++ flag = 1; ++ ++ p += mblength; ++ memset (&state_wc, '\0', sizeof(mbstate_t)); ++ mblength = wcrtomb (mbc, lo_wc, &state_wc); ++ ++ assert (mblength != (size_t)-1 && ++ mblength != (size_t)-2); ++ ++ mblength = (mblength < 1) ? 1 : mblength; ++ } ++ } ++ ++ if (!flag) ++ { ++ for (i = 0; i < mblength; i++) ++ mbc[i] = *p++; ++ } ++ } ++ ++ for (i = 0; i < mblength; i++) ++ h = HASH (h, mbc[i]); ++ } ++ break; ++ ++ case IGNORE_TAB_EXPANSION: ++ { ++ size_t column = 0; ++ ++ while (1) ++ { ++ if (*p == '\n') ++ { ++ ++p; ++ break; ++ } ++ ++ MBC2WC (p, suffix_begin, mblength, wc, state, convfail); ++ ++ if (convfail) ++ { ++ h = HASH (h, *p++); ++ ++column; ++ } ++ else ++ { ++ bool flag; ++ ++ switch (wc) ++ { ++ case L'\b': ++ column -= 0 < column; ++ h = HASH (h, '\b'); ++ ++p; ++ break; ++ ++ case L'\t': ++ { ++ int repetitions; ++ ++ repetitions = TAB_WIDTH - column % TAB_WIDTH; ++ column += repetitions; ++ do ++ h = HASH (h, ' '); ++ while (--repetitions != 0); ++ ++p; ++ } ++ break; ++ ++ case L'\r': ++ column = 0; ++ h = HASH (h, '\r'); ++ ++p; ++ break; ++ ++ default: ++ flag = 0; ++ column += wcwidth (wc); ++ if (ignore_case) ++ { ++ lo_wc = towlower (wc); ++ if (lo_wc != wc) ++ { ++ flag = 1; ++ p += mblength; ++ memset (&state_wc, '\0', sizeof(mbstate_t)); ++ mblength = wcrtomb (mbc, lo_wc, &state_wc); ++ ++ assert (mblength != (size_t)-1 && ++ mblength != (size_t)-2); ++ ++ mblength = (mblength < 1) ? 1 : mblength; ++ } ++ } ++ ++ if (!flag) ++ { ++ for (i = 0; i < mblength; i++) ++ mbc[i] = *p++; ++ } ++ ++ for (i = 0; i < mblength; i++) ++ h = HASH (h, mbc[i]); ++ } ++ } ++ } ++ } ++ break; ++ ++ default: ++ while (1) ++ { ++ if (*p == '\n') ++ { ++ ++p; ++ break; ++ } ++ ++ MBC2WC (p, suffix_begin, mblength, wc, state, convfail); ++ ++ if (convfail) ++ mbc[0] = *p++; ++ else ++ { ++ int flag = 0; ++ ++ if (ignore_case) ++ { ++ lo_wc = towlower (wc); ++ if (lo_wc != wc) ++ { ++ flag = 1; ++ p += mblength; ++ memset (&state_wc, '\0', sizeof(mbstate_t)); ++ mblength = wcrtomb (mbc, lo_wc, &state_wc); ++ ++ assert (mblength != (size_t)-1 && ++ mblength != (size_t)-2); ++ ++ mblength = (mblength < 1) ? 1 : mblength; ++ } ++ } ++ ++ if (!flag) ++ { ++ for (i = 0; i < mblength; i++) ++ mbc[i] = *p++; ++ } ++ } ++ ++ for (i = 0; i < mblength; i++) ++ h = HASH (h, mbc[i]); ++ } ++ } ++ } ++ else ++#endif + /* Hash this line until we find a newline. */ + if (ignore_case) + switch (ignore_white_space) +--- diffutils-2.8.4/src/side.c.i18n 2002-06-11 02:06:32.000000000 -0400 ++++ diffutils-2.8.4/src/side.c 2002-11-16 18:41:37.000000000 -0500 +@@ -73,11 +73,72 @@ + register size_t out_position = 0; + register char const *text_pointer = line[0]; + register char const *text_limit = line[1]; ++#if defined HAVE_WCHAR_H && defined HAVE_WCTYPE_H ++ unsigned char mbc[MB_LEN_MAX]; ++ wchar_t wc; ++ mbstate_t state, state_bak; ++ size_t mbc_pos, mblength; ++ int mbc_loading_flag = 0; ++ int wc_width; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++#endif + + while (text_pointer < text_limit) + { + register unsigned char c = *text_pointer++; + ++#if defined HAVE_WCHAR_H && defined HAVE_WCTYPE_H ++ if (MB_CUR_MAX > 1 && mbc_loading_flag) ++ { ++ mbc_loading_flag = 0; ++ state_bak = state; ++ mbc[mbc_pos++] = c; ++ ++process_mbc: ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); ++ ++ switch (mblength) ++ { ++ case (size_t)-2: /* Incomplete multibyte character. */ ++ mbc_loading_flag = 1; ++ state = state_bak; ++ break; ++ ++ case (size_t)-1: /* Invalid as a multibyte character. */ ++ if (in_position++ < out_bound) ++ { ++ out_position = in_position; ++ putc (mbc[0], out); ++ } ++ memmove (mbc, mbc + 1, --mbc_pos); ++ if (mbc_pos > 0) ++ { ++ mbc[mbc_pos] = '\0'; ++ goto process_mbc; ++ } ++ break; ++ ++ default: ++ wc_width = wcwidth (wc); ++ if (wc_width < 1) /* Unprintable multibyte character. */ ++ { ++ if (in_position <= out_bound) ++ fprintf (out, "%lc", (wint_t)wc); ++ } ++ else /* Printable multibyte character. */ ++ { ++ in_position += wc_width; ++ if (in_position <= out_bound) ++ { ++ out_position = in_position; ++ fprintf (out, "%lc", (wint_t)wc); ++ } ++ } ++ } ++ continue; ++ } ++#endif + switch (c) + { + case '\t': +@@ -135,8 +196,39 @@ + break; + + default: +- if (! ISPRINT (c)) +- goto control_char; ++#if defined HAVE_WCHAR_H && defined HAVE_WCTYPE_H ++ if (MB_CUR_MAX > 1) ++ { ++ memset (mbc, '\0', MB_LEN_MAX); ++ mbc_pos = 0; ++ mbc[mbc_pos++] = c; ++ state_bak = state; ++ ++ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); ++ ++ /* The value of mblength is always less than 2 here. */ ++ switch (mblength) ++ { ++ case (size_t)-2: /* Incomplete multibyte character. */ ++ state = state_bak; ++ mbc_loading_flag = 1; ++ continue; ++ ++ case (size_t)-1: /* Invalid as a multibyte character. */ ++ state = state_bak; ++ break; ++ ++ default: ++ if (! iswprint (wc)) ++ goto control_char; ++ } ++ } ++ else ++#endif ++ { ++ if (! ISPRINT (c)) ++ goto control_char; ++ } + /* falls through */ + case ' ': + if (in_position++ < out_bound) +--- diffutils-2.8.4/src/util.c.i18n 2002-06-11 02:06:32.000000000 -0400 ++++ diffutils-2.8.4/src/util.c 2002-11-16 18:41:37.000000000 -0500 +@@ -321,7 +321,7 @@ + Return nonzero if the lines differ. */ + + bool +-lines_differ (char const *s1, char const *s2) ++lines_differ_singlebyte (char const *s1, char const *s2) + { + register unsigned char const *t1 = (unsigned char const *) s1; + register unsigned char const *t2 = (unsigned char const *) s2; +@@ -450,6 +450,293 @@ + + return 1; + } ++ ++#ifdef HANDLE_MULTIBYTE ++# define MBC2WC(T, END, MBLENGTH, WC, STATE, CONVFAIL) \ ++do \ ++{ \ ++ mbstate_t bak = STATE; \ ++ \ ++ CONVFAIL = 0; \ ++ MBLENGTH = mbrtowc (&WC, T, END - T, &STATE); \ ++ \ ++ switch (MBLENGTH) \ ++ { \ ++ case (size_t)-2: \ ++ case (size_t)-1: \ ++ STATE = bak; \ ++ ++CONVFAIL; \ ++ /* Fall through. */ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ } \ ++} \ ++while (0) ++ ++bool ++lines_differ_multibyte (char const *s1, char const *s2) ++{ ++ unsigned char const *end1, *end2; ++ unsigned char c1, c2; ++ wchar_t wc1, wc2, wc1_bak, wc2_bak; ++ size_t mblen1, mblen2; ++ mbstate_t state1, state2, state1_bak, state2_bak; ++ int convfail1, convfail2, convfail1_bak, convfail2_bak; ++ ++ unsigned char const *t1 = (unsigned char const *) s1; ++ unsigned char const *t2 = (unsigned char const *) s2; ++ unsigned char const *t1_bak, *t2_bak; ++ size_t column = 0; ++ ++ if (ignore_white_space == IGNORE_NO_WHITE_SPACE && !ignore_case) ++ { ++ while (*t1 != '\n') ++ if (*t1++ != * t2++) ++ return 1; ++ return 0; ++ } ++ ++ memset (&state1, '\0', sizeof (mbstate_t)); ++ memset (&state2, '\0', sizeof (mbstate_t)); ++ ++ end1 = s1 + strlen (s1); ++ end2 = s2 + strlen (s2); ++ ++ while (1) ++ { ++ c1 = *t1; ++ c2 = *t2; ++ MBC2WC (t1, end1, mblen1, wc1, state1, convfail1); ++ MBC2WC (t2, end2, mblen2, wc2, state2, convfail2); ++ ++ /* Test for exact char equality first, since it's a common case. */ ++ if (convfail1 ^ convfail2) ++ break; ++ else if (convfail1 && convfail2 && c1 != c2) ++ break; ++ else if (!convfail1 && !convfail2 && wc1 != wc2) ++ { ++ switch (ignore_white_space) ++ { ++ case IGNORE_ALL_SPACE: ++ /* For -w, just skip past any white space. */ ++ while (1) ++ { ++ if (convfail1) ++ break; ++ else if (wc1 == L'\n' || !iswspace (wc1)) ++ break; ++ ++ t1 += mblen1; ++ c1 = *t1; ++ MBC2WC (t1, end1, mblen1, wc1, state1, convfail1); ++ } ++ ++ while (1) ++ { ++ if (convfail2) ++ break; ++ else if (wc2 == L'\n' || !iswspace (wc2)) ++ break; ++ ++ t2 += mblen2; ++ c2 = *t2; ++ MBC2WC (t2, end2, mblen2, wc2, state2, convfail2); ++ } ++ t1 += mblen1; ++ t2 += mblen2; ++ break; ++ ++ case IGNORE_SPACE_CHANGE: ++ /* For -b, advance past any sequence of white space in ++ line 1 and consider it just one space, or nothing at ++ all if it is at the end of the line. */ ++ if (wc1 != L'\n' && iswspace (wc1)) ++ { ++ size_t mblen_bak; ++ mbstate_t state_bak; ++ ++ do ++ { ++ t1 += mblen1; ++ mblen_bak = mblen1; ++ state_bak = state1; ++ MBC2WC (t1, end1, mblen1, wc1, state1, convfail1); ++ } ++ while (!convfail1 && (wc1 != L'\n' && iswspace (wc1))); ++ ++ state1 = state_bak; ++ mblen1 = mblen_bak; ++ t1 -= mblen1; ++ convfail1 = 0; ++ wc1 = L' '; ++ } ++ ++ /* Likewise for line 2. */ ++ if (wc2 != L'\n' && iswspace (wc2)) ++ { ++ size_t mblen_bak; ++ mbstate_t state_bak; ++ ++ do ++ { ++ t2 += mblen2; ++ mblen_bak = mblen2; ++ state_bak = state2; ++ MBC2WC (t2, end2, mblen2, wc2, state2, convfail2); ++ } ++ while (!convfail2 && (wc2 != L'\n' && iswspace (wc2))); ++ ++ state2 = state_bak; ++ mblen2 = mblen_bak; ++ t2 -= mblen2; ++ convfail2 = 0; ++ wc2 = L' '; ++ } ++ ++ if (wc1 != wc2) ++ { ++ if (wc2 == L' ' && wc1 != L'\n' && ++ t1 > (unsigned char const *)s1 && ++ !convfail1_bak && iswspace (wc1_bak)) ++ { ++ t1 = t1_bak; ++ wc1 = wc1_bak; ++ state1 = state1_bak; ++ convfail1 = convfail1_bak; ++ continue; ++ } ++ if (wc1 == L' ' && wc2 != L'\n' ++ && t2 > (unsigned char const *)s2 ++ && !convfail2_bak && iswspace (wc2_bak)) ++ { ++ t2 = t2_bak; ++ wc2 = wc2_bak; ++ state2 = state2_bak; ++ convfail2 = convfail2_bak; ++ continue; ++ } ++ } ++ ++ t1_bak = t1; t2_bak = t2; ++ wc1_bak = wc1; wc2_bak = wc2; ++ state1_bak = state1; state2_bak = state2; ++ convfail1_bak = convfail1; convfail2_bak = convfail2; ++ ++ if (wc1 == L'\n') ++ wc1 = L' '; ++ else ++ t1 += mblen1; ++ ++ if (wc2 == L'\n') ++ wc2 = L' '; ++ else ++ t2 += mblen2; ++ ++ break; ++ ++ case IGNORE_TAB_EXPANSION: ++ if ((wc1 == L' ' && wc2 == L'\t') ++ || (wc1 == L'\t' && wc2 == L' ')) ++ { ++ size_t column2 = column; ++ ++ while (1) ++ { ++ if (convfail1) ++ { ++ ++t1; ++ break; ++ } ++ else if (wc1 == L' ') ++ column++; ++ else if (wc1 == L'\t') ++ column += TAB_WIDTH - column % TAB_WIDTH; ++ else ++ { ++ t1 += mblen1; ++ break; ++ } ++ ++ t1 += mblen1; ++ c1 = *t1; ++ MBC2WC (t1, end1, mblen1, wc1, state1, convfail1); ++ } ++ ++ while (1) ++ { ++ if (convfail2) ++ { ++ ++t2; ++ break; ++ } ++ else if (wc2 == L' ') ++ column2++; ++ else if (wc2 == L'\t') ++ column2 += TAB_WIDTH - column2 % TAB_WIDTH; ++ else ++ { ++ t2 += mblen2; ++ break; ++ } ++ ++ t2 += mblen2; ++ c2 = *t2; ++ MBC2WC (t2, end2, mblen2, wc2, state2, convfail2); ++ } ++ ++ if (column != column2) ++ return 1; ++ } ++ else ++ { ++ t1 += mblen1; ++ t2 += mblen2; ++ } ++ break; ++ ++ case IGNORE_NO_WHITE_SPACE: ++ t1 += mblen1; ++ t2 += mblen2; ++ break; ++ } ++ ++ /* Lowercase all letters if -i is specified. */ ++ if (ignore_case) ++ { ++ if (!convfail1) ++ wc1 = towlower (wc1); ++ if (!convfail2) ++ wc2 = towlower (wc2); ++ } ++ ++ if (convfail1 ^ convfail2) ++ break; ++ else if (convfail1 && convfail2 && c1 != c2) ++ break; ++ else if (!convfail1 && !convfail2 && wc1 != wc2) ++ break; ++ } ++ else ++ { ++ t1_bak = t1; t2_bak = t2; ++ wc1_bak = wc1; wc2_bak = wc2; ++ state1_bak = state1; state2_bak = state2; ++ convfail1_bak = convfail1; convfail2_bak = convfail2; ++ ++ t1 += mblen1; t2 += mblen2; ++ } ++ ++ if (!convfail1 && wc1 == L'\n') ++ return 0; ++ ++ column += convfail1 ? 1 : ++ (wc1 == L'\t') ? TAB_WIDTH - column % TAB_WIDTH : wcwidth (wc1); ++ } ++ ++ return 1; ++} ++#endif + + /* Find the consecutive changes at the start of the script START. + Return the last link before the first gap. */ diff --git a/pkgs/core/directfb/directfb.nm b/pkgs/core/directfb/directfb.nm new file mode 100644 index 0000000..cc4def0 --- /dev/null +++ b/pkgs/core/directfb/directfb.nm @@ -0,0 +1,67 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = DirectFB +PKG_VER = 1.4.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Graphics +PKG_URL = http://www.directfb.org/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = Graphics abstraction library for the Linux Framebuffer Device. + +PKG_DEPS += freetype libjpeg libpng sysfsutils zlib + +define PKG_DESCRIPTION + DirectFB is a thin library that provides hardware graphics acceleration, \ + input device handling and abstraction, integrated windowing system with \ + support for translucent windows and multiple display layers on top of the \ + Linux Framebuffer Device. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +# XXX Needs a double check +ifneq "$(TARGET)" "i686" +ifneq "$(TARGET)" "i586" +ifneq "$(TARGET)" "i486" + CONFIGURE_ARGS = --disable-mmx --disable-sse +endif +endif +endif + +CONFIGURE_OPTIONS += \ + --disable-x11 \ + --enable-sdl \ + --enable-video4linux2 \ + --enable-libv412 \ + --enable-zlib \ + $(CONFIGURE_ARGS) + +define STAGE_INSTALL_CMDS + find $(BUILDROOT)/usr/lib/directfb*/ -name "*.la" -exec rm -vf {} ; +endef diff --git a/pkgs/core/dmraid/dmraid.nm b/pkgs/core/dmraid/dmraid.nm new file mode 100644 index 0000000..16df42d --- /dev/null +++ b/pkgs/core/dmraid/dmraid.nm @@ -0,0 +1,66 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = dmraid +PKG_VER = 1.0.0.rc15 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://people.redhat.com/heinzm/sw/dmraid +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Device-mapper RAID tool and library. + +PKG_DEPS += lvm2 + +define PKG_DESCRIPTION + DMRAID supports RAID device discovery, RAID set activation, creation, \ + removal, rebuild and display of properties for ATARAID/DDF1 metadata on \ + Linux >= 2.4 using device-mapper. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +DIR_APP = $(DIR_SRC)/$(PKG_NAME)/$(PKG_VER) +PARALLELISMFLAGS = + +CONFIGURE_OPTIONS += \ + --sbindir=/sbin \ + --libdir=/lib \ + --disable-static \ + --disable-static_link + +define STAGE_BUILD_CMDS + cd $(DIR_APP) && make -C lib libdmraid.so +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) sbindir=$(BUILDROOT)/sbin + -mkdir -pv $(BUILDROOT)/{,usr}/lib + cd $(DIR_APP) && install -v -m 755 lib/libdmraid.so \ + $(BUILDROOT)/lib/libdmraid.so.$(PKG_VER) + ln -svf ../../lib/libdmraid.so.$(PKG_VER) $(BUILDROOT)/usr/lib/libdmraid.so +endef diff --git a/pkgs/core/dosfstools/dosfstools.nm b/pkgs/core/dosfstools/dosfstools.nm new file mode 100644 index 0000000..c855c59 --- /dev/null +++ b/pkgs/core/dosfstools/dosfstools.nm @@ -0,0 +1,56 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = dosfstools +PKG_VER = 3.0.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://www.daniel-baumann.ch/software/dosfstools/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = Utilities for making and checking MS-DOS FAT filesystems on Linux. + +define PKG_DESCRIPTION + The dosfstools package includes the mkdosfs and dosfsck utilities, \ + which respectively make and check MS-DOS FAT filesystems on hard \ + drives or on floppies. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install-bin DESTDIR=$(BUILDROOT) \ + PREFIX=/usr SBINDIR=/sbin +endef diff --git a/pkgs/core/dracut/dracut.nm b/pkgs/core/dracut/dracut.nm new file mode 100644 index 0000000..78cd111 --- /dev/null +++ b/pkgs/core/dracut/dracut.nm @@ -0,0 +1,58 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = dracut +PKG_VER = 004 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Boot +PKG_URL = http://sourceforge.net/apps/trac/dracut/wiki +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Initramfs generator using udev. + +PKG_DEPS += bash bzip2 cpio coreutils dmraid e2fsprogs gzip kbd lvm2 \ + mdadm udev which + +define PKG_DESCRIPTION + dracut is a new, event-driven initramfs infrastructure based around udev. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +define STAGE_PREPARE_CMDS + # All check scripts must be executeable + cd $(DIR_APP) && chmod 0755 modules.d/*/check +endef + +define STAGE_BUILD + cd $(DIR_APP) && make WITH_SWITCH_ROOT=1 +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) WITH_SWITCH_ROOT=1 \ + sbindir=/sbin sysconfdir=/etc mandir=/usr/share/man +endef diff --git a/pkgs/core/dracut/patches/dracut-004-emergency.patch b/pkgs/core/dracut/patches/dracut-004-emergency.patch new file mode 100644 index 0000000..4f1d67f --- /dev/null +++ b/pkgs/core/dracut/patches/dracut-004-emergency.patch @@ -0,0 +1,19 @@ +commit 5db587d7c118afc47b50b4872100b508c84646fa +Author: Harald Hoyer <harald@redhat.com> +Date: Wed Jan 20 16:04:55 2010 +0100 + + init: fixed emergency_shell argument parsing + +diff --git a/modules.d/99base/init b/modules.d/99base/init +index 8dc00a9..ab033a7 100755 +--- a/modules.d/99base/init ++++ b/modules.d/99base/init +@@ -35,7 +35,7 @@ wait_for_loginit() + + emergency_shell() + { +- if [ $1 = "-n" ]; then ++ if [ "$1" = "-n" ]; then + _rdshell_name=$2 + shift 2 + else diff --git a/pkgs/core/dracut/patches/dracut-004-firmware.patch b/pkgs/core/dracut/patches/dracut-004-firmware.patch new file mode 100644 index 0000000..b838f83 --- /dev/null +++ b/pkgs/core/dracut/patches/dracut-004-firmware.patch @@ -0,0 +1,19 @@ +diff -up dracut-004/modules.d/95udev-rules/install.fw dracut-004/modules.d/95udev-rules/install +--- dracut-004/modules.d/95udev-rules/install.fw 2010-01-29 16:40:11.000000000 +0100 ++++ dracut-004/modules.d/95udev-rules/install 2010-01-29 16:40:25.000000000 +0100 +@@ -15,7 +15,6 @@ inst_rules "$moddir/01-ignore.rules" + + # for firmware loading + inst_rules 50-firmware.rules +-dracut_install /lib/udev/firmware.sh + dracut_install cat uname + + if [ ! -x /lib/udev/vol_id ]; then +@@ -31,6 +30,7 @@ ata_id \ + cdrom_id \ + create_floppy_devices \ + edd_id \ ++firmware \ + firmware.sh \ + fw_unit_symlinks.sh \ + hid2hci \ diff --git a/pkgs/core/dvdrtools/dvdrtools.nm b/pkgs/core/dvdrtools/dvdrtools.nm new file mode 100644 index 0000000..c9f2c17 --- /dev/null +++ b/pkgs/core/dvdrtools/dvdrtools.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = dvdrtools +PKG_VER = 0.2.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://savannah.nongnu.org/projects/dvdrtools/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A set of command line programs that allows to record media. + +define PKG_DESCRIPTION + dvdrtools is a fork of cdrtools/cdrecord with support for writing to DVDs. \ + While its primary purpose is writing data DVDs, it includes basic support \ + for mastering video DVDs. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --disable-static \ + --mandir=/usr/share/man + +define STAGE_TEST + cd $(DIR_APP) && make check +endef diff --git a/pkgs/core/e2fsprogs/e2fsprogs.nm b/pkgs/core/e2fsprogs/e2fsprogs.nm new file mode 100644 index 0000000..fca6b59 --- /dev/null +++ b/pkgs/core/e2fsprogs/e2fsprogs.nm @@ -0,0 +1,100 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = e2fsprogs +PKG_VER = 1.41.8 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://e2fsprogs.sourceforge.net/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = Utilities for managing the extended (ext2/ext3/ext4) filesystems. + +PKG_PACKAGES += $(PKG_NAME_REAL)-devel + +define PKG_DESCRIPTION + The e2fsprogs package contains a number of utilities for creating, \ + checking, modifying, and correcting any inconsistencies in second \ + and third extended (ext2/ext3) filesystems. +endef + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += util-linux-ng + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + -mkdir -pv $(DIR_APP)/build + + # Fix DT_TEXTREL in e2fsprogs libraries. --disable-shared and + # --with-pic are not options in E2fsprogs: + cd $(DIR_APP) && \ + find lib/ -name Makefile.in -exec sed -i "s/$$(ALL_CFLAGS)/& -fPIC/" {} ; + + # At run time libblkid looks for the BLKID_DEBUG environment variable to + # enable debbugging, with getenv(3). Some suid-root programs use libblkid, + # such as mount(1). e2fsprogs includes a safe_getenv() function, which calls + # __secure_getenv() from libc. __secure_getenv will restrict some environment + # variables if the user is suid or sgid. So, this command replaces getenv() + # with safe_getenv(): + cd $(DIR_APP) && sed \ + -e "s/getenv("BLKID_DEBUG")/safe_getenv("BLKID_DEBUG")/" \ + -i lib/blkid/cache.c +endef + +define STAGE_BUILD + cd $(DIR_APP)/build && \ + ../configure \ + --prefix=/usr \ + --with-root-prefix="" \ + --enable-elf-shlibs \ + --disable-libblkid \ + --disable-fsck \ + --disable-uuidd \ + --disable-libuuid + + cd $(DIR_APP)/build && make $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + cd $(DIR_APP)/build && make check +endef + +define STAGE_INSTALL + cd $(DIR_APP)/build && make install DESTDIR=$(BUILDROOT) + cd $(DIR_APP)/build && make install-libs DESTDIR=$(BUILDROOT) + + ln -svf ../../lib/libcom_err.so.2 $(BUILDROOT)/usr/lib/libcom_err.so + ln -svf ../../lib/libe2p.so.2 $(BUILDROOT)/usr/lib/libe2p.so + ln -svf ../../lib/libext2fs.so.2 $(BUILDROOT)/usr/lib/libext2fs.so + ln -svf ../../lib/libss.so.2 $(BUILDROOT)/usr/lib/libss.so + ln -svf ../../lib/libuuid.so.1 $(BUILDROOT)/usr/lib/libuuid.so +endef diff --git a/pkgs/core/ebtables/ebtables.nm b/pkgs/core/ebtables/ebtables.nm new file mode 100644 index 0000000..4b889b2 --- /dev/null +++ b/pkgs/core/ebtables/ebtables.nm @@ -0,0 +1,67 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = ebtables +PKG_VER = v2.0.9-1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://ebtables.sourceforge.net/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Ethernet Bridge frame table administration tool. + +define PKG_DESCRIPTION + Ethernet bridge tables is a firewalling tool to transparently filter network \ + traffic passing a bridge. The filtering possibilities are limited to link \ + layer filtering and some basic filtering on higher network layers. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CFLAGS += -fno-stack-protector # XXX Why do we need this? + +define QUALITY_AGENT_WHITELIST_RPATH + /sbin/ebtables-restore \ + /sbin/ebtables +endef + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" BINDIR="/sbin" \ + LIBDIR="/lib/ebtables" MANDIR="/usr/share/man" $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/etc/{init.d,sysconfig} + cd $(DIR_APP) && make install DESTDIR="$(BUILDROOT)" BINDIR="/sbin" \ + LIBDIR="/lib/ebtables" MANDIR="/usr/share/man" INITDIR="/etc/init.d" + + rm -vfr $(BUILDROOT)/etc/{init.d,sysconfig} +endef diff --git a/pkgs/core/etherwake/etherwake.nm b/pkgs/core/etherwake/etherwake.nm new file mode 100644 index 0000000..35e5bbf --- /dev/null +++ b/pkgs/core/etherwake/etherwake.nm @@ -0,0 +1,56 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = etherwake +PKG_VER = 1.09 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = +PKG_LICENSE = +PKG_SUMMARY = Can wake up sleeping PCs by WOL. + +define PKG_DESCRIPTION + A little tool to send magic Wake-on-LAN packets You can wake up WOL \ + compliant Computers which have been powered down to sleep mode or start \ + WOL compliant Computers with a BIOS feature. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -e "s/^CFLAGS.*/CFLAGS = $(CFLAGS)/" -i Makefile +endef + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/usr/sbin + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) +endef diff --git a/pkgs/core/etherwake/patches/etherwake-1.09-install.patch b/pkgs/core/etherwake/patches/etherwake-1.09-install.patch new file mode 100644 index 0000000..77588eb --- /dev/null +++ b/pkgs/core/etherwake/patches/etherwake-1.09-install.patch @@ -0,0 +1,10 @@ +diff -Nur old/Makefile new/Makefile +--- old/Makefile 2006-06-08 09:14:23.000000000 +0200 ++++ new/Makefile 2010-02-23 23:07:09.000000000 +0100 +@@ -1,5 +1,5 @@ + CFLAGS = -Wall +-INSTALL = /usr/bin/install ++INSTALL = install + CC = gcc + + all: diff --git a/pkgs/core/eventlog/eventlog.nm b/pkgs/core/eventlog/eventlog.nm new file mode 100644 index 0000000..b13f9c8 --- /dev/null +++ b/pkgs/core/eventlog/eventlog.nm @@ -0,0 +1,53 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = eventlog +PKG_VER = 0.2.9 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.balabit.com/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Eventlog is an API for syslog-ng. + +define PKG_DESCRIPTION + A new API to format and send structured log messages. It supports multiple \ + message representations (plain, XML attributes and XML tags) and multiple \ + output methods (local syslogd). +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --libdir=/lib + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/usr/lib + rm -vf $(BUILDROOT)/lib/libevtlog.so + ln -svf ../../lib/libevtlog.so.0 $(BUILDROOT)/usr/lib/libevtlog.so + + mv -v $(BUILDROOT)/lib/pkgconfig $(BUILDROOT)/usr/lib/ +endef diff --git a/pkgs/core/expat/expat.nm b/pkgs/core/expat/expat.nm new file mode 100644 index 0000000..e4e7ada --- /dev/null +++ b/pkgs/core/expat/expat.nm @@ -0,0 +1,54 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = expat +PKG_VER = 2.0.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.libexpat.org/ +PKG_LICENSE = MIT +PKG_SUMMARY = An XML parser library. + +define PKG_DESCRIPTION + This is expat, the C library for parsing XML, written by James Clark. Expat \ + is a stream oriented XML parser. This means that you register handlers with \ + the parser prior to starting the parse. These handlers are called when the \ + parser discovers the associated structures in the document being parsed. A \ + start tag is an example of the kind of structures for which you may \ + register handlers. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --libdir=/lib --mandir=/usr/share + +define STAGE_INSTALL_CMDS + rm -vf $(BUILDROOT)/lib/libexpat.so + -mkdir -pv $(BUILDROOT)/usr/lib + ln -svf ../../lib/libexpat.so.1 $(BUILDROOT)/usr/lib/libexpat.so +endef diff --git a/pkgs/core/expect/expect.nm b/pkgs/core/expect/expect.nm new file mode 100644 index 0000000..c8c6048 --- /dev/null +++ b/pkgs/core/expect/expect.nm @@ -0,0 +1,67 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = expect +PKG_VER = 5.43 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Languages +PKG_URL = http://expect.nist.gov/ +PKG_LICENSE = Public Domain +PKG_SUMMARY = A program-script interaction and testing utility. + +PKG_BUILD_DEPS+= autoconf automake +PKG_DEPS += tcl + +define PKG_DESCRIPTION + xpect is a tcl application for automating and testing \ + interactive applications such as telnet, ftp, passwd, fsck, \ + rlogin, tip, etc. Expect makes it easy for a script to \ + control another program and interact with it. +endef + +PKG_TARBALL = $(THISAPP).0.tar.gz + +CONFIGURE_OPTIONS = \ + --mandir=/usr/share/man \ + --with-tcl=/usr/lib \ + --with-tclinclude=/usr/include/ \ + --with-x=no \ + --enable-shared + +define STAGE_TEST + cd $(DIR_APP) && make test +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install INSTALL_ROOT=$(BUILDROOT) + + # remove cryptdir/decryptdir, as Linux has no crypt command + rm -f $(BUILDROOT)/usr/bin/{cryptdir,decryptdir} + rm -f $(BUILDROOT)/usr/share/man1/{cryptdir,decryptdir}.1* + rm -f $(BUILDROOT)/usr/bin/autopasswd +endef diff --git a/pkgs/core/expect/patches/expect-5.32.2-random.patch b/pkgs/core/expect/patches/expect-5.32.2-random.patch new file mode 100644 index 0000000..94afc42 --- /dev/null +++ b/pkgs/core/expect/patches/expect-5.32.2-random.patch @@ -0,0 +1,19 @@ +diff -up expect-5.43/example/mkpasswd.random expect-5.43/example/mkpasswd +--- expect-5.43/example/mkpasswd.random 2004-12-07 00:38:21.000000000 +0100 ++++ expect-5.43/example/mkpasswd 2008-09-25 12:27:19.000000000 +0200 +@@ -92,7 +92,14 @@ proc insert {pvar char} { + } + + proc rand {m} { +- expr {int($m*rand())} ++ set device /dev/urandom ;# /dev/random can block ++ set fileId [open $device r] ++ binary scan [read $fileId 4] i1 number ++ set clipped [expr $number % $m] ++# puts "number is $number" ++# puts "clipped is $clipped" ++ close $fileId ++ return $clipped + } + + # choose left or right starting hand diff --git a/pkgs/core/expect/patches/expect-5.38.0-lib-spec.patch b/pkgs/core/expect/patches/expect-5.38.0-lib-spec.patch new file mode 100644 index 0000000..803f858 --- /dev/null +++ b/pkgs/core/expect/patches/expect-5.38.0-lib-spec.patch @@ -0,0 +1,12 @@ +diff -up expect-5.43/configure.in.lib-spec expect-5.43/configure.in +--- expect-5.43/configure.in.lib-spec 2005-02-08 02:45:06.000000000 +0100 ++++ expect-5.43/configure.in 2008-09-25 12:23:26.000000000 +0200 +@@ -1141,7 +1141,7 @@ if test $ac_cv_sys_long_file_names = no; + fi + + EXP_BUILD_LIB_SPEC="-L`pwd` -lexpect${EXP_LIB_VERSION}${DBGX}" +-EXP_LIB_SPEC="-L${INSTALL_ROOT}${exec_prefix}/lib -lexpect${EXP_LIB_VERSION}${DBGX}" ++EXP_LIB_SPEC="-L${libdir}/../.. -lexpect${EXP_LIB_VERSION}${DBGX}" + EXP_UNSHARED_LIB_FILE=libexpect${EXP_LIB_VERSION}${DBGX}.a + + # The TCL_SHARED_LIB_SUFFIX macro below relies on the DBGX macro, diff --git a/pkgs/core/expect/patches/expect-5.39.0-libdir.patch b/pkgs/core/expect/patches/expect-5.39.0-libdir.patch new file mode 100644 index 0000000..8546c90 --- /dev/null +++ b/pkgs/core/expect/patches/expect-5.39.0-libdir.patch @@ -0,0 +1,12 @@ +diff -up expect-5.43/Makefile.in.libdir expect-5.43/Makefile.in +--- expect-5.43/Makefile.in.libdir 2004-05-07 20:10:30.000000000 +0200 ++++ expect-5.43/Makefile.in 2008-09-25 12:24:08.000000000 +0200 +@@ -317,7 +317,7 @@ EXP_AND_TK_LIBS = $(LDFLAGS) @EXP_AND_TK + CFLAGS_INT = $(MH_CFLAGS) $(CPPFLAGS) $(XCFLAGS) + + LIB_INSTALL_DIR = $(tcl_libdir) +-LIB_RUNTIME_DIR = $(tcl_libdir) ++LIB_RUNTIME_DIR = $(subst $(INSTALL_ROOT),,$(tcl_libdir)) + # I don't understand why Tcl splits these up, but it does. LIB_RUNTIME_DIR + # can appear as part of the LD_SEARCH_FLAGS inherited by configure. + diff --git a/pkgs/core/expect/patches/expect-5.43.0-override_default_prefix.patch b/pkgs/core/expect/patches/expect-5.43.0-override_default_prefix.patch new file mode 100644 index 0000000..54fe1e8 --- /dev/null +++ b/pkgs/core/expect/patches/expect-5.43.0-override_default_prefix.patch @@ -0,0 +1,12 @@ +diff -Nur expect-5.43_old/configure expect-5.43_new/configure +--- expect-5.43_old/configure 2010-03-10 10:11:41.000000000 +0100 ++++ expect-5.43_new/configure 2010-03-10 10:12:01.000000000 +0100 +@@ -9,7 +9,7 @@ + + # Defaults: + ac_help= +-ac_default_prefix=/usr/local ++ac_default_prefix=/usr + # Any additions from configure.in: + ac_help="$ac_help + --enable-threads build with threads (not supported)" diff --git a/pkgs/core/expect/patches/expect-5.43.0-spawn-1.patch b/pkgs/core/expect/patches/expect-5.43.0-spawn-1.patch new file mode 100644 index 0000000..c2033c0 --- /dev/null +++ b/pkgs/core/expect/patches/expect-5.43.0-spawn-1.patch @@ -0,0 +1,217 @@ +Submitted By: LFS Book <lfs-book@linuxfromscratch.org> +Date: 2003-10-05 +Initial Package Version: 5.38 +Origin: Redhat RPM (Patch by HJ Lu) +Description: NA +diff -uNr expect-5.38.orig/exp_chan.c expect-5.38/exp_chan.c +--- expect-5.38.orig/exp_chan.c 2002-02-12 13:00:55.000000000 +1100 ++++ expect-5.38/exp_chan.c 2003-03-01 10:36:18.000000000 +1100 +@@ -519,6 +519,7 @@ + esPtr->buffer = Tcl_NewStringObj("",0); + Tcl_IncrRefCount(esPtr->buffer); + esPtr->umsize = exp_default_match_max; ++ esPtr->umsize_changed = exp_default_match_max_changed; + /* this will reallocate object with an appropriate sized buffer */ + expAdjust(esPtr); + +diff -uNr expect-5.38.orig/exp_command.h expect-5.38/exp_command.h +--- expect-5.38.orig/exp_command.h 2002-04-08 08:57:20.000000000 +1000 ++++ expect-5.38/exp_command.h 2003-03-01 10:36:18.000000000 +1100 +@@ -25,6 +25,7 @@ + EXTERN char * exp_get_var _ANSI_ARGS_((Tcl_Interp *,char *)); + + EXTERN int exp_default_match_max; ++EXTERN int exp_default_match_max_changed; + EXTERN int exp_default_parity; + EXTERN int exp_default_rm_nulls; + +@@ -97,6 +98,7 @@ + int msize; /* # of bytes that buffer can hold (max) */ + int umsize; /* # of bytes (min) that is guaranteed to match */ + /* this comes from match_max command */ ++ int umsize_changed; /* is umsize changed by user? */ + int printed; /* # of bytes written to stdout (if logging on) */ + /* but not actually returned via a match yet */ + int echoed; /* additional # of bytes (beyond "printed" above) */ +diff -uNr expect-5.38.orig/expect.c expect-5.38/expect.c +--- expect-5.38.orig/expect.c 2002-04-08 09:00:33.000000000 +1000 ++++ expect-5.38/expect.c 2003-03-01 10:36:18.000000000 +1100 +@@ -41,8 +41,17 @@ + #include "tcldbg.h" + #endif + ++/* The initial length is 2000. We increment it by 2000. The maximum ++ is 8MB (0x800000). */ ++#define EXP_MATCH_MAX 2000 ++#define EXP_MATCH_INC 2000 ++#define EXP_MATCH_STEP_LIMIT 0x700000 ++#define EXP_MATCH_LIMIT 0x800000 ++#define EXP_MATCH_LIMIT_QUOTE "0x800000" ++ + /* initial length of strings that we can guarantee patterns can match */ +-int exp_default_match_max = 2000; ++int exp_default_match_max = EXP_MATCH_MAX; ++int exp_default_match_max_changed = 0; + #define INIT_EXPECT_TIMEOUT_LIT "10" /* seconds */ + #define INIT_EXPECT_TIMEOUT 10 /* seconds */ + int exp_default_parity = TRUE; +@@ -1618,6 +1627,76 @@ + return newsize; + } + ++/* returns # of bytes until we see a newline at the end or EOF. */ ++/*ARGSUSED*/ ++static int ++expReadNewLine(interp,esPtr,save_flags) /* INTL */ ++Tcl_Interp *interp; ++ExpState *esPtr; ++int save_flags; ++{ ++ int size; ++ int exp_size; ++ int full_size; ++ int count; ++ char *str; ++ ++ count = 0; ++ for (;;) { ++ exp_size = expSizeGet(esPtr); ++ ++ /* When we reach the limit, we will only read one char at a ++ time. */ ++ if (esPtr->umsize >= EXP_MATCH_STEP_LIMIT) ++ size = TCL_UTF_MAX; ++ else ++ size = exp_size; ++ ++ if (exp_size + TCL_UTF_MAX >= esPtr->msize) { ++ if (esPtr->umsize >= EXP_MATCH_LIMIT) { ++ expDiagLogU("WARNING: interact buffer is full. probably your program\r\n"); ++ expDiagLogU("is not interactive or has a very long output line. The\r\n"); ++ expDiagLogU("current limit is " EXP_MATCH_LIMIT_QUOTE ".\r\n"); ++ expDiagLogU("Dumping first half of buffer in order to continue\r\n"); ++ expDiagLogU("Recommend you enlarge the buffer.\r\n"); ++ exp_buffer_shuffle(interp,esPtr,save_flags,EXPECT_OUT,"expect"); ++ return count; ++ } ++ else { ++ esPtr->umsize += EXP_MATCH_INC; ++ expAdjust(esPtr); ++ } ++ } ++ ++ full_size = esPtr->msize - (size / TCL_UTF_MAX); ++ size = Tcl_ReadChars(esPtr->channel, ++ esPtr->buffer, ++ full_size, ++ 1 /* append */); ++ if (size > 0) { ++ count += size; ++ /* We try again if there are more to read and we haven't ++ seen a newline at the end. */ ++ if (size == full_size) { ++ str = Tcl_GetStringFromObj(esPtr->buffer, &size); ++ if (str[size - 1] != '\n') ++ continue; ++ } ++ } ++ else { ++ /* It is even trickier. We got an error from read. We have ++ to recover from it. Let's make sure the size of ++ buffer is correct. It can be corrupted. */ ++ str = Tcl_GetString(esPtr->buffer); ++ Tcl_SetObjLength(esPtr->buffer, strlen(str)); ++ } ++ ++ break; ++ } ++ ++ return count; ++} ++ + /* returns # of bytes read or (non-positive) error of form EXP_XXX */ + /* returns 0 for end of file */ + /* If timeout is non-zero, set an alarm before doing the read, else assume */ +@@ -1632,6 +1711,8 @@ + { + int cc = EXP_TIMEOUT; + int size = expSizeGet(esPtr); ++ int full_size; ++ int count; + + if (size + TCL_UTF_MAX >= esPtr->msize) + exp_buffer_shuffle(interp,esPtr,save_flags,EXPECT_OUT,"expect"); +@@ -1648,11 +1729,43 @@ + } + #endif + +- ++ /* FIXME: If we ask less than what is available in the tcl buffer ++ when tcl has seen EOF, we will throw away the remaining data ++ since the next read will get EOF. Since expect is line-oriented, ++ we exand our buffer to get EOF or the next newline at the end of ++ the input buffer. I don't know if it is the right fix. H.J. */ ++ count = 0; ++ full_size = esPtr->msize - (size / TCL_UTF_MAX); + cc = Tcl_ReadChars(esPtr->channel, +- esPtr->buffer, +- esPtr->msize - (size / TCL_UTF_MAX), +- 1 /* append */); ++ esPtr->buffer, ++ full_size, ++ 1 /* append */); ++ if (cc > 0) { ++ count += cc; ++ /* It gets very tricky. There are more to read. We will expand ++ our buffer and get EOF or a newline at the end unless the ++ buffer length has been changed. */ ++ if (cc == full_size) { ++ char *str; ++ str = Tcl_GetStringFromObj(esPtr->buffer, &size); ++ if (str[size - 1] != '\n') { ++ if (esPtr->umsize_changed) { ++ char buf[20]; /* big enough for 64bit int in hex. */ ++ snprintf(buf,sizeof(buf),"0x%x", esPtr->umsize); ++ expDiagLogU("WARNING: interact buffer is not large enough to hold\r\n"); ++ expDiagLogU("all output. probably your program is not interactive or\r\n"); ++ expDiagLogU("has a very long output line. The current limit is "); ++ expDiagLogU(buf); ++ expDiagLogU(".\r\n"); ++ } ++ else { ++ cc = expReadNewLine(interp,esPtr,save_flags); ++ if (cc > 0) ++ count += cc; ++ } ++ } ++ } ++ } + i_read_errno = errno; + + #ifdef SIMPLE_EVENT +@@ -1673,7 +1786,7 @@ + } + } + #endif +- return cc; ++ return count > 0 ? count : cc; + } + + /* +@@ -2746,8 +2859,14 @@ + return(TCL_ERROR); + } + +- if (Default) exp_default_match_max = size; +- else esPtr->umsize = size; ++ if (Default) { ++ exp_default_match_max = size; ++ exp_default_match_max_changed = 1; ++ } ++ else { ++ esPtr->umsize = size; ++ esPtr->umsize_changed = 1; ++ } + + return(TCL_OK); + } diff --git a/pkgs/core/expect/patches/expect-5.43.0-tcl_8.5.8_fix-1.patch b/pkgs/core/expect/patches/expect-5.43.0-tcl_8.5.8_fix-1.patch new file mode 100644 index 0000000..5b9596a --- /dev/null +++ b/pkgs/core/expect/patches/expect-5.43.0-tcl_8.5.8_fix-1.patch @@ -0,0 +1,125 @@ +Submitted By: DJ Lucas <dj_AT_linuxfromscratch_DOT_org> +Date: 2008-09-28 +Initial Package Version: 5.43 +Upstream status: Not Submitted +Origin: LFS ticket 2126 (http://wiki.linuxfromscratch.org/lfs/ticket/2126) + Bryan Kadzban <bryan@kadzban.is-a-geek.net> +Description: Removes references to functions that Tcl 8.5 no longer exposes + and correct other minor build problems WRT TCL-8.5.x. + +diff -Naur expect-5.43-orig/Dbg.c expect-5.43/Dbg.c +--- expect-5.43-orig/Dbg.c 2002-03-22 22:11:54.000000000 -0600 ++++ expect-5.43/Dbg.c 2008-08-24 01:30:15.000000000 -0500 +@@ -9,7 +9,7 @@ + */ + + #include <stdio.h> +- ++#include "expect_cf.h" + #include "tcldbgcf.h" + #if 0 + /* tclInt.h drags in stdlib. By claiming no-stdlib, force it to drag in */ +diff -Naur expect-5.43-orig/exp_inter.c expect-5.43/exp_inter.c +--- expect-5.43-orig/exp_inter.c 2004-08-17 21:03:00.000000000 -0500 ++++ expect-5.43/exp_inter.c 2008-08-24 01:28:59.000000000 -0500 +@@ -36,6 +36,7 @@ + #include <ctype.h> + + #include "tcl.h" ++#include "tclInt.h" + #include "string.h" + + #include "exp_tty_in.h" +diff -Naur expect-5.43/exp_command.c expect-5.43-patched/exp_command.c +--- expect-5.43/exp_command.c 2004-08-20 13:18:01.000000000 -0400 ++++ expect-5.43-patched/exp_command.c 2008-01-12 11:42:45.000000000 -0500 +@@ -2265,6 +2265,8 @@ + /*NOTREACHED*/ + } + ++static struct exp_cmd_data cmd_data[]; ++ + /*ARGSUSED*/ + static int + Exp_CloseObjCmd(clientData, interp, objc, objv) +@@ -2311,12 +2313,23 @@ + /* Historical note: we used "close" long before there was a */ + /* Tcl builtin by the same name. */ + ++ /* The code that registered this function as the handler for */ ++ /* the "close" command stored away the old handler in the */ ++ /* exp_cmd_data for the "close" command. */ ++ ++ struct exp_cmd_data *cmd_ptr; + Tcl_CmdInfo info; ++ ++ for(cmd_ptr = &cmd_data[0]; cmd_ptr->name; cmd_ptr++) { ++ if(strncmp(cmd_ptr->name, "close", 5) == 0) ++ break; ++ } ++ + Tcl_ResetResult(interp); + if (0 == Tcl_GetCommandInfo(interp,"close",&info)) { + info.clientData = 0; + } +- return(Tcl_CloseObjCmd(info.clientData,interp,objc_orig,objv_orig)); ++ return(cmd_ptr->old_objProc(info.clientData,interp,objc_orig,objv_orig)); + } + + if (chanName) { +@@ -2961,7 +2974,10 @@ + /* if successful (i.e., TCL_RETURN is returned) */ + /* modify the result, so that we will handle it specially */ + +- int result = Tcl_ReturnObjCmd(clientData,interp,objc,objv); ++ Tcl_CmdInfo info; ++ Tcl_GetCommandInfo(interp, "return", &info); ++ ++ int result = info.objProc(clientData,interp,objc,objv); + if (result == TCL_RETURN) + result = EXP_TCL_RETURN; + return result; +@@ -3062,8 +3078,7 @@ + + for (;c->name;c++) { + /* if already defined, don't redefine */ +- if ((c->flags & EXP_REDEFINE) || +- !(Tcl_FindHashEntry(&globalNsPtr->cmdTable,c->name) || ++ if (!(Tcl_FindHashEntry(&globalNsPtr->cmdTable,c->name) || + Tcl_FindHashEntry(&currNsPtr->cmdTable,c->name))) { + if (c->objproc) + Tcl_CreateObjCommand(interp,c->name, +@@ -3072,6 +3087,21 @@ + Tcl_CreateCommand(interp,c->name,c->proc, + c->data,exp_deleteProc); + } ++ else if (c->flags & EXP_REDEFINE) { /* unless the REDEFINE flag is present */ ++ Tcl_CmdInfo info; ++ ++ if (Tcl_GetCommandInfo(interp, c->name, &info)) { ++ c->old_proc = info.proc; ++ c->old_objProc = info.objProc; ++ } ++ ++ if (c->objproc) ++ Tcl_CreateObjCommand(interp,c->name, ++ c->objproc,c->data,exp_deleteObjProc); ++ else ++ Tcl_CreateCommand(interp,c->name,c->proc, ++ c->data,exp_deleteProc); ++ } + if (!(c->name[0] == 'e' && + c->name[1] == 'x' && + c->name[2] == 'p') +diff -Naur expect-5.43/exp_command.h expect-5.43-patched/exp_command.h +--- expect-5.43/exp_command.h 2008-01-12 11:44:11.000000000 -0500 ++++ expect-5.43-patched/exp_command.h 2008-01-12 11:26:05.000000000 -0500 +@@ -297,6 +297,8 @@ + Tcl_CmdProc *proc; + ClientData data; + int flags; ++ Tcl_CmdProc *old_proc; /* these store the procedure for the old command, */ ++ Tcl_ObjCmdProc *old_objProc; /* if any */ + }; + + EXTERN void exp_create_commands _ANSI_ARGS_((Tcl_Interp *, diff --git a/pkgs/core/ez-ipupdate/ez-ipupdate.nm b/pkgs/core/ez-ipupdate/ez-ipupdate.nm new file mode 100644 index 0000000..b7846df --- /dev/null +++ b/pkgs/core/ez-ipupdate/ez-ipupdate.nm @@ -0,0 +1,46 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = ez-ipupdate +PKG_VER = 3.0.11b8 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://www.gusnet.cx/proj/ez-ipupdate/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Client for Dynamic DNS Services. + +define PKG_DESCRIPTION + ez-ipupdate is a small utility for updating your host name for a lot of \ + dynamic DNS service provider. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_CONFIGURE_CMDS + cd $(DIR_APP) && chmod -v 755 missing +endef diff --git a/pkgs/core/ez-ipupdate/patches/ez-ipupdate-3.0.11b8-10.patch b/pkgs/core/ez-ipupdate/patches/ez-ipupdate-3.0.11b8-10.patch new file mode 100644 index 0000000..fd19e11 --- /dev/null +++ b/pkgs/core/ez-ipupdate/patches/ez-ipupdate-3.0.11b8-10.patch @@ -0,0 +1,8024 @@ +--- ez-ipupdate-3.0.11b8.orig/Makefile.in ++++ ez-ipupdate-3.0.11b8/Makefile.in +@@ -1,6 +1,6 @@ +-# Makefile.in generated automatically by automake 1.3 from Makefile.am ++# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +-# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. ++# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, + # with or without modifications, as long as this notice is preserved. +@@ -11,7 +11,7 @@ + # PARTICULAR PURPOSE. + + +-SHELL = /bin/sh ++SHELL = @SHELL@ + + srcdir = @srcdir@ + top_srcdir = @top_srcdir@ +@@ -32,7 +32,7 @@ + includedir = @includedir@ + oldincludedir = /usr/include + +-DISTDIR = ++DESTDIR = + + pkgdatadir = $(datadir)/@PACKAGE@ + pkglibdir = $(libdir)/@PACKAGE@ +@@ -46,7 +46,7 @@ + AUTOHEADER = @AUTOHEADER@ + + INSTALL = @INSTALL@ +-INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) + INSTALL_DATA = @INSTALL_DATA@ + INSTALL_SCRIPT = @INSTALL_SCRIPT@ + transform = @program_transform_name@ +@@ -73,7 +73,7 @@ + + EXTRA_DIST = getpass.c ez-ipupdate.lsm example.conf example-pgpow.conf example-dhs.conf example-dyndns.conf example-ods.conf example-tzo.conf example-gnudip.conf example-easydns.conf example-justlinux.conf example-dyns.conf CHANGELOG mkbinary example-heipv6tb.conf + +-AUTOMAKE_OPTIONS=foreign ++AUTOMAKE_OPTIONS = foreign + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs + CONFIG_HEADER = config.h +@@ -90,50 +90,59 @@ + ez_ipupdate_DEPENDENCIES = + ez_ipupdate_LDFLAGS = + CFLAGS = @CFLAGS@ +-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +-LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +-DIST_COMMON = README COPYING INSTALL Makefile.am Makefile.in acconfig.h \ +-aclocal.m4 config.guess config.h.in config.sub configure configure.in \ +-install-sh missing mkinstalldirs stamp-h.in ++COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ ++DIST_COMMON = README ./stamp-h.in COPYING INSTALL Makefile.am \ ++Makefile.in acconfig.h aclocal.m4 config.guess config.h.in config.sub \ ++configure configure.in install-sh missing mkinstalldirs + + + DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + + TAR = tar +-GZIP = --best ++GZIP_ENV = --best ++DEP_FILES = .deps/cache_file.P .deps/conf_file.P .deps/ez-ipupdate.P \ ++.deps/md5.P .deps/pid_file.P + SOURCES = $(ez_ipupdate_SOURCES) + OBJECTS = $(ez_ipupdate_OBJECTS) + +-all: Makefile $(PROGRAMS) config.h +- ++all: all-redirect + .SUFFIXES: + .SUFFIXES: .S .c .o .s +-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +- cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps Makefile ++$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) ++ cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile + +-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + + $(ACLOCAL_M4): configure.in + cd $(srcdir) && $(ACLOCAL) + +-config.status: $(srcdir)/configure ++config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + + config.h: stamp-h +- @: ++ @if test ! -f $@; then \ ++ rm -f stamp-h; \ ++ $(MAKE) stamp-h; \ ++ else :; fi + stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES= CONFIG_HEADERS=config.h \ + $(SHELL) ./config.status +- @echo timestamp > stamp-h ++ @echo timestamp > stamp-h 2> /dev/null + $(srcdir)/config.h.in: $(srcdir)/stamp-h.in ++ @if test ! -f $@; then \ ++ rm -f $(srcdir)/stamp-h.in; \ ++ $(MAKE) $(srcdir)/stamp-h.in; \ ++ else :; fi + $(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h + cd $(top_srcdir) && $(AUTOHEADER) +- @echo timestamp > $(srcdir)/stamp-h.in ++ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null + + mostlyclean-hdr: + +@@ -158,20 +167,17 @@ + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ +- echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ +- $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ ++ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ ++ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + + uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ +- rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ ++ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +-.c.o: +- $(COMPILE) -c $< +- + .s.o: + $(COMPILE) -c $< + +@@ -195,8 +201,12 @@ + tags: TAGS + + ID: $(HEADERS) $(SOURCES) $(LISP) ++ list='$(SOURCES) $(HEADERS)'; \ ++ unique=`for i in $$list; do echo $$i; done | \ ++ awk ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ +- && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) ++ && mkid -f$$here/ID $$unique $(LISP) + + TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ +@@ -206,7 +216,7 @@ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ +- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) ++ || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP)) + + mostlyclean-tags: + +@@ -225,99 +235,148 @@ + # tarfile. + distcheck: dist + -rm -rf $(distdir) +- GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz ++ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ +- && $(MAKE) \ +- && $(MAKE) dvi \ +- && $(MAKE) check \ +- && $(MAKE) install \ +- && $(MAKE) installcheck \ +- && $(MAKE) dist ++ && $(MAKE) $(AM_MAKEFLAGS) \ ++ && $(MAKE) $(AM_MAKEFLAGS) dvi \ ++ && $(MAKE) $(AM_MAKEFLAGS) check \ ++ && $(MAKE) $(AM_MAKEFLAGS) install \ ++ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ ++ && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) +- @echo "========================"; \ +- echo "$(distdir).tar.gz is ready for distribution"; \ +- echo "========================" ++ @banner="$(distdir).tar.gz is ready for distribution"; \ ++ dashes=`echo "$$banner" | sed s/./=/g`; \ ++ echo "$$dashes"; \ ++ echo "$$banner"; \ ++ echo "$$dashes" + dist: distdir + -chmod -R a+r $(distdir) +- GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) ++ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) + dist-all: distdir + -chmod -R a+r $(distdir) +- GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) ++ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) + distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) ++ here=`cd $(top_builddir) && pwd`; \ ++ top_distdir=`cd $(distdir) && pwd`; \ ++ distdir=`cd $(distdir) && pwd`; \ ++ cd $(top_srcdir) \ ++ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ +- test -f $(distdir)/$$file \ +- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ +- || cp -p $$d/$$file $(distdir)/$$file; \ ++ if test -d $$d/$$file; then \ ++ cp -pr $$d/$$file $(distdir)/$$file; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ ++ || cp -p $$d/$$file $(distdir)/$$file || :; \ ++ fi; \ + done +-cache_file.o: cache_file.c config.h cache_file.h +-conf_file.o: conf_file.c config.h conf_file.h +-ez-ipupdate.o: ez-ipupdate.c config.h error.h md5.h dprintf.h \ +- conf_file.h cache_file.h pid_file.h +-md5.o: md5.c config.h md5.h +-pid_file.o: pid_file.c config.h error.h dprintf.h +- +-info: +-dvi: +-check: all +- $(MAKE) +-installcheck: +-install-exec: install-binPROGRAMS +- @$(NORMAL_INSTALL) + +-install-data: +- @$(NORMAL_INSTALL) ++DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-install: install-exec install-data all +- @: ++-include $(DEP_FILES) + +-uninstall: uninstall-binPROGRAMS ++mostlyclean-depend: + ++clean-depend: ++ ++distclean-depend: ++ -rm -rf .deps ++ ++maintainer-clean-depend: ++ ++%.o: %.c ++ @echo '$(COMPILE) -c $<'; \ ++ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< ++ @-cp .deps/$(*F).pp .deps/$(*F).P; \ ++ tr ' ' '\012' < .deps/$(*F).pp \ ++ | sed -e 's/^\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ ++ >> .deps/$(*F).P; \ ++ rm .deps/$(*F).pp ++ ++%.lo: %.c ++ @echo '$(LTCOMPILE) -c $<'; \ ++ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< ++ @-sed -e 's/^([^:]*).o[ ]*:/\1.lo \1.o :/' \ ++ < .deps/$(*F).pp > .deps/$(*F).P; \ ++ tr ' ' '\012' < .deps/$(*F).pp \ ++ | sed -e 's/^\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ ++ >> .deps/$(*F).P; \ ++ rm -f .deps/$(*F).pp ++info-am: ++info: info-am ++dvi-am: ++dvi: dvi-am ++check-am: all-am ++check: check-am ++installcheck-am: ++installcheck: installcheck-am ++all-recursive-am: config.h ++ $(MAKE) $(AM_MAKEFLAGS) all-recursive ++ ++install-exec-am: install-binPROGRAMS ++install-exec: install-exec-am ++ ++install-data-am: ++install-data: install-data-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++install: install-am ++uninstall-am: uninstall-binPROGRAMS ++uninstall: uninstall-am ++all-am: Makefile $(PROGRAMS) config.h ++all-redirect: all-am + install-strip: +- $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install ++ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install + installdirs: +- $(mkinstalldirs) $(DATADIR)$(bindir) ++ $(mkinstalldirs) $(DESTDIR)$(bindir) + + + mostlyclean-generic: +- -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + + clean-generic: +- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + + distclean-generic: +- -rm -f Makefile $(DISTCLEANFILES) ++ -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* +- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + + maintainer-clean-generic: +- -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +- -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +-mostlyclean: mostlyclean-hdr mostlyclean-binPROGRAMS \ +- mostlyclean-compile mostlyclean-tags \ ++mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS \ ++ mostlyclean-compile mostlyclean-tags mostlyclean-depend \ + mostlyclean-generic + +-clean: clean-hdr clean-binPROGRAMS clean-compile clean-tags \ +- clean-generic mostlyclean ++mostlyclean: mostlyclean-am ++ ++clean-am: clean-hdr clean-binPROGRAMS clean-compile clean-tags \ ++ clean-depend clean-generic mostlyclean-am + +-distclean: distclean-hdr distclean-binPROGRAMS distclean-compile \ +- distclean-tags distclean-generic clean ++clean: clean-am ++ ++distclean-am: distclean-hdr distclean-binPROGRAMS distclean-compile \ ++ distclean-tags distclean-depend distclean-generic \ ++ clean-am ++ ++distclean: distclean-am + -rm -f config.status + +-maintainer-clean: maintainer-clean-hdr maintainer-clean-binPROGRAMS \ ++maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ +- maintainer-clean-generic distclean ++ maintainer-clean-depend maintainer-clean-generic \ ++ distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." ++ ++maintainer-clean: maintainer-clean-am + -rm -f config.status + + .PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ +@@ -325,8 +384,11 @@ + maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ + mostlyclean-compile distclean-compile clean-compile \ + maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +-clean-tags maintainer-clean-tags distdir info dvi installcheck \ +-install-exec install-data install uninstall all installdirs \ ++clean-tags maintainer-clean-tags distdir mostlyclean-depend \ ++distclean-depend clean-depend maintainer-clean-depend info-am info \ ++dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ ++install-exec-am install-exec install-data-am install-data install-am \ ++install uninstall-am uninstall all-redirect all-am all installdirs \ + mostlyclean-generic distclean-generic clean-generic \ + maintainer-clean-generic clean mostlyclean distclean maintainer-clean + +--- ez-ipupdate-3.0.11b8.orig/aclocal.m4 ++++ ez-ipupdate-3.0.11b8/aclocal.m4 +@@ -1,7 +1,7 @@ +-dnl aclocal.m4 generated automatically by aclocal 1.3 ++dnl aclocal.m4 generated automatically by aclocal 1.4-p6 + +-dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +-dnl This Makefile.in is free software; the Free Software Foundation ++dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + +@@ -12,7 +12,7 @@ + + # Like AC_CONFIG_HEADER, but automatically create stamp file. + +-AC_DEFUN(AM_CONFIG_HEADER, ++AC_DEFUN([AM_CONFIG_HEADER], + [AC_PREREQ([2.12]) + AC_CONFIG_HEADER([$1]) + dnl When config.status generates a header, we must update the stamp-h file. +@@ -42,8 +42,9 @@ + dnl Usage: + dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +-AC_DEFUN(AM_INIT_AUTOMAKE, +-[AC_REQUIRE([AM_PROG_INSTALL]) ++AC_DEFUN([AM_INIT_AUTOMAKE], ++[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl ++AC_REQUIRE([AC_PROG_INSTALL]) + PACKAGE=[$1] + AC_SUBST(PACKAGE) + VERSION=[$2] +@@ -53,33 +54,53 @@ + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi + ifelse([$3],, +-AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE") +-AC_DEFINE_UNQUOTED(VERSION, "$VERSION")) ++AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) ++AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) + AC_REQUIRE([AM_SANITY_CHECK]) + AC_REQUIRE([AC_ARG_PROGRAM]) + dnl FIXME This is truly gross. + missing_dir=`cd $ac_aux_dir && pwd` +-AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) ++AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir) + AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +-AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) ++AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir) + AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) + AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) + AC_REQUIRE([AC_PROG_MAKE_SET])]) + ++# Copyright 2002 Free Software Foundation, Inc. + +-# serial 1 +- +-AC_DEFUN(AM_PROG_INSTALL, +-[AC_REQUIRE([AC_PROG_INSTALL]) +-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' +-AC_SUBST(INSTALL_SCRIPT)dnl +-]) ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2, or (at your option) ++# any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++ ++# AM_AUTOMAKE_VERSION(VERSION) ++# ---------------------------- ++# Automake X.Y traces this macro to ensure aclocal.m4 has been ++# generated from the m4 files accompanying Automake X.Y. ++AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"]) ++ ++# AM_SET_CURRENT_AUTOMAKE_VERSION ++# ------------------------------- ++# Call AM_AUTOMAKE_VERSION so it can be traced. ++# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. ++AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], ++ [AM_AUTOMAKE_VERSION([1.4-p6])]) + + # + # Check to make sure that the build environment is sane. + # + +-AC_DEFUN(AM_SANITY_CHECK, ++AC_DEFUN([AM_SANITY_CHECK], + [AC_MSG_CHECKING([whether build environment is sane]) + # Just in case + sleep 1 +@@ -120,7 +141,7 @@ + + dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) + dnl The program must properly implement --version. +-AC_DEFUN(AM_MISSING_PROG, ++AC_DEFUN([AM_MISSING_PROG], + [AC_MSG_CHECKING(for working $2) + # Run test in a subshell; some versions of sh will print an error if + # an executable is not found, even if stderr is redirected. +--- ez-ipupdate-3.0.11b8.orig/config.guess ++++ ez-ipupdate-3.0.11b8/config.guess +@@ -1,7 +1,10 @@ + #! /bin/sh + # Attempt to guess a canonical system name. +-# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. +-# ++# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, ++# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++timestamp='2003-01-10' ++ + # This file is free software; you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or +@@ -21,36 +24,220 @@ + # configuration script generated by Autoconf, you may include it under + # the same distribution terms that you use for the rest of that program. + +-# Written by Per Bothner <bothner@cygnus.com>. +-# The master version of this file is at the FSF in /home/gd/gnu/lib. ++# Originally written by Per Bothner <per@bothner.com>. ++# Please send patches to <config-patches@gnu.org>. Submit a context ++# diff and a properly formatted ChangeLog entry. + # + # This script attempts to guess a canonical system name similar to + # config.sub. If it succeeds, it prints the system name on stdout, and + # exits with 0. Otherwise, it exits with 1. + # + # The plan is that this can be called by configure scripts if you +-# don't specify an explicit system type (host/target name). +-# +-# Only a few systems have been added to this list; please add others +-# (but try to keep the structure clean). +-# ++# don't specify an explicit build system type. ++ ++me=`echo "$0" | sed -e 's,.*/,,'` ++ ++usage="\ ++Usage: $0 [OPTION] ++ ++Output the configuration name of the system `$me' is run on. ++ ++Operation modes: ++ -h, --help print this help, then exit ++ -t, --time-stamp print date of last modification, then exit ++ -v, --version print version number, then exit ++ ++Report bugs and patches to <config-patches@gnu.org>." ++ ++version="\ ++GNU config.guess ($timestamp) ++ ++Originally written by Per Bothner. ++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 ++Free Software Foundation, Inc. ++ ++This is free software; see the source for copying conditions. There is NO ++warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ++ ++help=" ++Try `$me --help' for more information." ++ ++# Parse command line ++while test $# -gt 0 ; do ++ case $1 in ++ --time-stamp | --time* | -t ) ++ echo "$timestamp" ; exit 0 ;; ++ --version | -v ) ++ echo "$version" ; exit 0 ;; ++ --help | --h* | -h ) ++ echo "$usage"; exit 0 ;; ++ -- ) # Stop option processing ++ shift; break ;; ++ - ) # Use stdin as input. ++ break ;; ++ -* ) ++ echo "$me: invalid option $1$help" >&2 ++ exit 1 ;; ++ * ) ++ break ;; ++ esac ++done ++ ++if test $# != 0; then ++ echo "$me: too many arguments$help" >&2 ++ exit 1 ++fi ++ ++trap 'exit 1' 1 2 15 ++ ++# CC_FOR_BUILD -- compiler used by this script. Note that the use of a ++# compiler to aid in system detection is discouraged as it requires ++# temporary files to be created and, as you can see below, it is a ++# headache to deal with in a portable fashion. ++ ++# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still ++# use `HOST_CC' if defined, but it is deprecated. ++ ++# Portable tmp directory creation inspired by the Autoconf team. ++ ++set_cc_for_build=' ++trap "exitcode=$?; (rm -f $tmpfiles 2>/dev/null; rmdir $tmp 2>/dev/null) && exit $exitcode" 0 ; ++trap "rm -f $tmpfiles 2>/dev/null; rmdir $tmp 2>/dev/null; exit 1" 1 2 13 15 ; ++: ${TMPDIR=/tmp} ; ++ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || ++ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || ++ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; ++dummy=$tmp/dummy ; ++tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; ++case $CC_FOR_BUILD,$HOST_CC,$CC in ++ ,,) echo "int x;" > $dummy.c ; ++ for c in cc gcc c89 c99 ; do ++ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then ++ CC_FOR_BUILD="$c"; break ; ++ fi ; ++ done ; ++ if test x"$CC_FOR_BUILD" = x ; then ++ CC_FOR_BUILD=no_compiler_found ; ++ fi ++ ;; ++ ,,*) CC_FOR_BUILD=$CC ;; ++ ,*,*) CC_FOR_BUILD=$HOST_CC ;; ++esac ;' + + # This is needed to find uname on a Pyramid OSx when run in the BSD universe. +-# (ghazi@noc.rutgers.edu 8/24/94.) ++# (ghazi@noc.rutgers.edu 1994-08-24) + if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH + fi + + UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown + UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown ++UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown + UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +-trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 +- + # Note: order is significant - the case branches are not exclusive. + + case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ++ *:NetBSD:*:*) ++ # NetBSD (nbsd) targets should (where applicable) match one or ++ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, ++ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently ++ # switched to ELF, *-*-netbsd* would select the old ++ # object file format. This provides both forward ++ # compatibility and a consistent mechanism for selecting the ++ # object file format. ++ # ++ # Note: NetBSD doesn't particularly care about the vendor ++ # portion of the name. We always set it to "unknown". ++ sysctl="sysctl -n hw.machine_arch" ++ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ ++ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` ++ case "${UNAME_MACHINE_ARCH}" in ++ armeb) machine=armeb-unknown ;; ++ arm*) machine=arm-unknown ;; ++ sh3el) machine=shl-unknown ;; ++ sh3eb) machine=sh-unknown ;; ++ *) machine=${UNAME_MACHINE_ARCH}-unknown ;; ++ esac ++ # The Operating System including object format, if it has switched ++ # to ELF recently, or will in the future. ++ case "${UNAME_MACHINE_ARCH}" in ++ arm*|i386|m68k|ns32k|sh3*|sparc|vax) ++ eval $set_cc_for_build ++ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ ++ | grep __ELF__ >/dev/null ++ then ++ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). ++ # Return netbsd for either. FIX? ++ os=netbsd ++ else ++ os=netbsdelf ++ fi ++ ;; ++ *) ++ os=netbsd ++ ;; ++ esac ++ # The OS release ++ # Debian GNU/NetBSD machines have a different userland, and ++ # thus, need a distinct triplet. However, they do not need ++ # kernel version information, so it can be replaced with a ++ # suitable tag, in the style of linux-gnu. ++ case "${UNAME_VERSION}" in ++ Debian*) ++ release='-gnu' ++ ;; ++ *) ++ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/./'` ++ ;; ++ esac ++ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: ++ # contains redundant information, the shorter form: ++ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. ++ echo "${machine}-${os}${release}" ++ exit 0 ;; ++ amiga:OpenBSD:*:*) ++ echo m68k-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ arc:OpenBSD:*:*) ++ echo mipsel-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ hp300:OpenBSD:*:*) ++ echo m68k-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ mac68k:OpenBSD:*:*) ++ echo m68k-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ macppc:OpenBSD:*:*) ++ echo powerpc-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ mvme68k:OpenBSD:*:*) ++ echo m68k-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ mvme88k:OpenBSD:*:*) ++ echo m88k-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ mvmeppc:OpenBSD:*:*) ++ echo powerpc-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ pmax:OpenBSD:*:*) ++ echo mipsel-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ sgi:OpenBSD:*:*) ++ echo mipseb-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ sun3:OpenBSD:*:*) ++ echo m68k-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ wgrisc:OpenBSD:*:*) ++ echo mipsel-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ *:OpenBSD:*:*) ++ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} ++ exit 0 ;; ++ *:MicroBSD:*:*) ++ echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE} ++ exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` +@@ -59,87 +246,91 @@ + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. +- cat <<EOF >dummy.s ++ eval $set_cc_for_build ++ cat <<EOF >$dummy.s ++ .data ++$Lformat: ++ .byte 37,100,45,37,120,10,0 # "%d-%x\n" ++ ++ .text + .globl main ++ .align 4 + .ent main + main: +- .frame $30,0,$26,0 +- .prologue 0 +- .long 0x47e03d80 # implver $0 +- lda $2,259 +- .long 0x47e20c21 # amask $2,$1 +- srl $1,8,$2 +- sll $2,2,$2 +- sll $0,3,$0 +- addl $1,$0,$0 +- addl $2,$0,$0 +- ret $31,($26),1 ++ .frame $30,16,$26,0 ++ ldgp $29,0($27) ++ .prologue 1 ++ .long 0x47e03d80 # implver $0 ++ lda $2,-1 ++ .long 0x47e20c21 # amask $2,$1 ++ lda $16,$Lformat ++ mov $0,$17 ++ not $1,$18 ++ jsr $26,printf ++ ldgp $29,0($26) ++ mov 0,$16 ++ jsr $26,exit + .end main + EOF +- ${CC-cc} dummy.s -o dummy 2>/dev/null ++ $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null + if test "$?" = 0 ; then +- ./dummy +- case "$?" in +- 7) ++ case `$dummy` in ++ 0-0) + UNAME_MACHINE="alpha" + ;; +- 15) ++ 1-0) + UNAME_MACHINE="alphaev5" + ;; +- 14) ++ 1-1) + UNAME_MACHINE="alphaev56" + ;; +- 10) ++ 1-101) + UNAME_MACHINE="alphapca56" + ;; +- 16) ++ 2-303) + UNAME_MACHINE="alphaev6" + ;; ++ 2-307) ++ UNAME_MACHINE="alphaev67" ++ ;; ++ 2-1307) ++ UNAME_MACHINE="alphaev68" ++ ;; ++ 3-1307) ++ UNAME_MACHINE="alphaev7" ++ ;; + esac + fi +- rm -f dummy.s dummy +- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]` ++ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` ++ exit 0 ;; ++ Alpha\ *:Windows_NT*:*) ++ # How do we know it's Interix rather than the generic POSIX subsystem? ++ # Should we change UNAME_MACHINE based on the output of uname instead ++ # of the specific Alpha model? ++ echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) +- echo m68k-cbm-sysv4 ++ echo m68k-unknown-sysv4 + exit 0;; +- amiga:NetBSD:*:*) +- echo m68k-cbm-netbsd${UNAME_RELEASE} +- exit 0 ;; +- amiga:OpenBSD:*:*) +- echo m68k-unknown-openbsd${UNAME_RELEASE} +- exit 0 ;; +- arc64:OpenBSD:*:*) +- echo mips64el-unknown-openbsd${UNAME_RELEASE} ++ *:[Aa]miga[Oo][Ss]:*:*) ++ echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; +- arc:OpenBSD:*:*) +- echo mipsel-unknown-openbsd${UNAME_RELEASE} ++ *:[Mm]orph[Oo][Ss]:*:*) ++ echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; +- hkmips:OpenBSD:*:*) +- echo mips-unknown-openbsd${UNAME_RELEASE} +- exit 0 ;; +- pmax:OpenBSD:*:*) +- echo mipsel-unknown-openbsd${UNAME_RELEASE} +- exit 0 ;; +- sgi:OpenBSD:*:*) +- echo mips-unknown-openbsd${UNAME_RELEASE} +- exit 0 ;; +- wgrisc:OpenBSD:*:*) +- echo mipsel-unknown-openbsd${UNAME_RELEASE} ++ *:OS/390:*:*) ++ echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; +- arm32:NetBSD:*:*) +- echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/./'` +- exit 0 ;; +- SR2?01:HI-UX/MPP:*:*) ++ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; +- Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) ++ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 +@@ -147,9 +338,16 @@ + echo pyramid-pyramid-bsd + fi + exit 0 ;; +- NILE:*:*:dcosx) ++ NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; ++ DRS?6000:UNIX_SV:4.2*:7*) ++ case `/usr/bin/uname -p` in ++ sparc) echo sparc-icl-nx7 && exit 0 ;; ++ esac ;; ++ sun4H:SunOS:5.*:*) ++ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; +@@ -175,7 +373,7 @@ + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) +- UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` ++ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) +@@ -189,30 +387,32 @@ + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; +- atari*:NetBSD:*:*) +- echo m68k-atari-netbsd${UNAME_RELEASE} +- exit 0 ;; +- atari*:OpenBSD:*:*) +- echo m68k-unknown-openbsd${UNAME_RELEASE} +- exit 0 ;; +- sun3*:NetBSD:*:*) +- echo m68k-sun-netbsd${UNAME_RELEASE} +- exit 0 ;; +- sun3*:OpenBSD:*:*) +- echo m68k-unknown-openbsd${UNAME_RELEASE} +- exit 0 ;; +- mac68k:NetBSD:*:*) +- echo m68k-apple-netbsd${UNAME_RELEASE} ++ # The situation for MiNT is a little confusing. The machine name ++ # can be virtually everything (everything which is not ++ # "atarist" or "atariste" at least should have a processor ++ # > m68000). The system name ranges from "MiNT" over "FreeMiNT" ++ # to the lowercase version "mint" (or "freemint"). Finally ++ # the system name "TOS" denotes a system which is actually not ++ # MiNT. But MiNT is downward compatible to TOS, so this should ++ # be no problem. ++ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) ++ echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; +- mac68k:OpenBSD:*:*) +- echo m68k-unknown-openbsd${UNAME_RELEASE} +- exit 0 ;; +- mvme68k:OpenBSD:*:*) +- echo m68k-unknown-openbsd${UNAME_RELEASE} +- exit 0 ;; +- mvme88k:OpenBSD:*:*) +- echo m88k-unknown-openbsd${UNAME_RELEASE} ++ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) ++ echo m68k-atari-mint${UNAME_RELEASE} ++ exit 0 ;; ++ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) ++ echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; ++ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) ++ echo m68k-milan-mint${UNAME_RELEASE} ++ exit 0 ;; ++ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) ++ echo m68k-hades-mint${UNAME_RELEASE} ++ exit 0 ;; ++ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) ++ echo m68k-unknown-mint${UNAME_RELEASE} ++ exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; +@@ -225,12 +425,18 @@ + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; +- 2020:CLIX:*:*) ++ 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) +- sed 's/^ //' << EOF >dummy.c +- int main (argc, argv) int argc; char **argv; { ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++#ifdef __cplusplus ++#include <stdio.h> /* for printf() prototype */ ++ int main (int argc, char *argv[]) { ++#else ++ int main (argc, argv) int argc; char *argv[]; { ++#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); +@@ -245,12 +451,20 @@ + exit (-1); + } + EOF +- ${CC-cc} dummy.c -o dummy \ +- && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/([0-9]*).*/\1/p'` \ +- && rm dummy.c dummy && exit 0 +- rm -f dummy.c dummy ++ $CC_FOR_BUILD -o $dummy $dummy.c \ ++ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/([0-9]*).*/\1/p'` \ ++ && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; ++ Motorola:PowerMAX_OS:*:*) ++ echo powerpc-motorola-powermax ++ exit 0 ;; ++ Motorola:*:4.3:PL8-*) ++ echo powerpc-harris-powermax ++ exit 0 ;; ++ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) ++ echo powerpc-harris-powermax ++ exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; +@@ -266,15 +480,18 @@ + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` +- if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then +- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ +- -o ${TARGET_BINARY_INTERFACE}x = x ] ; then ++ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] ++ then ++ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ ++ [ ${TARGET_BINARY_INTERFACE}x = x ] ++ then + echo m88k-dg-dgux${UNAME_RELEASE} +- else ++ else + echo m88k-dg-dguxbcs${UNAME_RELEASE} ++ fi ++ else ++ echo i586-dg-dgux${UNAME_RELEASE} + fi +- else echo i586-dg-dgux${UNAME_RELEASE} +- fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 +@@ -295,12 +512,21 @@ + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' +- i?86:AIX:*:*) ++ i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; ++ ia64:AIX:*:*) ++ if [ -x /usr/bin/oslevel ] ; then ++ IBM_REV=`/usr/bin/oslevel` ++ else ++ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} ++ fi ++ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} ++ exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then +- sed 's/^ //' << EOF >dummy.c ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() +@@ -311,8 +537,7 @@ + exit(0); + } + EOF +- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 +- rm -f dummy.c dummy ++ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 +@@ -320,8 +545,9 @@ + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; +- *:AIX:*:4) +- if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then ++ *:AIX:*:[45]) ++ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` ++ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc +@@ -329,7 +555,7 @@ + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else +- IBM_REV=4.${UNAME_RELEASE} ++ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; +@@ -339,7 +565,7 @@ + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; +- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and ++ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) +@@ -354,18 +580,85 @@ + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; +- 9000/[3478]??:HP-UX:*:*) ++ 9000/[34678]??:HP-UX:*:*) ++ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; +- 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; +- 9000/8?? ) HP_ARCH=hppa1.0 ;; ++ 9000/[678][0-9][0-9]) ++ if [ -x /usr/bin/getconf ]; then ++ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` ++ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` ++ case "${sc_cpu_version}" in ++ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 ++ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 ++ 532) # CPU_PA_RISC2_0 ++ case "${sc_kernel_bits}" in ++ 32) HP_ARCH="hppa2.0n" ;; ++ 64) HP_ARCH="hppa2.0w" ;; ++ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 ++ esac ;; ++ esac ++ fi ++ if [ "${HP_ARCH}" = "" ]; then ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ ++ #define _HPUX_SOURCE ++ #include <stdlib.h> ++ #include <unistd.h> ++ ++ int main () ++ { ++ #if defined(_SC_KERNEL_BITS) ++ long bits = sysconf(_SC_KERNEL_BITS); ++ #endif ++ long cpu = sysconf (_SC_CPU_VERSION); ++ ++ switch (cpu) ++ { ++ case CPU_PA_RISC1_0: puts ("hppa1.0"); break; ++ case CPU_PA_RISC1_1: puts ("hppa1.1"); break; ++ case CPU_PA_RISC2_0: ++ #if defined(_SC_KERNEL_BITS) ++ switch (bits) ++ { ++ case 64: puts ("hppa2.0w"); break; ++ case 32: puts ("hppa2.0n"); break; ++ default: puts ("hppa2.0"); break; ++ } break; ++ #else /* !defined(_SC_KERNEL_BITS) */ ++ puts ("hppa2.0"); break; ++ #endif ++ default: puts ("hppa1.0"); break; ++ } ++ exit (0); ++ } ++EOF ++ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` ++ test -z "$HP_ARCH" && HP_ARCH=hppa ++ fi ;; + esac +- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` ++ if [ ${HP_ARCH} = "hppa2.0w" ] ++ then ++ # avoid double evaluation of $set_cc_for_build ++ test -n "$CC_FOR_BUILD" || eval $set_cc_for_build ++ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null ++ then ++ HP_ARCH="hppa2.0w" ++ else ++ HP_ARCH="hppa64" ++ fi ++ fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; ++ ia64:HP-UX:*:*) ++ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` ++ echo ia64-hp-hpux${HPUX_REV} ++ exit 0 ;; + 3050*:HI-UX:*:*) +- sed 's/^ //' << EOF >dummy.c ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () +@@ -390,8 +683,7 @@ + exit (0); + } + EOF +- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 +- rm -f dummy.c dummy ++ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) +@@ -400,13 +692,16 @@ + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; ++ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) ++ echo hppa1.0-hp-mpeix ++ exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; +- i?86:OSF1:*:*) ++ i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else +@@ -434,57 +729,82 @@ + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; +- CRAY*X-MP:*:*:*) +- echo xmp-cray-unicos +- exit 0 ;; + CRAY*Y-MP:*:*:*) +- echo ymp-cray-unicos${UNAME_RELEASE} ++ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*([A-Z]90)/\1/' \ +- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ ++ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ ++ -e 's/.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) +- echo t90-cray-unicos${UNAME_RELEASE} ++ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' + exit 0 ;; +- CRAY-2:*:*:*) +- echo cray2-cray-unicos +- exit 0 ;; +- F300:UNIX_System_V:*:*) +- FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's////'` +- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` +- echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" +- exit 0 ;; +- F301:UNIX_System_V:*:*) +- echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` +- exit 0 ;; +- hp3[0-9][05]:NetBSD:*:*) +- echo m68k-hp-netbsd${UNAME_RELEASE} ++ CRAY*T3E:*:*:*) ++ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' + exit 0 ;; +- hp300:OpenBSD:*:*) +- echo m68k-unknown-openbsd${UNAME_RELEASE} ++ CRAY*SV1:*:*:*) ++ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' + exit 0 ;; +- i?86:BSD/386:*:* | *:BSD/OS:*:*) ++ *:UNICOS/mp:*:*) ++ echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' ++ exit 0 ;; ++ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) ++ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` ++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's////'` ++ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` ++ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" ++ exit 0 ;; ++ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; +- *:FreeBSD:*:*) +- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ++ sparc*:BSD/OS:*:*) ++ echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; +- *:NetBSD:*:*) +- echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/./'` ++ *:BSD/OS:*:*) ++ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; +- *:OpenBSD:*:*) +- echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/./'` ++ *:FreeBSD:*:*) ++ # Determine whether the default compiler uses glibc. ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #include <features.h> ++ #if __GLIBC__ >= 2 ++ LIBC=gnu ++ #else ++ LIBC= ++ #endif ++EOF ++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` ++ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) +- echo ${UNAME_MACHINE}-pc-cygwin32 ++ echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; ++ i*:PW*:*) ++ echo ${UNAME_MACHINE}-pc-pw32 ++ exit 0 ;; ++ x86:Interix*:3*) ++ echo i586-pc-interix3 ++ exit 0 ;; ++ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) ++ echo i${UNAME_MACHINE}-pc-mks ++ exit 0 ;; ++ i*:Windows_NT*:* | Pentium*:Windows_NT*:*) ++ # How do we know it's Interix rather than the generic POSIX subsystem? ++ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we ++ # UNAME_MACHINE based on the output of uname instead of i386? ++ echo i586-pc-interix ++ exit 0 ;; ++ i*:UWIN*:*) ++ echo ${UNAME_MACHINE}-pc-uwin ++ exit 0 ;; + p*:CYGWIN*:*) +- echo powerpcle-unknown-cygwin32 ++ echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +@@ -492,145 +812,159 @@ + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; +- *:Linux:*:*) +- # uname on the ARM produces all sorts of strangeness, and we need to +- # filter it out. +- case "$UNAME_MACHINE" in +- arm* | sa110*) UNAME_MACHINE="arm" ;; ++ i*86:Minix:*:*) ++ echo ${UNAME_MACHINE}-pc-minix ++ exit 0 ;; ++ arm*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-gnu ++ exit 0 ;; ++ ia64:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-gnu ++ exit 0 ;; ++ m68*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-gnu ++ exit 0 ;; ++ mips:Linux:*:*) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #undef CPU ++ #undef mips ++ #undef mipsel ++ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) ++ CPU=mipsel ++ #else ++ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) ++ CPU=mips ++ #else ++ CPU= ++ #endif ++ #endif ++EOF ++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` ++ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ++ ;; ++ mips64:Linux:*:*) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #undef CPU ++ #undef mips64 ++ #undef mips64el ++ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) ++ CPU=mips64el ++ #else ++ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) ++ CPU=mips64 ++ #else ++ CPU= ++ #endif ++ #endif ++EOF ++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` ++ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 ++ ;; ++ ppc:Linux:*:*) ++ echo powerpc-unknown-linux-gnu ++ exit 0 ;; ++ ppc64:Linux:*:*) ++ echo powerpc64-unknown-linux-gnu ++ exit 0 ;; ++ alpha:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: (.*)/\1/p' < /proc/cpuinfo` in ++ EV5) UNAME_MACHINE=alphaev5 ;; ++ EV56) UNAME_MACHINE=alphaev56 ;; ++ PCA56) UNAME_MACHINE=alphapca56 ;; ++ PCA57) UNAME_MACHINE=alphapca56 ;; ++ EV6) UNAME_MACHINE=alphaev6 ;; ++ EV67) UNAME_MACHINE=alphaev67 ;; ++ EV68*) UNAME_MACHINE=alphaev68 ;; ++ esac ++ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null ++ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi ++ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ++ exit 0 ;; ++ parisc:Linux:*:* | hppa:Linux:*:*) ++ # Look for CPU level ++ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in ++ PA7*) echo hppa1.1-unknown-linux-gnu ;; ++ PA8*) echo hppa2.0-unknown-linux-gnu ;; ++ *) echo hppa-unknown-linux-gnu ;; + esac +- ++ exit 0 ;; ++ parisc64:Linux:*:* | hppa64:Linux:*:*) ++ echo hppa64-unknown-linux-gnu ++ exit 0 ;; ++ s390:Linux:*:* | s390x:Linux:*:*) ++ echo ${UNAME_MACHINE}-ibm-linux ++ exit 0 ;; ++ sh*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-gnu ++ exit 0 ;; ++ sparc:Linux:*:* | sparc64:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-gnu ++ exit 0 ;; ++ x86_64:Linux:*:*) ++ echo x86_64-unknown-linux-gnu ++ exit 0 ;; ++ i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so +- # first see if it will tell us. +- ld_help_string=`ld --help 2>&1` +- ld_supported_emulations=`echo $ld_help_string \ +- | sed -ne '/supported emulations:/!d ++ # first see if it will tell us. cd to the root directory to prevent ++ # problems with other programs or directories called `ld' in the path. ++ # Set LC_ALL=C to ensure ld outputs messages in English. ++ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ ++ | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g +- s/.*supported emulations: *// ++ s/.*supported targets: *// + s/ .*// + p'` +- case "$ld_supported_emulations" in +- i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; +- i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; +- sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; +- armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; +- m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; +- elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;; ++ case "$ld_supported_targets" in ++ elf32-i386) ++ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ++ ;; ++ a.out-i386-linux) ++ echo "${UNAME_MACHINE}-pc-linux-gnuaout" ++ exit 0 ;; ++ coff-i386) ++ echo "${UNAME_MACHINE}-pc-linux-gnucoff" ++ exit 0 ;; ++ "") ++ # Either a pre-BFD a.out linker (linux-gnuoldld) or ++ # one that does not give us useful --help. ++ echo "${UNAME_MACHINE}-pc-linux-gnuoldld" ++ exit 0 ;; + esac +- +- if test "${UNAME_MACHINE}" = "alpha" ; then +- sed 's/^ //' <<EOF >dummy.s +- .globl main +- .ent main +- main: +- .frame $30,0,$26,0 +- .prologue 0 +- .long 0x47e03d80 # implver $0 +- lda $2,259 +- .long 0x47e20c21 # amask $2,$1 +- srl $1,8,$2 +- sll $2,2,$2 +- sll $0,3,$0 +- addl $1,$0,$0 +- addl $2,$0,$0 +- ret $31,($26),1 +- .end main +-EOF +- LIBC="" +- ${CC-cc} dummy.s -o dummy 2>/dev/null +- if test "$?" = 0 ; then +- ./dummy +- case "$?" in +- 7) +- UNAME_MACHINE="alpha" +- ;; +- 15) +- UNAME_MACHINE="alphaev5" +- ;; +- 14) +- UNAME_MACHINE="alphaev56" +- ;; +- 10) +- UNAME_MACHINE="alphapca56" +- ;; +- 16) +- UNAME_MACHINE="alphaev6" +- ;; +- esac +- +- objdump --private-headers dummy | \ +- grep ld.so.1 > /dev/null +- if test "$?" = 0 ; then +- LIBC="libc1" +- fi +- fi +- rm -f dummy.s dummy +- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 +- elif test "${UNAME_MACHINE}" = "mips" ; then +- cat >dummy.c <<EOF +-main(argc, argv) +- int argc; +- char *argv[]; +-{ +-#ifdef __MIPSEB__ +- printf ("%s-unknown-linux-gnu\n", argv[1]); +-#endif +-#ifdef __MIPSEL__ +- printf ("%sel-unknown-linux-gnu\n", argv[1]); +-#endif +- return 0; +-} +-EOF +- ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 +- rm -f dummy.c dummy +- else +- # Either a pre-BFD a.out linker (linux-gnuoldld) +- # or one that does not give us useful --help. +- # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. +- # If ld does not provide *any* "supported emulations:" +- # that means it is gnuoldld. +- echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" +- test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 +- +- case "${UNAME_MACHINE}" in +- i?86) +- VENDOR=pc; +- ;; +- *) +- VENDOR=unknown; +- ;; +- esac +- # Determine whether the default compiler is a.out or elf +- cat >dummy.c <<EOF +-#include <features.h> +-main(argc, argv) +- int argc; +- char *argv[]; +-{ +-#ifdef __ELF__ +-# ifdef __GLIBC__ +-# if __GLIBC__ >= 2 +- printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +-# else +- printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +-# endif +-# else +- printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +-# endif +-#else +- printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +-#endif +- return 0; +-} ++ # Determine whether the default compiler is a.out or elf ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #include <features.h> ++ #ifdef __ELF__ ++ # ifdef __GLIBC__ ++ # if __GLIBC__ >= 2 ++ LIBC=gnu ++ # else ++ LIBC=gnulibc1 ++ # endif ++ # else ++ LIBC=gnulibc1 ++ # endif ++ #else ++ #ifdef __INTEL_COMPILER ++ LIBC=gnu ++ #else ++ LIBC=gnuaout ++ #endif ++ #endif + EOF +- ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 +- rm -f dummy.c dummy +- fi ;; +-# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +-# are messed up and put the nodename in both sysname and nodename. +- i?86:DYNIX/ptx:4*:*) ++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` ++ test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 ++ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 ++ ;; ++ i*86:DYNIX/ptx:4*:*) ++ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. ++ # earlier versions are messed up and put the nodename in both ++ # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; +- i?86:UNIX_SV:4.2MP:2.*) ++ i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, +@@ -638,28 +972,59 @@ + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; +- i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) ++ i*86:OS/2:*:*) ++ # If we were able to find `uname', then EMX Unix compatibility ++ # is probably installed. ++ echo ${UNAME_MACHINE}-pc-os2-emx ++ exit 0 ;; ++ i*86:XTS-300:*:STOP) ++ echo ${UNAME_MACHINE}-unknown-stop ++ exit 0 ;; ++ i*86:atheos:*:*) ++ echo ${UNAME_MACHINE}-unknown-atheos ++ exit 0 ;; ++ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) ++ echo i386-unknown-lynxos${UNAME_RELEASE} ++ exit 0 ;; ++ i*86:*DOS:*:*) ++ echo ${UNAME_MACHINE}-pc-msdosdjgpp ++ exit 0 ;; ++ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) ++ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's//MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then +- echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} ++ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else +- echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} ++ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; +- i?86:*:3.2:*) ++ i*86:*:5:[78]*) ++ case `/bin/uname -X | grep "^Machine"` in ++ *486*) UNAME_MACHINE=i486 ;; ++ *Pentium) UNAME_MACHINE=i586 ;; ++ *Pent*|*Celeron) UNAME_MACHINE=i686 ;; ++ esac ++ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ++ exit 0 ;; ++ i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then +- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` +- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 +- (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ ++ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` ++ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 ++ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 ++ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ ++ && UNAME_MACHINE=i686 ++ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ ++ && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) ++ # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp +@@ -681,9 +1046,15 @@ + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; ++ mc68k:UNIX:SYSTEM5:3.51m) ++ echo m68k-convergent-sysv ++ exit 0 ;; ++ M680?0:D-NIX:5.3:*) ++ echo m68k-diab-dnix ++ exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; +- 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) ++ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* ([0-9][0-9]).*/\1/p' < /etc/.relid` +@@ -694,24 +1065,27 @@ + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; +- m68*:LynxOS:2.*:*) ++ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; +- i?86:LynxOS:2.*:*) +- echo i386-unknown-lynxos${UNAME_RELEASE} +- exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; +- rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) ++ rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; ++ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) ++ echo powerpc-unknown-lynxos${UNAME_RELEASE} ++ exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; ++ RM*:ReliantUNIX-*:*:*) ++ echo mips-sni-sysv4 ++ exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; +@@ -723,8 +1097,8 @@ + echo ns32k-sni-sysv + fi + exit 0 ;; +- PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort +- # says <Richard.M.Bartel@ccMail.Census.GOV> ++ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort ++ # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) +@@ -736,25 +1110,113 @@ + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; ++ *:VOS:*:*) ++ # From Paul.Green@stratus.com. ++ echo hppa1.1-stratus-vos ++ exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; +- news*:NEWS-OS:*:6*) ++ news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; +- R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) ++ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; ++ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. ++ echo powerpc-be-beos ++ exit 0 ;; ++ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. ++ echo powerpc-apple-beos ++ exit 0 ;; ++ BePC:BeOS:*:*) # BeOS running on Intel PC compatible. ++ echo i586-pc-beos ++ exit 0 ;; ++ SX-4:SUPER-UX:*:*) ++ echo sx4-nec-superux${UNAME_RELEASE} ++ exit 0 ;; ++ SX-5:SUPER-UX:*:*) ++ echo sx5-nec-superux${UNAME_RELEASE} ++ exit 0 ;; ++ SX-6:SUPER-UX:*:*) ++ echo sx6-nec-superux${UNAME_RELEASE} ++ exit 0 ;; ++ Power*:Rhapsody:*:*) ++ echo powerpc-apple-rhapsody${UNAME_RELEASE} ++ exit 0 ;; ++ *:Rhapsody:*:*) ++ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} ++ exit 0 ;; ++ *:Darwin:*:*) ++ case `uname -p` in ++ *86) UNAME_PROCESSOR=i686 ;; ++ powerpc) UNAME_PROCESSOR=powerpc ;; ++ esac ++ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} ++ exit 0 ;; ++ *:procnto*:*:* | *:QNX:[0123456789]*:*) ++ UNAME_PROCESSOR=`uname -p` ++ if test "$UNAME_PROCESSOR" = "x86"; then ++ UNAME_PROCESSOR=i386 ++ UNAME_MACHINE=pc ++ fi ++ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} ++ exit 0 ;; ++ *:QNX:*:4*) ++ echo i386-pc-qnx ++ exit 0 ;; ++ NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) ++ echo nsr-tandem-nsk${UNAME_RELEASE} ++ exit 0 ;; ++ *:NonStop-UX:*:*) ++ echo mips-compaq-nonstopux ++ exit 0 ;; ++ BS2000:POSIX*:*:*) ++ echo bs2000-siemens-sysv ++ exit 0 ;; ++ DS/*:UNIX_System_V:*:*) ++ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} ++ exit 0 ;; ++ *:Plan9:*:*) ++ # "uname -m" is not consistent, so use $cputype instead. 386 ++ # is converted to i386 for consistency with other x86 ++ # operating systems. ++ if test "$cputype" = "386"; then ++ UNAME_MACHINE=i386 ++ else ++ UNAME_MACHINE="$cputype" ++ fi ++ echo ${UNAME_MACHINE}-unknown-plan9 ++ exit 0 ;; ++ *:TOPS-10:*:*) ++ echo pdp10-unknown-tops10 ++ exit 0 ;; ++ *:TENEX:*:*) ++ echo pdp10-unknown-tenex ++ exit 0 ;; ++ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) ++ echo pdp10-dec-tops20 ++ exit 0 ;; ++ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) ++ echo pdp10-xkl-tops20 ++ exit 0 ;; ++ *:TOPS-20:*:*) ++ echo pdp10-unknown-tops20 ++ exit 0 ;; ++ *:ITS:*:*) ++ echo pdp10-unknown-its ++ exit 0 ;; + esac + + #echo '(No uname command or uname output not recognized.)' 1>&2 + #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +-cat >dummy.c <<EOF ++eval $set_cc_for_build ++cat >$dummy.c <<EOF + #ifdef _SEQUENT_ + # include <sys/types.h> + # include <sys/utsname.h> +@@ -792,7 +1254,10 @@ + #endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach ([0-9]*).*/\1/p') 2>/dev/null`; +- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); ++ if (version < 4) ++ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); ++ else ++ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); + #endif + +@@ -837,11 +1302,24 @@ + #endif + + #if defined (vax) +-#if !defined (ultrix) +- printf ("vax-dec-bsd\n"); exit (0); +-#else +- printf ("vax-dec-ultrix\n"); exit (0); +-#endif ++# if !defined (ultrix) ++# include <sys/param.h> ++# if defined (BSD) ++# if BSD == 43 ++ printf ("vax-dec-bsd4.3\n"); exit (0); ++# else ++# if BSD == 199006 ++ printf ("vax-dec-bsd4.3reno\n"); exit (0); ++# else ++ printf ("vax-dec-bsd\n"); exit (0); ++# endif ++# endif ++# else ++ printf ("vax-dec-bsd\n"); exit (0); ++# endif ++# else ++ printf ("vax-dec-ultrix\n"); exit (0); ++# endif + #endif + + #if defined (alliant) && defined (i860) +@@ -852,8 +1330,7 @@ + } + EOF + +-${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +-rm -f dummy.c dummy ++$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + + # Apollos put the system type in the environment. + +@@ -885,6 +1362,48 @@ + esac + fi + +-#echo '(Unable to guess system type)' 1>&2 ++cat >&2 <<EOF ++$0: unable to guess system type ++ ++This script, last modified $timestamp, has failed to recognize ++the operating system you are using. It is advised that you ++download the most up to date version of the config scripts from ++ ++ ftp://ftp.gnu.org/pub/gnu/config/ ++ ++If the version you run ($0) is already up to date, please ++send the following data and any information you think might be ++pertinent to <config-patches@gnu.org> in order to provide the needed ++information to handle your system. ++ ++config.guess timestamp = $timestamp ++ ++uname -m = `(uname -m) 2>/dev/null || echo unknown` ++uname -r = `(uname -r) 2>/dev/null || echo unknown` ++uname -s = `(uname -s) 2>/dev/null || echo unknown` ++uname -v = `(uname -v) 2>/dev/null || echo unknown` ++ ++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` ++/bin/uname -X = `(/bin/uname -X) 2>/dev/null` ++ ++hostinfo = `(hostinfo) 2>/dev/null` ++/bin/universe = `(/bin/universe) 2>/dev/null` ++/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` ++/bin/arch = `(/bin/arch) 2>/dev/null` ++/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` ++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` ++ ++UNAME_MACHINE = ${UNAME_MACHINE} ++UNAME_RELEASE = ${UNAME_RELEASE} ++UNAME_SYSTEM = ${UNAME_SYSTEM} ++UNAME_VERSION = ${UNAME_VERSION} ++EOF + + exit 1 ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "timestamp='" ++# time-stamp-format: "%:y-%02m-%02d" ++# time-stamp-end: "'" ++# End: +--- ez-ipupdate-3.0.11b8.orig/config.h.in ++++ ez-ipupdate-3.0.11b8/config.h.in +@@ -1,4 +1,4 @@ +-/* config.h.in. Generated automatically from configure.in by autoheader. */ ++/* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ + + /* Define as the return type of signal handlers (int or void). */ + #undef RETSIGTYPE +@@ -132,6 +132,9 @@ + /* Define if you have the <stdarg.h> header file. */ + #undef HAVE_STDARG_H + ++/* Define if you have the <string.h> header file. */ ++#undef HAVE_STRING_H ++ + /* Define if you have the <sys/socket.h> header file. */ + #undef HAVE_SYS_SOCKET_H + +@@ -153,6 +156,9 @@ + /* Define if you have the <syslog.h> header file. */ + #undef HAVE_SYSLOG_H + ++/* Define if you have the <time.h> header file. */ ++#undef HAVE_TIME_H ++ + /* Define if you have the <unistd.h> header file. */ + #undef HAVE_UNISTD_H + +@@ -161,3 +167,10 @@ + + /* Define if you have the socket library (-lsocket). */ + #undef HAVE_LIBSOCKET ++ ++/* Name of package */ ++#undef PACKAGE ++ ++/* Version number of package */ ++#undef VERSION ++ +--- ez-ipupdate-3.0.11b8.orig/config.sub ++++ ez-ipupdate-3.0.11b8/config.sub +@@ -1,6 +1,10 @@ + #! /bin/sh +-# Configuration validation subroutine script, version 1.1. +-# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc. ++# Configuration validation subroutine script. ++# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, ++# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ ++timestamp='2003-01-03' ++ + # This file is (in principle) common to ALL GNU software. + # The presence of a machine in this file suggests that SOME GNU software + # can handle that machine. It does not imply ALL GNU software can. +@@ -25,6 +29,9 @@ + # configuration script generated by Autoconf, you may include it under + # the same distribution terms that you use for the rest of that program. + ++# Please send patches to <config-patches@gnu.org>. Submit a context ++# diff and a properly formatted ChangeLog entry. ++# + # Configuration subroutine to validate and canonicalize a configuration type. + # Supply the specified configuration type as an argument. + # If it is invalid, we print an error message on stderr and exit with code 1. +@@ -45,30 +52,73 @@ + # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM + # It is wrong to echo any other type of specification. + +-if [ x$1 = x ] +-then +- echo Configuration name missing. 1>&2 +- echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 +- echo "or $0 ALIAS" 1>&2 +- echo where ALIAS is a recognized configuration type. 1>&2 +- exit 1 +-fi ++me=`echo "$0" | sed -e 's,.*/,,'` + +-# First pass through any local machine types. +-case $1 in +- *local*) +- echo $1 +- exit 0 +- ;; +- *) +- ;; ++usage="\ ++Usage: $0 [OPTION] CPU-MFR-OPSYS ++ $0 [OPTION] ALIAS ++ ++Canonicalize a configuration name. ++ ++Operation modes: ++ -h, --help print this help, then exit ++ -t, --time-stamp print date of last modification, then exit ++ -v, --version print version number, then exit ++ ++Report bugs and patches to <config-patches@gnu.org>." ++ ++version="\ ++GNU config.sub ($timestamp) ++ ++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 ++Free Software Foundation, Inc. ++ ++This is free software; see the source for copying conditions. There is NO ++warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ++ ++help=" ++Try `$me --help' for more information." ++ ++# Parse command line ++while test $# -gt 0 ; do ++ case $1 in ++ --time-stamp | --time* | -t ) ++ echo "$timestamp" ; exit 0 ;; ++ --version | -v ) ++ echo "$version" ; exit 0 ;; ++ --help | --h* | -h ) ++ echo "$usage"; exit 0 ;; ++ -- ) # Stop option processing ++ shift; break ;; ++ - ) # Use stdin as input. ++ break ;; ++ -* ) ++ echo "$me: invalid option $1$help" ++ exit 1 ;; ++ ++ *local*) ++ # First pass through any local machine types. ++ echo $1 ++ exit 0;; ++ ++ * ) ++ break ;; ++ esac ++done ++ ++case $# in ++ 0) echo "$me: missing argument$help" >&2 ++ exit 1;; ++ 1) ;; ++ *) echo "$me: too many arguments$help" >&2 ++ exit 1;; + esac + + # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). + # Here we must recognize all the valid KERNEL-OS combinations. + maybe_os=`echo $1 | sed 's/^(.*)-([^-]*-[^-]*)$/\2/'` + case $maybe_os in +- linux-gnu*) ++ nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^(.*)-([^-]*-[^-]*)$/\1/'` + ;; +@@ -94,15 +144,33 @@ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ +- -apple) ++ -apple | -axis) + os= + basic_machine=$1 + ;; ++ -sim | -cisco | -oki | -wec | -winbond) ++ os= ++ basic_machine=$1 ++ ;; ++ -scout) ++ ;; ++ -wrs) ++ os=-vxworks ++ basic_machine=$1 ++ ;; ++ -chorusos*) ++ os=-chorusos ++ basic_machine=$1 ++ ;; ++ -chorusrdb) ++ os=-chorusrdb ++ basic_machine=$1 ++ ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) +- os=sco3.2v5 ++ os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) +@@ -121,6 +189,9 @@ + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; ++ -udk*) ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +@@ -143,26 +214,72 @@ + -psos*) + os=-psos + ;; ++ -mint | -mint[0-9]*) ++ basic_machine=m68k-atari ++ os=-mint ++ ;; + esac + + # Decode aliases for certain CPU-COMPANY combinations. + case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. +- tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ +- | arme[lb] | pyramid | mn10200 | mn10300 \ +- | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ +- | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \ +- | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \ +- | mips64 | mipsel | mips64el | mips64orion | mips64orionel \ +- | mipstx39 | mipstx39el \ +- | sparc | sparclet | sparclite | sparc64 | v850) ++ 1750a | 580 \ ++ | a29k \ ++ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ ++ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ ++ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ ++ | clipper \ ++ | d10v | d30v | dlx | dsp16xx \ ++ | fr30 | frv \ ++ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ ++ | i370 | i860 | i960 | ia64 \ ++ | ip2k \ ++ | m32r | m68000 | m68k | m88k | mcore \ ++ | mips | mipsbe | mipseb | mipsel | mipsle \ ++ | mips16 \ ++ | mips64 | mips64el \ ++ | mips64vr | mips64vrel \ ++ | mips64orion | mips64orionel \ ++ | mips64vr4100 | mips64vr4100el \ ++ | mips64vr4300 | mips64vr4300el \ ++ | mips64vr5000 | mips64vr5000el \ ++ | mipsisa32 | mipsisa32el \ ++ | mipsisa32r2 | mipsisa32r2el \ ++ | mipsisa64 | mipsisa64el \ ++ | mipsisa64sb1 | mipsisa64sb1el \ ++ | mipsisa64sr71k | mipsisa64sr71kel \ ++ | mipstx39 | mipstx39el \ ++ | mn10200 | mn10300 \ ++ | msp430 \ ++ | ns16k | ns32k \ ++ | openrisc | or32 \ ++ | pdp10 | pdp11 | pj | pjl \ ++ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ ++ | pyramid \ ++ | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ ++ | sh64 | sh64le \ ++ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ ++ | strongarm \ ++ | tahoe | thumb | tic80 | tron \ ++ | v850 | v850e \ ++ | we32k \ ++ | x86 | xscale | xstormy16 | xtensa \ ++ | z8k) ++ basic_machine=$basic_machine-unknown ++ ;; ++ m6811 | m68hc11 | m6812 | m68hc12) ++ # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown ++ os=-none ++ ;; ++ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; ++ + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. +- i[34567]86) ++ i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. +@@ -171,27 +288,79 @@ + exit 1 + ;; + # Recognize the basic CPU types with company name. +- vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ +- | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ +- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ +- | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \ +- | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \ +- | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \ +- | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \ +- | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ +- | sparc64-* | mips64-* | mipsel-* \ +- | mips64el-* | mips64orion-* | mips64orionel-* \ +- | mipstx39-* | mipstx39el-* \ +- | f301-*) ++ 580-* \ ++ | a29k-* \ ++ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ ++ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ ++ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ ++ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ ++ | avr-* \ ++ | bs2000-* \ ++ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ ++ | clipper-* | cydra-* \ ++ | d10v-* | d30v-* | dlx-* \ ++ | elxsi-* \ ++ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ ++ | h8300-* | h8500-* \ ++ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ ++ | i*86-* | i860-* | i960-* | ia64-* \ ++ | ip2k-* \ ++ | m32r-* \ ++ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ ++ | m88110-* | m88k-* | mcore-* \ ++ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ ++ | mips16-* \ ++ | mips64-* | mips64el-* \ ++ | mips64vr-* | mips64vrel-* \ ++ | mips64orion-* | mips64orionel-* \ ++ | mips64vr4100-* | mips64vr4100el-* \ ++ | mips64vr4300-* | mips64vr4300el-* \ ++ | mips64vr5000-* | mips64vr5000el-* \ ++ | mipsisa32-* | mipsisa32el-* \ ++ | mipsisa32r2-* | mipsisa32r2el-* \ ++ | mipsisa64-* | mipsisa64el-* \ ++ | mipsisa64sb1-* | mipsisa64sb1el-* \ ++ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ ++ | mipstx39-* | mipstx39el-* \ ++ | msp430-* \ ++ | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ ++ | orion-* \ ++ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ ++ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ ++ | pyramid-* \ ++ | romp-* | rs6000-* \ ++ | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ ++ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ ++ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ ++ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ ++ | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ ++ | v850-* | v850e-* | vax-* \ ++ | we32k-* \ ++ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ ++ | xtensa-* \ ++ | ymp-* \ ++ | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. ++ 386bsd) ++ basic_machine=i386-unknown ++ os=-bsd ++ ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; ++ a29khif) ++ basic_machine=a29k-amd ++ os=-udi ++ ;; ++ adobe68k) ++ basic_machine=m68010-adobe ++ os=-scout ++ ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; +@@ -207,20 +376,24 @@ + os=-sysv + ;; + amiga | amiga-*) +- basic_machine=m68k-cbm ++ basic_machine=m68k-unknown + ;; + amigaos | amigados) +- basic_machine=m68k-cbm ++ basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) +- basic_machine=m68k-cbm ++ basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; ++ apollo68bsd) ++ basic_machine=m68k-apollo ++ os=-bsd ++ ;; + aux) + basic_machine=m68k-apple + os=-aux +@@ -229,6 +402,10 @@ + basic_machine=ns32k-sequent + os=-dynix + ;; ++ c90) ++ basic_machine=c90-cray ++ os=-unicos ++ ;; + convex-c1) + basic_machine=c1-convex + os=-bsd +@@ -249,27 +426,30 @@ + basic_machine=c38-convex + os=-bsd + ;; +- cray | ymp) +- basic_machine=ymp-cray +- os=-unicos +- ;; +- cray2) +- basic_machine=cray2-cray +- os=-unicos +- ;; +- [ctj]90-cray) +- basic_machine=c90-cray ++ cray | j90) ++ basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; ++ cris | cris-* | etrax*) ++ basic_machine=cris-axis ++ ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; ++ decsystem10* | dec10*) ++ basic_machine=pdp10-dec ++ os=-tops10 ++ ;; ++ decsystem20* | dec20*) ++ basic_machine=pdp10-dec ++ os=-tops20 ++ ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola +@@ -297,6 +477,10 @@ + encore | umax | mmax) + basic_machine=ns32k-encore + ;; ++ es1800 | OSE68k | ose68k | ose | OSE) ++ basic_machine=m68k-ericsson ++ os=-ose ++ ;; + fx2800) + basic_machine=i860-alliant + ;; +@@ -307,6 +491,10 @@ + basic_machine=tron-gmicro + os=-sysv + ;; ++ go32) ++ basic_machine=i386-pc ++ os=-go32 ++ ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 +@@ -315,6 +503,14 @@ + basic_machine=h8300-hitachi + os=-hms + ;; ++ h8300xray) ++ basic_machine=h8300-hitachi ++ os=-xray ++ ;; ++ h8500hms) ++ basic_machine=h8500-hitachi ++ os=-hms ++ ;; + harris) + basic_machine=m88k-harris + os=-sysv3 +@@ -330,13 +526,30 @@ + basic_machine=m68k-hp + os=-hpux + ;; ++ hp3k9[0-9][0-9] | hp9[0-9][0-9]) ++ basic_machine=hppa1.0-hp ++ ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; +- hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) ++ hp9k6[0-9][0-9] | hp6[0-9][0-9]) ++ basic_machine=hppa1.0-hp ++ ;; ++ hp9k7[0-79][0-9] | hp7[0-79][0-9]) ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k78[0-9] | hp78[0-9]) ++ # FIXME: really hppa2.0-hp ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) ++ # FIXME: really hppa2.0-hp ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) +@@ -345,27 +558,42 @@ + hppa-next) + os=-nextstep3 + ;; ++ hppaosf) ++ basic_machine=hppa1.1-hp ++ os=-osf ++ ;; ++ hppro) ++ basic_machine=hppa1.1-hp ++ os=-proelf ++ ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm +- os=-mvs + ;; + # I'm not sure what "Sysv32" means. Should this be sysv3.2? +- i[34567]86v32) ++ i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; +- i[34567]86v4*) ++ i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; +- i[34567]86v) ++ i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; +- i[34567]86sol2) ++ i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; ++ i386mach) ++ basic_machine=i386-mach ++ os=-mach ++ ;; ++ i386-vsta | vsta) ++ basic_machine=i386-unknown ++ os=-vsta ++ ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in +@@ -391,16 +619,16 @@ + basic_machine=ns32k-utek + os=-sysv + ;; ++ mingw32) ++ basic_machine=i386-pc ++ os=-mingw32 ++ ;; + miniframe) + basic_machine=m68000-convergent + ;; +- mipsel*-linux*) +- basic_machine=mipsel-unknown +- os=-linux-gnu +- ;; +- mips*-linux*) +- basic_machine=mips-unknown +- os=-linux-gnu ++ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) ++ basic_machine=m68k-atari ++ os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` +@@ -408,10 +636,38 @@ + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; ++ mmix*) ++ basic_machine=mmix-knuth ++ os=-mmixware ++ ;; ++ monitor) ++ basic_machine=m68k-rom68k ++ os=-coff ++ ;; ++ morphos) ++ basic_machine=powerpc-unknown ++ os=-morphos ++ ;; ++ msdos) ++ basic_machine=i386-pc ++ os=-msdos ++ ;; ++ mvs) ++ basic_machine=i370-ibm ++ os=-mvs ++ ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; ++ netbsd386) ++ basic_machine=i386-unknown ++ os=-netbsd ++ ;; ++ netwinder) ++ basic_machine=armv4l-rebel ++ os=-linux ++ ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos +@@ -424,6 +680,10 @@ + basic_machine=mips-sony + os=-newsos + ;; ++ necv70) ++ basic_machine=v70-nec ++ os=-sysv ++ ;; + next | m*-next ) + basic_machine=m68k-next + case $os in +@@ -449,9 +709,40 @@ + basic_machine=i960-intel + os=-nindy + ;; ++ mon960) ++ basic_machine=i960-intel ++ os=-mon960 ++ ;; ++ nonstopux) ++ basic_machine=mips-compaq ++ os=-nonstopux ++ ;; + np1) + basic_machine=np1-gould + ;; ++ nv1) ++ basic_machine=nv1-cray ++ os=-unicosmp ++ ;; ++ nsr-tandem) ++ basic_machine=nsr-tandem ++ ;; ++ op50n-* | op60c-*) ++ basic_machine=hppa1.1-oki ++ os=-proelf ++ ;; ++ or32 | or32-*) ++ basic_machine=or32-unknown ++ os=-coff ++ ;; ++ OSE68000 | ose68000) ++ basic_machine=m68000-ericsson ++ os=-ose ++ ;; ++ os68k) ++ basic_machine=m68k-none ++ os=-os68k ++ ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 +@@ -466,51 +757,85 @@ + pbb) + basic_machine=m68k-tti + ;; +- pc532 | pc532-*) ++ pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; +- pentium | p5 | k5 | nexen) ++ pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; +- pentiumpro | p6 | k6 | 6x86) ++ pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2) +- basic_machine=i786-pc ++ basic_machine=i686-pc + ;; +- pentium-* | p5-* | k5-* | nexen-*) ++ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; +- pentiumpro-* | p6-* | k6-* | 6x86-*) ++ pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) +- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ++ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; +- power) basic_machine=rs6000-ibm ++ power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown +- ;; ++ ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown +- ;; ++ ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; ++ ppc64) basic_machine=powerpc64-unknown ++ ;; ++ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ ppc64le | powerpc64little | ppc64-le | powerpc64-little) ++ basic_machine=powerpc64le-unknown ++ ;; ++ ppc64le-* | powerpc64little-*) ++ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; + ps2) + basic_machine=i386-ibm + ;; ++ pw32) ++ basic_machine=i586-unknown ++ os=-pw32 ++ ;; ++ rom68k) ++ basic_machine=m68k-rom68k ++ os=-coff ++ ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; ++ s390 | s390-*) ++ basic_machine=s390-ibm ++ ;; ++ s390x | s390x-*) ++ basic_machine=s390x-ibm ++ ;; ++ sa29200) ++ basic_machine=a29k-amd ++ os=-udi ++ ;; ++ sb1) ++ basic_machine=mipsisa64sb1-unknown ++ ;; ++ sb1el) ++ basic_machine=mipsisa64sb1el-unknown ++ ;; + sequent) + basic_machine=i386-sequent + ;; +@@ -518,6 +843,10 @@ + basic_machine=sh-hitachi + os=-hms + ;; ++ sparclite-wrs | simso-wrs) ++ basic_machine=sparclite-wrs ++ os=-vxworks ++ ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 +@@ -525,6 +854,13 @@ + spur) + basic_machine=spur-unknown + ;; ++ st2000) ++ basic_machine=m68k-tandem ++ ;; ++ stratus) ++ basic_machine=i860-stratus ++ os=-sysv4 ++ ;; + sun2) + basic_machine=m68000-sun + ;; +@@ -565,16 +901,40 @@ + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; ++ sv1) ++ basic_machine=sv1-cray ++ os=-unicos ++ ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; ++ t3e) ++ basic_machine=alphaev5-cray ++ os=-unicos ++ ;; ++ t90) ++ basic_machine=t90-cray ++ os=-unicos ++ ;; ++ tic4x | c4x*) ++ basic_machine=tic4x-unknown ++ os=-coff ++ ;; ++ tic54x | c54x*) ++ basic_machine=tic54x-unknown ++ os=-coff ++ ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; ++ toad1) ++ basic_machine=pdp10-xkl ++ os=-tops20 ++ ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; +@@ -586,6 +946,10 @@ + basic_machine=a29k-nyu + os=-sym1 + ;; ++ v810 | necv810) ++ basic_machine=v810-nec ++ os=-none ++ ;; + vaxv) + basic_machine=vax-dec + os=-sysv +@@ -595,8 +959,8 @@ + os=-vms + ;; + vpp*|vx|vx-*) +- basic_machine=f301-fujitsu +- ;; ++ basic_machine=f301-fujitsu ++ ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks +@@ -609,13 +973,25 @@ + basic_machine=a29k-wrs + os=-vxworks + ;; +- xmp) +- basic_machine=xmp-cray +- os=-unicos ++ w65*) ++ basic_machine=w65-wdc ++ os=-none ++ ;; ++ w89k-*) ++ basic_machine=hppa1.1-winbond ++ os=-proelf + ;; +- xps | xps100) ++ xps | xps100) + basic_machine=xps100-honeywell + ;; ++ ymp) ++ basic_machine=ymp-cray ++ os=-unicos ++ ;; ++ z8k-*-coff) ++ basic_machine=z8k-unknown ++ os=-sim ++ ;; + none) + basic_machine=none-none + os=-none +@@ -623,12 +999,14 @@ + + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. +- mips) +- if [ x$os = x-linux-gnu ]; then +- basic_machine=mips-unknown +- else +- basic_machine=mips-mips +- fi ++ w89k) ++ basic_machine=hppa1.1-winbond ++ ;; ++ op50n) ++ basic_machine=hppa1.1-oki ++ ;; ++ op60c) ++ basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm +@@ -639,16 +1017,26 @@ + vax) + basic_machine=vax-dec + ;; ++ pdp10) ++ # there are many clones, so DEC is not a safe bet ++ basic_machine=pdp10-unknown ++ ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; +- sparc) ++ sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) ++ basic_machine=sh-unknown ++ ;; ++ sh64) ++ basic_machine=sh64-unknown ++ ;; ++ sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; +- cydra) ++ cydra) + basic_machine=cydra-cydrome + ;; + orion) +@@ -657,6 +1045,15 @@ + orion105) + basic_machine=clipper-highlevel + ;; ++ mac | mpw | mac-mpw) ++ basic_machine=m68k-apple ++ ;; ++ pmac | pmac-mpw) ++ basic_machine=powerpc-apple ++ ;; ++ *-unknown) ++ # Make sure to match an already-canonicalized machine name. ++ ;; + *) + echo Invalid configuration `$1': machine `$basic_machine' not recognized 1>&2 + exit 1 +@@ -710,13 +1107,41 @@ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ +- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ ++ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ +- | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ +- | -mingw32* | -linux-gnu* | -uxpv*) ++ | -chorusos* | -chorusrdb* \ ++ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ ++ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ ++ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ ++ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ ++ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ ++ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ ++ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ ++ | -powermax* | -dnix* | -microbsd*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; ++ -qnx*) ++ case $basic_machine in ++ x86-* | i*86-*) ++ ;; ++ *) ++ os=-nto$os ++ ;; ++ esac ++ ;; ++ -nto-qnx*) ++ ;; ++ -nto*) ++ os=`echo $os | sed -e 's|nto|nto-qnx|'` ++ ;; ++ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ ++ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ ++ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ++ ;; ++ -mac*) ++ os=`echo $os | sed -e 's|mac|macos|'` ++ ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; +@@ -726,6 +1151,12 @@ + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; ++ -opened*) ++ os=-openedition ++ ;; ++ -wince*) ++ os=-wince ++ ;; + -osfrose*) + os=-osfrose + ;; +@@ -741,11 +1172,23 @@ + -acis*) + os=-aos + ;; ++ -atheos*) ++ os=-atheos ++ ;; ++ -386bsd) ++ os=-bsd ++ ;; + -ctix* | -uts*) + os=-sysv + ;; ++ -nova*) ++ os=-rtmk-nova ++ ;; + -ns2 ) +- os=-nextstep2 ++ os=-nextstep2 ++ ;; ++ -nsk*) ++ os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) +@@ -772,9 +1215,18 @@ + # This must come after -sysvr4. + -sysv*) + ;; ++ -ose*) ++ os=-ose ++ ;; ++ -es1800*) ++ os=-ose ++ ;; + -xenix) + os=-xenix + ;; ++ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) ++ os=-mint ++ ;; + -none) + ;; + *) +@@ -800,10 +1252,17 @@ + *-acorn) + os=-riscix1.2 + ;; ++ arm*-rebel) ++ os=-linux ++ ;; + arm*-semi) + os=-aout + ;; +- pdp11-*) ++ # This must come before the *-dec entry. ++ pdp10-*) ++ os=-tops20 ++ ;; ++ pdp11-*) + os=-none + ;; + *-dec | vax-*) +@@ -821,15 +1280,39 @@ + # default. + # os=-sunos4 + ;; ++ m68*-cisco) ++ os=-aout ++ ;; ++ mips*-cisco) ++ os=-elf ++ ;; ++ mips*-*) ++ os=-elf ++ ;; ++ or32-*) ++ os=-coff ++ ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; ++ *-be) ++ os=-beos ++ ;; + *-ibm) + os=-aix + ;; ++ *-wec) ++ os=-proelf ++ ;; ++ *-winbond) ++ os=-proelf ++ ;; ++ *-oki) ++ os=-proelf ++ ;; + *-hp) + os=-hpux + ;; +@@ -872,27 +1355,39 @@ + *-next) + os=-nextstep3 + ;; +- *-gould) ++ *-gould) + os=-sysv + ;; +- *-highlevel) ++ *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; +- *-sgi) ++ *-sgi) + os=-irix + ;; +- *-siemens) ++ *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; +- f301-fujitsu) ++ f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; ++ *-rom68k) ++ os=-coff ++ ;; ++ *-*bug) ++ os=-coff ++ ;; ++ *-apple) ++ os=-macos ++ ;; ++ *-atari*) ++ os=-mint ++ ;; + *) + os=-none + ;; +@@ -914,9 +1409,15 @@ + -aix*) + vendor=ibm + ;; ++ -beos*) ++ vendor=be ++ ;; + -hpux*) + vendor=hp + ;; ++ -mpeix*) ++ vendor=hp ++ ;; + -hiux*) + vendor=hitachi + ;; +@@ -932,21 +1433,41 @@ + -genix*) + vendor=ns + ;; +- -mvs*) ++ -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; +- -vxsim* | -vxworks*) ++ -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; ++ -hms*) ++ vendor=hitachi ++ ;; ++ -mpw* | -macos*) ++ vendor=apple ++ ;; ++ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) ++ vendor=atari ++ ;; ++ -vos*) ++ vendor=stratus ++ ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; + esac + + echo $basic_machine$os ++exit 0 ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "timestamp='" ++# time-stamp-format: "%:y-%02m-%02d" ++# time-stamp-end: "'" ++# End: +--- ez-ipupdate-3.0.11b8.orig/configure ++++ ez-ipupdate-3.0.11b8/configure +@@ -1,7 +1,7 @@ + #! /bin/sh + + # Guess values for system-dependent variables and create Makefiles. +-# Generated automatically using autoconf version 2.12 ++# Generated automatically using autoconf version 2.13 + # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. + # + # This configure script is free software; the Free Software Foundation +@@ -58,6 +58,7 @@ + # Initialize some other variables. + subdirs= + MFLAGS= MAKEFLAGS= ++SHELL=${CONFIG_SHELL-/bin/sh} + # Maximum number of lines to put in a shell here document. + ac_max_here_lines=12 + +@@ -341,7 +342,7 @@ + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) +- echo "configure generated by autoconf version 2.12" ++ echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) +@@ -511,9 +512,11 @@ + # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. + ac_cpp='$CPP $CPPFLAGS' + ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ++ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' + cross_compiling=$ac_cv_prog_cc_cross + ++ac_exeext= ++ac_objext=o + if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then +@@ -549,6 +552,7 @@ + ac_config_sub=$ac_aux_dir/config.sub + ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + ++am__api_version="1.4" + # Find a good install program. We prefer a C program (faster), + # so one script is as good as another. But avoid the broken or + # incompatible versions: +@@ -556,28 +560,30 @@ + # SunOS /usr/etc/install + # IRIX /sbin/install + # AIX /bin/install ++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag + # AFS /usr/afsws/bin/install, which mishandles nonexistent args + # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" + # ./install, which can be erroneously created by make from ./install.sh. + echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +-echo "configure:564: checking for a BSD compatible install" >&5 ++echo "configure:569: checking for a BSD compatible install" >&5 + if test -z "$INSTALL"; then + if eval "test "`echo '$''{'ac_cv_path_install'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +- IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" ++ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. +- for ac_prog in ginstall installbsd scoinst install; do ++ # Don't use installbsd from OSF since it installs stuff as root ++ # by default. ++ for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. +- # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" +@@ -607,13 +613,12 @@ + # It thinks the first close brace ends the variable substitution. + test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +- +- + test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + ++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ++ + echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +-echo "configure:617: checking whether build environment is sane" >&5 ++echo "configure:622: checking whether build environment is sane" >&5 + # Just in case + sleep 1 + echo timestamp > conftestfile +@@ -670,7 +675,7 @@ + test "$program_transform_name" = "" && program_transform_name="s,x,x," + + echo $ac_n "checking whether ${MAKE-make} sets ${MAKE}""... $ac_c" 1>&6 +-echo "configure:674: checking whether ${MAKE-make} sets ${MAKE}" >&5 ++echo "configure:679: checking whether ${MAKE-make} sets ${MAKE}" >&5 + set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` + if eval "test "`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -715,21 +720,21 @@ + + + missing_dir=`cd $ac_aux_dir && pwd` +-echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +-echo "configure:720: checking for working aclocal" >&5 ++echo $ac_n "checking for working aclocal-${am__api_version}""... $ac_c" 1>&6 ++echo "configure:725: checking for working aclocal-${am__api_version}" >&5 + # Run test in a subshell; some versions of sh will print an error if + # an executable is not found, even if stderr is redirected. + # Redirect stdin to placate older versions of autoconf. Sigh. +-if (aclocal --version) < /dev/null > /dev/null 2>&1; then +- ACLOCAL=aclocal ++if (aclocal-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then ++ ACLOCAL=aclocal-${am__api_version} + echo "$ac_t""found" 1>&6 + else +- ACLOCAL="$missing_dir/missing aclocal" ++ ACLOCAL="$missing_dir/missing aclocal-${am__api_version}" + echo "$ac_t""missing" 1>&6 + fi + + echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +-echo "configure:733: checking for working autoconf" >&5 ++echo "configure:738: checking for working autoconf" >&5 + # Run test in a subshell; some versions of sh will print an error if + # an executable is not found, even if stderr is redirected. + # Redirect stdin to placate older versions of autoconf. Sigh. +@@ -741,21 +746,21 @@ + echo "$ac_t""missing" 1>&6 + fi + +-echo $ac_n "checking for working automake""... $ac_c" 1>&6 +-echo "configure:746: checking for working automake" >&5 ++echo $ac_n "checking for working automake-${am__api_version}""... $ac_c" 1>&6 ++echo "configure:751: checking for working automake-${am__api_version}" >&5 + # Run test in a subshell; some versions of sh will print an error if + # an executable is not found, even if stderr is redirected. + # Redirect stdin to placate older versions of autoconf. Sigh. +-if (automake --version) < /dev/null > /dev/null 2>&1; then +- AUTOMAKE=automake ++if (automake-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then ++ AUTOMAKE=automake-${am__api_version} + echo "$ac_t""found" 1>&6 + else +- AUTOMAKE="$missing_dir/missing automake" ++ AUTOMAKE="$missing_dir/missing automake-${am__api_version}" + echo "$ac_t""missing" 1>&6 + fi + + echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +-echo "configure:759: checking for working autoheader" >&5 ++echo "configure:764: checking for working autoheader" >&5 + # Run test in a subshell; some versions of sh will print an error if + # an executable is not found, even if stderr is redirected. + # Redirect stdin to placate older versions of autoconf. Sigh. +@@ -768,7 +773,7 @@ + fi + + echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +-echo "configure:772: checking for working makeinfo" >&5 ++echo "configure:777: checking for working makeinfo" >&5 + # Run test in a subshell; some versions of sh will print an error if + # an executable is not found, even if stderr is redirected. + # Redirect stdin to placate older versions of autoconf. Sigh. +@@ -806,15 +811,16 @@ + # Extract the first word of "gcc", so it can be a program name with args. + set dummy gcc; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:810: checking for $ac_word" >&5 ++echo "configure:815: checking for $ac_word" >&5 + if eval "test "`echo '$''{'ac_cv_prog_CC'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. + else +- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" +- for ac_dir in $PATH; do ++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ++ ac_dummy="$PATH" ++ for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" +@@ -835,16 +841,17 @@ + # Extract the first word of "cc", so it can be a program name with args. + set dummy cc; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +-echo "configure:839: checking for $ac_word" >&5 ++echo "configure:845: checking for $ac_word" >&5 + if eval "test "`echo '$''{'ac_cv_prog_CC'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. + else +- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" ++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no +- for ac_dir in $PATH; do ++ ac_dummy="$PATH" ++ for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then +@@ -879,25 +886,61 @@ + echo "$ac_t""no" 1>&6 + fi + ++ if test -z "$CC"; then ++ case "`uname -s`" in ++ *win32* | *WIN32*) ++ # Extract the first word of "cl", so it can be a program name with args. ++set dummy cl; ac_word=$2 ++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 ++echo "configure:896: checking for $ac_word" >&5 ++if eval "test "`echo '$''{'ac_cv_prog_CC'+set}'`" = set"; then ++ echo $ac_n "(cached) $ac_c" 1>&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ++ ac_dummy="$PATH" ++ for ac_dir in $ac_dummy; do ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/$ac_word; then ++ ac_cv_prog_CC="cl" ++ break ++ fi ++ done ++ IFS="$ac_save_ifs" ++fi ++fi ++CC="$ac_cv_prog_CC" ++if test -n "$CC"; then ++ echo "$ac_t""$CC" 1>&6 ++else ++ echo "$ac_t""no" 1>&6 ++fi ++ ;; ++ esac ++ fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in $PATH" 1>&2; exit 1; } + fi + + echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +-echo "configure:887: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ++echo "configure:928: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + + ac_ext=c + # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. + ac_cpp='$CPP $CPPFLAGS' + ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ++ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' + cross_compiling=$ac_cv_prog_cc_cross + +-cat > conftest.$ac_ext <<EOF +-#line 897 "configure" ++cat > conftest.$ac_ext << EOF ++ ++#line 939 "configure" + #include "confdefs.h" ++ + main(){return(0);} + EOF +-if { (eval echo configure:901: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ++if { (eval echo configure:944: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then +@@ -911,18 +954,24 @@ + ac_cv_prog_cc_works=no + fi + rm -fr conftest* ++ac_ext=c ++# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ++ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' ++cross_compiling=$ac_cv_prog_cc_cross + + echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 + if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } + fi + echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +-echo "configure:921: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 ++echo "configure:970: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 + echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 + cross_compiling=$ac_cv_prog_cc_cross + + echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +-echo "configure:926: checking whether we are using GNU C" >&5 ++echo "configure:975: checking whether we are using GNU C" >&5 + if eval "test "`echo '$''{'ac_cv_prog_gcc'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -931,7 +980,7 @@ + yes; + #endif + EOF +-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:935: "$ac_try") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:984: "$ac_try") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes + else + ac_cv_prog_gcc=no +@@ -942,11 +991,15 @@ + + if test $ac_cv_prog_gcc = yes; then + GCC=yes +- ac_test_CFLAGS="${CFLAGS+set}" +- ac_save_CFLAGS="$CFLAGS" +- CFLAGS= +- echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +-echo "configure:950: checking whether ${CC-cc} accepts -g" >&5 ++else ++ GCC= ++fi ++ ++ac_test_CFLAGS="${CFLAGS+set}" ++ac_save_CFLAGS="$CFLAGS" ++CFLAGS= ++echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 ++echo "configure:1003: checking whether ${CC-cc} accepts -g" >&5 + if eval "test "`echo '$''{'ac_cv_prog_cc_g'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +@@ -961,20 +1014,24 @@ + fi + + echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +- if test "$ac_test_CFLAGS" = set; then +- CFLAGS="$ac_save_CFLAGS" +- elif test $ac_cv_prog_cc_g = yes; then ++if test "$ac_test_CFLAGS" = set; then ++ CFLAGS="$ac_save_CFLAGS" ++elif test $ac_cv_prog_cc_g = yes; then ++ if test "$GCC" = yes; then + CFLAGS="-g -O2" + else +- CFLAGS="-O2" ++ CFLAGS="-g" + fi + else +- GCC= +- test "${CFLAGS+set}" = set || CFLAGS="-g" ++ if test "$GCC" = yes; then ++ CFLAGS="-O2" ++ else ++ CFLAGS= ++ fi + fi + + echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +-echo "configure:978: checking how to run the C preprocessor" >&5 ++echo "configure:1035: checking how to run the C preprocessor" >&5 + # On Suns, sometimes $CPP names a directory. + if test -n "$CPP" && test -d "$CPP"; then + CPP= +@@ -989,14 +1046,14 @@ + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +-#line 993 "configure" ++#line 1050 "configure" + #include "confdefs.h" + #include <assert.h> + Syntax Error + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:999: "$ac_try") 1>&5; (eval $ac_try) 2>&5; } +-ac_err=`grep -v '^ *+' conftest.out` ++{ (eval echo configure:1056: "$ac_try") 1>&5; (eval $ac_try) 2>&5; } ++ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}$"` + if test -z "$ac_err"; then + : + else +@@ -1006,14 +1063,31 @@ + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +-#line 1010 "configure" ++#line 1067 "configure" + #include "confdefs.h" + #include <assert.h> + Syntax Error + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:1016: "$ac_try") 1>&5; (eval $ac_try) 2>&5; } +-ac_err=`grep -v '^ *+' conftest.out` ++{ (eval echo configure:1073: "$ac_try") 1>&5; (eval $ac_try) 2>&5; } ++ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}$"` ++if test -z "$ac_err"; then ++ : ++else ++ echo "$ac_err" >&5 ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ rm -rf conftest* ++ CPP="${CC-cc} -nologo -E" ++ cat > conftest.$ac_ext <<EOF ++#line 1084 "configure" ++#include "confdefs.h" ++#include <assert.h> ++Syntax Error ++EOF ++ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ++{ (eval echo configure:1090: "$ac_try") 1>&5; (eval $ac_try) 2>&5; } ++ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}$"` + if test -z "$ac_err"; then + : + else +@@ -1026,6 +1100,8 @@ + rm -f conftest* + fi + rm -f conftest* ++fi ++rm -f conftest* + ac_cv_prog_CPP="$CPP" + fi + CPP="$ac_cv_prog_CPP" +@@ -1041,28 +1117,30 @@ + # SunOS /usr/etc/install + # IRIX /sbin/install + # AIX /bin/install ++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag + # AFS /usr/afsws/bin/install, which mishandles nonexistent args + # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" + # ./install, which can be erroneously created by make from ./install.sh. + echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +-echo "configure:1049: checking for a BSD compatible install" >&5 ++echo "configure:1126: checking for a BSD compatible install" >&5 + if test -z "$INSTALL"; then + if eval "test "`echo '$''{'ac_cv_path_install'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else +- IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" ++ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. +- for ac_prog in ginstall installbsd scoinst install; do ++ # Don't use installbsd from OSF since it installs stuff as root ++ # by default. ++ for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. +- # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" +@@ -1092,16 +1170,18 @@ + # It thinks the first close brace ends the variable substitution. + test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + ++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' ++ + test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + + echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +-echo "configure:1100: checking return type of signal handlers" >&5 ++echo "configure:1180: checking return type of signal handlers" >&5 + if eval "test "`echo '$''{'ac_cv_type_signal'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <<EOF +-#line 1105 "configure" ++#line 1185 "configure" + #include "confdefs.h" + #include <sys/types.h> + #include <signal.h> +@@ -1118,7 +1198,7 @@ + int i; + ; return 0; } + EOF +-if { (eval echo configure:1122: "$ac_compile") 1>&5; (eval $ac_compile) 2>&5; }; then ++if { (eval echo configure:1202: "$ac_compile") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_type_signal=void + else +@@ -1139,12 +1219,12 @@ + + + echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 +-echo "configure:1143: checking for gethostbyname" >&5 ++echo "configure:1223: checking for gethostbyname" >&5 + if eval "test "`echo '$''{'ac_cv_func_gethostbyname'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <<EOF +-#line 1148 "configure" ++#line 1228 "configure" + #include "confdefs.h" + /* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname(); below. */ +@@ -1167,7 +1247,7 @@ + + ; return 0; } + EOF +-if { (eval echo configure:1171: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ++if { (eval echo configure:1251: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_gethostbyname=yes" + else +@@ -1188,7 +1268,7 @@ + + if test $ac_cv_func_gethostbyname = no; then + echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 +-echo "configure:1192: checking for gethostbyname in -lnsl" >&5 ++echo "configure:1272: checking for gethostbyname in -lnsl" >&5 + ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` + if eval "test "`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -1196,7 +1276,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lnsl $LIBS" + cat > conftest.$ac_ext <<EOF +-#line 1200 "configure" ++#line 1280 "configure" + #include "confdefs.h" + /* Override any gcc2 internal prototype to avoid an error. */ + /* We use char because int might match the return type of a gcc2 +@@ -1207,7 +1287,7 @@ + gethostbyname() + ; return 0; } + EOF +-if { (eval echo configure:1211: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ++if { (eval echo configure:1291: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -1236,12 +1316,12 @@ + + fi + echo $ac_n "checking for connect""... $ac_c" 1>&6 +-echo "configure:1240: checking for connect" >&5 ++echo "configure:1320: checking for connect" >&5 + if eval "test "`echo '$''{'ac_cv_func_connect'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <<EOF +-#line 1245 "configure" ++#line 1325 "configure" + #include "confdefs.h" + /* System header to define __stub macros and hopefully few prototypes, + which can conflict with char connect(); below. */ +@@ -1264,7 +1344,7 @@ + + ; return 0; } + EOF +-if { (eval echo configure:1268: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ++if { (eval echo configure:1348: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_connect=yes" + else +@@ -1285,7 +1365,7 @@ + + if test $ac_cv_func_connect = no; then + echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 +-echo "configure:1289: checking for connect in -lsocket" >&5 ++echo "configure:1369: checking for connect in -lsocket" >&5 + ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` + if eval "test "`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -1293,7 +1373,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lsocket $LIBS" + cat > conftest.$ac_ext <<EOF +-#line 1297 "configure" ++#line 1377 "configure" + #include "confdefs.h" + /* Override any gcc2 internal prototype to avoid an error. */ + /* We use char because int might match the return type of a gcc2 +@@ -1304,7 +1384,7 @@ + connect() + ; return 0; } + EOF +-if { (eval echo configure:1308: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ++if { (eval echo configure:1388: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -1364,12 +1444,12 @@ + herror + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:1368: checking for $ac_func" >&5 ++echo "configure:1448: checking for $ac_func" >&5 + if eval "test "`echo '$''{'ac_cv_func_$ac_func'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <<EOF +-#line 1373 "configure" ++#line 1453 "configure" + #include "confdefs.h" + /* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +@@ -1392,7 +1472,7 @@ + + ; return 0; } + EOF +-if { (eval echo configure:1396: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ++if { (eval echo configure:1476: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -1419,10 +1499,12 @@ + + for ac_hdr in arpa/inet.h \ + sys/types.h \ ++ time.h \ + sys/time.h \ + sys/stat.h \ + fcntl.h \ + signal.h \ ++ string.h \ + syslog.h \ + pwd.h \ + stdarg.h \ +@@ -1434,18 +1516,18 @@ + do + ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` + echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +-echo "configure:1438: checking for $ac_hdr" >&5 ++echo "configure:1520: checking for $ac_hdr" >&5 + if eval "test "`echo '$''{'ac_cv_header_$ac_safe'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <<EOF +-#line 1443 "configure" ++#line 1525 "configure" + #include "confdefs.h" + #include <$ac_hdr> + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:1448: "$ac_try") 1>&5; (eval $ac_try) 2>&5; } +-ac_err=`grep -v '^ *+' conftest.out` ++{ (eval echo configure:1530: "$ac_try") 1>&5; (eval $ac_try) 2>&5; } ++ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}$"` + if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +@@ -1478,18 +1560,18 @@ + do + ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` + echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +-echo "configure:1482: checking for $ac_hdr" >&5 ++echo "configure:1564: checking for $ac_hdr" >&5 + if eval "test "`echo '$''{'ac_cv_header_$ac_safe'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <<EOF +-#line 1487 "configure" ++#line 1569 "configure" + #include "confdefs.h" + #include <$ac_hdr> + EOF + ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +-{ (eval echo configure:1492: "$ac_try") 1>&5; (eval $ac_try) 2>&5; } +-ac_err=`grep -v '^ *+' conftest.out` ++{ (eval echo configure:1574: "$ac_try") 1>&5; (eval $ac_try) 2>&5; } ++ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}$"` + if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +@@ -1517,7 +1599,7 @@ + + + echo $ac_n "checking for sys_errlist in -lc""... $ac_c" 1>&6 +-echo "configure:1521: checking for sys_errlist in -lc" >&5 ++echo "configure:1603: checking for sys_errlist in -lc" >&5 + ac_lib_var=`echo c'_'sys_errlist | sed 'y%./+-%__p_%'` + if eval "test "`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +@@ -1525,7 +1607,7 @@ + ac_save_LIBS="$LIBS" + LIBS="-lc $LIBS" + cat > conftest.$ac_ext <<EOF +-#line 1529 "configure" ++#line 1611 "configure" + #include "confdefs.h" + /* Override any gcc2 internal prototype to avoid an error. */ + /* We use char because int might match the return type of a gcc2 +@@ -1536,7 +1618,7 @@ + sys_errlist() + ; return 0; } + EOF +-if { (eval echo configure:1540: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ++if { (eval echo configure:1622: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else +@@ -1563,12 +1645,12 @@ + for ac_func in getopt + do + echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +-echo "configure:1567: checking for $ac_func" >&5 ++echo "configure:1649: checking for $ac_func" >&5 + if eval "test "`echo '$''{'ac_cv_func_$ac_func'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <<EOF +-#line 1572 "configure" ++#line 1654 "configure" + #include "confdefs.h" + /* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +@@ -1591,7 +1673,7 @@ + + ; return 0; } + EOF +-if { (eval echo configure:1595: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ++if { (eval echo configure:1677: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" + else +@@ -1620,12 +1702,12 @@ + fi + + echo $ac_n "checking for getpass""... $ac_c" 1>&6 +-echo "configure:1624: checking for getpass" >&5 ++echo "configure:1706: checking for getpass" >&5 + if eval "test "`echo '$''{'ac_cv_func_getpass'+set}'`" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + cat > conftest.$ac_ext <<EOF +-#line 1629 "configure" ++#line 1711 "configure" + #include "confdefs.h" + /* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getpass(); below. */ +@@ -1648,7 +1730,7 @@ + + ; return 0; } + EOF +-if { (eval echo configure:1652: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ++if { (eval echo configure:1734: "$ac_link") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_getpass=yes" + else +@@ -1675,26 +1757,26 @@ + + + # Make sure we can run config.sub. +-if $ac_config_sub sun4 >/dev/null 2>&1; then : ++if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : + else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } + fi + + echo $ac_n "checking host system type""... $ac_c" 1>&6 +-echo "configure:1684: checking host system type" >&5 ++echo "configure:1766: checking host system type" >&5 + + host_alias=$host + case "$host_alias" in + NONE) + case $nonopt in + NONE) +- if host_alias=`$ac_config_guess`; then : ++ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; + esac + +-host=`$ac_config_sub $host_alias` ++host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` + host_cpu=`echo $host | sed 's/^([^-]*)-([^-]*)-(.*)$/\1/'` + host_vendor=`echo $host | sed 's/^([^-]*)-([^-]*)-(.*)$/\2/'` + host_os=`echo $host | sed 's/^([^-]*)-([^-]*)-(.*)$/\3/'` +@@ -1706,7 +1788,7 @@ + + + echo $ac_n "checking for user supplied default service""... $ac_c" 1>&6 +-echo "configure:1710: checking for user supplied default service" >&5 ++echo "configure:1792: checking for user supplied default service" >&5 + # Check whether --enable-default-service or --disable-default-service was given. + if test "${enable_default_service+set}" = set; then + enableval="$enable_default_service" +@@ -1800,7 +1882,7 @@ + esac + + echo $ac_n "checking whether user wants debugging support""... $ac_c" 1>&6 +-echo "configure:1804: checking whether user wants debugging support" >&5 ++echo "configure:1886: checking whether user wants debugging support" >&5 + # Check whether --enable-debug or --disable-debug was given. + if test "${enable_debug+set}" = set; then + enableval="$enable_debug" +@@ -1815,7 +1897,7 @@ + + + echo $ac_n "checking whether user wants to dissable MD5 support""... $ac_c" 1>&6 +-echo "configure:1819: checking whether user wants to dissable MD5 support" >&5 ++echo "configure:1901: checking whether user wants to dissable MD5 support" >&5 + # Check whether --enable-md5 or --disable-md5 was given. + if test "${enable_md5+set}" = set; then + enableval="$enable_md5" +@@ -1855,7 +1937,7 @@ + # Ultrix sh set writes to stderr and can't be redirected directly, + # and sets the high bit in the cache file unless we assign to the vars. + (set) 2>&1 | +- case `(ac_space=' '; set) 2>&1` in ++ case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\ into \, and sed turns \ into ). +@@ -1922,7 +2004,7 @@ + echo "running ${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec ${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) +- echo "$CONFIG_STATUS generated by autoconf version 2.12" ++ echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "$ac_cs_usage"; exit 0 ;; +@@ -1942,9 +2024,11 @@ + s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF + $ac_vpsub + $extrasub ++s%@SHELL@%$SHELL%g + s%@CFLAGS@%$CFLAGS%g + s%@CPPFLAGS@%$CPPFLAGS%g + s%@CXXFLAGS@%$CXXFLAGS%g ++s%@FFLAGS@%$FFLAGS%g + s%@DEFS@%$DEFS%g + s%@LDFLAGS@%$LDFLAGS%g + s%@LIBS@%$LIBS%g +@@ -1964,8 +2048,8 @@ + s%@infodir@%$infodir%g + s%@mandir@%$mandir%g + s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +-s%@INSTALL_DATA@%$INSTALL_DATA%g + s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g ++s%@INSTALL_DATA@%$INSTALL_DATA%g + s%@PACKAGE@%$PACKAGE%g + s%@VERSION@%$VERSION%g + s%@ACLOCAL@%$ACLOCAL%g +--- ez-ipupdate-3.0.11b8.orig/configure.in ++++ ez-ipupdate-3.0.11b8/configure.in +@@ -58,10 +58,12 @@ + dnl Checks for header files. + AC_CHECK_HEADERS( arpa/inet.h \ + sys/types.h \ ++ time.h \ + sys/time.h \ + sys/stat.h \ + fcntl.h \ + signal.h \ ++ string.h \ + syslog.h \ + pwd.h \ + stdarg.h \ +--- ez-ipupdate-3.0.11b8.orig/install-sh ++++ ez-ipupdate-3.0.11b8/install-sh +@@ -118,6 +118,7 @@ + + if [ -d $dst ]; then + instcmd=: ++ chmodcmd="" + else + instcmd=mkdir + fi +@@ -162,7 +163,7 @@ + + # Skip lots of stat calls in the usual case. + if [ ! -d "$dstdir" ]; then +-defaultIFS=' ++defaultIFS=' + ' + IFS="${IFS-${defaultIFS}}" + +--- ez-ipupdate-3.0.11b8.orig/missing ++++ ez-ipupdate-3.0.11b8/missing +@@ -1 +1,198 @@ +-#autoconf complains if this is not here ++#! /bin/sh ++# Common stub for a few missing GNU programs while installing. ++# Copyright (C) 1996, 1997, 2001, 2002 Free Software Foundation, Inc. ++# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2, or (at your option) ++# any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++# 02111-1307, USA. ++ ++if test $# -eq 0; then ++ echo 1>&2 "Try `$0 --help' for more information" ++ exit 1 ++fi ++ ++# In the cases where this matters, `missing' is being run in the ++# srcdir already. ++if test -f configure.in; then ++ configure_ac=configure.ac ++else ++ configure_ac=configure.in ++fi ++ ++case "$1" in ++ ++ -h|--h|--he|--hel|--help) ++ echo "\ ++$0 [OPTION]... PROGRAM [ARGUMENT]... ++ ++Handle `PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an ++error status if there is no known handling for PROGRAM. ++ ++Options: ++ -h, --help display this help and exit ++ -v, --version output version information and exit ++ ++Supported PROGRAM values: ++ aclocal touch file `aclocal.m4' ++ autoconf touch file `configure' ++ autoheader touch file `config.h.in' ++ automake touch all `Makefile.in' files ++ bison create `y.tab.[ch]', if possible, from existing .[ch] ++ flex create `lex.yy.c', if possible, from existing .c ++ lex create `lex.yy.c', if possible, from existing .c ++ makeinfo touch the output file ++ yacc create `y.tab.[ch]', if possible, from existing .[ch]" ++ ;; ++ ++ -v|--v|--ve|--ver|--vers|--versi|--versio|--version) ++ echo "missing - GNU libit 0.0" ++ ;; ++ ++ -*) ++ echo 1>&2 "$0: Unknown `$1' option" ++ echo 1>&2 "Try `$0 --help' for more information" ++ exit 1 ++ ;; ++ ++ aclocal*) ++ echo 1>&2 "\ ++WARNING: `$1' is missing on your system. You should only need it if ++ you modified `acinclude.m4' or `$configure_ac'. You might want ++ to install the `Automake' and `Perl' packages. Grab them from ++ any GNU archive site." ++ touch aclocal.m4 ++ ;; ++ ++ autoconf) ++ echo 1>&2 "\ ++WARNING: `$1' is missing on your system. You should only need it if ++ you modified `$configure_ac'. You might want to install the ++ `Autoconf' and `GNU m4' packages. Grab them from any GNU ++ archive site." ++ touch configure ++ ;; ++ ++ autoheader) ++ echo 1>&2 "\ ++WARNING: `$1' is missing on your system. You should only need it if ++ you modified `acconfig.h' or `$configure_ac'. You might want ++ to install the `Autoconf' and `GNU m4' packages. Grab them ++ from any GNU archive site." ++ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(([^)]*)).*/\1/p' $configure_ac` ++ test -z "$files" && files="config.h" ++ touch_files= ++ for f in $files; do ++ case "$f" in ++ *:*) touch_files="$touch_files "`echo "$f" | ++ sed -e 's/^[^:]*://' -e 's/:.*//'`;; ++ *) touch_files="$touch_files $f.in";; ++ esac ++ done ++ touch $touch_files ++ ;; ++ ++ automake*) ++ echo 1>&2 "\ ++WARNING: `$1' is missing on your system. You should only need it if ++ you modified `Makefile.am', `acinclude.m4' or `$configure_ac'. ++ You might want to install the `Automake' and `Perl' packages. ++ Grab them from any GNU archive site." ++ find . -type f -name Makefile.am -print | ++ sed 's/.am$/.in/' | ++ while read f; do touch "$f"; done ++ ;; ++ ++ bison|yacc) ++ echo 1>&2 "\ ++WARNING: `$1' is missing on your system. You should only need it if ++ you modified a `.y' file. You may need the `Bison' package ++ in order for those modifications to take effect. You can get ++ `Bison' from any GNU archive site." ++ rm -f y.tab.c y.tab.h ++ if [ $# -ne 1 ]; then ++ eval LASTARG="${$#}" ++ case "$LASTARG" in ++ *.y) ++ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` ++ if [ -f "$SRCFILE" ]; then ++ cp "$SRCFILE" y.tab.c ++ fi ++ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` ++ if [ -f "$SRCFILE" ]; then ++ cp "$SRCFILE" y.tab.h ++ fi ++ ;; ++ esac ++ fi ++ if [ ! -f y.tab.h ]; then ++ echo >y.tab.h ++ fi ++ if [ ! -f y.tab.c ]; then ++ echo 'main() { return 0; }' >y.tab.c ++ fi ++ ;; ++ ++ lex|flex) ++ echo 1>&2 "\ ++WARNING: `$1' is missing on your system. You should only need it if ++ you modified a `.l' file. You may need the `Flex' package ++ in order for those modifications to take effect. You can get ++ `Flex' from any GNU archive site." ++ rm -f lex.yy.c ++ if [ $# -ne 1 ]; then ++ eval LASTARG="${$#}" ++ case "$LASTARG" in ++ *.l) ++ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` ++ if [ -f "$SRCFILE" ]; then ++ cp "$SRCFILE" lex.yy.c ++ fi ++ ;; ++ esac ++ fi ++ if [ ! -f lex.yy.c ]; then ++ echo 'main() { return 0; }' >lex.yy.c ++ fi ++ ;; ++ ++ makeinfo) ++ echo 1>&2 "\ ++WARNING: `$1' is missing on your system. You should only need it if ++ you modified a `.texi' or `.texinfo' file, or any other file ++ indirectly affecting the aspect of the manual. The spurious ++ call might also be the consequence of using a buggy `make' (AIX, ++ DU, IRIX). You might want to install the `Texinfo' package or ++ the `GNU make' package. Grab either from any GNU archive site." ++ file=`echo "$*" | sed -n 's/.*-o ([^ ]*).*/\1/p'` ++ if test -z "$file"; then ++ file=`echo "$*" | sed 's/.* ([^ ]*) *$/\1/'` ++ file=`sed -n '/^@setfilename/ { s/.* ([^ ]*) *$/\1/; p; q; }' $file` ++ fi ++ touch $file ++ ;; ++ ++ *) ++ echo 1>&2 "\ ++WARNING: `$1' is needed, and you do not seem to have it handy on your ++ system. You might have modified some files without having the ++ proper tools for further handling them. Check the `README' file, ++ it often tells you about the needed prerequirements for installing ++ this package. You may also peek at any GNU archive site, in case ++ some other package would contain this missing `$1' program." ++ exit 1 ++ ;; ++esac ++ ++exit 0 +--- ez-ipupdate-3.0.11b8.orig/mkinstalldirs ++++ ez-ipupdate-3.0.11b8/mkinstalldirs +@@ -4,7 +4,7 @@ + # Created: 1993-05-16 + # Public domain + +-# $Id: mkinstalldirs,v 1.1.1.1 1999/04/19 00:34:59 amackay Exp $ ++# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ + + errstatus=0 + +@@ -22,7 +22,7 @@ + esac + + if test ! -d "$pathcomp"; then +- echo "mkdir $pathcomp" 1>&2 ++ echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + +--- ez-ipupdate-3.0.11b8.orig/ez-ipupdate.c ++++ ez-ipupdate-3.0.11b8/ez-ipupdate.c +@@ -139,6 +139,9 @@ + #if HAVE_SIGNAL_H + # include <signal.h> + #endif ++#if HAVE_TIME_H ++# include <time.h> ++#endif + #if HAVE_SYS_TIME_H + # include <sys/time.h> + #endif +@@ -165,7 +168,7 @@ + #endif + + +-#if __linux__ || __SVR4 || __OpenBSD__ || __FreeBSD__ || __NetBSD__ ++#if __GLIBC__ || __SVR4 || __OpenBSD__ || __FreeBSD__ || __NetBSD__ + # define IF_LOOKUP 1 + # include <sys/ioctl.h> + # include <net/if.h> +@@ -640,7 +643,7 @@ + fprintf(stdout, " -q, --quiet \t\t\tbe quiet\n"); + fprintf(stdout, " -r, --retrys <num>\t\tnumber of trys (default: 1)\n"); + fprintf(stdout, " -R, --run-as-user <user>\tchange to <user> for running, be ware\n\t\t\t\tthat this can cause problems with handeling\n\t\t\t\tSIGHUP properly if that user can't read the\n\t\t\t\tconfig file. also it can't write it's pid file \n\t\t\t\tto a root directory\n"); +- fprintf(stdout, " -Q, --run-as-euser <user>\tchange to effective <user> for running, \n\t\t\t\tthis is NOT secure but it does solve the \n\t\t\t\tproblems with run-as-user and config files and \n\t\t\t\tpid files.\n"); ++ fprintf(stdout, " -Q, --run-as-euser <user>\tchange to effective <user> for running, \n\t\t\t\tthis is NOT secure but it does solve the \n\t\t\t\tproblems with run-as-user and config files and \n\t\t\t\tpid files\n"); + fprintf(stdout, " -s, --server <server[:port]>\tthe server to connect to\n"); + fprintf(stdout, " -S, --service-type <server>\tthe type of service that you are using\n"); + width = fprintf(stdout, "\t\t\t\ttry one of: ") + 4*7; +@@ -682,7 +685,7 @@ + + void print_signalhelp( void ) + { +- fprintf(stdout, "\nsignals are only really used when in daemon mode.\n\n"); ++ fprintf(stdout, "\nsignals are only really used when in daemon mode\n\n"); + fprintf(stdout, "signals: \n"); + fprintf(stdout, " HUP\t\tcauses it to re-read its config file\n"); + fprintf(stdout, " TERM\t\twake up and possibly perform an update\n"); +@@ -693,7 +696,7 @@ + #if HAVE_SIGNAL_H + RETSIGTYPE sigint_handler(int sig) + { +- char message[] = "interupted.\n"; ++ char message[] = "interrupted\n"; + close(client_sockfd); + write(2, message, sizeof(message)-1); + +@@ -704,6 +707,10 @@ + } + #endif + ++#if HAVE_SYSLOG_H ++ closelog(); ++#endif ++ + exit(1); + } + RETSIGTYPE generic_sig_handler(int sig) +@@ -798,7 +805,7 @@ + sprintf(buf, "message incomplete because your OS sucks: %s\n", fmt); + #endif + +- syslog(LOG_NOTICE, buf); ++ syslog(LOG_NOTICE, "%s", buf); + } + else + { +@@ -1439,7 +1446,7 @@ + if(!(options & OPT_QUIET)) + { + fprintf(stderr, +- "connected to %s (%s) on port %d.\n", ++ "connected to %s (%s) on port %d\n", + host, + inet_ntoa(address.sin_addr), + ntohs(address.sin_port)); +@@ -1683,7 +1690,7 @@ + close(client_sockfd); + return(-1); + } +- if(strstr(buf, "\r\n") > 0) ++ if(strstr(buf, "\n") != NULL) + { + break; + } +@@ -1702,8 +1709,8 @@ + + if(options & OPT_DAEMON) + { +- fprintf(stderr, "no compile time default service was set therefor you must " +- "specify a service type.\n"); ++ fprintf(stderr, "no compile time default service was set, you must " ++ "specify a service type\n"); + + return(-1); + } +@@ -2039,7 +2046,7 @@ + } + else if(strstr(buf, "\nnumhost") != NULL) + { +- show_message("Too many or too few hosts found\n"); ++ show_message("too many or too few hosts found\n"); + retval = UPDATERES_SHUTDOWN; + } + else if(strstr(buf, "\ndnserr") != NULL) +@@ -2051,17 +2058,17 @@ + } + else if(strstr(buf, "\n911") != NULL) + { +- show_message("Ahhhh! call 911!\n"); ++ show_message("ahhhh! call 911!\n"); + retval = UPDATERES_SHUTDOWN; + } + else if(strstr(buf, "\n999") != NULL) + { +- show_message("Ahhhh! call 999!\n"); ++ show_message("ahhhh! call 999!\n"); + retval = UPDATERES_SHUTDOWN; + } + else if(strstr(buf, "\n!donator") != NULL) + { +- show_message("a feature requested is only available to donators, please donate.\n", host); ++ show_message("a feature requested is only available to donators, please donate\n", host); + retval = UPDATERES_OK; + } + // this one should be last as it is a stupid string to signify waits +@@ -2095,9 +2102,9 @@ + sprintf(reason, "problem parsing reason for wait response"); + } + +- show_message("Wait response received, waiting for %s before next update.\n", ++ show_message("wait response received, waiting for %s before next update\n", + format_time(howlong)); +- show_message("Wait response reason: %d\n", N_STR(reason)); ++ show_message("wait response reason: %d\n", N_STR(reason)); + sleep(howlong); + retval = UPDATERES_ERROR; + } +@@ -3370,7 +3377,7 @@ + { + if(!(options & OPT_QUIET)) + { +- fprintf(stderr, "warning: for GNUDIP the "address" parpameter is only used if set to "0.0.0.0" thus making an offline request.\n"); ++ fprintf(stderr, "warning: for GNUDIP the "address" parameter is only used if set to "0.0.0.0" thus making an offline request\n"); + } + } + +@@ -3392,7 +3399,7 @@ + + // send an offline request if address 0.0.0.0 is used + // otherwise, we ignore the address and send an update request +- gnudip_request[0] = strcmp(address, "0.0.0.0") == 0 ? '1' : '0'; ++ gnudip_request[0] = address && strcmp(address, "0.0.0.0") == 0 ? '1' : '0'; + gnudip_request[1] = '\0'; + + // find domainname +@@ -3943,22 +3950,22 @@ + break; + + case 201: +- show_message("Last update was less than %d seconds ago.\n", 300); ++ show_message("last update was less than %d seconds ago\n", 300); + return(UPDATERES_ERROR); + break; + + case 202: +- show_message("Server error.\n"); ++ show_message("server error\n"); + return(UPDATERES_ERROR); + break; + + case 203: +- show_message("Failure because account is frozen (by admin).\n"); ++ show_message("failure because account is frozen (by admin)\n"); + return(UPDATERES_SHUTDOWN); + break; + + case 204: +- show_message("Failure because account is locked (by user).\n"); ++ show_message("failure because account is locked (by user)\n"); + return(UPDATERES_SHUTDOWN); + break; + +@@ -4215,8 +4222,6 @@ + + switch(ret) + { +- char *p; +- + case -1: + if(!(options & OPT_QUIET)) + { +@@ -4349,7 +4354,7 @@ + case SIGHUP: + if(config_file) + { +- show_message("SIGHUP recieved, re-reading config file\n"); ++ show_message("SIGHUP received, re-reading config file\n"); + if(parse_conf_file(config_file, conf_commands) != 0) + { + show_message("error parsing config file "%s"\n", config_file); +@@ -4384,6 +4389,7 @@ + + int main(int argc, char **argv) + { ++ char *tmp; + int ifresolve_warned = 0; + int i; + int retval = 1; +@@ -4395,9 +4401,10 @@ + mcheck(NULL); + #endif + +- dprintf((stderr, "staring...\n")); ++ dprintf((stderr, "starting...\n")); + +- program_name = argv[0]; ++ tmp = strrchr(argv[0], '/'); ++ program_name = tmp ? tmp + 1 : argv[0]; + options = 0; + *user = '\0'; + timeout.tv_sec = DEFAULT_TIMEOUT; +@@ -4417,7 +4424,7 @@ + + if(!(options & OPT_QUIET) && !(options & OPT_DAEMON)) + { +- fprintf(stderr, "ez-ipupdate Version %s\nCopyright (C) 1998-2001 Angus Mackay.\n", VERSION); ++ fprintf(stderr, "%s Version %s\nCopyright (C) 1998-2001 Angus Mackay\n", program_name, VERSION); + } + + dprintf((stderr, "options: 0x%04X\n", options)); +@@ -4434,7 +4441,7 @@ + { + if(service->check_info() != 0) + { +- fprintf(stderr, "invalid data to perform requested action.\n"); ++ fprintf(stderr, "invalid data to perform requested action\n"); + exit(1); + } + } +@@ -4456,13 +4463,13 @@ + dprintf((stderr, "user_name: %s\n", user_name)); + dprintf((stderr, "password: %s\n", password)); + } +- if(*user_name == '\0') ++ if(*user_name == '\0' && !(options & OPT_DAEMON)) + { + printf("user name: "); + fgets(user_name, sizeof(user_name), stdin); + chomp(user_name); + } +- if(*password == '\0') ++ if(*password == '\0' && !(options & OPT_DAEMON)) + { + strncpy(password, getpass("password: "), sizeof(password)); + } +@@ -4480,7 +4487,7 @@ + + if(service->check_info() != 0) + { +- fprintf(stderr, "invalid data to perform requested action.\n"); ++ fprintf(stderr, "invalid data to perform requested action\n"); + exit(1); + } + +@@ -4503,7 +4510,7 @@ + + if(interface == NULL) + { +- fprintf(stderr, "invalid data to perform requested action.\n"); ++ fprintf(stderr, "invalid data to perform requested action\n"); + fprintf(stderr, "you must provide an interface for daemon mode"); + exit(1); + } +@@ -4519,23 +4526,25 @@ + if(fork() > 0) { exit(0); } /* parent */ + } + ++# if HAVE_SYSLOG_H ++ openlog(program_name, LOG_PID, LOG_DAEMON ); ++ //options |= OPT_QUIET; ++# endif ++ show_message("version %s, interface %s, host %s, server %s, service %s\n", ++ VERSION, N_STR(interface), N_STR(host), server, service->title); ++ + #if HAVE_GETPID + if(pid_file && pid_file_create(pid_file) != 0) + { +- fprintf(stderr, "exiting...\n"); ++ show_message("could not create pid file %s (%s), exiting\n", ++ pid_file, strerror(errno)); ++#if HAVE_SYSLOG_H ++ closelog(); ++#endif + exit(1); + } + #endif + +-# if HAVE_SYSLOG_H +- openlog(program_name, LOG_PID, LOG_USER ); +- options |= OPT_QUIET; +-# endif +- show_message("ez-ipupdate Version %s, Copyright (C) 1998-2001 Angus Mackay.\n", +- VERSION); +- show_message("%s started for interface %s host %s using server %s and service %s\n", +- program_name, N_STR(interface), N_STR(host), server, service->title); +- + memset(&sin, 0, sizeof(sin)); + + if(cache_file) +@@ -4560,7 +4569,7 @@ + strftime(timebuf, sizeof(timebuf), "%Y/%m/%d %H:%M", ts); + show_message("got last update %s on %s from cache file\n", ipstr, timebuf); + } +- else ++ else if(ipstr||ipdate) + { + show_message("malformed cache file: %s\n", cache_file); + } +@@ -4647,7 +4656,7 @@ + } + else + { +- show_message("failure to update %s->%s (%s)\n", ++ show_message("failed to update %s->%s (%s)\n", + interface, inet_ntoa(sin.sin_addr), N_STR(host)); + memset(&sin, 0, sizeof(sin)); + +@@ -4671,7 +4680,7 @@ + dprintf((stderr, "updateres: %d\n", updateres)); + if(updateres == UPDATERES_SHUTDOWN) + { +- show_message("shuting down updater for %s due to fatal error\n", ++ show_message("shutting down updater for %s due to fatal error\n", + N_STR(host)); + + if(notify_email && *notify_email != '\0') +@@ -4711,7 +4720,7 @@ + #endif + + #else +- fprintf(stderr, "sorry, this mode is only available on platforms that the "); ++ fprintf(stderr, "sorry, this mode is only available on platforms where the "); + fprintf(stderr, "IP address \ncan be determined. feel free to hack the code"); + fprintf(stderr, " though.\n"); + exit(1); +@@ -4799,7 +4808,7 @@ + } + else + { +- show_message("could not resolve ip address for %s.\n", interface); ++ show_message("could not resolve ip address for %s\n", interface); + exit(1); + } + close(sock); +@@ -4840,7 +4849,7 @@ + { + char ipbuf[64]; + +- if(address == NULL || *address == '\0') ++ if((address == NULL || *address == '\0') && interface != NULL) + { + #ifdef IF_LOOKUP + struct sockaddr_in sin; +--- ez-ipupdate-3.0.11b8.orig/example.conf ++++ ez-ipupdate-3.0.11b8/example.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +--- ez-ipupdate-3.0.11b8.orig/example-pgpow.conf ++++ ez-ipupdate-3.0.11b8/example-pgpow.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -10,8 +10,8 @@ + host=mydomain.penguinpowered.com + interface=eth1 + +-# if you use run-as ensure the user has permission to write this file +-cache-file=/tmp/ez-ipupdate.cache ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/example-dhs.conf ++++ ez-ipupdate-3.0.11b8/example-dhs.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -10,8 +10,8 @@ + host=mydomain.whatever.com + interface=eth1 + +-# if you use run-as ensure the user has permission to write this file +-cache-file=/tmp/ez-ipupdate.cache ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/example-dyndns.conf ++++ ez-ipupdate-3.0.11b8/example-dyndns.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -12,14 +12,9 @@ + interface=eth1 + max-interval=2073600 + +-# please create this file and ensure that the user that ez-ipupdate is running +-# as has write permissions to it then uncomment this line, if you don't your +-# dyndns account will probably get banned. if you run ez-ipupdate as root (bad +-# idea, use "run-as-user") then you can just uncomment this line. +-#cache-file=/etc/ez-ipupdate.cache.eth1 +- +-# for the mean time we'll just use a cache file in the temp directory +-cache-file=/tmp/ez-ipupdate.cache ++# if you don't use a cache file your dyndns account will probably get banned. ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/example-ods.conf ++++ ez-ipupdate-3.0.11b8/example-ods.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -10,8 +10,8 @@ + host=mydomain.ods.org + interface=eth1 + +-# if you use run-as ensure the user has permission to write this file +-cache-file=/tmp/ez-ipupdate.cache ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/example-tzo.conf ++++ ez-ipupdate-3.0.11b8/example-tzo.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -14,8 +14,8 @@ + max-interval=2073600 + interface=eth1 + +-# if you use run-as ensure the user has permission to write this file +-cache-file=/tmp/ez-ipupdate.cache ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/example-gnudip.conf ++++ ez-ipupdate-3.0.11b8/example-gnudip.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -14,8 +14,8 @@ + # any other value is ignored + #address=0.0.0.0 + +-# if you use run-as ensure the user has permission to write this file +-cache-file=/tmp/ez-ipupdate.cache ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/example-easydns.conf ++++ ez-ipupdate-3.0.11b8/example-easydns.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -10,8 +10,8 @@ + host=mydomain.whatever.com + interface=eth1 + +-# if you use run-as ensure the user has permission to write this file +-cache-file=/tmp/ez-ipupdate.cache ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/example-justlinux.conf ++++ ez-ipupdate-3.0.11b8/example-justlinux.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -10,8 +10,8 @@ + host=mydomain.penguinpowered.com + interface=eth1 + +-# if you use run-as ensure the user has permission to write this file +-cache-file=/tmp/ez-ipupdate.cache ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/example-dyns.conf ++++ ez-ipupdate-3.0.11b8/example-dyns.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -10,8 +10,8 @@ + host=myhost + #interface=eth1 + +-# if you use run-as ensure the user has permission to write this file +-#cache-file=/tmp/ez-ipupdate.cache ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/CHANGELOG ++++ ez-ipupdate-3.0.11b8/CHANGELOG +@@ -1,3 +1,86 @@ ++Changelog for ez-ipupdate: ++ ++version 3.0.11b7 is a bug fix for the new ODS server update (it was ++ez-ipupdate's bug). ++ ++version 3.0.11b6 has a small fix for dyns.cx changing their protocol by ++accident (lower case Host now). ++ ++version 3.0.7 -> 3.0.11x I can't remember, check the changelog. ++ ++version 3.0.7 gives us a default max-interval for dyndns and allows specifying ++intervals in days/weeks/months as well as support for another service ++zoneedit. ++ ++version 3.0.3 brings a fix for hn.org that was causing it to ignore the ++supplied IP address and always use the one that you were connecting from. ++ ++version 3.0.1 brings supoprt for hn.org and the option of using a pid file. ++ ++version 3.0.0 brings new symantics, now you MUST specify an interface and ++service-type for daemon mode. it also brings many fixes, it seems that there ++have been some serious bugs introduced some time after version 2.9.1 and this ++should fix those and bring some new features like self throttling. All users ++are strongly encoraged to upgrade to version 3.x.x. ++ ++version 2.9.3 brings long awaited support for a cache file. this was needed in ++a big way for use with the dyndns.org service. ++ ++version 2.9.2 brings support for justlinux.com's new version 2.0 service, now ++"justlinux" is for the justlinux v2.0 service and "pgpow" is for the justlinux ++v1.0 service. now that penguinpowered has switched to their v2.0 update method ++I don't know which one I like the best, probably dyndns.org. ++ ++version 2.9.0 adds support for EasyDNS. Their service is nice, very good web . ++site design, it is commercial though thanks to Mark Jeftovic for the code to . ++support EasyDNS . ++ ++version 2.8.0 adds support for GNUDip and TZO as well as a new feature to run. ++a command after every successful update. There are probably some bug fixes in. ++there too thanks to Jeremy Bopp for the code to support GNUDip and TZO . ++ ++version 2.6.0 adds support for ODS and a couple minor fixups. ++ ++version 2.4.2 adds support for dyndns and some other cleanups. the service ++that dyndns offers looks good, I still think I like justlinux better though. ++ ++version 2.2.2 gives us support for updating the MX record for dhs.org. I ++have to say that the implementation of dhs.org's service is laughable. I ++strongly advise people not to use it, it is just that bad. If you are updating ++a dhs.org acount with an MX record then there is 60 second sleep() call (or ++the length of the timeout, whichever is shorter) to get around problems with ++dhs' service. ++ ++version 2.2.1 brings support for our friends at dhs.org and fixes a socket ++leak in the dhs code and the penguinpowered code. I have to say though that I ++am not impressed with the dhs.org service, penguinpowered.com gets my vote for ++best implementation. (although they wont even acknowledge my client or put a ++link to it on thier site) ++ ++If you are getting errors connecting to the server for a justlinux.com service ++please ensure that you either specify "-S pgpow" or "--service penguinpowered" ++on either the command line or in the config file(in the config file the syntax ++is "service=penguinpowered"). The default for this tool is to think it is ++connecting to an ez-ip.net service. ++ ++Version 2.0.0 brings support for other services than just ez-ip.net and ++contains some bug fixes. ++ ++Version 1.0.1 brings some new features such the useage of config files, ++timeouts on I/O, set user id and many more. ++ ++Version 0.9.0 fixes a problem with a leaky file descriptor and some other ++litte things wrong. It also moves the version number up quite a bit as I have ++been running it in daemon mode for over 60 days without any problems. ++ ++Version 0.0.3 fixes a bug in the user/password code and a bunch of issues with ++the packaging (I copied another project to start this one and forgot to update ++some stuff). I Also added the system type to the User-Agent string. ++ ++Version 0.0.2 adds some nice features for those of use who use Linux. It ++now can run in daemon mode periodicly check the IP address of the specified ++interface and only update it if it has changed. It also adds the feature to ++turn your password in to '***' for the proccess listing. + + RCS file: /home/amackay/src/cvsroot/ez-ipupdate/ez-ipupdate.c,v + Working file: ez-ipupdate.c +--- ez-ipupdate-3.0.11b8.orig/example-heipv6tb.conf ++++ ez-ipupdate-3.0.11b8/example-heipv6tb.conf +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/ez-ipupdate -c ++#!/usr/sbin/ez-ipupdate -c + # + # example config file for ez-ipupdate + # +@@ -11,14 +11,9 @@ + interface=eth1 + max-interval=2073600 + +-# please create this file and ensure that the user that ez-ipupdate is running +-# as has write permissions to it then uncomment this line, if you don't your +-# dyndns account will probably get banned. if you run ez-ipupdate as root (bad +-# idea, use "run-as-user") then you can just uncomment this line. +-#cache-file=/etc/ez-ipupdate.cache.eth1 +- +-# for the mean time we'll just use a cache file in the temp directory +-cache-file=/tmp/ez-ipupdate.cache ++# if you don't use a cache file your account will probably get banned. ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache + + # uncomment this once you have everything working how you want and you are + # ready to have ez-ipupdate running in the background all the time. to stop it +--- ez-ipupdate-3.0.11b8.orig/debian/control ++++ ez-ipupdate-3.0.11b8/debian/control +@@ -0,0 +1,25 @@ ++Source: ez-ipupdate ++Section: net ++Priority: optional ++Maintainer: Sam Hocevar (Debian packages) <sam+deb@zoy.org> ++Build-Depends: debhelper (>= 4.1.68) ++Standards-Version: 3.6.2.1 ++ ++Package: ez-ipupdate ++Section: net ++Architecture: any ++Depends: ${shlibs:Depends}, ${misc:Depends}, adduser, debconf (>= 1.2.0) ++Provides: dyndns-client ++Description: client for most dynamic DNS services ++ ez-ipupdate is a quite complete client for the dynamic DNS service offered ++ by http://www.ez-ip.net/ and many more. ++ . ++ Currently supported are: ez-ip (http://www.EZ-IP.Net/), Penguinpowered ++ (http://www.penguinpowered.com/), DHS (http://members.dhs.org/), ++ dynDNS (http://members.dyndns.org/), ODS (http://www.ods.org/), ++ TZO (http://www.tzo.com/), EasyDNS (http://members.easydns.com/), ++ Justlinux (http://www.justlinux.com), Dyns (http://www.dyns.cx), ++ HN (http://dup.hn.org/), ZoneEdit (http://www.zoneedit.com/) and ++ Hurricane Electric's IPv6 Tunnel Broker (http://ipv6tb.he.net/). ++ . ++ All services using GNUDip are also supported. +--- ez-ipupdate-3.0.11b8.orig/debian/po/POTFILES.in ++++ ez-ipupdate-3.0.11b8/debian/po/POTFILES.in +@@ -0,0 +1 @@ ++[type: gettext/rfc822deb] templates +--- ez-ipupdate-3.0.11b8.orig/debian/po/templates.pot ++++ ez-ipupdate-3.0.11b8/debian/po/templates.pot +@@ -0,0 +1,252 @@ ++# SOME DESCRIPTIVE TITLE. ++# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER ++# This file is distributed under the same license as the PACKAGE package. ++# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. ++# ++#, fuzzy ++msgid "" ++msgstr "" ++"Project-Id-Version: PACKAGE VERSION\n" ++"Report-Msgid-Bugs-To: sam+deb@zoy.org\n" ++"POT-Creation-Date: 2005-11-14 20:17+0100\n" ++"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" ++"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" ++"Language-Team: LANGUAGE <LL@li.org>\n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=CHARSET\n" ++"Content-Transfer-Encoding: 8bit\n" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "configure manually" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "zoneedit" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ez-ip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "pgpow" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dhs" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-static" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-custom" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ods" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "tzo" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns-partner" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "gnudip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "justlinux" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "hn" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "heipv6tb" ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "Dynamic DNS provider to use:" ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "" ++"There are many Dynamic DNS providers supported by ez-ipupdate. If you want " ++"your default configuration to be created automatically, you must select the " ++"provider that you wish to use here. You must configure an account on your " ++"chosen provider's service yourself." ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "" ++"If you prefer your default ez-ipupdate configuration not to be managed for " ++"you, you may choose "configure manually"." ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "" ++"Whatever your decision, you can later put as many additional configuration " ++"files in /etc/ez-ipupdate/ as you need." ++msgstr "" ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "Does this system use dialup PPP to connect to the internet?" ++msgstr "" ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "" ++"If you use dialup PPP to connect to the internet, then ez-ipupdate can be " ++"run to notify providers of your new address when ppp connects to the " ++"network. Otherwise it will run in the background, and scan for changes to " ++"your address while you are online." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "Address for your Dynamic DNS server:" ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "" ++"The service type you selected requires a server address to connect to. You " ++"may specify either a full hostname or an IP address." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:33 ++msgid "Username for your Dynamic DNS account:" ++msgstr "" ++ ++#. Type: password ++#. Description ++#: ../templates:37 ++msgid "Password for your Dynamic DNS account:" ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "Network interface to monitor:" ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "" ++"ez-ipupdate will monitor the chosen network interface for changes of IP " ++"address. It is not possible to automatically detect which interface should " ++"be monitored, so you must name the interface here." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:49 ++msgid "Dynamic DNS hostname to keep updated:" ++msgstr "" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++msgid "Enable DNS wildcards for your Dynamic DNS hostname?" ++msgstr "" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++msgid "" ++"Many Dynamic DNS providers are capable of supporting "wildcard" DNS " ++"lookups. This means that for yourdomain, a lookup for anything.yourdomain " ++"will return an answer that points to yourdomain." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "MX record to add:" ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"Many Dynamic DNS providers are capable of supporting MX records. If you want " ++"an MX record enabled for your domain, specify the content of that MX record " ++"here. If you do not want an MX record, leave it blank." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"For further information on MX records, what they do, and how they are used, " ++"see your Dynamic DNS provider." ++msgstr "" +--- ez-ipupdate-3.0.11b8.orig/debian/po/cs.po ++++ ez-ipupdate-3.0.11b8/debian/po/cs.po +@@ -0,0 +1,315 @@ ++# ++# Translators, if you are not familiar with the PO format, gettext ++# documentation is worth reading, especially sections dedicated to ++# this format, e.g. by running: ++# info -n '(gettext)PO Files' ++# info -n '(gettext)Header Entry' ++# ++# Some information specific to po-debconf are available at ++# /usr/share/doc/po-debconf/README-trans ++# or http://www.debian.org/intl/l10n/po-debconf/README-trans ++# ++# Developers do not need to manually edit POT or PO files. ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: ez-ipupdate\n" ++"Report-Msgid-Bugs-To: sam+deb@zoy.org\n" ++"POT-Creation-Date: 2005-11-14 20:17+0100\n" ++"PO-Revision-Date: 2005-03-17 08:23+0100\n" ++"Last-Translator: Miroslav Kure <kurem@debian.cz>\n" ++"Language-Team: Czech <debian-l10n-czech@debian.org>\n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=ISO-8859-2\n" ++"Content-Transfer-Encoding: 8bit\n" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "configure manually" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "zoneedit" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ez-ip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "pgpow" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dhs" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-static" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-custom" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ods" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "tzo" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns-partner" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "gnudip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "justlinux" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "hn" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "heipv6tb" ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "Dynamic DNS provider to use:" ++msgstr "Poskytovatel dynamického DNS:" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"There are many Dynamic DNS providers supported by ez-ipupdate. If you want " ++"your default configuration to be created automatically, you must select the " ++"provider that you wish to use here. You must configure an account on your " ++"chosen provider's service yourself." ++msgstr "" ++"ez-ipupdate podporuje mnoho poskytovatelù dynamického DNS. Vyberte zde, " ++"kterého poskytovatele pouŸíváte. Konkrétní úèet u daného poskytovatele si " ++"v¹ak musíte nastavit sami." ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "" ++"If you prefer your default ez-ipupdate configuration not to be managed for " ++"you, you may choose "configure manually"." ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"Whatever your decision, you can later put as many additional configuration " ++"files in /etc/ez-ipupdate/ as you need." ++msgstr "" ++"Poznamenejme, Ÿe do adresáøe /etc/ez-ipupdate/ mùŸete pøidat libovolný poèet " ++"dal¹ích konfigurací. Tyto dodateèné konfigurace nebude ez-ipupdate nijak " ++"mìnit." ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "Does this system use dialup PPP to connect to the internet?" ++msgstr "" ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "" ++"If you use dialup PPP to connect to the internet, then ez-ipupdate can be " ++"run to notify providers of your new address when ppp connects to the " ++"network. Otherwise it will run in the background, and scan for changes to " ++"your address while you are online." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "Address for your Dynamic DNS server:" ++msgstr "Adresa serveru dynamického DNS:" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "" ++"The service type you selected requires a server address to connect to. You " ++"may specify either a full hostname or an IP address." ++msgstr "" ++"SluŸba, kterou jste vybrali, vyŸaduje adresu serveru, ke kterému se má " ++"pøipojit. MùŸete zadat buï celé jméno serveru nebo jeho IP adresu." ++ ++#. Type: string ++#. Description ++#: ../templates:33 ++msgid "Username for your Dynamic DNS account:" ++msgstr "UŸivatelské jméno pro úèet dynamického DNS:" ++ ++#. Type: password ++#. Description ++#: ../templates:37 ++msgid "Password for your Dynamic DNS account:" ++msgstr "Heslo pro úèet dynamického DNS:" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "Network interface to monitor:" ++msgstr "Sledovat sí»ové rozhraní:" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "" ++"ez-ipupdate will monitor the chosen network interface for changes of IP " ++"address. It is not possible to automatically detect which interface should " ++"be monitored, so you must name the interface here." ++msgstr "" ++"ez-ipupdate bude na daném sí»ovém rozhraní sledovat zmìny IP adresy. Program " ++"neumí odhadnout, které rozhraní má sledovat a proto zde musíte uvést pøesný " ++"název rozhraní." ++ ++#. Type: string ++#. Description ++#: ../templates:49 ++msgid "Dynamic DNS hostname to keep updated:" ++msgstr "Dynamické DNS jméno poèítaèe, jeŸ se má udrŸovat aktuální:" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++msgid "Enable DNS wildcards for your Dynamic DNS hostname?" ++msgstr "Povolit zástupné znaky DNS pro dynamické DNS jméno poèítaèe?" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++#, fuzzy ++msgid "" ++"Many Dynamic DNS providers are capable of supporting "wildcard" DNS " ++"lookups. This means that for yourdomain, a lookup for anything.yourdomain " ++"will return an answer that points to yourdomain." ++msgstr "" ++"Mnoho poskytovatelù dynamického DNS podporuje DNS dotazy se zástupnými " ++"znaky. To znamená, Ÿe pro vasedomena vrátí dotaz na cokoliv.vasedomena " ++"odpovìï ukazující na vasedomena. Chcete-li tuto moŸnost povolit, odpovìzte " ++"zde kladnì." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "MX record to add:" ++msgstr "MX záznam:" ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"Many Dynamic DNS providers are capable of supporting MX records. If you want " ++"an MX record enabled for your domain, specify the content of that MX record " ++"here. If you do not want an MX record, leave it blank." ++msgstr "" ++"Mnoho poskytovatelù dynamického DNS podporuje MX záznamy. Chcete-li pro svou " ++"doménu povolit MX záznam, zadejte zde jeho obsah. V opaèném pøípadì ponechte " ++"pole prázdné." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"For further information on MX records, what they do, and how they are used, " ++"see your Dynamic DNS provider." ++msgstr "" ++"Dal¹í informace o MX záznamech (co dìlají, jak se pouŸívají) naleznete u " ++"svého poskytovatele dynamického DNS." ++ ++#~ msgid "Manage your default configuration with debconf?" ++#~ msgstr "Spravovat nastavení pomocí debconfu?" ++ ++#~ msgid "" ++#~ "ez-ipupdate can manage your default configuration automatically using " ++#~ "debconf. If you do not want your default configuration managed " ++#~ "automatically, decline this option." ++#~ msgstr "" ++#~ "Buï mùŸete spravovat výchozí konfiguraci ez-ipupdate automaticky pomocí " ++#~ "debconfu, nebo ruènì úpravou konfiguraèního souboru." ++ ++#~ msgid "Run as a daemon?" ++#~ msgstr "Spou¹tìt jako daemon?" ++ ++#~ msgid "" ++#~ "By default ez-ipupdate will run as a daemon to manage the configuration. " ++#~ "Refuse here if you do not want this. Instead, ez-ipupdate will install a " ++#~ "script in /etc/ppp/ip-up.d that will run all non-daemon configurations " ++#~ "when the ppp interface is brought up. See the /usr/share/doc/ez-ipupdate/" ++#~ "README.Debian file for more information." ++#~ msgstr "" ++#~ "Implicitnì se ez-ipupdate spou¹tí jako daemon. Pokud tomu tak nechcete, " ++#~ "zamítnìte zde a ez-ipupdate místo toho nainstaluje do adresáøe /etc/ppp/" ++#~ "ip-up.d skript, který se bude spou¹tìt pøi kaŸdém nahození ppp rozhraní. " ++#~ "Podrobnosti naleznete v /usr/share/doc/ez-ipupdate/README.Debian." ++ ++#~ msgid "" ++#~ "If none of these automated behaviors suit you, you should probably not " ++#~ "manage your default configuration using debconf." ++#~ msgstr "" ++#~ "Pokud vám Ÿádné z automatických chování nevyhovuje, pravdìpodobnì " ++#~ "nechcete, aby se výchozí konfigurace spravovala pomocí debconfu." +--- ez-ipupdate-3.0.11b8.orig/debian/po/fr.po ++++ ez-ipupdate-3.0.11b8/debian/po/fr.po +@@ -0,0 +1,318 @@ ++# translation of fr.po to French ++# ++# Translators, if you are not familiar with the PO format, gettext ++# documentation is worth reading, especially sections dedicated to ++# this format, e.g. by running: ++# info -n '(gettext)PO Files' ++# info -n '(gettext)Header Entry' ++# Some information specific to po-debconf are available at ++# /usr/share/doc/po-debconf/README-trans ++# or http://www.debian.org/intl/l10n/po-debconf/README-trans# ++# Developers do not need to manually edit POT or PO files. ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: ez-ipupdate\n" ++"Report-Msgid-Bugs-To: sam+deb@zoy.org\n" ++"POT-Creation-Date: 2005-11-14 20:17+0100\n" ++"PO-Revision-Date: 2005-03-17 08:39+0100\n" ++"Last-Translator: Christian perrier <bubulle@debian.org>\n" ++"Language-Team: French <debian-l10n-french@lists.debian.org>\n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=ISO-8859-15\n" ++"Content-Transfer-Encoding: 8bit\n" ++"X-Generator: KBabel 1.9.1\n" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "configure manually" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "zoneedit" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ez-ip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "pgpow" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dhs" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-static" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-custom" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ods" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "tzo" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns-partner" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "gnudip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "justlinux" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "hn" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "heipv6tb" ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "Dynamic DNS provider to use:" ++msgstr "Fournisseur de service de nom dynamique à utiliser :" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"There are many Dynamic DNS providers supported by ez-ipupdate. If you want " ++"your default configuration to be created automatically, you must select the " ++"provider that you wish to use here. You must configure an account on your " ++"chosen provider's service yourself." ++msgstr "" ++"De nombreux fournisseurs de service de nom dynamique sont gérés par ez-" ++"ipupdate. Veuillez choisir le vôtre. La configuration de votre compte chez " ++"ce fournisseur doit être effectuée à part." ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "" ++"If you prefer your default ez-ipupdate configuration not to be managed for " ++"you, you may choose "configure manually"." ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"Whatever your decision, you can later put as many additional configuration " ++"files in /etc/ez-ipupdate/ as you need." ++msgstr "" ++"Veuillez noter que si vous ajoutez des configurations supplémentaires dans /" ++"etc/ez-ipupdate/, elles ne seront ultérieurement pas modifiées." ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "Does this system use dialup PPP to connect to the internet?" ++msgstr "" ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "" ++"If you use dialup PPP to connect to the internet, then ez-ipupdate can be " ++"run to notify providers of your new address when ppp connects to the " ++"network. Otherwise it will run in the background, and scan for changes to " ++"your address while you are online." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "Address for your Dynamic DNS server:" ++msgstr "Adresse de votre serveur de nom dynamique :" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "" ++"The service type you selected requires a server address to connect to. You " ++"may specify either a full hostname or an IP address." ++msgstr "" ++"Le type de service que vous avez choisi a besoin de l'adresse d'un serveur. " ++"Vous pouvez indiquer un nom d'hôte complètement qualifié ou une adresse IP." ++ ++#. Type: string ++#. Description ++#: ../templates:33 ++msgid "Username for your Dynamic DNS account:" ++msgstr "Identifiant de votre compte de service de nom dynamique :" ++ ++#. Type: password ++#. Description ++#: ../templates:37 ++msgid "Password for your Dynamic DNS account:" ++msgstr "Mot de passe de votre compte de service de nom dynamique :" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "Network interface to monitor:" ++msgstr "Interface réseau à surveiller :" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "" ++"ez-ipupdate will monitor the chosen network interface for changes of IP " ++"address. It is not possible to automatically detect which interface should " ++"be monitored, so you must name the interface here." ++msgstr "" ++"Ez-ipupdate surveille les changements d'adresse IP sur une interface réseau. " ++"Cette interface ne peut pas être détectée automatiquement et vous devez donc " ++"l'indiquer ici." ++ ++#. Type: string ++#. Description ++#: ../templates:49 ++msgid "Dynamic DNS hostname to keep updated:" ++msgstr "Nom d'hôte dynamique à tenir à jour :" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++msgid "Enable DNS wildcards for your Dynamic DNS hostname?" ++msgstr "" ++"Faut-il activer les requêtes DNS génériques pour votre nom d'hôte dynamique ?" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++#, fuzzy ++msgid "" ++"Many Dynamic DNS providers are capable of supporting "wildcard" DNS " ++"lookups. This means that for yourdomain, a lookup for anything.yourdomain " ++"will return an answer that points to yourdomain." ++msgstr "" ++"De nombreux fournisseurs de services de nom dynamique gèrent les requêtes " ++"DNS génériques (« wildcard DNS »). Cela signifie qu'une requête pour " ++"« adresse.votre.domaine » sera résolue vers « votre.domaine »." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "MX record to add:" ++msgstr "Enregistrement MX à ajouter :" ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"Many Dynamic DNS providers are capable of supporting MX records. If you want " ++"an MX record enabled for your domain, specify the content of that MX record " ++"here. If you do not want an MX record, leave it blank." ++msgstr "" ++"De nombreux fournisseurs de services de nom dynamique gèrent les " ++"enregistrements MX. Si vous souhaitez en activer un pour votre domaine, " ++"veuillez en indiquer le contenu ici. Si vous laissez ce champ vide, aucun " ++"enregistrement MX ne sera ajouté." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"For further information on MX records, what they do, and how they are used, " ++"see your Dynamic DNS provider." ++msgstr "" ++"Pour plus d'informations sur les enregistrements MX et leur utilisation, " ++"veuillez consulter votre fournisseur de service de nom dynamique." ++ ++#~ msgid "Manage your default configuration with debconf?" ++#~ msgstr "Voulez-vous gérer la configuration par défaut avec debconf ?" ++ ++#~ msgid "" ++#~ "ez-ipupdate can manage your default configuration automatically using " ++#~ "debconf. If you do not want your default configuration managed " ++#~ "automatically, decline this option." ++#~ msgstr "" ++#~ "Ez-ipupdate peut gérer votre configuration par défaut automatiquement " ++#~ "avec l'outil de configuration debconf. Vous pouvez choisir de ne pas " ++#~ "utiliser cette option." ++ ++#~ msgid "Run as a daemon?" ++#~ msgstr "Faut-il utiliser ez-ipudate comme un démon ?" ++ ++#~ msgid "" ++#~ "By default ez-ipupdate will run as a daemon to manage the configuration. " ++#~ "Refuse here if you do not want this. Instead, ez-ipupdate will install a " ++#~ "script in /etc/ppp/ip-up.d that will run all non-daemon configurations " ++#~ "when the ppp interface is brought up. See the /usr/share/doc/ez-ipupdate/" ++#~ "README.Debian file for more information." ++#~ msgstr "" ++#~ "Par défaut, ez-ipupdate fonctionne comme un démon pour gérer la " ++#~ "configuration. Vous pouvez choisir de ne pas utiliser cette option. Dans " ++#~ "ce cas, ez-ipupdate installera un script dans /etc/ppp/ip-up.d qui " ++#~ "exécutera toutes les configurations qui ne sont pas gérées par un démon, " ++#~ "lorsque l'interface PPP sera activée. Veuillez consulter le fichier /usr/" ++#~ "share/doc/ez-ipupdate/README.Debian pour plus d'informations." ++ ++#~ msgid "" ++#~ "If none of these automated behaviors suit you, you should probably not " ++#~ "manage your default configuration using debconf." ++#~ msgstr "" ++#~ "Si aucun de ces fonctionnements automatisés ne vous convient, vous " ++#~ "devriez éviter de gérer la configuration par défaut avec debconf." +--- ez-ipupdate-3.0.11b8.orig/debian/po/de.po ++++ ez-ipupdate-3.0.11b8/debian/po/de.po +@@ -0,0 +1,324 @@ ++# translation of de-new.po to German ++# translation of de.po to German ++# ++# Translators, if you are not familiar with the PO format, gettext ++# documentation is worth reading, especially sections dedicated to ++# this format, e.g. by running: ++# info -n '(gettext)PO Files' ++# info -n '(gettext)Header Entry' ++# Some information specific to po-debconf are available at ++# /usr/share/doc/po-debconf/README-trans ++# or http://www.debian.org/intl/l10n/po-debconf/README-trans# ++# Developers do not need to manually edit POT or PO files. ++# Jens Nachtigall <nachtigall@web.de>, 2005. ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: de-new\n" ++"Report-Msgid-Bugs-To: sam+deb@zoy.org\n" ++"POT-Creation-Date: 2005-11-14 20:17+0100\n" ++"PO-Revision-Date: 2005-03-21 21:43+0100\n" ++"Last-Translator: Jens Nachtigall <nachtigall@web.de>\n" ++"Language-Team: German <debian-l10n-german@lists.debian.org>\n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=UTF-8\n" ++"Content-Transfer-Encoding: 8bit\n" ++"X-Generator: KBabel 1.9.1\n" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "configure manually" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "zoneedit" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ez-ip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "pgpow" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dhs" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-static" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-custom" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ods" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "tzo" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns-partner" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "gnudip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "justlinux" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "hn" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "heipv6tb" ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "Dynamic DNS provider to use:" ++msgstr "Zu benutzender Dynamischer DNS-Provider:" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"There are many Dynamic DNS providers supported by ez-ipupdate. If you want " ++"your default configuration to be created automatically, you must select the " ++"provider that you wish to use here. You must configure an account on your " ++"chosen provider's service yourself." ++msgstr "" ++"ez-ipupdate unterstÃŒtzt viele Dynamische DNS-Provider. WÀhlen Sie hier den " ++"Provider aus, den Sie benutzen möchten. Das Benutzerkonto mÃŒssen Sie beim " ++"Provider Ihrer Wahl selbst einrichten." ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "" ++"If you prefer your default ez-ipupdate configuration not to be managed for " ++"you, you may choose "configure manually"." ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"Whatever your decision, you can later put as many additional configuration " ++"files in /etc/ez-ipupdate/ as you need." ++msgstr "" ++"Beachten Sie, dass Sie unter /etc/ez-ipupdate/ so viele zusÀtzliche " ++"Konfigurationen haben können, wie Sie wollen. ez-ipupdate wird diese nicht " ++"verÀndern." ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "Does this system use dialup PPP to connect to the internet?" ++msgstr "" ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "" ++"If you use dialup PPP to connect to the internet, then ez-ipupdate can be " ++"run to notify providers of your new address when ppp connects to the " ++"network. Otherwise it will run in the background, and scan for changes to " ++"your address while you are online." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "Address for your Dynamic DNS server:" ++msgstr "Adresse fÃŒr Ihren Dynamischen DNS-Server:" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "" ++"The service type you selected requires a server address to connect to. You " ++"may specify either a full hostname or an IP address." ++msgstr "" ++"FÃŒr den ausgewÀhlten Service wird eine Server-Adresse benötigt, zu der eine " ++"Verbindung aufgebaut wird. Sie können entweder einen vollstÀndigen Host-" ++"Namen oder eine IP-Adresse angeben." ++ ++#. Type: string ++#. Description ++#: ../templates:33 ++msgid "Username for your Dynamic DNS account:" ++msgstr "Benutzername fÃŒr Ihr Dynamisches DNS-Konto:" ++ ++#. Type: password ++#. Description ++#: ../templates:37 ++msgid "Password for your Dynamic DNS account:" ++msgstr "Passwort fÃŒr Ihr Dynamisches DNS-Konto:" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "Network interface to monitor:" ++msgstr "Zu verwaltende Netzwerk-Schnittstelle:" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "" ++"ez-ipupdate will monitor the chosen network interface for changes of IP " ++"address. It is not possible to automatically detect which interface should " ++"be monitored, so you must name the interface here." ++msgstr "" ++"ez-ipupdate wird die ausgewÀhlte Netzwerk-Schnittstelle auf VerÀnderungen " ++"der IP-Adresse beobachten. Es ist nicht möglich automatisch festzustellen, " ++"welche Schnittstelle beobachtet werden soll. Deshalb mÃŒssen Sie hier den " ++"Namen der Schnittstelle selbst angeben." ++ ++#. Type: string ++#. Description ++#: ../templates:49 ++msgid "Dynamic DNS hostname to keep updated:" ++msgstr "Zu aktualisierender Dynamischer DNS-Hostname:" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++msgid "Enable DNS wildcards for your Dynamic DNS hostname?" ++msgstr "DNS-Wildcards fÃŒr Ihren Dynamischen DNS-Hostnamen aktivieren?" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++#, fuzzy ++msgid "" ++"Many Dynamic DNS providers are capable of supporting "wildcard" DNS " ++"lookups. This means that for yourdomain, a lookup for anything.yourdomain " ++"will return an answer that points to yourdomain." ++msgstr "" ++"Viele Dynamische DNS-Provider unterstÃŒtzen DNS-Lookups mit Platzhaltern " ++"(»wildcards«). Das bedeutet: Haben Sie eine Domain namens »ihredomain«, dann " ++"werden Anfragen nach »irgendetwas.ihredomain« mit einer Antwort erwidert, " ++"die auf »ihredomain« verweist. Soll diese FÀhigkeit aktiviert sein, dann " ++"stimmen Sie hier zu." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "MX record to add:" ++msgstr "HinzuzufÃŒgender MX-Record:" ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"Many Dynamic DNS providers are capable of supporting MX records. If you want " ++"an MX record enabled for your domain, specify the content of that MX record " ++"here. If you do not want an MX record, leave it blank." ++msgstr "" ++"Viele Dynamische DNS-Provider unterstÃŒtzen MX-Records. Wollen Sie fÃŒr Ihre " ++"Domain einen MX-Record hinzufÃŒgen, dann geben Sie hier bitte den Inhalt des " ++"MX-Records an. Wollen Sie keinen MX-Record, dann lassen Sie das Feld frei." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"For further information on MX records, what they do, and how they are used, " ++"see your Dynamic DNS provider." ++msgstr "" ++"Weitere Informationen ÃŒber MX-Records, wofÃŒr sie gut sind, und wie sie " ++"verwendet werden, erfahren Sie von Ihrem Dynamischen DNS-Provider." ++ ++#~ msgid "Manage your default configuration with debconf?" ++#~ msgstr "Standard-Konfiguration mit debconf verwalten?" ++ ++#~ msgid "" ++#~ "ez-ipupdate can manage your default configuration automatically using " ++#~ "debconf. If you do not want your default configuration managed " ++#~ "automatically, decline this option." ++#~ msgstr "" ++#~ "ez-ipupdate kann Ihre Standard-Konfiguration automatisch mittels debconf " ++#~ "verwalten. Wenn Sie nicht wollen, dass Ihre Standard-Konfiguration " ++#~ "automatisch verwaltet wird, dann lehnen Sie diese Option ab." ++ ++#~ msgid "Run as a daemon?" ++#~ msgstr "Als Daemon laufen?" ++ ++#~ msgid "" ++#~ "By default ez-ipupdate will run as a daemon to manage the configuration. " ++#~ "Refuse here if you do not want this. Instead, ez-ipupdate will install a " ++#~ "script in /etc/ppp/ip-up.d that will run all non-daemon configurations " ++#~ "when the ppp interface is brought up. See the /usr/share/doc/ez-ipupdate/" ++#~ "README.Debian file for more information." ++#~ msgstr "" ++#~ "StandardmÀÃig wird ez-ipupdate Ihre Konfiguration als Daemon verwalten. " ++#~ "Lehnen Sie hier ab, wenn Sie das nicht wÃŒnschen. Stattdessen wÃŒrde ez-" ++#~ "ipupdate dann unter /etc/ppp/ip-up.d/ ein Skript installieren, welches " ++#~ "sÀmtliche Nicht-Daemon-Konfigurationen ausfÃŒhrt, sobald die PPP-" ++#~ "Schnittstelle hochgefahren wird. Lesen Sie die Datei /usr/share/doc/ez-" ++#~ "ipupdate/README.Debian fÃŒr weitere Informationen." ++ ++#~ msgid "" ++#~ "If none of these automated behaviors suit you, you should probably not " ++#~ "manage your default configuration using debconf." ++#~ msgstr "" ++#~ "Sollte Ihnen keine dieser Automatismen zusagen, dann ist es " ++#~ "wahrscheinlich besser, wenn Sie Ihre Standard-Konfiguration nicht mittels " ++#~ "debconf verwalten." +--- ez-ipupdate-3.0.11b8.orig/debian/po/pt_BR.po ++++ ez-ipupdate-3.0.11b8/debian/po/pt_BR.po +@@ -0,0 +1,319 @@ ++# Translators, if you are not familiar with the PO format, gettext ++# documentation is worth reading, especially sections dedicated to ++# this format, e.g. by running: ++# info -n '(gettext)PO Files' ++# info -n '(gettext)Header Entry' ++# Some information specific to po-debconf are available at ++# /usr/share/doc/po-debconf/README-trans ++# or http://www.debian.org/intl/l10n/po-debconf/README-trans ++# Developers do not need to manually edit POT or PO files. ++# ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: ez-ipupdate 3.0.11\n" ++"Report-Msgid-Bugs-To: sam+deb@zoy.org\n" ++"POT-Creation-Date: 2005-11-14 20:17+0100\n" ++"PO-Revision-Date: 2005-03-21 23:11-0300\n" ++"Last-Translator: Felipe Augusto van de Wiel (faw) <felipe@cathedrallabs>\n" ++"Language-Team: Portuguese/Brazil <debian-l10n-portuguese@lists.debian.org>\n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=UTF-8\n" ++"Content-Transfer-Encoding: 8bit\n" ++"pt_BR\n" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "configure manually" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "zoneedit" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ez-ip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "pgpow" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dhs" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-static" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-custom" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ods" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "tzo" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns-partner" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "gnudip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "justlinux" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "hn" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "heipv6tb" ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "Dynamic DNS provider to use:" ++msgstr "Provedor de DNS Dinâmico a ser usado:" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"There are many Dynamic DNS providers supported by ez-ipupdate. If you want " ++"your default configuration to be created automatically, you must select the " ++"provider that you wish to use here. You must configure an account on your " ++"chosen provider's service yourself." ++msgstr "" ++"Há vários provedores de DNS Dinâmico suportados pelo ez-ipupdate. Você deve " ++"selecionar o provedor que você gostaria de usar aqui. Você mesmo deve " ++"configurar uma conta no serviço do provedor que você escolheu." ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "" ++"If you prefer your default ez-ipupdate configuration not to be managed for " ++"you, you may choose "configure manually"." ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"Whatever your decision, you can later put as many additional configuration " ++"files in /etc/ez-ipupdate/ as you need." ++msgstr "" ++"Note que você pode colocar quantas configurações adicionais no /etc/ez-" ++"ipupdate/ você quiser. ez-ipupdate não vai modificá-las." ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "Does this system use dialup PPP to connect to the internet?" ++msgstr "" ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "" ++"If you use dialup PPP to connect to the internet, then ez-ipupdate can be " ++"run to notify providers of your new address when ppp connects to the " ++"network. Otherwise it will run in the background, and scan for changes to " ++"your address while you are online." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "Address for your Dynamic DNS server:" ++msgstr "Endereço do seu servidor de DNS Dinâmico:" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "" ++"The service type you selected requires a server address to connect to. You " ++"may specify either a full hostname or an IP address." ++msgstr "" ++"O tipo do serviço que você selecionou requer um endereço de servidor para se " ++"conectar. Você pode especificar um nome de máquina ou um endereço IP." ++ ++#. Type: string ++#. Description ++#: ../templates:33 ++msgid "Username for your Dynamic DNS account:" ++msgstr "Nome do usuário para a sua conta de DNS Dinâmico:" ++ ++#. Type: password ++#. Description ++#: ../templates:37 ++msgid "Password for your Dynamic DNS account:" ++msgstr "Senha para a sua conta de DNS Dinâmico:" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "Network interface to monitor:" ++msgstr "Interface de rede para monitorar:" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "" ++"ez-ipupdate will monitor the chosen network interface for changes of IP " ++"address. It is not possible to automatically detect which interface should " ++"be monitored, so you must name the interface here." ++msgstr "" ++"ez-ipupdate irá monitorar mudanças do endereço IP na interface de rede " ++"escolhida. Não é possÃvel detectar automaticamente qual interface deve ser " ++"monitorada, portanto você deve nomear a interface aqui." ++ ++#. Type: string ++#. Description ++#: ../templates:49 ++msgid "Dynamic DNS hostname to keep updated:" ++msgstr "Nome de máquina do DNS Dinâmico para manter atualizado:" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++msgid "Enable DNS wildcards for your Dynamic DNS hostname?" ++msgstr "" ++"Habilitar máscaras ("wildcards") de DNS para o seu nome de máquina do DNS " ++"Dinâmico?" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++#, fuzzy ++msgid "" ++"Many Dynamic DNS providers are capable of supporting "wildcard" DNS " ++"lookups. This means that for yourdomain, a lookup for anything.yourdomain " ++"will return an answer that points to yourdomain." ++msgstr "" ++"Vários provedores de DNS Dinâmico são capazes de suportar consultas para " ++""máscaras" ("wildcards") de DNS. Isso significa que para o seu domÃnio, " ++"uma consulta para qualquercoisa.seudominio vai retornar uma resposta que " ++"aponta para o seu domÃnio. Se você deseja que esse recurso seja ativado, " ++"aceite aqui." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "MX record to add:" ++msgstr "Entrada MX a ser adicionada:" ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"Many Dynamic DNS providers are capable of supporting MX records. If you want " ++"an MX record enabled for your domain, specify the content of that MX record " ++"here. If you do not want an MX record, leave it blank." ++msgstr "" ++"Vários provedores de DNS Dinâmico são capazes de suportar entradas MX. Se " ++"você deseja que uma entrada MX seja habilitada para o seu domÃnio, " ++"especifique aqui o conteúdo da sua entrada MX. Se você não quer uma entrada " ++"MX, deixe em branco." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"For further information on MX records, what they do, and how they are used, " ++"see your Dynamic DNS provider." ++msgstr "" ++"Para maiores informações sobre entradas MX, o que elas fazem, e como são " ++"usadas, veja o seu provedor de DNS Dinâmico." ++ ++#~ msgid "Manage your default configuration with debconf?" ++#~ msgstr "Gerenciar suas configurações "default" com o debconf?" ++ ++#~ msgid "" ++#~ "ez-ipupdate can manage your default configuration automatically using " ++#~ "debconf. If you do not want your default configuration managed " ++#~ "automatically, decline this option." ++#~ msgstr "" ++#~ "ez-ipupdate pode gerenciar suas configurações "default" automaticamente " ++#~ "usando o deconf. Se você não quer que suas configurações "default" " ++#~ "sejam gerenciadas automaticamente, negue esta opção." ++ ++#~ msgid "Run as a daemon?" ++#~ msgstr "Executar como serviço?" ++ ++#~ msgid "" ++#~ "By default ez-ipupdate will run as a daemon to manage the configuration. " ++#~ "Refuse here if you do not want this. Instead, ez-ipupdate will install a " ++#~ "script in /etc/ppp/ip-up.d that will run all non-daemon configurations " ++#~ "when the ppp interface is brought up. See the /usr/share/doc/ez-ipupdate/" ++#~ "README.Debian file for more information." ++#~ msgstr "" ++#~ "Por "default" ez-ipupdate é executado como serviço para gerenciar a " ++#~ "configuração. Recuse aqui se você não quiser isso. Ao invés disso, ez-" ++#~ "ipupdate instalará um script em /etc/ppp/ip-up.d que executará todas as " ++#~ "configurações quando a interface ppp for ativada. Veja o arquivo /usr/" ++#~ "share/doc/ez-ipupdate/README.Debian para mais informações." ++ ++#~ msgid "" ++#~ "If none of these automated behaviors suit you, you should probably not " ++#~ "manage your default configuration using debconf." ++#~ msgstr "" ++#~ "Se nenhum dos comportamentos automáticos atender você, você não deveria " ++#~ "gerenciar suas configurações "default" usando o debconf." +--- ez-ipupdate-3.0.11b8.orig/debian/po/vi.po ++++ ez-ipupdate-3.0.11b8/debian/po/vi.po +@@ -0,0 +1,308 @@ ++# Vietnamese Translation for ez-ipupdate. ++# Copyright © 2005 Free Software Foundation, Inc. ++# Clytie Siddall <clytie@riverland.net.au>, 2005. ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: ez-ipupdate 3.0.11b8-8.1\n" ++"Report-Msgid-Bugs-To: sam+deb@zoy.org\n" ++"POT-Creation-Date: 2005-11-14 20:17+0100\n" ++"PO-Revision-Date: 2005-06-02 21:37+0930\n" ++"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n" ++"Language-Team: Vietnamese <gnomevi-list@lists.sourceforge.net>\n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=utf-8\n" ++"Content-Transfer-Encoding: 8bit\n" ++"Plural-Forms: nplurals=1; plural=0\n" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "configure manually" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "zoneedit" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ez-ip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "pgpow" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dhs" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-static" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyndns-custom" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "ods" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "tzo" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "easydns-partner" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "gnudip" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "justlinux" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "dyns" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "hn" ++msgstr "" ++ ++#. Type: select ++#. Choices ++#: ../templates:3 ++msgid "heipv6tb" ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "Dynamic DNS provider to use:" ++msgstr "Nhà cung cấp DNS Äá»ng cần dùng:" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"There are many Dynamic DNS providers supported by ez-ipupdate. If you want " ++"your default configuration to be created automatically, you must select the " ++"provider that you wish to use here. You must configure an account on your " ++"chosen provider's service yourself." ++msgstr "" ++"Trình ez-ipupdate có há» trợ nhiá»u nhà cung cấp DNS Äá»ng. á» Äây thì bạn hãy " ++"chá»n nhà cung cấp nà o bạn muá»n dùng. Cần phải tá»± cấu hình má»t tà i khoản trên " ++"dá»ch vụ Äã chá»n." ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++msgid "" ++"If you prefer your default ez-ipupdate configuration not to be managed for " ++"you, you may choose "configure manually"." ++msgstr "" ++ ++#. Type: select ++#. Description ++#: ../templates:4 ++#, fuzzy ++msgid "" ++"Whatever your decision, you can later put as many additional configuration " ++"files in /etc/ez-ipupdate/ as you need." ++msgstr "" ++"Hãy ghi chú rằng bạn có thá» chÚn cà ng nhiá»u cấu hình thêm và o /etc/ez-" ++"ipupdate/ cà ng muá»n, và trình ez-ipupdate sẜ khÃŽng sá»a Äá»i chúng." ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "Does this system use dialup PPP to connect to the internet?" ++msgstr "" ++ ++#. Type: boolean ++#. Description ++#: ../templates:19 ++msgid "" ++"If you use dialup PPP to connect to the internet, then ez-ipupdate can be " ++"run to notify providers of your new address when ppp connects to the " ++"network. Otherwise it will run in the background, and scan for changes to " ++"your address while you are online." ++msgstr "" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "Address for your Dynamic DNS server:" ++msgstr "Äá»a chá» cho máy phục vụ DNS Äá»ng của bạn:" ++ ++#. Type: string ++#. Description ++#: ../templates:27 ++msgid "" ++"The service type you selected requires a server address to connect to. You " ++"may specify either a full hostname or an IP address." ++msgstr "" ++"Bạn Äã chá»n loại dá»ch vụ cần thiết má»t Äá»a chá» máy phục vụ Äá» kết ná»i Äến " ++"nó. Bạn có thá» ghi rõ hoặc má»t tên máy Äầy Äủ hoặc má»t Äá»a chá» IP." ++ ++#. Type: string ++#. Description ++#: ../templates:33 ++msgid "Username for your Dynamic DNS account:" ++msgstr "Tên ngÆ°á»i dùng cho tà i khoản DNS Äá»ng của bạn:" ++ ++#. Type: password ++#. Description ++#: ../templates:37 ++msgid "Password for your Dynamic DNS account:" ++msgstr "Máºt khẩu cho tà i khoản DNS Äá»ng của bạn:" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "Network interface to monitor:" ++msgstr "Giao diá»n mạng cần theo dõi:" ++ ++#. Type: string ++#. Description ++#: ../templates:42 ++msgid "" ++"ez-ipupdate will monitor the chosen network interface for changes of IP " ++"address. It is not possible to automatically detect which interface should " ++"be monitored, so you must name the interface here." ++msgstr "" ++"Trình ez-ipupdate sẜ theo dõi giao diá»n mạng Äã chá»n, Äá» tìm lần thay Äá»i " ++"Äá»a chá» IP nà o. KhÃŽng thá» tá»± Äá»ng phát hiá»n giao diá»n nà o cần theo dõi, thì " ++"bạn hãy gõ tên của giao diá»n ấy và o Äây." ++ ++#. Type: string ++#. Description ++#: ../templates:49 ++msgid "Dynamic DNS hostname to keep updated:" ++msgstr "Tên máy DNS Äá»ng cần cáºp nháºt suá»t:" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++msgid "Enable DNS wildcards for your Dynamic DNS hostname?" ++msgstr "Báºt kÃœ tá»± Äại diá»n DNS cho tên máy DNS Äá»ng khÃŽng?" ++ ++#. Type: boolean ++#. Description ++#: ../templates:54 ++#, fuzzy ++msgid "" ++"Many Dynamic DNS providers are capable of supporting "wildcard" DNS " ++"lookups. This means that for yourdomain, a lookup for anything.yourdomain " ++"will return an answer that points to yourdomain." ++msgstr "" ++"Nhiá»u nhà cung cấp dá»ch vụ DNS Äá»ng có khả nÄng há» trợ viá»c tra cứu DNS loại " ++"«Äại diá»n». Có nghÄ©a là cho miá»n_tÃŽi, khi tra cứu cáigì.miá»n_tÃŽi sẜ gá»i trả " ++"má»t trả lá»i ngụ Ãœ miá»n_tÃŽi. Nếu bạn muá»n báºt tÃnh nÄng nà y thì hãy Äá»ng Ãœ á» " ++"Äây." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "MX record to add:" ++msgstr "Mục ghi MX cần thêm:" ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"Many Dynamic DNS providers are capable of supporting MX records. If you want " ++"an MX record enabled for your domain, specify the content of that MX record " ++"here. If you do not want an MX record, leave it blank." ++msgstr "" ++"Nhiá»u nhà cung cấp dá»ch vụ DNS Äá»ng có khả nÄng há» trợ mục ghi MX. Nếu bạn " ++"muá»n báºt má»t mục ghi MX cho miá»n bạn, thì hãy ghi rõ ná»i dung của mục ghi MX " ++"ấy và o Äây. Nếu bạn khÃŽng muá»n Äiá»u ấy thì hãy bá» rá»ng." ++ ++#. Type: string ++#. Description ++#: ../templates:61 ++msgid "" ++"For further information on MX records, what they do, and how they are used, " ++"see your Dynamic DNS provider." ++msgstr "" ++"Äá» tìm thÃŽng tin thêm vá» mục ghi MX, chức nÄng chúng và cách sá» dụng chúng, " ++"hãy xem nhà cung cấp dá»ch vụ DNS Äá»ng của bạn." ++ ++#~ msgid "Manage your default configuration with debconf?" ++#~ msgstr "Quản lÃœ cấu hình mặc Äá»nh bạn dùng debconf khÃŽng?" ++ ++#~ msgid "" ++#~ "ez-ipupdate can manage your default configuration automatically using " ++#~ "debconf. If you do not want your default configuration managed " ++#~ "automatically, decline this option." ++#~ msgstr "" ++#~ "Trình ez-ipupdate có thá» tá»± Äá»ng quản lÃœ cấu hình bạn dùng debconf. Nếu " ++#~ "bạn khÃŽng muá»n Äiá»u nà y thì hãy từ khá»i tùy chá»n nà y." ++ ++#~ msgid "Run as a daemon?" ++#~ msgstr "Chạy trong ná»n khÃŽng?" ++ ++#~ msgid "" ++#~ "By default ez-ipupdate will run as a daemon to manage the configuration. " ++#~ "Refuse here if you do not want this. Instead, ez-ipupdate will install a " ++#~ "script in /etc/ppp/ip-up.d that will run all non-daemon configurations " ++#~ "when the ppp interface is brought up. See the /usr/share/doc/ez-ipupdate/" ++#~ "README.Debian file for more information." ++#~ msgstr "" ++#~ "Mặc Äá»nh là trình ez-ipupdate sẜ chạy trong ná»n (là dÊmon) Äá» quản lÃœ " ++#~ "tiến trình cấu hình. Hãy từ chá»i á» Äây nếu bạn khÃŽng muá»n Äiá»u nà y. Thay " ++#~ "và o Äó, trình ez-ipupdate sẜ cà i Äặt má»t táºp lá»nh và o /etc/ppp/ip-up.d mà " ++#~ "sẜ chạy má»i cấu hình khÃŽng phải là trình ná»n khi giao diá»n ppp má»i hoạt " ++#~ "Äá»ng. Hãy xem táºp tin /usr/share/doc/ez-ipupdate/README.Debian Äá» tìm " ++#~ "thÃŽng tin thêm." ++ ++#~ msgid "" ++#~ "If none of these automated behaviors suit you, you should probably not " ++#~ "manage your default configuration using debconf." ++#~ msgstr "" ++#~ "Nếu bạn khÃŽng muá»n dùng cách tá»± Äá»ng nà o thì rất có thá» là bạn khÃŽng nên " ++#~ "quản lÃœ cấu hình mặc Äá»nh dùng debconf." +--- ez-ipupdate-3.0.11b8.orig/debian/changelog ++++ ez-ipupdate-3.0.11b8/debian/changelog +@@ -0,0 +1,208 @@ ++ez-ipupdate (3.0.11b8-10) unstable; urgency=low ++ ++ * debian/templates: ++ + Allow translation of the "configure manually" option (Closes: #339047). ++ * debian/rules: ++ + Use dh_install instead of cp. ++ + Use dh_installexamples instead of cp. ++ ++ -- Sam Hocevar (Debian packages) <sam+deb@zoy.org> Mon, 14 Nov 2005 20:11:20 +0100 ++ ++ez-ipupdate (3.0.11b8-9) unstable; urgency=low ++ ++ * Acknowledge NMU. Thanks to Lucas Wall (Closes: #237444, #300821). ++ * debian/control: ++ + Set policy to 3.6.2.1. ++ * debian/rules: ++ + Use dh_installman instead of dh_installmanpages. ++ * debian/po/vi.po: ++ + Vietnamese debconf template translation, thanks to Clytie Siddall ++ (Closes: #311643). ++ * debian/config debian/templates: ++ + Merge the "manage the config file automatically?" and the "choose ++ service type" questions and set the priority to high (Closes: #275600). ++ + Put zoneedit higher in the list of services in debconf because it is ++ easy to set up. ++ + Do not ask for the interface in PPP mode. ++ + Tuned the questions so that they do not refer to a particular debconf ++ backend, and many other fixes suggested by Joey Hess (Closes: #275602). ++ + Replaced ez-ipupdate/daemon with ez-ipupdate/ppp. ++ * CHANGELOG: ++ + Changelog information more recent than 2001/07/04 is not available; I ++ added the NEWS information to this file instead (Closes: #306751). ++ * ez-ipupdate.c: ++ + Fixed a segfault thanks to Robert Jacobs (Closes: #323718). ++ ++ -- Sam Hocevar (Debian packages) <sam+deb@zoy.org> Sat, 12 Nov 2005 10:32:58 +0100 ++ ++ez-ipupdate (3.0.11b8-8.1) unstable; urgency=low ++ ++ * Non-maintainer upload ++ * Switched to po-debconf. (closes: #237444) ++ * Added Czech debconf template translation. ++ * Added French debconf template translation. ++ * Added German debconf template translation. ++ * Added Brazilian Portuguese debconf template translation. (closes: #300821) ++ ++ -- Lucas Wall <lwall@debian.org> Fri, 25 Mar 2005 17:34:15 -0300 ++ ++ez-ipupdate (3.0.11b8-8) unstable; urgency=critical ++ ++ * ez-ipupdate.c: ++ + Fixed the format string vulnerability in CAN-2004-0980 (Closes: #280822). ++ * debian/control: ++ + Set policy to 3.6.1.1. ++ ++ -- Sam Hocevar (Debian packages) <sam+deb@zoy.org> Sat, 13 Nov 2004 15:45:58 +0100 ++ ++ez-ipupdate (3.0.11b8-7) unstable; urgency=low ++ ++ * debian/control: ++ + Set policy to 3.6.1.0. ++ + Set debhelper build-dependency to (>= 4.1.68) because of dh_installppp. ++ * debian/rules: ++ + Use dh_installppp instead of doing the work by hand (Closes: #212896). ++ ++ -- Sam Hocevar (Debian packages) <sam+deb@zoy.org> Mon, 27 Oct 2003 13:39:09 +0100 ++ ++ez-ipupdate (3.0.11b8-6) unstable; urgency=low ++ ++ * debian/control: ++ + Set policy to 3.6.0. No changes required. ++ + Updated debhelper build-dependency to (>= 3.4.4) because we now ++ use debian/compat. ++ + Use ${misc:Depends}. ++ * debian/config: ++ + Fixed the wildcard/MX prompting, thanks to Sam Couter (Closes: #201720). ++ ++ -- Sam Hocevar (Debian packages) <sam+deb@zoy.org> Thu, 17 Jul 2003 14:44:06 +0200 ++ ++ez-ipupdate (3.0.11b8-5) unstable; urgency=low ++ ++ * Do not prompt for a username or password in daemon mode (Closes: #198141). ++ * debian/postinst: ++ + Removed useless verbosity when installing the package for the first time. ++ ++ -- Sam Hocevar (Debian packages) <sam+deb@zoy.org> Fri, 20 Jun 2003 10:17:37 +0200 ++ ++ez-ipupdate (3.0.11b8-4) unstable; urgency=low ++ ++ * Do not output the "invalid cache file" message if the reason is that the ++ cache file is empty. ++ * debian/postinst: ++ + Removed a temporary file that was left behind. ++ * Log to LOG_DAEMON instead of LOG_USER so that messages go to daemon.log. ++ * Only show the executable name in syslog, not its full path. ++ * Do not switch to OPT_QUIET in daemon mode, so that daemon.log shows ++ useful information such as login failures (Closes: #179717). ++ * Fixed a few spelling errors in the log messages. ++ * Open syslog before creating the pid file so that errors regarding the ++ pid file creation are logged as well. ++ ++ -- Sam Hocevar (Debian packages) <sam+deb@zoy.org> Thu, 19 Jun 2003 02:51:13 +0200 ++ ++ez-ipupdate (3.0.11b8-3) unstable; urgency=low ++ ++ * Fixed a crash in the GNUDip code when no address is specified. ++ * debian/control: ++ + Set policy to 3.5.10. ++ + Removed the leading "a" in the package description. ++ + Added URLs for the various services in the long description. ++ * debian/postinst: ++ + Fixed default cache filename, thanks to Daniel Bonniot (Closes: #194004). ++ + Added an invariant section to the default configuration file to preserve ++ user changes (Closes: #191642). ++ + No longer clear the password in debconf. ++ * debian/config: ++ + The GNUDip service needs a server address when run as a daemon; added a ++ debconf prompt for this. ++ + Added a debconf prompt to run ez-ipupdate as a daemon or through the ++ PPP ip-up.d script (Closes: #85942). ++ * debian/ppp: ++ + Added this script for /etc/ppp/ip-up.d/. ++ ++ -- Sam Hocevar (Debian packages) <sam+deb@zoy.org> Wed, 18 Jun 2003 15:08:00 +0200 ++ ++ez-ipupdate (3.0.11b8-2) unstable; urgency=low ++ ++ * Re-ran "rm -f config.sub config.guess configure install-sh missing \ ++ mkinstalldirs && aclocal && automake --copy --add-missing && autoconf" ++ * Updated policy to 3.5.9.0. ++ ++ -- Samuel Hocevar <sam@zoy.org> Wed, 23 Apr 2003 05:29:22 +0200 ++ ++ez-ipupdate (3.0.11b8-1) unstable; urgency=low ++ ++ * New upstream release. ++ * The debconf-created file is now mode 700 to avoid password exposure ++ (Closes: #190237). ++ ++ -- Samuel Hocevar <sam@zoy.org> Wed, 23 Apr 2003 05:03:37 +0200 ++ ++ez-ipupdate (3.0.11b7-3) unstable; urgency=low ++ ++ * The "faster than light" release. ++ * Really fixed the timestamp skew in debian/rules (Closes: #180901). ++ ++ -- Samuel Hocevar <sam@zoy.org> Fri, 14 Feb 2003 02:12:38 +0100 ++ ++ez-ipupdate (3.0.11b7-2) unstable; urgency=low ++ ++ * The "bloody valentine" release. ++ * Fixed another timestamp skew in debian/rules (Closes: #180901, #180904). ++ ++ -- Samuel Hocevar <sam@zoy.org> Fri, 14 Feb 2003 01:06:02 +0100 ++ ++ez-ipupdate (3.0.11b7-1) unstable; urgency=low ++ ++ * The "eternal hellfire for lazy maintainers" release. ++ * New upstream package (Closes: #167038). ++ * Removed dependency on debconf-tiny (Closes: #137029). ++ * We now Provide: dyndns-client (Closes: #139082). ++ * Updated authors list in debian/copyright (Closes: #177772). ++ * Fixed -Wall warnings. ++ * This release fixes a hang in ODS_read_response() (Closes: #169043). ++ * Added various safety checks in the init.d script. ++ * Fixed the reload rule in the init.d script (Closes: #144798). ++ * The init.d script only looks for files ending with .conf (Closes: #139518). ++ * Applied a patch to handle running ez-ipupdate as a user, courtesy of Sam ++ Couter (Closes: #127913). ++ * Applied a patch for debconf management of the default configuration, ++ courtesy of Sam Couter again (Closes: #100327). ++ * Prevented timestamp skews in debian/rules. ++ * Wrote a short manpage (Closes: #168361). ++ ++ -- Samuel Hocevar <sam@zoy.org> Thu, 13 Feb 2003 15:56:57 +0100 ++ ++ez-ipupdate (3.0.11b5-1) unstable; urgency=low ++ ++ * New upstream package. ++ ++ -- Samuel Hocevar <sam@zoy.org> Thu, 8 Nov 2001 19:43:21 +0100 ++ ++ez-ipupdate (3.0.10-2) unstable; urgency=low ++ ++ * Now builds and runs properly on Hurd (Closes: #108058). ++ ++ -- Samuel Hocevar <sam@zoy.org> Thu, 9 Aug 2001 15:31:23 +0200 ++ ++ez-ipupdate (3.0.10-1) unstable; urgency=low ++ ++ * New upstream release. ++ * Fixed typo in init.d (Closes: #97175). ++ ++ -- Samuel Hocevar <sam@zoy.org> Fri, 11 May 2001 18:51:35 +0200 ++ ++ez-ipupdate (3.0.6-1) unstable; urgency=low ++ ++ * New upstream release. ++ * Fixed moronic errors in the init.d file (Closes: #85057, #85955, #85956). ++ * Removed generic installation instructions from /usr/share/doc. ++ ++ -- Samuel Hocevar <sam@zoy.org> Thu, 1 Mar 2001 11:44:35 +0100 ++ ++ez-ipupdate (3.0.4-1) unstable; urgency=low ++ ++ * Initial Release (Closes: #78202). ++ ++ -- Samuel Hocevar <sam@zoy.org> Mon, 25 Dec 2000 05:48:01 +0100 +--- ez-ipupdate-3.0.11b8.orig/debian/templates ++++ ez-ipupdate-3.0.11b8/debian/templates +@@ -0,0 +1,67 @@ ++Template: ez-ipupdate/service_type ++Type: select ++__Choices: configure manually, zoneedit, ez-ip, pgpow, dhs, dyndns, dyndns-static, dyndns-custom, ods, tzo, easydns, easydns-partner, gnudip, justlinux, dyns, hn, heipv6tb ++_Description: Dynamic DNS provider to use: ++ There are many Dynamic DNS providers supported by ez-ipupdate. If you want ++ your default configuration to be created automatically, you must select the ++ provider that you wish to use here. You must configure an account on your ++ chosen provider's service yourself. ++ . ++ If you prefer your default ez-ipupdate configuration not to be managed for ++ you, you may choose "configure manually". ++ . ++ Whatever your decision, you can later put as many additional configuration ++ files in /etc/ez-ipupdate/ as you need. ++ ++Template: ez-ipupdate/ppp ++Type: boolean ++Default: false ++_Description: Does this system use dialup PPP to connect to the internet? ++ If you use dialup PPP to connect to the internet, then ez-ipupdate can ++ be run to notify providers of your new address when ppp connects to the ++ network. Otherwise it will run in the background, and scan for changes ++ to your address while you are online. ++ ++Template: ez-ipupdate/server ++Type: string ++_Description: Address for your Dynamic DNS server: ++ The service type you selected requires a server address to connect to. You ++ may specify either a full hostname or an IP address. ++ ++Template: ez-ipupdate/username ++Type: string ++_Description: Username for your Dynamic DNS account: ++ ++Template: ez-ipupdate/password ++Type: password ++_Description: Password for your Dynamic DNS account: ++ ++Template: ez-ipupdate/interface ++Type: string ++Default: eth0 ++_Description: Network interface to monitor: ++ ez-ipupdate will monitor the chosen network interface for changes of IP ++ address. It is not possible to automatically detect which interface should ++ be monitored, so you must name the interface here. ++ ++Template: ez-ipupdate/hostname ++Type: string ++_Description: Dynamic DNS hostname to keep updated: ++ ++Template: ez-ipupdate/dns_wildcard ++Type: boolean ++Default: false ++_Description: Enable DNS wildcards for your Dynamic DNS hostname? ++ Many Dynamic DNS providers are capable of supporting "wildcard" DNS ++ lookups. This means that for yourdomain, a lookup for anything.yourdomain ++ will return an answer that points to yourdomain. ++ ++Template: ez-ipupdate/dns_mx ++Type: string ++_Description: MX record to add: ++ Many Dynamic DNS providers are capable of supporting MX records. If you ++ want an MX record enabled for your domain, specify the content of that MX ++ record here. If you do not want an MX record, leave it blank. ++ . ++ For further information on MX records, what they do, and how they are ++ used, see your Dynamic DNS provider. +--- ez-ipupdate-3.0.11b8.orig/debian/copyright ++++ ez-ipupdate-3.0.11b8/debian/copyright +@@ -0,0 +1,16 @@ ++This package was debianized by Sam Hocevar <sam@zoy.org> on ++Mon, 25 Dec 2000 05:48:01 +0100. ++ ++It was downloaded from http://ez-ipupdate.com/ ++ ++Upstream Authors: Angus Mackay <amackay@gusnet.cx> ++ Jeremy Bopp <jbopp@mail.utexas.edu> ++ Mark Jeftovic <markjr@easydns.com> ++ Stefaan Ponnet <webmaster@dyns.cx> ++ Colin Viebrock <colin@easydns.com> ++ Tim Brown <timb@machine.org.uk> ++ ++License: GNU General Public License. ++ ++On Debian GNU/Linux systems, a copy of the GNU GPL can be found in ++/usr/share/common-licenses/GPL. +--- ez-ipupdate-3.0.11b8.orig/debian/dirs ++++ ez-ipupdate-3.0.11b8/debian/dirs +@@ -0,0 +1,4 @@ ++etc/ez-ipupdate ++etc/ppp/ip-up.d/ ++usr/sbin ++usr/share/doc/ez-ipupdate/examples +--- ez-ipupdate-3.0.11b8.orig/debian/init ++++ ez-ipupdate-3.0.11b8/debian/init +@@ -0,0 +1,96 @@ ++#! /bin/sh ++ ++PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin ++DAEMON=/usr/sbin/ez-ipupdate ++NAME=ez-ipupdate ++DESC="Dynamic DNS client" ++ ++test -f "$DAEMON" || exit 0 ++ ++set -e ++ ++case "$1" in ++ start) ++ echo -n "Starting $DESC:" ++ configs=`find "/etc/$NAME/" -name '*.conf' | \ ++ sed -e 's,.*/(.*).conf,\1,'` ++ if [ x"$configs" = x ] ++ then ++ echo " no .conf file in /etc/$NAME." ++ exit 0 ++ fi ++ ++ echo -n " $NAME" ++ for config in `echo "$configs"` ++ do ++ # Don't run configurations that are not daemons ++ if ! grep -q '^ *daemon' "/etc/$NAME/$config.conf"; then continue; fi ++ # Don't run configurations that run in the foreground ++ if grep -q '^ *foreground' "/etc/$NAME/$config.conf"; then continue; fi ++ # Ok, launch an ez-ipupdate instance ++ if start-stop-daemon --start --quiet \ ++ --pidfile "/var/run/$NAME/$config.pid" \ ++ --exec "$DAEMON" \ ++ -- -d -c "/etc/$NAME/$config.conf" \ ++ -F "/var/run/$NAME/$config.pid" ++ then ++ echo -n " $config" ++ fi ++ done ++ echo "." ++ ;; ++ stop) ++ echo -n "Stopping $DESC:" ++ pidfiles=`find "/var/run/$NAME/" -name "*.pid" | \ ++ sed -e 's,.*/(.*).pid,\1,'` ++ if [ x"$pidfiles" = x ] ++ then ++ echo " no $NAME running." ++ exit 0 ++ fi ++ ++ echo -n " $NAME" ++ for pidfile in `echo "$pidfiles"` ++ do ++ if start-stop-daemon --stop --signal 3 --quiet \ ++ --pidfile "/var/run/$NAME/$pidfile.pid" ++ then ++ echo -n " $pidfile" ++ fi ++ done ++ echo "." ++ ;; ++ reload) ++ echo -n "Reloading $DESC configuration files:" ++ pidfiles=`find "/var/run/$NAME" -name "*.pid" | \ ++ sed -e 's,.*/(.*).pid,\1,'` ++ if [ x"$pidfiles" = x ] ++ then ++ echo " no $NAME running." ++ exit 0 ++ fi ++ ++ echo -n " $NAME" ++ for pidfile in `echo "$pidfiles"` ++ do ++ if start-stop-daemon --stop --signal 1 --quiet \ ++ --pidfile "/var/run/$NAME/$pidfile.pid" ++ then ++ echo -n " $pidfile" ++ fi ++ done ++ echo "." ++ ;; ++ restart|force-reload) ++ $0 stop ++ sleep 1 ++ $0 start ++ ;; ++ *) ++ N="/etc/init.d/$NAME" ++ echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 ++ exit 1 ++ ;; ++esac ++ ++exit 0 +--- ez-ipupdate-3.0.11b8.orig/debian/README.Debian ++++ ez-ipupdate-3.0.11b8/debian/README.Debian +@@ -0,0 +1,37 @@ ++Notes for ez-ipupdate on Debian ++=============================== ++ ++Configuration files ++------------------- ++ To configure this package, put your configuration files the /etc/ez-ipupdate/ ++directory. ++ ++ To avoid password exposure, it is recommended you set the permission for all ++configuration files in this directory to 700 (-rwx------). You will still be ++able to use the run-as-user option because the file is opened before root ++permissions are dropped. ++ ++Automated behavior ++------------------ ++ The init.d script will launch an ez-ipupdate daemon for each configuration ++file in that directory that has the "daemon" option set and the "foreground" ++option disabled. ++ ++ The ppp script will launch ez-ipupdate once for each configuration file in ++the /etc/ez-ipupdate/ directory that has the "daemon" and the "foreground" ++options disabled. ++ ++ If you do not want your configuration files to be automatically used, please ++set the "foreground" option in them, or put them in an alternate directory. ++ ++Cache files ++----------- ++ You may store cache files in /var/cache/ez-ipupdate/, as the daemon has write ++permission to this directory. ++ ++ ++ -- Sam Hocevar <sam@zoy.org> Mon, 25 Dec 2000 05:48:01 +0100 ++ updated on Thu, 13 Feb 2003 15:56:36 +0100 (cache files) ++ updated on Wed, 23 Apr 2003 04:59:52 +0200 (file permissions) ++ updated on Wed, 18 Jun 2003 20:08:44 +0200 (ppp ip-up.d) ++ +--- ez-ipupdate-3.0.11b8.orig/debian/rules ++++ ez-ipupdate-3.0.11b8/debian/rules +@@ -0,0 +1,87 @@ ++#!/usr/bin/make -f ++# Sample debian/rules that uses debhelper. ++# GNU copyright 1997 to 1999 by Joey Hess. ++ ++# Uncomment this to turn on verbose mode. ++#export DH_VERBOSE=1 ++ ++export DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) ++export DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) ++ ++confflags = --prefix=/usr ++confflags += --mandir=$${prefix}/share/man --infodir=$${prefix}/share/info ++ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE)) ++ confflags += --build $(DEB_HOST_GNU_TYPE) ++else ++ confflags += --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE) ++endif ++ ++configure: configure-stamp ++configure-stamp: ++ dh_testdir ++ touch configure.in \ ++ && touch aclocal.m4 \ ++ && touch configure \ ++ && touch stamp-h.in \ ++ && touch config.h.in \ ++ && touch `find -name Makefile.in` ++ CFLAGS=-Wall ./configure $(confflags) ++ touch configure-stamp ++ ++build: configure-stamp build-stamp ++build-stamp: ++ dh_testdir ++ $(MAKE) ++ touch build-stamp ++ ++clean: ++ dh_testdir ++ dh_testroot ++ rm -f build-stamp configure-stamp ++ -$(MAKE) distclean ++ chmod a-x ex*conf ++ dh_clean ++ debconf-updatepo ++ ++install: build ++ dh_testdir ++ dh_testroot ++ dh_clean -k ++ dh_installdirs ++ dh_install ez-ipupdate /usr/sbin/ ++ dh_installppp ++ ++# Build architecture-independent files here. ++binary-indep: build install ++# We have nothing to do by default. ++ ++# Build architecture-dependent files here. ++binary-arch: build install ++# dh_testversion ++ dh_testdir ++ dh_testroot ++ dh_installdebconf ++ dh_installdocs ++ dh_installexamples ex*conf ++ dh_installmenu ++# dh_installemacsen ++# dh_installpam ++ dh_installinit ++ dh_installcron ++ dh_installman ez-ipupdate.8 ++ dh_installinfo ++ dh_installchangelogs CHANGELOG ++ dh_link ++ dh_strip ++ dh_compress ++ dh_fixperms ++# dh_makeshlibs ++ dh_installdeb ++# dh_perl ++ dh_shlibdeps ++ dh_gencontrol ++ dh_md5sums ++ dh_builddeb ++ ++binary: binary-indep binary-arch ++.PHONY: build clean binary-indep binary-arch binary install configure +--- ez-ipupdate-3.0.11b8.orig/debian/docs ++++ ez-ipupdate-3.0.11b8/debian/docs +@@ -0,0 +1 @@ ++README +--- ez-ipupdate-3.0.11b8.orig/debian/postinst ++++ ez-ipupdate-3.0.11b8/debian/postinst +@@ -0,0 +1,139 @@ ++#! /bin/sh ++# postinst script for ez-ipupdate ++# ++# see: dh_installdeb(1) ++ ++set -e ++ ++# Load the debconf library ++. /usr/share/debconf/confmodule ++ ++# summary of how this script can be called: ++# * <postinst> `configure' <most-recently-configured-version> ++# * <old-postinst> `abort-upgrade' <new version> ++# * <conflictor's-postinst> `abort-remove' `in-favour' <package> ++# <new-version> ++# * <deconfigured's-postinst> `abort-deconfigure' `in-favour' ++# <failed-install-package> <version> `removing' ++# <conflicting-package> <version> ++# for details, see http://www.debian.org/doc/debian-policy/ or ++# the debian-policy package ++# ++# quoting from the policy: ++# Any necessary prompting should almost always be confined to the ++# post-installation script, and should be protected with a conditional ++# so that unnecessary prompting doesn't happen if a package's ++# installation fails and the `postinst' is called with `abort-upgrade', ++# `abort-remove' or `abort-deconfigure'. ++ ++case "$1" in ++ configure) ++ # Create the user if it doesn't exist ++ if ! id ez-ipupd 2>/dev/null 1>&2 ; then ++ adduser --system --home /var/cache/ez-ipupdate \ ++ --shell /bin/false --gecos "Dynamic DNS client" \ ++ --disabled-password --disabled-login ez-ipupd ++ fi ++ # Create the default cache file ++ touch /var/cache/ez-ipupdate/default-cache ++ chown ez-ipupd /var/cache/ez-ipupdate/default-cache ++ # Remove spurious cache file from the 3.0.11b8-2 broken package ++ rm -f /var/cache/ez-ipupdate/cache-default ++ # Create the directory where the PID file will be stored ++ mkdir -p /var/run/ez-ipupdate ++ chown -R ez-ipupd /var/run/ez-ipupdate ++ # Create the default config file (maybe) ++ db_get ez-ipupdate/service_type ++ if [ "$RET" != "configure manually" ] ; then ++ service="$RET" ++ conf="/etc/ez-ipupdate/default.conf" ++ newconf="$conf.dpkg-new" ++ # Grab answers from debconf ++ db_get ez-ipupdate/ppp ++ ppp="$RET" ++ db_get ez-ipupdate/username ++ username="$RET" ++ db_get ez-ipupdate/password ++ password="$RET" ++ db_get ez-ipupdate/hostname ++ hostname="$RET" ++ db_get ez-ipupdate/interface ++ interface="$RET" ++ echo "#!/usr/sbin/ez-ipupdate -c" > "$newconf" ++ cat >> "$newconf" << EOF ++### ++### Default ez-ipupdate configuration file - EDIT WITH CARE ++### Use `dpkg-reconfigure ez-ipupdate' to update the debconf-generated lines. ++### ++ ++### The following lines were generated by debconf ++ ++service-type=$service ++EOF ++ db_get ez-ipupdate/server || RET="" ++ if [ -n "$RET" ]; then ++ echo "server=$RET" >> "$newconf" ++ else ++ echo "#server=(default)" >> "$newconf" ++ fi ++ cat >> "$newconf" << EOF ++user=$username:$password ++host=$hostname ++interface=$interface ++EOF ++ db_get ez-ipupdate/dns_wildcard || RET="false" ++ if [ "$RET" = "true" ]; then ++ echo "wildcard" >> "$newconf" ++ else ++ echo "#wildcard" >> "$newconf" ++ fi ++ db_get ez-ipupdate/dns_mx || RET="" ++ if [ -n "$RET" ]; then ++ echo "mx=$RET" >> "$newconf" ++ else ++ echo "#mx=(none)" >> "$newconf" ++ fi ++ cat >> "$newconf" << EOF ++run-as-user=ez-ipupd ++cache-file=/var/cache/ez-ipupdate/default-cache ++EOF ++ if [ "$ppp" = "true" ]; then ++ echo "#daemon" >> "$newconf" ++ else ++ echo "daemon" >> "$newconf" ++ fi ++ echo >> "$newconf" ++ if grep -q '^### Changes below this' "$conf" >/dev/null 2>&1; then ++ sed -ne '/^### Changes below this/,$p' < "$conf" >> "$newconf" ++ else ++ cat >> "$newconf" << EOF ++### Changes below this line will be preserved on upgrades. ++ ++EOF ++ fi ++ # Fix the file permissions ++ chmod 700 "$newconf" ++ rm -f "$conf" && mv "$newconf" "$conf" ++ # Remove that old file, from broken 3.0.11b8-3 package ++ rm -f "$conf.new" ++ fi ++ ;; ++ ++ abort-upgrade|abort-remove|abort-deconfigure) ++ ;; ++ ++ *) ++ echo "postinst called with unknown argument `$1'" >&2 ++ exit 1 ++ ;; ++esac ++ ++# dh_installdeb will replace this with shell code automatically ++# generated by other debhelper scripts. ++ ++#DEBHELPER# ++ ++# ez-ipupdate is a bit misbehaved. ++db_stop ++ ++exit 0 +--- ez-ipupdate-3.0.11b8.orig/debian/config ++++ ez-ipupdate-3.0.11b8/debian/config +@@ -0,0 +1,165 @@ ++#!/bin/sh ++ ++set -e ++ ++# Source debconf library ++. /usr/share/debconf/confmodule ++ ++service_supports_wildcards() ++{ ++ service=$1 ++ ret=1 ++ ++ case "$service" in ++ ez-ip|dhs|dyndns|dyndns-static|easydns|easydns-partner) ++ ret=0 ++ ;; ++ esac ++ ++ return $ret ++} ++ ++service_supports_mx() ++{ ++ service=$1 ++ ret=1 ++ ++ case "$service" in ++ ez-ip|dhs|dyndns|dyndns-static|easydns|zoneedit) ++ ret=0 ++ ;; ++ esac ++ ++ return $ret ++} ++ ++service_needs_server() ++{ ++ service=$1 ++ ret=1 ++ ++ case "$service" in ++ gnudip) ++ ret=0 ++ ;; ++ esac ++ ++ return $ret ++} ++ ++# I no longer claim this question, migrate it. ++if db_get ez-ipupdate/daemon; then ++ case "$RET" in ++ true) db_set ez-ipupdate/ppp "false" ;; ++ false) db_set ez-ipupdate/ppp "true" ;; ++ esac ++ db_unregister ez-ipupdate/daemon ++fi ++ ++# I no longer claim this question either. ++if db_get ez-ipupdate/manage_default_config_automatically; then ++ case "$RET" in ++ false) db_set ez-ipupdate/service_type "configure manually" ;; ++ esac ++ db_unregister ez-ipupdate/manage_default_config_automatically ++fi ++ ++# Name the configuration file ++conf=/etc/ez-ipupdate/default.conf ++ ++# Do you want debconf to manage the default configuration? ++if [ -f "$conf" ]; then ++ service="`sed -ne 's/^service-type *= *//p' < $conf`" ++fi ++if [ -n "$service" ]; then ++ db_set ez-ipupdate/service_type "$service" ++fi ++db_input high ez-ipupdate/service_type || true ++db_go ++ ++db_get ez-ipupdate/service_type ++if [ "$RET" != "configure manually" ]; then ++ if [ -f "$conf" ]; then ++ # Grab existing values from config file ++ if grep "^daemon" $conf > /dev/null 2>&1; then ++ ppp="false" ++ fi ++ service="`sed -ne 's/^service-type *= *//p' < $conf`" ++ server="`sed -ne 's/^server *= *//p' < $conf`" ++ username="`sed -ne 's/^user *= *([^:]*):.*/\1/p' < $conf`" ++ password="`sed -ne 's/^user *= *[^:]*://p' < $conf`" ++ hostname="`sed -ne 's/^host *= *//p' < $conf`" ++ interface="`sed -ne 's/^interface *= *//p' < $conf`" ++ if grep "^wildcard" $conf > /dev/null 2>&1; then ++ wildcard="true" ++ fi ++ dns_mx="`sed -ne 's/^mx *= *//p' < $conf`" ++ # Poke the values into debconf ++ if [ -n "$ppp" ]; then ++ db_set ez-ipupdate/ppp "$ppp" ++ fi ++ if [ -n "$service" ]; then ++ db_set ez-ipupdate/service_type "$service" ++ fi ++ if [ -n "$server" ]; then ++ db_set ez-ipupdate/server "$server" ++ fi ++ if [ -n "$username" ]; then ++ db_set ez-ipupdate/username "$username" ++ fi ++ if [ -n "$password" ]; then ++ db_set ez-ipupdate/password "$password" ++ fi ++ if [ -n "$hostname" ]; then ++ db_set ez-ipupdate/hostname "$hostname" ++ fi ++ if [ -n "$interface" ]; then ++ db_set ez-ipupdate/interface "$interface" ++ fi ++ if [ "$wildcard" = true ]; then ++ db_set ez-ipupdate/dns_wildcard true ++ fi ++ if [ -n "$dns_mx" ]; then ++ db_set ez-ipupdate/dns_mx "$dns_mx" ++ fi ++ fi ++ # Ask for new answers ++ db_beginblock ++ db_input high ez-ipupdate/ppp || true ++ db_input high ez-ipupdate/username || true ++ db_input high ez-ipupdate/password || true ++ db_input high ez-ipupdate/hostname || true ++ db_endblock ++ db_go ++ # Need to determine whether wildcards and MX records are supported ++ # by the chosen service ++ db_beginblock ++ db_get ez-ipupdate/service_type ++ service_type="$RET" ++ if service_needs_server "$service_type"; then ++ db_input high ez-ipupdate/server || true ++ else ++ db_set ez-ipupdate/server "" ++ fi ++ if service_supports_wildcards "$service_type"; then ++ db_input medium ez-ipupdate/dns_wildcard || true ++ else ++ db_set ez-ipupdate/dns_wildcard false ++ fi ++ if service_supports_mx "$service_type"; then ++ db_input medium ez-ipupdate/dns_mx || true ++ else ++ db_set ez-ipupdate/dns_mx "" ++ fi ++ db_endblock ++ db_go ++ # Check whether we really need to know the listening interface ++ db_beginblock ++ db_get ez-ipupdate/ppp ++ ppp="$RET" ++ if [ "$ppp" = "false" ]; then ++ db_input high ez-ipupdate/interface || true ++ fi ++ db_endblock ++ db_go ++fi +--- ez-ipupdate-3.0.11b8.orig/debian/postrm ++++ ez-ipupdate-3.0.11b8/debian/postrm +@@ -0,0 +1,54 @@ ++#! /bin/sh ++# postrm script for ez-ipupdate ++# ++# see: dh_installdeb(1) ++ ++set -e ++ ++# summary of how this script can be called: ++# * <postrm> `remove' ++# * <postrm> `purge' ++# * <old-postrm> `upgrade' <new-version> ++# * <new-postrm> `failed-upgrade' <old-version> ++# * <new-postrm> `abort-install' ++# * <new-postrm> `abort-install' <old-version> ++# * <new-postrm> `abort-upgrade' <old-version> ++# * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version> ++# for details, see http://www.debian.org/doc/debian-policy/ or ++# the debian-policy package ++ ++#DEBHELPER# ++ ++remove_var_run() { ++ # Delete the user account, if it exists ++ if id ez-ipupd 2>/dev/null 1>&2 ; then ++ deluser ez-ipupd ++ # The --remove-home option to deluser requires ++ # perl-modules? WTF? ++ rm -Rf /var/cache/ez-ipupdate ++ fi ++ # And remove the directory where the PID files were stored ++ rm -rf /var/run/ez-ipupdate ++} ++ ++case "$1" in ++ purge) ++ rm -f /etc/ez-ipupdate/default.conf ++ remove_var_run ++ ;; ++ ++ remove) ++ remove_var_run ++ ;; ++ ++ upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ++ ;; ++ ++ *) ++ echo "postrm called with unknown argument `$1'" >&2 ++ exit 1 ++ ;; ++ ++esac ++ ++exit 0 +--- ez-ipupdate-3.0.11b8.orig/debian/preinst ++++ ez-ipupdate-3.0.11b8/debian/preinst +@@ -0,0 +1,35 @@ ++#! /bin/sh ++# preinst script for ez-ipupdate ++# ++# see: dh_installdeb(1) ++ ++set -e ++ ++# summary of how this script can be called: ++# * <new-preinst> `install' ++# * <new-preinst> `install' <old-version> ++# * <new-preinst> `upgrade' <old-version> ++# * <old-preinst> `abort-upgrade' <new-version> ++# ++# for details, see http://www.debian.org/doc/debian-policy/ or ++# the debian-policy package ++ ++case "$1" in ++ install|upgrade) ++ ;; ++ ++ abort-upgrade) ++ ;; ++ ++ *) ++ echo "preinst called with unknown argument `$1'" >&2 ++ exit 1 ++ ;; ++esac ++ ++# dh_installdeb will replace this with shell code automatically ++# generated by other debhelper scripts. ++ ++#DEBHELPER# ++ ++exit 0 +--- ez-ipupdate-3.0.11b8.orig/debian/prerm ++++ ez-ipupdate-3.0.11b8/debian/prerm +@@ -0,0 +1,37 @@ ++#! /bin/sh ++# prerm script for ez-ipupdate ++# ++# see: dh_installdeb(1) ++ ++set -e ++ ++# summary of how this script can be called: ++# * <prerm> `remove' ++# * <old-prerm> `upgrade' <new-version> ++# * <new-prerm> `failed-upgrade' <old-version> ++# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version> ++# * <deconfigured's-prerm> `deconfigure' `in-favour' ++# <package-being-installed> <version> `removing' ++# <conflicting-package> <version> ++# for details, see http://www.debian.org/doc/debian-policy/ or ++# the debian-policy package ++ ++case "$1" in ++ remove|upgrade|deconfigure) ++ ;; ++ ++ failed-upgrade) ++ ;; ++ ++ *) ++ echo "prerm called with unknown argument `$1'" >&2 ++ exit 1 ++ ;; ++esac ++ ++# dh_installdeb will replace this with shell code automatically ++# generated by other debhelper scripts. ++ ++#DEBHELPER# ++ ++exit 0 +--- ez-ipupdate-3.0.11b8.orig/debian/compat ++++ ez-ipupdate-3.0.11b8/debian/compat +@@ -0,0 +1 @@ ++4 +--- ez-ipupdate-3.0.11b8.orig/debian/ez-ipupdate.ppp.ip-up ++++ ez-ipupdate-3.0.11b8/debian/ez-ipupdate.ppp.ip-up +@@ -0,0 +1,25 @@ ++#!/bin/sh ++# ++# Default ez-ipupdate ip-up script ++# /etc/ppp/ip-up.d/ez-ipupdate ++# ++ ++PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin ++DAEMON=/usr/sbin/ez-ipupdate ++NAME=ez-ipupdate ++ ++[ -x $DAEMON ] || exit 0 ++ ++configs=`find "/etc/$NAME/" -name '*.conf' | sed -e 's,.*/(.*).conf,\1,'` ++[ x"$configs" = x ] && exit 0 ++ ++for config in `echo "$configs"` ++do ++ # Don't run daemon configurations ++ if grep -q '^ *daemon' "/etc/$NAME/$config.conf"; then continue; fi ++ # Don't run configurations that run in the foreground ++ if grep -q '^ *foreground' "/etc/$NAME/$config.conf"; then continue; fi ++ # Ok, launch an ez-ipupdate instance ++ "$DAEMON" -c "/etc/$NAME/$config.conf" ++done ++ +--- ez-ipupdate-3.0.11b8.orig/ez-ipupdate.8 ++++ ez-ipupdate-3.0.11b8/ez-ipupdate.8 +@@ -0,0 +1,140 @@ ++." DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. ++." I DO WHATEVER I WANT YOU DUMBASS SCRIPT! -- Sam ++.TH EZ-IPUPDATE "8" "February 2003" "ez-ipupdate - 3.0.11b7" "Dynamic DNS client" ++.SH NAME ++ez-ipupdate - dynamic DNS client ++.SH SYNOPSIS ++.B ez-ipupdate ++.RI [ options ] ++.SH DESCRIPTION ++This manual page documents briefly the ++.B ez-ipupdate ++dynamic DNS client. ++ ++.SH OPTIONS ++.B ez-ipupdate ++follows the usual GNU command line syntax, with long ++options starting with two dashes (`-'). ++.TP ++\fB-a\fR, \fB--address\fR <ip address> ++string to send as your ip address ++.TP ++\fB-b\fR, \fB--cache-file\fR <file> ++file to use for caching the ipaddress ++.TP ++\fB-c\fR, \fB--config-file\fR <file> ++configuration file, almost all arguments can be ++given with: <name>[=<value>] ++to see a list of possible config commands ++try "echo help | ez-ipupdate \fB-c\fR -" ++.TP ++\fB-d\fR, \fB--daemon\fR ++run as a daemon periodicly updating if ++necessary ++.TP ++\fB-e\fR, \fB--execute\fR <command> ++shell command to execute after a successful ++update ++.TP ++\fB-f\fR, \fB--foreground\fR ++when running as a daemon run in the foreground ++.TP ++\fB-F\fR, \fB--pidfile\fR <file> ++use <file> as a pid file ++.TP ++\fB-g\fR, \fB--request-uri\fR <uri> ++URI to send updates to ++.TP ++\fB-h\fR, \fB--host\fR <host> ++string to send as host parameter ++.TP ++\fB-i\fR, \fB--interface\fR <iface> ++which interface to use ++.TP ++\fB-L\fR, \fB--cloak_title\fR <host> ++some stupid thing for DHS only ++.TP ++\fB-m\fR, \fB--mx\fR <mail exchange> ++string to send as your mail exchange ++.HP ++\fB-M\fR, \fB--max-interval\fR <# of sec> max time in between updates ++.TP ++\fB-N\fR, \fB--notify-email\fR <email> ++address to send mail to if bad things happen ++.TP ++\fB-o\fR, \fB--offline\fR ++set to off line mode ++.TP ++\fB-p\fR, \fB--resolv-period\fR <sec> ++period to check IP if it can't be resolved ++.TP ++\fB-P\fR, \fB--period\fR <# of sec> ++period to check IP in daemon ++mode (default: 1800 seconds) ++.TP ++\fB-q\fR, \fB--quiet\fR ++be quiet ++.TP ++\fB-r\fR, \fB--retrys\fR <num> ++number of trys (default: 1) ++.TP ++\fB-R\fR, \fB--run-as-user\fR <user> ++change to <user> for running, be ware ++that this can cause problems with handeling ++SIGHUP properly if that user can't read the ++config file. also it can't write it's pid file ++to a root directory ++.TP ++\fB-Q\fR, \fB--run-as-euser\fR <user> ++change to effective <user> for running, ++this is NOT secure but it does solve the ++problems with run-as-user and config files and ++pid files. ++.TP ++\fB-s\fR, \fB--server\fR <server[:port]> ++the server to connect to ++.TP ++\fB-S\fR, \fB--service-type\fR <server> ++the type of service that you are using ++try one of: null ezip pgpow dhs ++dyndns dyndns-static dyndns-custom ++ods tzo easydns easydns-partner ++gnudip justlinux dyns hn zoneedit ++heipv6tb ++.TP ++\fB-t\fR, \fB--timeout\fR <sec.millisec> ++the amount of time to wait on I/O ++.TP ++\fB-T\fR, \fB--connection-type\fR <num> ++number sent to TZO as your connection ++type (default: 1) ++.TP ++\fB-U\fR, \fB--url\fR <url> ++string to send as the url parameter ++.TP ++\fB-u\fR, \fB--user\fR <user[:passwd]> ++user ID and password, if either is left blank ++they will be prompted for ++.TP ++\fB-w\fR, \fB--wildcard\fR ++set your domain to have a wildcard alias ++.TP ++\fB-z\fR, \fB--partner\fR <partner> ++specify easyDNS partner (for easydns-partner ++services) ++.TP ++\fB--help\fR ++display this help and exit ++.TP ++\fB--version\fR ++output version information and exit ++.TP ++\fB--credits\fR ++print the credits and exit ++.TP ++\fB--signalhelp\fR ++print help about signals ++.br ++.SH AUTHOR ++This manual page was written by Sam Hocevar <sam@zoy.org> for the Debian ++GNU/Linux system (but may be used by others). diff --git a/pkgs/core/ez-ipupdate/patches/ez-ipupdate-3.0.11b8-pidfile.patch b/pkgs/core/ez-ipupdate/patches/ez-ipupdate-3.0.11b8-pidfile.patch new file mode 100644 index 0000000..65d5ab2 --- /dev/null +++ b/pkgs/core/ez-ipupdate/patches/ez-ipupdate-3.0.11b8-pidfile.patch @@ -0,0 +1,11 @@ +--- a/ez-ipupdate.c 2003-05-27 17:48:26.000000000 +0300 ++++ b/ez-ipupdate.c 2003-05-27 19:28:38.000000000 +0300 +@@ -629,7 +629,7 @@ + #endif + fprintf(stdout, " -e, --execute <command>\tshell command to execute after a successful\n\t\t\t\tupdate\n"); + fprintf(stdout, " -f, --foreground\t\twhen running as a daemon run in the foreground\n"); +- fprintf(stdout, " -F, --pidfile <file>\t\tuse <file> as a pid file\n"); ++ fprintf(stdout, " -F, --pid-file <file>\t\tuse <file> as a pid file\n"); + fprintf(stdout, " -g, --request-uri <uri>\tURI to send updates to\n"); + fprintf(stdout, " -h, --host <host>\t\tstring to send as host parameter\n"); + fprintf(stdout, " -i, --interface <iface>\twhich interface to use\n"); diff --git a/pkgs/core/file/file.nm b/pkgs/core/file/file.nm new file mode 100644 index 0000000..a11d14a --- /dev/null +++ b/pkgs/core/file/file.nm @@ -0,0 +1,61 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = file +PKG_VER = 5.04 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Tools +PKG_URL = http://www.darwinsys.com/file/ +PKG_LICENSE = BSD +PKG_SUMMARY = A utility for determining file types. + +define PKG_DESCRIPTION + The file command is used to identify a particular file according to the \ + type of data contained by the file. File can identify many different \ + file types, including ELF binaries, system libraries, RPM packages, and \ + different graphics formats. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --disable-static + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + cd $(DIR_APP) && make check +endef diff --git a/pkgs/core/findutils/findutils.nm b/pkgs/core/findutils/findutils.nm new file mode 100644 index 0000000..4c3ed1f --- /dev/null +++ b/pkgs/core/findutils/findutils.nm @@ -0,0 +1,74 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = findutils +PKG_VER = 4.4.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Tools +PKG_URL = http://www.gnu.org/software/findutils/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = The GNU versions of find utilities (find and xargs). + +define PKG_DESCRIPTION + The findutils package contains programs which will help you locate \ + files on your system. The find utility searches through a hierarchy \ + of directories looking for files which match a certain set of criteria \ + (such as a filename pattern). The xargs utility builds and executes \ + command lines from standard input arguments (usually lists of file \ + names generated by the find command). +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --libexecdir=/usr/lib/findutils \ + --localstatedir=/var/lib/locate + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +# fails +#define STAGE_TEST +# cd $(DIR_APP) && make check +#endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/bin + mv -v $(BUILDROOT)/usr/bin/find $(BUILDROOT)/bin + + sed -i -e 's/find:=$${BINDIR}/find:=/bin/' $(BUILDROOT)/usr/bin/updatedb +endef diff --git a/pkgs/core/firewall/firewall.init b/pkgs/core/firewall/firewall.init new file mode 100644 index 0000000..8c5d893 --- /dev/null +++ b/pkgs/core/firewall/firewall.init @@ -0,0 +1,13 @@ +description "Starts the firewall" +author "IPFire Team" + +start on starting network +stop on stopped network + +pre-start script + firewall start +end script + +post-stop script + firewall stop +end script diff --git a/pkgs/core/firewall/firewall.nm b/pkgs/core/firewall/firewall.nm new file mode 100644 index 0000000..d8cdaaa --- /dev/null +++ b/pkgs/core/firewall/firewall.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = firewall +PKG_VER = +PKG_REL = 0 + +PKG_MAINTAINER = Michael Tremer <michael.tremer@ipfire.org> +PKG_GROUP = Networking/Firewall +PKG_URL = http://www.ipfire.org/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = The IPFire Firewall Engine. + +PKG_DEPS += iproute2 iptables + +define PKG_DESCRIPTION + This script installs IPFire's firewall. +endef + +DIR_APP = $(DIR_SOURCE)/src + +PKG_TARBALL = + +STAGE_PREPARE = # Do nothing +STAGE_BUILD = # Do nothing + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/usr/{lib,share}/firewall $(BUILDROOT)/usr/bin + for i in $(DIR_APP)/{functions,zones}*; do \ + install -m 644 -v $$i $(BUILDROOT)/usr/lib/firewall; \ + done + cp -avf $(DIR_APP)/macros $(BUILDROOT)/usr/share/firewall/ + install -m 755 -v $(DIR_APP)/firewall $(BUILDROOT)/usr/bin +endef diff --git a/pkgs/core/firewall/src/firewall b/pkgs/core/firewall/src/firewall new file mode 100644 index 0000000..44d0937 --- /dev/null +++ b/pkgs/core/firewall/src/firewall @@ -0,0 +1,111 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# This is the script, that is runned by the user to contol the firewall # +# We only do some actions here and call the functions from the libs. # +# # +# Actions (as known at the moment): # +# - start/stop/restart/reload # +# - show # +# - running? # +# - serveral config # +# - calc (cidr|subnets|...) # +# - ... # +# # +############################################################################### + +PATH=/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin + +LIBDIR=/usr/lib/firewall + +function include() { + local file=$1 + local path + for path in $LIBDIR .; do + if [ -f "$path/$file" ]; then + . $path/$file + return # found + fi + done + echo "Couldn't include $file. File was not found!" >&2 + _exit 1 +} + +function usage() { + echo "Usage: $0 [global options] command [command options]" + echo + _exit ${1-1} +} + +include functions + +while [ "$#" -gt 0 ]; do + arg=$1 + shift + case "$arg" in + --debug|-d) + debug 1 + decho "Debug mode is enabled." + ;; + --verbose|-v) + verbose 1 + vecho "${BOLD}Verbose mode is enabled.${NORMAL}" + ;; + calc) + shift + case "$1" in + mask2cidr) + mask_to_cidr $@ + _exit $? + ;; + *) + usage + ;; + esac + ;; + config) + config_load $@ + _exit $? + ;; + help|-h|--help) + usage 0 + ;; + notify) + ;; + reload) + ;; + start|restart) + _start + _exit $@ + ;; + stop) + _stop + _exit $@ + ;; + *) + usage + ;; + esac +done + +error "No command was given." +usage diff --git a/pkgs/core/firewall/src/functions b/pkgs/core/firewall/src/functions new file mode 100644 index 0000000..d8fb597 --- /dev/null +++ b/pkgs/core/firewall/src/functions @@ -0,0 +1,111 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +DEBUG= +VERBOSE= +TMPDIR=$(mktemp -d) + +BOLD="\033[1;39m" +NORMAL="\033[0;39m" +ERROR="\033[1;31m" + +function debug() { + if [ -n "$1" ]; then + DEBUG=$1 + verbose $1 + return + else + if [ "$DEBUG" = "1" ]; then + return 0 + else + return 1 + fi + fi + +} + +function verbose() { + if [ -n "$1" ]; then + VERBOSE=$1 + return + else + if [ "$VERBOSE" = "1" ]; then + return 0 + else + return 1 + fi + fi +} + +function decho() { + debug && echo -e "${ERROR}$@${NORMAL}" +} + +function vecho() { + verbose && echo -e "$@" +} + +function error() { + echo -e "${ERROR}ERROR${NORMAL}: $@" >&2 + _exit 1 +} + +function ifs() { + if [ -n "$1" ]; then + IFS_SAVE=$IFS + echo $1 + else + echo $IFS_SAVE + fi +} + +function uppercase() { + tr [a-z] [A-Z] <<< "$@" +} + +include functions.commands +include functions.config +include functions.firewall +include functions.ip +include functions.iptables +include functions.macros +include functions.zones + +function _start() { + local zone + local policy + + firewall_init + zones_local_add + + for zone in $(network zone list); do + zone=$(basename ${zone}) + policy=${zone%%[0-9]*} + zones_${policy}_add ${zone} + done + + iptables_commit +} + +function _stop() { + iptables_flush + iptables_commit +} diff --git a/pkgs/core/firewall/src/functions.commands b/pkgs/core/firewall/src/functions.commands new file mode 100644 index 0000000..d46a536 --- /dev/null +++ b/pkgs/core/firewall/src/functions.commands @@ -0,0 +1,29 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +function cmd_quiet() { + $@ &>/dev/null +} + +function _exit() { + rm -rf $TMPDIR + exit $@ +} diff --git a/pkgs/core/firewall/src/functions.config b/pkgs/core/firewall/src/functions.config new file mode 100644 index 0000000..8abda04 --- /dev/null +++ b/pkgs/core/firewall/src/functions.config @@ -0,0 +1,70 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +CONFIG_NONE=0 +CONFIG_TEXT=1 +CONFIG_SQLITE=2 + +function config_type() { + if _config_is_sqlite $1; then + echo $CONFIG_SQLITE + else + echo $CONFIG_TEXT + fi +} + +function config_load() { + local file + local type + file=$1 + + if ! [ -f "$file" ]; then + error "Cannot load config file $file. File does not exist!" + exit 1 + fi + + vecho "Loading config file: $file" + + type=$(config_type $file) + if [ "$type" = "$CONFIG_SQLITE" ]; then + eval $(_config_load_sqlite $file) + else + eval $(_config_load_text $file) + fi +} + +function _config_is_sqlite() { + file $1 2>/dev/null | grep -q "SQLite 3.x database" +} + +function _config_dump_sqlite() { + sqlite3 -noheader -column $1 "SELECT * FROM config;" +} + +function _config_load_sqlite() { + _config_dump_sqlite $1 | while read KEY VALUE; do + echo "$KEY=$VALUE" + done +} + +function _config_load_text() { + readhash $1 +} diff --git a/pkgs/core/firewall/src/functions.firewall b/pkgs/core/firewall/src/functions.firewall new file mode 100644 index 0000000..b98128b --- /dev/null +++ b/pkgs/core/firewall/src/functions.firewall @@ -0,0 +1,59 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +function firewall_init() { + decho "Initializing firewall interface." + iptables_init + firewall_tcp_state_flags + firewall_connection_tracking +} + +function firewall_tcp_state_flags() { + vecho "Adding ${BOLD}TCP State Flags${NORMAL} chain..." + chain_create BADTCP_LOG + iptables -A BADTCP_LOG -p tcp -j $(iptables_LOG "Illegal TCP state: ") + iptables -A BADTCP_LOG -j DROP + + chain_create BADTCP + iptables -A BADTCP -p tcp --tcp-flags ALL NONE -j BADTCP_LOG + iptables -A BADTCP -p tcp --tcp-flags SYN,FIN SYN,FIN -j BADTCP_LOG + iptables -A BADTCP -p tcp --tcp-flags SYN,RST SYN,RST -j BADTCP_LOG + iptables -A BADTCP -p tcp --tcp-flags FIN,RST FIN,RST -j BADTCP_LOG + iptables -A BADTCP -p tcp --tcp-flags ACK,FIN FIN -j BADTCP_LOG + iptables -A BADTCP -p tcp --tcp-flags ACK,PSH PSH -j BADTCP_LOG + iptables -A BADTCP -p tcp --tcp-flags ACK,URG URG -j BADTCP_LOG + + iptables -A INPUT -p tcp -j BADTCP + iptables -A OUTPUT -p tcp -j BADTCP + iptables -A FORWARD -p tcp -j BADTCP +} + +function firewall_connection_tracking() { + vecho "Adding ${BOLD}Connection Tracking${NORMAL} chain..." + chain_create CONNTRACK + iptables -A CONNTRACK -m state --state ESTABLISHED,RELATED -j ACCEPT + iptables -A CONNTRACK -m state --state INVALID -j $(iptables_LOG "INVALID packet: ") + iptables -A CONNTRACK -m state --state INVALID -j DROP + + iptables -A INPUT -p tcp -j CONNTRACK + iptables -A OUTPUT -p tcp -j CONNTRACK + iptables -A FORWARD -p tcp -j CONNTRACK +} diff --git a/pkgs/core/firewall/src/functions.ip b/pkgs/core/firewall/src/functions.ip new file mode 100644 index 0000000..78a29ac --- /dev/null +++ b/pkgs/core/firewall/src/functions.ip @@ -0,0 +1,231 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# General IP address manipulation functions +# ip_encode - Encodes an IP to an integer +# Parameters: ip address (e.g. 192.168.0.1) +# Returns : integer +# ip_decode - Decodes an integer to an IP +# Parameters: integer +# Returns : ip address +# ip_valid - Checks if given IP is valid +# Parameters: IP +# Returns : boolean +# +# General subnet functions +# ip_range - Enumerates members of an IP range +# Parameters: ip range (e.g. 192.168.0.1-192.168.0.128) +# Returns : several subnets/IPs +# ip_range_explicit - Enumerates ALL IP addresses of an IP range +# Parameters: ip range +# Returns : several IPs +# subnet_network - Calculates the network address of a CIDR +# Parameters: CIDR network (e.g. 192.168.0.0/24) +# Returns : Network address +# subnet_broadcast - Calculates the broadcast address of a CIDR +# Parameters: CIDR network +# Returns : Broadcast address +# ip_in_subnet - Checks if an IP is in given subnet +# Parameters: IP address, subnet +# Returns : Boolean +# mask_to_cidr - Converts a subnet mask to cidr type +# Parameters: subnet (e.g. 255.255.255.0) +# Returns : CIDR (e.g. 24) +# + +function ip_encode() { + IFS=$(ifs .) + + local int=0 + for field in $1; do + int=$(( $(( $int << 8 )) | $field )) + done + + echo $int + IFS=$(ifs) +} + +function ip_decode() { + addr=$1 + + local x + local y + + y=$(($addr & 255)) + for x in 1 2 3; do + addr=$(($addr >> 8)) + y=$(($addr & 255)).$y + done + + echo $y +} + +function ip_range() { + local first + local last + local l + local x + local y + local z + local vlsm + + case "$1" in + !*) + echo $1 + return + ;; + [0-9]*.*.*.*-*.*.*.*) + ;; + *) + echo $1 + return + ;; + esac + + first=$(ip_encode ${1%-*}) + last=$(ip_encode ${1#*-}) + + if [ $first -gt $last ]; then + error "Invalid IP address range: $1" + fi + + l=$(( $last + 1 )) + + while [ $l -gt $first ]; do + vlsm= + x=31 + y=2 + z=1 + + while [ $(( $first % $y )) -eq 0 ] && [ $l -gt $(( $first + $y )) ]; do + vlsm=/$x + x=$(( $x - 1 )) + z=$y + y=$(( $y * 2 )) + done + + echo $(ip_decode $first)$vlsm + first=$(($first + $z)) + done +} + +function ip_range_explicit() { + local first + local last + + case $1 in + [0-9]*.*.*.*-*.*.*.*) + ;; + *) + echo $1 + return + ;; + esac + + first=$(ip_encode ${1%-*}) + last=$(ip_encode ${1#*-}) + + if [ $first -gt $last ]; then + error "Invalid IP address range: $1" + fi + + while ! [ $first -gt $last ]; do + echo $(ip_decode $first) + first=$(($first + 1)) + done +} + +function _netmask() { + local vlsm + vlsm=${1#*/} + [ $vlsm -eq 0 ] && echo 0 || echo $(( -1 << $(( 32 - $vlsm )) )) +} + +function subnet_network() { + local encodedaddr + encodedaddr=$(ip_encode ${1%/*}) + local netmask + netmask=$(_netmask $1) + + echo $(ip_decode $(($encodedaddr & $netmask))) +} + +function _broadcast() { + local x + x=$(( 32 - ${1#*/} )) + [ $x -eq 32 ] && echo -1 || echo $(( $(( 1 << $x )) - 1 )) +} + +function subnet_broadcast() { + local encodedaddr + encodedaddr=$(ip_encode ${1%/*}) + local netmask + netmask=$(_netmask $1) + local broadcast + broadcast=$(_broadcast $1) + + echo $(ip_decode $(( $(($encodedaddr & $netmask)) | $broadcast ))) +} + +function ip_in_subnet() { + local netmask + netmask=$(_netmask $2) + [ $(( $(ip_encode $1) & $netmask)) = $(( $(ip_encode ${2%/*}) & $netmask )) ] +} + +function mask_to_cidr() { + local mask + mask=$(ip_encode $1) + local cidr + cidr=0 + local x + x=$(( 128 << 24 )) # 0x80000000 + + while [ $(( $x & $mask )) -ne 0 ]; do + [ $mask -eq $x ] && mask=0 || mask=$(( $mask << 1 )) + cidr=$(($cidr + 1)) + done + + if [ $(( $mask & 2147483647 )) -ne 0 ]; then # 2147483647 = 0x7fffffff + echo "Invalid net mask: $1" >&2 + else + echo $cidr + fi +} + +function ip_valid() { + local x + IFS=$(ifs .) + for x in $1; do + case $x in + [0-9]|[0-9][0-9]|[1-2][0-9][0-9]) + [ $x -lt 256 ] || { IFS=$(ifs); return 1; } + ;; + *) + IFS=$(ifs) + return 1 + ;; + esac + done + IFS=$(ifs) + return 0 +} diff --git a/pkgs/core/firewall/src/functions.iptables b/pkgs/core/firewall/src/functions.iptables new file mode 100644 index 0000000..630bcce --- /dev/null +++ b/pkgs/core/firewall/src/functions.iptables @@ -0,0 +1,181 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +IPTABLES_FILE=$TMPDIR/iptables + +function iptables() { + local arg + local args + local table + + table=filter + + # Parsing arguments + while [ $# -gt 0 ]; do + arg=${1} + shift + case "${arg}" in + -t) + table=${1} + shift + ;; + -A) + args="${args} -A $(uppercase ${1})" + shift + ;; + *) + args="${args} ${arg}" + ;; + esac + done + echo "${args:1:${#args}}" >> ${IPTABLES_FILE}-${table} +} + +function iptables_flush() { + decho "Flushing iptables" + iptables "* filter" + chain_create INPUT ACCEPT + chain_create OUTPUT ACCEPT + chain_create FORWARD ACCEPT +} + +function iptables_init() { + iptables "* filter" + chain_create -t filter INPUT DROP + chain_create -t filter OUTPUT DROP + chain_create -t filter FORWARD DROP + + iptables -t mangle "* mangle" + chain_create -t mangle PREROUTING ACCEPT + chain_create -t mangle INPUT ACCEPT + chain_create -t mangle OUTPUT ACCEPT + chain_create -t mangle FORWARD ACCEPT + chain_create -t mangle POSTROUTING ACCEPT + + iptables -t nat "* nat" + chain_create -t nat PREROUTING ACCEPT + chain_create -t nat OUTPUT ACCEPT + chain_create -t nat POSTROUTING ACCEPT +} + +function iptables_commit() { + local chain + + vecho "Committing firewall configuration." + iptables -t filter "COMMIT" + iptables -t mangle "COMMIT" + iptables -t nat "COMMIT" + + for table in filter mangle nat; do + [ -e ${IPTABLES_FILE}-${table} ] || continue + cat ${IPTABLES_FILE}-${table} >> $IPTABLES_FILE + done + + decho "Dumping iptables output" + if debug; then + counter=1 + cat $IPTABLES_FILE | while read LINE; do + printf "%4d | %s\n" "$counter" "$LINE" + counter=$(( $counter + 1 )) + done + fi + + iptables-restore $(debug && echo "-v") < $IPTABLES_FILE +} + +function chain_create() { + local args + if [ "${1}" = "-t" ]; then + args="${1} ${2}" + shift 2 + fi + iptables ${args} ":$1 ${2--} [0:0]" +} + +function iptables_LOG() { + local prefix + prefix=$1 + + if [ "$LOG_FACILITY" = "syslog" ]; then + echo -n "LOG" + [ -n "$prefix" ] && echo -n " --log-prefix "$prefix"" + else + echo -n "NFLOG" + [ -n "$prefix" ] && echo -n " --nflog-prefix "$prefix"" + echo -n " --nflog-threshold 30" + fi + echo +} + +function iptables_protocol() { + local PROTO + PROTO=$1 + for proto in tcp udp esp ah; do + if [ "$PROTO" = "$proto" ]; then + echo "-p $PROTO" + break + fi + done +} + +IPTABLES_PORT=0 +IPTABLES_MULTIPORT=1 +IPTABLES_PORTRANGE=2 + +function _iptables_port_range() { + grep -q ":" <<< $@ +} + +function _iptables_port_multiport() { + grep -q "," <<< $@ +} + +function _iptables_port() { + if _iptables_port_range "$@"; then + echo $IPTABLES_PORTRANGE + elif _iptables_port_multiport "$@"; then + echo $IPTABLES_MULTIPORT + else + echo $IPTABLES_PORT + fi +} + +function iptables_source_port() { + [ -z "$@" ] && return + local type + type=$(_iptables_port $@) + if [ "$type" = "$IPTABLES_MULTIPORT" ]; then + echo "-m multiport --source-ports $@" + else + echo "--sport $@" + fi +} + +function iptables_destination_port() { + [ -z "$@" ] && return + local type + type=$(_iptables_port $@) + if [ "$type" = "$IPTABLES_MULTIPORT" ]; then + echo "-m multiport --destination-ports $@" + else + echo "--dport $@" + fi +} diff --git a/pkgs/core/firewall/src/functions.macros b/pkgs/core/firewall/src/functions.macros new file mode 100644 index 0000000..2ea6f37 --- /dev/null +++ b/pkgs/core/firewall/src/functions.macros @@ -0,0 +1,75 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +function macro() { + local file + local line + local rules + + file=$1 + if [ "${file:0:1}" != "/" ]; then + file="/usr/share/firewall/macros/$file" + fi + shift + + if _config_is_sqlite $file; then + rules=$(macro_parse $@ < $file) + else + rules=$(sqlite3 -noheader -column $file | macro_parse $@) + fi + + while read line <<< ${rules}; do + iptables ${line} + done +} + +function macro_parse() { + local STRING + grep -v "^#" | while read ACTION SOURCE DESTINATION PROTOCOL LOCAL_PORT REMOTE_PORT RATE; do + STRING="" + + # Handle inlcudes + if [ "$ACTION" = "INCLUDE" ]; then + marco $SOURCE $@ + fi + + # Protocol + STRING="$STRING $(iptables_protocol $PROTOCOL)" + # Ports + if [ -n "$PORT_SWITCH" ]; then + # Switch ports for upload rule + STRING="$STRING $(iptables_source_port $REMOTE_PORT)" + STRING="$STRING $(iptables_destination_port $LOCAL_PORT)" + else + STRING="$STRING $(iptables_source_port $LOCAL_PORT)" + STRING="$STRING $(iptables_destination_port $REMOTE_PORT)" + fi + + if [ "$ACTION" = "ACCEPT" ]; then + STRING="$STRING -j ACCEPT" + + elif [ "$ACTION" = "DROP" ]; then + STRING="$STRING -j DROP" + + fi + [ -n "$STRING" ] && echo "$STRING $@" + done +} diff --git a/pkgs/core/firewall/src/functions.zones b/pkgs/core/firewall/src/functions.zones new file mode 100644 index 0000000..5528b49 --- /dev/null +++ b/pkgs/core/firewall/src/functions.zones @@ -0,0 +1,103 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +include zones.blue +include zones.green +include zones.orange +include zones.red + +function zones_global_add() { + local device + local name + + device=$1 + + vecho "Adding zone "$device"" + + name=$(uppercase "ZONE_$device") + + ### FILTER + chain_create $name + iptables -A INPUT -i $device -j $name + iptables -A FORWARD -i $device -j $name + iptables -A FORWARD -o $device -j $name + iptables -A OUTPUT -o $device -j $name + + # Leave some space for own rules + chain_create ${name}_CUSTOM + iptables -A $name -j ${name}_CUSTOM + + # Intrusion Preventions System + chain_create ${name}_IPS + iptables -A $name -i $device -j ${name}_IPS + + # Portforwarding + chain_create ${name}_PORTFW + iptables -A $name -i $device -j ${name}_PORTFW + + # Outgoing firewall + chain_create ${name}_OUTFW + iptables -A $name -o $device -j ${name}_OUTFW + + # Policy rules + chain_create ${name}_POLICY + iptables -A $name -j ${name}_POLICY + + ### MANGLE + chain_create -t mangle $name + iptables -t mangle -A PREROUTING -i $device -j $name + iptables -t mangle -A POSTROUTING -o $device -j $name + + # Quality of Service + chain_create -t mangle ${name}_QOS_INC + iptables -t mangle -A $name -i $device -j ${name}_QOS_INC + chain_create -t mangle ${name}_QOS_OUT + iptables -t mangle -A $name -o $device -j ${name}_QOS_OUT + + ### NAT + chain_create -t nat ${name} + iptables -t nat -A PREROUTING -i $device -j ${name} + iptables -t nat -A POSTROUTING -o $device -j ${name} + + # Network Address Translation + chain_create -t nat ${name}_NAT + iptables -t nat -A $name -i $device -j ${name}_NAT + + # Portforwarding + chain_create -t nat ${name}_PORTFW + iptables -t nat -A $name -i $device -j ${name}_PORTFW + + # UPNP + chain_create -t nat ${name}_UPNP + iptables -t nat -A $name -j ${name}_UPNP +} + + +### LOCAL ZONE +function zones_local_add() { + + decho "Adding zone "local"" + + # Accept everything on lo + iptables -A INPUT -i lo -j ACCEPT + iptables -A OUTPUT -o lo -j ACCEPT + +} diff --git a/pkgs/core/firewall/src/macros/DHCP b/pkgs/core/firewall/src/macros/DHCP new file mode 100644 index 0000000..41d8a87 --- /dev/null +++ b/pkgs/core/firewall/src/macros/DHCP @@ -0,0 +1,5 @@ +# IPFire Macro +# This macro handles the dynamic host configuration protocol. +# ACTION SRC DST PROTO LOCAL_PORT REMOTE_PORT RATE +CUSTOM - - tcp 68 67 +CUSTOM - - udp 68 67 diff --git a/pkgs/core/firewall/src/macros/HTTP b/pkgs/core/firewall/src/macros/HTTP new file mode 100644 index 0000000..bce11f9 --- /dev/null +++ b/pkgs/core/firewall/src/macros/HTTP @@ -0,0 +1,4 @@ +# IPFire Macro +# This macro handles plaintext HTTP (WWW) traffic. +# ACTION SRC DST PROTO LOCAL_PORT REMOTE_PORT RATE +CUSTOM - - tcp - 80 diff --git a/pkgs/core/firewall/src/macros/HTTPS b/pkgs/core/firewall/src/macros/HTTPS new file mode 100644 index 0000000..65b2e9e --- /dev/null +++ b/pkgs/core/firewall/src/macros/HTTPS @@ -0,0 +1,4 @@ +# IPFire Macro +# This macro handles secure HTTP (WWW) traffic. +# ACTION SRC DST PROTO LOCAL_PORT REMOTE_PORT RATE +CUSTOM - - tcp - 443 diff --git a/pkgs/core/firewall/src/macros/WWW b/pkgs/core/firewall/src/macros/WWW new file mode 100644 index 0000000..ca72d0f --- /dev/null +++ b/pkgs/core/firewall/src/macros/WWW @@ -0,0 +1,5 @@ +# IPFire Macro +# This macro handles WWW traffic. +# ACTION SRC DST PROTO SRC_PORT DST_PORT RATE +INCLUDE HTTP +INCLUDE HTTPS diff --git a/pkgs/core/firewall/src/zones.blue b/pkgs/core/firewall/src/zones.blue new file mode 100644 index 0000000..e9823a5 --- /dev/null +++ b/pkgs/core/firewall/src/zones.blue @@ -0,0 +1,42 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +function zones_blue_add() { + # $1 = device + + zones_global_add $1 + zones_policy_blue $1 + +} + +function zones_policy_blue() { + local device + local name + + device=$1 + name=$(uppercase "$device") + + # Accept dhcp traffic + #macro DHCP -A ZONE_${name}_POLICY -i ${device} -j ACCEPT + + # Mac filter + : # TODO +} diff --git a/pkgs/core/firewall/src/zones.green b/pkgs/core/firewall/src/zones.green new file mode 100644 index 0000000..5566587 --- /dev/null +++ b/pkgs/core/firewall/src/zones.green @@ -0,0 +1,38 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +function zones_green_add() { + # $1 = device + + zones_global_add $1 + zones_policy_green $1 + +} + +function zones_policy_green() { + local device + + device=$1 + + # Accept any traffic from green + iptables -A ZONE_${device}_POLICY -i $device -j ACCEPT + iptables -A ZONE_${device}_POLICY -o $device -j ACCEPT +} diff --git a/pkgs/core/firewall/src/zones.orange b/pkgs/core/firewall/src/zones.orange new file mode 100644 index 0000000..55f5acc --- /dev/null +++ b/pkgs/core/firewall/src/zones.orange @@ -0,0 +1,38 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +function zones_orange_add() { + # $1 = device + + zones_global_add $1 + zones_policy_orange $1 + +} + +function zones_policy_orange() { + local device + local name + + device=$1 + name=$(uppercase "$device") + + : # TODO +} diff --git a/pkgs/core/firewall/src/zones.red b/pkgs/core/firewall/src/zones.red new file mode 100644 index 0000000..549300c --- /dev/null +++ b/pkgs/core/firewall/src/zones.red @@ -0,0 +1,38 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +function zones_red_add() { + # $1 = device + + zones_global_add $1 + zones_policy_red $1 + +} + +function zones_policy_red() { + local device + local name + + device=$1 + name=$(uppercase "$device") + + : # TODO +} diff --git a/pkgs/core/flex/flex.nm b/pkgs/core/flex/flex.nm new file mode 100644 index 0000000..ee12293 --- /dev/null +++ b/pkgs/core/flex/flex.nm @@ -0,0 +1,65 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = flex +PKG_VER = 2.5.35 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://flex.sourceforge.net/ +PKG_LICENSE = BSD +PKG_SUMMARY = A tool for creating scanners (text pattern recognizers). + +PKG_BUILD_DEPS+= bison +PKG_DEPS += m4 + +define PKG_DESCRIPTION + The flex program generates scanners. Scanners are programs which can \ + recognize lexical patterns in text. Flex takes pairs of regular \ + expressions and C code as input and generates a C source file as \ + output. The output file is compiled and linked with a library to \ + produce an executable. The executable searches through its input for \ + occurrences of the regular expressions. When a match is found, it \ + executes the corresponding C code. Flex was designed to work with \ + both Yacc and Bison, and is used by many programs as part of their \ + build process. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --mandir=/usr/share/man + +define STAGE_TEST + cd $(DIR_APP) && make check +endef + +define STAGE_INSTALL_CMDS + echo "#!/bin/sh" > $(BUILDROOT)/usr/bin/lex + echo "exec /usr/bin/flex -l "$$@"" >> $(BUILDROOT)/usr/bin/lex + chmod 755 $(BUILDROOT)/usr/bin/lex +endef diff --git a/pkgs/core/flex/patches/flex-2.5.35-gcc44-1.patch b/pkgs/core/flex/patches/flex-2.5.35-gcc44-1.patch new file mode 100644 index 0000000..8f0e80f --- /dev/null +++ b/pkgs/core/flex/patches/flex-2.5.35-gcc44-1.patch @@ -0,0 +1,24 @@ +Submitted by: Matt Burgess (matthew at linuxfromscratch dot org) +Date: 2009-05-03 +Initial Package Version: 2.5.35 +Origin: Matt Burgess +Upstream Status: Submitted (attached to sourceforge bug 2178663) +Description: Fixes an error caused by header cleanups in GCC 4.4.0 that is + evident from the test suite and would affect any C++ lexers + generated by Flex. Without this patch, Flex will generate lexers + containing references to the 'EOF' symbol without including the + necessary C++ header file, leading to: + + error: 'EOF' was not declared in this scope + +diff -Naur flex-2.5.35.orig/skel.c flex-2.5.35/skel.c +--- flex-2.5.35.orig/skel.c 2008-02-26 21:34:19.000000000 +0000 ++++ flex-2.5.35/skel.c 2009-05-03 15:18:14.000000000 +0000 +@@ -284,6 +284,7 @@ + "/* begin standard C++ headers. */", + "#include <iostream> ", + "#include <errno.h>", ++ "#include <cstdio>", + "#include <cstdlib>", + "#include <cstring>", + "/* end standard C++ headers. */", diff --git a/pkgs/core/fontconfig/fontconfig.nm b/pkgs/core/fontconfig/fontconfig.nm new file mode 100644 index 0000000..4beacc0 --- /dev/null +++ b/pkgs/core/fontconfig/fontconfig.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = fontconfig +PKG_VER = 2.7.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Graphics +PKG_URL = http://fontconfig.org/ +PKG_LICENSE = MIT +PKG_SUMMARY = Font configuration and customization library. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += freetype libxml2 + +define PKG_DESCRIPTION + Fontconfig is designed to locate fonts within the \ + system and select them according to requirements specified by \ + applications. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --enable-libxml2 diff --git a/pkgs/core/freeradius/freeradius.init b/pkgs/core/freeradius/freeradius.init new file mode 100644 index 0000000..a89f62c --- /dev/null +++ b/pkgs/core/freeradius/freeradius.init @@ -0,0 +1,12 @@ +description "Starts the free RADIUS server" +author "IPFire Team" + +start on started network +stop on starting shutdown + +exec /usr/sbin/radiusd -f +respawn + +post-stop script + rm -vf /var/run/radiusd/radiusd.sock +end script diff --git a/pkgs/core/freeradius/freeradius.nm b/pkgs/core/freeradius/freeradius.nm new file mode 100644 index 0000000..8e94125 --- /dev/null +++ b/pkgs/core/freeradius/freeradius.nm @@ -0,0 +1,85 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = freeradius-server +PKG_VER = 2.1.6 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Daemons +PKG_URL = http://www.freeradius.org +PKG_LICENSE = GPLv2+ and LGPLv2+ +PKG_SUMMARY = High-performance and highly configurable free RADIUS server. + +PKG_BUILD_DEPS+= libtool +PKG_DEPS += gdbm libpcap openssl perl + +define PKG_DESCRIPTION + The FreeRADIUS Server Project is a high performance and highly \ + configurable GPL'd free RADIUS server. \ + FreeRADIUS is an Internet authentication daemon, which implements \ + the RADIUS protocol, as defined in RFC 2865. It allows \ + Network Access Servers to perform authentication for dial-up users. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +define QUALITY_AGENT_WHITELIST_RPATH + /usr/bin/* + /usr/sbin/* + /usr/lib/freeradius/* +endef + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + $(CONFIGURE_ARCH) \ + --prefix=/usr \ + --sysconfdir=/etc \ + --libdir=/usr/lib/freeradius \ + --localstatedir=/var \ + --with-system-libtool \ + --with-threads \ + --with-thread-pool \ + --disable-ltdl-install \ + --with-gnu-ld \ + --without-rlm_eap_ikev2 \ + --without-rlm_sql_iodbc \ + --without-rlm_sql_firebird \ + --without-rlm_sql_db2 \ + --without-rlm_sql_oracle + + cd $(DIR_APP) && make LIBTOOL="libtool --tag=CC" #$(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && R=$(BUILDROOT) make install +endef + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/etc/logrotate.d/ + cp -vf $(DIR_SOURCE)/logrotate/freeradius $(BUILDROOT)/etc/logrotate.d/ +endef diff --git a/pkgs/core/freeradius/freeradius.pam b/pkgs/core/freeradius/freeradius.pam new file mode 100644 index 0000000..fff3238 --- /dev/null +++ b/pkgs/core/freeradius/freeradius.pam @@ -0,0 +1,6 @@ +#%PAM-1.0 +auth include system-auth +account required pam_nologin.so +account include system-auth +password include system-auth +session include system-auth diff --git a/pkgs/core/freeradius/logrotate/freeradius b/pkgs/core/freeradius/logrotate/freeradius new file mode 100644 index 0000000..8c5c6fb --- /dev/null +++ b/pkgs/core/freeradius/logrotate/freeradius @@ -0,0 +1,56 @@ +# You can use this to rotate the /var/log/radius/* files, simply copy +# it to /etc/logrotate.d/radiusd + +# There are different detail-rotating strategies you can use. One is +# to write to a single detail file per IP and use the rotate config +# below. Another is to write to a daily detail file per IP with: +# detailfile = ${radacctdir}/%{Client-IP-Address}/%Y%m%d-detail +# (or similar) in radiusd.conf, without rotation. If you go with the +# second technique, you will need another cron job that removes old +# detail files. You do not need to comment out the below for method #2. +/var/log/radius/radacct/*/detail { + monthly + rotate 4 + nocreate + missingok + compress +} + +/var/log/radius/checkrad.log { + monthly + rotate 4 + create + missingok + compress +} + +/var/log/radius/radius.log { + monthly + rotate 4 + create + missingok + compress +} + +/var/log/radius/radutmp { + monthly + rotate 4 + create + compress + missingok +} + +/var/log/radius/radwtmp { + monthly + rotate 4 + create + compress + missingok +} +/var/log/radius/sqltrace.sql { + monthly + rotate 4 + create + compress + missingok +} diff --git a/pkgs/core/freeradius/patches/freeradius-2.1.6-cert-config.patch b/pkgs/core/freeradius/patches/freeradius-2.1.6-cert-config.patch new file mode 100644 index 0000000..8390beb --- /dev/null +++ b/pkgs/core/freeradius/patches/freeradius-2.1.6-cert-config.patch @@ -0,0 +1,68 @@ +diff -r -u freeradius-server-2.1.8.orig/raddb/certs/ca.cnf freeradius-server-2.1.8/raddb/certs/ca.cnf +--- freeradius-server-2.1.8.orig/raddb/certs/ca.cnf 2009-12-30 10:44:35.000000000 -0500 ++++ freeradius-server-2.1.8/raddb/certs/ca.cnf 2010-01-08 12:35:23.000000000 -0500 +@@ -14,9 +14,9 @@ + RANDFILE = $dir/.rand + name_opt = ca_default + cert_opt = ca_default +-default_days = 365 ++default_days = 60 + default_crl_days = 30 +-default_md = md5 ++default_md = sha1 + preserve = no + policy = policy_match + +Only in freeradius-server-2.1.8/raddb/certs: ca.cnf~ +diff -r -u freeradius-server-2.1.8.orig/raddb/certs/client.cnf freeradius-server-2.1.8/raddb/certs/client.cnf +--- freeradius-server-2.1.8.orig/raddb/certs/client.cnf 2009-12-30 10:44:35.000000000 -0500 ++++ freeradius-server-2.1.8/raddb/certs/client.cnf 2010-01-08 12:35:37.000000000 -0500 +@@ -14,9 +14,9 @@ + RANDFILE = $dir/.rand + name_opt = ca_default + cert_opt = ca_default +-default_days = 365 ++default_days = 60 + default_crl_days = 30 +-default_md = md5 ++default_md = sha1 + preserve = no + policy = policy_match + +Only in freeradius-server-2.1.8/raddb/certs: client.cnf~ +diff -r -u freeradius-server-2.1.8.orig/raddb/certs/server.cnf freeradius-server-2.1.8/raddb/certs/server.cnf +--- freeradius-server-2.1.8.orig/raddb/certs/server.cnf 2009-12-30 10:44:35.000000000 -0500 ++++ freeradius-server-2.1.8/raddb/certs/server.cnf 2010-01-08 12:35:05.000000000 -0500 +@@ -14,9 +14,9 @@ + RANDFILE = $dir/.rand + name_opt = ca_default + cert_opt = ca_default +-default_days = 365 ++default_days = 60 + default_crl_days = 30 +-default_md = md5 ++default_md = sha1 + preserve = no + policy = policy_match + +Only in freeradius-server-2.1.8/raddb/certs: server.cnf~ +diff -r -u freeradius-server-2.1.8.orig/raddb/eap.conf freeradius-server-2.1.8/raddb/eap.conf +--- freeradius-server-2.1.8.orig/raddb/eap.conf 2009-12-30 10:44:35.000000000 -0500 ++++ freeradius-server-2.1.8/raddb/eap.conf 2010-01-08 12:36:04.000000000 -0500 +@@ -251,15 +251,6 @@ + cipher_list = "DEFAULT" + + # +- +- # This configuration entry should be deleted +- # once the server is running in a normal +- # configuration. It is here ONLY to make +- # initial deployments easier. +- # +- make_cert_command = "${certdir}/bootstrap" +- +- # + # Session resumption / fast reauthentication + # cache. + # +Only in freeradius-server-2.1.8/raddb: eap.conf~ diff --git a/pkgs/core/freetype/freetype.nm b/pkgs/core/freetype/freetype.nm new file mode 100644 index 0000000..3c39f80 --- /dev/null +++ b/pkgs/core/freetype/freetype.nm @@ -0,0 +1,55 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = freetype +PKG_VER = 2.3.9 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Graphics +PKG_URL = http://www.freetype.org/ +PKG_LICENSE = FTL GPLv2+ +PKG_SUMMARY = A free and portable font rendering engine. + +PKG_DEPS += zlib + +define PKG_DESCRIPTION + The FreeType engine is a free and portable font rendering \ + engine, developed to provide advanced font support for a variety of \ + platforms and environments. FreeType is a library which can open and \ + manages font files as well as efficiently load, hint and render \ + individual glyphs. FreeType is not a font server or a complete \ + text-rendering library. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && \ + sed -i -r -e 's:.*(#.*BYTE.*) .*:\1:' \ + -e 's:.*(#.*SUBPIX.*) .*:\1:' \ + include/freetype/config/ftoption.h +endef diff --git a/pkgs/core/fuse/fuse.nm b/pkgs/core/fuse/fuse.nm new file mode 100644 index 0000000..22f5b7f --- /dev/null +++ b/pkgs/core/fuse/fuse.nm @@ -0,0 +1,50 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = fuse +PKG_VER = 2.7.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://fuse.sf.net/ +PKG_LICENSE = GPL+ +PKG_SUMMARY = File System in Userspace (FUSE) utilities. + +define PKG_DESCRIPTION + With FUSE it is possible to implement a fully functional \ + filesystem in a userspace program. This package contains the \ + FUSE userspace tools to mount a FUSE filesystem. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --disable-kernel-module + +define STAGE_INSTALL_CMDS + rm -vrf $(BUILDROOT)/etc/init.d +endef diff --git a/pkgs/core/fuse/patches/fuse-2.7.4-openfix.patch b/pkgs/core/fuse/patches/fuse-2.7.4-openfix.patch new file mode 100644 index 0000000..e5b9eae --- /dev/null +++ b/pkgs/core/fuse/patches/fuse-2.7.4-openfix.patch @@ -0,0 +1,36 @@ +diff -up fuse-2.7.2/lib/fuse.c.BAD fuse-2.7.2/lib/fuse.c +--- a/lib/fuse.c 2008-01-21 09:55:42.000000000 -0500 ++++ b/lib/fuse.c 2008-01-21 09:57:20.000000000 -0500 +@@ -633,17 +633,15 @@ static int fuse_compat_open(struct fuse_ + { + int err; + if (!fs->compat || fs->compat >= 25) +- err = fs->op.open(path, fi); ++ err = (fs->op.open)(path, fi); + else if (fs->compat == 22) { + struct fuse_file_info_compat tmp; + memcpy(&tmp, fi, sizeof(tmp)); +- err = ((struct fuse_operations_compat22 *) &fs->op)->open(path, +- &tmp); ++ err = (((struct fuse_operations_compat22 *) &fs->op)->open)(path, &tmp); + memcpy(fi, &tmp, sizeof(tmp)); + fi->fh = tmp.fh; + } else +- err = ((struct fuse_operations_compat2 *) &fs->op) +- ->open(path, fi->flags); ++ err = (((struct fuse_operations_compat2 *) &fs->op)->open)(path, fi->flags); + return err; + } + +diff -up fuse-2.7.2/lib/fuse_lowlevel.c.BAD fuse-2.7.2/lib/fuse_lowlevel.c +--- a/lib/fuse_lowlevel.c 2008-01-21 09:57:52.000000000 -0500 ++++ b/lib/fuse_lowlevel.c 2008-01-21 09:58:15.000000000 -0500 +@@ -605,7 +605,7 @@ static void do_open(fuse_req_t req, fuse + fi.flags = arg->flags; + + if (req->f->op.open) +- req->f->op.open(req, nodeid, &fi); ++ (req->f->op.open)(req, nodeid, &fi); + else + fuse_reply_open(req, &fi); + } diff --git a/pkgs/core/fuse/patches/fuse-2.7.4-udev_rules.patch b/pkgs/core/fuse/patches/fuse-2.7.4-udev_rules.patch new file mode 100644 index 0000000..d52fc32 --- /dev/null +++ b/pkgs/core/fuse/patches/fuse-2.7.4-udev_rules.patch @@ -0,0 +1,5 @@ +--- a/util/udev.rules 2005-11-03 19:38:05.000000000 +0100 ++++ b/util/udev.rules 2005-11-03 19:38:13.000000000 +0100 +@@ -1 +1 @@ +-KERNEL=="fuse", MODE="0666" ++KERNEL=="fuse", NAME="%k", MODE="0666",OWNER="root",GROUP="root" diff --git a/pkgs/core/gawk/gawk.nm b/pkgs/core/gawk/gawk.nm new file mode 100644 index 0000000..2e851b8 --- /dev/null +++ b/pkgs/core/gawk/gawk.nm @@ -0,0 +1,64 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gawk +PKG_VER = 3.1.7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Tools +PKG_URL = http://www.gnu.org/software/gawk/gawk.html +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = The GNU version of the awk text processing utility. + +define PKG_DESCRIPTION + The gawk package contains the GNU version of awk, a text processing \ + utility. Awk interprets a special-purpose programming language to do \ + quick and easy text pattern matching and reformatting jobs. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ac_cv_func_working_mktime=yes \ + ./configure \ + --prefix=/usr \ + --libexecdir=/usr/lib + + cd $(DIR_APP) && echo "#define HAVE_LANGINFO_CODESET 1" >> config.h + cd $(DIR_APP) && echo "#define HAVE_LC_MESSAGES 1" >> config.h + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + cd $(DIR_APP) && make check +endef diff --git a/pkgs/core/gcc/gcc.nm b/pkgs/core/gcc/gcc.nm new file mode 100644 index 0000000..471f908 --- /dev/null +++ b/pkgs/core/gcc/gcc.nm @@ -0,0 +1,129 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gcc +PKG_VER = 4.4.3 +PKG_REL = 0 + +PKG_MAINTAINER = Michael Tremer <michael.tremer@ipfire.org> +PKG_GROUP = Development/Compilers +PKG_URL = http://gcc.gnu.org/ +PKG_LICENSE = GPLv3+ and GPLv2+ with exceptions +PKG_SUMMARY = Various compilers (C, C++, Objective-C, Java, ...). + +define PKG_DESCRIPTION + The gcc package contains the GNU Compiler Collection. \ + You'll need this package in order to compile C code. +endef + +PKG_BUILD_DEPS = +PKG_DEPS += binutils glibc gmp kernel-headers mpfr + +CFLAGS = -D__USE_XOPEN2K8 -pipe +CXXFLAGS = + +ifeq "$(MACHINE)" "i586" + CONFIGURE_ARGS = --disable-decimal-float +endif + +ifeq "$(MACHINE)" "x86_64" + CONFIGURE_ARGS = --without-cloog --without-ppl --disable-multilib +else + CONFIG_CPU = --with-cpu=$(TARGET_MACHINE) --with-arch=$(TARGET_MACHINE) +endif + +PKG_TARBALL += $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + -mkdir -v $(DIR_SRC)/gcc-build + + # Remove unneeded features that will save some compile time + rm -rf $(DIR_APP)/lib{gfortran,java,objc} \ + $(DIR_APP)/gcc/{fortran,java,objc,objcp} + + # Apply a sed substitution that will suppress the installation of + # libiberty.a. The version of libiberty.a provided by Binutils will be used + # instead: + cd $(DIR_APP) && sed -i 's/install_to_$$(INSTALL_DEST) //' libiberty/Makefile.in + + # Branding gcc + cd $(DIR_APP) && sed -e "s:PKGVERSION:"(GCC for $(DISTRO_NAME)-$(DISTRO_VERSION)) ":" \ + -i gcc/version.c + + # Libgomp uses -Werror regardless of --disable-werror, and this will cause a + # build failure when -D_FORTIFY_SOURCE=2 causes build time warnings: + cd $(DIR_APP) && sed -e "s/-Werror//" -i libgomp/configure + + # Apply the following sed to force the build to use the -fomit-frame-pointer + # compiler flag in order to ensure consistent compiler builds: + cd $(DIR_APP) && sed -i 's/^T_CFLAGS =$$/& -fomit-frame-pointer/' gcc/Makefile.in + + # The fixincludes script is known to occasionally erroneously attempt to + # "fix" the system headers installed so far. As the headers up to this point + # are known to not require fixing, issue the following command to prevent + # the fixincludes script from running: + cd $(DIR_APP) && sed -i 's@./fixinc.sh@-c true@' gcc/Makefile.in +endef + +define STAGE_BUILD + cd $(DIR_SRC)/gcc-build && \ + ../$(THISAPP)/configure \ + $(CONFIG_CPU) \ + --prefix=/usr \ + --libexecdir=/usr/lib \ + --mandir=/usr/share/man \ + --enable-espf \ + --enable-shared \ + --enable-threads=posix \ + --enable-__cxa_atexit \ + --enable-clocale=gnu \ + --enable-languages=c,c++ \ + --disable-bootstrap \ + --disable-werror \ + --disable-libssp \ + --disable-static \ + $(CONFIGURE_ARGS) + + cd $(DIR_SRC)/gcc-build && make $(PARALLELISMFLAGS) +endef + +# Requires dejagnu +#define STAGE_TEST +# cd $(DIR_SRC)/gcc-build && make -k check +# cd $(DIR_APP) && ./contrib/test_summary +#endef + +define STAGE_INSTALL + cd $(DIR_SRC)/gcc-build && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/lib + ln -sfv ../usr/bin/cpp $(BUILDROOT)/lib/cpp + ln -sfv gcc $(BUILDROOT)/usr/bin/cc +endef diff --git a/pkgs/core/gcc/patches/gcc-4.4-optimize_linking.patch b/pkgs/core/gcc/patches/gcc-4.4-optimize_linking.patch new file mode 100644 index 0000000..659586d --- /dev/null +++ b/pkgs/core/gcc/patches/gcc-4.4-optimize_linking.patch @@ -0,0 +1,24 @@ +diff -Naur gcc-4.4-20100216.orig/gcc/config/i386/linux.h gcc-4.4-20100216/gcc/config/i386/linux.h +--- gcc-4.4-20100216.orig/gcc/config/i386/linux.h 2010-02-26 17:44:46.000000000 +0000 ++++ gcc-4.4-20100216/gcc/config/i386/linux.h 2010-02-26 17:46:55.000000000 +0000 +@@ -113,7 +113,7 @@ + { "dynamic_linker", LINUX_DYNAMIC_LINKER } + + #undef LINK_SPEC +-#define LINK_SPEC "-m %(link_emulation) %{shared:-shared} \ ++#define LINK_SPEC "-m %(link_emulation) %{shared:-shared} --hash-style=gnu -O1 \ + %{!shared: \ + %{!ibcs: \ + %{!static: \ +diff -Naur gcc-4.4-20100216.orig/gcc/config/i386/linux64.h gcc-4.4-20100216/gcc/config/i386/linux64.h +--- gcc-4.4-20100216.orig/gcc/config/i386/linux64.h 2010-02-26 17:44:46.000000000 +0000 ++++ gcc-4.4-20100216/gcc/config/i386/linux64.h 2010-02-26 17:47:47.000000000 +0000 +@@ -75,7 +75,7 @@ + #endif + + #undef LINK_SPEC +-#define LINK_SPEC "%{" SPEC_64 ":-m elf_x86_64} %{" SPEC_32 ":-m elf_i386} \ ++#define LINK_SPEC "%{" SPEC_64 ":-m elf_x86_64} %{" SPEC_32 ":-m elf_i386} --hash-style=gnu -O1 \ + %{shared:-shared} \ + %{!shared: \ + %{!static: \ diff --git a/pkgs/core/gcc/patches/gcc-4.4.1-asprintf_fix.patch b/pkgs/core/gcc/patches/gcc-4.4.1-asprintf_fix.patch new file mode 100644 index 0000000..7704430 --- /dev/null +++ b/pkgs/core/gcc/patches/gcc-4.4.1-asprintf_fix.patch @@ -0,0 +1,16 @@ +https://hardened.gentooexperimental.org/trac/secure/raw-attachment/ticket/33/libiberty.h-asprintf-glibc-2.8.patch + +--- gcc-4.0/include/libiberty.h.orig 2007-02-09 15:29:21.000000000 +0000 ++++ gcc-4.0/include/libiberty.h 2008-07-25 21:17:25.000000000 +0000 +@@ -554,8 +554,11 @@ + /* Like sprintf but provides a pointer to malloc'd storage, which must + be freed by the caller. */ + ++/* asprintf may be declared as a macro by glibc with __USE_FORTIFY_LEVEL. */ ++#ifndef asprintf + extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2; + #endif ++#endif + + #if !HAVE_DECL_VASPRINTF + /* Like vsprintf but provides a pointer to malloc'd storage, which diff --git a/pkgs/core/gcc/patches/gcc-4.4.1-espf-1.patch b/pkgs/core/gcc/patches/gcc-4.4.1-espf-1.patch new file mode 100644 index 0000000..e531e13 --- /dev/null +++ b/pkgs/core/gcc/patches/gcc-4.4.1-espf-1.patch @@ -0,0 +1,504 @@ +diff -Nur gcc-4.4.0_vanilla/gcc/config.in gcc-4.4.0/gcc/config.in +--- gcc-4.4.0_vanilla/gcc/config.in 2009-04-21 11:08:08.000000000 +0200 ++++ gcc-4.4.0/gcc/config.in 2009-07-11 12:35:50.000000000 +0200 +@@ -65,6 +65,12 @@ + #endif + + ++/* Define to 1 to enable espf. */ ++#ifndef USED_FOR_TARGET ++#undef ENABLE_ESPF ++#endif ++ ++ + /* Define to 1 to enable fixed-point arithmetic extension to C. */ + #ifndef USED_FOR_TARGET + #undef ENABLE_FIXED_POINT +@@ -101,6 +107,12 @@ + #endif + + ++/* Define to 1 to enable libssp. */ ++#ifndef USED_FOR_TARGET ++#undef ENABLE_LIBSSP ++#endif ++ ++ + /* Define to 1 if translation of program messages to the user's native + language is requested. */ + #ifndef USED_FOR_TARGET +@@ -1465,6 +1477,12 @@ + #endif + + ++/* Define if your target C library provides fortify_sources level 2 support */ ++#ifndef USED_FOR_TARGET ++#undef TARGET_LIBC_PROVIDES_FORTIFY2 ++#endif ++ ++ + /* Define if your target C library provides stack protector support */ + #ifndef USED_FOR_TARGET + #undef TARGET_LIBC_PROVIDES_SSP +diff -Nur gcc-4.4.0_vanilla/gcc/configure gcc-4.4.0/gcc/configure +--- gcc-4.4.0_vanilla/gcc/configure 2009-03-24 18:46:03.000000000 +0100 ++++ gcc-4.4.0/gcc/configure 2009-07-11 12:35:57.000000000 +0200 +@@ -458,7 +458,7 @@ + # include <unistd.h> + #endif" + +-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical build_libsubdir build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn strict_warn warn_cflags nocommon_flag TREEBROWSER valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_decimal_float enable_fixed_point enable_shared TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR onestep PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI datarootdir docdir htmldir SET_MAKE AWK LN_S LN RANLIB ac_ct_RANLIB ranlib_flags INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON NM AR COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LTLIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file extra_opt_files USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS BUILD_LDFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN OBJDUMP ac_ct_OBJDUMP ac_ct_AR STRIP ac_ct_STRIP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 objdir enable_fast_install gcc_cv_as ORIGINAL_AS_FOR_TARGET gcc_cv_ld ORIGINAL_LD_FOR_TARGET gcc_cv_nm ORIGINAL_NM_FOR_TARGET gcc_cv_objdump gcc_cv_readelf libgcc_visibility GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir subdirs srcdir all_compilers all_gtfiles all_lang_makefrags all_lang_makefiles all_languages all_selected_languages build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines build_file_translate check_languages cpp_install_dir xmake_file tmake_file extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines c_target_objs cxx_target_objs fortran_target_objs target_cpu_default GMPLIBS GMPINC PPLLIBS PPLINC CLOOGLIBS CLOOGINC LIBOBJS LTLIBOBJS' ++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical build_libsubdir build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn strict_warn warn_cflags nocommon_flag TREEBROWSER valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_decimal_float enable_fixed_point enable_shared TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR onestep PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI datarootdir docdir htmldir SET_MAKE AWK LN_S LN RANLIB ac_ct_RANLIB ranlib_flags INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON NM AR COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LTLIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file extra_opt_files USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS BUILD_LDFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN OBJDUMP ac_ct_OBJDUMP ac_ct_AR STRIP ac_ct_STRIP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 objdir enable_fast_install gcc_cv_as ORIGINAL_AS_FOR_TARGET gcc_cv_ld ORIGINAL_LD_FOR_TARGET gcc_cv_nm ORIGINAL_NM_FOR_TARGET gcc_cv_objdump gcc_cv_readelf libgcc_visibility enable_espf GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir subdirs srcdir all_compilers all_gtfiles all_lang_makefrags all_lang_makefiles all_languages all_selected_languages build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines build_file_translate check_languages cpp_install_dir xmake_file tmake_file extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines c_target_objs cxx_target_objs fortran_target_objs target_cpu_default GMPLIBS GMPINC PPLLIBS PPLINC CLOOGLIBS CLOOGINC LIBOBJS LTLIBOBJS' + ac_subst_files='language_hooks' + ac_pwd=`pwd` + +@@ -1078,6 +1078,11 @@ + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) ++ --enable-espf ++ Enable Stack protector, Position independent executable and ++ Fortify_sources as default if we have suppot for it when compiling ++ and link with -z relro and -z now as default. ++ Linux targets supported i*86, x86_64 + --enable-maintainer-mode + enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer +@@ -24177,6 +24182,50 @@ + ;; + esac + ++echo "$as_me:$LINENO: checking linker -z now support" >&5 ++echo $ECHO_N "checking linker -z now support... $ECHO_C" >&6 ++if test "${gcc_cv_ld_now+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ gcc_cv_ld_now=no ++if test $in_tree_ld = yes ; then ++ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \ ++ && test $in_tree_ld_is_elf = yes; then ++ gcc_cv_ld_now=yes ++ fi ++elif test x$gcc_cv_ld != x; then ++ # Check if linker supports -z now options ++ if $gcc_cv_ld --help 2>/dev/null | grep now > /dev/null; then ++ gcc_cv_ld_now=yes ++ fi ++fi ++ ++fi ++echo "$as_me:$LINENO: result: $gcc_cv_ld_now" >&5 ++echo "${ECHO_T}$gcc_cv_ld_now" >&6 ++ ++echo "$as_me:$LINENO: checking linker -z relro support" >&5 ++echo $ECHO_N "checking linker -z relro support... $ECHO_C" >&6 ++if test "${gcc_cv_ld_relro+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ gcc_cv_ld_relro=no ++if test $in_tree_ld = yes ; then ++ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \ ++ && test $in_tree_ld_is_elf = yes; then ++ gcc_cv_ld_relro=yes ++ fi ++elif test x$gcc_cv_ld != x; then ++ # Check if linker supports -z relro and -z norelro options ++ if $gcc_cv_ld --help 2>/dev/null | grep relro > /dev/null; then ++ gcc_cv_ld_relro=yes ++ fi ++fi ++ ++fi ++echo "$as_me:$LINENO: result: $gcc_cv_ld_relro" >&5 ++echo "${ECHO_T}$gcc_cv_ld_relro" >&6 ++ + echo "$as_me:$LINENO: checking linker --sysroot support" >&5 + echo $ECHO_N "checking linker --sysroot support... $ECHO_C" >&6 + if test "${gcc_cv_ld_sysroot+set}" = set; then +@@ -24213,6 +24262,49 @@ + + fi + ++# Test for fortify_sources support level 2 in target C library. ++echo "$as_me:$LINENO: checking for FORTIFY_SOURCES level 2 in target C library" >&5 ++echo $ECHO_N "checking for FORTIFY_SOURCES level 2 in target C library... $ECHO_C" >&6 ++if test "${gcc_cv_libc_provides_fortify2+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ gcc_cv_libc_provides_fortify2=no ++ case "$target" in ++ *-*-linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu) ++ if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x; then ++ if test "x$with_sysroot" = x; then ++ glibc_header_dir="${exec_prefix}/${target_noncanonical}/sys-include" ++ elif test "x$with_build_sysroot" != "x"; then ++ glibc_header_dir="${with_build_sysroot}/usr/include" ++ elif test "x$with_sysroot" = xyes; then ++ glibc_header_dir="${exec_prefix}/${target_noncanonical}/sys-root/usr/include" ++ else ++ glibc_header_dir="${with_sysroot}/usr/include" ++ fi ++ else ++ glibc_header_dir=/usr/include ++ fi ++ # grep __USE_FORTIFY_LEVEL 2 in $glibc_header_dir/features.h ++ if test -f $glibc_header_dir/features.h \ ++ && grep '__USE_FORTIFY_LEVEL 2' $glibc_header_dir/features.h > /dev/null; then ++ gcc_cv_libc_provides_fortify2=yes ++ else ++ gcc_cv_libc_provides_fortify2=no ++ fi ++ ;; ++ *) gcc_cv_libc_provides_fortify2=no ;; ++ esac ++fi ++echo "$as_me:$LINENO: result: $gcc_cv_libc_provides_fortify2" >&5 ++echo "${ECHO_T}$gcc_cv_libc_provides_fortify2" >&6 ++if test x$gcc_cv_libc_provides_fortify2 = xyes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define TARGET_LIBC_PROVIDES_FORTIFY2 1 ++_ACEOF ++ ++fi ++ + # Test for stack protector support in target C library. + echo "$as_me:$LINENO: checking __stack_chk_fail in target C library" >&5 + echo $ECHO_N "checking __stack_chk_fail in target C library... $ECHO_C" >&6 +@@ -24375,6 +24467,42 @@ + + fi + ++if test x"$enable_libssp" = xyes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define ENABLE_LIBSSP 1 ++_ACEOF ++ ++fi ++ ++# Check whether --enable-espf was given and we have -z now and -z relro support. ++# Check whether --enable-espf or --disable-espf was given. ++if test "${enable_espf+set}" = set; then ++ enableval="$enable_espf" ++ ++ case $target in ++ i?86*-*-linux* | x86_64*-*-linux*) ++ if test x$gcc_cv_ld_relro = xyes && test x"$gcc_cv_ld_now" = xyes; then ++ enable_espf=yes ++ else ++ enable_espf=no ++ fi ++ ;; ++ *) ++ enable_espf=no ++ ;; ++ esac ++ ++fi; ++if test x$enable_espf = xyes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define ENABLE_ESPF 1 ++_ACEOF ++ ++fi ++ ++ + # Check if TFmode long double should be used by default or not. + # Some glibc targets used DFmode long double, but with glibc 2.4 + # and later they can use TFmode. +@@ -25581,6 +25709,7 @@ + s,@gcc_cv_objdump@,$gcc_cv_objdump,;t t + s,@gcc_cv_readelf@,$gcc_cv_readelf,;t t + s,@libgcc_visibility@,$libgcc_visibility,;t t ++s,@enable_espf@,$enable_espf,;t t + s,@GGC@,$GGC,;t t + s,@zlibdir@,$zlibdir,;t t + s,@zlibinc@,$zlibinc,;t t +diff -Nur gcc-4.4.0_vanilla/gcc/espf.h gcc-4.4.0/gcc/espf.h +--- gcc-4.4.0_vanilla/gcc/espf.h 1970-01-01 01:00:00.000000000 +0100 ++++ gcc-4.4.0/gcc/espf.h 2009-07-11 12:36:43.000000000 +0200 +@@ -0,0 +1,104 @@ ++#ifndef GCC_ESPF_H ++#define GCC_ESPF_H ++/* Version 0.2.20090614.1 (C) 2009 by Magnus Granberg <zorry@ume.nu> */ ++/* Gentoo espf.h patch Version 20090614.1 (C) 2009 by Magnus Granberg <zorry@ume.nu> */ ++ ++/* FIXME: ++ 1. Fix so that we can have -fPIE or -fpie options. ++*/ ++/* This file add's -fstack-protector-all, -Fpie|-fpie, -pie, -D_FORTIFY_SOURCES=2, -z relro, -z now, -Wformat ++ and -Wformat-security as default if the define's and the spec allow it. ++ ++ On Gentoo ++ Added a hack for gcc-specs-* in toolchain-funcs.eclass to support older hardened GCC patches and ++ we don't need to change the code on gcc-specs-*. ++ This will add some unsupported upstream commands options as -nopie and -z nonow. ++ -D__KERNEL__ is added so we don't have -fPIE|-fpie and -fstack-protector-all when building kernels. ++ ESPF_CC1_SPEC is added to CC1_SPEC. ++ -D_FORTIFY_SOURCES=2 is added with gentoo's patchset as default so no need to set it hear. ++ -Wformat* is added with gentoo's patchset as default so no need to set it hear. ++ -z relro is set by binutils as default so no need to set it hear. ++*/ ++ ++#ifdef ENABLE_ESPF ++ ++ /* Hack to support gcc-specs-* in toolchain-funcs.eclass */ ++ #define ESPF_CC1_SPEC "%{!fno-stack-protector: %{!fno-stack-protector-all: %{!nopie: %{!fstrict-overflow: }}}}" ++ ++ /* This will add -Wformat -Wformat-security -Wstack-protector in espf_cc1_options_warnings and -fstack-protector-all in ++ espf_cc1_options_ssp and incompatible pie commands in espf_cc1_options_pie_incompatible. ++ ESPF_CC1_OPTIONS_SPEC is added to CC1_OPTIONS_SPEC in gcc/gcc.c */ ++ #define ESPF_CC1_OPTIONS_SPEC "%(espf_cc1_options_ssp) %(espf_cc1_options_pie_incompatible)" ++ ++ /* This will add -z now if we don't have -z nonow or -z lazy ++ ESPF_LINK_SPEC is added to LINK_COMMAND_SPEC in gcc/gcc.c */ ++ #define ESPF_LINK_SPEC "%{!now:%{!lazy:%{!nonow:-z now}}}" ++ ++ /* This will add -fstack-protector-all if we don't have -D__KERNEL__ -nostdlib -nodefaultlibs -fno-stack-protector -fstack-protector ++ -fstack-protector-all and we have ENABLE_LIBSSP or TARGET_LIBC_PROVIDES_SSP defined. */ ++ #if defined (ENABLE_LIBSSP) || defined (TARGET_LIBC_PROVIDES_SSP) ++ #define ESPF_CC1_OPTIONS_SSP_SPEC \ ++ "%{!D__KERNEL__:%{!nostdlib:%{!nodefaultlibs: %{!fno-stack-protector: \ ++ %{!fstack-protector:%{!fstack-protector-all:-fstack-protector-all}}}}}}" ++ #else ++ #define ESPF_CC1_OPTIONS_SSP_SPEC "" ++ #endif ++ ++ /* If HAVE_LD_PIE not defined we will not add any -pie -fPIE commands and incompatible pie check */ ++ #ifdef HAVE_LD_PIE ++ ++ /* This will add -fPIE if we don't have -D__KERNEL__ -pie -fpic -fPIC -fpie -fPIE -fno-pic -fno-PIC -fno-pie -fno-PIE ++ -shared -static -nostdlib -nostartfiles -nopie ++ We use ESPF_COMPILER_COMMAND_SPEC to add -fPIE before do_spec (compiler_command_spec) is run in gcc/gcc.c main() */ ++ #define ESPF_COMPILER_COMMAND_SPEC "%(espf_compiler_command_pie)" ++ #define ESPF_COMPILER_COMMAND_PIE_SPEC \ ++ "%{!D__KERNEL__:%{!pie: %{!fpic:%{!fPIC:%{!fpie:%{!fPIE: %{!fno-pic:%{!fno-PIC:%{!fno-pie:%{!fno-PIE: \ ++ %{!shared: %{!static: %{!nostdlib: %{!nostartfiles:%{!nopie:-fPIE}} } }}}} }}}} }}}}" ++ ++ /* This adds some incompatible rules for -pie and -shared ++ We can't have -shared when -static -pie -fPIE -fpie -fno-PIC -fno-pic ++ and -pie when -static -pg -p -profile */ ++ #define ESPF_CC1_OPTIONS_PIE_INCOMPATIBLE_SPEC \ ++ "%{shared:%{static|pie|fPIE|fpie|fno-PIC|fno-pic:%e-shared and -static|pie|fPIE|fpie|fno-PIC|fno-pic are incompatible}} \ ++ %{pie:%{static|pg|p|profile:%e-pie and -static|pg|p|profile are incompatible}}" ++ ++ /* This will add -pie if we don't have -pie A -fno-pic -fno-PIC -fno-pie -fno-PIE -shared -static -r ++ -nostdlib -nostartfiles -nopie ++ We use ESPF_LINK_COMMAND_SPEC to add -pie before do_spec (link_command_spec) is run in gcc/gcc.c main() */ ++ #define ESPF_LINK_COMMAND_SPEC "%(espf_link_command_pie)" ++ #define ESPF_LINK_COMMAND_PIE_SPEC \ ++ "%{!pie:%{!A:%{!fno-pie:%{!fno-PIE:%{!fno-pic:%{!fno-PIC:%{!shared:%{!static:%{!r: \ ++ %{!nostdlib:%{!nostartfiles:%{!nopie:-pie}}}}}}}}}}}}" ++ #else ++ #define ESPF_COMPILER_COMMAND_SPEC "" ++ #define ESPF_CC1_OPTIONS_PIE_INCOMPATIBLE_SPEC "" ++ #define ESPF_LINK_COMMAND_SPEC "" ++ #endif ++ ++ /* We add extra spec name's to the EXTRA_SPECS list */ ++ #define ESPF_EXTRA_SPECS \ ++ { "espf_link", ESPF_LINK_SPEC }, \ ++ { "espf_link_command", ESPF_LINK_COMMAND_SPEC }, \ ++ { "espf_link_command_pie", ESPF_LINK_COMMAND_PIE_SPEC }, \ ++ { "espf_compiler_command", ESPF_COMPILER_COMMAND_SPEC }, \ ++ { "espf_compiler_command_pie", ESPF_COMPILER_COMMAND_PIE_SPEC }, \ ++ { "espf_cc1", ESPF_CC1_SPEC }, \ ++ { "espf_cc1_options", ESPF_CC1_OPTIONS_SPEC }, \ ++ { "espf_cc1_options_ssp", ESPF_CC1_OPTIONS_SSP_SPEC }, \ ++ { "espf_cc1_options_pie_incompatible", ESPF_CC1_OPTIONS_PIE_INCOMPATIBLE_SPEC } ++ ++ static const char *cc1_spec = CC1_SPEC ESPF_CC1_SPEC; ++ static const char *espf_compiler_command_spec = ESPF_COMPILER_COMMAND_SPEC; ++ static const char *espf_link_command_spec = ESPF_LINK_COMMAND_SPEC; ++ ++#else ++ ++ #define ESPF_CC1_OPTIONS_SPEC "" ++ #define ESPF_LINK_SPEC "" ++ #define ESPF_EXTRA_SPECS \ ++ { "espf_cc1_options", ESPF_CC1_OPTIONS_SPEC }, \ ++ { "espf_link", ESPF_LINK_SPEC } ++ ++#endif ++ ++#endif /* End GCC_ESPF_H */ +diff -Nur gcc-4.4.0_vanilla/gcc/gcc.c gcc-4.4.0/gcc/gcc.c +--- gcc-4.4.0_vanilla/gcc/gcc.c 2009-03-17 22:25:59.000000000 +0100 ++++ gcc-4.4.0/gcc/gcc.c 2009-07-11 12:36:43.000000000 +0200 +@@ -83,6 +83,7 @@ + #include "gcc.h" + #include "flags.h" + #include "opts.h" ++#include "espf.h" /* for espf support */ + + /* By default there is no special suffix for target executables. */ + /* FIXME: when autoconf is fixed, remove the host check - dj */ +@@ -726,7 +727,7 @@ + #ifndef LINK_COMMAND_SPEC + #define LINK_COMMAND_SPEC "\ + %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\ +- %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\ ++ %(linker) %l " LINK_PIE_SPEC " %(espf_link) %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\ + %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\ + %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\ + %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib)\ +@@ -758,7 +759,9 @@ + + static const char *asm_debug; + static const char *cpp_spec = CPP_SPEC; ++#ifndef ENABLE_ESPF + static const char *cc1_spec = CC1_SPEC; ++#endif + static const char *cc1plus_spec = CC1PLUS_SPEC; + static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC; + static const char *link_ssp_spec = LINK_SSP_SPEC; +@@ -826,6 +829,7 @@ + /* NB: This is shared amongst all front-ends, except for Ada. */ + static const char *cc1_options = + "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ ++ %(espf_cc1_options)\ + %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\ + %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\ + %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\ +@@ -1628,7 +1632,7 @@ + const char *const ptr; + }; + +-static const struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS }; ++static const struct spec_list_1 extra_specs_1[] = { ESPF_EXTRA_SPECS, EXTRA_SPECS }; + static struct spec_list *extra_specs = (struct spec_list *) 0; + #endif + +@@ -6782,6 +6786,12 @@ + + if (input_file_compiler) + { ++ ++#ifdef ENABLE_ESPF ++ /* We add -fpie or -fPIE as default if the spec allow it */ ++ do_self_spec (espf_compiler_command_spec); ++#endif ++ + /* Ok, we found an applicable compiler. Run its spec. */ + + if (input_file_compiler->spec[0] == '#') +@@ -6873,6 +6883,10 @@ + " to the linker.\n\n")); + fflush (stdout); + } ++#ifdef ENABLE_ESPF ++ /* We add -pie as default if the spec allow it */ ++ do_self_spec (espf_link_command_spec); ++#endif + value = do_spec (link_command_spec); + if (value < 0) + error_count = 1; +diff -Nur gcc-4.4.0_vanilla/gcc/Makefile.in gcc-4.4.0/gcc/Makefile.in +--- gcc-4.4.0_vanilla/gcc/Makefile.in 2009-03-25 13:00:32.000000000 +0100 ++++ gcc-4.4.0/gcc/Makefile.in 2009-07-11 12:36:10.000000000 +0200 +@@ -580,13 +580,23 @@ + INHIBIT_LIBC_CFLAGS = -Dinhibit_libc + endif + ++# Doesn't compile with PIE or SSP ++enable_espf = @enable_espf@ ++ifeq ($(enable_espf),yes) ++ESPF_NOPIE_CFLAGS = -fno-PIE ++ESPF_NOSSP_CFLAGS = -fno-stack-protector ++else ++ESPF_NOPIE_CFLAGS= ++ESPF_NOSSP_CFLAGS= ++endif ++ + # Options to use when compiling libgcc2.a. + # + LIBGCC2_DEBUG_CFLAGS = -g + LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) \ + $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) \ + -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED \ +- $(INHIBIT_LIBC_CFLAGS) ++ $(INHIBIT_LIBC_CFLAGS) $(ESPF_NOSSP_CFLAGS) + + # Additional options to use when compiling libgcc2.a. + # Some targets override this to -isystem include +@@ -599,7 +609,7 @@ + CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ + -finhibit-size-directive -fno-inline-functions -fno-exceptions \ + -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \ +- $(INHIBIT_LIBC_CFLAGS) ++ $(INHIBIT_LIBC_CFLAGS) $(ESPF_NOSSP_CFLAGS) + + # Additional sources to handle exceptions; overridden by targets as needed. + LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \ +@@ -1719,7 +1729,7 @@ + echo LIBGCC_SYNC = '$(LIBGCC_SYNC)' >> tmp-libgcc.mvars + echo LIBGCC_SYNC_CFLAGS = '$(LIBGCC_SYNC_CFLAGS)' >> tmp-libgcc.mvars + echo CRTSTUFF_CFLAGS = '$(CRTSTUFF_CFLAGS)' >> tmp-libgcc.mvars +- echo CRTSTUFF_T_CFLAGS = '$(CRTSTUFF_T_CFLAGS)' >> tmp-libgcc.mvars ++ echo CRTSTUFF_T_CFLAGS = '$(CRTSTUFF_T_CFLAGS) $(ESPF_NOPIE_CFLAGS)' >> tmp-libgcc.mvars + echo CRTSTUFF_T_CFLAGS_S = '$(CRTSTUFF_T_CFLAGS_S)' >> tmp-libgcc.mvars + + mv tmp-libgcc.mvars libgcc.mvars +@@ -1754,12 +1764,14 @@ + $(T)crtbegin.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ + gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H) + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \ ++ $(ESPF_NOPIE_CFLAGS) \ + -c $(srcdir)/crtstuff.c -DCRT_BEGIN \ + -o $(T)crtbegin$(objext) + + $(T)crtend.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ + gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H) + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \ ++ $(ESPF_NOPIE_CFLAGS) \ + -c $(srcdir)/crtstuff.c -DCRT_END \ + -o $(T)crtend$(objext) + +@@ -1780,6 +1792,7 @@ + $(T)crtbeginT.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \ + gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H) + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \ ++ $(ESPF_NOPIE_CFLAGS) \ + -c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFT_O \ + -o $(T)crtbeginT$(objext) + +@@ -3057,7 +3070,7 @@ + output.h $(INSN_ATTR_H) $(SYSTEM_H) $(TOPLEV_H) $(TARGET_H) libfuncs.h \ + $(TARGET_DEF_H) $(FUNCTION_H) $(SCHED_INT_H) $(TM_P_H) $(EXPR_H) \ + langhooks.h $(GGC_H) $(OPTABS_H) $(REAL_H) tm-constrs.h $(GIMPLE_H) +- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ ++ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(ESPF_NOSSP_CFLAGS)\ + $(out_file) $(OUTPUT_OPTION) + + # Build auxiliary files that support ecoff format. +diff -Nur gcc-4.4.0_vanilla/gcc/opts.c gcc-4.4.0/gcc/opts.c +--- gcc-4.4.0_vanilla/gcc/opts.c 2009-03-28 18:28:45.000000000 +0100 ++++ gcc-4.4.0/gcc/opts.c 2009-07-11 12:36:31.000000000 +0200 +@@ -897,7 +897,9 @@ + #endif + flag_regmove = opt2; + flag_strict_aliasing = opt2; ++#ifndef ENABLE_ESPF + flag_strict_overflow = opt2; ++#endif + flag_delete_null_pointer_checks = opt2; + flag_reorder_blocks = opt2; + flag_reorder_functions = opt2; +diff -Nur gcc-4.4.0_vanilla/gcc/varasm.c gcc-4.4.0/gcc/varasm.c +--- gcc-4.4.0_vanilla/gcc/varasm.c 2009-03-17 21:18:21.000000000 +0100 ++++ gcc-4.4.0/gcc/varasm.c 2009-07-11 12:36:25.000000000 +0200 +@@ -5607,7 +5607,11 @@ + bool is_local; + + is_local = targetm.binds_local_p (decl); +- if (!flag_shlib) ++ #ifdef ENABLE_ESPF ++ if (!flag_pic) ++ #else ++ if (!flag_shlib) ++ #endif + { + if (is_local) + kind = TLS_MODEL_LOCAL_EXEC; diff --git a/pkgs/core/gdb/gdb.nm b/pkgs/core/gdb/gdb.nm new file mode 100644 index 0000000..f26d0cb --- /dev/null +++ b/pkgs/core/gdb/gdb.nm @@ -0,0 +1,49 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gdb +PKG_VER = 6.8 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Debuggers +PKG_URL = http://gnu.org/software/gdb/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = A GNU source-level debugger for C, C++, Java and other languages. + +PKG_DEPS += python readline zlib + +define PKG_DESCRIPTION + GDB, the GNU debugger, allows you to debug programs written in C, C++, \ + Java, and other languages, by executing them in a controlled fashion \ + and printing their data. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --mandir=/usr/share/man \ + --disable-werror diff --git a/pkgs/core/gdbm/gdbm.nm b/pkgs/core/gdbm/gdbm.nm new file mode 100644 index 0000000..5587015 --- /dev/null +++ b/pkgs/core/gdbm/gdbm.nm @@ -0,0 +1,56 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gdbm +PKG_VER = 1.8.3 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/gdbm/ +PKG_LICENSE = GPL +PKG_SUMMARY = The GDBM package contains the GNU Database Manager. + +define PKG_DESCRIPTION + The GDBM package contains the GNU Database Manager. This is a disk file \ + format database which stores key/data-pairs in single files. The actual \ + data of any record being stored is indexed by a unique key, which can be \ + retrieved in less time than if it was stored in a text file. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --mandir=/usr/share/man + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -i Makefile.* \ + -e "s/^BINOWN = .*/BINOWN = root/" \ + -e "s/^BINGRP = .*/BINGRP = root/" +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install install-compat INSTALL_ROOT=$(BUILDROOT) +endef diff --git a/pkgs/core/gettext/gettext.nm b/pkgs/core/gettext/gettext.nm new file mode 100644 index 0000000..07fdefb --- /dev/null +++ b/pkgs/core/gettext/gettext.nm @@ -0,0 +1,54 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gettext +PKG_VER = 0.17 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://www.gnu.org/software/gettext/ +PKG_LICENSE = GPLv3 LGPL2+ +PKG_SUMMARY = GNU libraries and utilities for producing multi-lingual messages. + +PKG_PACKAGES += $(PKG_NAME_REAL)-devel + +define PKG_DESCRIPTION + The GNU gettext package provides a set of tools and documentation for \ + producing multi-lingual messages in programs. Tools include a set of \ + conventions about how programs should be written to support message \ + catalogs, a directory and file naming organization for the message \ + catalogs, a runtime library which supports the retrieval of translated \ + messages, and stand-alone programs for handling the translatable and \ + the already translated strings. Gettext provides an easy to use \ + library and tools for creating, using, and modifying natural language \ + catalogs and is a powerful and simple method for internationalizing \ + programs. +endef + +PKG_BUILD_DEPS+= autoconf automake + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/gettext/patches/gettext-0.17-automake-1.patch b/pkgs/core/gettext/patches/gettext-0.17-automake-1.patch new file mode 100644 index 0000000..d6e1196 --- /dev/null +++ b/pkgs/core/gettext/patches/gettext-0.17-automake-1.patch @@ -0,0 +1,27 @@ +diff -urN gettext-0.17.org/gettext-tools/gnulib-m4/openmp.m4 gettext-0.17/gettext-tools/gnulib-m4/openmp.m4 +--- gettext-0.17.org/gettext-tools/gnulib-m4/openmp.m4 2007-05-27 21:50:22.000000000 +0200 ++++ gettext-0.17/gettext-tools/gnulib-m4/openmp.m4 2009-08-19 14:33:04.694430366 +0200 +@@ -1,11 +1,15 @@ +-# openmp.m4 serial 4 +-dnl Copyright (C) 2006-2007 Free Software Foundation, Inc. ++# openmp.m4 serial 7 ++dnl Copyright (C) 2006-2009 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + + dnl This file can be removed once we assume autoconf >= 2.62. + ++dnl Expand to nothing in autoconf >= 2.62. m4_copy has a different ++dnl semantic in autoconf > 2.63. ++m4_ifdef([AC_OPENMP], [], [ ++ + # _AC_LANG_OPENMP + # --------------- + # Expands to some language dependent source code for testing the presence of +@@ -90,3 +94,5 @@ + fi + AC_SUBST([OPENMP_]_AC_LANG_PREFIX[FLAGS]) + ]) ++ ++]) diff --git a/pkgs/core/gettext/patches/gettext-0.17-open-args-1.patch b/pkgs/core/gettext/patches/gettext-0.17-open-args-1.patch new file mode 100644 index 0000000..5506572 --- /dev/null +++ b/pkgs/core/gettext/patches/gettext-0.17-open-args-1.patch @@ -0,0 +1,25 @@ +2007-11-07 Jim Meyering <meyering@redhat.com> + Bruno Haible <bruno@clisp.org> + + * write-catalog.c (msgdomain_list_print): Fix open() call. + +--- gettext-0.17/gettext-tools/src/write-catalog.c 7 Oct 2007 19:35:31 -0000 1.4 ++++ gettext-0.17/gettext-tools/src/write-catalog.c 7 Nov 2007 11:43:15 -0000 +@@ -1,5 +1,5 @@ + /* GNU gettext - internationalization aids +- Copyright (C) 1995-1998, 2000-2006 Free Software Foundation, Inc. ++ Copyright (C) 1995-1998, 2000-2007 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -220,7 +220,9 @@ + /* Open the output file. */ + if (!to_stdout) + { +- fd = open (filename, O_WRONLY | O_CREAT); ++ fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, ++ /* 0666 in portable POSIX notation: */ ++ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (fd < 0) + { + const char *errno_description = strerror (errno); diff --git a/pkgs/core/gettext/patches/gettext-0.17-rpathFix.patch b/pkgs/core/gettext/patches/gettext-0.17-rpathFix.patch new file mode 100644 index 0000000..c50458c --- /dev/null +++ b/pkgs/core/gettext/patches/gettext-0.17-rpathFix.patch @@ -0,0 +1,140 @@ +diff -up ./gettext-runtime/libasprintf/configure.ac.rpathFix~ ./gettext-runtime/libasprintf/configure.ac +--- ./gettext-runtime/libasprintf/configure.ac.rpathFix~ 2007-10-08 05:37:36.000000000 +1000 ++++ ./gettext-runtime/libasprintf/configure.ac 2008-08-28 16:43:18.000000000 +1000 +@@ -54,7 +54,8 @@ dnl Checks for header files. + dnl Checks for typedefs, structures, and compiler characteristics. + AC_C_INLINE + AC_TYPE_SIZE_T +-gl_AC_TYPE_LONG_LONG ++AC_TYPE_LONG_LONG_INT ++#gl_AC_TYPE_LONG_LONG + gt_TYPE_LONGDOUBLE + gt_TYPE_WCHAR_T + gt_TYPE_WINT_T +diff -up ./gettext-tools/gnulib-tests/Makefile.gnulib.rpathFix~ ./gettext-tools/gnulib-tests/Makefile.gnulib +--- ./gettext-tools/gnulib-tests/Makefile.gnulib.rpathFix~ 2007-10-28 01:39:18.000000000 +1000 ++++ ./gettext-tools/gnulib-tests/Makefile.gnulib 2008-08-28 16:43:18.000000000 +1000 +@@ -16,7 +16,7 @@ ACLOCAL_AMFLAGS = -I ../gnulib-m4 + + SUBDIRS = + TESTS = +-TESTS_ENVIRONMENT = ++TESTS_ENVIRONMENT = LD_LIBRARY_PATH='../intl/.libs:../src/.libs:../.libs:../../../../../lib:../../../../../lib64' + noinst_PROGRAMS = + check_PROGRAMS = + noinst_HEADERS = +diff -up ./gettext-tools/src/Makefile.am.rpathFix~ ./gettext-tools/src/Makefile.am +--- ./gettext-tools/src/Makefile.am.rpathFix~ 2007-10-08 05:37:38.000000000 +1000 ++++ ./gettext-tools/src/Makefile.am 2008-08-28 17:16:45.000000000 +1000 +@@ -62,6 +62,7 @@ projectsdir = $(pkgdatadir)/projects + pkglibdir = $(libdir)/gettext + + AM_CPPFLAGS = \ ++ -I../../../../../../usr/include \ + -I. -I$(srcdir) \ + -I.. -I$(top_srcdir) \ + -I$(top_srcdir)/libgrep \ +@@ -82,7 +83,7 @@ LDADD = ../gnulib-lib/libgettextlib.la @ + + SED = sed + YACC = @YACC@ -d +-GCJ = @GCJ@ ++GCJ = gcj + GCJFLAGS = @GCJFLAGS@ + JAR = @JAR@ + JAVACOMP = $(SHELL) ../javacomp.sh +diff -up ./gettext-tools/tests/Makefile.am.rpathFix~ ./gettext-tools/tests/Makefile.am +--- ./gettext-tools/tests/Makefile.am.rpathFix~ 2007-10-21 07:54:40.000000000 +1000 ++++ ./gettext-tools/tests/Makefile.am 2008-08-28 16:43:18.000000000 +1000 +@@ -181,6 +181,7 @@ TESTS_ENVIRONMENT = top_srcdir=$(top_src + LOCALE_JA='@LOCALE_JA@' \ + host_os='@host_os@' \ + CONFIG_SHELL='$(SHELL)' \ ++ LD_LIBRARY_PATH='../intl/.libs:../src/.libs:../.libs:../../../../../lib:../../../../../lib64' \ + $(SHELL) + + xg-c-1.ok.po: $(top_srcdir)/src/xgettext.c $(top_srcdir)/src/msgfmt.c +diff -up ./m4/libtool.m4.rpathFix~ ./m4/libtool.m4 +--- ./m4/libtool.m4.rpathFix~ 2007-10-27 10:46:10.000000000 +1000 ++++ ./m4/libtool.m4 2008-08-28 16:43:18.000000000 +1000 +@@ -1616,7 +1616,7 @@ linux* | k*bsd*-gnu) + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. +- hardcode_into_libs=yes ++ #hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then +@@ -2872,7 +2872,8 @@ if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + +- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++# _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty +@@ -3340,7 +3341,8 @@ case $host_os in + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + +- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' ++# _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using +@@ -3368,7 +3370,8 @@ case $host_os in + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++# _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; +@@ -3377,7 +3380,8 @@ case $host_os in + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + +- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++# _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' + ;; +@@ -3387,7 +3391,8 @@ case $host_os in + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH +- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++# _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists +@@ -3584,8 +3589,9 @@ case $host_os in + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + +- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' +- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++# _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when +@@ -5582,7 +5588,8 @@ ifelse([$1],[CXX],[ + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH +- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++# _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then diff --git a/pkgs/core/ghostscript/ghostscript.nm b/pkgs/core/ghostscript/ghostscript.nm new file mode 100644 index 0000000..9721ec8 --- /dev/null +++ b/pkgs/core/ghostscript/ghostscript.nm @@ -0,0 +1,61 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = ghostscript +PKG_VER = 8.70 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Printing +PKG_URL = http://ghostscript.com +PKG_LICENSE = GPL +PKG_SUMMARY = An interpreter for the PostScript language and for PDF. + +define PKG_DESCRIPTION + Ghostscript is a package of software that provides:\ + \ + * An interpreter for the PostScript (TM) language, with the ability to \ + convert PostScript language files to many raster formats, view them \ + on displays, and print them on printers that don't have PostScript \ + language capability built in; \ + * An interpreter for Portable Document Format (PDF) files, with the \ + same abilities; \ + * The ability to convert PostScript language files to PDF (with some \ + limitations) and vice versa; and \ + * A set of C procedures (the Ghostscript library) that implement the \ + graphics and filtering (data compression / decompression \ + / conversion) capabilities that appear as primitive operations in \ + the PostScript language and in PDF. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --without-omni + +define STAGE_INSTALL_CMDS + chown -v root:root $(BUILDROOT)/usr/share/ghostscript/8.70/Resource/Font/* +endef diff --git a/pkgs/core/glib2/glib2-locale.sh b/pkgs/core/glib2/glib2-locale.sh new file mode 100644 index 0000000..8dd50d5 --- /dev/null +++ b/pkgs/core/glib2/glib2-locale.sh @@ -0,0 +1,3 @@ +# Use the current locale charset for filenames +# in applications using GLib +export G_FILENAME_ENCODING=@locale diff --git a/pkgs/core/glib2/glib2.nm b/pkgs/core/glib2/glib2.nm new file mode 100644 index 0000000..7011034 --- /dev/null +++ b/pkgs/core/glib2/glib2.nm @@ -0,0 +1,62 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = glib +PKG_VER = 2.23.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gtk.org +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = A library of handy utility functions. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += pcre + +define PKG_DESCRIPTION + GLib is the low-level core library that forms the basis \ + for projects such as GTK+ and GNOME. It provides data structure \ + handling for C, portability wrappers, and interfaces for such runtime \ + functionality as an event loop, threads, dynamic loading, and an \ + object system. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --with-pcre=system + +define STAGE_INSTALL_CMDS + cd $(DIR_APP) && ./mkinstalldirs $(BUILDROOT)/lib + cd $(BUILDROOT)/usr/lib && for name in glib gobject gmodule gthread gio; do \ + mv -v lib$${name}-2.0.so.* ../../lib; \ + ln -svf ../../lib/lib$${name}-2.0.so.*.* lib$${name}-2.0.so; \ + done + + -mkdir -pv $(BUILDROOT)/etc/profile.d/ + cp -vf $(DIR_SOURCE)/glib2-locale.sh $(BUILDROOT)/etc/profile.d/ +endef diff --git a/pkgs/core/glibc/glibc-stack_chk_fail.c b/pkgs/core/glibc/glibc-stack_chk_fail.c new file mode 100644 index 0000000..217bf1a --- /dev/null +++ b/pkgs/core/glibc/glibc-stack_chk_fail.c @@ -0,0 +1,321 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Copyright (C) 2006-2007 Gentoo Foundation Inc. + * License terms as above. + * + * Hardened Gentoo SSP handler + * + * An SSP failure handler that does not use functions from the rest of + * glibc; it uses the INTERNAL_SYSCALL methods directly. This ensures + * no possibility of recursion into the handler. + * + * Direct all bug reports to http://bugs.gentoo.org/ + * + * Re-written from the glibc-2.3 Hardened Gentoo SSP handler + * by Kevin F. Quinn - <kevquinn[@]gentoo.org> + * + * The following people contributed to the glibc-2.3 Hardened + * Gentoo SSP handler, from which this implementation draws much: + * + * Ned Ludd - <solar[@]gentoo.org> + * Alexander Gabert - <pappy[@]gentoo.org> + * The PaX Team - <pageexec[@]freemail.hu> + * Peter S. Mazinger - <ps.m[@]gmx.net> + * Yoann Vandoorselaere - <yoann[@]prelude-ids.org> + * Robert Connolly - <robert[@]linuxfromscratch.org> + * Cory Visi <cory[@]visi.name> + * Mike Frysinger <vapier[@]gentoo.org> + */ + +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> + +#include <sys/types.h> + +#include <sysdep-cancel.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +#include <kernel-features.h> + +#include <alloca.h> +/* from sysdeps */ +#include <socketcall.h> +/* for the stuff in bits/socket.h */ +#include <sys/socket.h> +#include <sys/un.h> + + +/* Sanity check on SYSCALL macro names - force compilation + * failure if the names used here do not exist + */ +#if !defined __NR_socketcall && !defined __NR_socket +# error Cannot do syscall socket or socketcall +#endif +#if !defined __NR_socketcall && !defined __NR_connect +# error Cannot do syscall connect or socketcall +#endif +#ifndef __NR_write +# error Cannot do syscall write +#endif +#ifndef __NR_close +# error Cannot do syscall close +#endif +#ifndef __NR_getpid +# error Cannot do syscall getpid +#endif +#ifndef __NR_kill +# error Cannot do syscall kill +#endif +#ifndef __NR_exit +# error Cannot do syscall exit +#endif +#ifdef SSP_SMASH_DUMPS_CORE +# define ENABLE_SSP_SMASH_DUMPS_CORE 1 +# if !defined _KERNEL_NSIG && !defined _NSIG +# error No _NSIG or _KERNEL_NSIG for rt_sigaction +# endif +# if !defined __NR_sigaction && !defined __NR_rt_sigaction +# error Cannot do syscall sigaction or rt_sigaction +# endif +/* Although rt_sigaction expects sizeof(sigset_t) - it expects the size + * of the _kernel_ sigset_t which is not the same as the user sigset_t. + * Most arches have this as _NSIG bits - mips has _KERNEL_NSIG bits for + * some reason. + */ +# ifdef _KERNEL_NSIG +# define _SSP_NSIG _KERNEL_NSIG +# else +# define _SSP_NSIG _NSIG +# endif +#else +# define _SSP_NSIG 0 +# define ENABLE_SSP_SMASH_DUMPS_CORE 0 +#endif + +/* Define DO_SIGACTION - default to newer rt signal interface but + * fallback to old as needed. + */ +#ifdef __NR_rt_sigaction +# define DO_SIGACTION(signum, act, oldact) \ + INLINE_SYSCALL(rt_sigaction, 4, signum, act, oldact, _SSP_NSIG/8) +#else +# define DO_SIGACTION(signum, act, oldact) \ + INLINE_SYSCALL(sigaction, 3, signum, act, oldact) +#endif + +/* Define DO_SOCKET/DO_CONNECT functions to deal with socketcall vs socket/connect */ +#if defined(__NR_socket) && defined(__NR_connect) +# define USE_OLD_SOCKETCALL 0 +#else +# define USE_OLD_SOCKETCALL 1 +#endif +/* stub out the __NR_'s so we can let gcc optimize away dead code */ +#ifndef __NR_socketcall +# define __NR_socketcall 0 +#endif +#ifndef __NR_socket +# define __NR_socket 0 +#endif +#ifndef __NR_connect +# define __NR_connect 0 +#endif +#define DO_SOCKET(result, domain, type, protocol) \ + do { \ + if (USE_OLD_SOCKETCALL) { \ + socketargs[0] = domain; \ + socketargs[1] = type; \ + socketargs[2] = protocol; \ + socketargs[3] = 0; \ + result = INLINE_SYSCALL(socketcall, 2, SOCKOP_socket, socketargs); \ + } else \ + result = INLINE_SYSCALL(socket, 3, domain, type, protocol); \ + } while (0) +#define DO_CONNECT(result, sockfd, serv_addr, addrlen) \ + do { \ + if (USE_OLD_SOCKETCALL) { \ + socketargs[0] = sockfd; \ + socketargs[1] = (unsigned long int)serv_addr; \ + socketargs[2] = addrlen; \ + socketargs[3] = 0; \ + result = INLINE_SYSCALL(socketcall, 2, SOCKOP_connect, socketargs); \ + } else \ + result = INLINE_SYSCALL(connect, 3, sockfd, serv_addr, addrlen); \ + } while (0) + +#ifndef _PATH_LOG +# define _PATH_LOG "/dev/log" +#endif + +static const char path_log[] = _PATH_LOG; + +/* For building glibc with SSP switched on, define __progname to a + * constant if building for the run-time loader, to avoid pulling + * in more of libc.so into ld.so + */ +#ifdef IS_IN_rtld +static char *__progname = "<rtld>"; +#else +extern char *__progname; +#endif + + +/* Common handler code, used by stack_chk_fail and __stack_smash_handler + * Inlined to ensure no self-references to the handler within itself. + * Data static to avoid putting more than necessary on the stack, + * to aid core debugging. + */ +__attribute__ ((__noreturn__ , __always_inline__)) +static inline void +__hardened_gentoo_stack_chk_fail(char func[], int damaged) +{ +#define MESSAGE_BUFSIZ 256 + static pid_t pid; + static int plen, i; + static char message[MESSAGE_BUFSIZ]; + static const char msg_ssa[] = ": stack smashing attack"; + static const char msg_inf[] = " in function "; + static const char msg_ssd[] = "*** stack smashing detected ***: "; + static const char msg_terminated[] = " - terminated\n"; + static const char msg_report[] = "Report to http://bugs.gentoo.org/\n"; + static const char msg_unknown[] = "<unknown>"; + static int log_socket, connect_result; + static struct sockaddr_un sock; + static unsigned long int socketargs[4]; + + /* Build socket address + */ + sock.sun_family = AF_UNIX; + i = 0; + while ((path_log[i] != '\0') && (i<(sizeof(sock.sun_path)-1))) { + sock.sun_path[i] = path_log[i]; + i++; + } + sock.sun_path[i] = '\0'; + + /* Try SOCK_DGRAM connection to syslog */ + connect_result = -1; + DO_SOCKET(log_socket, AF_UNIX, SOCK_DGRAM, 0); + if (log_socket != -1) + DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock)); + if (connect_result == -1) { + if (log_socket != -1) + INLINE_SYSCALL(close, 1, log_socket); + /* Try SOCK_STREAM connection to syslog */ + DO_SOCKET(log_socket, AF_UNIX, SOCK_STREAM, 0); + if (log_socket != -1) + DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock)); + } + + /* Build message. Messages are generated both in the old style and new style, + * so that log watchers that are configured for the old-style message continue + * to work. + */ +#define strconcat(str) \ + {i=0; while ((str[i] != '\0') && ((i+plen)<(MESSAGE_BUFSIZ-1))) \ + {\ + message[plen+i]=str[i];\ + i++;\ + }\ + plen+=i;} + + /* R.Henderson post-gcc-4 style message */ + plen = 0; + strconcat(msg_ssd); + if (__progname != (char *)0) + strconcat(__progname) + else + strconcat(msg_unknown); + strconcat(msg_terminated); + + /* Write out error message to STDERR, to syslog if open */ + INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen); + if (connect_result != -1) + INLINE_SYSCALL(write, 3, log_socket, message, plen); + + /* Dr. Etoh pre-gcc-4 style message */ + plen = 0; + if (__progname != (char *)0) + strconcat(__progname) + else + strconcat(msg_unknown); + strconcat(msg_ssa); + strconcat(msg_inf); + if (func != NULL) + strconcat(func) + else + strconcat(msg_unknown); + strconcat(msg_terminated); + /* Write out error message to STDERR, to syslog if open */ + INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen); + if (connect_result != -1) + INLINE_SYSCALL(write, 3, log_socket, message, plen); + + /* Direct reports to bugs.gentoo.org */ + plen=0; + strconcat(msg_report); + message[plen++]='\0'; + + /* Write out error message to STDERR, to syslog if open */ + INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen); + if (connect_result != -1) + INLINE_SYSCALL(write, 3, log_socket, message, plen); + + if (log_socket != -1) + INLINE_SYSCALL(close, 1, log_socket); + + /* Suicide */ + pid = INLINE_SYSCALL(getpid, 0); + + if (ENABLE_SSP_SMASH_DUMPS_CORE) { + static struct sigaction default_abort_act; + /* Remove any user-supplied handler for SIGABRT, before using it */ + default_abort_act.sa_handler = SIG_DFL; + default_abort_act.sa_sigaction = NULL; + __sigfillset(&default_abort_act.sa_mask); + default_abort_act.sa_flags = 0; + if (DO_SIGACTION(SIGABRT, &default_abort_act, NULL) == 0) + INLINE_SYSCALL(kill, 2, pid, SIGABRT); + } + + /* Note; actions cannot be added to SIGKILL */ + INLINE_SYSCALL(kill, 2, pid, SIGKILL); + + /* In case the kill didn't work, exit anyway + * The loop prevents gcc thinking this routine returns + */ + while (1) + INLINE_SYSCALL(exit, 0); +} + +__attribute__ ((__noreturn__)) +void __stack_chk_fail(void) +{ + __hardened_gentoo_stack_chk_fail(NULL, 0); +} + +#ifdef ENABLE_OLD_SSP_COMPAT +__attribute__ ((__noreturn__)) +void __stack_smash_handler(char func[], int damaged) +{ + __hardened_gentoo_stack_chk_fail(func, damaged); +} +#endif diff --git a/pkgs/core/glibc/glibc.nm b/pkgs/core/glibc/glibc.nm new file mode 100644 index 0000000..9741527 --- /dev/null +++ b/pkgs/core/glibc/glibc.nm @@ -0,0 +1,233 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = glibc +PKG_VER = 2.11.1 +PKG_REL = 0 + +PKG_MAINTAINER = Michael Tremer <michael.tremer@ipfire.org> +PKG_GROUP = System/Base +PKG_URL = http://sources.redhat.com/glibc/ +PKG_LICENSE = GPLv2+ LGPLv2+ +PKG_SUMMARY = The GNU libc libraries. + +PKG_PACKAGES += $(PKG_NAME_REAL)-devel + +define PKG_DESCRIPTION + The glibc package contains standard libraries which are used by \ + multiple programs on the system. In order to save disk space and \ + memory, as well as to make upgrading easier, common system code is \ + kept in one place and shared between programs. This particular package \ + contains the most important sets of shared libraries: the standard C \ + library and the standard math library. Without these two libraries, a \ + Linux system will not function. +endef + +PKG_BUILD_DEPS = # Has got no dependencies + +CFLAGS = -O2 -fomit-frame-pointer -pipe -DPIC -fno-strict-aliasing \ + -mno-tls-direct-seg-refs -D_FORTIFY_SOURCE=2 \ + -fstack-protector-all +CXXFLAGS = $(CFLAGS) + +OPTIMIZED_KERNEL = 2.6.18 + +PKG_OBJECTS += $(THISAPP).tar.bz2 + +# $(THISAPP)-pt_pax-1.patch - Support for PT_PaX markings. + +# $(THISAPP)-strlcpy_strlcat-1.patch +# This patch adds the strlcpy and strlcat functions and manual pages to Glibc. +# A paper written about these functions is available here: +# http://www.courtesan.com/todd/papers/strlcpy.html. The Glibc project has +# refused to add these functions, and that mail tread starts here: +# http://sources.redhat.com/ml/libc-alpha/2000-08/msg00052.html. Linus Torvalds +# has added a similar function to the Linux kernel, and that mail thread is +# here: http://lwn.net/Articles/33814/. The strlcpy() and strlcat() functions +# are replacements for strncpy() and strncat(). The controversy of these +# functions is that strlcpy() and strlcat() copy the source data to the +# destination buffer until the destination is full, and discards the rest of +# the data if there is any. This means that these functions will never +# overflow. The basis for the Glibc team's refusal to add these functions is +# that they silently hide programing errors, and they have a higher performance +# hit than strncpy() and strncat(). These functions should not be needed in a +# perfect world, but were invented to deal with the real world. Many packages +# will use these functions if they are found, such as Perl and many BLFS +# packages. These functions do reduce buffer overflows, and so they are +# recommended. After installing this patch no other effort is needed to use it. +# Packages will use autotools to detect whether they are available or not. + +# $(THISAPP)-asprintf_reset2null-1.patch +# The asprintf(3) and vasprintf(3) functions are GNU extentions, not defined +# by C or Posix standards. In Glibc these functions leave (char **strp) undefined +# after an error. This patch resets (char **strp) to NULL after an error, for +# sanity. + +# $(THISAPP)-issetugid-1.patch +# This patch adds the issetugid() function, which is a front-end to the +# __libc_enable_secure() dynamic linker private function. This function +# reports whether the program is running with matching real and effective +# ID's, or not, to determine whether the program is running with set-uid or +# set-gid privileges. Many packages will search for issetugid() and use it if +# found, such as Ncurses. This is safer than allowing each program to +# determine privileges itself because it is tested at a lower level which is +# not manipulatable by the user. Apply this patch with the following command: + +# $(THISAPP)-localedef_trampoline-1.patch +# The next patch modifies the localedef program so it does not use GCC +# Trampoline code (http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html), +# which relies on an executable stack to run. Without this patch the localedef +# program will be killed if it is run on a kernel with PaX memory protection. +# See http://pax.grsecurity.net/docs/pageexec.txt and +# http://pax.grsecurity.net/docs/segmexec.txt for more information. + +# $(THISAPP)-sanitize_env.patch +# This patch resticts the environment, particularly with setuid programs. + +# $(THISAPP)-mktemp_urandom.patch +# The patch modifies __gen_tempname(), used by the mk*temp()/tmpnam() family +# of functions, to use /dev/urandom instead of hp-timing, gettimeofday(), or +# getpid(): + +# $(THISAPP)-res_randomid.patch +# The res_randomid() function is a pseudo-random number generator, using +# getpid() for entropy. See: http://www.openbsd.org/advisories/res_random.txt +# for the vulnerability. This patch uses /dev/urandom instead. + +# $(THISAPP)-resolv_response_length.patch +# This patch does a check on the buffer size of res_* functions. + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE + @cd $(DIR_SRC) && $(DO_EXTRACT) $(DIR_DL)/$(firstword $(PKG_OBJECTS)) + @mkdir $(DIR_SRC)/glibc-build + + # In the vi_VN.TCVN locale, bash enters an infinite loop at startup. It is + # unknown whether this is a bash bug or a Glibc problem. Disable + # installation of this locale in order to avoid the problem. + cd $(DIR_APP) && sed -i '/vi_VN.TCVN/d' localedata/SUPPORTED + + # The ldd shell script contains Bash-specific syntax. Change its default + # program interpreter to /bin/bash in case another /bin/sh is installed. + cd $(DIR_APP) && sed -i 's|@BASH@|/bin/bash|' elf/ldd.bash.in + + $(DO_PATCHES) + + # We don't install pt_chown(1) on the final system, so why install it to + # $(TOOLS_DIR): + cd $(DIR_APP) && sed -e "/^install.*pt_chown/d" -i login/Makefile + + # ldconfig is statically linked, so don't build it PIC: + cd $(DIR_APP) && sed "s/CFLAGS-ldconfig.c =/& -fno-PIC -fno-PIE/" \ + -i elf/Makefile + + # Build nscd with -fstack-protector-all, instead of -fstack-protector: + cd $(DIR_APP) && sed -e "s/fstack-protector/&-all/" -i nscd/Makefile + + # We don't need to set -march=i?86 in confparams because GCC was built with + # --with-arch=i?86. + + cat $(DIR_SOURCE)/$(PKG_NAME)-stack_chk_fail.c \ + > $(DIR_APP)/debug/stack_chk_fail.c + + cd $(DIR_APP) && \ + sed -e "s|libs -o|libs -L/usr/lib -Wl,-dynamic-linker=$(shell readelf -l /bin/sh | sed -n 's@.*interpret.*$(TOOLS_DIR)(.*)]$$@\1@p') -o|" \ + -i scripts/test-installation.pl + + # Fix a very weird issue with rpath + cd $(DIR_APP) && sed -e "s/LDFLAGS-rpath-ORIGIN/LDFLAGS/g" \ + -i iconvdata/Makefile +endef + +define STAGE_BUILD + # --enable-stackguard-randomization could be added here, but this is primarily + # for attacks by local users, and we shouldn't have those in the rebooted + # system. Adding this will empty the /dev/random entropy pool (via + # /dev/urandom), unless the system is running a Random Number Gathering Daemon + # (rngd). This version of Glibc uses high precision timing with SSP, so the + # canary value changes at run-time. This is not as good as /dev/urandom, but + # it's better than nothing and has very good performance. + + cd $(DIR_APP) && sed 's/-nostdlib/& -fno-stack-protector/g' -i.orig configure + + cd $(DIR_SRC)/glibc-build && \ + CFLAGS= \ + CXXFLAGS= \ + ../$(THISAPP)/configure \ + --prefix=/usr \ + --libexecdir=/usr/lib/glibc \ + --disable-profile \ + --enable-add-ons \ + --enable-kernel=$(OPTIMIZED_KERNEL) \ + --without-selinux \ + --disable-werror \ + --enable-bind-now \ + --enable-stackguard-randomization \ + --with-stack-protector=all \ + --enable-omitfp + + # Our GCC is already passing -fPIC, and that's all we want for the libraries. + # LDFLAGS.so is appended to so we don't build shared libraries with + # DT_TEXTREL (and to tell us if something goes wrong). For now we only build + # the libraries, not the programs: + echo "build-programs=no" \ + >> $(DIR_SRC)/glibc-build/configparms + + cd $(DIR_SRC)/glibc-build && make PARALLELMFLAGS=$(PARALLELISMFLAGS) \ + CFLAGS="-O2 -DPIC -fno-stack-protector -U_FORTIFY_SOURCE" \ + CXXFLAGS="-O2 -DPIC -fno-stack-protector -U_FORTIFY_SOURCE" + + # Then build the programs with hardening, so everything possible in + # $(TOOLS_DIR) is hardened: + echo "CFLAGS = $(CFLAGS)" > $(DIR_SRC)/glibc-build/configparms + echo "CXXFLAGS = $(CXXFLAGS)" >> $(DIR_SRC)/glibc-build/configparms + cd $(DIR_SRC)/glibc-build && make PARALLELMFLAGS=$(PARALLELISMFLAGS) \ + CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" +endef + +#define STAGE_TEST +# cd $(DIR_SRC)/glibc-build && cp -vf ../$(THISAPP)/iconvdata/gconv-modules iconvdata +# cd $(DIR_SRC)/glibc-build && make -k check 2>&1 | tee glibc-check-log +# cd $(DIR_SRC)/glibc-build && grep Error glibc-check-log +#endef + +define STAGE_INSTALL + cd $(DIR_SRC)/glibc-build && make install install_root=$(BUILDROOT) + + # Locales + -mkdir -pv $(BUILDROOT)/usr/lib/locale + # This would install all locales that are supported + cd $(DIR_SRC)/glibc-build && make localedata/install-locales install_root=$(BUILDROOT) + + # Timezone + cp -v --remove-destination $(BUILDROOT)/usr/share/zoneinfo/GMT $(BUILDROOT)/etc/localtime + + # Configuration + cp -vf $(DIR_SOURCE)/{ld.so.conf,nsswitch.conf} $(BUILDROOT)/etc +endef diff --git a/pkgs/core/glibc/ld.so.conf b/pkgs/core/glibc/ld.so.conf new file mode 100644 index 0000000..c6b8205 --- /dev/null +++ b/pkgs/core/glibc/ld.so.conf @@ -0,0 +1,4 @@ +# Begin /etc/ld.so.conf +/usr/lib/sasl2 +/usr/local/lib +# End /etc/ld.so.conf diff --git a/pkgs/core/glibc/nsswitch.conf b/pkgs/core/glibc/nsswitch.conf new file mode 100644 index 0000000..067e63b --- /dev/null +++ b/pkgs/core/glibc/nsswitch.conf @@ -0,0 +1,15 @@ +# Begin /etc/nsswitch.conf + +passwd: files +group: files +shadow: files + +hosts: files dns +networks: files + +protocols: files +services: files +ethers: files +rpc: files + +# End /etc/nsswitch.conf diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-arc4random.patch b/pkgs/core/glibc/patches/glibc-2.10.1-arc4random.patch new file mode 100644 index 0000000..c877c8c --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-arc4random.patch @@ -0,0 +1,541 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2006-01-01 +Initial Package Version: 2.3.6 +Upstream Status: Not submitted +Origin: http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/crypt/arc4random.c +Description: This patch adds the arc4random() and arc4randomII() functions +to Glibc, and hooks so mktemp(3) can use arc4randomII(). + +Also see: +http://www.linuxfromscratch.org/hlfs/ +http://www.linuxfromscratch.org/hints/downloads/files/entropy.txt + +diff -Naur glibc-2.3.6.orig/manual/arc4random.3 glibc-2.3.6/manual/arc4random.3 +--- glibc-2.3.6.orig/manual/arc4random.3 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.3.6/manual/arc4random.3 2006-01-01 07:48:48.000000000 +0000 +@@ -0,0 +1,74 @@ ++.TH ARC4RANDOM 3 "February 11, 2005" ++.SH NAME ++arc4random - arc4 random number generator ++.SH SYNOPSIS ++.nf ++.B #include <stdlib.h> ++.sp ++.I u_int32_t ++.B arc4random(void); ++.sp ++.I u_int32_t ++.B arc4randomII(void); ++.fi ++.SH DESCRIPTION ++The \fBarc4random()\fP function generates a pseudo-random number using the ++ARC4 cipher key stream generator. ARCFOUR uses 8*8 8 bit S-Boxes, and can ++be in about (2**1700) states. ++ ++The \fBarc4random()\fP function is seeded automatically from /dev/urandom, ++or from sysctl \fBurandom\fP if /dev/urandom is not accessible (chroot), or from ++sysctl random.uuid if sysctl \fBurandom\fP is not accessible. \fBgettimeofday(2)\fP ++is always included when initializing the state of \fBarc4random()\fP, this makes ++it impossible to generate the same random sequence twice. \fBarc4random()\fP ++is intended to be safe to use with encryption software to provide entropy. ++ ++The \fBarc4randomII()\fP function is identical to \fBarc4random()\fP except ++that \fBarc4randomII()\fP is seeded automatically from /dev/erandom, and ++sysctl erandom. \fBarc4randomII()\fP is NOT intended for cryptography, but is ++ideal for \fBmktemp(3)\fP, and other functions with a short lifespan. ++\fBarc4randomII()\fP and erandom do not consume any kernel entropy. ++ ++Sysctl urandom, and erandom require a modified kernel. See: ++http://www.linuxfromscratch.org/hlfs/ ++ ++.SH EXAMPLES ++.TP ++Return a random number between 0 and 100. ++.sp ++arc4random() % 100; ++.TP ++Return any random number. ++.sp ++arc4random(); ++.TP ++.nf ++Sample program; this will display a number between 0 and 65536. ++ ++#include <stdlib.h> ++#include <stdio.h> ++ ++int main(void) { ++ int random_number; ++ random_number = arc4random() % 65536; ++ printf("%d\n", random_number); ++ return 0; ++} ++.fi ++.SH "SEE ALSO" ++.BR random (3), ++.BR gettimeofday (2), ++.BR mktemp (3) ++ ++.SH HISTORY ++An algorithm called RC4 was designed by RSA Data Security, Inc. It was ++considered a trade secret, but not trademarked. Because it was a trade ++secret, it obviously could not be patented. A clone of this was posted ++anonymously to USENET and confirmed to be equivalent by several sources ++who had access to the original cipher. Because of the trade secret situation, ++RSA Data Security, Inc. can do nothing about the release of the ++ARC4 algorithm. Since RC4 used to be a trade secret, the cipher is now ++referred to as ARC4 (Another RC4). ++ ++These functions first appeared in OpenBSD 2.1. ++ +diff -Naur glibc-2.3.6.orig/stdlib/Makefile glibc-2.3.6/stdlib/Makefile +--- glibc-2.3.6.orig/stdlib/Makefile 2005-02-16 11:23:58.000000000 +0000 ++++ glibc-2.3.6/stdlib/Makefile 2006-01-01 07:48:48.000000000 +0000 +@@ -27,7 +27,7 @@ + + routines := \ + atof atoi atol atoll \ +- abort \ ++ abort arc4random arc4randomII \ + bsearch qsort msort \ + getenv putenv setenv secure-getenv \ + exit on_exit atexit cxa_atexit cxa_finalize old_atexit \ +diff -Naur glibc-2.3.6.orig/stdlib/Versions glibc-2.3.6/stdlib/Versions +--- glibc-2.3.6.orig/stdlib/Versions 2004-05-03 21:25:53.000000000 +0000 ++++ glibc-2.3.6/stdlib/Versions 2006-01-01 07:50:28.000000000 +0000 +@@ -11,6 +11,8 @@ + + # a* + a64l; abort; abs; atexit; atof; atoi; atol; atoll; ++ arc4random_stir; arc4random_addrandom; arc4random; ++ arc4random_stirII; arc4random_addrandomII; arc4randomII; + + # b* + bsearch; +diff -Naur glibc-2.3.6.orig/stdlib/arc4random.c glibc-2.3.6/stdlib/arc4random.c +--- glibc-2.3.6.orig/stdlib/arc4random.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.3.6/stdlib/arc4random.c 2006-01-01 07:48:48.000000000 +0000 +@@ -0,0 +1,205 @@ ++/* ++ * Arc4 random number generator for OpenBSD. ++ * Copyright 1996 David Mazieres <dm@lcs.mit.edu>. ++ * ++ * Modification and redistribution in source and binary forms is ++ * permitted provided that due credit is given to the author and the ++ * OpenBSD project by leaving this copyright notice intact. ++ */ ++ ++/* ++ * This code is derived from section 17.1 of Applied Cryptography, ++ * second edition, which describes a stream cipher allegedly ++ * compatible with RSA Labs "RC4" cipher (the actual description of ++ * which is a trade secret). The same algorithm is used as a stream ++ * cipher called "arcfour" in Tatu Ylonen's ssh package. ++ * ++ * Here the stream cipher has been modified always to include the time ++ * when initializing the state. That makes it impossible to ++ * regenerate the same random sequence twice, so this can't be used ++ * for encryption, but will generate good random numbers. ++ * ++ * RC4 is a registered trademark of RSA Laboratories. ++ */ ++ ++/* ++ * Modified by Robert Connolly from OpenBSD lib/libc/crypt/arc4random.c v1.11. ++ * This is arc4random(3) using urandom. ++ */ ++ ++#include <fcntl.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/param.h> ++#include <sys/time.h> ++#include <sys/sysctl.h> ++ ++#ifdef __GNUC__ ++#define inline __inline ++#else /* !__GNUC__ */ ++#define inline ++#endif /* !__GNUC__ */ ++ ++struct arc4_stream { ++ u_int8_t i; ++ u_int8_t j; ++ u_int8_t s[256]; ++}; ++ ++static int rs_initialized; ++static struct arc4_stream rs; ++static pid_t arc4_stir_pid; ++ ++static inline u_int8_t arc4_getbyte(struct arc4_stream *); ++ ++static inline void ++arc4_init(struct arc4_stream *as) ++{ ++ int n; ++ ++ for (n = 0; n < 256; n++) ++ as->s[n] = n; ++ as->i = 0; ++ as->j = 0; ++} ++ ++static inline void ++arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen) ++{ ++ int n; ++ u_int8_t si; ++ ++ as->i--; ++ for (n = 0; n < 256; n++) { ++ as->i = (as->i + 1); ++ si = as->s[as->i]; ++ as->j = (as->j + si + dat[n % datlen]); ++ as->s[as->i] = as->s[as->j]; ++ as->s[as->j] = si; ++ } ++ as->j = as->i; ++} ++ ++static void ++arc4_stir(struct arc4_stream *as) ++{ ++ int n, fd; ++ struct { ++ struct timeval tv; ++ u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; ++ } rdat; ++ ++ gettimeofday(&rdat.tv, NULL); ++ ++ /* /dev/urandom is a multithread interface, sysctl is not. */ ++ /* Try to use /dev/urandom before sysctl. */ ++ fd = open("/dev/urandom", O_RDONLY); ++ if (fd != -1) { ++ read(fd, rdat.rnd, sizeof(rdat.rnd)); ++ close(fd); ++ } ++ ++#if defined(SYSCTL_URANDOM) ++ else { ++ /* /dev/urandom failed? Maybe we're in a chroot. */ ++ int mib[]={CTL_KERN, KERN_RANDOM, RANDOM_URANDOM}; ++ u_int i; ++ size_t len; ++ ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ if (i < sizeof(rdat.rnd) / 4) { ++ /* Sysctl urandom failed? Maybe we're running a vanilla kernel. */ ++ mib[2] = RANDOM_UUID; ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ } ++ } ++#endif ++ ++ arc4_stir_pid = getpid(); ++ /* ++ * Time to give up. If no entropy could be found then we will just ++ * use gettimeofday. ++ */ ++ arc4_addrandom(as, (void *)&rdat, sizeof(rdat)); ++ ++ /* ++ * Discard early keystream, as per recommendations in: ++ * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps ++ * We discard 256 words. A long word is 4 bytes. ++ */ ++ for (n = 0; n < 256 * 4; n ++) ++ arc4_getbyte(as); ++} ++ ++static inline u_int8_t ++arc4_getbyte(struct arc4_stream *as) ++{ ++ u_int8_t si, sj; ++ ++ as->i = (as->i + 1); ++ si = as->s[as->i]; ++ as->j = (as->j + si); ++ sj = as->s[as->j]; ++ as->s[as->i] = sj; ++ as->s[as->j] = si; ++ return (as->s[(si + sj) & 0xff]); ++} ++ ++static inline u_int32_t ++arc4_getword(struct arc4_stream *as) ++{ ++ u_int32_t val; ++ val = arc4_getbyte(as) << 24; ++ val |= arc4_getbyte(as) << 16; ++ val |= arc4_getbyte(as) << 8; ++ val |= arc4_getbyte(as); ++ return val; ++} ++ ++void ++arc4random_stir(void) ++{ ++ if (!rs_initialized) { ++ arc4_init(&rs); ++ rs_initialized = 1; ++ } ++ arc4_stir(&rs); ++} ++ ++void ++arc4random_addrandom(u_char *dat, int datlen) ++{ ++ if (!rs_initialized) ++ arc4random_stir(); ++ arc4_addrandom(&rs, dat, datlen); ++} ++ ++u_int32_t ++arc4random(void) ++{ ++ if (!rs_initialized || arc4_stir_pid != getpid()) ++ arc4random_stir(); ++ return arc4_getword(&rs); ++} ++ ++#if 0 ++/*-------- Test code --------*/ ++#include <stdlib.h> ++#include <stdio.h> ++ ++int main(void) { ++ int random_number; ++ random_number = arc4random() % 65536; ++ printf("A random number between 0 and 65536 is %d\n", random_number); ++ return 0; ++} ++#endif +diff -Naur glibc-2.3.6.orig/stdlib/arc4randomII.c glibc-2.3.6/stdlib/arc4randomII.c +--- glibc-2.3.6.orig/stdlib/arc4randomII.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.3.6/stdlib/arc4randomII.c 2006-01-01 07:48:48.000000000 +0000 +@@ -0,0 +1,196 @@ ++/* ++ * Arc4 random number generator for OpenBSD. ++ * Copyright 1996 David Mazieres <dm@lcs.mit.edu>. ++ * ++ * Modification and redistribution in source and binary forms is ++ * permitted provided that due credit is given to the author and the ++ * OpenBSD project by leaving this copyright notice intact. ++ */ ++ ++/* ++ * This code is derived from section 17.1 of Applied Cryptography, ++ * second edition, which describes a stream cipher allegedly ++ * compatible with RSA Labs "RC4" cipher (the actual description of ++ * which is a trade secret). The same algorithm is used as a stream ++ * cipher called "arcfour" in Tatu Ylonen's ssh package. ++ * ++ * Here the stream cipher has been modified always to include the time ++ * when initializing the state. That makes it impossible to ++ * regenerate the same random sequence twice, so this can't be used ++ * for encryption, but will generate good random numbers. ++ * ++ * RC4 is a registered trademark of RSA Laboratories. ++ */ ++ ++/* ++ * Modified by Robert Connolly from OpenBSD lib/libc/crypt/arc4random.c v1.11. ++ * This is arc4randomII(3) using erandom. ++ */ ++ ++#include <fcntl.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/param.h> ++#include <sys/time.h> ++#include <sys/sysctl.h> ++ ++#ifdef __GNUC__ ++#define inline __inline ++#else /* !__GNUC__ */ ++#define inline ++#endif /* !__GNUC__ */ ++ ++struct arc4_streamII { ++ u_int8_t i; ++ u_int8_t j; ++ u_int8_t s[256]; ++}; ++ ++static int rs_initializedII; ++static struct arc4_streamII rs; ++static pid_t arc4_stir_pidII; ++ ++static inline u_int8_t arc4_getbyteII(struct arc4_streamII *); ++ ++static inline void ++arc4_initII(struct arc4_streamII *as) ++{ ++ int n; ++ ++ for (n = 0; n < 256; n++) ++ as->s[n] = n; ++ as->i = 0; ++ as->j = 0; ++} ++ ++static inline void ++arc4_addrandomII(struct arc4_streamII *as, u_char *dat, int datlen) ++{ ++ int n; ++ u_int8_t si; ++ ++ as->i--; ++ for (n = 0; n < 256; n++) { ++ as->i = (as->i + 1); ++ si = as->s[as->i]; ++ as->j = (as->j + si + dat[n % datlen]); ++ as->s[as->i] = as->s[as->j]; ++ as->s[as->j] = si; ++ } ++ as->j = as->i; ++} ++ ++static void ++arc4_stirII(struct arc4_streamII *as) ++{ ++ int n, fd; ++ struct { ++ struct timeval tv; ++ u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; ++ } rdat; ++ ++ gettimeofday(&rdat.tv, NULL); ++ ++ /* /dev/urandom is a multithread interface, sysctl is not. */ ++ /* Try to use /dev/urandom before sysctl. */ ++ fd = open("/dev/erandom", O_RDONLY); ++ if (fd != -1) { ++ read(fd, rdat.rnd, sizeof(rdat.rnd)); ++ close(fd); ++ } ++ ++#if defined(SYSCTL_ERANDOM) ++ else { ++ /* /dev/urandom failed? Maybe we're in a chroot. */ ++ int mib[]={CTL_KERN, KERN_RANDOM, RANDOM_ERANDOM}; ++ u_int i; ++ size_t len; ++ ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ } ++#endif ++ ++ arc4_stir_pidII = getpid(); ++ /* ++ * Time to give up. If no entropy could be found then we will just ++ * use gettimeofday. ++ */ ++ arc4_addrandomII(as, (void *)&rdat, sizeof(rdat)); ++ ++ /* ++ * Discard early keystream, as per recommendations in: ++ * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps ++ * We discard 256 words. A long word is 4 bytes. ++ */ ++ for (n = 0; n < 256 * 4; n ++) ++ arc4_getbyteII(as); ++} ++ ++static inline u_int8_t ++arc4_getbyteII(struct arc4_streamII *as) ++{ ++ u_int8_t si, sj; ++ ++ as->i = (as->i + 1); ++ si = as->s[as->i]; ++ as->j = (as->j + si); ++ sj = as->s[as->j]; ++ as->s[as->i] = sj; ++ as->s[as->j] = si; ++ return (as->s[(si + sj) & 0xff]); ++} ++ ++static inline u_int32_t ++arc4_getwordII(struct arc4_streamII *as) ++{ ++ u_int32_t val; ++ val = arc4_getbyteII(as) << 24; ++ val |= arc4_getbyteII(as) << 16; ++ val |= arc4_getbyteII(as) << 8; ++ val |= arc4_getbyteII(as); ++ return val; ++} ++ ++void ++arc4random_stirII(void) ++{ ++ if (!rs_initializedII) { ++ arc4_initII(&rs); ++ rs_initializedII = 1; ++ } ++ arc4_stirII(&rs); ++} ++ ++void ++arc4random_addrandomII(u_char *dat, int datlen) ++{ ++ if (!rs_initializedII) ++ arc4random_stirII(); ++ arc4_addrandomII(&rs, dat, datlen); ++} ++ ++u_int32_t ++arc4randomII(void) ++{ ++ if (!rs_initializedII || arc4_stir_pidII != getpid()) ++ arc4random_stirII(); ++ return arc4_getwordII(&rs); ++} ++ ++#if 0 ++/*-------- Test code --------*/ ++#include <stdlib.h> ++#include <stdio.h> ++ ++int main(void) { ++ int random_number; ++ random_number = arc4randomII() % 65536; ++ printf("A random number between 0 and 65536 is %d\n", random_number); ++ return 0; ++} ++#endif +diff -Naur glibc-2.3.6.orig/stdlib/stdlib.h glibc-2.3.6/stdlib/stdlib.h +--- glibc-2.3.6.orig/stdlib/stdlib.h 2005-07-18 01:15:30.000000000 +0000 ++++ glibc-2.3.6/stdlib/stdlib.h 2006-01-01 07:48:48.000000000 +0000 +@@ -572,6 +572,15 @@ + extern int lcong48_r (unsigned short int __param[7], + struct drand48_data *__buffer) + __THROW __nonnull ((1, 2)); ++ ++#define LIBC_HAS_ARC4RANDOM ++u_int32_t arc4random(void); ++void arc4random_stir(void); ++void arc4random_addrandom(unsigned char *, int); ++u_int32_t arc4randomII(void); ++void arc4random_stirII(void); ++void arc4random_addrandomII(unsigned char *, int); ++ + # endif /* Use misc. */ + #endif /* Use SVID or X/Open. */ diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-asprintf_reset2null-1.patch b/pkgs/core/glibc/patches/glibc-2.10.1-asprintf_reset2null-1.patch new file mode 100644 index 0000000..60dd425 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-asprintf_reset2null-1.patch @@ -0,0 +1,59 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2007-05-07 +Initial Package Version: 2.5 +Upstream Status: Submitted +http://sourceware.org/ml/libc-alpha/2004-05/msg00067.html +http://sourceware.org/ml/libc-alpha/2004-06/msg00007.html +Origin: Alt-Linux / Dmitry V. Levin +Description: + +The asprintf(3) and vasprintf(3) functions are GNU extentions, not defined +by C or Posix standards. In Glibc these functions leave (char **strp) undefined +after an error. This patch resets (char **strp) to NULL after an error, for +sanity. + +This patch, and the behavior it sets, was reviewed and discussed on the Glibc +mailing list, and appeared to be accepted, and then it looks like it was +forgotten about. + +2004-06-03 Dmitry V. Levin <ldv@altlinux.org> + + * libio/vasprintf.c (_IO_vasprintf): Reset the result pointer + to NULL on any error. + * manual/stdio.texi: Reflect the change in asprintf API. + +--- glibc-2.5.orig/libio/vasprintf.c ++++ glibc-2.5/libio/vasprintf.c +@@ -50,7 +50,10 @@ _IO_vasprintf (result_ptr, format, args) + we know we will never seek on the stream. */ + string = (char *) malloc (init_string_size); + if (string == NULL) +- return -1; ++ { ++ *result_ptr = NULL; ++ return -1; ++ } + #ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; + #endif +@@ -64,6 +67,7 @@ #endif + if (ret < 0) + { + free (sf._sbf._f._IO_buf_base); ++ *result_ptr = NULL; + return ret; + } + /* Only use realloc if the size we need is of the same (binary) +--- glibc-2.5.orig/manual/stdio.texi ++++ glibc-2.5/manual/stdio.texi +@@ -2398,7 +2398,9 @@ to the newly allocated string at that lo + + The return value is the number of characters allocated for the buffer, or + less than zero if an error occurred. Usually this means that the buffer +-could not be allocated. ++could not be allocated, and the value of @var{ptr} in this situation is ++implementation-dependent (in glibc, @var{ptr} will be set to the null ++pointer, but this behavior should not be relied upon). + + Here is how to use @code{asprintf} to get the same result as the + @code{snprintf} example, but more easily: diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-hardened-configure-picdefault.patch b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-configure-picdefault.patch new file mode 100644 index 0000000..19f2544 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-configure-picdefault.patch @@ -0,0 +1,29 @@ +Prevent default-fPIE from confusing configure into thinking +PIC code is default. This causes glibc to build both PIC and +non-PIC code as normal, which on the hardened compiler generates +PIC and PIE. + +Patch by Kevin F. Quinn <kevquinn@gentoo.org> + +--- glibc-2.10.1/configure.in ++++ glibc-2.10.1/configure.in +@@ -2145,7 +2145,7 @@ + # error PIC is default. + #endif + EOF +-if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then ++if eval "${CC-cc} -fno-PIE -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then + libc_cv_pic_default=no + fi + rm -f conftest.*]) +--- glibc-2.10.1/configure ++++ glibc-2.10.1/configure +@@ -7698,7 +7698,7 @@ + # error PIC is default. + #endif + EOF +-if eval "${CC-cc} -S conftest.c 2>&5 1>&5"; then ++if eval "${CC-cc} -fno-PIE -S conftest.c 2>&5 1>&5"; then + libc_cv_pic_default=no + fi + rm -f conftest.* diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-hardened-inittls-nosysenter.patch b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-inittls-nosysenter.patch new file mode 100644 index 0000000..ce9c907 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-inittls-nosysenter.patch @@ -0,0 +1,273 @@ +When building glibc PIE (which is not something upstream support), +several modifications are necessary to the glibc build process. + +First, any syscalls in PIEs must be of the PIC variant, otherwise +textrels ensue. Then, any syscalls made before the initialisation +of the TLS will fail on i386, as the sysenter variant on i386 uses +the TLS, giving rise to a chicken-and-egg situation. This patch +defines a PIC syscall variant that doesn't use sysenter, even when the sysenter +version is normally used, and uses the non-sysenter version for the brk +syscall that is performed by the TLS initialisation. Further, the TLS +initialisation is moved in this case prior to the initialisation of +dl_osversion, as that requires further syscalls. + +csu/libc-start.c: Move initial TLS initialization to before the +initialisation of dl_osversion, when INTERNAL_SYSCALL_NOSYSENTER is defined + +csu/libc-tls.c: Use the no-sysenter version of sbrk when +INTERNAL_SYSCALL_NOSYSENTER is defined. + +misc/sbrk.c: Define a no-sysenter version of sbrk, using the no-sysenter +version of brk - if INTERNAL_SYSCALL_NOSYSENTER is defined. + +misc/brk.c: Define a no-sysenter version of brk if +INTERNAL_SYSCALL_NOSYSENTER is defined. + +sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NOSYSENTER +Make INTERNAL_SYSCALL always use the PIC variant, even if not SHARED. + +Patch by Kevin F. Quinn <kevquinn@gentoo.org> + +--- glibc-2.10.1/csu/libc-start.c ++++ glibc-2.10.1/csu/libc-start.c +@@ -28,6 +28,7 @@ + extern int __libc_multiple_libcs; + + #include <tls.h> ++#include <sysdep.h> + #ifndef SHARED + # include <dl-osinfo.h> + extern void __pthread_initialize_minimal (void); +@@ -129,6 +130,11 @@ + # endif + _dl_aux_init (auxvec); + # endif ++# ifdef INTERNAL_SYSCALL_NOSYSENTER ++ /* Do the initial TLS initialization before _dl_osversion, ++ since the latter uses the uname syscall. */ ++ __pthread_initialize_minimal (); ++# endif + # ifdef DL_SYSDEP_OSCHECK + if (!__libc_multiple_libcs) + { +@@ -138,10 +144,12 @@ + } + # endif + ++# ifndef INTERNAL_SYSCALL_NOSYSENTER + /* Initialize the thread library at least a bit since the libgcc + functions are using thread functions if these are available and + we need to setup errno. */ + __pthread_initialize_minimal (); ++# endif + + /* Set up the stack checker's canary. */ + uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (); +--- glibc-2.10.1/csu/libc-tls.c ++++ glibc-2.10.1/csu/libc-tls.c +@@ -23,6 +23,7 @@ + #include <unistd.h> + #include <stdio.h> + #include <sys/param.h> ++#include <sysdep.h> + + + #ifdef SHARED +@@ -29,6 +30,9 @@ + #error makefile bug, this file is for static only + #endif + ++#ifdef INTERNAL_SYSCALL_NOSYSENTER ++extern void *__sbrk_nosysenter (intptr_t __delta); ++#endif + extern ElfW(Phdr) *_dl_phdr; + extern size_t _dl_phnum; + +@@ -141,14 +145,26 @@ + + The initialized value of _dl_tls_static_size is provided by dl-open.c + to request some surplus that permits dynamic loading of modules with +- IE-model TLS. */ ++ IE-model TLS. ++ ++ Where the normal sbrk would use a syscall that needs the TLS (i386) ++ use the special non-sysenter version instead. */ + #if TLS_TCB_AT_TP + tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign); ++# ifdef INTERNAL_SYSCALL_NOSYSENTER ++ tlsblock = __sbrk_nosysenter (tcb_offset + tcbsize + max_align); ++# else + tlsblock = __sbrk (tcb_offset + tcbsize + max_align); ++# endif + #elif TLS_DTV_AT_TP + tcb_offset = roundup (tcbsize, align ?: 1); ++# ifdef INTERNAL_SYSCALL_NOSYSENTER ++ tlsblock = __sbrk_nosysenter (tcb_offset + memsz + max_align ++ + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size)); ++# else + tlsblock = __sbrk (tcb_offset + memsz + max_align + + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size)); ++# endif + tlsblock += TLS_PRE_TCB_SIZE; + #else + /* In case a model with a different layout for the TCB and DTV +--- glibc-2.10.1/misc/sbrk.c ++++ glibc-2.10.1/misc/sbrk.c +@@ -18,6 +18,7 @@ + + #include <stdint.h> + #include <unistd.h> ++#include <sysdep.h> + + /* Defined in brk.c. */ + extern void *__curbrk; +@@ -29,6 +30,35 @@ + /* Extend the process's data space by INCREMENT. + If INCREMENT is negative, shrink data space by - INCREMENT. + Return start of new space allocated, or -1 for errors. */ ++#ifdef INTERNAL_SYSCALL_NOSYSENTER ++/* This version is used by csu/libc-tls.c whem initialising the TLS ++ if the SYSENTER version requires the TLS (which it does on i386). ++ Obviously using the TLS before it is initialised is broken. */ ++extern int __brk_nosysenter (void *addr); ++void * ++__sbrk_nosysenter (intptr_t increment) ++{ ++ void *oldbrk; ++ ++ /* If this is not part of the dynamic library or the library is used ++ via dynamic loading in a statically linked program update ++ __curbrk from the kernel's brk value. That way two separate ++ instances of __brk and __sbrk can share the heap, returning ++ interleaved pieces of it. */ ++ if (__curbrk == NULL || __libc_multiple_libcs) ++ if (__brk_nosysenter (0) < 0) /* Initialize the break. */ ++ return (void *) -1; ++ ++ if (increment == 0) ++ return __curbrk; ++ ++ oldbrk = __curbrk; ++ if (__brk_nosysenter (oldbrk + increment) < 0) ++ return (void *) -1; ++ ++ return oldbrk; ++} ++#endif + void * + __sbrk (intptr_t increment) + { +--- glibc-2.10.1/sysdeps/unix/sysv/linux/i386/brk.c ++++ glibc-2.10.1/sysdeps/unix/sysv/linux/i386/brk.c +@@ -31,6 +31,30 @@ + linker. */ + weak_alias (__curbrk, ___brk_addr) + ++#ifdef INTERNAL_SYSCALL_NOSYSENTER ++/* This version is used by csu/libc-tls.c whem initialising the TLS ++ * if the SYSENTER version requires the TLS (which it does on i386). ++ * Obviously using the TLS before it is initialised is broken. */ ++int ++__brk_nosysenter (void *addr) ++{ ++ void *__unbounded newbrk; ++ ++ INTERNAL_SYSCALL_DECL (err); ++ newbrk = (void *__unbounded) INTERNAL_SYSCALL_NOSYSENTER (brk, err, 1, ++ __ptrvalue (addr)); ++ ++ __curbrk = newbrk; ++ ++ if (newbrk < addr) ++ { ++ __set_errno (ENOMEM); ++ return -1; ++ } ++ ++ return 0; ++} ++#endif + int + __brk (void *addr) + { +--- glibc-2.10.1/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ glibc-2.10.1/sysdeps/unix/sysv/linux/i386/sysdep.h +@@ -187,7 +187,7 @@ + /* The original calling convention for system calls on Linux/i386 is + to use int $0x80. */ + #ifdef I386_USE_SYSENTER +-# ifdef SHARED ++# if defined SHARED || defined __PIC__ + # define ENTER_KERNEL call *%gs:SYSINFO_OFFSET + # else + # define ENTER_KERNEL call *_dl_sysinfo +@@ -358,7 +358,7 @@ + possible to use more than four parameters. */ + #undef INTERNAL_SYSCALL + #ifdef I386_USE_SYSENTER +-# ifdef SHARED ++# if defined SHARED || defined __PIC__ + # define INTERNAL_SYSCALL(name, err, nr, args...) \ + ({ \ + register unsigned int resultvar; \ +@@ -384,6 +384,18 @@ + : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \ + ASMFMT_##nr(args) : "memory", "cc"); \ + (int) resultvar; }) ++# define INTERNAL_SYSCALL_NOSYSENTER(name, err, nr, args...) \ ++ ({ \ ++ register unsigned int resultvar; \ ++ EXTRAVAR_##nr \ ++ asm volatile ( \ ++ LOADARGS_NOSYSENTER_##nr \ ++ "movl %1, %%eax\n\t" \ ++ "int $0x80\n\t" \ ++ RESTOREARGS_NOSYSENTER_##nr \ ++ : "=a" (resultvar) \ ++ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \ ++ (int) resultvar; }) + # else + # define INTERNAL_SYSCALL(name, err, nr, args...) \ + ({ \ +@@ -447,12 +459,20 @@ + + #define LOADARGS_0 + #ifdef __PIC__ +-# if defined I386_USE_SYSENTER && defined SHARED ++# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ ) + # define LOADARGS_1 \ + "bpushl .L__X'%k3, %k3\n\t" + # define LOADARGS_5 \ + "movl %%ebx, %4\n\t" \ + "movl %3, %%ebx\n\t" ++# define LOADARGS_NOSYSENTER_1 \ ++ "bpushl .L__X'%k2, %k2\n\t" ++# define LOADARGS_NOSYSENTER_2 LOADARGS_NOSYSENTER_1 ++# define LOADARGS_NOSYSENTER_3 LOADARGS_3 ++# define LOADARGS_NOSYSENTER_4 LOADARGS_3 ++# define LOADARGS_NOSYSENTER_5 \ ++ "movl %%ebx, %3\n\t" \ ++ "movl %2, %%ebx\n\t" + # else + # define LOADARGS_1 \ + "bpushl .L__X'%k2, %k2\n\t" +@@ -474,11 +495,18 @@ + + #define RESTOREARGS_0 + #ifdef __PIC__ +-# if defined I386_USE_SYSENTER && defined SHARED ++# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ ) + # define RESTOREARGS_1 \ + "bpopl .L__X'%k3, %k3\n\t" + # define RESTOREARGS_5 \ + "movl %4, %%ebx" ++# define RESTOREARGS_NOSYSENTER_1 \ ++ "bpopl .L__X'%k2, %k2\n\t" ++# define RESTOREARGS_NOSYSENTER_2 RESTOREARGS_NOSYSENTER_1 ++# define RESTOREARGS_NOSYSENTER_3 RESTOREARGS_3 ++# define RESTOREARGS_NOSYSENTER_4 RESTOREARGS_3 ++# define RESTOREARGS_NOSYSENTER_5 \ ++ "movl %3, %%ebx" + # else + # define RESTOREARGS_1 \ + "bpopl .L__X'%k2, %k2\n\t" diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-localedef_trampoline-1.patch b/pkgs/core/glibc/patches/glibc-2.10.1-localedef_trampoline-1.patch new file mode 100644 index 0000000..4d26016 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-localedef_trampoline-1.patch @@ -0,0 +1,64 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2007-05-05 +Initial Package Version: 2.5 +Upstream Status: Rejected - http://sources.redhat.com/bugzilla/show_bug.cgi?id=3333 +Origin: Fedora's glibc-fedora.patch (via glibc-2.5.90-21) +Description: Avoid segmentation faults, or kills, on PaX and Exe-Shield kernels, + and some non-x86 architectures. + +* Sun Jun 01 2003 Jakub Jelinek <jakub@redhat.com> 2.3.2-46 + - avoid using trampolines in localedef + +This patch is also known as: +local-localedef-fix-trampoline.diff (Debian) +1040_all_2.3.3-localedef-fix-trampoline.patch (Gentoo) + +Also see: +http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=231438 + +diff -Naur glibc-2.5.orig/locale/programs/3level.h glibc-2.5/locale/programs/3level.h +--- glibc-2.5.orig/locale/programs/3level.h 2005-12-07 05:47:27.000000000 +0000 ++++ glibc-2.5/locale/programs/3level.h 2006-10-11 08:05:00.000000000 +0000 +@@ -202,6 +202,42 @@ + } + } + } ++ ++/* GCC ATM seems to do a poor job with pointers to nested functions passed ++ to inlined functions. Help it a little bit with this hack. */ ++#define wchead_table_iterate(tp, fn) \ ++do \ ++ { \ ++ struct wchead_table *t = (tp); \ ++ uint32_t index1; \ ++ for (index1 = 0; index1 < t->level1_size; index1++) \ ++ { \ ++ uint32_t lookup1 = t->level1[index1]; \ ++ if (lookup1 != ((uint32_t) ~0)) \ ++ { \ ++ uint32_t lookup1_shifted = lookup1 << t->q; \ ++ uint32_t index2; \ ++ for (index2 = 0; index2 < (1 << t->q); index2++) \ ++ { \ ++ uint32_t lookup2 = t->level2[index2 + lookup1_shifted]; \ ++ if (lookup2 != ((uint32_t) ~0)) \ ++ { \ ++ uint32_t lookup2_shifted = lookup2 << t->p; \ ++ uint32_t index3; \ ++ for (index3 = 0; index3 < (1 << t->p); index3++) \ ++ { \ ++ struct element_t *lookup3 \ ++ = t->level3[index3 + lookup2_shifted]; \ ++ if (lookup3 != NULL) \ ++ fn ((((index1 << t->q) + index2) << t->p) + index3, \ ++ lookup3); \ ++ } \ ++ } \ ++ } \ ++ } \ ++ } \ ++ } while (0) ++ + #endif + + #ifndef NO_FINALIZE diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-pt_pax-1.patch b/pkgs/core/glibc/patches/glibc-2.10.1-pt_pax-1.patch new file mode 100644 index 0000000..1d69588 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-pt_pax-1.patch @@ -0,0 +1,40 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2006-10-11 +Initial Package Version: 2.5 +Upstream Status: Not submitted - PaX specific. Will not be accepted upstream. +Origin: http://www.gtlib.cc.gatech.edu/pub/gentoo/gentoo-x86-portage/sys-libs/ \ + glibc/files/2.3.3/glibc-2.3.3_pre20040117-pt_pax.diff +Description: This is needed for Pax. http://pax.grsecurity.net/ +Also see: +http://www.linuxfromscratch.org/hlfs/ + +diff -Naur glibc-2.5.orig/elf/elf.h glibc-2.5/elf/elf.h +--- glibc-2.5.orig/elf/elf.h 2006-07-10 21:54:02.000000000 +0000 ++++ glibc-2.5/elf/elf.h 2006-10-11 21:30:02.000000000 +0000 +@@ -569,6 +569,7 @@ + #define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ + #define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ + #define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ ++#define PT_PAX_FLAGS 0x65041580 /* Indicates PaX flag markings */ + #define PT_LOSUNW 0x6ffffffa + #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ + #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +@@ -582,6 +583,18 @@ + #define PF_X (1 << 0) /* Segment is executable */ + #define PF_W (1 << 1) /* Segment is writable */ + #define PF_R (1 << 2) /* Segment is readable */ ++#define PF_PAGEEXEC (1 << 4) /* Enable PAGEEXEC */ ++#define PF_NOPAGEEXEC (1 << 5) /* Disable PAGEEXEC */ ++#define PF_SEGMEXEC (1 << 6) /* Enable SEGMEXEC */ ++#define PF_NOSEGMEXEC (1 << 7) /* Disable SEGMEXEC */ ++#define PF_MPROTECT (1 << 8) /* Enable MPROTECT */ ++#define PF_NOMPROTECT (1 << 9) /* Disable MPROTECT */ ++#define PF_RANDEXEC (1 << 10) /* Enable RANDEXEC */ ++#define PF_NORANDEXEC (1 << 11) /* Disable RANDEXEC */ ++#define PF_EMUTRAMP (1 << 12) /* Enable EMUTRAMP */ ++#define PF_NOEMUTRAMP (1 << 13) /* Disable EMUTRAMP */ ++#define PF_RANDMMAP (1 << 14) /* Enable RANDMMAP */ ++#define PF_NORANDMMAP (1 << 15) /* Disable RANDMMAP */ + #define PF_MASKOS 0x0ff00000 /* OS-specific */ + #define PF_MASKPROC 0xf0000000 /* Processor-specific */ + diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-sanitize_env.patch.off b/pkgs/core/glibc/patches/glibc-2.10.1-sanitize_env.patch.off new file mode 100644 index 0000000..5d0e942 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-sanitize_env.patch.off @@ -0,0 +1,1062 @@ +From: http://sisyphus.ru/srpm/Sisyphus/glibc/patches/10 + +I added MUDFLAP_OPTIONS to sysdeps/generic/unsecvars.h. + +diff -Naur glibc-2.8-20080929.orig/argp/argp-help.c glibc-2.8-20080929/argp/argp-help.c +--- glibc-2.8-20080929.orig/argp/argp-help.c 2007-03-15 20:08:18.000000000 +0000 ++++ glibc-2.8-20080929/argp/argp-help.c 2008-10-15 00:30:49.000000000 +0000 +@@ -165,7 +165,7 @@ + static void + fill_in_uparams (const struct argp_state *state) + { +- const char *var = getenv ("ARGP_HELP_FMT"); ++ const char *var = __secure_getenv ("ARGP_HELP_FMT"); + + #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0); + +diff -Naur glibc-2.8-20080929.orig/catgets/catgets.c glibc-2.8-20080929/catgets/catgets.c +--- glibc-2.8-20080929.orig/catgets/catgets.c 2002-05-15 03:46:42.000000000 +0000 ++++ glibc-2.8-20080929/catgets/catgets.c 2008-10-15 00:30:49.000000000 +0000 +@@ -50,7 +50,7 @@ + || (__libc_enable_secure && strchr (env_var, '/') != NULL)) + env_var = "C"; + +- nlspath = getenv ("NLSPATH"); ++ nlspath = __secure_getenv ("NLSPATH"); + if (nlspath != NULL && *nlspath != '\0') + { + /* Append the system dependent directory. */ +diff -Naur glibc-2.8-20080929.orig/debug/pcprofile.c glibc-2.8-20080929/debug/pcprofile.c +--- glibc-2.8-20080929.orig/debug/pcprofile.c 2001-07-06 04:54:45.000000000 +0000 ++++ glibc-2.8-20080929/debug/pcprofile.c 2008-10-15 00:30:49.000000000 +0000 +@@ -38,7 +38,7 @@ + { + /* See whether the environment variable `PCPROFILE_OUTPUT' is defined. + If yes, it should name a FIFO. We open it and mark ourself as active. */ +- const char *outfile = getenv ("PCPROFILE_OUTPUT"); ++ const char *outfile = __secure_getenv ("PCPROFILE_OUTPUT"); + + if (outfile != NULL && *outfile != '\0') + { +diff -Naur glibc-2.8-20080929.orig/debug/segfault.c glibc-2.8-20080929/debug/segfault.c +--- glibc-2.8-20080929.orig/debug/segfault.c 2007-08-22 06:52:12.000000000 +0000 ++++ glibc-2.8-20080929/debug/segfault.c 2008-10-15 00:30:49.000000000 +0000 +@@ -149,7 +149,7 @@ + install_handler (void) + { + struct sigaction sa; +- const char *sigs = getenv ("SEGFAULT_SIGNALS"); ++ const char *sigs = __secure_getenv ("SEGFAULT_SIGNALS"); + const char *name; + + sa.sa_handler = (void *) catch_segfault; +@@ -157,7 +157,7 @@ + sa.sa_flags = SA_RESTART; + + /* Maybe we are expected to use an alternative stack. */ +- if (getenv ("SEGFAULT_USE_ALTSTACK") != 0) ++ if (__secure_getenv ("SEGFAULT_USE_ALTSTACK") != 0) + { + void *stack_mem = malloc (2 * SIGSTKSZ); + struct sigaltstack ss; +@@ -203,7 +203,7 @@ + } + + /* Preserve the output file name if there is any given. */ +- name = getenv ("SEGFAULT_OUTPUT_NAME"); ++ name = __secure_getenv ("SEGFAULT_OUTPUT_NAME"); + if (name != NULL && name[0] != '\0') + { + int ret = access (name, R_OK | W_OK); +diff -Naur glibc-2.8-20080929.orig/elf/Versions glibc-2.8-20080929/elf/Versions +--- glibc-2.8-20080929.orig/elf/Versions 2008-03-08 05:42:26.000000000 +0000 ++++ glibc-2.8-20080929/elf/Versions 2008-10-15 00:30:49.000000000 +0000 +@@ -60,6 +60,8 @@ + _dl_make_stack_executable; + # Only here for gdb while a better method is developed. + _dl_debug_state; ++ # For sanitizing environment. ++ __libc_security_mask; + # Pointer protection. + __pointer_chk_guard; + } +diff -Naur glibc-2.8-20080929.orig/elf/dl-support.c glibc-2.8-20080929/elf/dl-support.c +--- glibc-2.8-20080929.orig/elf/dl-support.c 2007-06-20 03:18:16.000000000 +0000 ++++ glibc-2.8-20080929/elf/dl-support.c 2008-10-15 00:30:49.000000000 +0000 +@@ -163,6 +163,7 @@ + internal_function + _dl_aux_init (ElfW(auxv_t) *av) + { ++ int security_mask = 0; + int seen = 0; + uid_t uid = 0; + gid_t gid = 0; +@@ -196,25 +197,27 @@ + break; + #endif + case AT_UID: ++ if (seen & 1) break; + uid ^= av->a_un.a_val; + seen |= 1; + break; + case AT_EUID: ++ if (seen & 2) break; + uid ^= av->a_un.a_val; + seen |= 2; + break; + case AT_GID: ++ if (seen & 4) break; + gid ^= av->a_un.a_val; + seen |= 4; + break; + case AT_EGID: ++ if (seen & 8) break; + gid ^= av->a_un.a_val; + seen |= 8; + break; + case AT_SECURE: +- seen = -1; +- __libc_enable_secure = av->a_un.a_val; +- __libc_enable_secure_decided = 1; ++ security_mask |= av->a_un.a_val != 0; + break; + # ifdef DL_PLATFORM_AUXV + DL_PLATFORM_AUXV +@@ -222,7 +225,9 @@ + } + if (seen == 0xf) + { +- __libc_enable_secure = uid != 0 || gid != 0; ++ security_mask |= ((uid != 0) << 1) | ((gid != 0) << 2); ++ __libc_security_mask = security_mask; ++ __libc_enable_secure = __libc_security_mask != 0; + __libc_enable_secure_decided = 1; + } + } +@@ -239,19 +244,19 @@ + if (!_dl_pagesize) + _dl_pagesize = __getpagesize (); + +- _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; ++ _dl_verbose = *(__secure_getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; + + /* Initialize the data structures for the search paths for shared + objects. */ +- _dl_init_paths (getenv ("LD_LIBRARY_PATH")); ++ _dl_init_paths (__secure_getenv ("LD_LIBRARY_PATH")); + +- _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0'; ++ _dl_lazy = *(__secure_getenv ("LD_BIND_NOW") ?: "") == '\0'; + +- _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0'; ++ _dl_bind_not = *(__secure_getenv ("LD_BIND_NOT") ?: "") != '\0'; + +- _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; ++ _dl_dynamic_weak = *(__secure_getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; + +- _dl_profile_output = getenv ("LD_PROFILE_OUTPUT"); ++ _dl_profile_output = __secure_getenv ("LD_PROFILE_OUTPUT"); + if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0') + _dl_profile_output + = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0]; +@@ -264,6 +269,8 @@ + EXTRA_UNSECURE_ENVVARS + #endif + ; ++ static const char restricted_envvars[] = ++ RESTRICTED_ENVVARS; + const char *cp = unsecure_envvars; + + while (cp < unsecure_envvars + sizeof (unsecure_envvars)) +@@ -272,8 +279,31 @@ + cp = (const char *) __rawmemchr (cp, '\0') + 1; + } + +- if (__access ("/etc/suid-debug", F_OK) != 0) +- __unsetenv ("MALLOC_CHECK_"); ++ if (__libc_security_mask & 2) ++ { ++ static const char unsecure_uid_envvars[] = ++ UNSECURE_UID_ENVVARS; ++ ++ cp = unsecure_uid_envvars; ++ while (cp < unsecure_uid_envvars + sizeof (unsecure_uid_envvars)) ++ { ++ __unsetenv (cp); ++ cp = (const char *) __rawmemchr (cp, '\0') + 1; ++ } ++ } ++ ++ /* This loop is buggy: it will only check the first occurrence of each ++ variable (but will correctly remove all in case of a match). This ++ may be a problem if the list is later re-ordered or accessed by an ++ application with something other than the glibc getenv(). */ ++ cp = restricted_envvars; ++ while (cp < restricted_envvars + sizeof (restricted_envvars)) ++ { ++ const char *value = getenv (cp); ++ if (value && (value[0] == '.' || strchr(value, '/'))) ++ __unsetenv (cp); ++ cp = (const char *) __rawmemchr (cp, '\0') + 1; ++ } + } + + #ifdef DL_PLATFORM_INIT +diff -Naur glibc-2.8-20080929.orig/elf/dl-sysdep.c glibc-2.8-20080929/elf/dl-sysdep.c +--- glibc-2.8-20080929.orig/elf/dl-sysdep.c 2008-03-08 07:28:36.000000000 +0000 ++++ glibc-2.8-20080929/elf/dl-sysdep.c 2008-10-15 00:30:49.000000000 +0000 +@@ -54,8 +54,10 @@ + #ifdef NEED_DL_BASE_ADDR + ElfW(Addr) _dl_base_addr; + #endif +-int __libc_enable_secure attribute_relro = 0; ++int __libc_enable_secure attribute_relro = 1; + INTVARDEF(__libc_enable_secure) ++int __libc_security_mask attribute_relro = 0x7fffffff; ++INTVARDEF(__libc_security_mask) + int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion + of init-first. */ + /* This variable contains the lowest stack address ever used. */ +@@ -80,6 +82,10 @@ + # define DL_STACK_END(cookie) ((void *) (cookie)) + #endif + ++#ifdef HAVE_AUX_XID ++#undef HAVE_AUX_XID ++#endif ++ + ElfW(Addr) + _dl_sysdep_start (void **start_argptr, + void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, +@@ -89,19 +95,19 @@ + ElfW(Word) phnum = 0; + ElfW(Addr) user_entry; + ElfW(auxv_t) *av; +-#ifdef HAVE_AUX_SECURE ++ int security_mask = 0; ++#if 0 + # define set_seen(tag) (tag) /* Evaluate for the side effects. */ +-# define set_seen_secure() ((void) 0) + #else + uid_t uid = 0; + gid_t gid = 0; + unsigned int seen = 0; +-# define set_seen_secure() (seen = -1) + # ifdef HAVE_AUX_XID + # define set_seen(tag) (tag) /* Evaluate for the side effects. */ + # else + # define M(type) (1 << (type)) + # define set_seen(tag) seen |= M ((tag)->a_type) ++# define is_seen(tag) seen & M ((tag)->a_type) + # endif + #endif + #ifdef NEED_DL_SYSINFO +@@ -135,21 +141,18 @@ + _dl_base_addr = av->a_un.a_val; + break; + #endif +-#ifndef HAVE_AUX_SECURE + case AT_UID: + case AT_EUID: ++ if (is_seen (av)) break; + uid ^= av->a_un.a_val; + break; + case AT_GID: + case AT_EGID: ++ if (is_seen (av)) break; + gid ^= av->a_un.a_val; + break; +-#endif + case AT_SECURE: +-#ifndef HAVE_AUX_SECURE +- seen = -1; +-#endif +- INTUSE(__libc_enable_secure) = av->a_un.a_val; ++ security_mask |= av->a_un.a_val != 0; + break; + case AT_PLATFORM: + GLRO(dl_platform) = (void *) av->a_un.a_val; +@@ -178,8 +181,6 @@ + #endif + } + +-#ifndef HAVE_AUX_SECURE +- if (seen != -1) + { + /* Fill in the values we have not gotten from the kernel through the + auxiliary vector. */ +@@ -191,12 +192,12 @@ + SEE (GID, gid, gid); + SEE (EGID, gid, egid); + # endif +- +- /* If one of the two pairs of IDs does not match this is a setuid +- or setgid run. */ +- INTUSE(__libc_enable_secure) = uid | gid; + } +-#endif ++ /* If one of the two pairs of IDs does not match ++ this is a setuid or setgid run. */ ++ security_mask |= ((uid != 0) << 1) | ((gid != 0) << 2); ++ INTUSE(__libc_security_mask) = security_mask; ++ INTUSE(__libc_enable_secure) = security_mask != 0; + + #ifndef HAVE_AUX_PAGESIZE + if (GLRO(dl_pagesize) == 0) +diff -Naur glibc-2.8-20080929.orig/elf/enbl-secure.c glibc-2.8-20080929/elf/enbl-secure.c +--- glibc-2.8-20080929.orig/elf/enbl-secure.c 2005-12-14 08:46:07.000000000 +0000 ++++ glibc-2.8-20080929/elf/enbl-secure.c 2008-10-15 00:30:49.000000000 +0000 +@@ -27,11 +27,17 @@ + int __libc_enable_secure_decided; + /* Safest assumption, if somehow the initializer isn't run. */ + int __libc_enable_secure = 1; ++int __libc_security_mask = 0x7fffffff; + + void + __libc_init_secure (void) + { + if (__libc_enable_secure_decided == 0) +- __libc_enable_secure = (__geteuid () != __getuid () +- || __getegid () != __getgid ()); ++ { ++ __libc_security_mask = ++ ((__geteuid () != __getuid ()) << 1) | ++ ((__getegid () != __getgid ()) << 2); ++ __libc_enable_secure = __libc_security_mask != 0; ++ __libc_security_mask |= __libc_enable_secure; ++ } + } +diff -Naur glibc-2.8-20080929.orig/elf/rtld.c glibc-2.8-20080929/elf/rtld.c +--- glibc-2.8-20080929.orig/elf/rtld.c 2008-03-08 07:29:40.000000000 +0000 ++++ glibc-2.8-20080929/elf/rtld.c 2008-10-15 00:30:49.000000000 +0000 +@@ -2500,6 +2500,7 @@ + GLRO(dl_profile_output) + = &"/var/tmp\0/var/profile"[INTUSE(__libc_enable_secure) ? 9 : 0]; + ++ if (__builtin_expect (!INTUSE(__libc_enable_secure), 1)) + while ((envline = _dl_next_ld_env_entry (&runp)) != NULL) + { + size_t len = 0; +@@ -2566,8 +2567,7 @@ + case 9: + /* Test whether we want to see the content of the auxiliary + array passed up from the kernel. */ +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "SHOW_AUXV", 9) == 0) ++ if (memcmp (envline, "SHOW_AUXV", 9) == 0) + _dl_show_auxv (); + break; + +@@ -2580,8 +2580,7 @@ + + case 11: + /* Path where the binary is found. */ +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "ORIGIN_PATH", 11) == 0) ++ if (memcmp (envline, "ORIGIN_PATH", 11) == 0) + GLRO(dl_origin_path) = &envline[12]; + break; + +@@ -2600,8 +2599,7 @@ + break; + } + +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "DYNAMIC_WEAK", 12) == 0) ++ if (memcmp (envline, "DYNAMIC_WEAK", 12) == 0) + GLRO(dl_dynamic_weak) = 1; + break; + +@@ -2611,8 +2609,7 @@ + #ifdef EXTRA_LD_ENVVARS_13 + EXTRA_LD_ENVVARS_13 + #endif +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "USE_LOAD_BIAS", 13) == 0) ++ if (memcmp (envline, "USE_LOAD_BIAS", 13) == 0) + { + GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0; + break; +@@ -2624,8 +2621,7 @@ + + case 14: + /* Where to place the profiling data file. */ +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "PROFILE_OUTPUT", 14) == 0 ++ if (memcmp (envline, "PROFILE_OUTPUT", 14) == 0 + && envline[15] != '\0') + GLRO(dl_profile_output) = &envline[15]; + break; +@@ -2669,16 +2665,39 @@ + EXTRA_UNSECURE_ENVVARS + #endif + UNSECURE_ENVVARS; ++ static const char restricted_envvars[] = ++ RESTRICTED_ENVVARS; + const char *nextp; + +- nextp = unsecure_envvars; +- do ++ for (nextp = unsecure_envvars; *nextp != '\0'; ++ nextp = (char *) rawmemchr (nextp, '\0') + 1) + { + unsetenv (nextp); +- /* We could use rawmemchr but this need not be fast. */ +- nextp = (char *) (strchr) (nextp, '\0') + 1; + } +- while (*nextp != '\0'); ++ ++ if (__builtin_expect (INTUSE(__libc_security_mask) & 2, 0)) ++ { ++ static const char unsecure_uid_envvars[] = ++ UNSECURE_UID_ENVVARS; ++ ++ for (nextp = unsecure_uid_envvars; *nextp != '\0'; ++ nextp = (char *) rawmemchr (nextp, '\0') + 1) ++ { ++ unsetenv (nextp); ++ } ++ } ++ ++ /* This loop is buggy: it will only check the first occurrence of each ++ variable (but will correctly remove all in case of a match). This ++ may be a problem if the list is later re-ordered or accessed by an ++ application with something other than the glibc getenv(). */ ++ for (nextp = restricted_envvars; *nextp != '\0'; ++ nextp = (char *) rawmemchr (nextp, '\0') + 1) ++ { ++ const char *value = getenv (nextp); ++ if (value && (value[0] == '.' || strchr(value, '/'))) ++ unsetenv (nextp); ++ } + + if (__access ("/etc/suid-debug", F_OK) != 0) + { +diff -Naur glibc-2.8-20080929.orig/gmon/gmon.c glibc-2.8-20080929/gmon/gmon.c +--- glibc-2.8-20080929.orig/gmon/gmon.c 2008-03-19 06:43:31.000000000 +0000 ++++ glibc-2.8-20080929/gmon/gmon.c 2008-10-15 00:30:49.000000000 +0000 +@@ -326,8 +326,8 @@ + # define O_NOFOLLOW 0 + #endif + +- env = getenv ("GMON_OUT_PREFIX"); +- if (env != NULL && !__libc_enable_secure) ++ env = __secure_getenv ("GMON_OUT_PREFIX"); ++ if (env != NULL) + { + size_t len = strlen (env); + char buf[len + 20]; +diff -Naur glibc-2.8-20080929.orig/iconv/gconv_cache.c glibc-2.8-20080929/iconv/gconv_cache.c +--- glibc-2.8-20080929.orig/iconv/gconv_cache.c 2007-07-28 19:00:25.000000000 +0000 ++++ glibc-2.8-20080929/iconv/gconv_cache.c 2008-10-15 00:30:49.000000000 +0000 +@@ -55,7 +55,7 @@ + + /* We cannot use the cache if the GCONV_PATH environment variable is + set. */ +- __gconv_path_envvar = getenv ("GCONV_PATH"); ++ __gconv_path_envvar = __secure_getenv ("GCONV_PATH"); + if (__gconv_path_envvar != NULL) + return -1; + +diff -Naur glibc-2.8-20080929.orig/include/unistd.h glibc-2.8-20080929/include/unistd.h +--- glibc-2.8-20080929.orig/include/unistd.h 2006-07-31 05:57:52.000000000 +0000 ++++ glibc-2.8-20080929/include/unistd.h 2008-10-15 00:30:49.000000000 +0000 +@@ -142,10 +142,12 @@ + and some functions contained in the C library ignore various + environment variables that normally affect them. */ + extern int __libc_enable_secure attribute_relro; ++extern int __libc_security_mask attribute_relro; + extern int __libc_enable_secure_decided; + #ifdef IS_IN_rtld + /* XXX The #ifdef should go. */ + extern int __libc_enable_secure_internal attribute_relro attribute_hidden; ++extern int __libc_security_mask_internal attribute_relro attribute_hidden; + #endif + + +diff -Naur glibc-2.8-20080929.orig/intl/dcigettext.c glibc-2.8-20080929/intl/dcigettext.c +--- glibc-2.8-20080929.orig/intl/dcigettext.c 2008-03-31 00:37:17.000000000 +0000 ++++ glibc-2.8-20080929/intl/dcigettext.c 2008-10-15 00:30:49.000000000 +0000 +@@ -1391,7 +1391,7 @@ + + if (!output_charset_cached) + { +- const char *value = getenv ("OUTPUT_CHARSET"); ++ const char *value = __secure_getenv ("OUTPUT_CHARSET"); + + if (value != NULL && value[0] != '\0') + { +diff -Naur glibc-2.8-20080929.orig/io/getdirname.c glibc-2.8-20080929/io/getdirname.c +--- glibc-2.8-20080929.orig/io/getdirname.c 2001-07-06 04:54:53.000000000 +0000 ++++ glibc-2.8-20080929/io/getdirname.c 2008-10-15 00:30:49.000000000 +0000 +@@ -31,7 +31,7 @@ + char *pwd; + struct stat64 dotstat, pwdstat; + +- pwd = getenv ("PWD"); ++ pwd = __secure_getenv ("PWD"); + if (pwd != NULL + && stat64 (".", &dotstat) == 0 + && stat64 (pwd, &pwdstat) == 0 +diff -Naur glibc-2.8-20080929.orig/libidn/toutf8.c glibc-2.8-20080929/libidn/toutf8.c +--- glibc-2.8-20080929.orig/libidn/toutf8.c 2005-02-22 01:25:30.000000000 +0000 ++++ glibc-2.8-20080929/libidn/toutf8.c 2008-10-15 00:30:49.000000000 +0000 +@@ -74,7 +74,7 @@ + const char * + stringprep_locale_charset (void) + { +- const char *charset = getenv ("CHARSET"); /* flawfinder: ignore */ ++ const char *charset = __secure_getenv ("CHARSET"); + + if (charset && *charset) + return charset; +diff -Naur glibc-2.8-20080929.orig/locale/newlocale.c glibc-2.8-20080929/locale/newlocale.c +--- glibc-2.8-20080929.orig/locale/newlocale.c 2008-03-31 00:37:03.000000000 +0000 ++++ glibc-2.8-20080929/locale/newlocale.c 2008-10-15 00:30:49.000000000 +0000 +@@ -104,7 +104,7 @@ + locale_path = NULL; + locale_path_len = 0; + +- locpath_var = getenv ("LOCPATH"); ++ locpath_var = __secure_getenv ("LOCPATH"); + if (locpath_var != NULL && locpath_var[0] != '\0') + { + if (__argz_create_sep (locpath_var, ':', +diff -Naur glibc-2.8-20080929.orig/locale/setlocale.c glibc-2.8-20080929/locale/setlocale.c +--- glibc-2.8-20080929.orig/locale/setlocale.c 2008-03-31 00:37:03.000000000 +0000 ++++ glibc-2.8-20080929/locale/setlocale.c 2008-10-15 00:30:49.000000000 +0000 +@@ -246,7 +246,7 @@ + locale_path = NULL; + locale_path_len = 0; + +- locpath_var = getenv ("LOCPATH"); ++ locpath_var = __secure_getenv ("LOCPATH"); + if (locpath_var != NULL && locpath_var[0] != '\0') + { + if (__argz_create_sep (locpath_var, ':', +diff -Naur glibc-2.8-20080929.orig/malloc/arena.c glibc-2.8-20080929/malloc/arena.c +--- glibc-2.8-20080929.orig/malloc/arena.c 2007-12-12 00:11:27.000000000 +0000 ++++ glibc-2.8-20080929/malloc/arena.c 2008-10-15 00:30:49.000000000 +0000 +@@ -494,10 +494,10 @@ + # undef NO_STARTER + # endif + #endif ++ s = NULL; + #ifdef _LIBC + secure = __libc_enable_secure; +- s = NULL; +- if (__builtin_expect (_environ != NULL, 1)) ++ if (! secure && __builtin_expect (_environ != NULL, 1)) + { + char **runp = _environ; + char *envline; +@@ -520,26 +520,20 @@ + s = &envline[7]; + break; + case 8: +- if (! secure) +- { + if (memcmp (envline, "TOP_PAD_", 8) == 0) + mALLOPt(M_TOP_PAD, atoi(&envline[9])); + else if (memcmp (envline, "PERTURB_", 8) == 0) + mALLOPt(M_PERTURB, atoi(&envline[9])); +- } + break; + case 9: +- if (! secure && memcmp (envline, "MMAP_MAX_", 9) == 0) ++ if (memcmp (envline, "MMAP_MAX_", 9) == 0) + mALLOPt(M_MMAP_MAX, atoi(&envline[10])); + break; + case 15: +- if (! secure) +- { + if (memcmp (envline, "TRIM_THRESHOLD_", 15) == 0) + mALLOPt(M_TRIM_THRESHOLD, atoi(&envline[16])); + else if (memcmp (envline, "MMAP_THRESHOLD_", 15) == 0) + mALLOPt(M_MMAP_THRESHOLD, atoi(&envline[16])); +- } + break; + default: + break; +diff -Naur glibc-2.8-20080929.orig/malloc/memusage.c glibc-2.8-20080929/malloc/memusage.c +--- glibc-2.8-20080929.orig/malloc/memusage.c 2006-12-08 17:13:24.000000000 +0000 ++++ glibc-2.8-20080929/malloc/memusage.c 2008-10-15 00:30:49.000000000 +0000 +@@ -214,7 +214,7 @@ + static void + me (void) + { +- const char *env = getenv ("MEMUSAGE_PROG_NAME"); ++ const char *env = __secure_getenv ("MEMUSAGE_PROG_NAME"); + size_t prog_len = strlen (__progname); + + initialized = -1; +@@ -250,7 +250,7 @@ + if (!start_sp) + start_sp = GETSP (); + +- outname = getenv ("MEMUSAGE_OUTPUT"); ++ outname = __secure_getenv ("MEMUSAGE_OUTPUT"); + if (outname != NULL && outname[0] != '\0' + && (access (outname, R_OK | W_OK) == 0 || errno == ENOENT)) + { +@@ -273,7 +273,7 @@ + /* Determine the buffer size. We use the default if the + environment variable is not present. */ + buffer_size = DEFAULT_BUFFER_SIZE; +- if (getenv ("MEMUSAGE_BUFFER_SIZE") != NULL) ++ if (__secure_getenv ("MEMUSAGE_BUFFER_SIZE") != NULL) + { + buffer_size = atoi (getenv ("MEMUSAGE_BUFFER_SIZE")); + if (buffer_size == 0 || buffer_size > DEFAULT_BUFFER_SIZE) +@@ -281,7 +281,7 @@ + } + + /* Possibly enable timer-based stack pointer retrieval. */ +- if (getenv ("MEMUSAGE_NO_TIMER") == NULL) ++ if (__secure_getenv ("MEMUSAGE_NO_TIMER") == NULL) + { + struct sigaction act; + +@@ -302,7 +302,7 @@ + } + } + +- if (!not_me && getenv ("MEMUSAGE_TRACE_MMAP") != NULL) ++ if (!not_me && __secure_getenv ("MEMUSAGE_TRACE_MMAP") != NULL) + trace_mmap = true; + } + } +diff -Naur glibc-2.8-20080929.orig/nis/nis_defaults.c glibc-2.8-20080929/nis/nis_defaults.c +--- glibc-2.8-20080929.orig/nis/nis_defaults.c 2006-10-11 16:22:34.000000000 +0000 ++++ glibc-2.8-20080929/nis/nis_defaults.c 2008-10-15 00:30:49.000000000 +0000 +@@ -358,7 +358,7 @@ + + char *cptr = defaults; + if (cptr == NULL) +- cptr = getenv ("NIS_DEFAULTS"); ++ cptr = __secure_getenv ("NIS_DEFAULTS"); + + if (cptr != NULL) + { +@@ -385,7 +385,7 @@ + + char *cptr = defaults; + if (cptr == NULL) +- cptr = getenv ("NIS_DEFAULTS"); ++ cptr = __secure_getenv ("NIS_DEFAULTS"); + + if (cptr != NULL) + { +@@ -417,7 +417,7 @@ + return searchttl (defaults); + } + +- cptr = getenv ("NIS_DEFAULTS"); ++ cptr = __secure_getenv ("NIS_DEFAULTS"); + if (cptr == NULL) + return DEFAULT_TTL; + +@@ -445,7 +445,7 @@ + result = searchaccess (param, result); + else + { +- cptr = getenv ("NIS_DEFAULTS"); ++ cptr = __secure_getenv ("NIS_DEFAULTS"); + if (cptr != NULL && strstr (cptr, "access=") != NULL) + result = searchaccess (cptr, result); + } +diff -Naur glibc-2.8-20080929.orig/nis/nis_local_names.c glibc-2.8-20080929/nis/nis_local_names.c +--- glibc-2.8-20080929.orig/nis/nis_local_names.c 2006-04-07 06:52:01.000000000 +0000 ++++ glibc-2.8-20080929/nis/nis_local_names.c 2008-10-15 00:30:49.000000000 +0000 +@@ -30,7 +30,7 @@ + + char *cptr; + if (__nisgroup[0] == '\0' +- && (cptr = getenv ("NIS_GROUP")) != NULL ++ && (cptr = __secure_getenv ("NIS_GROUP")) != NULL + && strlen (cptr) < NIS_MAXNAMELEN) + { + char *cp = stpcpy (__nisgroup, cptr); +diff -Naur glibc-2.8-20080929.orig/nis/nis_subr.c glibc-2.8-20080929/nis/nis_subr.c +--- glibc-2.8-20080929.orig/nis/nis_subr.c 2007-07-28 20:43:36.000000000 +0000 ++++ glibc-2.8-20080929/nis/nis_subr.c 2008-10-15 00:30:49.000000000 +0000 +@@ -178,7 +178,7 @@ + } + + /* Get the search path, where we have to search "name" */ +- path = getenv ("NIS_PATH"); ++ path = __secure_getenv ("NIS_PATH"); + if (path == NULL) + path = strdupa ("$"); + else +diff -Naur glibc-2.8-20080929.orig/posix/execvp.c glibc-2.8-20080929/posix/execvp.c +--- glibc-2.8-20080929.orig/posix/execvp.c 2007-01-03 23:01:15.000000000 +0000 ++++ glibc-2.8-20080929/posix/execvp.c 2008-10-15 00:30:49.000000000 +0000 +@@ -90,7 +90,7 @@ + { + size_t pathlen; + size_t alloclen = 0; +- char *path = getenv ("PATH"); ++ char *path = __secure_getenv ("PATH"); + if (path == NULL) + { + pathlen = confstr (_CS_PATH, (char *) NULL, 0); +@@ -116,11 +116,11 @@ + if (path == NULL) + { + /* There is no `PATH' in the environment. +- The default search path is the current directory +- followed by the path `confstr' returns for `_CS_PATH'. */ ++ The default search path is what `confstr' returns ++ for `_CS_PATH'. */ + path = name + pathlen + len + 1; +- path[0] = ':'; +- (void) confstr (_CS_PATH, path + 1, pathlen); ++ path[0] = '\0'; ++ (void) confstr (_CS_PATH, path, pathlen); + } + + /* Copy the file name at the top. */ +diff -Naur glibc-2.8-20080929.orig/posix/glob.c glibc-2.8-20080929/posix/glob.c +--- glibc-2.8-20080929.orig/posix/glob.c 2007-10-15 04:59:03.000000000 +0000 ++++ glibc-2.8-20080929/posix/glob.c 2008-10-15 00:30:49.000000000 +0000 +@@ -557,7 +557,7 @@ + && (dirname[2] == '\0' || dirname[2] == '/'))) + { + /* Look up home directory. */ +- const char *home_dir = getenv ("HOME"); ++ const char *home_dir = __secure_getenv ("HOME"); + # ifdef _AMIGA + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = "SYS:"; +diff -Naur glibc-2.8-20080929.orig/posix/wordexp.c glibc-2.8-20080929/posix/wordexp.c +--- glibc-2.8-20080929.orig/posix/wordexp.c 2007-01-25 00:43:39.000000000 +0000 ++++ glibc-2.8-20080929/posix/wordexp.c 2008-10-15 00:30:49.000000000 +0000 +@@ -320,7 +320,7 @@ + results are unspecified. We do a lookup on the uid if + HOME is unset. */ + +- home = getenv ("HOME"); ++ home = __secure_getenv ("HOME"); + if (home != NULL) + { + *word = w_addstr (*word, word_length, max_length, home); +@@ -1493,7 +1493,7 @@ + } + } + else +- value = getenv (env); ++ value = __secure_getenv (env); + + if (value == NULL && (flags & WRDE_UNDEF)) + { +@@ -2262,7 +2262,7 @@ + /* Find out what the field separators are. + * There are two types: whitespace and non-whitespace. + */ +- ifs = getenv ("IFS"); ++ ifs = __secure_getenv ("IFS"); + + if (ifs == NULL) + /* IFS unset - use <space><tab><newline>. */ +diff -Naur glibc-2.8-20080929.orig/resolv/res_hconf.c glibc-2.8-20080929/resolv/res_hconf.c +--- glibc-2.8-20080929.orig/resolv/res_hconf.c 2007-11-23 03:03:31.000000000 +0000 ++++ glibc-2.8-20080929/resolv/res_hconf.c 2008-10-15 00:30:49.000000000 +0000 +@@ -304,7 +304,7 @@ + + memset (&_res_hconf, '\0', sizeof (_res_hconf)); + +- hconf_name = getenv (ENV_HOSTCONF); ++ hconf_name = __secure_getenv (ENV_HOSTCONF); + if (hconf_name == NULL) + hconf_name = _PATH_HOSTCONF; + +@@ -323,23 +323,23 @@ + fclose (fp); + } + +- envval = getenv (ENV_SPOOF); ++ envval = __secure_getenv (ENV_SPOOF); + if (envval) + arg_spoof (ENV_SPOOF, 1, envval); + +- envval = getenv (ENV_MULTI); ++ envval = __secure_getenv (ENV_MULTI); + if (envval) + arg_bool (ENV_MULTI, 1, envval, HCONF_FLAG_MULTI); + +- envval = getenv (ENV_REORDER); ++ envval = __secure_getenv (ENV_REORDER); + if (envval) + arg_bool (ENV_REORDER, 1, envval, HCONF_FLAG_REORDER); + +- envval = getenv (ENV_TRIM_ADD); ++ envval = __secure_getenv (ENV_TRIM_ADD); + if (envval) + arg_trimdomain_list (ENV_TRIM_ADD, 1, envval); + +- envval = getenv (ENV_TRIM_OVERR); ++ envval = __secure_getenv (ENV_TRIM_OVERR); + if (envval) + { + _res_hconf.num_trimdomains = 0; +diff -Naur glibc-2.8-20080929.orig/resolv/res_init.c glibc-2.8-20080929/resolv/res_init.c +--- glibc-2.8-20080929.orig/resolv/res_init.c 2008-04-07 17:20:25.000000000 +0000 ++++ glibc-2.8-20080929/resolv/res_init.c 2008-10-15 00:30:49.000000000 +0000 +@@ -201,7 +201,7 @@ + #endif + + /* Allow user to override the local domain definition */ +- if ((cp = getenv("LOCALDOMAIN")) != NULL) { ++ if ((cp = __secure_getenv("LOCALDOMAIN")) != NULL) { + (void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); + statp->defdname[sizeof(statp->defdname) - 1] = '\0'; + haveenv++; +@@ -470,7 +470,7 @@ + #endif /* !RFC1535 */ + } + +- if ((cp = getenv("RES_OPTIONS")) != NULL) ++ if ((cp = __secure_getenv("RES_OPTIONS")) != NULL) + res_setoptions(statp, cp, "env"); + statp->options |= RES_INIT; + return (0); +diff -Naur glibc-2.8-20080929.orig/resolv/res_query.c glibc-2.8-20080929/resolv/res_query.c +--- glibc-2.8-20080929.orig/resolv/res_query.c 2007-02-09 23:43:25.000000000 +0000 ++++ glibc-2.8-20080929/resolv/res_query.c 2008-10-15 00:30:49.000000000 +0000 +@@ -474,7 +474,7 @@ + + if (statp->options & RES_NOALIASES) + return (NULL); +- file = getenv("HOSTALIASES"); ++ file = __secure_getenv("HOSTALIASES"); + if (file == NULL || (fp = fopen(file, "r")) == NULL) + return (NULL); + setbuf(fp, NULL); +diff -Naur glibc-2.8-20080929.orig/stdlib/fmtmsg.c glibc-2.8-20080929/stdlib/fmtmsg.c +--- glibc-2.8-20080929.orig/stdlib/fmtmsg.c 2006-05-15 18:41:18.000000000 +0000 ++++ glibc-2.8-20080929/stdlib/fmtmsg.c 2008-10-15 00:30:49.000000000 +0000 +@@ -205,8 +205,8 @@ + static void + init (void) + { +- const char *msgverb_var = getenv ("MSGVERB"); +- const char *sevlevel_var = getenv ("SEV_LEVEL"); ++ const char *msgverb_var = __secure_getenv ("MSGVERB"); ++ const char *sevlevel_var = __secure_getenv ("SEV_LEVEL"); + + if (msgverb_var != NULL && msgverb_var[0] != '\0') + { +diff -Naur glibc-2.8-20080929.orig/sunrpc/rpc_svcout.c glibc-2.8-20080929/sunrpc/rpc_svcout.c +--- glibc-2.8-20080929.orig/sunrpc/rpc_svcout.c 2005-11-21 15:43:03.000000000 +0000 ++++ glibc-2.8-20080929/sunrpc/rpc_svcout.c 2008-10-15 00:30:49.000000000 +0000 +@@ -897,7 +897,7 @@ + f_print (fout, "\t\t_rpcpmstart = 1;\n"); + if (logflag) + open_log_file (infile, "\t\t"); +- f_print (fout, "\t\tif ((netid = getenv("NLSPROVIDER")) == NULL) {\n"); ++ f_print (fout, "\t\tif ((netid = __secure_getenv("NLSPROVIDER")) == NULL) {\n"); + sprintf (_errbuf, "cannot get transport name"); + print_err_message ("\t\t\t"); + f_print (fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n"); +diff -Naur glibc-2.8-20080929.orig/sysdeps/generic/unsecvars.h glibc-2.8-20080929/sysdeps/generic/unsecvars.h +--- glibc-2.8-20080929.orig/sysdeps/generic/unsecvars.h 2006-10-11 16:24:05.000000000 +0000 ++++ glibc-2.8-20080929/sysdeps/generic/unsecvars.h 2008-10-15 00:32:09.000000000 +0000 +@@ -2,25 +2,87 @@ + all stuffed in a single string which means they have to be terminated + with a '\0' explicitly. */ + #define UNSECURE_ENVVARS \ +- "GCONV_PATH\0" \ +- "GETCONF_DIR\0" \ +- "HOSTALIASES\0" \ +- "LD_AUDIT\0" \ +- "LD_DEBUG\0" \ +- "LD_DEBUG_OUTPUT\0" \ +- "LD_DYNAMIC_WEAK\0" \ +- "LD_LIBRARY_PATH\0" \ +- "LD_ORIGIN_PATH\0" \ +- "LD_PRELOAD\0" \ +- "LD_PROFILE\0" \ +- "LD_SHOW_AUXV\0" \ +- "LD_USE_LOAD_BIAS\0" \ +- "LOCALDOMAIN\0" \ +- "LOCPATH\0" \ +- "MALLOC_TRACE\0" \ +- "NIS_PATH\0" \ +- "NLSPATH\0" \ +- "RESOLV_HOST_CONF\0" \ +- "RES_OPTIONS\0" \ +- "TMPDIR\0" \ ++ "ARGP_HELP_FMT\0" \ ++ "DATEMSK\0" \ ++ "GCONV_PATH\0" \ ++ "GETCONF_DIR\0" \ ++ "GMON_OUT_PREFIX\0" \ ++ "HESIOD_CONFIG\0" \ ++ "HES_DOMAIN\0" \ ++ "HOSTALIASES\0" \ ++ "LD_AUDIT\0" \ ++ "LD_BIND_NOT\0" \ ++ "LD_BIND_NOW\0" \ ++ "LD_DEBUG\0" \ ++ "LD_DEBUG_OUTPUT\0" \ ++ "LD_DYNAMIC_WEAK\0" \ ++ "LD_HWCAP_MASK\0" \ ++ "LD_LIBRARY_PATH\0" \ ++ "LD_ORIGIN_PATH\0" \ ++ "LD_POINTER_GUARD\0" \ ++ "LD_PRELOAD\0" \ ++ "LD_PROFILE\0" \ ++ "LD_PROFILE_OUTPUT\0" \ ++ "LD_SHOW_AUXV\0" \ ++ "LD_TRACE_LOADED_OBJECTS\0" \ ++ "LD_TRACE_PRELINKING\0" \ ++ "LD_USE_LOAD_BIAS\0" \ ++ "LD_VERBOSE\0" \ ++ "LD_WARN\0" \ ++ "LOCALDOMAIN\0" \ ++ "LOCPATH\0" \ ++ "MALLOC_CHECK_\0" \ ++ "MALLOC_MMAP_MAX_\0" \ ++ "MALLOC_MMAP_THRESHOLD_\0" \ ++ "MALLOC_PERTURB_\0" \ ++ "MALLOC_TOP_PAD_\0" \ ++ "MALLOC_TRACE\0" \ ++ "MALLOC_TRIM_THRESHOLD_\0" \ ++ "MEMUSAGE_BUFFER_SIZE\0" \ ++ "MEMUSAGE_NO_TIMER\0" \ ++ "MEMUSAGE_OUTPUT\0" \ ++ "MEMUSAGE_PROG_NAME\0" \ ++ "MEMUSAGE_TRACE_MMAP\0" \ ++ "MSGVERB\0" \ ++ "MUDFLAP_OPTIONS\0" \ ++ "NIS_DEFAULTS\0" \ ++ "NIS_GROUP\0" \ ++ "NIS_PATH\0" \ ++ "NLSPATH\0" \ ++ "PCPROFILE_OUTPUT\0" \ ++ "POSIXLY_CORRECT\0" \ ++ "PWD\0" \ ++ "RESOLV_ADD_TRIM_DOMAINS\0" \ ++ "RESOLV_HOST_CONF\0" \ ++ "RESOLV_MULTI\0" \ ++ "RESOLV_OVERRIDE_TRIM_DOMAINS\0" \ ++ "RESOLV_REORDER\0" \ ++ "RESOLV_SPOOF_CHECK\0" \ ++ "RES_OPTIONS\0" \ ++ "SEGFAULT_OUTPUT_NAME\0" \ ++ "SEGFAULT_SIGNALS\0" \ ++ "SEGFAULT_USE_ALTSTACK\0" \ ++ "SEV_LEVEL\0" \ ++ "TZ\0" \ + "TZDIR\0" ++ ++#define UNSECURE_UID_ENVVARS \ ++ "TMPDIR\0" ++ ++#define RESTRICTED_ENVVARS \ ++ "LANG\0" \ ++ "LANGUAGE\0" \ ++ "LC_ADDRESS\0" \ ++ "LC_ALL\0" \ ++ "LC_COLLATE\0" \ ++ "LC_CTYPE\0" \ ++ "LC_IDENTIFICATION\0" \ ++ "LC_MEASUREMENT\0" \ ++ "LC_MESSAGES\0" \ ++ "LC_MONETARY\0" \ ++ "LC_NAME\0" \ ++ "LC_NUMERIC\0" \ ++ "LC_PAPER\0" \ ++ "LC_TELEPHONE\0" \ ++ "LC_TIME\0" \ ++ "LC_XXX\0" +diff -Naur glibc-2.8-20080929.orig/sysdeps/posix/spawni.c glibc-2.8-20080929/sysdeps/posix/spawni.c +--- glibc-2.8-20080929.orig/sysdeps/posix/spawni.c 2006-06-04 22:16:05.000000000 +0000 ++++ glibc-2.8-20080929/sysdeps/posix/spawni.c 2008-10-15 00:30:49.000000000 +0000 +@@ -227,16 +227,15 @@ + } + + /* We have to search for FILE on the path. */ +- path = getenv ("PATH"); ++ path = __secure_getenv ("PATH"); + if (path == NULL) + { + /* There is no `PATH' in the environment. +- The default search path is the current directory +- followed by the path `confstr' returns for `_CS_PATH'. */ ++ The default search path is ehat `confstr' returns ++ for `_CS_PATH'. */ + len = confstr (_CS_PATH, (char *) NULL, 0); +- path = (char *) __alloca (1 + len); +- path[0] = ':'; +- (void) confstr (_CS_PATH, path + 1, len); ++ path = (char *) __alloca (len); ++ (void) confstr (_CS_PATH, path, len); + } + + len = strlen (file) + 1; +diff -Naur glibc-2.8-20080929.orig/sysdeps/unix/sysv/linux/dl-librecon.h glibc-2.8-20080929/sysdeps/unix/sysv/linux/dl-librecon.h +--- glibc-2.8-20080929.orig/sysdeps/unix/sysv/linux/dl-librecon.h 2004-03-05 10:14:48.000000000 +0000 ++++ glibc-2.8-20080929/sysdeps/unix/sysv/linux/dl-librecon.h 2008-10-15 00:30:49.000000000 +0000 +@@ -53,7 +53,7 @@ + + #define DL_OSVERSION_INIT \ + do { \ +- char *assume_kernel = getenv ("LD_ASSUME_KERNEL"); \ ++ char *assume_kernel = __secure_getenv ("LD_ASSUME_KERNEL"); \ + if (assume_kernel) \ + _dl_osversion_init (assume_kernel); \ + } while (0) +diff -Naur glibc-2.8-20080929.orig/sysdeps/unix/sysv/linux/i386/dl-librecon.h glibc-2.8-20080929/sysdeps/unix/sysv/linux/i386/dl-librecon.h +--- glibc-2.8-20080929.orig/sysdeps/unix/sysv/linux/i386/dl-librecon.h 2004-10-14 01:53:55.000000000 +0000 ++++ glibc-2.8-20080929/sysdeps/unix/sysv/linux/i386/dl-librecon.h 2008-10-15 00:30:49.000000000 +0000 +@@ -57,6 +57,7 @@ + /* Extra unsecure variables. The names are all stuffed in a single + string which means they have to be terminated with a '\0' explicitly. */ + #define EXTRA_UNSECURE_ENVVARS \ ++ "LD_LIBRARY_VERSION\0" \ + "LD_AOUT_LIBRARY_PATH\0" \ + "LD_AOUT_PRELOAD\0" + +diff -Naur glibc-2.8-20080929.orig/time/getdate.c glibc-2.8-20080929/time/getdate.c +--- glibc-2.8-20080929.orig/time/getdate.c 2007-12-10 01:40:43.000000000 +0000 ++++ glibc-2.8-20080929/time/getdate.c 2008-10-15 00:30:49.000000000 +0000 +@@ -115,7 +115,7 @@ + struct stat64 st; + int mday_ok = 0; + +- datemsk = getenv ("DATEMSK"); ++ datemsk = __secure_getenv ("DATEMSK"); + if (datemsk == NULL || *datemsk == '\0') + return 1; + +diff -Naur glibc-2.8-20080929.orig/time/tzfile.c glibc-2.8-20080929/time/tzfile.c +--- glibc-2.8-20080929.orig/time/tzfile.c 2007-11-06 01:03:43.000000000 +0000 ++++ glibc-2.8-20080929/time/tzfile.c 2008-10-15 00:30:49.000000000 +0000 +@@ -149,7 +149,7 @@ + unsigned int len, tzdir_len; + char *new, *tmp; + +- tzdir = getenv ("TZDIR"); ++ tzdir = __secure_getenv ("TZDIR"); + if (tzdir == NULL || *tzdir == '\0') + { + tzdir = default_tzdir; +diff -Naur glibc-2.8-20080929.orig/time/tzset.c glibc-2.8-20080929/time/tzset.c +--- glibc-2.8-20080929.orig/time/tzset.c 2008-03-19 06:43:34.000000000 +0000 ++++ glibc-2.8-20080929/time/tzset.c 2008-10-15 00:30:49.000000000 +0000 +@@ -383,8 +383,11 @@ + return; + is_initialized = 1; + +- /* Examine the TZ environment variable. */ +- tz = getenv ("TZ"); ++ /* Examine the TZ environment variable. This doesn't really have to be ++ a __secure_getenv() call as __tzfile_read() tries to only read files ++ found under a trusted directory, but this helps reduce the amount of ++ security-critical code. */ ++ tz = __secure_getenv ("TZ"); + if (tz == NULL && !explicit) + /* Use the site-wide default. This is a file name which means we + would not see changes to the file if we compare only the file diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-strlcpy_strlcat-1.patch b/pkgs/core/glibc/patches/glibc-2.10.1-strlcpy_strlcat-1.patch new file mode 100644 index 0000000..5cbacbf --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-strlcpy_strlcat-1.patch @@ -0,0 +1,349 @@ +diff -Naur glibc-2.7.orig/manual/strlcpy.3 glibc-2.7/manual/strlcpy.3 +--- glibc-2.7.orig/manual/strlcpy.3 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.7/manual/strlcpy.3 2008-01-19 23:13:56.000000000 +0000 +@@ -0,0 +1,186 @@ ++." $OpenBSD: strlcpy.3,v 1.18 2005/08/06 03:24:19 jaredy Exp $ ++." ++." Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com> ++." ++." Permission to use, copy, modify, and distribute this software for any ++." purpose with or without fee is hereby granted, provided that the above ++." copyright notice and this permission notice appear in all copies. ++." ++." THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++." WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++." MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++." ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++." WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++." ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++." OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++." ++.Dd June 22, 1998 ++.Dt STRLCPY 3 ++.Os ++.Sh NAME ++.Nm strlcpy , ++.Nm strlcat ++.Nd size-bounded string copying and concatenation ++.Sh SYNOPSIS ++.Fd #include <string.h> ++.Ft size_t ++.Fn strlcpy "char *dst" "const char *src" "size_t size" ++.Ft size_t ++.Fn strlcat "char *dst" "const char *src" "size_t size" ++.Sh DESCRIPTION ++The ++.Fn strlcpy ++and ++.Fn strlcat ++functions copy and concatenate strings respectively. ++They are designed ++to be safer, more consistent, and less error prone replacements for ++.Xr strncpy 3 ++and ++.Xr strncat 3 . ++Unlike those functions, ++.Fn strlcpy ++and ++.Fn strlcat ++take the full size of the buffer (not just the length) and guarantee to ++NUL-terminate the result (as long as ++.Fa size ++is larger than 0 or, in the case of ++.Fn strlcat , ++as long as there is at least one byte free in ++.Fa dst ) . ++Note that a byte for the NUL should be included in ++.Fa size . ++Also note that ++.Fn strlcpy ++and ++.Fn strlcat ++only operate on true ++.Dq C ++strings. ++This means that for ++.Fn strlcpy ++.Fa src ++must be NUL-terminated and for ++.Fn strlcat ++both ++.Fa src ++and ++.Fa dst ++must be NUL-terminated. ++.Pp ++The ++.Fn strlcpy ++function copies up to ++.Fa size ++- 1 characters from the NUL-terminated string ++.Fa src ++to ++.Fa dst , ++NUL-terminating the result. ++.Pp ++The ++.Fn strlcat ++function appends the NUL-terminated string ++.Fa src ++to the end of ++.Fa dst . ++It will append at most ++.Fa size ++- strlen(dst) - 1 bytes, NUL-terminating the result. ++.Sh RETURN VALUES ++The ++.Fn strlcpy ++and ++.Fn strlcat ++functions return the total length of the string they tried to create. ++For ++.Fn strlcpy ++that means the length of ++.Fa src . ++For ++.Fn strlcat ++that means the initial length of ++.Fa dst ++plus ++the length of ++.Fa src . ++While this may seem somewhat confusing, it was done to make ++truncation detection simple. ++.Pp ++Note, however, that if ++.Fn strlcat ++traverses ++.Fa size ++characters without finding a NUL, the length of the string is considered ++to be ++.Fa size ++and the destination string will not be NUL-terminated (since there was ++no space for the NUL). ++This keeps ++.Fn strlcat ++from running off the end of a string. ++In practice this should not happen (as it means that either ++.Fa size ++is incorrect or that ++.Fa dst ++is not a proper ++.Dq C ++string). ++The check exists to prevent potential security problems in incorrect code. ++.Sh EXAMPLES ++The following code fragment illustrates the simple case: ++.Bd -literal -offset indent ++char *s, *p, buf[BUFSIZ]; ++ ++&... ++ ++(void)strlcpy(buf, s, sizeof(buf)); ++(void)strlcat(buf, p, sizeof(buf)); ++.Ed ++.Pp ++To detect truncation, perhaps while building a pathname, something ++like the following might be used: ++.Bd -literal -offset indent ++char *dir, *file, pname[MAXPATHLEN]; ++ ++&... ++ ++if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname)) ++ goto toolong; ++if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) ++ goto toolong; ++.Ed ++.Pp ++Since it is known how many characters were copied the first time, things ++can be sped up a bit by using a copy instead of an append: ++.Bd -literal -offset indent ++char *dir, *file, pname[MAXPATHLEN]; ++size_t n; ++ ++&... ++ ++n = strlcpy(pname, dir, sizeof(pname)); ++if (n >= sizeof(pname)) ++ goto toolong; ++if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n) ++ goto toolong; ++.Ed ++.Pp ++However, one may question the validity of such optimizations, as they ++defeat the whole purpose of ++.Fn strlcpy ++and ++.Fn strlcat . ++As a matter of fact, the first version of this manual page got it wrong. ++.Sh SEE ALSO ++.Xr snprintf 3 , ++.Xr strncat 3 , ++.Xr strncpy 3 ++.Sh HISTORY ++The ++.Fn strlcpy ++and ++.Fn strlcat ++functions first appeared in ++.Ox 2.4 . +diff -Naur glibc-2.7.orig/string/Makefile glibc-2.7/string/Makefile +--- glibc-2.7.orig/string/Makefile 2007-02-01 16:10:11.000000000 +0000 ++++ glibc-2.7/string/Makefile 2008-01-19 23:14:48.000000000 +0000 +@@ -40,7 +40,12 @@ + addsep replace) \ + envz basename \ + strcoll_l strxfrm_l string-inlines memrchr \ +- xpg-strerror strerror_l ++ xpg-strerror strerror_l strlcat strlcpy ++ ++# These routines will be omitted from the libc shared object. ++# Instead the static object files will be included in a special archive ++# linked against when the shared library will be used. ++static-only-routines = strlcat strlcpy + + # Gcc internally generates calls to unbounded memcpy and memset + # for -fbounded-pointer compiles. Glibc uses memchr for explicit checks. +diff -Naur glibc-2.7.orig/string/string.h glibc-2.7/string/string.h +--- glibc-2.7.orig/string/string.h 2007-09-15 02:35:08.000000000 +0000 ++++ glibc-2.7/string/string.h 2008-01-19 23:13:56.000000000 +0000 +@@ -354,6 +354,24 @@ + extern char *strsep (char **__restrict __stringp, + __const char *__restrict __delim) + __THROW __nonnull ((1, 2)); ++ ++/* ++ * Appends __src to string __dst of size __n (unlike strncat, __n is the ++ * full size of __dst, not space left). At most __n-1 characters ++ * will be copied. Always NUL terminates (unless __n <= strlen(__dst)). ++ * Returns strlen(__src) + MIN(__n, strlen(initial __dst)). ++ * If retval >= __n, truncation occurred. ++ */ ++extern size_t strlcat (char *__dst, __const char *__src, size_t __n) ++ __THROW __nonnull ((1, 2)); ++ ++/* ++ * Copy __src to string __dst of size __n. At most __n-1 characters ++ * will be copied. Always NUL terminates (unless __n == 0). ++ * Returns strlen(__src); if retval >= __n, truncation occurred. ++ */ ++extern size_t strlcpy (char *__dst, __const char *__src, size_t __n) ++ __THROW __nonnull ((1, 2)); + #endif + + #ifdef __USE_GNU +diff -Naur glibc-2.7.orig/string/strlcat.c glibc-2.7/string/strlcat.c +--- glibc-2.7.orig/string/strlcat.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.7/string/strlcat.c 2008-01-19 23:13:56.000000000 +0000 +@@ -0,0 +1,55 @@ ++/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ ++ ++/* ++ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include <sys/types.h> ++#include <string.h> ++ ++/* ++ * Appends src to string dst of size siz (unlike strncat, siz is the ++ * full size of dst, not space left). At most siz-1 characters ++ * will be copied. Always NUL terminates (unless siz <= strlen(dst)). ++ * Returns strlen(src) + MIN(siz, strlen(initial dst)). ++ * If retval >= siz, truncation occurred. ++ */ ++size_t ++strlcat(char *dst, const char *src, size_t siz) ++{ ++ char *d = dst; ++ const char *s = src; ++ size_t n = siz; ++ size_t dlen; ++ ++ /* Find the end of dst and adjust bytes left but don't go past end */ ++ while (n-- != 0 && *d != '\0') ++ d++; ++ dlen = d - dst; ++ n = siz - dlen; ++ ++ if (n == 0) ++ return(dlen + strlen(s)); ++ while (*s != '\0') { ++ if (n != 1) { ++ *d++ = *s; ++ n--; ++ } ++ s++; ++ } ++ *d = '\0'; ++ ++ return(dlen + (s - src)); /* count does not include NUL */ ++} +diff -Naur glibc-2.7.orig/string/strlcpy.c glibc-2.7/string/strlcpy.c +--- glibc-2.7.orig/string/strlcpy.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.7/string/strlcpy.c 2008-01-19 23:13:56.000000000 +0000 +@@ -0,0 +1,51 @@ ++/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ ++ ++/* ++ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include <sys/types.h> ++#include <string.h> ++ ++/* ++ * Copy src to string dst of size siz. At most siz-1 characters ++ * will be copied. Always NUL terminates (unless siz == 0). ++ * Returns strlen(src); if retval >= siz, truncation occurred. ++ */ ++size_t ++strlcpy(char *dst, const char *src, size_t siz) ++{ ++ char *d = dst; ++ const char *s = src; ++ size_t n = siz; ++ ++ /* Copy as many bytes as will fit */ ++ if (n != 0) { ++ while (--n != 0) { ++ if ((*d++ = *s++) == '\0') ++ break; ++ } ++ } ++ ++ /* Not enough room in dst, add NUL and traverse rest of src */ ++ if (n == 0) { ++ if (siz != 0) ++ *d = '\0'; /* NUL-terminate dst */ ++ while (*s++) ++ ; ++ } ++ ++ return(s - src - 1); /* count does not include NUL */ ++} diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-undefine-__i686.patch b/pkgs/core/glibc/patches/glibc-2.10.1-undefine-__i686.patch new file mode 100644 index 0000000..ce0ebd4 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-undefine-__i686.patch @@ -0,0 +1,44 @@ +If gcc is configured to generate i686 code or better by default (like +when using the --with-arch=pentium3 configure option), then the __i686 +macro will always be defined automatically and thus screw up the +compilation of some .S files. +http://bugs.gentoo.org/131108 + +2006-04-25 Mike Frysinger <vapier@gentoo.org> + + * sysdeps/i386/sysdep.h (__i686): Undefine. + +--- glibc-2.10.1/sysdeps/i386/sysdep.h ++++ glibc-2.10.1/sysdeps/i386/sysdep.h +@@ -17,6 +17,14 @@ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + ++/* ++ * When building for i686 targets or better, gcc automatically defines ++ * '__i686' to '1' for us which causes trouble when using section names ++ * like '__i686.get_pc_thunk.reg'. Since we check for __i686__ in the ++ * code, killing '__i686' shouldn't be a problem. ++ */ ++#undef __i686 ++ + #include <sysdeps/generic/sysdep.h> + + #ifdef __ASSEMBLER__ + +2006-04-25 Mike Frysinger <vapier@gentoo.org> + + * sysdeps/pthread/pt-initfini.c: Include sysdep.h. + +--- glibc-2.10.1/nptl/sysdeps/pthread/pt-initfini.c ++++ glibc-2.10.1/nptl/sysdeps/pthread/pt-initfini.c +@@ -45,6 +45,9 @@ + /* Embed an #include to pull in the alignment and .end directives. */ + asm ("\n#include "defs.h""); + ++/* Embed an #include to pull in asm settings. */ ++asm ("\n#include <sysdep.h>"); ++ + /* The initial common code ends here. */ + asm ("\n/*@HEADER_ENDS*/"); + diff --git a/pkgs/core/glibc/patches/glibc-2.11.1-hardened-pie.patch b/pkgs/core/glibc/patches/glibc-2.11.1-hardened-pie.patch new file mode 100644 index 0000000..5816133 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.11.1-hardened-pie.patch @@ -0,0 +1,38 @@ +2009-11-08 Magnus Granberg <zorry@ume.nu> + + bug #292139 + * Makeconfig +link-pie: set +link to +link-pie + +link-static: change $(static-start-installed-name) to S$(static-start-installed-name) + +prector: set +prector to +prectorS +postctor: set +postctor to +postctorS + + +--- a/Makeconfig 2009-11-06 16:39:18.000000000 +0100 ++++ b/Makeconfig 2009-11-08 03:14:45.000000000 +0100 +@@ -447,11 +447,12 @@ + $(common-objpfx)libc% $(+postinit),$^) \ + $(link-extra-libs) $(link-libc) $(+postctorS) $(+postinit) + endif +++link = $(+link-pie) + # Command for statically linking programs with the C library. + ifndef +link-static + +link-static = $(CC) -nostdlib -nostartfiles -static -o $@ \ + $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ +- $(addprefix $(csu-objpfx),$(static-start-installed-name)) \ ++ $(addprefix $(csu-objpfx),S$(static-start-installed-name)) \ + $(+preinit) $(+prector) \ + $(filter-out $(addprefix $(csu-objpfx),start.o \ + $(start-installed-name))\ +@@ -549,11 +550,10 @@ + ifeq ($(elf),yes) + +preinit = $(addprefix $(csu-objpfx),crti.o) + +postinit = $(addprefix $(csu-objpfx),crtn.o) +-+prector = `$(CC) --print-file-name=crtbegin.o` +-+postctor = `$(CC) --print-file-name=crtend.o` +-# Variants of the two previous definitions for linking PIE programs. + +prectorS = `$(CC) --print-file-name=crtbeginS.o` + +postctorS = `$(CC) --print-file-name=crtendS.o` +++prector = $(+prectorS) +++postctor = $(+postctorS) + +interp = $(addprefix $(elf-objpfx),interp.os) + endif + csu-objpfx = $(common-objpfx)csu/ diff --git a/pkgs/core/glibc/patches/glibc-2.11.1-mktemp_urandom.patch b/pkgs/core/glibc/patches/glibc-2.11.1-mktemp_urandom.patch new file mode 100644 index 0000000..5d1bafc --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.11.1-mktemp_urandom.patch @@ -0,0 +1,161 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2010-02-19 +Initial Package Version: 2.11.1 +Upstream Status: Not Submitted +Origin: Based on http://www.uclibc.org/cgi-bin/viewcvs.cgi/trunk/uClibc/libc/ + misc/internals/tempname.c?rev=8887&r1=5747&r2=8887 +Description: +Use /dev/urandom exclusively with __gen_tempname(), for the mktemp/tmpnam +family, instead of hp-timing, gettimeofday(), or getpid(). return -1 if +/dev/urandom does not open. + +diff -Naur glibc-2.11.1.orig/sysdeps/posix/tempname.c glibc-2.11.1/sysdeps/posix/tempname.c +--- glibc-2.11.1.orig/sysdeps/posix/tempname.c 2009-12-08 20:10:20.000000000 +0000 ++++ glibc-2.11.1/sysdeps/posix/tempname.c 2010-02-19 17:36:44.000000000 +0000 +@@ -51,10 +51,6 @@ + # include <fcntl.h> + #endif + +-#if HAVE_SYS_TIME_H || _LIBC +-# include <sys/time.h> +-#endif +- + #if HAVE_STDINT_H || _LIBC + # include <stdint.h> + #endif +@@ -93,11 +89,11 @@ + # define struct_stat64 struct stat64 + #else + # define struct_stat64 struct stat +-# define __getpid getpid +-# define __gettimeofday gettimeofday + # define __mkdir mkdir + # define __open open + # define __open64 open ++# define __close close ++# define __read read + # define __lxstat64(version, path, buf) lstat (path, buf) + # define __xstat64(version, path, buf) stat (path, buf) + #endif +@@ -106,25 +102,6 @@ + # define __secure_getenv getenv + #endif + +-#ifdef _LIBC +-# include <hp-timing.h> +-# if HP_TIMING_AVAIL +-# define RANDOM_BITS(Var) \ +- if (__builtin_expect (value == UINT64_C (0), 0)) \ +- { \ +- /* If this is the first time this function is used initialize \ +- the variable we accumulate the value in to some somewhat \ +- random value. If we'd not do this programs at startup time \ +- might have a reduced set of possible names, at least on slow \ +- machines. */ \ +- struct timeval tv; \ +- __gettimeofday (&tv, NULL); \ +- value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \ +- } \ +- HP_TIMING_NOW (Var) +-# endif +-#endif +- + /* Use the widest available unsigned type if uint64_t is not + available. The algorithm below extracts a number less than 62**6 + (approximately 2**35.725) from uint64_t, so ancient hosts where +@@ -209,6 +186,19 @@ + static const char letters[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + ++static unsigned int fillrand(unsigned char *buf, unsigned int len) ++{ ++ int fd; ++ unsigned int result = -1; ++ fd = __open("/dev/urandom", O_RDONLY|O_NONBLOCK|O_NOCTTY); ++ if (fd >= 0) ++ { ++ result = __read(fd, buf, len); ++ __close(fd); ++ } ++ return result; ++} ++ + /* Generate a temporary file name based on TMPL. TMPL must match the + rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). + The name constructed does not exist at the time of the call to +@@ -219,13 +209,12 @@ + at the time of the call. + __GT_FILE: create the file using open(O_CREAT|O_EXCL) + and return a read-write fd. The file is mode 0600. +- __GT_DIR: create a directory, which will be mode 0700. ++ __GT_DIR: create a directory, which will be mode 0700. */ + +- We use a clever algorithm to get hard-to-predict names. */ + int + __gen_tempname (char *tmpl, int suffixlen, int flags, int kind) + { +- int len; ++ int len, i; + char *XXXXXX; + static uint64_t value; + uint64_t random_time_bits; +@@ -233,6 +222,8 @@ + int fd = -1; + int save_errno = errno; + struct_stat64 st; ++ unsigned char randomness[6]; ++ unsigned int k; + + /* A lower bound on the number of temporary files to attempt to + generate. The maximum total number of temporary file names that +@@ -260,39 +251,20 @@ + /* This is where the Xs start. */ + XXXXXX = &tmpl[len - 6 - suffixlen]; + +- /* Get some more or less random data. */ +-#ifdef RANDOM_BITS +- RANDOM_BITS (random_time_bits); +-#else +-# if HAVE_GETTIMEOFDAY || _LIBC +- { +- struct timeval tv; +- __gettimeofday (&tv, NULL); +- random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; +- } +-# else +- random_time_bits = time (NULL); +-# endif +-#endif +- value += random_time_bits ^ __getpid (); ++ /* Get some random data, and die otherwise. */ ++ if (fillrand(randomness, sizeof(randomness)) != sizeof(randomness)) ++ { ++ __set_errno (ENODEV); ++ return -1; ++ } ++ for (i = 0 ; i < sizeof(randomness) ; i++) ++ { ++ k = ((randomness[i]) % 62); ++ XXXXXX[i] = letters[k]; ++ } + + for (count = 0; count < attempts; value += 7777, ++count) + { +- uint64_t v = value; +- +- /* Fill in the random bits. */ +- XXXXXX[0] = letters[v % 62]; +- v /= 62; +- XXXXXX[1] = letters[v % 62]; +- v /= 62; +- XXXXXX[2] = letters[v % 62]; +- v /= 62; +- XXXXXX[3] = letters[v % 62]; +- v /= 62; +- XXXXXX[4] = letters[v % 62]; +- v /= 62; +- XXXXXX[5] = letters[v % 62]; +- + switch (kind) + { + case __GT_FILE: diff --git a/pkgs/core/glibc/patches/glibc-2.11.1-owl-alt-res_randomid.patch b/pkgs/core/glibc/patches/glibc-2.11.1-owl-alt-res_randomid.patch new file mode 100644 index 0000000..969b8dc --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.11.1-owl-alt-res_randomid.patch @@ -0,0 +1,317 @@ +# Improve res_randomid in the resolver. + +--- a/include/resolv.h ++++ b/include/resolv.h +@@ -31,6 +31,7 @@ extern struct __res_state _res; + # endif + + /* Now define the internal interfaces. */ ++extern unsigned int _shuffle_next (void); + extern int __res_vinit (res_state, int); + extern int __res_maybe_init (res_state, int); + extern void _sethtent (int); +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -29,7 +29,7 @@ distribute := ../conf/portability.h mapv4v6addr.h mapv4v6hostent.h \ + Banner res_hconf.h res_debug.h README gai_misc.h ga_test.c + + routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ +- res_hconf res_libc res-state ++ res_hconf res_libc res-state shuffle + + tests = tst-aton tst-leaks tst-inet_ntop + xtests = tst-leaks2 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -570,7 +570,9 @@ net_mask(in) /* XXX - should really use system's version of this */ + + u_int + res_randomid(void) { +- return 0xffff & __getpid(); ++/* We should probably randomize the port number as well, ++ * but this may be better done in the kernel */ ++ return _shuffle_next(); + } + #ifdef _LIBC + libc_hidden_def (__res_randomid) +--- a/resolv/res_mkquery.c ++++ b/resolv/res_mkquery.c +@@ -120,6 +120,7 @@ res_nmkquery(res_state statp, + return (-1); + memset(buf, 0, HFIXEDSZ); + hp = (HEADER *) buf; ++#ifdef USE_OLD_RANDOMIZE_CODE + /* We randomize the IDs every time. The old code just + incremented by one after the initial randomization which + still predictable if the application does multiple +@@ -137,6 +138,9 @@ res_nmkquery(res_state statp, + } + while ((randombits & 0xffff) == 0); + statp->id = (statp->id + randombits) & 0xffff; ++#else ++ statp->id = res_randomid (); ++#endif + hp->id = statp->id; + hp->opcode = op; + hp->rd = (statp->options & RES_RECURSE) != 0; +--- /dev/null ++++ b/resolv/shuffle.c +@@ -0,0 +1,258 @@ ++/* ++ * Written by Solar Designer and placed in the public domain. ++ */ ++ ++#include <unistd.h> ++#include <fcntl.h> ++#include <resolv.h> ++ ++#ifdef __linux__ ++#define DEVICE "/dev/urandom" ++#else ++#undef DEVICE ++#endif ++ ++#if defined(DEVICE) && defined(_LIBC) ++#define CONSERVE_KERNEL_RANDOMNESS ++#else ++#undef CONSERVE_KERNEL_RANDOMNESS ++#endif ++ ++#ifdef DEVICE ++#include <errno.h> ++#endif ++ ++#include <stdlib.h> ++#include <string.h> ++#include <sys/time.h> ++#include <sys/times.h> ++ ++#ifdef TEST ++#include <stdio.h> ++#endif ++ ++#define DIV 0x8000 ++ ++static unsigned char pool[0x100]; ++ ++static struct { ++ unsigned int base, xor; ++ unsigned char s[0x80]; ++} seed_c; ++static unsigned char seed_f[0x100]; ++ ++static struct { ++ unsigned int msb; ++ unsigned int a, b; ++ unsigned int n; ++} state; ++ ++static void pool_update(unsigned int seed) ++{ ++ int i, x; ++ ++ __srandom(seed ^ __random()); ++ for (i = 0; i < sizeof(pool); i++) { ++ x = __random(); ++ pool[i] += (x >> 16) ^ x; ++ } ++} ++ ++#ifdef DEVICE ++static int read_loop(int fd, char *buffer, int count) ++{ ++ int offset, block; ++ ++ offset = 0; ++ while (count > 0) { ++ block = __read(fd, &buffer[offset], count); ++ ++ if (block < 0) { ++ if (errno == EINTR) continue; ++ return block; ++ } ++ if (!block) return offset; ++ ++ offset += block; ++ count -= block; ++ } ++ ++ return offset; ++} ++ ++static int read_random(char *buffer, int count) ++{ ++ int fd; ++#ifdef CONSERVE_KERNEL_RANDOMNESS ++ unsigned int seed[2]; ++ ++ if (count > sizeof(pool)) ++ return -1; ++#endif ++ ++ if ((fd = __open(DEVICE, O_RDONLY)) < 0) ++ return -1; ++ ++#ifdef CONSERVE_KERNEL_RANDOMNESS ++ if (read_loop(fd, (char *)seed, sizeof(seed)) != sizeof(seed)) { ++ __close(fd); ++ return -1; ++ } ++ __close(fd); ++ ++ memset(pool, 'X', sizeof(pool)); ++ pool_update(seed[0]); ++ pool_update(seed[1]); ++ ++ memcpy(buffer, pool, count); ++#else ++ count = read_loop(fd, buffer, count); ++ __close(fd); ++#endif ++ ++ return count; ++} ++#else ++#define read_random(buffer, count) (-1) ++#endif ++ ++static void shuffle_init() ++{ ++ struct timeval tv; ++ ++ if (read_random((char *)seed_f, sizeof(seed_f)) != sizeof(seed_f)) { ++ memset(pool, 'X', sizeof(pool)); ++ pool_update(__getpid()); ++ pool_update(__getppid()); ++ if (!__gettimeofday(&tv, NULL)) { ++ pool_update(tv.tv_sec); ++ pool_update(tv.tv_usec); ++ } ++ ++ memcpy(seed_f, pool, sizeof(seed_f)); ++ } ++ ++ state.msb = 0; ++ state.n = DIV; /* force a reseed() */ ++} ++ ++static void reseed() ++{ ++ struct tms buf; ++ ++ if (read_random((char *)&seed_c, sizeof(seed_c)) != sizeof(seed_c)) { ++ pool_update(__times(&buf)); ++ pool_update(buf.tms_utime); ++ pool_update(buf.tms_stime); ++ ++ memcpy(&seed_c, pool, sizeof(seed_c)); ++ } ++ ++ seed_c.base &= 0x1fff; ++ seed_c.base <<= 3; ++ seed_c.base += DIV + 3; ++ seed_c.xor &= (DIV - 1); ++ state.msb ^= 0x8000; ++ state.a = 1; ++ state.b = 1; ++ state.n = 0; ++} ++ ++/* ++ * Now, time for a puzzle. Think of division by DIV in seed_c.base. ++ * This is not as slow as it might appear: the inner loop needs only ++ * a few iterations per call, on average. ++ */ ++static unsigned int shuffle_1_next() ++{ ++ if (state.n >= DIV - 1) ++ reseed(); ++ ++ if (state.n && state.b <= state.a) { ++ do { ++ state.b = ++state.a; ++ do { ++ state.b *= seed_c.base; ++ state.b %= DIV; ++ } while (state.b > state.a); ++ } while (state.a != state.b); ++ } ++ ++ state.b *= seed_c.base; ++ state.b %= DIV; ++ state.n++; ++ ++ return state.b ^ seed_c.xor; ++} ++ ++/* ++ * The idea behind shuffle_2 is David Wagner's (any bugs are mine, ++ * of course). ++ */ ++static unsigned int shuffle_2(unsigned int x) ++{ ++ unsigned int i, sum; ++ ++ sum = 0; ++ for (i = 0; i < 8; i++) { ++ sum += 0x79b9; ++ x ^= ((unsigned int)seed_c.s[(x ^ sum) & 0x7f]) << 7; ++ x = ((x & 0xff) << 7) | (x >> 8); ++ } ++ ++ return x; ++} ++ ++/* ++ * A full 16-bit permutation. This one can't be re-seeded, but still ++ * makes some attacks quite a bit harder. ++ */ ++static unsigned int shuffle_3(unsigned int x) ++{ ++ unsigned int i, sum; ++ ++ sum = 0; ++ for (i = 0; i < 8; i++) { ++ sum += 0x79b9; ++ x ^= ((unsigned int)seed_f[(x ^ sum) & 0xff]) << 8; ++ x = ((x & 0xff) << 8) | (x >> 8); ++ } ++ ++ return x; ++} ++ ++unsigned int _shuffle_next() ++{ ++ static int initialized = 0; ++ unsigned int pid, x; ++ ++/* This isn't MT-safe, but the resolver itself isn't safe, anyway */ ++ if (!initialized) { ++ shuffle_init(); ++ initialized = 1; ++ } ++ ++/* Make sure the sequence we generate changes after fork() */ ++ pid = __getpid(); ++ ++ x = shuffle_1_next(); ++ x ^= pid & 0x7fff; ++ x = shuffle_2(x); ++ x |= state.msb; ++ x ^= (pid >> 15) & 0xffff; ++ x = shuffle_3(x); ++ ++ return x; ++} ++ ++#ifdef TEST ++int main() ++{ ++ int i; ++ ++ for (i = 0; i < 0xfffe; i++) ++ printf("%u\n", _shuffle_next()); ++ ++ return 0; ++} ++#endif diff --git a/pkgs/core/gmp/gmp.nm b/pkgs/core/gmp/gmp.nm new file mode 100644 index 0000000..4e398b1 --- /dev/null +++ b/pkgs/core/gmp/gmp.nm @@ -0,0 +1,75 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gmp +PKG_VER = 5.0.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://gmplib.org/ +PKG_LICENSE = LGPLv3+ +PKG_SUMMARY = A GNU arbitrary precision library. + +PKG_BUILD_DEPS:= $(filter-out gcc,$(PKG_BUILD_DEPS)) + +define PKG_DESCRIPTION + The gmp package contains GNU MP, a library for arbitrary precision \ + arithmetic, signed integers operations, rational numbers and floating \ + point numbers. GNU MP is designed for speed, for both small and very \ + large operands. GNU MP is fast because it uses fullwords as the basic \ + arithmetic type, it uses fast algorithms, it carefully optimizes \ + assembly code for many CPUs' most common inner loops, and it generally \ + emphasizes speed over simplicity/elegance in its operations. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +ifeq "$(MACHINE)" "x86_64" + ABI = 64 +else + ABI = 32 +endif + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ABI=$(ABI) \ + ./configure \ + --prefix=/usr \ + --enable-cxx \ + --enable-mpbsd \ + --disable-static + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + cd $(DIR_APP) && make check +endef diff --git a/pkgs/core/gnupg2/gnupg2.nm b/pkgs/core/gnupg2/gnupg2.nm new file mode 100644 index 0000000..ce290de --- /dev/null +++ b/pkgs/core/gnupg2/gnupg2.nm @@ -0,0 +1,50 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gnupg +PKG_VER = 2.0.12 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Security/Tools +PKG_URL = http://www.gnupg.org/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = Utility for secure communication and data storage. + +PKG_DEPS += curl libassuan libgcrypt libksba pinentry pth + +define PKG_DESCRIPTION + The GnuPG 2 package is GNU's tool for secure communication and data \ + storage. It can be used to encrypt data and to create digital signatures. \ + It includes an advanced key management facility and is compliant with the \ + proposed OpenPGP Internet standard as described in RFC2440 and the S/MIME \ + standard as described by several RFCs. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --libexecdir=/usr/lib/gnupg2 diff --git a/pkgs/core/gnutls/gnutls.nm b/pkgs/core/gnutls/gnutls.nm new file mode 100644 index 0000000..af5601e --- /dev/null +++ b/pkgs/core/gnutls/gnutls.nm @@ -0,0 +1,50 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gnutls +PKG_VER = 2.8.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gnu.org/software/gnutls/ +PKG_LICENSE = LGPLv2.1+ +PKG_SUMMARY = A general-purpose cryptography library. + +PKG_DEPS += libgcrypt lzo + +define PKG_DESCRIPTION + GnuTLS is a project that aims to develop a library which provides \ + a secure layer, over a reliable transport layer. Currently the \ + GnuTLS library implements the proposed standards by the IETF's \ + TLS working group. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --with-included-libcfg \ + --disable-srp-authentication diff --git a/pkgs/core/gobject-introspection/gobject-introspection.nm b/pkgs/core/gobject-introspection/gobject-introspection.nm new file mode 100644 index 0000000..854e602 --- /dev/null +++ b/pkgs/core/gobject-introspection/gobject-introspection.nm @@ -0,0 +1,49 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gobject-introspection +PKG_VER = 0.6.5 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Libraries +PKG_URL = http://live.gnome.org/GObjectIntrospection +PKG_LICENSE = GPLv2+, LGPLv2+, MIT +PKG_SUMMARY = Introspection system for GObject-based libraries. + +PKG_BUILD_DEPS+= bison flex pkg-config +PKG_DEPS += glib2 libtool python + +define PKG_DESCRIPTION + GObject Introspection can scan C header and source files in order \ + to generate introspection "typelib" files. It also provides an API to \ + examine typelib files, useful for creating language bindings among \ + other things. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += --sbindir=/sbin --disable-static diff --git a/pkgs/core/gperf/gperf.nm b/pkgs/core/gperf/gperf.nm new file mode 100644 index 0000000..984c847 --- /dev/null +++ b/pkgs/core/gperf/gperf.nm @@ -0,0 +1,46 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gperf +PKG_VER = 3.0.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/gperf/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A perfect hash function generator. + +define PKG_DESCRIPTION + Gperf is a perfect hash function generator written in C++. Simply \ + stated, a perfect hash function is a hash function and a data \ + structure that allows recognition of a key word in a set of words \ + using exactly one probe into the data structure. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --disable-static diff --git a/pkgs/core/grep/grep.nm b/pkgs/core/grep/grep.nm new file mode 100644 index 0000000..20d86c4 --- /dev/null +++ b/pkgs/core/grep/grep.nm @@ -0,0 +1,65 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = grep +PKG_VER = 2.5.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Text +PKG_URL = http://www.gnu.org/software/grep/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = A pattern matching utilities. + +define PKG_DESCRIPTION + The GNU versions of commonly used grep utilities. Grep searches through \ + textual input for lines which contain a match to a specified pattern and then \ + prints the matching lines. GNU's grep utilities include grep, egrep and fgrep. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + # --without-included-regex makes Grep use libc for regex. This gets rid of + # some compiler warnings, and I can't imagine why it's unsafe. + + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --bindir=/bin \ + --without-included-regex + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + cd $(DIR_APP) && make check +endef + diff --git a/pkgs/core/groff/groff.nm b/pkgs/core/groff/groff.nm new file mode 100644 index 0000000..892b3f8 --- /dev/null +++ b/pkgs/core/groff/groff.nm @@ -0,0 +1,88 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = groff +PKG_VER = 1.18.1.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Text +PKG_URL = http://groff.ffii.org/ +PKG_LICENSE = GPLv2 and GFDL +PKG_SUMMARY = A document formatting system. + +PKG_BUILD_DEPS+= bison + +define PKG_DESCRIPTION + Groff is a document formatting system. Groff takes standard text and \ + formatting commands as input and produces formatted output. The \ + created documents can be shown on a display or printed on a printer. \ + Groff's formatting commands allow you to specify font type and size, \ + bold type, italic type, the number and size of columns on a page, and \ + more. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +export PAGE=A4 +CONFIGURE_OPTIONS += --enable-multibyte +PARALLELISMFLAGS = + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -i \ + -e 's/2010/002D/' \ + -e 's/2212/002D/' \ + -e 's/2018/0060/' \ + -e 's/2019/0027/' font/devutf8/R.proto +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/usr/{bin,include,sbin,share/man} + cd $(DIR_APP) && make install \ + manroot=$(BUILDROOT)/usr/share/man \ + bindir=$(BUILDROOT)/usr/bin \ + mandir=$(BUILDROOT)/usr/share/man \ + prefix=$(BUILDROOT)/usr \ + exec_prefix=$(BUILDROOT)/usr \ + sbindir=$(BUILDROOT)/usr/sbin \ + sysconfdir=$(BUILDROOT)/etc \ + datadir=$(BUILDROOT)/usr/share \ + infodir=$(BUILDROOT)/usr/share/info \ + sysconfdir=$(BUILDROOT)/etc \ + includedir=$(BUILDROOT)/usr/include \ + libdir=$(BUILDROOT)/usr/lib \ + libexecdir=$(BUILDROOT)/usr/libexec \ + localstatedir=$(BUILDROOT)/var \ + sharedstatedir=$(BUILDROOT)/usr/com \ + infodir=$(BUILDROOT)/usr/share/info + + ln -svf eqn $(BUILDROOT)/usr/bin/geqn + ln -svf tbl $(BUILDROOT)/usr/bin/gtbl +endef diff --git a/pkgs/core/groff/patches/groff-1.18.1.4-debian_fixes-1.patch b/pkgs/core/groff/patches/groff-1.18.1.4-debian_fixes-1.patch new file mode 100644 index 0000000..9e94645 --- /dev/null +++ b/pkgs/core/groff/patches/groff-1.18.1.4-debian_fixes-1.patch @@ -0,0 +1,18983 @@ +Submitted By: Matthew Burgess (matthew at linuxfromscratch dot org) +Date: 2006-10-20 +Initial Package Version: 1.18.1.4 +Origin: http://ftp.debian.org/debian/pool/main/g/groff/groff_1.18.1.1-12.diff.gz +Upstream Status: This is a debian-specific patch +Description: Adds the ascii8 and nippon devices to groff for man-db. + +diff -Naur groff-1.18.1.4.orig/ChangeLog.jp groff-1.18.1.4/ChangeLog.jp +--- groff-1.18.1.4.orig/ChangeLog.jp 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/ChangeLog.jp 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,345 @@ ++2002-11-04 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * src/libs/libgroff/encoding.cc: for C or POSIX locale, ++ use ascii8 encoding handler ++ * font/devX*: new font desc for M, G ++ * src/xditview: support ENABLE_MULTIBYTE (Japanese only?) ++ ++2002-10-09 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * update groff-1.18-7 ++ ++2002-09-23 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * src/roff/troff/input.cc: fix bug in wchar_charinfo() ++ check u<CODE> where <CODE> is 4- HEX chars ++ * src/device/grohtml/post-html.cc: works ENABLE_MULTIBYTE ++ * font/devhtml: add font M, G for Japanese ++ ++2002-09-22 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * new multibyte patch ++ ++2001-08-16 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * tmac/euc-jp.tmac: ++ fix disappearing `-' char ++ ++2001-07-21 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * add ENABLE_MULTIBYTE support to src/xditview ++ ++2001-07-20 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * introduce "fontset" in font/*/DESC ++ obsoletes "ondemand" ++ ++2001-07-19 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * don't use input_encoding->is_wchar_code() ++ * fix troffrc empty line ++ * fix duplicate strcasecmp() ++ ++2001-07-19 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * sub font selection move into environment::add_char() ++ it makes possible to use [uni<code>] ++ ++2001-07-19 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * use generic iconv_handler instead of euc_handler ++ * internal code now uses UCS-2 ++ ++2001-07-19 Fumitoshi UKAI <ukai@debian.or.jp ++ ++ * wchar%x -> uni%X ++ - still no code conversion ++ - font description is not accurate ++ * change "fixed" to charset range ++ ++2001-07-18 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * Configuration Change: ++ obsolete: --enable-japanese (#ifdef NIPPON) ++ new: --enable-multibyte (#ifdef ENABLE_MULTIBYTE) ++ ++2001-07-18 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * create charinfo for wchar on demand (src/roff/troff/input.cc) ++ * use "fixed" for font wchar metric (src/libs/libgroff/font.cc) ++ - font/*/M,G ++ ++2001-07-17 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * add utf8 encoding handler to src/libs/libgroff/encoding.cc ++ (this utf8 encodig handler is too slow!) ++ ++2001-07-15 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * based on groff 1.17.2-1 ++ * use src/include/encoding.h instead of eucmac.h ++ * introduce src/libs/libgroff/encoding.cc ++ * introduce tmac/euc-jp.tmac for EUC-JP documents ++ ++2001-05-24 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++ * Apply for groff-1.17 ++ ++2000-01-06 Yoshiaki Yanagihara <yochi@debian.or.jp> ++ ++ * Apply japanese patch "jgroff-0.101" ++ (thanks hanataka@abyss.rim.or.jp). ++ * Added japanese extention option at configure.in, aclocal.m4. ++ ++Sat Jan 1 17:10:32 JST 2000 HANATAKA Shinya <hanataka@abyss.rim.or.jp> ++ ++ * jgroff-0.100 €ò€œ€Î€Þ€Þ groff-1.14 €ËŬÍÑ€·€Æ jgroff-101 ++ €È€·€¿¡£ ++ * grohtml €òÆüËÜžì€ËÂбþ€µ€»€ë¡£ ++ * ÆüËÜžì¥Þ¥Ë¥å¥¢¥ëÍÑ€Ë tmac.docj €È tmac.andocj ¥Þ¥¯¥í€òÄɲᣠ++ ++Sun Mar 15 18:23:12 1998 Yoshiaki Yanagihara <yochi@debian.or.jp> ++ ++ * jgroff €Î¥Ù¡Œ¥¹€ò groff-1.11a €ËÊѹ¹€·¡¢jgroff-0.99¥Ñ¥Ã¥Á€ò ++ ŬÍÑ€·€¿€â€Î€ò jgroff-0.100 €È€·€¿¡£ ++ ŽðËÜŪ€Ë jgroff-0.99 €Èµ¡Çœ€ÏƱ€ž *€Ï€º*¡£ ++ ++Fri Dec 22 11:47:46 1995 Kitagawa Toshiyuki <tm-kita@kh.rim.or.jp> ++ ++ * ¥Ð¡Œ¥ž¥ç¥ó0.99¡£ ++ ++Mon Dec 18 18:28:37 1995 Kitagawa Toshiyuki <tm-kita@kh.rim.or.jp> ++ ++ * tmac/Makefile.sub: ¥¿¡Œ¥²¥Ã¥È stamp-wrap¡¢uninstall_sub €¬°ìÉô ++ OS€Îsh€Ç¹œÊž¥š¥é¡Œ€È€Ê€ë¥ª¥ê¥ž¥Ê¥ë¥Ð¥°€òœ€Àµ¡£ ++ ++Wed Dec 13 15:09:26 1995 Kitagawa Toshiyuki <tm-kita@kh.rim.or.jp> ++ ++ * jgroff.sh: ¥ª¥ê¥ž¥Ê¥ë€Ç¥€¥ó¥¹¥È¡Œ¥ë¥Ñ¥¹€¬Êѹ¹€µ€ì€¿€Î€Ë¹ç€ï€»¡¢ ++ GROFF_TMAC_PATH¡¢GROFF_FONT_PATH€òshare/groffÇÛ²Œ€ËÊѹ¹¡£ ++ ++Sat Dec 9 15:28:36 1995 Kitagawa Toshiyuki <tm-kita@kh.rim.or.jp> ++ ++ * wchar.h€«€éeucmac.h€Ë¥Õ¥¡¥€¥ëÌŸ€òÊѹ¹¡£ ++ ++Fri Dec 8 12:15:47 1995 Yoshio Takaeda <shio@yinyan.bekkoame.or.jp> ++ ++ * troff/env.cc(add_char): ¡ØASCIIÊž»ú + ²þ¹Ô¥³¡Œ¥É + EUCÊž»ú¡Ù€È€€€Š ++ ¥Ñ¥¿¡Œ¥ó€Î»þ¡¢²þ¹Ô¥³¡Œ¥É€¬¥¹¥Ú¡Œ¥¹€ËÊÑŽ¹€µ€ì€Ê€€¥Ð¥°€òœ€Àµ¡£ ++ ++Thu Dec 7 21:35:06 1995 Yanagihara Yoshiaki <yosiaki@bsd2.kbnes.nec.co.jp> ++ ++ * troff/input.cc (process_input_stack): gcc-2.7.0€ÇÊÑ¿ôÄêµÁ€¬¥¹¥³¡Œ¥× ++ °ãÈ¿€È€Ê€Ã€Æ€·€Þ€Š²Õœê€òœ€Àµ¡£ ++ ++Thu Dec 7 21:35:06 1995 Yanagihara Yoshiaki <yosiaki@bsd2.kbnes.nec.co.jp> ++ ++ * jgroff€Î¥Ù¡Œ¥¹¥œ¡Œ¥¹€ògroff-1.10€ËÊѹ¹¡£ ++ ++Thu Apr 6 16:56:32 1995 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * devdvi/M.proto-NTT: DNP€Îpk¥Õ¥©¥ó¥È€Î¥Á¥§¥Ã¥¯¥µ¥àÃÍ€¬0€Ê€Î€Ç¡¢€³ ++ €ì€Ë¹ç€ï€»€Æchecksum€ÎÃÍ€ò0€ËÊѹ¹¡£ ++ ++Mon Apr 3 20:36:37 1995 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * troff/env.cc (possibly_break_line): ++ line¥ê¥¹¥ÈÃæ€Îkword_space_node€òÄŽÀ°€¹€ëœèÍý€Ç¡¢lineÃæ€Ë€³€Î¥Î¡Œ¥É ++ €¬ŽÞ€Þ€ì€Æ€€€Ê€€Ÿì¹ç€ÏœèÍý€ò¥¹¥¥Ã¥×€¹€ë€è€Š€Ë€·€¿(EUC¥³¡Œ¥É€òŽÞ€Þ ++ €Ê€€roff€òœèÍý€¹€ëŸì¹ç€Ë€Ïkword_space_node€Ïžœ€ì€Ê€€€Î€ÇœèÍý€¬¹â® ++ ²œ€µ€ì€ë)¡£ ++ ++Mon Apr 3 20:36:37 1995 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * troff/env.cc (add_char): hwkern¡¢vlower€ÎœéŽü²œ€ÏdeviceœéŽü²œžå ++ €Ë°ìÅÙ€À€±¹Ô€š€ÐÎÉ€€€Î€Çenvironment¥¯¥é¥¹€Î¥³¥ó¥¹¥È¥é¥¯¥¿€Ç€³€ì€ò ++ ¹Ô€Š€è€Š€ËÊѹ¹¡£ ++ ++Sat Apr 1 17:57:23 1995 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * troff/input.cc (mount_on_demand): on demand€Ç¥Þ¥Š¥ó¥È€µ€ì€ë¥Õ¥© ++ ¥ó¥ÈÌŸ€ò¥Ç¥Ð¥€¥¹€Ž€È€ÎDESC¥Õ¥¡¥€¥ë€Ç»ØÄê€Ç€€ë€è€Š€ËÊѹ¹¡£ ++ ¥Ç¥£¥ì¥¯¥Æ¥£¥Öondemand€Ç»ØÄꀷ€¿¥Õ¥©¥ó¥È€¬on demand€Ç¥Þ¥Š¥ó¥È€µ€ì€ë¡£ ++ ++Fri Mar 31 20:23:43 1995 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * libgroff/font.cc (load): ŽÁ»ú¥Õ¥©¥ó¥È¥Õ¥¡¥€¥ëÍр˥ǥ£¥ì¥¯¥Æ¥£¥Ö ++ fixedkanji€òÄɲᣀ³€ì€Ï³ÆÊž»ú€Î¥á¥È¥ê¥Ã¥¯€¬ÁŽ€ÆƱ€ž€Ç€¢€ë»ö€ò»ØÄê ++ €¹€ë€â€Î€Ç¡¢fixedkanji€¬»ØÄꀵ€ì€Æ€€€ëŸì¹ç€Ïcharset€ÏÉŸ²Á€µ€ì€Ê€€ ++ €¿€áŽÁ»ú¥Õ¥©¥ó¥È€Î¥í¡Œ¥É€¬Â®€€¡£ ++ ++Thu Mar 30 18:20:24 1995 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * troff: nodeŒ±ÊÌ€òÊž»úÎóÈæ³Ó€Ç¹Ô€Ã€Æ€€€¿€¬¹â®²œ€Î€¿€á¿ôÃÍÈæ³Ó€Ë ++ Êѹ¹€·€¿¡£ ++ ++Wed Mar 29 20:20:49 1995 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * troff/input.cc: ŽÁ»ú¥Õ¥©¥ó¥È(M€ÈG)€òon demand€Ç¥Þ¥Š¥ó¥È€¹€ë€è€Š ++ €ËÊѹ¹¡£€³€ì€Ë€è€Ã€ÆŽÁ»ú€òŽÞ€Þ€Ê€€roff¥Õ¥¡¥€¥ë€ÎœèÍý»þŽÖ€¬¹â®²œ€µ ++ €ì€¿¡£ ++ ++Fri Mar 10 15:34:26 1995 Shigeki Yoshida <shige@theta.iis.u-tokyo.ac.jp> ++ ++ * troff/input.cc (process): geqn€Ç¡¢ ++ ++ .EQ ++ Í×ÁÇ sub µ¹æ ++ .EN ++ ++ €òœèÍý€¹€ë€È¡¢"illegal token in argument to \Z"€È€Ê€Ã€Æ€·€Þ€Š¥Ð¥° ++ (\Z¥·¡Œ¥±¥ó¥¹€Î°ú¿ô€ËEUCÊž»ú€¬Í耿Ÿì¹ç€ÎÂбþϳ€ì)€òœ€Àµ¡£ ++ ++Mon Feb 6 11:22:33 1995 Yoshio Takaeda <e50110@sakura.kudpc.kyoto-u.ac.jp> ++ ++ * troff/input.cc: ¹ÔƬ¶Ø§ʞ»ú€ÎEUC¥³¡Œ¥É€Î°ìÉô€¬ÉÔÀµ¡£ ++ ++Mon Jan 30 14:02:54 1995 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * ¥Ð¡Œ¥ž¥ç¥ó0.97¡£ ++ ++Fri Dec 10 14:26:14 1994 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> ++ ++ * devdvi/M.proto: NTT JTeX€ÈASCIIÆüËÜžìTeXΟÊý€Îdvi¥Õ¥¡¥€¥ë€ò°·€š€ë€è€Š ++ M.proto¥Õ¥¡¥€¥ë€òÊѹ¹¡£ ++ ++Fri Dec 9 14:26:14 1994 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> ++ ++ * troff/node.cc: boldfont_list[]€Ë¥Õ¥©¥ó¥ÈÌŸ B €òÅÐÏ¿€·€Æ€€€Ê€«€Ã ++ €¿€¿€á¡¢dvi¥Õ¥¡¥€¥ë€Ë¥Ž¥·¥Ã¥¯Â΀¬œÐÎÏ€µ€ì€Æ€€€Ê€«€Ã€¿¡£ ++ ++Fri Dec 9 14:23:22 1994 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> ++ ++ * grotty/tty.cc (add_char): EUCÊž»ú€ËÂЀ·€ÆWCHAR_MODE€òÀßÄꀷ€Æ€€ ++ €Ê€«€Ã€¿€¿€á¡¢ttyœÐÎπǥŽ¥·¥Ã¥¯Â΀¬ÆóœÅÂÇ€Á€µ€ì€Æ€€€Ê€«€Ã€¿¡£ ++ ++Fri Dec 9 14:19:33 1994 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> ++ ++ * devdvi/Makefile.sub: ¥Õ¥©¥ó¥È¥Õ¥¡¥€¥ë G €Ç¡¢name¥Ç¥£¥ì¥¯¥Æ¥£¥Ö€¬ ++ `name M'€Ë€Ê€Ã€Æ€€€ë¡£ ++ ++Wed Nov 30 13:24:54 1994 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * ¥Ð¡Œ¥ž¥ç¥ó0.96¡£ ++ ++ * grodvi/dvi.cc: FreeBSD 1.1.5R€Îstrcmp(3)€Ç€Ï°ú¿ô€Ë¥Ì¥ë¥Ý¥€¥ó¥¿€ò ++ ÅÏ€¹€È¥³¥¢¥À¥ó¥×€·€Æ€·€Þ€Š€Î€Ç¡¢€³€ì€ò²óÈò€¹€ë¥³¡Œ¥É€òÄɲÀ·€¿¡£ ++ ++Tue Nov 29 13:52:54 1994 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * troff/input.cc: EUC€Î¥¹¥Ú¡Œ¥¹Êž»ú(0xa1a1)€ÏASCII€Î¥¹¥Ú¡Œ¥¹Êž»ú€È ++ €·€ÆœèÍý€¹€ë€è€Šœ€Àµ¡£ ++ ++ * devnippon/createM: JISX0208€Ë€ª€€€ÆÊž»ú€¬Ì€ÄêµÁ€ÎÉôʬ€Ë€Ä€€€Æ€Ï ++ ¥Õ¥©¥ó¥È¥Õ¥¡¥€¥ë€ËœÐÎÏ€·€Ê€€€è€Šœ€Àµ¡£ ++ ++Mon Nov 28 18:15:31 1994 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * grodvi/dvi.cc: grodvi€òÆüËܞ천€·€¿¡£ ++ ++Fri Nov 25 15:39:05 1994 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * troff/env.cc: EUCÊž»ú€Ç»Ï€Þ€ë¹Ô€ËÂЀ·€Æ¶ÑÅù³ä€êÉÕ€±€¬¹Ô€ï€ì€¿Ÿì ++ ¹ç¡¢¹ÔƬ€Ë͟ʬ€Ê¶õÇò€¬Æþ€ë»ö€¬€¢€Ã€¿€Î€Ç€³€ì€òœ€Àµ€·€¿¡£ ++ ++Fri Nov 18 20:19:55 1994 Masubuchi Toshimichi <tmasu@st.rim.or.jp> ++ ++ * devnippon/createM.c: createM€ÎœªÎ»¥¹¥Æ¡Œ¥¿¥¹€¬ÉÔÄê€Ë€Ê€ë€¿€á¡¢ ++ make€¬œªÎ»€·€Æ€·€Þ€Š¡£createM€ÎœªÎ»¥¹¥Æ¡Œ¥¿¥¹€¬0€Ë€Ê€ë€è€Šœ€Àµ¡£ ++ ++ * devnippon/Makefile.sub: PATHŽÄ¶ÊÑ¿ô€Ë¥«¥ì¥ó¥È¥Ç¥£¥ì¥¯¥È¥ê€¬ŽÞ€Þ ++ €ì€Æ€€€Ê€€Ÿì¹ç¡¢devnippon/M€òmake€¹€ë»þÅÀ€ÇcreateM€¬ž«€Ä€«€é€ºmake ++ ¥š¥é¡Œ€Ë€Ê€ë¥Ð¥°€òœ€Àµ¡£ ++ ++Thu Nov 17 17:11:26 1994 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * devnippon/createM.c: gets()€òfgets()€ËÊѹ¹¡£ ++ ++Sat Nov 12 13:38:19 1994 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * ¥Ð¡Œ¥ž¥ç¥ó0.95¡£ ++ ++ * troff/env.cc: .stt ¥ê¥¯¥š¥¹¥È€òÄɲÃ(¥í¡Œ¥«¥ë€Ê¥Þ¥Ë¥å¥¢¥ëœñŒ°€Ë¹ç ++ €ï€»€ë€¿€á -> €³€Î¥ê¥¯¥š¥¹¥È€ÏÈóžø³«)¡£ ++ ++ * troff/input.cc (init_charset_table): ASCII€Î¹ÔƬ¶Ø§ʞ»ú€È€·€Æ ++ ,:;>}€òÄɲÀ·€¿¡£ ++ ++ * EUC¥Õ¥©¥ó¥È¥Õ¥¡¥€¥ë€Ï¡¢make»þ€Ë¥Ä¡Œ¥ë€Ë€è€Ã€ÆÀžÀ®€¹€ë€è€ŠÊѹ¹¡£ ++ €³€ì€Ë€è€êpatch¥µ¥€¥º€¬€«€Ê€êŸ®€µ€¯€Ê€Ã€¿¡£ ++ ++Fri Nov 11 20:53:00 1994 Kitagawa Toshiyuki <kitagawa@bsd2.kbnes.nec.co.jp> ++ ++ * troff/env.cc (add_char): <EUCÊž»ú> + <ASCIIÊž»ú>€ÎŸì¹ç¡¢ŽÖ€ËÆþ€ì ++ €ë¶õÇò€Ï¶Ø§€Ë°ãÈ¿€·€Ê€€€«€®€ê¥Ö¥ì¡Œ¥¯²ÄÇœ€Ê¶õÇò€¬Æþ€ë€è€Šœ€Àµ€·€¿¡£ ++ ++ ++Tue Oct 25 04:46:09 1994 Kitagawa Toshiyuki (kitagawa@bsd2.kbnes.nec.co.jp) ++ ++ * ¥Ð¡Œ¥ž¥ç¥ó0.94¡£ ++ ++ * libdriver/input.cc (do_file): -Tlatin1€ÇEUC€Ç€Ï€Ê€€Êž»ú¥³¡Œ¥É€ò ++ EUC€ÈÈœÃÇ€·€Æ€·€Þ€Š¥Ð¥°€òœ€Àµ¡£ ++ ++Mon Oct 24 07:16:19 1994 Kitagawa Toshiyuki (kitagawa@bsd2.kbnes.nec.co.jp) ++ ++ * troff/node.cc (is_boldfont): FreeBSD 1.1.5€Ç¡¢¥Œ¥íÈÖÃÏ»²ŸÈ€Î€¿€á¥³ ++ ¥¢¥À¥ó¥×€¹€ë¥Ð¥°€òœ€Àµ¡£ ++ ++ * indxbib/dirnamemax.c: FreeBSD 1.1.5€Ïpathconf()€ò»ý€Ã€Æ€€€Ê€€€Î€Ç ++ _POSIX_VERSION€òundef€·€¿¡£ ++ ++ * ¥Ð¡Œ¥ž¥ç¥ó0.93¡£ ++ ++ * geqn€òÆüËܞ천€·€¿¡£ ++ ++ * devps/DESC€Îwcharkern€òÀßÄꀹ€ë€È¹ÔƬ€Ë¶õÇò€¬Æþ€Ã€Æ€·€Þ€Š¥Ð¥°€Î ++ œ€ÀµÊýË¡€òÊѹ¹¡£ ++ ++Sat Oct 22 08:19:15 1994 Kitagawa Toshiyuki (kitagawa@bsd2.kbnes.nec.co.jp) ++ ++ * ¥Ð¡Œ¥ž¥ç¥ó0.90¡£ ++ ++ * xtotroff€òÆüËܞ천¡£ ++ ++Fri Oct 21 05:33:02 1994 Kitagawa Toshiyuki (kitagawa@bsd2.kbnes.nec.co.jp) ++ ++ * devps/DESC€Îwcharkern€òÀßÄꀹ€ë€È¹ÔƬ€Ë¶õÇò€¬Æþ€Ã€Æ€·€Þ€Š»ö€¬€¢ ++ €Ã€¿€Î€Ç¡¢€³€ì€òœ€Àµ¡£ ++ ++ * pre-release¥Ð¡Œ¥ž¥ç¥ó¡£ ++ ++ * gxditview€òÆüËܞ천€·€¿(¥Õ¥©¥ó¥È¥á¥È¥ê¥Ã¥¯€ÎŒè€êœÐ€·€¬€€€€²Ãžº)¡£ ++ ++Thu Oct 20 05:23:09 1994 Kitagawa Toshiyuki (kitagawa@bsd2.kbnes.nec.co.jp) ++ ++ * ¥Õ¥©¥ó¥ÈÈÖ¹æ3€Ë¥Ü¡Œ¥ë¥ÉÂΰʳ°€Î¥Õ¥©¥ó¥È€ò¥Þ¥Š¥ó¥È€·€¿Ÿì¹ç¡¢ŽÁ»ú¥Õ¥© ++ ¥ó¥È€¬¥Ž¥·¥Ã¥¯Â΀ˀʀÀƀ·€Þ€Š¥Ð¥°€òœ€Àµ¡£ ++ ++Wed Oct 19 06:48:55 1994 Kitagawa Toshiyuki (kitagawa@bsd2.kbnes.nec.co.jp) ++ ++ * beta¥Ð¡Œ¥ž¥ç¥ó¡£ ++ ++Tue Oct 18 05:02:59 1994 Kitagawa Toshiyuki (kitagawa@bsd2.kbnes.nec.co.jp) ++ ++ * pic: ++ gpic€òÆüËÜžìÂбþ€·€¿¡£ ++ ++ * tbl: ++ gtbl€òÆüËÜžìÂбþ€·€¿¡£ ++ ++ * troff/troff: ++ Times-Bold°Ê³°€Î¥Ü¡Œ¥ë¥ÉÂ΀¬¥«¥ì¥ó¥È¥Õ¥©¥ó¥È€Î»þ¡¢ŽÁ»ú¥Õ¥©¥ó¥È€¬¥Ž ++ ¥·¥Ã¥¯€ËÀÚ€êÂØ€ï€é€Ê€€¥Ð¥°€òœ€Àµ¡£ ++ ++ * troff/troff: ++ DESC€Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Öwcharkern€òÄɲÀ·¡¢ASCIIÊž»ú€ÈEUCÊž»ú€ÎŽÖ€Ë¡¢ ++ »ØÄꀷ€¿unit¿ô€À€±breakÉÔ²ÄÇœ€Ê¶õÇò€òÆþ€ì€ë€è€Š€Ë€·€¿¡£ ++ ++ * troff/troff: ++ DESC€Ë¥Ç¥£¥ì¥¯¥Æ¥£¥Ölowerwchar€òÄɲÀ·¡¢ASCIIÊž»ú€ËÂЀ·€ÆEUCÊž»ú€ò¡¢ ++ »ØÄꀷ€¿unit¿ô€À€±²Œ€²€ë€è€Š€Ë€·€¿(ASCIIÊž»ú€¬Íî€Á¹þ€ó€Çž«€š€ë€¿€á)¡£ ++ ++Fri Oct 14 08:29:06 1994 Kitagawa Toshiyuki (kitagawa@bsd2.kbnes.nec.co.jp) ++ ++ * aplah¥Ð¡Œ¥ž¥ç¥ó¡£ +diff -Naur groff-1.18.1.4.orig/Makefile.in groff-1.18.1.4/Makefile.in +--- groff-1.18.1.4.orig/Makefile.in 2002-09-16 16:51:00.000000000 +0000 ++++ groff-1.18.1.4/Makefile.in 2006-10-18 18:54:44.000000000 +0000 +@@ -136,7 +136,11 @@ + # directory will be always added. + # `troffrc' and `troffrc-end' (and `eqnrc') are searched neither in the + # current nor in the home directory. ++ifeq (,$(extratmacdirs)) + tmacpath=$(systemtmacdir):$(localtmacdir):$(tmacdir) ++else ++tmacpath=$(systemtmacdir):$(localtmacdir):$(tmacdir):$(extratmacdirs) ++endif + + # `sys_tmac_prefix' is prefix (if any) for system macro packages. + sys_tmac_prefix=@sys_tmac_prefix@ +@@ -195,6 +199,9 @@ + man7ext=7 + man7dir=$(manroot)/man$(man7ext) + ++# DVI file format. ++DVIFORMAT=@DVIFORMAT@ ++ + # The configure script checks whether all necessary utility programs for + # grohtml are available -- only then we can build the HTML documentation. + make_html=@make_html@ +@@ -261,6 +268,8 @@ + # -DRETSIGTYPE=int if signal handlers return int not void + # -DIS_EBCDIC_HOST if the host's encoding is EBCDIC + # -DPAGEA4 if the the printer's page size is A4 ++# -DENABLE_MULTIBYTE enable multibyte extension ++# -DHAVE_LANGINFO_CODESET if you have nl_langinfo(CODESET) + DEFINES=@DEFS@ + + # Include +@@ -395,7 +404,8 @@ + "PERLPATH=$(PERLPATH)" \ + "SH_SCRIPT_SED_CMD=$(SH_SCRIPT_SED_CMD)" \ + "PURIFY=$(PURIFY)" \ +- "PURIFYCCFLAGS=$(PURIFYCCFLAGS)" ++ "PURIFYCCFLAGS=$(PURIFYCCFLAGS)" \ ++ "DVIFORMAT=$(DVIFORMAT)" + + SHELL=/bin/sh + INCDIRS=src/include +@@ -437,8 +447,10 @@ + font/devhtml + ALLTTYDEVDIRS=\ + font/devascii \ ++ font/devascii8 \ + font/devlatin1 \ + font/devutf8 \ ++ font/devnippon \ + font/devcp1047 + OTHERDIRS=\ + man \ +@@ -483,7 +495,7 @@ + fi + + do=all +-dodirs=$(ALLDIRS) dot ++dodirs=$(DISTDIRS) + # Default target for subdir_Makefile + subdir=src/roff/troff + +diff -Naur groff-1.18.1.4.orig/README.jp groff-1.18.1.4/README.jp +--- groff-1.18.1.4.orig/README.jp 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/README.jp 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,142 @@ ++ ++ ÆüËÜžìÂбþÈÇ groff-1.12 (jgroff-0.101) ++ ++ ++ ËÌÀî ¿®µü (Kitagawa Toshiyuki) ++ tm-kita@kh.rim.or.jp ++ ++ Ìøž¶ ÎÉÎŒ (Yanagihara Yoshiaki) ++ yochi@debian.or.jp ++ ++ GNU€Îroff¥Õ¥©¡Œ¥Þ¥Ã¥¿groff(version 1.12)€ÎÆüËÜžìÂбþ€ò¹Ô€Ê€€€Þ€·€¿¡£ ++ Ÿå°ÌžßŽ¹€È€Ê€Ã€Æ€€€Þ€¹€Î€Ç¡¢ÆüËÜžì€òŽÞ€Þ€Ê€€roff¥Ç¡Œ¥¿€Ï¥ª¥ê¥ž¥Ê¥ë€É ++€ª€ê€ÎÆ°ºî€Ë€Ê€ê€Þ€¹¡£ÆüËܞ천€ËŽØ€¹€ëœ€ÀµÉôʬ€Ë€Ä€€€Æ€ÎÃøºîž¢€ÏGNU ++General Public License Version 2 €ËœŸ€€€Þ€¹(ŸÜºÙ€ÏCOPYING€òžæÍ÷€¯€À€µ€€)¡£ ++ ++ ÆüËÜžìgroff(jgroff)€Îžœ¥Ð¡Œ¥ž¥ç¥ó€Ï0.101(ºÇœªŠÂÈÇ)€Ç€¹¡£€³€Î¥Ð¡Œ¥ž¥ç¥ó ++€Ç€Ï°Ê²Œ€Î¥â¥ž¥å¡Œ¥ë€¬ÆüËܞ천€µ€ì€Æ€€€Þ€¹¡£ ++ ++ groff ... groff¥É¥é¥€¥Ð ++ gtroff ... groffËÜÂÎ ++ grotty ... ÃŒËöÍѥݥ¹¥È¥×¥í¥»¥Ã¥µ ++ grops ... PostScriptÍѥݥ¹¥È¥×¥í¥»¥Ã¥µ ++ grohtml ... HTMLÍѥݥ¹¥È¥×¥í¥»¥Ã¥µ(Thanks HANATAKA Shinya ++ <hanataka@abyss.rim.or.jp>) ++ grodvi ... DVIÍѥݥ¹¥È¥×¥í¥»¥Ã¥µ (NTT JTeX or ASCIIÆüËÜžìTeX) ++ gxditview ... X¥Š¥£¥ó¥É¥ŠÍѥݥ¹¥È¥×¥í¥»¥Ã¥µ ++ gtbl ... tbl¥Þ¥¯¥íÍÑ¥×¥ê¥×¥í¥»¥Ã¥µ ++ gpic ... pic¥Þ¥¯¥íÍÑ¥×¥ê¥×¥í¥»¥Ã¥µ ++ geqn ... eqn¥Þ¥¯¥íÍÑ¥×¥ê¥×¥í¥»¥Ã¥µ ++ xtotroff ... X€Î¥Õ¥©¥ó¥È€«€égroffÍÑ¥Õ¥©¥ó¥È¥Õ¥¡¥€¥ë€òºîÀ®€¹ ++ €ë¥Ä¡Œ¥ë ++ ++¡ô lj4¥Ý¥¹¥È¥×¥í¥»¥Ã¥µ¡¢bibŽØÏ¢€Î¥³¥Þ¥ó¥É€ÏÆüËÜžìÌ€Âбþ€Ç€¹¡£ ++ ++ ++¡ý ¥€¥ó¥¹¥È¡Œ¥ë ++ ++ °Ê²Œ€ÎŽÄ¶€ÇmakeœÐÍè€ë€³€È€ò³Îǧ€·€Æ€€€Þ€¹¡£ ++ ++ ¡ù FreeBSD 2.1.0-RELEASE ++ XFree86-3.1.2, gcc 2.6.3 ++ ++ ¡ù Debian GNU/Linux 2.2 ++ ++ ¡ù NEC EWS/4800/310 ++ SVR4.2 Release9.1 Rev.B, X11R5, gcc 2.6.0 ++ ++ (1) ¥ª¥ê¥ž¥Ê¥ë€ÈƱÍÍconfigure€òŒÂ¹Ô€·€¿žå¡¢make & install€·€Æ²Œ€µ€€¡£ ++ ŸÜ€·€¯€ÏINSTALL€ò»²ŸÈ€·€Æ€¯€À€µ€€¡£ ++ ++ *) grodvi€ÏNTT JTeX·ÁŒ°€Þ€¿€ÏASCIIÆüËÜžìTeX·ÁŒ°€ÎDVI¥Õ¥¡¥€¥ë€ò¥µ¥Ý¡Œ ++ ¥È€·€Æ€€€Þ€¹¡£groff€¬œÐÎÏ€¹€ëDVI¥Õ¥¡¥€¥ë€òASCIIÆüËÜžìTeX·ÁŒ°€Ë ++ €·€¿€€Ÿì¹ç€Ïconfigure --JTeX=ASCII€È€·€Æ€¯€À€µ€€¡£ ++ --JTeX¥ª¥×¥·¥ç¥ó€ò»ØÄꀷ€Ê€«€Ã€¿Ÿì¹ç€ÏNTT JTeX·ÁŒ°€Ë€Ê€ê€Þ€¹¡£ ++ ++ (2) groff€Îmake€Îžå¡¢gxditview(groff€ÎX¥Š¥£¥ó¥É¥ŠÍѥݥ¹¥È¥×¥í¥»¥Ã¥µ) ++ €òmake€·€Þ€¹¡£¥È¥Ã¥×¥Ç¥£¥ì¥¯¥È¥êÄŸ²Œ€Îxditview€Øcd€·€Æ¡¢ ++ ++ % xmkmf ++ % make depend ++ % make all ++ % make install install.man ++ ++ €Ç¡¢¥€¥ó¥¹¥È¡Œ¥ëŽ°Î»€Ç€¹¡£ ++ ++ ++¡ý »È€€Êý ++ ++ groff€Î-T¥ª¥×¥·¥ç¥ó€Ë-Tnippon(ÃŒËöÉœŒš)€òÄɲÀ·€¿°Ê³°€Ï¥ª¥ê¥ž¥Ê¥ë€Î€Þ ++€Þ€Ç€¹¡£ ++°Ê²Œ€Ï»ÈÍÑÎã¡£ ++ ++ (£±) groff -Tnippon -man groff.jman ++ ++ ÆüËÜžì€òŽÞ€àroff¥Õ¥¡¥€¥ë(groff.jman)€òman¥Þ¥¯¥í€ò»È€Ã€Æ¥Õ¥©¡Œ¥Þ¥Ã¥È€·¡¢ ++ÃŒËö€ËÉœŒš€·€Þ€¹¡£ ++ ++ (£²) groff -Tps -man groff.jman ++ ++ ÆüËÜžì€òŽÞ€àroff¥Õ¥¡¥€¥ë€ò¥Õ¥©¡Œ¥Þ¥Ã¥È€·¡¢PostScript€ËÊÑŽ¹€·€Þ€¹¡£ ++ ++ (£³) groff -TX100 -man groff.jman ++ ++ ÆüËÜžì€òŽÞ€àroff¥Õ¥¡¥€¥ë€ò¥Õ¥©¡Œ¥Þ¥Ã¥È€·¡¢X¥Š¥£¥ó¥É¥Š€ËÉœŒš€·€Þ€¹¡£ ++ ++ (£Ž) groff -Tdvi -man groff.jman ++ ++ ÆüËÜžì€òŽÞ€àroff¥Õ¥¡¥€¥ë€ò¥Õ¥©¡Œ¥Þ¥Ã¥È€·¡¢DVI¥Õ¥¡¥€¥ë€òœÐÎÏ€·€Þ€¹¡£ ++ ++ ++¡ý ÆüËܞ천€Ë€Ä€€€Æ ++ ++¡Š ÆüËÜžìÊž»ú¥³¡Œ¥É€ÏÆüËÜžìEUC(€Î¥³¡Œ¥É¥»¥Ã¥È1)€Î€ß¥µ¥Ý¡Œ¥È€·€Æ€€€Þ€¹¡£ ++ ++¡Š ÆüËÜžì¥Õ¥©¥ó¥È€Ë€Ä€€€Æ€Ï¡¢¥«¥ì¥ó¥È¥Õ¥©¥ó¥È€¬¥Ü¡Œ¥ë¥ÉÂ΀λþ€Ï¥Ž¥·¥Ã ++ ¥¯Â΀ˡ¢€œ€ì°Ê³°€Î¥Õ¥©¥ó¥È(¥í¡Œ¥Þ¥ó¡¢¥€¥¿¥ê¥Ã¥¯¡¢¥€¥¿¥ê¥Ã¥¯¥Ü¡Œ¥ë¥É ++ Åù)€¬¥«¥ì¥ó¥È¥Õ¥©¥ó¥È€Î»þ€ÏÌÀÄ«Â΀ˡ¢Œ«Æ°Åª€ËÀÚ€êÂØ€ï€ê€Þ€¹¡£ÆüËÜžì ++ ¥Õ¥©¥ó¥È€òÄŸÀÜ»ØÄꀹ€ë€³€È€ÏœÐÍè€Þ€»€ó¡£ ++ ++ (Ãí) ¥Õ¥©¥ó¥È¥Õ¥¡¥€¥ëÌŸ€¬'B'€Çœª€Ã€Æ€€€ë¥Õ¥©¥ó¥È(B¡¢TB¡¢HNB€Ê€É)€ò ++ ¥Ü¡Œ¥ë¥É¥Õ¥©¥ó¥È€È€·€Æ€€€Þ€¹¡£ ++ ++¡Š ¹ÔƬ¡¢€ª€è€Ó¹ÔËö¶Ø§€ËÂбþ€·€Æ€€€Þ€¹¡£€œ€ì€Ÿ€ì€Î¶Ø§ʞ»ú€Ï¡¢ ++ ++ ¹ÔƬ¶Ø§ʞ»ú: ¡¢ ¡£¡€¡¥¡Š¡§¡š¡©¡ª¡Ë¡Í¡Ï¡Ñ¡×¡Ù¡Û ++ €¡€£€¥€§€©€Ã€ã€å€ç¥¡¥£¥¥¥§¥©¥Ã¥ã¥å¥ç ++ . ? ! " ' ) ] * , : ; > } ++ ¹ÔËö¶Ø§ʞ»ú: ¡Ê ¡Ì¡Î¡Ð¡Ö¡Ø¡Ú ++ ++ €òÄêµÁ€·€Æ€€€Þ€¹¡£ ++ ++¡Š -Tps€ò»ØÄꀷ€¿Ÿì¹ç¡¢EUCÊž»ú€ÈASCIIÊž»ú€ÎŽÖ€Ë€Ï¡¢Éý€Î¶¹€€¶õÇò€¬Œ«Æ° ++ Ū€ËÁÞÆþ€µ€ì€Þ€¹¡£€³€Î¶õÇò€ÎÉý€Ïdevps/DESC€Îwcharkern€Ç»ØÄꀷ€Þ€¹¡£ ++ unitñ°Ì€Ç€¹¡£0€ò»ØÄꀹ€ë€È¶õÇò€ÏÁÞÆþ€µ€ì€Ê€¯€Ê€ê€Þ€¹¡£ ++ ++¡Š -Tps€ò»ØÄꀷ€¿Ÿì¹ç¡¢EUCÊž»ú€ÏASCIIÊž»ú€ËÂЀ·€ÆŸ¯€·²Œ€²€ÆœÐÎÏ€µ€ì€Þ ++ €¹(€œ€Î€Þ€Þ€À€ÈASCIIÊž»ú€¬Íî€Á¹þ€ó€Çž«€š€ë€¿€á)¡£€³€Î²Œ€²Éý€Ï ++ devps/DESC€Îlowerwchar€Ç»ØÄꀷ€Þ€¹¡£unitñ°Ì€Ç€¹¡£0€ò»ØÄꀹ€ë€È»ú²Œ ++ €²€Ï¹Ô€Ê€ï€ì€Þ€»€ó¡£ ++ ++¡Š ¥ª¥ê¥ž¥Ê¥ë€Ç€Ï²þ¹Ô¥³¡Œ¥É€Ï̵Ÿò·ï€Ë¥¹¥Ú¡Œ¥¹Êž»ú€ËÊÑŽ¹€µ€ì€Þ€¹€¬¡¢EUC ++ Êž»ú€Ç°Ï€Þ€ì€¿²þ¹Ô¥³¡Œ¥É€Ï¥¹¥Ú¡Œ¥¹€ËÊÑŽ¹€»€ºÌµ»ë€¹€ë€è€Š€Ë€·€Þ€·€¿¡£ ++ ++¡Š EUC€Î¥¹¥Ú¡Œ¥¹Êž»ú(0xa1a1)€ÏASCII€Î¥¹¥Ú¡Œ¥¹Êž»ú€È€·€ÆœèÍý€µ€ì€Þ€¹¡£ ++ ++ ++¡ý ŒÕŒ ++ ++grodvi€ÎASCIIÆüËÜžìTeXÂбþ€Ï¡¢±§ÅÔµÜÂç³Ø€Î²£ÅÄ€µ€ó€¬¹Ô€Ê€Ã€Æ€¯€À€µ€€€Þ ++€·€¿¡£grohtml€ÎÆüËÜžì(EUC)Âбþ€Ï¡¢²Ö¿ó¿®ºÈ€µ€ó€¬¹Ô€Ã€Æ€¯€ì€Þ€·€¿¡£ ++€Þ€¿¡¢Â¿€¯€ÎÊý€«€é¥Ð¥°€ËŽØ€¹€ëÊó¹ð¡¢œ€Àµ¥€¥á¡Œ¥ž€òÁ÷€Ã€Æĺ€€Þ€·€¿¡£ ++žæ¶šÎÏ€¯€À€µ€Ã€¿³§Í̀ˀπȀƀ⎶ŒÕ€·€Æ€ª€ê€Þ€¹¡£ÍÆñ€Š€Ž€¶€€€Þ€·€¿¡£ ++ ++ ++¡ý €ªŽê€€ ++ ++žœ¥Ð¡Œ¥ž¥ç¥ó€Ç€Ïlj4¥Ý¥¹¥È¥×¥í¥»¥Ã¥µ¡¢bibŽØÏ¢€Î¥³¥Þ¥ó¥É·²€¬ÆüËܞ천€µ€ì ++€Æ€ª€ê€Þ€»€ó¡£€³€ì€é€ÎÆüËܞ천€ò¹Ô€Ã€Æ€¯€À€µ€ëÊý€òÊ眞Ã×€·€Æ€ª€ê€Þ€¹¡£ ++€Œ€Òžæ¶šÎÏ€¯€À€µ€€¡£€Þ€¿¡¢ÆüËÜžìÂбþgroff€ËŽØ€·€Æžæ°Õž«¡¢žæŽõËŸÅù€ò ++À§Èó€ªÊ¹€«€»€¯€À€µ€€¡£º£žå€Î»²¹Í€Ë€µ€»€Æĺ€€Þ€¹(€â€Á€í€ó¥Ð¥°Êó¹ð€â ++Ž¿·Þ€Ç€¹¡ª)¡£ ++°ÊŸå€ÏE-Mail€Ë€Æ¡¢tm-kita@kh.rim.or.jp°ž€Ë€ªÁ÷€ê€¯€À€µ€€¡£ +diff -Naur groff-1.18.1.4.orig/TODO.jp groff-1.18.1.4/TODO.jp +--- groff-1.18.1.4.orig/TODO.jp 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/TODO.jp 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,19 @@ ++TODO lists ++ ++- configure ++ nl_langinfo() ++ iconv() ++ ++- font/devdvi ++ G,M -- NTT and/or ASCII ++- src/devices ++ grohtml ++ grodvi ++ grolbp ++ grolj4 ++- src/xditview ++ ++- command line option to specify input/output encoding ++- font code? ++ can we assume wchar code == font code? ++ [to simplify indexing] +diff -Naur groff-1.18.1.4.orig/aclocal.m4 groff-1.18.1.4/aclocal.m4 +--- groff-1.18.1.4.orig/aclocal.m4 2002-06-18 09:36:43.000000000 +0000 ++++ groff-1.18.1.4/aclocal.m4 2006-10-18 18:54:44.000000000 +0000 +@@ -356,6 +356,19 @@ + AC_MSG_RESULT(no);AC_MSG_ERROR([header files do not support C++ (if you are using a version of gcc/g++ earlier than 2.5, you should install libg++)])) + AC_LANG_POP(C++)])dnl + dnl ++dnl Support Multibyte characters, such as Japanese Code (EUC-JP) ++dnl ++AC_DEFUN(GROFF_MULTIBYTE, ++[AC_MSG_CHECKING([whether to enable multibyte extension]) ++AC_ARG_ENABLE(multibyte, [ --enable-multibyte Enable multibyte extension], ++ multibyte=$enableval, multibyte=no) ++if test "x$multibyte" != "xno"; then ++ AC_DEFINE(ENABLE_MULTIBYTE, 1, ++ [Define if you want to use multibyte extension.]) ++fi ++AC_MSG_RESULT([$multibyte]) ++])dnl ++dnl + dnl + AC_DEFUN(GROFF_TMAC, + [AC_MSG_CHECKING([for prefix of system macro packages]) +@@ -415,6 +428,33 @@ + AC_MSG_RESULT([$tmac_wrap]) + AC_SUBST(tmac_wrap)])dnl + dnl ++dnl codeset.m4 from gettext, by Bruno Haible. ++dnl ++AC_DEFUN(GROFF_LANGINFO_CODESET, ++[AC_CACHE_CHECK([for nl_langinfo and CODESET], groff_cv_langinfo_codeset, ++ [AC_TRY_LINK([#include <langinfo.h>], ++ [char* cs = nl_langinfo(CODESET);], ++ groff_cv_langinfo_codeset=yes, ++ groff_cv_langinfo_codeset=no) ++ ]) ++ if test $groff_cv_langinfo_codeset = yes; then ++ AC_DEFINE(HAVE_LANGINFO_CODESET, 1, ++ [Define if you have <langinfo.h> and nl_langinfo(CODESET).]) ++ fi ++])dnl ++dnl ++dnl ++AC_DEFUN(GROFF_DVIFORMAT, ++[AC_MSG_CHECKING([japanese dvi file format]) ++if test "x$dvi_format" != "xASCII"; then ++ DVIFORMAT=NTT ++else ++ DVIFORMAT=ASCII ++fi ++AC_MSG_RESULT([$DVIFORMAT]) ++AC_SUBST(DVIFORMAT) ++])dnl ++dnl + dnl + AC_DEFUN(GROFF_G, + [AC_MSG_CHECKING([for existing troff installation]) +@@ -481,7 +521,7 @@ + AC_DEFINE(IS_EBCDIC_HOST, 1, + [Define if the host's encoding is EBCDIC.]), + groff_cv_ebcdic="no" +- TTYDEVDIRS="font/devascii font/devlatin1" ++ TTYDEVDIRS="font/devascii font/devlatin1 font/devascii8 font/devnippon" + OTHERDEVDIRS="font/devlj4 font/devlbp" + AC_MSG_RESULT(no)) + AC_SUBST(TTYDEVDIRS) +diff -Naur groff-1.18.1.4.orig/configure groff-1.18.1.4/configure +--- groff-1.18.1.4.orig/configure 2002-09-20 16:14:00.000000000 +0000 ++++ groff-1.18.1.4/configure 2006-10-18 18:54:44.000000000 +0000 +@@ -305,7 +305,7 @@ + # include <unistd.h> + #endif" + +-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS groff_top_builddir CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX TTYDEVDIRS OTHERDEVDIRS LPR LP LPQ PSPRINT DVIPRINT PERLPATH YACC RANLIB ac_ct_RANLIB INSTALL_INFO INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SH_SCRIPT_SED_CMD CPP EGREP LIBM LIBOBJS BROKEN_SPOOLER_FLAGS PAGE g sys_tmac_prefix tmac_wrap pnmcut pnmcrop pnmtopng gs psselect make_html make_install_html LTLIBOBJS' ++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS groff_top_builddir CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX TTYDEVDIRS OTHERDEVDIRS LPR LP LPQ PSPRINT DVIPRINT PERLPATH YACC RANLIB ac_ct_RANLIB INSTALL_INFO INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SH_SCRIPT_SED_CMD CPP EGREP LIBM LIBOBJS BROKEN_SPOOLER_FLAGS PAGE g sys_tmac_prefix tmac_wrap pnmcut pnmcrop pnmtopng gs psselect make_html make_install_html DVIFORMAT LTLIBOBJS' + ac_subst_files='' + + # Initialize some variables set by options. +@@ -841,6 +841,11 @@ + + cat <<_ACEOF + ++Optional Features: ++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) ++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes] ++ --enable-multibyte Enable multibyte extension ++ + Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags +@@ -2530,7 +2535,7 @@ + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + groff_cv_ebcdic="no" +- TTYDEVDIRS="font/devascii font/devlatin1" ++ TTYDEVDIRS="font/devascii font/devlatin1 font/devascii8 font/devnippon" + OTHERDEVDIRS="font/devlj4 font/devlbp" + echo "$as_me:$LINENO: result: no" >&5 + echo "${ECHO_T}no" >&6 +@@ -5859,6 +5864,84 @@ + esac + + ++echo "$as_me:$LINENO: checking whether to enable multibyte extension" >&5 ++echo $ECHO_N "checking whether to enable multibyte extension... $ECHO_C" >&6 ++# Check whether --enable-multibyte or --disable-multibyte was given. ++if test "${enable_multibyte+set}" = set; then ++ enableval="$enable_multibyte" ++ multibyte=$enableval ++else ++ multibyte=no ++fi; ++if test "x$multibyte" != "xno"; then ++ ++cat >>confdefs.h <<_ACEOF ++#define ENABLE_MULTIBYTE 1 ++_ACEOF ++ ++fi ++echo "$as_me:$LINENO: result: $multibyte" >&5 ++echo "${ECHO_T}$multibyte" >&6 ++ ++echo "$as_me:$LINENO: checking japanese dvi file format" >&5 ++echo $ECHO_N "checking japanese dvi file format... $ECHO_C" >&6 ++if test "x$dvi_format" != "xASCII"; then ++ DVIFORMAT=NTT ++else ++ DVIFORMAT=ASCII ++fi ++echo "$as_me:$LINENO: result: $DVIFORMAT" >&5 ++echo "${ECHO_T}$DVIFORMAT" >&6 ++ ++ ++echo "$as_me:$LINENO: checking for nl_langinfo and CODESET" >&5 ++echo $ECHO_N "checking for nl_langinfo and CODESET... $ECHO_C" >&6 ++if test "${groff_cv_langinfo_codeset+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++#line $LINENO "configure" ++#include "confdefs.h" ++#include <langinfo.h> ++int ++main () ++{ ++char* cs = nl_langinfo(CODESET); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ groff_cv_langinfo_codeset=yes ++else ++ echo "$as_me: failed program was:" >&5 ++cat conftest.$ac_ext >&5 ++groff_cv_langinfo_codeset=no ++fi ++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext ++ ++fi ++echo "$as_me:$LINENO: result: $groff_cv_langinfo_codeset" >&5 ++echo "${ECHO_T}$groff_cv_langinfo_codeset" >&6 ++ if test $groff_cv_langinfo_codeset = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define HAVE_LANGINFO_CODESET 1 ++_ACEOF ++ ++ fi ++ + ac_config_files="$ac_config_files stamp-h" + + ac_config_files="$ac_config_files Makefile doc/Makefile src/xditview/Imakefile" +@@ -6497,6 +6580,7 @@ + s,@psselect@,$psselect,;t t + s,@make_html@,$make_html,;t t + s,@make_install_html@,$make_install_html,;t t ++s,@DVIFORMAT@,$DVIFORMAT,;t t + s,@LTLIBOBJS@,$LTLIBOBJS,;t t + CEOF + +diff -Naur groff-1.18.1.4.orig/configure.ac groff-1.18.1.4/configure.ac +--- groff-1.18.1.4.orig/configure.ac 2002-07-23 21:44:20.000000000 +0000 ++++ groff-1.18.1.4/configure.ac 2006-10-18 18:54:44.000000000 +0000 +@@ -68,6 +68,9 @@ + GROFF_G + GROFF_TMAC + GROFF_HTML_PROGRAMS ++GROFF_MULTIBYTE ++GROFF_DVIFORMAT ++GROFF_LANGINFO_CODESET + AC_CONFIG_FILES(stamp-h, [echo timestamp > stamp-h]) + AC_CONFIG_FILES([Makefile doc/Makefile src/xditview/Imakefile]) + AC_OUTPUT +diff -Naur groff-1.18.1.4.orig/contrib/eqn2graph/eqn2graph.sh groff-1.18.1.4/contrib/eqn2graph/eqn2graph.sh +--- groff-1.18.1.4.orig/contrib/eqn2graph/eqn2graph.sh 2002-07-17 04:55:46.000000000 +0000 ++++ groff-1.18.1.4/contrib/eqn2graph/eqn2graph.sh 2006-10-18 18:54:44.000000000 +0000 +@@ -32,7 +32,7 @@ + # + # Thus, we pass -U to groff(1), and everything else to convert(1). + # +-# $Id: eqn2graph.sh,v 1.2 2002/07/17 04:55:46 wlemb Exp $ ++# $Id: eqn2graph.sh,v 1.3 2003/10/28 07:46:23 wlemb Exp $ + # + groff_opts="" + convert_opts="" +@@ -58,17 +58,34 @@ + shift + done + ++# create temporary directory ++tmp= ++for d in "$GROFF_TMPDIR" "$TMPDIR" "$TMP" "$TEMP" /tmp; do ++ test -z "$d" && continue ++ ++ tmp=`(umask 077 && mktemp -d -q "$d/eqn2graph-XXXXXX") 2> /dev/null` \ ++ && test -n "$tmp" && test -d "$tmp" \ ++ && break ++ ++ tmp=$d/eqn2graph$$-$RANDOM ++ (umask 077 && mkdir $tmp) 2> /dev/null && break ++done; ++if test -z "$tmp"; then ++ echo "$0: cannot create temporary directory" >&2 ++ { (exit 1); exit 1; } ++fi ++ ++trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 2 15 ++ + # Here goes: + # 1. Add .EQ/.EN. + # 2. Process through eqn(1) to emit troff markup. + # 3. Process through groff(1) to emit Postscript. + # 4. Use convert(1) to crop the Postscript and turn it into a bitmap. +-tmp=/usr/tmp/eqn2graph-$$ +-trap "rm ${tmp}.*" 0 2 15 + read equation +-(echo ".EQ"; echo 'delim $$'; echo ".EN"; echo '$'"${equation}"'$') | \ +- groff -e $groff_opts -Tps >${tmp}.ps \ +- && convert -crop 0x0 $convert_opts ${tmp}.ps ${tmp}.${format} \ +- && cat ${tmp}.${format} ++(echo ".EQ"; echo 'delim $$'; echo ".EN"; echo '$'"$equation"'$') | \ ++ groff -e $groff_opts -Tps -P-pletter > $tmp/eqn2graph.ps \ ++ && convert -crop 0x0 $convert_opts $tmp/eqn2graph.ps $tmp/eqn2graph.$format \ ++ && cat $tmp/eqn2graph.$format + + # End +diff -Naur groff-1.18.1.4.orig/contrib/mom/groff_mom.man groff-1.18.1.4/contrib/mom/groff_mom.man +--- groff-1.18.1.4.orig/contrib/mom/groff_mom.man 2002-09-04 21:44:16.000000000 +0000 ++++ groff-1.18.1.4/contrib/mom/groff_mom.man 2006-10-18 18:54:44.000000000 +0000 +@@ -13,6 +13,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff/copyright. ++.. + . + .mso www.tmac + . +diff -Naur groff-1.18.1.4.orig/contrib/pic2graph/pic2graph.sh groff-1.18.1.4/contrib/pic2graph/pic2graph.sh +--- groff-1.18.1.4.orig/contrib/pic2graph/pic2graph.sh 2002-07-17 04:55:46.000000000 +0000 ++++ groff-1.18.1.4/contrib/pic2graph/pic2graph.sh 2006-10-18 18:54:44.000000000 +0000 +@@ -32,7 +32,7 @@ + # We don't have complete option coverage on eqn because this is primarily + # intended as a pic translator; we can live with eqn defaults. + # +-# $Id: pic2graph.sh,v 1.2 2002/07/17 04:55:46 wlemb Exp $ ++# $Id: pic2graph.sh,v 1.5 2003/10/31 19:32:36 wlemb Exp $ + # + groffpic_opts="" + gs_opts="" +@@ -44,7 +44,7 @@ + do + case $1 in + -unsafe) +- groffpic_opts="-U" ++ groffpic_opts="-U";; + -format) + format=$2 + shift;; +@@ -68,16 +68,34 @@ + eqndelim="delim $eqndelim" + fi + ++# create temporary directory ++tmp= ++for d in "$GROFF_TMPDIR" "$TMPDIR" "$TMP" "$TEMP" /tmp; do ++ test -z "$d" && continue ++ ++ tmp=`(umask 077 && mktemp -d -q "$d/pic2graph-XXXXXX") 2> /dev/null` \ ++ && test -n "$tmp" && test -d "$tmp" \ ++ && break ++ ++ tmp=$d/pic2graph$$-$RANDOM ++ (umask 077 && mkdir $tmp) 2> /dev/null \ ++ && break ++done; ++if test -z "$tmp"; then ++ echo "$0: cannot create temporary directory" >&2 ++ { (exit 1); exit 1; } ++fi ++ ++trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 2 15 ++ + # Here goes: + # 1. Wrap the input in dummy .PS/PE macros (and add possibly null .EQ/.EN) + # 2. Process through eqn and pic to emit troff markup. + # 3. Process through groff to emit Postscript. + # 4. Use convert(1) to crop the PostScript and turn it into a bitmap. +-tmp=/usr/tmp/pic2graph-$$ +-trap "rm ${tmp}.*" 0 2 15 + (echo ".EQ"; echo $eqndelim; echo ".EN"; echo ".PS"; cat; echo ".PE") | \ +- groff -e -p $groffpic_opts -Tps >${tmp}.ps \ +- && convert -crop 0x0 $convert_opts ${tmp}.ps ${tmp}.${format} \ +- && cat ${tmp}.${format} ++ groff -e -p $groffpic_opts -Tps -P-pletter > $tmp/pic2graph.ps \ ++ && convert -crop 0x0 $convert_opts $tmp/pic2graph.ps $tmp/pic2graph.$format \ ++ && cat $tmp/pic2graph.$format + + # End +diff -Naur groff-1.18.1.4.orig/font/devX100/DESC groff-1.18.1.4/font/devX100/DESC +--- groff-1.18.1.4.orig/font/devX100/DESC 2000-02-06 09:35:04.000000000 +0000 ++++ groff-1.18.1.4/font/devX100/DESC 2006-10-18 18:54:44.000000000 +0000 +@@ -1,5 +1,17 @@ + styles R I B BI +-fonts 6 0 0 0 0 0 S ++fonts 8 0 0 0 0 0 S M G ++fontset B G 2E00..9FFF ++fontset CB G 2E00..9FFF ++fontset HB G 2E00..9FFF ++fontset NB G 2E00..9FFF ++fontset TB G 2E00..9FFF ++fontset - M 2E00..9FFF ++fontset B G FF00..FFEF ++fontset CB G FF00..FFEF ++fontset HB G FF00..FFEF ++fontset NB G FF00..FFEF ++fontset TB G FF00..FFEF ++fontset - M FF00..FFEF + sizes 8 10 12 14 18 24 0 + res 100 + X11 +diff -Naur groff-1.18.1.4.orig/font/devX100/M.proto groff-1.18.1.4/font/devX100/M.proto +--- groff-1.18.1.4.orig/font/devX100/M.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devX100/M.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,5 @@ ++name M ++spacewidth 3 ++charset ++u2E00..u9FFF 20 0 ++uFF00..uFFEF 20 0 +diff -Naur groff-1.18.1.4.orig/font/devX100/Makefile.sub groff-1.18.1.4/font/devX100/Makefile.sub +--- groff-1.18.1.4.orig/font/devX100/Makefile.sub 2000-02-06 09:35:06.000000000 +0000 ++++ groff-1.18.1.4/font/devX100/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -1,2 +1,13 @@ + DEV=X100 +-DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S ++DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S M G ++CLEANADD=M G ++ ++M: M.proto ++ @echo Making M ++ @-rm -f M ++ @cat $(srcdir)/M.proto > M ++ ++G: M ++ @echo Making G ++ @-rm -f G ++ @sed -e 's/name M/name G/' M > G +diff -Naur groff-1.18.1.4.orig/font/devX100-12/DESC groff-1.18.1.4/font/devX100-12/DESC +--- groff-1.18.1.4.orig/font/devX100-12/DESC 2000-02-06 09:35:07.000000000 +0000 ++++ groff-1.18.1.4/font/devX100-12/DESC 2006-10-18 18:54:44.000000000 +0000 +@@ -1,5 +1,17 @@ + styles R I B BI +-fonts 6 0 0 0 0 0 S ++fonts 8 0 0 0 0 0 S M G ++fontset B G 2E00..9FFF ++fontset CB G 2E00..9FFF ++fontset HB G 2E00..9FFF ++fontset NB G 2E00..9FFF ++fontset TB G 2E00..9FFF ++fontset - M 2E00..9FFF ++fontset B G FF00..FFEF ++fontset CB G FF00..FFEF ++fontset HB G FF00..FFEF ++fontset NB G FF00..FFEF ++fontset TB G FF00..FFEF ++fontset - M FF00..FFEF + sizes 8 10 12 14 18 24 0 + res 100 + X11 +diff -Naur groff-1.18.1.4.orig/font/devX100-12/M.proto groff-1.18.1.4/font/devX100-12/M.proto +--- groff-1.18.1.4.orig/font/devX100-12/M.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devX100-12/M.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,5 @@ ++name M ++spacewidth 4 ++charset ++u2E00..u9FFF 20 0 ++uFF00..uFFEF 20 0 +diff -Naur groff-1.18.1.4.orig/font/devX100-12/Makefile.sub groff-1.18.1.4/font/devX100-12/Makefile.sub +--- groff-1.18.1.4.orig/font/devX100-12/Makefile.sub 2000-02-06 09:35:07.000000000 +0000 ++++ groff-1.18.1.4/font/devX100-12/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -1,2 +1,14 @@ + DEV=X100-12 +-DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S ++DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S M G ++CLEANADD=M G ++ ++M: M.proto ++ @echo Making M ++ @-rm -f M ++ @cat $(srcdir)/M.proto > M ++ ++G: M ++ @echo Making G ++ @-rm -f G ++ @sed -e 's/name M/name G/' M > G ++ +diff -Naur groff-1.18.1.4.orig/font/devX75/DESC groff-1.18.1.4/font/devX75/DESC +--- groff-1.18.1.4.orig/font/devX75/DESC 2000-02-06 09:35:09.000000000 +0000 ++++ groff-1.18.1.4/font/devX75/DESC 2006-10-18 18:54:44.000000000 +0000 +@@ -1,5 +1,17 @@ + styles R I B BI +-fonts 6 0 0 0 0 0 S ++fonts 8 0 0 0 0 0 S M G ++fontset B G 2E00..9FFF ++fontset CB G 2E00..9FFF ++fontset HB G 2E00..9FFF ++fontset NB G 2E00..9FFF ++fontset TB G 2E00..9FFF ++fontset - M 2E00..9FFF ++fontset B G FF00..FFEF ++fontset CB G FF00..FFEF ++fontset HB G FF00..FFEF ++fontset NB G FF00..FFEF ++fontset TB G FF00..FFEF ++fontset - M FF00..FFEF + sizes 8 10 12 14 18 24 0 + res 75 + X11 +diff -Naur groff-1.18.1.4.orig/font/devX75/M.proto groff-1.18.1.4/font/devX75/M.proto +--- groff-1.18.1.4.orig/font/devX75/M.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devX75/M.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,6 @@ ++name M ++spacewidth 2 ++charset ++u2E00..u9FFF 10 0 ++uFF00..uFFEF 10 0 ++ +diff -Naur groff-1.18.1.4.orig/font/devX75/Makefile.sub groff-1.18.1.4/font/devX75/Makefile.sub +--- groff-1.18.1.4.orig/font/devX75/Makefile.sub 2000-02-06 09:35:10.000000000 +0000 ++++ groff-1.18.1.4/font/devX75/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -1,2 +1,13 @@ + DEV=X75 +-DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S ++DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S M G ++CLEANADD=M G ++ ++M: M.proto ++ @echo Making M ++ @-rm -f M ++ @cat $(srcdir)/M.proto > M ++ ++G: M ++ @echo Making G ++ @-rm -f G ++ @sed -e 's/name M/name G/' M > G +diff -Naur groff-1.18.1.4.orig/font/devX75-12/DESC groff-1.18.1.4/font/devX75-12/DESC +--- groff-1.18.1.4.orig/font/devX75-12/DESC 2000-02-06 09:35:11.000000000 +0000 ++++ groff-1.18.1.4/font/devX75-12/DESC 2006-10-18 18:54:44.000000000 +0000 +@@ -1,5 +1,17 @@ + styles R I B BI +-fonts 6 0 0 0 0 0 S ++fonts 8 0 0 0 0 0 S M G ++fontset B G 2E00..9FFF ++fontset CB G 2E00..9FFF ++fontset HB G 2E00..9FFF ++fontset NB G 2E00..9FFF ++fontset TB G 2E00..9FFF ++fontset - M 2E00..9FFF ++fontset B G FF00..FFEF ++fontset CB G FF00..FFEF ++fontset HB G FF00..FFEF ++fontset NB G FF00..FFEF ++fontset TB G FF00..FFEF ++fontset - M FF00..FFEF + sizes 8 10 12 14 18 24 0 + res 75 + X11 +diff -Naur groff-1.18.1.4.orig/font/devX75-12/M.proto groff-1.18.1.4/font/devX75-12/M.proto +--- groff-1.18.1.4.orig/font/devX75-12/M.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devX75-12/M.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,5 @@ ++name M ++spacewidth 2 ++charset ++u2E00..u9FFF 12 0 ++uFF00..uFFEF 12 0 +diff -Naur groff-1.18.1.4.orig/font/devX75-12/Makefile.sub groff-1.18.1.4/font/devX75-12/Makefile.sub +--- groff-1.18.1.4.orig/font/devX75-12/Makefile.sub 2000-02-06 09:35:12.000000000 +0000 ++++ groff-1.18.1.4/font/devX75-12/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -1,2 +1,13 @@ + DEV=X75-12 +-DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S ++DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S M G ++CLEANADD=M G ++ ++M: M.proto ++ @echo Making M ++ @-rm -f M ++ @cat $(srcdir)/M.proto > M ++ ++G: M ++ @echo Making G ++ @-rm -f G ++ @sed -e 's/name M/name G/' M > G +diff -Naur groff-1.18.1.4.orig/font/devascii/Makefile.sub groff-1.18.1.4/font/devascii/Makefile.sub +--- groff-1.18.1.4.orig/font/devascii/Makefile.sub 2000-02-06 09:35:12.000000000 +0000 ++++ groff-1.18.1.4/font/devascii/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -12,8 +12,8 @@ + @-rm -f $@ + @(charwidth=`expr $(RES) / $(CPI)` ; \ + sed -e "s/^name [A-Z]*$$/name $@/" \ +- -e "s/^\([^ ]*\) [0-9]+ /\1 $$charwidth /" \ +- -e "s/^spacewidth [0-9]+$$/spacewidth $$charwidth/" \ ++ -e "s/^\([^ ]*\) [0-9][0-9]* /\1 $$charwidth /" \ ++ -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ + -e "s/^internalname .*$$/internalname $@/" \ + -e "/^internalname/s/BI/3/" \ + -e "/^internalname/s/B/2/" \ +diff -Naur groff-1.18.1.4.orig/font/devascii8/DESC.proto groff-1.18.1.4/font/devascii8/DESC.proto +--- groff-1.18.1.4.orig/font/devascii8/DESC.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devascii8/DESC.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,8 @@ ++res 240 ++hor 24 ++vert 40 ++unitwidth 10 ++sizes 10 0 ++fonts 4 R I B BI ++tcommand ++postpro grotty +diff -Naur groff-1.18.1.4.orig/font/devascii8/Makefile.sub groff-1.18.1.4/font/devascii8/Makefile.sub +--- groff-1.18.1.4.orig/font/devascii8/Makefile.sub 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devascii8/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,31 @@ ++DEV=ascii8 ++FONTS=R I B BI ++DEVFILES=$(FONTS) DESC ++CLEANADD=$(FONTS) DESC ++ ++RES=240 ++CPI=10 ++LPI=6 ++ ++$(FONTS): R.proto ++ @echo Making $@ ++ @-rm -f $@ ++ @(charwidth=`expr $(RES) / $(CPI)` ; \ ++ sed -e "s/^name [A-Z]*$$/name $@/" \ ++ -e "s/^\([^ ]*\) [0-9][0-9]* /\1 $$charwidth /" \ ++ -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ ++ -e "s/^internalname .*$$/internalname $@/" \ ++ -e "/^internalname/s/BI/3/" \ ++ -e "/^internalname/s/B/2/" \ ++ -e "/^internalname/s/I/1/" \ ++ -e "/^internalname .*[^ 0-9]/d" \ ++ $(srcdir)/R.proto >$@) ++ ++DESC: DESC.proto ++ @echo Making $@ ++ @-rm -f $@ ++ @sed -e "s/^res .*$$/res $(RES)/" \ ++ -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \ ++ -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \ ++ -e "s/^fonts .*$$/fonts `set $(FONTS); echo $$#` $(FONTS)/" \ ++ $(srcdir)/DESC.proto >$@ +diff -Naur groff-1.18.1.4.orig/font/devascii8/R.proto groff-1.18.1.4/font/devascii8/R.proto +--- groff-1.18.1.4.orig/font/devascii8/R.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devascii8/R.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,262 @@ ++name R ++internalname 0 ++spacewidth 24 ++charset ++! 24 0 0041 ++" 24 0 0042 ++dq " ++lq " ++rq " ++# 24 0 0043 ++sh " ++$ 24 0 0044 ++Do " ++% 24 0 0045 ++& 24 0 0046 ++' 24 0 0047 ++aa " ++fm " ++aq " ++cq " ++( 24 0 0050 ++) 24 0 0051 ++* 24 0 0052 ++** " +++ 24 0 0053 ++pl " ++, 24 0 0054 ++- 24 0 0055 ++hy " ++- " ++mi " ++en " ++. 24 0 0056 ++/ 24 0 0057 ++sl " ++f/ " ++0 24 0 0060 ++1 24 0 0061 ++2 24 0 0062 ++3 24 0 0063 ++4 24 0 0064 ++5 24 0 0065 ++6 24 0 0066 ++7 24 0 0067 ++8 24 0 0070 ++9 24 0 0071 ++: 24 0 0072 ++; 24 0 0073 ++< 24 0 0074 ++la " ++fo " ++= 24 0 0075 ++eq " ++> 24 0 0076 ++ra " ++fc " ++? 24 0 0077 ++@ 24 0 0100 ++at " ++A 24 0 0101 ++*A " ++B 24 0 0102 ++*B " ++C 24 0 0103 ++D 24 0 0104 ++E 24 0 0105 ++*E " ++F 24 0 0106 ++G 24 0 0107 ++H 24 0 0110 ++*Y " ++I 24 0 0111 ++*I " ++J 24 0 0112 ++K 24 0 0113 ++*K " ++L 24 0 0114 ++M 24 0 0115 ++*M " ++N 24 0 0116 ++*N " ++O 24 0 0117 ++ci " ++*O " ++P 24 0 0120 ++*R " ++Q 24 0 0121 ++R 24 0 0122 ++S 24 0 0123 ++T 24 0 0124 ++*T " ++U 24 0 0125 ++V 24 0 0126 ++W 24 0 0127 ++X 24 0 0130 ++*X " ++Y 24 0 0131 ++*U " ++Z 24 0 0132 ++*Z " ++[ 24 0 0133 ++lB " ++\ 24 0 0134 ++rs " ++] 24 0 0135 ++rB " ++a^ 24 0 0136 ++^ " ++ha " ++_ 24 0 0137 ++ru " ++ul " ++` 24 0 0140 ++oq " ++ga " ++a 24 0 0141 ++b 24 0 0142 ++c 24 0 0143 ++d 24 0 0144 ++e 24 0 0145 ++f 24 0 0146 ++g 24 0 0147 ++h 24 0 0150 ++i 24 0 0151 ++.i " ++j 24 0 0152 ++k 24 0 0153 ++l 24 0 0154 ++m 24 0 0155 ++n 24 0 0156 ++o 24 0 0157 ++*o " ++p 24 0 0160 ++q 24 0 0161 ++r 24 0 0162 ++s 24 0 0163 ++t 24 0 0164 ++u 24 0 0165 ++v 24 0 0166 ++w 24 0 0167 ++x 24 0 0170 ++mu " ++y 24 0 0171 ++z 24 0 0172 ++lC 24 0 0173 ++{ " ++ba 24 0 0174 ++or " ++bv " ++br " ++| " ++lb " ++lc " ++lf " ++lk " ++lt " ++rb " ++rc " ++rf " ++rk " ++rt " ++rC 24 0 0175 ++} " ++a~ 24 0 0176 ++~ " ++ap " ++ti " ++char161 24 0 0241 ++char162 24 0 0242 ++char163 24 0 0243 ++char164 24 0 0244 ++char165 24 0 0245 ++char166 24 0 0246 ++char167 24 0 0247 ++char168 24 0 0250 ++char169 24 0 0251 ++char170 24 0 0252 ++char171 24 0 0253 ++char172 24 0 0254 ++char173 24 0 0255 ++char174 24 0 0256 ++char175 24 0 0257 ++char176 24 0 0260 ++char177 24 0 0261 ++char178 24 0 0262 ++char179 24 0 0263 ++char180 24 0 0264 ++char181 24 0 0265 ++char182 24 0 0266 ++char183 24 0 0267 ++char184 24 0 0270 ++char185 24 0 0271 ++char186 24 0 0272 ++char187 24 0 0273 ++char188 24 0 0274 ++char189 24 0 0275 ++char190 24 0 0276 ++char191 24 0 0277 ++char192 24 0 0300 ++char193 24 0 0301 ++char194 24 0 0302 ++char195 24 0 0303 ++char196 24 0 0304 ++char197 24 0 0305 ++char198 24 0 0306 ++char199 24 0 0307 ++char200 24 0 0310 ++char201 24 0 0311 ++char202 24 0 0312 ++char203 24 0 0313 ++char204 24 0 0314 ++char205 24 0 0315 ++char206 24 0 0316 ++char207 24 0 0317 ++char208 24 0 0320 ++char209 24 0 0321 ++char210 24 0 0322 ++char211 24 0 0323 ++char212 24 0 0324 ++char213 24 0 0325 ++char214 24 0 0326 ++char215 24 0 0327 ++char216 24 0 0330 ++char217 24 0 0331 ++char218 24 0 0332 ++char219 24 0 0333 ++char220 24 0 0334 ++char221 24 0 0335 ++char222 24 0 0336 ++char223 24 0 0337 ++char224 24 0 0340 ++char225 24 0 0341 ++char226 24 0 0342 ++char227 24 0 0343 ++char228 24 0 0344 ++char229 24 0 0345 ++char230 24 0 0346 ++char231 24 0 0347 ++char232 24 0 0350 ++char233 24 0 0351 ++char234 24 0 0352 ++char235 24 0 0353 ++char236 24 0 0354 ++char237 24 0 0355 ++char238 24 0 0356 ++char239 24 0 0357 ++char240 24 0 0360 ++char241 24 0 0361 ++char242 24 0 0362 ++char243 24 0 0363 ++char244 24 0 0364 ++char245 24 0 0365 ++char246 24 0 0366 ++char247 24 0 0367 ++char248 24 0 0370 ++char249 24 0 0371 ++char250 24 0 0372 ++char251 24 0 0373 ++char252 24 0 0374 ++char253 24 0 0375 ++char254 24 0 0376 ++char255 24 0 0377 +diff -Naur groff-1.18.1.4.orig/font/devdvi/DESC.in groff-1.18.1.4/font/devdvi/DESC.in +--- groff-1.18.1.4.orig/font/devdvi/DESC.in 2002-03-16 07:45:07.000000000 +0000 ++++ groff-1.18.1.4/font/devdvi/DESC.in 2006-10-18 18:54:44.000000000 +0000 +@@ -6,6 +6,10 @@ + sizes 500-1000000 0 + styles R I B BI + family T +-fonts 13 0 0 0 0 0 0 0 0 0 MI S EX CW ++fonts 15 0 0 0 0 0 0 0 0 0 MI S EX CW M G ++fontset B G 100..FFFF ++fontset HB G 100..FFFF ++fontset SB G 100..FFFF ++fontset - M 100..FFFF + tcommand + postpro grodvi +diff -Naur groff-1.18.1.4.orig/font/devdvi/FixMetric.sed groff-1.18.1.4/font/devdvi/FixMetric.sed +--- groff-1.18.1.4.orig/font/devdvi/FixMetric.sed 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devdvi/FixMetric.sed 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,77 @@ ++s/1006514,.*0x212b$/370845,815360,145600 1 0x212b/ ++s/1006514,.*0x212c$/370845,815360,145600 1 0x212c/ ++s/1006514,.*0x2126$/370845,815360,145600 1 0x2126/ ++s/1006514,.*0x2127$/370845,815360,145600 1 0x2127/ ++s/1006514,.*0x2128$/370845,815360,145600 1 0x2128/ ++s/1006514,.*0x212a$/370845,815360,145600 1 0x212a/ ++s/1006514,.*0x212d$/370845,815360,145600 1 0x212d/ ++s/1006514,.*0x212e$/370845,815360,145600 1 0x212e/ ++s/1006514,.*0x213e$/370845,815360,145600 1 0x213e/ ++s/1006514,.*0x2142$/370845,815360,145600 1 0x2142/ ++s/1006514,.*0x2143$/370845,815360,145600 1 0x2143/ ++s/1006514,.*0x2146$/370845,815360,145600 1 0x2146/ ++s/1006514,.*0x2147$/370845,815360,145600 1 0x2147/ ++s/1006514,.*0x2124$/370845,815360,145600 1 0x2124/ ++s/1006514,.*0x2125$/370845,815360,145600 1 0x2125/ ++s/1006514,.*0x214b$/528496,815360,145600 1 0x214b/ ++s/1006514,.*0x214d$/528496,815360,145600 1 0x214d/ ++s/1006514,.*0x214f$/528496,815360,145600 1 0x214f/ ++s/1006514,.*0x2151$/528496,815360,145600 1 0x2151/ ++s/1006514,.*0x2153$/528496,815360,145600 1 0x2153/ ++s/1006514,.*0x2155$/528496,815360,145600 1 0x2155/ ++s/1006514,.*0x2157$/528496,815360,145600 1 0x2157/ ++s/1006514,.*0x2159$/528496,815360,145600 1 0x2159/ ++s/1006514,.*0x215b$/528496,815360,145600 1 0x215b/ ++s/1006514,.*0x2129$/528496,815360,145600 1 0x2129/ ++s/1006514,.*0x212f$/528496,815360,145600 1 0x212f/ ++s/1006514,.*0x2130$/528496,815360,145600 1 0x2130/ ++s/1006514,.*0x2133$/528496,815360,145600 1 0x2133/ ++s/1006514,.*0x2135$/528496,815360,145600 1 0x2135/ ++s/1006514,.*0x2148$/528496,815360,145600 1 0x2148/ ++s/1006514,.*0x2149$/528496,815360,145600 1 0x2149/ ++s/1006514,.*0x216b$/528496,815360,145600 1 0x216b/ ++s/1006514,.*0x216c$/528496,815360,145600 1 0x216c/ ++s/1006514,.*0x216d$/528496,815360,145600 1 0x216d/ ++s/1006514,.*0x2178$/528496,815360,145600 1 0x2178/ ++s/1006514,.*0x214a$/528496,815360,145600 1 0x214a/ ++s/1006514,.*0x214c$/528496,815360,145600 1 0x214c/ ++s/1006514,.*0x214e$/528496,815360,145600 1 0x214e/ ++s/1006514,.*0x2150$/528496,815360,145600 1 0x2150/ ++s/1006514,.*0x2152$/528496,815360,145600 1 0x2152/ ++s/1006514,.*0x2154$/528496,815360,145600 1 0x2154/ ++s/1006514,.*0x2156$/528496,815360,145600 1 0x2156/ ++s/1006514,.*0x2158$/528496,815360,145600 1 0x2158/ ++s/1006514,.*0x215a$/528496,815360,145600 1 0x215a/ ++s/1006514,.*0x2122$/528496,815360,145600 1 0x2122/ ++s/1006514,.*0x2123$/528496,815360,145600 1 0x2123/ ++s/1006514,.*0x2136$/783741,815360,145600 1 0x2136/ ++s/1006514,.*0x2137$/783741,815360,145600 1 0x2137/ ++s/1006514,.*0x2139$/783741,815360,145600 1 0x2139/ ++s/1006514,.*0x2168$/783741,815360,145600 1 0x2168/ ++s/1006514,.*0x2169$/783741,815360,145600 1 0x2169/ ++s/1006514,.*0x216a$/783741,815360,145600 1 0x216a/ ++s/1006514,.*0x2170$/783741,815360,145600 1 0x2170/ ++s/1006514,.*0x2171$/783741,815360,145600 1 0x2171/ ++s/1006514,.*0x2172$/783741,815360,145600 1 0x2172/ ++s/1006514,.*0x2421$/783741,815360,145600 1 0x2421/ ++s/1006514,.*0x2423$/783741,815360,145600 1 0x2423/ ++s/1006514,.*0x2425$/783741,815360,145600 1 0x2425/ ++s/1006514,.*0x2427$/783741,815360,145600 1 0x2427/ ++s/1006514,.*0x2429$/783741,815360,145600 1 0x2429/ ++s/1006514,.*0x2443$/783741,815360,145600 1 0x2443/ ++s/1006514,.*0x2463$/783741,815360,145600 1 0x2463/ ++s/1006514,.*0x2465$/783741,815360,145600 1 0x2465/ ++s/1006514,.*0x2467$/783741,815360,145600 1 0x2467/ ++s/1006514,.*0x246e$/783741,815360,145600 1 0x246e/ ++s/1006514,.*0x2521$/783741,815360,145600 1 0x2521/ ++s/1006514,.*0x2523$/783741,815360,145600 1 0x2523/ ++s/1006514,.*0x2525$/783741,815360,145600 1 0x2525/ ++s/1006514,.*0x2527$/783741,815360,145600 1 0x2527/ ++s/1006514,.*0x2529$/783741,815360,145600 1 0x2529/ ++s/1006514,.*0x2543$/783741,815360,145600 1 0x2543/ ++s/1006514,.*0x2563$/783741,815360,145600 1 0x2563/ ++s/1006514,.*0x2565$/783741,815360,145600 1 0x2565/ ++s/1006514,.*0x2567$/783741,815360,145600 1 0x2567/ ++s/1006514,.*0x256e$/783741,815360,145600 1 0x256e/ ++s/1006514,.*0x2575$/783741,815360,145600 1 0x2575/ ++s/1006514,.*0x2576$/783741,815360,145600 1 0x2576/ +diff -Naur groff-1.18.1.4.orig/font/devdvi/M.proto-ASCII groff-1.18.1.4/font/devdvi/M.proto-ASCII +--- groff-1.18.1.4.orig/font/devdvi/M.proto-ASCII 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devdvi/M.proto-ASCII 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,4 @@ ++name M ++internalname min10 ++checksum -375402250 ++designsize 10485760 +diff -Naur groff-1.18.1.4.orig/font/devdvi/M.proto-NTT groff-1.18.1.4/font/devdvi/M.proto-NTT +--- groff-1.18.1.4.orig/font/devdvi/M.proto-NTT 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devdvi/M.proto-NTT 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,6882 @@ ++name M ++internalname dmj10 ++checksum 0 ++designsize 10485760 ++charset ++¡¡ F 1:0 ++¡¢ F 2:0 ++¡£ F 3:0 ++¡€ F 4:0 ++¡¥ F 5:0 ++¡Š F 6:0 ++¡§ F 7:0 ++¡š F 8:0 ++¡© F 9:0 ++¡ª F 10:0 ++¡« F 11:0 ++¡¬ F 12:0 ++¡ F 13:0 ++¡® F 14:0 ++¡¯ F 15:0 ++¡° F 16:0 ++¡± F 17:0 ++¡² F 18:0 ++¡³ F 19:0 ++¡Ž F 20:0 ++¡µ F 21:0 ++¡¶ F 22:0 ++¡· F 23:0 ++¡ž F 24:0 ++¡¹ F 25:0 ++¡º F 26:0 ++¡» F 27:0 ++¡Œ F 28:0 ++¡œ F 29:0 ++¡Ÿ F 30:0 ++¡¿ F 31:0 ++¡À F 32:0 ++¡Á F 33:0 ++¡Â F 34:0 ++¡Ã F 35:0 ++¡Ä F 36:0 ++¡Å F 37:0 ++¡Æ F 38:0 ++¡Ç F 39:0 ++¡È F 40:0 ++¡É F 41:0 ++¡Ê F 42:0 ++¡Ë F 43:0 ++¡Ì F 44:0 ++¡Í F 45:0 ++¡Î F 46:0 ++¡Ï F 47:0 ++¡Ð F 48:0 ++¡Ñ F 49:0 ++¡Ò F 50:0 ++¡Ó F 51:0 ++¡Ô F 52:0 ++¡Õ F 53:0 ++¡Ö F 54:0 ++¡× F 55:0 ++¡Ø F 56:0 ++¡Ù F 57:0 ++¡Ú F 58:0 ++¡Û F 59:0 ++¡Ü F 60:0 ++¡Ý F 61:0 ++¡Þ F 62:0 ++¡ß F 63:0 ++¡à F 64:0 ++¡á F 65:0 ++¡â F 66:0 ++¡ã F 67:0 ++¡ä F 68:0 ++¡å F 69:0 ++¡æ F 70:0 ++¡ç F 71:0 ++¡è F 72:0 ++¡é F 73:0 ++¡ê F 74:0 ++¡ë F 75:0 ++¡ì F 76:0 ++¡í F 77:0 ++¡î F 78:0 ++¡ï F 79:0 ++¡ð F 80:0 ++¡ñ F 81:0 ++¡ò F 82:0 ++¡ó F 83:0 ++¡ô F 84:0 ++¡õ F 85:0 ++¡ö F 86:0 ++¡÷ F 87:0 ++¡ø F 88:0 ++¡ù F 89:0 ++¡ú F 90:0 ++¡û F 91:0 ++¡ü F 92:0 ++¡ý F 93:0 ++¡þ F 94:0 ++¢¡ F 101:0 ++¢¢ F 102:0 ++¢£ F 103:0 ++¢€ F 104:0 ++¢¥ F 105:0 ++¢Š F 106:0 ++¢§ F 107:0 ++¢š F 108:0 ++¢© F 109:0 ++¢ª F 110:0 ++¢« F 111:0 ++¢¬ F 112:0 ++¢ F 113:0 ++¢® F 114:0 ++¢º F 126:0 ++¢» F 127:0 ++¢Œ F 128:0 ++¢œ F 129:0 ++¢Ÿ F 130:0 ++¢¿ F 131:0 ++¢À F 132:0 ++¢Á F 133:0 ++¢Ê F 142:0 ++¢Ë F 143:0 ++¢Ì F 144:0 ++¢Í F 145:0 ++¢Î F 146:0 ++¢Ï F 147:0 ++¢Ð F 148:0 ++¢Ü F 160:0 ++¢Ý F 161:0 ++¢Þ F 162:0 ++¢ß F 163:0 ++¢à F 164:0 ++¢á F 165:0 ++¢â F 166:0 ++¢ã F 167:0 ++¢ä F 168:0 ++¢å F 169:0 ++¢æ F 170:0 ++¢ç F 171:0 ++¢è F 172:0 ++¢é F 173:0 ++¢ê F 174:0 ++¢ò F 182:0 ++¢ó F 183:0 ++¢ô F 184:0 ++¢õ F 185:0 ++¢ö F 186:0 ++¢÷ F 187:0 ++¢ø F 188:0 ++¢ù F 189:0 ++¢þ F 194:0 ++£° F 48:1 ++£± F 49:1 ++£² F 50:1 ++£³ F 51:1 ++£Ž F 52:1 ++£µ F 53:1 ++£¶ F 54:1 ++£· F 55:1 ++£ž F 56:1 ++£¹ F 57:1 ++£Á F 65:1 ++£Â F 66:1 ++£Ã F 67:1 ++£Ä F 68:1 ++£Å F 69:1 ++£Æ F 70:1 ++£Ç F 71:1 ++£È F 72:1 ++£É F 73:1 ++£Ê F 74:1 ++£Ë F 75:1 ++£Ì F 76:1 ++£Í F 77:1 ++£Î F 78:1 ++£Ï F 79:1 ++£Ð F 80:1 ++£Ñ F 81:1 ++£Ò F 82:1 ++£Ó F 83:1 ++£Ô F 84:1 ++£Õ F 85:1 ++£Ö F 86:1 ++£× F 87:1 ++£Ø F 88:1 ++£Ù F 89:1 ++£Ú F 90:1 ++£á F 97:1 ++£â F 98:1 ++£ã F 99:1 ++£ä F 100:1 ++£å F 101:1 ++£æ F 102:1 ++£ç F 103:1 ++£è F 104:1 ++£é F 105:1 ++£ê F 106:1 ++£ë F 107:1 ++£ì F 108:1 ++£í F 109:1 ++£î F 110:1 ++£ï F 111:1 ++£ð F 112:1 ++£ñ F 113:1 ++£ò F 114:1 ++£ó F 115:1 ++£ô F 116:1 ++£õ F 117:1 ++£ö F 118:1 ++£÷ F 119:1 ++£ø F 120:1 ++£ù F 121:1 ++£ú F 122:1 ++€¡ F 1:2 ++€¢ F 2:2 ++€£ F 3:2 ++€€ F 4:2 ++€¥ F 5:2 ++€Š F 6:2 ++€§ F 7:2 ++€š F 8:2 ++€© F 9:2 ++€ª F 10:2 ++€« F 11:2 ++€¬ F 12:2 ++€ F 13:2 ++€® F 14:2 ++€¯ F 15:2 ++€° F 16:2 ++€± F 17:2 ++€² F 18:2 ++€³ F 19:2 ++€Ž F 20:2 ++€µ F 21:2 ++€¶ F 22:2 ++€· F 23:2 ++€ž F 24:2 ++€¹ F 25:2 ++€º F 26:2 ++€» F 27:2 ++€Œ F 28:2 ++€œ F 29:2 ++€Ÿ F 30:2 ++€¿ F 31:2 ++€À F 32:2 ++€Á F 33:2 ++€Â F 34:2 ++€Ã F 35:2 ++€Ä F 36:2 ++€Å F 37:2 ++€Æ F 38:2 ++€Ç F 39:2 ++€È F 40:2 ++€É F 41:2 ++€Ê F 42:2 ++€Ë F 43:2 ++€Ì F 44:2 ++€Í F 45:2 ++€Î F 46:2 ++€Ï F 47:2 ++€Ð F 48:2 ++€Ñ F 49:2 ++€Ò F 50:2 ++€Ó F 51:2 ++€Ô F 52:2 ++€Õ F 53:2 ++€Ö F 54:2 ++€× F 55:2 ++€Ø F 56:2 ++€Ù F 57:2 ++€Ú F 58:2 ++€Û F 59:2 ++€Ü F 60:2 ++€Ý F 61:2 ++€Þ F 62:2 ++€ß F 63:2 ++€à F 64:2 ++€á F 65:2 ++€â F 66:2 ++€ã F 67:2 ++€ä F 68:2 ++€å F 69:2 ++€æ F 70:2 ++€ç F 71:2 ++€è F 72:2 ++€é F 73:2 ++€ê F 74:2 ++€ë F 75:2 ++€ì F 76:2 ++€í F 77:2 ++€î F 78:2 ++€ï F 79:2 ++€ð F 80:2 ++€ñ F 81:2 ++€ò F 82:2 ++€ó F 83:2 ++¥¡ F 1:3 ++¥¢ F 2:3 ++¥£ F 3:3 ++¥€ F 4:3 ++¥¥ F 5:3 ++¥Š F 6:3 ++¥§ F 7:3 ++¥š F 8:3 ++¥© F 9:3 ++¥ª F 10:3 ++¥« F 11:3 ++¥¬ F 12:3 ++¥ F 13:3 ++¥® F 14:3 ++¥¯ F 15:3 ++¥° F 16:3 ++¥± F 17:3 ++¥² F 18:3 ++¥³ F 19:3 ++¥Ž F 20:3 ++¥µ F 21:3 ++¥¶ F 22:3 ++¥· F 23:3 ++¥ž F 24:3 ++¥¹ F 25:3 ++¥º F 26:3 ++¥» F 27:3 ++¥Œ F 28:3 ++¥œ F 29:3 ++¥Ÿ F 30:3 ++¥¿ F 31:3 ++¥À F 32:3 ++¥Á F 33:3 ++¥Â F 34:3 ++¥Ã F 35:3 ++¥Ä F 36:3 ++¥Å F 37:3 ++¥Æ F 38:3 ++¥Ç F 39:3 ++¥È F 40:3 ++¥É F 41:3 ++¥Ê F 42:3 ++¥Ë F 43:3 ++¥Ì F 44:3 ++¥Í F 45:3 ++¥Î F 46:3 ++¥Ï F 47:3 ++¥Ð F 48:3 ++¥Ñ F 49:3 ++¥Ò F 50:3 ++¥Ó F 51:3 ++¥Ô F 52:3 ++¥Õ F 53:3 ++¥Ö F 54:3 ++¥× F 55:3 ++¥Ø F 56:3 ++¥Ù F 57:3 ++¥Ú F 58:3 ++¥Û F 59:3 ++¥Ü F 60:3 ++¥Ý F 61:3 ++¥Þ F 62:3 ++¥ß F 63:3 ++¥à F 64:3 ++¥á F 65:3 ++¥â F 66:3 ++¥ã F 67:3 ++¥ä F 68:3 ++¥å F 69:3 ++¥æ F 70:3 ++¥ç F 71:3 ++¥è F 72:3 ++¥é F 73:3 ++¥ê F 74:3 ++¥ë F 75:3 ++¥ì F 76:3 ++¥í F 77:3 ++¥î F 78:3 ++¥ï F 79:3 ++¥ð F 80:3 ++¥ñ F 81:3 ++¥ò F 82:3 ++¥ó F 83:3 ++¥ô F 84:3 ++¥õ F 85:3 ++¥ö F 86:3 ++Š¡ F 1:4 ++Š¢ F 2:4 ++Š£ F 3:4 ++Š€ F 4:4 ++Š¥ F 5:4 ++ŠŠ F 6:4 ++Š§ F 7:4 ++Šš F 8:4 ++Š© F 9:4 ++Šª F 10:4 ++Š« F 11:4 ++Š¬ F 12:4 ++Š F 13:4 ++Š® F 14:4 ++Š¯ F 15:4 ++Š° F 16:4 ++Š± F 17:4 ++Š² F 18:4 ++Š³ F 19:4 ++ŠŽ F 20:4 ++Šµ F 21:4 ++Š¶ F 22:4 ++Š· F 23:4 ++Šž F 24:4 ++ŠÁ F 33:4 ++ŠÂ F 34:4 ++ŠÃ F 35:4 ++ŠÄ F 36:4 ++ŠÅ F 37:4 ++ŠÆ F 38:4 ++ŠÇ F 39:4 ++ŠÈ F 40:4 ++ŠÉ F 41:4 ++ŠÊ F 42:4 ++ŠË F 43:4 ++ŠÌ F 44:4 ++ŠÍ F 45:4 ++ŠÎ F 46:4 ++ŠÏ F 47:4 ++ŠÐ F 48:4 ++ŠÑ F 49:4 ++ŠÒ F 50:4 ++ŠÓ F 51:4 ++ŠÔ F 52:4 ++ŠÕ F 53:4 ++ŠÖ F 54:4 ++Š× F 55:4 ++ŠØ F 56:4 ++§¡ F 1:5 ++§¢ F 2:5 ++§£ F 3:5 ++§€ F 4:5 ++§¥ F 5:5 ++§Š F 6:5 ++§§ F 7:5 ++§š F 8:5 ++§© F 9:5 ++§ª F 10:5 ++§« F 11:5 ++§¬ F 12:5 ++§ F 13:5 ++§® F 14:5 ++§¯ F 15:5 ++§° F 16:5 ++§± F 17:5 ++§² F 18:5 ++§³ F 19:5 ++§Ž F 20:5 ++§µ F 21:5 ++§¶ F 22:5 ++§· F 23:5 ++§ž F 24:5 ++§¹ F 25:5 ++§º F 26:5 ++§» F 27:5 ++§Œ F 28:5 ++§œ F 29:5 ++§Ÿ F 30:5 ++§¿ F 31:5 ++§À F 32:5 ++§Á F 33:5 ++§Ñ F 49:5 ++§Ò F 50:5 ++§Ó F 51:5 ++§Ô F 52:5 ++§Õ F 53:5 ++§Ö F 54:5 ++§× F 55:5 ++§Ø F 56:5 ++§Ù F 57:5 ++§Ú F 58:5 ++§Û F 59:5 ++§Ü F 60:5 ++§Ý F 61:5 ++§Þ F 62:5 ++§ß F 63:5 ++§à F 64:5 ++§á F 65:5 ++§â F 66:5 ++§ã F 67:5 ++§ä F 68:5 ++§å F 69:5 ++§æ F 70:5 ++§ç F 71:5 ++§è F 72:5 ++§é F 73:5 ++§ê F 74:5 ++§ë F 75:5 ++§ì F 76:5 ++§í F 77:5 ++§î F 78:5 ++§ï F 79:5 ++§ð F 80:5 ++§ñ F 81:5 ++š¡ F 1:6 ++š¢ F 2:6 ++š£ F 3:6 ++š€ F 4:6 ++š¥ F 5:6 ++šŠ F 6:6 ++š§ F 7:6 ++šš F 8:6 ++š© F 9:6 ++šª F 10:6 ++š« F 11:6 ++š¬ F 12:6 ++š F 13:6 ++š® F 14:6 ++š¯ F 15:6 ++š° F 16:6 ++š± F 17:6 ++š² F 18:6 ++š³ F 19:6 ++šŽ F 20:6 ++šµ F 21:6 ++š¶ F 22:6 ++š· F 23:6 ++šž F 24:6 ++š¹ F 25:6 ++šº F 26:6 ++š» F 27:6 ++šŒ F 28:6 ++šœ F 29:6 ++šŸ F 30:6 ++š¿ F 31:6 ++šÀ F 32:6 ++°¡ F 0:a ++°¢ F 1:a ++°£ F 2:a ++°€ F 3:a ++°¥ F 4:a ++°Š F 5:a ++°§ F 6:a ++°š F 7:a ++°© F 8:a ++°ª F 9:a ++°« F 10:a ++°¬ F 11:a ++° F 12:a ++°® F 13:a ++°¯ F 14:a ++°° F 15:a ++°± F 16:a ++°² F 17:a ++°³ F 18:a ++°Ž F 19:a ++°µ F 20:a ++°¶ F 21:a ++°· F 22:a ++°ž F 23:a ++°¹ F 24:a ++°º F 25:a ++°» F 26:a ++°Œ F 27:a ++°œ F 28:a ++°Ÿ F 29:a ++°¿ F 30:a ++°À F 31:a ++°Á F 32:a ++°Â F 33:a ++°Ã F 34:a ++°Ä F 35:a ++°Å F 36:a ++°Æ F 37:a ++°Ç F 38:a ++°È F 39:a ++°É F 40:a ++°Ê F 41:a ++°Ë F 42:a ++°Ì F 43:a ++°Í F 44:a ++°Î F 45:a ++°Ï F 46:a ++°Ð F 47:a ++°Ñ F 48:a ++°Ò F 49:a ++°Ó F 50:a ++°Ô F 51:a ++°Õ F 52:a ++°Ö F 53:a ++°× F 54:a ++°Ø F 55:a ++°Ù F 56:a ++°Ú F 57:a ++°Û F 58:a ++°Ü F 59:a ++°Ý F 60:a ++°Þ F 61:a ++°ß F 62:a ++°à F 63:a ++°á F 64:a ++°â F 65:a ++°ã F 66:a ++°ä F 67:a ++°å F 68:a ++°æ F 69:a ++°ç F 70:a ++°è F 71:a ++°é F 72:a ++°ê F 73:a ++°ë F 74:a ++°ì F 75:a ++°í F 76:a ++°î F 77:a ++°ï F 78:a ++°ð F 79:a ++°ñ F 80:a ++°ò F 81:a ++°ó F 82:a ++°ô F 83:a ++°õ F 84:a ++°ö F 85:a ++°÷ F 86:a ++°ø F 87:a ++°ù F 88:a ++°ú F 89:a ++°û F 90:a ++°ü F 91:a ++°ý F 92:a ++°þ F 93:a ++±¡ F 94:a ++±¢ F 95:a ++±£ F 96:a ++±€ F 97:a ++±¥ F 98:a ++±Š F 99:a ++±§ F 100:a ++±š F 101:a ++±© F 102:a ++±ª F 103:a ++±« F 104:a ++±¬ F 105:a ++± F 106:a ++±® F 107:a ++±¯ F 108:a ++±° F 109:a ++±± F 110:a ++±² F 111:a ++±³ F 112:a ++±Ž F 113:a ++±µ F 114:a ++±¶ F 115:a ++±· F 116:a ++±ž F 117:a ++±¹ F 118:a ++±º F 119:a ++±» F 120:a ++±Œ F 121:a ++±œ F 122:a ++±Ÿ F 123:a ++±¿ F 124:a ++±À F 125:a ++±Á F 126:a ++±Â F 127:a ++±Ã F 128:a ++±Ä F 129:a ++±Å F 130:a ++±Æ F 131:a ++±Ç F 132:a ++±È F 133:a ++±É F 134:a ++±Ê F 135:a ++±Ë F 136:a ++±Ì F 137:a ++±Í F 138:a ++±Î F 139:a ++±Ï F 140:a ++±Ð F 141:a ++±Ñ F 142:a ++±Ò F 143:a ++±Ó F 144:a ++±Ô F 145:a ++±Õ F 146:a ++±Ö F 147:a ++±× F 148:a ++±Ø F 149:a ++±Ù F 150:a ++±Ú F 151:a ++±Û F 152:a ++±Ü F 153:a ++±Ý F 154:a ++±Þ F 155:a ++±ß F 156:a ++±à F 157:a ++±á F 158:a ++±â F 159:a ++±ã F 160:a ++±ä F 161:a ++±å F 162:a ++±æ F 163:a ++±ç F 164:a ++±è F 165:a ++±é F 166:a ++±ê F 167:a ++±ë F 168:a ++±ì F 169:a ++±í F 170:a ++±î F 171:a ++±ï F 172:a ++±ð F 173:a ++±ñ F 174:a ++±ò F 175:a ++±ó F 176:a ++±ô F 177:a ++±õ F 178:a ++±ö F 179:a ++±÷ F 180:a ++±ø F 181:a ++±ù F 182:a ++±ú F 183:a ++±û F 184:a ++±ü F 185:a ++±ý F 186:a ++±þ F 187:a ++²¡ F 188:a ++²¢ F 189:a ++²£ F 190:a ++²€ F 191:a ++²¥ F 192:a ++²Š F 193:a ++²§ F 194:a ++²š F 195:a ++²© F 196:a ++²ª F 197:a ++²« F 198:a ++²¬ F 199:a ++² F 200:a ++²® F 201:a ++²¯ F 202:a ++²° F 203:a ++²± F 204:a ++²² F 205:a ++²³ F 206:a ++²Ž F 207:a ++²µ F 208:a ++²¶ F 209:a ++²· F 210:a ++²ž F 211:a ++²¹ F 212:a ++²º F 213:a ++²» F 214:a ++²Œ F 215:a ++²œ F 216:a ++²Ÿ F 217:a ++²¿ F 218:a ++²À F 219:a ++²Á F 220:a ++²Â F 221:a ++²Ã F 222:a ++²Ä F 223:a ++²Å F 224:a ++²Æ F 225:a ++²Ç F 226:a ++²È F 227:a ++²É F 228:a ++²Ê F 229:a ++²Ë F 230:a ++²Ì F 231:a ++²Í F 232:a ++²Î F 233:a ++²Ï F 234:a ++²Ð F 235:a ++²Ñ F 236:a ++²Ò F 237:a ++²Ó F 238:a ++²Ô F 239:a ++²Õ F 240:a ++²Ö F 241:a ++²× F 242:a ++²Ø F 243:a ++²Ù F 244:a ++²Ú F 245:a ++²Û F 246:a ++²Ü F 247:a ++²Ý F 248:a ++²Þ F 249:a ++²ß F 250:a ++²à F 251:a ++²á F 252:a ++²â F 253:a ++²ã F 254:a ++²ä F 255:a ++²å F 0:b ++²æ F 1:b ++²ç F 2:b ++²è F 3:b ++²é F 4:b ++²ê F 5:b ++²ë F 6:b ++²ì F 7:b ++²í F 8:b ++²î F 9:b ++²ï F 10:b ++²ð F 11:b ++²ñ F 12:b ++²ò F 13:b ++²ó F 14:b ++²ô F 15:b ++²õ F 16:b ++²ö F 17:b ++²÷ F 18:b ++²ø F 19:b ++²ù F 20:b ++²ú F 21:b ++²û F 22:b ++²ü F 23:b ++²ý F 24:b ++²þ F 25:b ++³¡ F 26:b ++³¢ F 27:b ++³£ F 28:b ++³€ F 29:b ++³¥ F 30:b ++³Š F 31:b ++³§ F 32:b ++³š F 33:b ++³© F 34:b ++³ª F 35:b ++³« F 36:b ++³¬ F 37:b ++³ F 38:b ++³® F 39:b ++³¯ F 40:b ++³° F 41:b ++³± F 42:b ++³² F 43:b ++³³ F 44:b ++³Ž F 45:b ++³µ F 46:b ++³¶ F 47:b ++³· F 48:b ++³ž F 49:b ++³¹ F 50:b ++³º F 51:b ++³» F 52:b ++³Œ F 53:b ++³œ F 54:b ++³Ÿ F 55:b ++³¿ F 56:b ++³À F 57:b ++³Á F 58:b ++³Â F 59:b ++³Ã F 60:b ++³Ä F 61:b ++³Å F 62:b ++³Æ F 63:b ++³Ç F 64:b ++³È F 65:b ++³É F 66:b ++³Ê F 67:b ++³Ë F 68:b ++³Ì F 69:b ++³Í F 70:b ++³Î F 71:b ++³Ï F 72:b ++³Ð F 73:b ++³Ñ F 74:b ++³Ò F 75:b ++³Ó F 76:b ++³Ô F 77:b ++³Õ F 78:b ++³Ö F 79:b ++³× F 80:b ++³Ø F 81:b ++³Ù F 82:b ++³Ú F 83:b ++³Û F 84:b ++³Ü F 85:b ++³Ý F 86:b ++³Þ F 87:b ++³ß F 88:b ++³à F 89:b ++³á F 90:b ++³â F 91:b ++³ã F 92:b ++³ä F 93:b ++³å F 94:b ++³æ F 95:b ++³ç F 96:b ++³è F 97:b ++³é F 98:b ++³ê F 99:b ++³ë F 100:b ++³ì F 101:b ++³í F 102:b ++³î F 103:b ++³ï F 104:b ++³ð F 105:b ++³ñ F 106:b ++³ò F 107:b ++³ó F 108:b ++³ô F 109:b ++³õ F 110:b ++³ö F 111:b ++³÷ F 112:b ++³ø F 113:b ++³ù F 114:b ++³ú F 115:b ++³û F 116:b ++³ü F 117:b ++³ý F 118:b ++³þ F 119:b ++Ž¡ F 120:b ++Ž¢ F 121:b ++Ž£ F 122:b ++Ž€ F 123:b ++Ž¥ F 124:b ++ŽŠ F 125:b ++Ž§ F 126:b ++Žš F 127:b ++Ž© F 128:b ++Žª F 129:b ++Ž« F 130:b ++Ž¬ F 131:b ++Ž F 132:b ++Ž® F 133:b ++Ž¯ F 134:b ++Ž° F 135:b ++Ž± F 136:b ++Ž² F 137:b ++Ž³ F 138:b ++ŽŽ F 139:b ++Žµ F 140:b ++Ž¶ F 141:b ++Ž· F 142:b ++Žž F 143:b ++Ž¹ F 144:b ++Žº F 145:b ++Ž» F 146:b ++ŽŒ F 147:b ++Žœ F 148:b ++ŽŸ F 149:b ++Ž¿ F 150:b ++ŽÀ F 151:b ++ŽÁ F 152:b ++ŽÂ F 153:b ++ŽÃ F 154:b ++ŽÄ F 155:b ++ŽÅ F 156:b ++ŽÆ F 157:b ++ŽÇ F 158:b ++ŽÈ F 159:b ++ŽÉ F 160:b ++ŽÊ F 161:b ++ŽË F 162:b ++ŽÌ F 163:b ++ŽÍ F 164:b ++ŽÎ F 165:b ++ŽÏ F 166:b ++ŽÐ F 167:b ++ŽÑ F 168:b ++ŽÒ F 169:b ++ŽÓ F 170:b ++ŽÔ F 171:b ++ŽÕ F 172:b ++ŽÖ F 173:b ++Ž× F 174:b ++ŽØ F 175:b ++ŽÙ F 176:b ++ŽÚ F 177:b ++ŽÛ F 178:b ++ŽÜ F 179:b ++ŽÝ F 180:b ++ŽÞ F 181:b ++Žß F 182:b ++Žà F 183:b ++Žá F 184:b ++Žâ F 185:b ++Žã F 186:b ++Žä F 187:b ++Žå F 188:b ++Žæ F 189:b ++Žç F 190:b ++Žè F 191:b ++Žé F 192:b ++Žê F 193:b ++Žë F 194:b ++Žì F 195:b ++Ží F 196:b ++Žî F 197:b ++Žï F 198:b ++Žð F 199:b ++Žñ F 200:b ++Žò F 201:b ++Žó F 202:b ++Žô F 203:b ++Žõ F 204:b ++Žö F 205:b ++Ž÷ F 206:b ++Žø F 207:b ++Žù F 208:b ++Žú F 209:b ++Žû F 210:b ++Žü F 211:b ++Žý F 212:b ++Žþ F 213:b ++µ¡ F 214:b ++µ¢ F 215:b ++µ£ F 216:b ++µ€ F 217:b ++µ¥ F 218:b ++µŠ F 219:b ++µ§ F 220:b ++µš F 221:b ++µ© F 222:b ++µª F 223:b ++µ« F 224:b ++µ¬ F 225:b ++µ F 226:b ++µ® F 227:b ++µ¯ F 228:b ++µ° F 229:b ++µ± F 230:b ++µ² F 231:b ++µ³ F 232:b ++µŽ F 233:b ++µµ F 234:b ++µ¶ F 235:b ++µ· F 236:b ++µž F 237:b ++µ¹ F 238:b ++µº F 239:b ++µ» F 240:b ++µŒ F 241:b ++µœ F 242:b ++µŸ F 243:b ++µ¿ F 244:b ++µÀ F 245:b ++µÁ F 246:b ++µÂ F 247:b ++µÃ F 248:b ++µÄ F 249:b ++µÅ F 250:b ++µÆ F 251:b ++µÇ F 252:b ++µÈ F 253:b ++µÉ F 254:b ++µÊ F 255:b ++µË F 0:c ++µÌ F 1:c ++µÍ F 2:c ++µÎ F 3:c ++µÏ F 4:c ++µÐ F 5:c ++µÑ F 6:c ++µÒ F 7:c ++µÓ F 8:c ++µÔ F 9:c ++µÕ F 10:c ++µÖ F 11:c ++µ× F 12:c ++µØ F 13:c ++µÙ F 14:c ++µÚ F 15:c ++µÛ F 16:c ++µÜ F 17:c ++µÝ F 18:c ++µÞ F 19:c ++µß F 20:c ++µà F 21:c ++µá F 22:c ++µâ F 23:c ++µã F 24:c ++µä F 25:c ++µå F 26:c ++µæ F 27:c ++µç F 28:c ++µè F 29:c ++µé F 30:c ++µê F 31:c ++µë F 32:c ++µì F 33:c ++µí F 34:c ++µî F 35:c ++µï F 36:c ++µð F 37:c ++µñ F 38:c ++µò F 39:c ++µó F 40:c ++µô F 41:c ++µõ F 42:c ++µö F 43:c ++µ÷ F 44:c ++µø F 45:c ++µù F 46:c ++µú F 47:c ++µû F 48:c ++µü F 49:c ++µý F 50:c ++µþ F 51:c ++¶¡ F 52:c ++¶¢ F 53:c ++¶£ F 54:c ++¶€ F 55:c ++¶¥ F 56:c ++¶Š F 57:c ++¶§ F 58:c ++¶š F 59:c ++¶© F 60:c ++¶ª F 61:c ++¶« F 62:c ++¶¬ F 63:c ++¶ F 64:c ++¶® F 65:c ++¶¯ F 66:c ++¶° F 67:c ++¶± F 68:c ++¶² F 69:c ++¶³ F 70:c ++¶Ž F 71:c ++¶µ F 72:c ++¶¶ F 73:c ++¶· F 74:c ++¶ž F 75:c ++¶¹ F 76:c ++¶º F 77:c ++¶» F 78:c ++¶Œ F 79:c ++¶œ F 80:c ++¶Ÿ F 81:c ++¶¿ F 82:c ++¶À F 83:c ++¶Á F 84:c ++¶Â F 85:c ++¶Ã F 86:c ++¶Ä F 87:c ++¶Å F 88:c ++¶Æ F 89:c ++¶Ç F 90:c ++¶È F 91:c ++¶É F 92:c ++¶Ê F 93:c ++¶Ë F 94:c ++¶Ì F 95:c ++¶Í F 96:c ++¶Î F 97:c ++¶Ï F 98:c ++¶Ð F 99:c ++¶Ñ F 100:c ++¶Ò F 101:c ++¶Ó F 102:c ++¶Ô F 103:c ++¶Õ F 104:c ++¶Ö F 105:c ++¶× F 106:c ++¶Ø F 107:c ++¶Ù F 108:c ++¶Ú F 109:c ++¶Û F 110:c ++¶Ü F 111:c ++¶Ý F 112:c ++¶Þ F 113:c ++¶ß F 114:c ++¶à F 115:c ++¶á F 116:c ++¶â F 117:c ++¶ã F 118:c ++¶ä F 119:c ++¶å F 120:c ++¶æ F 121:c ++¶ç F 122:c ++¶è F 123:c ++¶é F 124:c ++¶ê F 125:c ++¶ë F 126:c ++¶ì F 127:c ++¶í F 128:c ++¶î F 129:c ++¶ï F 130:c ++¶ð F 131:c ++¶ñ F 132:c ++¶ò F 133:c ++¶ó F 134:c ++¶ô F 135:c ++¶õ F 136:c ++¶ö F 137:c ++¶÷ F 138:c ++¶ø F 139:c ++¶ù F 140:c ++¶ú F 141:c ++¶û F 142:c ++¶ü F 143:c ++¶ý F 144:c ++¶þ F 145:c ++·¡ F 146:c ++·¢ F 147:c ++·£ F 148:c ++·€ F 149:c ++·¥ F 150:c ++·Š F 151:c ++·§ F 152:c ++·š F 153:c ++·© F 154:c ++·ª F 155:c ++·« F 156:c ++·¬ F 157:c ++· F 158:c ++·® F 159:c ++·¯ F 160:c ++·° F 161:c ++·± F 162:c ++·² F 163:c ++·³ F 164:c ++·Ž F 165:c ++·µ F 166:c ++·¶ F 167:c ++·· F 168:c ++·ž F 169:c ++·¹ F 170:c ++·º F 171:c ++·» F 172:c ++·Œ F 173:c ++·œ F 174:c ++·Ÿ F 175:c ++·¿ F 176:c ++·À F 177:c ++·Á F 178:c ++·Â F 179:c ++·Ã F 180:c ++·Ä F 181:c ++·Å F 182:c ++·Æ F 183:c ++·Ç F 184:c ++·È F 185:c ++·É F 186:c ++·Ê F 187:c ++·Ë F 188:c ++·Ì F 189:c ++·Í F 190:c ++·Î F 191:c ++·Ï F 192:c ++·Ð F 193:c ++·Ñ F 194:c ++·Ò F 195:c ++·Ó F 196:c ++·Ô F 197:c ++·Õ F 198:c ++·Ö F 199:c ++·× F 200:c ++·Ø F 201:c ++·Ù F 202:c ++·Ú F 203:c ++·Û F 204:c ++·Ü F 205:c ++·Ý F 206:c ++·Þ F 207:c ++·ß F 208:c ++·à F 209:c ++·á F 210:c ++·â F 211:c ++·ã F 212:c ++·ä F 213:c ++·å F 214:c ++·æ F 215:c ++·ç F 216:c ++·è F 217:c ++·é F 218:c ++·ê F 219:c ++·ë F 220:c ++·ì F 221:c ++·í F 222:c ++·î F 223:c ++·ï F 224:c ++·ð F 225:c ++·ñ F 226:c ++·ò F 227:c ++·ó F 228:c ++·ô F 229:c ++·õ F 230:c ++·ö F 231:c ++·÷ F 232:c ++·ø F 233:c ++·ù F 234:c ++·ú F 235:c ++·û F 236:c ++·ü F 237:c ++·ý F 238:c ++·þ F 239:c ++ž¡ F 240:c ++ž¢ F 241:c ++ž£ F 242:c ++ž€ F 243:c ++ž¥ F 244:c ++žŠ F 245:c ++ž§ F 246:c ++žš F 247:c ++ž© F 248:c ++žª F 249:c ++ž« F 250:c ++ž¬ F 251:c ++ž F 252:c ++ž® F 253:c ++ž¯ F 254:c ++ž° F 255:c ++ž± F 0:d ++ž² F 1:d ++ž³ F 2:d ++žŽ F 3:d ++žµ F 4:d ++ž¶ F 5:d ++ž· F 6:d ++žž F 7:d ++ž¹ F 8:d ++žº F 9:d ++ž» F 10:d ++žŒ F 11:d ++žœ F 12:d ++žŸ F 13:d ++ž¿ F 14:d ++žÀ F 15:d ++žÁ F 16:d ++žÂ F 17:d ++žÃ F 18:d ++žÄ F 19:d ++žÅ F 20:d ++žÆ F 21:d ++žÇ F 22:d ++žÈ F 23:d ++žÉ F 24:d ++žÊ F 25:d ++žË F 26:d ++žÌ F 27:d ++žÍ F 28:d ++žÎ F 29:d ++žÏ F 30:d ++žÐ F 31:d ++žÑ F 32:d ++žÒ F 33:d ++žÓ F 34:d ++žÔ F 35:d ++žÕ F 36:d ++žÖ F 37:d ++ž× F 38:d ++žØ F 39:d ++žÙ F 40:d ++žÚ F 41:d ++žÛ F 42:d ++žÜ F 43:d ++žÝ F 44:d ++žÞ F 45:d ++žß F 46:d ++žà F 47:d ++žá F 48:d ++žâ F 49:d ++žã F 50:d ++žä F 51:d ++žå F 52:d ++žæ F 53:d ++žç F 54:d ++žè F 55:d ++žé F 56:d ++žê F 57:d ++žë F 58:d ++žì F 59:d ++ží F 60:d ++žî F 61:d ++žï F 62:d ++žð F 63:d ++žñ F 64:d ++žò F 65:d ++žó F 66:d ++žô F 67:d ++žõ F 68:d ++žö F 69:d ++ž÷ F 70:d ++žø F 71:d ++žù F 72:d ++žú F 73:d ++žû F 74:d ++žü F 75:d ++žý F 76:d ++žþ F 77:d ++¹¡ F 78:d ++¹¢ F 79:d ++¹£ F 80:d ++¹€ F 81:d ++¹¥ F 82:d ++¹Š F 83:d ++¹§ F 84:d ++¹š F 85:d ++¹© F 86:d ++¹ª F 87:d ++¹« F 88:d ++¹¬ F 89:d ++¹ F 90:d ++¹® F 91:d ++¹¯ F 92:d ++¹° F 93:d ++¹± F 94:d ++¹² F 95:d ++¹³ F 96:d ++¹Ž F 97:d ++¹µ F 98:d ++¹¶ F 99:d ++¹· F 100:d ++¹ž F 101:d ++¹¹ F 102:d ++¹º F 103:d ++¹» F 104:d ++¹Œ F 105:d ++¹œ F 106:d ++¹Ÿ F 107:d ++¹¿ F 108:d ++¹À F 109:d ++¹Á F 110:d ++¹Â F 111:d ++¹Ã F 112:d ++¹Ä F 113:d ++¹Å F 114:d ++¹Æ F 115:d ++¹Ç F 116:d ++¹È F 117:d ++¹É F 118:d ++¹Ê F 119:d ++¹Ë F 120:d ++¹Ì F 121:d ++¹Í F 122:d ++¹Î F 123:d ++¹Ï F 124:d ++¹Ð F 125:d ++¹Ñ F 126:d ++¹Ò F 127:d ++¹Ó F 128:d ++¹Ô F 129:d ++¹Õ F 130:d ++¹Ö F 131:d ++¹× F 132:d ++¹Ø F 133:d ++¹Ù F 134:d ++¹Ú F 135:d ++¹Û F 136:d ++¹Ü F 137:d ++¹Ý F 138:d ++¹Þ F 139:d ++¹ß F 140:d ++¹à F 141:d ++¹á F 142:d ++¹â F 143:d ++¹ã F 144:d ++¹ä F 145:d ++¹å F 146:d ++¹æ F 147:d ++¹ç F 148:d ++¹è F 149:d ++¹é F 150:d ++¹ê F 151:d ++¹ë F 152:d ++¹ì F 153:d ++¹í F 154:d ++¹î F 155:d ++¹ï F 156:d ++¹ð F 157:d ++¹ñ F 158:d ++¹ò F 159:d ++¹ó F 160:d ++¹ô F 161:d ++¹õ F 162:d ++¹ö F 163:d ++¹÷ F 164:d ++¹ø F 165:d ++¹ù F 166:d ++¹ú F 167:d ++¹û F 168:d ++¹ü F 169:d ++¹ý F 170:d ++¹þ F 171:d ++º¡ F 172:d ++º¢ F 173:d ++º£ F 174:d ++º€ F 175:d ++º¥ F 176:d ++ºŠ F 177:d ++º§ F 178:d ++ºš F 179:d ++º© F 180:d ++ºª F 181:d ++º« F 182:d ++º¬ F 183:d ++º F 184:d ++º® F 185:d ++º¯ F 186:d ++º° F 187:d ++º± F 188:d ++º² F 189:d ++º³ F 190:d ++ºŽ F 191:d ++ºµ F 192:d ++º¶ F 193:d ++º· F 194:d ++ºž F 195:d ++º¹ F 196:d ++ºº F 197:d ++º» F 198:d ++ºŒ F 199:d ++ºœ F 200:d ++ºŸ F 201:d ++º¿ F 202:d ++ºÀ F 203:d ++ºÁ F 204:d ++ºÂ F 205:d ++ºÃ F 206:d ++ºÄ F 207:d ++ºÅ F 208:d ++ºÆ F 209:d ++ºÇ F 210:d ++ºÈ F 211:d ++ºÉ F 212:d ++ºÊ F 213:d ++ºË F 214:d ++ºÌ F 215:d ++ºÍ F 216:d ++ºÎ F 217:d ++ºÏ F 218:d ++ºÐ F 219:d ++ºÑ F 220:d ++ºÒ F 221:d ++ºÓ F 222:d ++ºÔ F 223:d ++ºÕ F 224:d ++ºÖ F 225:d ++º× F 226:d ++ºØ F 227:d ++ºÙ F 228:d ++ºÚ F 229:d ++ºÛ F 230:d ++ºÜ F 231:d ++ºÝ F 232:d ++ºÞ F 233:d ++ºß F 234:d ++ºà F 235:d ++ºá F 236:d ++ºâ F 237:d ++ºã F 238:d ++ºä F 239:d ++ºå F 240:d ++ºæ F 241:d ++ºç F 242:d ++ºè F 243:d ++ºé F 244:d ++ºê F 245:d ++ºë F 246:d ++ºì F 247:d ++ºí F 248:d ++ºî F 249:d ++ºï F 250:d ++ºð F 251:d ++ºñ F 252:d ++ºò F 253:d ++ºó F 254:d ++ºô F 255:d ++ºõ F 0:e ++ºö F 1:e ++º÷ F 2:e ++ºø F 3:e ++ºù F 4:e ++ºú F 5:e ++ºû F 6:e ++ºü F 7:e ++ºý F 8:e ++ºþ F 9:e ++»¡ F 10:e ++»¢ F 11:e ++»£ F 12:e ++»€ F 13:e ++»¥ F 14:e ++»Š F 15:e ++»§ F 16:e ++»š F 17:e ++»© F 18:e ++»ª F 19:e ++»« F 20:e ++»¬ F 21:e ++» F 22:e ++»® F 23:e ++»¯ F 24:e ++»° F 25:e ++»± F 26:e ++»² F 27:e ++»³ F 28:e ++»Ž F 29:e ++»µ F 30:e ++»¶ F 31:e ++»· F 32:e ++»ž F 33:e ++»¹ F 34:e ++»º F 35:e ++»» F 36:e ++»Œ F 37:e ++»œ F 38:e ++»Ÿ F 39:e ++»¿ F 40:e ++»À F 41:e ++»Á F 42:e ++»Â F 43:e ++»Ã F 44:e ++»Ä F 45:e ++»Å F 46:e ++»Æ F 47:e ++»Ç F 48:e ++»È F 49:e ++»É F 50:e ++»Ê F 51:e ++»Ë F 52:e ++»Ì F 53:e ++»Í F 54:e ++»Î F 55:e ++»Ï F 56:e ++»Ð F 57:e ++»Ñ F 58:e ++»Ò F 59:e ++»Ó F 60:e ++»Ô F 61:e ++»Õ F 62:e ++»Ö F 63:e ++»× F 64:e ++»Ø F 65:e ++»Ù F 66:e ++»Ú F 67:e ++»Û F 68:e ++»Ü F 69:e ++»Ý F 70:e ++»Þ F 71:e ++»ß F 72:e ++»à F 73:e ++»á F 74:e ++»â F 75:e ++»ã F 76:e ++»ä F 77:e ++»å F 78:e ++»æ F 79:e ++»ç F 80:e ++»è F 81:e ++»é F 82:e ++»ê F 83:e ++»ë F 84:e ++»ì F 85:e ++»í F 86:e ++»î F 87:e ++»ï F 88:e ++»ð F 89:e ++»ñ F 90:e ++»ò F 91:e ++»ó F 92:e ++»ô F 93:e ++»õ F 94:e ++»ö F 95:e ++»÷ F 96:e ++»ø F 97:e ++»ù F 98:e ++»ú F 99:e ++»û F 100:e ++»ü F 101:e ++»ý F 102:e ++»þ F 103:e ++Œ¡ F 104:e ++Œ¢ F 105:e ++Œ£ F 106:e ++Œ€ F 107:e ++Œ¥ F 108:e ++ŒŠ F 109:e ++Œ§ F 110:e ++Œš F 111:e ++Œ© F 112:e ++Œª F 113:e ++Œ« F 114:e ++Œ¬ F 115:e ++Œ F 116:e ++Œ® F 117:e ++Œ¯ F 118:e ++Œ° F 119:e ++Œ± F 120:e ++Œ² F 121:e ++Œ³ F 122:e ++ŒŽ F 123:e ++Œµ F 124:e ++Œ¶ F 125:e ++Œ· F 126:e ++Œž F 127:e ++Œ¹ F 128:e ++Œº F 129:e ++Œ» F 130:e ++ŒŒ F 131:e ++Œœ F 132:e ++ŒŸ F 133:e ++Œ¿ F 134:e ++ŒÀ F 135:e ++ŒÁ F 136:e ++ŒÂ F 137:e ++ŒÃ F 138:e ++ŒÄ F 139:e ++ŒÅ F 140:e ++ŒÆ F 141:e ++ŒÇ F 142:e ++ŒÈ F 143:e ++ŒÉ F 144:e ++ŒÊ F 145:e ++ŒË F 146:e ++ŒÌ F 147:e ++ŒÍ F 148:e ++ŒÎ F 149:e ++ŒÏ F 150:e ++ŒÐ F 151:e ++ŒÑ F 152:e ++ŒÒ F 153:e ++ŒÓ F 154:e ++ŒÔ F 155:e ++ŒÕ F 156:e ++ŒÖ F 157:e ++Œ× F 158:e ++ŒØ F 159:e ++ŒÙ F 160:e ++ŒÚ F 161:e ++ŒÛ F 162:e ++ŒÜ F 163:e ++ŒÝ F 164:e ++ŒÞ F 165:e ++Œß F 166:e ++Œà F 167:e ++Œá F 168:e ++Œâ F 169:e ++Œã F 170:e ++Œä F 171:e ++Œå F 172:e ++Œæ F 173:e ++Œç F 174:e ++Œè F 175:e ++Œé F 176:e ++Œê F 177:e ++Œë F 178:e ++Œì F 179:e ++Œí F 180:e ++Œî F 181:e ++Œï F 182:e ++Œð F 183:e ++Œñ F 184:e ++Œò F 185:e ++Œó F 186:e ++Œô F 187:e ++Œõ F 188:e ++Œö F 189:e ++Œ÷ F 190:e ++Œø F 191:e ++Œù F 192:e ++Œú F 193:e ++Œû F 194:e ++Œü F 195:e ++Œý F 196:e ++Œþ F 197:e ++œ¡ F 198:e ++œ¢ F 199:e ++œ£ F 200:e ++œ€ F 201:e ++œ¥ F 202:e ++œŠ F 203:e ++œ§ F 204:e ++œš F 205:e ++œ© F 206:e ++œª F 207:e ++œ« F 208:e ++œ¬ F 209:e ++œ F 210:e ++œ® F 211:e ++œ¯ F 212:e ++œ° F 213:e ++œ± F 214:e ++œ² F 215:e ++œ³ F 216:e ++œŽ F 217:e ++œµ F 218:e ++œ¶ F 219:e ++œ· F 220:e ++œž F 221:e ++œ¹ F 222:e ++œº F 223:e ++œ» F 224:e ++œŒ F 225:e ++œœ F 226:e ++œŸ F 227:e ++œ¿ F 228:e ++œÀ F 229:e ++œÁ F 230:e ++œÂ F 231:e ++œÃ F 232:e ++œÄ F 233:e ++œÅ F 234:e ++œÆ F 235:e ++œÇ F 236:e ++œÈ F 237:e ++œÉ F 238:e ++œÊ F 239:e ++œË F 240:e ++œÌ F 241:e ++œÍ F 242:e ++œÎ F 243:e ++œÏ F 244:e ++œÐ F 245:e ++œÑ F 246:e ++œÒ F 247:e ++œÓ F 248:e ++œÔ F 249:e ++œÕ F 250:e ++œÖ F 251:e ++œ× F 252:e ++œØ F 253:e ++œÙ F 254:e ++œÚ F 255:e ++œÛ F 0:f ++œÜ F 1:f ++œÝ F 2:f ++œÞ F 3:f ++œß F 4:f ++œà F 5:f ++œá F 6:f ++œâ F 7:f ++œã F 8:f ++œä F 9:f ++œå F 10:f ++œæ F 11:f ++œç F 12:f ++œè F 13:f ++œé F 14:f ++œê F 15:f ++œë F 16:f ++œì F 17:f ++œí F 18:f ++œî F 19:f ++œï F 20:f ++œð F 21:f ++œñ F 22:f ++œò F 23:f ++œó F 24:f ++œô F 25:f ++œõ F 26:f ++œö F 27:f ++œ÷ F 28:f ++œø F 29:f ++œù F 30:f ++œú F 31:f ++œû F 32:f ++œü F 33:f ++œý F 34:f ++œþ F 35:f ++Ÿ¡ F 36:f ++Ÿ¢ F 37:f ++Ÿ£ F 38:f ++Ÿ€ F 39:f ++Ÿ¥ F 40:f ++ŸŠ F 41:f ++Ÿ§ F 42:f ++Ÿš F 43:f ++Ÿ© F 44:f ++Ÿª F 45:f ++Ÿ« F 46:f ++Ÿ¬ F 47:f ++Ÿ F 48:f ++Ÿ® F 49:f ++Ÿ¯ F 50:f ++Ÿ° F 51:f ++Ÿ± F 52:f ++Ÿ² F 53:f ++Ÿ³ F 54:f ++ŸŽ F 55:f ++Ÿµ F 56:f ++Ÿ¶ F 57:f ++Ÿ· F 58:f ++Ÿž F 59:f ++Ÿ¹ F 60:f ++Ÿº F 61:f ++Ÿ» F 62:f ++ŸŒ F 63:f ++Ÿœ F 64:f ++ŸŸ F 65:f ++Ÿ¿ F 66:f ++ŸÀ F 67:f ++ŸÁ F 68:f ++ŸÂ F 69:f ++ŸÃ F 70:f ++ŸÄ F 71:f ++ŸÅ F 72:f ++ŸÆ F 73:f ++ŸÇ F 74:f ++ŸÈ F 75:f ++ŸÉ F 76:f ++ŸÊ F 77:f ++ŸË F 78:f ++ŸÌ F 79:f ++ŸÍ F 80:f ++ŸÎ F 81:f ++ŸÏ F 82:f ++ŸÐ F 83:f ++ŸÑ F 84:f ++ŸÒ F 85:f ++ŸÓ F 86:f ++ŸÔ F 87:f ++ŸÕ F 88:f ++ŸÖ F 89:f ++Ÿ× F 90:f ++ŸØ F 91:f ++ŸÙ F 92:f ++ŸÚ F 93:f ++ŸÛ F 94:f ++ŸÜ F 95:f ++ŸÝ F 96:f ++ŸÞ F 97:f ++Ÿß F 98:f ++Ÿà F 99:f ++Ÿá F 100:f ++Ÿâ F 101:f ++Ÿã F 102:f ++Ÿä F 103:f ++Ÿå F 104:f ++Ÿæ F 105:f ++Ÿç F 106:f ++Ÿè F 107:f ++Ÿé F 108:f ++Ÿê F 109:f ++Ÿë F 110:f ++Ÿì F 111:f ++Ÿí F 112:f ++Ÿî F 113:f ++Ÿï F 114:f ++Ÿð F 115:f ++Ÿñ F 116:f ++Ÿò F 117:f ++Ÿó F 118:f ++Ÿô F 119:f ++Ÿõ F 120:f ++Ÿö F 121:f ++Ÿ÷ F 122:f ++Ÿø F 123:f ++Ÿù F 124:f ++Ÿú F 125:f ++Ÿû F 126:f ++Ÿü F 127:f ++Ÿý F 128:f ++Ÿþ F 129:f ++¿¡ F 130:f ++¿¢ F 131:f ++¿£ F 132:f ++¿€ F 133:f ++¿¥ F 134:f ++¿Š F 135:f ++¿§ F 136:f ++¿š F 137:f ++¿© F 138:f ++¿ª F 139:f ++¿« F 140:f ++¿¬ F 141:f ++¿ F 142:f ++¿® F 143:f ++¿¯ F 144:f ++¿° F 145:f ++¿± F 146:f ++¿² F 147:f ++¿³ F 148:f ++¿Ž F 149:f ++¿µ F 150:f ++¿¶ F 151:f ++¿· F 152:f ++¿ž F 153:f ++¿¹ F 154:f ++¿º F 155:f ++¿» F 156:f ++¿Œ F 157:f ++¿œ F 158:f ++¿Ÿ F 159:f ++¿¿ F 160:f ++¿À F 161:f ++¿Á F 162:f ++¿Â F 163:f ++¿Ã F 164:f ++¿Ä F 165:f ++¿Å F 166:f ++¿Æ F 167:f ++¿Ç F 168:f ++¿È F 169:f ++¿É F 170:f ++¿Ê F 171:f ++¿Ë F 172:f ++¿Ì F 173:f ++¿Í F 174:f ++¿Î F 175:f ++¿Ï F 176:f ++¿Ð F 177:f ++¿Ñ F 178:f ++¿Ò F 179:f ++¿Ó F 180:f ++¿Ô F 181:f ++¿Õ F 182:f ++¿Ö F 183:f ++¿× F 184:f ++¿Ø F 185:f ++¿Ù F 186:f ++¿Ú F 187:f ++¿Û F 188:f ++¿Ü F 189:f ++¿Ý F 190:f ++¿Þ F 191:f ++¿ß F 192:f ++¿à F 193:f ++¿á F 194:f ++¿â F 195:f ++¿ã F 196:f ++¿ä F 197:f ++¿å F 198:f ++¿æ F 199:f ++¿ç F 200:f ++¿è F 201:f ++¿é F 202:f ++¿ê F 203:f ++¿ë F 204:f ++¿ì F 205:f ++¿í F 206:f ++¿î F 207:f ++¿ï F 208:f ++¿ð F 209:f ++¿ñ F 210:f ++¿ò F 211:f ++¿ó F 212:f ++¿ô F 213:f ++¿õ F 214:f ++¿ö F 215:f ++¿÷ F 216:f ++¿ø F 217:f ++¿ù F 218:f ++¿ú F 219:f ++¿û F 220:f ++¿ü F 221:f ++¿ý F 222:f ++¿þ F 223:f ++À¡ F 224:f ++À¢ F 225:f ++À£ F 226:f ++À€ F 227:f ++À¥ F 228:f ++ÀŠ F 229:f ++À§ F 230:f ++Àš F 231:f ++À© F 232:f ++Àª F 233:f ++À« F 234:f ++À¬ F 235:f ++À F 236:f ++À® F 237:f ++À¯ F 238:f ++À° F 239:f ++À± F 240:f ++À² F 241:f ++À³ F 242:f ++ÀŽ F 243:f ++Àµ F 244:f ++À¶ F 245:f ++À· F 246:f ++Àž F 247:f ++À¹ F 248:f ++Àº F 249:f ++À» F 250:f ++ÀŒ F 251:f ++Àœ F 252:f ++ÀŸ F 253:f ++À¿ F 254:f ++ÀÀ F 255:f ++ÀÁ F 0:g ++À F 1:g ++Àà F 2:g ++ÀÄ F 3:g ++ÀÅ F 4:g ++ÀÆ F 5:g ++ÀÇ F 6:g ++ÀÈ F 7:g ++ÀÉ F 8:g ++ÀÊ F 9:g ++ÀË F 10:g ++ÀÌ F 11:g ++ÀÍ F 12:g ++ÀÎ F 13:g ++ÀÏ F 14:g ++ÀÐ F 15:g ++ÀÑ F 16:g ++ÀÒ F 17:g ++ÀÓ F 18:g ++ÀÔ F 19:g ++ÀÕ F 20:g ++ÀÖ F 21:g ++À× F 22:g ++ÀØ F 23:g ++ÀÙ F 24:g ++ÀÚ F 25:g ++ÀÛ F 26:g ++ÀÜ F 27:g ++ÀÝ F 28:g ++ÀÞ F 29:g ++Àß F 30:g ++Àà F 31:g ++Àá F 32:g ++Àâ F 33:g ++Àã F 34:g ++Àä F 35:g ++Àå F 36:g ++Àæ F 37:g ++Àç F 38:g ++Àè F 39:g ++Àé F 40:g ++Àê F 41:g ++Àë F 42:g ++Àì F 43:g ++Àí F 44:g ++Àî F 45:g ++Àï F 46:g ++Àð F 47:g ++Àñ F 48:g ++Àò F 49:g ++Àó F 50:g ++Àô F 51:g ++Àõ F 52:g ++Àö F 53:g ++À÷ F 54:g ++Àø F 55:g ++Àù F 56:g ++Àú F 57:g ++Àû F 58:g ++Àü F 59:g ++Àý F 60:g ++Àþ F 61:g ++Á¡ F 62:g ++Á¢ F 63:g ++Á£ F 64:g ++Á€ F 65:g ++Á¥ F 66:g ++ÁŠ F 67:g ++Á§ F 68:g ++Áš F 69:g ++Á© F 70:g ++Áª F 71:g ++Á« F 72:g ++Á¬ F 73:g ++Á F 74:g ++Á® F 75:g ++Á¯ F 76:g ++Á° F 77:g ++Á± F 78:g ++Á² F 79:g ++Á³ F 80:g ++ÁŽ F 81:g ++Áµ F 82:g ++Á¶ F 83:g ++Á· F 84:g ++Áž F 85:g ++Á¹ F 86:g ++Áº F 87:g ++Á» F 88:g ++ÁŒ F 89:g ++Áœ F 90:g ++ÁŸ F 91:g ++Á¿ F 92:g ++ÁÀ F 93:g ++ÁÁ F 94:g ++Á F 95:g ++Áà F 96:g ++ÁÄ F 97:g ++ÁÅ F 98:g ++ÁÆ F 99:g ++ÁÇ F 100:g ++ÁÈ F 101:g ++ÁÉ F 102:g ++ÁÊ F 103:g ++ÁË F 104:g ++ÁÌ F 105:g ++ÁÍ F 106:g ++ÁÎ F 107:g ++ÁÏ F 108:g ++ÁÐ F 109:g ++ÁÑ F 110:g ++ÁÒ F 111:g ++ÁÓ F 112:g ++ÁÔ F 113:g ++ÁÕ F 114:g ++ÁÖ F 115:g ++Á× F 116:g ++ÁØ F 117:g ++ÁÙ F 118:g ++ÁÚ F 119:g ++ÁÛ F 120:g ++ÁÜ F 121:g ++ÁÝ F 122:g ++ÁÞ F 123:g ++Áß F 124:g ++Áà F 125:g ++Áá F 126:g ++Áâ F 127:g ++Áã F 128:g ++Áä F 129:g ++Áå F 130:g ++Áæ F 131:g ++Áç F 132:g ++Áè F 133:g ++Áé F 134:g ++Áê F 135:g ++Áë F 136:g ++Áì F 137:g ++Áí F 138:g ++Áî F 139:g ++Áï F 140:g ++Áð F 141:g ++Áñ F 142:g ++Áò F 143:g ++Áó F 144:g ++Áô F 145:g ++Áõ F 146:g ++Áö F 147:g ++Á÷ F 148:g ++Áø F 149:g ++Áù F 150:g ++Áú F 151:g ++Áû F 152:g ++Áü F 153:g ++Áý F 154:g ++Áþ F 155:g ++¡ F 156:g ++¢ F 157:g ++£ F 158:g ++€ F 159:g ++Â¥ F 160:g ++Š F 161:g ++§ F 162:g ++š F 163:g ++© F 164:g ++ª F 165:g ++« F 166:g ++¬ F 167:g ++ F 168:g ++® F 169:g ++¯ F 170:g ++° F 171:g ++± F 172:g ++² F 173:g ++³ F 174:g ++ÂŽ F 175:g ++µ F 176:g ++¶ F 177:g ++· F 178:g ++ž F 179:g ++¹ F 180:g ++º F 181:g ++» F 182:g ++ÂŒ F 183:g ++Âœ F 184:g ++Ÿ F 185:g ++¿ F 186:g ++ÂÀ F 187:g ++ÂÁ F 188:g ++ F 189:g ++Âà F 190:g ++ÂÄ F 191:g ++ÂÅ F 192:g ++ÂÆ F 193:g ++ÂÇ F 194:g ++ÂÈ F 195:g ++ÂÉ F 196:g ++ÂÊ F 197:g ++ÂË F 198:g ++ÂÌ F 199:g ++ÂÍ F 200:g ++ÂÎ F 201:g ++ÂÏ F 202:g ++ÂÐ F 203:g ++ÂÑ F 204:g ++ÂÒ F 205:g ++ÂÓ F 206:g ++ÂÔ F 207:g ++ÂÕ F 208:g ++ÂÖ F 209:g ++Â× F 210:g ++ÂØ F 211:g ++ÂÙ F 212:g ++ÂÚ F 213:g ++ÂÛ F 214:g ++ÂÜ F 215:g ++ÂÝ F 216:g ++ÂÞ F 217:g ++Âß F 218:g ++Âà F 219:g ++Âá F 220:g ++Ââ F 221:g ++Âã F 222:g ++Âä F 223:g ++Âå F 224:g ++Âæ F 225:g ++Âç F 226:g ++Âè F 227:g ++Âé F 228:g ++Âê F 229:g ++Âë F 230:g ++Âì F 231:g ++Âí F 232:g ++Âî F 233:g ++Âï F 234:g ++Âð F 235:g ++Âñ F 236:g ++Âò F 237:g ++Âó F 238:g ++Âô F 239:g ++Âõ F 240:g ++Âö F 241:g ++Â÷ F 242:g ++Âø F 243:g ++Âù F 244:g ++Âú F 245:g ++Âû F 246:g ++Âü F 247:g ++Âý F 248:g ++Âþ F 249:g ++á F 250:g ++â F 251:g ++ã F 252:g ++À F 253:g ++Ã¥ F 254:g ++Ê F 255:g ++ç F 0:h ++Ú F 1:h ++é F 2:h ++ê F 3:h ++ë F 4:h ++ì F 5:h ++à F 6:h ++î F 7:h ++ï F 8:h ++ð F 9:h ++ñ F 10:h ++ò F 11:h ++ó F 12:h ++ÃŽ F 13:h ++õ F 14:h ++ö F 15:h ++÷ F 16:h ++Þ F 17:h ++ù F 18:h ++ú F 19:h ++û F 20:h ++ÃŒ F 21:h ++Ãœ F 22:h ++ß F 23:h ++ÿ F 24:h ++ÃÀ F 25:h ++ÃÁ F 26:h ++àF 27:h ++Ãà F 28:h ++ÃÄ F 29:h ++ÃÅ F 30:h ++ÃÆ F 31:h ++ÃÇ F 32:h ++ÃÈ F 33:h ++ÃÉ F 34:h ++ÃÊ F 35:h ++ÃË F 36:h ++ÃÌ F 37:h ++ÃÍ F 38:h ++ÃÎ F 39:h ++ÃÏ F 40:h ++ÃÐ F 41:h ++ÃÑ F 42:h ++ÃÒ F 43:h ++ÃÓ F 44:h ++ÃÔ F 45:h ++ÃÕ F 46:h ++ÃÖ F 47:h ++Ã× F 48:h ++ÃØ F 49:h ++ÃÙ F 50:h ++ÃÚ F 51:h ++ÃÛ F 52:h ++ÃÜ F 53:h ++ÃÝ F 54:h ++ÃÞ F 55:h ++Ãß F 56:h ++Ãà F 57:h ++Ãá F 58:h ++Ãâ F 59:h ++Ãã F 60:h ++Ãä F 61:h ++Ãå F 62:h ++Ãæ F 63:h ++Ãç F 64:h ++Ãè F 65:h ++Ãé F 66:h ++Ãê F 67:h ++Ãë F 68:h ++Ãì F 69:h ++Ãí F 70:h ++Ãî F 71:h ++Ãï F 72:h ++Ãð F 73:h ++Ãñ F 74:h ++Ãò F 75:h ++Ãó F 76:h ++Ãô F 77:h ++Ãõ F 78:h ++Ãö F 79:h ++Ã÷ F 80:h ++Ãø F 81:h ++Ãù F 82:h ++Ãú F 83:h ++Ãû F 84:h ++Ãü F 85:h ++Ãý F 86:h ++Ãþ F 87:h ++Ä¡ F 88:h ++Ä¢ F 89:h ++Ä£ F 90:h ++Ä€ F 91:h ++Ä¥ F 92:h ++ÄŠ F 93:h ++ħ F 94:h ++Äš F 95:h ++Ä© F 96:h ++Ī F 97:h ++Ä« F 98:h ++Ĭ F 99:h ++Ä F 100:h ++Ä® F 101:h ++į F 102:h ++Ä° F 103:h ++ı F 104:h ++IJ F 105:h ++ij F 106:h ++ÄŽ F 107:h ++ĵ F 108:h ++Ķ F 109:h ++Ä· F 110:h ++Äž F 111:h ++Ĺ F 112:h ++ĺ F 113:h ++Ä» F 114:h ++ÄŒ F 115:h ++Äœ F 116:h ++ÄŸ F 117:h ++Ä¿ F 118:h ++ÄÀ F 119:h ++ÄÁ F 120:h ++Ä F 121:h ++Äà F 122:h ++ÄÄ F 123:h ++ÄÅ F 124:h ++ÄÆ F 125:h ++ÄÇ F 126:h ++ÄÈ F 127:h ++ÄÉ F 128:h ++ÄÊ F 129:h ++ÄË F 130:h ++ÄÌ F 131:h ++ÄÍ F 132:h ++ÄÎ F 133:h ++ÄÏ F 134:h ++ÄÐ F 135:h ++ÄÑ F 136:h ++ÄÒ F 137:h ++ÄÓ F 138:h ++ÄÔ F 139:h ++ÄÕ F 140:h ++ÄÖ F 141:h ++Ä× F 142:h ++ÄØ F 143:h ++ÄÙ F 144:h ++ÄÚ F 145:h ++ÄÛ F 146:h ++ÄÜ F 147:h ++ÄÝ F 148:h ++ÄÞ F 149:h ++Äß F 150:h ++Äà F 151:h ++Äá F 152:h ++Äâ F 153:h ++Äã F 154:h ++Ää F 155:h ++Äå F 156:h ++Äæ F 157:h ++Äç F 158:h ++Äè F 159:h ++Äé F 160:h ++Äê F 161:h ++Äë F 162:h ++Äì F 163:h ++Äí F 164:h ++Äî F 165:h ++Äï F 166:h ++Äð F 167:h ++Äñ F 168:h ++Äò F 169:h ++Äó F 170:h ++Äô F 171:h ++Äõ F 172:h ++Äö F 173:h ++Ä÷ F 174:h ++Äø F 175:h ++Äù F 176:h ++Äú F 177:h ++Äû F 178:h ++Äü F 179:h ++Äý F 180:h ++Äþ F 181:h ++Å¡ F 182:h ++Å¢ F 183:h ++Å£ F 184:h ++Å€ F 185:h ++Å¥ F 186:h ++ÅŠ F 187:h ++ŧ F 188:h ++Åš F 189:h ++Å© F 190:h ++Ū F 191:h ++Å« F 192:h ++Ŭ F 193:h ++Å F 194:h ++Å® F 195:h ++ů F 196:h ++Å° F 197:h ++ű F 198:h ++Ų F 199:h ++ų F 200:h ++ÅŽ F 201:h ++ŵ F 202:h ++Ŷ F 203:h ++Å· F 204:h ++Åž F 205:h ++Ź F 206:h ++ź F 207:h ++Å» F 208:h ++ÅŒ F 209:h ++Åœ F 210:h ++ÅŸ F 211:h ++Å¿ F 212:h ++ÅÀ F 213:h ++ÅÁ F 214:h ++Å F 215:h ++Åà F 216:h ++ÅÄ F 217:h ++ÅÅ F 218:h ++ÅÆ F 219:h ++ÅÇ F 220:h ++ÅÈ F 221:h ++ÅÉ F 222:h ++ÅÊ F 223:h ++ÅË F 224:h ++ÅÌ F 225:h ++ÅÍ F 226:h ++ÅÎ F 227:h ++ÅÏ F 228:h ++ÅÐ F 229:h ++ÅÑ F 230:h ++ÅÒ F 231:h ++ÅÓ F 232:h ++ÅÔ F 233:h ++ÅÕ F 234:h ++ÅÖ F 235:h ++Å× F 236:h ++ÅØ F 237:h ++ÅÙ F 238:h ++ÅÚ F 239:h ++ÅÛ F 240:h ++ÅÜ F 241:h ++ÅÝ F 242:h ++ÅÞ F 243:h ++Åß F 244:h ++Åà F 245:h ++Åá F 246:h ++Åâ F 247:h ++Åã F 248:h ++Åä F 249:h ++Åå F 250:h ++Åæ F 251:h ++Åç F 252:h ++Åè F 253:h ++Åé F 254:h ++Åê F 255:h ++Åë F 0:i ++Åì F 1:i ++Åí F 2:i ++Åî F 3:i ++Åï F 4:i ++Åð F 5:i ++Åñ F 6:i ++Åò F 7:i ++Åó F 8:i ++Åô F 9:i ++Åõ F 10:i ++Åö F 11:i ++Å÷ F 12:i ++Åø F 13:i ++Åù F 14:i ++Åú F 15:i ++Åû F 16:i ++Åü F 17:i ++Åý F 18:i ++Åþ F 19:i ++Æ¡ F 20:i ++Æ¢ F 21:i ++Æ£ F 22:i ++Æ€ F 23:i ++Æ¥ F 24:i ++ÆŠ F 25:i ++Ƨ F 26:i ++Æš F 27:i ++Æ© F 28:i ++ƪ F 29:i ++Æ« F 30:i ++Ƭ F 31:i ++Æ F 32:i ++Æ® F 33:i ++Ư F 34:i ++Æ° F 35:i ++Ʊ F 36:i ++Ʋ F 37:i ++Ƴ F 38:i ++ÆŽ F 39:i ++Ƶ F 40:i ++ƶ F 41:i ++Æ· F 42:i ++Æž F 43:i ++ƹ F 44:i ++ƺ F 45:i ++Æ» F 46:i ++ÆŒ F 47:i ++Æœ F 48:i ++ÆŸ F 49:i ++Æ¿ F 50:i ++ÆÀ F 51:i ++ÆÁ F 52:i ++Æ F 53:i ++Æà F 54:i ++ÆÄ F 55:i ++ÆÅ F 56:i ++ÆÆ F 57:i ++ÆÇ F 58:i ++ÆÈ F 59:i ++ÆÉ F 60:i ++ÆÊ F 61:i ++ÆË F 62:i ++ÆÌ F 63:i ++ÆÍ F 64:i ++ÆÎ F 65:i ++ÆÏ F 66:i ++ÆÐ F 67:i ++ÆÑ F 68:i ++ÆÒ F 69:i ++ÆÓ F 70:i ++ÆÔ F 71:i ++ÆÕ F 72:i ++ÆÖ F 73:i ++Æ× F 74:i ++ÆØ F 75:i ++ÆÙ F 76:i ++ÆÚ F 77:i ++ÆÛ F 78:i ++ÆÜ F 79:i ++ÆÝ F 80:i ++ÆÞ F 81:i ++Æß F 82:i ++Æà F 83:i ++Æá F 84:i ++Æâ F 85:i ++Æã F 86:i ++Æä F 87:i ++Æå F 88:i ++Ææ F 89:i ++Æç F 90:i ++Æè F 91:i ++Æé F 92:i ++Æê F 93:i ++Æë F 94:i ++Æì F 95:i ++Æí F 96:i ++Æî F 97:i ++Æï F 98:i ++Æð F 99:i ++Æñ F 100:i ++Æò F 101:i ++Æó F 102:i ++Æô F 103:i ++Æõ F 104:i ++Æö F 105:i ++Æ÷ F 106:i ++Æø F 107:i ++Æù F 108:i ++Æú F 109:i ++Æû F 110:i ++Æü F 111:i ++Æý F 112:i ++Æþ F 113:i ++Ç¡ F 114:i ++Ç¢ F 115:i ++Ç£ F 116:i ++Ç€ F 117:i ++Ç¥ F 118:i ++ÇŠ F 119:i ++ǧ F 120:i ++Çš F 121:i ++Ç© F 122:i ++Ǫ F 123:i ++Ç« F 124:i ++Ǭ F 125:i ++Ç F 126:i ++Ç® F 127:i ++ǯ F 128:i ++Ç° F 129:i ++DZ F 130:i ++Dz F 131:i ++dz F 132:i ++ÇŽ F 133:i ++ǵ F 134:i ++Ƕ F 135:i ++Ç· F 136:i ++Çž F 137:i ++ǹ F 138:i ++Ǻ F 139:i ++Ç» F 140:i ++ÇŒ F 141:i ++Çœ F 142:i ++ÇŸ F 143:i ++Ç¿ F 144:i ++ÇÀ F 145:i ++ÇÁ F 146:i ++Ç F 147:i ++Çà F 148:i ++ÇÄ F 149:i ++ÇÅ F 150:i ++ÇÆ F 151:i ++ÇÇ F 152:i ++ÇÈ F 153:i ++ÇÉ F 154:i ++ÇÊ F 155:i ++ÇË F 156:i ++ÇÌ F 157:i ++ÇÍ F 158:i ++ÇÎ F 159:i ++ÇÏ F 160:i ++ÇÐ F 161:i ++ÇÑ F 162:i ++ÇÒ F 163:i ++ÇÓ F 164:i ++ÇÔ F 165:i ++ÇÕ F 166:i ++ÇÖ F 167:i ++Ç× F 168:i ++ÇØ F 169:i ++ÇÙ F 170:i ++ÇÚ F 171:i ++ÇÛ F 172:i ++ÇÜ F 173:i ++ÇÝ F 174:i ++ÇÞ F 175:i ++Çß F 176:i ++Çà F 177:i ++Çá F 178:i ++Çâ F 179:i ++Çã F 180:i ++Çä F 181:i ++Çå F 182:i ++Çæ F 183:i ++Çç F 184:i ++Çè F 185:i ++Çé F 186:i ++Çê F 187:i ++Çë F 188:i ++Çì F 189:i ++Çí F 190:i ++Çî F 191:i ++Çï F 192:i ++Çð F 193:i ++Çñ F 194:i ++Çò F 195:i ++Çó F 196:i ++Çô F 197:i ++Çõ F 198:i ++Çö F 199:i ++Ç÷ F 200:i ++Çø F 201:i ++Çù F 202:i ++Çú F 203:i ++Çû F 204:i ++Çü F 205:i ++Çý F 206:i ++Çþ F 207:i ++È¡ F 208:i ++È¢ F 209:i ++È£ F 210:i ++È€ F 211:i ++È¥ F 212:i ++ÈŠ F 213:i ++ȧ F 214:i ++Èš F 215:i ++È© F 216:i ++Ȫ F 217:i ++È« F 218:i ++Ȭ F 219:i ++È F 220:i ++È® F 221:i ++ȯ F 222:i ++È° F 223:i ++ȱ F 224:i ++Ȳ F 225:i ++ȳ F 226:i ++ÈŽ F 227:i ++ȵ F 228:i ++ȶ F 229:i ++È· F 230:i ++Èž F 231:i ++ȹ F 232:i ++Ⱥ F 233:i ++È» F 234:i ++ÈŒ F 235:i ++Èœ F 236:i ++ÈŸ F 237:i ++È¿ F 238:i ++ÈÀ F 239:i ++ÈÁ F 240:i ++È F 241:i ++Èà F 242:i ++ÈÄ F 243:i ++ÈÅ F 244:i ++ÈÆ F 245:i ++ÈÇ F 246:i ++ÈÈ F 247:i ++ÈÉ F 248:i ++ÈÊ F 249:i ++ÈË F 250:i ++ÈÌ F 251:i ++ÈÍ F 252:i ++ÈÎ F 253:i ++ÈÏ F 254:i ++ÈÐ F 255:i ++ÈÑ F 0:j ++ÈÒ F 1:j ++ÈÓ F 2:j ++ÈÔ F 3:j ++ÈÕ F 4:j ++ÈÖ F 5:j ++È× F 6:j ++ÈØ F 7:j ++ÈÙ F 8:j ++ÈÚ F 9:j ++ÈÛ F 10:j ++ÈÜ F 11:j ++ÈÝ F 12:j ++ÈÞ F 13:j ++Èß F 14:j ++Èà F 15:j ++Èá F 16:j ++Èâ F 17:j ++Èã F 18:j ++Èä F 19:j ++Èå F 20:j ++Èæ F 21:j ++Èç F 22:j ++Èè F 23:j ++Èé F 24:j ++Èê F 25:j ++Èë F 26:j ++Èì F 27:j ++Èí F 28:j ++Èî F 29:j ++Èï F 30:j ++Èð F 31:j ++Èñ F 32:j ++Èò F 33:j ++Èó F 34:j ++Èô F 35:j ++Èõ F 36:j ++Èö F 37:j ++È÷ F 38:j ++Èø F 39:j ++Èù F 40:j ++Èú F 41:j ++Èû F 42:j ++Èü F 43:j ++Èý F 44:j ++Èþ F 45:j ++É¡ F 46:j ++É¢ F 47:j ++É£ F 48:j ++É€ F 49:j ++É¥ F 50:j ++ÉŠ F 51:j ++ɧ F 52:j ++Éš F 53:j ++É© F 54:j ++ɪ F 55:j ++É« F 56:j ++ɬ F 57:j ++É F 58:j ++É® F 59:j ++ɯ F 60:j ++É° F 61:j ++ɱ F 62:j ++ɲ F 63:j ++ɳ F 64:j ++ÉŽ F 65:j ++ɵ F 66:j ++ɶ F 67:j ++É· F 68:j ++Éž F 69:j ++ɹ F 70:j ++ɺ F 71:j ++É» F 72:j ++ÉŒ F 73:j ++Éœ F 74:j ++ÉŸ F 75:j ++É¿ F 76:j ++ÉÀ F 77:j ++ÉÁ F 78:j ++É F 79:j ++Éà F 80:j ++ÉÄ F 81:j ++ÉÅ F 82:j ++ÉÆ F 83:j ++ÉÇ F 84:j ++ÉÈ F 85:j ++ÉÉ F 86:j ++ÉÊ F 87:j ++ÉË F 88:j ++ÉÌ F 89:j ++ÉÍ F 90:j ++ÉÎ F 91:j ++ÉÏ F 92:j ++ÉÐ F 93:j ++ÉÑ F 94:j ++ÉÒ F 95:j ++ÉÓ F 96:j ++ÉÔ F 97:j ++ÉÕ F 98:j ++ÉÖ F 99:j ++É× F 100:j ++ÉØ F 101:j ++ÉÙ F 102:j ++ÉÚ F 103:j ++ÉÛ F 104:j ++ÉÜ F 105:j ++ÉÝ F 106:j ++ÉÞ F 107:j ++Éß F 108:j ++Éà F 109:j ++Éá F 110:j ++Éâ F 111:j ++Éã F 112:j ++Éä F 113:j ++Éå F 114:j ++Éæ F 115:j ++Éç F 116:j ++Éè F 117:j ++Éé F 118:j ++Éê F 119:j ++Éë F 120:j ++Éì F 121:j ++Éí F 122:j ++Éî F 123:j ++Éï F 124:j ++Éð F 125:j ++Éñ F 126:j ++Éò F 127:j ++Éó F 128:j ++Éô F 129:j ++Éõ F 130:j ++Éö F 131:j ++É÷ F 132:j ++Éø F 133:j ++Éù F 134:j ++Éú F 135:j ++Éû F 136:j ++Éü F 137:j ++Éý F 138:j ++Éþ F 139:j ++Ê¡ F 140:j ++Ê¢ F 141:j ++Ê£ F 142:j ++Ê€ F 143:j ++Ê¥ F 144:j ++ÊŠ F 145:j ++ʧ F 146:j ++Êš F 147:j ++Ê© F 148:j ++ʪ F 149:j ++Ê« F 150:j ++ʬ F 151:j ++Ê F 152:j ++Ê® F 153:j ++ʯ F 154:j ++Ê° F 155:j ++ʱ F 156:j ++ʲ F 157:j ++ʳ F 158:j ++ÊŽ F 159:j ++ʵ F 160:j ++ʶ F 161:j ++Ê· F 162:j ++Êž F 163:j ++ʹ F 164:j ++ʺ F 165:j ++Ê» F 166:j ++ÊŒ F 167:j ++Êœ F 168:j ++ÊŸ F 169:j ++Ê¿ F 170:j ++ÊÀ F 171:j ++ÊÁ F 172:j ++Ê F 173:j ++Êà F 174:j ++ÊÄ F 175:j ++ÊÅ F 176:j ++ÊÆ F 177:j ++ÊÇ F 178:j ++ÊÈ F 179:j ++ÊÉ F 180:j ++ÊÊ F 181:j ++ÊË F 182:j ++ÊÌ F 183:j ++ÊÍ F 184:j ++ÊÎ F 185:j ++ÊÏ F 186:j ++ÊÐ F 187:j ++ÊÑ F 188:j ++ÊÒ F 189:j ++ÊÓ F 190:j ++ÊÔ F 191:j ++ÊÕ F 192:j ++ÊÖ F 193:j ++Ê× F 194:j ++ÊØ F 195:j ++ÊÙ F 196:j ++ÊÚ F 197:j ++ÊÛ F 198:j ++ÊÜ F 199:j ++ÊÝ F 200:j ++ÊÞ F 201:j ++Êß F 202:j ++Êà F 203:j ++Êá F 204:j ++Êâ F 205:j ++Êã F 206:j ++Êä F 207:j ++Êå F 208:j ++Êæ F 209:j ++Êç F 210:j ++Êè F 211:j ++Êé F 212:j ++Êê F 213:j ++Êë F 214:j ++Êì F 215:j ++Êí F 216:j ++Êî F 217:j ++Êï F 218:j ++Êð F 219:j ++Êñ F 220:j ++Êò F 221:j ++Êó F 222:j ++Êô F 223:j ++Êõ F 224:j ++Êö F 225:j ++Ê÷ F 226:j ++Êø F 227:j ++Êù F 228:j ++Êú F 229:j ++Êû F 230:j ++Êü F 231:j ++Êý F 232:j ++Êþ F 233:j ++Ë¡ F 234:j ++Ë¢ F 235:j ++Ë£ F 236:j ++Ë€ F 237:j ++Ë¥ F 238:j ++ËŠ F 239:j ++˧ F 240:j ++Ëš F 241:j ++Ë© F 242:j ++˪ F 243:j ++Ë« F 244:j ++ˬ F 245:j ++Ë F 246:j ++Ë® F 247:j ++˯ F 248:j ++Ë° F 249:j ++˱ F 250:j ++˲ F 251:j ++˳ F 252:j ++ËŽ F 253:j ++˵ F 254:j ++˶ F 255:j ++Ë· F 0:k ++Ëž F 1:k ++˹ F 2:k ++˺ F 3:k ++Ë» F 4:k ++ËŒ F 5:k ++Ëœ F 6:k ++ËŸ F 7:k ++Ë¿ F 8:k ++ËÀ F 9:k ++ËÁ F 10:k ++Ë F 11:k ++Ëà F 12:k ++ËÄ F 13:k ++ËÅ F 14:k ++ËÆ F 15:k ++ËÇ F 16:k ++ËÈ F 17:k ++ËÉ F 18:k ++ËÊ F 19:k ++ËË F 20:k ++ËÌ F 21:k ++ËÍ F 22:k ++ËÎ F 23:k ++ËÏ F 24:k ++ËÐ F 25:k ++ËÑ F 26:k ++ËÒ F 27:k ++ËÓ F 28:k ++ËÔ F 29:k ++ËÕ F 30:k ++ËÖ F 31:k ++Ë× F 32:k ++ËØ F 33:k ++ËÙ F 34:k ++ËÚ F 35:k ++ËÛ F 36:k ++ËÜ F 37:k ++ËÝ F 38:k ++ËÞ F 39:k ++Ëß F 40:k ++Ëà F 41:k ++Ëá F 42:k ++Ëâ F 43:k ++Ëã F 44:k ++Ëä F 45:k ++Ëå F 46:k ++Ëæ F 47:k ++Ëç F 48:k ++Ëè F 49:k ++Ëé F 50:k ++Ëê F 51:k ++Ëë F 52:k ++Ëì F 53:k ++Ëí F 54:k ++Ëî F 55:k ++Ëï F 56:k ++Ëð F 57:k ++Ëñ F 58:k ++Ëò F 59:k ++Ëó F 60:k ++Ëô F 61:k ++Ëõ F 62:k ++Ëö F 63:k ++Ë÷ F 64:k ++Ëø F 65:k ++Ëù F 66:k ++Ëú F 67:k ++Ëû F 68:k ++Ëü F 69:k ++Ëý F 70:k ++Ëþ F 71:k ++Ì¡ F 72:k ++Ì¢ F 73:k ++Ì£ F 74:k ++Ì€ F 75:k ++Ì¥ F 76:k ++ÌŠ F 77:k ++̧ F 78:k ++Ìš F 79:k ++Ì© F 80:k ++̪ F 81:k ++Ì« F 82:k ++̬ F 83:k ++Ì F 84:k ++Ì® F 85:k ++̯ F 86:k ++Ì° F 87:k ++̱ F 88:k ++̲ F 89:k ++̳ F 90:k ++ÌŽ F 91:k ++̵ F 92:k ++̶ F 93:k ++Ì· F 94:k ++Ìž F 95:k ++̹ F 96:k ++̺ F 97:k ++Ì» F 98:k ++ÌŒ F 99:k ++Ìœ F 100:k ++ÌŸ F 101:k ++Ì¿ F 102:k ++ÌÀ F 103:k ++ÌÁ F 104:k ++Ì F 105:k ++Ìà F 106:k ++ÌÄ F 107:k ++ÌÅ F 108:k ++ÌÆ F 109:k ++ÌÇ F 110:k ++ÌÈ F 111:k ++ÌÉ F 112:k ++ÌÊ F 113:k ++ÌË F 114:k ++ÌÌ F 115:k ++ÌÍ F 116:k ++ÌÎ F 117:k ++ÌÏ F 118:k ++ÌÐ F 119:k ++ÌÑ F 120:k ++ÌÒ F 121:k ++ÌÓ F 122:k ++ÌÔ F 123:k ++ÌÕ F 124:k ++ÌÖ F 125:k ++Ì× F 126:k ++ÌØ F 127:k ++ÌÙ F 128:k ++ÌÚ F 129:k ++ÌÛ F 130:k ++ÌÜ F 131:k ++ÌÝ F 132:k ++ÌÞ F 133:k ++Ìß F 134:k ++Ìà F 135:k ++Ìá F 136:k ++Ìâ F 137:k ++Ìã F 138:k ++Ìä F 139:k ++Ìå F 140:k ++Ìæ F 141:k ++Ìç F 142:k ++Ìè F 143:k ++Ìé F 144:k ++Ìê F 145:k ++Ìë F 146:k ++Ìì F 147:k ++Ìí F 148:k ++Ìî F 149:k ++Ìï F 150:k ++Ìð F 151:k ++Ìñ F 152:k ++Ìò F 153:k ++Ìó F 154:k ++Ìô F 155:k ++Ìõ F 156:k ++Ìö F 157:k ++Ì÷ F 158:k ++Ìø F 159:k ++Ìù F 160:k ++Ìú F 161:k ++Ìû F 162:k ++Ìü F 163:k ++Ìý F 164:k ++Ìþ F 165:k ++Í¡ F 166:k ++Í¢ F 167:k ++Í£ F 168:k ++Í€ F 169:k ++Í¥ F 170:k ++ÍŠ F 171:k ++ͧ F 172:k ++Íš F 173:k ++Í© F 174:k ++ͪ F 175:k ++Í« F 176:k ++ͬ F 177:k ++Í F 178:k ++Í® F 179:k ++ͯ F 180:k ++Í° F 181:k ++ͱ F 182:k ++Ͳ F 183:k ++ͳ F 184:k ++ÍŽ F 185:k ++͵ F 186:k ++Ͷ F 187:k ++Í· F 188:k ++Íž F 189:k ++͹ F 190:k ++ͺ F 191:k ++Í» F 192:k ++ÍŒ F 193:k ++Íœ F 194:k ++ÍŸ F 195:k ++Í¿ F 196:k ++ÍÀ F 197:k ++ÍÁ F 198:k ++Í F 199:k ++Íà F 200:k ++ÍÄ F 201:k ++ÍÅ F 202:k ++ÍÆ F 203:k ++ÍÇ F 204:k ++ÍÈ F 205:k ++ÍÉ F 206:k ++ÍÊ F 207:k ++ÍË F 208:k ++ÍÌ F 209:k ++ÍÍ F 210:k ++ÍÎ F 211:k ++ÍÏ F 212:k ++ÍÐ F 213:k ++ÍÑ F 214:k ++ÍÒ F 215:k ++ÍÓ F 216:k ++ÍÔ F 217:k ++ÍÕ F 218:k ++ÍÖ F 219:k ++Í× F 220:k ++ÍØ F 221:k ++ÍÙ F 222:k ++ÍÚ F 223:k ++ÍÛ F 224:k ++ÍÜ F 225:k ++ÍÝ F 226:k ++ÍÞ F 227:k ++Íß F 228:k ++Íà F 229:k ++Íá F 230:k ++Íâ F 231:k ++Íã F 232:k ++Íä F 233:k ++Íå F 234:k ++Íæ F 235:k ++Íç F 236:k ++Íè F 237:k ++Íé F 238:k ++Íê F 239:k ++Íë F 240:k ++Íì F 241:k ++Íí F 242:k ++Íî F 243:k ++Íï F 244:k ++Íð F 245:k ++Íñ F 246:k ++Íò F 247:k ++Íó F 248:k ++Íô F 249:k ++Íõ F 250:k ++Íö F 251:k ++Í÷ F 252:k ++Íø F 253:k ++Íù F 254:k ++Íú F 255:k ++Íû F 0:l ++Íü F 1:l ++Íý F 2:l ++Íþ F 3:l ++Ρ F 4:l ++΢ F 5:l ++Σ F 6:l ++΀ F 7:l ++Î¥ F 8:l ++Ί F 9:l ++Χ F 10:l ++Κ F 11:l ++Ω F 12:l ++Ϊ F 13:l ++Ϋ F 14:l ++ά F 15:l ++Î F 16:l ++ή F 17:l ++ί F 18:l ++ΰ F 19:l ++α F 20:l ++β F 21:l ++γ F 22:l ++ÎŽ F 23:l ++ε F 24:l ++ζ F 25:l ++η F 26:l ++Ξ F 27:l ++ι F 28:l ++κ F 29:l ++λ F 30:l ++ÎŒ F 31:l ++Îœ F 32:l ++Ο F 33:l ++ο F 34:l ++ÎÀ F 35:l ++ÎÁ F 36:l ++ΠF 37:l ++Îà F 38:l ++ÎÄ F 39:l ++ÎÅ F 40:l ++ÎÆ F 41:l ++ÎÇ F 42:l ++ÎÈ F 43:l ++ÎÉ F 44:l ++ÎÊ F 45:l ++ÎË F 46:l ++ÎÌ F 47:l ++ÎÍ F 48:l ++ÎÎ F 49:l ++ÎÏ F 50:l ++ÎÐ F 51:l ++ÎÑ F 52:l ++ÎÒ F 53:l ++ÎÓ F 54:l ++ÎÔ F 55:l ++ÎÕ F 56:l ++ÎÖ F 57:l ++Î× F 58:l ++ÎØ F 59:l ++ÎÙ F 60:l ++ÎÚ F 61:l ++ÎÛ F 62:l ++ÎÜ F 63:l ++ÎÝ F 64:l ++ÎÞ F 65:l ++Îß F 66:l ++Îà F 67:l ++Îá F 68:l ++Îâ F 69:l ++Îã F 70:l ++Îä F 71:l ++Îå F 72:l ++Îæ F 73:l ++Îç F 74:l ++Îè F 75:l ++Îé F 76:l ++Îê F 77:l ++Îë F 78:l ++Îì F 79:l ++Îí F 80:l ++Îî F 81:l ++Îï F 82:l ++Îð F 83:l ++Îñ F 84:l ++Îò F 85:l ++Îó F 86:l ++Îô F 87:l ++Îõ F 88:l ++Îö F 89:l ++Î÷ F 90:l ++Îø F 91:l ++Îù F 92:l ++Îú F 93:l ++Îû F 94:l ++Îü F 95:l ++Îý F 96:l ++Îþ F 97:l ++Ï¡ F 98:l ++Ï¢ F 99:l ++Ï£ F 100:l ++Ï€ F 101:l ++Ï¥ F 102:l ++ÏŠ F 103:l ++ϧ F 104:l ++Ïš F 105:l ++Ï© F 106:l ++Ϫ F 107:l ++Ï« F 108:l ++Ϭ F 109:l ++Ï F 110:l ++Ï® F 111:l ++ϯ F 112:l ++Ï° F 113:l ++ϱ F 114:l ++ϲ F 115:l ++ϳ F 116:l ++ÏŽ F 117:l ++ϵ F 118:l ++϶ F 119:l ++Ï· F 120:l ++Ïž F 121:l ++Ϲ F 122:l ++Ϻ F 123:l ++Ï» F 124:l ++ÏŒ F 125:l ++Ïœ F 126:l ++ÏŸ F 127:l ++Ï¿ F 128:l ++ÏÀ F 129:l ++ÏÁ F 130:l ++Ï F 131:l ++Ïà F 132:l ++ÏÄ F 133:l ++ÏÅ F 134:l ++ÏÆ F 135:l ++ÏÇ F 136:l ++ÏÈ F 137:l ++ÏÉ F 138:l ++ÏÊ F 139:l ++ÏË F 140:l ++ÏÌ F 141:l ++ÏÍ F 142:l ++ÏÎ F 143:l ++ÏÏ F 144:l ++ÏÐ F 145:l ++ÏÑ F 146:l ++ÏÒ F 147:l ++ÏÓ F 148:l ++С F 0:m ++Т F 1:m ++У F 2:m ++Ѐ F 3:m ++Ð¥ F 4:m ++Њ F 5:m ++Ч F 6:m ++К F 7:m ++Щ F 8:m ++Ъ F 9:m ++Ы F 10:m ++Ь F 11:m ++Ð F 12:m ++Ю F 13:m ++Я F 14:m ++а F 15:m ++б F 16:m ++в F 17:m ++г F 18:m ++ÐŽ F 19:m ++е F 20:m ++ж F 21:m ++з F 22:m ++О F 23:m ++й F 24:m ++к F 25:m ++л F 26:m ++ÐŒ F 27:m ++Ðœ F 28:m ++П F 29:m ++п F 30:m ++ÐÀ F 31:m ++ÐÁ F 32:m ++РF 33:m ++Ðà F 34:m ++ÐÄ F 35:m ++ÐÅ F 36:m ++ÐÆ F 37:m ++ÐÇ F 38:m ++ÐÈ F 39:m ++ÐÉ F 40:m ++ÐÊ F 41:m ++ÐË F 42:m ++ÐÌ F 43:m ++ÐÍ F 44:m ++ÐÎ F 45:m ++ÐÏ F 46:m ++ÐÐ F 47:m ++ÐÑ F 48:m ++ÐÒ F 49:m ++ÐÓ F 50:m ++ÐÔ F 51:m ++ÐÕ F 52:m ++ÐÖ F 53:m ++Ð× F 54:m ++ÐØ F 55:m ++ÐÙ F 56:m ++ÐÚ F 57:m ++ÐÛ F 58:m ++ÐÜ F 59:m ++ÐÝ F 60:m ++ÐÞ F 61:m ++Ðß F 62:m ++Ðà F 63:m ++Ðá F 64:m ++Ðâ F 65:m ++Ðã F 66:m ++Ðä F 67:m ++Ðå F 68:m ++Ðæ F 69:m ++Ðç F 70:m ++Ðè F 71:m ++Ðé F 72:m ++Ðê F 73:m ++Ðë F 74:m ++Ðì F 75:m ++Ðí F 76:m ++Ðî F 77:m ++Ðï F 78:m ++Ðð F 79:m ++Ðñ F 80:m ++Ðò F 81:m ++Ðó F 82:m ++Ðô F 83:m ++Ðõ F 84:m ++Ðö F 85:m ++Ð÷ F 86:m ++Ðø F 87:m ++Ðù F 88:m ++Ðú F 89:m ++Ðû F 90:m ++Ðü F 91:m ++Ðý F 92:m ++Ðþ F 93:m ++Ñ¡ F 94:m ++Ñ¢ F 95:m ++Ñ£ F 96:m ++Ñ€ F 97:m ++Ñ¥ F 98:m ++ÑŠ F 99:m ++ѧ F 100:m ++Ñš F 101:m ++Ñ© F 102:m ++Ѫ F 103:m ++Ñ« F 104:m ++Ѭ F 105:m ++Ñ F 106:m ++Ñ® F 107:m ++ѯ F 108:m ++Ñ° F 109:m ++ѱ F 110:m ++Ѳ F 111:m ++ѳ F 112:m ++ÑŽ F 113:m ++ѵ F 114:m ++Ѷ F 115:m ++Ñ· F 116:m ++Ñž F 117:m ++ѹ F 118:m ++Ѻ F 119:m ++Ñ» F 120:m ++ÑŒ F 121:m ++Ñœ F 122:m ++ÑŸ F 123:m ++Ñ¿ F 124:m ++ÑÀ F 125:m ++ÑÁ F 126:m ++Ñ F 127:m ++Ñà F 128:m ++ÑÄ F 129:m ++ÑÅ F 130:m ++ÑÆ F 131:m ++ÑÇ F 132:m ++ÑÈ F 133:m ++ÑÉ F 134:m ++ÑÊ F 135:m ++ÑË F 136:m ++ÑÌ F 137:m ++ÑÍ F 138:m ++ÑÎ F 139:m ++ÑÏ F 140:m ++ÑÐ F 141:m ++ÑÑ F 142:m ++ÑÒ F 143:m ++ÑÓ F 144:m ++ÑÔ F 145:m ++ÑÕ F 146:m ++ÑÖ F 147:m ++Ñ× F 148:m ++ÑØ F 149:m ++ÑÙ F 150:m ++ÑÚ F 151:m ++ÑÛ F 152:m ++ÑÜ F 153:m ++ÑÝ F 154:m ++ÑÞ F 155:m ++Ñß F 156:m ++Ñà F 157:m ++Ñá F 158:m ++Ñâ F 159:m ++Ñã F 160:m ++Ñä F 161:m ++Ñå F 162:m ++Ñæ F 163:m ++Ñç F 164:m ++Ñè F 165:m ++Ñé F 166:m ++Ñê F 167:m ++Ñë F 168:m ++Ñì F 169:m ++Ñí F 170:m ++Ñî F 171:m ++Ñï F 172:m ++Ñð F 173:m ++Ññ F 174:m ++Ñò F 175:m ++Ñó F 176:m ++Ñô F 177:m ++Ñõ F 178:m ++Ñö F 179:m ++Ñ÷ F 180:m ++Ñø F 181:m ++Ñù F 182:m ++Ñú F 183:m ++Ñû F 184:m ++Ñü F 185:m ++Ñý F 186:m ++Ñþ F 187:m ++Ò¡ F 188:m ++Ò¢ F 189:m ++Ò£ F 190:m ++Ò€ F 191:m ++Ò¥ F 192:m ++ÒŠ F 193:m ++Ò§ F 194:m ++Òš F 195:m ++Ò© F 196:m ++Òª F 197:m ++Ò« F 198:m ++Ò¬ F 199:m ++Ò F 200:m ++Ò® F 201:m ++Ò¯ F 202:m ++Ò° F 203:m ++Ò± F 204:m ++Ò² F 205:m ++Ò³ F 206:m ++ÒŽ F 207:m ++Òµ F 208:m ++Ò¶ F 209:m ++Ò· F 210:m ++Òž F 211:m ++Ò¹ F 212:m ++Òº F 213:m ++Ò» F 214:m ++ÒŒ F 215:m ++Òœ F 216:m ++ÒŸ F 217:m ++Ò¿ F 218:m ++ÒÀ F 219:m ++ÒÁ F 220:m ++Ò F 221:m ++Òà F 222:m ++ÒÄ F 223:m ++ÒÅ F 224:m ++ÒÆ F 225:m ++ÒÇ F 226:m ++ÒÈ F 227:m ++ÒÉ F 228:m ++ÒÊ F 229:m ++ÒË F 230:m ++ÒÌ F 231:m ++ÒÍ F 232:m ++ÒÎ F 233:m ++ÒÏ F 234:m ++ÒÐ F 235:m ++ÒÑ F 236:m ++ÒÒ F 237:m ++ÒÓ F 238:m ++ÒÔ F 239:m ++ÒÕ F 240:m ++ÒÖ F 241:m ++Ò× F 242:m ++ÒØ F 243:m ++ÒÙ F 244:m ++ÒÚ F 245:m ++ÒÛ F 246:m ++ÒÜ F 247:m ++ÒÝ F 248:m ++ÒÞ F 249:m ++Òß F 250:m ++Òà F 251:m ++Òá F 252:m ++Òâ F 253:m ++Òã F 254:m ++Òä F 255:m ++Òå F 0:n ++Òæ F 1:n ++Òç F 2:n ++Òè F 3:n ++Òé F 4:n ++Òê F 5:n ++Òë F 6:n ++Òì F 7:n ++Òí F 8:n ++Òî F 9:n ++Òï F 10:n ++Òð F 11:n ++Òñ F 12:n ++Òò F 13:n ++Òó F 14:n ++Òô F 15:n ++Òõ F 16:n ++Òö F 17:n ++Ò÷ F 18:n ++Òø F 19:n ++Òù F 20:n ++Òú F 21:n ++Òû F 22:n ++Òü F 23:n ++Òý F 24:n ++Òþ F 25:n ++Ó¡ F 26:n ++Ó¢ F 27:n ++Ó£ F 28:n ++Ó€ F 29:n ++Ó¥ F 30:n ++ÓŠ F 31:n ++Ó§ F 32:n ++Óš F 33:n ++Ó© F 34:n ++Óª F 35:n ++Ó« F 36:n ++Ó¬ F 37:n ++Ó F 38:n ++Ó® F 39:n ++Ó¯ F 40:n ++Ó° F 41:n ++Ó± F 42:n ++Ó² F 43:n ++Ó³ F 44:n ++ÓŽ F 45:n ++Óµ F 46:n ++Ó¶ F 47:n ++Ó· F 48:n ++Óž F 49:n ++Ó¹ F 50:n ++Óº F 51:n ++Ó» F 52:n ++ÓŒ F 53:n ++Óœ F 54:n ++ÓŸ F 55:n ++Ó¿ F 56:n ++ÓÀ F 57:n ++ÓÁ F 58:n ++Ó F 59:n ++Óà F 60:n ++ÓÄ F 61:n ++ÓÅ F 62:n ++ÓÆ F 63:n ++ÓÇ F 64:n ++ÓÈ F 65:n ++ÓÉ F 66:n ++ÓÊ F 67:n ++ÓË F 68:n ++ÓÌ F 69:n ++ÓÍ F 70:n ++ÓÎ F 71:n ++ÓÏ F 72:n ++ÓÐ F 73:n ++ÓÑ F 74:n ++ÓÒ F 75:n ++ÓÓ F 76:n ++ÓÔ F 77:n ++ÓÕ F 78:n ++ÓÖ F 79:n ++Ó× F 80:n ++ÓØ F 81:n ++ÓÙ F 82:n ++ÓÚ F 83:n ++ÓÛ F 84:n ++ÓÜ F 85:n ++ÓÝ F 86:n ++ÓÞ F 87:n ++Óß F 88:n ++Óà F 89:n ++Óá F 90:n ++Óâ F 91:n ++Óã F 92:n ++Óä F 93:n ++Óå F 94:n ++Óæ F 95:n ++Óç F 96:n ++Óè F 97:n ++Óé F 98:n ++Óê F 99:n ++Óë F 100:n ++Óì F 101:n ++Óí F 102:n ++Óî F 103:n ++Óï F 104:n ++Óð F 105:n ++Óñ F 106:n ++Óò F 107:n ++Óó F 108:n ++Óô F 109:n ++Óõ F 110:n ++Óö F 111:n ++Ó÷ F 112:n ++Óø F 113:n ++Óù F 114:n ++Óú F 115:n ++Óû F 116:n ++Óü F 117:n ++Óý F 118:n ++Óþ F 119:n ++Ô¡ F 120:n ++Ô¢ F 121:n ++Ô£ F 122:n ++Ô€ F 123:n ++Ô¥ F 124:n ++ÔŠ F 125:n ++Ô§ F 126:n ++Ôš F 127:n ++Ô© F 128:n ++Ôª F 129:n ++Ô« F 130:n ++Ô¬ F 131:n ++Ô F 132:n ++Ô® F 133:n ++Ô¯ F 134:n ++Ô° F 135:n ++Ô± F 136:n ++Ô² F 137:n ++Ô³ F 138:n ++ÔŽ F 139:n ++Ôµ F 140:n ++Ô¶ F 141:n ++Ô· F 142:n ++Ôž F 143:n ++Ô¹ F 144:n ++Ôº F 145:n ++Ô» F 146:n ++ÔŒ F 147:n ++Ôœ F 148:n ++ÔŸ F 149:n ++Ô¿ F 150:n ++ÔÀ F 151:n ++ÔÁ F 152:n ++Ô F 153:n ++Ôà F 154:n ++ÔÄ F 155:n ++ÔÅ F 156:n ++ÔÆ F 157:n ++ÔÇ F 158:n ++ÔÈ F 159:n ++ÔÉ F 160:n ++ÔÊ F 161:n ++ÔË F 162:n ++ÔÌ F 163:n ++ÔÍ F 164:n ++ÔÎ F 165:n ++ÔÏ F 166:n ++ÔÐ F 167:n ++ÔÑ F 168:n ++ÔÒ F 169:n ++ÔÓ F 170:n ++ÔÔ F 171:n ++ÔÕ F 172:n ++ÔÖ F 173:n ++Ô× F 174:n ++ÔØ F 175:n ++ÔÙ F 176:n ++ÔÚ F 177:n ++ÔÛ F 178:n ++ÔÜ F 179:n ++ÔÝ F 180:n ++ÔÞ F 181:n ++Ôß F 182:n ++Ôà F 183:n ++Ôá F 184:n ++Ôâ F 185:n ++Ôã F 186:n ++Ôä F 187:n ++Ôå F 188:n ++Ôæ F 189:n ++Ôç F 190:n ++Ôè F 191:n ++Ôé F 192:n ++Ôê F 193:n ++Ôë F 194:n ++Ôì F 195:n ++Ôí F 196:n ++Ôî F 197:n ++Ôï F 198:n ++Ôð F 199:n ++Ôñ F 200:n ++Ôò F 201:n ++Ôó F 202:n ++Ôô F 203:n ++Ôõ F 204:n ++Ôö F 205:n ++Ô÷ F 206:n ++Ôø F 207:n ++Ôù F 208:n ++Ôú F 209:n ++Ôû F 210:n ++Ôü F 211:n ++Ôý F 212:n ++Ôþ F 213:n ++Õ¡ F 214:n ++Õ¢ F 215:n ++Õ£ F 216:n ++Õ€ F 217:n ++Õ¥ F 218:n ++ÕŠ F 219:n ++Õ§ F 220:n ++Õš F 221:n ++Õ© F 222:n ++Õª F 223:n ++Õ« F 224:n ++Õ¬ F 225:n ++Õ F 226:n ++Õ® F 227:n ++Õ¯ F 228:n ++Õ° F 229:n ++Õ± F 230:n ++Õ² F 231:n ++Õ³ F 232:n ++ÕŽ F 233:n ++Õµ F 234:n ++Õ¶ F 235:n ++Õ· F 236:n ++Õž F 237:n ++Õ¹ F 238:n ++Õº F 239:n ++Õ» F 240:n ++ÕŒ F 241:n ++Õœ F 242:n ++ÕŸ F 243:n ++Õ¿ F 244:n ++ÕÀ F 245:n ++ÕÁ F 246:n ++Õ F 247:n ++Õà F 248:n ++ÕÄ F 249:n ++ÕÅ F 250:n ++ÕÆ F 251:n ++ÕÇ F 252:n ++ÕÈ F 253:n ++ÕÉ F 254:n ++ÕÊ F 255:n ++ÕË F 0:o ++ÕÌ F 1:o ++ÕÍ F 2:o ++ÕÎ F 3:o ++ÕÏ F 4:o ++ÕÐ F 5:o ++ÕÑ F 6:o ++ÕÒ F 7:o ++ÕÓ F 8:o ++ÕÔ F 9:o ++ÕÕ F 10:o ++ÕÖ F 11:o ++Õ× F 12:o ++ÕØ F 13:o ++ÕÙ F 14:o ++ÕÚ F 15:o ++ÕÛ F 16:o ++ÕÜ F 17:o ++ÕÝ F 18:o ++ÕÞ F 19:o ++Õß F 20:o ++Õà F 21:o ++Õá F 22:o ++Õâ F 23:o ++Õã F 24:o ++Õä F 25:o ++Õå F 26:o ++Õæ F 27:o ++Õç F 28:o ++Õè F 29:o ++Õé F 30:o ++Õê F 31:o ++Õë F 32:o ++Õì F 33:o ++Õí F 34:o ++Õî F 35:o ++Õï F 36:o ++Õð F 37:o ++Õñ F 38:o ++Õò F 39:o ++Õó F 40:o ++Õô F 41:o ++Õõ F 42:o ++Õö F 43:o ++Õ÷ F 44:o ++Õø F 45:o ++Õù F 46:o ++Õú F 47:o ++Õû F 48:o ++Õü F 49:o ++Õý F 50:o ++Õþ F 51:o ++Ö¡ F 52:o ++Ö¢ F 53:o ++Ö£ F 54:o ++Ö€ F 55:o ++Ö¥ F 56:o ++ÖŠ F 57:o ++Ö§ F 58:o ++Öš F 59:o ++Ö© F 60:o ++Öª F 61:o ++Ö« F 62:o ++Ö¬ F 63:o ++Ö F 64:o ++Ö® F 65:o ++Ö¯ F 66:o ++Ö° F 67:o ++Ö± F 68:o ++Ö² F 69:o ++Ö³ F 70:o ++ÖŽ F 71:o ++Öµ F 72:o ++Ö¶ F 73:o ++Ö· F 74:o ++Öž F 75:o ++Ö¹ F 76:o ++Öº F 77:o ++Ö» F 78:o ++ÖŒ F 79:o ++Öœ F 80:o ++ÖŸ F 81:o ++Ö¿ F 82:o ++ÖÀ F 83:o ++ÖÁ F 84:o ++Ö F 85:o ++Öà F 86:o ++ÖÄ F 87:o ++ÖÅ F 88:o ++ÖÆ F 89:o ++ÖÇ F 90:o ++ÖÈ F 91:o ++ÖÉ F 92:o ++ÖÊ F 93:o ++ÖË F 94:o ++ÖÌ F 95:o ++ÖÍ F 96:o ++ÖÎ F 97:o ++ÖÏ F 98:o ++ÖÐ F 99:o ++ÖÑ F 100:o ++ÖÒ F 101:o ++ÖÓ F 102:o ++ÖÔ F 103:o ++ÖÕ F 104:o ++ÖÖ F 105:o ++Ö× F 106:o ++ÖØ F 107:o ++ÖÙ F 108:o ++ÖÚ F 109:o ++ÖÛ F 110:o ++ÖÜ F 111:o ++ÖÝ F 112:o ++ÖÞ F 113:o ++Öß F 114:o ++Öà F 115:o ++Öá F 116:o ++Öâ F 117:o ++Öã F 118:o ++Öä F 119:o ++Öå F 120:o ++Öæ F 121:o ++Öç F 122:o ++Öè F 123:o ++Öé F 124:o ++Öê F 125:o ++Öë F 126:o ++Öì F 127:o ++Öí F 128:o ++Öî F 129:o ++Öï F 130:o ++Öð F 131:o ++Öñ F 132:o ++Öò F 133:o ++Öó F 134:o ++Öô F 135:o ++Öõ F 136:o ++Öö F 137:o ++Ö÷ F 138:o ++Öø F 139:o ++Öù F 140:o ++Öú F 141:o ++Öû F 142:o ++Öü F 143:o ++Öý F 144:o ++Öþ F 145:o ++ס F 146:o ++×¢ F 147:o ++×£ F 148:o ++×€ F 149:o ++×¥ F 150:o ++׊ F 151:o ++ק F 152:o ++ך F 153:o ++ש F 154:o ++ת F 155:o ++׫ F 156:o ++׬ F 157:o ++× F 158:o ++×® F 159:o ++ׯ F 160:o ++×° F 161:o ++×± F 162:o ++ײ F 163:o ++׳ F 164:o ++׎ F 165:o ++×µ F 166:o ++׶ F 167:o ++×· F 168:o ++מ F 169:o ++×¹ F 170:o ++׺ F 171:o ++×» F 172:o ++׌ F 173:o ++ל F 174:o ++ן F 175:o ++׿ F 176:o ++×À F 177:o ++×Á F 178:o ++× F 179:o ++×à F 180:o ++×Ä F 181:o ++×Å F 182:o ++×Æ F 183:o ++×Ç F 184:o ++×È F 185:o ++×É F 186:o ++×Ê F 187:o ++×Ë F 188:o ++×Ì F 189:o ++×Í F 190:o ++×Î F 191:o ++×Ï F 192:o ++×Ð F 193:o ++×Ñ F 194:o ++×Ò F 195:o ++×Ó F 196:o ++×Ô F 197:o ++×Õ F 198:o ++×Ö F 199:o ++×× F 200:o ++×Ø F 201:o ++×Ù F 202:o ++×Ú F 203:o ++×Û F 204:o ++×Ü F 205:o ++×Ý F 206:o ++×Þ F 207:o ++×ß F 208:o ++×à F 209:o ++×á F 210:o ++×â F 211:o ++×ã F 212:o ++×ä F 213:o ++×å F 214:o ++×æ F 215:o ++×ç F 216:o ++×è F 217:o ++×é F 218:o ++×ê F 219:o ++×ë F 220:o ++×ì F 221:o ++×í F 222:o ++×î F 223:o ++×ï F 224:o ++×ð F 225:o ++×ñ F 226:o ++×ò F 227:o ++×ó F 228:o ++×ô F 229:o ++×õ F 230:o ++×ö F 231:o ++×÷ F 232:o ++×ø F 233:o ++×ù F 234:o ++×ú F 235:o ++×û F 236:o ++×ü F 237:o ++×ý F 238:o ++×þ F 239:o ++Ø¡ F 240:o ++Ø¢ F 241:o ++Ø£ F 242:o ++Ø€ F 243:o ++Ø¥ F 244:o ++ØŠ F 245:o ++ا F 246:o ++Øš F 247:o ++Ø© F 248:o ++ت F 249:o ++Ø« F 250:o ++ج F 251:o ++Ø F 252:o ++Ø® F 253:o ++د F 254:o ++Ø° F 255:o ++ر F 0:p ++ز F 1:p ++س F 2:p ++ØŽ F 3:p ++ص F 4:p ++ض F 5:p ++Ø· F 6:p ++Øž F 7:p ++ع F 8:p ++غ F 9:p ++Ø» F 10:p ++ØŒ F 11:p ++Øœ F 12:p ++ØŸ F 13:p ++Ø¿ F 14:p ++ØÀ F 15:p ++ØÁ F 16:p ++Ø F 17:p ++Øà F 18:p ++ØÄ F 19:p ++ØÅ F 20:p ++ØÆ F 21:p ++ØÇ F 22:p ++ØÈ F 23:p ++ØÉ F 24:p ++ØÊ F 25:p ++ØË F 26:p ++ØÌ F 27:p ++ØÍ F 28:p ++ØÎ F 29:p ++ØÏ F 30:p ++ØÐ F 31:p ++ØÑ F 32:p ++ØÒ F 33:p ++ØÓ F 34:p ++ØÔ F 35:p ++ØÕ F 36:p ++ØÖ F 37:p ++Ø× F 38:p ++ØØ F 39:p ++ØÙ F 40:p ++ØÚ F 41:p ++ØÛ F 42:p ++ØÜ F 43:p ++ØÝ F 44:p ++ØÞ F 45:p ++Øß F 46:p ++Øà F 47:p ++Øá F 48:p ++Øâ F 49:p ++Øã F 50:p ++Øä F 51:p ++Øå F 52:p ++Øæ F 53:p ++Øç F 54:p ++Øè F 55:p ++Øé F 56:p ++Øê F 57:p ++Øë F 58:p ++Øì F 59:p ++Øí F 60:p ++Øî F 61:p ++Øï F 62:p ++Øð F 63:p ++Øñ F 64:p ++Øò F 65:p ++Øó F 66:p ++Øô F 67:p ++Øõ F 68:p ++Øö F 69:p ++Ø÷ F 70:p ++Øø F 71:p ++Øù F 72:p ++Øú F 73:p ++Øû F 74:p ++Øü F 75:p ++Øý F 76:p ++Øþ F 77:p ++Ù¡ F 78:p ++Ù¢ F 79:p ++Ù£ F 80:p ++Ù€ F 81:p ++Ù¥ F 82:p ++ÙŠ F 83:p ++Ù§ F 84:p ++Ùš F 85:p ++Ù© F 86:p ++Ùª F 87:p ++Ù« F 88:p ++Ù¬ F 89:p ++Ù F 90:p ++Ù® F 91:p ++Ù¯ F 92:p ++Ù° F 93:p ++Ù± F 94:p ++Ù² F 95:p ++Ù³ F 96:p ++ÙŽ F 97:p ++Ùµ F 98:p ++Ù¶ F 99:p ++Ù· F 100:p ++Ùž F 101:p ++Ù¹ F 102:p ++Ùº F 103:p ++Ù» F 104:p ++ÙŒ F 105:p ++Ùœ F 106:p ++ÙŸ F 107:p ++Ù¿ F 108:p ++ÙÀ F 109:p ++ÙÁ F 110:p ++Ù F 111:p ++Ùà F 112:p ++ÙÄ F 113:p ++ÙÅ F 114:p ++ÙÆ F 115:p ++ÙÇ F 116:p ++ÙÈ F 117:p ++ÙÉ F 118:p ++ÙÊ F 119:p ++ÙË F 120:p ++ÙÌ F 121:p ++ÙÍ F 122:p ++ÙÎ F 123:p ++ÙÏ F 124:p ++ÙÐ F 125:p ++ÙÑ F 126:p ++ÙÒ F 127:p ++ÙÓ F 128:p ++ÙÔ F 129:p ++ÙÕ F 130:p ++ÙÖ F 131:p ++Ù× F 132:p ++ÙØ F 133:p ++ÙÙ F 134:p ++ÙÚ F 135:p ++ÙÛ F 136:p ++ÙÜ F 137:p ++ÙÝ F 138:p ++ÙÞ F 139:p ++Ùß F 140:p ++Ùà F 141:p ++Ùá F 142:p ++Ùâ F 143:p ++Ùã F 144:p ++Ùä F 145:p ++Ùå F 146:p ++Ùæ F 147:p ++Ùç F 148:p ++Ùè F 149:p ++Ùé F 150:p ++Ùê F 151:p ++Ùë F 152:p ++Ùì F 153:p ++Ùí F 154:p ++Ùî F 155:p ++Ùï F 156:p ++Ùð F 157:p ++Ùñ F 158:p ++Ùò F 159:p ++Ùó F 160:p ++Ùô F 161:p ++Ùõ F 162:p ++Ùö F 163:p ++Ù÷ F 164:p ++Ùø F 165:p ++Ùù F 166:p ++Ùú F 167:p ++Ùû F 168:p ++Ùü F 169:p ++Ùý F 170:p ++Ùþ F 171:p ++Ú¡ F 172:p ++Ú¢ F 173:p ++Ú£ F 174:p ++Ú€ F 175:p ++Ú¥ F 176:p ++ÚŠ F 177:p ++Ú§ F 178:p ++Úš F 179:p ++Ú© F 180:p ++Úª F 181:p ++Ú« F 182:p ++Ú¬ F 183:p ++Ú F 184:p ++Ú® F 185:p ++Ú¯ F 186:p ++Ú° F 187:p ++Ú± F 188:p ++Ú² F 189:p ++Ú³ F 190:p ++ÚŽ F 191:p ++Úµ F 192:p ++Ú¶ F 193:p ++Ú· F 194:p ++Úž F 195:p ++Ú¹ F 196:p ++Úº F 197:p ++Ú» F 198:p ++ÚŒ F 199:p ++Úœ F 200:p ++ÚŸ F 201:p ++Ú¿ F 202:p ++ÚÀ F 203:p ++ÚÁ F 204:p ++Ú F 205:p ++Úà F 206:p ++ÚÄ F 207:p ++ÚÅ F 208:p ++ÚÆ F 209:p ++ÚÇ F 210:p ++ÚÈ F 211:p ++ÚÉ F 212:p ++ÚÊ F 213:p ++ÚË F 214:p ++ÚÌ F 215:p ++ÚÍ F 216:p ++ÚÎ F 217:p ++ÚÏ F 218:p ++ÚÐ F 219:p ++ÚÑ F 220:p ++ÚÒ F 221:p ++ÚÓ F 222:p ++ÚÔ F 223:p ++ÚÕ F 224:p ++ÚÖ F 225:p ++Ú× F 226:p ++ÚØ F 227:p ++ÚÙ F 228:p ++ÚÚ F 229:p ++ÚÛ F 230:p ++ÚÜ F 231:p ++ÚÝ F 232:p ++ÚÞ F 233:p ++Úß F 234:p ++Úà F 235:p ++Úá F 236:p ++Úâ F 237:p ++Úã F 238:p ++Úä F 239:p ++Úå F 240:p ++Úæ F 241:p ++Úç F 242:p ++Úè F 243:p ++Úé F 244:p ++Úê F 245:p ++Úë F 246:p ++Úì F 247:p ++Úí F 248:p ++Úî F 249:p ++Úï F 250:p ++Úð F 251:p ++Úñ F 252:p ++Úò F 253:p ++Úó F 254:p ++Úô F 255:p ++Úõ F 0:q ++Úö F 1:q ++Ú÷ F 2:q ++Úø F 3:q ++Úù F 4:q ++Úú F 5:q ++Úû F 6:q ++Úü F 7:q ++Úý F 8:q ++Úþ F 9:q ++Û¡ F 10:q ++Û¢ F 11:q ++Û£ F 12:q ++Û€ F 13:q ++Û¥ F 14:q ++ÛŠ F 15:q ++Û§ F 16:q ++Ûš F 17:q ++Û© F 18:q ++Ûª F 19:q ++Û« F 20:q ++Û¬ F 21:q ++Û F 22:q ++Û® F 23:q ++Û¯ F 24:q ++Û° F 25:q ++Û± F 26:q ++Û² F 27:q ++Û³ F 28:q ++ÛŽ F 29:q ++Ûµ F 30:q ++Û¶ F 31:q ++Û· F 32:q ++Ûž F 33:q ++Û¹ F 34:q ++Ûº F 35:q ++Û» F 36:q ++ÛŒ F 37:q ++Ûœ F 38:q ++ÛŸ F 39:q ++Û¿ F 40:q ++ÛÀ F 41:q ++ÛÁ F 42:q ++Û F 43:q ++Ûà F 44:q ++ÛÄ F 45:q ++ÛÅ F 46:q ++ÛÆ F 47:q ++ÛÇ F 48:q ++ÛÈ F 49:q ++ÛÉ F 50:q ++ÛÊ F 51:q ++ÛË F 52:q ++ÛÌ F 53:q ++ÛÍ F 54:q ++ÛÎ F 55:q ++ÛÏ F 56:q ++ÛÐ F 57:q ++ÛÑ F 58:q ++ÛÒ F 59:q ++ÛÓ F 60:q ++ÛÔ F 61:q ++ÛÕ F 62:q ++ÛÖ F 63:q ++Û× F 64:q ++ÛØ F 65:q ++ÛÙ F 66:q ++ÛÚ F 67:q ++ÛÛ F 68:q ++ÛÜ F 69:q ++ÛÝ F 70:q ++ÛÞ F 71:q ++Ûß F 72:q ++Ûà F 73:q ++Ûá F 74:q ++Ûâ F 75:q ++Ûã F 76:q ++Ûä F 77:q ++Ûå F 78:q ++Ûæ F 79:q ++Ûç F 80:q ++Ûè F 81:q ++Ûé F 82:q ++Ûê F 83:q ++Ûë F 84:q ++Ûì F 85:q ++Ûí F 86:q ++Ûî F 87:q ++Ûï F 88:q ++Ûð F 89:q ++Ûñ F 90:q ++Ûò F 91:q ++Ûó F 92:q ++Ûô F 93:q ++Ûõ F 94:q ++Ûö F 95:q ++Û÷ F 96:q ++Ûø F 97:q ++Ûù F 98:q ++Ûú F 99:q ++Ûû F 100:q ++Ûü F 101:q ++Ûý F 102:q ++Ûþ F 103:q ++Ü¡ F 104:q ++Ü¢ F 105:q ++Ü£ F 106:q ++Ü€ F 107:q ++Ü¥ F 108:q ++ÜŠ F 109:q ++ܧ F 110:q ++Üš F 111:q ++Ü© F 112:q ++ܪ F 113:q ++Ü« F 114:q ++ܬ F 115:q ++Ü F 116:q ++Ü® F 117:q ++ܯ F 118:q ++Ü° F 119:q ++ܱ F 120:q ++ܲ F 121:q ++ܳ F 122:q ++ÜŽ F 123:q ++ܵ F 124:q ++ܶ F 125:q ++Ü· F 126:q ++Üž F 127:q ++ܹ F 128:q ++ܺ F 129:q ++Ü» F 130:q ++ÜŒ F 131:q ++Üœ F 132:q ++ÜŸ F 133:q ++Ü¿ F 134:q ++ÜÀ F 135:q ++ÜÁ F 136:q ++Ü F 137:q ++Üà F 138:q ++ÜÄ F 139:q ++ÜÅ F 140:q ++ÜÆ F 141:q ++ÜÇ F 142:q ++ÜÈ F 143:q ++ÜÉ F 144:q ++ÜÊ F 145:q ++ÜË F 146:q ++ÜÌ F 147:q ++ÜÍ F 148:q ++ÜÎ F 149:q ++ÜÏ F 150:q ++ÜÐ F 151:q ++ÜÑ F 152:q ++ÜÒ F 153:q ++ÜÓ F 154:q ++ÜÔ F 155:q ++ÜÕ F 156:q ++ÜÖ F 157:q ++Ü× F 158:q ++ÜØ F 159:q ++ÜÙ F 160:q ++ÜÚ F 161:q ++ÜÛ F 162:q ++ÜÜ F 163:q ++ÜÝ F 164:q ++ÜÞ F 165:q ++Üß F 166:q ++Üà F 167:q ++Üá F 168:q ++Üâ F 169:q ++Üã F 170:q ++Üä F 171:q ++Üå F 172:q ++Üæ F 173:q ++Üç F 174:q ++Üè F 175:q ++Üé F 176:q ++Üê F 177:q ++Üë F 178:q ++Üì F 179:q ++Üí F 180:q ++Üî F 181:q ++Üï F 182:q ++Üð F 183:q ++Üñ F 184:q ++Üò F 185:q ++Üó F 186:q ++Üô F 187:q ++Üõ F 188:q ++Üö F 189:q ++Ü÷ F 190:q ++Üø F 191:q ++Üù F 192:q ++Üú F 193:q ++Üû F 194:q ++Üü F 195:q ++Üý F 196:q ++Üþ F 197:q ++Ý¡ F 198:q ++Ý¢ F 199:q ++Ý£ F 200:q ++Ý€ F 201:q ++Ý¥ F 202:q ++ÝŠ F 203:q ++ݧ F 204:q ++Ýš F 205:q ++Ý© F 206:q ++ݪ F 207:q ++Ý« F 208:q ++ݬ F 209:q ++Ý F 210:q ++Ý® F 211:q ++ݯ F 212:q ++Ý° F 213:q ++ݱ F 214:q ++ݲ F 215:q ++ݳ F 216:q ++ÝŽ F 217:q ++ݵ F 218:q ++ݶ F 219:q ++Ý· F 220:q ++Ýž F 221:q ++ݹ F 222:q ++ݺ F 223:q ++Ý» F 224:q ++ÝŒ F 225:q ++Ýœ F 226:q ++ÝŸ F 227:q ++Ý¿ F 228:q ++ÝÀ F 229:q ++ÝÁ F 230:q ++Ý F 231:q ++Ýà F 232:q ++ÝÄ F 233:q ++ÝÅ F 234:q ++ÝÆ F 235:q ++ÝÇ F 236:q ++ÝÈ F 237:q ++ÝÉ F 238:q ++ÝÊ F 239:q ++ÝË F 240:q ++ÝÌ F 241:q ++ÝÍ F 242:q ++ÝÎ F 243:q ++ÝÏ F 244:q ++ÝÐ F 245:q ++ÝÑ F 246:q ++ÝÒ F 247:q ++ÝÓ F 248:q ++ÝÔ F 249:q ++ÝÕ F 250:q ++ÝÖ F 251:q ++Ý× F 252:q ++ÝØ F 253:q ++ÝÙ F 254:q ++ÝÚ F 255:q ++ÝÛ F 0:r ++ÝÜ F 1:r ++ÝÝ F 2:r ++ÝÞ F 3:r ++Ýß F 4:r ++Ýà F 5:r ++Ýá F 6:r ++Ýâ F 7:r ++Ýã F 8:r ++Ýä F 9:r ++Ýå F 10:r ++Ýæ F 11:r ++Ýç F 12:r ++Ýè F 13:r ++Ýé F 14:r ++Ýê F 15:r ++Ýë F 16:r ++Ýì F 17:r ++Ýí F 18:r ++Ýî F 19:r ++Ýï F 20:r ++Ýð F 21:r ++Ýñ F 22:r ++Ýò F 23:r ++Ýó F 24:r ++Ýô F 25:r ++Ýõ F 26:r ++Ýö F 27:r ++Ý÷ F 28:r ++Ýø F 29:r ++Ýù F 30:r ++Ýú F 31:r ++Ýû F 32:r ++Ýü F 33:r ++Ýý F 34:r ++Ýþ F 35:r ++Þ¡ F 36:r ++Þ¢ F 37:r ++Þ£ F 38:r ++Þ€ F 39:r ++Þ¥ F 40:r ++ÞŠ F 41:r ++Þ§ F 42:r ++Þš F 43:r ++Þ© F 44:r ++Þª F 45:r ++Þ« F 46:r ++Þ¬ F 47:r ++Þ F 48:r ++Þ® F 49:r ++Þ¯ F 50:r ++Þ° F 51:r ++Þ± F 52:r ++Þ² F 53:r ++Þ³ F 54:r ++ÞŽ F 55:r ++Þµ F 56:r ++Þ¶ F 57:r ++Þ· F 58:r ++Þž F 59:r ++Þ¹ F 60:r ++Þº F 61:r ++Þ» F 62:r ++ÞŒ F 63:r ++Þœ F 64:r ++ÞŸ F 65:r ++Þ¿ F 66:r ++ÞÀ F 67:r ++ÞÁ F 68:r ++Þ F 69:r ++Þà F 70:r ++ÞÄ F 71:r ++ÞÅ F 72:r ++ÞÆ F 73:r ++ÞÇ F 74:r ++ÞÈ F 75:r ++ÞÉ F 76:r ++ÞÊ F 77:r ++ÞË F 78:r ++ÞÌ F 79:r ++ÞÍ F 80:r ++ÞÎ F 81:r ++ÞÏ F 82:r ++ÞÐ F 83:r ++ÞÑ F 84:r ++ÞÒ F 85:r ++ÞÓ F 86:r ++ÞÔ F 87:r ++ÞÕ F 88:r ++ÞÖ F 89:r ++Þ× F 90:r ++ÞØ F 91:r ++ÞÙ F 92:r ++ÞÚ F 93:r ++ÞÛ F 94:r ++ÞÜ F 95:r ++ÞÝ F 96:r ++ÞÞ F 97:r ++Þß F 98:r ++Þà F 99:r ++Þá F 100:r ++Þâ F 101:r ++Þã F 102:r ++Þä F 103:r ++Þå F 104:r ++Þæ F 105:r ++Þç F 106:r ++Þè F 107:r ++Þé F 108:r ++Þê F 109:r ++Þë F 110:r ++Þì F 111:r ++Þí F 112:r ++Þî F 113:r ++Þï F 114:r ++Þð F 115:r ++Þñ F 116:r ++Þò F 117:r ++Þó F 118:r ++Þô F 119:r ++Þõ F 120:r ++Þö F 121:r ++Þ÷ F 122:r ++Þø F 123:r ++Þù F 124:r ++Þú F 125:r ++Þû F 126:r ++Þü F 127:r ++Þý F 128:r ++Þþ F 129:r ++ß¡ F 130:r ++ߢ F 131:r ++ߣ F 132:r ++߀ F 133:r ++ߥ F 134:r ++ߊ F 135:r ++ߧ F 136:r ++ßš F 137:r ++ß© F 138:r ++ߪ F 139:r ++ß« F 140:r ++߬ F 141:r ++ß F 142:r ++ß® F 143:r ++߯ F 144:r ++ß° F 145:r ++ß± F 146:r ++ß² F 147:r ++ß³ F 148:r ++ߎ F 149:r ++ßµ F 150:r ++߶ F 151:r ++ß· F 152:r ++ßž F 153:r ++ß¹ F 154:r ++ߺ F 155:r ++ß» F 156:r ++ߌ F 157:r ++ßœ F 158:r ++ߟ F 159:r ++ß¿ F 160:r ++ßÀ F 161:r ++ßÁ F 162:r ++ß F 163:r ++ßà F 164:r ++ßÄ F 165:r ++ßÅ F 166:r ++ßÆ F 167:r ++ßÇ F 168:r ++ßÈ F 169:r ++ßÉ F 170:r ++ßÊ F 171:r ++ßË F 172:r ++ßÌ F 173:r ++ßÍ F 174:r ++ßÎ F 175:r ++ßÏ F 176:r ++ßÐ F 177:r ++ßÑ F 178:r ++ßÒ F 179:r ++ßÓ F 180:r ++ßÔ F 181:r ++ßÕ F 182:r ++ßÖ F 183:r ++ß× F 184:r ++ßØ F 185:r ++ßÙ F 186:r ++ßÚ F 187:r ++ßÛ F 188:r ++ßÜ F 189:r ++ßÝ F 190:r ++ßÞ F 191:r ++ßß F 192:r ++ßà F 193:r ++ßá F 194:r ++ßâ F 195:r ++ßã F 196:r ++ßä F 197:r ++ßå F 198:r ++ßæ F 199:r ++ßç F 200:r ++ßè F 201:r ++ßé F 202:r ++ßê F 203:r ++ßë F 204:r ++ßì F 205:r ++ßí F 206:r ++ßî F 207:r ++ßï F 208:r ++ßð F 209:r ++ßñ F 210:r ++ßò F 211:r ++ßó F 212:r ++ßô F 213:r ++ßõ F 214:r ++ßö F 215:r ++ß÷ F 216:r ++ßø F 217:r ++ßù F 218:r ++ßú F 219:r ++ßû F 220:r ++ßü F 221:r ++ßý F 222:r ++ßþ F 223:r ++à¡ F 224:r ++ࢠF 225:r ++࣠F 226:r ++à€ F 227:r ++ॠF 228:r ++àŠ F 229:r ++ৠF 230:r ++àš F 231:r ++à© F 232:r ++ઠF 233:r ++à« F 234:r ++ଠF 235:r ++à F 236:r ++à® F 237:r ++௠F 238:r ++à° F 239:r ++à± F 240:r ++ಠF 241:r ++à³ F 242:r ++àŽ F 243:r ++ൠF 244:r ++චF 245:r ++à· F 246:r ++àž F 247:r ++๠F 248:r ++ຠF 249:r ++à» F 250:r ++àŒ F 251:r ++àœ F 252:r ++àŸ F 253:r ++à¿ F 254:r ++àÀ F 255:r ++àÁ F 0:s ++à F 1:s ++àà F 2:s ++àÄ F 3:s ++àÅ F 4:s ++àÆ F 5:s ++àÇ F 6:s ++àÈ F 7:s ++àÉ F 8:s ++àÊ F 9:s ++àË F 10:s ++àÌ F 11:s ++àÍ F 12:s ++àÎ F 13:s ++àÏ F 14:s ++àÐ F 15:s ++àÑ F 16:s ++àÒ F 17:s ++àÓ F 18:s ++àÔ F 19:s ++àÕ F 20:s ++àÖ F 21:s ++à× F 22:s ++àØ F 23:s ++àÙ F 24:s ++àÚ F 25:s ++àÛ F 26:s ++àÜ F 27:s ++àÝ F 28:s ++àÞ F 29:s ++àß F 30:s ++àà F 31:s ++àá F 32:s ++àâ F 33:s ++àã F 34:s ++àä F 35:s ++àå F 36:s ++àæ F 37:s ++àç F 38:s ++àè F 39:s ++àé F 40:s ++àê F 41:s ++àë F 42:s ++àì F 43:s ++àí F 44:s ++àî F 45:s ++àï F 46:s ++àð F 47:s ++àñ F 48:s ++àò F 49:s ++àó F 50:s ++àô F 51:s ++àõ F 52:s ++àö F 53:s ++à÷ F 54:s ++àø F 55:s ++àù F 56:s ++àú F 57:s ++àû F 58:s ++àü F 59:s ++àý F 60:s ++àþ F 61:s ++á¡ F 62:s ++ᢠF 63:s ++ᣠF 64:s ++ဠF 65:s ++ᥠF 66:s ++አF 67:s ++᧠F 68:s ++áš F 69:s ++á© F 70:s ++᪠F 71:s ++á« F 72:s ++ᬠF 73:s ++á F 74:s ++á® F 75:s ++ᯠF 76:s ++á° F 77:s ++á± F 78:s ++á² F 79:s ++á³ F 80:s ++ᎠF 81:s ++áµ F 82:s ++ᶠF 83:s ++á· F 84:s ++áž F 85:s ++á¹ F 86:s ++ẠF 87:s ++á» F 88:s ++ጠF 89:s ++ᜠF 90:s ++០F 91:s ++á¿ F 92:s ++áÀ F 93:s ++áÁ F 94:s ++á F 95:s ++áà F 96:s ++áÄ F 97:s ++áÅ F 98:s ++áÆ F 99:s ++áÇ F 100:s ++áÈ F 101:s ++áÉ F 102:s ++áÊ F 103:s ++áË F 104:s ++áÌ F 105:s ++áÍ F 106:s ++áÎ F 107:s ++áÏ F 108:s ++áÐ F 109:s ++áÑ F 110:s ++áÒ F 111:s ++áÓ F 112:s ++áÔ F 113:s ++áÕ F 114:s ++áÖ F 115:s ++á× F 116:s ++áØ F 117:s ++áÙ F 118:s ++áÚ F 119:s ++áÛ F 120:s ++áÜ F 121:s ++áÝ F 122:s ++áÞ F 123:s ++áß F 124:s ++áà F 125:s ++áá F 126:s ++áâ F 127:s ++áã F 128:s ++áä F 129:s ++áå F 130:s ++áæ F 131:s ++áç F 132:s ++áè F 133:s ++áé F 134:s ++áê F 135:s ++áë F 136:s ++áì F 137:s ++áí F 138:s ++áî F 139:s ++áï F 140:s ++áð F 141:s ++áñ F 142:s ++áò F 143:s ++áó F 144:s ++áô F 145:s ++áõ F 146:s ++áö F 147:s ++á÷ F 148:s ++áø F 149:s ++áù F 150:s ++áú F 151:s ++áû F 152:s ++áü F 153:s ++áý F 154:s ++áþ F 155:s ++â¡ F 156:s ++⢠F 157:s ++⣠F 158:s ++†F 159:s ++⥠F 160:s ++⊠F 161:s ++⧠F 162:s ++âš F 163:s ++â© F 164:s ++⪠F 165:s ++â« F 166:s ++⬠F 167:s ++â F 168:s ++â® F 169:s ++⯠F 170:s ++â° F 171:s ++â± F 172:s ++â² F 173:s ++â³ F 174:s ++⎠F 175:s ++âµ F 176:s ++ⶠF 177:s ++â· F 178:s ++âž F 179:s ++â¹ F 180:s ++⺠F 181:s ++â» F 182:s ++⌠F 183:s ++✠F 184:s ++⟠F 185:s ++â¿ F 186:s ++âÀ F 187:s ++âÁ F 188:s ++â F 189:s ++âà F 190:s ++âÄ F 191:s ++âÅ F 192:s ++âÆ F 193:s ++âÇ F 194:s ++âÈ F 195:s ++âÉ F 196:s ++âÊ F 197:s ++âË F 198:s ++âÌ F 199:s ++âÍ F 200:s ++âÎ F 201:s ++âÏ F 202:s ++âÐ F 203:s ++âÑ F 204:s ++âÒ F 205:s ++âÓ F 206:s ++âÔ F 207:s ++âÕ F 208:s ++âÖ F 209:s ++â× F 210:s ++âØ F 211:s ++âÙ F 212:s ++âÚ F 213:s ++âÛ F 214:s ++âÜ F 215:s ++âÝ F 216:s ++âÞ F 217:s ++âß F 218:s ++âà F 219:s ++âá F 220:s ++ââ F 221:s ++âã F 222:s ++âä F 223:s ++âå F 224:s ++âæ F 225:s ++âç F 226:s ++âè F 227:s ++âé F 228:s ++âê F 229:s ++âë F 230:s ++âì F 231:s ++âí F 232:s ++âî F 233:s ++âï F 234:s ++âð F 235:s ++âñ F 236:s ++âò F 237:s ++âó F 238:s ++âô F 239:s ++âõ F 240:s ++âö F 241:s ++â÷ F 242:s ++âø F 243:s ++âù F 244:s ++âú F 245:s ++âû F 246:s ++âü F 247:s ++âý F 248:s ++âþ F 249:s ++ã¡ F 250:s ++㢠F 251:s ++㣠F 252:s ++〠F 253:s ++㥠F 254:s ++㊠F 255:s ++㧠F 0:t ++ãš F 1:t ++ã© F 2:t ++㪠F 3:t ++ã« F 4:t ++㬠F 5:t ++ã F 6:t ++ã® F 7:t ++㯠F 8:t ++ã° F 9:t ++ã± F 10:t ++ã² F 11:t ++ã³ F 12:t ++㎠F 13:t ++ãµ F 14:t ++㶠F 15:t ++ã· F 16:t ++ãž F 17:t ++ã¹ F 18:t ++㺠F 19:t ++ã» F 20:t ++㌠F 21:t ++㜠F 22:t ++㟠F 23:t ++ã¿ F 24:t ++ãÀ F 25:t ++ãÁ F 26:t ++ã F 27:t ++ãà F 28:t ++ãÄ F 29:t ++ãÅ F 30:t ++ãÆ F 31:t ++ãÇ F 32:t ++ãÈ F 33:t ++ãÉ F 34:t ++ãÊ F 35:t ++ãË F 36:t ++ãÌ F 37:t ++ãÍ F 38:t ++ãÎ F 39:t ++ãÏ F 40:t ++ãÐ F 41:t ++ãÑ F 42:t ++ãÒ F 43:t ++ãÓ F 44:t ++ãÔ F 45:t ++ãÕ F 46:t ++ãÖ F 47:t ++ã× F 48:t ++ãØ F 49:t ++ãÙ F 50:t ++ãÚ F 51:t ++ãÛ F 52:t ++ãÜ F 53:t ++ãÝ F 54:t ++ãÞ F 55:t ++ãß F 56:t ++ãà F 57:t ++ãá F 58:t ++ãâ F 59:t ++ãã F 60:t ++ãä F 61:t ++ãå F 62:t ++ãæ F 63:t ++ãç F 64:t ++ãè F 65:t ++ãé F 66:t ++ãê F 67:t ++ãë F 68:t ++ãì F 69:t ++ãí F 70:t ++ãî F 71:t ++ãï F 72:t ++ãð F 73:t ++ãñ F 74:t ++ãò F 75:t ++ãó F 76:t ++ãô F 77:t ++ãõ F 78:t ++ãö F 79:t ++ã÷ F 80:t ++ãø F 81:t ++ãù F 82:t ++ãú F 83:t ++ãû F 84:t ++ãü F 85:t ++ãý F 86:t ++ãþ F 87:t ++ä¡ F 88:t ++ä¢ F 89:t ++ä£ F 90:t ++ä€ F 91:t ++ä¥ F 92:t ++äŠ F 93:t ++ä§ F 94:t ++äš F 95:t ++ä© F 96:t ++äª F 97:t ++ä« F 98:t ++ä¬ F 99:t ++ä F 100:t ++ä® F 101:t ++ä¯ F 102:t ++ä° F 103:t ++ä± F 104:t ++ä² F 105:t ++ä³ F 106:t ++äŽ F 107:t ++äµ F 108:t ++ä¶ F 109:t ++ä· F 110:t ++äž F 111:t ++ä¹ F 112:t ++äº F 113:t ++ä» F 114:t ++äŒ F 115:t ++äœ F 116:t ++äŸ F 117:t ++ä¿ F 118:t ++äÀ F 119:t ++äÁ F 120:t ++ä F 121:t ++äà F 122:t ++äÄ F 123:t ++äÅ F 124:t ++äÆ F 125:t ++äÇ F 126:t ++äÈ F 127:t ++äÉ F 128:t ++äÊ F 129:t ++äË F 130:t ++äÌ F 131:t ++äÍ F 132:t ++äÎ F 133:t ++äÏ F 134:t ++äÐ F 135:t ++äÑ F 136:t ++äÒ F 137:t ++äÓ F 138:t ++äÔ F 139:t ++äÕ F 140:t ++äÖ F 141:t ++ä× F 142:t ++äØ F 143:t ++äÙ F 144:t ++äÚ F 145:t ++äÛ F 146:t ++äÜ F 147:t ++äÝ F 148:t ++äÞ F 149:t ++äß F 150:t ++äà F 151:t ++äá F 152:t ++äâ F 153:t ++äã F 154:t ++ää F 155:t ++äå F 156:t ++äæ F 157:t ++äç F 158:t ++äè F 159:t ++äé F 160:t ++äê F 161:t ++äë F 162:t ++äì F 163:t ++äí F 164:t ++äî F 165:t ++äï F 166:t ++äð F 167:t ++äñ F 168:t ++äò F 169:t ++äó F 170:t ++äô F 171:t ++äõ F 172:t ++äö F 173:t ++ä÷ F 174:t ++äø F 175:t ++äù F 176:t ++äú F 177:t ++äû F 178:t ++äü F 179:t ++äý F 180:t ++äþ F 181:t ++å¡ F 182:t ++å¢ F 183:t ++å£ F 184:t ++å€ F 185:t ++å¥ F 186:t ++åŠ F 187:t ++å§ F 188:t ++åš F 189:t ++å© F 190:t ++åª F 191:t ++å« F 192:t ++å¬ F 193:t ++å F 194:t ++å® F 195:t ++å¯ F 196:t ++å° F 197:t ++å± F 198:t ++å² F 199:t ++å³ F 200:t ++åŽ F 201:t ++åµ F 202:t ++å¶ F 203:t ++å· F 204:t ++åž F 205:t ++å¹ F 206:t ++åº F 207:t ++å» F 208:t ++åŒ F 209:t ++åœ F 210:t ++åŸ F 211:t ++å¿ F 212:t ++åÀ F 213:t ++åÁ F 214:t ++å F 215:t ++åà F 216:t ++åÄ F 217:t ++åÅ F 218:t ++åÆ F 219:t ++åÇ F 220:t ++åÈ F 221:t ++åÉ F 222:t ++åÊ F 223:t ++åË F 224:t ++åÌ F 225:t ++åÍ F 226:t ++åÎ F 227:t ++åÏ F 228:t ++åÐ F 229:t ++åÑ F 230:t ++åÒ F 231:t ++åÓ F 232:t ++åÔ F 233:t ++åÕ F 234:t ++åÖ F 235:t ++å× F 236:t ++åØ F 237:t ++åÙ F 238:t ++åÚ F 239:t ++åÛ F 240:t ++åÜ F 241:t ++åÝ F 242:t ++åÞ F 243:t ++åß F 244:t ++åà F 245:t ++åá F 246:t ++åâ F 247:t ++åã F 248:t ++åä F 249:t ++åå F 250:t ++åæ F 251:t ++åç F 252:t ++åè F 253:t ++åé F 254:t ++åê F 255:t ++åë F 0:u ++åì F 1:u ++åí F 2:u ++åî F 3:u ++åï F 4:u ++åð F 5:u ++åñ F 6:u ++åò F 7:u ++åó F 8:u ++åô F 9:u ++åõ F 10:u ++åö F 11:u ++å÷ F 12:u ++åø F 13:u ++åù F 14:u ++åú F 15:u ++åû F 16:u ++åü F 17:u ++åý F 18:u ++åþ F 19:u ++æ¡ F 20:u ++æ¢ F 21:u ++æ£ F 22:u ++æ€ F 23:u ++æ¥ F 24:u ++æŠ F 25:u ++æ§ F 26:u ++æš F 27:u ++æ© F 28:u ++æª F 29:u ++æ« F 30:u ++æ¬ F 31:u ++æ F 32:u ++æ® F 33:u ++æ¯ F 34:u ++æ° F 35:u ++æ± F 36:u ++æ² F 37:u ++æ³ F 38:u ++æŽ F 39:u ++æµ F 40:u ++æ¶ F 41:u ++æ· F 42:u ++æž F 43:u ++æ¹ F 44:u ++æº F 45:u ++æ» F 46:u ++æŒ F 47:u ++æœ F 48:u ++æŸ F 49:u ++æ¿ F 50:u ++æÀ F 51:u ++æÁ F 52:u ++æ F 53:u ++æà F 54:u ++æÄ F 55:u ++æÅ F 56:u ++æÆ F 57:u ++æÇ F 58:u ++æÈ F 59:u ++æÉ F 60:u ++æÊ F 61:u ++æË F 62:u ++æÌ F 63:u ++æÍ F 64:u ++æÎ F 65:u ++æÏ F 66:u ++æÐ F 67:u ++æÑ F 68:u ++æÒ F 69:u ++æÓ F 70:u ++æÔ F 71:u ++æÕ F 72:u ++æÖ F 73:u ++æ× F 74:u ++æØ F 75:u ++æÙ F 76:u ++æÚ F 77:u ++æÛ F 78:u ++æÜ F 79:u ++æÝ F 80:u ++æÞ F 81:u ++æß F 82:u ++æà F 83:u ++æá F 84:u ++æâ F 85:u ++æã F 86:u ++æä F 87:u ++æå F 88:u ++ææ F 89:u ++æç F 90:u ++æè F 91:u ++æé F 92:u ++æê F 93:u ++æë F 94:u ++æì F 95:u ++æí F 96:u ++æî F 97:u ++æï F 98:u ++æð F 99:u ++æñ F 100:u ++æò F 101:u ++æó F 102:u ++æô F 103:u ++æõ F 104:u ++æö F 105:u ++æ÷ F 106:u ++æø F 107:u ++æù F 108:u ++æú F 109:u ++æû F 110:u ++æü F 111:u ++æý F 112:u ++æþ F 113:u ++ç¡ F 114:u ++ç¢ F 115:u ++ç£ F 116:u ++ç€ F 117:u ++ç¥ F 118:u ++çŠ F 119:u ++ç§ F 120:u ++çš F 121:u ++ç© F 122:u ++çª F 123:u ++ç« F 124:u ++ç¬ F 125:u ++ç F 126:u ++ç® F 127:u ++ç¯ F 128:u ++ç° F 129:u ++ç± F 130:u ++ç² F 131:u ++ç³ F 132:u ++çŽ F 133:u ++çµ F 134:u ++ç¶ F 135:u ++ç· F 136:u ++çž F 137:u ++ç¹ F 138:u ++çº F 139:u ++ç» F 140:u ++çŒ F 141:u ++çœ F 142:u ++çŸ F 143:u ++ç¿ F 144:u ++çÀ F 145:u ++çÁ F 146:u ++ç F 147:u ++çà F 148:u ++çÄ F 149:u ++çÅ F 150:u ++çÆ F 151:u ++çÇ F 152:u ++çÈ F 153:u ++çÉ F 154:u ++çÊ F 155:u ++çË F 156:u ++çÌ F 157:u ++çÍ F 158:u ++çÎ F 159:u ++çÏ F 160:u ++çÐ F 161:u ++çÑ F 162:u ++çÒ F 163:u ++çÓ F 164:u ++çÔ F 165:u ++çÕ F 166:u ++çÖ F 167:u ++ç× F 168:u ++çØ F 169:u ++çÙ F 170:u ++çÚ F 171:u ++çÛ F 172:u ++çÜ F 173:u ++çÝ F 174:u ++çÞ F 175:u ++çß F 176:u ++çà F 177:u ++çá F 178:u ++çâ F 179:u ++çã F 180:u ++çä F 181:u ++çå F 182:u ++çæ F 183:u ++çç F 184:u ++çè F 185:u ++çé F 186:u ++çê F 187:u ++çë F 188:u ++çì F 189:u ++çí F 190:u ++çî F 191:u ++çï F 192:u ++çð F 193:u ++çñ F 194:u ++çò F 195:u ++çó F 196:u ++çô F 197:u ++çõ F 198:u ++çö F 199:u ++ç÷ F 200:u ++çø F 201:u ++çù F 202:u ++çú F 203:u ++çû F 204:u ++çü F 205:u ++çý F 206:u ++çþ F 207:u ++è¡ F 208:u ++è¢ F 209:u ++è£ F 210:u ++è€ F 211:u ++è¥ F 212:u ++èŠ F 213:u ++è§ F 214:u ++èš F 215:u ++è© F 216:u ++èª F 217:u ++è« F 218:u ++è¬ F 219:u ++è F 220:u ++è® F 221:u ++è¯ F 222:u ++è° F 223:u ++è± F 224:u ++è² F 225:u ++è³ F 226:u ++èŽ F 227:u ++èµ F 228:u ++è¶ F 229:u ++è· F 230:u ++èž F 231:u ++è¹ F 232:u ++èº F 233:u ++è» F 234:u ++èŒ F 235:u ++èœ F 236:u ++èŸ F 237:u ++è¿ F 238:u ++èÀ F 239:u ++èÁ F 240:u ++è F 241:u ++èà F 242:u ++èÄ F 243:u ++èÅ F 244:u ++èÆ F 245:u ++èÇ F 246:u ++èÈ F 247:u ++èÉ F 248:u ++èÊ F 249:u ++èË F 250:u ++èÌ F 251:u ++èÍ F 252:u ++èÎ F 253:u ++èÏ F 254:u ++èÐ F 255:u ++èÑ F 0:v ++èÒ F 1:v ++èÓ F 2:v ++èÔ F 3:v ++èÕ F 4:v ++èÖ F 5:v ++è× F 6:v ++èØ F 7:v ++èÙ F 8:v ++èÚ F 9:v ++èÛ F 10:v ++èÜ F 11:v ++èÝ F 12:v ++èÞ F 13:v ++èß F 14:v ++èà F 15:v ++èá F 16:v ++èâ F 17:v ++èã F 18:v ++èä F 19:v ++èå F 20:v ++èæ F 21:v ++èç F 22:v ++èè F 23:v ++èé F 24:v ++èê F 25:v ++èë F 26:v ++èì F 27:v ++èí F 28:v ++èî F 29:v ++èï F 30:v ++èð F 31:v ++èñ F 32:v ++èò F 33:v ++èó F 34:v ++èô F 35:v ++èõ F 36:v ++èö F 37:v ++è÷ F 38:v ++èø F 39:v ++èù F 40:v ++èú F 41:v ++èû F 42:v ++èü F 43:v ++èý F 44:v ++èþ F 45:v ++é¡ F 46:v ++é¢ F 47:v ++é£ F 48:v ++é€ F 49:v ++é¥ F 50:v ++éŠ F 51:v ++é§ F 52:v ++éš F 53:v ++é© F 54:v ++éª F 55:v ++é« F 56:v ++é¬ F 57:v ++é F 58:v ++é® F 59:v ++é¯ F 60:v ++é° F 61:v ++é± F 62:v ++é² F 63:v ++é³ F 64:v ++éŽ F 65:v ++éµ F 66:v ++é¶ F 67:v ++é· F 68:v ++éž F 69:v ++é¹ F 70:v ++éº F 71:v ++é» F 72:v ++éŒ F 73:v ++éœ F 74:v ++éŸ F 75:v ++é¿ F 76:v ++éÀ F 77:v ++éÁ F 78:v ++é F 79:v ++éà F 80:v ++éÄ F 81:v ++éÅ F 82:v ++éÆ F 83:v ++éÇ F 84:v ++éÈ F 85:v ++éÉ F 86:v ++éÊ F 87:v ++éË F 88:v ++éÌ F 89:v ++éÍ F 90:v ++éÎ F 91:v ++éÏ F 92:v ++éÐ F 93:v ++éÑ F 94:v ++éÒ F 95:v ++éÓ F 96:v ++éÔ F 97:v ++éÕ F 98:v ++éÖ F 99:v ++é× F 100:v ++éØ F 101:v ++éÙ F 102:v ++éÚ F 103:v ++éÛ F 104:v ++éÜ F 105:v ++éÝ F 106:v ++éÞ F 107:v ++éß F 108:v ++éà F 109:v ++éá F 110:v ++éâ F 111:v ++éã F 112:v ++éä F 113:v ++éå F 114:v ++éæ F 115:v ++éç F 116:v ++éè F 117:v ++éé F 118:v ++éê F 119:v ++éë F 120:v ++éì F 121:v ++éí F 122:v ++éî F 123:v ++éï F 124:v ++éð F 125:v ++éñ F 126:v ++éò F 127:v ++éó F 128:v ++éô F 129:v ++éõ F 130:v ++éö F 131:v ++é÷ F 132:v ++éø F 133:v ++éù F 134:v ++éú F 135:v ++éû F 136:v ++éü F 137:v ++éý F 138:v ++éþ F 139:v ++ê¡ F 140:v ++ê¢ F 141:v ++ê£ F 142:v ++ê€ F 143:v ++ê¥ F 144:v ++êŠ F 145:v ++ê§ F 146:v ++êš F 147:v ++ê© F 148:v ++êª F 149:v ++ê« F 150:v ++ê¬ F 151:v ++ê F 152:v ++ê® F 153:v ++ê¯ F 154:v ++ê° F 155:v ++ê± F 156:v ++ê² F 157:v ++ê³ F 158:v ++êŽ F 159:v ++êµ F 160:v ++ê¶ F 161:v ++ê· F 162:v ++êž F 163:v ++ê¹ F 164:v ++êº F 165:v ++ê» F 166:v ++êŒ F 167:v ++êœ F 168:v ++êŸ F 169:v ++ê¿ F 170:v ++êÀ F 171:v ++êÁ F 172:v ++ê F 173:v ++êà F 174:v ++êÄ F 175:v ++êÅ F 176:v ++êÆ F 177:v ++êÇ F 178:v ++êÈ F 179:v ++êÉ F 180:v ++êÊ F 181:v ++êË F 182:v ++êÌ F 183:v ++êÍ F 184:v ++êÎ F 185:v ++êÏ F 186:v ++êÐ F 187:v ++êÑ F 188:v ++êÒ F 189:v ++êÓ F 190:v ++êÔ F 191:v ++êÕ F 192:v ++êÖ F 193:v ++ê× F 194:v ++êØ F 195:v ++êÙ F 196:v ++êÚ F 197:v ++êÛ F 198:v ++êÜ F 199:v ++êÝ F 200:v ++êÞ F 201:v ++êß F 202:v ++êà F 203:v ++êá F 204:v ++êâ F 205:v ++êã F 206:v ++êä F 207:v ++êå F 208:v ++êæ F 209:v ++êç F 210:v ++êè F 211:v ++êé F 212:v ++êê F 213:v ++êë F 214:v ++êì F 215:v ++êí F 216:v ++êî F 217:v ++êï F 218:v ++êð F 219:v ++êñ F 220:v ++êò F 221:v ++êó F 222:v ++êô F 223:v ++êõ F 224:v ++êö F 225:v ++ê÷ F 226:v ++êø F 227:v ++êù F 228:v ++êú F 229:v ++êû F 230:v ++êü F 231:v ++êý F 232:v ++êþ F 233:v ++ë¡ F 234:v ++ë¢ F 235:v ++ë£ F 236:v ++ë€ F 237:v ++ë¥ F 238:v ++ëŠ F 239:v ++ë§ F 240:v ++ëš F 241:v ++ë© F 242:v ++ëª F 243:v ++ë« F 244:v ++ë¬ F 245:v ++ë F 246:v ++ë® F 247:v ++ë¯ F 248:v ++ë° F 249:v ++ë± F 250:v ++ë² F 251:v ++ë³ F 252:v ++ëŽ F 253:v ++ëµ F 254:v ++ë¶ F 255:v ++ë· F 0:w ++ëž F 1:w ++ë¹ F 2:w ++ëº F 3:w ++ë» F 4:w ++ëŒ F 5:w ++ëœ F 6:w ++ëŸ F 7:w ++ë¿ F 8:w ++ëÀ F 9:w ++ëÁ F 10:w ++ë F 11:w ++ëà F 12:w ++ëÄ F 13:w ++ëÅ F 14:w ++ëÆ F 15:w ++ëÇ F 16:w ++ëÈ F 17:w ++ëÉ F 18:w ++ëÊ F 19:w ++ëË F 20:w ++ëÌ F 21:w ++ëÍ F 22:w ++ëÎ F 23:w ++ëÏ F 24:w ++ëÐ F 25:w ++ëÑ F 26:w ++ëÒ F 27:w ++ëÓ F 28:w ++ëÔ F 29:w ++ëÕ F 30:w ++ëÖ F 31:w ++ë× F 32:w ++ëØ F 33:w ++ëÙ F 34:w ++ëÚ F 35:w ++ëÛ F 36:w ++ëÜ F 37:w ++ëÝ F 38:w ++ëÞ F 39:w ++ëß F 40:w ++ëà F 41:w ++ëá F 42:w ++ëâ F 43:w ++ëã F 44:w ++ëä F 45:w ++ëå F 46:w ++ëæ F 47:w ++ëç F 48:w ++ëè F 49:w ++ëé F 50:w ++ëê F 51:w ++ëë F 52:w ++ëì F 53:w ++ëí F 54:w ++ëî F 55:w ++ëï F 56:w ++ëð F 57:w ++ëñ F 58:w ++ëò F 59:w ++ëó F 60:w ++ëô F 61:w ++ëõ F 62:w ++ëö F 63:w ++ë÷ F 64:w ++ëø F 65:w ++ëù F 66:w ++ëú F 67:w ++ëû F 68:w ++ëü F 69:w ++ëý F 70:w ++ëþ F 71:w ++ì¡ F 72:w ++ì¢ F 73:w ++ì£ F 74:w ++ì€ F 75:w ++ì¥ F 76:w ++ìŠ F 77:w ++ì§ F 78:w ++ìš F 79:w ++ì© F 80:w ++ìª F 81:w ++ì« F 82:w ++ì¬ F 83:w ++ì F 84:w ++ì® F 85:w ++ì¯ F 86:w ++ì° F 87:w ++ì± F 88:w ++ì² F 89:w ++ì³ F 90:w ++ìŽ F 91:w ++ìµ F 92:w ++ì¶ F 93:w ++ì· F 94:w ++ìž F 95:w ++ì¹ F 96:w ++ìº F 97:w ++ì» F 98:w ++ìŒ F 99:w ++ìœ F 100:w ++ìŸ F 101:w ++ì¿ F 102:w ++ìÀ F 103:w ++ìÁ F 104:w ++ì F 105:w ++ìà F 106:w ++ìÄ F 107:w ++ìÅ F 108:w ++ìÆ F 109:w ++ìÇ F 110:w ++ìÈ F 111:w ++ìÉ F 112:w ++ìÊ F 113:w ++ìË F 114:w ++ìÌ F 115:w ++ìÍ F 116:w ++ìÎ F 117:w ++ìÏ F 118:w ++ìÐ F 119:w ++ìÑ F 120:w ++ìÒ F 121:w ++ìÓ F 122:w ++ìÔ F 123:w ++ìÕ F 124:w ++ìÖ F 125:w ++ì× F 126:w ++ìØ F 127:w ++ìÙ F 128:w ++ìÚ F 129:w ++ìÛ F 130:w ++ìÜ F 131:w ++ìÝ F 132:w ++ìÞ F 133:w ++ìß F 134:w ++ìà F 135:w ++ìá F 136:w ++ìâ F 137:w ++ìã F 138:w ++ìä F 139:w ++ìå F 140:w ++ìæ F 141:w ++ìç F 142:w ++ìè F 143:w ++ìé F 144:w ++ìê F 145:w ++ìë F 146:w ++ìì F 147:w ++ìí F 148:w ++ìî F 149:w ++ìï F 150:w ++ìð F 151:w ++ìñ F 152:w ++ìò F 153:w ++ìó F 154:w ++ìô F 155:w ++ìõ F 156:w ++ìö F 157:w ++ì÷ F 158:w ++ìø F 159:w ++ìù F 160:w ++ìú F 161:w ++ìû F 162:w ++ìü F 163:w ++ìý F 164:w ++ìþ F 165:w ++í¡ F 166:w ++í¢ F 167:w ++í£ F 168:w ++í€ F 169:w ++í¥ F 170:w ++íŠ F 171:w ++í§ F 172:w ++íš F 173:w ++í© F 174:w ++íª F 175:w ++í« F 176:w ++í¬ F 177:w ++í F 178:w ++í® F 179:w ++í¯ F 180:w ++í° F 181:w ++í± F 182:w ++í² F 183:w ++í³ F 184:w ++íŽ F 185:w ++íµ F 186:w ++í¶ F 187:w ++í· F 188:w ++íž F 189:w ++í¹ F 190:w ++íº F 191:w ++í» F 192:w ++íŒ F 193:w ++íœ F 194:w ++íŸ F 195:w ++í¿ F 196:w ++íÀ F 197:w ++íÁ F 198:w ++í F 199:w ++íà F 200:w ++íÄ F 201:w ++íÅ F 202:w ++íÆ F 203:w ++íÇ F 204:w ++íÈ F 205:w ++íÉ F 206:w ++íÊ F 207:w ++íË F 208:w ++íÌ F 209:w ++íÍ F 210:w ++íÎ F 211:w ++íÏ F 212:w ++íÐ F 213:w ++íÑ F 214:w ++íÒ F 215:w ++íÓ F 216:w ++íÔ F 217:w ++íÕ F 218:w ++íÖ F 219:w ++í× F 220:w ++íØ F 221:w ++íÙ F 222:w ++íÚ F 223:w ++íÛ F 224:w ++íÜ F 225:w ++íÝ F 226:w ++íÞ F 227:w ++íß F 228:w ++íà F 229:w ++íá F 230:w ++íâ F 231:w ++íã F 232:w ++íä F 233:w ++íå F 234:w ++íæ F 235:w ++íç F 236:w ++íè F 237:w ++íé F 238:w ++íê F 239:w ++íë F 240:w ++íì F 241:w ++íí F 242:w ++íî F 243:w ++íï F 244:w ++íð F 245:w ++íñ F 246:w ++íò F 247:w ++íó F 248:w ++íô F 249:w ++íõ F 250:w ++íö F 251:w ++í÷ F 252:w ++íø F 253:w ++íù F 254:w ++íú F 255:w ++íû F 0:x ++íü F 1:x ++íý F 2:x ++íþ F 3:x ++î¡ F 4:x ++î¢ F 5:x ++î£ F 6:x ++î€ F 7:x ++î¥ F 8:x ++îŠ F 9:x ++î§ F 10:x ++îš F 11:x ++î© F 12:x ++îª F 13:x ++î« F 14:x ++î¬ F 15:x ++î F 16:x ++î® F 17:x ++î¯ F 18:x ++î° F 19:x ++î± F 20:x ++î² F 21:x ++î³ F 22:x ++îŽ F 23:x ++îµ F 24:x ++î¶ F 25:x ++î· F 26:x ++îž F 27:x ++î¹ F 28:x ++îº F 29:x ++î» F 30:x ++îŒ F 31:x ++îœ F 32:x ++îŸ F 33:x ++î¿ F 34:x ++îÀ F 35:x ++îÁ F 36:x ++î F 37:x ++îà F 38:x ++îÄ F 39:x ++îÅ F 40:x ++îÆ F 41:x ++îÇ F 42:x ++îÈ F 43:x ++îÉ F 44:x ++îÊ F 45:x ++îË F 46:x ++îÌ F 47:x ++îÍ F 48:x ++îÎ F 49:x ++îÏ F 50:x ++îÐ F 51:x ++îÑ F 52:x ++îÒ F 53:x ++îÓ F 54:x ++îÔ F 55:x ++îÕ F 56:x ++îÖ F 57:x ++î× F 58:x ++îØ F 59:x ++îÙ F 60:x ++îÚ F 61:x ++îÛ F 62:x ++îÜ F 63:x ++îÝ F 64:x ++îÞ F 65:x ++îß F 66:x ++îà F 67:x ++îá F 68:x ++îâ F 69:x ++îã F 70:x ++îä F 71:x ++îå F 72:x ++îæ F 73:x ++îç F 74:x ++îè F 75:x ++îé F 76:x ++îê F 77:x ++îë F 78:x ++îì F 79:x ++îí F 80:x ++îî F 81:x ++îï F 82:x ++îð F 83:x ++îñ F 84:x ++îò F 85:x ++îó F 86:x ++îô F 87:x ++îõ F 88:x ++îö F 89:x ++î÷ F 90:x ++îø F 91:x ++îù F 92:x ++îú F 93:x ++îû F 94:x ++îü F 95:x ++îý F 96:x ++îþ F 97:x ++ï¡ F 98:x ++ï¢ F 99:x ++ï£ F 100:x ++ï€ F 101:x ++ï¥ F 102:x ++ïŠ F 103:x ++ï§ F 104:x ++ïš F 105:x ++ï© F 106:x ++ïª F 107:x ++ï« F 108:x ++ï¬ F 109:x ++ï F 110:x ++ï® F 111:x ++ï¯ F 112:x ++ï° F 113:x ++ï± F 114:x ++ï² F 115:x ++ï³ F 116:x ++ïŽ F 117:x ++ïµ F 118:x ++ï¶ F 119:x ++ï· F 120:x ++ïž F 121:x ++ï¹ F 122:x ++ïº F 123:x ++ï» F 124:x ++ïŒ F 125:x ++ïœ F 126:x ++ïŸ F 127:x ++ï¿ F 128:x ++ïÀ F 129:x ++ïÁ F 130:x ++ï F 131:x ++ïà F 132:x ++ïÄ F 133:x ++ïÅ F 134:x ++ïÆ F 135:x ++ïÇ F 136:x ++ïÈ F 137:x ++ïÉ F 138:x ++ïÊ F 139:x ++ïË F 140:x ++ïÌ F 141:x ++ïÍ F 142:x ++ïÎ F 143:x ++ïÏ F 144:x ++ïÐ F 145:x ++ïÑ F 146:x ++ïÒ F 147:x ++ïÓ F 148:x ++ïÔ F 149:x ++ïÕ F 150:x ++ïÖ F 151:x ++ï× F 152:x ++ïØ F 153:x ++ïÙ F 154:x ++ïÚ F 155:x ++ïÛ F 156:x ++ïÜ F 157:x ++ïÝ F 158:x ++ïÞ F 159:x ++ïß F 160:x ++ïà F 161:x ++ïá F 162:x ++ïâ F 163:x ++ïã F 164:x ++ïä F 165:x ++ïå F 166:x ++ïæ F 167:x ++ïç F 168:x ++ïè F 169:x ++ïé F 170:x ++ïê F 171:x ++ïë F 172:x ++ïì F 173:x ++ïí F 174:x ++ïî F 175:x ++ïï F 176:x ++ïð F 177:x ++ïñ F 178:x ++ïò F 179:x ++ïó F 180:x ++ïô F 181:x ++ïõ F 182:x ++ïö F 183:x ++ï÷ F 184:x ++ïø F 185:x ++ïù F 186:x ++ïú F 187:x ++ïû F 188:x ++ïü F 189:x ++ïý F 190:x ++ïþ F 191:x ++ð¡ F 192:x ++ð¢ F 193:x ++ð£ F 194:x ++ð€ F 195:x ++ð¥ F 196:x ++ðŠ F 197:x ++ð§ F 198:x ++ðš F 199:x ++ð© F 200:x ++ðª F 201:x ++ð« F 202:x ++ð¬ F 203:x ++ð F 204:x ++ð® F 205:x ++ð¯ F 206:x ++ð° F 207:x ++ð± F 208:x ++ð² F 209:x ++ð³ F 210:x ++ðŽ F 211:x ++ðµ F 212:x ++ð¶ F 213:x ++ð· F 214:x ++ðž F 215:x ++ð¹ F 216:x ++ðº F 217:x ++ð» F 218:x ++ðŒ F 219:x ++ðœ F 220:x ++ðŸ F 221:x ++ð¿ F 222:x ++ðÀ F 223:x ++ðÁ F 224:x ++ð F 225:x ++ðà F 226:x ++ðÄ F 227:x ++ðÅ F 228:x ++ðÆ F 229:x ++ðÇ F 230:x ++ðÈ F 231:x ++ðÉ F 232:x ++ðÊ F 233:x ++ðË F 234:x ++ðÌ F 235:x ++ðÍ F 236:x ++ðÎ F 237:x ++ðÏ F 238:x ++ðÐ F 239:x ++ðÑ F 240:x ++ðÒ F 241:x ++ðÓ F 242:x ++ðÔ F 243:x ++ðÕ F 244:x ++ðÖ F 245:x ++ð× F 246:x ++ðØ F 247:x ++ðÙ F 248:x ++ðÚ F 249:x ++ðÛ F 250:x ++ðÜ F 251:x ++ðÝ F 252:x ++ðÞ F 253:x ++ðß F 254:x ++ðà F 255:x ++ðá F 0:y ++ðâ F 1:y ++ðã F 2:y ++ðä F 3:y ++ðå F 4:y ++ðæ F 5:y ++ðç F 6:y ++ðè F 7:y ++ðé F 8:y ++ðê F 9:y ++ðë F 10:y ++ðì F 11:y ++ðí F 12:y ++ðî F 13:y ++ðï F 14:y ++ðð F 15:y ++ðñ F 16:y ++ðò F 17:y ++ðó F 18:y ++ðô F 19:y ++ðõ F 20:y ++ðö F 21:y ++ð÷ F 22:y ++ðø F 23:y ++ðù F 24:y ++ðú F 25:y ++ðû F 26:y ++ðü F 27:y ++ðý F 28:y ++ðþ F 29:y ++ñ¡ F 30:y ++ñ¢ F 31:y ++ñ£ F 32:y ++ñ€ F 33:y ++ñ¥ F 34:y ++ñŠ F 35:y ++ñ§ F 36:y ++ñš F 37:y ++ñ© F 38:y ++ñª F 39:y ++ñ« F 40:y ++ñ¬ F 41:y ++ñ F 42:y ++ñ® F 43:y ++ñ¯ F 44:y ++ñ° F 45:y ++ñ± F 46:y ++ñ² F 47:y ++ñ³ F 48:y ++ñŽ F 49:y ++ñµ F 50:y ++ñ¶ F 51:y ++ñ· F 52:y ++ñž F 53:y ++ñ¹ F 54:y ++ñº F 55:y ++ñ» F 56:y ++ñŒ F 57:y ++ñœ F 58:y ++ñŸ F 59:y ++ñ¿ F 60:y ++ñÀ F 61:y ++ñÁ F 62:y ++ñ F 63:y ++ñà F 64:y ++ñÄ F 65:y ++ñÅ F 66:y ++ñÆ F 67:y ++ñÇ F 68:y ++ñÈ F 69:y ++ñÉ F 70:y ++ñÊ F 71:y ++ñË F 72:y ++ñÌ F 73:y ++ñÍ F 74:y ++ñÎ F 75:y ++ñÏ F 76:y ++ñÐ F 77:y ++ñÑ F 78:y ++ñÒ F 79:y ++ñÓ F 80:y ++ñÔ F 81:y ++ñÕ F 82:y ++ñÖ F 83:y ++ñ× F 84:y ++ñØ F 85:y ++ñÙ F 86:y ++ñÚ F 87:y ++ñÛ F 88:y ++ñÜ F 89:y ++ñÝ F 90:y ++ñÞ F 91:y ++ñß F 92:y ++ñà F 93:y ++ñá F 94:y ++ñâ F 95:y ++ñã F 96:y ++ñä F 97:y ++ñå F 98:y ++ñæ F 99:y ++ñç F 100:y ++ñè F 101:y ++ñé F 102:y ++ñê F 103:y ++ñë F 104:y ++ñì F 105:y ++ñí F 106:y ++ñî F 107:y ++ñï F 108:y ++ñð F 109:y ++ññ F 110:y ++ñò F 111:y ++ñó F 112:y ++ñô F 113:y ++ñõ F 114:y ++ñö F 115:y ++ñ÷ F 116:y ++ñø F 117:y ++ñù F 118:y ++ñú F 119:y ++ñû F 120:y ++ñü F 121:y ++ñý F 122:y ++ñþ F 123:y ++ò¡ F 124:y ++ò¢ F 125:y ++ò£ F 126:y ++ò€ F 127:y ++ò¥ F 128:y ++òŠ F 129:y ++ò§ F 130:y ++òš F 131:y ++ò© F 132:y ++òª F 133:y ++ò« F 134:y ++ò¬ F 135:y ++ò F 136:y ++ò® F 137:y ++ò¯ F 138:y ++ò° F 139:y ++ò± F 140:y ++ò² F 141:y ++ò³ F 142:y ++òŽ F 143:y ++òµ F 144:y ++ò¶ F 145:y ++ò· F 146:y ++òž F 147:y ++ò¹ F 148:y ++òº F 149:y ++ò» F 150:y ++òŒ F 151:y ++òœ F 152:y ++òŸ F 153:y ++ò¿ F 154:y ++òÀ F 155:y ++òÁ F 156:y ++ò F 157:y ++òà F 158:y ++òÄ F 159:y ++òÅ F 160:y ++òÆ F 161:y ++òÇ F 162:y ++òÈ F 163:y ++òÉ F 164:y ++òÊ F 165:y ++òË F 166:y ++òÌ F 167:y ++òÍ F 168:y ++òÎ F 169:y ++òÏ F 170:y ++òÐ F 171:y ++òÑ F 172:y ++òÒ F 173:y ++òÓ F 174:y ++òÔ F 175:y ++òÕ F 176:y ++òÖ F 177:y ++ò× F 178:y ++òØ F 179:y ++òÙ F 180:y ++òÚ F 181:y ++òÛ F 182:y ++òÜ F 183:y ++òÝ F 184:y ++òÞ F 185:y ++òß F 186:y ++òà F 187:y ++òá F 188:y ++òâ F 189:y ++òã F 190:y ++òä F 191:y ++òå F 192:y ++òæ F 193:y ++òç F 194:y ++òè F 195:y ++òé F 196:y ++òê F 197:y ++òë F 198:y ++òì F 199:y ++òí F 200:y ++òî F 201:y ++òï F 202:y ++òð F 203:y ++òñ F 204:y ++òò F 205:y ++òó F 206:y ++òô F 207:y ++òõ F 208:y ++òö F 209:y ++ò÷ F 210:y ++òø F 211:y ++òù F 212:y ++òú F 213:y ++òû F 214:y ++òü F 215:y ++òý F 216:y ++òþ F 217:y ++ó¡ F 218:y ++ó¢ F 219:y ++ó£ F 220:y ++ó€ F 221:y ++ó¥ F 222:y ++óŠ F 223:y ++ó§ F 224:y ++óš F 225:y ++ó© F 226:y ++óª F 227:y ++ó« F 228:y ++ó¬ F 229:y ++ó F 230:y ++ó® F 231:y ++ó¯ F 232:y ++ó° F 233:y ++ó± F 234:y ++ó² F 235:y ++ó³ F 236:y ++óŽ F 237:y ++óµ F 238:y ++ó¶ F 239:y ++ó· F 240:y ++óž F 241:y ++ó¹ F 242:y ++óº F 243:y ++ó» F 244:y ++óŒ F 245:y ++óœ F 246:y ++óŸ F 247:y ++ó¿ F 248:y ++óÀ F 249:y ++óÁ F 250:y ++ó F 251:y ++óà F 252:y ++óÄ F 253:y ++óÅ F 254:y ++óÆ F 255:y ++óÇ F 0:z ++óÈ F 1:z ++óÉ F 2:z ++óÊ F 3:z ++óË F 4:z ++óÌ F 5:z ++óÍ F 6:z ++óÎ F 7:z ++óÏ F 8:z ++óÐ F 9:z ++óÑ F 10:z ++óÒ F 11:z ++óÓ F 12:z ++óÔ F 13:z ++óÕ F 14:z ++óÖ F 15:z ++ó× F 16:z ++óØ F 17:z ++óÙ F 18:z ++óÚ F 19:z ++óÛ F 20:z ++óÜ F 21:z ++óÝ F 22:z ++óÞ F 23:z ++óß F 24:z ++óà F 25:z ++óá F 26:z ++óâ F 27:z ++óã F 28:z ++óä F 29:z ++óå F 30:z ++óæ F 31:z ++óç F 32:z ++óè F 33:z ++óé F 34:z ++óê F 35:z ++óë F 36:z ++óì F 37:z ++óí F 38:z ++óî F 39:z ++óï F 40:z ++óð F 41:z ++óñ F 42:z ++óò F 43:z ++óó F 44:z ++óô F 45:z ++óõ F 46:z ++óö F 47:z ++ó÷ F 48:z ++óø F 49:z ++óù F 50:z ++óú F 51:z ++óû F 52:z ++óü F 53:z ++óý F 54:z ++óþ F 55:z ++ô¡ F 56:z ++ô¢ F 57:z ++ô£ F 58:z ++ô€ F 59:z +diff -Naur groff-1.18.1.4.orig/font/devdvi/Makefile.sub groff-1.18.1.4/font/devdvi/Makefile.sub +--- groff-1.18.1.4.orig/font/devdvi/Makefile.sub 2002-02-27 02:23:12.000000000 +0000 ++++ groff-1.18.1.4/font/devdvi/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -3,15 +3,68 @@ + TR TI TB TBI CW CWI HR HI HB HBI \ + TREC TIEC TBEC TBIEC CWEC CWIEC HREC HIEC HBEC HBIEC \ + TRTC TITC TBTC TBITC CWTC CWITC HRTC HITC HBTC HBITC \ +- MI S EX SA SB \ ++ MI S EX SA SB M G \ + generate/CompileFonts generate/Makefile \ + generate/msam.map generate/msbm.map \ + generate/texb.map generate/texex.map generate/texi.map generate/texmi.map \ + generate/texr.map generate/texsy.map generate/textt.map \ + generate/ec.map generate/tc.map + +-CLEANADD=DESC ++CLEANADD=DESC M G + + DESC: DESC.in + cat $(srcdir)/DESC.in >DESC + test -z '$(DVIPRINT)' || echo print '$(DVIPRINT)' >>DESC ++ ++M: M.proto-$(DVIFORMAT) ++ @echo Making $@ ++ @-rm -f $@ ++ cp M.proto-$(DVIFORMAT) M ++# @if [ x$(DVIFORMAT) = xNTT ]; then \ ++# sed -e 's/ F / 959887,808326,151561 1 /' \ ++# -e 's/:0$$/:dmjsy10/' \ ++# -e 's/:1$$/:dmjroma10/' \ ++# -e 's/:2$$/:dmjhira10/' \ ++# -e 's/:3$$/:dmjkata10/' \ ++# -e 's/:4$$/:dmjgreek10/' \ ++# -e 's/:5$$/:dmjrussian10/' \ ++# -e 's/:6$$/:dmjkeisen10/' \ ++# -e 's/:a$$/:dmjka10/' \ ++# -e 's/:b$$/:dmjkb10/' \ ++# -e 's/:c$$/:dmjkc10/' \ ++# -e 's/:d$$/:dmjkd10/' \ ++# -e 's/:e$$/:dmjke10/' \ ++# -e 's/:f$$/:dmjkf10/' \ ++# -e 's/:g$$/:dmjkg10/' \ ++# -e 's/:h$$/:dmjkh10/' \ ++# -e 's/:i$$/:dmjki10/' \ ++# -e 's/:j$$/:dmjkj10/' \ ++# -e 's/:k$$/:dmjkk10/' \ ++# -e 's/:l$$/:dmjkl10/' \ ++# -e 's/:m$$/:dmjkm10/' \ ++# -e 's/:n$$/:dmjkn10/' \ ++# -e 's/:o$$/:dmjko10/' \ ++# -e 's/:p$$/:dmjkp10/' \ ++# -e 's/:q$$/:dmjkq10/' \ ++# -e 's/:r$$/:dmjkr10/' \ ++# -e 's/:s$$/:dmjks10/' \ ++# -e 's/:t$$/:dmjkt10/' \ ++# -e 's/:u$$/:dmjku10/' \ ++# -e 's/:v$$/:dmjkv10/' \ ++# -e 's/:w$$/:dmjkw10/' \ ++# -e 's/:x$$/:dmjkx10/' \ ++# -e 's/:y$$/:dmjky10/' \ ++# -e 's/:z$$/:dmjkz10/' \ ++# < M.proto-NTT > M ;\ ++# else \ ++# ../devnippon/createM -jis "1006514,815360,145600" 1 < M.proto-ASCII | \ ++# sed -f FixMetric.sed > M ;\ ++# fi ++ ++G: M ++ @echo Making $@ ++ @-rm -f $@ ++ @sed -e 's/name M/name G/' \ ++ -e 's/dmj/dgj/' \ ++ -e 's/internalname min10/internalname goth10/' \ ++ < M > G +diff -Naur groff-1.18.1.4.orig/font/devhtml/DESC.proto groff-1.18.1.4/font/devhtml/DESC.proto +--- groff-1.18.1.4.orig/font/devhtml/DESC.proto 2002-08-07 12:52:23.000000000 +0000 ++++ groff-1.18.1.4/font/devhtml/DESC.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -3,7 +3,11 @@ + vert 40 + unitwidth 10 + sizes 6 8 10 12 14 16 18 0 +-fonts 9 R I B BI CR CI CB CBI S ++fonts 11 R I B BI CR CI CB CBI S M G ++fontset B G 2E00..9FFF ++fontset - M 2E00..9FFF ++fontset B G FF00..FFEF ++fontset - M FF00..FFEF + tcommand + html + postpro post-grohtml +diff -Naur groff-1.18.1.4.orig/font/devhtml/M.proto groff-1.18.1.4/font/devhtml/M.proto +--- groff-1.18.1.4.orig/font/devhtml/M.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devhtml/M.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,5 @@ ++name M ++spacewidth 16 ++charset ++u2E00..u9FFF 16,14,2 0 ++uFF00..uFFEF 16,14,2 0 +diff -Naur groff-1.18.1.4.orig/font/devhtml/Makefile.sub groff-1.18.1.4/font/devhtml/Makefile.sub +--- groff-1.18.1.4.orig/font/devhtml/Makefile.sub 2002-08-07 12:52:23.000000000 +0000 ++++ groff-1.18.1.4/font/devhtml/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -1,8 +1,10 @@ + DEV=html + PROTOFONTS=R I B BI CR CI CB CBI + FONTS=$(PROTOFONTS) S +-DEVFILES=$(FONTS) DESC +-CLEANADD=$(FONTS) DESC ++WFONTS=M G ++ALLFONTS=$(FONTS) $(WFONTS) ++DEVFILES=$(ALLFONTS) DESC ++CLEANADD=$(ALLFONTS) DESC + + RES=240 + CPI=10 +@@ -13,8 +15,8 @@ + @-rm -f $@ + @(charwidth=`expr $(RES) / $(CPI)` ; \ + sed -e "s/^name [A-Z]*$$/name $@/" \ +- -e "s/^\([^ ]*\) [0-9]+ /\1 $$charwidth /" \ +- -e "s/^spacewidth [0-9]+$$/spacewidth $$charwidth/" \ ++ -e "s/^\([^ ]*\) [0-9][0-9]* /\1 $$charwidth /" \ ++ -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ + -e "s/^internalname .*$$/internalname $@/" \ + -e "/^internalname/s/CR/4/" \ + -e "/^internalname/s/BI/3/" \ +@@ -29,6 +31,19 @@ + @sed -e "s/^res .*$$/res $(RES)/" \ + -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \ + -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \ +- -e "s/^fonts .*$$/fonts `set $(FONTS); echo $$#` $(FONTS)/" \ ++ -e "s/^fonts .*$$/fonts `set $(ALLFONTS); echo $$#` $(ALLFONTS)/" \ + $(srcdir)/DESC.proto >$@ + ++M: M.proto ++ @echo Making M ++ @-rm -f M ++ @(wcharwidth=`expr $(RES) / $(CPI) * 2`; \ ++ spacewidth=`expr $(RES) / $(CPI)`; \ ++ sed -e "s/^u\([0-9A-F]*\)..u\([0-9A-F]*\) [0-9][0-9]*/u\1..u\2 $$wcharwidth/" \ ++ -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$spacewidth/" \ ++ $(srcdir)/M.proto > $@) ++ ++G: M ++ @echo Making G ++ @-rm -f G ++ @sed -e 's/name M/name G/' M > G +diff -Naur groff-1.18.1.4.orig/font/devlbp/Makefile.sub groff-1.18.1.4/font/devlbp/Makefile.sub +--- groff-1.18.1.4.orig/font/devlbp/Makefile.sub 2002-03-08 07:33:49.000000000 +0000 ++++ groff-1.18.1.4/font/devlbp/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -13,9 +13,9 @@ + -rm -f DESC + cat $(srcdir)/DESC.in >>DESC + if test "$(PAGE)" = A4; then \ +- echo "papersize a4" >>DESC; \ ++ echo "papersize /etc/papersize a4" >>DESC; \ + else \ +- echo "papersize letter" >>DESC; \ ++ echo "papersize /etc/papersize letter" >>DESC; \ + fi + test -z '$(LBPPRINT)' || echo print '$(LBPPRINT)' >>DESC + +diff -Naur groff-1.18.1.4.orig/font/devlj4/Makefile.sub groff-1.18.1.4/font/devlj4/Makefile.sub +--- groff-1.18.1.4.orig/font/devlj4/Makefile.sub 2000-02-06 09:35:37.000000000 +0000 ++++ groff-1.18.1.4/font/devlj4/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -22,9 +22,9 @@ + echo "unitwidth `expr 7620000 / $(LJ4RES)`" >>DESC + cat $(srcdir)/DESC.in >>DESC + if test "$(PAGE)" = A4; then \ +- echo "papersize a4" >>DESC; \ ++ echo "papersize /etc/papersize a4" >>DESC; \ + else \ +- echo "papersize letter" >>DESC; \ ++ echo "papersize /etc/papersize letter" >>DESC; \ + fi + test -z '$(LJ4PRINT)' || echo print '$(LJ4PRINT)' >>DESC + +diff -Naur groff-1.18.1.4.orig/font/devnippon/DESC.proto groff-1.18.1.4/font/devnippon/DESC.proto +--- groff-1.18.1.4.orig/font/devnippon/DESC.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devnippon/DESC.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,12 @@ ++res 240 ++hor 24 ++vert 40 ++unitwidth 10 ++sizes 10 0 ++fonts 6 R I B BI M G ++fontset B G 2E00..9FFF ++fontset - M 2E00..9FFF ++fontset B G FF00..FFEF ++fontset - M FF00..FFEF ++tcommand ++postpro grotty +diff -Naur groff-1.18.1.4.orig/font/devnippon/M.proto groff-1.18.1.4/font/devnippon/M.proto +--- groff-1.18.1.4.orig/font/devnippon/M.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devnippon/M.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,6 @@ ++name M ++internalname 4 ++spacewidth 48 ++charset ++u2E00..u9FFF 48 0 ++uFF00..uFFEF 48 0 +diff -Naur groff-1.18.1.4.orig/font/devnippon/Makefile.sub groff-1.18.1.4/font/devnippon/Makefile.sub +--- groff-1.18.1.4.orig/font/devnippon/Makefile.sub 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devnippon/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,48 @@ ++DEV=nippon ++FONTS=R I B BI ++WFONTS=M G ++ALLFONTS=$(FONTS) $(WFONTS) ++DEVFILES=$(ALLFONTS) DESC ++CLEANADD=$(ALLFONTS) DESC ++ ++RES=240 ++CPI=10 ++LPI=6 ++ ++$(FONTS): R.proto ++ @echo Making $@ ++ @-rm -f $@ ++ @(charwidth=`expr $(RES) / $(CPI)` ; \ ++ sed -e "s/^name [A-Z]*$$/name $@/" \ ++ -e "s/^\([^ ]*\) [0-9][0-9]* /\1 $$charwidth /" \ ++ -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ ++ -e "s/^internalname .*$$/internalname $@/" \ ++ -e "/^internalname/s/BI/3/" \ ++ -e "/^internalname/s/B/2/" \ ++ -e "/^internalname/s/I/1/" \ ++ -e "/^internalname .*[^ 0-9]/d" \ ++ $(srcdir)/R.proto >$@) ++ ++M: M.proto ++ @echo Making M ++ @-rm -f M ++ @(wcharwidth=`expr $(RES) / $(CPI) * 2` ; \ ++ spacewidth=`expr $(RES) / $(CPI)` ; \ ++ sed -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$spacewidth/" \ ++ -e "s/^u\([0-9A-F]*\)..u\([0-9A-F]*\) [0-9][0-9]*/u\1..u\2 $$wcharwidth/" \ ++ $(srcdir)/M.proto > $@) ++ ++G: M ++ @echo Making G ++ @-rm -f G ++ @sed -e 's/name M/name G/' \ ++ -e 's/internalname 4/internalname 5/' M > G ++ ++DESC: DESC.proto ++ @echo Making $@ ++ @-rm -f $@ ++ @sed -e "s/^res .*$$/res $(RES)/" \ ++ -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \ ++ -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \ ++ -e "s/^fonts .*$$/fonts `set $(ALLFONTS); echo $$#` $(ALLFONTS)/" \ ++ $(srcdir)/DESC.proto >$@ +diff -Naur groff-1.18.1.4.orig/font/devnippon/R.proto groff-1.18.1.4/font/devnippon/R.proto +--- groff-1.18.1.4.orig/font/devnippon/R.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devnippon/R.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,167 @@ ++name R ++internalname 0 ++spacewidth 24 ++charset ++! 24 0 0041 ++" 24 0 0042 ++dq " ++lq " ++rq " ++# 24 0 0043 ++sh " ++$ 24 0 0044 ++Do " ++% 24 0 0045 ++& 24 0 0046 ++' 24 0 0047 ++aa " ++fm " ++aq " ++cq " ++( 24 0 0050 ++) 24 0 0051 ++* 24 0 0052 ++** " +++ 24 0 0053 ++pl " ++, 24 0 0054 ++- 24 0 0055 ++hy " ++- " ++mi " ++en " ++. 24 0 0056 ++/ 24 0 0057 ++sl " ++f/ " ++0 24 0 0060 ++1 24 0 0061 ++2 24 0 0062 ++3 24 0 0063 ++4 24 0 0064 ++5 24 0 0065 ++6 24 0 0066 ++7 24 0 0067 ++8 24 0 0070 ++9 24 0 0071 ++: 24 0 0072 ++; 24 0 0073 ++< 24 0 0074 ++la " ++fo " ++= 24 0 0075 ++eq " ++> 24 0 0076 ++ra " ++fc " ++? 24 0 0077 ++@ 24 0 0100 ++at " ++A 24 0 0101 ++*A " ++B 24 0 0102 ++*B " ++C 24 0 0103 ++D 24 0 0104 ++E 24 0 0105 ++*E " ++F 24 0 0106 ++G 24 0 0107 ++H 24 0 0110 ++*Y " ++I 24 0 0111 ++*I " ++J 24 0 0112 ++K 24 0 0113 ++*K " ++L 24 0 0114 ++M 24 0 0115 ++*M " ++N 24 0 0116 ++*N " ++O 24 0 0117 ++ci " ++*O " ++P 24 0 0120 ++*R " ++Q 24 0 0121 ++R 24 0 0122 ++S 24 0 0123 ++T 24 0 0124 ++*T " ++U 24 0 0125 ++V 24 0 0126 ++W 24 0 0127 ++X 24 0 0130 ++*X " ++Y 24 0 0131 ++*U " ++Z 24 0 0132 ++*Z " ++[ 24 0 0133 ++lB " ++\ 24 0 0134 ++rs " ++] 24 0 0135 ++rB " ++a^ 24 0 0136 ++^ " ++ha " ++_ 24 0 0137 ++ru " ++ul " ++` 24 0 0140 ++oq " ++ga " ++a 24 0 0141 ++b 24 0 0142 ++c 24 0 0143 ++d 24 0 0144 ++e 24 0 0145 ++f 24 0 0146 ++g 24 0 0147 ++h 24 0 0150 ++i 24 0 0151 ++.i " ++j 24 0 0152 ++k 24 0 0153 ++l 24 0 0154 ++m 24 0 0155 ++n 24 0 0156 ++o 24 0 0157 ++*o " ++p 24 0 0160 ++q 24 0 0161 ++r 24 0 0162 ++s 24 0 0163 ++t 24 0 0164 ++u 24 0 0165 ++v 24 0 0166 ++w 24 0 0167 ++x 24 0 0170 ++mu " ++y 24 0 0171 ++z 24 0 0172 ++lC 24 0 0173 ++{ " ++ba 24 0 0174 ++or " ++bv " ++br " ++| " ++lb " ++lc " ++lf " ++lk " ++lt " ++rb " ++rc " ++rf " ++rk " ++rt " ++rC 24 0 0175 ++} " ++a~ 24 0 0176 ++~ " ++ap " ++ti " +diff -Naur groff-1.18.1.4.orig/font/devps/DESC.in groff-1.18.1.4/font/devps/DESC.in +--- groff-1.18.1.4.orig/font/devps/DESC.in 2000-02-06 09:35:57.000000000 +0000 ++++ groff-1.18.1.4/font/devps/DESC.in 2006-10-18 18:54:44.000000000 +0000 +@@ -1,11 +1,33 @@ + res 72000 + hor 1 + vert 1 ++lowerwchar 300 ++wcharkern 400 + sizescale 1000 + unitwidth 1000 + sizes 1000-10000000 0 + styles R I B BI + family T +-fonts 9 0 0 0 0 0 SS S ZD ZDR ++fonts 11 0 0 0 0 0 SS S ZD ZDR M G ++fontset B G 2E00..9FFF ++fontset AB G 2E00..9FFF ++fontset BMB G 2E00..9FFF ++fontset CB G 2E00..9FFF ++fontset HB G 2E00..9FFF ++fontset HNB G 2E00..9FFF ++fontset NB G 2E00..9FFF ++fontset PB G 2E00..9FFF ++fontset TB G 2E00..9FFF ++fontset - M 2E00..9FFF ++fontset B G FF00..FFEF ++fontset AB G FF00..FFEF ++fontset BMB G FF00..FFEF ++fontset CB G FF00..FFEF ++fontset HB G FF00..FFEF ++fontset HNB G FF00..FFEF ++fontset NB G FF00..FFEF ++fontset PB G FF00..FFEF ++fontset TB G FF00..FFEF ++fontset - M FF00..FFEF + tcommand + postpro grops +diff -Naur groff-1.18.1.4.orig/font/devps/M.proto groff-1.18.1.4/font/devps/M.proto +--- groff-1.18.1.4.orig/font/devps/M.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devps/M.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,9 @@ ++name M ++internalname Ryumin-Light-EUC-H ++spacewidth 250 ++encodingname EUC-JP ++charset ++u2E00..u9FFF 1000 3 ++uFF00..uFF5F 1000 3 ++uFF60..uFF9F 500 3 ++uFFA0..uFFEF 1000 3 +diff -Naur groff-1.18.1.4.orig/font/devps/Makefile.sub groff-1.18.1.4/font/devps/Makefile.sub +--- groff-1.18.1.4.orig/font/devps/Makefile.sub 2002-06-04 13:03:19.000000000 +0000 ++++ groff-1.18.1.4/font/devps/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -2,23 +2,23 @@ + DISTFILES=text.enc download \ + S ZD ZDR SS AB ABI AI AR BMB BMBI BMI BMR \ + CB CBI CI CR HB HBI HI HR HNB HNBI HNI HNR \ +- NB NBI NI NR PB PBI PI PR TB TBI TI TR ZCMI ++ NB NBI NI NR PB PBI PI PR TB TBI TI TR ZCMI M G + PSFILES=prologue symbolsl.pfa zapfdr.pfa + DEVGENFILES=generate/Makefile generate/afmname generate/dingbats.map \ + generate/dingbats.rmap generate/lgreekmap generate/symbol.sed \ + generate/symbolchars generate/symbolsl.afm generate/textmap + DEVFILES=DESC $(PSFILES) $(DISTFILES) $(DEVGENFILES) + +-CLEANADD=DESC $(PSFILES) ++CLEANADD=DESC $(PSFILES) M G + + DESC: DESC.in + -rm -f DESC + cat $(srcdir)/DESC.in >DESC + echo broken $(BROKEN_SPOOLER_FLAGS) >>DESC + if test "$(PAGE)" = A4; then \ +- echo "papersize a4" >>DESC; \ ++ echo "papersize /etc/papersize a4" >>DESC; \ + else \ +- echo "papersize letter" >>DESC; \ ++ echo "papersize /etc/papersize letter" >>DESC; \ + fi + test -z '$(PSPRINT)' || echo print '$(PSPRINT)' >>DESC + +@@ -33,3 +33,14 @@ + $(PSFILES): + -rm -f $@ + sed -f $(srcdir)/psstrip.sed $? >$@ ++ ++M: M.proto ++ @echo Making M ++ @-rm -f M ++ @cp M.proto M ++ ++G: M ++ @echo Making G ++ @-rm -f G ++ @sed -e 's/name M/name G/' \ ++ -e 's/internalname Ryumin-Light-EUC-H/internalname GothicBBB-Medium-EUC-H/' M > G +diff -Naur groff-1.18.1.4.orig/font/devutf8/DESC.proto groff-1.18.1.4/font/devutf8/DESC.proto +--- groff-1.18.1.4.orig/font/devutf8/DESC.proto 2000-02-06 09:36:22.000000000 +0000 ++++ groff-1.18.1.4/font/devutf8/DESC.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -3,6 +3,10 @@ + vert 40 + unitwidth 10 + sizes 10 0 +-fonts 4 R I B BI ++fonts 6 R I B BI M G ++fontset B G 2E00..9FFF ++fontset B G FF00..FFEF ++fontset - M 2E00..9FFF ++fontset - M FF00..FFEF + tcommand + postpro grotty +diff -Naur groff-1.18.1.4.orig/font/devutf8/M.proto groff-1.18.1.4/font/devutf8/M.proto +--- groff-1.18.1.4.orig/font/devutf8/M.proto 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/font/devutf8/M.proto 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,6 @@ ++name M ++internalname 4 ++spacewidth 48 ++charset ++u2E00..u9FFF 48 0 ++uFF00..uFFEF 48 0 +diff -Naur groff-1.18.1.4.orig/font/devutf8/Makefile.sub groff-1.18.1.4/font/devutf8/Makefile.sub +--- groff-1.18.1.4.orig/font/devutf8/Makefile.sub 2000-02-06 09:36:22.000000000 +0000 ++++ groff-1.18.1.4/font/devutf8/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -1,7 +1,8 @@ + DEV=utf8 + FONTS=R I B BI +-DEVFILES=$(FONTS) DESC +-CLEANADD=$(FONTS) DESC ++WFONTS=M G ++DEVFILES=$(FONTS) $(WFONTS) DESC ++CLEANADD=$(FONTS) $(WFONTS) DESC + + RES=240 + CPI=10 +@@ -12,8 +13,8 @@ + @-rm -f $@ + @(charwidth=`expr $(RES) / $(CPI)` ; \ + sed -e "s/^name [A-Z]*$$/name $@/" \ +- -e "s/^\([^ ]*\) [0-9]+ /\1 $$charwidth /" \ +- -e "s/^spacewidth [0-9]+$$/spacewidth $$charwidth/" \ ++ -e "s/^\([^ ]*\) [0-9][0-9]* /\1 $$charwidth /" \ ++ -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ + -e "s/^internalname .*$$/internalname $@/" \ + -e "/^internalname/s/BI/3/" \ + -e "/^internalname/s/B/2/" \ +@@ -21,12 +22,27 @@ + -e "/^internalname .*[^ 0-9]/d" \ + $(srcdir)/R.proto >$@) + ++M: M.proto ++ @echo Making M ++ @-rm -f M ++ (wcharwidth=`expr $(RES) / $(CPI) * 2` ; \ ++ spacewidth=`expr $(RES) / $(CPI)` ; \ ++ sed -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$spacewidth/" \ ++ -e "s/^u\([0-9A-F]*\)..u\([0-9A-F]*\) [0-9][0-9]*/u\1..u\2 $$wcharwidth/" \ ++ $(srcdir)/M.proto > $@) ++ ++G: M ++ @echo Making G ++ @-rm -f G ++ @sed -e 's/name M/name G/' \ ++ -e 's/internalname 4/internalname 5/' M > G ++ + DESC: DESC.proto + @echo Making $@ + @-rm -f $@ + @sed -e "s/^res .*$$/res $(RES)/" \ + -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \ + -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \ +- -e "s/^fonts .*$$/fonts `set $(FONTS); echo $$#` $(FONTS)/" \ ++ -e "s/^fonts .*$$/fonts `set $(FONTS) $(WFONTS); echo $$#` $(FONTS) $(WFONTS)/" \ + $(srcdir)/DESC.proto >$@ + +diff -Naur groff-1.18.1.4.orig/man/ditroff.man groff-1.18.1.4/man/ditroff.man +--- groff-1.18.1.4.orig/man/ditroff.man 2002-02-19 16:28:30.000000000 +0000 ++++ groff-1.18.1.4/man/ditroff.man 2006-10-18 18:54:44.000000000 +0000 +@@ -18,6 +18,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff/copyright. ++.. + . + ." -------------------------------------------------------------------- + ." Setup +diff -Naur groff-1.18.1.4.orig/man/groff.man groff-1.18.1.4/man/groff.man +--- groff-1.18.1.4.orig/man/groff.man 2002-06-29 20:46:03.000000000 +0000 ++++ groff-1.18.1.4/man/groff.man 2006-10-18 18:54:44.000000000 +0000 +@@ -19,6 +19,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff/copyright. ++.. + . + ." -------------------------------------------------------------------- + ." Setup +diff -Naur groff-1.18.1.4.orig/man/groff_char.man groff-1.18.1.4/man/groff_char.man +--- groff-1.18.1.4.orig/man/groff_char.man 2002-07-20 03:54:14.000000000 +0000 ++++ groff-1.18.1.4/man/groff_char.man 2006-10-18 18:54:44.000000000 +0000 +@@ -32,6 +32,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff/copyright. ++.. + . + ." -------------------------------------------------------------------- + ." Setup Part 1 +diff -Naur groff-1.18.1.4.orig/man/groff_diff.man groff-1.18.1.4/man/groff_diff.man +--- groff-1.18.1.4.orig/man/groff_diff.man 2002-07-05 15:04:22.000000000 +0000 ++++ groff-1.18.1.4/man/groff_diff.man 2006-10-18 18:54:44.000000000 +0000 +@@ -23,6 +23,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff/copyright. ++.. + . + ." -------------------------------------------------------------------- + ." Setup +diff -Naur groff-1.18.1.4.orig/man/groff_out.man groff-1.18.1.4/man/groff_out.man +--- groff-1.18.1.4.orig/man/groff_out.man 2002-09-12 10:00:17.000000000 +0000 ++++ groff-1.18.1.4/man/groff_out.man 2006-10-18 18:54:44.000000000 +0000 +@@ -19,6 +19,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff/copyright. ++.. + . + ." -------------------------------------------------------------------- + ." Setup +diff -Naur groff-1.18.1.4.orig/man/groff_tmac.man groff-1.18.1.4/man/groff_tmac.man +--- groff-1.18.1.4.orig/man/groff_tmac.man 2002-08-21 07:37:10.000000000 +0000 ++++ groff-1.18.1.4/man/groff_tmac.man 2006-10-18 18:54:44.000000000 +0000 +@@ -32,6 +32,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff/copyright. ++.. + . + ." -------------------------------------------------------------------- + ." Setup +diff -Naur groff-1.18.1.4.orig/man/roff.man groff-1.18.1.4/man/roff.man +--- groff-1.18.1.4.orig/man/roff.man 2002-04-23 04:28:59.000000000 +0000 ++++ groff-1.18.1.4/man/roff.man 2006-10-18 18:54:44.000000000 +0000 +@@ -18,6 +18,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff/copyright. ++.. + . + ." -------------------------------------------------------------------- + ." Setup +diff -Naur groff-1.18.1.4.orig/mdate.sh groff-1.18.1.4/mdate.sh +--- groff-1.18.1.4.orig/mdate.sh 2001-03-09 15:26:30.000000000 +0000 ++++ groff-1.18.1.4/mdate.sh 2006-10-18 18:54:44.000000000 +0000 +@@ -2,41 +2,4 @@ + + # Print the modification date of $1 `nicely'. + +-# Don't want foreign dates. +- +-LANGUAGE= +-LC_ALL=C; export LC_ALL +- +- +-(date; +-if ls -L /dev/null 1>/dev/null 2>&1; then ls -L -l $1; else ls -l $1; fi +-) | awk ' +-BEGIN { +- full["Jan"] = "January"; number["Jan"] = 1; +- full["Feb"] = "February"; number["Feb"] = 2; +- full["Mar"] = "March"; number["Mar"] = 3; +- full["Apr"] = "April"; number["Apr"] = 4; +- full["May"] = "May"; number["May"] = 5; +- full["Jun"] = "June"; number["Jun"] = 6; +- full["Jul"] = "July"; number["Jul"] = 7; +- full["Aug"] = "August"; number["Aug"] = 8; +- full["Sep"] = "September"; number["Sep"] = 9; +- full["Oct"] = "October"; number["Oct"] = 10; +- full["Nov"] = "November"; number["Nov"] = 11; +- full["Dec"] = "December"; number["Dec"] = 12; +-} +- +-NR == 1 { +- month = $2; +- year = $NF; +-} +- +-NR == 2 { +- if ($(NF-1) ~ /:/) { +- if (number[$(NF-3)] > number[month]) +- year--; +- } +- else +- year = $(NF-1); +- print $(NF-2), full[$(NF-3)], year +-}' ++perl -MPOSIX -le 'print strftime("%d %B %Y", localtime((stat $ARGV[0])[9]))' $1 +diff -Naur groff-1.18.1.4.orig/src/devices/grodvi/dvi.cc groff-1.18.1.4/src/devices/grodvi/dvi.cc +--- groff-1.18.1.4.orig/src/devices/grodvi/dvi.cc 2002-03-01 01:15:36.000000000 +0000 ++++ groff-1.18.1.4/src/devices/grodvi/dvi.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -21,6 +21,7 @@ + + #include "driver.h" + #include "nonposix.h" ++#include "encoding.h" + + extern "C" const char *Version_string; + +@@ -104,6 +105,9 @@ + struct output_font { + dvi_font *f; + int point_size; ++#ifdef ENABLE_MULTIBYTE ++ const char *sf; // subfont name ++#endif + output_font() : f(0) { } + }; + +@@ -121,6 +125,9 @@ + output_font output_font_table[FONTS_MAX]; + font *cur_font; + int cur_point_size; ++#ifdef ENABLE_MULTIBYTE ++ const char *cur_subfont; ++#endif + color cur_color; + int pushed; + int pushed_h; +@@ -341,9 +348,18 @@ + if (*env->col != cur_color) + set_color(env->col); + int code = f->get_code(index); ++#ifdef ENABLE_MULTIBYTE ++ const char *sf = f->get_subfont_name(index); ++ if (env->size != cur_point_size || f != cur_font || ++ (sf != cur_subfont && strcmp(sf, cur_subfont))) { ++#else + if (env->size != cur_point_size || f != cur_font) { ++#endif + cur_font = f; + cur_point_size = env->size; ++#ifdef ENABLE_MULTIBYTE ++ cur_subfont = sf; ++#endif + int i; + for (i = 0;; i++) { + if (i >= FONTS_MAX) { +@@ -352,9 +368,16 @@ + if (output_font_table[i].f == 0) { + output_font_table[i].f = (dvi_font *)cur_font; + output_font_table[i].point_size = cur_point_size; ++#ifdef ENABLE_MULTIBYTE ++ output_font_table[i].sf = cur_subfont; ++#endif + define_font(i); + } + if (output_font_table[i].f == cur_font ++#ifdef ENABLE_MULTIBYTE ++ && (output_font_table[i].sf == cur_subfont || ++ strcmp(output_font_table[i].sf, cur_subfont) == 0) ++#endif + && output_font_table[i].point_size == cur_point_size) + break; + } +@@ -398,7 +421,13 @@ + out4(f->checksum); + out4(output_font_table[i].point_size*RES_7227); + out4(int((double(f->design_size)/(1<<20))*RES_7227*100 + .5)); ++#ifdef ENABLE_MULTIBYTE ++ const char *nm; ++ if (!(nm = output_font_table[i].sf)) ++ nm = f->get_internal_name(); ++#else + const char *nm = f->get_internal_name(); ++#endif + out1(0); + out_string(nm); + } +@@ -889,6 +918,7 @@ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); ++ init_encoding_handler(); + int c; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, +diff -Naur groff-1.18.1.4.orig/src/devices/grohtml/html.h groff-1.18.1.4/src/devices/grohtml/html.h +--- groff-1.18.1.4.orig/src/devices/grohtml/html.h 2002-02-17 17:05:53.000000000 +0000 ++++ groff-1.18.1.4/src/devices/grohtml/html.h 2006-10-18 18:54:44.000000000 +0000 +@@ -49,6 +49,9 @@ + class simple_output { + public: + simple_output(FILE *, int max_line_length); ++#ifdef ENABLE_MULTIBYTE ++ simple_output &put_string(const wchar *, int); ++#endif + simple_output &put_string(const char *, int); + simple_output &put_string(const char *s); + simple_output &put_string(const string &s); +diff -Naur groff-1.18.1.4.orig/src/devices/grohtml/post-html.cc groff-1.18.1.4/src/devices/grohtml/post-html.cc +--- groff-1.18.1.4.orig/src/devices/grohtml/post-html.cc 2006-10-14 12:32:59.000000000 +0000 ++++ groff-1.18.1.4/src/devices/grohtml/post-html.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -29,6 +29,7 @@ + #include "html.h" + #include "html-text.h" + #include "html-table.h" ++#include "encoding.h" // XXX: ukai + + #include <time.h> + +@@ -280,6 +281,9 @@ + public: + char_buffer(); + ~char_buffer(); ++#ifdef ENABLE_MULTIBYTE ++ char *add_string(const wchar *, unsigned int); ++#endif + char *add_string(const char *, unsigned int); + char *add_string(const string &); + private: +@@ -301,6 +305,43 @@ + } + } + ++#ifdef ENABLE_MULTIBYTE ++char *char_buffer::add_string (const wchar *s, unsigned int length) ++{ ++ int i=0; ++ unsigned int old_used; ++ ++ if (tail == 0) { ++ tail = new char_block; ++ head = tail; ++ } else { ++ if (tail->used + length*2 + 1 > char_block::SIZE) { ++ tail->next = new char_block; ++ tail = tail->next; ++ } ++ } ++ // at this point we have a tail which is ready for the string. ++ if (tail->used + length*2 + 1 > char_block::SIZE) { ++ fatal("need to increase char_block::SIZE"); ++ } ++ ++ old_used = tail->used; ++ do { ++ length -= output_encoding->put_wchar(s[i], (unsigned char *)tail->buffer, &tail->used, length*2); ++ i++; ++ } while (length>0); ++ ++ // add terminating nul character ++ ++ tail->buffer[tail->used] = '\0'; ++ tail->used++; ++ ++ // and return start of new string ++ ++ return( &tail->buffer[old_used] ); ++} ++#endif ++ + char *char_buffer::add_string (const char *s, unsigned int length) + { + int i=0; +@@ -320,6 +361,7 @@ + } + + old_used = tail->used; ++ /* XXX: encoding - ukai */ + do { + tail->buffer[tail->used] = s[i]; + tail->used++; +@@ -1917,6 +1959,15 @@ + + current_paragraph->do_para(&html, "", indentation, pageoffset, linelength); + } ++#if 0 // def ENABLE_MULTIBYTE /* XXX */ ++ else if (strcmp(fontname, "M") == 0) { ++ current_paragraph->done_bold(); ++ current_paragraph->done_italic(); ++ current_paragraph->done_tt(); ++ } else if (strcmp(fontname, "G") == 0) { ++ current_paragraph->do_bold(); ++ } ++#endif + } + + void html_printer::determine_header_level (int level) +@@ -2948,6 +2999,11 @@ + current_paragraph->done_italic(); + current_paragraph->done_tt(); + } ++#ifdef ENABLE_MULTIBYTE ++ else if (strcmp(fontname, "G") == 0) { ++ current_paragraph->done_bold(); ++ } ++#endif + } + + /* +@@ -2992,6 +3048,15 @@ + current_paragraph->do_italic(); + current_paragraph->do_bold(); + } ++#ifdef ENABLE_MULTIBYTE ++ else if (strcmp(fontname, "M") == 0) { ++ current_paragraph->done_bold(); ++ current_paragraph->done_italic(); ++ current_paragraph->done_tt(); ++ } else if (strcmp(fontname, "G") == 0) { ++ current_paragraph->do_bold(); ++ } ++#endif + } + + /* +@@ -3331,7 +3396,23 @@ + + last_sbuf_length = sbuf.length(); + if (html_glyph == NULL) ++#ifdef ENABLE_MULTIBYTE ++ { ++ if (is_wchar_code(code)) { ++ int mblen = output_encoding->max_wchar_len(); ++ unsigned char *wbuf = new unsigned char[mblen]; ++ int i = 0, j = 0; ++ output_encoding->put_wchar(code, wbuf, &j, mblen); ++ for (i = 0; i < j; i++) { ++ sbuf += wbuf[i]; ++ } ++ } ++ else ++ sbuf += ((char)code); ++ } ++#else + sbuf += ((char)code); ++#endif + else + sbuf += html_glyph; + } +@@ -3445,12 +3526,12 @@ + return; + + flush_sbuf(); ++ sbuf_style = sty; /* XXX? */ + add_to_sbuf(i, name); + sbuf_end_hpos = env->hpos + w; + sbuf_start_hpos = env->hpos; + sbuf_prev_hpos = env->hpos; + sbuf_vpos = env->vpos; +- sbuf_style = sty; + sbuf_kern = 0; + } + +@@ -3659,6 +3740,7 @@ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); ++ init_encoding_handler(); + int c; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, +diff -Naur groff-1.18.1.4.orig/src/devices/grops/ps.cc groff-1.18.1.4/src/devices/grops/ps.cc +--- groff-1.18.1.4.orig/src/devices/grops/ps.cc 2002-06-19 21:07:33.000000000 +0000 ++++ groff-1.18.1.4/src/devices/grops/ps.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -24,6 +24,7 @@ + #include "cset.h" + #include "nonposix.h" + #include "paper.h" ++#include "encoding.h" + + #include "ps.h" + #include <time.h> +@@ -193,12 +194,23 @@ + return *this; + } + ++#ifdef ENABLE_MULTIBYTE ++ps_output &ps_output::put_string(const wchar *s, int n) ++#else + ps_output &ps_output::put_string(const char *s, int n) ++#endif + { + int len = 0; + int i; + for (i = 0; i < n; i++) { ++#ifdef ENABLE_MULTIBYTE ++ wchar wc = s[i]; ++ char c = 0; ++ if (is_wchar_singlebyte(wc)) ++ c = wchar_singlebyte(wc); ++#else + char c = s[i]; ++#endif + if (is_ascii(c) && csprint(c)) { + if (c == '(' || c == ')' || c == '\') + len += 2; +@@ -224,8 +236,13 @@ + putc('\n', fp); + col = 0; + } ++#ifdef ENABLE_MULTIBYTE ++ int nb = output_encoding->put_wchar(s[i], fp, "%02x"); ++ col += nb * 2; ++#else + fprintf(fp, "%02x", s[i] & 0377); + col += 2; ++#endif + } + putc('>', fp); + col++; +@@ -396,6 +413,9 @@ + int encoding_index; + char *encoding; + char *reencoded_name; ++#ifdef ENABLE_MULTIBYTE ++ char *encodingname; ++#endif + ~ps_font(); + void handle_unknown_font_command(const char *command, const char *arg, + const char *filename, int lineno); +@@ -414,6 +434,9 @@ + + ps_font::ps_font(const char *nm) + : font(nm), encoding_index(-1), encoding(0), reencoded_name(0) ++#ifdef ENABLE_MULTIBYTE ++ , encodingname(0) ++#endif + { + } + +@@ -421,6 +444,9 @@ + { + a_delete encoding; + a_delete reencoded_name; ++#ifdef ENABLE_MULTIBYTE ++ a_delete encodingname; ++#endif + } + + void ps_font::handle_unknown_font_command(const char *command, const char *arg, +@@ -433,6 +459,15 @@ + else + encoding = strsave(arg); + } ++#ifdef ENABLE_MULTIBYTE ++ if (strcmp(command, "encodingname") == 0) { ++ if (arg == 0) ++ error_with_file_and_line(filename, lineno, ++ "`encodingname' command requires an argument"); ++ else ++ encodingname = strsave(arg); ++ } ++#endif + } + + static void handle_unknown_desc_command(const char *command, const char *arg, +@@ -487,7 +522,11 @@ + int paper_length; + int equalise_spaces; + enum { SBUF_SIZE = 256 }; ++#ifdef ENABLE_MULTIBYTE ++ wchar sbuf[SBUF_SIZE]; ++#else + char sbuf[SBUF_SIZE]; ++#endif + int sbuf_len; + int sbuf_start_hpos; + int sbuf_vpos; +@@ -606,7 +645,11 @@ + { + if (i == space_char_index || invis_count > 0) + return; ++#ifdef ENABLE_MULTIBYTE ++ wchar code = f->get_code(i); ++#else + unsigned char code = f->get_code(i); ++#endif + style sty(f, env->size, env->height, env->slant); + if (sty.slant != 0) { + if (sty.slant > 80 || sty.slant < -80) { +@@ -763,6 +806,14 @@ + if (sty == defined_styles[i]) { + sprintf(buf, "F%d", i); + out.put_symbol(buf); ++#ifdef ENABLE_MULTIBYTE ++ char *encodingname = ((ps_font *)sty.f)->encodingname; ++ if (encodingname != 0) { ++ select_output_encoding_handler(encodingname); ++ } else { ++ select_output_encoding_handler("LATIN1"); ++ } ++#endif + return; + } + if (ndefined_styles >= MAX_DEFINED_STYLES) +@@ -772,6 +823,14 @@ + const char *psname = sty.f->get_internal_name(); + if (psname == 0) + fatal("no internalname specified for font `%1'", sty.f->get_name()); ++#ifdef ENABLE_MULTIBYTE ++ char *encodingname = ((ps_font *)sty.f)->encodingname; ++ if (encodingname != 0) { ++ select_output_encoding_handler(encodingname); ++ } else { ++ select_output_encoding_handler("LATIN1"); ++ } ++#endif + char *encoding = ((ps_font *)sty.f)->encoding; + if (encoding != 0) { + char *s = ((ps_font *)sty.f)->reencoded_name; +@@ -1555,6 +1614,7 @@ + string env; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); ++ init_encoding_handler(); + int c; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, +diff -Naur groff-1.18.1.4.orig/src/devices/grops/ps.h groff-1.18.1.4/src/devices/grops/ps.h +--- groff-1.18.1.4.orig/src/devices/grops/ps.h 2002-01-24 22:37:32.000000000 +0000 ++++ groff-1.18.1.4/src/devices/grops/ps.h 2006-10-18 18:54:44.000000000 +0000 +@@ -18,10 +18,16 @@ + with groff; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + ++#include "encoding.h" // XXX ++ + class ps_output { + public: + ps_output(FILE *, int max_line_length); ++#ifdef ENABLE_MULTIBYTE ++ ps_output &put_string(const wchar *, int); ++#else + ps_output &put_string(const char *, int); ++#endif + ps_output &put_number(int); + ps_output &put_fix_number(int); + ps_output &put_float(double); +diff -Naur groff-1.18.1.4.orig/src/devices/grotty/grotty.man groff-1.18.1.4/src/devices/grotty/grotty.man +--- groff-1.18.1.4.orig/src/devices/grotty/grotty.man 2002-10-01 19:01:45.000000000 +0000 ++++ groff-1.18.1.4/src/devices/grotty/grotty.man 2006-10-18 18:54:44.000000000 +0000 +@@ -50,7 +50,9 @@ + command + with a + .BR -Tascii , +-.B -Tlatin1 ++.BR -Tascii8 , ++.BR -Tlatin1 , ++.B -Tnippon + or + .B -Tutf8 + option on ASCII based systems, and with +@@ -235,8 +237,10 @@ + .I name + is the name of the device, usually + .BR ascii , ++.BR ascii8 , + .BR latin1 , + .BR utf8 , ++.B nippon + or + .BR cp1047 . + .TP +@@ -315,10 +319,20 @@ + device. + . + .TP ++.B @FONTDIR@/devascii8/DESC ++Device description file for ++.B ascii8 ++device. ++.TP + .B @FONTDIR@/devlatin1/DESC + Device description file for + .B latin1 + device. ++.TP ++.B @FONTDIR@/devnippon/DESC ++Device description file for ++.B nippon ++device. + . + .TP + .BI @FONTDIR@/devlatin1/ F +diff -Naur groff-1.18.1.4.orig/src/devices/grotty/tty.cc groff-1.18.1.4/src/devices/grotty/tty.cc +--- groff-1.18.1.4.orig/src/devices/grotty/tty.cc 2002-06-19 21:31:15.000000000 +0000 ++++ groff-1.18.1.4/src/devices/grotty/tty.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -20,6 +20,7 @@ + + #include "driver.h" + #include "device.h" ++#include "encoding.h" + + extern "C" const char *Version_string; + +@@ -51,8 +52,18 @@ + HDRAW_MODE = 0x08, + CU_MODE = 0x10, + COLOR_CHANGE = 0x20 ++#ifdef ENABLE_MULTIBYTE ++ , WCHAR_MODE = 0x100 ++#endif + }; + ++#ifdef ENABLE_MULTIBYTE ++# ifdef putchar ++# undef putchar ++# endif ++#define putchar(wc) output_encoding->put_wchar((wc), stdout) ++#endif ++ + // Mode to use for bold-underlining. + static unsigned char bold_underline_mode = BOLD_MODE|UNDERLINE_MODE; + +@@ -89,6 +100,7 @@ + static tty_font *load_tty_font(const char *); + }; + ++ + tty_font *tty_font::load_tty_font(const char *s) + { + tty_font *f = new tty_font(s); +@@ -98,8 +110,26 @@ + } + const char *num = f->get_internal_name(); + long n; ++#ifdef ENABLE_MULTIBYTE ++ if (num != 0) { ++ n = strtol(num, 0, 0); ++ switch (n) { ++ case 1: ++ f->mode = int(UNDERLINE_MODE); ++ break; ++ case 2: ++ case 5: ++ f->mode = int(BOLD_MODE); ++ break; ++ case 3: ++ f->mode = int(BOLD_MODE|UNDERLINE_MODE); ++ break; ++ } ++ } ++#else + if (num != 0 && (n = strtol(num, 0, 0)) != 0) + f->mode = int(n & (BOLD_MODE|UNDERLINE_MODE)); ++#endif + if (!underline_flag) + f->mode &= ~UNDERLINE_MODE; + if (!bold_flag) +@@ -135,6 +165,9 @@ + short hpos; + unsigned int code; + unsigned char mode; ++#ifdef ENABLE_MULTIBYTE ++ short cols; ++#endif + unsigned char back_color_idx; + unsigned char fore_color_idx; + void *operator new(size_t); +@@ -184,7 +217,7 @@ + void make_underline(); + void make_bold(unsigned int); + unsigned char color_to_idx(color *col); +- void add_char(unsigned int, int, int, color *, color *, unsigned char); ++ void add_char(unsigned int, int, int, color *, color *, font *, unsigned char); + public: + tty_printer(const char *device); + ~tty_printer(); +@@ -193,7 +226,7 @@ + void special(char *arg, const environment *env, char type); + void change_color(const environment *env); + void change_fill_color(const environment *env); +- void put_char(unsigned int); ++ int put_char(unsigned int); + void put_color(unsigned char, int); + void begin_page(int) { } + void end_page(int page_length); +@@ -203,6 +236,10 @@ + tty_printer::tty_printer(const char *device) : cached_v(0) + { + is_utf8 = !strcmp(device, "utf8"); ++#ifdef ENABLE_MULTIBYTE ++ if (is_utf8) ++ select_output_encoding_handler("UTF-8"); ++#endif + tty_colors[0].set_rgb(0, // black + 0, + 0); +@@ -242,8 +279,18 @@ + void tty_printer::make_underline() + { + if (old_drawing_scheme) { ++#if 0 /* def ENABLE_MULTIBYTE XXX: not necessary? */ ++ if ((p->mode & WCHAR_MODE)) { ++ putchar('_'); putchar('_'); ++ putchar('\b'); putchar('\b'); ++ } else { ++ putchar('_'); ++ putchar('\b'); ++ } ++#else + putchar('_'); + putchar('\b'); ++#endif + } + else { + if (!is_underline) { +@@ -285,17 +332,25 @@ + void tty_printer::set_char(int i, font *f, const environment *env, + int w, const char *name) + { ++#ifdef ENABLE_MULTIBYTE ++ if (is_wchar_code(i)) { ++ add_char(wchar_code(i), env->hpos, env->vpos, env->col, env->fill, ++ f, ((tty_font *)f)->get_mode()); ++ return; ++ } ++#endif + if (w != font::hor) + fatal("width of character not equal to horizontal resolution"); + add_char(f->get_code(i), + env->hpos, env->vpos, + env->col, env->fill, +- ((tty_font *)f)->get_mode()); ++ f, ((tty_font *)f)->get_mode()); + } + + void tty_printer::add_char(unsigned int c, + int h, int v, + color *fore, color *back, ++ font *curfont, + unsigned char mode) + { + #if 0 +@@ -338,6 +393,16 @@ + g->code = c; + g->fore_color_idx = color_to_idx(fore); + g->back_color_idx = color_to_idx(back); ++#ifdef ENABLE_MULTIBYTE ++ if (is_wchar_code(c)) ++ mode |= WCHAR_MODE; ++ if (curfont && curfont->contains(c)) { ++ int gw0 = curfont->get_space_width(font::unitwidth); ++ int gw = curfont->get_width(c, font::unitwidth); ++ g->cols = gw/gw0; ++ } else ++ g->cols = 1; /* XXX */ ++#endif + g->mode = mode; + + // The list will be reversed later. After reversal, it must be in +@@ -357,7 +422,7 @@ + void tty_printer::special(char *arg, const environment *env, char type) + { + if (type == 'u') { +- add_char(*arg - '0', env->hpos, env->vpos, env->col, env->fill, CU_MODE); ++ add_char(*arg - '0', env->hpos, env->vpos, env->col, env->fill, get_font_from_index(env->fontno), CU_MODE); + return; + } + if (type != 'p') +@@ -395,12 +460,12 @@ + + void tty_printer::change_color(const environment *env) + { +- add_char(0, env->hpos, env->vpos, env->col, env->fill, COLOR_CHANGE); ++ add_char(0, env->hpos, env->vpos, env->col, env->fill, get_font_from_index(env->fontno), COLOR_CHANGE); + } + + void tty_printer::change_fill_color(const environment *env) + { +- add_char(0, env->hpos, env->vpos, env->col, env->fill, COLOR_CHANGE); ++ add_char(0, env->hpos, env->vpos, env->col, env->fill, get_font_from_index(env->fontno), COLOR_CHANGE); + } + + void tty_printer::draw(int code, int *p, int np, const environment *env) +@@ -420,7 +485,7 @@ + len = -len; + } + while (len >= 0) { +- add_char('|', env->hpos, v, env->col, env->fill, VDRAW_MODE); ++ add_char('|', env->hpos, v, env->col, env->fill, get_font_from_index(env->fontno), VDRAW_MODE); + len -= font::vert; + v += font::vert; + } +@@ -434,18 +499,24 @@ + len = -len; + } + while (len >= 0) { +- add_char('-', h, env->vpos, env->col, env->fill, HDRAW_MODE); ++ add_char('-', h, env->vpos, env->col, env->fill, get_font_from_index(env->fontno), HDRAW_MODE); + len -= font::hor; + h += font::hor; + } + } + } + +-void tty_printer::put_char(unsigned int wc) ++int tty_printer::put_char(unsigned int wc) + { ++#ifdef ENABLE_MULTIBYTE ++ if (wc >= 0x80) { ++ return output_encoding->put_wchar(make_wchar(wc), stdout); ++ } ++#else + if (is_utf8 && wc >= 0x80) { + char buf[6 + 1]; + int count; ++ int len; + char *p = buf; + if (wc < 0x800) + count = 1, *p = (unsigned char)((wc >> 6) | 0xc0); +@@ -458,14 +529,18 @@ + else if (wc <= 0x7fffffff) + count = 5, *p = (unsigned char)((wc >> 30) | 0xfC); + else +- return; ++ return 0; ++ len = count; + do *++p = (unsigned char)(((wc >> (6 * --count)) & 0x3f) | 0x80); + while (count > 0); + *++p = '\0'; + putstring(buf); ++ return len; + } ++#endif + else + putchar(wc); ++ return 1; + } + + void tty_printer::put_color(unsigned char color_index, int back) +@@ -629,7 +704,11 @@ + } + } + put_char(p->code); ++#ifdef ENABLE_MULTIBYTE ++ hpos += p->cols; ++#else + hpos++; ++#endif + } + if (!old_drawing_scheme + && (is_bold || is_underline +@@ -667,6 +746,7 @@ + if (getenv("GROFF_NO_SGR")) + old_drawing_scheme = 1; + setbuf(stderr, stderr_buf); ++ init_encoding_handler(); + int c; + static const struct option long_options[] = { + { "help", no_argument, 0, CHAR_MAX + 1 }, +diff -Naur groff-1.18.1.4.orig/src/include/config.h groff-1.18.1.4/src/include/config.h +--- groff-1.18.1.4.orig/src/include/config.h 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/src/include/config.h 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,187 @@ ++/* src/include/config.h. Generated by configure. */ ++/* src/include/config.hin. Generated from configure.ac by autoheader. */ ++ ++/* Define if your C++ doesn't understand `delete []'. */ ++/* #undef ARRAY_DELETE_NEEDS_SIZE */ ++ ++/* Define if you want to use multibyte extension. */ ++#define ENABLE_MULTIBYTE 1 ++ ++/* Define if you have a C++ <limits.h>. */ ++#define HAVE_CC_LIMITS_H 1 ++ ++/* Define if you have a C++ <osfcn.h>. */ ++/* #undef HAVE_CC_OSFCN_H */ ++ ++/* Define to 1 if you have the <dirent.h> header file. */ ++#define HAVE_DIRENT_H 1 ++ ++/* Define to 1 if you have the `fmod' function. */ ++#define HAVE_FMOD 1 ++ ++/* Define to 1 if you have the `getcwd' function. */ ++#define HAVE_GETCWD 1 ++ ++/* Define to 1 if you have the `getpagesize' function. */ ++#define HAVE_GETPAGESIZE 1 ++ ++/* Define to 1 if you have the `gettimeofday' function. */ ++#define HAVE_GETTIMEOFDAY 1 ++ ++/* Define to 1 if you have the <inttypes.h> header file. */ ++#define HAVE_INTTYPES_H 1 ++ ++/* Define to 1 if you have the `isatty' function. */ ++#define HAVE_ISATTY 1 ++ ++/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */ ++#define HAVE_LANGINFO_CODESET 1 ++ ++/* Define to 1 if you have the <limits.h> header file. */ ++#define HAVE_LIMITS_H 1 ++ ++/* Define to 1 if you have the <math.h> header file. */ ++#define HAVE_MATH_H 1 ++ ++/* Define to 1 if you have the <memory.h> header file. */ ++#define HAVE_MEMORY_H 1 ++ ++/* Define if you have mkstemp(). */ ++#define HAVE_MKSTEMP 1 ++ ++/* Define to 1 if you have a working `mmap' system call. */ ++#define HAVE_MMAP 1 ++ ++/* Define to 1 if you have the `putenv' function. */ ++#define HAVE_PUTENV 1 ++ ++/* Define to 1 if you have the `rename' function. */ ++#define HAVE_RENAME 1 ++ ++/* Define to 1 if you have the `snprintf' function. */ ++#define HAVE_SNPRINTF 1 ++ ++/* Define to 1 if you have the <stdint.h> header file. */ ++#define HAVE_STDINT_H 1 ++ ++/* Define to 1 if you have the <stdlib.h> header file. */ ++#define HAVE_STDLIB_H 1 ++ ++/* Define to 1 if you have the `strcasecmp' function. */ ++#define HAVE_STRCASECMP 1 ++ ++/* Define to 1 if you have the `strerror' function. */ ++#define HAVE_STRERROR 1 ++ ++/* Define to 1 if you have the <strings.h> header file. */ ++#define HAVE_STRINGS_H 1 ++ ++/* Define to 1 if you have the <string.h> header file. */ ++#define HAVE_STRING_H 1 ++ ++/* Define to 1 if you have the `strncasecmp' function. */ ++#define HAVE_STRNCASECMP 1 ++ ++/* Define to 1 if you have the `strsep' function. */ ++#define HAVE_STRSEP 1 ++ ++/* Define to 1 if you have the `strtol' function. */ ++#define HAVE_STRTOL 1 ++ ++/* Define if <math.h> defines struct exception. */ ++#define HAVE_STRUCT_EXCEPTION 1 ++ ++/* Define to 1 if you have the <sys/dir.h> header file. */ ++#define HAVE_SYS_DIR_H 1 ++ ++/* Define if you have sys_errlist in <errno.h> or in <stdio.h>. */ ++#define HAVE_SYS_ERRLIST 1 ++ ++/* Define if you have sysnerr in <errno.h> or <stdio.h>. */ ++#define HAVE_SYS_NERR 1 ++ ++/* Define to 1 if you have the <sys/stat.h> header file. */ ++#define HAVE_SYS_STAT_H 1 ++ ++/* Define to 1 if you have the <sys/time.h> header file. */ ++#define HAVE_SYS_TIME_H 1 ++ ++/* Define to 1 if you have the <sys/types.h> header file. */ ++#define HAVE_SYS_TYPES_H 1 ++ ++/* Define to 1 if you have the <unistd.h> header file. */ ++#define HAVE_UNISTD_H 1 ++ ++/* Define if the host's encoding is EBCDIC. */ ++/* #undef IS_EBCDIC_HOST */ ++ ++/* Define if localtime() takes a long * not a time_t *. */ ++/* #undef LONG_FOR_TIME_T */ ++ ++/* Define if your C++ doesn't declare gettimeofday(). */ ++/* #undef NEED_DECLARATION_GETTIMEOFDAY */ ++ ++/* Define if your C++ doesn't declare hypot(). */ ++/* #undef NEED_DECLARATION_HYPOT */ ++ ++/* Define if your C++ doesn't declare pclose(). */ ++/* #undef NEED_DECLARATION_PCLOSE */ ++ ++/* Define if your C++ doesn't declare popen(). */ ++/* #undef NEED_DECLARATION_POPEN */ ++ ++/* Define if your C++ doesn't declare putenv(). */ ++/* #undef NEED_DECLARATION_PUTENV */ ++ ++/* Define if your C++ doesn't declare strcasecmp(). */ ++/* #undef NEED_DECLARATION_STRCASECMP */ ++ ++/* Define if your C++ doesn't declare strncasecmp(). */ ++/* #undef NEED_DECLARATION_STRNCASECMP */ ++ ++/* Define to the address where bug reports for this package should be sent. */ ++#define PACKAGE_BUGREPORT "" ++ ++/* Define to the full name of this package. */ ++#define PACKAGE_NAME "" ++ ++/* Define to the full name and version of this package. */ ++#define PACKAGE_STRING "" ++ ++/* Define to the one symbol short name of this package. */ ++#define PACKAGE_TARNAME "" ++ ++/* Define to the version of this package. */ ++#define PACKAGE_VERSION "" ++ ++/* Define if the printer's page size is A4. */ ++#define PAGEA4 1 ++ ++/* Define as the return type of signal handlers (`int' or `void'). */ ++#define RETSIGTYPE void ++ ++/* Define if srand() returns void not int. */ ++#define RET_TYPE_SRAND_IS_VOID 1 ++ ++/* Define to 1 if you have the ANSI C header files. */ ++#define STDC_HEADERS 1 ++ ++/* Define to 1 if `sys_siglist' is declared by <signal.h> or <unistd.h>. */ ++#define SYS_SIGLIST_DECLARED 1 ++ ++/* Define if your C++ compiler uses a traditional (Reiser) preprocessor. */ ++/* #undef TRADITIONAL_CPP */ ++ ++/* Define if the 0200 bit of the status returned by wait() indicates whether a ++ core image was produced for a process that was terminated by a signal. */ ++/* #undef WCOREFLAG */ ++ ++/* Define if -D_POSIX_SOURCE is necessary. */ ++/* #undef _POSIX_SOURCE */ ++ ++/* Define if you have ISC 3.x or 4.x. */ ++/* #undef _SYSV3 */ ++ ++/* Define uintmax_t to `unsigned long' or `unsigned long long' if <inttypes.h> ++ does not exist. */ ++/* #undef uintmax_t */ +diff -Naur groff-1.18.1.4.orig/src/include/config.hin groff-1.18.1.4/src/include/config.hin +--- groff-1.18.1.4.orig/src/include/config.hin 2002-09-06 07:32:26.000000000 +0000 ++++ groff-1.18.1.4/src/include/config.hin 2006-10-18 18:54:44.000000000 +0000 +@@ -1,84 +1,96 @@ +-/* src/include/config.hin. Generated automatically from configure.ac by autoheader. */ ++/* src/include/config.hin. Generated from configure.ac by autoheader. */ + + /* Define if your C++ doesn't understand `delete []'. */ + #undef ARRAY_DELETE_NEEDS_SIZE + ++/* Define if you want to use multibyte extension. */ ++#undef ENABLE_MULTIBYTE ++ + /* Define if you have a C++ <limits.h>. */ + #undef HAVE_CC_LIMITS_H + + /* Define if you have a C++ <osfcn.h>. */ + #undef HAVE_CC_OSFCN_H + +-/* Define if you have the <dirent.h> header file. */ ++/* Define to 1 if you have the <dirent.h> header file. */ + #undef HAVE_DIRENT_H + +-/* Define if you have the `fmod' function. */ ++/* Define to 1 if you have the `fmod' function. */ + #undef HAVE_FMOD + +-/* Define if you have the `getcwd' function. */ ++/* Define to 1 if you have the `getcwd' function. */ + #undef HAVE_GETCWD + +-/* Define if you have the `getpagesize' function. */ ++/* Define to 1 if you have the `getpagesize' function. */ + #undef HAVE_GETPAGESIZE + +-/* Define if you have the `gettimeofday' function. */ ++/* Define to 1 if you have the `gettimeofday' function. */ + #undef HAVE_GETTIMEOFDAY + +-/* Define if you have the <limits.h> header file. */ ++/* Define to 1 if you have the <inttypes.h> header file. */ ++#undef HAVE_INTTYPES_H ++ ++/* Define to 1 if you have the `isatty' function. */ ++#undef HAVE_ISATTY ++ ++/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */ ++#undef HAVE_LANGINFO_CODESET ++ ++/* Define to 1 if you have the <limits.h> header file. */ + #undef HAVE_LIMITS_H + +-/* Define if you have the <math.h> header file. */ ++/* Define to 1 if you have the <math.h> header file. */ + #undef HAVE_MATH_H + ++/* Define to 1 if you have the <memory.h> header file. */ ++#undef HAVE_MEMORY_H ++ + /* Define if you have mkstemp(). */ + #undef HAVE_MKSTEMP + +-/* Define if you have a working `mmap' system call. */ ++/* Define to 1 if you have a working `mmap' system call. */ + #undef HAVE_MMAP + +-/* Define if you have the `putenv' function. */ ++/* Define to 1 if you have the `putenv' function. */ + #undef HAVE_PUTENV + +-/* Define if you have the `rename' function. */ ++/* Define to 1 if you have the `rename' function. */ + #undef HAVE_RENAME + +-/* Define if you have the `snprintf' function. */ ++/* Define to 1 if you have the `snprintf' function. */ + #undef HAVE_SNPRINTF + +-/* Define if you have the `isatty' function. */ +-#undef HAVE_ISATTY +- +-/* Define if you have the <stdint.h> header file. */ ++/* Define to 1 if you have the <stdint.h> header file. */ + #undef HAVE_STDINT_H + +-/* Define if you have the <stdlib.h> header file. */ ++/* Define to 1 if you have the <stdlib.h> header file. */ + #undef HAVE_STDLIB_H + +-/* Define if you have the `strcasecmp' function. */ ++/* Define to 1 if you have the `strcasecmp' function. */ + #undef HAVE_STRCASECMP + +-/* Define if you have the `strerror' function. */ ++/* Define to 1 if you have the `strerror' function. */ + #undef HAVE_STRERROR + +-/* Define if you have the <strings.h> header file. */ ++/* Define to 1 if you have the <strings.h> header file. */ + #undef HAVE_STRINGS_H + +-/* Define if you have the <string.h> header file. */ ++/* Define to 1 if you have the <string.h> header file. */ + #undef HAVE_STRING_H + +-/* Define if you have the `strncasecmp' function. */ ++/* Define to 1 if you have the `strncasecmp' function. */ + #undef HAVE_STRNCASECMP + +-/* Define if you have the `strsep' function. */ ++/* Define to 1 if you have the `strsep' function. */ + #undef HAVE_STRSEP + +-/* Define if you have the `strtol' function. */ ++/* Define to 1 if you have the `strtol' function. */ + #undef HAVE_STRTOL + + /* Define if <math.h> defines struct exception. */ + #undef HAVE_STRUCT_EXCEPTION + +-/* Define if you have the <sys/dir.h> header file. */ ++/* Define to 1 if you have the <sys/dir.h> header file. */ + #undef HAVE_SYS_DIR_H + + /* Define if you have sys_errlist in <errno.h> or in <stdio.h>. */ +@@ -87,10 +99,16 @@ + /* Define if you have sysnerr in <errno.h> or <stdio.h>. */ + #undef HAVE_SYS_NERR + +-/* Define if you have the <sys/time.h> header file. */ ++/* Define to 1 if you have the <sys/stat.h> header file. */ ++#undef HAVE_SYS_STAT_H ++ ++/* Define to 1 if you have the <sys/time.h> header file. */ + #undef HAVE_SYS_TIME_H + +-/* Define if you have the <unistd.h> header file. */ ++/* Define to 1 if you have the <sys/types.h> header file. */ ++#undef HAVE_SYS_TYPES_H ++ ++/* Define to 1 if you have the <unistd.h> header file. */ + #undef HAVE_UNISTD_H + + /* Define if the host's encoding is EBCDIC. */ +@@ -120,6 +138,21 @@ + /* Define if your C++ doesn't declare strncasecmp(). */ + #undef NEED_DECLARATION_STRNCASECMP + ++/* Define to the address where bug reports for this package should be sent. */ ++#undef PACKAGE_BUGREPORT ++ ++/* Define to the full name of this package. */ ++#undef PACKAGE_NAME ++ ++/* Define to the full name and version of this package. */ ++#undef PACKAGE_STRING ++ ++/* Define to the one symbol short name of this package. */ ++#undef PACKAGE_TARNAME ++ ++/* Define to the version of this package. */ ++#undef PACKAGE_VERSION ++ + /* Define if the printer's page size is A4. */ + #undef PAGEA4 + +@@ -129,7 +162,10 @@ + /* Define if srand() returns void not int. */ + #undef RET_TYPE_SRAND_IS_VOID + +-/* Define if `sys_siglist' is declared by <signal.h> or <unistd.h>. */ ++/* Define to 1 if you have the ANSI C header files. */ ++#undef STDC_HEADERS ++ ++/* Define to 1 if `sys_siglist' is declared by <signal.h> or <unistd.h>. */ + #undef SYS_SIGLIST_DECLARED + + /* Define if your C++ compiler uses a traditional (Reiser) preprocessor. */ +diff -Naur groff-1.18.1.4.orig/src/include/device.h groff-1.18.1.4/src/include/device.h +--- groff-1.18.1.4.orig/src/include/device.h 2000-02-06 09:36:30.000000000 +0000 ++++ groff-1.18.1.4/src/include/device.h 2006-10-18 18:54:44.000000000 +0000 +@@ -18,4 +18,9 @@ + with groff; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + ++#ifndef _DEVICE_H ++#define _DEVICE_H ++ + extern const char *device; ++ ++#endif /* _DEVICE_H */ +diff -Naur groff-1.18.1.4.orig/src/include/driver.h groff-1.18.1.4/src/include/driver.h +--- groff-1.18.1.4.orig/src/include/driver.h 2002-02-17 17:05:53.000000000 +0000 ++++ groff-1.18.1.4/src/include/driver.h 2006-10-18 18:54:44.000000000 +0000 +@@ -27,6 +27,7 @@ + #include <errno.h> + #include <assert.h> + #include <math.h> ++#include "encoding.h" // XXX: ukai + #include "errarg.h" + #include "error.h" + #include "font.h" +diff -Naur groff-1.18.1.4.orig/src/include/encoding.h groff-1.18.1.4/src/include/encoding.h +--- groff-1.18.1.4.orig/src/include/encoding.h 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/src/include/encoding.h 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,175 @@ ++// -*- C++ -*- ++/* Copyright (c) 2001 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++This file is part of groff. ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation; either version 2, or (at your option) any later ++version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; if not, write to the Free Software ++Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ ++ ++#ifndef ENCODING_H ++#define ENCODING_H ++ ++#include <config.h> ++ ++#ifdef ENABLE_MULTIBYTE ++typedef int wchar; // negative is used for charcode & index ++#else ++typedef char wchar; ++#endif ++ ++#include <stdio.h> ++ ++#ifdef __cplusplus ++class encoding_istream { ++public: ++ encoding_istream() {}; ++ virtual ~encoding_istream() {}; ++ virtual int getbyte() = 0; ++ virtual int peekbyte() = 0; ++ virtual void ungetbyte(int ch) = 0; ++}; ++ ++class encoding_istream_str: public encoding_istream { ++private: ++ const unsigned char *s; ++ int *i; ++ encoding_istream_str() {}; ++public: ++ encoding_istream_str(const unsigned char *s0, int *i0) : s(s0), i(i0) {}; ++ ~encoding_istream_str() {}; ++ inline int getbyte() { return s[(*i)++]; }; ++ inline int peekbyte() { return s[(*i)]; }; ++ inline void ungetbyte(int ch) { --(*i); }; ++}; ++ ++class encoding_istream_fp: public encoding_istream { ++private: ++ FILE *fp; ++public: ++ encoding_istream_fp(FILE *fp0) : fp(fp0) {}; ++ ~encoding_istream_fp() {}; ++ inline int getbyte() { return fgetc(fp); }; ++ inline int peekbyte() { int ch = fgetc(fp); ungetc(ch, fp); return ch; }; ++ inline void ungetbyte(int ch) { ungetc(ch, fp); }; ++}; ++ ++class encoding_ostream { ++public: ++ encoding_ostream() {}; ++ virtual ~encoding_ostream() {}; ++ virtual void putbyte(unsigned char ch) = 0; ++}; ++ ++class encoding_ostream_str: public encoding_ostream { ++private: ++ unsigned char *s; ++ int *i; ++ int len; ++ encoding_ostream_str() {}; ++public: ++ encoding_ostream_str(unsigned char *s0, int *i0, int max) : s(s0), i(i0), len(max) {}; ++ ~encoding_ostream_str() {}; ++ inline void putbyte(unsigned char ch) { ++ if (*i < len) ++ s[(*i)++] = ch; ++ } ++}; ++ ++class encoding_ostream_fp: public encoding_ostream { ++private: ++ FILE *fp; ++ const char *format; ++public: ++ encoding_ostream_fp(FILE *ofp, const char *fmt = "%c") : fp(ofp), format(fmt) {}; ++ ~encoding_ostream_fp() {}; ++ inline void putbyte(unsigned char ch) { ++ fprintf(fp, format, ch); ++ } ++}; ++ ++class encoding_handler { ++public: ++ encoding_handler() {}; ++ virtual ~encoding_handler() {}; ++ ++ // name of this encoding_handler ++ virtual const char *name() { return ""; }; ++ ++ // check if this byte is byte in multibyte character in this encoding? ++ virtual int is_wchar_byte(unsigned char c) { return 0; }; ++ ++ // make new wchar from c0 (beginning of multibytes) and rest from `in' ++ virtual wchar make_wchar(unsigned char c0, encoding_istream& in) { ++ return wchar(c0); ++ } ++ // make new wchar from c0 (beginning of multibytes) and rest from `fp' ++ virtual wchar make_wchar(unsigned char c0, FILE *fp) { ++ encoding_istream_fp in(fp); ++ return make_wchar(c0, in); ++ } ++ // make new wchar from c0 (beginning of multibtyes) and rest from ++ // s[*i], *i will be changed to point the byte of next character. ++ virtual wchar make_wchar(unsigned char c0, const unsigned char *s, int *i) { ++ encoding_istream_str in(s, i); ++ return make_wchar(c0, in); ++ } ++ ++ // put wchar to outputstream ++ // returns number of bytes written ++ virtual int put_wchar(wchar wc, encoding_ostream& eos) { ++ eos.putbyte((unsigned char)wc); ++ return 1; ++ } ++ // put wchar to `fp' using `fmt' ++ // returns number of bytes written ++ virtual int put_wchar(wchar wc, FILE *fp, const char *fmt = "%c") { ++ encoding_ostream_fp out(fp, fmt); ++ return put_wchar(wc, out); ++ } ++ // put wchar to s[*i] (until maxlen) ++ // *i will be changed to point the byte of next character. ++ virtual int put_wchar(wchar wc, unsigned char *s, int *i, int maxlen) { ++ encoding_ostream_str out(s, i, maxlen); ++ return put_wchar(wc, out); ++ } ++ ++ // maximum number of bytes of multibyte character in this encoding ++ virtual int max_wchar_len() { return 1; }; ++ ++}; ++ ++encoding_handler* select_input_encoding_handler(const char* encoding_name); ++encoding_handler* select_output_encoding_handler(const char* encoding_name); ++extern encoding_handler* input_encoding; ++extern encoding_handler* output_encoding; ++void init_encoding_handler(); ++ ++// check if wc is wchar? ++int is_wchar_code(wchar wc); ++ ++// check if wc is wchar & can be represented in single byte? ++int is_wchar_singlebyte(wchar wc); ++ ++// get singlebyte representation of wchar (if is_wchar_singlebyte(wc)) ++unsigned char wchar_singlebyte(wchar wc); ++ ++// get actual wide character code ++int wchar_code(wchar wc); ++ ++// make wchar from wide character code ++int make_wchar(int w); ++ ++#endif ++ ++#endif /* ENCODING_H */ +diff -Naur groff-1.18.1.4.orig/src/include/font.h groff-1.18.1.4/src/include/font.h +--- groff-1.18.1.4.orig/src/include/font.h 2002-07-09 07:57:02.000000000 +0000 ++++ groff-1.18.1.4/src/include/font.h 2006-10-18 18:54:44.000000000 +0000 +@@ -18,11 +18,17 @@ + with groff; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + ++#include "encoding.h" ++ + typedef void (*FONT_COMMAND_HANDLER)(const char *, const char *, + const char *, int); + + struct font_kern_list; + struct font_char_metric; ++#ifdef ENABLE_MULTIBYTE ++struct fontset_list; ++struct font_wchar_metric; ++#endif + struct font_widths_cache; + + class font { +@@ -53,6 +59,9 @@ + const char *get_special_device_encoding(int index); + const char *get_name(); + const char *get_internal_name(); ++#ifdef ENABLE_MULTIBYTE ++ const char *get_subfont_name(int index); ++#endif + + static int scan_papersize(const char *, const char **, double *, double *); + +@@ -62,6 +71,9 @@ + static int load_desc(); + static int name_to_index(const char *); + static int number_to_index(int); ++#ifdef ENABLE_MULTIBYTE ++ static int wchar_index(wchar); ++#endif + static FONT_COMMAND_HANDLER + set_unknown_desc_command_handler(FONT_COMMAND_HANDLER); + +@@ -76,6 +88,11 @@ + static int spare2; + static int sizescale; + static int tcommand; ++#ifdef ENABLE_MULTIBYTE ++ // XXX: should be in charinfo or font_wchar_metric? ++ static int lowerwchar; ++ static int wcharkern; ++#endif + static int pass_filenames; + static int use_charnames_in_special; + +@@ -83,13 +100,27 @@ + static const char **style_table; + static const char *family; + static int *sizes; ++#ifdef ENABLE_MULTIBYTE ++ // fontsets - sub font list ++ static fontset_list *fontsets; ++ // get fontset for `wc' in current font `fname' ++ static int get_fontset_font(const char *fname, wchar wc); ++ // is the fontno's font load on demand? ++ static int is_on_demand(int fontno); ++#endif + private: + unsigned ligatures; + font_kern_list **kern_hash_table; + int space_width; +- short *ch_index; ++ short *ch_index; /* XXX: this is used unless font_wchar_metric. */ + int nindices; + font_char_metric *ch; ++#ifdef ENABLE_MULTIBYTE ++ // font metric for wchar ++ font_wchar_metric *wch; ++ // get font metric for wchar indexed by c ++ font_wchar_metric *get_font_wchar_metric(int c); ++#endif + int ch_used; + int ch_size; + int special; +diff -Naur groff-1.18.1.4.orig/src/include/lib.h groff-1.18.1.4/src/include/lib.h +--- groff-1.18.1.4.orig/src/include/lib.h 2002-03-08 07:33:49.000000000 +0000 ++++ groff-1.18.1.4/src/include/lib.h 2006-10-18 18:54:44.000000000 +0000 +@@ -88,8 +88,15 @@ + + extern char invalid_char_table[]; + ++#include "encoding.h" /* XXX: ukai */ ++ + inline int invalid_input_char(int c) + { ++#ifdef ENABLE_MULTIBYTE ++ if (input_encoding->is_wchar_byte(c)) ++ return 0; ++ else ++#endif + return c >= 0 && invalid_char_table[c]; + } + +diff -Naur groff-1.18.1.4.orig/src/include/printer.h groff-1.18.1.4/src/include/printer.h +--- groff-1.18.1.4.orig/src/include/printer.h 2002-04-14 10:22:57.000000000 +0000 ++++ groff-1.18.1.4/src/include/printer.h 2006-10-18 18:54:44.000000000 +0000 +@@ -38,6 +38,8 @@ + + #include "color.h" + ++#include "encoding.h" ++ + struct environment { + int fontno; + int size; +@@ -63,6 +65,9 @@ + printer(); + virtual ~printer(); + void load_font(int i, const char *name); ++#ifdef ENABLE_MULTIBYTE ++ void set_wchar_char(wchar c, char *s, int i0, int len, const environment *env, int *widthp = 0); ++#endif + void set_ascii_char(unsigned char c, const environment *env, + int *widthp = 0); + void set_special_char(const char *nm, const environment *env, +diff -Naur groff-1.18.1.4.orig/src/libs/libdriver/input.cc groff-1.18.1.4/src/libs/libdriver/input.cc +--- groff-1.18.1.4.orig/src/libs/libdriver/input.cc 2002-09-06 08:10:38.000000000 +0000 ++++ groff-1.18.1.4/src/libs/libdriver/input.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -250,6 +250,7 @@ + + #include "driver.h" + #include "device.h" ++#include "encoding.h" + + #include <stdlib.h> + #include <errno.h> +@@ -1439,6 +1440,19 @@ + char *subcmd_str = get_string_arg(); + char subcmd = subcmd_str[0]; + switch (subcmd) { ++#ifdef ENABLE_MULTIBYTE ++ case 'e': // x encoding: select encoding ++ { ++ char *str_arg = get_string_arg(); ++ if (str_arg == 0) ++ warning("empty argument for `x encoding' command"); ++ else { ++ select_input_encoding_handler(str_arg); ++ delete str_arg; ++ } ++ break; ++ } ++#endif + case 'f': // x font: mount font + { + IntArg n = get_integer_arg(); +@@ -1517,7 +1531,7 @@ + return stopped; + } + +- ++//////////////////////////////////////////////////////////////// + /********************************************************************** + exported part (by driver.h) + **********************************************************************/ +@@ -1625,6 +1639,18 @@ + if (str_arg[0] != 'i') + fatal("the third command must be `x init'"); + delete str_arg; ++#ifdef ENABLE_MULTIBYTE ++ Char c = get_char(); ++ while (is_space_or_tab(c) && c != Char('\n') && c != Char(EOF)) ++ c = get_char(); ++ unget_char(c); ++ if (c != Char('\n') && c != Char(EOF)) { ++ const char *tmp_encoding = get_string_arg(); ++ if (tmp_encoding && *tmp_encoding) ++ select_input_encoding_handler(tmp_encoding); ++ delete tmp_encoding; ++ } ++#endif + skip_line_x(); + } + +@@ -1763,6 +1789,18 @@ + size_t i = 0; + while ((c = str_arg[i++]) != '\0') { + EnvInt w; ++#ifdef ENABLE_MULTIBYTE ++ if (input_encoding->is_wchar_byte(c)) { ++ int i0 = i - 1; ++ wchar wc = input_encoding->make_wchar(c, (const unsigned char *)str_arg, (int *)&i); ++ if (is_wchar_code(wc)) { ++ /* XXX: singlebyte check? */ ++ pr->set_wchar_char(wc, str_arg, i0, i - i0, current_env, &w); ++ } else { ++ pr->set_ascii_char((unsigned char) c, current_env, &w); ++ } ++ } else ++#endif + pr->set_ascii_char((unsigned char) c, current_env, &w); + current_env->hpos += w; + } +diff -Naur groff-1.18.1.4.orig/src/libs/libdriver/printer.cc groff-1.18.1.4/src/libs/libdriver/printer.cc +--- groff-1.18.1.4.orig/src/libs/libdriver/printer.cc 2002-04-14 10:22:57.000000000 +0000 ++++ groff-1.18.1.4/src/libs/libdriver/printer.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -27,6 +27,7 @@ + */ + + #include "driver.h" ++#include "encoding.h" + + printer *pr = 0; + +@@ -138,6 +139,24 @@ + } + } + ++#ifdef ENABLE_MULTIBYTE ++void printer::set_wchar_char(wchar c, char *s, int i0, int len, const environment *env, int *widthp) ++{ ++ unsigned char *buf = new unsigned char[len+1]; ++ memset(buf, 0, len+1); ++ memcpy(buf, s+i0, len); ++ font *f; ++ int w; ++ int i = set_char_and_width((const char *)buf, env, &w, &f); ++ if (i != -1) { ++ set_char(c, f, env, w, (const char *)buf); ++ if (widthp) ++ *widthp = w; ++ } ++ delete [] buf; ++} ++#endif ++ + void printer::set_special_char(const char *nm, const environment *env, + int *widthp) + { +diff -Naur groff-1.18.1.4.orig/src/libs/libgroff/Makefile.sub groff-1.18.1.4/src/libs/libgroff/Makefile.sub +--- groff-1.18.1.4.orig/src/libs/libgroff/Makefile.sub 2002-08-23 07:04:40.000000000 +0000 ++++ groff-1.18.1.4/src/libs/libgroff/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -6,6 +6,7 @@ + color.$(OBJEXT) \ + cset.$(OBJEXT) \ + device.$(OBJEXT) \ ++ encoding.$(OBJEXT) \ + errarg.$(OBJEXT) \ + error.$(OBJEXT) \ + fatal.$(OBJEXT) \ +@@ -45,6 +46,7 @@ + $(srcdir)/color.cc \ + $(srcdir)/cset.cc \ + $(srcdir)/device.cc \ ++ $(srcdir)/encoding.cc \ + $(srcdir)/errarg.cc \ + $(srcdir)/error.cc \ + $(srcdir)/fatal.cc \ +diff -Naur groff-1.18.1.4.orig/src/libs/libgroff/encoding.cc groff-1.18.1.4/src/libs/libgroff/encoding.cc +--- groff-1.18.1.4.orig/src/libs/libgroff/encoding.cc 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/src/libs/libgroff/encoding.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,441 @@ ++// -*- C++ -*- ++/* Copyright (C) 2001 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++This file is part of groff. ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation; either version 2, or (at your option) any later ++version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; if not, write to the Free Software ++Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ ++ ++#include "encoding.h" ++#include "device.h" ++ ++#include <string.h> ++#ifdef ENABLE_MULTIBYTE ++#include <locale.h> ++#include <wchar.h> ++#ifdef HAVE_LANGINFO_CODESET ++#include <langinfo.h> ++#else ++#include <stdlib.h> ++#endif ++#endif ++ ++class ascii8_handler : public encoding_handler { ++ // encoding handler for 8bit ascii ++ // no multibyte support ++public: ++ ascii8_handler() {} ++ ~ascii8_handler() {} ++ ++ const char *name() { return "C"; }; /* ??? */ ++ ++ inline int is_wchar_byte(unsigned char c) { return 0; } ++ inline wchar make_wchar(unsigned char c0, encoding_istream& eis) { ++ return wchar(c0); ++ } ++ inline int put_wchar(wchar wc, encoding_ostream& eos) { ++ eos.putbyte((unsigned char)wchar_code(wc)); ++ return 1; ++ } ++ inline int max_wchar_len() { return 1; }; ++ ++}; ++ ++#ifdef ENABLE_MULTIBYTE ++class utf8_handler: public encoding_handler { ++public: ++ utf8_handler() { } ++ ~utf8_handler() { } ++ ++ const char *name() { return "UTF-8"; }; ++ ++ inline int is_wchar_byte(unsigned char c) { ++ return (c >= 0x80); ++ } ++ ++ /* ++ 0000 0000-0000 007F 0xxxxxxx ++ 0000 0080-0000 07FF 110xxxxx 10xxxxxx ++ 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx ++ ++ 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx ++ 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx ++ 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx ++ */ ++ ++ inline wchar make_wchar(unsigned char c0, encoding_istream& eis) { ++ wchar wc = 0; ++ int count = 0; ++ if (! is_wchar_byte(c0)) { ++ return c0; ++ } ++ if ((c0 & 0xFC) == 0xFC) { ++ wc = c0 & 0x01; ++ count = 5; ++ } else if ((c0 & 0xF8) == 0xF8) { ++ wc = c0 & 0x03; ++ count = 4; ++ } else if ((c0 & 0xF0) == 0xF0) { ++ wc = c0 & 0x07; ++ count = 3; ++ } else if ((c0 & 0xE0) == 0xE0) { ++ wc = c0 & 0x0F; ++ count = 2; ++ } else if ((c0 & 0xC0) == 0xC0) { ++ wc = c0 & 0x1F; ++ count = 1; ++ } ++ for (; count > 0; count--) { ++ wc <<= 6; ++ int c1 = eis.getbyte(); ++ if (! is_wchar_byte(c1)) { ++ /* illegal utf8 sequence? */ ++ } ++ wc |= (c1 & 0x3F); ++ } ++ return -wc; // XXX: negative ++ } ++ ++ inline int put_wchar(wchar wc, encoding_ostream& eos) { ++ int count = 0; ++ if (! is_wchar_code(wc)) { ++ eos.putbyte(wc); ++ return 1; ++ } ++ wc = -wc; // XXX: negative -> character code ++ ++ if (wc < 0x800) { ++ count = 1; eos.putbyte((wc >> 6) | 0xC0); ++ } else if (wc < 0x10000) { ++ count = 2; eos.putbyte((wc >> 12) | 0xE0); ++ } else if (wc < 0x200000) { ++ count = 3; eos.putbyte((wc >> 18) | 0xF0); ++ } else if (wc < 0x4000000) { ++ count = 4; eos.putbyte((wc >> 24) | 0xf8); ++ } else if (wc <= 0x7fffffff) { ++ count = 5; eos.putbyte((wc >> 30) | 0xFC); ++ } ++ for (int i = 0; i < count; i++) { ++ eos.putbyte(((wc >> 6 * (count - i - 1)) & 0x3f) | 0x80); ++ } ++ return count; ++ } ++ inline int max_wchar_len() { return 6; }; /* XXX 3?*/ ++ ++}; ++ ++#define USE_ICONV ++#ifdef USE_ICONV ++#include <iconv.h> ++#include <errno.h> ++ ++class iconv_handler : public encoding_handler { ++private: ++ iconv_t icd, ocd; ++ const char *encoding_name; ++ static iconv_handler *ih_header; ++ ++public: ++ iconv_handler *next; ++ ++ static iconv_handler *new_iconv_handler(const char *ename) { ++ iconv_handler *ip; ++ // if already created, use it. ++ for (ip = ih_header; ip != NULL; ip = ip->next) { ++ if (strcmp(ip->name(), ename) == 0) { ++ return ip; ++ } ++ } ++ // not found, create new one. ++ ip = new iconv_handler(ename); ++ ip->next = ih_header; ++ ih_header = ip; ++ return ip; ++ } ++ iconv_handler(const char *ename) : encoding_name(ename) { ++ // internal code is UCS-2BE ++ icd = iconv_open("UCS-2BE", encoding_name); ++ ocd = iconv_open(encoding_name, "UCS-2BE"); ++ }; ++ ~iconv_handler() {}; ++ ++ const char *name() { return encoding_name; }; ++ ++ inline int is_wchar_byte(unsigned char c) { ++ return (c >= 0x80); /* ??? */ ++ } ++ ++ inline wchar make_wchar(unsigned char c0, encoding_istream& eis) { ++ wchar wc = 0; ++ char inbuf[8], outbuf[8]; ++ char *inp, *outp; ++ size_t inbytesleft, outbytesleft; ++ int i = 0; ++ ++ if (! is_wchar_byte(c0)) { ++ return c0; ++ } ++ for (inbuf[i++] = c0; ;inbuf[i++] = eis.getbyte()) { ++ inbytesleft = i; ++ outbytesleft = sizeof(outbuf); ++ inp = inbuf; ++ outp = outbuf; ++ size_t r = iconv(icd, &inp, &inbytesleft, &outp, &outbytesleft); ++ if (r == (size_t)-1) { ++ if (errno == EILSEQ) { ++ /* illegal sequence? */ ++ return '?'; ++ } else if (errno == EINVAL) { ++ /* incomplete sequence? */ ++ continue; ++ } else if (errno == E2BIG) { ++ /* no room to output? */ ++ return '?'; ++ } ++ } ++ /* ok */ ++ /* UCS-2 is 2 bytes */ ++ wc = ((outbuf[0] & 0x0ff) << 8) | (outbuf[1] & 0x0ff); ++ return -wc; // XXX: negative ++ } ++ } ++ ++ ++ inline int put_wchar(wchar wc, encoding_ostream& eos) { ++ char inbuf[4], outbuf[4]; ++ char *inp, *outp; ++ size_t inbytesleft, outbytesleft; ++ ++ if (!is_wchar_code(wc)) { ++ eos.putbyte(wc & 0x0ff); ++ return 1; ++ } ++ wc = -wc; // XXX: negative -> character code ++ ++ inbuf[0] = (wc >> 8) & 0x0ff; ++ inbuf[1] = (wc >> 0) & 0x0ff; ++ inbuf[2] = 0; ++ inbytesleft = 2; ++ outbytesleft = 4; ++ inp = inbuf; ++ outp = outbuf; ++ size_t r = iconv(ocd, &inp, &inbytesleft, &outp, &outbytesleft); ++ if (r == (size_t)-1) { ++ if (errno == EILSEQ) { ++ /* illegal sequence? */; ++ } else if (errno == EINVAL) { ++ /* incomplete sequence? */; ++ } else if (errno == E2BIG) { ++ /* no room to output? */; ++ } ++ eos.putbyte('?'); ++ return 1; ++ } ++ char *op = outbuf; ++ int n = 0; ++ for (; op < outp; op++, n++) { ++ eos.putbyte(*op & 0x0ff); ++ } ++ return outp - outbuf; ++ } ++ inline int max_wchar_len() { return 6; }; /* XXX */ ++ ++}; ++#else ++class euc_handler : public encoding_handler { ++ static const int WCTABLE_OFFSET = 0xa1; ++ static const int WCTABLE_SIZE = 94; ++ static const int EUCMASK = 0x8080; ++ ++public: ++ euc_handler() {} ++ ~euc_handler() {}; ++ ++ const char *name() { return "EUC-JP"; }; ++ ++ inline int is_wchar_byte(unsigned char c) { ++ return (c >= 0xa1 && c <= 0xfe); ++ } ++ ++ inline wchar make_wchar(unsigned char c0, encoding_istream& eis) { ++ wchar wc; ++ if (! is_wchar_byte(c0)) { ++ return c0; ++ } ++ int c1 = eis.peekbyte(); ++ if (! is_wchar_byte(c1)) { ++ eis.ungetbyte(c1); ++ return c0; ++ } ++ c1 = eis.getbyte(); ++ wc = (c0 & 0xff) << 8; ++ wc |= (c1 & 0xff); ++ ++ if (wc == 0xa1a1) ++ return ' '; ++ return -wc; ++ } ++ ++ inline int put_wchar(wchar wc, encoding_ostream& eos) { ++ if (is_wchar_code(wc)) { ++ wc = -wc; ++ eos.putbyte((wc >> 8) & 0x0ff); ++ eos.putbyte((wc >> 0) & 0x0ff); ++ return 2; ++ } else { ++ eos.putbyte(wc & 0x0ff); ++ return 1; ++ } ++ } ++ inline int max_wchar_len() { return 2; }; /* XXX */ ++}; ++#endif /* USE_ICONV */ ++#endif ++ ++static ascii8_handler ascii8; ++#ifdef ENABLE_MULTIBYTE ++static utf8_handler utf8; ++#ifdef USE_ICONV ++iconv_handler *iconv_handler::ih_header = NULL; ++#else ++static euc_handler eucjp; ++#endif ++#endif ++ ++encoding_handler *input_encoding = &ascii8; ++encoding_handler *output_encoding = &ascii8; ++ ++static void ++new_encoding_handler(encoding_handler **eptr, const char *encoding_name) ++{ ++ if (!encoding_name) { ++ *eptr = &ascii8; ++ return; ++ } ++#ifdef ENABLE_MULTIBYTE ++ if (strcmp(encoding_name, "UTF-8") == 0) { ++ *eptr = &utf8; ++ return; ++ } ++#ifdef USE_ICONV ++ if (strcmp(encoding_name, "C") != 0) { ++ *eptr = iconv_handler::new_iconv_handler(encoding_name); ++ return; ++ } ++#else ++ // printf("encoding request: [%s]\n", encoding_name); ++ if (strcmp(encoding_name, "EUC-JP") == 0) { ++ // printf("encoding: [EUC-JP]\n"); ++ *eptr = &eucjp; ++ return; ++ } ++#endif ++#endif ++ // default ++ *eptr = &ascii8; ++ return; ++} ++ ++encoding_handler * ++select_input_encoding_handler(const char *encoding_name) ++{ ++ new_encoding_handler(&input_encoding, encoding_name); ++ return input_encoding; ++} ++ ++encoding_handler * ++select_output_encoding_handler(const char *encoding_name) ++{ ++ new_encoding_handler(&output_encoding, encoding_name); ++ return output_encoding; ++} ++ ++void ++init_encoding_handler() ++{ ++#ifdef ENABLE_MULTIBYTE ++ const char *locale, *charset; ++ // groff 1 defines ISO-8859-1 as the input encoding, so this is required ++ // for compatibility. groff 2 will define UTF-8 (or possibly officially ++ // allow it to be switchable?) ++ select_input_encoding_handler("ISO-8859-1"); ++ select_output_encoding_handler("C"); ++ ++ locale = setlocale(LC_ALL, ""); ++ if (locale == NULL || ++ strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) { ++ return; ++ } ++ /* check LC_CTYPE is C or POSIX */ ++ locale = setlocale(LC_CTYPE, NULL); ++ if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) { ++ return; ++ } ++ /* otherwise */ ++#if HAVE_LANGINFO_CODESET ++ charset = nl_langinfo(CODESET); ++#else ++ charset = strchr(locale, '.'); ++ if (charset) ++ ++charset; ++ else ++ charset = ""; ++#endif ++ if (strncmp(locale, "ja", 2) == 0 || strncmp(locale, "zh", 2) == 0 || ++ (strncmp(locale, "ko", 2) == 0 && strcmp(charset, "UTF-8") == 0)) { ++ select_input_encoding_handler(charset); ++ select_output_encoding_handler(charset); ++ } else if ((!device || strcmp(device, "ascii8") == 0)) { ++ select_input_encoding_handler(NULL); ++ select_output_encoding_handler(NULL); ++ } ++#endif ++ return; ++} ++ ++int ++is_wchar_code(wchar wc) ++{ ++ return (wc < 0); ++} ++ ++int ++is_wchar_singlebyte(wchar wc) ++{ ++ return ((-256 < wc) && (wc < 0)); ++} ++ ++unsigned char ++wchar_singlebyte(wchar wc) ++{ ++ if (wc >= 0) ++ return (unsigned char)wc; ++ else ++ return (unsigned char)-wc; ++} ++ ++int ++wchar_code(wchar wc) ++{ ++ if (wc >= 0) ++ return wc; ++ else ++ return -wc; ++} ++ ++int ++make_wchar(int w) ++{ ++ return -w; ++} +diff -Naur groff-1.18.1.4.orig/src/libs/libgroff/font.cc groff-1.18.1.4/src/libs/libgroff/font.cc +--- groff-1.18.1.4.orig/src/libs/libgroff/font.cc 2002-07-23 23:50:52.000000000 +0000 ++++ groff-1.18.1.4/src/libs/libgroff/font.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -25,6 +25,7 @@ + #include <assert.h> + #include <math.h> + #include <stdlib.h> ++#include "encoding.h" // XXX: ukai + #include "errarg.h" + #include "error.h" + #include "cset.h" +@@ -43,8 +44,39 @@ + int italic_correction; + int subscript_correction; + char *special_device_coding; ++#ifdef ENABLE_MULTIBYTE ++ char *subfont_name; ++#endif + }; + ++#ifdef ENABLE_MULTIBYTE ++struct fontset_list { ++ struct fontset_list *next; ++ char *primary_font_name; ++ int fontset_font; ++ wchar start_code; ++ wchar end_code; ++ int on_demand; ++}; ++ ++fontset_list *font::fontsets = NULL; ++ ++struct font_wchar_metric { ++ struct font_wchar_metric *next; ++ char type; ++ int start_code; ++ int end_code; ++ int width; ++ int height; ++ int depth; ++ int pre_math_space; ++ int italic_correction; ++ int subscript_correction; ++ char *special_device_coding; ++ char *subfont_name; ++}; ++#endif ++ + struct font_kern_list { + int i1; + int i2; +@@ -149,7 +181,11 @@ + + font::font(const char *s) + : ligatures(0), kern_hash_table(0), space_width(0), ch_index(0), nindices(0), +- ch(0), ch_used(0), ch_size(0), special(0), widths_cache(0) ++ ch(0), ++#ifdef ENABLE_MULTIBYTE ++ wch(0), ++#endif ++ ch_used(0), ch_size(0), special(0), widths_cache(0) + { + name = new char[strlen(s) + 1]; + strcpy(name, s); +@@ -183,6 +219,17 @@ + widths_cache = widths_cache->next; + delete tem; + } ++#ifdef ENABLE_MULTIBYTE ++ struct font_wchar_metric *wcp, *nwcp; ++ for (wcp = wch; wcp != NULL; wcp = nwcp) { ++ nwcp = wcp->next; ++ if (wcp->special_device_coding) ++ delete [] wcp->special_device_coding; ++ if (wcp->subfont_name) ++ delete [] wcp->subfont_name; ++ delete wcp; ++ } ++#endif + } + + static int scale_round(int n, int x, int y) +@@ -244,6 +291,11 @@ + + int font::contains(int c) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) ++ return 1; ++#endif + return c >= 0 && c < nindices && ch_index[c] >= 0; + } + +@@ -266,8 +318,31 @@ + a_delete width; + } + ++#ifdef ENABLE_MULTIBYTE ++struct font_wchar_metric * ++font::get_font_wchar_metric(int c) ++{ ++ /* XXX: c is font index, not char code... */ ++ /* XXX: we assume wchar_code == font index code for wchars */ ++ /* XXX: does really code conflicts with index? */ ++ struct font_wchar_metric *wcp; ++ for (wcp = wch; wcp != NULL; wcp = wcp->next) { ++ if (wcp->start_code <= wchar_code(c) && wchar_code(c) <= wcp->end_code) { ++ return wcp; ++ } ++ } ++ return NULL; ++} ++#endif ++ + int font::get_width(int c, int point_size) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) { ++ return scale(wcp->width, point_size); ++ } ++#endif + assert(c >= 0 && c < nindices); + int i = ch_index[c]; + assert(i >= 0); +@@ -299,30 +374,60 @@ + + int font::get_height(int c, int point_size) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) { ++ return scale(wcp->height, point_size); ++ } ++#endif + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].height, point_size); + } + + int font::get_depth(int c, int point_size) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) { ++ return scale(wcp->depth, point_size); ++ } ++#endif + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].depth, point_size); + } + + int font::get_italic_correction(int c, int point_size) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) { ++ return scale(wcp->italic_correction, point_size); ++ } ++#endif + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].italic_correction, point_size); + } + + int font::get_left_italic_correction(int c, int point_size) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) { ++ return scale(wcp->pre_math_space, point_size); ++ } ++#endif + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].pre_math_space, point_size); + } + + int font::get_subscript_correction(int c, int point_size) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) { ++ return scale(wcp->subscript_correction, point_size); ++ } ++#endif + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return scale(ch[ch_index[c]].subscript_correction, point_size); + } +@@ -371,12 +476,24 @@ + + int font::get_character_type(int c) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) { ++ return wcp->type; ++ } ++#endif + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return ch[ch_index[c]].type; + } + + int font::get_code(int c) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) { ++ return c; ++ } ++#endif + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return ch[ch_index[c]].code; + } +@@ -393,10 +510,26 @@ + + const char *font::get_special_device_encoding(int c) + { ++#ifdef ENABLE_MULTIBYTE ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) ++ return wcp->special_device_coding; ++#endif + assert(c >= 0 && c < nindices && ch_index[c] >= 0); + return( ch[ch_index[c]].special_device_coding ); + } + ++#ifdef ENABLE_MULTIBYTE ++const char *font::get_subfont_name(int c) ++{ ++ font_wchar_metric *wcp = get_font_wchar_metric(c); ++ if (wcp != NULL) ++ return wcp->subfont_name; ++ assert(c >= 0 && c < nindices && ch_index[c] >= 0); ++ return ch[ch_index[c]].subfont_name; ++} ++#endif ++ + void font::alloc_ch_index(int index) + { + if (nindices == 0) { +@@ -554,9 +687,11 @@ + return 0; + } + ++ + // If the font can't be found, then if not_found is non-NULL, it will be set + // to 1 otherwise a message will be printed. + ++ + int font::load(int *not_found) + { + char *path; +@@ -570,7 +705,7 @@ + } + text_file t(fp, path); + t.skip_comments = 1; +- char *p; ++ char *p = NULL; + for (;;) { + if (!t.next()) { + t.error("missing charset command"); +@@ -681,6 +816,9 @@ + } + else if (strcmp(command, "charset") == 0) { + had_charset = 1; ++#ifdef ENABLE_MULTIBYTE ++ int had_range = 0; ++#endif + int last_index = -1; + for (;;) { + if (!t.next()) { +@@ -695,6 +833,11 @@ + command = nm; + break; + } ++#ifdef ENABLE_MULTIBYTE ++ int start_code = 0; ++ int end_code = 0; ++ int nrange = sscanf(nm, "u%X..u%X", &start_code, &end_code); ++#endif + if (p[0] == '"') { + if (last_index == -1) { + t.error("first charset entry is duplicate"); +@@ -711,7 +854,64 @@ + } + copy_entry(index, last_index); + } ++#ifdef ENABLE_MULTIBYTE ++ else if (nrange == 2) { ++ had_range = 1; ++ font_wchar_metric *wcp = new font_wchar_metric; ++ wcp->start_code = start_code; ++ wcp->end_code = end_code; ++ wcp->height = 0; ++ wcp->depth = 0; ++ wcp->pre_math_space = 0; ++ wcp->italic_correction = 0; ++ wcp->subscript_correction = 0; ++ int nparms = sscanf(p, "%d,%d,%d,%d,%d,%d", ++ &wcp->width, &wcp->height, &wcp->depth, ++ &wcp->italic_correction, ++ &wcp->pre_math_space, ++ &wcp->subscript_correction); ++ if (nparms < 1) { ++ t.error("bad width for `%1'", nm); ++ return 0; ++ } ++ p = strtok(0, WS); ++ if (p == 0) { ++ t.error("missing character type for `%1'", nm); ++ return 0; ++ } ++ int type; ++ if (sscanf(p, "%d", &type) != 1) { ++ t.error("bad character type for `%1'", nm); ++ return 0; ++ } ++ if (type < 0 || type > 255) { ++ t.error("character type `%1' out of range", type); ++ return 0; ++ } ++ wcp->type = type; ++ ++ p = strtok(0, WS); ++ if ((p == 0) || (strcmp(p, "--") == 0)) { ++ wcp->subfont_name = NULL; ++ } else { ++ wcp->subfont_name = new char[strlen(p) + 1]; ++ strcpy(wcp->subfont_name, p); ++ } ++ ++ p = strtok(0, WS); ++ if ((p == NULL) || (strcmp(p, "--") == 0)) { ++ wcp->special_device_coding = NULL; ++ } else { ++ wcp->special_device_coding = new char[strlen(p) + 1]; ++ strcpy(wcp->special_device_coding, p); ++ } ++ wcp->next = wch; ++ wch = wcp; ++ p = NULL; ++ } ++#endif + else { ++ + font_char_metric metric; + metric.height = 0; + metric.depth = 0; +@@ -747,6 +947,16 @@ + t.error("missing code for `%1'", nm); + return 0; + } ++#ifdef ENABLE_MULTIBYTE ++ char *subp = strchr(p, ':'); ++ if (subp) { ++ *subp++ = '\0'; ++ metric.subfont_name = new char[strlen(subp) + 1]; ++ strcpy(metric.subfont_name, subp); ++ } else { ++ metric.subfont_name = NULL; ++ } ++#endif + char *ptr; + metric.code = (int)strtol(p, &ptr, 0); + if (metric.code == 0 && ptr == p) { +@@ -777,7 +987,11 @@ + } + } + } ++#ifdef ENABLE_MULTIBYTE ++ if (!had_range && last_index == -1) { ++#else + if (last_index == -1) { ++#endif + t.error("I didn't seem to find any characters"); + return 0; + } +@@ -811,6 +1025,11 @@ + { "biggestfont", &font::biggestfont }, + { "spare2", &font::spare2 }, + { "sizescale", &font::sizescale } ++#ifdef ENABLE_MULTIBYTE ++ , ++ { "lowerwchar", &font::lowerwchar }, ++ { "wcharkern", &font::wcharkern } ++#endif + }; + + int font::load_desc() +@@ -981,6 +1200,67 @@ + tcommand = 1; + else if (strcmp("use_charnames_in_special", p) == 0) + use_charnames_in_special = 1; ++#ifdef ENABLE_MULTIBYTE ++ else if (strcmp("fontset", p) == 0) { ++ /* fontset <primary-fontname> <fontname> <code>..<code> [ondemand] */ ++ p = strtok(0, WS); ++ if (p == NULL) { ++ t.error("no primary font for fontset"); ++ return 0; ++ } ++ char *pfont = NULL; ++ if (strcmp(p, "-") != 0) { ++ pfont = new char[strlen(p)+1]; ++ strcpy(pfont, p); ++ } ++ p = strtok(0, WS); ++ if (p == NULL) { ++ t.error("no fontset font for `%1'", ++ pfont ? pfont : "-"); ++ return 0; ++ } ++ int fontset_font = 0; ++ for (int i = 0; i < nfonts; i++) { ++ if (strcmp(p, font_name_table[i]) == 0) { ++ fontset_font = i; ++ break; ++ } ++ } ++ if (fontset_font == nfonts) { ++ t.error("fontset font `%1' for font `%2' not defined", ++ p, pfont ? pfont : "-"); ++ return 0; ++ } ++ p = strtok(0, WS); ++ if (p == NULL) { ++ t.error("no range for fontset font `%1' for font `%2'", ++ font_name_table[fontset_font], ++ pfont ? pfont : "-"); ++ return 0; ++ } ++ wchar start_code = 0; ++ wchar end_code = 0; ++ int nparms = sscanf(p, "%x..%x", &start_code, &end_code); ++ if (nparms != 2) { ++ t.error("invalid range format `%1'", p); ++ return 0; ++ } ++ p = strtok(0, WS); ++ int on_demand = 0; ++ if (p != NULL && strcmp(p, "ondemand") == 0) { ++ on_demand = 1; ++ } ++ /* XXX */ ++ fontset_list *fl = new fontset_list; ++ fl->primary_font_name = pfont; ++ fl->fontset_font = fontset_font; ++ fl->start_code = start_code; ++ fl->end_code = end_code; ++ fl->on_demand = on_demand; ++ fl->next = fontsets; ++ fontsets = fl; ++ } ++#endif + else if (strcmp("charset", p) == 0) + break; + else if (unknown_desc_command_handler) { +@@ -1020,6 +1300,39 @@ + return 1; + } + ++#ifdef ENABLE_MULTIBYTE ++int ++font::get_fontset_font(const char *fname, wchar wc) { ++ fontset_list *fl; ++ int avail_fontno = -1; ++ wc = wchar_code(wc); ++ for (fl = fontsets; fl != NULL; fl = fl->next) { ++ if (fl->primary_font_name == NULL) { ++ if (fl->start_code <= wc && wc <= fl->end_code) { ++ avail_fontno = fl->fontset_font; ++ } ++ } ++ else if (fname && strcmp(fl->primary_font_name, fname) == 0) { ++ if (fl->start_code <= wc && wc <= fl->end_code) { ++ return fl->fontset_font; ++ } ++ } ++ } ++ return avail_fontno; ++} ++ ++int ++font::is_on_demand(int fontno) { ++ fontset_list *fl; ++ for (fl = fontsets; fl != NULL; fl = fl->next) { ++ if (fl->fontset_font == fontno) { ++ return fl->on_demand; ++ } ++ } ++ return 0; ++} ++#endif ++ + void font::handle_unknown_font_command(const char *, const char *, + const char *, int) + { +diff -Naur groff-1.18.1.4.orig/src/libs/libgroff/fontfile.cc groff-1.18.1.4/src/libs/libgroff/fontfile.cc +--- groff-1.18.1.4.orig/src/libs/libgroff/fontfile.cc 2002-05-31 14:31:01.000000000 +0000 ++++ groff-1.18.1.4/src/libs/libgroff/fontfile.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -24,6 +24,7 @@ + #include <assert.h> + #include <stdlib.h> + #include <errno.h> ++#include "encoding.h" // XXX: ukai + #include "font.h" + #include "searchpath.h" + #include "device.h" +@@ -36,6 +37,10 @@ + int font::res = 0; + int font::hor = 1; + int font::vert = 1; ++#ifdef ENABLE_MULTIBYTE ++int font::lowerwchar = 0; ++int font::wcharkern = 0; ++#endif + int font::unitwidth = 0; + int font::paperwidth = 0; + int font::paperlength = 0; +diff -Naur groff-1.18.1.4.orig/src/libs/libgroff/nametoindex.cc groff-1.18.1.4/src/libs/libgroff/nametoindex.cc +--- groff-1.18.1.4.orig/src/libs/libgroff/nametoindex.cc 2002-04-05 20:55:38.000000000 +0000 ++++ groff-1.18.1.4/src/libs/libgroff/nametoindex.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -24,6 +24,7 @@ + #include <ctype.h> + #include <assert.h> + #include <stdlib.h> ++#include "encoding.h" // XXX: ukai + #include "errarg.h" + #include "error.h" + #include "font.h" +@@ -37,6 +38,9 @@ + character_indexer(); + ~character_indexer(); + int ascii_char_index(unsigned char); ++#ifdef ENABLE_MULTIBYTE ++ int wchar_index(wchar); ++#endif + int named_char_index(const char *); + int numbered_char_index(int); + private: +@@ -68,6 +72,13 @@ + return ascii_index[c]; + } + ++#ifdef ENABLE_MULTIBYTE ++int character_indexer::wchar_index(wchar wc) ++{ ++ return wc; /* XXX: wchar code == index */ ++} ++#endif ++ + int character_indexer::numbered_char_index(int n) + { + if (n >= 0 && n < NSMALL) { +@@ -103,6 +114,30 @@ + int font::name_to_index(const char *s) + { + assert(s != 0 && s[0] != '\0' && s[0] != ' '); ++#ifdef ENABLE_MULTIBYTE ++ { ++ int i = 1; ++ wchar wc = input_encoding->make_wchar(s[0], (const unsigned char *)s, &i); ++ /* XXX ++ * if wchar can be represented in single byte (<256), ++ * it should be the same as char<wc>. ++ */ ++ if (is_wchar_singlebyte(wc)) { ++ return indexer.ascii_char_index(wchar_singlebyte(wc)); ++ } ++ if (is_wchar_code(wc)) { ++ return indexer.wchar_index(wc); ++ } ++ /* XXX: uA1A1 and \xa1a1 are synonyms */ ++ if (s[0] == 'u') { ++ char *res; ++ long n = strtol(s + 1, &res, 16); ++ if (res != s + 1 && *res == '\0') { ++ return indexer.wchar_index(n); ++ } ++ } ++ } ++#endif + if (s[1] == '\0') + return indexer.ascii_char_index(s[0]); + /* char128 and \200 are synonyms */ +@@ -115,3 +150,9 @@ + return indexer.named_char_index(s); + } + ++#ifdef ENABLE_MULTIBYTE ++int font::wchar_index(wchar wc) ++{ ++ return indexer.wchar_index(wc); ++} ++#endif +diff -Naur groff-1.18.1.4.orig/src/libs/libgroff/searchpath.cc groff-1.18.1.4/src/libs/libgroff/searchpath.cc +--- groff-1.18.1.4.orig/src/libs/libgroff/searchpath.cc 2001-08-19 21:32:28.000000000 +0000 ++++ groff-1.18.1.4/src/libs/libgroff/searchpath.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -19,6 +19,7 @@ + with groff; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + ++#include "encoding.h" + #include "lib.h" + + #include <stdlib.h> +diff -Naur groff-1.18.1.4.orig/src/libs/libgroff/tmpfile.cc groff-1.18.1.4/src/libs/libgroff/tmpfile.cc +--- groff-1.18.1.4.orig/src/libs/libgroff/tmpfile.cc 2002-09-06 07:50:42.000000000 +0000 ++++ groff-1.18.1.4/src/libs/libgroff/tmpfile.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -24,6 +24,7 @@ + #include <errno.h> + #include <stdlib.h> + ++#include "encoding.h" + #include "posix.h" + #include "errarg.h" + #include "error.h" +diff -Naur groff-1.18.1.4.orig/src/preproc/eqn/box.cc groff-1.18.1.4/src/preproc/eqn/box.cc +--- groff-1.18.1.4.orig/src/preproc/eqn/box.cc 2002-04-04 14:04:45.000000000 +0000 ++++ groff-1.18.1.4/src/preproc/eqn/box.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -80,7 +80,7 @@ + + int nroff = 0; // should we grok ndefine or tdefine? + +-struct { ++struct S { + const char *name; + int *ptr; + } param_table[] = { +diff -Naur groff-1.18.1.4.orig/src/preproc/eqn/eqn.y groff-1.18.1.4/src/preproc/eqn/eqn.y +--- groff-1.18.1.4.orig/src/preproc/eqn/eqn.y 2000-02-06 09:38:01.000000000 +0000 ++++ groff-1.18.1.4/src/preproc/eqn/eqn.y 2006-10-18 18:54:44.000000000 +0000 +@@ -21,6 +21,7 @@ + #include <string.h> + #include <stdlib.h> + ++#include "encoding.h" /* XXX */ + #include "lib.h" + #include "box.h" + extern int non_empty_flag; +diff -Naur groff-1.18.1.4.orig/src/preproc/eqn/lex.cc groff-1.18.1.4/src/preproc/eqn/lex.cc +--- groff-1.18.1.4.orig/src/preproc/eqn/lex.cc 2002-02-10 01:22:11.000000000 +0000 ++++ groff-1.18.1.4/src/preproc/eqn/lex.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -23,6 +23,7 @@ + #include "eqn_tab.h" + #include "stringclass.h" + #include "ptable.h" ++#include "encoding.h" + + struct definition { + char is_macro; +@@ -375,6 +376,11 @@ + lex_error("invalid input character code %1", c); + else { + line += char(c); ++#ifdef ENABLE_MULTIBYTE ++ if (input_encoding->is_wchar_byte(c)) { ++ line += char(getc(fp)); ++ } ++#endif + if (c == '\n') + break; + } +diff -Naur groff-1.18.1.4.orig/src/preproc/eqn/main.cc groff-1.18.1.4/src/preproc/eqn/main.cc +--- groff-1.18.1.4.orig/src/preproc/eqn/main.cc 2002-02-19 16:28:31.000000000 +0000 ++++ groff-1.18.1.4/src/preproc/eqn/main.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -258,6 +258,7 @@ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); ++ init_encoding_handler(); + int opt; + int load_startup_file = 1; + static const struct option long_options[] = { +diff -Naur groff-1.18.1.4.orig/src/preproc/eqn/text.cc groff-1.18.1.4/src/preproc/eqn/text.cc +--- groff-1.18.1.4.orig/src/preproc/eqn/text.cc 2000-02-06 09:38:06.000000000 +0000 ++++ groff-1.18.1.4/src/preproc/eqn/text.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -21,13 +21,20 @@ + #include "eqn.h" + #include "pbox.h" + #include "ptable.h" ++#include "encoding.h" + + class char_box : public simple_box { + unsigned char c; ++#ifdef ENABLE_MULTIBYTE ++ wchar wc; ++#endif + char next_is_italic; + char prev_is_italic; + public: + char_box(unsigned char); ++#ifdef ENABLE_MULTIBYTE ++ char_box(unsigned char, wchar); ++#endif + void debug_print(); + void output(); + int is_char(); +@@ -165,11 +172,22 @@ + } + + char_box::char_box(unsigned char cc) +-: c(cc), next_is_italic(0), prev_is_italic(0) ++: c(cc), ++#ifdef ENABLE_MULTIBYTE ++ wc(cc), ++#endif ++ next_is_italic(0), prev_is_italic(0) + { + spacing_type = char_table[c].spacing_type; + } + ++#ifdef ENABLE_MULTIBYTE ++char_box::char_box(unsigned char cc, wchar wc) ++: c(cc), wc(wc), next_is_italic(0), prev_is_italic(0) ++{ ++} ++#endif ++ + void char_box::hint(unsigned flags) + { + if (flags & HINT_PREV_IS_ITALIC) +@@ -188,7 +206,11 @@ + if (c == '\') + fputs("\e", stdout); + else ++#ifdef ENABLE_MULTIBYTE ++ output_encoding->put_wchar(wc, stdout); ++#else + putchar(c); ++#endif + if (!next_is_italic) + fputs("\/", stdout); + else +@@ -497,6 +519,14 @@ + break; + default: + normal_char: ++#ifdef ENABLE_MULTIBYTE ++ if (input_encoding->is_wchar_byte(c)) { ++ int i = 1; ++ wchar wc = input_encoding->make_wchar(c, (unsigned char *)s, &i); ++ b = new char_box('A', wc); // char_info of wc is same the 'A'. ++ s += i; ++ } else ++#endif + b = new char_box(c); + break; + } +diff -Naur groff-1.18.1.4.orig/src/preproc/html/pre-html.cc groff-1.18.1.4/src/preproc/html/pre-html.cc +--- groff-1.18.1.4.orig/src/preproc/html/pre-html.cc 2002-09-05 23:37:01.000000000 +0000 ++++ groff-1.18.1.4/src/preproc/html/pre-html.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -63,6 +63,10 @@ + #define DEFAULT_IMAGE_RES 100 // number of pixels per inch resolution + #define IMAGE_BOARDER_PIXELS 0 + #define INLINE_LEADER_CHAR '\' ++#define A4_LENGTH 841890 // taken from devps/Makefile.sub ++#define LETTER_LENGTH 792000 // taken from devps/Makefile.sub ++#define A4_OFFSET 0 ++#define LETTER_OFFSET 50 // 50/72 of an inch + + #define TRANSPARENT "-background white -transparent white" + #define MIN_ALPHA_BITS 0 +@@ -104,6 +108,7 @@ + static char *macroset_template= NULL; // image template passed to troff by -D + static int troff_arg = 0; // troff arg index + static char *image_dir = NULL; // user specified image directory ++static char *gsPaper = NULL; // the paper size that gs must use + static int textAlphaBits = MAX_ALPHA_BITS; + static int graphicAlphaBits = MAX_ALPHA_BITS; + static char *antiAlias = NULL; // antialias arguments we pass to gs. +@@ -211,6 +216,54 @@ + } + + /* ++ * get_papersize - returns an integer determining the paper length from ++ * devps/DESC ++ */ ++ ++static int get_papersize (void) ++{ ++ char *pathp; ++ FILE *f; ++ int res; ++ f = font_path.open_file("devps/DESC", &pathp); ++ if (f == 0) ++ fatal("can't open devps/DESC"); ++ while (get_line(f)) { ++ int n = sscanf(linebuf, "paperlength %d", &res); ++ if (n >= 1) { ++ fclose(f); ++ return res; ++ } ++ if (!strncmp(linebuf, "papersize", 9)) { ++ double length; ++ char *p = linebuf + 9; ++ while (*p == ' ' || *p == '\t') ++ p++; ++ for (p = strtok(p, " \t"); p; p = strtok(0, " \t")) { ++ if (font::scan_papersize(p, 0, &length, 0)) { ++ fclose(f); ++ return int(length * postscriptRes + 0.5); ++ } ++ } ++ fatal("bad argument to `papersize' keyword in devps/DESC"); ++ } ++ } ++ fatal("can't find `papersize' or `paperlength' keyword in devps/DESC"); ++ return 0; ++} ++ ++/* ++ * determine_vertical_offset - works out the default vertical offset from ++ * the page length ++ */ ++ ++static void determine_vertical_offset (void) ++{ ++ vertical_offset = ((A4_LENGTH-get_papersize())*72)/postscriptRes; ++ gsPaper = "-sPAPERSIZE=a4"; ++} ++ ++/* + * html_system - a wrapper for system() + */ + +@@ -1469,6 +1522,7 @@ + int ok=1; + + postscriptRes = get_resolution(); ++ determine_vertical_offset(); + i = scanArguments(argc, argv); + setupAntiAlias(); + checkImageDir(); +diff -Naur groff-1.18.1.4.orig/src/preproc/refer/command.cc groff-1.18.1.4/src/preproc/refer/command.cc +--- groff-1.18.1.4.orig/src/preproc/refer/command.cc 2002-02-10 01:22:12.000000000 +0000 ++++ groff-1.18.1.4/src/preproc/refer/command.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -632,7 +632,7 @@ + ? means that the previous argument is optional, * means that the + previous argument can occur any number of times. */ + +-struct { ++struct S { + const char *name; + command_t func; + const char *arg_types; +diff -Naur groff-1.18.1.4.orig/src/roff/groff/groff.cc groff-1.18.1.4/src/roff/groff/groff.cc +--- groff-1.18.1.4.orig/src/roff/groff/groff.cc 2002-09-22 08:35:48.000000000 +0000 ++++ groff-1.18.1.4/src/roff/groff/groff.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -107,6 +107,7 @@ + program_name = argv[0]; + static char stderr_buf[BUFSIZ]; + setbuf(stderr, stderr_buf); ++ init_encoding_handler(); + assert(NCOMMANDS <= MAX_COMMANDS); + string Pargs, Largs, Fargs; + int vflag = 0; +diff -Naur groff-1.18.1.4.orig/src/roff/groff/groff.man groff-1.18.1.4/src/roff/groff/groff.man +--- groff-1.18.1.4.orig/src/roff/groff/groff.man 2002-07-13 09:28:17.000000000 +0000 ++++ groff-1.18.1.4/src/roff/groff/groff.man 2006-10-18 18:54:44.000000000 +0000 +@@ -15,6 +15,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff-base/copyright. ++.. + . + ." -------------------------------------------------------------------- + ." Setup +@@ -118,7 +122,7 @@ + .c -------------------------------------------------------------------- + .c ShortOpt ([char [punct]]) + .c +-.c `-c' somwhere in the text ++.c `-c' somewhere in the text + .c second arg is punctuation + .c + .de ShortOpt +@@ -130,7 +134,7 @@ + .c -------------------------------------------------------------------- + .c LongOpt ([name [punct]]) + .c +-.c `--name' somwhere in the text ++.c `--name' somewhere in the text + .c second arg is punctuation + .c + .de LongOpt +@@ -314,7 +318,7 @@ + .B groff + program allows to control the whole + .I groff +-system by comand line options. ++system by command line options. + . + This is a great simplification in comparison to the classical case (which + uses pipes only). +@@ -610,7 +614,7 @@ + . + . + ." -------------------------------------------------------------------- +-.SS Tranparent Options ++.SS Transparent Options + ." -------------------------------------------------------------------- + . + The following options are transparently handed over to the formatter +@@ -695,7 +699,7 @@ + is much easier than + .IR "classical roff" . + . +-This section gives an overview of the parts that consitute the groff ++This section gives an overview of the parts that constitute the groff + system. + . + It complements +@@ -948,6 +952,10 @@ + Text output using the EBCDIC code page IBM cp1047 (e.g. OS/390 Unix). + . + .TP ++.B nippon ++Text output using the Japanese-EUC character set. ++. ++.TP + .B dvi + TeX DVI format. + . +@@ -956,6 +964,12 @@ + HTML output. + . + .TP ++.B ascii8 ++For typewriter-like devices. Unlike ++.BR ascii , ++this device is 8 bit clean. This device is intended to be used ++for codesets other than ASCII and ISO-8859-1. ++.TP + .B latin1 + Text output using the ISO Latin-1 (ISO 8859-1) character set; see + .BR iso_8859_1 (7). +@@ -1031,7 +1045,7 @@ + . + .P + Today, most printing or drawing hardware is handled by the operating +-system, by device drivers, or by software interfaces, usally accepting ++system, by device drivers, or by software interfaces, usually accepting + PostScript. + . + Consequently, there isn't an urgent need for more hardware device +diff -Naur groff-1.18.1.4.orig/src/roff/nroff/nroff.man groff-1.18.1.4/src/roff/nroff/nroff.man +--- groff-1.18.1.4.orig/src/roff/nroff/nroff.man 2002-02-07 08:36:54.000000000 +0000 ++++ groff-1.18.1.4/src/roff/nroff/nroff.man 2006-10-18 18:54:44.000000000 +0000 +@@ -53,8 +53,10 @@ + command using groff. + Only + .BR ascii , ++.BR ascii8 , + .BR latin1 , + .BR utf8 , ++.BR nippon , + and + .B cp1047 + are valid arguments for the +diff -Naur groff-1.18.1.4.orig/src/roff/nroff/nroff.sh groff-1.18.1.4/src/roff/nroff/nroff.sh +--- groff-1.18.1.4.orig/src/roff/nroff/nroff.sh 2002-02-07 08:36:54.000000000 +0000 ++++ groff-1.18.1.4/src/roff/nroff/nroff.sh 2006-10-18 18:54:44.000000000 +0000 +@@ -12,6 +12,8 @@ + T=-Tlatin1 ;; + IBM-1047) + T=-Tcp1047 ;; ++ EUC-JP) ++ T=-Tnippon ;; + *) + case "${LC_ALL-${LC_CTYPE-${LANG}}}" in + *.UTF-8) +@@ -20,6 +22,8 @@ + T=-Tlatin1 ;; + *.IBM-1047) + T=-Tcp1047 ;; ++ ja_JP.ujis | ja_JP.eucJP) ++ T=-Tnippon ;; + *) + case "$LESSCHARSET" in + utf-8) +@@ -28,8 +32,10 @@ + T=-Tlatin1 ;; + cp1047) + T=-Tcp1047 ;; ++ japanese) ++ T=-Tnippon ;; + *) +- T=-Tascii ;; ++ T=-Tascii8 ;; + esac ;; + esac ;; + esac +@@ -52,7 +58,7 @@ + exit 1 ;; + -[iptSUC] | -[mrno]*) + opts="$opts $1" ;; +- -Tascii | -Tlatin1 | -Tutf8 | -Tcp1047) ++ -Tascii | -Tlatin1 | -Tutf8 | -Tcp1047 | -Tascii8 | -Tnippon) + T=$1 ;; + -T*) + # ignore other devices +diff -Naur groff-1.18.1.4.orig/src/roff/troff/charinfo.h groff-1.18.1.4/src/roff/troff/charinfo.h +--- groff-1.18.1.4.orig/src/roff/troff/charinfo.h 2002-03-22 16:11:18.000000000 +0000 ++++ groff-1.18.1.4/src/roff/troff/charinfo.h 2006-10-18 18:54:44.000000000 +0000 +@@ -29,9 +29,16 @@ + macro *mac; + unsigned char special_translation; + unsigned char hyphenation_code; ++#ifdef ENABLE_MULTIBYTE ++ unsigned short flags; ++#else + unsigned char flags; ++#endif + unsigned char ascii_code; + unsigned char asciify_code; ++#ifdef ENABLE_MULTIBYTE ++ wchar wchar_code; ++#endif + char not_found; + char transparent_translate; // non-zero means translation applies + // to transparent throughput +@@ -47,6 +54,11 @@ + OVERLAPS_VERTICALLY = 16, + TRANSPARENT = 32, + NUMBERED = 64 ++#ifdef ENABLE_MULTIBYTE ++ , ++ DONT_BREAK_BEFORE = 0x100, // 256, pre kinsoku ++ DONT_BREAK_AFTER = 0x200 // 512, post kinsoku ++#endif + }; + enum { + TRANSLATE_NONE, +@@ -74,7 +86,11 @@ + int get_translation_input(); + charinfo *get_translation(int = 0); + void set_translation(charinfo *, int, int); ++#ifdef ENABLE_MULTIBYTE ++ void set_flags(unsigned short); ++#else + void set_flags(unsigned char); ++#endif + void set_special_translation(int, int); + int get_special_translation(int = 0); + macro *set_macro(macro *, int = 0); +@@ -84,6 +100,12 @@ + int get_number(); + int numbered(); + int is_fallback(); ++#ifdef ENABLE_MULTIBYTE ++ wchar get_wchar_code(); ++ void set_wchar_code(wchar); ++ int cannot_break_before(); // pre kinsoku ++ int cannot_break_after(); // post kinsoku ++#endif + symbol *get_symbol(); + }; + +@@ -131,6 +153,18 @@ + return fallback; + } + ++#ifdef ENABLE_MULTIBYTE ++inline int charinfo::cannot_break_before() ++{ ++ return flags & DONT_BREAK_BEFORE; ++} ++ ++inline int charinfo::cannot_break_after() ++{ ++ return flags & DONT_BREAK_AFTER; ++} ++#endif ++ + inline charinfo *charinfo::get_translation(int transparent_throughput) + { + return (transparent_throughput && !transparent_translate +@@ -153,7 +187,18 @@ + return (translate_input ? asciify_code : 0); + } + ++#ifdef ENABLE_MULTIBYTE ++inline wchar charinfo::get_wchar_code() ++{ ++ return wchar_code; ++} ++#endif ++ ++#ifdef ENABLE_MULTIBYTE ++inline void charinfo::set_flags(unsigned short c) ++#else + inline void charinfo::set_flags(unsigned char c) ++#endif + { + flags = c; + } +diff -Naur groff-1.18.1.4.orig/src/roff/troff/env.cc groff-1.18.1.4/src/roff/troff/env.cc +--- groff-1.18.1.4.orig/src/roff/troff/env.cc 2002-10-03 15:53:06.000000000 +0000 ++++ groff-1.18.1.4/src/roff/troff/env.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -32,6 +32,7 @@ + #include "charinfo.h" + #include "macropath.h" + #include "input.h" ++#include "font.h" // ENABLE_MULTIBYTE only? + #include <math.h> + + symbol default_family("T"); +@@ -264,6 +265,13 @@ + void environment::add_char(charinfo *ci) + { + int s; ++#ifdef ENABLE_MULTIBYTE ++ int fontno = get_font(); // current font # ++ int fontset_font = get_fontset_fontno(fontno, ci->get_wchar_code()); ++ if (fontno >= 0 && fontno != fontset_font) { ++ change_curfont(fontset_font); ++ } ++#endif + if (interrupted) + ; + // don't allow fields in dummy environments +@@ -286,11 +294,95 @@ + else { + if (line == 0) + start_line(); ++#ifdef ENABLE_MULTIBYTE ++ /* ++ * XXX: NEED REWRITE TO BE MORE GENERIC ++ * This code is based on jgroff ++ * about kerning between ASCII and EUC-JP ++ */ ++ if (!ci->get_wchar_code()) { ++ /* ++ * This node is a ASCII character node. ++ */ ++ if (!pre_char_is_ascii && enable_wcharkern && !hwkern.is_zero()) { ++ /* ++ * Insert a little space node between EUC and ASCII. ++ */ ++ word_space_node *ws; ++ ++ if (ci->ends_sentence() || ci->transparent() || ci->cannot_break_before()) ++ ws = new unbreakable_space_node(hwkern.to_units(), get_fill_color()); ++ else ++ ws = new word_space_node(hwkern.to_units(), ++ get_fill_color(), ++ new width_list(env_space_width(this), ++ env_sentence_space_width(this))); ++ curenv->add_node(ws); ++ } ++ pre_char_is_ascii = 1; ++ pre_wchar_cannot_break_after = 0; ++ } else { ++ /* ++ * This node is a EUC charcater node. ++ */ ++ if (!pre_char_is_ascii && line->get_node_type() == NODE_NEWLINE_SPACE) { ++ /* ++ * remove a newline-node. ++ */ ++ node *ns_node = line; ++ line = line->next; ++ width_total -= ns_node->width(); ++ space_total -= ns_node->nspaces(); ++ delete ns_node; ++ } ++ ++ if (!pre_wchar_cannot_break_after && !ci->cannot_break_before()) { ++ /* ++ * add a zero-width-space-node before EUC charcater node. ++ */ ++ add_node(new kword_space_node(get_fill_color())); ++ met_with_kword_space = 1; ++ } ++ pre_wchar_cannot_break_after = ci->cannot_break_after(); ++ ++ if (pre_char_is_ascii && enable_wcharkern && !hwkern.is_zero()) { ++ /* ++ * Insert a little space node between ASCII and EUC. ++ */ ++ unbreakable_space_node *ws = ++ new unbreakable_space_node(hwkern.to_units(), get_fill_color()); ++ curenv->add_node(ws); ++ } ++ pre_char_is_ascii = 0; ++ ++ if (!vlower.is_zero()) { ++ /* ++ * Lower a EUC charcater node. ++ */ ++ curenv->add_node(new vmotion_node(vlower.to_units(), ++ get_fill_color())); // lower ++ } ++ } ++#endif + if (ci != hyphen_indicator_char) + line = line->add_char(ci, this, &width_total, &space_total); + else + line = line->add_discretionary_hyphen(); ++#ifdef ENABLE_MULTIBYTE ++ enable_wcharkern = 1; ++ if (!vlower.is_zero() && ci->get_wchar_code()) { ++ /* ++ * Raise a EUC charcater node. ++ */ ++ curenv->add_node(new vmotion_node(-vlower.to_units(), ++ get_fill_color())); // raise ++ } ++#endif + } ++#ifdef ENABLE_MULTIBYTE ++ if (fontset_font >= 0 && fontno != fontset_font) ++ change_curfont(fontno); /* restore saved font # */ ++#endif + } + + node *environment::make_char_node(charinfo *ci) +@@ -394,7 +486,11 @@ + width_total += x; + return; + } ++#ifdef ENABLE_MULTIBYTE ++ add_node(new newline_space_node(x, get_fill_color())); // This node may be removed ++#else + add_node(new word_space_node(x, get_fill_color(), w)); ++#endif + possibly_break_line(0, spread_flag); + spread_flag = 0; + } +@@ -480,6 +576,35 @@ + warning(WARN_FONT, "bad font number"); + } + ++#ifdef ENABLE_MULTIBYTE ++void environment::change_curfont(symbol nm) ++{ ++ int n = symbol_fontno(nm); ++ if (n < 0) { ++ n = next_available_font_position(); ++ if (!mount_font(n, nm)) ++ return; ++ } ++ fontno = n; ++} ++ ++void environment::change_curfont(int n) ++{ ++ if (is_good_fontno(n)) ++ fontno = n; ++ else ++ error("bad font number"); ++} ++ ++void environment::set_encoding(symbol enc) ++{ ++ if (enc.is_null() || enc.is_empty()) ++ return; ++ select_input_encoding_handler(enc.contents()); ++ select_output_encoding_handler(enc.contents()); ++} ++#endif /* ENABLE_MULTIBYTE */ ++ + void environment::set_family(symbol fam) + { + if (interrupted) +@@ -649,6 +774,16 @@ + control_char('.'), + no_break_control_char('''), + hyphen_indicator_char(0) ++#ifdef ENABLE_MULTIBYTE ++ , ++ stretch_threshold(0), ++ pre_wchar_cannot_break_after(0), ++ pre_char_is_ascii(-1), ++ enable_wcharkern(0), ++ met_with_kword_space(0), ++ hwkern(font::wcharkern), ++ vlower(font::lowerwchar) ++#endif + { + prev_family = family = lookup_family(default_family); + prev_fontno = fontno = 1; +@@ -739,6 +874,16 @@ + control_char(e->control_char), + no_break_control_char(e->no_break_control_char), + hyphen_indicator_char(e->hyphen_indicator_char) ++#ifdef ENABLE_MULTIBYTE ++ , ++ stretch_threshold(e->stretch_threshold), ++ pre_wchar_cannot_break_after(0), ++ pre_char_is_ascii(-1), ++ enable_wcharkern(0), ++ met_with_kword_space(0), ++ hwkern(font::wcharkern), ++ vlower(font::lowerwchar) ++#endif + { + } + +@@ -1781,6 +1926,9 @@ + target_text_length = line_length - saved_indent; + width_total = H0; + space_total = 0; ++#ifdef ENABLE_MULTIBYTE ++ enable_wcharkern = 0; ++#endif + } + + hunits environment::get_hyphenation_space() +@@ -1819,6 +1967,23 @@ + skip_line(); + } + ++#ifdef ENABLE_MULTIBYTE ++void stretch_threshold_request() ++{ ++ int n; ++ if (has_arg() && get_integer(&n)) { ++ if (n < 0 || n > 100) { ++ warning(WARN_RANGE, "stretch threshold value %1 out of range", n); ++ } else { ++ curenv->stretch_threshold = n; ++ } ++ } else { ++ curenv->stretch_threshold = 0; ++ } ++ skip_line(); ++} ++#endif ++ + breakpoint *environment::choose_breakpoint() + { + hunits x = width_total; +@@ -2014,6 +2179,30 @@ + // When a macro follows a paragraph in fill mode, the + // current line should not be empty. + || (width_total - line->width()) > target_text_length)) { ++#ifdef ENABLE_MULTIBYTE ++ if (met_with_kword_space) { ++ node *linep = line; ++ node *prep = 0; ++ while (linep->next) { ++ if (linep->next->get_node_type() == NODE_GLYPH) ++ prep = 0; ++ else if (linep->next->get_node_type() == NODE_KWORD_SPACE) ++ prep = linep; ++ linep = linep->next; ++ } ++ if (prep) { ++ /* ++ * delete a kword_space_node which is in the top of line. ++ */ ++ linep = prep->next; ++ prep->next = linep->next; ++ width_total -= linep->width(); ++ space_total -= linep->nspaces(); ++ delete linep; ++ } ++ met_with_kword_space = 0; ++ } ++#endif + hyphenate_line(start_here); + breakpoint *bp = choose_breakpoint(); + if (bp == 0) +@@ -2026,6 +2215,15 @@ + bp->nd->split(bp->index, &pre, &post); + *ndp = post; + hunits extra_space_width = H0; ++#ifdef ENABLE_MULTIBYTE ++ int sv_adjust_mode = adjust_mode; ++ if (stretch_threshold) { ++ int ratio = bp->width * 100 / target_text_length; ++ if (ratio < stretch_threshold) { ++ adjust_mode = ADJUST_LEFT; ++ } ++ } ++#endif + switch(adjust_mode) { + case ADJUST_BOTH: + if (bp->nspaces != 0) +@@ -2041,6 +2239,9 @@ + saved_indent += target_text_length - bp->width; + break; + } ++#ifdef ENABLE_MULTIBYTE ++ adjust_mode = sv_adjust_mode; ++#endif + distribute_space(pre, bp->nspaces, extra_space_width); + hunits output_width = bp->width + extra_space_width; + input_line_start -= output_width; +@@ -3237,6 +3438,9 @@ + init_request("hys", hyphenation_space_request); + init_request("hym", hyphenation_margin_request); + init_request("pvs", post_vertical_spacing); ++#ifdef ENABLE_MULTIBYTE ++ init_request("stt", stretch_threshold_request); ++#endif + init_int_env_reg(".f", get_font); + init_int_env_reg(".b", get_bold); + init_hunits_env_reg(".i", get_indent); +diff -Naur groff-1.18.1.4.orig/src/roff/troff/env.h groff-1.18.1.4/src/roff/troff/env.h +--- groff-1.18.1.4.orig/src/roff/troff/env.h 2002-09-20 14:39:32.000000000 +0000 ++++ groff-1.18.1.4/src/roff/troff/env.h 2006-10-18 18:54:44.000000000 +0000 +@@ -213,6 +213,15 @@ + unsigned char control_char; + unsigned char no_break_control_char; + charinfo *hyphen_indicator_char; ++#ifdef ENABLE_MULTIBYTE ++ int stretch_threshold; ++ int pre_wchar_cannot_break_after; ++ int pre_char_is_ascii; ++ int enable_wcharkern; ++ int met_with_kword_space; ++ hunits hwkern; ++ vunits vlower; ++#endif + + environment(symbol); + environment(const environment *); // for temporary environment +@@ -279,6 +288,10 @@ + void wrap_up_tab(); + void set_font(int); + void set_font(symbol); ++#ifdef ENABLE_MULTIBYTE ++ void change_curfont(int); ++ void change_curfont(symbol); ++#endif + void set_family(symbol); + void set_size(int); + void set_char_height(int); +@@ -309,6 +322,9 @@ + const char *get_point_size_string(); + const char *get_requested_point_size_string(); + void output_pending_lines(); ++#ifdef ENABLE_MULTIBYTE ++ void set_encoding(symbol); ++#endif + + friend void title_length(); + friend void space_size(); +@@ -347,6 +363,9 @@ + #ifdef WIDOW_CONTROL + friend void widow_control_request(); + #endif /* WIDOW_CONTROL */ ++#ifdef ENABLE_MULTIBYTE ++ friend void stretch_threshold_request(); ++#endif + + friend void do_divert(int append, int boxing); + }; +diff -Naur groff-1.18.1.4.orig/src/roff/troff/input.cc groff-1.18.1.4/src/roff/troff/input.cc +--- groff-1.18.1.4.orig/src/roff/troff/input.cc 2002-10-03 15:52:20.000000000 +0000 ++++ groff-1.18.1.4/src/roff/troff/input.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -35,6 +35,7 @@ + #include "macropath.h" + #include "defs.h" + #include "input.h" ++#include "encoding.h" // XXX: ukai + + // Needed for getpid() and isatty() + #include "posix.h" +@@ -89,6 +90,11 @@ + charinfo *charset_table[256]; + unsigned char hpf_code_table[256]; + ++#ifdef ENABLE_MULTIBYTE ++charinfo *wcharset_table_entry(wchar wc); ++ ++#endif /* ENABLE_MULTIBYTE */ ++ + static int warning_mask = DEFAULT_WARNING_MASK; + static int inhibit_errors = 0; + static int ignoring = 0; +@@ -148,6 +154,20 @@ + input_iterator *make_temp_iterator(const char *); + const char *input_char_description(int); + ++#ifdef ENABLE_MULTIBYTE ++static void ++select_encoding() ++{ ++ symbol e = get_long_name(1); ++ if (e.is_null()) { ++ skip_line(); ++ return; ++ } ++ curenv->set_encoding(e); ++ skip_line(); ++ ++} ++#endif + + void set_escape_char() + { +@@ -1524,6 +1544,19 @@ + type = TOKEN_NEWLINE; + } + ++#ifdef ENABLE_MULTIBYTE ++class encoding_istream_input : public encoding_istream { ++private: ++ node **np; ++public: ++ encoding_istream_input(node **n) : np(n) {}; ++ ~encoding_istream_input() {}; ++ int getbyte() { return input_stack::get(np); }; ++ int peekbyte() { return input_stack::peek(); }; ++ void ungetbyte(int ch) { return; }; ++}; ++#endif ++ + void token::next() + { + if (nd) { +@@ -1533,6 +1566,10 @@ + units x; + for (;;) { + node *n; ++#ifdef ENABLE_MULTIBYTE ++ encoding_istream_input einput(&n); ++#endif ++ + int cc = input_stack::get(&n); + if (cc != escape_char || escape_char == 0) { + handle_normal_char: +@@ -1686,8 +1723,22 @@ + } + return; + default: ++#ifdef ENABLE_MULTIBYTE ++ wc = input_encoding->make_wchar(cc, einput); ++ if (is_wchar_code(wc)) { ++ type = TOKEN_WCHAR; ++ c = 0; ++ } else if (wc == ' ') { ++ type = TOKEN_SPACE; ++ c = cc; ++ } else { ++ type = TOKEN_CHAR; ++ c = cc; ++ } ++#else + type = TOKEN_CHAR; + c = cc; ++#endif + return; + } + } +@@ -2057,6 +2108,10 @@ + switch(type) { + case TOKEN_CHAR: + return c == t.c; ++#ifdef ENABLE_MULTIBYTE ++ case TOKEN_WCHAR: ++ return wc == t.wc; ++#endif + case TOKEN_SPECIAL: + return nm == t.nm; + case TOKEN_NUMBERED_CHAR: +@@ -2563,6 +2618,27 @@ + } + break; + } ++#ifdef ENABLE_MULTIBYTE ++ case token::TOKEN_WCHAR: ++ { ++ wchar wch = tok.wc; ++ ++ if (possibly_handle_first_page_transition()) ++ ; ++ else { ++ for (;;) { ++ curenv->add_char(wcharset_table_entry(wch)); ++ tok.next(); ++ if (tok.type != token::TOKEN_WCHAR) ++ break; ++ wch = tok.wc; ++ } ++ suppress_next = 1; ++ bol = 0; ++ } ++ break; ++ } ++#endif /* ENABLE_MULTIBYTE */ + case token::TOKEN_TRANSPARENT: + { + if (bol) { +@@ -6018,6 +6094,10 @@ + { + if (type == TOKEN_CHAR) + return charset_table[c]; ++#ifdef ENABLE_MULTIBYTE ++ if (type == TOKEN_WCHAR) ++ return wcharset_table_entry(wc); ++#endif + if (type == TOKEN_SPECIAL) + return get_charinfo(nm); + if (type == TOKEN_NUMBERED_CHAR) +@@ -6070,6 +6150,11 @@ + case TOKEN_CHAR: + *pp = (*pp)->add_char(charset_table[c], curenv, &w, &s); + break; ++#ifdef ENABLE_MULTIBYTE ++ case TOKEN_WCHAR: ++ *pp = (*pp)->add_char(wcharset_table_entry(wc), curenv, &w, &s); ++ break; ++#endif + case TOKEN_DUMMY: + n = new dummy_node; + break; +@@ -6142,6 +6227,11 @@ + case TOKEN_CHAR: + curenv->add_char(charset_table[c]); + break; ++#ifdef ENABLE_MULTIBYTE ++ case TOKEN_WCHAR: ++ curenv->add_char(wcharset_table_entry(wc)); ++ break; ++#endif + case TOKEN_DUMMY: + curenv->add_node(new dummy_node); + break; +@@ -6900,6 +6990,7 @@ + if (!safer_flag) + mac_path = ¯o_path; + set_string(".T", device); ++ init_encoding_handler(); + init_charset_table(); + init_hpf_code_table(); + if (!font::load_desc()) +@@ -6924,6 +7015,9 @@ + // In the DESC file a font name of 0 (zero) means leave this + // position empty. + if (strcmp(font::font_name_table[i], "0") != 0) ++#ifdef ENABLE_MULTIBYTE ++ if (!font::is_on_demand(i)) ++#endif + mount_font(j, symbol(font::font_name_table[i])); + curdiv = topdiv = new top_level_diversion; + if (nflag) +@@ -7081,6 +7175,9 @@ + init_request("ecs", save_escape_char); + init_request("el", else_request); + init_request("em", end_macro); ++#ifdef ENABLE_MULTIBYTE ++ init_request("encoding", select_encoding); ++#endif + init_request("eo", escape_off); + init_request("ex", exit_request); + init_request("fchar", define_fallback_character); +@@ -7533,12 +7630,92 @@ + + dictionary charinfo_dictionary(501); + ++#ifdef ENABLE_MULTIBYTE ++struct charinfo_list { ++ struct charinfo_list *next; ++ charinfo *ci; ++} *wcharset_table = NULL; ++ ++/* XXX: use more efficient method? */ ++static charinfo* ++lookup_wcharset_table(wchar wc) ++{ ++ struct charinfo_list *cl; ++ for (cl = wcharset_table; cl; cl = cl->next) { ++ if (cl->ci && cl->ci->get_wchar_code() == wc) ++ return cl->ci; ++ } ++ return NULL; ++} ++ ++static void ++add_wcharset_table(charinfo *ci) ++{ ++ struct charinfo_list *cl = new struct charinfo_list; ++ cl->next = wcharset_table; ++ cl->ci = ci; ++ wcharset_table = cl; ++} ++ ++charinfo *wcharset_table_entry(wchar wc) ++{ ++ if (! is_wchar_code(wc)) ++ return NULL; ++ charinfo *cp = lookup_wcharset_table(wc); ++ if (cp == NULL) { ++ int i = wchar_code(wc); ++ char buf[16]; ++ if (i > 0x100) ++ sprintf(buf, "u%04X", i); ++ else { ++ cp = get_charinfo_by_number(i); ++ if (cp != NULL) ++ return cp; ++ sprintf(buf, "char%d", i); // ??? ++ } ++ symbol nm = symbol(buf); ++ cp = new charinfo(nm); ++ (void)charinfo_dictionary.lookup(nm, cp); ++ cp->set_wchar_code(wc); ++ add_wcharset_table(cp); ++ } ++ return cp; ++} ++ ++static charinfo * ++wchar_charinfo(symbol nm) ++{ ++ const char *p = nm.contents(); ++ if (*p != 'u') { ++ return NULL; ++ } ++ char *pp; ++ wchar wc = make_wchar(strtol(p + 1, &pp, 16)); ++ if (pp < p + 5) ++ return NULL; ++ charinfo *cp = lookup_wcharset_table(wc); ++ if (cp) ++ return cp; ++ /* create on demand */ ++ cp = new charinfo(nm); ++ cp->set_wchar_code(wc); ++ add_wcharset_table(cp); ++ return cp; ++} ++#endif ++ + charinfo *get_charinfo(symbol nm) + { + void *p = charinfo_dictionary.lookup(nm); + if (p != 0) + return (charinfo *)p; ++#ifdef ENABLE_MULTIBYTE ++ charinfo *cp = wchar_charinfo(nm); ++ if (cp == NULL) ++ cp = new charinfo(nm); ++#else + charinfo *cp = new charinfo(nm); ++#endif + (void)charinfo_dictionary.lookup(nm, cp); + return cp; + } +@@ -7548,6 +7725,9 @@ + charinfo::charinfo(symbol s) + : translation(0), mac(0), special_translation(TRANSLATE_NONE), + hyphenation_code(0), flags(0), ascii_code(0), asciify_code(0), ++#ifdef ENABLE_MULTIBYTE ++ wchar_code(0), ++#endif + not_found(0), transparent_translate(1), translate_input(0), + fallback(0), nm(s) + { +@@ -7592,6 +7772,14 @@ + asciify_code = c; + } + ++#ifdef ENABLE_MULTIBYTE ++void charinfo::set_wchar_code(wchar wc) ++{ ++ wchar_code = wc; ++ index = wc; /* XXX: wchar code == index */ ++} ++#endif ++ + macro *charinfo::set_macro(macro *m, int f) + { + macro *tem = mac; +@@ -7647,6 +7835,13 @@ + int font::name_to_index(const char *nm) + { + charinfo *ci; ++#ifdef ENABLE_MULTIBYTE ++ int i = 1; ++ wchar wc = input_encoding->make_wchar(nm[0], (const unsigned char *)nm, &i); ++ if (is_wchar_code(wc)) { ++ ci = wcharset_table_entry(wc); ++ } else ++#endif + if (nm[1] == 0) + ci = charset_table[nm[0] & 0xff]; + else if (nm[0] == '\' && nm[2] == 0) +@@ -7663,3 +7858,10 @@ + { + return get_charinfo_by_number(n)->get_index(); + } ++ ++#ifdef ENABLE_MULTIBYTE ++int font::wchar_index(wchar wc) ++{ ++ return(wcharset_table_entry(wc)->get_index()); ++} ++#endif +diff -Naur groff-1.18.1.4.orig/src/roff/troff/node.cc groff-1.18.1.4/src/roff/troff/node.cc +--- groff-1.18.1.4.orig/src/roff/troff/node.cc 2002-10-03 21:55:09.000000000 +0000 ++++ groff-1.18.1.4/src/roff/troff/node.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -38,6 +38,7 @@ + #include "input.h" + #include "div.h" + #include "geometry.h" ++#include "encoding.h" + + #include "nonposix.h" + +@@ -745,8 +746,15 @@ + int current_font_number; + symbol *font_position; + int nfont_positions; ++#ifdef ENABLE_MULTIBYTE ++ const char *current_encoding; ++#endif + enum { TBUF_SIZE = 256 }; ++#ifdef ENABLE_MULTIBYTE ++ wchar tbuf[TBUF_SIZE]; ++#else + char tbuf[TBUF_SIZE]; ++#endif + int tbuf_len; + int tbuf_kern; + int begun_page; +@@ -756,6 +764,9 @@ + void put(int i); + void put(unsigned int i); + void put(const char *s); ++#ifdef ENABLE_MULTIBYTE ++ void putw(const wchar wc); ++#endif + void set_font(tfont *tf); + void flush_tbuf(); + public: +@@ -799,6 +810,13 @@ + putc(c, fp); + } + ++#ifdef ENABLE_MULTIBYTE ++inline void troff_output_file::putw(wchar wc) ++{ ++ output_encoding->put_wchar(wc, fp); ++} ++#endif ++ + inline void troff_output_file::put(unsigned char c) + { + putc(c, fp); +@@ -956,7 +974,11 @@ + check_output_limits(hpos, vpos - current_size); + + for (int i = 0; i < tbuf_len; i++) ++#ifdef ENABLE_MULTIBYTE ++ putw(tbuf[i]); ++#else + put(tbuf[i]); ++#endif + put('\n'); + tbuf_len = 0; + } +@@ -988,7 +1010,13 @@ + flush_tbuf(); + set_font(tf); + } ++#ifdef ENABLE_MULTIBYTE ++ wchar c = ci->get_wchar_code(); ++ if (c == '\0') ++ c = ci->get_ascii_code(); ++#else + char c = ci->get_ascii_code(); ++#endif + if (c == '\0') { + flush_tbuf(); + do_motion(); +@@ -1014,7 +1042,8 @@ + } + else if (tcommand_flag) { + if (tbuf_len > 0 && hpos == output_hpos && vpos == output_vpos +- && gcol == current_glyph_color && fcol == current_fill_color ++ && (!gcol || gcol == current_glyph_color) ++ && (!fcol || fcol == current_fill_color) + && kk == tbuf_kern + && tbuf_len < TBUF_SIZE) { + check_charinfo(tf, ci); +@@ -1039,17 +1068,26 @@ + check_charinfo(tf, ci); + // check_output_limits(output_hpos, output_vpos); + if (vpos == output_vpos +- && gcol == current_glyph_color && fcol == current_fill_color ++ && (!gcol || gcol == current_glyph_color) ++ && (!fcol || fcol == current_fill_color) + && n > 0 && n < 100 && !force_motion) { + put(char(n/10 + '0')); + put(char(n%10 + '0')); ++#ifdef ENABLE_MULTIBYTE ++ putw(c); ++#else + put(c); ++#endif + output_hpos = hpos; + } + else { + do_motion(); + put('c'); ++#ifdef ENABLE_MULTIBYTE ++ putw(c); ++#else + put(c); ++#endif + } + hpos += w.to_units() + kk; + } +@@ -1063,7 +1101,13 @@ + return; + if (tf != current_tfont) + set_font(tf); ++#ifdef ENABLE_MULTIBYTE ++ wchar c = ci->get_wchar_code(); ++ if (c == '\0') ++ c = ci->get_ascii_code(); ++#else + char c = ci->get_ascii_code(); ++#endif + if (c == '\0') { + do_motion(); + glyph_color(gcol); +@@ -1087,11 +1131,16 @@ + else { + int n = hpos - output_hpos; + if (vpos == output_vpos +- && gcol == current_glyph_color && fcol == current_fill_color ++ && (!gcol || gcol == current_glyph_color) ++ && (!fcol || fcol == current_fill_color) + && n > 0 && n < 100) { + put(char(n/10 + '0')); + put(char(n%10 + '0')); ++#ifdef ENABLE_MULTIBYTE ++ putw(c); ++#else + put(c); ++#endif + output_hpos = hpos; + } + else { +@@ -1099,13 +1148,26 @@ + glyph_color(gcol); + fill_color(fcol); + put('c'); ++#ifdef ENABLE_MULTIBYTE ++ putw(c); ++#else + put(c); ++#endif + } + } + } + + void troff_output_file::set_font(tfont *tf) + { ++#ifdef ENABLE_MULTIBYTE ++ /* XXX */ ++ if (current_encoding != output_encoding->name()) { ++ put("x encoding "); ++ put(output_encoding->name()); ++ put('\n'); ++ current_encoding = output_encoding->name(); ++ } ++#endif + if (current_tfont == tf) + return; + int n = tf->get_input_position(); +@@ -1162,7 +1224,7 @@ + + void troff_output_file::fill_color(color *col) + { +- if ((current_fill_color == col) || !color_flag) ++ if (!col || current_fill_color == col || !color_flag) + return; + flush_tbuf(); + put("DF"); +@@ -1210,7 +1272,7 @@ + + void troff_output_file::glyph_color(color *col) + { +- if ((current_glyph_color == col) || !color_flag) ++ if (!col || current_glyph_color == col || !color_flag) + return; + flush_tbuf(); + put("m"); +@@ -1497,7 +1559,17 @@ + put(' '); + put(vresolution); + put('\n'); ++#ifdef ENABLE_MULTIBYTE ++ current_encoding = output_encoding->name(); ++ put("x init"); ++ if (current_encoding && *current_encoding != '\0') { ++ put(' '); ++ put(current_encoding); ++ } ++ put('\n'); ++#else + put("x init\n"); ++#endif + } + + /* output_file */ +@@ -1777,6 +1849,9 @@ + int same(node *); + const char *type(); + int force_tprint(); ++#ifdef ENABLE_MULTIBYTE ++ node_type get_node_type(); ++#endif + }; + + glyph_node *glyph_node::free_list = 0; +@@ -1802,6 +1877,9 @@ + int same(node *); + const char *type(); + int force_tprint(); ++#ifdef ENABLE_MULTIBYTE ++ node_type get_node_type(); ++#endif + }; + + class kern_pair_node : public node { +@@ -5225,6 +5303,55 @@ + return 0; + } + ++#ifdef ENABLE_MULTIBYTE ++kword_space_node::kword_space_node(color *c, node *x) : word_space_node(0, c, new width_list(0, 0), x) ++{} ++ ++node *kword_space_node::copy() ++{ ++ return new kword_space_node(col); ++} ++newline_space_node::newline_space_node(hunits d, color *c, node *x) : word_space_node(d, c, new width_list(0, 0), x) ++{} ++ ++node *newline_space_node::copy() ++{ ++ return new newline_space_node(n, col); ++} ++ ++const char *kword_space_node::type() ++{ ++ return "kword_space_node"; ++} ++const char *newline_space_node::type() ++{ ++ return "newline_space_node"; ++} ++ ++node_type node::get_node_type() ++{ ++ return NODE_ANOTHER; ++} ++node_type glyph_node::get_node_type() ++{ ++ return NODE_GLYPH; ++} ++ ++node_type ligature_node::get_node_type() ++{ ++ return NODE_ANOTHER; ++} ++ ++node_type kword_space_node::get_node_type() ++{ ++ return NODE_KWORD_SPACE; ++} ++node_type newline_space_node::get_node_type() ++{ ++ return NODE_NEWLINE_SPACE; ++} ++#endif ++ + int unbreakable_space_node::same(node *nd) + { + return n == ((unbreakable_space_node *)nd)->n +@@ -5625,6 +5752,28 @@ + return 0; + } + ++#ifdef ENABLE_MULTIBYTE ++int get_fontset_fontno(int n, wchar wc) ++{ ++ if (n >= 0 && n < font_table_size && font_table[n] != 0) { ++ /* XXX: external_name should be used? */ ++ int fn = font::get_fontset_font(font_table[n]->get_name().contents(), wc); ++ if (fn >= 0) { ++ symbol nm(font::font_name_table[fn]); ++ int nn = symbol_fontno(nm); ++ if (nn < 0) { ++ nn = next_available_font_position(); ++ if (!mount_font(nn, nm)) { ++ return -1; /* XXX */ ++ } ++ } ++ return nn; ++ } ++ } ++ return n; ++} ++#endif ++ + hunits env_digit_width(environment *env) + { + node *n = make_glyph_node(charset_table['0'], env); +diff -Naur groff-1.18.1.4.orig/src/roff/troff/node.h groff-1.18.1.4/src/roff/troff/node.h +--- groff-1.18.1.4.orig/src/roff/troff/node.h 2002-10-02 14:23:28.000000000 +0000 ++++ groff-1.18.1.4/src/roff/troff/node.h 2006-10-18 18:54:44.000000000 +0000 +@@ -20,6 +20,8 @@ + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + ++#include "config.h" ++ + struct hyphen_list { + unsigned char hyphen; + unsigned char breakable; +@@ -31,6 +33,9 @@ + void hyphenate(hyphen_list *, unsigned); + + enum hyphenation_type { HYPHEN_MIDDLE, HYPHEN_BOUNDARY, HYPHEN_INHIBIT }; ++#ifdef ENABLE_MULTIBYTE ++enum node_type {NODE_GLYPH, NODE_KWORD_SPACE, NODE_NEWLINE_SPACE, NODE_ANOTHER}; ++#endif + + class ascii_output_file; + +@@ -106,6 +111,9 @@ + + virtual int same(node *) = 0; + virtual const char *type() = 0; ++#ifdef ENABLE_MULTIBYTE ++ virtual node_type get_node_type(); ++#endif + }; + + inline node::node() +@@ -212,6 +220,24 @@ + int force_tprint(); + }; + ++#ifdef ENABLE_MULTIBYTE ++class kword_space_node : public word_space_node { ++public: ++ kword_space_node(color *, node * = 0); ++ node *copy(); ++ const char *type(); ++ node_type get_node_type(); ++}; ++ ++class newline_space_node : public word_space_node { ++public: ++ newline_space_node(hunits, color *, node * = 0); ++ node *copy(); ++ const char *type(); ++ node_type get_node_type(); ++}; ++#endif ++ + class unbreakable_space_node : public word_space_node { + unbreakable_space_node(hunits, int, color *, node * = 0); + public: +@@ -538,6 +564,9 @@ + node *copy_node_list(node *); + + int get_bold_fontno(int f); ++#ifdef ENABLE_MULTIBYTE ++int get_fontset_fontno(int f, wchar wc); ++#endif + + inline hyphen_list::hyphen_list(unsigned char code, hyphen_list *p) + : hyphen(0), breakable(0), hyphenation_code(code), next(p) +@@ -595,3 +624,4 @@ + + font_family *lookup_family(symbol); + symbol get_font_name(int, environment *); ++ +diff -Naur groff-1.18.1.4.orig/src/roff/troff/token.h groff-1.18.1.4/src/roff/troff/token.h +--- groff-1.18.1.4.orig/src/roff/troff/token.h 2002-06-22 21:31:41.000000000 +0000 ++++ groff-1.18.1.4/src/roff/troff/token.h 2006-10-18 18:54:44.000000000 +0000 +@@ -28,12 +28,18 @@ + symbol nm; + node *nd; + unsigned char c; ++#ifdef ENABLE_MULTIBYTE ++ wchar wc; ++#endif + int val; + units dim; + enum token_type { + TOKEN_BACKSPACE, + TOKEN_BEGIN_TRAP, + TOKEN_CHAR, // a normal printing character ++#ifdef ENABLE_MULTIBYTE ++ TOKEN_WCHAR, // a multibyte character ++#endif + TOKEN_DUMMY, // & + TOKEN_EMPTY, // this is the initial value + TOKEN_END_TRAP, +diff -Naur groff-1.18.1.4.orig/src/roff/troff/troff.h groff-1.18.1.4/src/roff/troff/troff.h +--- groff-1.18.1.4.orig/src/roff/troff/troff.h 2002-06-19 13:20:18.000000000 +0000 ++++ groff-1.18.1.4/src/roff/troff/troff.h 2006-10-18 18:54:44.000000000 +0000 +@@ -28,6 +28,7 @@ + #include <stdlib.h> + #include <errno.h> + ++#include "encoding.h" + #include "assert.h" + #include "color.h" + #include "device.h" +diff -Naur groff-1.18.1.4.orig/src/roff/troff/troff.man groff-1.18.1.4/src/roff/troff/troff.man +--- groff-1.18.1.4.orig/src/roff/troff/troff.man 2002-09-16 08:42:45.000000000 +0000 ++++ groff-1.18.1.4/src/roff/troff/troff.man 2006-10-18 18:54:44.000000000 +0000 +@@ -22,6 +22,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff-base/copyright. ++.. + . + . + ." -------------------------------------------------------------------- +diff -Naur groff-1.18.1.4.orig/src/utils/tfmtodit/tfmtodit.cc groff-1.18.1.4/src/utils/tfmtodit/tfmtodit.cc +--- groff-1.18.1.4.orig/src/utils/tfmtodit/tfmtodit.cc 2001-08-19 21:32:41.000000000 +0000 ++++ groff-1.18.1.4/src/utils/tfmtodit/tfmtodit.cc 2006-10-18 18:54:44.000000000 +0000 +@@ -650,7 +650,7 @@ + gives the groff name of the character, `i' gives its index in + the encoding, which is filled in later (-1 if it does not appear). */ + +-struct { ++struct S { + const char *ch; + int i; + } lig_chars[] = { +@@ -670,7 +670,7 @@ + + // Each possible ligature appears in this table. + +-struct { ++struct S2 { + unsigned char c1, c2, res; + const char *ch; + } lig_table[] = { +diff -Naur groff-1.18.1.4.orig/src/xditview/Dvi.c groff-1.18.1.4/src/xditview/Dvi.c +--- groff-1.18.1.4.orig/src/xditview/Dvi.c 2000-03-01 13:50:49.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/Dvi.c 2006-10-18 18:54:44.000000000 +0000 +@@ -4,6 +4,8 @@ + #endif /* lint */ + #endif /* SABER */ + ++#include "config.h" ++ + /* + * Dvi.c - Dvi display widget + * +@@ -49,6 +51,8 @@ + NBI -adobe-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\ + S -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\ + SS -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\ ++M -misc-fixed-medium-r-normal--*-100-*-*-*-*-jisx0208.1983-0\n\ ++G -misc-fixed-medium-r-normal--*-100-*-*-*-*-jisx0208.1983-0\ + "; + + #define offset(field) XtOffset(DviWidget, field) +@@ -94,6 +98,20 @@ + + static void SaveToFile (); + ++/* font.c */ ++extern void ParseFontMap(); ++extern void DestroyFontMap(); ++extern void ForgetFonts(); ++ ++/* page.c */ ++extern void DestroyFileMap(); ++extern int SearchPagePosition(); ++extern void FileSeek(); ++extern void ForgetPagePositions(); ++ ++/* parse.c */ ++extern int ParseInput(); ++ + DviClassRec dviClassRec = { + { + &widgetClassRec, /* superclass */ +@@ -406,6 +424,7 @@ + return ret; + } + ++void + SetDevice (dw, name) + DviWidget dw; + char *name; +@@ -559,6 +578,9 @@ + DviWidgetClass super = (DviWidgetClass) wc->core_class.superclass; + if (wc->command_class.save == InheritSaveToFile) + wc->command_class.save = super->command_class.save; ++#ifdef ENABLE_MULTIBYTE ++ DviInitLocale(); ++#endif + } + + /* +diff -Naur groff-1.18.1.4.orig/src/xditview/DviChar.c groff-1.18.1.4/src/xditview/DviChar.c +--- groff-1.18.1.4.orig/src/xditview/DviChar.c 2002-04-07 04:48:51.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/DviChar.c 2006-10-18 18:54:44.000000000 +0000 +@@ -5,7 +5,10 @@ + * font indexes and back + */ + +-#include "DviChar.h" ++#include <stdlib.h> ++#include "config.h" ++#include "DviChar.h" ++#include "encoding.h" + + extern char *xmalloc(); + +@@ -21,7 +24,7 @@ + static int standard_maps_loaded = 0; + static void load_standard_maps (); + static int hash_name (); +-static dispose_hash(), compute_hash(); ++static void dispose_hash(), compute_hash(); + + DviCharNameMap * + DviFindMap (encoding) +@@ -58,7 +61,7 @@ + compute_hash (map); + } + +-static ++static void + dispose_hash (map) + DviCharNameMap *map; + { +@@ -88,7 +91,7 @@ + return i; + } + +-static ++static void + compute_hash (map) + DviCharNameMap *map; + { +@@ -120,7 +123,10 @@ + { + int i; + DviCharNameHash *h; +- ++#ifdef ENABLE_MULTIBYTE ++ if (map->char_index) ++ return (*map->char_index)(map, name); ++#endif + i = hash_name (name) % DVI_HASH_SIZE; + for (h = map->buckets[i]; h; h=h->next) + if (!strcmp (h->name, name)) +@@ -128,9 +134,47 @@ + return -1; + } + ++#ifdef ENABLE_MULTIBYTE ++#include <X11/Xlib.h> ++void ++DviChar2XChar2b(int c, XChar2b *xc) ++{ ++ /* XXX: can we assume 'c' is EUC-JP ? */ ++ xc->byte1 = (c >> 8) & 0x7f; ++ xc->byte2 = (c) &0x7f; ++ return; ++} ++ ++int ++DviCharIndexJISX0208_1983(map, name) ++ DviCharNameMap *map; ++ char *name; ++{ ++ /* XXX: can we assume name points EUC-JP chars? */ ++ unsigned char ub = *name, lb = *(name + 1); ++ int wc; ++ wc = (name[0] & 0xff) << 8; ++ wc |= (name[1] & 0xff); ++ return(wc); ++} ++ ++static DviCharNameMap JISX0208_1983_0_map = { ++ "jisx0208.1983-0", ++ 0, ++ DviChar2XChar2b, ++ DviCharIndexJISX0208_1983, ++{ ++{ "DummyEntry", /* 0 */}, ++}}; ++#endif ++ + static DviCharNameMap ISO8859_1_map = { + "iso8859-1", + 0, ++#ifdef ENABLE_MULTIBYTE ++ 0, ++ 0, ++#endif + { + { 0, /* 0 */}, + { 0, /* 1 */}, +@@ -393,6 +437,10 @@ + static DviCharNameMap Adobe_Symbol_map = { + "adobe-fontspecific", + 1, ++#ifdef ENABLE_MULTIBYTE ++ 0, ++ 0, ++#endif + { + { 0, /* 0 */}, + { 0, /* 1 */}, +@@ -659,4 +707,7 @@ + standard_maps_loaded = 1; + DviRegisterMap (&ISO8859_1_map); + DviRegisterMap (&Adobe_Symbol_map); ++#ifdef ENABLE_MULTIBYTE ++ DviRegisterMap (&JISX0208_1983_0_map); ++#endif + } +diff -Naur groff-1.18.1.4.orig/src/xditview/DviChar.h groff-1.18.1.4/src/xditview/DviChar.h +--- groff-1.18.1.4.orig/src/xditview/DviChar.h 2000-02-06 09:38:57.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/DviChar.h 2006-10-18 18:54:44.000000000 +0000 +@@ -10,6 +10,8 @@ + * CharSetRegistry from the CharSetEncoding + */ + ++#include "config.h" ++ + # define DVI_MAX_SYNONYMS 10 + # define DVI_MAP_SIZE 256 + # define DVI_HASH_SIZE 256 +@@ -23,6 +25,10 @@ + typedef struct _dviCharNameMap { + char *encoding; + int special; ++#ifdef ENABLE_MULTIBYTE ++ void (*char2XChar2b)(/* int c, XChar2b *xc */); ++ int (*char_index)(/* struct _dviCharNameMap *map, char *name */); ++#endif + char *dvi_names[DVI_MAP_SIZE][DVI_MAX_SYNONYMS]; + DviCharNameHash *buckets[DVI_HASH_SIZE]; + } DviCharNameMap; +diff -Naur groff-1.18.1.4.orig/src/xditview/DviP.h groff-1.18.1.4/src/xditview/DviP.h +--- groff-1.18.1.4.orig/src/xditview/DviP.h 2000-02-06 09:38:57.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/DviP.h 2006-10-18 18:54:44.000000000 +0000 +@@ -8,6 +8,7 @@ + + #ifndef _XtDviP_h + #define _XtDviP_h ++#include "config.h" + + #include "Dvi.h" + #include "DviChar.h" +@@ -89,9 +90,17 @@ + #define DVI_CHAR_CACHE_SIZE 1024 + + typedef struct _dviCharCache { ++#ifdef ENABLE_MULTIBYTE ++ XTextItem16 cache[DVI_TEXT_CACHE_SIZE]; ++#else + XTextItem cache[DVI_TEXT_CACHE_SIZE]; ++#endif + char adjustable[DVI_TEXT_CACHE_SIZE]; ++#ifdef ENABLE_MULTIBYTE ++ XChar2b char_cache[DVI_CHAR_CACHE_SIZE]; ++#else + char char_cache[DVI_CHAR_CACHE_SIZE]; ++#endif + int index; + int max; + int char_index; +@@ -182,6 +191,7 @@ + int word_flag; + } DviPart; + ++extern int DviGetAndPut(); + #define DviGetIn(dw,cp)\ + (dw->dvi.tmpFile ? (\ + DviGetAndPut (dw, cp) \ +@@ -228,6 +238,11 @@ + extern DeviceFont *QueryDeviceFont (); + + extern char *GetWord(), *GetLine(); ++ ++#ifdef ENABLE_MULTIBYTE ++extern void DviInitLocale(); ++extern int DviGEtCharacter(); ++#endif + #endif /* _XtDviP_h */ + + +diff -Naur groff-1.18.1.4.orig/src/xditview/FontMap.jisx0208 groff-1.18.1.4/src/xditview/FontMap.jisx0208 +--- groff-1.18.1.4.orig/src/xditview/FontMap.jisx0208 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/FontMap.jisx0208 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,2 @@ ++M -misc-fixed-medium-r-normal--*-100-*-*-*-*-jisx0208.1983-0 ++G -misc-fixed-medium-r-normal--*-100-*-*-*-*-jisx0208.1983-0 +diff -Naur groff-1.18.1.4.orig/src/xditview/GXditview-ad.h groff-1.18.1.4/src/xditview/GXditview-ad.h +--- groff-1.18.1.4.orig/src/xditview/GXditview-ad.h 2000-02-06 09:39:04.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/GXditview-ad.h 2006-10-18 18:54:44.000000000 +0000 +@@ -50,3 +50,24 @@ + "GXditview.promptShell.promptDialog.cancel.label: Cancel", + "GXditview.promptShell.promptDialog.cancel.translations: #override \ + <BtnUp>: Cancel() unset()", ++"GXditview*fontMap: \ ++TR -adobe-times-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++TI -adobe-times-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\ ++TB -adobe-times-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++TBI -adobe-times-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\ ++CR -adobe-courier-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++CI -adobe-courier-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\ ++CB -adobe-courier-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++CBI -adobe-courier-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\ ++HR -adobe-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++HI -adobe-helvetica-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\ ++HB -adobe-helvetica-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++HBI -adobe-helvetica-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\ ++NR -adobe-new century schoolbook-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++NI -adobe-new century schoolbook-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\ ++NB -adobe-new century schoolbook-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++NBI -adobe-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\ ++S -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\ ++SS -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\ ++M -misc-fixed-medium-r-normal--*-100-*-*-*-*-jisx0208.1983-0\n\ ++G -misc-fixed-medium-r-normal--*-100-*-*-*-*-jisx0208.1983-0", +diff -Naur groff-1.18.1.4.orig/src/xditview/GXditview.ad groff-1.18.1.4/src/xditview/GXditview.ad +--- groff-1.18.1.4.orig/src/xditview/GXditview.ad 2000-02-06 09:38:57.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/GXditview.ad 2006-10-18 18:54:44.000000000 +0000 +@@ -55,3 +55,25 @@ + GXditview.promptShell.promptDialog.cancel.label: Cancel + GXditview.promptShell.promptDialog.cancel.translations: #override \ + <BtnUp>: Cancel() unset() ++ ++GXditview*fontMap: \ ++TR -adobe-times-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++TI -adobe-times-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\ ++TB -adobe-times-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++TBI -adobe-times-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\ ++CR -adobe-courier-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++CI -adobe-courier-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\ ++CB -adobe-courier-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++CBI -adobe-courier-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\ ++HR -adobe-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++HI -adobe-helvetica-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\ ++HB -adobe-helvetica-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++HBI -adobe-helvetica-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\ ++NR -adobe-new century schoolbook-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++NI -adobe-new century schoolbook-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\ ++NB -adobe-new century schoolbook-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ ++NBI -adobe-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\ ++S -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\ ++SS -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\ ++M -misc-fixed-medium-r-normal--*-100-*-*-*-*-jisx0208.1983-0\n\ ++G -misc-fixed-medium-r-normal--*-100-*-*-*-*-jisx0208.1983-0 +diff -Naur groff-1.18.1.4.orig/src/xditview/XFontName.c groff-1.18.1.4/src/xditview/XFontName.c +--- groff-1.18.1.4.orig/src/xditview/XFontName.c 2000-02-06 09:38:58.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/XFontName.c 2006-10-18 18:54:44.000000000 +0000 +@@ -225,6 +225,7 @@ + return True; + } + ++Bool + XCopyFontName (name1, name2, fontNameAttributes) + XFontName *name1, *name2; + unsigned int fontNameAttributes; +diff -Naur groff-1.18.1.4.orig/src/xditview/config.h groff-1.18.1.4/src/xditview/config.h +--- groff-1.18.1.4.orig/src/xditview/config.h 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/config.h 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,4 @@ ++#ifndef _config_h ++#include "../include/config.h" ++#define _config_h ++#endif +diff -Naur groff-1.18.1.4.orig/src/xditview/device.c groff-1.18.1.4/src/xditview/device.c +--- groff-1.18.1.4.orig/src/xditview/device.c 2000-12-02 21:12:53.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/device.c 2006-10-18 18:54:44.000000000 +0000 +@@ -2,10 +2,12 @@ + + #include <stdio.h> + #include <ctype.h> ++#include <stdlib.h> + + #include <X11/Xos.h> + #include <X11/Intrinsic.h> + ++#include "config.h" + #include "device.h" + + #ifndef FONTPATH +@@ -48,6 +50,9 @@ + Device *dev; + struct charinfo *char_table[CHAR_TABLE_SIZE]; + struct charinfo *code_table[256]; ++#ifdef ENABLE_MULTIBYTE ++ struct charrange *range; ++#endif + }; + + struct charinfo { +@@ -71,6 +76,15 @@ + static struct charinfo *add_char(); + static int read_charset_section(); + static char *canonicalize_name(); ++#ifdef ENABLE_MULTIBYTE ++struct charrange { ++ struct charrange *next; ++ int width; ++ int start_code; ++ int end_code; ++}; ++static void add_charrange(); ++#endif + + static + Device *new_device(name) +@@ -256,6 +270,9 @@ + f->char_table[i] = 0; + for (i = 0; i < 256; i++) + f->code_table[i] = 0; ++#ifdef ENABLE_MULTIBYTE ++ f->range = 0; ++#endif + return f; + } + +@@ -267,6 +284,15 @@ + + if (!f) + return; ++#ifdef ENABLE_MULTIBYTE ++ { ++ struct charrange *cp, *cp2; ++ for (cp = f->range; cp != NULL; cp = cp2) { ++ cp2 = cp->next; ++ XtFree((char *)cp); ++ } ++ } ++#endif + XtFree(f->name); + for (i = 0; i < CHAR_TABLE_SIZE; i++) { + struct charinfo *ptr = f->char_table[i]; +@@ -342,6 +368,20 @@ + { + struct charinfo *p; + ++#ifdef ENABLE_MULTIBYTE ++ int wc; ++ extern DviWCharP(); ++ if (DviWCharP(name, &wc)) { ++ struct charrange *rp; ++ for (rp = f->range; rp != NULL; rp = rp->next) { ++ if (rp->start_code <= wc && wc <= rp->end_code) { ++ *widthp = scale_round(rp->width, ps, ++ f->dev->unitwidth); ++ return 1; ++ } ++ } ++ } ++#endif + name = canonicalize_name(name); + for (p = f->char_table[hash_name(name) % CHAR_TABLE_SIZE];; p = p->next) { + if (!p) +@@ -424,6 +464,22 @@ + return ci; + } + ++#ifdef ENABLE_MULTIBYTE ++static void ++add_charrange(f, width, start_code, end_code) ++ DeviceFont *f; ++ int width, start_code, end_code; ++{ ++ struct charrange *ci; ++ ci = (struct charrange *)XtMalloc(sizeof(struct charrange)); ++ ci->start_code = start_code; ++ ci->end_code = end_code; ++ ci->width = width; ++ ci->next = f->range; ++ f->range = ci; ++} ++#endif ++ + /* Return non-zero for success. */ + + static +@@ -439,11 +495,31 @@ + int width; + int code; + char *p; ++#ifdef ENABLE_MULTIBYTE ++ int scode, ecode; ++#endif + + current_lineno++; + name = strtok(buf, WS); + if (!name) + continue; /* ignore blank lines */ ++#ifdef ENABLE_MULTIBYTE ++ if (sscanf(name, "u%X..u%X", &scode, &ecode) == 2) { ++ p = strtok((char *)0, WS); ++ if (!p) ++ break; ++ if (sscanf(p, "%d", &width) != 1) { ++ error("bad width field"); ++ return 0; ++ } ++ p = strtok((char *)0, WS); ++ if (!p) { ++ error("missing type field"); ++ return 0; ++ } ++ add_charrange(f, width, scode, ecode); ++ } else { ++#endif + p = strtok((char *)0, WS); + if (!p) /* end of charset section */ + break; +@@ -479,6 +555,9 @@ + } + last_charinfo = add_char(f, name, width, code); + } ++#ifdef ENABLE_MULTIBYTE ++ } ++#endif + } + return 1; + } +@@ -559,7 +638,7 @@ + FILE *open_device_file(device_name, file_name, result) + char *device_name, *file_name, **result; + { +- char *buf, *path; ++ char *buf; + FILE *fp; + + buf = XtMalloc(3 + strlen(device_name) + 1 + strlen(file_name) + 1); +diff -Naur groff-1.18.1.4.orig/src/xditview/draw.c groff-1.18.1.4/src/xditview/draw.c +--- groff-1.18.1.4.orig/src/xditview/draw.c 2000-02-06 09:39:00.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/draw.c 2006-10-18 18:54:44.000000000 +0000 +@@ -10,6 +10,7 @@ + #include <stdio.h> + #include <ctype.h> + #include <math.h> ++#include "config.h" + + /* math.h on a Sequent doesn't define M_PI, apparently */ + #ifndef M_PI +@@ -17,6 +18,7 @@ + #endif + + #include "DviP.h" ++#include "encoding.h" /* XXX */ + + #define DeviceToX(dw, n) ((int)((n) * (dw)->dvi.scale_factor + .5)) + #define XPos(dw) (DeviceToX((dw), (dw)->dvi.state->x - \ +@@ -25,6 +27,10 @@ + + static int FakeCharacter(); + ++/* font.c */ ++extern int MaxFontPosition(); ++ ++void + HorizontalMove(dw, delta) + DviWidget dw; + int delta; +@@ -32,6 +38,7 @@ + dw->dvi.state->x += delta; + } + ++void + HorizontalGoto(dw, NewPosition) + DviWidget dw; + int NewPosition; +@@ -39,6 +46,7 @@ + dw->dvi.state->x = NewPosition; + } + ++void + VerticalMove(dw, delta) + DviWidget dw; + int delta; +@@ -46,6 +54,7 @@ + dw->dvi.state->y += delta; + } + ++void + VerticalGoto(dw, NewPosition) + DviWidget dw; + int NewPosition; +@@ -53,6 +62,7 @@ + dw->dvi.state->y = NewPosition; + } + ++void + AdjustCacheDeltas (dw) + DviWidget dw; + { +@@ -94,14 +104,21 @@ + } + } + ++void + FlushCharCache (dw) + DviWidget dw; + { + if (dw->dvi.cache.char_index != 0) { + AdjustCacheDeltas (dw); ++#ifdef ENABLE_MULTIBYTE ++ XDrawText16 (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, ++ dw->dvi.cache.start_x, dw->dvi.cache.start_y, ++ dw->dvi.cache.cache, dw->dvi.cache.index + 1); ++#else + XDrawText (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, + dw->dvi.cache.start_x, dw->dvi.cache.start_y, + dw->dvi.cache.cache, dw->dvi.cache.index + 1); ++#endif + } + dw->dvi.cache.index = 0; + dw->dvi.cache.max = DVI_TEXT_CACHE_SIZE; +@@ -115,6 +132,7 @@ + dw->dvi.cache.start_y = dw->dvi.cache.y = YPos (dw); + } + ++void + Newline (dw) + DviWidget dw; + { +@@ -123,6 +141,7 @@ + dw->dvi.word_flag = 0; + } + ++void + Word (dw) + DviWidget dw; + { +@@ -135,7 +154,6 @@ + :\ + (fi)->max_bounds.width\ + ) +- + + static + int charExists (fi, c) +@@ -152,14 +170,25 @@ + || p->ascent != 0 || p->descent != 0 || p->attributes != 0); + } + +-static ++static void ++#ifdef ENABLE_MULTIBYTE ++DoCharacter (dw, c, wid, char2xchar2b) ++#else + DoCharacter (dw, c, wid) ++#endif + DviWidget dw; + int c; + int wid; /* width in device units */ ++#ifdef ENABLE_MULTIBYTE ++ void (*char2xchar2b)(); ++#endif + { + register XFontStruct *font; ++#ifdef ENABLE_MULTIBYTE ++ register XTextItem16 *text; ++#else + register XTextItem *text; ++#endif + int x, y; + + x = XPos(dw); +@@ -225,9 +254,25 @@ + text->font = None; + dw->dvi.cache.x += text->delta; + } ++#ifdef ENABLE_MULTIBYTE ++ if (charExists(font, c) || char2xchar2b) { ++#else + if (charExists(font, c)) { ++#endif + int w; ++#ifdef ENABLE_MULTIBYTE ++ if (char2xchar2b) { ++ (*char2xchar2b)(c, ++ &dw->dvi.cache.char_cache[dw->dvi.cache.char_index++]); ++ } else { ++ dw->dvi.cache.char_cache[dw->dvi.cache.char_index]. ++ byte1 = (unsigned char)'\0'; ++ dw->dvi.cache.char_cache[dw->dvi.cache.char_index++]. ++ byte2 = (unsigned char)c; ++ } ++#else + dw->dvi.cache.char_cache[dw->dvi.cache.char_index++] = (char) c; ++#endif + ++text->nchars; + w = charWidth(font, c); + dw->dvi.cache.x += w; +@@ -291,7 +336,11 @@ + if (map) + c = DviCharIndex (map, buf); + if (c >= 0) ++#ifdef ENABLE_MULTIBYTE ++ DoCharacter (dw, c, wid, map->char2XChar2b); ++#else + DoCharacter (dw, c, wid); ++#endif + else + (void) FakeCharacter (dw, buf, wid); + dw->dvi.state->font_number = prevFont; +@@ -345,6 +394,7 @@ + return 1; + } + ++void + PutNumberedCharacter (dw, c) + DviWidget dw; + int c; +@@ -368,7 +418,11 @@ + dw->dvi.state->font_size, c, &wid)) + return; + if (dw->dvi.native) { ++#ifdef ENABLE_MULTIBYTE ++ DoCharacter (dw, c, wid, NULL); ++#else + DoCharacter (dw, c, wid); ++#endif + return; + } + map = QueryFontMap (dw, dw->dvi.state->font_number); +@@ -379,7 +433,11 @@ + name = device_name_for_code ((DeviceFont *)0, c)) { + int code = DviCharIndex (map, name); + if (code >= 0) { ++#ifdef ENABLE_MULTIBYTE ++ DoCharacter (dw, code, wid, map->char2XChar2b); ++#else + DoCharacter (dw, code, wid); ++#endif + break; + } + if (FakeCharacter (dw, name, wid)) +@@ -387,13 +445,14 @@ + } + } + ++void + ClearPage (dw) + DviWidget dw; + { + XClearWindow (XtDisplay (dw), XtWindow (dw)); + } + +-static ++static void + setGC (dw) + DviWidget dw; + { +@@ -417,7 +476,7 @@ + } + } + +-static ++static void + setFillGC (dw) + DviWidget dw; + { +@@ -444,6 +503,7 @@ + } + } + ++void + DrawLine (dw, x, y) + DviWidget dw; + int x, y; +@@ -459,6 +519,7 @@ + xp + DeviceToX (dw, x), yp + DeviceToX (dw, y)); + } + ++void + DrawCircle (dw, diam) + DviWidget dw; + int diam; +@@ -473,6 +534,7 @@ + d, d, 0, 64*360); + } + ++void + DrawFilledCircle (dw, diam) + DviWidget dw; + int diam; +@@ -490,6 +552,7 @@ + d, d, 0, 64*360); + } + ++void + DrawEllipse (dw, a, b) + DviWidget dw; + int a, b; +@@ -501,6 +564,7 @@ + DeviceToX (dw, a), DeviceToX (dw, b), 0, 64*360); + } + ++void + DrawFilledEllipse (dw, a, b) + DviWidget dw; + int a, b; +@@ -515,6 +579,7 @@ + DeviceToX (dw, a), DeviceToX (dw, b), 0, 64*360); + } + ++void + DrawArc (dw, x0, y0, x1, y1) + DviWidget dw; + int x0, y0, x1, y1; +@@ -541,6 +606,7 @@ + rad*2, rad*2, angle1, angle2); + } + ++void + DrawPolygon (dw, v, n) + DviWidget dw; + int *v; +@@ -572,7 +638,7 @@ + XtFree((char *)p); + } + +- ++void + DrawFilledPolygon (dw, v, n) + DviWidget dw; + int *v; +@@ -608,7 +674,7 @@ + + #define POINTS_MAX 10000 + +-static ++static void + appendPoint(points, pointi, x, y) + XPoint *points; + int *pointi; +@@ -623,7 +689,7 @@ + + #define FLATNESS 1 + +-static ++static void + flattenCurve(points, pointi, x2, y2, x3, y3, x4, y4) + XPoint *points; + int *pointi; +@@ -659,7 +725,7 @@ + } + } + +- ++void + DrawSpline (dw, v, n) + DviWidget dw; + int *v; +diff -Naur groff-1.18.1.4.orig/src/xditview/encoding.h groff-1.18.1.4/src/xditview/encoding.h +--- groff-1.18.1.4.orig/src/xditview/encoding.h 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/encoding.h 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,31 @@ ++// -*- C++ -*- ++/* Copyright (c) 2001 Fumitoshi UKAI <ukai@debian.or.jp> ++ ++This file is part of groff. ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation; either version 2, or (at your option) any later ++version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; if not, write to the Free Software ++Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ ++ ++#ifndef ENCODING_H ++#define ENCODING_H ++ ++#include "config.h" ++ ++#ifdef ENABLE_MULTIBYTE ++typedef unsigned int wchar; ++#else ++typedef char wchar; ++#endif ++ ++#endif +diff -Naur groff-1.18.1.4.orig/src/xditview/font.c groff-1.18.1.4/src/xditview/font.c +--- groff-1.18.1.4.orig/src/xditview/font.c 2000-02-06 09:39:01.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/font.c 2006-10-18 18:54:44.000000000 +0000 +@@ -9,10 +9,16 @@ + #include <X11/StringDefs.h> + #include <stdio.h> + #include <ctype.h> ++#include <stdlib.h> + #include "DviP.h" + #include "XFontName.h" + +-static DisposeFontSizes(); ++static void DisposeFontSizes(); ++void DestroyFontMap(); ++ ++/* XFontName.c */ ++extern Bool XParseFontName(); ++extern Bool XFormatFontName(); + + static char * + savestr (s) +@@ -115,7 +121,7 @@ + # define SizePosition 8 + # define EncodingPosition 13 + +-static ++static int + ConvertFontNameToSize (n) + char *n; + { +@@ -191,7 +197,7 @@ + return sizes; + } + +-static ++static void + DisposeFontSizes (dw, fs) + DviWidget dw; + DviFontSizeList *fs; +@@ -263,6 +269,7 @@ + return f; + } + ++void + ForgetFonts (dw) + DviWidget dw; + { +@@ -322,6 +329,7 @@ + } + #endif + ++void + ParseFontMap (dw) + DviWidget dw; + { +@@ -357,6 +365,7 @@ + dw->dvi.font_map = fm; + } + ++void + DestroyFontMap (font_map) + DviFontMap *font_map; + { +@@ -374,6 +383,7 @@ + + /* ARGSUSED */ + ++void + SetFontPosition (dw, position, dvi_name, extra) + DviWidget dw; + int position; +diff -Naur groff-1.18.1.4.orig/src/xditview/lex.c groff-1.18.1.4/src/xditview/lex.c +--- groff-1.18.1.4.orig/src/xditview/lex.c 2000-02-06 09:39:02.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/lex.c 2006-10-18 18:54:44.000000000 +0000 +@@ -2,8 +2,10 @@ + #include <X11/IntrinsicP.h> + #include <X11/StringDefs.h> + #include <stdio.h> ++#include "config.h" + #include "DviP.h" + ++int + DviGetAndPut(dw, cp) + DviWidget dw; + int *cp; +@@ -67,6 +69,7 @@ + return Buffer; + } + ++int + GetNumber(dw) + DviWidget dw; + { +@@ -90,6 +93,98 @@ + DviUngetC(dw, c); + return i; + } ++ ++#ifdef ENABLE_MULTIBYTE ++#include <locale.h> ++#include <langinfo.h> ++#include <iconv.h> ++#include <errno.h> ++ ++static iconv_t icd; ++void ++DviInitLocale() ++{ ++ char *enc; ++ setlocale(LC_ALL, ""); ++ enc = nl_langinfo(CODESET); ++ icd = iconv_open("UCS-2BE", enc); ++} ++ ++int ++DviGetCharacter(dw, cp) ++ DviWidget dw; ++ char *cp; ++{ ++ char inbuf[8]; ++ char outbuf[8]; ++ char *inp, *outp; ++ size_t inbytesleft, outbytesleft = 8; ++ int i = 0; ++ int j; ++ int wc = 0; ++ int c; ++ size_t r; ++ ++ while (wc == 0) { ++ DviGetC(dw, &c); ++ if (c == EOF) ++ return EOF; ++ inbuf[i++] = c; ++ inbytesleft = i; ++ outbytesleft = BUFSIZ; ++ inp = inbuf; ++ outp = outbuf; ++ r = iconv(icd, &inp, &inbytesleft, &outp, &outbytesleft); ++ if (r == (size_t)-1) { ++ if (errno == EILSEQ) { ++ /* illegal sequence */ ++ } else if (errno == EINVAL) { ++ /* incomplete sequence */ ++ continue; ++ } else if (errno == E2BIG) { ++ /* no room to output? */ ++ ++ } ++ DviUngetC(dw, c); ++ } ++ /* ok - pass inbuf to cp */ ++ for (j = 0; j < i; j++) { ++ cp[j] = inbuf[j]; ++ } ++ cp[j] = '\0'; ++ return i; ++ } ++ /* NOT REACHED */ ++} ++ ++int ++DviWCharP(char *name, int *wc) ++{ ++ char outbuf[BUFSIZ]; ++ char *inp, *outp; ++ int inbytesleft, outbytesleft; ++ size_t r; ++ *wc = 0; ++ inp = name; ++ inbytesleft = strlen(name); ++ outp = outbuf; ++ outbytesleft = sizeof(outbuf)-1; ++ r = iconv(icd, &inp, &inbytesleft, &outp, &outbytesleft); ++ if (r < 0) { ++ return 0; ++ } ++ /* UCS-2 check */ ++ if (outbuf + 2 != outp) { ++ return 0; ++ } ++ for (inp = outbuf; inp < outp; inp++) { ++ *wc <<= 8; ++ *wc |= (*inp) & 0x0ff; ++ } ++ return 1; ++} ++ ++#endif + + /* + Local Variables: +diff -Naur groff-1.18.1.4.orig/src/xditview/page.c groff-1.18.1.4/src/xditview/page.c +--- groff-1.18.1.4.orig/src/xditview/page.c 2000-02-06 09:39:02.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/page.c 2006-10-18 18:54:44.000000000 +0000 +@@ -28,6 +28,7 @@ + return m; + } + ++void + DestroyFileMap (m) + DviFileMap *m; + { +@@ -39,6 +40,7 @@ + } + } + ++void + ForgetPagePositions (dw) + DviWidget dw; + { +@@ -46,6 +48,7 @@ + dw->dvi.file_map = 0; + } + ++void + RememberPagePosition(dw, number) + DviWidget dw; + int number; +@@ -64,6 +67,7 @@ + m->position = ftell (dw->dvi.file); + } + ++int + SearchPagePosition (dw, number) + DviWidget dw; + int number; +@@ -75,6 +79,7 @@ + return m->position; + } + ++void + FileSeek(dw, position) + DviWidget dw; + long position; +diff -Naur groff-1.18.1.4.orig/src/xditview/parse.c groff-1.18.1.4/src/xditview/parse.c +--- groff-1.18.1.4.orig/src/xditview/parse.c 2002-04-07 04:48:51.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/parse.c 2006-10-18 18:54:44.000000000 +0000 +@@ -9,15 +9,49 @@ + #include <X11/StringDefs.h> + #include <stdio.h> + #include <ctype.h> ++#include "config.h" + #include "DviP.h" ++#include "encoding.h" + + static int StopSeen = 0; +-static ParseDrawFunction(), ParseDeviceControl(); +-static push_env(), pop_env(); ++static void ParseDrawFunction(), ParseDeviceControl(); ++static void push_env(), pop_env(); ++ ++/* draw.c */ ++extern int PutCharacter(); ++extern int PutNumberedCharacter(); ++extern void HorizontalGoto(); ++extern void Word(); ++extern void VerticalGoto(); ++extern void VerticalMove(); ++extern void FlushCharCache(); ++extern void Newline(); ++extern void DrawLine(); ++extern void DrawCircle(); ++extern void DrawFilledCircle(); ++extern void DrawEllipse(); ++extern void DrawFilledEllipse(); ++extern void DrawArc(); ++extern void DrawPolygon(); ++extern void DrawFilledPolygon(); ++extern void DrawSpline(); ++ ++/* Dvi.c */ ++extern void SetDevice(); ++ ++/* page.c */ ++extern void RememberPagePosition(); ++ ++/* font.c */ ++extern void SetFontPosition(); ++ ++/* lex.c */ ++extern int GetNumber(); + + #define HorizontalMove(dw, delta) ((dw)->dvi.state->x += (delta)) + + ++int + ParseInput(dw) + register DviWidget dw; + { +@@ -57,11 +91,17 @@ + DviGetC(dw,&otherc)-'0'); + /* fall through */ + case 'c': /* single ascii character */ ++#ifdef ENABLE_MULTIBYTE ++ DviGetCharacter(dw, Buffer); ++ if (Buffer[0] == ' ') ++ break; ++#else + DviGetC(dw,&c); + if (c == ' ') + break; + Buffer[0] = c; + Buffer[1] = '\0'; ++#endif + (void) PutCharacter (dw, Buffer); + break; + case 'C': +@@ -69,10 +109,15 @@ + (void) PutCharacter (dw, Buffer); + break; + case 't': ++#ifdef ENABLE_MULTIBYTE ++ while (DviGetCharacter(dw, Buffer) != EOF ++ && Buffer[0] != ' ' && Buffer[0] != '\n') { ++#else + Buffer[1] = '\0'; + while (DviGetC (dw, &c) != EOF + && c != ' ' && c != '\n') { + Buffer[0] = c; ++#endif + HorizontalMove (dw, PutCharacter (dw, Buffer)); + } + break; +@@ -158,7 +203,7 @@ + } + } + +-static ++static void + push_env(dw) + DviWidget dw; + { +@@ -177,7 +222,7 @@ + dw->dvi.state = new; + } + +-static ++static void + pop_env(dw) + DviWidget dw; + { +@@ -188,7 +233,7 @@ + XtFree ((char *) old); + } + +-static ++static void + InitTypesetter (dw) + DviWidget dw; + { +@@ -200,7 +245,7 @@ + + #define DRAW_ARGS_MAX 128 + +-static ++static void + ParseDrawFunction(dw, buf) + DviWidget dw; + char *buf; +@@ -284,13 +329,12 @@ + } + } + +-static ++static void + ParseDeviceControl(dw) /* Parse the x commands */ + DviWidget dw; + { + char str[20], str1[50]; + int c, n; +- extern int LastPage, CurrentPage; + + GetWord (dw, str, 20); + switch (str[0]) { /* crude for now */ +diff -Naur groff-1.18.1.4.orig/src/xditview/xditview.c groff-1.18.1.4/src/xditview/xditview.c +--- groff-1.18.1.4.orig/src/xditview/xditview.c 2002-06-23 14:11:55.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/xditview.c 2006-10-18 18:54:44.000000000 +0000 +@@ -46,6 +46,7 @@ + #include <X11/Xaw/SimpleMenu.h> + #include <X11/Xaw/SmeBSB.h> + ++#include <stdlib.h> + #include <signal.h> + + #include "Dvi.h" +@@ -101,7 +102,7 @@ + * Report the syntax for calling xditview. + */ + +-static ++static void + Syntax(call) + char *call; + { +@@ -126,12 +127,12 @@ + char *name; + void (*function)(); + } menuEntries[] = { +- "nextPage", NextPage, +- "previousPage", PreviousPage, +- "selectPage", SelectPage, +- "print", Print, +- "openFile", OpenFile, +- "quit", Quit, ++ {"nextPage", NextPage}, ++ {"previousPage",PreviousPage}, ++ {"selectPage", SelectPage}, ++ {"print", Print}, ++ {"openFile", OpenFile}, ++ {"quit", Quit}, + }; + + static void NextPageAction(), PreviousPageAction(), SelectPageAction(); +@@ -139,17 +140,18 @@ + static void AcceptAction(), CancelAction(); + static void PrintAction(); + static void RerasterizeAction(); ++static void MakePrompt(); + + XtActionsRec xditview_actions[] = { +- "NextPage", NextPageAction, +- "PreviousPage", PreviousPageAction, +- "SelectPage", SelectPageAction, +- "Print", PrintAction, +- "OpenFile", OpenFileAction, +- "Rerasterize", RerasterizeAction, +- "Quit", QuitAction, +- "Accept", AcceptAction, +- "Cancel", CancelAction, ++ {"NextPage", NextPageAction}, ++ {"PreviousPage", PreviousPageAction}, ++ {"SelectPage", SelectPageAction}, ++ {"Print", PrintAction}, ++ {"OpenFile", OpenFileAction}, ++ {"Rerasterize", RerasterizeAction}, ++ {"Quit", QuitAction}, ++ {"Accept", AcceptAction}, ++ {"Cancel", CancelAction}, + }; + + #define MenuNextPage 0 +@@ -318,6 +320,7 @@ + + static char fileBuf[1024]; + ++static void + ResetMenuEntry (entry) + Widget entry; + { +@@ -516,6 +519,7 @@ + CancelAction (widget, event, params, num_params); + } + ++static void + MakePrompt(centerw, prompt, func, def) + Widget centerw; + char *prompt; +diff -Naur groff-1.18.1.4.orig/src/xditview/xtotroff.c groff-1.18.1.4/src/xditview/xtotroff.c +--- groff-1.18.1.4.orig/src/xditview/xtotroff.c 2000-03-01 13:50:49.000000000 +0000 ++++ groff-1.18.1.4/src/xditview/xtotroff.c 2006-10-18 18:54:44.000000000 +0000 +@@ -2,6 +2,7 @@ + * xtotroff + * + * convert X font metrics into troff font metrics ++ * XXX: ENABLE_MULTIBYTE may not work yet + */ + + #include <X11/Xlib.h> +@@ -10,6 +11,7 @@ + #include <unistd.h> + #include <stdlib.h> + #include <fcntl.h> ++#include "config.h" + #include "XFontName.h" + #include "DviChar.h" + +@@ -171,6 +173,47 @@ + fprintf (out, "spacewidth %d\n", w); + } + fprintf (out, "charset\n"); ++#if 0 /* def ENABLE_MULTIBYTE */ ++ if (fi->min_byte1 != 0 || fi->max_byte1 != 0) { ++ /* ++ * 2 byte code font. ++ */ ++ int N; ++ int D = fi->max_char_or_byte2 - fi->min_char_or_byte2 + 1; ++ int max = (fi->max_byte1 - fi->min_byte1 + 1) * ++ (fi->max_char_or_byte2 - fi->min_char_or_byte2 + 1); ++ unsigned byte1; ++ unsigned byte2; ++ unsigned int euc_code; ++ ++ for (N = 0; N < max; N++) { ++ byte1 = N / D + fi->min_byte1; ++ byte2 = N % D + fi->min_char_or_byte2; ++ euc_code = ((byte1 << 8) | byte2) & 0xffff | 0x8080; ++ wid = fi->max_bounds.width; ++ fputc(byte1 & 0xff | 0x80, out);/* output EUC code */ ++ fputc(byte2 & 0xff | 0x80, out);/* output EUC code */ ++ fprintf (out, "\t%d", wid); ++ if (groff_flag) { ++ int param[5]; ++ param[0] = fi->max_bounds.ascent; ++ param[1] = fi->max_bounds.descent; ++ param[2] = 0 /* charRBearing (fi, c) - wid */; ++ param[3] = 0 /* charLBearing (fi, c) */; ++ param[4] = 0; /* XXX */ ++ for (j = 0; j < 5; j++) ++ if (param[j] < 0) ++ param[j] = 0; ++ for (j = 4; j >= 0; j--) ++ if (param[j] != 0) ++ break; ++ for (k = 0; k <= j; k++) ++ fprintf (out, ",%d", param[k]); ++ } ++ fprintf (out, "\t0\t%#x\n", euc_code); ++ } ++ } else ++#endif /* ENABLE_MULTIBYTE */ + for (c = fi->min_char_or_byte2; c <= fi->max_char_or_byte2; c++) { + char *name = DviCharName (char_map,c,0); + if (charExists (fi, c) && (groff_flag || name)) { +diff -Naur groff-1.18.1.4.orig/stamp-h groff-1.18.1.4/stamp-h +--- groff-1.18.1.4.orig/stamp-h 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/stamp-h 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1 @@ ++timestamp +diff -Naur groff-1.18.1.4.orig/tmac/Makefile.sub groff-1.18.1.4/tmac/Makefile.sub +--- groff-1.18.1.4.orig/tmac/Makefile.sub 2002-07-13 20:41:16.000000000 +0000 ++++ groff-1.18.1.4/tmac/Makefile.sub 2006-10-18 18:54:44.000000000 +0000 +@@ -25,15 +25,19 @@ + html.tmac www.tmac \ + eqnrc \ + troffrc troffrc-end \ +- hyphen.us ++ hyphen.us \ ++ andocj.tmac \ ++ euc-jp.tmac \ ++ gb.tmac big5.tmac + SPECIALFILES=an.tmac man.tmac s.tmac ms.tmac +-STRIPFILES=e.tmac doc.tmac doc-old.tmac +-MDOCFILES=doc-common doc-ditroff doc-nroff doc-syms ++STRIPFILES=e.tmac doc.tmac doc-old.tmac docj.tmac ++MDOCFILES=doc-common doc-ditroff doc-nroff doc-syms docj-ditroff docj-nroff + mdocdir=$(tmacdir)/mdoc + CLEANADD=\ + stamp-wrap stamp-sed *-wrap man.tmac-sed ms.tmac-sed \ + stamp-strip e.tmac-s doc.tmac-s doc-old.tmac-s \ +- doc-common-s doc-ditroff-s doc-nroff-s doc-syms-s mdoc.local-s ++ doc-common-s doc-ditroff-s doc-nroff-s doc-syms-s mdoc.local-s \ ++ docj.tmac-s docj-ditroff-s docj-nroff-s + tmac_s_prefix= + tmac_an_prefix= + tmac_wrap= +diff -Naur groff-1.18.1.4.orig/tmac/andocj.tmac groff-1.18.1.4/tmac/andocj.tmac +--- groff-1.18.1.4.orig/tmac/andocj.tmac 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/tmac/andocj.tmac 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,12 @@ ++." Load either tmac.an or tmac.doc. ++.if !\n(.g .ab These macros require groff. ++.de Dd ++.rm Dd ++.do mso tmac.docj ++\*(Dd\ ++.. ++.de TH ++.rm TH ++.do mso tmac.an ++\*(TH\ ++.. +diff -Naur groff-1.18.1.4.orig/tmac/big5.tmac groff-1.18.1.4/tmac/big5.tmac +--- groff-1.18.1.4.orig/tmac/big5.tmac 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/tmac/big5.tmac 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,15 @@ ++." Kinsoku table for the BIG5 encoding of Chinese, recoded from ++." kinsoku.el in Emacs 22.0.50. ++." Needs review by native zh_TW speaker. ++." ++.cflags 256 ¡B¡C¡A¡D¡G¡F¡H¡I¡Ã¡Ä ++.cflags 256 ¡²Éi¡X¡þ¡U¡L¡Š¡š¡^ ++.cflags 256 ¡f¡b¡r¡n¡v¡z¡j¡Ñ¡×¡Õ¡Ø¡Û¡ñ¢X ++.cflags 256 ¡œ¡µ¡¶¡Ÿ¡¿¡°¢E¡÷¡ö¡ô¡ã ++.cflags 512 ¡Ö¡Ù¡ï¡ð¢X¢C¡ì ++.cflags 512 ÛÖ¶yÅV¡D¡¶¡ù£H¢} ++." ++." http://tcl.apache.org/sources/tcl/tools/encoding/big5.txt lists U+FF0D ++." as FULLWIDTH HYPHEN-MINUS. Is this correct? ++." ++.hc ¡Ð +diff -Naur groff-1.18.1.4.orig/tmac/docj-ditroff groff-1.18.1.4/tmac/docj-ditroff +--- groff-1.18.1.4.orig/tmac/docj-ditroff 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/tmac/docj-ditroff 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,305 @@ ++." Copyright (c) 1991 The Regents of the University of California. ++." All rights reserved. ++." ++." Redistribution and use in source and binary forms, with or without ++." modification, are permitted provided that the following conditions ++." are met: ++." 1. Redistributions of source code must retain the above copyright ++." notice, this list of conditions and the following disclaimer. ++." 2. Redistributions in binary form must reproduce the above copyright ++." notice, this list of conditions and the following disclaimer in the ++." documentation and/or other materials provided with the distribution. ++." 3. All advertising materials mentioning features or use of this software ++." must display the following acknowledgement: ++." This product includes software developed by the University of ++." California, Berkeley and its contributors. ++." 4. Neither the name of the University nor the names of its contributors ++." may be used to endorse or promote products derived from this software ++." without specific prior written permission. ++." ++." THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++." ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++." IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++." ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++." FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++." DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++." OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++." HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++." LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++." OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++." SUCH DAMAGE. ++." ++." @(#)doc-ditroff 5.8 (Berkeley) 8/5/91 ++." ++." tmac.mdoc-ditroff ++.if \n(.g .if !rC .nr C 0 ++.ds aD \fI\s10 ++.ds aR \f(CO\s10 ++.ds cM \f(CB\s10 ++.ds dF \fR\s10 ++.ds eM \fI\s10 ++.ds eR \fC\s10 ++.ds eV \fC\s10 ++.ds fA \f(CO\s10 ++.ds fD \f(CB\s10 ++.ds fL \f(CB\s10 ++.ds fN \f(CB\s10 ++.ds fP \fP\s0 ++.ds fS \s0 ++.ds fT \f(CO\s10 ++.ds Hs \fR\s10 ++.ds iC \f(CB\s10 ++.ds lI \fC ++.ds lP \fR|(|\fP\s10 ++.ds lp \fR(\fP\s10 ++.ds rP \fR|)|\fP\s10 ++.ds rp \fR)\fP\s10 ++.ds lB \fR^[^\fP\s10 ++.ds rB \fR^]\fP\s10 ++.ds mL \fB\s10 ++.ds nM \f(CB\s10 ++.ds nO \fR\s10 ++.ds nT \s0 ++.ds pA \fC\s10 ++.ds Pu \fR{\ .\ ,\ :\ ;\ (\ )\ [\ ]\ \fR} ++.ds rA \fR\s10 ++.ds rT \f(CO\s10 ++.ds sH \fB\s10 ++.ds sP \s0 ++.ds sY \fB\s10 ++.ds sX \fR\s10 ++.ds tF \fR ++.ds tN \s9 ++.ds vA \fI\s10 ++.ds Vs \fR\s10 ++.ds vT \f(CB\s10 ++.ds xR \fC\s10 ++.tr *(** ++.nr sI \w\fC,u*5 ++.nr Ti \n(sIu ++.nr Pp .5v ++.ds lS \0 ++.nr lS \w'\0'u ++.nr dI 6n ++.de pL ++.nr Hm .5i ++.nr Fm .5i ++.nr ll 6.5i ++.ll 6.5i ++.nr lt 6.5i ++.lt 6.5i ++.nr po 1i ++.po 1.i ++.nr dV .5v ++.. ++.ds <= (<= ++.ds >= (>= ++.ie \n(.g {\ ++. ds Lq (lq ++. ds Rq (rq ++.} ++.el {\ ++. ds Lq &`` ++. ds Rq &'' ++.} ++.ds ua (ua ++.ds aa (aa ++.ds ga (ga ++.ds sR &' ++.ds sL &` ++.ds q &" ++.ds Pi (*p ++.ds Ne (!= ++.ds Le (<= ++.ds Ge (>= ++.ds Lt < ++.ds Gt > ++.ds Pm (+- ++.ds If (if ++.ds Na \fINaN\fP ++.ds Ba \fR&|\fP ++.nr gX 0 ++.de hK ++.ds hT \*(dT ++.if !"\*(cH"Null" {\ ++. ie !"\*(gP"Null" .as hT |(|\*(cH\*(gP|) ++. el .as hT \|(\|\*(cH\|) ++.} ++.if "\*(cH"Null" {\ ++. if !"\*(gP"Null" .as hT &|(|\*(gP|) ++.} ++.wh 0 hM ++.wh -1.25i fM ++.nr nL \n(nl ++.ie \n(gX==1 {\ ++. rm n1 ++. bp ++.} ++.el {\ ++' bp ++.} ++.if \n(nL>0 {\ ++. if !\nC {\ ++. nr % 1 ++. } ++.} ++.nr gX 0 ++.em lM ++.. ++.nr fW \w\fC0 ++.de sW ++.nr sW \w\fC\$1 ++.ie \n(sW>=\n(fW {\ ++. ie \n(sW%\n(fW .nr sW (\n(sW/\n(fW)+1 ++. el .nr sW \n(sW/\n(fW ++.} ++.el {\ ++. ie \n(sW>0 .nr sW 1 ++. el .nr sW 0 ++.} ++.. ++.de aW ++.nr sW \w\fC\*(A\$1 ++.ie \n(sW>=\n(fW {\ ++. ie \n(sW%\n(fW .nr sW (\n(sW/\n(fW)+1 ++. el .nr sW \n(sW/\n(fW ++.} ++.el {\ ++. ie \n(sW>0 .nr sW 1 ++. el .nr sW 0 ++.} ++.. ++.de Ql ++.if \n(aC==0 {\ ++. ds mN Ql ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. nr fV \n(.$ ++. fV ++.} ++.nr aP \n(aP+1 ++.aW \n(aP ++.nr aP \n(aP-1 ++.if \n(sW>2 .Li ++.if \n(sW<=2 {\ ++. if (\n(aP>0) {\ ++. ds A\n(aP Li ++. nr aP \n(aP -1 ++. } ++. if (\n(aP==0) {\ ++. rm C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 ++. rm S1 S2 S3 S4 S5 S6 S7 S8 S9 ++. rn A8 A9 ++. rn A7 A8 ++. rn A6 A7 ++. rn A5 A6 ++. rn A4 A5 ++. rn A3 A4 ++. rn A2 A3 ++. rn A1 A2 ++. ds A1 Li ++. nr fV \n(aC+1 ++. nr aC 0 ++. fV ++. } ++. ds qL &\*(sL ++. ds qR &\*(sR ++. En ++.} ++.. ++.de Sh ++.nr nS 0 ++.nr sE 0 ++.nr iS 0 ++'ad ++.ie "\$1"NAME" {\ ++. hK ++' in 0 ++.} ++.el {\ ++. ie "\$1"ÌŸÁ°" {\ ++. hK ++' in 0 ++. } ++. el {\ ++. ie "\$1"ÌŸŸÎ" {\ ++. hK ++' in 0 ++. } ++. el {\ ++. nr nS 0 ++. nr nA 0 ++. nr nF 0 ++. nr nT 0 ++. nr nY 0 ++. nr oT 0 ++. if "\$1"SYNOPSIS" {\ ++. na ++. nr nS 1 ++. } ++. if "\$1"œñŒ°" {\ ++. na ++. nr nS 1 ++. } ++. if "\$1"DESCRIPTION" {\ ++. nr fY 0 ++. nr fZ 0 ++. nr fB 0 ++. nr Fb 0 ++. ds Fb ++. } ++. if "\$1"ÀâÌÀ" {\ ++. nr fY 0 ++. nr fZ 0 ++. nr fB 0 ++. nr Fb 0 ++. ds Fb ++. } ++. if "\$1"²òÀâ" {\ ++. nr fY 0 ++. nr fZ 0 ++. nr fB 0 ++. nr Fb 0 ++. ds Fb ++. } ++. if "\$1"SEE" {\ ++. nr nA 1 ++. na ++. } ++. if "\$1"ŽØÏ¢¹àÌÜ" {\ ++. nr nA 1 ++. na ++. } ++. if "\$1"FILES" .nr nF 1 ++. if "\$1"¥Õ¥¡¥€¥ë" .nr nF 1 ++. if "\$1"ŽØÏ¢¥Õ¥¡¥€¥ë" .nr nF 1 ++. if "\$1"STANDARDS" .nr nT 1 ++. if "\$1"œàµò" .nr nT 1 ++. if "\$1"µ¬³Ê" .nr nT 1 ++. if "\$1"AUTHORS" .nr nY 1 ++. if "\$1"ÃøŒÔ" .nr nY 1 ++. if "\$1"ºîŒÔ" .nr nY 1 ++. if "\$1"SEE" .nr sE 1 ++. if "\$1"ŽØÏ¢¹àÌÜ" .nr sE 1 ++. in 0 ++. nr aN 0 ++. } ++. } ++.} ++.pL ++'sp ++.ns ++.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i ++.if !\n(cR .ne 3 ++'fi ++&\*(sH\$1 |\$2 |\$3 |\$4 |\$5 |\$6 |\$7 |\$8 |\$9 ++&\fP\s0& ++.in \n(.iu+\n(Tiu ++.ns ++.. +diff -Naur groff-1.18.1.4.orig/tmac/docj-nroff groff-1.18.1.4/tmac/docj-nroff +--- groff-1.18.1.4.orig/tmac/docj-nroff 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/tmac/docj-nroff 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,247 @@ ++." Copyright (c) 1991 The Regents of the University of California. ++." All rights reserved. ++." ++." Redistribution and use in source and binary forms, with or without ++." modification, are permitted provided that the following conditions ++." are met: ++." 1. Redistributions of source code must retain the above copyright ++." notice, this list of conditions and the following disclaimer. ++." 2. Redistributions in binary form must reproduce the above copyright ++." notice, this list of conditions and the following disclaimer in the ++." documentation and/or other materials provided with the distribution. ++." 3. All advertising materials mentioning features or use of this software ++." must display the following acknowledgement: ++." This product includes software developed by the University of ++." California, Berkeley and its contributors. ++." 4. Neither the name of the University nor the names of its contributors ++." may be used to endorse or promote products derived from this software ++." without specific prior written permission. ++." ++." THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++." ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++." IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++." ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++." FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++." DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++." OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++." HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++." LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++." OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++." SUCH DAMAGE. ++." ++." @(#)doc-nroff 5.6 (Berkeley) 8/5/91 ++." ++." tmac.mdoc-nroff ++.ds aD \fI ++.ds aR \fI ++.ds cM \fB ++.ds dF \fR ++.ds eM \fI ++.ds eR \fR ++.ds eV \fR ++.ds fA \fI ++.ds fD \fB ++.ds fL \fB ++.ds fN \fB ++.ds fP \fP ++.ds fS ++.ds fT \fI ++.ds Hs \fR ++.ds iC \fB ++.ds lI \fR ++.ds lP \fR|(\fP ++.ds rP \fR|)\fP ++.ds lp \fR|(\fP ++.ds rp \fR|)\fP ++.ds lB \fR|[|\fP ++.ds rB \fR|]\fP ++.ds mL \fB ++.ds nM \fB ++.ds nO \fR ++.ds pA \fI ++.ds Pu {\ .\ ,\ ;\ :\ (\ )\ [\ ]} ++.ds rA \fR ++.ds rT \fI ++.ds sH \fB ++.ds sP ++.ds sY \fB ++.ds sX \fI ++.ds tF \fR ++.ds tN ++.ds vA \fI ++.ds Vs \fR ++.ds vT \fB ++.ds xR \fR ++.nr sI .5i ++.nr Ti .5i ++.nr cR 1 ++.nr Pp 1v ++.ds lS \0\0 ++.nr lS \w'\0\0'u ++.nr dI 6n ++.de pL ++.ie \n(cR .nr Hm 0 ++.el .nr Hm .5i ++.nr Fm .5i ++.nr ll 78n ++.ll 78n ++.nr lt 78n ++.lt 78n ++.nr po 0i ++.po 0i ++.nr dV 1v ++.ad l ++.na ++.. ++.ds <= &<&= ++.ds >= &>&= ++.ds Rq '' ++.ds Lq `` ++.ds ua ^ ++.ds aa ' ++.ds ga ` ++.ds sL ` ++.ds sR ' ++.ds q &" ++.ds Pi pi ++.ds Ne != ++.ds Le <= ++.ds Ge >= ++.ds Lt < ++.ds Gt > ++.ds Pm +- ++.ds If infinity ++.ds Na \fINaN\fP ++.ds Ba \fR&|\fP ++ ++.de hK ++.nr % 1 ++.ds hT \*(dT ++.if !"\*(cH"Null" {\ ++. ie !"\*(gP"Null" .as hT |(|\*(cH\*(gP|) ++. el .as hT \|(\|\*(cH\|) ++.} ++.if "\*(cH"Null" .if !"\*(gP"Null" .as hT &|(|\*(gP|) ++.ie \n(cR {\ ++. hM ++. wh -1v fM ++.} ++.el {\ ++. wh 0 hM ++. wh -1.167i fM ++.} ++.if \n(nl==0:\n(nl==-1 'bp ++.em lM ++.. ++.nr fW \w'0' ++.de sW ++.nr sW \w\$1 ++.ie \n(sW>=\n(fW {\ ++. ie \n(sW%\n(fW .nr sW (\n(sW/\n(fW)+1 ++. el .nr sW \n(sW/\n(fW ++.} ++.el .nr sW 0 ++.. ++.de aW ++.nr sW \w\*(A\$1 ++.ie \n(sW>=\n(fW {\ ++. ie \n(sW%\n(fW .nr sW (\n(sW/\n(fW)+1 ++. el .nr sW \n(sW/\n(fW ++.} ++.el .nr sW 0 ++.. ++.de Ql ++.if \n(aC==0 {\ ++. ds mN Ql ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++.} ++.ds qL &\*(sL ++.ds qR &\*(sR ++.En \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++.de Sh ++.nr nS 0 ++.nr sE 0 ++.nr iS 0 ++.ie "\$1"NAME" {\ ++. hK ++' in 0 ++.} ++.el {\ ++. ie "\$1"ÌŸÁ°" {\ ++. hK ++' in 0 ++. } ++. el {\ ++. ie "\$1"ÌŸŸÎ" {\ ++. hK ++' in 0 ++. } ++. el {\ ++. nr nS 0 ++. nr nA 0 ++. nr nF 0 ++. nr nT 0 ++. nr nY 0 ++. nr aN 0 ++. nr oT 0 ++. if "\$1"SEE" .nr nA 1 ++. if "\$1"ŽØÏ¢¹àÌÜ" .nr nA 1 ++. if "\$1"FILES" .nr nF 1 ++. if "\$1"¥Õ¥¡¥€¥ë" .nr nF 1 ++. if "\$1"ŽØÏ¢¥Õ¥¡¥€¥ë" .nr nF 1 ++. if "\$1"STANDARDS" .nr nT 1 ++. if "\$1"œàµò" .nr nT 1 ++. if "\$1"µ¬³Ê" .nr nT 1 ++. if "\$1"SYNOPSIS" .nr nS 1 ++. if "\$1"œñŒ°" .nr nS 1 ++. if "\$1"DESCRIPTION" {\ ++. rr fB ++. rr Fb ++. ds Fb ++. nr fY 0 ++. nr fZ 0 ++. } ++. if "\$1"ÀâÌÀ" {\ ++. rr fB ++. rr Fb ++. ds Fb ++. nr fY 0 ++. nr fZ 0 ++. } ++. if "\$1"²òÀâ" {\ ++. rr fB ++. rr Fb ++. ds Fb ++. nr fY 0 ++. nr fZ 0 ++. } ++. if "\$1"AUTHORS" .nr nY 1 ++. if "\$1"ÃøŒÔ" .nr nY 1 ++. if "\$1"ºîŒÔ" .nr nY 1 ++. in 0 ++. } ++. } ++.} ++.pL ++'sp ++.ns ++.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i ++.if !\n(cR .ne 3 ++'fi ++&\*(sH\$1 |\$2 |\$3 |\$4 |\$5 |\$6 |\$7 |\$8 |\$9 ++&\fP\s0& ++.in \n(.iu+\n(Tiu ++.if "\$1"SEE" .nr sE 1 ++.ns ++.. +diff -Naur groff-1.18.1.4.orig/tmac/docj.tmac groff-1.18.1.4/tmac/docj.tmac +--- groff-1.18.1.4.orig/tmac/docj.tmac 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/tmac/docj.tmac 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,3427 @@ ++." Copyright (c) 1991 The Regents of the University of California. ++." All rights reserved. ++." ++." Redistribution and use in source and binary forms, with or without ++." modification, are permitted provided that the following conditions ++." are met: ++." 1. Redistributions of source code must retain the above copyright ++." notice, this list of conditions and the following disclaimer. ++." 2. Redistributions in binary form must reproduce the above copyright ++." notice, this list of conditions and the following disclaimer in the ++." documentation and/or other materials provided with the distribution. ++." 3. All advertising materials mentioning features or use of this software ++." must display the following acknowledgement: ++." This product includes software developed by the University of ++." California, Berkeley and its contributors. ++." 4. Neither the name of the University nor the names of its contributors ++." may be used to endorse or promote products derived from this software ++." without specific prior written permission. ++." ++." THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++." ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++." IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++." ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++." FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++." DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++." OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++." HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++." LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++." OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++." SUCH DAMAGE. ++." ++." @(#)doc 5.8 (Berkeley) 8/5/91 ++." Modified by jjc@jclark.com as follows: the doc-* files are assumed to be ++." installed as mdoc/doc-* rather than tmac.doc-* (the filename ++." `tmac.doc-common' would be too long); when using groff, the doc-* files ++." are loaded using the `mso' request. ++." ++." .mdoc-parse - attempt to parse troff request arguments ++." %beginstrip% ++.if \n(.g {\ ++.cp 0 ++.ftr C CR ++.} ++.if \n(.g .ig ++.de sO ++.so /usr/share/tmac/\$1 ++.. ++.if !\n(.g .ig ++.de sO ++.mso mdoc/\$1 ++.. ++.if t {\ ++. sO docj-ditroff ++.} ++.if n {\ ++. sO docj-nroff ++.} ++.sO doc-common ++.sO doc-syms ++." NS Db macro - start/stop DEBUG MODE ++." NS Db register DEBUG MODE ++." NS iN register DEBUG MODE (inline if 1, to stderr if 0 (default)) ++.nr Db 0 ++.de Db ++.ie \n(.$==0 {\ ++. ie \n(Db==0 {\ ++.tm DEBUGGING ON ++. nr Db 1 ++. } ++. el {\ ++.tm DEBUGGING OFF ++. nr Db 0 ++. } ++.} ++.el {\ ++. if "\$1"on" {\ ++.tm DEBUGGING ON ++. nr Db 1 ++. } ++. if "\$1"off" {\ ++.tm DEBUGGING OFF ++. nr Db 0 ++. } ++.} ++.. ++." NS aV macro - parse argument vector (recursive) (.aV arg ... ) ++." NS fV macro - parse argument vector (recursive) (.fV) ++." NS aC register argument counter (aV/fV) ++." NS fV register argument counter (must set to \n(.$ prior to reuqest) (fV) ++." NS A[0-9] argument vector (aV/fV) ++." NS C[0-9] reg. arg type(1=macro, 2=arg, 3=punct-suf, 4=punct-pre) (aV/fV) ++." NS S[0-9] space vector (sV) ++." NS aP register argument pointer (aV) ++." NS yU local string used for debugging ++." NS iI local register (indent for inline debug mode) ++." NS mN name of calling request (set in each user requestable macro) ++.de aV ++.nr aC \n(aC+1 ++.ie "\$1"|" {\ ++. if "\*(mN"Op" .ds A\n(aC \fR\$1\fP ++. if "\*(mN"Ar" .ds A\n(aC \fR\$1\fP ++. if "\*(mN"Fl" .ds A\n(aC \fR\$1\fP ++. if "\*(mN"Cm" .ds A\n(aC \fR\$1\fP ++. if "\*(mN"It" .ds A\n(aC \fR\$1\fP ++.} ++.el .ds A\n(aC \$1 ++.aU \n(aC ++.nr C\n(aC \n(aT ++.s\n(aT ++.if \n(Db {\ ++. if \n(aT==1 .ds yU Executable ++. if \n(aT==2 .ds yU String ++. if \n(aT==3 .ds yU Closing Punctuation or suffix ++. if \n(aT==4 .ds yU Opening Punctuation or prefix ++. if \n(iN==1 {\ ++. br ++. nr iI \n(.iu ++. in -\n(iIu ++. if \n(aC==1 {\ ++&\fBDEBUG(argv) MACRO:\fP `.\*(mN' \fBLine #:\fP \n(.c ++. } ++&\t\fBArgc:\fP \n(aC \fBArgv:\fP `\*(A\n(aC' \fBLength:\fP \n(sW ++&\t\fBSpace:\fP `\*(S\n(aC' \fBClass:\fP \*(yU ++. } ++. if \n(iN==0 {\ ++. if \n(aC==1 {\ ++. tm DEBUG(argv) MACRO: `.\*(mN' Line #: \n(.c ++. } ++. tm \tArgc: \n(aC Argv: `\*(A\n(aC' Length: \n(sW ++. tm \tSpace: `\*(S\n(aC' Class: \*(yU ++. } ++.} ++.ie \n(.$==1 {\ ++. nr aP 0 ++. ie \n(dZ==1 {\ ++. if \n(oM>1 .as b1 \*(S0 ++. } ++. el {\ ++. if \n(oM>0 {\ ++. if \n(fC==0 .as b1 \*(S0 ++. } ++. } ++. ds S0 \*(S\n(aC ++. if \n(Db {\ ++. if \n(iN==1 {\ ++&MACRO REQUEST: \t.\*(mN \*(A1 \*(A2 \*(A3 \*(A4 \*(A5 \*(A6 \*(A7 \*(A8 \*(A9 ++. br ++. in \n(iIu ++. } ++. if \n(iN==0 {\ ++.tm \tMACRO REQUEST: .\*(mN \*(A1 \*(A2 \*(A3 \*(A4 \*(A5 \*(A6 \*(A7 \*(A8 \*(A9 ++. } ++. } ++.} ++.el .aV \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++.de fV ++.nr aC \n(aC+1 ++.if "\*(A\n(aC"|" {\ ++. if "\*(mN"Op" .ds A\n(aC \fR\*(A\n(aC\fP ++. if "\*(mN"Ar" .ds A\n(aC \fR\*(A\n(aC\fP ++. if "\*(mN"Fl" .ds A\n(aC \fR&\*(A\n(aC\fP ++. if "\*(mN"Cm" .ds A\n(aC \fR\*(A\n(aC\fP ++. if "\*(mN"It" .ds A\n(aC \fR\*(A\n(aC\fP ++.} ++.aU \n(aC ++.nr C\n(aC \n(aT ++.s\n(aT ++.if \n(Db {\ ++. if \n(aT==1 .ds yU Executable ++. if \n(aT==2 .ds yU String ++. if \n(aT==3 .ds yU Closing Punctuation or suffix ++. if \n(aT==4 .ds yU Opening Punctuation or prefix ++. if \n(iN==1 {\ ++. br ++. nr iI \n(.iu ++. in -\n(iIu ++. if \n(aC==1 {\ ++&\fBDEBUG(fargv) MACRO:\fP `.\*(mN' \fBLine #:\fP \n(.c ++. } ++&\t\fBArgc:\fP \n(aC \fBArgv:\fP `\*(A\n(aC' \fBLength:\fP \n(sW ++&\t\fBSpace:\fP `\*(S\n(aC' \fBClass:\fP \*(yU ++. } ++. if \n(iN==0 {\ ++. if \n(aC==1 {\ ++. tm DEBUG(fargv) MACRO: `.\*(mN' Line #: \n(.c ++. } ++. tm \tArgc: \n(aC Argv: `\*(A\n(aC' Length: \n(sW ++. tm \tSpace: `\*(S\n(aC' Class: \*(yU ++. } ++.} ++.ie \n(fV==1 {\ ++. nr aP 0 ++. ie \n(dZ==1 {\ ++. if \n(oM>1 .as b1 \*(S0 ++. } ++. el {\ ++. if \n(oM>0 {\ ++. if \n(fC==0 .as b1 \*(S0 ++. } ++. } ++. ds S0 \*(S\n(aC ++. nr fV 0 ++. if \n(Db {\ ++. ie \n(iN {\ ++&\tMACRO REQUEST: .\*(mN \*(A1 \*(A2 \*(A3 \*(A4 \*(A5 \*(A6 \*(A7 \*(A8 \*(A9 ++. br ++. in \n(iIu ++. } ++. el {\ ++.tm \tMACRO REQUEST: .\*(mN \*(A1 \*(A2 \*(A3 \*(A4 \*(A5 \*(A6 \*(A7 \*(A8 \*(A9 ++. } ++. } ++.} ++.el {\ ++. nr fV \n(fV-1 ++. fV ++.} ++.. ++." NS aX macro - stuff saved strings into `b1' (used by -diag list) ++.de aX ++.nr aP \n(aP+1 ++.as b1 &\*(A\n(aP ++.ie \n(fV==1 {\ ++. nr aP 0 ++. nr fV 0 ++.} ++.el {\ ++. as b1 &\*(sV ++. nr fV \n(fV-1 ++. aX ++.} ++.. ++." NS aI macro - append arg to arg vector: .aI [arg] [type] (used by .En only) ++.de aI ++.ie \n(aC<9 {\ ++. nr aC \n(aC+1 ++. ds A\n(aC \$1 ++. nr C\n(aC \$2 ++. s\$2 ++. ds xV S\n(aC ++.} ++.el {\ ++. tm Usage: Too many arguments (maximum of 8 accepted) (#\n(.c) ++. tm \*(A1 \*(A2 \*(A3 \*(A4 \*(A5 \*(A6 \*(A7 \*(A8 \*(A9 ++.} ++.. ++." ++." NS aZ macro - print buffer (pB) and clean up arg vectors (aY) ++.de aZ ++.pB ++.aY ++.. ++." NS aY macro - clean up arg vector ++.de aY ++.rm C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 ++.rm A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 ++.rm S1 S2 S3 S4 S5 S6 S7 S8 S9 ++.nr aC 0 ++.nr aP 0 ++.. ++." NS pB macro - test for end of vector (eol) (print b1 buffer or divert) ++.de pB ++.ie \n(dZ==1 {\ ++. if \n(oM==1 {&\*(b1 ++. rm S0 ++. ds b1 ++. } ++. if \n(oM==0 {\ ++. x2 ++. } ++.} ++.el {\ ++. ie \n(oM==0 {&\*(b1 ++. rm S0 ++. ds b1 ++. } ++. el {\ ++. if ((\n(sM==1)&(\n(tP==0)) {\ ++. x1 ++. } ++. } ++.} ++.hy ++.. ++." NS x1 macro - save buffer and divert if tP flag set ++." NS eB diversion string ++." NS b2 string save of buffer ++." NS lK register count of lines read from input file ++.de x1 ++.nr dZ \n(dZ+1 ++.ds b2 \*(b1 ++.ds b1 ++.nr lK \n(.c ++.ev 2 ++.fi ++.di eB ++.. ++." ++." NS x2 macro - end diversion and print ++." NS b0 string local temporary ++.de x2 ++.br ++.di ++.ev ++.ie (\n(.c-\n(lK>1) {\ ++. ds b0 &\*(eB\ ++. ds b1 \*(b2\*(b0\*(b1 ++.} ++.el .ds b1 \*(b2\*(b1 ++&\*(b1 ++.rm eB b2 b0 b1 ++.nr dZ \n(dZ-1 ++.. ++." NS Fl macro - flags (appends - and prints flags) ++." NS cF register save current font ++." NS cZ register save current font size ++.de Fl ++.as b1 &\*(fL ++.if \n(aC==0 {\ ++. ie \n(.$==0 {\ ++. as b1 &|-|\fP\s0 ++. pB ++. } ++. el {\ ++. ds mN Fl ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>0 {\ ++. ie (\n(aC-\n(aP)==0 {\ ++. as b1 &|-\fP\s0 ++. aZ ++. } ++. el {\ ++. nr aP \n(aP+1 ++. ie \n(C\n(aP==1 {\ ++. as b1 &|-\fP\s0 ++. \*(A\n(aP ++. } ++. el {\ ++. nr cF \n(.f ++. nr cZ \n(.s ++. if \n(C\n(aP==3 {\ ++. as b1 &|-| ++. } ++. fR ++. } ++. } ++.} ++.. ++." ++." NS fR macro - Fl flag recursion routine (special handling) ++." NS jM local register ++." NS jN local register ++." ++.de fR ++.hy 0 ++.nr jM \n(C\n(aP ++.ie \n(jM==1 {\ ++. as b1 &\fP\s0 ++. \*(A\n(aP ++.} ++.el {\ ++. nr jN \n(aP ++. ie \n(jM==2 {\ ++. ie !"\*(A\n(aP"\*(Ba" {\ ++. ie !"\*(A\n(aP"\fR|\fP" {\ ++. ie "\*(A\n(aP"-" .as b1 &|-^-| ++. el .as b1 &|-\*(A\n(aP ++. } ++. el .as b1 &\*(A\n(aP ++. } ++. el .as b1 &\*(A\n(aP ++. } ++. el .as b1 &\f\n(cF\s\n(cZ\*(A\n(aP\fP\s0 ++. ie \n(aC==\n(aP {\ ++. if \n(jM==4 .as b1 &|- ++. as b1 &\fP\s0 ++. aZ ++. } ++. el {\ ++. nr aP \n(aP+1 ++. ie ((\n(C\n(aP==3)&(\n(C\n(jN==4)) .as b1 &|- ++. el .as b1 &\*(S\n(jN ++. fR \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.rr jM jN ++.. ++." ++." NS nR macro - general name recursion routine ++." NS jM local register ++." NS jN local register ++.de nR ++.hy 0 ++.nr jM \n(C\n(aP ++.ie \n(jM==1 {\ ++. as b1 &\f\n(cF\s\n(cZ ++. \*(A\n(aP ++.} ++.el {\ ++. nr jN \n(aP ++. ie \n(jM==2 .as b1 &\*(A\n(aP ++. el .as b1 &\f\n(cF\s\n(cZ\*(A\n(aP\fP\s0 ++. ie \n(aC==\n(aP {\ ++. as b1 &\f\n(cF\s\n(cZ ++. aZ ++. } ++. el {\ ++. nr aP \n(aP+1 ++. as b1 &\*(S\n(jN ++. nR ++. } ++.} ++.rr jM jN ++.. ++." NS Ar macro - command line `argument' macro ++." ++.de Ar ++.as b1 \*(aR ++.if \n(aC==0 {\ ++. ie \n(.$==0 {\ ++. as b1 file\ ...\fP\s0 ++. pB ++. } ++. el {\ ++. ds mN Ar ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>0 {\ ++. ie (\n(aC-\n(aP)==0 {\ ++. as b1 &file\ ...\fP\s0 ++. aZ ++. } ++. el {\ ++. nr aP \n(aP+1 ++. ie \n(C\n(aP==1 {\ ++. as b1 &file\ ...\fP\s0 ++. \*(A\n(aP ++. } ++. el {\ ++. nr cF \n(.f ++. nr cZ \n(.s ++. if \n(C\n(aP==3 {\ ++. as b1 &file\ ... ++. } ++. nR ++. } ++. } ++.} ++.. ++." NS Ad macro - Addresses ++.de Ad ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Ad address ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Ad ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(aD ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Cd macro - Config declaration (for section 4 SYNOPSIS) (not callable) ++." needs work - not very translatable ++.de Cd ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Cd Configuration file declaration (#\n(.c) ++. el {\ ++. ds mN Cd ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.br ++.if \n(aC>\n(aP {\ ++. as b1 \*(nM ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. ie \n(nS {\ ++. if "\*(mN"Cd" {\ ++. rs ++. ie \n(nS>1 .br ++. el {\ ++. if \n(iS==0 .nr iS \n(Dsu ++. } ++. in +\n(iSu ++. ti -\n(iSu ++. nr nS \n(nS+1 ++. } ++. nR ++. in -\n(iSu ++. } ++. el .nR ++.} ++.. ++." NS Cm macro - Interactive command modifier (flag) ++.de Cm ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Cm Interactive command modifier ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Cm ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(cM ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Dv macro - define variable ++.de Dv ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Dv define_variable ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Dv ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(eR ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Em macro - Emphasis ++.de Em ++.if \n(aC==0 {\ ++. ie \n(.$==0 {\ ++. tm Usage: .Em text ... \*(Pu (#\n(.c) ++. } ++. el {\ ++. ds mN Em ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(eM ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Er macro - Errnotype ++.de Er ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Er ERRNOTYPE ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Er ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(eR ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Ev macro - Environment variable ++.de Ev ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Ev ENVIRONMENT_VARIABLE ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Ev ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(eV ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Fd macro - function declaration - not callable (& no err check) ++." NS fD register subroutine test (in synopsis only) ++." NS fY register subroutine count (in synopsis only) (fortran only) ++." NS fZ register also subroutine count (in synopsis only) ++.de Fd ++.ds mN Fd ++.if \n(nS>0 {\ ++." if a variable type was the last thing given, want vertical space ++. if \n(fX>0 {\ ++. Pp ++. nr fX 0 ++. } ++." if a subroutine was the last thing given, want vertical space ++. if \n(fZ>0 {\ ++. ie \n(fD==0 {\ ++. Pp ++. rs ++. } ++. el .br ++. } ++. nr fD \n(fD+1 ++.} ++.nr cF \n(.f ++.nr cZ \n(.s ++&\*(fD\$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.br ++.ft \n(cF ++.fs \n(cZ ++.. ++." NS Fr macro - function return value - not callable (at the moment) ++.de Fr ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Fr Function_return_value... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Fr ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(aR ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Ic macro - Interactive command ++.de Ic ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Ic Interactive command ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Ic ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(iC ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Li macro - literals ++.de Li ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage .Li argument ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Li ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(lI ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Or macro - Pipe symbol (OR) ++.de Or ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Or ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Or ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(iC ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Ms macro - Math symbol ++.de Ms ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Ms Math symbol ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Ms ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(sY ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Nm macro - Name of command or page topic ++." NS n1 string - save first invocation of .Nm ++." NS iS register - indent second command line in a synopsis ++.de Nm ++.if \n(aC==0 {\ ++. ie \n(.$==0 {\ ++. ie "\*(n1"" .tm Usage: .Nm Name(s) ... \*(Pu (#\n(.c) ++. el &\*(nM\*(n1\fP\s0 ++. } ++. el {\ ++. ds mN Nm ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>0 {\ ++. ie \n(aC==\n(aP {\ ++. as b1 &\*(nM\*(n1\fP\s0 ++. aZ ++. } ++. el {\ ++. as b1 \*(nM ++. nr aP \n(aP+1 ++. ie \n(C\n(aP==1 {\ ++. as b1 &\*(n1\fP\s0 ++. \*(A\n(aP ++. } ++. el {\ ++. nr cF \n(.f ++. nr cZ \n(.s ++. if \n(nS {\ ++. if "\*(mN"Nm" {\ ++. rs ++. in -\n(iSu ++. ie \n(nS>1 .br ++. el {\ ++. if \n(iS==0 {\ ++. sw \$1 ++. nr iS ((\n(sWu+1)*\n(fW)u ++. } ++. } ++. in +\n(iSu ++. ti -\n(iSu ++. nr nS \n(nS+1 ++. } ++. } ++. if "\*(n1"" .ds n1 \*(A\n(aP ++. nR ++. } ++. } ++.} ++.. ++." NS Pa macro - Pathname ++.de Pa ++.if \n(aC==0 {\ ++. ie \n(.$==0 &\*(pA~\fP\s0 ++. el {\ ++. ds mN Pa ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(pA ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Sy macro - Symbolics ++.de Sy ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Sy symbolic_text ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Sy ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(sY ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Tn macro - Trade Name Macro ++.de Tn ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Tn Trade_name(s) ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Tn ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(tN\*(tF ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS nN macro - Trade Name Macro for inside of reference ++.de nN ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Tn Trade_name(s) ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Tn ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(tN ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS Va macro - variable name macro ++.de Va ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Va variable_name(s) ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Va ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. as b1 \*(vA ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." ++." NS No macro - Normal text macro (default text style if mess up) ++.de No ++.as b1 \*(nO ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .No must be called with arguments (#\n(.c) ++. el {\ ++. ds mN No ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. ie \n(C\n(aP==1 {\ ++. \*(A\n(aP ++. } ++. el {\ ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++. } ++.} ++.. ++."------------------------------------------------------------------------ ++." NS Op macro - Option Expression ++.de Op ++.if \n(aC==0 {\ ++. ds mN Op ++.} ++." .ds qL &\*(lO ++." .ds qR &\*(rO ++.ds qL &\*(lB ++.ds qR &\*(rB ++.En \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 ++.. ++." NS Aq macro - Enclose string in angle brackets ++.de Aq ++.if \n(aC==0 .ds mN Aq ++.ds qL &< ++.ds qR &> ++.En \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Bq macro - Enclose string in square brackets ++.de Bq ++.if \n(aC==0 .ds mN Bq ++.ds qL &\*(lB ++.ds qR &\*(rB ++.En \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Dq macro - Enclose string in double quotes ++.de Dq ++.if \n(aC==0 .ds mN Dq ++.ds qL &\*(Lq ++.ds qR &\*(Rq ++.En \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Eq macro - Enclose string in double quotes ++.de Eq ++.if \n(aC==0 .ds mN Eq ++.ds qL \$1 ++.ds qR \$2 ++.En \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Pq macro - Enclose string in parenthesis ++.de Pq ++.if \n(aC==0 .ds mN Pq ++.ds qL &\*(lP ++.ds qR &\*(rP ++.En \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Ql macro - Quoted literal is in file mdocj-[dit|n|g]roff (too large ++." an if-else to carry along recursively for `if n ...') ++." ++." NS Sq macro - Enclose string in single quotes ++.de Qq ++.if \n(aC==0 .ds mN Qq ++.ds qL &\*q ++.ds qR &\*q ++.En \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Sq macro - Enclose string in single quotes ++.de Sq ++.if \n(aC==0 .ds mN Sq ++.ds qL &\*(sL ++.ds qR &\*(sR ++.En \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." ++." NS Es macro - Set up strings for .En call ++.de Es ++.if \n(aC==0 {\ ++. ie \n(.$>2 .aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. el {\ ++. ds qL \$1 ++. ds qR \$2 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. ds qL \*(A\n(aP ++. nr aP \n(aP+1 ++. ds qR \*(A\n(aP ++. ie \n(aC>\n(aP .c\n(C\n(aP ++. el .aZ ++.} ++.. ++." .tm En beg arg(A[\n(aP])==\*(A\n(aP; ++." .tm En oM==\n(oM; dZ==\n(dZ; Xt==\n(Xt; aC==\n(aC ++." NS En macro - Enclose string with given args (eg [ and ] etc) ++." NS qL string variable set by calling macro ++." NS qR string variable set by calling macro ++." NS aJ register (for vR) ++.de En ++.ie \n(aC==0 {\ ++. ie \n(.$==0 {\ ++. as b1 &\*(qL\*(qR ++. pB ++. } ++. el {\ ++.". as mN (En) ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. as b1 &\*(qL ++. } ++.} ++.el {\ ++. as b1 &\*(qL ++.} ++.if \n(aC>0 {\ ++. ie (\n(aC-\n(aP)==0 {\ ++. as b1 &\*(qR ++. aZ ++. } ++. el {\ ++. ie \n(C\n(aC==3 {\ ++. nr aJ \n(aC-1 ++. vR ++. nr aJ \n(aJ+1 ++. ds A\n(aJ &\*(qR\*(A\n(aJ ++. nr aJ 0 ++. } ++. el .aI &\*(qR 3 ++. nr aP \n(aP+1 ++. if \n(C\n(aP==1 .\*(A\n(aP ++. if \n(C\n(aP>1 {\ ++. nr aP \n(aP-1 ++. No ++. } ++. } ++.} ++.. ++." NS vR macro - vector routine (for En, trace backwards past trail punct) ++.de vR ++.if \n(C\n(aJ==3 {\ ++. nr aJ \n(aJ-1 ++. vR ++.} ++.. ++."------------------------------------------------------------------------ ++." NS Ao macro - Angle open ++.de Ao ++.if \n(aC==0 .ds mN Ao ++.ds qL &< ++.eO \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Ac macro - Angle close ++.de Ac ++.if \n(aC==0 .ds mN Ac ++.ds qR &> ++.eC \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Bo macro - Bracket open ++.de Bo ++.if \n(aC==0 .ds mN Bo ++.ds qL &[ ++.eO \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Bc macro - Bracket close ++.de Bc ++.if \n(aC==0 .ds mN Bc ++.ds qR &] ++.eC \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Do macro - Double Quote open ++.de Do ++.if \n(aC==0 .ds mN Do ++.ds qL &\*(Lq ++.eO \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Dc macro - Double Quote close ++.de Dc ++.if \n(aC==0 .ds mN Dc ++.ds qR &\*(Rq ++.eC \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Eo macro - Enclose open ++.de Eo ++.if \n(aC==0 .ds mN Eo ++.ds qL \$1 ++.eO \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Ec macro - Enclose close ++.de Ec ++.if \n(aC==0 .ds mN Ec ++.ds qR \$1 ++.eC \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Oo macro - Option open ++.de Oo ++.if \n(aC==0 .ds mN Oo ++.ds qL &[ ++.eO \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Oc macro - Option close ++.de Oc ++.if \n(aC==0 .ds mN Oc ++.ds qR &] ++.eC \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Po macro - Parenthesis open ++.de Po ++.if \n(aC==0 .ds mN Po ++.ds qL &( ++.eO \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Pc macro - Parenthesis close ++.de Pc ++.if \n(aC==0 .ds mN Pc ++.ds qR &) ++.eC \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Qo macro - Straight Double Quote open ++.de Qo ++.if \n(aC==0 .ds mN Qo ++.ds qL &\*q ++.eO \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Qc macro - Straight Double Quote close ++.de Qc ++.if \n(aC==0 .ds mN Qc ++.ds qR &\*q ++.eC \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS So macro - Single Quote open ++.de So ++.if \n(aC==0 .ds mN So ++.ds qL &\*(sL ++.eO \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Sc macro - Single Quote close ++.de Sc ++.if \n(aC==0 .ds mN Sc ++.ds qR &\*(sR ++.eC \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Xo macro - Extend open (continue) ++.de Xo ++.if \n(aC==0 .ds mN Xo ++." .nr mN 1 ++.ds qL ++.eO \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS Xe macro - Extend close (end) ++.de Xc ++." .nr mN 0 ++.if \n(aC==0 .ds mN Xc ++.ds qR ++.eC \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS eO macro - enclose string open ++." NS oM register (extension possible) ++.de eO ++.nr oM \n(oM+1 ++." .tm eO last arg==A[\n(aC]==\*(A\n(aC; aP==\n(aP; oM==\n(oM; dZ==\n(dZ; ++.ie \n(aC==0 {\ ++. ie \n(.$>0 {\ ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. as b1 \*(qL ++. } ++. el {\ ++. as b1 \*(qL ++. if (\n(dZ==0)&(\n(sM==1) {\ ++. nr dZ \n(dZ+1 ++. ds b2 \*(b1 ++. ds b1 ++. nr lK \n(.c ++. ev 2 ++. fi ++. di eB ++. } ++. } ++.} ++.el {\ ++. as b1 \*(qL ++.} ++.ie \n(aC>0 {\ ++. if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. ie \n(C\n(aP==1 .\*(A\n(aP ++. el {\ ++. nr aP \n(aP-1 ++. No ++. } ++. } ++. if \n(aC==\n(aP {\ ++. if \n(tP==1 {\ ++." .tm SETTING Xt!!! ++. nr Xt 1 ++. } ++."." . ds S0 ++."CHANGED ds S0 \*(iV ++. aY ++. } ++.} ++.el {\ ++. if \n(oM>1 .as b1 \*(sV ++.} ++.. ++." ++." NS eC macro - enclose string close ++." NS aa local register ++.de eC ++.nr oM \n(oM-1 ++." tm eC last arg==A[\n(aC]==\*(A\n(aC; aP==\n(aP; oM==\n(oM; dZ==\n(dZ; ++.as b1 \*(qR ++.if \n(aC==0 {\ ++. ie \n(.$>0 {\ ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++. el {\ ++. ie "\*(xB"" {\ ++. pB ++. } ++. el {\ ++. pB ++.\*(L\n(lC ++. nr Xt 0 ++. ds xB ++. } ++. } ++.} ++.if \n(aC>0 {\ ++. ie \n(aC==\n(aP {\ ++. ie \n(oM==0 {\ ++. aZ ++. } ++. el .aY ++. } ++. el {\ ++. nr aa \n(aP+1 ++. if \n(C\n(aa==2 .as b1 \*(S\n(aC ++." tm CURRENT arg (aP==\*(A\n(aP and ap+1==\*(A\n(aa) tP==\n(tP Xt==\n(Xt ++. rr aa ++. if \n(tP>0 {\ ++." tm UNSETTING Xt==\n(Xt!!!! ++. if \n(Xt>0 .nr Xt \n(Xt-1 ++." tm NOW Xt==\n(Xt!!!! ++. } ++. No ++. } ++.} ++.. ++."------------------------------------------------------------------------ ++." NS Pf macro - Prefix (calls .pF) ++.de Pf ++.if \n(aC==0 .ds mN Pf ++.ds qL &\$1 ++.pF \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." NS pF macro - Prefix (for prefixing open quotes, brackets etc) ++.de pF ++.ie \n(aC==0 {\ ++. as b1 &\*(qL ++. ie \n(.$<2 {\ ++. tm Warning: Missing arguments - prefix .Pf) ++. pB ++. } ++. el .aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.} ++.el {\ ++. ie (\n(aC-\n(aP)>1 {\ ++. nr aP \n(aP+1 ++. as b1 &\*(A\n(aP ++. } ++. el .tm Warning: .Pf: trailing prefix (#\n(.c) ++.} ++.if \n(aC>0 {\ ++. ie (\n(aC-\n(aP)==0 .aZ ++. el {\ ++. nr aP \n(aP+1 ++. c\n(C\n(aP ++. } ++.} ++.. ++." NS Ns macro - remove space (space remove done by .aV or .fV) ++.de Ns ++.if \n(aC==0 {\ ++. ds mN Ns ++. ie \n(.$>0 .aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. el .tm Usage: .Ns must be called with arguments (#\n(.c) ++.} ++.No ++.. ++.de Ap ++.if \n(aC==0 {\ ++. ds mN Ap ++. tm Usage: Ap "cannot be first request on a line (no .Ap)" (#\n(.c) ++.} ++.as b1 &' ++.No ++.. ++." NS Hv macro - Hard (unpaddable) Space vector ++." NS iV string inter-vector space ++." NS sV string inter-argument space ++.de Hv ++.ds iV \*(sV ++.ds sV \*(hV ++.. ++." NS Sv macro - Soft Space vector (troff limitation) ++.de Sv ++.ds sV \*(iV ++.. ++." NS Tv macro - Tab Space vector ++.de Tv ++.ds sV \*(tV ++.. ++." NS Sm macro - Space mode ++." NS sM register - default is one (space mode on) ++.nr sM 1 ++.de Sm ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm "Usage: .Sm [off | on]" (#\n(.c) ++. el {\ ++. ds mN Sm ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>0 {\ ++. nr aP \n(aP+1 ++. if "\*(A\n(aP"on" {\ ++. ds sV \*(iV ++. nr sM 1 ++. } ++. if "\*(A\n(aP"off" {\ ++. ds sV ++. rm S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 ++. nr sM 0 ++. } ++. ie \n(aC>\n(aP {\ ++. No ++. } ++. el .aY ++.} ++.. ++."------------------------------------------------------------------------ ++." Size and Argument type macros ++." NS aT macro - argument type ++." NS aU macro - argument type (same as .aT but uses A[1-9] strings ++." NS aT register argument type ++.if \n(.g {\ ++.de aT ++.nr aT 0 ++.ie \n(sW>2:(\A'\$1'==0) {\ ++. nr aT 2 ++.} ++.el {\ ++. if \n(sW==1 {\ ++. ie \n(z\$1>2 {\ ++. nr aT \n(z\$1 ++. } ++. el .nr aT 2 ++. } ++. if \n(sW==2 {\ ++. ie \n(\$1 {\ ++. nr aT 1 ++. } ++. el .nr aT 2 ++. } ++.} ++.. ++.de aU ++.nr aT 0 ++.aW \$1 ++.ie \n(sW>2:(\A'\*(A\$1'==0) .nr aT 2 ++.el {\ ++. if \n(sW==1 {\ ++. ie \n(z\*(A\$1>2 {\ ++. nr aT \n(z\*(A\$1 ++. } ++. el .nr aT 2 ++. } ++. if \n(sW==2 {\ ++. ie (\n(\*(A\$1) {\ ++. nr aT 1 ++. } ++. el .nr aT 2 ++. } ++.} ++.. ++.} ++.if !\n(.g {\ ++.de aT ++.nr aT 0 ++.ie \n(sW>2 {\ ++. nr aT 2 ++.} ++.el {\ ++. if \n(sW==1 {\ ++. ie \n(z\$1>2 {\ ++. nr aT \n(z\$1 ++. } ++. el .nr aT 2 ++. } ++. if \n(sW==2 {\ ++. ie \n(\$1 {\ ++. nr aT 1 ++. } ++. el .nr aT 2 ++. } ++.} ++.. ++.de aU ++.nr aT 0 ++.aW \$1 ++.ie \n(sW>2 .nr aT 2 ++.el {\ ++. if \n(sW==1 {\ ++. ie \n(z\*(A\$1>2 {\ ++. nr aT \n(z\*(A\$1 ++. } ++. el .nr aT 2 ++. } ++. if \n(sW==2 {\ ++. ie (\n(\*(A\$1) {\ ++. nr aT 1 ++. } ++. el .nr aT 2 ++. } ++.} ++.. ++.} ++." NS s1 macro - set spacing for class type 1 ++." NS s2 macro - set spacing for class type 2 ++." NS s3 macro - set spacing for class type 3 ++." NS s1 macro - set spacing for class type 1 ++." NS s2 macro - set spacing for class type 2 ++." NS s3 macro - set spacing for class type 3 ++." NS s4 macro - set spacing for class type 4 ++." NS S[0-9] string spacing ++." NS xX local register ++." NS aa local register ++.de s0 ++.tm MDOC-ERROR: bogus type 0 (can't set space '\*(A\n(aC') (#\n(.c) ++.. ++.de s1 ++.if \n(\*(A\n(aC==3 {\ ++. nr xX \n(aC-1 ++. rm S\n(xX ++. ds S\n(aC \*(sV ++.} ++.if \n(\*(A\n(aC==2 {\ ++. nr xX \n(aC-1 ++." this kludge can probably go away, but need to double check first ++. ie "\*(A\n(aC"Nb" .ds S\n(xX \*(hV ++. el .rm S\n(xX ++.} ++.. ++.de s2 ++.ds S\n(aC \*(sV ++.. ++.de s3 ++.if \n(aC>1 {\ ++. nr xX \n(aC-1 ++. rm S\n(xX ++.} ++.ds S\n(aC \*(sV ++.. ++.de s4 ++.nr aa 0 ++.. ++." Class switches (on current argument aP) ++." NS c0 macro - catch errors (non-existent class type 0) ++." NS c1 macro - call request if type 1 ++." NS c2 macro - call .No if type 2 ++." NS c3 macro - call .No if type 3 ++." NS c4 macro - call .No if type 4 ++.de c0 ++.tm MDOC-ERROR: bogus class 0 (can't determine '\*(A\n(aC') (#\n(.c) ++.. ++.de c1 ++.\*(A\n(aP ++.. ++.de c2 ++.nr aP \n(aP-1 ++.No ++.. ++.de c3 ++.nr aP \n(aP-1 ++.No ++.. ++.de c4 ++.nr aP \n(aP-1 ++.No ++.. ++." NS y1 macro - ignore if class 1 ++." NS y2 macro - ignore if class 2 ++." NS y3 macro - append if type 3 ++." NS y4 macro - append if type 4 ++.de y1 ++.nr aa 1 ++.. ++.de y2 ++.nr aa 1 ++.. ++.de y3 ++.as b1 \*(A\n(aP ++.nr aP \n(aP+1 ++.n\C\n(aP ++.. ++.de y4 ++.as b1 \*(A\n(aP ++.nr aP \n(aP+1 ++.n\C\n(aP ++.. ++."-------------------------------------------------------------------------- ++." Ns Bf macro - Begin Font Mode (will be begin-mode/end-mode in groff & TeX) ++." Ns Ef macro - End Font Mode ++.de Bf ++.ds mN Bf ++.ie \n(.$>0 {\ ++. nr bF \n(.f ++. nr bZ \n(.s ++. if "\$1"Em" &\*(eM\c ++. if "\$1"Li" &\*(lI\c ++. if "\$1"Sy" &\*(sY\c ++. if "\$1"-emphasis" &\*(eM\c ++. if "\$1"-literal" &\*(lI\c ++. if "\$1"-symbolic" &\*(sY\c ++.} ++.el .tm Usage .Bf [Em | emphasis | Li | literal | Sy | symbolic] (#\n(.c) ++.. ++.de Ef ++.ds mN Ef ++.ie \n(.$>0 .tm Usage .Ef (does not take arguments) (#\n(.c) ++.el &\f\n(bF\s\n(bZ ++.. ++." Ns Bk macro - Begin Keep ++." Ns Ek macro - End Keep ++." Ns kS string - keep type ++.de Bk ++.ds mN Bk ++.ie \n(.$==0 {\ ++.tm Usage: .Bk [-lines | -words] (#\n(.c) ++.} ++.el {\ ++. if !"\*(kS"" .tm .Bk: nesting keeps not implemented yet. (#\n(.c) ++. if "\$1"-lines" .tm .Bd -lines: Not implemented yet. (#\n(.c) ++. if "\$1"-words" .Hv ++. ds kS \$1 ++.} ++.. ++.de Ek ++.ds mN Ek ++.ie \n(.$>0 .tm Usage .Ek (does not take arguments) (#\n(.c) ++.el {\ ++. if "\*(kS"-lines" .tm .Bd -lines: Not implemented yet. (#\n(.c) ++. if "\*(kS"-words" .Sv ++. rm kS ++.} ++.. ++." NS Bd macro - Begin Display display-type [offset string] ++." NS Ed macro - end Display ++." NS O[0-9] registers - stack of indent ++." NS d[0-9] registers - display-type stack ++.de Bd ++.ds mN Bd ++.ie \n(.$==0 {\ ++.tm Usage: .Bd [-literal | -filled | -ragged | -unfilled] [-offset [string]] [-compact] (#\n(.c) ++.} ++.el {\ ++. ds aa ++. nr bV 0 ++. nr iD 0 ++. nr dP \n(dP+1 ++. if "\$1"-literal" {\ ++. nr iD \n(iD+1 ++. ds d\n(dP dL ++. nr cF \n(.f ++. nr cZ \n(.s ++. ie t {&\*(lI ++' ta 9n 18n 27n 36n 45n 54n 63n 72n ++. } ++. el {\ ++' ta 8n 16n 24n 32n 40n 48n 56n 64n 72n ++. } ++. nf ++. } ++. if "\$1"-filled" {\ ++. nr iD \n(iD+1 ++. ds d\n(dP dF ++. br ++. } ++. if "\$1"-ragged" {\ ++. nr iD \n(iD+1 ++. ds d\n(dP dR ++. na ++. } ++. if "\$1"-unfilled" {\ ++. nr iD \n(iD+1 ++. ds d\n(dP dU ++. nf ++. } ++." .tm Here is argc: \n(.$ and here is iD \n(iD ++. if ((\n(iD>=1)&(\n(.$>\n(iD)) {\ ++. bV \$2 \$3 \$4 ++. } ++. if \n(O\n(dP>0 'in \n(.iu+\n(O\n(dPu ++. if (\n(bV==0) {\ ++. if (\n(nS==0) {\ ++. ie "\*(d\n(dP"dR" .sp \n(dVu ++. el 'sp \n(dVu ++. } ++. } ++. if \n(cR==0 .ne 2v ++. nr bV 0 ++. nr iD 0 ++.} ++.. ++." NS bV macro - resolve remaining .Bd arguments ++.de bV ++." .tm in bV with args: \$1 \$2 \$3 ++.nr iD 1 ++.ds bY ++.if "\$1"-offset" {\ ++. ds bY \$2 ++. if "\*(bY"left" {\ ++. nr iD \n(iD+1 ++. nr O\n(dP 0 ++. } ++. if "\*(bY"right" {\ ++. nr iD \n(iD+1 ++. nr O\n(dP (\n(.l/3)u ++. } ++. if "\*(bY"center" {\ ++. nr iD \n(iD+1 ++. nr O\n(dP (\n(.l-\n(.i)/4u ++. } ++. if "\*(bY"indent" {\ ++. nr iD \n(iD+1 ++. nr O\n(dP \n(dIu ++. } ++. if "\*(bY"indent-two" {\ ++. nr iD \n(iD+1 ++. nr O\n(dP \n(dIu+\n(dIu ++. } ++. if \n(iD==1 {\ ++. nr iD \n(iD+1 ++. sW "\*(bY" ++. ie \n(sW>2 {\ ++. ie ((\*(bY>9n)&(\*(bY<100n)) {\ ++. nr O\n(dP \*(bY ++. } ++. el .nr O\n(dP (\n(sW)*\n(fWu ++. } ++. el {\ ++. if \n(sW==2 .aT \*(bY ++. ie \n(aT==1 {\ ++. nr O\n(dP \n(\*(bY ++. } ++. el .nr O\n(dP \*(bY ++. } ++. } ++.} ++.if "\$1"-compact" {\ ++. nr bV 1 ++.} ++.if \n(iD<\n(.$ {\ ++. ie "\*(bY"" {\ ++. bV \$2 \$3 ++. } ++. el {\ ++. bV \$3 ++. } ++.} ++.. ++." NS Ed macro - end display ++.de Ed ++.ds mN Ed ++.br ++.if \n(dP==0 .tm mdoc: Extraneous .Ed ++.if "\*(d\n(dP"dL" {\ ++. ft \n(cF ++. fz \n(cZ ++.} ++.in \n(.iu-\n(O\n(dPu ++.rr O\n(dP ++.rm d\n(dP ++.nr dP \n(dP-1 ++.fi ++.if t .ad ++.. ++."-------------------------------------------------------------------------- ++." NS Bl macro - begin list (.Bl list-type) ++." NS L[0-9] registers - stack of list types ++.de Bl ++.ie \n(.$==0 {\ ++.tm Usage: .Bl [[-hang | -tag] [-width]] [ -item | -enum | -bullet | -diag] (#\n(.c) ++.} ++.el {\ ++. ds mN Bl ++. nr aP 0 ++. nr lC \n(lC+1 ++. ds A1 \$2 ++. ds A2 \$3 ++. ds A3 \$4 ++. ds A4 \$5 ++. ds A5 \$6 ++. ds A6 \$7 ++. ds A7 \$8 ++. ds A8 \$9 ++. nr fV \n(.$-1 ++. if "\$1"-hang" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC hL ++. nr w\n(lC 6n ++. nr tC 1 ++. } ++. if "\$1"-tag" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC tL ++. nr tC 1 ++. } ++. if "\$1"-item" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC iT ++. nr tC 1 ++. } ++. if "\$1"-enum" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC nU ++. nr w\n(lC 3n ++. nr tC 1 ++. } ++. if "\$1"-bullet" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC bU ++. nr w\n(lC 2n ++. nr tC 1 ++. } ++. if "\$1"-dash" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC hU ++. nr w\n(lC 2n ++. nr tC 1 ++. } ++. if "\$1"-hyphen" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC hU ++. nr w\n(lC 2n ++. nr tC 1 ++. } ++. if "\$1"-inset" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC lL ++. nr tC 1 ++. } ++. if "\$1"-diag" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC mL ++. nr mL 1 ++. } ++. if "\$1"-ohang" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC oL ++. nr tC 1 ++. } ++. if "\$1"-column" {\ ++. nr aP \n(aP+1 ++. ds L\n(lC cL ++. } ++. ie \n(aP==0 {\ ++. tm \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. tm Usage: .Bl [[-inset|-tag] -width] [-item|-enum|-bullet|-diag] (#\n(.c) ++. } ++. el {\ ++. tY ++. if (\n(aP==1)&(\n(aP<\n(.$) {\ ++. nr aP 0 ++. lV ++. if "\*(L\n(lC"cL" {\ ++. W\n(wV ++. nr w\n(lC 0 ++' in -\n(eWu ++. ie \n(v\n(lC==1 {\ ++. nr aa 0 ++. } ++. el {\ ++. sp \n(dVu ++. } ++. nf ++. nr wV 0 ++. } ++. } ++. } ++. nr aP 0 ++." . ds b1 ++. aY ++." .tm Here is L[\n(lC]==\*(L\n(lC ++.} ++.. ++.if \n(.g {\ ++. nr i 10 ++. while \ni<100 {\ ++. nr num!\nin 1 ++. nr i +1 ++. } ++.} ++." NS lV macro - resolve remaining .Bl arguments ++.de lV ++.nr aP \n(aP+1 ++.if \n(fV>=\n(aP {\ ++. nr iD 0 ++. if "\*(A\n(aP"-compact" {\ ++. nr iD 1 ++. nr v\n(lC 1 ++. } ++. if "\*(A\n(aP"-width" {\ ++. nr iD 1 ++. nr aP \n(aP+1 ++. nr tW 1 ++. ds t\n(lC TagwidtH ++. ds tS \*(A\n(aP ++. aW \n(aP ++. ie \n(sW>2 {\ ++. nr w\n(lC (\n(sW)*\n(fWu ++. if \n(sW==3 {\ ++. ie \n(.g {\ ++. if \A'\*(tS' .if r num!\*(tS {\ ++. nr w\n(lC \*(tS ++. } ++. } ++. el {\ ++. if (\*(tS>9n)&(\*(tS<99n) {\ ++. nr w\n(lC \*(tSu ++. } ++. } ++. } ++. } ++. el {\ ++. aT \*(tS ++. ie \n(aT==1 {\ ++. nr w\n(lC \n(\*(tS ++. } ++. el {\ ++. nr w\n(lC \*(tSu ++. } ++. } ++. } ++. if "\*(A\n(aP"-offset" {\ ++. nr iD 1 ++. nr aP \n(aP+1 ++. ie "\*(A\n(aP"indent" {\ ++. nr o\n(lC \n(Dsu ++. } ++. el {\ ++. ds tS \*(A\n(aP ++. aW \n(aP ++. ie \n(sW>2 {\ ++. nr o\n(lC (\n(sW)*\n(fWu ++. ie \n(.g {\ ++. if \A'\*(tS' .if r num!\*(tS {\ ++. nr o\n(lC \*(tS ++. } ++. } ++. el {\ ++. if (\*(tS>9n)&(\*(tS<100n) {\ ++. nr o\n(lC \*(tS ++. } ++. } ++. } ++. el {\ ++. ie \n(C\n(aP==1 .nr o\n(lC \n(\*(tS ++. el .nr o\n(lC \*(tS ++. } ++. } ++. } ++. if \n(iD==0 {\ ++. if "\*(L\n(lC"cL" {\ ++. nr wV \n(wV+1 ++. ds A\n(wV \*(A\n(aP ++. } ++. } ++. if \n(fV>\n(aP .lV ++.} ++.. ++." NS El macro - end list ++." NS iD local register ++.de El ++.ie \n(.$>0 {\ ++. tm Usage: .El (#\n(.c) ++.} ++.el {\ ++. ds mN El ++. nr iD 0 ++. if "\*(L\n(lC"cL" {\ ++. nr iD 1 ++. cC ++. } ++. if "\*(L\n(lC"nU" {\ ++. nr nU 0 ++. } ++. if \n(mL>0 {\ ++. nr iD 1 ++. nr mL 0 ++. tZ ++. nr lC \n(lC-1 ++. tY ++. } ++. if "\*(L\n(lC"iT" {\ ++' in \n(.iu-\n(o\n(lCu ++. tZ ++. nr lC \n(lC-1 ++. tY ++. nr iD 1 ++. } ++. if "\*(L\n(lC"oL" {\ ++' in \n(.iu-\n(o\n(lCu ++. tZ ++. nr lC \n(lC-1 ++. tY ++. nr iD 1 ++. } ++. if "\*(L\n(lC"lL" {\ ++' in \n(.iu-\n(o\n(lCu ++. tZ ++. nr lC \n(lC-1 ++. tY ++. nr iD 1 ++. } ++. if \n(iD==0 {\ ++. lE ++. } ++. br ++. nr iD 0 ++.} ++.. ++." NS It macro - list item ++." NS iD local register ++." NS aA save pA font string for section FILES (no underline if nroff) ++.de It ++.if "\*(L\n(lC"" {\ ++. tm Usage .Bl -list-type [-width [string] | -compact | -offset [string]] (#\n(.c) ++. tm .It \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 ++.} ++." .tm Here is L[\n(lC]==\*(L\n(lC ++.ne 3v ++.ie \n(.$>0 {\ ++. ds mN It ++. ds b1 ++. nr iD 0 ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. if "\*(L\n(lC"mL" {\ ++. nr iD 1 ++. nr aP 0 ++. aX ++. \*(L\n(lC ++. } ++. if "\*(L\n(lC"cL" {\ ++. ds b1 ++. nr aP 0 ++. nr iD 1 ++. \*(L\n(lC ++. } ++. if "\*(L\n(lC"iT" {\ ++. nr aP 0 ++. nr iD 1 ++. \*(L\n(lC ++. } ++. if \n(iD==0 {\ ++. fV ++." tm ------------------------------------------------------------------------ ++." tm It list-type==\*(L\n(lC, aP==\n(aP ++." tm It beg arg(A[1])==\*(A1; oM==\n(oM; dZ==\n(dZ; Xt==\n(Xt; aC==\n(aC ++. nr oM \n(oM+1 ++. nr tP 1 ++. nr aP \n(aP+1 ++. nr tX \n(C\n(aP ++. ds tX \*(A\n(aP ++. if \n(nF==1 {\ ++. ds aA \*(pA ++. if n .ds pA \*(nO ++. } ++. ie \n(C\n(aP==1 {\ ++. \*(A\n(aP ++. } ++. el {\ ++. nr aP \n(aP-1 ++. No ++. } ++." tm in It here is b1==\*(b1 ++." tm It mid arg(A[1])==\*(A1; oM==\n(oM; dZ==\n(dZ; Xt==\n(Xt; aC==\n(aC ++. ie \n(Xt==1 .ds xB &\*(L\n(lC ++. el .\*(L\n(lC ++. } ++. nr iD 0 ++.} ++.el .\*(L\n(lC ++.. ++." NS lL macro - .It item of list-type inset ++.de lL ++.lY ++.br ++&\*(b1 ++.nr oM \n(oM-1 ++.nr tP 0 ++.ds b1 ++.aY ++'fi ++.. ++." NS hL macro - .It item of list-type hanging label (as opposed to tagged) ++.de hL ++.lX ++.nr bb \n(w\n(lCu+\n(lSu ++.ti -\n(bbu ++.ie \w\*(b1u>=(\n(w\n(lCu) &\*(b1 ++.el &\*(b1\h'|\n(bbu'\c ++.nr oM \n(oM-1 ++.ds b1 ++.nr tP 0 ++.aY ++'fi ++.. ++." NS oL macro - .It item of list-type overhanging label ++.de oL ++.lY ++&\*(b1 ++.br ++.nr oM \n(oM-1 ++.ds b1 ++.nr tP 0 ++.aY ++'fi ++.. ++." NS iT macro - .It item of list-type [empty label] ++.de iT ++.lY ++.br ++." .ds b1 ++.aY ++'fi ++.. ++." NS nU macro - Enumerated list ++." NS nU register count ++." NS hU macro - Hyphen paragraph list (sub bullet list) ++." NS bU macro - Bullet paragraph list ++.de nU ++.nr oM \n(oM+1 ++.nr nU \n(nU+1 ++.ds b1 &\n(nU. ++.uL ++.. ++.de bU ++.nr oM \n(oM+1 ++.nr bU \n(bU+1 ++.ds b1 &\*(sY&(bu\fP ++.uL ++.. ++.de hU ++.nr oM \n(oM+1 ++.nr bU \n(bU+1 ++.ds b1 &\*(sY&-\fP ++.uL ++.. ++." NS uL macro - .It item of list-type enum/bullet/hyphen ++.de uL ++.lX ++.nr bb \n(w\n(lCu+\n(lSu ++.ti -\n(bbu ++.ie \w\*(b1u>=(\n(w\n(lCu) &\*(b1 ++.el &\*(b1\h'|\n(bbu'\c ++.nr oM \n(oM-1 ++." .nr dZ \n(dZ+1 ++.ds b1 ++.nr tP 0 ++.aY ++'fi ++.. ++." NS mL macro - .It item of list-type diagnostic-message ++.de mL ++.nr cF \n(.f ++.nr cZ \n(.s ++.ie \n(mL==1 {\ ++. nr zB \n(.c ++. ie (\n(zB-\n(zA)>1 .Pp ++. el .br ++. nr zA \n(zB ++. nr zB 0 ++.} ++.el {\ ++. nr zA \n(.c ++. br ++.} ++&\*(sY\*(b1\f\n(cF\s\n(cZ\*(lS\c ++.aY ++.ds b1 ++'fi ++.. ++." NS tL macro - .It item of list-type "tag" ++.de tL ++." tm in tL here is b1==\*(b1 ++.if \n(tW==0 .lW ++.lX ++.nr bb \n(w\n(lCu+\n(lSu ++.ti -\n(bbu ++.ie (\w\*(b1u)>(\n(w\n(lCu) {&\*(b1 ++. br ++.} ++.el &\*(b1\h'|\n(bbu'\c ++.if \n(nF==1 {\ ++. if n .ds pA \*(aA ++.} ++.nr oM \n(oM-1 ++.nr tP 0 ++." .nr dZ \n(dZ+1 ++.ds b1 ++.aY ++'fi ++.. ++." NS lW macro - resolve unknown label/tag width (if .Bl [inset | tag] only) ++.de lW ++.if !"TagwidtH"\*(t\n(lC" {\ ++. ie \n(tX==1 {\ ++. ds t\n(lN \*(tX ++. nr w\n(lN \n(\*(tX ++. } ++. el {\ ++. ds t\n(lN No ++. nr w\n(lN \n(No ++. } ++. if !"\*(t\n(lC"\*(t\n(lN" .nr tC 1 ++.} ++.. ++." NS lX macro - set up vertical spacing (if compact) and offset+indent (all) ++.de lX ++.ie \n(tC {\ ++. nr tC 0 ++. nr tW 0 ++. if \n(v\n(lC==0 .sp \n(dVu ++. in \n(.iu+\n(w\n(lCu+\n(o\n(lCu+\n(lSu ++.} ++.el {\ ++. ie \n(v\n(lC==1 {\ ++. nr aa 0 ++. } ++. el {\ ++. sp \n(dVu ++. } ++.} ++.if !\n(cR .ne 2v ++.. ++." NS lY macro - set up vertical spacing (if compact) and offset+indent (all) ++.de lY ++.ie \n(tC {\ ++. nr tC 0 ++. nr tW 0 ++. if \n(v\n(lC==0 .sp \n(dVu ++. in \n(.iu+\n(o\n(lCu ++.} ++.el {\ ++. ie \n(v\n(lC==1 {\ ++. nr aa 0 ++. } ++. el {\ ++. sp \n(dVu ++. } ++.} ++.if !\n(cR .ne 2v ++.. ++." NS tS temporary string ++." NS hL macro - hanging list function ++." NS tS temporary string ++." NS hL macro - hanging list function ++." NS lT macro - tagged list function ++." NS lE macro - list end function ++." NS tX string (initial string) ++." NS tX register (initial class) ++." NS tC parameter change flag ++." NS Xt save current list-type flag ++." NS lC register - list type stack counter ++." NS tP register tag flag (for diversions) ++." NS w[0-9] register tag stack (nested tags) ++." NS t[0-9] register tag string stack (nested tags) ++." NS o[0-9] register offset stack (nested tags) ++." NS v[0-9] register vertical tag break stack ++." NS h[0-9] register horizontal tag stack (continuous if 1, break if 0) ++.nr lC 0 ++.nr wV 0 ++.nr w1 0 ++.nr o1 0 ++.nr v1 0 ++.nr h1 0 ++.ds t\n(lC ++.de lE ++." IN lC o[\n(lC]==\n(o\n(lC, w[\n(lC]==\n(w\n(lC, ++.ie \n(o\n(lC>0 {\ ++' in \n(.iu-(\n(w\n(lCu)-(\n(o\n(lCu)-\n(lSu ++. rr o\n(lC ++.} ++.el 'in \n(.iu-\n(w\n(lCu-\n(lSu ++.if \n(lC<=0 .tm Extraneous .El call (#\n(.c) ++.tZ ++.nr lC \n(lC-1 ++.tY ++.. ++." NS tY macro - set up next block for list ++." NS tZ macro - decrement stack ++." NS tY register (next possible lC value) ++.de tY ++.nr tY (\n(lC+1) ++.nr w\n(tY 0 ++.nr h\n(tY 0 ++.nr o\n(tY 0 ++.ds t\n(tY \*(t\n(lC ++.ds L\n(tY ++.nr v\n(tY 0 ++.. ++.de tZ ++.rm L\n(tY ++.rr w\n(tY ++.rr h\n(tY ++.rr o\n(tY ++.rm t\n(tY ++.rr v\n(tY ++.nr tY \n(tY-1 ++.. ++." initial values ++.nr w1 0 ++.nr o1 0 ++.nr h1 0 ++.ds t1 ++.nr v1 0 ++.nr tY 1 ++." NS Xr macro - cross reference (man page only) ++.de Xr ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Xr manpage_name [section#] \*(Pu (#\n(.c) ++. el {\ ++. ds mN Xr ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. ie \n(C\n(aP==1 .tm Usage: .Xr manpage_name [section#] \*(Pu (#\n(.c) ++. el {\ ++. ie \n(C\n(aP>2 .y\n(C\n(aP ++. el {\ ++. as b1 &\*(xR\*(A\n(aP\fP\s0 ++. if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. if \n(C\n(aP==2 {\ ++. as b1 &(\*(A\n(aP) ++. nr aP \n(aP+1 ++. } ++. if \n(aC>=\n(aP {\ ++. c\n(C\n(aP ++. } ++. } ++. } ++. aZ ++. } ++.} ++.. ++." NS Sx macro - cross section reference ++.de Sx ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Sx Usage: .Sx Section Header \*(Pu (#\n(.c) ++. el {\ ++. ds mN Sx ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. as b1 \*(sX ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS cC macro - column-list end-list ++." NS eW macro - column indent width ++." NS cI register - column indent width ++." NS W[1-5] macro - establish tabs for list-type column ++.de cC ++'in \n(.iu-\n(o\n(lCu-\n(w\n(lCu ++.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i ++.fi ++.tZ ++.nr lC \n(lC-1 ++.tY ++.. ++.de W1 ++.ta \w\*(A1 u ++.nr eW \w\*(A1 u ++'in \n(.iu+\n(eWu+\n(o\n(lCu ++.. ++.de W2 ++.ta \w\*(A1 u +\w\*(A2 u ++.nr eW \w\*(A1 u+\w\*(A2 u ++'in \n(.iu+\n(eWu+\n(o\n(lCu ++.. ++.de W3 ++.ta \w\*(A1 u +\w\*(A2 u +\w\*(A3 u ++.nr eW \w\*(A1 u+\w\*(A2 u+\w\*(A3 u ++'in \n(.iu+\n(eWu+\n(o\n(lCu ++.. ++.de W4 ++.ta \w\*(A1 u +\w\*(A2 u +\w\*(A3 u +\w\*(A4 u ++.nr eW \w\*(A1 u+\w\*(A2 u +\w\*(A3 u +\w\*(A4 u ++'in \n(.iu+\n(eWu+\n(o\n(lCu ++.. ++.de W5 ++.ta \w\*(A1 u +\w\*(A2 u +\w\*(A3 u +\w\*(A4 u +\w\*(A5 u ++.nr eW \w\*(A1 u +\w\*(A2 u +\w\*(A3 u +\w\*(A4 u +\w\*(A5 u ++' in \n(.iu+\n(eWu+\n(o\n(lCu ++.. ++." This is packed abnormally close, intercol width should be an option ++.de W6 ++.ta \w\*(A1 u +\w\*(A2 u +\w\*(A3 u +\w\*(A4 u +\w\*(A5 u +\w\*(A6 ++.nr eW \w\*(A1 u +\w\*(A2 u +\w\*(A3 u +\w\*(A4 u +\w\*(A5 u +\w\*(A6 ++' in \n(.iu+\n(eWu+\n(o\n(lCu ++.. ++." NS cL macro - column items ++.de cL ++.if \n(w\n(lC==0 .nr w\n(lC \n(eWu ++.if \n(.u==0 {\ ++. fi ++' in \n(.iu+\n(eWu ++.} ++.ti -\n(eWu ++.fV ++.nr aP \n(aP+1 ++.ie \n(aC>=\n(aP {\ ++. if "\*(A\n(aP"Ta" {\ ++. nr jJ \n(aP-1 ++. rm S\n(jJ ++. rr jJ ++. } ++. c\n(C\n(aP ++.} ++.el .tm Usage: .It column_string [Ta [column_string ...] ] (#\n(.c) ++.. ++." NS Ta macro - append tab (\t) ++.de Ta ++.ie \n(aC>0 {\ ++. nr aP \n(aP+1 ++. ie \n(aC>=\n(aP {\ ++. if "\*(A\n(aP"Ta" {\ ++. nr jJ \n(aP-1 ++. rm S\n(jJ ++. rr jJ ++. } ++. as b1 \t ++. c\n(C\n(aP ++. } ++. el {\ ++. as b1 \t\c ++. rm S\n(aP ++. pB ++. aY ++." . ds b1 ++. } ++.} ++.el {\ ++. tm Usage: Ta must follow column entry: e.g. (#\n(.c) ++. tm .It column_string [Ta [column_string ...] ] ++.} ++.. ++." ++." NS Dl macro - display (one line) literal ++.de Dl ++'ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i ++.in \n(.iu+\n(Dsu ++.ie \n(aC==0 {\ ++. ie \n(.$==0 {\ ++. tm Usage: .Dl argument ... (#\n(.c) ++. } ++. el {\ ++. ds mN Dl ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. Li ++. } ++.} ++.el {\ ++. tm Usage: .Dl not callable by other macros (#\n(.c) ++.} ++.in \n(.iu-\n(Dsu ++.. ++." ++." NS D1 macro - display (one line) ++.de D1 ++'ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i ++.in \n(.iu+\n(Dsu ++.ie \n(aC==0 {\ ++. ie \n(.$==0 {\ ++. tm Usage: .D1 argument ... (#\n(.c) ++. } ++. el {\ ++. ds mN D1 ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. nr aP \n(aP+1 ++. ie \n(C\n(aP==1 .\*(A\n(aP ++. el .No ++. } ++.} ++.el {\ ++. tm Usage: .D1 not callable by other macros (#\n(.c) ++.} ++.in \n(.iu-\n(Dsu ++.. ++." NS Ex macro - DEFUNCT ++.de Ex ++.tm Ex defunct, Use .D1: \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." ++." NS Ex macro - DEFUNCT ++.de Ex ++.tm Ex defunct, Use .D1: \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.. ++." ++." NS Vt macro - Variable type (for forcing old style variable declarations) ++." this is not done in the same manner as .Ot for fortrash - clean up later ++.de Vt ++." if a function declaration was the last thing given, want vertical space ++.if \n(fD>0 {\ ++. Pp ++. nr fD 0 ++.} ++." if a subroutine was the last thing given, want vertical space ++.if \n(fZ>0 {\ ++. ie \n(fX==0 {\ ++. Pp ++. rs ++. } ++. el .br ++.} ++.nr fX \n(fX+1 ++.nr cF \n(.f ++.nr cZ \n(.s ++\*(fT&\$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.ie \n(oT==0 .br ++.el &\ & ++.ft \n(cF ++.fs \n(cZ ++.. ++." ++." NS Ft macro - Function type ++.nr fZ 0 ++.de Ft ++.if \n(nS>0 {\ ++. if \n(fZ>0 {\ ++. Pp ++. nr fD 0 ++. nr fX 0 ++. } ++. if \n(fD>0 {\ ++. Pp ++. nr fD 0 ++. nr fX 0 ++. } ++. if \n(fX>0 {\ ++. Pp ++. nr fX 0 ++. } ++. nr fY 1 ++.} ++.nr cF \n(.f ++.nr cZ \n(.s ++&\*(fT\$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.ft \n(cF ++.fs \n(cZ ++." .br ++.. ++." ++." NS Ot macro - Old Function type (fortran - no newline) ++." Ns oT register ++.nr oT 0 ++.de Ot ++.nr oT 1 ++.if \n(nS>0 {\ ++. if \n(fZ>0 {\ ++. Pp ++. nr fD 0 ++. nr fX 0 ++. } ++. if \n(fD>0 {\ ++. Pp ++. nr fD 0 ++. nr fX 0 ++. } ++. if \n(fX>0 {\ ++. Pp ++. nr fX 0 ++. } ++. nr fY 1 ++.} ++.if \n(.$==4 .as b1 &\*(fT&\$1 \$2 \$3 \$4 ++.if \n(.$==3 .as b1 &\*(fT&\$1 \$2 \$3 ++.if \n(.$==2 .as b1 &\*(fT&\$1 \$2 ++.if \n(.$==1 .as b1 &\*(fT&\$1 ++.as b1 &\ \fP ++.. ++." ++." NS Fa macro - Function arguments ++.de Fa ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Fa Function Arguments ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Fa ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.ie \n(fC>0 {\ ++. fC ++.} ++.el {\ ++. if \n(aC>\n(aP {\ ++. as b1 \*(fA ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++. if \n(nS>0 {\ ++. if \n(fZ>0 .br ++. } ++. } ++.} ++.. ++." NS fC macro - interal .Fa for .FO and .Fc ++.de fC ++.ie \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++." . nr aa \n(aP ++." . if \n(nS>0 {\ ++. ds Fb ++. nr fB 0 ++. nr Fb 0 ++. fB \*(A\n(aP ++. if \n(fB>1 {\ ++. rm A\n(aP ++. rn Fb A\n(aP ++. } ++." . } ++. if \n(fC>1 {\ ++. as b1 &\f\n(cF\s\n(cZ,\*(S\n(aP\*(fA\*(A\n(aP\fP\s0 ++." . as b1 &\,\*(S\n(aP\fP\s0\*(fA\*(A\n(aP\fP\s0 ++. } ++. if \n(fC==1 {\ ++. as b1 &|\*(fA\*(A\n(aP\fP\s0 ++. } ++. nr fC \n(fC+1 ++. fC ++.} ++.el {\ ++. aY ++.} ++.. ++." NS Fn macro - functions ++." NS fY register - dick with old style function declarations (fortran) ++." NS fZ register - break a line when more than one function in a synopsis ++." ++.de Fn ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Fn function_name function_arg(s) ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN Fn ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(nS>0 {\ ++." if there is/has been more than one subroutine declaration ++. if \n(fY==0 {\ ++. if \n(fZ>0 {\ ++. Pp ++. nr fX 0 ++. nr fD 0 ++. } ++. } ++. if \n(fY==1 {\ ++. br ++. nr fX 0 ++. nr fD 0 ++. nr fY 0 ++. } ++. if \n(fD>0 {\ ++. Pp ++. nr fX 0 ++. } ++. if \n(fX>0 {\ ++. Pp ++. nr fD 0 ++. } ++. nr fZ \n(fZ+1 ++. nr fY 0 ++. rs ++. ie \n(nS>1 .br ++. el {\ ++. if \n(iS==0 {\ ++. nr iS ((8)*\n(fW)u ++. } ++. } ++. in +\n(iSu ++. ti -\n(iSu ++. nr nS \n(nS+1 ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. as b1 \*(fN\*(A\n(aP\fP\s0\*(lp ++. ie \n(aC>\n(aP {\ ++. as b1 \*(fA ++. nr aP \n(aP+1 ++. f\n(C\n(aP ++. } ++. el {\ ++. as b1 |\*(rp ++. aZ ++. } ++. if \n(nS>0 {\ ++. in -\n(iSu ++. } ++.} ++.. ++." ++." NS f1 macro - class switch ++." NS f2 macro - handle function arguments ++." NS f3 macro - punctuation ++." NS f4 macro - write out function ++.de f1 ++.as b1 \*(rp\f\n(cF\s\n(cZ ++.\*(A\n(aP ++.. ++.de f2 ++.if \n(nS>0 {\ ++. ds Fb ++. nr fB 0 ++. nr Fb 0 ++. fB \*(A\n(aP ++. if \n(fB>1 {\ ++. rm A\n(aP ++. rn Fb A\n(aP ++. } ++.} ++.as b1 \*(A\n(aP ++.ie \n(aC>\n(aP {\ ++. nr aa \n(aP ++. nr aP \n(aP+1 ++. if \n(C\n(aP==2 {\ ++. as b1 &|\f\n(cF\s\n(cZ,\*(S\n(aa\fP\s0| ++. } ++. f\n(C\n(aP ++.} ++.el {\ ++. as b1 \*(rp\f\n(cF\s\n(cZ ++. aZ ++.} ++.. ++.de f3 ++.as b1 \*(rp\f\n(cF\s\n(cZ\*(A\n(aP ++.ie \n(aC>\n(aP {\ ++. No ++.} ++.el .aZ ++.. ++.de f4 ++.as b1 \*(rp\f\n(cF\s\n(cZ\*(S\n(aP\*(A\n(aP ++.ie \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. No ++.} ++.el .aZ ++.. ++.de Fo ++.hy 0 ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .Fo function_name ++. el {\ ++. ds mN Fo ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(nS>0 {\ ++." if there is/has been more than one subroutine declaration ++. if \n(fY==0 {\ ++. if \n(fZ>0 {\ ++. Pp ++. nr fX 0 ++. nr fD 0 ++. } ++. } ++. if \n(fY==1 {\ ++. br ++. nr fX 0 ++. nr fD 0 ++. nr fY 0 ++. } ++. if \n(fD>0 {\ ++. Pp ++. nr fX 0 ++. } ++. if \n(fX>0 {\ ++. Pp ++. nr fD 0 ++. } ++. nr fZ \n(fZ+1 ++. nr fY 0 ++. rs ++. ie \n(nS>1 .br ++. el {\ ++. if \n(iS==0 {\ ++. nr iS ((8)*\n(fW)u ++. } ++. } ++. in +\n(iSu ++. ti -\n(iSu ++. nr nS \n(nS+1 ++.} ++.if \n(aC>\n(aP {\ ++. nr oM \n(oM+1 ++. nr fC 1 ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. as b1 \*(fN\*(A\n(aP\fP\s0\*(lp ++. aY ++.} ++.. ++.de Fc ++.if \n(aC==0 {\ ++. if \n(.$>0 {\ ++. ds mN Fo ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.nr fC 0 ++.nr oM \n(oM-1 ++.as b1 |\*(rp ++.ie \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. \*(A\n(aP ++.} ++.el {\ ++. aZ ++.} ++.if \n(nS>0 {\ ++. in -\n(iSu ++.} ++.hy ++.. ++." NS fb macro - if SYNOPSIS, set hard space inbetween function args ++." NS fb register - count of words in a function argument ++." NS Fb register - counter ++." NS Fb string - temporary string ++.de fB ++." .tm fB==\n(fB, Fb==\n(Fb, 1==\$1 2==\$2 3==\$3 4==\$4 5==\$5 6==\$6 ++.if \n(fB==0 {\ ++. nr fB \n(.$ ++. nr Fb 0 ++. ds Fb ++.} ++.nr Fb \n(Fb+1 ++.as Fb &\$1 ++.if \n(Fb<\n(fB {\ ++. as Fb &\*(hV ++. fB \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++.} ++.. ++." NS Fc - Function close - not implemented yet ++." NS Fo - Function open - not implemented yet ++." ++." Very crude references, stash all reference info into strings (usual ++." use of b1 buffer, then b1 contents copied to string of retrievable ++." naming convention), print out reference on .Re request and clean up. ++." Ordering very limited, no fancy citations, but can do articles, journals ++." and books - need to add several missing options (like city etc). ++." should be able to grab a refer entry, massage it a wee bit (prefix ++." a `.' to the %[A-Z]) and not worry (ha!) ++." ++." NS Rs macro - Reference Start ++." NS rS register - Reference Start flag ++." NS rS string - Reference Start buffer name for next save (of b1 buffer) ++.de Rs ++.nr rS 1 ++.rC ++.if \n(nA==1 .Pp ++.nr Kl 0 ++.. ++." NS Re macro - Reference End ++.de Re ++.rZ ++.rC ++.nr rS 0 ++.. ++." NS rC macro - reference cleanup ++.de rC ++.nr uK 0 ++.nr jK 0 ++.nr nK 0 ++.nr oK 0 ++.nr qK 0 ++.nr rK 0 ++.nr tK 0 ++.nr vK 0 ++.nr dK 0 ++.nr pK 0 ++.nr bK 0 ++.ds rS ++.rm U1 U2 U3 U4 U5 U6 U7 U8 ++.rm uK jK nK oK rK qK tK vK dK pK bK ++.. ++." NS rZ macro - reference print ++.de rZ ++.if \n(uK {&\*(U1, ++. nr aK 1 ++. if (\n(uK>1 {\ ++. aK ++. } ++. nr Kl -\n(uK ++.} ++.if \n(tK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 {\ ++. ie (\n(jK==1):(\n(bK==1) {&\*q\*(tK\*q. ++. } ++. el {&\*(eM\*(tK\*(nO. ++. } ++. } ++. if \n(Kl>0 {\ ++. ie (\n(jK==1):(\n(bK==1) {&\*q\*(tK\*q, ++. } ++. el {&\*(eM\*(tK\*(nO, ++. } ++. } ++.} ++.if \n(bK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 &\*(eM\*(bK\*(nO. ++. if \n(Kl>0 &\*(eM\*(bK\*(nO, ++.} ++.if \n(jK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 &\*(eM\*(jK\*(nO. ++. if \n(Kl>0 &\*(eM\*(jK\*(nO, ++.} ++.if \n(rK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 &\*(rK. ++. if \n(Kl>0 &\*(rK, ++.} ++.if \n(nK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 &\*(nK. ++. if \n(Kl>0 &\*(nK, ++.} ++.if \n(vK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 &\*(vK. ++. if \n(Kl>0 &\*(vK, ++.} ++.if \n(pK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 &\*(pK. ++. if \n(Kl>0 &\*(pK, ++.} ++.if \n(qK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 &\*(qK. ++. if \n(Kl>0 &\*(qK, ++.} ++.if \n(dK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 &\*(dK. ++. if \n(Kl>0 &\*(dK, ++.} ++.if \n(oK {\ ++. nr Kl \n(Kl-1 ++. if \n(Kl==0 &\*(oK. ++. if \n(Kl>0 &\*(oK, ++.} ++.if \n(Kl>0 .tm unresolved reference problem ++.. ++." NS aK macro - print out reference authors ++.de aK ++.nr aK \n(aK+1 ++.ie (\n(uK-\n(aK)==0 {&and \*(U\n(aK, ++.} ++.el {&\*(U\n(aK, ++. aK ++.} ++.. ++." NS %A macro - reference author(s) ++." NS uK register - reference author(s) counter ++." NS U[1-9] strings - reference author(s) names ++.de %A ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%A Author_name (#\n(.c) ++. el {\ ++. nr uK \n(uK+1 ++. nr Kl \n(Kl+1 ++. ds rS U\n(uK ++. ds mN %A ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS %B macro - [reference] Book Name ++." NS bK string - Book Name ++." NS bK register - Book Name flag ++.de %B ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%B Book Name (#\n(.c) ++. el {\ ++. ds mN %B ++. if \n(rS>0 {\ ++. nr bK \n(bK+1 ++. nr Kl \n(Kl+1 ++. ds rS bK ++. } ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. ie \n(rS==0 {\ ++. as b1 &\*(eM ++. nR ++. } ++. el .rR ++.} ++.. ++." NS %D macro - [reference] Date ++." NS dK string - Date String ++." NS dK register - Date flag ++.de %D ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%D Date (#\n(.c) ++. el {\ ++. ds mN %D ++. nr dK \n(dK+1 ++. nr Kl \n(Kl+1 ++. ds rS dK ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS %J macro - [reference] Journal Name ++." NS jK register - [reference] Journal Name flag ++." NS jK string - [reference] Journal Name ++.de %J ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%J Journal Name (#\n(.c) ++. el {\ ++. ds mN %J ++. nr jK \n(jK+1 ++. ds rS jK ++. nr Kl \n(Kl+1 ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS %N macro - [reference] issue number ++." NS nK register - [reference] issue number flag ++." NS nK string - [reference] issue number ++.de %N ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%N issue number (#\n(.c) ++. el {\ ++. nr nK \n(nK+1 ++. nr Kl \n(Kl+1 ++. ds rS nK ++. ds mN %N ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS %O macro - [reference] optional information ++." NS oK register - [reference] optional information flag ++." NS oK string - [reference] optional information ++.de %O ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%O optional information ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN %O ++. nr oK \n(oK+1 ++. nr Kl \n(Kl+1 ++. ds rS oK ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS %P macro - [reference] page numbers ++." NS pK register - [reference] page number flag ++." NS pK string - [reference] page number ++.de %P ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%P page numbers ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN %P ++. nr pK \n(pK+1 ++. nr Kl \n(Kl+1 ++. ds rS pK ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS %Q macro - Corporate or Foreign Author ++." NS qK string - Corporate or Foreign Author ++." NS qK register - Corporate or Foreign Author flag ++.de %Q ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%Q Corporate or Foreign Author (#\n(.c) ++. el {\ ++. ds mN %Q ++. nr qK \n(qK+1 ++. nr Kl \n(Kl+1 ++. ds rS qK ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS %R macro - [reference] report name ++." NS rK string - [reference] report name ++." NS rK register - [reference] report flag ++.de %R ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%R reference report (#\n(.c) ++. el {\ ++. ds mN %R ++. nr rK \n(rK+1 ++. nr Kl \n(Kl+1 ++. ds rS rK ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS %T macro - reference title ++." NS tK string - reference title ++." NS tK register - reference title flag ++.de %T ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%T (#\n(.c) ++. el {\ ++. ds mN %T ++. if \n(rS>0 {\ ++. nr tK \n(tK+1 ++. nr Kl \n(Kl+1 ++. ds rS tK ++. } ++. ds A1 \$1 ++. ds A2 \$2 ++. ds A3 \$3 ++. ds A4 \$4 ++. ds A5 \$5 ++. ds A6 \$6 ++. ds A7 \$7 ++. ds A8 \$8 ++. ds A9 \$9 ++. nr fV \n(.$ ++. fV ++. } ++.} ++.if \n(aC>\n(aP {\ ++." . ie \n(jS==1 {\ ++." . nr cF \n(.f ++." . nr cZ \n(.s ++." . ds qL &\*(Lq\*(rA ++." . ds qR &\*(Rq\f\n(cF\s\n(cZ ++." . En \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++." . } ++." . el {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. ie \n(rS==0 {\ ++. as b1 &\*(eM ++. nR ++. } ++. el .rR ++." . } ++.} ++.. ++." NS %V macro - reference volume ++." NS vK string - reference volume ++." NS vK register - reference volume flag ++.de %V ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .%V Volume , ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN %V ++. nr vK \n(vK+1 ++. nr Kl \n(Kl+1 ++. ds rS vK ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. rR ++.} ++.. ++." NS rR macro - reference recursion routine ++." NS jM local register ++." NS jN local register ++.de rR ++.hy 0 ++.nr jM \n(C\n(aP ++.ie \n(jM==1 {\ ++." . as b1 &\f\n(cF\s\n(cZ ++. ie "\*(A\n(aP"Tn" {\ ++. nN ++. } ++. el {\ ++. if \n(aC>8 .tm Usage: \*(mN - maximum 8 arguments (#\n(.c) ++. aI rR 1 ++. \*(A\n(aP ++. } ++.} ++.el {\ ++. nr jN \n(aP ++. ie \n(jM==2 .as b1 &\*(A\n(aP ++. el .as b1 &\*(A\n(aP ++." . el .as b1 &\f\n(cF\s\n(cZ\*(A\n(aP\fP\s0 ++. ie \n(aC==\n(aP {\ ++." . as b1 &\f\n(cF\s\n(cZ ++. rD ++. } ++. el {\ ++. nr aP \n(aP+1 ++. as b1 &\*(S\n(jN ++. rR ++. } ++.} ++.rr jM jN ++.. ++." NS rD macro - save b1 buffer in to appropriate name ++.de rD ++.as \*(rS \*(b1 ++.ds b1 ++.ds rS ++.aY ++.. ++." NS Hf macro - source include header files. ++.de Hf ++.Pp ++File: ++.Pa \$1 ++.Pp ++.nr cF \n(.f ++.nr cZ \n(.s ++.ie t {\ ++&\*(lI ++.br ++.ta +9n 18n 27n 36n 45n 54n 63n 72n ++.} ++.el {\ ++.ta +8n 16n 24n 32n 40n 48n 56n 64n 72n ++.} ++.nf ++.so \$1 ++.fi ++.ft \n(cF ++.fz \n(cZ ++.Pp ++.. ++." NS An macro - author name ++." NS aN register ++.nr aN 0 ++.de An ++.if \n(nY==1 {\ ++. ie \n(aN==1 {\ ++. br ++. } ++. el {\ ++. nr aN 1 ++. } ++.} ++.if \n(aC==0 {\ ++. ie \n(.$==0 .tm Usage: .An author_name ... \*(Pu (#\n(.c) ++. el {\ ++. ds mN An ++. aV \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9 ++. } ++.} ++.if \n(aC>\n(aP {\ ++. nr aP \n(aP+1 ++. nr cF \n(.f ++. nr cZ \n(.s ++. nR ++.} ++.. ++." NS Sf macro -defunct ++.de Sf ++.tm .Sf defunct, use prefix or Ns ++.. ++.ds rV "function returns the value 0 if successful; otherwise the value -1 is returned and the global variable \*(vAerrno\fP is set to indicate the error. ++." Ns Rv macro - return values ++." Ns rV string - standard return message ++.de Rv ++.ie \n(.$==0 {\ ++.tm Usage: .Rv [-std] (#\n(.c) ++.} ++.el {\ ++. ds mN Rv ++." . nr aP 0 ++." . nr lR \n(lR+1 ++." . ds A1 \$2 ++." . ds A2 \$3 ++." . ds A3 \$4 ++." . ds A4 \$5 ++." . ds A5 \$6 ++." . ds A6 \$7 ++." . ds A7 \$8 ++." . ds A8 \$9 ++." . nr fV \n(.$-1 ++. if "\$1"-std" {\ ++. nr cH \*(cH ++. if (\n(cH<2):(\n(cH>3) .tm Usage: .Rv -std sections 2 and 3 only ++. br ++&The ++.Fn \$2 ++&\*(rV ++. } ++.} ++.. +diff -Naur groff-1.18.1.4.orig/tmac/euc-jp.tmac groff-1.18.1.4/tmac/euc-jp.tmac +--- groff-1.18.1.4.orig/tmac/euc-jp.tmac 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/tmac/euc-jp.tmac 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,7 @@ ++." euc-jp.tmac ++." ++.cflags 256 ,:;>} ++.cflags 256 ¡¢¡£¡€¡¥¡Š¡§¡š¡©¡ª¡Ë¡Í¡Ï¡Ñ¡×¡Ù¡Û€¡€£€¥€§€©€Ã€ã€å€ç¡Œ ++.cflags 256 ¥¡¥£¥¥¥§¥©¥Ã¥ã¥å¥ç ++.cflags 512 ¡Ê¡Ì¡Î¡Ð¡Ö¡Ø¡Ú ++.hc ¡Ÿ +diff -Naur groff-1.18.1.4.orig/tmac/gb.tmac groff-1.18.1.4/tmac/gb.tmac +--- groff-1.18.1.4.orig/tmac/gb.tmac 1970-01-01 00:00:00.000000000 +0000 ++++ groff-1.18.1.4/tmac/gb.tmac 2006-10-18 18:54:44.000000000 +0000 +@@ -0,0 +1,15 @@ ++." Kinsoku table for the GB2312 encoding of Chinese, recoded from ++." kinsoku.el in Emacs 22.0.50. ++." Checked by Simon Law, who reckons this is "mostly right". That will ++." probably do for now ... ++." ++.cflags 256 ¡¢¡££®£¬¡€¡¥¡Š¡§¡š¡©¡ª¡«¡¬¡¡¯¡±£©¡³¡µ¡·¡¹¡»¡œ ++.cflags 256 ¡¿£»£º£¿£¡¡À¡Á¡Â¡Ã¡ã¡ä¡å¡æ£¯£Ü£¢£ß£þ£üšå ++.cflags 512 šÅšÆšÇšÈšÉšÊšËšÌšÍšÎšÏšÐšÑšÒšÓšÔšÕšÖš×šØšÙšè ++." Simon Law supplied these. ++.cflags 512 £š¡®¡°¡²¡Ž¡¶¡ž¡º¡Œ¡Ÿ ++." ++." http://tcl.apache.org/sources/tcl/tools/encoding/gb2312.txt lists U+FF0D ++." as FULLWIDTH HYPHEN-MINUS. Is this correct? ++." ++.hc £ +diff -Naur groff-1.18.1.4.orig/tmac/groff_trace.man groff-1.18.1.4/tmac/groff_trace.man +--- groff-1.18.1.4.orig/tmac/groff_trace.man 2002-07-13 20:52:47.000000000 +0000 ++++ groff-1.18.1.4/tmac/groff_trace.man 2006-10-18 18:54:44.000000000 +0000 +@@ -31,6 +31,10 @@ + A copy of the Free Documentation License is included as a file called + FDL in the main directory of the groff source package. + .. ++.ig ++A copy of the GNU Free Documentation License is also available in this ++Debian package as /usr/share/doc/groff/copyright. ++.. + . + ." -------------------------------------------------------------------- + ." Setup +diff -Naur groff-1.18.1.4.orig/tmac/troffrc groff-1.18.1.4/tmac/troffrc +--- groff-1.18.1.4.orig/tmac/troffrc 2002-03-02 16:30:46.000000000 +0000 ++++ groff-1.18.1.4/tmac/troffrc 2006-10-18 18:54:44.000000000 +0000 +@@ -13,7 +13,9 @@ + .do ds troffrc!X100 X.tmac + .do ds troffrc!X100-12 X.tmac + .do ds troffrc!ascii tty.tmac ++.do ds troffrc!ascii8 tty.tmac + .do ds troffrc!latin1 tty.tmac ++.do ds troffrc!nippon tty.tmac + .do ds troffrc!utf8 tty.tmac + .do ds troffrc!cp1047 tty.tmac + .do ds troffrc!lj4 lj4.tmac +@@ -36,4 +38,13 @@ + ." Load hyphenation patterns from `hyphen.us' (in the tmac directory). + .do hpf hyphen.us + . ++." For CJK hack. The hardcoded list of locales is especially nasty, but ++." getting the locale charmap requires a troff extension. ++.ie "\V[LANG]"ja_JP.eucJP" .do mso euc-jp.tmac ++.el .ie "\V[LANG]"zh_CN" .do mso gb.tmac ++.el .ie "\V[LANG]"zh_CN.GBK" .do mso gb.tmac ++.el .ie "\V[LANG]"zh_SG" .do mso gb.tmac ++.el .ie "\V[LANG]"zh_SG.GBK" .do mso gb.tmac ++.el .if "\V[LANG]"zh_TW" .do mso big5.tmac ++. + ." Don't let blank lines creep in here. +diff -Naur groff-1.18.1.4.orig/tmac/tty.tmac groff-1.18.1.4/tmac/tty.tmac +--- groff-1.18.1.4.orig/tmac/tty.tmac 2002-04-20 14:51:11.000000000 +0000 ++++ groff-1.18.1.4/tmac/tty.tmac 2006-10-18 18:54:44.000000000 +0000 +@@ -68,7 +68,7 @@ + .ie '*(.T'cp1047' \ + . do mso cp1047.tmac + .el \ +-. if '*(.T'latin1' \ ++. if !'*(.T'ascii' \ + . do mso latin1.tmac + . + ." If you want the character definitions in tty-char.tmac to be loaded diff --git a/pkgs/core/grub/grub.conf b/pkgs/core/grub/grub.conf new file mode 100644 index 0000000..df7481f --- /dev/null +++ b/pkgs/core/grub/grub.conf @@ -0,0 +1,37 @@ +timeout 10 +default saved +#serial --unit=0 --speed=9600 +foreground = 6d6963 +background = ffffff +#hiddenmenu +splashimage (hd0,0)/grub/splash.xpm.gz +title IPFire (1024x768) + root (hd0,0) + kernel /vmlinuz-ipfire root=ROOT panic=10 vga=791 @SERIAL@ MOUNT + initrd /ipfirerd.img + savedefault 0 +title IPFire (VESA) + root (hd0,0) + kernel /vmlinuz-ipfire root=ROOT panic=10 @SERIAL@ MOUNT + initrd /ipfirerd.img + savedefault 1 +title IPFire SMP (1024x768) + root (hd0,0) + kernel /vmlinuz-ipfire-smp root=ROOT panic=10 acpi=off vga=791 @SERIAL@ MOUNT + initrd /ipfirerd-smp.img + savedefault 2 +title IPFire SMP (VESA) + root (hd0,0) + kernel /vmlinuz-ipfire-smp root=ROOT panic=10 acpi=off @SERIAL@ MOUNT + initrd /ipfirerd-smp.img + savedefault 3 +title IPFire SMP-HT (Intel Pentium 4) (1024x768) + root (hd0,0) + kernel /vmlinuz-ipfire-smp root=ROOT panic=10 acpi=ht vga=791 @SERIAL@ MOUNT + initrd /ipfirerd-smp.img + savedefault 4 +title IPFire SMP-HT (Intel Pentium 4) (VESA) + root (hd0,0) + kernel /vmlinuz-ipfire-smp root=ROOT panic=10 acpi=ht @SERIAL@ MOUNT + initrd /ipfirerd-smp.img + savedefault 5 diff --git a/pkgs/core/grub/grub.nm b/pkgs/core/grub/grub.nm new file mode 100644 index 0000000..2cf83d5 --- /dev/null +++ b/pkgs/core/grub/grub.nm @@ -0,0 +1,75 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = grub +PKG_VER = 1.98 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Boot +PKG_URL = http://www.gnu.org/software/grub/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Grand Unified Boot Loader. + +PKG_BUILD_DEPS+= autoconf automake bison paxctl +PKG_DEPS += freetype ncurses + +define PKG_DESCRIPTION + GRUB (Grand Unified Boot Loader) is an experimental boot loader \ + capable of booting into most free operating systems - Linux, FreeBSD, \ + NetBSD, GNU Mach, and others as well as most commercial operating \ + systems. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define QUALITY_AGENT_WHITELIST_EXECSTACK + /usr/sbin/grub +endef + +#CFLAGS += -fno-strict-aliasing -fno-stack-protector -fno-pic -fno-pie -nopie +#CXXFLAGS = + +define STAGE_BUILD + cd $(DIR_APP) && \ + grub_cv_prog_objcopy_absolute=yes \ + ./configure \ + --prefix=/usr \ + --sysconfdir=/etc + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + sed -e "s/pkgdatadir/pkglibdir/g" -i $(BUILDROOT)/usr/sbin/grub-install + + mkdir -pv $(BUILDROOT)/boot/grub + for i in $(DIR_SOURCE)/{grub.conf,splash.xpm.gz}; do \ + cp -vf $$i $(BUILDROOT)/boot/grub; \ + done +endef diff --git a/pkgs/core/grub/splash.xpm.gz b/pkgs/core/grub/splash.xpm.gz new file mode 100644 index 0000000..ff94776 --- /dev/null +++ b/pkgs/core/grub/splash.xpm.gz @@ -0,0 +1,497 @@ +/* XPM */ +static char * Bootsplash_xpm[] = { +"640 480 14 1", +". c #030303", +"+ c #171717", +"@ c #272727", +"# c #383838", +"$ c #4A4A4A", +"% c #575757", +"& c #6F6F6F", +"* c #888888", +"= c #989898", +"- c #A8A8A8", +"; c #B8B8B8", +"> c #C7C7C7", +", c #D7D7D7", +"' c #E7E7E7", +">;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>>;>>;>>;>>>;>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>>,>>,>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,,>,,>,,>,,,>,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,',,',,',',,',',,',',',',',',',',',',',',',',',','','','','','',''',''',''','", +";>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>>;;>>>;>>;;>>>;;>;>;>;>;>;>;>;>;>>;>>;>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>>,>,>,>,>,>,>,>,>,>,,>,,>,,>,>>,>>,>>,>>,>,>,>>,>,>,>,>>,>,>,>,>,>,>,>,>,>,,>,,>,,>,,>,>,,>,,>,,>,,>,,,>,,,>,,,>,,,>,>,>,>,>,>,>,,>,,>,,>,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,',,',',',',',',',',','','','',',,',,',,',,',',',,',',',',,',',',',',',',',','','','','',','','','','',''',''',''','''", +">>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>>;;>;>>>;>>;>>>;>;>;>>>;>;>>>>>;>>>;>>>;>>>>>>>;>>>>>;>>>;>>;>>;>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>,>>>,>,>,>>,>,>>,>>>,,>>,>>,>,,>>,>,>,>,>,>,>,>,,>,>,>,>,>,>,,,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,,,,>,,,,,>,,>,,,,,,,,,,,,,,,>,,>,,>,,>,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,',,',,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,',,,',',',,',',,',,,'',,',,','',,',',',',',',','',',',',',',','',',',',',',',',',',',',',''", +";>>;>;>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>;;>>>>>;;>>;;>;>;>>>;>>>;>>>;>;>>>;>>>;>>>;>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>>,>,>,>,>,>,>,>>,>>>,>,>>>,>>>>,>,>>,>,>>,>,>>,,>,>>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>>,,>,,,>,,,>,,,>,,,,,,,,,,,,,>,>,,,,,>,,,,,,,,>,>,,>,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,',,',',',',',',',,',,,',',,,',,,,',',,',',,',',,'',',,',,',',',',',',',',',',',',',',','',''',''',''',''''''''''''','", +";>;>>;>>;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>;>;>;;;>;>>;>;;;>>;>;>>>;>>;>>>;;>>;>>>>;>;>>;>>>;>>>>>>;>;>>>;>;>>;>>>;>>>;>>>;>>>>>;>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>,>>,>>>>>,>>>>>,>>>>>>>>>>>>>>,>>,>>>>,>,>>,,>>,>>,>>>,>,>,>,>>,>,,>>,>,>,>,>,>,>,>,>,>,>,,,>,>,,>,,,,>,,>>,,>,>,>,,,>,>>,>,>,>>,,,,,>,>,,,>,>,,>,,,,,,,,,,,,,,,,,,>,,,,,>,,,,,,,,,>,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,',,',,,,,',,,,,',,,,,,,,,,,,,,',,',,,,',',,'',,',,',,,',',',',,','',,',',',',',',',',',',''',','','',',',,'',,'',','',',',',',','''", +";>;>;>;;>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>;>>>;>;>;>>>>>;>>;>;>>;>;>;>>>>;>;>;>>>>>>>>;>>>;>;>>>>>>>>>>>>>>;>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>,>>>>>>>>>,>>,>>,>>>>>>>,>>>>>>,>>>,>,>,>,>,>,>,>>>,>,>,>>>>,>>>,>>,>>,>,>>>,>,>,>>,>>,,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>>,>,>,,,>>,,,>,>,>,,,,>,>,,,,,,>,>,,,,>,,,,,,,>,,,>,>,,>,,>,,>,,,,,>,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,',,,,,,,,,',,',,',,,,,,,',,,,,,',,,',',',',',',',,,',',',,,,',,,',,',,'',,',,,',',,',,'',',',',',',',',',',',,'',',',',','''',''',,''',','','','','','", +";>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>;>;>>;;>;>>>;;>;;>;>;>>;>>;>>>;>;>;>>>>>;>;>;>;>>>;>>>>>;>>;>;>>;>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>>>>>>>>>>>>>>>>>>>,>>>>>>,>,>>,>,>,>,>,>,>>,>,>>,>>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,>,,>,,,,>>,,,>,,>,>,,,,>,>,>,,,,,>,,>,>,>,,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,',,,,,,,,,,,,,,,,,,,',,,,,,',',,',',',',',,,',,'',',,',',',,,',',',',',',',','','',',','',''',,'',',''','','','','','','''", +">;>;>>;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;>;>;;>>;>;;>>;>>>;>;>>;>;>>;>;>>>;>>;>;>>;>>>>>>;>>;>>;>>>>>>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>>>,>>>>>>>>>,>,>,>,>,>,>,>,>>,>,>,>,>>>,>>>>,>>>,>>,>,>>,>,>,,>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,>,>,>,>,,,>,>,>>,,>,>,,>,,,,>,>,>,,,,,>,>,,>,,,,,,,,>,,,,,>,,>,>,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,',,,',,,,,,,,,',',',',',',',',,',',',',,,',,',,,',,,',',',,,','',',',',',,',',',',',',',',',','',','',,''',','',',',''''','','',''','", +">;>;;>;>;>>;>>;>>;>;>>>;>>;>;>>;>>;>>;>;>>>;>>;>;>>;>>;>>;>;>>>;>>;>;>>;>>;>>;>;>>>;>>;>;>>;>>;>>;>;>>>;>>;>;>>;>>;>>;>;>>>;>>;>;>>;>>;>>;>;>>>;>>;>;>>>;>>;>;>>>;>;>>;>>>>>;>>>;>;>>>>>>;>;>>;>>>>>>>;>>;>>;>>>>;>>;>>>;>>>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>,>,>,>>>>>>>>>>>>>>>>>>,>>>,>>>,>,>>,>,>,>,>>,>>>,>>,>,>>>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,>,,,,>,,,>,,,,>,>,,,>,,>,>,,,,,>,,,>,>,>,,,,>,,,,,,,,,,>,,,,,,,,,,,,,>,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,',',',,,,,,,,,,,,,,,,,,',,,',,,',',,',,'',,'',,',,',',',,,',,',','',',',',',',','','','',',',','',,'''',','','',,''','','',''''", +";>;>>;>;>;>;>;>;;>;>;;>;>;>;>;>;>;>;;>;>;;>;>;>;>;>;>;>;;>;>;;>;>;>;>;>;>;>;;>;>;;>;>;>;>;>;>;>;;>;>;;>;>;>;>;>;>;>;;>;>;;>;>;>;>;>;>;>;;>;>;>;>;;>>;;>;>;>;>>;;>;>>;>>;;>;>>;;>>>>;>;>;>>>>;>>>>;>;>>>;>>>>>;>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>>>,>>,>>>>>>>>,>>,>,>,>,>,>,>,>>,>,>>,>>>>,>>,>>>,>,>>,,>,>,>>>,,>,>,>>,>>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,>,,,>,>,,>>,,>>,>,,,,>,,,>,,,,>,>,,,>,,,,,,,>,,,,,>,,>,,,,,,,,>,,>,,,>,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,,,,',,',,,,,,,,',,',',',',',',',,',',,',,,,',,',,,',,,,',,',',,,'',',',,',,',',',',',',',',',,',,','','',''',,',''','','''','',''''',','", +">>;;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>>;>>;;>;>>;;>>;>>>;>>;>>>;>;>>;>>>>;>>>>;;>>>>>>>;>;>>>;>>>>>>;>>>>;>>>>;>>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>,>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>>>>>,>>>>,>>,>,>>,>>,,>>>,>,>>>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,,>>,>,>,,,,>,,,,,>,>,,>,,,>,>,,,,,>,,,>,>,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,',,,',,,,,,,,,,,,,',,,',,,,,,,,,,,,,,,,,,',,,,',,',',,',,'',,'',',',,,''',,',',',',',',',',',',',',',''',''',',','',','',',,'','',','','',',,'''''", +";>>>;>;>;>;>;>;>;>>;;>;>;>;>;>;>;>;>;>>;;>;>;>;>;>;>;>;>;>>;;>;>;>;>;>;>;>;>;>>;;>;>;>;>;>;>;>;>;>>;;>;>;>;>;>;>;>;>;>>;;>;>;>;>;>;>;>>;>;;>>;>;>>;>;>;;>;>;>;;>>;>;>>>;;>>;>;>>;>;>;>;>>>>>;>>;>>;>>>>>;>>>;>>>>;>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>,>>>,>>,>>>,>>>>,>,>,>,>,>,>,>,>>>>,>,>>,>>>,>>,>>>,,>>,>>,>>>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>>,,,,,,>,>>,,>,>,>,,,>,,>,>,,,,>,>,,,>,,,,,,>,,,>,,>,>,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,',,,',,',,,',,,',,',',',',',',',,,,',',,',,,',,',,,',,,',,,'',,,',',,,',',',',',',',',',',',',,'',,','',',',''',''',','',''',''',''''',','", +";;;>;>;>;>;>;>;>>;>>;>;>>>;>;>;>;>;>>;>>;>;>>>;>;>;>;>;>>;>>;>;>>>;>;>;>;>;>>;>>;>;>>>;>;>;>;>;>>;>>;>;>>>;>;>;>;>;>>;>>;>;>>>;>;>;>;;>;>>;>;>>;;>;>;>>>;>>;>>>;>;>>;;>>>;>>>;>>>>>>;>>;>;>>>;>>>>>;>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>,>>>>,>>,>>,>>,>,>>>,>>,>,>,>,>,>,>,>,>>>,>,>,>,>,>,>,>,>,,>,>,>,>,,,>,,,>>,>>,,>,,>,,,>,,>,,,>,,,,>,>,,,,>,,,>,>,,,,,>,,,,,,,,>,,,,,,>,,>,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',',,,,',,',,',,,'',,'',,'',,,'',,','',',,,',',',',',',',','''',,'',',,''','',,'',''',','','',','',',''''''", +">>;>>;>>;>>;>>;;>;>;>;>;;>>;>;>;>>;;>;>;>;>;;>>;>;>;>>;;>;>;>;>;;>>;>;>;>>;;>;>;>;>;;>>;>;>;>>;;>;>;>;>;;>>;>;>;>>;;>;>;>;>;>;>;>>>;>>;>;;>>;;>>>;>;>;;>>;>>;;>>;>;>>>>;>>;;>>;>;;>>>>;>>>>;>>;>;>>>>>>>;>>;>;>>>;>>>>>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>,>>,>>,>>>>,>>>,>,>,>,>,>,>>>>,>,>>,>,>>,>>,>>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>>,>,>,,>,,,>,,>,>,>,,>,>,>,,>,>,,,,,,>,,,>,,,,,,>,,,,,>,,>,,,,,,>,,,,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,',,',',,',,',',,',',',',',',,,,',',,',,',,,',,,',,,',,,',',,',,',,',',',',',',',',',',',,','','','',,'','''',',,'''','',''''',''',',','", +";>>;>;>;>;>;>;>>;>;>>;>>;;>;>>>;;>>;>;>;>;>>;;>>;>>;>;>>;>;>>;>>;;>;>>>;;>>;>;>;>;>>;;>>;>>;>;>>;>;>>;>>;;>;>>>;;>>;>;>;>>;;>;>>;;>;>;>>>;;>>;;;>;>>>>;>;>;>>>;>;>>;>;>>;>>>;>>>>>;>;>>>;>>;>>>>>>;>;>>>>;>>>>>>>>>;>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>>>>>,>>>>>>>>>>>>,>,>>>,>>>>>,>>,>>,>,>>>,>,>>,>>>,>>,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,,>,,>,>,>,,>,,>,,,>,,,,,,>,,>,,>,>,>,,,>,,,>,>,,,,>,,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',',,,',,,',,',','',,'',,'',,',','',',,',',',',',',',',',','',',',',',','','',,','''',,''','',',,'',''''''''", +">;;>;>;>;>;>;>;;>;>;;>;;>>;>;;>>;>;>;>;>;>;>>;;>>;;>;>;;>;>;;>;;>>;>;;>>;>;>;>;>;>;>>;;>>;;>;>;;>;>;;>;;>>;>;;>>;>;>;>;>;;>>;>;;>>;>;>;;>>;>;>>>;>;>;>;>>;>;>;>>;>;>>>;>>;>;>>;>;>>>>>;>>;>>>;>>;>>>>;>>>>>>>>;>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>,>>>,>>>>>>,>>>,>>>>>,>,>,>>,>>>,>,>,>,>,>,>>>>,>>,>,>,>>>>,>,>>>,>,>>>>,>,>,>,>,>,>,>>>,>,>,>,>,>,>,>,>,>>,,>,>,>,,>,,>,,>,>,>,>,>,,>,>,>,,>,,>,,,,,,,>,,,>,,,,,>,,,,,>,,>,>,,,,,>,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,',,,',,',',',,',,,,,',',',',',,,,',,',',,',,,',,,',,,',,',',,',,,',',,',,,',',',',',',','',',',',',','',',''','',,''',,''',''''''',',',','", +">>;>;>;>;>;>;>>;>;>>;>>>;>;>>;;>;>;>;>;>>;>;>>;;>>;>;>>;>;>>;>>>;>;>>;;>;>;>;>;>>;>;>>;;>>;>;>>;>;>>;>>>;>;>>;;>;>;>;>;>>;>;>>>;;>;>;>>;;>;>;>;>;>;>;>>;>;>>;>;>>>;>;>>;>>>>;>;>>;>;>>>>>>;>>>>>>>>>>>>;>;>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>>>>>,>>>,>>>>>>>>>>>>,>,>>,>>>,>>,>,>>>,>,>,>,>,,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>,,,>,,>,>,,>,>>,,>,,>,>,,,>,,,>,,,,>,,>,,>,,>,>,>,,,>,,,>,,>,,,>,>,,,,,,,,,,,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,',,,',,,,,',,,,,,,,,,,,,',',,,,,,,,,,',',,',,,,',,',,,'',,'',,',,,',','',,',',''',',',',',',',',,',''','','',','',','',''','''',',',',',,'''''''''", +";;>>;>>;>;>>;>;>>;>;>;;;>>;>;>>;>;>;>;>;>;>;>;>>;;>>;>;>>;>;>;;;>>;>;>>;>;>;>;>;>;>;>;>>;;>>;>;>>;>;>;;;>>;>;>>;>;>;>;>;;>;>;>;>>;>>;>;>>;>;>;>;>;>;>;>>;>;>>;>;>>;>>;>>>;;>>>>>>>;>>;>;>>>;>;>;>;>>>;>>>>>>>>>>>>>>>;>>>>>;>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>>>>,>,>,>,>>,>>>>,>>>,>>>,>>>,>,>,>>>,>>>,>,>>,>,>>,>>,>,>,>,>,>,>,>,>,>,>,,>,>,>>,,,,>,>,>,,,>,>,,>,,>,>,,>,,>,,>,,,,,,,>,,,>,,,,,,,,,,,,>,,>,,,,>,,,,,>,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,',,,',,',,,,,',',',',,,,,',,',',,',',',,,',,,',,'',,',',,',',',,,,',',',',',',','',',',',',',','',',','',,',',',''''',''''',',',','", +">>;;>;>;>;;>;>;;>;>;>>>;;>;>;>;>>;>;>;>;>;>;>;>;>>;;>>;;>;>;>>>;;>;>;>;>>;>;>;>;>;>;>;>;>>;;>>;;>;>;>>>;;>;>;>;>>;>>;>>>;>;>;>;;>;;>;>;;>;>;>;>;>;>>>;>;>>;;>>;>;>>;>>;;>>>;>;>;>>>>;>>>;>>>>>>>>>;>>>>;>>;>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>>>>>,>,>>>,>,>>,>,>>>>>>>>>,>>>,>>,>,>>,>,>>,>,>>>,>,>>,>,>>,,>,>,>,>,>,>,>,>,>,>,>,>,>>,>,>,>,>,,,>>>,,,>,,>>,,>,>,>,,,>,>,,,,>,,,>,>,>,,,>,,,>,>,,,>,,,,,,,,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,',,,,,,,,,',,,,,,',',,,,,,,,',',,',,,,',,,,,,',',,',,',,,',',,',',',','',',',',',',','',','',',','',''',',''',',''','''',',''',',''''''''''", +";;>>;>;>;>>;>;>>;>;>;>;>>;>;>;>;;>>>;>;>>;>;>;>;>;>>;;>>;>;>;>;>>;>;>;>;;>>>;>;>>;>;>;>;>;>>;;>>;>;>;>;>>;>;>;>;;>;>;>;;>>;>;>>;>>;>;>>;>>;>;>;>>;>;;>>>;>>>;>;>>;>>;>>>;>;>;>>>;>;>>>;>>;>;>>;>>>>>;>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>,>,>,>>>>,>>,>>,>>,>>>>,>>>,>,>>,>,>>>>,>>>,>,>>,>>>,>,>,>,>,>,>,>,,>,>,>,,,>>>,,,>>,,>,,,>,,,,>,,>,,,,>,>,,,>,,,,,,,>,,,>,,,,,>,,,>,,>,>,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,',,',',,,',,',,,,,,',',',,,,',,',',',,',',',,',',',',',',',',',,',,',,',',',',',',',','',,',',',',,','',','','',''',',''',',''',',',',','", +">;>;>>;>;>;>>;>;>>;>;>;;>;>;>;>>>;;>;>;;>;>;>;>;>;;>>;>;>>;>;>;;>;>;>;>>>;;>;>;;>;>;>;>;>;;>>;>;>>;>;>;;>;>;>;>>;>;>;>>;;>;>;>;>;>;>;>;>;>;>;>;>;>>>>;;>>;;>;>>;>>;>>;>>;>>>>;>>>>;>;>>>>>>>;>>>;>;>>;>>;>>>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>,>>>,>>>>>>>>>>>,>,>>>>,>>>,>>,>,>>,,>,>>,>>>,>,,>,>,>,>,>,>,,>,>,>,>,>,>,>,>>,>,>,,>>,,,,>>,,,>,>,>,,>>,,>,,>,>,,,>,>,,>,>,>,,,,>,,,>,,>,,,>,,,,,,,,>,,,,>,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,,',',',,,,,,',',,,,,,',,',',,,',',,',,',,',,,',',',',',',',',',',',',',,',',''','',''',',''',','',',','',','','',''''''''''''", +";>;>;;>>;>;>;>;>;;>;>;>>;>;>;>;;;>>;>;>>;>;>;>>;>>;>;>;>;;>;>;>>;>;>;>;;;>>;>;>>;>;>;>>;>>;>;>;>;;>;>;>>;>;>>;>;>;>>;>;>>;>;>;>;>;>;>;>;>;>;>>;>;>;;>>;>;>>>>;>>;>>;>>;>>;>;>>;>;>>>>;>;>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>;>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>>>,>>>>,>>>>>,>>>,>>,>,>,>,>>>>,>,>>>,>>>,>>>,>>>>,>,>,>,>,>>>,>,>>,>,>,>>,>,>,>,>,>,>,>,>,,>,>>,,>>>,,,>>,,>,,>,>,,>,,>,,>,,>,,,,>,,,,,,>,>,,,>,,,,,,,,,,>,,,>,,,,>,,,,>,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,',',,,',,',',,,,,,,,,',',,,,,'',',,',,,,',',,,',,',,',,',',,,',',',',',',',',',',','',',',,',',',',''',,'',','',''','''','','',',',',',','", +";>;>>;>;>>;>;>;>>;>;>>;>;>>>;>>>;;>>;>;>;>;>;>;>;>;>;>;>>;>;>>;>;>>>;>>>;;>>;>;>;>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>>;;>;>;>;>>;>;>;>>>;>;>;>;>>;>;>;>>;>>;>;>;;>;>>>;>>;>>;>>>;>>>>>;>>>>>>>>;>>>>>>;>>>;>;>>;>;>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>,>>>>>>,>>,>>>>>>>>,>>>>>,>,>>,>,>>,>>,>,>>>,>>,>>>,>,>>,,>,>>>,>,>>,>,>,>,>,>,>,,>,>,,>,,,,>>>,,,>,,>,,>,>,,>,,>,,>,>,>,,>,,>,>,,,,>,,,>,>,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,,,,,,,',',',',,,,',',,,,,',,,',',,,',',',',',,',',',',',,,',,,',',',',',',',,','''','',',',',,''',''',',','',',''','','''''''''''''", +">>;>;>;>;;>;>;>;>;>>;;>;>;>;>;;>>;>;>;>>;>>;>;>;>;>;>;>;>;>>;;>;>;>;>;;>>;>;>;>>;>>;>;>;>;>;>>;>;>;>;>>;>;>;>;>;;>>;>;>;>;>>;>;>;;>>;>;>;>;>;>;>>;>;>;>>>;>>>>;;>>>;>>;>>;>>>;>;>>;>;>;>;>>;>>;>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>>>>>>,>,>,>>>,>,>>>,>>,>>>,>>,>>,>,>,>>,>,>,>,>,>>>,>,,>,>>,,>,>,>,>,>,>,>>,>,,>,>>>,,,,>,>,>,,>,,>,>,,>,,>,,,,,,>,,>,,,,,,>,,,>,,,,,,,>,,>,,,,,>,,,,>,,,,>,,,,,,>,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,,,,',,,,,',,',,,,,,,,,,',,,,,',',',,',,',,',,',,',,,',',,,',',',''',',',',',',',',','',',,',','',','''',',',',''',',''',','''',',',',',',','", +";>;>;>;>>;>;>;>;>;>;>>>;>;>;>>;;>;>;>;;>;>;>;>>;>;>;>;>;>>;;>>>;>;>;>>;;>;>;>;;>;>;>;>>;>;>;;>;>;>>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>>;;>;>>>;>;>;>;>>;>>;>;;>>;;>;>>;;>>;>>;>;>;>>>>;>>>>>;>>>>>>>>;>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>,>>,>>>>>>,>>,>>,>>>>,>>>,>>>>>>>>,>>,>>>>>>>,>>>>>,>>>,>>,>>>,>>,>>>,>>,>,>>,>>,>,,>,>>>,>,>,>,>,>,>,>,>,>,,,,>>,>,,,,>>>,,,>,,>,>,,>,,>,,>,,>,>,>,,>,,,>,>,,,>,,,>,,>,,,,,,,>,,>,,,>,,,,>,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,',,,',,,,,,,,',',',',,,',',,,,',,',,',,',,',,',,',',,',',',',,',,,',',,',',',',',',,'',',',',,','',,'',''',',','''','''',','''','''''''''''", +">;>;>>;>;>;>;>;>;>;>;;>;>;>;>;>>;>;>;>>;>;>;>;>>;>;>;>;>;;>>;;>;>;>;>;>>;>;>;>>;>;>;>;>>;>;>>;>;>;;>;;>>;>;>>;>;>;>;>;>;>;;>>;>;;>>;>;>;>;>;>;>;>>;>>;>>;>>;>>>>>>;>>;>>;>>>;>;>>>>;>>>>;>>;>>>>;>;>>>>;>>;>>>;>>>>>;>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>>>>>>,>,>,>>>,>,>>,>,>>,>,>,>>,>,>,>,>,>>>,>>,>>,>>,>,>,>,>,>,>,>,>,>,>,>,>>>,,,>,>,>>,,,>>,,>,,>,>,,>,,>,,>,,,>,,>,,,>,,,,,>,,,>,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,',,,,,,,,,,,,,,,',,',,',,,,,,,,,',,,,',',,',,',,',,',',',,',',,',',',,',',',',','',',',',',',',',''','''',','',',',',''','',','',',''',',''',',',',','", +">;>;;>;>;>>>;>;>;>;>>;>;>;>;>;>;>;>>;>;>;>>;>;;>;>>>;>;>>;>;>>;>;>;>>;;>;>>;>;>;>;>;>;;>;>;>;>>;>>;>>>;>;>;;>;>;>;>>;>>;>>;>;>;>>;>;>;>;>;>;>;>;;>;>;>;>;>>;>;;>;>>;>>;>>;>>>>>;>;>>;>;>>;>>;>>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>,>>>>>,>,>>>>>>,>>,>>>>>>,>>>>>,>>>,>>>>>>,>>>>>,>>>>,>,>>,>,>,>,>,>,>,>>>,>,>,>,>,>,>,>,,,>>,>,,>,,>,>,,,>,>,,>,,>,>,,,>,,>,,,>,,>,,,>,>,,,>,,,>,>,,,,,,>,>,,>,,,,,,>,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,',,,',,',,',,,,,,,,,,',',',',,,',,,,',,,',,',,',,,',,',',,',,,',,',',',,',,',,',',',',',','',',,',',,',','',''','',,'',','',','','','',''''''''''''", +";>;>>;>;>;;;>>;>>;>;;>;>;>;>;>;>>;>;>;>;>;;>;>>;>;;;>>;>;>;>;;>;>>;;>>>;>;>>;>;>;>;>;>>;>;>;>;>;>;>;;>;>>;>>;>;>>;>;>;;>;>;>>;>;;>>;>;>>;>;>;>>>>;>>>;>>;>;>>>>>>;>>;>>>;>>;>;>>>>;>>>>>>>>>>;>;>>>>;>>>;>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>>>>>>,>>,>>>>>>>,>>,>>>,>,>>>,>>,>,>,>>>,>,>>,,>,>,>,>>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,>>,,>,>,,>,,>,,>,,>,,>>,,>,>,>,,,,,>,,,>,,,,,,,>,,,,,,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,',,',',,,,,,,,,,',,,',',,',,',,',,,',',',,,',,'',,'',,',,'',',,'',',',',',',',,','',',','',','',',','',',''','''''','',''',',',',',','", +">;>;>;>;>>>;>;>;>;>>;>;>>;>>;>;;>;>;>;>;>>;>;>;>>>>;>;>;>;>>>;>;;>>;;;>;>;;>;>;>>>;>;>;>>;>;>;>;>;>>;>;;>;>;>>;;>;>;>>;>;>;;>;>>>;>;>;;>;>;>;>;;>>;;>>;>;>>;>;>;>>;>>;;>>;>>>>;>;>>;>;>;>>>>>>>>>;>>>>;>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>>>>>,>,>>>>>>>>>,>,>>>>,>>,>>>>>,>>,>>,>>>,>,>,>>,>>>,>>,>>,>>,>>,,,>,>>,>,>>,>,>,>,>,>,>,>,>,>,,>,>,>,,,,,>,,,>,>,>,,>,,>,,>,,,,,,,,,,>,>,,,>,,,>,,>,>,,,>,,>,,,,,,,,,,,,,,,,>,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,',,,,',,,',,',,',,,,,,,,',',',',,,',,,,,',,',,,,,',',,,,',',',',,',,',',',,,',',,',',',',',','''',','','',','',',''','','',''',',','','',''''''''''''''", +">>;>;>;>;>;>;>;>;>>;>;>;>;>;>;>>;>;>;>>;>;>;>;>;;>;>;>;>;>;;;>>>;>;>>>;>;>>;>;>;;;>>;>;>;>;>;>;>;>;;>;>>;>>;;>>;>;>;>;>;>;>>;>;;;>;>;>>;>;>>;>>;>;>>;>>;>;>>;>>>;>>;>>>;>>;>;>>>>>;>>>>>>;>>;>>;>>;>>>>>>>>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>,>>>>>>,>>,>>,>>>>>,>,>>>>>,>,>>>,>>,>>,>,>>>>>,>>,,>>,>>,>,>,>,>>>>>,>,>,>,,>,>,>,>,>,>,>,>,>,>,>,,>,>>>,>,>,>,,,>,>,,>,,,,,>,>,>,>,>,,,,,>,,,>,,,,,,,,,,,,,,>,,,,,>,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,,,,,,,,,',,,',,,,,,,,,',,,',',,',,,',',,,','',',,',,,',',',',',',',','',',',',',',',,',',',',','',','',','','',',','',''','','',',',',',',','", +";>;>;>;>;>;>;>;>;;>;>;>;>;>;>;>;>>;>;;>;>;>;>;>>;>;>;>;>;>>>>;;>;>;>;>;>;>;>>;>>>;;>;>;>;>;>;>>;>;>>;>;>;;>>;>;>>;>;>;>;>;>>;>>>;>;>;>;>>;>;>>;>>;>>;>;>>;>>;>;>>;>>;>>>;>>>>;>;>>>>;>;>>>;>>>>>>>>>;>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>,>>>>>>>>>>>>>>>>>>>>,>>>>>>,>,>>>>>,>>>,>>,>>>>,>,>>,>,>>,>>,>,>>>,>,,>,,>,>,>>,>>,>,>,>,>,>,>,,>,,>,>,>,>,,,,,>,>,,>>,,,>,,>,>,>,,,>,,>,,,,>,>,,,>,,,>,,>,,>,>,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,',,,,,,,',,',',,',,,,',,,',',',',,,',,',,',,',',,',',,,,,',',,'',,,',',,,',',',',,',',',',',','',','',','',,','',''',,'',''''',''',''',''''''''''''''''''", +">;>>;>>;>;>;>;>;>>;>>>;>;>;>;>;>;;>>>;>>;>;>;>;;>;>;>>>;>;;;;>>;>;>;>;>;>;>;;>;>;>>;>;>;>;>;>;>;>;>;>;>;>>;;>;>;>>;>;>;>>;;>;>;;>;>;>;>;;>;>;>;>;>;>;>>;>;>>;>>;>>>;>>;>>>>;>>>>;>;>>>>;>>>>>>;>>;>>>>>>;>>>>>>>>;>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>,>>,>,>>>>>,>,>>>>,>,>>>>,>>,>>>,>,>>>,>>,>>>,>,>>>,,>>,>>,>>,>>,>,>,,>,>,>,>,>,>,>,>,>,>,>,,>,>>,>,,,>,,,>,>,>,,,>,,,>,,>,,,,>,,,,,>,,,>,,,,,,,,,,>,,>,,,,,,,,,>,,,>,,>,,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,',,,,,,,,,,',,,,,',,,',,,,',,,,'',',,,',,,',',',',',,',,','',',',',',',',,',','',',''',','',,''','',,','',','','',',',',',',',',','", +">;>;>;>;>;>>>;>;>;>;;>;>;>;>;>;>>;>;>;;>>;>>;>>;>;>;>;>;>>>>;>;>;>;>>;>;>;>>;>;>;>;>>;>>;>>;>;>;>;>;>;>;>;>>;>;>;>;>;>>;;>;>;>>;>;>;>>;>>;>>;>>;>>;>>;>;>>;>>;>>;;>>;>;>;>>>;>>>>>>;>>>>>;>>;>>>>>>;>>;>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>,>>>>>>>,>>>>>,>,>>,>>,>,>>>,>>,>>,>,>>>,>,>>>,>,>,>,>,>,>,>>,>,>,>,>,>,>,,>,>,>,,,>,>,>,,,>,>,>,>,,>,,,>,,,>,>,,,>,>,,,>,>,,,>,,,>,>,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',,,,,,',,',',,,,,,,,,',',',',,,',',,,',,,',',,',',,,','',,'',,',,',','',',',,,',',',',',','',',',,',',,','',''',',',',''','','','','''''''''''''''''''", +";>;>;>;>;>;;>>;>;>;>>;>;>>;>>;>;>;>;>>;>;>;;>>;>;>;>;>;>;;>;>;>;>>;;>>;>>;>;>;>;>;>;;>;>>;;>;>>;>>;>;>>;>;>;>;>;>;>>;>;>>;>>;>;>>;>>;;>;>;>;>;>;>;>;>>;>;>>;>>;>>>>;>>>>>>;>>;>;>;>>;>>;>>;>>;>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>,>>,>>>>,>,>,>>>,>,>>>>,>>,>>>,>,>>,>>,>>,>,>,>>>,>,>,>,>,>>,>>,>,>,>,>,>,>,>,>>,>,,>,>,>,>,,>,>,,>,>,>,>,,>>,,>,>,,,>>,,,,>,,,,,>,,,>,,,,,,,,>,,>,,>,>,,,>,,,,>,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,',,',,,,,,',,,,,,,,,,',',,',,,,,,,,,',,,,,',,',',,,',,',',',,,,',,,',,',',',,,',',''',',',',',',','',''','','','',',,'','',''','','','',''',',',',',',',',','", +";>;>;>>>;>>;;>;>;>;;>;>;>;>;>;>;>;>;;>;>;>>;;>;>;>>;>;>>>;>;>;>>;;>>;>;>;>;>>;>;>;>>>;>;;>>>;;>;>;>>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;;>>;>;>;>>>;>>>;>;>;>>;>>>;>>;>;>>;>;>;>>;>>>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>,>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>,>>>>,>>,>>>>,>>,>,>,>>>,>,>,>,>,>>>,>>,>,>,>>,>,>,>,>,>,>,,>,,>,>,>,>,>,>,,>,>,,,,>,,>,,,>,,,,>,,,,>,>,,>,>,,,>,,,>,,>,,,,,,,,>,,,,,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,',,,,,',,,',,,,,,,,',',',',,',',',',,',,',,',,,,',,'',,',',,',',,','',',,',,',',',',',',',,',','',',',',''''','','',,'',''''','','','''''''''''''''''", +">;>;>;>;>;;>>;>;>;>>;>;>;>;>;>;>;>;>>;>;>>;>>;>;>;;>;>;;;>;>;>;;>>;;>;>;>>;>;>;>;>;;;>;>>;>;>>;>;>;;>;>;;>;>;>;>;>;>;>;>>;>;>;>;>>;>;>;>;>;;>>;;>>>;>>;>>;;>>>;>>>;>;>>>>;>>>>;>>>>;>;>>>;>>>;>;>>>>>;>>>>;>>>>;>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>,>>,>>,>,>>,>>,>>>>,>,>,>>,>,>>>,>,>>,>>,>,>>,>>>,>>,,>>,>,>>>,>,>,>,,>,>,>,,>,>,>,>,>,>,>>,>,>,,>,>,>,,>,>,,,>>,>,,>,,>,,>,>,,>,>,,>,,,,,,,>,,>,>,,,,,>,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,',,,',,,',,',',,,,,,,',,,,',,,,,',,',,',,',',,',,',',,',',,',',',,,',',,',',',',',',','',',','',',',',',',','','''','',','','','''',',',',',','','", +">;>>;;>;>>;>;>>;>;>;>>;>;>;>;>;>;>>;>;>;;>;>;>>;>>;>;>>>;>;>;>>;>;>>;>;>;>;>;>;>>;>>;>;>;;>;>;>;>>>;>;>>;>;>;>;>;>;>;>;;>;>>;>;>;>;>;>;>;>>>;>>;>;>>;>;>>>>;;>>;>>;>>;>>>>;>;>>;>;>>>>;>>>>;>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>,>>>,>>>,>>>,,>>,>>>,>>>,>,>,>,>,>>>,>>,>>,>,>,>,>,>,>,,>,>,,>,>,,,>,>,,>,>,,,>,>,,>,,>,,,>,,,,>,,,,>,>,>,,,,,,,,>,>,,,,,>,>,,>,,>,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,',,,,,,,,,,,',',',,,,',,,,',',,',,',,',,',',',,,',',,,'',',',,'',',',',',',',',',',',','',',',''',',',''',,'',,''',','','','',',''''''''''''''''", +";>;;>>;>;>;>;>;>>;>;>;>;>;>;>>>;>;;>;>;>>;>;>;>;>;>;>;>;>;>>;>;>;>;;>;>;;>;>>;>;;>>;>;>;>>;>;>;>;;;>>;>;>;>>;>>;>;>;>;>>;>;;>;>;>;>;>>>;>>;;>>;>;>;;>>>;>;>>>;>>;>>>>>;>;>>>>>;>>>>;>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>,>>>>>,>,>,>,>,>>,>,>>>,>>,>>,>,>>>,>>,,>>,,>>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>>,>,>,>,>,>,>,,>>,,,>,>,,>,,>,,>,>,,>,>,,,,,,,,>,>,>,,,,,,>,,,,,,,,,,,,,,,,,>,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,',,,,,,,,',,,,,,,,,,,,,',,',,',,,,,,,,,,',,,',',,,',,',,',,',,',,,'',,','',,,',,',',,',,',',',',',',',','',',,',',',,'',''',,''',''',,'''','','',''''',',',',',','','", +";>>;>;>;>;>>;>;;>;>;>;>>;>>;;;>;>>;>>>;;>;>;>;>;>;>;>;>;>>;>;>;>;>>;>;>>;>;>;>;>>;>;>;>;>;>;>>;>>>;;>;>;>;>;>;>;>>;>>;>;>;>>;>>;>;>;;;>;>;>>;>;>>>>>;;>>>;>;>>;>>;>;;>>>>;>;>>>;>;>>>;>;>>>>;>;>>>>;>>>>;>>;>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>,>>,>>,>>>>>>,>>>>>,>>>>>>>>>>>>>>>>>,>,>,>>,>>>,>,>>,>>>,>>>,>>,,>,>>>,>,>,>>,>,>,>,>,>,>,>>>,>,,>,,>,>,,>,,,>,,,,>>,,,>,,,>,>,,,>,>,,,>,>,>,>,,,,,,,,,>,,,,,>,,,>,,,>,,>,,,,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,',',,,,,,,,,,,',',',',,,',,,,,',,',,,',,',,',,'',,,',,,,,'',',',',',',',',',',',',',',',','',','','','',,''',',','''',',''''','',','''''''''''''''''", +";>;>;>;>;>;;>;>>;>;>;>;>;>;>>>>;>;>;>;>>;>;>;>;>;>;>;>;>;;>;>;>>;>;>>;>;>;>;>>;>;;>>;>;>;>;>;;>;>;>>;>;>;>;>;>>;>;>;;>;>;>;>;;>>;>;>>>;>>>;>;>>;;;>;>>;;>>;>>;>>;>>>>>;>>>;>>;>>>>>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>>>>,>>>,>,>,>,>,>,>,>,>,>>>>>,>>>,>>>>,>>,>,>>,>,>,>>,>,,,>,>>,>,>,>,>,>,>,>,>,,,>,>,>,>,>,>,>,>,>,>>,,,>>,>,>,,>,,>,,,,,>,,,,,,,,>,>,>,>,,,,,>,,,>,,,>,,,,,,>,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,',',,',,,,,,,,,',,,',',,',,,',,',,,,,',,',',,'',',,,',',,',,',',',',',',',',',',',','',',',',','''',,''',',','','',','','''',',',',',',','','", +">;>;>>;>;>>;>;>;>>;>;>;>;>;>;;>;>;>;>;;>;>;>;>>;>>;>;>;>>;>;>;;>;>;>;>;>>;>;;>;>>>;>;>;>;>;>>;>;>;>;>>;>;>;>;;>;>;>>;>;>;>;>>;>;>>;>;>;;;>>;>;>>>>;>;>>>;>>;>>;>>;;>;>>;>>>;>>>;>;>>;>>;>>>>;>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>>,>>>,>>,>>>>>>>>>>>>>>>>>>>>>>,>,>>,>,>>,>,>,>,>>,>,>>>,>,>>>>>,>>,>,>,>,>,>,>,>,>,>>,,>,>,,>,,>,>,,>,,>,,,>>,,,,,,>,,,>,>,>,>,,>,>,>,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,,',,,,,,,,',',',',,,',,,,',,',',,,,','',,',,,',',,','',',,',',',,',',',',',',',',''','',',','','',',,''',,''','','',','','',''''''''''''''''''''", +">;>;>;>>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>>>;>>>;>;>;>;>;>>;>;>;>;>>;>;>;>;>;;>;>>;>;;>;>>;>;>>;>;>;>;>;>;;>>>;>;>>;>;>;>>;>;>>;>;>;>;>;>;>>>>;>>;>>;;>>;>>;>>;>>;>>;>>>>>>>>>;>>>;>>>>;>>>>>>;>>>;>>>>;>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>,>>>>>,>>,>>>,>>>>>>>,>>>,>,>,>,>,>,>,>,>,>>>,>>,>>,>>>,>>>,>>,>,,>>,>,,,,>,>,>,>,>,>,>,>,>,>,>,,>,,>,>,,>>,,>,>,,>,,>,,,,>,>>,,,>,,,,>,,,>,,,,,,,>,>,>,>,,,,,,,>,,>,>,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,',,,,,,,,',,,,',,',,,,,,',',,,,,,,,,,',,',',,',,,,'',',,,,',,',',,,',,',,,,'',',',',,',',',',',',',',',','','',',',',''',,''',,'','','''','','',',',',',',','','','", +">;>;>;;>;>;;>;>;>;>;>;>;>;>;>;>>;>;>;;>;;;>;>;>;>;>;>;>;>>;>;>;>>;>;>;>>;>;>;>;>;>;;>;>>;>;>;>;>;>;>>;>;>;>;>;>>;>;;>;>>;>;>;>;>;>;>;;>;>;>>;>;>>;>;>>>;>>;>>;>>;>;>;>;>>>;>>;>;>>>>>;>>>>>;>>>>>>>>;>>>>>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>,>,>>>>>,>>>>>>>>>>>>>>>>>>,>>>,>>,>>,,>>,,>,>,>>>>,>,>>>>>>,>,>>>,>,>,>,>,>,>,>>,>>,>,>>,,>,>,,>,>,>,>,>>,>,,,>,,>,>,,,>,,,>,>,>,,>,,,,,,,>,,>,,,,,,,,,>,,,,>,,>,,,,,,,,,>,,,,>,,,>,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,',,,,,',',',',,,,,,,,',,',',,,,,',',,',',',',',,,''',,',,,','',',',',',',',',',',',,',','',''',',''',','',''','',''','''''''''''''''''''','''", +">>;>;>>;>;>>;>;>;>>>;>>;>>;>;>;;>;>;>>;>>>;>;>;>;>;>;>;>;>>;>;>;;>;>>;>;>>;>;>>;>;>>;>;;>;>;>;>;>>;>;>;;>>;>;>;;>;>>;>;;>;>;>;>;>;>;>>;>>;>;>;>>;>>>;;>>>;>>;>>;>>>>>>>;>>>;>>>>>;>;>>;>;>>>>>;>>>>>>>;>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>,>>>>>>>,>>>>>,>,>,>,>,>,>,>,>,>,>>>>>,>>>,>>>>>,>>,,>>,>,>,,>,>,>,,>>,>,>,>,>,>,>,,>,,>,,,,>,>,>,>,,,>,,>,,,,>,>,,>,,>,,>,>,>,,,,,,>,,,>,>,>,,,,,,,,>,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,',,,,,,,,',,,,,,,,,',',',',,,',,,',',',,,',,',,',,',',',,',',',',,,,',',',',',',',',',','','',',',,'','',',''','',''','',''',',',',',',',',','''','", +";>;>;>;>>;>;>>;>;>;>;>;>;>;>;>>;>;>;;>;>;>;>;>>;>>;>;>;>;;>;>;>>;>;>;>;>;>;>;>;>>;>;>>>;>;>;>;>>;;>>;>>;;>;>;>>;>;>>;>>;>;>;>;>;>;>;>;>;>;>>>;>;>;;>>>;>;>>;>;>>;>;>;>>>;>>>;>;>>>>>>>>>>;>>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>,>>,>>,>>>,>>>,>>>,>>>>>>>>>>>>>>>>,>>>>,>,,>>>,>>,>,,,>>,>>>,>>>,>>,>,>>>>,,>,>,>,>,>,>,>,>,>,>,>>,>,>,,>,>,>,>,,>>,,,,>,,>,,,>,,,,,,>,>,,,,,>,,,,,,,,>,,>,,,,,,,>,,>,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,',,',,,,',',,,,,,',',',,,,,,,,,,',,,',,,,',,'',',,',,',,',,',',,',',',''',',',',',',',',''','',',,',',''','',','',,'','',','',','',''''''''''''''''''''''", +">;>;>;>;;>;>;;>;>;>;>;>;>;>>;>;>>>;>>;>;>;>;>;>;>;>;>;>;>>;>>;>;>;>;>>;>;>>;>;>;;>;>;>;>;>>;>>;;>>;>;>;>>;>>;>;>>;;>;>;>;>;>;>>>;>;>>;>>;>;>;>>;>>>;>;>>>;>>;>>;>>>;>>;>>>;>>>>>>>;>>;>>>>>;>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>>>>>>,>,>,>,>,>,>,>,>>,>,>>>>,>,>>,>,>>>>,>>,,>>,,,>,>,>>,,,>>,>,>,>,>,>,>,>,,>,>,>,>,,>,>,,>,,,>,>,,>,>>,,>,,,>,,>,>,>,,,,,>,>,,,,>,>,>,,,,,,>,,>,,,,,,,,>,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,,,,',,,,,,,,,,,',,,,,,',,',,,,,,',',',',',',',,',',,',,,',',,',,',,,',',',,',',',,,',',',',',',',',',','',''','',',','',',''',''',''','''','''',',',',',','',','','", +">;>;>;>>;>;>>;>>;>;>;>>;>;;>;>;;;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;;>;>;;>;>;>>;>;>;>;>;;>>;;>>;;>;>;>;>;;>;>;;>>;>;>;>;>;>>;;>;>;;>>;>>>;>;>>;>;>>>;>;>>;>>;>>;>>>;>>;>>>;>;>;>>>>>>>;>;>>>;>>>>>;>>>;>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>,>>>,>>>,>>,>>>>,>>,>>>>>>>>>>>>>>>>>,>>>,>,>>>>,>>,>>,>,>>,>>>,>>>>,>,>,>>>,,>,>,>,>,>,>,>,>>,,>,,>,,>,>,>,,>,>,,,>,,,>,,>,,>,,>,,,>,,>,>,>,,,,>,>,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,',,',,,,,,',',,,,,,,,,,,,,,',,,',,,,',,,,',',',',',',,,'',',,',',,',',',',',',',',',',,',',',','','',''',','','',','',','',','''''''''''''''''''''", +";>;>>;>;>>;>;>;;>;>;>;>>;>>;>;>>>;>;>>;;>>;>;>;>;>>;>>;>;>;>;>;>>>;>>;>;>>>;>;>;>;>;>;>>>;;>>;>;>>;>;>;>;>>;>;>>;;>;>;>>>;>;;>>;>>>;>;>;;>>;>;>;>>;>;>>>;>>;>>;>>>;>>>;>>;>>>>>>;>;>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>,>,>,>,>,>,>,>>>,>,>>>,>,>>,>>,>,>>,>>,>,>,,>,>,>,>,,>>>,>,>,>,>,>,>,>,,>,>,>,>,>,,>,>,>,,>>,,>>,,>,,>,,>,,,>,,>,,,,,,>,>,,,,>,,,>,>,,>,,,,,>,,>,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,',,,,,,,',,,,,',,,,,,,',,',,,,,',',',',',',',,',,',',,'',',,',,',',,,'',,,',',,','',',',',',',',','',''',','','','','',',','',',''''',''',''''',',',',',',','','','", +">>;;>;>;;>;>;>>;>;>;>;;>;>;>>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>>;;;>;>>;>>;>;>;;>;>>;>;>;;>;>;>;>>;>;>;>;>>>;>;>;>;>>;;>;;>;>>;>>;>;>>;>>;>>>>;>;>>>>;>>;>>>;>>>;>>>;>>>>>>>>>>>>;>>;>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>>>>>,>>>>>>>,>>,>>,>,>,>>>>>>>>>>>>>>>>>,>>,>>>,>>>,>>,>,>>,>>,>,>>,>>,>,>,>>,>>,,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,,>,,>,,,>,,,>,,>,,>,,>>,,>,,>,>,,,,,,>,,,,>,,,,,,,,,>,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,,',,,,',,',,,,,,',',,,,,,,,',,,',,',,',,,',,,,',',,',,,',',,''',,,'',',,',',',',',',',',',',,',',,','',',',',''','','',',,'','',','''''''''''''''''''''''", +">;>>;>;>>;>;>;>>;>;>;>>;>;>;;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;;>>>;>;>;>;>;>;>>;>;;>;>;>>;>;>;>;;>;>;>;>;>;>;>;>;>;>>;>>;>;>;>>;>>;>;>;>>;;>;>>>;>;>>;>>>;>>>;>>>;>>;>;>>;>;>>;>>>>>;>>>>>>>>;>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>,>>>>>>>,>,>,>,>,>,>,>,>>,>>>,>>,>>,>>,>>,>,>,>>>,>>,>,>>,>,>,>,>>,>,>,>,>,>,>,>,,>,>,>,,,>,>,>,,>,,>>,,>>,,>,,>,,>,,,>,,>,,,,,>,>,,,>,>,,,,>,,,>,,,,,>,,,>,,,,,,>,,,>,,,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,',,,,,',,,,,,,,,',,,,,,',',',,,,',,',,',,',',,'',,',',,',',',',,,,''',,,',',',',',',',',',',','','''',',','',''',,'',''',''''',','''',',',',',',','','','','", +";>;>;>;>;>>;>;;>;>;>;>;>;>>>;>;>;>;>;>;>;>;>>;>;>;>;>>;>>;>;>>;>;>;>;>>;;>;>;>;>;>;>;>;>>>;>;>>;>;>;>;>>;>>>;>;>;>;>;>;>;>;>;>;>;>>>;>;>;>>>;>;>>>>;>>;>>;>;>>;>>>;>>>;>>;>>>>>>>>>>;>>>;>>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>,>>>>>>,>>,>>>>>>>>>>>>>>>>,>>,>,>,>>,>>,>>,>>>,>,>,>,>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>>,>,,>,>>,>,,>,>,,>,,,>,,,>,,>,,>,,>,,,>,,>,>,,,,,>,,,,,,>,,,,>,,,>,,,,,>,,,>,,,,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,',,,,',',,',,,,',',,,,,,',',,,',,',,',,,,',,,',,,',',,',,','',',,,'',',',',',',',',',''','',',',,',''','',',''',',','',',''''',','''''''''''''''''''','''", +">;>;>>;>;>;>;>>;>;>>;>>;>;;>>;>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;;>;>>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>>;>;;>>;>;>;>>;>>;>>;>>;>>;>>>;>>>>>;>>;>>;>>>>;>>>>>>;>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>>>>>>>,>,>,>,>,>,>,>>>,>>>>>,>>,>>,>>,,>>>,>>,>>,>>,>>>,>,>,>>,>,>,>,>,>,>,>,,>,>,,>,,>,>,,>,>,,>,>,>,>,>,,,,,>,,,>,,,,,,,,>,>,,,>,>,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,,,',,',,',',,,,,,',,,,,',,',',,'',,',',,',',,',',,',',',,',',',',',',',',',',','',','''',,'','',',',''','''','',,',''''',',',',',','',','''','", +">;>;>;>>;>;>;>;>>;;>;;>;>;>;>;>;>;>;>;>;>;>;;>;>;>;>;>;>;>;>>;>;;>;>;>;>;>>;>;>>;>>;>;>;>;>;>;;>;>;>;>;>;;>;>;>;>;>;>;>>>;>;>;>;>;>;>;>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>;>;>>>;>>>>>;>>>>>;>>>>>>;>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>,>>>>>>>,>>>>,>>>>>>,>>,>>,>>>>>>>>>>>>>>,>>>,>,>>>,>>,>>,>>>,,>>,>>,>,>,>,,>,>,>,>,>,>,>,>,>,>,>,>,>,>>,>,>,,>,>,,>,,>,>,,>,,,>,>,,,>,>,>,>,>,>,,,,>,,,,,>,,,,,>,,>,,>,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,,,',,',',',,,,,',,,,',,',,','',,,',,,,',,,',',,',,,',',',',',,',',,,',',',',',',',',',',,','',,,''',','','',',''',','',''''',',''''''''''''''''''''''''", +";>;>;>;;>;>>;>;>;>>;>>;>;>;;>>;>>;>>;>;>;>;>>;>;>>>;>;>;>;>;>>;>>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>>;>;>;>>;>>;>;>;>;>;>>;>>;>;>;>>;>;>>;;>>;>>;>>;;>>>>>;>>>;>>>>>;>>>>;>>>>>;>>>;>>>>>>>>;>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>>>>>,>,>,>,>,>,>>,>,>>,>,>>,>>,>>,,>>>,>>,>>,>,>,>>,>>>,>,>,>,>,>,>,>,>,>,>,,,,>,>,>,>,,>,>,>,,,>,,>>,,>,>,>,,,,,>,,,,,,,>,,,>,>,,,,>,,,>,,>,,,,,,>,,>,,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,,,',,,,,,,,,,,,,',,,,',,',,',,,,',',,',',,',',,',',',',,',,',,,'',',''',',',',',',',',',','',',,''',,'',','',''',',','',''',',''''',',',',',','','',','','", +">>;>;>>;>;;>;>;>;>;>;>;>;>>>;>;>;>;>;>>>;>;>;>>;;;>;>;>>>;>;;>;>;>>;>;>;>;>;>;>;>;>;>;>;;>;>;>;>>;>;>>;>;>;>>>;;>;>;>;;>;>;>;>;>;>>;>>>;>;>;>;>>;>>;>>;>>>;>;>>>;>>>;>;>>>;>>>>>;>;>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>,>>>>>,>>,>>,>,>>>>>>>>>>>>>,>>>>,>>>,>>>,>,>,>>,,>>,>,>,>>,>,>>,>,>,>>,>,>,>,>,>,>,>,,>,>>,>,,>,>,>,,,>,,>>,,>,,,>,,,,,>,>,>,,>,>,>,,,>,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,>,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,',,',,,,,,,,',,',,',,',,,,',,',,,,,,',,,,,',,,,',,',',,,',,',',',',''',,',,,,,',',',',',',',''','',',''',,''',''',',',,''','','',','',',',''''''''''''''''''''''''", +";>;>;>;>;>>;>;>;>;>;>;>;>;;;>;>;>;>;>;;;>>;>;>;>>>;>;>;>;>;>>>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;;>>;>;>;>;>;>;>>;>;>;>>;>;>>;>>;>;>>;>;>>>;>;>>>>;>>;>>;>;>>>;>>;>;>>>>;>>>;>>;>>>>>>>>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>,>>>>>>>>>>>>>,>>,>>>>>,>>>>>,>,>,>,>,>,>>>,>,>>,>>>,>>,>>>,>>,>,>>>,>,>>,>,,>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,,>,,>>,,>,,>,>,>,>,,>,>,,>,,,>,,,,,,,>,,,>,>,,,>,>,,>,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,',,,,,,,,,',,',',,',,,',',',,'',,',',',,',,,',',,',,,',',,,,',',''',',',',',',',',',',',','',,''',',',',''',''','''''',''','''''',',',',','','',','','','", +";>;>;>;>>;>;>;>;>;>>;>>;>>>;>;>;>;>;>>>;;>;>;>;>;>;>>;;>;>>;;>;>;>;>;>>;>>;>;>;>;>>>;>;>;>>;>;>>;>;>;>>;>;>;>;;>;>;>>;>;>>;>;;>;>>;>;>;>;>;>>;;>>>;>>;>>>>;>>>;>>>>;>;>>;>>>;>>>>;>;>;>>>>;>>>>;>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>,>>>>>>>>>,>>>>>,>,>>>>>>>>>>>>,>,>>>,>>,>,>>>,>,>>>,>>,>,>>,>,>,>>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,,,,>,,,>,,>,,,,>,>,,>,>,>,,,>,,,,,>,,,,,,,,,>,,,>,,>,,>,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,,,,',,,,,,',,',,,,,,,,,,',,,',,,,,',,,,',,,',,',,'',',,',,',',,','',,',,,,',',',',',',',',',',','','',,'',''',',','',',',',','',''',','''''''''''',''''''''''''''", +">;>;>;>;;>;>>>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>;>;;>>;>;;>;>>;>;>>;>;>;;>>>;>;>;>;>;>;>;;>>;>;>;>;>;;>>;>;>>>;>;>;;>;>;;>;>>>>;;>>>;>;>>>;>>>;;>>;>>>;>;>>;>>;>;>>>>;>>>>>>>;>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>>>>,>>,>,>>>>>,>>>>>,>,>,>,>,>,>>>>>,>>,>>>,>,>>,>,>,>>,>,>>,>,>,>,,>,>,>>,>,>,>,>,>,>,>,,>,>,>,,>,>,,>,>,>,,>,>>,,>>,,>,,>,>,,,,>,,,,,,,>,,,>,>,,,,,>,,>,,,,,,,,,,,,,,,>,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,',,',,,,,',',,,,,,,',,',',',,,',,,',',,',',,,',,',,',,,',',',',,,',',,',','',',',',',',',',','','',',',','','',,''','',','''',''','',',''',',',',',','''','','','',''", +">;>;>;>>;>>;;>;>;>;>;>;>;>;>;>>>;>;>;>;>;>>;>;>;>;>>;>;>>>;>;;>;>;>;>;>>;>;;>;>>;;>;>;>;>>>;>;>;>;>;>>;;>;>;;;>;>;>>;>;>>;>;;>;>>>;;>;>>;;>;>;>>>;>>;;>>;>>>>>>>>>;>>>>;>;>>>>>;>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>,>>>>>>>>>>>>>>>>>>,>,>>>,>>>>>>>>>>>>>>,>,,>>,>>,>>>>,>,>>,>>,>>>,>,>>,>>>>,>,>>,>,>,>,>,>,>,>,>>,>,>,>>,>,,>,>,,>,>,,>,,>,,,>,,>,,>,>,>,,>,>,>,,,>,,,,,,>,>,,,,,,>,>,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,',,,,,,,,,,,,,,,,,',',',,,,,,,,,,',,,',,,,',,,',',,',,',,',,',,',,',',',',',,',,',',',',',',',',',,'',',',',',',',''',,'',''',',''',''','''','''''''''''''',''''''''',''''", +";>;>>;>;>;;>>;>;>;>;>;>;>;>;>;;>>;>>;>;>;>;>;>;>>;>;>;>;;>>;>>;>;>;>;>;>>;>>;>;;>>;>>>;>;;;>;>;>;>>;>;>>;>;>>>;>>;>;>>;>;>;>>;>;>;>>>;>;>>>>;>>;>>;>>>;>>;>;>;>;>;>>;>>>>>;>;>>>>>>>;>>>>;>>>>>>>>;>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>,>>,>,>>,>>>>>>>>>,>,>,>,>,>,>>,>>>>,>>>,>>,>,>>>,>,>,>,>,>>,>,>,,,>,>>,,>,>,>,>,>,>,>,>,,,,>,,,,>,>>,>,,>,,,>,,>,,>,,>,,,>,,>,,,>,,,,>,,>,,,>,>,,,,,,>,>,,,,,>,>,>,,>,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,,,,,,,,',',',',,,',,,,',,',',,,',,,',,',',,',,,',,',,',',',',',,,',',',',',',','',','',','','',',',''',',,'','',',','',',''',',',',',',''','',',''''',''", +">>;;>;>;>>;;>>;>>;>;>;>;>>>;>>;;>;;>;>;>;>;>;>;>;>;>;>;>;;>;>;>>;>;>;>;;>;;>;>>;>;>;;>;>>>;>;>;>;;>;>;>;>>;>;>;;>;>;;>;>;>;>;>>;>;>;>>>;>;>>;>>>;>>;>>;>>;>>>>>>>>;>>;>>>>>>>>;>;>>>>>;>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>,>>,>,>>,>>,>>,>>,>,>>>>,>>>,>,>,>>>>,>,>,>>,>,>,>,>,>,>,>,>>>,,>>>,,,,>,,>,,>>,,>,,>,,>,,>,,,,,,>,,,>,,,,>,,,>,,,,>,,,,,,,,,>,,,,,,,,,,,,>,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,,,,,,,,',,,',,,,,,,,,,,',,,',,,',,,,',,',',,',',,',',',',',',',,',',,''',',',',',',',',',',',','',',','','',,',''','',''''','''',','''''''''''','''''''','''''''", +";>>>;>;>;>>;>;>;;>>>;>;>;>;>;;>>;>>;>;>;>;>;>;>;>>;>;>>;>>;>;>;;>;>;>;>>;>>>;>;>;>;>>;>;>;>;>;>;>>;>;>;>;;>;>;>>;>;>>;>;>;>;>;>>;>;>;>;>;>;>>;;>>;>>;>>;>>>;>;>;>>>;>>;>>;>>;>>>>;>;>>>;>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>>>>>>>>>>,>,>>>,>>>,>,>,>,>,>,>,>>,>>>>,>>,>>,>>>,>>>,,>,>,>,>>>,>,,,>>,>,>>,>,>,>,>,>,>,>,>,,,>>,,,>>,>,,>,>,,,>,>,>,>,,,>,,>>,>,,,>,,>,>,,,>,,,>,,,>,>,,>,,,,,>,,,,,,,,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,,,,,,,,,',,',,,',,,',,',',',',,,',,,',,',',,',,,,,',,,',,',',,,',',',',',',',,,,',',',',',',',','',',',,'','','',''''',',''',',','',',''''''',',',','''','',''''','',''", +";;;>;>;>;;>;>;>>;>;>;>>;;>;>>;>;>;>;>>>;>>;>>;>;;>;>;>;>;>;>;>>;>>>;>;;>;>;;>>;>;>;;>;>;>;>>;>>;>;>>;>;>>;>;>;>;>>;>;>>;>;>>>;;>>>;>;>;>>>;>>>>;>>;>>;>>;>>>>>>;>;>>;>>;>>>>>>>>>>>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>,>>,>>,>,>,,>>>,>>,>,>,>,>>>,,>,>>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,>,,>,>,,,>,,,>,>,,>,,,,>,>,,>,,,,>,,,>,,,>,,,,,,,,,>,,,,,>,,,,>,,,,,,,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,',,,',,,',',,,'',,',,,',',,,',,,',',,',''',',',',',',',',',','',''',,','',',',,'','','''','',''',',',','''''''','''''''','''''''''", +">>>;>>;>>>;>;>;;>;>;>;>>;>;>;>;>;>;>;;;>;>;>;>;>>;>;>;>;>;>>;>;>;;>>;>>;>;>>;;>;>;>>;>;>;>;>;>;>;>;;>>;>;>;>;>;>;;>>;;>>;>;;>>>;;>>;>>;>;>>;>;>>;>>;>>;>>;>;>;>>>>>>>>>>>;>;>;>;>>;>>>>>>>>;>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>>>>>>>,>>>,>>,>,>>,>,>,>,>,>,>,>,>>>,>>,>>>,>>>>>>,,>>,>>,>>,>>,,>>>,>,,>,>,>,>,>,>,>,>,,>,>,>,>,>>,,>,,>,>,,>>,,>,>,,,>,,,>,>,,,>,,,,>,,,>,,,>,,,,,>,,>,,,,,>,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,',',,',,,',,',',,',,,',',',',',,,',,,',,',,',',,','',,,',,'',,','',,''',,',',',,,',',',',',',',',',',',',,''',',''','','','',','','',',''''''',',',',''''','','''',',''''", +";;>;>;>;;>;>;>>>;>;>;>;>;>;>;>;>;>;>>>;>;>;>;>;>;>>;>;>;>;;>;>;>>;;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>;>>;;>;>;>;>;>;>>;;>>;;>;>>;;>>>>;>;>>;>;>>>;>;>>;>>;>>;>>>>>;>;>;>;>>;>>>>>>>>>>>>>;>>>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>>,>>>>>>>>>>>>>>,>>>,>>,>>,>,,>,>>>,>,>>,>,>,>>,>,>,>>>,>>,>,>,>,>,>,>>,>,,>,,>,,,>>,>,,,>,>,,>,>,,>,,>,>,,,,>>,,>,>,,,>,,,>,,,>,>,,,,,,>,,,,,,,,,,,,>,,,,,>,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,',,,,',,,,,',,,',,,,,,,,,',,,,,,,,',,'',',',',',',','','',','','',,''',','','',','','','','''',',',''''''''',',''''''','''''',''", +">>;>;>;>;>>;>;;;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>;>;>>;>;>;>>;>;>>;>;;>;>;>;;>;>;>;>;>;>;>>;>;>>;>;>>;>>;>;>>;>;>>;>>;>>;;;>>;>;>>>;>;>>>>;>>;>>;>>>>;>>>>>>>;>>>>>>>>;>>;>>;>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>,>>>,>>,>>,>>>>,>,>,>,>,>,>,>>,>>,>>,>>>>,>>,>,>>>,>>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,>>>,,>,>,>,,,>,,>,>,,>,,,,>,>,,,>,,,,,>,,,>,,,>,,,,,>,,>,,,,>,>,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,',,,,,,,,,,,,,',,',,,,,,,,,>,,,,,,',',,,,,,,,',,,,,,',,,,,,,,,,,',,,',,',',',',',',',',','',',',','',,'',','',,''','',''','',','''''',',',','''''',','''','''''''", +";>;>;>>;>;>;>>>;>;>;>;>;>;>>>;>;>;>;>;>;>;>;>;>>;>;>>;>>;>;>>;>;;>;>;;>;>>;>;>>;>>>;>;>;>;>;>;;>;>;>;>>;;>>;>;>;;>;>;>;>;>;>>>>>;>;>;>;>>>;>;;>>;>>;>>;>;>>;>;>;>>>>;>;>;>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>>,>,>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>,>>,>>,>>,>,>>,>>,>,,>,>,>,>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,,>>,,,,>,,,>,>,>,,>,,,>,,>,>>,,,>,,,,>,>,,,>,,,>,,,,>,,,,,,,,>,,,,,,>,,,,,,,>,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,',,',,,,,,,',,,,,,,,,,,,,,,,,,,,,,>,,>,,,,,,,',',',',,,,,,,,,,,,',,,,,,,,,,',,',',',',',',',',',',,',',',','''',','',''',,'','',''','''',',','''''''','','''''','''','''''", +">;>;>;>>;>;>;;>>;>;>;>>;>>;;;>>;>>;>;>>;>>;>;>;;>;>;>;>;>;>;;>;>>>;>>;>;>;>>;>;>;;;>>;>>;>>>;>>;>;>;>;;>>;;>;>;>>;>;>;>;>;>;;>;;>>>;>;>;>;>>>>;>>;>>;>>>>;>>>>>>;>;>>>>>>>>;>>>>>>;>>>>>>;>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>,>>,>>,>>>>>,>,>,>,>,>,>>>>>,>>,>>,>>>,>,>>,>>>>,>>>,>,>>>,>,,>,>,>,>,>,>,>,>,>,>,,>,>>,,>,>>,>,>,,,>,>,,>>,,>,,,,,,>,,>,>,,,,,>,,,>,,,>,,,,,>,,>,,,,>,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,',,,,,,,,>,,>,,,,,,,',,,,,,',,',,,,,,,,',,,,,,,,,,',,,',',',',',',','','''',''',',,',''',',','''',''',','',','''''''',',',''''','','''',''''',''", +">;>;>;;>;>;>>;;>;>;>;>;>;>>>;>;>;>;>;;>>;>;>;>>;>;>;>;>;>;>>;>;>;;>;>;>;>;;>;>;>>>;>;>;>;;;>;>;>>;>;>>;>;>>;>>;>;>>;>;>;>>>>;>>>;;>>>;>>>;>;>>;>>;>>;>;>>>;>;>>>>>;>>;>>;>>>;>;>>>>>;>>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>,>>>,>,>>>>>>>>>>>>,>,>>,>>>,>>,>,>>,>,>,>,>>,,>,>>,,>,>>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,>,,,>,,>,>,,>,>,,>,,>,>,>,,>,,,>,>,>,,,>,,,>,,>,,>,,,,,>,,,,,,,,,>,,,,,,,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,',,,,,,,,,,,,,,,,',,,,,,,,>,,>>,>,,,,',,,',',,,,,,,,',,,,,,,,,,,,,,',,,',',',',',',',',',',',,',',',''',',,',''',,','','''','','',',',','''''',''''''''','''''',''''", +";>;>;>>;>>;>;>>>;>>;>;>;>;>;>;>;>;>>>;;>;>;>;>;>;>;>;>;>;>>;>;>;>>;>;>;>;>>;>;>;>;>;>;>;>>>;>;>;;>>;>;>;>;>;>;>;>;;>;>;>;;;>>;;>>>;;>>;>;>>>;>>;>>;>>>>;>;>>>;>;>>>>>>>>>;>>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>,>>>>>>>>>>,>>,>,>,>>>>>,>>>>,>,>,>,>,>,>>,>,>>>,>>>,>>>>,>>>>,>>,>>>,>,,>>>>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>>,,>>,,,>,>,,,>,,>,,,>,,>,,>,,,,,,,>,,,>,,,,,,,,,,>,,,>,,>,>,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,',,,,,,,,,,,,,,,,,,,,,,,,,,,>,>,,,,',,,',,',',',,,,,,,,,,,,,,,,,,,',,,,',',',',',',',',','',',',',','''','','','','',','','',''''''''',',''','','','''''','''''''", +">>;>;>;>;>;>;>;;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>>;;>>;>;>;>>;>;>;>>;>;>;>;>;>;>>;;>;>;>>;;>;>;>;>;>;>;>;>>;>>>;>>>>;>>;>;>>;>>;>>;>>;>>;>>;>;>>>>>;>>>>>;>;>;>>>>>>;>>>>>;>>>;>>;>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>,>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>>>>>>,>>>>,>,>,>>,>,,>,>,,>>,>,>,>>>>,>,,>,>>,>,>,>,>,>,>,>,>,>,,>,>,,>,,>,>,,,,>>,,,,>>,,>,,>,,,>,,>,,>,>,>,,,>,,,>,>,,>,,>,,,,,,,,,,,,>,,,>,,>,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,',,,,,,,,,,,,,,,,,,>,>,>>,>,>,,,,,',,,',,,,,,,,,,,,,,,,,,,,,,,,,,,'',',',',',',',''',',','','','',','',',','','','',','','',',',',''''','''''',''','','''''',''", +";>>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;;>;>;>>;>>;>;>>;>>;>;;>>;;>;>;>;>>;>;>;;>;>;>;>;>;>;;>>;>>;>;>>;>;>;>;>;>;>>;>;>;;;>;>;;>>;>;>>;>;>>>;>;>>;>>;>>>>>;>;>>>;>;>>>>>>;>>;>>>>>;>>>;>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>>>,>>,>>,>>>>>,>>>,>,>,>,>,>>,>>>,>,>>>>>,>>>>>>,>>,>,>>>,>,,>,>,>>,>,,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>>,,>,>>,,,>,,>,>,>,,>,,>,,,,,,>,,,>,,,,>,,,,,,,>,,>,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,',',,,,,,,',,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,>,>,,,,,',,',,,',,,,,,,,,,,,,,>,,,,,,,,,,,,,,',',',',',',','',',',','','',','',''',''''','''','','''''''',',''',',''''''''''',''''''''", +";;>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>>>;>;>;>;;>;>;>;>;>;>>;>;>>>;>;>;;>;>;>>;>;>;>>;>>;>>;>;>;>;>;>;>>;>;>;>;>;;>;>;>>>;>>;>>;>;>>;>;>>;;>>>;>>;>>>;;>;>>>>;>>;>>;>>;>>>>>>;>>;>>>>>>>>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>,>>>>>>>>>>>>>>,>>,>>,>>,>,,>>,>,,>,>>>,>>,,>>>>,>,>,>,>>>,,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,,,>,,,>,,>>,,>,,,,,>,,,>,,>,>,,,,>,,,>,,,,,>,,>,,,,,,,,,>,,,,,>,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,',',,,,,,>,>,,,,,,,,,>,>,>>,>>,,,,,,,,,,,',,,,,,,,,,,,,,>,,,,,,,,,,',',',',',',',',',',','',',',,',','','',',',',,'',','''''',',','''''','''''','',',','''','''','", +">>;>;>>;>>;>;>;>;>>;>>;>>;>;>>>;>;;;>>;>;>>;>>;>;>;>;>;;>;>;>;>;>;>>;>>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>>;>;>>>;>>;>;>;;>;>;>>;>;>>;>;>;>>>>;>>;>>;;>>>>>>;>>>;>>>;>>>>>>;>>>>;>>>>>>>;>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>,>>,>>>>>>,>,>,>,>,>,>>>,>>,>>>,>>>>>,>>>>>>,,>>,>>>,>,,>>>,>,>,,>>>,>,>,>,>,>,>,>,,,>,>,,>,>>,,>,>,,>>,,>,,,>,,,>,>,,>,>,,>,,,>,>,,,>,,,>,>,,,,,,,>,,>,,,,,,>,,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,',,,,,',,,,,,,>,>,,,,,,,,>,,>,>>,>,,,,',,',,,,,,,,,,,,>,>,,,,,>,,,,,,,,',,',,',',',',',',',','',','''','',','',','''',''''',,','''''',',',''','','''''''''''''','''''", +";>;>;;>;>;>>;>;>;;>;>;>;>;>>;;>;>>>;;>;>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;;>;>>;;>;>;>>;>>;>;>>;>;>>;>;>>>;>;>>;>>;>>>>;>;>;>>;>>>;>>>;>;>>>>;>>>>>;>;>>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>>>>>,>>>>,>>,>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>,>>,>>>,>,>>,>,,>,>>>,>,>,>,>>,,,>>,>>>,,,>,>,>,>,>,>,>,>,>,>,>>,>,,,>,>,>,,,,>,>,>,,>>,,,>,,,,,>,,,>,,,,>,,,>,,,,,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,',,,,,,,,,,,',,,,,,,,,,,,,>,>,,,>,,>,>>>,>,>,,,,,,,,,,,,,,,,>,>,,,,>,,>,,,,,,,,,,,',,',',',',',''',',',,''',',',',''','','',','',',,'''',','','''''',''''''',',''',''''''''''''", +">;>;>>;>;>;;>;>;>>;>;>;>;>;;>>;>;>;>>;>;>;>;>;>;>;>>;>;>>;>;>>;>;>;>;>;>;>;>;>;>;;>>;>;>>;>;>;>;>;>>;>;;>>;>;>;;>;;>>;>;>>;>;>;>;>;>;>;>>;>>;>;>>;>>>>;>>;>>>;>>>>;>>>>;>;>>>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>>,>>>,>,>>>,>,>>,>,>,>,>,>>>,>>,>>,>,>>>,>>>>>,>,>,>>,>>,>,>>>,>,>,,>>>,>,>,>,>,>,>,>,>,>,,>,,>,>>,>,,,,>>,>,,,>,>,,,,>,,>>,>,,,>,,,,>,,,>,,,>,>,,,>,,,,,,>,,,,>,,,>,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,',,',,,',,,,,,',,,,,>,>,>,,,>,,,>,>,,>>,>,>,,,,,,,,',,,,>,,,,>>,,>,,,,>,,,,',,',,'',',',',',',,,''','',',',''',',',',''','''','''',','''','''',',''','',''''','''','''''','''", +">;>>;>;>;>>;>;>;;>;>;>;>;>>;;>;>;>;;>;>;>;>;>>;>>;;>;>;;>;>;;>;>;>;>;>;>>>;>;>;>>;;>;>>;>;>;>;>;>;>>;>>;;>;>;>>;>>>;>;>;>>;>>>;>;>>>>>;>>;>>;>>;>>>;>>>;>>>;>>>;>>>;>>>>>>>;>>>;>>>>>;>>>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>>>>>,>>,>>,>>>,>,>>,>,,>>>,>,>>,>>,>>,,>>,>>>,,>>,>,>,>,>,>,>,>,>,>,>,>,,,,>,>,>>,,,>,>>,,,>,>,>,,,,,,>,>,,>,>,,,>,,>,,,,,,,,,,>,,>,,,,,,,,,,,,>,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,,,,,,',,',,,,,,,,,>,>,>,,,>,>,>>>,>>>,,>,>,,,,,,,,,,,,>,>,,>,,>,,,,,,,,,,,,,',,',',',',''''',,',',',',','',',''',','',','',''','','''',','''',''',''',''''','''','',''','", +";>;;>;>;>;>;>>;>>;>;>;>>;>;>>;>>;>>;>>;>;>;>;;>;>>;>>;>>;>;>>;>>;>>;>;>;>;>;>;>;;>>;>;>;>>;>>;>>;>;>;>;>>;>>;>;>;;>;>>;>;>>;>;>>>;;>;>>;>>;>>;>>>;>>>;>>>;>>>;>>>>>>>;>>;>>>>>>>>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>,>>,>>>,>>>>>>,>>,>>,>>>>,>,>,>,>>>>>>,>>,>>>>>,>>>>,>,>>>,>>,>,>,>>,,>,,>>,>,>,>,>,>,>,>,>,>,,>,,>,>>>>,,>,,,>,>,,,,>>,,>,,,,>,>,>,,,>,,,,,>,,,,,>,>,>,,>,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,,,,',,,',,,,,,,,,,,,>,>,>,>,,>,,>,>,,>>,,>>>,>,>,>,,,,,,,,>,,,,,,>,,,,,,,,,,',',,,',',',',',,',,''',',',','',',''',,'',','',''',','','',',''''',''','''''''',''''','''''''''''", +";>>;>;>;>;>>;>;>;>>;>;>;>;>;>;;>;>;>;>;>>>;>>>;>;>;;>;>;>>;>;>;>;>;>>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;;>>;>>;>;>;>>;;>;>>;;>>>>;>>;>>;>>>;>>;>;>>>;>>;>>>>;>;>>>>;>>>;>>;>>;>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>>,>>>,>>,>>>>>>>>,>>>>>>>>>>>,>,>,>>,>,>,>,>>,,>,>>,,>,>,>>,>,>,>>>>,>,>,>,>,>,>,>,>,>,,>>,,>,>,,,,,>,>,>,,>,>,>,,,>,,>,>,>,,,,>,,,>,>,,,>,>,,,,,,,,,,>,,>,,>,,,,,,,>,,,,>,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,',,',,,,,,>,>,>,,>>,>,>,,,>>>,,>>>,>,>,>,,,,,,,>,>>,>,>,>,,,,,,,,,,',',',',',','',',,,',',''',','',',''',','','',',''','','''',',''',''','','''''','''''''''''''''", +";>;>>;>>;>;;>;>>;>;>;>;>;>;>;>>;>;>;>;>;>;>;;>;>;>>;>;>;>;>;>;>;>;>;>;>;>>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;;>;;>;>>>;>>>;>;>>>;>;>>;>>;>>;;>;>>>>>>;>>;>>>;>>>>>;>>>>>;>>>>>>>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>,>,>,>,>,>>,>>>,>>>>,>>>>,>>>>,>>>,>>>,>>,>>,>,,>,>>,>,>,>,>,>,>,>,>>,,>>,>,>,>>,>,,>,>,,>,>,,>,,>,>,,,,,>,>,,>,,,,,>,,,,>,>,>,,>,,,,,,,,,,>,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,,,,>,>>>,>>,>>>,>,>,,,>>>>,>>,>>,>,>>,>,>,,,>,,>,,,,,,,',',',,',',',',',','',''''',',',''',','',',''',''','''','','''',''''',''','''''','','''','','','','''", +">;>;>;;>;>>;>;;>;>;>;>;>;>;>;>;>>;>;>;>;>;>>;>;>;>;>;>>;>;>;>;>;>;>;>;>;;>;;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>>>;>>;;>;>;>;>;>;>>>;>>;>>;>>>>>>;>;>;>>>>>;>>;>>;>>>;>>>>>>;>>>>>;>>>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>>>,>,>>,>>>>>>,>,>>>>>>>>>>>>>>,>>>,>,>>,>,>,>,,>>,>>,>,>>,>,,>,>>,>,>,>>,>,>,>,>,>,>,,>,>,,,>,>,,>,>,,>,,>,,,>,>,>,,,,>,>>,,,,>,,>,>,,,>,,,,,,,,,,,,>,>,,>,,,,,>,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,,,,,,,,',',',,,,,,,,>>,>>>,>>>>>>>,>,>,,,>,>>>>,>,>,,>,>,,>>,,>,,>,>,,,,,,,,',',,',',',',',',',',,',',',','''',',',','','',',','''',',''',',''',''',',''''''',''''''''''''','", +">;>;>>>;>;;>;>>;>;>;>;>>>;>;>>;;>>;>;>;>;>;;>;>;>;>;>;;>;>;>;>;>;>>;>;>>;>>;>>;>;>;>;>;>;>;>;>;>;>;>>>;>;>;>;;>;>;;>>>;>>;>>>;>;;>>;>;>>;>;>;>;>>>>>>;>;>>;>>>>>>>>>;>>;>>>>>;>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>>>>>>>>>>,>>>>>,>,>,>,>,>,>,>>,>,>>>>,>>>,>>>,>,>,>>,>,>,>>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,,>,,>>,,,,>,,>,>,,,,>,>,,>,,,,>,,,>,>,>,,>,>,,,,,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,>>,>>>>>>>;>>>,>,,>,>>,,>,>>>,>>,>,>>,,>,,>,,>,,,,,,',',,,'',',',','','',',','',',',',,,'',''','',','','''',','''',''''','','''''','',''''',''''',''''''", +">;>;;;>;>>;>;>;>>;>;>>;;>;>>;;>>;>;>;>;>;>>;>;>;>;>;>>;>;>>>;>;>;;>;>;>;>;>;>;>>;>;>>;>>;>>;>>;>;>>;;>;>;>;>>;>;>>;>;>;>>;>;>;>>>;>>>>;>>>;>>>>;>;>;>>>>;>>>;>;>>;>>>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>>>,>>,>>,>>,>>,>>>,>>>>>>>>>>>>>>>>,>>>,>,>>,>,>>,>>,>>>,>,>>,>,>,,>,>,>>>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,,>,>,>,,,>>,>,>,,,,>,>,,,>,,,>,,,,>,,,,,,,>,,,,,>,,>,,,,,>,,,>,,>,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,',,,,,',,',,,',,,',,,,',,,>,>>>>>>;;;;;;;>>>,>,>,>>>>>,,>>,>,>,,>,,>,,>,,>,>,,,,,,,'',,',',',',,',','','',',''','''','',',','''''',',',''',',''',','''''',''''',''',''''',''''',''''", +";>;>>>>;>;>;>>;;>>;>;;>>;>;>>;>;;>>;>;>>;>;>>;>>;>>;>;>;>;;;>>>;>>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;;>>;>;>;>;;>;>;>>;>>;>;>;>>>;>;>>;>;>>;>>;>;>>>>>>;>;>>>;>>>>>>>>>;>>;>>>>>>;>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>,>>>>,>,>,>,>,>,>,>,>>,>>>>,>>>>>,>,>>,>,>>>,>>,>,>>>>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,,>,>>,>,,,>,>,,>,,,,,>,>,,,,>,,,>,,,>,,,>,>,>,,,,,>,,,,,,,,>,,,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,',,,,,,,,,,,',,,,',,,,,,,>>>>>;;>;;;;;;;>,>,>,>,>,,>>>,,>,>,>,>,>,>,,>,,>,,,,,',,,,'',',',','',',',',',',',,'',','',,''','',,','','''',''''','''''',',''','''''''','''''''''''''''", +";>>;;;>;>;>>;;>>;>;>>;;>;>;;>;>>;>;>>;;>;>;>;>;>;>;>;>>;>>>;>;>;>;>>;>;>;;>;>;>;>;>;>;>;>;>;>;>;>>;>;>>;>;>>;>;>;>;>;>;>>>;>;>;>>;>;>>;>;>>;>>;>;>>>>>>;>>>;>>>;>>;>>;>>>>;>>>>>>;>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>,>>,>>>>,>>>>>>>>>>>>>>>>,>>,>,,>>,>,>,>>,>,>>,>,>>,>,>,,,,>>,>,>>,>,>,>,>,>,>,>>,>,>,>,,>,>,,,,,>,>,,,>,>,>,>,>,,,>,>,,>>,,,>,,>,,,,,,,>,,,,,,>,>,,>,,,,,>,,,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,',,,,,,>;;;>;;;;---;;;>>,>,>,>>>,>>>,>,>,>,>,,,>,>,>,>,>,,,,',',,,',',',',',',',',','','',''',','','',''''',''',','',',''',',',''''',''','',''''',''','',''',''", +">;;>>>;>;>;;>>;>;>;>;>>;>;>>>;>;>;>;;>>;>;>;>;>;>;>;>;;>;>;>;;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>>;>>;>>>;;>;>>;>>;>>>;>>;>>;>>>>;>>;>;>>>;>>>>;>>;>>>>>>;>>>>>>;>>>>>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>>>>>>,>>>>>>>,>,>,>,>,>,>,>,>>,>>>>>>,>>>,>>,>>,>,>,>,>>,>>>>>>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,>,>>>>,,>,>,>,,,>,>,,>,>,>,,>,,,,>,,,,,>,>,>,,,>,,>,,,,,,,,,,>,,,>,,>,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,',,',,,,,',,,,',,,,,,,,>>>;;;;;;;----;;>>>,>,>,>,>,,>>,>>>,>,>>,,>,>,>,,,,,,',,,,',,',',',',',''','',','',',',''',',','',',''',','',''''','''''''','''',''''''',''''''''''''''''", +">>;>;>;>;>>;>;>;>;>>;;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>>;>;>;>>;>;>;>;>>;>;>;>;>>>;>;>>;>>;>;>>>;>;>;>;>;>>;;>>;;>;>>;>;>>;>>;>>;>>;>>;>>>;>>>;>>>;>>>>;>>>;>;>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>>,>>>>>,>,>>>>>>>,>,>>>>>>>>,>>>>>>>>,>>,>,>,>>,>>,>,>,>>,>>>>,>,>,,,>,>,>,>,>,>,>,>,>,>,>,>,>,,>>,>,>,,>,,,,>,,,>,>,>,,,,>,,,>,,>,,>,>,,>,>,,,,,,,>,,,,,,,>,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,',,,,,,,,,,,,,,',,,,',,,,',,',,,,>>;;----------;>>>,>>>,>,>>>,>>,>>,>,,>>,>>>>>>,,,,,,,',',',,,',',''',',',','',,''',',',''','',''',','''','',',''',',',',''''''''','',''''',''''''',''''", +";;>;>;>>;>;>;>;>;>;;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>>;>;>;>;;>>;>;;>;>>;>;>;>;>;>;>;>;;>;>;>>;>;>>;>;>>;;>;>>;>>;>>>;>>;;>>;>>>;>;>>>;>>>>>;>>;>>>>;>>;>>>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>>>,>>>>>>>,>>,>>>>>>>>,>,>>>>>,>,>,>>,>>,>>>>,>>,>>>>>,>>,,>,>>>,>>,>,>>,>>,>,>,>,>,>,>,>,>,>,>,,>,,>,>,,>,>,>,>,,,>,>,>,,,>,,,,,>,,>,,,,,,,>,>,>,,,,>,>,,,,>,,,>,,,,,,,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,',,,,',,,,,,,,,,,,,,,>>;;;;---====-;;>>>,>,>>,>,,>>,>>>>>>,>,>>>>,>,>,,,',',,,,,'',,',',',',',',',''',','','',,'','',,'''',','',''''','''''''''','',','','''','''','','''''''", +">;>;>;;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;;>>;>;>;>;>;>;;>;>;>;>>;;>;>>>;;;>;>;>;>;>;>;>;>>>>;>;;>>;>;>;>>;>>>>;>>>;>>;;>>;>>>;>>;>>>>>;>>>;>>>>>>>>;>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>,>>,>>,>,>>>>>>>,>>,>>,>,>>,>,>,,,>>,>>>,>,,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,>,>,,,>,,>,>,,>,>,>,,>,>,,,>,,,>,>,>,,,,,,>,>,,,,,>,,,,>,,,>,,>,,>,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,',,,,,,,',,,,',,',',,',,,,,>>>;----=-===--;>>>>>>,>,>>,>,>,>>>>>>>>>>>>>>,,,,,,,,'',',,,',,,',',','','',,,','','',''','',''',',''',''',',''',',',',','''''''''''','''''''''''''',''", +">>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>>;>;>;>;>>;;>;>>;>>;>;>>;>;>>;>;>>;>;;;>>>>;>;>>;>;>;>;>;;>;>;>>;>>;>>;>;>;;;>>;;>>;>>>;>>>;>>>>>>;>;>>;>>>>;>>;>>>>;>>>>>>>;>>>>>>;>>>>;>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>,>>,>,>>>,>>>>>>>>>>>>,>,>,>>,>>>,>>>,>>>,>>>,>,>>,>,>>>,>,>>,>,>,>>>,>,>,>,>,>,>,>,>,,>,>,>,,>,>,,>,>,>,,>,,>,,,,,,>,,>,>,,,>,,,,,,,,>,>,,,,,,>,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,,,,',,,,',,,,,,,,,,,,,,,,,,>>;;--=====--;;>>>>,>>,>,>,>>>>>>>>>>>>>>>,>,>,,,,',,',,,,,,'',,','',',','''','',','',,'',''','','',''',''''',''''''''''',''',''',''''''''','''','''''", +";>;>>;>;>;>>;>>;>;>;>;>;>;>;>>>;>;>>>;>;>;>;>;>;>;>;>;>;>>>;;>;>;>>;;>;>;>;>;>;>;>>>;>;;>;>;;>>;>>;>;>>;>;>;>>;;>;>>;>;>>>>;>>>;>>;>>;>;>>;>;>;>>>>;>>;>;>>>>>;>;>>;>>>>;>>>>>;>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>,>>,>>>>>>>>,>,>>,>>>>>>>>>>>,>,>,>,>,>,>>>>>>,>>,>>,>,>>,>>>,>>,>>,>,>>,,>>,>,>,>>>,,,>,>,>,>,>,>,>,>,>>,,>,,>,>,,>,,>,,,>>,,>,,>>,>>,,>,,,>,>,,>,>,>,>,,,,>,,>,,,,>,,,,>,,,>,,,,,,,,,,,,>,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,',,,,,,',,,',,,,',',,',',',,,,,,,>>>;--==**==-;;>>>>>>,>,>,>,,>>;;>;>>;>>>>>>,>,,,,',,,',,,,,,,',',','',',,,''',','',''',',','','','',','',',''',',','','''',''',''',''','''''','''''''", +">;>;;>;>;>;>;>;>;>;>;>;>;>;>;;>>;>;;>>;>;>;>;>;>>;>>;>;>;;;>>;>;>;>>;>>;>;>;>;>;>;>;>;>>;>;>>;>;>;>;>;;>;>;>;>>>;>;>>;>>;;>>;>;>>;>>;>>>;>>;>>>;>;>>;>>>>>>;>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>,>,>>>>>>>>>>>>>,>,>,>>,>>,>>>>,>>,,>>,>,>,>>>,>>,>,>,>,>,,>>>>,>,>,>,>,>,>,>,,,>,>,>,>,>,>,>,,>>,,,,>,>,,,,,,>,,,>,,,,>,,,,,,,,,,>,,,,,>,,,,,>,,,>,,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,,,,,',,,,,,>>;;--=***==--;>>>>>>,>,>,>>>>>>;;;;;>;;>>>>,,,,,,,',',,,,,,,',','',,'',''',',''','',,'',''','',''',''',''''','''''''''',''''''''''''''','''''''''''''", +">;>>;>>>;>;>;>;>>;>>;>;>;>;>>;;>;>>;;>;>;>;>;>;>;>;>;>;>>>;>>;>;>;>;>;>;>;>;>;>;>;>;>;;>;>;>;>;>;>>;>>;>;>>;>;>>;>;>>;>;>>;>>>>;>>;>>;>;>>>>;>>>>>>>>;>>;>>>>;>>>>;>>>;>>>>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>>>>>,>>,>>>,>>>>>,>,>,>,>,>>>>>>>>,>>,>>,>,>>,>>>,>>>,>>,,>>,>,>,>,>>>>,,,>,>,>,>,>,>,>,>,>>,,>,,>,>,>,>,,>,,,>>,>,,>,>,>,,,>,>,>,>,,>,>,>,>,>,,,>,,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,,,,,,,,,',,,,,',,',,,',,,,',,,>,>;--==*****--;;;>>>>>,>,>,>,>>>;;;;;;;>;>>>>>,,,,,,,,',',,,,,,,',,'',',',,','',,'',''','',''','',',',''',',''',',',',''''','','',','''''''',''''',''''", +">;>;>;>;>;>;>;>;>;>;>;>>;>>;;>>;>;;>>;>>;>>;>;>;>;>;>;>;>;>;;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;;>;>;>>;>;>>;>>;>>;;>>>;>>;>>>>;>>>;>;>;>;>>>>>>;>>>>;>>>>>>>>;>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>,>>,>>>>>>>>>>>>>,>>>>>>>>>>>,>,>,>,>>,>>>,>>>,>>,>,>,,>>,>>>,>>,>>>,>,,,>>>,>,>,>,>,>,>,>,>,,>,>,>>,>,,,>,>,,>>,,,,,>,,>,,,>,>,,,,,>,,,,,,,,,,,,,>,,,,>,,,,,>,>,,>,,,,>,,,,,,,>,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,',,,',,,,,,,,',,,,',,,,,,>>;--==**&***=--;>;>>>>>,>,>,>>>>>;;;;;;;;>>>,>,,,,,,',,,,,>,,',','',','','',',''','',,'',',',''',''','',''''','''''''''','''''''''''',''''''''','''''''", +">;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>>>;>;>;>;>;>>;>;>;>;>;>;>;>>;>;>;>;>;>>;>>;>>;>>;>;>;>;>>;>;>;>>;>;>;>>;>>;>>;>;>>>;;>>;>;>>>>;;>>;>;>;>>>;>>>>>>>>>;>;>>>>;>;>>;>>;>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>,>,>>>>>,>,>,>,>,>>>>>>>>,>>,>,>>,>>,>>,>>>>,>,>,>,>,>,,>,>>>,,>>,>,>,>,>,>,>,>,>,>,>,,,>,,>>,,,>,>,,>>,>,>,>,,>,,,,>,>,,,>,>,>,>,>,>,,,>,,,,,>,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,,,,,,,,,,',,',,,,',',,',,,,,>;-==**&*&**==--;;;>>>>>,>,>,>,>;;;-;;;;>;>>>>,>,,,,,,,',,,>,,,,',,',',',',''',','',''',',''',','',''','',',''',',',',',''',','',''''''','',''''''''''''", +";>;>;>;>;>>;>>;>;>;>>;>;>;>;>;>;;;>;>;>>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;;>;>;>;;>;>;>;>;>;>;>>;>;;>>>;>;>>;>;>>>;>>>>;>>;>>>;>;>;>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>;>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>,>>,>>>>>,>>>>>>>>>>>>>,>>>>>>>>>>>>>,>,>,>>>,>>>,>>,>>>>,>,>,>>>,>>,>>,>>>>,,>>,>,>>,>,>,>,>,>,>,>,,>,>>,>,>,,>,>,,,>,,,>,,,>,,>,,>,>,,,>,>,,,,,,,,,,,,>,,,,>,,,,>,,>,>,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,',,,,,,,',,',,,,,,,',,,,,,,,,',,>>;;==***&&&&*==--;;;;>>>,>,>,>>>>>;-;--;;>;>>>,>,,,,,,,,,>,>,>,,,,'','','',',',',','',,'','','''',''','',''''',''''''''''''''''''',',''''''''','''''','''", +";>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>>;>>;;>;>;>;>>;>>;>>>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>>;>>>;>;>>;>;>>;;>>;>>;>;>>>;>;>;>>;>>;>;>>>;;>>;>>>;>>>>;>>>>;>>>>;>;>>>;>>;>>>;>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>,>>>,>>>,>,>,>,>,>,>>>>>>,>>>,>>>,>>,>,>>>,>,>,>>,>>,>,>,,>>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,,>,>,>,,>>,,>>,,>>,,>,,>,>,,>,,>,,>,>,>,>,>,,,,>,>,,,>,,,,,,,,,>,,,,,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,',,,,',,',,,,,,,>>;-=*&&&&&***==--;;;;>>>>,,>,>>>>>;;--;;;;>>>>>,>,,,,,,,,,,>>>,,',,',,',','',''','',''','','',','',','''',',''',',',',''',','','''''''',''''''''','''''''", +";>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;;>>;>;>;>;>;>;>;>;>;>;>;>;>;;>>>;>;>;>;>;>;>>;>>;;>;;>>;>;;>>;>;>>;>;>;>>>;>;>;>;>;>>;>>>>;;>>>;>>>;>>;>;>>>>;>>;>>>>>>;>>>;>>;>>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>,>,>,>,>>,>>,>>,>,>,>>>,>,>,>,>,>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>>,>,>,>,>,>,,,>,,,>,,,>,,>,,,,>,,>,,,,,,,,,,,,>,>,,,,,,,,,,,>,,>,,,,,>,,>,,,,,,>,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',',,,,>;;==**&&&&&**=---;;;;;>>>,>,>>>>>;;;---;;;;>>>>>,,>,,,,,,>>>>>,,,',''',',','',,'','',,'',''','''',''',',''''','''''''','''''''''','','''''','''''''''''''", +">;>;>;>;>;>;>>>;>;>;>;>;>;>;>;>;>;>>;;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>;>>;>>;;>>;;>>;>;>;>>>;;>;>;>;;>;>;>;>;>;>>>;>>;>>;;>>>>;>>>;>>;>>>>>;>;>>;>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>>,>>,>>,>>>>>,>>,>>,>,>,>,>,>>>>>>,>>>,>>,>>>,>>>,>,>,>,>>,>>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,,>,,>,,>,>,,,>,>,,>>,,>>,,>,,>,>,,>,,>,>,>,>,>,,,,,,>,,>,,>,,>,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,',,,,,,,',',,',,,,,,',,,,,,,,,,,,>>;-=*&&&&&&&**=---;;;;>>>,>,>,>>>>;;----;;>>>>>,>>>,>>,>>>>>>>>,,,,,,,','',',''',',''',',',''',','','','',',''',',',''''',''',','''''''''','''',''''''''''", +";>;>>;>>;>;>;;>>;>;>;>>;>>;>;>;>>;>;>>;>;>;>;>>;>;>;>>;>;>>;>;>;>;;>>;>>;>;>;;>>;;>>;>>;>;>;>;>>;>;>;>>;>;>;>;>>;>;>;>;>;>>>;>;>>;>;>;>>>;>;>>>>;>>>;>>;>>;>;>>;>>>;>>>>>>>;>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>,>,>,>>>,>>>,>>,>>,>,>>>,>>>,>>,>,>,>,>,>,>,>,,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,,>,,,>,,,>,,,>,,>,,>,,,,,,,>,>,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,,,,,',,',,,,,,,,,,,,,,,,,,,,,,,,,,,>>;-=**&&&&&**==----;;;;>,>,>,>>>>>;;---;;;;;>>>>>,>>>>>>>>>>>>>,,,'''',',','',,'',',','','',',''','','''''''','''''',',''',''''''','''',''''''''',''',''''", +";>;>;>;>;>;>>;;>;>>>;;>>;>;>;>;>;>;>;>>;>>;>;;>;>;>;;>;>;>;>;>>;>>;;>;;>;>;>>;>;>>;>;;>;>;>;>;>;>>;>;>;>>;>>>;>;>>;>>;>>>;>>;>>;>>;>>>;>>;>>>;>>>;>>>>>>;>>>>>>>>;>>>>>;>>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>>>>>>,>>,>>>>>,>>>>>,>,>,>,>>>>>>>>,>>,>,>>,>>,>,>>,,>>,,>>,>>,>>,>,>>>,>,>>,>,>,>,>,>,>,>,,>,,>,>,>>,>,>,,,>,,>>,,>>,,>,,>,>,,>,,>,,>,>,>,,,,,,,>,>,,>,>,>,,>,,,,,>,,>,,>,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>,;;-=**&&&&&&**==--;-;;;;>>>,>,>>>>>;;----;;>;>>>>>>>>>>>>;>;>>>>,,,,,','','',''',''','','',''',','','',',',',''',','''''''''','','''',''''''','''''''''''''", +">;>;>;>;>>;>;>>;>;;>>;;>;>>;>;>;>;>;>;>;>;>;>>;>;>;>>;>;>;>;>;>;>;>>>>;>;>;>;>;>;;>;>>;>;>;>;>;>;;>;>;>;>>;;>>;>>;>;>;>;>>;>>;>>;>>;>>>;>>>;>>>;>>>>;>>>>>>;>>;>>>>>;>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>>>>>,>,>>>,>,>>>>>>>>>,>,>,>,>>,>>>>,>>,>>>>,>>>,>>>,>,>,>,>>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,,>,,,>,,>,>>,,>,,,>,,,>,,>,,,,,,,>,,>,,,,,,,>,>,>,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,>,>,,,,,,>,>;;-=*&&&%&&&*==----;-;;>>>,>,>,>>>;;----;;;;>;>;>>;>>;;;;;;;;;>>,,,',',',','',',',',','',',',''''','','''''''',''''','','','''''',''''''','''',''''''''''''", +">;>;>;>;;>;>;>;>>;>;>>;>;;>;>;>;>;>;>;>;>;>;>;>>;>;>;>>;>;>>;;>;>;;;;>;>;>;>;>;>>;>;>;>>;>;>;>;>>;>;>;>>;>>>;>>;>;>>>>>;>;>;>>;>>;>>;>>>;>>>;>>>;>>>>>;>>;>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>>>>>>>>>>>>,>>>>>>>>>>>>>>,>,>,>,>>>>>>>,>>,>,>>,>>>,>,>,>,>>,,>>,>>,>,,>>,>,>,,>,>,>,>,>,>,>,>,>,>,>>,>,>,>,>,,,,>,>,>,,>>,,>,,>,>,>,,,>,,>,>,>,,,,,,,>,,,,,,>,,>,>,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,,,,,,,,,,,,,,>,>,,,,,,,>>;-=**&&%&%&**==--;-;;;>>>>,>,>>>>>;;-=--;;;>;;>;;;;;;;;;;;;;>;>>,,,',',','',',''',''','',''',',,''','',',',',''',',''''',''','''''','''''''''''','''''','''", +";>;>;>;>>;>;>;>;>;>;>;>;>>>;>>;>>>;>;>;>;>;>;>;;>>;>;>;>;>;>>>;>;>>>>>;>>;>;>;>>;>;>;>;;>;>;>>;>;>;>>;>;>;>;>;;>>>;;;>;>>>>>;>>;>>;>>>;>>>;>>;>>>;>>;>>>>>>>>>>>;>>>>;>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>,>>,>>,>>,>>,>>>>>>>>>>,>,>>>,>>>>,>>,>,>>>,>,>,>>>,>>,>,>>,>,>,>,>>,>,>,>,>,>,>,>,>,,>,,,>,>,>,>,,>>,,>,>,>,,,,>,,>,,,>,,>,,>,,,,,,>,>,>,,,>,,>,,,,,,,,>,,>,,>,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,',,,,,',,,,,,,,,',,,>,>,>,>,>>>,,,,,,>>>;;-=*&&&%&&&&*=---;;;;;>>>,>,>,,>>>;--==--;;;>;;;;;;;;;;;;;;;;;>>,,,','',',,''',,'',',',''','''',',''','''''''','''''',''''''','','''','''',''''''',''''''''", +">;>>;>>;>;>;>;>;>;>;>;>;>;;>;>;;;>;>;>>;>>;>;>>;>;>>;>;>;>;;;>;>>;;;;>;>;>>;>;;>;>;>;>>;>;>>;;>>;>;>;>;>>;>;>>>;;>>>>>;>;>;>>;>>;>>;>>>;>>>;>>;>>>>>>>;>;>>;>>;>>>;>>>>>>;>>>>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>,>>>>>>,>>>>>>>>>>>,>>>>>,>,>,>,>,>>>>,>>,>,,>>,>>>,>,>>>,>>,>>,>>,>>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>>,>,,>,,>,>,,>,,,>,,>>,,,>,,>,>,,>,,,,>,>,,,,,,,,>,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',,,,,,,,,,,>,>>,>>>>>>,,,,,>>>;--**&%&%&&&*==-;;;;>>>>>>,>,>>>>>;;===---;;;;;;;;;---;-;;;;;;>;>>,,,',',''',,''',',''',','',',''',','',',','''',',',''','','''''''''''',''''','''''''''''''", +">;>;>;;>;>;>;>;>;>;>;>;>;>>;>;>>>;>>;>;>;;>>;>;>;>;;>;>;>;>>>;>;;>>>>;>;>;>>;>>;>>>;>;>;>>;;>>;;>>;>;>>;;>>>;;>>;>;>;>>;>>>;>>;>>;>>>;>>>;>>>>>;>;>;>>>>>>>>>>>>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>,>>,>>>>>>,>>>>>>>>>>>>>,>>>,>>>>,>>>,>>,>,>,>>,>,>,>,>,>>,>,>>>,,>>,>,>,>,>,>,>,>,>,,>,,>,>,,>,>,,>,,>>,,>,,,>>,,,>,,,>,,>,>,,,,,>,>,>,,,>,,>,,,,,,,>,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,',,,>,>>,>>,>;>>>,,,>,>>>--=*&&&%%&&&*==--;;>;>>>,>>,>,,>>;;-====--;;;;;;-;-;---;--;;;;;>>>',','',',''',',''',,',''','''','''','''''',','''''''''''''',','','''''''''''''''''''''''''", +">;>;>>;>;>;>;>;>>>;>;>;>;;>;>;>;>;;>;>;>>;>;>;>;>;>>;>>;>;>;>;>>;>;;>;>;>;;>;>;>;;>;>;>;>;>>;>>;>;>;>;>>>;;>>>;>>;>>;>>>;;>>;>>;>>>;>>;>>;>;>;>>>>>>;>>;>;>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>>>>,>>>>>,>>,>>>>,>,>,>,>,>,>>,>,>>,>>>,>,>>>,>>,>,>,>>,>>,>,,>>>,,,>>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,,>,,,>,,>>,,,>,,>,>,,>,,,>,>,>,,,,,,>,,,,,,,>,>,,,,,,,,>,,,,,>,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,,>>>>>>>;;;>>>>,>>>;;--=*&&%&%&&**=--;;;>>>>>>,>,>>>>;;--====----;--;--------;-;;;;;;>>,,',,','',,'',',,''''','',','',','',',',''''',',','','','''''''''',''''','''',''''''',''''", +">;>;>;>;>>;>>;>;>;>;>>>;>>;>>;>;>>;>;>;>;>;>;>;>;>;>>;;>;>;>;>;;>;>>;>;>;>>;>;>;>>;>;>;>;>;;>;;>;>;>;>;;>>>;>;>;>>;>>;;>>>;>>;>>>;>>;>>;>>>>>>>>;>>>>>>>>>>>>>>;>>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>>>>>>>,>>>>,>>,>>>,>,>>,>>,>>>,>>,>>,>>,,>>>>,,>,>,>,>,>,>,>,>,>,>,>,,>,>>,>,>,,>,,>,>,>,,,>,>,>,,>,,>,,>,,,,,,,>,>,,,>,>,>,,,,,,,>,,>,,,,,,,,,,,,,,,>,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,',,,,,,',,',,,,,,,,,,',,,,',,,,>>>>;>>;;--;>,>>>>>;;-=**&&%%%&&&*=--;>>>>>>,>>,>,>>;;--=***==---------=-=----;;;;;;;>,,,,',',',''',''''',,',','',','''',''''''',','''''',''''''',''','''''',''',''''''',''''''''", +">;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;;>>;>;>;>;>>;>;;>;>;>;>;>;>;>;>;>;>;>;>>;>>;>;>;>>>>;>;>;>;>>;>;>>>>;>>>;>>;;>>>>>;>>>;>;>;>>>>;>>;>>;>;>>;>>>;>>>;>>>>;>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>>>>>>,>>,>>,>>>>,>,>>>>,>,>,>,>,>,>>>,>,>>,>>,>>>>,>>,>>,>,>>,>>,>,>>>,,>,>>,>,>,>,>,>,>,>,>,>,,>,>,>,,>,>,>,>,>,>,>,,>>,,,,,,,,,>,,>,,>,>,>,,,,,>,,,,,,,,>,,>,,,,,,,,,>,,>,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,,,',,,,,,,>>;>;;;;----;>>>>>;;-==*&&%&%&&&**=--;;;>>>>>>>,>>>>;;-===**==------=-===-=---;-;;-;;;>,,',','',','',,','',''''''''',','',',',''''',',''''',',''''',''','''''''''''''''''''''''''", +">;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;;>;>;>;>;>;>>;>>;>;>;>;>>;>;>;>>>;>>;>;>;>;>;>;>>;>>;>;>;>;>;>;>;;>;>;>>;>>;;>>>;>;>>;;>>;>>>>;>;>>>;>>>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>,>>>>>,>>>>>>>>>>>>>,>,>>>,>>,>,>,>>,>,>,>>,>,>,>,>,>,,>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,,,>,,>,,>,,,>,,,>,>,>>,>,,>,,>,,,,,,>,>,,,>,>,,>,,,,,,,>,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',',,,,,,,,',,,,>>;-;-;--==-;;>>>>;--=*&&&%%%%&&**=--;;>;>>;>>,>>>;;;-==*****==--=-=========-;-;;-;-;>>,,,,',,'',',''',','',',,',,',''',''''''',','''''',''''',','''''''','''''','',''''''''','''", +">;;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>>;>>;>;>;>;>;>;>>>;;>;>;>;>;>;;>;>;>>;>>;>;;>>;>;>;>;>;>>;>>>;>;>>;>>;>>>;;>>>;>>>>;>>;>;>>>>;>>>;>;>;>;>>>>>>>;>;>;>>>>;>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>,>>,>>>>>>>>>,>,>>,>>>>,>>>>,>,>,>,>,>>>>>>,>>,>>>>>>,>>,>>>,>,>>,>>>,>>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>>,>,>,>,,>>,,>>,,,>,,,,>,,,>,,>,>,,,,,,>,,,,,,,,,>,,>,,,,,,,,,,,,,,,>,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,>>;;----==**=-;;;;;;--=**&%&%%&&&&*==--;;;;;;>>>>>;-==**&&&&&&**=======*====---;-;--;-;>>,,,,',,''',',''',''''''''''','',',',','''',',',''',''''''','','''''',''''''''''''''''''''", +">>;>>;>>;>>;>;>;>>;>;>;>>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;;;>>>;>>;>;;>>>;>>;>;>;;>;>>;;>;>;>;>;>;>;;>;>>>;>;>;>;;>>>;>;>>;>;>>;>>>;>;>>>;>>;>>>>>>>>;>;>>>>>>>;>>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>,>>>>>>>>>>,>,>,>>,>>>,,>,>>,>>,>,>>>,>,>,>,>,>>,>>,>,,>>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,,,>,,,>,,,,>,,>,>,,,>,,,>,,,,>,>,,,>,>,>,,>,,,,,,,,,>,,,,>,,>,,,,,,,>,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,,,,,,',,',,,,>>;---===****=-;;;;--=**&&%%%%%&&**==-----=------==***&&&%%%%%%&&&*********==-;------;;;>>,,,,',,',',',,',',,',',',',','''''''''','''''''''',''','''''''''''''''''''','''','''''''", +";>;>;>;>;;>;>;>;>;>;>>;;>;>>>;>;>;;>;>;>;>;>;>;>;>;>;>>>>;;>;;>;>>>;;>;;>;>;>>;>;>;>>;>>;>;>;>;>>;>>;;>;>>>;>>>;;>>;>;>>>;>;>;>>>>>;>>;>>>>;>;>>;>>>>>>;>>>>>>>>;>>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>>>>>,>>,>>>>,>>>>,>,>,>,>,>>>>>,>>>,>,>>>,>>,>>,>>,,>>>,>>>,>,>,>,>,>>>,,>,>,>,>,>,>,>,>,,>,,>,>,,>,>,,>,>,>,>,>,>>,>,,,,>,>,,>,,,>,>,,,,>,,,,,,,,,,,>,>,,>,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,',,,,,,,,,,,,,>;;======*&&&*=-----==**&&&%%%&&&***=-===**&*===----;----==**&&%%%%%&&***=*==-------;;;;;;>>,,,',''','''','''',''','''',',',',',''',','',''''',''','',''','','','',''''','''''''''", +">;>;>;>;>>>;>>;>;>>;;>>>;>;;>>;>;>>;>;>;>;>>>;>;>;>;>;;;;>;>>>;>;;;>>;>>;>;>;>>;>;>;;>;;>>;>>;>;>;>;>>>;>;;>>;>>>;>>>>;;>>>>>>;>;>>>;>>>>;>>>>;>>>>>;>>>>;>>>;>>>>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>,>>>>,>>>>>>>>>>>>,>,>>,>,>>>>,>>,>,>,>,>>>,,>>,,>>,>,>,>>,>,,>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,,,>,,>,,,,,>,>,,,,>,>,>,,,,>,>,,,,>,>,>,>,,,,,,,,,>,,,,,,,,>,,,,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,',,,,',,',,,,>;-==*****&&&&*=--===**&&&%%%%%&&&**=**&%%%&*-;>,,',,''',,>;;;--*&&%%%%&****===--==--;-;;;>>>,,,,,','',','',','',''',','''''''''',''',''''',''''''''''''''''''''''''''''''''',''''", +">;>;>;>;>;;>;>;>;;>>;;;>;>>;;>;>;>>;>;>;>>;;>;>>>;>;>>>>;>>;;>;>>>;;>;>>;>;>;;>;>;>>;>>;>;>;>;>;>>;>;>;>>>>;>;>;>>;>;>>>;>;;>>>>>;>>>;>;>>;>>>>>>;>>>;>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>>>>>>>>>>>>>,>,>>>>>,>>>,>,>,>,>,>>>>>>,>>>,>,>>,>>>>>,>>,>,>>>,>>>,>,>,>>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,>,>,>,>,,>,>,>,,,>,>,,>,,,,>,,,,,,>,>,,,,,,,,,>,,,>,,,,,,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,',,,>;-=**&*&&&&&&&*====***&&%%%%%%&&&*&&&&%%&*->,,',','','',,>>;;;>>;-*&&%%%&**=====*=--;-;;;;>>,,,,,'',','','''','',,'''',',',',',''',''',''''','',',''','''''''''''''''''''''''''''", +";>;>;>;>;>;>;>;>>;>;>>>;>;;>>;>>;;>>;>;>;;>>;>;;>>;>;;>;>;;>>;>;>;>>;>;;>;>;>>;>;>;>;>;>;>;>;>>;>;>>;>>;>;;>>;>>>;>>>;>;>>>;>;>;>>>;>>>>;>>;>>;>>>;>>>>;>>>>>>>;>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>>>,>>>>>>>,>>>>>>>>>>>>>>>,>,>,>>>,>>>,>>,>,>,>>,>>,>>,>>,,>,>>,>,>,>>,,,>,>,>,>,>,>,>,>,,,>,,>,>,>,,>,>,,,>,,,>,>,>,,,>,,>,>,,,,>,,>,>,>,,,,,>,>,,>,,,,>,,,,>,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,',,,,,,>>;-**&&&&&%%%&&**=****&&&&%%%%%%&&&&%$%&*->,,',',''''',',,>>>>;>;>>>;=*&%$%&*=*=**=---;--;;;>>,,',,,''','',','','''',,''''''''''','''''',','''''''''''''','',','''''''''''''''''''", +">;>>;>;>>;>>;>>;>;>;;>;>>>;>;>;>>;;>;>;>>;;>;>>;;>;>>;>;>>;>;>>;>;>;>;>>>;>;>;>>;>;>;>;>;>;>;;>;>;>;>;>;>>>;>;>;>>;>>;>>;>>>>>>;>;>>;>;>>>>>>>>;>>>>;>>>>;>>>>>>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>>,>>>>,>>,>,>,>,>,>>>>>>>,>,>>,>>,>>>>>,>,>,>>,>,>,>>,>,>>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,,>>,>,,>>,,>>,,,>,,>,,>,,,,,>,>,,,,,,,,,>,>,,,,,,,,,>,,,,,>,,,,,,,,>,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,',,',,,,,',,,,,>--**&&&&&%%%%%&&***&*&&&%%%%%&%&%%%%%&=;,,',','',',''''',,>>>;>;>;;>;;=*%%$%&****=-------;;>>,,,,',',','''','',','''',',',',',''',',''''''',','','',''''''''''','''''''''''''''''", +">;>;>>;>;>;;>;;>;>;>>;>;;;>>;>;;>>>;>>;>;>>;>;;>>>;>;>;>;>;>;;>;>;>>;>;;;>>;>;>;>;>;>;>;>;>;>>;>>;>>;>;>;>;>;>>>;>>;>>;>>;>;>;>>>>;>>>>>;>;>;>>>>>;>>>;>>>>;>>>;>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>>>,>>>>>>>>>>,>,>,>,>>>,>>,>>,>,>,>>>,>,>>,>>>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,,,>,,,>>,,>,,>,,>,>,>,,>,>,>,>,>,,,,,>,>,,>,,,,>,>,,,,,,,>,,,,,,>,,,,,>,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,',,,>>-=*&&&%%%%%%%%&&&&*&&&&&&%%%%%%%%$%&*=;;,,,,',',''''',',,,,>>>>>>>>;>;;;=&%%%%&&**---;-----;;>,,,,',''',','','''',',''''''''''','''',''','''''''''''''','''''''''',''',''',''''''", +">;>;;>;>;>>;>>;>;>;>;>>;>>;>;>>;;;>;>;>;>;>;>>;>;;>>;>;>;>;>>;>;>;;>;>>>;>;>>;>;>;>>;>>;>>;>;>;>;>;>>>;>>;>>;>;>>;>>;>>;>>>;>>;>>>>;>;>>>>>>>>;>>>>>;>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>,>>>>>>>>,>>,>>>>>>>>,>,>,>>,>>>>>>>>,>>,>>>,>>>,>,>,>>>,>>,>,,>,>>,>,>,>>,>,>,>,>,>,>,>,>,>,,>,>,,,>,>>>,,,>,>,,>>,,,>,,>,,>,,,>,,>,,,,,,,,,,>,>,,,,,,,,,>,,,,,,,>,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,>>-=*&&%%%&%%$%%%&&&&&&&%%%%%%%%$$%%&*=-;>>,',','',',''''',,,,,>>>>>>>>;;;;-*&%%%&**=--------;;>>,',',,,'',','',',''',',',',','''',''''',''','',',''''',''','',''''''''''''''''''''", +";>;>>;>;>;;>>;>;>;>;>;>;>;;>;>;>>>;>;>;>;>>;>;>;>>;;>;>;>;>;>;>;>>;>;>;;>;>;;>;>;>;;>;>;>;>;>;>>>;>;>;>>;>;>>;>;>>;>>>;>>;>>>>>;>;>>>>>;>;>>;>>;>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>>>>>>>>,>>,>>>>>>>,>>>>,>,>,>>,>>,>,>>,>>>>,>,,>,>,>,>>,>,>>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>>,,>,,,>,>,>,>,,,>,>,>,,>,,,>,,>,,>,>,>,>,>,,,,>,>,>,>,,,,,,,>,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,',,,,,,,,',,,,,,',,',,,,>-=&&&%%%%%$%$$%%%&&&&%&&%%%%$$$%%&*=--;>>,,,',',''',',','',,,,,,,>>>>>>>;;-*&%$$&*==----=----;>,,,,''','''','','',''''''''''',''',','''''''''''''',''''''''''''''''''''''''''''''", +";>;>>;>;>>>;;>>;>;>;>;>;>>;>;>;>;>;>;>;>;;>;>;>;;>>;>;>;>;>;>;>>;>;>>;>>;>;>>>;>;>>>;>;>;>>;>;;>>;>;>>;>;>>;>>>;>>;>;>>;>;>;>;>>>>;>;>>>>>>>>>>>>>;>>>>>>;>>>>>>>>;>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>,>,>>,>>>>>>,>,>>>>>,>>>>>>,>>>,>>>>,>>,,>,>>>>,>>,>>,>>,>,>,>,>>,,>>,>,>,>,>,>,>,>,,>,,>,,>,>,>,>,,,>,,>>,,,>,,>,,>,>,,,,>,,,,,,,,,,>,,,,,,,,,,,>,>,>,,,>,,,,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,',,,,,',',,,,,,',,>>;=*%%%%$%$$%$%%%%%%%&%%%%%%$$$$&&===--;>>,,,,,',,,',',',,,',,,,,,,>>>>;>;;;-*&%$$&*====-====--;>,,',''',','','','',',',',',''','''''','',','','','''''''''''','''''''''''''''''''", +">;>;;>;>;;>>;>;>;>;>;>>;>;>;>;>;>;>;>>>;>>;>;>>>;>;>;>;>>>;>;>;;>;>;;>;;>;>;;>>;>;;;>;>;>;;>;>>;>>;>;;>>;>;>>;>>;>>;>>;>>>>>>>>;>>>;>>;>>;>;>>;>>>>>;>>>>>>;>>;>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>>>,>>,>>>>>>,>>>>>>>>>,>>,>>>>,>,>,>>,>,>,>>,>>,>,>>,>>,>>>,,>>>,>>,>>,>,>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,,>>,>,>,,>,>,,>,,,>>,,>,,,>,,,>,>,,>,>,>,>,>,,,>,>,>,,>,,,,,,,,,,,,>,,>,,,,,>,,,,,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,,,,,,,,',',,,,,>>-**&%%%%$%$$$$$%%%%%%&%%%%$$$%%&**=--;>>>,,,,,,,',,,,,,,',,,,,,,,,,,>>>>;;;;-*&%$%%*=====-===--;>,,',',''',''','',''''''','',''','','''''''''''''''''','','''''','''',''','''''''", +">;>>;>;>>;;>;>;>;>;>>;;>>;>;>;>;>;>;>;>;>;>>;;;>;>;>>>;;;>;>;>>;>;>>;>>;>;>>;;>;>>>;>>;>;>>>;>>;>;>>>>;>>;>;>>;>>;>>;>>;>;>;>;>>;>>>;>>;>>>>>>>>;>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>,>>,>>>>>>>>>,>>>>>>>,>>>>>>,>>,>>>,>>>>>,>,>>>,,>>,>,>,>,>>,,>,>,>,>,>,>,>,>,>,>,>,>,,>>,,>,>,>,>,,>,>,>,,,,>,,>,,>,>,,,>,,,,,,,,,,,>,,,,,,,,,,,>,,,>,,>,,,,,,,,>,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,',,,,,',,,,>;=*&%%$%$$%$%$$%%%%%%%%%%%$$$%&**==-;;>>>,,,,,,,,,,,,,,,,,,,,,,,>,>,,>>>>;;--=*&$$%&**=========;;,,,''',''',''','',',',''',''',''''''','','','''''','''''''''''''''''''''''''''''", +">;>;>>;>;>>;>;>;>;>;>>;;>>;>;>;>;>;>;>;>;>;>>>>;>;>;;>>>;>>;>;>;>>;>;>;>>;>;>>;>;>;>;>>;>;;;>;;>>>;;>;>;>;>>;>>;>>;>>;>;>>>>>>;>>>;>>>>>>>>;>>;>>;>>>>>;>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>,>>>>>>>,>>,>,>>>,>,>,>>>,>,>,>>,>>>,>>>,>,>>,>,,>>,>,>>>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,>>,,>,,>,,>,,>,>,,>,>>,>,,>,>,,>,,>,,,>,>,>,>,>,,,>,>,>,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,',,,,,',,,,,',,,,,,>>-=&&%$%$%$$$$$$$$%%%%%%%$$$$%&&*==-;;>>>>,>>,,,>,>,,,,>,,>,,,>,>,>,>>>>>>;;;--=*&$$$%**====**===;>,,,,''',',','','''''','''','','',','''''''','',''''',''',''''''''''''''''''''''", +">;>;;>;>;>;>>;>;>>;>;>>;;>;>>;>>;>>;>;>;>;>;;;>;>;>>;;;>>;>;>;>;>;>;>>;;>;>;>;>>;>;>;;>;>>>;>>>;;>>>;>>;>>;>>;>>;>>;>>>>;>;>>>>;>>>;>;>;>;>>>>>>>>;>>>>>>;>>>>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>,>>>>>>>>>,>>,>>>>>>>>>,>>>>>>,>>>>>>>,>>,>>,>,>,>>,>>>>>,>>>,>,>,>>,>,,>>>,>>,>,>,>,>,>,>,>,,>,,,>,>,>,>,>,>,,>,,>,,,>,>,,,,,,,>,,>,>,,,,,,,,,>,,,,,,,,,,,,,,,>,>,,>,,>,,>,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,,,',,,',,,,,',,',,>;=*&%%$$$%$%$%$$$$%$%%$%$$$$%&**=--;;>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>;;;---=*%$$%%*****=**==-;,,'',',''''','',','''',','''''''''''',','''''''''''''','''''''','''''''''''''''", +";>;>>;>;>;>;>>;>;>;>;;>>>;>;>>;;>;;>;>;>;>;>>>;>;>;;>>>;>;>>;>;>;>;>;;>>;>;>;>;;>;>;>>;>;>;>;>;>>;;>;>;>;>>;>>;>>;>>>;;>>>>;>>;>>;>>>>>>>>>>;>;>>>>;>>>>>>>>;>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>>>>>>>,>>>>>>>,>,>>,>>>>,>,>>>>,>,>,>>>,>>,>>>>>,>,>,,>,>,>,>,>>,>,>,>>,,>,>,>,>,>,>,>,>,>,>,>,>>,,>,,>,>,,,>,>,>,,>,,>,>,>>,>,,,>,,,>,>,>,>,,,>,>,>,>,,>,,>,,,,,,,,,,,,,,,>,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,,,,,,,,,',,,,,,,,>;=*&%%$%$$$$$$%$%$$%$$$$$$%%&&*=--;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;>;;;-=-=&%$$$&&*******=-;>,','''',','','''',','''''',',''',','''''',''','','''''''','''''''','''''''''''", +";>;>>;>;>;>;;>;>;>;>>;;;>;>;;>>;>>;>;>;>;>;;>;>>;>>;>;;>;>;>;>;>;>;>>;>;>>;>;>>;>;>;;>;>;>;>>;>;>>>;>>;>>;>>;>>;>>;;>>>;>;>>;>>>;>>;>;>>;>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>,>>>>>>,>,>>>>>>>>>,>,>>>>,>,>>>>>,>,>>,>>,>,>>,>>,>>,>>,>>>,>,>>,>,>,>>,>>,>,>,>,>,>,>,>,>,,>,,>,>>,>,,>>,,,>,,>,>,,>,,,,,,>,>,,>,,,,,,,,,>,,,,,,,,,,,,,,,>,,>,>,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,',,',,,,,,,',,',,,',,',,,>>-*&%%$$%$$%$$$$$%$$%$$$$$%&&**=-;;;;>>;>;>>;>>>>>>>>>>>>>>>>>>>>;>>>;>;>;;;----==&$$$%&********=;>,,',',','','','''''',',',''''','''''',''''''''''''',''''''''''''''''''''''''''", +">;>;;>;>;>;>>;>>;>;>;>>>;>;>>;;>>;>;>;>;>;>>;>;>;>;>;>>;>;>;>;>;>>;>;>;>;;>>;>;>;>;>>;>;>;>>;>>;>;>;>;>;>>;>>;>>;>>>>;>>>>;>>>;>>;>>>>>>>>;>>>;>>>;>>>;>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>>>>>,>>>,>,>>>>>>>,>>>>>>,>,>>>,>>>,>>>,>>,>>>,>>,>,>,>>,>,>,>>,>,>,,>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,,>,>,,>,,>,>,,>,>,>,,,>,,>,>,>,>,,,>,>,>,,>,>,>,,,,,,,,,>,,>,,>,,,,,>,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,;-*&%%%$$$$$$%$%$$$$$%$$$$%&**=--;;;;-;;-;-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--==&%$$$$&&&&&&**=-;,,,',''','','',',','''''',','''''',''''',',''''','''',''''''''''''',''''''''''", +">;>>;>;>;>;>;>;>;>;>;;>;>>;;>>>;;>>;>;>;>;>;>>;>;>;>;>;>;>;>>;>;;>;>;>;>>;;>;>;>>>;>;>>;>;>;>;>>>;>>;>>;>>;>>;>>;>;>>;>;>>>;>>>>>>;>;>;>;>>;>>>>>>>>>>>>>>>;>;>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>>>>>>>,>>>>>,>>>>>,>,>,>>>,>,>>>>>,>>,>,>>,>>>,>>,,>>,>>>,>>,>,>,>>,>,>,>>>,>,>,>,>,>,>,>,,>,>,>,,>>,>,>,,>,,>,>,,>,,>,,,>,,>,,>,,>,,,,,,>,,,,,,,>,,,,,,,>,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',',,',',,',,,,,>-=&%%$%$%$%$$$$$%$$$$$$$%&&*=---;--=*******=--;-;;;;;;;;;;;;;;;;;;;;;;;;;;-;---==*&$$$$%&&**&**=-;,,,'',''',''''''''',',''''''','',''',','''''',''''''''''''','','''''''''''''''", +">;>;>>;>>;>;>;;>>;>;>>;>;;>>;;>>;;>>;>>>;>;>;;>;>;>;>;>>;>;>;>;>>;>;>;>>;>>;>;>;;;>;>;;>;>;>>;>;;>>;>>;>;>>;>>;>>;>;>>>>>;>>;>;>;>>>>>>>>>>>;>>;>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>,>>>>>>>>,>>>>>,>,>>,>>>>,>>,,>>,>>>,>>,,>>,>,>>,>,,>,>>,>,,>,>,>,>,>,>,>,>,>,,>,>>,,,>,,>,>,>,,>,>,,>,,>,,>,,>,,>,,>,>,>,,,>,>,>,,,,,,>,,,,,,>,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,',,,',,,,,,,,,,,,,,,,,>,>;-*&%$$$$$$$$$$$$$$$$$$$%&**=---=*&&%&%%&%&&&*=----------;----;--;--;-;-;-;-----==&$$$$$&&&&&**=->>,',',',''',',',','''',','','''''''''''''''''''''''''','''''''''''''''''''''''", +">;>;;>>;>;>;>>>;>;>;>;>;>>;>;>;>>;;>;;;>;>;>>;>;>;>;>;;>;>;>;>>;>;>;>>;;>;>;>;>>>;>>;>>>;>>;>>;>>;>;>;>>;>>;>>;>>>>;>;>;>>>>>>;>>;>>>;>>;>>>>>>>>>>;>>>>>>>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>,>>>>,>>,>,>>>>>,>>>>>,>,>,>>>,>,>>,>>,>>,>,>>,>>>,>,>,>,>,>>,>,>>,>,>>>,>,>,>>,>,>,>,>,>,>,>,>,,>,>,,,>>,>,>,,,>,>,,,>,>,,>,,,,>,,>,,,,,,,,,>,,,,,,,,>,>,,,,>,,,,,>,,,,,>,,>,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,',,,,,,,,',,,,',,',,',,',,',,,,>>-=&%%$%$$%$$%$$$$$$$$$$%&**==*&&%&&&&**&&&&%%&&=---;-------;-----------------===**%$$$$%%&&&**=-;,,,'','','','''''','''''','''','','','','','''','','''''''''''''''''''''''''''", +";>;>>;;>;>;>;;;>;>>;>>;>;;>>;>;>;>>;>>>;>>;>;>;>>;>>;>>;>;>;>;;>;>;>;;>>;>;>;>;;>;>;>;;;>;>;>;>>;>>;>>;>>;>>;>>;;>>;>>>>>;>;>>>>>>;>>>>>>;>>;>;>>>>>;>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>,>>>>>>,>>>,>>>>,>>>,>>>,>>,>,>>>,>>,>>>,>>,>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>>,,>,>>,,>,,,>>,,,,>,>,,,>,,>,>,,>,,,>,>,>,>,,,>,>,>,,,,,,>,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,',,,,>>-*&%$$$$$$$$$%$$$$$$$%&**==*&%%&&*=***=***&&%%&*=----------------------------==**%$$$$$%&&&**=-;,,,,',',',''',',''',',','''',''''''''''''''','''''''''''''''''''''''''''''''''", +";>;>;>>;>>;>>>;>;;>;;>;>>>;>;>;>;>;>;;>;>;>;>>;>;>;>;>;>>;>;>>;>>>;>>;>;>>;>;>>;>;>;>>>>>;>>;>;>;>;>;>>;>>;>>;>>>;>>;>;>>;>>;>;>;>>;>>;>>>>>>>>>;>>>>>>;>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>,>>,>>>>>>>>>>>,>,>>>,>>>>,>>>,>,>>,>>,>>>>,,>>,>>,,>>,>>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,,>,,>,>,,>,,>,>,,,>>>,>,,>>,,>,,,>,,,>,,>,,,,,,>,,,,,,,>,,,>,,,>,,,,>,,>,,>,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,',',,',,',,',,,,,,,>>;=&%$%$$$%$$$$$$$$$#$%&***&%%&&***&&%%%%&%&&%%$&&*=============================**&$$$$$%%&&**=->>,',',','',''''','''''''',''''','','',''''''''''''','''',''''','''''''''''''''", +">;>;>;;>;>;>;;>;>>;>>;>;;;>;>;>;>;>;>>;>;>;>;;>;>;>>;>;>;>>;>;>;>;>;;>;>;;>>;>;>;>;>;;;>;>;>>;>;>>>;>;>>;>>>;>>;>>;>>>>;>>>;>>>>>>>>>>>>>>;>>;>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>,>>>>,>>>>>>>>,>>>,>,>>>>>,>>>,>,>>>,>>>>,>>,>>,>,>>,>,>,>>>,>>,>,>,>>,>>,>,>,,>,>,>,>,>,>,>,>,>,>,,>,>,>>,,>,>,,,,,,>,,,>,,,>,,>>,,>,,,>,>,,,>,>,>,,,>,,,,,,,,>,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,',,,,,,,,,,,,',,,,,,,',,,,,>;=&%$$%$$$%$$$$$#$$$#&&**&%%&&*&%###$$$###@$%$%%%&=============================**&%#$$$$%&&&*=-;,,,,',','''',',''',',','''',','',''''''',''','','''''''''''''''','''''''''''''", +">;>;>>;>;>;>>;>;>;>;>;>>>;>;>;>;>;>;>;>;>>;>>;>;>;;>;>;>;;>;>;>;>;>>;>;>>;>;>;>>;>;>>>;>;>>;>>>;>;>;>>;>>;;>>;>>;>>;>>>>;>>>>;>;>;>>;>>;>>>;>>>;>>>>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>,>>,>>>,>>>>>,>,>>,>>>>>,>>,>,>>>,>>,>>>,>>>,>>,>,>,>,>>,>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>>,>,>,,>,>,,>,>>,>,,>>,,>,>,,,,,>,,>,,,,,>,,,,,,,>,,,,>,,>,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,',,,',,',,,,,',,,,,,',,,,;=&%$$$$$$$$$$$$#$##$&&*&%%&&&$#@@$%&*&&&$@+@@#$$$&*====*=====****&*&*****==*=***&%#$$$$$&&**=;;,,'',,',,','''',''''''',''''''''''','','''''''''',''''''''',''''''''''''''''''", +";>>;>;>;>>;>;>;>;>;>>;>;;>;>;>>>;>;>;>;>;>;>;>;>;>>;>;>;>>>;>;>;>;>;>>;>;>;>;>;;>>;>;;>>;>;>;;>;>>;>;>>;>>>;>>;>>;>>;>;>>>;>;>>>>>;>>>>>;>>>>>>>;>>>>;>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>,>>>>>>>>,>,>>>,>>,>,>>,>>>,>>,,>>,>,>>,>>>,,>>,>>,>>>,>,>,>,>,>,>,>,>,>,,>,,,,>,,>,>,,,>,>,,,>,>,,,>,,>,,>,>,,>,,,>,>,,,>,>,>,,,>,,,,,,,,>,,,>,,>,,>,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,,,,,,,,',,,,,,,,',,,,,',',,,,,>;=&%%$%$$$%$$$##$#$#$&&&%%%&%#@@$&-;,,,,;=&$++++@@#&*********&&%&%&&&%&%&&&******&%#$$$$$%&**=-;,,,,',,',''',''',',',''','',''',',''''''','''''''''','''''''''''''''''''''''''", +";>;>;>>;;>;>;>;>;>;;>;>>;>;>>;;>;>;>>;>;>;>;>>;>;>;>>;>;>;;>>;>;>;>;;>;>;>;>;>>;>;>;>>;>>;>>>;>>;>;>>;>>;>>;>>;>>>;>>>>;>>;>>>;>>>>>;>>>>>;>;>>>>>;>>>>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>>,>>>>,>>>>>,>>,>>>,>,>,>>>>>,>>>,>>>,>>>,>>,>,>>,>>>>,>>,,>>>,>,>,>,,>,>>,>,>,>,>,>,>,>,>,>,>>,>,>,,>,>,>,,>,,>,,>,,,>,,>,,,>,,,>,,,,,>,,,,,,,>,,,,>,>,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,',',,',,,',,,,,,,,,,,>;=&%$$$$$$$$$$#$####%&&$$%%$@+#&->'''''''',-&#+..++#&*****&%%%%&&******&&&%%&****&%##$$$$$&&*=-;>,',',,,',''',''''''',''''''',''''','''''''','','''''''','''''''''''''''''''''", +">;>;>;;>>;>;>;>;>>>;>;>;>;>;;>>;>;>;>>;>;>;>;;>>;>;>;>;>;>>;;>;>;>;>>;>;>;>>;>;>;>;>;;>;>>;>;>;>>;>>;>>;>>>;>>;>;>>>;>>>;>>>;>>>>;>>>;>>;>>>>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>,>>>>>>>>>>>>>>>>,>,>>>>,>>>>>>>,>>>>>>,>,>>>,>,>>,>>>,>>,>>>>,>>,,>,>,>>>,,,>,>,>,>>>>,,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,,>,,>,>,,>,>,>,,,,>,>,,>>,,>,>,,,>,>,>,,,>,,,,,,,,,,,>,,,>,,,,,,,,>,,,,,,,,>,,,,,>,,>,,,,,,,,,,,,,,,,,,,',,,,,',,,,,',,',,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,>;*&%$%$%$$$$$##$####%&%$$%$++$=>''''''''''''>*$....@$&&*&&$#%&******=*==**&%$$&&&&$###$$$$%&*=->>,,,,,,,,'',''',',',''','',''''',''''','''''''''''''''''''''''''''''''''''''''", +">;>;>>;>;>>;>>>;;;>;>;>;>;>>;>;>>;>;;>;>;>;>>;>;>>;>;>;>;;>>;>;>>>;;>;>;>;>;>;>;>>;>>>>;;>;>>>;;>>;>>;>>;;>>;>>>;>;>>;>>>;>>>;>;>>;>>>>>>>>;>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>,>>>>,>,>>>>,>,>>>>>>,>>>>>,>>,>,>,>>,,>>,>>>,>>>,>,>>>,>,>>>,,,,>>,>,>,>,>,>,>,>,,>,,>,,>,>,>,,>,,>,>,,>,>,,,>,>,,,,>,,,,>,,,,>,,,,,,,>,,,,>,,>,>,,>,,,>,,,>,,>,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',',,',,',,',,,,,,,>-=&%%$$$$%$$$#####@@%%$$$$++$*-,''''''''''''',=$....@%&&$##$&&&%%%%%%%%&&**&%$#%&&$@##$$$$%&**=;>,,',,>,,,''','''''',''''''',''''','''''',''',''',''''''''''',''''''''''''''''", +">>;>;>;>;>;>;>;>>>>;>>;>;>;>;>;>;>;>>;>;>>;>;>;>;;>;>>;>>;>;>;>;;>>>;>;>;>;>>;>;>;>;;;>>>>>;;>>;>;>;>>;>>>;>>;>;>>>;>>>;>>>;>>>>>>>>;>;>;>>>>>>;>>>>>>>;>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>,>>>>,>>>>>>>,>>>>,>,>,>>>,>,>>>,>>>>>,>>>,>>,,>>,,>,>>,,>>,>,,>>>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,>,>,,>,,>,,,>>,,>,>,>,,,>,>,,,>,,,>,>,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,',,,,,,,,,,,',,,,,,,,,,,,,,>>;=&%%$$$$$$$#$$##@@@$$#$$@+#*=;>'''''''''''''',=#...+$%$@@$$$###@@@@++@@#%&*&&##%%$@###$$$$&&*=->,,>,>>,,'',''',','''','',''''',''','''''','''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>;;>;;>;>;>;>;>;>;>;>;;>;>;>;>;>;>;>>;>;>;>;>;>>;>>;;;>>;>>;>;;>;>;>;>>>;>;;;>>>;>>;>>>;>>;>>>;>>>;>>>>;>>>;>>;>;>>>;>>>>>>>;>>>>>>>;>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>>>>>>,>>>>,>>>>,>>,>>>,>>>>>>>>,>>,>>,>,>>,>,>>,>>,>,>>,>>>>>,>>>,>,>>,,>,>>,>,>,>,>,>,>,,>,>,,>,>,>,>,>,,>,,>,,>,>,>,,,>,,,>,,>,,>,,,>,,>,,,,,,,>,,,,>,>,,>,,>,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,',,,,,,,,,,',,',,,,,,',,,,,,,,>,,,,>-=&%%$%$$$$$######+@###$@++&=-;;>,'''''''''''''>*@...@@+@#@@@@@#$$#$###@@+@$&&&#@##+@#$$$$$%&*=-;>,>>>>>,,'',''''',''''''','','''''''',''''''',''''',''''','''''''''''''''''''", +">;>;>;>;>;>;>;>>;>>;>;>>>;>;>;>;>;>>;>;>;>;>;>;>;;>;>;>;>;>;;>;;>>>;>;>;>;>>;>>;>;>;>;>>>>;;>>;>;>;>>;>>;>;>>;>>;>;>>;>>>;>>>>;>>>>>>;>>>>;>;>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>>>>>,>>>>,>>>>>>,>>>>,>,>,>>>,>>>,>>>>,>>>>,>,>>,>>,>>,,>,>,,>,>>,>>,>,>,>,>,>,>,>,>,>>,>,>,,>,>,>,>,>,,>,>,>,,,>,,>,,,>,,>,,>,,,>,,>,,,>,>,>,,,>,,,,,,,,,,,,,,,>,,>,,>,,,,>,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,,',,',,,,',,,,,>>,>,>>;=*%%$$%$$$$#$###@++@#$#@+%=-;;>,>''''''''''''',-%+.+@++.+++$&=;>>,,,>;=*%@+@%%%@+@+@###$$$%&**=;>>>;;;,,,''',',''','',''''''''',''''''''','''''''''',''''''''''''''''''''''''", +">;>>;>>;>;>;>;>;>;>;>;>;>;>;>>;>>;>;>>;>;>;>;>;>>;>;>;>;>;>>;>>;>;>;>;>;>;>;>;>;>;>;>>;;>>>;>;>>;>>;>>;>>;>>;>;>>>>;>>;>>>;>;>>;>>;>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>>>>,>>>>>>>>>,>>>>,>>,>>,>,>>>>>>,>>>>,>>,>,>,>,>>>>,>,>,>>,>>>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,>,>,>,,>,,>,>,,,>,>>,,>,>,>,,>,,>,,>,,>,,,,>,,,,,,>,,,,>,,,>,,>,>,,,,,,,,,,,,,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,,',,,,',,,,,,,,,',,,,,,>,>>,,,>>;=&&%$$$$%$$####@@+++##@.#*--;>>,,,'''''''''''''>*#..++...#&=->''''''''',;*%@@$%$.+++##$$$$$%&*=------;>,'','''','''''',','','''''','''''''',''','''''''''''''''''''''''''''''", +";>;>>;;>;>;>;>;>;>;>;>;;>>;>;>;>;>;>;;>;>>>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>>;>;>>;>;>;>>;>>;>>;>>;>>;>>>>>>;>>>;>>;>>>>>>>>>>>>;>>>>>>>>>;>>>;>>>;>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>,>>,>>>>,>>>>>>>>>>>,>,>,>>>,>,>>,>>>,>>>,,>,>>>>,>,>,>,>,>,>,>,>,>,>>>,>,>,>,>,>,>,>>,>,>,>,,>,>,,>>,,,>>,,,,>,>,,,,,,>,,,,>,,>,,,,>,,>,>,>,,,>,,,,>,,,,,,,>,,,,,,,,,>,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,,,,,',,',',,,,,,,,,>>>>>,,>>-=&%%$%$$$$$$###@@+++##@+%=-;>>,,,,'''''''''''',,;%+.@+.+%*--;>,'''''''''',-&@+#$+..+@##$$$$&&&=======;>',''',''',',''''''''','',''''','''''''''''''''''''''''''''''''''''''''", +">;>;;>>>;>;>;>;>;>;>;>>;;>;>;>;>;>;>>;>>;;>;>>;>;>;>;>>>;>;>;>;>;>;>;>;;>;>;>;>>;>;>>;>>;>>;>;>;>>;>>;>>;>>;>;;>>>;>>>;>>>;>>;>>;>;>>>>;>;>>>>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>>>>>,>>>>>>,>>>>,>>,>>,>>>>>>>>,>>>>>,>>,>>>,>>>>>,>,,>>>,>>,>>,>,>>>,>,>>,,>,>,>,>,>,>,>,,>,>,,>,>,>,>>,,,>>,,,>>,,,>,>>,>>,,>,>,,>,,>,>,,,,,,,,,>,,,,>,,,,,>,,,,,,,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,,',,,,',,',,,,,,,,',,',,,>>>>>>,,>;=*&%%$$$$$$#$###@++++#@+@*-;;>>,,,,'''''''''''',,;*@+++@%=-;;;>>,'''''''''''>*#@#@.++@##$$$$%&&****&*=;,,'','',''''',','','''''''',''''',''''''''''''''','''''''''''''''''''''", +";>;>>;;>>;>;>;>;>;>>;>;>>;>;>;>;>>;>;>;;>>;>;>>;>;>;>;;>>;>;>;>;>;>>>;>>;>;>;>;;>>;>;>>;>;>;>>;>>;>>;>>;>>;>>>>>;>>>;>>>;>>>>>;>>>>>;>>>>>;>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>,>>>>>>,>>,>,>,>,>>>,>,>>>,>>,>,>,>,>,>>>,,>>,>>,>>,>,,,>>,>,>>,>,>,>,>,>,>,>>,,>,>,>,,>,,,>>,,,>>,,,>,>,,,,,,,,>,,,>,,>,,,,,>,>,>,>,,,>,,,,>,>,,>,,,>,,,,,,,,,,,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,',,',,,,,,,,,,>;;>>,>;=*&&%%$%$$$$$###@@+++@#@.$=;;>>,,,,','''''''''',,,>=$+@#&=-;;>,>,,'''''''''''';*@@+..+@##$$$$%%&&&&&&*=>,',''''',','''''''','',',''''''''','','''''''''''''''''''''''''''''''''", +";>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;;>;>;>>;;>;>;;>;>;>;>>;;>;>;>;>;>>;;>;>;>>;>;>>;>;>>;>;>>;>>;>>;>>;>>;>>;>>;;>;>>;>>>;>>>;>;>>>>>;>>>>;>>>>>;>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>,>>>,>>>>>>>>,>,>>>>>>>>>>>>>,>>>,>,>>,>>>>>,>>>>,,>>>,>>,>,>,>>>>,>,>>,>,>>,>,>,>,>,>,,>>,>,>,>,>,>>,,,>,,,,>>,>,,>>,>,>,,,>,,>,,,>,>,,,,,,,,,>,,,,>,,,,,,,,,>,,,,,>,,,>,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,',,,,,,,,',,',,,,,,',',,,,,>>;;>>>>-*&%%%$$%$%$$$###@@+.++#@+&-;;;>,,,',',''''''''',,>>-&@@%=-;;>>,,,,,''''''''''''>&++..++@#$$$$%%%%&%&&*->,'',','''''','',''''''''''''',''''''''''',''',''''','''''''''''''''''''", +">;>;>>;>;>;>>;>>;>;>;>;>;>;>>>;>>;>;>>;>>;>;>>;>;>;>;;>>;>>>;>;>;>;>>;>;>;>;>;>;>>;>;>>;>;>;>;>>;>>;>>;>>;>>>>>;>>>;>>>;>>>>>>;>>>>;>>>;>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>,>>>>>>>>>>>,>>,>>>>>>,>,>,>,>,>,>>,>,>>>,>>,,>,>>>,,>>>>,>,>,>>>,>,,>,>,>,,>,>,,>,>,>,>,>,>>,,,>,,>,>,>,,>,>,>>,>,,,,>,,,>,,,>,>,,>,,>,,,,,>,>,>,>,,,>,,,,,>,,,>,,,,,>,,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,,>>;;-;>>;=&%%%$%$$$$$#$$$#@+++++@+@*;;;>>,,',',',''''''',;----&##*=;;>,,,,,'''''''''''''',-%....@@##$$$$%%%%%%&=;,',''''',','''''','','',''','''''''''','''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;>;;>;>;>>;>>;>>;;>;>;>>;;>;>;>;>;>>;>>;>>;>;>;;>;>>;;>;;>;>;>;>;>;>;>;>>;>;>>;>;>>;>>;>>;>>;>>;>;>>>;>>>;>>;>;>>;>>;>>>>;>>>>;>>>>>>;>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>,>>>>,>>,>>>>>>,>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>,,>>,>,,>,>>>,>,>,>>,>,>>,>>>,>>,>,>,>,>,>,,>,>,>,>,,>,,>,>,>,,,>,>,>,>,>,,>,,>,,>,,>,>,>,>,,,,,,,,>,,,,>,,,,,>,,,,,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,',,,,,,',,,',',,',,,,',,,',,,>>;---;;-*&%%%$$$$$$$$####@@..++@+$=;>>>>,,,,',','','''>*&*-==*$&**=->,,''',,''''''''''''';*@..++@#$$$$$%%%%%&&-,,'',',''''','','''''''''',''''','','''''''''''''''''''''''''''''''''''''", +";>;>;>>;>;>;>>>;>>;>;>;;>;;>>;>;>;;>>;>;>>;>;>;>;>;>;>;>;>>;>;>>>;>>;>;>;>;>;>;>;>;>>;>;>>;>;>>;>>;>>;>>>;>>>>;>>>;>>;>>>>>>>>>>;>>>>>>>>>;>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>,>>>>,>>,>,>,>,>,>,>,>,>,>,>>>,>,>>>,>,>>>>>,>,>>,>>,>>,>,>>,>,>,,>,>,>,>,>,>>,>,>,,>,>,>>,>,>,,>,,>,>,,>,,>,,>,,>,,>,,,,,,,,,,>,>,>,,,>,,,,,>,,,,,>,>,,,,,,,>,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,,,,',,,',,,,,,,>;-=---=*&%$$$$%$$$$$$$##@+++.+++$->;>>,,,,',',,,',',,=@#;',=&&&%%*=-,,,,''',''''''''''',>=$...+@##$$$$$$%%%&=;,',''''',',''''''',','',''''',''''''''''''''''','''''''''''''''''''''''''", +";>;>;;>;>;>;;;>;;>;>;>>;>>;;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;;>;>;;;>;>;>>;>>;>>;>>>;>;>;>>;>;>>;>>;>>>;>>;;>>;>;>>>;>>>>>;>;>;>>>;>>>;>>;>>>>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>>,>>>>>>>>,>>>>>>>,>>>>>>>>>>>,>>>,>,>>>,>,>>>,>,>,>,>,>,>,>,,>>>,,>,>,>>,>,>,>,>,>,,>,>,,>,>,>,,,,>,,>,>,,>,,>,,>,,>,,>,,,>,,>,>,>,>,,,,,,,>,,,,>,,,,,>,,,,,,,,>,,,,,,>,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,',',,,,,,,,',,,,,>;-*===*&%%$$$$$$%$$$####@++.++.+%->>;>>,,,,,,',,',,'>%+.#=>-&&%@%>,-;,',,',',''''''''''>;=&..+++##$$$$%$%%%*->,'',','''''','','''''''''''''''''','',''''','''''''''''''''''''''''''''''", +">;>;>>;>;>;>>>;>>;>;>;>;>;>>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>>>;>;>;>;>;>;;>;>;>>;>>;>>;>>;>;>>;;>>;>>>;>>>>>;>>>;>;>>>>>>;>>>>;>>>>>;>>>>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>,>>>>>,>>>,>,>>,>>>>>,>,>>>>,>,>,>,>,>>>,>>,>>,>>>>>,>>,>,>>>>,>>,>,>>,,,>>,>>,>,>,>,>,>,>>,>,>,>,>,,>,>>,>,,>,,,>,,>,,>,,>,,>,,,>,,,>,,,,,,,,>,>,>,,,>,,,>,,>,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,',,,,,,,',,,,',,',,,,,,,,,,',',,',,,,,,,>;=****&&%$%$$%$$$$$#$$#@@++.....%->>>>>,,',',,',,,,,=#..+%=*%%#++%;;*>,'',',',''''''',,>;=&+..+@@#$$$$$$%%&=>,',''''',','''''''''',',','''''',''''''',''''''''','''''''''''''''''''''''", +">;>;>;>>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>>;>>;>;>;>;>;>;>;>;>;>>;>;>>;>>;>;>;>;>>>;>>>>;>>;>>>;>;>>>;>>;>>>;>;>>>>;>>>>>;>>>>;>>>>;>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>>>,>>>,>>>,>,>,,>,>,>>>,,>,>,>>>,>,>>>,>,,>,>,>,>,>,>,,>,>,>,>,>,>,,,>,>,>,>>,,>,>,,>,,>,,,>,,>,>,,>,>,>,>,,,,,,>,,,,,,,,,,,>,,,,,>,,,>,,>,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,',,,,,,,,,,',',,,,,;-*&&&%%%$$$$$$%$$$$####@+......%;>>>>,,,,,,',,,',',*$+..@$@#$#..+&*%=,,',',',''''''',,;;-&+..++##$$$$%$%&=>,''',',''''','','',',''''''','','''''''''''''''''''''''''''''''''''''''''''", +";>>;>;>;>;>;>;>;>;;>;>;>;>;>;>;>;>;>;>;>;>>>;>;>;>;>;>;;>;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>>;>;>>;>;>>;>>;>;>>>>;>>;>>>;>>>>>;>>>>>>;>>>>>>>>;>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>,>>,>>>,>>,>>>,>,>,>,>,>,>,>,>>>,>>,>>>>,>>>,,>>>,>>>,,>,>>,,>>,>>,>,>,>,>,>,>>,>,,,>,>,>,>,>,>,>,,,,>,,>,>,,>,,>,>,>,,>,,>,,,,,,,>,,>,,,>,,>,,>,>,,,,,>,,,>,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,',,',,',,,,,,,,,,,;-*&&%%%$$%$$$$$$$$#$##@@++.....%;>>>>>,,,,,,,',,,,,&%+.....+##+..@++*',,,,,,',,'''',,>>--&+..++@#$$$$$%%*;,,',''''',',''''''''''''''''''''''''',''''''''''''''''''''''''''''''''''''''", +";>;>>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>>>;>;>>;;>;>;>;>;>;>>;>>>;>;>;>;>;>;>;>;>;>>;>>;>;>>>;>;>>;>>>;>>;>>;>>;>;>>;>>>;>>;>>;>>>;>>;>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>,>>>>>,>>>>>>>>>,>>>>>>,>>>>>,>>>>>>>>>>>>,>>>,>,>>,>>,>,>>,,>>>,,>>,,>>,>,>,>>,>,>,>>,>,>,>,>,,>,>>>,>,,>,,>,>,,,>,>>,,>,,,>,>,,,>,,,,>,,>,,>,>,>,,,>,,>,,,,,,,,,,,,>,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,,,',',,,,,,,,,,',',',,,,,>-*&%%%%$$$%$%$$$$$#$##@@+......%->>,>>,,,',,,,,,,,,*%#.....+#%@.....&,,',',,,,,,',,,,>;;=&+..++@##$$$%%&-,,''',',''''''',',',''',','''''''''','''',''''''','''''''''''''''''''''''''''", +">;>;;>;>>;>>;>;>;>;>>;>>>;>;>;>;>;;>>;>;;>>;>;>;>>;>;>;>;;;>;>>>;>>;>>;>;>;>;>;>;>>;>;;>>>;>>;;>>;>>;>>>;>>>;>>>;>>>;>>>>>>>>;>>>>;>>;>;>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>>>>>,>>>>,>,>>>,>,>,>,>,>>>>,>>>>,>>>,>>>,>>>>,>>>,>>>>,>,>>,>,>,>,>,,>,>,>,>,>>,>,,,>,>,>,>,>,>,>,,,>,>,>,>,,>,>,,>,>,,,,,>,,,,,,,>,,,,,>,>,>,>,,>,,,,,,,,,,>,,>,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,,,,,,,,,,,,,,',',',,,,,,,,,,,>;=&&%%$$$$$$$$%$$$$###@+++.....%->>>>,>,,,,,,,,,,,,*&%+....+$%#....+*',,,,,',',,,,,,>>;-=&+..++@#$$$$$&*>,'',''''',',','''''','''''',','',''''''''''',''''''''''''''''''''''''''''''''", +">;>>;>;;>>;>;>;>;>>;>;;;>>;>>;>;>>;;>;>>;;>>;>>;;>;>;>;>>>;>>;;>;>;>;>;>;>;>>;>>;>;>>>>;;>>;>>>;>>;>>;;>>;>>>;>>>;>>>>;>;>>;>>>>;>>>>>>>>>;>>>>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>,>>,>>>,>>>>>,>>>>>>>>>>>,>,>>,>,>>,>>>,>,>,>,>,>,>>,,>,>>,,>,>,>>>,>>,>,>,>,>,,>,>,>,>,>,,>,,>,>,,>,,>,,,>,,>,,,>,,,,>,>>,,,>,>,>,,,>,>,,,,,,,,,,,,,>,,,,>,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,',,,,,,,,,',,,',,',,,,,,,,',',,',,,,,>=*%%%$%$%$$$$$$$$#$##@@+......$->>,>>>,,,,,,,,,,,,=&&#....@$&&@...@-,,,,,,,,,,,,,,,>>;-=%...++@##$$$$&-,,,'',','''''''''','''',''''''''''',''',''''''''''''',''''''''''''''''''''''''", +";>;;>>>;;>;>>;>;>;;>;>>>;>;>;>;>;;>>>;>;>>;>;>;>>;>;>;>;>;>;;>>;>;>;>;>>>;>;>>;>;>>;;>;>>;>>>;>>;>>;>>>;>>>;>>>;>>;>;>>>>>>>>>;>>;>>>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>,>>>>>>>>>>>>>>>>>,>,>,>,>,>>,>>,>>>,>>,>,>>>,>,>,>>,>,>>,>,>>,>>,>,>,>,,>,>,>,>,>>,>,>,,,>,>,>,>,,>,>,>,,>>,>,>,,>,,>,>,,,,>,>,,,,,,,>,,,,,>,>,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',',,,,',,,',,,',,,',,,,,',,,,,,,>;*&%%$$%$$%$$$$$#$###@++......#=;>>,>,>,,,,,,,,,,,>&&&#++@##%*%#++&>,,,',,,,,',,,,>>;;-*$....+@#$$$$$*;,'','''',','',','''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>;;>>;>;;>;>;>>;>;>;>;>;>;>;>>>;;>;>;>;;>;>;>;>>;>;>;>;>>;;>;>;>;>;>;>;>>;>;>>;>>;>;>>>;;>>;>>;>>;>>>;>>>;>>;>>>>>;>>>;>>;>>>>>>;>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>>>>,>,>>,>,>>,>,>,>>>>>>>>>>>>>,>>,>>,>>,>>,,>>>,>>,>>,>,>,>,>,>,>,>,>,>>,>,>,>,>,,>,>,,>>,>,>,>,>,>,,>,,>,,,,,>,>,,>,,,>,>,,,,>,>,>,>,,,>,>,,,,,>,,,,,,>,,,,,,>,,>,,>,,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,>;-*%%%$%%$%$%$$$$#$##@++......+*;>>,>>,,,,,,,,,,,>,-**&%$$$@#&&&%&=,,,,,,,,,,,,,,>>>;;=&@...++@@#$$$$*>,'',''''''','''''''''',''''','',''''','''''''''','''''''''''''''''''''''''''''", +">;;;>;>;>;>>;>>;>;>;>;>;>;>;>;>;;;>>;>;>;>>;>;>;>;;>>;>;>;>;>>;>;>;>;>;>;>;;>>;>;>;>>;>;;>>>;>>;>>;>>;>>>;>>>;>>>;>;>>>;>>>>>>>>;>>>;>>>>>>>>>>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>>>>,>,>,>,>,>,>>,>>,>>,>>>>>>,>,>>,>,>>,>>>,>,>,>>>,>,>,,>,>,>,>,>>,>,>>,,,>,,>,,>,,>,>,>,,>>,>,,,>,,,>,,,,>,>,,,,,,,,,>,,,,,,>,,,,>,>,,,,>,>,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,,',,,,',,',,',,,,',,,',',,,,,,,,>-=&&$%$$%%$$%$$#$###@++......+%->>>,>>,>,,,,,,,,,>;=&&&%&#+#%&&*=>>>,,,,,,,,,,,>>>;;-=$.....+@##$$$$*>,',',',',''''',','',''''','''''''','''''''',''''''''''''''''''''''''''''''''''", +">>>;>>;>;>;>;>;>;>>;>;>;>;>>>;>>>;;>;>;>;>>;>;>;>>;>;>;>>;>;>;>>;>;>>;>;>>>>;>;>>>;>;>>>>;>>>;>>;>>;>>;>>>;>>>;>>>>>>;>>>>;>>;>>>>>>>>>>>;>;>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>,>>>>>>>>>,>>,>>>>>>>,>,>,>>>>>>>>>>>,>>>,>>,>>,>,,>>,>>,>>>,>>>,,>,>>>,,,>>>,>>,>,>,>,>,,>,>,,,>>,>,>,>,>,>,,,>,>,,>,,>>,,>,,>,>,,>,,>,>,>,>,,,>,>,>,,,>,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,',,,,,',,,,,,,,,,',,,,',,,,',,,,,,,,>-*&%%%%%%$$$$$$$###@++.......#=>>>,>>,>,>,>,>,>,>>;=*&*&#.+%*=-;>>>>>,,,,>,>>>>>>;;=&+.....++##$$$#&>,,',',,'',''''''''''',''''''''',''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;;>;>;>;>;>;>;;>;>;>;>;;;>;>;>>;>;>;>;;>;>>;>;>;>;>;;>;>;>;>>;>;;>;>;;;>>;>;>;>;>>;;>>;;>>;>>;>>;>>;>;>>;>>>;>;>>>>>;>>;>>>>;>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>>,>>>>>>>>>,>,>,>,>,>>,>>,>>>,>>>,>,>>,>,>,>,>,>>,>,,>>>>,,>,>,>,>,>,>,>>,>,>>,,,>,>,>,,>,,>>,,>,>,,>,,,>,,>,,>,>,,>,,,,,,,,,>,,,,,,,,,,,,,>,,,,,,,>,,>,,,,,,,,,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,',,,,,,,,,,,,',',,',,,,,',,',',,,,,>,>,,>>-=&&%%%%%$$%$#$$#@@+........+&->,>,>>,>,,,,,>,>>>;-=*&&#@#$&*-;;>>>>>>>>>>,>>>>>;-&@......+@@##$$$%;,,,,,',,',',''','',''','','','''''',''',''''''''',''''''''''''''''''''''''''''", +";>;>>;>>;>>;>;>;>>;>>;>>;>>>;>;>;>;>>;>;>>;>>;>;>;>;>;>>;>;>;>;;>;>>;>;>>>;>;>>;>;>>;>>>;>>>;>>;>>;>>>>>>>;>>>;>>>>;>>;>>>>>>>;>>>;>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>,>>>>>>>,>>,>>>,>>>,>,>,>,>>>>>>>>>>,>>,>>,>>,>,>>,>,>,>>,>>,>,>,>>>,,>,>>,>,>,>,>,>,>,,>,>,,>>>,>,,>,>,>,,,,>,,,>,>,>,,,>,,>,,,,>,,>,>,>,>,,,>,>,>,,>,,>,,,,>,,>,,,,,,,,,,>,,>,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,',,',,,,,,,,,',,,,,,,,,,',,,,,>,,>>;-*&&%&&%$$$$$$#$#@+.........%=>>>,,>>>>>>>,>>>;==*&*&***&****==;;>>,>,>,>>,>>>;=&#........+##$$$$%->,,>,>,,,''',''''''''''''''''''''''''''''''''','''''''''''''''''''''''''''''''", +">;>;>;>;>;;>;>>;>;>;>;>;>;>;>;>;>;>;;>>;>;>;;>;>;>;>;>;>>;>;>;>>>;>;>;>;>;>>;>;>>;>;>;>;>>;>>;>>;>>;;>;>;>>>;>>;>;>>>>>>>>;>;>>>>>>>>>>>>;>>>;>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>,>>>>>>>>,>>>>>>,>>>>>>>>>>>>>,>,>,>,>,>>,>>,>>,>>>>,>>,>>>,>>,>>,>,>,>,>>,>,>>,>,>,>,>,>,>>,>,>,,,,>,>,,>,>,>>,>,,>,>,,,>,>,,>,,>,>,,>,,,,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,,,,,,',,',',,,',',',',',,,,,>,>,,,,>>-*&&&&%$%$$$$##@@++........@&;;>>,>,>,>,>>>-**&&*==;;>>,>>>;-=*=-;>,>,>,,>>>-=&#........++@##$$$$*;;>;;>>>,,,,''',',','',''''','',''',''''',''''''''''''''''''''''''''''''''''''", +">;>;>;>;>>;>;>;>;>;>;>;>;>;>>;>;>;>>;>;>;>;>;>;>;>>>;>;;>;>;>;>;;>>;>;>;>>;>>;>;>>>;>>>;>>;>>;>>>;>>>>>>>;>>>;>>>;>>;>>;>>>>>>>;>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>,>>>>>>,>>,>,>,>,>>>>>>>>>>,>>>,>>,>>,>,>>,>>,,>>,>>,>,>>,>,>,>,>,,>,>,>,>,>,>,,>,>,,>>,>,,>>,>,>,,,>,>,>,,>>,,,>,,,>,,,>,,,>,>,>,>,,,>,>,>,,>,,>,,,,>,>,,,>,,>,,,,,,>,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,',,,,,',,,,,,,,,,,,,,,,,,,,,',,,,,>>,,,,,>>-**&&%$$$$$$$##++..........$=;>>>>,>>>>>;=&&&*--;>>>,,'''''''>-*=->>,>>>>;=*$+..........+@##$$$$&=------;>>',','''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>;>;>;>;>;>;>;>;>;>;>;>;;>;>>;>;>;>;>>;>>;>;>;;>>;>>;>;>;>;>>;;>;>>;>;>;>>;>;;>>;;>>;>;>>;>;>>;>>;>;>>>;>>>;>>>>>;>>>>;>;>>>>>>;>>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>,>>>,>>,>>>>>>>>>>>>>,>,>,>,>,>>,>>,>>,>>>,>,>,>>>,>,>,>>>,>>,>,>,>,>>,>,>,>,>,>,>>,>,>>,,>,>,,>,,>,,>,,>,,,>,,,>,,>,>,,,>,,>,>,,,,,,,,>,,,,,,>,,,,,,>,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',',,,',',,',',',',,',,,,>>>>,,,,>;-**&%%%$$$$###++..........+%=;>>>>>>>;;=%%&**=--;;>>,,''''''''>==-;>>;-*&%#............+@@$#$$$%&*****==-;>,,','','','''','''''','''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;>;>;>;>;>;>;>>;>>;>;>>;>>;>;>;>;>;;>;>;>>;>>;;>;>;>>;>;>;;>>;>>;>;>;>>;>;>>;>;>>;>>>>;>>>;>>>;>>>>;>>>;>>>;>;>>>>>;>>>>;>>>;>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>>>>>>>>>>>>,>>>,>>,>>,>,>,>>>>>>>>>>,>>,>>,>>,>>>,>>,>,>>,>>,>,>,,>,>>>,>>,>,>,>,>,>,>,,>,>,,>,>,,>,>,>,>,>,>,,>>,,>>,,>,,,>,>,,>,,,,>,>,>,,,,>,>,,,,,>,,,,,,>,,,,,,,,,,>,,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,',,,,,,,,',',,,,,',,,,,,,,,,,,,',,,,,>>>>>>,,,,>;==*%%$$$$$$#@++...........#&-;>>>>>>;*&$$%&&**=-;;>>,,'''''''''=*=-==&$@+.............+@@#$$$$$&&&&&&**=-;,,'','''''',''''','''''',''''''','''','''''''''''''''''''''''''''''", +">;;>;>;>;>>>;>;>>;>;>;;>>;>;>;;>;>;>;>;>>;>;>;;>;;>>>;>;>;>>;>>;>;>;;>;>>;>;>>>;>>;>>;>>;;>>;>;>>;>>;>;>>;>>>;>>>>>>;>;>>>>>>>;>>>>>>;>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>,>>,>>>,>,>>>>>>>>>>,>>>>>>>>,>,>,>,>>,>>,>>>>,>,>>,>,>>,>>,>>,>,>>,>,,>,>,>,>,>,>,>,>,>>,>,,>,>,>>,,>,>,,>,,,>,,,>,,,>,,,>,,,,>,,>,>,,,,,,>,>,,,,>,>,,,>,,>,,,,,>,,,>,,,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,',,,,,,,,,',,,,,,,',',',',,,,',,,>>;;>>>>>>>;-=*&%%$$$$##@@.............#&-;;>;>;-&%%%%%%%&**=-;;>>,''''''''>***=**$+...............+@##$$$$%%%&&&&&*=-;>,,'',','''''''''''',''''','''''''''''''''''''''''''''''''''''''''", +">>;>;>;>>;;>;>>;>;>;>>;;>;>;>>;>;>;>>>;;>;>;>>;>>>;;>;>;>;;>>;>;>;>>;>>;>>;>;;>>;>;>>>;>>>;>>>>;>>;>>>>;>>;>>>;>>;>>>>>>>;>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>>,>>>,>,>,>,>>>>>>>,>>>,>>,>,>>>,>,>>,>>,>,>,>,>>,>,>>,>>,>>,>,>,>,>,>,,>,>,>,,>,,,>,>,,>,,>>,,>>,,>>,,>>,,>,>,,>,,,>,>,>,,,,,>,,,,,,,,,,,,,,>,,,,,>,,,,,,>,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,',,,,',,,',,',,,,,,,,,',,,,,,,,>;;;>>,>>>>;-*%%%$$$$##@++............+$*=-;;;;-&&&%%%%&%&&**--;;>>,'''''',*=---==%#.............++@##$$$$$%%%%%%%&&=->,,'',''',''',''',''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;;>>;>;;>;>;>;>>;>;>;>;>;>;>;;>>>;>>;>;>;;;>>;>;>;>>;;>>;>;>;>;>>;>;>>;>;>>;>;>>;>;>>;;>>;>>;>;>>>>>;>;>>>>>>>;>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>,>,>>,>,>>>,>>>,>,>>>,>,>,>>>,>>,>,>,>>,>,,>,>>,>,>,>,>,>>,>,>,>,>,>>,>,>>,>,,,>,,,>,,,>,,,,>,,,>,,,>,,,,,,,>,>,,,>,,>,>,,>,>,,,>,,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,',,,,,,,,,,,',,,,,,,,,,',,',',',,',',,,,>;;-;;>;>;;;;-*&%$$$$$##++............+$&=-=----=&&&&%%%%%%%&&&=-;;>>,,''''-*-;>>>;-*$+............++###$$$$$%$%%%%&&*=;>,,'''''',''','''''''''''''''',''''''''''''''''''''''''''''''''''", +";>>;>;>>;;>;>>;>;>;>;>;>;>>;>;>;>;>>;;;>;;>;>;>>>;;>;>;>;>;>;;>;>;>;>;;>;>>;>>>;>;>>;>>;>>;>>>;>>>>>>>;>;>>>>>>;>>;>>>>>>>;>>;>>>>>>>;>>;>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>,>>>,>,>>>>>>,>>,>,>,>,>>>>>>>>,>>>,>,>>,>>,>>,,>>>,>>,,>>,>,>,>>,>,>>>,>,>,>,>,>,>,,>,>,,>,>,,>,,>,,,,>,>,,>>,,>>,,>,>,,>,,,>,>,,>,>,>,,,,>,,,>,,,,,,,,,,,,,,>,,,,,,,>,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',',,,,,',,',,',,,,,,,,,,,,,,,,,,,,>>;---;;;;;;;-*&%%$$$##@++............%=;;;--===*&%**%%&%&&%&&&&*=-;;>>,,,;&=>,,,',,>-&+...........++@##$$$$$$$%%%%&&&*-;,,,',',''''''''''',''','''''''''''''''''''''''''''''''''''''''''", +">;;>>;>;>>>;>;>;>;>;>;>>;>;>;>;>>;>;>>>;>>;>;>;>;>>;>;>>;>>;>>;>;>;>;>>>>;>;>;;>>>;>>;>>;>>;>;>>;>;>;>>>>;>;>;>>;>>;>>;>;>>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>>>,>>>>>>>>,>,>,>,>>,>,>>>,>>,>>,>>>,,>>,>>>,>>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>>,>,>,>,,,>,,,>,,,,>,,>,>,,,>,,,,,,,,>,,,>,,,,,>,>,,>,,>,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',',',',',',,',,,,>;-===------;=*%$%%$$##@+............%-,,,,>;---=*&%**%%%%%&%%&%&*=-;;;>>;**;,,'''''',>&@...........+@@#$$$%$%$$$%%%%&*=->,',''',','','',''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>;>;;>;>;>;>;>;>;;>;>;>;>;>;>;>;;>;>;>>;>;>;;>;>>;>;;>;>;>>;>>>;>;;>>>;>>>;;>>;>>;>>;>>>;>>>>;>>>;>>>>>>>>>>>>>>>>>>>>;>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>,>,>>,>>>>>>>,>>>>>>>>>>>>,>,>,>>>>>>>>>,>>>>,>>,>>,>>,>,>>>,>,>,>>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,,>,,>>,,>>,,>>,,,>,,,,>,,>,>,>,>,,,>,,,>,,>,,,,,,,,,,,,,,,,>,,,,>,,,,,,>,,,>,,>,,,,,,>,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,',,,,,,,,,,',',,',,',,,,,,,,,,,,',,,,,,>>>-=======---=*%%%%$$##@+...........$;'''',,,>;;-=*%&*&&%&%&%&&&%&&*=-;;-**->''''''''''>*@..........++@##$$%$%$%$%%%&&&*=;>,',,,'',''''''''''''''','''','''''''''''''''''''''''''''''''''", +";;>;>;>;>>;>;>;>>;>>;>>;>;>>>;>;>;>;>>;>;>;;>;>;>>;>;;>;>>;>;>;;>;;>>;>>;;>>;>;>>;>>;>>>;>>;>>;;>>>>;>>>;>;>;>>;>>>;>>;>;>>>;>>>>>>;>>>>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>,>,>>,>>>>>>>,>,>,>,>>,>,>>,>>,>>>>,>>,>,>>>,>,>>,>,>,,>>>,>,>,>,>,>,>,>>,>,>,,>,>,>,>,>,,>,>>,,>,,,>,,,>,,,,>,,>,>,,>,,,,,,,,,>,,,>,,,,,,,,,>,>,>,>,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,',,,,,,,,',,,,,',,',',',',,,,,,,,,>>;-=***====-=*&%&%$$##@++..........#;''''''',,,>>;-*%&*&%%&%&%%&&&&&*=--*&=>'''''''''''',*@..........++###$%%%$$$%%%%&&*=;>,,',,,,'',''''',''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>>;>;>;>;>;>;>;>;;>;>;>;>;>>;>;>>;>;>>;>;>>;>;>;>;>>>;>>;>;>;>>>;>;>;>>>;>>;>>;>>;>>>>;>;>>;>>;>>>>;>>>;>>>>>>>;>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>,>,>>>>>>>>,>>>,>>>,>>,>,>>,>>,>,,>>>,>,>>,>>,>,>,>>>,>,>,>,>,,>,>,>,>,,>,,>,,>>,>,,,>,>,>,,>>,,>,>,>,,,>,,>,,>,>,>,>,,,>,,,>,>,,>,,,,,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,,,,,,,,,,,,',',,,,,,',,,,,,,,,,,,,',',,,,>,>>;-***&****=*&%%&%%$#@@+..........@-'''''''''',,,>;-*&&*&%%%&&%&%&&&&*=*&=>,''''''''''''''*@.........++@##$%%&%%$%%%&&&**-;>,,,,,',''',''''''',''''''''''''''''''''''''''''''''''''''''''", +";>>;>>;>;>;>>;>;>;>;>;>;>;>>;>;>;>;>;;>;>;>>;>;;>>;>;>;>;>>;;>;>;;>>>;>>;;>;>>>;;>>>;>;>>;>>;>>;>>>>>>;>>>;>>>>;>>>;>;>>>>>>>>;>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>>>>>,>>>,>>,>>,>>,>>>>>>>,>,>,>>>,>,>>,>>>,>>,>,>>,>>>>,,>>,>,>>,>,>,>>,,,>,>,>,>,>>,>,>,>,>,>,>,>,,,>,,>,,>,>,>,,,>,,,,>,,>,,>,,>,,,,,,,,,>,,>,,,,,,,,,,>,,,>,,,,,,,,,>,,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,',,',,,',,',',',',',,,,,,,,,>>;;-**&&&&****%%&&%$##@++.........+=''''''''''''',,,>-*&**&&%&%&%&%&%&&&&*;,''''''''''''''',*+.........++@##%&&%%%%%%%&&*==;>>,,,,,',''','''''''''',''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;;>;>;>;>;>;>;>;>;>>;>;>;>>;>;>;;>;>>;;>;>;>;>;>;>;>;>>>;;>>;>>;>>;;>>>;;>>>;>>;>>;>>>>;>;>>>;>>>;>>>>>>>>>>>;>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>,>>>,>,>,>>>>>>,>>>>>,>>,>>,>>,>>,>,>,,>>>,>,>,,>,>,>,>,>>>,>,>,>,,,>,>,>,,>,>,,>,>>>,,>,,>,,,>,,>>,,>>,,,>,,>,,>,,>,>,>,>,,,,,,>,,>,,>,,,,,>,,,>,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,>>>>;--*&&&&&&&&%%&&&%$#@++.........+&'''''''''''''''',,>-*&&*&%&%&%&&%&%&%*->,'''''''''''''''',&+........+++##%&&&&%%%&&&***=;;>>>,,,',''''''','''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>>;>;>;>;>;>;>;>;>;;>>>;>;>;>>;>>>;>;>>;>;>>;>;>>;>;>;>;>>;;>;>>;>>;>;>>>>;>>;>>;>;>;>;>>>>;>>>;>>>;>>;>;>>;>>>;>>>>>>>;>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>,>>>>>>,>>,>>>>,>>,>>>>>,>>>>>>,>>,>,>>,>,>>,>>,>>,>,>,>>,>>>,>,>>,>>>,>>>,>,>>,,>,>,>,>>,>,>,>,>,,>,>,,,,,>>,>,,>>,,>,,,>,,,,>,,>,,,,>,,,,,,,,,>,>,>,,,,,,,,>,>,,,,,,,,,,,,,,>,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,',,,,,,,,,,,',,',,',',,',,,',',',',,,,,,,,,>>;>--=&&&&&&&%%&&*&%$@@+..........%,'''''''''''''''',,,>-*&**&&%&%&%&%%%&->'''''''''''''''''''>%..........+@#$&***&%%&&&**=--;;>>>,,,','',''''''''''','''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;>>;>>;>>;>>>;>;>>>;;>;>;>;>;>;;>;>;>;>>;;>;>;;>;>;>;>;>>>>;>;>;>;>>;>;>>;>>;>>>>>>>>>;>;>>>;>>>;>>>>>>>>>>>;>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>,>>>>>>,>>,>>>,>,>>>,>>>>,>>>,>>,>>>,>>>>>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>>>,>,,,>,>,,>,>,>,>,>,,>,,,>,>,,>,>,>,>,,,,,,,>,>,,>,,,,,,>,,,>,,>,,,>,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,,,',,,,,,,,,,,,,,,,',,,,,,,,,,',,,,>>>>;;--*&&%%%%%%&&*&*%#@++.........#;'''''''''''''''''',,,>;*&&**%&%&%%&%&-;,'''''''''''''''''''';#.........++@$&*===*%&***==-;;;>>>,,,',''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>>;>;>;>;>;>;>;>;>;>;;;>>;>;>;>;>;>>;>;>;>;>>;>>;>>;>;>;>>;>;;>>;>>;>>;>>;>;>>;>>;;>;>;>;>>>>>;>>>;>>>>;>>>;>;>>>>>>;>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>,>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>,>>>>,>>>,>>,>>,>,>>,>,>>>,,>,>,>>,>>,>>>,>,>,>,>,>>,>>,>,>,>,>,>,>,>>,,>,,>,>,,,>,,>,>,,,>,,>,,>,,,>,>,>,>,,,>,,,,,,,>,>,>,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,',',,',,',,,,',',',,,,,,,>,>>>>;-==&&&&%%%&&***&$#++.........@='''''''''''''''''',,'',>;*&***&%%&%%&=;,''''''''''''''''''''''*+..........+#%*==-=*&&*==--;;>>>>>,,,,',''''',''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>>;;>>;>;>;>;>;>;>;>;>>>;;>;>;>;>;>;;>;>;>;>;;>>;>;>;>>;>;>;>>>;>;>;>>;>>;>>>;>>;>>>>>;>>>>;>;>>;>;>>>>;>>;>>>>>;>>>;>>>>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>,>>>>>,>>,>>>>,>,>>>,>>>>,>>>,>>,>>>>,>>>,>,>>,>,>>,>>,>>,,>,>,>>,>,>,>,,>,>,>,>,>,>,>,,>,>,>,>,>,>,>,>,,,>>,,>,,>,,>,,,,,,>,,>,,,>,>,>,,,,,,,>,,>,>,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,',,',,,,,,,',,,,,,,,,,',,,',,,,,,,',,,,,,>,>>;;;-=*&&%%%%&&****&#@+.........+&>''''''''''''''''''',,',,>-*&***&&%%&=;>,'''''''''''''''''''''',&.........++@$*=--;-*&=--;;;;>>>,>,,,,''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;;>>;;>;>;>>;>;>;>>;>;>;>>;>;>>>;>;>>;>;>>;>>;;>;>;>;>;>;>>>;;>;>>>;>;>;>>>;>>;>;>;>;>>;>;>>>>;>>>>>;>>>>>>>;>>>>;>>>>>>;>>>>>>;>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>,>>>>>>>,>>>>>>,>>>,>>>,>>>,>>,>,>>>,>>>>>,>>>,>,>,>,>>>,>>,>,>,>>,>>>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,,>>,,,>,>,>,>,,>,>,>,,,,>,>,,,,,,,>,>,>,,,,,,,>,,>,,,,,>,,>,,,,,,>,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,',,,,,',,,',,,,,,,,',',',,,,,,,,,>>>>;;-==*&&&%%%***=**%@++.........#-''''''''''''''''''',,,''',>;*&***&&&*;>'''''''''''''''''''''''''-#..........+#&*=--;;*&*-;;;>>>>>>,,,,,','''''',''',''''''''''''''''''''''''''''''''''''''", +";>;>;>>;>>;>;>;;>;>;>;;>;>;>;>;>>;;;>>;>;>;>>;>;>;>>;>;>>;>;>;;>;>>>;>;>>;>>;>;>;>>>>>>;>;>>>>>;>;>>>;>;>>;>>;>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>>,>,>>>>>,>>,>>>,>>>,>>>,>>,>>>,>,>>,>,>,>,>,>>>>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,>,,,>>,,,>,,,>,,>,,,>,>,,,,>,>,>,,,,,,,,>,>,,,,,,,,,>,,,,,,,,>,,,,,,,,,,>,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,',,,',,',',,,,,,',,',,,>,,>>>;;-=**&&%%&****=*&#+..........+*,''''''''''''''''''',,,'''',>;*&&*&&*;>>''''''''''''''''''''''''''&+.........+@$*=---;;=*=;;>>>>,>,,,,,''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;;>;>>;>;>>;>;>;>>;>>;>;>;>;>>;>;>;>;>;;>;>;>;;>;>;;>;>>>;>>;;>>;>;>;>;>;>>>;;>;;>>>>>;>;>>>>>;>>>>>>>>>>>;>>>>;>>;>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>,>>>>,>>>>>,>>>,>>>>>>>,>>>,>>>,>>>,>>>,>>>>>,>,>>>,>>,>>>>,>>,,>,>>,>>>,>,>>>,,>,>,>,>,>,>,>,>,>,>,,>,>,,>,,>,>,,,>>,,,>>,,>,>,>,,,>,,>,>,>,,,,,,>,>,>,>,,,,,>,,>,,>,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,',,,',,,,,,,,,',,,,,,,,',',,,,,,,,,>,>>>;;-=**&&%%&&***=**%@+..........%>'''''''''''''''''''',>,,'''',,>-*&*=;;>''''''''''''''''''''''''''';$..........+@%&==-;;;=&*->>,>,>>>,,,,'',''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;>;;>;>>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>>;>;>;>>;>;>>;>>;;>>;>>>;>;>;>>;>>>;>>>>>>>;>;>>;>>>;>;>>;>;>>;>;>>>>>;>>>>>>>>>>;>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>,>>,>>>>>>>>,>>>,>>>,>>>,>,>>>>,>>,>>>,,>,>,>>>,>,>,>,>,>>,,>>,>,>,>,>,>,>,>,>,>,>>,>,>,>,>,>,,>>,,,>,,,>,>,,,,>,>,,>,,,>,,>,>,,,,,,,,,,>,,>,,,,,,,,,>,,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,,,,,,',,',',,,,,',,',,,,,',',,,,,,,,>,>;--=*&&%%&***=*=&$@+..........@=,'''''''''''''''''''',,,,''''',,>>;;>>>,''''''''''''''''''''''''''''*+..........+@$&==--;;-&&->>>,>,>,,,,'''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>>;>;;>;>;>;>;>;;>>;>;>;>;;>;>;>>;>;>;>>;>;>>;>;>;;>;>;>;>;>;>>>;>>;>;>;>;>;;>>;>;>>>;>>>>>>>;>>>>>>;>>;>>>;>>>;>>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>,>,>>>,>>>,>>>,>>>>,>,>,>>,>,>>>>>>>,,>>,>>,>,>>,,>>,>>,>>>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,>,>,>,>,,>,>,>,,,,>,,,>,,>,,,,>,>,>,>,>,,,,,,,>,>,>,,,,,,,,,>,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,',',,,,,,',,,,>,>>;;-=**&%&*******&#+...........+%>'''''''''''''''''''',,>>,'''''''',,>>>>'''''''''''''''''''''''''''''>%...........++@&*=--;;-*%->>,>,,,,,',''',''',''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>>>;>>;>>;>;>>>;>;>;>;>>;>;>;>;>;>>;;>;>;>;>;>;>>>;>;>>;>>;>;>;>>;>>>;>>;>>;>>>>;>>>;>;>;>>>>;>>;>>>>>>;>>>;>>>;>>>>>>>;>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>,>>>,>>>>>,>>,>>>>>>>>>,>>>,>>>,>>,>,>>>,>>,>>>>,,>,,>,>>,>>,>>,>,>>>,>,,>,>,>,>,>,>,>,>,>,,,>,>,,>,,>,,>,,,>,>,,>,,>,,>,>,>,,>,>,,,,>,>,,,,,,,,,,>,>,,>,,,,,,,>,>,,,,,,,>,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,',,',,,,',,',,',,',,,,',,,,,',',,,,,',,,,,>;;-=*&%&*=**=**&@++...........@=,''''''''''''''''''''>-==;,''''''',,,>>,''''''''''''''''''''''''''''''=@...........+++%*=--;;;*&=>,,,>,,,''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;;;>;>;>;>;>;;;;>>;>>;>;>;>;>;>;>;;>>;>;>;>;>;>;>;>>;>;>>;>;>;>;>>>;>>;>>>>>;>;>>>;>>;>>>;>;>>>>>>;>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>,>>>>>,>>>>>>>>>>,>>>>>>>,>>,>>,>>>,>>>,>>>>>,>>,>>>>>,>,>>>,>>>>,>>,>,>,>,>,,>,>>>,>,>,>,>,>,>,>,>,>>,>,>,>,>,>,>,>>,,>,,>,>,,>,,,,>,,>,,,>,>,,,,,,>,>,>,>,,,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,',',,,,',',,,,,,,>>;-=*&%*===***&$@++............%>''''''''''''''''''''-&%%%&='''''''',>>,''''''''''''''''''''''''''''''';$............+.+#&*--;;>=*=>,,,,,'',''''''''',''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>>>;>;>;>;>;>>>>>;>;>;>;>>;>;>;>;>>;>>;>;>;>;>;>;>;>>;>;>;>>;>>;>;>>;>>;>;;>>;>>>;>>>>>;>>>>>;>>;>>>>>>;>>;>>>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>,>,>,>>>>>,>>>,>>>,>>>,>,>>,>>,>,,>>>,>,>>,,>,>,>>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,>,,,,>,,>,,,>,>,>,>,,>,,>,,,>,>,>,>,,,,,,,,>,,>,>,,>,,,,>,,,>,,,>,,,,,>,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,',,,,,,',,',,,,,',,,,,',,,,,,,',,,,,>>;-*&&*==****&$@++............@*,'''''''''''''''''''-&%%%&&&-''''''',,>,,,''''''''''''''''''''''''''''',*+............+.+@%*=-;;>;*->,,'',''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>>>;>;;>;>>;>;>;>;>;;;>;>;>>;>;>>;>>;>;>;;>>;>;>;>;>;>>;>;>>>;>;>>;>>;>;>>>;>>>>;>>>;>>>;>;>>>;>;>>>>>;>>>;>>>>>>>;>>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>,>>>>>>>>,>>>>>,>>>,>>>,>>>>,>>>,>>>>>,>>,>,>>>>>,>>,>>,>>,>,>,>,>>>,>,>,>,>,>,>,>,>>,>,,,>,,>,>,>>,>,,>,>>,>,,>,,,>,,,>,,>,,>,,,,,,,>,>,>,,,,,,,,,,,>,,,>,,,,,,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,',,,',,,,',,,',',,,',',,',,,,,,,>>;-&&=-=*=**%@+++++...........$;'''''''''''''''''''>&%%%=;,,'''''''',;-;,,''''''''''''''''''''''''''''''-#...........++...+$*==;;>>->,,,''','','''''''''''''''''''''''''''''''''''''''''''''''", +">;>;;;>;>>;>>;>;>;>;>;>>>;>;>;;>;>;;>;>;>>;>>;;>;>>;>>;>;;>>;>;;>>>;;>;>>>>>;;>>;>;>>;>>;>;>>>>;>>>>>>;>>>>>;>>>;>>>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>,>>>>>,>>>>>>>,>>>>>>,>,>>>,>>>,>>>,>>>,>>,>,>,>>,>>>,>,,>>,>,>,>,>,>>,>>,>,,>,>,>,>,>,>,>,>,,>,,>>,>,>,>,>,,>,>,>,,,,>,,>,>,,>,,,>,,,,,>,>,>,,,,,,,>,>,,>,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,,',,,,,,,,','',,,>>-&*---==*&%@+++@+++.........+&>''''''''''',,'',;,,;&%%*>>'''''''''';=*;,,''''''''''''''''''''''''''''''>%+........+++++....#&=--;>>>,,',''''''''','''''''''''''''''''''''''''''''''''''''''''", +";>;>>>;>;>;;>;>>;>>;>;>;;>;>;>>;>;>>;>;>;>;>;>>;>;>>;;>>>;>;>>>>;;>>>>>;;>;>>>;>;>>>;>;>>>>;>;>>>;>;>>>;>>;>>;>>>;>;>>>>>>;>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>>>>>>,>>>>,>>,>>>>>,>>>,>>>,>>>,>>,>>,>>>>,>>,>,>>>,>>,>>>,>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,,,>,>,,>,,>,,,>,,>,>,,>,,,>,,>>,,>>,>,,,,,,,>,>,>,,,,,,,,,,,,,>,,,>,,,>,,,,,,,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,',,',,',,,,,',,',,,,',',',',,,',',',,',,,',,,;**-;-==*&$@+++@@@@+++.......#=''''''''''',>>,',-->-&%&=>,'''''''''>=&*>,,'''''''''''''''''''''''''''''',*@........++++......@%*-;>,,>,,''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;;>;>;>>;>;;>;>;>>;>>;>;>;>;>>;;>;>;>;>;>;;>;>;;>>;;;>;>>;;;>>>;;>;>>>>;>;>>>>;>;>>>;>>>>>>;>>;>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>,>>>>>>>>>,>,>>>,>>>>>>>,>,>>>,>>>,>>>,>>,>>,>>,>,>>,>,>>,,>>,>>,,>,>>>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,>,>,,>,,>,,,>,,,>,,,,>,>,>,>,,,,,,>,,>,>,,>,>,,,,>,,,>,,,>,,,,,>,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,',,'',,',>-*;;;-=*%#+++.++###@++.......$;'''''''''',>;>>',-*--&%&=;,'''''''''-&%*;,>,'''''',,,,'''''''''''''''''''';$......++@@+++......+$*-;,,,,,,'''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;;>>;>>;>;>;>>;>;>;>;;>>;>;>>;;>>>;>;>;>;>;>>>;>>;>;>>>;>;>>>>;;>>;>;>;;>>;>>;>;>>>>;>>>;>;>>>;>>>>;>>;>;>>>;>;>>>>>>;>>>>;>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>,>>,>>>>>>,>>>,>>>,>>,>>,>>>,>>>>,>>>,>>,>,>,>>>>>,,,>,>>>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>>,,>,,,>,,,,>,,>,>,,,>,,>,>,,,>,,,,,,,,,,>,>,,,,,,,,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,,,,,,',',,',',,,,,,',,',,,',',',,,,',,',,,;=;>;-=*%@@+++.+@#$$#@++.....+&,'''''','''>;;>,,,;**=&&&*>>,,,,'''',*&&&>,>;,''',,,>,,''''''''''''''''''',>&+.....++@@@@+++......#*->,,,,,,'','''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>;>;>;>;>;>;>;>;>>;>;>>;;>>;;>;>;>;>;>;>;>;;>;>;>;>;>>;;>>>;>;>>;>>>;>>;>;>>;;>>>;>>>>>;>>>;>;>>>>>>>>;>>>>>;>>>>>>;>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>>>>>>>>>>,>>,>,>>>>>>>,>,>>>,>>>,>>>,>>,>>,>>,>,>,>,>,>>>,>>>,>,>,>>>,>>,,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,>>,,>>,>,>,>,,>,>,,,,,,>,>,,>,>,>,>,,,,,>,>,,>,>,,>,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,',,,,,,,,,,,',,',,,,,',,,,,,,,',','',',>;;;;;-*$@@++..++@$%%$#@++....@=,''''',,,,,>>>>,,,>=&*&&&*--=***;''',*&&=>,;--;>>>>,,,''',','''''''''''''''>*@....++@@@@@@++.......#*;>,,,,,,''''','''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;>;>;>;>;>;;>;>;;>>;;>>;>>>;>;>;>;;>>>;>;>;>;>;>>>;>;>>;>;>>;>>>;>>>;>>>;>>;>;>;>>>;>>>>>;>;>>;>>>>;>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>>,>>>>>>>>>>,>>,>>>>,>>>,>>>,>>>,>>,>,>>>,>>>>,>>,,>>,,>>,>,>,>,>,,>>>>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,>,,,,>,,,>,,,>,,>,,>,>,>,>,,,>,,,,,,,,,>,>,,,,,,,,,,,,,>,>,,>,,,>,,>,,,>,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,',,,,,,,,,,,,',,',,,,,,,',',,,',',',,,,',',',,;>>>;-*#@+++.+.+#%%%%$#@++....$;''',>>>>',;;-;;;;;>;*&&&&&**&&&&*,'',;**;'';**-;>,,,>>>,,,,,,,'''''''''''',,;#....++@##@#$$#++......#=;,,',,,'''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;>;>>;>;>>>;>;>>;>;>>;>;;;>;>;>;>>;;;>;>;>;>>>;;>;>>;>;>>;>>>;;>>;>>;>;>>;>>>>>>;>;>>;>>>>>>>>>>>;>>>>>;>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>,>>>,>>>>>>,>>>,>>>,>>>,>>>>>>>>,>>>,>,>>,>>>,>>>,>,>,>,>,>>>,,,>,>,>,>,>,>,>,>,>,,>,,>>,>,>,>,>,>,>,>,,>,,>,,>,,,,>,,,,>,,,>,>,>,>,,,,,>,,>,,>,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,',',,,,,,',,',,,,,',,,,,,,',,,',',''>>,>;-*$@+++++@#$%&&%%$##@+....&;,''=**=>,>********=;-=*&*&&*&**&*>''',>>,''>=**-;;;===;>>>>>>;;;;;>'''''''',;%+...+@@##@#%&&%#@+....+$=>,,',,,''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>;>>;>;;;>>;>;>;>;;>;>>>;>;>>;>;>>>>;>>;>;;>>;>>;;>>>;>>;;>>>>;>;>>>>;>>;>;>;>>>>;>>>;>>;>;>;>>>>>;>>>;>>>>>>>>;>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>,>>>>>>>>>>>>>,>>>,>>,>>>,>>>,>>>,>,>>,>,,>,>>,>,>>>,>>,,>>,>,>>>,>,>>,>,,>>>>>,>,>,>,>,>,>,>,>,,>>,,,>,>,,>,>,,,>,,>,>,,>,,>,>,,>,>,>,>,,,,,,,,>,>,,,>,,,,,,,,>,,,>,,,,,,,,,,,>,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,',,',,,,,,,,,',,',',',,,',,,',',,,,>>;*%@+++@#$%%&&&%%%%$@@+...+*,'',=**=,,;**&******->;=*********-''''>>-;,'>=***==**=;,>>>>-=******-;''''',,>&+...++#####%***&%##+...@%=>,,,>,,'''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>>;>;>>;>;>;>>>;;>;>;>;>>;>>;;>;>;>;>;>;;;>;>;>>>;>>;>;>>;;>;>>>>;>;>>>>;;>>>>>>>;>>;>;>>;>>>>>>>>>>;>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>,>>>,>>>>>,>>,>>>>>>>>>>,>>>,>>>,>>>>>,>>,>>>,>>,>>,>,>,>>>,>,>,>,>>>,>,>,>>,,,,>,>,>,>,>,>,>,>,>>,,,>>,>,,>,>,,>>,,>,>,,>,>,,,,>,,>,,,,,>,>,>,>,,,,,>,,,,,>,,>,,,,>,,,>,,,,,,>,,,,,>,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,,,,,,,,,,',',,',,,',,,,,,',,,,',','',,,>>=&#@+@#$%%&&=;-&&%$$#@+...#=>,',=**=,,;***->;***-,,;-*****--;,''''>==;''>-*******->>>>>-**********-,''''>>=@...+@#####&-;-=*&%%#+.+#&;,,',>,,''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;;>>;>;;>;>;>;>;>>;>;>>;>;>;>>;>>;>;>;>;>>>;>;>;;>;>;>;>>;>>>;>;>;>>>;>;>>;>;>;>;>>>>>>>>>>>;>;>>;>>>>>>>>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>>>,>>>,>>>,>,>>>,>>>,>>,>>>,>>>,>>,>>,>>,>>,,,>,>>,>,>>>>,>,>,>,>,>,>,>,>,,>>>,,,>,>,>,>,,,,>,,>,>,,,>,>,,>,,,>,>,,,,,,,,,>,>,,,>,>,,,,,,>,,,,,,,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,',,,,',,',,',',,,,,,,,',,,,',,',,,,',,',',,,,,,-*%##$$%&&*->,>;&%%%##@++..$;,'',-**-,,;=*=->>===-,'>;=**=,'''''''>-==,'',-=**=*==;,>;;;==*==---==*=;,,',,>-#...+@####$&-;>>;-*&%$#+@$*-,,,>>','''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;;>;>>;>;>;>;>;>;>>;;>;>;>;;>;>;>>;>;>;>;>;>;>>;>>;>>;>;>;>;>>;>>;>>;>>;>>>;>>>>;>;>;>;>;>>>>>>>>;>;>>;>>>;>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>,>>,>>>>>>,>>>>,>>>,>>>>>,>>>,>>>,>>,>>>,>>,>,>,>>,>>,>>>>,>,>,>,>,,>,>,>,>,>,>,>,>,,>,,,,>>,>,>,,,>,>>,>,,>,,>,,>,,>,,>,>,,>,>,>,>,>,,,,>,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,',',,',,,,',,',',,',,'',,',,>=*%%%%&&*;,,,,>;*&%%$#@++.+%;>'',-==-,>;===-;-===;,',;-===,'''''''>==-,''';====-->,,>;--===->,,,-===;,,,,,>;$+.++@####$&-;>,,,>;=&%$##%*;,,;;,''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;;>>>;>;>;>;>;>;>;>;;>>;>;>;>>;>;>;>>;>;>;>;>>;>;>;>>;>>;>>;>>;>>;>>;>>;>>>;>>>;>>>;>>>>>>>>;>>;>>>>>>;>>;>>>>>>>;>>>>;>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>,>>>,>>>,>>>>>>>>>>,>,>>>>,>>>,>>>>,>,>>>,>>,>,>>>,>,>,>,>>>,>,>>,>,>,,>>,>,>>,>>>,>,>,>,>,>,>,>,>,>,>>>,,>,,>,>,>,,,,>,>,,>,>,,>,,,>,,,>,,,,,,,,,,,>,,,>,,>,,,>,,>,,,,>,,,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,',,,,,,,,,,,',,,',,,,,,,,,,,',',,,,,,,',,',,',,',>;=**&&&=;,,,,,,>;&&%%$#@++.+&;,,',-==-,>;-===---=-,''>>-==-,'''''',;-=;''',;==-->,,''>---===>''',;-=-;>>,,>>>%+.++@##$#$&-;>>,,',>;*&&%%&=;>;;>,'''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>;>;;>>;>;>;>;>;>;>>;>;>>;>;>;>;>;>;>;>;>;>;;>;>;>>;>;>;>;>>;>>;>>;>>;>>;>;>>;>>;>>>;>;>;>;>>>>>;>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>,>,>>>>>>,>>>,>>>,>,>>>>>,>,>>,>>,>,>>>>>>,>,>>>,>>,>>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,,>>,>,,,>,>>,,,>,>,,,>,,>,,,>,,,>,>,>,>,>,,,>,,,,,,,,,,,,,,>,,,,,>,,>,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,,,,,',,,',,,',,',,',',,,,',',',,,',,',',,,,>;-*&**;,,,,',',,;*&%%%##++.@*;,,'>;--;'>;-------;>''',;----,''''',>;---,''';---;>,''',;=----,'',>--;;;;>,',>>&@.+@@$#$#%*-;>>,,,'''>-*&&&&*--->''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>;>;;>>;>;>;>;>>;>;>;>;>;>;>>;>;>;>;>;>;>;>>;>>;>;>>;>>;>;;>;>>;>>;>>>;>>>;>>>>>;>;>>>>>>>>>;>>>>>>>;>>>;>>;>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>>>>>>>>,>>>>,>>>,>>>>>,>,>>>>,>>>,>>>,>,,>,>,>,,>,>,>>,>,>,>>,,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,>>,>,,,>,>,,,>,>,,,>,>,,>,>,,,,,,,,,>,,,>,>,,>,,>,,>,,,,,>,,,,,,,,,,,,,,>,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,',,',,,',,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,>,>>--*=;>,,,',,,,,>>*&&%%#@@+.#*>>,,>---;',;---;>>,'''''>;----''''',>;---;''',;---;>>'''';----;>,,,>>;;;;;;,,,>>*@.++##$#$$*-;>>,,',''',>-**&&&&-,''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>>;>>;>;>;>;>>;>;>;>;>;>;>;;>;>;>;>;>>;>>;>;>;>;>;>;>;>>>>;>>;>>;>>;;>>;>>>;>;>>>>>>;>;>;>>>>>;>>;>>>>>>>>>>>;>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>>,>>,>>,>>>,>>>>,>>>>,>>>,>,>>>>,>,>>,>,>>,>>>>>,>>>>>>>,>>,>,>,>,>,>>>,>,>,>,>,>,>,>,>,>,,,>,>,>,>>,>,,,,,,>>,,>,>>,,,,>,>,,>,,>,,>,>,>,,>,,>,,,,,>,,,,,>,,,>,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,,,',,',,',,',',,',,,',',',,','',',,>>;;--;>,,',',',',,,>=&%&%$@@++#->>,,;;--;',>;-;>''''''''>;;;-;,''''>;;;;-;,''';-;-;;>,''',;-;-;;>>>;>;;;;;>'',>>=#.+@##$$$%*-;>>,,,'''''',>-=**=>,''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>;>;;>;>>>;>;;>;>;>;>>;>>;>>;>;>;>;>;>;>;>;>;>>>;>>>;>;>;>>;>>;>>;>>>;>;>;>>>>>;>;>;>>>>>>;>;>>>>>>;>;>>>;>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>,>>>,>,>>>,>>>>>>,>>>>,>>>>,>>>,>,>,>,,>,,>,>,>>>,>,>,>,>,>,>>>,>,>,>,>,>,>,>>,,>,>,>,,>,>,>>>,,,>,,,,,>>,>,,,>,,>,,>,,,,,,>,,,,,,,>,,,,,>,,,,,,,,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,',,,,,,,',,,',,,,,,,',,,,',,,>>;;;>,',',,,',',,,,>=&&%%$#@++$->>,>;-;;>''>;;;>''''''',>;;;;>'''',,;-;;;;''',;;;;;;>'''''>;;;;;;;;;;;;;;;,'',>>-#++@#$$#$%=;;>>,,,','''''',,>>>''''''''''''''''''''''''''''''''''''''''''''''''''", +">;;>;>;>>;>;>;>;>>;>;>;>;;>;;>;>;>>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>>;>>;>>;>>>>;>>;>;>>>>>>>;>;>>>>>>>;>>;>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>>>>>>,>>>>,>>,>>>,>>>>>>>>>,>>>,>,>,>>,>,>>,>,>>,>,>>,>>>>,>>>>,>>,,>,>>>,>,>,>>,,>,>,>,>,>,>,>,,,>,>,,,>,>,,>,,,,>,>,>>,>,,,,,>,,,>,,,,,>,>,,,,>,>,>,,,>,,>,,,>,,>,,>,,,,,,,,,,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,',,',,,,,',',,,,',',,,,',,,',',',,,',',,,',,,,,,',',,'',,,,',,,>-&&&%$#@++%;>>,,>;;;;'',;;>>''''''',;;;;;>''''',>;;;;;,'''>;;;;;,'''''',>;;;;;>;;;;;;>,'',>>-#++@##$$$&=-;>>,,''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>;>;>;>;>;>>;>;>;>;>>;>>;>;>;;>>;>>;>;>;>>;>;>>;>;>>;>;>>;>;>>;>>;>>;;>>>>>;>>;>;>;>>;>>>;>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>>>>>,>>,>>,>>>,>>>>>>>,>>>>,>>>>,>>>>,>>,,>>>,,>>,>>>,>,,>>,>,>,,>>,>,>,>,>,>,>,>>>,,>,>>,,>,>,>,>,>,,,,>,,>,>,>,,>,,,>,>,,,,>,>,,,,,,>,,,,,,,,,,,,,>,,,,,,,,>,,,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,,,',',,,,,,,,,,,,',',,,',,,,,,',',,,,',,,',,,',,,',,,'',',,,,,;*%&%$#@@@%;>>,',,,,''',,,,,''''''',>>;>>''''''',>;>>>''''>;>>>>'''''''',,>>>>;>>>;>>,''',>>;$++##$$$%&-;;>,,,,,',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>>;>;>;>;>;;>>;>>;>;>;>;>>;>>;;>>;>;>;>;;>;>;>;>>;>;>>;>;>>;>>;>;>;>>>;;>;>>;>>>;>>>>>>;>>>>>>;>;>>;>>>>;>>>;>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>>>>,>>,>>,>>>>>>,>>>,>>>,>,>,>>,>,>>,>,>>,>,>,>,>>,,>>>,>,>,>,>>,>,>>,>>,,>,>,>,>,>,>,>,,,,>,>,,>>,>,,,>,>,,>>,,>,,>,,,,>,,>,>,,>,>,,,,,>,>,>,,>,,>,,>,>,,>,,,,,>,>,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,',,,,,,,,',,',',,,,,,,,',,,',',,,,,',',',',,,',',',',',,,,',,',,>>*&&&%##@@&;>>,'''''''''''''',,,,,,,>>>>,'''''''',,>>,''''',>>,''''''''''',,>>>>>>>,,'''',>>;$+@##$$$%*-;;>>,,'''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>>;>;>;>>;>;>;>;>;>;>;;>;>>;;>;>>;>;>>>;>>;>>;>>;>;>>;>>;>;>>>>>>;>>>>>>>>;>>>;>;>;>>>;>;>>>>>;>>>>>>>;>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>,>>>,>>>>>>>,>>>,>>,>>,>>>,>>>,>>>,,>>,>,>>>,,>>,>,>>,>>,>,>,>,>,>,>,>,>>,>,>,,,>,>,>,,,>,,,>,,>,,>>,>,,>,,,>,,,,,>,>,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,',,,,,,,,,',',',,,,',,,,,',',,',,,,,',',,,,,',,','',,',,,,,>=&&&%$@@@&;>>''''''''''''','',,,,',,,,'''''''''''','''''''''''''''''''''''',',',''''''''>>>;$+@##$$%%*-;;>,,,,','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;;>;>;>;>;;>;>;>;>;>;>>;>;>;>>;>;>;>>;;>;>;>;>;>;>>;>;>;>>>>;;>;;>>;>;>;>;>>;>>>>>>>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>,>,>>,>>,>>>,>,>>>,>>>,>,>,>>,>>>,>>,>>,>>,>,>>,>>>>,>>>,,,>>,>,>,>,>,>,,>,>,>,>,>,>,>,,>,,>,>>,>,>,,>>,,>>,,>,>,,,,,,>,,>,,,>,>,,,,,>,>,>,,>,>,>,>,,>,,,>,,,,,,,,>,,,,>,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,',,',,,,,',,,,,',,',,',,,,,,',',,',,',,,',,,','',,,,','',,',',,,',',',,,>-*&&%$#@@&;>>,''''''''''''',,,,>,,,,'''''''''''''''''''''''''''''''''''''''''''''''''''',;>;%@@#$$%&&=;;>>>,,'','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>>;>>;>;>>>;>;>;>;>>;>;>;>;>;;>;>;>;;>>;>>;>>;>>;>;>;>>>;>;>>;>>>>;>>>>>>>>>>;>;>;>;>>;>>;>>;>>;>>>>>>>;>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>,>>>>>>>>>,>>>>>>,>>>>>,>>>,>>>>>>>>,>,>>>,>>,>>,>,>,>,>,,>>,,>>>>,>,>,>>,>,>,>>,>,>,>,>,>,,>,>,>,,>,,,,>,>,,,>,,>,>,,,>,>,>,,>,,>,>,,,,>,>,,,,,,>,,,,,,,,,,,>,,,,,,,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',',,,,,,,,,,,,,',,,,,,,',,',,,',',,,,,',',,,',',,,'',,',,',,,>;**&&%##@&;;>,''''''''''',,',,>>>>,,,'''''''''''''''''''''''''''''''''''''''''''''''''''>>;;$@##$$&%&-;;>>,,,,''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>;>;>;>;>;;;>;>>>;>;>;>;>>;>;>>;>;>;>>;;>;>;>;>;>>;>;>>;;>>>;>>>;>;>;>;>;>;>;>>>>>>>>>;>>>>>>>>>>>;>>>;>>>>>>>;>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>>>,>>>>>>,>,>>>>>>>,>>>>>>,>>>,>>>>,>,>,>>,>>,>>>,>>,>>>,>>,>>>,>,>>,,>,>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>>,>,>>,>,,>>,,>,,,>,>,,,>,,>,,>,,,>,>,,,,,>,>,,,,,>,,,>,,>,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,',,,,,,,,,,,,,,,',',,',,',',,',',',,,,,,',,,,,',',',,',',,,',',,,',,',',,,>>***&%$##&;>>>''''''''',,',,,,>>>>,,,,''''''''''''''''''''''''''''''''''''''''''''''''''>>>;%@##%%&&*-;;>>,,',,,'',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;>;>;>;>;>>>;>;;>>;>;>;>;;>>;>;>;>>;>;>>;>>>;>>;>;>>>;>>;>;>>>;>>;>>>;>>>>>>>;>;>;>;>>>>;>>;>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>,>>>,>>,>>>,>>>,>,>>>>>>,>>,>,>,>>,>>,,>>,>>,>>,>>>,>>,>>,>,>,>,,>,>,>,>,>,>,>,>,>,,>,,,>,>,>,,>,,,>,,>,>,,>,>,,>,,,>,,>,,,,,>,>,,,,>,>,,,>,,,,,,,>,,,,,,,,,,,,,>,,>,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,',,,,,,,,,,,,,,,,,,,,,',',,',',',,',,,,',,,'',,',,',',',',',,>>-&**%$##&;;>>'''''',',',,,,,,>>>;>>,,,','''''''''''',,,,,''''''''''''''''''''''''''''',>;;;%##$%&&&=;;>>>,,,''','',','''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>;>;>;>;>;>;>;>>;;>;>;>;>>;;>;>;>;>;>;>;>;;>>;>>;>>;;>;>>>>;>;>>;>>;>>>>;>;>;>>>>>>>>>;>>>;>>>>>;>>>>>>>>>;>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>>>>>,>>>,>>>>>,>,>,>>,>>>>>,>>>,>>>,>,>,>,>>,,>,>,>,>,>,>,>>>,>,>,>,>,>,>,>,,>,>,>>,>,,,>,,>,>,,>,>,>,>,,,>,,>,,,>,,>,>,,,,,>,,,,,,>,,,,>,,>,,,,>,,>,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,',,,,',,,,',,,',,',',',,',',',',',,,,',,,',,',,',',,'',,,',',',,,',,',,',,>;***&%##&;;>>,'''',',,,,,,,,,>;;;;>>>>,,>,,,'''',,,,,,>,,,,''''''''''''''''''''''''''',>>;;%##%&&&*-;;>>,,,,,,','','''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>;>;>;;>>;>;>>;>;>>;>;>;>;>>;>;>>;>;>;>;>;>>>>;>;>;>>;>>;>>;>;>>>>>>>;>;>;>;>>>>>>>>;>>>>>>;>>;>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>,>>,>>>>,>>>>,>>>>>>,>>,>>,>,>>>>,>>>,>,>>>>>>,>>>,>,>>>,>>>,>>,>>>,>,>>>,>,>,>,>,>>>,,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,,>,>,,>,,,>,,>,,,,>,>,,>,,,,,>,>,,,>,>,,,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,',,,',,,',,,,',,',,',',',',',,,,>;=***%$$&-;;>,,,',,,,,,,,,,>,>>;;;;;>>>>>>>>,,,,',,>>>>;>>>,,,,,,,,',',',',,',','''',,>>;>-%#$&&*&*->>>>>,,,'',',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>>;>>;>;>;>>;>;>>;;>;>;>;>>;>;>;;>;>;>;>>;>;>>;>;>;>;>>>>;>>;>>;>>>;>;>;>;>>>>>;>>>>;>;>>>>;>>;>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>>>>>,>>>>,>>>>>>>>,>>>,>>>>>,>,>,>>,>>,>>,>,>,>,>,>>,,>>>,>,>,>>>,>>>,,,>>,>,>,>,>,>,>,>,>,>,,,>,>,,>,>,,>,>,,>,,>>,,>,,>,>,,,>,,,>,>,,,,,>,,,,,>,,,,,>,>,,>,>,,>,,,>,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,',,,,,,',,',,',,,',,',',',',',',,',',,',,',,,',,','',',,',',,',,',,',,,,>>-***&%$&-;;>,,,,,',,,,,,,,,>>>;----;;;;;;;;>,,,,,,>>;;;;>>,,,,,,,,,,,,,,,',,,',,,,,',,>;;-%$&&**&-;>>>,,,,',,',',''',''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>>;>;>>;>;>>;>;>>>;>>;>;>>>;;>;>>;>>;>;>>>;>>>>>>>;>>>>>;>>>>>;>>>>>>>>>>>>;>>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>,>>>,>>,>>>,>,>>>>>>>>,>>,>>,>>>>>,>>>,>>>,,>,>>,>,>,>,,>>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,,>,,>,>,,,>,,>,>,,>,,>,>,,>,,>,>,,,>,>,,,,>,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,',,,,,,,,,,,,,,,,,',,,',,,,,,,,,,',,,,,,',,',',',,',,,,,,',',,,',,',',',,,,,>>;**=*&$&=;;;>,,,,,,,,,,,,,,,>>;-----;-;;-;-;>>,,,>>;;--;;>>>>,,,,,,,,',,,,,,,,,,,,,,,>>;>-&%&****;;>>>>,,,,'',',',,''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;>;>;>;>;>;>;>;>>;>;>;;>;>;>;>;>;>>;>;;>>;>;>>;;>>>>;>>;>>>>;>;>>>;>;>;>>;>;>>>>>;>>>>;>;>>>;>>;>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>>>>>,>>,>>>>,>>,>>>,>>>>>,>>>>>,>,>,>,>>,>>,>>,>,,>>,,>>,,>>>>>,>,>,>,>>,>,>>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,>,,>,,>,>,,>>,,>,,,,>,,>,,,>,,,>,,,,>,,,,,>,>,,,>,,,>,,>,,>,,>,,,,,,,,>,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,',,,',,',',,,,,,,,',',',',,,,',',,,',,,,,',,','',',',,'',,',',,',',,,,>>>-****&&=;;>>,,,,,,,,,,>,>,,>>>;-===-=--=-=-;>>,,>;---=-->>>>>>>,>,,,,,,,,,,,,,,,,,,,>;;;=&****&=>>>>,>,,,,,',',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>>;>;>;>;>>>;>;>>;>;>;>;>;>;>>;>;>;>;>;>;>>;>>;>>;>;>>>;>;>>;>;>;;>>>>>;>>>>>>;>>>>>>;>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>,>>,>,>>>>>>>>>,>>,>>,>>>>>,>>,>,>>>,,>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,>,>,>,>,>,,,>,,,,>,,>,>,,>,,>,,,>,,,,>,,,>,>,,,,,,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,',,,,,,,,,,',,,',,,,,,,,',',,,,,',,,',',,',,,,,',,,',,',',,',',',',,,,>>;**=&*&=-;;>>,,>,>,>>,,,>,>,>;;-===========-;>>>>;-====-;;>>>>>>>>>,>,,,>,,,,,,,,,,>>>;>-******;;>>>,,,',',,',',',',''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;;;>;>;>>>;;;>;>;;>;>;>;>;>;>;>;>>;>;>;>;>>;>;>>;;>>>;>;>>>;>>>>>>>>;>;>>>;>;>;>>;>;>>>>;>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>,>,>>,>>>>>>>>>>>>,>,>,>,>>>,>>,>>,>,>>,>>>,>,>,>>>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,>>,>,>,>,>,>,,>,,,>,>,>,>>,,>,,,,>,,>,,>,,,>,>,,,>,,,,>,,,>,>,,,,>,>,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,',,',,,,',,,,',',',,,,,',',,',',,,',,','',,',',',,,',',',',',,,,,,>>>-*****=-;;;>>,>,,>,,>,,,>,>,>;--*********==-;>;;;==***=-;>>>>>>>>>>>>>,>>>>>,>,>>,>;;;;-*===*->>>,>,,,,,',',,',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>>;>;>;;>>>>;>;>>;>;>;>;>;>;>;>;;>>>;>;>;>>;>;>>>;;>;>>>;>>;;>;;>;>>;>>;>>>>>>>>>>>>;>>>>;>>>>;>>>;>>;>>;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>>>>>>>>,>>,>>>>>>>>,>,>,>,>,>,>>>>>>,>>,>>,>>>,>>>,>>,,>>,>>>,>,>,>,>,>,>,>>,>>,>,>,>,>,>,>,>,,,>,,>,,>,,>,>,,>,>,>,,>,,,>,,>,>,,,,>,,>,>,,,,,>,,,>,,,>,,,,,,>,,,,,>,,>,,>,,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,',,,,,',,,,,,',,,,,',,,,,,,',',,,,',,',,',,',,,,,',,',,,',',,,',,,',',,,,,,>>;*****=--;;>>>>>,>,>,>,>,,>>>>;-=*********=-;;>--=****=--;;;;;;>>>>,>>>>,>,>>,>,>>>>;>;-===**;>>,>,,,,,,,,,',',,'',''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";;;>;>>;>>;;;;>>;>;>;>>>;>>;>>;>;>>;>;>;>>>;>;>>;;>>>;>>;;>>;>>>>>>>;>>>;>>;>;>;>;>;>>>>>;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>>>>>>>>>>>>>>,>,>>>>,>>,>>,>>,>,>>,>>>,>>,,>>,>>,>,>,>,>>,>,>,>>,>,>,>,>,>,>>,>,>,>,>,>,>,,>,>,,,>,,>,>,,>,,,>,>>,,>,,,,>,>,,,>,,,>,,,,>,,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,',,,,',',,,,',',,,',',',,,,',',,',,',,',,','',,',,'',',,',','',',,',,,>,,>>-****=;-;;;>>,>>>,>,>,,>,>>>>;;=***&&*&&**==-;-=*&&**=--;-;;;;;>>>>>>>>>>>>>>>,>>>;;>;-=-==->>>,,>,,,,''',','',,''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>;;>;;>>>;>;>;>;>;;;>;>;>;>;>;;>;>;>;>;>;>>;>>;>;>;>>>;>>;>;>;;>>>;>>>>>;>>>>>>>;>>;>>>>;>>>;>>>>>;>>>>>;>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>,>>,>>>>>>>,>>>>>>>>,>>,>,>,>,>>>>>,>,>>,>>,>>,>>>>,>>,>,>,>>>,>,>,>>>,>,>,,>,>,>,,>,>,>,>,>,>,>,,>,>,>,>,>,>,,>,>,>,>,,>,>,,,>,,,,,>,,>,>,,,,,>,,,>,,,>,,,,>,,>,,,,,>,,,,,,,>,,,,,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,,',,,,,,,,,,',,,,,,',,,,,,',,,,,,,,',,,,,,,',,',,,',,,,',',',,,',',,',,,',',,,,,,>,,>;=*=*=---;;>>>,>,>,>,>>,>,,>>>;-=**&&&&&&**=-==**&&&**=--;;-;;;;;;;>>>>>>>>>>>>>>>;>;;-=-==;>>,>,,,,',,,,',,,,''',''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";;>;>>;>>>;>;>;>>;>;>>>;>;>;>;>;>>>;>;>;>;>>;>;>;>;>>>;>;>>;>>>;>>>;;>>>;>;>>>;>;>;>>;>>>>;>>>>>>>>>>>>>;>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>>>>>>>>>>>,>>>,>,>>,>>>>>>>>>>>,>,>>>>>,>>>>>,>>,>,>>,>,>>>,>,>>>,>,>,>,>>>>,>>>,>>,>,>,>,>,>,>,,>,>,,>,,>,,>,>,,,>,,,>,>,,,>,>,>,>,,,>,,,,>,>,,,>,,,>,,,,>,,,,,,,>,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,',,,,,,',,,,,,',,,,,',',',',,,',',',,',,',,',',,',,,',',,,',','',,,',',,,,,,,>>-**==----;;>>>>>>>,>,>,,>>>>>;-=**&&&&&&***==*&&&&&&==-------;;;;;>;>>>>>>>>>>>;>;;>;--=*;>>,,,,,,,,',',,''',,,'','''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;;;>;>;>;>>;>;>;>;>;>;>;>;;;>;>;>;>>;>>;>>;>;>;>>>;>>;;>>>;>>>>;>>>>>;>>;>>>>>>>>;>>>>;>;>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>,>>,>>>>,>>>>>>>>>>>,>,>,>,>>>>>,>>,>>,>,>>,>>,>>,>>>,,>,>>,,>>,>,>,>,,>,>,>,>,,,>,>,>,>,>,>,>,>,>,,>,>,>,,,>>,,>,>,,,>,>,,,,>,,,>,,>,>,,,,,>,,,>,,,>,,,,,>,>,,,>,,,,,,,,,,,,,>,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,',,,',,',,,,',',,,,,,,,',,,',,,',,',,',,,,',,'',,',',',,,',,''',,,',,,,,,,,;***=--;--;;>>>>,>>,>,>>,,>>>>;-=**&&&&&&&****&&&&&**==----;--;;;;;;;>;>>>>>>>;>;>>;;--*->>>>,,,,',,,','',,,''','''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>>>;>;>;>;;>;>;>;>;>>;>>;>>>;>;>;>>;>;>;>;>;>;>;>;>>>;>>;;>>;>;>>;>;>>>>>>;>>>;>>>>>;>>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>,>>>>>>>>>>>,>>,>,>>,>>>>>>>>,>,>>,>>>,>,>>,>>,>>>,>,,>>>>,>>>>,>,>,>>>>,>,>,>,>>>,>,>,>,>,>,>,>,,>,>,>,>,>,>,,,>,>,>,>,>,,>,>,,>,,>,,,,,>,>,,,>,,,>,,,,>,,,,,,,,,,,,>,,,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,',,,,,,,,,,,',,,,,,',',',,,',,,',,,',,',,',',,',,,',,,',,'',',',,,',,,',,,,,,>>;***-----;;>>>>>,>,>,,>>,>>>>>;-**&&&%&&&&&&&&&%&&&*===------;;;;;>;;>;>;>>;>;>;;>;;-==;>,,>,,,,,',',,,','',,',','''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>>;>;>;>>>;>>>;>>>;>>;>>>>>>>;>>>>;>>>;>;;>>>;>>>;>;>>>;>>;>>>>>>>>>>;>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>,>,>,>>>>>,>>>,>>>>,>>,>>,>,>>>>>,,>>,,>,>>>,>,,,>>,>,>,>,,>,>,>,>,>,>,,>,>,,>,>,>,,>,,>>,,>,,>,,>,,>,,,>,,>,>,>,>,,,,,>,,,>,,,>,,,>,,,>,>,,>,,,,,>,,>,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,',,,,,',,',,',,,,,',',,,,,,,',,,,',,',,',,,',,,',,'',,'',,',,,',',,'',',',,',,,,,>>=**--;--;;;;>>>>>>>>,>,>,>>>;;-=**&&&&&&&&&&&%&&&**====-------;;;;;;;>;>>;>;;;;>;>;-=;>>>>,,,,,',,,',',',,'',',''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>;>;>;>>;>>;;>;>;>>;;>>;>;>;;>;>;>;>;>>>;>>>>>;>>>;>>>>>>>>>>>>>;>>;>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>>>,>>>>>>>,>>,>>,>>>>>>>>>,>,>>>>,>>,>,>>>>>,>>>,>,,>,>>,>>>,>,,>,>>>,,>>>,>>,>,>,>,>,>,>,>,>,,>>,>,,>,>,,>,,,>,,>,,>,,>,,>,,,>,,,,,>,,>,>,,,>,,,>,,,,,,,>,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,',,,,,',,,,,,,,,',,,,,,,',',',,,',,',,',,,',',',',',,,',,',','',,,',',,,',,',,'',,,>>;=*=----======--;;>>>>>>>>>>>;;-**&&%&&&&&&%&%&&&***=-==----;-;;;;;;-==****===-;>;-=->>,,,>,,,,',',',',''',','','''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;;>;>;>>;>>;>;>;;>>;>>;>;>;>;>;>;>;>;>;>;>>>>;>;>>>;>>;>>>>;>>>>>>>>;>>;>;>>>;>>>>>>;>;>>;>;>>>>>>>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>,>>>>>>>>>>,>,>,>,>>>>,>,>>,>>,>>,>,>>,>>,>>>,>>,>,>,>>>>,>,>,>>,>,>,,>,>,>,>,>,>,>,>,>,,,>,>,,>,>,,>>,>,>,,>,>,,>,,>>,,,>,>,,,,,,,,>,,,>,,,>,>,,,,,,>,,>,,,,,>,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,',,,,,',,,,,',,',',,,,',',',,,,,,,,',,,,',,',',,,,,,',,',',,',,',,,''',','',,,',',,',',,,>-****&&%&&&***====--;;>>>>>>;;-=**&&%&%&%&%&%&&&***===-------==*&&&&&&&&&%%%&&*=-=-;>,>>,,,,,,,',',',',',',','',''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;>;>;>;>;>;>>;>;>;>;>;>;>;>>>;>;>;>>>;>;;>;>;>;>>>;>;>;>>;>;;>;>>>>>>>>;>>>;>>;>>>>>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>,>>>,>>>,>,>>,>>>>>>>>>>,>>>>>>,>>,>>,>>,>>>,>>,>,>>,>>>,>>,,,>>>,>,>,,>,>>,>,>,>,>,>,>,>,>,>>>,>,>>,>,>,,,>,,>,>,,,>,,,>,,,>,,>,,>,>,>,>,,,>,,,>,,,,,>,>,,,,,,,>,,,,,>,,>,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',',,,,,,,,,,',,,,,,,,,',,,,,,,',',',',,',',,',,,',',',,',,',,',,',,',',,,',,,',',,,'',',',,>>-*&&&%&&&&****====-=-=--;;;>>;;-**&&&&&&&&&&&&&&***===-----**&&%&&&&&*&&&&&%&&**=*--;>,>,,,,,,,,',','',','',',''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>>;>;>;>;>;>>>;>;>;>;>;>;>;;>;>>>;>>>;>>;>>>>;>>;>>>>>>;>;>;>;>>;>>>;>>>;>>;>;>>;>>>>>;>>>>;>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>,>>>>>>>>>>>,>>>>>>>>,>,>,>,>,>>>,>,>>>,>>,>>,>>>,>>,>>,>,>>,,>>,>>>>,,,>>,>>>,>>,>>,>,>,>,>,>,>,,>,,,>,,,,>,,>,>,,>,,>,>,>,,>,,>,>,>,,,>,,,,,,,,>,,,>,,,,>,,,,,,,>,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,,,,,',',,',,,',,',',,,,,,,,',,,,',,,',,',,,',',',',',',',,',',',',',','',',',',,,;-=**&&*=;;>;;--=---=---=-=--;;;;-=**&&&%&%&%&&&&***===-=--*&%%%%&%&&*&***-;>,>>--===--;;,>,,,',,',,',','',',',','''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>>;>;>;>;;>;>;>;>;>;>;>;>>;;>;>>>;>>;>>;>;>;;>>;>;>;>>;>>>;;>;>>>>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>>,>>>>,>>>,>>>>>>>>>>>>,>>>>,>>>,>>,>>,>,>>>,>,>>,>,>>,>,>,,>>>,>,>,,>,>,,,>,>,>,>,>,>,>,>,>,>,>>,>,>,,>,>,,>,,,>,,>,>,,,,,,,>,>,,>,>,>,,,>,,,>,,,,,>,,,>,,,,,,,,>,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,,,,,,,,,',',',,,,',,',',,',,',,',,,',,',,',,',',,',,',',,,,',',''',,;;----;,,,,''',,,>;----=--======-;-==*&&&&&&&&&&*&***===-=*&%%%&&&&&&**=;,''''''''',>;----;>,,,,,,,',','',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;>>;>;>;>;>;>;>;>;;>>;>;>;>>>;>;>;>>>>;>>>>;>;>>;;>>>>>>;>;>;>;>>>>>>;>;>;>;>>;>>;>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>,>,>,>>>,>>>>,>>,>>>,>>>,>,>>>,>,>>>,>>,>>>,>,>,>,>>,>,>>>,>,>,>,>,>,>,>,,>,>,,>,,>,>,>,,>,,>>,,>,,,,>,>,>,>,,,>,,,,,,,>,,,>,,,,>,,,>,,,,,>,,>,,,>,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,',,,,,,,,,,,',,,',,',,',',',',,,,,,,',',',,',,',,,',,',',,',,,',,',,,'','',',',',','',',,>>;;>>,,,,',,,',',,,,>;--=---===*==-==***&&&&&&&&&***===-=&&%&%&%&&&&*=>,'''''''''',',,,>;;-;>>,',',',',','','',,','''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>>;>>;>;>>;>;>;>>;>;>>>;>;>;>;>;;>>;>>>;;;>>;;>>>>>;>>>;>;>;>>>;>>>>;>;>>>>>>>>>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>,>,>>>>>,>>,>>>>>>>>>,>>>,>,>>,>>,>>,>,>>>,>,>>>,>,>>,>>,,>,>,>>>,>>,>,>,,>,>,>,>,>,>,,>,>,,>,>,>,>,,,,>,>,>,,>,>,>,,>,,,>,,>,,,>,>,>,,,>,,,>,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,',,,',,,',,,,,',,,,,,,,,',',',,,,,,',,',,',',,',,',','',,',',',,',,,,',',,',',',',,>,,,,',,,,,',,',,,,,,,,>---=--==****==**&&&&&&&******===*&%&%&&&&&&*=;,,,,''''''',',,,,,,,>;;;>>,,',','','',',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>;;>>>;>;;>;>;;>;>;>;>>;>>;>>;;>>>>;>>>;;>;>>>;>>;>>>>;>>>>;>>>>>;>>;>>>;>;>>>>>>>;>>>>>;>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>,>>>>>>,>,>>>>>>>>,>>>,>>>,>,>,>,>>>,>>>>,>>,>>,>>,>>,>>,>,>,>>,>,>,>>>,>,>,,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>>,,>,,,>,,>,,,>,,,>,,,>,,>,,,,,,>,,,>,,,,,,>,,>,,,>,,>,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,,,,,,',',',,,,,,',',',,',,,',,,',,,',,',,,',,',',',,''',,',',,',',',,,,,,,,,,,,,,,,,,,,,,,,,>,>;--=-===*&&&*****&&&*&&&***==-*&%&%&&&&&&**;,,,,,,,,'',,,,,,,,,,,,>;;;>,,,',','','''',,',''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>>;>;>;>>;>;>>;>;>;>;>;>;>;>;>>;;>>;>;>>>>;>;>>;>>;>;>>>;>;>>;>;>>>>>;>>>>>>;>>>;>>>>;>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>,>>>>>>>>>>>>>>>>>>,>>,>>>>,>>,>>,>>,>>,>>>,>>,>>,>>,,>,>>,>>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,,>,,>,>,>,,>,,>,>,,>,,,>,,>,>,>,,>,,,>,,,,,,,,,,,,,,,,,>,,>,,>,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,',,,,',,',,',,,,',,',,,,,,,',',,,,,',,',,',,,',,,'',',,,'',',,',','',,,'',',',',',',',,,',,,,,,>,,>,>,,,>,>,>,>>;----===**&&&*****&*&*****===*&&&&&&&&&*&=->>,,,,,,,>,,,,,,,,,,,,,,,>>>>,,','','',','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;>;>;>>;>;>;;>>;;>>;>;>;>;>;>;>>>;>>;>;>>;>>;>>;>;>>>;>>;>>>>>;>>>>>;>>>>;>>>>>;>>;>>;>>>>;>>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>,>,>,>,>,>,>>>>>,>,>>>>>,>>>>>,>>,,>,>,>,>>,>>,>,>,>,>>,>,>,,>,>,,>,>,>,>,>,,>,,,>,>,,>,,,>,>,>,,>,,,>,,>,,,,>,>,>,,>,,,,,,,,,,>,,>,>,,>,,>,,>,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,,,,,,,,,,,,,',',',,,,',',,,',,,,',',',',,,,,'',,,',',,',',,',',,,,',',',,,',,',,,,,>>>>>>>>>>>>>>>,,>,,>;-=--===*&&%&&***&*****===-*&%&&&&&*&***->>>>>>>>>>>>>>>>>>>>,>,,,,,>>>,',','','''','','''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;;>;>;>>;;>>;;>;>;>;>;>;>>;;>>;>;>>;>;>>>;>>;>;>>;>>;>;>;>>;>;>>>;>>>>;>;>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>,>>>,>>,>>,>>,>>>>>>>>>>>>>>>>>>>,>,>>>>,>,,>>>,>,>>,>>>>>,>>>,>,>>,>>,>,>>,>,>>>>,>,>>,>,>,>,>,,>,>,>,>,>>,>>,>,,>,,>,,>>,,>,,>,>,,,,,>,,,>,>,>,>,>,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,>,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,',,',',',',,,,,,,,',,,,,',,,',',,,',,,',''',,,',,',,',',,',',','',',',,',',',,,,>>>>>>;>;;;;>;>>>>>>>>,>>;---===**&%%&*********====&&&&&*&******;>>>>>>>>>>;;;;;;>;>;>>>>,,,,,>,,,'',''',,',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>>>;>>;>;>;>>;>;>>;>;>;>>>;>;>>;>;>>;>;>>>;;>>;>>;>;>>;>>>>>>>;>>>>;>>;>>>>>>;>>;>>;>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>>>>>>>>>>>,>>,>>,>>,>,>,>,>>>>,>,>>>>,>,>>,>,>>,>,,>>,,>>>,>,>,>>,>,>,>>,,,,>,>,,>,>,>,>,>>,>,>,,>,,,>,,,,>,>,>,>,,,>,,,>,,,>,>,>,,>,,,,,,,,,,,>,>,,>,>,>,>,,>,,,,>,,>,,>,,,,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,',,,,',,,,,,,,',,',,,,',,,',,,,,,,,,,,',',',',,',',,,',',,,,',,,,',,,,,',',',,',,',',,',',',,,,',',,,',,,,,>>>;;;;;;;;;;;;;;;;>>>>>>>;-----==*&&%%&******===-=*&&&&&*&*&***-;>>>>>>;;;;;;;;;;;;;;;;>>>>,,>,,,',''',''',',','''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>;;>;>;>>;>;;>;>;>;>;>>;;;>;>;>>;>;>>;>;>;>>>;>>>>;>>;>>;>;>;>>>>;>>>;>>>;>>>>>>>>>>>>;>>;>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>,>>,>>>>>,>>>>>>>>>>>>,>>>>,>,>>>>>,>>>>,>,>>>,>>>,,>>>,>,,>>,>,>,>>>>,>,>>,>,>,>,>,,>,>,>,>,>>,,>>>,,,>,,,>,>,>,>,,>,,,>,,,>,,>,>,>,>,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,,,,',,,,,,,',',,,',,,,,,,,,,,,,,,',,',,',',',',',',',,',',,',',,','',',,','',',,,,,,,,,,>>>;;;------------;;;;>>>>>>;---=-==**&%%&****====--*&&&********==-;>>>;;;;---------------;;>>>,,,,,,','''','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;;>>;>;>;;>;>>;>;>;>>;>;>>>;>;>;>>;>;>>>;>;>;>>;>;>>;>>;>>;>>>;>;>>;>>>>;>>>;>>;>>;>;>>>>>>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>>>>,>>>>>>,>,>,>,>,>>>,>>>,>>,>,>>,>,>>>>,,>>,,>>,>,>,>>,>,>>,>,>,,>,>,,>,>,>,>,>,>,,,>,>,>,,>,,,,>>,>,>,>,,>,,,>,>,>,,,>,,>,,,,,,,,,,>,>,>,,,>,,,>,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,,,,',,,,,,',',',',',',,',,,',,,,,',,,,,',',,',,',,',',',,,',',,,,,,,,,,'',,,>>;--=--=-=-=-=-=-----;;;>>>>;-----===*&&%%&*=====--=*&*&*&****====;;;;;;;;----=-=-==-=-------;>>>,,,,,',,''',',',''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;;>;>;>>;>>;>;>;>;;>;>;>;>;>>>;>;>>;;>;>>>>;>>;>>;>>;>>;>>>;>>>;>>>;>>>>>;>>>>>;>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>>>>>>>>>>,>>>>>>,>>,>>>>>>>>>>,>>>,>>>,>>>,>>>>,>,,>>>,>>>,>>,>>,>>,>,,>,>,>>,>,>>,>,>,>,>,>,>,>,>,,>,>,>>,>,,,,,>,,>,>,>,,,,,,>,>,,>,,,>,>,>,,>,,,,,,>,,,,>,,,,,,,,,,,>,>,,>,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,',,,,,,',,,',,,,,',,',,,,,,,,,,,,',,',,',',',,','',,,',,',',',,',,',',',,'',',,'>,,,,,,>>;--=================---;;;;>;-----===**&&%**===--=-=*&******=*===-->;;;;--==================--;>>,,,,,''',','','','''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;>>;>;>;;>;>;>;>>;>;>;>;>;>;>>>;>>;>>;;;>>;>>;>>;>>;>>>;>>>;>>>;>>;>;>>>>>;>>>>>>;>>>>>;>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>,>,>,>,>>>>,>,>,>>>,>,>,>,>>>>>,>>,,>>,>,>,>,,>>>>,>>,>,>,>,,>,>,>,>,>,>,>,>,>,,>,>,,>,,>,>,>,>,,,>,,>>,>,,,,>,,,>,,,,,,>,,,>,>,,,,>,,,,,,>,>,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,,',,,,,,,,,,',,,,,,',',',',',',,,,,',,',,,,',,,,'',,',,',,,',',',',,,',,,,,,,,>,,',,>>;-=*==***=*=*=**=*=*====-;;;;;;------==*&&&&*=-=----=*******=====---;;;---====*=*=**=*******==--;>>>,,,,',',',,','''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;>>;>>>;>;>;>>;>;>;>;>;>;>;>>;>;>>>;>>;>>;>>;>>;>>>;>>>;>>;>>>>>;>>;>>>;>>;>>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>,>>,>>>>>>>>,>,>>>>>>>>>>,>,>>>>>,>,>>>>>,>>,>,,>,>,>>,>>>,>,>>>,,,>>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,>,,>,,>,>,>,,,>,>,,>,,,,>,>,>,,>,,>,>,,,,,>,,,,,>,,,,>,,>,,,,,,,,,,,,,,,>,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,',,',,,,',',,,,,,,,,,,,,,',',,',,',',,',',,,',',',,',',,',,',',,,,,,,>,>>,,,,>>;-==*******************===--;;-;------===*&&&*=------******====------;;--==********************==--;;;>>,,,',',,,',''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>>;>;>;;>>;>;>;;>;>;>>>;>;>;>;>>;>>;>>;>>;>>;>>;>>;>>>;>>>;>>>;>>>>>>>>>>>;>>>;>>;>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>>>>>>>>>>,>>,>,>>>>>>>,>,>,>,>>>>,>,>,>>>,,>,>>>>,>>>,>>>,>>,,>>>,>,,>>>,,>,>>,>,>,>,>,>,>,>,>,,>,>,>,>,>,>,>,,>,,>,>,,,>,,>,>,,>,,,>,,>,,,,,>,>,,,,>,,,,>,,,>,,,>,,,,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,',,,,,,,,,,,,',,,,,,,',',',',',',,,,',,,,',,,',,,,',,',,',',,',',',',,',,,,,>>>>;,,,,>--=**&*&**&**&*****&******==-----;---=--==**&*=-----;-*****=====---------==***&****&***&**&*&*&***===---->,,,,,,,,,,''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;>;;>;>;>>;;>;>;>>;>>>;;>;>>;>>;>;>;>>>;>>;>>;>>;>>;>>;>>>;>>>;>>>;>;>;>>;>>>>>>>>>>>>;>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>>>>,>>,>>>>>>>>>,>>>>>>>>,>>>>>,>,,>>,>>,>,>>,>>>,,>,>>,>,>>,>>,>,>,>,>,>,>,>,>,>,>,,>,,>,,>,,,>,,,>,>,,>>,,,>,,,>,,>,,>,,,,>,>,,,,>,>,,,>,,,,,,,,,,,,>,,>,,,,,,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,,,,,',,,',,',,,,,',,,',,,,,,,,,,,,',',,',',,',,','',',',',,,',,',',',,',,,,,>>>>;;>>>>;;-=**&*&&&&*&&*&&&&*&&&&&&***=----;-----=-==***==-;-;;-=*======----;-;--==***&*&&&&&*&&&&&&&*&&&&&******==->,>,,,,,,,,'''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;;>;>>;>;>;;>>;>>;>;>;>;>>;>>;>;>;>>;>;;>>;>>;>>;>>;>>>>>;>;>>;>>>;>>>>>>;>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>,>>,>>>>>>,>,>,>,>>>,>,>,>,>,>,>,>>>>>>,>,>>,>,>>,,>>>>,>,>,>,>>,,>,>,>,>,>,>,>,>,>,>,>>,>,>,>,>,>,>,>,,,>,,>,>,,,>,,>,,>,,>,>,,,,>,>,,,,>,,,,,>,,>,,>,,,,,,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,',,,,,,',,,',,,,',,,',,,,',',',',',',,,,',,,',,',,,,,',,,,,'',',',,,',',,,,,,,>>>>;;;>;;-=***&&&&&&&&&&&&*&&&&*&&&&&&***=---;--=--=-===*=--;;-;-=======--;-;---==***&&&&&*&&&&&&&&&&&&&&&&&&&&&&&&&*-;>>>>>>,,,,''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>;>;>;>>;>>;>;>;>;>;>;>;>>;>;>>;>>;>>>>>;>>;>>;>>;>>;>;>>>>>;>>>;>>>;>>>>>>;>>>>>>;>;>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>,>>,>>>>,>>,>>>>>>>>,>>,>>>>>>>>,>>>>>>,>>>>>>>,>,>,>,>>,>,>>,>>>,>,,>,>,>,>,>,>>,>,>>,>,>,>,>,>,>,,>,,,>,>,>,>,>,,>,>,>,,,>,,>,>,,,,>,,,,,,,>,,,,,,>,,,,,>,,,,,,,,,,,>,,,,,,,>,,,>,,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,',,,,,,,,,',,,,,,,,',,,,,,,,,,,,,',',,',,',,,','',,'',',,,',,',',',,',,,>>>>>;;;;---==*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&**=------=-=-====--;;;;;-=====-----;-;--=**&&&&&&&&&&&&&&&&&&&&&&&&&&%%&%&&%*=--;;>>>,,,,''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>>;;>;>;>;>;>;>;>;>;>;>;>>;>;>;>;>;;>>;>>;>>;>>>;>>>>;>;>>>;>>;>>>;>>;>>>>>>;>>>>>;>>>>;>;>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>>,>>>>>>>,>,>,>>>,>,>,>>>,>,>,>>,>>>,>>,>>>,>,>,>>,>>,>>>,>>,>,>,>,>,,>,>,>,>,>,>,>,,>>,>,,>,>,,,>,,,>,,>>,,,>,,,>,>,,>>,>,>,,,>,>,,,>,>,,,,,>,,>,,>,,,,>,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,',',,',,,',',',,',',',,,',,',,',',,,,',,,',,',,',',',,',,,,,,>>>;;;---***&&&&%&%&%&%&%&%&%&%&&%&%&&&&&&&&*=-;-----=-=====---;;;;;-==-----;-;--==**&&&&&&&%&%&%&%&&%&%&%%%%%%%%%%%$%%&*=--;;;>>>,,,'''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;;>>;>;>;>;>;>;>;>;>;>;>>;>;>>>;>;>>>;>>;>>;>>;>;>>;>>;>>>;>>;>>;>>>;>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>,>>>>>>>>>,>,>>>>>>>>,>>>>>>>,>,>>,>>,>>,>>,>>,>,>,>>>,>,>,>,>,>,>,>,>>,>,>>,>,>,>,>,>,,>,>,,>,,>,>,,>>,,>>,,>,,,>>,,>,,>,,>,,,,,,,>,,,,,>,,,,,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,',,,,,,,,,,,,',,,,,,,,',,,,,,,',,,,,,',,,',,',,,','',,'',,',',,',',',,,',,,>,>>>;;;-;=*&%&%%%%%%%%%%%%%%%%&%%%&%%%%%%%%%&&*=----====-===-----------==----;----=**&&%%%%%%%&%%%&%%%%&%%%&%%%%%%$$%$$%&**==-;;>>>,,,'''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;;>>;;>>;>;>>;>;>;>;>;>;>;>>;>;>;>>>;;>>;>>>;>>;>>>>>;>>>>;>>;>>>>>>>>>>>>>>>>;>>;>>>>;>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>,>>>>>>>>,>>,>,>>>>>>>,>,>,>>>>,>,>,>>>,>>,>>,>>,>,>,>,>>>,>,>,>>>,>,>>,>,>>,,>,>,,>,>,>,>,>,>,>,>,>,>,,>,>,,,>,,,>,>,>,,,>,,>,,>,,>,>,>,,,>,>,,,>,>,,,,,,,>,,,,,>,>,,,,,,,,>,,>,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,',,',,,',',,,,,,',',,,,',',',,',',',,'',,',,,',,,,,',,,',,',',,',,',',,,,>,>>>;;;;--=*&%%%%%$%%%%%%%%%%%%%%%%%%%%%%%%%%&&**=--=-======-=-----------------;-==**&&%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$%%***==--;;>>>,,,''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>;>>;;>>;;>;>>>;>;>>>;>>;>;>>;>;;>>>;>>;;>>;>>;>;;>>;>;>>>>>;>;>>;>>;>>;>;>>>>>>>;>>>>>;>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>>>>>,>>,>>>>>>>>,>>,>>>>>>>,>,>>>>>>,>>>,>>>>,>>>>,>>>,>,>,>>>,>,>,>,,>,>>,>>,>,>>,>,>,>,>,>,>,,>,,>,>>,>,,>>,,>>,,,>,>,>,,>,,>,,,,,,>,,>,,,,,>,,,,,>,,>,,,,>,,,,,,,,,>,,>,,,,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,,,,,,,,,',,,,,',,',,,,,',,,,,,,,,,,,,,',,,',,',',','',,'',,',,,',',',',,',,,,,>>>;;;---=**%$$$$$$%$%%%%%%%%%%%%%%%%%$$$%%$%%&*============-=-----------------==**&%%%%$$$%%%%%%%%%%%$%%$%$%$$$$$$$$%&**===---;;>>,,,,,'''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>>;;>>>;>;>;>;>;;>>;;>>>;>>;>>>;>>;>>>>;>>;>>>>>>>>>>;>;>>>>;>>>>>>>>>>>;>>>>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>>>>>>>,>>,>>>>>>>,>,>,>>>>>,>,>>,>,>>,>,>>,>,>>,,>>,>>>,>,>,>>,>>>,>,>,>,>,>,,>,>,>,>,>,>,>,>>,,>,,>,>,,,>,,,>>,,>,,,,,,>,,,>>,>,,,,,,>,>,,,>,>,,,,,>,,,,>,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,,,,,,,',,,,,,,,,',,,',',',,',',',,,',,,',,,,',,,',,',','',',,',',',,,,,>,>>>>>;;---==*&&%&%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&**======*====-------;-;-;------==**&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&**===---;;;>>>,,,''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>>;;>;>;>;>;>>;>;>>;;>;>>;>;>;>>;>;>>;>>;>;>;>;>;>>>>>;>>>>>>;>>;>>;>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>,>>>>>>>,>>,>>>>>>,>>,>>>>>>>>,>,>>>>,>>>,>>>>,>>,>>,>>>,>>,,>,>>>,,>,>,>,>,>,>,>,>>,>,>,>,>,,,>,>,,>>,>,,>,,>>,,>>,,,>,,>>,>>,,>,,,,,>,>,>,,,,,>,,,,,,>,,,,,>,,,,,,,,>,,,>,,,>,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,',',,,',,,,',,',,',,,',,,,,',,,,,,,',,',',,',',,',,',,,',,,,,,',',,,',',,,,,>>>>;;;;----===**************&*&*&&*&&&&&&&&&&**==--==-=-=-------;---;-;;;;----==**&&&&&&&&&&&&&&&&*&*&**&********=*===-=---;;;>>>,>,',''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;;>>;>;>;>>;>;>;>>;>>;>;>>;>>;>>;>>;>;>;>>>>>>>>>;>;>>>;>;>;>>;>>>>>>;>>>>>;>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>>,>>>>>>,>,>,>,>>>>>>,>>>,>>,>,>>,>>>,>>,>,>,>>>>,,>>>,>,>,>>,>>,>,>,,>,>,>,>,>>,,>,,>,,,>,>,>,,,>,,,,>,,>,,,,,,,,>,>,>,,,,,,,>,>,,,>,>,,,,,>,,,,,>,,>,,,>,,,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,,,,,,',,',',,,,',',',,',,,,,',,,,',',,'',,','',',','',,',,,,,,,,>>>>;;;;-;---------=====*===*===**==*=**=*=**==--------------;--;;;-;;--;-;---=====**********==*=*==*=========--------;;;;;;>>>>,,,,','''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>>;>;>;>;>;>;>;>>;>>;>>>;;>;>>>;>>;>>>>>>;>;>;>;>>>>>;>>>>>>>>>>>;>>;>>>;>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>,>>>>>>,>,>>,>>>,>,>>>>>>>>>,>,>,>>,>>,>>>>,>>>,,>,>,>>>,>>,,>>>,,>,>,>>,>,>,>>,>>,>,>,>,>,,>>,>,>,>>,>,>,,>>,,>>,>,>,,>,>,>,>,,,>,,>,>,>,,,,,>,,,,,>,,>,,,>,,,,,,,,,,,,,,>,,,,,,>,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,',,,,,,,,,,,,',',,',,,,,,,,,',',,,,,',,','',,,',',,,',',,',',,,',,',,',,,',',,,>,>>>>>>;>;;;;;;;-;--;----------=--=-=-=-===-=-----;--------;-;-;;-;;;;;;;;;;-----====-==-=---=-=---=--------;;-;-;;;;;>;;>>>>>,,,,,',','''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>>;>>;>;>;>;>;>;>;>>;>;>;>>;;>>>>>;;>>;>>;>;;>;>>>;>>>>;>;>>;>>;>>;>>;>>>>>>>>>>;>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>>>>>>>>>,>>>>>>,>,>,>,>>>>>>,>>,>>,>,>,>,>>>,>>>,,>>,>>>,>,>>,>>,>,>,>,>,,>,>,>,>,>,>,>,,>,,>,,>,,>,>,,,>,,,>,,>,>,>,,,>,,>,,,>,,,>,,>,>,,,>,>,,,,,,,,,>,,>,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,,,',,',,,,,,,,',,',',',,,,,',',,',,,,,',',,,',',,,',,',,',',',,',',',,,,,,,,,,,,>>>>>>>>>>;>;>;;;;;;;;;;-;;-;-;--;-;;--;--;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;--;;--;-;--;-;-;;-;;;;;;;;>;;;>;>;>>>>>>>>>,>,,,,,,,''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;;>;>;>;>;>;>;>;;>>>;>;;>>;>;;;>>>;>>;>>>>>>;>;>>>;>>>>;>>>;>>>>>>>>>;>;>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>>>,>>,>>,>>>>>,>>>>>>>>>>>>,>,>>>,>>,>>>,>>>,>>>,>,>>>,>,>,>,>,>>,>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>>,,>,,>,>,,>,,>,,,>,,>,,>,,,,>,,,,>,,,,,,>,>,,>,,,,,,,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,',,,',,,',,',,,,,,,,,,,',',,,,,',,',',,',,',,',',',,',,',',,',',',',,',,,,,,,,,,,,,,,>,>>>>>>>>>>>>>>>>>>;>>;>;>>;>;;;>;;>;;;>>>>>>>>;>;>>>>>>>;>>>>;>>>>;;>;;;;>;;;>;>;;>>;>>>;>>>>>>>>>>>>,>>,>,,,,,,,,,,,'''','''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>>;>;>;>>;>>;>;>>;>;>>>>;>;>>>>>;>>;>>;;>;;>>>>>>;>>;>>>>;>>>>;>;>;>>>>>;>;>>>>>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>,>,>,>>>>>,>>>,>>,>>,>>,>,>,>>,,>>,>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,,>,,>,,>,>,>,,,>>,>,,>,,>,,,>,>,,>,,>,,>,>,,,,>,,,>,>,,,,,,,,,,>,>,,,,,,,,>,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,',',',',,,,',,',,,',,,',,,,',',,,',',',',,,',',',,',',,',',',,,,,,,,,,,,,,,,,,,,,,>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>,>>,>>,>,,,,,,,,,,,,,,,',,','',','''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>>;>;;>>;>;>;>;>;>;;>>;>>;;>;>>;>>;>>>>>>;>;>;>>;>>;>;>>>;>>>>>>>>;>>>>>>>>;>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>,>>,>>>,>>,>>,>>>>,>>>>>>>>>>>,>,>>>,>>>,>>,>>,>>>,>>,>>>,>>>,>>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,>>,,,,>,,>,>,>,,,,>,,,>,,>,,,,>,>,,,>,,,,,>,,>,>,,,,,,,>,,,,,,,,,,,>,,>,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,,,,,,,',',,',,',,,,,,,,,,,,',',,',,',',',,,'',,,,',',,,',,,',',',',',',,'',,,',,',,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,>,,,,>>,>,>,,,>,>,>,>,,,,>,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',',,',','''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>;>;;>>>;;>;>>;>;>;>>>;>;>>;>>;>;>>;>>>;>;>;>>>>>;>>;>>>>;>>>;>>;>>;>>>;>>>;>>>>;>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>,>>>>>>>>>>>>>>,>>>>>>,>>>>,>,>,>,>,>>>>,>>,>,>>,>>,>>>,>>,>>,>,>,,>>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,,,>,>,>,,>,,,>,>,,>>,,,>,,,>,,,,,>,,,>,>,,,,,,,,>,,>,,,,,>,,,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,',,',,,,,',,,,,,,',,',',',,,,,,,,,',,,,',',,,',',,','',,'',',,',',,',',',,',',',,',',',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,',',,','','',''''','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>>;>;>>;>;;>;>>>;>;>>;>;>;>>;>>;>>;>;>>;>>;>;>>>>>>;>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>,>>>>,>>>>>>,>>>>>,>>>>>>>>>>>>,>>>,>>>,>>>,>>,>>,>,>,>>,>>>>,>,>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,,>,,>,,>,>,>,,>>,>,,>,,>,,>,,>,,>,,,>,,,>,,,>,>,,,>,,,,,,>,,>,,,,,,,,>,,,,,>,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,',',',',,,',',,,',',,,',,',,,',,,,',,',,',',',',',',,'',,,',,'',''','',,','',',',',',,,,,',,,,,,,',,,,',',',,,,'',,',,',,,',',',',,',,,'''','','','''','''',''','''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;>;>;;>;>;>>;>;>;>;>;>>;>>;>;>>;>>;>>>>;>>;>>>;>;>;>>;>;>>>;>>;>;>>;>;>>>>>>;>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>,>>>>>,>,>,>,>,>>>,>>>,>>>,>>>,>>,>>>>,>,>>,,>>,>,>,>>,>>>,>,>,,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,,>,>,,>,,>,,>,,>,,,,>,>,>,,>,,,,,>,,,>,>,,,,,,>,>,,>,,,,,,,,,,,,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,',,',,,,,,',',',',,,,,,,,',',,,,',,,,',,',',,',,',',',',',',,',',',','',,''','',,',,',','',',,',,',','''''',''''''','''''','''''','''''''''''',''''''''''','''''''''','''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>;>;>>;>;>;>;>>;>;>>;>;>;>;>>;>>>;>>;;>;>>;>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>;>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>,>,>>>>,>>>,>>>>>>>>>>>>>,>>>,>,>,>>,>>>,>>,,>,>>,>,>>,>>>,>,,>,>,>,>>>>,>,>,>,>,>,>,>,>,>,>,>,>>,>,,>,,>,,>,>,>,>,,>,,>,>,,,>,,>,,,>,>,,,>,,,,,>,,,,,,,,,,,>,,,>,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',,',,',,,,,,,,,,,',,,,,,,,,,,',',',,,,,',',,',',,',,,',',',',',,,',',',',,',',',,',',,',,'','','',',','','''','',,',',',,',','',',','',','''',',',',',''''',',''',''''','','',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>;>>;;>>;>;>>;>>>;>;>>;;>>;>>>>>;>>>;>;>>>>>>>>;>;>;>;>>;>;>>;>;>>;>>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>,>>>>>>>,>>>>>>,>>,>,>,>,>,>>>,>>>>>>,>,>,>>,>>>,>>,>>>,>>,,>>,>>>,>,>>,,,,>,>,>,>,>,>,>,>,,,>,>,>,,,>,>,>,,>,,>,,>,,>,,,,>,,,>,,,,,,>,,,,,>,,,,>,,,>,,>,,>,>,,,,,,,,>,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',',',',,,,,,',',',',,,,,,,',',,',,',,,',,',',,',,',,,',',,,',',',,',,,'',','','',',',','',',','',,,'',''',''',''''''',''','',''',','',''''''''',''''','''','''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>>;;>;>;>>;>;>;;>>>;>;>>;>>;>;;>>;>>;>>;>;>;>;>>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>,>>>>,>>>>>>>>>>,>>>,>,>,>>>>>,>>>,,>>,>,>,>>,>>,,>>,,>,>,>,>>>,>,>,>,>,>,>,>,,>>,,,>,>,>,>,>,,>,>,>,>,,>,,>,>,,>,>,>,>,>,,,>,>,,,>,,,,>,,,,,,,,,,,,,>,,,,,,,,,,>,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,,',,,,,,,,,,,,,,',',,,,,,,,,',',',,,,',,,',,',,,',',,',,',,'',,','',',,,'',','',,',',',,',',',',,',''',,'''',',','',,'',',,','','',''',''''''''',',',''''',''''','''','''''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>;>;;>>>>;>>;>>>;>>;>;>>>>;>>;>>>>>;>;>>>;>>>>>>>;>>;>>;>;>>;>>;>>;>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>,>>>>>,>>>,>>,>>>,>>>>,>,>,>,>,>>>,>>,>>>,>,>>,>,>>>,>>,>>,>,>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,,>,>,,>,,>,,,>,,,>,,>,>,,,>,,,,,>,,,,>,,,,,>,,,>,,,,>,,>,,>,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,',,,,,',,',',',,,,,,,',,',',,',',',,,,',,',,',,,,',',,',',',,',',,',',',',',,','','',',,''',,',''',',''',',''',''','',',''',',',','''''',',''''','''''''','',''',''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>>>;>>;>;;>>;>;;>;>;>;>;>;>>>;>>;;>;>>>>;>>>>;>;>;>>;>>>>>>>;>>;>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>,>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>>>>>>,>>,>>,>>,>>,>>>>,,>>,>>,>>,>>>,>,>,>,>>,>>>,>,>,>,>,>,>,>>,>,>,>>,>,>,,>,,>,>,>,,>,>,>,,,,,>,>,,>,>,,>,>,,,>,>,,>,,,,>,,,,,,,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,',,,',,,',,,,',,,',,,,',,,,,,,',',',,',,,',,,,,,','',',',',,'',',,',,',',',,',','',',',','',',,','','',,,''',',,''',','','','',',''''',','''''''',',''''''',''''','','''''''','''','''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;;>;>>;;>>>>;>>>;>>;>>;;>>;>>>>;>;>>>;>;>>;>>>>>>;>>;>>>>>>>>;>>>>>>;>>>>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>,>>,>>>,>,>,>,>,>,>>,>>,>>,>>,>>,>,>>>,>,>,>,>>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,>,>,>,,,>,>,,>,,,>,>,>,,,,>,,,>,,,,,>,,,,,,,,>,,,,,>,,>,,>,>,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,,',,,,,,,',,,,,',',',,,,,,,,,',,',',',',,,,',,,',',,,',',',',',',',,',',,',',',',,',''',',','''',',''',',','','',''',''',',',''''',',','''','','''',','''''''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>>;;>;>>>;>;>>>;;;>>;;>;>>;>>>>;>>;>;>>>>;>>>>>;>>>;>;>>>>>>;>;>>>>>>>;>>>>>>;>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>,>>,>>>>,>>>,>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>>>,>,>>>,>>>,>,>>,>>>,,>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,,>,>,,,>,>,>>,,>,,,>,>,,>,,,>,>,,,>,>,>,>,,,>,,,,,,,,,,,,,,,,,>,,,>,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,',,,,',,',,,,',',,,,,,',',',',,',,,,',,,,',',,'',,,',',,,',',',,',,'',','',',',','',',',',','',,,',',','',''',','',','',''',''',',''''''',','''''','''''',''''','',''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";;>>;>;>>;>;;;>;>;>;>>>;>>>;>;>>;>;>>;>>;>>;;>>>;>;>>>;>>>>>>>;>>>>>>;>;>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>>>>>>,>>>,>>,>>,>>,>,>,>,>,>,>,>>>,>>,>>,>>,>>,>>,,>>,>,>>,>,>,,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,,>,>>,>,,,,,>,,,>,,>,,>,,>,,,,,>,,,,,,,,>,,,,,>,>,>,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,',,,,,,,,,,,,,,,',',,,,,,,,',,',',,'',',,,',,,'',,','',,',,',','',,,,',,',',',',',',','',',,''',',''','',,'',',''''','','',','''',',',''''',',''''''',''','''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>>>;>;>;>;>;>;>;>>>;>;>>;>>>;>>;>>>;>>;>>;>>>;>;>>;>>>;>>;>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>,>>,>>,>>>,>,>>,>>,>>>,>,>,>>,>,>,>,>,>,>,>,>,>,,>,,>>,>,>>,>,,>,,,,,,>,>>,,,>,>,>,,>,,>,>,>,>,,,>,>,>,,,,>,,,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,',,,,,',,,,,,,,,,,,,,,,',,',,',',,',,,,,',',',',,',,,',,,,,',',',',,,',,,,,','',,',,,,''',',',',',',',','',,',''',',''',,'',''',''',',','','','''',','''''',','''''',',',''',''''''''''''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;;>>;>;>>;>>;>;>;>;>>>;>>;;>>>;>>;>>;>>>>>>;>>>>;>>;>>>>>>>;>>>>>>>>>>>;>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>>,>>>>>>>,>>,>>,>>,>,>,>,>,>,>,>,>>,>,>>,>,>>,>>,>>,,>>,>,>>,>>,,>,>>,>,>>,>>,>,>,>,>,>,>,>,>,>,,>,,>,,,>,>,>>,>>,,>,,>,>,,,,,>,,>,,,,,,,,,>,,,,,,,>,,,>,,,>,,,>,,,>,,,,,,,,,,>,,>,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,,,,,,,,,,',,',',,,,,,,,,',,,',,,',',,',,',,'',,'','',,,',','''',,,',',',',',',',',''',',,','',,''','',,'',,'',''','','',',''''',',''''','','''''''''''','','','''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>>;;>>>;>>;>;>>;>>;>;>>>;>>>;;>>;>>>>>;>;>;>>;>;>>>>>>;>>;>>>>;>>>>>;>>>>>>;>>>>>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>,>>>>>,>>>>>>>>>>>>>>>>>>>,>>>>,>,>>,>>,>>,>>>,>>>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,>,>,,,,,>,,>,,>,,,>,>,>,,>,,>,>,>,>,,,>,>,>,,,,,,,,>,,,>,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,',,,,,,,,',',',,,,,,',,,,',',',',,,',',',,',,',,',,',,,',,',,',',',',,,,,'',',',',',',',',',,'','','','',','',''',''','',''','',''',',','''',',''''''',''','','''''''''''',''''',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;>;>>;>>;;>;>;>>;>;>;>>;>;>;>>;>>>>;>>;>;>>>>>>;>>>>>>>>;>>>>>>;>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>,>>>>>,>>,>,>,>,>,>,>,>>,>,>>>>,>>,>>,>>,,>>,,>>,>>>,,>>,>>,>,>,>,>,>,>,>,>,>,>,>>,,>,,>,>,>,>,,>>,>,,>,>,,>>,,>,,,>,,,>,,,,,,,,>,,,,,,,>,>,>,,,,,,,,>,,,,,,,>,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,',,,,,,,,,',,',',,,,,,,,',',,,,,',,,,,,,,',',,,,,',,',,',,',,',',,',,',',',','','',,',',',',',',',','',,'',',,','',','',,'',',''',','',''','''''''',''''','',''',''''''''''''''',''''','''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>>;;>;>>;>>;>;>>;>>;>;>>>;>;>>;>;>>;>>>>;>;>;>>;>;>>;>>>>;>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>>,>>>>>>,>>>>>,>>>>,>>>>>>>>>>>>>>,>>>,>,>>>,>>,>>,>>>,>>>,>>,,>>>,>,>,>>,>>>,>,>,>,>,>,>,>,,>,>,>,>,,>,,>,>,,>,>,,,>,,,,>,,>,,,>,,,>,>,>,>,,,>,>,,,,,,,,,>,,>,,,,,>,,>,,,,>,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,',,,,,,,,,,,',,,',,,,,',',,,',',',,,,,',',',,,,,',,',',',,',',',',,,',,,,',,,',',',',',',',','','',',','',',''',,''',','',','',''',','',',',''',',''',''''''','',','','','''''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;;>>;>;>>;>>;>>;>>;>;>>;>>;>>;>>>;>>;>;>>;>>>>>>>>;>>>;>>>;>>;>>>>>>>;>>>>>>>;>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>>>,>>>,>,>>>>,>>>>>,>,>,>,>,>,>>>,>>,>>,>>,>>>,>,>,>,>,>,>>>,,,>,>>,>,>,>,,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,,>,>,>,>,>,,>,,>,>,>,>,,,,,,,,>,,,,,>,,>,,>,,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,',,,',,,,,',,,,,,',,,,',,',',,,,',,',',,',,,',,',,',,,',',','',',''',',',',',',',',',',',',',','',',,''',,'','',''','',',''',''''''','''','''','','''''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>>>;>;>;;>;>;>>;>;>;>>;>>;>>>;>>;;>>;>>>>>>>;>;>;>;>>>>>>;>>>;>>;>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>,>>>>>>>>>,>>>>,>,>>>>>>>>>>>>,>>,>>>,>>,>>,>,>>,>>>,>,>>,,>>>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,,,>,,>,>,,>,>,,>,,,>,,,>,,,,,>,,,,,>,,>,>,>,,,,>,>,,,>,,,,,,,>,,,,>,,,,,,,,,,,>,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,',,,,,,,,,,,,',,,,,',',,,',,,,,,',,',',,',',,',,'',,',,',,'',,',',,,',',,,',',',',',',',',',',',''',',,''''','''','','',''','''','',',',',''',''',''''''','','''',''''',''''','''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;;>;;>;>;>>;>>;>;;>>;>>;>>;>>;;>>;>>>>;>>;>;>;>>>>>>>>>;>;>>>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>,>>>,>>>>,>>>>>>,>,>,>,>>,>>,>>>,>>,>>>>>,>>,>,>,>>>,>>>,,>,>,>,>,>,>,,>,>,>,>,>,>,>,>,>,>,>,,>,>>,>,>,,>>,,>>,,>>,>,,,>,>,,,>,,,,,>,>,,,,>,,,,>,,>,,,,,,,,,>,,>,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,',,',,',,,',,',,,,',,,',',',,,',,,',,,,',,',,,',',',',,,'',',',',',',',',',',',',',','','',',,'','',',,',',,',','','','',','',''''''''','','''','',''''''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>;>;>;>;>>>>>;>;>;>;>>;>>>;>>;>;>>;>>>;>>>;>;>;>>>>>>>;>;>>>;>>>>>>>;>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>,>>>,>>>>,>>,>>>>>>>>,>>,>>,>,>,>>,>,>>,>,>>,>>,,>>,>,>>,>>,>>>,>,>>,>,>,>,>,>,>,>,,>,>,,>>,>,,,,>,,>,,,>,,,>,,,,>,>,,>,>,,,>,>,,,,,>,>,,>,,,,,,,>,,>,>,,,,,,,,,,,,,,>,,>,,,,,,,,>,,,,,>,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,,,,',,,',,,,,',,,,,,',,',',,',,,,,,,',',,',,',',,',,',,',,,',,',,,',,',',,',',',',',',',',',',',',','',',',','''',''','',''','',''',''',',',','''''','''''''',','''''''''',''','''''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>;>;>;;;>;>;>>;>>;>>;>;>>;>>>;>>>;>>>;>>;>>>;>;>>;>>>>;>>>>>>>;>>>>>>;>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>,>>>>,>>,>>,>>>>>>>>,>>>,>>>>,>,>,>>>>>>,>>>>>,>>,>,>>,>>,>,>>>,,>>,>,>,>>,,>>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,,>>,,>,,>,>,>,>,,>,>,,,>,,>,,>,,,,,>,>,,,,,,,,,>,>,,,,,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,',,,,,,,,,,',,,,,,',,,,,,,,,,,,,,',',',,,,',,',,,',,',',',',',,','',',',',',,',,',',',',',',',','',',',','',''',,','','','',,'','','',',''''''''',',''','',','''''','','''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>;>>>;>>>>;>>;>;>;>>;>>>>;>;>;>>;>>>;>>>>>>;>>>>>>>>>>;>>;>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>>,>>,>>>>>>>>,>,>>>>>>,>,>,>>,>,>>>,>>>>,>>,>>>,>,>>>,>,>,>,,>>,>,>>,>,>,>,>,>,>,>,,>,,>,>>,>,>,,,>,>,>,,>,,>,>,,,,>,,>,,,>,,>,>,,,,,>,>,>,,>,,,,,>,,>,,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,',,,,,,',,',,,',,',',',',',,,,,,',',,',,',,,',,',,',,',',',,,',,',','',',',',',',',',',',',','',',',',','','',','','''','','',''',',',',','''',''''''''','','''''',''''',''''','''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;;>>;>;;>>;>;>>>;>>>;;>>;>>>;>>>;>>>;>;>>>;>;>>;>;>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>,>>,>>,>>>>>,>,>>>>>>>,>>>,>,>>>,>,>,>>,,>>,>,>,>,>>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,>>,,>,,,>,>,>,,,>,>,,>,,,>,,>,,,,,>,>,,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,',',',,',,',,',,',,',,',,',,,,',,',,'',,',,,',',',',',',',',',',',','',',',','','','',',',','',''','',''''''''''',''',',''',''''''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>;>>;>;>>>>;>;>>;;>>;;>>>>>>;;>>;>>>;>>;>>;>>>>>>>>>>>;>>>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>,>>>>>,>>,>>>,>,>>>>>>,>>>,>,>>>>,>,>,>>,>,>>>,>,>>>,>>,>>>,>>>,>>>,,>>,>,>,>>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,,>,,>>,,,>,,>,,>,,>,,>,,>,,,>,>,,,,,>,>,>,>,,,,,,,,,,,>,,,,,>,,,,,,,,,,,,>,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,,,',,,,',,,',',,',',',',',',',,,,,,,',,',,',,',,',,',,',','',,','',,,',',',',',',',',',',',',''',',','',','','',',','','','''',''','',',',',',''',''''','''','','''',''',''''''''''''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;;>>;>;>;>;;>>>;>>>;>>>>;;>;>>>;>>;>>>;>>>>>>;>;>;>>;>>>;>>;>;>>>>>>;>>;>>>>;>>>;>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>,>>>>>,>>>>>,>>>>>>>,>>>>,>,>>>,>,>>,>,>,>,,>>,,>>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>>,,>,,>,>,>,>,>,,,>,>,,>,>,,>,,>,,>,,,>,,,,,>,>,,,,,,,,>,,>,>,,>,,,,>,,,,>,,>,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,',,,',,,,',,,,,,,,,,,,,,,,,,,,,,,,,,,',',,,',,',,',,',,',',',,',,',',,,','',',',,,',',',',',',',',',,'',',','','',','',''','','',',',',''',''''''''',''',',''''',''''''''''''''''','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;;>;>>;>;>>;;>>;;>>;>;>>>>;>;>>;>>;>>>;>;>;>>>>>>>>>;>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>,>>>>>,>,>>>,>,>>,>,>,>>,>,>>,>>,>>,>>,>,>>,>>>>,>>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,,>,,>,>,>,,>,>,>,,>>,,>,>,,,,>,,>,,>,,>,>,,>,>,,,,>,>,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,',,',',,,,',,',',',',,,,,',,,',,,,,',,',,',,',,',,,,',',',,',','',',,',',',',',',',''',','',',',','',',',',','',''',''',','',',',',''','''''',','''',''',''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>;>>;>;>>;>>;>>;>>>;>>;>>;;>>>>;>>>>>;>>>;>>>;>>;>>;>>>>>>>>>>>;>>>>>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>,>>>>,>>>>>>>,>>>>>,>>>>>>,>>>>>>>>>>>,>>>,>>>,>>,>>>,>>>,>,>,>,>>,>,,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,,>,,,>,,>,>,>,,>,,>,,,>,,,>,,,,,,>,,,,,,,,>,,>,,>,,,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,',,,',,',,,,,,',',,,',,,',',,',,',,,',',,'',',',,',',,,',,',',',',',',',','',,,'',',',',''',',''','',',''','''',''',''''''''',''',',''''''','','''''''''',''''''',''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;;>;>;>>>;>;>;>;>;;>>>;>>;>>>;;>>>;>;>>>;>>>;>>>;>>>>>>;>>;>>;>>>>>>>>;>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>>,>>>,>>,>>>,>>,>>>,>,>,>,>,>>,>,>>,>>,>>,>,>,,>>>,>>,>,>,>>>>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,,>,,>>,,>>,,>>,,>,,,>,>,,,>,,>,>,,>,,,>,>,,,>,>,>,,,,,,,,,,>,,,,,>,,,,>,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,,,,,,',,,,,,,',,',,,,',,,,,,',',,,,,'',,',',,',,,',,'',',,',,,',,'',,','',',',',',',',',',',',''',,',',','',,'''',,'','''',,'',','','',',',',',''',''''',''','''''','',''','''','''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>;>;;>>;>>;>>>>;;>>>;>>;>>;>;>>;>>;>>;>>>;>>>>;>>;>>;>>>>>;>>>>;>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>,>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>,>>,>>,>>,>>>>,,>>>,>>>,>,,,>>,>,>>,>,>,>,>,>,>,>,>,,>,,>,>,>,>,,>,,,>,,,>,,>,>,,,,>,,,>,,,>,,,>,,,,,>,,,,,,>,,>,,>,,,,,>,,,,,>,,,,,,,,,>,,>,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,,,,,,,',,',,,,,,,',,,,',',',,,,',',,,,',,,',,,',,,',,,,',,',',',,',',',,,',,',',',',',',',',',,''',''',',''',,,''',',',,'''',''','',''''''''''','''',''','''''',''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;;>>>;>;>;>;>;;>>>;;>>;>>>>>>;>>>;>>;>>;>>>;>>>>;>>>>>>>;>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>,>>,>>>,>>>>>>>,>,>>,>,>,>,>>,>,>,>,>,>>>,>>>,>>,>>,>>,,>>>>,,>,>,>,>>>,>,>>,,>,>,>,>,>,>,>,>,>>,,>,>,>,>,>,>,>>,,>>,,>,>,>,>,>,>,,,>,,>,>,,,>,>,,,>,>,,,>,,>,,>,>,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,',,,,,,,,,',,',,,,,,,,,,,,,,',,',,,',',,',,'',,',',',',',',,',,',',',,'',',',',',',',',',',''',,,'',,',',','''',',''','',','',''','',',',',',''',',''''''','',''''',''','''',''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>>;>;>>>;>>>;>>>;>>>>;>>;;>;>>>;>>>>>>>>>;>>;>>>>>>;>>;>>>>;>>>>>;>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>,>>,>>,>>,>>>,,>,>>>,>>,>,>,>,>,>>>,>,>,>,>,>,>,>,>,,>>,,>,,>,,>,>,,,>,,,>,,>,,,>,,,,>,>,,>,,,,,>,,,,,>,,,,>,,,,,,,,,,,,>,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',',,,,,,',,',',',',',',,,,,,',,,',,',,,,',,,',',,',,',,',,',','',,',',',',',',',',',',,'''',,'',',','',',''',,''',''',',','',''''''''''',''''','','''''''','''''''',''''''',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>;>>;>;>;>;>;>;>>;>;>>;>>>>;>;>>>;>;>;>;>>>>>;>;>>>>>>>>;>>>>>>>>>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>>>>>>,>>>>>>>>,>>,>,>>>,>,>,>,>,>,>,>>>>,>>,>>>,>>,>>,,>>>,>,>>>,>>>,>,>>,>,,>>>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,>>,,>>,,>,,>,>,,>,,,,>,,,>,>,,>,>,>,,,>,,,,>,,,>,,,,>,,,,,,,,,,>,,,,>,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,,,,,,,,,,',',,,,,,,,,,,,,,,,',',',,',,,',,',',,',',,',,,',',',',',,,,',,',,,',',',',',',','',,',''',',','',',',',''',,'','''''',''',',',',',''',','''''','','','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>;>;>>;>;>;>;>;>>;>>;>>;>;>>>;>;>>>>>>>;>;>>>>>;>>;>;>>>>>>>;>>>;>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>,>>>>>>>>,>>>>>>>>,>>>>>>>>>>>>>>>,>,>>,>>>,>>>>>,>>>>,>>,>,,>>,,,>>,>,>,>>,,,>,>,>,>,>,>,>,,>,>,,>,,>,>,>,,,>,,,>,,>>,,,>,,>,>,,>,>,,,>,,,,,,,>,,,>,,,>,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,',,',',',',',,,,,,,',,',,,',,,',,',,',',',,',,',,,''',',',''',',',',',',','','',',,,',''','','','',,'''','',,','',',''''''''',''''','','''''''''''',''''''''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>>;>>;>;>>>;>>>;>>>;>>;>;>>;>>>>>;>;>;>>>>>>;>>>>>>>>>>;>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>,>,>>>>>>,>,>,>,>,>,>,>>>,>>>,>,>,>,>,>,,>,>,>>>>>,>>>>,>,>,>,>,>>,>,>,>,>,>,>,>>,>,>>,>,>,,>,>,>,>,>,,>,,,>,,>,,>,,>,,,>,>,,,>,>,>,,,>,,,,,,,>,,,,,>,,,,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,',,',,,,',,',',,,,,,,,,,,,,',',',,,',,',,,',,,',,',,,',',,,',''',,,,',',,,,',',',',',',',,',','''''',',','','','''',,''','''','','',',',',''',',''''''',','','','''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;;>;>;>>;>;>;>;>>;;>>>;>>>;>>>;>;>>;>>>;>;>;>>>>;>;>>;>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>,>>>>>,>>>,>>>>>>>>>>>>>>>,>>,>,>>>>,>>>,>>>>>>,>,,>,>,>,,>,>,>>,>>,>,>,>,>,>,>,>,,>,,>,,,>,>,>,,>,,>,,>,>,>,>,>,,>,,,>,,>,,,,,>,,,,,,,>,,,>,,>,,,,,>,,,,,,,,,,,,,>,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',',,,,,,,,,,',,,,,,,,,',,',',',',,,,,',,',,',',',,',',',,'',,',',',,,,,'',',','',',',',',',',',',',',',,,',',',','',',',,'',','',','','',''''''''',''''','',''''','''''''''',''''''','''''',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>;>>;>>;>;>>>;>>>>;;>>;>>>;>>>>>>>>;>>>>>>>>;>>>>>;>>;>>>>>>>>>;>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>,>>>>>>>>,>>>>,>>>>>,>>>,>,>,>,>,>,>,>>,>>>,>,>>>,>>,>,,,>,>>>>,>>,>>,>>>,>,>,>,>,>,>,>,>,>,>>,,>,>,>>,,>,>,>,>,,>,,,>,,>,,,>,,>,,,>,>,>,>,,,>,>,,,,>,,,,,,>,,>,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,',,,',,',,,,,,,,,,,,,,',',,,',,',,,,,',,',,,',',,',,,',','',',,',,',,',',',',',',',''',','','',',',''',',''','',''','','','''',',',','''',','''''',''''''',''',',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;;>>;;>;>>;>;;>>;>;>>>>;>;>;>;>;>;>;>>>;>;>;>>>>;>>>>>>>>>>>>>>>>>;>>;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>,>>>>>,>>>,>>>>>>>>>>>>>>>,>>>,>>>>,>,>>,>>>>,>>,>,>>,>,>,>,,>,>>,>,>,>,>,>,>,>,>,,>>,>,>,>,>,>,>,,,>,,>>,,>,,>>,,,,>,>,,,,>,,,,>,,,>,>,,,>,,>,,,,,,,,,,,,,,>,,>,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,',',',',',,,,',,,',,'',',,',,',',,,,',',',,,',,',',',',',',',',',',',',,','',','',',',',','',',','',','','','',','''''''',','''','',''','',','','''''','''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>;>;>>>;>;>>>>;>>>;>;>;>>>>;>>>;>>>>;>>>>>>>;>>>>>;>>;>>>>;>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>>>>,>>>>>>>>>,>,>,>,>,>,>>>>,>>,>,,>>>,>>,>,>>,>>,>,>,>>,>,>>,>,>,>>,>,>,>,>,>,>,>>,,,>,,,>,,>,>,,>>,>,>,,>,>,,,,>,>,,,>,>,,,>,>,,,>,,,,>,,,,,,,>,>,,>,>,,,,,,,,,,>,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,',,,,,,,,',,',,',,,,,,,,,,,,,,,,',,,',,,',,,,,',,',,','',',,',,'',',',,',',',',,',',',',',',',',',',',',''','',','',''',''',''','','',',',',','''',''''''''''''''''''''''''''','''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;;>;>>;>;>>;>;;>>;;>>;>>>;>;>>>;>>>>;>>>;>;>>>>;>>;>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>,>>>>,>>,>>>>>>>>>>>,>>>>,>>,>>,>>>>>>>>>>>>,>,>>,>>>>>>,>>>,>,>,>>,>>,>>,>,>,>>,>,>,>,>>,>,>,>,>,>,>,,>>,,>>,>,>,>,>,,,>,,,>,,>,>,>,,>,,>,,>,,>,,,,,>,,,>,,,>,>,>,,,,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,',,',,',',',',',,,',,,',,,',',,',,',,,,',,',,',,,,',',',',',,',',',',',',',','','',',',',','',''','',,'',,''',''''','''''''''''',''',','','','','','''''''''''''''''''''',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>;>;>>;>>>;>>>;>>;>>>;>;>>>;>;>>;>>;>>;>>>>;>>>>;>;>>>>>>>>>>>;>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>>,>>>,>>>>>>>>>,>,>,>,>,>,>>>,>>,>,>,>>,>,>>>,>>,>,>>,>>,>,>>,>,>>>,>,,>,>,>,>,>,>,>,>,,>,,>,>,,,>,,>,,>,>,,>,,,>,,>,,>,,>,,>,,>,>,,,,>,,>,,,,,,,,>,,>,>,,,>,,,,>,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,,,,,,',',,',,,,,,',,,,,,,,,,',,,',,',',,,',,,',,'',,,',,',',',',,',',,,',',',',',',',',',',',,',''',',',',',,'',''',''',',',',''',',',',',',''','''''''''','''''','',''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>>>;>;>>;;>>>;>>;>>;;>>>>>;>>>>>>>;>>>>>;>>>>>>;>>>>>>>>;>>>;>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>,>>>>>>>>>,>>,>,>>>>>>>>>>>>>>>>,>>>>,>>,>>>,>,>>,>>,>,>,>>,>,>,>>,,,>>>,>,>,>,>,>,>,>,>,>,>,,>,>>,>,>,>,,>,>,,>>,,>,,>,,>,,,,,>,,,,>,>,,,,,,,>,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,',,,,',,,,,,,',,,,',,,,,,',',',',,,',,,',,,',',,',,',,,',',',,',',,',',',',',',,',',',',',',',',''',',',','',''''','',',',',''''','','','''''''''','''',',',''''''','''''',','','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>;>;>;>>>;>;>>;>>;>>>;>;;>>>;;>;>>>;>;>>>>;>;>>>>;>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>,>>,>>,>>>>>>>>,>,>,>,>,>,>,>>>,,>>>,>>,>,>>,>,>,>>>,>>,>,>,>,>,>>>,,>,>,>,>,>,>,>,>,>,>,>>,>,,>,,>,,>,>,,>,>,,>,,,>,,,>,>>,,>,>,,,,,>,>,>,,,,,,,>,,>,,,,,,,,>,,,>,,,>,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,,,',,,,,',,,,,,,',,,',,',,,,,,,,,',,,',,',,,,,',,',,'',',,,',,',,',',',,',',,'',',',',',',',',',',',',','',',',,',',',''','',',''','','',',',','''',','''''',','',''''',''''''''',''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;>>>;>;;>;>>;>>;>>;>;>>>>>;>>>;>>;>>>>>>;>>>>>;>>>;>>>>>>;>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>>>>,>,>>,>>>>>>>>>>>>>,>,>>>,>,>>,>>>,>>,>>>,,>>,,>>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,,>,,,>,,>,>,,>,>,,,>,,>,,>,>,,,>,,,,,>,,,,,>,>,,,,,,>,>,,>,,,,,,>,,>,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,',',',',,,',,',,','',,',,',,,,,'',',',,',',,',',',',,,',',',',',',','',','',',',,'','','',''',','','',','','','''''''',','''''',''''''''''','''''''''''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;;>>>>;>>;>>;>>;>>>>;>;>>>>>>>;>>>;>;>>>>>;>>>>;>>>>>;>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>>>>>,>,>,>,>,>,>>>>,>,>>>>,>>,>,>,>>,,>>>,>>>,,>,>>>,>,>,>>,>,>,>,>,>,>,>,,>,>,>,>,>,,>,>,,,>>,,>,,>,,,>,>,>,>,>,,>,>,,,,,>,>,>,,,,,,,,>,>,,,,,,,>,,,,,,,>,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,',,,,,',,,,,,,,,,',,',',',,,,,,,,,,',,',,',,,,,',,',,','',,,,',,',',,',',',','',',',',',',',',',','',','','','','','',,','','',''','',''',',',','''',',''''','','',''''''''','','''''',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>>>;;;>>;>>;>>>;>>;>;>>>>;>;>;>>>;>>>>>>;>>>>;>>>>>;>>>>>;>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>,>>,>>>>>>>>>,>>,>>>>,>>>,>,>>>>>>>>>>>>>,>,>>>,>,>>>,>>>,>,>>>,,>>,>,>>,>,,>>,>,>,,>,>,>,>,>,>,>,>>,>,>,>,>,>>,,,>>,,,>,,>,>,>,,>,,,>,,,>,,,,,>,>,,,,,,,,>,,>,,,,,,>,,>,,,,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',',,',',,,,,,,,,,',',',',',,,,,,',,',',,',,',',,,',',',',,,'',',',,,',,',',',',',',',',',',,',',',',',',',',''''','',''','',''',''''''''',''''','',''''''''','''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>;;>>>>>;>>;>>;;>>;>;>>;>;>>>>>>;>>>;>;>>>>;>>>>;>>;>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>,>>>>>,>,>,>,>,>,>>>>,>>,>>,>>>,,>>>,>,>>>,>,>,>,>>>,,>,>>,>>,>,>,>,>,>,>,,,>,,>,,>,>,,,>>,,,>>,>,>,,,>,,,,>,,,>,,,>,>,,,,,>,>,>,>,,,,,,>,,,,,>,,,,,,,,,,,,,>,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,',',,',,,,,,,,,,,,',',',,',,,',,,',,',',,',',,,',',,',,,''',,',',',',',',',',','''','','',',''',''',',,,'','',',''',',',',',','''',','''''''','',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;;>>>;>;>;>;>>;>>>>;>>>;>>>>;>;>;>>>;>>>>>;>>>>;>>>>>>>>>;>>>>;>>;>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>,>>,>>>>>>,>,>>>>,>>>>,>,>>>>>>>>>>>>,>,>>,>>,>,>,>>,>,>,>>,>,>>>,>,>,>,>>>,>,>,,>,>,>,>,>,>,>>,>,>,>,>,,>>>,,,>,,,>,,,>>,,>>,>,,>,,>,>,,,,>,>,,,,,,,,,>,>,,,,>,,,,,>,,,>,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,',,,,',,,,,,',,',,,,,,,,',',',',',',,,,,,',,',',,',,',,,',',,',',',',','',,,',',',',',',',',',',',,,',',','',',','',','''',''','',','',''''''''',',''''','',','''''',''''''''','''',''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;;>;>;>;>>;>>;>;>;>>;>>;>;>>>;>>;>>;>;>>>>>;>>>>;>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>,>>>>>,>>>>>>>>>>,>,>,>,>,>,>>>,>>>,>>>>>,>>>,>>>,>,>>,,>,>>,>,>,>,>>,>>,>,>,>,>,>,>,,>,,>,,>,,>,,,,>,>,>,,>,>,,,>,,,,,>,>,,>,,>,>,,,,,>,>,,>,,,,,,>,,,,>,,,,,>,,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,,',,,,',,,,,,,,',,',,,,,,,,,,,,,,,',',,,',,,,',,',,'',,',',,,',,,',',,',',',',,',',',',',','','''','',',,','',',','',','',,'',''',''',',',',''''',','''''''''',',''',''',''''','''''''''''','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>;>>>;>;>>;>>;>>>;>;>;>>>>;>>>>>;>>>>;>>;>>>>;>>;>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>,>>,>,>>>>>>>>>>>>,>>,>,>>>,>,>>,,>>,,>>>,>,>>>,>,>,>,>,>,,>>,>,>,>,>,>,>,>,>,>,>>,>,>,>>,>,,>,>,>,,>>,,,>,>,,,,>,,>,,,,,>,>,,,,>,,,,,>,,,,>,,,>,,,,,,>,,,,,,,,,,,>,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',',,',,,,,,',,',',',',',',,,',',,',',,',,',,,,',,,'',,',',,',',',',,',',',',',',',',,',,',','','',','''','',',',''',''','',','''''''',','''''','','',''''''''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;;>;>;>;>;>>;>>;>;>>>>>;>;>>>;>;>>>;>;>>>>>>;>>>>>>>>>>>;>>>>;>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>>>>>,>>>>>,>>,>>>>>>>,>,>,>,>,>,>>,>>>,>,>>>,>>>>,>>>,,>>>,>,>,>,>>>,>>,>>,,>,>,>,>,>,>,>,>,,>,,>,>,>,,,,>,,>,,,,>,,,>,,>,,>,>,,>,,>,>,,,,,>,>,,,>,>,,,>,,,,,,,,>,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,,,,,,,,,,,,,',,,,',,,,',,,',,'',',',',,',',',',,',',,',',',',',',',','','',',',,','','',,',',''','',''',''','''',',',','''',',','''''''''',''','',''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;>;>>>;>>;>>;>>;>;>>>>>;>>>>>;>>>>>;>;>>>>;>>>;>>>>>>>;>>>>>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>,>>>,>>>>,>,>>>>>>>>>>>>>,>>>,>>,>>,>>>,,>>,,>>>,>,>,>>,>>,,,>,>,>,>>,>,>,>,>,>,>,>,>>,>,,>,>,>>>,,>,>,>>,,>,>,>,,,>,,,>,,,,,,,,>,>,,,,,>,,,,,,,,,,>,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,',,,,,,,,,',',,,,',,',',',',',',',,,',,',',,',',,',,,',,,',,',,,',','',,,'',,',',',',',',',',',','','',',,'',''''',','',''',',',''',',''''''''',''''''','','',''','''''''''','','''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>;>;>>;>>;>>;>;>>;>;>>>;>;>>>;>;>>>>>>;>>>>;>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>>>>>>>,>>>,>>>>>>>,>>>>>,>,>,>,>,>,>>>,>,>>>>,>>,,>>>,>>>,>>,>>>,>,>,>>>,>,>>,>,>,>,>,>,>,>,>,,,,>,,>,>,,,,,,>,>,,,,>,,>,,,,>,,>,>,,>,>,>,>,,,,>,>,,,,>,,>,>,,,,,,,,,,,>,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,',,,,,',,,',',,,,,',,,,,,,,,,,,,,,,,,',,',,,,',,,,',,',',,'',,',,'',',,',,'',,',',,',',',',',',',','',','',''',',',,','',',','',''',','''',',',',''',',''''''''''''''''''''',''''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;;;>>;>;>>;>>;>>;>>;>>>;>>>;>>;>>>>>>>>;>>>>;>>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>,>>>>>>,>>>>,>>,>>>>>,>>>>>>>>>>>>>>,>>>>,>,>>,>>>>,>>,,>,>,>,>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>>,>,>>,>,>>>>,>,,>,>,>,>,,>,>,,>,,,,>,,>,,,,,,>,,,,,>,>,,,,,,,>,,>,,>,>,,,>,,>,,,>,,,,>,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,,,',,,,',',,',',',',',',,,',,'',,',',,',,',',,,',,',,,,',',',,',',','',',',',',',',',',,'',',',,'',''','',','',',''','''',',''''''''',''''','','',',','','',''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>;>>>;>>;>>>;>>;>;>;>>;>>>;>>>;>;>;>>>>;>>>>;>>;>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>,>>>>>>>,>,>>,>,>,>,>,>,>,>>,>,>>>,>>>,>,>,>,>>>,>>>,>>,>>,>,>,>,>>,>,>,>,>,>,>,>,>,,>,>,,,,>,,,,,>,>,,,>,,,>,>,,>,,>,>,,,>,,>,>,,,,>,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,',,,,',,,',,,,',,,,,,,',,,,,,,,,,',,',,,,',,,',,,',,,',',',','',',',,'',,',,',,',',',',',',''',''',',','',',','','','','''','',','','',',',',''',',''','',''''''''''''',''','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;;>;>;>>;>>;>>>;>>>>>>>>>;>>>;>>>>>>>;>>>>;>>>>>>>>>;>>>>>>;>>>>>>>;>>>;>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>,>>>,>>>,>,>,>,>>,>,>,>>,>,>,,>,>,>,>,>,>,>,>,>>,,>,>>,>,>>,>,,,>>,,>>,>,,>,,>,,>,,>,,>,,,,>,>,,,,,,>,>,,,,>,,>,>,,>,,,,,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,',,,,',,',,,,',',',',,,',,',',,,',,,',,'',,',,',,,,',,',',,,',',','',',',',',',',,',',,','',',''',','','','',','','',','','''''','','''','''''''''','',''''''''''''''''''',''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>;>>>;>>;>;>;>>;>;>;>;>>>;>>;>;>>;>>>;>>>>;>>;>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>,>>,>>>,>,>>>>>>>>,>>>,>,>,>,>,>,>,>>>,>>,>>,>>>,>,>>,,>>>,>>,>,>,>,>>,>,>>,>>,>,>,>,>,>,>,>,,,>,>,,>,,>,,>,,>>,,,>,,,,>,,,>,,,,,>,,>,,>,>,,,,>,>,>,,,,,>,,,,,,,,,,,,,>,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,',,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,',,,',',',',,',,,',,',,'',,',',,''',',',',,',',',',',','','','',',',',',''',,',',',''',''','''','',','''',''','''','','',''''''',''''','''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;;>>;>;>>;>>>;>>;>>>>>;>>;>>;>>>>>>>>>>>>;>>>>>>;>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>,>>,>,>>>>,>>>>>>>>>>>>>>>,>>>,>>,>>,>>,>,>>>,,>>,>>,>>>,>,,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,,>,>,>,>,>,>,,>>,>,,>,,>,,,,,,>,,,,,,,,>,,,,>,,>,,>,,>,,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,',,',',,',',,,,',',',',,,,',,',',,,',,,',,'',',',',,',',,',',,,',',,',',',',',',',',',',',',','',''',,''',''','',',',''','',''''',',''',''',''''''''''',',''''','''','',''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>;>;>>;>>;>>>;>>;>;>>>;>>>>>;>;>;>>;>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>,>>>>>>>>>>>>,>>>>,>,>,>,>,>,>,>>,>>>,>>,>>,>>>,>,>>>,>>,>>,,>,>>>>,>,>>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,,>,>,,,>,,,,,>,,,>,,>,>,>,,,>,>,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,',,,,,,',',,',,,,',,,',,',,,,',,',,',,,'',',',',',,',',',',',',',',',',',','',',',',''','',','',''''',','','',',''''',''','''',','','',''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;;>>>>;>>;>;>;>>;>>>>;>>>;>;>>>>>>;>>>>>>;>>;>>>>>>;>>;>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>>,>>,>>>>>,>>>>>>>>>>>>>>,>,>,>>,>>,>>>,>,>>,>,>,>,>,>>>>,,>,>>,>,>,,>,>,>,>,>,>,>,>,>,,,>,,>,>,>,>,>,,>,,>,,>,,>,>,>,,>,,>,,,,,,,>,,,,,,,>,,,,,>,,>,,>,,,>,,,,,>,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,',,,',,,,',',,',',,',,,,,,,',',,,,',,',',,,',',,','',,',,',,'',,,',',',,,'',',',',',',',',',',''',','',',',',','','',','',','''','',''''',',''',''','''''''''''''','''''''''',''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>;;>>;>>>>;>>;>>;>;>>>;>>>>;>;>>>>>>;>>>>>>>>;>>;>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>>>>>>>>>>>>>>>>,>,>>,>,>,>,>,>,>,>>>>>,>>>,>>,>,>>,>>,>>>,>>>,>,,>>,>,>,>,>>,>,>,>,>,>,>,>,,>,,>>,>,>,>,,>,,,>,,>,,>,>,,,>,,,,>,,>,,>,>,>,,,>,>,>,,,,>,,,,,,,>,,,>,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,',,,,,,,,,,',,,,,,,,,,,,,',',,',,,,',,,,',,,',',,,,',,,,,',,',',,,,'',',,','',,',',',',',',',',','',,',',','',''','',',','','','',','','',',''''',''',''','',',',','',''','''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;;>>>;>>;>;>>;>>;>>>>>;>>;>;>>>>>;>;>>>;>;>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>,>>>,>>>>,>>,>,>>,>>>>>>>>>>>>>>>>>>>>,>,>,>>,>>,>>>,>,>,>>,,>>,>,>,>>,,>>,>>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,,>,>,,>,>,>,>,,,>,>,,>,>,,>,,,,,,,,,,>,,,,,,>,>,,,,>,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,',',,,,,',,,',,,',',,',',,,',',,'',',',',,,'',',,',',,',',',,',',',',',',',',','',','',',',',','',''','',''',''',''','''',',''',''',''''''''''''''''''''''',''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>;>>;>>;>;>>;>>;>;>>;>>>>>;>;>>>>>;>>>>>>>>>>>;>>>>;>>>>>>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>,>>,>,>,>,>,>,>,>,>>>,>>,>>,>>,>>,>>>,>,>>,>,>,>,>,>>,>,>,>>,>,>,>,>,>,>,>,>,>,>>>,>,>,>,,>,>,,>,,,>,>,,,>,,,,>,,>,>,>,>,>,,,>,>,,,,,,,,>,,,,,>,,>,,,,,,,,,>,,,>,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,,,,',,',',,,,',,,,,',',,',,,',,,,,',,,,',,',,',,,',,',,'',,,',',,,'',',,,',',',',',',',','',','','',',','','','',','','',,'','',',''',''''',''','''','''','','','''''','''''',''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;>>;>>>>;>>;>>>>;>>>;>;>>>>>;>>>>;>>>;>;>;>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>,>>>,>,>>,>,>>>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>,>>,>,>>,>>,>>>,>>,>,>,>,>,>,,>,>,>,>,>,>,>,>,,,>,,,,,>,,>,>,,,>,,>,>,>,,>,,>,>,,>,,,>,,,,,,,>,,,,>,>,,>,,,,,>,,,,,,,>,,,,>,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,,,,,,,,,,,,,,,',,,,,,',,,,,,,,',,,',',,',',,',,',,,',,',,',,,'',,',''',,,','',',',',',',',',',,'',',',','',',''',','',','','''',','''',,''',',''',''','''','''''''''''',''''''''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>;>>;;>>>;>>;>>>>;>>>>>;>;>>>>;>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>,>,>,>,>,>,>,>>>,>>,>,>>,>>,>>>,>,>,>>,>,>,>,>>,>>,>>>>,>,>,>,>,>,>,>,>,>,>,>>>,>,>,,>,>,>,>,,>,,>,,>,,,>,,,>,,,>,>,>,,,>,,,,,,,,,>,,>,,,>,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,,,,,',,',,,',',',,,',,,,,',,,',,',,,',',',',',',,,,',',,,,'',',,',',',',',',',','',',','',',','',',','',','','',','''',',''',''''',''','''','''',','',''','''''','','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>;>>;>>>;;>>;>>;>;>>>;>;>>>>>>;>>>;>>>>;>>>>;>>>>;>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>>>>,>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>>>,>,>>>,>>>,>>,>>,>,>>>>,>,>>>,>,>,>,>,>,,,,>,>,>,>,>,>,>,>,>,>,>,,,>,>,>,,>,>,,>,>,,>,>,,,>,,,>,>,>,,,,,,,>,,,>,>,>,,,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,',,',,,,,,,,,,,',',,,,,,,',,,,,,,',,,',',,,',,',,,',,,,',,,',,','',,',','',,,',',,',',',',',',',',',',',,','',',',''','','','','''',',''','''',',''',''','''','''''''','''''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>>;>;>>>;>>;>>>>;>>;>>>;>;>>>>>>>>;>>>>;>>>>;>>>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>>>,>>>,>,>>>>>>,>,>>,>,>,>,>,>,>>>>,>,>>,>>>,>>,>,>,>,,>>>,>,>,>>>,>,>,>>>>,>,>,>,>,>,>,>,>,>,,>,>,>,,>,>,,,,>,,>,,>,,,,>>,,>>,,,,,>,>,>,>,,,>,,,,,,>,>,,>,,>,,,,>,,,,,,,>,,,,,,>,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,,',,',,,,',',',,',,,,',',,',,',',',',,'',,',,,,,',',',,,'',',',',',',',',',',','',','''',,',''',',',',',',''',',''',',''',''''',''',''',''''','','''''''''''''''''''''',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>>;>>;>>;>>;>>>;>>>;>>>;>>>>>>;>>;>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>,>>>>>>>>,>>>>>,>>,>>>>>,>>>>>>>>>>>>,>,>>>>>,>>,>>,>>,>>,>>>,>,>,>>>,,,>,>>>,,>,>,>,>,>,>,>,>,>,,>,>,,>,>,>,,>,>>,>,>,,>,>,>,,,>,,,,>,>,,,,,,,,,>,,,>,>,,,,,,,,,,,>,,,,>,,,>,,,,,,>,,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,',,',,,',,,',,,,,,,,',,,,,,',,,',,,,,',,,',,,',,,',,',',','',,',,','',,',',',',',',',',',',','',',,',''',','',','''','',','',','''',','',',''',''','''','''''''',''',''','','''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>;>>;>>>;>>;>>;>>>;>>>;>;>>>>;>>>;>>>>>>>>;>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>,>,>,>,>>>>>,>,>,>>,>>,>>,>>,>>,,>>,>>>,,>>>,>>,,>>,>,>,>,>,>,>,>,>,,>,>,>,>,,>,>,>,,,,,>,,>,>,,,>,,,,>,>,,>,>,>,>,>,,,>,,,,,,>,,>,>,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,,',',,',,',',,,,',,',',',,',',,',,'',,',,,',',,,',',',',,',',,,',',',',',',',',',',''',',',','','''',,'','','',''',','','','''',''','''','''','',''''','''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>;>>>;>>;>>;>>;>>>;>>>;>>>>;>>>>>>>>>>;>>;>>>>>>>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>,>>>>>,>,>>,>,>>>,>>>>>>>>>>>>>,>,>>,>>>,>>,>>>,>,>>,>>>,>>,>,>>,>,>,,>>,>>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,>,>>,,>,,>,>,,>,>,>,,,>,,,,,,,,,,,>,,,>,>,,,,,,,,>,,>,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,,,',,,,',,',,,,,,,,,,,,,,',,,',,,,,',,,',,,,',,',,,',,',',,,',',,',,','',,','',',',',',',',','','',,,'',','',',',,''','','',''','''',''''''',''',''',''''','''''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>;;>>;>;>>>>>>;>>>;>>;>;>>>;>;>>;>;>>>>>>>>>;>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>,>>>>>>>>>>>>>>>,>,>,>,>,>,>>>>,>>,>>>,>>,>>,>>,>,>,>>,>,>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>,,>,>,>,,>,,>,,,>,,,,>,,>,,>,>,>,>,>,>,,,>,,,,>,,>,,,,,,,,,,,,,,,,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,',,,,,,',',,,',',',,,,',,,',',,',,',',,',,,',,',',,',',',',',',',,,',',,',',',',',',',',',','''',',','','','',,'','','','',','',',',',''',''','','','''',''''',''''''','','''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";;>>;>>>>;>>>;>;>;>>;>>>;>>>>>>>>>>;>>>>>>;>>;>>>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>,>>>>>>>>>>>>,>>,>>>,>>,>>>>>>>>>>>>,>,>>>>,>,>>,>>,>>,>>,>>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>>,>,>,,>,>>,,,,>,,>,>,>,>,>,>,,>,,>,,,,,,,,,,,,,>,,,,>,,,,,>,,>,,>,,>,,>,,>,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,,,,,,,',,,,,',,,,,,,',',,,',,,,,,,',,,,',,,',',',,',',,,',,,',',,','',,',',',',',',',',',',',',,,','',','','','',',','','',','',''''''''',''','''''''''','''','''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>;>>;>>>>;>>;>>;>>>;>;>>;>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>>>>>>,>>>>>,>,>,>,>,>>>>>>,>,>>>>,>>,>>,>,>>,>,>>,>,>,>>>,>,>,>,>>,>>,>,>,>,>,>,>,>,,,>,,>>,>,,,>>>,,>,,>,,>,,,>,,>,,>,,>,>>,>,>,>,>,,,>,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,',,,,',,,,',,,,,',,',,,,,',,,',','',,',',,',',,,,',,',,'',,'',',,',',,,',',',',',',',',','','',''',',','',',','',''',''''','''','',',',',''',''','',','','''',''''''''',''''''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>>>;>;;>>>>>>>;>>;>>>>;>>>;>>;>>>;>;>>>>>>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>,>>,>>>>,>>>>>>>>>>>>,>,>,>>>,>,>>,>>>,>>,>,>>>,>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,,>>,>,>,,,,>>,,,,,>,>,,>,,>>,,>,,,>,,>,,,,,,,,,,,,,>,,,>,,,>,,>,,,,,>,,,>,,,,,,>,,,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,',,,,,',,,,',,,,,',,,,,,,',',,,',,,,,,,',,',,',,,,',',',,',,,',,,,,'',','',',,',',',',',',',',',',',',','',','','','',,'',',','',','',''''''',''',''',''''''''',''','''''''''','',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;;>>;>>>;>;>;>>>;>>>;>>>>;>>>>>;>>>>>>;>>>>;>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>,>>,>>>>>>>>>>>>,>>>>>>>,>>>,>,>,>,>,>>>>>>,>,>>>,>>>,>,>,>>>,>,>>>,>>,>,>,>>>,>,>>,>,>,>,>,>,>,>,>,>,,>,>,>>>,,>,>,>,>,,>,,>,,,>,,>,,,>,,>,>,>,>,>,>,,,>,,,,,,,,,,>,,,,,,>,,,>,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,',,,',,,,,',',,,,,,',,,',',',,,',,',,',',',,,',',',,',''',,',,,,',',',',',',',',',',','',',','',,'','',',',''','',''','''','',',',''',''',''''',','',''''''','',''','''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>>>;>>>>;>>>>>>;>>>;>>>;>>>>;>>>>>;>>>>>;>>>>>>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>,>>>>>>,>,>>>>,>>>>>>>>>>,>,>,>>,>>,>>,>,>>>>>,,>>,>,,>>,>>,>,>,>,>,>,,>,>,,>,>,>,>,>,>,>,>,,>,,,>,>,>,>,,,>,,>>,,>,,,,>,>,,,>,,,,,,,,,,,,>,,,>,>,,>,,,,>,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,',',,,,,,',',,,,',,,,',,',,',,',,',,,'',,',,',',',,,,','',',',',',',',',',',',',',,''',',,'','','',''',',',''','',','','''''',''',''',',''''''''''',''''''','''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>;>;;>>>;>;>>>;>>>;>>>>;>>>;>;>>>>;>>>>>;>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>>>>,>>>,>>,>>>>>>>>>>,>,>,>,>>>>>>,>>>,>>,>>>,>,,>,>>,>>>>>,>,>,>>,>,>,>>,>>,>,>>,>,>,>,>,,>,>,>,>,>,>,,>,,,,>>,,>,,,>,,>,>,,,>,>,,>,>,>,>,>,>,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,>,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,',,,,',,,',,',,,,,,',,',,,,',',,',,,,',,',,',,',,',',,',,',,,',,''',',,',',',,',,',',',',',','','',,',''',',',','',,'',''',',',''',''',','''',''','''''','',','',''','''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>>;>>>>>;>>>>>;>>>;>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>,>,>>,>>>>>>>>>,>,>>>>,>>,>>>,>>>>,>>,>>,,>,>>,>>,>,>,>,>,>,>,>,>,,>,>,>,>,>>,,,>,>,>,>,>,>,>>,,>,>,>,>,>,>,,,>,,>,,>,,,,,,,,,,,,>,,,,>,>,,,,,>,>,,>,,>,,>,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,',,,,,,,,,,,,,,',,,,,,',',,,,,,,',',,',,',,,,,',,',,,',','',,',,,,,',',',,',','',',',',',',',',','',',,'','','',''','',','''''','',',''',',''',''',','''''''''''''''''''''','''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>;>;>>>;>;>>>;>>;>>>>;>>;>;>>>>>;>>>;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>,>>,>>>,>>,>>,>>>>>>>>,>,>,>,>>>>>,>,>,>>>,>,>,>,>>,>>,>>,>,>>,>,>>,>>>,>,>>>,>,>>,>,>,>,>,,>,>,>,,>,,>,>,,>,,>,,,>,,>,,>,,>,,>,,,>,,>,>,>,>,>,>,,>,,,,,,,>,>,,,,,,,,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,',,',,',,,,',,',,,,',',',,,,,',,',,',',,,',,'',,',,,,',',''',',',,',',',,',',',',',',','',','''',,'','','',,'',','',',','','''',''''',''','''''','',''','','''','','''''''''','''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>;>;>>;>>;>>;>>;>>>;>>>>>>>>>>;>>>;>>>;>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>,>>>>>>>>>,>,>>>>>>,>,>>>,>>>,>,>,>,>>,>,>,>,>,>,,>>,>,,,>,>,,>,>,>,>,>>,>,,>,>,>,,>,>,,>,,>>,,>,,>,,,,,>,,,>,,>,,,,,,,,,,,,,,,>,,,>,,,,,,,,>,,>,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,,',,,',,,,',,,,,,,',',,',,,',,',',,',,,',,,'',,',',,,',,',',',','',',',',',',',','',',,,'',','',','',',''','',''','',',''',',''',''','','''''','''''',''''''''','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;;>>>>;>>>>>;>>;>>>;>>>;>;>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>,>>>>,>>>>>>,>>>>>>>>>>,>,>,>,>>>>,>,>,>>>,>>>>,>>,>>>,>>,>>>,>>,>,>>>,,>>,>>>,>,>,>,>,>,>,,>,>,>,,>,>>,>,,>,,>,,,>,>,,>,>,>,,>,>,,,,>,>,>,>,>,>,>,,,,>,,,,>,,>,,,,,,,>,,,,,>,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,,,',,,,,',,,,,,,,,',,,',',',,,,,',,',,,',,,,',',',,'',,',,',,'',',',',,',',,',',',',','','',,',''',','',','',''',','',''','','''','''''',''',''''''',','''',''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>;>;>>;>;>>>;>>>;>>>;>>>>>>>;>>;>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>,>>>>,>>>,>>>>,>,>>>,>>>>>>>>>,>,>>>,>>,>>,>,>>,>>,,>>,>>,,>>,>>,>,,>>,>,>>,,>,>,>,>,>,>,>,,>,>,>,,>,,>,>,,>,,>,>,,>,>,,,>,,>,,,>,>,,,,,,,,,,,,,,,>,,,,>,,,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,,,,,,,',,,,',',,',,',,,,,,,,',',,,,',',,',',,',,',',,,',',,',,,',',',',,','',',',',',',',','',',','',',''','',,'',',''','','',','',',',''',''','','''''',''',''',''''','''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>;>>>>>>;>>>;>>>;>>>>>;>;>>>;>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>,>>>>>,>>,>,>,>,>>>>>,>>>,>>,>>>,>>,>,>>,>>,>>>,>,,>>>>,>,>,>,>>,>,>,>,>,>,>,>>,>,>,>>,>,>,,>,>,>,>,>,,>,,>,>,>,,>,,>,,>,>,>,>,>,>,>,,,>,,,,,>,,>,,,,,>,,,>,,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,,,',,,',,,,,',,,,,,,',,',',',',,,',',',,,',,,',,',',,',',,,',','',,',,','',',,',',',',',',',','',',',','',',',','',''',',',''',''',''''''',''',''',''','''''''''''''''''''',','''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>>;>;>;>>>;>>>;>>>>;>>>>>>>>>>>;>>>>>>;>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>>>>>>>>,>>>,>>>>>,>>>>>,>>>>>>>>>>>,>,>>,>,>>,>>>,>>,>,>>>,>,>>,,>>,>>,,,,>,>>,>,>,>,>,>,>,>,>,>,,,>,,>,,,,>,>,>,,>,,,,>,>,,>,,,,,>,,>,,,>,,,,,,,,,,,,,>,,,,,>,,,,,,,>,,,,,,,,,>,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,,,,,,',,,,,',,,,,',',,,,,,,,,,,,',,,',,,,',,',',,',,,',,',',',,',,',',',,',,,'',',',',',',','',','',',',','',',''','',,''''',',''','''',',''',''',''''''','',','','''''',''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>;>>;>>>;>;>>>;>>;>;>>;>>;>>;>>;>>>>;>>>>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>,>>>>,>,>,>,>,>>>>,>>>,>>,>,>>,>>>>,,>>>,>,>>,>>,>>>>>>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>>>,>,,,>,,>,>>,,,>,>,>,>,,,>,,>,>,,>,>,>,>,>,>,,,>,>,,,>,>,,,,,>,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,',,',,,,,',',,,',,,,,,,',',',',',,,',,,',',,',,,,',',',,',,,',',',',',',,',',',,',',',',',',',','',,',',''',',''',,'',''',','''',','',','''',''',''',',','''''''''''',',''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>>>;>>>>>;>>;>>>>>>>>>>;>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>>,>>>>,>,>>>>>,>>>>>>>>>>>>,>>>,>>,>>,>>,>>,,>>>,>,>>>,>>,,>,>,,>,>,>,,>,>,>,>,>,>,>,>,>,>,,>,,,,>,>>,,>,>,,>,>,,>,,,,>,>,,,>,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,>,,>,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,',,,',',,,',,',',,',,',',',',,,',',,',,'',',','',',',',',',','',','''',',,','',,''',',','',',','','',''',',''',''',''''''','','',',''''''','''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>;>>>;>;>>;>>>;>>;>>;>>>>>;>>>>>>>>>;>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>,>>,>>>,>>>>>>,>,>>>,>,>,>,>,>>>,>,>>>>,>>,>>,>>>,,>>,>,,>>,>>,>,>>,>,>,>>>,>,>,>,>,>,>,>,>,,>,>,>>,,>,,,>,>,,,>,,>,,>,>,,,,>,>,,>,,,>,>,>,>,>,,,,,>,,,>,>,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,,',,,',,',,',',,,,,,,',',',',,,,',,',,',,,',,,',,,',,,',',,'',',',',',,',',,',',',',',',','',',',',,','''','''',',''',',''','','','',''''',''',''','''''''''''''''''''''''''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;;>>>;>>>>;>>>;>>>>>;>>>>;>>>>;>>>>;>>>>>>>>;>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>>,>>>>,>,>>,>>,>>,,>>>>,>>>>,>>,>>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,,,>,>,,>,>,,,,>,>,,>,,>,,>,,,,,,,,,,>,>,,,>,,,,,,,,,,>,>,,,,>,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,,,,,',,',',,,,,,,,',',,',,',,',',,',,',',',',,,',,,,,',,',',',,',',',',',',',',',,',',','',',,',',',,''',,'','','','','','',',''',''','''',','','',''','''','''''''','''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>;>>>;>>>>;>>>;>;>>>>>;>>;>>>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>,>>,>>>,>>>>>,>,>,>,>,>>>,>,>>>,>>>,>>>>>,>,,>>,,>>,>,>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,,>>,,,>,>,,>,>>,,,>,,,>,,>,,,>,>,>,>,,,,,,,,,,>,,,>,,>,,,,,,,,,,>,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,',,,,,,,,,',',',,',,,,',,,,',',',,,,,,,,,',,',,,,',,',',',,','',',',','',,',,',',',,',',',',',','',''',','','',''',''',''',''','',''''',''''''',''',''',''''''''',''',''','''','',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>>;>>;>;>>>;>>>>;>>;>>>>>;>;>>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>,>>>>>,>>,>,>>>>>>>>>>>>,>>,>>>>>>>>>>>,>>>>,>,>>,>>>,>,>,>>>,>>,>,>>>,>,>,>>,>>,,>,>,>,>,>,>,>,>,>,,,>,>>,>,>,>,>,,,>>,>,,>,>,,,,>,,,>,,>,,,>,,,,,,,,>,>,>,,>,,,>,,,>,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,,,,,',,,,,',,,,,,,,',',',',,',,',',,',,,,,',',,,,,,',',',,',',',',',',',',',',',',',',','',',','',,'',,',','',,'',''',','',',',''',''',''','','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>;>>>;>>>>;>>>;>>>>>>>>>;>>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>>>>>>,>>,>,>>,>>>>>>,>,>,>,>,>>>,>,>>>>,>>,>,>>,>>,>>,>>,>>,,>,>>>,,>,>,>>>,>,>,>,>,>,>,>,>,>,>,,,,>,,,>,,>>,,,,,>,>,,>,>,,>,>,,,,>,,>,>,>,>,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,',,,',,',,,,',,,,',',',',,,,,,,,',,',,,',,,','',,,','',',',,',',',',',,,',',',',',',',',',',',',','',,''','''',','''','','','',''','',''',''','''''''''','','''''',''''''','''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>>>;>;>>>;>>>>;>;>;>>>>>;>>;>>>>>>;>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>,>,>>>>>>>>>>>>,>>>>,>,>>,>>>>,>>,>,>,>,>>,>>>,>,,>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>>,>,>>,,>,,,,>>,>,,,>,,>,,>,,,>,>,>,,,,,,,,,>,>,>,>,>,>,,>,>,,>,>,,,,,,>,,>,,,>,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',,,,',,,,,,,,,,,,,,,,,,',,,,,,,,,',',',',,,,,',,',',,',,,',',,,',,',',,',,',',''',',',',',',',',',',',',',',''',','',,'',',',''',','',''',''''',''',''',','',',''','',','''','',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>>;>>>>>;>>>;>>>>>>>>;>>;>>>>>>>>;>>>>;>>>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>>,>>,>>>>>>>>,>,>,>,>,>,>>,>,>>>,>>,>,>>,>>,>,>>>,>,>,>,>>>,,>,>>,>,>,>,>,>,>,>,>,>,,>,,>,,>,>,,>,>,>>,>,,>,>,>,,,,>,,>,,>,,,,>,>,>,>,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,',',,',,',',,,,',',',,,,,,,,,','',,,',,,,',,'',',,',,',,,',',',',,',,,,',',',',',',','',',','','',,'','',''',''',',','''','',','','''',''','''''''''''''''''''''''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>>;>;>>>;>>>;>>;>>>>>>>>;>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>>>>>>>>,>>>>>,>,>>,>>>>>>>>>>>>>>>>,>>,>>,>>>>,>>,>>>>,>,>>>,>,>,>,>>,>,>>,>,>,>,>,>,>,>,>,>,,>,>,>,,>,>,,>,,,>,,>,,>,,>,>,,>,,>,,>,>,,,,,,,,,>,>,>,,>,,,>,,>,,>,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,',,,',,,,,,,,,,,,,,,,,,,,,,',,,,,,',',',',,,,,',',,',',,',,,,,',',',',',',',',',,'',',',',',',',',','',''',',','',',',',',',',''''',','','','''',',''',''',',','',',''','''',''''','',''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>;>>>>>;>;>>;>>>>>;>;>;>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>,>>,>>>>>>,>>>,>>>>>>>>>,>,>,>,>,>,>,>,>>,>>,>>,>,>>,>,>,,>,>>,,>>>,>,>,>,>>,,>,>,>,>,>,>,>,>,>,>>,>,,>,>,>,>,,>,>,,>,,>,,>,,,>,,,>,,>,,,>,>,>,,>,,,,,,,,,,,>,,,,,,,,>,,,,,,,>,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,',,,',',,',,',,,,',',',,,,,,,,',',,,,',,',,',,'',',',,,',,,',',,,','',,',',',',',',',',',,'',,',',',','''','','','',','''',''','',','''',''',''''''''''''',''',''''','''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";;>>;>>;>;>>>>>>>>>;>>>>>>>>;>>>>>>>;>>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>,>>>,>,>>>>>>>>>>>>>>>>>,>>,>>>,>>>,>>>,>>>>>,>>>,,>>,>,>,>,,>>>>,>,>,>,>,>,>,>,>,,>,>,>,>,,>,>,,>,,>,,>,>,,>,,>,>,,>,,,>,,,,,,>,,>,>,>,>,>,,,>,,>,>,,,,,,,>,,,,,,>,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,,,,,,,',,,,,,,,',',',',,,',',,',,',,',,,',,,'',,'',,','',,',,,',',',',',',',',','',,'',',','',',,'','',',',','',,''','',''''',''',''','',''','','''''''''''''''''','','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>;>>;>;>;>;>>>>;>>>;>>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>,>>>>>,>,>,>,>,>,>,>>>>,>>,>>,>,>>,>,>,>,,>>,>>>>,>,>>>,>>>,,,>,>,>,>,>,>,>,>,,>,>,>,>,,>,>,>,,>,>,>,,,>>,,>,,,>,,,>,>,,>,>,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,',,,,,',,',',',,,,,',',',,,,,,,,,',,,',,,',,,',,'',,'',,,',,,',',,'',,'',',',',',',',',','','','',''',,'','',','','''''',''',','''',',''',''',''',''','''''','','''','''','''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>;>>>>;>>>>>>>>;>>>;>>>>;>>>>>;>>>;>>>>>;>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>,>>,>>>>>>>>>>,>>,>>>>>>,>>>>>>>>>>>>>>,>,>>>,>>,>>>,>>,>>,>>,>,>,,>,>,>,,>,>,,>>>,>,>,>,>,>,>,>,>>,,>,,>,>>,>,,>,>,,,>,>>,,,,>,,>,,>,>,,,>,,,,>,>,>,>,>,>,,>,,,>,>,,>,>,,,,,,,>,,,,,,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,',,,,,,,,,,,,,,,,,',,',,,,,,',',',',,',',,,',,,',,',,,',,,'',,',',',,',,'',,,,',',',',',',',',,',',',',','','','',',',',,','',','',',','''',''',''',''''''''',''''''','''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>;>>>>;>;>;>>>>;>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>>>>,>,>>,>>>>>>>,>>,>>>,>,>,>,>,>,>>>>,>,>>,>>,>>>,>>,>>,>>>,>>>,>>,>>,>>,>>,,>,>,>,>,>,>,>,>,,>,>,>,>,,,,>,,>,,>,>,,,,>>,,>,,,>,,,>,>,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',',,',,,,,,,,,,',',,,,,,,,,,',,,',',',',,',',',,',,,',',,',',',',,','',',',',',',',',''',',','',',',','',''','''','''','',''','',',''',''',''','','',''','',''''''''''','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>;>;>>>>>>>;>>>>>>;>>;>>;>>>>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>>>>>,>,>>>>,>>>,>,>,>,>,>>,,>>,>,>,>>,>,>,>,>>>>,>,>,>,>,>,>,>,>,>,>,,>,>>>,>,,>,>,,,>>,,,>,>,>,,,>,,>,,,,>,>,>,>,>,>,>,,>,,,,,>,,>,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,',',,',',,,,,,',',',',,,',',,,',,,',,',,',',',',,',',,',',',',',,',',',',',',',',,','',',,',',''','',,',',,'',','','''',''''''',''','',''','''''','''''''',''',''''''''''''',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>;>>>>;>;>>;>>>;>>>>>>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>,>>>>>>>,>>,>>,>,>,>,>,>,>,>>>>,>,>>,>>>>,>>>,>>,>>>,>>,>>,,>,>,>,>,,>,,>,>,>,>,>,>,>,,>,,,>,>,>,,,,>,>,,,>>,,,>>,,,,,>,>,,>,,>,>,,,,,,,,,,,,,,,,,>,,,,,,,,,>,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,,,,,,,',',',,,,,,,,',,,,,',,,',,',,,',,,',,,',,',',',,',,',,'',',',',',',',','','',','''','',,'','''',''',''',''',','',',',''','''''','''','',''','''''''''''','''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>>;>;>>>>>>>>>>>;>>;>>;>>>>>;>>;>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>,>>>>>>>>>,>>>>>>,>,>>>>>>,>>>>>>>>,>>>>>>,>,>>>,>>,>,>>>,>>,>>,>,>,>>,>>>,>>,>>,>>,>>,>,>,>,>,>,>,>>,>>>,,>,,>>,>,,,>>,,,>>,,,>,>,>,,,>,,,>,,,>,,>,>,>,>,>,>,,,,,>,,>,>,,,,,,,>,,,,,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,',,,,,,',,,,',,',,',',,,,,,,,',',',',,,',',,,',,',,',',',',',',',,',',',',',',,,',',',',',',',',',',',',,',','',',',','',','','',',''',','''',''',',',''''''''''''''','''','''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>>>>>;>;>;>>;>>>>>>>;>>>>;>>>>>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>,>,>>>>,>,>,>>>>,>,>>,>>,>>,>>,>>,>,>,>,>,>>,>>,>,,,>>,>,>,>,>,,>,>,>,>,>,>,>,,,>,,,>,>,>,,>,>>,,,>>,,,>,,,,>,,>,,>,>,,>,,,>,,,,,,,,,,,,>,>,,,,,,,,,,,>,,,,,,,,>,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,',,',,,',,,,,,,,,,,,',,',,,,,,,,,,',',,',',',,',,,',,',',,',,,',',',',',','',',',',',',',','','','','',',','',''',','','','','''',''''','''',''''''','',','','',''''','''',''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>>>;>;>>>>>>>>>;>;>;>>>>;>>>>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>,>>>>,>>>,>>>>>>>,>>>>>>>>,>>,>>>>,>>,>>,>>,>>,>>>,>>,>,>>,>>>>>,,>,>,>,>,>>,>,>,>,>,>,>,>,>,,>>,>,,>,>,,,,>>,,,>,>,>,>,,>,,>,,,,>,,,,,,>,>,>,>,>,,,,,,,,>,,>,,>,,,>,,,,>,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',',',,',,,',,',',',',',,,,,',,,,,',,',',,',,,',,',',,,',,,',',,,',',',',',',',',,',',',',',',',','',,'',','','','',',',',','',',''',',','''''''''''''',''''''''''','''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>>>>;>;>>;>>>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>,>>>,>>,>>>>,>,>,>>>>>>,>,>>,>>,>>,>>,>>,,>>,>>>,>,>,,,>,>>>,>>>,>>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,>>,,,,>,,>,>,,,>,,,>,,>,>,,>,>,,,,,,,,,,,,>,,>,,>,,,,,,,,,,,,,,>,,,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,',,,,,,,,,,,',,',,,,,,,,,,','',,',',,',,,,',,',',,',',,'',',',',,'',',',',',',',','',',',','','',''',''','','','','''',''''',''''''',''''''',','',','',''''',''''''',''',''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>>;>;>>>>;>>>>;>>>;>>>>>>>>;>>>>>;>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>,>>>,>>>>>>>>>>>,>>>>>>,>,>,>>>>,>>,>>,>>,>>,>>>>,>,>,>,>>>>>,>,>,>,>,>,,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,,>>,>,>,,>,,>,,>,>,,>,,,>,,,,>,>,>,>,>,>,,,,,,,,,>,,>,>,,,,>,,,,>,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,',,',,',,,,',,,',,',,,,,,,',',',',,,,,,,',,,',,,',,',',,',',,',',,,',',,'',,,,',',',',',',',,',''',',',',',',',,'','','','',',''',',''',',','''',','''''''''''''','''','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>>>;>>>>>;>>>;>>>>;>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>,>>,>>>>,>>>,>>>>,>,>>,>>>>,>,>,>>>>>>>,>>>,>>,>>>>>,>>,,>,>>,>>>,>,,>,>>,>,>,>,>>,>,>,>,>,>,>,>,>,,>,,>>,>,,>,>>,,,>,,>,,>,>,,,>,,>,,>,,,>,>,,,,,,,,,,,,,>,>,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,',,,,,,,,,,,,,,,,,',,,,,,',,',,,,,,,,,',',',,',',,',',',,,',',,',',,',',',',',,''',',',',',',','','',,',',',','','''','',',',','',','','',',''''',','''','','',''',','''''''''''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>;>>>;>;>>>;>>>>;>>>>>>>>>>;>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>>,>,>,>,>,>>,>>>,>,>>,>>,>>,>>,,>>,>>>,>,>,>,>>>,,>,>,>,>,>,>,>,>,>,>,>,,,>,>,>,,,>,,>,,>,,>,,>,,>,,,,>,>,,,,,,>,>,>,>,>,,,,,,,,,>,,>,,,,,,,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,',,,,',',,,',,',',',',,,',,,',,',,',,,,,',',,,',,',,',',',',,',',,,',',',',',',',',','',',''',',''',,',','','''','''',''','''',',''''','',''''''','''''',''''''','','''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>;>>>>>>>>>>;>>>;>>;>>>>;>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>,>>>>>,>>,>,>>>,>,>,>,>>>>>>>>>,>>>,>,>>,>>,>>>,>>,>>>,>,>,>,>,>>>,,,>>,>,>,>,>,>,>,>,,>,>,,>,>>,,>,,>,>,>,,>,>,>,,>,,,,>,>,,,>,>,>,,,,,,,,,,,,>,,>,,,,,,,,,>,,,,,>,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,',,',,',,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,',,',,','',',,'',,',,',,,',',,',',',',',',',',',',',',','','',,','',,'''',','',',''',','','',',''''',','''''','','''''','''''',',''''''',''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>>;>>;>>;>>;>>>>>>>>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>,>>>>,>>>>>>,>>>>>>>>>,>>>>>>>>>,>,>,>,>>,>,>>>,>>,>>,,>,>,>,,>>,>,>,>,>,,>>>,>,>,>,>,>,>,>,>,>,,>,>>,>,,>>,>,>,,>,>,,>,,,>,,>,>,,>,,>,,,,,,,>,>,>,>,>,,,,,,,>,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,,,,,,,,,,,,',,',',,,,',',',',',',',,',,',',,',,,',,,,,,',,,',',',',',',',',,',',',',',',',',',','',',',''',','',',,'''','',',',''','',''''',','''',',',''''','',''','',''''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>>>>;>>;>>;>>;>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>,>>>>>>,>,>,>>>>>>>,>>,>>>,>,>>,>>,>>>>>,>>>>,>>>,>,>>>>,,>>,>,>,>,>,>,>,>,>,>,>,,,>,,>,,>,,,,>,>,,>,,>>,,>,,,>,,,>,,>,>,>,,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,>,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,,',,,,,',,,,,,,,,,,,,,,,,,',,,',,,',,',','',',',,',,',',',,',',',',',',',',',',',','',',',',,,',',''','',,,','','''','','',',',''''','''''''','''''''''''''''''''','','''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>;>;>>>>>>>>>;>>>>>;>>>;>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>,>,>>>>>>>,>>,>>>>>>,>,>,>>>,>>>,>>>>,>>>,>>,,>,>>,,>>,,,>>>,,,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>>,>,>,>>,,>,,>,>,,,>,,,>,,>,>,,>,,,,,>,>,>,>,>,,,>,,,,>,,>,,>,>,,,>,,>,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,',,,,,',,,,,,,',,,',,',',',',',',',,,',,,',,',,',,,,',',,',,',,,',',,',',',,,',',',',',',',',,',',',''''',',,'','''',','',','','','','''',',''',',',''''',',',''','''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>>>>;>>;>>>>>>>;>;>>>>>>>;>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>,>>,>>>>,>>>>>>>>,>,>>>>>>>,>,>,>>>>>>,>>>,>>,>,>>>,>,>,>>>,>,>>>,>>>>,,>>>,>,>,>>,>,>,>,>,>,>,>,,>,,>,>,,,>,,>,,,>,,>,>,,>>,,>,>,>,,,,>,,>,>,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,,,,,,,,,,,,',,',,,,,,,,,,,,,,,,,,,,,,',',,',',,',,,'',,',,',',',,',','',',,,',',',',',',',',','',''','',,,,''''','',',''','''',''','','','''''',''''''','','''''','''','',''''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>;>>;>>>;>>;>>>>>>>;>>>>>>>>>;>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>,>,>>>>>>>>>,>,>>>,>>,>>>>,>,>>>,>,>,>>>,>,>,>,,>,>,>,>>,>,,>,>,>,>,>,>,>,>,,>>,>,>>,>,>,,>,>,>,,,>,,,,>,,,,,>,>,,>,,,,,>,>,>,>,>,,>,,,,,>,,>,>,,,>,,,,>,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,',,,,,,,',',,',',',',',',',',,,,',,,,',,,',,,',,',,',,',',',,,,',',',',',',',',',',','',',',',''''',',,',','',','',',',','',''''',',',''',',',''''''','''',''''''''',''''','''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>;>>;>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>,>>>,>>,>>>>>,>,>,>,>>>>>,>>,>>,>,,>>>>,>>,>>,>,,>>,>>,>>,>>,>,>,>,>>,>,>,>,>,>,>,>,>>,,,,>,,>,>,,>,>,,,>,>,>,>,,,>,>,,,,>,,>,>,>,,,,,,,,,,,,,,>,,,,,,,,,,>,,,>,,,,>,,,,,,,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,',',,,,,,,,,,,,,,,,,,,,,,,',',,',',,',',',,',',',,',,,',,''',,',',,',',',',',',',',,',',',',,',,','''','',''',,''',''',''',',''''''','''''''',',''''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>;>>;>>>>>>>>>>>;>>>>>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>>>>>,>>>>>>>>>>,>>,>>>>>>>>,>,>>>,>>,>>>>>,>,>>,>>,>>>>>,>>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,,>>,>,>,,>,>>,,,>,>,>,,,>,>,>,,,>,>,,>,,,,,,>,>,>,>,>,,>,,,,>,>,,,>,,,,,,,,,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,,,',,,,,,,,',,,,,,,',,',,',',',',',',',',,,',,',,',,,,',',,,',',,'',,'',,,',',',',',',',',',',','','','','','','',,'','',,'',','''','','','',',',''',',',''''''','''',''',''',''''','''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>>>;>>;>>;>>>>>;>>>>>>>>>>;>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>,>>>>,>>,>>,>>>>>>>,>,>,>>>>>,>>>,>>,>,>>>>,>>,>,>,>,,>>,>,>,>,>>,>>>,>,>>,>,>,>,>,>,>,>,,>,,>,>,,>,>,,,>>,>,,,>,>,>,,,,>,>,,>,,,>,>,,,,,,,,,,,,>,,,>,,,,,>,,,,,,,,,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,,',,,,',,',,,,,,',,,,,,,,,,,,,,,,',,',,,',,',',,,',',,,',',,',,',',',',',',',',',',',',',',',',',',','',','',',''','''',',''','','','''''',''''''','',''''','''''''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>>>;>>>>>>;>>;>;>>>>>>>>>>;>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>,>>>>>,>>>,>>>>>>>,>>,>>>>>>>,>,>>>,>>,>>,>>,>,>>,>>>,>,>>>,>>>,>,>,>>,,,>,>,>,>,>,>,>,>,>,>,>,>>,,>,>,>,>>,,,,,>>,,>,>,,>,>,,,,>,,>,,,,>,>,>,>,>,>,,,,,,,>,,,,,,>,,,>,,>,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,',,,,,,,,',,,,,',',',',',',',,',,',',,,',,,'',,',',',,,',',',',',,,',',,',',',',',',','',',',',',',,''','',',','',,''',','','','''',',''',',',''''''',''''',''''''''''''',''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>>;>>>>>>>>>>>;>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>,>,>>>>,>>,>,>,>>>>>,>>,>>>,>>,>>>,>>,>,>>>,>,>,>,>,>>,>,>>>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,>,,,,,>>,>,,,>,,,,>,>,,>,>,,>,,>,>,,,,,,,,,,,,,>,>,,,,,>,,>,,,>,,,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,,,,,',,',',,,',,,,,,,,,,,,,,,,',,',,,,',',,',,,',,,',',',,,',',,,',',',',',',',',',',',',',','','',''',,'',''','',''',''',','','',','''','''''''',',''''',''''',''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>;>>;>>;>>;>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>,>>,>>>>>>,>>>>>>>>>>>,>,>>>,>>,>>>,>>,>>,>,>>,,>>,>,>,>>,>,>,>,>,>>>,>,>,>,>,>,>,>,>,,>,>>,>,>,>,>>,,>,,>>,>,>>,,,,,>,,,>,,,>,,,,,>,>,>,>,>,,,,,>,,>,,,,,,,,,,,,,,,,>,,,,,,>,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,',,,,,,,',,,',,,,,,,,,,,,,',',',',',',,',,',,,',',,,',,',',',',,,','',,',''',',',,',',',',',',',',','',',',',',,'',',',,',','',',','''','','''''',''',',',''''',','''',''''''''''','''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>>>>>;>>>>>;>>>>;>>>>>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>,>>>>>>>>>>>>>,>>>>>>>,>>>>>>,>,>,>,>,>>>>,>>>,>>,>>>,>>,>>,>,>>>,>>>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,,>,>,,>,,>,,,,>,,,>>,>,,>,,,>,>,,>,>,,,,,,,,,,>,,,,,,,,,,>,,>,,,,,>,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,',,,',',,,,,,,,,,,,,',,',,',,',,',,,',,',,',,'',,,,,',',,,,',',',',',',',',',',',',','','',''','','''''','',''''',',''','',',',''',''''''',''''''','''',''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>;>;>>>>>;>>>>;>>>>>>;>>>>;>>>>>>>>>>>>;>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>>,>>>>>>>,>>,>>>,>>,>>>>>>>>>>>>,>,>>,>>,>>,,>>,>>,>>,>>,>>,,>>,>>,>,>>>,>,>,>>,>,>,>,>,>,>,>,>,,>,>>,>,>,>,>,>,>,,>>,,>>,,,,,>,,>,>,,,>,,,,,>,>,>,>,,,>,,>,,>,>,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,',,,,,,',,,,,,,',',',',',,,',,,,,',,',,',',,',,',',,,'','',,','',',,',,',',',',',',','',',',',',',,'',',',',,'','',,',''',','''''''''','',',','''''','''',''''''''',''''''''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>;>>>>>;>>>>;>>>>>;>>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>>>>>>>>>>,>>,>,>,>,>>>>>,>,>>,>>>,>>,>>,>>,>,>,>>,>>,>,>>,,>,>>,>,>,>,>,>,>,>,>,>,,>,>,,>,,>,,>,,,>,,>,,>,,,,>,>,,,>,,,>,>,,>,>,,,,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,',',,,,',,',,,,,,,,,,,',,,','',,',,',,,,',',',,',',,,',,',',,',,',',',,',',',',',',,','',','','',','''',''',','''',','''',',,',',',''''''''','','''','''',''',''''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>>>;>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>,>>,>,>>>,>>>>>>>>,>>,>>>>,>>>,>>,>>>,>>,>>>,>>>,>,>>>,,>>>,>,>,>,>,>,>,>,>,>,>,>>,>,>,>,>,>,>,>,,>,,>,,>>,>,,,>,>,,>,,>,,,,,,,>,>,>,>,,,>,,>,>,,>,,,>,>,,,,>,,>,,,,>,,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,',,,,',,,',,,,,,,,,,',,,,,,',,,,,,,,,,,,,',',',',',,,,',,,,,',,',,',',,',,,',,',,',',',,',','',',','',',',',',','',','',',',','',',,'',,'',',','''',','''''''''''',',',','''''','''''''''''''''''',''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>>>>>>;>>>>;>>>>>>;>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>,>>,>>>>,>>,>>>,>>>>>>>>>>>>>,>>>,>,>,>>>,>>>,>>>,>>>,>>,>,>,>,>,>>,,>>>,,,>>,>,>,>,>,>,>,>,>,>,>,>,>,,,,>,>,,>,,>,,,>,>,>,,>,,,>,,>,,,,>,,>,,>,>,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,',,',',',,,,,,,,,,,,,',',,,',',,',,',,,',,',',',',',',,,'',',',,,,',',,',',',',',','',',','',',',''','',''',''','',',''',',',',',','''''''''',','''','',','',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>;>>;>>>>>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>,>,>>,>>>>,>>>>>>,>>>,>>,>,>,>,>>>,>>>,>>>,>,>>>,,>>>,>,>,>,>>>,>,>,>,>,>,>,>,>,>>,>,,>,>,>>,>>,,>,,>,>,>,>,>,,>,>,,>,,,>,,,,,,>,>,>,>,,,,>,,>,,>,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,,,,,,,,',,',',',',,,,',',,,',,,',,',,',',,',,,',,,'',,,',,,'',',','',',',',',',','',',',','',',,'','',,'',,'','','',','','''''''',',',','''''',''''''''''''''''''','''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>;>>;>>>>;>>>>>>;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>,>>>>,>,>>>,>>>,>>>,>>>,>,>>,>>,>,>,>>,,>>>,,>>,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,>,,,>,,>,,>,,,>,,>,,,>,,,>,,>,>,,,>,>,,,,,,,,,>,,,,,,,,,,,,,,,,,>,,,,>,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,',,,,,,',,',,,',',,,,,,,,,,,',,,,,',,,,',,,',,',',,',,',',',',,'',',',,',',,',',',',',',',',,',',','',',''','',''',''','','','''','',',',',''''''''','''''','','''''',''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>>>>>>;>>;>>>>>>>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>,>>>,>>,>>>>>,>>,>>>,>,>>>>,>>>>,>>>,>>,>,>>>>,>,>>,>>>,>>>>,>>,>,>,,>>,>,>>,>,>,>,>,>,>,>,,>,>,>,>,,>>,>,,>,>,>>,,>,,>,>,,>,,>,,,,,>,,,,>,>,>,>,,,>,,>,>,,>,,>,,>,,,,>,,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,',,,,,,,,,',,,,,,',,,,,,,',',',',,,',',,,'',',,',,',,',,',,',,,',,',',,',','',,',',',',',',',',','',''',',,',',',','',',',','''','',','','''''''''',',','''','',''''',',''''''''''',''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>>;>>>>>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>,>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>,>,>>,>>,>>>>>,>,>>>>,>>,,>>,,>,>,>,>,>>>,>,>,>,>>,>,>,>,>,>,>>,>,,>,,>>,,>,,>,,,>,,,>,>,>,,,>,>,,,>,>>,,>,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,',,,,',',,,,',,,',,,,,,,,',,,,,',,,,,,',,',,,,',',',',',,',,',',',',,',',,',',',',',',','',',',','''',''','',',','','',''','''','',',',',',''''''',''''''','''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>>>>>>;>>>>>>;>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>,>>>>>>>>,>>>>>,>>,>,>,>,>>>,>>>>>>>>,>>>,>,>>,>>,>,>,>>,>,>>>>,>>,>>,,>,>>,>,>,,>,>,>,>,>,>,,>,>,,>>,,>,>,>,>,>,,>,,>,,>,>,,,,>,>,,,,>,,,,,,>,>,>,,,>,>,,>,,>,>,>,,,>,,,,,>,,>,,,,,,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,',,,,,,,,,,',,,,',',',,,,',',,',',',,',,',',,,',,',,',',,',',',,',',','',',',',',',',','',',',',,,',',',',''','','','','',',''''''''''''''',',''''',',''''',''','''''','''''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>;>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>,>>>,>,>>>>>>>>>>>>,>>,>,>,>,>>,>,>>>,>>,>,>,>>,>>>,>,,>>,>,>,>>,>,>,>>,>,>,>,>,>,>,>,>,,>>,,,>,>,>,,,>,,>,>,,>,,,,>,>,,>,,>,>,,>,>,>,,,,,,>,,,,,,,,,,,,,,,,>,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',,,',',,,,',,,,,,,',',,,,',,,',,',,',,,',',,',,',,',',',,,',',,',',,',',',',',',',',,',',''''','',''',',',','','','',''',',,',',',',',''''','',''''',''''''''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>>>>>;>>>>;>>>>>>>>>;>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>,>>,>,>,>>,>>>>>>>>,>>>,>,>>,>>>>>>,>>,>,>>>,>,>,>,>,>,>>,>,,>>,>,>,>,>,>,>,>,>,,>>,,>,>,>>,,>,,>,>,,>>,>,,,>,,,>,,,,,,,,,,,>,>,,,>,,,>,,>,>,,,>,,,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,,,,,,,,,',,,,,,',,,,',',',,,,',',,,',,',,',,,',,',',',',',,,,',',',','',,',',',',',',',',''','',',,,',','',','',''',',','',''',''''''''''''''',','''''''',''''',','''''','',''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>;>>;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>,>>>>>>,>>,>>,>>,>>>>>>>>>>>>,>,>,>,>>,>>>>,>>>,>,,,>>,>,>,>,>>,>>,>,>>,>,>,>>,,>,>,>,>,>,>,>,,>,>,,>>,,,>,,,>,>,>,,>,>,,,,>,,>,>,,>,>,>,>,>,,,,,>,,,,>,,,,,,,,>,,,,,,,,,>,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,',,',,',,',,,,,',,,,,,',,,,,,,,',,,,,',',,,',,,',',',,,',,,',,''',,',',,',,,',',',',',',',',',,',',',''',','',','','',,''''',''',,'',',',',',',',''''','','''''',','''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>>>>>;>>>>>>>>>>;>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>,>>>>>>>>>>>,>,>,>,>>>>>>>>>>,>,>,>>,>,>>>>,>,>>>,>>>,>,>,>>,>,>,>,>>,>>,>,>,>,>,>,>,>,>,>,>,,>>,,>,>,,,>,,>,,,>,>,,>,,,,>,,>,,,,,,,,>,>,,,>,,,,,>,,>,,,,,>,,>,,,,,,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,',,,',,',,,',',',',,,',',,,,,',,',',,,,,'',,'',,',,,,'',',',,'',',,',',',',',',',','',',',','',','',','',''',,','',''','','''''''''''',',''''','','''''''','''''''''',''',''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>>>>;>>>>>>>>>>>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>,>>>>>>>>>,>>,>>,>>>>>>>>>,>,>,>,>,>>>>>,>>>>,>,>>>>,>,>>,,>>>,>,>,>>,>,>>,>,,>,>,>,>,>,>,>,>,>,,>,>,,>>,,>,>,>,>,>,>,,,>,,>,>,,,>,,>,>,>,>,,,,>,,,>,,>,,,,,,>,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,,,,',,',,',',,,,,,,,,,',,,,,,,,',,,,,','',,',,,',',',,,',,,',',',',,',,'',,',',',',',',',','','',',''',',','','','',',',''''',',','','',',',',',',''''','''''''','''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>;>>>>>;>>;>>;>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>,>>,>>>>>>,>>,>>>,>>>>>>,>,>,>,>>>>>>>>>>>,>,>>,>,>>>,>,,>>,>,>>>,>,>,>,>,>>,>,,>,>>,>,>,>,>,>,>,,,>,>,>,>,>,,,>,,>,,,,>,,>,>,,>,,>,,>,,>,,,,,,,,,,>,,,>,,,,,,,,>,,,,>,,,,,,,,>,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,',,',,,,,,,,,,,,',,',,',,,,,',',',,,',',,,,,',,,',,',,,'',,',',,,',,',',',,',',',',',',',',',',,',,',',,'',',',',','','','',,','''''',''','''''''''''',','','',',''',','''''',''','''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>;>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>>>>>>>>,>,>,>,>,>,>>>,>>>,>,>>>>,>,>>,>,>,>,>>>,>,,>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>>,,>,,>>,>,>,,,>,,,>,,>,>,,,>,>,>,>,>,,,>,,,>,>,,>,,,>,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',',,,,,,,',,,,',',,,',',,,,'',,,',',,'',,',,',,'',,',,',',',',',',','',''',''',,','','','',',''','''',',',''','',',',',',',''''''''''''''''''''',','''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>,>>>>>,>>,>>,>,>,>>,>>>>>>,>,>,>,>>>>>>>>,>>>,>,>>,>>,>>,,>>,>>,>,>>>,>,,>,>>>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,>,,>,,>,,>,,,>,,,>>,,,>,,>,,,,,>,,,,,,,,,,,>,,>,,,,,,,,,,,,,>,,,,,>,,,,>,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,',,,,,',,,',',',,,,,,',',',,',,',,,',',,,',',,,,',,',',,,',',',',,,',',',,,',',',',',',,',',',',''',','','',''',,'',','',''',',',''''''''''''',','','','','','','''''''''',''''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>;>>>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>,>,>,>>,>>,>>,>>,>>,>>>,>>,>>>,>,>,>>,>>,,>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>>,>,,>>,>,>,,>>,,,>,>,,,,>,>,>,>,>,>,>,>,,,,,,,,>,,>,,>,,>,,,>,,,,,>,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,,,,,,',,,,',,,,,,,',',,,,,,,,,,',,',,',,',,',,',',',',,',',,',,','',',',,''',',',',',','',',',',',',',',',',',',''',','','','','''',',',',',','''''''''''''','''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>;>>>;>>>>>>>>>>>>>;>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>,>>,>>>,>,>,>,>,>>>>>>>>>,>>,>>,>>,>>>,>>,>,>,>,>,>>>,>>,>,,>>,,>,>,>,>,>,>,>,>,>,,>,>,>,,>,,,>,>,,,,,>,>,,,>,>,,,>,>,,>,,,,,,,,,,,,,,>,>,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,',,,,,,',',',',,,',,',,',,',,',,',',,,,',',,',',,',,',,',',,,',',',',',',,',',','',','',''',''',',',''','','','',','''''''''''',',',','',',''''','''''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>;>>;>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>,>>>,>>,>>>,>>>>>>>>>>>>>>>>>,>,>,>,>>>,>>>>>,>>,>>,>,>>>,>>,>,>,>,>,>>>,>,>,>>,>,>,>,>,>,>,>,>,>,,,>,>,>,>,,>,>,>,,,>,>,,,,>,,>,,>,,>,>,>,>,>,>,>,,,,,,>,,>,,>,>,,,,,,,>,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,,',,,,,,,,,,',,,,',,',,,,',',,,,,,,,,',,,',,',,',,',,',,,','',,,',',,'',',',',',',',',',',',','',''','',',',',',',',','',',','','','''''',',',',',','''''''''''''''',''''','''''''''''''''','''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>;>>;>>>>>>>>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>>>,>,>,>>>>>>>>>,>,>>,>,>>,>>,>>,>,>,>>,>>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>>,,>,>,>,,>,,>,,>,,>,,,,,,,,,,,,>,>,,,,,,,,,,,,>,>,,,,,>,,>,,,,,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,,,,,,',,,,,,,',,,,,,',',',',,,',,',,,,,',,',,,',',,,',',,,',,,',',',',',',',',',',',',,',',',','',',',''',','','','',''''',,',','''''''''''',',','',','','''','''',''''','''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>;>>>;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>,>>,>>>>>>,>>>>>>>,>,>,>,>>>>>,>>,>>>,>>>,>>>,>>,>>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,>>,>,,,>,,,,,>,,,>,,>,,>,,>,,>,,>,>,>,>,>,,,,,,,>,>,,>,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,',',,,,,',',,,,,,,,,,',,',,',',,',,,'',',,'',,','','',',,',',,,',',',',',',','',',',',',,',','','','','','','',',''''','',',',',',',''''''''''''''','''''''''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>;>>>>;>>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>,>>,>>>>>>>,>>,>>>,>,>,>>>>>>>>>,>,>>,>>,>>,>,>>,,>>,>,>,>,>>,>>,>>,>,,>>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,,>,>,,>,>>,,>>,,>,,>,,>,,,>,,,,,,,,,,,,>,>,>,,,,,>,,,,,,>,,,>,>,,,,,,,>,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,,,,,,',,,,,',',,,,,',',',',',,',,,',,,',,,',,,,,',,,',',,,,,',',',,,''',,',',',',',',',',',',','','',',','',',','','','',',',''',''''''''''''',','','',','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>>>>>>>>>>>>>>,>,>,>,>>,>>,>>,>>,>>>,>,>>,>,>>>,>>,>,>,>,>,>>>,>,>,>,>,>,>,>,>,>,,>,,>,>>,>,>,,>,>,,>,,>,,,>,,>,,>,,>,,,>,>,>,>,>,,,,,,,,>,,,,,,,>,,,,,>,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,',,',,,,',,,,',,,,,,,',,,,,,,,,,,,,,,',,,',,,',',','',,',,',,','',,,',',',,,',',',',',',',','',''','',',','','',''','',',''','''',',''',',',',',','''''''''''''','','''','','','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>>>>>;>>>>>>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>,>>>>>,>>,>>>>>>>>,>>,>>,>,>,>,>>>>>>>>>>>>,>>,>>,>>,>,>>>>,>>>,,>>,>>,>,>,>>,>,,>,>,>,>,>,>,>,>,>,>,>>,,>,,>,>,>,,>,>,,>,,>>,,>,,>,,,>,,>,>,,,,,,,,,>,>,>,,,>,,>,>,,,,>,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,',,,,',,,',',',',',',',,',',',',,,',,,',',',,',',,,',',',',',',',',',',',',',,',',,',',','',',',',',',','',','',','','',''''''''''''','','',''','''''''''''''''''',''''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>>>>;>>>>;>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>>,>,>>>>>>>>,>>>>>>>>,>,>,>,>,>,>>,>>,>>,>>>>,,,>>,,>>>,>,>>,>,>>,>,>>,>>,>,>,>,>,>,>,>,>,,,>>,>,,>,>,,>,,,>,,>,>,,>,,>,,>,,,>,,,,>,>,>,>,,,,,,,>,,,,,,,,,>,,,,,,,,,>,,,,,,,,>,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,',,',,,,,,,',,',,,,,',,,,',,,,,,,,,,,,,,',,,',,,',,,,',,',,,',,',,'',',',,',',',,',',',',',','',','',',',',','',''',',''','''','''',''',',',',',',',','''''''','''',''''',''''''''''''',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>>>>;>>>>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>,>>,>,>>>>>>>,>,>>>>>>,>>>>>,>>>>>,>>,>,>>>>,>>>,>,>>,>,>>>,,>,>,>,>,>,>,>,>,>,>,>,>,>>,,,>,>,,>,>,>,>,>,>,,,>,,>,,,,>,>,,>,>,,,,,,>,,>,>,>,,,,,>,,>,,,,,>,,,>,,,,,>,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,',,,,,,',,,,',,,,',,,,',',',',',',',,',,,',,',',,',,'',',',',,,',,',',',',',',',',',',',',',','','','',',',','''',',',','',',''',''''''''''''''''',',',''''',''','''''',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>>>>>,>>,>>>>>,>,>>>>>,>,>>,>,>>>,>>>,>,>>,>,>>,>,>>,>,,>>,>>>,>>,>,>,>,>,>,>,>,>,,,>>,>,,>>,>,,,>,>,,,>,>,,>,,>,>,,,>,,>,,>,>,,,,>,,,,,,,>,,,,,,,,>,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,',,,,,,',,,',,,,',,,,,,,,,,,,,,',,',',,',,,',',',,,,',,,',','',,',,',,',',',',',',',','','',',',',','''',',,'',','',','',','',',',',',',',',',''''''',''''',''','''''',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>>>>>>>;>>>>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>>,>>>>>>,>,>>>>>,>,>,>>>>,>>,>,>>>,>>,>,>,>>,>>,>,>>,>>>,>,,>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,,>,>>,,,,>>,,>,>,,>,>,,,>,,>,,>,,,,,>,,,>,>,>,,,>,,>,>,,,,>,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,',,',,,',,,,,',,',',',',',',',,,',,,',,',',,,',,'',,',',,',,',',',',',',',',',',',',,',',,'','',',',,',''',',''','''','''','',''''''''''''''''''',''',','''''''','''''''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>;>>;>>>>;>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>,>>>>,>>>,>>>,>>>,>>,>>>>>>>>>>>,>>>,>,>>>>>,>,>>>>>>>>,>>>,>>>>,>,>>,>>,>>,>>,>>>,,>,,,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,,>>,>,,>,>,,>,,,,>,>,,,>,,,>,>,,,>,,,,,,,>,,,,,,,,,>,,,,>,,,,,>,,,>,,>,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,,,,,,,',,',,,,,,,,,,,',,,,,,,,,,,,,,,,,,,',',,',,',,,,'',,',,,',',',',',',',',',',',',',',',','',',''',,',','',''',',''',',',',''',','','',',',',',',',',','''''''''','''''''',''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>,>>>>>>,>,>,>,>,>,>>,>,>>>,>>>,>>,>,>>,,>>,>>>>,>>,>>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,,,>,,>,,>,,>,>,,,,>,,,>,,,,,>,,,>,>,>,,,,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,',,,,,,,,,,,',,',,',,,',',',',',',',',',',,,',,',,',',,,',,'',,',,,',',,,',',,,',,',',',',',',',',',,,'','',','',','',,'',',''',',''','','''''''''''''''''','','','''',','''''''','','','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>>>>;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>,>>>>>>>,>,>>>>,>>,>,>,>>>>>>>>>>>>,>>>,>,>>,,>>,>,>>,>>>>,>,,>,>,>,,,>,>,>,>,>,>,>,>,>,,,>,>>,,>,>,,>,,>>,>,>,,>,>,,>,,>,>,>,>,,>,>,,,>,,,,,,,,>,>,,,,,,>,,,,,,,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,',,,',,,',',,',,,',,'',,,''',,,''',',',',',',',',','','''',',','',',''',''',''',','''','',''',',',',',',',',''''''''''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>,>>,>>>>>>>>,>,>>>>>>,>>>,>>>>>>>>,>,>,>,,>,>>,>>>>,>>,>,>>,>,>>,,>>,>>>,>,>>>>>>,>,>,>,>,>,>,>,>>>,,,>,>,,>,>,>,,,,,>,,>,,,>,,>,,>,,,,,>,,,,,>,,,>,>,>,,,,,,,,>,,,,,,,>,,>,,>,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,,,,,,',,,',,,,,',,,,,',,',,',,,',,',',',',',,,,,',,',,,',,,',,',',,',',',,,'',,,,'',,,,',',',',',',',',',',',,'',',',,''',,'',,'',',''',','','',','''''''''''''''''','',','''''''''','',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>,>>>,>,>,>,>>>>>,>>>>>,>>,>,>>,>>>,>>>>,>,>>,>,>,>,>,>,,,,>,>,>,>,>,>,>,>,,,,>>,>,>,>,,>,,>>>,>,>,,>,>,,,,>,,>,>,,>,,>,,,>,,,,,,,>,,>,,>,,,>,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',',,,,,',,,',,,,,,,,,,,,,',',,',,,',',',,',,',,',',,,',',,'',',,'',',',',',',',',',',',','',,','','',,''',''',','','''',''','''',',',',',',','',''''''''','',''''''''''','''''''',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>;>>>>;>>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>,>>>>>,>>>>,>>>>,>>>>>>>>>,>,>>>,>,>,>>,>>>,>>,>,>,,>,>,>>,>>,>,>>,>,>>>>>,>,>,>,>,>,>,>,>>,,,>,>,>,>,,>,,,,,,,>,>,,,>,>,,>,>,,>,,,>,,>,,,>,>,>,,,,,,,,>,,,,,>,,,>,,,,,,>,,,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,',,,,,,,,,,,',,,,,,,,',',',',',',,,,,',',',,,,,',,',',',,,'',',,',,',',',,',,,',',',',',',',',',',''',','',''',','',,''','',,'',','',','''''''''''''','',',''','''''',''''''','''''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>,>>>>>,>>>>,>>>>,>,>,>>>>>>,>>>>,>>,>>,>>>,>,>>>>>,>>>,>,,>,>,,>,>,>,,,>,>,>,>,>,>,>,,>,,>>,>,>,>,>,>,>,>,>>,,>,>,,,>,,,,,,>,,>,,,>,,,>,,,,,,,>,>,,,,,,>,,,,,>,,,>,,>,,,,>,,,,,,,>,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,,,,,,,,',,,,',,',,,,,,,,,,,,,,',',,,,,,',',',,',,,,,',',,,,',,'',,',',',',',',',',',',',',''',',,,',',,',','',',''',,'',''',''','''',',',',',',','''''''','''','''''',''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>,>>>>>>,>,>,>>,>,>>,>>,>>,>,>>,>,,>,>,>,>>>,>>,>>>>,>,>>,>,>,>,>,>,>,>,>,>>,,>,,,>,,>,,>,,>,,,>,,,>,>,,>,>,>,,>,,,>,,,>,,>,,>,>,,,,>,,>,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',,',,,,',,,,,,,',,',',',',',,,,',',--*-->,,',,'',',,','',,',,',',',',',',',',',',',',',',',''''''',''','',','',,''','',','','',','''''''''''''','','''''',''',''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>>>;>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>,>>>>>>,>>,>>,>>>,>>>>,>>>>,>,>>>>>>>>>>,>>,>>,>>,>>>,>>,>>>,>>,>>,>,>,>,>,,>,>>,>,>,>,>,>,>,>,>,>,,,>,>,>,>,>,>,,>,,>>,,>>,,,>,,,,>,,>,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;**-,,',,,,,,,,',,,,',',,,,,,,,,,,,,,,',',,,=*&&&&&&-,,',,>=*-,,,,',',',',',,,',',',',',',',',',',',',',,',,',',,','''',''',,'','''','',''',',',',',',',''',''',','''''''',''''''',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>>;>>>;>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>,>,>>>>,>,>,>,>,>>,>>>>>,>>,>,>,>>>,>>,>,>,>>>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,>>,,>,>,>,>,,>,>,>,,>,>,,,>,,>,>,,>,,,>,,>,,,>,>,,,>,>,>,,,>,,>,,>,,,,,>,,>,,,>,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,;&&&&;,,',,,,,,,,,',,,,,,,',',',',',',,,,,,>*%&&&%&&&>,',,,*&&&-',',,,',,,','',,',,,',',',',',',',',',','','',','''',,,'',,''','',',''','','''''''''''''',''''''''''','',''''',''''''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>>,>>,>>,>>>>>>>>>>>,>,>>>>>>>>>,>>>,>,>>>,>>>,>>,,>,>,>>,>>,,>,>>>,>,>,>,>,>,>,>,>,>,>,,,>,,>>,>,,>,,>,,>,>,,>,,,>,>,,>,,,>,,,>,,>,,,>,,,,,>,,,,,,,>,,,,,,,,,,,,>,,,,,,>,,,,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,*&&&&*,,,,',,',,,,,,',,',,,,,,,,,,,,,',',',&&&&%*&*&*,,','-&&&&&',,'',,'',',,'',',',',',',',',',',',',',,','',',',,'''',''',,'',''',','','',',',',',','''','',',''','''''''''''',''''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>>,>>,>>>,>>>>>>,>>,>>>,>>>>>>,>,>,>,>>>,>>,>,>,>>,>>,>>>,>>>,>,>,>>,>,,,>,>,>,>>,>,>,>,>,>,>>,>,>,,,>,>,>,>,>,,,,>,>,>,,>,,>,,>,,>>,,>,,,>,,,>,>,,,>,>,,,,,,>,>,,>,>,,,,,,,,,,,,,,>,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*%&&&*,,,,,,,,',,',,,,,,',,',',',',',,,,,,=&&&&=,,,,,',,,,-&&&&*,',,',',,',,',,,',',',',',',',',','','''',','',',''',','',''','',','''','',''''''''''',',''''''','''','','',''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>;>>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>,>>>>,>>>,>>,>,>,>>>>>>>>,>,>,>>>>>>,>>,>>,>>,>,>>>,>,>>,>>>>,>,>>,,>,>,>,>,>,>,,>,>,,>>,>,>,>,>,,>>,,>,,,>>,,>,,>,>,,,,>,,>,,,>,,,,,>,,,,,,>,,>,,,,,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',>&&&&;,,,,,,',,,,,,',,,,,,,,,,,,,,,,',','>*&&&=,,',,,,'',,,&&&&-,,',,',',',','',',',,',',',',',',',',',,',',,','',','',',',','''''',','','',',',',',''''',','''''',''','''''',''','''',''','''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>>,>,>,>,>>>>>,>,>,>>,>,>,>,>,>>,,>>>,>,>,,>,>>,>,>>,>,>,>,>,>,>>,>,>>,,,,>,,,>,>,,,>,>,>,,,>,,>,,,,>,>,,>,,,>,,,>,>,,,,>,>,,,,,,,,>,,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,>*=;,',,',,,,',',,,,',,',',',',',',,,,,,-&%&*,',,',',,,',',=*;,',,',',,',',,,',,','',',',',',',',',','''',''',','',',''',''',',',','',''',''''''''',',''''','',''''''''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>>>,>,>>,>,>>>,>>>,>>,>>,>,>,>>>>>>>>>>,>,>>>>,>>,>>>,>>>,>>,>>>,,>>,>>>,>,,>,>,>,>,>,>,>,>,>,,,>,,,>>>,>,>,>,,>>,,,,>,>,>,>,,>,>,,,,>,,>,,,>,,,,,>,>,,,,,,>,,>,,,>,,,,>,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',',,,*&&&-,,',,,',',',',',,,',',,',',,'',',',',,',',',',',',',','',,,',',','','',',,'',,'',''''','','',',',','''''',''''''''','',''','',''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>>;>>>>>>>>>>>;>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>>>>,>,>,>,>,>>,>>,,>>>,>>,>>,,>>,>>,,>>>,,>,>,>>>,>>,>,>,>,>,>,>,>,>,>,>>>,,,>,>,>,>,,,>>,>,,>,,,,,>,,,>,>,,,>,,>,,,>,>,,,,,>,,>,,,,,>,,,,,,,,,,>,,,,,,,,>,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,',,,,,',,,',,,,',',,,',',',',,,,,','&&&&>,',,',,,,',,',,',',,',',',',,,',',','',',',',',','','',,''',',','',',''''',''',''',',''',','''''''',',','',''','',''''','''''''''''''''''''',''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>,>>,>>,>>>>,>,>>>>>>>>>>>,>>,>>>,>,>>,>,>>>,>,>>>>,,>>>,>,>,,>>,>,>,>,>,>,>,>,>,>,>,,,,>>,>,>,,,>,>,,,>,>,,>>,>,,>,,,>,>,,>,,,>,,,,,>,>,,,,,,,>,,,,,>,>,,,,,,,,,,,>,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,',,,,',,,,,',,,',,,,,,',,,,,,,,',',,,,'&&&&>,,',,',',,',,',',,',,,',','',',,',,',,',',',',',',',','',,',','',''',',,',',',',','',','''',',','''''''',''','''''','''''','''',''''',''','''''''''=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>,>>>,>>>>>>,>>>>,>>>>>,>,>,>,>,>>,>>,>,>>>>>,>>,>,>>,>,,>>,>,,>>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>==-=;>,>,>,,>,>,>->,>,,,,,>,,>;-==->-===>,>,>,,,,>,>;-,,,,,>,,,,,,-=-=;;===-,>,,,,,,,,,,->,,,,,,,,,,,,----,,,,,,,,,,,,',,,,,,,>>>>;>>>,,,,,',>>>>>,,>=****=>',',',,,,'>>>>&&&&->>>>,,','>>>>>>>>,,',',,,>>>>',',;=***=;,',',',',>-****=;,,'',',',,','','',''',''','''',','',-****=->','''''''','>>>>'','>=***=-'','''',;=***=->''*&*'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>,>>>,>>>>>>>,>>,>,>>>>>>>>>>>,>>>>>>>,>,>>,>>,>,>>,>>>,>>,>>,>,>,>,>>,>,>,>,>,>,>,>,>,,>,>,*&&%&,,>,,>,,,>,*&;,,>,>>,,>,,*%&&=,&&&&*,,,,>,,,,,,&&,>,,,,,>,,,>&&&&;;&&&&-,,,>,,,,,,>&*,,,,,,,,,,,-&%&&,,,,,,,,,',,,,,,,,,,&&&&&&&&',,,,,,*&&&*,*&&&&&&&&&-,,,,',,,*&&&&&&&&&&&&-,,,'*&&&&&&&>,',','-&&&&',;*&&&&&&>,',',',;*&&&&&&&&&*>,'','''','','',','',''',',''',>=&&&&&&&&&*>,'','',''>&&&&>'>=&&&&&&-''''''=*&&&&&&&&==&&&*,'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>;>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>,>>>>>>>>>,>,>,>,>,>>>,,>,>,>>>,>,>,>>,>,>>,>,>,>,,>,>>,>,>,>>,>,>,>,>,>,>,>,>,,>,=%&&&>>,>,,>>,>>&&*,>,,,,>,,>;&&%&;,*&%&&,>,,,>,>,,-&&-,>,>,,,>,,-&%&&,,&&%&*,,,,,>,,,,*&&>,>,,,,,,,,*&&&*,,,,,',,,,,,,,,,,,,'&&&&%&&*,,,',,,*&&&&*&&&%&&&&&&&*>',,,',*&&&&%&&&&&&&-'',,*&&&&&&&>,,',',-&&&*,;&&&&&&&*'',',',=&&&&&&&&&&&&&=','',','',','',''',',',''','-&&&&&&&&&&&&&='''''''',&&&&>>*&&&&&&*,''''>*&&&&&&&&&&&&&&*;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>,>>,>>>>,>>>,>,>,>,>>>>>>>>>>,>>>>>,>>,>>>>,>>,>>>,>,>>>,>>>,>>,>,>,>,>,,>,>,>,>,>,>,>,>,>,,>&&%%=,,>>,,,,>=&&&,>,>,,,>,,=%&&&,,-&&&&;,>,,,,,,,*%&*,,,,,,,,,,*&&&=,,=&&&&,,,,,,,,,,&&&=,,,,,,,,,,&&&&;,,,,,,,,,,,,,,,,',,,*&%&&&%*,,,,,,,*%&&&%&&*&&&&&&&&&&,,',,,*&&&&&&&%&&&&=,,',*&&&&&&&>',',',-&&&&;&&&&*&&&;,',','*&&&&&&*&*&&&&&&=',','',''',',','''','',','=&&&&&*****&&&&&=','',''>&&&&>*&&&***&-','',*&&&&&*=**&&&&&*,'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>,>>,>>>>>>>>,>>>,>>>>>>>>>>>>>,>,>,>,>,>,>,>,>>,>,>,,>>,>>,,>>,>,>,>,>,>,>,>>,>>,>>,>,>,>,>,>,>,,>,>,>>,&&&&&>,,,,>>,,&&%&=,,,,>,,,,&&%&=,>,&&%&*,,>,>,>,;&&%&;>,,>,,>,>&&%&;,,;&%&&->,,,,,,,-&&&&,,,,,,,,,;&%&&,,,,,,,,,,,,,,,,,,,,,=--*&&&&,,,,',,*&&&&&*;,',,-*&&&&&*,,',,--=-&&&&*-=-->',,'-=-=&&&&>,',',,-&&&*&&&=,,'>*,',','*&&&&*;,,',>=&&&&&='',',',,',''',',',''''''-&&&&*-,',',-*&&&&;'''',',&&&&*&&=,'',=>''''=&&&&=>''',-&&&&*,'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>;>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>,>>>>,>>>,>>,>>,>,>>>>>>>>>>>>>>>,>>,>>>>>>>,>,>>>>,>>>,>,>,>,>,>,>,>,>,,>,>,>,>,>,>,>,>,,>,,,>-%&%&>>>,>,,>-&%&&&,>>,,>,>>&&&&>,,,*&&&&,,,,,,,,=&&&&*,,,,,,,,-&&&&,,>,&&&&*,,,,,,,,*%&&&-,,,,,,,,*&&&=,,,,,,,,,,,',,,,,,,,,,,,-&&&*,,',,,,*&%&&;,,,,,',,-&&&&&;,,,,,,,'&&&&-,,,,,,',,',,>&&&&>,',,',-&&&&&&;,',',',',',=&&&&=,'',''''>*&&&*,','''''',',''','',',,',*&&&*>','''',>*&&&*,,''''>&&&&&&-'''''''''';&&&&*'''''''-&&&&-'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>,>,>,>,>,,>,>>,>>,>,>,>,>>,>,,>>,,>>,>,>>>,>>,>>,>,>>,>,>,>,>,>,>,,>,>,>>,,>*%&&=,,>,,>,*&&&%&;,,,>,,,*&%&*,>,>;&%&&;>,>,>,,&%&%&&,,>,>,,,&&%&=,,,,=%&%*>,,,>,,;&&&%&*,,,,,,,>&&%&;,,,,,,,,,,,,',,,,,',,,,,=&&%*,,,',,,*&&&*',,',,,,,'-&&&&*,,'',','&&&&-',',',',',,';&&&&>,,'',,-&&&&&-,',',',',',,*&&&=',',',,',,>*&&&='',,',,'','',''','''',=&&&&-'''','''';&&&&-'','',&&&&&=','''''',''=&&&*,''''''''*&&&*'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>;>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>,>>>>,>>,>,>>,>,>>,>>>>,>>>>>>>>>>>>>>>,>>>,>>>,>>,>,>>,>>,>>>,>>>,,,>>,>,,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,*&%&&,,>,>,>&%&%&&*>,,>,>,&&&%-,,,,>&&%&=,,,,,,-&&&&&&=,,,,,,>&&&&;,,,,>&&&&-,,,,,,*&%&&%&;,,,,,,-&&&&,,,,,',,,',,,,,,,',,,,',,-&&&&,,,,,,,*&&&*,,,,',',,',*&&&&>,,,,',,*&%&-,,,,',,,',',>&&&&>',,'',-&&&&*',',',',',',=&&&&','','','','=&&&*,''','','','',''',',''*&&&*',','','','*&&&*'''',,&&&&*,''','',''''*&&&='''''''''-&&&&,''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>>,>,>,>,>,>,>,>>,>,>>,>>,>>>>,>>,>>,,>>,>,>>>,>,>>,>>,>,>,>,>,>,>,>,>,>,,>,>,>,>-&&%&;,>,,>=&&&&%&&>>,,>,;&%&&>,>,,,=&&&&>,>,>,*%&%&%&&,,,>,,=&%&&,,,,,,&&%&*,,,,,,&&&&&&&*,,,,,,*&&&=,,,,,,,,,,,,,,,,,,,,,,,,,-%&&*,,,',,,*&%&*,,',,,,',,,;&%&&-',',,',&&&&-',',,',',,,';&&&&>,',,',-&%&&;,',',',',','&&&&-,',,',',',',>&&&&,,','',','','',',''',;&&&&;''''''','',-&&&&,,'''>&&&&='''''''''','*&&&-'''''''''>*&&&,''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>,>>>,>,>>,>,>>>>,>>>>>>>>>>>>>>,>>>>>,>>,>>,,,>>,>>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,>&&&%=,,>,>&&%&*&&&=,,,,>*&&&*,,,>,>;%&%&;,,,,>&&&&*&&&;>,,,>&&&&=,,,,,,=&&&&,,,,,-&%&&&&&&,,,,,>&&%&;,,,,,,,,,,,,,,,,,,,',,,,,-&&&&',,,',,*&&&*,,,,',,,,',,*&&&*,,',,,'*&&&=,,'',',,'',,>&&&&>,',',,-&&&&,,',',',',',>&&&&>''','',',',',*&&&>',',''',''','''','''=&&&*,',',','''''>&&&&;'',',&&&&>''''''''''''*&&&;'''''''''>&&&*>''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>,>>,>>>,>>>>,>>>>>>>>>>,>,>>,>,>,>,>,>,>,>>>,>,>>,>>,>>>>,>,>,>,>,>,>,>,>,>,>>>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,>,*%&&&,>,,-&%&*,&%&&>,>,,&%&%-,>,,,,,&&&&=>,>,*&%&--&%&*,,,,>&&&&>,>,,,,>&%&&-,,,,*&&&>=%&&-,,,,-&&&*,,',,,,,,,,,,,',,,,,,',,,,-%&&&,',,,,,*%&&*,,',,',',,,,*&&%*,,,',,,*%&&-',,,,,',,,',>%&&&>',,','-&&&*,',',',',','-&&&*--------------&&&&-''',','',','',','','*&&&*,''''''',',',*&&&-'''',&&&&>',','','''''*&&&-''''''''',&&&&,''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">;>>>>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>>>>>>,>,>,>>,>>,>>,>,>>,>>,>>,>>,>,>>,>>,>,>,>,>,>,>,>,>,>,>,,,>,>,>,,>>,>,;&%&&>>,,*&&%-,=&&&-,,,-&&&&,,,>,,,,=&%&&,,,,&&%&>,*%&&>,,,*&%&*,,,,>,,>*&&%*,,,;%&%*,>*&%&,,,,*&%&=,,,,,',,,,,,,,,,,',,,,,,',-&&&*,,,,,,,*&&&*,,,,,,,,',,,*%&&*,',,',,*&&&-,','',,'',,'>&&&&>,',',,-&&&*,',',',',','=&&&&&&&&&&&&&&&&&&&&&&-',''','','',','','',*&&&*',',','''''''*&&&*',''>&&&&>'''''''','''*&&&*''','''''-&&&&,''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>;>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>>,>>>>,>>>,>>,>>>>>>>,>>,>>,>,>,>,>,>,>,>,>>>>>,>>,>>>,>,>>,>>,>>,>>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,&&%&=,>>&%&&,,;%&%*>>,*&%&*>,,,>,>,;&&&&;,,-&&&=,,-&&&=,,,&&&&-,,,,,,,,=&&&&,,,=&&&-,,*&&&;,,>&&&&>,,,,,,,,,,,,,,,,,,,,,,,,,,=&&&&,',',,,*&%&*',',',',,',,*&&%*,,',,,,&&&&-,',,,',,,',,>&&&&>',',',-&&&&',',',',',',*&&&&&&&&&&&&&&&&&&&&&&>,',',','','''','',''*&&&*''''''','',',*&&&*'',',&&&&>''''''''''''=&&&*,''''''''=&*&*'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>>>>>,>>>>>>>>>>,>>,>>>,>>>>,>>>>>>>>>>>>>>,>,>>,>>>,>>,>>,>,>,>,>>,>,,>,>,>,>,>,>,>>,>,>,>,>,>,>,>,>,>,,>,>>,>,,>=&%&&,,*&&&=>,,*&&&;,>&&&&-,>,,,,,,>&&%&=,,&&%&;,>,&&%*>,;&&%&>,,,,,,,,>&&&&;,>&&%*,,,;&&&*,,=&%&*,,,,,,,,',,,,,,,,,,,',,',,,-&%&*,,,,',,*&&&*,,,,,,,,,,',*&&&*,,,',',*%&&-,,'',,'',,',>&&&&>,,',',-&&&*,',',',',','*&&&&******************,'','''','',','','',,*&&&*',','''',''''*&&&*''''>&&*&,''','''''',';&&&&=''''''';&&&&-'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>,>>>>,>,>,>,>,>,>,>>>,>>>,>>,>>,>>,>>>>,>,>>>>,>>,>>,>,>,>,,>,>,>,>,>,>,>,>,,>,>,>,,>,>,>;&&&&>,&%&&,,,>-&%&*,-&%&&,,,>,>,>,,=&&&&,;&&&*,,,,*&&&-,=%&&*,,>,>,,,,,*&%&*,=&&&=,,,,*%&*>,&&&&-,,,,,,,,,,,,',,,',,,,,,,,,,=&&&&,,,,,,,*&%&*,,',',',',,,*&&&&',',,,'&&&&-',,,',,',',,>%&&&>',,','=&&&*',',',',',',*&&&*,,',','',''''',''',',',',''','''','''''*&&&*''''','''',',*&&&*,''',&&&&>,''''',''''''=&&&&=''''';&&&&*,'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>,>>>>>>>,>,>>,>>>>>,>,>>>>>>>>>>>,>>,>>>,>,>,>>,>>,>>,,>,>>,>,,>>,>,>,>>,>>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,,,>,&%&&--&&&*,>,,>&&&&,*&%&*,,,,,,,,>,;&%&%>=%&%-,,>,>&&&*,&&&&-,,,,,,>,,,-&&&&,&&%*>,,,,-&&&=>&&%&>,,,,',,,,,,,,,,,,,,,,,,,,',-&&&*,,',,,,*&&&*,,,,,,,,,,',*&&&&',,',,'&&&&-,',,',,',,',>&&&&>,',','-&%&&',',',',',',=&&&&'',',',',',,'',',''',','',''',','',',',*&&&*',','',''''''&&&&-'','>&&&&,'''','''''''',*&&&&**--*&&&&&>''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>,>>>>>>>>,>,>>>>>>,>,>,>,>,>>>,>,>,>>>>>,>>,>,>,>>>>,>>,>>,,>,>>,>,>,>,>,>,>,>,>,>,>,,>,,>,>,>,>,>,>,>,=&%&&*&%&>,,>,,=&%&*&&&&;>,>,>,>,,,,&&&&=&&&&,,,,,,*&%&=&&&&,,,,,,,,,,,,&&&&=&&&*,,,,,,&&&&*&&&*,,,,,,,,,,,,,,,,',,',,',,,,,=&&%*,,,',,,*&%&*',',',',',,,&%&&*,',,','&&&&-,',',',,',,'>&&&&>,',,',-&&&*,',',',',','-&&&&>,',','','',',''',,'''','',',''','','''*&&&*''''''','',',&&&&-'''',&&&&>,'''''''''''''>*&&&&&&&&&&*&;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>,>,>>>,>>,>>>>>>>,>,>>>>>>>>>>>,>>>>>>,>,>,>>,>>,>>>,,>,>,>,>,>>>,,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,,>,;&&&%&%&*,>,,>,,&&&&&%&&,,,,,,,,>,,,-&%&&&%&->,,,,>;&&&%&%&*,,>,,,,,>,,,*&%&&%&&;,,,,,,=&&&&%&&-,,,,,,,,',,,,,,,,,,,,,,,,,,,-&&&&',,,,,,*&&&*,,,,,,,,,,'>&&&&=,,',,,,*&%&-,,,',,',',',>&&%&>,',',,-&&&*,',',',',',,>&&&&-,''',,','','',,''',,'','','',''','',''-&&&&>',','''''''-&&&&>''''>&&&&,'','''',''''''''-&&&&&&&&&*,''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>,>>>,>>>>>>>>>>>>>>>,>>,>>>>>>,>,>,>,>,>>,,>,>>,>>>>,>,>>,,>>,>>,>>,>>,,>>>,>>>,>,>,>,>,>,>,>,>,>,>,>,>,,,>,>,,>,,>,&%&&&&&;,,>,,,>=%&%&%&=>,>,>,>,,,>,>&&&%&&&,,,>,,,,*%&&&&&-,,,,>,,,,,,,-&&&&&%*,,,,,,,>&%&&&&&,,,,,,,,,,,',,,,,,,',,,,,',,,-%&&*,,,',,,*&%&*,',',',',,,=&&&&>,',,','&&&&-',',,',,',,,>&&&&>',',',-&&&&',',',',','''&&&&*',,'','','',''',','','',''','','','''',&&&&-''''','',',*&&&*'',''>*&&&>'''','''''''''';*&&&&**=->''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>,>>,>>,>>>>>,>,>,>>>>>>>>>>,>>>>,>>>,>,>>>,>,>>,>>,>>,>,>,>>,,>,>,>,>,>,>,>,>,>,>,>,,>,,>,,>>,>,,>,>,,>,=&%%&%*>,,,>,,>>&&%&&%>,,,,,,,>,,,,,*%&&%&*,,,,,>,,-&&%&%*>,,,,,,,,,,,,,&&%&&&-,,,,,,,,=&&%&&*,,,,,,,,,,,,,-**-,,,,',,,,,,,-&&%*,,,,',,*&&&*,,,,,,,,',;&&&&*,,,',,,,*&&&-,,',',',,','>&&&&>,,',',-&&&*,',',',',',,'-&&&&=',',',','',',','',','',';**=,','',',''*&&&*,',''''''';&&&&='''''>&&&&,''''''''''''',*&&=;,,'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>;>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>,>>>>>>>>,>>,>>>>>>>>>,>>>>,>>>>>>>,>,>,>,>,>>,>,>>,>,>>>,,>,>>>,>>,>,>>,>,>,,>>,>,>,>,>,>,>,>,>,>,>,>,,>,>,>,,>,>,,>,,>,,;&&&&%-,,>,,>,,>*&&&&&,,,>,>,,,>,>,>-&%&&&>,,>,,,,,,&&&&&=,,,,,>,,>,,,,,*&&%&&,,,,,,,,,;&&&&&-,',,,',,,,,,=&&&&*,,,,',,',,,=&&&*,,,,,,,*%&&*,,',',',,>*&%&&;,',,',',&&&&-',,',,',',,,>&&&&>,',','-&&&&',',',',','','&&&&&;,'','',','>>',',''','';&&&&*,','''',';&&&&=''','','>*&&&*,',''',&&&&>'''''''''''''*&&;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>,>>,>>>>>>>>,>>>,>>>>>>,>>>,>,>>>>>>>>>>>,>>>>,>>>>,>,>>>>>,,>>,>,>>,>,>>>>,>>,>,>,>,>,>,>,>,>,>,>,>>,>,>,>,>,,>,>,>,,>,>*%&%*>,>,>,,>,,-%%&&=,>,,,,>,,,,,,,,&&&%*,>,,,>,,>,*&%&%;,,>,,,,,,,,,,,;&&&&=,,,,,,,,,,*%&%*,,,,,,,,,,,,;&&%&&&;,,,,,,,,,'-&%&&,',',,,*&&&&=,,,,,,'=*%&&&*,,',,',,'*&&&-,',,',,,',',>&&&&>,',',,-&&&*,',',',',',''';&&&&&=>'',''',=*&''',','','*&&&&&='',',''''*&&&&=,'''''>*&&&&-''''''>&&&&>'','''''','',&&&-,',,;-**=*-,'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +";>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>,>>,>>>>,>>>>>,>,>,>,>,>>,>,>>,>,>>>>,>,,>>>,>>,>>,>,>,,>,>,>>,>>>,>,>,>,>,>,>,>,>,,,>,,>,>,>>,,,,>,>,,>-&%&*,,,,,>,,>,,&&%&;,,,>,,,>,>,>,,,*%&&-,,,,,,,,,,>&&&&,,,,,,,,,,>,,,,,&%&&>,,,,,,,,,,-&&&*,,,,,,,,,,,,=&&&&&&-,,,,,,,,,,-&&&*,,,,',,*&&&&&**--=*&&&&&&&>',,',,',,&&&&-',',,',',',,>&&&&>',,','-&&&&',',',',',',','=&&&&&**=--**&&&&=',''',''>&&&&&&*,'''''',',*&&&&*=---*&&&&&*','',''>*&&&>'''',''''''',*&&&&*&&&&&&&&&&=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>;>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>,>>>>>>>>>>>>>,>>>>,>,>>>>>>>>>>,>>>,>>,>>,>,>>,>>,,>>,>>,>,>>>>,>,>,,>>,,>,>,>,>,>,>,>,>,,>>,>,>,,>,,,>>,>,,>,,>>&&&>>,>,,,>,,,,=&&*>,>,,>,,,,,,,,>,-&&&,,>,>,,,,,,,*&&=,,,,,>,,,,,,,,,,=&&=,,,,,,,,,,,,&&&;,,,,,,,,',,,;&%&&%&-,,',,',,,,=&&&&,,,,,,,*%&&&&&&&&&&&&&&&*>,,',,',,,'&&&&-,,',',,',,',>&&&&>,',,',-&&&*,',',',',',','',-&&&&&&&&&&&&&&&*,',''',',*&&&&&=',',','','>*&&&&&&&&&&&&&*''''''''>&&&&,'''''''''''''*&&&&&&&&&&&&&&&&*,''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>,>>,>,>>,>,>>>>>,>>>>>,>,>,>,>,>>,>>,>>>,>>>,>>,>>>,>,>,>>>,,>,>,>,>>,,>>,>,>,>,>,>,>,,>,>,,>,,>,>,>>,,>,,>,>,>,,*&*,,>,,>,,>,>,,&%-,,,,,,,>,>,>,,,,,&&=,,,,,>,,,,,,;%&>,,>,,,,,,,,,,,,,;%&;,,,,,,,,,,,,=&&,,,,',,,,,,,,,&&&&&&,,,,,,,,,',-%&&*,',,',,*&&&&&&&&&&&&&&&*>,',,,,,',',*%&&-,',,,',,'',,>&&&&>,',','-&&&&',',',',',',','',;*&&&&&&&&&&&*-,'',','',,=&&&&&;''''''''''',=&&&&&&&&&&*-''',''''',&&&&>,''''''''''''>=&&&&&&&****&&&&&=''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>,>>>>>>>>>>>>>>>>,>>>>,>,>>>>>>>>>>>,>>,>>,>>,>,>>,>>,>>,>>>,>,>>,>,>>>,>,>>,>,>,>,>,>,>,>>,>,>,,>,>,,>,,,>,,>,,,>,,>>-&;>,,>,,>,,,>,,=&>,>,>,>,,,,,,,,,,,*&,,>,,,,,>,,,,,*&,,,,,,,,,,,,>,,,,,&*,,,,,,,,,,,,,>*=,,,,,,,,,,,,,,>*%&*>,,,,,',,,,,-****,,,,,,,*&&&*>-*&&&%&**>,',,',',,',,,=***-,',',',,,'',>****>',',,,-***=',',',',','',','','-***&&&***;,'',''','''',=*&*;',',',',',''''>=**&&&**-,'',''',''',*==*,'','''',''''''';-=*-;,,'''>=&&&&,'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>,>>>>>,>>>>>>>>>>>,>,>>,>>>>,>>>>>>,>,>,>,>,>>,>>,>>,>>>>,>,>,>,>>,>,>,>,>,>>,,>,>>,,>,>,>,>,>,>,>,>,,>,>>,>,>>,>>,,>,,>,>,,>,,>;,,>,,>,,,>,,>,,;,,,,,,,>,,>,>,>,>,,>,,,,,,,,,,,,,,>>>,,,>,,>,,,,,,,,,,>>,,,,,,,,,,,,,,>,,,,,,',,,,,,,,,,>>,,,',,,,,,,',,,,,,,',,',,*%&&*,,,,>>>,,,,',,,',,',,,',,,,,',,',','',,,',,,,',,','','',',',',','',',',',',','',,>>>','',',',','',',',,>,',''''''''',','''''>,>,'',''''''',''''''''''''''''''''''''''''''''''''**&&;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>;>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>,>>,>,>>>>>>>>,>>>,>,>,>>>>>>>>>>,>>,>>,>>,>,>>>,>>>,>,>>,>>,>,>,>>,>,>,>>,>,>,>,>,>,>,,>,>,,,>,,>,,,,>,>,>,>,,>,,>,,>,,,>,,>,>,,,,>,,>,>,>,,,>,,,,,,,,,>,,>,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,',,,,,',*&&&*,,',,,,',,,,',,,',,',','',',',',,,,,'',','',,',',,',',',',',',',,',',',',','',',''',',''','','',''''',''''',',',',''''','',''''''''',''''''','''''''''','''''''''''''''''''''''*&&&='''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>,>>>>>,>>>>>>>>>>,>>,>>>,>>>>>>>,>,>,>,>,>>,>>,>>>,>>>,,>>,>,>>,>,>>,>>,>,>,>,>,>,>,>,>,>,>,>,>>,>,>>,>,>,,>>,>,,>,,>,,>,>,,>,>,>,,,>,,,>,>,,,,,,,,,>,,,,>,,,,>,,,,,,,,,>,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,',,,,,,,,,',,,,',,,,,,,,,',,,,*&&&*,,,,',',,'',,'',,,',,,,,',,',,,'',',,',',,',',','',',',',',',','''',',''',',','',',''',,'','','',,',''',','''''''',','',''''',''',''',''''''''','',''''''''''''''''''''''''''''**&&-'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>>,>>>>,>>>>>>>>>,>,>,>>>>>>>>>>,>>>,>>,>,>>,>>>,>,>,>>,>>,>,,>,>,>,>>>,>,>,>,>,>,>,>,,>,>,,>,>,>>,,>,>,,>,>,>,>,,>,,,,,>,>,,>,,,>,,>,>,>,,,,>,>,,,>,,,,>,>,,>,,,,,,,,,>,,,,,,,>,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,,',,',,',,,',,*%&&*,',,,,,',,,',,,',,','',,',,',',,',',',,',',',,',,',',',',',',',',,','',,',','',','',','',',''','''',',',''',',','''''''','',''',''''''','''''''''''''''''''''''''-;''''''''''',*&&&;'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>,>>>>>>,>,>>>>>>>>>,>,>,>,>>>>,>>>,>>>,>>,,>>,>>>,>,>,>>>>,>>>,>,,>>,>,>,>,>,>,>,>,>,,>,>,,>,,>,,>,>,,>,,,>,,>,>,>,>,,,,>,,>,,>,,,,,,>,>,,,,,,,,,>,,,,,,,,,,,>,,,,,,>,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,,',,',,,',,,,,,,,,,,*&&&*,,,',',,,',,,',,',,,,',',',',,',,',,',',',,',',,',',',',',',',',''',','','',',''',,''','','','',','','''',''''''',',',''''''''''','',''','','',''',''''''',''''';&&*;'''''''';*&&&*''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>,>>>>>>>,>>,>>>>>>,>,>,>>>>>>>>>>,,>>,>,>>,>>>,>>>,>>,,>>>>,>,,,>,>,>,>>,,>>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,>,,>,>,>,>,,,>,,>,>,,>,,>,,,>,>,,,,,>,>,,>,,,,,>,,>,>,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,',,',',',*&&&*,,,,,,',,',',,',,',',,,',,,',,',,',',',,',',',',',',',',',',',',',',','',,',',',''',,'','',',''''','',','',',',''''''','',''','''''''''''''''''',''''''','''''',*&&&&*--,>--*&&&&&-''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>,>>,>>>>>>>,>>,>>>>>>,>,>,>,>,>>>>,>>>>,>>,>>,>,>,>>>,,>,>>>>>>,>,>>,>>>,,>,>,>,>,>,>,>,>,,>,>,>,>,>,>,>,,>,>,,,,>,,>,,,>,,,>,,>,,,>,,,,,>,>,,,,>,,,,>,,,,,,,,,>,,,,>,,,,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,',,,,',',,',,,,,,,,,,,*%&&*,',',',,',,,',,',,,',',',',',',',,',,',',',',',',',',',',',','',','',',''',''','',''',',','''',',''',''',''''''',',',''''',''''','',''''''''''''''','''''''''''-&&&&&&&&&&&&&&&&&='''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>,>>>>>>>>>,>,>>>>>>>>,>,>>>>>>>>>>>,>,>>,>,>>,>>,>>,>>,>,>>>,>,,>,,>,>,>,>,,>>,>,>,>,>,>,>,>,>>,>,>,,,>,>,,,>,>,,,>>,>,>,,>,,,>,,,>,,>,,,>,>,,,,,>,>,,,>,,,,>,,>,,,,,,,>,,,,>,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,',,,',,,,,,,,,',,,,',,,,,,,',,',,',',,*&&&*,,,,,',,,',,,',,',',,',,,',,,',,',',',',,',,,',',',',',',',',,',',',',',,',','',',',''','',','',',''',''',',',''''''',','''',','''''','','','''''''''''''''''''';*&&&&&&&&&&&&&*;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>>>>>>>>>,>>>>>,>>,>,>>>>>>,>,>,>,>,>>>>>,>>>,>>,>>,>>,>,>>,>,>>>>,>>,>>,>,>>,>,>,>,>,>,>,>,>,,,>,,>,>>,,>,>,>,,,>>,,,>,,,>,>,>,>,>,,,>,,>,,,,,>,>,,,,,,,,,,>,,,,,,>,,>,,,,>,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,',',,,,,,',,,,,,*&&&*',',,',',',',,,',,,',,'',,',',,',',',,',',',',',',',',',',',''',','',',''',',','','',','',''','','',''','''''',',','''''','''''',','''''''''',''''''''''',''''''''>=*&*&&*&&&*-''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>,>>>>>>>>>>,>,>>>>>>>>>>>,>,>,>>,>>,>>,>>,>>>,>>,>>,,>,>,>>,>,>,>,>>,>,>,>,>,>,>,>>,>,>,>,,>>,>,,>,>>,,,>,,>,>,,,,,>,,,>,>,,>,,,>,>,,,,>,>,,>,,>,,,>,,>,,,,,,,,,,,,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',',,,,,,',,,,,,,',',,,,',',,-=-=-,,,',,,,,,,',',,',,',,,,',',',',,',',',',,',',',',',',',',',',','',',',',',''',',',','','','',''','',,'',',','''''',''','''','''''''''''',''''','''''''''''''''''''''>;;--;>,''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>,>>>>>>>>>>,>>>,>>>>,>>>>,>>,>>>>>,>>,>>,>>>>>,>,>,>,>,>>,>>>,>>,>>,>>,>>,,>,>,>,>>>,>,>,,>,>,>,>,,>,>,>,>,>,>,>,>,,>,>,>,,,>,>,,>,,,>,>,>,,>,>,>,,,,>,,,>,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,>,,>,,,,,,,,,,,,>,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,,',,,,,,',,,',,,',,,,',,,',',',',,,',,',','',,',,,',',,',',',',',,',',',',',',',',',',,','',','',,'',''','','',',''','','''''''''''',','','''','''',''','','''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>>>>>>,>>>>>>>>>>>,>,>>>>>>>>>>,>>,>>>,>>,>>,>,>,>>>,>>>,>,>>,>>>,>>>,>>>>,>,>,>,>,>,>,>,,>,>,,>,>>,>,,>,,>,>,>,,,>,,,>,,>,>,,>,,,>,,,>,>,>,,,>,,>,>,>,,>,>,,>,,>,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,',,,,,,,,,',,,,,,,',,,,,,,,,,,,,,',,,',,,',,,,',,,,',,,',',,,,',,',',,,'',',',,',',',',',',',',',',','',''',,','',''','',',','','''','','',',',','',','''','''''''','''','''''',''',''''','''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>,>>>,>>,>>,>,>>>>>,>,>,>,>,>>>>,>,>>,>>>>>>,>>>,>>,>,>>,>,>,>,>,,>>,,,>,>,>,>,>,>,>,>,>,>,>,,>,,,>,>,,>,,>,,>,>,>>,,,>,,>,,>,>,,,>,,,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,',,',,,,,',,',,,,',',',,',',',,,',,',',,'',,',',',',,,,'',',',',,'',,,',,',',',',',',',',',',',',','',,''',','',,'',,''',','',','','','''''''','''''','''','',''','''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>,>>>>>>>>,>>>>>>>>>>,>>>>>,>>>>>>>>>>>>,>,>>>,>>>,>,>,>>,,>>,>,>>,>>,>>,>,>>,,>>>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,>,>,,>,,>,>,,,>,,>,,,>,,,>,>,,,>,>,,,,,,,,,>,,,>,,>,,>,,,,,,,>,,>,,>,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,',,,',,,',,,','',,,',,',,',,,'',,',',',,,',',',',',',',','',','',,','',,''',''','','',''','',''',',',',''',',''','''''''''''','''','''','''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>,>>,>>>>>>>,>>,>,>,>,>,>,>>>>>,>>,>,>>>,>,>>>,>>,>>,>>,>,,>,>,>>>,,>,>,>,>,>,>,>,>,,>,>,,>,>,>,>,>,,>,>,,>,,>,,>,,>,,>,>,,>,,,,,>,,,,>,>,>,>,,,,>,,,,,,,,>,,>,,,,,,,,,,,,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,',,,,,,,,,',,,,,',',',,',,',',',',,,',,,,',,,,',,',,,,',,,,,',,',,',,',',,'',,,',',',,',',',',',',',',',,','',',''',',',',',',','','',''','','''''','''',''','','','','''',''',''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>,>>>,>>>>>>>>>>>,>>>>>>>>>>>,>>,>>>>>>>>>>>>>>>>>,>,>,>>>,>>,>>,>>,,>>,>>,>,>,>>>,>>>,,,>>>,>,>,>,>,>,>,>,>,>,>>,>,>,>,,,>,>,,>,>,>,,>,,>,,>,,,,>,,>,>,,,>,>,,,,,,,,>,,,,,>,>,,,,,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,',',,,,,,,,,,,,,,,,,,',,,,',,,',',,',,',',,'',',',,',',',,',',,''',,',',',',',',',',',',','','',',',,'',''',',''','',',''',',','',',',''',''','''''','''''',''''''''''''''',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>,>>>>>>>>>>>,>>,>>>>>>>,>>>>,>,>>>>>>>,>,>,>,>,>,>,>,>>,>>>>,>>,>>,>>,>>,>,>,>>,>,>,>,>,>,>>>,,>,>,>,>,>,>,>,>,>,,>,,,>,,>,>>,>,,,>,,>,,>,,>,,>,,>,>,,,>,,,,>,,,,,>,>,>,,,>,>,,,,,,>,,>,,,,,,>,,>,,>,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,,,',,',',,',',,,',',,',,',,',,,',,,',,,',,',',,,',,',',',,,',',',',',',',',',',',','',',','','',',','','','','''',',''''',''''''',''',''',',''','',''',''''','',''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>,>,>>>>>>>>>>>>>>>>>>,>>,>,>,>>>,>>,>>,>>>,>>,>>>,>,>,>,>,>,>>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,,,,>,>,>,,,>,>,,>,,,>,,,>,>,,>,>,,,>,,,,,,,,,,,,,,,>,,>,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',',',,,,,,,,,,,,',,,,,,,,,,,',,',',,',,',,',,',,'',,',',',,'',',',',,',',',',',','','',',','',',',''',','',','',','','',',''',',',''',''',''''''''''''''''',''''''''',''''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>,>>,>>>>>,>>,>,>,>,>,>,>,>>>,>>,>>>>,>>,>>,>>,,>>,>>,,>,>>,>,>,>,>,>>,>,>,>,>,>,>,>,>>,>,>,>,>,>>>>,,>,,,>>,,>,>,,,>,,>,>,,,>,,,,,>,,>,>,>,>,>,,,>,,,,,,,>,,,,,,,,,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,',,',,',,,,,,,',,',,',,',,,,,,,,,,',,',',',,,',',',',',,,',,,,',,',,',',,',,,',,',,',',,,',,','',',',',',',',,',','',',,',','',','','',','''','','','',''''''',''',''','',''','',','''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>,>>>>>>>>>,>>>>>>>,>>>>>>>>>,>>>>>>>>>>>>>>>>>>>,>>>,>>,>,>,>>>,>,>,>>,>,>,>>>,>,>>,>>,>>,,>,>,>,>,>,>,>,>,,,>,,>,,,>,,,,,>,,>>,,,>,,,>,>,,>,,,,>,,>,>,>,,,,,,,,,,,,,,>,,,>,,>,,,,>,,,,>,,>,,,,>,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,',,',,,,,,,,,,,,,,',,',',,,,,,,,,',,,,,,,,',,',,,',',,',,',',,',',',',,',',','',,',',,',',',',',','',',',',''','',',','','',''',',','''','',',',',',''',''','''''','''''''',''','',''''',''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>,>>>>>>>,>>>>>>>,>>>>>>,>>,>>,>>>,>>,>,>,>,>,>,>,>,>>>,>>>>,>>>>>,>>,>>>,>>,>>>,>,>,>,>,>,>,>>>,>,>,>,>,>,>,>,>>,>,>,>,>,,>>,>,>,,,>>,,>,>,,,>,,>,>,,>,,,,,,,,>,>,>,>,,>,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,',,,,,,,,,',,',',,,,',',',,,',,',',,,',,',,,',',,,',,',',',,,',,'',,',',',',',',',','',',',',',','',''',',',',',',''',','',''''''''''',''',''''',''''','',''''''''''','''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>,>>>>>>>>>>>>>,>>>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>,,>>,>,,>>,>>,,>>,>>,,>>,>>,>,>,>,>,,>,>,>,>,>,>,>,>,,,>,>,>,>,>>,,>,,,>,>,,,>,>,,>,,>,,,,>,>,,>,>,>,,,,,,,,,>,,,>,,>,,>,,>,,,,,,,,,>,,,,,,,,>,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,',',,,,,,,,,,,',',,,,,,',,,',,,',',,',,'',,,',',',,',,,''',',',,',',',',',',',',',,','','',',','',','','',','''',''','''',',',',',''',''','',''','''''''','','''''''',''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>>>>>>,>>,>,>>,>>,>>,>,>,>,>,>,>,>>>,>>>>>,>>>>,>>,>>>,>>,>>>>,>,>>,>,>>,>>,>,>,>,>,>,>,>,>>,>,,>,,>,>,,>,,>,>,>,,>>,,,>,,>,,>,>,,,,>,,,,,,,>,>,>,>,,,,,,,,,>,,,,,,>,,,,>,,,,,>,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,',,,,,,,,,',,,,,,',,,',',',,,,',',',,',',,',,,,',,',,,'',,',,,',,'',,,,',',',',,',',',',',',','',',',',',',','',',''',''',,'',','',','','''''''',''',''''',''',','','''''',''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>,>>>>>,>>>,>>>>>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>,>>,>,>>>,>,>>,>,>,>,>,>,,>,>>,,>>>,>,>,>,>,>,>,>,>,>,>,,>,>,>,>,>,,>,>,>,,>,,>,,,>>,,>,,>,,,>,>,,,>,>,>,,>,,,,,,,>,>,,>,,,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,',,',,,,',,,,,,,,',,',,,,,,',,',,,',,,,,,,',,,,,,,,,,,',,',',,',,,',,,,',',',',',','',,,',',,',',',',',',',','',','','','',',''',',',',''',''','','','',',',',''',''',''''''''''''''''''''','''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>,>>>>>>>>>>>>>>>>>>>>,>>>,>,>,>>,>,>,>,>,>,>,>,>>,>>,>>,>>>>,>>>,>>,>>,>>>>,>,>>,,>,>>,>,>>,>,>,>,>,>,>,>,>,>,>,>,>>,,>,,>,,>,,>>,,,>,,>,,,>,,,>,>,,,,,,>,,,,>,>,,,,,,,,,>,,,,>,,,,,,,,,>,,>,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,',,,,,,,,,,,,,',',,,',',',',',,,',,,',,,',,'',',,',,',,,',',,'',,','',',',',',',',',','',',',',','',',,'','','',','','','','',''''''''',''','','','','','',','''''''',''','''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>,>>>>>>>>>>>,>>>>,>>>>,>>,>>>,>>>>>>>>>>>>>>>>>>>>>>>,>>,>>,>>,>,>>,,>>,>>,>>,,>,>,>,>>,>,>,>>,>,>,>,>,>,>,>,>,,>,,,>,,>,,>,>,>,>,,>,,,>>,,>,,>,>,>,,,,>,>,>,,,>,>,,,,>,,>,>,,,,,>,,,,,>,,,,>,,,,,,>,,>,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,',,,,,,,,,,,,,,,,',,,,,,,',,,',,',,',,',,,,,',,,,,,,,,,',',,',,,',',',,,',',,',,',',,',',',',,,',',',',',',',',',,',',',',',','''',',''',','','','','''',',',',',''','''''''''''''''''''','''''''','''''''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''", +">>>>>>>>>>>>>>>>>>>>,>>>>>,>>>>>,>>>>>>,>>>>>>>,>,>>,>,>,>,>,>,>,>>,>>>,>>,>>>,>>>,>>,>>,>>>,>>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,,>,>,,>,,>,>,,>,,,>,,,>,,,,,>,>,,,,,,,>,,,,,,>,,,,,,,,,>,,,,,>,,,,>,,,,,,,,,,,,,,,>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',,,,',,,,',,',,,,,,,,,,,',,,,,',',,,',',',',',,,,',,',',,,',,',,',',,',,',',',,',','',,',',',',',',',','',''',','','',,',',',',''','','','',',''''''''''',''''','','','','',''''''','''''''',''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''"}; diff --git a/pkgs/core/gssdp/gssdp.nm b/pkgs/core/gssdp/gssdp.nm new file mode 100644 index 0000000..86b025d --- /dev/null +++ b/pkgs/core/gssdp/gssdp.nm @@ -0,0 +1,44 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gssdp +PKG_VER = 0.7.0 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gupnp.org +PKG_LICENSE = LGPL +PKG_SUMMARY = Resource discovery and announcement over SSDP. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += glib2 libsoup + +define PKG_DESCRIPTION + GSSDP implements resource discovery and announcement over SSDP. +endef + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/gupnp-av/gupnp-av.nm b/pkgs/core/gupnp-av/gupnp-av.nm new file mode 100644 index 0000000..2d6ef25 --- /dev/null +++ b/pkgs/core/gupnp-av/gupnp-av.nm @@ -0,0 +1,47 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gupnp-av +PKG_VER = 0.5.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gupnp.org +PKG_LICENSE = LGPL +PKG_SUMMARY = gupnp audio/video helpers. + +PKG_DEPS += gssdp gupnp + +define PKG_DESCRIPTION + GUPnP-AV is a collection of helpers for building AV (audio/video) \ + applications using GUPnP. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --without-gnome diff --git a/pkgs/core/gupnp-igd/gupnp-igd.nm b/pkgs/core/gupnp-igd/gupnp-igd.nm new file mode 100644 index 0000000..cef00a2 --- /dev/null +++ b/pkgs/core/gupnp-igd/gupnp-igd.nm @@ -0,0 +1,46 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gupnp-igd +PKG_VER = 0.1.3 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gupnp.org +PKG_LICENSE = LGPL +PKG_SUMMARY = gupnp - Internet Gateway device implementation (Microsoft). + +PKG_DEPS += gssdp gupnp libsoup + +define PKG_DESCRIPTION + This is a library to handle Internet Gateway Device port mappings. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --without-gnome diff --git a/pkgs/core/gupnp/gupnp.nm b/pkgs/core/gupnp/gupnp.nm new file mode 100644 index 0000000..6cbc325 --- /dev/null +++ b/pkgs/core/gupnp/gupnp.nm @@ -0,0 +1,49 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gupnp +PKG_VER = 0.13.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gupnp.org +PKG_LICENSE = LGPL +PKG_SUMMARY = An UPNP framework. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += glib2 gssdp libsoup libxml2 util-linux-ng + +define PKG_DESCRIPTION + GUPnP is an object-oriented open source framework for creating UPnP\ + devices and control points, written in C using GObject and libsoup.\ + The GUPnP API is intended to be easy to use, efficient and flexible. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --without-gnome diff --git a/pkgs/core/gzip/gzip.nm b/pkgs/core/gzip/gzip.nm new file mode 100644 index 0000000..8f2c0a8 --- /dev/null +++ b/pkgs/core/gzip/gzip.nm @@ -0,0 +1,71 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = gzip +PKG_VER = 1.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Compression +PKG_URL = http://www.gzip.org/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = The GNU data compression program. + +define PKG_DESCRIPTION + The gzip package contains the popular GNU gzip data compression \ + program. Gzipped files have a .gz extension. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + # NO_ASM is for textrels. + cd $(DIR_APP) && \ + DEFS=NO_ASM \ + CPPFLAGS="-DHAVE_LSTAT" \ + ./configure \ + --prefix=/usr \ + --bindir=/bin + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + cd $(DIR_APP) && make check +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/usr/bin + mv -v $(BUILDROOT)/bin/{gzexe,uncompress,zcmp,zdiff,zegrep} $(BUILDROOT)/usr/bin + mv -v $(BUILDROOT)/bin/{zfgrep,zforce,zgrep,zless,zmore,znew} $(BUILDROOT)/usr/bin +endef diff --git a/pkgs/core/gzip/patches/gzip-1.3.13-cve-2006-4337_len.patch b/pkgs/core/gzip/patches/gzip-1.3.13-cve-2006-4337_len.patch new file mode 100644 index 0000000..db9f981 --- /dev/null +++ b/pkgs/core/gzip/patches/gzip-1.3.13-cve-2006-4337_len.patch @@ -0,0 +1,15 @@ +http://cvs.fedoraproject.org/viewvc/devel/gzip/gzip-1.3.5-cve-2006-4337_len.patch?view=co + +http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-4337 + +--- gzip-1.3.5/unlzh.c.len 2006-11-22 09:35:10.000000000 +0100 ++++ gzip-1.3.5/unlzh.c 2006-11-22 09:38:52.000000000 +0100 +@@ -199,7 +199,7 @@ + } + *p = ch; + } +- start[len] = nextcode; ++ start[len] = start[len] + weight[len]; + } + } + diff --git a/pkgs/core/gzip/patches/gzip-1.3.13-cve-2006-4338.patch b/pkgs/core/gzip/patches/gzip-1.3.13-cve-2006-4338.patch new file mode 100644 index 0000000..2442ab1 --- /dev/null +++ b/pkgs/core/gzip/patches/gzip-1.3.13-cve-2006-4338.patch @@ -0,0 +1,33 @@ +http://cvs.fedoraproject.org/viewvc/devel/gzip/gzip-1.3.5-cve-2006-4338.patch?view=co + +http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-4338 + +--- gzip-1.3.3/unlzh.c.4338 2006-09-07 10:49:31.000000000 +0200 ++++ gzip-1.3.3/unlzh.c 2006-09-07 11:37:53.000000000 +0200 +@@ -260,7 +260,7 @@ + if (bitbuf & mask) c = right[c]; + else c = left [c]; + mask >>= 1; +- } while (c >= NT); ++ } while (c >= NT && (mask || c != left[c])); + } + fillbuf((int) pt_len[c]); + if (c <= 2) { +@@ -296,7 +296,7 @@ + if (bitbuf & mask) j = right[j]; + else j = left [j]; + mask >>= 1; +- } while (j >= NC); ++ } while (j >= NC && (mask || j != left[j])); + } + fillbuf((int) c_len[j]); + return j; +@@ -313,7 +313,7 @@ + if (bitbuf & mask) j = right[j]; + else j = left [j]; + mask >>= 1; +- } while (j >= NP); ++ } while (j >= NP && (mask || j != left[j])); + } + fillbuf((int) pt_len[j]); + if (j != 0) j = ((unsigned) 1 << (j - 1)) + getbits((int) (j - 1)); diff --git a/pkgs/core/gzip/patches/gzip-1.3.13-openbsd-owl-tmp.patch b/pkgs/core/gzip/patches/gzip-1.3.13-openbsd-owl-tmp.patch new file mode 100644 index 0000000..8028df3 --- /dev/null +++ b/pkgs/core/gzip/patches/gzip-1.3.13-openbsd-owl-tmp.patch @@ -0,0 +1,47 @@ +http://cvs.fedoraproject.org/viewvc/devel/gzip/gzip-1.3.12-openbsd-owl-tmp.patch?view=co + +--- gzip-1.3.12/znew.in.owl-tmp 2007-06-04 09:15:11.000000000 +0200 ++++ gzip-1.3.12/znew.in 2007-06-04 09:23:18.000000000 +0200 +@@ -55,28 +55,27 @@ + # block is the disk block size (best guess, need not be exact) + + warn="(does not preserve modes and timestamp)" +-tmp=${TMPDIR-/tmp}/zfoo.$$ +-set -C +-echo hi > $tmp || exit +-if test -z "`(${CPMOD-cpmod} $tmp $tmp) 2>&1`"; then +- cpmod=${CPMOD-cpmod} ++cpmod= ++cpmodarg= ++if type ${CPMOD:-cpmod} 2>/dev/null; then ++ cpmod=${CPMOD:-cpmod} + warn="" + fi + +-if test -z "$cpmod" && ${TOUCH-touch} -r $tmp $tmp 2>/dev/null; then +- cpmod="${TOUCH-touch}" ++if test -z "$cpmod"; then ++ cpmod=touch + cpmodarg="-r" + warn="(does not preserve file modes)" + fi + +-# check if GZIP env. variable uses -S or --suffix +-gzip -q $tmp +-ext=`echo $tmp* | sed "s|$tmp||"` +-rm -f $tmp* +-if test -z "$ext"; then +- echo znew: error determining gzip extension +- exit 1 +-fi ++case "$GZIP" in ++ *-S*) ext=`echo "$GZIP" | sed 's/^.*-S[[:space:]]*([^[:space:]]*).*$/\1/'` ++ ;; ++ *-suffix*) ext=`echo "$GZIP" | sed 's/^.*--suffix=([^[:space:]]*).*$/\1/'` ++ ;; ++ *) ext='.gz' ++ ;; ++esac + if test "$ext" = ".Z"; then + echo znew: cannot use .Z as gzip extension. + exit 1 diff --git a/pkgs/core/hdparm/hdparm.nm b/pkgs/core/hdparm/hdparm.nm new file mode 100644 index 0000000..67a32ab --- /dev/null +++ b/pkgs/core/hdparm/hdparm.nm @@ -0,0 +1,59 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = hdparm +PKG_VER = 9.27 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Hardware +PKG_URL = http://sourceforge.net/projects/hdparm/ +PKG_LICENSE = BSD +PKG_SUMMARY = A utility for displaying and/or setting hard disk parameters. + +define PKG_DESCRIPTION + Hdparm is a useful system utility for setting (E)IDE hard drive \ + parameters. For example, hdparm can be used to tweak hard drive \ + performance and to spin down hard drives for power conservation. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + # fix sgio.c failur + cd $(DIR_APP) && mv sgio.c sgio.c.orig + cd $(DIR_APP) && grep -v "#include <scsi/scsi.h>" sgio.c.orig > sgio.c + cd $(DIR_APP) && sed -i -e "s/-O2/$(CFLAGS)/g" Makefile + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) binprefix=/usr +endef diff --git a/pkgs/core/hostapd/config b/pkgs/core/hostapd/config new file mode 100644 index 0000000..783f325 --- /dev/null +++ b/pkgs/core/hostapd/config @@ -0,0 +1,145 @@ +# Example hostapd build time configuration +# +# This file lists the configuration options that are used when building the +# hostapd binary. All lines starting with # are ignored. Configuration option +# lines must be commented out complete, if they are not to be included, i.e., +# just setting VARIABLE=n is not disabling that variable. +# +# This file is included in Makefile, so variables like CFLAGS and LIBS can also +# be modified from here. In most cass, these lines should use += in order not +# to override previous values of the variables. + +# Driver interface for Host AP driver +CONFIG_DRIVER_HOSTAP=y + +# Driver interface for wired authenticator +#CONFIG_DRIVER_WIRED=y + +# Driver interface for madwifi driver +#CONFIG_DRIVER_MADWIFI=y +#CFLAGS += -I../../madwifi # change to the madwifi source directory + +# Driver interface for Prism54 driver +CONFIG_DRIVER_PRISM54=y + +# Driver interface for drivers using the nl80211 kernel interface +CONFIG_DRIVER_NL80211=y +# driver_nl80211.c requires a rather new libnl (version 1.1) which may not be +# shipped with your distribution yet. If that is the case, you need to build +# newer libnl version and point the hostapd build to use it. +LIBNL=/usr/src/libnl +CFLAGS += -I$(LIBNL)/include +LIBS += -L$(LIBNL)/lib + +# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) +#CONFIG_DRIVER_BSD=y +#CFLAGS += -I/usr/local/include +#LIBS += -L/usr/local/lib + +# Driver interface for no driver (e.g., RADIUS server only) +#CONFIG_DRIVER_NONE=y + +# IEEE 802.11F/IAPP +CONFIG_IAPP=y + +# WPA2/IEEE 802.11i RSN pre-authentication +CONFIG_RSN_PREAUTH=y + +# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS) +CONFIG_PEERKEY=y + +# IEEE 802.11w (management frame protection) +# This version is an experimental implementation based on IEEE 802.11w/D1.0 +# draft and is subject to change since the standard has not yet been finalized. +# Driver support is also needed for IEEE 802.11w. +#CONFIG_IEEE80211W=y + +# Integrated EAP server +CONFIG_EAP=y + +# EAP-MD5 for the integrated EAP server +CONFIG_EAP_MD5=y + +# EAP-TLS for the integrated EAP server +CONFIG_EAP_TLS=y + +# EAP-MSCHAPv2 for the integrated EAP server +CONFIG_EAP_MSCHAPV2=y + +# EAP-PEAP for the integrated EAP server +CONFIG_EAP_PEAP=y + +# EAP-GTC for the integrated EAP server +CONFIG_EAP_GTC=y + +# EAP-TTLS for the integrated EAP server +CONFIG_EAP_TTLS=y + +# EAP-SIM for the integrated EAP server +#CONFIG_EAP_SIM=y + +# EAP-AKA for the integrated EAP server +#CONFIG_EAP_AKA=y + +# EAP-AKA' for the integrated EAP server +# This requires CONFIG_EAP_AKA to be enabled, too. +#CONFIG_EAP_AKA_PRIME=y + +# EAP-PAX for the integrated EAP server +#CONFIG_EAP_PAX=y + +# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) +#CONFIG_EAP_PSK=y + +# EAP-SAKE for the integrated EAP server +#CONFIG_EAP_SAKE=y + +# EAP-GPSK for the integrated EAP server +#CONFIG_EAP_GPSK=y +# Include support for optional SHA256 cipher suite in EAP-GPSK +#CONFIG_EAP_GPSK_SHA256=y + +# EAP-FAST for the integrated EAP server +# Note: Default OpenSSL package does not include support for all the +# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL, +# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch) +# to add the needed functions. +#CONFIG_EAP_FAST=y + +# Wi-Fi Protected Setup (WPS) +CONFIG_WPS=y +# Enable UPnP support for external WPS Registrars +CONFIG_WPS_UPNP=y + +# EAP-IKEv2 +CONFIG_EAP_IKEV2=y + +# Trusted Network Connect (EAP-TNC) +CONFIG_EAP_TNC=y + +# PKCS#12 (PFX) support (used to read private key and certificate file from +# a file that usually has extension .p12 or .pfx) +CONFIG_PKCS12=y + +# RADIUS authentication server. This provides access to the integrated EAP +# server from external hosts using RADIUS. +CONFIG_RADIUS_SERVER=y + +# Build IPv6 support for RADIUS operations +CONFIG_IPV6=y + +# IEEE Std 802.11r-2008 (Fast BSS Transition) +CONFIG_IEEE80211R=y + +# Use the hostapd's IEEE 802.11 authentication (ACL), but without +# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211) +#CONFIG_DRIVER_RADIUS_ACL=y + +# IEEE 802.11n (High Throughput) support +CONFIG_IEEE80211N=y + +# Remove debugging code that is printing out debug messages to stdout. +# This can be used to reduce the size of the hostapd considerably if debugging +# code is not needed. +CONFIG_NO_STDOUT_DEBUG=n + diff --git a/pkgs/core/hostapd/hostapd.nm b/pkgs/core/hostapd/hostapd.nm new file mode 100644 index 0000000..1a66641 --- /dev/null +++ b/pkgs/core/hostapd/hostapd.nm @@ -0,0 +1,60 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = hostapd +PKG_VER = 0.6.9 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://hostap.epitest.fi/hostapd/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = User space daemon to create Wifi Access points. + +PKG_DEPS += libnl openssl + +define PKG_DESCRIPTION + Hostapd is a user space daemon for access point and authentication \ + servers. It implements IEEE 802.11 access point management, IEEE \ + 802.1X/WPA/WPA2/EAP Authenticators, RADIUS client, EAP server, and \ + RADIUS authentication server. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_PREPARE_CMDS + cd $(DIR_APP)/hostapd && cp -vf $(DIR_SOURCE)/config .config + cd $(DIR_APP)/hostapd && sed -e "s@/usr/local@$(BUILDROOT)/usr@g" -i Makefile +endef + +define STAGE_BUILD + cd $(DIR_APP)/hostapd && make $(PARALLELISMFLAGS) CC=gcc +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/usr/bin + cd $(DIR_APP)/hostapd && make install +endef diff --git a/pkgs/core/hplip/hplip.nm b/pkgs/core/hplip/hplip.nm new file mode 100644 index 0000000..2372e3b --- /dev/null +++ b/pkgs/core/hplip/hplip.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = hplip +PKG_VER = 3.10.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Printing +PKG_URL = http://hplipopensource.com/hplip-web/index.html +PKG_LICENSE = GPLv2* +PKG_SUMMARY = HP Printer/Scanner Library (full version). + +PKG_BUILD_DEPS+= autoconf automake libtool +PKG_DEPS += cups dbus libjpeg libusb-compat net-snmp python sane + +define PKG_DESCRIPTION + HPLIP (Hewlett-Packard Linux Imaging & Printing) is an HP-developed \ + olution for printing, scanning, and faxing with HP inkjet and laser based \ + printers in Linux. The HPLIP project provides printing support for 1,924 \ + printer models. \ + This is the full version including printer/scanner support. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc diff --git a/pkgs/core/htop/htop.nm b/pkgs/core/htop/htop.nm new file mode 100644 index 0000000..72fd130 --- /dev/null +++ b/pkgs/core/htop/htop.nm @@ -0,0 +1,48 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = htop +PKG_VER = 0.8.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/System +PKG_URL = http://htop.sourceforge.net/ +PKG_LICENSE = GPL+ +PKG_SUMMARY = Interactive process viewer. + +PKG_DEPS += ncurses + +define PKG_DESCRIPTION + htop is an interactive text-mode process viewer for Linux, similar to \ + top(1). +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_INSTALL_CMDS + rm -rf $(BUILDROOT)/usr/share/{applications,pixmaps} +endef diff --git a/pkgs/core/iana-etc/iana-etc.nm b/pkgs/core/iana-etc/iana-etc.nm new file mode 100644 index 0000000..77eea99 --- /dev/null +++ b/pkgs/core/iana-etc/iana-etc.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = iana-etc +PKG_VER = 2.30 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://www.iana.org/ +PKG_LICENSE = +PKG_SUMMARY = The Internet Assigned Numbers Authority. + +define PKG_DESCRIPTION + The Internet Assigned Numbers Authority (IANA) is responsible for the \ + global coordination of the DNS Root, IP addressing, and other Internet \ + protocol resources. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef diff --git a/pkgs/core/initscripts/functions b/pkgs/core/initscripts/functions new file mode 100644 index 0000000..c5451ff --- /dev/null +++ b/pkgs/core/initscripts/functions @@ -0,0 +1,284 @@ +#!/bin/sh +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### +# +# Partly based on scripts by DJ Lucas - dj@linuxfromscratch.org +# + +# Distro Information +DISTRO="$(</etc/system-release)" # The distro name +DISTRO_CONTACT="http://bugtracker.ipfire.org" # Bug report address + +# This sets default terminal options. +# stty sane - this has been removed as nobody recalls +# the reason for it in the first place - if no problems arize, +# then it will be removed completely at a later date. + +# Setup default values for the environment +umask 022 + +# If we boot, we should only allow the +# use tools that are available in /bin:/sbin +if [ -n "${UPSTART_JOB}" ]; then + PATH="/bin:/sbin" +fi + +# Find current screen size +if [ -z "${COLUMNS}" ]; then + COLUMNS=$(stty size) + COLUMNS=${COLUMNS##* } +fi + +# When using remote connections, such as a serial port, stty size returns 0 +if [ "${COLUMNS}" = "0" ]; then + COLUMNS=80 +fi + +## Measurements for positioning result messages +COL=$((${COLUMNS} - 8)) +WCOL=$((${COL} - 2)) + +# Set Cursur Position Commands, used via echo -e +SET_COL="\033[${COL}G" # at the $COL char +SET_WCOL="\033[${WCOL}G" # at the $WCOL char +CURS_UP="\033[1A\033[0G" # Up one line, at the 0'th char + +# Normal colors +CLR_NORM_BLK="\033[0;30m" # black +CLR_NORM_RED="\033[0;31m" # red +CLR_NORM_GRN="\033[0;32m" # green +CLR_NORM_YEL="\033[0;33m" # yellow +CLR_NORM_BLU="\033[0;34m" # blue +CLR_NORM_MAG="\033[0;35m" # magenta +CLR_NORM_CYN="\033[0;36m" # cyan +CLR_NORM_WHT="\033[0;37m" # white +CLR_NORM_GRY="\033[0;39m" # grey + +# Emphased colors +CLR_BOLD_BLK="\033[1;30m" # black +CLR_BOLD_RED="\033[1;31m" # red +CLR_BOLD_GRN="\033[1;32m" # green +CLR_BOLD_YEL="\033[1;33m" # yellow +CLR_BOLD_BLU="\033[1;34m" # blue +CLR_BOLD_MAG="\033[1;35m" # magenta +CLR_BOLD_CYN="\033[1;36m" # cyan +CLR_BOLD_WHT="\033[1;37m" # white +CLR_BOLD_GRY="\033[1;39m" # grey + +# Background colors +CLR_BACK_BLK="\033[40m" # black +CLR_BACK_RED="\033[41m" # red +CLR_BACK_GRN="\033[42m" # green +CLR_BACK_YEL="\033[43m" # yellow +CLR_BACK_BLU="\033[44m" # blue +CLR_BACK_MAG="\033[45m" # magenta +CLR_BACK_CYN="\033[46m" # cyan +CLR_BACK_WHT="\033[47m" # white + +# Action colors +BOLD=$CLR_BOLD_GRY +DONE=$CLR_BOLD_GRN +SKIP=$CLR_BOLD_BLU +WARN=$CLR_BOLD_MAG +FAIL=$CLR_BOLD_RED +NORMAL=$CLR_NORM_GRY + +# Color hooks +BRACKET_L="${CLR_BOLD_BLU}[${NORMAL}" +BRACKET_R="${CLR_BOLD_BLU}]${NORMAL}" + +# Define custom colors used in messages printed to the screen +BRACKET=${CLR_BOLD_BLU} # Blue +FAILURE=${CLR_BOLD_RED} # Red +INFO=${CLR_BOLD_CYN} # Cyan +NORMAL=${CLR_NORM_GRY} # Grey +SUCCESS=${CLR_BOLD_GRN} # Green +WARNING=${CLR_BOLD_YEL} # Yellow + +# Prefix boot messages for easier reading on framebuffer consoles +PREFIX_SUCCESS=" ${SUCCESS}*${NORMAL} " +PREFIX_WARNING="${WARNING}**${NORMAL} " +PREFIX_FAILURE="${FAILURE}***${NORMAL}" + +welcome_message="Welcome to ${INFO}${DISTRO}${NORMAL}" +welcome_message_length=$((${#DISTRO} + 11)) + +# Error message displayed when a script's exit value is not zero +print_error_msg() { + # ${link} and ${error_value} are defined by the rc script + echo -e "${FAILURE}FAILURE: You should not be reading this error message." + echo -e "" + echo -e -n "${FAILURE}It means that an unforseen error took place in" + echo -e -n "${INFO} ${link}" + echo -e "${FAILURE}," + echo -e "${FAILURE}which exited with a return value of ${error_value}." + echo -e "" + echo -e -n "${FAILURE}If you are able to track this error down to a bug" + echo -e "${FAILURE}in one of the files" + echo -e -n "provided by ${INFO}${DISTRO}${FAILURE}, " + echo -e -n "${FAILURE}please be so kind to inform us at " + echo -e "${INFO}${DISTRO_CONTACT}${FAILURE}.${NORMAL}" + echo -e "" + echo -e "${INFO}Press Enter to continue..." + echo -e "${NORMAL}" + read ENTER +} + +################################################################################ +# log_success_msg() # +# Usage: log_success_msg [$MESSAGE | "message"] # +# # +# Purpose: Print a successful status message to the screen and optionally # +# a boot log file. # +# # +# Inputs: accepts one string value, either a quoted string or optionally # +# the value of $MESSAGE if set in the running environment. # +# # +# Return values: Not used # +################################################################################ +log_success_msg() { + echo -n -e "${PREFIX_SUCCESS}${INDENT}${@}" + echo -e "${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]${NORMAL}" +} + +################################################################################ +# log_failure_msg() # +# Usage: log_failure_msg [$MESSAGE | "message"] # +# # +# Purpose: Print a failure status message to the screen and optionally # +# a boot log file. # +# # +# Inputs: accepts one string value, either a quoted string or optionally # +# the value of $MESSAGE if set in the running environment. # +# # +# Return values: Not used # +################################################################################ +log_failure_msg() { + echo -n -e "${PREFIX_FAILURE}${INDENT}${@}" + echo -e "${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]${NORMAL}" +} + +################################################################################ +# log_warning_msg() # +# Usage: log_warning_msg [$MESSAGE | "message"] # +# # +# Purpose: Print a warning status message to the screen and optionally # +# a boot log file. # +# # +# Inputs: accepts one string value, either a quoted string or optionally # +# the value of $MESSAGE if set in the running environment. # +# # +# Return values: Not used # +################################################################################ +log_warning_msg() { + echo -n -e "${PREFIX_WARNING}${INDENT}${@}" + echo -e "${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]${NORMAL}" +} + +############################## evaluate_retval() ############################### +# evaluate_retval requires that you pass exactly one evaluation parameter of # +# (start, stop, other) based on the previous action that is being evaluated. # +# This function is intended for use with start_daemon and killproc to # +# interpret the LSB exit codes properly, othewise the checks only for success # +# or failure. # +################################################################################ +evaluate_retval() { + local error_value="${?}" + + # Handle LSB defined return values + case "${1}" in + start) + case "${error_value}" in + 0) + log_success_msg "Starting ${MESSAGE} " + return "${error_value}" + ;; + 2) + log_failure_msg "Starting ${MESSAGE} Error: Invalid argument!" + return "${error_value}" + ;; + 5) + log_failure_msg "Starting ${MESSAGE} Error: Not available!" + return "${error_value}" + ;; + *) + log_failure_msg "Starting ${MESSAGE} Error: General failure!" + return "${error_value}" + ;; + esac + ;; + + stop) + case "${error_value}" in + 0) + log_success_msg "Stopping ${MESSAGE} " + return "${error_value}" + ;; + 2) + log_failure_msg "Stopping ${MESSAGE} Error: Invalid argument!" + return "${error_value}" + ;; + 5) + log_failure_msg "Stopping ${MESSAGE} Error: Not available!" + return "${error_value}" + ;; + 7) + log_warning_msg "Stopping ${MESSAGE} Warning: Not running!" + return "${error_value}" + ;; + *) + log_failure_msg "Stopping ${MESSAGE} Error: General failure!" + return "${error_value}" + ;; + esac + ;; + + force-reload) + message="Forcefully reloading " + ;; + + reload) + message="Reloading " + ;; + + restart) + message="Restarting " + ;; + + try-restart) + message="Trying restart " + ;; + + standard) + # $message or $MESSAGE must be set, but not both in order + # to use the 'standard' target. + ;; + esac + + # Print messages for the generic force-reload, reload, restart, + # and try-restart targets + if [ "${error_value}" = "0" ]; then + log_success_msg "${message}${MESSAGE} " + return "${error_value}" + else + log_failure_msg "${message}${MESSAGE} " + return "${error_value}" + fi +} diff --git a/pkgs/core/initscripts/init/checkfs.conf b/pkgs/core/initscripts/init/checkfs.conf new file mode 100644 index 0000000..f1de5d4 --- /dev/null +++ b/pkgs/core/initscripts/init/checkfs.conf @@ -0,0 +1,77 @@ +description "Check / filesystem" +author "IPFire Team" + +start on stopped udevtrigger + +console output + +script + # If requested, do not check the filesystems + [ -f /fastboot ] && exit 0 + + set -e + . /etc/init/functions + + mount -n -o remount,ro / >/dev/null + if [ ${?} != 0 ]; then + log_failure_msg "Mounting root file system in read-only mode" + echo -e "${FAILURE}FAILURE:\n" + echo -e -n "${FAILURE}Cannot check root filesystem because it " + echo -e "${FAILURE}could not be mounted" + echo -e "${FAILURE}in read-only mode.\n\n" + echo -e -n "${FAILURE}After you press Enter, this system will be " + echo -e "${FAILURE}halted and powered off.\n" + echo -e "${INFO}Press enter to continue...${NORMAL}" + read ENTER + ## XXX need to shutdown the system cleanly here + fi + + # Force check if /forcefsck is found + if [ -f /forcefsck ]; then + options="-f" + else + options="" + fi + + # Note: -a option used to be -p; but this fails e.g. + # on fsck.minix + fsck ${options} -a -A -C -T + error_value=${?} + + if [ "${error_value}" = 1 ]; then + log_warning_msg "Checking file systems..." + echo -e "${WARNING}WARNING:\n" + echo -e "${WARNING}File system errors were found and have been" + echo -e "${WARNING}corrected. You may want to double-check that" + echo -e "${WARNING}everything was fixed properly.${NORMAL}" + elif [ "${error_value}" = 2 -o "${error_value}" = 3 ]; then + log_warning_msg "Checking file systems..." + echo -e "${WARNING}WARNING:\n" + echo -e "${WARNING}File system errors were found and have been been" + echo -e "${WARNING}corrected, but the nature of the errors require" + echo -e "${WARNING}this system to be rebooted.\n" + echo -e "After you press enter, this system will be rebooted.\n" + echo -e "${INFO}Press Enter to continue...${NORMAL}" + read ENTER + ## XXX need to reboot the system here + elif [ "${error_value}" -gt 3 -a "${error_value}" -lt 16 ]; then + log_failure_msg "Checking file systems..." + echo -e "${FAILURE}FAILURE:\n" + echo -e "${FAILURE}File system errors were encountered that could" + echo -e "${FAILURE}not be fixed automatically. This system cannot" + echo -e "${FAILURE}continue to boot and will therefore be halted" + echo -e "${FAILURE}until those errors are fixed manually by a" + echo -e "${FAILURE}System Administrator.\n" + echo -e "${FAILURE}After you press Enter, this system will be" + echo -e "${FAILURE}halted and powered off.\n" + echo -e "${INFO}Press Enter to continue...${NORMAL}" + read ENTER + ## XXX need to shutdown the system here + elif [ "${error_value}" -ge 16 ]; then + log_failure_msg "Checking file systems..." + echo -e "${FAILURE}FAILURE:\n" + echo -e "${FAILURE}Unexpected Failure running fsck. Exited with error" + echo -e "${FAILURE}code: ${error_value}.${NORMAL}" + exit ${error_value} + fi +end script diff --git a/pkgs/core/initscripts/init/cleanfs.conf b/pkgs/core/initscripts/init/cleanfs.conf new file mode 100644 index 0000000..43a70d8 --- /dev/null +++ b/pkgs/core/initscripts/init/cleanfs.conf @@ -0,0 +1,8 @@ +description "Cleaning / filesystem" +author "IPFire Team" + +start on stopping mountfs + +pre-start script + rm -rf /tmp/* /var/{lock,run}/* +end script diff --git a/pkgs/core/initscripts/init/control-alt-delete.conf b/pkgs/core/initscripts/init/control-alt-delete.conf new file mode 100644 index 0000000..3181894 --- /dev/null +++ b/pkgs/core/initscripts/init/control-alt-delete.conf @@ -0,0 +1,6 @@ +description "Control-Alt-Delete / Handling" +author "IPFire Team" + +start on control-alt-delete + +exec initctl emit --no-wait reboot diff --git a/pkgs/core/initscripts/init/load-modules.conf b/pkgs/core/initscripts/init/load-modules.conf new file mode 100644 index 0000000..b64658c --- /dev/null +++ b/pkgs/core/initscripts/init/load-modules.conf @@ -0,0 +1,49 @@ +description "Trigger coldplug events" +author "IPFire Team" + +start on stopped mount-kernel-filesystems + +script + # Exit if there's no modules file or there are no + # valid entries + [ -r /etc/sysconfig/modules ] && + egrep -qv '^($|#)' /etc/sysconfig/modules || + exit 0 + + # If proc is mounted, find the current kernel + # message level + if [ -f /proc/sys/kernel/printk ]; then + prev_msg=`cat /proc/sys/kernel/printk | \ + sed 'l 1' | sed -n '2~0p' | \ + sed 's/\//'` + else + prev_msg="6" + fi + + # Now set the message level to 1 so not to make too + # much noise when loading modules + dmesg -n 1 + + # Only try to load modules if the user has actually given us + # some modules to load. + if egrep -qv '^(#|$)' /etc/sysconfig/modules 2>/dev/null; then + # Read in the configuration file. + exec 9>&0 < /etc/sysconfig/modules + + while read module args; do + # Ignore comments and blank lines. + case "${module}" in + ""|#*) continue ;; + esac + + # Attempt to load the module, making + # sure to pass any arguments provided. + modprobe ${module} ${args} > /dev/null + done + + exec 0>&9 9>&- + + fi + # Set the kernel message level back to it's previous value. + dmesg -n "${prev_msg}" +end script diff --git a/pkgs/core/initscripts/init/loopback.conf b/pkgs/core/initscripts/init/loopback.conf new file mode 100644 index 0000000..fc5d64a --- /dev/null +++ b/pkgs/core/initscripts/init/loopback.conf @@ -0,0 +1,16 @@ +description "Bringing up the local network" +author "IPFire Team" + +start on started udev + +script + [ -e "/etc/sysconfig/network" ] && \ + . /etc/sysconfig/network + + ip addr add 127.0.0.1/8 label lo dev lo + ip link set lo up + + if [ -n "${HOSTNAME}" ]; then + hostname "${HOSTNAME}" + fi +end script diff --git a/pkgs/core/initscripts/init/mount-kernel-filesystems.conf b/pkgs/core/initscripts/init/mount-kernel-filesystems.conf new file mode 100644 index 0000000..cef79e5 --- /dev/null +++ b/pkgs/core/initscripts/init/mount-kernel-filesystems.conf @@ -0,0 +1,16 @@ +description "Mount kernel virtual systems" +author "IPFire Team" + +start on stopped welcome + +script + if ! mountpoint /proc > /dev/null; then + mount -n /proc || failed=1 + fi + + if ! mountpoint /sys > /dev/null; then + mount -n /sys || failed=1 + fi + + exit ${failed} +end script diff --git a/pkgs/core/initscripts/init/mountfs.conf b/pkgs/core/initscripts/init/mountfs.conf new file mode 100644 index 0000000..c432c5c --- /dev/null +++ b/pkgs/core/initscripts/init/mountfs.conf @@ -0,0 +1,22 @@ +description "Mount / filesystem" +author "IPFire Team" + +start on stopped checkfs + +console output + +script + mount -n -o remount,rw / >/dev/null + + # Remove fsck-related file system watermarks. + rm -f /fastboot /forcefsck + + > /etc/mtab + mount -f / + mount -f /proc + mount -f /sys + + # This will mount all filesystems that do not have _netdev in + # their option list. _netdev denotes a network filesystem. + mount -a -O no_netdev >/dev/null +end script diff --git a/pkgs/core/initscripts/init/serial.conf b/pkgs/core/initscripts/init/serial.conf new file mode 100644 index 0000000..44b76fd --- /dev/null +++ b/pkgs/core/initscripts/init/serial.conf @@ -0,0 +1,24 @@ +description "Start a tty" +author "IPFire Team" + +# Automatically start a configured serial console +# +# How this works: +# +# On boot, a udev helper examines /dev/console. If a serial console is the +# primary console (last console on the commandline in grub), the event +# 'serial-console-available <port name> <speed>' is emitted, which +# triggers this script. +# +# If your serial console is not the primary console, or you want a getty +# on serial even if it's not the console, create your own event by copying +# /etc/init/tty[2-6], and changing the getty line in that file. + +start on serial-console-available * +stop on starting shutdown or starting reboot + +pre-start script + /sbin/securetty $DEV +end script + +exec /sbin/agetty $DEV $SPEED vt100-nav diff --git a/pkgs/core/initscripts/init/shutdown.conf b/pkgs/core/initscripts/init/shutdown.conf new file mode 100644 index 0000000..36805c1 --- /dev/null +++ b/pkgs/core/initscripts/init/shutdown.conf @@ -0,0 +1,24 @@ +description "Shutdown or reboot the system" +author "IPFire Team" + +start on shutdown or reboot + +console output + +script + # Exterminate any lil' process that managed to evade my merciless + # terminating. + killall5 -15 || true + sleep 5 + killall5 -9 || true + + mount -n -o remount,ro / || true + + # The UPSTART_EVENTS variable contains the event that has been called. + # The script use it to perform the requested action. + if [ "${UPSTART_EVENTS}" = "reboot" ]; then + reboot -pf + else + halt -pf + fi +end script diff --git a/pkgs/core/initscripts/init/swap.conf b/pkgs/core/initscripts/init/swap.conf new file mode 100644 index 0000000..8cbf129 --- /dev/null +++ b/pkgs/core/initscripts/init/swap.conf @@ -0,0 +1,6 @@ +description "Activating swap partitions" +author "IPFire Team" + +start on stopped checkfs + +exec /sbin/swapon -a diff --git a/pkgs/core/initscripts/init/sysctl.conf b/pkgs/core/initscripts/init/sysctl.conf new file mode 100644 index 0000000..2289a9a --- /dev/null +++ b/pkgs/core/initscripts/init/sysctl.conf @@ -0,0 +1,14 @@ +description "Set sysctl settings" +author "IPFire Team" + +start on stopped mount-kernel-filesystems + +script + if [ -f "/etc/sysctl.conf" ]; then + sysctl -q -p + fi + if [ -d "/proc/sys/kernel/grsecurity" -a \ + -f "/etc/grsec/sysctl.conf" ]; then + sysctl -q -p /etc/grsec/sysctl.conf + fi +end script diff --git a/pkgs/core/initscripts/init/tty1.conf b/pkgs/core/initscripts/init/tty1.conf new file mode 100644 index 0000000..04d0c91 --- /dev/null +++ b/pkgs/core/initscripts/init/tty1.conf @@ -0,0 +1,8 @@ +description "Start a tty" +author "IPFire Team" + +start on stopped mountfs +stop on starting shutdown + +respawn +exec /sbin/agetty 9600 tty1 diff --git a/pkgs/core/initscripts/init/tty2.conf b/pkgs/core/initscripts/init/tty2.conf new file mode 100644 index 0000000..af5458a --- /dev/null +++ b/pkgs/core/initscripts/init/tty2.conf @@ -0,0 +1,8 @@ +description "Start a tty" +author "IPFire Team" + +start on stopped mountfs +stop on starting shutdown + +respawn +exec /sbin/agetty 9600 tty2 diff --git a/pkgs/core/initscripts/init/tty3.conf b/pkgs/core/initscripts/init/tty3.conf new file mode 100644 index 0000000..2903dd1 --- /dev/null +++ b/pkgs/core/initscripts/init/tty3.conf @@ -0,0 +1,8 @@ +description "Start a tty" +author "IPFire Team" + +start on stopped mountfs +stop on starting shutdown + +respawn +exec /sbin/agetty 9600 tty3 diff --git a/pkgs/core/initscripts/init/tty4.conf b/pkgs/core/initscripts/init/tty4.conf new file mode 100644 index 0000000..0480207 --- /dev/null +++ b/pkgs/core/initscripts/init/tty4.conf @@ -0,0 +1,8 @@ +description "Start a tty" +author "IPFire Team" + +start on stopped mountfs +stop on starting shutdown + +respawn +exec /sbin/agetty 9600 tty4 diff --git a/pkgs/core/initscripts/init/udev.conf b/pkgs/core/initscripts/init/udev.conf new file mode 100644 index 0000000..15da729 --- /dev/null +++ b/pkgs/core/initscripts/init/udev.conf @@ -0,0 +1,28 @@ +description "Start Udev Daemon" +author "IPFire Team" + +start on stopped mount-kernel-filesystems +stop on starting shutdown + +emits block-device-added block-device-removed +emits network-device-added network-device-removed + +console output + +pre-start script + # Mount a temporary file system over /dev, so that any devices + # made or removed during this boot don't affect the next one. + # The reason we don't write to mtab is because we don't ever + # want /dev to be unavailable (such as by `umount -a'). + mount -n -t tmpfs tmpfs /dev -o mode=755 + + # Udev handles uevents itself, so we don't need to have + # the kernel call out to any binary in response to them + echo > /proc/sys/kernel/hotplug + + # Copy static device nodes to /dev + cp -a /lib/udev/devices/* /dev +end script + +exec /sbin/udevd +respawn diff --git a/pkgs/core/initscripts/init/udevtrigger.conf b/pkgs/core/initscripts/init/udevtrigger.conf new file mode 100644 index 0000000..754ccd7 --- /dev/null +++ b/pkgs/core/initscripts/init/udevtrigger.conf @@ -0,0 +1,15 @@ +description "Trigger udev events" +author "IPFire Team" + +start on started udev + +console output + +script + # Now traverse /sys in order to "coldplug" devices that have + # already been discovered + udevadm trigger + + # Now wait for udevd to process the uevents we triggered + udevadm settle --timeout=5 || true +end script diff --git a/pkgs/core/initscripts/init/welcome.conf b/pkgs/core/initscripts/init/welcome.conf new file mode 100644 index 0000000..37ca7eb --- /dev/null +++ b/pkgs/core/initscripts/init/welcome.conf @@ -0,0 +1,24 @@ +description "Display a welcome message to the user" +author "IPFire Team" + +start on startup + +console output + +script + . /etc/init/functions + + # dcol are spaces before the message to center the + # message on screen. + dcol=$(( $(( ${COLUMNS} - ${welcome_message_length} )) / 2 )) + echo -e "\033[${dcol}G${welcome_message}" + + system_message=$(uname -r) + system_message_length=${#system_message} + system_message="Running on Linux ${FAILURE}${system_message}${NORMAL}" + system_message_length=$((17 + ${system_message_length})) + dcol=$(( $(( ${COLUMNS} - ${system_message_length} )) / 2 )) + echo -e "\033[${dcol}G${system_message}" + + echo "" +end script diff --git a/pkgs/core/initscripts/initscripts.nm b/pkgs/core/initscripts/initscripts.nm new file mode 100644 index 0000000..00d449f --- /dev/null +++ b/pkgs/core/initscripts/initscripts.nm @@ -0,0 +1,68 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = initscripts +PKG_VER = $(DISTRO_VERSION) +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Boot +PKG_URL = +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = The set of scripts that initalize the system. + +PKG_DEPS += coreutils e2fsprogs module-init-tools procps sysvinit \ + system-release upstart util-linux-ng + +define PKG_DESCRIPTION + The initscripts package contains the basic system scripts used to boot \ + your system and shut the system down cleanly. +endef + +DIR_APP = $(DIR_SOURCE) + +define STAGE_PREPARE_CMDS + cd $(DIR_APP)/src && make clean +endef + +define STAGE_BUILD + cd $(DIR_APP)/src && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP)/src && make install clean DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/etc/{init,sysconfig} + + cp -vf $(DIR_SOURCE)/functions $(BUILDROOT)/etc/init/ + + for i in $(DIR_SOURCE)/sysconfig/*; do \ + install -v -m 644 $$i $(BUILDROOT)/etc/sysconfig/; \ + done + chmod -v 755 $(BUILDROOT)/etc/sysconfig/rc.local + + cp -vf $(DIR_SOURCE)/sysctl.conf $(BUILDROOT)/etc +endef diff --git a/pkgs/core/initscripts/src/Makefile b/pkgs/core/initscripts/src/Makefile new file mode 100644 index 0000000..452f45f --- /dev/null +++ b/pkgs/core/initscripts/src/Makefile @@ -0,0 +1,21 @@ + +PROGS = console_check securetty + +CFLAGS += -D_GNU_SOURCE + +all: $(PROGS) + +clean: + rm -vf $(PROGS) *.o + +install: + -mkdir -pv $(DESTDIR)/lib/udev $(DESTDIR)/sbin + install -v -m 755 console_check $(DESTDIR)/lib/udev/ + install -v -m 755 securetty $(DESTDIR)/sbin + + +console_check: console_check.o + $(CC) $(LDFLAGS) -o $@ $< + +securetty: securetty.o + $(CC) $(LDFLAGS) -o $@ $< diff --git a/pkgs/core/initscripts/src/console_check.c b/pkgs/core/initscripts/src/console_check.c new file mode 100644 index 0000000..740f2a8 --- /dev/null +++ b/pkgs/core/initscripts/src/console_check.c @@ -0,0 +1,180 @@ + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> + +#include <sys/ioctl.h> + +#include <linux/serial.h> +#include <linux/serial_core.h> + +struct speeds +{ + speed_t speed; + unsigned long value; +}; + +struct speeds speed_map[] = +{ + {B50, 50}, + {B75, 75}, + {B110, 110}, + {B134, 134}, + {B150, 150}, + {B200, 200}, + {B300, 300}, + {B600, 600}, + {B1200, 1200}, + {B1800, 1800}, + {B2400, 2400}, + {B4800, 4800}, + {B9600, 9600}, + {B19200, 19200}, + {B38400, 38400}, +#ifdef B57600 + {B57600, 57600}, +#endif +#ifdef B115200 + {B115200, 115200}, +#endif +#ifdef B230400 + {B230400, 230400}, +#endif +#ifdef B460800 + {B460800, 460800}, +#endif + {0, 0} +}; + +int termcmp(struct termios *a, struct termios *b) { + if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag || + a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag || + cfgetispeed(a) != cfgetispeed(b) || cfgetospeed(a) != cfgetospeed(b)) + return 1; + return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc)); +} + +int get_serial_speed(int fd) { + struct termios mode; + + if (!tcgetattr(fd, &mode)) { + int i; + speed_t speed; + + speed = cfgetospeed(&mode); + for (i = 0; speed_map[i].value != 0; i++) + if (speed_map[i].speed == speed) + return speed_map[i].value; + } + return 0; +} + +int compare_termios_to_console(char *dev, int *speed) { + struct termios cmode, mode; + int fd, cfd; + + cfd = open ("/dev/console", O_RDONLY); + tcgetattr(cfd, &cmode); + close(cfd); + + fd = open(dev, O_RDONLY|O_NONBLOCK); + tcgetattr(fd, &mode); + + if (!termcmp(&cmode, &mode)) { + *speed = get_serial_speed(fd); + close(fd); + return 1; + } + close(fd); + return 0; +} + +char *serial_tty_name(int type) { + switch (type) { + case PORT_8250...PORT_MAX_8250: + return "ttyS"; + case PORT_PMAC_ZILOG: + return "ttyPZ"; + case PORT_MPSC: + return "ttyMM"; + case PORT_CPM: + return "ttyCPM"; + case PORT_MPC52xx: + return "ttyPSC"; + default: + return NULL; + } +} + +char *check_serial_console(int *speed) { + int fd; + char *ret = NULL, *device; + char twelve = 12; + struct serial_struct si, si2; + char *tty_name; + + memset(&si, 0, sizeof(si)); + memset(&si2, 0, sizeof(si)); + + fd = open("/dev/console", O_RDWR); + if (ioctl (fd, TIOCLINUX, &twelve) >= 0) + goto out; + + if (ioctl(fd, TIOCGSERIAL, &si) < 0) + goto out; + close(fd); + + tty_name = serial_tty_name(si.type); + if (!tty_name) + goto out; + + asprintf(&device, "%s%d", tty_name, si.line); + fd = open(device, O_RDWR|O_NONBLOCK); + if (fd == -1) + goto out; + + if (ioctl(fd, TIOCGSERIAL, &si2) < 0) + goto out; + + if (memcmp(&si,&si2, sizeof(si))) + goto out; + + *speed = get_serial_speed(fd); + ret = device; +out: + close(fd); + return ret; +} + +int emit_console_event(char *dev, int speed) { + char *args[] = { "initctl", "emit", "--no-wait", "serial-console-available", NULL, NULL, NULL }; + + asprintf(&args[4],"DEV=%s", dev); + if (speed) + asprintf(&args[5],"SPEED=%d", speed); + execv("/sbin/initctl", args); + return 1; +} + +int main(int argc, char **argv) { + char *device; + int speed; + + if (argc < 2) { + printf("usage: console_check <device>\n"); + exit(1); + } + chdir("/dev"); + device = argv[1]; + if (!strcmp(device, "console")) { + device = check_serial_console(&speed); + if (device) + return emit_console_event(device, speed); + } else if (compare_termios_to_console(device, &speed)) { + return emit_console_event(device, speed); + } + return 0; +} diff --git a/pkgs/core/initscripts/src/securetty.c b/pkgs/core/initscripts/src/securetty.c new file mode 100644 index 0000000..9bdc8c2 --- /dev/null +++ b/pkgs/core/initscripts/src/securetty.c @@ -0,0 +1,94 @@ + +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> + +void alarm_handler(int num) { + return; +} + +int open_and_lock_securetty() { + int fd; + struct flock lock; + struct sigaction act, oldact; + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + + fd = open("/etc/securetty", O_RDWR); + if (fd == -1) { + syslog(LOG_ERR, "Couldn't open /etc/securetty: %s",strerror(errno)); + return -1; + } + act.sa_handler = alarm_handler; + act.sa_flags = 0; + sigaction(SIGALRM, &act, &oldact); + alarm(2); + while (fcntl(fd, F_SETLKW, &lock) == -1) { + if (errno == EINTR) { + syslog(LOG_ERR, "Couldn't lock /etc/securetty: Timeout exceeded"); + } else { + syslog(LOG_ERR, "Couldn't lock /etc/securetty: %s",strerror(errno)); + } + return -1; + } + alarm(0); + sigaction(SIGALRM, &oldact, NULL); + return fd; +} + +int rewrite_securetty(char *terminal) { + int fd; + char *buf, *pos; + struct stat sbuf; + + fd = open_and_lock_securetty(); + if (fd == -1) + return 1; + if (fstat(fd, &sbuf) == -1) { + close(fd); + syslog(LOG_ERR, "Couldn't stat /etc/securetty: %s",strerror(errno)); + return 1; + } + buf = malloc(sbuf.st_size + 1); + if (read(fd, buf, sbuf.st_size) != sbuf.st_size) { + close(fd); + syslog(LOG_ERR, "Couldn't read /etc/securetty: %s",strerror(errno)); + return 1; + } + if (!strncmp(buf,terminal,strlen(terminal)) && buf[strlen(terminal)] == '\n') + goto out_ok; + if ((pos = strstr(buf, terminal))) { + if (pos[strlen(terminal)] == '\n' && *(pos-1) == '\n') + goto out_ok; + } + if (lseek(fd, 0, SEEK_END) == -1) { + close(fd); + syslog(LOG_ERR, "Couldn't seek to end of /etc/securetty: %s",strerror(errno)); + return 1; + } + write(fd, terminal, strlen(terminal)); + write(fd, "\n", 1); +out_ok: + close(fd); + return 0; +} + +int main(int argc, char **argv) { + if (argc < 2 ) { + fprintf(stderr, "Usage: securetty <device>\n"); + exit(1); + } + openlog("securetty", LOG_CONS, LOG_DAEMON); + return rewrite_securetty(argv[1]); +} diff --git a/pkgs/core/initscripts/sysconfig/clock b/pkgs/core/initscripts/sysconfig/clock new file mode 100644 index 0000000..99132e1 --- /dev/null +++ b/pkgs/core/initscripts/sysconfig/clock @@ -0,0 +1 @@ +UTC=no diff --git a/pkgs/core/initscripts/sysconfig/createfiles b/pkgs/core/initscripts/sysconfig/createfiles new file mode 100644 index 0000000..8d1f89d --- /dev/null +++ b/pkgs/core/initscripts/sysconfig/createfiles @@ -0,0 +1,28 @@ +######################################################################## +# Begin /etc/sysconfig/createfiles +# +# Description : Createfiles script config file +# +# Authors : +# +# Version : 00.00 +# +# Notes : The syntax of this file is as follows: +# if type is equal to "file" or "dir" +# <filename> <type> <permissions> <user> <group> +# if type is equal to "dev" +# <filename> <type> <permissions> <user> <group> <devtype> <major> <minor> +# +# <filename> is the name of the file which is to be created +# <type> is either file, dir, or dev. +# file creates a new file +# dir creates a new directory +# dev creates a new device +# <devtype> is either block, char or pipe +# block creates a block device +# char creates a character deivce +# pipe creates a pipe, this will ignore the <major> and <minor> fields +# <major> and <minor> are the major and minor numbers used for the device. +######################################################################## + +# End /etc/sysconfig/createfiles diff --git a/pkgs/core/initscripts/sysconfig/modules b/pkgs/core/initscripts/sysconfig/modules new file mode 100644 index 0000000..d6fc14c --- /dev/null +++ b/pkgs/core/initscripts/sysconfig/modules @@ -0,0 +1,21 @@ +######################################################################## +# Begin /etc/sysconfig/modules +# +# Description : Module auto-loading configuration +# +# Authors : +# +# Version : 00.00 +# +# Notes : The syntax of this file is as follows: +# <module> [<arg1> <arg2> ...] +# +# Each module should be on it's own line, and any options that you want +# passed to the module should follow it. The line deliminator is either +# a space or a tab. +######################################################################## + +# For dialin with pppd +ppp_generic + +# End /etc/sysconfig/modules diff --git a/pkgs/core/initscripts/sysconfig/network b/pkgs/core/initscripts/sysconfig/network new file mode 100644 index 0000000..45e537e --- /dev/null +++ b/pkgs/core/initscripts/sysconfig/network @@ -0,0 +1 @@ +HOSTNAME=ipfire.localdomain diff --git a/pkgs/core/initscripts/sysconfig/rc b/pkgs/core/initscripts/sysconfig/rc new file mode 100644 index 0000000..ffb70d9 --- /dev/null +++ b/pkgs/core/initscripts/sysconfig/rc @@ -0,0 +1,52 @@ +# Begin /etc/sysconfig/rc + +# Author: DJ Lucas - dj@linuxfromscratch.org +# Version: 1.0 LSB V.3.1 + +# Global variable inherited by initscripts are in caps +# Local variables for the rc script are in lowercase + +# Source site specific rc configuration +. /etc/sysconfig/rc.site + +# This sets default terminal options. +# stty sane - this has been removed as nobody recalls +# the reason for it in the first place - if no problems arize, +# then it will be removed completely at a later date. + +# Setup default values for the environment +umask 022 +PATH="/bin:/sbin" + +# Find current screen size +if [ -z "${COLUMNS}" ]; then + COLUMNS=$(stty size) + COLUMNS=${COLUMNS##* } +fi + +# When using remote connections, such as a serial port, stty size returns 0 +if [ "${COLUMNS}" = "0" ]; then + COLUMNS=80 +fi + +## Measurements for positioning result messages +COL=$((${COLUMNS} - 8)) +WCOL=$((${COL} - 2)) + +# Set Cursur Position Commands, used via echo -e +SET_COL="\033[${COL}G" # at the $COL char +SET_WCOL="\033[${WCOL}G" # at the $WCOL char +CURS_UP="\033[1A\033[0G" # Up one line, at the 0'th char + +# Bootlogging and interactive startup require a valid tempfs mount +# if this mount is not present, disable them +if [ "${TEMPFS_MOUNT}" = "" -o ! -d "${TEMPFS_MOUNT}" ]; then + TEMPFS_MOUNT="" + iprompt="" + BOOTLOG_ENAB="" +fi + +# Export the environment variables so they are inherited by the scripts +export PATH SET_COL SET_WCOL CURS_UP TEMPFS_MOUNT BOOTLOG_ENAB RUNLEVEL + +# End /etc/sysconfig/rc diff --git a/pkgs/core/initscripts/sysconfig/rc.local b/pkgs/core/initscripts/sysconfig/rc.local new file mode 100644 index 0000000..90347d7 --- /dev/null +++ b/pkgs/core/initscripts/sysconfig/rc.local @@ -0,0 +1,27 @@ +#!/bin/sh +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### +# Used for private calls after boot # +############################################################################### + +# power button shutdown +if grep -q '^button' /proc/modules ; then + head -1 /proc/acpi/event | grep -q 'button/power PWRF' && init 0 & +fi diff --git a/pkgs/core/initscripts/sysconfig/rc.site b/pkgs/core/initscripts/sysconfig/rc.site new file mode 100644 index 0000000..82b7cc7 --- /dev/null +++ b/pkgs/core/initscripts/sysconfig/rc.site @@ -0,0 +1,71 @@ +# Set base directory information +RC_BASE="/etc" +RC_FUNCTIONS="${RC_BASE}/init.d/ipfire-functions" + +# Location of network device scripts and config files +NETWORK_SCRIPTS="/etc/init.d/networking" +NETWORK_DEVICES="/etc/sysconfig/network-devices" + +# Directory to store boot process accounting information +# Used for boot logging and interactive flag when rootfs +# is not writable +TEMPFS_MOUNT="${RC_BASE}/init.d/boottemp" + +# Bootlogging (requires a tempfs mount) +BOOTLOG_ENAB="yes" + +# Distro Information +DISTRO="$(cat /etc/system-release)" # The distro name +DISTRO_CONTACT="http://bugtracker.ipfire.org" # Bug report address +DISTRO_MINI="ipfire" # Short name used in filenames for distro config + +# Define custom colors used in messages printed to the screen +BRACKET="\033[1;34m" # Blue +FAILURE="\033[1;31m" # Red +INFO="\033[1;36m" # Cyan +NORMAL="\033[0;39m" # Grey +SUCCESS="\033[1;32m" # Green +WARNING="\033[1;33m" # Yellow + +# Prefix boot messages for easier reading on framebuffer consoles +PREFIX_SUCCESS=" ${SUCCESS}*${NORMAL} " +PREFIX_WARNING="${WARNING}**${NORMAL} " +PREFIX_FAILURE="${FAILURE}***${NORMAL}" + +# Export varialbles so that they are inherited by the initscripts +export RC_BASE RC_FUNCTIONS TEMPFS_MOUNT BOOTLOG_ENAB +export NETWORK_DEVICES NETWORK_SCRIPTS +export DISTRO DISTRO_CONTACT DISTRO_MINI +export BRACKET FAILURE INFO NORMAL SUCCESS WARNING +export PREFIX_SUCCESS PREFIX_WARNING PREFIX_FAILURE + +# Interactive startup +iprompt="yes" # Wether to display the interactive boot promp +itime="2" # The ammount of time (in seconds) to display the prompt +dlen="$(( 11 + ${#DISTRO} ))" # The total length of the distro welcome string +ilen="38" # The total length of the interactive message +welcome_message="Welcome to ${INFO}${DISTRO}${NORMAL}" +i_message="Press '${FAILURE}I${NORMAL}' to enter interactive startup" + +# Error message displayed when a script's exit value is not zero +print_error_msg() +{ + # ${link} and ${error_value} are defined by the rc script + echo -e "${FAILURE}FAILURE: You should not be reading this error message." + echo -e "" + echo -e -n "${FAILURE}It means that an unforseen error took place in" + echo -e -n "${INFO} ${link}" + echo -e "${FAILURE}," + echo -e "${FAILURE}which exited with a return value of ${error_value}." + echo -e "" + echo -e -n "${FAILURE}If you are able to track this error down to a bug" + echo -e "${FAILURE}in one of the files" + echo -e -n "provided by ${INFO}${DISTRO}${FAILURE}, " + echo -e -n "${FAILURE}please be so kind to inform us at " + echo -e "${INFO}${DISTRO_CONTACT}${FAILURE}.${NORMAL}" + echo -e "" + echo -e "${INFO}Press Enter to continue..." + echo -e "${NORMAL}" + read ENTER +} + diff --git a/pkgs/core/initscripts/sysctl.conf b/pkgs/core/initscripts/sysctl.conf new file mode 100644 index 0000000..bcf90e8 --- /dev/null +++ b/pkgs/core/initscripts/sysctl.conf @@ -0,0 +1,24 @@ +net.ipv4.ip_forward = 1 +net.ipv4.ip_dynaddr = 1 +net.ipv4.icmp_echo_ignore_broadcasts = 1 +net.ipv4.icmp_ignore_bogus_error_responses = 1 + +net.ipv4.tcp_sack = 0 +net.ipv4.tcp_timestamps = 0 +net.ipv4.tcp_syncookies = 1 +net.ipv4.tcp_fin_timeout = 30 +net.ipv4.tcp_window_scaling = 0 +net.ipv4.tcp_syn_retries = 3 +net.ipv4.tcp_synack_retries = 3 + +net.ipv4.conf.default.rp_filter = 0 +net.ipv4.conf.default.accept_redirects = 0 +net.ipv4.conf.default.accept_source_route = 0 +net.ipv4.conf.default.log_martians = 1 + +net.ipv4.conf.all.rp_filter = 0 +net.ipv4.conf.all.accept_redirects = 0 +net.ipv4.conf.all.accept_source_route = 0 +net.ipv4.conf.all.log_martians = 1 + +kernel.printk = 1 4 1 7 diff --git a/pkgs/core/intltool/intltool.nm b/pkgs/core/intltool/intltool.nm new file mode 100644 index 0000000..d3bf691 --- /dev/null +++ b/pkgs/core/intltool/intltool.nm @@ -0,0 +1,48 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = intltool +PKG_VER = 0.40.5 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Localization/Tools +PKG_URL = http://www.gnome.org/ +PKG_LICENSE = GPLv2 with exceptions +PKG_SUMMARY = Utility for internationalizing various kinds of data files. + +define PKG_DESCRIPTION + This tool automatically extracts translatable strings from oaf, glade, \ + bonobo ui, nautilus theme, .desktop, and other data files and puts \ + them in the po files. +endef + +PKG_DEPS += expat gettext perl-xml-parser + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --mandir=/usr/share/man diff --git a/pkgs/core/iproute2/iproute2.nm b/pkgs/core/iproute2/iproute2.nm new file mode 100644 index 0000000..94c29a0 --- /dev/null +++ b/pkgs/core/iproute2/iproute2.nm @@ -0,0 +1,65 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = iproute2 +PKG_VER = 2.6.29-1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://www.linuxfoundation.org/en/Net:Iproute2 +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Advanced IP routing and network device configuration tools. + +PKG_BUILD_DEPS+= bison flex +PKG_DEPS += db + +define PKG_DESCRIPTION + The iproute package contains networking utilities (ip and rtmon, for \ + example) which are designed to use the advanced networking \ + capabilities of the Linux 2.4.x and 2.6.x kernel. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -i -e "s@DESTDIR=.*@DESTDIR=@" \ + -e "s@/share/@/usr/share/@g" Makefile +endef + +define STAGE_BUILD + cd $(DIR_APP) && make OPT_FLAGS="$(CFLAGS)" #$(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + -mkdir -pv $(BUILDROOT)/usr/sbin + cd $(DIR_APP) && mv -v $(BUILDROOT)/sbin/arpd $(BUILDROOT)/usr/sbin +endef diff --git a/pkgs/core/iproute2/patches/iproute2-2.6.29-1-opt_flags.patch b/pkgs/core/iproute2/patches/iproute2-2.6.29-1-opt_flags.patch new file mode 100644 index 0000000..aea7362 --- /dev/null +++ b/pkgs/core/iproute2/patches/iproute2-2.6.29-1-opt_flags.patch @@ -0,0 +1,12 @@ +diff -up iproute2-2.6.29/Makefile.opt iproute2-2.6.29/Makefile +--- iproute2-2.6.29/Makefile.opt 2008-08-12 14:19:58.000000000 +0200 ++++ iproute2-2.6.29/Makefile 2008-08-12 14:21:42.000000000 +0200 +@@ -22,7 +22,7 @@ ADDLIB+=ipx_ntop.o ipx_pton.o + + CC = gcc + HOSTCC = gcc +-CCOPTS = -D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall ++CCOPTS = -D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall $(OPT_FLAGS) + CFLAGS = $(CCOPTS) -I../include $(DEFINES) + YACCFLAGS = -d -t -v + diff --git a/pkgs/core/iptables/iptables.nm b/pkgs/core/iptables/iptables.nm new file mode 100644 index 0000000..c82c579 --- /dev/null +++ b/pkgs/core/iptables/iptables.nm @@ -0,0 +1,87 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = iptables +PKG_VER = 1.4.5 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://www.netfilter.org/ +PKG_LICENSE = GPL+ +PKG_SUMMARY = Tools for managing Linux kernel packet filtering capabilities. + +#PKG_DEPS += m4 + +define PKG_DESCRIPTION + The iptables utility controls the network packet filtering code in the \ + Linux kernel. If you need to set up firewalls and/or IP masquerading, \ + you should install this package. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CFLAGS += -fno-strict-aliasing + +CONFIGURE_OPTIONS += \ + --bindir=/bin \ + --sbindir=/sbin \ + --libdir=/lib \ + --libexecdir=/lib \ + --sysconfdir=/etc \ + --with-pkgconfigdir=/usr/lib/pkgconfig \ + --mandir=/usr/share/man \ + --with-kernel=/usr \ + --with-kbuild=/usr \ + --with-ksource=/usr \ + --enable-devel \ + --enable-libipq + +define STAGE_PREPARE_CMDS + # Make more space for target name on output. + cd $(DIR_APP) && sed -e "s/%-9s/%-18s/g" -i ip{,6}tables.c +endef + +define STAGE_INSTALL_CMDS + # install ip*tables.h header files + -mkdir -pv $(BUILDROOT)/usr/include/{iptables,libiptc} + cd $(DIR_APP) && install -v -m 644 include/ip{,6}tables.h \ + $(BUILDROOT)/usr/include + cd $(DIR_APP) && install -v -m 644 include/iptables/internal.h \ + $(BUILDROOT)/usr/include/iptables/ + cd $(DIR_APP) && install -v -m 644 include/libiptc/*.h \ + $(BUILDROOT)/usr/include/libiptc + + -mkdir -pv $(BUILDROOT)/usr/lib + rm -vf $(BUILDROOT)/lib/libip{,4,6}tc.so $(BUILDROOT)/lib/libxtables.so + ln -svf ../../lib/libiptc.so.0 $(BUILDROOT)/usr/lib/libiptc.so + ln -svf ../../lib/libip4tc.so.0 $(BUILDROOT)/usr/lib/libip4tc.so + ln -svf ../../lib/libip6tc.so.0 $(BUILDROOT)/usr/lib/libip6tc.so + ln -svf ../../lib/libxtables.so.2 $(BUILDROOT)/usr/lib/libxtables.so + + # Replace absolute symlink + ln -svf ../sbin/iptables-multi $(BUILDROOT)/bin/iptables-xml +endef diff --git a/pkgs/core/iputils/iputils.nm b/pkgs/core/iputils/iputils.nm new file mode 100644 index 0000000..a65e78a --- /dev/null +++ b/pkgs/core/iputils/iputils.nm @@ -0,0 +1,88 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = iputils +PKG_VER = s20071127 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://www.skbuff.net/iputils +PKG_LICENSE = BSD +PKG_SUMMARY = Network monitoring tools including ping. + +PKG_BUILD_DEPS+= libcap +PKG_DEPS += libidn + +define PKG_DESCRIPTION + The iputils package contains basic utilities for monitoring a network, \ + including ping. The ping command sends a series of ICMP protocol \ + ECHO_REQUEST packets to a specified network host to discover whether \ + the target machine is alive and receiving network traffic. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +PKG_PATCHES = $(THISAPP)-addrcache.patch +PKG_PATCHES += $(THISAPP)-arping-infiniband.patch +PKG_PATCHES += $(THISAPP)-arping_timeout.patch +PKG_PATCHES += $(THISAPP)-countermeasures.patch +PKG_PATCHES += $(THISAPP)-idn.patch +PKG_PATCHES += $(THISAPP)-open-max.patch +PKG_PATCHES += $(THISAPP)-ping-subint.patch +PKG_PATCHES += $(THISAPP)-ping_cleanup.patch +PKG_PATCHES += $(THISAPP)-rh.patch +PKG_PATCHES += $(THISAPP)-traffic_class.patch +PKG_PATCHES += $(THISAPP)-warnings.patch +PKG_PATCHES += $(THISAPP)-output.patch + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/{bin,sbin} $(BUILDROOT)/usr/sbin + + cd $(DIR_APP) && install -cp clockdiff $(BUILDROOT)/usr/sbin/ + cd $(DIR_APP) && install -cp arping $(BUILDROOT)/sbin/ + cd $(DIR_APP) && install -cp ping $(BUILDROOT)/bin/ + cd $(DIR_APP) && install -cp ping6 $(BUILDROOT)/bin/ + cd $(DIR_APP) && install -cp rdisc $(BUILDROOT)/sbin/ + cd $(DIR_APP) && install -cp tracepath $(BUILDROOT)/bin/ + cd $(DIR_APP) && install -cp tracepath6 $(BUILDROOT)/bin/ + + ln -svf ../../sbin/arping $(BUILDROOT)/usr/sbin/arping + ln -svf ../../bin/ping6 $(BUILDROOT)/usr/sbin/ + ln -svf ../../bin/tracepath $(BUILDROOT)/usr/sbin/ + ln -svf ../../bin/tracepath6 $(BUILDROOT)/usr/sbin/ + + setcap cap_net_admin=ep $(BUILDROOT)/bin/ping + setcap cap_net_admin=ep $(BUILDROOT)/bin/ping6 +endef diff --git a/pkgs/core/iputils/patches/iputils-s20071127-addrcache.patch b/pkgs/core/iputils/patches/iputils-s20071127-addrcache.patch new file mode 100644 index 0000000..188dbca --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-addrcache.patch @@ -0,0 +1,31 @@ +--- iputils/ping.c.addrcache 2002-09-20 17:08:11.000000000 +0200 ++++ iputils/ping.c 2003-05-15 16:41:19.000000000 +0200 +@@ -1124,6 +1124,12 @@ + { + struct hostent *hp; + static char buf[4096]; ++ static __u32 addr_cache = 0; ++ ++ if ( addr == addr_cache ) ++ return buf; ++ ++ addr_cache = addr; + + if ((options & F_NUMERIC) || + !(hp = gethostbyaddr((char *)&addr, 4, AF_INET))) +--- iputils/ping6.c.addrcache 2002-09-20 17:08:11.000000000 +0200 ++++ iputils/ping6.c 2003-05-15 16:41:19.000000000 +0200 +@@ -893,7 +893,12 @@ + */ + char * pr_addr(struct in6_addr *addr) + { +- struct hostent *hp = NULL; ++ static struct hostent *hp; ++ static struct in6_addr addr_cache; ++ ++ if (memcmp(addr, &addr_cache, sizeof(addr_cache)) == 0) ++ return hp ? hp->h_name : pr_addr_n(addr); ++ memcpy(&addr_cache, addr, sizeof(addr_cache)); + + if (!(options&F_NUMERIC)) + hp = gethostbyaddr((__u8*)addr, sizeof(struct in6_addr), AF_INET6); diff --git a/pkgs/core/iputils/patches/iputils-s20071127-arping-infiniband.patch b/pkgs/core/iputils/patches/iputils-s20071127-arping-infiniband.patch new file mode 100644 index 0000000..9884b70 --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-arping-infiniband.patch @@ -0,0 +1,244 @@ +diff -up iputils-s20071127/arping.c.infiniband iputils-s20071127/arping.c +--- iputils-s20071127/arping.c.infiniband 2007-11-27 01:57:27.000000000 +0100 ++++ iputils-s20071127/arping.c 2008-08-08 10:05:04.000000000 +0200 +@@ -50,14 +50,26 @@ int unicasting; + int s; + int broadcast_only; + +-struct sockaddr_ll me; +-struct sockaddr_ll he; ++/* ++ * Make these two structs have padding at the end so the overly long Infiniband ++ * hardware addresses can have the remainder of their address tacked onto ++ * the end of the struct without overlapping anything. ++ */ ++struct sockaddr_ll me[2]; ++struct sockaddr_ll he[2]; + + struct timeval start, last; + + int sent, brd_sent; + int received, brd_recv, req_recv; + ++#define SYSFS_MNT_PATH "/sys" ++#define SYSFS_CLASS "class" ++#define SYSFS_NET "net" ++#define SYSFS_BROADCAST "broadcast" ++#define SYSFS_PATH_ENV "SYSFS_PATH" ++#define SYSFS_PATH_LEN 256 ++ + #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \ + ((tv1).tv_usec-(tv2).tv_usec)/1000 ) + +@@ -124,7 +136,8 @@ int send_pack(int s, struct in_addr src, + p+=4; + + gettimeofday(&now, NULL); +- err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, sizeof(*HE)); ++ err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, (ah->ar_hln > 8) ? ++ sizeof(*HE) + ah->ar_hln - 8 : sizeof(*HE)); + if (err == p-buf) { + last = now; + sent++; +@@ -172,7 +185,7 @@ void catcher(void) + finish(); + + if (last.tv_sec==0 || MS_TDIFF(tv,last) > 500) { +- send_pack(s, src, dst, &me, &he); ++ send_pack(s, src, dst, &me[0], &he[0]); + if (count == 0 && unsolicited) + finish(); + } +@@ -219,7 +232,7 @@ int recv_pack(unsigned char *buf, int le + return 0; + if (ah->ar_pln != 4) + return 0; +- if (ah->ar_hln != me.sll_halen) ++ if (ah->ar_hln != me[0].sll_halen) + return 0; + if (len < sizeof(*ah) + 2*(4 + ah->ar_hln)) + return 0; +@@ -230,7 +243,7 @@ int recv_pack(unsigned char *buf, int le + return 0; + if (src.s_addr != dst_ip.s_addr) + return 0; +- if (memcmp(p+ah->ar_hln+4, &me.sll_addr, ah->ar_hln)) ++ if (memcmp(p+ah->ar_hln+4, &me[0].sll_addr, ah->ar_hln)) + return 0; + } else { + /* DAD packet was: +@@ -248,7 +261,7 @@ int recv_pack(unsigned char *buf, int le + */ + if (src_ip.s_addr != dst.s_addr) + return 0; +- if (memcmp(p, &me.sll_addr, me.sll_halen) == 0) ++ if (memcmp(p, &me[0].sll_addr, me[0].sll_halen) == 0) + return 0; + if (src.s_addr && src.s_addr != dst_ip.s_addr) + return 0; +@@ -264,7 +277,7 @@ int recv_pack(unsigned char *buf, int le + printf("for %s ", inet_ntoa(dst_ip)); + s_printed = 1; + } +- if (memcmp(p+ah->ar_hln+4, me.sll_addr, ah->ar_hln)) { ++ if (memcmp(p+ah->ar_hln+4, me[0].sll_addr, ah->ar_hln)) { + if (!s_printed) + printf("for "); + printf("["); +@@ -290,12 +303,69 @@ int recv_pack(unsigned char *buf, int le + if (quit_on_reply) + finish(); + if(!broadcast_only) { +- memcpy(he.sll_addr, p, me.sll_halen); ++ memcpy(he[0].sll_addr, p, me[0].sll_halen); + unicasting=1; + } + return 1; + } + ++int get_sysfs_mnt_path(char *mnt_path, size_t len) ++{ ++ const char *sysfs_path_env; ++ int pth_len=0; ++ ++ if (len == 0 || mnt_path == NULL) ++ return -1; ++ ++ /* possible overrride of real mount path */ ++ sysfs_path_env = getenv(SYSFS_PATH_ENV); ++ memset(mnt_path, 0, len); ++ strncpy(mnt_path, ++ sysfs_path_env != NULL ? sysfs_path_env : SYSFS_MNT_PATH, ++ len-1); ++ ++ if ((pth_len = strlen(mnt_path)) > 0 && mnt_path[pth_len-1] == '/') ++ mnt_path[pth_len-1] = '\0'; ++ ++ return 0; ++} ++ ++int make_sysfs_broadcast_path(char *broadcast_path, size_t len) ++{ ++ char mnt_path[SYSFS_PATH_LEN]; ++ ++ if (get_sysfs_mnt_path(mnt_path, len) != 0) ++ return -1; ++ ++ snprintf(broadcast_path, len, ++ "%s/" SYSFS_CLASS "/" SYSFS_NET "/%s/" SYSFS_BROADCAST, ++ mnt_path, device); ++ ++ return 0; ++} ++ ++char * read_sysfs_broadcast(char *brdcast_path) ++{ ++ int fd; ++ int len_to_read; ++ char *brdcast = NULL; ++ ++ if ((fd = open(brdcast_path, O_RDONLY)) > -1) { ++ len_to_read = lseek(fd, 0L, SEEK_END); ++ if ((brdcast = malloc(len_to_read+1)) != NULL) { ++ lseek(fd, 0L, SEEK_SET); ++ memset(brdcast, 0, len_to_read+1); ++ if (read(fd, brdcast, len_to_read) == -1) { ++ free(brdcast); ++ brdcast = NULL; ++ } ++ } ++ close(fd); ++ } ++ ++ return brdcast; ++} ++ + int + main(int argc, char **argv) + { +@@ -459,9 +529,9 @@ main(int argc, char **argv) + close(probe_fd); + }; + +- me.sll_family = AF_PACKET; +- me.sll_ifindex = ifindex; +- me.sll_protocol = htons(ETH_P_ARP); ++ me[0].sll_family = AF_PACKET; ++ me[0].sll_ifindex = ifindex; ++ me[0].sll_protocol = htons(ETH_P_ARP); + if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { + perror("bind"); + exit(2); +@@ -474,14 +544,33 @@ main(int argc, char **argv) + exit(2); + } + } +- if (me.sll_halen == 0) { ++ if (me[0].sll_halen == 0) { + if (!quiet) + printf("Interface "%s" is not ARPable (no ll address)\n", device); + exit(dad?0:2); + } ++ he[0] = me[0]; ++ he[1] = me[1]; ++ { ++ char brdcast_path[SYSFS_PATH_LEN]; ++ char *brdcast_val; ++ char *next_ch; ++ ++ if (make_sysfs_broadcast_path(brdcast_path, sizeof brdcast_path) != 0) { ++ perror("sysfs attribute broadcast"); ++ exit(2); ++ } ++ ++ if ((brdcast_val = read_sysfs_broadcast(brdcast_path)) == NULL) { ++ perror("sysfs read broadcast value"); ++ exit(2); ++ } ++ for (ch=0; ch<he[0].sll_halen; ch++) { ++ he[0].sll_addr[ch] = strtol(brdcast_val + (ch*3), &next_ch, 16); ++ } + +- he = me; +- memset(he.sll_addr, -1, he.sll_halen); ++ free(brdcast_val); ++ } + + if (!quiet) { + printf("ARPING %s ", inet_ntoa(dst)); +@@ -501,12 +590,12 @@ main(int argc, char **argv) + while(1) { + sigset_t sset, osset; + unsigned char packet[4096]; +- struct sockaddr_ll from; ++ struct sockaddr_ll from[2]; + socklen_t alen = sizeof(from); + int cc; + + if ((cc = recvfrom(s, packet, sizeof(packet), 0, +- (struct sockaddr *)&from, &alen)) < 0) { ++ (struct sockaddr *)&from[0], &alen)) < 0) { + perror("arping: recvfrom"); + continue; + } +@@ -514,7 +603,7 @@ main(int argc, char **argv) + sigaddset(&sset, SIGALRM); + sigaddset(&sset, SIGINT); + sigprocmask(SIG_BLOCK, &sset, &osset); +- recv_pack(packet, cc, &from); ++ recv_pack(packet, cc, &from[0]); + sigprocmask(SIG_SETMASK, &osset, NULL); + } + } +diff -up iputils-s20071127/Makefile.infiniband iputils-s20071127/Makefile +--- iputils-s20071127/Makefile.infiniband 2008-08-08 09:17:35.000000000 +0200 ++++ iputils-s20071127/Makefile 2008-08-08 10:02:10.000000000 +0200 +@@ -37,6 +37,8 @@ rdisc_srv: rdisc_srv.o + rdisc_srv.o: rdisc.c + $(CC) $(CFLAGS) -DRDISC_SERVER -o rdisc_srv.o rdisc.c + ++arping: arping.o ++ $(CC) $(LDFLAGS) arping.o $(LOADLIBES) $(LDLIBS) -o arping + + check-kernel: + ifeq ($(KERNEL_INCLUDE),) diff --git a/pkgs/core/iputils/patches/iputils-s20071127-arping_timeout.patch b/pkgs/core/iputils/patches/iputils-s20071127-arping_timeout.patch new file mode 100644 index 0000000..656ec0b --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-arping_timeout.patch @@ -0,0 +1,65 @@ +diff -up iputils-s20070202/arping.c.arping_timeout iputils-s20070202/arping.c +--- iputils-s20070202/arping.c.arping_timeout 2008-02-18 16:51:36.000000000 +0100 ++++ iputils-s20070202/arping.c 2008-02-18 16:54:03.000000000 +0100 +@@ -45,7 +45,8 @@ struct in_addr src, dst; + char *target; + int dad, unsolicited, advert; + int quiet; +-int count=-1; ++int count; ++int forever = 1; + int timeout; + int unicasting; + int s; +@@ -59,7 +60,7 @@ int broadcast_only; + struct sockaddr_ll me[2]; + struct sockaddr_ll he[2]; + +-struct timeval start, last; ++struct timeval last; + + int sent, brd_sent; + int received, brd_recv, req_recv; +@@ -172,13 +173,15 @@ void catcher(void) + + gettimeofday(&tv, NULL); + +- if (start.tv_sec==0) +- start = tv; +- +- if (count-- == 0 || (timeout && MS_TDIFF(tv,start) > timeout*1000 + 500)) +- finish(); ++ if (!forever && count == 0) { ++ if (timeout && MS_TDIFF(tv, last) > timeout * 1000 + 500) ++ finish(); ++ else if (!timeout) ++ finish(); ++ } + +- if (last.tv_sec==0 || MS_TDIFF(tv,last) > 500) { ++ if ((count > 0 || forever) && (last.tv_sec == 0 || MS_TDIFF(tv, last) > 500)) { ++ count--; + send_pack(s, src, dst, &me[0], &he[0]); + if (count == 0 && unsolicited) + finish(); +@@ -339,6 +342,10 @@ main(int argc, char **argv) + break; + case 'c': + count = atoi(optarg); ++ if (count > 0) ++ forever = 0; ++ else ++ forever = 1; + break; + case 'w': + timeout = atoi(optarg); +@@ -544,7 +551,8 @@ main(int argc, char **argv) + sigaddset(&sset, SIGALRM); + sigaddset(&sset, SIGINT); + sigprocmask(SIG_BLOCK, &sset, &osset); +- recv_pack(packet, cc, &from[0]); ++ if (recv_pack(packet, cc, from) && count == 0 && !forever) ++ finish(); + sigprocmask(SIG_SETMASK, &osset, NULL); + } + } diff --git a/pkgs/core/iputils/patches/iputils-s20071127-countermeasures.patch b/pkgs/core/iputils/patches/iputils-s20071127-countermeasures.patch new file mode 100644 index 0000000..5e6f4bc --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-countermeasures.patch @@ -0,0 +1,12 @@ +--- iputils/ping_common.c.countermeasures Tue May 21 10:06:05 2002 ++++ iputils/ping_common.c Tue May 21 10:12:42 2002 +@@ -628,7 +628,8 @@ + tvsub(tv, &tmp_tv); + triptime = tv->tv_sec * 1000000 + tv->tv_usec; + if (triptime < 0) { +- fprintf(stderr, "Warning: time of day goes back (%ldus), taking countermeasures.\n", triptime); ++ if (options & F_VERBOSE) ++ fprintf(stderr, "Warning: time of day goes back (%ldus), taking countermeasures.\n", triptime); + triptime = 0; + if (!(options & F_LATENCY)) { + gettimeofday(tv, NULL); diff --git a/pkgs/core/iputils/patches/iputils-s20071127-idn.patch b/pkgs/core/iputils/patches/iputils-s20071127-idn.patch new file mode 100644 index 0000000..b575006 --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-idn.patch @@ -0,0 +1,130 @@ +--- iputils-s20070202/ping.c.idn 2007-08-06 14:45:36.000000000 +0200 ++++ iputils-s20070202/ping.c 2007-08-06 14:45:36.000000000 +0200 +@@ -58,6 +58,9 @@ + * This program has to run SUID to ROOT to access the ICMP socket. + */ + ++#include <idna.h> ++#include <locale.h> ++ + #include "ping_common.h" + + #include <netinet/ip.h> +@@ -122,6 +128,10 @@ + char *target, hnamebuf[MAXHOSTNAMELEN]; + char rspace[3 + 4 * NROUTES + 1]; /* record route space */ + ++ char *idn; ++ int rc = 0; ++ setlocale(LC_ALL, ""); ++ + icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + socket_errno = errno; + +@@ -242,13 +254,27 @@ + if (argc == 1) + options |= F_NUMERIC; + } else { ++ rc = idna_to_ascii_lz (target, &idn, 0); ++ if (rc == IDNA_SUCCESS) ++ hp = gethostbyname (idn); ++ else { ++ fprintf(stderr, "ping: IDN encoding of '%s' failed with error code %d\n", target, rc); ++ exit(2); ++ } ++ free(idn); +- hp = gethostbyname(target); + if (!hp) { + fprintf(stderr, "ping: unknown host %s\n", target); + exit(2); + } + memcpy(&whereto.sin_addr, hp->h_addr, 4); ++ rc = idna_to_unicode_lzlz (hp->h_name, &idn, 0); ++ if (rc == IDNA_SUCCESS) ++ strncpy(hnamebuf, idn, sizeof(hnamebuf) - 1); ++ else { ++ fprintf(stderr, "ping: IDN encoding of '%s' failed with error code %d\n", hp->h_name, rc); ++ exit(2); ++ } ++ free(idn); +- strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1); + hnamebuf[sizeof(hnamebuf) - 1] = 0; + hostname = hnamebuf; + } +--- iputils-s20070202/Makefile.idn 2007-08-06 14:45:36.000000000 +0200 ++++ iputils-s20070202/Makefile 2007-08-06 14:45:36.000000000 +0200 +@@ -27,8 +27,13 @@ + + + tftpd: tftpd.o tftpsubs.o ++ + ping: ping.o ping_common.o ++ $(CC) $(CFLAGS) ping.o ping_common.o -lidn -o ping ++ + ping6: ping6.o ping_common.o ++ $(CC) $(CFLAGS) ping6.o ping_common.o -o ping6 ++ + ping.o ping6.o ping_common.o: ping_common.h + tftpd.o tftpsubs.o: tftp.h + +--- iputils-s20070202/ping6.c.idn 2007-08-06 14:45:36.000000000 +0200 ++++ iputils-s20070202/ping6.c 2007-08-06 14:45:36.000000000 +0200 +@@ -66,6 +66,9 @@ + * More statistics could always be gathered. + * This program has to run SUID to ROOT to access the ICMP socket. + */ ++#define _GNU_SOURCE ++#include <locale.h> ++ + #include "ping_common.h" + + #include <linux/filter.h> +@@ -210,6 +216,8 @@ + int err, csum_offset, sz_opt; + static uint32_t scope_id = 0; + ++ setlocale(LC_ALL, ""); ++ + icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + socket_errno = errno; + +@@ -296,6 +306,7 @@ + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; ++ hints.ai_flags = AI_IDN; + gai = getaddrinfo(target, NULL, &hints, &ai); + if (gai) { + fprintf(stderr, "unknown host\n"); +@@ -328,6 +341,7 @@ + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; ++ hints.ai_flags = AI_IDN; + gai = getaddrinfo(target, NULL, &hints, &ai); + if (gai) { + fprintf(stderr, "unknown host\n"); +--- iputils-s20070202/ping_common.c.idn 2007-08-06 14:45:36.000000000 +0200 ++++ iputils-s20070202/ping_common.c 2007-08-06 14:47:41.000000000 +0200 +@@ -1,3 +1,5 @@ ++#include <locale.h> ++ + #include "ping_common.h" + #include <ctype.h> + #include <sched.h> +@@ -97,6 +102,7 @@ + + void common_options(int ch) + { ++ setlocale(LC_ALL, "C"); + switch(ch) { + case 'a': + options |= F_AUDIBLE; +@@ -222,6 +230,7 @@ + default: + abort(); + } ++ setlocale(LC_ALL, ""); + } + + diff --git a/pkgs/core/iputils/patches/iputils-s20071127-open-max.patch b/pkgs/core/iputils/patches/iputils-s20071127-open-max.patch new file mode 100644 index 0000000..d8ce652 --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-open-max.patch @@ -0,0 +1,30 @@ +diff -up iputils-s20071127/rdisc.c.open_max iputils-s20071127/rdisc.c +--- iputils-s20071127/rdisc.c.open_max 2008-02-25 11:15:37.000000000 +0100 ++++ iputils-s20071127/rdisc.c 2008-02-25 11:17:30.000000000 +0100 +@@ -240,14 +240,25 @@ void do_fork(void) + { + int t; + pid_t pid; ++ long open_max; + + if (trace) + return; ++ if ((open_max = sysconf(_SC_OPEN_MAX)) == -1) { ++ if (errno == 0) { ++ (void) fprintf(stderr, "OPEN_MAX is not supported\n"); ++ } ++ else { ++ (void) fprintf(stderr, "sysconf() error\n"); ++ } ++ exit(1); ++ } ++ + + if ((pid=fork()) != 0) + exit(0); + +- for (t = 0; t < OPEN_MAX; t++) ++ for (t = 0; t < open_max; t++) + if (t != s) + close(t); + diff --git a/pkgs/core/iputils/patches/iputils-s20071127-output.patch b/pkgs/core/iputils/patches/iputils-s20071127-output.patch new file mode 100644 index 0000000..365169b --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-output.patch @@ -0,0 +1,34 @@ +diff -up iputils-s20071127/ping_common.c.output iputils-s20071127/ping_common.c +--- iputils-s20071127/ping_common.c.output 2008-02-26 14:12:02.000000000 +0100 ++++ iputils-s20071127/ping_common.c 2008-02-26 14:24:34.000000000 +0100 +@@ -791,8 +791,10 @@ static long llsqrt(long long a) + */ + void finish(void) + { +- struct timeval tv = cur_time; ++ struct timeval tv; ++ char *comma = ""; + ++ gettimeofday(&tv, NULL); + tvsub(&tv, &start_time); + + putchar('\n'); +@@ -827,12 +829,15 @@ void finish(void) + (long)tmax/1000, (long)tmax%1000, + (long)tmdev/1000, (long)tmdev%1000 + ); ++ comma = ", "; ++ } ++ if (pipesize > 1) { ++ printf("%spipe %d", comma, pipesize); ++ comma = ", "; + } +- if (pipesize > 1) +- printf(", pipe %d", pipesize); + if (ntransmitted > 1 && nreceived && (!interval || (options&(F_FLOOD|F_ADAPTIVE)))) { + int ipg = (1000000*(long long)tv.tv_sec+tv.tv_usec)/(ntransmitted-1); +- printf(", ipg/ewma %d.%03d/%d.%03d ms", ++ printf("%sipg/ewma %d.%03d/%d.%03d ms", comma, + ipg/1000, ipg%1000, rtt/8000, (rtt/8)%1000); + } + putchar('\n'); diff --git a/pkgs/core/iputils/patches/iputils-s20071127-ping-subint.patch b/pkgs/core/iputils/patches/iputils-s20071127-ping-subint.patch new file mode 100644 index 0000000..e19e724 --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-ping-subint.patch @@ -0,0 +1,12 @@ +--- iputils-ss021109-vanilla/ping.c Thu Nov 7 23:53:21 2002 ++++ iputils/ping.c Sun Jan 12 03:39:24 2003 +@@ -285,6 +285,9 @@ + perror("ping: IP_MULTICAST_IF"); + exit(2); + } ++ } else if (icmp_sock >= 0) { ++ /* We possible tried to SO_BINDTODEVICE() a subinterface like 'eth0:1' */ ++ perror("Warning: cannot bind to specified iface, falling back"); + } + } + } diff --git a/pkgs/core/iputils/patches/iputils-s20071127-ping_cleanup.patch b/pkgs/core/iputils/patches/iputils-s20071127-ping_cleanup.patch new file mode 100644 index 0000000..071ab82 --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-ping_cleanup.patch @@ -0,0 +1,50 @@ +--- iputils/ping.c.OLD 2006-02-06 10:34:35.000000000 +0100 ++++ iputils/ping.c 2006-02-06 10:34:35.000000000 +0100 +@@ -855,9 +855,36 @@ + case ICMP_SR_FAILED: + printf("Source Route Failed\n"); + break; ++ case ICMP_NET_UNKNOWN: ++ printf("Destination Net Unknown\n"); ++ break; ++ case ICMP_HOST_UNKNOWN: ++ printf("Destination Host Unknown\n"); ++ break; ++ case ICMP_HOST_ISOLATED: ++ printf("Source Host Isolated\n"); ++ break; ++ case ICMP_NET_ANO: ++ printf("Destination Net Prohibited\n"); ++ break; ++ case ICMP_HOST_ANO: ++ printf("Destination Host Prohibited\n"); ++ break; ++ case ICMP_NET_UNR_TOS: ++ printf("Destination Net Unreachable for Type of Service\n"); ++ break; ++ case ICMP_HOST_UNR_TOS: ++ printf("Destination Host Unreachable for Type of Service\n"); ++ break; + case ICMP_PKT_FILTERED: + printf("Packet filtered\n"); + break; ++ case ICMP_PREC_VIOLATION: ++ printf("Precedence Violation\n"); ++ break; ++ case ICMP_PREC_CUTOFF: ++ printf("Precedence Cutoff\n"); ++ break; + default: + printf("Dest Unreachable, Bad Code: %d\n", code); + break; +--- iputils/ping_common.c.OLD 2006-02-06 10:34:35.000000000 +0100 ++++ iputils/ping_common.c 2006-02-06 10:34:35.000000000 +0100 +@@ -819,7 +819,7 @@ + } + if (pipesize > 1) + printf(", pipe %d", pipesize); +- if (ntransmitted > 1 && (!interval || (options&(F_FLOOD|F_ADAPTIVE)))) { ++ if (ntransmitted > 1 && nreceived && (!interval || (options&(F_FLOOD|F_ADAPTIVE)))) { + int ipg = (1000000*(long long)tv.tv_sec+tv.tv_usec)/(ntransmitted-1); + printf(", ipg/ewma %d.%03d/%d.%03d ms", + ipg/1000, ipg%1000, rtt/8000, (rtt/8)%1000); diff --git a/pkgs/core/iputils/patches/iputils-s20071127-rh.patch b/pkgs/core/iputils/patches/iputils-s20071127-rh.patch new file mode 100644 index 0000000..16d4745 --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-rh.patch @@ -0,0 +1,13 @@ +--- iputils/Makefile.rh7 2002-09-20 20:23:55.000000000 +0200 ++++ iputils/Makefile 2004-05-12 15:08:25.638310270 +0200 +@@ -24,8 +24,8 @@ + CC=gcc + # What a pity, all new gccs are buggy and -Werror does not work. Sigh. + #CCOPT=-D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall -g -Werror +-CCOPT=-D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall -g +-CFLAGS=$(CCOPT) $(GLIBCFIX) $(DEFINES) ++CCOPT?=-D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall -g ++CFLAGS?=$(CCOPT) $(GLIBCFIX) $(DEFINES) + + IPV4_TARGETS=tracepath ping clockdiff rdisc arping tftpd rarpd + IPV6_TARGETS=tracepath6 traceroute6 ping6 diff --git a/pkgs/core/iputils/patches/iputils-s20071127-traffic_class.patch b/pkgs/core/iputils/patches/iputils-s20071127-traffic_class.patch new file mode 100644 index 0000000..8a4ddf0 --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-traffic_class.patch @@ -0,0 +1,14 @@ +diff -up iputils-s20070202/ping6.c.flowlabel iputils-s20070202/ping6.c +--- iputils-s20070202/ping6.c.flowlabel 2008-02-01 11:10:53.000000000 +0100 ++++ iputils-s20070202/ping6.c 2008-02-01 11:16:47.000000000 +0100 +@@ -86,6 +86,10 @@ char copyright[] = + #define SOL_ICMPV6 IPPROTO_ICMPV6 + #endif + ++#ifndef IVP6_FLOWINFO_SEND ++#define IPV6_FLOWINFO_SEND 33 ++#endif ++ + /* RFC3542 */ + #ifndef ICMP6_DST_UNREACH_BEYONDSCOPE + #define ICMP6_DST_UNREACH_BEYONDSCOPE ICMP6_DST_UNREACH_NOTNEIGHBOR diff --git a/pkgs/core/iputils/patches/iputils-s20071127-warnings.patch b/pkgs/core/iputils/patches/iputils-s20071127-warnings.patch new file mode 100644 index 0000000..a2d0a83 --- /dev/null +++ b/pkgs/core/iputils/patches/iputils-s20071127-warnings.patch @@ -0,0 +1,126 @@ +diff -up iputils-s20071127/ping_common.c.warnings iputils-s20071127/ping_common.c +--- iputils-s20071127/ping_common.c.warnings 2008-06-02 13:29:27.000000000 +0200 ++++ iputils-s20071127/ping_common.c 2008-06-02 13:29:27.000000000 +0200 +@@ -338,7 +338,7 @@ resend: + * high preload or pipe size is very confusing. */ + if ((preload < screen_width && pipesize < screen_width) || + in_flight() < screen_width) +- write(STDOUT_FILENO, ".", 1); ++ printf("."); + } + return interval - tokens; + } +@@ -391,7 +391,7 @@ resend: + + if (i == 0 && !(options & F_QUIET)) { + if (options & F_FLOOD) +- write(STDOUT_FILENO, "E", 1); ++ printf("E"); + else + perror("ping: sendmsg"); + } +@@ -717,9 +717,9 @@ restamp: + + if (options & F_FLOOD) { + if (!csfailed) +- write(STDOUT_FILENO, "\b \b", 3); ++ printf("\b \b"); + else +- write(STDOUT_FILENO, "\bC", 1); ++ printf("\bC"); + } else { + int i; + __u8 *cp, *dp; +diff -up iputils-s20071127/clockdiff.c.warnings iputils-s20071127/clockdiff.c +--- iputils-s20071127/clockdiff.c.warnings 2007-11-27 01:57:27.000000000 +0100 ++++ iputils-s20071127/clockdiff.c 2008-06-02 13:29:27.000000000 +0200 +@@ -628,8 +628,6 @@ main(int argc, char *argv[]) + } + } + +- nice(-16); +- + if ((measure_status = (ip_opt_len ? measure_opt : measure)(&server)) < 0) { + if (errno) + perror("measure"); +diff -up iputils-s20071127/ping6.c.warnings iputils-s20071127/ping6.c +--- iputils-s20071127/ping6.c.warnings 2008-06-02 13:30:06.000000000 +0200 ++++ iputils-s20071127/ping6.c 2008-06-02 13:31:14.000000000 +0200 +@@ -667,7 +667,7 @@ int receive_error_msg() + if (options & F_QUIET) + goto out; + if (options & F_FLOOD) +- write(STDOUT_FILENO, "E", 1); ++ printf("E"); + else if (e->ee_errno != EMSGSIZE) + fprintf(stderr, "ping: local error: %s\n", strerror(e->ee_errno)); + else +@@ -690,7 +690,7 @@ int receive_error_msg() + if (options & F_QUIET) + goto out; + if (options & F_FLOOD) { +- write(STDOUT_FILENO, "\bE", 2); ++ printf("\bE"); + } else { + printf("From %s icmp_seq=%u ", pr_addr(&sin6->sin6_addr), ntohs(icmph.icmp6_seq)); + pr_icmph(e->ee_type, e->ee_code, e->ee_info); +@@ -838,7 +838,7 @@ parse_reply(struct msghdr *msg, int cc, + return 0; + nerrors++; + if (options & F_FLOOD) { +- write(STDOUT_FILENO, "\bE", 2); ++ printf("\bE"); + return 0; + } + printf("From %s: icmp_seq=%u ", pr_addr(&from->sin6_addr), ntohs(icmph1->icmp6_seq)); +diff -up iputils-s20071127/ping.c.warnings iputils-s20071127/ping.c +--- iputils-s20071127/ping.c.warnings 2008-06-02 13:29:27.000000000 +0200 ++++ iputils-s20071127/ping.c 2008-06-02 13:29:27.000000000 +0200 +@@ -367,7 +367,7 @@ main(int argc, char **argv) + } + source.sin_port = 0; + close(probe_fd); +- } while (0); ++ } + + if (whereto.sin_addr.s_addr == 0) + whereto.sin_addr.s_addr = source.sin_addr.s_addr; +@@ -594,7 +594,7 @@ int receive_error_msg() + if (options & F_QUIET) + goto out; + if (options & F_FLOOD) +- write(STDOUT_FILENO, "E", 1); ++ printf("E"); + else if (e->ee_errno != EMSGSIZE) + fprintf(stderr, "ping: local error: %s\n", strerror(e->ee_errno)); + else +@@ -630,7 +630,7 @@ int receive_error_msg() + if (options & F_QUIET) + goto out; + if (options & F_FLOOD) { +- write(STDOUT_FILENO, "\bE", 2); ++ printf("\bE"); + } else { + printf("From %s icmp_seq=%u ", pr_addr(sin->sin_addr.s_addr), ntohs(icmph.un.echo.sequence)); + pr_icmph(e->ee_type, e->ee_code, e->ee_info, NULL); +@@ -795,7 +795,7 @@ parse_reply(struct msghdr *msg, int cc, + return !error_pkt; + if (options & F_FLOOD) { + if (error_pkt) +- write(STDOUT_FILENO, "\bE", 2); ++ printf("\bE"); + return !error_pkt; + } + printf("From %s: icmp_seq=%u ", +@@ -812,9 +812,9 @@ parse_reply(struct msghdr *msg, int cc, + } + if ((options & F_FLOOD) && !(options & (F_VERBOSE|F_QUIET))) { + if (!csfailed) +- write(STDOUT_FILENO, "!E", 2); ++ printf("!E"); + else +- write(STDOUT_FILENO, "!EC", 3); ++ printf("!EC"); + return 0; + } + if (!(options & F_VERBOSE) || uid) diff --git a/pkgs/core/iw/iw.nm b/pkgs/core/iw/iw.nm new file mode 100644 index 0000000..b7ed0fc --- /dev/null +++ b/pkgs/core/iw/iw.nm @@ -0,0 +1,56 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = iw +PKG_VER = 0.9.17 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://www.linuxwireless.org/en/users/Documentation/iw +PKG_LICENSE = BSD +PKG_SUMMARY = A nl80211 based wireless configuration tool. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += libnl + +define PKG_DESCRIPTION + iw is a new nl80211 based CLI configuration utility for wireless \ + devices. Currently you can only use this utility to configure devices \ + which use a mac80211 driver as these are the new drivers being written \ + - only because most new wireless devices being sold are now SoftMAC. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/sbin + mv -v $(BUILDROOT)/usr/sbin/iw $(BUILDROOT)/sbin/iw +endef diff --git a/pkgs/core/iw/patches/iw-0.9.17-default-install-to-PREFIX-sbin.patch b/pkgs/core/iw/patches/iw-0.9.17-default-install-to-PREFIX-sbin.patch new file mode 100644 index 0000000..74c8e33 --- /dev/null +++ b/pkgs/core/iw/patches/iw-0.9.17-default-install-to-PREFIX-sbin.patch @@ -0,0 +1,42 @@ +From f8a9dbbbde041fca098b579c3669819e8282577a Mon Sep 17 00:00:00 2001 +From: John W. Linville <linville@tuxdriver.com> +Date: Wed, 30 Sep 2009 09:17:39 -0400 +Subject: [iw PATCH] default install to $(PREFIX)/sbin + +The iw utility isn't generally useful to normal users, so move it to +$(PREFIX)/sbin with other system management executables. + +Signed-off-by: John W. Linville <linville@tuxdriver.com> +--- +As "suggested" by Johannes... :-) + + Makefile | 6 +++--- + 1 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Makefile b/Makefile +index cb5fcc1..68bef4d 100644 +--- a/Makefile ++++ b/Makefile +@@ -3,7 +3,7 @@ + MAKEFLAGS += --no-print-directory + + PREFIX ?= /usr +-BINDIR ?= $(PREFIX)/bin ++SBINDIR ?= $(PREFIX)/sbin + MANDIR ?= $(PREFIX)/share/man + PKG_CONFIG ?= pkg-config + +@@ -85,8 +85,8 @@ check: + + install: iw iw.8.gz + @$(NQ) ' INST iw' +- $(Q)$(MKDIR) $(DESTDIR)$(BINDIR) +- $(Q)$(INSTALL) -m 755 -t $(DESTDIR)$(BINDIR) iw ++ $(Q)$(MKDIR) $(DESTDIR)$(SBINDIR) ++ $(Q)$(INSTALL) -m 755 -t $(DESTDIR)$(SBINDIR) iw + @$(NQ) ' INST iw.8' + $(Q)$(MKDIR) $(DESTDIR)$(MANDIR)/man8/ + $(Q)$(INSTALL) -m 644 -t $(DESTDIR)$(MANDIR)/man8/ iw.8.gz +-- +1.6.2.5 + diff --git a/pkgs/core/joe/joe.nm b/pkgs/core/joe/joe.nm new file mode 100644 index 0000000..d5366eb --- /dev/null +++ b/pkgs/core/joe/joe.nm @@ -0,0 +1,45 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = joe +PKG_VER = 3.7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Editors +PKG_URL = http://joe-editor.sourceforge.net/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A small text editor similar to wordstar in matter of usage. + +define PKG_DESCRIPTION + Joe is a small and friendly text editor which provides the look \ + and feel of the good old wordstar. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc diff --git a/pkgs/core/jwhois/jwhois.nm b/pkgs/core/jwhois/jwhois.nm new file mode 100644 index 0000000..3ac74d4 --- /dev/null +++ b/pkgs/core/jwhois/jwhois.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = jwhois +PKG_VER = 4.0 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Internet +PKG_URL = http://www.gnu.org/software/jwhois/ +PKG_LICENSE = GPLv3 +PKG_SUMMARY = Internet whois/nicname client. + +PKG_DEPS += gdbm + +define PKG_DESCRIPTION + A whois client that accepts both traditional and finger-style queries. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +PKG_PATCHES = $(THISAPP)-connect.patch +PKG_PATCHES += $(THISAPP)-ipv6match.patch +PKG_PATCHES += $(THISAPP)-enum.patch +PKG_PATCHES += $(THISAPP)-fclose.patch +PKG_PATCHES += $(THISAPP)-conf.patch +PKG_PATCHES += $(THISAPP)-gi.patch +PKG_PATCHES += $(THISAPP)-conf_update.patch +PKG_PATCHES += $(THISAPP)-conf_update2.patch +PKG_PATCHES += $(THISAPP)-dotster.patch +PKG_PATCHES += $(THISAPP)-conf_update3.patch +PKG_PATCHES += $(THISAPP)-conf_update4.patch + +CONFIGURE_OPTIONS += --sysconfdir=/etc diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-conf.patch b/pkgs/core/jwhois/patches/jwhois-4.0-conf.patch new file mode 100644 index 0000000..7de452d --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-conf.patch @@ -0,0 +1,47 @@ +diff -up jwhois-4.0/example/jwhois.conf_old jwhois-4.0/example/jwhois.conf +--- jwhois-4.0/example/jwhois.conf_old 2007-03-26 11:12:08.000000000 +0200 ++++ jwhois-4.0/example/jwhois.conf 2008-10-13 14:43:48.000000000 +0200 +@@ -593,13 +593,12 @@ cidr6-blocks { + "2001:1600::/23" = "whois.ripe.net"; + "2001:1800::/23" = "whois.arin.net"; + "2001:1A00::/23" = "whois.ripe.net"; +- "2001:1C00::/23" = "whois.ripe.net"; +- "2001:1E00::/23" = "whois.ripe.net"; ++ "2001:1C00::/22" = "whois.ripe.net"; + "2001:2000::/20" = "whois.ripe.net"; + "2001:3000::/21" = "whois.ripe.net"; + "2001:3800::/22" = "whois.ripe.net"; + "2001:4000::/23" = "whois.ripe.net"; +- "2001:4200::/23" = "whois.arin.net"; ++ "2001:4200::/23" = "whois.afrinic.net"; + "2001:4400::/23" = "whois.apnic.net"; + "2001:4600::/23" = "whois.ripe.net"; + "2001:4800::/23" = "whois.arin.net"; +@@ -612,21 +611,15 @@ cidr6-blocks { + + "2003:0000::/18" = "whois.ripe.net"; + +- "2400:0000::/19" = "whois.apnic.net"; +- "2400:2000::/19" = "whois.apnic.net"; +- "2400:4000::/21" = "whois.apnic.net"; +- "2404:0000::/23" = "whois.apnic.net"; +- +- "2600:0000::/22" = "whois.arin.net"; +- "2604:0000::/22" = "whois.arin.net"; +- "2608:0000::/22" = "whois.arin.net"; +- "260C:0000::/22" = "whois.arin.net"; ++ "2400:0000::/12" = "whois.apnic.net"; ++ ++ "2600:0000::/12" = "whois.arin.net"; + "2610:0000::/23" = "whois.arin.net"; ++ "2620:0000::/23" = "whois.arin.net"; + +- "2800:0000::/23" = "whois.lacnic.net"; ++ "2800:0000::/12" = "whois.lacnic.net"; + +- "2A00:0000::/21" = "whois.ripe.net"; +- "2A01:0000::/16" = "whois.ripe.net"; ++ "2C00:0000::/12" = "whois.afrinic.net"; + + # + # Experimental IPv6 network 6bone (RFC2471) diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-conf_update.patch b/pkgs/core/jwhois/patches/jwhois-4.0-conf_update.patch new file mode 100644 index 0000000..f3457e2 --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-conf_update.patch @@ -0,0 +1,482 @@ +diff -up jwhois-4.0/example/jwhois.conf.conf_update jwhois-4.0/example/jwhois.conf +--- jwhois-4.0/example/jwhois.conf.conf_update 2009-02-27 10:17:01.000000000 +0100 ++++ jwhois-4.0/example/jwhois.conf 2009-02-27 10:57:26.000000000 +0100 +@@ -32,6 +32,7 @@ whois-servers { + "^CORE-[0-9]+$" = "struct handles"; + "^CO[CH]O-[0-9]+$" = "struct handles"; + ".*-[A-Z]+$" = "struct handles"; ++ ".*-6BONE$" = "struct handles"; + + # + # Catch AS numbers +@@ -86,6 +87,7 @@ whois-servers { + # Pseudo-ccTLDs must be listed above gTLDs + # + "\.ae\.org$" = "whois.centralnic.net"; ++ "\.ar\.com$" = "whois.centralnic.com"; + "\.br\.com$" = "whois.centralnic.net"; + "\.cn\.com$" = "whois.centralnic.net"; + "\.de\.com$" = "whois.centralnic.net"; +@@ -108,17 +110,21 @@ whois-servers { + "\.uy\.com$" = "whois.centralnic.net"; + "\.web\.com$" = "whois.centralnic.net"; + "\.za\.com$" = "whois.centralnic.net"; ++ "\.za\.net$" = "whois.za.net"; ++ "\.za\.org$" = "whois.za.org"; + + "\.ac$" = "whois.nic.ac"; +- "\.ae$" = "whois.uaenic.ae"; ++ "\.ae$" = "whois.aeda.net.ae"; + "\.aero$" = "whois.aero"; +- "\.af$" = "whois.nic.af"; ++ "\.af$" = "whois.cocca.cx"; + "\.ag$" = "whois.nic.ag"; +- "\.ai$" = "whois.offshore.ai"; ++ "\.ai$" = "whois.ai"; + "\.al$" = "whois.ripe.net"; + "\.am$" = "whois.amnic.net"; + "\.ar$" = "www.nic.ar"; ++ "\.arpa$" = "whois.iana.org"; + "\.as$" = "whois.nic.as"; ++ "\.asia$" = "whois.nic.asia"; + "\.at$" = "whois.nic.at"; + "\.asn\.au$" = "whois.ausregistry.net.au"; + "\.com\.au$" = "whois.ausregistry.net.au"; +@@ -130,25 +136,33 @@ whois-servers { + "\.ba$" = "whois.ripe.net"; + "\.be$" = "whois.dns.be"; + "\.bg$" = "whois.register.bg"; +- "\.bi$" = "www.nic.bi"; +- "\.biz$" = "whois.neulevel.biz"; ++ "\.bi$" = "whois.nic.bi"; ++ "\.biz$" = "whois.biz"; + "\.bj$" = "whois.nic.bj"; + "\.bm$" = "rwhois.ibl.bm 4321"; ++ "\.bo$" = "whois.nic.bo"; + "\.br$" = "whois.nic.br"; + "\.bv$" = "whois.ripe.net"; + "\.by$" = "whois.ripe.net"; + "\.bz$" = "whois.belizenic.bz"; ++ "\.co\.ca$" = "whois.co.ca"; + "\.ca$" = "whois.cira.ca"; + "\.cat$" = "whois.cat"; +- "\.cc$" = "whois.nic.cc"; ++ "\.cc$" { ++ whois-server = "ccwhois.verisign-grs.com"; ++ query-format = "domain $*"; ++ } + "\.cd$" = "whois.nic.cd"; + "\.cg$" = "www.nic.cg"; + "\.ch$" = "whois.nic.ch"; + "\.ci$" = "whois.nic.ci"; + "\.ck$" = "whois.nic.ck"; + "\.cl$" = "whois.nic.cl"; ++ "\.co\.cm$" = "whois.netcom.cm"; ++ "\.com\.cm$" = "whois.netcom.cm"; ++ "\.net\.cm$" = "whois.netcom.cm"; + "\.edu\.cn$" = "whois.edu.cn"; +- "\.cn$" = "whois.cnnic.net.cn"; ++ "\.cn$" = "whois.cnnic.cn"; + "\.com$" { + whois-server = "whois.verisign-grs.com"; + query-format = "domain $*"; +@@ -166,7 +180,7 @@ whois-servers { + "\.do$" = "whois.nic.do"; + "\.dz$" = "whois.ripe.net"; + "\.ec$" = "www.nic.ec"; +- "\.edu$" = "whois.educause.net"; ++ "\.edu$" = "whois.educause.edu"; + "\.ee$" = "whois.eenet.ee"; + "\.eg$" = "whois.ripe.net"; + "\.es$" = "www.nic.es"; +@@ -176,17 +190,20 @@ whois-servers { + "\.fm$" = "www.dot.fm"; + "\.fo$" = "whois.ripe.net"; + "\.fr$" = "whois.nic.fr"; ++ "\.gd$" = "whois.adamsnames.com"; + "\.gi$" = "whois2.afilias-grs.net"; + "\.gov$" = "whois.nic.gov"; +- "\.gg$" = "whois.isles.net"; ++ "\.gg$" = "whois.gg"; + "\.gm$" = "whois.ripe.net"; + "\.gp$" = "whois.nic.gp"; + "\.gr$" = "whois.ripe.net"; +- "\.gs$" = "203.119.12.22"; ++ "\.gs$" = "whois.nic.gs"; + "\.gt$" = "www.gt"; +- "\.hk$" = "whois.hkdnr.net.hk"; ++ "\.hk$" = "whois.hkirc.hk"; + "\.hm$" = "whois.registry.hm"; ++ "\.hn$" = "whois2.afilias-grs.net"; + "\.hr$" = "www.dns.hr"; ++ "\.ht$" = "whois.nic.ht"; + "\.hu$" = "whois.nic.hu"; + "\.id$" = "whois.idnic.net.id"; + "\.ie$" = "whois.domainregistry.ie"; +@@ -200,29 +217,39 @@ whois-servers { + "\.is$" = "whois.isnic.is"; + "\.it$" = "whois.nic.it"; + "\.je$" = "whois.isles.net"; ++ "\.jobs$" { ++ whois-server = "jobswhois.verisign-grs.com"; ++ query-format = "domain $*"; ++ } + "\.jp$" { + whois-server = "whois.jprs.jp"; + query-format = "$* /e"; + } ++ "\.ke$" = "whois.kenic.or.ke"; ++ "\.kp$" = "whois.kcce.kp"; + "\.kg$" = "whois.domain.kg"; +- "\.ki$" = "whois.nic.ki"; ++ "\.ki$" = "whois.cocca.cx"; + "\.kr$" = "whois.krnic.net"; + "\.kz$" = "whois.nic.kz"; + "\.la$" = "whois.nic.la"; + "\.lb$" = "cgi.aub.edu.lb"; ++ "\.lc$" = "whois2.afilias-grs.net"; + "\.li$" = "whois.nic.li"; + "\.lk$" = "whois.nic.lk"; + "\.lt$" = "whois.domreg.lt"; + "\.lu$" = "whois.dns.lu"; + "\.lv$" = "whois.nic.lv"; + "\.ly$" = "whois.nic.ly"; +- "\.ma$" = "whois.ripe.net"; ++ "\.ma$" = "whois.iam.net.ma"; ++ "\.md$" = "whois.nic.md"; ++ "\.me$" = "whois.nic.me"; + "\.mil$" = "whois.nic.mil"; + "\.mk$" = "whois.ripe.net"; + "\.mm$" = "whois.nic.mm"; ++ "\.mn$" = "whois2.afilias-grs.net"; + "\.mobi$" = "whois.dotmobiregistry.net"; +- "\.ms$" = "whois.adamsnames.tc"; +- "\.mt$" = "www.um.edu.mt"; ++ "\.ms$" = "whois.nic.ms"; ++ "\.mt$" = "whois.nic.org.mt"; + "\.mu$" = "whois.nic.mu"; + "\.museum$" = "whois.museum"; + "\.mw$" = "www.tarsus.net"; +@@ -234,31 +261,37 @@ whois-servers { + whois-server = "whois.verisign-grs.com"; + query-format = "domain $*"; + } ++ "\.nf$" = "whois.cocca.cx"; + "\.ng$" = "whois.rg.net"; + "\.nl$" = "whois.domain-registry.nl"; + "\.no$" = "whois.norid.no"; + "\.nu$" = "whois.nic.nu"; + "\.nz$" = "whois.srs.net.nz"; + "\.org$" = "whois.publicinterestregistry.net"; +- "\.pe$" = "whois.nic.pe"; ++ "\.pe$" = "kero.yachay.pe"; + "\.pk$" = "pknic.net.pk"; + "\.pl$" = "whois.dns.pl"; + "\.pm$" = "whois.nic.pm"; ++ "\.pr$" = "whois.nic.pr"; + "\.pro$" = "whois.registrypro.pro"; + "\.pt$" = "whois.dns.pt"; + "\.pw$" = "whois.nic.pw"; + "\.re$" = "whois.nic.re"; + "\.ro$" = "whois.rotld.ro"; ++ "\.edu.ru$" = "whois.informika.ru"; + "\.ru$" = "whois.ripn.net"; + "\.rw$" = "www.nic.rw"; + "\.sa$" = "saudinic.net.sa"; ++ "\.sb$" = "whois.nic.sb"; ++ "\.sc$" = "whois2.afilias-grs.net"; + "\.se$" = "whois.iis.se"; + "\.sg$" = "whois.nic.net.sg"; + "\.sh$" = "whois.nic.sh"; + "\.si$" = "whois.arnes.si"; + "\.sj$" = "whois.ripe.net"; +- "\.sk$" = "whois.ripe.net"; ++ "\.sk$" = "whois.sk-nic.sk"; + "\.sm$" = "whois.ripe.net"; ++ "\.sn$" = "whois.nic.sn"; + "\.sr$" = "whois.register.sr"; + "\.st$" = "whois.nic.st"; + "\.su$" = "whois.ripn.net"; +@@ -273,8 +306,12 @@ whois-servers { + "\.tn$" = "whois.ripe.net"; + "\.to$" = "whois.tonic.to"; + "\.tr$" = "whois.nic.tr"; ++ "\.travel$" = "whois.nic.travel"; + "\.tt$" = "www.nic.tt"; +- "\.tv$" = "whois.nic.tv"; ++ "\.tv$" { ++ whois-server = "tvwhois.verisign-grs.com"; ++ query-format = "domain $*"; ++ } + "\.tw$" = "whois.twnic.net"; + "\.ua$" = "whois.com.ua"; + "\.ug$" = "whois.co.ug"; +@@ -285,8 +322,11 @@ whois-servers { + "\.us$" = "whois.nic.us"; + "\.com\.uy$" = "dns.antel.net.uy"; + "\.uy$" = "www.rau.edu.uy"; # is a whois server +- "\.uz$" = "www.noc.uz"; ++ "\.co\.uz$" = "whois.reg.uz"; ++ "\.com\.uz$" = "whois.reg.uz"; ++ "\.uz$" = "whois.cctld.uz"; + "\.va$" = "whois.ripe.net"; ++ "\.vc$" = "whois2.afilias-grs.net"; + "\.ve$" = "whois.nic.ve"; + "\.vi$" = "www.nic.vi"; + "\.vg$" = "whois.adamsnames.tc"; +@@ -299,6 +339,7 @@ whois-servers { + "\.ac\.za$" = "whois.ac.za"; + "\.org\.za$" = "rwhois.org.za 4321"; + "\.co\.za$" = "whois.co.za"; ++ "\.nom\.za$" = "www.nom.za"; + # "\.za$" = "whois.frd.ac.za"; + + # +@@ -594,7 +635,7 @@ cidr-blocks { + cidr6-blocks { + type = cidr6; + +- "2001:0000::/23" = "whois.iana.org"; ++ "2001:0000::/23" = "whois.iana.org"; # correct, but nothing usable is returned + "2001:0200::/23" = "whois.apnic.net"; + "2001:0400::/23" = "whois.arin.net"; + "2001:0600::/23" = "whois.ripe.net"; +@@ -611,6 +652,7 @@ cidr6-blocks { + "2001:2000::/20" = "whois.ripe.net"; + "2001:3000::/21" = "whois.ripe.net"; + "2001:3800::/22" = "whois.ripe.net"; ++ "2001:3C00::/22" = "whois.arin.net"; # not correct, but shows better information + "2001:4000::/23" = "whois.ripe.net"; + "2001:4200::/23" = "whois.afrinic.net"; + "2001:4400::/23" = "whois.apnic.net"; +@@ -623,6 +665,8 @@ cidr6-blocks { + "2001:A000::/20" = "whois.apnic.net"; + "2001:B000::/20" = "whois.apnic.net"; + ++ "2002:0000::/16" = "whois.arin.net"; # not correct, but shows better information ++ + "2003:0000::/18" = "whois.ripe.net"; + + "2400:0000::/12" = "whois.apnic.net"; +@@ -636,6 +680,34 @@ cidr6-blocks { + "2C00:0000::/12" = "whois.afrinic.net"; + + # ++ # IPv6 blocks by carriers used for SixXS; ++ # see e.g. http://www.sixxs.net/pops/ ++ # ++ "2001:0610::/32" = "whois.sixxs.net"; ++ "2001:06A0::/32" = "whois.sixxs.net"; ++ "2001:06A8::/32" = "whois.sixxs.net"; ++ "2001:06F8::/32" = "whois.sixxs.net"; ++ "2001:0770::/32" = "whois.sixxs.net"; ++ "2001:07B8::/32" = "whois.sixxs.net"; ++ "2001:0808::/32" = "whois.sixxs.net"; ++ "2001:0838::/32" = "whois.sixxs.net"; ++ "2001:0960::/32" = "whois.sixxs.net"; ++ "2001:0A60::/32" = "whois.sixxs.net"; ++ "2001:0AD0::/32" = "whois.sixxs.net"; ++ "2001:0B18::/32" = "whois.sixxs.net"; ++ "2001:1418::/32" = "whois.sixxs.net"; ++ "2001:14B8::/32" = "whois.sixxs.net"; ++ "2001:15C0::/32" = "whois.sixxs.net"; ++ "2001:16D8::/32" = "whois.sixxs.net"; ++ "2001:1938::/32" = "whois.sixxs.net"; ++ "2001:4830::/32" = "whois.sixxs.net"; ++ "2001:4978::/32" = "whois.sixxs.net"; ++ "2001:41E0::/32" = "whois.sixxs.net"; ++ "2001:4428::/32" = "whois.sixxs.net"; ++ "2A01:0198::/32" = "whois.sixxs.net"; ++ "2A01:0348::/32" = "whois.sixxs.net"; ++ ++ # + # Experimental IPv6 network 6bone (RFC2471) + # Phaseout at Jun, 6 2006 (RFC3701) + # +@@ -678,6 +750,33 @@ handles { + whois-server = "saudinic.net.sa"; + query-format = "PERSON $*"; + } ++ ".*-SIXXS$" = "whois.sixxs.net"; ++ ".*-6BONE$" = "whois.6bone.net"; ++ ".*-IRNIC$" = "whois.nic.ir"; ++ ".*-RIPN$" = "whois.ripn.net"; ++ ".*-AFRINIC$" = "whois.afrinic.net"; ++ "^C[0-9]+-LRMS$" { ++ whois-server = "whois.afilias.info"; ++ query-format = "CONTACT ID $*"; ++ } ++ "^D[0-9]+-LRMS$" { ++ whois-server = "whois.afilias.info"; ++ query-format = "DOMAIN ID $*"; ++ } ++ "^H[0-9]+-LRMS$" { ++ whois-server = "whois.afilias.info"; ++ query-format = "HOST ID $*"; ++ } ++ "^R[0-9]+-LRMS$" { ++ whois-server = "whois.afilias.info"; ++ query-format = "REGISTRAR ID $*"; ++ } ++ ".*-KENIC$" = "whois.kenic.or.ke"; ++ ".*-UANIC$" = "whois.com.ua"; ++ ".*-COOP$" { ++ whois-server = "whois.nic.coop"; ++ query-format = "CONTACT $*"; ++ } + } + + # +@@ -685,11 +784,6 @@ handles { + # each host. + # + server-options { +- "rwhois\.nic\.ve" { +- rwhois = true; +- rwhois-display = "dump"; +- rwhois-limit = 10; +- } + "rwhois\.exodus\.net" { + rwhois = true; + } +@@ -761,13 +855,6 @@ server-options { + form-element = "name"; + } + +- "www\.um\.edu\.mt" { +- http = "true"; +- http-method = "GET"; +- http-action = "/cgi-bin/nic/whois"; +- form-element = "domain"; +- } +- + "www\.gt" { + http = "true"; + http-method = "GET"; +@@ -784,13 +871,6 @@ server-options { + query-format = "Upit=${+2}"; # All but last domain segment + } + +- "whois\.offshore\.ai" { +- http = "true"; +- http-method = "POST"; +- http-action = "/cgi-bin/whois.pl"; +- form-element = "domain-name"; +- } +- + "www\.io\.io" { + http = "true"; + http-method = "GET"; +@@ -820,11 +900,12 @@ server-options { + form-element = "query"; + } + +- "www\.nic\.bi" { +- http = "true"; +- http-method = "POST"; +- http-action = "/cgi-bin/whoisbi.pl"; # Formatting problems in Lynx +- form-element = "DOMAINWHOIS"; ++ "whois\.nic\.bi" { ++ http = "true"; # I can't connect on port 43 ++ http-method = "GET"; ++ http-action = "/register/whois.hei"; ++ form-element = "query"; ++ form-extra = "type=domain"; + } + + "www\.nic\.cg" { +@@ -855,13 +936,6 @@ server-options { + form-element = "name"; + } + +- "www\.noc\.uz" { +- http = "true"; +- http-method = "POST"; +- http-action = "/whois.php4"; +- form-element = "dname"; +- } +- + "www\.nic\.vi" { + http = "true"; + http-method = "POST"; +@@ -885,9 +959,9 @@ server-options { + + "www\.nic\.tg" { + http = "true"; +- http-method = "GET"; +- http-action = "/moteur/info_dom.php"; +- form-element = "domaine"; ++ http-method = "POST"; ++ http-action = "/nictg/indexplus.php?pg=verifdom&op=whois"; ++ query-format = "tosearch=${+2}&typedom=.tg"; + } + + "cgi\.aub\.edu\.lb" { +@@ -917,38 +991,60 @@ server-options { + form-element = "nombre"; + } + +- "www\.denic\.de" { +- http = "true"; +- http-method = "POST"; +- http-action = "/en/whois/data.jsp"; +- form-element = "domainname"; +- form-extra = "service=WhoisData&lang=en&submit=Accept"; +- } + "whois\.denic\.de" { + whois-server = "whois.denic.de"; + query-format = "-C UTF-8 -T dn,ace $*"; + answer-charset = "UTF-8"; + } ++ + "whois\.enum\.denic\.de" { + whois-server = "whois.enum.denic.de"; + query-format = "-C UTF-8 -T dn $*"; + answer-charset = "UTF-8"; + } ++ + "whois\.nic\.ad\.jp" { + query-format = "$*/e"; + } ++ + "whois\.nic\.ch" { + answer-charset = "UTF-8"; + } ++ + "whois\.nic\.li" { + answer-charset = "UTF-8"; + } ++ + "whois\.centralnic\.*" { + whois-redirect = ".*Whois Server: \(.*\)"; + } ++ + ".*\.verisign-grs\.com" { + whois-redirect = ".*Whois Server: \(.*\)"; + } ++ ++ "whois\.sixxs\.net" { ++ whois-redirect = ".*ReferralServer: whois://\(.*\)"; ++ } ++ ++ "whois2\.afilias-grs\.net" { ++ whois-redirect = "Whois Server:\(.*\)"; ++ } ++ ++ "whois\.registrar\.telekom\.de" { ++ query-format = "full $*"; ++ } ++ ++ "whois\.rrpproxy\.net" { ++ answer-charset = "UTF-8"; ++ } ++ ++ "www\.nom\.za" { ++ http = "true"; ++ http-method = "POST"; ++ http-action = "/do.php"; ++ query-format = "chkDomain=${+3}&chkAvail=Check"; ++ } + } + + # diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-conf_update2.patch b/pkgs/core/jwhois/patches/jwhois-4.0-conf_update2.patch new file mode 100644 index 0000000..df9ca4e --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-conf_update2.patch @@ -0,0 +1,90 @@ +--- jwhois-4.0/example/jwhois.conf 2009-02-27 22:20:48.000000000 +0100 ++++ jwhois-4.0/example/jwhois.conf.rsc 2009-03-08 12:33:22.000000000 +0100 +@@ -178,7 +178,7 @@ + "\.dk$" = "whois.dk-hostmaster.dk"; + "\.dm$" = "whois.nic.dm"; + "\.do$" = "whois.nic.do"; +- "\.dz$" = "whois.ripe.net"; ++ "\.dz$" = "www.nic.dz"; + "\.ec$" = "www.nic.ec"; + "\.edu$" = "whois.educause.edu"; + "\.ee$" = "whois.eenet.ee"; +@@ -268,6 +268,7 @@ + "\.nu$" = "whois.nic.nu"; + "\.nz$" = "whois.srs.net.nz"; + "\.org$" = "whois.publicinterestregistry.net"; ++ "\.pa$" = "www.nic.pa"; + "\.pe$" = "kero.yachay.pe"; + "\.pk$" = "pknic.net.pk"; + "\.pl$" = "whois.dns.pl"; +@@ -296,6 +297,7 @@ + "\.st$" = "whois.nic.st"; + "\.su$" = "whois.ripn.net"; + "\.tc$" = "whois.adamsnames.tc"; ++ "\.tel$" = "whois.nic.tel"; + "\.tf$" = "whois.afnic.fr"; + "\.tg$" = "www.nic.tg"; + "\.th$" = "whois.thnic.net"; +@@ -321,7 +323,7 @@ + "\.fed\.us$" = "whois.nic.gov"; + "\.us$" = "whois.nic.us"; + "\.com\.uy$" = "dns.antel.net.uy"; +- "\.uy$" = "www.rau.edu.uy"; # is a whois server ++ "\.uy$" = "whois.nic.org.uy"; + "\.co\.uz$" = "whois.reg.uz"; + "\.com\.uz$" = "whois.reg.uz"; + "\.uz$" = "whois.cctld.uz"; +@@ -335,7 +337,7 @@ + "\.wf$" = "whois.nic.wf"; + "\.ws$" = "whois.worldsite.ws"; + "\.yt$" = "whois.nic.yt"; +- "\.yu$" = "whois.ripe.net"; ++ "\.yu$" = "www.nic.yu"; + "\.ac\.za$" = "whois.ac.za"; + "\.org\.za$" = "rwhois.org.za 4321"; + "\.co\.za$" = "whois.co.za"; +@@ -363,6 +365,7 @@ + type = regex; + + "\.9\.4\.e164\.arpa$" = "whois.enum.denic.de"; ++ "\.1\.6\.e164\.arpa$" = "whois-check.enum.com.au"; + } + + # +@@ -741,7 +744,7 @@ + ".*-NICAT$" = "whois.nic.at"; + ".*-CZ$" = "whois.nic.cz"; + ".*-NICIR$" = "whois.nic.ir"; +- ".*-UYNIC$" = "www.rau.edu.uy"; ++ ".*-UYNIC$" = "whois.nic.org.uy"; + ".*-ITNIC$" = "whois.nic.it"; + ".*-FRNIC$" = "whois.nic.fr"; + ".*-LACNIC$" = "whois.lacnic.net"; +@@ -1045,6 +1048,27 @@ + http-action = "/do.php"; + query-format = "chkDomain=${+3}&chkAvail=Check"; + } ++ ++ "www\.nic\.pa" { ++ http = "true"; ++ http-method = "GET"; ++ http-action = "/egh/whois.php"; ++ form-element = "nombre_d"; ++ } ++ ++ "www\.nic\.dz" { ++ http = "true"; ++ http-method = "POST"; ++ http-action = "/index.php?option=com_content&task=view&id=37&Itemid=51"; ++ form-element = "domain_name"; ++ } ++ ++ "www\.nic\.yu" { ++ http = "true"; ++ http-method = "GET"; ++ http-action = "/cgi-bin/checkavail.cgi"; ++ form-element = "domain"; ++ } + } + + # diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-conf_update3.patch b/pkgs/core/jwhois/patches/jwhois-4.0-conf_update3.patch new file mode 100644 index 0000000..a954666 --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-conf_update3.patch @@ -0,0 +1,61 @@ +--- jwhois-4.0/example/jwhois.conf 2009-05-03 13:15:33.000000000 +0200 ++++ jwhois-4.0/example/jwhois.conf.rsc 2009-05-03 13:17:52.000000000 +0200 +@@ -119,7 +119,7 @@ + "\.af$" = "whois.cocca.cx"; + "\.ag$" = "whois.nic.ag"; + "\.ai$" = "whois.ai"; +- "\.al$" = "whois.ripe.net"; ++ "\.al$" = "www.ert.gov.al"; + "\.am$" = "whois.amnic.net"; + "\.ar$" = "www.nic.ar"; + "\.arpa$" = "whois.iana.org"; +@@ -168,6 +168,7 @@ + query-format = "domain $*"; + } + "\.coop$" = "whois.nic.coop"; ++ "\.cu$" = "www.nic.cu"; + "\.cx$" = "whois.nic.cx"; + "\.cy$" = "whois.ripe.net"; + "\.cz$" = "whois.nic.cz"; +@@ -254,7 +255,7 @@ + "\.museum$" = "whois.museum"; + "\.mw$" = "www.tarsus.net"; + "\.mx$" = "whois.nic.mx"; +- "\.my$" = "whois.mynic.net.my"; ++ "\.my$" = "whois.domainregistry.my"; + "\.na$" = "whois.na-nic.com.na"; + "\.name$" = "whois.nic.name"; + "\.net$" { +@@ -293,6 +294,7 @@ + "\.sk$" = "whois.sk-nic.sk"; + "\.sm$" = "whois.ripe.net"; + "\.sn$" = "whois.nic.sn"; ++ "\.so$" = "whois.nic.so"; + "\.sr$" = "whois.register.sr"; + "\.st$" = "whois.nic.st"; + "\.su$" = "whois.ripn.net"; +@@ -1069,9 +1071,24 @@ + http-action = "/cgi-bin/checkavail.cgi"; + form-element = "domain"; + } ++ + "whois\.dotster\.com" { + answer-charset = "UTF-8"; + } ++ ++ "www\.ert\.gov\.al" { ++ http = "true"; ++ http-method = "POST"; ++ http-action = "/ert_eng/domain_res.html"; ++ query-format = "Domain=${+2}"; ++ } ++ ++ "www\.nic\.cu" { ++ http = "true"; ++ http-method = "GET"; ++ http-action = "/dom_det.php"; ++ form-element = "domsrch"; ++ } + } + + # diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-conf_update4.patch b/pkgs/core/jwhois/patches/jwhois-4.0-conf_update4.patch new file mode 100644 index 0000000..ffbe53d --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-conf_update4.patch @@ -0,0 +1,168 @@ +--- jwhois-4.0/example/jwhois.conf 2009-08-16 17:59:06.000000000 +0200 ++++ jwhois-4.0/example/jwhois.conf.rsc 2009-08-16 17:59:39.000000000 +0200 +@@ -121,6 +121,7 @@ + "\.ai$" = "whois.ai"; + "\.al$" = "www.ert.gov.al"; + "\.am$" = "whois.amnic.net"; ++ "\.edu\.ar$" = "www.riu.edu.ar"; + "\.ar$" = "www.nic.ar"; + "\.arpa$" = "whois.iana.org"; + "\.as$" = "whois.nic.as"; +@@ -142,8 +143,9 @@ + "\.bm$" = "rwhois.ibl.bm 4321"; + "\.bo$" = "whois.nic.bo"; + "\.br$" = "whois.nic.br"; ++ "\.bs$" = "www.register.bs"; + "\.bv$" = "whois.ripe.net"; +- "\.by$" = "whois.ripe.net"; ++ "\.by$" = "www.domain.by"; + "\.bz$" = "whois.belizenic.bz"; + "\.co\.ca$" = "whois.co.ca"; + "\.ca$" = "whois.cira.ca"; +@@ -176,7 +178,10 @@ + whois-server = "whois.denic.de"; + query-format = "-C UTF-8 -T dn,ace $*"; + } +- "\.dk$" = "whois.dk-hostmaster.dk"; ++ "\.dk$" { ++ whois-server = "whois.dk-hostmaster.dk"; ++ query-format = "--show-handles $*"; ++ } + "\.dm$" = "whois.nic.dm"; + "\.do$" = "whois.nic.do"; + "\.dz$" = "www.nic.dz"; +@@ -257,13 +262,16 @@ + "\.mx$" = "whois.nic.mx"; + "\.my$" = "whois.domainregistry.my"; + "\.na$" = "whois.na-nic.com.na"; +- "\.name$" = "whois.nic.name"; ++ "\.name$" { ++ whois-server = "whois.nic.name"; ++ query-format = "domain = $*"; ++ } + "\.net$" { + whois-server = "whois.verisign-grs.com"; + query-format = "domain $*"; + } + "\.nf$" = "whois.cocca.cx"; +- "\.ng$" = "whois.rg.net"; ++ "\.ng$" = "whois.nic.net.ng"; + "\.nl$" = "whois.domain-registry.nl"; + "\.no$" = "whois.norid.no"; + "\.nu$" = "whois.nic.nu"; +@@ -276,6 +284,7 @@ + "\.pm$" = "whois.nic.pm"; + "\.pr$" = "whois.nic.pr"; + "\.pro$" = "whois.registrypro.pro"; ++ "\.ps$" = "www.nic.ps"; + "\.pt$" = "whois.dns.pt"; + "\.pw$" = "whois.nic.pw"; + "\.re$" = "whois.nic.re"; +@@ -287,17 +296,19 @@ + "\.sb$" = "whois.nic.sb"; + "\.sc$" = "whois2.afilias-grs.net"; + "\.se$" = "whois.iis.se"; +- "\.sg$" = "whois.nic.net.sg"; ++ "\.sg$" = "whois.sgnic.sg"; + "\.sh$" = "whois.nic.sh"; + "\.si$" = "whois.arnes.si"; + "\.sj$" = "whois.ripe.net"; + "\.sk$" = "whois.sk-nic.sk"; ++ "\.sl$" = "whois.nic.sl"; + "\.sm$" = "whois.ripe.net"; + "\.sn$" = "whois.nic.sn"; + "\.so$" = "whois.nic.so"; + "\.sr$" = "whois.register.sr"; + "\.st$" = "whois.nic.st"; + "\.su$" = "whois.ripn.net"; ++ "\.sv$" = "www.svnet.org.sv"; + "\.tc$" = "whois.adamsnames.tc"; + "\.tel$" = "whois.nic.tel"; + "\.tf$" = "whois.afnic.fr"; +@@ -345,6 +356,7 @@ + "\.co\.za$" = "whois.co.za"; + "\.nom\.za$" = "www.nom.za"; + # "\.za$" = "whois.frd.ac.za"; ++ "\.co\.zw$" = "www.zispa.co.zw"; + + # + # Specify different port numbers to connect to by postfixing the IP +@@ -782,6 +794,22 @@ + whois-server = "whois.nic.coop"; + query-format = "CONTACT $*"; + } ++ ".*CONTACT-NAME$" { ++ whois-server = "whois.nic.name"; ++ query-format = "contact = $*"; ++ } ++ ".*REGISTRAR-NAME$" { ++ whois-server = "whois.nic.name"; ++ query-format = "registrar = $*"; ++ } ++ "^C[0-9]+-AERO$" { ++ whois-server = "whois.aero"; ++ query-format = "CONTACT ID $*"; ++ } ++ "^D[0-9]+-AERO$" { ++ whois-server = "whois.aero"; ++ query-format = "DOMAIN ID $*"; ++ } + } + + # +@@ -1089,6 +1117,55 @@ + http-action = "/dom_det.php"; + form-element = "domsrch"; + } ++ ++ "www\.nic\.ps" { ++ http = "true"; ++ http-method = "GET"; ++ http-action = "/whois/domain_whois.php"; ++ form-element = "dname"; ++ } ++ ++ "www\.svnet\.org\.sv" { ++ http = "true"; ++ http-method = "POST"; ++ http-action = "/registro/consultas/whois.php"; ++ form-element = "subdominio"; ++ } ++ ++ "www\.zispa\.co\.zw" { ++ http = "true"; ++ http-method = "GET"; ++ http-action = "/cgi-bin/search"; ++ form-element = "domain"; ++ } ++ ++ "www\.riu\.edu\.ar" { ++ http = "true"; ++ http-method = "POST"; ++ http-action = "/cgi-bin/verdom.pl.nuevo"; ++ query-format = "username=${+3}"; ++ } ++ ++ "www\.register\.bs" { ++ http = "true"; ++ http-method = "POST"; ++ http-action = "/cgi-bin/search.pl"; ++ form-element = "name"; ++ } ++ ++ "www\.domain\.by" { ++ http = "true"; ++ http-method = "POST"; ++ http-action = "/cgi-bin/registry.cgi"; ++ query-format = "domain=${+2}&lang=e&mode=slquest"; ++ } ++ ++ "www\.nic\.ac" { ++ http = "true"; ++ http-method = "GET"; ++ http-action = "/cgi-bin/whois"; ++ form-element = "textfield"; ++ } + } + + # diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-connect.patch b/pkgs/core/jwhois/patches/jwhois-4.0-connect.patch new file mode 100644 index 0000000..2a639d7 --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-connect.patch @@ -0,0 +1,58 @@ +This fixes somewhat reversed logic of trying to connect to WHOIS server. +Tue Nov 20 2007, Lubomir Kundrak <lkundrak@redhat.com> + +--- jwhois-4.0/src/utils.c.connect 2007-06-26 09:00:20.000000000 +0200 ++++ jwhois-4.0/src/utils.c 2007-11-20 17:05:33.000000000 +0100 +@@ -247,7 +247,7 @@ make_connect(const char *host, int port) + { + return -1; + } +- while (res) ++ for (; res; res = res->ai_next) + { + sa = res->ai_addr; + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); +@@ -266,15 +266,15 @@ make_connect(const char *host, int port) + flags = fcntl(sockfd, F_GETFL, 0); + if (fcntl(sockfd, F_SETFL, flags|O_NONBLOCK) == -1) + { ++ close (sockfd); + return -1; + } + +- + error = connect(sockfd, res->ai_addr, res->ai_addrlen); +- + if (error < 0 && errno != EINPROGRESS) + { +- break; ++ close (sockfd); ++ continue; + } + + FD_ZERO(&fdset); +@@ -283,18 +283,20 @@ make_connect(const char *host, int port) + error = select(FD_SETSIZE, NULL, &fdset, NULL, &timeout); + if (error == 0) + { +- break; ++ close (sockfd); ++ return -1; + } + + retlen = sizeof(retval); + error = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &retval, &retlen); + if (error < 0 || retval) + { +- break; ++ close (sockfd); ++ return -1; + } +- res = res->ai_next; ++ ++ break; + } +- if (error < 0 || retval) return -1; + #endif + + return sockfd; diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-dotster.patch b/pkgs/core/jwhois/patches/jwhois-4.0-dotster.patch new file mode 100644 index 0000000..0f10435 --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-dotster.patch @@ -0,0 +1,13 @@ +diff -up jwhois-4.0/example/jwhois.conf_old jwhois-4.0/example/jwhois.conf +--- jwhois-4.0/example/jwhois.conf_old 2009-04-23 16:16:41.000000000 +0200 ++++ jwhois-4.0/example/jwhois.conf 2009-04-23 16:18:15.000000000 +0200 +@@ -1069,6 +1069,9 @@ server-options { + http-action = "/cgi-bin/checkavail.cgi"; + form-element = "domain"; + } ++ "whois\.dotster\.com" { ++ answer-charset = "UTF-8"; ++ } + } + + # diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-enum.patch b/pkgs/core/jwhois/patches/jwhois-4.0-enum.patch new file mode 100644 index 0000000..1abae4e --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-enum.patch @@ -0,0 +1,43 @@ +diff -up jwhois-4.0/example/jwhois.conf.enum jwhois-4.0/example/jwhois.conf +--- jwhois-4.0/example/jwhois.conf.enum 2009-01-27 13:39:48.000000000 +0100 ++++ jwhois-4.0/example/jwhois.conf 2009-01-27 13:42:09.000000000 +0100 +@@ -17,6 +17,11 @@ whois-servers { + type = regex; + + # ++ # Catch ENUM domains ++ # ++ "\([0-9]\.\)+e164\.arpa" = "struct enum-blocks"; ++ ++ # + # You can use the special value `struct' to redirect the query + # to another block which optionally can use another type of matching. + # Here we use it to have IPv4 numbers matched using CIDR blocks instead +@@ -311,6 +316,15 @@ whois-servers { + } + + # ++# enum-blocks ++# ++enum-blocks { ++ type = regex; ++ ++ "\.9\.4\.e164\.arpa$" = "whois.enum.denic.de"; ++} ++ ++# + # cidr-blocks contains a list of all known CIDR blocks assigned to + # RIPE or APNIC. Default all queries to ARIN which has most other blocks. + # +@@ -915,6 +929,11 @@ server-options { + query-format = "-C UTF-8 -T dn,ace $*"; + answer-charset = "UTF-8"; + } ++ "whois\.enum\.denic\.de" { ++ whois-server = "whois.enum.denic.de"; ++ query-format = "-C UTF-8 -T dn $*"; ++ answer-charset = "UTF-8"; ++ } + "whois\.nic\.ad\.jp" { + query-format = "$*/e"; + } diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-fclose.patch b/pkgs/core/jwhois/patches/jwhois-4.0-fclose.patch new file mode 100644 index 0000000..e9c896f --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-fclose.patch @@ -0,0 +1,12 @@ +diff -up jwhois-4.0/src/init.c_old jwhois-4.0/src/init.c +--- jwhois-4.0/src/init.c_old 2007-06-26 08:59:17.000000000 +0200 ++++ jwhois-4.0/src/init.c 2009-01-27 15:49:35.000000000 +0100 +@@ -283,6 +283,8 @@ parse_args(int *argc, char ***argv) + if (in) + jconfig_parse_file(in); + ++ fclose(in); ++ + if (verbose>1) + { + printf("[Debug: Cache = %s]\n", cache?"On":"Off"); diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-gi.patch b/pkgs/core/jwhois/patches/jwhois-4.0-gi.patch new file mode 100644 index 0000000..c5582c9 --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-gi.patch @@ -0,0 +1,12 @@ +diff -up jwhois-4.0/example/jwhois.conf_old jwhois-4.0/example/jwhois.conf +--- jwhois-4.0/example/jwhois.conf_old 2009-01-23 12:57:35.000000000 +0100 ++++ jwhois-4.0/example/jwhois.conf 2009-01-23 12:58:41.000000000 +0100 +@@ -171,7 +171,7 @@ whois-servers { + "\.fm$" = "www.dot.fm"; + "\.fo$" = "whois.ripe.net"; + "\.fr$" = "whois.nic.fr"; +- "\.gi$" = "www.nic.gi"; ++ "\.gi$" = "whois2.afilias-grs.net"; + "\.gov$" = "whois.nic.gov"; + "\.gg$" = "whois.isles.net"; + "\.gm$" = "whois.ripe.net"; diff --git a/pkgs/core/jwhois/patches/jwhois-4.0-ipv6match.patch b/pkgs/core/jwhois/patches/jwhois-4.0-ipv6match.patch new file mode 100644 index 0000000..0e5ad0e --- /dev/null +++ b/pkgs/core/jwhois/patches/jwhois-4.0-ipv6match.patch @@ -0,0 +1,15 @@ +When IPv6 address mask did not end on an octed boundary, the the opposite +part of last byte of host address was taken into account when a match was +attempted. -- Lubomir Kundrak <lkundrak@redhat.com> + +--- jwhois-4.0/src/lookup.c.ipv6-match 2007-12-04 17:09:57.000000000 +0100 ++++ jwhois-4.0/src/lookup.c 2007-12-04 17:10:20.000000000 +0100 +@@ -149,7 +149,7 @@ static int ipv6_address_is_in_network(co + } + /* i == bits / 8 */ + if (bits % 8 != 0 +- && (addr->s6_addr[i] & (0xFFu << (bits % 8))) != net->s6_addr[i]) ++ && (addr->s6_addr[i] & (0xFFu << 8-(bits % 8))) != net->s6_addr[i]) + return 0; + return 1; + } diff --git a/pkgs/core/kbd/kbd.nm b/pkgs/core/kbd/kbd.nm new file mode 100644 index 0000000..4c43afd --- /dev/null +++ b/pkgs/core/kbd/kbd.nm @@ -0,0 +1,69 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = kbd +PKG_VER = 1.15.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://ftp.altlinux.org/pub/people/legion/kbd +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Tools for configuring the console (keyboard, virtual terminals, etc.). + +PKG_BUILD_DEPS+= autoconf automake + +define PKG_DESCRIPTION + The kbd package contains tools for managing a Linux \ + system's console's behavior, including the keyboard, the screen \ + fonts, the virtual terminals and font files. +endef + +PKG_TARBALL = $(THISAPP).tar.gz +PKG_OBJECTS += kbd-latarcyrheb-16-fixed.tar.bz2 +PKG_OBJECTS += kbd-latsun-fonts.tar.bz2 + +CONFIGURE_OPTIONS += --datadir=/lib/kbd + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + # Adding our own fonts + cd $(DIR_APP) && $(DO_EXTRACT) $(DIR_DL)/kbd-latsun-fonts.tar.bz2 + cd $(DIR_APP) && $(DO_EXTRACT) $(DIR_DL)/kbd-latarcyrheb-16-fixed.tar.bz2 + + cd $(DIR_APP) && autoreconf --force --install + cd $(DIR_APP) && sed -i "s/ifdef OPTIONAL_PROGS/ifeq ($$(OPTIONAL_PROGS),yes)/" man/Makefile.in +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/bin + mv -v $(BUILDROOT)/usr/bin/{kbd_mode,loadkeys,openvt,setfont} $(BUILDROOT)/bin +endef diff --git a/pkgs/core/kbd/patches/kbd-1.15.1-backspace-1.patch b/pkgs/core/kbd/patches/kbd-1.15.1-backspace-1.patch new file mode 100644 index 0000000..8fec171 --- /dev/null +++ b/pkgs/core/kbd/patches/kbd-1.15.1-backspace-1.patch @@ -0,0 +1,250 @@ +Submitted By: Matt Burgess +Date: 2008-12-06 +Initial Package Version: 1.15 +Upstream Status: Not submitted, possibly incomplete +Description: Makes Backspace and Delete keys consistent in all i386 keymaps. +Makes the Backspace key send character code 127, and Delete send a well known +escape sequence. Obsoletes the /etc/kbd/bs-sends-del file for i386. + +Original patch for 1.12 by Alexander Patrakov. +Updated for 1.13 (drop ru.map, the change is upstream, and add ru_win.map, +ru-cp1251.map) by Ken Moffat <ken at linuxfromscratch dot org>. +Re-diffed against 1.15 by Matt Burgess <matthew at linuxfromscratch.org>. + +diff -Naur kbd-1.15.orig/data/keymaps/i386/dvorak/dvorak-l.map kbd-1.15/data/keymaps/i386/dvorak/dvorak-l.map +--- kbd-1.15.orig/data/keymaps/i386/dvorak/dvorak-l.map 2008-06-20 12:36:01.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/dvorak/dvorak-l.map 2008-12-03 22:27:55.000000000 +0000 +@@ -43,7 +43,7 @@ + keycode 11 = three numbersign + keycode 12 = two at + keycode 13 = one exclam +- keycode 14 = BackSpace Delete ++ keycode 14 = Delete Delete + ! -------------------------------------------------------------------------- + ! Row 3 + ! -------------------------------------------------------------------------- +diff -Naur kbd-1.15.orig/data/keymaps/i386/dvorak/dvorak-r.map kbd-1.15/data/keymaps/i386/dvorak/dvorak-r.map +--- kbd-1.15.orig/data/keymaps/i386/dvorak/dvorak-r.map 2008-06-20 12:36:01.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/dvorak/dvorak-r.map 2008-12-03 22:28:13.000000000 +0000 +@@ -43,7 +43,7 @@ + keycode 11 = slash question + keycode 12 = bracketleft braceleft + keycode 13 = bracketright braceright +- keycode 14 = BackSpace Delete ++ keycode 14 = Delete Delete + ! -------------------------------------------------------------------------- + ! Row 3 + ! -------------------------------------------------------------------------- +diff -Naur kbd-1.15.orig/data/keymaps/i386/fgGIod/tr_f-latin5.map kbd-1.15/data/keymaps/i386/fgGIod/tr_f-latin5.map +--- kbd-1.15.orig/data/keymaps/i386/fgGIod/tr_f-latin5.map 2008-10-23 20:03:58.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/fgGIod/tr_f-latin5.map 2008-12-03 22:40:32.000000000 +0000 +@@ -51,7 +51,7 @@ + alt keycode 12 = Meta_minus + keycode 13 = minus underscore + alt keycode 13 = Meta_equal +-keycode 14 = BackSpace Delete ++keycode 14 = Delete Delete + alt keycode 14 = Meta_Delete + keycode 15 = Tab Meta_Tab + alt keycode 15 = Meta_Tab +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/lt.l4.map kbd-1.15/data/keymaps/i386/qwerty/lt.l4.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/lt.l4.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/lt.l4.map 2008-12-03 22:42:14.000000000 +0000 +@@ -205,7 +205,7 @@ + # edit this if you want the key above <Enter> to delete symbols above + # cursor, not before. + keycode 14 = \ +- BackSpace BackSpace BackSpace BackSpace \ ++ Delete Delete Delete Delete \ + Delete Delete Delete Delete \ + Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace \ + Meta_Delete Meta_Delete Meta_Delete Meta_Delete +@@ -506,7 +506,7 @@ + + # Edit this if you want strict VT100 emulation. + string F111 = "\033[3$" +-keycode 111 = Delete F111 Delete F111 \ ++keycode 111 = Remove F111 Remove F111 \ + Remove Remove Remove Remove \ + Meta_Delete Meta_Delete Meta_Delete Meta_Delete \ + Boot Boot Boot Boot +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/lt.map kbd-1.15/data/keymaps/i386/qwerty/lt.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/lt.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/lt.map 2008-12-03 22:42:58.000000000 +0000 +@@ -204,7 +204,7 @@ + # edit this if you want the key above <Enter> to delete symbols above + # cursor, not before. + keycode 14 = \ +- BackSpace BackSpace BackSpace BackSpace \ ++ Delete Delete Delete Delete \ + Delete Delete Delete Delete \ + Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace \ + Meta_Delete Meta_Delete Meta_Delete Meta_Delete +@@ -505,7 +505,7 @@ + + # Edit this if you want strict VT100 emulation. + string F111 = "\033[3$" +-keycode 111 = Delete F111 Delete F111 \ ++keycode 111 = Remove F111 Remove F111 \ + Remove Remove Remove Remove \ + Meta_Delete Meta_Delete Meta_Delete Meta_Delete \ + Boot Boot Boot Boot +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/no-latin1.map kbd-1.15/data/keymaps/i386/qwerty/no-latin1.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/no-latin1.map 2008-06-20 12:36:00.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/no-latin1.map 2008-12-03 22:44:25.000000000 +0000 +@@ -3,7 +3,7 @@ + # Send comments to Kjetil T. Homme <kjetilho@ifi.uio.no> + include "linux-with-alt-and-altgr" + plain keycode 83 = KP_Comma +- plain keycode 111 = Delete # "Remove" originally, weird... ++ plain keycode 111 = Remove + strings as usual + + keycode 1 = Escape +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/ru1.map kbd-1.15/data/keymaps/i386/qwerty/ru1.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/ru1.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/ru1.map 2008-12-03 22:45:32.000000000 +0000 +@@ -143,8 +143,8 @@ + + # The keycode "0xFF" is too dangerous for many programs (including emacs). + # So let it be bracket instead of Hard Sign. +-# altgr keycode 27 = +0xDF +-# altgr shift keycode 27 = +0xFF ++altgr keycode 27 = +0xDF ++altgr shift keycode 27 = +0xFF + control keycode 27 = Control_bracketright + altgr control keycode 27 = Control_bracketright + alt keycode 27 = Meta_bracketright +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/ru2.map kbd-1.15/data/keymaps/i386/qwerty/ru2.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/ru2.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/ru2.map 2008-12-03 22:46:15.000000000 +0000 +@@ -46,7 +46,7 @@ + alt keycode 12 = Meta_minus + keycode 13 = equal plus equal plus + alt keycode 13 = Meta_equal +- keycode 14 = BackSpace BackSpace BackSpace BackSpace ++ keycode 14 = Delete Delete Delete Delete + alt keycode 14 = Meta_Delete + keycode 15 = Tab Tab Tab Tab + alt keycode 15 = Meta_Tab +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/ru-cp1251.map kbd-1.15/data/keymaps/i386/qwerty/ru-cp1251.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/ru-cp1251.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/ru-cp1251.map 2008-12-03 22:47:12.000000000 +0000 +@@ -39,7 +39,7 @@ + alt keycode 12 = Meta_minus + keycode 13 = equal plus equal plus + alt keycode 13 = Meta_equal +- keycode 14 = BackSpace ++ keycode 14 = Delete + alt keycode 14 = Meta_Delete + keycode 15 = Tab + alt keycode 15 = Meta_Tab +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/ru-ms.map kbd-1.15/data/keymaps/i386/qwerty/ru-ms.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/ru-ms.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/ru-ms.map 2008-12-03 22:48:10.000000000 +0000 +@@ -89,8 +89,8 @@ + altgr alt keycode 13 = Meta_equal + shift alt keycode 13 = Meta_plus + altgr shift alt keycode 13 = Meta_plus +- keycode 14 = BackSpace BackSpace BackSpace BackSpace +-# keycode 14 = Delete Delete Delete Delete ++# keycode 14 = BackSpace BackSpace BackSpace BackSpace ++ keycode 14 = Delete Delete Delete Delete + alt keycode 14 = Meta_Delete + altgr alt keycode 14 = Meta_Delete + keycode 15 = Tab Tab Tab Tab +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/ru_win.map kbd-1.15/data/keymaps/i386/qwerty/ru_win.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/ru_win.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/ru_win.map 2008-12-03 22:49:17.000000000 +0000 +@@ -42,7 +42,7 @@ + alt keycode 12 = Meta_minus + keycode 13 = equal plus equal plus + alt keycode 13 = Meta_equal +- keycode 14 = BackSpace BackSpace BackSpace BackSpace ++ keycode 14 = Delete Delete Delete Delete + alt keycode 14 = Meta_Delete + keycode 15 = Tab Tab Tab Tab + alt keycode 15 = Meta_Tab +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/se-ir209.map kbd-1.15/data/keymaps/i386/qwerty/se-ir209.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/se-ir209.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/se-ir209.map 2008-12-03 22:50:18.000000000 +0000 +@@ -345,7 +345,7 @@ + keycode 109 = Next Scroll_Forward + keycode 110 = Insert + +- keycode 111 = Delete # "Remove" originally, weird... ++ keycode 111 = Remove + control alt keycode 111 = Boot + control altgr keycode 111 = Boot + +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/se-lat6.map kbd-1.15/data/keymaps/i386/qwerty/se-lat6.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/se-lat6.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/se-lat6.map 2008-12-03 22:50:44.000000000 +0000 +@@ -374,6 +374,6 @@ + keycode 109 = Next Scroll_Forward + keycode 110 = Insert + +- keycode 111 = Delete # "Remove" originally, weird... ++ keycode 111 = Remove + control alt keycode 111 = Boot + control altgr keycode 111 = Boot +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/tr_q-latin5.map kbd-1.15/data/keymaps/i386/qwerty/tr_q-latin5.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/tr_q-latin5.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/tr_q-latin5.map 2008-12-03 22:52:09.000000000 +0000 +@@ -49,7 +49,7 @@ + alt keycode 12 = Meta_minus + keycode 13 = minus underscore + alt keycode 13 = Meta_equal +-keycode 14 = BackSpace Delete ++keycode 14 = Delete Delete + alt keycode 14 = Meta_Delete + keycode 15 = Tab Meta_Tab + alt keycode 15 = Meta_Tab +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/ua.map kbd-1.15/data/keymaps/i386/qwerty/ua.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/ua.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/ua.map 2008-12-03 22:52:52.000000000 +0000 +@@ -249,7 +249,7 @@ + shift ctrll ctrlr keycode 13 = plus + alt ctrll ctrlr keycode 13 = Meta_equal + shift alt ctrll ctrlr keycode 13 = Meta_plus +-keycode 14 = BackSpace Delete ++keycode 14 = Delete Delete + control keycode 14 = BackSpace + alt keycode 14 = Meta_Delete + ctrlr keycode 14 = BackSpace +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/ua-utf.map kbd-1.15/data/keymaps/i386/qwerty/ua-utf.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/ua-utf.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/ua-utf.map 2008-12-03 22:53:36.000000000 +0000 +@@ -250,7 +250,7 @@ + shift ctrll ctrlr keycode 13 = plus + alt ctrll ctrlr keycode 13 = Meta_equal + shift alt ctrll ctrlr keycode 13 = Meta_plus +-keycode 14 = BackSpace Delete ++keycode 14 = Delete Delete + control keycode 14 = BackSpace + alt keycode 14 = Meta_Delete + ctrlr keycode 14 = BackSpace +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/ua-utf-ws.map kbd-1.15/data/keymaps/i386/qwerty/ua-utf-ws.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/ua-utf-ws.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/ua-utf-ws.map 2008-12-03 22:54:06.000000000 +0000 +@@ -260,7 +260,7 @@ + shift ctrll ctrlr keycode 13 = plus + alt ctrll ctrlr keycode 13 = Meta_equal + shift alt ctrll ctrlr keycode 13 = Meta_plus +-keycode 14 = BackSpace Delete ++keycode 14 = Delete Delete + control keycode 14 = BackSpace + alt keycode 14 = Meta_Delete + ctrlr keycode 14 = BackSpace +diff -Naur kbd-1.15.orig/data/keymaps/i386/qwerty/ua-ws.map kbd-1.15/data/keymaps/i386/qwerty/ua-ws.map +--- kbd-1.15.orig/data/keymaps/i386/qwerty/ua-ws.map 2008-10-23 20:03:59.000000000 +0100 ++++ kbd-1.15/data/keymaps/i386/qwerty/ua-ws.map 2008-12-03 22:54:23.000000000 +0000 +@@ -260,7 +260,7 @@ + shift ctrll ctrlr keycode 13 = plus + alt ctrll ctrlr keycode 13 = Meta_equal + shift alt ctrll ctrlr keycode 13 = Meta_plus +-keycode 14 = BackSpace Delete ++keycode 14 = Delete Delete + control keycode 14 = BackSpace + alt keycode 14 = Meta_Delete + ctrlr keycode 14 = BackSpace diff --git a/pkgs/core/kernel-headers/kernel-headers.nm b/pkgs/core/kernel-headers/kernel-headers.nm new file mode 100644 index 0000000..f40561a --- /dev/null +++ b/pkgs/core/kernel-headers/kernel-headers.nm @@ -0,0 +1,18 @@ + +include ../../core/kernel/kernel.nm + +PKG_BUILD_DEPS = + +STAGE_PREPARE_CMDS = + +define STAGE_BUILD + cd $(DIR_APP) && make mrproper + cd $(DIR_APP) && make ARCH=x86 headers_check +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make ARCH=x86 INSTALL_HDR_PATH=dest headers_install + -mkdir -pv $(BUILDROOT)/usr/include + cd $(DIR_APP) && find dest/include ( -name .install -o -name ..install.cmd ) -delete + cd $(DIR_APP) && cp -rv dest/include/* $(BUILDROOT)/usr/include +endef diff --git a/pkgs/core/kernel-headers/patches b/pkgs/core/kernel-headers/patches new file mode 120000 index 0000000..fa2c707 --- /dev/null +++ b/pkgs/core/kernel-headers/patches @@ -0,0 +1 @@ +../kernel/patches \ No newline at end of file diff --git a/pkgs/core/kernel/config b/pkgs/core/kernel/config new file mode 100644 index 0000000..f6ed5b5 --- /dev/null +++ b/pkgs/core/kernel/config @@ -0,0 +1,3555 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31 +# Wed Sep 16 12:05:54 2009 +# +# CONFIG_64BIT is not set +CONFIG_X86_32=y +# CONFIG_X86_64 is not set +CONFIG_X86=y +CONFIG_OUTPUT_FORMAT="elf32-i386" +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_FAST_CMPXCHG_LOCAL=y +CONFIG_MMU=y +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_GPIO=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y +# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_ZONE_DMA32 is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y +# CONFIG_AUDIT_ARCH is not set +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_X86_32_SMP=y +CONFIG_X86_HT=y +CONFIG_X86_TRAMPOLINE=y +CONFIG_KTIME_SCALAR=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_IKCONFIG=y +# CONFIG_IKCONFIG_PROC is not set +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +CONFIG_RELAY=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_COUNTERS=y + +# +# Performance Counters +# +CONFIG_PERF_COUNTERS=y +CONFIG_EVENT_PROFILE=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_SLUB_DEBUG=y +CONFIG_STRIP_ASM_SYMS=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y +CONFIG_OPROFILE=y +CONFIG_OPROFILE_IBS=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_SLOW_WORK=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +# CONFIG_SLABINFO is not set +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_PREEMPT_NOTIFIERS=y +# CONFIG_FREEZER is not set + +# +# Processor type and features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SMP=y +CONFIG_SPARSE_IRQ=y +CONFIG_X86_MPPARSE=y +# CONFIG_X86_BIGSMP is not set +CONFIG_X86_EXTENDED_PLATFORM=y +# CONFIG_X86_ELAN is not set +# CONFIG_X86_RDC321X is not set +# CONFIG_X86_32_NON_STANDARD is not set +CONFIG_SCHED_OMIT_FRAME_POINTER=y +# CONFIG_PARAVIRT_GUEST is not set +# CONFIG_MEMTEST is not set +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +CONFIG_M686=y +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MEFFICEON is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MPSC is not set +# CONFIG_MCORE2 is not set +# CONFIG_GENERIC_CPU is not set +CONFIG_X86_GENERIC=y +CONFIG_X86_CPU=y +CONFIG_X86_L1_CACHE_BYTES=64 +CONFIG_X86_INTERNODE_CACHE_BYTES=64 +CONFIG_X86_CMPXCHG=y +CONFIG_X86_L1_CACHE_SHIFT=5 +CONFIG_X86_XADD=y +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_INVLPG=y +CONFIG_X86_BSWAP=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_TSC=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=4 +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_CYRIX_32=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR=y +CONFIG_CPU_SUP_TRANSMETA_32=y +CONFIG_CPU_SUP_UMC_32=y +# CONFIG_X86_DS is not set +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_DMI=y +# CONFIG_IOMMU_HELPER is not set +CONFIG_IOMMU_API=y +CONFIG_NR_CPUS=8 +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set +CONFIG_X86_MCE=y +# CONFIG_X86_OLD_MCE is not set +CONFIG_X86_NEW_MCE=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y +# CONFIG_X86_ANCIENT_MCE is not set +CONFIG_X86_MCE_THRESHOLD=y +CONFIG_X86_MCE_INJECT=m +CONFIG_X86_THERMAL_VECTOR=y +CONFIG_VM86=y +# CONFIG_TOSHIBA is not set +# CONFIG_I8K is not set +# CONFIG_X86_REBOOTFIXUPS is not set +CONFIG_MICROCODE=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_X86_MSR=y +CONFIG_X86_CPUID=y +# CONFIG_X86_CPU_DEBUG is not set +CONFIG_NOHIGHMEM=y +# CONFIG_HIGHMEM4G is not set +# CONFIG_HIGHMEM64G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_X86_PAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_MMU_NOTIFIER=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_RESERVE_LOW_64K=y +# CONFIG_MATH_EMULATION is not set +CONFIG_MTRR=y +# CONFIG_MTRR_SANITIZER is not set +CONFIG_X86_PAT=y +CONFIG_SECCOMP=y +CONFIG_CC_STACKPROTECTOR_ALL=y +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +# CONFIG_KEXEC is not set +CONFIG_PHYSICAL_START=0x1000000 +# CONFIG_RELOCATABLE is not set +CONFIG_PHYSICAL_ALIGN=0x100000 +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Power management and ACPI options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_SUSPEND is not set +# CONFIG_HIBERNATION is not set +CONFIG_ACPI=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_BLACKLIST_YEAR=2001 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_PCI_SLOT=y +CONFIG_X86_PM_TIMER=y +# CONFIG_ACPI_CONTAINER is not set +# CONFIG_ACPI_SBS is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m + +# +# CPUFreq processor drivers +# +CONFIG_X86_ACPI_CPUFREQ=m +CONFIG_X86_POWERNOW_K6=m +CONFIG_X86_POWERNOW_K7=m +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=m +CONFIG_X86_GX_SUSPMOD=m +CONFIG_X86_SPEEDSTEP_CENTRINO=m +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y +CONFIG_X86_SPEEDSTEP_ICH=m +CONFIG_X86_SPEEDSTEP_SMI=m +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_LONGRUN=m +CONFIG_X86_LONGHAUL=m +CONFIG_X86_E_POWERSAVER=m + +# +# shared options +# +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Bus options (PCI etc.) +# +CONFIG_PCI=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GOMMCONFIG is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOOLPC is not set +CONFIG_PCI_GOANY=y +CONFIG_PCI_BIOS=y +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_OLPC=y +CONFIG_PCI_DOMAINS=y +CONFIG_DMAR=y +CONFIG_DMAR_DEFAULT_ON=y +# CONFIG_DMAR_BROKEN_GFX_WA is not set +CONFIG_DMAR_FLOPPY_WA=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIEAER=y +# CONFIG_PCIE_ECRC is not set +# CONFIG_PCIEAER_INJECT is not set +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEBUG is not set +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_LEGACY=y +CONFIG_PCI_STUB=m +CONFIG_HT_IRQ=y +CONFIG_PCI_IOV=y +CONFIG_ISA_DMA_API=y +# CONFIG_ISA is not set +# CONFIG_MCA is not set +# CONFIG_SCx200 is not set +CONFIG_OLPC=y +CONFIG_K8_NB=y +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m +CONFIG_I82092=m +CONFIG_PCCARD_NONSTATIC=m +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats / Emulations +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_HAVE_ATOMIC_IOMAP=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_MIGRATE=y +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_PIMSM_V2=y +# CONFIG_NETLABEL is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_CONNTRACK_IPV6=m +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +# CONFIG_IP6_NF_SECURITY is not set +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +# CONFIG_BRIDGE_EBT_ULOG is not set +CONFIG_BRIDGE_EBT_NFLOG=m +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +# CONFIG_ATM_LANE is not set +CONFIG_ATM_BR2684=m +CONFIG_ATM_BR2684_IPFILTER=y +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +CONFIG_NET_DSA=y +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_DSA_TAG_TRAILER=y +CONFIG_NET_DSA_MV88E6XXX=y +CONFIG_NET_DSA_MV88E6060=y +CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y +CONFIG_NET_DSA_MV88E6131=y +CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +# CONFIG_NET_SCH_INGRESS is not set + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +CONFIG_DCB=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NET_DROP_MONITOR=y +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_CFG80211=m +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_WIRELESS_OLD_REGULATORY is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_DEFAULT_PS=y +CONFIG_MAC80211_DEFAULT_PS_VALUE=1 + +# +# Rate control algorithm selection +# +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=m +# CONFIG_MTD is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_SUPERIO=y +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_AX88796 is not set +CONFIG_PARPORT_1284=y +CONFIG_PNP=y +# CONFIG_PNP_DEBUG_MESSAGES is not set + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_FD=m +# CONFIG_PARIDE is not set +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +# CONFIG_CISS_SCSI_TAPE is not set +CONFIG_BLK_DEV_DAC960=m +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_OSD=m +CONFIG_BLK_DEV_SX8=m +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_VIRTIO_BLK=m +CONFIG_BLK_DEV_HD=y +CONFIG_MISC_DEVICES=y +# CONFIG_IBM_ASM is not set +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +CONFIG_ICS932S401=m +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HP_ILO=m +CONFIG_ISL29003=m +CONFIG_C2PORT=m +# CONFIG_C2PORT_DURAMAR_2150 is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +# CONFIG_EEPROM_LEGACY is not set +CONFIG_EEPROM_MAX6875=m +CONFIG_EEPROM_93CX6=m +CONFIG_CB710_CORE=m +# CONFIG_CB710_DEBUG is not set +CONFIG_CB710_DEBUG_ASSUMPTIONS=y +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +# CONFIG_SCSI_FC_TGT_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS_DEBUG=y +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_SCSI_BNX2_ISCSI=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=32 +CONFIG_AIC7XXX_RESET_DELAY_MS=5000 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_RESET_DELAY_MS=4000 +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_SCSI_MVSAS=m +# CONFIG_SCSI_MVSAS_DEBUG is not set +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_ARCMSR=m +# CONFIG_SCSI_ARCMSR_AER is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_MPT2SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +# CONFIG_SCSI_MPT2SAS_LOGGING is not set +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_FLASHPOINT=y +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +CONFIG_FCOE=m +CONFIG_FCOE_FNIC=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_IMM=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_IPR=m +CONFIG_SCSI_IPR_TRACE=y +CONFIG_SCSI_IPR_DUMP=y +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_LPFC_DEBUG_FS is not set +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_NSP32=m +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_SCSI_DH=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_SCSI_OSD_DPRINT_SENSE=1 +# CONFIG_SCSI_OSD_DEBUG is not set +CONFIG_ATA=m +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_ACPI=y +CONFIG_SATA_PMP=y +CONFIG_SATA_AHCI=m +CONFIG_SATA_SIL24=m +CONFIG_ATA_SFF=y +CONFIG_SATA_SVW=m +CONFIG_ATA_PIIX=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_SX4=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIS=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m +CONFIG_SATA_INIC162X=m +CONFIG_PATA_ACPI=m +CONFIG_PATA_ALI=m +CONFIG_PATA_AMD=m +CONFIG_PATA_ARTOP=m +CONFIG_PATA_ATIIXP=m +CONFIG_PATA_CMD640_PCI=m +CONFIG_PATA_CMD64X=m +CONFIG_PATA_CS5520=m +CONFIG_PATA_CS5530=m +CONFIG_PATA_CS5535=m +CONFIG_PATA_CS5536=m +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=m +CONFIG_ATA_GENERIC=m +CONFIG_PATA_HPT366=m +CONFIG_PATA_HPT37X=m +CONFIG_PATA_HPT3X2N=m +CONFIG_PATA_HPT3X3=m +CONFIG_PATA_HPT3X3_DMA=y +CONFIG_PATA_IT821X=m +CONFIG_PATA_IT8213=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_NINJA32=m +CONFIG_PATA_NS87410=m +CONFIG_PATA_NS87415=m +CONFIG_PATA_OPTI=m +CONFIG_PATA_OPTIDMA=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC_OLD=m +CONFIG_PATA_RADISYS=m +CONFIG_PATA_RZ1000=m +CONFIG_PATA_SC1200=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m +CONFIG_PATA_SCH=m +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID6_PQ=m +CONFIG_MD_MULTIPATH=m +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_DELAY=m +CONFIG_DM_UEVENT=y +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +# CONFIG_FUSION_FC is not set +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_CTL=m +# CONFIG_FUSION_LOGGING is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# You can enable one or both FireWire driver stacks. +# + +# +# See the help texts for more information. +# +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_OHCI_DEBUG=y +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIREWIRE_NET=m +# CONFIG_IEEE1394 is not set +CONFIG_I2O=m +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_BUS=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +CONFIG_IFB=m +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_MACVLAN=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_VETH is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_REALTEK_PHY=m +CONFIG_NATIONAL_PHY=m +CONFIG_STE10XP=m +CONFIG_LSI_ET1011C_PHY=m +# CONFIG_FIXED_PHY is not set +CONFIG_MDIO_BITBANG=m +CONFIG_MDIO_GPIO=m +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_CASSINI=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +CONFIG_ETHOC=m +CONFIG_DNET=m +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_DE2104X_DSL=0 +CONFIG_TULIP=m +CONFIG_TULIP_MWI=y +CONFIG_TULIP_MMIO=y +CONFIG_TULIP_NAPI=y +CONFIG_TULIP_NAPI_HW_MITIGATION=y +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_ULI526X=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_HP100=m +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=m +CONFIG_AMD8111_ETH=m +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +CONFIG_FORCEDETH=m +CONFIG_FORCEDETH_NAPI=y +CONFIG_E100=m +CONFIG_FEALNX=m +CONFIG_NATSEMI=m +CONFIG_NE2K_PCI=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +CONFIG_8139TOO_TUNE_TWISTER=y +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_R6040=m +CONFIG_SIS900=m +CONFIG_EPIC100=m +CONFIG_SMSC9420=m +CONFIG_SUNDANCE=m +CONFIG_SUNDANCE_MMIO=y +CONFIG_TLAN=m +CONFIG_KS8842=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_SC92031=m +# CONFIG_NET_POCKET is not set +CONFIG_ATL2=m +CONFIG_NETDEV_1000=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_IP1000=m +CONFIG_IGB=m +CONFIG_IGB_DCA=y +CONFIG_IGBVF=m +CONFIG_NS83820=m +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +CONFIG_R8169=m +CONFIG_R8169_VLAN=y +CONFIG_SIS190=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_VIA_VELOCITY=m +CONFIG_TIGON3=m +CONFIG_BNX2=m +CONFIG_CNIC=m +CONFIG_QLA3XXX=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL1C=m +CONFIG_JME=m +CONFIG_NETDEV_10000=y +CONFIG_MDIO=m +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3_DEPENDS=y +CONFIG_CHELSIO_T3=m +CONFIG_ENIC=m +CONFIG_IXGBE=m +CONFIG_IXGBE_DCA=y +CONFIG_IXGBE_DCB=y +CONFIG_IXGB=m +CONFIG_S2IO=m +CONFIG_VXGE=m +# CONFIG_VXGE_DEBUG_TRACE_ALL is not set +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +CONFIG_NETXEN_NIC=m +CONFIG_NIU=m +CONFIG_MLX4_EN=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_TEHUTI=m +CONFIG_BNX2X=m +CONFIG_QLGE=m +CONFIG_SFC=m +CONFIG_BE2NET=m +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +CONFIG_WLAN_80211=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_AIRO=m +CONFIG_ATMEL=m +CONFIG_PCI_ATMEL=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_AT76C50X_USB=m +CONFIG_AIRO_CS=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PRISM54=m +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +CONFIG_ADM8211=m +CONFIG_MAC80211_HWSIM=m +CONFIG_MWL8K=m +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_PCI=m +CONFIG_P54_LEDS=y +CONFIG_ATH_COMMON=m +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +CONFIG_ATH9K=m +# CONFIG_ATH9K_DEBUG is not set +CONFIG_AR9170_USB=m +CONFIG_AR9170_LEDS=y +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBIPW=m +# CONFIG_LIBIPW_DEBUG is not set +CONFIG_IWLWIFI=m +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y +# CONFIG_IWLWIFI_DEBUG is not set +CONFIG_IWLAGN=m +CONFIG_IWL4965=y +CONFIG_IWL5000=y +CONFIG_IWL3945=m +CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_CS=m +CONFIG_B43=m +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCMCIA=y +CONFIG_B43_PIO=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_HWRNG=y +# CONFIG_B43LEGACY_DEBUG is not set +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_RT2X00=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_HT=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_HERMES=m +CONFIG_HERMES_CACHE_FW_ON_INIT=y +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_NORTEL_HERMES=m +CONFIG_PCI_HERMES=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_SPECTRUM=m + +# +# WiMAX Wireless Broadband devices +# + +# +# Enable MMC support to see WiMAX SDIO drivers +# +# CONFIG_WIMAX_I2400M_USB is not set + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_WAN is not set +CONFIG_ATM_DRIVERS=y +CONFIG_ATM_DUMMY=m +CONFIG_ATM_TCP=m +CONFIG_ATM_LANAI=m +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_FORE200E=m +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_FORE200E_TX_RETRY=16 +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_HE=m +# CONFIG_ATM_HE_USE_SUNI is not set +CONFIG_ATM_SOLOS=m +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +CONFIG_PPPOL2TP=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLHC=m +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y +# CONFIG_NET_FC is not set +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_VIRTIO_NET=m +CONFIG_ISDN=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_L1OIP=m + +# +# mISDN hardware drivers +# +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_MISDN_HFCUSB=m +# CONFIG_ISDN_I4L is not set +# CONFIG_ISDN_CAPI is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_POLLDEV=m + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_MATRIX=m +CONFIG_KEYBOARD_LM8323=m +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_NOZOMI=m + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +# CONFIG_SERIAL_8250_CS is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=m +CONFIG_HVC_DRIVER=y +CONFIG_VIRTIO_CONSOLE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=m +CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_NVRAM=m +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +CONFIG_IPWIRELESS=m +# CONFIG_MWAVE is not set +# CONFIG_PC8736x_GPIO is not set +# CONFIG_NSC_GPIO is not set +# CONFIG_CS5535_GPIO is not set +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_HPET=y +CONFIG_HPET_MMAP=y +# CONFIG_HANGCHECK_TIMER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set +CONFIG_DEVPORT=y +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_GPIO=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_SIMTEC=m + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m + +# +# Graphics adapter I2C/DDC channel drivers +# +CONFIG_I2C_VOODOO3=m + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_STUB=m +CONFIG_SCx200_ACB=m + +# +# Miscellaneous I2C Chip support +# +CONFIG_DS1682=m +CONFIG_SENSORS_TSL2550=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCF857X=m + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_GPIO=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2433_CRC=y +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +CONFIG_WM8350_POWER=m +CONFIG_BATTERY_DS2760=m +CONFIG_BATTERY_DS2782=m +CONFIG_BATTERY_OLPC=m +CONFIG_BATTERY_BQ27x00=m +CONFIG_BATTERY_MAX17040=m +CONFIG_CHARGER_PCF50633=m +CONFIG_HWMON=m +CONFIG_HWMON_VID=m +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7473=m +CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATK0110=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_LIS3LV02D=m +CONFIG_SENSORS_APPLESMC=m +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_WM8350_WATCHDOG=m +CONFIG_ACQUIRE_WDT=m +CONFIG_ADVANTECH_WDT=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_SC520_WDT=m +CONFIG_EUROTECH_WDT=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_WAFER_WDT=m +CONFIG_I6300ESB_WDT=m +CONFIG_ITCO_WDT=m +# CONFIG_ITCO_VENDOR_SUPPORT is not set +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_HP_WATCHDOG=m +CONFIG_SC1200_WDT=m +CONFIG_PC87413_WDT=m +CONFIG_60XX_WDT=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC7240_WDT=m +CONFIG_CPU5_WDT=m +CONFIG_SMSC_SCH311X_WDT=m +CONFIG_SMSC37B787_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83697UG_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_MACHZ_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_PCMCIAHOST=y +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=m +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +CONFIG_TPS65010=m +# CONFIG_MFD_TMIO is not set +CONFIG_MFD_WM8400=m +CONFIG_MFD_WM8350=m +CONFIG_MFD_WM8350_I2C=m +CONFIG_MFD_PCF50633=m +CONFIG_PCF50633_ADC=m +CONFIG_PCF50633_GPIO=m +CONFIG_AB3100_CORE=m +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_USERSPACE_CONSUMER=m +CONFIG_REGULATOR_BQ24022=m +CONFIG_REGULATOR_MAX1586=m +CONFIG_REGULATOR_WM8350=m +CONFIG_REGULATOR_WM8400=m +CONFIG_REGULATOR_PCF50633=m +CONFIG_REGULATOR_LP3971=m +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_COMMON=m +# CONFIG_VIDEO_ALLOW_V4L1 is not set +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_MPEG=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_FB_IVTV=m +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9T031=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_TW9910=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOC_CAMERA_OV772X=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SN9C20X_EVDEV=y +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +# CONFIG_VIDEO_PVRUSB2 is not set +CONFIG_VIDEO_HDPVR=m +# CONFIG_VIDEO_EM28XX is not set +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_ZC0301 is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +CONFIG_USB_S2255=m +CONFIG_RADIO_ADAPTERS=y +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_SI470X is not set +# CONFIG_USB_MR800 is not set +# CONFIG_RADIO_TEA5764 is not set +CONFIG_DVB_DYNAMIC_MINORS=y +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported SAA7146 based PCI Adapters +# +CONFIG_TTPCI_EEPROM=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_SMS_SIANO_MDTV=m + +# +# Siano module components +# +CONFIG_SMS_USB_DRV=m + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set + +# +# Supported BT878 Adapters +# +CONFIG_DVB_BT8XX=m + +# +# Supported Pluto2 Adapters +# +CONFIG_DVB_PLUTO2=m + +# +# Supported SDMC DM1105 Adapters +# +CONFIG_DVB_DM1105=m + +# +# Supported DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DAB=y +CONFIG_USB_DABUSB=m + +# +# Graphics support +# +CONFIG_AGP=m +CONFIG_AGP_ALI=m +CONFIG_AGP_ATI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_INTEL=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AGP_EFFICEON=m +# CONFIG_DRM is not set +CONFIG_VGASTATE=m +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DDC=m +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_FOREIGN_ENDIAN=y +CONFIG_FB_BOTH_ENDIAN=y +# CONFIG_FB_BIG_ENDIAN is not set +# CONFIG_FB_LITTLE_ENDIAN is not set +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_HECUBA=m +CONFIG_FB_SVGALIB=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +CONFIG_FB_CIRRUS=m +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_CYBER2000=m +CONFIG_FB_ARC=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_IMSTT=y +CONFIG_FB_VGA16=m +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=y +CONFIG_FB_N411=m +CONFIG_FB_HGA=m +CONFIG_FB_HGA_ACCEL=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_I2C=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_BACKLIGHT=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_I2C=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_BACKLIGHT=y +CONFIG_FB_I810=m +CONFIG_FB_I810_GTF=y +CONFIG_FB_I810_I2C=y +CONFIG_FB_LE80578=m +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_VIA=m +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_KYRO=m +CONFIG_FB_3DFX=m +CONFIG_FB_3DFX_ACCEL=y +CONFIG_FB_3DFX_I2C=y +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FB_TRIDENT=m +CONFIG_FB_ARK=m +CONFIG_FB_PM3=m +CONFIG_FB_CARMINE=m +CONFIG_FB_CARMINE_DRAM_EVAL=y +# CONFIG_CARMINE_DRAM_CUSTOM is not set +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_LX=m +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +CONFIG_FB_TMIO=m +CONFIG_FB_TMIO_ACCELL=y +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_METRONOME=m +CONFIG_FB_MB862XX=m +CONFIG_FB_MB862XX_PCI_GDC=y +CONFIG_FB_BROADSHEET=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_ILI9320 is not set +CONFIG_LCD_PLATFORM=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=m +# CONFIG_BACKLIGHT_PROGEAR is not set +# CONFIG_BACKLIGHT_CARILLO_RANCH is not set +CONFIG_BACKLIGHT_MBP_NVIDIA=m +CONFIG_BACKLIGHT_SAHARA=m + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_VGACON_SOFT_SCROLLBACK=y +CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128 +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_RAWMIDI_SEQ=m +CONFIG_SND_OPL3_LIB_SEQ=m +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +CONFIG_SND_EMU10K1_SEQ=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +# CONFIG_SND_PCSP is not set +CONFIG_SND_DUMMY=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_SB_COMMON=m +CONFIG_SND_SB16_DSP=m +CONFIG_SND_PCI=y +CONFIG_SND_AD1889=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AW2=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +CONFIG_SND_BT87X_OVERCLOCK=y +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_OXYGEN=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5530=m +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_CTXFI=m +CONFIG_SND_DARLA20=m +CONFIG_SND_GINA20=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_GINA24=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MONA=m +CONFIG_SND_MIA=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIOX=m +CONFIG_SND_INDIGODJX=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_RECONFIG=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INPUT_JACK=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_INTELHDMI=y +CONFIG_SND_HDA_ELD=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_CA0110=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_GENERIC=y +# CONFIG_SND_HDA_POWER_SAVE is not set +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HIFIER=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_LX6464ES=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SIS7019=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRTUOSO=m +CONFIG_SND_VX222=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_USB_CAIAQ=m +# CONFIG_SND_USB_CAIAQ_INPUT is not set +CONFIG_SND_USB_US122L=m +CONFIG_SND_PCMCIA=y +CONFIG_SND_VXPOCKET=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_SOC=m +CONFIG_SND_SOC_I2C_AND_SPI=m +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_SND_SOC_AD73311=m +CONFIG_SND_SOC_AK4535=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_L3=m +CONFIG_SND_SOC_PCM3008=m +CONFIG_SND_SOC_SPDIF=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_UDA134X=m +CONFIG_SND_SOC_UDA1380=m +CONFIG_SND_SOC_WM8350=m +CONFIG_SND_SOC_WM8400=m +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8728=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8900=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8940=m +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8971=m +CONFIG_SND_SOC_WM8988=m +CONFIG_SND_SOC_WM8990=m +CONFIG_SND_SOC_WM9081=m +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=m +# CONFIG_HID_DEBUG is not set +CONFIG_HIDRAW=y + +# +# USB Input Devices +# +CONFIG_USB_HID=m +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DRAGONRISE=m +# CONFIG_DRAGONRISE_FF is not set +CONFIG_HID_EZKEY=m +CONFIG_HID_KYE=m +CONFIG_HID_GYRATION=m +CONFIG_HID_KENSINGTON=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_NTRIG=m +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=m +# CONFIG_SMARTJOYPLUS_FF is not set +CONFIG_HID_TOPSEED=m +CONFIG_HID_THRUSTMASTER=m +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_HID_ZEROPLUS=m +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DYNAMIC_MINORS=y +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_MON is not set +CONFIG_USB_WUSB=m +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_C67X00_HCD=m +CONFIG_USB_XHCI_HCD=m +# CONFIG_USB_XHCI_HCD_DEBUGGING is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_OXU210HP_HCD=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_ISP1760_HCD=m +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD_SSB=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_CS=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_WHCI_HCD=m +CONFIG_USB_HWA_HCD=m + +# +# Enable Host or Gadget support to see Inventra options +# + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_LIBUSUAL=y + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +CONFIG_USB_SEVSEG=m +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_ATM is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_NOP_USB_XCEIV=m +CONFIG_UWB=m +CONFIG_UWB_HWA=m +CONFIG_UWB_WHCI=m +CONFIG_UWB_WLP=m +CONFIG_UWB_I1480U=m +CONFIG_UWB_I1480U_WLP=m +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# +CONFIG_LEDS_ALIX2=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_GPIO=m +CONFIG_LEDS_GPIO_PLATFORM=y +CONFIG_LEDS_LP3944=m +# CONFIG_LEDS_CLEVO_MAIL is not set +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_WM8350=m +CONFIG_LEDS_BD2802=m + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_GPIO=m +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=m +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_S35390A=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RX8025=m + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=m +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1511=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_WM8350=m +CONFIG_RTC_DRV_PCF50633=m + +# +# on-CPU RTC drivers +# +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_INTEL_IOATDMA=m +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +CONFIG_DCA=m +# CONFIG_AUXDISPLAY is not set +CONFIG_UIO=m +# CONFIG_UIO_CIF is not set +# CONFIG_UIO_PDRV is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_SMX is not set +# CONFIG_UIO_AEC is not set +# CONFIG_UIO_SERCOS3 is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set +CONFIG_X86_PLATFORM_DEVICES=y +# CONFIG_ACER_WMI is not set +CONFIG_ASUS_LAPTOP=m +CONFIG_DELL_WMI=m +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +CONFIG_TC1100_WMI=m +# CONFIG_HP_WMI is not set +CONFIG_MSI_LAPTOP=m +CONFIG_PANASONIC_LAPTOP=m +CONFIG_COMPAL_LAPTOP=m +CONFIG_SONY_LAPTOP=m +CONFIG_SONYPI_COMPAT=y +CONFIG_THINKPAD_ACPI=m +# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set +# CONFIG_THINKPAD_ACPI_DEBUG is not set +# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_INTEL_MENLOW=m +CONFIG_ACPI_WMI=m +CONFIG_ACPI_ASUS=m +CONFIG_ACPI_TOSHIBA=m + +# +# Firmware Drivers +# +# CONFIG_EDD is not set +CONFIG_FIRMWARE_MEMMAP=y +# CONFIG_DELL_RBU is not set +# CONFIG_DCDBAS is not set +CONFIG_DMIID=y +# CONFIG_ISCSI_IBFT_FIND is not set + +# +# File systems +# +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y +CONFIG_EXT3_FS=m +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=m +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_FS_XIP=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=m +CONFIG_REISER4_FS=m +# CONFIG_REISER4_DEBUG is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_GENERIC_ACL=y + +# +# Caches +# +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +CONFIG_FSCACHE_HISTOGRAM=y +# CONFIG_FSCACHE_DEBUG is not set +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +CONFIG_CACHEFILES_HISTOGRAM=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_EXOFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_AUFS_FS=m +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_511 is not set +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_HINOTIFY is not set +CONFIG_AUFS_EXPORT=y +# CONFIG_AUFS_RDU is not set +# CONFIG_AUFS_SHWH is not set +# CONFIG_AUFS_BR_RAMFS is not set +# CONFIG_AUFS_BR_FUSE is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_BDEV_LOOP=y +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +# CONFIG_NFS_V4 is not set +CONFIG_NFS_FSCACHE=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +# CONFIG_NFSD_V4 is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +# CONFIG_CIFS_WEAK_PW_HASH is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=y +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_STACKTRACE=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_ARCH_WANT_FRAME_POINTERS=y +# CONFIG_FRAME_POINTER is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FTRACE_SYSCALLS=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_KMEMCHECK=y +CONFIG_STRICT_DEVMEM=y +CONFIG_X86_VERBOSE_BOOTUP=y +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +CONFIG_4KSTACKS=y +CONFIG_DOUBLEFAULT=y +# CONFIG_IOMMU_STRESS is not set +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=0 +CONFIG_OPTIMIZE_INLINING=y + +# +# Security options +# + +# +# Grsecurity +# +CONFIG_GRKERNSEC=y +# CONFIG_GRKERNSEC_LOW is not set +# CONFIG_GRKERNSEC_MEDIUM is not set +# CONFIG_GRKERNSEC_HIGH is not set +CONFIG_GRKERNSEC_CUSTOM=y + +# +# Address Space Protection +# +# CONFIG_GRKERNSEC_KMEM is not set +# CONFIG_GRKERNSEC_IO is not set +CONFIG_GRKERNSEC_PROC_MEMMAP=y +CONFIG_GRKERNSEC_BRUTE=y +CONFIG_GRKERNSEC_MODHARDEN=y +CONFIG_GRKERNSEC_HIDESYM=y + +# +# Role Based Access Control Options +# +CONFIG_GRKERNSEC_NO_RBAC=y +# CONFIG_GRKERNSEC_ACL_HIDEKERN is not set +CONFIG_GRKERNSEC_ACL_MAXTRIES=3 +CONFIG_GRKERNSEC_ACL_TIMEOUT=30 + +# +# Filesystem Protections +# +# CONFIG_GRKERNSEC_PROC is not set +CONFIG_GRKERNSEC_LINK=y +CONFIG_GRKERNSEC_FIFO=y +CONFIG_GRKERNSEC_CHROOT=y +CONFIG_GRKERNSEC_CHROOT_MOUNT=y +CONFIG_GRKERNSEC_CHROOT_DOUBLE=y +CONFIG_GRKERNSEC_CHROOT_PIVOT=y +CONFIG_GRKERNSEC_CHROOT_CHDIR=y +CONFIG_GRKERNSEC_CHROOT_CHMOD=y +CONFIG_GRKERNSEC_CHROOT_FCHDIR=y +CONFIG_GRKERNSEC_CHROOT_MKNOD=y +CONFIG_GRKERNSEC_CHROOT_SHMAT=y +CONFIG_GRKERNSEC_CHROOT_UNIX=y +CONFIG_GRKERNSEC_CHROOT_FINDTASK=y +CONFIG_GRKERNSEC_CHROOT_NICE=y +CONFIG_GRKERNSEC_CHROOT_SYSCTL=y +CONFIG_GRKERNSEC_CHROOT_CAPS=y + +# +# Kernel Auditing +# +# CONFIG_GRKERNSEC_AUDIT_GROUP is not set +# CONFIG_GRKERNSEC_EXECLOG is not set +CONFIG_GRKERNSEC_RESLOG=y +CONFIG_GRKERNSEC_CHROOT_EXECLOG=y +# CONFIG_GRKERNSEC_AUDIT_CHDIR is not set +CONFIG_GRKERNSEC_AUDIT_MOUNT=y +CONFIG_GRKERNSEC_AUDIT_IPC=y +CONFIG_GRKERNSEC_SIGNAL=y +CONFIG_GRKERNSEC_FORKFAIL=y +CONFIG_GRKERNSEC_TIME=y +CONFIG_GRKERNSEC_PROC_IPADDR=y +# CONFIG_GRKERNSEC_AUDIT_TEXTREL is not set + +# +# Executable Protections +# +CONFIG_GRKERNSEC_EXECVE=y +CONFIG_GRKERNSEC_DMESG=y +CONFIG_GRKERNSEC_HARDEN_PTRACE=y +# CONFIG_GRKERNSEC_TPE is not set + +# +# Network Protections +# +CONFIG_GRKERNSEC_RANDNET=y +CONFIG_GRKERNSEC_BLACKHOLE=y +# CONFIG_GRKERNSEC_SOCKET is not set + +# +# Sysctl support +# +CONFIG_GRKERNSEC_SYSCTL=y +CONFIG_GRKERNSEC_SYSCTL_ON=y + +# +# Logging Options +# +CONFIG_GRKERNSEC_FLOODTIME=10 +CONFIG_GRKERNSEC_FLOODBURST=4 + +# +# PaX +# +CONFIG_PAX=y + +# +# PaX Control +# +# CONFIG_PAX_SOFTMODE is not set +CONFIG_PAX_EI_PAX=y +CONFIG_PAX_PT_PAX_FLAGS=y +# CONFIG_PAX_NO_ACL_FLAGS is not set +CONFIG_PAX_HAVE_ACL_FLAGS=y +# CONFIG_PAX_HOOK_ACL_FLAGS is not set + +# +# Non-executable pages +# +CONFIG_PAX_NOEXEC=y +# CONFIG_PAX_PAGEEXEC is not set +CONFIG_PAX_SEGMEXEC=y +CONFIG_PAX_EMUTRAMP=y +CONFIG_PAX_MPROTECT=y +CONFIG_PAX_NOELFRELOCS=y +CONFIG_PAX_KERNEXEC=y + +# +# Address Space Layout Randomization +# +CONFIG_PAX_ASLR=y +CONFIG_PAX_RANDKSTACK=y +CONFIG_PAX_RANDUSTACK=y +CONFIG_PAX_RANDMMAP=y + +# +# Miscellaneous hardening features +# +CONFIG_PAX_MEMORY_SANITIZE=y +# CONFIG_PAX_MEMORY_UDEREF is not set +CONFIG_PAX_REFCOUNT=y +CONFIG_PAX_USERCOPY=y +# CONFIG_KEYS is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +# CONFIG_SECURITY_PATH is not set +CONFIG_SECURITY_FILE_CAPABILITIES=y +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_IMA is not set +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_GF128MUL=m +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CTR=m +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=m +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRC32C_INTEL=m +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=m +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SALSA20_586 is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_SERPENT=m +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH_586=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ZLIB=m +CONFIG_CRYPTO_LZO=m + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_CRYPTO_DEV_HIFN_795X=m +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_KVM_IRQCHIP=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_INTEL=m +CONFIG_KVM_AMD=m +# CONFIG_KVM_TRACE is not set +CONFIG_LGUEST=m +CONFIG_VIRTIO=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC_T10DIF=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_NLATTR=y diff --git a/pkgs/core/kernel/ipfire_logo.ppm b/pkgs/core/kernel/ipfire_logo.ppm new file mode 100644 index 0000000..08d901a --- /dev/null +++ b/pkgs/core/kernel/ipfire_logo.ppm @@ -0,0 +1,15124 @@ +P3 +# CREATOR: GIMP PNM Filter Version 1.1 +63 80 +255 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +249 +226 +16 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +249 +226 +16 +249 +226 +16 +249 +226 +16 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +212 +0 +253 +206 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +251 +222 +3 +249 +226 +16 +254 +227 +0 +254 +227 +0 +254 +227 +0 +254 +227 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +212 +0 +253 +212 +0 +253 +212 +0 +253 +212 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +251 +222 +3 +251 +222 +3 +249 +226 +16 +249 +226 +16 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +212 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +253 +212 +0 +0 +1 +0 +251 +222 +3 +251 +222 +3 +251 +222 +3 +251 +222 +3 +254 +227 +0 +254 +227 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +251 +163 +0 +251 +163 +0 +251 +163 +0 +254 +176 +0 +0 +1 +0 +253 +212 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +251 +222 +3 +251 +222 +3 +251 +222 +3 +251 +222 +3 +251 +222 +3 +251 +222 +3 +251 +222 +3 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +251 +163 +0 +251 +163 +0 +255 +151 +0 +255 +151 +0 +251 +163 +0 +250 +190 +17 +253 +212 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +251 +222 +3 +254 +227 +0 +253 +218 +0 +253 +212 +0 +253 +212 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +247 +145 +3 +255 +145 +0 +253 +140 +3 +255 +125 +0 +255 +151 +0 +252 +182 +0 +253 +206 +0 +253 +212 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +253 +206 +0 +253 +212 +0 +253 +212 +0 +254 +201 +0 +254 +201 +0 +253 +206 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +140 +3 +255 +125 +0 +252 +111 +1 +253 +140 +3 +254 +176 +0 +254 +201 +0 +253 +212 +0 +253 +218 +0 +254 +227 +0 +253 +218 +0 +253 +218 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +132 +0 +250 +122 +6 +255 +103 +0 +255 +103 +0 +253 +140 +3 +254 +176 +0 +255 +192 +0 +253 +206 +0 +253 +218 +0 +254 +227 +0 +253 +218 +0 +253 +212 +0 +255 +192 +0 +254 +176 +0 +252 +182 +0 +252 +182 +0 +250 +190 +17 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +140 +3 +252 +111 +1 +255 +87 +0 +253 +73 +0 +252 +94 +0 +253 +140 +3 +254 +176 +0 +255 +192 +0 +254 +201 +0 +253 +218 +0 +254 +227 +0 +253 +218 +0 +253 +206 +0 +252 +182 +0 +255 +168 +0 +254 +176 +0 +252 +182 +0 +252 +182 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +255 +125 +0 +255 +87 +0 +253 +53 +0 +251 +62 +1 +255 +103 +0 +255 +145 +0 +255 +168 +0 +252 +182 +0 +254 +201 +0 +251 +222 +3 +254 +227 +0 +253 +212 +0 +254 +201 +0 +254 +176 +0 +251 +163 +0 +254 +176 +0 +252 +182 +0 +252 +182 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +140 +3 +255 +103 +0 +251 +62 +1 +252 +39 +0 +253 +73 +0 +255 +125 +0 +255 +151 +0 +255 +168 +0 +254 +176 +0 +254 +201 +0 +254 +227 +0 +253 +218 +0 +253 +212 +0 +254 +201 +0 +254 +176 +0 +255 +151 +0 +254 +176 +0 +252 +182 +0 +252 +182 +0 +252 +182 +0 +252 +182 +0 +249 +171 +5 +249 +171 +5 +249 +171 +5 +249 +171 +5 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +255 +125 +0 +255 +87 +0 +252 +39 +0 +252 +39 +0 +255 +87 +0 +252 +132 +0 +251 +163 +0 +254 +176 +0 +255 +192 +0 +253 +206 +0 +251 +222 +3 +251 +222 +3 +253 +212 +0 +255 +192 +0 +255 +151 +0 +255 +151 +0 +254 +176 +0 +252 +182 +0 +252 +182 +0 +254 +176 +0 +254 +176 +0 +254 +176 +0 +254 +176 +0 +254 +176 +0 +249 +171 +5 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +132 +0 +255 +103 +0 +253 +53 +0 +254 +23 +0 +253 +53 +0 +255 +103 +0 +255 +151 +0 +254 +176 +0 +255 +192 +0 +253 +206 +0 +253 +218 +0 +253 +218 +0 +253 +218 +0 +254 +201 +0 +255 +168 +0 +255 +125 +0 +255 +145 +0 +254 +176 +0 +254 +176 +0 +254 +176 +0 +255 +168 +0 +255 +168 +0 +255 +168 +0 +255 +168 +0 +254 +176 +0 +249 +171 +5 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +250 +122 +6 +255 +87 +0 +252 +39 +0 +254 +23 +0 +253 +53 +0 +252 +111 +1 +253 +156 +0 +255 +192 +0 +253 +206 +0 +253 +212 +0 +253 +218 +0 +254 +227 +0 +253 +206 +0 +252 +182 +0 +253 +140 +3 +252 +111 +1 +252 +132 +0 +251 +163 +0 +251 +163 +0 +255 +151 +0 +255 +145 +0 +255 +145 +0 +253 +156 +0 +254 +176 +0 +254 +176 +0 +254 +176 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +73 +0 +252 +82 +5 +0 +1 +0 +0 +1 +0 +250 +122 +6 +252 +111 +1 +251 +62 +1 +254 +23 +0 +254 +23 +0 +251 +62 +1 +252 +111 +1 +253 +156 +0 +252 +182 +0 +252 +182 +0 +254 +176 +0 +255 +192 +0 +254 +176 +0 +255 +145 +0 +252 +111 +1 +251 +62 +1 +253 +53 +0 +251 +62 +1 +255 +103 +0 +255 +125 +0 +255 +125 +0 +255 +125 +0 +255 +125 +0 +255 +145 +0 +254 +176 +0 +254 +176 +0 +255 +168 +0 +251 +163 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +251 +62 +1 +251 +62 +1 +253 +53 +0 +253 +53 +0 +252 +82 +5 +252 +111 +1 +252 +111 +1 +255 +87 +0 +253 +53 +0 +254 +23 +0 +254 +23 +0 +251 +62 +1 +255 +103 +0 +255 +125 +0 +252 +94 +0 +255 +87 +0 +255 +145 +0 +252 +182 +0 +255 +192 +0 +254 +176 +0 +255 +168 +0 +253 +140 +3 +252 +111 +1 +255 +103 +0 +252 +94 +0 +251 +62 +1 +253 +53 +0 +253 +73 +0 +252 +111 +1 +255 +145 +0 +253 +156 +0 +255 +151 +0 +251 +163 +0 +255 +168 +0 +247 +158 +17 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +53 +0 +252 +39 +0 +254 +23 +0 +254 +23 +0 +253 +53 +0 +255 +87 +0 +252 +94 +0 +253 +73 +0 +252 +39 +0 +254 +23 +0 +254 +23 +0 +253 +53 +0 +253 +53 +0 +252 +39 +0 +253 +73 +0 +255 +145 +0 +253 +206 +0 +253 +235 +0 +253 +247 +0 +252 +241 +0 +253 +247 +0 +247 +234 +53 +250 +206 +52 +254 +185 +33 +255 +168 +0 +253 +140 +3 +252 +111 +1 +251 +62 +1 +252 +39 +0 +255 +87 +0 +255 +125 +0 +255 +125 +0 +253 +156 +0 +251 +163 +0 +253 +156 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +53 +0 +254 +23 +0 +254 +23 +0 +254 +23 +0 +255 +0 +0 +254 +23 +0 +253 +53 +0 +251 +62 +1 +253 +53 +0 +252 +39 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +254 +23 +0 +252 +82 +5 +253 +156 +0 +253 +235 +0 +247 +234 +53 +243 +230 +87 +243 +227 +122 +243 +227 +122 +245 +230 +150 +245 +230 +150 +254 +208 +136 +253 +197 +105 +254 +195 +91 +250 +206 +52 +250 +190 +17 +247 +145 +3 +252 +94 +0 +252 +39 +0 +252 +39 +0 +255 +103 +0 +255 +151 +0 +253 +156 +0 +255 +145 +0 +253 +140 +3 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +53 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +254 +23 +0 +254 +23 +0 +254 +23 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +254 +23 +0 +255 +87 +0 +248 +147 +35 +249 +189 +72 +245 +207 +109 +247 +223 +154 +246 +228 +184 +249 +236 +207 +240 +229 +209 +234 +225 +211 +234 +225 +211 +227 +210 +189 +227 +210 +189 +234 +196 +163 +231 +192 +138 +245 +207 +109 +249 +189 +72 +249 +171 +5 +252 +111 +1 +254 +23 +0 +252 +39 +0 +255 +125 +0 +255 +145 +0 +255 +145 +0 +252 +132 +0 +252 +132 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +240 +42 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +254 +23 +0 +239 +71 +0 +242 +132 +58 +243 +179 +115 +234 +196 +163 +227 +210 +189 +216 +207 +200 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +216 +207 +200 +227 +210 +189 +224 +207 +170 +231 +192 +138 +228 +174 +82 +253 +164 +50 +252 +94 +0 +254 +23 +0 +252 +39 +0 +255 +103 +0 +255 +125 +0 +255 +125 +0 +255 +125 +0 +250 +122 +6 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +240 +42 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +254 +23 +0 +240 +42 +0 +226 +105 +71 +233 +162 +120 +216 +194 +174 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +208 +199 +191 +216 +194 +174 +234 +196 +163 +243 +179 +115 +237 +149 +36 +248 +83 +28 +255 +0 +0 +252 +39 +0 +252 +94 +0 +255 +103 +0 +255 +103 +0 +252 +111 +1 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +230 +94 +76 +215 +157 +140 +205 +177 +161 +175 +158 +146 +175 +158 +146 +162 +141 +126 +175 +158 +146 +188 +173 +162 +199 +188 +177 +199 +188 +177 +199 +188 +177 +199 +188 +177 +199 +188 +177 +199 +188 +177 +199 +188 +177 +199 +188 +177 +199 +188 +177 +199 +188 +177 +199 +188 +177 +205 +177 +161 +233 +162 +120 +242 +132 +58 +240 +42 +0 +255 +0 +0 +252 +39 +0 +253 +73 +0 +255 +87 +0 +255 +103 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +236 +73 +58 +223 +147 +134 +165 +137 +118 +129 +110 +98 +141 +122 +107 +141 +122 +107 +141 +122 +107 +141 +122 +107 +129 +110 +98 +138 +127 +118 +188 +173 +162 +188 +173 +162 +188 +173 +162 +188 +173 +162 +188 +173 +162 +188 +173 +162 +188 +173 +162 +188 +173 +162 +188 +173 +162 +188 +173 +162 +188 +173 +162 +205 +177 +161 +189 +129 +78 +232 +86 +43 +238 +0 +0 +255 +0 +0 +252 +39 +0 +253 +73 +0 +252 +94 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +238 +0 +0 +238 +0 +0 +204 +17 +0 +199 +98 +76 +148 +107 +96 +129 +110 +98 +141 +122 +107 +97 +82 +72 +87 +66 +54 +87 +66 +54 +87 +66 +54 +87 +66 +54 +115 +93 +80 +129 +110 +98 +175 +158 +146 +175 +158 +146 +175 +158 +146 +175 +158 +146 +175 +158 +146 +175 +158 +146 +175 +158 +146 +175 +158 +146 +175 +158 +146 +175 +158 +146 +175 +158 +146 +175 +144 +117 +226 +105 +71 +223 +4 +0 +238 +0 +0 +254 +23 +0 +251 +62 +1 +255 +87 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +223 +4 +0 +212 +0 +0 +182 +48 +41 +144 +92 +77 +120 +95 +77 +87 +66 +54 +73 +51 +33 +129 +110 +98 +188 +173 +162 +199 +188 +177 +188 +173 +162 +108 +96 +89 +40 +23 +16 +45 +34 +29 +108 +78 +63 +162 +141 +126 +162 +141 +126 +162 +141 +126 +141 +122 +107 +129 +110 +98 +141 +122 +107 +141 +122 +107 +141 +122 +107 +129 +110 +98 +141 +122 +107 +165 +137 +118 +180 +109 +90 +179 +0 +0 +238 +0 +0 +238 +0 +0 +253 +53 +0 +255 +87 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +223 +4 +0 +204 +17 +0 +164 +3 +0 +146 +57 +50 +108 +78 +63 +73 +51 +33 +64 +51 +42 +175 +158 +146 +232 +224 +218 +246 +242 +239 +246 +242 +239 +246 +242 +239 +232 +224 +218 +153 +141 +133 +10 +3 +1 +10 +3 +1 +115 +93 +80 +141 +122 +107 +108 +78 +63 +115 +93 +80 +129 +110 +98 +129 +110 +98 +115 +93 +80 +129 +110 +98 +141 +122 +107 +129 +110 +98 +115 +93 +80 +144 +92 +77 +182 +48 +41 +212 +0 +0 +238 +0 +0 +252 +39 +0 +252 +82 +5 +252 +111 +1 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +212 +0 +0 +179 +0 +0 +116 +0 +0 +78 +33 +25 +87 +66 +54 +45 +34 +29 +138 +127 +118 +199 +188 +177 +216 +207 +200 +239 +233 +231 +246 +242 +239 +246 +242 +239 +246 +242 +239 +239 +233 +231 +138 +127 +118 +10 +3 +1 +45 +34 +29 +58 +39 +28 +58 +39 +28 +58 +39 +28 +97 +82 +72 +108 +96 +89 +108 +96 +89 +97 +82 +72 +64 +51 +42 +87 +66 +54 +115 +93 +80 +88 +59 +44 +100 +16 +5 +179 +0 +0 +238 +0 +0 +238 +0 +0 +251 +62 +1 +248 +98 +10 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +212 +0 +0 +164 +3 +0 +81 +2 +0 +78 +33 +25 +40 +23 +16 +108 +96 +89 +188 +173 +162 +208 +199 +191 +224 +215 +208 +232 +224 +218 +239 +233 +231 +246 +242 +239 +239 +233 +231 +239 +233 +231 +216 +207 +200 +64 +51 +42 +29 +22 +18 +10 +3 +1 +76 +66 +59 +162 +141 +126 +208 +199 +191 +239 +233 +231 +246 +242 +239 +239 +233 +231 +208 +199 +191 +141 +122 +107 +73 +51 +33 +64 +51 +42 +53 +2 +0 +149 +0 +0 +238 +0 +0 +238 +0 +0 +252 +39 +0 +252 +82 +5 +248 +83 +28 +253 +73 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +212 +0 +0 +149 +0 +0 +64 +0 +0 +58 +39 +28 +58 +39 +28 +153 +141 +133 +199 +188 +177 +216 +207 +200 +224 +215 +208 +232 +224 +218 +232 +224 +218 +239 +233 +231 +239 +233 +231 +239 +233 +231 +224 +215 +208 +153 +141 +133 +40 +23 +16 +97 +82 +72 +188 +173 +162 +208 +199 +191 +216 +207 +200 +224 +215 +208 +239 +233 +231 +252 +254 +251 +246 +242 +239 +239 +233 +231 +153 +141 +133 +45 +34 +29 +34 +5 +2 +116 +0 +0 +212 +0 +0 +255 +0 +0 +254 +23 +0 +252 +39 +0 +252 +39 +0 +253 +53 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +238 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +204 +17 +0 +131 +17 +1 +53 +2 +0 +40 +23 +16 +87 +66 +54 +188 +173 +162 +208 +199 +191 +224 +215 +208 +232 +224 +218 +232 +224 +218 +232 +224 +218 +232 +224 +218 +232 +224 +218 +188 +173 +162 +188 +173 +162 +162 +141 +126 +87 +66 +54 +175 +158 +146 +199 +188 +177 +224 +215 +208 +232 +224 +218 +232 +224 +218 +232 +224 +218 +239 +233 +231 +246 +242 +239 +246 +242 +239 +224 +215 +208 +108 +96 +89 +17 +0 +0 +81 +2 +0 +204 +17 +0 +238 +0 +0 +255 +0 +0 +255 +0 +0 +254 +23 +0 +253 +53 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +39 +0 +238 +0 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +204 +17 +0 +116 +0 +0 +42 +3 +1 +17 +0 +0 +97 +82 +72 +188 +173 +162 +208 +199 +191 +224 +215 +208 +224 +215 +208 +232 +224 +218 +232 +224 +218 +232 +224 +218 +208 +199 +191 +29 +22 +18 +153 +141 +133 +175 +158 +146 +115 +93 +80 +97 +82 +72 +216 +207 +200 +216 +207 +200 +232 +224 +218 +232 +224 +218 +232 +224 +218 +239 +233 +231 +239 +233 +231 +239 +233 +231 +224 +215 +208 +138 +127 +118 +40 +23 +16 +64 +0 +0 +179 +0 +0 +238 +0 +0 +255 +0 +0 +255 +0 +0 +254 +23 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +23 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +223 +4 +0 +179 +0 +0 +116 +0 +0 +34 +5 +2 +0 +1 +0 +108 +96 +89 +199 +188 +177 +208 +199 +191 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +175 +158 +146 +29 +22 +18 +29 +22 +18 +45 +34 +29 +87 +66 +54 +10 +3 +1 +97 +82 +72 +153 +141 +133 +232 +224 +218 +232 +224 +218 +232 +224 +218 +232 +224 +218 +232 +224 +218 +232 +224 +218 +208 +199 +191 +153 +141 +133 +45 +34 +29 +53 +2 +0 +164 +3 +0 +238 +0 +0 +255 +0 +0 +254 +23 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +212 +0 +0 +179 +0 +0 +100 +16 +5 +17 +0 +0 +0 +1 +0 +97 +82 +72 +199 +188 +177 +208 +199 +191 +216 +207 +200 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +175 +158 +146 +76 +66 +59 +0 +1 +0 +10 +3 +1 +108 +78 +63 +10 +3 +1 +10 +3 +1 +138 +127 +118 +232 +224 +218 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +199 +188 +177 +138 +127 +118 +45 +34 +29 +42 +3 +1 +164 +3 +0 +238 +0 +0 +255 +0 +0 +252 +39 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +212 +0 +0 +179 +0 +0 +81 +2 +0 +17 +0 +0 +0 +1 +0 +76 +66 +59 +188 +173 +162 +216 +207 +200 +216 +207 +200 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +199 +188 +177 +141 +122 +107 +64 +51 +42 +64 +51 +42 +87 +66 +54 +129 +110 +98 +64 +51 +42 +199 +188 +177 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +224 +215 +208 +216 +207 +200 +199 +188 +177 +129 +110 +98 +10 +3 +1 +42 +3 +1 +149 +0 +0 +238 +0 +0 +238 +0 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +39 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +223 +4 +0 +164 +3 +0 +81 +2 +0 +10 +3 +1 +0 +1 +0 +29 +22 +18 +175 +158 +146 +216 +207 +200 +216 +207 +200 +216 +207 +200 +216 +207 +200 +216 +207 +200 +216 +207 +200 +216 +207 +200 +175 +158 +146 +141 +122 +107 +115 +93 +80 +10 +3 +1 +141 +122 +107 +188 +173 +162 +208 +199 +191 +216 +207 +200 +216 +207 +200 +216 +207 +200 +216 +207 +200 +208 +199 +191 +199 +188 +177 +175 +158 +146 +76 +66 +59 +0 +1 +0 +34 +5 +2 +131 +17 +1 +223 +4 +0 +238 +0 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +39 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +164 +3 +0 +64 +0 +0 +10 +3 +1 +0 +1 +0 +0 +1 +0 +108 +96 +89 +199 +188 +177 +216 +207 +200 +216 +207 +200 +216 +207 +200 +216 +207 +200 +208 +199 +191 +223 +147 +134 +229 +105 +88 +230 +94 +76 +229 +105 +88 +248 +126 +98 +223 +122 +99 +223 +122 +99 +217 +137 +110 +217 +188 +181 +216 +207 +200 +216 +207 +200 +216 +207 +200 +208 +199 +191 +188 +173 +162 +97 +82 +72 +0 +1 +0 +0 +1 +0 +22 +0 +3 +116 +0 +0 +212 +0 +0 +238 +0 +0 +235 +36 +9 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +39 +0 +254 +23 +0 +255 +0 +0 +255 +0 +0 +238 +0 +0 +164 +3 +0 +53 +2 +0 +10 +3 +1 +0 +1 +0 +0 +1 +0 +29 +22 +18 +162 +141 +126 +199 +188 +177 +208 +199 +191 +199 +188 +177 +205 +177 +161 +236 +73 +58 +243 +69 +41 +248 +126 +98 +255 +165 +114 +250 +191 +166 +253 +217 +189 +254 +228 +219 +246 +242 +239 +254 +228 +219 +239 +136 +103 +215 +157 +140 +208 +199 +191 +188 +173 +162 +129 +110 +98 +45 +34 +29 +0 +1 +0 +0 +1 +0 +0 +1 +0 +17 +0 +0 +100 +16 +5 +204 +17 +0 +238 +0 +0 +238 +0 +0 +252 +39 +0 +252 +39 +0 +253 +53 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +39 +0 +255 +0 +0 +255 +0 +0 +223 +4 +0 +149 +0 +0 +42 +3 +1 +10 +3 +1 +0 +1 +0 +0 +1 +0 +0 +1 +0 +64 +51 +42 +175 +158 +146 +199 +188 +177 +199 +188 +177 +229 +105 +88 +235 +36 +9 +240 +42 +0 +240 +42 +0 +248 +92 +36 +248 +143 +92 +253 +177 +133 +250 +191 +166 +253 +217 +189 +254 +228 +219 +254 +228 +219 +223 +122 +99 +162 +141 +126 +129 +110 +98 +45 +34 +29 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +10 +3 +1 +64 +0 +0 +179 +0 +0 +238 +0 +0 +255 +0 +0 +255 +0 +0 +254 +23 +0 +254 +23 +0 +253 +53 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +156 +0 +255 +125 +0 +252 +132 +0 +255 +125 +0 +0 +1 +0 +253 +53 +0 +254 +23 +0 +255 +0 +0 +212 +0 +0 +116 +0 +0 +22 +0 +3 +0 +1 +0 +0 +1 +0 +0 +1 +0 +10 +3 +1 +129 +110 +98 +188 +173 +162 +175 +158 +146 +175 +158 +146 +199 +98 +76 +243 +69 +41 +235 +36 +9 +240 +42 +0 +240 +42 +0 +240 +42 +0 +248 +92 +36 +248 +143 +92 +253 +177 +133 +250 +191 +166 +250 +191 +166 +223 +122 +99 +224 +215 +208 +224 +215 +208 +199 +188 +177 +108 +96 +89 +0 +1 +0 +0 +1 +0 +0 +1 +0 +10 +3 +1 +42 +3 +1 +131 +17 +1 +223 +4 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +252 +39 +0 +252 +82 +5 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +255 +151 +0 +252 +111 +1 +252 +111 +1 +252 +111 +1 +252 +94 +0 +253 +53 +0 +254 +23 +0 +238 +0 +0 +179 +0 +0 +64 +0 +0 +10 +3 +1 +0 +1 +0 +0 +1 +0 +0 +1 +0 +153 +141 +133 +239 +233 +231 +239 +233 +231 +224 +215 +208 +199 +188 +177 +188 +173 +162 +230 +94 +76 +243 +69 +41 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +239 +71 +0 +249 +123 +63 +248 +143 +92 +226 +105 +71 +216 +207 +200 +246 +242 +239 +255 +251 +248 +255 +251 +248 +239 +233 +231 +138 +127 +118 +10 +3 +1 +0 +1 +0 +0 +1 +0 +17 +0 +0 +81 +2 +0 +179 +0 +0 +238 +0 +0 +255 +0 +0 +255 +0 +0 +255 +0 +0 +254 +23 +0 +253 +73 +0 +252 +111 +1 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +250 +190 +17 +255 +151 +0 +255 +87 +0 +251 +62 +1 +255 +87 +0 +253 +73 +0 +240 +42 +0 +252 +39 +0 +212 +0 +0 +116 +0 +0 +34 +5 +2 +10 +3 +1 +0 +1 +0 +0 +1 +0 +138 +127 +118 +246 +242 +239 +252 +254 +251 +255 +251 +248 +246 +242 +239 +239 +233 +231 +224 +215 +208 +188 +173 +162 +230 +94 +76 +248 +83 +28 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +241 +61 +2 +232 +86 +43 +205 +177 +161 +246 +242 +239 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +246 +242 +239 +138 +127 +118 +10 +3 +1 +0 +1 +0 +10 +3 +1 +34 +5 +2 +116 +0 +0 +204 +17 +0 +240 +42 +0 +254 +23 +0 +255 +0 +0 +254 +23 +0 +253 +73 +0 +255 +125 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +206 +0 +255 +192 +0 +255 +151 +0 +253 +73 +0 +252 +39 +0 +252 +39 +0 +252 +39 +0 +253 +73 +0 +229 +54 +6 +149 +0 +0 +53 +2 +0 +10 +3 +1 +0 +1 +0 +0 +1 +0 +97 +82 +72 +232 +224 +218 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +255 +251 +248 +249 +236 +207 +249 +229 +192 +199 +188 +177 +232 +93 +65 +243 +69 +41 +240 +42 +0 +240 +42 +0 +240 +42 +0 +229 +54 +6 +205 +154 +135 +239 +233 +231 +255 +251 +248 +252 +254 +251 +252 +254 +251 +252 +254 +251 +255 +251 +248 +252 +254 +251 +239 +233 +231 +108 +96 +89 +0 +1 +0 +0 +1 +0 +10 +3 +1 +53 +2 +0 +149 +0 +0 +215 +80 +5 +248 +98 +10 +253 +53 +0 +251 +62 +1 +255 +103 +0 +253 +140 +3 +251 +163 +0 +250 +190 +17 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +218 +0 +253 +206 +0 +252 +182 +0 +253 +140 +3 +253 +73 +0 +254 +23 +0 +254 +23 +0 +252 +82 +5 +252 +111 +1 +187 +54 +1 +81 +2 +0 +17 +0 +0 +0 +1 +0 +0 +1 +0 +45 +34 +29 +208 +199 +191 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +246 +228 +184 +252 +219 +138 +240 +229 +209 +199 +188 +177 +232 +93 +65 +248 +92 +36 +240 +42 +0 +229 +54 +6 +217 +137 +110 +232 +224 +218 +246 +242 +239 +255 +251 +248 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +208 +199 +191 +64 +51 +42 +0 +1 +0 +0 +1 +0 +10 +3 +1 +64 +0 +0 +165 +64 +27 +212 +142 +16 +237 +149 +36 +252 +111 +1 +253 +140 +3 +254 +176 +0 +255 +192 +0 +254 +201 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +251 +222 +3 +253 +218 +0 +254 +201 +0 +251 +163 +0 +252 +111 +1 +253 +53 +0 +252 +39 +0 +239 +71 +0 +243 +119 +33 +214 +102 +32 +100 +16 +5 +17 +0 +0 +0 +1 +0 +0 +1 +0 +10 +3 +1 +138 +127 +118 +246 +242 +239 +252 +254 +251 +252 +254 +251 +252 +254 +251 +255 +251 +248 +252 +254 +251 +252 +254 +251 +246 +228 +184 +254 +208 +136 +246 +228 +184 +232 +224 +218 +217 +188 +181 +232 +93 +65 +248 +112 +57 +216 +126 +60 +224 +207 +170 +246 +242 +239 +252 +254 +251 +252 +254 +251 +252 +254 +251 +255 +251 +248 +255 +251 +248 +252 +254 +251 +255 +251 +248 +252 +254 +251 +252 +254 +251 +153 +141 +133 +10 +3 +1 +0 +1 +0 +0 +1 +0 +17 +0 +0 +83 +41 +15 +189 +129 +78 +207 +175 +92 +228 +174 +82 +221 +134 +23 +236 +173 +0 +254 +201 +0 +253 +212 +0 +253 +212 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +227 +0 +253 +218 +0 +255 +192 +0 +252 +132 +0 +253 +73 +0 +251 +62 +1 +247 +98 +31 +243 +119 +33 +214 +102 +32 +100 +16 +5 +22 +0 +3 +0 +1 +0 +0 +1 +0 +0 +1 +0 +76 +66 +59 +216 +207 +200 +252 +254 +251 +252 +254 +251 +255 +251 +248 +255 +251 +248 +255 +251 +248 +252 +254 +251 +252 +254 +251 +251 +212 +160 +255 +165 +114 +250 +191 +166 +254 +243 +226 +239 +233 +231 +234 +225 +211 +231 +192 +138 +254 +208 +136 +246 +228 +184 +254 +243 +226 +252 +254 +251 +255 +251 +248 +252 +254 +251 +255 +251 +248 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +224 +215 +208 +76 +66 +59 +0 +1 +0 +0 +1 +0 +0 +1 +0 +17 +0 +0 +83 +41 +15 +127 +102 +70 +194 +168 +113 +194 +168 +113 +166 +132 +52 +212 +179 +0 +253 +218 +0 +254 +227 +0 +254 +227 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +241 +0 +253 +235 +0 +253 +218 +0 +255 +168 +0 +252 +94 +0 +252 +82 +5 +250 +122 +6 +214 +102 +32 +165 +64 +27 +100 +16 +5 +22 +0 +3 +10 +3 +1 +0 +1 +0 +0 +1 +0 +10 +3 +1 +153 +141 +133 +246 +242 +239 +255 +251 +248 +255 +251 +248 +254 +243 +226 +249 +236 +207 +249 +236 +207 +249 +236 +207 +253 +217 +189 +243 +69 +41 +253 +53 +0 +249 +123 +63 +254 +243 +226 +246 +242 +239 +254 +243 +226 +254 +208 +136 +253 +197 +105 +245 +230 +150 +249 +236 +207 +255 +251 +248 +255 +251 +248 +252 +254 +251 +252 +254 +251 +252 +254 +251 +252 +254 +251 +255 +251 +248 +255 +251 +248 +252 +254 +251 +252 +254 +251 +153 +141 +133 +10 +3 +1 +0 +1 +0 +0 +1 +0 +10 +3 +1 +22 +0 +3 +34 +5 +2 +108 +78 +63 +175 +144 +117 +216 +198 +139 +187 +156 +67 +226 +204 +5 +253 +235 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +241 +0 +252 +241 +0 +253 +218 +0 +247 +145 +3 +252 +111 +1 +247 +145 +3 +216 +93 +0 +165 +64 +27 +81 +2 +0 +81 +2 +0 +53 +2 +0 +17 +0 +0 +10 +3 +1 +0 +1 +0 +64 +51 +42 +199 +188 +177 +254 +243 +226 +249 +236 +207 +254 +243 +226 +253 +217 +189 +254 +208 +136 +255 +212 +149 +245 +207 +109 +243 +119 +33 +254 +23 +0 +253 +156 +0 +255 +212 +149 +254 +243 +226 +252 +254 +251 +249 +229 +192 +248 +149 +70 +253 +164 +50 +241 +219 +98 +254 +243 +226 +254 +243 +226 +249 +229 +192 +249 +236 +207 +249 +236 +207 +254 +243 +226 +254 +243 +226 +254 +243 +226 +254 +243 +226 +252 +254 +251 +252 +254 +251 +208 +199 +191 +64 +51 +42 +0 +1 +0 +10 +3 +1 +17 +0 +0 +53 +2 +0 +42 +3 +1 +10 +3 +1 +64 +51 +42 +141 +122 +107 +216 +198 +139 +226 +204 +5 +253 +235 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +247 +0 +253 +247 +0 +253 +206 +0 +236 +147 +0 +247 +172 +33 +214 +102 +32 +131 +17 +1 +64 +0 +0 +53 +2 +0 +131 +17 +1 +149 +0 +0 +64 +0 +0 +17 +0 +0 +0 +1 +0 +108 +96 +89 +232 +224 +218 +249 +236 +207 +247 +223 +154 +250 +222 +164 +253 +197 +105 +250 +206 +52 +254 +225 +88 +246 +135 +42 +255 +87 +0 +253 +53 +0 +254 +185 +33 +254 +208 +136 +255 +212 +149 +255 +251 +248 +251 +212 +160 +252 +39 +0 +252 +165 +79 +253 +197 +105 +251 +212 +160 +251 +212 +160 +254 +208 +136 +255 +212 +149 +251 +212 +160 +250 +222 +164 +246 +228 +184 +249 +229 +192 +254 +243 +226 +252 +254 +251 +252 +254 +251 +239 +233 +231 +108 +96 +89 +0 +1 +0 +10 +3 +1 +64 +0 +0 +116 +0 +0 +81 +2 +0 +17 +0 +0 +0 +1 +0 +29 +22 +18 +127 +102 +70 +214 +208 +7 +253 +235 +0 +252 +241 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +253 +0 +252 +241 +0 +246 +202 +21 +250 +206 +52 +178 +109 +17 +116 +0 +0 +64 +0 +0 +40 +23 +16 +83 +41 +15 +187 +54 +1 +212 +0 +0 +116 +0 +0 +34 +5 +2 +10 +3 +1 +153 +141 +133 +254 +228 +219 +252 +189 +140 +249 +189 +72 +253 +197 +105 +247 +158 +17 +251 +163 +0 +254 +185 +33 +246 +135 +42 +252 +82 +5 +251 +62 +1 +252 +111 +1 +255 +87 +0 +255 +87 +0 +249 +236 +207 +253 +197 +105 +252 +111 +1 +252 +189 +140 +252 +165 +79 +246 +135 +42 +254 +182 +99 +254 +182 +99 +253 +197 +105 +252 +219 +138 +245 +204 +88 +254 +195 +91 +243 +179 +115 +251 +212 +160 +249 +236 +207 +254 +243 +226 +254 +243 +226 +153 +141 +133 +29 +22 +18 +22 +0 +3 +116 +0 +0 +149 +0 +0 +131 +17 +1 +83 +41 +15 +40 +23 +16 +10 +3 +1 +10 +3 +1 +135 +126 +11 +237 +235 +0 +253 +247 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +247 +0 +252 +241 +0 +249 +226 +16 +190 +156 +11 +83 +41 +15 +78 +33 +25 +88 +59 +44 +104 +77 +52 +140 +97 +37 +215 +80 +5 +223 +4 +0 +149 +0 +0 +42 +3 +1 +45 +34 +29 +188 +173 +162 +234 +196 +163 +247 +98 +31 +253 +164 +50 +253 +164 +50 +255 +103 +0 +250 +122 +6 +255 +87 +0 +252 +165 +79 +248 +149 +70 +255 +103 +0 +255 +87 +0 +249 +123 +63 +242 +132 +58 +254 +243 +226 +254 +225 +88 +249 +171 +5 +253 +217 +189 +252 +165 +79 +252 +94 +0 +250 +122 +6 +252 +111 +1 +254 +176 +0 +250 +190 +17 +253 +164 +50 +255 +125 +0 +252 +111 +1 +250 +122 +6 +252 +165 +79 +250 +222 +164 +249 +229 +192 +188 +173 +162 +64 +51 +42 +34 +5 +2 +149 +0 +0 +179 +0 +0 +187 +54 +1 +178 +109 +17 +140 +97 +37 +73 +51 +33 +29 +22 +18 +43 +37 +9 +166 +163 +1 +252 +241 +0 +237 +235 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +247 +0 +253 +247 +0 +226 +204 +5 +135 +126 +11 +96 +80 +25 +104 +77 +52 +0 +1 +0 +0 +1 +0 +0 +1 +0 +226 +90 +0 +223 +4 +0 +164 +3 +0 +42 +3 +1 +76 +66 +59 +208 +199 +191 +234 +196 +163 +252 +132 +0 +247 +174 +61 +253 +164 +50 +255 +125 +0 +249 +171 +5 +252 +132 +0 +254 +182 +99 +255 +212 +149 +255 +151 +0 +255 +125 +0 +251 +212 +160 +254 +243 +226 +254 +243 +226 +254 +185 +33 +250 +122 +6 +254 +243 +226 +243 +179 +115 +255 +125 +0 +253 +140 +3 +247 +172 +33 +254 +225 +88 +248 +147 +35 +250 +122 +6 +246 +135 +42 +254 +182 +99 +248 +147 +35 +252 +132 +0 +249 +189 +72 +250 +222 +164 +208 +199 +191 +76 +66 +59 +42 +3 +1 +164 +3 +0 +204 +17 +0 +202 +42 +0 +253 +156 +0 +0 +1 +0 +0 +1 +0 +104 +77 +52 +73 +51 +33 +96 +80 +25 +191 +187 +0 +237 +235 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +237 +235 +0 +237 +235 +0 +191 +187 +0 +135 +126 +11 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +216 +93 +0 +235 +36 +9 +179 +0 +0 +64 +0 +0 +108 +96 +89 +216 +207 +200 +231 +192 +138 +253 +156 +0 +253 +197 +105 +247 +174 +61 +255 +151 +0 +253 +164 +50 +247 +174 +61 +249 +229 +192 +251 +212 +160 +255 +168 +0 +255 +151 +0 +246 +228 +184 +249 +236 +207 +254 +208 +136 +255 +168 +0 +253 +156 +0 +249 +236 +207 +253 +197 +105 +255 +151 +0 +250 +190 +17 +243 +227 +122 +249 +229 +192 +248 +147 +35 +253 +156 +0 +249 +189 +72 +252 +219 +138 +249 +189 +72 +251 +163 +0 +254 +185 +33 +251 +212 +160 +224 +215 +208 +97 +82 +72 +64 +0 +0 +179 +0 +0 +212 +0 +0 +239 +71 +0 +253 +156 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +127 +102 +70 +135 +126 +11 +166 +163 +1 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +214 +208 +7 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +235 +125 +1 +235 +36 +9 +204 +17 +0 +100 +16 +5 +129 +110 +98 +224 +215 +208 +252 +189 +140 +249 +171 +5 +252 +219 +138 +245 +204 +88 +254 +176 +0 +252 +219 +138 +249 +229 +192 +254 +228 +219 +245 +207 +109 +254 +176 +0 +254 +176 +0 +249 +236 +207 +249 +236 +207 +254 +182 +99 +254 +176 +0 +254 +176 +0 +246 +228 +184 +245 +204 +88 +254 +176 +0 +254 +185 +33 +253 +217 +189 +246 +242 +239 +254 +208 +136 +254 +176 +0 +252 +182 +0 +250 +190 +17 +250 +190 +17 +252 +182 +0 +250 +190 +17 +246 +228 +184 +232 +224 +218 +115 +93 +80 +81 +2 +0 +179 +0 +0 +238 +0 +0 +252 +94 +0 +251 +163 +0 +250 +190 +17 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +235 +125 +1 +229 +54 +6 +212 +0 +0 +116 +0 +0 +141 +122 +107 +224 +215 +208 +227 +210 +189 +247 +223 +154 +246 +228 +184 +245 +230 +150 +254 +225 +88 +243 +227 +122 +247 +223 +154 +253 +217 +189 +245 +204 +88 +246 +202 +21 +245 +204 +88 +246 +242 +239 +246 +242 +239 +253 +217 +189 +250 +206 +52 +250 +206 +52 +240 +229 +209 +247 +223 +154 +250 +206 +52 +245 +207 +109 +239 +233 +231 +246 +242 +239 +246 +242 +239 +247 +223 +154 +249 +207 +71 +246 +202 +21 +246 +202 +21 +250 +206 +52 +252 +219 +138 +234 +225 +211 +224 +215 +208 +129 +110 +98 +116 +0 +0 +212 +0 +0 +238 +0 +0 +252 +111 +1 +252 +182 +0 +254 +201 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +236 +147 +0 +226 +90 +0 +235 +36 +9 +149 +0 +0 +168 +120 +102 +216 +207 +200 +232 +224 +218 +246 +242 +239 +249 +236 +207 +243 +230 +173 +243 +227 +122 +243 +230 +87 +245 +207 +109 +234 +196 +163 +253 +217 +189 +250 +222 +164 +240 +229 +209 +239 +233 +231 +239 +233 +231 +239 +233 +231 +249 +229 +192 +246 +228 +184 +239 +233 +231 +239 +233 +231 +249 +229 +192 +234 +225 +211 +239 +233 +231 +239 +233 +231 +239 +233 +231 +239 +233 +231 +240 +229 +209 +243 +230 +173 +243 +230 +173 +249 +236 +207 +239 +233 +231 +239 +233 +231 +216 +207 +200 +148 +107 +96 +149 +0 +0 +223 +4 +0 +252 +39 +0 +253 +140 +3 +255 +192 +0 +253 +206 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +236 +173 +0 +235 +125 +1 +240 +42 +0 +179 +0 +0 +180 +109 +90 +216 +194 +174 +240 +229 +209 +249 +236 +207 +243 +230 +173 +243 +227 +122 +243 +230 +87 +247 +234 +53 +249 +207 +71 +243 +179 +115 +250 +191 +166 +237 +209 +206 +237 +209 +206 +224 +215 +208 +232 +224 +218 +239 +233 +231 +239 +233 +231 +232 +224 +218 +237 +209 +206 +237 +209 +206 +232 +224 +218 +239 +233 +231 +232 +224 +218 +232 +224 +218 +232 +224 +218 +232 +224 +218 +239 +233 +231 +239 +233 +231 +239 +233 +231 +232 +224 +218 +232 +224 +218 +232 +224 +218 +227 +210 +189 +180 +109 +90 +179 +0 +0 +238 +0 +0 +252 +82 +5 +251 +163 +0 +254 +201 +0 +253 +212 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +247 +158 +17 +252 +82 +5 +229 +54 +6 +199 +98 +76 +224 +207 +170 +224 +207 +170 +246 +228 +184 +245 +230 +150 +243 +230 +87 +247 +234 +53 +249 +226 +16 +253 +218 +0 +247 +174 +61 +255 +165 +114 +250 +191 +166 +232 +185 +177 +232 +185 +177 +232 +185 +177 +224 +215 +208 +224 +215 +208 +237 +209 +206 +232 +185 +177 +232 +185 +177 +237 +209 +206 +224 +215 +208 +234 +225 +211 +234 +225 +211 +234 +225 +211 +234 +225 +211 +232 +224 +218 +234 +225 +211 +240 +229 +209 +240 +229 +209 +234 +225 +211 +224 +215 +208 +224 +207 +170 +199 +98 +76 +204 +17 +0 +251 +62 +1 +255 +125 +0 +255 +192 +0 +253 +212 +0 +251 +222 +3 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +176 +0 +250 +122 +6 +239 +71 +0 +214 +102 +32 +231 +192 +138 +224 +207 +170 +243 +230 +173 +243 +227 +122 +243 +230 +87 +249 +226 +16 +249 +226 +16 +251 +222 +3 +254 +185 +33 +248 +149 +70 +239 +136 +103 +237 +142 +131 +237 +142 +131 +237 +142 +131 +232 +185 +177 +216 +207 +200 +232 +185 +177 +223 +147 +134 +237 +142 +131 +232 +185 +177 +216 +194 +174 +227 +210 +189 +227 +210 +189 +227 +210 +189 +227 +210 +189 +227 +210 +189 +224 +207 +170 +224 +207 +170 +224 +207 +170 +234 +225 +211 +216 +207 +200 +216 +198 +139 +214 +102 +32 +252 +94 +0 +252 +94 +0 +251 +163 +0 +253 +206 +0 +253 +218 +0 +253 +235 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +251 +222 +3 +253 +206 +0 +255 +151 +0 +252 +94 +0 +250 +122 +6 +228 +174 +82 +231 +192 +138 +226 +201 +122 +243 +227 +122 +243 +230 +87 +249 +226 +16 +249 +226 +16 +251 +222 +3 +253 +212 +0 +247 +158 +17 +248 +112 +57 +232 +93 +65 +230 +94 +76 +229 +105 +88 +237 +142 +131 +217 +188 +181 +215 +157 +140 +229 +105 +88 +229 +105 +88 +223 +147 +134 +234 +196 +163 +234 +196 +163 +231 +192 +138 +224 +207 +170 +224 +207 +170 +224 +207 +170 +216 +198 +139 +216 +198 +139 +224 +207 +170 +227 +210 +189 +224 +207 +170 +245 +207 +109 +236 +147 +0 +252 +111 +1 +255 +145 +0 +255 +192 +0 +251 +222 +3 +254 +227 +0 +252 +241 +0 +252 +241 +0 +252 +241 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +254 +227 +0 +254 +227 +0 +254 +176 +0 +252 +111 +1 +250 +122 +6 +253 +164 +50 +228 +174 +82 +226 +201 +122 +241 +219 +98 +247 +223 +55 +249 +226 +16 +249 +226 +16 +251 +222 +3 +253 +218 +0 +250 +190 +17 +250 +122 +6 +248 +83 +28 +243 +69 +41 +236 +73 +58 +229 +105 +88 +223 +147 +134 +223 +122 +99 +236 +73 +58 +236 +73 +58 +223 +122 +99 +233 +162 +120 +243 +179 +115 +232 +189 +115 +232 +189 +115 +226 +201 +122 +226 +201 +122 +226 +201 +122 +226 +201 +122 +216 +198 +139 +224 +207 +170 +226 +201 +122 +249 +207 +71 +251 +163 +0 +252 +132 +0 +254 +176 +0 +253 +218 +0 +254 +227 +0 +252 +241 +0 +253 +247 +0 +253 +247 +0 +253 +247 +0 +253 +247 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +241 +0 +253 +235 +0 +253 +218 +0 +255 +145 +0 +252 +111 +1 +247 +158 +17 +247 +174 +61 +245 +207 +109 +241 +219 +98 +247 +223 +55 +249 +226 +16 +249 +226 +16 +249 +226 +16 +251 +222 +3 +253 +206 +0 +251 +163 +0 +255 +103 +0 +251 +62 +1 +235 +36 +9 +236 +73 +58 +230 +94 +76 +236 +73 +58 +235 +36 +9 +243 +69 +41 +248 +126 +98 +230 +148 +90 +252 +165 +79 +247 +174 +61 +249 +189 +72 +245 +204 +88 +245 +204 +88 +241 +219 +98 +245 +207 +109 +226 +201 +122 +216 +198 +139 +245 +204 +88 +250 +190 +17 +255 +151 +0 +251 +163 +0 +253 +212 +0 +254 +227 +0 +252 +241 +0 +252 +241 +0 +253 +247 +0 +253 +247 +0 +253 +247 +0 +252 +253 +0 +253 +247 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +247 +0 +252 +241 +0 +253 +235 +0 +255 +192 +0 +255 +125 +0 +255 +125 +0 +235 +125 +1 +246 +135 +42 +237 +149 +36 +247 +172 +33 +236 +173 +0 +246 +202 +21 +253 +212 +0 +249 +226 +16 +253 +212 +0 +250 +190 +17 +252 +132 +0 +252 +82 +5 +240 +42 +0 +235 +36 +9 +243 +69 +41 +235 +36 +9 +240 +42 +0 +248 +83 +28 +249 +123 +63 +248 +149 +70 +237 +149 +36 +247 +172 +33 +254 +185 +33 +247 +172 +33 +237 +149 +36 +237 +149 +36 +221 +134 +23 +216 +126 +60 +216 +126 +60 +237 +149 +36 +251 +163 +0 +251 +163 +0 +254 +201 +0 +254 +227 +0 +254 +227 +0 +252 +241 +0 +253 +247 +0 +253 +247 +0 +253 +247 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +253 +0 +252 +253 +0 +253 +247 +0 +254 +201 +0 +255 +125 +0 +255 +87 +0 +248 +98 +10 +246 +135 +42 +237 +149 +36 +236 +147 +0 +236 +147 +0 +247 +158 +17 +249 +171 +5 +249 +171 +5 +254 +185 +33 +250 +190 +17 +251 +163 +0 +252 +111 +1 +251 +62 +1 +240 +42 +0 +240 +42 +0 +253 +53 +0 +251 +62 +1 +247 +98 +31 +243 +119 +33 +248 +147 +35 +247 +158 +17 +250 +122 +6 +252 +82 +5 +241 +61 +2 +239 +71 +0 +252 +94 +0 +216 +93 +0 +242 +132 +58 +242 +132 +58 +248 +147 +35 +253 +140 +3 +255 +145 +0 +252 +182 +0 +254 +227 +0 +253 +235 +0 +252 +241 +0 +252 +241 +0 +253 +247 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +253 +0 +253 +247 +0 +254 +227 +0 +254 +201 +0 +255 +192 +0 +254 +201 +0 +249 +207 +71 +245 +207 +109 +245 +207 +109 +250 +206 +52 +246 +202 +21 +252 +182 +0 +253 +156 +0 +236 +147 +0 +247 +145 +3 +253 +140 +3 +255 +145 +0 +252 +132 +0 +252 +82 +5 +251 +62 +1 +253 +53 +0 +251 +62 +1 +252 +82 +5 +248 +98 +10 +252 +132 +0 +252 +132 +0 +253 +73 +0 +252 +39 +0 +252 +39 +0 +253 +53 +0 +248 +98 +10 +254 +185 +33 +249 +207 +71 +252 +219 +138 +250 +222 +164 +254 +225 +88 +251 +222 +3 +253 +212 +0 +255 +192 +0 +252 +182 +0 +253 +218 +0 +252 +241 +0 +252 +241 +0 +253 +247 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +252 +253 +0 +253 +247 +0 +253 +235 +0 +253 +235 +0 +249 +226 +16 +247 +223 +55 +245 +207 +109 +255 +212 +149 +252 +219 +138 +254 +225 +88 +247 +223 +55 +251 +222 +3 +250 +190 +17 +251 +163 +0 +236 +147 +0 +252 +132 +0 +252 +82 +5 +255 +87 +0 +255 +103 +0 +253 +73 +0 +253 +73 +0 +252 +82 +5 +255 +103 +0 +250 +122 +6 +250 +122 +6 +253 +53 +0 +253 +53 +0 +253 +53 +0 +253 +73 +0 +252 +111 +1 +254 +201 +0 +247 +223 +55 +241 +219 +98 +251 +212 +160 +251 +212 +160 +252 +219 +138 +254 +225 +88 +249 +226 +16 +254 +227 +0 +253 +212 +0 +254 +201 +0 +254 +227 +0 +253 +247 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +247 +0 +253 +247 +0 +253 +247 +0 +252 +241 +0 +251 +222 +3 +249 +207 +71 +253 +197 +105 +243 +179 +115 +253 +177 +133 +243 +179 +115 +254 +195 +91 +250 +206 +52 +253 +218 +0 +253 +218 +0 +249 +171 +5 +251 +163 +0 +247 +145 +3 +252 +111 +1 +252 +39 +0 +252 +82 +5 +252 +94 +0 +252 +94 +0 +255 +103 +0 +255 +125 +0 +252 +132 +0 +251 +62 +1 +251 +62 +1 +253 +73 +0 +255 +87 +0 +255 +103 +0 +249 +171 +5 +253 +212 +0 +250 +206 +52 +253 +197 +105 +252 +189 +140 +253 +177 +133 +253 +177 +133 +254 +182 +99 +254 +195 +91 +250 +206 +52 +251 +222 +3 +251 +222 +3 +254 +227 +0 +253 +247 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +235 +0 +253 +247 +0 +253 +235 +0 +246 +202 +21 +247 +174 +61 +248 +149 +70 +248 +143 +92 +248 +143 +92 +248 +143 +92 +248 +143 +92 +248 +149 +70 +247 +174 +61 +250 +190 +17 +253 +206 +0 +250 +190 +17 +251 +163 +0 +247 +158 +17 +252 +132 +0 +251 +62 +1 +254 +23 +0 +252 +111 +1 +252 +111 +1 +255 +125 +0 +255 +145 +0 +252 +94 +0 +253 +73 +0 +255 +87 +0 +255 +103 +0 +252 +111 +1 +253 +140 +3 +250 +190 +17 +250 +190 +17 +247 +172 +33 +248 +149 +70 +248 +143 +92 +248 +143 +92 +248 +143 +92 +248 +143 +92 +248 +143 +92 +252 +165 +79 +254 +185 +33 +251 +222 +3 +253 +235 +0 +252 +241 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +253 +235 +0 +252 +241 +0 +253 +206 +0 +248 +147 +35 +249 +123 +63 +248 +112 +57 +248 +112 +57 +248 +112 +57 +248 +112 +57 +248 +112 +57 +248 +112 +57 +246 +135 +42 +247 +158 +17 +250 +190 +17 +252 +182 +0 +249 +171 +5 +251 +163 +0 +247 +145 +3 +252 +111 +1 +252 +39 +0 +252 +94 +0 +253 +140 +3 +255 +151 +0 +255 +151 +0 +255 +87 +0 +252 +94 +0 +252 +111 +1 +255 +125 +0 +253 +140 +3 +253 +156 +0 +252 +182 +0 +247 +172 +33 +246 +135 +42 +249 +123 +63 +248 +112 +57 +248 +112 +57 +248 +112 +57 +248 +112 +57 +248 +112 +57 +248 +112 +57 +246 +135 +42 +254 +185 +33 +253 +218 +0 +253 +235 +0 +252 +253 +0 +252 +253 +0 +252 +253 +0 +253 +247 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +226 +204 +5 +254 +227 +0 +253 +212 +0 +253 +156 +0 +247 +98 +31 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +92 +36 +252 +111 +1 +247 +145 +3 +249 +171 +5 +249 +171 +5 +251 +163 +0 +247 +158 +17 +253 +140 +3 +252 +94 +0 +252 +111 +1 +251 +163 +0 +251 +163 +0 +253 +156 +0 +255 +103 +0 +250 +122 +6 +252 +132 +0 +255 +151 +0 +251 +163 +0 +251 +163 +0 +251 +163 +0 +252 +132 +0 +247 +98 +31 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +83 +28 +248 +92 +36 +250 +122 +6 +247 +145 +3 +251 +163 +0 +251 +222 +3 +252 +241 +0 +237 +235 +0 +237 +235 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +191 +187 +0 +212 +179 +0 +249 +171 +5 +235 +125 +1 +248 +98 +10 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +248 +98 +10 +247 +145 +3 +249 +171 +5 +251 +163 +0 +247 +158 +17 +247 +145 +3 +252 +132 +0 +253 +140 +3 +249 +171 +5 +252 +182 +0 +251 +163 +0 +252 +132 +0 +253 +140 +3 +253 +156 +0 +249 +171 +5 +254 +176 +0 +247 +158 +17 +250 +122 +6 +239 +71 +0 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +241 +61 +2 +240 +42 +0 +241 +61 +2 +229 +54 +6 +212 +142 +16 +191 +187 +0 +214 +208 +7 +214 +208 +7 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +180 +177 +1 +180 +177 +1 +190 +156 +11 +215 +80 +5 +235 +36 +9 +235 +36 +9 +235 +36 +9 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +235 +36 +9 +229 +54 +6 +243 +119 +33 +247 +158 +17 +253 +156 +0 +247 +145 +3 +236 +147 +0 +247 +145 +3 +236 +173 +0 +236 +173 +0 +236 +173 +0 +236 +173 +0 +247 +158 +17 +251 +163 +0 +249 +171 +5 +249 +171 +5 +253 +156 +0 +250 +122 +6 +239 +71 +0 +235 +36 +9 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +240 +42 +0 +223 +4 +0 +223 +4 +0 +212 +0 +0 +161 +114 +0 +141 +135 +0 +166 +163 +1 +180 +177 +1 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +180 +177 +1 +166 +163 +1 +141 +135 +0 +161 +114 +0 +187 +54 +1 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +194 +44 +0 +194 +44 +0 +194 +44 +0 +216 +93 +0 +236 +147 +0 +223 +150 +0 +236 +147 +0 +223 +150 +0 +190 +156 +11 +212 +179 +0 +212 +179 +0 +212 +179 +0 +212 +179 +0 +212 +179 +0 +236 +173 +0 +236 +173 +0 +223 +150 +0 +221 +134 +23 +216 +93 +0 +194 +44 +0 +194 +44 +0 +194 +44 +0 +194 +44 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +202 +42 +0 +194 +44 +0 +178 +109 +17 +141 +135 +0 +141 +135 +0 +141 +135 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +135 +126 +11 +135 +126 +11 +135 +126 +11 +141 +135 +0 +166 +163 +1 +180 +177 +1 +180 +177 +1 +180 +177 +1 +180 +177 +1 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +180 +177 +1 +166 +163 +1 +141 +135 +0 +135 +126 +11 +135 +126 +11 +135 +126 +11 +135 +126 +11 +135 +126 +11 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +141 +135 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +180 +177 +1 +180 +177 +1 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +191 +187 +0 +180 +177 +1 +166 +163 +1 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 +0 +1 +0 diff --git a/pkgs/core/kernel/kernel.nm b/pkgs/core/kernel/kernel.nm new file mode 100644 index 0000000..27fc3f9 --- /dev/null +++ b/pkgs/core/kernel/kernel.nm @@ -0,0 +1,110 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = linux +PKG_VER = 2.6.31.1 +PKG_REL = 0 + +PKG_MAINTAINER = Michael Tremer <michael.tremer@ipfire.org> +PKG_GROUP = System/Kernels +PKG_URL = http://www.kernel.org/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = The Linux kernel. + +define PKG_DESCRIPTION + The kernel package contains the Linux kernel (vmlinuz), the core of any \ + Linux operating system. The kernel handles the basic functions \ + of the operating system: memory allocation, process allocation, device \ + input and output, etc. +endef + +CFLAGS = +CXXFLAGS = + +LOCALVERSION = -ipfire1 +FULLVER = $(PKG_VER)$(LOCALVERSION) + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && echo "$(LOCALVERSION)" > localversion-ipfire + rm -f $(DIR_APP)/localversion-grsec + + cd $(DIR_APP) && sed -e "s/^HOSTCFLAGS.*=.*/& -fPIC/g" -i Makefile + + #cd $(DIR_APP) && echo "source "crypto/ocf/Kconfig"" >> crypto/Kconfig + + cd $(DIR_APP) && cp -vf $(DIR_SOURCE)/$(DISTRO_SNAME)_logo.ppm \ + drivers/video/logo/logo_linux_clut224.ppm +endef + +define STAGE_BUILD + cd $(DIR_APP) && make mrproper + + # Select right optimization for the linux kernel. + if [ "$(TARGET)" == "i486" ]; then \ + sed -e "s/^CONFIG_M686=y/# CONFIG_686 is not set/" \ + -e "s/^# CONFIG_M486 is not set/CONFIG_M486=y/" \ + < $(DIR_SOURCE)/config > $(DIR_APP)/.config; \ + elif [ "$(TARGET)" == "i586" ]; then \ + sed -e "s/^CONFIG_M686=y/# CONFIG_686 is not set/" \ + -e "s/^# CONFIG_M586TSC is not set/CONFIG_M586TSC=y/" \ + < $(DIR_SOURCE)/config > $(DIR_APP)/.config; \ + elif [ "$(TARGET)" == "via-c7" ]; then \ + sed -e "s/^CONFIG_M686=y/# CONFIG_686 is not set/" \ + -e "s/^# CONFIG_MVIAC7 is not set/CONFIG_MVIAC7=y/" \ + < $(DIR_SOURCE)/config > $(DIR_APP)/.config; \ + elif [ "$(TARGET)" == "via-c3" ]; then \ + sed -e "s/^CONFIG_M686=y/# CONFIG_686 is not set/" \ + -e "s/^# CONFIG_MVIAC3_2 is not set/CONFIG_MVIAC3_2=y/" \ + < $(DIR_SOURCE)/config > $(DIR_APP)/.config; \ + else \ + cp -f $(DIR_SOURCE)/config $(DIR_APP)/.config; \ + fi + + cd $(DIR_APP) && yes "" | make oldconfig + + cd $(DIR_APP) && make CC="gcc -nopie" $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make modules_install INSTALL_MOD_PATH=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/boot + cd $(DIR_APP) && cp -v arch/x86/boot/bzImage $(BUILDROOT)/boot/$(DISTRO_SNAME)kernel-$(FULLVER) + cd $(DIR_APP) && cp -v System.map $(BUILDROOT)/boot/System.map-$(FULLVER) + + ln -svf $(SNAME)kernel-$(FULLVER) $(BUILDROOT)/boot/$(DISTRO_SNAME)kernel + ln -svf System.map-$(FULLVER) $(BUILDROOT)/boot/System.map + + -mkdir -pv $(BUILDROOT)/lib/modules/$(FULLVER)/extra + + rm -vf $(BUILDROOT)/lib/modules/$(FULLVER)/{build,source} +endef diff --git a/pkgs/core/kernel/patches/aufs2-2.6.31.1-1.patch b/pkgs/core/kernel/patches/aufs2-2.6.31.1-1.patch new file mode 100644 index 0000000..1f6f612 --- /dev/null +++ b/pkgs/core/kernel/patches/aufs2-2.6.31.1-1.patch @@ -0,0 +1,25456 @@ +diff -Nur linux-2.6.31-vanilla/Documentation/ABI/testing/debugfs-aufs linux-2.6.31/Documentation/ABI/testing/debugfs-aufs +--- linux-2.6.31-vanilla/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/Documentation/ABI/testing/debugfs-aufs 2009-09-16 13:55:29.000000000 +0200 +@@ -0,0 +1,40 @@ ++What: /debug/aufs/si_<id>/ ++Date: March 2009 ++Contact: J. R. Okajima <hooanon05@yahoo.co.jp> ++Description: ++ Under /debug/aufs, a directory named si_<id> is created ++ per aufs mount, where <id> is a unique id generated ++ internally. ++ ++What: /debug/aufs/si_<id>/xib ++Date: March 2009 ++Contact: J. R. Okajima <hooanon05@yahoo.co.jp> ++Description: ++ It shows the consumed blocks by xib (External Inode Number ++ Bitmap), its block size and file size. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. ++ ++What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN ++Date: March 2009 ++Contact: J. R. Okajima <hooanon05@yahoo.co.jp> ++Description: ++ It shows the consumed blocks by xino (External Inode Number ++ Translation Table), its link count, block size and file ++ size. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. ++ ++What: /debug/aufs/si_<id>/xigen ++Date: March 2009 ++Contact: J. R. Okajima <hooanon05@yahoo.co.jp> ++Description: ++ It shows the consumed blocks by xigen (External Inode ++ Generation Table), its block size and file size. ++ If CONFIG_AUFS_EXPORT is disabled, this entry will not ++ be created. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. +diff -Nur linux-2.6.31-vanilla/Documentation/ABI/testing/sysfs-aufs linux-2.6.31/Documentation/ABI/testing/sysfs-aufs +--- linux-2.6.31-vanilla/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/Documentation/ABI/testing/sysfs-aufs 2009-09-16 13:55:29.000000000 +0200 +@@ -0,0 +1,25 @@ ++What: /sys/fs/aufs/si_<id>/ ++Date: March 2009 ++Contact: J. R. Okajima <hooanon05@yahoo.co.jp> ++Description: ++ Under /sys/fs/aufs, a directory named si_<id> is created ++ per aufs mount, where <id> is a unique id generated ++ internally. ++ ++What: /sys/fs/aufs/si_<id>/br0, br1 ... brN ++Date: March 2009 ++Contact: J. R. Okajima <hooanon05@yahoo.co.jp> ++Description: ++ It shows the abolute path of a member directory (which ++ is called branch) in aufs, and its permission. ++ ++What: /sys/fs/aufs/si_<id>/xi_path ++Date: March 2009 ++Contact: J. R. Okajima <hooanon05@yahoo.co.jp> ++Description: ++ It shows the abolute path of XINO (External Inode Number ++ Bitmap, Translation Table and Generation Table) file ++ even if it is the default path. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see ++ Documentation/filesystems/aufs/aufs.5 in detail. +diff -Nur linux-2.6.31-vanilla/fs/aufs/aufs.h linux-2.6.31/fs/aufs/aufs.h +--- linux-2.6.31-vanilla/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/aufs.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * all header files ++ */ ++ ++#ifndef __AUFS_H__ ++#define __AUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include "debug.h" ++ ++#include "branch.h" ++#include "cpup.h" ++#include "dcsub.h" ++#include "dbgaufs.h" ++#include "dentry.h" ++#include "dir.h" ++#include "file.h" ++#include "fstype.h" ++#include "inode.h" ++#include "loop.h" ++#include "module.h" ++#include "opts.h" ++#include "rwsem.h" ++#include "spl.h" ++#include "super.h" ++#include "sysaufs.h" ++#include "vfsub.h" ++#include "whout.h" ++#include "wkq.h" ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/branch.c linux-2.6.31/fs/aufs/branch.c +--- linux-2.6.31-vanilla/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/branch.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,969 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * branch management ++ */ ++ ++#include <linux/file.h> ++#include "aufs.h" ++ ++/* ++ * free a single branch ++ */ ++static void au_br_do_free(struct au_branch *br) ++{ ++ int i; ++ struct au_wbr *wbr; ++ ++ if (br->br_xino.xi_file) ++ fput(br->br_xino.xi_file); ++ mutex_destroy(&br->br_xino.xi_nondir_mtx); ++ ++ AuDebugOn(atomic_read(&br->br_count)); ++ ++ wbr = br->br_wbr; ++ if (wbr) { ++ for (i = 0; i < AuBrWh_Last; i++) ++ dput(wbr->wbr_wh[i]); ++ AuDebugOn(atomic_read(&wbr->wbr_wh_running)); ++ AuRwDestroy(&wbr->wbr_wh_rwsem); ++ } ++ ++ /* some filesystems acquire extra lock */ ++ lockdep_off(); ++ mntput(br->br_mnt); ++ lockdep_on(); ++ ++ kfree(wbr); ++ kfree(br); ++} ++ ++/* ++ * frees all branches ++ */ ++void au_br_free(struct au_sbinfo *sbinfo) ++{ ++ aufs_bindex_t bmax; ++ struct au_branch **br; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ bmax = sbinfo->si_bend + 1; ++ br = sbinfo->si_branch; ++ while (bmax--) ++ au_br_do_free(*br++); ++} ++ ++/* ++ * find the index of a branch which is specified by @br_id. ++ */ ++int au_br_index(struct super_block *sb, aufs_bindex_t br_id) ++{ ++ aufs_bindex_t bindex, bend; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (au_sbr_id(sb, bindex) == br_id) ++ return bindex; ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * add a branch ++ */ ++ ++static int test_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2) ++{ ++ if (unlikely(h_d1 == h_d2)) ++ return 1; ++ return !!au_test_subdir(h_d1, h_d2) ++ || !!au_test_subdir(h_d2, h_d1) ++ || au_test_loopback_overlap(sb, h_d1, h_d2) ++ || au_test_loopback_overlap(sb, h_d2, h_d1); ++} ++ ++/* ++ * returns a newly allocated branch. @new_nbranch is a number of branches ++ * after adding a branch. ++ */ ++static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch, ++ int perm) ++{ ++ struct au_branch *add_branch; ++ struct dentry *root; ++ ++ root = sb->s_root; ++ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS); ++ if (unlikely(!add_branch)) ++ goto out; ++ ++ add_branch->br_wbr = NULL; ++ if (au_br_writable(perm)) { ++ /* may be freed separately at changing the branch permission */ ++ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr), ++ GFP_NOFS); ++ if (unlikely(!add_branch->br_wbr)) ++ goto out_br; ++ } ++ ++ if (unlikely(au_sbr_realloc(au_sbi(sb), new_nbranch) ++ || au_di_realloc(au_di(root), new_nbranch) ++ || au_ii_realloc(au_ii(root->d_inode), new_nbranch))) ++ goto out_wbr; ++ return add_branch; /* success */ ++ ++ out_wbr: ++ kfree(add_branch->br_wbr); ++ out_br: ++ kfree(add_branch); ++ out: ++ return ERR_PTR(-ENOMEM); ++} ++ ++/* ++ * test if the branch permission is legal or not. ++ */ ++static int test_br(struct inode *inode, int brperm, char *path) ++{ ++ int err; ++ ++ err = 0; ++ if (unlikely(au_br_writable(brperm) && IS_RDONLY(inode))) { ++ AuErr("write permission for readonly mount or inode, %s\n", ++ path); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++/* ++ * returns: ++ * 0: success, the caller will add it ++ * plus: success, it is already unified, the caller should ignore it ++ * minus: error ++ */ ++static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct dentry *root; ++ struct inode *inode, *h_inode; ++ ++ root = sb->s_root; ++ bend = au_sbend(sb); ++ if (unlikely(bend >= 0 ++ && au_find_dbindex(root, add->path.dentry) >= 0)) { ++ err = 1; ++ if (!remount) { ++ err = -EINVAL; ++ AuErr("%s duplicated\n", add->pathname); ++ } ++ goto out; ++ } ++ ++ err = -ENOSPC; /* -E2BIG; */ ++ if (unlikely(AUFS_BRANCH_MAX <= add->bindex ++ || AUFS_BRANCH_MAX - 1 <= bend)) { ++ AuErr("number of branches exceeded %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EDOM; ++ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) { ++ AuErr("bad index %d\n", add->bindex); ++ goto out; ++ } ++ ++ inode = add->path.dentry->d_inode; ++ err = -ENOENT; ++ if (unlikely(!inode->i_nlink)) { ++ AuErr("no existence %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ if (unlikely(inode->i_sb == sb)) { ++ AuErr("%s must be outside\n", add->pathname); ++ goto out; ++ } ++ ++ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) { ++ AuErr("unsupported filesystem, %s (%s)\n", ++ add->pathname, au_sbtype(inode->i_sb)); ++ goto out; ++ } ++ ++ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname); ++ if (unlikely(err)) ++ goto out; ++ ++ if (bend < 0) ++ return 0; /* success */ ++ ++ err = -EINVAL; ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (unlikely(test_overlap(sb, add->path.dentry, ++ au_h_dptr(root, bindex)))) { ++ AuErr("%s is overlapped\n", add->pathname); ++ goto out; ++ } ++ ++ err = 0; ++ if (au_opt_test(au_mntflags(sb), WARN_PERM)) { ++ h_inode = au_h_dptr(root, 0)->d_inode; ++ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO) ++ || h_inode->i_uid != inode->i_uid ++ || h_inode->i_gid != inode->i_gid) ++ AuWarn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", ++ add->pathname, ++ inode->i_uid, inode->i_gid, ++ (inode->i_mode & S_IALLUGO), ++ h_inode->i_uid, h_inode->i_gid, ++ (h_inode->i_mode & S_IALLUGO)); ++ } ++ ++ out: ++ return err; ++} ++ ++/* ++ * initialize or clean the whiteouts for an adding branch ++ */ ++static int au_br_init_wh(struct super_block *sb, struct au_branch *br, ++ int new_perm, struct dentry *h_root) ++{ ++ int err, old_perm; ++ aufs_bindex_t bindex; ++ struct mutex *h_mtx; ++ struct au_wbr *wbr; ++ struct au_hinode *hdir; ++ ++ wbr = br->br_wbr; ++ old_perm = br->br_perm; ++ br->br_perm = new_perm; ++ hdir = NULL; ++ h_mtx = NULL; ++ bindex = au_br_index(sb, br->br_id); ++ if (0 <= bindex) { ++ hdir = au_hi(sb->s_root->d_inode, bindex); ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ } else { ++ h_mtx = &h_root->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_PARENT); ++ } ++ if (!wbr) ++ err = au_wh_init(h_root, br, sb); ++ else { ++ wbr_wh_write_lock(wbr); ++ err = au_wh_init(h_root, br, sb); ++ wbr_wh_write_unlock(wbr); ++ } ++ if (hdir) ++ au_hin_imtx_unlock(hdir); ++ else ++ mutex_unlock(h_mtx); ++ br->br_perm = old_perm; ++ ++ if (!err && wbr && !au_br_writable(new_perm)) { ++ kfree(wbr); ++ br->br_wbr = NULL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_init(struct au_branch *br, struct super_block *sb, ++ int perm, struct path *path) ++{ ++ int err; ++ struct au_wbr *wbr; ++ ++ wbr = br->br_wbr; ++ au_rw_init(&wbr->wbr_wh_rwsem); ++ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh)); ++ atomic_set(&wbr->wbr_wh_running, 0); ++ wbr->wbr_bytes = 0; ++ ++ err = au_br_init_wh(sb, br, perm, path->dentry); ++ ++ return err; ++} ++ ++/* intialize a new branch */ ++static int au_br_init(struct au_branch *br, struct super_block *sb, ++ struct au_opt_add *add) ++{ ++ int err; ++ ++ err = 0; ++ memset(&br->br_xino, 0, sizeof(br->br_xino)); ++ mutex_init(&br->br_xino.xi_nondir_mtx); ++ br->br_perm = add->perm; ++ br->br_mnt = add->path.mnt; /* set first, mntget() later */ ++ atomic_set(&br->br_count, 0); ++ br->br_xino_upper = AUFS_XINO_TRUNC_INIT; ++ atomic_set(&br->br_xino_running, 0); ++ br->br_id = au_new_br_id(sb); ++ ++ if (au_br_writable(add->perm)) { ++ err = au_wbr_init(br, sb, add->perm, &add->path); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ if (au_opt_test(au_mntflags(sb), XINO)) { ++ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino, ++ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1); ++ if (unlikely(err)) { ++ AuDebugOn(br->br_xino.xi_file); ++ goto out; ++ } ++ } ++ ++ sysaufs_br_init(br); ++ mntget(add->path.mnt); ++ ++ out: ++ return err; ++} ++ ++static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex, ++ struct au_branch *br, aufs_bindex_t bend, ++ aufs_bindex_t amount) ++{ ++ struct au_branch **brp; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ brp = sbinfo->si_branch + bindex; ++ memmove(brp + 1, brp, sizeof(*brp) * amount); ++ *brp = br; ++ sbinfo->si_bend++; ++ if (unlikely(bend < 0)) ++ sbinfo->si_bend = 0; ++} ++ ++static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex, ++ aufs_bindex_t bend, aufs_bindex_t amount) ++{ ++ struct au_hdentry *hdp; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ hdp = dinfo->di_hdentry + bindex; ++ memmove(hdp + 1, hdp, sizeof(*hdp) * amount); ++ au_h_dentry_init(hdp); ++ dinfo->di_bend++; ++ if (unlikely(bend < 0)) ++ dinfo->di_bstart = 0; ++} ++ ++static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex, ++ aufs_bindex_t bend, aufs_bindex_t amount) ++{ ++ struct au_hinode *hip; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ hip = iinfo->ii_hinode + bindex; ++ memmove(hip + 1, hip, sizeof(*hip) * amount); ++ hip->hi_inode = NULL; ++ au_hin_init(hip, NULL); ++ iinfo->ii_bend++; ++ if (unlikely(bend < 0)) ++ iinfo->ii_bstart = 0; ++} ++ ++static void au_br_do_add(struct super_block *sb, struct dentry *h_dentry, ++ struct au_branch *br, aufs_bindex_t bindex) ++{ ++ struct dentry *root; ++ struct inode *root_inode; ++ aufs_bindex_t bend, amount; ++ ++ root = sb->s_root; ++ root_inode = root->d_inode; ++ au_plink_block_maintain(sb); ++ bend = au_sbend(sb); ++ amount = bend + 1 - bindex; ++ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount); ++ au_br_do_add_hdp(au_di(root), bindex, bend, amount); ++ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount); ++ au_set_h_dptr(root, bindex, dget(h_dentry)); ++ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode), ++ /*flags*/0); ++} ++ ++int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount) ++{ ++ int err; ++ aufs_bindex_t bend, add_bindex; ++ struct dentry *root, *h_dentry; ++ struct inode *root_inode; ++ struct au_branch *add_branch; ++ ++ root = sb->s_root; ++ root_inode = root->d_inode; ++ IMustLock(root_inode); ++ err = test_add(sb, add, remount); ++ if (unlikely(err < 0)) ++ goto out; ++ if (err) { ++ err = 0; ++ goto out; /* success */ ++ } ++ ++ bend = au_sbend(sb); ++ add_branch = au_br_alloc(sb, bend + 2, add->perm); ++ err = PTR_ERR(add_branch); ++ if (IS_ERR(add_branch)) ++ goto out; ++ ++ err = au_br_init(add_branch, sb, add); ++ if (unlikely(err)) { ++ au_br_do_free(add_branch); ++ goto out; ++ } ++ ++ add_bindex = add->bindex; ++ h_dentry = add->path.dentry; ++ if (!remount) ++ au_br_do_add(sb, h_dentry, add_branch, add_bindex); ++ else { ++ sysaufs_brs_del(sb, add_bindex); ++ au_br_do_add(sb, h_dentry, add_branch, add_bindex); ++ sysaufs_brs_add(sb, add_bindex); ++ } ++ ++ if (!add_bindex) { ++ au_cpup_attr_all(root_inode, /*force*/1); ++ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes; ++ } else ++ au_add_nlink(root_inode, h_dentry->d_inode); ++ ++ /* ++ * this test/set prevents aufs from handling unnecesary inotify events ++ * of xino files, in a case of re-adding a writable branch which was ++ * once detached from aufs. ++ */ ++ if (au_xino_brid(sb) < 0 ++ && au_br_writable(add_branch->br_perm) ++ && !au_test_fs_bad_xino(h_dentry->d_sb) ++ && add_branch->br_xino.xi_file ++ && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry) ++ au_xino_brid_set(sb, add_branch->br_id); ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * delete a branch ++ */ ++ ++/* to show the line number, do not make it inlined function */ ++#define AuVerbose(do_info, fmt, args...) do { \ ++ if (do_info) \ ++ AuInfo(fmt, ##args); \ ++} while (0) ++ ++/* ++ * test if the branch is deletable or not. ++ */ ++static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex, ++ unsigned int sigen) ++{ ++ int err, i, j, ndentry; ++ aufs_bindex_t bstart, bend; ++ unsigned char verbose; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry *d; ++ struct inode *inode; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, root, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ verbose = !!au_opt_test(au_mntflags(root->d_sb), VERBOSE); ++ for (i = 0; !err && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ ndentry = dpage->ndentry; ++ for (j = 0; !err && j < ndentry; j++) { ++ d = dpage->dentries[j]; ++ AuDebugOn(!atomic_read(&d->d_count)); ++ inode = d->d_inode; ++ if (au_digen(d) == sigen && au_iigen(inode) == sigen) ++ di_read_lock_child(d, AuLock_IR); ++ else { ++ di_write_lock_child(d); ++ err = au_reval_dpath(d, sigen); ++ if (!err) ++ di_downgrade_lock(d, AuLock_IR); ++ else { ++ di_write_unlock(d); ++ break; ++ } ++ } ++ ++ bstart = au_dbstart(d); ++ bend = au_dbend(d); ++ if (bstart <= bindex ++ && bindex <= bend ++ && au_h_dptr(d, bindex) ++ && (!S_ISDIR(inode->i_mode) || bstart == bend)) { ++ err = -EBUSY; ++ AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d)); ++ } ++ di_read_unlock(d, AuLock_IR); ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return err; ++} ++ ++static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex, ++ unsigned int sigen) ++{ ++ int err; ++ struct inode *i; ++ aufs_bindex_t bstart, bend; ++ unsigned char verbose; ++ ++ err = 0; ++ verbose = !!au_opt_test(au_mntflags(sb), VERBOSE); ++ list_for_each_entry(i, &sb->s_inodes, i_sb_list) { ++ AuDebugOn(!atomic_read(&i->i_count)); ++ if (!list_empty(&i->i_dentry)) ++ continue; ++ ++ if (au_iigen(i) == sigen) ++ ii_read_lock_child(i); ++ else { ++ ii_write_lock_child(i); ++ err = au_refresh_hinode_self(i, /*do_attr*/1); ++ if (!err) ++ ii_downgrade_lock(i); ++ else { ++ ii_write_unlock(i); ++ break; ++ } ++ } ++ ++ bstart = au_ibstart(i); ++ bend = au_ibend(i); ++ if (bstart <= bindex ++ && bindex <= bend ++ && au_h_iptr(i, bindex) ++ && (!S_ISDIR(i->i_mode) || bstart == bend)) { ++ err = -EBUSY; ++ AuVerbose(verbose, "busy i%lu\n", i->i_ino); ++ ii_read_unlock(i); ++ break; ++ } ++ ii_read_unlock(i); ++ } ++ ++ return err; ++} ++ ++static int test_children_busy(struct dentry *root, aufs_bindex_t bindex) ++{ ++ int err; ++ unsigned int sigen; ++ ++ sigen = au_sigen(root->d_sb); ++ DiMustNoWaiters(root); ++ IiMustNoWaiters(root->d_inode); ++ di_write_unlock(root); ++ err = test_dentry_busy(root, bindex, sigen); ++ if (!err) ++ err = test_inode_busy(root->d_sb, bindex, sigen); ++ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */ ++ ++ return err; ++} ++ ++static void au_br_do_del_brp(struct au_sbinfo *sbinfo, ++ const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_branch **brp, **p; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ brp = sbinfo->si_branch + bindex; ++ if (bindex < bend) ++ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex)); ++ sbinfo->si_branch[0 + bend] = NULL; ++ sbinfo->si_bend--; ++ ++ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, GFP_NOFS); ++ if (p) ++ sbinfo->si_branch = p; ++} ++ ++static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_hdentry *hdp, *p; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ hdp = dinfo->di_hdentry + bindex; ++ if (bindex < bend) ++ memmove(hdp, hdp + 1, sizeof(*hdp) * (bend - bindex)); ++ dinfo->di_hdentry[0 + bend].hd_dentry = NULL; ++ dinfo->di_bend--; ++ ++ p = krealloc(dinfo->di_hdentry, sizeof(*p) * bend, GFP_NOFS); ++ if (p) ++ dinfo->di_hdentry = p; ++} ++ ++static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_hinode *hip, *p; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ hip = iinfo->ii_hinode + bindex; ++ if (bindex < bend) ++ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex)); ++ iinfo->ii_hinode[0 + bend].hi_inode = NULL; ++ au_hin_init(iinfo->ii_hinode + bend, NULL); ++ iinfo->ii_bend--; ++ ++ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, GFP_NOFS); ++ if (p) ++ iinfo->ii_hinode = p; ++} ++ ++static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_branch *br) ++{ ++ aufs_bindex_t bend; ++ struct au_sbinfo *sbinfo; ++ struct dentry *root; ++ struct inode *inode; ++ ++ SiMustWriteLock(sb); ++ ++ root = sb->s_root; ++ inode = root->d_inode; ++ au_plink_block_maintain(sb); ++ sbinfo = au_sbi(sb); ++ bend = sbinfo->si_bend; ++ ++ dput(au_h_dptr(root, bindex)); ++ au_hiput(au_hi(inode, bindex)); ++ au_br_do_free(br); ++ ++ au_br_do_del_brp(sbinfo, bindex, bend); ++ au_br_do_del_hdp(au_di(root), bindex, bend); ++ au_br_do_del_hip(au_ii(inode), bindex, bend); ++} ++ ++int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount) ++{ ++ int err, rerr, i; ++ unsigned int mnt_flags; ++ aufs_bindex_t bindex, bend, br_id; ++ unsigned char do_wh, verbose; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ ++ err = 0; ++ bindex = au_find_dbindex(sb->s_root, del->h_path.dentry); ++ if (bindex < 0) { ++ if (remount) ++ goto out; /* success */ ++ err = -ENOENT; ++ AuErr("%s no such branch\n", del->pathname); ++ goto out; ++ } ++ AuDbg("bindex b%d\n", bindex); ++ ++ err = -EBUSY; ++ mnt_flags = au_mntflags(sb); ++ verbose = !!au_opt_test(mnt_flags, VERBOSE); ++ bend = au_sbend(sb); ++ if (unlikely(!bend)) { ++ AuVerbose(verbose, "no more branches left\n"); ++ goto out; ++ } ++ br = au_sbr(sb, bindex); ++ i = atomic_read(&br->br_count); ++ if (unlikely(i)) { ++ AuVerbose(verbose, "%d file(s) opened\n", i); ++ goto out; ++ } ++ ++ wbr = br->br_wbr; ++ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph); ++ if (do_wh) { ++ /* instead of WbrWhMustWriteLock(wbr) */ ++ SiMustWriteLock(sb); ++ for (i = 0; i < AuBrWh_Last; i++) { ++ dput(wbr->wbr_wh[i]); ++ wbr->wbr_wh[i] = NULL; ++ } ++ } ++ ++ err = test_children_busy(sb->s_root, bindex); ++ if (unlikely(err)) { ++ if (do_wh) ++ goto out_wh; ++ goto out; ++ } ++ ++ err = 0; ++ br_id = br->br_id; ++ if (!remount) ++ au_br_do_del(sb, bindex, br); ++ else { ++ sysaufs_brs_del(sb, bindex); ++ au_br_do_del(sb, bindex, br); ++ sysaufs_brs_add(sb, bindex); ++ } ++ ++ if (!bindex) { ++ au_cpup_attr_all(sb->s_root->d_inode, /*force*/1); ++ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes; ++ } else ++ au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode); ++ if (au_opt_test(mnt_flags, PLINK)) ++ au_plink_half_refresh(sb, br_id); ++ ++ if (au_xino_brid(sb) == br->br_id) ++ au_xino_brid_set(sb, -1); ++ goto out; /* success */ ++ ++ out_wh: ++ /* revert */ ++ rerr = au_br_init_wh(sb, br, br->br_perm, del->h_path.dentry); ++ if (rerr) ++ AuWarn("failed re-creating base whiteout, %s. (%d)\n", ++ del->pathname, rerr); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * change a branch permission ++ */ ++ ++static void au_warn_ima(void) ++{ ++#ifdef CONFIG_IMA ++ AuWarn("RW -> RO makes IMA to produce wrong message"); ++#endif ++} ++ ++static int do_need_sigen_inc(int a, int b) ++{ ++ return au_br_whable(a) && !au_br_whable(b); ++} ++ ++static int need_sigen_inc(int old, int new) ++{ ++ return do_need_sigen_inc(old, new) ++ || do_need_sigen_inc(new, old); ++} ++ ++static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ unsigned long n, ul, bytes, files; ++ aufs_bindex_t bstart; ++ struct file *file, *hf, **a; ++ const int step_bytes = 1024, /* memory allocation unit */ ++ step_files = step_bytes / sizeof(*a); ++ ++ err = -ENOMEM; ++ n = 0; ++ bytes = step_bytes; ++ files = step_files; ++ a = kmalloc(bytes, GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ /* no need file_list_lock() since sbinfo is locked? defered? */ ++ list_for_each_entry(file, &sb->s_files, f_u.fu_list) { ++ if (special_file(file->f_dentry->d_inode->i_mode)) ++ continue; ++ ++ AuDbg("%.*s\n", AuDLNPair(file->f_dentry)); ++ fi_read_lock(file); ++ if (unlikely(au_test_mmapped(file))) { ++ err = -EBUSY; ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ goto out_free; ++ } ++ ++ bstart = au_fbstart(file); ++ if (!S_ISREG(file->f_dentry->d_inode->i_mode) ++ || !(file->f_mode & FMODE_WRITE) ++ || bstart != bindex) { ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ continue; ++ } ++ ++ hf = au_h_fptr(file, bstart); ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ ++ if (n < files) ++ a[n++] = hf; ++ else { ++ void *p; ++ ++ err = -ENOMEM; ++ bytes += step_bytes; ++ files += step_files; ++ p = krealloc(a, bytes, GFP_NOFS); ++ if (p) { ++ a = p; ++ a[n++] = hf; ++ } else ++ goto out_free; ++ } ++ } ++ ++ err = 0; ++ if (n) ++ au_warn_ima(); ++ for (ul = 0; ul < n; ul++) { ++ /* todo: already flushed? */ ++ /* cf. fs/super.c:mark_files_ro() */ ++ hf = a[ul]; ++ hf->f_mode &= ~FMODE_WRITE; ++ if (!file_check_writeable(hf)) { ++ file_release_write(hf); ++ mnt_drop_write(hf->f_vfsmnt); ++ } ++ } ++ ++ out_free: ++ kfree(a); ++ out: ++ return err; ++} ++ ++int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, ++ int *do_update) ++{ ++ int err, rerr; ++ aufs_bindex_t bindex; ++ struct path path; ++ struct dentry *root; ++ struct au_branch *br; ++ ++ root = sb->s_root; ++ au_plink_block_maintain(sb); ++ bindex = au_find_dbindex(root, mod->h_root); ++ if (bindex < 0) { ++ if (remount) ++ return 0; /* success */ ++ err = -ENOENT; ++ AuErr("%s no such branch\n", mod->path); ++ goto out; ++ } ++ AuDbg("bindex b%d\n", bindex); ++ ++ err = test_br(mod->h_root->d_inode, mod->perm, mod->path); ++ if (unlikely(err)) ++ goto out; ++ ++ br = au_sbr(sb, bindex); ++ if (br->br_perm == mod->perm) ++ return 0; /* success */ ++ ++ if (au_br_writable(br->br_perm)) { ++ /* remove whiteout base */ ++ err = au_br_init_wh(sb, br, mod->perm, mod->h_root); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!au_br_writable(mod->perm)) { ++ /* rw --> ro, file might be mmapped */ ++ DiMustNoWaiters(root); ++ IiMustNoWaiters(root->d_inode); ++ di_write_unlock(root); ++ err = au_br_mod_files_ro(sb, bindex); ++ /* aufs_write_lock() calls ..._child() */ ++ di_write_lock_child(root); ++ ++ if (unlikely(err)) { ++ rerr = -ENOMEM; ++ br->br_wbr = kmalloc(sizeof(*br->br_wbr), ++ GFP_NOFS); ++ if (br->br_wbr) { ++ path.mnt = br->br_mnt; ++ path.dentry = mod->h_root; ++ rerr = au_wbr_init(br, sb, br->br_perm, ++ &path); ++ } ++ if (unlikely(rerr)) { ++ AuIOErr("nested error %d (%d)\n", ++ rerr, err); ++ br->br_perm = mod->perm; ++ } ++ } ++ } ++ } else if (au_br_writable(mod->perm)) { ++ /* ro --> rw */ ++ err = -ENOMEM; ++ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS); ++ if (br->br_wbr) { ++ path.mnt = br->br_mnt; ++ path.dentry = mod->h_root; ++ err = au_wbr_init(br, sb, mod->perm, &path); ++ if (unlikely(err)) { ++ kfree(br->br_wbr); ++ br->br_wbr = NULL; ++ } ++ } ++ } ++ ++ if (!err) { ++ *do_update |= need_sigen_inc(br->br_perm, mod->perm); ++ br->br_perm = mod->perm; ++ } ++ ++ out: ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/branch.h linux-2.6.31/fs/aufs/branch.h +--- linux-2.6.31-vanilla/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/branch.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,219 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * branch filesystems and xino for them ++ */ ++ ++#ifndef __AUFS_BRANCH_H__ ++#define __AUFS_BRANCH_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/fs.h> ++#include <linux/mount.h> ++#include <linux/aufs_type.h> ++#include "rwsem.h" ++#include "super.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* a xino file */ ++struct au_xino_file { ++ struct file *xi_file; ++ struct mutex xi_nondir_mtx; ++ ++ /* todo: make xino files an array to support huge inode number */ ++ ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *xi_dbgaufs; ++#endif ++}; ++ ++/* members for writable branch only */ ++enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last}; ++struct au_wbr { ++ struct au_rwsem wbr_wh_rwsem; ++ struct dentry *wbr_wh[AuBrWh_Last]; ++ atomic_t wbr_wh_running; ++#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */ ++#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */ ++#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */ ++ ++ /* mfs mode */ ++ unsigned long long wbr_bytes; ++}; ++ ++/* protected by superblock rwsem */ ++struct au_branch { ++ struct au_xino_file br_xino; ++ ++ aufs_bindex_t br_id; ++ ++ int br_perm; ++ struct vfsmount *br_mnt; ++ atomic_t br_count; ++ ++ struct au_wbr *br_wbr; ++ ++ /* xino truncation */ ++ blkcnt_t br_xino_upper; /* watermark in blocks */ ++ atomic_t br_xino_running; ++ ++#ifdef CONFIG_SYSFS ++ /* an entry under sysfs per mount-point */ ++ char br_name[8]; ++ struct attribute br_attr; ++#endif ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* branch permission and attribute */ ++enum { ++ AuBrPerm_RW, /* writable, linkable wh */ ++ AuBrPerm_RO, /* readonly, no wh */ ++ AuBrPerm_RR, /* natively readonly, no wh */ ++ ++ AuBrPerm_RWNoLinkWH, /* un-linkable whiteouts */ ++ ++ AuBrPerm_ROWH, /* whiteout-able */ ++ AuBrPerm_RRWH, /* whiteout-able */ ++ ++ AuBrPerm_Last ++}; ++ ++static inline int au_br_writable(int brperm) ++{ ++ return brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH; ++} ++ ++static inline int au_br_whable(int brperm) ++{ ++ return brperm == AuBrPerm_RW ++ || brperm == AuBrPerm_ROWH ++ || brperm == AuBrPerm_RRWH; ++} ++ ++static inline int au_br_rdonly(struct au_branch *br) ++{ ++ return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY) ++ || !au_br_writable(br->br_perm)) ++ ? -EROFS : 0; ++} ++ ++static inline int au_br_hinotifyable(int brperm __maybe_unused) ++{ ++#ifdef CONFIG_AUFS_HINOTIFY ++ return brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH; ++#else ++ return 0; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* branch.c */ ++struct au_sbinfo; ++void au_br_free(struct au_sbinfo *sinfo); ++int au_br_index(struct super_block *sb, aufs_bindex_t br_id); ++struct au_opt_add; ++int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); ++struct au_opt_del; ++int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); ++struct au_opt_mod; ++int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, ++ int *do_update); ++ ++/* xino.c */ ++static const loff_t au_loff_max = LLONG_MAX; ++ ++int au_xib_trunc(struct super_block *sb); ++ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos); ++ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos); ++struct file *au_xino_create2(struct file *base_file, struct file *copy_src); ++struct file *au_xino_create(struct super_block *sb, char *fname, int silent); ++ino_t au_xino_new_ino(struct super_block *sb); ++int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino); ++int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino); ++int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t *ino); ++int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino, ++ struct file *base_file, int do_test); ++int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex); ++ ++struct au_opt_xino; ++int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount); ++void au_xino_clr(struct super_block *sb); ++struct file *au_xino_def(struct super_block *sb); ++int au_xino_path(struct seq_file *seq, struct file *file); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Superblock to branch */ ++static inline ++aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_id; ++} ++ ++static inline ++struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_mnt; ++} ++ ++static inline ++struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr_mnt(sb, bindex)->mnt_sb; ++} ++ ++static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ atomic_dec_return(&au_sbr(sb, bindex)->br_count); ++} ++ ++static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_perm; ++} ++ ++static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_br_whable(au_sbr_perm(sb, bindex)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * wbr_wh_read_lock, wbr_wh_write_lock ++ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock ++ */ ++AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem); ++ ++#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem) ++#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem) ++#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem) ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_BRANCH_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/cpup.c linux-2.6.31/fs/aufs/cpup.c +--- linux-2.6.31-vanilla/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/cpup.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,1048 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * copy-up functions, see wbr_policy.c for copy-down ++ */ ++ ++#include <linux/file.h> ++#include <linux/fs_stack.h> ++#include <linux/mm.h> ++#include <linux/uaccess.h> ++#include "aufs.h" ++ ++void au_cpup_attr_flags(struct inode *dst, struct inode *src) ++{ ++ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE ++ | S_NOATIME | S_NOCMTIME; ++ ++ dst->i_flags |= src->i_flags & ~mask; ++ if (au_test_fs_notime(dst->i_sb)) ++ dst->i_flags |= S_NOATIME | S_NOCMTIME; ++} ++ ++void au_cpup_attr_timesizes(struct inode *inode) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ fsstack_copy_attr_times(inode, h_inode); ++ vfsub_copy_inode_size(inode, h_inode); ++} ++ ++void au_cpup_attr_nlink(struct inode *inode, int force) ++{ ++ struct inode *h_inode; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend; ++ ++ sb = inode->i_sb; ++ bindex = au_ibstart(inode); ++ h_inode = au_h_iptr(inode, bindex); ++ if (!force ++ && !S_ISDIR(h_inode->i_mode) ++ && au_opt_test(au_mntflags(sb), PLINK) ++ && au_plink_test(inode)) ++ return; ++ ++ inode->i_nlink = h_inode->i_nlink; ++ ++ /* ++ * fewer nlink makes find(1) noisy, but larger nlink doesn't. ++ * it may includes whplink directory. ++ */ ++ if (S_ISDIR(h_inode->i_mode)) { ++ bend = au_ibend(inode); ++ for (bindex++; bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode) ++ au_add_nlink(inode, h_inode); ++ } ++ } ++} ++ ++void au_cpup_attr_changeable(struct inode *inode) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ inode->i_mode = h_inode->i_mode; ++ inode->i_uid = h_inode->i_uid; ++ inode->i_gid = h_inode->i_gid; ++ au_cpup_attr_timesizes(inode); ++ au_cpup_attr_flags(inode, h_inode); ++} ++ ++void au_cpup_igen(struct inode *inode, struct inode *h_inode) ++{ ++ struct au_iinfo *iinfo = au_ii(inode); ++ ++ IiMustWriteLock(inode); ++ ++ iinfo->ii_higen = h_inode->i_generation; ++ iinfo->ii_hsb1 = h_inode->i_sb; ++} ++ ++void au_cpup_attr_all(struct inode *inode, int force) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ au_cpup_attr_changeable(inode); ++ if (inode->i_nlink > 0) ++ au_cpup_attr_nlink(inode, force); ++ inode->i_rdev = h_inode->i_rdev; ++ inode->i_blkbits = h_inode->i_blkbits; ++ au_cpup_igen(inode, h_inode); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */ ++ ++/* keep the timestamps of the parent dir when cpup */ ++void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, ++ struct path *h_path) ++{ ++ struct inode *h_inode; ++ ++ dt->dt_dentry = dentry; ++ dt->dt_h_path = *h_path; ++ h_inode = h_path->dentry->d_inode; ++ dt->dt_atime = h_inode->i_atime; ++ dt->dt_mtime = h_inode->i_mtime; ++ /* smp_mb(); */ ++} ++ ++void au_dtime_revert(struct au_dtime *dt) ++{ ++ struct iattr attr; ++ int err; ++ ++ attr.ia_atime = dt->dt_atime; ++ attr.ia_mtime = dt->dt_mtime; ++ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET ++ | ATTR_ATIME | ATTR_ATIME_SET; ++ ++ err = vfsub_notify_change(&dt->dt_h_path, &attr); ++ if (unlikely(err)) ++ AuWarn("restoring timestamps failed(%d). ignored\n", err); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static noinline_for_stack ++int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src) ++{ ++ int err, sbits; ++ struct iattr ia; ++ struct path h_path; ++ struct inode *h_isrc, *h_idst; ++ ++ h_path.dentry = au_h_dptr(dst, bindex); ++ h_idst = h_path.dentry->d_inode; ++ h_path.mnt = au_sbr_mnt(dst->d_sb, bindex); ++ h_isrc = h_src->d_inode; ++ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID ++ | ATTR_ATIME | ATTR_MTIME ++ | ATTR_ATIME_SET | ATTR_MTIME_SET; ++ ia.ia_uid = h_isrc->i_uid; ++ ia.ia_gid = h_isrc->i_gid; ++ ia.ia_atime = h_isrc->i_atime; ++ ia.ia_mtime = h_isrc->i_mtime; ++ if (h_idst->i_mode != h_isrc->i_mode ++ && !S_ISLNK(h_idst->i_mode)) { ++ ia.ia_valid |= ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ } ++ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID)); ++ au_cpup_attr_flags(h_idst, h_isrc); ++ err = vfsub_notify_change(&h_path, &ia); ++ ++ /* is this nfs only? */ ++ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) { ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ err = vfsub_notify_change(&h_path, &ia); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_copy_file(struct file *dst, struct file *src, loff_t len, ++ char *buf, unsigned long blksize) ++{ ++ int err; ++ size_t sz, rbytes, wbytes; ++ unsigned char all_zero; ++ char *p, *zp; ++ struct mutex *h_mtx; ++ /* reduce stack usage */ ++ struct iattr *ia; ++ ++ zp = page_address(ZERO_PAGE(0)); ++ if (unlikely(!zp)) ++ return -ENOMEM; /* possible? */ ++ ++ err = 0; ++ all_zero = 0; ++ while (len) { ++ AuDbg("len %lld\n", len); ++ sz = blksize; ++ if (len < blksize) ++ sz = len; ++ ++ rbytes = 0; ++ /* todo: signal_pending? */ ++ while (!rbytes || err == -EAGAIN || err == -EINTR) { ++ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos); ++ err = rbytes; ++ } ++ if (unlikely(err < 0)) ++ break; ++ ++ all_zero = 0; ++ if (len >= rbytes && rbytes == blksize) ++ all_zero = !memcmp(buf, zp, rbytes); ++ if (!all_zero) { ++ wbytes = rbytes; ++ p = buf; ++ while (wbytes) { ++ size_t b; ++ ++ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos); ++ err = b; ++ /* todo: signal_pending? */ ++ if (unlikely(err == -EAGAIN || err == -EINTR)) ++ continue; ++ if (unlikely(err < 0)) ++ break; ++ wbytes -= b; ++ p += b; ++ } ++ } else { ++ loff_t res; ++ ++ AuLabel(hole); ++ res = vfsub_llseek(dst, rbytes, SEEK_CUR); ++ err = res; ++ if (unlikely(res < 0)) ++ break; ++ } ++ len -= rbytes; ++ err = 0; ++ } ++ ++ /* the last block may be a hole */ ++ if (!err && all_zero) { ++ AuLabel(last hole); ++ ++ err = 1; ++ if (au_test_nfs(dst->f_dentry->d_sb)) { ++ /* nfs requires this step to make last hole */ ++ /* is this only nfs? */ ++ do { ++ /* todo: signal_pending? */ ++ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ if (err == 1) ++ dst->f_pos--; ++ } ++ ++ if (err == 1) { ++ ia = (void *)buf; ++ ia->ia_size = dst->f_pos; ++ ia->ia_valid = ATTR_SIZE | ATTR_FILE; ++ ia->ia_file = dst; ++ h_mtx = &dst->f_dentry->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2); ++ err = vfsub_notify_change(&dst->f_path, ia); ++ mutex_unlock(h_mtx); ++ } ++ } ++ ++ return err; ++} ++ ++int au_copy_file(struct file *dst, struct file *src, loff_t len) ++{ ++ int err; ++ unsigned long blksize; ++ unsigned char do_kfree; ++ char *buf; ++ ++ err = -ENOMEM; ++ blksize = dst->f_dentry->d_sb->s_blocksize; ++ if (!blksize || PAGE_SIZE < blksize) ++ blksize = PAGE_SIZE; ++ AuDbg("blksize %lu\n", blksize); ++ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *)); ++ if (do_kfree) ++ buf = kmalloc(blksize, GFP_NOFS); ++ else ++ buf = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!buf)) ++ goto out; ++ ++ if (len > (1 << 22)) ++ AuDbg("copying a large file %lld\n", (long long)len); ++ ++ src->f_pos = 0; ++ dst->f_pos = 0; ++ err = au_do_copy_file(dst, src, len, buf, blksize); ++ if (do_kfree) ++ kfree(buf); ++ else ++ free_page((unsigned long)buf); ++ ++ out: ++ return err; ++} ++ ++/* ++ * to support a sparse file which is opened with O_APPEND, ++ * we need to close the file. ++ */ ++static int au_cp_regular(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len) ++{ ++ int err, i; ++ enum { SRC, DST }; ++ struct { ++ aufs_bindex_t bindex; ++ unsigned int flags; ++ struct dentry *dentry; ++ struct file *file; ++ void *label, *label_file; ++ } *f, file[] = { ++ { ++ .bindex = bsrc, ++ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, ++ .file = NULL, ++ .label = &&out, ++ .label_file = &&out_src ++ }, ++ { ++ .bindex = bdst, ++ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, ++ .file = NULL, ++ .label = &&out_src, ++ .label_file = &&out_dst ++ } ++ }; ++ struct super_block *sb; ++ ++ /* bsrc branch can be ro/rw. */ ++ sb = dentry->d_sb; ++ f = file; ++ for (i = 0; i < 2; i++, f++) { ++ f->dentry = au_h_dptr(dentry, f->bindex); ++ f->file = au_h_open(dentry, f->bindex, f->flags, /*file*/NULL); ++ err = PTR_ERR(f->file); ++ if (IS_ERR(f->file)) ++ goto *f->label; ++ err = -EINVAL; ++ if (unlikely(!f->file->f_op)) ++ goto *f->label_file; ++ } ++ ++ /* try stopping to update while we copyup */ ++ IMustLock(file[SRC].dentry->d_inode); ++ err = au_copy_file(file[DST].file, file[SRC].file, len); ++ ++ out_dst: ++ fput(file[DST].file); ++ au_sbr_put(sb, file[DST].bindex); ++ out_src: ++ fput(file[SRC].file); ++ au_sbr_put(sb, file[SRC].bindex); ++ out: ++ return err; ++} ++ ++static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, ++ struct inode *h_dir, struct path *h_path) ++{ ++ int err, rerr; ++ loff_t l; ++ ++ err = 0; ++ l = i_size_read(au_h_iptr(dentry->d_inode, bsrc)); ++ if (len == -1 || l < len) ++ len = l; ++ if (len) ++ err = au_cp_regular(dentry, bdst, bsrc, len); ++ if (!err) ++ goto out; /* success */ ++ ++ rerr = vfsub_unlink(h_dir, h_path, /*force*/0); ++ if (rerr) { ++ AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n", ++ AuDLNPair(h_path->dentry), err, rerr); ++ err = -EIO; ++ } ++ ++ out: ++ return err; ++} ++ ++static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, ++ struct inode *h_dir) ++{ ++ int err, symlen; ++ mm_segment_t old_fs; ++ char *sym; ++ ++ err = -ENOSYS; ++ if (unlikely(!h_src->d_inode->i_op->readlink)) ++ goto out; ++ ++ err = -ENOMEM; ++ sym = __getname(); ++ if (unlikely(!sym)) ++ goto out; ++ ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ symlen = h_src->d_inode->i_op->readlink(h_src, (char __user *)sym, ++ PATH_MAX); ++ err = symlen; ++ set_fs(old_fs); ++ ++ if (symlen > 0) { ++ sym[symlen] = 0; ++ err = vfsub_symlink(h_dir, h_path, sym); ++ } ++ __putname(sym); ++ ++ out: ++ return err; ++} ++ ++/* return with the lower dst inode is locked */ ++static noinline_for_stack ++int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent) ++{ ++ int err; ++ umode_t mode; ++ unsigned int mnt_flags; ++ unsigned char isdir; ++ const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME); ++ struct au_dtime dt; ++ struct path h_path; ++ struct dentry *h_src, *h_dst, *h_parent; ++ struct inode *h_inode, *h_dir; ++ struct super_block *sb; ++ ++ /* bsrc branch can be ro/rw. */ ++ h_src = au_h_dptr(dentry, bsrc); ++ h_inode = h_src->d_inode; ++ AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc)); ++ ++ /* try stopping to be referenced while we are creating */ ++ h_dst = au_h_dptr(dentry, bdst); ++ h_parent = h_dst->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ AuDebugOn(h_parent != h_dst->d_parent); ++ ++ sb = dentry->d_sb; ++ h_path.mnt = au_sbr_mnt(sb, bdst); ++ if (do_dt) { ++ h_path.dentry = h_parent; ++ au_dtime_store(&dt, dst_parent, &h_path); ++ } ++ h_path.dentry = h_dst; ++ ++ isdir = 0; ++ mode = h_inode->i_mode; ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ /* try stopping to update while we are referencing */ ++ IMustLock(h_inode); ++ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR); ++ if (!err) ++ err = au_do_cpup_regular ++ (dentry, bdst, bsrc, len, ++ au_h_iptr(dst_parent->d_inode, bdst), &h_path); ++ break; ++ case S_IFDIR: ++ isdir = 1; ++ err = vfsub_mkdir(h_dir, &h_path, mode); ++ if (!err) { ++ /* ++ * strange behaviour from the users view, ++ * particularry setattr case ++ */ ++ if (au_ibstart(dst_parent->d_inode) == bdst) ++ au_cpup_attr_nlink(dst_parent->d_inode, ++ /*force*/1); ++ au_cpup_attr_nlink(dentry->d_inode, /*force*/1); ++ } ++ break; ++ case S_IFLNK: ++ err = au_do_cpup_symlink(&h_path, h_src, h_dir); ++ break; ++ case S_IFCHR: ++ case S_IFBLK: ++ AuDebugOn(!capable(CAP_MKNOD)); ++ /*FALLTHROUGH*/ ++ case S_IFIFO: ++ case S_IFSOCK: ++ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); ++ break; ++ default: ++ AuIOErr("Unknown inode type 0%o\n", mode); ++ err = -EIO; ++ } ++ ++ mnt_flags = au_mntflags(sb); ++ if (!au_opt_test(mnt_flags, UDBA_NONE) ++ && !isdir ++ && au_opt_test(mnt_flags, XINO) ++ && h_inode->i_nlink == 1 ++ /* todo: unnecessary? */ ++ /* && dentry->d_inode->i_nlink == 1 */ ++ && bdst < bsrc ++ && !au_ftest_cpup(flags, KEEPLINO)) ++ au_xino_write(sb, bsrc, h_inode->i_ino, /*ino*/0); ++ /* ignore this error */ ++ ++ if (do_dt) ++ au_dtime_revert(&dt); ++ return err; ++} ++ ++/* ++ * copyup the @dentry from @bsrc to @bdst. ++ * the caller must set the both of lower dentries. ++ * @len is for truncating when it is -1 copyup the entire file. ++ * in link/rename cases, @dst_parent may be different from the real one. ++ */ ++static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent) ++{ ++ int err, rerr; ++ aufs_bindex_t old_ibstart; ++ unsigned char isdir, plink; ++ struct au_dtime dt; ++ struct path h_path; ++ struct dentry *h_src, *h_dst, *h_parent; ++ struct inode *dst_inode, *h_dir, *inode; ++ struct super_block *sb; ++ ++ AuDebugOn(bsrc <= bdst); ++ ++ sb = dentry->d_sb; ++ h_path.mnt = au_sbr_mnt(sb, bdst); ++ h_dst = au_h_dptr(dentry, bdst); ++ h_parent = h_dst->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ h_src = au_h_dptr(dentry, bsrc); ++ inode = dentry->d_inode; ++ ++ if (!dst_parent) ++ dst_parent = dget_parent(dentry); ++ else ++ dget(dst_parent); ++ ++ plink = !!au_opt_test(au_mntflags(sb), PLINK); ++ dst_inode = au_h_iptr(inode, bdst); ++ if (dst_inode) { ++ if (unlikely(!plink)) { ++ err = -EIO; ++ AuIOErr("i%lu exists on a upper branch " ++ "but plink is disabled\n", inode->i_ino); ++ goto out; ++ } ++ ++ if (dst_inode->i_nlink) { ++ const int do_dt = au_ftest_cpup(flags, DTIME); ++ ++ h_src = au_plink_lkup(inode, bdst); ++ err = PTR_ERR(h_src); ++ if (IS_ERR(h_src)) ++ goto out; ++ if (unlikely(!h_src->d_inode)) { ++ err = -EIO; ++ AuIOErr("i%lu exists on a upper branch " ++ "but plink is broken\n", inode->i_ino); ++ dput(h_src); ++ goto out; ++ } ++ ++ if (do_dt) { ++ h_path.dentry = h_parent; ++ au_dtime_store(&dt, dst_parent, &h_path); ++ } ++ h_path.dentry = h_dst; ++ err = vfsub_link(h_src, h_dir, &h_path); ++ if (do_dt) ++ au_dtime_revert(&dt); ++ dput(h_src); ++ goto out; ++ } else ++ /* todo: cpup_wh_file? */ ++ /* udba work */ ++ au_update_brange(inode, 1); ++ } ++ ++ old_ibstart = au_ibstart(inode); ++ err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent); ++ if (unlikely(err)) ++ goto out; ++ dst_inode = h_dst->d_inode; ++ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2); ++ ++ err = cpup_iattr(dentry, bdst, h_src); ++ isdir = S_ISDIR(dst_inode->i_mode); ++ if (!err) { ++ if (bdst < old_ibstart) ++ au_set_ibstart(inode, bdst); ++ au_set_h_iptr(inode, bdst, au_igrab(dst_inode), ++ au_hi_flags(inode, isdir)); ++ mutex_unlock(&dst_inode->i_mutex); ++ if (!isdir ++ && h_src->d_inode->i_nlink > 1 ++ && plink) ++ au_plink_append(inode, bdst, h_dst); ++ goto out; /* success */ ++ } ++ ++ /* revert */ ++ h_path.dentry = h_parent; ++ mutex_unlock(&dst_inode->i_mutex); ++ au_dtime_store(&dt, dst_parent, &h_path); ++ h_path.dentry = h_dst; ++ if (!isdir) ++ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ else ++ rerr = vfsub_rmdir(h_dir, &h_path); ++ au_dtime_revert(&dt); ++ if (rerr) { ++ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); ++ err = -EIO; ++ } ++ ++ out: ++ dput(dst_parent); ++ return err; ++} ++ ++struct au_cpup_single_args { ++ int *errp; ++ struct dentry *dentry; ++ aufs_bindex_t bdst, bsrc; ++ loff_t len; ++ unsigned int flags; ++ struct dentry *dst_parent; ++}; ++ ++static void au_call_cpup_single(void *args) ++{ ++ struct au_cpup_single_args *a = args; ++ *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len, ++ a->flags, a->dst_parent); ++} ++ ++int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent) ++{ ++ int err, wkq_err; ++ umode_t mode; ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bsrc); ++ mode = h_dentry->d_inode->i_mode & S_IFMT; ++ if ((mode != S_IFCHR && mode != S_IFBLK) ++ || capable(CAP_MKNOD)) ++ err = au_cpup_single(dentry, bdst, bsrc, len, flags, ++ dst_parent); ++ else { ++ struct au_cpup_single_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .bdst = bdst, ++ .bsrc = bsrc, ++ .len = len, ++ .flags = flags, ++ .dst_parent = dst_parent ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_single, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++/* ++ * copyup the @dentry from the first active lower branch to @bdst, ++ * using au_cpup_single(). ++ */ ++static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ unsigned int flags) ++{ ++ int err; ++ aufs_bindex_t bsrc, bend; ++ ++ bend = au_dbend(dentry); ++ for (bsrc = bdst + 1; bsrc <= bend; bsrc++) ++ if (au_h_dptr(dentry, bsrc)) ++ break; ++ ++ err = au_lkup_neg(dentry, bdst); ++ if (!err) { ++ err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL); ++ if (!err) ++ return 0; /* success */ ++ ++ /* revert */ ++ au_set_h_dptr(dentry, bdst, NULL); ++ au_set_dbstart(dentry, bsrc); ++ } ++ ++ return err; ++} ++ ++struct au_cpup_simple_args { ++ int *errp; ++ struct dentry *dentry; ++ aufs_bindex_t bdst; ++ loff_t len; ++ unsigned int flags; ++}; ++ ++static void au_call_cpup_simple(void *args) ++{ ++ struct au_cpup_simple_args *a = args; ++ *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags); ++} ++ ++int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ unsigned int flags) ++{ ++ int err, wkq_err; ++ unsigned char do_sio; ++ struct dentry *parent; ++ struct inode *h_dir; ++ ++ parent = dget_parent(dentry); ++ h_dir = au_h_iptr(parent->d_inode, bdst); ++ do_sio = !!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) { ++ /* ++ * testing CAP_MKNOD is for generic fs, ++ * but CAP_FSETID is for xfs only, currently. ++ */ ++ umode_t mode = dentry->d_inode->i_mode; ++ do_sio = (((mode & (S_IFCHR | S_IFBLK)) ++ && !capable(CAP_MKNOD)) ++ || ((mode & (S_ISUID | S_ISGID)) ++ && !capable(CAP_FSETID))); ++ } ++ if (!do_sio) ++ err = au_cpup_simple(dentry, bdst, len, flags); ++ else { ++ struct au_cpup_simple_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .bdst = bdst, ++ .len = len, ++ .flags = flags ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_simple, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * copyup the deleted file for writing. ++ */ ++static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *wh_dentry, struct file *file, ++ loff_t len) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct dentry *h_d_dst, *h_d_start; ++ ++ dinfo = au_di(dentry); ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ bstart = dinfo->di_bstart; ++ h_d_dst = dinfo->di_hdentry[0 + bdst].hd_dentry; ++ dinfo->di_bstart = bdst; ++ dinfo->di_hdentry[0 + bdst].hd_dentry = wh_dentry; ++ h_d_start = dinfo->di_hdentry[0 + bstart].hd_dentry; ++ if (file) ++ dinfo->di_hdentry[0 + bstart].hd_dentry ++ = au_h_fptr(file, au_fbstart(file))->f_dentry; ++ err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME, ++ /*h_parent*/NULL); ++ if (!err && file) { ++ err = au_reopen_nondir(file); ++ dinfo->di_hdentry[0 + bstart].hd_dentry = h_d_start; ++ } ++ dinfo->di_hdentry[0 + bdst].hd_dentry = h_d_dst; ++ dinfo->di_bstart = bstart; ++ ++ return err; ++} ++ ++static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ struct file *file) ++{ ++ int err; ++ struct au_dtime dt; ++ struct dentry *parent, *h_parent, *wh_dentry; ++ struct au_branch *br; ++ struct path h_path; ++ ++ br = au_sbr(dentry->d_sb, bdst); ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ h_path.dentry = h_parent; ++ h_path.mnt = br->br_mnt; ++ au_dtime_store(&dt, parent, &h_path); ++ err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len); ++ if (unlikely(err)) ++ goto out_wh; ++ ++ dget(wh_dentry); ++ h_path.dentry = wh_dentry; ++ err = vfsub_unlink(h_parent->d_inode, &h_path, /*force*/0); ++ if (unlikely(err)) { ++ AuIOErr("failed remove copied-up tmp file %.*s(%d)\n", ++ AuDLNPair(wh_dentry), err); ++ err = -EIO; ++ } ++ au_dtime_revert(&dt); ++ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry); ++ ++ out_wh: ++ dput(wh_dentry); ++ out: ++ dput(parent); ++ return err; ++} ++ ++struct au_cpup_wh_args { ++ int *errp; ++ struct dentry *dentry; ++ aufs_bindex_t bdst; ++ loff_t len; ++ struct file *file; ++}; ++ ++static void au_call_cpup_wh(void *args) ++{ ++ struct au_cpup_wh_args *a = args; ++ *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file); ++} ++ ++int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ struct file *file) ++{ ++ int err, wkq_err; ++ struct dentry *parent, *h_orph, *h_parent, *h_dentry; ++ struct inode *dir, *h_dir, *h_tmpdir, *h_inode; ++ struct au_wbr *wbr; ++ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ h_orph = NULL; ++ h_parent = NULL; ++ h_dir = au_igrab(au_h_iptr(dir, bdst)); ++ h_tmpdir = h_dir; ++ if (!h_dir->i_nlink) { ++ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; ++ h_orph = wbr->wbr_orph; ++ ++ h_parent = dget(au_h_dptr(parent, bdst)); ++ au_set_h_dptr(parent, bdst, NULL); ++ au_set_h_dptr(parent, bdst, dget(h_orph)); ++ h_tmpdir = h_orph->d_inode; ++ au_set_h_iptr(dir, bdst, NULL, 0); ++ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); ++ ++ /* this temporary unlock is safe */ ++ if (file) ++ h_dentry = au_h_fptr(file, au_fbstart(file))->f_dentry; ++ else ++ h_dentry = au_h_dptr(dentry, au_dbstart(dentry)); ++ h_inode = h_dentry->d_inode; ++ IMustLock(h_inode); ++ mutex_unlock(&h_inode->i_mutex); ++ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3); ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ } ++ ++ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)) ++ err = au_cpup_wh(dentry, bdst, len, file); ++ else { ++ struct au_cpup_wh_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .bdst = bdst, ++ .len = len, ++ .file = file ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_wh, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ if (h_orph) { ++ mutex_unlock(&h_tmpdir->i_mutex); ++ au_set_h_iptr(dir, bdst, NULL, 0); ++ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); ++ au_set_h_dptr(parent, bdst, NULL); ++ au_set_h_dptr(parent, bdst, h_parent); ++ } ++ iput(h_dir); ++ dput(parent); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * generic routine for both of copy-up and copy-down. ++ */ ++/* cf. revalidate function in file.c */ ++int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, ++ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent, void *arg), ++ void *arg) ++{ ++ int err; ++ struct au_pin pin; ++ struct dentry *d, *parent, *h_parent, *real_parent; ++ ++ err = 0; ++ parent = dget_parent(dentry); ++ if (IS_ROOT(parent)) ++ goto out; ++ ++ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2, ++ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE); ++ ++ /* do not use au_dpage */ ++ real_parent = parent; ++ while (1) { ++ dput(parent); ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ if (h_parent) ++ goto out; /* success */ ++ ++ /* find top dir which is necessary to cpup */ ++ do { ++ d = parent; ++ dput(parent); ++ parent = dget_parent(d); ++ di_read_lock_parent3(parent, !AuLock_IR); ++ h_parent = au_h_dptr(parent, bdst); ++ di_read_unlock(parent, !AuLock_IR); ++ } while (!h_parent); ++ ++ if (d != real_parent) ++ di_write_lock_child3(d); ++ ++ /* somebody else might create while we were sleeping */ ++ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) { ++ if (au_h_dptr(d, bdst)) ++ au_update_dbstart(d); ++ ++ au_pin_set_dentry(&pin, d); ++ err = au_do_pin(&pin); ++ if (!err) { ++ err = cp(d, bdst, h_parent, arg); ++ au_unpin(&pin); ++ } ++ } ++ ++ if (d != real_parent) ++ di_write_unlock(d); ++ if (unlikely(err)) ++ break; ++ } ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent __maybe_unused , ++ void *arg __maybe_unused) ++{ ++ return au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME); ++} ++ ++int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); ++} ++ ++int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ int err; ++ struct dentry *parent; ++ struct inode *dir; ++ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ err = 0; ++ if (au_h_iptr(dir, bdst)) ++ goto out; ++ ++ di_read_unlock(parent, AuLock_IR); ++ di_write_lock_parent(parent); ++ /* someone else might change our inode while we were sleeping */ ++ if (!au_h_iptr(dir, bdst)) ++ err = au_cpup_dirs(dentry, bdst); ++ di_downgrade_lock(parent, AuLock_IR); ++ ++ out: ++ dput(parent); ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/cpup.h linux-2.6.31/fs/aufs/cpup.h +--- linux-2.6.31-vanilla/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/cpup.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,81 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * copy-up/down functions ++ */ ++ ++#ifndef __AUFS_CPUP_H__ ++#define __AUFS_CPUP_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/path.h> ++#include <linux/time.h> ++#include <linux/aufs_type.h> ++ ++struct inode; ++struct file; ++ ++void au_cpup_attr_flags(struct inode *dst, struct inode *src); ++void au_cpup_attr_timesizes(struct inode *inode); ++void au_cpup_attr_nlink(struct inode *inode, int force); ++void au_cpup_attr_changeable(struct inode *inode); ++void au_cpup_igen(struct inode *inode, struct inode *h_inode); ++void au_cpup_attr_all(struct inode *inode, int force); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* cpup flags */ ++#define AuCpup_DTIME 1 /* do dtime_store/revert */ ++#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, ++ for link(2) */ ++#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) ++#define au_fset_cpup(flags, name) { (flags) |= AuCpup_##name; } ++#define au_fclr_cpup(flags, name) { (flags) &= ~AuCpup_##name; } ++ ++int au_copy_file(struct file *dst, struct file *src, loff_t len); ++int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, ++ aufs_bindex_t bsrc, loff_t len, unsigned int flags, ++ struct dentry *dst_parent); ++int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ unsigned int flags); ++int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, ++ struct file *file); ++ ++int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, ++ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent, void *arg), ++ void *arg); ++int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* keep timestamps when copyup */ ++struct au_dtime { ++ struct dentry *dt_dentry; ++ struct path dt_h_path; ++ struct timespec dt_atime, dt_mtime; ++}; ++void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, ++ struct path *h_path); ++void au_dtime_revert(struct au_dtime *dt); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_CPUP_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/dbgaufs.c linux-2.6.31/fs/aufs/dbgaufs.c +--- linux-2.6.31-vanilla/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/dbgaufs.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,331 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * debugfs interface ++ */ ++ ++#include <linux/debugfs.h> ++#include "aufs.h" ++ ++#ifndef CONFIG_SYSFS ++#error DEBUG_FS depends upon SYSFS ++#endif ++ ++static struct dentry *dbgaufs; ++static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH; ++ ++/* 20 is max digits length of ulong 64 */ ++struct dbgaufs_arg { ++ int n; ++ char a[20 * 4]; ++}; ++ ++/* ++ * common function for all XINO files ++ */ ++static int dbgaufs_xi_release(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ kfree(file->private_data); ++ return 0; ++} ++ ++static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt) ++{ ++ int err; ++ struct kstat st; ++ struct dbgaufs_arg *p; ++ ++ err = -ENOMEM; ++ p = kmalloc(sizeof(*p), GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ ++ err = 0; ++ p->n = 0; ++ file->private_data = p; ++ if (!xf) ++ goto out; ++ ++ err = vfs_getattr(xf->f_vfsmnt, xf->f_dentry, &st); ++ if (!err) { ++ if (do_fcnt) ++ p->n = snprintf ++ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n", ++ (long)file_count(xf), st.blocks, st.blksize, ++ (long long)st.size); ++ else ++ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n", ++ st.blocks, st.blksize, ++ (long long)st.size); ++ AuDebugOn(p->n >= sizeof(p->a)); ++ } else { ++ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err); ++ err = 0; ++ } ++ ++ out: ++ return err; ++ ++} ++ ++static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dbgaufs_arg *p; ++ ++ p = file->private_data; ++ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int dbgaufs_xib_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0); ++ si_read_unlock(sb); ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xib_fop = { ++ .open = dbgaufs_xib_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define DbgaufsXi_PREFIX "xi" ++ ++static int dbgaufs_xino_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ long l; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ struct file *xf; ++ struct qstr *name; ++ ++ err = -ENOENT; ++ xf = NULL; ++ name = &file->f_dentry->d_name; ++ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX) ++ || memcmp(name->name, DbgaufsXi_PREFIX, ++ sizeof(DbgaufsXi_PREFIX) - 1))) ++ goto out; ++ err = strict_strtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l); ++ if (unlikely(err)) ++ goto out; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ if (l <= au_sbend(sb)) { ++ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file; ++ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1); ++ } else ++ err = -ENOENT; ++ si_read_unlock(sb); ++ ++ out: ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xino_fop = { ++ .open = dbgaufs_xino_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ aufs_bindex_t bend; ++ struct au_branch *br; ++ struct au_xino_file *xi; ++ ++ if (!au_sbi(sb)->si_dbgaufs) ++ return; ++ ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ xi = &br->br_xino; ++ if (xi->xi_dbgaufs) { ++ debugfs_remove(xi->xi_dbgaufs); ++ xi->xi_dbgaufs = NULL; ++ } ++ } ++} ++ ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ struct au_sbinfo *sbinfo; ++ struct dentry *parent; ++ struct au_branch *br; ++ struct au_xino_file *xi; ++ aufs_bindex_t bend; ++ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */ ++ ++ sbinfo = au_sbi(sb); ++ parent = sbinfo->si_dbgaufs; ++ if (!parent) ++ return; ++ ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex); ++ br = au_sbr(sb, bindex); ++ xi = &br->br_xino; ++ AuDebugOn(xi->xi_dbgaufs); ++ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent, ++ sbinfo, &dbgaufs_xino_fop); ++ /* ignore an error */ ++ if (unlikely(!xi->xi_dbgaufs)) ++ AuWarn1("failed %s under debugfs\n", name); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++static int dbgaufs_xigen_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0); ++ si_read_unlock(sb); ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xigen_fop = { ++ .open = dbgaufs_xigen_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ ++ /* ++ * This function is a dynamic '__init' fucntion actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++ ++ err = -EIO; ++ sbinfo->si_dbgaufs_xigen = debugfs_create_file ++ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, ++ &dbgaufs_xigen_fop); ++ if (sbinfo->si_dbgaufs_xigen) ++ err = 0; ++ ++ return err; ++} ++#else ++static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) ++{ ++ return 0; ++} ++#endif /* CONFIG_AUFS_EXPORT */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo) ++{ ++ /* ++ * This function is a dynamic '__init' fucntion actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++ ++ debugfs_remove_recursive(sbinfo->si_dbgaufs); ++ sbinfo->si_dbgaufs = NULL; ++ kobject_put(&sbinfo->si_kobj); ++} ++ ++int dbgaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ char name[SysaufsSiNameLen]; ++ ++ /* ++ * This function is a dynamic '__init' fucntion actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++ ++ err = -ENOENT; ++ if (!dbgaufs) { ++ AuErr1("/debug/aufs is uninitialized\n"); ++ goto out; ++ } ++ ++ err = -EIO; ++ sysaufs_name(sbinfo, name); ++ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs); ++ if (unlikely(!sbinfo->si_dbgaufs)) ++ goto out; ++ kobject_get(&sbinfo->si_kobj); ++ ++ sbinfo->si_dbgaufs_xib = debugfs_create_file ++ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, ++ &dbgaufs_xib_fop); ++ if (unlikely(!sbinfo->si_dbgaufs_xib)) ++ goto out_dir; ++ ++ err = dbgaufs_xigen_init(sbinfo); ++ if (!err) ++ goto out; /* success */ ++ ++ out_dir: ++ dbgaufs_si_fin(sbinfo); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void dbgaufs_fin(void) ++{ ++ debugfs_remove(dbgaufs); ++} ++ ++int __init dbgaufs_init(void) ++{ ++ int err; ++ ++ err = -EIO; ++ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL); ++ if (dbgaufs) ++ err = 0; ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/dbgaufs.h linux-2.6.31/fs/aufs/dbgaufs.h +--- linux-2.6.31-vanilla/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/dbgaufs.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * debugfs interface ++ */ ++ ++#ifndef __DBGAUFS_H__ ++#define __DBGAUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/init.h> ++#include <linux/aufs_type.h> ++ ++struct super_block; ++struct au_sbinfo; ++ ++#ifdef CONFIG_DEBUG_FS ++/* dbgaufs.c */ ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo); ++int dbgaufs_si_init(struct au_sbinfo *sbinfo); ++void dbgaufs_fin(void); ++int __init dbgaufs_init(void); ++ ++#else ++ ++static inline ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* empty */ ++} ++ ++static inline ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* empty */ ++} ++ ++static inline ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo) ++{ ++ /* empty */ ++} ++ ++static inline ++int dbgaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ return 0; ++} ++ ++#define dbgaufs_fin() do {} while (0) ++ ++static inline ++int __init dbgaufs_init(void) ++{ ++ return 0; ++} ++#endif /* CONFIG_DEBUG_FS */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __DBGAUFS_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/dcsub.c linux-2.6.31/fs/aufs/dcsub.c +--- linux-2.6.31-vanilla/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/dcsub.c 2009-09-16 13:55:29.000000000 +0200 +@@ -0,0 +1,223 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * sub-routines for dentry cache ++ */ ++ ++#include "aufs.h" ++ ++static void au_dpage_free(struct au_dpage *dpage) ++{ ++ int i; ++ struct dentry **p; ++ ++ p = dpage->dentries; ++ for (i = 0; i < dpage->ndentry; i++) ++ dput(*p++); ++ free_page((unsigned long)dpage->dentries); ++} ++ ++int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) ++{ ++ int err; ++ void *p; ++ ++ err = -ENOMEM; ++ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp); ++ if (unlikely(!dpages->dpages)) ++ goto out; ++ ++ p = (void *)__get_free_page(gfp); ++ if (unlikely(!p)) ++ goto out_dpages; ++ ++ dpages->dpages[0].ndentry = 0; ++ dpages->dpages[0].dentries = p; ++ dpages->ndpage = 1; ++ return 0; /* success */ ++ ++ out_dpages: ++ kfree(dpages->dpages); ++ out: ++ return err; ++} ++ ++void au_dpages_free(struct au_dcsub_pages *dpages) ++{ ++ int i; ++ struct au_dpage *p; ++ ++ p = dpages->dpages; ++ for (i = 0; i < dpages->ndpage; i++) ++ au_dpage_free(p++); ++ kfree(dpages->dpages); ++} ++ ++static int au_dpages_append(struct au_dcsub_pages *dpages, ++ struct dentry *dentry, gfp_t gfp) ++{ ++ int err, sz; ++ struct au_dpage *dpage; ++ void *p; ++ ++ dpage = dpages->dpages + dpages->ndpage - 1; ++ sz = PAGE_SIZE / sizeof(dentry); ++ if (unlikely(dpage->ndentry >= sz)) { ++ AuLabel(new dpage); ++ err = -ENOMEM; ++ sz = dpages->ndpage * sizeof(*dpages->dpages); ++ p = au_kzrealloc(dpages->dpages, sz, ++ sz + sizeof(*dpages->dpages), gfp); ++ if (unlikely(!p)) ++ goto out; ++ ++ dpages->dpages = p; ++ dpage = dpages->dpages + dpages->ndpage; ++ p = (void *)__get_free_page(gfp); ++ if (unlikely(!p)) ++ goto out; ++ ++ dpage->ndentry = 0; ++ dpage->dentries = p; ++ dpages->ndpage++; ++ } ++ ++ dpage->dentries[dpage->ndentry++] = dget(dentry); ++ return 0; /* success */ ++ ++ out: ++ return err; ++} ++ ++int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, ++ au_dpages_test test, void *arg) ++{ ++ int err; ++ struct dentry *this_parent = root; ++ struct list_head *next; ++ struct super_block *sb = root->d_sb; ++ ++ err = 0; ++ spin_lock(&dcache_lock); ++ repeat: ++ next = this_parent->d_subdirs.next; ++ resume: ++ if (this_parent->d_sb == sb ++ && !IS_ROOT(this_parent) ++ && atomic_read(&this_parent->d_count) ++ && this_parent->d_inode ++ && (!test || test(this_parent, arg))) { ++ err = au_dpages_append(dpages, this_parent, GFP_ATOMIC); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ while (next != &this_parent->d_subdirs) { ++ struct list_head *tmp = next; ++ struct dentry *dentry = list_entry(tmp, struct dentry, ++ d_u.d_child); ++ next = tmp->next; ++ if (/*d_unhashed(dentry) || */!dentry->d_inode) ++ continue; ++ if (!list_empty(&dentry->d_subdirs)) { ++ this_parent = dentry; ++ goto repeat; ++ } ++ if (dentry->d_sb == sb ++ && atomic_read(&dentry->d_count) ++ && (!test || test(dentry, arg))) { ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ if (unlikely(err)) ++ goto out; ++ } ++ } ++ ++ if (this_parent != root) { ++ next = this_parent->d_u.d_child.next; ++ this_parent = this_parent->d_parent; /* dcache_lock is locked */ ++ goto resume; ++ } ++ out: ++ spin_unlock(&dcache_lock); ++ return err; ++} ++ ++int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, ++ int do_include, au_dpages_test test, void *arg) ++{ ++ int err; ++ ++ err = 0; ++ spin_lock(&dcache_lock); ++ if (do_include && (!test || test(dentry, arg))) { ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ if (unlikely(err)) ++ goto out; ++ } ++ while (!IS_ROOT(dentry)) { ++ dentry = dentry->d_parent; /* dcache_lock is locked */ ++ if (!test || test(dentry, arg)) { ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ if (unlikely(err)) ++ break; ++ } ++ } ++ ++ out: ++ spin_unlock(&dcache_lock); ++ ++ return err; ++} ++ ++struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2) ++{ ++ struct dentry *trap, **dentries; ++ int err, i, j; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ ++ trap = ERR_PTR(-ENOMEM); ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages_rev(&dpages, d1, /*do_include*/1, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ trap = d1; ++ for (i = 0; !err && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ for (j = 0; !err && j < dpage->ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ err = (d == d2); ++ if (!err) ++ trap = d; ++ } ++ } ++ if (!err) ++ trap = NULL; ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return trap; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/dcsub.h linux-2.6.31/fs/aufs/dcsub.h +--- linux-2.6.31-vanilla/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/dcsub.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,54 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * sub-routines for dentry cache ++ */ ++ ++#ifndef __AUFS_DCSUB_H__ ++#define __AUFS_DCSUB_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/types.h> ++ ++struct dentry; ++ ++struct au_dpage { ++ int ndentry; ++ struct dentry **dentries; ++}; ++ ++struct au_dcsub_pages { ++ int ndpage; ++ struct au_dpage *dpages; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp); ++void au_dpages_free(struct au_dcsub_pages *dpages); ++typedef int (*au_dpages_test)(struct dentry *dentry, void *arg); ++int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, ++ au_dpages_test test, void *arg); ++int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, ++ int do_include, au_dpages_test test, void *arg); ++struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DCSUB_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/debug.c linux-2.6.31/fs/aufs/debug.c +--- linux-2.6.31-vanilla/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/debug.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,431 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * debug print functions ++ */ ++ ++#include <linux/module.h> ++#include <linux/vt_kern.h> ++#include "aufs.h" ++ ++int aufs_debug; ++MODULE_PARM_DESC(debug, "debug print"); ++module_param_named(debug, aufs_debug, int, S_IRUGO | S_IWUSR | S_IWGRP); ++ ++char *au_plevel = KERN_DEBUG; ++#define dpri(fmt, arg...) do { \ ++ if (au_debug_test()) \ ++ printk("%s" fmt, au_plevel, ##arg); \ ++} while (0) ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dpri_whlist(struct au_nhash *whlist) ++{ ++ unsigned long ul, n; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (ul = 0; ul < n; ul++) { ++ hlist_for_each_entry(tpos, pos, head, wh_hash) ++ dpri("b%d, %.*s, %d\n", ++ tpos->wh_bindex, ++ tpos->wh_str.len, tpos->wh_str.name, ++ tpos->wh_str.len); ++ head++; ++ } ++} ++ ++void au_dpri_vdir(struct au_vdir *vdir) ++{ ++ unsigned long ul; ++ union au_vdir_deblk_p p; ++ unsigned char *o; ++ ++ if (!vdir || IS_ERR(vdir)) { ++ dpri("err %ld\n", PTR_ERR(vdir)); ++ return; ++ } ++ ++ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n", ++ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk, ++ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version); ++ for (ul = 0; ul < vdir->vd_nblk; ul++) { ++ p.deblk = vdir->vd_deblk[ul]; ++ o = p.deblk; ++ dpri("[%lu]: %p\n", ul, o); ++ } ++} ++ ++static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, ++ struct dentry *wh) ++{ ++ char *n = NULL; ++ int l = 0; ++ ++ if (!inode || IS_ERR(inode)) { ++ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode)); ++ return -1; ++ } ++ ++ /* the type of i_blocks depends upon CONFIG_LSF */ ++ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) ++ && sizeof(inode->i_blocks) != sizeof(u64)); ++ if (wh) { ++ n = (void *)wh->d_name.name; ++ l = wh->d_name.len; ++ } ++ ++ dpri("i%d: i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," ++ " ct %lld, np %lu, st 0x%lx, f 0x%x, g %x%s%.*s\n", ++ bindex, ++ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", ++ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, ++ i_size_read(inode), (unsigned long long)inode->i_blocks, ++ (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff, ++ inode->i_mapping ? inode->i_mapping->nrpages : 0, ++ inode->i_state, inode->i_flags, inode->i_generation, ++ l ? ", wh " : "", l, n); ++ return 0; ++} ++ ++void au_dpri_inode(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_inode(-1, inode, NULL); ++ if (err || !au_test_aufs(inode->i_sb)) ++ return; ++ ++ iinfo = au_ii(inode); ++ if (!iinfo) ++ return; ++ dpri("i-1: bstart %d, bend %d, gen %d\n", ++ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode)); ++ if (iinfo->ii_bstart < 0) ++ return; ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) ++ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, ++ iinfo->ii_hinode[0 + bindex].hi_whdentry); ++} ++ ++static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry) ++{ ++ struct dentry *wh = NULL; ++ ++ if (!dentry || IS_ERR(dentry)) { ++ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); ++ return -1; ++ } ++ /* do not call dget_parent() here */ ++ dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n", ++ bindex, ++ AuDLNPair(dentry->d_parent), AuDLNPair(dentry), ++ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", ++ atomic_read(&dentry->d_count), dentry->d_flags); ++ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) { ++ struct au_iinfo *iinfo = au_ii(dentry->d_inode); ++ if (iinfo) ++ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry; ++ } ++ do_pri_inode(bindex, dentry->d_inode, wh); ++ return 0; ++} ++ ++void au_dpri_dentry(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_dentry(-1, dentry); ++ if (err || !au_test_aufs(dentry->d_sb)) ++ return; ++ ++ dinfo = au_di(dentry); ++ if (!dinfo) ++ return; ++ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n", ++ dinfo->di_bstart, dinfo->di_bend, ++ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry)); ++ if (dinfo->di_bstart < 0) ++ return; ++ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++) ++ do_pri_dentry(bindex, dinfo->di_hdentry[0 + bindex].hd_dentry); ++} ++ ++static int do_pri_file(aufs_bindex_t bindex, struct file *file) ++{ ++ char a[32]; ++ ++ if (!file || IS_ERR(file)) { ++ dpri("f%d: err %ld\n", bindex, PTR_ERR(file)); ++ return -1; ++ } ++ a[0] = 0; ++ if (bindex < 0 ++ && file->f_dentry ++ && au_test_aufs(file->f_dentry->d_sb) ++ && au_fi(file)) ++ snprintf(a, sizeof(a), ", mmapped %d", au_test_mmapped(file)); ++ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, pos %llu%s\n", ++ bindex, file->f_mode, file->f_flags, (long)file_count(file), ++ file->f_pos, a); ++ if (file->f_dentry) ++ do_pri_dentry(bindex, file->f_dentry); ++ return 0; ++} ++ ++void au_dpri_file(struct file *file) ++{ ++ struct au_finfo *finfo; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_file(-1, file); ++ if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb)) ++ return; ++ ++ finfo = au_fi(file); ++ if (!finfo) ++ return; ++ if (finfo->fi_bstart < 0) ++ return; ++ for (bindex = finfo->fi_bstart; bindex <= finfo->fi_bend; bindex++) { ++ struct au_hfile *hf; ++ ++ hf = finfo->fi_hfile + bindex; ++ do_pri_file(bindex, hf ? hf->hf_file : NULL); ++ } ++} ++ ++static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br) ++{ ++ struct vfsmount *mnt; ++ struct super_block *sb; ++ ++ if (!br || IS_ERR(br)) ++ goto out; ++ mnt = br->br_mnt; ++ if (!mnt || IS_ERR(mnt)) ++ goto out; ++ sb = mnt->mnt_sb; ++ if (!sb || IS_ERR(sb)) ++ goto out; ++ ++ dpri("s%d: {perm 0x%x, cnt %d, wbr %p}, " ++ "%s, dev 0x%02x%02x, flags 0x%lx, cnt(BIAS) %d, active %d, " ++ "xino %d\n", ++ bindex, br->br_perm, atomic_read(&br->br_count), br->br_wbr, ++ au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev), ++ sb->s_flags, sb->s_count - S_BIAS, ++ atomic_read(&sb->s_active), !!br->br_xino.xi_file); ++ return 0; ++ ++ out: ++ dpri("s%d: err %ld\n", bindex, PTR_ERR(br)); ++ return -1; ++} ++ ++void au_dpri_sb(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ aufs_bindex_t bindex; ++ int err; ++ /* to reuduce stack size */ ++ struct { ++ struct vfsmount mnt; ++ struct au_branch fake; ++ } *a; ++ ++ /* this function can be called from magic sysrq */ ++ a = kzalloc(sizeof(*a), GFP_ATOMIC); ++ if (unlikely(!a)) { ++ dpri("no memory\n"); ++ return; ++ } ++ ++ a->mnt.mnt_sb = sb; ++ a->fake.br_perm = 0; ++ a->fake.br_mnt = &a->mnt; ++ a->fake.br_xino.xi_file = NULL; ++ atomic_set(&a->fake.br_count, 0); ++ smp_mb(); /* atomic_set */ ++ err = do_pri_br(-1, &a->fake); ++ kfree(a); ++ dpri("dev 0x%x\n", sb->s_dev); ++ if (err || !au_test_aufs(sb)) ++ return; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ dpri("nw %d, gen %u, kobj %d\n", ++ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation, ++ atomic_read(&sbinfo->si_kobj.kref.refcount)); ++ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++) ++ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dbg_sleep_jiffy(int jiffy) ++{ ++ while (jiffy) ++ jiffy = schedule_timeout_uninterruptible(jiffy); ++} ++ ++void au_dbg_iattr(struct iattr *ia) ++{ ++#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) \ ++ dpri(#name "\n") ++ AuBit(MODE); ++ AuBit(UID); ++ AuBit(GID); ++ AuBit(SIZE); ++ AuBit(ATIME); ++ AuBit(MTIME); ++ AuBit(CTIME); ++ AuBit(ATIME_SET); ++ AuBit(MTIME_SET); ++ AuBit(FORCE); ++ AuBit(ATTR_FLAG); ++ AuBit(KILL_SUID); ++ AuBit(KILL_SGID); ++ AuBit(FILE); ++ AuBit(KILL_PRIV); ++ AuBit(OPEN); ++ AuBit(TIMES_SET); ++#undef AuBit ++ dpri("ia_file %p\n", ia->ia_file); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen) ++{ ++ struct dentry *parent; ++ ++ parent = dget_parent(dentry); ++ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode) ++ || IS_ROOT(dentry) ++ || au_digen(parent) != sigen); ++ dput(parent); ++} ++ ++void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen) ++{ ++ struct dentry *parent; ++ ++ parent = dget_parent(dentry); ++ AuDebugOn(S_ISDIR(dentry->d_inode->i_mode) ++ || au_digen(parent) != sigen); ++ dput(parent); ++} ++ ++void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) ++{ ++ int err, i, j; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ AuDebugOn(err); ++ err = au_dcsub_pages_rev(&dpages, parent, /*do_include*/1, NULL, NULL); ++ AuDebugOn(err); ++ for (i = dpages.ndpage - 1; !err && i >= 0; i--) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ for (j = dpage->ndentry - 1; !err && j >= 0; j--) ++ AuDebugOn(au_digen(dentries[j]) != sigen); ++ } ++ au_dpages_free(&dpages); ++} ++ ++void au_dbg_verify_hf(struct au_finfo *finfo) ++{ ++ struct au_hfile *hf; ++ aufs_bindex_t bend, bindex; ++ ++ if (finfo->fi_bstart >= 0) { ++ bend = finfo->fi_bend; ++ for (bindex = finfo->fi_bstart; bindex <= bend; bindex++) { ++ hf = finfo->fi_hfile + bindex; ++ AuDebugOn(hf->hf_file || hf->hf_br); ++ } ++ } ++} ++ ++void au_dbg_verify_kthread(void) ++{ ++ if (au_test_wkq(current)) { ++ au_dbg_blocked(); ++ BUG(); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused) ++{ ++#ifdef AuForceNoPlink ++ au_opt_clr(sbinfo->si_mntflags, PLINK); ++#endif ++#ifdef AuForceNoXino ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++#endif ++#ifdef AuForceNoRefrof ++ au_opt_clr(sbinfo->si_mntflags, REFROF); ++#endif ++#ifdef AuForceHinotify ++ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HINOTIFY); ++#endif ++#ifdef AuForceRd0 ++ sbinfo->si_rdblk = 0; ++ sbinfo->si_rdhash = 0; ++#endif ++} ++ ++int __init au_debug_init(void) ++{ ++ aufs_bindex_t bindex; ++ struct au_vdir_destr destr; ++ ++ bindex = -1; ++ AuDebugOn(bindex >= 0); ++ ++ destr.len = -1; ++ AuDebugOn(destr.len < NAME_MAX); ++ ++#ifdef CONFIG_4KSTACKS ++ AuWarn("CONFIG_4KSTACKS is defined.\n"); ++#endif ++ ++#ifdef AuForceNoBrs ++ sysaufs_brs = 0; ++#endif ++ ++ return 0; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/debug.h linux-2.6.31/fs/aufs/debug.h +--- linux-2.6.31-vanilla/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/debug.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,263 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * debug print functions ++ */ ++ ++#ifndef __AUFS_DEBUG_H__ ++#define __AUFS_DEBUG_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <asm/system.h> ++#include <linux/bug.h> ++/* #include <linux/err.h> */ ++#include <linux/init.h> ++/* #include <linux/kernel.h> */ ++#include <linux/delay.h> ++/* #include <linux/kd.h> */ ++/* #include <linux/vt_kern.h> */ ++#include <linux/sysrq.h> ++#include <linux/aufs_type.h> ++ ++#include <asm/system.h> ++ ++#ifdef CONFIG_AUFS_DEBUG ++#define AuDebugOn(a) BUG_ON(a) ++ ++/* module parameter */ ++extern int aufs_debug; ++static inline void au_debug(int n) ++{ ++ aufs_debug = n; ++ smp_mb(); ++} ++ ++static inline int au_debug_test(void) ++{ ++ return aufs_debug; ++} ++#else ++#define AuDebugOn(a) do {} while (0) ++#define au_debug() do {} while (0) ++static inline int au_debug_test(void) ++{ ++ return 0; ++} ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* debug print */ ++ ++#define AuDpri(lvl, fmt, arg...) \ ++ printk(lvl AUFS_NAME " %s:%d:%s[%d]: " fmt, \ ++ __func__, __LINE__, current->comm, current->pid, ##arg) ++#define AuDbg(fmt, arg...) do { \ ++ if (au_debug_test()) \ ++ AuDpri(KERN_DEBUG, "DEBUG: " fmt, ##arg); \ ++} while (0) ++#define AuLabel(l) AuDbg(#l "\n") ++#define AuInfo(fmt, arg...) AuDpri(KERN_INFO, fmt, ##arg) ++#define AuWarn(fmt, arg...) AuDpri(KERN_WARNING, fmt, ##arg) ++#define AuErr(fmt, arg...) AuDpri(KERN_ERR, fmt, ##arg) ++#define AuIOErr(fmt, arg...) AuErr("I/O Error, " fmt, ##arg) ++#define AuWarn1(fmt, arg...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuWarn(fmt, ##arg); \ ++} while (0) ++ ++#define AuErr1(fmt, arg...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuErr(fmt, ##arg); \ ++} while (0) ++ ++#define AuIOErr1(fmt, arg...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuIOErr(fmt, ##arg); \ ++} while (0) ++ ++#define AuUnsupportMsg "This operation is not supported." \ ++ " Please report this application to aufs-users ML." ++#define AuUnsupport(fmt, args...) do { \ ++ AuErr(AuUnsupportMsg "\n" fmt, ##args); \ ++ dump_stack(); \ ++} while (0) ++ ++#define AuTraceErr(e) do { \ ++ if (unlikely((e) < 0)) \ ++ AuDbg("err %d\n", (int)(e)); \ ++} while (0) ++ ++#define AuTraceErrPtr(p) do { \ ++ if (IS_ERR(p)) \ ++ AuDbg("err %ld\n", PTR_ERR(p)); \ ++} while (0) ++ ++/* dirty macros for debug print, use with "%.*s" and caution */ ++#define AuLNPair(qstr) (qstr)->len, (qstr)->name ++#define AuDLNPair(d) AuLNPair(&(d)->d_name) ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_sbinfo; ++struct au_finfo; ++struct dentry; ++#ifdef CONFIG_AUFS_DEBUG ++extern char *au_plevel; ++struct au_nhash; ++void au_dpri_whlist(struct au_nhash *whlist); ++struct au_vdir; ++void au_dpri_vdir(struct au_vdir *vdir); ++struct inode; ++void au_dpri_inode(struct inode *inode); ++void au_dpri_dentry(struct dentry *dentry); ++struct file; ++void au_dpri_file(struct file *filp); ++struct super_block; ++void au_dpri_sb(struct super_block *sb); ++ ++void au_dbg_sleep_jiffy(int jiffy); ++struct iattr; ++void au_dbg_iattr(struct iattr *ia); ++ ++void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen); ++void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen); ++void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen); ++void au_dbg_verify_hf(struct au_finfo *finfo); ++void au_dbg_verify_kthread(void); ++ ++int __init au_debug_init(void); ++void au_debug_sbinfo_init(struct au_sbinfo *sbinfo); ++#define AuDbgWhlist(w) do { \ ++ AuDbg(#w "\n"); \ ++ au_dpri_whlist(w); \ ++} while (0) ++ ++#define AuDbgVdir(v) do { \ ++ AuDbg(#v "\n"); \ ++ au_dpri_vdir(v); \ ++} while (0) ++ ++#define AuDbgInode(i) do { \ ++ AuDbg(#i "\n"); \ ++ au_dpri_inode(i); \ ++} while (0) ++ ++#define AuDbgDentry(d) do { \ ++ AuDbg(#d "\n"); \ ++ au_dpri_dentry(d); \ ++} while (0) ++ ++#define AuDbgFile(f) do { \ ++ AuDbg(#f "\n"); \ ++ au_dpri_file(f); \ ++} while (0) ++ ++#define AuDbgSb(sb) do { \ ++ AuDbg(#sb "\n"); \ ++ au_dpri_sb(sb); \ ++} while (0) ++ ++#define AuDbgSleep(sec) do { \ ++ AuDbg("sleep %d sec\n", sec); \ ++ ssleep(sec); \ ++} while (0) ++ ++#define AuDbgSleepJiffy(jiffy) do { \ ++ AuDbg("sleep %d jiffies\n", jiffy); \ ++ au_dbg_sleep_jiffy(jiffy); \ ++} while (0) ++ ++#define AuDbgIAttr(ia) do { \ ++ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \ ++ au_dbg_iattr(ia); \ ++} while (0) ++#else ++static inline void au_dbg_verify_dir_parent(struct dentry *dentry, ++ unsigned int sigen) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_nondir_parent(struct dentry *dentry, ++ unsigned int sigen) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_hf(struct au_finfo *finfo) ++{ ++ /* empty */ ++} ++static inline void au_dbg_verify_kthread(void) ++{ ++ /* empty */ ++} ++ ++static inline int au_debug_init(void) ++{ ++ return 0; ++} ++static inline void au_debug_sbinfo_init(struct au_sbinfo *sbinfo) ++{ ++ /* empty */ ++} ++#define AuDbgWhlist(w) do {} while (0) ++#define AuDbgVdir(v) do {} while (0) ++#define AuDbgInode(i) do {} while (0) ++#define AuDbgDentry(d) do {} while (0) ++#define AuDbgFile(f) do {} while (0) ++#define AuDbgSb(sb) do {} while (0) ++#define AuDbgSleep(sec) do {} while (0) ++#define AuDbgSleepJiffy(jiffy) do {} while (0) ++#define AuDbgIAttr(ia) do {} while (0) ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_MAGIC_SYSRQ ++int __init au_sysrq_init(void); ++void au_sysrq_fin(void); ++ ++#ifdef CONFIG_HW_CONSOLE ++#define au_dbg_blocked() do { \ ++ WARN_ON(1); \ ++ handle_sysrq('w', vc_cons[fg_console].d->vc_tty); \ ++} while (0) ++#else ++#define au_dbg_blocked() do {} while (0) ++#endif ++ ++#else ++static inline int au_sysrq_init(void) ++{ ++ return 0; ++} ++#define au_sysrq_fin() do {} while (0) ++#define au_dbg_blocked() do {} while (0) ++#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DEBUG_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/dentry.c linux-2.6.31/fs/aufs/dentry.c +--- linux-2.6.31-vanilla/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/dentry.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,879 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * lookup and dentry operations ++ */ ++ ++#include <linux/namei.h> ++#include "aufs.h" ++ ++static void au_h_nd(struct nameidata *h_nd, struct nameidata *nd) ++{ ++ if (nd) { ++ *h_nd = *nd; ++ ++ /* ++ * gave up supporting LOOKUP_CREATE/OPEN for lower fs, ++ * due to whiteout and branch permission. ++ */ ++ h_nd->flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE ++ | LOOKUP_FOLLOW); ++ /* unnecessary? */ ++ h_nd->intent.open.file = NULL; ++ } else ++ memset(h_nd, 0, sizeof(*h_nd)); ++} ++ ++struct au_lkup_one_args { ++ struct dentry **errp; ++ struct qstr *name; ++ struct dentry *h_parent; ++ struct au_branch *br; ++ struct nameidata *nd; ++}; ++ ++struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent, ++ struct au_branch *br, struct nameidata *nd) ++{ ++ struct dentry *h_dentry; ++ int err; ++ struct nameidata h_nd; ++ ++ if (au_test_fs_null_nd(h_parent->d_sb)) ++ return vfsub_lookup_one_len(name->name, h_parent, name->len); ++ ++ au_h_nd(&h_nd, nd); ++ h_nd.path.dentry = h_parent; ++ h_nd.path.mnt = br->br_mnt; ++ ++ err = __lookup_one_len(name->name, &h_nd.last, NULL, name->len); ++ h_dentry = ERR_PTR(err); ++ if (!err) { ++ path_get(&h_nd.path); ++ h_dentry = vfsub_lookup_hash(&h_nd); ++ path_put(&h_nd.path); ++ } ++ ++ return h_dentry; ++} ++ ++static void au_call_lkup_one(void *args) ++{ ++ struct au_lkup_one_args *a = args; ++ *a->errp = au_lkup_one(a->name, a->h_parent, a->br, a->nd); ++} ++ ++#define AuLkup_ALLOW_NEG 1 ++#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) ++#define au_fset_lkup(flags, name) { (flags) |= AuLkup_##name; } ++#define au_fclr_lkup(flags, name) { (flags) &= ~AuLkup_##name; } ++ ++struct au_do_lookup_args { ++ unsigned int flags; ++ mode_t type; ++ struct nameidata *nd; ++}; ++ ++/* ++ * returns positive/negative dentry, NULL or an error. ++ * NULL means whiteout-ed or not-found. ++ */ ++static struct dentry* ++au_do_lookup(struct dentry *h_parent, struct dentry *dentry, ++ aufs_bindex_t bindex, struct qstr *wh_name, ++ struct au_do_lookup_args *args) ++{ ++ struct dentry *h_dentry; ++ struct inode *h_inode, *inode; ++ struct qstr *name; ++ struct au_branch *br; ++ int wh_found, opq; ++ unsigned char wh_able; ++ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG); ++ ++ name = &dentry->d_name; ++ wh_found = 0; ++ br = au_sbr(dentry->d_sb, bindex); ++ wh_able = !!au_br_whable(br->br_perm); ++ if (wh_able) ++ wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0); ++ h_dentry = ERR_PTR(wh_found); ++ if (!wh_found) ++ goto real_lookup; ++ if (unlikely(wh_found < 0)) ++ goto out; ++ ++ /* We found a whiteout */ ++ /* au_set_dbend(dentry, bindex); */ ++ au_set_dbwh(dentry, bindex); ++ if (!allow_neg) ++ return NULL; /* success */ ++ ++ real_lookup: ++ h_dentry = au_lkup_one(name, h_parent, br, args->nd); ++ if (IS_ERR(h_dentry)) ++ goto out; ++ ++ h_inode = h_dentry->d_inode; ++ if (!h_inode) { ++ if (!allow_neg) ++ goto out_neg; ++ } else if (wh_found ++ || (args->type && args->type != (h_inode->i_mode & S_IFMT))) ++ goto out_neg; ++ ++ if (au_dbend(dentry) <= bindex) ++ au_set_dbend(dentry, bindex); ++ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) ++ au_set_dbstart(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, h_dentry); ++ ++ inode = dentry->d_inode; ++ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able ++ || (inode && !S_ISDIR(inode->i_mode))) ++ goto out; /* success */ ++ ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ opq = au_diropq_test(h_dentry, br); ++ mutex_unlock(&h_inode->i_mutex); ++ if (opq > 0) ++ au_set_dbdiropq(dentry, bindex); ++ else if (unlikely(opq < 0)) { ++ au_set_h_dptr(dentry, bindex, NULL); ++ h_dentry = ERR_PTR(opq); ++ } ++ goto out; ++ ++ out_neg: ++ dput(h_dentry); ++ h_dentry = NULL; ++ out: ++ return h_dentry; ++} ++ ++static int au_test_shwh(struct super_block *sb, const struct qstr *name) ++{ ++ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH) ++ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))) ++ return -EPERM; ++ return 0; ++} ++ ++/* ++ * returns the number of lower positive dentries, ++ * otherwise an error. ++ * can be called at unlinking with @type is zero. ++ */ ++int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, ++ struct nameidata *nd) ++{ ++ int npositive, err; ++ aufs_bindex_t bindex, btail, bdiropq; ++ unsigned char isdir; ++ struct qstr whname; ++ struct au_do_lookup_args args = { ++ .flags = 0, ++ .type = type, ++ .nd = nd ++ }; ++ const struct qstr *name = &dentry->d_name; ++ struct dentry *parent; ++ struct inode *inode; ++ ++ parent = dget_parent(dentry); ++ err = au_test_shwh(dentry->d_sb, name); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_wh_name_alloc(&whname, name); ++ if (unlikely(err)) ++ goto out; ++ ++ inode = dentry->d_inode; ++ isdir = !!(inode && S_ISDIR(inode->i_mode)); ++ if (!type) ++ au_fset_lkup(args.flags, ALLOW_NEG); ++ ++ npositive = 0; ++ btail = au_dbtaildir(parent); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ struct dentry *h_parent, *h_dentry; ++ struct inode *h_inode, *h_dir; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry) { ++ if (h_dentry->d_inode) ++ npositive++; ++ if (type != S_IFDIR) ++ break; ++ continue; ++ } ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent) ++ continue; ++ h_dir = h_parent->d_inode; ++ if (!h_dir || !S_ISDIR(h_dir->i_mode)) ++ continue; ++ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname, ++ &args); ++ mutex_unlock(&h_dir->i_mutex); ++ err = PTR_ERR(h_dentry); ++ if (IS_ERR(h_dentry)) ++ goto out_wh; ++ au_fclr_lkup(args.flags, ALLOW_NEG); ++ ++ if (au_dbwh(dentry) >= 0) ++ break; ++ if (!h_dentry) ++ continue; ++ h_inode = h_dentry->d_inode; ++ if (!h_inode) ++ continue; ++ npositive++; ++ if (!args.type) ++ args.type = h_inode->i_mode & S_IFMT; ++ if (args.type != S_IFDIR) ++ break; ++ else if (isdir) { ++ /* the type of lower may be different */ ++ bdiropq = au_dbdiropq(dentry); ++ if (bdiropq >= 0 && bdiropq <= bindex) ++ break; ++ } ++ } ++ ++ if (npositive) { ++ AuLabel(positive); ++ au_update_dbstart(dentry); ++ } ++ err = npositive; ++ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) ++ && au_dbstart(dentry) < 0)) ++ /* both of real entry and whiteout found */ ++ err = -EIO; ++ ++ out_wh: ++ kfree(whname.name); ++ out: ++ dput(parent); ++ return err; ++} ++ ++struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent, ++ struct au_branch *br) ++{ ++ struct dentry *dentry; ++ int wkq_err; ++ ++ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC)) ++ dentry = au_lkup_one(name, parent, br, /*nd*/NULL); ++ else { ++ struct au_lkup_one_args args = { ++ .errp = &dentry, ++ .name = name, ++ .h_parent = parent, ++ .br = br, ++ .nd = NULL ++ }; ++ ++ wkq_err = au_wkq_wait(au_call_lkup_one, &args); ++ if (unlikely(wkq_err)) ++ dentry = ERR_PTR(wkq_err); ++ } ++ ++ return dentry; ++} ++ ++/* ++ * lookup @dentry on @bindex which should be negative. ++ */ ++int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ int err; ++ struct dentry *parent, *h_parent, *h_dentry; ++ struct qstr *name; ++ ++ name = &dentry->d_name; ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bindex); ++ h_dentry = au_sio_lkup_one(name, h_parent, ++ au_sbr(dentry->d_sb, bindex)); ++ err = PTR_ERR(h_dentry); ++ if (IS_ERR(h_dentry)) ++ goto out; ++ if (unlikely(h_dentry->d_inode)) { ++ err = -EIO; ++ AuIOErr("b%d %.*s should be negative.\n", ++ bindex, AuDLNPair(h_dentry)); ++ dput(h_dentry); ++ goto out; ++ } ++ ++ if (bindex < au_dbstart(dentry)) ++ au_set_dbstart(dentry, bindex); ++ if (au_dbend(dentry) < bindex) ++ au_set_dbend(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, h_dentry); ++ err = 0; ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* subset of struct inode */ ++struct au_iattr { ++ unsigned long i_ino; ++ /* unsigned int i_nlink; */ ++ uid_t i_uid; ++ gid_t i_gid; ++ u64 i_version; ++/* ++ loff_t i_size; ++ blkcnt_t i_blocks; ++*/ ++ umode_t i_mode; ++}; ++ ++static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode) ++{ ++ ia->i_ino = h_inode->i_ino; ++ /* ia->i_nlink = h_inode->i_nlink; */ ++ ia->i_uid = h_inode->i_uid; ++ ia->i_gid = h_inode->i_gid; ++ ia->i_version = h_inode->i_version; ++/* ++ ia->i_size = h_inode->i_size; ++ ia->i_blocks = h_inode->i_blocks; ++*/ ++ ia->i_mode = (h_inode->i_mode & S_IFMT); ++} ++ ++static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode) ++{ ++ return ia->i_ino != h_inode->i_ino ++ /* || ia->i_nlink != h_inode->i_nlink */ ++ || ia->i_uid != h_inode->i_uid ++ || ia->i_gid != h_inode->i_gid ++ || ia->i_version != h_inode->i_version ++/* ++ || ia->i_size != h_inode->i_size ++ || ia->i_blocks != h_inode->i_blocks ++*/ ++ || ia->i_mode != (h_inode->i_mode & S_IFMT); ++} ++ ++static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent, ++ struct au_branch *br) ++{ ++ int err; ++ struct au_iattr ia; ++ struct inode *h_inode; ++ struct dentry *h_d; ++ struct super_block *h_sb; ++ ++ err = 0; ++ memset(&ia, -1, sizeof(ia)); ++ h_sb = h_dentry->d_sb; ++ h_inode = h_dentry->d_inode; ++ if (h_inode) ++ au_iattr_save(&ia, h_inode); ++ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb)) ++ /* nfs d_revalidate may return 0 for negative dentry */ ++ /* fuse d_revalidate always return 0 for negative dentry */ ++ goto out; ++ ++ /* main purpose is namei.c:cached_lookup() and d_revalidate */ ++ h_d = au_lkup_one(&h_dentry->d_name, h_parent, br, /*nd*/NULL); ++ err = PTR_ERR(h_d); ++ if (IS_ERR(h_d)) ++ goto out; ++ ++ err = 0; ++ if (unlikely(h_d != h_dentry ++ || h_d->d_inode != h_inode ++ || (h_inode && au_iattr_test(&ia, h_inode)))) ++ err = au_busy_or_stale(); ++ dput(h_d); ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, ++ struct dentry *h_parent, struct au_branch *br) ++{ ++ int err; ++ ++ err = 0; ++ if (udba == AuOpt_UDBA_REVAL) { ++ IMustLock(h_dir); ++ err = (h_dentry->d_parent->d_inode != h_dir); ++ } else if (udba == AuOpt_UDBA_HINOTIFY) ++ err = au_h_verify_dentry(h_dentry, h_parent, br); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_do_refresh_hdentry(struct au_hdentry *p, struct au_dinfo *dinfo, ++ struct dentry *parent) ++{ ++ struct dentry *h_d, *h_dp; ++ struct au_hdentry tmp, *q; ++ struct super_block *sb; ++ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ bend = dinfo->di_bend; ++ bwh = dinfo->di_bwh; ++ bdiropq = dinfo->di_bdiropq; ++ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) { ++ h_d = p->hd_dentry; ++ if (!h_d) ++ continue; ++ ++ h_dp = dget_parent(h_d); ++ if (h_dp == au_h_dptr(parent, bindex)) { ++ dput(h_dp); ++ continue; ++ } ++ ++ new_bindex = au_find_dbindex(parent, h_dp); ++ dput(h_dp); ++ if (dinfo->di_bwh == bindex) ++ bwh = new_bindex; ++ if (dinfo->di_bdiropq == bindex) ++ bdiropq = new_bindex; ++ if (new_bindex < 0) { ++ au_hdput(p); ++ p->hd_dentry = NULL; ++ continue; ++ } ++ ++ /* swap two lower dentries, and loop again */ ++ q = dinfo->di_hdentry + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hd_dentry) { ++ bindex--; ++ p--; ++ } ++ } ++ ++ sb = parent->d_sb; ++ dinfo->di_bwh = -1; ++ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh)) ++ dinfo->di_bwh = bwh; ++ ++ dinfo->di_bdiropq = -1; ++ if (bdiropq >= 0 ++ && bdiropq <= au_sbend(sb) ++ && au_sbr_whable(sb, bdiropq)) ++ dinfo->di_bdiropq = bdiropq; ++ ++ bend = au_dbend(parent); ++ p = dinfo->di_hdentry; ++ for (bindex = 0; bindex <= bend; bindex++, p++) ++ if (p->hd_dentry) { ++ dinfo->di_bstart = bindex; ++ break; ++ } ++ ++ p = dinfo->di_hdentry + bend; ++ for (bindex = bend; bindex >= 0; bindex--, p--) ++ if (p->hd_dentry) { ++ dinfo->di_bend = bindex; ++ break; ++ } ++} ++ ++/* ++ * returns the number of found lower positive dentries, ++ * otherwise an error. ++ */ ++int au_refresh_hdentry(struct dentry *dentry, mode_t type) ++{ ++ int npositive, err; ++ unsigned int sigen; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct super_block *sb; ++ struct dentry *parent; ++ ++ DiMustWriteLock(dentry); ++ ++ sb = dentry->d_sb; ++ AuDebugOn(IS_ROOT(dentry)); ++ sigen = au_sigen(sb); ++ parent = dget_parent(dentry); ++ AuDebugOn(au_digen(parent) != sigen ++ || au_iigen(parent->d_inode) != sigen); ++ ++ dinfo = au_di(dentry); ++ err = au_di_realloc(dinfo, au_sbend(sb) + 1); ++ npositive = err; ++ if (unlikely(err)) ++ goto out; ++ au_do_refresh_hdentry(dinfo->di_hdentry + dinfo->di_bstart, dinfo, ++ parent); ++ ++ npositive = 0; ++ bstart = au_dbstart(parent); ++ if (type != S_IFDIR && dinfo->di_bstart == bstart) ++ goto out_dgen; /* success */ ++ ++ npositive = au_lkup_dentry(dentry, bstart, type, /*nd*/NULL); ++ if (npositive < 0) ++ goto out; ++ if (dinfo->di_bwh >= 0 && dinfo->di_bwh <= dinfo->di_bstart) ++ d_drop(dentry); ++ ++ out_dgen: ++ au_update_digen(dentry); ++ out: ++ dput(parent); ++ AuTraceErr(npositive); ++ return npositive; ++} ++ ++static noinline_for_stack ++int au_do_h_d_reval(struct dentry *h_dentry, struct nameidata *nd, ++ struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ int err, valid; ++ int (*reval)(struct dentry *, struct nameidata *); ++ ++ err = 0; ++ reval = NULL; ++ if (h_dentry->d_op) ++ reval = h_dentry->d_op->d_revalidate; ++ if (!reval) ++ goto out; ++ ++ AuDbg("b%d\n", bindex); ++ if (au_test_fs_null_nd(h_dentry->d_sb)) ++ /* it may return tri-state */ ++ valid = reval(h_dentry, NULL); ++ else { ++ struct nameidata h_nd; ++ int locked; ++ struct dentry *parent; ++ ++ au_h_nd(&h_nd, nd); ++ parent = nd->path.dentry; ++ locked = (nd && nd->path.dentry != dentry); ++ if (locked) ++ di_read_lock_parent(parent, AuLock_IR); ++ BUG_ON(bindex > au_dbend(parent)); ++ h_nd.path.dentry = au_h_dptr(parent, bindex); ++ BUG_ON(!h_nd.path.dentry); ++ h_nd.path.mnt = au_sbr(parent->d_sb, bindex)->br_mnt; ++ path_get(&h_nd.path); ++ valid = reval(h_dentry, &h_nd); ++ path_put(&h_nd.path); ++ if (locked) ++ di_read_unlock(parent, AuLock_IR); ++ } ++ ++ if (unlikely(valid < 0)) ++ err = valid; ++ else if (!valid) ++ err = -EINVAL; ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* todo: remove this */ ++static int h_d_revalidate(struct dentry *dentry, struct inode *inode, ++ struct nameidata *nd, int do_udba) ++{ ++ int err; ++ umode_t mode, h_mode; ++ aufs_bindex_t bindex, btail, bstart, ibs, ibe; ++ unsigned char plus, unhashed, is_root, h_plus; ++ struct inode *first, *h_inode, *h_cached_inode; ++ struct dentry *h_dentry; ++ struct qstr *name, *h_name; ++ ++ err = 0; ++ plus = 0; ++ mode = 0; ++ first = NULL; ++ ibs = -1; ++ ibe = -1; ++ unhashed = !!d_unhashed(dentry); ++ is_root = !!IS_ROOT(dentry); ++ name = &dentry->d_name; ++ ++ /* ++ * Theoretically, REVAL test should be unnecessary in case of INOTIFY. ++ * But inotify doesn't fire some necessary events, ++ * IN_ATTRIB for atime/nlink/pageio ++ * IN_DELETE for NFS dentry ++ * Let's do REVAL test too. ++ */ ++ if (do_udba && inode) { ++ mode = (inode->i_mode & S_IFMT); ++ plus = (inode->i_nlink > 0); ++ first = au_h_iptr(inode, au_ibstart(inode)); ++ ibs = au_ibstart(inode); ++ ibe = au_ibend(inode); ++ } ++ ++ bstart = au_dbstart(dentry); ++ btail = bstart; ++ if (inode && S_ISDIR(inode->i_mode)) ++ btail = au_dbtaildir(dentry); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ ++ AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry)); ++ h_name = &h_dentry->d_name; ++ if (unlikely(do_udba ++ && !is_root ++ && (unhashed != !!d_unhashed(h_dentry) ++ || name->len != h_name->len ++ || memcmp(name->name, h_name->name, name->len)) ++ )) { ++ AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n", ++ unhashed, d_unhashed(h_dentry), ++ AuDLNPair(dentry), AuDLNPair(h_dentry)); ++ goto err; ++ } ++ ++ err = au_do_h_d_reval(h_dentry, nd, dentry, bindex); ++ if (unlikely(err)) ++ /* do not goto err, to keep the errno */ ++ break; ++ ++ /* todo: plink too? */ ++ if (!do_udba) ++ continue; ++ ++ /* UDBA tests */ ++ h_inode = h_dentry->d_inode; ++ if (unlikely(!!inode != !!h_inode)) ++ goto err; ++ ++ h_plus = plus; ++ h_mode = mode; ++ h_cached_inode = h_inode; ++ if (h_inode) { ++ h_mode = (h_inode->i_mode & S_IFMT); ++ h_plus = (h_inode->i_nlink > 0); ++ } ++ if (inode && ibs <= bindex && bindex <= ibe) ++ h_cached_inode = au_h_iptr(inode, bindex); ++ ++ if (unlikely(plus != h_plus ++ || mode != h_mode ++ || h_cached_inode != h_inode)) ++ goto err; ++ continue; ++ ++ err: ++ err = -EINVAL; ++ break; ++ } ++ ++ return err; ++} ++ ++static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct dentry *parent; ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ if (au_digen(dentry) == sigen && au_iigen(inode) == sigen) ++ return 0; ++ ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ AuDebugOn(au_digen(parent) != sigen ++ || au_iigen(parent->d_inode) != sigen); ++ au_dbg_verify_gen(parent, sigen); ++ ++ /* returns a number of positive dentries */ ++ err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT); ++ if (err >= 0) ++ err = au_refresh_hinode(inode, dentry); ++ ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ return err; ++} ++ ++int au_reval_dpath(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct dentry *d, *parent; ++ struct inode *inode; ++ ++ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS)) ++ return simple_reval_dpath(dentry, sigen); ++ ++ /* slow loop, keep it simple and stupid */ ++ /* cf: au_cpup_dirs() */ ++ err = 0; ++ parent = NULL; ++ while (au_digen(dentry) != sigen ++ || au_iigen(dentry->d_inode) != sigen) { ++ d = dentry; ++ while (1) { ++ dput(parent); ++ parent = dget_parent(d); ++ if (au_digen(parent) == sigen ++ && au_iigen(parent->d_inode) == sigen) ++ break; ++ d = parent; ++ } ++ ++ inode = d->d_inode; ++ if (d != dentry) ++ di_write_lock_child(d); ++ ++ /* someone might update our dentry while we were sleeping */ ++ if (au_digen(d) != sigen || au_iigen(d->d_inode) != sigen) { ++ di_read_lock_parent(parent, AuLock_IR); ++ /* returns a number of positive dentries */ ++ err = au_refresh_hdentry(d, inode->i_mode & S_IFMT); ++ if (err >= 0) ++ err = au_refresh_hinode(inode, d); ++ di_read_unlock(parent, AuLock_IR); ++ } ++ ++ if (d != dentry) ++ di_write_unlock(d); ++ dput(parent); ++ if (unlikely(err)) ++ break; ++ } ++ ++ return err; ++} ++ ++/* ++ * if valid returns 1, otherwise 0. ++ */ ++static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ++{ ++ int valid, err; ++ unsigned int sigen; ++ unsigned char do_udba; ++ struct super_block *sb; ++ struct inode *inode; ++ ++ err = -EINVAL; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW); ++ sigen = au_sigen(sb); ++ if (au_digen(dentry) != sigen) { ++ AuDebugOn(IS_ROOT(dentry)); ++ if (inode) ++ err = au_reval_dpath(dentry, sigen); ++ if (unlikely(err)) ++ goto out_dgrade; ++ AuDebugOn(au_digen(dentry) != sigen); ++ } ++ if (inode && au_iigen(inode) != sigen) { ++ AuDebugOn(IS_ROOT(dentry)); ++ err = au_refresh_hinode(inode, dentry); ++ if (unlikely(err)) ++ goto out_dgrade; ++ AuDebugOn(au_iigen(inode) != sigen); ++ } ++ di_downgrade_lock(dentry, AuLock_IR); ++ ++ AuDebugOn(au_digen(dentry) != sigen); ++ AuDebugOn(inode && au_iigen(inode) != sigen); ++ err = -EINVAL; ++ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE); ++ if (do_udba && inode) { ++ aufs_bindex_t bstart = au_ibstart(inode); ++ ++ if (bstart >= 0 ++ && au_test_higen(inode, au_h_iptr(inode, bstart))) ++ goto out; ++ } ++ ++ err = h_d_revalidate(dentry, inode, nd, do_udba); ++ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) ++ /* both of real entry and whiteout found */ ++ err = -EIO; ++ goto out; ++ ++ out_dgrade: ++ di_downgrade_lock(dentry, AuLock_IR); ++ out: ++ aufs_read_unlock(dentry, AuLock_IR); ++ AuTraceErr(err); ++ valid = !err; ++ if (!valid) ++ AuDbg("%.*s invalid\n", AuDLNPair(dentry)); ++ return valid; ++} ++ ++static void aufs_d_release(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ aufs_bindex_t bend, bindex; ++ ++ dinfo = dentry->d_fsdata; ++ if (!dinfo) ++ return; ++ ++ /* dentry may not be revalidated */ ++ bindex = dinfo->di_bstart; ++ if (bindex >= 0) { ++ struct au_hdentry *p; ++ ++ bend = dinfo->di_bend; ++ p = dinfo->di_hdentry + bindex; ++ while (bindex++ <= bend) { ++ if (p->hd_dentry) ++ au_hdput(p); ++ p++; ++ } ++ } ++ kfree(dinfo->di_hdentry); ++ AuRwDestroy(&dinfo->di_rwsem); ++ au_cache_free_dinfo(dinfo); ++ au_hin_di_reinit(dentry); ++} ++ ++struct dentry_operations aufs_dop = { ++ .d_revalidate = aufs_d_revalidate, ++ .d_release = aufs_d_release ++}; +diff -Nur linux-2.6.31-vanilla/fs/aufs/dentry.h linux-2.6.31/fs/aufs/dentry.h +--- linux-2.6.31-vanilla/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/dentry.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,231 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * lookup and dentry operations ++ */ ++ ++#ifndef __AUFS_DENTRY_H__ ++#define __AUFS_DENTRY_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/dcache.h> ++#include <linux/aufs_type.h> ++#include "rwsem.h" ++ ++/* make a single member structure for future use */ ++/* todo: remove this structure */ ++struct au_hdentry { ++ struct dentry *hd_dentry; ++}; ++ ++struct au_dinfo { ++ atomic_t di_generation; ++ ++ struct au_rwsem di_rwsem; ++ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq; ++ struct au_hdentry *di_hdentry; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dentry.c */ ++extern struct dentry_operations aufs_dop; ++struct au_branch; ++struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent, ++ struct au_branch *br, struct nameidata *nd); ++struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent, ++ struct au_branch *br); ++int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, ++ struct dentry *h_parent, struct au_branch *br); ++ ++int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, ++ struct nameidata *nd); ++int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex); ++int au_refresh_hdentry(struct dentry *dentry, mode_t type); ++int au_reval_dpath(struct dentry *dentry, unsigned int sigen); ++ ++/* dinfo.c */ ++int au_alloc_dinfo(struct dentry *dentry); ++int au_di_realloc(struct au_dinfo *dinfo, int nbr); ++ ++void di_read_lock(struct dentry *d, int flags, unsigned int lsc); ++void di_read_unlock(struct dentry *d, int flags); ++void di_downgrade_lock(struct dentry *d, int flags); ++void di_write_lock(struct dentry *d, unsigned int lsc); ++void di_write_unlock(struct dentry *d); ++void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir); ++void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir); ++void di_write_unlock2(struct dentry *d1, struct dentry *d2); ++ ++struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex); ++aufs_bindex_t au_dbtail(struct dentry *dentry); ++aufs_bindex_t au_dbtaildir(struct dentry *dentry); ++ ++void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++void au_update_digen(struct dentry *dentry); ++void au_update_dbrange(struct dentry *dentry, int do_put_zero); ++void au_update_dbstart(struct dentry *dentry); ++void au_update_dbend(struct dentry *dentry); ++int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_dinfo *au_di(struct dentry *dentry) ++{ ++ return dentry->d_fsdata; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for dinfo */ ++enum { ++ AuLsc_DI_CHILD, /* child first */ ++ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hinotify */ ++ AuLsc_DI_CHILD3, /* copyup dirs */ ++ AuLsc_DI_PARENT, ++ AuLsc_DI_PARENT2, ++ AuLsc_DI_PARENT3 ++}; ++ ++/* ++ * di_read_lock_child, di_write_lock_child, ++ * di_read_lock_child2, di_write_lock_child2, ++ * di_read_lock_child3, di_write_lock_child3, ++ * di_read_lock_parent, di_write_lock_parent, ++ * di_read_lock_parent2, di_write_lock_parent2, ++ * di_read_lock_parent3, di_write_lock_parent3, ++ */ ++#define AuReadLockFunc(name, lsc) \ ++static inline void di_read_lock_##name(struct dentry *d, int flags) \ ++{ di_read_lock(d, flags, AuLsc_DI_##lsc); } ++ ++#define AuWriteLockFunc(name, lsc) \ ++static inline void di_write_lock_##name(struct dentry *d) \ ++{ di_write_lock(d, AuLsc_DI_##lsc); } ++ ++#define AuRWLockFuncs(name, lsc) \ ++ AuReadLockFunc(name, lsc) \ ++ AuWriteLockFunc(name, lsc) ++ ++AuRWLockFuncs(child, CHILD); ++AuRWLockFuncs(child2, CHILD2); ++AuRWLockFuncs(child3, CHILD3); ++AuRWLockFuncs(parent, PARENT); ++AuRWLockFuncs(parent2, PARENT2); ++AuRWLockFuncs(parent3, PARENT3); ++ ++#undef AuReadLockFunc ++#undef AuWriteLockFunc ++#undef AuRWLockFuncs ++ ++#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem) ++#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem) ++#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: memory barrier? */ ++static inline unsigned int au_digen(struct dentry *d) ++{ ++ return atomic_read(&au_di(d)->di_generation); ++} ++ ++static inline void au_h_dentry_init(struct au_hdentry *hdentry) ++{ ++ hdentry->hd_dentry = NULL; ++} ++ ++static inline void au_hdput(struct au_hdentry *hd) ++{ ++ dput(hd->hd_dentry); ++} ++ ++static inline aufs_bindex_t au_dbstart(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bstart; ++} ++ ++static inline aufs_bindex_t au_dbend(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bend; ++} ++ ++static inline aufs_bindex_t au_dbwh(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bwh; ++} ++ ++static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bdiropq; ++} ++ ++/* todo: hard/soft set? */ ++static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ au_di(dentry)->di_bstart = bindex; ++} ++ ++static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ au_di(dentry)->di_bend = bindex; ++} ++ ++static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ /* dbwh can be outside of bstart - bend range */ ++ au_di(dentry)->di_bwh = bindex; ++} ++ ++static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ au_di(dentry)->di_bdiropq = bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_HINOTIFY ++static inline void au_digen_dec(struct dentry *d) ++{ ++ atomic_dec_return(&au_di(d)->di_generation); ++} ++ ++static inline void au_hin_di_reinit(struct dentry *dentry) ++{ ++ dentry->d_fsdata = NULL; ++} ++#else ++static inline void au_hin_di_reinit(struct dentry *dentry __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* CONFIG_AUFS_HINOTIFY */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DENTRY_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/dinfo.c linux-2.6.31/fs/aufs/dinfo.c +--- linux-2.6.31-vanilla/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/dinfo.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,367 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * dentry private data ++ */ ++ ++#include "aufs.h" ++ ++int au_alloc_dinfo(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ struct super_block *sb; ++ int nbr; ++ ++ dinfo = au_cache_alloc_dinfo(); ++ if (unlikely(!dinfo)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ nbr = au_sbend(sb) + 1; ++ if (nbr <= 0) ++ nbr = 1; ++ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS); ++ if (unlikely(!dinfo->di_hdentry)) ++ goto out_dinfo; ++ ++ atomic_set(&dinfo->di_generation, au_sigen(sb)); ++ /* smp_mb(); */ /* atomic_set */ ++ au_rw_init_wlock_nested(&dinfo->di_rwsem, AuLsc_DI_CHILD); ++ dinfo->di_bstart = -1; ++ dinfo->di_bend = -1; ++ dinfo->di_bwh = -1; ++ dinfo->di_bdiropq = -1; ++ ++ dentry->d_fsdata = dinfo; ++ dentry->d_op = &aufs_dop; ++ return 0; /* success */ ++ ++ out_dinfo: ++ au_cache_free_dinfo(dinfo); ++ out: ++ return -ENOMEM; ++} ++ ++int au_di_realloc(struct au_dinfo *dinfo, int nbr) ++{ ++ int err, sz; ++ struct au_hdentry *hdp; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*hdp) * (dinfo->di_bend + 1); ++ if (!sz) ++ sz = sizeof(*hdp); ++ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS); ++ if (hdp) { ++ dinfo->di_hdentry = hdp; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void do_ii_write_lock(struct inode *inode, unsigned int lsc) ++{ ++ switch (lsc) { ++ case AuLsc_DI_CHILD: ++ ii_write_lock_child(inode); ++ break; ++ case AuLsc_DI_CHILD2: ++ ii_write_lock_child2(inode); ++ break; ++ case AuLsc_DI_CHILD3: ++ ii_write_lock_child3(inode); ++ break; ++ case AuLsc_DI_PARENT: ++ ii_write_lock_parent(inode); ++ break; ++ case AuLsc_DI_PARENT2: ++ ii_write_lock_parent2(inode); ++ break; ++ case AuLsc_DI_PARENT3: ++ ii_write_lock_parent3(inode); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++static void do_ii_read_lock(struct inode *inode, unsigned int lsc) ++{ ++ switch (lsc) { ++ case AuLsc_DI_CHILD: ++ ii_read_lock_child(inode); ++ break; ++ case AuLsc_DI_CHILD2: ++ ii_read_lock_child2(inode); ++ break; ++ case AuLsc_DI_CHILD3: ++ ii_read_lock_child3(inode); ++ break; ++ case AuLsc_DI_PARENT: ++ ii_read_lock_parent(inode); ++ break; ++ case AuLsc_DI_PARENT2: ++ ii_read_lock_parent2(inode); ++ break; ++ case AuLsc_DI_PARENT3: ++ ii_read_lock_parent3(inode); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++void di_read_lock(struct dentry *d, int flags, unsigned int lsc) ++{ ++ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc); ++ if (d->d_inode) { ++ if (au_ftest_lock(flags, IW)) ++ do_ii_write_lock(d->d_inode, lsc); ++ else if (au_ftest_lock(flags, IR)) ++ do_ii_read_lock(d->d_inode, lsc); ++ } ++} ++ ++void di_read_unlock(struct dentry *d, int flags) ++{ ++ if (d->d_inode) { ++ if (au_ftest_lock(flags, IW)) ++ ii_write_unlock(d->d_inode); ++ else if (au_ftest_lock(flags, IR)) ++ ii_read_unlock(d->d_inode); ++ } ++ au_rw_read_unlock(&au_di(d)->di_rwsem); ++} ++ ++void di_downgrade_lock(struct dentry *d, int flags) ++{ ++ if (d->d_inode && au_ftest_lock(flags, IR)) ++ ii_downgrade_lock(d->d_inode); ++ au_rw_dgrade_lock(&au_di(d)->di_rwsem); ++} ++ ++void di_write_lock(struct dentry *d, unsigned int lsc) ++{ ++ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc); ++ if (d->d_inode) ++ do_ii_write_lock(d->d_inode, lsc); ++} ++ ++void di_write_unlock(struct dentry *d) ++{ ++ if (d->d_inode) ++ ii_write_unlock(d->d_inode); ++ au_rw_write_unlock(&au_di(d)->di_rwsem); ++} ++ ++void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir) ++{ ++ AuDebugOn(d1 == d2 ++ || d1->d_inode == d2->d_inode ++ || d1->d_sb != d2->d_sb); ++ ++ if (isdir && au_test_subdir(d1, d2)) { ++ di_write_lock_child(d1); ++ di_write_lock_child2(d2); ++ } else { ++ /* there should be no races */ ++ di_write_lock_child(d2); ++ di_write_lock_child2(d1); ++ } ++} ++ ++void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) ++{ ++ AuDebugOn(d1 == d2 ++ || d1->d_inode == d2->d_inode ++ || d1->d_sb != d2->d_sb); ++ ++ if (isdir && au_test_subdir(d1, d2)) { ++ di_write_lock_parent(d1); ++ di_write_lock_parent2(d2); ++ } else { ++ /* there should be no races */ ++ di_write_lock_parent(d2); ++ di_write_lock_parent2(d1); ++ } ++} ++ ++void di_write_unlock2(struct dentry *d1, struct dentry *d2) ++{ ++ di_write_unlock(d1); ++ if (d1->d_inode == d2->d_inode) ++ au_rw_write_unlock(&au_di(d2)->di_rwsem); ++ else ++ di_write_unlock(d2); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ struct dentry *d; ++ ++ DiMustAnyLock(dentry); ++ ++ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) ++ return NULL; ++ AuDebugOn(bindex < 0); ++ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry; ++ AuDebugOn(d && (atomic_read(&d->d_count) <= 0)); ++ return d; ++} ++ ++aufs_bindex_t au_dbtail(struct dentry *dentry) ++{ ++ aufs_bindex_t bend, bwh; ++ ++ bend = au_dbend(dentry); ++ if (0 <= bend) { ++ bwh = au_dbwh(dentry); ++ if (!bwh) ++ return bwh; ++ if (0 < bwh && bwh < bend) ++ return bwh - 1; ++ } ++ return bend; ++} ++ ++aufs_bindex_t au_dbtaildir(struct dentry *dentry) ++{ ++ aufs_bindex_t bend, bopq; ++ ++ bend = au_dbtail(dentry); ++ if (0 <= bend) { ++ bopq = au_dbdiropq(dentry); ++ if (0 <= bopq && bopq < bend) ++ bend = bopq; ++ } ++ return bend; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_dentry) ++{ ++ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; ++ ++ DiMustWriteLock(dentry); ++ ++ if (hd->hd_dentry) ++ au_hdput(hd); ++ hd->hd_dentry = h_dentry; ++} ++ ++void au_update_digen(struct dentry *dentry) ++{ ++ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++void au_update_dbrange(struct dentry *dentry, int do_put_zero) ++{ ++ struct au_dinfo *dinfo; ++ struct dentry *h_d; ++ ++ DiMustWriteLock(dentry); ++ ++ dinfo = au_di(dentry); ++ if (!dinfo || dinfo->di_bstart < 0) ++ return; ++ ++ if (do_put_zero) { ++ aufs_bindex_t bindex, bend; ++ ++ bend = dinfo->di_bend; ++ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) { ++ h_d = dinfo->di_hdentry[0 + bindex].hd_dentry; ++ if (h_d && !h_d->d_inode) ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++ } ++ ++ dinfo->di_bstart = -1; ++ while (++dinfo->di_bstart <= dinfo->di_bend) ++ if (dinfo->di_hdentry[0 + dinfo->di_bstart].hd_dentry) ++ break; ++ if (dinfo->di_bstart > dinfo->di_bend) { ++ dinfo->di_bstart = -1; ++ dinfo->di_bend = -1; ++ return; ++ } ++ ++ dinfo->di_bend++; ++ while (0 <= --dinfo->di_bend) ++ if (dinfo->di_hdentry[0 + dinfo->di_bend].hd_dentry) ++ break; ++ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0); ++} ++ ++void au_update_dbstart(struct dentry *dentry) ++{ ++ aufs_bindex_t bindex, bend; ++ struct dentry *h_dentry; ++ ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ if (h_dentry->d_inode) { ++ au_set_dbstart(dentry, bindex); ++ return; ++ } ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++} ++ ++void au_update_dbend(struct dentry *dentry) ++{ ++ aufs_bindex_t bindex, bstart; ++ struct dentry *h_dentry; ++ ++ bstart = au_dbstart(dentry); ++ for (bindex = au_dbend(dentry); bindex <= bstart; bindex--) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ if (h_dentry->d_inode) { ++ au_set_dbend(dentry, bindex); ++ return; ++ } ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++} ++ ++int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry) ++{ ++ aufs_bindex_t bindex, bend; ++ ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) ++ if (au_h_dptr(dentry, bindex) == h_dentry) ++ return bindex; ++ return -1; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/dir.c linux-2.6.31/fs/aufs/dir.c +--- linux-2.6.31-vanilla/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/dir.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,593 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * directory operations ++ */ ++ ++#include <linux/file.h> ++#include <linux/fs_stack.h> ++#include "aufs.h" ++ ++void au_add_nlink(struct inode *dir, struct inode *h_dir) ++{ ++ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); ++ ++ dir->i_nlink += h_dir->i_nlink - 2; ++ if (h_dir->i_nlink < 2) ++ dir->i_nlink += 2; ++} ++ ++void au_sub_nlink(struct inode *dir, struct inode *h_dir) ++{ ++ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); ++ ++ dir->i_nlink -= h_dir->i_nlink - 2; ++ if (h_dir->i_nlink < 2) ++ dir->i_nlink -= 2; ++} ++ ++loff_t au_dir_size(struct file *file, struct dentry *dentry) ++{ ++ loff_t sz; ++ aufs_bindex_t bindex, bend; ++ struct file *h_file; ++ struct dentry *h_dentry; ++ ++ sz = 0; ++ if (file) { ++ AuDebugOn(!file->f_dentry); ++ AuDebugOn(!file->f_dentry->d_inode); ++ AuDebugOn(!S_ISDIR(file->f_dentry->d_inode->i_mode)); ++ ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); ++ bindex <= bend && sz < KMALLOC_MAX_SIZE; ++ bindex++) { ++ h_file = au_h_fptr(file, bindex); ++ if (h_file ++ && h_file->f_dentry ++ && h_file->f_dentry->d_inode) ++ sz += i_size_read(h_file->f_dentry->d_inode); ++ } ++ } else { ++ AuDebugOn(!dentry); ++ AuDebugOn(!dentry->d_inode); ++ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode)); ++ ++ bend = au_dbtaildir(dentry); ++ for (bindex = au_dbstart(dentry); ++ bindex <= bend && sz < KMALLOC_MAX_SIZE; ++ bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) ++ sz += i_size_read(h_dentry->d_inode); ++ } ++ } ++ if (sz < KMALLOC_MAX_SIZE) ++ sz = roundup_pow_of_two(sz); ++ if (sz > KMALLOC_MAX_SIZE) ++ sz = KMALLOC_MAX_SIZE; ++ else if (sz < NAME_MAX) { ++ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX); ++ sz = AUFS_RDBLK_DEF; ++ } ++ return sz; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int reopen_dir(struct file *file) ++{ ++ int err; ++ unsigned int flags; ++ aufs_bindex_t bindex, btail, bstart; ++ struct dentry *dentry, *h_dentry; ++ struct file *h_file; ++ ++ /* open all lower dirs */ ++ dentry = file->f_dentry; ++ bstart = au_dbstart(dentry); ++ for (bindex = au_fbstart(file); bindex < bstart; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbstart(file, bstart); ++ ++ btail = au_dbtaildir(dentry); ++ for (bindex = au_fbend(file); btail < bindex; bindex--) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbend(file, btail); ++ ++ spin_lock(&file->f_lock); ++ flags = file->f_flags; ++ spin_unlock(&file->f_lock); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ h_file = au_h_fptr(file, bindex); ++ if (h_file) ++ continue; ++ ++ h_file = au_h_open(dentry, bindex, flags, file); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; /* close all? */ ++ au_set_h_fptr(file, bindex, h_file); ++ } ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ err = 0; ++ ++ out: ++ return err; ++} ++ ++static int do_open_dir(struct file *file, int flags) ++{ ++ int err; ++ aufs_bindex_t bindex, btail; ++ struct dentry *dentry, *h_dentry; ++ struct file *h_file; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ dentry = file->f_dentry; ++ au_set_fvdir_cache(file, NULL); ++ au_fi(file)->fi_maintain_plink = 0; ++ file->f_version = dentry->d_inode->i_version; ++ bindex = au_dbstart(dentry); ++ au_set_fbstart(file, bindex); ++ btail = au_dbtaildir(dentry); ++ au_set_fbend(file, btail); ++ for (; !err && bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ ++ h_file = au_h_open(dentry, bindex, flags, file); ++ if (IS_ERR(h_file)) { ++ err = PTR_ERR(h_file); ++ break; ++ } ++ au_set_h_fptr(file, bindex, h_file); ++ } ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ if (!err) ++ return 0; /* success */ ++ ++ /* close all */ ++ for (bindex = au_fbstart(file); bindex <= btail; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbstart(file, -1); ++ au_set_fbend(file, -1); ++ return err; ++} ++ ++static int aufs_open_dir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ return au_do_open(file, do_open_dir); ++} ++ ++static int aufs_release_dir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ struct au_vdir *vdir_cache; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ sb = file->f_dentry->d_sb; ++ si_noflush_read_lock(sb); ++ fi_write_lock(file); ++ vdir_cache = au_fvdir_cache(file); ++ if (vdir_cache) ++ au_vdir_free(vdir_cache); ++ if (au_fi(file)->fi_maintain_plink) { ++ sbinfo = au_sbi(sb); ++ /* clear the flag without write-lock */ ++ sbinfo->au_si_status &= ~AuSi_MAINTAIN_PLINK; ++ smp_mb(); ++ wake_up_all(&sbinfo->si_plink_wq); ++ } ++ fi_write_unlock(file); ++ au_finfo_fin(file); ++ si_read_unlock(sb); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) { ++ struct path h_path; ++ struct inode *h_inode; ++ ++ if (au_test_ro(sb, bindex, inode)) ++ continue; ++ h_path.dentry = au_h_dptr(dentry, bindex); ++ if (!h_path.dentry) ++ continue; ++ h_inode = h_path.dentry->d_inode; ++ if (!h_inode) ++ continue; ++ ++ /* no mnt_want_write() */ ++ /* cf. fs/nsfd/vfs.c and fs/nfsd/nfs4recover.c */ ++ /* todo: inotiry fired? */ ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ mutex_lock(&h_inode->i_mutex); ++ err = filemap_fdatawrite(h_inode->i_mapping); ++ AuDebugOn(!h_inode->i_fop); ++ if (!err && h_inode->i_fop->fsync) ++ err = h_inode->i_fop->fsync(NULL, h_path.dentry, ++ datasync); ++ if (!err) ++ err = filemap_fdatawrite(h_inode->i_mapping); ++ if (!err) ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++ mutex_unlock(&h_inode->i_mutex); ++ } ++ ++ return err; ++} ++ ++static int au_do_fsync_dir(struct file *file, int datasync) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct file *h_file; ++ struct super_block *sb; ++ struct inode *inode; ++ struct mutex *h_mtx; ++ ++ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ sb = file->f_dentry->d_sb; ++ inode = file->f_dentry->d_inode; ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { ++ h_file = au_h_fptr(file, bindex); ++ if (!h_file || au_test_ro(sb, bindex, inode)) ++ continue; ++ ++ err = vfs_fsync(h_file, h_file->f_dentry, datasync); ++ if (!err) { ++ h_mtx = &h_file->f_dentry->d_inode->i_mutex; ++ mutex_lock(h_mtx); ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ mutex_unlock(h_mtx); ++ } ++ } ++ ++ out: ++ return err; ++} ++ ++/* ++ * @file may be NULL ++ */ ++static int aufs_fsync_dir(struct file *file, struct dentry *dentry, ++ int datasync) ++{ ++ int err; ++ struct super_block *sb; ++ ++ IMustLock(dentry->d_inode); ++ ++ err = 0; ++ sb = dentry->d_sb; ++ si_noflush_read_lock(sb); ++ if (file) ++ err = au_do_fsync_dir(file, datasync); ++ else { ++ di_write_lock_child(dentry); ++ err = au_do_fsync_dir_no_file(dentry, datasync); ++ } ++ au_cpup_attr_timesizes(dentry->d_inode); ++ di_write_unlock(dentry); ++ if (file) ++ fi_write_unlock(file); ++ ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir) ++{ ++ int err; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ err = au_vdir_init(file); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ if (!au_test_nfsd(current)) { ++ err = au_vdir_fill_de(file, dirent, filldir); ++ fsstack_copy_attr_atime(inode, ++ au_h_iptr(inode, au_ibstart(inode))); ++ } else { ++ /* ++ * nfsd filldir may call lookup_one_len(), vfs_getattr(), ++ * encode_fh() and others. ++ */ ++ struct inode *h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ si_read_unlock(sb); ++ lockdep_off(); ++ err = au_vdir_fill_de(file, dirent, filldir); ++ lockdep_on(); ++ fsstack_copy_attr_atime(inode, h_inode); ++ fi_write_unlock(file); ++ ++ AuTraceErr(err); ++ return err; ++ } ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuTestEmpty_WHONLY 1 ++#define AuTestEmpty_CALLED (1 << 1) ++#define AuTestEmpty_SHWH (1 << 2) ++#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) ++#define au_fset_testempty(flags, name) { (flags) |= AuTestEmpty_##name; } ++#define au_fclr_testempty(flags, name) { (flags) &= ~AuTestEmpty_##name; } ++ ++#ifndef CONFIG_AUFS_SHWH ++#undef AuTestEmpty_SHWH ++#define AuTestEmpty_SHWH 0 ++#endif ++ ++struct test_empty_arg { ++ struct au_nhash *whlist; ++ unsigned int flags; ++ int err; ++ aufs_bindex_t bindex; ++}; ++ ++static int test_empty_cb(void *__arg, const char *__name, int namelen, ++ loff_t offset __maybe_unused, u64 ino, ++ unsigned int d_type) ++{ ++ struct test_empty_arg *arg = __arg; ++ char *name = (void *)__name; ++ ++ arg->err = 0; ++ au_fset_testempty(arg->flags, CALLED); ++ /* smp_mb(); */ ++ if (name[0] == '.' ++ && (namelen == 1 || (name[1] == '.' && namelen == 2))) ++ goto out; /* success */ ++ ++ if (namelen <= AUFS_WH_PFX_LEN ++ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ if (au_ftest_testempty(arg->flags, WHONLY) ++ && !au_nhash_test_known_wh(arg->whlist, name, namelen)) ++ arg->err = -ENOTEMPTY; ++ goto out; ++ } ++ ++ name += AUFS_WH_PFX_LEN; ++ namelen -= AUFS_WH_PFX_LEN; ++ if (!au_nhash_test_known_wh(arg->whlist, name, namelen)) ++ arg->err = au_nhash_append_wh ++ (arg->whlist, name, namelen, ino, d_type, arg->bindex, ++ au_ftest_testempty(arg->flags, SHWH)); ++ ++ out: ++ /* smp_mb(); */ ++ AuTraceErr(arg->err); ++ return arg->err; ++} ++ ++static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg) ++{ ++ int err; ++ struct file *h_file; ++ ++ h_file = au_h_open(dentry, arg->bindex, ++ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE, ++ /*file*/NULL); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ err = 0; ++ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) ++ && !h_file->f_dentry->d_inode->i_nlink) ++ goto out_put; ++ ++ do { ++ arg->err = 0; ++ au_fclr_testempty(arg->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_readdir(h_file, test_empty_cb, arg); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err && au_ftest_testempty(arg->flags, CALLED)); ++ ++ out_put: ++ fput(h_file); ++ au_sbr_put(dentry->d_sb, arg->bindex); ++ out: ++ return err; ++} ++ ++struct do_test_empty_args { ++ int *errp; ++ struct dentry *dentry; ++ struct test_empty_arg *arg; ++}; ++ ++static void call_do_test_empty(void *args) ++{ ++ struct do_test_empty_args *a = args; ++ *a->errp = do_test_empty(a->dentry, a->arg); ++} ++ ++static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg) ++{ ++ int err, wkq_err; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, arg->bindex); ++ h_inode = h_dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ); ++ mutex_unlock(&h_inode->i_mutex); ++ if (!err) ++ err = do_test_empty(dentry, arg); ++ else { ++ struct do_test_empty_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .arg = arg ++ }; ++ unsigned int flags = arg->flags; ++ ++ wkq_err = au_wkq_wait(call_do_test_empty, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ arg->flags = flags; ++ } ++ ++ return err; ++} ++ ++int au_test_empty_lower(struct dentry *dentry) ++{ ++ int err; ++ unsigned int rdhash; ++ aufs_bindex_t bindex, bstart, btail; ++ struct au_nhash whlist; ++ struct test_empty_arg arg; ++ ++ SiMustAnyLock(dentry->d_sb); ++ ++ rdhash = au_sbi(dentry->d_sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry)); ++ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ ++ arg.flags = 0; ++ arg.whlist = &whlist; ++ bstart = au_dbstart(dentry); ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) ++ au_fset_testempty(arg.flags, SHWH); ++ arg.bindex = bstart; ++ err = do_test_empty(dentry, &arg); ++ if (unlikely(err)) ++ goto out_whlist; ++ ++ au_fset_testempty(arg.flags, WHONLY); ++ btail = au_dbtaildir(dentry); ++ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) { ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) { ++ arg.bindex = bindex; ++ err = do_test_empty(dentry, &arg); ++ } ++ } ++ ++ out_whlist: ++ au_nhash_wh_free(&whlist); ++ out: ++ return err; ++} ++ ++int au_test_empty(struct dentry *dentry, struct au_nhash *whlist) ++{ ++ int err; ++ struct test_empty_arg arg; ++ aufs_bindex_t bindex, btail; ++ ++ err = 0; ++ arg.whlist = whlist; ++ arg.flags = AuTestEmpty_WHONLY; ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) ++ au_fset_testempty(arg.flags, SHWH); ++ btail = au_dbtaildir(dentry); ++ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) { ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) { ++ arg.bindex = bindex; ++ err = sio_test_empty(dentry, &arg); ++ } ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++const struct file_operations aufs_dir_fop = { ++ .read = generic_read_dir, ++ .readdir = aufs_readdir, ++ .unlocked_ioctl = aufs_ioctl_dir, ++ .open = aufs_open_dir, ++ .release = aufs_release_dir, ++ .flush = aufs_flush, ++ .fsync = aufs_fsync_dir ++}; +diff -Nur linux-2.6.31-vanilla/fs/aufs/dir.h linux-2.6.31/fs/aufs/dir.h +--- linux-2.6.31-vanilla/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/dir.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,127 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * directory operations ++ */ ++ ++#ifndef __AUFS_DIR_H__ ++#define __AUFS_DIR_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/fs.h> ++#include <linux/aufs_type.h> ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* need to be faster and smaller */ ++ ++struct au_nhash { ++ unsigned int nh_num; ++ struct hlist_head *nh_head; ++}; ++ ++struct au_vdir_destr { ++ unsigned char len; ++ unsigned char name[0]; ++} __packed; ++ ++struct au_vdir_dehstr { ++ struct hlist_node hash; ++ struct au_vdir_destr *str; ++}; ++ ++struct au_vdir_de { ++ ino_t de_ino; ++ unsigned char de_type; ++ /* caution: packed */ ++ struct au_vdir_destr de_str; ++} __packed; ++ ++struct au_vdir_wh { ++ struct hlist_node wh_hash; ++#ifdef CONFIG_AUFS_SHWH ++ ino_t wh_ino; ++ aufs_bindex_t wh_bindex; ++ unsigned char wh_type; ++#else ++ aufs_bindex_t wh_bindex; ++#endif ++ /* caution: packed */ ++ struct au_vdir_destr wh_str; ++} __packed; ++ ++union au_vdir_deblk_p { ++ unsigned char *deblk; ++ struct au_vdir_de *de; ++}; ++ ++struct au_vdir { ++ unsigned char **vd_deblk; ++ unsigned long vd_nblk; ++ struct { ++ unsigned long ul; ++ union au_vdir_deblk_p p; ++ } vd_last; ++ ++ unsigned long vd_version; ++ unsigned int vd_deblk_sz; ++ unsigned long vd_jiffy; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dir.c */ ++extern const struct file_operations aufs_dir_fop; ++void au_add_nlink(struct inode *dir, struct inode *h_dir); ++void au_sub_nlink(struct inode *dir, struct inode *h_dir); ++loff_t au_dir_size(struct file *file, struct dentry *dentry); ++int au_test_empty_lower(struct dentry *dentry); ++int au_test_empty(struct dentry *dentry, struct au_nhash *whlist); ++ ++/* vdir.c */ ++unsigned int au_rdhash_est(loff_t sz); ++int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp); ++void au_nhash_wh_free(struct au_nhash *whlist); ++int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, ++ int limit); ++int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen); ++int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, ++ unsigned int d_type, aufs_bindex_t bindex, ++ unsigned char shwh); ++void au_vdir_free(struct au_vdir *vdir); ++int au_vdir_init(struct file *file); ++int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir); ++ ++/* ioctl.c */ ++long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg); ++ ++#ifdef CONFIG_AUFS_RDU ++/* rdu.c */ ++long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg); ++#else ++static inline long au_rdu_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ return -EINVAL; ++} ++#endif ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DIR_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/export.c linux-2.6.31/fs/aufs/export.c +--- linux-2.6.31-vanilla/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/export.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,746 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * export via nfs ++ */ ++ ++#include <linux/exportfs.h> ++#include <linux/file.h> ++#include <linux/mnt_namespace.h> ++#include <linux/namei.h> ++#include <linux/nsproxy.h> ++#include <linux/random.h> ++#include "aufs.h" ++ ++union conv { ++#ifdef CONFIG_AUFS_INO_T_64 ++ __u32 a[2]; ++#else ++ __u32 a[1]; ++#endif ++ ino_t ino; ++}; ++ ++static ino_t decode_ino(__u32 *a) ++{ ++ union conv u; ++ ++ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a)); ++ u.a[0] = a[0]; ++#ifdef CONFIG_AUFS_INO_T_64 ++ u.a[1] = a[1]; ++#endif ++ return u.ino; ++} ++ ++static void encode_ino(__u32 *a, ino_t ino) ++{ ++ union conv u; ++ ++ u.ino = ino; ++ a[0] = u.a[0]; ++#ifdef CONFIG_AUFS_INO_T_64 ++ a[1] = u.a[1]; ++#endif ++} ++ ++/* NFS file handle */ ++enum { ++ Fh_br_id, ++ Fh_sigen, ++#ifdef CONFIG_AUFS_INO_T_64 ++ /* support 64bit inode number */ ++ Fh_ino1, ++ Fh_ino2, ++ Fh_dir_ino1, ++ Fh_dir_ino2, ++#else ++ Fh_ino1, ++ Fh_dir_ino1, ++#endif ++ Fh_igen, ++ Fh_h_type, ++ Fh_tail, ++ ++ Fh_ino = Fh_ino1, ++ Fh_dir_ino = Fh_dir_ino1 ++}; ++ ++static int au_test_anon(struct dentry *dentry) ++{ ++ return !!(dentry->d_flags & DCACHE_DISCONNECTED); ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* inode generation external table */ ++ ++int au_xigen_inc(struct inode *inode) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ __u32 igen; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ sb = inode->i_sb; ++ sbinfo = au_sbi(sb); ++ /* ++ * temporary workaround for escaping from SiMustAnyLock() in ++ * au_mntflags(), since this function is called from au_iinfo_fin(). ++ */ ++ if (unlikely(!au_opt_test(sbinfo->si_mntflags, XINO))) ++ goto out; ++ ++ pos = inode->i_ino; ++ pos *= sizeof(igen); ++ igen = inode->i_generation + 1; ++ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen, ++ sizeof(igen), &pos); ++ if (sz == sizeof(igen)) ++ goto out; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xigen error (%zd)\n", sz); ++ } ++ ++ out: ++ return err; ++} ++ ++int au_xigen_new(struct inode *inode) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ err = 0; ++ /* todo: dirty, at mount time */ ++ if (inode->i_ino == AUFS_ROOT_INO) ++ goto out; ++ sb = inode->i_sb; ++ SiMustAnyLock(sb); ++ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) ++ goto out; ++ ++ err = -EFBIG; ++ pos = inode->i_ino; ++ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) { ++ AuIOErr1("too large i%lld\n", pos); ++ goto out; ++ } ++ pos *= sizeof(inode->i_generation); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ file = sbinfo->si_xigen; ++ BUG_ON(!file); ++ ++ if (i_size_read(file->f_dentry->d_inode) ++ < pos + sizeof(inode->i_generation)) { ++ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); ++ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, ++ sizeof(inode->i_generation), &pos); ++ } else ++ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, ++ sizeof(inode->i_generation), &pos); ++ if (sz == sizeof(inode->i_generation)) ++ goto out; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xigen error (%zd)\n", sz); ++ } ++ ++ out: ++ return err; ++} ++ ++int au_xigen_set(struct super_block *sb, struct file *base) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ file = au_xino_create2(base, sbinfo->si_xigen); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ err = 0; ++ if (sbinfo->si_xigen) ++ fput(sbinfo->si_xigen); ++ sbinfo->si_xigen = file; ++ ++ out: ++ return err; ++} ++ ++void au_xigen_clr(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ if (sbinfo->si_xigen) { ++ fput(sbinfo->si_xigen); ++ sbinfo->si_xigen = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino, ++ ino_t dir_ino) ++{ ++ struct dentry *dentry, *d; ++ struct inode *inode; ++ unsigned int sigen; ++ ++ dentry = NULL; ++ inode = ilookup(sb, ino); ++ if (!inode) ++ goto out; ++ ++ dentry = ERR_PTR(-ESTALE); ++ sigen = au_sigen(sb); ++ if (unlikely(is_bad_inode(inode) ++ || IS_DEADDIR(inode) ++ || sigen != au_iigen(inode))) ++ goto out_iput; ++ ++ dentry = NULL; ++ if (!dir_ino || S_ISDIR(inode->i_mode)) ++ dentry = d_find_alias(inode); ++ else { ++ spin_lock(&dcache_lock); ++ list_for_each_entry(d, &inode->i_dentry, d_alias) ++ if (!au_test_anon(d) ++ && d->d_parent->d_inode->i_ino == dir_ino) { ++ dentry = dget_locked(d); ++ break; ++ } ++ spin_unlock(&dcache_lock); ++ } ++ if (unlikely(dentry && sigen != au_digen(dentry))) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ ++ out_iput: ++ iput(inode); ++ out: ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: dirty? */ ++/* if exportfs_decode_fh() passed vfsmount*, we could be happy */ ++static struct vfsmount *au_mnt_get(struct super_block *sb) ++{ ++ struct mnt_namespace *ns; ++ struct vfsmount *pos, *mnt; ++ ++ spin_lock(&vfsmount_lock); ++ /* no get/put ?? */ ++ AuDebugOn(!current->nsproxy); ++ ns = current->nsproxy->mnt_ns; ++ AuDebugOn(!ns); ++ mnt = NULL; ++ /* the order (reverse) will not be a problem */ ++ list_for_each_entry(pos, &ns->list, mnt_list) ++ if (pos->mnt_sb == sb) { ++ mnt = mntget(pos); ++ break; ++ } ++ spin_unlock(&vfsmount_lock); ++ AuDebugOn(!mnt); ++ ++ return mnt; ++} ++ ++struct au_nfsd_si_lock { ++ const unsigned int sigen; ++ const aufs_bindex_t br_id; ++ unsigned char force_lock; ++}; ++ ++static aufs_bindex_t si_nfsd_read_lock(struct super_block *sb, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ aufs_bindex_t bindex; ++ ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ /* branch id may be wrapped around */ ++ bindex = au_br_index(sb, nsi_lock->br_id); ++ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb)) ++ goto out; /* success */ ++ ++ if (!nsi_lock->force_lock) ++ si_read_unlock(sb); ++ bindex = -1; ++ ++ out: ++ return bindex; ++} ++ ++struct find_name_by_ino { ++ int called, found; ++ ino_t ino; ++ char *name; ++ int namelen; ++}; ++ ++static int ++find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset, ++ u64 ino, unsigned int d_type) ++{ ++ struct find_name_by_ino *a = arg; ++ ++ a->called++; ++ if (a->ino != ino) ++ return 0; ++ ++ memcpy(a->name, name, namelen); ++ a->namelen = namelen; ++ a->found = 1; ++ return 1; ++} ++ ++static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry, *parent; ++ struct file *file; ++ struct inode *dir; ++ struct find_name_by_ino arg; ++ int err; ++ ++ parent = path->dentry; ++ if (nsi_lock) ++ si_read_unlock(parent->d_sb); ++ path_get(path); ++ file = vfsub_dentry_open(path, au_dir_roflags, current_cred()); ++ dentry = (void *)file; ++ if (IS_ERR(file)) ++ goto out; ++ ++ dentry = ERR_PTR(-ENOMEM); ++ arg.name = __getname(); ++ if (unlikely(!arg.name)) ++ goto out_file; ++ arg.ino = ino; ++ arg.found = 0; ++ do { ++ arg.called = 0; ++ /* smp_mb(); */ ++ err = vfsub_readdir(file, find_name_by_ino, &arg); ++ } while (!err && !arg.found && arg.called); ++ dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_name; ++ dentry = ERR_PTR(-ENOENT); ++ if (!arg.found) ++ goto out_name; ++ ++ /* do not call au_lkup_one() */ ++ dir = parent->d_inode; ++ mutex_lock(&dir->i_mutex); ++ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen); ++ mutex_unlock(&dir->i_mutex); ++ AuTraceErrPtr(dentry); ++ if (IS_ERR(dentry)) ++ goto out_name; ++ AuDebugOn(au_test_anon(dentry)); ++ if (unlikely(!dentry->d_inode)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ENOENT); ++ } ++ ++ out_name: ++ __putname(arg.name); ++ out_file: ++ fput(file); ++ out: ++ if (unlikely(nsi_lock ++ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0)) ++ if (!IS_ERR(dentry)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino, ++ ino_t dir_ino, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry; ++ struct path path; ++ ++ if (dir_ino != AUFS_ROOT_INO) { ++ path.dentry = decode_by_ino(sb, dir_ino, 0); ++ dentry = path.dentry; ++ if (!path.dentry || IS_ERR(path.dentry)) ++ goto out; ++ AuDebugOn(au_test_anon(path.dentry)); ++ } else ++ path.dentry = dget(sb->s_root); ++ ++ path.mnt = au_mnt_get(sb); ++ dentry = au_lkup_by_ino(&path, ino, nsi_lock); ++ path_put(&path); ++ ++ out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int h_acceptable(void *expv, struct dentry *dentry) ++{ ++ return 1; ++} ++ ++static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath, ++ char *buf, int len, struct super_block *sb) ++{ ++ char *p; ++ int n; ++ struct path path; ++ ++ p = d_path(h_rootpath, buf, len); ++ if (IS_ERR(p)) ++ goto out; ++ n = strlen(p); ++ ++ path.mnt = h_rootpath->mnt; ++ path.dentry = h_parent; ++ p = d_path(&path, buf, len); ++ if (IS_ERR(p)) ++ goto out; ++ if (n != 1) ++ p += n; ++ ++ path.mnt = au_mnt_get(sb); ++ path.dentry = sb->s_root; ++ p = d_path(&path, buf, len - strlen(p)); ++ mntput(path.mnt); ++ if (IS_ERR(p)) ++ goto out; ++ if (n != 1) ++ p[strlen(p)] = '/'; ++ ++ out: ++ AuTraceErrPtr(p); ++ return p; ++} ++ ++static ++struct dentry *decode_by_path(struct super_block *sb, aufs_bindex_t bindex, ++ ino_t ino, __u32 *fh, int fh_len, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry, *h_parent, *root; ++ struct super_block *h_sb; ++ char *pathname, *p; ++ struct vfsmount *h_mnt; ++ struct au_branch *br; ++ int err; ++ struct path path; ++ ++ br = au_sbr(sb, bindex); ++ /* au_br_get(br); */ ++ h_mnt = br->br_mnt; ++ h_sb = h_mnt->mnt_sb; ++ /* todo: call lower fh_to_dentry()? fh_to_parent()? */ ++ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail), ++ fh_len - Fh_tail, fh[Fh_h_type], ++ h_acceptable, /*context*/NULL); ++ dentry = h_parent; ++ if (unlikely(!h_parent || IS_ERR(h_parent))) { ++ AuWarn1("%s decode_fh failed, %ld\n", ++ au_sbtype(h_sb), PTR_ERR(h_parent)); ++ goto out; ++ } ++ dentry = NULL; ++ if (unlikely(au_test_anon(h_parent))) { ++ AuWarn1("%s decode_fh returned a disconnected dentry\n", ++ au_sbtype(h_sb)); ++ goto out_h_parent; ++ } ++ ++ dentry = ERR_PTR(-ENOMEM); ++ pathname = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!pathname)) ++ goto out_h_parent; ++ ++ root = sb->s_root; ++ path.mnt = h_mnt; ++ di_read_lock_parent(root, !AuLock_IR); ++ path.dentry = au_h_dptr(root, bindex); ++ di_read_unlock(root, !AuLock_IR); ++ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb); ++ dentry = (void *)p; ++ if (IS_ERR(p)) ++ goto out_pathname; ++ ++ si_read_unlock(sb); ++ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); ++ dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_relock; ++ ++ dentry = ERR_PTR(-ENOENT); ++ AuDebugOn(au_test_anon(path.dentry)); ++ if (unlikely(!path.dentry->d_inode)) ++ goto out_path; ++ ++ if (ino != path.dentry->d_inode->i_ino) ++ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL); ++ else ++ dentry = dget(path.dentry); ++ ++ out_path: ++ path_put(&path); ++ out_relock: ++ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0)) ++ if (!IS_ERR(dentry)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ out_pathname: ++ free_page((unsigned long)pathname); ++ out_h_parent: ++ dput(h_parent); ++ out: ++ /* au_br_put(br); */ ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry * ++aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, ++ int fh_type) ++{ ++ struct dentry *dentry; ++ __u32 *fh = fid->raw; ++ ino_t ino, dir_ino; ++ aufs_bindex_t bindex; ++ struct au_nfsd_si_lock nsi_lock = { ++ .sigen = fh[Fh_sigen], ++ .br_id = fh[Fh_br_id], ++ .force_lock = 0 ++ }; ++ ++ AuDebugOn(fh_len < Fh_tail); ++ ++ dentry = ERR_PTR(-ESTALE); ++ /* branch id may be wrapped around */ ++ bindex = si_nfsd_read_lock(sb, &nsi_lock); ++ if (unlikely(bindex < 0)) ++ goto out; ++ nsi_lock.force_lock = 1; ++ ++ /* is this inode still cached? */ ++ ino = decode_ino(fh + Fh_ino); ++ AuDebugOn(ino == AUFS_ROOT_INO); ++ dir_ino = decode_ino(fh + Fh_dir_ino); ++ dentry = decode_by_ino(sb, ino, dir_ino); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (dentry) ++ goto accept; ++ ++ /* is the parent dir cached? */ ++ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (dentry) ++ goto accept; ++ ++ /* lookup path */ ++ dentry = decode_by_path(sb, bindex, ino, fh, fh_len, &nsi_lock); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (unlikely(!dentry)) ++ /* todo?: make it ESTALE */ ++ goto out_unlock; ++ ++ accept: ++ if (dentry->d_inode->i_generation == fh[Fh_igen]) ++ goto out_unlock; /* success */ ++ ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ out_unlock: ++ si_read_unlock(sb); ++ out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++#if 0 /* reserved for future use */ ++/* support subtreecheck option */ ++static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid, ++ int fh_len, int fh_type) ++{ ++ struct dentry *parent; ++ __u32 *fh = fid->raw; ++ ino_t dir_ino; ++ ++ dir_ino = decode_ino(fh + Fh_dir_ino); ++ parent = decode_by_ino(sb, dir_ino, 0); ++ if (IS_ERR(parent)) ++ goto out; ++ if (!parent) ++ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]), ++ dir_ino, fh, fh_len); ++ ++ out: ++ AuTraceErrPtr(parent); ++ return parent; ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, ++ int connectable) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct super_block *sb, *h_sb; ++ struct inode *inode; ++ struct dentry *parent, *h_parent; ++ struct au_branch *br; ++ ++ AuDebugOn(au_test_anon(dentry)); ++ ++ parent = NULL; ++ err = -ENOSPC; ++ if (unlikely(*max_len <= Fh_tail)) { ++ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len); ++ goto out; ++ } ++ ++ err = FILEID_ROOT; ++ if (IS_ROOT(dentry)) { ++ AuDebugOn(dentry->d_inode->i_ino != AUFS_ROOT_INO); ++ goto out; ++ } ++ ++ err = -EIO; ++ h_parent = NULL; ++ sb = dentry->d_sb; ++ aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR); ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, !AuLock_IR); ++ inode = dentry->d_inode; ++ AuDebugOn(!inode); ++#ifdef CONFIG_AUFS_DEBUG ++ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) ++ AuWarn1("NFS-exporting requires xino\n"); ++#endif ++ ++ bend = au_dbtaildir(parent); ++ for (bindex = au_dbstart(parent); bindex <= bend; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (h_parent) { ++ dget(h_parent); ++ break; ++ } ++ } ++ if (unlikely(!h_parent)) ++ goto out_unlock; ++ ++ err = -EPERM; ++ br = au_sbr(sb, bindex); ++ h_sb = br->br_mnt->mnt_sb; ++ if (unlikely(!h_sb->s_export_op)) { ++ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb)); ++ goto out_dput; ++ } ++ ++ fh[Fh_br_id] = br->br_id; ++ fh[Fh_sigen] = au_sigen(sb); ++ encode_ino(fh + Fh_ino, inode->i_ino); ++ encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino); ++ fh[Fh_igen] = inode->i_generation; ++ ++ *max_len -= Fh_tail; ++ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail), ++ max_len, ++ /*connectable or subtreecheck*/0); ++ err = fh[Fh_h_type]; ++ *max_len += Fh_tail; ++ /* todo: macros? */ ++ if (err != 255) ++ err = 99; ++ else ++ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb)); ++ ++ out_dput: ++ dput(h_parent); ++ out_unlock: ++ di_read_unlock(parent, !AuLock_IR); ++ dput(parent); ++ aufs_read_unlock(dentry, AuLock_IR); ++ out: ++ if (unlikely(err < 0)) ++ err = 255; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct export_operations aufs_export_op = { ++ .fh_to_dentry = aufs_fh_to_dentry, ++ /* .fh_to_parent = aufs_fh_to_parent, */ ++ .encode_fh = aufs_encode_fh ++}; ++ ++void au_export_init(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ __u32 u; ++ ++ sb->s_export_op = &aufs_export_op; ++ sbinfo = au_sbi(sb); ++ sbinfo->si_xigen = NULL; ++ get_random_bytes(&u, sizeof(u)); ++ BUILD_BUG_ON(sizeof(u) != sizeof(int)); ++ atomic_set(&sbinfo->si_xigen_next, u); ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/file.c linux-2.6.31/fs/aufs/file.c +--- linux-2.6.31-vanilla/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/file.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,568 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * handling file/dir, and address_space operation ++ */ ++ ++#include <linux/file.h> ++#include <linux/fsnotify.h> ++#include <linux/namei.h> ++#include <linux/pagemap.h> ++#include "aufs.h" ++ ++/* drop flags for writing */ ++unsigned int au_file_roflags(unsigned int flags) ++{ ++ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC); ++ flags |= O_RDONLY | O_NOATIME; ++ return flags; ++} ++ ++/* common functions to regular file and dir */ ++struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, ++ struct file *file) ++{ ++ struct file *h_file; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err, exec_flag; ++ struct path h_path; ++ ++ /* a race condition can happen between open and unlink/rmdir */ ++ h_file = ERR_PTR(-ENOENT); ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (au_test_nfsd(current) && !h_dentry) ++ goto out; ++ h_inode = h_dentry->d_inode; ++ if (au_test_nfsd(current) && !h_inode) ++ goto out; ++ if (unlikely((!d_unhashed(dentry) && d_unhashed(h_dentry)) ++ || !h_inode)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, bindex); ++ h_file = ERR_PTR(-EACCES); ++ exec_flag = flags & vfsub_fmode_to_uint(FMODE_EXEC); ++ if (exec_flag && (br->br_mnt->mnt_flags & MNT_NOEXEC)) ++ goto out; ++ ++ /* drop flags for writing */ ++ if (au_test_ro(sb, bindex, dentry->d_inode)) ++ flags = au_file_roflags(flags); ++ flags &= ~O_CREAT; ++ atomic_inc(&br->br_count); ++ h_path.dentry = h_dentry; ++ h_path.mnt = br->br_mnt; ++ path_get(&h_path); ++ h_file = vfsub_dentry_open(&h_path, flags, current_cred()); ++ if (IS_ERR(h_file)) ++ goto out_br; ++ ++ if (exec_flag) { ++ err = deny_write_access(h_file); ++ if (unlikely(err)) { ++ fput(h_file); ++ h_file = ERR_PTR(err); ++ goto out_br; ++ } ++ } ++ fsnotify_open(h_dentry); ++ goto out; /* success */ ++ ++ out_br: ++ atomic_dec(&br->br_count); ++ out: ++ return h_file; ++} ++ ++int au_do_open(struct file *file, int (*open)(struct file *file, int flags)) ++{ ++ int err; ++ unsigned int flags; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_finfo_init(file); ++ if (unlikely(err)) ++ goto out; ++ ++ di_read_lock_child(dentry, AuLock_IR); ++ spin_lock(&file->f_lock); ++ flags = file->f_flags; ++ spin_unlock(&file->f_lock); ++ err = open(file, flags); ++ di_read_unlock(dentry, AuLock_IR); ++ ++ fi_write_unlock(file); ++ if (unlikely(err)) ++ au_finfo_fin(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++int au_reopen_nondir(struct file *file) ++{ ++ int err; ++ unsigned int flags; ++ aufs_bindex_t bstart, bindex, bend; ++ struct dentry *dentry; ++ struct file *h_file, *h_file_tmp; ++ ++ dentry = file->f_dentry; ++ bstart = au_dbstart(dentry); ++ h_file_tmp = NULL; ++ if (au_fbstart(file) == bstart) { ++ h_file = au_h_fptr(file, bstart); ++ if (file->f_mode == h_file->f_mode) ++ return 0; /* success */ ++ h_file_tmp = h_file; ++ get_file(h_file_tmp); ++ au_set_h_fptr(file, bstart, NULL); ++ } ++ AuDebugOn(au_fbstart(file) < bstart ++ || au_fi(file)->fi_hfile[0 + bstart].hf_file); ++ ++ spin_lock(&file->f_lock); ++ flags = file->f_flags & ~O_TRUNC; ++ spin_unlock(&file->f_lock); ++ h_file = au_h_open(dentry, bstart, flags, file); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; /* todo: close all? */ ++ ++ err = 0; ++ au_set_fbstart(file, bstart); ++ au_set_h_fptr(file, bstart, h_file); ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ ++ /* close lower files */ ++ bend = au_fbend(file); ++ for (bindex = bstart + 1; bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbend(file, bstart); ++ ++ out: ++ if (h_file_tmp) ++ fput(h_file_tmp); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_reopen_wh(struct file *file, aufs_bindex_t btgt, ++ struct dentry *hi_wh) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct dentry *h_dentry; ++ ++ dinfo = au_di(file->f_dentry); ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ bstart = dinfo->di_bstart; ++ dinfo->di_bstart = btgt; ++ h_dentry = dinfo->di_hdentry[0 + btgt].hd_dentry; ++ dinfo->di_hdentry[0 + btgt].hd_dentry = hi_wh; ++ err = au_reopen_nondir(file); ++ dinfo->di_hdentry[0 + btgt].hd_dentry = h_dentry; ++ dinfo->di_bstart = bstart; ++ ++ return err; ++} ++ ++static int au_ready_to_write_wh(struct file *file, loff_t len, ++ aufs_bindex_t bcpup) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *dentry, *hi_wh; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ hi_wh = au_hi_wh(inode, bcpup); ++ if (!hi_wh) ++ err = au_sio_cpup_wh(dentry, bcpup, len, file); ++ else ++ /* already copied-up after unlink */ ++ err = au_reopen_wh(file, bcpup, hi_wh); ++ ++ sb = dentry->d_sb; ++ if (!err && inode->i_nlink > 1 && au_opt_test(au_mntflags(sb), PLINK)) ++ au_plink_append(inode, bcpup, au_h_dptr(dentry, bcpup)); ++ ++ return err; ++} ++ ++/* ++ * prepare the @file for writing. ++ */ ++int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin) ++{ ++ int err; ++ aufs_bindex_t bstart, bcpup; ++ struct dentry *dentry, *parent, *h_dentry; ++ struct inode *h_inode, *inode; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ bstart = au_fbstart(file); ++ inode = dentry->d_inode; ++ err = au_test_ro(sb, bstart, inode); ++ if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE)) { ++ err = au_pin(pin, dentry, bstart, AuOpt_UDBA_NONE, /*flags*/0); ++ goto out; ++ } ++ ++ /* need to cpup */ ++ parent = dget_parent(dentry); ++ di_write_lock_parent(parent); ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ bcpup = err; ++ if (unlikely(err < 0)) ++ goto out_dgrade; ++ err = 0; ++ ++ if (!au_h_dptr(parent, bcpup)) { ++ err = au_cpup_dirs(dentry, bcpup); ++ if (unlikely(err)) ++ goto out_dgrade; ++ } ++ ++ err = au_pin(pin, dentry, bcpup, AuOpt_UDBA_NONE, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_dgrade; ++ ++ h_dentry = au_h_fptr(file, bstart)->f_dentry; ++ h_inode = h_dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ if (d_unhashed(dentry) /* || d_unhashed(h_dentry) */ ++ /* || !h_inode->i_nlink */) { ++ err = au_ready_to_write_wh(file, len, bcpup); ++ di_downgrade_lock(parent, AuLock_IR); ++ } else { ++ di_downgrade_lock(parent, AuLock_IR); ++ if (!au_h_dptr(dentry, bcpup)) ++ err = au_sio_cpup_simple(dentry, bcpup, len, ++ AuCpup_DTIME); ++ if (!err) ++ err = au_reopen_nondir(file); ++ } ++ mutex_unlock(&h_inode->i_mutex); ++ ++ if (!err) { ++ au_pin_set_parent_lflag(pin, /*lflag*/0); ++ goto out_dput; /* success */ ++ } ++ au_unpin(pin); ++ goto out_unlock; ++ ++ out_dgrade: ++ di_downgrade_lock(parent, AuLock_IR); ++ out_unlock: ++ di_read_unlock(parent, AuLock_IR); ++ out_dput: ++ dput(parent); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_file_refresh_by_inode(struct file *file, int *need_reopen) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct au_finfo *finfo; ++ struct dentry *dentry, *parent, *hi_wh; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ finfo = au_fi(file); ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ bstart = au_ibstart(inode); ++ if (bstart == finfo->fi_bstart) ++ goto out; ++ ++ parent = dget_parent(dentry); ++ if (au_test_ro(sb, bstart, inode)) { ++ di_read_lock_parent(parent, !AuLock_IR); ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ bstart = err; ++ di_read_unlock(parent, !AuLock_IR); ++ if (unlikely(err < 0)) ++ goto out_parent; ++ err = 0; ++ } ++ ++ di_read_lock_parent(parent, AuLock_IR); ++ hi_wh = au_hi_wh(inode, bstart); ++ if (au_opt_test(au_mntflags(sb), PLINK) ++ && au_plink_test(inode) ++ && !d_unhashed(dentry)) { ++ err = au_test_and_cpup_dirs(dentry, bstart); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ /* always superio. */ ++ err = au_pin(&pin, dentry, bstart, AuOpt_UDBA_NONE, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (!err) ++ err = au_sio_cpup_simple(dentry, bstart, -1, ++ AuCpup_DTIME); ++ au_unpin(&pin); ++ } else if (hi_wh) { ++ /* already copied-up after unlink */ ++ err = au_reopen_wh(file, bstart, hi_wh); ++ *need_reopen = 0; ++ } ++ ++ out_unlock: ++ di_read_unlock(parent, AuLock_IR); ++ out_parent: ++ dput(parent); ++ out: ++ return err; ++} ++ ++static void au_do_refresh_file(struct file *file) ++{ ++ aufs_bindex_t bindex, bend, new_bindex, brid; ++ struct au_hfile *p, tmp, *q; ++ struct au_finfo *finfo; ++ struct super_block *sb; ++ ++ FiMustWriteLock(file); ++ ++ sb = file->f_dentry->d_sb; ++ finfo = au_fi(file); ++ p = finfo->fi_hfile + finfo->fi_bstart; ++ brid = p->hf_br->br_id; ++ bend = finfo->fi_bend; ++ for (bindex = finfo->fi_bstart; bindex <= bend; bindex++, p++) { ++ if (!p->hf_file) ++ continue; ++ ++ new_bindex = au_br_index(sb, p->hf_br->br_id); ++ if (new_bindex == bindex) ++ continue; ++ if (new_bindex < 0) { ++ au_set_h_fptr(file, bindex, NULL); ++ continue; ++ } ++ ++ /* swap two lower inode, and loop again */ ++ q = finfo->fi_hfile + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hf_file) { ++ bindex--; ++ p--; ++ } ++ } ++ ++ p = finfo->fi_hfile; ++ if (!au_test_mmapped(file) && !d_unhashed(file->f_dentry)) { ++ bend = au_sbend(sb); ++ for (finfo->fi_bstart = 0; finfo->fi_bstart <= bend; ++ finfo->fi_bstart++, p++) ++ if (p->hf_file) { ++ if (p->hf_file->f_dentry ++ && p->hf_file->f_dentry->d_inode) ++ break; ++ else ++ au_hfput(p, file); ++ } ++ } else { ++ bend = au_br_index(sb, brid); ++ for (finfo->fi_bstart = 0; finfo->fi_bstart < bend; ++ finfo->fi_bstart++, p++) ++ if (p->hf_file) ++ au_hfput(p, file); ++ bend = au_sbend(sb); ++ } ++ ++ p = finfo->fi_hfile + bend; ++ for (finfo->fi_bend = bend; finfo->fi_bend >= finfo->fi_bstart; ++ finfo->fi_bend--, p--) ++ if (p->hf_file) { ++ if (p->hf_file->f_dentry ++ && p->hf_file->f_dentry->d_inode) ++ break; ++ else ++ au_hfput(p, file); ++ } ++ AuDebugOn(finfo->fi_bend < finfo->fi_bstart); ++} ++ ++/* ++ * after branch manipulating, refresh the file. ++ */ ++static int refresh_file(struct file *file, int (*reopen)(struct file *file)) ++{ ++ int err, need_reopen; ++ struct dentry *dentry; ++ aufs_bindex_t bend, bindex; ++ ++ dentry = file->f_dentry; ++ err = au_fi_realloc(au_fi(file), au_sbend(dentry->d_sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ au_do_refresh_file(file); ++ ++ err = 0; ++ need_reopen = 1; ++ if (!au_test_mmapped(file)) ++ err = au_file_refresh_by_inode(file, &need_reopen); ++ if (!err && need_reopen && !d_unhashed(dentry)) ++ err = reopen(file); ++ if (!err) { ++ au_update_figen(file); ++ return 0; /* success */ ++ } ++ ++ /* error, close all lower files */ ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ ++ out: ++ return err; ++} ++ ++/* common function to regular file and dir */ ++int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), ++ int wlock) ++{ ++ int err; ++ unsigned int sigen, figen; ++ aufs_bindex_t bstart; ++ unsigned char pseudo_link; ++ struct dentry *dentry; ++ ++ err = 0; ++ dentry = file->f_dentry; ++ sigen = au_sigen(dentry->d_sb); ++ fi_write_lock(file); ++ figen = au_figen(file); ++ di_write_lock_child(dentry); ++ bstart = au_dbstart(dentry); ++ pseudo_link = (bstart != au_ibstart(dentry->d_inode)); ++ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) { ++ if (!wlock) { ++ di_downgrade_lock(dentry, AuLock_IR); ++ fi_downgrade_lock(file); ++ } ++ goto out; /* success */ ++ } ++ ++ AuDbg("sigen %d, figen %d\n", sigen, figen); ++ if (sigen != au_digen(dentry) ++ || sigen != au_iigen(dentry->d_inode)) { ++ err = au_reval_dpath(dentry, sigen); ++ if (unlikely(err < 0)) ++ goto out; ++ AuDebugOn(au_digen(dentry) != sigen ++ || au_iigen(dentry->d_inode) != sigen); ++ } ++ ++ err = refresh_file(file, reopen); ++ if (!err) { ++ if (!wlock) { ++ di_downgrade_lock(dentry, AuLock_IR); ++ fi_downgrade_lock(file); ++ } ++ } else { ++ di_write_unlock(dentry); ++ fi_write_unlock(file); ++ } ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* cf. aufs_nopage() */ ++/* for madvise(2) */ ++static int aufs_readpage(struct file *file __maybe_unused, struct page *page) ++{ ++ unlock_page(page); ++ return 0; ++} ++ ++/* they will never be called. */ ++#ifdef CONFIG_AUFS_DEBUG ++static int aufs_write_begin(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned flags, ++ struct page **pagep, void **fsdata) ++{ AuUnsupport(); return 0; } ++static int aufs_write_end(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned copied, ++ struct page *page, void *fsdata) ++{ AuUnsupport(); return 0; } ++static int aufs_writepage(struct page *page, struct writeback_control *wbc) ++{ AuUnsupport(); return 0; } ++static void aufs_sync_page(struct page *page) ++{ AuUnsupport(); } ++ ++static int aufs_set_page_dirty(struct page *page) ++{ AuUnsupport(); return 0; } ++static void aufs_invalidatepage(struct page *page, unsigned long offset) ++{ AuUnsupport(); } ++static int aufs_releasepage(struct page *page, gfp_t gfp) ++{ AuUnsupport(); return 0; } ++static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb, ++ const struct iovec *iov, loff_t offset, ++ unsigned long nr_segs) ++{ AuUnsupport(); return 0; } ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++struct address_space_operations aufs_aop = { ++ .readpage = aufs_readpage, ++#ifdef CONFIG_AUFS_DEBUG ++ .writepage = aufs_writepage, ++ .sync_page = aufs_sync_page, ++ .set_page_dirty = aufs_set_page_dirty, ++ .write_begin = aufs_write_begin, ++ .write_end = aufs_write_end, ++ .invalidatepage = aufs_invalidatepage, ++ .releasepage = aufs_releasepage, ++ .direct_IO = aufs_direct_IO, ++#endif /* CONFIG_AUFS_DEBUG */ ++}; +diff -Nur linux-2.6.31-vanilla/fs/aufs/file.h linux-2.6.31/fs/aufs/file.h +--- linux-2.6.31-vanilla/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/file.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,174 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * file operations ++ */ ++ ++#ifndef __AUFS_FILE_H__ ++#define __AUFS_FILE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/fs.h> ++#include <linux/poll.h> ++#include <linux/aufs_type.h> ++#include "rwsem.h" ++ ++struct au_branch; ++struct au_hfile { ++ struct file *hf_file; ++ struct au_branch *hf_br; ++}; ++ ++struct au_vdir; ++struct au_finfo { ++ atomic_t fi_generation; ++ ++ struct au_rwsem fi_rwsem; ++ struct au_hfile *fi_hfile; ++ aufs_bindex_t fi_bstart, fi_bend; ++ ++ union { ++ /* non-dir only */ ++ struct { ++ struct vm_operations_struct *fi_h_vm_ops; ++ struct vm_operations_struct *fi_vm_ops; ++ }; ++ ++ /* dir only */ ++ struct { ++ struct au_vdir *fi_vdir_cache; ++ int fi_maintain_plink; ++ }; ++ }; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* file.c */ ++extern struct address_space_operations aufs_aop; ++unsigned int au_file_roflags(unsigned int flags); ++struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, ++ struct file *file); ++int au_do_open(struct file *file, int (*open)(struct file *file, int flags)); ++int au_reopen_nondir(struct file *file); ++struct au_pin; ++int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin); ++int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), ++ int wlock); ++ ++/* poll.c */ ++#ifdef CONFIG_AUFS_POLL ++unsigned int aufs_poll(struct file *file, poll_table *wait); ++#endif ++ ++/* f_op.c */ ++extern const struct file_operations aufs_file_fop; ++int aufs_flush(struct file *file, fl_owner_t id); ++ ++/* finfo.c */ ++void au_hfput(struct au_hfile *hf, struct file *file); ++void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, ++ struct file *h_file); ++ ++void au_update_figen(struct file *file); ++ ++void au_finfo_fin(struct file *file); ++int au_finfo_init(struct file *file); ++int au_fi_realloc(struct au_finfo *finfo, int nbr); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_finfo *au_fi(struct file *file) ++{ ++ return file->private_data; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * fi_read_lock, fi_write_lock, ++ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock ++ */ ++AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem); ++ ++#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem) ++#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem) ++#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: hard/soft set? */ ++static inline aufs_bindex_t au_fbstart(struct file *file) ++{ ++ FiMustAnyLock(file); ++ return au_fi(file)->fi_bstart; ++} ++ ++static inline aufs_bindex_t au_fbend(struct file *file) ++{ ++ FiMustAnyLock(file); ++ return au_fi(file)->fi_bend; ++} ++ ++static inline struct au_vdir *au_fvdir_cache(struct file *file) ++{ ++ FiMustAnyLock(file); ++ return au_fi(file)->fi_vdir_cache; ++} ++ ++static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex) ++{ ++ FiMustWriteLock(file); ++ au_fi(file)->fi_bstart = bindex; ++} ++ ++static inline void au_set_fbend(struct file *file, aufs_bindex_t bindex) ++{ ++ FiMustWriteLock(file); ++ au_fi(file)->fi_bend = bindex; ++} ++ ++static inline void au_set_fvdir_cache(struct file *file, ++ struct au_vdir *vdir_cache) ++{ ++ FiMustWriteLock(file); ++ au_fi(file)->fi_vdir_cache = vdir_cache; ++} ++ ++static inline struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex) ++{ ++ FiMustAnyLock(file); ++ return au_fi(file)->fi_hfile[0 + bindex].hf_file; ++} ++ ++/* todo: memory barrier? */ ++static inline unsigned int au_figen(struct file *f) ++{ ++ return atomic_read(&au_fi(f)->fi_generation); ++} ++ ++static inline int au_test_mmapped(struct file *f) ++{ ++ /* FiMustAnyLock(f); */ ++ return !!(au_fi(f)->fi_h_vm_ops); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_FILE_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/finfo.c linux-2.6.31/fs/aufs/finfo.c +--- linux-2.6.31-vanilla/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/finfo.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,128 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * file private data ++ */ ++ ++#include <linux/file.h> ++#include "aufs.h" ++ ++void au_hfput(struct au_hfile *hf, struct file *file) ++{ ++ if (file->f_flags & vfsub_fmode_to_uint(FMODE_EXEC)) ++ allow_write_access(hf->hf_file); ++ fput(hf->hf_file); ++ hf->hf_file = NULL; ++ atomic_dec_return(&hf->hf_br->br_count); ++ hf->hf_br = NULL; ++} ++ ++void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val) ++{ ++ struct au_finfo *finfo = au_fi(file); ++ struct au_hfile *hf; ++ ++ hf = finfo->fi_hfile + bindex; ++ if (hf->hf_file) ++ au_hfput(hf, file); ++ if (val) { ++ hf->hf_file = val; ++ hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex); ++ } ++} ++ ++void au_update_figen(struct file *file) ++{ ++ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_finfo_fin(struct file *file) ++{ ++ struct au_finfo *finfo; ++ aufs_bindex_t bindex, bend; ++ ++ fi_write_lock(file); ++ bend = au_fbend(file); ++ bindex = au_fbstart(file); ++ if (bindex >= 0) ++ /* ++ * calls fput() instead of filp_close(), ++ * since no dnotify or lock for the lower file. ++ */ ++ for (; bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ ++ finfo = au_fi(file); ++ au_dbg_verify_hf(finfo); ++ kfree(finfo->fi_hfile); ++ fi_write_unlock(file); ++ AuRwDestroy(&finfo->fi_rwsem); ++ au_cache_free_finfo(finfo); ++} ++ ++int au_finfo_init(struct file *file) ++{ ++ struct au_finfo *finfo; ++ struct dentry *dentry; ++ ++ dentry = file->f_dentry; ++ finfo = au_cache_alloc_finfo(); ++ if (unlikely(!finfo)) ++ goto out; ++ ++ finfo->fi_hfile = kcalloc(au_sbend(dentry->d_sb) + 1, ++ sizeof(*finfo->fi_hfile), GFP_NOFS); ++ if (unlikely(!finfo->fi_hfile)) ++ goto out_finfo; ++ ++ au_rw_init_wlock(&finfo->fi_rwsem); ++ finfo->fi_bstart = -1; ++ finfo->fi_bend = -1; ++ atomic_set(&finfo->fi_generation, au_digen(dentry)); ++ /* smp_mb(); */ /* atomic_set */ ++ ++ file->private_data = finfo; ++ return 0; /* success */ ++ ++ out_finfo: ++ au_cache_free_finfo(finfo); ++ out: ++ return -ENOMEM; ++} ++ ++int au_fi_realloc(struct au_finfo *finfo, int nbr) ++{ ++ int err, sz; ++ struct au_hfile *hfp; ++ ++ err = -ENOMEM; ++ sz = sizeof(*hfp) * (finfo->fi_bend + 1); ++ if (!sz) ++ sz = sizeof(*hfp); ++ hfp = au_kzrealloc(finfo->fi_hfile, sz, sizeof(*hfp) * nbr, GFP_NOFS); ++ if (hfp) { ++ finfo->fi_hfile = hfp; ++ err = 0; ++ } ++ ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/f_op.c linux-2.6.31/fs/aufs/f_op.c +--- linux-2.6.31-vanilla/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/f_op.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,823 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * file and vm operations ++ */ ++ ++#include <linux/file.h> ++#include <linux/fs_stack.h> ++#include <linux/ima.h> ++#include <linux/mman.h> ++#include <linux/mm.h> ++#include <linux/security.h> ++#include "aufs.h" ++ ++/* common function to regular file and dir */ ++int aufs_flush(struct file *file, fl_owner_t id) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct dentry *dentry; ++ struct file *h_file; ++ ++ dentry = file->f_dentry; ++ si_noflush_read_lock(dentry->d_sb); ++ fi_read_lock(file); ++ di_read_lock_child(dentry, AuLock_IW); ++ ++ err = 0; ++ bend = au_fbend(file); ++ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { ++ h_file = au_h_fptr(file, bindex); ++ if (!h_file || !h_file->f_op || !h_file->f_op->flush) ++ continue; ++ ++ err = h_file->f_op->flush(h_file, id); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ } ++ au_cpup_attr_timesizes(dentry->d_inode); ++ ++ di_read_unlock(dentry, AuLock_IW); ++ fi_read_unlock(file); ++ si_read_unlock(dentry->d_sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int do_open_nondir(struct file *file, int flags) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct au_finfo *finfo; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ dentry = file->f_dentry; ++ finfo = au_fi(file); ++ finfo->fi_h_vm_ops = NULL; ++ finfo->fi_vm_ops = NULL; ++ bindex = au_dbstart(dentry); ++ /* O_TRUNC is processed already */ ++ BUG_ON(au_test_ro(dentry->d_sb, bindex, dentry->d_inode) ++ && (flags & O_TRUNC)); ++ ++ h_file = au_h_open(dentry, bindex, flags, file); ++ if (IS_ERR(h_file)) ++ err = PTR_ERR(h_file); ++ else { ++ au_set_fbstart(file, bindex); ++ au_set_fbend(file, bindex); ++ au_set_h_fptr(file, bindex, h_file); ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ } ++ return err; ++} ++ ++static int aufs_open_nondir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ return au_do_open(file, do_open_nondir); ++} ++ ++static int aufs_release_nondir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ struct super_block *sb = file->f_dentry->d_sb; ++ ++ si_noflush_read_lock(sb); ++ kfree(au_fi(file)->fi_vm_ops); ++ au_finfo_fin(file); ++ si_read_unlock(sb); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ struct dentry *dentry; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ err = vfsub_read_u(h_file, buf, count, ppos); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t aufs_write(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *h_file; ++ char __user *buf = (char __user *)ubuf; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ bstart = au_fbstart(file); ++ h_file = au_h_fptr(file, bstart); ++ au_unpin(&pin); ++ err = vfsub_write_u(h_file, buf, count, ppos); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = h_file->f_dentry->d_inode->i_mode; ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov, ++ unsigned long nv, loff_t pos) ++{ ++ ssize_t err; ++ struct file *file, *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ file = kio->ki_filp; ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -ENOSYS; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->aio_read) { ++ err = security_file_permission(h_file, MAY_READ); ++ if (unlikely(err)) ++ goto out_unlock; ++ if (!is_sync_kiocb(kio)) { ++ get_file(h_file); ++ fput(file); ++ } ++ kio->ki_filp = h_file; ++ err = h_file->f_op->aio_read(kio, iov, nv, pos); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ fsstack_copy_attr_atime(dentry->d_inode, ++ h_file->f_dentry->d_inode); ++ } else ++ /* currently there is no such fs */ ++ WARN_ON_ONCE(h_file->f_op && h_file->f_op->read); ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov, ++ unsigned long nv, loff_t pos) ++{ ++ ssize_t err; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *file, *h_file; ++ ++ file = kio->ki_filp; ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ err = -ENOSYS; ++ bstart = au_fbstart(file); ++ h_file = au_h_fptr(file, bstart); ++ au_unpin(&pin); ++ if (h_file->f_op && h_file->f_op->aio_write) { ++ err = security_file_permission(h_file, MAY_WRITE); ++ if (unlikely(err)) ++ goto out_unlock; ++ if (!is_sync_kiocb(kio)) { ++ get_file(h_file); ++ fput(file); ++ } ++ kio->ki_filp = h_file; ++ err = h_file->f_op->aio_write(kio, iov, nv, pos); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = h_file->f_dentry->d_inode->i_mode; ++ } else ++ /* currently there is no such fs */ ++ WARN_ON_ONCE(h_file->f_op && h_file->f_op->write); ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) ++{ ++ ssize_t err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -EINVAL; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (au_test_loopback_kthread()) { ++ file->f_mapping = h_file->f_mapping; ++ smp_mb(); /* unnecessary? */ ++ } ++ err = vfsub_splice_to(h_file, ppos, pipe, len, flags); ++ /* todo: necessasry? */ ++ /* file->f_ra = h_file->f_ra; */ ++ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t ++aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, ++ size_t len, unsigned int flags) ++{ ++ ssize_t err; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *h_file; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ au_unpin(&pin); ++ err = vfsub_splice_from(pipe, h_file, ppos, len, flags); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = h_file->f_dentry->d_inode->i_mode; ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct file *au_safe_file(struct vm_area_struct *vma) ++{ ++ struct file *file; ++ ++ file = vma->vm_file; ++ if (file->private_data && au_test_aufs(file->f_dentry->d_sb)) ++ return file; ++ return NULL; ++} ++ ++static void au_reset_file(struct vm_area_struct *vma, struct file *file) ++{ ++ vma->vm_file = file; ++ /* smp_mb(); */ /* flush vm_file */ ++} ++ ++static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++ int err; ++ static DECLARE_WAIT_QUEUE_HEAD(wq); ++ struct file *file, *h_file; ++ struct au_finfo *finfo; ++ ++ /* todo: non-robr mode, user vm_file as it is? */ ++ wait_event(wq, (file = au_safe_file(vma))); ++ ++ /* do not revalidate, no si lock */ ++ finfo = au_fi(file); ++ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; ++ AuDebugOn(!h_file || !finfo->fi_h_vm_ops); ++ ++ fi_write_lock(file); ++ vma->vm_file = h_file; ++ err = finfo->fi_h_vm_ops->fault(vma, vmf); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ au_reset_file(vma, file); ++ fi_write_unlock(file); ++#if 0 /* def CONFIG_SMP */ ++ /* wake_up_nr(&wq, online_cpu - 1); */ ++ wake_up_all(&wq); ++#else ++ wake_up(&wq); ++#endif ++ ++ return err; ++} ++ ++static int aufs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++ int err; ++ static DECLARE_WAIT_QUEUE_HEAD(wq); ++ struct file *file, *h_file; ++ struct au_finfo *finfo; ++ ++ wait_event(wq, (file = au_safe_file(vma))); ++ ++ finfo = au_fi(file); ++ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; ++ AuDebugOn(!h_file || !finfo->fi_h_vm_ops); ++ ++ fi_write_lock(file); ++ vma->vm_file = h_file; ++ err = finfo->fi_h_vm_ops->page_mkwrite(vma, vmf); ++ au_reset_file(vma, file); ++ fi_write_unlock(file); ++ wake_up(&wq); ++ ++ return err; ++} ++ ++static void aufs_vm_close(struct vm_area_struct *vma) ++{ ++ static DECLARE_WAIT_QUEUE_HEAD(wq); ++ struct file *file, *h_file; ++ struct au_finfo *finfo; ++ ++ wait_event(wq, (file = au_safe_file(vma))); ++ ++ finfo = au_fi(file); ++ h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; ++ AuDebugOn(!h_file || !finfo->fi_h_vm_ops); ++ ++ fi_write_lock(file); ++ vma->vm_file = h_file; ++ finfo->fi_h_vm_ops->close(vma); ++ au_reset_file(vma, file); ++ fi_write_unlock(file); ++ wake_up(&wq); ++} ++ ++static struct vm_operations_struct aufs_vm_ops = { ++ /* .close and .page_mkwrite are not set by default */ ++ .fault = aufs_fault, ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static unsigned long au_prot_conv(unsigned long flags) ++{ ++ unsigned long prot; ++ ++ prot = 0; ++ if (flags & VM_READ) ++ prot |= PROT_READ; ++ if (flags & VM_WRITE) ++ prot |= PROT_WRITE; ++ if (flags & VM_EXEC) ++ prot |= PROT_EXEC; ++ return prot; ++} ++ ++static struct vm_operations_struct *au_vm_ops(struct file *h_file, ++ struct vm_area_struct *vma) ++{ ++ struct vm_operations_struct *vm_ops; ++ int err; ++ ++ vm_ops = ERR_PTR(-ENODEV); ++ if (!h_file->f_op || !h_file->f_op->mmap) ++ goto out; ++ ++ err = ima_file_mmap(h_file, au_prot_conv(vma->vm_flags)); ++ vm_ops = ERR_PTR(err); ++ if (err) ++ goto out; ++ ++ err = h_file->f_op->mmap(h_file, vma); ++ vm_ops = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ vm_ops = vma->vm_ops; ++ err = do_munmap(current->mm, vma->vm_start, ++ vma->vm_end - vma->vm_start); ++ if (unlikely(err)) { ++ AuIOErr("failed internal unmapping %.*s, %d\n", ++ AuDLNPair(h_file->f_dentry), err); ++ vm_ops = ERR_PTR(-EIO); ++ } ++ ++ out: ++ return vm_ops; ++} ++ ++static int au_custom_vm_ops(struct au_finfo *finfo, struct vm_area_struct *vma) ++{ ++ int err; ++ struct vm_operations_struct *h_ops; ++ ++ AuRwMustAnyLock(&finfo->fi_rwsem); ++ ++ err = 0; ++ h_ops = finfo->fi_h_vm_ops; ++ AuDebugOn(!h_ops); ++ if ((!h_ops->page_mkwrite && !h_ops->close) ++ || finfo->fi_vm_ops) ++ goto out; ++ ++ err = -ENOMEM; ++ finfo->fi_vm_ops = kmemdup(&aufs_vm_ops, sizeof(aufs_vm_ops), GFP_NOFS); ++ if (unlikely(!finfo->fi_vm_ops)) ++ goto out; ++ ++ err = 0; ++ if (h_ops->page_mkwrite) ++ finfo->fi_vm_ops->page_mkwrite = aufs_page_mkwrite; ++ if (h_ops->close) ++ finfo->fi_vm_ops->close = aufs_vm_close; ++ ++ vma->vm_ops = finfo->fi_vm_ops; ++ ++ out: ++ return err; ++} ++ ++static int aufs_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ int err; ++ unsigned char wlock, mmapped; ++ struct dentry *dentry; ++ struct super_block *sb; ++ struct file *h_file; ++ struct vm_operations_struct *vm_ops; ++ ++ dentry = file->f_dentry; ++ wlock = !!(file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED); ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ mmapped = !!au_test_mmapped(file); ++ if (wlock) { ++ struct au_pin pin; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ } else ++ di_downgrade_lock(dentry, AuLock_IR); ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (!mmapped && au_test_fs_bad_mapping(h_file->f_dentry->d_sb)) { ++ /* ++ * by this assignment, f_mapping will differs from aufs inode ++ * i_mapping. ++ * if someone else mixes the use of f_dentry->d_inode and ++ * f_mapping->host, then a problem may arise. ++ */ ++ file->f_mapping = h_file->f_mapping; ++ } ++ ++ vm_ops = NULL; ++ if (!mmapped) { ++ vm_ops = au_vm_ops(h_file, vma); ++ err = PTR_ERR(vm_ops); ++ if (IS_ERR(vm_ops)) ++ goto out_unlock; ++ } ++ ++ /* ++ * unnecessary to handle MAP_DENYWRITE and deny_write_access()? ++ * currently MAP_DENYWRITE from userspace is ignored, but elf loader ++ * sets it. when FMODE_EXEC is set (by open_exec() or sys_uselib()), ++ * both of the aufs file and the lower file is deny_write_access()-ed. ++ * finally I hope we can skip handlling MAP_DENYWRITE here. ++ */ ++ err = generic_file_mmap(file, vma); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ vma->vm_ops = &aufs_vm_ops; ++ /* test again */ ++ if (!au_test_mmapped(file)) ++ au_fi(file)->fi_h_vm_ops = vm_ops; ++ ++ err = au_custom_vm_ops(au_fi(file), vma); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ vfsub_file_accessed(h_file); ++ fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_fsync_nondir(struct file *file, struct dentry *dentry, ++ int datasync) ++{ ++ int err; ++ struct au_pin pin; ++ struct inode *inode; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ inode = dentry->d_inode; ++ IMustLock(file->f_mapping->host); ++ if (inode != file->f_mapping->host) { ++ mutex_unlock(&file->f_mapping->host->i_mutex); ++ mutex_lock(&inode->i_mutex); ++ } ++ IMustLock(inode); ++ ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = 0; /* -EBADF; */ /* posix? */ ++ if (unlikely(!(file->f_mode & FMODE_WRITE))) ++ goto out; ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ ++ err = -EINVAL; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->fsync) { ++ struct dentry *h_d; ++ struct mutex *h_mtx; ++ ++ /* ++ * no filemap_fdatawrite() since aufs file has no its own ++ * mapping, but dir. ++ */ ++ h_d = h_file->f_dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ err = h_file->f_op->fsync(h_file, h_d, datasync); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ au_cpup_attr_timesizes(inode); ++ mutex_unlock(h_mtx); ++ } ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ if (inode != file->f_mapping->host) { ++ mutex_unlock(&inode->i_mutex); ++ mutex_lock(&file->f_mapping->host->i_mutex); ++ } ++ return err; ++} ++ ++/* no one supports this operation, currently */ ++#if 0 ++static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync) ++{ ++ int err; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct file *file, *h_file; ++ struct super_block *sb; ++ ++ file = kio->ki_filp; ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++ mutex_lock(&inode->i_mutex); ++ ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ err = 0; /* -EBADF; */ /* posix? */ ++ if (unlikely(!(file->f_mode & FMODE_WRITE))) ++ goto out; ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ ++ err = -ENOSYS; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->aio_fsync) { ++ struct dentry *h_d; ++ struct mutex *h_mtx; ++ ++ h_d = h_file->f_dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ if (!is_sync_kiocb(kio)) { ++ get_file(h_file); ++ fput(file); ++ } ++ kio->ki_filp = h_file; ++ err = h_file->f_op->aio_fsync(kio, datasync); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ au_cpup_attr_timesizes(inode); ++ mutex_unlock(h_mtx); ++ } ++ ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++#endif ++ ++static int aufs_fasync(int fd, struct file *file, int flag) ++{ ++ int err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->fasync) ++ err = h_file->f_op->fasync(fd, h_file, flag); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* no one supports this operation, currently */ ++#if 0 ++static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset, ++ size_t len, loff_t *pos , int more) ++{ ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++const struct file_operations aufs_file_fop = { ++ /* ++ * while generic_file_llseek/_unlocked() don't use BKL, ++ * don't use it since it operates file->f_mapping->host. ++ * in aufs, it may be a real file and may confuse users by UDBA. ++ */ ++ /* .llseek = generic_file_llseek, */ ++ ++ .read = aufs_read, ++ .write = aufs_write, ++ .aio_read = aufs_aio_read, ++ .aio_write = aufs_aio_write, ++#ifdef CONFIG_AUFS_POLL ++ .poll = aufs_poll, ++#endif ++ .mmap = aufs_mmap, ++ .open = aufs_open_nondir, ++ .flush = aufs_flush, ++ .release = aufs_release_nondir, ++ .fsync = aufs_fsync_nondir, ++ /* .aio_fsync = aufs_aio_fsync_nondir, */ ++ .fasync = aufs_fasync, ++ /* .sendpage = aufs_sendpage, */ ++ .splice_write = aufs_splice_write, ++ .splice_read = aufs_splice_read, ++#if 0 ++ .aio_splice_write = aufs_aio_splice_write, ++ .aio_splice_read = aufs_aio_splice_read ++#endif ++}; +diff -Nur linux-2.6.31-vanilla/fs/aufs/fstype.h linux-2.6.31/fs/aufs/fstype.h +--- linux-2.6.31-vanilla/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/fstype.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,485 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * judging filesystem type ++ */ ++ ++#ifndef __AUFS_FSTYPE_H__ ++#define __AUFS_FSTYPE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/cramfs_fs.h> ++#include <linux/fs.h> ++#include <linux/magic.h> ++#include <linux/romfs_fs.h> ++#include <linux/aufs_type.h> ++ ++static inline int au_test_aufs(struct super_block *sb) ++{ ++ return sb->s_magic == AUFS_SUPER_MAGIC; ++} ++ ++static inline const char *au_sbtype(struct super_block *sb) ++{ ++ return sb->s_type->name; ++} ++ ++static inline int au_test_iso9660(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE) ++ return sb->s_magic == ROMFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_romfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE) ++ return sb->s_magic == ISOFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_cramfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) ++ return sb->s_magic == CRAMFS_MAGIC; ++#endif ++ return 0; ++} ++ ++static inline int au_test_nfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE) ++ return sb->s_magic == NFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_fuse(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE) ++ return sb->s_magic == FUSE_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_xfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE) ++ return sb->s_magic == XFS_SB_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_tmpfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_TMPFS ++ return sb->s_magic == TMPFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE) ++ return !strcmp(au_sbtype(sb), "ecryptfs"); ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_smbfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE) ++ return sb->s_magic == SMB_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ocfs2(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE) ++ return sb->s_magic == OCFS2_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE) ++ return sb->s_magic == DLMFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_coda(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE) ++ return sb->s_magic == CODA_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_v9fs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE) ++ return sb->s_magic == V9FS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ext4(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE) ++ return sb->s_magic == EXT4_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_sysv(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE) ++ return !strcmp(au_sbtype(sb), "sysv"); ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ramfs(struct super_block *sb) ++{ ++ return sb->s_magic == RAMFS_MAGIC; ++} ++ ++static inline int au_test_ubifs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE) ++ return sb->s_magic == UBIFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_procfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_PROC_FS ++ return sb->s_magic == PROC_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_sysfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_SYSFS ++ return sb->s_magic == SYSFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_configfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE) ++ return sb->s_magic == CONFIGFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_minix(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE) ++ return sb->s_magic == MINIX3_SUPER_MAGIC ++ || sb->s_magic == MINIX2_SUPER_MAGIC ++ || sb->s_magic == MINIX2_SUPER_MAGIC2 ++ || sb->s_magic == MINIX_SUPER_MAGIC ++ || sb->s_magic == MINIX_SUPER_MAGIC2; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_cifs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE) ++ return sb->s_magic == CIFS_MAGIC_NUMBER; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_fat(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE) ++ return sb->s_magic == MSDOS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_msdos(struct super_block *sb) ++{ ++ return au_test_fat(sb); ++} ++ ++static inline int au_test_vfat(struct super_block *sb) ++{ ++ return au_test_fat(sb); ++} ++ ++static inline int au_test_securityfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_SECURITYFS ++ return sb->s_magic == SECURITYFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_squashfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE) ++ return sb->s_magic == SQUASHFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_btrfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE) ++ return sb->s_magic == BTRFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_xenfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE) ++ return sb->s_magic == XENFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_debugfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_DEBUG_FS ++ return sb->s_magic == DEBUGFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_nilfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE) ++ return sb->s_magic == NILFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * they can't be an aufs branch. ++ */ ++static inline int au_test_fs_unsuppoted(struct super_block *sb) ++{ ++ return ++#ifndef CONFIG_AUFS_BR_RAMFS ++ au_test_ramfs(sb) || ++#endif ++ au_test_procfs(sb) ++ || au_test_sysfs(sb) ++ || au_test_configfs(sb) ++ || au_test_debugfs(sb) ++ || au_test_securityfs(sb) ++ || au_test_xenfs(sb) ++ || au_test_ecryptfs(sb) ++ /* || !strcmp(au_sbtype(sb), "unionfs") */ ++ || au_test_aufs(sb); /* will be supported in next version */ ++} ++ ++/* ++ * If the filesystem supports NFS-export, then it has to support NULL as ++ * a nameidata parameter for ->create(), ->lookup() and ->d_revalidate(). ++ * We can apply this principle when we handle a lower filesystem. ++ */ ++static inline int au_test_fs_null_nd(struct super_block *sb) ++{ ++ return !!sb->s_export_op; ++} ++ ++static inline int au_test_fs_remote(struct super_block *sb) ++{ ++ return !au_test_tmpfs(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ && !au_test_ramfs(sb) ++#endif ++ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * Note: these functions (below) are created after reading ->getattr() in all ++ * filesystems under linux/fs. it means we have to do so in every update... ++ */ ++ ++/* ++ * some filesystems require getattr to refresh the inode attributes before ++ * referencing. ++ * in most cases, we can rely on the inode attribute in NFS (or every remote fs) ++ * and leave the work for d_revalidate() ++ */ ++static inline int au_test_fs_refresh_iattr(struct super_block *sb) ++{ ++ return au_test_nfs(sb) ++ || au_test_fuse(sb) ++ /* || au_test_smbfs(sb) */ /* untested */ ++ /* || au_test_ocfs2(sb) */ /* untested */ ++ /* || au_test_btrfs(sb) */ /* untested */ ++ /* || au_test_coda(sb) */ /* untested */ ++ /* || au_test_v9fs(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which don't maintain i_size or i_blocks. ++ */ ++static inline int au_test_fs_bad_iattr_size(struct super_block *sb) ++{ ++ return au_test_xfs(sb) ++ /* || au_test_ext4(sb) */ /* untested */ ++ /* || au_test_ocfs2(sb) */ /* untested */ ++ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */ ++ /* || au_test_sysv(sb) */ /* untested */ ++ /* || au_test_ubifs(sb) */ /* untested */ ++ /* || au_test_minix(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which don't store the correct value in some of their inode ++ * attributes. ++ */ ++static inline int au_test_fs_bad_iattr(struct super_block *sb) ++{ ++ return au_test_fs_bad_iattr_size(sb) ++ /* || au_test_cifs(sb) */ /* untested */ ++ || au_test_fat(sb) ++ || au_test_msdos(sb) ++ || au_test_vfat(sb); ++} ++ ++/* they don't check i_nlink in link(2) */ ++static inline int au_test_fs_no_limit_nlink(struct super_block *sb) ++{ ++ return au_test_tmpfs(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ || au_test_ramfs(sb) ++#endif ++ || au_test_ubifs(sb); ++} ++ ++/* ++ * filesystems which sets S_NOATIME and S_NOCMTIME. ++ */ ++static inline int au_test_fs_notime(struct super_block *sb) ++{ ++ return au_test_nfs(sb) ++ || au_test_fuse(sb) ++ || au_test_ubifs(sb) ++ /* || au_test_cifs(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which requires replacing i_mapping. ++ */ ++static inline int au_test_fs_bad_mapping(struct super_block *sb) ++{ ++ return au_test_fuse(sb) ++ || au_test_ubifs(sb); ++} ++ ++/* temporary support for i#1 in cramfs */ ++static inline int au_test_fs_unique_ino(struct inode *inode) ++{ ++ if (au_test_cramfs(inode->i_sb)) ++ return inode->i_ino != 1; ++ return 1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * the filesystem where the xino files placed must support i/o after unlink and ++ * maintain i_size and i_blocks. ++ */ ++static inline int au_test_fs_bad_xino(struct super_block *sb) ++{ ++ return au_test_fs_remote(sb) ++ || au_test_fs_bad_iattr_size(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ || !(au_test_ramfs(sb) || au_test_fs_null_nd(sb)) ++#else ++ || !au_test_fs_null_nd(sb) /* to keep xino code simple */ ++#endif ++ /* don't want unnecessary work for xino */ ++ || au_test_aufs(sb) ++ || au_test_ecryptfs(sb) ++ || au_test_nilfs(sb); ++} ++ ++static inline int au_test_fs_trunc_xino(struct super_block *sb) ++{ ++ return au_test_tmpfs(sb) ++ || au_test_ramfs(sb); ++} ++ ++/* ++ * test if the @sb is real-readonly. ++ */ ++static inline int au_test_fs_rr(struct super_block *sb) ++{ ++ return au_test_squashfs(sb) ++ || au_test_iso9660(sb) ++ || au_test_cramfs(sb) ++ || au_test_romfs(sb); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_FSTYPE_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/hinotify.c linux-2.6.31/fs/aufs/hinotify.c +--- linux-2.6.31-vanilla/fs/aufs/hinotify.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/hinotify.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,755 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * inotify for the lower directories ++ */ ++ ++#include "aufs.h" ++ ++static const __u32 AuHinMask = (IN_MOVE | IN_DELETE | IN_CREATE); ++static struct inotify_handle *au_hin_handle; ++ ++AuCacheFuncs(hinotify, HINOTIFY); ++ ++int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, ++ struct inode *h_inode) ++{ ++ int err; ++ struct au_hinotify *hin; ++ s32 wd; ++ ++ err = -ENOMEM; ++ hin = au_cache_alloc_hinotify(); ++ if (hin) { ++ AuDebugOn(hinode->hi_notify); ++ hinode->hi_notify = hin; ++ hin->hin_aufs_inode = inode; ++ ++ inotify_init_watch(&hin->hin_watch); ++ wd = inotify_add_watch(au_hin_handle, &hin->hin_watch, h_inode, ++ AuHinMask); ++ if (wd >= 0) ++ return 0; /* success */ ++ ++ err = wd; ++ put_inotify_watch(&hin->hin_watch); ++ au_cache_free_hinotify(hin); ++ hinode->hi_notify = NULL; ++ } ++ ++ return err; ++} ++ ++void au_hin_free(struct au_hinode *hinode) ++{ ++ int err; ++ struct au_hinotify *hin; ++ ++ hin = hinode->hi_notify; ++ if (hin) { ++ err = 0; ++ if (atomic_read(&hin->hin_watch.count)) ++ err = inotify_rm_watch(au_hin_handle, &hin->hin_watch); ++ if (unlikely(err)) ++ /* it means the watch is already removed */ ++ AuWarn("failed inotify_rm_watch() %d\n", err); ++ au_cache_free_hinotify(hin); ++ hinode->hi_notify = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_hin_ctl(struct au_hinode *hinode, int do_set) ++{ ++ struct inode *h_inode; ++ struct inotify_watch *watch; ++ ++ if (!hinode->hi_notify) ++ return; ++ ++ h_inode = hinode->hi_inode; ++ IMustLock(h_inode); ++ ++ /* todo: try inotify_find_update_watch()? */ ++ watch = &hinode->hi_notify->hin_watch; ++ mutex_lock(&h_inode->inotify_mutex); ++ /* mutex_lock(&watch->ih->mutex); */ ++ if (do_set) { ++ AuDebugOn(watch->mask & AuHinMask); ++ watch->mask |= AuHinMask; ++ } else { ++ AuDebugOn(!(watch->mask & AuHinMask)); ++ watch->mask &= ~AuHinMask; ++ } ++ /* mutex_unlock(&watch->ih->mutex); */ ++ mutex_unlock(&h_inode->inotify_mutex); ++} ++ ++void au_reset_hinotify(struct inode *inode, unsigned int flags) ++{ ++ aufs_bindex_t bindex, bend; ++ struct inode *hi; ++ struct dentry *iwhdentry; ++ ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { ++ hi = au_h_iptr(inode, bindex); ++ if (!hi) ++ continue; ++ ++ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */ ++ iwhdentry = au_hi_wh(inode, bindex); ++ if (iwhdentry) ++ dget(iwhdentry); ++ au_igrab(hi); ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ au_set_h_iptr(inode, bindex, au_igrab(hi), ++ flags & ~AuHi_XINO); ++ iput(hi); ++ dput(iwhdentry); ++ /* mutex_unlock(&hi->i_mutex); */ ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int hin_xino(struct inode *inode, struct inode *h_inode) ++{ ++ int err; ++ aufs_bindex_t bindex, bend, bfound, bstart; ++ struct inode *h_i; ++ ++ err = 0; ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ AuWarn("branch root dir was changed\n"); ++ goto out; ++ } ++ ++ bfound = -1; ++ bend = au_ibend(inode); ++ bstart = au_ibstart(inode); ++#if 0 /* reserved for future use */ ++ if (bindex == bend) { ++ /* keep this ino in rename case */ ++ goto out; ++ } ++#endif ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ if (au_h_iptr(inode, bindex) == h_inode) { ++ bfound = bindex; ++ break; ++ } ++ } ++ if (bfound < 0) ++ goto out; ++ ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ h_i = au_h_iptr(inode, bindex); ++ if (!h_i) ++ continue; ++ ++ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0); ++ /* ignore this error */ ++ /* bad action? */ ++ } ++ ++ /* children inode number will be broken */ ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int hin_gen_tree(struct dentry *dentry) ++{ ++ int err, i, j, ndentry; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, dentry, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ if (IS_ROOT(d)) ++ continue; ++ ++ d_drop(d); ++ au_digen_dec(d); ++ if (d->d_inode) ++ /* todo: reset children xino? ++ cached children only? */ ++ au_iigen_dec(d->d_inode); ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ ++ /* discard children */ ++ dentry_unhash(dentry); ++ dput(dentry); ++ out: ++ return err; ++} ++ ++/* ++ * return 0 if processed. ++ */ ++static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode, ++ const unsigned int isdir) ++{ ++ int err; ++ struct dentry *d; ++ struct qstr *dname; ++ ++ err = 1; ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ AuWarn("branch root dir was changed\n"); ++ err = 0; ++ goto out; ++ } ++ ++ if (!isdir) { ++ AuDebugOn(!name); ++ au_iigen_dec(inode); ++ spin_lock(&dcache_lock); ++ list_for_each_entry(d, &inode->i_dentry, d_alias) { ++ dname = &d->d_name; ++ if (dname->len != nlen ++ && memcmp(dname->name, name, nlen)) ++ continue; ++ err = 0; ++ spin_lock(&d->d_lock); ++ __d_drop(d); ++ au_digen_dec(d); ++ spin_unlock(&d->d_lock); ++ break; ++ } ++ spin_unlock(&dcache_lock); ++ } else { ++ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS); ++ d = d_find_alias(inode); ++ if (!d) { ++ au_iigen_dec(inode); ++ goto out; ++ } ++ ++ dname = &d->d_name; ++ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) ++ err = hin_gen_tree(d); ++ dput(d); ++ } ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir) ++{ ++ int err; ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ if (IS_ROOT(dentry) ++ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */ ++ ) { ++ AuWarn("branch root dir was changed\n"); ++ return 0; ++ } ++ ++ err = 0; ++ if (!isdir) { ++ d_drop(dentry); ++ au_digen_dec(dentry); ++ if (inode) ++ au_iigen_dec(inode); ++ } else { ++ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS); ++ if (inode) ++ err = hin_gen_tree(dentry); ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* hinotify job flags */ ++#define AuHinJob_XINO0 1 ++#define AuHinJob_GEN (1 << 1) ++#define AuHinJob_DIRENT (1 << 2) ++#define AuHinJob_ISDIR (1 << 3) ++#define AuHinJob_TRYXINO0 (1 << 4) ++#define AuHinJob_MNTPNT (1 << 5) ++#define au_ftest_hinjob(flags, name) ((flags) & AuHinJob_##name) ++#define au_fset_hinjob(flags, name) { (flags) |= AuHinJob_##name; } ++#define au_fclr_hinjob(flags, name) { (flags) &= ~AuHinJob_##name; } ++ ++struct hin_job_args { ++ unsigned int flags; ++ struct inode *inode, *h_inode, *dir, *h_dir; ++ struct dentry *dentry; ++ char *h_name; ++ int h_nlen; ++}; ++ ++static int hin_job(struct hin_job_args *a) ++{ ++ const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR); ++ ++ /* reset xino */ ++ if (au_ftest_hinjob(a->flags, XINO0) && a->inode) ++ hin_xino(a->inode, a->h_inode); /* ignore this error */ ++ ++ if (au_ftest_hinjob(a->flags, TRYXINO0) ++ && a->inode ++ && a->h_inode) { ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ if (!a->h_inode->i_nlink) ++ hin_xino(a->inode, a->h_inode); /* ignore this error */ ++ mutex_unlock(&a->h_inode->i_mutex); ++ } ++ ++ /* make the generation obsolete */ ++ if (au_ftest_hinjob(a->flags, GEN)) { ++ int err = -1; ++ if (a->inode) ++ err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode, ++ isdir); ++ if (err && a->dentry) ++ hin_gen_by_name(a->dentry, isdir); ++ /* ignore this error */ ++ } ++ ++ /* make dir entries obsolete */ ++ if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) { ++ struct au_vdir *vdir; ++ ++ vdir = au_ivdir(a->inode); ++ if (vdir) ++ vdir->vd_jiffy = 0; ++ /* IMustLock(a->inode); */ ++ /* a->inode->i_version++; */ ++ } ++ ++ /* can do nothing but warn */ ++ if (au_ftest_hinjob(a->flags, MNTPNT) ++ && a->dentry ++ && d_mountpoint(a->dentry)) ++ AuWarn("mount-point %.*s is removed or renamed\n", ++ AuDLNPair(a->dentry)); ++ ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static char *in_name(u32 mask) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++#define test_ret(flag) if (mask & flag) \ ++ return #flag; ++ test_ret(IN_ACCESS); ++ test_ret(IN_MODIFY); ++ test_ret(IN_ATTRIB); ++ test_ret(IN_CLOSE_WRITE); ++ test_ret(IN_CLOSE_NOWRITE); ++ test_ret(IN_OPEN); ++ test_ret(IN_MOVED_FROM); ++ test_ret(IN_MOVED_TO); ++ test_ret(IN_CREATE); ++ test_ret(IN_DELETE); ++ test_ret(IN_DELETE_SELF); ++ test_ret(IN_MOVE_SELF); ++ test_ret(IN_UNMOUNT); ++ test_ret(IN_Q_OVERFLOW); ++ test_ret(IN_IGNORED); ++ return ""; ++#undef test_ret ++#else ++ return "??"; ++#endif ++} ++ ++static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen, ++ struct inode *dir) ++{ ++ struct dentry *dentry, *d, *parent; ++ struct qstr *dname; ++ ++ parent = d_find_alias(dir); ++ if (!parent) ++ return NULL; ++ ++ dentry = NULL; ++ spin_lock(&dcache_lock); ++ list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) { ++ /* AuDbg("%.*s\n", AuDLNPair(d)); */ ++ dname = &d->d_name; ++ if (dname->len != nlen || memcmp(dname->name, name, nlen)) ++ continue; ++ if (!atomic_read(&d->d_count) || !d->d_fsdata) { ++ spin_lock(&d->d_lock); ++ __d_drop(d); ++ spin_unlock(&d->d_lock); ++ continue; ++ } ++ ++ dentry = dget(d); ++ break; ++ } ++ spin_unlock(&dcache_lock); ++ dput(parent); ++ ++ if (dentry) ++ di_write_lock_child(dentry); ++ ++ return dentry; ++} ++ ++static struct inode *lookup_wlock_by_ino(struct super_block *sb, ++ aufs_bindex_t bindex, ino_t h_ino) ++{ ++ struct inode *inode; ++ ino_t ino; ++ int err; ++ ++ inode = NULL; ++ err = au_xino_read(sb, bindex, h_ino, &ino); ++ if (!err && ino) ++ inode = ilookup(sb, ino); ++ if (!inode) ++ goto out; ++ ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ AuWarn("wrong root branch\n"); ++ iput(inode); ++ inode = NULL; ++ goto out; ++ } ++ ++ ii_write_lock_child(inode); ++ ++ out: ++ return inode; ++} ++ ++enum { CHILD, PARENT }; ++struct postproc_args { ++ struct inode *h_dir, *dir, *h_child_inode; ++ u32 mask; ++ unsigned int flags[2]; ++ unsigned int h_child_nlen; ++ char h_child_name[]; ++}; ++ ++static void postproc(void *_args) ++{ ++ struct postproc_args *a = _args; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend, bfound; ++ unsigned char xino, try_iput; ++ int err; ++ struct inode *inode; ++ ino_t h_ino; ++ struct hin_job_args args; ++ struct dentry *dentry; ++ struct au_sbinfo *sbinfo; ++ ++ AuDebugOn(!_args); ++ AuDebugOn(!a->h_dir); ++ AuDebugOn(!a->dir); ++ AuDebugOn(!a->mask); ++ AuDbg("mask 0x%x %s, i%lu, hi%lu, hci%lu\n", ++ a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino, ++ a->h_child_inode ? a->h_child_inode->i_ino : 0); ++ ++ inode = NULL; ++ dentry = NULL; ++ /* ++ * do not lock a->dir->i_mutex here ++ * because of d_revalidate() may cause a deadlock. ++ */ ++ sb = a->dir->i_sb; ++ AuDebugOn(!sb); ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!sbinfo); ++ /* big aufs lock */ ++ si_noflush_write_lock(sb); ++ ++ ii_read_lock_parent(a->dir); ++ bfound = -1; ++ bend = au_ibend(a->dir); ++ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++) ++ if (au_h_iptr(a->dir, bindex) == a->h_dir) { ++ bfound = bindex; ++ break; ++ } ++ ii_read_unlock(a->dir); ++ if (unlikely(bfound < 0)) ++ goto out; ++ ++ xino = !!au_opt_test(au_mntflags(sb), XINO); ++ h_ino = 0; ++ if (a->h_child_inode) ++ h_ino = a->h_child_inode->i_ino; ++ ++ if (a->h_child_nlen ++ && (au_ftest_hinjob(a->flags[CHILD], GEN) ++ || au_ftest_hinjob(a->flags[CHILD], MNTPNT))) ++ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, ++ a->dir); ++ try_iput = 0; ++ if (dentry) ++ inode = dentry->d_inode; ++ if (xino && !inode && h_ino ++ && (au_ftest_hinjob(a->flags[CHILD], XINO0) ++ || au_ftest_hinjob(a->flags[CHILD], TRYXINO0) ++ || au_ftest_hinjob(a->flags[CHILD], GEN))) { ++ inode = lookup_wlock_by_ino(sb, bfound, h_ino); ++ try_iput = 1; ++ } ++ ++ args.flags = a->flags[CHILD]; ++ args.dentry = dentry; ++ args.inode = inode; ++ args.h_inode = a->h_child_inode; ++ args.dir = a->dir; ++ args.h_dir = a->h_dir; ++ args.h_name = a->h_child_name; ++ args.h_nlen = a->h_child_nlen; ++ err = hin_job(&args); ++ if (dentry) { ++ if (dentry->d_fsdata) ++ di_write_unlock(dentry); ++ dput(dentry); ++ } ++ if (inode && try_iput) { ++ ii_write_unlock(inode); ++ iput(inode); ++ } ++ ++ ii_write_lock_parent(a->dir); ++ args.flags = a->flags[PARENT]; ++ args.dentry = NULL; ++ args.inode = a->dir; ++ args.h_inode = a->h_dir; ++ args.dir = NULL; ++ args.h_dir = NULL; ++ args.h_name = NULL; ++ args.h_nlen = 0; ++ err = hin_job(&args); ++ ii_write_unlock(a->dir); ++ ++ out: ++ au_nwt_done(&sbinfo->si_nowait); ++ si_write_unlock(sb); ++ ++ iput(a->h_child_inode); ++ iput(a->h_dir); ++ iput(a->dir); ++ kfree(a); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void aufs_inotify(struct inotify_watch *watch, u32 wd __maybe_unused, ++ u32 mask, u32 cookie __maybe_unused, ++ const char *h_child_name, struct inode *h_child_inode) ++{ ++ struct au_hinotify *hinotify; ++ struct postproc_args *args; ++ int len, wkq_err; ++ unsigned char isdir, isroot, wh; ++ char *p; ++ struct inode *dir; ++ unsigned int flags[2]; ++ ++ /* if IN_UNMOUNT happens, there must be another bug */ ++ AuDebugOn(mask & IN_UNMOUNT); ++ if (mask & (IN_IGNORED | IN_UNMOUNT)) { ++ put_inotify_watch(watch); ++ return; ++ } ++#ifdef AuDbgHinotify ++ au_debug(1); ++ if (1 || !h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) { ++ AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s," ++ " hi%lu\n", ++ watch->inode->i_ino, wd, mask, in_name(mask), cookie, ++ h_child_name ? h_child_name : "", ++ h_child_inode ? h_child_inode->i_ino : 0); ++ WARN_ON(1); ++ } ++ au_debug(0); ++#endif ++ ++ hinotify = container_of(watch, struct au_hinotify, hin_watch); ++ AuDebugOn(!hinotify || !hinotify->hin_aufs_inode); ++ dir = igrab(hinotify->hin_aufs_inode); ++ if (!dir) ++ return; ++ ++ isroot = (dir->i_ino == AUFS_ROOT_INO); ++ len = 0; ++ wh = 0; ++ if (h_child_name) { ++ len = strlen(h_child_name); ++ if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ h_child_name += AUFS_WH_PFX_LEN; ++ len -= AUFS_WH_PFX_LEN; ++ wh = 1; ++ } ++ } ++ ++ isdir = 0; ++ if (h_child_inode) ++ isdir = !!S_ISDIR(h_child_inode->i_mode); ++ flags[PARENT] = AuHinJob_ISDIR; ++ flags[CHILD] = 0; ++ if (isdir) ++ flags[CHILD] = AuHinJob_ISDIR; ++ switch (mask & IN_ALL_EVENTS) { ++ case IN_MOVED_FROM: ++ case IN_MOVED_TO: ++ AuDebugOn(!h_child_name || !h_child_inode); ++ au_fset_hinjob(flags[CHILD], GEN); ++ au_fset_hinjob(flags[CHILD], XINO0); ++ au_fset_hinjob(flags[CHILD], MNTPNT); ++ au_fset_hinjob(flags[PARENT], DIRENT); ++ break; ++ ++ case IN_CREATE: ++ AuDebugOn(!h_child_name || !h_child_inode); ++ au_fset_hinjob(flags[PARENT], DIRENT); ++ au_fset_hinjob(flags[CHILD], GEN); ++ break; ++ ++ case IN_DELETE: ++ /* ++ * aufs never be able to get this child inode. ++ * revalidation should be in d_revalidate() ++ * by checking i_nlink, i_generation or d_unhashed(). ++ */ ++ AuDebugOn(!h_child_name); ++ au_fset_hinjob(flags[PARENT], DIRENT); ++ au_fset_hinjob(flags[CHILD], GEN); ++ au_fset_hinjob(flags[CHILD], TRYXINO0); ++ au_fset_hinjob(flags[CHILD], MNTPNT); ++ break; ++ ++ default: ++ AuDebugOn(1); ++ } ++ ++ if (wh) ++ h_child_inode = NULL; ++ ++ /* iput() and kfree() will be called in postproc() */ ++ /* ++ * inotify_mutex is already acquired and kmalloc/prune_icache may lock ++ * iprune_mutex. strange. ++ */ ++ lockdep_off(); ++ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS); ++ lockdep_on(); ++ if (unlikely(!args)) { ++ AuErr1("no memory\n"); ++ iput(dir); ++ return; ++ } ++ args->flags[PARENT] = flags[PARENT]; ++ args->flags[CHILD] = flags[CHILD]; ++ args->mask = mask; ++ args->dir = dir; ++ args->h_dir = igrab(watch->inode); ++ if (h_child_inode) ++ h_child_inode = igrab(h_child_inode); /* can be NULL */ ++ args->h_child_inode = h_child_inode; ++ args->h_child_nlen = len; ++ if (len) { ++ p = (void *)args; ++ p += sizeof(*args); ++ memcpy(p, h_child_name, len + 1); ++ } ++ ++ lockdep_off(); ++ wkq_err = au_wkq_nowait(postproc, args, dir->i_sb); ++ lockdep_on(); ++ if (unlikely(wkq_err)) ++ AuErr("wkq %d\n", wkq_err); ++} ++ ++static void aufs_inotify_destroy(struct inotify_watch *watch __maybe_unused) ++{ ++ return; ++} ++ ++static struct inotify_operations aufs_inotify_ops = { ++ .handle_event = aufs_inotify, ++ .destroy_watch = aufs_inotify_destroy ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_hin_destroy_cache(void) ++{ ++ kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]); ++ au_cachep[AuCache_HINOTIFY] = NULL; ++} ++ ++int __init au_hinotify_init(void) ++{ ++ int err; ++ ++ err = -ENOMEM; ++ au_cachep[AuCache_HINOTIFY] = AuCache(au_hinotify); ++ if (au_cachep[AuCache_HINOTIFY]) { ++ err = 0; ++ au_hin_handle = inotify_init(&aufs_inotify_ops); ++ if (IS_ERR(au_hin_handle)) { ++ err = PTR_ERR(au_hin_handle); ++ au_hin_destroy_cache(); ++ } ++ } ++ AuTraceErr(err); ++ return err; ++} ++ ++void au_hinotify_fin(void) ++{ ++ inotify_destroy(au_hin_handle); ++ if (au_cachep[AuCache_HINOTIFY]) ++ au_hin_destroy_cache(); ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/iinfo.c linux-2.6.31/fs/aufs/iinfo.c +--- linux-2.6.31-vanilla/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/iinfo.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,283 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * inode private data ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct inode *h_inode; ++ ++ IiMustAnyLock(inode); ++ ++ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ return h_inode; ++} ++ ++/* todo: hard/soft set? */ ++void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct au_iinfo *iinfo = au_ii(inode); ++ struct inode *h_inode; ++ ++ IiMustWriteLock(inode); ++ ++ iinfo->ii_bstart = bindex; ++ h_inode = iinfo->ii_hinode[bindex + 0].hi_inode; ++ if (h_inode) ++ au_cpup_igen(inode, h_inode); ++} ++ ++void au_hiput(struct au_hinode *hinode) ++{ ++ au_hin_free(hinode); ++ dput(hinode->hi_whdentry); ++ iput(hinode->hi_inode); ++} ++ ++unsigned int au_hi_flags(struct inode *inode, int isdir) ++{ ++ unsigned int flags; ++ const unsigned int mnt_flags = au_mntflags(inode->i_sb); ++ ++ flags = 0; ++ if (au_opt_test(mnt_flags, XINO)) ++ au_fset_hi(flags, XINO); ++ if (isdir && au_opt_test(mnt_flags, UDBA_HINOTIFY)) ++ au_fset_hi(flags, HINOTIFY); ++ return flags; ++} ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags) ++{ ++ struct au_hinode *hinode; ++ struct inode *hi; ++ struct au_iinfo *iinfo = au_ii(inode); ++ ++ IiMustWriteLock(inode); ++ ++ hinode = iinfo->ii_hinode + bindex; ++ hi = hinode->hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ AuDebugOn(h_inode && hi); ++ ++ if (hi) ++ au_hiput(hinode); ++ hinode->hi_inode = h_inode; ++ if (h_inode) { ++ int err; ++ struct super_block *sb = inode->i_sb; ++ struct au_branch *br; ++ ++ if (bindex == iinfo->ii_bstart) ++ au_cpup_igen(inode, h_inode); ++ br = au_sbr(sb, bindex); ++ hinode->hi_id = br->br_id; ++ if (au_ftest_hi(flags, XINO)) { ++ err = au_xino_write(sb, bindex, h_inode->i_ino, ++ inode->i_ino); ++ if (unlikely(err)) ++ AuIOErr1("failed au_xino_write() %d\n", err); ++ } ++ ++ if (au_ftest_hi(flags, HINOTIFY) ++ && au_br_hinotifyable(br->br_perm)) { ++ err = au_hin_alloc(hinode, inode, h_inode); ++ if (unlikely(err)) ++ AuIOErr1("au_hin_alloc() %d\n", err); ++ } ++ } ++} ++ ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh) ++{ ++ struct au_hinode *hinode; ++ ++ IiMustWriteLock(inode); ++ ++ hinode = au_ii(inode)->ii_hinode + bindex; ++ AuDebugOn(hinode->hi_whdentry); ++ hinode->hi_whdentry = h_wh; ++} ++ ++void au_update_iigen(struct inode *inode) ++{ ++ atomic_set(&au_ii(inode)->ii_generation, au_sigen(inode->i_sb)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++/* it may be called at remount time, too */ ++void au_update_brange(struct inode *inode, int do_put_zero) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ if (!iinfo || iinfo->ii_bstart < 0) ++ return; ++ ++ IiMustWriteLock(inode); ++ ++ if (do_put_zero) { ++ aufs_bindex_t bindex; ++ ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++) { ++ struct inode *h_i; ++ ++ h_i = iinfo->ii_hinode[0 + bindex].hi_inode; ++ if (h_i && !h_i->i_nlink) ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ } ++ } ++ ++ iinfo->ii_bstart = -1; ++ while (++iinfo->ii_bstart <= iinfo->ii_bend) ++ if (iinfo->ii_hinode[0 + iinfo->ii_bstart].hi_inode) ++ break; ++ if (iinfo->ii_bstart > iinfo->ii_bend) { ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ return; ++ } ++ ++ iinfo->ii_bend++; ++ while (0 <= --iinfo->ii_bend) ++ if (iinfo->ii_hinode[0 + iinfo->ii_bend].hi_inode) ++ break; ++ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend || iinfo->ii_bend < 0); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_iinfo_init(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ struct super_block *sb; ++ int nbr, i; ++ ++ sb = inode->i_sb; ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ nbr = au_sbend(sb) + 1; ++ if (unlikely(nbr <= 0)) ++ nbr = 1; ++ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); ++ if (iinfo->ii_hinode) { ++ for (i = 0; i < nbr; i++) ++ iinfo->ii_hinode[i].hi_id = -1; ++ ++ atomic_set(&iinfo->ii_generation, au_sigen(sb)); ++ /* smp_mb(); */ /* atomic_set */ ++ au_rw_init(&iinfo->ii_rwsem); ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ iinfo->ii_vdir = NULL; ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr) ++{ ++ int err, sz; ++ struct au_hinode *hip; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*hip) * (iinfo->ii_bend + 1); ++ if (!sz) ++ sz = sizeof(*hip); ++ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS); ++ if (hip) { ++ iinfo->ii_hinode = hip; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++static int au_iinfo_write0(struct super_block *sb, struct au_hinode *hinode, ++ ino_t ino) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ unsigned char locked; ++ ++ err = 0; ++ locked = !!si_noflush_read_trylock(sb); ++ bindex = au_br_index(sb, hinode->hi_id); ++ if (bindex >= 0) ++ err = au_xino_write0(sb, bindex, hinode->hi_inode->i_ino, ino); ++ /* error action? */ ++ if (locked) ++ si_read_unlock(sb); ++ return err; ++} ++ ++void au_iinfo_fin(struct inode *inode) ++{ ++ ino_t ino; ++ aufs_bindex_t bend; ++ unsigned char unlinked = !inode->i_nlink; ++ struct au_iinfo *iinfo; ++ struct au_hinode *hi; ++ struct super_block *sb; ++ ++ if (unlinked) { ++ int err = au_xigen_inc(inode); ++ if (unlikely(err)) ++ AuWarn1("failed resetting i_generation, %d\n", err); ++ } ++ ++ iinfo = au_ii(inode); ++ /* bad_inode case */ ++ if (!iinfo) ++ return; ++ ++ if (iinfo->ii_vdir) ++ au_vdir_free(iinfo->ii_vdir); ++ ++ if (iinfo->ii_bstart >= 0) { ++ sb = inode->i_sb; ++ ino = 0; ++ if (unlinked) ++ ino = inode->i_ino; ++ hi = iinfo->ii_hinode + iinfo->ii_bstart; ++ bend = iinfo->ii_bend; ++ while (iinfo->ii_bstart++ <= bend) { ++ if (hi->hi_inode) { ++ if (unlinked || !hi->hi_inode->i_nlink) { ++ au_iinfo_write0(sb, hi, ino); ++ /* ignore this error */ ++ ino = 0; ++ } ++ au_hiput(hi); ++ } ++ hi++; ++ } ++ } ++ ++ kfree(iinfo->ii_hinode); ++ AuRwDestroy(&iinfo->ii_rwsem); ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/inode.c linux-2.6.31/fs/aufs/inode.c +--- linux-2.6.31-vanilla/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/inode.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,413 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * inode functions ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_igrab(struct inode *inode) ++{ ++ if (inode) { ++ AuDebugOn(!atomic_read(&inode->i_count)); ++ atomic_inc_return(&inode->i_count); ++ } ++ return inode; ++} ++ ++static void au_refresh_hinode_attr(struct inode *inode, int do_version) ++{ ++ au_cpup_attr_all(inode, /*force*/0); ++ au_update_iigen(inode); ++ if (do_version) ++ inode->i_version++; ++} ++ ++int au_refresh_hinode_self(struct inode *inode, int do_attr) ++{ ++ int err; ++ aufs_bindex_t bindex, new_bindex; ++ unsigned char update; ++ struct inode *first; ++ struct au_hinode *p, *q, tmp; ++ struct super_block *sb; ++ struct au_iinfo *iinfo; ++ ++ IiMustWriteLock(inode); ++ ++ update = 0; ++ sb = inode->i_sb; ++ iinfo = au_ii(inode); ++ err = au_ii_realloc(iinfo, au_sbend(sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ first = p->hi_inode; ++ err = 0; ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++, p++) { ++ if (!p->hi_inode) ++ continue; ++ ++ new_bindex = au_br_index(sb, p->hi_id); ++ if (new_bindex == bindex) ++ continue; ++ ++ if (new_bindex < 0) { ++ update++; ++ au_hiput(p); ++ p->hi_inode = NULL; ++ continue; ++ } ++ ++ if (new_bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = new_bindex; ++ if (iinfo->ii_bend < new_bindex) ++ iinfo->ii_bend = new_bindex; ++ /* swap two lower inode, and loop again */ ++ q = iinfo->ii_hinode + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hi_inode) { ++ bindex--; ++ p--; ++ } ++ } ++ au_update_brange(inode, /*do_put_zero*/0); ++ if (do_attr) ++ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); ++ ++ out: ++ return err; ++} ++ ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry) ++{ ++ int err, update; ++ unsigned int flags; ++ aufs_bindex_t bindex, bend; ++ unsigned char isdir; ++ struct inode *first; ++ struct au_hinode *p; ++ struct au_iinfo *iinfo; ++ ++ err = au_refresh_hinode_self(inode, /*do_attr*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ update = 0; ++ iinfo = au_ii(inode); ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ first = p->hi_inode; ++ isdir = S_ISDIR(inode->i_mode); ++ flags = au_hi_flags(inode, isdir); ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { ++ struct inode *h_i; ++ struct dentry *h_d; ++ ++ h_d = au_h_dptr(dentry, bindex); ++ if (!h_d || !h_d->d_inode) ++ continue; ++ ++ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) { ++ h_i = au_h_iptr(inode, bindex); ++ if (h_i) { ++ if (h_i == h_d->d_inode) ++ continue; ++ err = -EIO; ++ break; ++ } ++ } ++ if (bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = bindex; ++ if (iinfo->ii_bend < bindex) ++ iinfo->ii_bend = bindex; ++ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags); ++ update = 1; ++ } ++ au_update_brange(inode, /*do_put_zero*/0); ++ ++ if (unlikely(err)) ++ goto out; ++ ++ au_refresh_hinode_attr(inode, update && isdir); ++ ++ out: ++ return err; ++} ++ ++static int set_inode(struct inode *inode, struct dentry *dentry) ++{ ++ int err; ++ unsigned int flags; ++ umode_t mode; ++ aufs_bindex_t bindex, bstart, btail; ++ unsigned char isdir; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ struct au_iinfo *iinfo; ++ ++ IiMustWriteLock(inode); ++ ++ err = 0; ++ isdir = 0; ++ bstart = au_dbstart(dentry); ++ h_inode = au_h_dptr(dentry, bstart)->d_inode; ++ mode = h_inode->i_mode; ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_iop; ++ inode->i_fop = &aufs_file_fop; ++ inode->i_mapping->a_ops = &aufs_aop; ++ break; ++ case S_IFDIR: ++ isdir = 1; ++ btail = au_dbtaildir(dentry); ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ break; ++ case S_IFLNK: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_symlink_iop; ++ break; ++ case S_IFBLK: ++ case S_IFCHR: ++ case S_IFIFO: ++ case S_IFSOCK: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_iop; ++ init_special_inode(inode, mode, h_inode->i_rdev); ++ break; ++ default: ++ AuIOErr("Unknown file type 0%o\n", mode); ++ err = -EIO; ++ goto out; ++ } ++ ++ /* do not set inotify for whiteouted dirs (SHWH mode) */ ++ flags = au_hi_flags(inode, isdir); ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH) ++ && au_ftest_hi(flags, HINOTIFY) ++ && dentry->d_name.len > AUFS_WH_PFX_LEN ++ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) ++ au_fclr_hi(flags, HINOTIFY); ++ iinfo = au_ii(inode); ++ iinfo->ii_bstart = bstart; ++ iinfo->ii_bend = btail; ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry) ++ au_set_h_iptr(inode, bindex, ++ au_igrab(h_dentry->d_inode), flags); ++ } ++ au_cpup_attr_all(inode, /*force*/1); ++ ++ out: ++ return err; ++} ++ ++/* successful returns with iinfo write_locked */ ++static int reval_inode(struct inode *inode, struct dentry *dentry, int *matched) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct inode *h_inode, *h_dinode; ++ ++ *matched = 0; ++ ++ /* ++ * before this function, if aufs got any iinfo lock, it must be only ++ * one, the parent dir. ++ * it can happen by UDBA and the obsoleted inode number. ++ */ ++ err = -EIO; ++ if (unlikely(inode->i_ino == parent_ino(dentry))) ++ goto out; ++ ++ err = 0; ++ ii_write_lock_new_child(inode); ++ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode; ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode && h_inode == h_dinode) { ++ *matched = 1; ++ err = 0; ++ if (au_iigen(inode) != au_digen(dentry)) ++ err = au_refresh_hinode(inode, dentry); ++ break; ++ } ++ } ++ ++ if (unlikely(err)) ++ ii_write_unlock(inode); ++ out: ++ return err; ++} ++ ++int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino) ++{ ++ int err; ++ struct mutex *mtx; ++ const int isdir = (d_type == DT_DIR); ++ ++ /* prevent hardlinks from race condition */ ++ mtx = NULL; ++ if (!isdir) { ++ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx; ++ mutex_lock(mtx); ++ } ++ err = au_xino_read(sb, bindex, h_ino, ino); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!*ino) { ++ err = -EIO; ++ *ino = au_xino_new_ino(sb); ++ if (unlikely(!*ino)) ++ goto out; ++ err = au_xino_write(sb, bindex, h_ino, *ino); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ out: ++ if (!isdir) ++ mutex_unlock(mtx); ++ return err; ++} ++ ++/* successful returns with iinfo write_locked */ ++/* todo: return with unlocked? */ ++struct inode *au_new_inode(struct dentry *dentry, int must_new) ++{ ++ struct inode *inode; ++ struct dentry *h_dentry; ++ struct super_block *sb; ++ ino_t h_ino, ino; ++ int err, match; ++ aufs_bindex_t bstart; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ h_dentry = au_h_dptr(dentry, bstart); ++ h_ino = h_dentry->d_inode->i_ino; ++ err = au_xino_read(sb, bstart, h_ino, &ino); ++ inode = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ new_ino: ++ if (!ino) { ++ ino = au_xino_new_ino(sb); ++ if (unlikely(!ino)) { ++ inode = ERR_PTR(-EIO); ++ goto out; ++ } ++ } ++ ++ AuDbg("i%lu\n", (unsigned long)ino); ++ inode = au_iget_locked(sb, ino); ++ err = PTR_ERR(inode); ++ if (IS_ERR(inode)) ++ goto out; ++ ++ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); ++ if (inode->i_state & I_NEW) { ++ ii_write_lock_new_child(inode); ++ err = set_inode(inode, dentry); ++ unlock_new_inode(inode); ++ if (!err) ++ goto out; /* success */ ++ ++ iget_failed(inode); ++ ii_write_unlock(inode); ++ goto out_iput; ++ } else if (!must_new) { ++ err = reval_inode(inode, dentry, &match); ++ if (!err) ++ goto out; /* success */ ++ else if (match) ++ goto out_iput; ++ } ++ ++ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode))) ++ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir," ++ " b%d, %s, %.*s, hi%lu, i%lu.\n", ++ bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry), ++ (unsigned long)h_ino, (unsigned long)ino); ++ ino = 0; ++ err = au_xino_write(sb, bstart, h_ino, /*ino*/0); ++ if (!err) { ++ iput(inode); ++ goto new_ino; ++ } ++ ++ out_iput: ++ iput(inode); ++ inode = ERR_PTR(err); ++ out: ++ return inode; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode) ++{ ++ int err; ++ ++ err = au_br_rdonly(au_sbr(sb, bindex)); ++ ++ /* pseudo-link after flushed may happen out of bounds */ ++ if (!err ++ && inode ++ && au_ibstart(inode) <= bindex ++ && bindex <= au_ibend(inode)) { ++ /* ++ * permission check is unnecessary since vfsub routine ++ * will be called later ++ */ ++ struct inode *hi = au_h_iptr(inode, bindex); ++ if (hi) ++ err = IS_IMMUTABLE(hi) ? -EROFS : 0; ++ } ++ ++ return err; ++} ++ ++int au_test_h_perm(struct inode *h_inode, int mask) ++{ ++ if (!current_fsuid()) ++ return 0; ++ return inode_permission(h_inode, mask); ++} ++ ++int au_test_h_perm_sio(struct inode *h_inode, int mask) ++{ ++ if (au_test_nfs(h_inode->i_sb) ++ && (mask & MAY_WRITE) ++ && S_ISDIR(h_inode->i_mode)) ++ mask |= MAY_READ; /* force permission check */ ++ return au_test_h_perm(h_inode, mask); ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/inode.h linux-2.6.31/fs/aufs/inode.h +--- linux-2.6.31-vanilla/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/inode.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,497 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * inode operations ++ */ ++ ++#ifndef __AUFS_INODE_H__ ++#define __AUFS_INODE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/fs.h> ++#include <linux/inotify.h> ++#include <linux/aufs_type.h> ++#include "rwsem.h" ++ ++struct vfsmount; ++ ++struct au_hinotify { ++#ifdef CONFIG_AUFS_HINOTIFY ++ struct inotify_watch hin_watch; ++ struct inode *hin_aufs_inode; /* no get/put */ ++#endif ++}; ++ ++struct au_hinode { ++ struct inode *hi_inode; ++ aufs_bindex_t hi_id; ++#ifdef CONFIG_AUFS_HINOTIFY ++ struct au_hinotify *hi_notify; ++#endif ++ ++ /* reference to the copied-up whiteout with get/put */ ++ struct dentry *hi_whdentry; ++}; ++ ++struct au_vdir; ++struct au_iinfo { ++ atomic_t ii_generation; ++ struct super_block *ii_hsb1; /* no get/put */ ++ ++ struct au_rwsem ii_rwsem; ++ aufs_bindex_t ii_bstart, ii_bend; ++ __u32 ii_higen; ++ struct au_hinode *ii_hinode; ++ struct au_vdir *ii_vdir; ++}; ++ ++struct au_icntnr { ++ struct au_iinfo iinfo; ++ struct inode vfs_inode; ++}; ++ ++/* au_pin flags */ ++#define AuPin_DI_LOCKED 1 ++#define AuPin_MNT_WRITE (1 << 1) ++#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) ++#define au_fset_pin(flags, name) { (flags) |= AuPin_##name; } ++#define au_fclr_pin(flags, name) { (flags) &= ~AuPin_##name; } ++ ++struct au_pin { ++ /* input */ ++ struct dentry *dentry; ++ unsigned int udba; ++ unsigned char lsc_di, lsc_hi, flags; ++ aufs_bindex_t bindex; ++ ++ /* output */ ++ struct dentry *parent; ++ struct au_hinode *hdir; ++ struct vfsmount *h_mnt; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_iinfo *au_ii(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ if (iinfo->ii_hinode) ++ return iinfo; ++ return NULL; /* debugging bad_inode case */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* inode.c */ ++struct inode *au_igrab(struct inode *inode); ++int au_refresh_hinode_self(struct inode *inode, int do_attr); ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry); ++int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino); ++struct inode *au_new_inode(struct dentry *dentry, int must_new); ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode); ++int au_test_h_perm(struct inode *h_inode, int mask); ++int au_test_h_perm_sio(struct inode *h_inode, int mask); ++ ++static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ++ ino_t h_ino, unsigned int d_type, ino_t *ino) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ return au_ino(sb, bindex, h_ino, d_type, ino); ++#else ++ return 0; ++#endif ++} ++ ++/* i_op.c */ ++extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop; ++ ++/* au_wr_dir flags */ ++#define AuWrDir_ADD_ENTRY 1 ++#define AuWrDir_ISDIR (1 << 1) ++#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) ++#define au_fset_wrdir(flags, name) { (flags) |= AuWrDir_##name; } ++#define au_fclr_wrdir(flags, name) { (flags) &= ~AuWrDir_##name; } ++ ++struct au_wr_dir_args { ++ aufs_bindex_t force_btgt; ++ unsigned char flags; ++}; ++int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, ++ struct au_wr_dir_args *args); ++ ++struct dentry *au_pinned_h_parent(struct au_pin *pin); ++void au_pin_init(struct au_pin *pin, struct dentry *dentry, ++ aufs_bindex_t bindex, int lsc_di, int lsc_hi, ++ unsigned int udba, unsigned char flags); ++int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int udba, unsigned char flags) __must_check; ++int au_do_pin(struct au_pin *pin) __must_check; ++void au_unpin(struct au_pin *pin); ++ ++/* i_op_add.c */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); ++int aufs_create(struct inode *dir, struct dentry *dentry, int mode, ++ struct nameidata *nd); ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry); ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode); ++ ++/* i_op_del.c */ ++int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); ++int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_unlink(struct inode *dir, struct dentry *dentry); ++int aufs_rmdir(struct inode *dir, struct dentry *dentry); ++ ++/* i_op_ren.c */ ++int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); ++int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, ++ struct inode *dir, struct dentry *dentry); ++ ++/* iinfo.c */ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); ++void au_hiput(struct au_hinode *hinode); ++void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex); ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh); ++unsigned int au_hi_flags(struct inode *inode, int isdir); ++ ++/* hinode flags */ ++#define AuHi_XINO 1 ++#define AuHi_HINOTIFY (1 << 1) ++#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) ++#define au_fset_hi(flags, name) { (flags) |= AuHi_##name; } ++#define au_fclr_hi(flags, name) { (flags) &= ~AuHi_##name; } ++ ++#ifndef CONFIG_AUFS_HINOTIFY ++#undef AuHi_HINOTIFY ++#define AuHi_HINOTIFY 0 ++#endif ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags); ++ ++void au_update_iigen(struct inode *inode); ++void au_update_brange(struct inode *inode, int do_put_zero); ++ ++int au_iinfo_init(struct inode *inode); ++void au_iinfo_fin(struct inode *inode); ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr); ++ ++/* plink.c */ ++void au_plink_block_maintain(struct super_block *sb); ++#ifdef CONFIG_AUFS_DEBUG ++void au_plink_list(struct super_block *sb); ++#else ++static inline void au_plink_list(struct super_block *sb) ++{ ++ /* nothing */ ++} ++#endif ++int au_plink_test(struct inode *inode); ++struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex); ++void au_plink_append(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++void au_plink_put(struct super_block *sb); ++void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); ++long au_plink_ioctl(struct file *file, unsigned int cmd); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for iinfo */ ++enum { ++ AuLsc_II_CHILD, /* child first */ ++ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hinotify */ ++ AuLsc_II_CHILD3, /* copyup dirs */ ++ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ ++ AuLsc_II_PARENT2, ++ AuLsc_II_PARENT3, /* copyup dirs */ ++ AuLsc_II_NEW_CHILD ++}; ++ ++/* ++ * ii_read_lock_child, ii_write_lock_child, ++ * ii_read_lock_child2, ii_write_lock_child2, ++ * ii_read_lock_child3, ii_write_lock_child3, ++ * ii_read_lock_parent, ii_write_lock_parent, ++ * ii_read_lock_parent2, ii_write_lock_parent2, ++ * ii_read_lock_parent3, ii_write_lock_parent3, ++ * ii_read_lock_new_child, ii_write_lock_new_child, ++ */ ++#define AuReadLockFunc(name, lsc) \ ++static inline void ii_read_lock_##name(struct inode *i) \ ++{ \ ++ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuWriteLockFunc(name, lsc) \ ++static inline void ii_write_lock_##name(struct inode *i) \ ++{ \ ++ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuRWLockFuncs(name, lsc) \ ++ AuReadLockFunc(name, lsc) \ ++ AuWriteLockFunc(name, lsc) ++ ++AuRWLockFuncs(child, CHILD); ++AuRWLockFuncs(child2, CHILD2); ++AuRWLockFuncs(child3, CHILD3); ++AuRWLockFuncs(parent, PARENT); ++AuRWLockFuncs(parent2, PARENT2); ++AuRWLockFuncs(parent3, PARENT3); ++AuRWLockFuncs(new_child, NEW_CHILD); ++ ++#undef AuReadLockFunc ++#undef AuWriteLockFunc ++#undef AuRWLockFuncs ++ ++/* ++ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock ++ */ ++AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem); ++ ++#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) ++#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem) ++#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline unsigned int au_iigen(struct inode *inode) ++{ ++ return atomic_read(&au_ii(inode)->ii_generation); ++} ++ ++/* tiny test for inode number */ ++/* tmpfs generation is too rough */ ++static inline int au_test_higen(struct inode *inode, struct inode *h_inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ AuRwMustAnyLock(&iinfo->ii_rwsem); ++ return !(iinfo->ii_hsb1 == h_inode->i_sb ++ && iinfo->ii_higen == h_inode->i_generation); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline aufs_bindex_t au_ii_br_id(struct inode *inode, ++ aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_id; ++} ++ ++static inline aufs_bindex_t au_ibstart(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_bstart; ++} ++ ++static inline aufs_bindex_t au_ibend(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_bend; ++} ++ ++static inline struct au_vdir *au_ivdir(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_vdir; ++} ++ ++static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry; ++} ++ ++static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_bend = bindex; ++} ++ ++static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_vdir = vdir; ++} ++ ++static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode + bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct dentry *au_pinned_parent(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->parent; ++ return NULL; ++} ++ ++static inline struct inode *au_pinned_h_dir(struct au_pin *pin) ++{ ++ if (pin && pin->hdir) ++ return pin->hdir->hi_inode; ++ return NULL; ++} ++ ++static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->hdir; ++ return NULL; ++} ++ ++static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry) ++{ ++ if (pin) ++ pin->dentry = dentry; ++} ++ ++static inline void au_pin_set_parent_lflag(struct au_pin *pin, ++ unsigned char lflag) ++{ ++ if (pin) { ++ /* dirty macros require brackets */ ++ if (lflag) { ++ au_fset_pin(pin->flags, DI_LOCKED); ++ } else { ++ au_fclr_pin(pin->flags, DI_LOCKED); ++ } ++ } ++} ++ ++static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent) ++{ ++ if (pin) { ++ dput(pin->parent); ++ pin->parent = dget(parent); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_HINOTIFY ++/* hinotify.c */ ++int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, ++ struct inode *h_inode); ++void au_hin_free(struct au_hinode *hinode); ++void au_hin_ctl(struct au_hinode *hinode, int do_set); ++void au_reset_hinotify(struct inode *inode, unsigned int flags); ++ ++int __init au_hinotify_init(void); ++void au_hinotify_fin(void); ++ ++static inline ++void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val) ++{ ++ hinode->hi_notify = val; ++} ++ ++static inline void au_iigen_dec(struct inode *inode) ++{ ++ atomic_dec_return(&au_ii(inode)->ii_generation); ++} ++ ++#else ++static inline ++int au_hin_alloc(struct au_hinode *hinode __maybe_unused, ++ struct inode *inode __maybe_unused, ++ struct inode *h_inode __maybe_unused) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void au_hin_free(struct au_hinode *hinode __maybe_unused) ++{ ++ /* nothing */ ++} ++ ++static inline void au_hin_ctl(struct au_hinode *hinode __maybe_unused, ++ int do_set __maybe_unused) ++{ ++ /* nothing */ ++} ++ ++static inline void au_reset_hinotify(struct inode *inode __maybe_unused, ++ unsigned int flags __maybe_unused) ++{ ++ /* nothing */ ++} ++ ++static inline int au_hinotify_init(void) ++{ ++ return 0; ++} ++ ++#define au_hinotify_fin() do {} while (0) ++ ++static inline ++void au_hin_init(struct au_hinode *hinode __maybe_unused, ++ struct au_hinotify *val __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* CONFIG_AUFS_HINOTIFY */ ++ ++static inline void au_hin_suspend(struct au_hinode *hdir) ++{ ++ au_hin_ctl(hdir, /*do_set*/0); ++} ++ ++static inline void au_hin_resume(struct au_hinode *hdir) ++{ ++ au_hin_ctl(hdir, /*do_set*/1); ++} ++ ++static inline void au_hin_imtx_lock(struct au_hinode *hdir) ++{ ++ mutex_lock(&hdir->hi_inode->i_mutex); ++ au_hin_suspend(hdir); ++} ++ ++static inline void au_hin_imtx_lock_nested(struct au_hinode *hdir, ++ unsigned int sc __maybe_unused) ++{ ++ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc); ++ au_hin_suspend(hdir); ++} ++ ++static inline void au_hin_imtx_unlock(struct au_hinode *hdir) ++{ ++ au_hin_resume(hdir); ++ mutex_unlock(&hdir->hi_inode->i_mutex); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_INODE_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/ioctl.c linux-2.6.31/fs/aufs/ioctl.c +--- linux-2.6.31-vanilla/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/ioctl.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * ioctl ++ * plink-management and readdir in userspace. ++ */ ++ ++#include "aufs.h" ++ ++long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err; ++ ++ switch (cmd) { ++ case AUFS_CTL_PLINK_MAINT: ++ case AUFS_CTL_PLINK_CLEAN: ++ err = au_plink_ioctl(file, cmd); ++ break; ++ ++ case AUFS_CTL_RDU: ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_ioctl(file, cmd, arg); ++ break; ++ ++ default: ++ err = -EINVAL; ++ } ++ ++ AuTraceErr(err); ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/i_op_add.c linux-2.6.31/fs/aufs/i_op_add.c +--- linux-2.6.31-vanilla/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/i_op_add.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,649 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * inode operations (add entry) ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * final procedure of adding a new entry, except link(2). ++ * remove whiteout, instantiate, copyup the parent dir's times and size ++ * and update version. ++ * if it failed, re-create the removed whiteout. ++ */ ++static int epilog(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct dentry *dentry) ++{ ++ int err, rerr; ++ aufs_bindex_t bwh; ++ struct path h_path; ++ struct inode *inode, *h_dir; ++ struct dentry *wh; ++ ++ bwh = -1; ++ if (wh_dentry) { ++ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(h_dir); ++ AuDebugOn(au_h_iptr(dir, bindex) != h_dir); ++ bwh = au_dbwh(dentry); ++ h_path.dentry = wh_dentry; ++ h_path.mnt = au_sbr_mnt(dir->i_sb, bindex); ++ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ inode = au_new_inode(dentry, /*must_new*/1); ++ if (!IS_ERR(inode)) { ++ d_instantiate(dentry, inode); ++ dir = dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(dir); ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ dir->i_version++; ++ return 0; /* success */ ++ } ++ ++ err = PTR_ERR(inode); ++ if (!wh_dentry) ++ goto out; ++ ++ /* revert */ ++ /* dir inode is locked */ ++ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent); ++ rerr = PTR_ERR(wh); ++ if (IS_ERR(wh)) { ++ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } else ++ dput(wh); ++ ++ out: ++ return err; ++} ++ ++/* ++ * simple tests for the adding inode operations. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir) ++{ ++ int err; ++ umode_t h_mode; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ h_inode = h_dentry->d_inode; ++ if (!dentry->d_inode) { ++ err = -EEXIST; ++ if (unlikely(h_inode)) ++ goto out; ++ } else { ++ /* rename(2) case */ ++ err = -EIO; ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ ++ h_mode = h_inode->i_mode; ++ if (!isdir) { ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(h_mode))) ++ goto out; ++ } else if (unlikely(!S_ISDIR(h_mode))) { ++ err = -ENOTDIR; ++ goto out; ++ } ++ } ++ ++ err = -EIO; ++ /* expected parent dir is locked */ ++ if (unlikely(h_parent != h_dentry->d_parent)) ++ goto out; ++ err = 0; ++ ++ out: ++ return err; ++} ++ ++/* ++ * initial procedure of adding a new entry. ++ * prepare writable branch and the parent dir, lock it, ++ * and lookup whiteout for the new entry. ++ */ ++static struct dentry* ++lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, ++ struct dentry *src_dentry, struct au_pin *pin, ++ struct au_wr_dir_args *wr_dir_args) ++{ ++ struct dentry *wh_dentry, *h_parent; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ unsigned int udba; ++ aufs_bindex_t bcpup; ++ ++ err = au_wr_dir(dentry, src_dentry, wr_dir_args); ++ bcpup = err; ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ udba = au_opt_udba(sb); ++ err = au_pin(pin, dentry, bcpup, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ h_parent = au_pinned_h_parent(pin); ++ if (udba != AuOpt_UDBA_NONE ++ && au_dbstart(dentry) == bcpup) { ++ err = au_may_add(dentry, bcpup, h_parent, ++ au_ftest_wrdir(wr_dir_args->flags, ISDIR)); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_unpin; ++ } ++ ++ br = au_sbr(sb, bcpup); ++ if (dt) { ++ struct path tmp = { ++ .dentry = h_parent, ++ .mnt = br->br_mnt ++ }; ++ au_dtime_store(dt, au_pinned_parent(pin), &tmp); ++ } ++ ++ wh_dentry = NULL; ++ if (bcpup != au_dbwh(dentry)) ++ goto out; /* success */ ++ ++ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br); ++ ++ out_unpin: ++ if (IS_ERR(wh_dentry)) ++ au_unpin(pin); ++ out: ++ return wh_dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { Mknod, Symlink, Creat }; ++struct simple_arg { ++ int type; ++ union { ++ struct { ++ int mode; ++ struct nameidata *nd; ++ } c; ++ struct { ++ const char *symname; ++ } s; ++ struct { ++ int mode; ++ dev_t dev; ++ } m; ++ } u; ++}; ++ ++static int add_simple(struct inode *dir, struct dentry *dentry, ++ struct simple_arg *arg) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ unsigned char created; ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ struct dentry *wh_dentry, *parent; ++ struct inode *h_dir; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ IMustLock(dir); ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ aufs_read_lock(dentry, AuLock_DW); ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin, ++ &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ bstart = au_dbstart(dentry); ++ h_path.dentry = au_h_dptr(dentry, bstart); ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ h_dir = au_pinned_h_dir(&pin); ++ switch (arg->type) { ++ case Creat: ++ err = vfsub_create(h_dir, &h_path, arg->u.c.mode); ++ break; ++ case Symlink: ++ err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname); ++ break; ++ case Mknod: ++ err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev); ++ break; ++ default: ++ BUG(); ++ } ++ created = !err; ++ if (!err) ++ err = epilog(dir, bstart, wh_dentry, dentry); ++ ++ /* revert */ ++ if (unlikely(created && err && h_path.dentry->d_inode)) { ++ int rerr; ++ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ if (rerr) { ++ AuIOErr("%.*s revert failure(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } ++ au_dtime_revert(&dt); ++ d_drop(dentry); ++ } ++ ++ au_unpin(&pin); ++ dput(wh_dentry); ++ ++ out: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ return err; ++} ++ ++int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) ++{ ++ struct simple_arg arg = { ++ .type = Mknod, ++ .u.m = { ++ .mode = mode, ++ .dev = dev ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) ++{ ++ struct simple_arg arg = { ++ .type = Symlink, ++ .u.s.symname = symname ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_create(struct inode *dir, struct dentry *dentry, int mode, ++ struct nameidata *nd) ++{ ++ struct simple_arg arg = { ++ .type = Creat, ++ .u.c = { ++ .mode = mode, ++ .nd = nd ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_link_args { ++ aufs_bindex_t bdst, bsrc; ++ struct au_pin pin; ++ struct path h_path; ++ struct dentry *src_parent, *parent; ++}; ++ ++static int au_cpup_before_link(struct dentry *src_dentry, ++ struct au_link_args *a) ++{ ++ int err; ++ struct dentry *h_src_dentry; ++ struct mutex *h_mtx; ++ ++ di_read_lock_parent(a->src_parent, AuLock_IR); ++ err = au_test_and_cpup_dirs(src_dentry, a->bdst); ++ if (unlikely(err)) ++ goto out; ++ ++ h_src_dentry = au_h_dptr(src_dentry, a->bsrc); ++ h_mtx = &h_src_dentry->d_inode->i_mutex; ++ err = au_pin(&a->pin, src_dentry, a->bdst, ++ au_opt_udba(src_dentry->d_sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ err = au_sio_cpup_simple(src_dentry, a->bdst, -1, ++ AuCpup_DTIME /* | AuCpup_KEEPLINO */); ++ mutex_unlock(h_mtx); ++ au_unpin(&a->pin); ++ ++ out: ++ di_read_unlock(a->src_parent, AuLock_IR); ++ return err; ++} ++ ++static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a) ++{ ++ int err; ++ unsigned char plink; ++ struct inode *h_inode, *inode; ++ struct dentry *h_src_dentry; ++ struct super_block *sb; ++ ++ plink = 0; ++ h_inode = NULL; ++ sb = src_dentry->d_sb; ++ inode = src_dentry->d_inode; ++ if (au_ibstart(inode) <= a->bdst) ++ h_inode = au_h_iptr(inode, a->bdst); ++ if (!h_inode || !h_inode->i_nlink) { ++ /* copyup src_dentry as the name of dentry. */ ++ au_set_dbstart(src_dentry, a->bdst); ++ au_set_h_dptr(src_dentry, a->bdst, dget(a->h_path.dentry)); ++ h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1, ++ AuCpup_KEEPLINO, a->parent); ++ mutex_unlock(&h_inode->i_mutex); ++ au_set_h_dptr(src_dentry, a->bdst, NULL); ++ au_set_dbstart(src_dentry, a->bsrc); ++ } else { ++ /* the inode of src_dentry already exists on a.bdst branch */ ++ h_src_dentry = d_find_alias(h_inode); ++ if (!h_src_dentry && au_plink_test(inode)) { ++ plink = 1; ++ h_src_dentry = au_plink_lkup(inode, a->bdst); ++ err = PTR_ERR(h_src_dentry); ++ if (IS_ERR(h_src_dentry)) ++ goto out; ++ ++ if (unlikely(!h_src_dentry->d_inode)) { ++ dput(h_src_dentry); ++ h_src_dentry = NULL; ++ } ++ ++ } ++ if (h_src_dentry) { ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path); ++ dput(h_src_dentry); ++ } else { ++ AuIOErr("no dentry found for hi%lu on b%d\n", ++ h_inode->i_ino, a->bdst); ++ err = -EIO; ++ } ++ } ++ ++ if (!err && !plink) ++ au_plink_append(inode, a->bdst, a->h_path.dentry); ++ ++out: ++ return err; ++} ++ ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry) ++{ ++ int err, rerr; ++ struct au_dtime dt; ++ struct au_link_args *a; ++ struct dentry *wh_dentry, *h_src_dentry; ++ struct inode *inode; ++ struct super_block *sb; ++ struct au_wr_dir_args wr_dir_args = { ++ /* .force_btgt = -1, */ ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ IMustLock(dir); ++ inode = src_dentry->d_inode; ++ IMustLock(inode); ++ ++ err = -ENOENT; ++ if (unlikely(!inode->i_nlink)) ++ goto out; ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ a->parent = dentry->d_parent; /* dir inode is locked */ ++ aufs_read_and_write_lock2(dentry, src_dentry, /*AuLock_FLUSH*/0); ++ a->src_parent = dget_parent(src_dentry); ++ wr_dir_args.force_btgt = au_dbstart(src_dentry); ++ ++ di_write_lock_parent(a->parent); ++ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, ++ &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_unlock; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ a->bdst = au_dbstart(dentry); ++ a->h_path.dentry = au_h_dptr(dentry, a->bdst); ++ a->h_path.mnt = au_sbr_mnt(sb, a->bdst); ++ a->bsrc = au_dbstart(src_dentry); ++ if (au_opt_test(au_mntflags(sb), PLINK)) { ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) ++ err = au_cpup_or_link(src_dentry, a); ++ else { ++ h_src_dentry = au_h_dptr(src_dentry, a->bdst); ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path); ++ } ++ } else { ++ /* ++ * copyup src_dentry to the branch we process, ++ * and then link(2) to it. ++ */ ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) { ++ au_unpin(&a->pin); ++ di_write_unlock(a->parent); ++ err = au_cpup_before_link(src_dentry, a); ++ di_write_lock_parent(a->parent); ++ if (!err) ++ err = au_pin(&a->pin, dentry, a->bdst, ++ au_opt_udba(sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_wh; ++ } ++ if (!err) { ++ h_src_dentry = au_h_dptr(src_dentry, a->bdst); ++ err = -ENOENT; ++ if (h_src_dentry && h_src_dentry->d_inode) ++ err = vfsub_link(h_src_dentry, ++ au_pinned_h_dir(&a->pin), ++ &a->h_path); ++ } ++ } ++ if (unlikely(err)) ++ goto out_unpin; ++ ++ if (wh_dentry) { ++ a->h_path.dentry = wh_dentry; ++ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out_revert; ++ } ++ ++ dir->i_version++; ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ inc_nlink(inode); ++ inode->i_ctime = dir->i_ctime; ++ if (!d_unhashed(a->h_path.dentry)) ++ d_instantiate(dentry, au_igrab(inode)); ++ else ++ /* some filesystem calls d_drop() */ ++ d_drop(dentry); ++ goto out_unpin; /* success */ ++ ++ out_revert: ++ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, /*force*/0); ++ if (!rerr) ++ goto out_dt; ++ AuIOErr("%.*s reverting failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ out_dt: ++ d_drop(dentry); ++ au_dtime_revert(&dt); ++ out_unpin: ++ au_unpin(&a->pin); ++ out_wh: ++ dput(wh_dentry); ++ out_unlock: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ di_write_unlock(a->parent); ++ dput(a->src_parent); ++ aufs_read_and_write_unlock2(dentry, src_dentry); ++ kfree(a); ++ out: ++ return err; ++} ++ ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ++{ ++ int err, rerr; ++ aufs_bindex_t bindex; ++ unsigned char diropq; ++ struct path h_path; ++ struct dentry *wh_dentry, *parent, *opq_dentry; ++ struct mutex *h_mtx; ++ struct super_block *sb; ++ struct { ++ struct au_pin pin; ++ struct au_dtime dt; ++ } *a; /* reduce the stack usage */ ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR ++ }; ++ ++ IMustLock(dir); ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ aufs_read_lock(dentry, AuLock_DW); ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, ++ &a->pin, &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_free; ++ ++ sb = dentry->d_sb; ++ bindex = au_dbstart(dentry); ++ h_path.dentry = au_h_dptr(dentry, bindex); ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ /* make the dir opaque */ ++ diropq = 0; ++ h_mtx = &h_path.dentry->d_inode->i_mutex; ++ if (wh_dentry ++ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ opq_dentry = au_diropq_create(dentry, bindex); ++ mutex_unlock(h_mtx); ++ err = PTR_ERR(opq_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out_dir; ++ dput(opq_dentry); ++ diropq = 1; ++ } ++ ++ err = epilog(dir, bindex, wh_dentry, dentry); ++ if (!err) { ++ inc_nlink(dir); ++ goto out_unlock; /* success */ ++ } ++ ++ /* revert */ ++ if (diropq) { ++ AuLabel(revert opq); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(dentry, bindex); ++ mutex_unlock(h_mtx); ++ if (rerr) { ++ AuIOErr("%.*s reverting diropq failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } ++ } ++ ++ out_dir: ++ AuLabel(revert dir); ++ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path); ++ if (rerr) { ++ AuIOErr("%.*s reverting dir failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ err = -EIO; ++ } ++ d_drop(dentry); ++ au_dtime_revert(&a->dt); ++ out_unlock: ++ au_unpin(&a->pin); ++ dput(wh_dentry); ++ out_free: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ kfree(a); ++ out: ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/i_op.c linux-2.6.31/fs/aufs/i_op.c +--- linux-2.6.31-vanilla/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/i_op.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,891 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * inode operations (except add/del/rename) ++ */ ++ ++#include <linux/device_cgroup.h> ++#include <linux/fs_stack.h> ++#include <linux/mm.h> ++#include <linux/namei.h> ++#include <linux/security.h> ++#include <linux/uaccess.h> ++#include "aufs.h" ++ ++static int h_permission(struct inode *h_inode, int mask, ++ struct vfsmount *h_mnt, int brperm) ++{ ++ int err; ++ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); ++ ++ err = -EACCES; ++ if ((write_mask && IS_IMMUTABLE(h_inode)) ++ || ((mask & MAY_EXEC) ++ && S_ISREG(h_inode->i_mode) ++ && ((h_mnt->mnt_flags & MNT_NOEXEC) ++ || !(h_inode->i_mode & S_IXUGO)))) ++ goto out; ++ ++ /* ++ * - skip the lower fs test in the case of write to ro branch. ++ * - nfs dir permission write check is optimized, but a policy for ++ * link/rename requires a real check. ++ */ ++ if ((write_mask && !au_br_writable(brperm)) ++ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) ++ && write_mask && !(mask & MAY_READ)) ++ || !h_inode->i_op->permission) { ++ /* AuLabel(generic_permission); */ ++ err = generic_permission(h_inode, mask, NULL); ++ } else { ++ /* AuLabel(h_inode->permission); */ ++ err = h_inode->i_op->permission(h_inode, mask); ++ AuTraceErr(err); ++ } ++ ++ if (!err) ++ err = devcgroup_inode_permission(h_inode, mask); ++ if (!err) ++ err = security_inode_permission ++ (h_inode, mask & (MAY_READ | MAY_WRITE | MAY_EXEC ++ | MAY_APPEND)); ++ ++#if 0 ++ if (!err) { ++ /* todo: do we need to call ima_path_check()? */ ++ struct path h_path = { ++ .dentry = ++ .mnt = h_mnt ++ }; ++ err = ima_path_check(&h_path, ++ mask & (MAY_READ | MAY_WRITE | MAY_EXEC), ++ IMA_COUNT_LEAVE); ++ } ++#endif ++ ++ out: ++ return err; ++} ++ ++static int aufs_permission(struct inode *inode, int mask) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ const unsigned char isdir = !!S_ISDIR(inode->i_mode); ++ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); ++ struct inode *h_inode; ++ struct super_block *sb; ++ struct au_branch *br; ++ ++ sb = inode->i_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ii_read_lock_child(inode); ++ ++ if (!isdir || write_mask) { ++ err = au_busy_or_stale(); ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ if (unlikely(!h_inode ++ || (h_inode->i_mode & S_IFMT) ++ != (inode->i_mode & S_IFMT))) ++ goto out; ++ ++ err = 0; ++ bindex = au_ibstart(inode); ++ br = au_sbr(sb, bindex); ++ err = h_permission(h_inode, mask, br->br_mnt, br->br_perm); ++ if (write_mask && !err) { ++ /* test whether the upper writable branch exists */ ++ err = -EROFS; ++ for (; bindex >= 0; bindex--) ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = 0; ++ break; ++ } ++ } ++ goto out; ++ } ++ ++ /* non-write to dir */ ++ err = 0; ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode) { ++ err = au_busy_or_stale(); ++ if (unlikely(!S_ISDIR(h_inode->i_mode))) ++ break; ++ ++ br = au_sbr(sb, bindex); ++ err = h_permission(h_inode, mask, br->br_mnt, ++ br->br_perm); ++ } ++ } ++ ++ out: ++ ii_read_unlock(inode); ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, ++ struct nameidata *nd) ++{ ++ struct dentry *ret, *parent; ++ struct inode *inode, *h_inode; ++ struct mutex *mtx; ++ struct super_block *sb; ++ int err, npositive; ++ aufs_bindex_t bstart; ++ ++ IMustLock(dir); ++ ++ sb = dir->i_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_alloc_dinfo(dentry); ++ ret = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_read_lock_parent(parent, AuLock_IR); ++ npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, nd); ++ di_read_unlock(parent, AuLock_IR); ++ err = npositive; ++ ret = ERR_PTR(err); ++ if (unlikely(err < 0)) ++ goto out_unlock; ++ ++ inode = NULL; ++ if (npositive) { ++ bstart = au_dbstart(dentry); ++ h_inode = au_h_dptr(dentry, bstart)->d_inode; ++ if (!S_ISDIR(h_inode->i_mode)) { ++ /* ++ * stop 'race'-ing between hardlinks under different ++ * parents. ++ */ ++ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx; ++ mutex_lock(mtx); ++ inode = au_new_inode(dentry, /*must_new*/0); ++ mutex_unlock(mtx); ++ } else ++ inode = au_new_inode(dentry, /*must_new*/0); ++ ret = (void *)inode; ++ } ++ if (IS_ERR(inode)) ++ goto out_unlock; ++ ++ ret = d_splice_alias(inode, dentry); ++ if (unlikely(IS_ERR(ret) && inode)) ++ ii_write_unlock(inode); ++ ++ out_unlock: ++ di_write_unlock(dentry); ++ out: ++ si_read_unlock(sb); ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent, ++ const unsigned char add_entry, aufs_bindex_t bcpup, ++ aufs_bindex_t bstart) ++{ ++ int err; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ ++ if (add_entry) { ++ au_update_dbstart(dentry); ++ IMustLock(parent->d_inode); ++ } else ++ di_write_lock_parent(parent); ++ ++ err = 0; ++ if (!au_h_dptr(parent, bcpup)) { ++ if (bstart < bcpup) ++ err = au_cpdown_dirs(dentry, bcpup); ++ else ++ err = au_cpup_dirs(dentry, bcpup); ++ } ++ if (!err && add_entry) { ++ h_parent = au_h_dptr(parent, bcpup); ++ h_dir = h_parent->d_inode; ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ err = au_lkup_neg(dentry, bcpup); ++ /* todo: no unlock here */ ++ mutex_unlock(&h_dir->i_mutex); ++ if (bstart < bcpup && au_dbstart(dentry) < 0) { ++ au_set_dbstart(dentry, 0); ++ au_update_dbrange(dentry, /*do_put_zero*/0); ++ } ++ } ++ ++ if (!add_entry) ++ di_write_unlock(parent); ++ if (!err) ++ err = bcpup; /* success */ ++ ++ return err; ++} ++ ++/* ++ * decide the branch and the parent dir where we will create a new entry. ++ * returns new bindex or an error. ++ * copyup the parent dir if needed. ++ */ ++int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, ++ struct au_wr_dir_args *args) ++{ ++ int err; ++ aufs_bindex_t bcpup, bstart, src_bstart; ++ const unsigned char add_entry = !!au_ftest_wrdir(args->flags, ++ ADD_ENTRY); ++ struct super_block *sb; ++ struct dentry *parent; ++ struct au_sbinfo *sbinfo; ++ ++ sb = dentry->d_sb; ++ sbinfo = au_sbi(sb); ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(dentry); ++ bcpup = bstart; ++ if (args->force_btgt < 0) { ++ if (src_dentry) { ++ src_bstart = au_dbstart(src_dentry); ++ if (src_bstart < bstart) ++ bcpup = src_bstart; ++ } else if (add_entry) { ++ err = AuWbrCreate(sbinfo, dentry, ++ au_ftest_wrdir(args->flags, ISDIR)); ++ bcpup = err; ++ } ++ ++ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) { ++ if (add_entry) ++ err = AuWbrCopyup(sbinfo, dentry); ++ else { ++ if (!IS_ROOT(dentry)) { ++ di_read_lock_parent(parent, !AuLock_IR); ++ err = AuWbrCopyup(sbinfo, dentry); ++ di_read_unlock(parent, !AuLock_IR); ++ } else ++ err = AuWbrCopyup(sbinfo, dentry); ++ } ++ bcpup = err; ++ if (unlikely(err < 0)) ++ goto out; ++ } ++ } else { ++ bcpup = args->force_btgt; ++ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode)); ++ } ++ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup); ++ if (bstart < bcpup) ++ au_update_dbrange(dentry, /*do_put_zero*/1); ++ ++ err = bcpup; ++ if (bcpup == bstart) ++ goto out; /* success */ ++ ++ /* copyup the new parent into the branch we process */ ++ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart); ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *au_pinned_h_parent(struct au_pin *pin) ++{ ++ if (pin && pin->parent) ++ return au_h_dptr(pin->parent, pin->bindex); ++ return NULL; ++} ++ ++void au_unpin(struct au_pin *p) ++{ ++ if (au_ftest_pin(p->flags, MNT_WRITE)) ++ mnt_drop_write(p->h_mnt); ++ if (!p->hdir) ++ return; ++ ++ au_hin_imtx_unlock(p->hdir); ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_unlock(p->parent, AuLock_IR); ++ iput(p->hdir->hi_inode); ++ dput(p->parent); ++ p->parent = NULL; ++ p->hdir = NULL; ++ p->h_mnt = NULL; ++} ++ ++int au_do_pin(struct au_pin *p) ++{ ++ int err; ++ struct super_block *sb; ++ struct dentry *h_dentry, *h_parent; ++ struct au_branch *br; ++ struct inode *h_dir; ++ ++ err = 0; ++ sb = p->dentry->d_sb; ++ br = au_sbr(sb, p->bindex); ++ if (IS_ROOT(p->dentry)) { ++ if (au_ftest_pin(p->flags, MNT_WRITE)) { ++ p->h_mnt = br->br_mnt; ++ err = mnt_want_write(p->h_mnt); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_err; ++ } ++ } ++ goto out; ++ } ++ ++ h_dentry = NULL; ++ if (p->bindex <= au_dbend(p->dentry)) ++ h_dentry = au_h_dptr(p->dentry, p->bindex); ++ ++ p->parent = dget_parent(p->dentry); ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_lock(p->parent, AuLock_IR, p->lsc_di); ++ ++ h_dir = NULL; ++ h_parent = au_h_dptr(p->parent, p->bindex); ++ p->hdir = au_hi(p->parent->d_inode, p->bindex); ++ if (p->hdir) ++ h_dir = p->hdir->hi_inode; ++ ++ /* udba case */ ++ if (unlikely(!p->hdir || !h_dir)) { ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_unlock(p->parent, AuLock_IR); ++ dput(p->parent); ++ p->parent = NULL; ++ goto out_err; ++ } ++ ++ au_igrab(h_dir); ++ au_hin_imtx_lock_nested(p->hdir, p->lsc_hi); ++ ++ if (unlikely(p->hdir->hi_inode != h_parent->d_inode)) { ++ err = -EBUSY; ++ goto out_unpin; ++ } ++ if (h_dentry) { ++ err = au_h_verify(h_dentry, p->udba, h_dir, h_parent, br); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_unpin; ++ } ++ } ++ ++ if (au_ftest_pin(p->flags, MNT_WRITE)) { ++ p->h_mnt = br->br_mnt; ++ err = mnt_want_write(p->h_mnt); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_unpin; ++ } ++ } ++ goto out; /* success */ ++ ++ out_unpin: ++ au_unpin(p); ++ out_err: ++ AuErr("err %d\n", err); ++ err = au_busy_or_stale(); ++ out: ++ return err; ++} ++ ++void au_pin_init(struct au_pin *p, struct dentry *dentry, ++ aufs_bindex_t bindex, int lsc_di, int lsc_hi, ++ unsigned int udba, unsigned char flags) ++{ ++ p->dentry = dentry; ++ p->udba = udba; ++ p->lsc_di = lsc_di; ++ p->lsc_hi = lsc_hi; ++ p->flags = flags; ++ p->bindex = bindex; ++ ++ p->parent = NULL; ++ p->hdir = NULL; ++ p->h_mnt = NULL; ++} ++ ++int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int udba, unsigned char flags) ++{ ++ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2, ++ udba, flags); ++ return au_do_pin(pin); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuIcpup_DID_CPUP 1 ++#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name) ++#define au_fset_icpup(flags, name) { (flags) |= AuIcpup_##name; } ++#define au_fclr_icpup(flags, name) { (flags) &= ~AuIcpup_##name; } ++ ++struct au_icpup_args { ++ unsigned char flags; ++ unsigned char pin_flags; ++ aufs_bindex_t btgt; ++ struct au_pin pin; ++ struct path h_path; ++ struct inode *h_inode; ++}; ++ ++static int au_lock_and_icpup(struct dentry *dentry, struct iattr *ia, ++ struct au_icpup_args *a) ++{ ++ int err; ++ unsigned int udba; ++ loff_t sz; ++ aufs_bindex_t bstart; ++ struct dentry *hi_wh, *parent; ++ struct inode *inode; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = 0 ++ }; ++ ++ di_write_lock_child(dentry); ++ bstart = au_dbstart(dentry); ++ inode = dentry->d_inode; ++ if (S_ISDIR(inode->i_mode)) ++ au_fset_wrdir(wr_dir_args.flags, ISDIR); ++ /* plink or hi_wh() case */ ++ if (bstart != au_ibstart(inode)) ++ wr_dir_args.force_btgt = au_ibstart(inode); ++ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); ++ if (unlikely(err < 0)) ++ goto out_dentry; ++ a->btgt = err; ++ if (err != bstart) ++ au_fset_icpup(a->flags, DID_CPUP); ++ ++ err = 0; ++ a->pin_flags = AuPin_MNT_WRITE; ++ parent = NULL; ++ if (!IS_ROOT(dentry)) { ++ au_fset_pin(a->pin_flags, DI_LOCKED); ++ parent = dget_parent(dentry); ++ di_write_lock_parent(parent); ++ } ++ ++ udba = au_opt_udba(dentry->d_sb); ++ if (d_unhashed(dentry) || (ia->ia_valid & ATTR_FILE)) ++ udba = AuOpt_UDBA_NONE; ++ err = au_pin(&a->pin, dentry, a->btgt, udba, a->pin_flags); ++ if (unlikely(err)) { ++ if (parent) { ++ di_write_unlock(parent); ++ dput(parent); ++ } ++ goto out_dentry; ++ } ++ a->h_path.dentry = au_h_dptr(dentry, bstart); ++ a->h_inode = a->h_path.dentry->d_inode; ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ sz = -1; ++ if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode)) ++ sz = ia->ia_size; ++ ++ hi_wh = NULL; ++ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unhashed(dentry)) { ++ hi_wh = au_hi_wh(inode, a->btgt); ++ if (!hi_wh) { ++ err = au_sio_cpup_wh(dentry, a->btgt, sz, /*file*/NULL); ++ if (unlikely(err)) ++ goto out_unlock; ++ hi_wh = au_hi_wh(inode, a->btgt); ++ /* todo: revalidate hi_wh? */ ++ } ++ } ++ ++ if (parent) { ++ au_pin_set_parent_lflag(&a->pin, /*lflag*/0); ++ di_downgrade_lock(parent, AuLock_IR); ++ dput(parent); ++ } ++ if (!au_ftest_icpup(a->flags, DID_CPUP)) ++ goto out; /* success */ ++ ++ if (!d_unhashed(dentry)) { ++ err = au_sio_cpup_simple(dentry, a->btgt, sz, AuCpup_DTIME); ++ if (!err) ++ a->h_path.dentry = au_h_dptr(dentry, a->btgt); ++ } else if (!hi_wh) ++ a->h_path.dentry = au_h_dptr(dentry, a->btgt); ++ else ++ a->h_path.dentry = hi_wh; /* do not dget here */ ++ ++ out_unlock: ++ mutex_unlock(&a->h_inode->i_mutex); ++ a->h_inode = a->h_path.dentry->d_inode; ++ if (!err) { ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ goto out; /* success */ ++ } ++ ++ au_unpin(&a->pin); ++ ++ out_dentry: ++ di_write_unlock(dentry); ++ out: ++ return err; ++} ++ ++static int aufs_setattr(struct dentry *dentry, struct iattr *ia) ++{ ++ int err; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *file; ++ struct au_icpup_args *a; ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ file = NULL; ++ if (ia->ia_valid & ATTR_FILE) { ++ /* currently ftruncate(2) only */ ++ file = ia->ia_file; ++ fi_write_lock(file); ++ ia->ia_file = au_h_fptr(file, au_fbstart(file)); ++ } ++ ++ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) ++ ia->ia_valid &= ~ATTR_MODE; ++ ++ err = au_lock_and_icpup(dentry, ia, a); ++ if (unlikely(err < 0)) ++ goto out_si; ++ if (au_ftest_icpup(a->flags, DID_CPUP)) { ++ ia->ia_file = NULL; ++ ia->ia_valid &= ~ATTR_FILE; ++ } ++ ++ a->h_path.mnt = au_sbr_mnt(sb, a->btgt); ++ if (ia->ia_valid & ATTR_SIZE) { ++ struct file *f; ++ ++ if (ia->ia_size < i_size_read(inode)) { ++ /* unmap only */ ++ err = vmtruncate(inode, ia->ia_size); ++ if (unlikely(err)) ++ goto out_unlock; ++ } ++ ++ f = NULL; ++ if (ia->ia_valid & ATTR_FILE) ++ f = ia->ia_file; ++ mutex_unlock(&a->h_inode->i_mutex); ++ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f); ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ } else ++ err = vfsub_notify_change(&a->h_path, ia); ++ if (!err) ++ au_cpup_attr_changeable(inode); ++ ++ out_unlock: ++ mutex_unlock(&a->h_inode->i_mutex); ++ au_unpin(&a->pin); ++ di_write_unlock(dentry); ++ out_si: ++ if (file) { ++ fi_write_unlock(file); ++ ia->ia_file = file; ++ ia->ia_valid |= ATTR_FILE; ++ } ++ si_read_unlock(sb); ++ kfree(a); ++ out: ++ return err; ++} ++ ++static int au_getattr_lock_reval(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *parent; ++ ++ err = 0; ++ inode = dentry->d_inode; ++ di_write_lock_child(dentry); ++ if (au_digen(dentry) != sigen || au_iigen(inode) != sigen) { ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ /* returns a number of positive dentries */ ++ err = au_refresh_hdentry(dentry, inode->i_mode & S_IFMT); ++ if (err > 0) ++ err = au_refresh_hinode(inode, dentry); ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ if (unlikely(!err)) ++ err = -EIO; ++ } ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ di_read_unlock(dentry, AuLock_IR); ++ ++ return err; ++} ++ ++static void au_refresh_iattr(struct inode *inode, struct kstat *st, ++ unsigned int nlink) ++{ ++ inode->i_mode = st->mode; ++ inode->i_uid = st->uid; ++ inode->i_gid = st->gid; ++ inode->i_atime = st->atime; ++ inode->i_mtime = st->mtime; ++ inode->i_ctime = st->ctime; ++ ++ au_cpup_attr_nlink(inode, /*force*/0); ++ if (S_ISDIR(inode->i_mode)) { ++ inode->i_nlink -= nlink; ++ inode->i_nlink += st->nlink; ++ } ++ ++ spin_lock(&inode->i_lock); ++ inode->i_blocks = st->blocks; ++ i_size_write(inode, st->size); ++ spin_unlock(&inode->i_lock); ++} ++ ++static int aufs_getattr(struct vfsmount *mnt __maybe_unused, ++ struct dentry *dentry, struct kstat *st) ++{ ++ int err; ++ unsigned int mnt_flags; ++ aufs_bindex_t bindex; ++ unsigned char udba_none, positive; ++ struct super_block *sb, *h_sb; ++ struct inode *inode; ++ struct vfsmount *h_mnt; ++ struct dentry *h_dentry; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ si_read_lock(sb, AuLock_FLUSH); ++ mnt_flags = au_mntflags(sb); ++ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE); ++ ++ /* support fstat(2) */ ++ if (!d_unhashed(dentry) && !udba_none) { ++ unsigned int sigen = au_sigen(sb); ++ if (au_digen(dentry) == sigen && au_iigen(inode) == sigen) ++ di_read_lock_child(dentry, AuLock_IR); ++ else { ++ /* NFSD may skip the revalidation */ ++ if (!au_test_nfsd(current)) ++ AuDebugOn(!IS_ROOT(dentry)); ++ else { ++ err = au_busy_or_stale(); ++ if (unlikely(!IS_ROOT(dentry))) ++ goto out; ++ } ++ err = au_getattr_lock_reval(dentry, sigen); ++ if (unlikely(err)) ++ goto out; ++ } ++ } else ++ di_read_lock_child(dentry, AuLock_IR); ++ ++ bindex = au_ibstart(inode); ++ h_mnt = au_sbr_mnt(sb, bindex); ++ h_sb = h_mnt->mnt_sb; ++ if (!au_test_fs_bad_iattr(h_sb) && udba_none) ++ goto out_fill; /* success */ ++ ++ h_dentry = NULL; ++ if (au_dbstart(dentry) == bindex) ++ h_dentry = dget(au_h_dptr(dentry, bindex)); ++ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) { ++ h_dentry = au_plink_lkup(inode, bindex); ++ if (IS_ERR(h_dentry)) ++ goto out_fill; /* pretending success */ ++ } ++ /* illegally overlapped or something */ ++ if (unlikely(!h_dentry)) ++ goto out_fill; /* pretending success */ ++ ++ positive = !!h_dentry->d_inode; ++ if (positive) ++ err = vfs_getattr(h_mnt, h_dentry, st); ++ dput(h_dentry); ++ if (!err) { ++ if (positive) ++ au_refresh_iattr(inode, st, h_dentry->d_inode->i_nlink); ++ goto out_fill; /* success */ ++ } ++ goto out_unlock; ++ ++ out_fill: ++ generic_fillattr(inode, st); ++ out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int h_readlink(struct dentry *dentry, int bindex, char __user *buf, ++ int bufsiz) ++{ ++ int err; ++ struct super_block *sb; ++ struct dentry *h_dentry; ++ ++ err = -EINVAL; ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (unlikely(/* !h_dentry ++ || !h_dentry->d_inode ++ || !h_dentry->d_inode->i_op ++ || */ !h_dentry->d_inode->i_op->readlink)) ++ goto out; ++ ++ err = security_inode_readlink(h_dentry); ++ if (unlikely(err)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ if (!au_test_ro(sb, bindex, dentry->d_inode)) { ++ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry); ++ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode); ++ } ++ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz); ++ ++ out: ++ return err; ++} ++ ++static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) ++{ ++ int err; ++ ++ aufs_read_lock(dentry, AuLock_IR); ++ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz); ++ aufs_read_unlock(dentry, AuLock_IR); ++ ++ return err; ++} ++ ++static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd) ++{ ++ int err; ++ char *buf; ++ mm_segment_t old_fs; ++ ++ err = -ENOMEM; ++ buf = __getname(); ++ if (unlikely(!buf)) ++ goto out; ++ ++ aufs_read_lock(dentry, AuLock_IR); ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = h_readlink(dentry, au_dbstart(dentry), (char __user *)buf, ++ PATH_MAX); ++ set_fs(old_fs); ++ aufs_read_unlock(dentry, AuLock_IR); ++ ++ if (err >= 0) { ++ buf[err] = 0; ++ /* will be freed by put_link */ ++ nd_set_link(nd, buf); ++ return NULL; /* success */ ++ } ++ __putname(buf); ++ ++ out: ++ path_put(&nd->path); ++ AuTraceErr(err); ++ return ERR_PTR(err); ++} ++ ++static void aufs_put_link(struct dentry *dentry __maybe_unused, ++ struct nameidata *nd, void *cookie __maybe_unused) ++{ ++ __putname(nd_get_link(nd)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void aufs_truncate_range(struct inode *inode __maybe_unused, ++ loff_t start __maybe_unused, ++ loff_t end __maybe_unused) ++{ ++ AuUnsupport(); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct inode_operations aufs_symlink_iop = { ++ .permission = aufs_permission, ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr, ++ .readlink = aufs_readlink, ++ .follow_link = aufs_follow_link, ++ .put_link = aufs_put_link ++}; ++ ++struct inode_operations aufs_dir_iop = { ++ .create = aufs_create, ++ .lookup = aufs_lookup, ++ .link = aufs_link, ++ .unlink = aufs_unlink, ++ .symlink = aufs_symlink, ++ .mkdir = aufs_mkdir, ++ .rmdir = aufs_rmdir, ++ .mknod = aufs_mknod, ++ .rename = aufs_rename, ++ ++ .permission = aufs_permission, ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr ++}; ++ ++struct inode_operations aufs_iop = { ++ .permission = aufs_permission, ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr, ++ .truncate_range = aufs_truncate_range ++}; +diff -Nur linux-2.6.31-vanilla/fs/aufs/i_op_del.c linux-2.6.31/fs/aufs/i_op_del.c +--- linux-2.6.31-vanilla/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/i_op_del.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,468 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * inode operations (del entry) ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * decide if a new whiteout for @dentry is necessary or not. ++ * when it is necessary, prepare the parent dir for the upper branch whose ++ * branch index is @bcpup for creation. the actual creation of the whiteout will ++ * be done by caller. ++ * return value: ++ * 0: wh is unnecessary ++ * plus: wh is necessary ++ * minus: error ++ */ ++int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) ++{ ++ int need_wh, err; ++ aufs_bindex_t bstart; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ if (*bcpup < 0) { ++ *bcpup = bstart; ++ if (au_test_ro(sb, bstart, dentry->d_inode)) { ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ *bcpup = err; ++ if (unlikely(err < 0)) ++ goto out; ++ } ++ } else ++ AuDebugOn(bstart < *bcpup ++ || au_test_ro(sb, *bcpup, dentry->d_inode)); ++ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart); ++ ++ if (*bcpup != bstart) { ++ err = au_cpup_dirs(dentry, *bcpup); ++ if (unlikely(err)) ++ goto out; ++ need_wh = 1; ++ } else { ++ aufs_bindex_t old_bend, new_bend, bdiropq = -1; ++ ++ old_bend = au_dbend(dentry); ++ if (isdir) { ++ bdiropq = au_dbdiropq(dentry); ++ au_set_dbdiropq(dentry, -1); ++ } ++ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0, ++ /*nd*/NULL); ++ err = need_wh; ++ if (isdir) ++ au_set_dbdiropq(dentry, bdiropq); ++ if (unlikely(err < 0)) ++ goto out; ++ new_bend = au_dbend(dentry); ++ if (!need_wh && old_bend != new_bend) { ++ au_set_h_dptr(dentry, new_bend, NULL); ++ au_set_dbend(dentry, old_bend); ++ } ++ } ++ AuDbg("need_wh %d\n", need_wh); ++ err = need_wh; ++ ++ out: ++ return err; ++} ++ ++/* ++ * simple tests for the del-entry operations. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir) ++{ ++ int err; ++ umode_t h_mode; ++ struct dentry *h_dentry, *h_latest; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ h_inode = h_dentry->d_inode; ++ if (dentry->d_inode) { ++ err = -ENOENT; ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ ++ h_mode = h_inode->i_mode; ++ if (!isdir) { ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(h_mode))) ++ goto out; ++ } else if (unlikely(!S_ISDIR(h_mode))) { ++ err = -ENOTDIR; ++ goto out; ++ } ++ } else { ++ /* rename(2) case */ ++ err = -EIO; ++ if (unlikely(h_inode)) ++ goto out; ++ } ++ ++ err = -ENOENT; ++ /* expected parent dir is locked */ ++ if (unlikely(h_parent != h_dentry->d_parent)) ++ goto out; ++ err = 0; ++ ++ /* ++ * rmdir a dir may break the consistency on some filesystem. ++ * let's try heavy test. ++ */ ++ err = -EACCES; ++ if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE))) ++ goto out; ++ ++ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent, ++ au_sbr(dentry->d_sb, bindex)); ++ err = -EIO; ++ if (IS_ERR(h_latest)) ++ goto out; ++ if (h_latest == h_dentry) ++ err = 0; ++ dput(h_latest); ++ ++ out: ++ return err; ++} ++ ++/* ++ * decide the branch where we operate for @dentry. the branch index will be set ++ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent ++ * dir for reverting. ++ * when a new whiteout is necessary, create it. ++ */ ++static struct dentry* ++lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup, ++ struct au_dtime *dt, struct au_pin *pin) ++{ ++ struct dentry *wh_dentry; ++ struct super_block *sb; ++ struct path h_path; ++ int err, need_wh; ++ unsigned int udba; ++ aufs_bindex_t bcpup; ++ ++ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup); ++ wh_dentry = ERR_PTR(need_wh); ++ if (unlikely(need_wh < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ udba = au_opt_udba(sb); ++ bcpup = *rbcpup; ++ err = au_pin(pin, dentry, bcpup, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ h_path.dentry = au_pinned_h_parent(pin); ++ if (udba != AuOpt_UDBA_NONE ++ && au_dbstart(dentry) == bcpup) { ++ err = au_may_del(dentry, bcpup, h_path.dentry, isdir); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_unpin; ++ } ++ ++ h_path.mnt = au_sbr_mnt(sb, bcpup); ++ au_dtime_store(dt, au_pinned_parent(pin), &h_path); ++ wh_dentry = NULL; ++ if (!need_wh) ++ goto out; /* success, no need to create whiteout */ ++ ++ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry); ++ if (!IS_ERR(wh_dentry)) ++ goto out; /* success */ ++ /* returns with the parent is locked and wh_dentry is dget-ed */ ++ ++ out_unpin: ++ au_unpin(pin); ++ out: ++ return wh_dentry; ++} ++ ++/* ++ * when removing a dir, rename it to a unique temporary whiteout-ed name first ++ * in order to be revertible and save time for removing many child whiteouts ++ * under the dir. ++ * returns 1 when there are too many child whiteout and caller should remove ++ * them asynchronously. returns 0 when the number of children is enough small to ++ * remove now or the branch fs is a remote fs. ++ * otherwise return an error. ++ */ ++static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex, ++ struct au_nhash *whlist, struct inode *dir) ++{ ++ int rmdir_later, err, dirwh; ++ struct dentry *h_dentry; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ SiMustAnyLock(sb); ++ h_dentry = au_h_dptr(dentry, bindex); ++ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex)); ++ if (unlikely(err)) ++ goto out; ++ ++ /* stop monitoring */ ++ au_hin_free(au_hi(dentry->d_inode, bindex)); ++ ++ if (!au_test_fs_remote(h_dentry->d_sb)) { ++ dirwh = au_sbi(sb)->si_dirwh; ++ rmdir_later = (dirwh <= 1); ++ if (!rmdir_later) ++ rmdir_later = au_nhash_test_longer_wh(whlist, bindex, ++ dirwh); ++ if (rmdir_later) ++ return rmdir_later; ++ } ++ ++ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist); ++ if (unlikely(err)) { ++ AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n", ++ AuDLNPair(h_dentry), bindex, err); ++ err = 0; ++ } ++ ++ out: ++ return err; ++} ++ ++/* ++ * final procedure for deleting a entry. ++ * maintain dentry and iattr. ++ */ ++static void epilog(struct inode *dir, struct dentry *dentry, ++ aufs_bindex_t bindex) ++{ ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ d_drop(dentry); ++ inode->i_ctime = dir->i_ctime; ++ ++ if (atomic_read(&dentry->d_count) == 1) { ++ au_set_h_dptr(dentry, au_dbstart(dentry), NULL); ++ au_update_dbstart(dentry); ++ } ++ if (au_ibstart(dir) == bindex) ++ au_cpup_attr_timesizes(dir); ++ dir->i_version++; ++} ++ ++/* ++ * when an error happened, remove the created whiteout and revert everything. ++ */ ++static int do_revert(int err, struct inode *dir, aufs_bindex_t bwh, ++ struct dentry *wh_dentry, struct dentry *dentry, ++ struct au_dtime *dt) ++{ ++ int rerr; ++ struct path h_path = { ++ .dentry = wh_dentry, ++ .mnt = au_sbr_mnt(dir->i_sb, bwh) ++ }; ++ ++ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bwh), &h_path, dentry); ++ if (!rerr) { ++ au_set_dbwh(dentry, bwh); ++ au_dtime_revert(dt); ++ return 0; ++ } ++ ++ AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", ++ AuDLNPair(dentry), err, rerr); ++ return -EIO; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int aufs_unlink(struct inode *dir, struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bwh, bindex, bstart; ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ struct inode *inode, *h_dir; ++ struct dentry *parent, *wh_dentry; ++ ++ IMustLock(dir); ++ inode = dentry->d_inode; ++ if (unlikely(!inode)) ++ return -ENOENT; /* possible? */ ++ IMustLock(inode); ++ ++ aufs_read_lock(dentry, AuLock_DW); ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ ++ bstart = au_dbstart(dentry); ++ bwh = au_dbwh(dentry); ++ bindex = -1; ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ h_path.dentry = au_h_dptr(dentry, bstart); ++ dget(h_path.dentry); ++ if (bindex == bstart) { ++ h_dir = au_pinned_h_dir(&pin); ++ err = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ } else { ++ /* dir inode is locked */ ++ h_dir = wh_dentry->d_parent->d_inode; ++ IMustLock(h_dir); ++ err = 0; ++ } ++ ++ if (!err) { ++ drop_nlink(inode); ++ epilog(dir, dentry, bindex); ++ ++ /* update target timestamps */ ++ if (bindex == bstart) { ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++ inode->i_ctime = h_path.dentry->d_inode->i_ctime; ++ } else ++ /* todo: this timestamp may be reverted later */ ++ inode->i_ctime = h_dir->i_ctime; ++ goto out_unlock; /* success */ ++ } ++ ++ /* revert */ ++ if (wh_dentry) { ++ int rerr; ++ ++ rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt); ++ if (rerr) ++ err = rerr; ++ } ++ ++ out_unlock: ++ au_unpin(&pin); ++ dput(wh_dentry); ++ dput(h_path.dentry); ++ out: ++ di_write_unlock(parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++ return err; ++} ++ ++int aufs_rmdir(struct inode *dir, struct dentry *dentry) ++{ ++ int err, rmdir_later; ++ aufs_bindex_t bwh, bindex, bstart; ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct inode *inode; ++ struct dentry *parent, *wh_dentry, *h_dentry; ++ struct au_whtmp_rmdir *args; ++ ++ IMustLock(dir); ++ inode = dentry->d_inode; ++ err = -ENOENT; /* possible? */ ++ if (unlikely(!inode)) ++ goto out; ++ IMustLock(inode); ++ ++ aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH); ++ err = -ENOMEM; ++ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS); ++ if (unlikely(!args)) ++ goto out_unlock; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ err = au_test_empty(dentry, &args->whlist); ++ if (unlikely(err)) ++ goto out_args; ++ ++ bstart = au_dbstart(dentry); ++ bwh = au_dbwh(dentry); ++ bindex = -1; ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_args; ++ ++ h_dentry = au_h_dptr(dentry, bstart); ++ dget(h_dentry); ++ rmdir_later = 0; ++ if (bindex == bstart) { ++ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir); ++ if (err > 0) { ++ rmdir_later = err; ++ err = 0; ++ } ++ } else { ++ /* stop monitoring */ ++ au_hin_free(au_hi(inode, bstart)); ++ ++ /* dir inode is locked */ ++ IMustLock(wh_dentry->d_parent->d_inode); ++ err = 0; ++ } ++ ++ if (!err) { ++ clear_nlink(inode); ++ au_set_dbdiropq(dentry, -1); ++ epilog(dir, dentry, bindex); ++ ++ if (rmdir_later) { ++ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args); ++ args = NULL; ++ } ++ ++ goto out_unpin; /* success */ ++ } ++ ++ /* revert */ ++ AuLabel(revert); ++ if (wh_dentry) { ++ int rerr; ++ ++ rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt); ++ if (rerr) ++ err = rerr; ++ } ++ ++ out_unpin: ++ au_unpin(&pin); ++ dput(wh_dentry); ++ dput(h_dentry); ++ out_args: ++ di_write_unlock(parent); ++ if (args) ++ au_whtmp_rmdir_free(args); ++ out_unlock: ++ aufs_read_unlock(dentry, AuLock_DW); ++ out: ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/i_op_ren.c linux-2.6.31/fs/aufs/i_op_ren.c +--- linux-2.6.31-vanilla/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/i_op_ren.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,957 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * inode operation (rename entry) ++ * todo: this is crazy monster ++ */ ++ ++#include "aufs.h" ++ ++enum { AuSRC, AuDST, AuSrcDst }; ++enum { AuPARENT, AuCHILD, AuParentChild }; ++ ++#define AuRen_ISDIR 1 ++#define AuRen_ISSAMEDIR (1 << 1) ++#define AuRen_WHSRC (1 << 2) ++#define AuRen_WHDST (1 << 3) ++#define AuRen_MNT_WRITE (1 << 4) ++#define AuRen_DT_DSTDIR (1 << 5) ++#define AuRen_DIROPQ (1 << 6) ++#define AuRen_CPUP (1 << 7) ++#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) ++#define au_fset_ren(flags, name) { (flags) |= AuRen_##name; } ++#define au_fclr_ren(flags, name) { (flags) &= ~AuRen_##name; } ++ ++struct au_ren_args { ++ struct { ++ struct dentry *dentry, *h_dentry, *parent, *h_parent, ++ *wh_dentry; ++ struct inode *dir, *inode; ++ struct au_hinode *hdir; ++ struct au_dtime dt[AuParentChild]; ++ aufs_bindex_t bstart; ++ } sd[AuSrcDst]; ++ ++#define src_dentry sd[AuSRC].dentry ++#define src_dir sd[AuSRC].dir ++#define src_inode sd[AuSRC].inode ++#define src_h_dentry sd[AuSRC].h_dentry ++#define src_parent sd[AuSRC].parent ++#define src_h_parent sd[AuSRC].h_parent ++#define src_wh_dentry sd[AuSRC].wh_dentry ++#define src_hdir sd[AuSRC].hdir ++#define src_h_dir sd[AuSRC].hdir->hi_inode ++#define src_dt sd[AuSRC].dt ++#define src_bstart sd[AuSRC].bstart ++ ++#define dst_dentry sd[AuDST].dentry ++#define dst_dir sd[AuDST].dir ++#define dst_inode sd[AuDST].inode ++#define dst_h_dentry sd[AuDST].h_dentry ++#define dst_parent sd[AuDST].parent ++#define dst_h_parent sd[AuDST].h_parent ++#define dst_wh_dentry sd[AuDST].wh_dentry ++#define dst_hdir sd[AuDST].hdir ++#define dst_h_dir sd[AuDST].hdir->hi_inode ++#define dst_dt sd[AuDST].dt ++#define dst_bstart sd[AuDST].bstart ++ ++ struct dentry *h_trap; ++ struct au_branch *br; ++ struct au_hinode *src_hinode; ++ struct path h_path; ++ struct au_nhash whlist; ++ aufs_bindex_t btgt; ++ ++ unsigned int flags; ++ ++ struct au_whtmp_rmdir *thargs; ++ struct dentry *h_dst; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * functions for reverting. ++ * when an error happened in a single rename systemcall, we should revert ++ * everything as if nothing happend. ++ * we don't need to revert the copied-up/down the parent dir since they are ++ * harmless. ++ */ ++ ++#define RevertFailure(fmt, args...) do { \ ++ AuIOErr("revert failure: " fmt " (%d, %d)\n", \ ++ ##args, err, rerr); \ ++ err = -EIO; \ ++} while (0) ++ ++static void au_ren_rev_diropq(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(a->src_dentry, a->btgt); ++ au_hin_imtx_unlock(a->src_hinode); ++ if (rerr) ++ RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry)); ++} ++ ++ ++static void au_ren_rev_rename(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = au_lkup_one(&a->src_dentry->d_name, a->src_h_parent, ++ a->br, /*nd*/NULL); ++ rerr = PTR_ERR(a->h_path.dentry); ++ if (IS_ERR(a->h_path.dentry)) { ++ RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry)); ++ return; ++ } ++ ++ rerr = vfsub_rename(a->dst_h_dir, ++ au_h_dptr(a->src_dentry, a->btgt), ++ a->src_h_dir, &a->h_path); ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ ++ if (rerr) ++ RevertFailure("rename %.*s", AuDLNPair(a->src_dentry)); ++} ++ ++static void au_ren_rev_cpup(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = a->dst_h_dentry; ++ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*force*/0); ++ au_set_h_dptr(a->src_dentry, a->btgt, NULL); ++ au_set_dbstart(a->src_dentry, a->src_bstart); ++ if (rerr) ++ RevertFailure("unlink %.*s", AuDLNPair(a->dst_h_dentry)); ++} ++ ++ ++static void au_ren_rev_whtmp(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = au_lkup_one(&a->dst_dentry->d_name, a->dst_h_parent, ++ a->br, /*nd*/NULL); ++ rerr = PTR_ERR(a->h_path.dentry); ++ if (IS_ERR(a->h_path.dentry)) { ++ RevertFailure("lookup %.*s", AuDLNPair(a->dst_dentry)); ++ return; ++ } ++ if (a->h_path.dentry->d_inode) { ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ return; ++ } ++ ++ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path); ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ if (!rerr) { ++ au_set_h_dptr(a->dst_dentry, a->btgt, NULL); ++ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst)); ++ } else ++ RevertFailure("rename %.*s", AuDLNPair(a->h_dst)); ++} ++ ++static void au_ren_rev_whsrc(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = a->src_wh_dentry; ++ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry); ++ if (rerr) ++ RevertFailure("unlink %.*s", AuDLNPair(a->src_wh_dentry)); ++} ++ ++static void au_ren_rev_drop(struct au_ren_args *a) ++{ ++ struct dentry *d, *h_d; ++ int i; ++ aufs_bindex_t bend, bindex; ++ ++ for (i = 0; i < AuSrcDst; i++) { ++ d = a->sd[i].dentry; ++ d_drop(d); ++ bend = au_dbend(d); ++ for (bindex = au_dbstart(d); bindex <= bend; bindex++) { ++ h_d = au_h_dptr(d, bindex); ++ if (h_d) ++ d_drop(h_d); ++ } ++ } ++ ++ au_update_dbstart(a->dst_dentry); ++ if (a->thargs) ++ d_drop(a->h_dst); ++} ++#undef RevertFailure ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * when we have to copyup the renaming entry, do it with the rename-target name ++ * in order to minimize the cost (the later actual rename is unnecessary). ++ * otherwise rename it on the target branch. ++ */ ++static int au_ren_or_cpup(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *d; ++ ++ d = a->src_dentry; ++ if (au_dbstart(d) == a->btgt) { ++ a->h_path.dentry = a->dst_h_dentry; ++ if (au_ftest_ren(a->flags, DIROPQ) ++ && au_dbdiropq(d) == a->btgt) ++ au_fclr_ren(a->flags, DIROPQ); ++ AuDebugOn(au_dbstart(d) != a->btgt); ++ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt), ++ a->dst_h_dir, &a->h_path); ++ } else { ++ struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex; ++ ++ au_fset_ren(a->flags, CPUP); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_set_dbstart(d, a->btgt); ++ au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry)); ++ err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1, ++ !AuCpup_DTIME, a->dst_parent); ++ if (unlikely(err)) { ++ au_set_h_dptr(d, a->btgt, NULL); ++ au_set_dbstart(d, a->src_bstart); ++ } ++ mutex_unlock(h_mtx); ++ } ++ ++ return err; ++} ++ ++/* cf. aufs_rmdir() */ ++static int au_ren_del_whtmp(struct au_ren_args *a) ++{ ++ int err; ++ struct inode *dir; ++ ++ dir = a->dst_dir; ++ SiMustAnyLock(dir->i_sb); ++ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt, ++ au_sbi(dir->i_sb)->si_dirwh) ++ || au_test_fs_remote(a->h_dst->d_sb)) { ++ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist); ++ if (unlikely(err)) ++ AuWarn("failed removing whtmp dir %.*s (%d), " ++ "ignored.\n", AuDLNPair(a->h_dst), err); ++ } else { ++ au_nhash_wh_free(&a->thargs->whlist); ++ a->thargs->whlist = a->whlist; ++ a->whlist.nh_num = 0; ++ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs); ++ dput(a->h_dst); ++ a->thargs = NULL; ++ } ++ ++ return 0; ++} ++ ++/* make it 'opaque' dir. */ ++static int au_ren_diropq(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *diropq; ++ ++ err = 0; ++ a->src_hinode = au_hi(a->src_inode, a->btgt); ++ au_hin_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD); ++ diropq = au_diropq_create(a->src_dentry, a->btgt); ++ au_hin_imtx_unlock(a->src_hinode); ++ if (IS_ERR(diropq)) ++ err = PTR_ERR(diropq); ++ dput(diropq); ++ ++ return err; ++} ++ ++static int do_rename(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *d, *h_d; ++ ++ /* prepare workqueue args for asynchronous rmdir */ ++ h_d = a->dst_h_dentry; ++ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) { ++ err = -ENOMEM; ++ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS); ++ if (unlikely(!a->thargs)) ++ goto out; ++ a->h_dst = dget(h_d); ++ } ++ ++ /* create whiteout for src_dentry */ ++ if (au_ftest_ren(a->flags, WHSRC)) { ++ a->src_wh_dentry ++ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent); ++ err = PTR_ERR(a->src_wh_dentry); ++ if (IS_ERR(a->src_wh_dentry)) ++ goto out_thargs; ++ } ++ ++ /* lookup whiteout for dentry */ ++ if (au_ftest_ren(a->flags, WHDST)) { ++ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name, ++ a->br); ++ err = PTR_ERR(h_d); ++ if (IS_ERR(h_d)) ++ goto out_whsrc; ++ if (!h_d->d_inode) ++ dput(h_d); ++ else ++ a->dst_wh_dentry = h_d; ++ } ++ ++ /* rename dentry to tmpwh */ ++ if (a->thargs) { ++ err = au_whtmp_ren(a->dst_h_dentry, a->br); ++ if (unlikely(err)) ++ goto out_whdst; ++ ++ d = a->dst_dentry; ++ au_set_h_dptr(d, a->btgt, NULL); ++ err = au_lkup_neg(d, a->btgt); ++ if (unlikely(err)) ++ goto out_whtmp; ++ a->dst_h_dentry = au_h_dptr(d, a->btgt); ++ } ++ ++ /* cpup src */ ++ if (a->dst_h_dentry->d_inode && a->src_bstart != a->btgt) { ++ struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex; ++ ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1, ++ !AuCpup_DTIME); ++ mutex_unlock(h_mtx); ++ if (unlikely(err)) ++ goto out_whtmp; ++ } ++ ++ /* rename by vfs_rename or cpup */ ++ d = a->dst_dentry; ++ if (au_ftest_ren(a->flags, ISDIR) ++ && (a->dst_wh_dentry ++ || au_dbdiropq(d) == a->btgt ++ /* hide the lower to keep xino */ ++ || a->btgt < au_dbend(d) ++ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ))) ++ au_fset_ren(a->flags, DIROPQ); ++ err = au_ren_or_cpup(a); ++ if (unlikely(err)) ++ /* leave the copied-up one */ ++ goto out_whtmp; ++ ++ /* make dir opaque */ ++ if (au_ftest_ren(a->flags, DIROPQ)) { ++ err = au_ren_diropq(a); ++ if (unlikely(err)) ++ goto out_rename; ++ } ++ ++ /* update target timestamps */ ++ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt); ++ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt); ++ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ ++ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime; ++ ++ /* remove whiteout for dentry */ ++ if (a->dst_wh_dentry) { ++ a->h_path.dentry = a->dst_wh_dentry; ++ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path, ++ a->dst_dentry); ++ if (unlikely(err)) ++ goto out_diropq; ++ } ++ ++ /* remove whtmp */ ++ if (a->thargs) ++ au_ren_del_whtmp(a); /* ignore this error */ ++ ++ err = 0; ++ goto out_success; ++ ++ out_diropq: ++ if (au_ftest_ren(a->flags, DIROPQ)) ++ au_ren_rev_diropq(err, a); ++ out_rename: ++ if (!au_ftest_ren(a->flags, CPUP)) ++ au_ren_rev_rename(err, a); ++ else ++ au_ren_rev_cpup(err, a); ++ out_whtmp: ++ if (a->thargs) ++ au_ren_rev_whtmp(err, a); ++ out_whdst: ++ dput(a->dst_wh_dentry); ++ a->dst_wh_dentry = NULL; ++ out_whsrc: ++ if (a->src_wh_dentry) ++ au_ren_rev_whsrc(err, a); ++ au_ren_rev_drop(a); ++ out_success: ++ dput(a->src_wh_dentry); ++ dput(a->dst_wh_dentry); ++ out_thargs: ++ if (a->thargs) { ++ dput(a->h_dst); ++ au_whtmp_rmdir_free(a->thargs); ++ a->thargs = NULL; ++ } ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * test if @dentry dir can be rename destination or not. ++ * success means, it is a logically empty dir. ++ */ ++static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist) ++{ ++ return au_test_empty(dentry, whlist); ++} ++ ++/* ++ * test if @dentry dir can be rename source or not. ++ * if it can, return 0 and @children is filled. ++ * success means, ++ * - it is a logically empty dir. ++ * - or, it exists on writable branch and has no children including whiteouts ++ * on the lower branch. ++ */ ++static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt) ++{ ++ int err; ++ unsigned int rdhash; ++ aufs_bindex_t bstart; ++ ++ bstart = au_dbstart(dentry); ++ if (bstart != btgt) { ++ struct au_nhash whlist; ++ ++ SiMustAnyLock(dentry->d_sb); ++ rdhash = au_sbi(dentry->d_sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, ++ dentry)); ++ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_test_empty(dentry, &whlist); ++ au_nhash_wh_free(&whlist); ++ goto out; ++ } ++ ++ if (bstart == au_dbtaildir(dentry)) ++ return 0; /* success */ ++ ++ err = au_test_empty_lower(dentry); ++ ++ out: ++ if (err == -ENOTEMPTY) { ++ AuWarn1("renaming dir who has child(ren) on multiple branches," ++ " is not supported\n"); ++ err = -EXDEV; ++ } ++ return err; ++} ++ ++/* side effect: sets whlist and h_dentry */ ++static int au_ren_may_dir(struct au_ren_args *a) ++{ ++ int err; ++ unsigned int rdhash; ++ struct dentry *d; ++ ++ d = a->dst_dentry; ++ SiMustAnyLock(d->d_sb); ++ ++ err = 0; ++ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) { ++ rdhash = au_sbi(d->d_sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d)); ++ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ ++ au_set_dbstart(d, a->dst_bstart); ++ err = may_rename_dstdir(d, &a->whlist); ++ au_set_dbstart(d, a->btgt); ++ } ++ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d)); ++ if (unlikely(err)) ++ goto out; ++ ++ d = a->src_dentry; ++ a->src_h_dentry = au_h_dptr(d, au_dbstart(d)); ++ if (au_ftest_ren(a->flags, ISDIR)) { ++ err = may_rename_srcdir(d, a->btgt); ++ if (unlikely(err)) { ++ au_nhash_wh_free(&a->whlist); ++ a->whlist.nh_num = 0; ++ } ++ } ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * simple tests for rename. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++static int au_may_ren(struct au_ren_args *a) ++{ ++ int err, isdir; ++ struct inode *h_inode; ++ ++ if (a->src_bstart == a->btgt) { ++ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent, ++ au_ftest_ren(a->flags, ISDIR)); ++ if (unlikely(err)) ++ goto out; ++ err = -EINVAL; ++ if (unlikely(a->src_h_dentry == a->h_trap)) ++ goto out; ++ } ++ ++ err = 0; ++ if (a->dst_bstart != a->btgt) ++ goto out; ++ ++ err = -EIO; ++ h_inode = a->dst_h_dentry->d_inode; ++ isdir = !!au_ftest_ren(a->flags, ISDIR); ++ if (!a->dst_dentry->d_inode) { ++ if (unlikely(h_inode)) ++ goto out; ++ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent, ++ isdir); ++ } else { ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent, ++ isdir); ++ if (unlikely(err)) ++ goto out; ++ err = -ENOTEMPTY; ++ if (unlikely(a->dst_h_dentry == a->h_trap)) ++ goto out; ++ err = 0; ++ } ++ ++ out: ++ if (unlikely(err == -ENOENT || err == -EEXIST)) ++ err = -EIO; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * locking order ++ * (VFS) ++ * - src_dir and dir by lock_rename() ++ * - inode if exitsts ++ * (aufs) ++ * - lock all ++ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, ++ * + si_read_lock ++ * + di_write_lock2_child() ++ * + di_write_lock_child() ++ * + ii_write_lock_child() ++ * + di_write_lock_child2() ++ * + ii_write_lock_child2() ++ * + src_parent and parent ++ * + di_write_lock_parent() ++ * + ii_write_lock_parent() ++ * + di_write_lock_parent2() ++ * + ii_write_lock_parent2() ++ * + lower src_dir and dir by vfsub_lock_rename() ++ * + verify the every relationships between child and parent. if any ++ * of them failed, unlock all and return -EBUSY. ++ */ ++static void au_ren_unlock(struct au_ren_args *a) ++{ ++ struct super_block *sb; ++ ++ sb = a->dst_dentry->d_sb; ++ if (au_ftest_ren(a->flags, MNT_WRITE)) ++ mnt_drop_write(a->br->br_mnt); ++ vfsub_unlock_rename(a->src_h_parent, a->src_hdir, ++ a->dst_h_parent, a->dst_hdir); ++} ++ ++static int au_ren_lock(struct au_ren_args *a) ++{ ++ int err; ++ unsigned int udba; ++ ++ err = 0; ++ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt); ++ a->src_hdir = au_hi(a->src_dir, a->btgt); ++ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt); ++ a->dst_hdir = au_hi(a->dst_dir, a->btgt); ++ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir, ++ a->dst_h_parent, a->dst_hdir); ++ udba = au_opt_udba(a->src_dentry->d_sb); ++ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode ++ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode)) ++ err = au_busy_or_stale(); ++ if (!err && au_dbstart(a->src_dentry) == a->btgt) ++ err = au_h_verify(a->src_h_dentry, udba, ++ a->src_h_parent->d_inode, a->src_h_parent, ++ a->br); ++ if (!err && au_dbstart(a->dst_dentry) == a->btgt) ++ err = au_h_verify(a->dst_h_dentry, udba, ++ a->dst_h_parent->d_inode, a->dst_h_parent, ++ a->br); ++ if (!err) { ++ err = mnt_want_write(a->br->br_mnt); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_fset_ren(a->flags, MNT_WRITE); ++ goto out; /* success */ ++ } ++ ++ err = au_busy_or_stale(); ++ ++ out_unlock: ++ au_ren_unlock(a); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_ren_refresh_dir(struct au_ren_args *a) ++{ ++ struct inode *dir; ++ ++ dir = a->dst_dir; ++ dir->i_version++; ++ if (au_ftest_ren(a->flags, ISDIR)) { ++ /* is this updating defined in POSIX? */ ++ au_cpup_attr_timesizes(a->src_inode); ++ au_cpup_attr_nlink(dir, /*force*/1); ++ if (a->dst_inode) { ++ clear_nlink(a->dst_inode); ++ au_cpup_attr_timesizes(a->dst_inode); ++ } ++ } ++ if (au_ibstart(dir) == a->btgt) ++ au_cpup_attr_timesizes(dir); ++ ++ if (au_ftest_ren(a->flags, ISSAMEDIR)) ++ return; ++ ++ dir = a->src_dir; ++ dir->i_version++; ++ if (au_ftest_ren(a->flags, ISDIR)) ++ au_cpup_attr_nlink(dir, /*force*/1); ++ if (au_ibstart(dir) == a->btgt) ++ au_cpup_attr_timesizes(dir); ++} ++ ++static void au_ren_refresh(struct au_ren_args *a) ++{ ++ aufs_bindex_t bend, bindex; ++ struct dentry *d, *h_d; ++ struct inode *i, *h_i; ++ struct super_block *sb; ++ ++ d = a->src_dentry; ++ au_set_dbwh(d, -1); ++ bend = au_dbend(d); ++ for (bindex = a->btgt + 1; bindex <= bend; bindex++) { ++ h_d = au_h_dptr(d, bindex); ++ if (h_d) ++ au_set_h_dptr(d, bindex, NULL); ++ } ++ au_set_dbend(d, a->btgt); ++ ++ sb = d->d_sb; ++ i = a->src_inode; ++ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i)) ++ return; /* success */ ++ ++ bend = au_ibend(i); ++ for (bindex = a->btgt + 1; bindex <= bend; bindex++) { ++ h_i = au_h_iptr(i, bindex); ++ if (h_i) { ++ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0); ++ /* ignore this error */ ++ au_set_h_iptr(i, bindex, NULL, 0); ++ } ++ } ++ au_set_ibend(i, a->btgt); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* mainly for link(2) and rename(2) */ ++int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) ++{ ++ aufs_bindex_t bdiropq, bwh; ++ struct dentry *parent; ++ struct au_branch *br; ++ ++ parent = dentry->d_parent; ++ IMustLock(parent->d_inode); /* dir is locked */ ++ ++ bdiropq = au_dbdiropq(parent); ++ bwh = au_dbwh(dentry); ++ br = au_sbr(dentry->d_sb, btgt); ++ if (au_br_rdonly(br) ++ || (0 <= bdiropq && bdiropq < btgt) ++ || (0 <= bwh && bwh < btgt)) ++ btgt = -1; ++ ++ AuDbg("btgt %d\n", btgt); ++ return btgt; ++} ++ ++/* sets src_bstart, dst_bstart and btgt */ ++static int au_ren_wbr(struct au_ren_args *a) ++{ ++ int err; ++ struct au_wr_dir_args wr_dir_args = { ++ /* .force_btgt = -1, */ ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ a->src_bstart = au_dbstart(a->src_dentry); ++ a->dst_bstart = au_dbstart(a->dst_dentry); ++ if (au_ftest_ren(a->flags, ISDIR)) ++ au_fset_wrdir(wr_dir_args.flags, ISDIR); ++ wr_dir_args.force_btgt = a->src_bstart; ++ if (a->dst_inode && a->dst_bstart < a->src_bstart) ++ wr_dir_args.force_btgt = a->dst_bstart; ++ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt); ++ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args); ++ a->btgt = err; ++ ++ return err; ++} ++ ++static void au_ren_dt(struct au_ren_args *a) ++{ ++ a->h_path.dentry = a->src_h_parent; ++ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path); ++ if (!au_ftest_ren(a->flags, ISSAMEDIR)) { ++ a->h_path.dentry = a->dst_h_parent; ++ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path); ++ } ++ ++ au_fclr_ren(a->flags, DT_DSTDIR); ++ if (!au_ftest_ren(a->flags, ISDIR)) ++ return; ++ ++ a->h_path.dentry = a->src_h_dentry; ++ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path); ++ if (a->dst_h_dentry->d_inode) { ++ au_fset_ren(a->flags, DT_DSTDIR); ++ a->h_path.dentry = a->dst_h_dentry; ++ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path); ++ } ++} ++ ++static void au_ren_rev_dt(int err, struct au_ren_args *a) ++{ ++ struct dentry *h_d; ++ struct mutex *h_mtx; ++ ++ au_dtime_revert(a->src_dt + AuPARENT); ++ if (!au_ftest_ren(a->flags, ISSAMEDIR)) ++ au_dtime_revert(a->dst_dt + AuPARENT); ++ ++ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) { ++ h_d = a->src_dt[AuCHILD].dt_h_path.dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_dtime_revert(a->src_dt + AuCHILD); ++ mutex_unlock(h_mtx); ++ ++ if (au_ftest_ren(a->flags, DT_DSTDIR)) { ++ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_dtime_revert(a->dst_dt + AuCHILD); ++ mutex_unlock(h_mtx); ++ } ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry, ++ struct inode *_dst_dir, struct dentry *_dst_dentry) ++{ ++ int err; ++ /* reduce stack space */ ++ struct au_ren_args *a; ++ ++ IMustLock(_src_dir); ++ IMustLock(_dst_dir); ++ ++ err = -ENOMEM; ++ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE); ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ a->src_dir = _src_dir; ++ a->src_dentry = _src_dentry; ++ a->src_inode = a->src_dentry->d_inode; ++ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */ ++ a->dst_dir = _dst_dir; ++ a->dst_dentry = _dst_dentry; ++ a->dst_inode = a->dst_dentry->d_inode; ++ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */ ++ if (a->dst_inode) { ++ IMustLock(a->dst_inode); ++ au_igrab(a->dst_inode); ++ } ++ ++ err = -ENOTDIR; ++ if (S_ISDIR(a->src_inode->i_mode)) { ++ au_fset_ren(a->flags, ISDIR); ++ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode))) ++ goto out_free; ++ aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, ++ AuLock_DIR | AuLock_FLUSH); ++ } else ++ aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, ++ AuLock_FLUSH); ++ ++ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */ ++ di_write_lock_parent(a->dst_parent); ++ ++ /* which branch we process */ ++ err = au_ren_wbr(a); ++ if (unlikely(err < 0)) ++ goto out_unlock; ++ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt); ++ a->h_path.mnt = a->br->br_mnt; ++ ++ /* are they available to be renamed */ ++ err = au_ren_may_dir(a); ++ if (unlikely(err)) ++ goto out_children; ++ ++ /* prepare the writable parent dir on the same branch */ ++ if (a->dst_bstart == a->btgt) { ++ au_fset_ren(a->flags, WHDST); ++ } else { ++ err = au_cpup_dirs(a->dst_dentry, a->btgt); ++ if (unlikely(err)) ++ goto out_children; ++ } ++ ++ if (a->src_dir != a->dst_dir) { ++ /* ++ * this temporary unlock is safe, ++ * because both dir->i_mutex are locked. ++ */ ++ di_write_unlock(a->dst_parent); ++ di_write_lock_parent(a->src_parent); ++ err = au_wr_dir_need_wh(a->src_dentry, ++ au_ftest_ren(a->flags, ISDIR), ++ &a->btgt); ++ di_write_unlock(a->src_parent); ++ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1); ++ au_fclr_ren(a->flags, ISSAMEDIR); ++ } else ++ err = au_wr_dir_need_wh(a->src_dentry, ++ au_ftest_ren(a->flags, ISDIR), ++ &a->btgt); ++ if (unlikely(err < 0)) ++ goto out_children; ++ if (err) ++ au_fset_ren(a->flags, WHSRC); ++ ++ /* lock them all */ ++ err = au_ren_lock(a); ++ if (unlikely(err)) ++ goto out_children; ++ ++ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) { ++ err = au_may_ren(a); ++ if (unlikely(err)) ++ goto out_hdir; ++ } ++ ++ /* store timestamps to be revertible */ ++ au_ren_dt(a); ++ ++ /* here we go */ ++ err = do_rename(a); ++ if (unlikely(err)) ++ goto out_dt; ++ ++ /* update dir attributes */ ++ au_ren_refresh_dir(a); ++ ++ /* dput/iput all lower dentries */ ++ au_ren_refresh(a); ++ ++ goto out_hdir; /* success */ ++ ++ out_dt: ++ au_ren_rev_dt(err, a); ++ out_hdir: ++ au_ren_unlock(a); ++ out_children: ++ au_nhash_wh_free(&a->whlist); ++ out_unlock: ++ if (unlikely(err && au_ftest_ren(a->flags, ISDIR))) { ++ au_update_dbstart(a->dst_dentry); ++ d_drop(a->dst_dentry); ++ } ++ if (!err) ++ d_move(a->src_dentry, a->dst_dentry); ++ if (au_ftest_ren(a->flags, ISSAMEDIR)) ++ di_write_unlock(a->dst_parent); ++ else ++ di_write_unlock2(a->src_parent, a->dst_parent); ++ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry); ++ out_free: ++ iput(a->dst_inode); ++ if (a->thargs) ++ au_whtmp_rmdir_free(a->thargs); ++ kfree(a); ++ out: ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/Kconfig linux-2.6.31/fs/aufs/Kconfig +--- linux-2.6.31-vanilla/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/Kconfig 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,140 @@ ++config AUFS_FS ++ tristate "Aufs (Advanced multi layered unification filesystem) support" ++ depends on EXPERIMENTAL ++ help ++ Aufs is a stackable unification filesystem such as Unionfs, ++ which unifies several directories and provides a merged single ++ directory. ++ In the early days, aufs was entirely re-designed and ++ re-implemented Unionfs Version 1.x series. Introducing many ++ original ideas, approaches and improvements, it becomes totally ++ different from Unionfs while keeping the basic features. ++ ++if AUFS_FS ++choice ++ prompt "Maximum number of branches" ++ default AUFS_BRANCH_MAX_127 ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_127 ++ bool "127" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_511 ++ bool "511" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_1023 ++ bool "1023" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_32767 ++ bool "32767" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++endchoice ++ ++config AUFS_HINOTIFY ++ bool "Use inotify to detect actions on a branch" ++ depends on INOTIFY ++ help ++ If you want to modify files on branches directly, eg. bypassing aufs, ++ and want aufs to detect the changes of them fully, then enable this ++ option and use 'udba=inotify' mount option. ++ It will have a negative impact to the performance. ++ See detail in aufs.5. ++ ++config AUFS_EXPORT ++ bool "NFS-exportable aufs" ++ depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS) ++ help ++ If you want to export your mounted aufs via NFS, then enable this ++ option. There are several requirements for this configuration. ++ See detail in aufs.5. ++ ++config AUFS_RDU ++ bool "Readdir in userspace" ++ help ++ If you have millions of files under a single aufs directory, and ++ meet the out of memory, then enable this option and set ++ environment variables for your readdir(3). ++ See detail in aufs.5. ++ ++config AUFS_SHWH ++ bool "Show whiteouts" ++ help ++ If you want to make the whiteouts in aufs visible, then enable ++ this option and specify 'shwh' mount option. Although it may ++ sounds like philosophy or something, but in technically it ++ simply shows the name of whiteout with keeping its behaviour. ++ ++config AUFS_BR_RAMFS ++ bool "Ramfs (initramfs/rootfs) as an aufs branch" ++ help ++ If you want to use ramfs as an aufs branch fs, then enable this ++ option. Generally tmpfs is recommended. ++ Aufs prohibited them to be a branch fs by default, because ++ initramfs becomes unusable after switch_root or something ++ generally. If you sets initramfs as an aufs branch and boot your ++ system by switch_root, you will meet a problem easily since the ++ files in initramfs may be inaccessible. ++ Unless you are going to use ramfs as an aufs branch fs without ++ switch_root or something, leave it N. ++ ++config AUFS_BR_FUSE ++ bool "Fuse fs as an aufs branch" ++ depends on FUSE_FS ++ select AUFS_POLL ++ help ++ If you want to use fuse-based userspace filesystem as an aufs ++ branch fs, then enable this option. ++ It implements the internal poll(2) operation which is ++ implemented by fuse only (curretnly). ++ ++config AUFS_DEBUG ++ bool "Debug aufs" ++ help ++ Enable this to compile aufs internal debug code. ++ It will have a negative impact to the performance. ++ ++config AUFS_MAGIC_SYSRQ ++ bool ++ depends on AUFS_DEBUG && MAGIC_SYSRQ ++ default y ++ help ++ Automatic configuration for internal use. ++ When aufs supports Magic SysRq, enabled automatically. ++ ++config AUFS_BDEV_LOOP ++ bool ++ depends on BLK_DEV_LOOP ++ default y ++ help ++ Automatic configuration for internal use. ++ Convert =[ym] into =y. ++ ++config AUFS_INO_T_64 ++ bool ++ depends on AUFS_EXPORT ++ depends on 64BIT && !(ALPHA || S390) ++ default y ++ help ++ Automatic configuration for internal use. ++ /* typedef unsigned long/int __kernel_ino_t */ ++ /* alpha and s390x are int */ ++ ++config AUFS_POLL ++ bool ++ help ++ Automatic configuration for internal use. ++endif +diff -Nur linux-2.6.31-vanilla/fs/aufs/loop.c linux-2.6.31/fs/aufs/loop.c +--- linux-2.6.31-vanilla/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/loop.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * support for loopback block device as a branch ++ */ ++ ++#include <linux/loop.h> ++#include "aufs.h" ++ ++/* ++ * test if two lower dentries have overlapping branches. ++ */ ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2) ++{ ++ struct inode *h_inode; ++ struct loop_device *l; ++ ++ h_inode = h_d1->d_inode; ++ if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR) ++ return 0; ++ ++ l = h_inode->i_sb->s_bdev->bd_disk->private_data; ++ h_d1 = l->lo_backing_file->f_dentry; ++ /* h_d1 can be local NFS. in this case aufs cannot detect the loop */ ++ if (unlikely(h_d1->d_sb == sb)) ++ return 1; ++ return !!au_test_subdir(h_d1, h_d2); ++} ++ ++/* true if a kernel thread named 'loop[0-9].*' accesses a file */ ++int au_test_loopback_kthread(void) ++{ ++ const char c = current->comm[4]; ++ ++ return current->mm == NULL ++ && '0' <= c && c <= '9' ++ && strncmp(current->comm, "loop", 4) == 0; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/loop.h linux-2.6.31/fs/aufs/loop.h +--- linux-2.6.31-vanilla/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/loop.h 2009-09-16 13:55:29.000000000 +0200 +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * support for loopback mount as a branch ++ */ ++ ++#ifndef __AUFS_LOOP_H__ ++#define __AUFS_LOOP_H__ ++ ++#ifdef __KERNEL__ ++ ++struct dentry; ++struct super_block; ++ ++#ifdef CONFIG_AUFS_BDEV_LOOP ++/* loop.c */ ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2); ++int au_test_loopback_kthread(void); ++#else ++static inline ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1, ++ struct dentry *h_d2) ++{ ++ return 0; ++} ++ ++static inline int au_test_loopback_kthread(void) ++{ ++ return 0; ++} ++#endif /* BLK_DEV_LOOP */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_LOOP_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/magic.mk linux-2.6.31/fs/aufs/magic.mk +--- linux-2.6.31-vanilla/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/magic.mk 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,52 @@ ++ ++# defined in ${srctree}/fs/fuse/inode.c ++# tristate ++ifdef CONFIG_FUSE_FS ++ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546 ++endif ++ ++# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h ++# tristate ++ifdef CONFIG_OCFS2_FS ++ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f ++endif ++ ++# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h ++# tristate ++ifdef CONFIG_OCFS2_FS_O2CB ++ccflags-y += -DDLMFS_MAGIC=0x76a9f425 ++endif ++ ++# defined in ${srctree}/fs/ramfs/inode.c ++# always true ++ccflags-y += -DRAMFS_MAGIC=0x858458f6 ++ ++# defined in ${srctree}/fs/cifs/cifsfs.c ++# tristate ++ifdef CONFIG_CIFS_FS ++ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42 ++endif ++ ++# defined in ${srctree}/fs/xfs/xfs_sb.h ++# tristate ++ifdef CONFIG_XFS_FS ++ccflags-y += -DXFS_SB_MAGIC=0x58465342 ++endif ++ ++# defined in ${srctree}/fs/configfs/mount.c ++# tristate ++ifdef CONFIG_CONFIGFS_FS ++ccflags-y += -DCONFIGFS_MAGIC=0x62656570 ++endif ++ ++# defined in ${srctree}/fs/9p/v9fs.h ++# tristate ++ifdef CONFIG_9P_FS ++ccflags-y += -DV9FS_MAGIC=0x01021997 ++endif ++ ++# defined in ${srctree}/fs/ubifs/ubifs.h ++# tristate ++ifdef CONFIG_UBIFS_FS ++ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905 ++endif +diff -Nur linux-2.6.31-vanilla/fs/aufs/Makefile linux-2.6.31/fs/aufs/Makefile +--- linux-2.6.31-vanilla/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/Makefile 2009-09-16 13:55:29.000000000 +0200 +@@ -0,0 +1,24 @@ ++ ++include ${src}/magic.mk ++-include ${src}/priv_def.mk ++ ++obj-$(CONFIG_AUFS_FS) += aufs.o ++aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ ++ wkq.o vfsub.o dcsub.o \ ++ cpup.o whout.o plink.o wbr_policy.o \ ++ dinfo.o dentry.o \ ++ finfo.o file.o f_op.o \ ++ dir.o vdir.o \ ++ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ ++ ioctl.o ++ ++# all are boolean ++aufs-$(CONFIG_SYSFS) += sysfs.o ++aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o ++aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o ++aufs-$(CONFIG_AUFS_HINOTIFY) += hinotify.o ++aufs-$(CONFIG_AUFS_EXPORT) += export.o ++aufs-$(CONFIG_AUFS_POLL) += poll.o ++aufs-$(CONFIG_AUFS_RDU) += rdu.o ++aufs-$(CONFIG_AUFS_DEBUG) += debug.o ++aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o +diff -Nur linux-2.6.31-vanilla/fs/aufs/module.c linux-2.6.31/fs/aufs/module.c +--- linux-2.6.31-vanilla/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/module.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,173 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * module global variables and operations ++ */ ++ ++#include <linux/module.h> ++#include <linux/seq_file.h> ++#include "aufs.h" ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp) ++{ ++ if (new_sz <= nused) ++ return p; ++ ++ p = krealloc(p, new_sz, gfp); ++ if (p) ++ memset(p + nused, 0, new_sz - nused); ++ return p; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * aufs caches ++ */ ++struct kmem_cache *au_cachep[AuCache_Last]; ++static int __init au_cache_init(void) ++{ ++ au_cachep[AuCache_DINFO] = AuCache(au_dinfo); ++ if (au_cachep[AuCache_DINFO]) ++ au_cachep[AuCache_ICNTNR] = AuCache(au_icntnr); ++ if (au_cachep[AuCache_ICNTNR]) ++ au_cachep[AuCache_FINFO] = AuCache(au_finfo); ++ if (au_cachep[AuCache_FINFO]) ++ au_cachep[AuCache_VDIR] = AuCache(au_vdir); ++ if (au_cachep[AuCache_VDIR]) ++ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); ++ if (au_cachep[AuCache_DEHSTR]) ++ return 0; ++ ++ return -ENOMEM; ++} ++ ++static void au_cache_fin(void) ++{ ++ int i; ++ for (i = 0; i < AuCache_Last; i++) ++ if (au_cachep[i]) { ++ kmem_cache_destroy(au_cachep[i]); ++ au_cachep[i] = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_dir_roflags; ++ ++/* ++ * functions for module interface. ++ */ ++MODULE_LICENSE("GPL"); ++/* MODULE_LICENSE("GPL v2"); */ ++MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>"); ++MODULE_DESCRIPTION(AUFS_NAME ++ " -- Advanced multi layered unification filesystem"); ++MODULE_VERSION(AUFS_VERSION); ++ ++/* it should be 'byte', but param_set_byte() prints it by "%c" */ ++short aufs_nwkq = AUFS_NWKQ_DEF; ++MODULE_PARM_DESC(nwkq, "the number of workqueue thread, " AUFS_WKQ_NAME); ++module_param_named(nwkq, aufs_nwkq, short, S_IRUGO); ++ ++/* this module parameter has no meaning when SYSFS is disabled */ ++int sysaufs_brs = 1; ++MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN"); ++module_param_named(brs, sysaufs_brs, int, S_IRUGO); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */ ++ ++int au_seq_path(struct seq_file *seq, struct path *path) ++{ ++ return seq_path(seq, path, au_esc_chars); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int __init aufs_init(void) ++{ ++ int err, i; ++ char *p; ++ ++ p = au_esc_chars; ++ for (i = 1; i <= ' '; i++) ++ *p++ = i; ++ *p++ = '\'; ++ *p++ = '\x7f'; ++ *p = 0; ++ ++ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); ++ ++ sysaufs_brs_init(); ++ au_debug_init(); ++ ++ err = -EINVAL; ++ if (unlikely(aufs_nwkq <= 0)) ++ goto out; ++ ++ err = sysaufs_init(); ++ if (unlikely(err)) ++ goto out; ++ err = au_wkq_init(); ++ if (unlikely(err)) ++ goto out_sysaufs; ++ err = au_hinotify_init(); ++ if (unlikely(err)) ++ goto out_wkq; ++ err = au_sysrq_init(); ++ if (unlikely(err)) ++ goto out_hin; ++ err = au_cache_init(); ++ if (unlikely(err)) ++ goto out_sysrq; ++ err = register_filesystem(&aufs_fs_type); ++ if (unlikely(err)) ++ goto out_cache; ++ pr_info(AUFS_NAME " " AUFS_VERSION "\n"); ++ goto out; /* success */ ++ ++ out_cache: ++ au_cache_fin(); ++ out_sysrq: ++ au_sysrq_fin(); ++ out_hin: ++ au_hinotify_fin(); ++ out_wkq: ++ au_wkq_fin(); ++ out_sysaufs: ++ sysaufs_fin(); ++ out: ++ return err; ++} ++ ++static void __exit aufs_exit(void) ++{ ++ unregister_filesystem(&aufs_fs_type); ++ au_cache_fin(); ++ au_sysrq_fin(); ++ au_hinotify_fin(); ++ au_wkq_fin(); ++ sysaufs_fin(); ++} ++ ++module_init(aufs_init); ++module_exit(aufs_exit); +diff -Nur linux-2.6.31-vanilla/fs/aufs/module.h linux-2.6.31/fs/aufs/module.h +--- linux-2.6.31-vanilla/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/module.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * module initialization and module-global ++ */ ++ ++#ifndef __AUFS_MODULE_H__ ++#define __AUFS_MODULE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/slab.h> ++ ++struct path; ++struct seq_file; ++ ++/* module parameters */ ++extern short aufs_nwkq; ++extern int sysaufs_brs; ++ ++/* ---------------------------------------------------------------------- */ ++ ++extern int au_dir_roflags; ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp); ++int au_seq_path(struct seq_file *seq, struct path *path); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* kmem cache */ ++enum { ++ AuCache_DINFO, ++ AuCache_ICNTNR, ++ AuCache_FINFO, ++ AuCache_VDIR, ++ AuCache_DEHSTR, ++#ifdef CONFIG_AUFS_HINOTIFY ++ AuCache_HINOTIFY, ++#endif ++ AuCache_Last ++}; ++ ++#define AuCache(type) KMEM_CACHE(type, SLAB_RECLAIM_ACCOUNT) ++ ++extern struct kmem_cache *au_cachep[]; ++ ++#define AuCacheFuncs(name, index) \ ++static inline void *au_cache_alloc_##name(void) \ ++{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \ ++static inline void au_cache_free_##name(void *p) \ ++{ kmem_cache_free(au_cachep[AuCache_##index], p); } ++ ++AuCacheFuncs(dinfo, DINFO); ++AuCacheFuncs(icntnr, ICNTNR); ++AuCacheFuncs(finfo, FINFO); ++AuCacheFuncs(vdir, VDIR); ++AuCacheFuncs(dehstr, DEHSTR); ++ ++/* ---------------------------------------------------------------------- */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_MODULE_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/opts.c linux-2.6.31/fs/aufs/opts.c +--- linux-2.6.31-vanilla/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/opts.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,1546 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * mount options/flags ++ */ ++ ++#include <linux/file.h> ++#include <linux/namei.h> ++#include <linux/types.h> /* a distribution requires */ ++#include <linux/parser.h> ++#include "aufs.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { ++ Opt_br, ++ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend, ++ Opt_idel, Opt_imod, Opt_ireorder, ++ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir, ++ Opt_rdblk_def, Opt_rdhash_def, ++ Opt_xino, Opt_zxino, Opt_noxino, ++ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, ++ Opt_trunc_xino_path, Opt_itrunc_xino, ++ Opt_trunc_xib, Opt_notrunc_xib, ++ Opt_shwh, Opt_noshwh, ++ Opt_plink, Opt_noplink, Opt_list_plink, ++ Opt_udba, ++ /* Opt_lock, Opt_unlock, */ ++ Opt_cmd, Opt_cmd_args, ++ Opt_diropq_a, Opt_diropq_w, ++ Opt_warn_perm, Opt_nowarn_perm, ++ Opt_wbr_copyup, Opt_wbr_create, ++ Opt_refrof, Opt_norefrof, ++ Opt_verbose, Opt_noverbose, ++ Opt_sum, Opt_nosum, Opt_wsum, ++ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err ++}; ++ ++static match_table_t options = { ++ {Opt_br, "br=%s"}, ++ {Opt_br, "br:%s"}, ++ ++ {Opt_add, "add=%d:%s"}, ++ {Opt_add, "add:%d:%s"}, ++ {Opt_add, "ins=%d:%s"}, ++ {Opt_add, "ins:%d:%s"}, ++ {Opt_append, "append=%s"}, ++ {Opt_append, "append:%s"}, ++ {Opt_prepend, "prepend=%s"}, ++ {Opt_prepend, "prepend:%s"}, ++ ++ {Opt_del, "del=%s"}, ++ {Opt_del, "del:%s"}, ++ /* {Opt_idel, "idel:%d"}, */ ++ {Opt_mod, "mod=%s"}, ++ {Opt_mod, "mod:%s"}, ++ /* {Opt_imod, "imod:%d:%s"}, */ ++ ++ {Opt_dirwh, "dirwh=%d"}, ++ ++ {Opt_xino, "xino=%s"}, ++ {Opt_noxino, "noxino"}, ++ {Opt_trunc_xino, "trunc_xino"}, ++ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, ++ {Opt_notrunc_xino, "notrunc_xino"}, ++ {Opt_trunc_xino_path, "trunc_xino=%s"}, ++ {Opt_itrunc_xino, "itrunc_xino=%d"}, ++ /* {Opt_zxino, "zxino=%s"}, */ ++ {Opt_trunc_xib, "trunc_xib"}, ++ {Opt_notrunc_xib, "notrunc_xib"}, ++ ++ {Opt_plink, "plink"}, ++ {Opt_noplink, "noplink"}, ++#ifdef CONFIG_AUFS_DEBUG ++ {Opt_list_plink, "list_plink"}, ++#endif ++ ++ {Opt_udba, "udba=%s"}, ++ ++ {Opt_diropq_a, "diropq=always"}, ++ {Opt_diropq_a, "diropq=a"}, ++ {Opt_diropq_w, "diropq=whiteouted"}, ++ {Opt_diropq_w, "diropq=w"}, ++ ++ {Opt_warn_perm, "warn_perm"}, ++ {Opt_nowarn_perm, "nowarn_perm"}, ++ ++ /* keep them temporary */ ++ {Opt_ignore_silent, "coo=%s"}, ++ {Opt_ignore_silent, "nodlgt"}, ++ {Opt_ignore_silent, "nodirperm1"}, ++ {Opt_ignore_silent, "clean_plink"}, ++ ++#ifdef CONFIG_AUFS_SHWH ++ {Opt_shwh, "shwh"}, ++#endif ++ {Opt_noshwh, "noshwh"}, ++ ++ {Opt_rendir, "rendir=%d"}, ++ ++ {Opt_refrof, "refrof"}, ++ {Opt_norefrof, "norefrof"}, ++ ++ {Opt_verbose, "verbose"}, ++ {Opt_verbose, "v"}, ++ {Opt_noverbose, "noverbose"}, ++ {Opt_noverbose, "quiet"}, ++ {Opt_noverbose, "q"}, ++ {Opt_noverbose, "silent"}, ++ ++ {Opt_sum, "sum"}, ++ {Opt_nosum, "nosum"}, ++ {Opt_wsum, "wsum"}, ++ ++ {Opt_rdcache, "rdcache=%d"}, ++ {Opt_rdblk, "rdblk=%d"}, ++ {Opt_rdblk_def, "rdblk=def"}, ++ {Opt_rdhash, "rdhash=%d"}, ++ {Opt_rdhash_def, "rdhash=def"}, ++ ++ {Opt_wbr_create, "create=%s"}, ++ {Opt_wbr_create, "create_policy=%s"}, ++ {Opt_wbr_copyup, "cpup=%s"}, ++ {Opt_wbr_copyup, "copyup=%s"}, ++ {Opt_wbr_copyup, "copyup_policy=%s"}, ++ ++ /* internal use for the scripts */ ++ {Opt_ignore_silent, "si=%s"}, ++ ++ {Opt_br, "dirs=%s"}, ++ {Opt_ignore, "debug=%d"}, ++ {Opt_ignore, "delete=whiteout"}, ++ {Opt_ignore, "delete=all"}, ++ {Opt_ignore, "imap=%s"}, ++ ++ /* temporary workaround, due to old mount(8)? */ ++ {Opt_ignore_silent, "relatime"}, ++ ++ {Opt_err, NULL} ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static const char *au_parser_pattern(int val, struct match_token *token) ++{ ++ while (token->pattern) { ++ if (token->token == val) ++ return token->pattern; ++ token++; ++ } ++ BUG(); ++ return "??"; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t brperms = { ++ {AuBrPerm_RO, AUFS_BRPERM_RO}, ++ {AuBrPerm_RR, AUFS_BRPERM_RR}, ++ {AuBrPerm_RW, AUFS_BRPERM_RW}, ++ ++ {AuBrPerm_ROWH, AUFS_BRPERM_ROWH}, ++ {AuBrPerm_RRWH, AUFS_BRPERM_RRWH}, ++ {AuBrPerm_RWNoLinkWH, AUFS_BRPERM_RWNLWH}, ++ ++ {AuBrPerm_ROWH, "nfsro"}, ++ {AuBrPerm_RO, NULL} ++}; ++ ++static int br_perm_val(char *perm) ++{ ++ int val; ++ substring_t args[MAX_OPT_ARGS]; ++ ++ val = match_token(perm, brperms, args); ++ return val; ++} ++ ++const char *au_optstr_br_perm(int brperm) ++{ ++ return au_parser_pattern(brperm, (void *)brperms); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t udbalevel = { ++ {AuOpt_UDBA_REVAL, "reval"}, ++ {AuOpt_UDBA_NONE, "none"}, ++#ifdef CONFIG_AUFS_HINOTIFY ++ {AuOpt_UDBA_HINOTIFY, "inotify"}, ++#endif ++ {-1, NULL} ++}; ++ ++static int udba_val(char *str) ++{ ++ substring_t args[MAX_OPT_ARGS]; ++ ++ return match_token(str, udbalevel, args); ++} ++ ++const char *au_optstr_udba(int udba) ++{ ++ return au_parser_pattern(udba, (void *)udbalevel); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t au_wbr_create_policy = { ++ {AuWbrCreate_TDP, "tdp"}, ++ {AuWbrCreate_TDP, "top-down-parent"}, ++ {AuWbrCreate_RR, "rr"}, ++ {AuWbrCreate_RR, "round-robin"}, ++ {AuWbrCreate_MFS, "mfs"}, ++ {AuWbrCreate_MFS, "most-free-space"}, ++ {AuWbrCreate_MFSV, "mfs:%d"}, ++ {AuWbrCreate_MFSV, "most-free-space:%d"}, ++ ++ {AuWbrCreate_MFSRR, "mfsrr:%d"}, ++ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"}, ++ {AuWbrCreate_PMFS, "pmfs"}, ++ {AuWbrCreate_PMFSV, "pmfs:%d"}, ++ ++ {-1, NULL} ++}; ++ ++/* ++ * cf. linux/lib/parser.c and cmdline.c ++ * gave up calling memparse() since it uses simple_strtoull() instead of ++ * strict_...(). ++ */ ++static int au_match_ull(substring_t *s, unsigned long long *result) ++{ ++ int err; ++ unsigned int len; ++ char a[32]; ++ ++ err = -ERANGE; ++ len = s->to - s->from; ++ if (len + 1 <= sizeof(a)) { ++ memcpy(a, s->from, len); ++ a[len] = '\0'; ++ err = strict_strtoull(a, 0, result); ++ } ++ return err; ++} ++ ++static int au_wbr_mfs_wmark(substring_t *arg, char *str, ++ struct au_opt_wbr_create *create) ++{ ++ int err; ++ unsigned long long ull; ++ ++ err = 0; ++ if (!au_match_ull(arg, &ull)) ++ create->mfsrr_watermark = ull; ++ else { ++ AuErr("bad integer in %s\n", str); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_mfs_sec(substring_t *arg, char *str, ++ struct au_opt_wbr_create *create) ++{ ++ int n, err; ++ ++ err = 0; ++ if (!match_int(arg, &n) && 0 <= n) ++ create->mfs_second = n; ++ else { ++ AuErr("bad integer in %s\n", str); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_create_val(char *str, struct au_opt_wbr_create *create) ++{ ++ int err, e; ++ substring_t args[MAX_OPT_ARGS]; ++ ++ err = match_token(str, au_wbr_create_policy, args); ++ create->wbr_create = err; ++ switch (err) { ++ case AuWbrCreate_MFSRRV: ++ e = au_wbr_mfs_wmark(&args[0], str, create); ++ if (!e) ++ e = au_wbr_mfs_sec(&args[1], str, create); ++ if (unlikely(e)) ++ err = e; ++ break; ++ case AuWbrCreate_MFSRR: ++ e = au_wbr_mfs_wmark(&args[0], str, create); ++ if (unlikely(e)) { ++ err = e; ++ break; ++ } ++ /*FALLTHROUGH*/ ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_PMFS: ++ create->mfs_second = AUFS_MFS_SECOND_DEF; ++ break; ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFSV: ++ e = au_wbr_mfs_sec(&args[0], str, create); ++ if (unlikely(e)) ++ err = e; ++ break; ++ } ++ ++ return err; ++} ++ ++const char *au_optstr_wbr_create(int wbr_create) ++{ ++ return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy); ++} ++ ++static match_table_t au_wbr_copyup_policy = { ++ {AuWbrCopyup_TDP, "tdp"}, ++ {AuWbrCopyup_TDP, "top-down-parent"}, ++ {AuWbrCopyup_BUP, "bup"}, ++ {AuWbrCopyup_BUP, "bottom-up-parent"}, ++ {AuWbrCopyup_BU, "bu"}, ++ {AuWbrCopyup_BU, "bottom-up"}, ++ {-1, NULL} ++}; ++ ++static int au_wbr_copyup_val(char *str) ++{ ++ substring_t args[MAX_OPT_ARGS]; ++ ++ return match_token(str, au_wbr_copyup_policy, args); ++} ++ ++const char *au_optstr_wbr_copyup(int wbr_copyup) ++{ ++ return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; ++ ++static void dump_opts(struct au_opts *opts) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++ /* reduce stack space */ ++ union { ++ struct au_opt_add *add; ++ struct au_opt_del *del; ++ struct au_opt_mod *mod; ++ struct au_opt_xino *xino; ++ struct au_opt_xino_itrunc *xino_itrunc; ++ struct au_opt_wbr_create *create; ++ } u; ++ struct au_opt *opt; ++ ++ opt = opts->opt; ++ while (opt->type != Opt_tail) { ++ switch (opt->type) { ++ case Opt_add: ++ u.add = &opt->add; ++ AuDbg("add {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_del: ++ case Opt_idel: ++ u.del = &opt->del; ++ AuDbg("del {%s, %p}\n", ++ u.del->pathname, u.del->h_path.dentry); ++ break; ++ case Opt_mod: ++ case Opt_imod: ++ u.mod = &opt->mod; ++ AuDbg("mod {%s, 0x%x, %p}\n", ++ u.mod->path, u.mod->perm, u.mod->h_root); ++ break; ++ case Opt_append: ++ u.add = &opt->add; ++ AuDbg("append {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_prepend: ++ u.add = &opt->add; ++ AuDbg("prepend {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_dirwh: ++ AuDbg("dirwh %d\n", opt->dirwh); ++ break; ++ case Opt_rdcache: ++ AuDbg("rdcache %d\n", opt->rdcache); ++ break; ++ case Opt_rdblk: ++ AuDbg("rdblk %u\n", opt->rdblk); ++ break; ++ case Opt_rdblk_def: ++ AuDbg("rdblk_def\n"); ++ break; ++ case Opt_rdhash: ++ AuDbg("rdhash %u\n", opt->rdhash); ++ break; ++ case Opt_rdhash_def: ++ AuDbg("rdhash_def\n"); ++ break; ++ case Opt_xino: ++ u.xino = &opt->xino; ++ AuDbg("xino {%s %.*s}\n", ++ u.xino->path, ++ AuDLNPair(u.xino->file->f_dentry)); ++ break; ++ case Opt_trunc_xino: ++ AuLabel(trunc_xino); ++ break; ++ case Opt_notrunc_xino: ++ AuLabel(notrunc_xino); ++ break; ++ case Opt_trunc_xino_path: ++ case Opt_itrunc_xino: ++ u.xino_itrunc = &opt->xino_itrunc; ++ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex); ++ break; ++ ++ case Opt_noxino: ++ AuLabel(noxino); ++ break; ++ case Opt_trunc_xib: ++ AuLabel(trunc_xib); ++ break; ++ case Opt_notrunc_xib: ++ AuLabel(notrunc_xib); ++ break; ++ case Opt_shwh: ++ AuLabel(shwh); ++ break; ++ case Opt_noshwh: ++ AuLabel(noshwh); ++ break; ++ case Opt_plink: ++ AuLabel(plink); ++ break; ++ case Opt_noplink: ++ AuLabel(noplink); ++ break; ++ case Opt_list_plink: ++ AuLabel(list_plink); ++ break; ++ case Opt_udba: ++ AuDbg("udba %d, %s\n", ++ opt->udba, au_optstr_udba(opt->udba)); ++ break; ++ case Opt_diropq_a: ++ AuLabel(diropq_a); ++ break; ++ case Opt_diropq_w: ++ AuLabel(diropq_w); ++ break; ++ case Opt_warn_perm: ++ AuLabel(warn_perm); ++ break; ++ case Opt_nowarn_perm: ++ AuLabel(nowarn_perm); ++ break; ++ case Opt_refrof: ++ AuLabel(refrof); ++ break; ++ case Opt_norefrof: ++ AuLabel(norefrof); ++ break; ++ case Opt_verbose: ++ AuLabel(verbose); ++ break; ++ case Opt_noverbose: ++ AuLabel(noverbose); ++ break; ++ case Opt_sum: ++ AuLabel(sum); ++ break; ++ case Opt_nosum: ++ AuLabel(nosum); ++ break; ++ case Opt_wsum: ++ AuLabel(wsum); ++ break; ++ case Opt_wbr_create: ++ u.create = &opt->wbr_create; ++ AuDbg("create %d, %s\n", u.create->wbr_create, ++ au_optstr_wbr_create(u.create->wbr_create)); ++ switch (u.create->wbr_create) { ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFSV: ++ AuDbg("%d sec\n", u.create->mfs_second); ++ break; ++ case AuWbrCreate_MFSRR: ++ AuDbg("%llu watermark\n", ++ u.create->mfsrr_watermark); ++ break; ++ case AuWbrCreate_MFSRRV: ++ AuDbg("%llu watermark, %d sec\n", ++ u.create->mfsrr_watermark, ++ u.create->mfs_second); ++ break; ++ } ++ break; ++ case Opt_wbr_copyup: ++ AuDbg("copyup %d, %s\n", opt->wbr_copyup, ++ au_optstr_wbr_copyup(opt->wbr_copyup)); ++ break; ++ default: ++ BUG(); ++ } ++ opt++; ++ } ++#endif ++} ++ ++void au_opts_free(struct au_opts *opts) ++{ ++ struct au_opt *opt; ++ ++ opt = opts->opt; ++ while (opt->type != Opt_tail) { ++ switch (opt->type) { ++ case Opt_add: ++ case Opt_append: ++ case Opt_prepend: ++ path_put(&opt->add.path); ++ break; ++ case Opt_del: ++ case Opt_idel: ++ path_put(&opt->del.h_path); ++ break; ++ case Opt_mod: ++ case Opt_imod: ++ dput(opt->mod.h_root); ++ break; ++ case Opt_xino: ++ fput(opt->xino.file); ++ break; ++ } ++ opt++; ++ } ++} ++ ++static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags, ++ aufs_bindex_t bindex) ++{ ++ int err; ++ struct au_opt_add *add = &opt->add; ++ char *p; ++ ++ add->bindex = bindex; ++ add->perm = AuBrPerm_Last; ++ add->pathname = opt_str; ++ p = strchr(opt_str, '='); ++ if (p) { ++ *p++ = 0; ++ if (*p) ++ add->perm = br_perm_val(p); ++ } ++ ++ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path); ++ if (!err) { ++ if (!p) { ++ add->perm = AuBrPerm_RO; ++ if (au_test_fs_rr(add->path.dentry->d_sb)) ++ add->perm = AuBrPerm_RR; ++ else if (!bindex && !(sb_flags & MS_RDONLY)) ++ add->perm = AuBrPerm_RW; ++ } ++ opt->type = Opt_add; ++ goto out; ++ } ++ AuErr("lookup failed %s (%d)\n", add->pathname, err); ++ err = -EINVAL; ++ ++ out: ++ return err; ++} ++ ++static int au_opts_parse_del(struct au_opt_del *del, substring_t args[]) ++{ ++ int err; ++ ++ del->pathname = args[0].from; ++ AuDbg("del path %s\n", del->pathname); ++ ++ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path); ++ if (unlikely(err)) ++ AuErr("lookup failed %s (%d)\n", del->pathname, err); ++ ++ return err; ++} ++ ++#if 0 /* reserved for future use */ ++static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_opt_del *del, substring_t args[]) ++{ ++ int err; ++ struct dentry *root; ++ ++ err = -EINVAL; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (bindex < 0 || au_sbend(sb) < bindex) { ++ AuErr("out of bounds, %d\n", bindex); ++ goto out; ++ } ++ ++ err = 0; ++ del->h_path.dentry = dget(au_h_dptr(root, bindex)); ++ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex)); ++ ++ out: ++ aufs_read_unlock(root, !AuLock_IR); ++ return err; ++} ++#endif ++ ++static int au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[]) ++{ ++ int err; ++ struct path path; ++ char *p; ++ ++ err = -EINVAL; ++ mod->path = args[0].from; ++ p = strchr(mod->path, '='); ++ if (unlikely(!p)) { ++ AuErr("no permssion %s\n", args[0].from); ++ goto out; ++ } ++ ++ *p++ = 0; ++ err = vfsub_kern_path(mod->path, lkup_dirflags, &path); ++ if (unlikely(err)) { ++ AuErr("lookup failed %s (%d)\n", mod->path, err); ++ goto out; ++ } ++ ++ mod->perm = br_perm_val(p); ++ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p); ++ mod->h_root = dget(path.dentry); ++ path_put(&path); ++ ++ out: ++ return err; ++} ++ ++#if 0 /* reserved for future use */ ++static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_opt_mod *mod, substring_t args[]) ++{ ++ int err; ++ struct dentry *root; ++ ++ err = -EINVAL; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (bindex < 0 || au_sbend(sb) < bindex) { ++ AuErr("out of bounds, %d\n", bindex); ++ goto out; ++ } ++ ++ err = 0; ++ mod->perm = br_perm_val(args[1].from); ++ AuDbg("mod path %s, perm 0x%x, %s\n", ++ mod->path, mod->perm, args[1].from); ++ mod->h_root = dget(au_h_dptr(root, bindex)); ++ ++ out: ++ aufs_read_unlock(root, !AuLock_IR); ++ return err; ++} ++#endif ++ ++static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino, ++ substring_t args[]) ++{ ++ int err; ++ struct file *file; ++ ++ file = au_xino_create(sb, args[0].from, /*silent*/0); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ ++ err = -EINVAL; ++ if (unlikely(file->f_dentry->d_sb == sb)) { ++ fput(file); ++ AuErr("%s must be outside\n", args[0].from); ++ goto out; ++ } ++ ++ err = 0; ++ xino->file = file; ++ xino->path = args[0].from; ++ ++ out: ++ return err; ++} ++ ++static ++int au_opts_parse_xino_itrunc_path(struct super_block *sb, ++ struct au_opt_xino_itrunc *xino_itrunc, ++ substring_t args[]) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct path path; ++ struct dentry *root; ++ ++ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path); ++ if (unlikely(err)) { ++ AuErr("lookup failed %s (%d)\n", args[0].from, err); ++ goto out; ++ } ++ ++ xino_itrunc->bindex = -1; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ if (au_h_dptr(root, bindex) == path.dentry) { ++ xino_itrunc->bindex = bindex; ++ break; ++ } ++ } ++ aufs_read_unlock(root, !AuLock_IR); ++ path_put(&path); ++ ++ if (unlikely(xino_itrunc->bindex < 0)) { ++ AuErr("no such branch %s\n", args[0].from); ++ err = -EINVAL; ++ } ++ ++ out: ++ return err; ++} ++ ++/* called without aufs lock */ ++int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts) ++{ ++ int err, n, token; ++ aufs_bindex_t bindex; ++ unsigned char skipped; ++ struct dentry *root; ++ struct au_opt *opt, *opt_tail; ++ char *opt_str; ++ /* reduce the stack space */ ++ union { ++ struct au_opt_xino_itrunc *xino_itrunc; ++ struct au_opt_wbr_create *create; ++ } u; ++ struct { ++ substring_t args[MAX_OPT_ARGS]; ++ } *a; ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ root = sb->s_root; ++ err = 0; ++ bindex = 0; ++ opt = opts->opt; ++ opt_tail = opt + opts->max_opt - 1; ++ opt->type = Opt_tail; ++ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { ++ err = -EINVAL; ++ skipped = 0; ++ token = match_token(opt_str, options, a->args); ++ switch (token) { ++ case Opt_br: ++ err = 0; ++ while (!err && (opt_str = strsep(&a->args[0].from, ":")) ++ && *opt_str) { ++ err = opt_add(opt, opt_str, opts->sb_flags, ++ bindex++); ++ if (unlikely(!err && ++opt > opt_tail)) { ++ err = -E2BIG; ++ break; ++ } ++ opt->type = Opt_tail; ++ skipped = 1; ++ } ++ break; ++ case Opt_add: ++ if (unlikely(match_int(&a->args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ bindex = n; ++ err = opt_add(opt, a->args[1].from, opts->sb_flags, ++ bindex); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_append: ++ err = opt_add(opt, a->args[0].from, opts->sb_flags, ++ /*dummy bindex*/1); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_prepend: ++ err = opt_add(opt, a->args[0].from, opts->sb_flags, ++ /*bindex*/0); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_del: ++ err = au_opts_parse_del(&opt->del, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#if 0 /* reserved for future use */ ++ case Opt_idel: ++ del->pathname = "(indexed)"; ++ if (unlikely(match_int(&args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ err = au_opts_parse_idel(sb, n, &opt->del, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#endif ++ case Opt_mod: ++ err = au_opts_parse_mod(&opt->mod, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#ifdef IMOD /* reserved for future use */ ++ case Opt_imod: ++ u.mod->path = "(indexed)"; ++ if (unlikely(match_int(&a->args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ err = au_opts_parse_imod(sb, n, &opt->mod, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#endif ++ case Opt_xino: ++ err = au_opts_parse_xino(sb, &opt->xino, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++ ++ case Opt_trunc_xino_path: ++ err = au_opts_parse_xino_itrunc_path ++ (sb, &opt->xino_itrunc, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++ ++ case Opt_itrunc_xino: ++ u.xino_itrunc = &opt->xino_itrunc; ++ if (unlikely(match_int(&a->args[0], &n))) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ u.xino_itrunc->bindex = n; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (n < 0 || au_sbend(sb) < n) { ++ AuErr("out of bounds, %d\n", n); ++ aufs_read_unlock(root, !AuLock_IR); ++ break; ++ } ++ aufs_read_unlock(root, !AuLock_IR); ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_dirwh: ++ if (unlikely(match_int(&a->args[0], &opt->dirwh))) ++ break; ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_rdcache: ++ if (unlikely(match_int(&a->args[0], &opt->rdcache))) ++ break; ++ err = 0; ++ opt->type = token; ++ break; ++ case Opt_rdblk: ++ if (unlikely(match_int(&a->args[0], &n) ++ || n < 0 ++ || n > KMALLOC_MAX_SIZE)) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ if (unlikely(n && n < NAME_MAX)) { ++ AuErr("rdblk must be larger than %d\n", ++ NAME_MAX); ++ break; ++ } ++ opt->rdblk = n; ++ err = 0; ++ opt->type = token; ++ break; ++ case Opt_rdhash: ++ if (unlikely(match_int(&a->args[0], &n) ++ || n < 0 ++ || n * sizeof(struct hlist_head) ++ > KMALLOC_MAX_SIZE)) { ++ AuErr("bad integer in %s\n", opt_str); ++ break; ++ } ++ opt->rdhash = n; ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_trunc_xino: ++ case Opt_notrunc_xino: ++ case Opt_noxino: ++ case Opt_trunc_xib: ++ case Opt_notrunc_xib: ++ case Opt_shwh: ++ case Opt_noshwh: ++ case Opt_plink: ++ case Opt_noplink: ++ case Opt_list_plink: ++ case Opt_diropq_a: ++ case Opt_diropq_w: ++ case Opt_warn_perm: ++ case Opt_nowarn_perm: ++ case Opt_refrof: ++ case Opt_norefrof: ++ case Opt_verbose: ++ case Opt_noverbose: ++ case Opt_sum: ++ case Opt_nosum: ++ case Opt_wsum: ++ case Opt_rdblk_def: ++ case Opt_rdhash_def: ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_udba: ++ opt->udba = udba_val(a->args[0].from); ++ if (opt->udba >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ AuErr("wrong value, %s\n", opt_str); ++ break; ++ ++ case Opt_wbr_create: ++ u.create = &opt->wbr_create; ++ u.create->wbr_create ++ = au_wbr_create_val(a->args[0].from, u.create); ++ if (u.create->wbr_create >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ AuErr("wrong value, %s\n", opt_str); ++ break; ++ case Opt_wbr_copyup: ++ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); ++ if (opt->wbr_copyup >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ AuErr("wrong value, %s\n", opt_str); ++ break; ++ ++ case Opt_ignore: ++ AuWarn("ignored %s\n", opt_str); ++ /*FALLTHROUGH*/ ++ case Opt_ignore_silent: ++ skipped = 1; ++ err = 0; ++ break; ++ case Opt_err: ++ AuErr("unknown option %s\n", opt_str); ++ break; ++ } ++ ++ if (!err && !skipped) { ++ if (unlikely(++opt > opt_tail)) { ++ err = -E2BIG; ++ opt--; ++ opt->type = Opt_tail; ++ break; ++ } ++ opt->type = Opt_tail; ++ } ++ } ++ ++ kfree(a); ++ dump_opts(opts); ++ if (unlikely(err)) ++ au_opts_free(opts); ++ ++ out: ++ return err; ++} ++ ++static int au_opt_wbr_create(struct super_block *sb, ++ struct au_opt_wbr_create *create) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 1; /* handled */ ++ sbinfo = au_sbi(sb); ++ if (sbinfo->si_wbr_create_ops->fin) { ++ err = sbinfo->si_wbr_create_ops->fin(sb); ++ if (!err) ++ err = 1; ++ } ++ ++ sbinfo->si_wbr_create = create->wbr_create; ++ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create; ++ switch (create->wbr_create) { ++ case AuWbrCreate_MFSRRV: ++ case AuWbrCreate_MFSRR: ++ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark; ++ /*FALLTHROUGH*/ ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFS: ++ case AuWbrCreate_PMFSV: ++ sbinfo->si_wbr_mfs.mfs_expire = create->mfs_second * HZ; ++ break; ++ } ++ ++ if (sbinfo->si_wbr_create_ops->init) ++ sbinfo->si_wbr_create_ops->init(sb); /* ignore */ ++ ++ return err; ++} ++ ++/* ++ * returns, ++ * plus: processed without an error ++ * zero: unprocessed ++ */ ++static int au_opt_simple(struct super_block *sb, struct au_opt *opt, ++ struct au_opts *opts) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 1; /* handled */ ++ sbinfo = au_sbi(sb); ++ switch (opt->type) { ++ case Opt_udba: ++ sbinfo->si_mntflags &= ~AuOptMask_UDBA; ++ sbinfo->si_mntflags |= opt->udba; ++ opts->given_udba |= opt->udba; ++ break; ++ ++ case Opt_plink: ++ au_opt_set(sbinfo->si_mntflags, PLINK); ++ break; ++ case Opt_noplink: ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_put(sb); ++ au_opt_clr(sbinfo->si_mntflags, PLINK); ++ break; ++ case Opt_list_plink: ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_list(sb); ++ break; ++ ++ case Opt_diropq_a: ++ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ); ++ break; ++ case Opt_diropq_w: ++ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ); ++ break; ++ ++ case Opt_warn_perm: ++ au_opt_set(sbinfo->si_mntflags, WARN_PERM); ++ break; ++ case Opt_nowarn_perm: ++ au_opt_clr(sbinfo->si_mntflags, WARN_PERM); ++ break; ++ ++ case Opt_refrof: ++ au_opt_set(sbinfo->si_mntflags, REFROF); ++ break; ++ case Opt_norefrof: ++ au_opt_clr(sbinfo->si_mntflags, REFROF); ++ break; ++ ++ case Opt_verbose: ++ au_opt_set(sbinfo->si_mntflags, VERBOSE); ++ break; ++ case Opt_noverbose: ++ au_opt_clr(sbinfo->si_mntflags, VERBOSE); ++ break; ++ ++ case Opt_sum: ++ au_opt_set(sbinfo->si_mntflags, SUM); ++ break; ++ case Opt_wsum: ++ au_opt_clr(sbinfo->si_mntflags, SUM); ++ au_opt_set(sbinfo->si_mntflags, SUM_W); ++ case Opt_nosum: ++ au_opt_clr(sbinfo->si_mntflags, SUM); ++ au_opt_clr(sbinfo->si_mntflags, SUM_W); ++ break; ++ ++ case Opt_wbr_create: ++ err = au_opt_wbr_create(sb, &opt->wbr_create); ++ break; ++ case Opt_wbr_copyup: ++ sbinfo->si_wbr_copyup = opt->wbr_copyup; ++ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup; ++ break; ++ ++ case Opt_dirwh: ++ sbinfo->si_dirwh = opt->dirwh; ++ break; ++ ++ case Opt_rdcache: ++ sbinfo->si_rdcache = opt->rdcache * HZ; ++ break; ++ case Opt_rdblk: ++ sbinfo->si_rdblk = opt->rdblk; ++ break; ++ case Opt_rdblk_def: ++ sbinfo->si_rdblk = AUFS_RDBLK_DEF; ++ break; ++ case Opt_rdhash: ++ sbinfo->si_rdhash = opt->rdhash; ++ break; ++ case Opt_rdhash_def: ++ sbinfo->si_rdhash = AUFS_RDHASH_DEF; ++ break; ++ ++ case Opt_shwh: ++ au_opt_set(sbinfo->si_mntflags, SHWH); ++ break; ++ case Opt_noshwh: ++ au_opt_clr(sbinfo->si_mntflags, SHWH); ++ break; ++ ++ case Opt_trunc_xino: ++ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); ++ break; ++ case Opt_notrunc_xino: ++ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO); ++ break; ++ ++ case Opt_trunc_xino_path: ++ case Opt_itrunc_xino: ++ err = au_xino_trunc(sb, opt->xino_itrunc.bindex); ++ if (!err) ++ err = 1; ++ break; ++ ++ case Opt_trunc_xib: ++ au_fset_opts(opts->flags, TRUNC_XIB); ++ break; ++ case Opt_notrunc_xib: ++ au_fclr_opts(opts->flags, TRUNC_XIB); ++ break; ++ ++ default: ++ err = 0; ++ break; ++ } ++ ++ return err; ++} ++ ++/* ++ * returns tri-state. ++ * plus: processed without an error ++ * zero: unprocessed ++ * minus: error ++ */ ++static int au_opt_br(struct super_block *sb, struct au_opt *opt, ++ struct au_opts *opts) ++{ ++ int err, do_refresh; ++ ++ err = 0; ++ switch (opt->type) { ++ case Opt_append: ++ opt->add.bindex = au_sbend(sb) + 1; ++ if (opt->add.bindex < 0) ++ opt->add.bindex = 0; ++ goto add; ++ case Opt_prepend: ++ opt->add.bindex = 0; ++ add: ++ case Opt_add: ++ err = au_br_add(sb, &opt->add, ++ au_ftest_opts(opts->flags, REMOUNT)); ++ if (!err) { ++ err = 1; ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ if (au_br_whable(opt->add.perm)) ++ au_fset_opts(opts->flags, REFRESH_NONDIR); ++ } ++ break; ++ ++ case Opt_del: ++ case Opt_idel: ++ err = au_br_del(sb, &opt->del, ++ au_ftest_opts(opts->flags, REMOUNT)); ++ if (!err) { ++ err = 1; ++ au_fset_opts(opts->flags, TRUNC_XIB); ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ au_fset_opts(opts->flags, REFRESH_NONDIR); ++ } ++ break; ++ ++ case Opt_mod: ++ case Opt_imod: ++ err = au_br_mod(sb, &opt->mod, ++ au_ftest_opts(opts->flags, REMOUNT), ++ &do_refresh); ++ if (!err) { ++ err = 1; ++ if (do_refresh) { ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ au_fset_opts(opts->flags, REFRESH_NONDIR); ++ } ++ } ++ break; ++ } ++ ++ return err; ++} ++ ++static int au_opt_xino(struct super_block *sb, struct au_opt *opt, ++ struct au_opt_xino **opt_xino, ++ struct au_opts *opts) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct dentry *root, *parent, *h_root; ++ ++ err = 0; ++ switch (opt->type) { ++ case Opt_xino: ++ err = au_xino_set(sb, &opt->xino, ++ !!au_ftest_opts(opts->flags, REMOUNT)); ++ if (unlikely(err)) ++ break; ++ ++ *opt_xino = &opt->xino; ++ au_xino_brid_set(sb, -1); ++ ++ /* safe d_parent access */ ++ parent = opt->xino.file->f_dentry->d_parent; ++ root = sb->s_root; ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ h_root = au_h_dptr(root, bindex); ++ if (h_root == parent) { ++ au_xino_brid_set(sb, au_sbr_id(sb, bindex)); ++ break; ++ } ++ } ++ break; ++ ++ case Opt_noxino: ++ au_xino_clr(sb); ++ au_xino_brid_set(sb, -1); ++ *opt_xino = (void *)-1; ++ break; ++ } ++ ++ return err; ++} ++ ++int au_opts_verify(struct super_block *sb, unsigned long sb_flags, ++ unsigned int pending) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ unsigned char do_plink, skip, do_free; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ struct dentry *root; ++ struct inode *dir, *h_dir; ++ struct au_sbinfo *sbinfo; ++ struct au_hinode *hdir; ++ ++ SiMustAnyLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA)); ++ ++ if (!(sb_flags & MS_RDONLY)) { ++ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) ++ AuWarn("first branch should be rw\n"); ++ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH))) ++ AuWarn("shwh should be used with ro\n"); ++ } ++ ++ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HINOTIFY) ++ && !au_opt_test(sbinfo->si_mntflags, XINO)) ++ AuWarn("udba=inotify requires xino\n"); ++ ++ err = 0; ++ root = sb->s_root; ++ dir = sb->s_root->d_inode; ++ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK); ++ bend = au_sbend(sb); ++ for (bindex = 0; !err && bindex <= bend; bindex++) { ++ skip = 0; ++ h_dir = au_h_iptr(dir, bindex); ++ br = au_sbr(sb, bindex); ++ do_free = 0; ++ ++ wbr = br->br_wbr; ++ if (wbr) ++ wbr_wh_read_lock(wbr); ++ ++ switch (br->br_perm) { ++ case AuBrPerm_RO: ++ case AuBrPerm_ROWH: ++ case AuBrPerm_RR: ++ case AuBrPerm_RRWH: ++ do_free = !!wbr; ++ skip = (!wbr ++ || (!wbr->wbr_whbase ++ && !wbr->wbr_plink ++ && !wbr->wbr_orph)); ++ break; ++ ++ case AuBrPerm_RWNoLinkWH: ++ /* skip = (!br->br_whbase && !br->br_orph); */ ++ skip = (!wbr || !wbr->wbr_whbase); ++ if (skip && wbr) { ++ if (do_plink) ++ skip = !!wbr->wbr_plink; ++ else ++ skip = !wbr->wbr_plink; ++ } ++ break; ++ ++ case AuBrPerm_RW: ++ /* skip = (br->br_whbase && br->br_ohph); */ ++ skip = (wbr && wbr->wbr_whbase); ++ if (skip) { ++ if (do_plink) ++ skip = !!wbr->wbr_plink; ++ else ++ skip = !wbr->wbr_plink; ++ } ++ break; ++ ++ default: ++ BUG(); ++ } ++ if (wbr) ++ wbr_wh_read_unlock(wbr); ++ ++ if (skip) ++ continue; ++ ++ hdir = au_hi(dir, bindex); ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ if (wbr) ++ wbr_wh_write_lock(wbr); ++ err = au_wh_init(au_h_dptr(root, bindex), br, sb); ++ if (wbr) ++ wbr_wh_write_unlock(wbr); ++ au_hin_imtx_unlock(hdir); ++ ++ if (!err && do_free) { ++ kfree(wbr); ++ br->br_wbr = NULL; ++ } ++ } ++ ++ return err; ++} ++ ++int au_opts_mount(struct super_block *sb, struct au_opts *opts) ++{ ++ int err; ++ unsigned int tmp; ++ aufs_bindex_t bend; ++ struct au_opt *opt; ++ struct au_opt_xino *opt_xino, xino; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 0; ++ opt_xino = NULL; ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) ++ err = au_opt_simple(sb, opt++, opts); ++ if (err > 0) ++ err = 0; ++ else if (unlikely(err < 0)) ++ goto out; ++ ++ /* disable xino and udba temporary */ ++ sbinfo = au_sbi(sb); ++ tmp = sbinfo->si_mntflags; ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL); ++ ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) ++ err = au_opt_br(sb, opt++, opts); ++ if (err > 0) ++ err = 0; ++ else if (unlikely(err < 0)) ++ goto out; ++ ++ bend = au_sbend(sb); ++ if (unlikely(bend < 0)) { ++ err = -EINVAL; ++ AuErr("no branches\n"); ++ goto out; ++ } ++ ++ if (au_opt_test(tmp, XINO)) ++ au_opt_set(sbinfo->si_mntflags, XINO); ++ opt = opts->opt; ++ while (!err && opt->type != Opt_tail) ++ err = au_opt_xino(sb, opt++, &opt_xino, opts); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_opts_verify(sb, sb->s_flags, tmp); ++ if (unlikely(err)) ++ goto out; ++ ++ /* restore xino */ ++ if (au_opt_test(tmp, XINO) && !opt_xino) { ++ xino.file = au_xino_def(sb); ++ err = PTR_ERR(xino.file); ++ if (IS_ERR(xino.file)) ++ goto out; ++ ++ err = au_xino_set(sb, &xino, /*remount*/0); ++ fput(xino.file); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ /* restore udba */ ++ sbinfo->si_mntflags &= ~AuOptMask_UDBA; ++ sbinfo->si_mntflags |= (tmp & AuOptMask_UDBA); ++ if (au_opt_test(tmp, UDBA_HINOTIFY)) { ++ struct inode *dir = sb->s_root->d_inode; ++ au_reset_hinotify(dir, ++ au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO); ++ } ++ ++ out: ++ return err; ++} ++ ++int au_opts_remount(struct super_block *sb, struct au_opts *opts) ++{ ++ int err, rerr; ++ struct inode *dir; ++ struct au_opt_xino *opt_xino; ++ struct au_opt *opt; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ dir = sb->s_root->d_inode; ++ sbinfo = au_sbi(sb); ++ err = 0; ++ opt_xino = NULL; ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) { ++ err = au_opt_simple(sb, opt, opts); ++ if (!err) ++ err = au_opt_br(sb, opt, opts); ++ if (!err) ++ err = au_opt_xino(sb, opt, &opt_xino, opts); ++ opt++; ++ } ++ if (err > 0) ++ err = 0; ++ AuTraceErr(err); ++ /* go on even err */ ++ ++ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0); ++ if (unlikely(rerr && !err)) ++ err = rerr; ++ ++ if (au_ftest_opts(opts->flags, TRUNC_XIB)) { ++ rerr = au_xib_trunc(sb); ++ if (unlikely(rerr && !err)) ++ err = rerr; ++ } ++ ++ /* will be handled by the caller */ ++ if (!au_ftest_opts(opts->flags, REFRESH_DIR) ++ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO))) ++ au_fset_opts(opts->flags, REFRESH_DIR); ++ ++ AuDbg("status 0x%x\n", opts->flags); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++unsigned int au_opt_udba(struct super_block *sb) ++{ ++ return au_mntflags(sb) & AuOptMask_UDBA; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/opts.h linux-2.6.31/fs/aufs/opts.h +--- linux-2.6.31-vanilla/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/opts.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,196 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * mount options/flags ++ */ ++ ++#ifndef __AUFS_OPTS_H__ ++#define __AUFS_OPTS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/path.h> ++#include <linux/aufs_type.h> ++ ++struct file; ++struct super_block; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* mount flags */ ++#define AuOpt_XINO 1 /* external inode number bitmap ++ and translation table */ ++#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */ ++#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */ ++#define AuOpt_UDBA_REVAL (1 << 3) ++#define AuOpt_UDBA_HINOTIFY (1 << 4) ++#define AuOpt_SHWH (1 << 5) /* show whiteout */ ++#define AuOpt_PLINK (1 << 6) /* pseudo-link */ ++#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */ ++#define AuOpt_REFROF (1 << 8) /* unimplemented */ ++#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */ ++#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */ ++#define AuOpt_SUM_W (1 << 11) /* unimplemented */ ++#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */ ++#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */ ++ ++#ifndef CONFIG_AUFS_HINOTIFY ++#undef AuOpt_UDBA_HINOTIFY ++#define AuOpt_UDBA_HINOTIFY 0 ++#endif ++#ifndef CONFIG_AUFS_SHWH ++#undef AuOpt_SHWH ++#define AuOpt_SHWH 0 ++#endif ++ ++#define AuOpt_Def (AuOpt_XINO \ ++ | AuOpt_UDBA_REVAL \ ++ | AuOpt_PLINK \ ++ /* | AuOpt_DIRPERM1 */ \ ++ | AuOpt_WARN_PERM) ++#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ ++ | AuOpt_UDBA_REVAL \ ++ | AuOpt_UDBA_HINOTIFY) ++ ++#define au_opt_test(flags, name) (flags & AuOpt_##name) ++#define au_opt_set(flags, name) do { \ ++ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \ ++ ((flags) |= AuOpt_##name); \ ++} while (0) ++#define au_opt_set_udba(flags, name) do { \ ++ (flags) &= ~AuOptMask_UDBA; \ ++ ((flags) |= AuOpt_##name); \ ++} while (0) ++#define au_opt_clr(flags, name) { ((flags) &= ~AuOpt_##name); } ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies to select one among multiple writable branches */ ++enum { ++ AuWbrCreate_TDP, /* top down parent */ ++ AuWbrCreate_RR, /* round robin */ ++ AuWbrCreate_MFS, /* most free space */ ++ AuWbrCreate_MFSV, /* mfs with seconds */ ++ AuWbrCreate_MFSRR, /* mfs then rr */ ++ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */ ++ AuWbrCreate_PMFS, /* parent and mfs */ ++ AuWbrCreate_PMFSV, /* parent and mfs with seconds */ ++ ++ AuWbrCreate_Def = AuWbrCreate_TDP ++}; ++ ++enum { ++ AuWbrCopyup_TDP, /* top down parent */ ++ AuWbrCopyup_BUP, /* bottom up parent */ ++ AuWbrCopyup_BU, /* bottom up */ ++ ++ AuWbrCopyup_Def = AuWbrCopyup_TDP ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_opt_add { ++ aufs_bindex_t bindex; ++ char *pathname; ++ int perm; ++ struct path path; ++}; ++ ++struct au_opt_del { ++ char *pathname; ++ struct path h_path; ++}; ++ ++struct au_opt_mod { ++ char *path; ++ int perm; ++ struct dentry *h_root; ++}; ++ ++struct au_opt_xino { ++ char *path; ++ struct file *file; ++}; ++ ++struct au_opt_xino_itrunc { ++ aufs_bindex_t bindex; ++}; ++ ++struct au_opt_wbr_create { ++ int wbr_create; ++ int mfs_second; ++ unsigned long long mfsrr_watermark; ++}; ++ ++struct au_opt { ++ int type; ++ union { ++ struct au_opt_xino xino; ++ struct au_opt_xino_itrunc xino_itrunc; ++ struct au_opt_add add; ++ struct au_opt_del del; ++ struct au_opt_mod mod; ++ int dirwh; ++ int rdcache; ++ unsigned int rdblk; ++ unsigned int rdhash; ++ int udba; ++ struct au_opt_wbr_create wbr_create; ++ int wbr_copyup; ++ }; ++}; ++ ++/* opts flags */ ++#define AuOpts_REMOUNT 1 ++#define AuOpts_REFRESH_DIR (1 << 1) ++#define AuOpts_REFRESH_NONDIR (1 << 2) ++#define AuOpts_TRUNC_XIB (1 << 3) ++#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) ++#define au_fset_opts(flags, name) { (flags) |= AuOpts_##name; } ++#define au_fclr_opts(flags, name) { (flags) &= ~AuOpts_##name; } ++ ++struct au_opts { ++ struct au_opt *opt; ++ int max_opt; ++ ++ unsigned int given_udba; ++ unsigned int flags; ++ unsigned long sb_flags; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++const char *au_optstr_br_perm(int brperm); ++const char *au_optstr_udba(int udba); ++const char *au_optstr_wbr_copyup(int wbr_copyup); ++const char *au_optstr_wbr_create(int wbr_create); ++ ++void au_opts_free(struct au_opts *opts); ++int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts); ++int au_opts_verify(struct super_block *sb, unsigned long sb_flags, ++ unsigned int pending); ++int au_opts_mount(struct super_block *sb, struct au_opts *opts); ++int au_opts_remount(struct super_block *sb, struct au_opts *opts); ++ ++unsigned int au_opt_udba(struct super_block *sb); ++ ++/* ---------------------------------------------------------------------- */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_OPTS_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/plink.c linux-2.6.31/fs/aufs/plink.c +--- linux-2.6.31-vanilla/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/plink.c 2009-09-16 13:55:29.000000000 +0200 +@@ -0,0 +1,396 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * pseudo-link ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * during a user process maintains the pseudo-links, ++ * prohibit adding a new plink and branch manipulation. ++ */ ++void au_plink_block_maintain(struct super_block *sb) ++{ ++ struct au_sbinfo *sbi = au_sbi(sb); ++ ++ SiMustAnyLock(sb); ++ ++ /* gave up wake_up_bit() */ ++ wait_event(sbi->si_plink_wq, !au_ftest_si(sbi, MAINTAIN_PLINK)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct pseudo_link { ++ struct list_head list; ++ struct inode *inode; ++}; ++ ++#ifdef CONFIG_AUFS_DEBUG ++void au_plink_list(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink; ++ ++ SiMustAnyLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ plink_list = &sbinfo->si_plink.head; ++ spin_lock(&sbinfo->si_plink.spin); ++ list_for_each_entry(plink, plink_list, list) ++ AuDbg("%lu\n", plink->inode->i_ino); ++ spin_unlock(&sbinfo->si_plink.spin); ++} ++#endif ++ ++/* is the inode pseudo-linked? */ ++int au_plink_test(struct inode *inode) ++{ ++ int found; ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink; ++ ++ sbinfo = au_sbi(inode->i_sb); ++ AuRwMustAnyLock(&sbinfo->si_rwsem); ++ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK)); ++ ++ found = 0; ++ plink_list = &sbinfo->si_plink.head; ++ spin_lock(&sbinfo->si_plink.spin); ++ list_for_each_entry(plink, plink_list, list) ++ if (plink->inode == inode) { ++ found = 1; ++ break; ++ } ++ spin_unlock(&sbinfo->si_plink.spin); ++ return found; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * generate a name for plink. ++ * the file will be stored under AUFS_WH_PLINKDIR. ++ */ ++/* 20 is max digits length of ulong 64 */ ++#define PLINK_NAME_LEN ((20 + 1) * 2) ++ ++static int plink_name(char *name, int len, struct inode *inode, ++ aufs_bindex_t bindex) ++{ ++ int rlen; ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, bindex); ++ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino); ++ return rlen; ++} ++ ++/* lookup the plink-ed @inode under the branch at @bindex */ ++struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct dentry *h_dentry, *h_parent; ++ struct au_branch *br; ++ struct inode *h_dir; ++ char a[PLINK_NAME_LEN]; ++ struct qstr tgtname = { ++ .name = a ++ }; ++ ++ br = au_sbr(inode->i_sb, bindex); ++ h_parent = br->br_wbr->wbr_plink; ++ h_dir = h_parent->d_inode; ++ tgtname.len = plink_name(a, sizeof(a), inode, bindex); ++ ++ /* always superio. */ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); ++ h_dentry = au_sio_lkup_one(&tgtname, h_parent, br); ++ mutex_unlock(&h_dir->i_mutex); ++ return h_dentry; ++} ++ ++/* create a pseudo-link */ ++static int do_whplink(struct qstr *tgt, struct dentry *h_parent, ++ struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = br->br_mnt ++ }; ++ struct inode *h_dir; ++ ++ h_dir = h_parent->d_inode; ++ again: ++ h_path.dentry = au_lkup_one(tgt, h_parent, br, /*nd*/NULL); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ err = 0; ++ /* wh.plink dir is not monitored */ ++ if (h_path.dentry->d_inode ++ && h_path.dentry->d_inode != h_dentry->d_inode) { ++ err = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ dput(h_path.dentry); ++ h_path.dentry = NULL; ++ if (!err) ++ goto again; ++ } ++ if (!err && !h_path.dentry->d_inode) ++ err = vfsub_link(h_dentry, h_dir, &h_path); ++ dput(h_path.dentry); ++ ++ out: ++ return err; ++} ++ ++struct do_whplink_args { ++ int *errp; ++ struct qstr *tgt; ++ struct dentry *h_parent; ++ struct dentry *h_dentry; ++ struct au_branch *br; ++}; ++ ++static void call_do_whplink(void *args) ++{ ++ struct do_whplink_args *a = args; ++ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br); ++} ++ ++static int whplink(struct dentry *h_dentry, struct inode *inode, ++ aufs_bindex_t bindex, struct au_branch *br) ++{ ++ int err, wkq_err; ++ struct au_wbr *wbr; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ char a[PLINK_NAME_LEN]; ++ struct qstr tgtname = { ++ .name = a ++ }; ++ ++ wbr = au_sbr(inode->i_sb, bindex)->br_wbr; ++ h_parent = wbr->wbr_plink; ++ h_dir = h_parent->d_inode; ++ tgtname.len = plink_name(a, sizeof(a), inode, bindex); ++ ++ /* always superio. */ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); ++ if (!au_test_wkq(current)) { ++ struct do_whplink_args args = { ++ .errp = &err, ++ .tgt = &tgtname, ++ .h_parent = h_parent, ++ .h_dentry = h_dentry, ++ .br = br ++ }; ++ wkq_err = au_wkq_wait(call_do_whplink, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } else ++ err = do_whplink(&tgtname, h_parent, h_dentry, br); ++ mutex_unlock(&h_dir->i_mutex); ++ ++ return err; ++} ++ ++/* free a single plink */ ++static void do_put_plink(struct pseudo_link *plink, int do_del) ++{ ++ iput(plink->inode); ++ if (do_del) ++ list_del(&plink->list); ++ kfree(plink); ++} ++ ++/* ++ * create a new pseudo-link for @h_dentry on @bindex. ++ * the linked inode is held in aufs @inode. ++ */ ++void au_plink_append(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry) ++{ ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink; ++ int found, err, cnt; ++ ++ sb = inode->i_sb; ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ err = 0; ++ cnt = 0; ++ found = 0; ++ plink_list = &sbinfo->si_plink.head; ++ spin_lock(&sbinfo->si_plink.spin); ++ list_for_each_entry(plink, plink_list, list) { ++ cnt++; ++ if (plink->inode == inode) { ++ found = 1; ++ break; ++ } ++ } ++ if (found) { ++ spin_unlock(&sbinfo->si_plink.spin); ++ return; ++ } ++ ++ plink = NULL; ++ if (!found) { ++ plink = kmalloc(sizeof(*plink), GFP_ATOMIC); ++ if (plink) { ++ plink->inode = au_igrab(inode); ++ list_add(&plink->list, plink_list); ++ cnt++; ++ } else ++ err = -ENOMEM; ++ } ++ spin_unlock(&sbinfo->si_plink.spin); ++ ++ if (!err) { ++ au_plink_block_maintain(sb); ++ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex)); ++ } ++ ++ if (unlikely(cnt > AUFS_PLINK_WARN)) ++ AuWarn1("unexpectedly many pseudo links, %d\n", cnt); ++ if (unlikely(err)) { ++ AuWarn("err %d, damaged pseudo link.\n", err); ++ if (!found && plink) ++ do_put_plink(plink, /*do_del*/1); ++ } ++} ++ ++/* free all plinks */ ++void au_plink_put(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink, *tmp; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ plink_list = &sbinfo->si_plink.head; ++ /* no spin_lock since sbinfo is write-locked */ ++ list_for_each_entry_safe(plink, tmp, plink_list, list) ++ do_put_plink(plink, 0); ++ INIT_LIST_HEAD(plink_list); ++} ++ ++/* free the plinks on a branch specified by @br_id */ ++void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id) ++{ ++ struct au_sbinfo *sbinfo; ++ struct list_head *plink_list; ++ struct pseudo_link *plink, *tmp; ++ struct inode *inode; ++ aufs_bindex_t bstart, bend, bindex; ++ unsigned char do_put; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ ++ plink_list = &sbinfo->si_plink.head; ++ /* no spin_lock since sbinfo is write-locked */ ++ list_for_each_entry_safe(plink, tmp, plink_list, list) { ++ do_put = 0; ++ inode = au_igrab(plink->inode); ++ ii_write_lock_child(inode); ++ bstart = au_ibstart(inode); ++ bend = au_ibend(inode); ++ if (bstart >= 0) { ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ if (!au_h_iptr(inode, bindex) ++ || au_ii_br_id(inode, bindex) != br_id) ++ continue; ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ do_put = 1; ++ break; ++ } ++ } else ++ do_put_plink(plink, 1); ++ ++ if (do_put) { ++ for (bindex = bstart; bindex <= bend; bindex++) ++ if (au_h_iptr(inode, bindex)) { ++ do_put = 0; ++ break; ++ } ++ if (do_put) ++ do_put_plink(plink, 1); ++ } ++ ii_write_unlock(inode); ++ iput(inode); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++long au_plink_ioctl(struct file *file, unsigned int cmd) ++{ ++ long err; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ err = -EACCES; ++ if (!capable(CAP_SYS_ADMIN)) ++ goto out; ++ ++ err = 0; ++ sb = file->f_dentry->d_sb; ++ sbinfo = au_sbi(sb); ++ switch (cmd) { ++ case AUFS_CTL_PLINK_MAINT: ++ /* ++ * pseudo-link maintenance mode, ++ * cleared by aufs_release_dir() ++ */ ++ si_write_lock(sb); ++ if (!au_ftest_si(sbinfo, MAINTAIN_PLINK)) { ++ au_fset_si(sbinfo, MAINTAIN_PLINK); ++ au_fi(file)->fi_maintain_plink = 1; ++ } else ++ err = -EBUSY; ++ si_write_unlock(sb); ++ break; ++ case AUFS_CTL_PLINK_CLEAN: ++ aufs_write_lock(sb->s_root); ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_put(sb); ++ aufs_write_unlock(sb->s_root); ++ break; ++ default: ++ err = -EINVAL; ++ } ++ out: ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/poll.c linux-2.6.31/fs/aufs/poll.c +--- linux-2.6.31-vanilla/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/poll.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * poll operation ++ * There is only one filesystem which implements ->poll operation, currently. ++ */ ++ ++#include "aufs.h" ++ ++unsigned int aufs_poll(struct file *file, poll_table *wait) ++{ ++ unsigned int mask; ++ int err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ /* We should pretend an error happened. */ ++ mask = POLLERR /* | POLLIN | POLLOUT */; ++ dentry = file->f_dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ /* it is not an error if h_file has no operation */ ++ mask = DEFAULT_POLLMASK; ++ h_file = au_h_fptr(file, au_fbstart(file)); ++ if (h_file->f_op && h_file->f_op->poll) ++ mask = h_file->f_op->poll(h_file, wait); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ out: ++ si_read_unlock(sb); ++ AuTraceErr((int)mask); ++ return mask; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/rdu.c linux-2.6.31/fs/aufs/rdu.c +--- linux-2.6.31-vanilla/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/rdu.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,331 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * readdir in userspace. ++ */ ++ ++#include <linux/security.h> ++#include <linux/uaccess.h> ++#include <linux/aufs_type.h> ++#include "aufs.h" ++ ++/* bits for struct aufs_rdu.flags */ ++#define AuRdu_CALLED 1 ++#define AuRdu_CONT (1 << 1) ++#define AuRdu_FULL (1 << 2) ++#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name) ++#define au_fset_rdu(flags, name) { (flags) |= AuRdu_##name; } ++#define au_fclr_rdu(flags, name) { (flags) &= ~AuRdu_##name; } ++ ++struct au_rdu_arg { ++ struct aufs_rdu *rdu; ++ union au_rdu_ent_ul ent; ++ unsigned long end; ++ ++ struct super_block *sb; ++ int err; ++}; ++ ++static int au_rdu_fill(void *__arg, const char *name, int nlen, ++ loff_t offset, u64 h_ino, unsigned int d_type) ++{ ++ int err, len; ++ struct au_rdu_arg *arg = __arg; ++ struct aufs_rdu *rdu = arg->rdu; ++ struct au_rdu_ent ent; ++ ++ err = 0; ++ arg->err = 0; ++ au_fset_rdu(rdu->cookie.flags, CALLED); ++ len = au_rdu_len(nlen); ++ if (arg->ent.ul + len < arg->end) { ++ ent.ino = h_ino; ++ ent.bindex = rdu->cookie.bindex; ++ ent.type = d_type; ++ ent.nlen = nlen; ++ ++ err = -EFAULT; ++ if (copy_to_user(arg->ent.e, &ent, sizeof(ent))) ++ goto out; ++ if (copy_to_user(arg->ent.e->name, name, nlen)) ++ goto out; ++ /* the terminating NULL */ ++ if (__put_user(0, arg->ent.e->name + nlen)) ++ goto out; ++ err = 0; ++ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */ ++ arg->ent.ul += len; ++ rdu->rent++; ++ } else { ++ err = -EFAULT; ++ au_fset_rdu(rdu->cookie.flags, FULL); ++ rdu->full = 1; ++ rdu->tail = arg->ent; ++ } ++ ++ out: ++ /* AuTraceErr(err); */ ++ return err; ++} ++ ++static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg) ++{ ++ int err; ++ loff_t offset; ++ struct au_rdu_cookie *cookie = &arg->rdu->cookie; ++ ++ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET); ++ err = offset; ++ if (unlikely(offset != cookie->h_pos)) ++ goto out; ++ ++ err = 0; ++ do { ++ arg->err = 0; ++ au_fclr_rdu(cookie->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_readdir(h_file, au_rdu_fill, arg); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err ++ && au_ftest_rdu(cookie->flags, CALLED) ++ && !au_ftest_rdu(cookie->flags, FULL)); ++ cookie->h_pos = h_file->f_pos; ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_rdu(struct file *file, struct aufs_rdu *rdu) ++{ ++ int err; ++ aufs_bindex_t bend; ++ struct au_rdu_arg arg; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct file *h_file; ++ struct au_rdu_cookie *cookie = &rdu->cookie; ++ ++ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out; ++ } ++ rdu->rent = 0; ++ rdu->tail = rdu->ent; ++ rdu->full = 0; ++ arg.rdu = rdu; ++ arg.ent = rdu->ent; ++ arg.end = arg.ent.ul; ++ arg.end += rdu->sz; ++ ++ err = -ENOTDIR; ++ if (unlikely(!file->f_op || !file->f_op->readdir)) ++ goto out; ++ ++ err = security_file_permission(file, MAY_READ); ++ AuTraceErr(err); ++ if (unlikely(err)) ++ goto out; ++ ++ dentry = file->f_dentry; ++ inode = dentry->d_inode; ++#if 1 ++ mutex_lock(&inode->i_mutex); ++#else ++ err = mutex_lock_killable(&inode->i_mutex); ++ AuTraceErr(err); ++ if (unlikely(err)) ++ goto out; ++#endif ++ err = -ENOENT; ++ if (unlikely(IS_DEADDIR(inode))) ++ goto out_mtx; ++ ++ arg.sb = inode->i_sb; ++ si_read_lock(arg.sb, AuLock_FLUSH); ++ fi_read_lock(file); ++ ++ err = -EAGAIN; ++ if (unlikely(au_ftest_rdu(cookie->flags, CONT) ++ && cookie->generation != au_figen(file))) ++ goto out_unlock; ++ ++ err = 0; ++ if (!rdu->blk) { ++ rdu->blk = au_sbi(arg.sb)->si_rdblk; ++ if (!rdu->blk) ++ rdu->blk = au_dir_size(file, /*dentry*/NULL); ++ } ++ bend = au_fbstart(file); ++ if (cookie->bindex < bend) ++ cookie->bindex = bend; ++ bend = au_fbend(file); ++ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */ ++ for (; !err && cookie->bindex <= bend; ++ cookie->bindex++, cookie->h_pos = 0) { ++ h_file = au_h_fptr(file, cookie->bindex); ++ if (!h_file) ++ continue; ++ ++ au_fclr_rdu(cookie->flags, FULL); ++ err = au_rdu_do(h_file, &arg); ++ AuTraceErr(err); ++ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err)) ++ break; ++ } ++ AuDbg("rent %llu\n", rdu->rent); ++ ++ if (!err && !au_ftest_rdu(cookie->flags, CONT)) { ++ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH); ++ au_fset_rdu(cookie->flags, CONT); ++ cookie->generation = au_figen(file); ++ } ++ ++ ii_read_lock_child(inode); ++ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode))); ++ ii_read_unlock(inode); ++ ++ out_unlock: ++ fi_read_unlock(file); ++ si_read_unlock(arg.sb); ++ out_mtx: ++ mutex_unlock(&inode->i_mutex); ++ out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu) ++{ ++ int err; ++ ino_t ino; ++ unsigned long long nent; ++ union au_rdu_ent_ul *u; ++ struct au_rdu_ent ent; ++ struct super_block *sb; ++ ++ err = 0; ++ nent = rdu->nent; ++ u = &rdu->ent; ++ sb = file->f_dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ while (nent-- > 0) { ++ err = !access_ok(VERIFY_WRITE, u->e, sizeof(ent)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ break; ++ } ++ ++ err = copy_from_user(&ent, u->e, sizeof(ent)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ break; ++ } ++ ++ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */ ++ if (!ent.wh) ++ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino); ++ else ++ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type, ++ &ino); ++ if (unlikely(err)) { ++ AuTraceErr(err); ++ break; ++ } ++ ++ err = __put_user(ino, &u->e->ino); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ break; ++ } ++ u->ul += au_rdu_len(ent.nlen); ++ } ++ si_read_unlock(sb); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_rdu_verify(struct aufs_rdu *rdu) ++{ ++ AuDbg("rdu{%llu, %p, (%u, %u) | %u | %llu, %u, %u | " ++ "%llu, b%d, 0x%x, g%u}\n", ++ rdu->sz, rdu->ent.e, rdu->verify[0], rdu->verify[1], ++ rdu->blk, ++ rdu->rent, rdu->shwh, rdu->full, ++ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags, ++ rdu->cookie.generation); ++ ++ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu) ++ && rdu->verify[AufsCtlRduV_SZ_PTR] == sizeof(rdu)) ++ return 0; ++ ++ AuDbg("%u:%u, %u:%u\n", ++ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu), ++ rdu->verify[AufsCtlRduV_SZ_PTR], (unsigned int)sizeof(rdu)); ++ return -EINVAL; ++} ++ ++long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err, e; ++ struct aufs_rdu rdu; ++ void __user *p = (void __user *)arg; ++ ++ err = copy_from_user(&rdu, p, sizeof(rdu)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out; ++ } ++ err = au_rdu_verify(&rdu); ++ if (unlikely(err)) ++ goto out; ++ ++ switch (cmd) { ++ case AUFS_CTL_RDU: ++ err = au_rdu(file, &rdu); ++ if (unlikely(err)) ++ break; ++ ++ e = copy_to_user(p, &rdu, sizeof(rdu)); ++ if (unlikely(e)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ } ++ break; ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_ino(file, &rdu); ++ break; ++ ++ default: ++ err = -EINVAL; ++ } ++ ++ out: ++ AuTraceErr(err); ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/rwsem.h linux-2.6.31/fs/aufs/rwsem.h +--- linux-2.6.31-vanilla/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/rwsem.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,186 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * simple read-write semaphore wrappers ++ */ ++ ++#ifndef __AUFS_RWSEM_H__ ++#define __AUFS_RWSEM_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/rwsem.h> ++ ++struct au_rwsem { ++ struct rw_semaphore rwsem; ++#ifdef CONFIG_AUFS_DEBUG ++ /* just for debugging, not almighty counter */ ++ atomic_t rcnt, wcnt; ++#endif ++}; ++ ++#ifdef CONFIG_AUFS_DEBUG ++#define AuDbgCntInit(rw) do { \ ++ atomic_set(&(rw)->rcnt, 0); \ ++ atomic_set(&(rw)->wcnt, 0); \ ++ smp_mb(); /* atomic set */ \ ++} while (0) ++ ++#define AuDbgRcntInc(rw) atomic_inc_return(&(rw)->rcnt) ++#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0) ++#define AuDbgWcntInc(rw) WARN_ON(atomic_inc_return(&(rw)->wcnt) > 1) ++#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0) ++#else ++#define AuDbgCntInit(rw) do {} while (0) ++#define AuDbgRcntInc(rw) do {} while (0) ++#define AuDbgRcntDec(rw) do {} while (0) ++#define AuDbgWcntInc(rw) do {} while (0) ++#define AuDbgWcntDec(rw) do {} while (0) ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* to debug easier, do not make them inlined functions */ ++#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list)) ++/* rwsem_is_locked() is unusable */ ++#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0) ++#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0) ++#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \ ++ && atomic_read(&(rw)->wcnt) <= 0) ++#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \ ++ || atomic_read(&(rw)->wcnt)) ++ ++static inline void au_rw_init(struct au_rwsem *rw) ++{ ++ AuDbgCntInit(rw); ++ init_rwsem(&rw->rwsem); ++} ++ ++static inline void au_rw_init_wlock(struct au_rwsem *rw) ++{ ++ au_rw_init(rw); ++ down_write(&rw->rwsem); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_init_wlock_nested(struct au_rwsem *rw, ++ unsigned int lsc) ++{ ++ au_rw_init(rw); ++ down_write_nested(&rw->rwsem, lsc); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_read_lock(struct au_rwsem *rw) ++{ ++ down_read(&rw->rwsem); ++ AuDbgRcntInc(rw); ++} ++ ++static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc) ++{ ++ down_read_nested(&rw->rwsem, lsc); ++ AuDbgRcntInc(rw); ++} ++ ++static inline void au_rw_read_unlock(struct au_rwsem *rw) ++{ ++ AuRwMustReadLock(rw); ++ AuDbgRcntDec(rw); ++ up_read(&rw->rwsem); ++} ++ ++static inline void au_rw_dgrade_lock(struct au_rwsem *rw) ++{ ++ AuRwMustWriteLock(rw); ++ AuDbgRcntInc(rw); ++ AuDbgWcntDec(rw); ++ downgrade_write(&rw->rwsem); ++} ++ ++static inline void au_rw_write_lock(struct au_rwsem *rw) ++{ ++ down_write(&rw->rwsem); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_write_lock_nested(struct au_rwsem *rw, ++ unsigned int lsc) ++{ ++ down_write_nested(&rw->rwsem, lsc); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_write_unlock(struct au_rwsem *rw) ++{ ++ AuRwMustWriteLock(rw); ++ AuDbgWcntDec(rw); ++ up_write(&rw->rwsem); ++} ++ ++/* why is not _nested version defined */ ++static inline int au_rw_read_trylock(struct au_rwsem *rw) ++{ ++ int ret = down_read_trylock(&rw->rwsem); ++ if (ret) ++ AuDbgRcntInc(rw); ++ return ret; ++} ++ ++static inline int au_rw_write_trylock(struct au_rwsem *rw) ++{ ++ int ret = down_write_trylock(&rw->rwsem); ++ if (ret) ++ AuDbgWcntInc(rw); ++ return ret; ++} ++ ++#undef AuDbgCntInit ++#undef AuDbgRcntInc ++#undef AuDbgRcntDec ++#undef AuDbgWcntInc ++#undef AuDbgWcntDec ++ ++#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ ++static inline void prefix##_read_lock(param) \ ++{ au_rw_read_lock(rwsem); } \ ++static inline void prefix##_write_lock(param) \ ++{ au_rw_write_lock(rwsem); } \ ++static inline int prefix##_read_trylock(param) \ ++{ return au_rw_read_trylock(rwsem); } \ ++static inline int prefix##_write_trylock(param) \ ++{ return au_rw_write_trylock(rwsem); } ++/* why is not _nested version defined */ ++/* static inline void prefix##_read_trylock_nested(param, lsc) ++{ au_rw_read_trylock_nested(rwsem, lsc)); } ++static inline void prefix##_write_trylock_nestd(param, lsc) ++{ au_rw_write_trylock_nested(rwsem, lsc); } */ ++ ++#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \ ++static inline void prefix##_read_unlock(param) \ ++{ au_rw_read_unlock(rwsem); } \ ++static inline void prefix##_write_unlock(param) \ ++{ au_rw_write_unlock(rwsem); } \ ++static inline void prefix##_downgrade_lock(param) \ ++{ au_rw_dgrade_lock(rwsem); } ++ ++#define AuSimpleRwsemFuncs(prefix, param, rwsem) \ ++ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ ++ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_RWSEM_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/sbinfo.c linux-2.6.31/fs/aufs/sbinfo.c +--- linux-2.6.31-vanilla/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/sbinfo.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,208 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * superblock private data ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * they are necessary regardless sysfs is disabled. ++ */ ++void au_si_free(struct kobject *kobj) ++{ ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ AuDebugOn(!list_empty(&sbinfo->si_plink.head)); ++ ++ sb = sbinfo->si_sb; ++ si_write_lock(sb); ++ au_xino_clr(sb); ++ au_br_free(sbinfo); ++ kfree(sbinfo->si_branch); ++ mutex_destroy(&sbinfo->si_xib_mtx); ++ si_write_unlock(sb); ++ AuRwDestroy(&sbinfo->si_rwsem); ++ ++ kfree(sbinfo); ++} ++ ++int au_si_alloc(struct super_block *sb) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ err = -ENOMEM; ++ sbinfo = kmalloc(sizeof(*sbinfo), GFP_NOFS); ++ if (unlikely(!sbinfo)) ++ goto out; ++ ++ /* will be reallocated separately */ ++ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); ++ if (unlikely(!sbinfo->si_branch)) ++ goto out_sbinfo; ++ ++ memset(&sbinfo->si_kobj, 0, sizeof(sbinfo->si_kobj)); ++ err = sysaufs_si_init(sbinfo); ++ if (unlikely(err)) ++ goto out_br; ++ ++ au_nwt_init(&sbinfo->si_nowait); ++ au_rw_init_wlock(&sbinfo->si_rwsem); ++ sbinfo->si_generation = 0; ++ sbinfo->au_si_status = 0; ++ sbinfo->si_bend = -1; ++ sbinfo->si_last_br_id = 0; ++ ++ sbinfo->si_wbr_copyup = AuWbrCopyup_Def; ++ sbinfo->si_wbr_create = AuWbrCreate_Def; ++ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + AuWbrCopyup_Def; ++ sbinfo->si_wbr_create_ops = au_wbr_create_ops + AuWbrCreate_Def; ++ ++ sbinfo->si_mntflags = AuOpt_Def; ++ ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ sbinfo->si_xib = NULL; ++ mutex_init(&sbinfo->si_xib_mtx); ++ sbinfo->si_xib_buf = NULL; ++ sbinfo->si_xino_brid = -1; ++ /* leave si_xib_last_pindex and si_xib_next_bit */ ++ ++ sbinfo->si_rdcache = AUFS_RDCACHE_DEF * HZ; ++ sbinfo->si_rdblk = AUFS_RDBLK_DEF; ++ sbinfo->si_rdhash = AUFS_RDHASH_DEF; ++ sbinfo->si_dirwh = AUFS_DIRWH_DEF; ++ ++ au_spl_init(&sbinfo->si_plink); ++ init_waitqueue_head(&sbinfo->si_plink_wq); ++ ++ /* leave other members for sysaufs and si_mnt. */ ++ sbinfo->si_sb = sb; ++ sb->s_fs_info = sbinfo; ++ au_debug_sbinfo_init(sbinfo); ++ return 0; /* success */ ++ ++ out_br: ++ kfree(sbinfo->si_branch); ++ out_sbinfo: ++ kfree(sbinfo); ++ out: ++ return err; ++} ++ ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr) ++{ ++ int err, sz; ++ struct au_branch **brp; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*brp) * (sbinfo->si_bend + 1); ++ if (unlikely(!sz)) ++ sz = sizeof(*brp); ++ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS); ++ if (brp) { ++ sbinfo->si_branch = brp; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++unsigned int au_sigen_inc(struct super_block *sb) ++{ ++ unsigned int gen; ++ ++ SiMustWriteLock(sb); ++ ++ gen = ++au_sbi(sb)->si_generation; ++ au_update_digen(sb->s_root); ++ au_update_iigen(sb->s_root->d_inode); ++ sb->s_root->d_inode->i_version++; ++ return gen; ++} ++ ++aufs_bindex_t au_new_br_id(struct super_block *sb) ++{ ++ aufs_bindex_t br_id; ++ int i; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ for (i = 0; i <= AUFS_BRANCH_MAX; i++) { ++ br_id = ++sbinfo->si_last_br_id; ++ if (br_id && au_br_index(sb, br_id) < 0) ++ return br_id; ++ } ++ ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dentry and super_block lock. call at entry point */ ++void aufs_read_lock(struct dentry *dentry, int flags) ++{ ++ si_read_lock(dentry->d_sb, flags); ++ if (au_ftest_lock(flags, DW)) ++ di_write_lock_child(dentry); ++ else ++ di_read_lock_child(dentry, flags); ++} ++ ++void aufs_read_unlock(struct dentry *dentry, int flags) ++{ ++ if (au_ftest_lock(flags, DW)) ++ di_write_unlock(dentry); ++ else ++ di_read_unlock(dentry, flags); ++ si_read_unlock(dentry->d_sb); ++} ++ ++void aufs_write_lock(struct dentry *dentry) ++{ ++ si_write_lock(dentry->d_sb); ++ di_write_lock_child(dentry); ++} ++ ++void aufs_write_unlock(struct dentry *dentry) ++{ ++ di_write_unlock(dentry); ++ si_write_unlock(dentry->d_sb); ++} ++ ++void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags) ++{ ++ si_read_lock(d1->d_sb, flags); ++ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR)); ++} ++ ++void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2) ++{ ++ di_write_unlock2(d1, d2); ++ si_read_unlock(d1->d_sb); ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/spl.h linux-2.6.31/fs/aufs/spl.h +--- linux-2.6.31-vanilla/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/spl.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * simple list protected by a spinlock ++ */ ++ ++#ifndef __AUFS_SPL_H__ ++#define __AUFS_SPL_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/spinlock.h> ++#include <linux/list.h> ++ ++struct au_splhead { ++ spinlock_t spin; ++ struct list_head head; ++}; ++ ++static inline void au_spl_init(struct au_splhead *spl) ++{ ++ spin_lock_init(&spl->spin); ++ INIT_LIST_HEAD(&spl->head); ++} ++ ++static inline void au_spl_add(struct list_head *list, struct au_splhead *spl) ++{ ++ spin_lock(&spl->spin); ++ list_add(list, &spl->head); ++ spin_unlock(&spl->spin); ++} ++ ++static inline void au_spl_del(struct list_head *list, struct au_splhead *spl) ++{ ++ spin_lock(&spl->spin); ++ list_del(list); ++ spin_unlock(&spl->spin); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_SPL_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/super.c linux-2.6.31/fs/aufs/super.c +--- linux-2.6.31-vanilla/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/super.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,874 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * mount and super_block operations ++ */ ++ ++#include <linux/buffer_head.h> ++#include <linux/module.h> ++#include <linux/seq_file.h> ++#include <linux/statfs.h> ++#include "aufs.h" ++ ++/* ++ * super_operations ++ */ ++static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused) ++{ ++ struct au_icntnr *c; ++ ++ c = au_cache_alloc_icntnr(); ++ if (c) { ++ inode_init_once(&c->vfs_inode); ++ c->vfs_inode.i_version = 1; /* sigen(sb); */ ++ c->iinfo.ii_hinode = NULL; ++ return &c->vfs_inode; ++ } ++ return NULL; ++} ++ ++static void aufs_destroy_inode(struct inode *inode) ++{ ++ au_iinfo_fin(inode); ++ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); ++} ++ ++struct inode *au_iget_locked(struct super_block *sb, ino_t ino) ++{ ++ struct inode *inode; ++ int err; ++ ++ inode = iget_locked(sb, ino); ++ if (unlikely(!inode)) { ++ inode = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ if (!(inode->i_state & I_NEW)) ++ goto out; ++ ++ err = au_xigen_new(inode); ++ if (!err) ++ err = au_iinfo_init(inode); ++ if (!err) ++ inode->i_version++; ++ else { ++ iget_failed(inode); ++ inode = ERR_PTR(err); ++ } ++ ++ out: ++ /* never return NULL */ ++ AuDebugOn(!inode); ++ AuTraceErrPtr(inode); ++ return inode; ++} ++ ++/* lock free root dinfo */ ++static int au_show_brs(struct seq_file *seq, struct super_block *sb) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct path path; ++ struct au_hdentry *hd; ++ struct au_branch *br; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ hd = au_di(sb->s_root)->di_hdentry; ++ for (bindex = 0; !err && bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ path.mnt = br->br_mnt; ++ path.dentry = hd[bindex].hd_dentry; ++ err = au_seq_path(seq, &path); ++ if (err > 0) ++ err = seq_printf(seq, "=%s", ++ au_optstr_br_perm(br->br_perm)); ++ if (!err && bindex != bend) ++ err = seq_putc(seq, ':'); ++ } ++ ++ return err; ++} ++ ++static void au_show_wbr_create(struct seq_file *m, int v, ++ struct au_sbinfo *sbinfo) ++{ ++ const char *pat; ++ ++ AuRwMustAnyLock(&sbinfo->si_rwsem); ++ ++ seq_printf(m, ",create="); ++ pat = au_optstr_wbr_create(v); ++ switch (v) { ++ case AuWbrCreate_TDP: ++ case AuWbrCreate_RR: ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_PMFS: ++ seq_printf(m, pat); ++ break; ++ case AuWbrCreate_MFSV: ++ seq_printf(m, /*pat*/"mfs:%lu", ++ sbinfo->si_wbr_mfs.mfs_expire / HZ); ++ break; ++ case AuWbrCreate_PMFSV: ++ seq_printf(m, /*pat*/"pmfs:%lu", ++ sbinfo->si_wbr_mfs.mfs_expire / HZ); ++ break; ++ case AuWbrCreate_MFSRR: ++ seq_printf(m, /*pat*/"mfsrr:%llu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark); ++ break; ++ case AuWbrCreate_MFSRRV: ++ seq_printf(m, /*pat*/"mfsrr:%llu:%lu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark, ++ sbinfo->si_wbr_mfs.mfs_expire / HZ); ++ break; ++ } ++} ++ ++static int au_show_xino(struct seq_file *seq, struct vfsmount *mnt) ++{ ++#ifdef CONFIG_SYSFS ++ return 0; ++#else ++ int err; ++ const int len = sizeof(AUFS_XINO_FNAME) - 1; ++ aufs_bindex_t bindex, brid; ++ struct super_block *sb; ++ struct qstr *name; ++ struct file *f; ++ struct dentry *d, *h_root; ++ ++ AuRwMustAnyLock(&sbinfo->si_rwsem); ++ ++ err = 0; ++ sb = mnt->mnt_sb; ++ f = au_sbi(sb)->si_xib; ++ if (!f) ++ goto out; ++ ++ /* stop printing the default xino path on the first writable branch */ ++ h_root = NULL; ++ brid = au_xino_brid(sb); ++ if (brid >= 0) { ++ bindex = au_br_index(sb, brid); ++ h_root = au_di(sb->s_root)->di_hdentry[0 + bindex].hd_dentry; ++ } ++ d = f->f_dentry; ++ name = &d->d_name; ++ /* safe ->d_parent because the file is unlinked */ ++ if (d->d_parent == h_root ++ && name->len == len ++ && !memcmp(name->name, AUFS_XINO_FNAME, len)) ++ goto out; ++ ++ seq_puts(seq, ",xino="); ++ err = au_xino_path(seq, f); ++ ++ out: ++ return err; ++#endif ++} ++ ++/* seq_file will re-call me in case of too long string */ ++static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt) ++{ ++ int err, n; ++ unsigned int mnt_flags, v; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++#define AuBool(name, str) do { \ ++ v = au_opt_test(mnt_flags, name); \ ++ if (v != au_opt_test(AuOpt_Def, name)) \ ++ seq_printf(m, ",%s" #str, v ? "" : "no"); \ ++} while (0) ++ ++#define AuStr(name, str) do { \ ++ v = mnt_flags & AuOptMask_##name; \ ++ if (v != (AuOpt_Def & AuOptMask_##name)) \ ++ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ ++} while (0) ++ ++#define AuUInt(name, str, val) do { \ ++ if (val != AUFS_##name##_DEF) \ ++ seq_printf(m, "," #str "=%u", val); \ ++} while (0) ++ ++ /* lock free root dinfo */ ++ sb = mnt->mnt_sb; ++ si_noflush_read_lock(sb); ++ sbinfo = au_sbi(sb); ++ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo)); ++ ++ mnt_flags = au_mntflags(sb); ++ if (au_opt_test(mnt_flags, XINO)) { ++ err = au_show_xino(m, mnt); ++ if (unlikely(err)) ++ goto out; ++ } else ++ seq_puts(m, ",noxino"); ++ ++ AuBool(TRUNC_XINO, trunc_xino); ++ AuStr(UDBA, udba); ++ AuBool(SHWH, shwh); ++ AuBool(PLINK, plink); ++ /* AuBool(DIRPERM1, dirperm1); */ ++ /* AuBool(REFROF, refrof); */ ++ ++ v = sbinfo->si_wbr_create; ++ if (v != AuWbrCreate_Def) ++ au_show_wbr_create(m, v, sbinfo); ++ ++ v = sbinfo->si_wbr_copyup; ++ if (v != AuWbrCopyup_Def) ++ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); ++ ++ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); ++ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) ++ seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); ++ ++ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh); ++ ++ n = sbinfo->si_rdcache / HZ; ++ AuUInt(RDCACHE, rdcache, n); ++ ++ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk); ++ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash); ++ ++ AuBool(SUM, sum); ++ /* AuBool(SUM_W, wsum); */ ++ AuBool(WARN_PERM, warn_perm); ++ AuBool(VERBOSE, verbose); ++ ++ out: ++ /* be sure to print "br:" last */ ++ if (!sysaufs_brs) { ++ seq_puts(m, ",br:"); ++ au_show_brs(m, sb); ++ } ++ si_read_unlock(sb); ++ return 0; ++ ++#undef Deleted ++#undef AuBool ++#undef AuStr ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* sum mode which returns the summation for statfs(2) */ ++ ++static u64 au_add_till_max(u64 a, u64 b) ++{ ++ u64 old; ++ ++ old = a; ++ a += b; ++ if (old < a) ++ return a; ++ return ULLONG_MAX; ++} ++ ++static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf) ++{ ++ int err; ++ u64 blocks, bfree, bavail, files, ffree; ++ aufs_bindex_t bend, bindex, i; ++ unsigned char shared; ++ struct vfsmount *h_mnt; ++ struct super_block *h_sb; ++ ++ blocks = 0; ++ bfree = 0; ++ bavail = 0; ++ files = 0; ++ ffree = 0; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ for (bindex = bend; bindex >= 0; bindex--) { ++ h_mnt = au_sbr_mnt(sb, bindex); ++ h_sb = h_mnt->mnt_sb; ++ shared = 0; ++ for (i = bindex + 1; !shared && i <= bend; i++) ++ shared = (au_sbr_sb(sb, i) == h_sb); ++ if (shared) ++ continue; ++ ++ /* sb->s_root for NFS is unreliable */ ++ err = vfs_statfs(h_mnt->mnt_root, buf); ++ if (unlikely(err)) ++ goto out; ++ ++ blocks = au_add_till_max(blocks, buf->f_blocks); ++ bfree = au_add_till_max(bfree, buf->f_bfree); ++ bavail = au_add_till_max(bavail, buf->f_bavail); ++ files = au_add_till_max(files, buf->f_files); ++ ffree = au_add_till_max(ffree, buf->f_ffree); ++ } ++ ++ buf->f_blocks = blocks; ++ buf->f_bfree = bfree; ++ buf->f_bavail = bavail; ++ buf->f_files = files; ++ buf->f_ffree = ffree; ++ ++ out: ++ return err; ++} ++ ++static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ int err; ++ struct super_block *sb; ++ ++ /* lock free root dinfo */ ++ sb = dentry->d_sb; ++ si_noflush_read_lock(sb); ++ if (!au_opt_test(au_mntflags(sb), SUM)) ++ /* sb->s_root for NFS is unreliable */ ++ err = vfs_statfs(au_sbr_mnt(sb, 0)->mnt_root, buf); ++ else ++ err = au_statfs_sum(sb, buf); ++ si_read_unlock(sb); ++ ++ if (!err) { ++ buf->f_type = AUFS_SUPER_MAGIC; ++ buf->f_namelen -= AUFS_WH_PFX_LEN; ++ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); ++ } ++ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* try flushing the lower fs at aufs remount/unmount time */ ++ ++static void au_fsync_br(struct super_block *sb) ++{ ++ aufs_bindex_t bend, bindex; ++ int brperm; ++ struct au_branch *br; ++ struct super_block *h_sb; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex < bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ brperm = br->br_perm; ++ if (brperm == AuBrPerm_RR || brperm == AuBrPerm_RRWH) ++ continue; ++ h_sb = br->br_mnt->mnt_sb; ++ if (bdev_read_only(h_sb->s_bdev)) ++ continue; ++ ++ lockdep_off(); ++ down_write(&h_sb->s_umount); ++ shrink_dcache_sb(h_sb); ++ sync_filesystem(h_sb); ++ up_write(&h_sb->s_umount); ++ lockdep_on(); ++ } ++} ++ ++/* ++ * this IS NOT for super_operations. ++ * I guess it will be reverted someday. ++ */ ++static void aufs_umount_begin(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ ++ si_write_lock(sb); ++ au_fsync_br(sb); ++ if (au_opt_test(au_mntflags(sb), PLINK)) ++ au_plink_put(sb); ++ if (sbinfo->si_wbr_create_ops->fin) ++ sbinfo->si_wbr_create_ops->fin(sb); ++ si_write_unlock(sb); ++} ++ ++/* final actions when unmounting a file system */ ++static void aufs_put_super(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ ++ aufs_umount_begin(sb); ++ dbgaufs_si_fin(sbinfo); ++ kobject_put(&sbinfo->si_kobj); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * refresh dentry and inode at remount time. ++ */ ++static int do_refresh(struct dentry *dentry, mode_t type, ++ unsigned int dir_flags) ++{ ++ int err; ++ struct dentry *parent; ++ ++ di_write_lock_child(dentry); ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ ++ /* returns the number of positive dentries */ ++ err = au_refresh_hdentry(dentry, type); ++ if (err >= 0) { ++ struct inode *inode = dentry->d_inode; ++ err = au_refresh_hinode(inode, dentry); ++ if (!err && type == S_IFDIR) ++ au_reset_hinotify(inode, dir_flags); ++ } ++ if (unlikely(err)) ++ AuErr("unrecoverable error %d, %.*s\n", err, AuDLNPair(dentry)); ++ ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ di_write_unlock(dentry); ++ ++ return err; ++} ++ ++static int test_dir(struct dentry *dentry, void *arg __maybe_unused) ++{ ++ return S_ISDIR(dentry->d_inode->i_mode); ++} ++ ++/* gave up consolidating with refresh_nondir() */ ++static int refresh_dir(struct dentry *root, unsigned int sigen) ++{ ++ int err, i, j, ndentry, e; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ struct inode *inode; ++ const unsigned int flags = au_hi_flags(root->d_inode, /*isdir*/1); ++ ++ err = 0; ++ list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) ++ if (S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) { ++ ii_write_lock_child(inode); ++ e = au_refresh_hinode_self(inode, /*do_attr*/1); ++ ii_write_unlock(inode); ++ if (unlikely(e)) { ++ AuDbg("e %d, i%lu\n", e, inode->i_ino); ++ if (!err) ++ err = e; ++ /* go on even if err */ ++ } ++ } ++ ++ e = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out; ++ } ++ e = au_dcsub_pages(&dpages, root, test_dir, NULL); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out_dpages; ++ } ++ ++ for (i = 0; !e && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; !e && j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ au_dbg_verify_dir_parent(d, sigen); ++ if (au_digen(d) != sigen) { ++ e = do_refresh(d, S_IFDIR, flags); ++ if (unlikely(e && !err)) ++ err = e; ++ /* break on err */ ++ } ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return err; ++} ++ ++static int test_nondir(struct dentry *dentry, void *arg __maybe_unused) ++{ ++ return !S_ISDIR(dentry->d_inode->i_mode); ++} ++ ++static int refresh_nondir(struct dentry *root, unsigned int sigen, ++ int do_dentry) ++{ ++ int err, i, j, ndentry, e; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ struct inode *inode; ++ ++ err = 0; ++ list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) ++ if (!S_ISDIR(inode->i_mode) && au_iigen(inode) != sigen) { ++ ii_write_lock_child(inode); ++ e = au_refresh_hinode_self(inode, /*do_attr*/1); ++ ii_write_unlock(inode); ++ if (unlikely(e)) { ++ AuDbg("e %d, i%lu\n", e, inode->i_ino); ++ if (!err) ++ err = e; ++ /* go on even if err */ ++ } ++ } ++ ++ if (!do_dentry) ++ goto out; ++ ++ e = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out; ++ } ++ e = au_dcsub_pages(&dpages, root, test_nondir, NULL); ++ if (unlikely(e)) { ++ if (!err) ++ err = e; ++ goto out_dpages; ++ } ++ ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ au_dbg_verify_nondir_parent(d, sigen); ++ inode = d->d_inode; ++ if (inode && au_digen(d) != sigen) { ++ e = do_refresh(d, inode->i_mode & S_IFMT, ++ /*dir_flags*/0); ++ if (unlikely(e && !err)) ++ err = e; ++ /* go on even err */ ++ } ++ } ++ } ++ ++ out_dpages: ++ au_dpages_free(&dpages); ++ out: ++ return err; ++} ++ ++static void au_remount_refresh(struct super_block *sb, unsigned int flags) ++{ ++ int err; ++ unsigned int sigen; ++ struct au_sbinfo *sbinfo; ++ struct dentry *root; ++ struct inode *inode; ++ ++ au_sigen_inc(sb); ++ sigen = au_sigen(sb); ++ sbinfo = au_sbi(sb); ++ au_fclr_si(sbinfo, FAILED_REFRESH_DIRS); ++ ++ root = sb->s_root; ++ DiMustNoWaiters(root); ++ inode = root->d_inode; ++ IiMustNoWaiters(inode); ++ au_reset_hinotify(inode, au_hi_flags(inode, /*isdir*/1)); ++ di_write_unlock(root); ++ ++ err = refresh_dir(root, sigen); ++ if (unlikely(err)) { ++ au_fset_si(sbinfo, FAILED_REFRESH_DIRS); ++ AuWarn("Refreshing directories failed, ignored (%d)\n", err); ++ } ++ ++ if (au_ftest_opts(flags, REFRESH_NONDIR)) { ++ err = refresh_nondir(root, sigen, !err); ++ if (unlikely(err)) ++ AuWarn("Refreshing non-directories failed, ignored" ++ "(%d)\n", err); ++ } ++ ++ /* aufs_write_lock() calls ..._child() */ ++ di_write_lock_child(root); ++ au_cpup_attr_all(root->d_inode, /*force*/1); ++} ++ ++/* stop extra interpretation of errno in mount(8), and strange error messages */ ++static int cvt_err(int err) ++{ ++ AuTraceErr(err); ++ ++ switch (err) { ++ case -ENOENT: ++ case -ENOTDIR: ++ case -EEXIST: ++ case -EIO: ++ err = -EINVAL; ++ } ++ return err; ++} ++ ++static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) ++{ ++ int err; ++ struct au_opts opts; ++ struct dentry *root; ++ struct inode *inode; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ root = sb->s_root; ++ if (!data || !*data) { ++ aufs_write_lock(root); ++ err = au_opts_verify(sb, *flags, /*pending*/0); ++ if (!err) ++ au_fsync_br(sb); ++ aufs_write_unlock(root); ++ goto out; ++ } ++ ++ err = -ENOMEM; ++ memset(&opts, 0, sizeof(opts)); ++ opts.opt = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!opts.opt)) ++ goto out; ++ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); ++ opts.flags = AuOpts_REMOUNT; ++ opts.sb_flags = *flags; ++ ++ /* parse it before aufs lock */ ++ err = au_opts_parse(sb, data, &opts); ++ if (unlikely(err)) ++ goto out_opts; ++ ++ sbinfo = au_sbi(sb); ++ inode = root->d_inode; ++ mutex_lock(&inode->i_mutex); ++ aufs_write_lock(root); ++ au_fsync_br(sb); ++ ++ /* au_opts_remount() may return an error */ ++ err = au_opts_remount(sb, &opts); ++ au_opts_free(&opts); ++ ++ if (au_ftest_opts(opts.flags, REFRESH_DIR) ++ || au_ftest_opts(opts.flags, REFRESH_NONDIR)) ++ au_remount_refresh(sb, opts.flags); ++ ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ ++ out_opts: ++ free_page((unsigned long)opts.opt); ++ out: ++ err = cvt_err(err); ++ AuTraceErr(err); ++ return err; ++} ++ ++static struct super_operations aufs_sop = { ++ .alloc_inode = aufs_alloc_inode, ++ .destroy_inode = aufs_destroy_inode, ++ .drop_inode = generic_delete_inode, ++ .show_options = aufs_show_options, ++ .statfs = aufs_statfs, ++ .put_super = aufs_put_super, ++ .remount_fs = aufs_remount_fs ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int alloc_root(struct super_block *sb) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *root; ++ ++ err = -ENOMEM; ++ inode = au_iget_locked(sb, AUFS_ROOT_INO); ++ err = PTR_ERR(inode); ++ if (IS_ERR(inode)) ++ goto out; ++ ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ inode->i_mode = S_IFDIR; ++ inode->i_nlink = 2; ++ unlock_new_inode(inode); ++ ++ root = d_alloc_root(inode); ++ if (unlikely(!root)) ++ goto out_iput; ++ err = PTR_ERR(root); ++ if (IS_ERR(root)) ++ goto out_iput; ++ ++ err = au_alloc_dinfo(root); ++ if (!err) { ++ sb->s_root = root; ++ return 0; /* success */ ++ } ++ dput(root); ++ goto out; /* do not iput */ ++ ++ out_iput: ++ iget_failed(inode); ++ iput(inode); ++ out: ++ return err; ++ ++} ++ ++static int aufs_fill_super(struct super_block *sb, void *raw_data, ++ int silent __maybe_unused) ++{ ++ int err; ++ struct au_opts opts; ++ struct dentry *root; ++ struct inode *inode; ++ char *arg = raw_data; ++ ++ if (unlikely(!arg || !*arg)) { ++ err = -EINVAL; ++ AuErr("no arg\n"); ++ goto out; ++ } ++ ++ err = -ENOMEM; ++ memset(&opts, 0, sizeof(opts)); ++ opts.opt = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!opts.opt)) ++ goto out; ++ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); ++ opts.sb_flags = sb->s_flags; ++ ++ err = au_si_alloc(sb); ++ if (unlikely(err)) ++ goto out_opts; ++ ++ /* all timestamps always follow the ones on the branch */ ++ sb->s_flags |= MS_NOATIME | MS_NODIRATIME; ++ sb->s_op = &aufs_sop; ++ sb->s_magic = AUFS_SUPER_MAGIC; ++ sb->s_maxbytes = 0; ++ au_export_init(sb); ++ ++ err = alloc_root(sb); ++ if (unlikely(err)) { ++ si_write_unlock(sb); ++ goto out_info; ++ } ++ root = sb->s_root; ++ inode = root->d_inode; ++ ++ /* ++ * actually we can parse options regardless aufs lock here. ++ * but at remount time, parsing must be done before aufs lock. ++ * so we follow the same rule. ++ */ ++ ii_write_lock_parent(inode); ++ aufs_write_unlock(root); ++ err = au_opts_parse(sb, arg, &opts); ++ if (unlikely(err)) ++ goto out_root; ++ ++ /* lock vfs_inode first, then aufs. */ ++ mutex_lock(&inode->i_mutex); ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ aufs_write_lock(root); ++ err = au_opts_mount(sb, &opts); ++ au_opts_free(&opts); ++ if (unlikely(err)) ++ goto out_unlock; ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ goto out_opts; /* success */ ++ ++ out_unlock: ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ out_root: ++ dput(root); ++ sb->s_root = NULL; ++ out_info: ++ kobject_put(&au_sbi(sb)->si_kobj); ++ sb->s_fs_info = NULL; ++ out_opts: ++ free_page((unsigned long)opts.opt); ++ out: ++ AuTraceErr(err); ++ err = cvt_err(err); ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_get_sb(struct file_system_type *fs_type, int flags, ++ const char *dev_name __maybe_unused, void *raw_data, ++ struct vfsmount *mnt) ++{ ++ int err; ++ struct super_block *sb; ++ ++ /* all timestamps always follow the ones on the branch */ ++ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ ++ err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt); ++ if (!err) { ++ sb = mnt->mnt_sb; ++ si_write_lock(sb); ++ sysaufs_brs_add(sb, 0); ++ si_write_unlock(sb); ++ } ++ return err; ++} ++ ++struct file_system_type aufs_fs_type = { ++ .name = AUFS_FSTYPE, ++ .fs_flags = ++ FS_RENAME_DOES_D_MOVE /* a race between rename and others */ ++ | FS_REVAL_DOT, /* for NFS branch and udba */ ++ .get_sb = aufs_get_sb, ++ .kill_sb = generic_shutdown_super, ++ /* no need to __module_get() and module_put(). */ ++ .owner = THIS_MODULE, ++}; +diff -Nur linux-2.6.31-vanilla/fs/aufs/super.h linux-2.6.31/fs/aufs/super.h +--- linux-2.6.31-vanilla/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/super.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,384 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * super_block operations ++ */ ++ ++#ifndef __AUFS_SUPER_H__ ++#define __AUFS_SUPER_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/fs.h> ++#include <linux/aufs_type.h> ++#include "rwsem.h" ++#include "spl.h" ++#include "wkq.h" ++ ++typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *); ++typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t, ++ loff_t *); ++ ++/* policies to select one among multiple writable branches */ ++struct au_wbr_copyup_operations { ++ int (*copyup)(struct dentry *dentry); ++}; ++ ++struct au_wbr_create_operations { ++ int (*create)(struct dentry *dentry, int isdir); ++ int (*init)(struct super_block *sb); ++ int (*fin)(struct super_block *sb); ++}; ++ ++struct au_wbr_mfs { ++ struct mutex mfs_lock; /* protect this structure */ ++ unsigned long mfs_jiffy; ++ unsigned long mfs_expire; ++ aufs_bindex_t mfs_bindex; ++ ++ unsigned long long mfsrr_bytes; ++ unsigned long long mfsrr_watermark; ++}; ++ ++struct au_branch; ++struct au_sbinfo { ++ /* nowait tasks in the system-wide workqueue */ ++ struct au_nowait_tasks si_nowait; ++ ++ struct au_rwsem si_rwsem; ++ ++ /* branch management */ ++ unsigned int si_generation; ++ ++ /* see above flags */ ++ unsigned char au_si_status; ++ ++ aufs_bindex_t si_bend; ++ aufs_bindex_t si_last_br_id; ++ struct au_branch **si_branch; ++ ++ /* policy to select a writable branch */ ++ unsigned char si_wbr_copyup; ++ unsigned char si_wbr_create; ++ struct au_wbr_copyup_operations *si_wbr_copyup_ops; ++ struct au_wbr_create_operations *si_wbr_create_ops; ++ ++ /* round robin */ ++ atomic_t si_wbr_rr_next; ++ ++ /* most free space */ ++ struct au_wbr_mfs si_wbr_mfs; ++ ++ /* mount flags */ ++ /* include/asm-ia64/siginfo.h defines a macro named si_flags */ ++ unsigned int si_mntflags; ++ ++ /* external inode number (bitmap and translation table) */ ++ au_readf_t si_xread; ++ au_writef_t si_xwrite; ++ struct file *si_xib; ++ struct mutex si_xib_mtx; /* protect xib members */ ++ unsigned long *si_xib_buf; ++ unsigned long si_xib_last_pindex; ++ int si_xib_next_bit; ++ aufs_bindex_t si_xino_brid; ++ /* reserved for future use */ ++ /* unsigned long long si_xib_limit; */ /* Max xib file size */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++ /* i_generation */ ++ struct file *si_xigen; ++ atomic_t si_xigen_next; ++#endif ++ ++ /* vdir parameters */ ++ unsigned long si_rdcache; /* max cache time in HZ */ ++ unsigned int si_rdblk; /* deblk size */ ++ unsigned int si_rdhash; /* hash size */ ++ ++ /* ++ * If the number of whiteouts are larger than si_dirwh, leave all of ++ * them after au_whtmp_ren to reduce the cost of rmdir(2). ++ * future fsck.aufs or kernel thread will remove them later. ++ * Otherwise, remove all whiteouts and the dir in rmdir(2). ++ */ ++ unsigned int si_dirwh; ++ ++ /* ++ * rename(2) a directory with all children. ++ */ ++ /* reserved for future use */ ++ /* int si_rendir; */ ++ ++ /* pseudo_link list */ ++ struct au_splhead si_plink; ++ wait_queue_head_t si_plink_wq; ++ ++ /* ++ * sysfs and lifetime management. ++ * this is not a small structure and it may be a waste of memory in case ++ * of sysfs is disabled, particulary when many aufs-es are mounted. ++ * but using sysfs is majority. ++ */ ++ struct kobject si_kobj; ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *si_dbgaufs, *si_dbgaufs_xib; ++#ifdef CONFIG_AUFS_EXPORT ++ struct dentry *si_dbgaufs_xigen; ++#endif ++#endif ++ ++ /* dirty, necessary for unmounting, sysfs and sysrq */ ++ struct super_block *si_sb; ++}; ++ ++/* sbinfo status flags */ ++/* ++ * set true when refresh_dirs() failed at remount time. ++ * then try refreshing dirs at access time again. ++ * if it is false, refreshing dirs at access time is unnecesary ++ */ ++#define AuSi_FAILED_REFRESH_DIRS 1 ++#define AuSi_MAINTAIN_PLINK (1 << 1) /* ioctl */ ++static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi, ++ unsigned int flag) ++{ ++ AuRwMustAnyLock(&sbi->si_rwsem); ++ return sbi->au_si_status & flag; ++} ++#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name) ++#define au_fset_si(sbinfo, name) do { \ ++ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ ++ (sbinfo)->au_si_status |= AuSi_##name; \ ++} while (0) ++#define au_fclr_si(sbinfo, name) do { \ ++ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ ++ (sbinfo)->au_si_status &= ~AuSi_##name; \ ++} while (0) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policy to select one among writable branches */ ++#define AuWbrCopyup(sbinfo, args...) \ ++ ((sbinfo)->si_wbr_copyup_ops->copyup(args)) ++#define AuWbrCreate(sbinfo, args...) \ ++ ((sbinfo)->si_wbr_create_ops->create(args)) ++ ++/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ ++#define AuLock_DW 1 /* write-lock dentry */ ++#define AuLock_IR (1 << 1) /* read-lock inode */ ++#define AuLock_IW (1 << 2) /* write-lock inode */ ++#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ ++#define AuLock_DIR (1 << 4) /* target is a dir */ ++#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) ++#define au_fset_lock(flags, name) { (flags) |= AuLock_##name; } ++#define au_fclr_lock(flags, name) { (flags) &= ~AuLock_##name; } ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* super.c */ ++extern struct file_system_type aufs_fs_type; ++struct inode *au_iget_locked(struct super_block *sb, ino_t ino); ++ ++/* sbinfo.c */ ++void au_si_free(struct kobject *kobj); ++int au_si_alloc(struct super_block *sb); ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr); ++ ++unsigned int au_sigen_inc(struct super_block *sb); ++aufs_bindex_t au_new_br_id(struct super_block *sb); ++ ++void aufs_read_lock(struct dentry *dentry, int flags); ++void aufs_read_unlock(struct dentry *dentry, int flags); ++void aufs_write_lock(struct dentry *dentry); ++void aufs_write_unlock(struct dentry *dentry); ++void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int isdir); ++void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); ++ ++/* wbr_policy.c */ ++extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; ++extern struct au_wbr_create_operations au_wbr_create_ops[]; ++int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_sbinfo *au_sbi(struct super_block *sb) ++{ ++ return sb->s_fs_info; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++void au_export_init(struct super_block *sb); ++ ++static inline int au_test_nfsd(struct task_struct *tsk) ++{ ++ return !tsk->mm && !strcmp(tsk->comm, "nfsd"); ++} ++ ++int au_xigen_inc(struct inode *inode); ++int au_xigen_new(struct inode *inode); ++int au_xigen_set(struct super_block *sb, struct file *base); ++void au_xigen_clr(struct super_block *sb); ++ ++static inline int au_busy_or_stale(void) ++{ ++ if (!au_test_nfsd(current)) ++ return -EBUSY; ++ return -ESTALE; ++} ++#else ++static inline void au_export_init(struct super_block *sb) ++{ ++ /* nothing */ ++} ++ ++static inline int au_test_nfsd(struct task_struct *tsk) ++{ ++ return 0; ++} ++ ++static inline int au_xigen_inc(struct inode *inode) ++{ ++ return 0; ++} ++ ++static inline int au_xigen_new(struct inode *inode) ++{ ++ return 0; ++} ++ ++static inline int au_xigen_set(struct super_block *sb, struct file *base) ++{ ++ return 0; ++} ++ ++static inline void au_xigen_clr(struct super_block *sb) ++{ ++ /* empty */ ++} ++ ++static inline int au_busy_or_stale(void) ++{ ++ return -EBUSY; ++} ++#endif /* CONFIG_AUFS_EXPORT */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo) ++{ ++ /* ++ * This function is a dynamic '__init' fucntion actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++#ifdef CONFIG_DEBUG_FS ++ sbinfo->si_dbgaufs = NULL; ++ sbinfo->si_dbgaufs_xib = NULL; ++#ifdef CONFIG_AUFS_EXPORT ++ sbinfo->si_dbgaufs_xigen = NULL; ++#endif ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock superblock. mainly for entry point functions */ ++/* ++ * si_noflush_read_lock, si_noflush_write_lock, ++ * si_read_unlock, si_write_unlock, si_downgrade_lock ++ */ ++AuSimpleLockRwsemFuncs(si_noflush, struct super_block *sb, ++ &au_sbi(sb)->si_rwsem); ++AuSimpleUnlockRwsemFuncs(si, struct super_block *sb, &au_sbi(sb)->si_rwsem); ++ ++#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem) ++#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem) ++#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem) ++ ++static inline void si_read_lock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ si_noflush_read_lock(sb); ++} ++ ++static inline void si_write_lock(struct super_block *sb) ++{ ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ si_noflush_write_lock(sb); ++} ++ ++static inline int si_read_trylock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ return si_noflush_read_trylock(sb); ++} ++ ++static inline int si_write_trylock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ return si_noflush_write_trylock(sb); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline aufs_bindex_t au_sbend(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_bend; ++} ++ ++static inline unsigned int au_mntflags(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_mntflags; ++} ++ ++static inline unsigned int au_sigen(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_generation; ++} ++ ++static inline struct au_branch *au_sbr(struct super_block *sb, ++ aufs_bindex_t bindex) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_branch[0 + bindex]; ++} ++ ++static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid) ++{ ++ SiMustWriteLock(sb); ++ au_sbi(sb)->si_xino_brid = brid; ++} ++ ++static inline aufs_bindex_t au_xino_brid(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_xino_brid; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_SUPER_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/sysaufs.c linux-2.6.31/fs/aufs/sysaufs.c +--- linux-2.6.31-vanilla/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/sysaufs.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * sysfs interface and lifetime management ++ * they are necessary regardless sysfs is disabled. ++ */ ++ ++#include <linux/fs.h> ++#include <linux/random.h> ++#include <linux/sysfs.h> ++#include "aufs.h" ++ ++unsigned long sysaufs_si_mask; ++struct kset *sysaufs_ket; ++ ++#define AuSiAttr(_name) { \ ++ .attr = { .name = __stringify(_name), .mode = 0444 }, \ ++ .show = sysaufs_si_##_name, \ ++} ++ ++static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path); ++struct attribute *sysaufs_si_attrs[] = { ++ &sysaufs_si_attr_xi_path.attr, ++ NULL, ++}; ++ ++static struct sysfs_ops au_sbi_ops = { ++ .show = sysaufs_si_show ++}; ++ ++static struct kobj_type au_sbi_ktype = { ++ .release = au_si_free, ++ .sysfs_ops = &au_sbi_ops, ++ .default_attrs = sysaufs_si_attrs ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int sysaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ ++ sbinfo->si_kobj.kset = sysaufs_ket; ++ /* cf. sysaufs_name() */ ++ err = kobject_init_and_add ++ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_ket->kobj*/NULL, ++ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo)); ++ ++ dbgaufs_si_null(sbinfo); ++ if (!err) { ++ err = dbgaufs_si_init(sbinfo); ++ if (unlikely(err)) ++ kobject_put(&sbinfo->si_kobj); ++ } ++ return err; ++} ++ ++void sysaufs_fin(void) ++{ ++ dbgaufs_fin(); ++ sysfs_remove_group(&sysaufs_ket->kobj, sysaufs_attr_group); ++ kset_unregister(sysaufs_ket); ++} ++ ++int __init sysaufs_init(void) ++{ ++ int err; ++ ++ do { ++ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask)); ++ } while (!sysaufs_si_mask); ++ ++ sysaufs_ket = kset_create_and_add(AUFS_NAME, NULL, fs_kobj); ++ err = PTR_ERR(sysaufs_ket); ++ if (IS_ERR(sysaufs_ket)) ++ goto out; ++ err = sysfs_create_group(&sysaufs_ket->kobj, sysaufs_attr_group); ++ if (unlikely(err)) { ++ kset_unregister(sysaufs_ket); ++ goto out; ++ } ++ ++ err = dbgaufs_init(); ++ if (unlikely(err)) ++ sysaufs_fin(); ++ out: ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/sysaufs.h linux-2.6.31/fs/aufs/sysaufs.h +--- linux-2.6.31-vanilla/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/sysaufs.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,120 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * sysfs interface and mount lifetime management ++ */ ++ ++#ifndef __SYSAUFS_H__ ++#define __SYSAUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/sysfs.h> ++#include <linux/aufs_type.h> ++#include "module.h" ++ ++struct super_block; ++struct au_sbinfo; ++ ++struct sysaufs_si_attr { ++ struct attribute attr; ++ int (*show)(struct seq_file *seq, struct super_block *sb); ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* sysaufs.c */ ++extern unsigned long sysaufs_si_mask; ++extern struct kset *sysaufs_ket; ++extern struct attribute *sysaufs_si_attrs[]; ++int sysaufs_si_init(struct au_sbinfo *sbinfo); ++int __init sysaufs_init(void); ++void sysaufs_fin(void); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* some people doesn't like to show a pointer in kernel */ ++static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo) ++{ ++ return sysaufs_si_mask ^ (unsigned long)sbinfo; ++} ++ ++#define SysaufsSiNamePrefix "si_" ++#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16) ++static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name) ++{ ++ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx", ++ sysaufs_si_id(sbinfo)); ++} ++ ++struct au_branch; ++#ifdef CONFIG_SYSFS ++/* sysfs.c */ ++extern struct attribute_group *sysaufs_attr_group; ++ ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb); ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf); ++ ++void sysaufs_br_init(struct au_branch *br); ++void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); ++void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); ++ ++#define sysaufs_brs_init() do {} while (0) ++ ++#else ++#define sysaufs_attr_group NULL ++ ++static inline ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) ++{ ++ return 0; ++} ++ ++static inline ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf) ++{ ++ return 0; ++} ++ ++static inline void sysaufs_br_init(struct au_branch *br) ++{ ++ /* empty */ ++} ++ ++static inline void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* nothing */ ++} ++ ++static inline void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ /* nothing */ ++} ++ ++static inline void sysaufs_brs_init(void) ++{ ++ sysaufs_brs = 0; ++} ++ ++#endif /* CONFIG_SYSFS */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __SYSAUFS_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/sysfs.c linux-2.6.31/fs/aufs/sysfs.c +--- linux-2.6.31-vanilla/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/sysfs.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,210 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * sysfs interface ++ */ ++ ++#include <linux/fs.h> ++#include <linux/module.h> ++#include <linux/seq_file.h> ++#include <linux/sysfs.h> ++#include "aufs.h" ++ ++static struct attribute *au_attr[] = { ++ NULL, /* need to NULL terminate the list of attributes */ ++}; ++ ++static struct attribute_group sysaufs_attr_group_body = { ++ .attrs = au_attr ++}; ++ ++struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) ++{ ++ int err; ++ ++ SiMustAnyLock(sb); ++ ++ err = 0; ++ if (au_opt_test(au_mntflags(sb), XINO)) { ++ err = au_xino_path(seq, au_sbi(sb)->si_xib); ++ seq_putc(seq, '\n'); ++ } ++ return err; ++} ++ ++/* ++ * the lifetime of branch is independent from the entry under sysfs. ++ * sysfs handles the lifetime of the entry, and never call ->show() after it is ++ * unlinked. ++ */ ++static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb, ++ aufs_bindex_t bindex) ++{ ++ struct path path; ++ struct dentry *root; ++ struct au_branch *br; ++ ++ AuDbg("b%d\n", bindex); ++ ++ root = sb->s_root; ++ di_read_lock_parent(root, !AuLock_IR); ++ br = au_sbr(sb, bindex); ++ path.mnt = br->br_mnt; ++ path.dentry = au_h_dptr(root, bindex); ++ au_seq_path(seq, &path); ++ di_read_unlock(root, !AuLock_IR); ++ seq_printf(seq, "=%s\n", au_optstr_br_perm(br->br_perm)); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct seq_file *au_seq(char *p, ssize_t len) ++{ ++ struct seq_file *seq; ++ ++ seq = kzalloc(sizeof(*seq), GFP_NOFS); ++ if (seq) { ++ /* mutex_init(&seq.lock); */ ++ seq->buf = p; ++ seq->size = len; ++ return seq; /* success */ ++ } ++ ++ seq = ERR_PTR(-ENOMEM); ++ return seq; ++} ++ ++#define SysaufsBr_PREFIX "br" ++ ++/* todo: file size may exceed PAGE_SIZE */ ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf) ++{ ++ ssize_t err; ++ long l; ++ aufs_bindex_t bend; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ struct seq_file *seq; ++ char *name; ++ struct attribute **cattr; ++ ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ ++ seq = au_seq(buf, PAGE_SIZE); ++ err = PTR_ERR(seq); ++ if (IS_ERR(seq)) ++ goto out; ++ ++ name = (void *)attr->name; ++ cattr = sysaufs_si_attrs; ++ while (*cattr) { ++ if (!strcmp(name, (*cattr)->name)) { ++ err = container_of(*cattr, struct sysaufs_si_attr, attr) ++ ->show(seq, sb); ++ goto out_seq; ++ } ++ cattr++; ++ } ++ ++ bend = au_sbend(sb); ++ if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) { ++ name += sizeof(SysaufsBr_PREFIX) - 1; ++ err = strict_strtol(name, 10, &l); ++ if (!err) { ++ if (l <= bend) ++ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l); ++ else ++ err = -ENOENT; ++ } ++ goto out_seq; ++ } ++ BUG(); ++ ++ out_seq: ++ if (!err) { ++ err = seq->count; ++ /* sysfs limit */ ++ if (unlikely(err == PAGE_SIZE)) ++ err = -EFBIG; ++ } ++ kfree(seq); ++ out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void sysaufs_br_init(struct au_branch *br) ++{ ++ br->br_attr.name = br->br_name; ++ br->br_attr.mode = S_IRUGO; ++ br->br_attr.owner = THIS_MODULE; ++} ++ ++void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ struct au_branch *br; ++ struct kobject *kobj; ++ aufs_bindex_t bend; ++ ++ dbgaufs_brs_del(sb, bindex); ++ ++ if (!sysaufs_brs) ++ return; ++ ++ kobj = &au_sbi(sb)->si_kobj; ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ sysfs_remove_file(kobj, &br->br_attr); ++ } ++} ++ ++void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ aufs_bindex_t bend; ++ struct kobject *kobj; ++ struct au_branch *br; ++ ++ dbgaufs_brs_add(sb, bindex); ++ ++ if (!sysaufs_brs) ++ return; ++ ++ kobj = &au_sbi(sb)->si_kobj; ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ snprintf(br->br_name, sizeof(br->br_name), SysaufsBr_PREFIX ++ "%d", bindex); ++ err = sysfs_create_file(kobj, &br->br_attr); ++ if (unlikely(err)) ++ AuWarn("failed %s under sysfs(%d)\n", br->br_name, err); ++ } ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/sysrq.c linux-2.6.31/fs/aufs/sysrq.c +--- linux-2.6.31-vanilla/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/sysrq.c 2009-09-16 13:55:29.000000000 +0200 +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * magic sysrq hanlder ++ */ ++ ++#include <linux/fs.h> ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++/* #include <linux/sysrq.h> */ ++#include "aufs.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void sysrq_sb(struct super_block *sb) ++{ ++ char *plevel; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ plevel = au_plevel; ++ au_plevel = KERN_WARNING; ++ au_debug(1); ++ ++ sbinfo = au_sbi(sb); ++ pr_warning("si=%lx\n", sysaufs_si_id(sbinfo)); ++ pr_warning(AUFS_NAME ": superblock\n"); ++ au_dpri_sb(sb); ++ pr_warning(AUFS_NAME ": root dentry\n"); ++ au_dpri_dentry(sb->s_root); ++ pr_warning(AUFS_NAME ": root inode\n"); ++ au_dpri_inode(sb->s_root->d_inode); ++#if 0 ++ struct inode *i; ++ pr_warning(AUFS_NAME ": isolated inode\n"); ++ list_for_each_entry(i, &sb->s_inodes, i_sb_list) ++ if (list_empty(&i->i_dentry)) ++ au_dpri_inode(i); ++#endif ++ pr_warning(AUFS_NAME ": files\n"); ++ list_for_each_entry(file, &sb->s_files, f_u.fu_list) ++ if (!special_file(file->f_dentry->d_inode->i_mode)) ++ au_dpri_file(file); ++ ++ au_plevel = plevel; ++ au_debug(0); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* module parameter */ ++static char *aufs_sysrq_key = "a"; ++module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO); ++MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME); ++ ++static void au_sysrq(int key __maybe_unused, ++ struct tty_struct *tty __maybe_unused) ++{ ++ struct kobject *kobj; ++ struct au_sbinfo *sbinfo; ++ ++ /* spin_lock(&sysaufs_ket->list_lock); */ ++ list_for_each_entry(kobj, &sysaufs_ket->list, entry) { ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ sysrq_sb(sbinfo->si_sb); ++ } ++ /* spin_unlock(&sysaufs_ket->list_lock); */ ++} ++ ++static struct sysrq_key_op au_sysrq_op = { ++ .handler = au_sysrq, ++ .help_msg = "Aufs", ++ .action_msg = "Aufs", ++ .enable_mask = SYSRQ_ENABLE_DUMP ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int __init au_sysrq_init(void) ++{ ++ int err; ++ char key; ++ ++ err = -1; ++ key = *aufs_sysrq_key; ++ if ('a' <= key && key <= 'z') ++ err = register_sysrq_key(key, &au_sysrq_op); ++ if (unlikely(err)) ++ AuErr("err %d, sysrq=%c\n", err, key); ++ return err; ++} ++ ++void au_sysrq_fin(void) ++{ ++ int err; ++ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op); ++ if (unlikely(err)) ++ AuErr("err %d (ignored)\n", err); ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/vdir.c linux-2.6.31/fs/aufs/vdir.c +--- linux-2.6.31-vanilla/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/vdir.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,879 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * virtual or vertical directory ++ */ ++ ++#include <linux/hash.h> ++#include "aufs.h" ++ ++static unsigned int calc_size(int nlen) ++{ ++ BUILD_BUG_ON(sizeof(ino_t) != sizeof(long)); ++ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t)); ++} ++ ++static int set_deblk_end(union au_vdir_deblk_p *p, ++ union au_vdir_deblk_p *deblk_end) ++{ ++ if (calc_size(0) <= deblk_end->deblk - p->deblk) { ++ p->de->de_str.len = 0; ++ /* smp_mb(); */ ++ return 0; ++ } ++ return -1; /* error */ ++} ++ ++/* returns true or false */ ++static int is_deblk_end(union au_vdir_deblk_p *p, ++ union au_vdir_deblk_p *deblk_end) ++{ ++ if (calc_size(0) <= deblk_end->deblk - p->deblk) ++ return !p->de->de_str.len; ++ return 1; ++} ++ ++static unsigned char *last_deblk(struct au_vdir *vdir) ++{ ++ return vdir->vd_deblk[vdir->vd_nblk - 1]; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* estimate the apropriate size for name hash table */ ++unsigned int au_rdhash_est(loff_t sz) ++{ ++ unsigned int n; ++ ++ n = UINT_MAX; ++ sz >>= 10; ++ if (sz < n) ++ n = sz; ++ if (sz < AUFS_RDHASH_DEF) ++ n = AUFS_RDHASH_DEF; ++ /* AuInfo("n %u\n", n); */ ++ return n; ++} ++ ++/* ++ * the allocated memory has to be freed by ++ * au_nhash_wh_free() or au_nhash_de_free(). ++ */ ++int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp) ++{ ++ struct hlist_head *head; ++ unsigned int u; ++ ++ head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp); ++ if (head) { ++ nhash->nh_num = num_hash; ++ nhash->nh_head = head; ++ for (u = 0; u < num_hash; u++) ++ INIT_HLIST_HEAD(head++); ++ return 0; /* success */ ++ } ++ ++ return -ENOMEM; ++} ++ ++static void nhash_count(struct hlist_head *head) ++{ ++#if 0 ++ unsigned long n; ++ struct hlist_node *pos; ++ ++ n = 0; ++ hlist_for_each(pos, head) ++ n++; ++ AuInfo("%lu\n", n); ++#endif ++} ++ ++static void au_nhash_wh_do_free(struct hlist_head *head) ++{ ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos, *node; ++ ++ hlist_for_each_entry_safe(tpos, pos, node, head, wh_hash) { ++ /* hlist_del(pos); */ ++ kfree(tpos); ++ } ++} ++ ++static void au_nhash_de_do_free(struct hlist_head *head) ++{ ++ struct au_vdir_dehstr *tpos; ++ struct hlist_node *pos, *node; ++ ++ hlist_for_each_entry_safe(tpos, pos, node, head, hash) { ++ /* hlist_del(pos); */ ++ au_cache_free_dehstr(tpos); ++ } ++} ++ ++static void au_nhash_do_free(struct au_nhash *nhash, ++ void (*free)(struct hlist_head *head)) ++{ ++ unsigned int n; ++ struct hlist_head *head; ++ ++ n = nhash->nh_num; ++ if (!n) ++ return; ++ ++ head = nhash->nh_head; ++ while (n-- > 0) { ++ nhash_count(head); ++ free(head++); ++ } ++ kfree(nhash->nh_head); ++} ++ ++void au_nhash_wh_free(struct au_nhash *whlist) ++{ ++ au_nhash_do_free(whlist, au_nhash_wh_do_free); ++} ++ ++static void au_nhash_de_free(struct au_nhash *delist) ++{ ++ au_nhash_do_free(delist, au_nhash_de_do_free); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, ++ int limit) ++{ ++ int num; ++ unsigned int u, n; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ ++ num = 0; ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (u = 0; u < n; u++, head++) ++ hlist_for_each_entry(tpos, pos, head, wh_hash) ++ if (tpos->wh_bindex == btgt && ++num > limit) ++ return 1; ++ return 0; ++} ++ ++static struct hlist_head *au_name_hash(struct au_nhash *nhash, ++ unsigned char *name, ++ unsigned int len) ++{ ++ unsigned int v; ++ /* const unsigned int magic_bit = 12; */ ++ ++ AuDebugOn(!nhash->nh_num || !nhash->nh_head); ++ ++ v = 0; ++ while (len--) ++ v += *name++; ++ /* v = hash_long(v, magic_bit); */ ++ v %= nhash->nh_num; ++ return nhash->nh_head + v; ++} ++ ++static int au_nhash_test_name(struct au_vdir_destr *str, const char *name, ++ int nlen) ++{ ++ return str->len == nlen && !memcmp(str->name, name, nlen); ++} ++ ++/* returns found or not */ ++int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen) ++{ ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ struct au_vdir_destr *str; ++ ++ head = au_name_hash(whlist, name, nlen); ++ hlist_for_each_entry(tpos, pos, head, wh_hash) { ++ str = &tpos->wh_str; ++ AuDbg("%.*s\n", str->len, str->name); ++ if (au_nhash_test_name(str, name, nlen)) ++ return 1; ++ } ++ return 0; ++} ++ ++/* returns found(true) or not */ ++static int test_known(struct au_nhash *delist, char *name, int nlen) ++{ ++ struct hlist_head *head; ++ struct au_vdir_dehstr *tpos; ++ struct hlist_node *pos; ++ struct au_vdir_destr *str; ++ ++ head = au_name_hash(delist, name, nlen); ++ hlist_for_each_entry(tpos, pos, head, hash) { ++ str = tpos->str; ++ AuDbg("%.*s\n", str->len, str->name); ++ if (au_nhash_test_name(str, name, nlen)) ++ return 1; ++ } ++ return 0; ++} ++ ++static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino, ++ unsigned char d_type) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ wh->wh_ino = ino; ++ wh->wh_type = d_type; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, ++ unsigned int d_type, aufs_bindex_t bindex, ++ unsigned char shwh) ++{ ++ int err; ++ struct au_vdir_destr *str; ++ struct au_vdir_wh *wh; ++ ++ AuDbg("%.*s\n", nlen, name); ++ AuDebugOn(!whlist->nh_num || !whlist->nh_head); ++ ++ err = -ENOMEM; ++ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS); ++ if (unlikely(!wh)) ++ goto out; ++ ++ err = 0; ++ wh->wh_bindex = bindex; ++ if (shwh) ++ au_shwh_init_wh(wh, ino, d_type); ++ str = &wh->wh_str; ++ str->len = nlen; ++ memcpy(str->name, name, nlen); ++ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen)); ++ /* smp_mb(); */ ++ ++ out: ++ return err; ++} ++ ++static int append_deblk(struct au_vdir *vdir) ++{ ++ int err; ++ unsigned long ul; ++ const unsigned int deblk_sz = vdir->vd_deblk_sz; ++ union au_vdir_deblk_p p, deblk_end; ++ unsigned char **o; ++ ++ err = -ENOMEM; ++ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), ++ GFP_NOFS); ++ if (unlikely(!o)) ++ goto out; ++ ++ vdir->vd_deblk = o; ++ p.deblk = kmalloc(deblk_sz, GFP_NOFS); ++ if (p.deblk) { ++ ul = vdir->vd_nblk++; ++ vdir->vd_deblk[ul] = p.deblk; ++ vdir->vd_last.ul = ul; ++ vdir->vd_last.p.deblk = p.deblk; ++ deblk_end.deblk = p.deblk + deblk_sz; ++ err = set_deblk_end(&p, &deblk_end); ++ } ++ ++ out: ++ return err; ++} ++ ++static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino, ++ unsigned int d_type, struct au_nhash *delist) ++{ ++ int err; ++ unsigned int sz; ++ const unsigned int deblk_sz = vdir->vd_deblk_sz; ++ union au_vdir_deblk_p p, *room, deblk_end; ++ struct au_vdir_dehstr *dehstr; ++ ++ p.deblk = last_deblk(vdir); ++ deblk_end.deblk = p.deblk + deblk_sz; ++ room = &vdir->vd_last.p; ++ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk ++ || !is_deblk_end(room, &deblk_end)); ++ ++ sz = calc_size(nlen); ++ if (unlikely(sz > deblk_end.deblk - room->deblk)) { ++ err = append_deblk(vdir); ++ if (unlikely(err)) ++ goto out; ++ ++ p.deblk = last_deblk(vdir); ++ deblk_end.deblk = p.deblk + deblk_sz; ++ /* smp_mb(); */ ++ AuDebugOn(room->deblk != p.deblk); ++ } ++ ++ err = -ENOMEM; ++ dehstr = au_cache_alloc_dehstr(); ++ if (unlikely(!dehstr)) ++ goto out; ++ ++ dehstr->str = &room->de->de_str; ++ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen)); ++ room->de->de_ino = ino; ++ room->de->de_type = d_type; ++ room->de->de_str.len = nlen; ++ memcpy(room->de->de_str.name, name, nlen); ++ ++ err = 0; ++ room->deblk += sz; ++ if (unlikely(set_deblk_end(room, &deblk_end))) ++ err = append_deblk(vdir); ++ /* smp_mb(); */ ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_vdir_free(struct au_vdir *vdir) ++{ ++ unsigned char **deblk; ++ ++ deblk = vdir->vd_deblk; ++ while (vdir->vd_nblk--) ++ kfree(*deblk++); ++ kfree(vdir->vd_deblk); ++ au_cache_free_vdir(vdir); ++} ++ ++static struct au_vdir *alloc_vdir(struct file *file) ++{ ++ struct au_vdir *vdir; ++ struct super_block *sb; ++ int err; ++ ++ sb = file->f_dentry->d_sb; ++ SiMustAnyLock(sb); ++ ++ err = -ENOMEM; ++ vdir = au_cache_alloc_vdir(); ++ if (unlikely(!vdir)) ++ goto out; ++ ++ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS); ++ if (unlikely(!vdir->vd_deblk)) ++ goto out_free; ++ ++ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk; ++ if (!vdir->vd_deblk_sz) { ++ /* estimate the apropriate size for deblk */ ++ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL); ++ /* AuInfo("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */ ++ } ++ vdir->vd_nblk = 0; ++ vdir->vd_version = 0; ++ vdir->vd_jiffy = 0; ++ err = append_deblk(vdir); ++ if (!err) ++ return vdir; /* success */ ++ ++ kfree(vdir->vd_deblk); ++ ++ out_free: ++ au_cache_free_vdir(vdir); ++ out: ++ vdir = ERR_PTR(err); ++ return vdir; ++} ++ ++static int reinit_vdir(struct au_vdir *vdir) ++{ ++ int err; ++ union au_vdir_deblk_p p, deblk_end; ++ ++ while (vdir->vd_nblk > 1) { ++ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); ++ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ ++ vdir->vd_nblk--; ++ } ++ p.deblk = vdir->vd_deblk[0]; ++ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz; ++ err = set_deblk_end(&p, &deblk_end); ++ /* keep vd_dblk_sz */ ++ vdir->vd_last.ul = 0; ++ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; ++ vdir->vd_version = 0; ++ vdir->vd_jiffy = 0; ++ /* smp_mb(); */ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuFillVdir_CALLED 1 ++#define AuFillVdir_WHABLE (1 << 1) ++#define AuFillVdir_SHWH (1 << 2) ++#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) ++#define au_fset_fillvdir(flags, name) { (flags) |= AuFillVdir_##name; } ++#define au_fclr_fillvdir(flags, name) { (flags) &= ~AuFillVdir_##name; } ++ ++#ifndef CONFIG_AUFS_SHWH ++#undef AuFillVdir_SHWH ++#define AuFillVdir_SHWH 0 ++#endif ++ ++struct fillvdir_arg { ++ struct file *file; ++ struct au_vdir *vdir; ++ struct au_nhash delist; ++ struct au_nhash whlist; ++ aufs_bindex_t bindex; ++ unsigned int flags; ++ int err; ++}; ++ ++static int fillvdir(void *__arg, const char *__name, int nlen, ++ loff_t offset __maybe_unused, u64 h_ino, ++ unsigned int d_type) ++{ ++ struct fillvdir_arg *arg = __arg; ++ char *name = (void *)__name; ++ struct super_block *sb; ++ ino_t ino; ++ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH); ++ ++ arg->err = 0; ++ sb = arg->file->f_dentry->d_sb; ++ au_fset_fillvdir(arg->flags, CALLED); ++ /* smp_mb(); */ ++ if (nlen <= AUFS_WH_PFX_LEN ++ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ if (test_known(&arg->delist, name, nlen) ++ || au_nhash_test_known_wh(&arg->whlist, name, nlen)) ++ goto out; /* already exists or whiteouted */ ++ ++ sb = arg->file->f_dentry->d_sb; ++ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino); ++ if (!arg->err) ++ arg->err = append_de(arg->vdir, name, nlen, ino, ++ d_type, &arg->delist); ++ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) { ++ name += AUFS_WH_PFX_LEN; ++ nlen -= AUFS_WH_PFX_LEN; ++ if (au_nhash_test_known_wh(&arg->whlist, name, nlen)) ++ goto out; /* already whiteouted */ ++ ++ if (shwh) ++ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type, ++ &ino); ++ if (!arg->err) ++ arg->err = au_nhash_append_wh ++ (&arg->whlist, name, nlen, ino, d_type, ++ arg->bindex, shwh); ++ } ++ ++ out: ++ if (!arg->err) ++ arg->vdir->vd_jiffy = jiffies; ++ /* smp_mb(); */ ++ AuTraceErr(arg->err); ++ return arg->err; ++} ++ ++static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir, ++ struct au_nhash *whlist, struct au_nhash *delist) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ int err; ++ unsigned int nh, u; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos, *n; ++ char *p, *o; ++ struct au_vdir_destr *destr; ++ ++ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH)); ++ ++ err = -ENOMEM; ++ o = p = __getname(); ++ if (unlikely(!p)) ++ goto out; ++ ++ err = 0; ++ nh = whlist->nh_num; ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ p += AUFS_WH_PFX_LEN; ++ for (u = 0; u < nh; u++) { ++ head = whlist->nh_head + u; ++ hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) { ++ destr = &tpos->wh_str; ++ memcpy(p, destr->name, destr->len); ++ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN, ++ tpos->wh_ino, tpos->wh_type, delist); ++ if (unlikely(err)) ++ break; ++ } ++ } ++ ++ __putname(o); ++ ++ out: ++ AuTraceErr(err); ++ return err; ++#else ++ return 0; ++#endif ++} ++ ++static int au_do_read_vdir(struct fillvdir_arg *arg) ++{ ++ int err; ++ unsigned int rdhash; ++ loff_t offset; ++ aufs_bindex_t bend, bindex, bstart; ++ unsigned char shwh; ++ struct file *hf, *file; ++ struct super_block *sb; ++ ++ file = arg->file; ++ sb = file->f_dentry->d_sb; ++ SiMustAnyLock(sb); ++ ++ rdhash = au_sbi(sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL)); ++ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out_delist; ++ ++ err = 0; ++ arg->flags = 0; ++ shwh = 0; ++ if (au_opt_test(au_mntflags(sb), SHWH)) { ++ shwh = 1; ++ au_fset_fillvdir(arg->flags, SHWH); ++ } ++ bstart = au_fbstart(file); ++ bend = au_fbend(file); ++ for (bindex = bstart; !err && bindex <= bend; bindex++) { ++ hf = au_h_fptr(file, bindex); ++ if (!hf) ++ continue; ++ ++ offset = vfsub_llseek(hf, 0, SEEK_SET); ++ err = offset; ++ if (unlikely(offset)) ++ break; ++ ++ arg->bindex = bindex; ++ au_fclr_fillvdir(arg->flags, WHABLE); ++ if (shwh ++ || (bindex != bend ++ && au_br_whable(au_sbr_perm(sb, bindex)))) ++ au_fset_fillvdir(arg->flags, WHABLE); ++ do { ++ arg->err = 0; ++ au_fclr_fillvdir(arg->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_readdir(hf, fillvdir, arg); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err && au_ftest_fillvdir(arg->flags, CALLED)); ++ } ++ ++ if (!err && shwh) ++ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist); ++ ++ au_nhash_wh_free(&arg->whlist); ++ ++ out_delist: ++ au_nhash_de_free(&arg->delist); ++ out: ++ return err; ++} ++ ++static int read_vdir(struct file *file, int may_read) ++{ ++ int err; ++ unsigned long expire; ++ unsigned char do_read; ++ struct fillvdir_arg arg; ++ struct inode *inode; ++ struct au_vdir *vdir, *allocated; ++ ++ err = 0; ++ inode = file->f_dentry->d_inode; ++ IMustLock(inode); ++ SiMustAnyLock(inode->i_sb); ++ ++ allocated = NULL; ++ do_read = 0; ++ expire = au_sbi(inode->i_sb)->si_rdcache; ++ vdir = au_ivdir(inode); ++ if (!vdir) { ++ do_read = 1; ++ vdir = alloc_vdir(file); ++ err = PTR_ERR(vdir); ++ if (IS_ERR(vdir)) ++ goto out; ++ err = 0; ++ allocated = vdir; ++ } else if (may_read ++ && (inode->i_version != vdir->vd_version ++ || time_after(jiffies, vdir->vd_jiffy + expire))) { ++ do_read = 1; ++ err = reinit_vdir(vdir); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ if (!do_read) ++ return 0; /* success */ ++ ++ arg.file = file; ++ arg.vdir = vdir; ++ err = au_do_read_vdir(&arg); ++ if (!err) { ++ /* file->f_pos = 0; */ ++ vdir->vd_version = inode->i_version; ++ vdir->vd_last.ul = 0; ++ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; ++ if (allocated) ++ au_set_ivdir(inode, allocated); ++ } else if (allocated) ++ au_vdir_free(allocated); ++ ++ out: ++ return err; ++} ++ ++static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src) ++{ ++ int err, rerr; ++ unsigned long ul, n; ++ const unsigned int deblk_sz = src->vd_deblk_sz; ++ ++ AuDebugOn(tgt->vd_nblk != 1); ++ ++ err = -ENOMEM; ++ if (tgt->vd_nblk < src->vd_nblk) { ++ unsigned char **p; ++ ++ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, ++ GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ tgt->vd_deblk = p; ++ } ++ ++ if (tgt->vd_deblk_sz != deblk_sz) { ++ unsigned char *p; ++ ++ tgt->vd_deblk_sz = deblk_sz; ++ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ tgt->vd_deblk[0] = p; ++ } ++ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz); ++ tgt->vd_version = src->vd_version; ++ tgt->vd_jiffy = src->vd_jiffy; ++ ++ n = src->vd_nblk; ++ for (ul = 1; ul < n; ul++) { ++ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz, ++ GFP_NOFS); ++ if (unlikely(!tgt->vd_deblk[ul])) ++ goto out; ++ tgt->vd_nblk++; ++ } ++ tgt->vd_nblk = n; ++ tgt->vd_last.ul = tgt->vd_last.ul; ++ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul]; ++ tgt->vd_last.p.deblk += src->vd_last.p.deblk ++ - src->vd_deblk[src->vd_last.ul]; ++ /* smp_mb(); */ ++ return 0; /* success */ ++ ++ out: ++ rerr = reinit_vdir(tgt); ++ BUG_ON(rerr); ++ return err; ++} ++ ++int au_vdir_init(struct file *file) ++{ ++ int err; ++ struct inode *inode; ++ struct au_vdir *vdir_cache, *allocated; ++ ++ err = read_vdir(file, !file->f_pos); ++ if (unlikely(err)) ++ goto out; ++ ++ allocated = NULL; ++ vdir_cache = au_fvdir_cache(file); ++ if (!vdir_cache) { ++ vdir_cache = alloc_vdir(file); ++ err = PTR_ERR(vdir_cache); ++ if (IS_ERR(vdir_cache)) ++ goto out; ++ allocated = vdir_cache; ++ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { ++ err = reinit_vdir(vdir_cache); ++ if (unlikely(err)) ++ goto out; ++ } else ++ return 0; /* success */ ++ ++ inode = file->f_dentry->d_inode; ++ err = copy_vdir(vdir_cache, au_ivdir(inode)); ++ if (!err) { ++ file->f_version = inode->i_version; ++ if (allocated) ++ au_set_fvdir_cache(file, allocated); ++ } else if (allocated) ++ au_vdir_free(allocated); ++ ++ out: ++ return err; ++} ++ ++static loff_t calc_offset(struct au_vdir *vdir) ++{ ++ loff_t offset; ++ union au_vdir_deblk_p p; ++ ++ p.deblk = vdir->vd_deblk[vdir->vd_last.ul]; ++ offset = vdir->vd_last.p.deblk - p.deblk; ++ offset += vdir->vd_deblk_sz * vdir->vd_last.ul; ++ return offset; ++} ++ ++/* returns true or false */ ++static int seek_vdir(struct file *file) ++{ ++ int valid; ++ unsigned int deblk_sz; ++ unsigned long ul, n; ++ loff_t offset; ++ union au_vdir_deblk_p p, deblk_end; ++ struct au_vdir *vdir_cache; ++ ++ valid = 1; ++ vdir_cache = au_fvdir_cache(file); ++ offset = calc_offset(vdir_cache); ++ AuDbg("offset %lld\n", offset); ++ if (file->f_pos == offset) ++ goto out; ++ ++ vdir_cache->vd_last.ul = 0; ++ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0]; ++ if (!file->f_pos) ++ goto out; ++ ++ valid = 0; ++ deblk_sz = vdir_cache->vd_deblk_sz; ++ ul = div64_u64(file->f_pos, deblk_sz); ++ AuDbg("ul %lu\n", ul); ++ if (ul >= vdir_cache->vd_nblk) ++ goto out; ++ ++ n = vdir_cache->vd_nblk; ++ for (; ul < n; ul++) { ++ p.deblk = vdir_cache->vd_deblk[ul]; ++ deblk_end.deblk = p.deblk + deblk_sz; ++ offset = ul; ++ offset *= deblk_sz; ++ while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) { ++ unsigned int l; ++ ++ l = calc_size(p.de->de_str.len); ++ offset += l; ++ p.deblk += l; ++ } ++ if (!is_deblk_end(&p, &deblk_end)) { ++ valid = 1; ++ vdir_cache->vd_last.ul = ul; ++ vdir_cache->vd_last.p = p; ++ break; ++ } ++ } ++ ++ out: ++ /* smp_mb(); */ ++ AuTraceErr(!valid); ++ return valid; ++} ++ ++int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir) ++{ ++ int err; ++ unsigned int l, deblk_sz; ++ union au_vdir_deblk_p deblk_end; ++ struct au_vdir *vdir_cache; ++ struct au_vdir_de *de; ++ ++ vdir_cache = au_fvdir_cache(file); ++ if (!seek_vdir(file)) ++ return 0; ++ ++ deblk_sz = vdir_cache->vd_deblk_sz; ++ while (1) { ++ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; ++ deblk_end.deblk += deblk_sz; ++ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) { ++ de = vdir_cache->vd_last.p.de; ++ AuDbg("%.*s, off%lld, i%lu, dt%d\n", ++ de->de_str.len, de->de_str.name, file->f_pos, ++ (unsigned long)de->de_ino, de->de_type); ++ err = filldir(dirent, de->de_str.name, de->de_str.len, ++ file->f_pos, de->de_ino, de->de_type); ++ if (unlikely(err)) { ++ AuTraceErr(err); ++ /* todo: ignore the error caused by udba? */ ++ /* return err; */ ++ return 0; ++ } ++ ++ l = calc_size(de->de_str.len); ++ vdir_cache->vd_last.p.deblk += l; ++ file->f_pos += l; ++ } ++ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) { ++ vdir_cache->vd_last.ul++; ++ vdir_cache->vd_last.p.deblk ++ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; ++ file->f_pos = deblk_sz * vdir_cache->vd_last.ul; ++ continue; ++ } ++ break; ++ } ++ ++ /* smp_mb(); */ ++ return 0; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/vfsub.c linux-2.6.31/fs/aufs/vfsub.c +--- linux-2.6.31-vanilla/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/vfsub.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,755 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * sub-routines for VFS ++ */ ++ ++#include <linux/ima.h> ++#include <linux/namei.h> ++#include <linux/security.h> ++#include <linux/splice.h> ++#include <linux/uaccess.h> ++#include "aufs.h" ++ ++int vfsub_update_h_iattr(struct path *h_path, int *did) ++{ ++ int err; ++ struct kstat st; ++ struct super_block *h_sb; ++ ++ /* for remote fs, leave work for its getattr or d_revalidate */ ++ /* for bad i_attr fs, handle them in aufs_getattr() */ ++ /* still some fs may acquire i_mutex. we need to skip them */ ++ err = 0; ++ if (!did) ++ did = &err; ++ h_sb = h_path->dentry->d_sb; ++ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb)); ++ if (*did) ++ err = vfs_getattr(h_path->mnt, h_path->dentry, &st); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_IMA ++#error IMA is not supported since it does not work well. Wait for their fixing. ++#endif ++ ++struct file *vfsub_dentry_open(struct path *path, int flags, ++ const struct cred *cred) ++{ ++ struct file *file; ++ ++ file = dentry_open(path->dentry, path->mnt, flags, cred); ++ if (IS_ERR(file)) ++ return file; ++ /* as NFSD does, just call ima_..._get() simply after dentry_open */ ++ ima_counts_get(file); ++ return file; ++} ++ ++struct file *vfsub_filp_open(const char *path, int oflags, int mode) ++{ ++ struct file *file; ++ ++ lockdep_off(); ++ file = filp_open(path, oflags, mode); ++ lockdep_on(); ++ if (IS_ERR(file)) ++ goto out; ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ ++ out: ++ return file; ++} ++ ++int vfsub_kern_path(const char *name, unsigned int flags, struct path *path) ++{ ++ int err; ++ ++ /* lockdep_off(); */ ++ err = kern_path(name, flags, path); ++ /* lockdep_on(); */ ++ if (!err && path->dentry->d_inode) ++ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, ++ int len) ++{ ++ struct path path = { ++ .mnt = NULL ++ }; ++ ++ /* VFS checks it too, but by WARN_ON_ONCE() */ ++ IMustLock(parent->d_inode); ++ ++ path.dentry = lookup_one_len(name, parent, len); ++ if (IS_ERR(path.dentry)) ++ goto out; ++ if (path.dentry->d_inode) ++ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ ++ ++ out: ++ return path.dentry; ++} ++ ++struct dentry *vfsub_lookup_hash(struct nameidata *nd) ++{ ++ struct path path = { ++ .mnt = nd->path.mnt ++ }; ++ ++ IMustLock(nd->path.dentry->d_inode); ++ ++ path.dentry = lookup_hash(nd); ++ if (!IS_ERR(path.dentry) && path.dentry->d_inode) ++ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ ++ ++ return path.dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2) ++{ ++ struct dentry *d; ++ ++ lockdep_off(); ++ d = lock_rename(d1, d2); ++ lockdep_on(); ++ au_hin_suspend(hdir1); ++ if (hdir1 != hdir2) ++ au_hin_suspend(hdir2); ++ ++ return d; ++} ++ ++void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2) ++{ ++ au_hin_resume(hdir1); ++ if (hdir1 != hdir2) ++ au_hin_resume(hdir2); ++ lockdep_off(); ++ unlock_rename(d1, d2); ++ lockdep_on(); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int vfsub_create(struct inode *dir, struct path *path, int mode) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mknod(path, path->dentry, mode, 0); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ if (au_test_fs_null_nd(dir->i_sb)) ++ err = vfs_create(dir, path->dentry, mode, NULL); ++ else { ++ struct nameidata h_nd; ++ ++ memset(&h_nd, 0, sizeof(h_nd)); ++ h_nd.flags = LOOKUP_CREATE; ++ h_nd.intent.open.flags = O_CREAT ++ | vfsub_fmode_to_uint(FMODE_READ); ++ h_nd.intent.open.create_mode = mode; ++ h_nd.path.dentry = path->dentry->d_parent; ++ h_nd.path.mnt = path->mnt; ++ path_get(&h_nd.path); ++ err = vfs_create(dir, path->dentry, mode, &h_nd); ++ path_put(&h_nd.path); ++ } ++ ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_symlink(struct inode *dir, struct path *path, const char *symname) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_symlink(path, path->dentry, symname); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ err = vfs_symlink(dir, path->dentry, symname); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mknod(path, path->dentry, mode, dev); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ err = vfs_mknod(dir, path->dentry, mode, dev); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++static int au_test_nlink(struct inode *inode) ++{ ++ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */ ++ ++ if (!au_test_fs_no_limit_nlink(inode->i_sb) ++ || inode->i_nlink < link_max) ++ return 0; ++ return -EMLINK; ++} ++ ++int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ err = au_test_nlink(src_dentry->d_inode); ++ if (unlikely(err)) ++ return err; ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_link(src_dentry, path, path->dentry); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_link(src_dentry, dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ /* fuse has different memory inode for the same inumber */ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ tmp.dentry = src_dentry; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, ++ struct inode *dir, struct path *path) ++{ ++ int err; ++ struct path tmp = { ++ .mnt = path->mnt ++ }; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ IMustLock(src_dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ tmp.dentry = src_dentry->d_parent; ++ err = security_path_rename(&tmp, src_dentry, path, path->dentry); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_rename(src_dir, src_dentry, dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ int did; ++ ++ tmp.dentry = d->d_parent; ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = src_dentry; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ tmp.dentry = src_dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_mkdir(struct inode *dir, struct path *path, int mode) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mkdir(path, path->dentry, mode); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ err = vfs_mkdir(dir, path->dentry, mode); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++int vfsub_rmdir(struct inode *dir, struct path *path) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_rmdir(path, path->dentry); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_rmdir(dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = { ++ .dentry = path->dentry->d_parent, ++ .mnt = path->mnt ++ }; ++ ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ ++ } ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ ++ err = vfs_read(file, ubuf, count, ppos); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++/* todo: kernel_read()? */ ++ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = vfsub_read_u(file, (char __user *)kbuf, count, ppos); ++ set_fs(oldfs); ++ return err; ++} ++ ++ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ ++ lockdep_off(); ++ err = vfs_write(file, ubuf, count, ppos); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = vfsub_write_u(file, (const char __user *)kbuf, count, ppos); ++ set_fs(oldfs); ++ return err; ++} ++ ++int vfsub_readdir(struct file *file, filldir_t filldir, void *arg) ++{ ++ int err; ++ ++ lockdep_off(); ++ err = vfs_readdir(file, filldir, arg); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++long vfsub_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) ++{ ++ long err; ++ ++ lockdep_off(); ++ err = do_splice_to(in, ppos, pipe, len, flags); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) ++{ ++ long err; ++ ++ lockdep_off(); ++ err = do_splice_from(pipe, out, ppos, len, flags); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */ ++int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, ++ struct file *h_file) ++{ ++ int err; ++ struct inode *h_inode; ++ ++ h_inode = h_path->dentry->d_inode; ++ if (!h_file) { ++ err = mnt_want_write(h_path->mnt); ++ if (err) ++ goto out; ++ err = inode_permission(h_inode, MAY_WRITE); ++ if (err) ++ goto out_mnt; ++ err = get_write_access(h_inode); ++ if (err) ++ goto out_mnt; ++ err = break_lease(h_inode, vfsub_fmode_to_uint(FMODE_WRITE)); ++ if (err) ++ goto out_inode; ++ } ++ ++ err = locks_verify_truncate(h_inode, h_file, length); ++ if (!err) ++ err = security_path_truncate(h_path, length, attr); ++ if (!err) { ++ lockdep_off(); ++ err = do_truncate(h_path->dentry, length, attr, h_file); ++ lockdep_on(); ++ } ++ ++ out_inode: ++ if (!h_file) ++ put_write_access(h_inode); ++ out_mnt: ++ if (!h_file) ++ mnt_drop_write(h_path->mnt); ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_vfsub_mkdir_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++ int mode; ++}; ++ ++static void au_call_vfsub_mkdir(void *args) ++{ ++ struct au_vfsub_mkdir_args *a = args; ++ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode); ++} ++ ++int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode) ++{ ++ int err, do_sio, wkq_err; ++ ++ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) ++ err = vfsub_mkdir(dir, path, mode); ++ else { ++ struct au_vfsub_mkdir_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path, ++ .mode = mode ++ }; ++ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++struct au_vfsub_rmdir_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++}; ++ ++static void au_call_vfsub_rmdir(void *args) ++{ ++ struct au_vfsub_rmdir_args *a = args; ++ *a->errp = vfsub_rmdir(a->dir, a->path); ++} ++ ++int vfsub_sio_rmdir(struct inode *dir, struct path *path) ++{ ++ int err, do_sio, wkq_err; ++ ++ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) ++ err = vfsub_rmdir(dir, path); ++ else { ++ struct au_vfsub_rmdir_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path ++ }; ++ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct notify_change_args { ++ int *errp; ++ struct path *path; ++ struct iattr *ia; ++}; ++ ++static void call_notify_change(void *args) ++{ ++ struct notify_change_args *a = args; ++ struct inode *h_inode; ++ ++ h_inode = a->path->dentry->d_inode; ++ IMustLock(h_inode); ++ ++ *a->errp = -EPERM; ++ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { ++ lockdep_off(); ++ *a->errp = notify_change(a->path->dentry, a->ia); ++ lockdep_on(); ++ if (!*a->errp) ++ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/ ++ } ++ AuTraceErr(*a->errp); ++} ++ ++int vfsub_notify_change(struct path *path, struct iattr *ia) ++{ ++ int err; ++ struct notify_change_args args = { ++ .errp = &err, ++ .path = path, ++ .ia = ia ++ }; ++ ++ call_notify_change(&args); ++ ++ return err; ++} ++ ++int vfsub_sio_notify_change(struct path *path, struct iattr *ia) ++{ ++ int err, wkq_err; ++ struct notify_change_args args = { ++ .errp = &err, ++ .path = path, ++ .ia = ia ++ }; ++ ++ wkq_err = au_wkq_wait(call_notify_change, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct unlink_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++}; ++ ++static void call_unlink(void *args) ++{ ++ struct unlink_args *a = args; ++ struct dentry *d = a->path->dentry; ++ struct inode *h_inode; ++ const int stop_sillyrename = (au_test_nfs(d->d_sb) ++ && atomic_read(&d->d_count) == 1); ++ ++ IMustLock(a->dir); ++ ++ a->path->dentry = d->d_parent; ++ *a->errp = security_path_unlink(a->path, d); ++ a->path->dentry = d; ++ if (unlikely(*a->errp)) ++ return; ++ ++ if (!stop_sillyrename) ++ dget(d); ++ h_inode = d->d_inode; ++ if (h_inode) ++ atomic_inc(&h_inode->i_count); ++ ++ lockdep_off(); ++ *a->errp = vfs_unlink(a->dir, d); ++ lockdep_on(); ++ if (!*a->errp) { ++ struct path tmp = { ++ .dentry = d->d_parent, ++ .mnt = a->path->mnt ++ }; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ ++ } ++ ++ if (!stop_sillyrename) ++ dput(d); ++ if (h_inode) ++ iput(h_inode); ++ ++ AuTraceErr(*a->errp); ++} ++ ++/* ++ * @dir: must be locked. ++ * @dentry: target dentry. ++ */ ++int vfsub_unlink(struct inode *dir, struct path *path, int force) ++{ ++ int err; ++ struct unlink_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path ++ }; ++ ++ if (!force) ++ call_unlink(&args); ++ else { ++ int wkq_err; ++ ++ wkq_err = au_wkq_wait(call_unlink, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/vfsub.h linux-2.6.31/fs/aufs/vfsub.h +--- linux-2.6.31-vanilla/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/vfsub.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,172 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * sub-routines for VFS ++ */ ++ ++#ifndef __AUFS_VFSUB_H__ ++#define __AUFS_VFSUB_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/fs.h> ++#include <linux/fs_stack.h> ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for lower inode */ ++/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */ ++/* reduce? gave up. */ ++enum { ++ AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */ ++ AuLsc_I_PARENT, /* lower inode, parent first */ ++ AuLsc_I_PARENT2, /* copyup dirs */ ++ AuLsc_I_PARENT3, /* copyup wh */ ++ AuLsc_I_CHILD, ++ AuLsc_I_CHILD2, ++ AuLsc_I_End ++}; ++ ++/* to debug easier, do not make them inlined functions */ ++#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) ++#define IMustLock(i) MtxMustLock(&(i)->i_mutex) ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void vfsub_copy_inode_size(struct inode *inode, ++ struct inode *h_inode) ++{ ++ spin_lock(&inode->i_lock); ++ fsstack_copy_inode_size(inode, h_inode); ++ spin_unlock(&inode->i_lock); ++} ++ ++int vfsub_update_h_iattr(struct path *h_path, int *did); ++struct file *vfsub_filp_open(const char *path, int oflags, int mode); ++struct file *vfsub_dentry_open(struct path *path, int flags, ++ const struct cred *cred); ++int vfsub_kern_path(const char *name, unsigned int flags, struct path *path); ++struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, ++ int len); ++struct dentry *vfsub_lookup_hash(struct nameidata *nd); ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_hinode; ++struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2); ++void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2); ++ ++int vfsub_create(struct inode *dir, struct path *path, int mode); ++int vfsub_symlink(struct inode *dir, struct path *path, ++ const char *symname); ++int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev); ++int vfsub_link(struct dentry *src_dentry, struct inode *dir, ++ struct path *path); ++int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry, ++ struct inode *hdir, struct path *path); ++int vfsub_mkdir(struct inode *dir, struct path *path, int mode); ++int vfsub_rmdir(struct inode *dir, struct path *path); ++ ++int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode); ++int vfsub_sio_rmdir(struct inode *dir, struct path *path); ++int vfsub_sio_notify_change(struct path *path, struct iattr *ia); ++int vfsub_notify_change(struct path *path, struct iattr *ia); ++int vfsub_unlink(struct inode *dir, struct path *path, int force); ++ ++/* ---------------------------------------------------------------------- */ ++ ++ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos); ++int vfsub_readdir(struct file *file, filldir_t filldir, void *arg); ++ ++long vfsub_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); ++long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, ++ struct file *h_file); ++ ++static inline void vfsub_file_accessed(struct file *h_file) ++{ ++ file_accessed(h_file); ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/ ++} ++ ++static inline void vfsub_touch_atime(struct vfsmount *h_mnt, ++ struct dentry *h_dentry) ++{ ++ struct path h_path = { ++ .dentry = h_dentry, ++ .mnt = h_mnt ++ }; ++ touch_atime(h_mnt, h_dentry); ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin) ++{ ++ loff_t err; ++ ++ lockdep_off(); ++ err = vfs_llseek(file, offset, origin); ++ lockdep_on(); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dirty workaround for strict type of fmode_t */ ++union vfsub_fmu { ++ fmode_t fm; ++ unsigned int ui; ++}; ++ ++static inline unsigned int vfsub_fmode_to_uint(fmode_t fm) ++{ ++ union vfsub_fmu u = { ++ .fm = fm ++ }; ++ ++ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui)); ++ ++ return u.ui; ++} ++ ++static inline fmode_t vfsub_uint_to_fmode(unsigned int ui) ++{ ++ union vfsub_fmu u = { ++ .ui = ui ++ }; ++ ++ return u.fm; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_VFSUB_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/wbr_policy.c linux-2.6.31/fs/aufs/wbr_policy.c +--- linux-2.6.31-vanilla/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/wbr_policy.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,641 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * policies for selecting one among multiple writable branches ++ */ ++ ++#include <linux/statfs.h> ++#include "aufs.h" ++ ++/* subset of cpup_attr() */ ++static noinline_for_stack ++int au_cpdown_attr(struct path *h_path, struct dentry *h_src) ++{ ++ int err, sbits; ++ struct iattr ia; ++ struct inode *h_isrc; ++ ++ h_isrc = h_src->d_inode; ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID; ++ ia.ia_mode = h_isrc->i_mode; ++ ia.ia_uid = h_isrc->i_uid; ++ ia.ia_gid = h_isrc->i_gid; ++ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); ++ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc); ++ err = vfsub_sio_notify_change(h_path, &ia); ++ ++ /* is this nfs only? */ ++ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) { ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ err = vfsub_sio_notify_change(h_path, &ia); ++ } ++ ++ return err; ++} ++ ++#define AuCpdown_PARENT_OPQ 1 ++#define AuCpdown_WHED (1 << 1) ++#define AuCpdown_MADE_DIR (1 << 2) ++#define AuCpdown_DIROPQ (1 << 3) ++#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name) ++#define au_fset_cpdown(flags, name) { (flags) |= AuCpdown_##name; } ++#define au_fclr_cpdown(flags, name) { (flags) &= ~AuCpdown_##name; } ++ ++struct au_cpdown_dir_args { ++ struct dentry *parent; ++ unsigned int flags; ++}; ++ ++static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst, ++ struct au_cpdown_dir_args *a) ++{ ++ int err; ++ struct dentry *opq_dentry; ++ ++ opq_dentry = au_diropq_create(dentry, bdst); ++ err = PTR_ERR(opq_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out; ++ dput(opq_dentry); ++ au_fset_cpdown(a->flags, DIROPQ); ++ ++ out: ++ return err; ++} ++ ++static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent, ++ struct inode *dir, aufs_bindex_t bdst) ++{ ++ int err; ++ struct path h_path; ++ struct au_branch *br; ++ ++ br = au_sbr(dentry->d_sb, bdst); ++ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ err = 0; ++ if (h_path.dentry->d_inode) { ++ h_path.mnt = br->br_mnt; ++ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path, ++ dentry); ++ } ++ dput(h_path.dentry); ++ ++ out: ++ return err; ++} ++ ++static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst, ++ struct dentry *h_parent, void *arg) ++{ ++ int err, rerr; ++ aufs_bindex_t bend, bopq, bstart; ++ unsigned char parent_opq; ++ struct path h_path; ++ struct dentry *parent; ++ struct inode *h_dir, *h_inode, *inode, *dir; ++ struct au_cpdown_dir_args *args = arg; ++ ++ bstart = au_dbstart(dentry); ++ /* dentry is di-locked */ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ h_dir = h_parent->d_inode; ++ AuDebugOn(h_dir != au_h_iptr(dir, bdst)); ++ IMustLock(h_dir); ++ ++ err = au_lkup_neg(dentry, bdst); ++ if (unlikely(err < 0)) ++ goto out; ++ h_path.dentry = au_h_dptr(dentry, bdst); ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst); ++ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, ++ S_IRWXU | S_IRUGO | S_IXUGO); ++ if (unlikely(err)) ++ goto out_put; ++ au_fset_cpdown(args->flags, MADE_DIR); ++ ++ bend = au_dbend(dentry); ++ bopq = au_dbdiropq(dentry); ++ au_fclr_cpdown(args->flags, WHED); ++ au_fclr_cpdown(args->flags, DIROPQ); ++ if (au_dbwh(dentry) == bdst) ++ au_fset_cpdown(args->flags, WHED); ++ if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst) ++ au_fset_cpdown(args->flags, PARENT_OPQ); ++ parent_opq = (au_ftest_cpdown(args->flags, PARENT_OPQ) ++ && args->parent == dentry); ++ h_inode = h_path.dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ if (au_ftest_cpdown(args->flags, WHED)) { ++ err = au_cpdown_dir_opq(dentry, bdst, args); ++ if (unlikely(err)) { ++ mutex_unlock(&h_inode->i_mutex); ++ goto out_dir; ++ } ++ } ++ ++ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart)); ++ mutex_unlock(&h_inode->i_mutex); ++ if (unlikely(err)) ++ goto out_opq; ++ ++ if (au_ftest_cpdown(args->flags, WHED)) { ++ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst); ++ if (unlikely(err)) ++ goto out_opq; ++ } ++ ++ inode = dentry->d_inode; ++ if (au_ibend(inode) < bdst) ++ au_set_ibend(inode, bdst); ++ au_set_h_iptr(inode, bdst, au_igrab(h_inode), ++ au_hi_flags(inode, /*isdir*/1)); ++ goto out; /* success */ ++ ++ /* revert */ ++ out_opq: ++ if (au_ftest_cpdown(args->flags, DIROPQ)) { ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(dentry, bdst); ++ mutex_unlock(&h_inode->i_mutex); ++ if (unlikely(rerr)) { ++ AuIOErr("failed removing diropq for %.*s b%d (%d)\n", ++ AuDLNPair(dentry), bdst, rerr); ++ err = -EIO; ++ goto out; ++ } ++ } ++ out_dir: ++ if (au_ftest_cpdown(args->flags, MADE_DIR)) { ++ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path); ++ if (unlikely(rerr)) { ++ AuIOErr("failed removing %.*s b%d (%d)\n", ++ AuDLNPair(dentry), bdst, rerr); ++ err = -EIO; ++ } ++ } ++ out_put: ++ au_set_h_dptr(dentry, bdst, NULL); ++ if (au_dbend(dentry) == bdst) ++ au_update_dbend(dentry); ++ out: ++ dput(parent); ++ return err; ++} ++ ++int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ int err; ++ struct au_cpdown_dir_args args = { ++ .parent = dget_parent(dentry), ++ .flags = 0 ++ }; ++ ++ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args); ++ dput(args.parent); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies for create */ ++ ++static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ for (; bindex >= 0; bindex--) ++ if (!au_br_rdonly(au_sbr(sb, bindex))) ++ return bindex; ++ return -EROFS; ++} ++ ++/* top down parent */ ++static int au_wbr_create_tdp(struct dentry *dentry, int isdir __maybe_unused) ++{ ++ int err; ++ aufs_bindex_t bstart, bindex; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ err = bstart; ++ if (!au_br_rdonly(au_sbr(sb, bstart))) ++ goto out; ++ ++ err = -EROFS; ++ parent = dget_parent(dentry); ++ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = bindex; ++ break; ++ } ++ } ++ dput(parent); ++ ++ /* bottom up here */ ++ if (unlikely(err < 0)) ++ err = au_wbr_bu(sb, bstart - 1); ++ ++ out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* an exception for the policy other than tdp */ ++static int au_wbr_create_exp(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bwh, bdiropq; ++ struct dentry *parent; ++ ++ err = -1; ++ bwh = au_dbwh(dentry); ++ parent = dget_parent(dentry); ++ bdiropq = au_dbdiropq(parent); ++ if (bwh >= 0) { ++ if (bdiropq >= 0) ++ err = min(bdiropq, bwh); ++ else ++ err = bwh; ++ AuDbg("%d\n", err); ++ } else if (bdiropq >= 0) { ++ err = bdiropq; ++ AuDbg("%d\n", err); ++ } ++ dput(parent); ++ ++ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err))) ++ err = -1; ++ ++ AuDbg("%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* round robin */ ++static int au_wbr_create_init_rr(struct super_block *sb) ++{ ++ int err; ++ ++ err = au_wbr_bu(sb, au_sbend(sb)); ++ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */ ++ /* smp_mb(); */ ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_rr(struct dentry *dentry, int isdir) ++{ ++ int err, nbr; ++ unsigned int u; ++ aufs_bindex_t bindex, bend; ++ struct super_block *sb; ++ atomic_t *next; ++ ++ err = au_wbr_create_exp(dentry); ++ if (err >= 0) ++ goto out; ++ ++ sb = dentry->d_sb; ++ next = &au_sbi(sb)->si_wbr_rr_next; ++ bend = au_sbend(sb); ++ nbr = bend + 1; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ if (!isdir) { ++ err = atomic_dec_return(next) + 1; ++ /* modulo for 0 is meaningless */ ++ if (unlikely(!err)) ++ err = atomic_dec_return(next) + 1; ++ } else ++ err = atomic_read(next); ++ AuDbg("%d\n", err); ++ u = err; ++ err = u % nbr; ++ AuDbg("%d\n", err); ++ if (!au_br_rdonly(au_sbr(sb, err))) ++ break; ++ err = -EROFS; ++ } ++ ++ out: ++ AuDbg("%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* most free space */ ++static void au_mfs(struct dentry *dentry) ++{ ++ struct super_block *sb; ++ struct au_branch *br; ++ struct au_wbr_mfs *mfs; ++ aufs_bindex_t bindex, bend; ++ int err; ++ unsigned long long b, bavail; ++ /* reduce the stack usage */ ++ struct kstatfs *st; ++ ++ st = kmalloc(sizeof(*st), GFP_NOFS); ++ if (unlikely(!st)) { ++ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM); ++ return; ++ } ++ ++ bavail = 0; ++ sb = dentry->d_sb; ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ MtxMustLock(&mfs->mfs_lock); ++ mfs->mfs_bindex = -EROFS; ++ mfs->mfsrr_bytes = 0; ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_rdonly(br)) ++ continue; ++ ++ /* sb->s_root for NFS is unreliable */ ++ err = vfs_statfs(br->br_mnt->mnt_root, st); ++ if (unlikely(err)) { ++ AuWarn1("failed statfs, b%d, %d\n", bindex, err); ++ continue; ++ } ++ ++ /* when the available size is equal, select the lower one */ ++ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail) ++ || sizeof(b) < sizeof(st->f_bsize)); ++ b = st->f_bavail * st->f_bsize; ++ br->br_wbr->wbr_bytes = b; ++ if (b >= bavail) { ++ bavail = b; ++ mfs->mfs_bindex = bindex; ++ mfs->mfs_jiffy = jiffies; ++ } ++ } ++ ++ mfs->mfsrr_bytes = bavail; ++ AuDbg("b%d\n", mfs->mfs_bindex); ++ kfree(st); ++} ++ ++static int au_wbr_create_mfs(struct dentry *dentry, int isdir __maybe_unused) ++{ ++ int err; ++ struct super_block *sb; ++ struct au_wbr_mfs *mfs; ++ ++ err = au_wbr_create_exp(dentry); ++ if (err >= 0) ++ goto out; ++ ++ sb = dentry->d_sb; ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mutex_lock(&mfs->mfs_lock); ++ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) ++ || mfs->mfs_bindex < 0 ++ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex))) ++ au_mfs(dentry); ++ mutex_unlock(&mfs->mfs_lock); ++ err = mfs->mfs_bindex; ++ ++ out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_init_mfs(struct super_block *sb) ++{ ++ struct au_wbr_mfs *mfs; ++ ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mutex_init(&mfs->mfs_lock); ++ mfs->mfs_jiffy = 0; ++ mfs->mfs_bindex = -EROFS; ++ ++ return 0; ++} ++ ++static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused) ++{ ++ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* most free space and then round robin */ ++static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir) ++{ ++ int err; ++ struct au_wbr_mfs *mfs; ++ ++ err = au_wbr_create_mfs(dentry, isdir); ++ if (err >= 0) { ++ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs; ++ mutex_lock(&mfs->mfs_lock); ++ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark) ++ err = au_wbr_create_rr(dentry, isdir); ++ mutex_unlock(&mfs->mfs_lock); ++ } ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_init_mfsrr(struct super_block *sb) ++{ ++ int err; ++ ++ au_wbr_create_init_mfs(sb); /* ignore */ ++ err = au_wbr_create_init_rr(sb); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* top down parent and most free space */ ++static int au_wbr_create_pmfs(struct dentry *dentry, int isdir) ++{ ++ int err, e2; ++ unsigned long long b; ++ aufs_bindex_t bindex, bstart, bend; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent; ++ struct au_branch *br; ++ ++ err = au_wbr_create_tdp(dentry, isdir); ++ if (unlikely(err < 0)) ++ goto out; ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(parent); ++ bend = au_dbtaildir(parent); ++ if (bstart == bend) ++ goto out_parent; /* success */ ++ ++ e2 = au_wbr_create_mfs(dentry, isdir); ++ if (e2 < 0) ++ goto out_parent; /* success */ ++ ++ /* when the available size is equal, select upper one */ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, err); ++ b = br->br_wbr->wbr_bytes; ++ AuDbg("b%d, %llu\n", err, b); ++ ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ br = au_sbr(sb, bindex); ++ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) { ++ b = br->br_wbr->wbr_bytes; ++ err = bindex; ++ AuDbg("b%d, %llu\n", err, b); ++ } ++ } ++ ++ out_parent: ++ dput(parent); ++ out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies for copyup */ ++ ++/* top down parent */ ++static int au_wbr_copyup_tdp(struct dentry *dentry) ++{ ++ return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0); ++} ++ ++/* bottom up parent */ ++static int au_wbr_copyup_bup(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bindex, bstart; ++ struct dentry *parent, *h_parent; ++ struct super_block *sb; ++ ++ err = -EROFS; ++ sb = dentry->d_sb; ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(parent); ++ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = bindex; ++ break; ++ } ++ } ++ dput(parent); ++ ++ /* bottom up here */ ++ if (unlikely(err < 0)) ++ err = au_wbr_bu(sb, bstart - 1); ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* bottom up */ ++static int au_wbr_copyup_bu(struct dentry *dentry) ++{ ++ int err; ++ ++ err = au_wbr_bu(dentry->d_sb, au_dbstart(dentry)); ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_wbr_copyup_operations au_wbr_copyup_ops[] = { ++ [AuWbrCopyup_TDP] = { ++ .copyup = au_wbr_copyup_tdp ++ }, ++ [AuWbrCopyup_BUP] = { ++ .copyup = au_wbr_copyup_bup ++ }, ++ [AuWbrCopyup_BU] = { ++ .copyup = au_wbr_copyup_bu ++ } ++}; ++ ++struct au_wbr_create_operations au_wbr_create_ops[] = { ++ [AuWbrCreate_TDP] = { ++ .create = au_wbr_create_tdp ++ }, ++ [AuWbrCreate_RR] = { ++ .create = au_wbr_create_rr, ++ .init = au_wbr_create_init_rr ++ }, ++ [AuWbrCreate_MFS] = { ++ .create = au_wbr_create_mfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSV] = { ++ .create = au_wbr_create_mfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSRR] = { ++ .create = au_wbr_create_mfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSRRV] = { ++ .create = au_wbr_create_mfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFS] = { ++ .create = au_wbr_create_pmfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFSV] = { ++ .create = au_wbr_create_pmfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ } ++}; +diff -Nur linux-2.6.31-vanilla/fs/aufs/whout.c linux-2.6.31/fs/aufs/whout.c +--- linux-2.6.31-vanilla/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/whout.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,1052 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * whiteout for logical deletion and opaque directory ++ */ ++ ++#include <linux/fs.h> ++#include "aufs.h" ++ ++#define WH_MASK S_IRUGO ++ ++/* ++ * If a directory contains this file, then it is opaque. We start with the ++ * .wh. flag so that it is blocked by lookup. ++ */ ++static struct qstr diropq_name = { ++ .name = AUFS_WH_DIROPQ, ++ .len = sizeof(AUFS_WH_DIROPQ) - 1 ++}; ++ ++/* ++ * generate whiteout name, which is NOT terminated by NULL. ++ * @name: original d_name.name ++ * @len: original d_name.len ++ * @wh: whiteout qstr ++ * returns zero when succeeds, otherwise error. ++ * succeeded value as wh->name should be freed by kfree(). ++ */ ++int au_wh_name_alloc(struct qstr *wh, const struct qstr *name) ++{ ++ char *p; ++ ++ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN)) ++ return -ENAMETOOLONG; ++ ++ wh->len = name->len + AUFS_WH_PFX_LEN; ++ p = kmalloc(wh->len, GFP_NOFS); ++ wh->name = p; ++ if (p) { ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len); ++ /* smp_mb(); */ ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * test if the @wh_name exists under @h_parent. ++ * @try_sio specifies the necessary of super-io. ++ */ ++int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, ++ struct au_branch *br, int try_sio) ++{ ++ int err; ++ struct dentry *wh_dentry; ++ struct inode *h_dir; ++ ++ h_dir = h_parent->d_inode; ++ if (!try_sio) ++ wh_dentry = au_lkup_one(wh_name, h_parent, br, /*nd*/NULL); ++ else ++ wh_dentry = au_sio_lkup_one(wh_name, h_parent, br); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ err = 0; ++ if (!wh_dentry->d_inode) ++ goto out_wh; /* success */ ++ ++ err = 1; ++ if (S_ISREG(wh_dentry->d_inode->i_mode)) ++ goto out_wh; /* success */ ++ ++ err = -EIO; ++ AuIOErr("%.*s Invalid whiteout entry type 0%o.\n", ++ AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode); ++ ++ out_wh: ++ dput(wh_dentry); ++ out: ++ return err; ++} ++ ++/* ++ * test if the @h_dentry sets opaque or not. ++ */ ++int au_diropq_test(struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ h_dir = h_dentry->d_inode; ++ err = au_wh_test(h_dentry, &diropq_name, br, ++ au_test_h_perm_sio(h_dir, MAY_EXEC)); ++ return err; ++} ++ ++/* ++ * returns a negative dentry whose name is unique and temporary. ++ */ ++struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, ++ struct qstr *prefix) ++{ ++#define HEX_LEN 4 ++ struct dentry *dentry; ++ int i; ++ char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1 ++ + HEX_LEN + 1], *name, *p; ++ static unsigned short cnt; ++ struct qstr qs; ++ ++ name = defname; ++ qs.len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1; ++ if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) { ++ dentry = ERR_PTR(-ENAMETOOLONG); ++ if (unlikely(qs.len >= PATH_MAX)) ++ goto out; ++ dentry = ERR_PTR(-ENOMEM); ++ name = kmalloc(qs.len + 1, GFP_NOFS); ++ if (unlikely(!name)) ++ goto out; ++ } ++ ++ /* doubly whiteout-ed */ ++ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2); ++ p = name + AUFS_WH_PFX_LEN * 2; ++ memcpy(p, prefix->name, prefix->len); ++ p += prefix->len; ++ *p++ = '.'; ++ AuDebugOn(name + qs.len + 1 - p <= HEX_LEN); ++ ++ qs.name = name; ++ for (i = 0; i < 3; i++) { ++ sprintf(p, "%.*d", HEX_LEN, cnt++); ++ dentry = au_sio_lkup_one(&qs, h_parent, br); ++ if (IS_ERR(dentry) || !dentry->d_inode) ++ goto out_name; ++ dput(dentry); ++ } ++ /* AuWarn("could not get random name\n"); */ ++ dentry = ERR_PTR(-EEXIST); ++ AuDbg("%.*s\n", AuLNPair(&qs)); ++ BUG(); ++ ++ out_name: ++ if (name != defname) ++ kfree(name); ++ out: ++ return dentry; ++#undef HEX_LEN ++} ++ ++/* ++ * rename the @h_dentry on @br to the whiteouted temporary name. ++ */ ++int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = br->br_mnt ++ }; ++ struct inode *h_dir; ++ struct dentry *h_parent; ++ ++ h_parent = h_dentry->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ /* under the same dir, no need to lock_rename() */ ++ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path); ++ AuTraceErr(err); ++ dput(h_path.dentry); ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * functions for removing a whiteout ++ */ ++ ++static int do_unlink_wh(struct inode *h_dir, struct path *h_path) ++{ ++ int force; ++ ++ /* ++ * forces superio when the dir has a sticky bit. ++ * this may be a violation of unix fs semantics. ++ */ ++ force = (h_dir->i_mode & S_ISVTX) ++ && h_path->dentry->d_inode->i_uid != current_fsuid(); ++ return vfsub_unlink(h_dir, h_path, force); ++} ++ ++int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, ++ struct dentry *dentry) ++{ ++ int err; ++ ++ err = do_unlink_wh(h_dir, h_path); ++ if (!err && dentry) ++ au_set_dbwh(dentry, -1); ++ ++ return err; ++} ++ ++static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh, ++ struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = br->br_mnt ++ }; ++ ++ err = 0; ++ h_path.dentry = au_lkup_one(wh, h_parent, br, /*nd*/NULL); ++ if (IS_ERR(h_path.dentry)) ++ err = PTR_ERR(h_path.dentry); ++ else { ++ if (h_path.dentry->d_inode ++ && S_ISREG(h_path.dentry->d_inode->i_mode)) ++ err = do_unlink_wh(h_parent->d_inode, &h_path); ++ dput(h_path.dentry); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * initialize/clean whiteout for a branch ++ */ ++ ++static void au_wh_clean(struct inode *h_dir, struct path *whpath, ++ const int isdir) ++{ ++ int err; ++ ++ if (!whpath->dentry->d_inode) ++ return; ++ ++ err = mnt_want_write(whpath->mnt); ++ if (!err) { ++ if (isdir) ++ err = vfsub_rmdir(h_dir, whpath); ++ else ++ err = vfsub_unlink(h_dir, whpath, /*force*/0); ++ mnt_drop_write(whpath->mnt); ++ } ++ if (unlikely(err)) ++ AuWarn("failed removing %.*s (%d), ignored.\n", ++ AuDLNPair(whpath->dentry), err); ++} ++ ++static int test_linkable(struct dentry *h_root) ++{ ++ struct inode *h_dir = h_root->d_inode; ++ ++ if (h_dir->i_op->link) ++ return 0; ++ ++ AuErr("%.*s (%s) doesn't support link(2), use noplink and rw+nolwh\n", ++ AuDLNPair(h_root), au_sbtype(h_root->d_sb)); ++ return -ENOSYS; ++} ++ ++/* todo: should this mkdir be done in /sbin/mount.aufs helper? */ ++static int au_whdir(struct inode *h_dir, struct path *path) ++{ ++ int err; ++ ++ err = -EEXIST; ++ if (!path->dentry->d_inode) { ++ int mode = S_IRWXU; ++ ++ if (au_test_nfs(path->dentry->d_sb)) ++ mode |= S_IXUGO; ++ err = mnt_want_write(path->mnt); ++ if (!err) { ++ err = vfsub_mkdir(h_dir, path, mode); ++ mnt_drop_write(path->mnt); ++ } ++ } else if (S_ISDIR(path->dentry->d_inode->i_mode)) ++ err = 0; ++ else ++ AuErr("unknown %.*s exists\n", AuDLNPair(path->dentry)); ++ ++ return err; ++} ++ ++struct au_wh_base { ++ const struct qstr *name; ++ struct dentry *dentry; ++}; ++ ++static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/0); ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++} ++ ++/* ++ * returns tri-state, ++ * minus: error, caller should print the mesage ++ * zero: succuess ++ * plus: error, caller should NOT print the mesage ++ */ ++static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr, ++ int do_plink, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ h_dir = h_root->d_inode; ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/0); ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ if (do_plink) { ++ err = test_linkable(h_root); ++ if (unlikely(err)) { ++ err = 1; ++ goto out; ++ } ++ ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); ++ } else ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); ++ ++ out: ++ return err; ++} ++ ++/* ++ * for the moment, aufs supports the branch filesystem which does not support ++ * link(2). testing on FAT which does not support i_op->setattr() fully either, ++ * copyup failed. finally, such filesystem will not be used as the writable ++ * branch. ++ * ++ * returns tri-state, see above. ++ */ ++static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr, ++ int do_plink, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ WbrWhMustWriteLock(wbr); ++ ++ err = test_linkable(h_root); ++ if (unlikely(err)) { ++ err = 1; ++ goto out; ++ } ++ ++ /* ++ * todo: should this create be done in /sbin/mount.aufs helper? ++ */ ++ err = -EEXIST; ++ h_dir = h_root->d_inode; ++ if (!base[AuBrWh_BASE].dentry->d_inode) { ++ err = mnt_want_write(h_path->mnt); ++ if (!err) { ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ err = vfsub_create(h_dir, h_path, WH_MASK); ++ mnt_drop_write(h_path->mnt); ++ } ++ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode)) ++ err = 0; ++ else ++ AuErr("unknown %.*s/%.*s exists\n", ++ AuDLNPair(h_root), AuDLNPair(base[AuBrWh_BASE].dentry)); ++ if (unlikely(err)) ++ goto out; ++ ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ if (do_plink) { ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); ++ } else ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry); ++ ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); ++ ++ out: ++ return err; ++} ++ ++/* ++ * initialize the whiteout base file/dir for @br. ++ */ ++int au_wh_init(struct dentry *h_root, struct au_branch *br, ++ struct super_block *sb) ++{ ++ int err, i; ++ const unsigned char do_plink ++ = !!au_opt_test(au_mntflags(sb), PLINK); ++ struct path path = { ++ .mnt = br->br_mnt ++ }; ++ struct inode *h_dir; ++ struct au_wbr *wbr = br->br_wbr; ++ static const struct qstr base_name[] = { ++ [AuBrWh_BASE] = { ++ .name = AUFS_BASE_NAME, ++ .len = sizeof(AUFS_BASE_NAME) - 1 ++ }, ++ [AuBrWh_PLINK] = { ++ .name = AUFS_PLINKDIR_NAME, ++ .len = sizeof(AUFS_PLINKDIR_NAME) - 1 ++ }, ++ [AuBrWh_ORPH] = { ++ .name = AUFS_ORPHDIR_NAME, ++ .len = sizeof(AUFS_ORPHDIR_NAME) - 1 ++ } ++ }; ++ struct au_wh_base base[] = { ++ [AuBrWh_BASE] = { ++ .name = base_name + AuBrWh_BASE, ++ .dentry = NULL ++ }, ++ [AuBrWh_PLINK] = { ++ .name = base_name + AuBrWh_PLINK, ++ .dentry = NULL ++ }, ++ [AuBrWh_ORPH] = { ++ .name = base_name + AuBrWh_ORPH, ++ .dentry = NULL ++ } ++ }; ++ ++ if (wbr) ++ WbrWhMustWriteLock(wbr); ++ ++ h_dir = h_root->d_inode; ++ for (i = 0; i < AuBrWh_Last; i++) { ++ /* doubly whiteouted */ ++ struct dentry *d; ++ ++ d = au_wh_lkup(h_root, (void *)base[i].name, br); ++ err = PTR_ERR(d); ++ if (IS_ERR(d)) ++ goto out; ++ ++ base[i].dentry = d; ++ AuDebugOn(wbr ++ && wbr->wbr_wh[i] ++ && wbr->wbr_wh[i] != base[i].dentry); ++ } ++ ++ if (wbr) ++ for (i = 0; i < AuBrWh_Last; i++) { ++ dput(wbr->wbr_wh[i]); ++ wbr->wbr_wh[i] = NULL; ++ } ++ ++ err = 0; ++ ++ switch (br->br_perm) { ++ case AuBrPerm_RO: ++ case AuBrPerm_ROWH: ++ case AuBrPerm_RR: ++ case AuBrPerm_RRWH: ++ au_wh_init_ro(h_dir, base, &path); ++ break; ++ ++ case AuBrPerm_RWNoLinkWH: ++ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path); ++ if (err > 0) ++ goto out; ++ else if (err) ++ goto out_err; ++ break; ++ ++ case AuBrPerm_RW: ++ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path); ++ if (err > 0) ++ goto out; ++ else if (err) ++ goto out_err; ++ break; ++ ++ default: ++ BUG(); ++ } ++ goto out; /* success */ ++ ++ out_err: ++ AuErr("an error(%d) on the writable branch %.*s(%s)\n", ++ err, AuDLNPair(h_root), au_sbtype(h_root->d_sb)); ++ out: ++ for (i = 0; i < AuBrWh_Last; i++) ++ dput(base[i].dentry); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * whiteouts are all hard-linked usually. ++ * when its link count reaches a ceiling, we create a new whiteout base ++ * asynchronously. ++ */ ++ ++struct reinit_br_wh { ++ struct super_block *sb; ++ struct au_branch *br; ++}; ++ ++static void reinit_br_wh(void *arg) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct path h_path; ++ struct reinit_br_wh *a = arg; ++ struct au_wbr *wbr; ++ struct inode *dir; ++ struct dentry *h_root; ++ struct au_hinode *hdir; ++ ++ err = 0; ++ wbr = a->br->br_wbr; ++ /* big aufs lock */ ++ si_noflush_write_lock(a->sb); ++ if (!au_br_writable(a->br->br_perm)) ++ goto out; ++ bindex = au_br_index(a->sb, a->br->br_id); ++ if (unlikely(bindex < 0)) ++ goto out; ++ ++ di_read_lock_parent(a->sb->s_root, AuLock_IR); ++ dir = a->sb->s_root->d_inode; ++ hdir = au_hi(dir, bindex); ++ h_root = au_h_dptr(a->sb->s_root, bindex); ++ ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ wbr_wh_write_lock(wbr); ++ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode, ++ h_root, a->br); ++ if (!err) { ++ err = mnt_want_write(a->br->br_mnt); ++ if (!err) { ++ h_path.dentry = wbr->wbr_whbase; ++ h_path.mnt = a->br->br_mnt; ++ err = vfsub_unlink(hdir->hi_inode, &h_path, /*force*/0); ++ mnt_drop_write(a->br->br_mnt); ++ } ++ } else { ++ AuWarn("%.*s is moved, ignored\n", AuDLNPair(wbr->wbr_whbase)); ++ err = 0; ++ } ++ dput(wbr->wbr_whbase); ++ wbr->wbr_whbase = NULL; ++ if (!err) ++ err = au_wh_init(h_root, a->br, a->sb); ++ wbr_wh_write_unlock(wbr); ++ au_hin_imtx_unlock(hdir); ++ di_read_unlock(a->sb->s_root, AuLock_IR); ++ ++ out: ++ if (wbr) ++ atomic_dec(&wbr->wbr_wh_running); ++ atomic_dec(&a->br->br_count); ++ au_nwt_done(&au_sbi(a->sb)->si_nowait); ++ si_write_unlock(a->sb); ++ kfree(arg); ++ if (unlikely(err)) ++ AuIOErr("err %d\n", err); ++} ++ ++static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br) ++{ ++ int do_dec, wkq_err; ++ struct reinit_br_wh *arg; ++ ++ do_dec = 1; ++ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1) ++ goto out; ++ ++ /* ignore ENOMEM */ ++ arg = kmalloc(sizeof(*arg), GFP_NOFS); ++ if (arg) { ++ /* ++ * dec(wh_running), kfree(arg) and dec(br_count) ++ * in reinit function ++ */ ++ arg->sb = sb; ++ arg->br = br; ++ atomic_inc(&br->br_count); ++ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb); ++ if (unlikely(wkq_err)) { ++ atomic_dec(&br->br_wbr->wbr_wh_running); ++ atomic_dec(&br->br_count); ++ kfree(arg); ++ } ++ do_dec = 0; ++ } ++ ++ out: ++ if (do_dec) ++ atomic_dec(&br->br_wbr->wbr_wh_running); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create the whiteout @wh. ++ */ ++static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex, ++ struct dentry *wh) ++{ ++ int err; ++ struct path h_path = { ++ .dentry = wh ++ }; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ ++ h_parent = wh->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ br = au_sbr(sb, bindex); ++ h_path.mnt = br->br_mnt; ++ wbr = br->br_wbr; ++ wbr_wh_read_lock(wbr); ++ if (wbr->wbr_whbase) { ++ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path); ++ if (!err || err != -EMLINK) ++ goto out; ++ ++ /* link count full. re-initialize br_whbase. */ ++ kick_reinit_br_wh(sb, br); ++ } ++ ++ /* return this error in this context */ ++ err = vfsub_create(h_dir, &h_path, WH_MASK); ++ ++ out: ++ wbr_wh_read_unlock(wbr); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create or remove the diropq. ++ */ ++static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags) ++{ ++ struct dentry *opq_dentry, *h_dentry; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, bindex); ++ h_dentry = au_h_dptr(dentry, bindex); ++ opq_dentry = au_lkup_one(&diropq_name, h_dentry, br, /*nd*/NULL); ++ if (IS_ERR(opq_dentry)) ++ goto out; ++ ++ if (au_ftest_diropq(flags, CREATE)) { ++ err = link_or_create_wh(sb, bindex, opq_dentry); ++ if (!err) { ++ au_set_dbdiropq(dentry, bindex); ++ goto out; /* success */ ++ } ++ } else { ++ struct path tmp = { ++ .dentry = opq_dentry, ++ .mnt = br->br_mnt ++ }; ++ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp); ++ if (!err) ++ au_set_dbdiropq(dentry, -1); ++ } ++ dput(opq_dentry); ++ opq_dentry = ERR_PTR(err); ++ ++ out: ++ return opq_dentry; ++} ++ ++struct do_diropq_args { ++ struct dentry **errp; ++ struct dentry *dentry; ++ aufs_bindex_t bindex; ++ unsigned int flags; ++}; ++ ++static void call_do_diropq(void *args) ++{ ++ struct do_diropq_args *a = args; ++ *a->errp = do_diropq(a->dentry, a->bindex, a->flags); ++} ++ ++struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags) ++{ ++ struct dentry *diropq, *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE)) ++ diropq = do_diropq(dentry, bindex, flags); ++ else { ++ int wkq_err; ++ struct do_diropq_args args = { ++ .errp = &diropq, ++ .dentry = dentry, ++ .bindex = bindex, ++ .flags = flags ++ }; ++ ++ wkq_err = au_wkq_wait(call_do_diropq, &args); ++ if (unlikely(wkq_err)) ++ diropq = ERR_PTR(wkq_err); ++ } ++ ++ return diropq; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * lookup whiteout dentry. ++ * @h_parent: lower parent dentry which must exist and be locked ++ * @base_name: name of dentry which will be whiteouted ++ * returns dentry for whiteout. ++ */ ++struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, ++ struct au_branch *br) ++{ ++ int err; ++ struct qstr wh_name; ++ struct dentry *wh_dentry; ++ ++ err = au_wh_name_alloc(&wh_name, base_name); ++ wh_dentry = ERR_PTR(err); ++ if (!err) { ++ wh_dentry = au_lkup_one(&wh_name, h_parent, br, /*nd*/NULL); ++ kfree(wh_name.name); ++ } ++ return wh_dentry; ++} ++ ++/* ++ * link/create a whiteout for @dentry on @bindex. ++ */ ++struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent) ++{ ++ struct dentry *wh_dentry; ++ struct super_block *sb; ++ int err; ++ ++ sb = dentry->d_sb; ++ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex)); ++ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) { ++ err = link_or_create_wh(sb, bindex, wh_dentry); ++ if (!err) ++ au_set_dbwh(dentry, bindex); ++ else { ++ dput(wh_dentry); ++ wh_dentry = ERR_PTR(err); ++ } ++ } ++ ++ return wh_dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Delete all whiteouts in this directory on branch bindex. */ ++static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist, ++ aufs_bindex_t bindex, struct au_branch *br) ++{ ++ int err; ++ unsigned long ul, n; ++ struct qstr wh_name; ++ char *p; ++ struct hlist_head *head; ++ struct au_vdir_wh *tpos; ++ struct hlist_node *pos; ++ struct au_vdir_destr *str; ++ ++ err = -ENOMEM; ++ p = __getname(); ++ wh_name.name = p; ++ if (unlikely(!wh_name.name)) ++ goto out; ++ ++ err = 0; ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ p += AUFS_WH_PFX_LEN; ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (ul = 0; !err && ul < n; ul++, head++) { ++ hlist_for_each_entry(tpos, pos, head, wh_hash) { ++ if (tpos->wh_bindex != bindex) ++ continue; ++ ++ str = &tpos->wh_str; ++ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) { ++ memcpy(p, str->name, str->len); ++ wh_name.len = AUFS_WH_PFX_LEN + str->len; ++ err = unlink_wh_name(h_dentry, &wh_name, br); ++ if (!err) ++ continue; ++ break; ++ } ++ AuIOErr("whiteout name too long %.*s\n", ++ str->len, str->name); ++ err = -EIO; ++ break; ++ } ++ } ++ __putname(wh_name.name); ++ ++ out: ++ return err; ++} ++ ++struct del_wh_children_args { ++ int *errp; ++ struct dentry *h_dentry; ++ struct au_nhash *whlist; ++ aufs_bindex_t bindex; ++ struct au_branch *br; ++}; ++ ++static void call_del_wh_children(void *args) ++{ ++ struct del_wh_children_args *a = args; ++ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp) ++{ ++ struct au_whtmp_rmdir *whtmp; ++ int err; ++ unsigned int rdhash; ++ ++ SiMustAnyLock(sb); ++ ++ whtmp = kmalloc(sizeof(*whtmp), gfp); ++ if (unlikely(!whtmp)) { ++ whtmp = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ ++ whtmp->dir = NULL; ++ whtmp->wh_dentry = NULL; ++ /* no estimation for dir size */ ++ rdhash = au_sbi(sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = AUFS_RDHASH_DEF; ++ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp); ++ if (unlikely(err)) { ++ kfree(whtmp); ++ whtmp = ERR_PTR(err); ++ } ++ ++ out: ++ return whtmp; ++} ++ ++void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp) ++{ ++ dput(whtmp->wh_dentry); ++ iput(whtmp->dir); ++ au_nhash_wh_free(&whtmp->whlist); ++ kfree(whtmp); ++} ++ ++/* ++ * rmdir the whiteouted temporary named dir @h_dentry. ++ * @whlist: whiteouted children. ++ */ ++int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_nhash *whlist) ++{ ++ int err; ++ struct path h_tmp; ++ struct inode *wh_inode, *h_dir; ++ struct au_branch *br; ++ ++ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(h_dir); ++ ++ br = au_sbr(dir->i_sb, bindex); ++ wh_inode = wh_dentry->d_inode; ++ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD); ++ ++ /* ++ * someone else might change some whiteouts while we were sleeping. ++ * it means this whlist may have an obsoleted entry. ++ */ ++ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE)) ++ err = del_wh_children(wh_dentry, whlist, bindex, br); ++ else { ++ int wkq_err; ++ struct del_wh_children_args args = { ++ .errp = &err, ++ .h_dentry = wh_dentry, ++ .whlist = whlist, ++ .bindex = bindex, ++ .br = br ++ }; ++ ++ wkq_err = au_wkq_wait(call_del_wh_children, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ mutex_unlock(&wh_inode->i_mutex); ++ ++ if (!err) { ++ h_tmp.dentry = wh_dentry; ++ h_tmp.mnt = br->br_mnt; ++ err = vfsub_rmdir(h_dir, &h_tmp); ++ /* d_drop(h_dentry); */ ++ } ++ ++ if (!err) { ++ if (au_ibstart(dir) == bindex) { ++ au_cpup_attr_timesizes(dir); ++ drop_nlink(dir); ++ } ++ return 0; /* success */ ++ } ++ ++ AuWarn("failed removing %.*s(%d), ignored\n", ++ AuDLNPair(wh_dentry), err); ++ return err; ++} ++ ++static void call_rmdir_whtmp(void *args) ++{ ++ int err; ++ struct au_whtmp_rmdir *a = args; ++ struct super_block *sb; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ struct au_branch *br; ++ struct au_hinode *hdir; ++ ++ /* rmdir by nfsd may cause deadlock with this i_mutex */ ++ /* mutex_lock(&a->dir->i_mutex); */ ++ sb = a->dir->i_sb; ++ si_noflush_read_lock(sb); ++ err = au_test_ro(sb, a->bindex, NULL); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -EIO; ++ br = au_sbr(sb, a->bindex); ++ ii_write_lock_parent(a->dir); ++ h_parent = dget_parent(a->wh_dentry); ++ h_dir = h_parent->d_inode; ++ hdir = au_hi(a->dir, a->bindex); ++ au_hin_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, br); ++ if (!err) { ++ err = mnt_want_write(br->br_mnt); ++ if (!err) { ++ err = au_whtmp_rmdir(a->dir, a->bindex, a->wh_dentry, ++ &a->whlist); ++ mnt_drop_write(br->br_mnt); ++ } ++ } ++ au_hin_imtx_unlock(hdir); ++ dput(h_parent); ++ ii_write_unlock(a->dir); ++ ++ out: ++ /* mutex_unlock(&a->dir->i_mutex); */ ++ au_nwt_done(&au_sbi(sb)->si_nowait); ++ si_read_unlock(sb); ++ au_whtmp_rmdir_free(a); ++ if (unlikely(err)) ++ AuIOErr("err %d\n", err); ++} ++ ++void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_whtmp_rmdir *args) ++{ ++ int wkq_err; ++ ++ IMustLock(dir); ++ ++ /* all post-process will be done in do_rmdir_whtmp(). */ ++ args->dir = au_igrab(dir); ++ args->bindex = bindex; ++ args->wh_dentry = dget(wh_dentry); ++ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb); ++ if (unlikely(wkq_err)) { ++ AuWarn("rmdir error %.*s (%d), ignored\n", ++ AuDLNPair(wh_dentry), wkq_err); ++ au_whtmp_rmdir_free(args); ++ } ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/whout.h linux-2.6.31/fs/aufs/whout.h +--- linux-2.6.31-vanilla/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/whout.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,87 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * whiteout for logical deletion and opaque directory ++ */ ++ ++#ifndef __AUFS_WHOUT_H__ ++#define __AUFS_WHOUT_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/aufs_type.h> ++#include "dir.h" ++ ++/* whout.c */ ++int au_wh_name_alloc(struct qstr *wh, const struct qstr *name); ++struct au_branch; ++int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, ++ struct au_branch *br, int try_sio); ++int au_diropq_test(struct dentry *h_dentry, struct au_branch *br); ++struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, ++ struct qstr *prefix); ++int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br); ++int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, ++ struct dentry *dentry); ++int au_wh_init(struct dentry *h_parent, struct au_branch *br, ++ struct super_block *sb); ++ ++/* diropq flags */ ++#define AuDiropq_CREATE 1 ++#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name) ++#define au_fset_diropq(flags, name) { (flags) |= AuDiropq_##name; } ++#define au_fclr_diropq(flags, name) { (flags) &= ~AuDiropq_##name; } ++ ++struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags); ++struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, ++ struct au_branch *br); ++struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent); ++ ++/* real rmdir for the whiteout-ed dir */ ++struct au_whtmp_rmdir { ++ struct inode *dir; ++ aufs_bindex_t bindex; ++ struct dentry *wh_dentry; ++ struct au_nhash whlist; ++}; ++ ++struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp); ++void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp); ++int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_nhash *whlist); ++void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_whtmp_rmdir *args); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct dentry *au_diropq_create(struct dentry *dentry, ++ aufs_bindex_t bindex) ++{ ++ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE); ++} ++ ++static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE)); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_WHOUT_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/wkq.c linux-2.6.31/fs/aufs/wkq.c +--- linux-2.6.31-vanilla/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/wkq.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,259 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * workqueue for asynchronous/super-io operations ++ * todo: try new dredential scheme ++ */ ++ ++#include <linux/module.h> ++#include "aufs.h" ++ ++/* internal workqueue named AUFS_WKQ_NAME */ ++static struct au_wkq { ++ struct workqueue_struct *q; ++ ++ /* balancing */ ++ atomic_t busy; ++} *au_wkq; ++ ++struct au_wkinfo { ++ struct work_struct wk; ++ struct super_block *sb; ++ ++ unsigned int flags; /* see wkq.h */ ++ ++ au_wkq_func_t func; ++ void *args; ++ ++ atomic_t *busyp; ++ struct completion *comp; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int enqueue(struct au_wkq *wkq, struct au_wkinfo *wkinfo) ++{ ++ wkinfo->busyp = &wkq->busy; ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) ++ return !queue_work(wkq->q, &wkinfo->wk); ++ else ++ return !schedule_work(&wkinfo->wk); ++} ++ ++static void do_wkq(struct au_wkinfo *wkinfo) ++{ ++ unsigned int idle, n; ++ int i, idle_idx; ++ ++ while (1) { ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) { ++ idle_idx = 0; ++ idle = UINT_MAX; ++ for (i = 0; i < aufs_nwkq; i++) { ++ n = atomic_inc_return(&au_wkq[i].busy); ++ if (n == 1 && !enqueue(au_wkq + i, wkinfo)) ++ return; /* success */ ++ ++ if (n < idle) { ++ idle_idx = i; ++ idle = n; ++ } ++ atomic_dec(&au_wkq[i].busy); ++ } ++ } else ++ idle_idx = aufs_nwkq; ++ ++ atomic_inc(&au_wkq[idle_idx].busy); ++ if (!enqueue(au_wkq + idle_idx, wkinfo)) ++ return; /* success */ ++ ++ /* impossible? */ ++ AuWarn1("failed to queue_work()\n"); ++ yield(); ++ } ++} ++ ++static void wkq_func(struct work_struct *wk) ++{ ++ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk); ++ ++ wkinfo->func(wkinfo->args); ++ atomic_dec_return(wkinfo->busyp); ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) ++ complete(wkinfo->comp); ++ else { ++ kobject_put(&au_sbi(wkinfo->sb)->si_kobj); ++ module_put(THIS_MODULE); ++ kfree(wkinfo); ++ } ++} ++ ++/* ++ * Since struct completion is large, try allocating it dynamically. ++ */ ++#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) ++#define AuWkqCompDeclare(name) struct completion *comp = NULL ++ ++static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) ++{ ++ *comp = kmalloc(sizeof(**comp), GFP_NOFS); ++ if (*comp) { ++ init_completion(*comp); ++ wkinfo->comp = *comp; ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++static void au_wkq_comp_free(struct completion *comp) ++{ ++ kfree(comp); ++} ++ ++#else ++ ++/* no braces */ ++#define AuWkqCompDeclare(name) \ ++ DECLARE_COMPLETION_ONSTACK(_ ## name); \ ++ struct completion *comp = &_ ## name ++ ++static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) ++{ ++ wkinfo->comp = *comp; ++ return 0; ++} ++ ++static void au_wkq_comp_free(struct completion *comp __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* 4KSTACKS */ ++ ++static void au_wkq_run(struct au_wkinfo *wkinfo) ++{ ++ au_dbg_verify_kthread(); ++ INIT_WORK(&wkinfo->wk, wkq_func); ++ do_wkq(wkinfo); ++} ++ ++int au_wkq_wait(au_wkq_func_t func, void *args) ++{ ++ int err; ++ AuWkqCompDeclare(comp); ++ struct au_wkinfo wkinfo = { ++ .flags = AuWkq_WAIT, ++ .func = func, ++ .args = args ++ }; ++ ++ err = au_wkq_comp_alloc(&wkinfo, &comp); ++ if (!err) { ++ au_wkq_run(&wkinfo); ++ /* no timeout, no interrupt */ ++ wait_for_completion(wkinfo.comp); ++ au_wkq_comp_free(comp); ++ } ++ ++ return err; ++ ++} ++ ++int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb) ++{ ++ int err; ++ struct au_wkinfo *wkinfo; ++ ++ atomic_inc(&au_sbi(sb)->si_nowait.nw_len); ++ ++ /* ++ * wkq_func() must free this wkinfo. ++ * it highly depends upon the implementation of workqueue. ++ */ ++ err = 0; ++ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS); ++ if (wkinfo) { ++ wkinfo->sb = sb; ++ wkinfo->flags = !AuWkq_WAIT; ++ wkinfo->func = func; ++ wkinfo->args = args; ++ wkinfo->comp = NULL; ++ kobject_get(&au_sbi(sb)->si_kobj); ++ __module_get(THIS_MODULE); ++ ++ au_wkq_run(wkinfo); ++ } else { ++ err = -ENOMEM; ++ atomic_dec(&au_sbi(sb)->si_nowait.nw_len); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_nwt_init(struct au_nowait_tasks *nwt) ++{ ++ atomic_set(&nwt->nw_len, 0); ++ /* smp_mb();*/ /* atomic_set */ ++ init_waitqueue_head(&nwt->nw_wq); ++} ++ ++void au_wkq_fin(void) ++{ ++ int i; ++ ++ for (i = 0; i < aufs_nwkq; i++) ++ if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) ++ destroy_workqueue(au_wkq[i].q); ++ kfree(au_wkq); ++} ++ ++int __init au_wkq_init(void) ++{ ++ int err, i; ++ struct au_wkq *nowaitq; ++ ++ /* '+1' is for accounting of nowait queue */ ++ err = -ENOMEM; ++ au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_NOFS); ++ if (unlikely(!au_wkq)) ++ goto out; ++ ++ err = 0; ++ for (i = 0; i < aufs_nwkq; i++) { ++ au_wkq[i].q = create_singlethread_workqueue(AUFS_WKQ_NAME); ++ if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) { ++ atomic_set(&au_wkq[i].busy, 0); ++ continue; ++ } ++ ++ err = PTR_ERR(au_wkq[i].q); ++ au_wkq_fin(); ++ goto out; ++ } ++ ++ /* nowait accounting */ ++ nowaitq = au_wkq + aufs_nwkq; ++ atomic_set(&nowaitq->busy, 0); ++ nowaitq->q = NULL; ++ /* smp_mb(); */ /* atomic_set */ ++ ++ out: ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/aufs/wkq.h linux-2.6.31/fs/aufs/wkq.h +--- linux-2.6.31-vanilla/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/wkq.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,82 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * workqueue for asynchronous/super-io operations ++ * todo: try new credentials management scheme ++ */ ++ ++#ifndef __AUFS_WKQ_H__ ++#define __AUFS_WKQ_H__ ++ ++#ifdef __KERNEL__ ++ ++#include <linux/sched.h> ++#include <linux/wait.h> ++#include <linux/aufs_type.h> ++ ++struct super_block; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue ++ */ ++struct au_nowait_tasks { ++ atomic_t nw_len; ++ wait_queue_head_t nw_wq; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++typedef void (*au_wkq_func_t)(void *args); ++ ++/* wkq flags */ ++#define AuWkq_WAIT 1 ++#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) ++#define au_fset_wkq(flags, name) { (flags) |= AuWkq_##name; } ++#define au_fclr_wkq(flags, name) { (flags) &= ~AuWkq_##name; } ++ ++/* wkq.c */ ++int au_wkq_wait(au_wkq_func_t func, void *args); ++int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb); ++void au_nwt_init(struct au_nowait_tasks *nwt); ++int __init au_wkq_init(void); ++void au_wkq_fin(void); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline int au_test_wkq(struct task_struct *tsk) ++{ ++ return !tsk->mm && !strcmp(tsk->comm, AUFS_WKQ_NAME); ++} ++ ++static inline void au_nwt_done(struct au_nowait_tasks *nwt) ++{ ++ if (!atomic_dec_return(&nwt->nw_len)) ++ wake_up_all(&nwt->nw_wq); ++} ++ ++static inline int au_nwt_flush(struct au_nowait_tasks *nwt) ++{ ++ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); ++ return 0; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_WKQ_H__ */ +diff -Nur linux-2.6.31-vanilla/fs/aufs/xino.c linux-2.6.31/fs/aufs/xino.c +--- linux-2.6.31-vanilla/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/fs/aufs/xino.c 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,1203 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * external inode number translation table and bitmap ++ */ ++ ++#include <linux/file.h> ++#include <linux/seq_file.h> ++#include <linux/uaccess.h> ++#include "aufs.h" ++ ++ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ do { ++ /* todo: signal_pending? */ ++ err = func(file, (char __user *)buf, size, pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ set_fs(oldfs); ++ ++#if 0 /* reserved for future use */ ++ if (err > 0) ++ fsnotify_access(file->f_dentry); ++#endif ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *buf, ++ size_t size, loff_t *pos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ lockdep_off(); ++ do { ++ /* todo: signal_pending? */ ++ err = func(file, (const char __user *)buf, size, pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ lockdep_on(); ++ set_fs(oldfs); ++ ++#if 0 /* reserved for future use */ ++ if (err > 0) ++ fsnotify_modify(file->f_dentry); ++#endif ++ ++ return err; ++} ++ ++struct do_xino_fwrite_args { ++ ssize_t *errp; ++ au_writef_t func; ++ struct file *file; ++ void *buf; ++ size_t size; ++ loff_t *pos; ++}; ++ ++static void call_do_xino_fwrite(void *args) ++{ ++ struct do_xino_fwrite_args *a = args; ++ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); ++} ++ ++ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos) ++{ ++ ssize_t err; ++ ++ /* todo: signal block and no wkq? */ ++ /* todo: new credential scheme */ ++ /* ++ * it breaks RLIMIT_FSIZE and normal user's limit, ++ * users should care about quota and real 'filesystem full.' ++ */ ++ if (!au_test_wkq(current)) { ++ int wkq_err; ++ struct do_xino_fwrite_args args = { ++ .errp = &err, ++ .func = func, ++ .file = file, ++ .buf = buf, ++ .size = size, ++ .pos = pos ++ }; ++ ++ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } else ++ err = do_xino_fwrite(func, file, buf, size, pos); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create a new xinofile at the same place/path as @base_file. ++ */ ++struct file *au_xino_create2(struct file *base_file, struct file *copy_src) ++{ ++ struct file *file; ++ struct dentry *base, *dentry, *parent; ++ struct inode *dir; ++ struct qstr *name; ++ int err; ++ struct path path; ++ ++ base = base_file->f_dentry; ++ parent = base->d_parent; /* dir inode is locked */ ++ dir = parent->d_inode; ++ IMustLock(dir); ++ ++ file = ERR_PTR(-EINVAL); ++ name = &base->d_name; ++ dentry = vfsub_lookup_one_len(name->name, parent, name->len); ++ if (IS_ERR(dentry)) { ++ file = (void *)dentry; ++ AuErr("%.*s lookup err %ld\n", AuLNPair(name), PTR_ERR(dentry)); ++ goto out; ++ } ++ ++ /* no need to mnt_want_write() since we call dentry_open() later */ ++ err = vfs_create(dir, dentry, S_IRUGO | S_IWUGO, NULL); ++ if (unlikely(err)) { ++ file = ERR_PTR(err); ++ AuErr("%.*s create err %d\n", AuLNPair(name), err); ++ goto out_dput; ++ } ++ ++ path.dentry = dentry; ++ path.mnt = base_file->f_vfsmnt; ++ path_get(&path); ++ file = vfsub_dentry_open(&path, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, ++ current_cred()); ++ if (IS_ERR(file)) { ++ AuErr("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file)); ++ goto out_dput; ++ } ++ ++ err = vfsub_unlink(dir, &file->f_path, /*force*/0); ++ if (unlikely(err)) { ++ AuErr("%.*s unlink err %d\n", AuLNPair(name), err); ++ goto out_fput; ++ } ++ ++ if (copy_src) { ++ /* no one can touch copy_src xino */ ++ err = au_copy_file(file, copy_src, ++ i_size_read(copy_src->f_dentry->d_inode)); ++ if (unlikely(err)) { ++ AuErr("%.*s copy err %d\n", AuLNPair(name), err); ++ goto out_fput; ++ } ++ } ++ goto out_dput; /* success */ ++ ++ out_fput: ++ fput(file); ++ file = ERR_PTR(err); ++ out_dput: ++ dput(dentry); ++ out: ++ return file; ++} ++ ++struct au_xino_lock_dir { ++ struct au_hinode *hdir; ++ struct dentry *parent; ++ struct mutex *mtx; ++}; ++ ++static void au_xino_lock_dir(struct super_block *sb, struct file *xino, ++ struct au_xino_lock_dir *ldir) ++{ ++ aufs_bindex_t brid, bindex; ++ ++ ldir->hdir = NULL; ++ bindex = -1; ++ brid = au_xino_brid(sb); ++ if (brid >= 0) ++ bindex = au_br_index(sb, brid); ++ if (bindex >= 0) { ++ ldir->hdir = au_hi(sb->s_root->d_inode, bindex); ++ au_hin_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT); ++ } else { ++ ldir->parent = dget_parent(xino->f_dentry); ++ ldir->mtx = &ldir->parent->d_inode->i_mutex; ++ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT); ++ } ++} ++ ++static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir) ++{ ++ if (ldir->hdir) ++ au_hin_imtx_unlock(ldir->hdir); ++ else { ++ mutex_unlock(ldir->mtx); ++ dput(ldir->parent); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* trucate xino files asynchronously */ ++ ++int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ aufs_bindex_t bi, bend; ++ struct au_branch *br; ++ struct file *new_xino, *file; ++ struct super_block *h_sb; ++ struct au_xino_lock_dir ldir; ++ ++ err = -EINVAL; ++ bend = au_sbend(sb); ++ if (unlikely(bindex < 0 || bend < bindex)) ++ goto out; ++ br = au_sbr(sb, bindex); ++ file = br->br_xino.xi_file; ++ if (!file) ++ goto out; ++ ++ au_xino_lock_dir(sb, file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ new_xino = au_xino_create2(file, file); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(new_xino); ++ if (IS_ERR(new_xino)) ++ goto out; ++ err = 0; ++ fput(file); ++ br->br_xino.xi_file = new_xino; ++ ++ h_sb = br->br_mnt->mnt_sb; ++ for (bi = 0; bi <= bend; bi++) { ++ if (unlikely(bi == bindex)) ++ continue; ++ br = au_sbr(sb, bi); ++ if (br->br_mnt->mnt_sb != h_sb) ++ continue; ++ ++ fput(br->br_xino.xi_file); ++ br->br_xino.xi_file = new_xino; ++ get_file(new_xino); ++ } ++ ++ out: ++ return err; ++} ++ ++struct xino_do_trunc_args { ++ struct super_block *sb; ++ struct au_branch *br; ++}; ++ ++static void xino_do_trunc(void *_args) ++{ ++ struct xino_do_trunc_args *args = _args; ++ struct super_block *sb; ++ struct au_branch *br; ++ struct inode *dir; ++ int err; ++ aufs_bindex_t bindex; ++ ++ err = 0; ++ sb = args->sb; ++ dir = sb->s_root->d_inode; ++ br = args->br; ++ ++ si_noflush_write_lock(sb); ++ ii_read_lock_parent(dir); ++ bindex = au_br_index(sb, br->br_id); ++ err = au_xino_trunc(sb, bindex); ++ if (!err ++ && br->br_xino.xi_file->f_dentry->d_inode->i_blocks ++ >= br->br_xino_upper) ++ br->br_xino_upper += AUFS_XINO_TRUNC_STEP; ++ ++ ii_read_unlock(dir); ++ if (unlikely(err)) ++ AuWarn("err b%d, (%d)\n", bindex, err); ++ atomic_dec(&br->br_xino_running); ++ atomic_dec(&br->br_count); ++ au_nwt_done(&au_sbi(sb)->si_nowait); ++ si_write_unlock(sb); ++ kfree(args); ++} ++ ++static void xino_try_trunc(struct super_block *sb, struct au_branch *br) ++{ ++ struct xino_do_trunc_args *args; ++ int wkq_err; ++ ++ if (br->br_xino.xi_file->f_dentry->d_inode->i_blocks ++ < br->br_xino_upper) ++ return; ++ ++ if (atomic_inc_return(&br->br_xino_running) > 1) ++ goto out; ++ ++ /* lock and kfree() will be called in trunc_xino() */ ++ args = kmalloc(sizeof(*args), GFP_NOFS); ++ if (unlikely(!args)) { ++ AuErr1("no memory\n"); ++ goto out_args; ++ } ++ ++ atomic_inc_return(&br->br_count); ++ args->sb = sb; ++ args->br = br; ++ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb); ++ if (!wkq_err) ++ return; /* success */ ++ ++ AuErr("wkq %d\n", wkq_err); ++ atomic_dec_return(&br->br_count); ++ ++ out_args: ++ kfree(args); ++ out: ++ atomic_dec_return(&br->br_xino_running); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_xino_do_write(au_writef_t write, struct file *file, ++ ino_t h_ino, ino_t ino) ++{ ++ loff_t pos; ++ ssize_t sz; ++ ++ pos = h_ino; ++ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) { ++ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); ++ return -EFBIG; ++ } ++ pos *= sizeof(ino); ++ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos); ++ if (sz == sizeof(ino)) ++ return 0; /* success */ ++ ++ AuIOErr("write failed (%zd)\n", sz); ++ return -EIO; ++} ++ ++/* ++ * write @ino to the xinofile for the specified branch{@sb, @bindex} ++ * at the position of @h_ino. ++ * even if @ino is zero, it is written to the xinofile and means no entry. ++ * if the size of the xino file on a specific filesystem exceeds the watermark, ++ * try truncating it. ++ */ ++int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino) ++{ ++ int err; ++ unsigned int mnt_flags; ++ struct au_branch *br; ++ ++ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max) ++ || ((loff_t)-1) > 0); ++ SiMustAnyLock(sb); ++ ++ mnt_flags = au_mntflags(sb); ++ if (!au_opt_test(mnt_flags, XINO)) ++ return 0; ++ ++ br = au_sbr(sb, bindex); ++ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, ++ h_ino, ino); ++ if (!err) { ++ if (au_opt_test(mnt_flags, TRUNC_XINO) ++ && au_test_fs_trunc_xino(br->br_mnt->mnt_sb)) ++ xino_try_trunc(sb, br); ++ return 0; /* success */ ++ } ++ ++ AuIOErr("write failed (%d)\n", err); ++ return -EIO; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* aufs inode number bitmap */ ++ ++static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE; ++static ino_t xib_calc_ino(unsigned long pindex, int bit) ++{ ++ ino_t ino; ++ ++ AuDebugOn(bit < 0 || page_bits <= bit); ++ ino = AUFS_FIRST_INO + pindex * page_bits + bit; ++ return ino; ++} ++ ++static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit) ++{ ++ AuDebugOn(ino < AUFS_FIRST_INO); ++ ino -= AUFS_FIRST_INO; ++ *pindex = ino / page_bits; ++ *bit = ino % page_bits; ++} ++ ++static int xib_pindex(struct super_block *sb, unsigned long pindex) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ struct au_sbinfo *sbinfo; ++ struct file *xib; ++ unsigned long *p; ++ ++ sbinfo = au_sbi(sb); ++ MtxMustLock(&sbinfo->si_xib_mtx); ++ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE ++ || !au_opt_test(sbinfo->si_mntflags, XINO)); ++ ++ if (pindex == sbinfo->si_xib_last_pindex) ++ return 0; ++ ++ xib = sbinfo->si_xib; ++ p = sbinfo->si_xib_buf; ++ pos = sbinfo->si_xib_last_pindex; ++ pos *= PAGE_SIZE; ++ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ if (unlikely(sz != PAGE_SIZE)) ++ goto out; ++ ++ pos = pindex; ++ pos *= PAGE_SIZE; ++ if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE) ++ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); ++ else { ++ memset(p, 0, PAGE_SIZE); ++ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ } ++ if (sz == PAGE_SIZE) { ++ sbinfo->si_xib_last_pindex = pindex; ++ return 0; /* success */ ++ } ++ ++ out: ++ AuIOErr1("write failed (%zd)\n", sz); ++ err = sz; ++ if (sz >= 0) ++ err = -EIO; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino) ++{ ++ int err, bit; ++ unsigned long pindex; ++ struct au_sbinfo *sbinfo; ++ ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return 0; ++ ++ err = 0; ++ if (ino) { ++ sbinfo = au_sbi(sb); ++ xib_calc_bit(ino, &pindex, &bit); ++ AuDebugOn(page_bits <= bit); ++ mutex_lock(&sbinfo->si_xib_mtx); ++ err = xib_pindex(sb, pindex); ++ if (!err) { ++ clear_bit(bit, sbinfo->si_xib_buf); ++ sbinfo->si_xib_next_bit = bit; ++ } ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ } ++ ++ if (!err) ++ err = au_xino_write(sb, bindex, h_ino, 0); ++ return err; ++} ++ ++/* get an unused inode number from bitmap */ ++ino_t au_xino_new_ino(struct super_block *sb) ++{ ++ ino_t ino; ++ unsigned long *p, pindex, ul, pend; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ int free_bit, err; ++ ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return iunique(sb, AUFS_FIRST_INO); ++ ++ sbinfo = au_sbi(sb); ++ mutex_lock(&sbinfo->si_xib_mtx); ++ p = sbinfo->si_xib_buf; ++ free_bit = sbinfo->si_xib_next_bit; ++ if (free_bit < page_bits && !test_bit(free_bit, p)) ++ goto out; /* success */ ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ ++ pindex = sbinfo->si_xib_last_pindex; ++ for (ul = pindex - 1; ul < ULONG_MAX; ul--) { ++ err = xib_pindex(sb, ul); ++ if (unlikely(err)) ++ goto out_err; ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ } ++ ++ file = sbinfo->si_xib; ++ pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE; ++ for (ul = pindex + 1; ul <= pend; ul++) { ++ err = xib_pindex(sb, ul); ++ if (unlikely(err)) ++ goto out_err; ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ } ++ BUG(); ++ ++ out: ++ set_bit(free_bit, p); ++ sbinfo->si_xib_next_bit++; ++ pindex = sbinfo->si_xib_last_pindex; ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ ino = xib_calc_ino(pindex, free_bit); ++ AuDbg("i%lu\n", (unsigned long)ino); ++ return ino; ++ out_err: ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ AuDbg("i0\n"); ++ return 0; ++} ++ ++/* ++ * read @ino from xinofile for the specified branch{@sb, @bindex} ++ * at the position of @h_ino. ++ * if @ino does not exist and @do_new is true, get new one. ++ */ ++int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t *ino) ++{ ++ int err; ++ ssize_t sz; ++ loff_t pos; ++ struct file *file; ++ struct au_sbinfo *sbinfo; ++ ++ *ino = 0; ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return 0; /* no xino */ ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ pos = h_ino; ++ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) { ++ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); ++ return -EFBIG; ++ } ++ pos *= sizeof(*ino); ++ ++ file = au_sbr(sb, bindex)->br_xino.xi_file; ++ if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*ino)) ++ return 0; /* no ino */ ++ ++ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos); ++ if (sz == sizeof(*ino)) ++ return 0; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xino read error (%zd)\n", sz); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* create and set a new xino file */ ++ ++struct file *au_xino_create(struct super_block *sb, char *fname, int silent) ++{ ++ struct file *file; ++ struct dentry *h_parent, *d; ++ struct inode *h_dir; ++ int err; ++ ++ /* ++ * at mount-time, and the xino file is the default path, ++ * hinotify is disabled so we have no inotify events to ignore. ++ * when a user specified the xino, we cannot get au_hdir to be ignored. ++ */ ++ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, ++ S_IRUGO | S_IWUGO); ++ if (IS_ERR(file)) { ++ if (!silent) ++ AuErr("open %s(%ld)\n", fname, PTR_ERR(file)); ++ return file; ++ } ++ ++ /* keep file count */ ++ h_parent = dget_parent(file->f_dentry); ++ h_dir = h_parent->d_inode; ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ /* mnt_want_write() is unnecessary here */ ++ err = vfsub_unlink(h_dir, &file->f_path, /*force*/0); ++ mutex_unlock(&h_dir->i_mutex); ++ dput(h_parent); ++ if (unlikely(err)) { ++ if (!silent) ++ AuErr("unlink %s(%d)\n", fname, err); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ d = file->f_dentry; ++ if (unlikely(sb == d->d_sb)) { ++ if (!silent) ++ AuErr("%s must be outside\n", fname); ++ goto out; ++ } ++ if (unlikely(au_test_fs_bad_xino(d->d_sb))) { ++ if (!silent) ++ AuErr("xino doesn't support %s(%s)\n", ++ fname, au_sbtype(d->d_sb)); ++ goto out; ++ } ++ return file; /* success */ ++ ++ out: ++ fput(file); ++ file = ERR_PTR(err); ++ return file; ++} ++ ++/* ++ * find another branch who is on the same filesystem of the specified ++ * branch{@btgt}. search until @bend. ++ */ ++static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt, ++ aufs_bindex_t bend) ++{ ++ aufs_bindex_t bindex; ++ struct super_block *tgt_sb = au_sbr_sb(sb, btgt); ++ ++ for (bindex = 0; bindex < btgt; bindex++) ++ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) ++ return bindex; ++ for (bindex++; bindex <= bend; bindex++) ++ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) ++ return bindex; ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * initialize the xinofile for the specified branch @br ++ * at the place/path where @base_file indicates. ++ * test whether another branch is on the same filesystem or not, ++ * if @do_test is true. ++ */ ++int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino, ++ struct file *base_file, int do_test) ++{ ++ int err; ++ ino_t ino; ++ aufs_bindex_t bend, bindex; ++ struct au_branch *shared_br, *b; ++ struct file *file; ++ struct super_block *tgt_sb; ++ ++ shared_br = NULL; ++ bend = au_sbend(sb); ++ if (do_test) { ++ tgt_sb = br->br_mnt->mnt_sb; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ b = au_sbr(sb, bindex); ++ if (tgt_sb == b->br_mnt->mnt_sb) { ++ shared_br = b; ++ break; ++ } ++ } ++ } ++ ++ if (!shared_br || !shared_br->br_xino.xi_file) { ++ struct au_xino_lock_dir ldir; ++ ++ au_xino_lock_dir(sb, base_file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ file = au_xino_create2(base_file, NULL); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ br->br_xino.xi_file = file; ++ } else { ++ br->br_xino.xi_file = shared_br->br_xino.xi_file; ++ get_file(br->br_xino.xi_file); ++ } ++ ++ ino = AUFS_ROOT_INO; ++ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, ++ h_ino, ino); ++ if (!err) ++ return 0; /* success */ ++ ++ ++ out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* trucate a xino bitmap file */ ++ ++/* todo: slow */ ++static int do_xib_restore(struct super_block *sb, struct file *file, void *page) ++{ ++ int err, bit; ++ ssize_t sz; ++ unsigned long pindex; ++ loff_t pos, pend; ++ struct au_sbinfo *sbinfo; ++ au_readf_t func; ++ ino_t *ino; ++ unsigned long *p; ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ MtxMustLock(&sbinfo->si_xib_mtx); ++ p = sbinfo->si_xib_buf; ++ func = sbinfo->si_xread; ++ pend = i_size_read(file->f_dentry->d_inode); ++ pos = 0; ++ while (pos < pend) { ++ sz = xino_fread(func, file, page, PAGE_SIZE, &pos); ++ err = sz; ++ if (unlikely(sz <= 0)) ++ goto out; ++ ++ err = 0; ++ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) { ++ if (unlikely(*ino < AUFS_FIRST_INO)) ++ continue; ++ ++ xib_calc_bit(*ino, &pindex, &bit); ++ AuDebugOn(page_bits <= bit); ++ err = xib_pindex(sb, pindex); ++ if (!err) ++ set_bit(bit, p); ++ else ++ goto out; ++ } ++ } ++ ++ out: ++ return err; ++} ++ ++static int xib_restore(struct super_block *sb) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ void *page; ++ ++ err = -ENOMEM; ++ page = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!page)) ++ goto out; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ for (bindex = 0; !err && bindex <= bend; bindex++) ++ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) ++ err = do_xib_restore ++ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page); ++ else ++ AuDbg("b%d\n", bindex); ++ free_page((unsigned long)page); ++ ++ out: ++ return err; ++} ++ ++int au_xib_trunc(struct super_block *sb) ++{ ++ int err; ++ ssize_t sz; ++ loff_t pos; ++ struct au_xino_lock_dir ldir; ++ struct au_sbinfo *sbinfo; ++ unsigned long *p; ++ struct file *file; ++ ++ SiMustWriteLock(sb); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ if (!au_opt_test(sbinfo->si_mntflags, XINO)) ++ goto out; ++ ++ file = sbinfo->si_xib; ++ if (i_size_read(file->f_dentry->d_inode) <= PAGE_SIZE) ++ goto out; ++ ++ au_xino_lock_dir(sb, file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ file = au_xino_create2(sbinfo->si_xib, NULL); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = file; ++ ++ p = sbinfo->si_xib_buf; ++ memset(p, 0, PAGE_SIZE); ++ pos = 0; ++ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos); ++ if (unlikely(sz != PAGE_SIZE)) { ++ err = sz; ++ AuIOErr("err %d\n", err); ++ if (sz >= 0) ++ err = -EIO; ++ goto out; ++ } ++ ++ mutex_lock(&sbinfo->si_xib_mtx); ++ /* mnt_want_write() is unnecessary here */ ++ err = xib_restore(sb); ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * xino mount option handlers ++ */ ++static au_readf_t find_readf(struct file *h_file) ++{ ++ const struct file_operations *fop = h_file->f_op; ++ ++ if (fop) { ++ if (fop->read) ++ return fop->read; ++ if (fop->aio_read) ++ return do_sync_read; ++ } ++ return ERR_PTR(-ENOSYS); ++} ++ ++static au_writef_t find_writef(struct file *h_file) ++{ ++ const struct file_operations *fop = h_file->f_op; ++ ++ if (fop) { ++ if (fop->write) ++ return fop->write; ++ if (fop->aio_write) ++ return do_sync_write; ++ } ++ return ERR_PTR(-ENOSYS); ++} ++ ++/* xino bitmap */ ++static void xino_clear_xib(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ if (sbinfo->si_xib) ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = NULL; ++ free_page((unsigned long)sbinfo->si_xib_buf); ++ sbinfo->si_xib_buf = NULL; ++} ++ ++static int au_xino_set_xib(struct super_block *sb, struct file *base) ++{ ++ int err; ++ loff_t pos; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ file = au_xino_create2(base, sbinfo->si_xib); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ if (sbinfo->si_xib) ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = file; ++ sbinfo->si_xread = find_readf(file); ++ sbinfo->si_xwrite = find_writef(file); ++ ++ err = -ENOMEM; ++ if (!sbinfo->si_xib_buf) ++ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS); ++ if (unlikely(!sbinfo->si_xib_buf)) ++ goto out_unset; ++ ++ sbinfo->si_xib_last_pindex = 0; ++ sbinfo->si_xib_next_bit = 0; ++ if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) { ++ pos = 0; ++ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf, ++ PAGE_SIZE, &pos); ++ if (unlikely(err != PAGE_SIZE)) ++ goto out_free; ++ } ++ err = 0; ++ goto out; /* success */ ++ ++ out_free: ++ free_page((unsigned long)sbinfo->si_xib_buf); ++ sbinfo->si_xib_buf = NULL; ++ if (err >= 0) ++ err = -EIO; ++ out_unset: ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = NULL; ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ out: ++ return err; ++} ++ ++/* xino for each branch */ ++static void xino_clear_br(struct super_block *sb) ++{ ++ aufs_bindex_t bindex, bend; ++ struct au_branch *br; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (!br || !br->br_xino.xi_file) ++ continue; ++ ++ fput(br->br_xino.xi_file); ++ br->br_xino.xi_file = NULL; ++ } ++} ++ ++static int au_xino_set_br(struct super_block *sb, struct file *base) ++{ ++ int err; ++ ino_t ino; ++ aufs_bindex_t bindex, bend, bshared; ++ struct { ++ struct file *old, *new; ++ } *fpair, *p; ++ struct au_branch *br; ++ struct inode *inode; ++ au_writef_t writef; ++ ++ SiMustWriteLock(sb); ++ ++ err = -ENOMEM; ++ bend = au_sbend(sb); ++ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS); ++ if (unlikely(!fpair)) ++ goto out; ++ ++ inode = sb->s_root->d_inode; ++ ino = AUFS_ROOT_INO; ++ writef = au_sbi(sb)->si_xwrite; ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { ++ br = au_sbr(sb, bindex); ++ bshared = is_sb_shared(sb, bindex, bindex - 1); ++ if (bshared >= 0) { ++ /* shared xino */ ++ *p = fpair[bshared]; ++ get_file(p->new); ++ } ++ ++ if (!p->new) { ++ /* new xino */ ++ p->old = br->br_xino.xi_file; ++ p->new = au_xino_create2(base, br->br_xino.xi_file); ++ err = PTR_ERR(p->new); ++ if (IS_ERR(p->new)) { ++ p->new = NULL; ++ goto out_pair; ++ } ++ } ++ ++ err = au_xino_do_write(writef, p->new, ++ au_h_iptr(inode, bindex)->i_ino, ino); ++ if (unlikely(err)) ++ goto out_pair; ++ } ++ ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { ++ br = au_sbr(sb, bindex); ++ if (br->br_xino.xi_file) ++ fput(br->br_xino.xi_file); ++ get_file(p->new); ++ br->br_xino.xi_file = p->new; ++ } ++ ++ out_pair: ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) ++ if (p->new) ++ fput(p->new); ++ else ++ break; ++ kfree(fpair); ++ out: ++ return err; ++} ++ ++void au_xino_clr(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ au_xigen_clr(sb); ++ xino_clear_xib(sb); ++ xino_clear_br(sb); ++ sbinfo = au_sbi(sb); ++ /* lvalue, do not call au_mntflags() */ ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++} ++ ++int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount) ++{ ++ int err, skip; ++ struct dentry *parent, *cur_parent; ++ struct qstr *dname, *cur_name; ++ struct file *cur_xino; ++ struct inode *dir; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ parent = dget_parent(xino->file->f_dentry); ++ if (remount) { ++ skip = 0; ++ dname = &xino->file->f_dentry->d_name; ++ cur_xino = sbinfo->si_xib; ++ if (cur_xino) { ++ cur_parent = dget_parent(cur_xino->f_dentry); ++ cur_name = &cur_xino->f_dentry->d_name; ++ skip = (cur_parent == parent ++ && dname->len == cur_name->len ++ && !memcmp(dname->name, cur_name->name, ++ dname->len)); ++ dput(cur_parent); ++ } ++ if (skip) ++ goto out; ++ } ++ ++ au_opt_set(sbinfo->si_mntflags, XINO); ++ dir = parent->d_inode; ++ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); ++ /* mnt_want_write() is unnecessary here */ ++ err = au_xino_set_xib(sb, xino->file); ++ if (!err) ++ err = au_xigen_set(sb, xino->file); ++ if (!err) ++ err = au_xino_set_br(sb, xino->file); ++ mutex_unlock(&dir->i_mutex); ++ if (!err) ++ goto out; /* success */ ++ ++ /* reset all */ ++ AuIOErr("failed creating xino(%d).\n", err); ++ ++ out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create a xinofile at the default place/path. ++ */ ++struct file *au_xino_def(struct super_block *sb) ++{ ++ struct file *file; ++ char *page, *p; ++ struct au_branch *br; ++ struct super_block *h_sb; ++ struct path path; ++ aufs_bindex_t bend, bindex, bwr; ++ ++ br = NULL; ++ bend = au_sbend(sb); ++ bwr = -1; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_writable(br->br_perm) ++ && !au_test_fs_bad_xino(br->br_mnt->mnt_sb)) { ++ bwr = bindex; ++ break; ++ } ++ } ++ ++ if (bwr >= 0) { ++ file = ERR_PTR(-ENOMEM); ++ page = __getname(); ++ if (unlikely(!page)) ++ goto out; ++ path.mnt = br->br_mnt; ++ path.dentry = au_h_dptr(sb->s_root, bwr); ++ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME)); ++ file = (void *)p; ++ if (!IS_ERR(p)) { ++ strcat(p, "/" AUFS_XINO_FNAME); ++ AuDbg("%s\n", p); ++ file = au_xino_create(sb, p, /*silent*/0); ++ if (!IS_ERR(file)) ++ au_xino_brid_set(sb, br->br_id); ++ } ++ __putname(page); ++ } else { ++ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); ++ if (IS_ERR(file)) ++ goto out; ++ h_sb = file->f_dentry->d_sb; ++ if (unlikely(au_test_fs_bad_xino(h_sb))) { ++ AuErr("xino doesn't support %s(%s)\n", ++ AUFS_XINO_DEFPATH, au_sbtype(h_sb)); ++ fput(file); ++ file = ERR_PTR(-EINVAL); ++ } ++ if (!IS_ERR(file)) ++ au_xino_brid_set(sb, -1); ++ } ++ ++ out: ++ return file; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_xino_path(struct seq_file *seq, struct file *file) ++{ ++ int err; ++ ++ err = au_seq_path(seq, &file->f_path); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ err = 0; ++#define Deleted "\040(deleted)" ++ seq->count -= sizeof(Deleted) - 1; ++ AuDebugOn(memcmp(seq->buf + seq->count, Deleted, ++ sizeof(Deleted) - 1)); ++#undef Deleted ++ ++ out: ++ return err; ++} +diff -Nur linux-2.6.31-vanilla/fs/Kconfig linux-2.6.31/fs/Kconfig +--- linux-2.6.31-vanilla/fs/Kconfig 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/fs/Kconfig 2009-09-16 13:55:56.000000000 +0200 +@@ -187,6 +187,7 @@ + source "fs/ufs/Kconfig" + source "fs/exofs/Kconfig" + source "fs/nilfs2/Kconfig" ++source "fs/aufs/Kconfig" + + endif # MISC_FILESYSTEMS + +diff -Nur linux-2.6.31-vanilla/fs/Makefile linux-2.6.31/fs/Makefile +--- linux-2.6.31-vanilla/fs/Makefile 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/fs/Makefile 2009-09-16 13:55:56.000000000 +0200 +@@ -124,3 +124,4 @@ + obj-$(CONFIG_BTRFS_FS) += btrfs/ + obj-$(CONFIG_GFS2_FS) += gfs2/ + obj-$(CONFIG_EXOFS_FS) += exofs/ ++obj-$(CONFIG_AUFS_FS) += aufs/ +diff -Nur linux-2.6.31-vanilla/fs/namei.c linux-2.6.31/fs/namei.c +--- linux-2.6.31-vanilla/fs/namei.c 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/fs/namei.c 2009-09-16 13:55:49.000000000 +0200 +@@ -337,6 +337,7 @@ + + return 0; + } ++EXPORT_SYMBOL(deny_write_access); + + /** + * path_get - get a reference to a path +@@ -1219,7 +1220,7 @@ + * needs parent already locked. Doesn't follow mounts. + * SMP-safe. + */ +-static struct dentry *lookup_hash(struct nameidata *nd) ++struct dentry *lookup_hash(struct nameidata *nd) + { + int err; + +@@ -1228,8 +1229,9 @@ + return ERR_PTR(err); + return __lookup_hash(&nd->last, nd->path.dentry, nd); + } ++EXPORT_SYMBOL(lookup_hash); + +-static int __lookup_one_len(const char *name, struct qstr *this, ++int __lookup_one_len(const char *name, struct qstr *this, + struct dentry *base, int len) + { + unsigned long hash; +@@ -1250,6 +1252,7 @@ + this->hash = end_name_hash(hash); + return 0; + } ++EXPORT_SYMBOL(__lookup_one_len); + + /** + * lookup_one_len - filesystem helper to lookup single pathname component +diff -Nur linux-2.6.31-vanilla/fs/namespace.c linux-2.6.31/fs/namespace.c +--- linux-2.6.31-vanilla/fs/namespace.c 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/fs/namespace.c 2009-09-16 13:55:49.000000000 +0200 +@@ -39,6 +39,7 @@ + + /* spinlock for vfsmount related operations, inplace of dcache_lock */ + __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); ++EXPORT_SYMBOL(vfsmount_lock); + + static int event; + static DEFINE_IDA(mnt_id_ida); +diff -Nur linux-2.6.31-vanilla/fs/open.c linux-2.6.31/fs/open.c +--- linux-2.6.31-vanilla/fs/open.c 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/fs/open.c 2009-09-16 13:55:49.000000000 +0200 +@@ -221,6 +221,7 @@ + mutex_unlock(&dentry->d_inode->i_mutex); + return err; + } ++EXPORT_SYMBOL(do_truncate); + + static long do_sys_truncate(const char __user *pathname, loff_t length) + { +diff -Nur linux-2.6.31-vanilla/fs/splice.c linux-2.6.31/fs/splice.c +--- linux-2.6.31-vanilla/fs/splice.c 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/fs/splice.c 2009-09-16 13:55:49.000000000 +0200 +@@ -1057,8 +1057,8 @@ + /* + * Attempt to initiate a splice from pipe to file. + */ +-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +- loff_t *ppos, size_t len, unsigned int flags) ++long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) + { + ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, + loff_t *, size_t, unsigned int); +@@ -1080,13 +1080,14 @@ + + return splice_write(pipe, out, ppos, len, flags); + } ++EXPORT_SYMBOL(do_splice_from); + + /* + * Attempt to initiate a splice from a file to a pipe. + */ +-static long do_splice_to(struct file *in, loff_t *ppos, +- struct pipe_inode_info *pipe, size_t len, +- unsigned int flags) ++long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) + { + ssize_t (*splice_read)(struct file *, loff_t *, + struct pipe_inode_info *, size_t, unsigned int); +@@ -1105,6 +1106,7 @@ + + return splice_read(in, ppos, pipe, len, flags); + } ++EXPORT_SYMBOL(do_splice_to); + + /** + * splice_direct_to_actor - splices data directly between two non-pipes +diff -Nur linux-2.6.31-vanilla/include/linux/aufs_type.h linux-2.6.31/include/linux/aufs_type.h +--- linux-2.6.31-vanilla/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/include/linux/aufs_type.h 2009-09-16 13:55:30.000000000 +0200 +@@ -0,0 +1,184 @@ ++/* ++ * Copyright (C) 2005-2009 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef __AUFS_TYPE_H__ ++#define __AUFS_TYPE_H__ ++ ++#include <linux/ioctl.h> ++#include <linux/types.h> ++ ++#define AUFS_VERSION "2-standalone.tree-20090914" ++ ++/* todo? move this to linux-2.6.19/include/magic.h */ ++#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_BRANCH_MAX_127 ++typedef __s8 aufs_bindex_t; ++#define AUFS_BRANCH_MAX 127 ++#else ++typedef __s16 aufs_bindex_t; ++#ifdef CONFIG_AUFS_BRANCH_MAX_511 ++#define AUFS_BRANCH_MAX 511 ++#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) ++#define AUFS_BRANCH_MAX 1023 ++#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) ++#define AUFS_BRANCH_MAX 32767 ++#endif ++#endif ++ ++#ifdef __KERNEL__ ++#ifndef AUFS_BRANCH_MAX ++#error unknown CONFIG_AUFS_BRANCH_MAX value ++#endif ++#endif /* __KERNEL__ */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AUFS_NAME "aufs" ++#define AUFS_FSTYPE AUFS_NAME ++ ++#define AUFS_ROOT_INO 2 ++#define AUFS_FIRST_INO 11 ++ ++#define AUFS_WH_PFX ".wh." ++#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) ++#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" ++#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME ++#define AUFS_XINO_TRUNC_INIT 64 /* blocks */ ++#define AUFS_XINO_TRUNC_STEP 4 /* blocks */ ++#define AUFS_DIRWH_DEF 3 ++#define AUFS_RDCACHE_DEF 10 /* seconds */ ++#define AUFS_RDBLK_DEF 512 /* bytes */ ++#define AUFS_RDHASH_DEF 32 ++#define AUFS_WKQ_NAME AUFS_NAME "d" ++#define AUFS_NWKQ_DEF 4 ++#define AUFS_MFS_SECOND_DEF 30 /* seconds */ ++#define AUFS_PLINK_WARN 100 /* number of plinks */ ++ ++#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ ++#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME ++ ++#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME ++#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk" ++#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph" ++ ++/* doubly whiteouted */ ++#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME ++#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME ++#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME ++ ++/* branch permission */ ++#define AUFS_BRPERM_RW "rw" ++#define AUFS_BRPERM_RO "ro" ++#define AUFS_BRPERM_RR "rr" ++#define AUFS_BRPERM_WH "wh" ++#define AUFS_BRPERM_NLWH "nolwh" ++#define AUFS_BRPERM_ROWH AUFS_BRPERM_RO "+" AUFS_BRPERM_WH ++#define AUFS_BRPERM_RRWH AUFS_BRPERM_RR "+" AUFS_BRPERM_WH ++#define AUFS_BRPERM_RWNLWH AUFS_BRPERM_RW "+" AUFS_BRPERM_NLWH ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ioctl */ ++enum { ++ AuCtl_PLINK_MAINT, ++ AuCtl_PLINK_CLEAN, ++ ++ /* readdir in userspace */ ++ AuCtl_RDU, ++ AuCtl_RDU_INO ++}; ++ ++/* borrowed from linux/include/linux/kernel.h */ ++#ifndef ALIGN ++#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) ++#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) ++#endif ++ ++/* borrowed from linux/include/linux/compiler-gcc3.h */ ++#ifndef __aligned ++#define __aligned(x) __attribute__((aligned(x))) ++#define __packed __attribute__((packed)) ++#endif ++ ++struct au_rdu_cookie { ++ __u64 h_pos; ++ __s16 bindex; ++ __u8 flags; ++ __u8 pad; ++ __u32 generation; ++} __aligned(8); ++ ++struct au_rdu_ent { ++ __u64 ino; ++ __s16 bindex; ++ __u8 type; ++ __u8 nlen; ++ __u8 wh; ++ char name[0]; ++} __aligned(8); ++ ++static inline int au_rdu_len(int nlen) ++{ ++ /* include the terminating NULL */ ++ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1, ++ sizeof(__u64)); ++} ++ ++union au_rdu_ent_ul { ++ struct au_rdu_ent __user *e; ++ unsigned long ul; ++}; ++ ++enum { ++ AufsCtlRduV_SZ, ++ AufsCtlRduV_SZ_PTR, ++ AufsCtlRduV_End ++}; ++ ++struct aufs_rdu { ++ /* input */ ++ union { ++ __u64 sz; /* AuCtl_RDU */ ++ __u64 nent; /* AuCtl_RDU_INO */ ++ }; ++ union au_rdu_ent_ul ent; ++ __u16 verify[AufsCtlRduV_End]; ++ ++ /* input/output */ ++ __u32 blk; ++ ++ /* output */ ++ union au_rdu_ent_ul tail; ++ /* number of entries which were added in a single call */ ++ __u64 rent; ++ __u8 full; ++ __u8 shwh; ++ ++ struct au_rdu_cookie cookie; ++} __aligned(8); ++ ++#define AuCtlType 'A' ++#define AUFS_CTL_PLINK_MAINT _IO(AuCtlType, AuCtl_PLINK_MAINT) ++#define AUFS_CTL_PLINK_CLEAN _IO(AuCtlType, AuCtl_PLINK_CLEAN) ++#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu) ++#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu) ++ ++#endif /* __AUFS_TYPE_H__ */ +diff -Nur linux-2.6.31-vanilla/include/linux/Kbuild linux-2.6.31/include/linux/Kbuild +--- linux-2.6.31-vanilla/include/linux/Kbuild 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/include/linux/Kbuild 2009-09-16 13:55:56.000000000 +0200 +@@ -34,6 +34,7 @@ + header-y += atmsap.h + header-y += atmsvc.h + header-y += atm_zatm.h ++header-y += aufs_type.h + header-y += auto_fs4.h + header-y += ax25.h + header-y += b1lli.h +diff -Nur linux-2.6.31-vanilla/include/linux/namei.h linux-2.6.31/include/linux/namei.h +--- linux-2.6.31-vanilla/include/linux/namei.h 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/include/linux/namei.h 2009-09-16 13:55:46.000000000 +0200 +@@ -75,6 +75,9 @@ + extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); + extern void release_open_intent(struct nameidata *); + ++extern struct dentry *lookup_hash(struct nameidata *nd); ++extern int __lookup_one_len(const char *name, struct qstr *this, ++ struct dentry *base, int len); + extern struct dentry *lookup_one_len(const char *, struct dentry *, int); + extern struct dentry *lookup_one_noperm(const char *, struct dentry *); + +diff -Nur linux-2.6.31-vanilla/include/linux/splice.h linux-2.6.31/include/linux/splice.h +--- linux-2.6.31-vanilla/include/linux/splice.h 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/include/linux/splice.h 2009-09-16 13:55:46.000000000 +0200 +@@ -82,4 +82,10 @@ + extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, + splice_direct_actor *); + ++extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++extern long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); ++ + #endif +diff -Nur linux-2.6.31-vanilla/security/device_cgroup.c linux-2.6.31/security/device_cgroup.c +--- linux-2.6.31-vanilla/security/device_cgroup.c 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/security/device_cgroup.c 2009-09-16 13:55:49.000000000 +0200 +@@ -513,6 +513,7 @@ + + return -EPERM; + } ++EXPORT_SYMBOL(devcgroup_inode_permission); + + int devcgroup_inode_mknod(int mode, dev_t dev) + { +diff -Nur linux-2.6.31-vanilla/security/integrity/ima/ima_main.c linux-2.6.31/security/integrity/ima/ima_main.c +--- linux-2.6.31-vanilla/security/integrity/ima/ima_main.c 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/security/integrity/ima/ima_main.c 2009-09-16 13:55:49.000000000 +0200 +@@ -324,6 +324,7 @@ + MAY_EXEC, FILE_MMAP); + return 0; + } ++EXPORT_SYMBOL(ima_file_mmap); + + /** + * ima_bprm_check - based on policy, collect/store measurement. +diff -Nur linux-2.6.31-vanilla/security/integrity/ima/ima_main.c.orig linux-2.6.31/security/integrity/ima/ima_main.c.orig +--- linux-2.6.31-vanilla/security/integrity/ima/ima_main.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.31/security/integrity/ima/ima_main.c.orig 2009-09-10 00:13:59.000000000 +0200 +@@ -0,0 +1,368 @@ ++/* ++ * Copyright (C) 2005,2006,2007,2008 IBM Corporation ++ * ++ * Authors: ++ * Reiner Sailer <sailer@watson.ibm.com> ++ * Serge Hallyn <serue@us.ibm.com> ++ * Kylene Hall <kylene@us.ibm.com> ++ * Mimi Zohar <zohar@us.ibm.com> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation, version 2 of the ++ * License. ++ * ++ * File: ima_main.c ++ * implements the IMA hooks: ima_bprm_check, ima_file_mmap, ++ * and ima_path_check. ++ */ ++#include <linux/module.h> ++#include <linux/file.h> ++#include <linux/binfmts.h> ++#include <linux/mount.h> ++#include <linux/mman.h> ++ ++#include "ima.h" ++ ++int ima_initialized; ++ ++char *ima_hash = "sha1"; ++static int __init hash_setup(char *str) ++{ ++ if (strncmp(str, "md5", 3) == 0) ++ ima_hash = "md5"; ++ return 1; ++} ++__setup("ima_hash=", hash_setup); ++ ++/** ++ * ima_file_free - called on __fput() ++ * @file: pointer to file structure being freed ++ * ++ * Flag files that changed, based on i_version; ++ * and decrement the iint readcount/writecount. ++ */ ++void ima_file_free(struct file *file) ++{ ++ struct inode *inode = file->f_dentry->d_inode; ++ struct ima_iint_cache *iint; ++ ++ if (!ima_initialized || !S_ISREG(inode->i_mode)) ++ return; ++ iint = ima_iint_find_get(inode); ++ if (!iint) ++ return; ++ ++ mutex_lock(&iint->mutex); ++ if (iint->opencount <= 0) { ++ printk(KERN_INFO ++ "%s: %s open/free imbalance (r:%ld w:%ld o:%ld f:%ld)\n", ++ __FUNCTION__, file->f_dentry->d_name.name, ++ iint->readcount, iint->writecount, ++ iint->opencount, atomic_long_read(&file->f_count)); ++ if (!(iint->flags & IMA_IINT_DUMP_STACK)) { ++ dump_stack(); ++ iint->flags |= IMA_IINT_DUMP_STACK; ++ } ++ } ++ iint->opencount--; ++ ++ if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) ++ iint->readcount--; ++ ++ if (file->f_mode & FMODE_WRITE) { ++ iint->writecount--; ++ if (iint->writecount == 0) { ++ if (iint->version != inode->i_version) ++ iint->flags &= ~IMA_MEASURED; ++ } ++ } ++ mutex_unlock(&iint->mutex); ++ kref_put(&iint->refcount, iint_free); ++} ++ ++/* ima_read_write_check - reflect possible reading/writing errors in the PCR. ++ * ++ * When opening a file for read, if the file is already open for write, ++ * the file could change, resulting in a file measurement error. ++ * ++ * Opening a file for write, if the file is already open for read, results ++ * in a time of measure, time of use (ToMToU) error. ++ * ++ * In either case invalidate the PCR. ++ */ ++enum iint_pcr_error { TOMTOU, OPEN_WRITERS }; ++static void ima_read_write_check(enum iint_pcr_error error, ++ struct ima_iint_cache *iint, ++ struct inode *inode, ++ const unsigned char *filename) ++{ ++ switch (error) { ++ case TOMTOU: ++ if (iint->readcount > 0) ++ ima_add_violation(inode, filename, "invalid_pcr", ++ "ToMToU"); ++ break; ++ case OPEN_WRITERS: ++ if (iint->writecount > 0) ++ ima_add_violation(inode, filename, "invalid_pcr", ++ "open_writers"); ++ break; ++ } ++} ++ ++static int get_path_measurement(struct ima_iint_cache *iint, struct file *file, ++ const unsigned char *filename) ++{ ++ int rc = 0; ++ ++ iint->opencount++; ++ iint->readcount++; ++ ++ rc = ima_collect_measurement(iint, file); ++ if (!rc) ++ ima_store_measurement(iint, file, filename); ++ return rc; ++} ++ ++static void ima_update_counts(struct ima_iint_cache *iint, int mask) ++{ ++ iint->opencount++; ++ if ((mask & MAY_WRITE) || (mask == 0)) ++ iint->writecount++; ++ else if (mask & (MAY_READ | MAY_EXEC)) ++ iint->readcount++; ++} ++ ++/** ++ * ima_path_check - based on policy, collect/store measurement. ++ * @path: contains a pointer to the path to be measured ++ * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE ++ * ++ * Measure the file being open for readonly, based on the ++ * ima_must_measure() policy decision. ++ * ++ * Keep read/write counters for all files, but only ++ * invalidate the PCR for measured files: ++ * - Opening a file for write when already open for read, ++ * results in a time of measure, time of use (ToMToU) error. ++ * - Opening a file for read when already open for write, ++ * could result in a file measurement error. ++ * ++ * Always return 0 and audit dentry_open failures. ++ * (Return code will be based upon measurement appraisal.) ++ */ ++int ima_path_check(struct path *path, int mask, int update_counts) ++{ ++ struct inode *inode = path->dentry->d_inode; ++ struct ima_iint_cache *iint; ++ struct file *file = NULL; ++ int rc; ++ ++ if (!ima_initialized || !S_ISREG(inode->i_mode)) ++ return 0; ++ iint = ima_iint_find_insert_get(inode); ++ if (!iint) ++ return 0; ++ ++ mutex_lock(&iint->mutex); ++ if (update_counts) ++ ima_update_counts(iint, mask); ++ ++ rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK); ++ if (rc < 0) ++ goto out; ++ ++ if ((mask & MAY_WRITE) || (mask == 0)) ++ ima_read_write_check(TOMTOU, iint, inode, ++ path->dentry->d_name.name); ++ ++ if ((mask & (MAY_WRITE | MAY_READ | MAY_EXEC)) != MAY_READ) ++ goto out; ++ ++ ima_read_write_check(OPEN_WRITERS, iint, inode, ++ path->dentry->d_name.name); ++ if (!(iint->flags & IMA_MEASURED)) { ++ struct dentry *dentry = dget(path->dentry); ++ struct vfsmount *mnt = mntget(path->mnt); ++ ++ file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE, ++ current_cred()); ++ if (IS_ERR(file)) { ++ int audit_info = 0; ++ ++ integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, ++ dentry->d_name.name, ++ "add_measurement", ++ "dentry_open failed", ++ 1, audit_info); ++ file = NULL; ++ goto out; ++ } ++ rc = get_path_measurement(iint, file, dentry->d_name.name); ++ } ++out: ++ mutex_unlock(&iint->mutex); ++ if (file) ++ fput(file); ++ kref_put(&iint->refcount, iint_free); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(ima_path_check); ++ ++static int process_measurement(struct file *file, const unsigned char *filename, ++ int mask, int function) ++{ ++ struct inode *inode = file->f_dentry->d_inode; ++ struct ima_iint_cache *iint; ++ int rc; ++ ++ if (!ima_initialized || !S_ISREG(inode->i_mode)) ++ return 0; ++ iint = ima_iint_find_insert_get(inode); ++ if (!iint) ++ return -ENOMEM; ++ ++ mutex_lock(&iint->mutex); ++ rc = ima_must_measure(iint, inode, mask, function); ++ if (rc != 0) ++ goto out; ++ ++ rc = ima_collect_measurement(iint, file); ++ if (!rc) ++ ima_store_measurement(iint, file, filename); ++out: ++ mutex_unlock(&iint->mutex); ++ kref_put(&iint->refcount, iint_free); ++ return rc; ++} ++ ++/* ++ * ima_counts_put - decrement file counts ++ * ++ * File counts are incremented in ima_path_check. On file open ++ * error, such as ETXTBSY, decrement the counts to prevent ++ * unnecessary imbalance messages. ++ */ ++void ima_counts_put(struct path *path, int mask) ++{ ++ struct inode *inode = path->dentry->d_inode; ++ struct ima_iint_cache *iint; ++ ++ /* The inode may already have been freed, freeing the iint ++ * with it. Verify the inode is not NULL before dereferencing ++ * it. ++ */ ++ if (!ima_initialized || !inode || !S_ISREG(inode->i_mode)) ++ return; ++ iint = ima_iint_find_insert_get(inode); ++ if (!iint) ++ return; ++ ++ mutex_lock(&iint->mutex); ++ iint->opencount--; ++ if ((mask & MAY_WRITE) || (mask == 0)) ++ iint->writecount--; ++ else if (mask & (MAY_READ | MAY_EXEC)) ++ iint->readcount--; ++ mutex_unlock(&iint->mutex); ++ ++ kref_put(&iint->refcount, iint_free); ++} ++ ++/* ++ * ima_counts_get - increment file counts ++ * ++ * - for IPC shm and shmat file. ++ * - for nfsd exported files. ++ * ++ * Increment the counts for these files to prevent unnecessary ++ * imbalance messages. ++ */ ++void ima_counts_get(struct file *file) ++{ ++ struct inode *inode = file->f_dentry->d_inode; ++ struct ima_iint_cache *iint; ++ ++ if (!ima_initialized || !S_ISREG(inode->i_mode)) ++ return; ++ iint = ima_iint_find_insert_get(inode); ++ if (!iint) ++ return; ++ mutex_lock(&iint->mutex); ++ iint->opencount++; ++ if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) ++ iint->readcount++; ++ ++ if (file->f_mode & FMODE_WRITE) ++ iint->writecount++; ++ mutex_unlock(&iint->mutex); ++ ++ kref_put(&iint->refcount, iint_free); ++} ++EXPORT_SYMBOL_GPL(ima_counts_get); ++ ++/** ++ * ima_file_mmap - based on policy, collect/store measurement. ++ * @file: pointer to the file to be measured (May be NULL) ++ * @prot: contains the protection that will be applied by the kernel. ++ * ++ * Measure files being mmapped executable based on the ima_must_measure() ++ * policy decision. ++ * ++ * Return 0 on success, an error code on failure. ++ * (Based on the results of appraise_measurement().) ++ */ ++int ima_file_mmap(struct file *file, unsigned long prot) ++{ ++ int rc; ++ ++ if (!file) ++ return 0; ++ if (prot & PROT_EXEC) ++ rc = process_measurement(file, file->f_dentry->d_name.name, ++ MAY_EXEC, FILE_MMAP); ++ return 0; ++} ++ ++/** ++ * ima_bprm_check - based on policy, collect/store measurement. ++ * @bprm: contains the linux_binprm structure ++ * ++ * The OS protects against an executable file, already open for write, ++ * from being executed in deny_write_access() and an executable file, ++ * already open for execute, from being modified in get_write_access(). ++ * So we can be certain that what we verify and measure here is actually ++ * what is being executed. ++ * ++ * Return 0 on success, an error code on failure. ++ * (Based on the results of appraise_measurement().) ++ */ ++int ima_bprm_check(struct linux_binprm *bprm) ++{ ++ int rc; ++ ++ rc = process_measurement(bprm->file, bprm->filename, ++ MAY_EXEC, BPRM_CHECK); ++ return 0; ++} ++ ++static int __init init_ima(void) ++{ ++ int error; ++ ++ ima_iintcache_init(); ++ error = ima_init(); ++ ima_initialized = 1; ++ return error; ++} ++ ++static void __exit cleanup_ima(void) ++{ ++ ima_cleanup(); ++} ++ ++late_initcall(init_ima); /* Start IMA after the TPM is available */ ++ ++MODULE_DESCRIPTION("Integrity Measurement Architecture"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.6.31-vanilla/security/security.c linux-2.6.31/security/security.c +--- linux-2.6.31-vanilla/security/security.c 2009-09-10 00:13:59.000000000 +0200 ++++ linux-2.6.31/security/security.c 2009-09-16 13:55:49.000000000 +0200 +@@ -386,6 +386,7 @@ + return 0; + return security_ops->path_mkdir(path, dentry, mode); + } ++EXPORT_SYMBOL(security_path_mkdir); + + int security_path_rmdir(struct path *path, struct dentry *dentry) + { +@@ -393,6 +394,7 @@ + return 0; + return security_ops->path_rmdir(path, dentry); + } ++EXPORT_SYMBOL(security_path_rmdir); + + int security_path_unlink(struct path *path, struct dentry *dentry) + { +@@ -400,6 +402,7 @@ + return 0; + return security_ops->path_unlink(path, dentry); + } ++EXPORT_SYMBOL(security_path_unlink); + + int security_path_symlink(struct path *path, struct dentry *dentry, + const char *old_name) +@@ -408,6 +411,7 @@ + return 0; + return security_ops->path_symlink(path, dentry, old_name); + } ++EXPORT_SYMBOL(security_path_symlink); + + int security_path_link(struct dentry *old_dentry, struct path *new_dir, + struct dentry *new_dentry) +@@ -416,6 +420,7 @@ + return 0; + return security_ops->path_link(old_dentry, new_dir, new_dentry); + } ++EXPORT_SYMBOL(security_path_link); + + int security_path_rename(struct path *old_dir, struct dentry *old_dentry, + struct path *new_dir, struct dentry *new_dentry) +@@ -426,6 +431,7 @@ + return security_ops->path_rename(old_dir, old_dentry, new_dir, + new_dentry); + } ++EXPORT_SYMBOL(security_path_rename); + + int security_path_truncate(struct path *path, loff_t length, + unsigned int time_attrs) +@@ -434,6 +440,7 @@ + return 0; + return security_ops->path_truncate(path, length, time_attrs); + } ++EXPORT_SYMBOL(security_path_truncate); + #endif + + int security_inode_create(struct inode *dir, struct dentry *dentry, int mode) +@@ -505,6 +512,7 @@ + return 0; + return security_ops->inode_readlink(dentry); + } ++EXPORT_SYMBOL(security_inode_readlink); + + int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) + { +@@ -519,6 +527,7 @@ + return 0; + return security_ops->inode_permission(inode, mask); + } ++EXPORT_SYMBOL(security_inode_permission); + + int security_inode_setattr(struct dentry *dentry, struct iattr *attr) + { +@@ -619,6 +628,7 @@ + { + return security_ops->file_permission(file, mask); + } ++EXPORT_SYMBOL(security_file_permission); + + int security_file_alloc(struct file *file) + { diff --git a/pkgs/core/kernel/patches/grsecurity-2.1.14-2.6.31.1-200910012153.patch b/pkgs/core/kernel/patches/grsecurity-2.1.14-2.6.31.1-200910012153.patch new file mode 100644 index 0000000..ae34c84 --- /dev/null +++ b/pkgs/core/kernel/patches/grsecurity-2.1.14-2.6.31.1-200910012153.patch @@ -0,0 +1,47055 @@ +diff -urNp linux-2.6.31.1/arch/alpha/include/asm/atomic.h linux-2.6.31.1/arch/alpha/include/asm/atomic.h +--- linux-2.6.31.1/arch/alpha/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/alpha/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -18,9 +18,11 @@ + #define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } ) + + #define atomic_read(v) ((v)->counter + 0) ++#define atomic_read_unchecked(v) ((v)->counter + 0) + #define atomic64_read(v) ((v)->counter + 0) + + #define atomic_set(v,i) ((v)->counter = (i)) ++#define atomic_set_unchecked(v,i) ((v)->counter = (i)) + #define atomic64_set(v,i) ((v)->counter = (i)) + + /* +@@ -44,6 +46,11 @@ static __inline__ void atomic_add(int i, + :"Ir" (i), "m" (v->counter)); + } + ++static __inline__ void atomic_add_unchecked(int i, atomic_unchecked_t * v) ++{ ++ atomic_add(i, (atomic_t *)v); ++} ++ + static __inline__ void atomic64_add(long i, atomic64_t * v) + { + unsigned long temp; +@@ -74,6 +81,11 @@ static __inline__ void atomic_sub(int i, + :"Ir" (i), "m" (v->counter)); + } + ++static __inline__ void atomic_sub_unchecked(int i, atomic_unchecked_t * v) ++{ ++ atomic_sub(i, (atomic_t *)v); ++} ++ + static __inline__ void atomic64_sub(long i, atomic64_t * v) + { + unsigned long temp; +@@ -246,6 +258,7 @@ static __inline__ int atomic64_add_unles + #define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0) + + #define atomic_inc(v) atomic_add(1,(v)) ++#define atomic_inc_unchecked(v) atomic_add_unchecked(1,(v)) + #define atomic64_inc(v) atomic64_add(1,(v)) + + #define atomic_dec(v) atomic_sub(1,(v)) +diff -urNp linux-2.6.31.1/arch/alpha/include/asm/elf.h linux-2.6.31.1/arch/alpha/include/asm/elf.h +--- linux-2.6.31.1/arch/alpha/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/alpha/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400 +@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N + + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL) ++ ++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28) ++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19) ++#endif ++ + /* $0 is set by ld.so to a pointer to a function which might be + registered using atexit. This provides a mean for the dynamic + linker to call DT_FINI functions for shared libraries that have +diff -urNp linux-2.6.31.1/arch/alpha/include/asm/pgtable.h linux-2.6.31.1/arch/alpha/include/asm/pgtable.h +--- linux-2.6.31.1/arch/alpha/include/asm/pgtable.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/alpha/include/asm/pgtable.h 2009-10-01 20:12:42.000000000 -0400 +@@ -101,6 +101,17 @@ struct vm_area_struct; + #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS) + #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) + #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE) ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE) ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE) ++#else ++# define PAGE_SHARED_NOEXEC PAGE_SHARED ++# define PAGE_COPY_NOEXEC PAGE_COPY ++# define PAGE_READONLY_NOEXEC PAGE_READONLY ++#endif ++ + #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE) + + #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x)) +diff -urNp linux-2.6.31.1/arch/alpha/kernel/module.c linux-2.6.31.1/arch/alpha/kernel/module.c +--- linux-2.6.31.1/arch/alpha/kernel/module.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/alpha/kernel/module.c 2009-10-01 20:12:42.000000000 -0400 +@@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, + + /* The small sections were sorted to the end of the segment. + The following should definitely cover them. */ +- gp = (u64)me->module_core + me->core_size - 0x8000; ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000; + got = sechdrs[me->arch.gotsecindex].sh_addr; + + for (i = 0; i < n; i++) { +diff -urNp linux-2.6.31.1/arch/alpha/kernel/osf_sys.c linux-2.6.31.1/arch/alpha/kernel/osf_sys.c +--- linux-2.6.31.1/arch/alpha/kernel/osf_sys.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/alpha/kernel/osf_sys.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1212,6 +1212,10 @@ arch_get_unmapped_area(struct file *filp + merely specific addresses, but regions of memory -- perhaps + this feature should be incorporated into all ports? */ + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ + if (addr) { + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); + if (addr != (unsigned long) -ENOMEM) +@@ -1219,8 +1223,8 @@ arch_get_unmapped_area(struct file *filp + } + + /* Next, try allocating at TASK_UNMAPPED_BASE. */ +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE), +- len, limit); ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit); ++ + if (addr != (unsigned long) -ENOMEM) + return addr; + +diff -urNp linux-2.6.31.1/arch/alpha/mm/fault.c linux-2.6.31.1/arch/alpha/mm/fault.c +--- linux-2.6.31.1/arch/alpha/mm/fault.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/alpha/mm/fault.c 2009-10-01 20:12:42.000000000 -0400 +@@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct * + __reload_thread(pcb); + } + ++#ifdef CONFIG_PAX_PAGEEXEC ++/* ++ * PaX: decide what to do with offenders (regs->pc = fault address) ++ * ++ * returns 1 when task should be killed ++ * 2 when patched PLT trampoline was detected ++ * 3 when unpatched PLT trampoline was detected ++ */ ++static int pax_handle_fetch_fault(struct pt_regs *regs) ++{ ++ ++#ifdef CONFIG_PAX_EMUPLT ++ int err; ++ ++ do { /* PaX: patched PLT emulation #1 */ ++ unsigned int ldah, ldq, jmp; ++ ++ err = get_user(ldah, (unsigned int *)regs->pc); ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4)); ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8)); ++ ++ if (err) ++ break; ++ ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U && ++ (ldq & 0xFFFF0000U) == 0xA77B0000U && ++ jmp == 0x6BFB0000U) ++ { ++ unsigned long r27, addr; ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL; ++ ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); ++ err = get_user(r27, (unsigned long *)addr); ++ if (err) ++ break; ++ ++ regs->r27 = r27; ++ regs->pc = r27; ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: patched PLT emulation #2 */ ++ unsigned int ldah, lda, br; ++ ++ err = get_user(ldah, (unsigned int *)regs->pc); ++ err |= get_user(lda, (unsigned int *)(regs->pc+4)); ++ err |= get_user(br, (unsigned int *)(regs->pc+8)); ++ ++ if (err) ++ break; ++ ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U && ++ (lda & 0xFFFF0000U) == 0xA77B0000U && ++ (br & 0xFFE00000U) == 0xC3E00000U) ++ { ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL; ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL; ++ ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: unpatched PLT emulation */ ++ unsigned int br; ++ ++ err = get_user(br, (unsigned int *)regs->pc); ++ ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) { ++ unsigned int br2, ldq, nop, jmp; ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver; ++ ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); ++ err = get_user(br2, (unsigned int *)addr); ++ err |= get_user(ldq, (unsigned int *)(addr+4)); ++ err |= get_user(nop, (unsigned int *)(addr+8)); ++ err |= get_user(jmp, (unsigned int *)(addr+12)); ++ err |= get_user(resolver, (unsigned long *)(addr+16)); ++ ++ if (err) ++ break; ++ ++ if (br2 == 0xC3600000U && ++ ldq == 0xA77B000CU && ++ nop == 0x47FF041FU && ++ jmp == 0x6B7B0000U) ++ { ++ regs->r28 = regs->pc+4; ++ regs->r27 = addr+16; ++ regs->pc = resolver; ++ return 3; ++ } ++ } ++ } while (0); ++#endif ++ ++ return 1; ++} ++ ++void pax_report_insns(void *pc, void *sp) ++{ ++ unsigned long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 5; i++) { ++ unsigned int c; ++ if (get_user(c, (unsigned int *)pc+i)) ++ printk(KERN_CONT "???????? "); ++ else ++ printk(KERN_CONT "%08x ", c); ++ } ++ printk("\n"); ++} ++#endif + + /* + * This routine handles page faults. It determines the address, +@@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns + good_area: + si_code = SEGV_ACCERR; + if (cause < 0) { +- if (!(vma->vm_flags & VM_EXEC)) ++ if (!(vma->vm_flags & VM_EXEC)) { ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc) ++ goto bad_area; ++ ++ up_read(&mm->mmap_sem); ++ switch (pax_handle_fetch_fault(regs)) { ++ ++#ifdef CONFIG_PAX_EMUPLT ++ case 2: ++ case 3: ++ return; ++#endif ++ ++ } ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp()); ++ do_group_exit(SIGKILL); ++#else + goto bad_area; ++#endif ++ ++ } + } else if (!cause) { + /* Allow reads even for write-only mappings */ + if (!(vma->vm_flags & (VM_READ | VM_WRITE))) +diff -urNp linux-2.6.31.1/arch/arm/include/asm/atomic.h linux-2.6.31.1/arch/arm/include/asm/atomic.h +--- linux-2.6.31.1/arch/arm/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/arm/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -20,6 +20,7 @@ + #ifdef __KERNEL__ + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + + #if __LINUX_ARM_ARCH__ >= 6 + +@@ -44,6 +45,11 @@ static inline void atomic_set(atomic_t * + : "cc"); + } + ++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i) ++{ ++ atomic_set((atomic_t *)v, i); ++} ++ + static inline void atomic_add(int i, atomic_t *v) + { + unsigned long tmp; +@@ -60,6 +66,11 @@ static inline void atomic_add(int i, ato + : "cc"); + } + ++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_add(i, (atomic_t *)v); ++} ++ + static inline int atomic_add_return(int i, atomic_t *v) + { + unsigned long tmp; +@@ -98,6 +109,11 @@ static inline void atomic_sub(int i, ato + : "cc"); + } + ++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_sub(i, (atomic_t *)v); ++} ++ + static inline int atomic_sub_return(int i, atomic_t *v) + { + unsigned long tmp; +@@ -164,6 +180,7 @@ static inline void atomic_clear_mask(uns + #endif + + #define atomic_set(v,i) (((v)->counter) = (i)) ++#define atomic_set_unchecked(v,i) (((v)->counter) = (i)) + + static inline int atomic_add_return(int i, atomic_t *v) + { +@@ -232,6 +249,7 @@ static inline int atomic_add_unless(atom + #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + + #define atomic_inc(v) atomic_add(1, v) ++#define atomic_inc_unchecked(v) atomic_add_unchecked(1, v) + #define atomic_dec(v) atomic_sub(1, v) + + #define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0) +diff -urNp linux-2.6.31.1/arch/arm/include/asm/elf.h linux-2.6.31.1/arch/arm/include/asm/elf.h +--- linux-2.6.31.1/arch/arm/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/arm/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400 +@@ -103,7 +103,14 @@ extern int arm_elf_read_implies_exec(con + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) ++ ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE 0x00008000UL ++ ++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10) ++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10) ++#endif + + /* When the program starts, a1 contains a pointer to a function to be + registered with atexit, as per the SVR4 ABI. A value of 0 means we +diff -urNp linux-2.6.31.1/arch/arm/include/asm/kmap_types.h linux-2.6.31.1/arch/arm/include/asm/kmap_types.h +--- linux-2.6.31.1/arch/arm/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/arm/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400 +@@ -19,6 +19,7 @@ enum km_type { + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_L2_CACHE, ++ KM_CLEARPAGE, + KM_TYPE_NR + }; + +diff -urNp linux-2.6.31.1/arch/arm/include/asm/uaccess.h linux-2.6.31.1/arch/arm/include/asm/uaccess.h +--- linux-2.6.31.1/arch/arm/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/arm/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400 +@@ -400,6 +400,9 @@ extern unsigned long __must_check __strn + + static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) + { ++ if ((long)n < 0) ++ return n; ++ + if (access_ok(VERIFY_READ, from, n)) + n = __copy_from_user(to, from, n); + else /* security hole - plug it */ +@@ -409,6 +412,9 @@ static inline unsigned long __must_check + + static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) + { ++ if ((long)n < 0) ++ return n; ++ + if (access_ok(VERIFY_WRITE, to, n)) + n = __copy_to_user(to, from, n); + return n; +diff -urNp linux-2.6.31.1/arch/arm/mach-ns9xxx/clock.c linux-2.6.31.1/arch/arm/mach-ns9xxx/clock.c +--- linux-2.6.31.1/arch/arm/mach-ns9xxx/clock.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/arm/mach-ns9xxx/clock.c 2009-10-01 20:12:42.000000000 -0400 +@@ -195,7 +195,7 @@ static int clk_debugfs_open(struct inode + return single_open(file, clk_debugfs_show, NULL); + } + +-static struct file_operations clk_debugfs_operations = { ++static const struct file_operations clk_debugfs_operations = { + .open = clk_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/arch/arm/mm/mmap.c linux-2.6.31.1/arch/arm/mm/mmap.c +--- linux-2.6.31.1/arch/arm/mm/mmap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/arm/mm/mmap.c 2009-10-01 20:12:42.000000000 -0400 +@@ -62,6 +62,10 @@ arch_get_unmapped_area(struct file *filp + if (len > TASK_SIZE) + return -ENOMEM; + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ + if (addr) { + if (do_align) + addr = COLOUR_ALIGN(addr, pgoff); +@@ -74,10 +78,10 @@ arch_get_unmapped_area(struct file *filp + return addr; + } + if (len > mm->cached_hole_size) { +- start_addr = addr = mm->free_area_cache; ++ start_addr = addr = mm->free_area_cache; + } else { +- start_addr = addr = TASK_UNMAPPED_BASE; +- mm->cached_hole_size = 0; ++ start_addr = addr = mm->mmap_base; ++ mm->cached_hole_size = 0; + } + + full_search: +@@ -93,8 +97,8 @@ full_search: + * Start a new search - just in case we missed + * some holes. + */ +- if (start_addr != TASK_UNMAPPED_BASE) { +- start_addr = addr = TASK_UNMAPPED_BASE; ++ if (start_addr != mm->mmap_base) { ++ start_addr = addr = mm->mmap_base; + mm->cached_hole_size = 0; + goto full_search; + } +diff -urNp linux-2.6.31.1/arch/avr32/include/asm/atomic.h linux-2.6.31.1/arch/avr32/include/asm/atomic.h +--- linux-2.6.31.1/arch/avr32/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/avr32/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -20,7 +20,9 @@ + #define ATOMIC_INIT(i) { (i) } + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + #define atomic_set(v, i) (((v)->counter) = i) ++#define atomic_set_unchecked(v, i) (((v)->counter) = i) + + /* + * atomic_sub_return - subtract the atomic variable +@@ -48,6 +50,18 @@ static inline int atomic_sub_return(int + } + + /* ++ * atomic_sub_return_unchecked - subtract the atomic variable ++ * @i: integer value to subtract ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically subtracts @i from @v. Returns the resulting value. ++ */ ++static inline int atomic_sub_return_unchecked(int i, atomic_unchecked_t *v) ++{ ++ return atomic_sub_return(i, (atomic_t *)v); ++} ++ ++/* + * atomic_add_return - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t +@@ -76,6 +90,18 @@ static inline int atomic_add_return(int + } + + /* ++ * atomic_add_return_unchecked - add integer to atomic variable ++ * @i: integer value to add ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically adds @i to @v. Returns the resulting value. ++ */ ++static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v) ++{ ++ return atomic_add_return(i, (atomic_t *)v); ++} ++ ++/* + * atomic_sub_unless - sub unless the number is a given value + * @v: pointer of type atomic_t + * @a: the amount to add to v... +@@ -176,9 +202,12 @@ static inline int atomic_sub_if_positive + #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) + + #define atomic_sub(i, v) (void)atomic_sub_return(i, v) ++#define atomic_sub_unchecked(i, v) (void)atomic_sub_return_unchecked(i, v) + #define atomic_add(i, v) (void)atomic_add_return(i, v) ++#define atomic_add_unchecked(i, v) (void)atomic_add_return_unchecked(i, v) + #define atomic_dec(v) atomic_sub(1, (v)) + #define atomic_inc(v) atomic_add(1, (v)) ++#define atomic_inc_unchecked(v) (void)atomic_add_return_unchecked(1, (v)) + + #define atomic_dec_return(v) atomic_sub_return(1, v) + #define atomic_inc_return(v) atomic_add_return(1, v) +diff -urNp linux-2.6.31.1/arch/avr32/include/asm/elf.h linux-2.6.31.1/arch/avr32/include/asm/elf.h +--- linux-2.6.31.1/arch/avr32/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/avr32/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400 +@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE 0x00001000UL ++ ++#define PAX_DELTA_MMAP_LEN 15 ++#define PAX_DELTA_STACK_LEN 15 ++#endif + + /* This yields a mask that user programs can use to figure out what + instruction set this CPU supports. This could be done in user space, +diff -urNp linux-2.6.31.1/arch/avr32/include/asm/kmap_types.h linux-2.6.31.1/arch/avr32/include/asm/kmap_types.h +--- linux-2.6.31.1/arch/avr32/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/avr32/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400 +@@ -22,7 +22,8 @@ D(10) KM_IRQ0, + D(11) KM_IRQ1, + D(12) KM_SOFTIRQ0, + D(13) KM_SOFTIRQ1, +-D(14) KM_TYPE_NR ++D(14) KM_CLEARPAGE, ++D(15) KM_TYPE_NR + }; + + #undef D +diff -urNp linux-2.6.31.1/arch/avr32/mm/fault.c linux-2.6.31.1/arch/avr32/mm/fault.c +--- linux-2.6.31.1/arch/avr32/mm/fault.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/avr32/mm/fault.c 2009-10-01 20:12:42.000000000 -0400 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru + + int exception_trace = 1; + ++#ifdef CONFIG_PAX_PAGEEXEC ++void pax_report_insns(void *pc, void *sp) ++{ ++ unsigned long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 20; i++) { ++ unsigned char c; ++ if (get_user(c, (unsigned char *)pc+i)) ++ printk(KERN_CONT "???????? "); ++ else ++ printk(KERN_CONT "%02x ", c); ++ } ++ printk("\n"); ++} ++#endif ++ + /* + * This routine handles page faults. It determines the address and the + * problem, and then passes it off to one of the appropriate routines. +@@ -157,6 +174,16 @@ bad_area: + up_read(&mm->mmap_sem); + + if (user_mode(regs)) { ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) { ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) { ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp); ++ do_group_exit(SIGKILL); ++ } ++ } ++#endif ++ + if (exception_trace && printk_ratelimit()) + printk("%s%s[%d]: segfault at %08lx pc %08lx " + "sp %08lx ecr %lu\n", +diff -urNp linux-2.6.31.1/arch/blackfin/include/asm/atomic.h linux-2.6.31.1/arch/blackfin/include/asm/atomic.h +--- linux-2.6.31.1/arch/blackfin/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/blackfin/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -15,8 +15,10 @@ + + #define ATOMIC_INIT(i) { (i) } + #define atomic_set(v, i) (((v)->counter) = i) ++#define atomic_set_unchecked(v, i) (((v)->counter) = i) + + #define atomic_read(v) __raw_uncached_fetch_asm(&(v)->counter) ++#define atomic_read_unchecked(v) __raw_uncached_fetch_asm(&(v)->counter) + + asmlinkage int __raw_uncached_fetch_asm(const volatile int *ptr); + +@@ -35,11 +37,21 @@ static inline void atomic_add(int i, ato + __raw_atomic_update_asm(&v->counter, i); + } + ++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_add(i, (atomic_t *)v); ++} ++ + static inline void atomic_sub(int i, atomic_t *v) + { + __raw_atomic_update_asm(&v->counter, -i); + } + ++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_sub(i, (atomic_t *)v); ++} ++ + static inline int atomic_add_return(int i, atomic_t *v) + { + return __raw_atomic_update_asm(&v->counter, i); +@@ -55,6 +67,11 @@ static inline void atomic_inc(volatile a + __raw_atomic_update_asm(&v->counter, 1); + } + ++static inline void atomic_inc_unchecked(volatile atomic_unchecked_t *v) ++{ ++ atomic_inc((atomic_t *)v); ++} ++ + static inline void atomic_dec(volatile atomic_t *v) + { + __raw_atomic_update_asm(&v->counter, -1); +diff -urNp linux-2.6.31.1/arch/blackfin/mach-bf561/coreb.c linux-2.6.31.1/arch/blackfin/mach-bf561/coreb.c +--- linux-2.6.31.1/arch/blackfin/mach-bf561/coreb.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/blackfin/mach-bf561/coreb.c 2009-10-01 20:12:42.000000000 -0400 +@@ -48,7 +48,7 @@ coreb_ioctl(struct inode *inode, struct + return ret; + } + +-static struct file_operations coreb_fops = { ++static const struct file_operations coreb_fops = { + .owner = THIS_MODULE, + .ioctl = coreb_ioctl, + }; +diff -urNp linux-2.6.31.1/arch/cris/arch-v10/drivers/sync_serial.c linux-2.6.31.1/arch/cris/arch-v10/drivers/sync_serial.c +--- linux-2.6.31.1/arch/cris/arch-v10/drivers/sync_serial.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/cris/arch-v10/drivers/sync_serial.c 2009-10-01 20:12:42.000000000 -0400 +@@ -244,7 +244,7 @@ static unsigned sync_serial_prescale_sha + + #define NUMBER_OF_PORTS 2 + +-static struct file_operations sync_serial_fops = { ++static const struct file_operations sync_serial_fops = { + .owner = THIS_MODULE, + .write = sync_serial_write, + .read = sync_serial_read, +diff -urNp linux-2.6.31.1/arch/cris/arch-v32/drivers/mach-fs/gpio.c linux-2.6.31.1/arch/cris/arch-v32/drivers/mach-fs/gpio.c +--- linux-2.6.31.1/arch/cris/arch-v32/drivers/mach-fs/gpio.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/cris/arch-v32/drivers/mach-fs/gpio.c 2009-10-01 20:12:42.000000000 -0400 +@@ -855,7 +855,7 @@ gpio_leds_ioctl(unsigned int cmd, unsign + return 0; + } + +-struct file_operations gpio_fops = { ++struct struct file_operations gpio_fops = { + .owner = THIS_MODULE, + .poll = gpio_poll, + .ioctl = gpio_ioctl, +diff -urNp linux-2.6.31.1/arch/cris/include/asm/atomic.h linux-2.6.31.1/arch/cris/include/asm/atomic.h +--- linux-2.6.31.1/arch/cris/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/cris/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -16,7 +16,9 @@ + #define ATOMIC_INIT(i) { (i) } + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + #define atomic_set(v,i) (((v)->counter) = (i)) ++#define atomic_set_unchecked(v,i) (((v)->counter) = (i)) + + /* These should be written in asm but we do it in C for now. */ + +@@ -28,6 +30,11 @@ static inline void atomic_add(int i, vol + cris_atomic_restore(v, flags); + } + ++static inline void atomic_add_unchecked(int i, volatile atomic_unchecked_t *v) ++{ ++ atomic_add(i, (volatile atomic_t *)v); ++} ++ + static inline void atomic_sub(int i, volatile atomic_t *v) + { + unsigned long flags; +@@ -36,6 +43,11 @@ static inline void atomic_sub(int i, vol + cris_atomic_restore(v, flags); + } + ++static inline void atomic_sub_unchecked(int i, volatile atomic_unchecked_t *v) ++{ ++ atomic_sub(i, (volatile atomic_t *)v); ++} ++ + static inline int atomic_add_return(int i, volatile atomic_t *v) + { + unsigned long flags; +@@ -76,6 +88,11 @@ static inline void atomic_inc(volatile a + cris_atomic_restore(v, flags); + } + ++static inline void atomic_inc_unchecked(volatile atomic_unchecked_t *v) ++{ ++ atomic_inc((volatile atomic_t *)v); ++} ++ + static inline void atomic_dec(volatile atomic_t *v) + { + unsigned long flags; +diff -urNp linux-2.6.31.1/arch/frv/include/asm/atomic.h linux-2.6.31.1/arch/frv/include/asm/atomic.h +--- linux-2.6.31.1/arch/frv/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/frv/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -37,7 +37,9 @@ + + #define ATOMIC_INIT(i) { (i) } + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + #define atomic_set(v, i) (((v)->counter) = (i)) ++#define atomic_set_unchecked(v, i) (((v)->counter) = (i)) + + #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS + static inline int atomic_add_return(int i, atomic_t *v) +@@ -99,16 +101,31 @@ static inline void atomic_add(int i, ato + atomic_add_return(i, v); + } + ++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_add_return(i, (atomic_t *)v); ++} ++ + static inline void atomic_sub(int i, atomic_t *v) + { + atomic_sub_return(i, v); + } + ++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_sub_return(i, (atomic_t *)v); ++} ++ + static inline void atomic_inc(atomic_t *v) + { + atomic_add_return(1, v); + } + ++static inline void atomic_inc_unchecked(atomic_unchecked_t *v) ++{ ++ atomic_add_return(1, (atomic_t *)v); ++} ++ + static inline void atomic_dec(atomic_t *v) + { + atomic_sub_return(1, v); +diff -urNp linux-2.6.31.1/arch/frv/include/asm/kmap_types.h linux-2.6.31.1/arch/frv/include/asm/kmap_types.h +--- linux-2.6.31.1/arch/frv/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/frv/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400 +@@ -23,6 +23,7 @@ enum km_type { + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, ++ KM_CLEARPAGE, + KM_TYPE_NR + }; + +diff -urNp linux-2.6.31.1/arch/h8300/include/asm/atomic.h linux-2.6.31.1/arch/h8300/include/asm/atomic.h +--- linux-2.6.31.1/arch/h8300/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/h8300/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -11,7 +11,9 @@ + #define ATOMIC_INIT(i) { (i) } + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + #define atomic_set(v, i) (((v)->counter) = i) ++#define atomic_set_unchecked(v, i) (((v)->counter) = i) + + #include <asm/system.h> + #include <linux/kernel.h> +@@ -25,7 +27,13 @@ static __inline__ int atomic_add_return( + return ret; + } + ++static __inline__ int atomic_add_return_unchecked(int i, atomic_unchecked_t *v) ++{ ++ return atomic_add_return(i, (atomic_t *)v); ++} ++ + #define atomic_add(i, v) atomic_add_return(i, v) ++#define atomic_add_unchecked(i, v) atomic_add_return_unchecked(i, v) + #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) + + static __inline__ int atomic_sub_return(int i, atomic_t *v) +@@ -37,7 +45,13 @@ static __inline__ int atomic_sub_return( + return ret; + } + ++static __inline__ int atomic_sub_return_unchecked(int i, atomic_unchecked_t *v) ++{ ++ return atomic_sub_return(i, (atomic_t *)v); ++} ++ + #define atomic_sub(i, v) atomic_sub_return(i, v) ++#define atomic_sub_unchecked(i, v) atomic_sub_return_unchecked(i, v) + #define atomic_sub_and_test(i,v) (atomic_sub_return(i, v) == 0) + + static __inline__ int atomic_inc_return(atomic_t *v) +@@ -50,7 +64,13 @@ static __inline__ int atomic_inc_return( + return ret; + } + ++static __inline__ int atomic_inc_return_unchecked(atomic_unchecked_t *v) ++{ ++ return atomic_inc_return((atomic_t *)v); ++} ++ + #define atomic_inc(v) atomic_inc_return(v) ++#define atomic_inc_unchecked(v) atomic_inc_return_unchecked(v) + + /* + * atomic_inc_and_test - increment and test +diff -urNp linux-2.6.31.1/arch/ia64/ia32/binfmt_elf32.c linux-2.6.31.1/arch/ia64/ia32/binfmt_elf32.c +--- linux-2.6.31.1/arch/ia64/ia32/binfmt_elf32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/ia32/binfmt_elf32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_ + + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack)) + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL) ++ ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) ++#endif ++ + /* Ugly but avoids duplication */ + #include "../../../fs/binfmt_elf.c" + +@@ -69,11 +76,11 @@ ia32_install_gate_page (struct vm_area_s + } + + +-static struct vm_operations_struct ia32_shared_page_vm_ops = { ++static const struct vm_operations_struct ia32_shared_page_vm_ops = { + .fault = ia32_install_shared_page + }; + +-static struct vm_operations_struct ia32_gate_page_vm_ops = { ++static const struct vm_operations_struct ia32_gate_page_vm_ops = { + .fault = ia32_install_gate_page + }; + +diff -urNp linux-2.6.31.1/arch/ia64/ia32/ia32priv.h linux-2.6.31.1/arch/ia64/ia32/ia32priv.h +--- linux-2.6.31.1/arch/ia64/ia32/ia32priv.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/ia32/ia32priv.h 2009-10-01 20:12:42.000000000 -0400 +@@ -296,7 +296,14 @@ typedef struct compat_siginfo { + #define ELF_DATA ELFDATA2LSB + #define ELF_ARCH EM_386 + +-#define IA32_STACK_TOP IA32_PAGE_OFFSET ++#ifdef CONFIG_PAX_RANDUSTACK ++#define __IA32_DELTA_STACK (current->mm->delta_stack) ++#else ++#define __IA32_DELTA_STACK 0UL ++#endif ++ ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK) ++ + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE + +diff -urNp linux-2.6.31.1/arch/ia64/include/asm/atomic.h linux-2.6.31.1/arch/ia64/include/asm/atomic.h +--- linux-2.6.31.1/arch/ia64/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -22,9 +22,11 @@ + #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + #define atomic64_read(v) ((v)->counter) + + #define atomic_set(v,i) (((v)->counter) = (i)) ++#define atomic_set_unchecked(v,i) (((v)->counter) = (i)) + #define atomic64_set(v,i) (((v)->counter) = (i)) + + static __inline__ int +@@ -201,8 +203,11 @@ atomic64_add_negative (__s64 i, atomic64 + #define atomic64_inc_and_test(v) (atomic64_add_return(1, (v)) == 0) + + #define atomic_add(i,v) atomic_add_return((i), (v)) ++#define atomic_add_unchecked(i,v) atomic_add((i), (atomic_t *)(v)) + #define atomic_sub(i,v) atomic_sub_return((i), (v)) ++#define atomic_sub_unchecked(i,v) atomic_sub((i), (atomic_t *)(v)) + #define atomic_inc(v) atomic_add(1, (v)) ++#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v)) + #define atomic_dec(v) atomic_sub(1, (v)) + + #define atomic64_add(i,v) atomic64_add_return((i), (v)) +diff -urNp linux-2.6.31.1/arch/ia64/include/asm/elf.h linux-2.6.31.1/arch/ia64/include/asm/elf.h +--- linux-2.6.31.1/arch/ia64/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400 +@@ -43,6 +43,13 @@ + */ + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL) + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL) ++ ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) ++#endif ++ + #define PT_IA_64_UNWIND 0x70000001 + + /* IA-64 relocations: */ +diff -urNp linux-2.6.31.1/arch/ia64/include/asm/pgtable.h linux-2.6.31.1/arch/ia64/include/asm/pgtable.h +--- linux-2.6.31.1/arch/ia64/include/asm/pgtable.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/include/asm/pgtable.h 2009-10-01 20:12:42.000000000 -0400 +@@ -143,6 +143,17 @@ + #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) + #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) + #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX) ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW) ++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) ++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) ++#else ++# define PAGE_SHARED_NOEXEC PAGE_SHARED ++# define PAGE_READONLY_NOEXEC PAGE_READONLY ++# define PAGE_COPY_NOEXEC PAGE_COPY ++#endif ++ + #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX) + #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX) + #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX) +diff -urNp linux-2.6.31.1/arch/ia64/include/asm/uaccess.h linux-2.6.31.1/arch/ia64/include/asm/uaccess.h +--- linux-2.6.31.1/arch/ia64/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400 +@@ -257,7 +257,7 @@ __copy_from_user (void *to, const void _ + const void *__cu_from = (from); \ + long __cu_len = (n); \ + \ +- if (__access_ok(__cu_to, __cu_len, get_fs())) \ ++ if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_to, __cu_len, get_fs())) \ + __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \ + __cu_len; \ + }) +@@ -269,7 +269,7 @@ __copy_from_user (void *to, const void _ + long __cu_len = (n); \ + \ + __chk_user_ptr(__cu_from); \ +- if (__access_ok(__cu_from, __cu_len, get_fs())) \ ++ if (__cu_len > 0 && __cu_len <= INT_MAX && __access_ok(__cu_from, __cu_len, get_fs())) \ + __cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \ + __cu_len; \ + }) +diff -urNp linux-2.6.31.1/arch/ia64/kernel/module.c linux-2.6.31.1/arch/ia64/kernel/module.c +--- linux-2.6.31.1/arch/ia64/kernel/module.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/kernel/module.c 2009-10-01 20:12:42.000000000 -0400 +@@ -315,8 +315,7 @@ module_alloc (unsigned long size) + void + module_free (struct module *mod, void *module_region) + { +- if (mod && mod->arch.init_unw_table && +- module_region == mod->module_init) { ++ if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) { + unw_remove_unwind_table(mod->arch.init_unw_table); + mod->arch.init_unw_table = NULL; + } +@@ -502,15 +501,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd + } + + static inline int ++in_init_rx (const struct module *mod, uint64_t addr) ++{ ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx; ++} ++ ++static inline int ++in_init_rw (const struct module *mod, uint64_t addr) ++{ ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw; ++} ++ ++static inline int + in_init (const struct module *mod, uint64_t addr) + { +- return addr - (uint64_t) mod->module_init < mod->init_size; ++ return in_init_rx(mod, addr) || in_init_rw(mod, addr); ++} ++ ++static inline int ++in_core_rx (const struct module *mod, uint64_t addr) ++{ ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx; ++} ++ ++static inline int ++in_core_rw (const struct module *mod, uint64_t addr) ++{ ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw; + } + + static inline int + in_core (const struct module *mod, uint64_t addr) + { +- return addr - (uint64_t) mod->module_core < mod->core_size; ++ return in_core_rx(mod, addr) || in_core_rw(mod, addr); + } + + static inline int +@@ -693,7 +716,14 @@ do_reloc (struct module *mod, uint8_t r_ + break; + + case RV_BDREL: +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core); ++ if (in_init_rx(mod, val)) ++ val -= (uint64_t) mod->module_init_rx; ++ else if (in_init_rw(mod, val)) ++ val -= (uint64_t) mod->module_init_rw; ++ else if (in_core_rx(mod, val)) ++ val -= (uint64_t) mod->module_core_rx; ++ else if (in_core_rw(mod, val)) ++ val -= (uint64_t) mod->module_core_rw; + break; + + case RV_LTV: +@@ -828,15 +858,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, + * addresses have been selected... + */ + uint64_t gp; +- if (mod->core_size > MAX_LTOFF) ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF) + /* + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated + * at the end of the module. + */ +- gp = mod->core_size - MAX_LTOFF / 2; ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2; + else +- gp = mod->core_size / 2; +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8); ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2; ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8); + mod->arch.gp = gp; + DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp); + } +diff -urNp linux-2.6.31.1/arch/ia64/kernel/sys_ia64.c linux-2.6.31.1/arch/ia64/kernel/sys_ia64.c +--- linux-2.6.31.1/arch/ia64/kernel/sys_ia64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/kernel/sys_ia64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil + if (REGION_NUMBER(addr) == RGN_HPAGE) + addr = 0; + #endif ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ addr = mm->free_area_cache; ++ else ++#endif ++ + if (!addr) + addr = mm->free_area_cache; + +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { + /* At this point: (!vma || addr < vma->vm_end). */ + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) { +- if (start_addr != TASK_UNMAPPED_BASE) { ++ if (start_addr != mm->mmap_base) { + /* Start a new search --- just in case we missed some holes. */ +- addr = TASK_UNMAPPED_BASE; ++ addr = mm->mmap_base; + goto full_search; + } + return -ENOMEM; +diff -urNp linux-2.6.31.1/arch/ia64/mm/fault.c linux-2.6.31.1/arch/ia64/mm/fault.c +--- linux-2.6.31.1/arch/ia64/mm/fault.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/mm/fault.c 2009-10-01 20:12:42.000000000 -0400 +@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned + return pte_present(pte); + } + ++#ifdef CONFIG_PAX_PAGEEXEC ++void pax_report_insns(void *pc, void *sp) ++{ ++ unsigned long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 8; i++) { ++ unsigned int c; ++ if (get_user(c, (unsigned int *)pc+i)) ++ printk(KERN_CONT "???????? "); ++ else ++ printk(KERN_CONT "%08x ", c); ++ } ++ printk("\n"); ++} ++#endif ++ + void __kprobes + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs) + { +@@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT) + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)); + +- if ((vma->vm_flags & mask) != mask) ++ if ((vma->vm_flags & mask) != mask) { ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) { ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip) ++ goto bad_area; ++ ++ up_read(&mm->mmap_sem); ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12); ++ do_group_exit(SIGKILL); ++ } ++#endif ++ + goto bad_area; + ++ } ++ + survive: + /* + * If for any reason at all we couldn't handle the fault, make +diff -urNp linux-2.6.31.1/arch/ia64/mm/init.c linux-2.6.31.1/arch/ia64/mm/init.c +--- linux-2.6.31.1/arch/ia64/mm/init.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/ia64/mm/init.c 2009-10-01 20:12:42.000000000 -0400 +@@ -122,6 +122,19 @@ ia64_init_addr_space (void) + vma->vm_start = current->thread.rbs_bot & PAGE_MASK; + vma->vm_end = vma->vm_start + PAGE_SIZE; + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT; ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) { ++ vma->vm_flags &= ~VM_EXEC; ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if (current->mm->pax_flags & MF_PAX_MPROTECT) ++ vma->vm_flags &= ~VM_MAYEXEC; ++#endif ++ ++ } ++#endif ++ + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + down_write(¤t->mm->mmap_sem); + if (insert_vm_struct(current->mm, vma)) { +diff -urNp linux-2.6.31.1/arch/m32r/include/asm/atomic.h linux-2.6.31.1/arch/m32r/include/asm/atomic.h +--- linux-2.6.31.1/arch/m32r/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/m32r/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -29,6 +29,14 @@ + #define atomic_read(v) ((v)->counter) + + /** ++ * atomic_read_unchecked - read atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically reads the value of @v. ++ */ ++#define atomic_read_unchecked(v) ((v)->counter) ++ ++/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value +@@ -38,6 +46,15 @@ + #define atomic_set(v,i) (((v)->counter) = (i)) + + /** ++ * atomic_set_unchecked - set atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * @i: required value ++ * ++ * Atomically sets the value of @v to @i. ++ */ ++#define atomic_set_unchecked(v,i) (((v)->counter) = (i)) ++ ++/** + * atomic_add_return - add integer to atomic variable and return it + * @i: integer value to add + * @v: pointer of type atomic_t +@@ -308,6 +325,10 @@ static __inline__ void atomic_set_mask(u + local_irq_restore(flags); + } + ++#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v)) ++#define atomic_add_unchecked(i,v) atomic_add((i),(atomic_t *)(v)) ++#define atomic_sub_unchecked(i,v) atomic_sub((i),(atomic_t *)(v)) ++ + /* Atomic operations are already serializing on m32r */ + #define smp_mb__before_atomic_dec() barrier() + #define smp_mb__after_atomic_dec() barrier() +diff -urNp linux-2.6.31.1/arch/m32r/lib/usercopy.c linux-2.6.31.1/arch/m32r/lib/usercopy.c +--- linux-2.6.31.1/arch/m32r/lib/usercopy.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/m32r/lib/usercopy.c 2009-10-01 20:12:42.000000000 -0400 +@@ -14,6 +14,9 @@ + unsigned long + __generic_copy_to_user(void __user *to, const void *from, unsigned long n) + { ++ if ((long)n < 0) ++ return n; ++ + prefetch(from); + if (access_ok(VERIFY_WRITE, to, n)) + __copy_user(to,from,n); +@@ -23,6 +26,9 @@ __generic_copy_to_user(void __user *to, + unsigned long + __generic_copy_from_user(void *to, const void __user *from, unsigned long n) + { ++ if ((long)n < 0) ++ return n; ++ + prefetchw(to); + if (access_ok(VERIFY_READ, from, n)) + __copy_user_zeroing(to,from,n); +diff -urNp linux-2.6.31.1/arch/m68k/include/asm/atomic_mm.h linux-2.6.31.1/arch/m68k/include/asm/atomic_mm.h +--- linux-2.6.31.1/arch/m68k/include/asm/atomic_mm.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/m68k/include/asm/atomic_mm.h 2009-10-01 20:12:42.000000000 -0400 +@@ -16,23 +16,40 @@ + #define ATOMIC_INIT(i) { (i) } + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + #define atomic_set(v, i) (((v)->counter) = i) ++#define atomic_set_unchecked(v, i) (((v)->counter) = i) + + static inline void atomic_add(int i, atomic_t *v) + { + __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i)); + } + ++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_add(i, (atomic_t *)v); ++} ++ + static inline void atomic_sub(int i, atomic_t *v) + { + __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "id" (i)); + } + ++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_sub(i, (atomic_t *)v); ++} ++ + static inline void atomic_inc(atomic_t *v) + { + __asm__ __volatile__("addql #1,%0" : "+m" (*v)); + } + ++static inline void atomic_inc_unchecked(atomic_unchecked_t *v) ++{ ++ atomic_inc((atomic_t *)v); ++} ++ + static inline void atomic_dec(atomic_t *v) + { + __asm__ __volatile__("subql #1,%0" : "+m" (*v)); +diff -urNp linux-2.6.31.1/arch/m68k/include/asm/atomic_no.h linux-2.6.31.1/arch/m68k/include/asm/atomic_no.h +--- linux-2.6.31.1/arch/m68k/include/asm/atomic_no.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/m68k/include/asm/atomic_no.h 2009-10-01 20:12:42.000000000 -0400 +@@ -16,7 +16,9 @@ + #define ATOMIC_INIT(i) { (i) } + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + #define atomic_set(v, i) (((v)->counter) = i) ++#define atomic_set_unchecked(v, i) (((v)->counter) = i) + + static __inline__ void atomic_add(int i, atomic_t *v) + { +@@ -27,6 +29,11 @@ static __inline__ void atomic_add(int i, + #endif + } + ++static __inline__ void atomic_add_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_add(i, (atomic_t *)v); ++} ++ + static __inline__ void atomic_sub(int i, atomic_t *v) + { + #ifdef CONFIG_COLDFIRE +@@ -36,6 +43,11 @@ static __inline__ void atomic_sub(int i, + #endif + } + ++static __inline__ void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_sub(i, (atomic_t *)v); ++} ++ + static __inline__ int atomic_sub_and_test(int i, atomic_t * v) + { + char c; +@@ -56,6 +68,11 @@ static __inline__ void atomic_inc(volati + __asm__ __volatile__("addql #1,%0" : "+m" (*v)); + } + ++static __inline__ void atomic_inc_unchecked(volatile atomic_unchecked_t *v) ++{ ++ atomic_inc((volatile atomic_t *)v); ++} ++ + /* + * atomic_inc_and_test - increment and test + * @v: pointer of type atomic_t +diff -urNp linux-2.6.31.1/arch/mips/include/asm/atomic.h linux-2.6.31.1/arch/mips/include/asm/atomic.h +--- linux-2.6.31.1/arch/mips/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mips/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -32,6 +32,14 @@ + #define atomic_read(v) ((v)->counter) + + /* ++ * atomic_read_unchecked - read atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically reads the value of @v. ++ */ ++#define atomic_read_unchecked(v) ((v)->counter) ++ ++/* + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value +@@ -41,6 +49,15 @@ + #define atomic_set(v, i) ((v)->counter = (i)) + + /* ++ * atomic_set_unchecked - set atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * @i: required value ++ * ++ * Atomically sets the value of @v to @i. ++ */ ++#define atomic_set_unchecked(v, i) ((v)->counter = (i)) ++ ++/* + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t +@@ -381,6 +398,9 @@ static __inline__ int atomic_add_unless( + * Atomically increments @v by 1. + */ + #define atomic_inc(v) atomic_add(1, (v)) ++#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v)) ++#define atomic_add_unchecked(i, v) atomic_add((i), (atomic_t *)(v)) ++#define atomic_sub_unchecked(i, v) atomic_sub((i), (atomic_t *)(v)) + + /* + * atomic_dec - decrement and test +diff -urNp linux-2.6.31.1/arch/mips/include/asm/elf.h linux-2.6.31.1/arch/mips/include/asm/elf.h +--- linux-2.6.31.1/arch/mips/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mips/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400 +@@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) + #endif + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) ++ ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) ++#endif ++ + #endif /* _ASM_ELF_H */ +diff -urNp linux-2.6.31.1/arch/mips/include/asm/page.h linux-2.6.31.1/arch/mips/include/asm/page.h +--- linux-2.6.31.1/arch/mips/include/asm/page.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mips/include/asm/page.h 2009-10-01 20:12:42.000000000 -0400 +@@ -92,7 +92,7 @@ extern void copy_user_highpage(struct pa + #ifdef CONFIG_CPU_MIPS32 + typedef struct { unsigned long pte_low, pte_high; } pte_t; + #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) +- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; }) ++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; }) + #else + typedef struct { unsigned long long pte; } pte_t; + #define pte_val(x) ((x).pte) +diff -urNp linux-2.6.31.1/arch/mips/include/asm/system.h linux-2.6.31.1/arch/mips/include/asm/system.h +--- linux-2.6.31.1/arch/mips/include/asm/system.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mips/include/asm/system.h 2009-10-01 20:12:42.000000000 -0400 +@@ -217,6 +217,6 @@ extern void per_cpu_trap_init(void); + */ + #define __ARCH_WANT_UNLOCKED_CTXSW + +-extern unsigned long arch_align_stack(unsigned long sp); ++#define arch_align_stack(x) ((x) & ALMASK) + + #endif /* _ASM_SYSTEM_H */ +diff -urNp linux-2.6.31.1/arch/mips/kernel/binfmt_elfn32.c linux-2.6.31.1/arch/mips/kernel/binfmt_elfn32.c +--- linux-2.6.31.1/arch/mips/kernel/binfmt_elfn32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mips/kernel/binfmt_elfn32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N + #undef ELF_ET_DYN_BASE + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) ++ ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) ++#endif ++ + #include <asm/processor.h> + #include <linux/module.h> + #include <linux/elfcore.h> +diff -urNp linux-2.6.31.1/arch/mips/kernel/binfmt_elfo32.c linux-2.6.31.1/arch/mips/kernel/binfmt_elfo32.c +--- linux-2.6.31.1/arch/mips/kernel/binfmt_elfo32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mips/kernel/binfmt_elfo32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N + #undef ELF_ET_DYN_BASE + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) ++ ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) ++#endif ++ + #include <asm/processor.h> + + /* +diff -urNp linux-2.6.31.1/arch/mips/kernel/process.c linux-2.6.31.1/arch/mips/kernel/process.c +--- linux-2.6.31.1/arch/mips/kernel/process.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mips/kernel/process.c 2009-10-01 20:12:42.000000000 -0400 +@@ -470,15 +470,3 @@ unsigned long get_wchan(struct task_stru + out: + return pc; + } +- +-/* +- * Don't forget that the stack pointer must be aligned on a 8 bytes +- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI. +- */ +-unsigned long arch_align_stack(unsigned long sp) +-{ +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) +- sp -= get_random_int() & ~PAGE_MASK; +- +- return sp & ALMASK; +-} +diff -urNp linux-2.6.31.1/arch/mips/kernel/syscall.c linux-2.6.31.1/arch/mips/kernel/syscall.c +--- linux-2.6.31.1/arch/mips/kernel/syscall.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mips/kernel/syscall.c 2009-10-01 20:12:42.000000000 -0400 +@@ -99,6 +99,11 @@ unsigned long arch_get_unmapped_area(str + do_color_align = 0; + if (filp || (flags & MAP_SHARED)) + do_color_align = 1; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ + if (addr) { + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); +@@ -109,7 +114,7 @@ unsigned long arch_get_unmapped_area(str + (!vmm || addr + len <= vmm->vm_start)) + return addr; + } +- addr = TASK_UNMAPPED_BASE; ++ addr = current->mm->mmap_base; + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + else +diff -urNp linux-2.6.31.1/arch/mips/mm/fault.c linux-2.6.31.1/arch/mips/mm/fault.c +--- linux-2.6.31.1/arch/mips/mm/fault.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mips/mm/fault.c 2009-10-01 20:12:42.000000000 -0400 +@@ -26,6 +26,23 @@ + #include <asm/ptrace.h> + #include <asm/highmem.h> /* For VMALLOC_END */ + ++#ifdef CONFIG_PAX_PAGEEXEC ++void pax_report_insns(void *pc) ++{ ++ unsigned long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 5; i++) { ++ unsigned int c; ++ if (get_user(c, (unsigned int *)pc+i)) ++ printk(KERN_CONT "???????? "); ++ else ++ printk(KERN_CONT "%08x ", c); ++ } ++ printk("\n"); ++} ++#endif ++ + /* + * This routine handles page faults. It determines the address, + * and the problem, and then passes it off to one of the appropriate +diff -urNp linux-2.6.31.1/arch/mn10300/include/asm/atomic.h linux-2.6.31.1/arch/mn10300/include/asm/atomic.h +--- linux-2.6.31.1/arch/mn10300/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mn10300/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -34,6 +34,15 @@ + #define atomic_read(v) ((v)->counter) + + /** ++ * atomic_read_unchecked - read atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically reads the value of @v. Note that the guaranteed ++ * useful range of an atomic_unchecked_t is only 24 bits. ++ */ ++#define atomic_read_unchecked(v) ((v)->counter) ++ ++/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value +@@ -43,6 +52,16 @@ + */ + #define atomic_set(v, i) (((v)->counter) = (i)) + ++/** ++ * atomic_set_unchecked - set atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * @i: required value ++ * ++ * Atomically sets the value of @v to @i. Note that the guaranteed ++ * useful range of an atomic_unchecked_t is only 24 bits. ++ */ ++#define atomic_set_unchecked(v, i) (((v)->counter) = (i)) ++ + #include <asm/system.h> + + /** +@@ -99,16 +118,31 @@ static inline void atomic_add(int i, ato + atomic_add_return(i, v); + } + ++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_add_return(i, (atomic_t *)v); ++} ++ + static inline void atomic_sub(int i, atomic_t *v) + { + atomic_sub_return(i, v); + } + ++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_sub_return(i, (atomic_t *)v); ++} ++ + static inline void atomic_inc(atomic_t *v) + { + atomic_add_return(1, v); + } + ++static inline void atomic_inc_unchecked(atomic_unchecked_t *v) ++{ ++ atomic_add_return(1, (atomic_t *)v); ++} ++ + static inline void atomic_dec(atomic_t *v) + { + atomic_sub_return(1, v); +diff -urNp linux-2.6.31.1/arch/mn10300/kernel/setup.c linux-2.6.31.1/arch/mn10300/kernel/setup.c +--- linux-2.6.31.1/arch/mn10300/kernel/setup.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/mn10300/kernel/setup.c 2009-10-01 20:12:42.000000000 -0400 +@@ -285,7 +285,7 @@ static void c_stop(struct seq_file *m, v + { + } + +-struct seq_operations cpuinfo_op = { ++const struct seq_operations cpuinfo_op = { + .start = c_start, + .next = c_next, + .stop = c_stop, +diff -urNp linux-2.6.31.1/arch/parisc/include/asm/atomic.h linux-2.6.31.1/arch/parisc/include/asm/atomic.h +--- linux-2.6.31.1/arch/parisc/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/parisc/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -177,6 +177,18 @@ static __inline__ int __atomic_add_retur + return ret; + } + ++static __inline__ int __atomic_add_return_unchecked(int i, atomic_unchecked_t *v) ++{ ++ int ret; ++ unsigned long flags; ++ _atomic_spin_lock_irqsave(v, flags); ++ ++ ret = (v->counter += i); ++ ++ _atomic_spin_unlock_irqrestore(v, flags); ++ return ret; ++} ++ + static __inline__ void atomic_set(atomic_t *v, int i) + { + unsigned long flags; +@@ -187,11 +199,26 @@ static __inline__ void atomic_set(atomic + _atomic_spin_unlock_irqrestore(v, flags); + } + ++static __inline__ void atomic_set_unchecked(atomic_unchecked_t *v, int i) ++{ ++ unsigned long flags; ++ _atomic_spin_lock_irqsave(v, flags); ++ ++ v->counter = i; ++ ++ _atomic_spin_unlock_irqrestore(v, flags); ++} ++ + static __inline__ int atomic_read(const atomic_t *v) + { + return v->counter; + } + ++static __inline__ int atomic_read_unchecked(const atomic_unchecked_t *v) ++{ ++ return v->counter; ++} ++ + /* exported interface */ + #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) + #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) +@@ -223,8 +250,11 @@ static __inline__ int atomic_add_unless( + #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + + #define atomic_add(i,v) ((void)(__atomic_add_return( (i),(v)))) ++#define atomic_add_unchecked(i,v) ((void)(__atomic_add_return_unchecked( ((i),(v)))) + #define atomic_sub(i,v) ((void)(__atomic_add_return(-(i),(v)))) ++#define atomic_sub_unchecked(i,v) ((void)(__atomic_add_return_unchecked(-(i),(v)))) + #define atomic_inc(v) ((void)(__atomic_add_return( 1,(v)))) ++#define atomic_inc_unchecked(v) ((void)(__atomic_add_return_unchecked( 1,(v)))) + #define atomic_dec(v) ((void)(__atomic_add_return( -1,(v)))) + + #define atomic_add_return(i,v) (__atomic_add_return( (i),(v))) +diff -urNp linux-2.6.31.1/arch/parisc/include/asm/elf.h linux-2.6.31.1/arch/parisc/include/asm/elf.h +--- linux-2.6.31.1/arch/parisc/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/parisc/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400 +@@ -343,6 +343,13 @@ struct pt_regs; /* forward declaration.. + + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000) + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE 0x10000UL ++ ++#define PAX_DELTA_MMAP_LEN 16 ++#define PAX_DELTA_STACK_LEN 16 ++#endif ++ + /* This yields a mask that user programs can use to figure out what + instruction set this CPU supports. This could be done in user space, + but it's not easy, and we've already done it here. */ +diff -urNp linux-2.6.31.1/arch/parisc/include/asm/pgtable.h linux-2.6.31.1/arch/parisc/include/asm/pgtable.h +--- linux-2.6.31.1/arch/parisc/include/asm/pgtable.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/parisc/include/asm/pgtable.h 2009-10-01 20:12:42.000000000 -0400 +@@ -207,6 +207,17 @@ + #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED) + #define PAGE_COPY PAGE_EXECREAD + #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED) ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED) ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED) ++#else ++# define PAGE_SHARED_NOEXEC PAGE_SHARED ++# define PAGE_COPY_NOEXEC PAGE_COPY ++# define PAGE_READONLY_NOEXEC PAGE_READONLY ++#endif ++ + #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) + #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) + #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) +diff -urNp linux-2.6.31.1/arch/parisc/kernel/module.c linux-2.6.31.1/arch/parisc/kernel/module.c +--- linux-2.6.31.1/arch/parisc/kernel/module.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/parisc/kernel/module.c 2009-10-01 20:12:42.000000000 -0400 +@@ -95,16 +95,38 @@ + + /* three functions to determine where in the module core + * or init pieces the location is */ ++static inline int in_init_rx(struct module *me, void *loc) ++{ ++ return (loc >= me->module_init_rx && ++ loc < (me->module_init_rx + me->init_size_rx)); ++} ++ ++static inline int in_init_rw(struct module *me, void *loc) ++{ ++ return (loc >= me->module_init_rw && ++ loc < (me->module_init_rw + me->init_size_rw)); ++} ++ + static inline int in_init(struct module *me, void *loc) + { +- return (loc >= me->module_init && +- loc <= (me->module_init + me->init_size)); ++ return in_init_rx(me, loc) || in_init_rw(me, loc); ++} ++ ++static inline int in_core_rx(struct module *me, void *loc) ++{ ++ return (loc >= me->module_core_rx && ++ loc < (me->module_core_rx + me->core_size_rx)); ++} ++ ++static inline int in_core_rw(struct module *me, void *loc) ++{ ++ return (loc >= me->module_core_rw && ++ loc < (me->module_core_rw + me->core_size_rw)); + } + + static inline int in_core(struct module *me, void *loc) + { +- return (loc >= me->module_core && +- loc <= (me->module_core + me->core_size)); ++ return in_core_rx(me, loc) || in_core_rw(me, loc); + } + + static inline int in_local(struct module *me, void *loc) +@@ -364,13 +386,13 @@ int module_frob_arch_sections(CONST Elf_ + } + + /* align things a bit */ +- me->core_size = ALIGN(me->core_size, 16); +- me->arch.got_offset = me->core_size; +- me->core_size += gots * sizeof(struct got_entry); +- +- me->core_size = ALIGN(me->core_size, 16); +- me->arch.fdesc_offset = me->core_size; +- me->core_size += fdescs * sizeof(Elf_Fdesc); ++ me->core_size_rw = ALIGN(me->core_size_rw, 16); ++ me->arch.got_offset = me->core_size_rw; ++ me->core_size_rw += gots * sizeof(struct got_entry); ++ ++ me->core_size_rw = ALIGN(me->core_size_rw, 16); ++ me->arch.fdesc_offset = me->core_size_rw; ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc); + + me->arch.got_max = gots; + me->arch.fdesc_max = fdescs; +@@ -388,7 +410,7 @@ static Elf64_Word get_got(struct module + + BUG_ON(value == 0); + +- got = me->module_core + me->arch.got_offset; ++ got = me->module_core_rw + me->arch.got_offset; + for (i = 0; got[i].addr; i++) + if (got[i].addr == value) + goto out; +@@ -406,7 +428,7 @@ static Elf64_Word get_got(struct module + #ifdef CONFIG_64BIT + static Elf_Addr get_fdesc(struct module *me, unsigned long value) + { +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset; ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset; + + if (!value) { + printk(KERN_ERR "%s: zero OPD requested!\n", me->name); +@@ -424,7 +446,7 @@ static Elf_Addr get_fdesc(struct module + + /* Create new one */ + fdesc->addr = value; +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset; ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset; + return (Elf_Addr)fdesc; + } + #endif /* CONFIG_64BIT */ +@@ -848,7 +870,7 @@ register_unwind_table(struct module *me, + + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr; + end = table + sechdrs[me->arch.unwind_section].sh_size; +- gp = (Elf_Addr)me->module_core + me->arch.got_offset; ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset; + + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n", + me->arch.unwind_section, table, end, gp); +diff -urNp linux-2.6.31.1/arch/parisc/kernel/sys_parisc.c linux-2.6.31.1/arch/parisc/kernel/sys_parisc.c +--- linux-2.6.31.1/arch/parisc/kernel/sys_parisc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/parisc/kernel/sys_parisc.c 2009-10-01 20:12:42.000000000 -0400 +@@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str + if (flags & MAP_FIXED) + return addr; + if (!addr) +- addr = TASK_UNMAPPED_BASE; ++ addr = current->mm->mmap_base; + + if (filp) { + addr = get_shared_area(filp->f_mapping, addr, len, pgoff); +diff -urNp linux-2.6.31.1/arch/parisc/kernel/traps.c linux-2.6.31.1/arch/parisc/kernel/traps.c +--- linux-2.6.31.1/arch/parisc/kernel/traps.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/parisc/kernel/traps.c 2009-10-01 20:12:42.000000000 -0400 +@@ -733,9 +733,7 @@ void notrace handle_interruption(int cod + + down_read(¤t->mm->mmap_sem); + vma = find_vma(current->mm,regs->iaoq[0]); +- if (vma && (regs->iaoq[0] >= vma->vm_start) +- && (vma->vm_flags & VM_EXEC)) { +- ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) { + fault_address = regs->iaoq[0]; + fault_space = regs->iasq[0]; + +diff -urNp linux-2.6.31.1/arch/parisc/mm/fault.c linux-2.6.31.1/arch/parisc/mm/fault.c +--- linux-2.6.31.1/arch/parisc/mm/fault.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/parisc/mm/fault.c 2009-10-01 20:12:42.000000000 -0400 +@@ -15,6 +15,7 @@ + #include <linux/sched.h> + #include <linux/interrupt.h> + #include <linux/module.h> ++#include <linux/unistd.h> + + #include <asm/uaccess.h> + #include <asm/traps.h> +@@ -52,7 +53,7 @@ DEFINE_PER_CPU(struct exception_data, ex + static unsigned long + parisc_acctyp(unsigned long code, unsigned int inst) + { +- if (code == 6 || code == 16) ++ if (code == 6 || code == 7 || code == 16) + return VM_EXEC; + + switch (inst & 0xf0000000) { +@@ -138,6 +139,116 @@ parisc_acctyp(unsigned long code, unsign + } + #endif + ++#ifdef CONFIG_PAX_PAGEEXEC ++/* ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address) ++ * ++ * returns 1 when task should be killed ++ * 2 when rt_sigreturn trampoline was detected ++ * 3 when unpatched PLT trampoline was detected ++ */ ++static int pax_handle_fetch_fault(struct pt_regs *regs) ++{ ++ ++#ifdef CONFIG_PAX_EMUPLT ++ int err; ++ ++ do { /* PaX: unpatched PLT emulation */ ++ unsigned int bl, depwi; ++ ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs)); ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4)); ++ ++ if (err) ++ break; ++ ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) { ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12; ++ ++ err = get_user(ldw, (unsigned int *)addr); ++ err |= get_user(bv, (unsigned int *)(addr+4)); ++ err |= get_user(ldw2, (unsigned int *)(addr+8)); ++ ++ if (err) ++ break; ++ ++ if (ldw == 0x0E801096U && ++ bv == 0xEAC0C000U && ++ ldw2 == 0x0E881095U) ++ { ++ unsigned int resolver, map; ++ ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8)); ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12)); ++ if (err) ++ break; ++ ++ regs->gr[20] = instruction_pointer(regs)+8; ++ regs->gr[21] = map; ++ regs->gr[22] = resolver; ++ regs->iaoq[0] = resolver | 3UL; ++ regs->iaoq[1] = regs->iaoq[0] + 4; ++ return 3; ++ } ++ } ++ } while (0); ++#endif ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ ++#ifndef CONFIG_PAX_EMUSIGRT ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) ++ return 1; ++#endif ++ ++ do { /* PaX: rt_sigreturn emulation */ ++ unsigned int ldi1, ldi2, bel, nop; ++ ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs)); ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4)); ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8)); ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12)); ++ ++ if (err) ++ break; ++ ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) && ++ ldi2 == 0x3414015AU && ++ bel == 0xE4008200U && ++ nop == 0x08000240U) ++ { ++ regs->gr[25] = (ldi1 & 2) >> 1; ++ regs->gr[20] = __NR_rt_sigreturn; ++ regs->gr[31] = regs->iaoq[1] + 16; ++ regs->sr[0] = regs->iasq[1]; ++ regs->iaoq[0] = 0x100UL; ++ regs->iaoq[1] = regs->iaoq[0] + 4; ++ regs->iasq[0] = regs->sr[2]; ++ regs->iasq[1] = regs->sr[2]; ++ return 2; ++ } ++ } while (0); ++#endif ++ ++ return 1; ++} ++ ++void pax_report_insns(void *pc, void *sp) ++{ ++ unsigned long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 5; i++) { ++ unsigned int c; ++ if (get_user(c, (unsigned int *)pc+i)) ++ printk(KERN_CONT "???????? "); ++ else ++ printk(KERN_CONT "%08x ", c); ++ } ++ printk("\n"); ++} ++#endif ++ + int fixup_exception(struct pt_regs *regs) + { + const struct exception_table_entry *fix; +@@ -192,8 +303,33 @@ good_area: + + acc_type = parisc_acctyp(code,regs->iir); + +- if ((vma->vm_flags & acc_type) != acc_type) ++ if ((vma->vm_flags & acc_type) != acc_type) { ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) && ++ (address & ~3UL) == instruction_pointer(regs)) ++ { ++ up_read(&mm->mmap_sem); ++ switch (pax_handle_fetch_fault(regs)) { ++ ++#ifdef CONFIG_PAX_EMUPLT ++ case 3: ++ return; ++#endif ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ case 2: ++ return; ++#endif ++ ++ } ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]); ++ do_group_exit(SIGKILL); ++ } ++#endif ++ + goto bad_area; ++ } + + /* + * If for any reason at all we couldn't handle the fault, make +diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/atomic.h linux-2.6.31.1/arch/powerpc/include/asm/atomic.h +--- linux-2.6.31.1/arch/powerpc/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -24,11 +24,21 @@ static __inline__ int atomic_read(const + return t; + } + ++static __inline__ int atomic_read_unchecked(const atomic_unchecked_t *v) ++{ ++ return atomic_read((const atomic_t *)v); ++} ++ + static __inline__ void atomic_set(atomic_t *v, int i) + { + __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i)); + } + ++static __inline__ void atomic_set_unchecked(atomic_unchecked_t *v, int i) ++{ ++ atomic_set((atomic_t *)v, i); ++} ++ + static __inline__ void atomic_add(int a, atomic_t *v) + { + int t; +@@ -44,6 +54,11 @@ static __inline__ void atomic_add(int a, + : "cc"); + } + ++static __inline__ void atomic_add_unchecked(int a, atomic_unchecked_t *v) ++{ ++ atomic_add(a, (atomic_t *)v); ++} ++ + static __inline__ int atomic_add_return(int a, atomic_t *v) + { + int t; +@@ -80,6 +95,11 @@ static __inline__ void atomic_sub(int a, + : "cc"); + } + ++static __inline__ void atomic_sub_unchecked(int a, atomic_unchecked_t *v) ++{ ++ atomic_sub(a, (atomic_t *)v); ++} ++ + static __inline__ int atomic_sub_return(int a, atomic_t *v) + { + int t; +@@ -114,6 +134,11 @@ static __inline__ void atomic_inc(atomic + : "cc", "xer"); + } + ++static __inline__ void atomic_inc_unchecked(atomic_unchecked_t *v) ++{ ++ atomic_inc((atomic_t *)v); ++} ++ + static __inline__ int atomic_inc_return(atomic_t *v) + { + int t; +diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/elf.h linux-2.6.31.1/arch/powerpc/include/asm/elf.h +--- linux-2.6.31.1/arch/powerpc/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400 +@@ -179,8 +179,19 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +-extern unsigned long randomize_et_dyn(unsigned long base); +-#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000)) ++#define ELF_ET_DYN_BASE (0x20000000) ++ ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE (0x10000000UL) ++ ++#ifdef __powerpc64__ ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28) ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28) ++#else ++#define PAX_DELTA_MMAP_LEN 15 ++#define PAX_DELTA_STACK_LEN 15 ++#endif ++#endif + + /* + * Our registers are always unsigned longs, whether we're a 32 bit +@@ -279,9 +290,6 @@ extern int arch_setup_additional_pages(s + (0x7ff >> (PAGE_SHIFT - 12)) : \ + (0x3ffff >> (PAGE_SHIFT - 12))) + +-extern unsigned long arch_randomize_brk(struct mm_struct *mm); +-#define arch_randomize_brk arch_randomize_brk +- + #endif /* __KERNEL__ */ + + /* +diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/kmap_types.h linux-2.6.31.1/arch/powerpc/include/asm/kmap_types.h +--- linux-2.6.31.1/arch/powerpc/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400 +@@ -26,6 +26,7 @@ enum km_type { + KM_SOFTIRQ1, + KM_PPC_SYNC_PAGE, + KM_PPC_SYNC_ICACHE, ++ KM_CLEARPAGE, + KM_TYPE_NR + }; + +diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/page_64.h linux-2.6.31.1/arch/powerpc/include/asm/page_64.h +--- linux-2.6.31.1/arch/powerpc/include/asm/page_64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/include/asm/page_64.h 2009-10-01 20:12:42.000000000 -0400 +@@ -170,15 +170,18 @@ do { \ + * stack by default, so in the absense of a PT_GNU_STACK program header + * we turn execute permission off. + */ +-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) ++#define VM_STACK_DEFAULT_FLAGS32 \ ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + + #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + ++#ifndef CONFIG_PAX_PAGEEXEC + #define VM_STACK_DEFAULT_FLAGS \ + (test_thread_flag(TIF_32BIT) ? \ + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64) ++#endif + + #include <asm-generic/getorder.h> + +diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/page.h linux-2.6.31.1/arch/powerpc/include/asm/page.h +--- linux-2.6.31.1/arch/powerpc/include/asm/page.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/include/asm/page.h 2009-10-01 20:12:42.000000000 -0400 +@@ -116,8 +116,9 @@ extern phys_addr_t kernstart_addr; + * and needs to be executable. This means the whole heap ends + * up being executable. + */ +-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) ++#define VM_DATA_DEFAULT_FLAGS32 \ ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + + #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/pte-common.h linux-2.6.31.1/arch/powerpc/include/asm/pte-common.h +--- linux-2.6.31.1/arch/powerpc/include/asm/pte-common.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/include/asm/pte-common.h 2009-10-01 20:12:42.000000000 -0400 +@@ -121,11 +121,11 @@ extern unsigned long bad_call_to_PMD_PAG + */ + #define PAGE_NONE __pgprot(_PAGE_BASE) + #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) +-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC) ++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC) + #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER) +-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) ++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC) + #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER) +-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) ++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC) + + #define __P000 PAGE_NONE + #define __P001 PAGE_READONLY +diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/pte-hash32.h linux-2.6.31.1/arch/powerpc/include/asm/pte-hash32.h +--- linux-2.6.31.1/arch/powerpc/include/asm/pte-hash32.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/include/asm/pte-hash32.h 2009-10-01 20:12:42.000000000 -0400 +@@ -21,6 +21,7 @@ + #define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */ + #define _PAGE_USER 0x004 /* usermode access allowed */ + #define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */ ++#define _PAGE_HWEXEC _PAGE_GUARDED + #define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */ + #define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */ + #define _PAGE_WRITETHRU 0x040 /* W: cache write-through */ +diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/reg.h linux-2.6.31.1/arch/powerpc/include/asm/reg.h +--- linux-2.6.31.1/arch/powerpc/include/asm/reg.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/include/asm/reg.h 2009-10-01 20:12:42.000000000 -0400 +@@ -195,6 +195,7 @@ + #define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */ + #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ + #define DSISR_NOHPTE 0x40000000 /* no translation found */ ++#define DSISR_GUARDED 0x10000000 /* fetch from guarded storage */ + #define DSISR_PROTFAULT 0x08000000 /* protection fault */ + #define DSISR_ISSTORE 0x02000000 /* access was a store */ + #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ +diff -urNp linux-2.6.31.1/arch/powerpc/include/asm/uaccess.h linux-2.6.31.1/arch/powerpc/include/asm/uaccess.h +--- linux-2.6.31.1/arch/powerpc/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400 +@@ -327,52 +327,6 @@ do { \ + extern unsigned long __copy_tofrom_user(void __user *to, + const void __user *from, unsigned long size); + +-#ifndef __powerpc64__ +- +-static inline unsigned long copy_from_user(void *to, +- const void __user *from, unsigned long n) +-{ +- unsigned long over; +- +- if (access_ok(VERIFY_READ, from, n)) +- return __copy_tofrom_user((__force void __user *)to, from, n); +- if ((unsigned long)from < TASK_SIZE) { +- over = (unsigned long)from + n - TASK_SIZE; +- return __copy_tofrom_user((__force void __user *)to, from, +- n - over) + over; +- } +- return n; +-} +- +-static inline unsigned long copy_to_user(void __user *to, +- const void *from, unsigned long n) +-{ +- unsigned long over; +- +- if (access_ok(VERIFY_WRITE, to, n)) +- return __copy_tofrom_user(to, (__force void __user *)from, n); +- if ((unsigned long)to < TASK_SIZE) { +- over = (unsigned long)to + n - TASK_SIZE; +- return __copy_tofrom_user(to, (__force void __user *)from, +- n - over) + over; +- } +- return n; +-} +- +-#else /* __powerpc64__ */ +- +-#define __copy_in_user(to, from, size) \ +- __copy_tofrom_user((to), (from), (size)) +- +-extern unsigned long copy_from_user(void *to, const void __user *from, +- unsigned long n); +-extern unsigned long copy_to_user(void __user *to, const void *from, +- unsigned long n); +-extern unsigned long copy_in_user(void __user *to, const void __user *from, +- unsigned long n); +- +-#endif /* __powerpc64__ */ +- + static inline unsigned long __copy_from_user_inatomic(void *to, + const void __user *from, unsigned long n) + { +@@ -396,6 +350,9 @@ static inline unsigned long __copy_from_ + if (ret == 0) + return 0; + } ++ if (!__builtin_constant_p(n)) ++ check_object_size(to, n, false); ++ + return __copy_tofrom_user((__force void __user *)to, from, n); + } + +@@ -422,6 +379,9 @@ static inline unsigned long __copy_to_us + if (ret == 0) + return 0; + } ++ if (!__builtin_constant_p(n)) ++ check_object_size(from, n, true); ++ + return __copy_tofrom_user(to, (__force const void __user *)from, n); + } + +@@ -439,6 +399,97 @@ static inline unsigned long __copy_to_us + return __copy_to_user_inatomic(to, from, size); + } + ++#ifndef __powerpc64__ ++ ++static inline unsigned long __must_check copy_from_user(void *to, ++ const void __user *from, unsigned long n) ++{ ++ unsigned long over; ++ ++ if (((long)n < 0) || (n > INT_MAX)) ++ return n; ++ ++ if (access_ok(VERIFY_READ, from, n)) { ++ if (!__builtin_constant_p(n)) ++ check_object_size(to, n, false); ++ ++ return __copy_tofrom_user((__force void __user *)to, from, n); ++ } ++ if ((unsigned long)from < TASK_SIZE) { ++ over = (unsigned long)from + n - TASK_SIZE; ++ if (!__builtin_constant_p(n - over)) ++ check_object_size(to, n - over, false); ++ return __copy_tofrom_user((__force void __user *)to, from, ++ n - over) + over; ++ } ++ return n; ++} ++ ++static inline unsigned long __must_check copy_to_user(void __user *to, ++ const void *from, unsigned long n) ++{ ++ unsigned long over; ++ ++ if (((long)n < 0) || (n > INT_MAX)) ++ return n; ++ ++ if (access_ok(VERIFY_WRITE, to, n)) { ++ if (!__builtin_constant_p(n)) ++ check_object_size(from, n, true); ++ return __copy_tofrom_user(to, (__force void __user *)from, n); ++ } ++ if ((unsigned long)to < TASK_SIZE) { ++ over = (unsigned long)to + n - TASK_SIZE; ++ if (!__builtin_constant_p(n)) ++ check_object_size(from, n - over, true); ++ return __copy_tofrom_user(to, (__force void __user *)from, ++ n - over) + over; ++ } ++ return n; ++} ++ ++#else /* __powerpc64__ */ ++ ++#define __copy_in_user(to, from, size) \ ++ __copy_tofrom_user((to), (from), (size)) ++ ++static inline unsigned long __must_check copy_from_user(void *to, ++ const void __user *from, unsigned long n) ++{ ++ if (unlikely(((long)n < 0) || (n > INT_MAX))) ++ return n; ++ ++ if (!__builtin_constant_p(n)) ++ check_object_size(to, n, false); ++ ++ if (likely(access_ok(VERIFY_READ, from, n))) ++ n = __copy_from_user(to, from, n); ++ else ++ memset(to, 0, n); ++ ++ return n; ++} ++ ++static inline unsigned long __must_check copy_to_user(void __user *to, ++ const void *from, unsigned long n) ++{ ++ if (unlikely(((long)n < 0) || (n > INT_MAX))) ++ return n; ++ ++ if (likely(access_ok(VERIFY_WRITE, to, n))) { ++ if (!__builtin_constant_p(n)) ++ check_object_size(from, n, true); ++ n = __copy_to_user(to, from, n); ++ } ++ ++ return n; ++} ++ ++extern unsigned long copy_in_user(void __user *to, const void __user *from, ++ unsigned long n); ++ ++#endif /* __powerpc64__ */ ++ + extern unsigned long __clear_user(void __user *addr, unsigned long size); + + static inline unsigned long clear_user(void __user *addr, unsigned long size) +diff -urNp linux-2.6.31.1/arch/powerpc/kernel/module_32.c linux-2.6.31.1/arch/powerpc/kernel/module_32.c +--- linux-2.6.31.1/arch/powerpc/kernel/module_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/kernel/module_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -162,7 +162,7 @@ int module_frob_arch_sections(Elf32_Ehdr + me->arch.core_plt_section = i; + } + if (!me->arch.core_plt_section || !me->arch.init_plt_section) { +- printk("Module doesn't contain .plt or .init.plt sections.\n"); ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name); + return -ENOEXEC; + } + +@@ -203,11 +203,16 @@ static uint32_t do_plt_call(void *locati + + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location); + /* Init, or core PLT? */ +- if (location >= mod->module_core +- && location < mod->module_core + mod->core_size) ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) || ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw)) + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr; +- else ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) || ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw)) + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr; ++ else { ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name); ++ return ~0UL; ++ } + + /* Find this entry, or if that fails, the next avail. entry */ + while (entry->jump[0]) { +diff -urNp linux-2.6.31.1/arch/powerpc/kernel/process.c linux-2.6.31.1/arch/powerpc/kernel/process.c +--- linux-2.6.31.1/arch/powerpc/kernel/process.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/kernel/process.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1147,36 +1147,3 @@ unsigned long arch_align_stack(unsigned + sp -= get_random_int() & ~PAGE_MASK; + return sp & ~0xf; + } +- +-static inline unsigned long brk_rnd(void) +-{ +- unsigned long rnd = 0; +- +- /* 8MB for 32bit, 1GB for 64bit */ +- if (is_32bit_task()) +- rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT))); +- else +- rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT))); +- +- return rnd << PAGE_SHIFT; +-} +- +-unsigned long arch_randomize_brk(struct mm_struct *mm) +-{ +- unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); +- +- if (ret < mm->brk) +- return mm->brk; +- +- return ret; +-} +- +-unsigned long randomize_et_dyn(unsigned long base) +-{ +- unsigned long ret = PAGE_ALIGN(base + brk_rnd()); +- +- if (ret < base) +- return base; +- +- return ret; +-} +diff -urNp linux-2.6.31.1/arch/powerpc/kernel/setup-common.c linux-2.6.31.1/arch/powerpc/kernel/setup-common.c +--- linux-2.6.31.1/arch/powerpc/kernel/setup-common.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/kernel/setup-common.c 2009-10-01 20:12:42.000000000 -0400 +@@ -328,7 +328,7 @@ static void c_stop(struct seq_file *m, v + { + } + +-struct seq_operations cpuinfo_op = { ++const struct seq_operations cpuinfo_op = { + .start =c_start, + .next = c_next, + .stop = c_stop, +diff -urNp linux-2.6.31.1/arch/powerpc/kernel/signal_32.c linux-2.6.31.1/arch/powerpc/kernel/signal_32.c +--- linux-2.6.31.1/arch/powerpc/kernel/signal_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/kernel/signal_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig + /* Save user registers on the stack */ + frame = &rt_sf->uc.uc_mcontext; + addr = frame; +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) { ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) { + if (save_user_regs(regs, frame, 0, 1)) + goto badframe; + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp; +diff -urNp linux-2.6.31.1/arch/powerpc/kernel/signal_64.c linux-2.6.31.1/arch/powerpc/kernel/signal_64.c +--- linux-2.6.31.1/arch/powerpc/kernel/signal_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/kernel/signal_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -429,7 +429,7 @@ int handle_rt_signal64(int signr, struct + current->thread.fpscr.val = 0; + + /* Set up to return from userspace. */ +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) { ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) { + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp; + } else { + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); +diff -urNp linux-2.6.31.1/arch/powerpc/kernel/sys_ppc32.c linux-2.6.31.1/arch/powerpc/kernel/sys_ppc32.c +--- linux-2.6.31.1/arch/powerpc/kernel/sys_ppc32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/kernel/sys_ppc32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -552,10 +552,10 @@ asmlinkage long compat_sys_sysctl(struct + if (oldlenp) { + if (!error) { + if (get_user(oldlen, oldlenp) || +- put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp))) ++ put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) || ++ copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused))) + error = -EFAULT; + } +- copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); + } + return error; + } +diff -urNp linux-2.6.31.1/arch/powerpc/kernel/vdso.c linux-2.6.31.1/arch/powerpc/kernel/vdso.c +--- linux-2.6.31.1/arch/powerpc/kernel/vdso.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/kernel/vdso.c 2009-10-01 20:12:42.000000000 -0400 +@@ -35,6 +35,7 @@ + #include <asm/firmware.h> + #include <asm/vdso.h> + #include <asm/vdso_datapage.h> ++#include <asm/mman.h> + + #include "setup.h" + +@@ -211,7 +212,7 @@ int arch_setup_additional_pages(struct l + vdso_base = VDSO32_MBASE; + #endif + +- current->mm->context.vdso_base = 0; ++ current->mm->context.vdso_base = ~0UL; + + /* vDSO has a problem and was disabled, just don't "enable" it for the + * process +@@ -228,7 +229,7 @@ int arch_setup_additional_pages(struct l + */ + down_write(&mm->mmap_sem); + vdso_base = get_unmapped_area(NULL, vdso_base, +- vdso_pages << PAGE_SHIFT, 0, 0); ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE); + if (IS_ERR_VALUE(vdso_base)) { + rc = vdso_base; + goto fail_mmapsem; +diff -urNp linux-2.6.31.1/arch/powerpc/kvm/timing.c linux-2.6.31.1/arch/powerpc/kvm/timing.c +--- linux-2.6.31.1/arch/powerpc/kvm/timing.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/kvm/timing.c 2009-10-01 20:12:42.000000000 -0400 +@@ -201,7 +201,7 @@ static int kvmppc_exit_timing_open(struc + return single_open(file, kvmppc_exit_timing_show, inode->i_private); + } + +-static struct file_operations kvmppc_exit_timing_fops = { ++static const struct file_operations kvmppc_exit_timing_fops = { + .owner = THIS_MODULE, + .open = kvmppc_exit_timing_open, + .read = seq_read, +diff -urNp linux-2.6.31.1/arch/powerpc/lib/usercopy_64.c linux-2.6.31.1/arch/powerpc/lib/usercopy_64.c +--- linux-2.6.31.1/arch/powerpc/lib/usercopy_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/lib/usercopy_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -9,22 +9,6 @@ + #include <linux/module.h> + #include <asm/uaccess.h> + +-unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) +-{ +- if (likely(access_ok(VERIFY_READ, from, n))) +- n = __copy_from_user(to, from, n); +- else +- memset(to, 0, n); +- return n; +-} +- +-unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) +-{ +- if (likely(access_ok(VERIFY_WRITE, to, n))) +- n = __copy_to_user(to, from, n); +- return n; +-} +- + unsigned long copy_in_user(void __user *to, const void __user *from, + unsigned long n) + { +@@ -35,7 +19,5 @@ unsigned long copy_in_user(void __user * + return n; + } + +-EXPORT_SYMBOL(copy_from_user); +-EXPORT_SYMBOL(copy_to_user); + EXPORT_SYMBOL(copy_in_user); + +diff -urNp linux-2.6.31.1/arch/powerpc/mm/fault.c linux-2.6.31.1/arch/powerpc/mm/fault.c +--- linux-2.6.31.1/arch/powerpc/mm/fault.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/mm/fault.c 2009-10-01 20:12:42.000000000 -0400 +@@ -30,6 +30,10 @@ + #include <linux/kprobes.h> + #include <linux/kdebug.h> + #include <linux/perf_counter.h> ++#include <linux/slab.h> ++#include <linux/pagemap.h> ++#include <linux/compiler.h> ++#include <linux/unistd.h> + + #include <asm/firmware.h> + #include <asm/page.h> +@@ -40,6 +44,7 @@ + #include <asm/uaccess.h> + #include <asm/tlbflush.h> + #include <asm/siginfo.h> ++#include <asm/ptrace.h> + + + #ifdef CONFIG_KPROBES +@@ -64,6 +69,33 @@ static inline int notify_page_fault(stru + } + #endif + ++#ifdef CONFIG_PAX_PAGEEXEC ++/* ++ * PaX: decide what to do with offenders (regs->nip = fault address) ++ * ++ * returns 1 when task should be killed ++ */ ++static int pax_handle_fetch_fault(struct pt_regs *regs) ++{ ++ return 1; ++} ++ ++void pax_report_insns(void *pc, void *sp) ++{ ++ unsigned long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 5; i++) { ++ unsigned int c; ++ if (get_user(c, (unsigned int *)pc+i)) ++ printk(KERN_CONT "???????? "); ++ else ++ printk(KERN_CONT "%08x ", c); ++ } ++ printk("\n"); ++} ++#endif ++ + /* + * Check whether the instruction at regs->nip is a store using + * an update addressing form which will update r1. +@@ -134,7 +166,7 @@ int __kprobes do_page_fault(struct pt_re + * indicate errors in DSISR but can validly be set in SRR1. + */ + if (trap == 0x400) +- error_code &= 0x48200000; ++ error_code &= 0x58200000; + else + is_write = error_code & DSISR_ISSTORE; + #else +@@ -250,7 +282,7 @@ good_area: + * "undefined". Of those that can be set, this is the only + * one which seems bad. + */ +- if (error_code & 0x10000000) ++ if (error_code & DSISR_GUARDED) + /* Guarded storage error. */ + goto bad_area; + #endif /* CONFIG_8xx */ +@@ -265,7 +297,7 @@ good_area: + * processors use the same I/D cache coherency mechanism + * as embedded. + */ +- if (error_code & DSISR_PROTFAULT) ++ if (error_code & (DSISR_PROTFAULT | DSISR_GUARDED)) + goto bad_area; + #endif /* CONFIG_PPC_STD_MMU */ + +@@ -335,6 +367,23 @@ bad_area: + bad_area_nosemaphore: + /* User mode accesses cause a SIGSEGV */ + if (user_mode(regs)) { ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) { ++#ifdef CONFIG_PPC_STD_MMU ++ if (is_exec && (error_code & (DSISR_PROTFAULT | DSISR_GUARDED))) { ++#else ++ if (is_exec && regs->nip == address) { ++#endif ++ switch (pax_handle_fetch_fault(regs)) { ++ } ++ ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]); ++ do_group_exit(SIGKILL); ++ } ++ } ++#endif ++ + _exception(SIGSEGV, regs, code, address); + return 0; + } +diff -urNp linux-2.6.31.1/arch/powerpc/mm/mmap_64.c linux-2.6.31.1/arch/powerpc/mm/mmap_64.c +--- linux-2.6.31.1/arch/powerpc/mm/mmap_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/mm/mmap_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -99,10 +99,22 @@ void arch_pick_mmap_layout(struct mm_str + */ + if (mmap_is_legacy()) { + mm->mmap_base = TASK_UNMAPPED_BASE; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base += mm->delta_mmap; ++#endif ++ + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; + } else { + mm->mmap_base = mmap_base(); ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; ++#endif ++ + mm->get_unmapped_area = arch_get_unmapped_area_topdown; + mm->unmap_area = arch_unmap_area_topdown; + } +diff -urNp linux-2.6.31.1/arch/powerpc/mm/slice.c linux-2.6.31.1/arch/powerpc/mm/slice.c +--- linux-2.6.31.1/arch/powerpc/mm/slice.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/mm/slice.c 2009-10-01 20:12:42.000000000 -0400 +@@ -426,6 +426,11 @@ unsigned long slice_get_unmapped_area(un + if (fixed && addr > (mm->task_size - len)) + return -EINVAL; + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!fixed && (mm->pax_flags & MF_PAX_RANDMMAP)) ++ addr = 0; ++#endif ++ + /* If hint, make sure it matches our alignment restrictions */ + if (!fixed && addr) { + addr = _ALIGN_UP(addr, 1ul << pshift); +diff -urNp linux-2.6.31.1/arch/powerpc/platforms/cell/spufs/file.c linux-2.6.31.1/arch/powerpc/platforms/cell/spufs/file.c +--- linux-2.6.31.1/arch/powerpc/platforms/cell/spufs/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/platforms/cell/spufs/file.c 2009-10-01 20:12:42.000000000 -0400 +@@ -147,7 +147,7 @@ static int __fops ## _open(struct inode + __simple_attr_check_format(__fmt, 0ull); \ + return spufs_attr_open(inode, file, __get, __set, __fmt); \ + } \ +-static struct file_operations __fops = { \ ++static const struct file_operations __fops = { \ + .owner = THIS_MODULE, \ + .open = __fops ## _open, \ + .release = spufs_attr_release, \ +@@ -309,7 +309,7 @@ static int spufs_mem_mmap_access(struct + return len; + } + +-static struct vm_operations_struct spufs_mem_mmap_vmops = { ++static const struct vm_operations_struct spufs_mem_mmap_vmops = { + .fault = spufs_mem_mmap_fault, + .access = spufs_mem_mmap_access, + }; +@@ -436,7 +436,7 @@ static int spufs_cntl_mmap_fault(struct + return spufs_ps_fault(vma, vmf, 0x4000, SPUFS_CNTL_MAP_SIZE); + } + +-static struct vm_operations_struct spufs_cntl_mmap_vmops = { ++static const struct vm_operations_struct spufs_cntl_mmap_vmops = { + .fault = spufs_cntl_mmap_fault, + }; + +@@ -1143,7 +1143,7 @@ spufs_signal1_mmap_fault(struct vm_area_ + #endif + } + +-static struct vm_operations_struct spufs_signal1_mmap_vmops = { ++static const struct vm_operations_struct spufs_signal1_mmap_vmops = { + .fault = spufs_signal1_mmap_fault, + }; + +@@ -1279,7 +1279,7 @@ spufs_signal2_mmap_fault(struct vm_area_ + #endif + } + +-static struct vm_operations_struct spufs_signal2_mmap_vmops = { ++static const struct vm_operations_struct spufs_signal2_mmap_vmops = { + .fault = spufs_signal2_mmap_fault, + }; + +@@ -1397,7 +1397,7 @@ spufs_mss_mmap_fault(struct vm_area_stru + return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_MSS_MAP_SIZE); + } + +-static struct vm_operations_struct spufs_mss_mmap_vmops = { ++static const struct vm_operations_struct spufs_mss_mmap_vmops = { + .fault = spufs_mss_mmap_fault, + }; + +@@ -1458,7 +1458,7 @@ spufs_psmap_mmap_fault(struct vm_area_st + return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_PS_MAP_SIZE); + } + +-static struct vm_operations_struct spufs_psmap_mmap_vmops = { ++static const struct vm_operations_struct spufs_psmap_mmap_vmops = { + .fault = spufs_psmap_mmap_fault, + }; + +@@ -1517,7 +1517,7 @@ spufs_mfc_mmap_fault(struct vm_area_stru + return spufs_ps_fault(vma, vmf, 0x3000, SPUFS_MFC_MAP_SIZE); + } + +-static struct vm_operations_struct spufs_mfc_mmap_vmops = { ++static const struct vm_operations_struct spufs_mfc_mmap_vmops = { + .fault = spufs_mfc_mmap_fault, + }; + +diff -urNp linux-2.6.31.1/arch/powerpc/platforms/pseries/dtl.c linux-2.6.31.1/arch/powerpc/platforms/pseries/dtl.c +--- linux-2.6.31.1/arch/powerpc/platforms/pseries/dtl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/platforms/pseries/dtl.c 2009-10-01 20:12:42.000000000 -0400 +@@ -209,7 +209,7 @@ static ssize_t dtl_file_read(struct file + return n_read * sizeof(struct dtl_entry); + } + +-static struct file_operations dtl_fops = { ++static const struct file_operations dtl_fops = { + .open = dtl_file_open, + .release = dtl_file_release, + .read = dtl_file_read, +diff -urNp linux-2.6.31.1/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.31.1/arch/powerpc/platforms/pseries/hvCall_inst.c +--- linux-2.6.31.1/arch/powerpc/platforms/pseries/hvCall_inst.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/powerpc/platforms/pseries/hvCall_inst.c 2009-10-01 20:12:42.000000000 -0400 +@@ -71,7 +71,7 @@ static int hc_show(struct seq_file *m, v + return 0; + } + +-static struct seq_operations hcall_inst_seq_ops = { ++static const struct seq_operations hcall_inst_seq_ops = { + .start = hc_start, + .next = hc_next, + .stop = hc_stop, +diff -urNp linux-2.6.31.1/arch/s390/hypfs/inode.c linux-2.6.31.1/arch/s390/hypfs/inode.c +--- linux-2.6.31.1/arch/s390/hypfs/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/s390/hypfs/inode.c 2009-10-01 20:12:42.000000000 -0400 +@@ -41,7 +41,7 @@ struct hypfs_sb_info { + + static const struct file_operations hypfs_file_ops; + static struct file_system_type hypfs_type; +-static struct super_operations hypfs_s_ops; ++static const struct super_operations hypfs_s_ops; + + /* start of list of all dentries, which have to be deleted on update */ + static struct dentry *hypfs_last_dentry; +@@ -476,7 +476,7 @@ static struct file_system_type hypfs_typ + .kill_sb = hypfs_kill_super + }; + +-static struct super_operations hypfs_s_ops = { ++static const struct super_operations hypfs_s_ops = { + .statfs = simple_statfs, + .drop_inode = hypfs_drop_inode, + .show_options = hypfs_show_options, +diff -urNp linux-2.6.31.1/arch/s390/include/asm/atomic.h linux-2.6.31.1/arch/s390/include/asm/atomic.h +--- linux-2.6.31.1/arch/s390/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/s390/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -71,19 +71,31 @@ static inline int atomic_read(const atom + return v->counter; + } + ++static inline int atomic_read_unchecked(const atomic_unchecked_t *v) ++{ ++ return atomic_read((const atomic_t *)v); ++} ++ + static inline void atomic_set(atomic_t *v, int i) + { + v->counter = i; + barrier(); + } + ++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i) ++{ ++ atomic_set((atomic_t *)v, i); ++} ++ + static __inline__ int atomic_add_return(int i, atomic_t * v) + { + return __CS_LOOP(v, i, "ar"); + } + #define atomic_add(_i, _v) atomic_add_return(_i, _v) ++#define atomic_add_unchecked(_i, _v) atomic_add((_i), (atomic_t *)(_v)) + #define atomic_add_negative(_i, _v) (atomic_add_return(_i, _v) < 0) + #define atomic_inc(_v) atomic_add_return(1, _v) ++#define atomic_inc_unchecked(_v) atomic_inc((atomic_t *)(_v)) + #define atomic_inc_return(_v) atomic_add_return(1, _v) + #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) + +@@ -92,6 +104,7 @@ static __inline__ int atomic_sub_return( + return __CS_LOOP(v, i, "sr"); + } + #define atomic_sub(_i, _v) atomic_sub_return(_i, _v) ++#define atomic_sub_unchecked(_i, _v) atomic_sub((_i), (atomic_t *)(_v)) + #define atomic_sub_and_test(_i, _v) (atomic_sub_return(_i, _v) == 0) + #define atomic_dec(_v) atomic_sub_return(1, _v) + #define atomic_dec_return(_v) atomic_sub_return(1, _v) +diff -urNp linux-2.6.31.1/arch/s390/include/asm/uaccess.h linux-2.6.31.1/arch/s390/include/asm/uaccess.h +--- linux-2.6.31.1/arch/s390/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/s390/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400 +@@ -232,6 +232,10 @@ static inline unsigned long __must_check + copy_to_user(void __user *to, const void *from, unsigned long n) + { + might_fault(); ++ ++ if ((long)n < 0) ++ return n; ++ + if (access_ok(VERIFY_WRITE, to, n)) + n = __copy_to_user(to, from, n); + return n; +@@ -257,6 +261,9 @@ copy_to_user(void __user *to, const void + static inline unsigned long __must_check + __copy_from_user(void *to, const void __user *from, unsigned long n) + { ++ if ((long)n < 0) ++ return n; ++ + if (__builtin_constant_p(n) && (n <= 256)) + return uaccess.copy_from_user_small(n, from, to); + else +@@ -283,6 +290,10 @@ static inline unsigned long __must_check + copy_from_user(void *to, const void __user *from, unsigned long n) + { + might_fault(); ++ ++ if ((long)n < 0) ++ return n; ++ + if (access_ok(VERIFY_READ, from, n)) + n = __copy_from_user(to, from, n); + else +diff -urNp linux-2.6.31.1/arch/s390/kernel/module.c linux-2.6.31.1/arch/s390/kernel/module.c +--- linux-2.6.31.1/arch/s390/kernel/module.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/s390/kernel/module.c 2009-10-01 20:12:42.000000000 -0400 +@@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr, + + /* Increase core size by size of got & plt and set start + offsets for got and plt. */ +- me->core_size = ALIGN(me->core_size, 4); +- me->arch.got_offset = me->core_size; +- me->core_size += me->arch.got_size; +- me->arch.plt_offset = me->core_size; +- me->core_size += me->arch.plt_size; ++ me->core_size_rw = ALIGN(me->core_size_rw, 4); ++ me->arch.got_offset = me->core_size_rw; ++ me->core_size_rw += me->arch.got_size; ++ me->arch.plt_offset = me->core_size_rx; ++ me->core_size_rx += me->arch.plt_size; + return 0; + } + +@@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base + if (info->got_initialized == 0) { + Elf_Addr *gotent; + +- gotent = me->module_core + me->arch.got_offset + ++ gotent = me->module_core_rw + me->arch.got_offset + + info->got_offset; + *gotent = val; + info->got_initialized = 1; +@@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base + else if (r_type == R_390_GOTENT || + r_type == R_390_GOTPLTENT) + *(unsigned int *) loc = +- (val + (Elf_Addr) me->module_core - loc) >> 1; ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1; + else if (r_type == R_390_GOT64 || + r_type == R_390_GOTPLT64) + *(unsigned long *) loc = val; +@@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */ + if (info->plt_initialized == 0) { + unsigned int *ip; +- ip = me->module_core + me->arch.plt_offset + ++ ip = me->module_core_rx + me->arch.plt_offset + + info->plt_offset; + #ifndef CONFIG_64BIT + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */ +@@ -317,7 +317,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base + val - loc + 0xffffUL < 0x1ffffeUL) || + (r_type == R_390_PLT32DBL && + val - loc + 0xffffffffULL < 0x1fffffffeULL))) +- val = (Elf_Addr) me->module_core + ++ val = (Elf_Addr) me->module_core_rx + + me->arch.plt_offset + + info->plt_offset; + val += rela->r_addend - loc; +@@ -339,7 +339,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base + case R_390_GOTOFF32: /* 32 bit offset to GOT. */ + case R_390_GOTOFF64: /* 64 bit offset to GOT. */ + val = val + rela->r_addend - +- ((Elf_Addr) me->module_core + me->arch.got_offset); ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset); + if (r_type == R_390_GOTOFF16) + *(unsigned short *) loc = val; + else if (r_type == R_390_GOTOFF32) +@@ -349,7 +349,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base + break; + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */ + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */ +- val = (Elf_Addr) me->module_core + me->arch.got_offset + ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset + + rela->r_addend - loc; + if (r_type == R_390_GOTPC) + *(unsigned int *) loc = val; +diff -urNp linux-2.6.31.1/arch/sh/include/asm/atomic.h linux-2.6.31.1/arch/sh/include/asm/atomic.h +--- linux-2.6.31.1/arch/sh/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sh/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -14,7 +14,9 @@ + #define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + #define atomic_set(v,i) ((v)->counter = (i)) ++#define atomic_set_unchecked(v,i) ((v)->counter = (i)) + + #if defined(CONFIG_GUSA_RB) + #include <asm/atomic-grb.h> +@@ -43,6 +45,9 @@ + #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) + + #define atomic_inc(v) atomic_add(1,(v)) ++#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v)) ++#define atomic_add_unchecked(i,v) atomic_add((i),(atomic_t *)(v)) ++#define atomic_sub_unchecked(i,v) atomic_sub((i),(atomic_t *)(v)) + #define atomic_dec(v) atomic_sub(1,(v)) + + #if !defined(CONFIG_GUSA_RB) && !defined(CONFIG_CPU_SH4A) +diff -urNp linux-2.6.31.1/arch/sparc/include/asm/atomic_32.h linux-2.6.31.1/arch/sparc/include/asm/atomic_32.h +--- linux-2.6.31.1/arch/sparc/include/asm/atomic_32.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/include/asm/atomic_32.h 2009-10-01 20:12:42.000000000 -0400 +@@ -24,12 +24,17 @@ extern int atomic_cmpxchg(atomic_t *, in + #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + extern int atomic_add_unless(atomic_t *, int, int); + extern void atomic_set(atomic_t *, int); ++extern void atomic_set_unchecked(atomic_unchecked_t *, int); + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + + #define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v))) ++#define atomic_add_unchecked(i, v) atomic_add((i), (atomic_t *)(v)) + #define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v))) ++#define atomic_sub_unchecked(i, v) atomic_sub((i), (atomic_t *)(v)) + #define atomic_inc(v) ((void)__atomic_add_return( 1, (v))) ++#define atomic_inc_unchecked(v) atomic_inc((atomic_t *)(v)) + #define atomic_dec(v) ((void)__atomic_add_return( -1, (v))) + + #define atomic_add_return(i, v) (__atomic_add_return( (int)(i), (v))) +diff -urNp linux-2.6.31.1/arch/sparc/include/asm/atomic_64.h linux-2.6.31.1/arch/sparc/include/asm/atomic_64.h +--- linux-2.6.31.1/arch/sparc/include/asm/atomic_64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/include/asm/atomic_64.h 2009-10-01 20:12:42.000000000 -0400 +@@ -14,14 +14,18 @@ + #define ATOMIC64_INIT(i) { (i) } + + #define atomic_read(v) ((v)->counter) ++#define atomic_read_unchecked(v) ((v)->counter) + #define atomic64_read(v) ((v)->counter) + + #define atomic_set(v, i) (((v)->counter) = i) ++#define atomic_set_unchecked(v, i) (((v)->counter) = i) + #define atomic64_set(v, i) (((v)->counter) = i) + + extern void atomic_add(int, atomic_t *); ++extern void atomic_add_unchecked(int, atomic_unchecked_t *); + extern void atomic64_add(int, atomic64_t *); + extern void atomic_sub(int, atomic_t *); ++extern void atomic_sub_unchecked(int, atomic_unchecked_t *); + extern void atomic64_sub(int, atomic64_t *); + + extern int atomic_add_ret(int, atomic_t *); +@@ -59,6 +63,7 @@ extern int atomic64_sub_ret(int, atomic6 + #define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0) + + #define atomic_inc(v) atomic_add(1, v) ++#define atomic_inc_unchecked(v) atomic_add_unchecked(1, v) + #define atomic64_inc(v) atomic64_add(1, v) + + #define atomic_dec(v) atomic_sub(1, v) +@@ -72,17 +77,28 @@ extern int atomic64_sub_ret(int, atomic6 + + static inline int atomic_add_unless(atomic_t *v, int a, int u) + { +- int c, old; ++ int c, old, new; + c = atomic_read(v); + for (;;) { +- if (unlikely(c == (u))) ++ if (unlikely(c == u)) + break; +- old = atomic_cmpxchg((v), c, c + (a)); ++ ++ asm volatile("addcc %2, %0, %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "tvs %%icc, 6\n" ++#endif ++ ++ : "=r" (new) ++ : "0" (c), "ir" (a) ++ : "cc"); ++ ++ old = atomic_cmpxchg(v, c, new); + if (likely(old == c)) + break; + c = old; + } +- return c != (u); ++ return c != u; + } + + #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) +@@ -93,17 +109,28 @@ static inline int atomic_add_unless(atom + + static inline int atomic64_add_unless(atomic64_t *v, long a, long u) + { +- long c, old; ++ long c, old, new; + c = atomic64_read(v); + for (;;) { +- if (unlikely(c == (u))) ++ if (unlikely(c == u)) + break; +- old = atomic64_cmpxchg((v), c, c + (a)); ++ ++ asm volatile("addcc %2, %0, %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "tvs %%xcc, 6\n" ++#endif ++ ++ : "=r" (new) ++ : "0" (c), "ir" (a) ++ : "cc"); ++ ++ old = atomic64_cmpxchg(v, c, new); + if (likely(old == c)) + break; + c = old; + } +- return c != (u); ++ return c != u; + } + + #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) +diff -urNp linux-2.6.31.1/arch/sparc/include/asm/elf_32.h linux-2.6.31.1/arch/sparc/include/asm/elf_32.h +--- linux-2.6.31.1/arch/sparc/include/asm/elf_32.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/include/asm/elf_32.h 2009-10-01 20:12:42.000000000 -0400 +@@ -116,6 +116,13 @@ typedef struct { + + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE) + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE 0x10000UL ++ ++#define PAX_DELTA_MMAP_LEN 16 ++#define PAX_DELTA_STACK_LEN 16 ++#endif ++ + /* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. This can NOT be done in userspace + on Sparc. */ +diff -urNp linux-2.6.31.1/arch/sparc/include/asm/elf_64.h linux-2.6.31.1/arch/sparc/include/asm/elf_64.h +--- linux-2.6.31.1/arch/sparc/include/asm/elf_64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/include/asm/elf_64.h 2009-10-01 20:12:42.000000000 -0400 +@@ -163,6 +163,12 @@ typedef struct { + #define ELF_ET_DYN_BASE 0x0000010000000000UL + #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL + ++#ifdef CONFIG_PAX_ASLR ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL) ++ ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 ) ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 ) ++#endif + + /* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ +diff -urNp linux-2.6.31.1/arch/sparc/include/asm/pgtable_32.h linux-2.6.31.1/arch/sparc/include/asm/pgtable_32.h +--- linux-2.6.31.1/arch/sparc/include/asm/pgtable_32.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/include/asm/pgtable_32.h 2009-10-01 20:12:42.000000000 -0400 +@@ -43,6 +43,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd) + BTFIXUPDEF_INT(page_none) + BTFIXUPDEF_INT(page_copy) + BTFIXUPDEF_INT(page_readonly) ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++BTFIXUPDEF_INT(page_shared_noexec) ++BTFIXUPDEF_INT(page_copy_noexec) ++BTFIXUPDEF_INT(page_readonly_noexec) ++#endif ++ + BTFIXUPDEF_INT(page_kernel) + + #define PMD_SHIFT SUN4C_PMD_SHIFT +@@ -64,6 +71,16 @@ extern pgprot_t PAGE_SHARED; + #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy)) + #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly)) + ++#ifdef CONFIG_PAX_PAGEEXEC ++extern pgprot_t PAGE_SHARED_NOEXEC; ++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec)) ++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec)) ++#else ++# define PAGE_SHARED_NOEXEC PAGE_SHARED ++# define PAGE_COPY_NOEXEC PAGE_COPY ++# define PAGE_READONLY_NOEXEC PAGE_READONLY ++#endif ++ + extern unsigned long page_kernel; + + #ifdef MODULE +diff -urNp linux-2.6.31.1/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.31.1/arch/sparc/include/asm/pgtsrmmu.h +--- linux-2.6.31.1/arch/sparc/include/asm/pgtsrmmu.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/include/asm/pgtsrmmu.h 2009-10-01 20:12:42.000000000 -0400 +@@ -115,6 +115,13 @@ + SRMMU_EXEC | SRMMU_REF) + #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \ + SRMMU_EXEC | SRMMU_REF) ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF) ++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF) ++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF) ++#endif ++ + #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \ + SRMMU_DIRTY | SRMMU_REF) + +diff -urNp linux-2.6.31.1/arch/sparc/include/asm/spinlock_64.h linux-2.6.31.1/arch/sparc/include/asm/spinlock_64.h +--- linux-2.6.31.1/arch/sparc/include/asm/spinlock_64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/include/asm/spinlock_64.h 2009-10-01 20:12:42.000000000 -0400 +@@ -99,7 +99,12 @@ static void inline __read_lock(raw_rwloc + __asm__ __volatile__ ( + "1: ldsw [%2], %0\n" + " brlz,pn %0, 2f\n" +-"4: add %0, 1, %1\n" ++"4: addcc %0, 1, %1\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++" tvs %%icc, 6\n" ++#endif ++ + " cas [%2], %0, %1\n" + " cmp %0, %1\n" + " bne,pn %%icc, 1b\n" +@@ -112,7 +117,7 @@ static void inline __read_lock(raw_rwloc + " .previous" + : "=&r" (tmp1), "=&r" (tmp2) + : "r" (lock) +- : "memory"); ++ : "memory", "cc"); + } + + static int inline __read_trylock(raw_rwlock_t *lock) +@@ -123,7 +128,12 @@ static int inline __read_trylock(raw_rwl + "1: ldsw [%2], %0\n" + " brlz,a,pn %0, 2f\n" + " mov 0, %0\n" +-" add %0, 1, %1\n" ++" addcc %0, 1, %1\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++" tvs %%icc, 6\n" ++#endif ++ + " cas [%2], %0, %1\n" + " cmp %0, %1\n" + " bne,pn %%icc, 1b\n" +@@ -142,7 +152,12 @@ static void inline __read_unlock(raw_rwl + + __asm__ __volatile__( + "1: lduw [%2], %0\n" +-" sub %0, 1, %1\n" ++" subcc %0, 1, %1\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++" tvs %%icc, 6\n" ++#endif ++ + " cas [%2], %0, %1\n" + " cmp %0, %1\n" + " bne,pn %%xcc, 1b\n" +diff -urNp linux-2.6.31.1/arch/sparc/include/asm/uaccess_32.h linux-2.6.31.1/arch/sparc/include/asm/uaccess_32.h +--- linux-2.6.31.1/arch/sparc/include/asm/uaccess_32.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/include/asm/uaccess_32.h 2009-10-01 20:12:42.000000000 -0400 +@@ -249,27 +249,49 @@ extern unsigned long __copy_user(void __ + + static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) + { +- if (n && __access_ok((unsigned long) to, n)) ++ if ((long)n < 0) ++ return n; ++ ++ if (n && __access_ok((unsigned long) to, n)) { ++ if (!__builtin_constant_p(n)) ++ check_object_size(from, n, true); + return __copy_user(to, (__force void __user *) from, n); +- else ++ } else + return n; + } + + static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) + { ++ if ((long)n < 0) ++ return n; ++ ++ if (!__builtin_constant_p(n)) ++ check_object_size(from, n, true); ++ + return __copy_user(to, (__force void __user *) from, n); + } + + static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) + { +- if (n && __access_ok((unsigned long) from, n)) ++ if ((long)n < 0) ++ return n; ++ ++ if (n && __access_ok((unsigned long) from, n)) { ++ if (!__builtin_constant_p(n)) ++ check_object_size(to, n, false); + return __copy_user((__force void __user *) to, from, n); +- else ++ } else + return n; + } + + static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) + { ++ if ((long)n < 0) ++ return n; ++ ++ if (!__builtin_constant_p(n)) ++ check_object_size(to, n, false); ++ + return __copy_user((__force void __user *) to, from, n); + } + +diff -urNp linux-2.6.31.1/arch/sparc/include/asm/uaccess_64.h linux-2.6.31.1/arch/sparc/include/asm/uaccess_64.h +--- linux-2.6.31.1/arch/sparc/include/asm/uaccess_64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/include/asm/uaccess_64.h 2009-10-01 20:12:42.000000000 -0400 +@@ -212,7 +212,15 @@ extern unsigned long copy_from_user_fixu + static inline unsigned long __must_check + copy_from_user(void *to, const void __user *from, unsigned long size) + { +- unsigned long ret = ___copy_from_user(to, from, size); ++ unsigned long ret; ++ ++ if (unlikely(((long)size > INT_MAX) || ((long)size < 0))) ++ return size; ++ ++ if (!__builtin_constant_p(size)) ++ check_object_size(to, size, false); ++ ++ ret = ___copy_from_user(to, from, size); + + if (unlikely(ret)) + ret = copy_from_user_fixup(to, from, size); +@@ -228,7 +236,15 @@ extern unsigned long copy_to_user_fixup( + static inline unsigned long __must_check + copy_to_user(void __user *to, const void *from, unsigned long size) + { +- unsigned long ret = ___copy_to_user(to, from, size); ++ unsigned long ret; ++ ++ if (unlikely(((long)size > INT_MAX) || ((long)size < 0))) ++ return size; ++ ++ if (!__builtin_constant_p(size)) ++ check_object_size(from, size, true); ++ ++ ret = ___copy_to_user(to, from, size); + + if (unlikely(ret)) + ret = copy_to_user_fixup(to, from, size); +diff -urNp linux-2.6.31.1/arch/sparc/kernel/Makefile linux-2.6.31.1/arch/sparc/kernel/Makefile +--- linux-2.6.31.1/arch/sparc/kernel/Makefile 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/kernel/Makefile 2009-10-01 20:12:42.000000000 -0400 +@@ -3,7 +3,7 @@ + # + + asflags-y := -ansi +-ccflags-y := -Werror ++#ccflags-y := -Werror + + extra-y := head_$(BITS).o + extra-y += init_task.o +diff -urNp linux-2.6.31.1/arch/sparc/kernel/sys_sparc_32.c linux-2.6.31.1/arch/sparc/kernel/sys_sparc_32.c +--- linux-2.6.31.1/arch/sparc/kernel/sys_sparc_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/kernel/sys_sparc_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str + if (ARCH_SUN4C && len > 0x20000000) + return -ENOMEM; + if (!addr) +- addr = TASK_UNMAPPED_BASE; ++ addr = current->mm->mmap_base; + + if (flags & MAP_SHARED) + addr = COLOUR_ALIGN(addr); +diff -urNp linux-2.6.31.1/arch/sparc/kernel/sys_sparc_64.c linux-2.6.31.1/arch/sparc/kernel/sys_sparc_64.c +--- linux-2.6.31.1/arch/sparc/kernel/sys_sparc_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/kernel/sys_sparc_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -125,7 +125,7 @@ unsigned long arch_get_unmapped_area(str + /* We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ +- if ((flags & MAP_SHARED) && ++ if ((filp || (flags & MAP_SHARED)) && + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) + return -EINVAL; + return addr; +@@ -140,6 +140,10 @@ unsigned long arch_get_unmapped_area(str + if (filp || (flags & MAP_SHARED)) + do_color_align = 1; + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ + if (addr) { + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); +@@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str + } + + if (len > mm->cached_hole_size) { +- start_addr = addr = mm->free_area_cache; ++ start_addr = addr = mm->free_area_cache; + } else { +- start_addr = addr = TASK_UNMAPPED_BASE; ++ start_addr = addr = mm->mmap_base; + mm->cached_hole_size = 0; + } + +@@ -175,8 +179,8 @@ full_search: + vma = find_vma(mm, VA_EXCLUDE_END); + } + if (unlikely(task_size < addr)) { +- if (start_addr != TASK_UNMAPPED_BASE) { +- start_addr = addr = TASK_UNMAPPED_BASE; ++ if (start_addr != mm->mmap_base) { ++ start_addr = addr = mm->mmap_base; + mm->cached_hole_size = 0; + goto full_search; + } +@@ -216,7 +220,7 @@ arch_get_unmapped_area_topdown(struct fi + /* We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ +- if ((flags & MAP_SHARED) && ++ if ((filp || (flags & MAP_SHARED)) && + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) + return -EINVAL; + return addr; +@@ -380,6 +384,12 @@ void arch_pick_mmap_layout(struct mm_str + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY || + sysctl_legacy_va_layout) { + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base += mm->delta_mmap; ++#endif ++ + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; + } else { +@@ -394,6 +404,12 @@ void arch_pick_mmap_layout(struct mm_str + gap = (task_size / 6 * 5); + + mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor); ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; ++#endif ++ + mm->get_unmapped_area = arch_get_unmapped_area_topdown; + mm->unmap_area = arch_unmap_area_topdown; + } +diff -urNp linux-2.6.31.1/arch/sparc/kernel/traps_64.c linux-2.6.31.1/arch/sparc/kernel/traps_64.c +--- linux-2.6.31.1/arch/sparc/kernel/traps_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/kernel/traps_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -93,6 +93,12 @@ void bad_trap(struct pt_regs *regs, long + + lvl -= 0x100; + if (regs->tstate & TSTATE_PRIV) { ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ if (lvl == 6) ++ pax_report_refcount_overflow(regs); ++#endif ++ + sprintf(buffer, "Kernel bad sw trap %lx", lvl); + die_if_kernel(buffer, regs); + } +@@ -111,11 +117,16 @@ void bad_trap(struct pt_regs *regs, long + void bad_trap_tl1(struct pt_regs *regs, long lvl) + { + char buffer[32]; +- ++ + if (notify_die(DIE_TRAP_TL1, "bad trap tl1", regs, + 0, lvl, SIGTRAP) == NOTIFY_STOP) + return; + ++#ifdef CONFIG_PAX_REFCOUNT ++ if (lvl == 6) ++ pax_report_refcount_overflow(regs); ++#endif ++ + dump_tl1_traplog((struct tl1_traplog *)(regs + 1)); + + sprintf (buffer, "Bad trap %lx at tl>0", lvl); +diff -urNp linux-2.6.31.1/arch/sparc/lib/atomic32.c linux-2.6.31.1/arch/sparc/lib/atomic32.c +--- linux-2.6.31.1/arch/sparc/lib/atomic32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/lib/atomic32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -80,6 +80,12 @@ void atomic_set(atomic_t *v, int i) + } + EXPORT_SYMBOL(atomic_set); + ++void atomic_set_unchecked(atomic_unchecked_t *v, int i) ++{ ++ atomic_set((atomic_t *)v, i); ++} ++EXPORT_SYMBOL(atomic_set_unchecked); ++ + unsigned long ___set_bit(unsigned long *addr, unsigned long mask) + { + unsigned long old, flags; +diff -urNp linux-2.6.31.1/arch/sparc/lib/atomic_64.S linux-2.6.31.1/arch/sparc/lib/atomic_64.S +--- linux-2.6.31.1/arch/sparc/lib/atomic_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/lib/atomic_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -18,7 +18,12 @@ + atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) + 1: lduw [%o1], %g1 +- add %g1, %o0, %g7 ++ addcc %g1, %o0, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o1], %g1, %g7 + cmp %g1, %g7 + bne,pn %icc, 2f +@@ -28,12 +33,32 @@ atomic_add: /* %o0 = increment, %o1 = at + 2: BACKOFF_SPIN(%o2, %o3, 1b) + .size atomic_add, .-atomic_add + ++ .globl atomic_add_unchecked ++ .type atomic_add_unchecked,#function ++atomic_add_unchecked: /* %o0 = increment, %o1 = atomic_ptr */ ++ BACKOFF_SETUP(%o2) ++1: lduw [%o1], %g1 ++ add %g1, %o0, %g7 ++ cas [%o1], %g1, %g7 ++ cmp %g1, %g7 ++ bne,pn %icc, 2f ++ nop ++ retl ++ nop ++2: BACKOFF_SPIN(%o2, %o3, 1b) ++ .size atomic_add_unchecked, .-atomic_add_unchecked ++ + .globl atomic_sub + .type atomic_sub,#function + atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) + 1: lduw [%o1], %g1 +- sub %g1, %o0, %g7 ++ subcc %g1, %o0, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o1], %g1, %g7 + cmp %g1, %g7 + bne,pn %icc, 2f +@@ -43,12 +68,32 @@ atomic_sub: /* %o0 = decrement, %o1 = at + 2: BACKOFF_SPIN(%o2, %o3, 1b) + .size atomic_sub, .-atomic_sub + ++ .globl atomic_sub_unchecked ++ .type atomic_sub_unchecked,#function ++atomic_sub_unchecked: /* %o0 = decrement, %o1 = atomic_ptr */ ++ BACKOFF_SETUP(%o2) ++1: lduw [%o1], %g1 ++ sub %g1, %o0, %g7 ++ cas [%o1], %g1, %g7 ++ cmp %g1, %g7 ++ bne,pn %icc, 2f ++ nop ++ retl ++ nop ++2: BACKOFF_SPIN(%o2, %o3, 1b) ++ .size atomic_sub_unchecked, .-atomic_sub_unchecked ++ + .globl atomic_add_ret + .type atomic_add_ret,#function + atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) + 1: lduw [%o1], %g1 +- add %g1, %o0, %g7 ++ addcc %g1, %o0, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o1], %g1, %g7 + cmp %g1, %g7 + bne,pn %icc, 2f +@@ -64,7 +109,12 @@ atomic_add_ret: /* %o0 = increment, %o1 + atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) + 1: lduw [%o1], %g1 +- sub %g1, %o0, %g7 ++ subcc %g1, %o0, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o1], %g1, %g7 + cmp %g1, %g7 + bne,pn %icc, 2f +@@ -80,7 +130,12 @@ atomic_sub_ret: /* %o0 = decrement, %o1 + atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) + 1: ldx [%o1], %g1 +- add %g1, %o0, %g7 ++ addcc %g1, %o0, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %xcc, 6 ++#endif ++ + casx [%o1], %g1, %g7 + cmp %g1, %g7 + bne,pn %xcc, 2f +@@ -95,7 +150,12 @@ atomic64_add: /* %o0 = increment, %o1 = + atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) + 1: ldx [%o1], %g1 +- sub %g1, %o0, %g7 ++ subcc %g1, %o0, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %xcc, 6 ++#endif ++ + casx [%o1], %g1, %g7 + cmp %g1, %g7 + bne,pn %xcc, 2f +@@ -110,7 +170,12 @@ atomic64_sub: /* %o0 = decrement, %o1 = + atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) + 1: ldx [%o1], %g1 +- add %g1, %o0, %g7 ++ addcc %g1, %o0, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %xcc, 6 ++#endif ++ + casx [%o1], %g1, %g7 + cmp %g1, %g7 + bne,pn %xcc, 2f +@@ -126,7 +191,12 @@ atomic64_add_ret: /* %o0 = increment, %o + atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ + BACKOFF_SETUP(%o2) + 1: ldx [%o1], %g1 +- sub %g1, %o0, %g7 ++ subcc %g1, %o0, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %xcc, 6 ++#endif ++ + casx [%o1], %g1, %g7 + cmp %g1, %g7 + bne,pn %xcc, 2f +diff -urNp linux-2.6.31.1/arch/sparc/lib/ksyms.c linux-2.6.31.1/arch/sparc/lib/ksyms.c +--- linux-2.6.31.1/arch/sparc/lib/ksyms.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/lib/ksyms.c 2009-10-01 20:12:42.000000000 -0400 +@@ -144,8 +144,10 @@ EXPORT_SYMBOL(__downgrade_write); + + /* Atomic counter implementation. */ + EXPORT_SYMBOL(atomic_add); ++EXPORT_SYMBOL(atomic_add_unchecked); + EXPORT_SYMBOL(atomic_add_ret); + EXPORT_SYMBOL(atomic_sub); ++EXPORT_SYMBOL(atomic_sub_unchecked); + EXPORT_SYMBOL(atomic_sub_ret); + EXPORT_SYMBOL(atomic64_add); + EXPORT_SYMBOL(atomic64_add_ret); +diff -urNp linux-2.6.31.1/arch/sparc/lib/rwsem_64.S linux-2.6.31.1/arch/sparc/lib/rwsem_64.S +--- linux-2.6.31.1/arch/sparc/lib/rwsem_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/lib/rwsem_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -11,7 +11,12 @@ + .globl __down_read + __down_read: + 1: lduw [%o0], %g1 +- add %g1, 1, %g7 ++ addcc %g1, 1, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o0], %g1, %g7 + cmp %g1, %g7 + bne,pn %icc, 1b +@@ -33,7 +38,12 @@ __down_read: + .globl __down_read_trylock + __down_read_trylock: + 1: lduw [%o0], %g1 +- add %g1, 1, %g7 ++ addcc %g1, 1, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cmp %g7, 0 + bl,pn %icc, 2f + mov 0, %o1 +@@ -51,7 +61,12 @@ __down_write: + or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 + 1: + lduw [%o0], %g3 +- add %g3, %g1, %g7 ++ addcc %g3, %g1, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o0], %g3, %g7 + cmp %g3, %g7 + bne,pn %icc, 1b +@@ -77,7 +92,12 @@ __down_write_trylock: + cmp %g3, 0 + bne,pn %icc, 2f + mov 0, %o1 +- add %g3, %g1, %g7 ++ addcc %g3, %g1, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o0], %g3, %g7 + cmp %g3, %g7 + bne,pn %icc, 1b +@@ -90,7 +110,12 @@ __down_write_trylock: + __up_read: + 1: + lduw [%o0], %g1 +- sub %g1, 1, %g7 ++ subcc %g1, 1, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o0], %g1, %g7 + cmp %g1, %g7 + bne,pn %icc, 1b +@@ -118,7 +143,12 @@ __up_write: + or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 + 1: + lduw [%o0], %g3 +- sub %g3, %g1, %g7 ++ subcc %g3, %g1, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o0], %g3, %g7 + cmp %g3, %g7 + bne,pn %icc, 1b +@@ -143,7 +173,12 @@ __downgrade_write: + or %g1, %lo(RWSEM_WAITING_BIAS), %g1 + 1: + lduw [%o0], %g3 +- sub %g3, %g1, %g7 ++ subcc %g3, %g1, %g7 ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ tvs %icc, 6 ++#endif ++ + cas [%o0], %g3, %g7 + cmp %g3, %g7 + bne,pn %icc, 1b +diff -urNp linux-2.6.31.1/arch/sparc/Makefile linux-2.6.31.1/arch/sparc/Makefile +--- linux-2.6.31.1/arch/sparc/Makefile 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/Makefile 2009-10-01 20:12:42.000000000 -0400 +@@ -81,7 +81,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc + # Export what is needed by arch/sparc/boot/Makefile + export VMLINUX_INIT VMLINUX_MAIN + VMLINUX_INIT := $(head-y) $(init-y) +-VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/ ++VMLINUX_MAIN := $(core-y) kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/ + VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y) + VMLINUX_MAIN += $(drivers-y) $(net-y) + +diff -urNp linux-2.6.31.1/arch/sparc/mm/fault_32.c linux-2.6.31.1/arch/sparc/mm/fault_32.c +--- linux-2.6.31.1/arch/sparc/mm/fault_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/mm/fault_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -21,6 +21,9 @@ + #include <linux/interrupt.h> + #include <linux/module.h> + #include <linux/kdebug.h> ++#include <linux/slab.h> ++#include <linux/pagemap.h> ++#include <linux/compiler.h> + + #include <asm/system.h> + #include <asm/page.h> +@@ -167,6 +170,267 @@ static unsigned long compute_si_addr(str + return safe_compute_effective_address(regs, insn); + } + ++#ifdef CONFIG_PAX_PAGEEXEC ++#ifdef CONFIG_PAX_DLRESOLVE ++void pax_emuplt_close(struct vm_area_struct *vma) ++{ ++ vma->vm_mm->call_dl_resolve = 0UL; ++} ++ ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++ unsigned int *kaddr; ++ ++ vmf->page = alloc_page(GFP_HIGHUSER); ++ if (!vmf->page) ++ return VM_FAULT_OOM; ++ ++ kaddr = kmap(vmf->page); ++ memset(kaddr, 0, PAGE_SIZE); ++ kaddr[0] = 0x9DE3BFA8U; /* save */ ++ flush_dcache_page(vmf->page); ++ kunmap(vmf->page); ++ return VM_FAULT_MAJOR; ++} ++ ++static const struct vm_operations_struct pax_vm_ops = { ++ .close = pax_emuplt_close, ++ .fault = pax_emuplt_fault ++}; ++ ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) ++{ ++ int ret; ++ ++ vma->vm_mm = current->mm; ++ vma->vm_start = addr; ++ vma->vm_end = addr + PAGE_SIZE; ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); ++ vma->vm_ops = &pax_vm_ops; ++ ++ ret = insert_vm_struct(current->mm, vma); ++ if (ret) ++ return ret; ++ ++ ++current->mm->total_vm; ++ return 0; ++} ++#endif ++ ++/* ++ * PaX: decide what to do with offenders (regs->pc = fault address) ++ * ++ * returns 1 when task should be killed ++ * 2 when patched PLT trampoline was detected ++ * 3 when unpatched PLT trampoline was detected ++ */ ++static int pax_handle_fetch_fault(struct pt_regs *regs) ++{ ++ ++#ifdef CONFIG_PAX_EMUPLT ++ int err; ++ ++ do { /* PaX: patched PLT emulation #1 */ ++ unsigned int sethi1, sethi2, jmpl; ++ ++ err = get_user(sethi1, (unsigned int *)regs->pc); ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4)); ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8)); ++ ++ if (err) ++ break; ++ ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && ++ (sethi2 & 0xFFC00000U) == 0x03000000U && ++ (jmpl & 0xFFFFE000U) == 0x81C06000U) ++ { ++ unsigned int addr; ++ ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; ++ addr = regs->u_regs[UREG_G1]; ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); ++ regs->pc = addr; ++ regs->npc = addr+4; ++ return 2; ++ } ++ } while (0); ++ ++ { /* PaX: patched PLT emulation #2 */ ++ unsigned int ba; ++ ++ err = get_user(ba, (unsigned int *)regs->pc); ++ ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) { ++ unsigned int addr; ++ ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2); ++ regs->pc = addr; ++ regs->npc = addr+4; ++ return 2; ++ } ++ } ++ ++ do { /* PaX: patched PLT emulation #3 */ ++ unsigned int sethi, jmpl, nop; ++ ++ err = get_user(sethi, (unsigned int *)regs->pc); ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4)); ++ err |= get_user(nop, (unsigned int *)(regs->pc+8)); ++ ++ if (err) ++ break; ++ ++ if ((sethi & 0xFFC00000U) == 0x03000000U && ++ (jmpl & 0xFFFFE000U) == 0x81C06000U && ++ nop == 0x01000000U) ++ { ++ unsigned int addr; ++ ++ addr = (sethi & 0x003FFFFFU) << 10; ++ regs->u_regs[UREG_G1] = addr; ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); ++ regs->pc = addr; ++ regs->npc = addr+4; ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: unpatched PLT emulation step 1 */ ++ unsigned int sethi, ba, nop; ++ ++ err = get_user(sethi, (unsigned int *)regs->pc); ++ err |= get_user(ba, (unsigned int *)(regs->pc+4)); ++ err |= get_user(nop, (unsigned int *)(regs->pc+8)); ++ ++ if (err) ++ break; ++ ++ if ((sethi & 0xFFC00000U) == 0x03000000U && ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) && ++ nop == 0x01000000U) ++ { ++ unsigned int addr, save, call; ++ ++ if ((ba & 0xFFC00000U) == 0x30800000U) ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2); ++ else ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2); ++ ++ err = get_user(save, (unsigned int *)addr); ++ err |= get_user(call, (unsigned int *)(addr+4)); ++ err |= get_user(nop, (unsigned int *)(addr+8)); ++ if (err) ++ break; ++ ++#ifdef CONFIG_PAX_DLRESOLVE ++ if (save == 0x9DE3BFA8U && ++ (call & 0xC0000000U) == 0x40000000U && ++ nop == 0x01000000U) ++ { ++ struct vm_area_struct *vma; ++ unsigned long call_dl_resolve; ++ ++ down_read(¤t->mm->mmap_sem); ++ call_dl_resolve = current->mm->call_dl_resolve; ++ up_read(¤t->mm->mmap_sem); ++ if (likely(call_dl_resolve)) ++ goto emulate; ++ ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); ++ ++ down_write(¤t->mm->mmap_sem); ++ if (current->mm->call_dl_resolve) { ++ call_dl_resolve = current->mm->call_dl_resolve; ++ up_write(¤t->mm->mmap_sem); ++ if (vma) ++ kmem_cache_free(vm_area_cachep, vma); ++ goto emulate; ++ } ++ ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) { ++ up_write(¤t->mm->mmap_sem); ++ if (vma) ++ kmem_cache_free(vm_area_cachep, vma); ++ return 1; ++ } ++ ++ if (pax_insert_vma(vma, call_dl_resolve)) { ++ up_write(¤t->mm->mmap_sem); ++ kmem_cache_free(vm_area_cachep, vma); ++ return 1; ++ } ++ ++ current->mm->call_dl_resolve = call_dl_resolve; ++ up_write(¤t->mm->mmap_sem); ++ ++emulate: ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; ++ regs->pc = call_dl_resolve; ++ regs->npc = addr+4; ++ return 3; ++ } ++#endif ++ ++ /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */ ++ if ((save & 0xFFC00000U) == 0x05000000U && ++ (call & 0xFFFFE000U) == 0x85C0A000U && ++ nop == 0x01000000U) ++ { ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; ++ regs->u_regs[UREG_G2] = addr + 4; ++ addr = (save & 0x003FFFFFU) << 10; ++ addr += (((call | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); ++ regs->pc = addr; ++ regs->npc = addr+4; ++ return 3; ++ } ++ } ++ } while (0); ++ ++ do { /* PaX: unpatched PLT emulation step 2 */ ++ unsigned int save, call, nop; ++ ++ err = get_user(save, (unsigned int *)(regs->pc-4)); ++ err |= get_user(call, (unsigned int *)regs->pc); ++ err |= get_user(nop, (unsigned int *)(regs->pc+4)); ++ if (err) ++ break; ++ ++ if (save == 0x9DE3BFA8U && ++ (call & 0xC0000000U) == 0x40000000U && ++ nop == 0x01000000U) ++ { ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2); ++ ++ regs->u_regs[UREG_RETPC] = regs->pc; ++ regs->pc = dl_resolve; ++ regs->npc = dl_resolve+4; ++ return 3; ++ } ++ } while (0); ++#endif ++ ++ return 1; ++} ++ ++void pax_report_insns(void *pc, void *sp) ++{ ++ unsigned long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 5; i++) { ++ unsigned int c; ++ if (get_user(c, (unsigned int *)pc+i)) ++ printk(KERN_CONT "???????? "); ++ else ++ printk(KERN_CONT "%08x ", c); ++ } ++ printk("\n"); ++} ++#endif ++ + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, + unsigned long address) + { +@@ -231,6 +495,24 @@ good_area: + if(!(vma->vm_flags & VM_WRITE)) + goto bad_area; + } else { ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) { ++ up_read(&mm->mmap_sem); ++ switch (pax_handle_fetch_fault(regs)) { ++ ++#ifdef CONFIG_PAX_EMUPLT ++ case 2: ++ case 3: ++ return; ++#endif ++ ++ } ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]); ++ do_group_exit(SIGKILL); ++ } ++#endif ++ + /* Allow reads even for write-only mappings */ + if(!(vma->vm_flags & (VM_READ | VM_EXEC))) + goto bad_area; +diff -urNp linux-2.6.31.1/arch/sparc/mm/fault_64.c linux-2.6.31.1/arch/sparc/mm/fault_64.c +--- linux-2.6.31.1/arch/sparc/mm/fault_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/mm/fault_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -20,6 +20,9 @@ + #include <linux/kprobes.h> + #include <linux/kdebug.h> + #include <linux/percpu.h> ++#include <linux/slab.h> ++#include <linux/pagemap.h> ++#include <linux/compiler.h> + + #include <asm/page.h> + #include <asm/pgtable.h> +@@ -249,6 +252,416 @@ static void noinline bogus_32bit_fault_a + show_regs(regs); + } + ++#ifdef CONFIG_PAX_PAGEEXEC ++#ifdef CONFIG_PAX_DLRESOLVE ++static void pax_emuplt_close(struct vm_area_struct *vma) ++{ ++ vma->vm_mm->call_dl_resolve = 0UL; ++} ++ ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++ unsigned int *kaddr; ++ ++ vmf->page = alloc_page(GFP_HIGHUSER); ++ if (!vmf->page) ++ return VM_FAULT_OOM; ++ ++ kaddr = kmap(vmf->page); ++ memset(kaddr, 0, PAGE_SIZE); ++ kaddr[0] = 0x9DE3BFA8U; /* save */ ++ flush_dcache_page(vmf->page); ++ kunmap(vmf->page); ++ return VM_FAULT_MAJOR; ++} ++ ++static const struct vm_operations_struct pax_vm_ops = { ++ .close = pax_emuplt_close, ++ .fault = pax_emuplt_fault ++}; ++ ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) ++{ ++ int ret; ++ ++ vma->vm_mm = current->mm; ++ vma->vm_start = addr; ++ vma->vm_end = addr + PAGE_SIZE; ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); ++ vma->vm_ops = &pax_vm_ops; ++ ++ ret = insert_vm_struct(current->mm, vma); ++ if (ret) ++ return ret; ++ ++ ++current->mm->total_vm; ++ return 0; ++} ++#endif ++ ++/* ++ * PaX: decide what to do with offenders (regs->tpc = fault address) ++ * ++ * returns 1 when task should be killed ++ * 2 when patched PLT trampoline was detected ++ * 3 when unpatched PLT trampoline was detected ++ */ ++static int pax_handle_fetch_fault(struct pt_regs *regs) ++{ ++ ++#ifdef CONFIG_PAX_EMUPLT ++ int err; ++ ++ do { /* PaX: patched PLT emulation #1 */ ++ unsigned int sethi1, sethi2, jmpl; ++ ++ err = get_user(sethi1, (unsigned int *)regs->tpc); ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4)); ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8)); ++ ++ if (err) ++ break; ++ ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && ++ (sethi2 & 0xFFC00000U) == 0x03000000U && ++ (jmpl & 0xFFFFE000U) == 0x81C06000U) ++ { ++ unsigned long addr; ++ ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; ++ addr = regs->u_regs[UREG_G1]; ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); ++ ++ if (test_thread_flag(TIF_32BIT)) ++ addr &= 0xFFFFFFFFUL; ++ ++ regs->tpc = addr; ++ regs->tnpc = addr+4; ++ return 2; ++ } ++ } while (0); ++ ++ { /* PaX: patched PLT emulation #2 */ ++ unsigned int ba; ++ ++ err = get_user(ba, (unsigned int *)regs->tpc); ++ ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) { ++ unsigned long addr; ++ ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2); ++ ++ if (test_thread_flag(TIF_32BIT)) ++ addr &= 0xFFFFFFFFUL; ++ ++ regs->tpc = addr; ++ regs->tnpc = addr+4; ++ return 2; ++ } ++ } ++ ++ do { /* PaX: patched PLT emulation #3 */ ++ unsigned int sethi, jmpl, nop; ++ ++ err = get_user(sethi, (unsigned int *)regs->tpc); ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4)); ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8)); ++ ++ if (err) ++ break; ++ ++ if ((sethi & 0xFFC00000U) == 0x03000000U && ++ (jmpl & 0xFFFFE000U) == 0x81C06000U && ++ nop == 0x01000000U) ++ { ++ unsigned long addr; ++ ++ addr = (sethi & 0x003FFFFFU) << 10; ++ regs->u_regs[UREG_G1] = addr; ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); ++ ++ if (test_thread_flag(TIF_32BIT)) ++ addr &= 0xFFFFFFFFUL; ++ ++ regs->tpc = addr; ++ regs->tnpc = addr+4; ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: patched PLT emulation #4 */ ++ unsigned int mov1, call, mov2; ++ ++ err = get_user(mov1, (unsigned int *)regs->tpc); ++ err |= get_user(call, (unsigned int *)(regs->tpc+4)); ++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8)); ++ ++ if (err) ++ break; ++ ++ if (mov1 == 0x8210000FU && ++ (call & 0xC0000000U) == 0x40000000U && ++ mov2 == 0x9E100001U) ++ { ++ unsigned long addr; ++ ++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC]; ++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2); ++ ++ if (test_thread_flag(TIF_32BIT)) ++ addr &= 0xFFFFFFFFUL; ++ ++ regs->tpc = addr; ++ regs->tnpc = addr+4; ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: patched PLT emulation #5 */ ++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop; ++ ++ err = get_user(sethi1, (unsigned int *)regs->tpc); ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4)); ++ err |= get_user(or1, (unsigned int *)(regs->tpc+8)); ++ err |= get_user(or2, (unsigned int *)(regs->tpc+12)); ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16)); ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20)); ++ err |= get_user(nop, (unsigned int *)(regs->tpc+24)); ++ ++ if (err) ++ break; ++ ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && ++ (sethi2 & 0xFFC00000U) == 0x0B000000U && ++ (or1 & 0xFFFFE000U) == 0x82106000U && ++ (or2 & 0xFFFFE000U) == 0x8A116000U && ++ sllx == 0x83287020 && ++ jmpl == 0x81C04005U && ++ nop == 0x01000000U) ++ { ++ unsigned long addr; ++ ++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU); ++ regs->u_regs[UREG_G1] <<= 32; ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU); ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5]; ++ regs->tpc = addr; ++ regs->tnpc = addr+4; ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: patched PLT emulation #6 */ ++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop; ++ ++ err = get_user(sethi1, (unsigned int *)regs->tpc); ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4)); ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8)); ++ err |= get_user(or, (unsigned int *)(regs->tpc+12)); ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16)); ++ err |= get_user(nop, (unsigned int *)(regs->tpc+20)); ++ ++ if (err) ++ break; ++ ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && ++ (sethi2 & 0xFFC00000U) == 0x0B000000U && ++ sllx == 0x83287020 && ++ (or & 0xFFFFE000U) == 0x8A116000U && ++ jmpl == 0x81C04005U && ++ nop == 0x01000000U) ++ { ++ unsigned long addr; ++ ++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10; ++ regs->u_regs[UREG_G1] <<= 32; ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU); ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5]; ++ regs->tpc = addr; ++ regs->tnpc = addr+4; ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: unpatched PLT emulation step 1 */ ++ unsigned int sethi, ba, nop; ++ ++ err = get_user(sethi, (unsigned int *)regs->tpc); ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4)); ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8)); ++ ++ if (err) ++ break; ++ ++ if ((sethi & 0xFFC00000U) == 0x03000000U && ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) && ++ nop == 0x01000000U) ++ { ++ unsigned long addr; ++ unsigned int save, call; ++ ++ if ((ba & 0xFFC00000U) == 0x30800000U) ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2); ++ else ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2); ++ ++ if (test_thread_flag(TIF_32BIT)) ++ addr &= 0xFFFFFFFFUL; ++ ++ err = get_user(save, (unsigned int *)addr); ++ err |= get_user(call, (unsigned int *)(addr+4)); ++ err |= get_user(nop, (unsigned int *)(addr+8)); ++ if (err) ++ break; ++ ++#ifdef CONFIG_PAX_DLRESOLVE ++ if (save == 0x9DE3BFA8U && ++ (call & 0xC0000000U) == 0x40000000U && ++ nop == 0x01000000U) ++ { ++ struct vm_area_struct *vma; ++ unsigned long call_dl_resolve; ++ ++ down_read(¤t->mm->mmap_sem); ++ call_dl_resolve = current->mm->call_dl_resolve; ++ up_read(¤t->mm->mmap_sem); ++ if (likely(call_dl_resolve)) ++ goto emulate; ++ ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); ++ ++ down_write(¤t->mm->mmap_sem); ++ if (current->mm->call_dl_resolve) { ++ call_dl_resolve = current->mm->call_dl_resolve; ++ up_write(¤t->mm->mmap_sem); ++ if (vma) ++ kmem_cache_free(vm_area_cachep, vma); ++ goto emulate; ++ } ++ ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) { ++ up_write(¤t->mm->mmap_sem); ++ if (vma) ++ kmem_cache_free(vm_area_cachep, vma); ++ return 1; ++ } ++ ++ if (pax_insert_vma(vma, call_dl_resolve)) { ++ up_write(¤t->mm->mmap_sem); ++ kmem_cache_free(vm_area_cachep, vma); ++ return 1; ++ } ++ ++ current->mm->call_dl_resolve = call_dl_resolve; ++ up_write(¤t->mm->mmap_sem); ++ ++emulate: ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; ++ regs->tpc = call_dl_resolve; ++ regs->tnpc = addr+4; ++ return 3; ++ } ++#endif ++ ++ /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */ ++ if ((save & 0xFFC00000U) == 0x05000000U && ++ (call & 0xFFFFE000U) == 0x85C0A000U && ++ nop == 0x01000000U) ++ { ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; ++ regs->u_regs[UREG_G2] = addr + 4; ++ addr = (save & 0x003FFFFFU) << 10; ++ addr += (((call | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); ++ ++ if (test_thread_flag(TIF_32BIT)) ++ addr &= 0xFFFFFFFFUL; ++ ++ regs->tpc = addr; ++ regs->tnpc = addr+4; ++ return 3; ++ } ++ } ++ } while (0); ++ ++#ifdef CONFIG_PAX_DLRESOLVE ++ do { /* PaX: unpatched PLT emulation step 2 */ ++ unsigned int save, call, nop; ++ ++ err = get_user(save, (unsigned int *)(regs->tpc-4)); ++ err |= get_user(call, (unsigned int *)regs->tpc); ++ err |= get_user(nop, (unsigned int *)(regs->tpc+4)); ++ if (err) ++ break; ++ ++ if (save == 0x9DE3BFA8U && ++ (call & 0xC0000000U) == 0x40000000U && ++ nop == 0x01000000U) ++ { ++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2); ++ ++ if (test_thread_flag(TIF_32BIT)) ++ dl_resolve &= 0xFFFFFFFFUL; ++ ++ regs->u_regs[UREG_RETPC] = regs->tpc; ++ regs->tpc = dl_resolve; ++ regs->tnpc = dl_resolve+4; ++ return 3; ++ } ++ } while (0); ++#endif ++ ++ do { /* PaX: patched PLT emulation #7, must be AFTER the unpatched PLT emulation */ ++ unsigned int sethi, ba, nop; ++ ++ err = get_user(sethi, (unsigned int *)regs->tpc); ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4)); ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8)); ++ ++ if (err) ++ break; ++ ++ if ((sethi & 0xFFC00000U) == 0x03000000U && ++ (ba & 0xFFF00000U) == 0x30600000U && ++ nop == 0x01000000U) ++ { ++ unsigned long addr; ++ ++ addr = (sethi & 0x003FFFFFU) << 10; ++ regs->u_regs[UREG_G1] = addr; ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2); ++ ++ if (test_thread_flag(TIF_32BIT)) ++ addr &= 0xFFFFFFFFUL; ++ ++ regs->tpc = addr; ++ regs->tnpc = addr+4; ++ return 2; ++ } ++ } while (0); ++ ++#endif ++ ++ return 1; ++} ++ ++void pax_report_insns(void *pc, void *sp) ++{ ++ unsigned long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 5; i++) { ++ unsigned int c; ++ if (get_user(c, (unsigned int *)pc+i)) ++ printk(KERN_CONT "???????? "); ++ else ++ printk(KERN_CONT "%08x ", c); ++ } ++ printk("\n"); ++} ++#endif ++ + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) + { + struct mm_struct *mm = current->mm; +@@ -315,6 +728,29 @@ asmlinkage void __kprobes do_sparc64_fau + if (!vma) + goto bad_area; + ++#ifdef CONFIG_PAX_PAGEEXEC ++ /* PaX: detect ITLB misses on non-exec pages */ ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address && ++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB)) ++ { ++ if (address != regs->tpc) ++ goto good_area; ++ ++ up_read(&mm->mmap_sem); ++ switch (pax_handle_fetch_fault(regs)) { ++ ++#ifdef CONFIG_PAX_EMUPLT ++ case 2: ++ case 3: ++ return; ++#endif ++ ++ } ++ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS)); ++ do_group_exit(SIGKILL); ++ } ++#endif ++ + /* Pure DTLB misses do not tell us whether the fault causing + * load/store/atomic was a write or not, it only says that there + * was no match. So in such a case we (carefully) read the +diff -urNp linux-2.6.31.1/arch/sparc/mm/init_32.c linux-2.6.31.1/arch/sparc/mm/init_32.c +--- linux-2.6.31.1/arch/sparc/mm/init_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/mm/init_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -316,6 +316,9 @@ extern void device_scan(void); + pgprot_t PAGE_SHARED __read_mostly; + EXPORT_SYMBOL(PAGE_SHARED); + ++pgprot_t PAGE_SHARED_NOEXEC __read_mostly; ++EXPORT_SYMBOL(PAGE_SHARED_NOEXEC); ++ + void __init paging_init(void) + { + switch(sparc_cpu_model) { +@@ -341,17 +344,17 @@ void __init paging_init(void) + + /* Initialize the protection map with non-constant, MMU dependent values. */ + protection_map[0] = PAGE_NONE; +- protection_map[1] = PAGE_READONLY; +- protection_map[2] = PAGE_COPY; +- protection_map[3] = PAGE_COPY; ++ protection_map[1] = PAGE_READONLY_NOEXEC; ++ protection_map[2] = PAGE_COPY_NOEXEC; ++ protection_map[3] = PAGE_COPY_NOEXEC; + protection_map[4] = PAGE_READONLY; + protection_map[5] = PAGE_READONLY; + protection_map[6] = PAGE_COPY; + protection_map[7] = PAGE_COPY; + protection_map[8] = PAGE_NONE; +- protection_map[9] = PAGE_READONLY; +- protection_map[10] = PAGE_SHARED; +- protection_map[11] = PAGE_SHARED; ++ protection_map[9] = PAGE_READONLY_NOEXEC; ++ protection_map[10] = PAGE_SHARED_NOEXEC; ++ protection_map[11] = PAGE_SHARED_NOEXEC; + protection_map[12] = PAGE_READONLY; + protection_map[13] = PAGE_READONLY; + protection_map[14] = PAGE_SHARED; +diff -urNp linux-2.6.31.1/arch/sparc/mm/Makefile linux-2.6.31.1/arch/sparc/mm/Makefile +--- linux-2.6.31.1/arch/sparc/mm/Makefile 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/mm/Makefile 2009-10-01 20:12:42.000000000 -0400 +@@ -2,7 +2,7 @@ + # + + asflags-y := -ansi +-ccflags-y := -Werror ++#ccflags-y := -Werror + + obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o + obj-y += fault_$(BITS).o +diff -urNp linux-2.6.31.1/arch/sparc/mm/srmmu.c linux-2.6.31.1/arch/sparc/mm/srmmu.c +--- linux-2.6.31.1/arch/sparc/mm/srmmu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/sparc/mm/srmmu.c 2009-10-01 20:12:42.000000000 -0400 +@@ -2149,6 +2149,13 @@ void __init ld_mmu_srmmu(void) + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED); + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC); ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC)); ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC)); ++#endif ++ + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); + +diff -urNp linux-2.6.31.1/arch/um/include/asm/kmap_types.h linux-2.6.31.1/arch/um/include/asm/kmap_types.h +--- linux-2.6.31.1/arch/um/include/asm/kmap_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/um/include/asm/kmap_types.h 2009-10-01 20:12:42.000000000 -0400 +@@ -23,6 +23,7 @@ enum km_type { + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, ++ KM_CLEARPAGE, + KM_TYPE_NR + }; + +diff -urNp linux-2.6.31.1/arch/um/include/asm/page.h linux-2.6.31.1/arch/um/include/asm/page.h +--- linux-2.6.31.1/arch/um/include/asm/page.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/um/include/asm/page.h 2009-10-01 20:12:42.000000000 -0400 +@@ -14,6 +14,9 @@ + #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) + #define PAGE_MASK (~(PAGE_SIZE-1)) + ++#define ktla_ktva(addr) (addr) ++#define ktva_ktla(addr) (addr) ++ + #ifndef __ASSEMBLY__ + + struct page; +diff -urNp linux-2.6.31.1/arch/um/sys-i386/syscalls.c linux-2.6.31.1/arch/um/sys-i386/syscalls.c +--- linux-2.6.31.1/arch/um/sys-i386/syscalls.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/um/sys-i386/syscalls.c 2009-10-01 20:12:42.000000000 -0400 +@@ -11,6 +11,21 @@ + #include "asm/uaccess.h" + #include "asm/unistd.h" + ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) ++{ ++ unsigned long pax_task_size = TASK_SIZE; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++#endif ++ ++ if (len > pax_task_size || addr > pax_task_size - len) ++ return -EINVAL; ++ ++ return 0; ++} ++ + /* + * Perform the select(nd, in, out, ex, tv) and mmap() system + * calls. Linux/i386 didn't use to be able to handle more than +diff -urNp linux-2.6.31.1/arch/x86/boot/bitops.h linux-2.6.31.1/arch/x86/boot/bitops.h +--- linux-2.6.31.1/arch/x86/boot/bitops.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/bitops.h 2009-10-01 20:12:42.000000000 -0400 +@@ -26,7 +26,7 @@ static inline int variable_test_bit(int + u8 v; + const u32 *p = (const u32 *)addr; + +- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr)); ++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr)); + return v; + } + +@@ -37,7 +37,7 @@ static inline int variable_test_bit(int + + static inline void set_bit(int nr, void *addr) + { +- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr)); ++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr)); + } + + #endif /* BOOT_BITOPS_H */ +diff -urNp linux-2.6.31.1/arch/x86/boot/boot.h linux-2.6.31.1/arch/x86/boot/boot.h +--- linux-2.6.31.1/arch/x86/boot/boot.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/boot.h 2009-10-01 20:12:42.000000000 -0400 +@@ -82,7 +82,7 @@ static inline void io_delay(void) + static inline u16 ds(void) + { + u16 seg; +- asm("movw %%ds,%0" : "=rm" (seg)); ++ asm volatile("movw %%ds,%0" : "=rm" (seg)); + return seg; + } + +@@ -178,7 +178,7 @@ static inline void wrgs32(u32 v, addr_t + static inline int memcmp(const void *s1, const void *s2, size_t len) + { + u8 diff; +- asm("repe; cmpsb; setnz %0" ++ asm volatile("repe; cmpsb; setnz %0" + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); + return diff; + } +diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/head_32.S linux-2.6.31.1/arch/x86/boot/compressed/head_32.S +--- linux-2.6.31.1/arch/x86/boot/compressed/head_32.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/compressed/head_32.S 2009-10-01 20:12:42.000000000 -0400 +@@ -75,7 +75,7 @@ ENTRY(startup_32) + notl %eax + andl %eax, %ebx + #else +- movl $LOAD_PHYSICAL_ADDR, %ebx ++ movl $____LOAD_PHYSICAL_ADDR, %ebx + #endif + + /* Target address to relocate to for decompression */ +@@ -148,7 +148,7 @@ relocated: + * and where it was actually loaded. + */ + movl %ebp, %ebx +- subl $LOAD_PHYSICAL_ADDR, %ebx ++ subl $____LOAD_PHYSICAL_ADDR, %ebx + jz 2f /* Nothing to be done if loaded at compiled addr. */ + /* + * Process relocations. +@@ -156,8 +156,7 @@ relocated: + + 1: subl $4, %edi + movl (%edi), %ecx +- testl %ecx, %ecx +- jz 2f ++ jecxz 2f + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) + jmp 1b + 2: +diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/head_64.S linux-2.6.31.1/arch/x86/boot/compressed/head_64.S +--- linux-2.6.31.1/arch/x86/boot/compressed/head_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/compressed/head_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -90,7 +90,7 @@ ENTRY(startup_32) + notl %eax + andl %eax, %ebx + #else +- movl $LOAD_PHYSICAL_ADDR, %ebx ++ movl $____LOAD_PHYSICAL_ADDR, %ebx + #endif + + /* Target address to relocate to for decompression */ +@@ -233,7 +233,7 @@ ENTRY(startup_64) + notq %rax + andq %rax, %rbp + #else +- movq $LOAD_PHYSICAL_ADDR, %rbp ++ movq $____LOAD_PHYSICAL_ADDR, %rbp + #endif + + /* Target address to relocate to for decompression */ +diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/misc.c linux-2.6.31.1/arch/x86/boot/compressed/misc.c +--- linux-2.6.31.1/arch/x86/boot/compressed/misc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/compressed/misc.c 2009-10-01 20:12:42.000000000 -0400 +@@ -288,7 +288,7 @@ static void parse_elf(void *output) + case PT_LOAD: + #ifdef CONFIG_RELOCATABLE + dest = output; +- dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR); ++ dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR); + #else + dest = (void *)(phdr->p_paddr); + #endif +@@ -335,7 +335,7 @@ asmlinkage void decompress_kernel(void * + error("Destination address too large"); + #endif + #ifndef CONFIG_RELOCATABLE +- if ((unsigned long)output != LOAD_PHYSICAL_ADDR) ++ if ((unsigned long)output != ____LOAD_PHYSICAL_ADDR) + error("Wrong destination address"); + #endif + +diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/mkpiggy.c linux-2.6.31.1/arch/x86/boot/compressed/mkpiggy.c +--- linux-2.6.31.1/arch/x86/boot/compressed/mkpiggy.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/compressed/mkpiggy.c 2009-10-01 20:12:42.000000000 -0400 +@@ -74,7 +74,7 @@ int main(int argc, char *argv[]) + + offs = (olen > ilen) ? olen - ilen : 0; + offs += olen >> 12; /* Add 8 bytes for each 32K block */ +- offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */ ++ offs += 64*1024; /* Add 64K bytes slack */ + offs = (offs+4095) & ~4095; /* Round to a 4K boundary */ + + printf(".section ".rodata.compressed","a",@progbits\n"); +diff -urNp linux-2.6.31.1/arch/x86/boot/compressed/relocs.c linux-2.6.31.1/arch/x86/boot/compressed/relocs.c +--- linux-2.6.31.1/arch/x86/boot/compressed/relocs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/compressed/relocs.c 2009-10-01 20:12:42.000000000 -0400 +@@ -10,8 +10,11 @@ + #define USE_BSD + #include <endian.h> + ++#include "../../../../include/linux/autoconf.h" ++ + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + static Elf32_Ehdr ehdr; ++static Elf32_Phdr *phdr; + static unsigned long reloc_count, reloc_idx; + static unsigned long *relocs; + +@@ -37,7 +40,7 @@ static const char* safe_abs_relocs[] = { + + static int is_safe_abs_reloc(const char* sym_name) + { +- int i; ++ unsigned int i; + + for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { + if (!strcmp(sym_name, safe_abs_relocs[i])) +@@ -245,9 +248,39 @@ static void read_ehdr(FILE *fp) + } + } + ++static void read_phdrs(FILE *fp) ++{ ++ unsigned int i; ++ ++ phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr)); ++ if (!phdr) { ++ die("Unable to allocate %d program headers\n", ++ ehdr.e_phnum); ++ } ++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) { ++ die("Seek to %d failed: %s\n", ++ ehdr.e_phoff, strerror(errno)); ++ } ++ if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) { ++ die("Cannot read ELF program headers: %s\n", ++ strerror(errno)); ++ } ++ for(i = 0; i < ehdr.e_phnum; i++) { ++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type); ++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset); ++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr); ++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr); ++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz); ++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz); ++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags); ++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align); ++ } ++ ++} ++ + static void read_shdrs(FILE *fp) + { +- int i; ++ unsigned int i; + Elf32_Shdr shdr; + + secs = calloc(ehdr.e_shnum, sizeof(struct section)); +@@ -282,7 +315,7 @@ static void read_shdrs(FILE *fp) + + static void read_strtabs(FILE *fp) + { +- int i; ++ unsigned int i; + for (i = 0; i < ehdr.e_shnum; i++) { + struct section *sec = &secs[i]; + if (sec->shdr.sh_type != SHT_STRTAB) { +@@ -307,7 +340,7 @@ static void read_strtabs(FILE *fp) + + static void read_symtabs(FILE *fp) + { +- int i,j; ++ unsigned int i,j; + for (i = 0; i < ehdr.e_shnum; i++) { + struct section *sec = &secs[i]; + if (sec->shdr.sh_type != SHT_SYMTAB) { +@@ -340,7 +373,9 @@ static void read_symtabs(FILE *fp) + + static void read_relocs(FILE *fp) + { +- int i,j; ++ unsigned int i,j; ++ uint32_t base; ++ + for (i = 0; i < ehdr.e_shnum; i++) { + struct section *sec = &secs[i]; + if (sec->shdr.sh_type != SHT_REL) { +@@ -360,9 +395,18 @@ static void read_relocs(FILE *fp) + die("Cannot read symbol table: %s\n", + strerror(errno)); + } ++ base = 0; ++ for (j = 0; j < ehdr.e_phnum; j++) { ++ if (phdr[j].p_type != PT_LOAD ) ++ continue; ++ if (secs[sec->shdr.sh_info].shdr.sh_offset < phdr[j].p_offset || secs[sec->shdr.sh_info].shdr.sh_offset >= phdr[j].p_offset + phdr[j].p_filesz) ++ continue; ++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr; ++ break; ++ } + for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { + Elf32_Rel *rel = &sec->reltab[j]; +- rel->r_offset = elf32_to_cpu(rel->r_offset); ++ rel->r_offset = elf32_to_cpu(rel->r_offset) + base; + rel->r_info = elf32_to_cpu(rel->r_info); + } + } +@@ -371,14 +415,14 @@ static void read_relocs(FILE *fp) + + static void print_absolute_symbols(void) + { +- int i; ++ unsigned int i; + printf("Absolute symbols\n"); + printf(" Num: Value Size Type Bind Visibility Name\n"); + for (i = 0; i < ehdr.e_shnum; i++) { + struct section *sec = &secs[i]; + char *sym_strtab; + Elf32_Sym *sh_symtab; +- int j; ++ unsigned int j; + + if (sec->shdr.sh_type != SHT_SYMTAB) { + continue; +@@ -406,14 +450,14 @@ static void print_absolute_symbols(void) + + static void print_absolute_relocs(void) + { +- int i, printed = 0; ++ unsigned int i, printed = 0; + + for (i = 0; i < ehdr.e_shnum; i++) { + struct section *sec = &secs[i]; + struct section *sec_applies, *sec_symtab; + char *sym_strtab; + Elf32_Sym *sh_symtab; +- int j; ++ unsigned int j; + if (sec->shdr.sh_type != SHT_REL) { + continue; + } +@@ -474,13 +518,13 @@ static void print_absolute_relocs(void) + + static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) + { +- int i; ++ unsigned int i; + /* Walk through the relocations */ + for (i = 0; i < ehdr.e_shnum; i++) { + char *sym_strtab; + Elf32_Sym *sh_symtab; + struct section *sec_applies, *sec_symtab; +- int j; ++ unsigned int j; + struct section *sec = &secs[i]; + + if (sec->shdr.sh_type != SHT_REL) { +@@ -504,6 +548,19 @@ static void walk_relocs(void (*visit)(El + if (sym->st_shndx == SHN_ABS) { + continue; + } ++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */ ++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strcmp(sym_name(sym_strtab, sym), "__per_cpu_load")) ++ continue; ++ ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32) ++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */ ++ if (!strcmp(sec_name(sym->st_shndx), ".init.text")) ++ continue; ++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text")) ++ continue; ++ if (!strcmp(sec_name(sym->st_shndx), ".text") && strcmp(sym_name(sym_strtab, sym), "__LOAD_PHYSICAL_ADDR")) ++ continue; ++#endif + if (r_type == R_386_NONE || r_type == R_386_PC32) { + /* + * NONE can be ignored and and PC relative +@@ -541,7 +598,7 @@ static int cmp_relocs(const void *va, co + + static void emit_relocs(int as_text) + { +- int i; ++ unsigned int i; + /* Count how many relocations I have and allocate space for them. */ + reloc_count = 0; + walk_relocs(count_reloc); +@@ -634,6 +691,7 @@ int main(int argc, char **argv) + fname, strerror(errno)); + } + read_ehdr(fp); ++ read_phdrs(fp); + read_shdrs(fp); + read_strtabs(fp); + read_symtabs(fp); +diff -urNp linux-2.6.31.1/arch/x86/boot/cpucheck.c linux-2.6.31.1/arch/x86/boot/cpucheck.c +--- linux-2.6.31.1/arch/x86/boot/cpucheck.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/cpucheck.c 2009-10-01 20:12:42.000000000 -0400 +@@ -74,7 +74,7 @@ static int has_fpu(void) + u16 fcw = -1, fsw = -1; + u32 cr0; + +- asm("movl %%cr0,%0" : "=r" (cr0)); ++ asm volatile("movl %%cr0,%0" : "=r" (cr0)); + if (cr0 & (X86_CR0_EM|X86_CR0_TS)) { + cr0 &= ~(X86_CR0_EM|X86_CR0_TS); + asm volatile("movl %0,%%cr0" : : "r" (cr0)); +@@ -90,7 +90,7 @@ static int has_eflag(u32 mask) + { + u32 f0, f1; + +- asm("pushfl ; " ++ asm volatile("pushfl ; " + "pushfl ; " + "popl %0 ; " + "movl %0,%1 ; " +@@ -115,7 +115,7 @@ static void get_flags(void) + set_bit(X86_FEATURE_FPU, cpu.flags); + + if (has_eflag(X86_EFLAGS_ID)) { +- asm("cpuid" ++ asm volatile("cpuid" + : "=a" (max_intel_level), + "=b" (cpu_vendor[0]), + "=d" (cpu_vendor[1]), +@@ -124,7 +124,7 @@ static void get_flags(void) + + if (max_intel_level >= 0x00000001 && + max_intel_level <= 0x0000ffff) { +- asm("cpuid" ++ asm volatile("cpuid" + : "=a" (tfms), + "=c" (cpu.flags[4]), + "=d" (cpu.flags[0]) +@@ -136,7 +136,7 @@ static void get_flags(void) + cpu.model += ((tfms >> 16) & 0xf) << 4; + } + +- asm("cpuid" ++ asm volatile("cpuid" + : "=a" (max_amd_level) + : "a" (0x80000000) + : "ebx", "ecx", "edx"); +@@ -144,7 +144,7 @@ static void get_flags(void) + if (max_amd_level >= 0x80000001 && + max_amd_level <= 0x8000ffff) { + u32 eax = 0x80000001; +- asm("cpuid" ++ asm volatile("cpuid" + : "+a" (eax), + "=c" (cpu.flags[6]), + "=d" (cpu.flags[1]) +@@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r + u32 ecx = MSR_K7_HWCR; + u32 eax, edx; + +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); + eax &= ~(1 << 15); +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); + + get_flags(); /* Make sure it really did something */ + err = check_flags(); +@@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r + u32 ecx = MSR_VIA_FCR; + u32 eax, edx; + +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); + eax |= (1<<1)|(1<<7); +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); + + set_bit(X86_FEATURE_CX8, cpu.flags); + err = check_flags(); +@@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r + u32 eax, edx; + u32 level = 1; + +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx)); +- asm("cpuid" ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); ++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx)); ++ asm volatile("cpuid" + : "+a" (level), "=d" (cpu.flags[0]) + : : "ecx", "ebx"); +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); + + err = check_flags(); + } +diff -urNp linux-2.6.31.1/arch/x86/boot/header.S linux-2.6.31.1/arch/x86/boot/header.S +--- linux-2.6.31.1/arch/x86/boot/header.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/header.S 2009-10-01 20:12:42.000000000 -0400 +@@ -224,7 +224,7 @@ setup_data: .quad 0 # 64-bit physical + # single linked list of + # struct setup_data + +-pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr ++pref_address: .quad ____LOAD_PHYSICAL_ADDR # preferred load addr + + #define ZO_INIT_SIZE (ZO__end - ZO_startup_32 + ZO_z_extract_offset) + #define VO_INIT_SIZE (VO__end - VO__text) +diff -urNp linux-2.6.31.1/arch/x86/boot/video-vesa.c linux-2.6.31.1/arch/x86/boot/video-vesa.c +--- linux-2.6.31.1/arch/x86/boot/video-vesa.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/boot/video-vesa.c 2009-10-01 20:12:42.000000000 -0400 +@@ -205,6 +205,7 @@ static void vesa_store_pm_info(void) + + boot_params.screen_info.vesapm_seg = oreg.es; + boot_params.screen_info.vesapm_off = oreg.di; ++ boot_params.screen_info.vesapm_size = oreg.cx; + } + + /* +diff -urNp linux-2.6.31.1/arch/x86/ia32/ia32_signal.c linux-2.6.31.1/arch/x86/ia32/ia32_signal.c +--- linux-2.6.31.1/arch/x86/ia32/ia32_signal.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/ia32/ia32_signal.c 2009-10-01 20:12:42.000000000 -0400 +@@ -403,7 +403,7 @@ static void __user *get_sigframe(struct + sp -= frame_size; + /* Align the stack pointer according to the i386 ABI, + * i.e. so that on function entry ((sp + 4) & 15) == 0. */ +- sp = ((sp + 4) & -16ul) - 4; ++ sp = ((sp - 12) & -16ul) - 4; + return (void __user *) sp; + } + +@@ -503,7 +503,7 @@ int ia32_setup_rt_frame(int sig, struct + 0xb8, + __NR_ia32_rt_sigreturn, + 0x80cd, +- 0, ++ 0 + }; + + frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); +diff -urNp linux-2.6.31.1/arch/x86/include/asm/alternative.h linux-2.6.31.1/arch/x86/include/asm/alternative.h +--- linux-2.6.31.1/arch/x86/include/asm/alternative.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/alternative.h 2009-10-01 20:12:42.000000000 -0400 +@@ -87,7 +87,7 @@ const unsigned char *const *find_nop_tab + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ + ".previous\n" \ +- ".section .altinstr_replacement, "ax"\n" \ ++ ".section .altinstr_replacement, "a"\n" \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + ".previous" + +diff -urNp linux-2.6.31.1/arch/x86/include/asm/apm.h linux-2.6.31.1/arch/x86/include/asm/apm.h +--- linux-2.6.31.1/arch/x86/include/asm/apm.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/apm.h 2009-10-01 20:12:42.000000000 -0400 +@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32 + __asm__ __volatile__(APM_DO_ZERO_SEGS + "pushl %%edi\n\t" + "pushl %%ebp\n\t" +- "lcall *%%cs:apm_bios_entry\n\t" ++ "lcall *%%ss:apm_bios_entry\n\t" + "setc %%al\n\t" + "popl %%ebp\n\t" + "popl %%edi\n\t" +@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as + __asm__ __volatile__(APM_DO_ZERO_SEGS + "pushl %%edi\n\t" + "pushl %%ebp\n\t" +- "lcall *%%cs:apm_bios_entry\n\t" ++ "lcall *%%ss:apm_bios_entry\n\t" + "setc %%bl\n\t" + "popl %%ebp\n\t" + "popl %%edi\n\t" +diff -urNp linux-2.6.31.1/arch/x86/include/asm/atomic_32.h linux-2.6.31.1/arch/x86/include/asm/atomic_32.h +--- linux-2.6.31.1/arch/x86/include/asm/atomic_32.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/atomic_32.h 2009-10-01 20:12:42.000000000 -0400 +@@ -25,6 +25,17 @@ static inline int atomic_read(const atom + } + + /** ++ * atomic_read_unchecked - read atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically reads the value of @v. ++ */ ++static inline int atomic_read_unchecked(const atomic_unchecked_t *v) ++{ ++ return v->counter; ++} ++ ++/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value +@@ -37,6 +48,18 @@ static inline void atomic_set(atomic_t * + } + + /** ++ * atomic_set_unchecked - set atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * @i: required value ++ * ++ * Atomically sets the value of @v to @i. ++ */ ++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i) ++{ ++ v->counter = i; ++} ++ ++/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t +@@ -45,7 +68,29 @@ static inline void atomic_set(atomic_t * + */ + static inline void atomic_add(int i, atomic_t *v) + { +- asm volatile(LOCK_PREFIX "addl %1,%0" ++ asm volatile(LOCK_PREFIX "addl %1,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "subl %1,%0\n" ++ "into\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ : "+m" (v->counter) ++ : "ir" (i)); ++} ++ ++/** ++ * atomic_add_unchecked - add integer to atomic variable ++ * @i: integer value to add ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically adds @i to @v. ++ */ ++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v) ++{ ++ asm volatile(LOCK_PREFIX "addl %1,%0\n" + : "+m" (v->counter) + : "ir" (i)); + } +@@ -59,7 +104,29 @@ static inline void atomic_add(int i, ato + */ + static inline void atomic_sub(int i, atomic_t *v) + { +- asm volatile(LOCK_PREFIX "subl %1,%0" ++ asm volatile(LOCK_PREFIX "subl %1,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "addl %1,%0\n" ++ "into\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ : "+m" (v->counter) ++ : "ir" (i)); ++} ++ ++/** ++ * atomic_sub_unchecked - subtract integer from atomic variable ++ * @i: integer value to subtract ++ * @v: pointer of type atomic_t ++ * ++ * Atomically subtracts @i from @v. ++ */ ++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ asm volatile(LOCK_PREFIX "subl %1,%0\n" + : "+m" (v->counter) + : "ir" (i)); + } +@@ -77,7 +144,16 @@ static inline int atomic_sub_and_test(in + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1" ++ asm volatile(LOCK_PREFIX "subl %2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "addl %2,%0\n" ++ "into\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ "sete %1\n" + : "+m" (v->counter), "=qm" (c) + : "ir" (i) : "memory"); + return c; +@@ -91,7 +167,30 @@ static inline int atomic_sub_and_test(in + */ + static inline void atomic_inc(atomic_t *v) + { +- asm volatile(LOCK_PREFIX "incl %0" ++ asm volatile(LOCK_PREFIX "incl %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "into\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ LOCK_PREFIX "decl %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ : "+m" (v->counter)); ++} ++ ++/** ++ * atomic_inc_unchecked - increment atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically increments @v by 1. ++ */ ++static inline void atomic_inc_unchecked(atomic_unchecked_t *v) ++{ ++ asm volatile(LOCK_PREFIX "incl %0\n" + : "+m" (v->counter)); + } + +@@ -103,7 +202,18 @@ static inline void atomic_inc(atomic_t * + */ + static inline void atomic_dec(atomic_t *v) + { +- asm volatile(LOCK_PREFIX "decl %0" ++ asm volatile(LOCK_PREFIX "decl %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "into\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1: \n" ++ LOCK_PREFIX "incl %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "+m" (v->counter)); + } + +@@ -119,7 +229,19 @@ static inline int atomic_dec_and_test(at + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "decl %0; sete %1" ++ asm volatile(LOCK_PREFIX "decl %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "into\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1: \n" ++ LOCK_PREFIX "incl %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sete %1\n" + : "+m" (v->counter), "=qm" (c) + : : "memory"); + return c != 0; +@@ -137,7 +259,19 @@ static inline int atomic_inc_and_test(at + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "incl %0; sete %1" ++ asm volatile(LOCK_PREFIX "incl %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "into\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1: \n" ++ LOCK_PREFIX "decl %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sete %1\n" + : "+m" (v->counter), "=qm" (c) + : : "memory"); + return c != 0; +@@ -156,7 +290,16 @@ static inline int atomic_add_negative(in + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1" ++ asm volatile(LOCK_PREFIX "addl %2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "subl %2,%0\n" ++ "into\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ "sets %1\n" + : "+m" (v->counter), "=qm" (c) + : "ir" (i) : "memory"); + return c; +@@ -179,7 +322,15 @@ static inline int atomic_add_return(int + #endif + /* Modern 486+ processor */ + __i = i; +- asm volatile(LOCK_PREFIX "xaddl %0, %1" ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "movl %0, %1\n" ++ "into\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ + : "+r" (i), "+m" (v->counter) + : : "memory"); + return i + __i; +@@ -227,17 +378,28 @@ static inline int atomic_xchg(atomic_t * + */ + static inline int atomic_add_unless(atomic_t *v, int a, int u) + { +- int c, old; ++ int c, old, new; + c = atomic_read(v); + for (;;) { +- if (unlikely(c == (u))) ++ if (unlikely(c == u)) + break; +- old = atomic_cmpxchg((v), c, c + (a)); ++ ++ asm volatile("addl %2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "into\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ : "=r" (new) ++ : "0" (c), "ir" (a)); ++ ++ old = atomic_cmpxchg(v, c, new); + if (likely(old == c)) + break; + c = old; + } +- return c != (u); ++ return c != u; + } + + #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) +diff -urNp linux-2.6.31.1/arch/x86/include/asm/atomic_64.h linux-2.6.31.1/arch/x86/include/asm/atomic_64.h +--- linux-2.6.31.1/arch/x86/include/asm/atomic_64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/atomic_64.h 2009-10-01 20:12:42.000000000 -0400 +@@ -24,6 +24,17 @@ static inline int atomic_read(const atom + } + + /** ++ * atomic_read_unchecked - read atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically reads the value of @v. ++ */ ++static inline int atomic_read_unchecked(const atomic_unchecked_t *v) ++{ ++ return v->counter; ++} ++ ++/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value +@@ -36,6 +47,18 @@ static inline void atomic_set(atomic_t * + } + + /** ++ * atomic_set_unchecked - set atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * @i: required value ++ * ++ * Atomically sets the value of @v to @i. ++ */ ++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i) ++{ ++ v->counter = i; ++} ++ ++/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t +@@ -44,7 +67,29 @@ static inline void atomic_set(atomic_t * + */ + static inline void atomic_add(int i, atomic_t *v) + { +- asm volatile(LOCK_PREFIX "addl %1,%0" ++ asm volatile(LOCK_PREFIX "addl %1,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "subl %1,%0\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ : "=m" (v->counter) ++ : "ir" (i), "m" (v->counter)); ++} ++ ++/** ++ * atomic_add_unchecked - add integer to atomic variable ++ * @i: integer value to add ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically adds @i to @v. ++ */ ++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v) ++{ ++ asm volatile(LOCK_PREFIX "addl %1,%0\n" + : "=m" (v->counter) + : "ir" (i), "m" (v->counter)); + } +@@ -58,7 +103,29 @@ static inline void atomic_add(int i, ato + */ + static inline void atomic_sub(int i, atomic_t *v) + { +- asm volatile(LOCK_PREFIX "subl %1,%0" ++ asm volatile(LOCK_PREFIX "subl %1,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "addl %1,%0\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ : "=m" (v->counter) ++ : "ir" (i), "m" (v->counter)); ++} ++ ++/** ++ * atomic_sub_unchecked - subtract the atomic variable ++ * @i: integer value to subtract ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically subtracts @i from @v. ++ */ ++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ asm volatile(LOCK_PREFIX "subl %1,%0\n" + : "=m" (v->counter) + : "ir" (i), "m" (v->counter)); + } +@@ -76,7 +143,16 @@ static inline int atomic_sub_and_test(in + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1" ++ asm volatile(LOCK_PREFIX "subl %2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "addl %2,%0\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ "sete %1\n" + : "=m" (v->counter), "=qm" (c) + : "ir" (i), "m" (v->counter) : "memory"); + return c; +@@ -90,7 +166,32 @@ static inline int atomic_sub_and_test(in + */ + static inline void atomic_inc(atomic_t *v) + { +- asm volatile(LOCK_PREFIX "incl %0" ++ asm volatile(LOCK_PREFIX "incl %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ LOCK_PREFIX "decl %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ : "=m" (v->counter) ++ : "m" (v->counter)); ++} ++ ++/** ++ * atomic_inc_unchecked - increment atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically increments @v by 1. ++ */ ++static inline void atomic_inc_unchecked(atomic_unchecked_t *v) ++{ ++ asm volatile(LOCK_PREFIX "incl %0\n" + : "=m" (v->counter) + : "m" (v->counter)); + } +@@ -103,7 +204,19 @@ static inline void atomic_inc(atomic_t * + */ + static inline void atomic_dec(atomic_t *v) + { +- asm volatile(LOCK_PREFIX "decl %0" ++ asm volatile(LOCK_PREFIX "decl %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1: \n" ++ LOCK_PREFIX "incl %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "=m" (v->counter) + : "m" (v->counter)); + } +@@ -120,7 +233,20 @@ static inline int atomic_dec_and_test(at + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "decl %0; sete %1" ++ asm volatile(LOCK_PREFIX "decl %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1: \n" ++ LOCK_PREFIX "incl %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sete %1\n" + : "=m" (v->counter), "=qm" (c) + : "m" (v->counter) : "memory"); + return c != 0; +@@ -138,7 +264,20 @@ static inline int atomic_inc_and_test(at + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "incl %0; sete %1" ++ asm volatile(LOCK_PREFIX "incl %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1: \n" ++ LOCK_PREFIX "decl %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sete %1\n" + : "=m" (v->counter), "=qm" (c) + : "m" (v->counter) : "memory"); + return c != 0; +@@ -157,7 +296,16 @@ static inline int atomic_add_negative(in + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1" ++ asm volatile(LOCK_PREFIX "addl %2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "subl %2,%0\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ "sets %1\n" + : "=m" (v->counter), "=qm" (c) + : "ir" (i), "m" (v->counter) : "memory"); + return c; +@@ -173,7 +321,15 @@ static inline int atomic_add_negative(in + static inline int atomic_add_return(int i, atomic_t *v) + { + int __i = i; +- asm volatile(LOCK_PREFIX "xaddl %0, %1" ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "movl %0, %1\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ + : "+r" (i), "+m" (v->counter) + : : "memory"); + return i + __i; +@@ -224,7 +380,15 @@ static inline void atomic64_set(atomic64 + */ + static inline void atomic64_add(long i, atomic64_t *v) + { +- asm volatile(LOCK_PREFIX "addq %1,%0" ++ asm volatile(LOCK_PREFIX "addq %1,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "subq %1,%0\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ + : "=m" (v->counter) + : "er" (i), "m" (v->counter)); + } +@@ -238,7 +402,15 @@ static inline void atomic64_add(long i, + */ + static inline void atomic64_sub(long i, atomic64_t *v) + { +- asm volatile(LOCK_PREFIX "subq %1,%0" ++ asm volatile(LOCK_PREFIX "subq %1,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "addq %1,%0\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ + : "=m" (v->counter) + : "er" (i), "m" (v->counter)); + } +@@ -256,7 +428,16 @@ static inline int atomic64_sub_and_test( + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "subq %2,%0; sete %1" ++ asm volatile(LOCK_PREFIX "subq %2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "addq %2,%0\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ "sete %1\n" + : "=m" (v->counter), "=qm" (c) + : "er" (i), "m" (v->counter) : "memory"); + return c; +@@ -270,7 +451,19 @@ static inline int atomic64_sub_and_test( + */ + static inline void atomic64_inc(atomic64_t *v) + { +- asm volatile(LOCK_PREFIX "incq %0" ++ asm volatile(LOCK_PREFIX "incq %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ LOCK_PREFIX "decq %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "=m" (v->counter) + : "m" (v->counter)); + } +@@ -283,7 +476,19 @@ static inline void atomic64_inc(atomic64 + */ + static inline void atomic64_dec(atomic64_t *v) + { +- asm volatile(LOCK_PREFIX "decq %0" ++ asm volatile(LOCK_PREFIX "decq %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1: \n" ++ LOCK_PREFIX "incq %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "=m" (v->counter) + : "m" (v->counter)); + } +@@ -300,7 +505,20 @@ static inline int atomic64_dec_and_test( + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "decq %0; sete %1" ++ asm volatile(LOCK_PREFIX "decq %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1: \n" ++ LOCK_PREFIX "incq %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sete %1\n" + : "=m" (v->counter), "=qm" (c) + : "m" (v->counter) : "memory"); + return c != 0; +@@ -318,7 +536,20 @@ static inline int atomic64_inc_and_test( + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "incq %0; sete %1" ++ asm volatile(LOCK_PREFIX "incq %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ ".pushsection .fixup,"ax"\n" ++ "1: \n" ++ LOCK_PREFIX "decq %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sete %1\n" + : "=m" (v->counter), "=qm" (c) + : "m" (v->counter) : "memory"); + return c != 0; +@@ -337,7 +568,16 @@ static inline int atomic64_add_negative( + { + unsigned char c; + +- asm volatile(LOCK_PREFIX "addq %2,%0; sets %1" ++ asm volatile(LOCK_PREFIX "addq %2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ LOCK_PREFIX "subq %2,%0\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ "sets %1\n" + : "=m" (v->counter), "=qm" (c) + : "er" (i), "m" (v->counter) : "memory"); + return c; +@@ -353,7 +593,15 @@ static inline int atomic64_add_negative( + static inline long atomic64_add_return(long i, atomic64_t *v) + { + long __i = i; +- asm volatile(LOCK_PREFIX "xaddq %0, %1;" ++ asm volatile(LOCK_PREFIX "xaddq %0, %1\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "movq %0, %1\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ + : "+r" (i), "+m" (v->counter) + : : "memory"); + return i + __i; +@@ -398,17 +646,29 @@ static inline long atomic_xchg(atomic_t + */ + static inline int atomic_add_unless(atomic_t *v, int a, int u) + { +- int c, old; ++ int c, old, new; + c = atomic_read(v); + for (;;) { +- if (unlikely(c == (u))) ++ if (unlikely(c == u)) + break; +- old = atomic_cmpxchg((v), c, c + (a)); ++ ++ asm volatile("addl %2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ : "=r" (new) ++ : "0" (c), "ir" (a)); ++ ++ old = atomic_cmpxchg(v, c, new); + if (likely(old == c)) + break; + c = old; + } +- return c != (u); ++ return c != u; + } + + #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) +@@ -424,17 +684,29 @@ static inline int atomic_add_unless(atom + */ + static inline int atomic64_add_unless(atomic64_t *v, long a, long u) + { +- long c, old; ++ long c, old, new; + c = atomic64_read(v); + for (;;) { +- if (unlikely(c == (u))) ++ if (unlikely(c == u)) + break; +- old = atomic64_cmpxchg((v), c, c + (a)); ++ ++ asm volatile("addq %2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ "jno 0f\n" ++ "int $4\n0:\n" ++ _ASM_EXTABLE(0b, 0b) ++#endif ++ ++ : "=r" (new) ++ : "0" (c), "er" (a)); ++ ++ old = atomic64_cmpxchg((v), c, new); + if (likely(old == c)) + break; + c = old; + } +- return c != (u); ++ return c != u; + } + + /** +diff -urNp linux-2.6.31.1/arch/x86/include/asm/boot.h linux-2.6.31.1/arch/x86/include/asm/boot.h +--- linux-2.6.31.1/arch/x86/include/asm/boot.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/boot.h 2009-10-01 20:12:42.000000000 -0400 +@@ -11,10 +11,15 @@ + #include <asm/pgtable_types.h> + + /* Physical address where kernel should be loaded. */ +-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ ++#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ + + (CONFIG_PHYSICAL_ALIGN - 1)) \ + & ~(CONFIG_PHYSICAL_ALIGN - 1)) + ++#ifndef __ASSEMBLY__ ++extern unsigned char __LOAD_PHYSICAL_ADDR[]; ++#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR) ++#endif ++ + /* Minimum kernel alignment, as a power of two */ + #ifdef CONFIG_X86_64 + #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT +diff -urNp linux-2.6.31.1/arch/x86/include/asm/cache.h linux-2.6.31.1/arch/x86/include/asm/cache.h +--- linux-2.6.31.1/arch/x86/include/asm/cache.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/cache.h 2009-10-01 20:12:42.000000000 -0400 +@@ -6,6 +6,7 @@ + #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + + #define __read_mostly __attribute__((__section__(".data.read_mostly"))) ++#define __read_only __attribute__((__section__(".data.read_only"))) + + #ifdef CONFIG_X86_VSMP + /* vSMP Internode cacheline shift */ +diff -urNp linux-2.6.31.1/arch/x86/include/asm/checksum_32.h linux-2.6.31.1/arch/x86/include/asm/checksum_32.h +--- linux-2.6.31.1/arch/x86/include/asm/checksum_32.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/checksum_32.h 2009-10-01 20:12:42.000000000 -0400 +@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene + int len, __wsum sum, + int *src_err_ptr, int *dst_err_ptr); + ++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst, ++ int len, __wsum sum, ++ int *src_err_ptr, int *dst_err_ptr); ++ ++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst, ++ int len, __wsum sum, ++ int *src_err_ptr, int *dst_err_ptr); ++ + /* + * Note: when you get a NULL pointer exception here this means someone + * passed in an incorrect kernel address to one of these functions. +@@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f + int *err_ptr) + { + might_sleep(); +- return csum_partial_copy_generic((__force void *)src, dst, ++ return csum_partial_copy_generic_from_user((__force void *)src, dst, + len, sum, err_ptr, NULL); + } + +@@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us + { + might_sleep(); + if (access_ok(VERIFY_WRITE, dst, len)) +- return csum_partial_copy_generic(src, (__force void *)dst, ++ return csum_partial_copy_generic_to_user(src, (__force void *)dst, + len, sum, NULL, err_ptr); + + if (len) +diff -urNp linux-2.6.31.1/arch/x86/include/asm/desc.h linux-2.6.31.1/arch/x86/include/asm/desc.h +--- linux-2.6.31.1/arch/x86/include/asm/desc.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/desc.h 2009-10-01 20:12:42.000000000 -0400 +@@ -15,6 +15,7 @@ static inline void fill_ldt(struct desc_ + desc->base1 = (info->base_addr & 0x00ff0000) >> 16; + desc->type = (info->read_exec_only ^ 1) << 1; + desc->type |= info->contents << 2; ++ desc->type |= info->seg_not_present ^ 1; + desc->s = 1; + desc->dpl = 0x3; + desc->p = info->seg_not_present ^ 1; +@@ -31,16 +32,12 @@ static inline void fill_ldt(struct desc_ + } + + extern struct desc_ptr idt_descr; +-extern gate_desc idt_table[]; +- +-struct gdt_page { +- struct desc_struct gdt[GDT_ENTRIES]; +-} __attribute__((aligned(PAGE_SIZE))); +-DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page); ++extern gate_desc idt_table[256]; + ++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)]; + static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) + { +- return per_cpu(gdt_page, cpu).gdt; ++ return cpu_gdt_table[cpu]; + } + + #ifdef CONFIG_X86_64 +@@ -115,19 +112,48 @@ static inline void paravirt_free_ldt(str + static inline void native_write_idt_entry(gate_desc *idt, int entry, + const gate_desc *gate) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + memcpy(&idt[entry], gate, sizeof(*gate)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, + const void *desc) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + memcpy(&ldt[entry], desc, 8); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry, + const void *desc, int type) + { + unsigned int size; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + switch (type) { + case DESC_TSS: + size = sizeof(tss_desc); +@@ -139,7 +165,17 @@ static inline void native_write_gdt_entr + size = sizeof(struct desc_struct); + break; + } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + memcpy(&gdt[entry], desc, size); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, +@@ -211,7 +247,19 @@ static inline void native_set_ldt(const + + static inline void native_load_tr_desc(void) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static inline void native_load_gdt(const struct desc_ptr *dtr) +@@ -246,8 +294,19 @@ static inline void native_load_tls(struc + unsigned int i; + struct desc_struct *gdt = get_cpu_gdt_table(cpu); + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + #define _LDT_empty(info) \ +@@ -379,4 +438,16 @@ static inline void set_system_intr_gate_ + _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); + } + ++#ifdef CONFIG_X86_32 ++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu) ++{ ++ struct desc_struct d; ++ ++ if (likely(limit)) ++ limit = (limit - 1UL) >> PAGE_SHIFT; ++ pack_descriptor(&d, base, limit, 0xFB, 0xC); ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S); ++} ++#endif ++ + #endif /* _ASM_X86_DESC_H */ +diff -urNp linux-2.6.31.1/arch/x86/include/asm/e820.h linux-2.6.31.1/arch/x86/include/asm/e820.h +--- linux-2.6.31.1/arch/x86/include/asm/e820.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/e820.h 2009-10-01 20:12:42.000000000 -0400 +@@ -135,7 +135,7 @@ extern char *memory_setup(void); + #define ISA_END_ADDRESS 0x100000 + #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS) + +-#define BIOS_BEGIN 0x000a0000 ++#define BIOS_BEGIN 0x000c0000 + #define BIOS_END 0x00100000 + + #ifdef __KERNEL__ +diff -urNp linux-2.6.31.1/arch/x86/include/asm/elf.h linux-2.6.31.1/arch/x86/include/asm/elf.h +--- linux-2.6.31.1/arch/x86/include/asm/elf.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/elf.h 2009-10-01 20:12:42.000000000 -0400 +@@ -263,7 +263,25 @@ extern int force_personality32; + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + ++#ifdef CONFIG_PAX_SEGMEXEC ++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2) ++#else + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) ++#endif ++ ++#ifdef CONFIG_PAX_ASLR ++#ifdef CONFIG_X86_32 ++#define PAX_ELF_ET_DYN_BASE 0x10000000UL ++ ++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16) ++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16) ++#else ++#define PAX_ELF_ET_DYN_BASE 0x400000UL ++ ++#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32) ++#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32) ++#endif ++#endif + + /* This yields a mask that user programs can use to figure out what + instruction set this CPU supports. This could be done in user space, +@@ -315,8 +333,7 @@ do { \ + #define ARCH_DLINFO \ + do { \ + if (vdso_enabled) \ +- NEW_AUX_ENT(AT_SYSINFO_EHDR, \ +- (unsigned long)current->mm->context.vdso); \ ++ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\ + } while (0) + + #define AT_SYSINFO 32 +@@ -327,7 +344,7 @@ do { \ + + #endif /* !CONFIG_X86_32 */ + +-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) ++#define VDSO_CURRENT_BASE (current->mm->context.vdso) + + #define VDSO_ENTRY \ + ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall)) +@@ -341,7 +358,4 @@ extern int arch_setup_additional_pages(s + extern int syscall32_setup_pages(struct linux_binprm *, int exstack); + #define compat_arch_setup_additional_pages syscall32_setup_pages + +-extern unsigned long arch_randomize_brk(struct mm_struct *mm); +-#define arch_randomize_brk arch_randomize_brk +- + #endif /* _ASM_X86_ELF_H */ +diff -urNp linux-2.6.31.1/arch/x86/include/asm/futex.h linux-2.6.31.1/arch/x86/include/asm/futex.h +--- linux-2.6.31.1/arch/x86/include/asm/futex.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/futex.h 2009-10-01 20:12:42.000000000 -0400 +@@ -11,6 +11,40 @@ + #include <asm/processor.h> + #include <asm/system.h> + ++#ifdef CONFIG_X86_32 ++#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \ ++ asm volatile( \ ++ "movw\t%w6, %%ds\n" \ ++ "1:\t" insn "\n" \ ++ "2:\tpushl\t%%ss\n" \ ++ "\tpopl\t%%ds\n" \ ++ "\t.section .fixup,"ax"\n" \ ++ "3:\tmov\t%3, %1\n" \ ++ "\tjmp\t2b\n" \ ++ "\t.previous\n" \ ++ _ASM_EXTABLE(1b, 3b) \ ++ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \ ++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS)) ++ ++#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ ++ asm volatile("movw\t%w7, %%es\n" \ ++ "1:\tmovl\t%%es:%2, %0\n" \ ++ "\tmovl\t%0, %3\n" \ ++ "\t" insn "\n" \ ++ "2:\t" LOCK_PREFIX "cmpxchgl %3, %%es:%2\n"\ ++ "\tjnz\t1b\n" \ ++ "3:\tpushl\t%%ss\n" \ ++ "\tpopl\t%%es\n" \ ++ "\t.section .fixup,"ax"\n" \ ++ "4:\tmov\t%5, %1\n" \ ++ "\tjmp\t3b\n" \ ++ "\t.previous\n" \ ++ _ASM_EXTABLE(1b, 4b) \ ++ _ASM_EXTABLE(2b, 4b) \ ++ : "=&a" (oldval), "=&r" (ret), \ ++ "+m" (*uaddr), "=&r" (tem) \ ++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS)) ++#else + #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \ + asm volatile("1:\t" insn "\n" \ + "2:\t.section .fixup,"ax"\n" \ +@@ -36,8 +70,9 @@ + : "=&a" (oldval), "=&r" (ret), \ + "+m" (*uaddr), "=&r" (tem) \ + : "r" (oparg), "i" (-EFAULT), "1" (0)) ++#endif + +-static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) ++static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) + { + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; +@@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser + + switch (op) { + case FUTEX_OP_SET: ++#ifdef CONFIG_X86_32 ++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg); ++#else + __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); ++#endif + break; + case FUTEX_OP_ADD: ++#ifdef CONFIG_X86_32 ++ __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret, oldval, ++ uaddr, oparg); ++#else + __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval, + uaddr, oparg); ++#endif + break; + case FUTEX_OP_OR: + __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg); +@@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser + return ret; + } + +-static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, ++static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, + int newval) + { + +@@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + +- asm volatile("1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n" ++ asm volatile( ++#ifdef CONFIG_X86_32 ++ "\tmovw %w5, %%ds\n" ++ "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n" ++ "2:\tpushl %%ss\n" ++ "\tpopl %%ds\n" ++ "\t.section .fixup, "ax"\n" ++#else ++ "1:\t" LOCK_PREFIX "cmpxchgl %3, %1\n" + "2:\t.section .fixup, "ax"\n" ++#endif + "3:\tmov %2, %0\n" + "\tjmp 2b\n" + "\t.previous\n" + _ASM_EXTABLE(1b, 3b) + : "=a" (oldval), "+m" (*uaddr) ++#ifdef CONFIG_X86_32 ++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS) ++#else + : "i" (-EFAULT), "r" (newval), "0" (oldval) ++#endif + : "memory" + ); + +diff -urNp linux-2.6.31.1/arch/x86/include/asm/i387.h linux-2.6.31.1/arch/x86/include/asm/i387.h +--- linux-2.6.31.1/arch/x86/include/asm/i387.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/i387.h 2009-10-01 20:12:42.000000000 -0400 +@@ -194,13 +194,8 @@ static inline int fxrstor_checking(struc + } + + /* We need a safe address that is cheap to find and that is already +- in L1 during context switch. The best choices are unfortunately +- different for UP and SMP */ +-#ifdef CONFIG_SMP +-#define safe_address (__per_cpu_offset[0]) +-#else +-#define safe_address (kstat_cpu(0).cpustat.user) +-#endif ++ in L1 during context switch. */ ++#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0) + + /* + * These must be called with preempt disabled +diff -urNp linux-2.6.31.1/arch/x86/include/asm/io_64.h linux-2.6.31.1/arch/x86/include/asm/io_64.h +--- linux-2.6.31.1/arch/x86/include/asm/io_64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/io_64.h 2009-10-01 20:12:42.000000000 -0400 +@@ -140,6 +140,17 @@ __OUTS(l) + + #include <linux/vmalloc.h> + ++#define ARCH_HAS_VALID_PHYS_ADDR_RANGE ++static inline int valid_phys_addr_range (unsigned long addr, size_t count) ++{ ++ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0; ++} ++ ++static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count) ++{ ++ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0; ++} ++ + #include <asm-generic/iomap.h> + + void __memcpy_fromio(void *, unsigned long, unsigned); +diff -urNp linux-2.6.31.1/arch/x86/include/asm/irqflags.h linux-2.6.31.1/arch/x86/include/asm/irqflags.h +--- linux-2.6.31.1/arch/x86/include/asm/irqflags.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/irqflags.h 2009-10-01 20:12:42.000000000 -0400 +@@ -147,6 +147,8 @@ static inline unsigned long __raw_local_ + #define INTERRUPT_RETURN iret + #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit + #define GET_CR0_INTO_EAX movl %cr0, %eax ++#define GET_CR0_INTO_EDX movl %cr0, %edx ++#define SET_CR0_FROM_EDX movl %edx, %cr0 + #endif + + +diff -urNp linux-2.6.31.1/arch/x86/include/asm/kvm_host.h linux-2.6.31.1/arch/x86/include/asm/kvm_host.h +--- linux-2.6.31.1/arch/x86/include/asm/kvm_host.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/kvm_host.h 2009-10-01 20:12:42.000000000 -0400 +@@ -528,7 +528,7 @@ struct kvm_x86_ops { + u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); + }; + +-extern struct kvm_x86_ops *kvm_x86_ops; ++extern const struct kvm_x86_ops *kvm_x86_ops; + + int kvm_mmu_module_init(void); + void kvm_mmu_module_exit(void); +diff -urNp linux-2.6.31.1/arch/x86/include/asm/local.h linux-2.6.31.1/arch/x86/include/asm/local.h +--- linux-2.6.31.1/arch/x86/include/asm/local.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/local.h 2009-10-01 20:12:42.000000000 -0400 +@@ -18,26 +18,90 @@ typedef struct { + + static inline void local_inc(local_t *l) + { +- asm volatile(_ASM_INC "%0" ++ asm volatile(_ASM_INC "%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ _ASM_DEC "%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "+m" (l->a.counter)); + } + + static inline void local_dec(local_t *l) + { +- asm volatile(_ASM_DEC "%0" ++ asm volatile(_ASM_DEC "%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ _ASM_INC "%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "+m" (l->a.counter)); + } + + static inline void local_add(long i, local_t *l) + { +- asm volatile(_ASM_ADD "%1,%0" ++ asm volatile(_ASM_ADD "%1,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ _ASM_SUB "%1,%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "+m" (l->a.counter) + : "ir" (i)); + } + + static inline void local_sub(long i, local_t *l) + { +- asm volatile(_ASM_SUB "%1,%0" ++ asm volatile(_ASM_SUB "%1,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ _ASM_ADD "%1,%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "+m" (l->a.counter) + : "ir" (i)); + } +@@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon + { + unsigned char c; + +- asm volatile(_ASM_SUB "%2,%0; sete %1" ++ asm volatile(_ASM_SUB "%2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ _ASM_ADD "%2,%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sete %1\n" + : "+m" (l->a.counter), "=qm" (c) + : "ir" (i) : "memory"); + return c; +@@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc + { + unsigned char c; + +- asm volatile(_ASM_DEC "%0; sete %1" ++ asm volatile(_ASM_DEC "%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ _ASM_INC "%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sete %1\n" + : "+m" (l->a.counter), "=qm" (c) + : : "memory"); + return c != 0; +@@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc + { + unsigned char c; + +- asm volatile(_ASM_INC "%0; sete %1" ++ asm volatile(_ASM_INC "%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ _ASM_DEC "%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sete %1\n" + : "+m" (l->a.counter), "=qm" (c) + : : "memory"); + return c != 0; +@@ -110,7 +225,24 @@ static inline int local_add_negative(lon + { + unsigned char c; + +- asm volatile(_ASM_ADD "%2,%0; sets %1" ++ asm volatile(_ASM_ADD "%2,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ _ASM_SUB "%2,%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "sets %1\n" + : "+m" (l->a.counter), "=qm" (c) + : "ir" (i) : "memory"); + return c; +@@ -133,7 +265,23 @@ static inline long local_add_return(long + #endif + /* Modern 486+ processor */ + __i = i; +- asm volatile(_ASM_XADD "%0, %1;" ++ asm volatile(_ASM_XADD "%0, %1\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ _ASM_MOV "%0,%1\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "+r" (i), "+m" (l->a.counter) + : : "memory"); + return i + __i; +diff -urNp linux-2.6.31.1/arch/x86/include/asm/mman.h linux-2.6.31.1/arch/x86/include/asm/mman.h +--- linux-2.6.31.1/arch/x86/include/asm/mman.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/mman.h 2009-10-01 20:12:42.000000000 -0400 +@@ -17,4 +17,14 @@ + #define MCL_CURRENT 1 /* lock all current mappings */ + #define MCL_FUTURE 2 /* lock all future mappings */ + ++#ifdef __KERNEL__ ++#ifndef __ASSEMBLY__ ++#ifdef CONFIG_X86_32 ++#define arch_mmap_check i386_mmap_check ++int i386_mmap_check(unsigned long addr, unsigned long len, ++ unsigned long flags); ++#endif ++#endif ++#endif ++ + #endif /* _ASM_X86_MMAN_H */ +diff -urNp linux-2.6.31.1/arch/x86/include/asm/mmu_context.h linux-2.6.31.1/arch/x86/include/asm/mmu_context.h +--- linux-2.6.31.1/arch/x86/include/asm/mmu_context.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/mmu_context.h 2009-10-01 20:12:42.000000000 -0400 +@@ -34,11 +34,17 @@ static inline void switch_mm(struct mm_s + struct task_struct *tsk) + { + unsigned cpu = smp_processor_id(); ++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP) ++ int tlbstate = TLBSTATE_OK; ++#endif + + if (likely(prev != next)) { + /* stop flush ipis for the previous mm */ + cpu_clear(cpu, prev->cpu_vm_mask); + #ifdef CONFIG_SMP ++#ifdef CONFIG_X86_32 ++ tlbstate = percpu_read(cpu_tlbstate.state); ++#endif + percpu_write(cpu_tlbstate.state, TLBSTATE_OK); + percpu_write(cpu_tlbstate.active_mm, next); + #endif +@@ -52,6 +58,26 @@ static inline void switch_mm(struct mm_s + */ + if (unlikely(prev->context.ldt != next->context.ldt)) + load_LDT_nolock(&next->context); ++ ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP) ++ if (!nx_enabled) { ++ smp_mb__before_clear_bit(); ++ cpu_clear(cpu, prev->context.cpu_user_cs_mask); ++ smp_mb__after_clear_bit(); ++ cpu_set(cpu, next->context.cpu_user_cs_mask); ++ } ++#endif ++ ++#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)) ++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base || ++ prev->context.user_cs_limit != next->context.user_cs_limit ++#ifdef CONFIG_SMP ++ || tlbstate != TLBSTATE_OK ++#endif ++ )) ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu); ++#endif ++ + } + #ifdef CONFIG_SMP + else { +@@ -65,6 +91,19 @@ static inline void switch_mm(struct mm_s + */ + load_cr3(next->pgd); + load_LDT_nolock(&next->context); ++ ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) ++ if (!nx_enabled) ++ cpu_set(cpu, next->context.cpu_user_cs_mask); ++#endif ++ ++#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)) ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled)) ++#endif ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu); ++#endif ++ + } + } + #endif +diff -urNp linux-2.6.31.1/arch/x86/include/asm/mmu.h linux-2.6.31.1/arch/x86/include/asm/mmu.h +--- linux-2.6.31.1/arch/x86/include/asm/mmu.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/mmu.h 2009-10-01 20:12:42.000000000 -0400 +@@ -9,10 +9,23 @@ + * we put the segment information here. + */ + typedef struct { +- void *ldt; ++ struct desc_struct *ldt; + int size; + struct mutex lock; +- void *vdso; ++ unsigned long vdso; ++ ++#ifdef CONFIG_X86_32 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++ unsigned long user_cs_base; ++ unsigned long user_cs_limit; ++ ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP) ++ cpumask_t cpu_user_cs_mask; ++#endif ++ ++#endif ++#endif ++ + } mm_context_t; + + #ifdef CONFIG_SMP +diff -urNp linux-2.6.31.1/arch/x86/include/asm/module.h linux-2.6.31.1/arch/x86/include/asm/module.h +--- linux-2.6.31.1/arch/x86/include/asm/module.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/module.h 2009-10-01 20:12:42.000000000 -0400 +@@ -74,7 +74,12 @@ struct mod_arch_specific {}; + # else + # define MODULE_STACKSIZE "" + # endif +-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE ++# ifdef CONFIG_GRKERNSEC ++# define MODULE_GRSEC "GRSECURITY " ++# else ++# define MODULE_GRSEC "" ++# endif ++# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC + #endif + + #endif /* _ASM_X86_MODULE_H */ +diff -urNp linux-2.6.31.1/arch/x86/include/asm/page_32_types.h linux-2.6.31.1/arch/x86/include/asm/page_32_types.h +--- linux-2.6.31.1/arch/x86/include/asm/page_32_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/page_32_types.h 2009-10-01 20:12:42.000000000 -0400 +@@ -15,6 +15,10 @@ + */ + #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) + ++#ifdef CONFIG_PAX_PAGEEXEC ++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1 ++#endif ++ + #ifdef CONFIG_4KSTACKS + #define THREAD_ORDER 0 + #else +diff -urNp linux-2.6.31.1/arch/x86/include/asm/page_64_types.h linux-2.6.31.1/arch/x86/include/asm/page_64_types.h +--- linux-2.6.31.1/arch/x86/include/asm/page_64_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/page_64_types.h 2009-10-01 20:12:42.000000000 -0400 +@@ -39,6 +39,9 @@ + #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) + #define __START_KERNEL_map _AC(0xffffffff80000000, UL) + ++#define ktla_ktva(addr) (addr) ++#define ktva_ktla(addr) (addr) ++ + /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */ + #define __PHYSICAL_MASK_SHIFT 46 + #define __VIRTUAL_MASK_SHIFT 47 +diff -urNp linux-2.6.31.1/arch/x86/include/asm/paravirt.h linux-2.6.31.1/arch/x86/include/asm/paravirt.h +--- linux-2.6.31.1/arch/x86/include/asm/paravirt.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/paravirt.h 2009-10-01 20:12:42.000000000 -0400 +@@ -1688,7 +1688,7 @@ static inline unsigned long __raw_local_ + + #define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4) + #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4) +-#define PARA_INDIRECT(addr) *%cs:addr ++#define PARA_INDIRECT(addr) *%ss:addr + #endif + + #define INTERRUPT_RETURN \ +@@ -1718,6 +1718,18 @@ static inline unsigned long __raw_local_ + call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \ + pop %edx; pop %ecx + ++#define GET_CR0_INTO_EDX \ ++ push %eax; push %ecx; \ ++ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \ ++ mov %eax, %edx; \ ++ pop %ecx; pop %eax ++ ++#define SET_CR0_FROM_EDX \ ++ push %eax; push %ecx; \ ++ mov %edx, %eax; \ ++ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0);\ ++ pop %ecx; pop %eax ++ + #define ENABLE_INTERRUPTS_SYSEXIT \ + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \ + CLBR_NONE, \ +diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgalloc.h linux-2.6.31.1/arch/x86/include/asm/pgalloc.h +--- linux-2.6.31.1/arch/x86/include/asm/pgalloc.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/pgalloc.h 2009-10-01 20:12:42.000000000 -0400 +@@ -58,6 +58,13 @@ static inline void pmd_populate_kernel(s + pmd_t *pmd, pte_t *pte) + { + paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT); ++ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE)); ++} ++ ++static inline void pmd_populate_user(struct mm_struct *mm, ++ pmd_t *pmd, pte_t *pte) ++{ ++ paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT); + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE)); + } + +diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable-2level.h linux-2.6.31.1/arch/x86/include/asm/pgtable-2level.h +--- linux-2.6.31.1/arch/x86/include/asm/pgtable-2level.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/pgtable-2level.h 2009-10-01 20:12:42.000000000 -0400 +@@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t + + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + *pmdp = pmd; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) +diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable_32.h linux-2.6.31.1/arch/x86/include/asm/pgtable_32.h +--- linux-2.6.31.1/arch/x86/include/asm/pgtable_32.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/pgtable_32.h 2009-10-01 20:12:42.000000000 -0400 +@@ -26,8 +26,6 @@ + struct mm_struct; + struct vm_area_struct; + +-extern pgd_t swapper_pg_dir[1024]; +- + static inline void pgtable_cache_init(void) { } + static inline void check_pgt_cache(void) { } + void paging_init(void); +@@ -48,6 +46,11 @@ extern void set_pmd_pfn(unsigned long, u + # include <asm/pgtable-2level.h> + #endif + ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; ++#ifdef CONFIG_X86_PAE ++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD]; ++#endif ++ + #if defined(CONFIG_HIGHPTE) + #define __KM_PTE \ + (in_nmi() ? KM_NMI_PTE : \ +@@ -84,6 +87,9 @@ do { \ + + #endif /* !__ASSEMBLY__ */ + ++#define HAVE_ARCH_UNMAPPED_AREA ++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN ++ + /* + * kern_addr_valid() is (1) for FLATMEM and (0) for + * SPARSEMEM and DISCONTIGMEM +diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable_32_types.h linux-2.6.31.1/arch/x86/include/asm/pgtable_32_types.h +--- linux-2.6.31.1/arch/x86/include/asm/pgtable_32_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/pgtable_32_types.h 2009-10-01 20:12:42.000000000 -0400 +@@ -8,7 +8,7 @@ + */ + #ifdef CONFIG_X86_PAE + # include <asm/pgtable-3level_types.h> +-# define PMD_SIZE (1UL << PMD_SHIFT) ++# define PMD_SIZE (_AC(1, UL) << PMD_SHIFT) + # define PMD_MASK (~(PMD_SIZE - 1)) + #else + # include <asm/pgtable-2level_types.h> +@@ -46,6 +46,19 @@ extern bool __vmalloc_start_set; /* set + # define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE) + #endif + ++#ifdef CONFIG_PAX_KERNEXEC ++#ifndef __ASSEMBLY__ ++extern unsigned char MODULES_EXEC_VADDR[]; ++extern unsigned char MODULES_EXEC_END[]; ++#endif ++#include <asm/boot.h> ++#define ktla_ktva(addr) (addr + LOAD_PHYSICAL_ADDR + PAGE_OFFSET) ++#define ktva_ktla(addr) (addr - LOAD_PHYSICAL_ADDR - PAGE_OFFSET) ++#else ++#define ktla_ktva(addr) (addr) ++#define ktva_ktla(addr) (addr) ++#endif ++ + #define MODULES_VADDR VMALLOC_START + #define MODULES_END VMALLOC_END + #define MODULES_LEN (MODULES_VADDR - MODULES_END) +diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable-3level.h linux-2.6.31.1/arch/x86/include/asm/pgtable-3level.h +--- linux-2.6.31.1/arch/x86/include/asm/pgtable-3level.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/pgtable-3level.h 2009-10-01 20:12:42.000000000 -0400 +@@ -38,12 +38,36 @@ static inline void native_set_pte_atomic + + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static inline void native_set_pud(pud_t *pudp, pud_t pud) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + set_64bit((unsigned long long *)(pudp), native_pud_val(pud)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + /* +diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable_64.h linux-2.6.31.1/arch/x86/include/asm/pgtable_64.h +--- linux-2.6.31.1/arch/x86/include/asm/pgtable_64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/pgtable_64.h 2009-10-01 20:12:42.000000000 -0400 +@@ -16,9 +16,12 @@ + + extern pud_t level3_kernel_pgt[512]; + extern pud_t level3_ident_pgt[512]; ++extern pud_t level3_vmalloc_pgt[512]; ++extern pud_t level3_vmemmap_pgt[512]; ++extern pud_t level2_vmemmap_pgt[512]; + extern pmd_t level2_kernel_pgt[512]; + extern pmd_t level2_fixmap_pgt[512]; +-extern pmd_t level2_ident_pgt[512]; ++extern pmd_t level2_ident_pgt[512*4]; + extern pgd_t init_level4_pgt[]; + + #define swapper_pg_dir init_level4_pgt +@@ -74,7 +77,19 @@ static inline pte_t native_ptep_get_and_ + + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + *pmdp = pmd; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + static inline void native_pmd_clear(pmd_t *pmd) +diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable.h linux-2.6.31.1/arch/x86/include/asm/pgtable.h +--- linux-2.6.31.1/arch/x86/include/asm/pgtable.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/pgtable.h 2009-10-01 20:12:42.000000000 -0400 +@@ -90,6 +90,11 @@ static inline void __init paravirt_paget + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ ++static inline int pte_user(pte_t pte) ++{ ++ return pte_val(pte) & _PAGE_USER; ++} ++ + static inline int pte_dirty(pte_t pte) + { + return pte_flags(pte) & _PAGE_DIRTY; +@@ -172,9 +177,29 @@ static inline pte_t pte_wrprotect(pte_t + return pte_clear_flags(pte, _PAGE_RW); + } + ++static inline pte_t pte_mkread(pte_t pte) ++{ ++ return __pte(pte_val(pte) | _PAGE_USER); ++} ++ + static inline pte_t pte_mkexec(pte_t pte) + { +- return pte_clear_flags(pte, _PAGE_NX); ++#ifdef CONFIG_X86_PAE ++ if (__supported_pte_mask & _PAGE_NX) ++ return pte_clear_flags(pte, _PAGE_NX); ++ else ++#endif ++ return pte_set_flags(pte, _PAGE_USER); ++} ++ ++static inline pte_t pte_exprotect(pte_t pte) ++{ ++#ifdef CONFIG_X86_PAE ++ if (__supported_pte_mask & _PAGE_NX) ++ return pte_set_flags(pte, _PAGE_NX); ++ else ++#endif ++ return pte_clear_flags(pte, _PAGE_USER); + } + + static inline pte_t pte_mkdirty(pte_t pte) +@@ -482,7 +507,7 @@ static inline pud_t *pud_offset(pgd_t *p + + static inline int pgd_bad(pgd_t pgd) + { +- return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE; ++ return (pgd_flags(pgd) & ~(_PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE; + } + + static inline int pgd_none(pgd_t pgd) +@@ -623,7 +648,19 @@ static inline void ptep_set_wrprotect(st + */ + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) + { +- memcpy(dst, src, count * sizeof(pgd_t)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ ++ memcpy(dst, src, count * sizeof(pgd_t)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + +diff -urNp linux-2.6.31.1/arch/x86/include/asm/pgtable_types.h linux-2.6.31.1/arch/x86/include/asm/pgtable_types.h +--- linux-2.6.31.1/arch/x86/include/asm/pgtable_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/pgtable_types.h 2009-10-01 20:12:42.000000000 -0400 +@@ -16,12 +16,11 @@ + #define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */ + #define _PAGE_BIT_PAT 7 /* on 4KB pages */ + #define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ +-#define _PAGE_BIT_UNUSED1 9 /* available for programmer */ ++#define _PAGE_BIT_SPECIAL 9 /* special mappings, no associated struct page */ + #define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */ + #define _PAGE_BIT_HIDDEN 11 /* hidden by kmemcheck */ + #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ +-#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1 +-#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1 ++#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SPECIAL + #define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ + + /* If _PAGE_BIT_PRESENT is clear, we use these: */ +@@ -39,7 +38,6 @@ + #define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY) + #define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE) + #define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL) +-#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1) + #define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP) + #define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT) + #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) +@@ -55,8 +53,10 @@ + + #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) + #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX) +-#else ++#elif defined(CONFIG_KMEMCHECK) + #define _PAGE_NX (_AT(pteval_t, 0)) ++#else ++#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN) + #endif + + #define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE) +@@ -93,6 +93,9 @@ + #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_ACCESSED) + ++#define PAGE_READONLY_NOEXEC PAGE_READONLY ++#define PAGE_SHARED_NOEXEC PAGE_SHARED ++ + #define __PAGE_KERNEL_EXEC \ + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL) + #define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX) +@@ -103,8 +106,8 @@ + #define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC) + #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT) + #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD) +-#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) +-#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT) ++#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RO | _PAGE_USER) ++#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER) + #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) + #define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE) + #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) +@@ -163,8 +166,8 @@ + * bits are combined, this will alow user to access the high address mapped + * VDSO in the presence of CONFIG_COMPAT_VDSO + */ +-#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */ +-#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */ ++#define PTE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */ ++#define PDE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */ + #define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */ + #endif + +@@ -277,7 +280,15 @@ static inline pteval_t pte_flags(pte_t p + typedef struct page *pgtable_t; + + extern pteval_t __supported_pte_mask; ++#ifdef CONFIG_X86_32 ++#ifdef CONFIG_X86_PAE + extern int nx_enabled; ++#else ++#define nx_enabled (0) ++#endif ++#else ++#define nx_enabled (1) ++#endif + + #define pgprot_writecombine pgprot_writecombine + extern pgprot_t pgprot_writecombine(pgprot_t prot); +diff -urNp linux-2.6.31.1/arch/x86/include/asm/processor.h linux-2.6.31.1/arch/x86/include/asm/processor.h +--- linux-2.6.31.1/arch/x86/include/asm/processor.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/processor.h 2009-10-01 20:12:42.000000000 -0400 +@@ -271,7 +271,7 @@ struct tss_struct { + + } ____cacheline_aligned; + +-DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss); ++extern struct tss_struct init_tss[NR_CPUS]; + + /* + * Save the original ist values for checking stack pointers during debugging +@@ -900,8 +900,17 @@ static inline void spin_lock_prefetch(co + */ + #define TASK_SIZE PAGE_OFFSET + #define TASK_SIZE_MAX TASK_SIZE ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2) ++#endif ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE) ++#else + #define STACK_TOP TASK_SIZE +-#define STACK_TOP_MAX STACK_TOP ++#endif ++#define STACK_TOP_MAX TASK_SIZE + + #define INIT_THREAD { \ + .sp0 = sizeof(init_stack) + (long)&init_stack, \ +@@ -918,7 +927,7 @@ static inline void spin_lock_prefetch(co + */ + #define INIT_TSS { \ + .x86_tss = { \ +- .sp0 = sizeof(init_stack) + (long)&init_stack, \ ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \ + .ss0 = __KERNEL_DS, \ + .ss1 = __KERNEL_CS, \ + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ +@@ -929,11 +938,7 @@ static inline void spin_lock_prefetch(co + extern unsigned long thread_saved_pc(struct task_struct *tsk); + + #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long)) +-#define KSTK_TOP(info) \ +-({ \ +- unsigned long *__ptr = (unsigned long *)(info); \ +- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \ +-}) ++#define KSTK_TOP(info) ((info)->task.thread.sp0) + + /* + * The below -8 is to reserve 8 bytes on top of the ring0 stack. +@@ -948,7 +953,7 @@ extern unsigned long thread_saved_pc(str + #define task_pt_regs(task) \ + ({ \ + struct pt_regs *__regs__; \ +- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \ ++ __regs__ = (struct pt_regs *)((task)->thread.sp0); \ + __regs__ - 1; \ + }) + +@@ -964,7 +969,7 @@ extern unsigned long thread_saved_pc(str + * space during mmap's. + */ + #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \ +- 0xc0000000 : 0xFFFFe000) ++ 0xc0000000 : 0xFFFFf000) + + #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \ + IA32_PAGE_OFFSET : TASK_SIZE_MAX) +@@ -1001,6 +1006,10 @@ extern void start_thread(struct pt_regs + */ + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) + ++#ifdef CONFIG_PAX_SEGMEXEC ++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3)) ++#endif ++ + #define KSTK_EIP(task) (task_pt_regs(task)->ip) + + /* Get/set a process' ability to use the timestamp counter instruction */ +diff -urNp linux-2.6.31.1/arch/x86/include/asm/ptrace.h linux-2.6.31.1/arch/x86/include/asm/ptrace.h +--- linux-2.6.31.1/arch/x86/include/asm/ptrace.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/ptrace.h 2009-10-01 20:12:42.000000000 -0400 +@@ -151,28 +151,29 @@ static inline unsigned long regs_return_ + } + + /* +- * user_mode_vm(regs) determines whether a register set came from user mode. ++ * user_mode(regs) determines whether a register set came from user mode. + * This is true if V8086 mode was enabled OR if the register set was from + * protected mode with RPL-3 CS value. This tricky test checks that with + * one comparison. Many places in the kernel can bypass this full check +- * if they have already ruled out V8086 mode, so user_mode(regs) can be used. ++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can ++ * be used. + */ +-static inline int user_mode(struct pt_regs *regs) ++static inline int user_mode_novm(struct pt_regs *regs) + { + #ifdef CONFIG_X86_32 + return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL; + #else +- return !!(regs->cs & 3); ++ return !!(regs->cs & SEGMENT_RPL_MASK); + #endif + } + +-static inline int user_mode_vm(struct pt_regs *regs) ++static inline int user_mode(struct pt_regs *regs) + { + #ifdef CONFIG_X86_32 + return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= + USER_RPL; + #else +- return user_mode(regs); ++ return user_mode_novm(regs); + #endif + } + +diff -urNp linux-2.6.31.1/arch/x86/include/asm/reboot.h linux-2.6.31.1/arch/x86/include/asm/reboot.h +--- linux-2.6.31.1/arch/x86/include/asm/reboot.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/reboot.h 2009-10-01 20:12:42.000000000 -0400 +@@ -18,7 +18,7 @@ extern struct machine_ops machine_ops; + + void native_machine_crash_shutdown(struct pt_regs *regs); + void native_machine_shutdown(void); +-void machine_real_restart(const unsigned char *code, int length); ++void machine_real_restart(const unsigned char *code, unsigned int length); + + typedef void (*nmi_shootdown_cb)(int, struct die_args*); + void nmi_shootdown_cpus(nmi_shootdown_cb callback); +diff -urNp linux-2.6.31.1/arch/x86/include/asm/rwsem.h linux-2.6.31.1/arch/x86/include/asm/rwsem.h +--- linux-2.6.31.1/arch/x86/include/asm/rwsem.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/rwsem.h 2009-10-01 20:12:42.000000000 -0400 +@@ -106,10 +106,26 @@ static inline void __down_read(struct rw + { + asm volatile("# beginning down_read\n\t" + LOCK_PREFIX " incl (%%eax)\n\t" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ LOCK_PREFIX "decl (%%eax)\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + /* adds 0x00000001, returns the old value */ +- " jns 1f\n" ++ " jns 2f\n" + " call call_rwsem_down_read_failed\n" +- "1:\n\t" ++ "2:\n\t" + "# ending down_read\n\t" + : "+m" (sem->count) + : "a" (sem) +@@ -124,13 +140,29 @@ static inline int __down_read_trylock(st + __s32 result, tmp; + asm volatile("# beginning __down_read_trylock\n\t" + " movl %0,%1\n\t" +- "1:\n\t" ++ "2:\n\t" + " movl %1,%2\n\t" + " addl %3,%2\n\t" +- " jle 2f\n\t" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ "subl %3,%2\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ " jle 3f\n\t" + LOCK_PREFIX " cmpxchgl %2,%0\n\t" +- " jnz 1b\n\t" +- "2:\n\t" ++ " jnz 2b\n\t" ++ "3:\n\t" + "# ending __down_read_trylock\n\t" + : "+m" (sem->count), "=&a" (result), "=&r" (tmp) + : "i" (RWSEM_ACTIVE_READ_BIAS) +@@ -148,12 +180,28 @@ static inline void __down_write_nested(s + tmp = RWSEM_ACTIVE_WRITE_BIAS; + asm volatile("# beginning down_write\n\t" + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ "movl %%edx,(%%eax)\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + /* subtract 0x0000ffff, returns the old value */ + " testl %%edx,%%edx\n\t" + /* was the count 0 before? */ +- " jz 1f\n" ++ " jz 2f\n" + " call call_rwsem_down_write_failed\n" +- "1:\n" ++ "2:\n" + "# ending down_write" + : "+m" (sem->count), "=d" (tmp) + : "a" (sem), "1" (tmp) +@@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s + __s32 tmp = -RWSEM_ACTIVE_READ_BIAS; + asm volatile("# beginning __up_read\n\t" + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ "movl %%edx,(%%eax)\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + /* subtracts 1, returns the old value */ +- " jns 1f\n\t" ++ " jns 2f\n\t" + " call call_rwsem_wake\n" +- "1:\n" ++ "2:\n" + "# ending __up_read\n" + : "+m" (sem->count), "=d" (tmp) + : "a" (sem), "1" (tmp) +@@ -204,11 +268,27 @@ static inline void __up_write(struct rw_ + asm volatile("# beginning __up_write\n\t" + " movl %2,%%edx\n\t" + LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ "movl %%edx,(%%eax)\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + /* tries to transition + 0xffff0001 -> 0x00000000 */ +- " jz 1f\n" ++ " jz 2f\n" + " call call_rwsem_wake\n" +- "1:\n\t" ++ "2:\n\t" + "# ending __up_write\n" + : "+m" (sem->count) + : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS) +@@ -222,10 +302,26 @@ static inline void __downgrade_write(str + { + asm volatile("# beginning __downgrade_write\n\t" + LOCK_PREFIX " addl %2,(%%eax)\n\t" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ LOCK_PREFIX "subl %2,(%%eax)\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ +- " jns 1f\n\t" ++ " jns 2f\n\t" + " call call_rwsem_downgrade_wake\n" +- "1:\n\t" ++ "2:\n\t" + "# ending __downgrade_write\n" + : "+m" (sem->count) + : "a" (sem), "i" (-RWSEM_WAITING_BIAS) +@@ -237,7 +333,23 @@ static inline void __downgrade_write(str + */ + static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) + { +- asm volatile(LOCK_PREFIX "addl %1,%0" ++ asm volatile(LOCK_PREFIX "addl %1,%0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ LOCK_PREFIX "subl %1,%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "+m" (sem->count) + : "ir" (delta)); + } +@@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in + { + int tmp = delta; + +- asm volatile(LOCK_PREFIX "xadd %0,%1" ++ asm volatile(LOCK_PREFIX "xadd %0,%1\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ "movl %0,%1\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "+r" (tmp), "+m" (sem->count) + : : "memory"); + +diff -urNp linux-2.6.31.1/arch/x86/include/asm/segment.h linux-2.6.31.1/arch/x86/include/asm/segment.h +--- linux-2.6.31.1/arch/x86/include/asm/segment.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/segment.h 2009-10-01 20:12:42.000000000 -0400 +@@ -88,7 +88,7 @@ + #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14) + #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8) + +-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15) ++#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15) + #ifdef CONFIG_SMP + #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8) + #else +@@ -102,6 +102,12 @@ + #define __KERNEL_STACK_CANARY 0 + #endif + ++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 17) ++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8) ++ ++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 18) ++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8) ++ + #define GDT_ENTRY_DOUBLEFAULT_TSS 31 + + /* +@@ -139,7 +145,7 @@ + */ + + /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ +-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) ++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16) + + + #else +diff -urNp linux-2.6.31.1/arch/x86/include/asm/spinlock.h linux-2.6.31.1/arch/x86/include/asm/spinlock.h +--- linux-2.6.31.1/arch/x86/include/asm/spinlock.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/spinlock.h 2009-10-01 20:12:42.000000000 -0400 +@@ -249,18 +249,50 @@ static inline int __raw_write_can_lock(r + static inline void __raw_read_lock(raw_rwlock_t *rw) + { + asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" +- "jns 1f\n" +- "call __read_lock_failed\n\t" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" + "1:\n" ++ LOCK_PREFIX " addl $1,(%0)\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "jns 2f\n" ++ "call __read_lock_failed\n\t" ++ "2:\n" + ::LOCK_PTR_REG (rw) : "memory"); + } + + static inline void __raw_write_lock(raw_rwlock_t *rw) + { + asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t" +- "jz 1f\n" +- "call __write_lock_failed\n\t" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" + "1:\n" ++ LOCK_PREFIX " addl %1,(%0)\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ "jz 2f\n" ++ "call __write_lock_failed\n\t" ++ "2:\n" + ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory"); + } + +@@ -286,12 +318,45 @@ static inline int __raw_write_trylock(ra + + static inline void __raw_read_unlock(raw_rwlock_t *rw) + { +- asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); ++ asm volatile(LOCK_PREFIX "incl %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ LOCK_PREFIX "decl %0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ ++ :"+m" (rw->lock) : : "memory"); + } + + static inline void __raw_write_unlock(raw_rwlock_t *rw) + { +- asm volatile(LOCK_PREFIX "addl %1, %0" ++ asm volatile(LOCK_PREFIX "addl %1, %0\n" ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#ifdef CONFIG_X86_32 ++ "into\n0:\n" ++#else ++ "jno 0f\n" ++ "int $4\n0:\n" ++#endif ++ ".pushsection .fixup,"ax"\n" ++ "1:\n" ++ LOCK_PREFIX "subl %1,%0\n" ++ "jmp 0b\n" ++ ".popsection\n" ++ _ASM_EXTABLE(0b, 1b) ++#endif ++ + : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory"); + } + +diff -urNp linux-2.6.31.1/arch/x86/include/asm/system.h linux-2.6.31.1/arch/x86/include/asm/system.h +--- linux-2.6.31.1/arch/x86/include/asm/system.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/system.h 2009-10-01 20:12:42.000000000 -0400 +@@ -227,7 +227,7 @@ static inline unsigned long get_limit(un + { + unsigned long __limit; + asm("lsll %1,%0" : "=r" (__limit) : "r" (segment)); +- return __limit + 1; ++ return __limit; + } + + static inline void native_clts(void) +@@ -353,6 +353,23 @@ static inline void native_wbinvd(void) + + #define stts() write_cr0(read_cr0() | X86_CR0_TS) + ++#define pax_open_kernel(cr0) \ ++do { \ ++ typecheck(unsigned long, cr0); \ ++ preempt_disable(); \ ++ barrier(); \ ++ cr0 = read_cr0(); \ ++ write_cr0(cr0 & ~X86_CR0_WP); \ ++} while (0) ++ ++#define pax_close_kernel(cr0) \ ++do { \ ++ typecheck(unsigned long, cr0); \ ++ write_cr0(cr0); \ ++ barrier(); \ ++ preempt_enable_no_resched(); \ ++} while (0) ++ + #endif /* __KERNEL__ */ + + static inline void clflush(volatile void *__p) +@@ -367,7 +384,7 @@ void enable_hlt(void); + + void cpu_idle_wait(void); + +-extern unsigned long arch_align_stack(unsigned long sp); ++#define arch_align_stack(x) ((x) & ~0xfUL) + extern void free_init_pages(char *what, unsigned long begin, unsigned long end); + + void default_idle(void); +diff -urNp linux-2.6.31.1/arch/x86/include/asm/uaccess_32.h linux-2.6.31.1/arch/x86/include/asm/uaccess_32.h +--- linux-2.6.31.1/arch/x86/include/asm/uaccess_32.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/uaccess_32.h 2009-10-01 20:12:42.000000000 -0400 +@@ -44,6 +44,9 @@ unsigned long __must_check __copy_from_u + static __always_inline unsigned long __must_check + __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) + { ++ if ((long)n < 0) ++ return n; ++ + if (__builtin_constant_p(n)) { + unsigned long ret; + +@@ -62,6 +65,8 @@ __copy_to_user_inatomic(void __user *to, + return ret; + } + } ++ if (!__builtin_constant_p(n)) ++ check_object_size(from, n, true); + return __copy_to_user_ll(to, from, n); + } + +@@ -89,6 +94,9 @@ __copy_to_user(void __user *to, const vo + static __always_inline unsigned long + __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) + { ++ if ((long)n < 0) ++ return n; ++ + /* Avoid zeroing the tail if the copy fails.. + * If 'n' is constant and 1, 2, or 4, we do still zero on a failure, + * but as the zeroing behaviour is only significant when n is not +@@ -138,6 +146,10 @@ static __always_inline unsigned long + __copy_from_user(void *to, const void __user *from, unsigned long n) + { + might_fault(); ++ ++ if ((long)n < 0) ++ return n; ++ + if (__builtin_constant_p(n)) { + unsigned long ret; + +@@ -153,6 +165,8 @@ __copy_from_user(void *to, const void __ + return ret; + } + } ++ if (!__builtin_constant_p(n)) ++ check_object_size(to, n, false); + return __copy_from_user_ll(to, from, n); + } + +@@ -160,6 +174,10 @@ static __always_inline unsigned long __c + const void __user *from, unsigned long n) + { + might_fault(); ++ ++ if ((long)n < 0) ++ return n; ++ + if (__builtin_constant_p(n)) { + unsigned long ret; + +@@ -182,14 +200,62 @@ static __always_inline unsigned long + __copy_from_user_inatomic_nocache(void *to, const void __user *from, + unsigned long n) + { +- return __copy_from_user_ll_nocache_nozero(to, from, n); ++ if ((long)n < 0) ++ return n; ++ ++ return __copy_from_user_ll_nocache_nozero(to, from, n); ++} ++ ++/** ++ * copy_to_user: - Copy a block of data into user space. ++ * @to: Destination address, in user space. ++ * @from: Source address, in kernel space. ++ * @n: Number of bytes to copy. ++ * ++ * Context: User context only. This function may sleep. ++ * ++ * Copy data from kernel space to user space. ++ * ++ * Returns number of bytes that could not be copied. ++ * On success, this will be zero. ++ */ ++static __always_inline unsigned long __must_check ++copy_to_user(void __user *to, const void *from, unsigned long n) ++{ ++ if (access_ok(VERIFY_WRITE, to, n)) ++ n = __copy_to_user(to, from, n); ++ return n; ++} ++ ++/** ++ * copy_from_user: - Copy a block of data from user space. ++ * @to: Destination address, in kernel space. ++ * @from: Source address, in user space. ++ * @n: Number of bytes to copy. ++ * ++ * Context: User context only. This function may sleep. ++ * ++ * Copy data from user space to kernel space. ++ * ++ * Returns number of bytes that could not be copied. ++ * On success, this will be zero. ++ * ++ * If some data could not be copied, this function will pad the copied ++ * data to the requested size using zero bytes. ++ */ ++static __always_inline unsigned long __must_check ++copy_from_user(void *to, const void __user *from, unsigned long n) ++{ ++ if (access_ok(VERIFY_READ, from, n)) ++ n = __copy_from_user(to, from, n); ++ else if ((long)n > 0) { ++ if (!__builtin_constant_p(n)) ++ check_object_size(to, n, false); ++ memset(to, 0, n); ++ } ++ return n; + } + +-unsigned long __must_check copy_to_user(void __user *to, +- const void *from, unsigned long n); +-unsigned long __must_check copy_from_user(void *to, +- const void __user *from, +- unsigned long n); + long __must_check strncpy_from_user(char *dst, const char __user *src, + long count); + long __must_check __strncpy_from_user(char *dst, +diff -urNp linux-2.6.31.1/arch/x86/include/asm/uaccess_64.h linux-2.6.31.1/arch/x86/include/asm/uaccess_64.h +--- linux-2.6.31.1/arch/x86/include/asm/uaccess_64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/uaccess_64.h 2009-10-01 20:12:42.000000000 -0400 +@@ -10,6 +10,8 @@ + #include <linux/lockdep.h> + #include <asm/page.h> + ++#define set_fs(x) (current_thread_info()->addr_limit = (x)) ++ + /* + * Copy To/From Userspace + */ +@@ -19,20 +21,22 @@ __must_check unsigned long + copy_user_generic(void *to, const void *from, unsigned len); + + __must_check unsigned long +-copy_to_user(void __user *to, const void *from, unsigned len); +-__must_check unsigned long +-copy_from_user(void *to, const void __user *from, unsigned len); +-__must_check unsigned long + copy_in_user(void __user *to, const void __user *from, unsigned len); + + static __always_inline __must_check +-int __copy_from_user(void *dst, const void __user *src, unsigned size) ++unsigned long __copy_from_user(void *dst, const void __user *src, unsigned size) + { +- int ret = 0; ++ unsigned ret = 0; + + might_fault(); +- if (!__builtin_constant_p(size)) ++ ++ if ((int)size < 0) ++ return size; ++ ++ if (!__builtin_constant_p(size)) { ++ check_object_size(dst, size, false); + return copy_user_generic(dst, (__force void *)src, size); ++ } + switch (size) { + case 1:__get_user_asm(*(u8 *)dst, (u8 __user *)src, + ret, "b", "b", "=q", 1); +@@ -70,13 +74,19 @@ int __copy_from_user(void *dst, const vo + } + + static __always_inline __must_check +-int __copy_to_user(void __user *dst, const void *src, unsigned size) ++unsigned long __copy_to_user(void __user *dst, const void *src, unsigned size) + { +- int ret = 0; ++ unsigned ret = 0; + + might_fault(); +- if (!__builtin_constant_p(size)) ++ ++ if ((int)size < 0) ++ return size; ++ ++ if (!__builtin_constant_p(size)) { ++ check_object_size(src, size, true); + return copy_user_generic((__force void *)dst, src, size); ++ } + switch (size) { + case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst, + ret, "b", "b", "iq", 1); +@@ -114,11 +124,39 @@ int __copy_to_user(void __user *dst, con + } + + static __always_inline __must_check +-int __copy_in_user(void __user *dst, const void __user *src, unsigned size) ++unsigned long copy_to_user(void __user *to, const void *from, unsigned len) + { +- int ret = 0; ++ if (access_ok(VERIFY_WRITE, to, len)) ++ len = __copy_to_user(to, from, len); ++ return len; ++} ++ ++static __always_inline __must_check ++unsigned long copy_from_user(void *to, const void __user *from, unsigned len) ++{ ++ if ((int)len < 0) ++ return len; ++ ++ if (access_ok(VERIFY_READ, from, len)) ++ len = __copy_from_user(to, from, len); ++ else if ((int)len > 0) { ++ if (!__builtin_constant_p(len)) ++ check_object_size(to, len, false); ++ memset(to, 0, len); ++ } ++ return len; ++} ++ ++static __always_inline __must_check ++unsigned long __copy_in_user(void __user *dst, const void __user *src, unsigned size) ++{ ++ unsigned ret = 0; + + might_fault(); ++ ++ if ((int)size < 0) ++ return size; ++ + if (!__builtin_constant_p(size)) + return copy_user_generic((__force void *)dst, + (__force void *)src, size); +@@ -179,30 +217,38 @@ __must_check unsigned long __clear_user( + __must_check long __copy_from_user_inatomic(void *dst, const void __user *src, + unsigned size); + +-static __must_check __always_inline int ++static __must_check __always_inline unsigned long + __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size) + { ++ if ((int)size < 0) ++ return size; ++ + return copy_user_generic((__force void *)dst, src, size); + } + +-extern long __copy_user_nocache(void *dst, const void __user *src, ++extern unsigned long __copy_user_nocache(void *dst, const void __user *src, + unsigned size, int zerorest); + +-static inline int +-__copy_from_user_nocache(void *dst, const void __user *src, unsigned size) ++static inline unsigned long __copy_from_user_nocache(void *dst, const void __user *src, unsigned size) + { + might_sleep(); ++ ++ if ((int)size < 0) ++ return size; ++ + return __copy_user_nocache(dst, src, size, 1); + } + +-static inline int +-__copy_from_user_inatomic_nocache(void *dst, const void __user *src, ++static inline unsigned long __copy_from_user_inatomic_nocache(void *dst, const void __user *src, + unsigned size) + { ++ if ((int)size < 0) ++ return size; ++ + return __copy_user_nocache(dst, src, size, 0); + } + +-unsigned long ++extern unsigned long + copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest); + + #endif /* _ASM_X86_UACCESS_64_H */ +diff -urNp linux-2.6.31.1/arch/x86/include/asm/uaccess.h linux-2.6.31.1/arch/x86/include/asm/uaccess.h +--- linux-2.6.31.1/arch/x86/include/asm/uaccess.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/uaccess.h 2009-10-01 20:12:42.000000000 -0400 +@@ -8,8 +8,11 @@ + #include <linux/thread_info.h> + #include <linux/prefetch.h> + #include <linux/string.h> ++#include <linux/sched.h> ++#include <linux/slab.h> + #include <asm/asm.h> + #include <asm/page.h> ++#include <asm/segment.h> + + #define VERIFY_READ 0 + #define VERIFY_WRITE 1 +@@ -29,7 +32,12 @@ + + #define get_ds() (KERNEL_DS) + #define get_fs() (current_thread_info()->addr_limit) ++#ifdef CONFIG_X86_32 ++void __set_fs(mm_segment_t x, int cpu); ++void set_fs(mm_segment_t x); ++#else + #define set_fs(x) (current_thread_info()->addr_limit = (x)) ++#endif + + #define segment_eq(a, b) ((a).seg == (b).seg) + +@@ -77,7 +85,26 @@ + * checks that the pointer is in the user space range - after calling + * this function, memory access functions may still return -EFAULT. + */ +-#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) ++#define access_ok(type, addr, size) \ ++({ \ ++ bool __ret_ao = __range_not_ok(addr, size) == 0; \ ++ unsigned long __addr_ao = (unsigned long)addr & PAGE_MASK; \ ++ unsigned long __end_ao = (unsigned long)addr + size - 1; \ ++ if (__ret_ao && unlikely((__end_ao ^ __addr_ao) & PAGE_MASK)) { \ ++ for (; __addr_ao <= __end_ao; __addr_ao += PAGE_SIZE) { \ ++ char __c_ao; \ ++ if (size > PAGE_SIZE) \ ++ cond_resched(); \ ++ if (__get_user(__c_ao, (char __user *)__addr_ao))\ ++ break; \ ++ if (type != VERIFY_WRITE) \ ++ continue; \ ++ if (__put_user(__c_ao, (char __user *)__addr_ao))\ ++ break; \ ++ } \ ++ } \ ++ __ret_ao; \ ++}) + + /* + * The exception table consists of pairs of addresses: the first is the +@@ -183,13 +210,21 @@ extern int __get_user_bad(void); + asm volatile("call __put_user_" #size : "=a" (__ret_pu) \ + : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") + +- ++#ifdef CONFIG_X86_32 ++#define _ASM_LOAD_USER_DS(ds) "movw %w" #ds ",%%ds\n" ++#define _ASM_LOAD_KERNEL_DS "pushl %%ss; popl %%ds\n" ++#else ++#define _ASM_LOAD_USER_DS(ds) ++#define _ASM_LOAD_KERNEL_DS ++#endif + + #ifdef CONFIG_X86_32 + #define __put_user_asm_u64(x, addr, err, errret) \ +- asm volatile("1: movl %%eax,0(%2)\n" \ +- "2: movl %%edx,4(%2)\n" \ ++ asm volatile(_ASM_LOAD_USER_DS(5) \ ++ "1: movl %%eax,%%ds:0(%2)\n" \ ++ "2: movl %%edx,%%ds:4(%2)\n" \ + "3:\n" \ ++ _ASM_LOAD_KERNEL_DS \ + ".section .fixup,"ax"\n" \ + "4: movl %3,%0\n" \ + " jmp 3b\n" \ +@@ -197,15 +232,18 @@ extern int __get_user_bad(void); + _ASM_EXTABLE(1b, 4b) \ + _ASM_EXTABLE(2b, 4b) \ + : "=r" (err) \ +- : "A" (x), "r" (addr), "i" (errret), "0" (err)) ++ : "A" (x), "r" (addr), "i" (errret), "0" (err), \ ++ "r"(__USER_DS)) + + #define __put_user_asm_ex_u64(x, addr) \ +- asm volatile("1: movl %%eax,0(%1)\n" \ +- "2: movl %%edx,4(%1)\n" \ ++ asm volatile(_ASM_LOAD_USER_DS(2) \ ++ "1: movl %%eax,%%ds:0(%1)\n" \ ++ "2: movl %%edx,%%ds:4(%1)\n" \ + "3:\n" \ ++ _ASM_LOAD_KERNEL_DS \ + _ASM_EXTABLE(1b, 2b - 1b) \ + _ASM_EXTABLE(2b, 3b - 2b) \ +- : : "A" (x), "r" (addr)) ++ : : "A" (x), "r" (addr), "r"(__USER_DS)) + + #define __put_user_x8(x, ptr, __ret_pu) \ + asm volatile("call __put_user_8" : "=a" (__ret_pu) \ +@@ -374,16 +412,18 @@ do { \ + } while (0) + + #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \ +- asm volatile("1: mov"itype" %2,%"rtype"1\n" \ ++ asm volatile(_ASM_LOAD_USER_DS(5) \ ++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \ + "2:\n" \ ++ _ASM_LOAD_KERNEL_DS \ + ".section .fixup,"ax"\n" \ + "3: mov %3,%0\n" \ + " xor"itype" %"rtype"1,%"rtype"1\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(1b, 3b) \ +- : "=r" (err), ltype(x) \ +- : "m" (__m(addr)), "i" (errret), "0" (err)) ++ : "=r" (err), ltype (x) \ ++ : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS)) + + #define __get_user_size_ex(x, ptr, size) \ + do { \ +@@ -407,10 +447,12 @@ do { \ + } while (0) + + #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ +- asm volatile("1: mov"itype" %1,%"rtype"0\n" \ ++ asm volatile(_ASM_LOAD_USER_DS(2) \ ++ "1: mov"itype" %%ds:%1,%"rtype"0\n" \ + "2:\n" \ ++ _ASM_LOAD_KERNEL_DS \ + _ASM_EXTABLE(1b, 2b - 1b) \ +- : ltype(x) : "m" (__m(addr))) ++ : ltype(x) : "m" (__m(addr)), "r"(__USER_DS)) + + #define __put_user_nocheck(x, ptr, size) \ + ({ \ +@@ -438,21 +480,26 @@ struct __large_struct { unsigned long bu + * aliasing issues. + */ + #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ +- asm volatile("1: mov"itype" %"rtype"1,%2\n" \ ++ asm volatile(_ASM_LOAD_USER_DS(5) \ ++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \ + "2:\n" \ ++ _ASM_LOAD_KERNEL_DS \ + ".section .fixup,"ax"\n" \ + "3: mov %3,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(1b, 3b) \ + : "=r"(err) \ +- : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) ++ : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\ ++ "r"(__USER_DS)) + + #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ +- asm volatile("1: mov"itype" %"rtype"0,%1\n" \ ++ asm volatile(_ASM_LOAD_USER_DS(2) \ ++ "1: mov"itype" %"rtype"0,%%ds:%1\n" \ + "2:\n" \ ++ _ASM_LOAD_KERNEL_DS \ + _ASM_EXTABLE(1b, 2b - 1b) \ +- : : ltype(x), "m" (__m(addr))) ++ : : ltype(x), "m" (__m(addr)), "r"(__USER_DS)) + + /* + * uaccess_try and catch +@@ -567,6 +614,7 @@ extern struct movsl_mask { + + #define ARCH_HAS_NOCACHE_UACCESS 1 + ++#define ARCH_HAS_SORT_EXTABLE + #ifdef CONFIG_X86_32 + # include "uaccess_32.h" + #else +diff -urNp linux-2.6.31.1/arch/x86/include/asm/vgtod.h linux-2.6.31.1/arch/x86/include/asm/vgtod.h +--- linux-2.6.31.1/arch/x86/include/asm/vgtod.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/vgtod.h 2009-10-01 20:12:42.000000000 -0400 +@@ -14,6 +14,7 @@ struct vsyscall_gtod_data { + int sysctl_enabled; + struct timezone sys_tz; + struct { /* extract of a clocksource struct */ ++ char name[8]; + cycle_t (*vread)(void); + cycle_t cycle_last; + cycle_t mask; +diff -urNp linux-2.6.31.1/arch/x86/include/asm/vsyscall.h linux-2.6.31.1/arch/x86/include/asm/vsyscall.h +--- linux-2.6.31.1/arch/x86/include/asm/vsyscall.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/include/asm/vsyscall.h 2009-10-01 20:12:42.000000000 -0400 +@@ -15,9 +15,10 @@ enum vsyscall_num { + + #ifdef __KERNEL__ + #include <linux/seqlock.h> ++#include <linux/getcpu.h> ++#include <linux/time.h> + + #define __section_vgetcpu_mode __attribute__ ((unused, __section__ (".vgetcpu_mode"), aligned(16))) +-#define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16))) + + /* Definitions for CONFIG_GENERIC_TIME definitions */ + #define __section_vsyscall_gtod_data __attribute__ \ +@@ -31,7 +32,6 @@ enum vsyscall_num { + #define VGETCPU_LSL 2 + + extern int __vgetcpu_mode; +-extern volatile unsigned long __jiffies; + + /* kernel space (writeable) */ + extern int vgetcpu_mode; +@@ -39,6 +39,9 @@ extern struct timezone sys_tz; + + extern void map_vsyscall(void); + ++extern int vgettimeofday(struct timeval * tv, struct timezone * tz); ++extern time_t vtime(time_t *t); ++extern long vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache); + #endif /* __KERNEL__ */ + + #endif /* _ASM_X86_VSYSCALL_H */ +diff -urNp linux-2.6.31.1/arch/x86/Kconfig linux-2.6.31.1/arch/x86/Kconfig +--- linux-2.6.31.1/arch/x86/Kconfig 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/Kconfig 2009-10-01 20:12:42.000000000 -0400 +@@ -1098,7 +1098,7 @@ config PAGE_OFFSET + hex + default 0xB0000000 if VMSPLIT_3G_OPT + default 0x80000000 if VMSPLIT_2G +- default 0x78000000 if VMSPLIT_2G_OPT ++ default 0x70000000 if VMSPLIT_2G_OPT + default 0x40000000 if VMSPLIT_1G + default 0xC0000000 + depends on X86_32 +@@ -1416,7 +1416,7 @@ config X86_PAT + + config EFI + bool "EFI runtime service support" +- depends on ACPI ++ depends on ACPI && !PAX_KERNEXEC + ---help--- + This enables the kernel to use EFI runtime services that are + available (such as the EFI variable services). +@@ -1602,9 +1602,10 @@ config HOTPLUG_CPU + Say N if you want to disable CPU hotplug. + + config COMPAT_VDSO +- def_bool y ++ def_bool n + prompt "Compat VDSO support" + depends on X86_32 || IA32_EMULATION ++ depends on !PAX_NOEXEC && !PAX_MEMORY_UDEREF + ---help--- + Map the 32-bit VDSO to the predictable old-style address too. + ---help--- +diff -urNp linux-2.6.31.1/arch/x86/Kconfig.cpu linux-2.6.31.1/arch/x86/Kconfig.cpu +--- linux-2.6.31.1/arch/x86/Kconfig.cpu 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/Kconfig.cpu 2009-10-01 20:12:42.000000000 -0400 +@@ -331,7 +331,7 @@ config X86_PPRO_FENCE + + config X86_F00F_BUG + def_bool y +- depends on M586MMX || M586TSC || M586 || M486 || M386 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC + + config X86_WP_WORKS_OK + def_bool y +@@ -351,7 +351,7 @@ config X86_POPAD_OK + + config X86_ALIGNMENT_16 + def_bool y +- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 ++ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 + + config X86_INTEL_USERCOPY + def_bool y +@@ -397,7 +397,7 @@ config X86_CMPXCHG64 + # generates cmov. + config X86_CMOV + def_bool y +- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64) ++ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64) + + config X86_MINIMUM_CPU_FAMILY + int +diff -urNp linux-2.6.31.1/arch/x86/Kconfig.debug linux-2.6.31.1/arch/x86/Kconfig.debug +--- linux-2.6.31.1/arch/x86/Kconfig.debug 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/Kconfig.debug 2009-10-01 20:12:42.000000000 -0400 +@@ -99,7 +99,7 @@ config X86_PTDUMP + config DEBUG_RODATA + bool "Write protect kernel read-only data structures" + default y +- depends on DEBUG_KERNEL ++ depends on DEBUG_KERNEL && BROKEN + ---help--- + Mark the kernel read-only data as write-protected in the pagetables, + in order to catch accidental (and incorrect) writes to such const +diff -urNp linux-2.6.31.1/arch/x86/kernel/acpi/boot.c linux-2.6.31.1/arch/x86/kernel/acpi/boot.c +--- linux-2.6.31.1/arch/x86/kernel/acpi/boot.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/acpi/boot.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1609,7 +1609,7 @@ static struct dmi_system_id __initdata a + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"), + }, + }, +- {} ++ { NULL, NULL, {{0, {0}}}, NULL} + }; + + /* +diff -urNp linux-2.6.31.1/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.31.1/arch/x86/kernel/acpi/realmode/wakeup.S +--- linux-2.6.31.1/arch/x86/kernel/acpi/realmode/wakeup.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/acpi/realmode/wakeup.S 2009-10-01 20:12:42.000000000 -0400 +@@ -104,7 +104,7 @@ _start: + movl %eax, %ecx + orl %edx, %ecx + jz 1f +- movl $0xc0000080, %ecx ++ mov $MSR_EFER, %ecx + wrmsr + 1: + +diff -urNp linux-2.6.31.1/arch/x86/kernel/acpi/sleep.c linux-2.6.31.1/arch/x86/kernel/acpi/sleep.c +--- linux-2.6.31.1/arch/x86/kernel/acpi/sleep.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/acpi/sleep.c 2009-10-01 20:12:42.000000000 -0400 +@@ -11,11 +11,12 @@ + #include <linux/cpumask.h> + #include <asm/segment.h> + #include <asm/desc.h> ++#include <asm/e820.h> + + #include "realmode/wakeup.h" + #include "sleep.h" + +-unsigned long acpi_wakeup_address; ++unsigned long acpi_wakeup_address = 0x2000; + unsigned long acpi_realmode_flags; + + /* address in low memory of the wakeup routine. */ +@@ -37,6 +38,10 @@ int acpi_save_state_mem(void) + { + struct wakeup_header *header; + ++#if defined(CONFIG_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_PAX_KERNEXEC) ++ unsigned long cr0; ++#endif ++ + if (!acpi_realmode) { + printk(KERN_ERR "Could not allocate memory during boot, " + "S3 disabled\n"); +@@ -99,8 +104,18 @@ int acpi_save_state_mem(void) + header->trampoline_segment = setup_trampoline() >> 4; + #ifdef CONFIG_SMP + stack_start.sp = temp_stack + sizeof(temp_stack); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + early_gdt_descr.address = + (unsigned long)get_cpu_gdt_table(smp_processor_id()); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + initial_gs = per_cpu_offset(smp_processor_id()); + #endif + initial_code = (unsigned long)wakeup_long64; +@@ -134,14 +149,8 @@ void __init acpi_reserve_bootmem(void) + return; + } + +- acpi_realmode = (unsigned long)alloc_bootmem_low(WAKEUP_SIZE); +- +- if (!acpi_realmode) { +- printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n"); +- return; +- } +- +- acpi_wakeup_address = virt_to_phys((void *)acpi_realmode); ++ reserve_early(acpi_wakeup_address, acpi_wakeup_address + WAKEUP_SIZE, "ACPI Wakeup Code"); ++ acpi_realmode = (unsigned long)__va(acpi_wakeup_address);; + } + + +diff -urNp linux-2.6.31.1/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.31.1/arch/x86/kernel/acpi/wakeup_32.S +--- linux-2.6.31.1/arch/x86/kernel/acpi/wakeup_32.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/acpi/wakeup_32.S 2009-10-01 20:12:42.000000000 -0400 +@@ -30,13 +30,11 @@ wakeup_pmode_return: + # and restore the stack ... but you need gdt for this to work + movl saved_context_esp, %esp + +- movl %cs:saved_magic, %eax +- cmpl $0x12345678, %eax ++ cmpl $0x12345678, saved_magic + jne bogus_magic + + # jump to place where we left off +- movl saved_eip, %eax +- jmp *%eax ++ jmp *(saved_eip) + + bogus_magic: + jmp bogus_magic +diff -urNp linux-2.6.31.1/arch/x86/kernel/alternative.c linux-2.6.31.1/arch/x86/kernel/alternative.c +--- linux-2.6.31.1/arch/x86/kernel/alternative.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/alternative.c 2009-10-01 20:12:42.000000000 -0400 +@@ -400,7 +400,7 @@ void apply_paravirt(struct paravirt_patc + + BUG_ON(p->len > MAX_PATCH_LEN); + /* prep the buffer with the original instructions */ +- memcpy(insnbuf, p->instr, p->len); ++ memcpy(insnbuf, ktla_ktva(p->instr), p->len); + used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf, + (unsigned long)p->instr, p->len); + +@@ -485,11 +485,26 @@ void __init alternative_instructions(voi + * instructions. And on the local CPU you need to be protected again NMI or MCE + * handlers seeing an inconsistent instruction while you patch. + */ +-void *text_poke_early(void *addr, const void *opcode, size_t len) ++void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len) + { + unsigned long flags; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + local_irq_save(flags); +- memcpy(addr, opcode, len); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ memcpy(ktla_ktva(addr), opcode, len); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + local_irq_restore(flags); + sync_core(); + /* Could also do a CLFLUSH here to speed up CPU recovery; but +@@ -512,35 +527,27 @@ void *text_poke_early(void *addr, const + */ + void *__kprobes text_poke(void *addr, const void *opcode, size_t len) + { +- unsigned long flags; +- char *vaddr; ++ unsigned char *vaddr = ktla_ktva(addr); + struct page *pages[2]; +- int i; ++ size_t i; ++ ++ if (!core_kernel_text((unsigned long)addr) + +- if (!core_kernel_text((unsigned long)addr)) { +- pages[0] = vmalloc_to_page(addr); +- pages[1] = vmalloc_to_page(addr + PAGE_SIZE); ++#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ && (vaddr < MODULES_EXEC_VADDR || MODULES_EXEC_END < vaddr) ++#endif ++ ++ ) { ++ pages[0] = vmalloc_to_page(vaddr); ++ pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE); + } else { +- pages[0] = virt_to_page(addr); ++ pages[0] = virt_to_page(vaddr); + WARN_ON(!PageReserved(pages[0])); +- pages[1] = virt_to_page(addr + PAGE_SIZE); ++ pages[1] = virt_to_page(vaddr + PAGE_SIZE); + } + BUG_ON(!pages[0]); +- local_irq_save(flags); +- set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0])); +- if (pages[1]) +- set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1])); +- vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0); +- memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len); +- clear_fixmap(FIX_TEXT_POKE0); +- if (pages[1]) +- clear_fixmap(FIX_TEXT_POKE1); +- local_flush_tlb(); +- sync_core(); +- /* Could also do a CLFLUSH here to speed up CPU recovery; but +- that causes hangs on some VIA CPUs. */ ++ text_poke_early(addr, opcode, len); + for (i = 0; i < len; i++) +- BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]); +- local_irq_restore(flags); ++ BUG_ON(((char *)vaddr)[i] != ((char *)opcode)[i]); + return addr; + } +diff -urNp linux-2.6.31.1/arch/x86/kernel/apm_32.c linux-2.6.31.1/arch/x86/kernel/apm_32.c +--- linux-2.6.31.1/arch/x86/kernel/apm_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/apm_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -403,7 +403,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq + static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); + static struct apm_user *user_list; + static DEFINE_SPINLOCK(user_list_lock); +-static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } }; ++static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } }; + + static const char driver_version[] = "1.16ac"; /* no spaces */ + +@@ -576,12 +576,25 @@ static long __apm_bios_call(void *_call) + struct desc_struct *gdt; + struct apm_bios_call *call = _call; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + cpu = get_cpu(); + BUG_ON(cpu != 0); + gdt = get_cpu_gdt_table(cpu); + save_desc_40 = gdt[0x40 / 8]; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + gdt[0x40 / 8] = bad_bios_desc; + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + apm_irq_save(flags); + APM_DO_SAVE_SEGS; + apm_bios_call_asm(call->func, call->ebx, call->ecx, +@@ -589,7 +602,17 @@ static long __apm_bios_call(void *_call) + &call->esi); + APM_DO_RESTORE_SEGS; + apm_irq_restore(flags); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + gdt[0x40 / 8] = save_desc_40; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + put_cpu(); + + return call->eax & 0xff; +@@ -652,19 +675,42 @@ static long __apm_bios_call_simple(void + struct desc_struct *gdt; + struct apm_bios_call *call = _call; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + cpu = get_cpu(); + BUG_ON(cpu != 0); + gdt = get_cpu_gdt_table(cpu); + save_desc_40 = gdt[0x40 / 8]; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + gdt[0x40 / 8] = bad_bios_desc; + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + apm_irq_save(flags); + APM_DO_SAVE_SEGS; + error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx, + &call->eax); + APM_DO_RESTORE_SEGS; + apm_irq_restore(flags); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + gdt[0x40 / 8] = save_desc_40; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + put_cpu(); + return error; + } +@@ -967,7 +1013,7 @@ recalc: + + static void apm_power_off(void) + { +- unsigned char po_bios_call[] = { ++ const unsigned char po_bios_call[] = { + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */ + 0x8e, 0xd0, /* movw ax,ss */ + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */ +@@ -1925,7 +1971,10 @@ static const struct file_operations apm_ + static struct miscdevice apm_device = { + APM_MINOR_DEV, + "apm_bios", +- &apm_bios_fops ++ &apm_bios_fops, ++ {NULL, NULL}, ++ NULL, ++ NULL + }; + + +@@ -2246,7 +2295,7 @@ static struct dmi_system_id __initdata a + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, + }, + +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL} + }; + + /* +@@ -2264,6 +2313,10 @@ static int __init apm_init(void) + struct desc_struct *gdt; + int err; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + dmi_check_system(apm_dmi_table); + + if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) { +@@ -2337,9 +2390,18 @@ static int __init apm_init(void) + * This is for buggy BIOS's that refer to (real mode) segment 0x40 + * even though they are called in protected mode. + */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + /* + * Set up the long jump entry point to the APM BIOS, which is called + * from inline assembly. +@@ -2358,6 +2420,11 @@ static int __init apm_init(void) + * code to that CPU. + */ + gdt = get_cpu_gdt_table(0); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + set_base(gdt[APM_CS >> 3], + __va((unsigned long)apm_info.bios.cseg << 4)); + set_base(gdt[APM_CS_16 >> 3], +@@ -2365,6 +2432,10 @@ static int __init apm_init(void) + set_base(gdt[APM_DS >> 3], + __va((unsigned long)apm_info.bios.dseg << 4)); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + proc_create("apm", 0, NULL, &apm_file_ops); + + kapmd_task = kthread_create(apm, NULL, "kapmd"); +diff -urNp linux-2.6.31.1/arch/x86/kernel/asm-offsets_32.c linux-2.6.31.1/arch/x86/kernel/asm-offsets_32.c +--- linux-2.6.31.1/arch/x86/kernel/asm-offsets_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/asm-offsets_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -115,6 +115,7 @@ void foo(void) + OFFSET(PV_CPU_iret, pv_cpu_ops, iret); + OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit); + OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0); ++ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0); + #endif + + #ifdef CONFIG_XEN +diff -urNp linux-2.6.31.1/arch/x86/kernel/asm-offsets_64.c linux-2.6.31.1/arch/x86/kernel/asm-offsets_64.c +--- linux-2.6.31.1/arch/x86/kernel/asm-offsets_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/asm-offsets_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -114,6 +114,7 @@ int main(void) + ENTRY(cr8); + BLANK(); + #undef ENTRY ++ DEFINE(TSS_size, sizeof(struct tss_struct)); + DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist)); + BLANK(); + DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); +diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/common.c linux-2.6.31.1/arch/x86/kernel/cpu/common.c +--- linux-2.6.31.1/arch/x86/kernel/cpu/common.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/cpu/common.c 2009-10-01 20:12:42.000000000 -0400 +@@ -84,60 +84,6 @@ static const struct cpu_dev __cpuinitcon + + static const struct cpu_dev *this_cpu __cpuinitdata = &default_cpu; + +-DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { +-#ifdef CONFIG_X86_64 +- /* +- * We need valid kernel segments for data and code in long mode too +- * IRET will check the segment types kkeil 2000/10/28 +- * Also sysret mandates a special GDT layout +- * +- * TLS descriptors are currently at a different place compared to i386. +- * Hopefully nobody expects them at a fixed place (Wine?) +- */ +- [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, +- [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, +-#else +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } }, +- /* +- * Segments used for calling PnP BIOS have byte granularity. +- * They code segments and data segments have fixed 64k limits, +- * the transfer segment sizes are set at run time. +- */ +- /* 32-bit code */ +- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } }, +- /* 16-bit code */ +- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } }, +- /* 16-bit data */ +- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } }, +- /* 16-bit data */ +- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } }, +- /* 16-bit data */ +- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } }, +- /* +- * The APM segments have byte granularity and their bases +- * are set at run time. All have 64k limits. +- */ +- /* 32-bit code */ +- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } }, +- /* 16-bit code */ +- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } }, +- /* data */ +- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, +- +- [GDT_ENTRY_ESPFIX_SS] = { { { 0x0000ffff, 0x00cf9200 } } }, +- [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, +- GDT_STACK_CANARY_INIT +-#endif +-} }; +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); +- + static int __init x86_xsave_setup(char *s) + { + setup_clear_cpu_cap(X86_FEATURE_XSAVE); +@@ -345,7 +291,7 @@ void switch_to_new_gdt(int cpu) + { + struct desc_ptr gdt_descr; + +- gdt_descr.address = (long)get_cpu_gdt_table(cpu); ++ gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); + gdt_descr.size = GDT_SIZE - 1; + load_gdt(&gdt_descr); + /* Reload the per-cpu base */ +@@ -799,6 +745,10 @@ static void __cpuinit identify_cpu(struc + /* Filter out anything that depends on CPUID levels we don't have */ + filter_cpuid_features(c, true); + ++#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) ++ setup_clear_cpu_cap(X86_FEATURE_SEP); ++#endif ++ + /* If the model name is still unset, do table lookup. */ + if (!c->x86_model_id[0]) { + const char *p; +@@ -982,7 +932,7 @@ static __init int setup_disablecpuid(cha + __setup("clearcpuid=", setup_disablecpuid); + + #ifdef CONFIG_X86_64 +-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; ++struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table }; + + DEFINE_PER_CPU_FIRST(union irq_stack_union, + irq_stack_union) __aligned(PAGE_SIZE); +@@ -1092,7 +1042,7 @@ void __cpuinit cpu_init(void) + int i; + + cpu = stack_smp_processor_id(); +- t = &per_cpu(init_tss, cpu); ++ t = init_tss + cpu; + orig_ist = &per_cpu(orig_ist, cpu); + + #ifdef CONFIG_NUMA +@@ -1190,7 +1140,7 @@ void __cpuinit cpu_init(void) + { + int cpu = smp_processor_id(); + struct task_struct *curr = current; +- struct tss_struct *t = &per_cpu(init_tss, cpu); ++ struct tss_struct *t = init_tss + cpu; + struct thread_struct *thread = &curr->thread; + + if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) { +diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +--- linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2009-10-01 20:12:42.000000000 -0400 +@@ -586,7 +586,7 @@ static const struct dmi_system_id sw_any + DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + #endif + +diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +--- linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2009-10-01 20:12:42.000000000 -0400 +@@ -225,7 +225,7 @@ static struct cpu_model models[] = + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL }, + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL }, + +- { NULL, } ++ { NULL, NULL, 0, NULL} + }; + #undef _BANIAS + #undef BANIAS +diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/intel.c linux-2.6.31.1/arch/x86/kernel/cpu/intel.c +--- linux-2.6.31.1/arch/x86/kernel/cpu/intel.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/cpu/intel.c 2009-10-01 20:12:42.000000000 -0400 +@@ -140,7 +140,7 @@ static void __cpuinit trap_init_f00f_bug + * Update the IDT descriptor and reload the IDT so that + * it uses the read-only mapped virtual address. + */ +- idt_descr.address = fix_to_virt(FIX_F00F_IDT); ++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT); + load_idt(&idt_descr); + } + #endif +diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/Makefile linux-2.6.31.1/arch/x86/kernel/cpu/Makefile +--- linux-2.6.31.1/arch/x86/kernel/cpu/Makefile 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/cpu/Makefile 2009-10-01 20:12:42.000000000 -0400 +@@ -7,10 +7,6 @@ ifdef CONFIG_FUNCTION_TRACER + CFLAGS_REMOVE_common.o = -pg + endif + +-# Make sure load_percpu_segment has no stackprotector +-nostackp := $(call cc-option, -fno-stack-protector) +-CFLAGS_common.o := $(nostackp) +- + obj-y := intel_cacheinfo.o addon_cpuid_features.o + obj-y += proc.o capflags.o powerflags.o common.o + obj-y += vmware.o hypervisor.o +diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/mcheck/mce.c linux-2.6.31.1/arch/x86/kernel/cpu/mcheck/mce.c +--- linux-2.6.31.1/arch/x86/kernel/cpu/mcheck/mce.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/cpu/mcheck/mce.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1370,14 +1370,14 @@ void __cpuinit mcheck_init(struct cpuinf + */ + + static DEFINE_SPINLOCK(mce_state_lock); +-static int open_count; /* #times opened */ ++static atomic_t open_count; /* #times opened */ + static int open_exclu; /* already open exclusive? */ + + static int mce_open(struct inode *inode, struct file *file) + { + spin_lock(&mce_state_lock); + +- if (open_exclu || (open_count && (file->f_flags & O_EXCL))) { ++ if (open_exclu || (atomic_read(&open_count) && (file->f_flags & O_EXCL))) { + spin_unlock(&mce_state_lock); + + return -EBUSY; +@@ -1385,7 +1385,7 @@ static int mce_open(struct inode *inode, + + if (file->f_flags & O_EXCL) + open_exclu = 1; +- open_count++; ++ atomic_inc(&open_count); + + spin_unlock(&mce_state_lock); + +@@ -1396,7 +1396,7 @@ static int mce_release(struct inode *ino + { + spin_lock(&mce_state_lock); + +- open_count--; ++ atomic_dec(&open_count); + open_exclu = 0; + + spin_unlock(&mce_state_lock); +@@ -1536,6 +1536,7 @@ static struct miscdevice mce_log_device + MISC_MCELOG_MINOR, + "mcelog", + &mce_chrdev_ops, ++ {NULL, NULL}, NULL, NULL + }; + + /* +diff -urNp linux-2.6.31.1/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.31.1/arch/x86/kernel/cpu/mtrr/generic.c +--- linux-2.6.31.1/arch/x86/kernel/cpu/mtrr/generic.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/cpu/mtrr/generic.c 2009-10-01 20:12:42.000000000 -0400 +@@ -23,14 +23,14 @@ static struct fixed_range_block fixed_ra + { MSR_MTRRfix64K_00000, 1 }, /* one 64k MTRR */ + { MSR_MTRRfix16K_80000, 2 }, /* two 16k MTRRs */ + { MSR_MTRRfix4K_C0000, 8 }, /* eight 4k MTRRs */ +- {} ++ { 0, 0 } + }; + + static unsigned long smp_changes_mask; + static int mtrr_state_set; + u64 mtrr_tom2; + +-struct mtrr_state_type mtrr_state = {}; ++struct mtrr_state_type mtrr_state; + EXPORT_SYMBOL_GPL(mtrr_state); + + /** +diff -urNp linux-2.6.31.1/arch/x86/kernel/crash.c linux-2.6.31.1/arch/x86/kernel/crash.c +--- linux-2.6.31.1/arch/x86/kernel/crash.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/crash.c 2009-10-01 20:12:42.000000000 -0400 +@@ -42,7 +42,7 @@ static void kdump_nmi_callback(int cpu, + regs = args->regs; + + #ifdef CONFIG_X86_32 +- if (!user_mode_vm(regs)) { ++ if (!user_mode(regs)) { + crash_fixup_ss_esp(&fixed_regs, regs); + regs = &fixed_regs; + } +diff -urNp linux-2.6.31.1/arch/x86/kernel/doublefault_32.c linux-2.6.31.1/arch/x86/kernel/doublefault_32.c +--- linux-2.6.31.1/arch/x86/kernel/doublefault_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/doublefault_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -11,7 +11,7 @@ + + #define DOUBLEFAULT_STACKSIZE (1024) + static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE]; +-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE) ++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2) + + #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM) + +@@ -21,7 +21,7 @@ static void doublefault_fn(void) + unsigned long gdt, tss; + + store_gdt(&gdt_desc); +- gdt = gdt_desc.address; ++ gdt = (unsigned long)gdt_desc.address; + + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); + +@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach + /* 0x2 bit is always set */ + .flags = X86_EFLAGS_SF | 0x2, + .sp = STACK_START, +- .es = __USER_DS, ++ .es = __KERNEL_DS, + .cs = __KERNEL_CS, + .ss = __KERNEL_DS, +- .ds = __USER_DS, ++ .ds = __KERNEL_DS, + .fs = __KERNEL_PERCPU, + + .__cr3 = __pa_nodebug(swapper_pg_dir), +diff -urNp linux-2.6.31.1/arch/x86/kernel/dumpstack_32.c linux-2.6.31.1/arch/x86/kernel/dumpstack_32.c +--- linux-2.6.31.1/arch/x86/kernel/dumpstack_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/dumpstack_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -113,11 +113,12 @@ void show_registers(struct pt_regs *regs + * When in-kernel, we also print out the stack and code at the + * time of the fault.. + */ +- if (!user_mode_vm(regs)) { ++ if (!user_mode(regs)) { + unsigned int code_prologue = code_bytes * 43 / 64; + unsigned int code_len = code_bytes; + unsigned char c; + u8 *ip; ++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]); + + printk(KERN_EMERG "Stack:\n"); + show_stack_log_lvl(NULL, regs, ®s->sp, +@@ -125,10 +126,10 @@ void show_registers(struct pt_regs *regs + + printk(KERN_EMERG "Code: "); + +- ip = (u8 *)regs->ip - code_prologue; ++ ip = (u8 *)regs->ip - code_prologue + cs_base; + if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { + /* try starting at IP */ +- ip = (u8 *)regs->ip; ++ ip = (u8 *)regs->ip + cs_base; + code_len = code_len - code_prologue + 1; + } + for (i = 0; i < code_len; i++, ip++) { +@@ -137,7 +138,7 @@ void show_registers(struct pt_regs *regs + printk(" Bad EIP value."); + break; + } +- if (ip == (u8 *)regs->ip) ++ if (ip == (u8 *)regs->ip + cs_base) + printk("<%02x> ", c); + else + printk("%02x ", c); +@@ -150,6 +151,7 @@ int is_valid_bugaddr(unsigned long ip) + { + unsigned short ud2; + ++ ip = ktla_ktva(ip); + if (ip < PAGE_OFFSET) + return 0; + if (probe_kernel_address((unsigned short *)ip, ud2)) +diff -urNp linux-2.6.31.1/arch/x86/kernel/dumpstack.c linux-2.6.31.1/arch/x86/kernel/dumpstack.c +--- linux-2.6.31.1/arch/x86/kernel/dumpstack.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/dumpstack.c 2009-10-01 20:12:42.000000000 -0400 +@@ -181,7 +181,7 @@ void dump_stack(void) + #endif + + printk("Pid: %d, comm: %.20s %s %s %.*s\n", +- current->pid, current->comm, print_tainted(), ++ task_pid_nr(current), current->comm, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); +@@ -242,7 +242,7 @@ void __kprobes oops_end(unsigned long fl + panic("Fatal exception in interrupt"); + if (panic_on_oops) + panic("Fatal exception"); +- do_exit(signr); ++ do_group_exit(signr); + } + + int __kprobes __die(const char *str, struct pt_regs *regs, long err) +@@ -296,7 +296,7 @@ void die(const char *str, struct pt_regs + unsigned long flags = oops_begin(); + int sig = SIGSEGV; + +- if (!user_mode_vm(regs)) ++ if (!user_mode(regs)) + report_bug(regs->ip, regs); + + if (__die(str, regs, err)) +diff -urNp linux-2.6.31.1/arch/x86/kernel/e820.c linux-2.6.31.1/arch/x86/kernel/e820.c +--- linux-2.6.31.1/arch/x86/kernel/e820.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/e820.c 2009-10-01 20:12:42.000000000 -0400 +@@ -733,7 +733,10 @@ struct early_res { + }; + static struct early_res early_res[MAX_EARLY_RES] __initdata = { + { 0, PAGE_SIZE, "BIOS data page" }, /* BIOS data page */ +- {} ++#ifdef CONFIG_VM86 ++ { PAGE_SIZE, ISA_START_ADDRESS, "V86 mode memory", 1 }, ++#endif ++ { 0, 0, {0}, 0 } + }; + + static int __init find_overlapped_early(u64 start, u64 end) +diff -urNp linux-2.6.31.1/arch/x86/kernel/efi_32.c linux-2.6.31.1/arch/x86/kernel/efi_32.c +--- linux-2.6.31.1/arch/x86/kernel/efi_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/efi_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -38,70 +38,38 @@ + */ + + static unsigned long efi_rt_eflags; +-static pgd_t efi_bak_pg_dir_pointer[2]; ++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS]; + +-void efi_call_phys_prelog(void) ++void __init efi_call_phys_prelog(void) + { +- unsigned long cr4; +- unsigned long temp; + struct desc_ptr gdt_descr; + + local_irq_save(efi_rt_eflags); + +- /* +- * If I don't have PAE, I should just duplicate two entries in page +- * directory. If I have PAE, I just need to duplicate one entry in +- * page directory. +- */ +- cr4 = read_cr4_safe(); + +- if (cr4 & X86_CR4_PAE) { +- efi_bak_pg_dir_pointer[0].pgd = +- swapper_pg_dir[pgd_index(0)].pgd; +- swapper_pg_dir[0].pgd = +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; +- } else { +- efi_bak_pg_dir_pointer[0].pgd = +- swapper_pg_dir[pgd_index(0)].pgd; +- efi_bak_pg_dir_pointer[1].pgd = +- swapper_pg_dir[pgd_index(0x400000)].pgd; +- swapper_pg_dir[pgd_index(0)].pgd = +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; +- temp = PAGE_OFFSET + 0x400000; +- swapper_pg_dir[pgd_index(0x400000)].pgd = +- swapper_pg_dir[pgd_index(temp)].pgd; +- } ++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS); ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY, ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); + + /* + * After the lock is released, the original page table is restored. + */ + __flush_tlb_all(); + +- gdt_descr.address = __pa(get_cpu_gdt_table(0)); ++ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0)); + gdt_descr.size = GDT_SIZE - 1; + load_gdt(&gdt_descr); + } + +-void efi_call_phys_epilog(void) ++void __init efi_call_phys_epilog(void) + { +- unsigned long cr4; + struct desc_ptr gdt_descr; + +- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); ++ gdt_descr.address = get_cpu_gdt_table(0); + gdt_descr.size = GDT_SIZE - 1; + load_gdt(&gdt_descr); + +- cr4 = read_cr4_safe(); +- +- if (cr4 & X86_CR4_PAE) { +- swapper_pg_dir[pgd_index(0)].pgd = +- efi_bak_pg_dir_pointer[0].pgd; +- } else { +- swapper_pg_dir[pgd_index(0)].pgd = +- efi_bak_pg_dir_pointer[0].pgd; +- swapper_pg_dir[pgd_index(0x400000)].pgd = +- efi_bak_pg_dir_pointer[1].pgd; +- } ++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS); + + /* + * After the lock is released, the original page table is restored. +diff -urNp linux-2.6.31.1/arch/x86/kernel/efi_stub_32.S linux-2.6.31.1/arch/x86/kernel/efi_stub_32.S +--- linux-2.6.31.1/arch/x86/kernel/efi_stub_32.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/efi_stub_32.S 2009-10-01 20:12:42.000000000 -0400 +@@ -6,6 +6,7 @@ + */ + + #include <linux/linkage.h> ++#include <linux/init.h> + #include <asm/page_types.h> + + /* +@@ -20,7 +21,7 @@ + * service functions will comply with gcc calling convention, too. + */ + +-.text ++__INIT + ENTRY(efi_call_phys) + /* + * 0. The function can only be called in Linux kernel. So CS has been +@@ -36,9 +37,7 @@ ENTRY(efi_call_phys) + * The mapping of lower virtual memory has been created in prelog and + * epilog. + */ +- movl $1f, %edx +- subl $__PAGE_OFFSET, %edx +- jmp *%edx ++ jmp 1f-__PAGE_OFFSET + 1: + + /* +@@ -47,14 +46,8 @@ ENTRY(efi_call_phys) + * parameter 2, ..., param n. To make things easy, we save the return + * address of efi_call_phys in a global variable. + */ +- popl %edx +- movl %edx, saved_return_addr +- /* get the function pointer into ECX*/ +- popl %ecx +- movl %ecx, efi_rt_function_ptr +- movl $2f, %edx +- subl $__PAGE_OFFSET, %edx +- pushl %edx ++ popl (saved_return_addr) ++ popl (efi_rt_function_ptr) + + /* + * 3. Clear PG bit in %CR0. +@@ -73,9 +66,8 @@ ENTRY(efi_call_phys) + /* + * 5. Call the physical function. + */ +- jmp *%ecx ++ call *(efi_rt_function_ptr-__PAGE_OFFSET) + +-2: + /* + * 6. After EFI runtime service returns, control will return to + * following instruction. We'd better readjust stack pointer first. +@@ -88,35 +80,28 @@ ENTRY(efi_call_phys) + movl %cr0, %edx + orl $0x80000000, %edx + movl %edx, %cr0 +- jmp 1f +-1: ++ + /* + * 8. Now restore the virtual mode from flat mode by + * adding EIP with PAGE_OFFSET. + */ +- movl $1f, %edx +- jmp *%edx ++ jmp 1f+__PAGE_OFFSET + 1: + + /* + * 9. Balance the stack. And because EAX contain the return value, + * we'd better not clobber it. + */ +- leal efi_rt_function_ptr, %edx +- movl (%edx), %ecx +- pushl %ecx ++ pushl (efi_rt_function_ptr) + + /* +- * 10. Push the saved return address onto the stack and return. ++ * 10. Return to the saved return address. + */ +- leal saved_return_addr, %edx +- movl (%edx), %ecx +- pushl %ecx +- ret ++ jmpl *(saved_return_addr) + ENDPROC(efi_call_phys) + .previous + +-.data ++__INITDATA + saved_return_addr: + .long 0 + efi_rt_function_ptr: +diff -urNp linux-2.6.31.1/arch/x86/kernel/entry_32.S linux-2.6.31.1/arch/x86/kernel/entry_32.S +--- linux-2.6.31.1/arch/x86/kernel/entry_32.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/entry_32.S 2009-10-01 20:12:42.000000000 -0400 +@@ -191,7 +191,7 @@ + + #endif /* CONFIG_X86_32_LAZY_GS */ + +-.macro SAVE_ALL ++.macro __SAVE_ALL _DS + cld + PUSH_GS + pushl %fs +@@ -224,7 +224,7 @@ + pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 +- movl $(__USER_DS), %edx ++ movl $_DS, %edx + movl %edx, %ds + movl %edx, %es + movl $(__KERNEL_PERCPU), %edx +@@ -232,6 +232,21 @@ + SET_KERNEL_GS %edx + .endm + ++.macro SAVE_ALL ++#ifdef CONFIG_PAX_KERNEXEC ++ __SAVE_ALL __KERNEL_DS ++ GET_CR0_INTO_EDX; ++ movl %edx, %esi; ++ orl $X86_CR0_WP, %edx; ++ xorl %edx, %esi; ++ SET_CR0_FROM_EDX ++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) ++ __SAVE_ALL __KERNEL_DS ++#else ++ __SAVE_ALL __USER_DS ++#endif ++.endm ++ + .macro RESTORE_INT_REGS + popl %ebx + CFI_ADJUST_CFA_OFFSET -4 +@@ -329,6 +344,11 @@ ENTRY(ret_from_fork) + CFI_ADJUST_CFA_OFFSET 4 + popfl + CFI_ADJUST_CFA_OFFSET -4 ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ xorl %esi, %esi ++#endif ++ + jmp syscall_exit + CFI_ENDPROC + END(ret_from_fork) +@@ -352,7 +372,17 @@ check_userspace: + movb PT_CS(%esp), %al + andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax + cmpl $USER_RPL, %eax ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ jae resume_userspace ++ ++ GET_CR0_INTO_EDX ++ xorl %esi, %edx ++ SET_CR0_FROM_EDX ++ jmp resume_kernel ++#else + jb resume_kernel # not returning to v8086 or userspace ++#endif + + ENTRY(resume_userspace) + LOCKDEP_SYS_EXIT +@@ -414,10 +444,9 @@ sysenter_past_esp: + /*CFI_REL_OFFSET cs, 0*/ + /* + * Push current_thread_info()->sysenter_return to the stack. +- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words +- * pushed above; +8 corresponds to copy_thread's esp0 setting. + */ +- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) ++ GET_THREAD_INFO(%ebp) ++ pushl TI_sysenter_return(%ebp) + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET eip, 0 + +@@ -430,9 +459,19 @@ sysenter_past_esp: + * Load the potential sixth argument from user stack. + * Careful about security. + */ ++ movl PT_OLDESP(%esp),%ebp ++ ++#ifdef CONFIG_PAX_MEMORY_UDEREF ++ mov PT_OLDSS(%esp),%ds ++1: movl %ds:(%ebp),%ebp ++ push %ss ++ pop %ds ++#else + cmpl $__PAGE_OFFSET-3,%ebp + jae syscall_fault + 1: movl (%ebp),%ebp ++#endif ++ + movl %ebp,PT_EBP(%esp) + .section __ex_table,"a" + .align 4 +@@ -455,12 +494,23 @@ sysenter_do_call: + testl $_TIF_ALLWORK_MASK, %ecx + jne sysexit_audit + sysenter_exit: ++ ++#ifdef CONFIG_PAX_RANDKSTACK ++ pushl %eax ++ CFI_ADJUST_CFA_OFFSET 4 ++ call pax_randomize_kstack ++ popl %eax ++ CFI_ADJUST_CFA_OFFSET -4 ++#endif ++ + /* if something modifies registers it must also disable sysexit */ + movl PT_EIP(%esp), %edx + movl PT_OLDESP(%esp), %ecx + xorl %ebp,%ebp + TRACE_IRQS_ON + 1: mov PT_FS(%esp), %fs ++2: mov PT_DS(%esp), %ds ++3: mov PT_ES(%esp), %es + PTGS_TO_GS + ENABLE_INTERRUPTS_SYSEXIT + +@@ -504,11 +554,17 @@ sysexit_audit: + + CFI_ENDPROC + .pushsection .fixup,"ax" +-2: movl $0,PT_FS(%esp) ++4: movl $0,PT_FS(%esp) ++ jmp 1b ++5: movl $0,PT_DS(%esp) ++ jmp 1b ++6: movl $0,PT_ES(%esp) + jmp 1b + .section __ex_table,"a" + .align 4 +- .long 1b,2b ++ .long 1b,4b ++ .long 2b,5b ++ .long 3b,6b + .popsection + PTGS_TO_GS_EX + ENDPROC(ia32_sysenter_target) +@@ -538,6 +594,10 @@ syscall_exit: + testl $_TIF_ALLWORK_MASK, %ecx # current->work + jne syscall_exit_work + ++#ifdef CONFIG_PAX_RANDKSTACK ++ call pax_randomize_kstack ++#endif ++ + restore_all: + TRACE_IRQS_IRET + restore_all_notrace: +@@ -602,7 +662,13 @@ ldt_ss: + mov PT_OLDESP(%esp), %eax /* load userspace esp */ + mov %dx, %ax /* eax: new kernel esp */ + sub %eax, %edx /* offset (low word is 0) */ +- PER_CPU(gdt_page, %ebx) ++#ifdef CONFIG_SMP ++ movl PER_CPU_VAR(cpu_number), %ebx ++ shll $PAGE_SHIFT_asm, %ebx ++ addl $cpu_gdt_table, %ebx ++#else ++ movl $cpu_gdt_table, %ebx ++#endif + shr $16, %edx + mov %dl, GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx) /* bits 16..23 */ + mov %dh, GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx) /* bits 24..31 */ +@@ -642,25 +708,19 @@ work_resched: + + work_notifysig: # deal with pending signals and + # notify-resume requests ++ movl %esp, %eax + #ifdef CONFIG_VM86 + testl $X86_EFLAGS_VM, PT_EFLAGS(%esp) +- movl %esp, %eax +- jne work_notifysig_v86 # returning to kernel-space or ++ jz 1f # returning to kernel-space or + # vm86-space +- xorl %edx, %edx +- call do_notify_resume +- jmp resume_userspace_sig + +- ALIGN +-work_notifysig_v86: + pushl %ecx # save ti_flags for do_notify_resume + CFI_ADJUST_CFA_OFFSET 4 + call save_v86_state # %eax contains pt_regs pointer + popl %ecx + CFI_ADJUST_CFA_OFFSET -4 + movl %eax, %esp +-#else +- movl %esp, %eax ++1: + #endif + xorl %edx, %edx + call do_notify_resume +@@ -695,6 +755,10 @@ END(syscall_exit_work) + + RING0_INT_FRAME # can't unwind into user space anyway + syscall_fault: ++#ifdef CONFIG_PAX_MEMORY_UDEREF ++ push %ss ++ pop %ds ++#endif + GET_THREAD_INFO(%ebp) + movl $-EFAULT,PT_EAX(%esp) + jmp resume_userspace +@@ -735,7 +799,13 @@ PTREGSCALL(vm86old) + * normal stack and adjusts ESP with the matching offset. + */ + /* fixup the stack */ +- PER_CPU(gdt_page, %ebx) ++#ifdef CONFIG_SMP ++ movl PER_CPU_VAR(cpu_number), %ebx ++ shll $PAGE_SHIFT_asm, %ebx ++ addl $cpu_gdt_table, %ebx ++#else ++ movl $cpu_gdt_table, %ebx ++#endif + mov GDT_ENTRY_ESPFIX_SS * 8 + 4(%ebx), %al /* bits 16..23 */ + mov GDT_ENTRY_ESPFIX_SS * 8 + 7(%ebx), %ah /* bits 24..31 */ + shl $16, %eax +@@ -1198,7 +1268,6 @@ return_to_handler: + ret + #endif + +-.section .rodata,"a" + #include "syscall_table_32.S" + + syscall_table_size=(.-sys_call_table) +@@ -1250,12 +1319,21 @@ error_code: + movl %ecx, %fs + UNWIND_ESPFIX_STACK + GS_TO_REG %ecx ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ GET_CR0_INTO_EDX ++ movl %edx, %esi ++ orl $X86_CR0_WP, %edx ++ xorl %edx, %esi ++ SET_CR0_FROM_EDX ++#endif ++ + movl PT_GS(%esp), %edi # get the function address + movl PT_ORIG_EAX(%esp), %edx # get the error code + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart + REG_TO_PTGS %ecx + SET_KERNEL_GS %ecx +- movl $(__USER_DS), %ecx ++ movl $(__KERNEL_DS), %ecx + movl %ecx, %ds + movl %ecx, %es + TRACE_IRQS_OFF +@@ -1351,6 +1429,13 @@ nmi_stack_correct: + xorl %edx,%edx # zero error code + movl %esp,%eax # pt_regs pointer + call do_nmi ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ GET_CR0_INTO_EDX ++ xorl %esi, %edx ++ SET_CR0_FROM_EDX ++#endif ++ + jmp restore_all_notrace + CFI_ENDPROC + +@@ -1391,6 +1476,13 @@ nmi_espfix_stack: + FIXUP_ESPFIX_STACK # %eax == %esp + xorl %edx,%edx # zero error code + call do_nmi ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ GET_CR0_INTO_EDX ++ xorl %esi, %edx ++ SET_CR0_FROM_EDX ++#endif ++ + RESTORE_REGS + lss 12+4(%esp), %esp # back to espfix stack + CFI_ADJUST_CFA_OFFSET -24 +diff -urNp linux-2.6.31.1/arch/x86/kernel/entry_64.S linux-2.6.31.1/arch/x86/kernel/entry_64.S +--- linux-2.6.31.1/arch/x86/kernel/entry_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/entry_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -1074,7 +1074,12 @@ ENTRY(\sym) + TRACE_IRQS_OFF + movq %rsp,%rdi /* pt_regs pointer */ + xorl %esi,%esi /* no error code */ +- PER_CPU(init_tss, %rbp) ++#ifdef CONFIG_SMP ++ imul $TSS_size, PER_CPU_VAR(cpu_number), %ebp ++ lea init_tss(%rbp), %rbp ++#else ++ lea init_tss(%rip), %rbp ++#endif + subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) + call \do_sym + addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) +diff -urNp linux-2.6.31.1/arch/x86/kernel/ftrace.c linux-2.6.31.1/arch/x86/kernel/ftrace.c +--- linux-2.6.31.1/arch/x86/kernel/ftrace.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/ftrace.c 2009-10-01 20:12:42.000000000 -0400 +@@ -284,9 +284,9 @@ int ftrace_update_ftrace_func(ftrace_fun + unsigned char old[MCOUNT_INSN_SIZE], *new; + int ret; + +- memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); ++ memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE); + new = ftrace_call_replace(ip, (unsigned long)func); +- ret = ftrace_modify_code(ip, old, new); ++ ret = ftrace_modify_code(ktla_ktva(ip), old, new); + + return ret; + } +diff -urNp linux-2.6.31.1/arch/x86/kernel/head32.c linux-2.6.31.1/arch/x86/kernel/head32.c +--- linux-2.6.31.1/arch/x86/kernel/head32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/head32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -13,12 +13,13 @@ + #include <asm/e820.h> + #include <asm/bios_ebda.h> + #include <asm/trampoline.h> ++#include <asm/boot.h> + + void __init i386_start_kernel(void) + { + reserve_trampoline_memory(); + +- reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); ++ reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&__bss_stop), "TEXT DATA BSS"); + + #ifdef CONFIG_BLK_DEV_INITRD + /* Reserve INITRD */ +diff -urNp linux-2.6.31.1/arch/x86/kernel/head_32.S linux-2.6.31.1/arch/x86/kernel/head_32.S +--- linux-2.6.31.1/arch/x86/kernel/head_32.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/head_32.S 2009-10-01 20:12:42.000000000 -0400 +@@ -19,6 +19,7 @@ + #include <asm/setup.h> + #include <asm/processor-flags.h> + #include <asm/percpu.h> ++#include <asm/msr-index.h> + + /* Physical address */ + #define pa(X) ((X) - __PAGE_OFFSET) +@@ -52,11 +53,7 @@ + * and small than max_low_pfn, otherwise will waste some page table entries + */ + +-#if PTRS_PER_PMD > 1 +-#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD) +-#else +-#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) +-#endif ++#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PTE) + + /* Enough space to fit pagetables for the low memory linear map */ + MAPPING_BEYOND_END = \ +@@ -73,6 +70,12 @@ INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_P + RESERVE_BRK(pagetables, INIT_MAP_SIZE) + + /* ++ * Real beginning of normal "text" segment ++ */ ++ENTRY(stext) ++ENTRY(_stext) ++ ++/* + * 32-bit kernel entrypoint; only used by the boot CPU. On entry, + * %esi points to the real-mode code as a 32-bit pointer. + * CS and DS must be 4 GB flat segments, but we don't depend on +@@ -80,6 +83,13 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE) + * can. + */ + .section .text.head,"ax",@progbits ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ jmp startup_32 ++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */ ++.fill PAGE_SIZE-5,1,0xcc ++#endif ++ + ENTRY(startup_32) + /* test KEEP_SEGMENTS flag to see if the bootloader is asking + us to not reload segments */ +@@ -97,6 +107,48 @@ ENTRY(startup_32) + movl %eax,%gs + 2: + ++#ifdef CONFIG_SMP ++ movl $pa(cpu_gdt_table),%edi ++ movl $__per_cpu_load,%eax ++ movw %ax,__KERNEL_PERCPU + 2(%edi) ++ rorl $16,%eax ++ movb %al,__KERNEL_PERCPU + 4(%edi) ++ movb %ah,__KERNEL_PERCPU + 7(%edi) ++ movl $__per_cpu_end - 1,%eax ++ subl $__per_cpu_load,%eax ++ movw %ax,__KERNEL_PERCPU + 0(%edi) ++#endif ++ ++#ifdef CONFIG_PAX_MEMORY_UDEREF ++ movl $NR_CPUS,%ecx ++ movl $pa(cpu_gdt_table),%edi ++1: ++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi) ++ addl $PAGE_SIZE_asm,%edi ++ loop 1b ++#endif ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ movl $pa(boot_gdt),%edi ++ movl $__LOAD_PHYSICAL_ADDR + __PAGE_OFFSET,%eax ++ movw %ax,__BOOT_CS + 2(%edi) ++ rorl $16,%eax ++ movb %al,__BOOT_CS + 4(%edi) ++ movb %ah,__BOOT_CS + 7(%edi) ++ rorl $16,%eax ++ ++ movl $NR_CPUS,%ecx ++ movl $pa(cpu_gdt_table),%edi ++1: ++ movw %ax,__KERNEL_CS + 2(%edi) ++ rorl $16,%eax ++ movb %al,__KERNEL_CS + 4(%edi) ++ movb %ah,__KERNEL_CS + 7(%edi) ++ rorl $16,%eax ++ addl $PAGE_SIZE_asm,%edi ++ loop 1b ++#endif ++ + /* + * Clear BSS first so that there are no surprises... + */ +@@ -140,9 +192,7 @@ ENTRY(startup_32) + cmpl $num_subarch_entries, %eax + jae bad_subarch + +- movl pa(subarch_entries)(,%eax,4), %eax +- subl $__PAGE_OFFSET, %eax +- jmp *%eax ++ jmp *pa(subarch_entries)(,%eax,4) + + bad_subarch: + WEAK(lguest_entry) +@@ -154,9 +204,9 @@ WEAK(xen_entry) + __INITDATA + + subarch_entries: +- .long default_entry /* normal x86/PC */ +- .long lguest_entry /* lguest hypervisor */ +- .long xen_entry /* Xen hypervisor */ ++ .long pa(default_entry) /* normal x86/PC */ ++ .long pa(lguest_entry) /* lguest hypervisor */ ++ .long pa(xen_entry) /* Xen hypervisor */ + num_subarch_entries = (. - subarch_entries) / 4 + .previous + #endif /* CONFIG_PARAVIRT */ +@@ -217,8 +267,11 @@ default_entry: + movl %eax, pa(max_pfn_mapped) + + /* Do early initialization of the fixmap area */ +- movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax +- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8) ++#ifdef CONFIG_COMPAT_VDSO ++ movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(swapper_pg_pmd+0x1000*KPMDS-8) ++#else ++ movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8) ++#endif + #else /* Not PAE */ + + page_pde_offset = (__PAGE_OFFSET >> 20); +@@ -248,8 +301,11 @@ page_pde_offset = (__PAGE_OFFSET >> 20); + movl %eax, pa(max_pfn_mapped) + + /* Do early initialization of the fixmap area */ +- movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax +- movl %eax,pa(swapper_pg_dir+0xffc) ++#ifdef CONFIG_COMPAT_VDSO ++ movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(swapper_pg_dir+0xffc) ++#else ++ movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,pa(swapper_pg_dir+0xffc) ++#endif + #endif + jmp 3f + /* +@@ -296,6 +352,7 @@ ENTRY(startup_32_smp) + orl %edx,%eax + movl %eax,%cr4 + ++#ifdef CONFIG_X86_PAE + btl $5, %eax # check if PAE is enabled + jnc 6f + +@@ -311,13 +368,16 @@ ENTRY(startup_32_smp) + jnc 6f + + /* Setup EFER (Extended Feature Enable Register) */ +- movl $0xc0000080, %ecx ++ movl $MSR_EFER, %ecx + rdmsr + + btsl $11, %eax + /* Make changes effective */ + wrmsr + ++ btsl $_PAGE_BIT_NX-32,pa(__supported_pte_mask+4) ++ movl $1,pa(nx_enabled) ++#endif + 6: + + /* +@@ -343,9 +403,7 @@ ENTRY(startup_32_smp) + + #ifdef CONFIG_SMP + cmpb $0, ready +- jz 1f /* Initial CPU cleans BSS */ +- jmp checkCPUtype +-1: ++ jnz checkCPUtype /* Initial CPU cleans BSS */ + #endif /* CONFIG_SMP */ + + /* +@@ -423,7 +481,7 @@ is386: movl $2,%ecx # set MP + 1: movl $(__KERNEL_DS),%eax # reload all the segment registers + movl %eax,%ss # after changing gdt. + +- movl $(__USER_DS),%eax # DS/ES contains default USER segment ++# movl $(__KERNEL_DS),%eax # DS/ES contains default KERNEL segment + movl %eax,%ds + movl %eax,%es + +@@ -437,8 +495,11 @@ is386: movl $2,%ecx # set MP + */ + cmpb $0,ready + jne 1f +- movl $per_cpu__gdt_page,%eax ++ movl $cpu_gdt_table,%eax + movl $per_cpu__stack_canary,%ecx ++#ifdef CONFIG_SMP ++ addl $__per_cpu_load,%ecx ++#endif + movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax) + shrl $16, %ecx + movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax) +@@ -456,10 +517,6 @@ is386: movl $2,%ecx # set MP + #ifdef CONFIG_SMP + movb ready, %cl + movb $1, ready +- cmpb $0,%cl # the first CPU calls start_kernel +- je 1f +- movl (stack_start), %esp +-1: + #endif /* CONFIG_SMP */ + jmp *(initial_code) + +@@ -545,22 +602,22 @@ early_page_fault: + jmp early_fault + + early_fault: +- cld + #ifdef CONFIG_PRINTK ++ cmpl $1,%ss:early_recursion_flag ++ je hlt_loop ++ incl %ss:early_recursion_flag ++ cld + pusha + movl $(__KERNEL_DS),%eax + movl %eax,%ds + movl %eax,%es +- cmpl $2,early_recursion_flag +- je hlt_loop +- incl early_recursion_flag + movl %cr2,%eax + pushl %eax + pushl %edx /* trapno */ + pushl $fault_msg + call printk ++; call dump_stack + #endif +- call dump_stack + hlt_loop: + hlt + jmp hlt_loop +@@ -568,8 +625,11 @@ hlt_loop: + /* This is the default interrupt "handler" :-) */ + ALIGN + ignore_int: +- cld + #ifdef CONFIG_PRINTK ++ cmpl $2,%ss:early_recursion_flag ++ je hlt_loop ++ incl %ss:early_recursion_flag ++ cld + pushl %eax + pushl %ecx + pushl %edx +@@ -578,9 +638,6 @@ ignore_int: + movl $(__KERNEL_DS),%eax + movl %eax,%ds + movl %eax,%es +- cmpl $2,early_recursion_flag +- je hlt_loop +- incl early_recursion_flag + pushl 16(%esp) + pushl 24(%esp) + pushl 32(%esp) +@@ -607,27 +664,37 @@ ENTRY(initial_code) + /* + * BSS section + */ +-.section ".bss.page_aligned","wa" +- .align PAGE_SIZE_asm + #ifdef CONFIG_X86_PAE ++.section .swapper_pg_pmd,"a",@progbits + swapper_pg_pmd: + .fill 1024*KPMDS,4,0 + #else ++.section .swapper_pg_dir,"a",@progbits + ENTRY(swapper_pg_dir) + .fill 1024,4,0 + #endif ++ + swapper_pg_fixmap: + .fill 1024,4,0 ++ ++.section .empty_zero_page,"a",@progbits + ENTRY(empty_zero_page) + .fill 4096,1,0 + + /* ++ * The IDT has to be page-aligned to simplify the Pentium ++ * F0 0F bug workaround.. We have a special link segment ++ * for this. ++ */ ++.section .idt,"a",@progbits ++ENTRY(idt_table) ++ .fill 256,8,0 ++ ++/* + * This starts the data section. + */ + #ifdef CONFIG_X86_PAE +-.section ".data.page_aligned","wa" +- /* Page-aligned for the benefit of paravirt? */ +- .align PAGE_SIZE_asm ++.section .swapper_pg_dir,"a",@progbits + ENTRY(swapper_pg_dir) + .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */ + # if KPMDS == 3 +@@ -650,11 +717,12 @@ ENTRY(swapper_pg_dir) + + .data + ENTRY(stack_start) +- .long init_thread_union+THREAD_SIZE ++ .long init_thread_union+THREAD_SIZE-8 + .long __BOOT_DS + + ready: .byte 0 + ++.section .rodata,"a",@progbits + early_recursion_flag: + .long 0 + +@@ -690,7 +758,7 @@ fault_msg: + .word 0 # 32 bit align gdt_desc.address + boot_gdt_descr: + .word __BOOT_DS+7 +- .long boot_gdt - __PAGE_OFFSET ++ .long pa(boot_gdt) + + .word 0 # 32-bit align idt_desc.address + idt_descr: +@@ -701,7 +769,7 @@ idt_descr: + .word 0 # 32 bit align gdt_desc.address + ENTRY(early_gdt_descr) + .word GDT_ENTRIES*8-1 +- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */ ++ .long cpu_gdt_table /* Overwritten for secondary CPUs */ + + /* + * The boot_gdt must mirror the equivalent in setup.S and is +@@ -710,5 +778,59 @@ ENTRY(early_gdt_descr) + .align L1_CACHE_BYTES + ENTRY(boot_gdt) + .fill GDT_ENTRY_BOOT_CS,8,0 +- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ +- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ ++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */ ++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */ ++ ++ .align PAGE_SIZE_asm ++ENTRY(cpu_gdt_table) ++ .rept NR_CPUS ++ .quad 0x0000000000000000 /* NULL descriptor */ ++ .quad 0x0000000000000000 /* 0x0b reserved */ ++ .quad 0x0000000000000000 /* 0x13 reserved */ ++ .quad 0x0000000000000000 /* 0x1b reserved */ ++ .quad 0x0000000000000000 /* 0x20 unused */ ++ .quad 0x0000000000000000 /* 0x28 unused */ ++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */ ++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */ ++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */ ++ .quad 0x0000000000000000 /* 0x4b reserved */ ++ .quad 0x0000000000000000 /* 0x53 reserved */ ++ .quad 0x0000000000000000 /* 0x5b reserved */ ++ ++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */ ++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */ ++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */ ++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */ ++ ++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */ ++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */ ++ ++ /* ++ * Segments used for calling PnP BIOS have byte granularity. ++ * The code segments and data segments have fixed 64k limits, ++ * the transfer segment sizes are set at run time. ++ */ ++ .quad 0x00409b000000ffff /* 0x90 32-bit code */ ++ .quad 0x00009b000000ffff /* 0x98 16-bit code */ ++ .quad 0x000093000000ffff /* 0xa0 16-bit data */ ++ .quad 0x0000930000000000 /* 0xa8 16-bit data */ ++ .quad 0x0000930000000000 /* 0xb0 16-bit data */ ++ ++ /* ++ * The APM segments have byte granularity and their bases ++ * are set at run time. All have 64k limits. ++ */ ++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */ ++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */ ++ .quad 0x004093000000ffff /* 0xc8 APM DS data */ ++ ++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */ ++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */ ++ .quad 0x0040930000000018 /* 0xe0 - STACK_CANARY */ ++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_CS */ ++ .quad 0x0000000000000000 /* 0xf0 - PCIBIOS_DS */ ++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ ++ ++ /* Be sure this is zeroed to avoid false validations in Xen */ ++ .fill PAGE_SIZE_asm - GDT_SIZE,1,0 ++ .endr +diff -urNp linux-2.6.31.1/arch/x86/kernel/head_64.S linux-2.6.31.1/arch/x86/kernel/head_64.S +--- linux-2.6.31.1/arch/x86/kernel/head_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/head_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -38,6 +38,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET + L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET) + L4_START_KERNEL = pgd_index(__START_KERNEL_map) + L3_START_KERNEL = pud_index(__START_KERNEL_map) ++L4_VMALLOC_START = pgd_index(VMALLOC_START) ++L3_VMALLOC_START = pud_index(VMALLOC_START) ++L4_VMEMMAP_START = pgd_index(VMEMMAP_START) ++L3_VMEMMAP_START = pud_index(VMEMMAP_START) + + .text + .section .text.head +@@ -85,35 +89,22 @@ startup_64: + */ + addq %rbp, init_level4_pgt + 0(%rip) + addq %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip) ++ addq %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip) ++ addq %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip) + addq %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip) + + addq %rbp, level3_ident_pgt + 0(%rip) ++ addq %rbp, level3_ident_pgt + 8(%rip) ++ addq %rbp, level3_ident_pgt + 16(%rip) ++ addq %rbp, level3_ident_pgt + 24(%rip) + +- addq %rbp, level3_kernel_pgt + (510*8)(%rip) +- addq %rbp, level3_kernel_pgt + (511*8)(%rip) ++ addq %rbp, level3_vmemmap_pgt + (L3_VMEMMAP_START*8)(%rip) + +- addq %rbp, level2_fixmap_pgt + (506*8)(%rip) ++ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip) ++ addq %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip) + +- /* Add an Identity mapping if I am above 1G */ +- leaq _text(%rip), %rdi +- andq $PMD_PAGE_MASK, %rdi +- +- movq %rdi, %rax +- shrq $PUD_SHIFT, %rax +- andq $(PTRS_PER_PUD - 1), %rax +- jz ident_complete +- +- leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx +- leaq level3_ident_pgt(%rip), %rbx +- movq %rdx, 0(%rbx, %rax, 8) +- +- movq %rdi, %rax +- shrq $PMD_SHIFT, %rax +- andq $(PTRS_PER_PMD - 1), %rax +- leaq __PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx +- leaq level2_spare_pgt(%rip), %rbx +- movq %rdx, 0(%rbx, %rax, 8) +-ident_complete: ++ addq %rbp, level2_fixmap_pgt + (506*8)(%rip) ++ addq %rbp, level2_fixmap_pgt + (507*8)(%rip) + + /* + * Fixup the kernel text+data virtual addresses. Note that +@@ -187,6 +178,10 @@ ENTRY(secondary_startup_64) + btl $20,%edi /* No Execute supported? */ + jnc 1f + btsl $_EFER_NX, %eax ++ leaq init_level4_pgt(%rip), %rdi ++ btsq $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi) ++ btsq $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi) ++ btsq $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi) + 1: wrmsr /* Make changes effective */ + + /* Setup cr0 */ +@@ -262,16 +257,16 @@ ENTRY(secondary_startup_64) + .quad x86_64_start_kernel + ENTRY(initial_gs) + .quad INIT_PER_CPU_VAR(irq_stack_union) +- __FINITDATA + + ENTRY(stack_start) + .quad init_thread_union+THREAD_SIZE-8 + .word 0 ++ __FINITDATA + + bad_address: + jmp bad_address + +- .section ".init.text","ax" ++ __INIT + #ifdef CONFIG_EARLY_PRINTK + .globl early_idt_handlers + early_idt_handlers: +@@ -316,18 +311,23 @@ ENTRY(early_idt_handler) + #endif /* EARLY_PRINTK */ + 1: hlt + jmp 1b ++ .previous + + #ifdef CONFIG_EARLY_PRINTK ++ __INITDATA + early_recursion_flag: + .long 0 ++ .previous + ++ .section .rodata,"a",@progbits + early_idt_msg: + .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n" + early_idt_ripmsg: + .asciz "RIP %s\n" +-#endif /* CONFIG_EARLY_PRINTK */ + .previous ++#endif /* CONFIG_EARLY_PRINTK */ + ++ .section .rodata,"a",@progbits + #define NEXT_PAGE(name) \ + .balign PAGE_SIZE; \ + ENTRY(name) +@@ -350,13 +350,31 @@ NEXT_PAGE(init_level4_pgt) + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .org init_level4_pgt + L4_PAGE_OFFSET*8, 0 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE ++ .org init_level4_pgt + L4_VMALLOC_START*8, 0 ++ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE ++ .org init_level4_pgt + L4_VMEMMAP_START*8, 0 ++ .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE + .org init_level4_pgt + L4_START_KERNEL*8, 0 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + + NEXT_PAGE(level3_ident_pgt) + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE ++#ifdef CONFIG_XEN + .fill 511,8,0 ++#else ++ .quad level2_ident_pgt + PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE ++ .quad level2_ident_pgt + 2*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE ++ .quad level2_ident_pgt + 3*PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE ++ .fill 508,8,0 ++#endif ++ ++NEXT_PAGE(level3_vmalloc_pgt) ++ .fill 512,8,0 ++ ++NEXT_PAGE(level3_vmemmap_pgt) ++ .fill L3_VMEMMAP_START,8,0 ++ .quad level2_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE + + NEXT_PAGE(level3_kernel_pgt) + .fill L3_START_KERNEL,8,0 +@@ -364,20 +382,23 @@ NEXT_PAGE(level3_kernel_pgt) + .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE + ++NEXT_PAGE(level2_vmemmap_pgt) ++ .fill 512,8,0 ++ + NEXT_PAGE(level2_fixmap_pgt) +- .fill 506,8,0 +- .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE +- /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */ +- .fill 5,8,0 ++ .fill 507,8,0 ++ .quad level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE ++ /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */ ++ .fill 4,8,0 + +-NEXT_PAGE(level1_fixmap_pgt) ++NEXT_PAGE(level1_vsyscall_pgt) + .fill 512,8,0 + +-NEXT_PAGE(level2_ident_pgt) +- /* Since I easily can, map the first 1G. ++ /* Since I easily can, map the first 4G. + * Don't set NX because code runs from these pages. + */ +- PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD) ++NEXT_PAGE(level2_ident_pgt) ++ PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, 4*PTRS_PER_PMD) + + NEXT_PAGE(level2_kernel_pgt) + /* +@@ -390,33 +411,49 @@ NEXT_PAGE(level2_kernel_pgt) + * If you want to increase this then increase MODULES_VADDR + * too.) + */ +- PMDS(0, __PAGE_KERNEL_LARGE_EXEC, +- KERNEL_IMAGE_SIZE/PMD_SIZE) +- +-NEXT_PAGE(level2_spare_pgt) +- .fill 512, 8, 0 ++ PMDS(0, __PAGE_KERNEL_LARGE_EXEC, KERNEL_IMAGE_SIZE/PMD_SIZE) + + #undef PMDS + #undef NEXT_PAGE + +- .data ++ .align PAGE_SIZE ++ENTRY(cpu_gdt_table) ++ .rept NR_CPUS ++ .quad 0x0000000000000000 /* NULL descriptor */ ++ .quad 0x00cf9b000000ffff /* __KERNEL32_CS */ ++ .quad 0x00af9b000000ffff /* __KERNEL_CS */ ++ .quad 0x00cf93000000ffff /* __KERNEL_DS */ ++ .quad 0x00cffb000000ffff /* __USER32_CS */ ++ .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */ ++ .quad 0x00affb000000ffff /* __USER_CS */ ++ .quad 0x0 /* unused */ ++ .quad 0,0 /* TSS */ ++ .quad 0,0 /* LDT */ ++ .quad 0,0,0 /* three TLS descriptors */ ++ .quad 0x0000f40000000000 /* node/CPU stored in limit */ ++ /* asm/segment.h:GDT_ENTRIES must match this */ ++ ++ /* zero the remaining page */ ++ .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0 ++ .endr ++ + .align 16 + .globl early_gdt_descr + early_gdt_descr: + .word GDT_ENTRIES*8-1 + early_gdt_descr_base: +- .quad INIT_PER_CPU_VAR(gdt_page) ++ .quad cpu_gdt_table + + ENTRY(phys_base) + /* This must match the first entry in level2_kernel_pgt */ + .quad 0x0000000000000000 + + #include "../../x86/xen/xen-head.S" +- +- .section .bss, "aw", @nobits ++ ++ .section .rodata,"a",@progbits + .align L1_CACHE_BYTES + ENTRY(idt_table) +- .skip IDT_ENTRIES * 16 ++ .fill 512,8,0 + + .section .bss.page_aligned, "aw", @nobits + .align PAGE_SIZE +diff -urNp linux-2.6.31.1/arch/x86/kernel/i386_ksyms_32.c linux-2.6.31.1/arch/x86/kernel/i386_ksyms_32.c +--- linux-2.6.31.1/arch/x86/kernel/i386_ksyms_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/i386_ksyms_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -10,8 +10,12 @@ + EXPORT_SYMBOL(mcount); + #endif + ++EXPORT_SYMBOL_GPL(cpu_gdt_table); ++ + /* Networking helper routines. */ + EXPORT_SYMBOL(csum_partial_copy_generic); ++EXPORT_SYMBOL(csum_partial_copy_generic_to_user); ++EXPORT_SYMBOL(csum_partial_copy_generic_from_user); + + EXPORT_SYMBOL(__get_user_1); + EXPORT_SYMBOL(__get_user_2); +@@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr); + + EXPORT_SYMBOL(csum_partial); + EXPORT_SYMBOL(empty_zero_page); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++EXPORT_SYMBOL(__LOAD_PHYSICAL_ADDR); ++#endif +diff -urNp linux-2.6.31.1/arch/x86/kernel/init_task.c linux-2.6.31.1/arch/x86/kernel/init_task.c +--- linux-2.6.31.1/arch/x86/kernel/init_task.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/init_task.c 2009-10-01 20:12:42.000000000 -0400 +@@ -39,5 +39,5 @@ EXPORT_SYMBOL(init_task); + * section. Since TSS's are completely CPU-local, we want them + * on exact cacheline boundaries, to eliminate cacheline ping-pong. + */ +-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; +- ++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS }; ++EXPORT_SYMBOL(init_tss); +diff -urNp linux-2.6.31.1/arch/x86/kernel/ioport.c linux-2.6.31.1/arch/x86/kernel/ioport.c +--- linux-2.6.31.1/arch/x86/kernel/ioport.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/ioport.c 2009-10-01 20:12:42.000000000 -0400 +@@ -6,6 +6,7 @@ + #include <linux/sched.h> + #include <linux/kernel.h> + #include <linux/capability.h> ++#include <linux/security.h> + #include <linux/errno.h> + #include <linux/types.h> + #include <linux/ioport.h> +@@ -41,6 +42,12 @@ asmlinkage long sys_ioperm(unsigned long + + if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) + return -EINVAL; ++#ifdef CONFIG_GRKERNSEC_IO ++ if (turn_on) { ++ gr_handle_ioperm(); ++ return -EPERM; ++ } ++#endif + if (turn_on && !capable(CAP_SYS_RAWIO)) + return -EPERM; + +@@ -67,7 +74,7 @@ asmlinkage long sys_ioperm(unsigned long + * because the ->io_bitmap_max value must match the bitmap + * contents: + */ +- tss = &per_cpu(init_tss, get_cpu()); ++ tss = init_tss + get_cpu(); + + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on); + +@@ -111,8 +118,13 @@ static int do_iopl(unsigned int level, s + return -EINVAL; + /* Trying to gain more privileges? */ + if (level > old) { ++#ifdef CONFIG_GRKERNSEC_IO ++ gr_handle_iopl(); ++ return -EPERM; ++#else + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; ++#endif + } + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); + +diff -urNp linux-2.6.31.1/arch/x86/kernel/irq_32.c linux-2.6.31.1/arch/x86/kernel/irq_32.c +--- linux-2.6.31.1/arch/x86/kernel/irq_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/irq_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -94,7 +94,7 @@ execute_on_irq_stack(int overflow, struc + return 0; + + /* build the stack frame on the IRQ stack */ +- isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); ++ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8); + irqctx->tinfo.task = curctx->tinfo.task; + irqctx->tinfo.previous_esp = current_stack_pointer; + +@@ -175,7 +175,7 @@ asmlinkage void do_softirq(void) + irqctx->tinfo.previous_esp = current_stack_pointer; + + /* build the stack frame on the softirq stack */ +- isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); ++ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8); + + call_on_stack(__do_softirq, isp); + /* +diff -urNp linux-2.6.31.1/arch/x86/kernel/kprobes.c linux-2.6.31.1/arch/x86/kernel/kprobes.c +--- linux-2.6.31.1/arch/x86/kernel/kprobes.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/kprobes.c 2009-10-01 20:12:42.000000000 -0400 +@@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f + char op; + s32 raddr; + } __attribute__((packed)) * jop; +- jop = (struct __arch_jmp_op *)from; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ ++ jop = (struct __arch_jmp_op *)(ktla_ktva(from)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + jop->raddr = (s32)((long)(to) - ((long)(from) + 5)); + jop->op = RELATIVEJUMP_INSTRUCTION; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } + + /* +@@ -345,16 +360,29 @@ static void __kprobes fix_riprel(struct + + static void __kprobes arch_copy_kprobe(struct kprobe *p) + { +- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif + + fix_riprel(p); + +- if (can_boost(p->addr)) ++ if (can_boost(ktla_ktva(p->addr))) + p->ainsn.boostable = 0; + else + p->ainsn.boostable = -1; + +- p->opcode = *p->addr; ++ p->opcode = *(ktla_ktva(p->addr)); + } + + int __kprobes arch_prepare_kprobe(struct kprobe *p) +@@ -432,7 +460,7 @@ static void __kprobes prepare_singlestep + if (p->opcode == BREAKPOINT_INSTRUCTION) + regs->ip = (unsigned long)p->addr; + else +- regs->ip = (unsigned long)p->ainsn.insn; ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn); + } + + void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, +@@ -453,7 +481,7 @@ static void __kprobes setup_singlestep(s + if (p->ainsn.boostable == 1 && !p->post_handler) { + /* Boost up -- we can execute copied instructions directly */ + reset_current_kprobe(); +- regs->ip = (unsigned long)p->ainsn.insn; ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn); + preempt_enable_no_resched(); + return; + } +@@ -523,7 +551,7 @@ static int __kprobes kprobe_handler(stru + struct kprobe_ctlblk *kcb; + + addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t)); +- if (*addr != BREAKPOINT_INSTRUCTION) { ++ if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) { + /* + * The breakpoint instruction was removed right + * after we hit it. Another cpu has removed +@@ -775,7 +803,7 @@ static void __kprobes resume_execution(s + struct pt_regs *regs, struct kprobe_ctlblk *kcb) + { + unsigned long *tos = stack_addr(regs); +- unsigned long copy_ip = (unsigned long)p->ainsn.insn; ++ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn); + unsigned long orig_ip = (unsigned long)p->addr; + kprobe_opcode_t *insn = p->ainsn.insn; + +@@ -958,7 +986,7 @@ int __kprobes kprobe_exceptions_notify(s + struct die_args *args = data; + int ret = NOTIFY_DONE; + +- if (args->regs && user_mode_vm(args->regs)) ++ if (args->regs && user_mode(args->regs)) + return ret; + + switch (val) { +diff -urNp linux-2.6.31.1/arch/x86/kernel/ldt.c linux-2.6.31.1/arch/x86/kernel/ldt.c +--- linux-2.6.31.1/arch/x86/kernel/ldt.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/ldt.c 2009-10-01 20:12:42.000000000 -0400 +@@ -66,13 +66,13 @@ static int alloc_ldt(mm_context_t *pc, i + if (reload) { + #ifdef CONFIG_SMP + preempt_disable(); +- load_LDT(pc); ++ load_LDT_nolock(pc); + if (!cpus_equal(current->mm->cpu_vm_mask, + cpumask_of_cpu(smp_processor_id()))) + smp_call_function(flush_ldt, current->mm, 1); + preempt_enable(); + #else +- load_LDT(pc); ++ load_LDT_nolock(pc); + #endif + } + if (oldsize) { +@@ -94,7 +94,7 @@ static inline int copy_ldt(mm_context_t + return err; + + for (i = 0; i < old->size; i++) +- write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE); ++ write_ldt_entry(new->ldt, i, old->ldt + i); + return 0; + } + +@@ -115,6 +115,24 @@ int init_new_context(struct task_struct + retval = copy_ldt(&mm->context, &old_mm->context); + mutex_unlock(&old_mm->context.lock); + } ++ ++ if (tsk == current) { ++ mm->context.vdso = ~0UL; ++ ++#ifdef CONFIG_X86_32 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++ mm->context.user_cs_base = 0UL; ++ mm->context.user_cs_limit = ~0UL; ++ ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP) ++ cpus_clear(mm->context.cpu_user_cs_mask); ++#endif ++ ++#endif ++#endif ++ ++ } ++ + return retval; + } + +@@ -229,6 +247,13 @@ static int write_ldt(void __user *ptr, u + } + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) { ++ error = -EINVAL; ++ goto out_unlock; ++ } ++#endif ++ + fill_ldt(&ldt, &ldt_info); + if (oldmode) + ldt.avl = 0; +diff -urNp linux-2.6.31.1/arch/x86/kernel/machine_kexec_32.c linux-2.6.31.1/arch/x86/kernel/machine_kexec_32.c +--- linux-2.6.31.1/arch/x86/kernel/machine_kexec_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/machine_kexec_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -26,7 +26,7 @@ + #include <asm/system.h> + #include <asm/cacheflush.h> + +-static void set_idt(void *newidt, __u16 limit) ++static void set_idt(struct desc_struct *newidt, __u16 limit) + { + struct desc_ptr curidt; + +@@ -38,7 +38,7 @@ static void set_idt(void *newidt, __u16 + } + + +-static void set_gdt(void *newgdt, __u16 limit) ++static void set_gdt(struct desc_struct *newgdt, __u16 limit) + { + struct desc_ptr curgdt; + +@@ -217,7 +217,7 @@ void machine_kexec(struct kimage *image) + } + + control_page = page_address(image->control_code_page); +- memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE); ++ memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE); + + relocate_kernel_ptr = control_page; + page_list[PA_CONTROL_PAGE] = __pa(control_page); +diff -urNp linux-2.6.31.1/arch/x86/kernel/module.c linux-2.6.31.1/arch/x86/kernel/module.c +--- linux-2.6.31.1/arch/x86/kernel/module.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/module.c 2009-10-01 20:12:42.000000000 -0400 +@@ -27,6 +27,7 @@ + #include <asm/system.h> + #include <asm/page.h> + #include <asm/pgtable.h> ++#include <asm/desc.h> + + #if 0 + #define DEBUGP printk +@@ -34,7 +35,7 @@ + #define DEBUGP(fmt...) + #endif + +-void *module_alloc(unsigned long size) ++static void *__module_alloc(unsigned long size, pgprot_t prot) + { + struct vm_struct *area; + +@@ -48,9 +49,92 @@ void *module_alloc(unsigned long size) + if (!area) + return NULL; + +- return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM, +- PAGE_KERNEL_EXEC); ++ return __vmalloc_area(area, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, prot); ++} ++ ++#ifdef CONFIG_PAX_KERNEXEC ++#ifdef CONFIG_X86_32 ++void *module_alloc(unsigned long size) ++{ ++ return __module_alloc(size, PAGE_KERNEL); ++} ++ ++void *module_alloc_exec(unsigned long size) ++{ ++ struct vm_struct *area; ++ ++ if (size == 0) ++ return NULL; ++ ++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_EXEC_VADDR, (unsigned long)&MODULES_EXEC_END); ++ if (area) ++ return area->addr; ++ ++ return NULL; ++} ++EXPORT_SYMBOL(module_alloc_exec); ++ ++void module_free_exec(struct module *mod, void *module_region) ++{ ++ struct vm_struct **p, *tmp; ++ ++ if (!module_region) ++ return; ++ ++ if ((PAGE_SIZE-1) & (unsigned long)module_region) { ++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region); ++ WARN_ON(1); ++ return; ++ } ++ ++ write_lock(&vmlist_lock); ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) ++ if (tmp->addr == module_region) ++ break; ++ ++ if (tmp) { ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++ memset(tmp->addr, 0xCC, tmp->size); ++ pax_close_kernel(cr0); ++ ++ *p = tmp->next; ++ kfree(tmp); ++ } ++ write_unlock(&vmlist_lock); ++ ++ if (!tmp) { ++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n", ++ module_region); ++ WARN_ON(1); ++ } ++} ++EXPORT_SYMBOL(module_free_exec); ++#else ++void *module_alloc(unsigned long size) ++{ ++ return __module_alloc(size, PAGE_KERNEL); ++} ++ ++void module_free_exec(struct module *mod, void *module_region) ++{ ++ module_free(mod, module_region); ++} ++EXPORT_SYMBOL(module_free_exec); ++ ++void *module_alloc_exec(unsigned long size) ++{ ++ return __module_alloc(size, PAGE_KERNEL_RX); ++} ++EXPORT_SYMBOL(module_alloc_exec); ++#endif ++#else ++void *module_alloc(unsigned long size) ++{ ++ return __module_alloc(size, PAGE_KERNEL_EXEC); + } ++#endif + + /* Free memory returned from module_alloc */ + void module_free(struct module *mod, void *module_region) +@@ -77,14 +161,20 @@ int apply_relocate(Elf32_Shdr *sechdrs, + unsigned int i; + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr; + Elf32_Sym *sym; +- uint32_t *location; ++ uint32_t *plocation, location; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif + + DEBUGP("Applying relocate section %u to %u\n", relsec, + sechdrs[relsec].sh_info); + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { + /* This is where to make the change */ +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr +- + rel[i].r_offset; ++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset; ++ location = (uint32_t)plocation; ++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR) ++ plocation = ktla_ktva((void *)plocation); + /* This is the symbol it is referring to. Note that all + undefined symbols have been resolved. */ + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr +@@ -93,11 +183,31 @@ int apply_relocate(Elf32_Shdr *sechdrs, + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_386_32: + /* We add the value into the location given */ +- *location += sym->st_value; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ *plocation += sym->st_value; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + break; + case R_386_PC32: + /* Add the value, subtract its postition */ +- *location += sym->st_value - (uint32_t)location; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ *plocation += sym->st_value - location; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + break; + default: + printk(KERN_ERR "module %s: Unknown relocation: %u\n", +@@ -131,6 +241,10 @@ int apply_relocate_add(Elf64_Shdr *sechd + void *loc; + u64 val; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + DEBUGP("Applying relocate section %u to %u\n", relsec, + sechdrs[relsec].sh_info); + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { +@@ -153,21 +267,61 @@ int apply_relocate_add(Elf64_Shdr *sechd + case R_X86_64_NONE: + break; + case R_X86_64_64: ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + *(u64 *)loc = val; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + break; + case R_X86_64_32: ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + *(u32 *)loc = val; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + if (val != *(u32 *)loc) + goto overflow; + break; + case R_X86_64_32S: ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + *(s32 *)loc = val; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + if ((s64)val != *(s32 *)loc) + goto overflow; + break; + case R_X86_64_PC32: + val -= (u64)loc; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + *(u32 *)loc = val; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + #if 0 + if ((s64)val != *(s32 *)loc) + goto overflow; +diff -urNp linux-2.6.31.1/arch/x86/kernel/paravirt.c linux-2.6.31.1/arch/x86/kernel/paravirt.c +--- linux-2.6.31.1/arch/x86/kernel/paravirt.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/paravirt.c 2009-10-01 20:12:42.000000000 -0400 +@@ -54,7 +54,7 @@ u64 _paravirt_ident_64(u64 x) + return x; + } + +-static void __init default_banner(void) ++static void default_banner(void) + { + printk(KERN_INFO "Booting paravirtualized kernel on %s\n", + pv_info.name); +@@ -125,9 +125,9 @@ unsigned paravirt_patch_jmp(void *insnbu + + /* Neat trick to map patch type back to the call within the + * corresponding structure. */ +-static void *get_call_destination(u8 type) ++static const void *get_call_destination(u8 type) + { +- struct paravirt_patch_template tmpl = { ++ const struct paravirt_patch_template tmpl = { + .pv_init_ops = pv_init_ops, + .pv_time_ops = pv_time_ops, + .pv_cpu_ops = pv_cpu_ops, +@@ -138,13 +138,13 @@ static void *get_call_destination(u8 typ + .pv_lock_ops = pv_lock_ops, + #endif + }; +- return *((void **)&tmpl + type); ++ return *((const void **)&tmpl + type); + } + + unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, + unsigned long addr, unsigned len) + { +- void *opfunc = get_call_destination(type); ++ const void *opfunc = get_call_destination(type); + unsigned ret; + + if (opfunc == NULL) +@@ -183,7 +183,7 @@ unsigned paravirt_patch_insns(void *insn + if (insn_len > len || start == NULL) + insn_len = len; + else +- memcpy(insnbuf, start, insn_len); ++ memcpy(insnbuf, ktla_ktva(start), insn_len); + + return insn_len; + } +@@ -311,21 +311,21 @@ void arch_flush_lazy_mmu_mode(void) + preempt_enable(); + } + +-struct pv_info pv_info = { ++struct pv_info pv_info __read_only = { + .name = "bare hardware", + .paravirt_enabled = 0, + .kernel_rpl = 0, + .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */ + }; + +-struct pv_init_ops pv_init_ops = { ++struct pv_init_ops pv_init_ops __read_only = { + .patch = native_patch, + .banner = default_banner, + .arch_setup = paravirt_nop, + .memory_setup = machine_specific_memory_setup, + }; + +-struct pv_time_ops pv_time_ops = { ++struct pv_time_ops pv_time_ops __read_only = { + .time_init = hpet_time_init, + .get_wallclock = native_get_wallclock, + .set_wallclock = native_set_wallclock, +@@ -333,7 +333,7 @@ struct pv_time_ops pv_time_ops = { + .get_tsc_khz = native_calibrate_tsc, + }; + +-struct pv_irq_ops pv_irq_ops = { ++struct pv_irq_ops pv_irq_ops __read_only = { + .init_IRQ = native_init_IRQ, + .save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), + .restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl), +@@ -346,7 +346,7 @@ struct pv_irq_ops pv_irq_ops = { + #endif + }; + +-struct pv_cpu_ops pv_cpu_ops = { ++struct pv_cpu_ops pv_cpu_ops __read_only = { + .cpuid = native_cpuid, + .get_debugreg = native_get_debugreg, + .set_debugreg = native_set_debugreg, +@@ -406,7 +406,7 @@ struct pv_cpu_ops pv_cpu_ops = { + .end_context_switch = paravirt_nop, + }; + +-struct pv_apic_ops pv_apic_ops = { ++struct pv_apic_ops pv_apic_ops __read_only = { + #ifdef CONFIG_X86_LOCAL_APIC + .setup_boot_clock = setup_boot_APIC_clock, + .setup_secondary_clock = setup_secondary_APIC_clock, +@@ -422,7 +422,7 @@ struct pv_apic_ops pv_apic_ops = { + #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) + #endif + +-struct pv_mmu_ops pv_mmu_ops = { ++struct pv_mmu_ops pv_mmu_ops __read_only = { + #ifndef CONFIG_X86_64 + .pagetable_setup_start = native_pagetable_setup_start, + .pagetable_setup_done = native_pagetable_setup_done, +diff -urNp linux-2.6.31.1/arch/x86/kernel/paravirt-spinlocks.c linux-2.6.31.1/arch/x86/kernel/paravirt-spinlocks.c +--- linux-2.6.31.1/arch/x86/kernel/paravirt-spinlocks.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/paravirt-spinlocks.c 2009-10-01 20:12:42.000000000 -0400 +@@ -13,7 +13,7 @@ default_spin_lock_flags(raw_spinlock_t * + __raw_spin_lock(lock); + } + +-struct pv_lock_ops pv_lock_ops = { ++struct pv_lock_ops pv_lock_ops __read_only = { + #ifdef CONFIG_SMP + .spin_is_locked = __ticket_spin_is_locked, + .spin_is_contended = __ticket_spin_is_contended, +diff -urNp linux-2.6.31.1/arch/x86/kernel/process_32.c linux-2.6.31.1/arch/x86/kernel/process_32.c +--- linux-2.6.31.1/arch/x86/kernel/process_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/process_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -70,6 +70,7 @@ EXPORT_PER_CPU_SYMBOL(current_task); + unsigned long thread_saved_pc(struct task_struct *tsk) + { + return ((unsigned long *)tsk->thread.sp)[3]; ++//XXX return tsk->thread.eip; + } + + #ifndef CONFIG_SMP +@@ -132,7 +133,7 @@ void __show_regs(struct pt_regs *regs, i + unsigned short ss, gs; + const char *board; + +- if (user_mode_vm(regs)) { ++ if (user_mode(regs)) { + sp = regs->sp; + ss = regs->ss & 0xffff; + gs = get_user_gs(regs); +@@ -213,8 +214,8 @@ int kernel_thread(int (*fn)(void *), voi + regs.bx = (unsigned long) fn; + regs.dx = (unsigned long) arg; + +- regs.ds = __USER_DS; +- regs.es = __USER_DS; ++ regs.ds = __KERNEL_DS; ++ regs.es = __KERNEL_DS; + regs.fs = __KERNEL_PERCPU; + regs.gs = __KERNEL_STACK_CANARY; + regs.orig_ax = -1; +@@ -250,7 +251,7 @@ int copy_thread(unsigned long clone_flag + struct task_struct *tsk; + int err; + +- childregs = task_pt_regs(p); ++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8; + *childregs = *regs; + childregs->ax = 0; + childregs->sp = sp; +@@ -279,6 +280,7 @@ int copy_thread(unsigned long clone_flag + * Set a new TLS for the child thread? + */ + if (clone_flags & CLONE_SETTLS) ++//XXX needs set_fs()? + err = do_set_thread_area(p, -1, + (struct user_desc __user *)childregs->si, 0); + +@@ -349,7 +351,7 @@ __switch_to(struct task_struct *prev_p, + struct thread_struct *prev = &prev_p->thread, + *next = &next_p->thread; + int cpu = smp_processor_id(); +- struct tss_struct *tss = &per_cpu(init_tss, cpu); ++ struct tss_struct *tss = init_tss + cpu; + + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ + +@@ -377,6 +379,11 @@ __switch_to(struct task_struct *prev_p, + */ + lazy_save_gs(prev->gs); + ++#ifdef CONFIG_PAX_MEMORY_UDEREF ++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit)) ++ __set_fs(task_thread_info(next_p)->addr_limit, cpu); ++#endif ++ + /* + * Load the per-thread Thread-Local Storage descriptor. + */ +@@ -495,3 +502,27 @@ unsigned long get_wchan(struct task_stru + return 0; + } + ++#ifdef CONFIG_PAX_RANDKSTACK ++asmlinkage void pax_randomize_kstack(void) ++{ ++ struct thread_struct *thread = ¤t->thread; ++ unsigned long time; ++ ++ if (!randomize_va_space) ++ return; ++ ++ rdtscl(time); ++ ++ /* P4 seems to return a 0 LSB, ignore it */ ++#ifdef CONFIG_MPENTIUM4 ++ time &= 0x1EUL; ++ time <<= 2; ++#else ++ time &= 0xFUL; ++ time <<= 3; ++#endif ++ ++ thread->sp0 ^= time; ++ load_sp0(init_tss + smp_processor_id(), thread); ++} ++#endif +diff -urNp linux-2.6.31.1/arch/x86/kernel/process_64.c linux-2.6.31.1/arch/x86/kernel/process_64.c +--- linux-2.6.31.1/arch/x86/kernel/process_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/process_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -94,7 +94,7 @@ static void __exit_idle(void) + void exit_idle(void) + { + /* idle loop has pid 0 */ +- if (current->pid) ++ if (task_pid_nr(current)) + return; + __exit_idle(); + } +@@ -173,7 +173,7 @@ void __show_regs(struct pt_regs *regs, i + if (!board) + board = ""; + printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n", +- current->pid, current->comm, print_tainted(), ++ task_pid_nr(current), current->comm, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version, board); +@@ -384,7 +384,7 @@ __switch_to(struct task_struct *prev_p, + struct thread_struct *prev = &prev_p->thread; + struct thread_struct *next = &next_p->thread; + int cpu = smp_processor_id(); +- struct tss_struct *tss = &per_cpu(init_tss, cpu); ++ struct tss_struct *tss = init_tss + cpu; + unsigned fsindex, gsindex; + + /* we're going to use this soon, after a few expensive things */ +@@ -543,12 +543,11 @@ unsigned long get_wchan(struct task_stru + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + stack = (unsigned long)task_stack_page(p); +- if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE) ++ if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64)) + return 0; + fp = *(u64 *)(p->thread.sp); + do { +- if (fp < (unsigned long)stack || +- fp >= (unsigned long)stack+THREAD_SIZE) ++ if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64)) + return 0; + ip = *(u64 *)(fp+8); + if (!in_sched_functions(ip)) +diff -urNp linux-2.6.31.1/arch/x86/kernel/process.c linux-2.6.31.1/arch/x86/kernel/process.c +--- linux-2.6.31.1/arch/x86/kernel/process.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/process.c 2009-10-01 20:12:42.000000000 -0400 +@@ -76,7 +76,7 @@ void exit_thread(void) + unsigned long *bp = t->io_bitmap_ptr; + + if (bp) { +- struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); ++ struct tss_struct *tss = init_tss + get_cpu(); + + t->io_bitmap_ptr = NULL; + clear_thread_flag(TIF_IO_BITMAP); +@@ -108,6 +108,9 @@ void flush_thread(void) + + clear_tsk_thread_flag(tsk, TIF_DEBUG); + ++#if defined(CONFIG_X86_32) && !defined(CONFIG_CC_STACKPROTECTOR) ++ loadsegment(gs, 0); ++#endif + tsk->thread.debugreg0 = 0; + tsk->thread.debugreg1 = 0; + tsk->thread.debugreg2 = 0; +@@ -611,17 +614,3 @@ static int __init idle_setup(char *str) + return 0; + } + early_param("idle", idle_setup); +- +-unsigned long arch_align_stack(unsigned long sp) +-{ +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) +- sp -= get_random_int() % 8192; +- return sp & ~0xf; +-} +- +-unsigned long arch_randomize_brk(struct mm_struct *mm) +-{ +- unsigned long range_end = mm->brk + 0x02000000; +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk; +-} +- +diff -urNp linux-2.6.31.1/arch/x86/kernel/ptrace.c linux-2.6.31.1/arch/x86/kernel/ptrace.c +--- linux-2.6.31.1/arch/x86/kernel/ptrace.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/ptrace.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1454,7 +1454,7 @@ void send_sigtrap(struct task_struct *ts + info.si_code = si_code; + + /* User-mode ip? */ +- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL; ++ info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL; + + /* Send us the fake SIGTRAP */ + force_sig_info(SIGTRAP, &info, tsk); +diff -urNp linux-2.6.31.1/arch/x86/kernel/reboot.c linux-2.6.31.1/arch/x86/kernel/reboot.c +--- linux-2.6.31.1/arch/x86/kernel/reboot.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/reboot.c 2009-10-01 20:12:42.000000000 -0400 +@@ -31,7 +31,7 @@ void (*pm_power_off)(void); + EXPORT_SYMBOL(pm_power_off); + + static const struct desc_ptr no_idt = {}; +-static int reboot_mode; ++static unsigned short reboot_mode; + enum reboot_type reboot_type = BOOT_KBD; + int reboot_force; + +@@ -257,7 +257,7 @@ static struct dmi_system_id __initdata r + DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), + }, + }, +- { } ++ { NULL, NULL, {{0, {0}}}, NULL} + }; + + static int __init reboot_init(void) +@@ -273,12 +273,12 @@ core_initcall(reboot_init); + controller to pulse the CPU reset line, which is more thorough, but + doesn't work with at least one type of 486 motherboard. It is easy + to stop this code working; hence the copious comments. */ +-static const unsigned long long +-real_mode_gdt_entries [3] = ++static struct desc_struct ++real_mode_gdt_entries [3] __read_only = + { +- 0x0000000000000000ULL, /* Null descriptor */ +- 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */ +- 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ ++ {{{0x00000000, 0x00000000}}}, /* Null descriptor */ ++ {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */ ++ {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */ + }; + + static const struct desc_ptr +@@ -327,7 +327,7 @@ static const unsigned char jump_to_bios + * specified by the code and length parameters. + * We assume that length will aways be less that 100! + */ +-void machine_real_restart(const unsigned char *code, int length) ++void machine_real_restart(const unsigned char *code, unsigned int length) + { + local_irq_disable(); + +@@ -347,8 +347,8 @@ void machine_real_restart(const unsigned + /* Remap the kernel at virtual address zero, as well as offset zero + from the kernel segment. This assumes the kernel segment starts at + virtual address PAGE_OFFSET. */ +- memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY, +- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS); ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY, ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); + + /* + * Use `swapper_pg_dir' as our page directory. +@@ -360,16 +360,15 @@ void machine_real_restart(const unsigned + boot)". This seems like a fairly standard thing that gets set by + REBOOT.COM programs, and the previous reset routine did this + too. */ +- *((unsigned short *)0x472) = reboot_mode; ++ *(unsigned short *)(__va(0x472)) = reboot_mode; + + /* For the switch to real mode, copy some code to low memory. It has + to be in the first 64k because it is running in 16-bit mode, and it + has to have the same physical and virtual address, because it turns + off paging. Copy it near the end of the first page, out of the way + of BIOS variables. */ +- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100), +- real_mode_switch, sizeof (real_mode_switch)); +- memcpy((void *)(0x1000 - 100), code, length); ++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch)); ++ memcpy(__va(0x1000 - 100), code, length); + + /* Set up the IDT for real mode. */ + load_idt(&real_mode_idt); +diff -urNp linux-2.6.31.1/arch/x86/kernel/setup.c linux-2.6.31.1/arch/x86/kernel/setup.c +--- linux-2.6.31.1/arch/x86/kernel/setup.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/setup.c 2009-10-01 20:12:42.000000000 -0400 +@@ -768,14 +768,14 @@ void __init setup_arch(char **cmdline_p) + + if (!boot_params.hdr.root_flags) + root_mountflags &= ~MS_RDONLY; +- init_mm.start_code = (unsigned long) _text; +- init_mm.end_code = (unsigned long) _etext; ++ init_mm.start_code = ktla_ktva((unsigned long) _text); ++ init_mm.end_code = ktla_ktva((unsigned long) _etext); + init_mm.end_data = (unsigned long) _edata; + init_mm.brk = _brk_end; + +- code_resource.start = virt_to_phys(_text); +- code_resource.end = virt_to_phys(_etext)-1; +- data_resource.start = virt_to_phys(_etext); ++ code_resource.start = virt_to_phys(ktla_ktva(_text)); ++ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1; ++ data_resource.start = virt_to_phys(_sdata); + data_resource.end = virt_to_phys(_edata)-1; + bss_resource.start = virt_to_phys(&__bss_start); + bss_resource.end = virt_to_phys(&__bss_stop)-1; +diff -urNp linux-2.6.31.1/arch/x86/kernel/setup_percpu.c linux-2.6.31.1/arch/x86/kernel/setup_percpu.c +--- linux-2.6.31.1/arch/x86/kernel/setup_percpu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/setup_percpu.c 2009-10-01 20:12:42.000000000 -0400 +@@ -25,19 +25,17 @@ + # define DBG(x...) + #endif + ++#ifdef CONFIG_SMP + DEFINE_PER_CPU(int, cpu_number); + EXPORT_PER_CPU_SYMBOL(cpu_number); ++#endif + +-#ifdef CONFIG_X86_64 + #define BOOT_PERCPU_OFFSET ((unsigned long)__per_cpu_load) +-#else +-#define BOOT_PERCPU_OFFSET 0 +-#endif + + DEFINE_PER_CPU(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET; + EXPORT_PER_CPU_SYMBOL(this_cpu_off); + +-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = { ++unsigned long __per_cpu_offset[NR_CPUS] __read_only = { + [0 ... NR_CPUS-1] = BOOT_PERCPU_OFFSET, + }; + EXPORT_SYMBOL(__per_cpu_offset); +@@ -429,13 +427,15 @@ early_param("percpu_alloc", percpu_alloc + static inline void setup_percpu_segment(int cpu) + { + #ifdef CONFIG_X86_32 +- struct desc_struct gdt; +- +- pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF, +- 0x2 | DESCTYPE_S, 0x8); +- gdt.s = 1; +- write_gdt_entry(get_cpu_gdt_table(cpu), +- GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S); ++ struct desc_struct d, *gdt = get_cpu_gdt_table(cpu); ++ unsigned long base = per_cpu_offset(cpu); ++ const unsigned long limit = VMALLOC_END - base - 1; ++ ++ if (limit < 64*1024) ++ pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4); ++ else ++ pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC); ++ write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S); + #endif + } + +@@ -486,6 +486,11 @@ void __init setup_per_cpu_areas(void) + /* alrighty, percpu areas up and running */ + delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; + for_each_possible_cpu(cpu) { ++#ifdef CONFIG_CC_STACKPROTECTOR ++#ifdef CONFIG_x86_32 ++ unsigned long canary = per_cpu(stack_canary, cpu); ++#endif ++#endif + per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size; + per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); + per_cpu(cpu_number, cpu) = cpu; +@@ -513,6 +518,12 @@ void __init setup_per_cpu_areas(void) + early_per_cpu_map(x86_cpu_to_node_map, cpu); + #endif + #endif ++#ifdef CONFIG_CC_STACKPROTECTOR ++#ifdef CONFIG_x86_32 ++ if (cpu == boot_cpu_id) ++ per_cpu(stack_canary, cpu) = canary; ++#endif ++#endif + /* + * Up to this point, the boot CPU has been using .data.init + * area. Reload any changed state for the boot CPU. +diff -urNp linux-2.6.31.1/arch/x86/kernel/signal.c linux-2.6.31.1/arch/x86/kernel/signal.c +--- linux-2.6.31.1/arch/x86/kernel/signal.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/signal.c 2009-10-01 20:12:42.000000000 -0400 +@@ -197,7 +197,7 @@ static unsigned long align_sigframe(unsi + * Align the stack pointer according to the i386 ABI, + * i.e. so that on function entry ((sp + 4) & 15) == 0. + */ +- sp = ((sp + 4) & -16ul) - 4; ++ sp = ((sp - 12) & -16ul) - 4; + #else /* !CONFIG_X86_32 */ + sp = round_down(sp, 16) - 8; + #endif +@@ -307,9 +307,9 @@ __setup_frame(int sig, struct k_sigactio + } + + if (current->mm->context.vdso) +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn); ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn); + else +- restorer = &frame->retcode; ++ restorer = (void __user *)&frame->retcode; + if (ka->sa.sa_flags & SA_RESTORER) + restorer = ka->sa.sa_restorer; + +@@ -377,7 +377,7 @@ static int __setup_rt_frame(int sig, str + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + + /* Set up to return from userspace. */ +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); + if (ka->sa.sa_flags & SA_RESTORER) + restorer = ka->sa.sa_restorer; + put_user_ex(restorer, &frame->pretcode); +@@ -789,7 +789,7 @@ static void do_signal(struct pt_regs *re + * X86_32: vm86 regs switched out by assembly code before reaching + * here, so testing against kernel CS suffices. + */ +- if (!user_mode(regs)) ++ if (!user_mode_novm(regs)) + return; + + if (current_thread_info()->status & TS_RESTORE_SIGMASK) +diff -urNp linux-2.6.31.1/arch/x86/kernel/smpboot.c linux-2.6.31.1/arch/x86/kernel/smpboot.c +--- linux-2.6.31.1/arch/x86/kernel/smpboot.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/smpboot.c 2009-10-01 20:12:42.000000000 -0400 +@@ -685,6 +685,10 @@ static int __cpuinit do_boot_cpu(int api + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), + }; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + INIT_WORK(&c_idle.work, do_fork_idle); + + alternatives_smp_switch(1); +@@ -727,7 +731,17 @@ do_rest: + (unsigned long)task_stack_page(c_idle.idle) - + KERNEL_STACK_OFFSET + THREAD_SIZE; + #endif ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + initial_code = (unsigned long)start_secondary; + stack_start.sp = (void *) c_idle.idle->thread.sp; + +diff -urNp linux-2.6.31.1/arch/x86/kernel/step.c linux-2.6.31.1/arch/x86/kernel/step.c +--- linux-2.6.31.1/arch/x86/kernel/step.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/step.c 2009-10-01 20:12:42.000000000 -0400 +@@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc + * and APM bios ones we just ignore here. + */ + if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) { +- u32 *desc; ++ struct desc_struct *desc; + unsigned long base; + +- seg &= ~7UL; ++ seg >>= 3; + + mutex_lock(&child->mm->context.lock); +- if (unlikely((seg >> 3) >= child->mm->context.size)) +- addr = -1L; /* bogus selector, access would fault */ ++ if (unlikely(seg >= child->mm->context.size)) ++ addr = -EINVAL; + else { +- desc = child->mm->context.ldt + seg; +- base = ((desc[0] >> 16) | +- ((desc[1] & 0xff) << 16) | +- (desc[1] & 0xff000000)); ++ desc = &child->mm->context.ldt[seg]; ++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000); + + /* 16-bit code segment? */ +- if (!((desc[1] >> 22) & 1)) ++ if (!((desc->b >> 22) & 1)) + addr &= 0xffff; + addr += base; + } +@@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t + unsigned char opcode[15]; + unsigned long addr = convert_ip_to_linear(child, regs); + ++ if (addr == -EINVAL) ++ return 0; ++ + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); + for (i = 0; i < copied; i++) { + switch (opcode[i]) { +@@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t + + #ifdef CONFIG_X86_64 + case 0x40 ... 0x4f: +- if (regs->cs != __USER_CS) ++ if ((regs->cs & 0xffff) != __USER_CS) + /* 32-bit mode: register increment */ + return 0; + /* 64-bit mode: REX prefix */ +diff -urNp linux-2.6.31.1/arch/x86/kernel/syscall_table_32.S linux-2.6.31.1/arch/x86/kernel/syscall_table_32.S +--- linux-2.6.31.1/arch/x86/kernel/syscall_table_32.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/syscall_table_32.S 2009-10-01 20:12:42.000000000 -0400 +@@ -1,3 +1,4 @@ ++.section .rodata,"a",@progbits + ENTRY(sys_call_table) + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ + .long sys_exit +diff -urNp linux-2.6.31.1/arch/x86/kernel/sys_i386_32.c linux-2.6.31.1/arch/x86/kernel/sys_i386_32.c +--- linux-2.6.31.1/arch/x86/kernel/sys_i386_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/sys_i386_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -24,6 +24,21 @@ + + #include <asm/syscalls.h> + ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) ++{ ++ unsigned long pax_task_size = TASK_SIZE; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++#endif ++ ++ if (len > pax_task_size || addr > pax_task_size - len) ++ return -EINVAL; ++ ++ return 0; ++} ++ + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +@@ -83,6 +98,205 @@ out: + return err; + } + ++unsigned long ++arch_get_unmapped_area(struct file *filp, unsigned long addr, ++ unsigned long len, unsigned long pgoff, unsigned long flags) ++{ ++ struct mm_struct *mm = current->mm; ++ struct vm_area_struct *vma; ++ unsigned long start_addr, pax_task_size = TASK_SIZE; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++#endif ++ ++ if (len > pax_task_size) ++ return -ENOMEM; ++ ++ if (flags & MAP_FIXED) ++ return addr; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ ++ if (addr) { ++ addr = PAGE_ALIGN(addr); ++ vma = find_vma(mm, addr); ++ if (pax_task_size - len >= addr && ++ (!vma || addr + len <= vma->vm_start)) ++ return addr; ++ } ++ if (len > mm->cached_hole_size) { ++ start_addr = addr = mm->free_area_cache; ++ } else { ++ start_addr = addr = mm->mmap_base; ++ mm->cached_hole_size = 0; ++ } ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) { ++ start_addr = 0x00110000UL; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ start_addr += mm->delta_mmap & 0x03FFF000UL; ++#endif ++ ++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base) ++ start_addr = addr = mm->mmap_base; ++ else ++ addr = start_addr; ++ } ++#endif ++ ++full_search: ++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { ++ /* At this point: (!vma || addr < vma->vm_end). */ ++ if (pax_task_size - len < addr) { ++ /* ++ * Start a new search - just in case we missed ++ * some holes. ++ */ ++ if (start_addr != mm->mmap_base) { ++ start_addr = addr = mm->mmap_base; ++ mm->cached_hole_size = 0; ++ goto full_search; ++ } ++ return -ENOMEM; ++ } ++ if (!vma || addr + len <= vma->vm_start) { ++ /* ++ * Remember the place where we stopped the search: ++ */ ++ mm->free_area_cache = addr + len; ++ return addr; ++ } ++ if (addr + mm->cached_hole_size < vma->vm_start) ++ mm->cached_hole_size = vma->vm_start - addr; ++ addr = vma->vm_end; ++ if (mm->start_brk <= addr && addr < mm->mmap_base) { ++ start_addr = addr = mm->mmap_base; ++ mm->cached_hole_size = 0; ++ goto full_search; ++ } ++ } ++} ++ ++unsigned long ++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, ++ const unsigned long len, const unsigned long pgoff, ++ const unsigned long flags) ++{ ++ struct vm_area_struct *vma; ++ struct mm_struct *mm = current->mm; ++ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++#endif ++ ++ /* requested length too big for entire address space */ ++ if (len > pax_task_size) ++ return -ENOMEM; ++ ++ if (flags & MAP_FIXED) ++ return addr; ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE)) ++ goto bottomup; ++#endif ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ ++ /* requesting a specific address */ ++ if (addr) { ++ addr = PAGE_ALIGN(addr); ++ vma = find_vma(mm, addr); ++ if (pax_task_size - len >= addr && ++ (!vma || addr + len <= vma->vm_start)) ++ return addr; ++ } ++ ++ /* check if free_area_cache is useful for us */ ++ if (len <= mm->cached_hole_size) { ++ mm->cached_hole_size = 0; ++ mm->free_area_cache = mm->mmap_base; ++ } ++ ++ /* either no address requested or can't fit in requested address hole */ ++ addr = mm->free_area_cache; ++ ++ /* make sure it can fit in the remaining address space */ ++ if (addr > len) { ++ vma = find_vma(mm, addr-len); ++ if (!vma || addr <= vma->vm_start) ++ /* remember the address as a hint for next time */ ++ return (mm->free_area_cache = addr-len); ++ } ++ ++ if (mm->mmap_base < len) ++ goto bottomup; ++ ++ addr = mm->mmap_base-len; ++ ++ do { ++ /* ++ * Lookup failure means no vma is above this address, ++ * else if new region fits below vma->vm_start, ++ * return with success: ++ */ ++ vma = find_vma(mm, addr); ++ if (!vma || addr+len <= vma->vm_start) ++ /* remember the address as a hint for next time */ ++ return (mm->free_area_cache = addr); ++ ++ /* remember the largest hole we saw so far */ ++ if (addr + mm->cached_hole_size < vma->vm_start) ++ mm->cached_hole_size = vma->vm_start - addr; ++ ++ /* try just below the current vma->vm_start */ ++ addr = vma->vm_start-len; ++ } while (len < vma->vm_start); ++ ++bottomup: ++ /* ++ * A failed mmap() very likely causes application failure, ++ * so fall back to the bottom-up function here. This scenario ++ * can happen with large stack limits and large mmap() ++ * allocations. ++ */ ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE; ++ else ++#endif ++ ++ mm->mmap_base = TASK_UNMAPPED_BASE; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base += mm->delta_mmap; ++#endif ++ ++ mm->free_area_cache = mm->mmap_base; ++ mm->cached_hole_size = ~0UL; ++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); ++ /* ++ * Restore the topdown base: ++ */ ++ mm->mmap_base = base; ++ mm->free_area_cache = base; ++ mm->cached_hole_size = ~0UL; ++ ++ return addr; ++} + + struct sel_arg_struct { + unsigned long n; +diff -urNp linux-2.6.31.1/arch/x86/kernel/sys_x86_64.c linux-2.6.31.1/arch/x86/kernel/sys_x86_64.c +--- linux-2.6.31.1/arch/x86/kernel/sys_x86_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/sys_x86_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -47,8 +47,8 @@ out: + return error; + } + +-static void find_start_end(unsigned long flags, unsigned long *begin, +- unsigned long *end) ++static void find_start_end(struct mm_struct *mm, unsigned long flags, ++ unsigned long *begin, unsigned long *end) + { + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) { + unsigned long new_begin; +@@ -67,7 +67,7 @@ static void find_start_end(unsigned long + *begin = new_begin; + } + } else { +- *begin = TASK_UNMAPPED_BASE; ++ *begin = mm->mmap_base; + *end = TASK_SIZE; + } + } +@@ -84,11 +84,15 @@ arch_get_unmapped_area(struct file *filp + if (flags & MAP_FIXED) + return addr; + +- find_start_end(flags, &begin, &end); ++ find_start_end(mm, flags, &begin, &end); + + if (len > end) + return -ENOMEM; + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ + if (addr) { + addr = PAGE_ALIGN(addr); + vma = find_vma(mm, addr); +@@ -143,7 +147,7 @@ arch_get_unmapped_area_topdown(struct fi + { + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; +- unsigned long addr = addr0; ++ unsigned long base = mm->mmap_base, addr = addr0; + + /* requested length too big for entire address space */ + if (len > TASK_SIZE) +@@ -156,6 +160,10 @@ arch_get_unmapped_area_topdown(struct fi + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) + goto bottomup; + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ + /* requesting a specific address */ + if (addr) { + addr = PAGE_ALIGN(addr); +@@ -213,13 +221,21 @@ bottomup: + * can happen with large stack limits and large mmap() + * allocations. + */ ++ mm->mmap_base = TASK_UNMAPPED_BASE; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base += mm->delta_mmap; ++#endif ++ ++ mm->free_area_cache = mm->mmap_base; + mm->cached_hole_size = ~0UL; +- mm->free_area_cache = TASK_UNMAPPED_BASE; + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); + /* + * Restore the topdown base: + */ +- mm->free_area_cache = mm->mmap_base; ++ mm->mmap_base = base; ++ mm->free_area_cache = base; + mm->cached_hole_size = ~0UL; + + return addr; +diff -urNp linux-2.6.31.1/arch/x86/kernel/time_32.c linux-2.6.31.1/arch/x86/kernel/time_32.c +--- linux-2.6.31.1/arch/x86/kernel/time_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/time_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -47,22 +47,32 @@ unsigned long profile_pc(struct pt_regs + unsigned long pc = instruction_pointer(regs); + + #ifdef CONFIG_SMP +- if (!user_mode_vm(regs) && in_lock_functions(pc)) { ++ if (!user_mode(regs) && in_lock_functions(pc)) { + #ifdef CONFIG_FRAME_POINTER +- return *(unsigned long *)(regs->bp + sizeof(long)); ++ return ktla_ktva(*(unsigned long *)(regs->bp + sizeof(long))); + #else + unsigned long *sp = (unsigned long *)®s->sp; + + /* Return address is either directly at stack pointer + or above a saved flags. Eflags has bits 22-31 zero, + kernel addresses don't. */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ return ktla_ktva(sp[0]); ++#else + if (sp[0] >> 22) + return sp[0]; + if (sp[1] >> 22) + return sp[1]; + #endif ++ ++#endif + } + #endif ++ ++ if (!user_mode(regs)) ++ pc = ktla_ktva(pc); ++ + return pc; + } + EXPORT_SYMBOL(profile_pc); +diff -urNp linux-2.6.31.1/arch/x86/kernel/time_64.c linux-2.6.31.1/arch/x86/kernel/time_64.c +--- linux-2.6.31.1/arch/x86/kernel/time_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/time_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -25,8 +25,6 @@ + #include <asm/time.h> + #include <asm/timer.h> + +-volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES; +- + unsigned long profile_pc(struct pt_regs *regs) + { + unsigned long pc = instruction_pointer(regs); +@@ -34,7 +32,7 @@ unsigned long profile_pc(struct pt_regs + /* Assume the lock function has either no stack frame or a copy + of flags from PUSHF + Eflags always has bits 22 and up cleared unlike kernel addresses. */ +- if (!user_mode_vm(regs) && in_lock_functions(pc)) { ++ if (!user_mode(regs) && in_lock_functions(pc)) { + #ifdef CONFIG_FRAME_POINTER + return *(unsigned long *)(regs->bp + sizeof(long)); + #else +diff -urNp linux-2.6.31.1/arch/x86/kernel/tls.c linux-2.6.31.1/arch/x86/kernel/tls.c +--- linux-2.6.31.1/arch/x86/kernel/tls.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/tls.c 2009-10-01 20:12:42.000000000 -0400 +@@ -85,6 +85,11 @@ int do_set_thread_area(struct task_struc + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) + return -EINVAL; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE)) ++ return -EINVAL; ++#endif ++ + set_tls_desc(p, idx, &info, 1); + + return 0; +diff -urNp linux-2.6.31.1/arch/x86/kernel/traps.c linux-2.6.31.1/arch/x86/kernel/traps.c +--- linux-2.6.31.1/arch/x86/kernel/traps.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/traps.c 2009-10-01 20:12:42.000000000 -0400 +@@ -70,14 +70,6 @@ asmlinkage int system_call(void); + + /* Do we ignore FPU interrupts ? */ + char ignore_fpu_irq; +- +-/* +- * The IDT has to be page-aligned to simplify the Pentium +- * F0 0F bug workaround.. We have a special link segment +- * for this. +- */ +-gate_desc idt_table[256] +- __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; + #endif + + DECLARE_BITMAP(used_vectors, NR_VECTORS); +@@ -115,7 +107,7 @@ static inline void preempt_conditional_c + static inline void + die_if_kernel(const char *str, struct pt_regs *regs, long err) + { +- if (!user_mode_vm(regs)) ++ if (!user_mode(regs)) + die(str, regs, err); + } + #endif +@@ -127,7 +119,7 @@ do_trap(int trapnr, int signr, char *str + struct task_struct *tsk = current; + + #ifdef CONFIG_X86_32 +- if (regs->flags & X86_VM_MASK) { ++ if (v8086_mode(regs)) { + /* + * traps 0, 1, 3, 4, and 5 should be forwarded to vm86. + * On nmi (interrupt 2), do_trap should not be called. +@@ -138,7 +130,7 @@ do_trap(int trapnr, int signr, char *str + } + #endif + +- if (!user_mode(regs)) ++ if (!user_mode_novm(regs)) + goto kernel_trap; + + #ifdef CONFIG_X86_32 +@@ -161,7 +153,7 @@ trap_signal: + printk_ratelimit()) { + printk(KERN_INFO + "%s[%d] trap %s ip:%lx sp:%lx error:%lx", +- tsk->comm, tsk->pid, str, ++ tsk->comm, task_pid_nr(tsk), str, + regs->ip, regs->sp, error_code); + print_vma_addr(" in ", regs->ip); + printk("\n"); +@@ -180,6 +172,12 @@ kernel_trap: + tsk->thread.trap_no = trapnr; + die(str, regs, error_code); + } ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ if (trapnr == 4) ++ pax_report_refcount_overflow(regs); ++#endif ++ + return; + + #ifdef CONFIG_X86_32 +@@ -268,14 +266,30 @@ do_general_protection(struct pt_regs *re + conditional_sti(regs); + + #ifdef CONFIG_X86_32 +- if (regs->flags & X86_VM_MASK) ++ if (v8086_mode(regs)) + goto gp_in_vm86; + #endif + + tsk = current; +- if (!user_mode(regs)) ++ if (!user_mode_novm(regs)) + goto gp_in_kernel; + ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) ++ if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) { ++ struct mm_struct *mm = tsk->mm; ++ unsigned long limit; ++ ++ down_write(&mm->mmap_sem); ++ limit = mm->context.user_cs_limit; ++ if (limit < TASK_SIZE) { ++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC); ++ up_write(&mm->mmap_sem); ++ return; ++ } ++ up_write(&mm->mmap_sem); ++ } ++#endif ++ + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; + +@@ -308,6 +322,13 @@ gp_in_kernel: + if (notify_die(DIE_GPF, "general protection fault", regs, + error_code, 13, SIGSEGV) == NOTIFY_STOP) + return; ++ ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++ if ((regs->cs & 0xFFFF) == __KERNEL_CS) ++ die("PAX: suspicious general protection fault", regs, error_code); ++ else ++#endif ++ + die("general protection fault", regs, error_code); + } + +@@ -561,7 +582,7 @@ dotraplinkage void __kprobes do_debug(st + } + + #ifdef CONFIG_X86_32 +- if (regs->flags & X86_VM_MASK) ++ if (v8086_mode(regs)) + goto debug_vm86; + #endif + +@@ -573,7 +594,7 @@ dotraplinkage void __kprobes do_debug(st + * kernel space (but re-enable TF when returning to user mode). + */ + if (condition & DR_STEP) { +- if (!user_mode(regs)) ++ if (!user_mode_novm(regs)) + goto clear_TF_reenable; + } + +@@ -760,7 +781,7 @@ do_simd_coprocessor_error(struct pt_regs + * Handle strange cache flush from user space exception + * in all other cases. This is undocumented behaviour. + */ +- if (regs->flags & X86_VM_MASK) { ++ if (v8086_mode(regs)) { + handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code); + return; + } +@@ -789,19 +810,14 @@ do_spurious_interrupt_bug(struct pt_regs + #ifdef CONFIG_X86_32 + unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) + { +- struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id()); + unsigned long base = (kesp - uesp) & -THREAD_SIZE; + unsigned long new_kesp = kesp - base; + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; +- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS]; ++ struct desc_struct ss; + + /* Set up base for espfix segment */ +- desc &= 0x00f0ff0000000000ULL; +- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) | +- ((((__u64)base) << 32) & 0xff00000000000000ULL) | +- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) | +- (lim_pages & 0xffff); +- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc; ++ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC); ++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S); + + return new_kesp; + } +diff -urNp linux-2.6.31.1/arch/x86/kernel/tsc.c linux-2.6.31.1/arch/x86/kernel/tsc.c +--- linux-2.6.31.1/arch/x86/kernel/tsc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/tsc.c 2009-10-01 20:12:42.000000000 -0400 +@@ -790,7 +790,7 @@ static struct dmi_system_id __initdata b + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"), + }, + }, +- {} ++ { NULL, NULL, {{0, {0}}}, NULL} + }; + + static void __init check_system_tsc_reliable(void) +diff -urNp linux-2.6.31.1/arch/x86/kernel/vm86_32.c linux-2.6.31.1/arch/x86/kernel/vm86_32.c +--- linux-2.6.31.1/arch/x86/kernel/vm86_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/vm86_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -148,7 +148,7 @@ struct pt_regs *save_v86_state(struct ke + do_exit(SIGSEGV); + } + +- tss = &per_cpu(init_tss, get_cpu()); ++ tss = init_tss + get_cpu(); + current->thread.sp0 = current->thread.saved_sp0; + current->thread.sysenter_cs = __KERNEL_CS; + load_sp0(tss, ¤t->thread); +@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm + tsk->thread.saved_fs = info->regs32->fs; + tsk->thread.saved_gs = get_user_gs(info->regs32); + +- tss = &per_cpu(init_tss, get_cpu()); ++ tss = init_tss + get_cpu(); + tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0; + if (cpu_has_sep) + tsk->thread.sysenter_cs = 0; +diff -urNp linux-2.6.31.1/arch/x86/kernel/vmi_32.c linux-2.6.31.1/arch/x86/kernel/vmi_32.c +--- linux-2.6.31.1/arch/x86/kernel/vmi_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/vmi_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -102,18 +102,43 @@ static unsigned patch_internal(int call, + { + u64 reloc; + struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + reloc = call_vrom_long_func(vmi_rom, get_reloc, call); + switch(rel->type) { + case VMI_RELOCATION_CALL_REL: + BUG_ON(len < 5); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + *(char *)insnbuf = MNEM_CALL; + patch_offset(insnbuf, ip, (unsigned long)rel->eip); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + return 5; + + case VMI_RELOCATION_JUMP_REL: + BUG_ON(len < 5); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + *(char *)insnbuf = MNEM_JMP; + patch_offset(insnbuf, ip, (unsigned long)rel->eip); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + return 5; + + case VMI_RELOCATION_NOP: +@@ -404,13 +429,13 @@ static void vmi_set_pud(pud_t *pudp, pud + + static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) + { +- const pte_t pte = { .pte = 0 }; ++ const pte_t pte = __pte(0ULL); + vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); + } + + static void vmi_pmd_clear(pmd_t *pmd) + { +- const pte_t pte = { .pte = 0 }; ++ const pte_t pte = __pte(0ULL); + vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD); + } + #endif +@@ -438,8 +463,8 @@ vmi_startup_ipi_hook(int phys_apicid, un + ap.ss = __KERNEL_DS; + ap.esp = (unsigned long) start_esp; + +- ap.ds = __USER_DS; +- ap.es = __USER_DS; ++ ap.ds = __KERNEL_DS; ++ ap.es = __KERNEL_DS; + ap.fs = __KERNEL_PERCPU; + ap.gs = __KERNEL_STACK_CANARY; + +@@ -640,12 +665,20 @@ static inline int __init activate_vmi(vo + u64 reloc; + const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + if (call_vrom_func(vmi_rom, vmi_init) != 0) { + printk(KERN_ERR "VMI ROM failed to initialize!"); + return 0; + } + savesegment(cs, kernel_cs); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + pv_info.paravirt_enabled = 1; + pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK; + pv_info.name = "vmi"; +@@ -836,6 +869,10 @@ static inline int __init activate_vmi(vo + + para_fill(pv_irq_ops.safe_halt, Halt); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + /* + * Alternative instruction rewriting doesn't happen soon enough + * to convert VMI_IRET to a call instead of a jump; so we have +diff -urNp linux-2.6.31.1/arch/x86/kernel/vmlinux.lds.S linux-2.6.31.1/arch/x86/kernel/vmlinux.lds.S +--- linux-2.6.31.1/arch/x86/kernel/vmlinux.lds.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/vmlinux.lds.S 2009-10-01 20:12:42.000000000 -0400 +@@ -26,6 +26,22 @@ + #include <asm/page_types.h> + #include <asm/cache.h> + #include <asm/boot.h> ++#include <asm/segment.h> ++ ++#undef PMD_SIZE ++#undef PMD_SHIFT ++#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) ++#define PMD_SHIFT 21 ++#else ++#define PMD_SHIFT 22 ++#endif ++#define PMD_SIZE (1 << PMD_SHIFT) ++ ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++#define __KERNEL_TEXT_OFFSET (LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR) ++#else ++#define __KERNEL_TEXT_OFFSET 0 ++#endif + + #undef i386 /* in case the preprocessor is a 32bit one */ + +@@ -34,46 +50,52 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONF + #ifdef CONFIG_X86_32 + OUTPUT_ARCH(i386) + ENTRY(phys_startup_32) +-jiffies = jiffies_64; + #else + OUTPUT_ARCH(i386:x86-64) + ENTRY(phys_startup_64) +-jiffies_64 = jiffies; + #endif + ++jiffies = jiffies_64; ++ + PHDRS { + text PT_LOAD FLAGS(5); /* R_E */ +- data PT_LOAD FLAGS(7); /* RWE */ ++ rodata PT_LOAD FLAGS(4); /* R__ */ ++ data PT_LOAD FLAGS(6); /* RW_ */ + #ifdef CONFIG_X86_64 +- user PT_LOAD FLAGS(7); /* RWE */ ++ user PT_LOAD FLAGS(5); /* R_E */ ++#endif ++ init.begin PT_LOAD FLAGS(6); /* RW_ */ + #ifdef CONFIG_SMP +- percpu PT_LOAD FLAGS(7); /* RWE */ ++ percpu PT_LOAD FLAGS(6); /* RW_ */ + #endif ++ text.init PT_LOAD FLAGS(5); /* R_E */ ++ text.exit PT_LOAD FLAGS(5); /* R_E */ + init PT_LOAD FLAGS(7); /* RWE */ +-#endif + note PT_NOTE FLAGS(0); /* ___ */ + } + + SECTIONS + { + #ifdef CONFIG_X86_32 +- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR; +- phys_startup_32 = startup_32 - LOAD_OFFSET; ++ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR; + #else +- . = __START_KERNEL; +- phys_startup_64 = startup_64 - LOAD_OFFSET; ++ . = __START_KERNEL; + #endif + + /* Text and read-only data */ + +- /* bootstrapping code */ +- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) { ++ .text (. - __KERNEL_TEXT_OFFSET): AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { ++ /* bootstrapping code */ ++#ifdef CONFIG_X86_32 ++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET; ++#else ++ phys_startup_64 = startup_64 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET; ++#endif ++ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET + __KERNEL_TEXT_OFFSET; + _text = .; + *(.text.head) +- } :text = 0x9090 + +- /* The rest of the text */ +- .text : AT(ADDR(.text) - LOAD_OFFSET) { ++ /* The rest of the text */ + #ifdef CONFIG_X86_32 + /* not really needed, already page aligned */ + . = ALIGN(PAGE_SIZE); +@@ -92,7 +114,10 @@ SECTIONS + _etext = .; + } :text = 0x9090 + +- NOTES :text :note ++ . += __KERNEL_TEXT_OFFSET; ++ ++ . = ALIGN(PAGE_SIZE); ++ NOTES :rodata :note + + /* Exception table */ + . = ALIGN(16); +@@ -100,22 +125,53 @@ SECTIONS + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; +- } :text = 0x9090 ++ } :rodata + + RO_DATA(PAGE_SIZE) + ++#ifdef CONFIG_X86_32 ++ . = ALIGN(PAGE_SIZE); ++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) { ++ *(.idt) ++ . = ALIGN(PAGE_SIZE); ++ *(.empty_zero_page) ++ *(.swapper_pg_pmd) ++ *(.swapper_pg_dir) ++ ++#if defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_MODULES) ++ . = ALIGN(PMD_SIZE); ++#endif ++ ++ } ++ ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES) ++ . = ALIGN(PAGE_SIZE); ++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) { ++ MODULES_EXEC_VADDR = .; ++ BYTE(0) ++ . += (8 * 1024 * 1024); ++ . = ALIGN(PMD_SIZE); ++ MODULES_EXEC_END = . - 1; ++ } ++#endif ++#endif ++ + /* Data */ + .data : AT(ADDR(.data) - LOAD_OFFSET) { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ . = ALIGN(PMD_SIZE); ++#else ++ . = ALIGN(PAGE_SIZE); ++#endif ++ + /* Start of data section */ + _sdata = .; + + /* init_task */ + INIT_TASK_DATA(THREAD_SIZE) + +-#ifdef CONFIG_X86_32 +- /* 32 bit has nosave before _edata */ + NOSAVE_DATA +-#endif + + PAGE_ALIGNED_DATA(PAGE_SIZE) + *(.data.idt) +@@ -182,12 +238,6 @@ SECTIONS + } + vgetcpu_mode = VVIRT(.vgetcpu_mode); + +- . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); +- .jiffies : AT(VLOAD(.jiffies)) { +- *(.jiffies) +- } +- jiffies = VVIRT(.jiffies); +- + .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) { + *(.vsyscall_3) + } +@@ -205,12 +255,19 @@ SECTIONS + #endif /* CONFIG_X86_64 */ + + /* Init code and data - will be freed after init */ +- . = ALIGN(PAGE_SIZE); + .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) { ++ BYTE(0) ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ . = ALIGN(PMD_SIZE); ++#else ++ . = ALIGN(PAGE_SIZE); ++#endif ++ + __init_begin = .; /* paired with __init_end */ +- } ++ } :init.begin + +-#if defined(CONFIG_X86_64) && defined(CONFIG_SMP) ++#ifdef CONFIG_SMP + /* + * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the + * output PHDR, so the next output section - .init.text - should +@@ -219,18 +276,26 @@ SECTIONS + PERCPU_VADDR(0, :percpu) + #endif + +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { ++ init_begin = .; ++ .init.text (. - __KERNEL_TEXT_OFFSET): AT(init_begin - LOAD_OFFSET) { + _sinittext = .; + INIT_TEXT + _einittext = .; +- } +-#ifdef CONFIG_X86_64 +- :init +-#endif ++ } :text.init ++ ++ /* ++ * .exit.text is discard at runtime, not link time, to deal with ++ * references from .altinstructions and .eh_frame ++ */ ++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { ++ EXIT_TEXT ++ . = ALIGN(16); ++ } :text.exit ++ . = init_begin + SIZEOF(.init.text) + SIZEOF(.exit.text); + + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { + INIT_DATA +- } ++ } :init + + . = ALIGN(16); + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { +@@ -276,14 +341,6 @@ SECTIONS + *(.altinstr_replacement) + } + +- /* +- * .exit.text is discard at runtime, not link time, to deal with +- * references from .altinstructions and .eh_frame +- */ +- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { +- EXIT_TEXT +- } +- + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { + EXIT_DATA + } +@@ -297,7 +354,7 @@ SECTIONS + } + #endif + +-#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP) ++#ifndef CONFIG_SMP + PERCPU(PAGE_SIZE) + #endif + +@@ -320,12 +377,6 @@ SECTIONS + . = ALIGN(PAGE_SIZE); + } + +-#ifdef CONFIG_X86_64 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { +- NOSAVE_DATA +- } +-#endif +- + /* BSS */ + . = ALIGN(PAGE_SIZE); + .bss : AT(ADDR(.bss) - LOAD_OFFSET) { +@@ -341,6 +392,7 @@ SECTIONS + __brk_base = .; + . += 64 * 1024; /* 64k alignment slop space */ + *(.brk_reservation) /* areas brk users have reserved */ ++ . = ALIGN(PMD_SIZE); + __brk_limit = .; + } + +@@ -369,13 +421,12 @@ SECTIONS + * for the boot processor. + */ + #define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load +-INIT_PER_CPU(gdt_page); + INIT_PER_CPU(irq_stack_union); + + /* + * Build-time check on the image size: + */ +-. = ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), ++. = ASSERT((_end - _text - __KERNEL_TEXT_OFFSET <= KERNEL_IMAGE_SIZE), + "kernel image bigger than KERNEL_IMAGE_SIZE"); + + #ifdef CONFIG_SMP +diff -urNp linux-2.6.31.1/arch/x86/kernel/vsyscall_64.c linux-2.6.31.1/arch/x86/kernel/vsyscall_64.c +--- linux-2.6.31.1/arch/x86/kernel/vsyscall_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/vsyscall_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -79,6 +79,7 @@ void update_vsyscall(struct timespec *wa + + write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); + /* copy vsyscall data */ ++ strlcpy(vsyscall_gtod_data.clock.name, clock->name, sizeof vsyscall_gtod_data.clock.name); + vsyscall_gtod_data.clock.vread = clock->vread; + vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; + vsyscall_gtod_data.clock.mask = clock->mask; +@@ -201,7 +202,7 @@ vgetcpu(unsigned *cpu, unsigned *node, s + We do this here because otherwise user space would do it on + its own in a likely inferior way (no access to jiffies). + If you don't like it pass NULL. */ +- if (tcache && tcache->blob[0] == (j = __jiffies)) { ++ if (tcache && tcache->blob[0] == (j = jiffies)) { + p = tcache->blob[1]; + } else if (__vgetcpu_mode == VGETCPU_RDTSCP) { + /* Load per CPU data from RDTSCP */ +@@ -240,13 +241,13 @@ static ctl_table kernel_table2[] = { + .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = vsyscall_sysctl_change }, +- {} ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + + static ctl_table kernel_root_table2[] = { + { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555, + .child = kernel_table2 }, +- {} ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + #endif + +diff -urNp linux-2.6.31.1/arch/x86/kernel/x8664_ksyms_64.c linux-2.6.31.1/arch/x86/kernel/x8664_ksyms_64.c +--- linux-2.6.31.1/arch/x86/kernel/x8664_ksyms_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kernel/x8664_ksyms_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -30,8 +30,6 @@ EXPORT_SYMBOL(__put_user_8); + + EXPORT_SYMBOL(copy_user_generic); + EXPORT_SYMBOL(__copy_user_nocache); +-EXPORT_SYMBOL(copy_from_user); +-EXPORT_SYMBOL(copy_to_user); + EXPORT_SYMBOL(__copy_from_user_inatomic); + + EXPORT_SYMBOL(copy_page); +diff -urNp linux-2.6.31.1/arch/x86/kvm/svm.c linux-2.6.31.1/arch/x86/kvm/svm.c +--- linux-2.6.31.1/arch/x86/kvm/svm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kvm/svm.c 2009-10-01 20:12:42.000000000 -0400 +@@ -2289,7 +2289,19 @@ static void reload_tss(struct kvm_vcpu * + int cpu = raw_smp_processor_id(); + + struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + load_TR_desc(); + } + +@@ -2673,7 +2685,7 @@ static u64 svm_get_mt_mask(struct kvm_vc + return 0; + } + +-static struct kvm_x86_ops svm_x86_ops = { ++static const struct kvm_x86_ops svm_x86_ops = { + .cpu_has_kvm_support = has_svm, + .disabled_by_bios = is_disabled, + .hardware_setup = svm_hardware_setup, +diff -urNp linux-2.6.31.1/arch/x86/kvm/vmx.c linux-2.6.31.1/arch/x86/kvm/vmx.c +--- linux-2.6.31.1/arch/x86/kvm/vmx.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kvm/vmx.c 2009-10-01 20:12:42.000000000 -0400 +@@ -519,9 +519,23 @@ static void reload_tss(void) + struct descriptor_table gdt; + struct desc_struct *descs; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + kvm_get_gdt(&gdt); + descs = (void *)gdt.base; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + load_TR_desc(); + } + +@@ -1321,6 +1335,11 @@ static __init int alloc_kvm_area(void) + + static __init int hardware_setup(void) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + if (setup_vmcs_config(&vmcs_config) < 0) + return -EIO; + +@@ -1336,8 +1355,19 @@ static __init int hardware_setup(void) + if (!cpu_has_vmx_flexpriority()) + flexpriority_enabled = 0; + +- if (!cpu_has_vmx_tpr_shadow()) +- kvm_x86_ops->update_cr8_intercept = NULL; ++ if (!cpu_has_vmx_tpr_shadow()) { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ *(void **)&kvm_x86_ops->update_cr8_intercept = NULL; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ ++ } + + return alloc_kvm_area(); + } +@@ -2239,7 +2269,7 @@ static int vmx_vcpu_setup(struct vcpu_vm + vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */ + + asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return)); +- vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */ ++ vmcs_writel(HOST_RIP, ktla_ktva(kvm_vmx_return)); /* 22.2.5 */ + vmcs_write32(VM_EXIT_MSR_STORE_COUNT, 0); + vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, 0); + vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, 0); +@@ -3493,6 +3523,12 @@ static void vmx_vcpu_run(struct kvm_vcpu + "jmp .Lkvm_vmx_return \n\t" + ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t" + ".Lkvm_vmx_return: " ++ ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++ "ljmp %[cs],$.Lkvm_vmx_return2\n\t" ++ ".Lkvm_vmx_return2: " ++#endif ++ + /* Save guest registers, load host registers, keep flags */ + "xchg %0, (%%"R"sp) \n\t" + "mov %%"R"ax, %c[rax](%0) \n\t" +@@ -3539,6 +3575,11 @@ static void vmx_vcpu_run(struct kvm_vcpu + [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])), + #endif + [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)) ++ ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++ ,[cs]"i"(__KERNEL_CS) ++#endif ++ + : "cc", "memory" + , R"bx", R"di", R"si" + #ifdef CONFIG_X86_64 +@@ -3555,7 +3596,7 @@ static void vmx_vcpu_run(struct kvm_vcpu + if (vmx->rmode.irq.pending) + fixup_rmode_irq(vmx); + +- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); ++ asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS)); + vmx->launched = 1; + + vmx_complete_interrupts(vmx); +@@ -3698,7 +3739,7 @@ static u64 vmx_get_mt_mask(struct kvm_vc + return ret; + } + +-static struct kvm_x86_ops vmx_x86_ops = { ++static const struct kvm_x86_ops vmx_x86_ops = { + .cpu_has_kvm_support = cpu_has_kvm_support, + .disabled_by_bios = vmx_disabled_by_bios, + .hardware_setup = hardware_setup, +diff -urNp linux-2.6.31.1/arch/x86/kvm/x86.c linux-2.6.31.1/arch/x86/kvm/x86.c +--- linux-2.6.31.1/arch/x86/kvm/x86.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/kvm/x86.c 2009-10-01 20:12:42.000000000 -0400 +@@ -73,42 +73,42 @@ static int kvm_dev_ioctl_get_supported_c + struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, + u32 function, u32 index); + +-struct kvm_x86_ops *kvm_x86_ops; ++const struct kvm_x86_ops *kvm_x86_ops; + EXPORT_SYMBOL_GPL(kvm_x86_ops); + + struct kvm_stats_debugfs_item debugfs_entries[] = { +- { "pf_fixed", VCPU_STAT(pf_fixed) }, +- { "pf_guest", VCPU_STAT(pf_guest) }, +- { "tlb_flush", VCPU_STAT(tlb_flush) }, +- { "invlpg", VCPU_STAT(invlpg) }, +- { "exits", VCPU_STAT(exits) }, +- { "io_exits", VCPU_STAT(io_exits) }, +- { "mmio_exits", VCPU_STAT(mmio_exits) }, +- { "signal_exits", VCPU_STAT(signal_exits) }, +- { "irq_window", VCPU_STAT(irq_window_exits) }, +- { "nmi_window", VCPU_STAT(nmi_window_exits) }, +- { "halt_exits", VCPU_STAT(halt_exits) }, +- { "halt_wakeup", VCPU_STAT(halt_wakeup) }, +- { "hypercalls", VCPU_STAT(hypercalls) }, +- { "request_irq", VCPU_STAT(request_irq_exits) }, +- { "irq_exits", VCPU_STAT(irq_exits) }, +- { "host_state_reload", VCPU_STAT(host_state_reload) }, +- { "efer_reload", VCPU_STAT(efer_reload) }, +- { "fpu_reload", VCPU_STAT(fpu_reload) }, +- { "insn_emulation", VCPU_STAT(insn_emulation) }, +- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) }, +- { "irq_injections", VCPU_STAT(irq_injections) }, +- { "nmi_injections", VCPU_STAT(nmi_injections) }, +- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) }, +- { "mmu_pte_write", VM_STAT(mmu_pte_write) }, +- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) }, +- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) }, +- { "mmu_flooded", VM_STAT(mmu_flooded) }, +- { "mmu_recycled", VM_STAT(mmu_recycled) }, +- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) }, +- { "mmu_unsync", VM_STAT(mmu_unsync) }, +- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) }, +- { "largepages", VM_STAT(lpages) }, ++ { "pf_fixed", VCPU_STAT(pf_fixed), NULL }, ++ { "pf_guest", VCPU_STAT(pf_guest), NULL }, ++ { "tlb_flush", VCPU_STAT(tlb_flush), NULL }, ++ { "invlpg", VCPU_STAT(invlpg), NULL }, ++ { "exits", VCPU_STAT(exits), NULL }, ++ { "io_exits", VCPU_STAT(io_exits), NULL }, ++ { "mmio_exits", VCPU_STAT(mmio_exits), NULL }, ++ { "signal_exits", VCPU_STAT(signal_exits), NULL }, ++ { "irq_window", VCPU_STAT(irq_window_exits), NULL }, ++ { "nmi_window", VCPU_STAT(nmi_window_exits), NULL }, ++ { "halt_exits", VCPU_STAT(halt_exits), NULL }, ++ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL }, ++ { "hypercalls", VCPU_STAT(hypercalls), NULL }, ++ { "request_irq", VCPU_STAT(request_irq_exits), NULL }, ++ { "irq_exits", VCPU_STAT(irq_exits), NULL }, ++ { "host_state_reload", VCPU_STAT(host_state_reload), NULL }, ++ { "efer_reload", VCPU_STAT(efer_reload), NULL }, ++ { "fpu_reload", VCPU_STAT(fpu_reload), NULL }, ++ { "insn_emulation", VCPU_STAT(insn_emulation), NULL }, ++ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL }, ++ { "irq_injections", VCPU_STAT(irq_injections), NULL }, ++ { "nmi_injections", VCPU_STAT(nmi_injections), NULL }, ++ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL }, ++ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL }, ++ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL }, ++ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL }, ++ { "mmu_flooded", VM_STAT(mmu_flooded), NULL }, ++ { "mmu_recycled", VM_STAT(mmu_recycled), NULL }, ++ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL }, ++ { "mmu_unsync", VM_STAT(mmu_unsync), NULL }, ++ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL }, ++ { "largepages", VM_STAT(lpages), NULL }, + { NULL } + }; + +@@ -1485,7 +1485,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, + struct kvm_interrupt *irq) + { +- if (irq->irq < 0 || irq->irq >= 256) ++ if (irq->irq >= 256) + return -EINVAL; + if (irqchip_in_kernel(vcpu->kvm)) + return -ENXIO; +@@ -2810,10 +2810,10 @@ static struct notifier_block kvmclock_cp + .notifier_call = kvmclock_cpufreq_notifier + }; + +-int kvm_arch_init(void *opaque) ++int kvm_arch_init(const void *opaque) + { + int r, cpu; +- struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque; ++ const struct kvm_x86_ops *ops = (const struct kvm_x86_ops *)opaque; + + if (kvm_x86_ops) { + printk(KERN_ERR "kvm: already loaded the other module\n"); +diff -urNp linux-2.6.31.1/arch/x86/lib/checksum_32.S linux-2.6.31.1/arch/x86/lib/checksum_32.S +--- linux-2.6.31.1/arch/x86/lib/checksum_32.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/checksum_32.S 2009-10-01 20:12:42.000000000 -0400 +@@ -28,7 +28,8 @@ + #include <linux/linkage.h> + #include <asm/dwarf2.h> + #include <asm/errno.h> +- ++#include <asm/segment.h> ++ + /* + * computes a partial checksum, e.g. for TCP/UDP fragments + */ +@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic ( + + #define ARGBASE 16 + #define FP 12 +- +-ENTRY(csum_partial_copy_generic) ++ ++ENTRY(csum_partial_copy_generic_to_user) + CFI_STARTPROC ++ pushl $(__USER_DS) ++ CFI_ADJUST_CFA_OFFSET 4 ++ popl %es ++ CFI_ADJUST_CFA_OFFSET -4 ++ jmp csum_partial_copy_generic ++ ++ENTRY(csum_partial_copy_generic_from_user) ++ pushl $(__USER_DS) ++ CFI_ADJUST_CFA_OFFSET 4 ++ popl %ds ++ CFI_ADJUST_CFA_OFFSET -4 ++ ++ENTRY(csum_partial_copy_generic) + subl $4,%esp + CFI_ADJUST_CFA_OFFSET 4 + pushl %edi +@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic) + jmp 4f + SRC(1: movw (%esi), %bx ) + addl $2, %esi +-DST( movw %bx, (%edi) ) ++DST( movw %bx, %es:(%edi) ) + addl $2, %edi + addw %bx, %ax + adcl $0, %eax +@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) ) + SRC(1: movl (%esi), %ebx ) + SRC( movl 4(%esi), %edx ) + adcl %ebx, %eax +-DST( movl %ebx, (%edi) ) ++DST( movl %ebx, %es:(%edi) ) + adcl %edx, %eax +-DST( movl %edx, 4(%edi) ) ++DST( movl %edx, %es:4(%edi) ) + + SRC( movl 8(%esi), %ebx ) + SRC( movl 12(%esi), %edx ) + adcl %ebx, %eax +-DST( movl %ebx, 8(%edi) ) ++DST( movl %ebx, %es:8(%edi) ) + adcl %edx, %eax +-DST( movl %edx, 12(%edi) ) ++DST( movl %edx, %es:12(%edi) ) + + SRC( movl 16(%esi), %ebx ) + SRC( movl 20(%esi), %edx ) + adcl %ebx, %eax +-DST( movl %ebx, 16(%edi) ) ++DST( movl %ebx, %es:16(%edi) ) + adcl %edx, %eax +-DST( movl %edx, 20(%edi) ) ++DST( movl %edx, %es:20(%edi) ) + + SRC( movl 24(%esi), %ebx ) + SRC( movl 28(%esi), %edx ) + adcl %ebx, %eax +-DST( movl %ebx, 24(%edi) ) ++DST( movl %ebx, %es:24(%edi) ) + adcl %edx, %eax +-DST( movl %edx, 28(%edi) ) ++DST( movl %edx, %es:28(%edi) ) + + lea 32(%esi), %esi + lea 32(%edi), %edi +@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) ) + shrl $2, %edx # This clears CF + SRC(3: movl (%esi), %ebx ) + adcl %ebx, %eax +-DST( movl %ebx, (%edi) ) ++DST( movl %ebx, %es:(%edi) ) + lea 4(%esi), %esi + lea 4(%edi), %edi + dec %edx +@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) ) + jb 5f + SRC( movw (%esi), %cx ) + leal 2(%esi), %esi +-DST( movw %cx, (%edi) ) ++DST( movw %cx, %es:(%edi) ) + leal 2(%edi), %edi + je 6f + shll $16,%ecx + SRC(5: movb (%esi), %cl ) +-DST( movb %cl, (%edi) ) ++DST( movb %cl, %es:(%edi) ) + 6: addl %ecx, %eax + adcl $0, %eax + 7: +@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) ) + + 6001: + movl ARGBASE+20(%esp), %ebx # src_err_ptr +- movl $-EFAULT, (%ebx) ++ movl $-EFAULT, %ss:(%ebx) + + # zero the complete destination - computing the rest + # is too much work +@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) ) + + 6002: + movl ARGBASE+24(%esp), %ebx # dst_err_ptr +- movl $-EFAULT,(%ebx) ++ movl $-EFAULT,%ss:(%ebx) + jmp 5000b + + .previous + ++ pushl %ss ++ CFI_ADJUST_CFA_OFFSET 4 ++ popl %ds ++ CFI_ADJUST_CFA_OFFSET -4 ++ pushl %ss ++ CFI_ADJUST_CFA_OFFSET 4 ++ popl %es ++ CFI_ADJUST_CFA_OFFSET -4 + popl %ebx + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE ebx +@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) ) + CFI_ADJUST_CFA_OFFSET -4 + ret + CFI_ENDPROC +-ENDPROC(csum_partial_copy_generic) ++ENDPROC(csum_partial_copy_generic_to_user) + + #else + + /* Version for PentiumII/PPro */ + + #define ROUND1(x) \ ++ nop; nop; nop; \ + SRC(movl x(%esi), %ebx ) ; \ + addl %ebx, %eax ; \ +- DST(movl %ebx, x(%edi) ) ; ++ DST(movl %ebx, %es:x(%edi)) ; + + #define ROUND(x) \ ++ nop; nop; nop; \ + SRC(movl x(%esi), %ebx ) ; \ + adcl %ebx, %eax ; \ +- DST(movl %ebx, x(%edi) ) ; ++ DST(movl %ebx, %es:x(%edi)) ; + + #define ARGBASE 12 +- +-ENTRY(csum_partial_copy_generic) ++ ++ENTRY(csum_partial_copy_generic_to_user) + CFI_STARTPROC ++ pushl $(__USER_DS) ++ CFI_ADJUST_CFA_OFFSET 4 ++ popl %es ++ CFI_ADJUST_CFA_OFFSET -4 ++ jmp csum_partial_copy_generic ++ ++ENTRY(csum_partial_copy_generic_from_user) ++ pushl $(__USER_DS) ++ CFI_ADJUST_CFA_OFFSET 4 ++ popl %ds ++ CFI_ADJUST_CFA_OFFSET -4 ++ ++ENTRY(csum_partial_copy_generic) + pushl %ebx + CFI_ADJUST_CFA_OFFSET 4 + CFI_REL_OFFSET ebx, 0 +@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic) + subl %ebx, %edi + lea -1(%esi),%edx + andl $-32,%edx +- lea 3f(%ebx,%ebx), %ebx ++ lea 3f(%ebx,%ebx,2), %ebx + testl %esi, %esi + jmp *%ebx + 1: addl $64,%esi +@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic) + jb 5f + SRC( movw (%esi), %dx ) + leal 2(%esi), %esi +-DST( movw %dx, (%edi) ) ++DST( movw %dx, %es:(%edi) ) + leal 2(%edi), %edi + je 6f + shll $16,%edx + 5: + SRC( movb (%esi), %dl ) +-DST( movb %dl, (%edi) ) ++DST( movb %dl, %es:(%edi) ) + 6: addl %edx, %eax + adcl $0, %eax + 7: + .section .fixup, "ax" + 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr +- movl $-EFAULT, (%ebx) ++ movl $-EFAULT, %ss:(%ebx) + # zero the complete destination (computing the rest is too much work) + movl ARGBASE+8(%esp),%edi # dst + movl ARGBASE+12(%esp),%ecx # len +@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) ) + rep; stosb + jmp 7b + 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr +- movl $-EFAULT, (%ebx) ++ movl $-EFAULT, %ss:(%ebx) + jmp 7b + .previous + ++ pushl %ss ++ CFI_ADJUST_CFA_OFFSET 4 ++ popl %ds ++ CFI_ADJUST_CFA_OFFSET -4 ++ pushl %ss ++ CFI_ADJUST_CFA_OFFSET 4 ++ popl %es ++ CFI_ADJUST_CFA_OFFSET -4 + popl %esi + CFI_ADJUST_CFA_OFFSET -4 + CFI_RESTORE esi +@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) ) + CFI_RESTORE ebx + ret + CFI_ENDPROC +-ENDPROC(csum_partial_copy_generic) ++ENDPROC(csum_partial_copy_generic_to_user) + + #undef ROUND + #undef ROUND1 +diff -urNp linux-2.6.31.1/arch/x86/lib/clear_page_64.S linux-2.6.31.1/arch/x86/lib/clear_page_64.S +--- linux-2.6.31.1/arch/x86/lib/clear_page_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/clear_page_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -43,7 +43,7 @@ ENDPROC(clear_page) + + #include <asm/cpufeature.h> + +- .section .altinstr_replacement,"ax" ++ .section .altinstr_replacement,"a" + 1: .byte 0xeb /* jmp <disp8> */ + .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */ + 2: +diff -urNp linux-2.6.31.1/arch/x86/lib/copy_page_64.S linux-2.6.31.1/arch/x86/lib/copy_page_64.S +--- linux-2.6.31.1/arch/x86/lib/copy_page_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/copy_page_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -104,7 +104,7 @@ ENDPROC(copy_page) + + #include <asm/cpufeature.h> + +- .section .altinstr_replacement,"ax" ++ .section .altinstr_replacement,"a" + 1: .byte 0xeb /* jmp <disp8> */ + .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */ + 2: +diff -urNp linux-2.6.31.1/arch/x86/lib/copy_user_64.S linux-2.6.31.1/arch/x86/lib/copy_user_64.S +--- linux-2.6.31.1/arch/x86/lib/copy_user_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/copy_user_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -21,7 +21,7 @@ + .byte 0xe9 /* 32bit jump */ + .long \orig-1f /* by default jump to orig */ + 1: +- .section .altinstr_replacement,"ax" ++ .section .altinstr_replacement,"a" + 2: .byte 0xe9 /* near jump with 32bit immediate */ + .long \alt-1b /* offset */ /* or alternatively to alt */ + .previous +@@ -64,32 +64,6 @@ + #endif + .endm + +-/* Standard copy_to_user with segment limit checking */ +-ENTRY(copy_to_user) +- CFI_STARTPROC +- GET_THREAD_INFO(%rax) +- movq %rdi,%rcx +- addq %rdx,%rcx +- jc bad_to_user +- cmpq TI_addr_limit(%rax),%rcx +- jae bad_to_user +- ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string +- CFI_ENDPROC +-ENDPROC(copy_to_user) +- +-/* Standard copy_from_user with segment limit checking */ +-ENTRY(copy_from_user) +- CFI_STARTPROC +- GET_THREAD_INFO(%rax) +- movq %rsi,%rcx +- addq %rdx,%rcx +- jc bad_from_user +- cmpq TI_addr_limit(%rax),%rcx +- jae bad_from_user +- ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string +- CFI_ENDPROC +-ENDPROC(copy_from_user) +- + ENTRY(copy_user_generic) + CFI_STARTPROC + ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string +@@ -107,6 +81,8 @@ ENDPROC(__copy_from_user_inatomic) + ENTRY(bad_from_user) + bad_from_user: + CFI_STARTPROC ++ testl %edx,%edx ++ js bad_to_user + movl %edx,%ecx + xorl %eax,%eax + rep +diff -urNp linux-2.6.31.1/arch/x86/lib/getuser.S linux-2.6.31.1/arch/x86/lib/getuser.S +--- linux-2.6.31.1/arch/x86/lib/getuser.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/getuser.S 2009-10-01 20:12:42.000000000 -0400 +@@ -33,6 +33,7 @@ + #include <asm/asm-offsets.h> + #include <asm/thread_info.h> + #include <asm/asm.h> ++#include <asm/segment.h> + + .text + ENTRY(__get_user_1) +@@ -40,7 +41,19 @@ ENTRY(__get_user_1) + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + jae bad_get_user ++ ++#ifdef CONFIG_X86_32 ++ pushl $(__USER_DS) ++ popl %ds ++#endif ++ + 1: movzb (%_ASM_AX),%edx ++ ++#ifdef CONFIG_X86_32 ++ pushl %ss ++ pop %ds ++#endif ++ + xor %eax,%eax + ret + CFI_ENDPROC +@@ -53,7 +66,19 @@ ENTRY(__get_user_2) + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + jae bad_get_user ++ ++#ifdef CONFIG_X86_32 ++ pushl $(__USER_DS) ++ popl %ds ++#endif ++ + 2: movzwl -1(%_ASM_AX),%edx ++ ++#ifdef CONFIG_X86_32 ++ pushl %ss ++ pop %ds ++#endif ++ + xor %eax,%eax + ret + CFI_ENDPROC +@@ -66,7 +91,19 @@ ENTRY(__get_user_4) + GET_THREAD_INFO(%_ASM_DX) + cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + jae bad_get_user ++ ++#ifdef CONFIG_X86_32 ++ pushl $(__USER_DS) ++ popl %ds ++#endif ++ + 3: mov -3(%_ASM_AX),%edx ++ ++#ifdef CONFIG_X86_32 ++ pushl %ss ++ pop %ds ++#endif ++ + xor %eax,%eax + ret + CFI_ENDPROC +@@ -89,6 +126,12 @@ ENDPROC(__get_user_8) + + bad_get_user: + CFI_STARTPROC ++ ++#ifdef CONFIG_X86_32 ++ pushl %ss ++ pop %ds ++#endif ++ + xor %edx,%edx + mov $(-EFAULT),%_ASM_AX + ret +diff -urNp linux-2.6.31.1/arch/x86/lib/memcpy_64.S linux-2.6.31.1/arch/x86/lib/memcpy_64.S +--- linux-2.6.31.1/arch/x86/lib/memcpy_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/memcpy_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -128,7 +128,7 @@ ENDPROC(__memcpy) + * It is also a lot simpler. Use this when possible: + */ + +- .section .altinstr_replacement, "ax" ++ .section .altinstr_replacement, "a" + 1: .byte 0xeb /* jmp <disp8> */ + .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */ + 2: +diff -urNp linux-2.6.31.1/arch/x86/lib/memset_64.S linux-2.6.31.1/arch/x86/lib/memset_64.S +--- linux-2.6.31.1/arch/x86/lib/memset_64.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/memset_64.S 2009-10-01 20:12:42.000000000 -0400 +@@ -118,7 +118,7 @@ ENDPROC(__memset) + + #include <asm/cpufeature.h> + +- .section .altinstr_replacement,"ax" ++ .section .altinstr_replacement,"a" + 1: .byte 0xeb /* jmp <disp8> */ + .byte (memset_c - memset) - (2f - 1b) /* offset */ + 2: +diff -urNp linux-2.6.31.1/arch/x86/lib/mmx_32.c linux-2.6.31.1/arch/x86/lib/mmx_32.c +--- linux-2.6.31.1/arch/x86/lib/mmx_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/mmx_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void * + { + void *p; + int i; ++ unsigned long cr0; + + if (unlikely(in_interrupt())) + return __memcpy(to, from, len); +@@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void * + kernel_fpu_begin(); + + __asm__ __volatile__ ( +- "1: prefetch (%0)\n" /* This set is 28 bytes */ +- " prefetch 64(%0)\n" +- " prefetch 128(%0)\n" +- " prefetch 192(%0)\n" +- " prefetch 256(%0)\n" ++ "1: prefetch (%1)\n" /* This set is 28 bytes */ ++ " prefetch 64(%1)\n" ++ " prefetch 128(%1)\n" ++ " prefetch 192(%1)\n" ++ " prefetch 256(%1)\n" + "2: \n" + ".section .fixup, "ax"\n" +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ ++ "3: \n" ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %%cr0, %0\n" ++ " movl %0, %%eax\n" ++ " andl $0xFFFEFFFF, %%eax\n" ++ " movl %%eax, %%cr0\n" ++#endif ++ ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %0, %%cr0\n" ++#endif ++ + " jmp 2b\n" + ".previous\n" + _ASM_EXTABLE(1b, 3b) +- : : "r" (from)); ++ : "=&r" (cr0) : "r" (from) : "ax"); + + for ( ; i > 5; i--) { + __asm__ __volatile__ ( +- "1: prefetch 320(%0)\n" +- "2: movq (%0), %%mm0\n" +- " movq 8(%0), %%mm1\n" +- " movq 16(%0), %%mm2\n" +- " movq 24(%0), %%mm3\n" +- " movq %%mm0, (%1)\n" +- " movq %%mm1, 8(%1)\n" +- " movq %%mm2, 16(%1)\n" +- " movq %%mm3, 24(%1)\n" +- " movq 32(%0), %%mm0\n" +- " movq 40(%0), %%mm1\n" +- " movq 48(%0), %%mm2\n" +- " movq 56(%0), %%mm3\n" +- " movq %%mm0, 32(%1)\n" +- " movq %%mm1, 40(%1)\n" +- " movq %%mm2, 48(%1)\n" +- " movq %%mm3, 56(%1)\n" ++ "1: prefetch 320(%1)\n" ++ "2: movq (%1), %%mm0\n" ++ " movq 8(%1), %%mm1\n" ++ " movq 16(%1), %%mm2\n" ++ " movq 24(%1), %%mm3\n" ++ " movq %%mm0, (%2)\n" ++ " movq %%mm1, 8(%2)\n" ++ " movq %%mm2, 16(%2)\n" ++ " movq %%mm3, 24(%2)\n" ++ " movq 32(%1), %%mm0\n" ++ " movq 40(%1), %%mm1\n" ++ " movq 48(%1), %%mm2\n" ++ " movq 56(%1), %%mm3\n" ++ " movq %%mm0, 32(%2)\n" ++ " movq %%mm1, 40(%2)\n" ++ " movq %%mm2, 48(%2)\n" ++ " movq %%mm3, 56(%2)\n" + ".section .fixup, "ax"\n" +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ ++ "3:\n" ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %%cr0, %0\n" ++ " movl %0, %%eax\n" ++ " andl $0xFFFEFFFF, %%eax\n" ++ " movl %%eax, %%cr0\n" ++#endif ++ ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %0, %%cr0\n" ++#endif ++ + " jmp 2b\n" + ".previous\n" + _ASM_EXTABLE(1b, 3b) +- : : "r" (from), "r" (to) : "memory"); ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); + + from += 64; + to += 64; +@@ -158,6 +187,7 @@ static void fast_clear_page(void *page) + static void fast_copy_page(void *to, void *from) + { + int i; ++ unsigned long cr0; + + kernel_fpu_begin(); + +@@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi + * but that is for later. -AV + */ + __asm__ __volatile__( +- "1: prefetch (%0)\n" +- " prefetch 64(%0)\n" +- " prefetch 128(%0)\n" +- " prefetch 192(%0)\n" +- " prefetch 256(%0)\n" ++ "1: prefetch (%1)\n" ++ " prefetch 64(%1)\n" ++ " prefetch 128(%1)\n" ++ " prefetch 192(%1)\n" ++ " prefetch 256(%1)\n" + "2: \n" + ".section .fixup, "ax"\n" +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ ++ "3: \n" ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %%cr0, %0\n" ++ " movl %0, %%eax\n" ++ " andl $0xFFFEFFFF, %%eax\n" ++ " movl %%eax, %%cr0\n" ++#endif ++ ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %0, %%cr0\n" ++#endif ++ + " jmp 2b\n" + ".previous\n" +- _ASM_EXTABLE(1b, 3b) : : "r" (from)); ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax"); + + for (i = 0; i < (4096-320)/64; i++) { + __asm__ __volatile__ ( +- "1: prefetch 320(%0)\n" +- "2: movq (%0), %%mm0\n" +- " movntq %%mm0, (%1)\n" +- " movq 8(%0), %%mm1\n" +- " movntq %%mm1, 8(%1)\n" +- " movq 16(%0), %%mm2\n" +- " movntq %%mm2, 16(%1)\n" +- " movq 24(%0), %%mm3\n" +- " movntq %%mm3, 24(%1)\n" +- " movq 32(%0), %%mm4\n" +- " movntq %%mm4, 32(%1)\n" +- " movq 40(%0), %%mm5\n" +- " movntq %%mm5, 40(%1)\n" +- " movq 48(%0), %%mm6\n" +- " movntq %%mm6, 48(%1)\n" +- " movq 56(%0), %%mm7\n" +- " movntq %%mm7, 56(%1)\n" ++ "1: prefetch 320(%1)\n" ++ "2: movq (%1), %%mm0\n" ++ " movntq %%mm0, (%2)\n" ++ " movq 8(%1), %%mm1\n" ++ " movntq %%mm1, 8(%2)\n" ++ " movq 16(%1), %%mm2\n" ++ " movntq %%mm2, 16(%2)\n" ++ " movq 24(%1), %%mm3\n" ++ " movntq %%mm3, 24(%2)\n" ++ " movq 32(%1), %%mm4\n" ++ " movntq %%mm4, 32(%2)\n" ++ " movq 40(%1), %%mm5\n" ++ " movntq %%mm5, 40(%2)\n" ++ " movq 48(%1), %%mm6\n" ++ " movntq %%mm6, 48(%2)\n" ++ " movq 56(%1), %%mm7\n" ++ " movntq %%mm7, 56(%2)\n" + ".section .fixup, "ax"\n" +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ ++ "3:\n" ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %%cr0, %0\n" ++ " movl %0, %%eax\n" ++ " andl $0xFFFEFFFF, %%eax\n" ++ " movl %%eax, %%cr0\n" ++#endif ++ ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %0, %%cr0\n" ++#endif ++ + " jmp 2b\n" + ".previous\n" +- _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory"); ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); + + from += 64; + to += 64; +@@ -280,47 +338,76 @@ static void fast_clear_page(void *page) + static void fast_copy_page(void *to, void *from) + { + int i; ++ unsigned long cr0; + + kernel_fpu_begin(); + + __asm__ __volatile__ ( +- "1: prefetch (%0)\n" +- " prefetch 64(%0)\n" +- " prefetch 128(%0)\n" +- " prefetch 192(%0)\n" +- " prefetch 256(%0)\n" ++ "1: prefetch (%1)\n" ++ " prefetch 64(%1)\n" ++ " prefetch 128(%1)\n" ++ " prefetch 192(%1)\n" ++ " prefetch 256(%1)\n" + "2: \n" + ".section .fixup, "ax"\n" +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ ++ "3: \n" ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %%cr0, %0\n" ++ " movl %0, %%eax\n" ++ " andl $0xFFFEFFFF, %%eax\n" ++ " movl %%eax, %%cr0\n" ++#endif ++ ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %0, %%cr0\n" ++#endif ++ + " jmp 2b\n" + ".previous\n" +- _ASM_EXTABLE(1b, 3b) : : "r" (from)); ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax"); + + for (i = 0; i < 4096/64; i++) { + __asm__ __volatile__ ( +- "1: prefetch 320(%0)\n" +- "2: movq (%0), %%mm0\n" +- " movq 8(%0), %%mm1\n" +- " movq 16(%0), %%mm2\n" +- " movq 24(%0), %%mm3\n" +- " movq %%mm0, (%1)\n" +- " movq %%mm1, 8(%1)\n" +- " movq %%mm2, 16(%1)\n" +- " movq %%mm3, 24(%1)\n" +- " movq 32(%0), %%mm0\n" +- " movq 40(%0), %%mm1\n" +- " movq 48(%0), %%mm2\n" +- " movq 56(%0), %%mm3\n" +- " movq %%mm0, 32(%1)\n" +- " movq %%mm1, 40(%1)\n" +- " movq %%mm2, 48(%1)\n" +- " movq %%mm3, 56(%1)\n" ++ "1: prefetch 320(%1)\n" ++ "2: movq (%1), %%mm0\n" ++ " movq 8(%1), %%mm1\n" ++ " movq 16(%1), %%mm2\n" ++ " movq 24(%1), %%mm3\n" ++ " movq %%mm0, (%2)\n" ++ " movq %%mm1, 8(%2)\n" ++ " movq %%mm2, 16(%2)\n" ++ " movq %%mm3, 24(%2)\n" ++ " movq 32(%1), %%mm0\n" ++ " movq 40(%1), %%mm1\n" ++ " movq 48(%1), %%mm2\n" ++ " movq 56(%1), %%mm3\n" ++ " movq %%mm0, 32(%2)\n" ++ " movq %%mm1, 40(%2)\n" ++ " movq %%mm2, 48(%2)\n" ++ " movq %%mm3, 56(%2)\n" + ".section .fixup, "ax"\n" +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ ++ "3:\n" ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %%cr0, %0\n" ++ " movl %0, %%eax\n" ++ " andl $0xFFFEFFFF, %%eax\n" ++ " movl %%eax, %%cr0\n" ++#endif ++ ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ " movl %0, %%cr0\n" ++#endif ++ + " jmp 2b\n" + ".previous\n" + _ASM_EXTABLE(1b, 3b) +- : : "r" (from), "r" (to) : "memory"); ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); + + from += 64; + to += 64; +diff -urNp linux-2.6.31.1/arch/x86/lib/putuser.S linux-2.6.31.1/arch/x86/lib/putuser.S +--- linux-2.6.31.1/arch/x86/lib/putuser.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/putuser.S 2009-10-01 20:12:42.000000000 -0400 +@@ -15,6 +15,7 @@ + #include <asm/thread_info.h> + #include <asm/errno.h> + #include <asm/asm.h> ++#include <asm/segment.h> + + + /* +@@ -39,7 +40,19 @@ ENTRY(__put_user_1) + ENTER + cmp TI_addr_limit(%_ASM_BX),%_ASM_CX + jae bad_put_user ++ ++#ifdef CONFIG_X86_32 ++ pushl $(__USER_DS) ++ popl %ds ++#endif ++ + 1: movb %al,(%_ASM_CX) ++ ++#ifdef CONFIG_X86_32 ++ pushl %ss ++ popl %ds ++#endif ++ + xor %eax,%eax + EXIT + ENDPROC(__put_user_1) +@@ -50,7 +63,19 @@ ENTRY(__put_user_2) + sub $1,%_ASM_BX + cmp %_ASM_BX,%_ASM_CX + jae bad_put_user ++ ++#ifdef CONFIG_X86_32 ++ pushl $(__USER_DS) ++ popl %ds ++#endif ++ + 2: movw %ax,(%_ASM_CX) ++ ++#ifdef CONFIG_X86_32 ++ pushl %ss ++ popl %ds ++#endif ++ + xor %eax,%eax + EXIT + ENDPROC(__put_user_2) +@@ -61,7 +86,19 @@ ENTRY(__put_user_4) + sub $3,%_ASM_BX + cmp %_ASM_BX,%_ASM_CX + jae bad_put_user ++ ++#ifdef CONFIG_X86_32 ++ pushl $(__USER_DS) ++ popl %ds ++#endif ++ + 3: movl %eax,(%_ASM_CX) ++ ++#ifdef CONFIG_X86_32 ++ pushl %ss ++ popl %ds ++#endif ++ + xor %eax,%eax + EXIT + ENDPROC(__put_user_4) +@@ -72,16 +109,34 @@ ENTRY(__put_user_8) + sub $7,%_ASM_BX + cmp %_ASM_BX,%_ASM_CX + jae bad_put_user ++ ++#ifdef CONFIG_X86_32 ++ pushl $(__USER_DS) ++ popl %ds ++#endif ++ + 4: mov %_ASM_AX,(%_ASM_CX) + #ifdef CONFIG_X86_32 + 5: movl %edx,4(%_ASM_CX) + #endif ++ ++#ifdef CONFIG_X86_32 ++ pushl %ss ++ popl %ds ++#endif ++ + xor %eax,%eax + EXIT + ENDPROC(__put_user_8) + + bad_put_user: + CFI_STARTPROC ++ ++#ifdef CONFIG_X86_32 ++ pushl %ss ++ popl %ds ++#endif ++ + movl $-EFAULT,%eax + EXIT + END(bad_put_user) +diff -urNp linux-2.6.31.1/arch/x86/lib/usercopy_32.c linux-2.6.31.1/arch/x86/lib/usercopy_32.c +--- linux-2.6.31.1/arch/x86/lib/usercopy_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/lib/usercopy_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -36,31 +36,38 @@ static inline int __movsl_is_ok(unsigned + * Copy a null terminated string from userspace. + */ + +-#define __do_strncpy_from_user(dst, src, count, res) \ +-do { \ +- int __d0, __d1, __d2; \ +- might_fault(); \ +- __asm__ __volatile__( \ +- " testl %1,%1\n" \ +- " jz 2f\n" \ +- "0: lodsb\n" \ +- " stosb\n" \ +- " testb %%al,%%al\n" \ +- " jz 1f\n" \ +- " decl %1\n" \ +- " jnz 0b\n" \ +- "1: subl %1,%0\n" \ +- "2:\n" \ +- ".section .fixup,"ax"\n" \ +- "3: movl %5,%0\n" \ +- " jmp 2b\n" \ +- ".previous\n" \ +- _ASM_EXTABLE(0b,3b) \ +- : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \ +- "=&D" (__d2) \ +- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ +- : "memory"); \ +-} while (0) ++static long __do_strncpy_from_user(char *dst, const char __user *src, long count) ++{ ++ int __d0, __d1, __d2; ++ long res = -EFAULT; ++ ++ might_fault(); ++ __asm__ __volatile__( ++ " movw %w10,%%ds\n" ++ " testl %1,%1\n" ++ " jz 2f\n" ++ "0: lodsb\n" ++ " stosb\n" ++ " testb %%al,%%al\n" ++ " jz 1f\n" ++ " decl %1\n" ++ " jnz 0b\n" ++ "1: subl %1,%0\n" ++ "2:\n" ++ " pushl %%ss\n" ++ " popl %%ds\n" ++ ".section .fixup,"ax"\n" ++ "3: movl %5,%0\n" ++ " jmp 2b\n" ++ ".previous\n" ++ _ASM_EXTABLE(0b,3b) ++ : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), ++ "=&D" (__d2) ++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst), ++ "r"(__USER_DS) ++ : "memory"); ++ return res; ++} + + /** + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking. +@@ -85,9 +92,7 @@ do { \ + long + __strncpy_from_user(char *dst, const char __user *src, long count) + { +- long res; +- __do_strncpy_from_user(dst, src, count, res); +- return res; ++ return __do_strncpy_from_user(dst, src, count); + } + EXPORT_SYMBOL(__strncpy_from_user); + +@@ -114,7 +119,7 @@ strncpy_from_user(char *dst, const char + { + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) +- __do_strncpy_from_user(dst, src, count, res); ++ res = __do_strncpy_from_user(dst, src, count); + return res; + } + EXPORT_SYMBOL(strncpy_from_user); +@@ -123,24 +128,30 @@ EXPORT_SYMBOL(strncpy_from_user); + * Zero Userspace + */ + +-#define __do_clear_user(addr,size) \ +-do { \ +- int __d0; \ +- might_fault(); \ +- __asm__ __volatile__( \ +- "0: rep; stosl\n" \ +- " movl %2,%0\n" \ +- "1: rep; stosb\n" \ +- "2:\n" \ +- ".section .fixup,"ax"\n" \ +- "3: lea 0(%2,%0,4),%0\n" \ +- " jmp 2b\n" \ +- ".previous\n" \ +- _ASM_EXTABLE(0b,3b) \ +- _ASM_EXTABLE(1b,2b) \ +- : "=&c"(size), "=&D" (__d0) \ +- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \ +-} while (0) ++static unsigned long __do_clear_user(void __user *addr, unsigned long size) ++{ ++ int __d0; ++ ++ might_fault(); ++ __asm__ __volatile__( ++ " movw %w6,%%es\n" ++ "0: rep; stosl\n" ++ " movl %2,%0\n" ++ "1: rep; stosb\n" ++ "2:\n" ++ " pushl %%ss\n" ++ " popl %%es\n" ++ ".section .fixup,"ax"\n" ++ "3: lea 0(%2,%0,4),%0\n" ++ " jmp 2b\n" ++ ".previous\n" ++ _ASM_EXTABLE(0b,3b) ++ _ASM_EXTABLE(1b,2b) ++ : "=&c"(size), "=&D" (__d0) ++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0), ++ "r"(__USER_DS)); ++ return size; ++} + + /** + * clear_user: - Zero a block of memory in user space. +@@ -157,7 +168,7 @@ clear_user(void __user *to, unsigned lon + { + might_fault(); + if (access_ok(VERIFY_WRITE, to, n)) +- __do_clear_user(to, n); ++ n = __do_clear_user(to, n); + return n; + } + EXPORT_SYMBOL(clear_user); +@@ -176,8 +187,7 @@ EXPORT_SYMBOL(clear_user); + unsigned long + __clear_user(void __user *to, unsigned long n) + { +- __do_clear_user(to, n); +- return n; ++ return __do_clear_user(to, n); + } + EXPORT_SYMBOL(__clear_user); + +@@ -200,14 +210,17 @@ long strnlen_user(const char __user *s, + might_fault(); + + __asm__ __volatile__( ++ " movw %w8,%%es\n" + " testl %0, %0\n" + " jz 3f\n" +- " andl %0,%%ecx\n" ++ " movl %0,%%ecx\n" + "0: repne; scasb\n" + " setne %%al\n" + " subl %%ecx,%0\n" + " addl %0,%%eax\n" + "1:\n" ++ " pushl %%ss\n" ++ " popl %%es\n" + ".section .fixup,"ax"\n" + "2: xorl %%eax,%%eax\n" + " jmp 1b\n" +@@ -219,7 +232,7 @@ long strnlen_user(const char __user *s, + " .long 0b,2b\n" + ".previous" + :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp) +- :"0" (n), "1" (s), "2" (0), "3" (mask) ++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS) + :"cc"); + return res & mask; + } +@@ -227,10 +240,121 @@ EXPORT_SYMBOL(strnlen_user); + + #ifdef CONFIG_X86_INTEL_USERCOPY + static unsigned long +-__copy_user_intel(void __user *to, const void *from, unsigned long size) ++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size) ++{ ++ int d0, d1; ++ __asm__ __volatile__( ++ " movw %w6, %%es\n" ++ " .align 2,0x90\n" ++ "1: movl 32(%4), %%eax\n" ++ " cmpl $67, %0\n" ++ " jbe 3f\n" ++ "2: movl 64(%4), %%eax\n" ++ " .align 2,0x90\n" ++ "3: movl 0(%4), %%eax\n" ++ "4: movl 4(%4), %%edx\n" ++ "5: movl %%eax, %%es:0(%3)\n" ++ "6: movl %%edx, %%es:4(%3)\n" ++ "7: movl 8(%4), %%eax\n" ++ "8: movl 12(%4),%%edx\n" ++ "9: movl %%eax, %%es:8(%3)\n" ++ "10: movl %%edx, %%es:12(%3)\n" ++ "11: movl 16(%4), %%eax\n" ++ "12: movl 20(%4), %%edx\n" ++ "13: movl %%eax, %%es:16(%3)\n" ++ "14: movl %%edx, %%es:20(%3)\n" ++ "15: movl 24(%4), %%eax\n" ++ "16: movl 28(%4), %%edx\n" ++ "17: movl %%eax, %%es:24(%3)\n" ++ "18: movl %%edx, %%es:28(%3)\n" ++ "19: movl 32(%4), %%eax\n" ++ "20: movl 36(%4), %%edx\n" ++ "21: movl %%eax, %%es:32(%3)\n" ++ "22: movl %%edx, %%es:36(%3)\n" ++ "23: movl 40(%4), %%eax\n" ++ "24: movl 44(%4), %%edx\n" ++ "25: movl %%eax, %%es:40(%3)\n" ++ "26: movl %%edx, %%es:44(%3)\n" ++ "27: movl 48(%4), %%eax\n" ++ "28: movl 52(%4), %%edx\n" ++ "29: movl %%eax, %%es:48(%3)\n" ++ "30: movl %%edx, %%es:52(%3)\n" ++ "31: movl 56(%4), %%eax\n" ++ "32: movl 60(%4), %%edx\n" ++ "33: movl %%eax, %%es:56(%3)\n" ++ "34: movl %%edx, %%es:60(%3)\n" ++ " addl $-64, %0\n" ++ " addl $64, %4\n" ++ " addl $64, %3\n" ++ " cmpl $63, %0\n" ++ " ja 1b\n" ++ "35: movl %0, %%eax\n" ++ " shrl $2, %0\n" ++ " andl $3, %%eax\n" ++ " cld\n" ++ "99: rep; movsl\n" ++ "36: movl %%eax, %0\n" ++ "37: rep; movsb\n" ++ "100:\n" ++ " pushl %%ss\n" ++ " popl %%es\n" ++ ".section .fixup,"ax"\n" ++ "101: lea 0(%%eax,%0,4),%0\n" ++ " jmp 100b\n" ++ ".previous\n" ++ ".section __ex_table,"a"\n" ++ " .align 4\n" ++ " .long 1b,100b\n" ++ " .long 2b,100b\n" ++ " .long 3b,100b\n" ++ " .long 4b,100b\n" ++ " .long 5b,100b\n" ++ " .long 6b,100b\n" ++ " .long 7b,100b\n" ++ " .long 8b,100b\n" ++ " .long 9b,100b\n" ++ " .long 10b,100b\n" ++ " .long 11b,100b\n" ++ " .long 12b,100b\n" ++ " .long 13b,100b\n" ++ " .long 14b,100b\n" ++ " .long 15b,100b\n" ++ " .long 16b,100b\n" ++ " .long 17b,100b\n" ++ " .long 18b,100b\n" ++ " .long 19b,100b\n" ++ " .long 20b,100b\n" ++ " .long 21b,100b\n" ++ " .long 22b,100b\n" ++ " .long 23b,100b\n" ++ " .long 24b,100b\n" ++ " .long 25b,100b\n" ++ " .long 26b,100b\n" ++ " .long 27b,100b\n" ++ " .long 28b,100b\n" ++ " .long 29b,100b\n" ++ " .long 30b,100b\n" ++ " .long 31b,100b\n" ++ " .long 32b,100b\n" ++ " .long 33b,100b\n" ++ " .long 34b,100b\n" ++ " .long 35b,100b\n" ++ " .long 36b,100b\n" ++ " .long 37b,100b\n" ++ " .long 99b,101b\n" ++ ".previous" ++ : "=&c"(size), "=&D" (d0), "=&S" (d1) ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) ++ : "eax", "edx", "memory"); ++ return size; ++} ++ ++static unsigned long ++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size) + { + int d0, d1; + __asm__ __volatile__( ++ " movw %w6, %%ds\n" + " .align 2,0x90\n" + "1: movl 32(%4), %%eax\n" + " cmpl $67, %0\n" +@@ -239,36 +363,36 @@ __copy_user_intel(void __user *to, const + " .align 2,0x90\n" + "3: movl 0(%4), %%eax\n" + "4: movl 4(%4), %%edx\n" +- "5: movl %%eax, 0(%3)\n" +- "6: movl %%edx, 4(%3)\n" ++ "5: movl %%eax, %%es:0(%3)\n" ++ "6: movl %%edx, %%es:4(%3)\n" + "7: movl 8(%4), %%eax\n" + "8: movl 12(%4),%%edx\n" +- "9: movl %%eax, 8(%3)\n" +- "10: movl %%edx, 12(%3)\n" ++ "9: movl %%eax, %%es:8(%3)\n" ++ "10: movl %%edx, %%es:12(%3)\n" + "11: movl 16(%4), %%eax\n" + "12: movl 20(%4), %%edx\n" +- "13: movl %%eax, 16(%3)\n" +- "14: movl %%edx, 20(%3)\n" ++ "13: movl %%eax, %%es:16(%3)\n" ++ "14: movl %%edx, %%es:20(%3)\n" + "15: movl 24(%4), %%eax\n" + "16: movl 28(%4), %%edx\n" +- "17: movl %%eax, 24(%3)\n" +- "18: movl %%edx, 28(%3)\n" ++ "17: movl %%eax, %%es:24(%3)\n" ++ "18: movl %%edx, %%es:28(%3)\n" + "19: movl 32(%4), %%eax\n" + "20: movl 36(%4), %%edx\n" +- "21: movl %%eax, 32(%3)\n" +- "22: movl %%edx, 36(%3)\n" ++ "21: movl %%eax, %%es:32(%3)\n" ++ "22: movl %%edx, %%es:36(%3)\n" + "23: movl 40(%4), %%eax\n" + "24: movl 44(%4), %%edx\n" +- "25: movl %%eax, 40(%3)\n" +- "26: movl %%edx, 44(%3)\n" ++ "25: movl %%eax, %%es:40(%3)\n" ++ "26: movl %%edx, %%es:44(%3)\n" + "27: movl 48(%4), %%eax\n" + "28: movl 52(%4), %%edx\n" +- "29: movl %%eax, 48(%3)\n" +- "30: movl %%edx, 52(%3)\n" ++ "29: movl %%eax, %%es:48(%3)\n" ++ "30: movl %%edx, %%es:52(%3)\n" + "31: movl 56(%4), %%eax\n" + "32: movl 60(%4), %%edx\n" +- "33: movl %%eax, 56(%3)\n" +- "34: movl %%edx, 60(%3)\n" ++ "33: movl %%eax, %%es:56(%3)\n" ++ "34: movl %%edx, %%es:60(%3)\n" + " addl $-64, %0\n" + " addl $64, %4\n" + " addl $64, %3\n" +@@ -282,6 +406,8 @@ __copy_user_intel(void __user *to, const + "36: movl %%eax, %0\n" + "37: rep; movsb\n" + "100:\n" ++ " pushl %%ss\n" ++ " popl %%ds\n" + ".section .fixup,"ax"\n" + "101: lea 0(%%eax,%0,4),%0\n" + " jmp 100b\n" +@@ -328,7 +454,7 @@ __copy_user_intel(void __user *to, const + " .long 99b,101b\n" + ".previous" + : "=&c"(size), "=&D" (d0), "=&S" (d1) +- : "1"(to), "2"(from), "0"(size) ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) + : "eax", "edx", "memory"); + return size; + } +@@ -338,6 +464,7 @@ __copy_user_zeroing_intel(void *to, cons + { + int d0, d1; + __asm__ __volatile__( ++ " movw %w6, %%ds\n" + " .align 2,0x90\n" + "0: movl 32(%4), %%eax\n" + " cmpl $67, %0\n" +@@ -346,36 +473,36 @@ __copy_user_zeroing_intel(void *to, cons + " .align 2,0x90\n" + "2: movl 0(%4), %%eax\n" + "21: movl 4(%4), %%edx\n" +- " movl %%eax, 0(%3)\n" +- " movl %%edx, 4(%3)\n" ++ " movl %%eax, %%es:0(%3)\n" ++ " movl %%edx, %%es:4(%3)\n" + "3: movl 8(%4), %%eax\n" + "31: movl 12(%4),%%edx\n" +- " movl %%eax, 8(%3)\n" +- " movl %%edx, 12(%3)\n" ++ " movl %%eax, %%es:8(%3)\n" ++ " movl %%edx, %%es:12(%3)\n" + "4: movl 16(%4), %%eax\n" + "41: movl 20(%4), %%edx\n" +- " movl %%eax, 16(%3)\n" +- " movl %%edx, 20(%3)\n" ++ " movl %%eax, %%es:16(%3)\n" ++ " movl %%edx, %%es:20(%3)\n" + "10: movl 24(%4), %%eax\n" + "51: movl 28(%4), %%edx\n" +- " movl %%eax, 24(%3)\n" +- " movl %%edx, 28(%3)\n" ++ " movl %%eax, %%es:24(%3)\n" ++ " movl %%edx, %%es:28(%3)\n" + "11: movl 32(%4), %%eax\n" + "61: movl 36(%4), %%edx\n" +- " movl %%eax, 32(%3)\n" +- " movl %%edx, 36(%3)\n" ++ " movl %%eax, %%es:32(%3)\n" ++ " movl %%edx, %%es:36(%3)\n" + "12: movl 40(%4), %%eax\n" + "71: movl 44(%4), %%edx\n" +- " movl %%eax, 40(%3)\n" +- " movl %%edx, 44(%3)\n" ++ " movl %%eax, %%es:40(%3)\n" ++ " movl %%edx, %%es:44(%3)\n" + "13: movl 48(%4), %%eax\n" + "81: movl 52(%4), %%edx\n" +- " movl %%eax, 48(%3)\n" +- " movl %%edx, 52(%3)\n" ++ " movl %%eax, %%es:48(%3)\n" ++ " movl %%edx, %%es:52(%3)\n" + "14: movl 56(%4), %%eax\n" + "91: movl 60(%4), %%edx\n" +- " movl %%eax, 56(%3)\n" +- " movl %%edx, 60(%3)\n" ++ " movl %%eax, %%es:56(%3)\n" ++ " movl %%edx, %%es:60(%3)\n" + " addl $-64, %0\n" + " addl $64, %4\n" + " addl $64, %3\n" +@@ -389,6 +516,8 @@ __copy_user_zeroing_intel(void *to, cons + " movl %%eax,%0\n" + "7: rep; movsb\n" + "8:\n" ++ " pushl %%ss\n" ++ " popl %%ds\n" + ".section .fixup,"ax"\n" + "9: lea 0(%%eax,%0,4),%0\n" + "16: pushl %0\n" +@@ -423,7 +552,7 @@ __copy_user_zeroing_intel(void *to, cons + " .long 7b,16b\n" + ".previous" + : "=&c"(size), "=&D" (d0), "=&S" (d1) +- : "1"(to), "2"(from), "0"(size) ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) + : "eax", "edx", "memory"); + return size; + } +@@ -439,6 +568,7 @@ static unsigned long __copy_user_zeroing + int d0, d1; + + __asm__ __volatile__( ++ " movw %w6, %%ds\n" + " .align 2,0x90\n" + "0: movl 32(%4), %%eax\n" + " cmpl $67, %0\n" +@@ -447,36 +577,36 @@ static unsigned long __copy_user_zeroing + " .align 2,0x90\n" + "2: movl 0(%4), %%eax\n" + "21: movl 4(%4), %%edx\n" +- " movnti %%eax, 0(%3)\n" +- " movnti %%edx, 4(%3)\n" ++ " movnti %%eax, %%es:0(%3)\n" ++ " movnti %%edx, %%es:4(%3)\n" + "3: movl 8(%4), %%eax\n" + "31: movl 12(%4),%%edx\n" +- " movnti %%eax, 8(%3)\n" +- " movnti %%edx, 12(%3)\n" ++ " movnti %%eax, %%es:8(%3)\n" ++ " movnti %%edx, %%es:12(%3)\n" + "4: movl 16(%4), %%eax\n" + "41: movl 20(%4), %%edx\n" +- " movnti %%eax, 16(%3)\n" +- " movnti %%edx, 20(%3)\n" ++ " movnti %%eax, %%es:16(%3)\n" ++ " movnti %%edx, %%es:20(%3)\n" + "10: movl 24(%4), %%eax\n" + "51: movl 28(%4), %%edx\n" +- " movnti %%eax, 24(%3)\n" +- " movnti %%edx, 28(%3)\n" ++ " movnti %%eax, %%es:24(%3)\n" ++ " movnti %%edx, %%es:28(%3)\n" + "11: movl 32(%4), %%eax\n" + "61: movl 36(%4), %%edx\n" +- " movnti %%eax, 32(%3)\n" +- " movnti %%edx, 36(%3)\n" ++ " movnti %%eax, %%es:32(%3)\n" ++ " movnti %%edx, %%es:36(%3)\n" + "12: movl 40(%4), %%eax\n" + "71: movl 44(%4), %%edx\n" +- " movnti %%eax, 40(%3)\n" +- " movnti %%edx, 44(%3)\n" ++ " movnti %%eax, %%es:40(%3)\n" ++ " movnti %%edx, %%es:44(%3)\n" + "13: movl 48(%4), %%eax\n" + "81: movl 52(%4), %%edx\n" +- " movnti %%eax, 48(%3)\n" +- " movnti %%edx, 52(%3)\n" ++ " movnti %%eax, %%es:48(%3)\n" ++ " movnti %%edx, %%es:52(%3)\n" + "14: movl 56(%4), %%eax\n" + "91: movl 60(%4), %%edx\n" +- " movnti %%eax, 56(%3)\n" +- " movnti %%edx, 60(%3)\n" ++ " movnti %%eax, %%es:56(%3)\n" ++ " movnti %%edx, %%es:60(%3)\n" + " addl $-64, %0\n" + " addl $64, %4\n" + " addl $64, %3\n" +@@ -491,6 +621,8 @@ static unsigned long __copy_user_zeroing + " movl %%eax,%0\n" + "7: rep; movsb\n" + "8:\n" ++ " pushl %%ss\n" ++ " popl %%ds\n" + ".section .fixup,"ax"\n" + "9: lea 0(%%eax,%0,4),%0\n" + "16: pushl %0\n" +@@ -525,7 +657,7 @@ static unsigned long __copy_user_zeroing + " .long 7b,16b\n" + ".previous" + : "=&c"(size), "=&D" (d0), "=&S" (d1) +- : "1"(to), "2"(from), "0"(size) ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) + : "eax", "edx", "memory"); + return size; + } +@@ -536,6 +668,7 @@ static unsigned long __copy_user_intel_n + int d0, d1; + + __asm__ __volatile__( ++ " movw %w6, %%ds\n" + " .align 2,0x90\n" + "0: movl 32(%4), %%eax\n" + " cmpl $67, %0\n" +@@ -544,36 +677,36 @@ static unsigned long __copy_user_intel_n + " .align 2,0x90\n" + "2: movl 0(%4), %%eax\n" + "21: movl 4(%4), %%edx\n" +- " movnti %%eax, 0(%3)\n" +- " movnti %%edx, 4(%3)\n" ++ " movnti %%eax, %%es:0(%3)\n" ++ " movnti %%edx, %%es:4(%3)\n" + "3: movl 8(%4), %%eax\n" + "31: movl 12(%4),%%edx\n" +- " movnti %%eax, 8(%3)\n" +- " movnti %%edx, 12(%3)\n" ++ " movnti %%eax, %%es:8(%3)\n" ++ " movnti %%edx, %%es:12(%3)\n" + "4: movl 16(%4), %%eax\n" + "41: movl 20(%4), %%edx\n" +- " movnti %%eax, 16(%3)\n" +- " movnti %%edx, 20(%3)\n" ++ " movnti %%eax, %%es:16(%3)\n" ++ " movnti %%edx, %%es:20(%3)\n" + "10: movl 24(%4), %%eax\n" + "51: movl 28(%4), %%edx\n" +- " movnti %%eax, 24(%3)\n" +- " movnti %%edx, 28(%3)\n" ++ " movnti %%eax, %%es:24(%3)\n" ++ " movnti %%edx, %%es:28(%3)\n" + "11: movl 32(%4), %%eax\n" + "61: movl 36(%4), %%edx\n" +- " movnti %%eax, 32(%3)\n" +- " movnti %%edx, 36(%3)\n" ++ " movnti %%eax, %%es:32(%3)\n" ++ " movnti %%edx, %%es:36(%3)\n" + "12: movl 40(%4), %%eax\n" + "71: movl 44(%4), %%edx\n" +- " movnti %%eax, 40(%3)\n" +- " movnti %%edx, 44(%3)\n" ++ " movnti %%eax, %%es:40(%3)\n" ++ " movnti %%edx, %%es:44(%3)\n" + "13: movl 48(%4), %%eax\n" + "81: movl 52(%4), %%edx\n" +- " movnti %%eax, 48(%3)\n" +- " movnti %%edx, 52(%3)\n" ++ " movnti %%eax, %%es:48(%3)\n" ++ " movnti %%edx, %%es:52(%3)\n" + "14: movl 56(%4), %%eax\n" + "91: movl 60(%4), %%edx\n" +- " movnti %%eax, 56(%3)\n" +- " movnti %%edx, 60(%3)\n" ++ " movnti %%eax, %%es:56(%3)\n" ++ " movnti %%edx, %%es:60(%3)\n" + " addl $-64, %0\n" + " addl $64, %4\n" + " addl $64, %3\n" +@@ -588,6 +721,8 @@ static unsigned long __copy_user_intel_n + " movl %%eax,%0\n" + "7: rep; movsb\n" + "8:\n" ++ " pushl %%ss\n" ++ " popl %%ds\n" + ".section .fixup,"ax"\n" + "9: lea 0(%%eax,%0,4),%0\n" + "16: jmp 8b\n" +@@ -616,7 +751,7 @@ static unsigned long __copy_user_intel_n + " .long 7b,16b\n" + ".previous" + : "=&c"(size), "=&D" (d0), "=&S" (d1) +- : "1"(to), "2"(from), "0"(size) ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) + : "eax", "edx", "memory"); + return size; + } +@@ -629,90 +764,146 @@ static unsigned long __copy_user_intel_n + */ + unsigned long __copy_user_zeroing_intel(void *to, const void __user *from, + unsigned long size); +-unsigned long __copy_user_intel(void __user *to, const void *from, ++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from, ++ unsigned long size); ++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from, + unsigned long size); + unsigned long __copy_user_zeroing_intel_nocache(void *to, + const void __user *from, unsigned long size); + #endif /* CONFIG_X86_INTEL_USERCOPY */ + + /* Generic arbitrary sized copy. */ +-#define __copy_user(to, from, size) \ +-do { \ +- int __d0, __d1, __d2; \ +- __asm__ __volatile__( \ +- " cmp $7,%0\n" \ +- " jbe 1f\n" \ +- " movl %1,%0\n" \ +- " negl %0\n" \ +- " andl $7,%0\n" \ +- " subl %0,%3\n" \ +- "4: rep; movsb\n" \ +- " movl %3,%0\n" \ +- " shrl $2,%0\n" \ +- " andl $3,%3\n" \ +- " .align 2,0x90\n" \ +- "0: rep; movsl\n" \ +- " movl %3,%0\n" \ +- "1: rep; movsb\n" \ +- "2:\n" \ +- ".section .fixup,"ax"\n" \ +- "5: addl %3,%0\n" \ +- " jmp 2b\n" \ +- "3: lea 0(%3,%0,4),%0\n" \ +- " jmp 2b\n" \ +- ".previous\n" \ +- ".section __ex_table,"a"\n" \ +- " .align 4\n" \ +- " .long 4b,5b\n" \ +- " .long 0b,3b\n" \ +- " .long 1b,2b\n" \ +- ".previous" \ +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ +- : "3"(size), "0"(size), "1"(to), "2"(from) \ +- : "memory"); \ +-} while (0) +- +-#define __copy_user_zeroing(to, from, size) \ +-do { \ +- int __d0, __d1, __d2; \ +- __asm__ __volatile__( \ +- " cmp $7,%0\n" \ +- " jbe 1f\n" \ +- " movl %1,%0\n" \ +- " negl %0\n" \ +- " andl $7,%0\n" \ +- " subl %0,%3\n" \ +- "4: rep; movsb\n" \ +- " movl %3,%0\n" \ +- " shrl $2,%0\n" \ +- " andl $3,%3\n" \ +- " .align 2,0x90\n" \ +- "0: rep; movsl\n" \ +- " movl %3,%0\n" \ +- "1: rep; movsb\n" \ +- "2:\n" \ +- ".section .fixup,"ax"\n" \ +- "5: addl %3,%0\n" \ +- " jmp 6f\n" \ +- "3: lea 0(%3,%0,4),%0\n" \ +- "6: pushl %0\n" \ +- " pushl %%eax\n" \ +- " xorl %%eax,%%eax\n" \ +- " rep; stosb\n" \ +- " popl %%eax\n" \ +- " popl %0\n" \ +- " jmp 2b\n" \ +- ".previous\n" \ +- ".section __ex_table,"a"\n" \ +- " .align 4\n" \ +- " .long 4b,5b\n" \ +- " .long 0b,3b\n" \ +- " .long 1b,6b\n" \ +- ".previous" \ +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ +- : "3"(size), "0"(size), "1"(to), "2"(from) \ +- : "memory"); \ +-} while (0) ++static unsigned long ++__generic_copy_to_user(void __user *to, const void *from, unsigned long size) ++{ ++ int __d0, __d1, __d2; ++ ++ __asm__ __volatile__( ++ " movw %w8,%%es\n" ++ " cmp $7,%0\n" ++ " jbe 1f\n" ++ " movl %1,%0\n" ++ " negl %0\n" ++ " andl $7,%0\n" ++ " subl %0,%3\n" ++ "4: rep; movsb\n" ++ " movl %3,%0\n" ++ " shrl $2,%0\n" ++ " andl $3,%3\n" ++ " .align 2,0x90\n" ++ "0: rep; movsl\n" ++ " movl %3,%0\n" ++ "1: rep; movsb\n" ++ "2:\n" ++ " pushl %%ss\n" ++ " popl %%es\n" ++ ".section .fixup,"ax"\n" ++ "5: addl %3,%0\n" ++ " jmp 2b\n" ++ "3: lea 0(%3,%0,4),%0\n" ++ " jmp 2b\n" ++ ".previous\n" ++ ".section __ex_table,"a"\n" ++ " .align 4\n" ++ " .long 4b,5b\n" ++ " .long 0b,3b\n" ++ " .long 1b,2b\n" ++ ".previous" ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS) ++ : "memory"); ++ return size; ++} ++ ++static unsigned long ++__generic_copy_from_user(void *to, const void __user *from, unsigned long size) ++{ ++ int __d0, __d1, __d2; ++ ++ __asm__ __volatile__( ++ " movw %w8,%%ds\n" ++ " cmp $7,%0\n" ++ " jbe 1f\n" ++ " movl %1,%0\n" ++ " negl %0\n" ++ " andl $7,%0\n" ++ " subl %0,%3\n" ++ "4: rep; movsb\n" ++ " movl %3,%0\n" ++ " shrl $2,%0\n" ++ " andl $3,%3\n" ++ " .align 2,0x90\n" ++ "0: rep; movsl\n" ++ " movl %3,%0\n" ++ "1: rep; movsb\n" ++ "2:\n" ++ " pushl %%ss\n" ++ " popl %%ds\n" ++ ".section .fixup,"ax"\n" ++ "5: addl %3,%0\n" ++ " jmp 2b\n" ++ "3: lea 0(%3,%0,4),%0\n" ++ " jmp 2b\n" ++ ".previous\n" ++ ".section __ex_table,"a"\n" ++ " .align 4\n" ++ " .long 4b,5b\n" ++ " .long 0b,3b\n" ++ " .long 1b,2b\n" ++ ".previous" ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS) ++ : "memory"); ++ return size; ++} ++ ++static unsigned long ++__copy_user_zeroing(void *to, const void __user *from, unsigned long size) ++{ ++ int __d0, __d1, __d2; ++ ++ __asm__ __volatile__( ++ " movw %w8,%%ds\n" ++ " cmp $7,%0\n" ++ " jbe 1f\n" ++ " movl %1,%0\n" ++ " negl %0\n" ++ " andl $7,%0\n" ++ " subl %0,%3\n" ++ "4: rep; movsb\n" ++ " movl %3,%0\n" ++ " shrl $2,%0\n" ++ " andl $3,%3\n" ++ " .align 2,0x90\n" ++ "0: rep; movsl\n" ++ " movl %3,%0\n" ++ "1: rep; movsb\n" ++ "2:\n" ++ " pushl %%ss\n" ++ " popl %%ds\n" ++ ".section .fixup,"ax"\n" ++ "5: addl %3,%0\n" ++ " jmp 6f\n" ++ "3: lea 0(%3,%0,4),%0\n" ++ "6: pushl %0\n" ++ " pushl %%eax\n" ++ " xorl %%eax,%%eax\n" ++ " rep; stosb\n" ++ " popl %%eax\n" ++ " popl %0\n" ++ " jmp 2b\n" ++ ".previous\n" ++ ".section __ex_table,"a"\n" ++ " .align 4\n" ++ " .long 4b,5b\n" ++ " .long 0b,3b\n" ++ " .long 1b,6b\n" ++ ".previous" ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS) ++ : "memory"); ++ return size; ++} + + unsigned long __copy_to_user_ll(void __user *to, const void *from, + unsigned long n) +@@ -775,9 +966,9 @@ survive: + } + #endif + if (movsl_is_ok(to, from, n)) +- __copy_user(to, from, n); ++ n = __generic_copy_to_user(to, from, n); + else +- n = __copy_user_intel(to, from, n); ++ n = __generic_copy_to_user_intel(to, from, n); + return n; + } + EXPORT_SYMBOL(__copy_to_user_ll); +@@ -786,7 +977,7 @@ unsigned long __copy_from_user_ll(void * + unsigned long n) + { + if (movsl_is_ok(to, from, n)) +- __copy_user_zeroing(to, from, n); ++ n = __copy_user_zeroing(to, from, n); + else + n = __copy_user_zeroing_intel(to, from, n); + return n; +@@ -797,10 +988,9 @@ unsigned long __copy_from_user_ll_nozero + unsigned long n) + { + if (movsl_is_ok(to, from, n)) +- __copy_user(to, from, n); ++ n = __generic_copy_from_user(to, from, n); + else +- n = __copy_user_intel((void __user *)to, +- (const void *)from, n); ++ n = __generic_copy_from_user_intel(to, from, n); + return n; + } + EXPORT_SYMBOL(__copy_from_user_ll_nozero); +@@ -812,9 +1002,9 @@ unsigned long __copy_from_user_ll_nocach + if (n > 64 && cpu_has_xmm2) + n = __copy_user_zeroing_intel_nocache(to, from, n); + else +- __copy_user_zeroing(to, from, n); ++ n = __copy_user_zeroing(to, from, n); + #else +- __copy_user_zeroing(to, from, n); ++ n = __copy_user_zeroing(to, from, n); + #endif + return n; + } +@@ -827,59 +1017,37 @@ unsigned long __copy_from_user_ll_nocach + if (n > 64 && cpu_has_xmm2) + n = __copy_user_intel_nocache(to, from, n); + else +- __copy_user(to, from, n); ++ n = __generic_copy_from_user(to, from, n); + #else +- __copy_user(to, from, n); ++ n = __generic_copy_from_user(to, from, n); + #endif + return n; + } + EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero); + +-/** +- * copy_to_user: - Copy a block of data into user space. +- * @to: Destination address, in user space. +- * @from: Source address, in kernel space. +- * @n: Number of bytes to copy. +- * +- * Context: User context only. This function may sleep. +- * +- * Copy data from kernel space to user space. +- * +- * Returns number of bytes that could not be copied. +- * On success, this will be zero. +- */ +-unsigned long +-copy_to_user(void __user *to, const void *from, unsigned long n) ++#ifdef CONFIG_PAX_MEMORY_UDEREF ++void __set_fs(mm_segment_t x, int cpu) + { +- if (access_ok(VERIFY_WRITE, to, n)) +- n = __copy_to_user(to, from, n); +- return n; ++ unsigned long limit = x.seg; ++ struct desc_struct d; ++ ++ current_thread_info()->addr_limit = x; ++ if (likely(limit)) ++ limit = (limit - 1UL) >> PAGE_SHIFT; ++ pack_descriptor(&d, 0UL, limit, 0xF3, 0xC); ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S); + } +-EXPORT_SYMBOL(copy_to_user); + +-/** +- * copy_from_user: - Copy a block of data from user space. +- * @to: Destination address, in kernel space. +- * @from: Source address, in user space. +- * @n: Number of bytes to copy. +- * +- * Context: User context only. This function may sleep. +- * +- * Copy data from user space to kernel space. +- * +- * Returns number of bytes that could not be copied. +- * On success, this will be zero. +- * +- * If some data could not be copied, this function will pad the copied +- * data to the requested size using zero bytes. +- */ +-unsigned long +-copy_from_user(void *to, const void __user *from, unsigned long n) ++void set_fs(mm_segment_t x) + { +- if (access_ok(VERIFY_READ, from, n)) +- n = __copy_from_user(to, from, n); +- else +- memset(to, 0, n); +- return n; ++ __set_fs(x, get_cpu()); ++ put_cpu(); + } +-EXPORT_SYMBOL(copy_from_user); ++#else ++void set_fs(mm_segment_t x) ++{ ++ current_thread_info()->addr_limit = x; ++} ++#endif ++ ++EXPORT_SYMBOL(set_fs); +diff -urNp linux-2.6.31.1/arch/x86/Makefile linux-2.6.31.1/arch/x86/Makefile +--- linux-2.6.31.1/arch/x86/Makefile 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/Makefile 2009-10-01 20:12:42.000000000 -0400 +@@ -188,3 +188,12 @@ define archhelp + echo ' FDARGS="..." arguments for the booted kernel' + echo ' FDINITRD=file initrd for the booted kernel' + endef ++ ++define OLD_LD ++ ++*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils. ++*** Please upgrade your binutils to 2.18 or newer ++endef ++ ++archprepare: ++ $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD))) +diff -urNp linux-2.6.31.1/arch/x86/mm/extable.c linux-2.6.31.1/arch/x86/mm/extable.c +--- linux-2.6.31.1/arch/x86/mm/extable.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/extable.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1,14 +1,81 @@ + #include <linux/module.h> + #include <linux/spinlock.h> ++#include <linux/sort.h> + #include <asm/uaccess.h> + ++/* ++ * The exception table needs to be sorted so that the binary ++ * search that we use to find entries in it works properly. ++ * This is used both for the kernel exception table and for ++ * the exception tables of modules that get loaded. ++ */ ++static int cmp_ex(const void *a, const void *b) ++{ ++ const struct exception_table_entry *x = a, *y = b; ++ ++ /* avoid overflow */ ++ if (x->insn > y->insn) ++ return 1; ++ if (x->insn < y->insn) ++ return -1; ++ return 0; ++} ++ ++static void swap_ex(void *a, void *b, int size) ++{ ++ struct exception_table_entry t, *x = a, *y = b; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ ++ t = *x; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ *x = *y; ++ *y = t; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ ++} ++ ++void sort_extable(struct exception_table_entry *start, ++ struct exception_table_entry *finish) ++{ ++ sort(start, finish - start, sizeof(struct exception_table_entry), ++ cmp_ex, swap_ex); ++} ++ ++#ifdef CONFIG_MODULES ++/* ++ * If the exception table is sorted, any referring to the module init ++ * will be at the beginning or the end. ++ */ ++void trim_init_extable(struct module *m) ++{ ++ /*trim the beginning*/ ++ while (m->num_exentries && within_module_init(m->extable[0].insn, m)) { ++ m->extable++; ++ m->num_exentries--; ++ } ++ /*trim the end*/ ++ while (m->num_exentries && ++ within_module_init(m->extable[m->num_exentries-1].insn, m)) ++ m->num_exentries--; ++} ++#endif /* CONFIG_MODULES */ + + int fixup_exception(struct pt_regs *regs) + { + const struct exception_table_entry *fixup; + + #ifdef CONFIG_PNPBIOS +- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) { ++ if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) { + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; + extern u32 pnp_bios_is_utter_crap; + pnp_bios_is_utter_crap = 1; +diff -urNp linux-2.6.31.1/arch/x86/mm/fault.c linux-2.6.31.1/arch/x86/mm/fault.c +--- linux-2.6.31.1/arch/x86/mm/fault.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/fault.c 2009-10-01 20:12:42.000000000 -0400 +@@ -11,10 +11,14 @@ + #include <linux/kprobes.h> /* __kprobes, ... */ + #include <linux/mmiotrace.h> /* kmmio_handler, ... */ + #include <linux/perf_counter.h> /* perf_swcounter_event */ ++#include <linux/unistd.h> ++#include <linux/compiler.h> + + #include <asm/traps.h> /* dotraplinkage, ... */ + #include <asm/pgalloc.h> /* pgd_*(), ... */ + #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ ++#include <asm/vsyscall.h> ++#include <asm/tlbflush.h> + + /* + * Page fault error code bits: +@@ -51,7 +55,7 @@ static inline int notify_page_fault(stru + int ret = 0; + + /* kprobe_running() needs smp_processor_id() */ +- if (kprobes_built_in() && !user_mode_vm(regs)) { ++ if (kprobes_built_in() && !user_mode(regs)) { + preempt_disable(); + if (kprobe_running() && kprobe_fault_handler(regs, 14)) + ret = 1; +@@ -171,6 +175,30 @@ force_sig_info_fault(int si_signo, int s + force_sig_info(si_signo, &info, tsk); + } + ++#ifdef CONFIG_PAX_EMUTRAMP ++static int pax_handle_fetch_fault(struct pt_regs *regs); ++#endif ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address) ++{ ++ pgd_t *pgd; ++ pud_t *pud; ++ pmd_t *pmd; ++ ++ pgd = pgd_offset(mm, address); ++ if (!pgd_present(*pgd)) ++ return NULL; ++ pud = pud_offset(pgd, address); ++ if (!pud_present(*pud)) ++ return NULL; ++ pmd = pmd_offset(pud, address); ++ if (!pmd_present(*pmd)) ++ return NULL; ++ return pmd; ++} ++#endif ++ + DEFINE_SPINLOCK(pgd_lock); + LIST_HEAD(pgd_list); + +@@ -543,7 +571,7 @@ static int is_errata93(struct pt_regs *r + static int is_errata100(struct pt_regs *regs, unsigned long address) + { + #ifdef CONFIG_X86_64 +- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && (address >> 32)) ++ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) && (address >> 32)) + return 1; + #endif + return 0; +@@ -570,7 +598,7 @@ static int is_f00f_bug(struct pt_regs *r + } + + static const char nx_warning[] = KERN_CRIT +-"kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n"; ++"kernel tried to execute NX-protected page - exploit attempt? (uid: %d, task: %s, pid: %d)\n"; + + static void + show_fault_oops(struct pt_regs *regs, unsigned long error_code, +@@ -579,15 +607,31 @@ show_fault_oops(struct pt_regs *regs, un + if (!oops_may_print()) + return; + +- if (error_code & PF_INSTR) { ++ if (nx_enabled && (error_code & PF_INSTR)) { + unsigned int level; + + pte_t *pte = lookup_address(address, &level); + + if (pte && pte_present(*pte) && !pte_exec(*pte)) +- printk(nx_warning, current_uid()); ++ printk(nx_warning, current_uid(), current->comm, task_pid_nr(current)); + } + ++#ifdef CONFIG_PAX_KERNEXEC ++#if defined(CONFIG_x86_32) && defined(CONFIG_MODULES) ++ if (init_mm.start_code <= address && address < (unsigned long)&MODULES_EXEC_END) ++#else ++ if (init_mm.start_code <= address && address < init_mm.end_code) ++#endif ++ { ++ if (current->signal->curr_ip) ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n", ++ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current_uid(), current_euid()); ++ else ++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n", ++ current->comm, task_pid_nr(current), current_uid(), current_euid()); ++ } ++#endif ++ + printk(KERN_ALERT "BUG: unable to handle kernel "); + if (address < PAGE_SIZE) + printk(KERN_CONT "NULL pointer dereference"); +@@ -712,6 +756,68 @@ __bad_area_nosemaphore(struct pt_regs *r + unsigned long address, int si_code) + { + struct task_struct *tsk = current; ++ struct mm_struct *mm = tsk->mm; ++ ++#ifdef CONFIG_X86_64 ++ if (mm && (error_code & PF_INSTR)) { ++ if (regs->ip == (unsigned long)vgettimeofday) { ++ regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_gettimeofday); ++ return; ++ } else if (regs->ip == (unsigned long)vtime) { ++ regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, fallback_time); ++ return; ++ } else if (regs->ip == (unsigned long)vgetcpu) { ++ regs->ip = (unsigned long)VDSO64_SYMBOL(mm->context.vdso, getcpu); ++ return; ++ } ++ } ++#endif ++ ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++ if (mm && (error_code & PF_USER)) { ++ unsigned long ip = regs->ip; ++ ++ if (v8086_mode(regs)) ++ ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff); ++ ++ /* ++ * It's possible to have interrupts off here: ++ */ ++ local_irq_enable(); ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && ++ ((nx_enabled && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && regs->ip == address))) { ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ switch (pax_handle_fetch_fault(regs)) { ++ case 2: ++ return; ++ } ++#endif ++ ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp); ++ do_group_exit(SIGKILL); ++ } ++#endif ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) { ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ switch (pax_handle_fetch_fault(regs)) { ++ case 2: ++ return; ++ } ++#endif ++ ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp); ++ do_group_exit(SIGKILL); ++ } ++#endif ++ ++ } ++#endif + + /* User mode accesses just cause a SIGSEGV */ + if (error_code & PF_USER) { +@@ -846,6 +952,106 @@ static int spurious_fault_check(unsigned + return 1; + } + ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) ++static int pax_handle_pageexec_fault(struct pt_regs *regs, struct mm_struct *mm, unsigned long address, unsigned long error_code) ++{ ++ pte_t *pte; ++ pmd_t *pmd; ++ spinlock_t *ptl; ++ unsigned char pte_mask; ++ ++ if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) || ++ !(mm->pax_flags & MF_PAX_PAGEEXEC)) ++ return 0; ++ ++ /* PaX: it's our fault, let's handle it if we can */ ++ ++ /* PaX: take a look at read faults before acquiring any locks */ ++ if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) { ++ /* instruction fetch attempt from a protected page in user mode */ ++ up_read(&mm->mmap_sem); ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ switch (pax_handle_fetch_fault(regs)) { ++ case 2: ++ return 1; ++ } ++#endif ++ ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp); ++ do_group_exit(SIGKILL); ++ } ++ ++ pmd = pax_get_pmd(mm, address); ++ if (unlikely(!pmd)) ++ return 0; ++ ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl); ++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) { ++ pte_unmap_unlock(pte, ptl); ++ return 0; ++ } ++ ++ if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) { ++ /* write attempt to a protected page in user mode */ ++ pte_unmap_unlock(pte, ptl); ++ return 0; ++ } ++ ++#ifdef CONFIG_SMP ++ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask))) ++#else ++ if (likely(address > get_limit(regs->cs))) ++#endif ++ { ++ set_pte(pte, pte_mkread(*pte)); ++ __flush_tlb_one(address); ++ pte_unmap_unlock(pte, ptl); ++ up_read(&mm->mmap_sem); ++ return 1; ++ } ++ ++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1)); ++ ++ /* ++ * PaX: fill DTLB with user rights and retry ++ */ ++ __asm__ __volatile__ ( ++#ifdef CONFIG_PAX_MEMORY_UDEREF ++ "movw %w4,%%es\n" ++#endif ++ "orb %2,(%1)\n" ++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC) ++/* ++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's ++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any* ++ * page fault when examined during a TLB load attempt. this is true not only ++ * for PTEs holding a non-present entry but also present entries that will ++ * raise a page fault (such as those set up by PaX, or the copy-on-write ++ * mechanism). in effect it means that we do *not* need to flush the TLBs ++ * for our target pages since their PTEs are simply not in the TLBs at all. ++ ++ * the best thing in omitting it is that we gain around 15-20% speed in the ++ * fast path of the page fault handler and can get rid of tracing since we ++ * can no longer flush unintended entries. ++ */ ++ "invlpg (%0)\n" ++#endif ++ "testb $0,%%es:(%0)\n" ++ "xorb %3,(%1)\n" ++#ifdef CONFIG_PAX_MEMORY_UDEREF ++ "pushl %%ss\n" ++ "popl %%es\n" ++#endif ++ : ++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS) ++ : "memory", "cc"); ++ pte_unmap_unlock(pte, ptl); ++ up_read(&mm->mmap_sem); ++ return 1; ++} ++#endif ++ + /* + * Handle a spurious fault caused by a stale TLB entry. + * +@@ -912,6 +1118,9 @@ int show_unhandled_signals = 1; + static inline int + access_error(unsigned long error_code, int write, struct vm_area_struct *vma) + { ++ if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC)) ++ return 1; ++ + if (write) { + /* write, present and write, not present: */ + if (unlikely(!(vma->vm_flags & VM_WRITE))) +@@ -945,17 +1154,16 @@ do_page_fault(struct pt_regs *regs, unsi + { + struct vm_area_struct *vma; + struct task_struct *tsk; +- unsigned long address; + struct mm_struct *mm; + int write; + int fault; + ++ /* Get the faulting address: */ ++ const unsigned long address = read_cr2(); ++ + tsk = current; + mm = tsk->mm; + +- /* Get the faulting address: */ +- address = read_cr2(); +- + /* + * Detect and handle instructions that would cause a page fault for + * both a tracked kernel page and a userspace page. +@@ -1015,7 +1223,7 @@ do_page_fault(struct pt_regs *regs, unsi + * User-mode registers count as a user access even for any + * potential system fault or CPU buglet: + */ +- if (user_mode_vm(regs)) { ++ if (user_mode(regs)) { + local_irq_enable(); + error_code |= PF_USER; + } else { +@@ -1069,6 +1277,11 @@ do_page_fault(struct pt_regs *regs, unsi + might_sleep(); + } + ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) ++ if (pax_handle_pageexec_fault(regs, mm, address, error_code)) ++ return; ++#endif ++ + vma = find_vma(mm, address); + if (unlikely(!vma)) { + bad_area(regs, error_code, address); +@@ -1080,18 +1293,24 @@ do_page_fault(struct pt_regs *regs, unsi + bad_area(regs, error_code, address); + return; + } +- if (error_code & PF_USER) { +- /* +- * Accessing the stack below %sp is always a bug. +- * The large cushion allows instructions like enter +- * and pusha to work. ("enter $65535, $31" pushes +- * 32 pointers and then decrements %sp by 65535.) +- */ +- if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) { +- bad_area(regs, error_code, address); +- return; +- } ++ /* ++ * Accessing the stack below %sp is always a bug. ++ * The large cushion allows instructions like enter ++ * and pusha to work. ("enter $65535, $31" pushes ++ * 32 pointers and then decrements %sp by 65535.) ++ */ ++ if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < task_pt_regs(tsk)->sp)) { ++ bad_area(regs, error_code, address); ++ return; ++ } ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (unlikely((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)) { ++ bad_area(regs, error_code, address); ++ return; + } ++#endif ++ + if (unlikely(expand_stack(vma, address))) { + bad_area(regs, error_code, address); + return; +@@ -1135,3 +1354,174 @@ good_area: + + up_read(&mm->mmap_sem); + } ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++static int pax_handle_fetch_fault_32(struct pt_regs *regs) ++{ ++ int err; ++ ++ do { /* PaX: gcc trampoline emulation #1 */ ++ unsigned char mov1, mov2; ++ unsigned short jmp; ++ unsigned int addr1, addr2; ++ ++#ifdef CONFIG_X86_64 ++ if ((regs->ip + 11) >> 32) ++ break; ++#endif ++ ++ err = get_user(mov1, (unsigned char __user *)regs->ip); ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1)); ++ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5)); ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6)); ++ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10)); ++ ++ if (err) ++ break; ++ ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) { ++ regs->cx = addr1; ++ regs->ax = addr2; ++ regs->ip = addr2; ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: gcc trampoline emulation #2 */ ++ unsigned char mov, jmp; ++ unsigned int addr1, addr2; ++ ++#ifdef CONFIG_X86_64 ++ if ((regs->ip + 9) >> 32) ++ break; ++#endif ++ ++ err = get_user(mov, (unsigned char __user *)regs->ip); ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1)); ++ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5)); ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6)); ++ ++ if (err) ++ break; ++ ++ if (mov == 0xB9 && jmp == 0xE9) { ++ regs->cx = addr1; ++ regs->ip = (unsigned int)(regs->ip + addr2 + 10); ++ return 2; ++ } ++ } while (0); ++ ++ return 1; /* PaX in action */ ++} ++ ++#ifdef CONFIG_X86_64 ++static int pax_handle_fetch_fault_64(struct pt_regs *regs) ++{ ++ int err; ++ ++ do { /* PaX: gcc trampoline emulation #1 */ ++ unsigned short mov1, mov2, jmp1; ++ unsigned char jmp2; ++ unsigned int addr1; ++ unsigned long addr2; ++ ++ err = get_user(mov1, (unsigned short __user *)regs->ip); ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2)); ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6)); ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8)); ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16)); ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18)); ++ ++ if (err) ++ break; ++ ++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) { ++ regs->r11 = addr1; ++ regs->r10 = addr2; ++ regs->ip = addr1; ++ return 2; ++ } ++ } while (0); ++ ++ do { /* PaX: gcc trampoline emulation #2 */ ++ unsigned short mov1, mov2, jmp1; ++ unsigned char jmp2; ++ unsigned long addr1, addr2; ++ ++ err = get_user(mov1, (unsigned short __user *)regs->ip); ++ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2)); ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10)); ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12)); ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20)); ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22)); ++ ++ if (err) ++ break; ++ ++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) { ++ regs->r11 = addr1; ++ regs->r10 = addr2; ++ regs->ip = addr1; ++ return 2; ++ } ++ } while (0); ++ ++ return 1; /* PaX in action */ ++} ++#endif ++ ++/* ++ * PaX: decide what to do with offenders (regs->ip = fault address) ++ * ++ * returns 1 when task should be killed ++ * 2 when gcc trampoline was detected ++ */ ++static int pax_handle_fetch_fault(struct pt_regs *regs) ++{ ++ if (v8086_mode(regs)) ++ return 1; ++ ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) ++ return 1; ++ ++#ifdef CONFIG_X86_32 ++ return pax_handle_fetch_fault_32(regs); ++#else ++ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) ++ return pax_handle_fetch_fault_32(regs); ++ else ++ return pax_handle_fetch_fault_64(regs); ++#endif ++} ++#endif ++ ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++void pax_report_insns(void *pc, void *sp) ++{ ++ long i; ++ ++ printk(KERN_ERR "PAX: bytes at PC: "); ++ for (i = 0; i < 20; i++) { ++ unsigned char c; ++ if (get_user(c, (unsigned char __user *)pc+i)) ++ printk(KERN_CONT "?? "); ++ else ++ printk(KERN_CONT "%02x ", c); ++ } ++ printk("\n"); ++ ++ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long)); ++ for (i = -1; i < 80 / sizeof(long); i++) { ++ unsigned long c; ++ if (get_user(c, (unsigned long __user *)sp+i)) ++#ifdef CONFIG_X86_32 ++ printk(KERN_CONT "???????? "); ++#else ++ printk(KERN_CONT "???????????????? "); ++#endif ++ else ++ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c); ++ } ++ printk("\n"); ++} ++#endif +diff -urNp linux-2.6.31.1/arch/x86/mm/highmem_32.c linux-2.6.31.1/arch/x86/mm/highmem_32.c +--- linux-2.6.31.1/arch/x86/mm/highmem_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/highmem_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -32,6 +32,10 @@ void *kmap_atomic_prot(struct page *page + enum fixed_addresses idx; + unsigned long vaddr; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ + pagefault_disable(); + +@@ -43,8 +47,17 @@ void *kmap_atomic_prot(struct page *page + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + BUG_ON(!pte_none(*(kmap_pte-idx))); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + set_pte(kmap_pte-idx, mk_pte(page, prot)); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + return (void *)vaddr; + } + +@@ -58,15 +71,29 @@ void kunmap_atomic(void *kvaddr, enum km + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + /* + * Force other mappings to Oops if they'll try to access this pte + * without first remap it. Keeping stale mappings around is a bad idea + * also, in case the page changes cacheability attributes or becomes + * a protected page in a hypervisor. + */ +- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) ++ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + kpte_clear_flush(kmap_pte-idx, vaddr); +- else { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ ++ } else { + #ifdef CONFIG_DEBUG_HIGHMEM + BUG_ON(vaddr < PAGE_OFFSET); + BUG_ON(vaddr >= (unsigned long)high_memory); +diff -urNp linux-2.6.31.1/arch/x86/mm/hugetlbpage.c linux-2.6.31.1/arch/x86/mm/hugetlbpage.c +--- linux-2.6.31.1/arch/x86/mm/hugetlbpage.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/hugetlbpage.c 2009-10-01 20:12:42.000000000 -0400 +@@ -267,13 +267,18 @@ static unsigned long hugetlb_get_unmappe + struct hstate *h = hstate_file(file); + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; +- unsigned long start_addr; ++ unsigned long start_addr, pax_task_size = TASK_SIZE; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++#endif + + if (len > mm->cached_hole_size) { +- start_addr = mm->free_area_cache; ++ start_addr = mm->free_area_cache; + } else { +- start_addr = TASK_UNMAPPED_BASE; +- mm->cached_hole_size = 0; ++ start_addr = mm->mmap_base; ++ mm->cached_hole_size = 0; + } + + full_search: +@@ -281,13 +286,13 @@ full_search: + + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { + /* At this point: (!vma || addr < vma->vm_end). */ +- if (TASK_SIZE - len < addr) { ++ if (pax_task_size - len < addr) { + /* + * Start a new search - just in case we missed + * some holes. + */ +- if (start_addr != TASK_UNMAPPED_BASE) { +- start_addr = TASK_UNMAPPED_BASE; ++ if (start_addr != mm->mmap_base) { ++ start_addr = mm->mmap_base; + mm->cached_hole_size = 0; + goto full_search; + } +@@ -310,9 +315,8 @@ static unsigned long hugetlb_get_unmappe + struct hstate *h = hstate_file(file); + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma, *prev_vma; +- unsigned long base = mm->mmap_base, addr = addr0; ++ unsigned long base = mm->mmap_base, addr; + unsigned long largest_hole = mm->cached_hole_size; +- int first_time = 1; + + /* don't allow allocations above current base */ + if (mm->free_area_cache > base) +@@ -322,7 +326,7 @@ static unsigned long hugetlb_get_unmappe + largest_hole = 0; + mm->free_area_cache = base; + } +-try_again: ++ + /* make sure it can fit in the remaining address space */ + if (mm->free_area_cache < len) + goto fail; +@@ -364,22 +368,26 @@ try_again: + + fail: + /* +- * if hint left us with no space for the requested +- * mapping then try again: +- */ +- if (first_time) { +- mm->free_area_cache = base; +- largest_hole = 0; +- first_time = 0; +- goto try_again; +- } +- /* + * A failed mmap() very likely causes application failure, + * so fall back to the bottom-up function here. This scenario + * can happen with large stack limits and large mmap() + * allocations. + */ +- mm->free_area_cache = TASK_UNMAPPED_BASE; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE; ++ else ++#endif ++ ++ mm->mmap_base = TASK_UNMAPPED_BASE; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base += mm->delta_mmap; ++#endif ++ ++ mm->free_area_cache = mm->mmap_base; + mm->cached_hole_size = ~0UL; + addr = hugetlb_get_unmapped_area_bottomup(file, addr0, + len, pgoff, flags); +@@ -387,6 +395,7 @@ fail: + /* + * Restore the topdown base: + */ ++ mm->mmap_base = base; + mm->free_area_cache = base; + mm->cached_hole_size = ~0UL; + +@@ -400,10 +409,17 @@ hugetlb_get_unmapped_area(struct file *f + struct hstate *h = hstate_file(file); + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; ++ unsigned long pax_task_size = TASK_SIZE; + + if (len & ~huge_page_mask(h)) + return -EINVAL; +- if (len > TASK_SIZE) ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++#endif ++ ++ if (len > pax_task_size) + return -ENOMEM; + + if (flags & MAP_FIXED) { +@@ -415,7 +431,7 @@ hugetlb_get_unmapped_area(struct file *f + if (addr) { + addr = ALIGN(addr, huge_page_size(h)); + vma = find_vma(mm, addr); +- if (TASK_SIZE - len >= addr && ++ if (pax_task_size - len >= addr && + (!vma || addr + len <= vma->vm_start)) + return addr; + } +diff -urNp linux-2.6.31.1/arch/x86/mm/init_32.c linux-2.6.31.1/arch/x86/mm/init_32.c +--- linux-2.6.31.1/arch/x86/mm/init_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/init_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -51,6 +51,7 @@ + #include <asm/cacheflush.h> + #include <asm/page_types.h> + #include <asm/init.h> ++#include <asm/desc.h> + + unsigned long highstart_pfn, highend_pfn; + +@@ -72,36 +73,6 @@ static __init void *alloc_low_page(void) + } + + /* +- * Creates a middle page table and puts a pointer to it in the +- * given global directory entry. This only returns the gd entry +- * in non-PAE compilation mode, since the middle layer is folded. +- */ +-static pmd_t * __init one_md_table_init(pgd_t *pgd) +-{ +- pud_t *pud; +- pmd_t *pmd_table; +- +-#ifdef CONFIG_X86_PAE +- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) { +- if (after_bootmem) +- pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE); +- else +- pmd_table = (pmd_t *)alloc_low_page(); +- paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT); +- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); +- pud = pud_offset(pgd, 0); +- BUG_ON(pmd_table != pmd_offset(pud, 0)); +- +- return pmd_table; +- } +-#endif +- pud = pud_offset(pgd, 0); +- pmd_table = pmd_offset(pud, 0); +- +- return pmd_table; +-} +- +-/* + * Create a page table and place a pointer to it in a middle page + * directory entry: + */ +@@ -121,13 +92,28 @@ static pte_t * __init one_page_table_ini + page_table = (pte_t *)alloc_low_page(); + + paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT); ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE)); ++#else + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); ++#endif + BUG_ON(page_table != pte_offset_kernel(pmd, 0)); + } + + return pte_offset_kernel(pmd, 0); + } + ++static pmd_t * __init one_md_table_init(pgd_t *pgd) ++{ ++ pud_t *pud; ++ pmd_t *pmd_table; ++ ++ pud = pud_offset(pgd, 0); ++ pmd_table = pmd_offset(pud, 0); ++ ++ return pmd_table; ++} ++ + pmd_t * __init populate_extra_pmd(unsigned long vaddr) + { + int pgd_idx = pgd_index(vaddr); +@@ -201,6 +187,7 @@ page_table_range_init(unsigned long star + int pgd_idx, pmd_idx; + unsigned long vaddr; + pgd_t *pgd; ++ pud_t *pud; + pmd_t *pmd; + pte_t *pte = NULL; + +@@ -210,8 +197,13 @@ page_table_range_init(unsigned long star + pgd = pgd_base + pgd_idx; + + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) { +- pmd = one_md_table_init(pgd); +- pmd = pmd + pmd_index(vaddr); ++ pud = pud_offset(pgd, vaddr); ++ pmd = pmd_offset(pud, vaddr); ++ ++#ifdef CONFIG_X86_PAE ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT); ++#endif ++ + for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); + pmd++, pmd_idx++) { + pte = page_table_kmap_check(one_page_table_init(pmd), +@@ -223,11 +215,23 @@ page_table_range_init(unsigned long star + } + } + +-static inline int is_kernel_text(unsigned long addr) ++static inline int is_kernel_text(unsigned long start, unsigned long end) + { +- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end) +- return 1; +- return 0; ++ unsigned long etext; ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ etext = ktva_ktla((unsigned long)&MODULES_EXEC_END); ++#else ++ etext = (unsigned long)&_etext; ++#endif ++ ++ if ((start > ktla_ktva(etext) || ++ end <= ktla_ktva((unsigned long)_stext)) && ++ (start > ktla_ktva((unsigned long)_einittext) || ++ end <= ktla_ktva((unsigned long)_sinittext)) && ++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000))) ++ return 0; ++ return 1; + } + + /* +@@ -243,9 +247,10 @@ kernel_physical_mapping_init(unsigned lo + int use_pse = page_size_mask == (1<<PG_LEVEL_2M); + unsigned long start_pfn, end_pfn; + pgd_t *pgd_base = swapper_pg_dir; +- int pgd_idx, pmd_idx, pte_ofs; ++ unsigned int pgd_idx, pmd_idx, pte_ofs; + unsigned long pfn; + pgd_t *pgd; ++ pud_t *pud; + pmd_t *pmd; + pte_t *pte; + unsigned pages_2m, pages_4k; +@@ -278,8 +283,13 @@ repeat: + pfn = start_pfn; + pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET); + pgd = pgd_base + pgd_idx; +- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) { +- pmd = one_md_table_init(pgd); ++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) { ++ pud = pud_offset(pgd, 0); ++ pmd = pmd_offset(pud, 0); ++ ++#ifdef CONFIG_X86_PAE ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT); ++#endif + + if (pfn >= end_pfn) + continue; +@@ -291,14 +301,13 @@ repeat: + #endif + for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn; + pmd++, pmd_idx++) { +- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET; ++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET; + + /* + * Map with big pages if possible, otherwise + * create normal page tables: + */ + if (use_pse) { +- unsigned int addr2; + pgprot_t prot = PAGE_KERNEL_LARGE; + /* + * first pass will use the same initial +@@ -308,11 +317,7 @@ repeat: + __pgprot(PTE_IDENT_ATTR | + _PAGE_PSE); + +- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE + +- PAGE_OFFSET + PAGE_SIZE-1; +- +- if (is_kernel_text(addr) || +- is_kernel_text(addr2)) ++ if (is_kernel_text(address, address + PMD_SIZE)) + prot = PAGE_KERNEL_LARGE_EXEC; + + pages_2m++; +@@ -329,7 +334,7 @@ repeat: + pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET); + pte += pte_ofs; + for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn; +- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) { ++ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) { + pgprot_t prot = PAGE_KERNEL; + /* + * first pass will use the same initial +@@ -337,7 +342,7 @@ repeat: + */ + pgprot_t init_prot = __pgprot(PTE_IDENT_ATTR); + +- if (is_kernel_text(addr)) ++ if (is_kernel_text(address, address + PAGE_SIZE)) + prot = PAGE_KERNEL_EXEC; + + pages_4k++; +@@ -489,7 +494,7 @@ void __init native_pagetable_setup_start + + pud = pud_offset(pgd, va); + pmd = pmd_offset(pud, va); +- if (!pmd_present(*pmd)) ++ if (!pmd_present(*pmd) || pmd_huge(*pmd)) + break; + + pte = pte_offset_kernel(pmd, va); +@@ -541,9 +546,7 @@ void __init early_ioremap_page_table_ran + + static void __init pagetable_init(void) + { +- pgd_t *pgd_base = swapper_pg_dir; +- +- permanent_kmaps_init(pgd_base); ++ permanent_kmaps_init(swapper_pg_dir); + } + + #ifdef CONFIG_ACPI_SLEEP +@@ -551,12 +554,12 @@ static void __init pagetable_init(void) + * ACPI suspend needs this for resume, because things like the intel-agp + * driver might have split up a kernel 4MB mapping. + */ +-char swsusp_pg_dir[PAGE_SIZE] ++pgd_t swsusp_pg_dir[PTRS_PER_PGD] + __attribute__ ((aligned(PAGE_SIZE))); + + static inline void save_pg_dir(void) + { +- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE); ++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD); + } + #else /* !CONFIG_ACPI_SLEEP */ + static inline void save_pg_dir(void) +@@ -588,7 +591,7 @@ void zap_low_mappings(bool early) + flush_tlb_all(); + } + +-pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP); ++pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP); + EXPORT_SYMBOL_GPL(__supported_pte_mask); + + /* user-defined highmem size */ +@@ -883,7 +886,7 @@ void __init mem_init(void) + set_highmem_pages_init(); + + codesize = (unsigned long) &_etext - (unsigned long) &_text; +- datasize = (unsigned long) &_edata - (unsigned long) &_etext; ++ datasize = (unsigned long) &_edata - (unsigned long) &_sdata; + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); +@@ -929,10 +932,10 @@ void __init mem_init(void) + ((unsigned long)&__init_end - + (unsigned long)&__init_begin) >> 10, + +- (unsigned long)&_etext, (unsigned long)&_edata, +- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, ++ (unsigned long)&_sdata, (unsigned long)&_edata, ++ ((unsigned long)&_edata - (unsigned long)&_sdata) >> 10, + +- (unsigned long)&_text, (unsigned long)&_etext, ++ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext), + ((unsigned long)&_etext - (unsigned long)&_text) >> 10); + + /* +diff -urNp linux-2.6.31.1/arch/x86/mm/init_64.c linux-2.6.31.1/arch/x86/mm/init_64.c +--- linux-2.6.31.1/arch/x86/mm/init_64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/init_64.c 2009-10-01 20:12:42.000000000 -0400 +@@ -159,12 +159,24 @@ void set_pte_vaddr_pud(pud_t *pud_page, + pmd_t *pmd; + pte_t *pte; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + pud = pud_page + pud_index(vaddr); + pmd = fill_pmd(pud, vaddr); + pte = fill_pte(pmd, vaddr); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + set_pte(pte, new_pte); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + /* + * It's enough to flush this one mapping. + * (PGE mappings get flushed as well) +@@ -222,14 +234,12 @@ static void __init __init_extra_mapping( + pgd = pgd_offset_k((unsigned long)__va(phys)); + if (pgd_none(*pgd)) { + pud = (pud_t *) spp_getpage(); +- set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE | +- _PAGE_USER)); ++ set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE)); + } + pud = pud_offset(pgd, (unsigned long)__va(phys)); + if (pud_none(*pud)) { + pmd = (pmd_t *) spp_getpage(); +- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | +- _PAGE_USER)); ++ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE)); + } + pmd = pmd_offset(pud, phys); + BUG_ON(!pmd_none(*pmd)); +@@ -848,8 +858,8 @@ int kern_addr_valid(unsigned long addr) + static struct vm_area_struct gate_vma = { + .vm_start = VSYSCALL_START, + .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE), +- .vm_page_prot = PAGE_READONLY_EXEC, +- .vm_flags = VM_READ | VM_EXEC ++ .vm_page_prot = PAGE_READONLY, ++ .vm_flags = VM_READ + }; + + struct vm_area_struct *get_gate_vma(struct task_struct *tsk) +@@ -883,7 +893,7 @@ int in_gate_area_no_task(unsigned long a + + const char *arch_vma_name(struct vm_area_struct *vma) + { +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso) + return "[vdso]"; + if (vma == &gate_vma) + return "[vsyscall]"; +diff -urNp linux-2.6.31.1/arch/x86/mm/init.c linux-2.6.31.1/arch/x86/mm/init.c +--- linux-2.6.31.1/arch/x86/mm/init.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/init.c 2009-10-01 20:12:42.000000000 -0400 +@@ -28,11 +28,10 @@ int direct_gbpages + #endif + ; + ++#if defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE) + int nx_enabled; + +-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) +-static int disable_nx __cpuinitdata; +- ++#ifndef CONFIG_PAX_PAGEEXEC + /* + * noexec = on|off + * +@@ -46,32 +45,26 @@ static int __init noexec_setup(char *str + if (!str) + return -EINVAL; + if (!strncmp(str, "on", 2)) { +- __supported_pte_mask |= _PAGE_NX; +- disable_nx = 0; ++ nx_enabled = 1; + } else if (!strncmp(str, "off", 3)) { +- disable_nx = 1; +- __supported_pte_mask &= ~_PAGE_NX; ++ nx_enabled = 0; + } + return 0; + } + early_param("noexec", noexec_setup); + #endif ++#endif + + #ifdef CONFIG_X86_PAE + static void __init set_nx(void) + { +- unsigned int v[4], l, h; +- +- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) { +- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]); ++ if (!nx_enabled && cpu_has_nx) { ++ unsigned l, h; + +- if ((v[3] & (1 << 20)) && !disable_nx) { +- rdmsr(MSR_EFER, l, h); +- l |= EFER_NX; +- wrmsr(MSR_EFER, l, h); +- nx_enabled = 1; +- __supported_pte_mask |= _PAGE_NX; +- } ++ __supported_pte_mask &= ~_PAGE_NX; ++ rdmsr(MSR_EFER, l, h); ++ l &= ~EFER_NX; ++ wrmsr(MSR_EFER, l, h); + } + } + #else +@@ -86,7 +79,7 @@ void __cpuinit check_efer(void) + unsigned long efer; + + rdmsrl(MSR_EFER, efer); +- if (!(efer & EFER_NX) || disable_nx) ++ if (!(efer & EFER_NX) || !nx_enabled) + __supported_pte_mask &= ~_PAGE_NX; + } + #endif +@@ -394,7 +387,13 @@ unsigned long __init_refok init_memory_m + */ + int devmem_is_allowed(unsigned long pagenr) + { +- if (pagenr <= 256) ++ if (!pagenr) ++ return 1; ++#ifdef CONFIG_VM86 ++ if (pagenr < (ISA_START_ADDRESS >> PAGE_SHIFT)) ++ return 1; ++#endif ++ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT)) + return 1; + if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) + return 0; +@@ -442,6 +441,76 @@ void free_init_pages(char *what, unsigne + + void free_initmem(void) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pgd_t *pgd; ++ pud_t *pud; ++ pmd_t *pmd; ++ ++#ifdef CONFIG_X86_32 ++ /* PaX: limit KERNEL_CS to actual size */ ++ unsigned long addr, limit; ++ struct desc_struct d; ++ int cpu; ++ ++#ifdef CONFIG_MODULES ++ limit = ktva_ktla((unsigned long)&MODULES_EXEC_END); ++#else ++ limit = (unsigned long)&_etext; ++#endif ++ limit = (limit - 1UL) >> PAGE_SHIFT; ++ ++ memset(__LOAD_PHYSICAL_ADDR + PAGE_OFFSET, POISON_FREE_INITMEM, PAGE_SIZE); ++ for (cpu = 0; cpu < NR_CPUS; cpu++) { ++ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC); ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S); ++ } ++ ++ /* PaX: make KERNEL_CS read-only */ ++ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_sdata; addr += PMD_SIZE) { ++ pgd = pgd_offset_k(addr); ++ pud = pud_offset(pgd, addr); ++ pmd = pmd_offset(pud, addr); ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW)); ++ } ++#ifdef CONFIG_X86_PAE ++ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) { ++ pgd = pgd_offset_k(addr); ++ pud = pud_offset(pgd, addr); ++ pmd = pmd_offset(pud, addr); ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask))); ++ } ++#endif ++#else ++ unsigned long addr, end; ++ ++ /* PaX: make kernel code/rodata read-only, rest non-executable */ ++ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) { ++ pgd = pgd_offset_k(addr); ++ pud = pud_offset(pgd, addr); ++ pmd = pmd_offset(pud, addr); ++ if ((unsigned long)_text <= addr && addr < (unsigned long)_sdata) ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW)); ++ else ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask))); ++ } ++ ++ addr = (unsigned long)__va(__pa(__START_KERNEL_map)); ++ end = addr + KERNEL_IMAGE_SIZE; ++ for (; addr < end; addr += PMD_SIZE) { ++ pgd = pgd_offset_k(addr); ++ pud = pud_offset(pgd, addr); ++ pmd = pmd_offset(pud, addr); ++ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_sdata))) ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW)); ++ else ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask))); ++ } ++#endif ++ ++ flush_tlb_all(); ++#endif ++ + free_init_pages("unused kernel memory", + (unsigned long)(&__init_begin), + (unsigned long)(&__init_end)); +diff -urNp linux-2.6.31.1/arch/x86/mm/iomap_32.c linux-2.6.31.1/arch/x86/mm/iomap_32.c +--- linux-2.6.31.1/arch/x86/mm/iomap_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/iomap_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -37,12 +37,26 @@ void *kmap_atomic_prot_pfn(unsigned long + enum fixed_addresses idx; + unsigned long vaddr; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + pagefault_disable(); + + debug_kmap_atomic(type); + idx = type + KM_TYPE_NR * smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + set_pte(kmap_pte - idx, pfn_pte(pfn, prot)); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + arch_flush_lazy_mmu_mode(); + + return (void *)vaddr; +diff -urNp linux-2.6.31.1/arch/x86/mm/ioremap.c linux-2.6.31.1/arch/x86/mm/ioremap.c +--- linux-2.6.31.1/arch/x86/mm/ioremap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/ioremap.c 2009-10-01 20:12:42.000000000 -0400 +@@ -111,8 +111,8 @@ int page_is_ram(unsigned long pagenr) + * Second special case: Some BIOSen report the PC BIOS + * area (640->1Mb) as ram even though it is not. + */ +- if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) && +- pagenr < (BIOS_END >> PAGE_SHIFT)) ++ if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) && ++ pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT)) + return 0; + + for (i = 0; i < e820.nr_map; i++) { +@@ -207,10 +207,7 @@ static void __iomem *__ioremap_caller(re + /* + * Don't allow anybody to remap normal RAM that we're using.. + */ +- for (pfn = phys_addr >> PAGE_SHIFT; +- (pfn << PAGE_SHIFT) < (last_addr & PAGE_MASK); +- pfn++) { +- ++ for (pfn = phys_addr >> PAGE_SHIFT; ((resource_size_t)pfn << PAGE_SHIFT) < (last_addr & PAGE_MASK); pfn++) { + int is_ram = page_is_ram(pfn); + + if (is_ram && pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn))) +@@ -272,6 +269,8 @@ static void __iomem *__ioremap_caller(re + break; + } + ++ prot = canon_pgprot(prot); ++ + /* + * Ok, go for it.. + */ +@@ -489,7 +488,7 @@ static int __init early_ioremap_debug_se + early_param("early_ioremap_debug", early_ioremap_debug_setup); + + static __initdata int after_paging_init; +-static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss; ++static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __read_only __aligned(PAGE_SIZE); + + static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) + { +@@ -521,8 +520,7 @@ void __init early_ioremap_init(void) + slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i); + + pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); +- memset(bm_pte, 0, sizeof(bm_pte)); +- pmd_populate_kernel(&init_mm, pmd, bm_pte); ++ pmd_populate_user(&init_mm, pmd, bm_pte); + + /* + * The boot-ioremap range spans multiple pmds, for which +diff -urNp linux-2.6.31.1/arch/x86/mm/mmap.c linux-2.6.31.1/arch/x86/mm/mmap.c +--- linux-2.6.31.1/arch/x86/mm/mmap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/mmap.c 2009-10-01 20:12:42.000000000 -0400 +@@ -36,7 +36,7 @@ + * Leave an at least ~128 MB hole. + */ + #define MIN_GAP (128*1024*1024) +-#define MAX_GAP (TASK_SIZE/6*5) ++#define MAX_GAP (pax_task_size/6*5) + + /* + * True on X86_32 or when emulating IA32 on X86_64 +@@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void) + return rnd << PAGE_SHIFT; + } + +-static unsigned long mmap_base(void) ++static unsigned long mmap_base(struct mm_struct *mm) + { + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; ++ unsigned long pax_task_size = TASK_SIZE; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++#endif + + if (gap < MIN_GAP) + gap = MIN_GAP; + else if (gap > MAX_GAP) + gap = MAX_GAP; + +- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd()); ++ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd()); + } + + /* + * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64 + * does, but not when emulating X86_32 + */ +-static unsigned long mmap_legacy_base(void) ++static unsigned long mmap_legacy_base(struct mm_struct *mm) + { +- if (mmap_is_ia32()) ++ if (mmap_is_ia32()) { ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) ++ return SEGMEXEC_TASK_UNMAPPED_BASE; ++ else ++#endif ++ + return TASK_UNMAPPED_BASE; +- else ++ } else + return TASK_UNMAPPED_BASE + mmap_rnd(); + } + +@@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo + void arch_pick_mmap_layout(struct mm_struct *mm) + { + if (mmap_is_legacy()) { +- mm->mmap_base = mmap_legacy_base(); ++ mm->mmap_base = mmap_legacy_base(mm); ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base += mm->delta_mmap; ++#endif ++ + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; + } else { +- mm->mmap_base = mmap_base(); ++ mm->mmap_base = mmap_base(mm); ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; ++#endif ++ + mm->get_unmapped_area = arch_get_unmapped_area_topdown; + mm->unmap_area = arch_unmap_area_topdown; + } +diff -urNp linux-2.6.31.1/arch/x86/mm/numa_32.c linux-2.6.31.1/arch/x86/mm/numa_32.c +--- linux-2.6.31.1/arch/x86/mm/numa_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/numa_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int + } + #endif + +-extern unsigned long find_max_low_pfn(void); + extern unsigned long highend_pfn, highstart_pfn; + + #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE) +diff -urNp linux-2.6.31.1/arch/x86/mm/pageattr.c linux-2.6.31.1/arch/x86/mm/pageattr.c +--- linux-2.6.31.1/arch/x86/mm/pageattr.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/pageattr.c 2009-10-01 20:12:42.000000000 -0400 +@@ -22,6 +22,7 @@ + #include <asm/pgalloc.h> + #include <asm/proto.h> + #include <asm/pat.h> ++#include <asm/desc.h> + + /* + * The current flushing context - we pass it instead of 5 arguments: +@@ -266,9 +267,10 @@ static inline pgprot_t static_protection + * Does not cover __inittext since that is gone later on. On + * 64bit we do not enforce !NX on the low mapping + */ +- if (within(address, (unsigned long)_text, (unsigned long)_etext)) ++ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext))) + pgprot_val(forbidden) |= _PAGE_NX; + ++#ifdef CONFIG_DEBUG_RODATA + /* + * The .rodata section needs to be read-only. Using the pfn + * catches all aliases. +@@ -276,6 +278,7 @@ static inline pgprot_t static_protection + if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT, + __pa((unsigned long)__end_rodata) >> PAGE_SHIFT)) + pgprot_val(forbidden) |= _PAGE_RW; ++#endif + + prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden)); + +@@ -328,8 +331,20 @@ EXPORT_SYMBOL_GPL(lookup_address); + */ + static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) + { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++#endif ++ + /* change init_mm */ + set_pte_atomic(kpte, pte); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + #ifdef CONFIG_X86_32 + if (!SHARED_KERNEL_PMD) { + struct page *page; +diff -urNp linux-2.6.31.1/arch/x86/mm/pageattr-test.c linux-2.6.31.1/arch/x86/mm/pageattr-test.c +--- linux-2.6.31.1/arch/x86/mm/pageattr-test.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/pageattr-test.c 2009-10-01 20:12:42.000000000 -0400 +@@ -36,7 +36,7 @@ enum { + + static int pte_testbit(pte_t pte) + { +- return pte_flags(pte) & _PAGE_UNUSED1; ++ return pte_flags(pte) & _PAGE_CPA_TEST; + } + + struct split_state { +diff -urNp linux-2.6.31.1/arch/x86/mm/pat.c linux-2.6.31.1/arch/x86/mm/pat.c +--- linux-2.6.31.1/arch/x86/mm/pat.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/pat.c 2009-10-01 20:12:42.000000000 -0400 +@@ -213,7 +213,7 @@ chk_conflict(struct memtype *new, struct + + conflict: + printk(KERN_INFO "%s:%d conflicting memory types " +- "%Lx-%Lx %s<->%s\n", current->comm, current->pid, new->start, ++ "%Lx-%Lx %s<->%s\n", current->comm, task_pid_nr(current), new->start, + new->end, cattr_name(new->type), cattr_name(entry->type)); + return -EBUSY; + } +@@ -487,7 +487,7 @@ int free_memtype(u64 start, u64 end) + + if (err) { + printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n", +- current->comm, current->pid, start, end); ++ current->comm, task_pid_nr(current), start, end); + } + + dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end); +@@ -588,7 +588,7 @@ int kernel_map_sync_memtype(u64 base, un + printk(KERN_INFO + "%s:%d ioremap_change_attr failed %s " + "for %Lx-%Lx\n", +- current->comm, current->pid, ++ current->comm, task_pid_nr(current), + cattr_name(flags), + base, (unsigned long long)(base + size)); + return -EINVAL; +@@ -628,7 +628,7 @@ static int reserve_pfn_range(u64 paddr, + free_memtype(paddr, paddr + size); + printk(KERN_ERR "%s:%d map pfn expected mapping type %s" + " for %Lx-%Lx, got %s\n", +- current->comm, current->pid, ++ current->comm, task_pid_nr(current), + cattr_name(want_flags), + (unsigned long long)paddr, + (unsigned long long)(paddr + size), +@@ -827,7 +827,7 @@ static int memtype_seq_show(struct seq_f + return 0; + } + +-static struct seq_operations memtype_seq_ops = { ++static const struct seq_operations memtype_seq_ops = { + .start = memtype_seq_start, + .next = memtype_seq_next, + .stop = memtype_seq_stop, +diff -urNp linux-2.6.31.1/arch/x86/mm/pgtable_32.c linux-2.6.31.1/arch/x86/mm/pgtable_32.c +--- linux-2.6.31.1/arch/x86/mm/pgtable_32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/pgtable_32.c 2009-10-01 20:12:42.000000000 -0400 +@@ -33,6 +33,10 @@ void set_pte_vaddr(unsigned long vaddr, + pmd_t *pmd; + pte_t *pte; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + pgd = swapper_pg_dir + pgd_index(vaddr); + if (pgd_none(*pgd)) { + BUG(); +@@ -49,11 +53,20 @@ void set_pte_vaddr(unsigned long vaddr, + return; + } + pte = pte_offset_kernel(pmd, vaddr); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + if (pte_val(pteval)) + set_pte_at(&init_mm, vaddr, pte, pteval); + else + pte_clear(&init_mm, vaddr, pte); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + /* + * It's enough to flush this one mapping. + * (PGE mappings get flushed as well) +diff -urNp linux-2.6.31.1/arch/x86/mm/tlb.c linux-2.6.31.1/arch/x86/mm/tlb.c +--- linux-2.6.31.1/arch/x86/mm/tlb.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/mm/tlb.c 2009-10-01 20:12:42.000000000 -0400 +@@ -12,7 +12,7 @@ + #include <asm/uv/uv.h> + + DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) +- = { &init_mm, 0, }; ++ = { &init_mm, 0 }; + + /* + * Smarter SMP flushing macros. +diff -urNp linux-2.6.31.1/arch/x86/oprofile/backtrace.c linux-2.6.31.1/arch/x86/oprofile/backtrace.c +--- linux-2.6.31.1/arch/x86/oprofile/backtrace.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/oprofile/backtrace.c 2009-10-01 20:12:42.000000000 -0400 +@@ -37,7 +37,7 @@ static void backtrace_address(void *data + unsigned int *depth = data; + + if ((*depth)--) +- oprofile_add_trace(addr); ++ oprofile_add_trace(ktla_ktva(addr)); + } + + static struct stacktrace_ops backtrace_ops = { +@@ -77,7 +77,7 @@ x86_backtrace(struct pt_regs * const reg + { + struct frame_head *head = (struct frame_head *)frame_pointer(regs); + +- if (!user_mode_vm(regs)) { ++ if (!user_mode(regs)) { + unsigned long stack = kernel_stack_pointer(regs); + if (depth) + dump_trace(NULL, regs, (unsigned long *)stack, 0, +diff -urNp linux-2.6.31.1/arch/x86/oprofile/op_model_p4.c linux-2.6.31.1/arch/x86/oprofile/op_model_p4.c +--- linux-2.6.31.1/arch/x86/oprofile/op_model_p4.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/oprofile/op_model_p4.c 2009-10-01 20:12:42.000000000 -0400 +@@ -48,7 +48,7 @@ static inline void setup_num_counters(vo + #endif + } + +-static int inline addr_increment(void) ++static inline int addr_increment(void) + { + #ifdef CONFIG_SMP + return smp_num_siblings == 2 ? 2 : 1; +diff -urNp linux-2.6.31.1/arch/x86/pci/common.c linux-2.6.31.1/arch/x86/pci/common.c +--- linux-2.6.31.1/arch/x86/pci/common.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/pci/common.c 2009-10-01 20:12:42.000000000 -0400 +@@ -370,7 +370,7 @@ static const struct dmi_system_id __devi + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), + }, + }, +- {} ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL} + }; + + void __init dmi_check_pciprobe(void) +diff -urNp linux-2.6.31.1/arch/x86/pci/fixup.c linux-2.6.31.1/arch/x86/pci/fixup.c +--- linux-2.6.31.1/arch/x86/pci/fixup.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/pci/fixup.c 2009-10-01 20:12:42.000000000 -0400 +@@ -364,7 +364,7 @@ static const struct dmi_system_id __devi + DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"), + }, + }, +- {} ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + + /* +@@ -435,7 +435,7 @@ static const struct dmi_system_id __devi + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + + static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev) +diff -urNp linux-2.6.31.1/arch/x86/pci/i386.c linux-2.6.31.1/arch/x86/pci/i386.c +--- linux-2.6.31.1/arch/x86/pci/i386.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/pci/i386.c 2009-10-01 20:12:42.000000000 -0400 +@@ -266,7 +266,7 @@ void pcibios_set_master(struct pci_dev * + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); + } + +-static struct vm_operations_struct pci_mmap_ops = { ++static const struct vm_operations_struct pci_mmap_ops = { + .access = generic_access_phys, + }; + +diff -urNp linux-2.6.31.1/arch/x86/pci/irq.c linux-2.6.31.1/arch/x86/pci/irq.c +--- linux-2.6.31.1/arch/x86/pci/irq.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/pci/irq.c 2009-10-01 20:12:42.000000000 -0400 +@@ -543,7 +543,7 @@ static __init int intel_router_probe(str + static struct pci_device_id __initdata pirq_440gx[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) }, +- { }, ++ { PCI_DEVICE(0, 0) } + }; + + /* 440GX has a proprietary PIRQ router -- don't use it */ +@@ -1107,7 +1107,7 @@ static struct dmi_system_id __initdata p + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + + int __init pcibios_irq_init(void) +diff -urNp linux-2.6.31.1/arch/x86/pci/pcbios.c linux-2.6.31.1/arch/x86/pci/pcbios.c +--- linux-2.6.31.1/arch/x86/pci/pcbios.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/pci/pcbios.c 2009-10-01 20:12:42.000000000 -0400 +@@ -56,50 +56,120 @@ union bios32 { + static struct { + unsigned long address; + unsigned short segment; +-} bios32_indirect = { 0, __KERNEL_CS }; ++} bios32_indirect __read_only = { 0, __PCIBIOS_CS }; + + /* + * Returns the entry point for the given service, NULL on error + */ + +-static unsigned long bios32_service(unsigned long service) ++static unsigned long __devinit bios32_service(unsigned long service) + { + unsigned char return_code; /* %al */ + unsigned long address; /* %ebx */ + unsigned long length; /* %ecx */ + unsigned long entry; /* %edx */ + unsigned long flags; ++ struct desc_struct d, *gdt; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif + + local_irq_save(flags); +- __asm__("lcall *(%%edi); cld" ++ ++ gdt = get_cpu_gdt_table(smp_processor_id()); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC); ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S); ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC); ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ ++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld" + : "=a" (return_code), + "=b" (address), + "=c" (length), + "=d" (entry) + : "0" (service), + "1" (0), +- "D" (&bios32_indirect)); ++ "D" (&bios32_indirect), ++ "r"(__PCIBIOS_DS) ++ : "memory"); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0; ++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0; ++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0; ++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + local_irq_restore(flags); + + switch (return_code) { +- case 0: +- return address + entry; +- case 0x80: /* Not present */ +- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service); +- return 0; +- default: /* Shouldn't happen */ +- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n", +- service, return_code); ++ case 0: { ++ int cpu; ++ unsigned char flags; ++ ++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry); ++ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) { ++ printk(KERN_WARNING "bios32_service: not valid\n"); + return 0; ++ } ++ address = address + PAGE_OFFSET; ++ length += 16UL; /* some BIOSs underreport this... */ ++ flags = 4; ++ if (length >= 64*1024*1024) { ++ length >>= PAGE_SHIFT; ++ flags |= 8; ++ } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ for (cpu = 0; cpu < NR_CPUS; cpu++) { ++ gdt = get_cpu_gdt_table(cpu); ++ pack_descriptor(&d, address, length, 0x9b, flags); ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S); ++ pack_descriptor(&d, address, length, 0x93, flags); ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S); ++ } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ ++ return entry; ++ } ++ case 0x80: /* Not present */ ++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service); ++ return 0; ++ default: /* Shouldn't happen */ ++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n", ++ service, return_code); ++ return 0; + } + } + + static struct { + unsigned long address; + unsigned short segment; +-} pci_indirect = { 0, __KERNEL_CS }; ++} pci_indirect __read_only = { 0, __PCIBIOS_CS }; + +-static int pci_bios_present; ++static int pci_bios_present __read_only; + + static int __devinit check_pcibios(void) + { +@@ -108,11 +178,13 @@ static int __devinit check_pcibios(void) + unsigned long flags, pcibios_entry; + + if ((pcibios_entry = bios32_service(PCI_SERVICE))) { +- pci_indirect.address = pcibios_entry + PAGE_OFFSET; ++ pci_indirect.address = pcibios_entry; + + local_irq_save(flags); +- __asm__( +- "lcall *(%%edi); cld\n\t" ++ __asm__("movw %w6, %%ds\n\t" ++ "lcall *%%ss:(%%edi); cld\n\t" ++ "push %%ss\n\t" ++ "pop %%ds\n\t" + "jc 1f\n\t" + "xor %%ah, %%ah\n" + "1:" +@@ -121,7 +193,8 @@ static int __devinit check_pcibios(void) + "=b" (ebx), + "=c" (ecx) + : "1" (PCIBIOS_PCI_BIOS_PRESENT), +- "D" (&pci_indirect) ++ "D" (&pci_indirect), ++ "r" (__PCIBIOS_DS) + : "memory"); + local_irq_restore(flags); + +@@ -165,7 +238,10 @@ static int pci_bios_read(unsigned int se + + switch (len) { + case 1: +- __asm__("lcall *(%%esi); cld\n\t" ++ __asm__("movw %w6, %%ds\n\t" ++ "lcall *%%ss:(%%esi); cld\n\t" ++ "push %%ss\n\t" ++ "pop %%ds\n\t" + "jc 1f\n\t" + "xor %%ah, %%ah\n" + "1:" +@@ -174,7 +250,8 @@ static int pci_bios_read(unsigned int se + : "1" (PCIBIOS_READ_CONFIG_BYTE), + "b" (bx), + "D" ((long)reg), +- "S" (&pci_indirect)); ++ "S" (&pci_indirect), ++ "r" (__PCIBIOS_DS)); + /* + * Zero-extend the result beyond 8 bits, do not trust the + * BIOS having done it: +@@ -182,7 +259,10 @@ static int pci_bios_read(unsigned int se + *value &= 0xff; + break; + case 2: +- __asm__("lcall *(%%esi); cld\n\t" ++ __asm__("movw %w6, %%ds\n\t" ++ "lcall *%%ss:(%%esi); cld\n\t" ++ "push %%ss\n\t" ++ "pop %%ds\n\t" + "jc 1f\n\t" + "xor %%ah, %%ah\n" + "1:" +@@ -191,7 +271,8 @@ static int pci_bios_read(unsigned int se + : "1" (PCIBIOS_READ_CONFIG_WORD), + "b" (bx), + "D" ((long)reg), +- "S" (&pci_indirect)); ++ "S" (&pci_indirect), ++ "r" (__PCIBIOS_DS)); + /* + * Zero-extend the result beyond 16 bits, do not trust the + * BIOS having done it: +@@ -199,7 +280,10 @@ static int pci_bios_read(unsigned int se + *value &= 0xffff; + break; + case 4: +- __asm__("lcall *(%%esi); cld\n\t" ++ __asm__("movw %w6, %%ds\n\t" ++ "lcall *%%ss:(%%esi); cld\n\t" ++ "push %%ss\n\t" ++ "pop %%ds\n\t" + "jc 1f\n\t" + "xor %%ah, %%ah\n" + "1:" +@@ -208,7 +292,8 @@ static int pci_bios_read(unsigned int se + : "1" (PCIBIOS_READ_CONFIG_DWORD), + "b" (bx), + "D" ((long)reg), +- "S" (&pci_indirect)); ++ "S" (&pci_indirect), ++ "r" (__PCIBIOS_DS)); + break; + } + +@@ -231,7 +316,10 @@ static int pci_bios_write(unsigned int s + + switch (len) { + case 1: +- __asm__("lcall *(%%esi); cld\n\t" ++ __asm__("movw %w6, %%ds\n\t" ++ "lcall *%%ss:(%%esi); cld\n\t" ++ "push %%ss\n\t" ++ "pop %%ds\n\t" + "jc 1f\n\t" + "xor %%ah, %%ah\n" + "1:" +@@ -240,10 +328,14 @@ static int pci_bios_write(unsigned int s + "c" (value), + "b" (bx), + "D" ((long)reg), +- "S" (&pci_indirect)); ++ "S" (&pci_indirect), ++ "r" (__PCIBIOS_DS)); + break; + case 2: +- __asm__("lcall *(%%esi); cld\n\t" ++ __asm__("movw %w6, %%ds\n\t" ++ "lcall *%%ss:(%%esi); cld\n\t" ++ "push %%ss\n\t" ++ "pop %%ds\n\t" + "jc 1f\n\t" + "xor %%ah, %%ah\n" + "1:" +@@ -252,10 +344,14 @@ static int pci_bios_write(unsigned int s + "c" (value), + "b" (bx), + "D" ((long)reg), +- "S" (&pci_indirect)); ++ "S" (&pci_indirect), ++ "r" (__PCIBIOS_DS)); + break; + case 4: +- __asm__("lcall *(%%esi); cld\n\t" ++ __asm__("movw %w6, %%ds\n\t" ++ "lcall *%%ss:(%%esi); cld\n\t" ++ "push %%ss\n\t" ++ "pop %%ds\n\t" + "jc 1f\n\t" + "xor %%ah, %%ah\n" + "1:" +@@ -264,7 +360,8 @@ static int pci_bios_write(unsigned int s + "c" (value), + "b" (bx), + "D" ((long)reg), +- "S" (&pci_indirect)); ++ "S" (&pci_indirect), ++ "r" (__PCIBIOS_DS)); + break; + } + +@@ -368,10 +465,13 @@ struct irq_routing_table * pcibios_get_i + + DBG("PCI: Fetching IRQ routing table... "); + __asm__("push %%es\n\t" ++ "movw %w8, %%ds\n\t" + "push %%ds\n\t" + "pop %%es\n\t" +- "lcall *(%%esi); cld\n\t" ++ "lcall *%%ss:(%%esi); cld\n\t" + "pop %%es\n\t" ++ "push %%ss\n\t" ++ "pop %%ds\n" + "jc 1f\n\t" + "xor %%ah, %%ah\n" + "1:" +@@ -382,7 +482,8 @@ struct irq_routing_table * pcibios_get_i + "1" (0), + "D" ((long) &opt), + "S" (&pci_indirect), +- "m" (opt) ++ "m" (opt), ++ "r" (__PCIBIOS_DS) + : "memory"); + DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map); + if (ret & 0xff00) +@@ -406,7 +507,10 @@ int pcibios_set_irq_routing(struct pci_d + { + int ret; + +- __asm__("lcall *(%%esi); cld\n\t" ++ __asm__("movw %w5, %%ds\n\t" ++ "lcall *%%ss:(%%esi); cld\n\t" ++ "push %%ss\n\t" ++ "pop %%ds\n" + "jc 1f\n\t" + "xor %%ah, %%ah\n" + "1:" +@@ -414,7 +518,8 @@ int pcibios_set_irq_routing(struct pci_d + : "0" (PCIBIOS_SET_PCI_HW_INT), + "b" ((dev->bus->number << 8) | dev->devfn), + "c" ((irq << 8) | (pin + 10)), +- "S" (&pci_indirect)); ++ "S" (&pci_indirect), ++ "r" (__PCIBIOS_DS)); + return !(ret & 0xff00); + } + EXPORT_SYMBOL(pcibios_set_irq_routing); +diff -urNp linux-2.6.31.1/arch/x86/power/cpu.c linux-2.6.31.1/arch/x86/power/cpu.c +--- linux-2.6.31.1/arch/x86/power/cpu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/power/cpu.c 2009-10-01 20:12:42.000000000 -0400 +@@ -126,7 +126,11 @@ static void do_fpu_end(void) + static void fix_processor_context(void) + { + int cpu = smp_processor_id(); +- struct tss_struct *t = &per_cpu(init_tss, cpu); ++ struct tss_struct *t = init_tss + cpu; ++ ++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_KERNEXEC) ++ unsigned long cr0; ++#endif + + set_tss_desc(cpu, t); /* + * This just modifies memory; should not be +@@ -136,8 +140,17 @@ static void fix_processor_context(void) + */ + + #ifdef CONFIG_X86_64 ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9; + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + syscall_init(); /* This sets MSR_*STAR and related */ + #endif + load_TR_desc(); /* This does ltr */ +diff -urNp linux-2.6.31.1/arch/x86/vdso/Makefile linux-2.6.31.1/arch/x86/vdso/Makefile +--- linux-2.6.31.1/arch/x86/vdso/Makefile 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/vdso/Makefile 2009-10-01 20:12:42.000000000 -0400 +@@ -122,7 +122,7 @@ quiet_cmd_vdso = VDSO $@ + $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \ + -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) + +-VDSO_LDFLAGS = -fPIC -shared $(call ld-option, -Wl$(comma)--hash-style=sysv) ++VDSO_LDFLAGS = -fPIC -shared --no-undefined $(call ld-option, -Wl$(comma)--hash-style=sysv) + GCOV_PROFILE := n + + # +diff -urNp linux-2.6.31.1/arch/x86/vdso/vclock_gettime.c linux-2.6.31.1/arch/x86/vdso/vclock_gettime.c +--- linux-2.6.31.1/arch/x86/vdso/vclock_gettime.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/vdso/vclock_gettime.c 2009-10-01 20:12:42.000000000 -0400 +@@ -22,24 +22,48 @@ + #include <asm/hpet.h> + #include <asm/unistd.h> + #include <asm/io.h> ++#include <asm/fixmap.h> + #include "vextern.h" + + #define gtod vdso_vsyscall_gtod_data + ++notrace noinline long __vdso_fallback_time(long *t) ++{ ++ long secs; ++ asm volatile("syscall" ++ : "=a" (secs) ++ : "0" (__NR_time),"D" (t) : "r11", "cx", "memory"); ++ return secs; ++} ++ + notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) + { + long ret; + asm("syscall" : "=a" (ret) : +- "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "memory"); ++ "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "r11", "cx", "memory"); + return ret; + } + ++notrace static inline cycle_t __vdso_vread_hpet(void) ++{ ++ return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0); ++} ++ ++notrace static inline cycle_t __vdso_vread_tsc(void) ++{ ++ cycle_t ret = (cycle_t)vget_cycles(); ++ ++ return ret >= gtod->clock.cycle_last ? ret : gtod->clock.cycle_last; ++} ++ + notrace static inline long vgetns(void) + { + long v; +- cycles_t (*vread)(void); +- vread = gtod->clock.vread; +- v = (vread() - gtod->clock.cycle_last) & gtod->clock.mask; ++ if (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3]) ++ v = __vdso_vread_tsc(); ++ else ++ v = __vdso_vread_hpet(); ++ v = (v - gtod->clock.cycle_last) & gtod->clock.mask; + return (v * gtod->clock.mult) >> gtod->clock.shift; + } + +@@ -88,7 +112,9 @@ notrace static noinline int do_monotonic + + notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) + { +- if (likely(gtod->sysctl_enabled && gtod->clock.vread)) ++ if (likely(gtod->sysctl_enabled && ++ ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) || ++ (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3])))) + switch (clock) { + case CLOCK_REALTIME: + return do_realtime(ts); +@@ -100,10 +126,20 @@ notrace int __vdso_clock_gettime(clockid + int clock_gettime(clockid_t, struct timespec *) + __attribute__((weak, alias("__vdso_clock_gettime"))); + +-notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) ++notrace noinline int __vdso_fallback_gettimeofday(struct timeval *tv, struct timezone *tz) + { + long ret; +- if (likely(gtod->sysctl_enabled && gtod->clock.vread)) { ++ asm("syscall" : "=a" (ret) : ++ "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "r11", "cx", "memory"); ++ return ret; ++} ++ ++notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) ++{ ++ if (likely(gtod->sysctl_enabled && ++ ((gtod->clock.name[0] == 'h' && gtod->clock.name[1] == 'p' && gtod->clock.name[2] == 'e' && gtod->clock.name[3] == 't' && !gtod->clock.name[4]) || ++ (gtod->clock.name[0] == 't' && gtod->clock.name[1] == 's' && gtod->clock.name[2] == 'c' && !gtod->clock.name[3])))) ++ { + if (likely(tv != NULL)) { + BUILD_BUG_ON(offsetof(struct timeval, tv_usec) != + offsetof(struct timespec, tv_nsec) || +@@ -118,9 +154,7 @@ notrace int __vdso_gettimeofday(struct t + } + return 0; + } +- asm("syscall" : "=a" (ret) : +- "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); +- return ret; ++ return __vdso_fallback_gettimeofday(tv, tz); + } + int gettimeofday(struct timeval *, struct timezone *) + __attribute__((weak, alias("__vdso_gettimeofday"))); +diff -urNp linux-2.6.31.1/arch/x86/vdso/vdso32-setup.c linux-2.6.31.1/arch/x86/vdso/vdso32-setup.c +--- linux-2.6.31.1/arch/x86/vdso/vdso32-setup.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/vdso/vdso32-setup.c 2009-10-01 20:12:42.000000000 -0400 +@@ -25,6 +25,7 @@ + #include <asm/tlbflush.h> + #include <asm/vdso.h> + #include <asm/proto.h> ++#include <asm/mman.h> + + enum { + VDSO_DISABLED = 0, +@@ -226,7 +227,7 @@ static inline void map_compat_vdso(int m + void enable_sep_cpu(void) + { + int cpu = get_cpu(); +- struct tss_struct *tss = &per_cpu(init_tss, cpu); ++ struct tss_struct *tss = init_tss + cpu; + + if (!boot_cpu_has(X86_FEATURE_SEP)) { + put_cpu(); +@@ -249,7 +250,7 @@ static int __init gate_vma_init(void) + gate_vma.vm_start = FIXADDR_USER_START; + gate_vma.vm_end = FIXADDR_USER_END; + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; +- gate_vma.vm_page_prot = __P101; ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags); + /* + * Make sure the vDSO gets into every core dump. + * Dumping its contents makes post-mortem fully interpretable later +@@ -331,14 +332,14 @@ int arch_setup_additional_pages(struct l + if (compat) + addr = VDSO_HIGH_BASE; + else { +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); ++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE); + if (IS_ERR_VALUE(addr)) { + ret = addr; + goto up_fail; + } + } + +- current->mm->context.vdso = (void *)addr; ++ current->mm->context.vdso = addr; + + if (compat_uses_vma || !compat) { + /* +@@ -365,7 +366,7 @@ int arch_setup_additional_pages(struct l + + up_fail: + if (ret) +- current->mm->context.vdso = NULL; ++ current->mm->context.vdso = 0; + + up_write(&mm->mmap_sem); + +@@ -388,7 +389,7 @@ static ctl_table abi_table2[] = { + .mode = 0644, + .proc_handler = proc_dointvec + }, +- {} ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + + static ctl_table abi_root_table2[] = { +@@ -398,7 +399,7 @@ static ctl_table abi_root_table2[] = { + .mode = 0555, + .child = abi_table2 + }, +- {} ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + + static __init int ia32_binfmt_init(void) +@@ -413,8 +414,14 @@ __initcall(ia32_binfmt_init); + + const char *arch_vma_name(struct vm_area_struct *vma) + { +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso) + return "[vdso]"; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso) ++ return "[vdso]"; ++#endif ++ + return NULL; + } + +@@ -423,7 +430,7 @@ struct vm_area_struct *get_gate_vma(stru + struct mm_struct *mm = tsk->mm; + + /* Check to see if this task was created in compat vdso mode */ +- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE) ++ if (mm && mm->context.vdso == VDSO_HIGH_BASE) + return &gate_vma; + return NULL; + } +diff -urNp linux-2.6.31.1/arch/x86/vdso/vdso.lds.S linux-2.6.31.1/arch/x86/vdso/vdso.lds.S +--- linux-2.6.31.1/arch/x86/vdso/vdso.lds.S 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/vdso/vdso.lds.S 2009-10-01 20:12:42.000000000 -0400 +@@ -35,3 +35,9 @@ VDSO64_PRELINK = VDSO_PRELINK; + #define VEXTERN(x) VDSO64_ ## x = vdso_ ## x; + #include "vextern.h" + #undef VEXTERN ++ ++#define VEXTERN(x) VDSO64_ ## x = __vdso_ ## x; ++VEXTERN(fallback_gettimeofday) ++VEXTERN(fallback_time) ++VEXTERN(getcpu) ++#undef VEXTERN +diff -urNp linux-2.6.31.1/arch/x86/vdso/vextern.h linux-2.6.31.1/arch/x86/vdso/vextern.h +--- linux-2.6.31.1/arch/x86/vdso/vextern.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/vdso/vextern.h 2009-10-01 20:12:42.000000000 -0400 +@@ -11,6 +11,5 @@ + put into vextern.h and be referenced as a pointer with vdso prefix. + The main kernel later fills in the values. */ + +-VEXTERN(jiffies) + VEXTERN(vgetcpu_mode) + VEXTERN(vsyscall_gtod_data) +diff -urNp linux-2.6.31.1/arch/x86/vdso/vma.c linux-2.6.31.1/arch/x86/vdso/vma.c +--- linux-2.6.31.1/arch/x86/vdso/vma.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/vdso/vma.c 2009-10-01 20:12:42.000000000 -0400 +@@ -57,7 +57,7 @@ static int __init init_vdso_vars(void) + if (!vbase) + goto oom; + +- if (memcmp(vbase, "\177ELF", 4)) { ++ if (memcmp(vbase, ELFMAG, SELFMAG)) { + printk("VDSO: I'm broken; not ELF\n"); + vdso_enabled = 0; + } +@@ -66,6 +66,7 @@ static int __init init_vdso_vars(void) + *(typeof(__ ## x) **) var_ref(VDSO64_SYMBOL(vbase, x), #x) = &__ ## x; + #include "vextern.h" + #undef VEXTERN ++ vunmap(vbase); + return 0; + + oom: +@@ -116,7 +117,7 @@ int arch_setup_additional_pages(struct l + goto up_fail; + } + +- current->mm->context.vdso = (void *)addr; ++ current->mm->context.vdso = addr; + + ret = install_special_mapping(mm, addr, vdso_size, + VM_READ|VM_EXEC| +@@ -124,7 +125,7 @@ int arch_setup_additional_pages(struct l + VM_ALWAYSDUMP, + vdso_pages); + if (ret) { +- current->mm->context.vdso = NULL; ++ current->mm->context.vdso = 0; + goto up_fail; + } + +@@ -132,10 +133,3 @@ up_fail: + up_write(&mm->mmap_sem); + return ret; + } +- +-static __init int vdso_setup(char *s) +-{ +- vdso_enabled = simple_strtoul(s, NULL, 0); +- return 0; +-} +-__setup("vdso=", vdso_setup); +diff -urNp linux-2.6.31.1/arch/x86/xen/debugfs.c linux-2.6.31.1/arch/x86/xen/debugfs.c +--- linux-2.6.31.1/arch/x86/xen/debugfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/xen/debugfs.c 2009-10-01 20:12:42.000000000 -0400 +@@ -100,7 +100,7 @@ static int xen_array_release(struct inod + return 0; + } + +-static struct file_operations u32_array_fops = { ++static const struct file_operations u32_array_fops = { + .owner = THIS_MODULE, + .open = u32_array_open, + .release= xen_array_release, +diff -urNp linux-2.6.31.1/arch/x86/xen/enlighten.c linux-2.6.31.1/arch/x86/xen/enlighten.c +--- linux-2.6.31.1/arch/x86/xen/enlighten.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/xen/enlighten.c 2009-10-01 20:12:42.000000000 -0400 +@@ -69,8 +69,6 @@ EXPORT_SYMBOL_GPL(xen_start_info); + + struct shared_info xen_dummy_shared_info; + +-void *xen_initial_gdt; +- + /* + * Point at some empty memory to start with. We map the real shared_info + * page as soon as fixmap is up and running. +@@ -490,7 +488,7 @@ static void xen_write_idt_entry(gate_des + + preempt_disable(); + +- start = __get_cpu_var(idt_desc).address; ++ start = (unsigned long)__get_cpu_var(idt_desc).address; + end = start + __get_cpu_var(idt_desc).size + 1; + + xen_mc_flush(); +@@ -1010,13 +1008,6 @@ asmlinkage void __init xen_start_kernel( + + machine_ops = xen_machine_ops; + +- /* +- * The only reliable way to retain the initial address of the +- * percpu gdt_page is to remember it here, so we can go and +- * mark it RW later, when the initial percpu area is freed. +- */ +- xen_initial_gdt = &per_cpu(gdt_page, 0); +- + xen_smp_init(); + + /* Get mfn list */ +diff -urNp linux-2.6.31.1/arch/x86/xen/mmu.c linux-2.6.31.1/arch/x86/xen/mmu.c +--- linux-2.6.31.1/arch/x86/xen/mmu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/xen/mmu.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1707,6 +1707,8 @@ __init pgd_t *xen_setup_kernel_pagetable + convert_pfn_mfn(init_level4_pgt); + convert_pfn_mfn(level3_ident_pgt); + convert_pfn_mfn(level3_kernel_pgt); ++ convert_pfn_mfn(level3_vmalloc_pgt); ++ convert_pfn_mfn(level3_vmemmap_pgt); + + l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd); + l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud); +@@ -1725,7 +1727,10 @@ __init pgd_t *xen_setup_kernel_pagetable + set_page_prot(init_level4_pgt, PAGE_KERNEL_RO); + set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO); + set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO); ++ set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO); ++ set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO); + set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO); ++ set_page_prot(level2_vmemmap_pgt, PAGE_KERNEL_RO); + set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO); + set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO); + +diff -urNp linux-2.6.31.1/arch/x86/xen/smp.c linux-2.6.31.1/arch/x86/xen/smp.c +--- linux-2.6.31.1/arch/x86/xen/smp.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/xen/smp.c 2009-10-01 20:12:42.000000000 -0400 +@@ -167,11 +167,6 @@ static void __init xen_smp_prepare_boot_ + { + BUG_ON(smp_processor_id() != 0); + native_smp_prepare_boot_cpu(); +- +- /* We've switched to the "real" per-cpu gdt, so make sure the +- old memory can be recycled */ +- make_lowmem_page_readwrite(xen_initial_gdt); +- + xen_setup_vcpu_info_placement(); + } + +@@ -231,8 +226,8 @@ cpu_initialize_context(unsigned int cpu, + gdt = get_cpu_gdt_table(cpu); + + ctxt->flags = VGCF_IN_KERNEL; +- ctxt->user_regs.ds = __USER_DS; +- ctxt->user_regs.es = __USER_DS; ++ ctxt->user_regs.ds = __KERNEL_DS; ++ ctxt->user_regs.es = __KERNEL_DS; + ctxt->user_regs.ss = __KERNEL_DS; + #ifdef CONFIG_X86_32 + ctxt->user_regs.fs = __KERNEL_PERCPU; +diff -urNp linux-2.6.31.1/arch/x86/xen/xen-ops.h linux-2.6.31.1/arch/x86/xen/xen-ops.h +--- linux-2.6.31.1/arch/x86/xen/xen-ops.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/x86/xen/xen-ops.h 2009-10-01 20:12:42.000000000 -0400 +@@ -10,8 +10,6 @@ + extern const char xen_hypervisor_callback[]; + extern const char xen_failsafe_callback[]; + +-extern void *xen_initial_gdt; +- + struct trap_info; + void xen_copy_trap_info(struct trap_info *traps); + +diff -urNp linux-2.6.31.1/arch/xtensa/include/asm/atomic.h linux-2.6.31.1/arch/xtensa/include/asm/atomic.h +--- linux-2.6.31.1/arch/xtensa/include/asm/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/arch/xtensa/include/asm/atomic.h 2009-10-01 20:12:42.000000000 -0400 +@@ -49,6 +49,14 @@ + #define atomic_read(v) ((v)->counter) + + /** ++ * atomic_read_unchecked - read atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically reads the value of @v. ++ */ ++#define atomic_read_unchecked(v) ((v)->counter) ++ ++/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value +@@ -58,6 +66,15 @@ + #define atomic_set(v,i) ((v)->counter = (i)) + + /** ++ * atomic_set_unchecked - set atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * @i: required value ++ * ++ * Atomically sets the value of @v to @i. ++ */ ++#define atomic_set_unchecked(v,i) ((v)->counter = (i)) ++ ++/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t +@@ -81,6 +98,11 @@ static inline void atomic_add(int i, ato + ); + } + ++static inline void atomic_add_unchecked(int i, atomic_unchecked_t * v) ++{ ++ atomic_add(i, (atomic_t *)v); ++} ++ + /** + * atomic_sub - subtract the atomic variable + * @i: integer value to subtract +@@ -105,6 +127,11 @@ static inline void atomic_sub(int i, ato + ); + } + ++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_sub(i, (atomic_t *)v); ++} ++ + /* + * We use atomic_{add|sub}_return to define other functions. + */ +@@ -165,6 +192,7 @@ static inline int atomic_sub_return(int + * Atomically increments @v by 1. + */ + #define atomic_inc(v) atomic_add(1,(v)) ++#define atomic_inc_unchecked(v) atomic_add_unchecked(1,(v)) + + /** + * atomic_inc - increment atomic variable +diff -urNp linux-2.6.31.1/crypto/lrw.c linux-2.6.31.1/crypto/lrw.c +--- linux-2.6.31.1/crypto/lrw.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/crypto/lrw.c 2009-10-01 20:12:42.000000000 -0400 +@@ -60,7 +60,7 @@ static int setkey(struct crypto_tfm *par + struct priv *ctx = crypto_tfm_ctx(parent); + struct crypto_cipher *child = ctx->child; + int err, i; +- be128 tmp = { 0 }; ++ be128 tmp = { 0, 0 }; + int bsize = crypto_cipher_blocksize(child); + + crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); +diff -urNp linux-2.6.31.1/Documentation/dontdiff linux-2.6.31.1/Documentation/dontdiff +--- linux-2.6.31.1/Documentation/dontdiff 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/Documentation/dontdiff 2009-10-01 20:12:42.000000000 -0400 +@@ -3,6 +3,7 @@ + *.bin + *.cpio + *.csp ++*.dbg + *.dsp + *.dvi + *.elf +@@ -49,11 +50,16 @@ + 53c700_d.h + CVS + ChangeSet ++GPATH ++GRTAGS ++GSYMS ++GTAGS + Image + Kerntypes + Module.markers + Module.symvers + PENDING ++PERF* + SCCS + System.map* + TAGS +@@ -76,7 +82,9 @@ btfixupprep + build + bvmlinux + bzImage* ++capflags.c + classlist.h* ++common-cmds.h + comp*.log + compile.h* + conf +@@ -103,13 +111,14 @@ gen_crc32table + gen_init_cpio + genksyms + *_gray256.c ++hash + ihex2fw + ikconfig.h* + initramfs_data.cpio ++initramfs_data.cpio.bz2 + initramfs_data.cpio.gz + initramfs_list + kallsyms +-kconfig + keywords.c + ksym.c* + ksym.h* +@@ -133,6 +142,7 @@ mkboot + mkbugboot + mkcpustr + mkdep ++mkpiggy + mkprep + mktables + mktree +@@ -149,6 +159,7 @@ patches* + pca200e.bin + pca200e_ecd.bin2 + piggy.gz ++piggy.S + piggyback + pnmtologo + ppc_defs.h* +@@ -164,6 +175,7 @@ setup + setup.bin + setup.elf + sImage ++slabinfo + sm_tbl* + split-include + syscalltab.h +@@ -187,14 +199,20 @@ version.h* + vmlinux + vmlinux-* + vmlinux.aout ++vmlinux.bin.all ++vmlinux.bin.bz2 + vmlinux.lds ++vmlinux.relocs ++voffset.h + vsyscall.lds + vsyscall_32.lds + wanxlfw.inc + uImage + unifdef ++utsrelease.h + wakeup.bin + wakeup.elf + wakeup.lds + zImage* + zconf.hash.c ++zoffset.h +diff -urNp linux-2.6.31.1/Documentation/kernel-parameters.txt linux-2.6.31.1/Documentation/kernel-parameters.txt +--- linux-2.6.31.1/Documentation/kernel-parameters.txt 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/Documentation/kernel-parameters.txt 2009-10-01 20:12:42.000000000 -0400 +@@ -1776,6 +1776,12 @@ and is between 256 and 4096 characters. + the specified number of seconds. This is to be used if + your oopses keep scrolling off the screen. + ++ pax_nouderef [X86-32] disables UDEREF. Most likely needed under certain ++ virtualization environments that don't cope well with the ++ expand down segment used by UDEREF on X86-32. ++ ++ pax_softmode= [X86-32] 0/1 to disable/enable PaX softmode on boot already. ++ + pcbit= [HW,ISDN] + + pcd. [PARIDE] +diff -urNp linux-2.6.31.1/drivers/acpi/blacklist.c linux-2.6.31.1/drivers/acpi/blacklist.c +--- linux-2.6.31.1/drivers/acpi/blacklist.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/acpi/blacklist.c 2009-10-01 20:12:42.000000000 -0400 +@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b + {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, + "Incorrect _ADR", 1}, + +- {""} ++ {"", "", 0, 0, 0, all_versions, 0} + }; + + #if CONFIG_ACPI_BLACKLIST_YEAR +diff -urNp linux-2.6.31.1/drivers/acpi/osl.c linux-2.6.31.1/drivers/acpi/osl.c +--- linux-2.6.31.1/drivers/acpi/osl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/acpi/osl.c 2009-10-01 20:12:42.000000000 -0400 +@@ -521,6 +521,8 @@ acpi_os_read_memory(acpi_physical_addres + void __iomem *virt_addr; + + virt_addr = ioremap(phys_addr, width); ++ if (!virt_addr) ++ return AE_NO_MEMORY; + if (!value) + value = &dummy; + +@@ -549,6 +551,8 @@ acpi_os_write_memory(acpi_physical_addre + void __iomem *virt_addr; + + virt_addr = ioremap(phys_addr, width); ++ if (!virt_addr) ++ return AE_NO_MEMORY; + + switch (width) { + case 8: +diff -urNp linux-2.6.31.1/drivers/acpi/processor_core.c linux-2.6.31.1/drivers/acpi/processor_core.c +--- linux-2.6.31.1/drivers/acpi/processor_core.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/acpi/processor_core.c 2009-10-01 20:12:42.000000000 -0400 +@@ -712,7 +712,7 @@ static int __cpuinit acpi_processor_star + return 0; + } + +- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); ++ BUG_ON(pr->id >= nr_cpu_ids); + + /* + * Buggy BIOS check +diff -urNp linux-2.6.31.1/drivers/acpi/processor_idle.c linux-2.6.31.1/drivers/acpi/processor_idle.c +--- linux-2.6.31.1/drivers/acpi/processor_idle.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/acpi/processor_idle.c 2009-10-01 20:12:42.000000000 -0400 +@@ -108,7 +108,7 @@ static struct dmi_system_id __cpuinitdat + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, + (void *)2}, +- {}, ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL}, + }; + + +diff -urNp linux-2.6.31.1/drivers/acpi/video.c linux-2.6.31.1/drivers/acpi/video.c +--- linux-2.6.31.1/drivers/acpi/video.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/acpi/video.c 2009-10-01 20:12:42.000000000 -0400 +@@ -283,7 +283,7 @@ static int acpi_video_device_brightness_ + struct file *file); + static ssize_t acpi_video_device_write_brightness(struct file *file, + const char __user *buffer, size_t count, loff_t *data); +-static struct file_operations acpi_video_device_brightness_fops = { ++static const struct file_operations acpi_video_device_brightness_fops = { + .owner = THIS_MODULE, + .open = acpi_video_device_brightness_open_fs, + .read = seq_read, +diff -urNp linux-2.6.31.1/drivers/ata/ahci.c linux-2.6.31.1/drivers/ata/ahci.c +--- linux-2.6.31.1/drivers/ata/ahci.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ata/ahci.c 2009-10-01 20:12:42.000000000 -0400 +@@ -629,7 +629,7 @@ static const struct pci_device_id ahci_p + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, + +- { } /* terminate list */ ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ + }; + + +diff -urNp linux-2.6.31.1/drivers/ata/ata_piix.c linux-2.6.31.1/drivers/ata/ata_piix.c +--- linux-2.6.31.1/drivers/ata/ata_piix.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ata/ata_piix.c 2009-10-01 20:12:42.000000000 -0400 +@@ -291,7 +291,7 @@ static const struct pci_device_id piix_p + { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (PCH) */ + { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, +- { } /* terminate list */ ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ + }; + + static struct pci_driver piix_pci_driver = { +@@ -608,7 +608,7 @@ static const struct ich_laptop ich_lapto + { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ + { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */ + /* end marker */ +- { 0, } ++ { 0, 0, 0 } + }; + + /** +@@ -1086,7 +1086,7 @@ static int piix_broken_suspend(void) + }, + }, + +- { } /* terminate list */ ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } /* terminate list */ + }; + static const char *oemstrs[] = { + "Tecra M3,", +diff -urNp linux-2.6.31.1/drivers/ata/libata-core.c linux-2.6.31.1/drivers/ata/libata-core.c +--- linux-2.6.31.1/drivers/ata/libata-core.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ata/libata-core.c 2009-10-01 20:12:42.000000000 -0400 +@@ -896,7 +896,7 @@ static const struct ata_xfer_ent { + { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 }, + { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 }, + { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 }, +- { -1, }, ++ { -1, 0, 0 } + }; + + /** +@@ -3141,7 +3141,7 @@ static const struct ata_timing ata_timin + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 }, + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 }, + +- { 0xFF } ++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + + #define ENOUGH(v, unit) (((v)-1)/(unit)+1) +@@ -4339,7 +4339,7 @@ static const struct ata_blacklist_entry + { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, + + /* End Marker */ +- { } ++ { NULL, NULL, 0 } + }; + + static int strn_pattern_cmp(const char *patt, const char *name, int wildchar) +diff -urNp linux-2.6.31.1/drivers/atm/adummy.c linux-2.6.31.1/drivers/atm/adummy.c +--- linux-2.6.31.1/drivers/atm/adummy.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/adummy.c 2009-10-01 20:12:42.000000000 -0400 +@@ -77,7 +77,7 @@ adummy_send(struct atm_vcc *vcc, struct + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + + return 0; + } +diff -urNp linux-2.6.31.1/drivers/atm/ambassador.c linux-2.6.31.1/drivers/atm/ambassador.c +--- linux-2.6.31.1/drivers/atm/ambassador.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/ambassador.c 2009-10-01 20:12:42.000000000 -0400 +@@ -453,7 +453,7 @@ static void tx_complete (amb_dev * dev, + PRINTD (DBG_FLOW|DBG_TX, "tx_complete %p %p", dev, tx); + + // VC layer stats +- atomic_inc(&ATM_SKB(skb)->vcc->stats->tx); ++ atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx); + + // free the descriptor + kfree (tx_descr); +@@ -494,7 +494,7 @@ static void rx_complete (amb_dev * dev, + dump_skb ("<<<", vc, skb); + + // VC layer stats +- atomic_inc(&atm_vcc->stats->rx); ++ atomic_inc_unchecked(&atm_vcc->stats->rx); + __net_timestamp(skb); + // end of our responsability + atm_vcc->push (atm_vcc, skb); +@@ -509,7 +509,7 @@ static void rx_complete (amb_dev * dev, + } else { + PRINTK (KERN_INFO, "dropped over-size frame"); + // should we count this? +- atomic_inc(&atm_vcc->stats->rx_drop); ++ atomic_inc_unchecked(&atm_vcc->stats->rx_drop); + } + + } else { +@@ -1349,7 +1349,7 @@ static int amb_send (struct atm_vcc * at + } + + if (check_area (skb->data, skb->len)) { +- atomic_inc(&atm_vcc->stats->tx_err); ++ atomic_inc_unchecked(&atm_vcc->stats->tx_err); + return -ENOMEM; // ? + } + +diff -urNp linux-2.6.31.1/drivers/atm/atmtcp.c linux-2.6.31.1/drivers/atm/atmtcp.c +--- linux-2.6.31.1/drivers/atm/atmtcp.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/atmtcp.c 2009-10-01 20:12:42.000000000 -0400 +@@ -206,7 +206,7 @@ static int atmtcp_v_send(struct atm_vcc + if (vcc->pop) vcc->pop(vcc,skb); + else dev_kfree_skb(skb); + if (dev_data) return 0; +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + return -ENOLINK; + } + size = skb->len+sizeof(struct atmtcp_hdr); +@@ -214,7 +214,7 @@ static int atmtcp_v_send(struct atm_vcc + if (!new_skb) { + if (vcc->pop) vcc->pop(vcc,skb); + else dev_kfree_skb(skb); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + return -ENOBUFS; + } + hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr)); +@@ -225,8 +225,8 @@ static int atmtcp_v_send(struct atm_vcc + if (vcc->pop) vcc->pop(vcc,skb); + else dev_kfree_skb(skb); + out_vcc->push(out_vcc,new_skb); +- atomic_inc(&vcc->stats->tx); +- atomic_inc(&out_vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->tx); ++ atomic_inc_unchecked(&out_vcc->stats->rx); + return 0; + } + +@@ -300,7 +300,7 @@ static int atmtcp_c_send(struct atm_vcc + out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci)); + read_unlock(&vcc_sklist_lock); + if (!out_vcc) { +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + goto done; + } + skb_pull(skb,sizeof(struct atmtcp_hdr)); +@@ -312,8 +312,8 @@ static int atmtcp_c_send(struct atm_vcc + __net_timestamp(new_skb); + skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len); + out_vcc->push(out_vcc,new_skb); +- atomic_inc(&vcc->stats->tx); +- atomic_inc(&out_vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->tx); ++ atomic_inc_unchecked(&out_vcc->stats->rx); + done: + if (vcc->pop) vcc->pop(vcc,skb); + else dev_kfree_skb(skb); +diff -urNp linux-2.6.31.1/drivers/atm/eni.c linux-2.6.31.1/drivers/atm/eni.c +--- linux-2.6.31.1/drivers/atm/eni.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/eni.c 2009-10-01 20:12:42.000000000 -0400 +@@ -525,7 +525,7 @@ static int rx_aal0(struct atm_vcc *vcc) + DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n", + vcc->dev->number); + length = 0; +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + } + else { + length = ATM_CELL_SIZE-1; /* no HEC */ +@@ -580,7 +580,7 @@ static int rx_aal5(struct atm_vcc *vcc) + size); + } + eff = length = 0; +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + } + else { + size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2); +@@ -597,7 +597,7 @@ static int rx_aal5(struct atm_vcc *vcc) + "(VCI=%d,length=%ld,size=%ld (descr 0x%lx))\n", + vcc->dev->number,vcc->vci,length,size << 2,descr); + length = eff = 0; +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + } + } + skb = eff ? atm_alloc_charge(vcc,eff << 2,GFP_ATOMIC) : NULL; +@@ -770,7 +770,7 @@ rx_dequeued++; + vcc->push(vcc,skb); + pushed++; + } +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + } + wake_up(&eni_dev->rx_wait); + } +@@ -1227,7 +1227,7 @@ static void dequeue_tx(struct atm_dev *d + PCI_DMA_TODEVICE); + if (vcc->pop) vcc->pop(vcc,skb); + else dev_kfree_skb_irq(skb); +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + wake_up(&eni_dev->tx_wait); + dma_complete++; + } +diff -urNp linux-2.6.31.1/drivers/atm/firestream.c linux-2.6.31.1/drivers/atm/firestream.c +--- linux-2.6.31.1/drivers/atm/firestream.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/firestream.c 2009-10-01 20:12:42.000000000 -0400 +@@ -748,7 +748,7 @@ static void process_txdone_queue (struct + } + } + +- atomic_inc(&ATM_SKB(skb)->vcc->stats->tx); ++ atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx); + + fs_dprintk (FS_DEBUG_TXMEM, "i"); + fs_dprintk (FS_DEBUG_ALLOC, "Free t-skb: %p\n", skb); +@@ -815,7 +815,7 @@ static void process_incoming (struct fs_ + #endif + skb_put (skb, qe->p1 & 0xffff); + ATM_SKB(skb)->vcc = atm_vcc; +- atomic_inc(&atm_vcc->stats->rx); ++ atomic_inc_unchecked(&atm_vcc->stats->rx); + __net_timestamp(skb); + fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb); + atm_vcc->push (atm_vcc, skb); +@@ -836,12 +836,12 @@ static void process_incoming (struct fs_ + kfree (pe); + } + if (atm_vcc) +- atomic_inc(&atm_vcc->stats->rx_drop); ++ atomic_inc_unchecked(&atm_vcc->stats->rx_drop); + break; + case 0x1f: /* Reassembly abort: no buffers. */ + /* Silently increment error counter. */ + if (atm_vcc) +- atomic_inc(&atm_vcc->stats->rx_drop); ++ atomic_inc_unchecked(&atm_vcc->stats->rx_drop); + break; + default: /* Hmm. Haven't written the code to handle the others yet... -- REW */ + printk (KERN_WARNING "Don't know what to do with RX status %x: %s.\n", +diff -urNp linux-2.6.31.1/drivers/atm/fore200e.c linux-2.6.31.1/drivers/atm/fore200e.c +--- linux-2.6.31.1/drivers/atm/fore200e.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/fore200e.c 2009-10-01 20:12:42.000000000 -0400 +@@ -931,9 +931,9 @@ fore200e_tx_irq(struct fore200e* fore200 + #endif + /* check error condition */ + if (*entry->status & STATUS_ERROR) +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + else +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + } + } + +@@ -1082,7 +1082,7 @@ fore200e_push_rpd(struct fore200e* fore2 + if (skb == NULL) { + DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len); + +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + return -ENOMEM; + } + +@@ -1125,14 +1125,14 @@ fore200e_push_rpd(struct fore200e* fore2 + + dev_kfree_skb_any(skb); + +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + return -ENOMEM; + } + + ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0); + + vcc->push(vcc, skb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + + ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0); + +@@ -1210,7 +1210,7 @@ fore200e_rx_irq(struct fore200e* fore200 + DPRINTK(2, "damaged PDU on %d.%d.%d\n", + fore200e->atm_dev->number, + entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + } + } + +@@ -1655,7 +1655,7 @@ fore200e_send(struct atm_vcc *vcc, struc + goto retry_here; + } + +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + + fore200e->tx_sat++; + DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n", +diff -urNp linux-2.6.31.1/drivers/atm/he.c linux-2.6.31.1/drivers/atm/he.c +--- linux-2.6.31.1/drivers/atm/he.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/he.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1728,7 +1728,7 @@ he_service_rbrq(struct he_dev *he_dev, i + + if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) { + hprintk("HBUF_ERR! (cid 0x%x)\n", cid); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + goto return_host_buffers; + } + +@@ -1761,7 +1761,7 @@ he_service_rbrq(struct he_dev *he_dev, i + RBRQ_LEN_ERR(he_dev->rbrq_head) + ? "LEN_ERR" : "", + vcc->vpi, vcc->vci); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + goto return_host_buffers; + } + +@@ -1820,7 +1820,7 @@ he_service_rbrq(struct he_dev *he_dev, i + vcc->push(vcc, skb); + spin_lock(&he_dev->global_lock); + +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + + return_host_buffers: + ++pdus_assembled; +@@ -2165,7 +2165,7 @@ __enqueue_tpd(struct he_dev *he_dev, str + tpd->vcc->pop(tpd->vcc, tpd->skb); + else + dev_kfree_skb_any(tpd->skb); +- atomic_inc(&tpd->vcc->stats->tx_err); ++ atomic_inc_unchecked(&tpd->vcc->stats->tx_err); + } + pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status)); + return; +@@ -2577,7 +2577,7 @@ he_send(struct atm_vcc *vcc, struct sk_b + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + return -EINVAL; + } + +@@ -2588,7 +2588,7 @@ he_send(struct atm_vcc *vcc, struct sk_b + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + return -EINVAL; + } + #endif +@@ -2600,7 +2600,7 @@ he_send(struct atm_vcc *vcc, struct sk_b + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + return -ENOMEM; + } +@@ -2642,7 +2642,7 @@ he_send(struct atm_vcc *vcc, struct sk_b + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + return -ENOMEM; + } +@@ -2673,7 +2673,7 @@ he_send(struct atm_vcc *vcc, struct sk_b + __enqueue_tpd(he_dev, tpd, cid); + spin_unlock_irqrestore(&he_dev->global_lock, flags); + +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + + return 0; + } +diff -urNp linux-2.6.31.1/drivers/atm/horizon.c linux-2.6.31.1/drivers/atm/horizon.c +--- linux-2.6.31.1/drivers/atm/horizon.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/horizon.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1033,7 +1033,7 @@ static void rx_schedule (hrz_dev * dev, + { + struct atm_vcc * vcc = ATM_SKB(skb)->vcc; + // VC layer stats +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + __net_timestamp(skb); + // end of our responsability + vcc->push (vcc, skb); +@@ -1185,7 +1185,7 @@ static void tx_schedule (hrz_dev * const + dev->tx_iovec = NULL; + + // VC layer stats +- atomic_inc(&ATM_SKB(skb)->vcc->stats->tx); ++ atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx); + + // free the skb + hrz_kfree_skb (skb); +diff -urNp linux-2.6.31.1/drivers/atm/idt77252.c linux-2.6.31.1/drivers/atm/idt77252.c +--- linux-2.6.31.1/drivers/atm/idt77252.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/idt77252.c 2009-10-01 20:12:42.000000000 -0400 +@@ -810,7 +810,7 @@ drain_scq(struct idt77252_dev *card, str + else + dev_kfree_skb(skb); + +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + } + + atomic_dec(&scq->used); +@@ -1073,13 +1073,13 @@ dequeue_rx(struct idt77252_dev *card, st + if ((sb = dev_alloc_skb(64)) == NULL) { + printk("%s: Can't allocate buffers for aal0.\n", + card->name); +- atomic_add(i, &vcc->stats->rx_drop); ++ atomic_add_unchecked(i, &vcc->stats->rx_drop); + break; + } + if (!atm_charge(vcc, sb->truesize)) { + RXPRINTK("%s: atm_charge() dropped aal0 packets.\n", + card->name); +- atomic_add(i - 1, &vcc->stats->rx_drop); ++ atomic_add_unchecked(i - 1, &vcc->stats->rx_drop); + dev_kfree_skb(sb); + break; + } +@@ -1096,7 +1096,7 @@ dequeue_rx(struct idt77252_dev *card, st + ATM_SKB(sb)->vcc = vcc; + __net_timestamp(sb); + vcc->push(vcc, sb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + + cell += ATM_CELL_PAYLOAD; + } +@@ -1133,13 +1133,13 @@ dequeue_rx(struct idt77252_dev *card, st + "(CDC: %08x)\n", + card->name, len, rpp->len, readl(SAR_REG_CDC)); + recycle_rx_pool_skb(card, rpp); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + return; + } + if (stat & SAR_RSQE_CRC) { + RXPRINTK("%s: AAL5 CRC error.\n", card->name); + recycle_rx_pool_skb(card, rpp); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + return; + } + if (skb_queue_len(&rpp->queue) > 1) { +@@ -1150,7 +1150,7 @@ dequeue_rx(struct idt77252_dev *card, st + RXPRINTK("%s: Can't alloc RX skb.\n", + card->name); + recycle_rx_pool_skb(card, rpp); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + return; + } + if (!atm_charge(vcc, skb->truesize)) { +@@ -1169,7 +1169,7 @@ dequeue_rx(struct idt77252_dev *card, st + __net_timestamp(skb); + + vcc->push(vcc, skb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + + return; + } +@@ -1191,7 +1191,7 @@ dequeue_rx(struct idt77252_dev *card, st + __net_timestamp(skb); + + vcc->push(vcc, skb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + + if (skb->truesize > SAR_FB_SIZE_3) + add_rx_skb(card, 3, SAR_FB_SIZE_3, 1); +@@ -1303,14 +1303,14 @@ idt77252_rx_raw(struct idt77252_dev *car + if (vcc->qos.aal != ATM_AAL0) { + RPRINTK("%s: raw cell for non AAL0 vc %u.%u\n", + card->name, vpi, vci); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + goto drop; + } + + if ((sb = dev_alloc_skb(64)) == NULL) { + printk("%s: Can't allocate buffers for AAL0.\n", + card->name); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + goto drop; + } + +@@ -1329,7 +1329,7 @@ idt77252_rx_raw(struct idt77252_dev *car + ATM_SKB(sb)->vcc = vcc; + __net_timestamp(sb); + vcc->push(vcc, sb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + + drop: + skb_pull(queue, 64); +@@ -1954,13 +1954,13 @@ idt77252_send_skb(struct atm_vcc *vcc, s + + if (vc == NULL) { + printk("%s: NULL connection in send().\n", card->name); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb(skb); + return -EINVAL; + } + if (!test_bit(VCF_TX, &vc->flags)) { + printk("%s: Trying to transmit on a non-tx VC.\n", card->name); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb(skb); + return -EINVAL; + } +@@ -1972,14 +1972,14 @@ idt77252_send_skb(struct atm_vcc *vcc, s + break; + default: + printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb(skb); + return -EINVAL; + } + + if (skb_shinfo(skb)->nr_frags != 0) { + printk("%s: No scatter-gather yet.\n", card->name); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb(skb); + return -EINVAL; + } +@@ -1987,7 +1987,7 @@ idt77252_send_skb(struct atm_vcc *vcc, s + + err = queue_skb(card, vc, skb, oam); + if (err) { +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb(skb); + return err; + } +@@ -2010,7 +2010,7 @@ idt77252_send_oam(struct atm_vcc *vcc, v + skb = dev_alloc_skb(64); + if (!skb) { + printk("%s: Out of memory in send_oam().\n", card->name); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + return -ENOMEM; + } + atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc); +diff -urNp linux-2.6.31.1/drivers/atm/iphase.c linux-2.6.31.1/drivers/atm/iphase.c +--- linux-2.6.31.1/drivers/atm/iphase.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/iphase.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1123,7 +1123,7 @@ static int rx_pkt(struct atm_dev *dev) + status = (u_short) (buf_desc_ptr->desc_mode); + if (status & (RX_CER | RX_PTE | RX_OFL)) + { +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + IF_ERR(printk("IA: bad packet, dropping it");) + if (status & RX_CER) { + IF_ERR(printk(" cause: packet CRC error\n");) +@@ -1146,7 +1146,7 @@ static int rx_pkt(struct atm_dev *dev) + len = dma_addr - buf_addr; + if (len > iadev->rx_buf_sz) { + printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + goto out_free_desc; + } + +@@ -1296,7 +1296,7 @@ static void rx_dle_intr(struct atm_dev * + ia_vcc = INPH_IA_VCC(vcc); + if (ia_vcc == NULL) + { +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + dev_kfree_skb_any(skb); + atm_return(vcc, atm_guess_pdu2truesize(len)); + goto INCR_DLE; +@@ -1308,7 +1308,7 @@ static void rx_dle_intr(struct atm_dev * + if ((length > iadev->rx_buf_sz) || (length > + (skb->len - sizeof(struct cpcs_trailer)))) + { +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + IF_ERR(printk("rx_dle_intr: Bad AAL5 trailer %d (skb len %d)", + length, skb->len);) + dev_kfree_skb_any(skb); +@@ -1324,7 +1324,7 @@ static void rx_dle_intr(struct atm_dev * + + IF_RX(printk("rx_dle_intr: skb push");) + vcc->push(vcc,skb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + iadev->rx_pkt_cnt++; + } + INCR_DLE: +@@ -2806,15 +2806,15 @@ static int ia_ioctl(struct atm_dev *dev, + { + struct k_sonet_stats *stats; + stats = &PRIV(_ia_dev[board])->sonet_stats; +- printk("section_bip: %d\n", atomic_read(&stats->section_bip)); +- printk("line_bip : %d\n", atomic_read(&stats->line_bip)); +- printk("path_bip : %d\n", atomic_read(&stats->path_bip)); +- printk("line_febe : %d\n", atomic_read(&stats->line_febe)); +- printk("path_febe : %d\n", atomic_read(&stats->path_febe)); +- printk("corr_hcs : %d\n", atomic_read(&stats->corr_hcs)); +- printk("uncorr_hcs : %d\n", atomic_read(&stats->uncorr_hcs)); +- printk("tx_cells : %d\n", atomic_read(&stats->tx_cells)); +- printk("rx_cells : %d\n", atomic_read(&stats->rx_cells)); ++ printk("section_bip: %d\n", atomic_read_unchecked(&stats->section_bip)); ++ printk("line_bip : %d\n", atomic_read_unchecked(&stats->line_bip)); ++ printk("path_bip : %d\n", atomic_read_unchecked(&stats->path_bip)); ++ printk("line_febe : %d\n", atomic_read_unchecked(&stats->line_febe)); ++ printk("path_febe : %d\n", atomic_read_unchecked(&stats->path_febe)); ++ printk("corr_hcs : %d\n", atomic_read_unchecked(&stats->corr_hcs)); ++ printk("uncorr_hcs : %d\n", atomic_read_unchecked(&stats->uncorr_hcs)); ++ printk("tx_cells : %d\n", atomic_read_unchecked(&stats->tx_cells)); ++ printk("rx_cells : %d\n", atomic_read_unchecked(&stats->rx_cells)); + } + ia_cmds.status = 0; + break; +@@ -2919,7 +2919,7 @@ static int ia_pkt_tx (struct atm_vcc *vc + if ((desc == 0) || (desc > iadev->num_tx_desc)) + { + IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);) +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + if (vcc->pop) + vcc->pop(vcc, skb); + else +@@ -3024,14 +3024,14 @@ static int ia_pkt_tx (struct atm_vcc *vc + ATM_DESC(skb) = vcc->vci; + skb_queue_tail(&iadev->tx_dma_q, skb); + +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + iadev->tx_pkt_cnt++; + /* Increment transaction counter */ + writel(2, iadev->dma+IPHASE5575_TX_COUNTER); + + #if 0 + /* add flow control logic */ +- if (atomic_read(&vcc->stats->tx) % 20 == 0) { ++ if (atomic_read_unchecked(&vcc->stats->tx) % 20 == 0) { + if (iavcc->vc_desc_cnt > 10) { + vcc->tx_quota = vcc->tx_quota * 3 / 4; + printk("Tx1: vcc->tx_quota = %d \n", (u32)vcc->tx_quota ); +diff -urNp linux-2.6.31.1/drivers/atm/lanai.c linux-2.6.31.1/drivers/atm/lanai.c +--- linux-2.6.31.1/drivers/atm/lanai.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/lanai.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1305,7 +1305,7 @@ static void lanai_send_one_aal5(struct l + vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0); + lanai_endtx(lanai, lvcc); + lanai_free_skb(lvcc->tx.atmvcc, skb); +- atomic_inc(&lvcc->tx.atmvcc->stats->tx); ++ atomic_inc_unchecked(&lvcc->tx.atmvcc->stats->tx); + } + + /* Try to fill the buffer - don't call unless there is backlog */ +@@ -1428,7 +1428,7 @@ static void vcc_rx_aal5(struct lanai_vcc + ATM_SKB(skb)->vcc = lvcc->rx.atmvcc; + __net_timestamp(skb); + lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb); +- atomic_inc(&lvcc->rx.atmvcc->stats->rx); ++ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx); + out: + lvcc->rx.buf.ptr = end; + cardvcc_write(lvcc, endptr, vcc_rxreadptr); +@@ -1670,7 +1670,7 @@ static int handle_service(struct lanai_d + DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 " + "vcc %d\n", lanai->number, (unsigned int) s, vci); + lanai->stats.service_rxnotaal5++; +- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err); ++ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err); + return 0; + } + if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) { +@@ -1682,7 +1682,7 @@ static int handle_service(struct lanai_d + int bytes; + read_unlock(&vcc_sklist_lock); + DPRINTK("got trashed rx pdu on vci %d\n", vci); +- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err); ++ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err); + lvcc->stats.x.aal5.service_trash++; + bytes = (SERVICE_GET_END(s) * 16) - + (((unsigned long) lvcc->rx.buf.ptr) - +@@ -1694,7 +1694,7 @@ static int handle_service(struct lanai_d + } + if (s & SERVICE_STREAM) { + read_unlock(&vcc_sklist_lock); +- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err); ++ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err); + lvcc->stats.x.aal5.service_stream++; + printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream " + "PDU on VCI %d!\n", lanai->number, vci); +@@ -1702,7 +1702,7 @@ static int handle_service(struct lanai_d + return 0; + } + DPRINTK("got rx crc error on vci %d\n", vci); +- atomic_inc(&lvcc->rx.atmvcc->stats->rx_err); ++ atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err); + lvcc->stats.x.aal5.service_rxcrc++; + lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4]; + cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr); +diff -urNp linux-2.6.31.1/drivers/atm/nicstar.c linux-2.6.31.1/drivers/atm/nicstar.c +--- linux-2.6.31.1/drivers/atm/nicstar.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/nicstar.c 2009-10-01 20:12:42.000000000 -0400 +@@ -1723,7 +1723,7 @@ static int ns_send(struct atm_vcc *vcc, + if ((vc = (vc_map *) vcc->dev_data) == NULL) + { + printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n", card->index); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb_any(skb); + return -EINVAL; + } +@@ -1731,7 +1731,7 @@ static int ns_send(struct atm_vcc *vcc, + if (!vc->tx) + { + printk("nicstar%d: Trying to transmit on a non-tx VC.\n", card->index); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb_any(skb); + return -EINVAL; + } +@@ -1739,7 +1739,7 @@ static int ns_send(struct atm_vcc *vcc, + if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) + { + printk("nicstar%d: Only AAL0 and AAL5 are supported.\n", card->index); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb_any(skb); + return -EINVAL; + } +@@ -1747,7 +1747,7 @@ static int ns_send(struct atm_vcc *vcc, + if (skb_shinfo(skb)->nr_frags != 0) + { + printk("nicstar%d: No scatter-gather yet.\n", card->index); +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb_any(skb); + return -EINVAL; + } +@@ -1792,11 +1792,11 @@ static int ns_send(struct atm_vcc *vcc, + + if (push_scqe(card, vc, scq, &scqe, skb) != 0) + { +- atomic_inc(&vcc->stats->tx_err); ++ atomic_inc_unchecked(&vcc->stats->tx_err); + dev_kfree_skb_any(skb); + return -EIO; + } +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + + return 0; + } +@@ -2111,14 +2111,14 @@ static void dequeue_rx(ns_dev *card, ns_ + { + printk("nicstar%d: Can't allocate buffers for aal0.\n", + card->index); +- atomic_add(i,&vcc->stats->rx_drop); ++ atomic_add_unchecked(i,&vcc->stats->rx_drop); + break; + } + if (!atm_charge(vcc, sb->truesize)) + { + RXPRINTK("nicstar%d: atm_charge() dropped aal0 packets.\n", + card->index); +- atomic_add(i-1,&vcc->stats->rx_drop); /* already increased by 1 */ ++ atomic_add_unchecked(i-1,&vcc->stats->rx_drop); /* already increased by 1 */ + dev_kfree_skb_any(sb); + break; + } +@@ -2133,7 +2133,7 @@ static void dequeue_rx(ns_dev *card, ns_ + ATM_SKB(sb)->vcc = vcc; + __net_timestamp(sb); + vcc->push(vcc, sb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + cell += ATM_CELL_PAYLOAD; + } + +@@ -2152,7 +2152,7 @@ static void dequeue_rx(ns_dev *card, ns_ + if (iovb == NULL) + { + printk("nicstar%d: Out of iovec buffers.\n", card->index); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + recycle_rx_buf(card, skb); + return; + } +@@ -2182,7 +2182,7 @@ static void dequeue_rx(ns_dev *card, ns_ + else if (NS_SKB(iovb)->iovcnt >= NS_MAX_IOVECS) + { + printk("nicstar%d: received too big AAL5 SDU.\n", card->index); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, NS_MAX_IOVECS); + NS_SKB(iovb)->iovcnt = 0; + iovb->len = 0; +@@ -2202,7 +2202,7 @@ static void dequeue_rx(ns_dev *card, ns_ + printk("nicstar%d: Expected a small buffer, and this is not one.\n", + card->index); + which_list(card, skb); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + recycle_rx_buf(card, skb); + vc->rx_iov = NULL; + recycle_iov_buf(card, iovb); +@@ -2216,7 +2216,7 @@ static void dequeue_rx(ns_dev *card, ns_ + printk("nicstar%d: Expected a large buffer, and this is not one.\n", + card->index); + which_list(card, skb); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, + NS_SKB(iovb)->iovcnt); + vc->rx_iov = NULL; +@@ -2240,7 +2240,7 @@ static void dequeue_rx(ns_dev *card, ns_ + printk(" - PDU size mismatch.\n"); + else + printk(".\n"); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, + NS_SKB(iovb)->iovcnt); + vc->rx_iov = NULL; +@@ -2256,7 +2256,7 @@ static void dequeue_rx(ns_dev *card, ns_ + if (!atm_charge(vcc, skb->truesize)) + { + push_rxbufs(card, skb); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + } + else + { +@@ -2268,7 +2268,7 @@ static void dequeue_rx(ns_dev *card, ns_ + ATM_SKB(skb)->vcc = vcc; + __net_timestamp(skb); + vcc->push(vcc, skb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + } + } + else if (NS_SKB(iovb)->iovcnt == 2) /* One small plus one large buffer */ +@@ -2283,7 +2283,7 @@ static void dequeue_rx(ns_dev *card, ns_ + if (!atm_charge(vcc, sb->truesize)) + { + push_rxbufs(card, sb); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + } + else + { +@@ -2295,7 +2295,7 @@ static void dequeue_rx(ns_dev *card, ns_ + ATM_SKB(sb)->vcc = vcc; + __net_timestamp(sb); + vcc->push(vcc, sb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + } + + push_rxbufs(card, skb); +@@ -2306,7 +2306,7 @@ static void dequeue_rx(ns_dev *card, ns_ + if (!atm_charge(vcc, skb->truesize)) + { + push_rxbufs(card, skb); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + } + else + { +@@ -2320,7 +2320,7 @@ static void dequeue_rx(ns_dev *card, ns_ + ATM_SKB(skb)->vcc = vcc; + __net_timestamp(skb); + vcc->push(vcc, skb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + } + + push_rxbufs(card, sb); +@@ -2342,7 +2342,7 @@ static void dequeue_rx(ns_dev *card, ns_ + if (hb == NULL) + { + printk("nicstar%d: Out of huge buffers.\n", card->index); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, + NS_SKB(iovb)->iovcnt); + vc->rx_iov = NULL; +@@ -2393,7 +2393,7 @@ static void dequeue_rx(ns_dev *card, ns_ + } + else + dev_kfree_skb_any(hb); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + } + else + { +@@ -2427,7 +2427,7 @@ static void dequeue_rx(ns_dev *card, ns_ + #endif /* NS_USE_DESTRUCTORS */ + __net_timestamp(hb); + vcc->push(vcc, hb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + } + } + +diff -urNp linux-2.6.31.1/drivers/atm/solos-pci.c linux-2.6.31.1/drivers/atm/solos-pci.c +--- linux-2.6.31.1/drivers/atm/solos-pci.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/solos-pci.c 2009-10-01 20:12:42.000000000 -0400 +@@ -663,7 +663,7 @@ void solos_bh(unsigned long card_arg) + } + atm_charge(vcc, skb->truesize); + vcc->push(vcc, skb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + break; + + case PKT_STATUS: +@@ -966,7 +966,7 @@ static uint32_t fpga_tx(struct solos_car + vcc = SKB_CB(oldskb)->vcc; + + if (vcc) { +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + solos_pop(vcc, oldskb); + } else + dev_kfree_skb_irq(oldskb); +diff -urNp linux-2.6.31.1/drivers/atm/suni.c linux-2.6.31.1/drivers/atm/suni.c +--- linux-2.6.31.1/drivers/atm/suni.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/suni.c 2009-10-01 20:12:42.000000000 -0400 +@@ -49,8 +49,8 @@ static DEFINE_SPINLOCK(sunis_lock); + + + #define ADD_LIMITED(s,v) \ +- atomic_add((v),&stats->s); \ +- if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX); ++ atomic_add_unchecked((v),&stats->s); \ ++ if (atomic_read_unchecked(&stats->s) < 0) atomic_set_unchecked(&stats->s,INT_MAX); + + + static void suni_hz(unsigned long from_timer) +diff -urNp linux-2.6.31.1/drivers/atm/uPD98402.c linux-2.6.31.1/drivers/atm/uPD98402.c +--- linux-2.6.31.1/drivers/atm/uPD98402.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/uPD98402.c 2009-10-01 20:12:42.000000000 -0400 +@@ -41,7 +41,7 @@ static int fetch_stats(struct atm_dev *d + struct sonet_stats tmp; + int error = 0; + +- atomic_add(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs); ++ atomic_add_unchecked(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs); + sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp); + if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp)); + if (zero && !error) { +@@ -160,9 +160,9 @@ static int uPD98402_ioctl(struct atm_dev + + + #define ADD_LIMITED(s,v) \ +- { atomic_add(GET(v),&PRIV(dev)->sonet_stats.s); \ +- if (atomic_read(&PRIV(dev)->sonet_stats.s) < 0) \ +- atomic_set(&PRIV(dev)->sonet_stats.s,INT_MAX); } ++ { atomic_add_unchecked(GET(v),&PRIV(dev)->sonet_stats.s); \ ++ if (atomic_read_unchecked(&PRIV(dev)->sonet_stats.s) < 0) \ ++ atomic_set_unchecked(&PRIV(dev)->sonet_stats.s,INT_MAX); } + + + static void stat_event(struct atm_dev *dev) +@@ -193,7 +193,7 @@ static void uPD98402_int(struct atm_dev + if (reason & uPD98402_INT_PFM) stat_event(dev); + if (reason & uPD98402_INT_PCO) { + (void) GET(PCOCR); /* clear interrupt cause */ +- atomic_add(GET(HECCT), ++ atomic_add_unchecked(GET(HECCT), + &PRIV(dev)->sonet_stats.uncorr_hcs); + } + if ((reason & uPD98402_INT_RFO) && +@@ -221,9 +221,9 @@ static int uPD98402_start(struct atm_dev + PUT(~(uPD98402_INT_PFM | uPD98402_INT_ALM | uPD98402_INT_RFO | + uPD98402_INT_LOS),PIMR); /* enable them */ + (void) fetch_stats(dev,NULL,1); /* clear kernel counters */ +- atomic_set(&PRIV(dev)->sonet_stats.corr_hcs,-1); +- atomic_set(&PRIV(dev)->sonet_stats.tx_cells,-1); +- atomic_set(&PRIV(dev)->sonet_stats.rx_cells,-1); ++ atomic_set_unchecked(&PRIV(dev)->sonet_stats.corr_hcs,-1); ++ atomic_set_unchecked(&PRIV(dev)->sonet_stats.tx_cells,-1); ++ atomic_set_unchecked(&PRIV(dev)->sonet_stats.rx_cells,-1); + return 0; + } + +diff -urNp linux-2.6.31.1/drivers/atm/zatm.c linux-2.6.31.1/drivers/atm/zatm.c +--- linux-2.6.31.1/drivers/atm/zatm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/atm/zatm.c 2009-10-01 20:12:42.000000000 -0400 +@@ -458,7 +458,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy + } + if (!size) { + dev_kfree_skb_irq(skb); +- if (vcc) atomic_inc(&vcc->stats->rx_err); ++ if (vcc) atomic_inc_unchecked(&vcc->stats->rx_err); + continue; + } + if (!atm_charge(vcc,skb->truesize)) { +@@ -468,7 +468,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy + skb->len = size; + ATM_SKB(skb)->vcc = vcc; + vcc->push(vcc,skb); +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + } + zout(pos & 0xffff,MTA(mbx)); + #if 0 /* probably a stupid idea */ +@@ -732,7 +732,7 @@ if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD + skb_queue_head(&zatm_vcc->backlog,skb); + break; + } +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + wake_up(&zatm_vcc->tx_wait); + } + +diff -urNp linux-2.6.31.1/drivers/block/cciss.c linux-2.6.31.1/drivers/block/cciss.c +--- linux-2.6.31.1/drivers/block/cciss.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/block/cciss.c 2009-10-01 20:12:42.000000000 -0400 +@@ -363,7 +363,7 @@ static void cciss_seq_stop(struct seq_fi + h->busy_configuring = 0; + } + +-static struct seq_operations cciss_seq_ops = { ++static const struct seq_operations cciss_seq_ops = { + .start = cciss_seq_start, + .show = cciss_seq_show, + .next = cciss_seq_next, +@@ -426,7 +426,7 @@ out: + return err; + } + +-static struct file_operations cciss_proc_fops = { ++static const struct file_operations cciss_proc_fops = { + .owner = THIS_MODULE, + .open = cciss_seq_open, + .read = seq_read, +diff -urNp linux-2.6.31.1/drivers/char/agp/agp.h linux-2.6.31.1/drivers/char/agp/agp.h +--- linux-2.6.31.1/drivers/char/agp/agp.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/agp/agp.h 2009-10-01 20:12:42.000000000 -0400 +@@ -126,7 +126,7 @@ struct agp_bridge_driver { + struct agp_bridge_data { + const struct agp_version *version; + const struct agp_bridge_driver *driver; +- struct vm_operations_struct *vm_ops; ++ const struct vm_operations_struct *vm_ops; + void *previous_size; + void *current_size; + void *dev_private_data; +diff -urNp linux-2.6.31.1/drivers/char/agp/alpha-agp.c linux-2.6.31.1/drivers/char/agp/alpha-agp.c +--- linux-2.6.31.1/drivers/char/agp/alpha-agp.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/agp/alpha-agp.c 2009-10-01 20:12:42.000000000 -0400 +@@ -40,7 +40,7 @@ static struct aper_size_info_fixed alpha + { 0, 0, 0 }, /* filled in by alpha_core_agp_setup */ + }; + +-struct vm_operations_struct alpha_core_agp_vm_ops = { ++const struct vm_operations_struct alpha_core_agp_vm_ops = { + .fault = alpha_core_agp_vm_fault, + }; + +diff -urNp linux-2.6.31.1/drivers/char/agp/frontend.c linux-2.6.31.1/drivers/char/agp/frontend.c +--- linux-2.6.31.1/drivers/char/agp/frontend.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/agp/frontend.c 2009-10-01 20:12:42.000000000 -0400 +@@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag + if (copy_from_user(&reserve, arg, sizeof(struct agp_region))) + return -EFAULT; + +- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment)) ++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv)) + return -EFAULT; + + client = agp_find_client_by_pid(reserve.pid); +diff -urNp linux-2.6.31.1/drivers/char/agp/intel-agp.c linux-2.6.31.1/drivers/char/agp/intel-agp.c +--- linux-2.6.31.1/drivers/char/agp/intel-agp.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/agp/intel-agp.c 2009-10-01 20:12:42.000000000 -0400 +@@ -2395,7 +2395,7 @@ static struct pci_device_id agp_intel_pc + ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), + ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), + ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), +- { } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(pci, agp_intel_pci_table); +diff -urNp linux-2.6.31.1/drivers/char/apm-emulation.c linux-2.6.31.1/drivers/char/apm-emulation.c +--- linux-2.6.31.1/drivers/char/apm-emulation.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/apm-emulation.c 2009-10-01 20:12:42.000000000 -0400 +@@ -393,7 +393,7 @@ static int apm_open(struct inode * inode + return as ? 0 : -ENOMEM; + } + +-static struct file_operations apm_bios_fops = { ++static const struct file_operations apm_bios_fops = { + .owner = THIS_MODULE, + .read = apm_read, + .poll = apm_poll, +diff -urNp linux-2.6.31.1/drivers/char/bfin-otp.c linux-2.6.31.1/drivers/char/bfin-otp.c +--- linux-2.6.31.1/drivers/char/bfin-otp.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/bfin-otp.c 2009-10-01 20:12:42.000000000 -0400 +@@ -133,7 +133,7 @@ static ssize_t bfin_otp_write(struct fil + # define bfin_otp_write NULL + #endif + +-static struct file_operations bfin_otp_fops = { ++static const struct file_operations bfin_otp_fops = { + .owner = THIS_MODULE, + .read = bfin_otp_read, + .write = bfin_otp_write, +diff -urNp linux-2.6.31.1/drivers/char/hpet.c linux-2.6.31.1/drivers/char/hpet.c +--- linux-2.6.31.1/drivers/char/hpet.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/hpet.c 2009-10-01 20:12:42.000000000 -0400 +@@ -995,7 +995,7 @@ static struct acpi_driver hpet_acpi_driv + }, + }; + +-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops }; ++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL }; + + static int __init hpet_init(void) + { +diff -urNp linux-2.6.31.1/drivers/char/hvcs.c linux-2.6.31.1/drivers/char/hvcs.c +--- linux-2.6.31.1/drivers/char/hvcs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/hvcs.c 2009-10-01 20:12:42.000000000 -0400 +@@ -269,7 +269,7 @@ struct hvcs_struct { + unsigned int index; + + struct tty_struct *tty; +- int open_count; ++ atomic_t open_count; + + /* + * Used to tell the driver kernel_thread what operations need to take +@@ -419,7 +419,7 @@ static ssize_t hvcs_vterm_state_store(st + + spin_lock_irqsave(&hvcsd->lock, flags); + +- if (hvcsd->open_count > 0) { ++ if (atomic_read(&hvcsd->open_count) > 0) { + spin_unlock_irqrestore(&hvcsd->lock, flags); + printk(KERN_INFO "HVCS: vterm state unchanged. " + "The hvcs device node is still in use.\n"); +@@ -1135,7 +1135,7 @@ static int hvcs_open(struct tty_struct * + if ((retval = hvcs_partner_connect(hvcsd))) + goto error_release; + +- hvcsd->open_count = 1; ++ atomic_set(&hvcsd->open_count, 1); + hvcsd->tty = tty; + tty->driver_data = hvcsd; + +@@ -1169,7 +1169,7 @@ fast_open: + + spin_lock_irqsave(&hvcsd->lock, flags); + kref_get(&hvcsd->kref); +- hvcsd->open_count++; ++ atomic_inc(&hvcsd->open_count); + hvcsd->todo_mask |= HVCS_SCHED_READ; + spin_unlock_irqrestore(&hvcsd->lock, flags); + +@@ -1213,7 +1213,7 @@ static void hvcs_close(struct tty_struct + hvcsd = tty->driver_data; + + spin_lock_irqsave(&hvcsd->lock, flags); +- if (--hvcsd->open_count == 0) { ++ if (atomic_dec_and_test(&hvcsd->open_count)) { + + vio_disable_interrupts(hvcsd->vdev); + +@@ -1239,10 +1239,10 @@ static void hvcs_close(struct tty_struct + free_irq(irq, hvcsd); + kref_put(&hvcsd->kref, destroy_hvcs_struct); + return; +- } else if (hvcsd->open_count < 0) { ++ } else if (atomic_read(&hvcsd->open_count) < 0) { + printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" + " is missmanaged.\n", +- hvcsd->vdev->unit_address, hvcsd->open_count); ++ hvcsd->vdev->unit_address, atomic_read(&hvcsd->open_count)); + } + + spin_unlock_irqrestore(&hvcsd->lock, flags); +@@ -1258,7 +1258,7 @@ static void hvcs_hangup(struct tty_struc + + spin_lock_irqsave(&hvcsd->lock, flags); + /* Preserve this so that we know how many kref refs to put */ +- temp_open_count = hvcsd->open_count; ++ temp_open_count = atomic_read(&hvcsd->open_count); + + /* + * Don't kref put inside the spinlock because the destruction +@@ -1273,7 +1273,7 @@ static void hvcs_hangup(struct tty_struc + hvcsd->tty->driver_data = NULL; + hvcsd->tty = NULL; + +- hvcsd->open_count = 0; ++ atomic_set(&hvcsd->open_count, 0); + + /* This will drop any buffered data on the floor which is OK in a hangup + * scenario. */ +@@ -1344,7 +1344,7 @@ static int hvcs_write(struct tty_struct + * the middle of a write operation? This is a crummy place to do this + * but we want to keep it all in the spinlock. + */ +- if (hvcsd->open_count <= 0) { ++ if (atomic_read(&hvcsd->open_count) <= 0) { + spin_unlock_irqrestore(&hvcsd->lock, flags); + return -ENODEV; + } +@@ -1418,7 +1418,7 @@ static int hvcs_write_room(struct tty_st + { + struct hvcs_struct *hvcsd = tty->driver_data; + +- if (!hvcsd || hvcsd->open_count <= 0) ++ if (!hvcsd || atomic_read(&hvcsd->open_count) <= 0) + return 0; + + return HVCS_BUFF_LEN - hvcsd->chars_in_buffer; +diff -urNp linux-2.6.31.1/drivers/char/ipmi/ipmi_msghandler.c linux-2.6.31.1/drivers/char/ipmi/ipmi_msghandler.c +--- linux-2.6.31.1/drivers/char/ipmi/ipmi_msghandler.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/ipmi/ipmi_msghandler.c 2009-10-01 20:12:42.000000000 -0400 +@@ -413,7 +413,7 @@ struct ipmi_smi { + struct proc_dir_entry *proc_dir; + char proc_dir_name[10]; + +- atomic_t stats[IPMI_NUM_STATS]; ++ atomic_unchecked_t stats[IPMI_NUM_STATS]; + + /* + * run_to_completion duplicate of smb_info, smi_info +@@ -446,9 +446,9 @@ static DEFINE_MUTEX(smi_watchers_mutex); + + + #define ipmi_inc_stat(intf, stat) \ +- atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat]) ++ atomic_inc_unchecked(&(intf)->stats[IPMI_STAT_ ## stat]) + #define ipmi_get_stat(intf, stat) \ +- ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat])) ++ ((unsigned int) atomic_read_unchecked(&(intf)->stats[IPMI_STAT_ ## stat])) + + static int is_lan_addr(struct ipmi_addr *addr) + { +@@ -2807,7 +2807,7 @@ int ipmi_register_smi(struct ipmi_smi_ha + INIT_LIST_HEAD(&intf->cmd_rcvrs); + init_waitqueue_head(&intf->waitq); + for (i = 0; i < IPMI_NUM_STATS; i++) +- atomic_set(&intf->stats[i], 0); ++ atomic_set_unchecked(&intf->stats[i], 0); + + intf->proc_dir = NULL; + +diff -urNp linux-2.6.31.1/drivers/char/ipmi/ipmi_si_intf.c linux-2.6.31.1/drivers/char/ipmi/ipmi_si_intf.c +--- linux-2.6.31.1/drivers/char/ipmi/ipmi_si_intf.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/ipmi/ipmi_si_intf.c 2009-10-01 20:12:42.000000000 -0400 +@@ -277,7 +277,7 @@ struct smi_info { + unsigned char slave_addr; + + /* Counters and things for the proc filesystem. */ +- atomic_t stats[SI_NUM_STATS]; ++ atomic_unchecked_t stats[SI_NUM_STATS]; + + struct task_struct *thread; + +@@ -285,9 +285,9 @@ struct smi_info { + }; + + #define smi_inc_stat(smi, stat) \ +- atomic_inc(&(smi)->stats[SI_STAT_ ## stat]) ++ atomic_inc_unchecked(&(smi)->stats[SI_STAT_ ## stat]) + #define smi_get_stat(smi, stat) \ +- ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_ ## stat])) ++ ((unsigned int) atomic_read_unchecked(&(smi)->stats[SI_STAT_ ## stat])) + + #define SI_MAX_PARMS 4 + +@@ -2926,7 +2926,7 @@ static int try_smi_init(struct smi_info + atomic_set(&new_smi->req_events, 0); + new_smi->run_to_completion = 0; + for (i = 0; i < SI_NUM_STATS; i++) +- atomic_set(&new_smi->stats[i], 0); ++ atomic_set_unchecked(&new_smi->stats[i], 0); + + new_smi->interrupt_disabled = 0; + atomic_set(&new_smi->stop_operation, 0); +diff -urNp linux-2.6.31.1/drivers/char/keyboard.c linux-2.6.31.1/drivers/char/keyboard.c +--- linux-2.6.31.1/drivers/char/keyboard.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/keyboard.c 2009-10-01 20:12:42.000000000 -0400 +@@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u + kbd->kbdmode == VC_MEDIUMRAW) && + value != KVAL(K_SAK)) + return; /* SAK is allowed even in raw mode */ ++ ++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP) ++ { ++ void *func = fn_handler[value]; ++ if (func == fn_show_state || func == fn_show_ptregs || ++ func == fn_show_mem) ++ return; ++ } ++#endif ++ + fn_handler[value](vc); + } + +@@ -1386,7 +1396,7 @@ static const struct input_device_id kbd_ + .evbit = { BIT_MASK(EV_SND) }, + }, + +- { }, /* Terminating entry */ ++ { 0 }, /* Terminating entry */ + }; + + MODULE_DEVICE_TABLE(input, kbd_ids); +diff -urNp linux-2.6.31.1/drivers/char/mem.c linux-2.6.31.1/drivers/char/mem.c +--- linux-2.6.31.1/drivers/char/mem.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/mem.c 2009-10-01 20:12:42.000000000 -0400 +@@ -18,6 +18,7 @@ + #include <linux/raw.h> + #include <linux/tty.h> + #include <linux/capability.h> ++#include <linux/security.h> + #include <linux/ptrace.h> + #include <linux/device.h> + #include <linux/highmem.h> +@@ -35,6 +36,10 @@ + # include <linux/efi.h> + #endif + ++#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC) ++extern struct file_operations grsec_fops; ++#endif ++ + /* + * Architectures vary in how they handle caching for addresses + * outside of main memory. +@@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f + if (!valid_phys_addr_range(p, count)) + return -EFAULT; + ++#ifdef CONFIG_GRKERNSEC_KMEM ++ gr_handle_mem_write(); ++ return -EPERM; ++#endif ++ + written = 0; + + #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED +@@ -301,7 +311,7 @@ static inline int private_mapping_ok(str + } + #endif + +-static struct vm_operations_struct mmap_mem_ops = { ++static const struct vm_operations_struct mmap_mem_ops = { + #ifdef CONFIG_HAVE_IOREMAP_PROT + .access = generic_access_phys + #endif +@@ -324,6 +334,11 @@ static int mmap_mem(struct file * file, + &vma->vm_page_prot)) + return -EINVAL; + ++#ifdef CONFIG_GRKERNSEC_KMEM ++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma)) ++ return -EPERM; ++#endif ++ + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, + size, + vma->vm_page_prot); +@@ -558,6 +573,11 @@ static ssize_t write_kmem(struct file * + ssize_t written; + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ + ++#ifdef CONFIG_GRKERNSEC_KMEM ++ gr_handle_kmem_write(); ++ return -EPERM; ++#endif ++ + if (p < (unsigned long) high_memory) { + + wrote = count; +@@ -763,6 +783,16 @@ static loff_t memory_lseek(struct file * + + static int open_port(struct inode * inode, struct file * filp) + { ++#ifdef CONFIG_GRKERNSEC_KMEM ++ gr_handle_open_port(); ++ return -EPERM; ++#endif ++ ++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; ++} ++ ++static int open_mem(struct inode * inode, struct file * filp) ++{ + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; + } + +@@ -770,7 +800,6 @@ static int open_port(struct inode * inod + #define full_lseek null_lseek + #define write_zero write_null + #define read_full read_zero +-#define open_mem open_port + #define open_kmem open_mem + #define open_oldmem open_mem + +@@ -888,6 +917,9 @@ static const struct { + #ifdef CONFIG_CRASH_DUMP + {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops, NULL}, + #endif ++#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC) ++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops}, ++#endif + }; + + static int memory_open(struct inode *inode, struct file *filp) +diff -urNp linux-2.6.31.1/drivers/char/misc.c linux-2.6.31.1/drivers/char/misc.c +--- linux-2.6.31.1/drivers/char/misc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/misc.c 2009-10-01 20:12:42.000000000 -0400 +@@ -91,7 +91,7 @@ static int misc_seq_show(struct seq_file + } + + +-static struct seq_operations misc_seq_ops = { ++static const struct seq_operations misc_seq_ops = { + .start = misc_seq_start, + .next = misc_seq_next, + .stop = misc_seq_stop, +diff -urNp linux-2.6.31.1/drivers/char/mspec.c linux-2.6.31.1/drivers/char/mspec.c +--- linux-2.6.31.1/drivers/char/mspec.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/mspec.c 2009-10-01 20:12:43.000000000 -0400 +@@ -239,7 +239,7 @@ mspec_fault(struct vm_area_struct *vma, + return VM_FAULT_NOPAGE; + } + +-static struct vm_operations_struct mspec_vm_ops = { ++static const struct vm_operations_struct mspec_vm_ops = { + .open = mspec_open, + .close = mspec_close, + .fault = mspec_fault, +diff -urNp linux-2.6.31.1/drivers/char/nvram.c linux-2.6.31.1/drivers/char/nvram.c +--- linux-2.6.31.1/drivers/char/nvram.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/nvram.c 2009-10-01 20:12:43.000000000 -0400 +@@ -429,7 +429,10 @@ static const struct file_operations nvra + static struct miscdevice nvram_dev = { + NVRAM_MINOR, + "nvram", +- &nvram_fops ++ &nvram_fops, ++ {NULL, NULL}, ++ NULL, ++ NULL + }; + + static int __init nvram_init(void) +diff -urNp linux-2.6.31.1/drivers/char/pcmcia/ipwireless/tty.c linux-2.6.31.1/drivers/char/pcmcia/ipwireless/tty.c +--- linux-2.6.31.1/drivers/char/pcmcia/ipwireless/tty.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/pcmcia/ipwireless/tty.c 2009-10-01 20:12:43.000000000 -0400 +@@ -51,7 +51,7 @@ struct ipw_tty { + int tty_type; + struct ipw_network *network; + struct tty_struct *linux_tty; +- int open_count; ++ atomic_t open_count; + unsigned int control_lines; + struct mutex ipw_tty_mutex; + int tx_bytes_queued; +@@ -127,10 +127,10 @@ static int ipw_open(struct tty_struct *l + mutex_unlock(&tty->ipw_tty_mutex); + return -ENODEV; + } +- if (tty->open_count == 0) ++ if (atomic_read(&tty->open_count) == 0) + tty->tx_bytes_queued = 0; + +- tty->open_count++; ++ atomic_inc(&tty->open_count); + + tty->linux_tty = linux_tty; + linux_tty->driver_data = tty; +@@ -146,9 +146,7 @@ static int ipw_open(struct tty_struct *l + + static void do_ipw_close(struct ipw_tty *tty) + { +- tty->open_count--; +- +- if (tty->open_count == 0) { ++ if (atomic_dec_return(&tty->open_count) == 0) { + struct tty_struct *linux_tty = tty->linux_tty; + + if (linux_tty != NULL) { +@@ -169,7 +167,7 @@ static void ipw_hangup(struct tty_struct + return; + + mutex_lock(&tty->ipw_tty_mutex); +- if (tty->open_count == 0) { ++ if (atomic_read(&tty->open_count) == 0) { + mutex_unlock(&tty->ipw_tty_mutex); + return; + } +@@ -198,7 +196,7 @@ void ipwireless_tty_received(struct ipw_ + return; + } + +- if (!tty->open_count) { ++ if (!atomic_read(&tty->open_count)) { + mutex_unlock(&tty->ipw_tty_mutex); + return; + } +@@ -240,7 +238,7 @@ static int ipw_write(struct tty_struct * + return -ENODEV; + + mutex_lock(&tty->ipw_tty_mutex); +- if (!tty->open_count) { ++ if (!atomic_read(&tty->open_count)) { + mutex_unlock(&tty->ipw_tty_mutex); + return -EINVAL; + } +@@ -280,7 +278,7 @@ static int ipw_write_room(struct tty_str + if (!tty) + return -ENODEV; + +- if (!tty->open_count) ++ if (!atomic_read(&tty->open_count)) + return -EINVAL; + + room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued; +@@ -322,7 +320,7 @@ static int ipw_chars_in_buffer(struct tt + if (!tty) + return 0; + +- if (!tty->open_count) ++ if (!atomic_read(&tty->open_count)) + return 0; + + return tty->tx_bytes_queued; +@@ -403,7 +401,7 @@ static int ipw_tiocmget(struct tty_struc + if (!tty) + return -ENODEV; + +- if (!tty->open_count) ++ if (!atomic_read(&tty->open_count)) + return -EINVAL; + + return get_control_lines(tty); +@@ -419,7 +417,7 @@ ipw_tiocmset(struct tty_struct *linux_tt + if (!tty) + return -ENODEV; + +- if (!tty->open_count) ++ if (!atomic_read(&tty->open_count)) + return -EINVAL; + + return set_control_lines(tty, set, clear); +@@ -433,7 +431,7 @@ static int ipw_ioctl(struct tty_struct * + if (!tty) + return -ENODEV; + +- if (!tty->open_count) ++ if (!atomic_read(&tty->open_count)) + return -EINVAL; + + /* FIXME: Exactly how is the tty object locked here .. */ +@@ -591,7 +589,7 @@ void ipwireless_tty_free(struct ipw_tty + against a parallel ioctl etc */ + mutex_lock(&ttyj->ipw_tty_mutex); + } +- while (ttyj->open_count) ++ while (atomic_read(&ttyj->open_count)) + do_ipw_close(ttyj); + ipwireless_disassociate_network_ttys(network, + ttyj->channel_idx); +diff -urNp linux-2.6.31.1/drivers/char/random.c linux-2.6.31.1/drivers/char/random.c +--- linux-2.6.31.1/drivers/char/random.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/random.c 2009-10-01 20:12:43.000000000 -0400 +@@ -253,8 +253,13 @@ + /* + * Configuration information + */ ++#ifdef CONFIG_GRKERNSEC_RANDNET ++#define INPUT_POOL_WORDS 512 ++#define OUTPUT_POOL_WORDS 128 ++#else + #define INPUT_POOL_WORDS 128 + #define OUTPUT_POOL_WORDS 32 ++#endif + #define SEC_XFER_SIZE 512 + + /* +@@ -291,10 +296,17 @@ static struct poolinfo { + int poolwords; + int tap1, tap2, tap3, tap4, tap5; + } poolinfo_table[] = { ++#ifdef CONFIG_GRKERNSEC_RANDNET ++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */ ++ { 512, 411, 308, 208, 104, 1 }, ++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */ ++ { 128, 103, 76, 51, 25, 1 }, ++#else + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */ + { 128, 103, 76, 51, 25, 1 }, + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */ + { 32, 26, 20, 14, 7, 1 }, ++#endif + #if 0 + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ + { 2048, 1638, 1231, 819, 411, 1 }, +@@ -1204,7 +1216,7 @@ EXPORT_SYMBOL(generate_random_uuid); + #include <linux/sysctl.h> + + static int min_read_thresh = 8, min_write_thresh; +-static int max_read_thresh = INPUT_POOL_WORDS * 32; ++static int max_read_thresh = OUTPUT_POOL_WORDS * 32; + static int max_write_thresh = INPUT_POOL_WORDS * 32; + static char sysctl_bootid[16]; + +diff -urNp linux-2.6.31.1/drivers/char/sonypi.c linux-2.6.31.1/drivers/char/sonypi.c +--- linux-2.6.31.1/drivers/char/sonypi.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/sonypi.c 2009-10-01 20:12:43.000000000 -0400 +@@ -490,7 +490,7 @@ static struct sonypi_device { + spinlock_t fifo_lock; + wait_queue_head_t fifo_proc_list; + struct fasync_struct *fifo_async; +- int open_count; ++ atomic_t open_count; + int model; + struct input_dev *input_jog_dev; + struct input_dev *input_key_dev; +@@ -894,7 +894,7 @@ static int sonypi_misc_fasync(int fd, st + static int sonypi_misc_release(struct inode *inode, struct file *file) + { + mutex_lock(&sonypi_device.lock); +- sonypi_device.open_count--; ++ atomic_dec(&sonypi_device.open_count); + mutex_unlock(&sonypi_device.lock); + return 0; + } +@@ -904,9 +904,9 @@ static int sonypi_misc_open(struct inode + lock_kernel(); + mutex_lock(&sonypi_device.lock); + /* Flush input queue on first open */ +- if (!sonypi_device.open_count) ++ if (!atomic_read(&sonypi_device.open_count)) + kfifo_reset(sonypi_device.fifo); +- sonypi_device.open_count++; ++ atomic_inc(&sonypi_device.open_count); + mutex_unlock(&sonypi_device.lock); + unlock_kernel(); + return 0; +diff -urNp linux-2.6.31.1/drivers/char/tpm/tpm_bios.c linux-2.6.31.1/drivers/char/tpm/tpm_bios.c +--- linux-2.6.31.1/drivers/char/tpm/tpm_bios.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/tpm/tpm_bios.c 2009-10-01 20:12:43.000000000 -0400 +@@ -343,14 +343,14 @@ static int tpm_ascii_bios_measurements_s + return 0; + } + +-static struct seq_operations tpm_ascii_b_measurments_seqops = { ++static const struct seq_operations tpm_ascii_b_measurments_seqops = { + .start = tpm_bios_measurements_start, + .next = tpm_bios_measurements_next, + .stop = tpm_bios_measurements_stop, + .show = tpm_ascii_bios_measurements_show, + }; + +-static struct seq_operations tpm_binary_b_measurments_seqops = { ++static const struct seq_operations tpm_binary_b_measurments_seqops = { + .start = tpm_bios_measurements_start, + .next = tpm_bios_measurements_next, + .stop = tpm_bios_measurements_stop, +diff -urNp linux-2.6.31.1/drivers/char/tty_ldisc.c linux-2.6.31.1/drivers/char/tty_ldisc.c +--- linux-2.6.31.1/drivers/char/tty_ldisc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/tty_ldisc.c 2009-10-01 20:12:43.000000000 -0400 +@@ -73,7 +73,7 @@ static void put_ldisc(struct tty_ldisc * + if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) { + struct tty_ldisc_ops *ldo = ld->ops; + +- ldo->refcount--; ++ atomic_dec(&ldo->refcount); + module_put(ldo->owner); + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + +@@ -107,7 +107,7 @@ int tty_register_ldisc(int disc, struct + spin_lock_irqsave(&tty_ldisc_lock, flags); + tty_ldiscs[disc] = new_ldisc; + new_ldisc->num = disc; +- new_ldisc->refcount = 0; ++ atomic_set(&new_ldisc->refcount, 0); + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + + return ret; +@@ -135,7 +135,7 @@ int tty_unregister_ldisc(int disc) + return -EINVAL; + + spin_lock_irqsave(&tty_ldisc_lock, flags); +- if (tty_ldiscs[disc]->refcount) ++ if (atomic_read(&tty_ldiscs[disc]->refcount)) + ret = -EBUSY; + else + tty_ldiscs[disc] = NULL; +@@ -175,7 +175,7 @@ static struct tty_ldisc *tty_ldisc_try_g + err = -EAGAIN; + else { + /* lock it */ +- ldops->refcount++; ++ atomic_inc(&ldops->refcount); + ld->ops = ldops; + atomic_set(&ld->users, 1); + err = 0; +diff -urNp linux-2.6.31.1/drivers/char/vt_ioctl.c linux-2.6.31.1/drivers/char/vt_ioctl.c +--- linux-2.6.31.1/drivers/char/vt_ioctl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/vt_ioctl.c 2009-10-01 20:12:43.000000000 -0400 +@@ -97,6 +97,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __ + case KDSKBENT: + if (!perm) + return -EPERM; ++ ++#ifdef CONFIG_GRKERNSEC ++ if (!capable(CAP_SYS_TTY_CONFIG)) ++ return -EPERM; ++#endif ++ + if (!i && v == K_NOSUCHMAP) { + /* deallocate map */ + key_map = key_maps[s]; +@@ -237,6 +243,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry + goto reterr; + } + ++#ifdef CONFIG_GRKERNSEC ++ if (!capable(CAP_SYS_TTY_CONFIG)) { ++ ret = -EPERM; ++ goto reterr; ++ } ++#endif ++ + q = func_table[i]; + first_free = funcbufptr + (funcbufsize - funcbufleft); + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) +diff -urNp linux-2.6.31.1/drivers/char/xilinx_hwicap/xilinx_hwicap.c linux-2.6.31.1/drivers/char/xilinx_hwicap/xilinx_hwicap.c +--- linux-2.6.31.1/drivers/char/xilinx_hwicap/xilinx_hwicap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/char/xilinx_hwicap/xilinx_hwicap.c 2009-10-01 20:12:43.000000000 -0400 +@@ -559,7 +559,7 @@ static int hwicap_release(struct inode * + return status; + } + +-static struct file_operations hwicap_fops = { ++static const struct file_operations hwicap_fops = { + .owner = THIS_MODULE, + .write = hwicap_write, + .read = hwicap_read, +diff -urNp linux-2.6.31.1/drivers/edac/edac_core.h linux-2.6.31.1/drivers/edac/edac_core.h +--- linux-2.6.31.1/drivers/edac/edac_core.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/edac/edac_core.h 2009-10-01 20:12:43.000000000 -0400 +@@ -99,11 +99,11 @@ extern int edac_debug_level; + + #else /* !CONFIG_EDAC_DEBUG */ + +-#define debugf0( ... ) +-#define debugf1( ... ) +-#define debugf2( ... ) +-#define debugf3( ... ) +-#define debugf4( ... ) ++#define debugf0( ... ) do {} while (0) ++#define debugf1( ... ) do {} while (0) ++#define debugf2( ... ) do {} while (0) ++#define debugf3( ... ) do {} while (0) ++#define debugf4( ... ) do {} while (0) + + #endif /* !CONFIG_EDAC_DEBUG */ + +diff -urNp linux-2.6.31.1/drivers/firmware/dmi_scan.c linux-2.6.31.1/drivers/firmware/dmi_scan.c +--- linux-2.6.31.1/drivers/firmware/dmi_scan.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/firmware/dmi_scan.c 2009-10-01 20:12:43.000000000 -0400 +@@ -391,11 +391,6 @@ void __init dmi_scan_machine(void) + } + } + else { +- /* +- * no iounmap() for that ioremap(); it would be a no-op, but +- * it's so early in setup that sucker gets confused into doing +- * what it shouldn't if we actually call it. +- */ + p = dmi_ioremap(0xF0000, 0x10000); + if (p == NULL) + goto error; +diff -urNp linux-2.6.31.1/drivers/gpio/gpiolib.c linux-2.6.31.1/drivers/gpio/gpiolib.c +--- linux-2.6.31.1/drivers/gpio/gpiolib.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpio/gpiolib.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1244,7 +1244,7 @@ static int gpiolib_open(struct inode *in + return single_open(file, gpiolib_show, NULL); + } + +-static struct file_operations gpiolib_operations = { ++static const struct file_operations gpiolib_operations = { + .open = gpiolib_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_drv.c linux-2.6.31.1/drivers/gpu/drm/drm_drv.c +--- linux-2.6.31.1/drivers/gpu/drm/drm_drv.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/drm_drv.c 2009-10-01 20:12:43.000000000 -0400 +@@ -417,7 +417,7 @@ int drm_ioctl(struct inode *inode, struc + char *kdata = NULL; + + atomic_inc(&dev->ioctl_count); +- atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); ++ atomic_inc_unchecked(&dev->counts[_DRM_STAT_IOCTLS]); + ++file_priv->ioctl_count; + + DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", +diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_fops.c linux-2.6.31.1/drivers/gpu/drm/drm_fops.c +--- linux-2.6.31.1/drivers/gpu/drm/drm_fops.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/drm_fops.c 2009-10-01 20:12:43.000000000 -0400 +@@ -66,7 +66,7 @@ static int drm_setup(struct drm_device * + } + + for (i = 0; i < ARRAY_SIZE(dev->counts); i++) +- atomic_set(&dev->counts[i], 0); ++ atomic_set_unchecked(&dev->counts[i], 0); + + dev->sigdata.lock = NULL; + +@@ -130,9 +130,9 @@ int drm_open(struct inode *inode, struct + + retcode = drm_open_helper(inode, filp, dev); + if (!retcode) { +- atomic_inc(&dev->counts[_DRM_STAT_OPENS]); ++ atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]); + spin_lock(&dev->count_lock); +- if (!dev->open_count++) { ++ if (atomic_inc_return(&dev->open_count) == 1) { + spin_unlock(&dev->count_lock); + retcode = drm_setup(dev); + goto out; +@@ -433,7 +433,7 @@ int drm_release(struct inode *inode, str + + lock_kernel(); + +- DRM_DEBUG("open_count = %d\n", dev->open_count); ++ DRM_DEBUG("open_count = %d\n", atomic_read(&dev->open_count)); + + if (dev->driver->preclose) + dev->driver->preclose(dev, file_priv); +@@ -445,7 +445,7 @@ int drm_release(struct inode *inode, str + DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", + task_pid_nr(current), + (long)old_encode_dev(file_priv->minor->device), +- dev->open_count); ++ atomic_read(&dev->open_count)); + + /* if the master has gone away we can't do anything with the lock */ + if (file_priv->minor->master) +@@ -522,9 +522,9 @@ int drm_release(struct inode *inode, str + * End inline drm_release + */ + +- atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); ++ atomic_inc_unchecked(&dev->counts[_DRM_STAT_CLOSES]); + spin_lock(&dev->count_lock); +- if (!--dev->open_count) { ++ if (atomic_dec_and_test(&dev->open_count)) { + if (atomic_read(&dev->ioctl_count)) { + DRM_ERROR("Device busy: %d\n", + atomic_read(&dev->ioctl_count)); +diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_ioctl.c linux-2.6.31.1/drivers/gpu/drm/drm_ioctl.c +--- linux-2.6.31.1/drivers/gpu/drm/drm_ioctl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/drm_ioctl.c 2009-10-01 20:12:43.000000000 -0400 +@@ -283,7 +283,7 @@ int drm_getstats(struct drm_device *dev, + stats->data[i].value = + (file_priv->master->lock.hw_lock ? file_priv->master->lock.hw_lock->lock : 0); + else +- stats->data[i].value = atomic_read(&dev->counts[i]); ++ stats->data[i].value = atomic_read_unchecked(&dev->counts[i]); + stats->data[i].type = dev->types[i]; + } + +diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_lock.c linux-2.6.31.1/drivers/gpu/drm/drm_lock.c +--- linux-2.6.31.1/drivers/gpu/drm/drm_lock.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/drm_lock.c 2009-10-01 20:12:43.000000000 -0400 +@@ -87,7 +87,7 @@ int drm_lock(struct drm_device *dev, voi + if (drm_lock_take(&master->lock, lock->context)) { + master->lock.file_priv = file_priv; + master->lock.lock_time = jiffies; +- atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); ++ atomic_inc_unchecked(&dev->counts[_DRM_STAT_LOCKS]); + break; /* Got lock */ + } + +@@ -165,7 +165,7 @@ int drm_unlock(struct drm_device *dev, v + return -EINVAL; + } + +- atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); ++ atomic_inc_unchecked(&dev->counts[_DRM_STAT_UNLOCKS]); + + /* kernel_context_switch isn't used by any of the x86 drm + * modules but is required by the Sparc driver. +diff -urNp linux-2.6.31.1/drivers/gpu/drm/drm_vm.c linux-2.6.31.1/drivers/gpu/drm/drm_vm.c +--- linux-2.6.31.1/drivers/gpu/drm/drm_vm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/drm_vm.c 2009-10-01 20:12:43.000000000 -0400 +@@ -369,28 +369,28 @@ static int drm_vm_sg_fault(struct vm_are + } + + /** AGP virtual memory operations */ +-static struct vm_operations_struct drm_vm_ops = { ++static const struct vm_operations_struct drm_vm_ops = { + .fault = drm_vm_fault, + .open = drm_vm_open, + .close = drm_vm_close, + }; + + /** Shared virtual memory operations */ +-static struct vm_operations_struct drm_vm_shm_ops = { ++static const struct vm_operations_struct drm_vm_shm_ops = { + .fault = drm_vm_shm_fault, + .open = drm_vm_open, + .close = drm_vm_shm_close, + }; + + /** DMA virtual memory operations */ +-static struct vm_operations_struct drm_vm_dma_ops = { ++static const struct vm_operations_struct drm_vm_dma_ops = { + .fault = drm_vm_dma_fault, + .open = drm_vm_open, + .close = drm_vm_close, + }; + + /** Scatter-gather virtual memory operations */ +-static struct vm_operations_struct drm_vm_sg_ops = { ++static const struct vm_operations_struct drm_vm_sg_ops = { + .fault = drm_vm_sg_fault, + .open = drm_vm_open, + .close = drm_vm_close, +diff -urNp linux-2.6.31.1/drivers/gpu/drm/i810/i810_dma.c linux-2.6.31.1/drivers/gpu/drm/i810/i810_dma.c +--- linux-2.6.31.1/drivers/gpu/drm/i810/i810_dma.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/i810/i810_dma.c 2009-10-01 20:12:43.000000000 -0400 +@@ -952,8 +952,8 @@ static int i810_dma_vertex(struct drm_de + dma->buflist[vertex->idx], + vertex->discard, vertex->used); + +- atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]); +- atomic_inc(&dev->counts[_DRM_STAT_DMA]); ++ atomic_add_unchecked(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]); ++ atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]); + sarea_priv->last_enqueue = dev_priv->counter - 1; + sarea_priv->last_dispatch = (int)hw_status[5]; + +@@ -1115,8 +1115,8 @@ static int i810_dma_mc(struct drm_device + i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used, + mc->last_render); + +- atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]); +- atomic_inc(&dev->counts[_DRM_STAT_DMA]); ++ atomic_add_unchecked(mc->used, &dev->counts[_DRM_STAT_SECONDARY]); ++ atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]); + sarea_priv->last_enqueue = dev_priv->counter - 1; + sarea_priv->last_dispatch = (int)hw_status[5]; + +diff -urNp linux-2.6.31.1/drivers/gpu/drm/i915/i915_drv.c linux-2.6.31.1/drivers/gpu/drm/i915/i915_drv.c +--- linux-2.6.31.1/drivers/gpu/drm/i915/i915_drv.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/i915/i915_drv.c 2009-10-01 20:12:43.000000000 -0400 +@@ -154,7 +154,7 @@ i915_pci_resume(struct pci_dev *pdev) + return i915_resume(dev); + } + +-static struct vm_operations_struct i915_gem_vm_ops = { ++static const struct vm_operations_struct i915_gem_vm_ops = { + .fault = i915_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +diff -urNp linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_atombios.c linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_atombios.c +--- linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_atombios.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_atombios.c 2009-10-01 20:12:43.000000000 -0400 +@@ -425,13 +425,13 @@ bool radeon_get_atom_connector_info_from + return true; + } + +-struct bios_connector { ++static struct bios_connector { + bool valid; + uint8_t line_mux; + uint16_t devices; + int connector_type; + struct radeon_i2c_bus_rec ddc_bus; +-}; ++} bios_connectors[ATOM_MAX_SUPPORTED_DEVICE];; + + bool radeon_get_atom_connector_info_from_supported_devices_table(struct + drm_device +@@ -447,7 +447,6 @@ bool radeon_get_atom_connector_info_from + uint8_t dac; + union atom_supported_devices *supported_devices; + int i, j; +- struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; + + atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); + +diff -urNp linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_state.c linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_state.c +--- linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_state.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_state.c 2009-10-01 20:12:43.000000000 -0400 +@@ -3007,7 +3007,7 @@ static int radeon_cp_getparam(struct drm + { + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_getparam_t *param = data; +- int value; ++ int value = 0; + + DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); + +diff -urNp linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_ttm.c linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_ttm.c +--- linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_ttm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/radeon/radeon_ttm.c 2009-10-01 20:12:43.000000000 -0400 +@@ -500,27 +500,10 @@ void radeon_ttm_fini(struct radeon_devic + DRM_INFO("radeon: ttm finalized\n"); + } + +-static struct vm_operations_struct radeon_ttm_vm_ops; +-static struct vm_operations_struct *ttm_vm_ops = NULL; +- +-static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +-{ +- struct ttm_buffer_object *bo; +- int r; +- +- bo = (struct ttm_buffer_object *)vma->vm_private_data; +- if (bo == NULL) { +- return VM_FAULT_NOPAGE; +- } +- r = ttm_vm_ops->fault(vma, vmf); +- return r; +-} +- + int radeon_mmap(struct file *filp, struct vm_area_struct *vma) + { + struct drm_file *file_priv; + struct radeon_device *rdev; +- int r; + + if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) { + return drm_mmap(filp, vma); +@@ -528,20 +511,9 @@ int radeon_mmap(struct file *filp, struc + + file_priv = (struct drm_file *)filp->private_data; + rdev = file_priv->minor->dev->dev_private; +- if (rdev == NULL) { ++ if (!rdev) + return -EINVAL; +- } +- r = ttm_bo_mmap(filp, vma, &rdev->mman.bdev); +- if (unlikely(r != 0)) { +- return r; +- } +- if (unlikely(ttm_vm_ops == NULL)) { +- ttm_vm_ops = vma->vm_ops; +- radeon_ttm_vm_ops = *ttm_vm_ops; +- radeon_ttm_vm_ops.fault = &radeon_ttm_fault; +- } +- vma->vm_ops = &radeon_ttm_vm_ops; +- return 0; ++ return ttm_bo_mmap(filp, vma, &rdev->mman.bdev); + } + + +diff -urNp linux-2.6.31.1/drivers/gpu/drm/ttm/ttm_bo_vm.c linux-2.6.31.1/drivers/gpu/drm/ttm/ttm_bo_vm.c +--- linux-2.6.31.1/drivers/gpu/drm/ttm/ttm_bo_vm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/gpu/drm/ttm/ttm_bo_vm.c 2009-10-01 20:12:43.000000000 -0400 +@@ -73,7 +73,7 @@ static int ttm_bo_vm_fault(struct vm_are + { + struct ttm_buffer_object *bo = (struct ttm_buffer_object *) + vma->vm_private_data; +- struct ttm_bo_device *bdev = bo->bdev; ++ struct ttm_bo_device *bdev; + unsigned long bus_base; + unsigned long bus_offset; + unsigned long bus_size; +@@ -88,6 +88,10 @@ static int ttm_bo_vm_fault(struct vm_are + unsigned long address = (unsigned long)vmf->virtual_address; + int retval = VM_FAULT_NOPAGE; + ++ if (!bo) ++ return VM_FAULT_NOPAGE; ++ bdev = bo->bdev; ++ + /* + * Work around locking order reversal in fault / nopfn + * between mmap_sem and bo_reserve: Perform a trylock operation +@@ -228,7 +232,7 @@ static void ttm_bo_vm_close(struct vm_ar + vma->vm_private_data = NULL; + } + +-static struct vm_operations_struct ttm_bo_vm_ops = { ++static const struct vm_operations_struct ttm_bo_vm_ops = { + .fault = ttm_bo_vm_fault, + .open = ttm_bo_vm_open, + .close = ttm_bo_vm_close +diff -urNp linux-2.6.31.1/drivers/hwmon/fschmd.c linux-2.6.31.1/drivers/hwmon/fschmd.c +--- linux-2.6.31.1/drivers/hwmon/fschmd.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/hwmon/fschmd.c 2009-10-01 20:12:43.000000000 -0400 +@@ -915,7 +915,7 @@ static int watchdog_ioctl(struct inode * + return ret; + } + +-static struct file_operations watchdog_fops = { ++static const struct file_operations watchdog_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = watchdog_open, +diff -urNp linux-2.6.31.1/drivers/hwmon/fscpos.c linux-2.6.31.1/drivers/hwmon/fscpos.c +--- linux-2.6.31.1/drivers/hwmon/fscpos.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/hwmon/fscpos.c 2009-10-01 20:12:43.000000000 -0400 +@@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client + unsigned long v = simple_strtoul(buf, NULL, 10); + + /* Range: 0..255 */ +- if (v < 0) v = 0; + if (v > 255) v = 255; + + mutex_lock(&data->update_lock); +diff -urNp linux-2.6.31.1/drivers/hwmon/k8temp.c linux-2.6.31.1/drivers/hwmon/k8temp.c +--- linux-2.6.31.1/drivers/hwmon/k8temp.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/hwmon/k8temp.c 2009-10-01 20:12:43.000000000 -0400 +@@ -138,7 +138,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n + + static struct pci_device_id k8temp_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, +- { 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, + }; + + MODULE_DEVICE_TABLE(pci, k8temp_ids); +diff -urNp linux-2.6.31.1/drivers/hwmon/sis5595.c linux-2.6.31.1/drivers/hwmon/sis5595.c +--- linux-2.6.31.1/drivers/hwmon/sis5595.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/hwmon/sis5595.c 2009-10-01 20:12:43.000000000 -0400 +@@ -699,7 +699,7 @@ static struct sis5595_data *sis5595_upda + + static struct pci_device_id sis5595_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(pci, sis5595_pci_ids); +diff -urNp linux-2.6.31.1/drivers/hwmon/via686a.c linux-2.6.31.1/drivers/hwmon/via686a.c +--- linux-2.6.31.1/drivers/hwmon/via686a.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/hwmon/via686a.c 2009-10-01 20:12:43.000000000 -0400 +@@ -769,7 +769,7 @@ static struct via686a_data *via686a_upda + + static struct pci_device_id via686a_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) }, +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(pci, via686a_pci_ids); +diff -urNp linux-2.6.31.1/drivers/hwmon/vt8231.c linux-2.6.31.1/drivers/hwmon/vt8231.c +--- linux-2.6.31.1/drivers/hwmon/vt8231.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/hwmon/vt8231.c 2009-10-01 20:12:43.000000000 -0400 +@@ -699,7 +699,7 @@ static struct platform_driver vt8231_dri + + static struct pci_device_id vt8231_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) }, +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(pci, vt8231_pci_ids); +diff -urNp linux-2.6.31.1/drivers/hwmon/w83791d.c linux-2.6.31.1/drivers/hwmon/w83791d.c +--- linux-2.6.31.1/drivers/hwmon/w83791d.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/hwmon/w83791d.c 2009-10-01 20:12:43.000000000 -0400 +@@ -330,8 +330,8 @@ static int w83791d_detect(struct i2c_cli + struct i2c_board_info *info); + static int w83791d_remove(struct i2c_client *client); + +-static int w83791d_read(struct i2c_client *client, u8 register); +-static int w83791d_write(struct i2c_client *client, u8 register, u8 value); ++static int w83791d_read(struct i2c_client *client, u8 reg); ++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value); + static struct w83791d_data *w83791d_update_device(struct device *dev); + + #ifdef DEBUG +diff -urNp linux-2.6.31.1/drivers/i2c/busses/i2c-i801.c linux-2.6.31.1/drivers/i2c/busses/i2c-i801.c +--- linux-2.6.31.1/drivers/i2c/busses/i2c-i801.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/i2c/busses/i2c-i801.c 2009-10-01 20:12:43.000000000 -0400 +@@ -578,7 +578,7 @@ static struct pci_device_id i801_ids[] = + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH_SMBUS) }, +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE (pci, i801_ids); +diff -urNp linux-2.6.31.1/drivers/i2c/busses/i2c-piix4.c linux-2.6.31.1/drivers/i2c/busses/i2c-piix4.c +--- linux-2.6.31.1/drivers/i2c/busses/i2c-piix4.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/i2c/busses/i2c-piix4.c 2009-10-01 20:12:43.000000000 -0400 +@@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat + .ident = "IBM", + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, + }, +- { }, ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }, + }; + + static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, +@@ -489,7 +489,7 @@ static struct pci_device_id piix4_ids[] + PCI_DEVICE_ID_SERVERWORKS_HT1000SB) }, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, + PCI_DEVICE_ID_SERVERWORKS_HT1100LD) }, +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE (pci, piix4_ids); +diff -urNp linux-2.6.31.1/drivers/i2c/busses/i2c-sis630.c linux-2.6.31.1/drivers/i2c/busses/i2c-sis630.c +--- linux-2.6.31.1/drivers/i2c/busses/i2c-sis630.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/i2c/busses/i2c-sis630.c 2009-10-01 20:12:43.000000000 -0400 +@@ -471,7 +471,7 @@ static struct i2c_adapter sis630_adapter + static struct pci_device_id sis630_ids[] __devinitdata = { + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) }, +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE (pci, sis630_ids); +diff -urNp linux-2.6.31.1/drivers/i2c/busses/i2c-sis96x.c linux-2.6.31.1/drivers/i2c/busses/i2c-sis96x.c +--- linux-2.6.31.1/drivers/i2c/busses/i2c-sis96x.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/i2c/busses/i2c-sis96x.c 2009-10-01 20:12:43.000000000 -0400 +@@ -247,7 +247,7 @@ static struct i2c_adapter sis96x_adapter + + static struct pci_device_id sis96x_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) }, +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE (pci, sis96x_ids); +diff -urNp linux-2.6.31.1/drivers/ieee1394/dma.c linux-2.6.31.1/drivers/ieee1394/dma.c +--- linux-2.6.31.1/drivers/ieee1394/dma.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ieee1394/dma.c 2009-10-01 20:12:43.000000000 -0400 +@@ -247,7 +247,7 @@ static int dma_region_pagefault(struct v + return 0; + } + +-static struct vm_operations_struct dma_region_vm_ops = { ++static const struct vm_operations_struct dma_region_vm_ops = { + .fault = dma_region_pagefault, + }; + +diff -urNp linux-2.6.31.1/drivers/ieee1394/dv1394.c linux-2.6.31.1/drivers/ieee1394/dv1394.c +--- linux-2.6.31.1/drivers/ieee1394/dv1394.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ieee1394/dv1394.c 2009-10-01 20:12:43.000000000 -0400 +@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c + based upon DIF section and sequence + */ + +-static void inline ++static inline void + frame_put_packet (struct frame *f, struct packet *p) + { + int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */ +@@ -2178,7 +2178,7 @@ static const struct ieee1394_device_id d + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + .version = AVC_SW_VERSION_ENTRY & 0xffffff + }, +- { } ++ { 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table); +diff -urNp linux-2.6.31.1/drivers/ieee1394/eth1394.c linux-2.6.31.1/drivers/ieee1394/eth1394.c +--- linux-2.6.31.1/drivers/ieee1394/eth1394.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ieee1394/eth1394.c 2009-10-01 20:12:43.000000000 -0400 +@@ -445,7 +445,7 @@ static const struct ieee1394_device_id e + .specifier_id = ETHER1394_GASP_SPECIFIER_ID, + .version = ETHER1394_GASP_VERSION, + }, +- {} ++ { 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table); +diff -urNp linux-2.6.31.1/drivers/ieee1394/hosts.c linux-2.6.31.1/drivers/ieee1394/hosts.c +--- linux-2.6.31.1/drivers/ieee1394/hosts.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ieee1394/hosts.c 2009-10-01 20:12:43.000000000 -0400 +@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso + } + + static struct hpsb_host_driver dummy_driver = { ++ .name = "dummy", + .transmit_packet = dummy_transmit_packet, + .devctl = dummy_devctl, + .isoctl = dummy_isoctl +diff -urNp linux-2.6.31.1/drivers/ieee1394/ohci1394.c linux-2.6.31.1/drivers/ieee1394/ohci1394.c +--- linux-2.6.31.1/drivers/ieee1394/ohci1394.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ieee1394/ohci1394.c 2009-10-01 20:12:43.000000000 -0400 +@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_ + printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) + + /* Module Parameters */ +-static int phys_dma = 1; ++static int phys_dma; + module_param(phys_dma, int, 0444); +-MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1)."); ++MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0)."); + + static void dma_trm_tasklet(unsigned long data); + static void dma_trm_reset(struct dma_trm_ctx *d); +@@ -3449,7 +3449,7 @@ static struct pci_device_id ohci1394_pci + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, +- { 0, }, ++ { 0, 0, 0, 0, 0, 0, 0 }, + }; + + MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl); +diff -urNp linux-2.6.31.1/drivers/ieee1394/raw1394.c linux-2.6.31.1/drivers/ieee1394/raw1394.c +--- linux-2.6.31.1/drivers/ieee1394/raw1394.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ieee1394/raw1394.c 2009-10-01 20:12:43.000000000 -0400 +@@ -2999,7 +2999,7 @@ static const struct ieee1394_device_id r + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff, + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff}, +- {} ++ { 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table); +diff -urNp linux-2.6.31.1/drivers/ieee1394/sbp2.c linux-2.6.31.1/drivers/ieee1394/sbp2.c +--- linux-2.6.31.1/drivers/ieee1394/sbp2.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ieee1394/sbp2.c 2009-10-01 20:12:43.000000000 -0400 +@@ -290,7 +290,7 @@ static const struct ieee1394_device_id s + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff, + .version = SBP2_SW_VERSION_ENTRY & 0xffffff}, +- {} ++ { 0, 0, 0, 0, 0, 0 } + }; + MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table); + +@@ -2112,7 +2112,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot + MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME); + MODULE_LICENSE("GPL"); + +-static int sbp2_module_init(void) ++static int __init sbp2_module_init(void) + { + int ret; + +diff -urNp linux-2.6.31.1/drivers/ieee1394/video1394.c linux-2.6.31.1/drivers/ieee1394/video1394.c +--- linux-2.6.31.1/drivers/ieee1394/video1394.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/ieee1394/video1394.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1310,7 +1310,7 @@ static const struct ieee1394_device_id v + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff, + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff + }, +- { } ++ { 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table); +diff -urNp linux-2.6.31.1/drivers/infiniband/hw/ehca/ehca_uverbs.c linux-2.6.31.1/drivers/infiniband/hw/ehca/ehca_uverbs.c +--- linux-2.6.31.1/drivers/infiniband/hw/ehca/ehca_uverbs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/infiniband/hw/ehca/ehca_uverbs.c 2009-10-01 20:12:43.000000000 -0400 +@@ -95,7 +95,7 @@ static void ehca_mm_close(struct vm_area + vma->vm_start, vma->vm_end, *count); + } + +-static struct vm_operations_struct vm_ops = { ++static const struct vm_operations_struct vm_ops = { + .open = ehca_mm_open, + .close = ehca_mm_close, + }; +diff -urNp linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_file_ops.c linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_file_ops.c +--- linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_file_ops.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_file_ops.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1151,7 +1151,7 @@ static int ipath_file_vma_fault(struct v + return 0; + } + +-static struct vm_operations_struct ipath_file_vm_ops = { ++static const struct vm_operations_struct ipath_file_vm_ops = { + .fault = ipath_file_vma_fault, + }; + +diff -urNp linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_mmap.c linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_mmap.c +--- linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_mmap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/infiniband/hw/ipath/ipath_mmap.c 2009-10-01 20:12:43.000000000 -0400 +@@ -74,7 +74,7 @@ static void ipath_vma_close(struct vm_ar + kref_put(&ip->ref, ipath_release_mmap_info); + } + +-static struct vm_operations_struct ipath_vm_ops = { ++static const struct vm_operations_struct ipath_vm_ops = { + .open = ipath_vma_open, + .close = ipath_vma_close, + }; +diff -urNp linux-2.6.31.1/drivers/input/keyboard/atkbd.c linux-2.6.31.1/drivers/input/keyboard/atkbd.c +--- linux-2.6.31.1/drivers/input/keyboard/atkbd.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/input/keyboard/atkbd.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1188,7 +1188,7 @@ static struct serio_device_id atkbd_seri + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, +- { 0 } ++ { 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(serio, atkbd_serio_ids); +diff -urNp linux-2.6.31.1/drivers/input/mouse/lifebook.c linux-2.6.31.1/drivers/input/mouse/lifebook.c +--- linux-2.6.31.1/drivers/input/mouse/lifebook.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/input/mouse/lifebook.c 2009-10-01 20:12:43.000000000 -0400 +@@ -116,7 +116,7 @@ static const struct dmi_system_id lifebo + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL} + }; + + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) +diff -urNp linux-2.6.31.1/drivers/input/mouse/psmouse-base.c linux-2.6.31.1/drivers/input/mouse/psmouse-base.c +--- linux-2.6.31.1/drivers/input/mouse/psmouse-base.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/input/mouse/psmouse-base.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1380,7 +1380,7 @@ static struct serio_device_id psmouse_se + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, +- { 0 } ++ { 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(serio, psmouse_serio_ids); +diff -urNp linux-2.6.31.1/drivers/input/mouse/synaptics.c linux-2.6.31.1/drivers/input/mouse/synaptics.c +--- linux-2.6.31.1/drivers/input/mouse/synaptics.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/input/mouse/synaptics.c 2009-10-01 20:12:43.000000000 -0400 +@@ -437,7 +437,7 @@ static void synaptics_process_packet(str + break; + case 2: + if (SYN_MODEL_PEN(priv->model_id)) +- ; /* Nothing, treat a pen as a single finger */ ++ break; /* Nothing, treat a pen as a single finger */ + break; + case 4 ... 15: + if (SYN_CAP_PALMDETECT(priv->capabilities)) +@@ -653,7 +653,7 @@ static const struct dmi_system_id toshib + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + #endif + +diff -urNp linux-2.6.31.1/drivers/input/mousedev.c linux-2.6.31.1/drivers/input/mousedev.c +--- linux-2.6.31.1/drivers/input/mousedev.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/input/mousedev.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han + + #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX + static struct miscdevice psaux_mouse = { +- PSMOUSE_MINOR, "psaux", &mousedev_fops ++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL + }; + static int psaux_registered; + #endif +diff -urNp linux-2.6.31.1/drivers/input/serio/i8042-x86ia64io.h linux-2.6.31.1/drivers/input/serio/i8042-x86ia64io.h +--- linux-2.6.31.1/drivers/input/serio/i8042-x86ia64io.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/input/serio/i8042-x86ia64io.h 2009-10-01 20:12:43.000000000 -0400 +@@ -167,7 +167,7 @@ static struct dmi_system_id __initdata i + DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + + /* +@@ -390,7 +390,7 @@ static struct dmi_system_id __initdata i + DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + + static struct dmi_system_id __initdata i8042_dmi_reset_table[] = { +@@ -436,7 +436,7 @@ static struct dmi_system_id __initdata i + DMI_MATCH(DMI_PRODUCT_NAME, "N10"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + + #ifdef CONFIG_PNP +@@ -455,7 +455,7 @@ static struct dmi_system_id __initdata i + DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + #endif + +@@ -522,7 +522,7 @@ static struct dmi_system_id __initdata i + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), + }, + }, +- { } ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, {0})}, NULL } + }; + + #endif /* CONFIG_X86 */ +diff -urNp linux-2.6.31.1/drivers/input/serio/serio_raw.c linux-2.6.31.1/drivers/input/serio/serio_raw.c +--- linux-2.6.31.1/drivers/input/serio/serio_raw.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/input/serio/serio_raw.c 2009-10-01 20:12:43.000000000 -0400 +@@ -376,7 +376,7 @@ static struct serio_device_id serio_raw_ + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, +- { 0 } ++ { 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids); +diff -urNp linux-2.6.31.1/drivers/isdn/capi/kcapi_proc.c linux-2.6.31.1/drivers/isdn/capi/kcapi_proc.c +--- linux-2.6.31.1/drivers/isdn/capi/kcapi_proc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/isdn/capi/kcapi_proc.c 2009-10-01 20:12:43.000000000 -0400 +@@ -89,14 +89,14 @@ static int contrstats_show(struct seq_fi + return 0; + } + +-static struct seq_operations seq_controller_ops = { ++static const struct seq_operations seq_controller_ops = { + .start = controller_start, + .next = controller_next, + .stop = controller_stop, + .show = controller_show, + }; + +-static struct seq_operations seq_contrstats_ops = { ++static const struct seq_operations seq_contrstats_ops = { + .start = controller_start, + .next = controller_next, + .stop = controller_stop, +@@ -194,14 +194,14 @@ applstats_show(struct seq_file *seq, voi + return 0; + } + +-static struct seq_operations seq_applications_ops = { ++static const struct seq_operations seq_applications_ops = { + .start = applications_start, + .next = applications_next, + .stop = applications_stop, + .show = applications_show, + }; + +-static struct seq_operations seq_applstats_ops = { ++static const struct seq_operations seq_applstats_ops = { + .start = applications_start, + .next = applications_next, + .stop = applications_stop, +@@ -264,7 +264,7 @@ static int capi_driver_show(struct seq_f + return 0; + } + +-static struct seq_operations seq_capi_driver_ops = { ++static const struct seq_operations seq_capi_driver_ops = { + .start = capi_driver_start, + .next = capi_driver_next, + .stop = capi_driver_stop, +diff -urNp linux-2.6.31.1/drivers/isdn/gigaset/common.c linux-2.6.31.1/drivers/isdn/gigaset/common.c +--- linux-2.6.31.1/drivers/isdn/gigaset/common.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/isdn/gigaset/common.c 2009-10-01 20:12:43.000000000 -0400 +@@ -665,7 +665,7 @@ struct cardstate *gigaset_initcs(struct + cs->commands_pending = 0; + cs->cur_at_seq = 0; + cs->gotfwver = -1; +- cs->open_count = 0; ++ atomic_set(&cs->open_count, 0); + cs->dev = NULL; + cs->tty = NULL; + cs->tty_dev = NULL; +diff -urNp linux-2.6.31.1/drivers/isdn/gigaset/gigaset.h linux-2.6.31.1/drivers/isdn/gigaset/gigaset.h +--- linux-2.6.31.1/drivers/isdn/gigaset/gigaset.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/isdn/gigaset/gigaset.h 2009-10-01 20:12:43.000000000 -0400 +@@ -446,7 +446,7 @@ struct cardstate { + spinlock_t cmdlock; + unsigned curlen, cmdbytes; + +- unsigned open_count; ++ atomic_t open_count; + struct tty_struct *tty; + struct tasklet_struct if_wake_tasklet; + unsigned control_state; +diff -urNp linux-2.6.31.1/drivers/isdn/gigaset/interface.c linux-2.6.31.1/drivers/isdn/gigaset/interface.c +--- linux-2.6.31.1/drivers/isdn/gigaset/interface.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/isdn/gigaset/interface.c 2009-10-01 20:12:43.000000000 -0400 +@@ -165,9 +165,7 @@ static int if_open(struct tty_struct *tt + return -ERESTARTSYS; // FIXME -EINTR? + tty->driver_data = cs; + +- ++cs->open_count; +- +- if (cs->open_count == 1) { ++ if (atomic_inc_return(&cs->open_count) == 1) { + spin_lock_irqsave(&cs->lock, flags); + cs->tty = tty; + spin_unlock_irqrestore(&cs->lock, flags); +@@ -195,10 +193,10 @@ static void if_close(struct tty_struct * + + if (!cs->connected) + gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ +- else if (!cs->open_count) ++ else if (!atomic_read(&cs->open_count)) + dev_warn(cs->dev, "%s: device not opened\n", __func__); + else { +- if (!--cs->open_count) { ++ if (!atomic_dec_return(&cs->open_count)) { + spin_lock_irqsave(&cs->lock, flags); + cs->tty = NULL; + spin_unlock_irqrestore(&cs->lock, flags); +@@ -233,7 +231,7 @@ static int if_ioctl(struct tty_struct *t + if (!cs->connected) { + gig_dbg(DEBUG_IF, "not connected"); + retval = -ENODEV; +- } else if (!cs->open_count) ++ } else if (!atomic_read(&cs->open_count)) + dev_warn(cs->dev, "%s: device not opened\n", __func__); + else { + retval = 0; +@@ -361,7 +359,7 @@ static int if_write(struct tty_struct *t + if (!cs->connected) { + gig_dbg(DEBUG_IF, "not connected"); + retval = -ENODEV; +- } else if (!cs->open_count) ++ } else if (!atomic_read(&cs->open_count)) + dev_warn(cs->dev, "%s: device not opened\n", __func__); + else if (cs->mstate != MS_LOCKED) { + dev_warn(cs->dev, "can't write to unlocked device\n"); +@@ -395,7 +393,7 @@ static int if_write_room(struct tty_stru + if (!cs->connected) { + gig_dbg(DEBUG_IF, "not connected"); + retval = -ENODEV; +- } else if (!cs->open_count) ++ } else if (!atomic_read(&cs->open_count)) + dev_warn(cs->dev, "%s: device not opened\n", __func__); + else if (cs->mstate != MS_LOCKED) { + dev_warn(cs->dev, "can't write to unlocked device\n"); +@@ -429,7 +427,7 @@ static int if_chars_in_buffer(struct tty + if (!cs->connected) { + gig_dbg(DEBUG_IF, "not connected"); + retval = -ENODEV; +- } else if (!cs->open_count) ++ } else if (!atomic_read(&cs->open_count)) + dev_warn(cs->dev, "%s: device not opened\n", __func__); + else if (cs->mstate != MS_LOCKED) { + dev_warn(cs->dev, "can't write to unlocked device\n"); +@@ -458,7 +456,7 @@ static void if_throttle(struct tty_struc + + if (!cs->connected) + gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ +- else if (!cs->open_count) ++ else if (!atomic_read(&cs->open_count)) + dev_warn(cs->dev, "%s: device not opened\n", __func__); + else { + //FIXME +@@ -483,7 +481,7 @@ static void if_unthrottle(struct tty_str + + if (!cs->connected) + gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ +- else if (!cs->open_count) ++ else if (!atomic_read(&cs->open_count)) + dev_warn(cs->dev, "%s: device not opened\n", __func__); + else { + //FIXME +@@ -515,7 +513,7 @@ static void if_set_termios(struct tty_st + goto out; + } + +- if (!cs->open_count) { ++ if (!atomic_read(&cs->open_count)) { + dev_warn(cs->dev, "%s: device not opened\n", __func__); + goto out; + } +diff -urNp linux-2.6.31.1/drivers/lguest/core.c linux-2.6.31.1/drivers/lguest/core.c +--- linux-2.6.31.1/drivers/lguest/core.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/lguest/core.c 2009-10-01 20:12:43.000000000 -0400 +@@ -92,9 +92,17 @@ static __init int map_switcher(void) + * it's worked so far. The end address needs +1 because __get_vm_area + * allocates an extra guard page, so we need space for that. + */ ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++ switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE, ++ VM_ALLOC | VM_KERNEXEC, SWITCHER_ADDR, SWITCHER_ADDR ++ + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE); ++#else + switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE, + VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR + + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE); ++#endif ++ + if (!switcher_vma) { + err = -ENOMEM; + printk("lguest: could not map switcher pages high\n"); +diff -urNp linux-2.6.31.1/drivers/lguest/lguest_user.c linux-2.6.31.1/drivers/lguest/lguest_user.c +--- linux-2.6.31.1/drivers/lguest/lguest_user.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/lguest/lguest_user.c 2009-10-01 20:12:43.000000000 -0400 +@@ -508,7 +508,7 @@ static int close(struct inode *inode, st + * uses: reading and writing a character device called /dev/lguest. All the + * work happens in the read(), write() and close() routines: + */ +-static struct file_operations lguest_fops = { ++static const struct file_operations lguest_fops = { + .owner = THIS_MODULE, + .release = close, + .write = write, +diff -urNp linux-2.6.31.1/drivers/md/bitmap.c linux-2.6.31.1/drivers/md/bitmap.c +--- linux-2.6.31.1/drivers/md/bitmap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/md/bitmap.c 2009-10-01 20:12:43.000000000 -0400 +@@ -58,7 +58,7 @@ + # if DEBUG > 0 + # define PRINTK(x...) printk(KERN_DEBUG x) + # else +-# define PRINTK(x...) ++# define PRINTK(x...) do {} while (0) + # endif + #endif + +diff -urNp linux-2.6.31.1/drivers/md/dm-table.c linux-2.6.31.1/drivers/md/dm-table.c +--- linux-2.6.31.1/drivers/md/dm-table.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/md/dm-table.c 2009-10-01 20:12:43.000000000 -0400 +@@ -359,7 +359,7 @@ static int device_area_is_invalid(struct + if (!dev_size) + return 0; + +- if ((start >= dev_size) || (start + len > dev_size)) { ++ if ((start >= dev_size) || (len > dev_size - start)) { + DMWARN("%s: %s too small for target: " + "start=%llu, len=%llu, dev_size=%llu", + dm_device_name(ti->table->md), bdevname(bdev, b), +diff -urNp linux-2.6.31.1/drivers/md/md.c linux-2.6.31.1/drivers/md/md.c +--- linux-2.6.31.1/drivers/md/md.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/md/md.c 2009-10-01 20:12:43.000000000 -0400 +@@ -5963,7 +5963,7 @@ static int md_seq_show(struct seq_file * + chunk_kb ? "KB" : "B"); + if (bitmap->file) { + seq_printf(seq, ", file: "); +- seq_path(seq, &bitmap->file->f_path, " \t\n"); ++ seq_path(seq, &bitmap->file->f_path, " \t\n\"); + } + + seq_printf(seq, "\n"); +@@ -6057,7 +6057,7 @@ static int is_mddev_idle(mddev_t *mddev, + struct gendisk *disk = rdev->bdev->bd_contains->bd_disk; + curr_events = (int)part_stat_read(&disk->part0, sectors[0]) + + (int)part_stat_read(&disk->part0, sectors[1]) - +- atomic_read(&disk->sync_io); ++ atomic_read_unchecked(&disk->sync_io); + /* sync IO will cause sync_io to increase before the disk_stats + * as sync_io is counted when a request starts, and + * disk_stats is counted when it completes. +diff -urNp linux-2.6.31.1/drivers/md/md.h linux-2.6.31.1/drivers/md/md.h +--- linux-2.6.31.1/drivers/md/md.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/md/md.h 2009-10-01 20:12:43.000000000 -0400 +@@ -303,7 +303,7 @@ static inline void rdev_dec_pending(mdk_ + + static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors) + { +- atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io); ++ atomic_add_unchecked(nr_sectors, &bdev->bd_contains->bd_disk->sync_io); + } + + struct mdk_personality +diff -urNp linux-2.6.31.1/drivers/media/dvb/dvb-core/dmxdev.c linux-2.6.31.1/drivers/media/dvb/dvb-core/dmxdev.c +--- linux-2.6.31.1/drivers/media/dvb/dvb-core/dmxdev.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/dvb/dvb-core/dmxdev.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1086,7 +1086,7 @@ static unsigned int dvb_dvr_poll(struct + return mask; + } + +-static struct file_operations dvb_dvr_fops = { ++static const struct file_operations dvb_dvr_fops = { + .owner = THIS_MODULE, + .read = dvb_dvr_read, + .write = dvb_dvr_write, +diff -urNp linux-2.6.31.1/drivers/media/dvb/firewire/firedtv-ci.c linux-2.6.31.1/drivers/media/dvb/firewire/firedtv-ci.c +--- linux-2.6.31.1/drivers/media/dvb/firewire/firedtv-ci.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/dvb/firewire/firedtv-ci.c 2009-10-01 20:12:43.000000000 -0400 +@@ -215,7 +215,7 @@ static unsigned int fdtv_ca_io_poll(stru + return POLLIN; + } + +-static struct file_operations fdtv_ca_fops = { ++static const struct file_operations fdtv_ca_fops = { + .owner = THIS_MODULE, + .ioctl = dvb_generic_ioctl, + .open = dvb_generic_open, +diff -urNp linux-2.6.31.1/drivers/media/video/cafe_ccic.c linux-2.6.31.1/drivers/media/video/cafe_ccic.c +--- linux-2.6.31.1/drivers/media/video/cafe_ccic.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/cafe_ccic.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1326,7 +1326,7 @@ static void cafe_v4l_vm_close(struct vm_ + mutex_unlock(&sbuf->cam->s_mutex); + } + +-static struct vm_operations_struct cafe_v4l_vm_ops = { ++static const struct vm_operations_struct cafe_v4l_vm_ops = { + .open = cafe_v4l_vm_open, + .close = cafe_v4l_vm_close + }; +diff -urNp linux-2.6.31.1/drivers/media/video/et61x251/et61x251_core.c linux-2.6.31.1/drivers/media/video/et61x251/et61x251_core.c +--- linux-2.6.31.1/drivers/media/video/et61x251/et61x251_core.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/et61x251/et61x251_core.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1494,7 +1494,7 @@ static void et61x251_vm_close(struct vm_ + } + + +-static struct vm_operations_struct et61x251_vm_ops = { ++static const struct vm_operations_struct et61x251_vm_ops = { + .open = et61x251_vm_open, + .close = et61x251_vm_close, + }; +diff -urNp linux-2.6.31.1/drivers/media/video/gspca/gspca.c linux-2.6.31.1/drivers/media/video/gspca/gspca.c +--- linux-2.6.31.1/drivers/media/video/gspca/gspca.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/gspca/gspca.c 2009-10-01 20:12:43.000000000 -0400 +@@ -99,7 +99,7 @@ static void gspca_vm_close(struct vm_are + frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED; + } + +-static struct vm_operations_struct gspca_vm_ops = { ++static const struct vm_operations_struct gspca_vm_ops = { + .open = gspca_vm_open, + .close = gspca_vm_close, + }; +diff -urNp linux-2.6.31.1/drivers/media/video/meye.c linux-2.6.31.1/drivers/media/video/meye.c +--- linux-2.6.31.1/drivers/media/video/meye.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/meye.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1589,7 +1589,7 @@ static void meye_vm_close(struct vm_area + meye.vma_use_count[idx]--; + } + +-static struct vm_operations_struct meye_vm_ops = { ++static const struct vm_operations_struct meye_vm_ops = { + .open = meye_vm_open, + .close = meye_vm_close, + }; +diff -urNp linux-2.6.31.1/drivers/media/video/sn9c102/sn9c102_core.c linux-2.6.31.1/drivers/media/video/sn9c102/sn9c102_core.c +--- linux-2.6.31.1/drivers/media/video/sn9c102/sn9c102_core.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/sn9c102/sn9c102_core.c 2009-10-01 20:12:43.000000000 -0400 +@@ -2075,7 +2075,7 @@ static void sn9c102_vm_close(struct vm_a + } + + +-static struct vm_operations_struct sn9c102_vm_ops = { ++static const struct vm_operations_struct sn9c102_vm_ops = { + .open = sn9c102_vm_open, + .close = sn9c102_vm_close, + }; +diff -urNp linux-2.6.31.1/drivers/media/video/stk-webcam.c linux-2.6.31.1/drivers/media/video/stk-webcam.c +--- linux-2.6.31.1/drivers/media/video/stk-webcam.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/stk-webcam.c 2009-10-01 20:12:43.000000000 -0400 +@@ -790,7 +790,7 @@ static void stk_v4l_vm_close(struct vm_a + if (sbuf->mapcount == 0) + sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_MAPPED; + } +-static struct vm_operations_struct stk_v4l_vm_ops = { ++static const struct vm_operations_struct stk_v4l_vm_ops = { + .open = stk_v4l_vm_open, + .close = stk_v4l_vm_close + }; +diff -urNp linux-2.6.31.1/drivers/media/video/usbvideo/konicawc.c linux-2.6.31.1/drivers/media/video/usbvideo/konicawc.c +--- linux-2.6.31.1/drivers/media/video/usbvideo/konicawc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/usbvideo/konicawc.c 2009-10-01 20:12:43.000000000 -0400 +@@ -225,7 +225,7 @@ static void konicawc_register_input(stru + int error; + + usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); +- strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); ++ strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname)); + + cam->input = input_dev = input_allocate_device(); + if (!input_dev) { +diff -urNp linux-2.6.31.1/drivers/media/video/usbvideo/quickcam_messenger.c linux-2.6.31.1/drivers/media/video/usbvideo/quickcam_messenger.c +--- linux-2.6.31.1/drivers/media/video/usbvideo/quickcam_messenger.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/usbvideo/quickcam_messenger.c 2009-10-01 20:12:43.000000000 -0400 +@@ -89,7 +89,7 @@ static void qcm_register_input(struct qc + int error; + + usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); +- strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); ++ strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname)); + + cam->input = input_dev = input_allocate_device(); + if (!input_dev) { +diff -urNp linux-2.6.31.1/drivers/media/video/uvc/uvc_v4l2.c linux-2.6.31.1/drivers/media/video/uvc/uvc_v4l2.c +--- linux-2.6.31.1/drivers/media/video/uvc/uvc_v4l2.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/uvc/uvc_v4l2.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1063,7 +1063,7 @@ static void uvc_vm_close(struct vm_area_ + buffer->vma_use_count--; + } + +-static struct vm_operations_struct uvc_vm_ops = { ++static const struct vm_operations_struct uvc_vm_ops = { + .open = uvc_vm_open, + .close = uvc_vm_close, + }; +diff -urNp linux-2.6.31.1/drivers/media/video/videobuf-dma-contig.c linux-2.6.31.1/drivers/media/video/videobuf-dma-contig.c +--- linux-2.6.31.1/drivers/media/video/videobuf-dma-contig.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/videobuf-dma-contig.c 2009-10-01 20:12:43.000000000 -0400 +@@ -105,7 +105,7 @@ static void videobuf_vm_close(struct vm_ + } + } + +-static struct vm_operations_struct videobuf_vm_ops = { ++static const struct vm_operations_struct videobuf_vm_ops = { + .open = videobuf_vm_open, + .close = videobuf_vm_close, + }; +diff -urNp linux-2.6.31.1/drivers/media/video/vino.c linux-2.6.31.1/drivers/media/video/vino.c +--- linux-2.6.31.1/drivers/media/video/vino.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/vino.c 2009-10-01 20:12:43.000000000 -0400 +@@ -3858,7 +3858,7 @@ static void vino_vm_close(struct vm_area + dprintk("vino_vm_close(): count = %d\n", fb->map_count); + } + +-static struct vm_operations_struct vino_vm_ops = { ++static const struct vm_operations_struct vino_vm_ops = { + .open = vino_vm_open, + .close = vino_vm_close, + }; +diff -urNp linux-2.6.31.1/drivers/media/video/zc0301/zc0301_core.c linux-2.6.31.1/drivers/media/video/zc0301/zc0301_core.c +--- linux-2.6.31.1/drivers/media/video/zc0301/zc0301_core.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/zc0301/zc0301_core.c 2009-10-01 20:12:43.000000000 -0400 +@@ -933,7 +933,7 @@ static void zc0301_vm_close(struct vm_ar + } + + +-static struct vm_operations_struct zc0301_vm_ops = { ++static const struct vm_operations_struct zc0301_vm_ops = { + .open = zc0301_vm_open, + .close = zc0301_vm_close, + }; +diff -urNp linux-2.6.31.1/drivers/media/video/zoran/zoran_driver.c linux-2.6.31.1/drivers/media/video/zoran/zoran_driver.c +--- linux-2.6.31.1/drivers/media/video/zoran/zoran_driver.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/media/video/zoran/zoran_driver.c 2009-10-01 20:12:43.000000000 -0400 +@@ -3172,7 +3172,7 @@ zoran_vm_close (struct vm_area_struct *v + mutex_unlock(&zr->resource_lock); + } + +-static struct vm_operations_struct zoran_vm_ops = { ++static const struct vm_operations_struct zoran_vm_ops = { + .open = zoran_vm_open, + .close = zoran_vm_close, + }; +diff -urNp linux-2.6.31.1/drivers/message/i2o/i2o_proc.c linux-2.6.31.1/drivers/message/i2o/i2o_proc.c +--- linux-2.6.31.1/drivers/message/i2o/i2o_proc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/message/i2o/i2o_proc.c 2009-10-01 20:12:43.000000000 -0400 +@@ -259,13 +259,6 @@ static char *scsi_devices[] = { + "Array Controller Device" + }; + +-static char *chtostr(u8 * chars, int n) +-{ +- char tmp[256]; +- tmp[0] = 0; +- return strncat(tmp, (char *)chars, n); +-} +- + static int i2o_report_query_status(struct seq_file *seq, int block_status, + char *group) + { +@@ -842,8 +835,7 @@ static int i2o_seq_show_ddm_table(struct + + seq_printf(seq, "%-#7x", ddm_table.i2o_vendor_id); + seq_printf(seq, "%-#8x", ddm_table.module_id); +- seq_printf(seq, "%-29s", +- chtostr(ddm_table.module_name_version, 28)); ++ seq_printf(seq, "%-.28s", ddm_table.module_name_version); + seq_printf(seq, "%9d ", ddm_table.data_size); + seq_printf(seq, "%8d", ddm_table.code_size); + +@@ -944,8 +936,8 @@ static int i2o_seq_show_drivers_stored(s + + seq_printf(seq, "%-#7x", dst->i2o_vendor_id); + seq_printf(seq, "%-#8x", dst->module_id); +- seq_printf(seq, "%-29s", chtostr(dst->module_name_version, 28)); +- seq_printf(seq, "%-9s", chtostr(dst->date, 8)); ++ seq_printf(seq, "%-.28s", dst->module_name_version); ++ seq_printf(seq, "%-.8s", dst->date); + seq_printf(seq, "%8d ", dst->module_size); + seq_printf(seq, "%8d ", dst->mpb_size); + seq_printf(seq, "0x%04x", dst->module_flags); +@@ -1276,14 +1268,10 @@ static int i2o_seq_show_dev_identity(str + seq_printf(seq, "Device Class : %s\n", i2o_get_class_name(work16[0])); + seq_printf(seq, "Owner TID : %0#5x\n", work16[2]); + seq_printf(seq, "Parent TID : %0#5x\n", work16[3]); +- seq_printf(seq, "Vendor info : %s\n", +- chtostr((u8 *) (work32 + 2), 16)); +- seq_printf(seq, "Product info : %s\n", +- chtostr((u8 *) (work32 + 6), 16)); +- seq_printf(seq, "Description : %s\n", +- chtostr((u8 *) (work32 + 10), 16)); +- seq_printf(seq, "Product rev. : %s\n", +- chtostr((u8 *) (work32 + 14), 8)); ++ seq_printf(seq, "Vendor info : %.16s\n", (u8 *) (work32 + 2)); ++ seq_printf(seq, "Product info : %.16s\n", (u8 *) (work32 + 6)); ++ seq_printf(seq, "Description : %.16s\n", (u8 *) (work32 + 10)); ++ seq_printf(seq, "Product rev. : %.8s\n", (u8 *) (work32 + 14)); + + seq_printf(seq, "Serial number : "); + print_serial_number(seq, (u8 *) (work32 + 16), +@@ -1328,10 +1316,8 @@ static int i2o_seq_show_ddm_identity(str + } + + seq_printf(seq, "Registering DDM TID : 0x%03x\n", result.ddm_tid); +- seq_printf(seq, "Module name : %s\n", +- chtostr(result.module_name, 24)); +- seq_printf(seq, "Module revision : %s\n", +- chtostr(result.module_rev, 8)); ++ seq_printf(seq, "Module name : %.24s\n", result.module_name); ++ seq_printf(seq, "Module revision : %.8s\n", result.module_rev); + + seq_printf(seq, "Serial number : "); + print_serial_number(seq, result.serial_number, sizeof(result) - 36); +@@ -1362,14 +1348,10 @@ static int i2o_seq_show_uinfo(struct seq + return 0; + } + +- seq_printf(seq, "Device name : %s\n", +- chtostr(result.device_name, 64)); +- seq_printf(seq, "Service name : %s\n", +- chtostr(result.service_name, 64)); +- seq_printf(seq, "Physical name : %s\n", +- chtostr(result.physical_location, 64)); +- seq_printf(seq, "Instance number : %s\n", +- chtostr(result.instance_number, 4)); ++ seq_printf(seq, "Device name : %.64s\n", result.device_name); ++ seq_printf(seq, "Service name : %.64s\n", result.service_name); ++ seq_printf(seq, "Physical name : %.64s\n", result.physical_location); ++ seq_printf(seq, "Instance number : %.4s\n", result.instance_number); + + return 0; + } +diff -urNp linux-2.6.31.1/drivers/misc/ibmasm/ibmasmfs.c linux-2.6.31.1/drivers/misc/ibmasm/ibmasmfs.c +--- linux-2.6.31.1/drivers/misc/ibmasm/ibmasmfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/misc/ibmasm/ibmasmfs.c 2009-10-01 20:12:43.000000000 -0400 +@@ -97,7 +97,7 @@ static int ibmasmfs_get_super(struct fil + return get_sb_single(fst, flags, data, ibmasmfs_fill_super, mnt); + } + +-static struct super_operations ibmasmfs_s_ops = { ++static const struct super_operations ibmasmfs_s_ops = { + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, + }; +diff -urNp linux-2.6.31.1/drivers/misc/phantom.c linux-2.6.31.1/drivers/misc/phantom.c +--- linux-2.6.31.1/drivers/misc/phantom.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/misc/phantom.c 2009-10-01 20:12:43.000000000 -0400 +@@ -271,7 +271,7 @@ static unsigned int phantom_poll(struct + return mask; + } + +-static struct file_operations phantom_file_ops = { ++static const struct file_operations phantom_file_ops = { + .open = phantom_open, + .release = phantom_release, + .unlocked_ioctl = phantom_ioctl, +diff -urNp linux-2.6.31.1/drivers/misc/sgi-gru/grufile.c linux-2.6.31.1/drivers/misc/sgi-gru/grufile.c +--- linux-2.6.31.1/drivers/misc/sgi-gru/grufile.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/misc/sgi-gru/grufile.c 2009-10-01 20:12:43.000000000 -0400 +@@ -53,7 +53,7 @@ struct gru_stats_s gru_stats; + /* Guaranteed user available resources on each node */ + static int max_user_cbrs, max_user_dsr_bytes; + +-static struct file_operations gru_fops; ++static const struct file_operations gru_fops; + static struct miscdevice gru_miscdev; + + +@@ -426,7 +426,7 @@ static void __exit gru_exit(void) + gru_proc_exit(); + } + +-static struct file_operations gru_fops = { ++static const struct file_operations gru_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = gru_file_unlocked_ioctl, + .mmap = gru_file_mmap, +@@ -438,7 +438,7 @@ static struct miscdevice gru_miscdev = { + .fops = &gru_fops, + }; + +-struct vm_operations_struct gru_vm_ops = { ++const struct vm_operations_struct gru_vm_ops = { + .close = gru_vma_close, + .fault = gru_fault, + }; +diff -urNp linux-2.6.31.1/drivers/misc/sgi-gru/grutables.h linux-2.6.31.1/drivers/misc/sgi-gru/grutables.h +--- linux-2.6.31.1/drivers/misc/sgi-gru/grutables.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/misc/sgi-gru/grutables.h 2009-10-01 20:12:43.000000000 -0400 +@@ -624,7 +624,7 @@ static inline int is_kernel_context(stru + */ + struct gru_unload_context_req; + +-extern struct vm_operations_struct gru_vm_ops; ++extern const struct vm_operations_struct gru_vm_ops; + extern struct device *grudev; + + extern struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma, +diff -urNp linux-2.6.31.1/drivers/mmc/core/debugfs.c linux-2.6.31.1/drivers/mmc/core/debugfs.c +--- linux-2.6.31.1/drivers/mmc/core/debugfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/mmc/core/debugfs.c 2009-10-01 20:12:43.000000000 -0400 +@@ -240,7 +240,7 @@ static int mmc_ext_csd_release(struct in + return 0; + } + +-static struct file_operations mmc_dbg_ext_csd_fops = { ++static const struct file_operations mmc_dbg_ext_csd_fops = { + .open = mmc_ext_csd_open, + .read = mmc_ext_csd_read, + .release = mmc_ext_csd_release, +diff -urNp linux-2.6.31.1/drivers/mtd/devices/doc2000.c linux-2.6.31.1/drivers/mtd/devices/doc2000.c +--- linux-2.6.31.1/drivers/mtd/devices/doc2000.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/mtd/devices/doc2000.c 2009-10-01 20:12:43.000000000 -0400 +@@ -776,7 +776,7 @@ static int doc_write(struct mtd_info *mt + + /* The ECC will not be calculated correctly if less than 512 is written */ + /* DBB- +- if (len != 0x200 && eccbuf) ++ if (len != 0x200) + printk(KERN_WARNING + "ECC needs a full sector write (adr: %lx size %lx)\n", + (long) to, (long) len); +diff -urNp linux-2.6.31.1/drivers/mtd/devices/doc2001.c linux-2.6.31.1/drivers/mtd/devices/doc2001.c +--- linux-2.6.31.1/drivers/mtd/devices/doc2001.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/mtd/devices/doc2001.c 2009-10-01 20:12:43.000000000 -0400 +@@ -395,6 +395,8 @@ static int doc_read (struct mtd_info *mt + /* Don't allow read past end of device */ + if (from >= this->totlen) + return -EINVAL; ++ if (!len) ++ return -EINVAL; + + /* Don't allow a single read to cross a 512-byte block boundary */ + if (from + len > ((from | 0x1ff) + 1)) +diff -urNp linux-2.6.31.1/drivers/mtd/ubi/build.c linux-2.6.31.1/drivers/mtd/ubi/build.c +--- linux-2.6.31.1/drivers/mtd/ubi/build.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/mtd/ubi/build.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1257,7 +1257,7 @@ static int __init bytes_str_to_int(const + unsigned long result; + + result = simple_strtoul(str, &endp, 0); +- if (str == endp || result < 0) { ++ if (str == endp) { + printk(KERN_ERR "UBI error: incorrect bytes count: "%s"\n", + str); + return -EINVAL; +diff -urNp linux-2.6.31.1/drivers/net/irda/vlsi_ir.c linux-2.6.31.1/drivers/net/irda/vlsi_ir.c +--- linux-2.6.31.1/drivers/net/irda/vlsi_ir.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/net/irda/vlsi_ir.c 2009-10-01 20:12:43.000000000 -0400 +@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s + /* no race - tx-ring already empty */ + vlsi_set_baud(idev, iobase); + netif_wake_queue(ndev); +- } +- else +- ; ++ } else { + /* keep the speed change pending like it would + * for any len>0 packet. tx completion interrupt + * will apply it when the tx ring becomes empty. + */ ++ } + spin_unlock_irqrestore(&idev->lock, flags); + dev_kfree_skb_any(skb); + return 0; +diff -urNp linux-2.6.31.1/drivers/net/pcnet32.c linux-2.6.31.1/drivers/net/pcnet32.c +--- linux-2.6.31.1/drivers/net/pcnet32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/net/pcnet32.c 2009-10-01 20:12:43.000000000 -0400 +@@ -78,7 +78,7 @@ static int cards_found; + /* + * VLB I/O addresses + */ +-static unsigned int pcnet32_portlist[] __initdata = ++static unsigned int pcnet32_portlist[] __devinitdata = + { 0x300, 0x320, 0x340, 0x360, 0 }; + + static int pcnet32_debug = 0; +diff -urNp linux-2.6.31.1/drivers/net/tg3.h linux-2.6.31.1/drivers/net/tg3.h +--- linux-2.6.31.1/drivers/net/tg3.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/net/tg3.h 2009-10-01 20:12:43.000000000 -0400 +@@ -89,6 +89,7 @@ + #define CHIPREV_ID_5750_A0 0x4000 + #define CHIPREV_ID_5750_A1 0x4001 + #define CHIPREV_ID_5750_A3 0x4003 ++#define CHIPREV_ID_5750_C1 0x4201 + #define CHIPREV_ID_5750_C2 0x4202 + #define CHIPREV_ID_5752_A0_HW 0x5000 + #define CHIPREV_ID_5752_A0 0x6000 +diff -urNp linux-2.6.31.1/drivers/net/usb/hso.c linux-2.6.31.1/drivers/net/usb/hso.c +--- linux-2.6.31.1/drivers/net/usb/hso.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/net/usb/hso.c 2009-10-01 20:12:43.000000000 -0400 +@@ -258,7 +258,7 @@ struct hso_serial { + + /* from usb_serial_port */ + struct tty_struct *tty; +- int open_count; ++ atomic_t open_count; + spinlock_t serial_lock; + + int (*write_data) (struct hso_serial *serial); +@@ -1179,7 +1179,7 @@ static void put_rxbuf_data_and_resubmit_ + struct urb *urb; + + urb = serial->rx_urb[0]; +- if (serial->open_count > 0) { ++ if (atomic_read(&serial->open_count) > 0) { + count = put_rxbuf_data(urb, serial); + if (count == -1) + return; +@@ -1215,7 +1215,7 @@ static void hso_std_serial_read_bulk_cal + DUMP1(urb->transfer_buffer, urb->actual_length); + + /* Anyone listening? */ +- if (serial->open_count == 0) ++ if (atomic_read(&serial->open_count) == 0) + return; + + if (status == 0) { +@@ -1310,8 +1310,7 @@ static int hso_serial_open(struct tty_st + spin_unlock_irq(&serial->serial_lock); + + /* check for port already opened, if not set the termios */ +- serial->open_count++; +- if (serial->open_count == 1) { ++ if (atomic_inc_return(&serial->open_count) == 1) { + tty->low_latency = 1; + serial->rx_state = RX_IDLE; + /* Force default termio settings */ +@@ -1324,7 +1323,7 @@ static int hso_serial_open(struct tty_st + result = hso_start_serial_device(serial->parent, GFP_KERNEL); + if (result) { + hso_stop_serial_device(serial->parent); +- serial->open_count--; ++ atomic_dec(&serial->open_count); + kref_put(&serial->parent->ref, hso_serial_ref_free); + } + } else { +@@ -1361,10 +1360,10 @@ static void hso_serial_close(struct tty_ + + /* reset the rts and dtr */ + /* do the actual close */ +- serial->open_count--; ++ atomic_dec(&serial->open_count); + kref_put(&serial->parent->ref, hso_serial_ref_free); +- if (serial->open_count <= 0) { +- serial->open_count = 0; ++ if (atomic_read(&serial->open_count) <= 0) { ++ atomic_set(&serial->open_count, 0); + spin_lock_irq(&serial->serial_lock); + if (serial->tty == tty) { + serial->tty->driver_data = NULL; +@@ -1444,7 +1443,7 @@ static void hso_serial_set_termios(struc + + /* the actual setup */ + spin_lock_irqsave(&serial->serial_lock, flags); +- if (serial->open_count) ++ if (atomic_read(&serial->open_count)) + _hso_serial_set_termios(tty, old); + else + tty->termios = old; +@@ -3087,7 +3086,7 @@ static int hso_resume(struct usb_interfa + /* Start all serial ports */ + for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { + if (serial_table[i] && (serial_table[i]->interface == iface)) { +- if (dev2ser(serial_table[i])->open_count) { ++ if (atomic_read(&dev2ser(serial_table[i])->open_count)) { + result = + hso_start_serial_device(serial_table[i], GFP_NOIO); + hso_kick_transmit(dev2ser(serial_table[i])); +diff -urNp linux-2.6.31.1/drivers/oprofile/buffer_sync.c linux-2.6.31.1/drivers/oprofile/buffer_sync.c +--- linux-2.6.31.1/drivers/oprofile/buffer_sync.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/oprofile/buffer_sync.c 2009-10-01 20:12:43.000000000 -0400 +@@ -341,7 +341,7 @@ static void add_data(struct op_entry *en + if (cookie == NO_COOKIE) + offset = pc; + if (cookie == INVALID_COOKIE) { +- atomic_inc(&oprofile_stats.sample_lost_no_mapping); ++ atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping); + offset = pc; + } + if (cookie != last_cookie) { +@@ -385,14 +385,14 @@ add_sample(struct mm_struct *mm, struct + /* add userspace sample */ + + if (!mm) { +- atomic_inc(&oprofile_stats.sample_lost_no_mm); ++ atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mm); + return 0; + } + + cookie = lookup_dcookie(mm, s->eip, &offset); + + if (cookie == INVALID_COOKIE) { +- atomic_inc(&oprofile_stats.sample_lost_no_mapping); ++ atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping); + return 0; + } + +@@ -561,7 +561,7 @@ void sync_buffer(int cpu) + /* ignore backtraces if failed to add a sample */ + if (state == sb_bt_start) { + state = sb_bt_ignore; +- atomic_inc(&oprofile_stats.bt_lost_no_mapping); ++ atomic_inc_unchecked(&oprofile_stats.bt_lost_no_mapping); + } + } + release_mm(mm); +diff -urNp linux-2.6.31.1/drivers/oprofile/event_buffer.c linux-2.6.31.1/drivers/oprofile/event_buffer.c +--- linux-2.6.31.1/drivers/oprofile/event_buffer.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/oprofile/event_buffer.c 2009-10-01 20:12:43.000000000 -0400 +@@ -42,7 +42,7 @@ static atomic_t buffer_ready = ATOMIC_IN + void add_event_entry(unsigned long value) + { + if (buffer_pos == buffer_size) { +- atomic_inc(&oprofile_stats.event_lost_overflow); ++ atomic_inc_unchecked(&oprofile_stats.event_lost_overflow); + return; + } + +diff -urNp linux-2.6.31.1/drivers/oprofile/oprofilefs.c linux-2.6.31.1/drivers/oprofile/oprofilefs.c +--- linux-2.6.31.1/drivers/oprofile/oprofilefs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/oprofile/oprofilefs.c 2009-10-01 20:12:43.000000000 -0400 +@@ -35,7 +35,7 @@ static struct inode *oprofilefs_get_inod + } + + +-static struct super_operations s_ops = { ++static const struct super_operations s_ops = { + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, + }; +@@ -187,7 +187,7 @@ static const struct file_operations atom + + + int oprofilefs_create_ro_atomic(struct super_block *sb, struct dentry *root, +- char const *name, atomic_t *val) ++ char const *name, atomic_unchecked_t *val) + { + struct dentry *d = __oprofilefs_create_file(sb, root, name, + &atomic_ro_fops, 0444); +diff -urNp linux-2.6.31.1/drivers/oprofile/oprofile_stats.c linux-2.6.31.1/drivers/oprofile/oprofile_stats.c +--- linux-2.6.31.1/drivers/oprofile/oprofile_stats.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/oprofile/oprofile_stats.c 2009-10-01 20:12:43.000000000 -0400 +@@ -30,10 +30,10 @@ void oprofile_reset_stats(void) + cpu_buf->sample_invalid_eip = 0; + } + +- atomic_set(&oprofile_stats.sample_lost_no_mm, 0); +- atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); +- atomic_set(&oprofile_stats.event_lost_overflow, 0); +- atomic_set(&oprofile_stats.bt_lost_no_mapping, 0); ++ atomic_set_unchecked(&oprofile_stats.sample_lost_no_mm, 0); ++ atomic_set_unchecked(&oprofile_stats.sample_lost_no_mapping, 0); ++ atomic_set_unchecked(&oprofile_stats.event_lost_overflow, 0); ++ atomic_set_unchecked(&oprofile_stats.bt_lost_no_mapping, 0); + } + + +diff -urNp linux-2.6.31.1/drivers/oprofile/oprofile_stats.h linux-2.6.31.1/drivers/oprofile/oprofile_stats.h +--- linux-2.6.31.1/drivers/oprofile/oprofile_stats.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/oprofile/oprofile_stats.h 2009-10-01 20:12:43.000000000 -0400 +@@ -13,10 +13,10 @@ + #include <asm/atomic.h> + + struct oprofile_stat_struct { +- atomic_t sample_lost_no_mm; +- atomic_t sample_lost_no_mapping; +- atomic_t bt_lost_no_mapping; +- atomic_t event_lost_overflow; ++ atomic_unchecked_t sample_lost_no_mm; ++ atomic_unchecked_t sample_lost_no_mapping; ++ atomic_unchecked_t bt_lost_no_mapping; ++ atomic_unchecked_t event_lost_overflow; + }; + + extern struct oprofile_stat_struct oprofile_stats; +diff -urNp linux-2.6.31.1/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.31.1/drivers/pci/hotplug/cpqphp_nvram.c +--- linux-2.6.31.1/drivers/pci/hotplug/cpqphp_nvram.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/pci/hotplug/cpqphp_nvram.c 2009-10-01 20:12:43.000000000 -0400 +@@ -428,9 +428,13 @@ static u32 store_HRT (void __iomem *rom_ + + void compaq_nvram_init (void __iomem *rom_start) + { ++ ++#ifndef CONFIG_PAX_KERNEXEC + if (rom_start) { + compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR); + } ++#endif ++ + dbg("int15 entry = %p\n", compaq_int15_entry_point); + + /* initialize our int15 lock */ +diff -urNp linux-2.6.31.1/drivers/pci/pcie/portdrv_pci.c linux-2.6.31.1/drivers/pci/pcie/portdrv_pci.c +--- linux-2.6.31.1/drivers/pci/pcie/portdrv_pci.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/pci/pcie/portdrv_pci.c 2009-10-01 20:12:43.000000000 -0400 +@@ -249,7 +249,7 @@ static void pcie_portdrv_err_resume(stru + static const struct pci_device_id port_pci_ids[] = { { + /* handle any PCI-Express port */ + PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0), +- }, { /* end: all zeroes */ } ++ }, { 0, 0, 0, 0, 0, 0, 0 } + }; + MODULE_DEVICE_TABLE(pci, port_pci_ids); + +diff -urNp linux-2.6.31.1/drivers/pci/proc.c linux-2.6.31.1/drivers/pci/proc.c +--- linux-2.6.31.1/drivers/pci/proc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/pci/proc.c 2009-10-01 20:12:43.000000000 -0400 +@@ -480,7 +480,16 @@ static const struct file_operations proc + static int __init pci_proc_init(void) + { + struct pci_dev *dev = NULL; ++ ++#ifdef CONFIG_GRKERNSEC_PROC_ADD ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL); ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL); ++#endif ++#else + proc_bus_pci_dir = proc_mkdir("bus/pci", NULL); ++#endif + proc_create("devices", 0, proc_bus_pci_dir, + &proc_bus_pci_dev_operations); + proc_initialized = 1; +diff -urNp linux-2.6.31.1/drivers/pcmcia/ti113x.h linux-2.6.31.1/drivers/pcmcia/ti113x.h +--- linux-2.6.31.1/drivers/pcmcia/ti113x.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/pcmcia/ti113x.h 2009-10-01 20:12:43.000000000 -0400 +@@ -903,7 +903,7 @@ static struct pci_device_id ene_tune_tbl + DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID, + ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE), + +- {} ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus) +diff -urNp linux-2.6.31.1/drivers/pcmcia/yenta_socket.c linux-2.6.31.1/drivers/pcmcia/yenta_socket.c +--- linux-2.6.31.1/drivers/pcmcia/yenta_socket.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/pcmcia/yenta_socket.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1366,7 +1366,7 @@ static struct pci_device_id yenta_table + + /* match any cardbus bridge */ + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), +- { /* all zeroes */ } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + MODULE_DEVICE_TABLE(pci, yenta_table); + +diff -urNp linux-2.6.31.1/drivers/pnp/pnpbios/bioscalls.c linux-2.6.31.1/drivers/pnp/pnpbios/bioscalls.c +--- linux-2.6.31.1/drivers/pnp/pnpbios/bioscalls.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/pnp/pnpbios/bioscalls.c 2009-10-01 20:12:43.000000000 -0400 +@@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr + set_limit(gdt[(selname) >> 3], size); \ + } while(0) + +-static struct desc_struct bad_bios_desc; ++static struct desc_struct bad_bios_desc __read_only; + + /* + * At some point we want to use this stack frame pointer to unwind +@@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func + struct desc_struct save_desc_40; + int cpu; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + /* + * PnP BIOSes are generally not terribly re-entrant. + * Also, don't rely on them to save everything correctly. +@@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func + + cpu = get_cpu(); + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8]; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc; + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + /* On some boxes IRQ's during PnP BIOS calls are deadly. */ + spin_lock_irqsave(&pnp_bios_lock, flags); + +@@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func + :"memory"); + spin_unlock_irqrestore(&pnp_bios_lock, flags); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + put_cpu(); + + /* If we get here and this is set then the PnP BIOS faulted on us. */ +@@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n + return status; + } + +-void pnpbios_calls_init(union pnp_bios_install_struct *header) ++void __init pnpbios_calls_init(union pnp_bios_install_struct *header) + { + int i; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + spin_lock_init(&pnp_bios_lock); + pnp_bios_callpoint.offset = header->fields.pm16offset; + pnp_bios_callpoint.segment = PNP_CS16; + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + bad_bios_desc.a = 0; +- bad_bios_desc.b = 0x00409200; ++ bad_bios_desc.b = 0x00409300; + + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); +@@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i + set_base(gdt[GDT_ENTRY_PNPBIOS_DS], + __va(header->fields.pm16dseg)); + } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + } +diff -urNp linux-2.6.31.1/drivers/pnp/quirks.c linux-2.6.31.1/drivers/pnp/quirks.c +--- linux-2.6.31.1/drivers/pnp/quirks.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/pnp/quirks.c 2009-10-01 20:12:43.000000000 -0400 +@@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = { + /* PnP resources that might overlap PCI BARs */ + {"PNP0c01", quirk_system_pci_resources}, + {"PNP0c02", quirk_system_pci_resources}, +- {""} ++ {"", NULL} + }; + + void pnp_fixup_device(struct pnp_dev *dev) +diff -urNp linux-2.6.31.1/drivers/pnp/resource.c linux-2.6.31.1/drivers/pnp/resource.c +--- linux-2.6.31.1/drivers/pnp/resource.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/pnp/resource.c 2009-10-01 20:12:43.000000000 -0400 +@@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s + return 1; + + /* check if the resource is valid */ +- if (*irq < 0 || *irq > 15) ++ if (*irq > 15) + return 0; + + /* check if the resource is reserved */ +@@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s + return 1; + + /* check if the resource is valid */ +- if (*dma < 0 || *dma == 4 || *dma > 7) ++ if (*dma == 4 || *dma > 7) + return 0; + + /* check if the resource is reserved */ +diff -urNp linux-2.6.31.1/drivers/s390/cio/qdio_debug.c linux-2.6.31.1/drivers/s390/cio/qdio_debug.c +--- linux-2.6.31.1/drivers/s390/cio/qdio_debug.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/s390/cio/qdio_debug.c 2009-10-01 20:12:43.000000000 -0400 +@@ -144,7 +144,7 @@ static void remove_debugfs_entry(struct + } + } + +-static struct file_operations debugfs_fops = { ++static const struct file_operations debugfs_fops = { + .owner = THIS_MODULE, + .open = qstat_seq_open, + .read = seq_read, +diff -urNp linux-2.6.31.1/drivers/s390/cio/qdio_perf.c linux-2.6.31.1/drivers/s390/cio/qdio_perf.c +--- linux-2.6.31.1/drivers/s390/cio/qdio_perf.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/s390/cio/qdio_perf.c 2009-10-01 20:12:43.000000000 -0400 +@@ -84,7 +84,7 @@ static int qdio_perf_seq_open(struct ino + return single_open(filp, qdio_perf_proc_show, NULL); + } + +-static struct file_operations qdio_perf_proc_fops = { ++static const struct file_operations qdio_perf_proc_fops = { + .owner = THIS_MODULE, + .open = qdio_perf_seq_open, + .read = seq_read, +diff -urNp linux-2.6.31.1/drivers/scsi/libfc/fc_exch.c linux-2.6.31.1/drivers/scsi/libfc/fc_exch.c +--- linux-2.6.31.1/drivers/scsi/libfc/fc_exch.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/scsi/libfc/fc_exch.c 2009-10-01 20:12:43.000000000 -0400 +@@ -73,12 +73,12 @@ struct fc_exch_mgr { + * all together if not used XXX + */ + struct { +- atomic_t no_free_exch; +- atomic_t no_free_exch_xid; +- atomic_t xid_not_found; +- atomic_t xid_busy; +- atomic_t seq_not_found; +- atomic_t non_bls_resp; ++ atomic_unchecked_t no_free_exch; ++ atomic_unchecked_t no_free_exch_xid; ++ atomic_unchecked_t xid_not_found; ++ atomic_unchecked_t xid_busy; ++ atomic_unchecked_t seq_not_found; ++ atomic_unchecked_t non_bls_resp; + } stats; + struct fc_exch **exches; /* for exch pointers indexed by xid */ + }; +@@ -523,7 +523,7 @@ struct fc_exch *fc_exch_alloc(struct fc_ + /* allocate memory for exchange */ + ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC); + if (!ep) { +- atomic_inc(&mp->stats.no_free_exch); ++ atomic_inc_unchecked(&mp->stats.no_free_exch); + goto out; + } + memset(ep, 0, sizeof(*ep)); +@@ -568,7 +568,7 @@ out: + return ep; + err: + spin_unlock_bh(&mp->em_lock); +- atomic_inc(&mp->stats.no_free_exch_xid); ++ atomic_inc_unchecked(&mp->stats.no_free_exch_xid); + mempool_free(ep, mp->ep_pool); + return NULL; + } +@@ -671,7 +671,7 @@ static enum fc_pf_rjt_reason fc_seq_look + xid = ntohs(fh->fh_ox_id); /* we originated exch */ + ep = fc_exch_find(mp, xid); + if (!ep) { +- atomic_inc(&mp->stats.xid_not_found); ++ atomic_inc_unchecked(&mp->stats.xid_not_found); + reject = FC_RJT_OX_ID; + goto out; + } +@@ -701,7 +701,7 @@ static enum fc_pf_rjt_reason fc_seq_look + ep = fc_exch_find(mp, xid); + if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) { + if (ep) { +- atomic_inc(&mp->stats.xid_busy); ++ atomic_inc_unchecked(&mp->stats.xid_busy); + reject = FC_RJT_RX_ID; + goto rel; + } +@@ -712,7 +712,7 @@ static enum fc_pf_rjt_reason fc_seq_look + } + xid = ep->xid; /* get our XID */ + } else if (!ep) { +- atomic_inc(&mp->stats.xid_not_found); ++ atomic_inc_unchecked(&mp->stats.xid_not_found); + reject = FC_RJT_RX_ID; /* XID not found */ + goto out; + } +@@ -733,7 +733,7 @@ static enum fc_pf_rjt_reason fc_seq_look + } else { + sp = &ep->seq; + if (sp->id != fh->fh_seq_id) { +- atomic_inc(&mp->stats.seq_not_found); ++ atomic_inc_unchecked(&mp->stats.seq_not_found); + reject = FC_RJT_SEQ_ID; /* sequence/exch should exist */ + goto rel; + } +@@ -1145,22 +1145,22 @@ static void fc_exch_recv_seq_resp(struct + + ep = fc_exch_find(mp, ntohs(fh->fh_ox_id)); + if (!ep) { +- atomic_inc(&mp->stats.xid_not_found); ++ atomic_inc_unchecked(&mp->stats.xid_not_found); + goto out; + } + if (ep->esb_stat & ESB_ST_COMPLETE) { +- atomic_inc(&mp->stats.xid_not_found); ++ atomic_inc_unchecked(&mp->stats.xid_not_found); + goto out; + } + if (ep->rxid == FC_XID_UNKNOWN) + ep->rxid = ntohs(fh->fh_rx_id); + if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) { +- atomic_inc(&mp->stats.xid_not_found); ++ atomic_inc_unchecked(&mp->stats.xid_not_found); + goto rel; + } + if (ep->did != ntoh24(fh->fh_s_id) && + ep->did != FC_FID_FLOGI) { +- atomic_inc(&mp->stats.xid_not_found); ++ atomic_inc_unchecked(&mp->stats.xid_not_found); + goto rel; + } + sof = fr_sof(fp); +@@ -1171,7 +1171,7 @@ static void fc_exch_recv_seq_resp(struct + } else { + sp = &ep->seq; + if (sp->id != fh->fh_seq_id) { +- atomic_inc(&mp->stats.seq_not_found); ++ atomic_inc_unchecked(&mp->stats.seq_not_found); + goto rel; + } + } +@@ -1230,10 +1230,10 @@ static void fc_exch_recv_resp(struct fc_ + + sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */ + if (!sp) { +- atomic_inc(&mp->stats.xid_not_found); ++ atomic_inc_unchecked(&mp->stats.xid_not_found); + FC_EM_DBG(mp, "seq lookup failed\n"); + } else { +- atomic_inc(&mp->stats.non_bls_resp); ++ atomic_inc_unchecked(&mp->stats.non_bls_resp); + FC_EM_DBG(mp, "non-BLS response to sequence"); + } + fc_frame_free(fp); +diff -urNp linux-2.6.31.1/drivers/scsi/scsi_logging.h linux-2.6.31.1/drivers/scsi/scsi_logging.h +--- linux-2.6.31.1/drivers/scsi/scsi_logging.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/scsi/scsi_logging.h 2009-10-01 20:12:43.000000000 -0400 +@@ -51,7 +51,7 @@ do { \ + } while (0); \ + } while (0) + #else +-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) ++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0) + #endif /* CONFIG_SCSI_LOGGING */ + + /* +diff -urNp linux-2.6.31.1/drivers/scsi/sg.c linux-2.6.31.1/drivers/scsi/sg.c +--- linux-2.6.31.1/drivers/scsi/sg.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/scsi/sg.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1185,7 +1185,7 @@ sg_vma_fault(struct vm_area_struct *vma, + return VM_FAULT_SIGBUS; + } + +-static struct vm_operations_struct sg_mmap_vm_ops = { ++static const struct vm_operations_struct sg_mmap_vm_ops = { + .fault = sg_vma_fault, + }; + +@@ -1317,7 +1317,7 @@ static void sg_rq_end_io(struct request + } + } + +-static struct file_operations sg_fops = { ++static const struct file_operations sg_fops = { + .owner = THIS_MODULE, + .read = sg_read, + .write = sg_write, +@@ -2194,8 +2194,11 @@ static int sg_proc_seq_show_int(struct s + static int sg_proc_single_open_adio(struct inode *inode, struct file *file); + static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer, + size_t count, loff_t *off); +-static struct file_operations adio_fops = { +- /* .owner, .read and .llseek added in sg_proc_init() */ ++ ++static const struct file_operations adio_fops = { ++ .owner = THIS_MODULE, ++ .read = seq_read, ++ .llseek = seq_lseek, + .open = sg_proc_single_open_adio, + .write = sg_proc_write_adio, + .release = single_release, +@@ -2204,7 +2207,10 @@ static struct file_operations adio_fops + static int sg_proc_single_open_dressz(struct inode *inode, struct file *file); + static ssize_t sg_proc_write_dressz(struct file *filp, + const char __user *buffer, size_t count, loff_t *off); +-static struct file_operations dressz_fops = { ++static const struct file_operations dressz_fops = { ++ .owner = THIS_MODULE, ++ .read = seq_read, ++ .llseek = seq_lseek, + .open = sg_proc_single_open_dressz, + .write = sg_proc_write_dressz, + .release = single_release, +@@ -2212,14 +2218,20 @@ static struct file_operations dressz_fop + + static int sg_proc_seq_show_version(struct seq_file *s, void *v); + static int sg_proc_single_open_version(struct inode *inode, struct file *file); +-static struct file_operations version_fops = { ++static const struct file_operations version_fops = { ++ .owner = THIS_MODULE, ++ .read = seq_read, ++ .llseek = seq_lseek, + .open = sg_proc_single_open_version, + .release = single_release, + }; + + static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v); + static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file); +-static struct file_operations devhdr_fops = { ++static const struct file_operations devhdr_fops = { ++ .owner = THIS_MODULE, ++ .read = seq_read, ++ .llseek = seq_lseek, + .open = sg_proc_single_open_devhdr, + .release = single_release, + }; +@@ -2229,11 +2241,14 @@ static int sg_proc_open_dev(struct inode + static void * dev_seq_start(struct seq_file *s, loff_t *pos); + static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos); + static void dev_seq_stop(struct seq_file *s, void *v); +-static struct file_operations dev_fops = { ++static const struct file_operations dev_fops = { ++ .owner = THIS_MODULE, ++ .read = seq_read, ++ .llseek = seq_lseek, + .open = sg_proc_open_dev, + .release = seq_release, + }; +-static struct seq_operations dev_seq_ops = { ++static const struct seq_operations dev_seq_ops = { + .start = dev_seq_start, + .next = dev_seq_next, + .stop = dev_seq_stop, +@@ -2242,11 +2257,14 @@ static struct seq_operations dev_seq_ops + + static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v); + static int sg_proc_open_devstrs(struct inode *inode, struct file *file); +-static struct file_operations devstrs_fops = { ++static const struct file_operations devstrs_fops = { ++ .owner = THIS_MODULE, ++ .read = seq_read, ++ .llseek = seq_lseek, + .open = sg_proc_open_devstrs, + .release = seq_release, + }; +-static struct seq_operations devstrs_seq_ops = { ++static const struct seq_operations devstrs_seq_ops = { + .start = dev_seq_start, + .next = dev_seq_next, + .stop = dev_seq_stop, +@@ -2255,11 +2273,14 @@ static struct seq_operations devstrs_seq + + static int sg_proc_seq_show_debug(struct seq_file *s, void *v); + static int sg_proc_open_debug(struct inode *inode, struct file *file); +-static struct file_operations debug_fops = { ++static const struct file_operations debug_fops = { ++ .owner = THIS_MODULE, ++ .read = seq_read, ++ .llseek = seq_lseek, + .open = sg_proc_open_debug, + .release = seq_release, + }; +-static struct seq_operations debug_seq_ops = { ++static const struct seq_operations debug_seq_ops = { + .start = dev_seq_start, + .next = dev_seq_next, + .stop = dev_seq_stop, +@@ -2269,7 +2290,7 @@ static struct seq_operations debug_seq_o + + struct sg_proc_leaf { + const char * name; +- struct file_operations * fops; ++ const struct file_operations * fops; + }; + + static struct sg_proc_leaf sg_proc_leaf_arr[] = { +@@ -2295,9 +2316,6 @@ sg_proc_init(void) + for (k = 0; k < num_leaves; ++k) { + leaf = &sg_proc_leaf_arr[k]; + mask = leaf->fops->write ? S_IRUGO | S_IWUSR : S_IRUGO; +- leaf->fops->owner = THIS_MODULE; +- leaf->fops->read = seq_read; +- leaf->fops->llseek = seq_lseek; + proc_create(leaf->name, mask, sg_proc_sgp, leaf->fops); + } + return 0; +diff -urNp linux-2.6.31.1/drivers/serial/8250_pci.c linux-2.6.31.1/drivers/serial/8250_pci.c +--- linux-2.6.31.1/drivers/serial/8250_pci.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/serial/8250_pci.c 2009-10-01 20:12:43.000000000 -0400 +@@ -3580,7 +3580,7 @@ static struct pci_device_id serial_pci_t + PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, + 0xffff00, pbn_default }, +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + static struct pci_driver serial_pci_driver = { +diff -urNp linux-2.6.31.1/drivers/spi/spidev.c linux-2.6.31.1/drivers/spi/spidev.c +--- linux-2.6.31.1/drivers/spi/spidev.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/spi/spidev.c 2009-10-01 20:12:43.000000000 -0400 +@@ -537,7 +537,7 @@ static int spidev_release(struct inode * + return status; + } + +-static struct file_operations spidev_fops = { ++static const struct file_operations spidev_fops = { + .owner = THIS_MODULE, + /* REVISIT switch to aio primitives, so that userspace + * gets more complete API coverage. It'll simplify things +diff -urNp linux-2.6.31.1/drivers/staging/android/binder.c linux-2.6.31.1/drivers/staging/android/binder.c +--- linux-2.6.31.1/drivers/staging/android/binder.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/staging/android/binder.c 2009-10-01 20:12:43.000000000 -0400 +@@ -2717,7 +2717,7 @@ static void binder_vma_close(struct vm_a + binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); + } + +-static struct vm_operations_struct binder_vm_ops = { ++static const struct vm_operations_struct binder_vm_ops = { + .open = binder_vma_open, + .close = binder_vma_close, + }; +diff -urNp linux-2.6.31.1/drivers/staging/b3dfg/b3dfg.c linux-2.6.31.1/drivers/staging/b3dfg/b3dfg.c +--- linux-2.6.31.1/drivers/staging/b3dfg/b3dfg.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/staging/b3dfg/b3dfg.c 2009-10-01 20:12:43.000000000 -0400 +@@ -454,7 +454,7 @@ static int b3dfg_vma_fault(struct vm_are + return VM_FAULT_NOPAGE; + } + +-static struct vm_operations_struct b3dfg_vm_ops = { ++static const struct vm_operations_struct b3dfg_vm_ops = { + .fault = b3dfg_vma_fault, + }; + +@@ -854,7 +854,7 @@ static int b3dfg_mmap(struct file *filp, + return r; + } + +-static struct file_operations b3dfg_fops = { ++static const struct file_operations b3dfg_fops = { + .owner = THIS_MODULE, + .open = b3dfg_open, + .release = b3dfg_release, +diff -urNp linux-2.6.31.1/drivers/staging/comedi/comedi_fops.c linux-2.6.31.1/drivers/staging/comedi/comedi_fops.c +--- linux-2.6.31.1/drivers/staging/comedi/comedi_fops.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/staging/comedi/comedi_fops.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1370,7 +1370,7 @@ void comedi_unmap(struct vm_area_struct + mutex_unlock(&dev->mutex); + } + +-static struct vm_operations_struct comedi_vm_ops = { ++static const struct vm_operations_struct comedi_vm_ops = { + .close = comedi_unmap, + }; + +diff -urNp linux-2.6.31.1/drivers/staging/cpc-usb/cpc-usb_drv.c linux-2.6.31.1/drivers/staging/cpc-usb/cpc-usb_drv.c +--- linux-2.6.31.1/drivers/staging/cpc-usb/cpc-usb_drv.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/staging/cpc-usb/cpc-usb_drv.c 2009-10-01 20:12:43.000000000 -0400 +@@ -104,7 +104,7 @@ static void cpcusb_read_interrupt_callba + + static int cpcusb_setup_intrep(CPC_USB_T *card); + +-static struct file_operations cpcusb_fops = { ++static const struct file_operations cpcusb_fops = { + /* + * The owner field is part of the module-locking + * mechanism. The idea is that the kernel knows +diff -urNp linux-2.6.31.1/drivers/staging/epl/EplApiLinuxKernel.c linux-2.6.31.1/drivers/staging/epl/EplApiLinuxKernel.c +--- linux-2.6.31.1/drivers/staging/epl/EplApiLinuxKernel.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/staging/epl/EplApiLinuxKernel.c 2009-10-01 20:12:43.000000000 -0400 +@@ -203,7 +203,7 @@ static int EplLinIoctl(struct inode *pDe + module_init(EplLinInit); + module_exit(EplLinExit); + +-static struct file_operations EplLinFileOps_g = { ++static const struct file_operations EplLinFileOps_g = { + .owner = THIS_MODULE, + .open = EplLinOpen, + .release = EplLinRelease, +diff -urNp linux-2.6.31.1/drivers/staging/go7007/go7007-v4l2.c linux-2.6.31.1/drivers/staging/go7007/go7007-v4l2.c +--- linux-2.6.31.1/drivers/staging/go7007/go7007-v4l2.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/staging/go7007/go7007-v4l2.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1717,7 +1717,7 @@ static int go7007_vm_fault(struct vm_are + return 0; + } + +-static struct vm_operations_struct go7007_vm_ops = { ++static const struct vm_operations_struct go7007_vm_ops = { + .open = go7007_vm_open, + .close = go7007_vm_close, + .fault = go7007_vm_fault, +diff -urNp linux-2.6.31.1/drivers/staging/panel/panel.c linux-2.6.31.1/drivers/staging/panel/panel.c +--- linux-2.6.31.1/drivers/staging/panel/panel.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/staging/panel/panel.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1263,7 +1263,7 @@ static int lcd_release(struct inode *ino + return 0; + } + +-static struct file_operations lcd_fops = { ++static const struct file_operations lcd_fops = { + .write = lcd_write, + .open = lcd_open, + .release = lcd_release, +@@ -1519,7 +1519,7 @@ static int keypad_release(struct inode * + return 0; + } + +-static struct file_operations keypad_fops = { ++static const struct file_operations keypad_fops = { + .read = keypad_read, /* read */ + .open = keypad_open, /* open */ + .release = keypad_release, /* close */ +diff -urNp linux-2.6.31.1/drivers/staging/poch/poch.c linux-2.6.31.1/drivers/staging/poch/poch.c +--- linux-2.6.31.1/drivers/staging/poch/poch.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/staging/poch/poch.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1056,7 +1056,7 @@ static int poch_ioctl(struct inode *inod + return 0; + } + +-static struct file_operations poch_fops = { ++static const struct file_operations poch_fops = { + .owner = THIS_MODULE, + .open = poch_open, + .release = poch_release, +diff -urNp linux-2.6.31.1/drivers/staging/rtl8192su/ieee80211/proc.c linux-2.6.31.1/drivers/staging/rtl8192su/ieee80211/proc.c +--- linux-2.6.31.1/drivers/staging/rtl8192su/ieee80211/proc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/staging/rtl8192su/ieee80211/proc.c 2009-10-01 20:12:43.000000000 -0400 +@@ -87,7 +87,7 @@ static int c_show(struct seq_file *m, vo + return 0; + } + +-static struct seq_operations crypto_seq_ops = { ++static const struct seq_operations crypto_seq_ops = { + .start = c_start, + .next = c_next, + .stop = c_stop, +@@ -99,7 +99,7 @@ static int crypto_info_open(struct inode + return seq_open(file, &crypto_seq_ops); + } + +-static struct file_operations proc_crypto_ops = { ++static const struct file_operations proc_crypto_ops = { + .open = crypto_info_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/drivers/uio/uio.c linux-2.6.31.1/drivers/uio/uio.c +--- linux-2.6.31.1/drivers/uio/uio.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/uio/uio.c 2009-10-01 20:12:43.000000000 -0400 +@@ -658,7 +658,7 @@ static int uio_vma_fault(struct vm_area_ + return 0; + } + +-static struct vm_operations_struct uio_vm_ops = { ++static const struct vm_operations_struct uio_vm_ops = { + .open = uio_vma_open, + .close = uio_vma_close, + .fault = uio_vma_fault, +diff -urNp linux-2.6.31.1/drivers/usb/atm/usbatm.c linux-2.6.31.1/drivers/usb/atm/usbatm.c +--- linux-2.6.31.1/drivers/usb/atm/usbatm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/atm/usbatm.c 2009-10-01 20:12:43.000000000 -0400 +@@ -333,7 +333,7 @@ static void usbatm_extract_one_cell(stru + if (printk_ratelimit()) + atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n", + __func__, vpi, vci); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + return; + } + +@@ -361,7 +361,7 @@ static void usbatm_extract_one_cell(stru + if (length > ATM_MAX_AAL5_PDU) { + atm_rldbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n", + __func__, length, vcc); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + goto out; + } + +@@ -370,14 +370,14 @@ static void usbatm_extract_one_cell(stru + if (sarb->len < pdu_length) { + atm_rldbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n", + __func__, pdu_length, sarb->len, vcc); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + goto out; + } + + if (crc32_be(~0, skb_tail_pointer(sarb) - pdu_length, pdu_length) != 0xc704dd7b) { + atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n", + __func__, vcc); +- atomic_inc(&vcc->stats->rx_err); ++ atomic_inc_unchecked(&vcc->stats->rx_err); + goto out; + } + +@@ -387,7 +387,7 @@ static void usbatm_extract_one_cell(stru + if (printk_ratelimit()) + atm_err(instance, "%s: no memory for skb (length: %u)!\n", + __func__, length); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + goto out; + } + +@@ -412,7 +412,7 @@ static void usbatm_extract_one_cell(stru + + vcc->push(vcc, skb); + +- atomic_inc(&vcc->stats->rx); ++ atomic_inc_unchecked(&vcc->stats->rx); + out: + skb_trim(sarb, 0); + } +@@ -616,7 +616,7 @@ static void usbatm_tx_process(unsigned l + struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc; + + usbatm_pop(vcc, skb); +- atomic_inc(&vcc->stats->tx); ++ atomic_inc_unchecked(&vcc->stats->tx); + + skb = skb_dequeue(&instance->sndqueue); + } +@@ -775,11 +775,11 @@ static int usbatm_atm_proc_read(struct a + if (!left--) + return sprintf(page, + "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n", +- atomic_read(&atm_dev->stats.aal5.tx), +- atomic_read(&atm_dev->stats.aal5.tx_err), +- atomic_read(&atm_dev->stats.aal5.rx), +- atomic_read(&atm_dev->stats.aal5.rx_err), +- atomic_read(&atm_dev->stats.aal5.rx_drop)); ++ atomic_read_unchecked(&atm_dev->stats.aal5.tx), ++ atomic_read_unchecked(&atm_dev->stats.aal5.tx_err), ++ atomic_read_unchecked(&atm_dev->stats.aal5.rx), ++ atomic_read_unchecked(&atm_dev->stats.aal5.rx_err), ++ atomic_read_unchecked(&atm_dev->stats.aal5.rx_drop)); + + if (!left--) { + if (instance->disconnected) +diff -urNp linux-2.6.31.1/drivers/usb/class/cdc-acm.c linux-2.6.31.1/drivers/usb/class/cdc-acm.c +--- linux-2.6.31.1/drivers/usb/class/cdc-acm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/class/cdc-acm.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1529,7 +1529,7 @@ static struct usb_device_id acm_ids[] = + USB_CDC_ACM_PROTO_AT_CDMA) }, + + /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */ +- { } ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(usb, acm_ids); +diff -urNp linux-2.6.31.1/drivers/usb/class/usblp.c linux-2.6.31.1/drivers/usb/class/usblp.c +--- linux-2.6.31.1/drivers/usb/class/usblp.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/class/usblp.c 2009-10-01 20:12:43.000000000 -0400 +@@ -228,7 +228,7 @@ static const struct quirk_printer_struct + { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */ + { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */ + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */ +- { 0, 0 } ++ { 0, 0, 0 } + }; + + static int usblp_wwait(struct usblp *usblp, int nonblock); +@@ -1412,7 +1412,7 @@ static struct usb_device_id usblp_ids [] + { USB_INTERFACE_INFO(7, 1, 2) }, + { USB_INTERFACE_INFO(7, 1, 3) }, + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */ +- { } /* Terminating entry */ ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */ + }; + + MODULE_DEVICE_TABLE (usb, usblp_ids); +diff -urNp linux-2.6.31.1/drivers/usb/class/usbtmc.c linux-2.6.31.1/drivers/usb/class/usbtmc.c +--- linux-2.6.31.1/drivers/usb/class/usbtmc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/class/usbtmc.c 2009-10-01 20:12:43.000000000 -0400 +@@ -956,7 +956,7 @@ static long usbtmc_ioctl(struct file *fi + return retval; + } + +-static struct file_operations fops = { ++static const struct file_operations fops = { + .owner = THIS_MODULE, + .read = usbtmc_read, + .write = usbtmc_write, +diff -urNp linux-2.6.31.1/drivers/usb/core/hub.c linux-2.6.31.1/drivers/usb/core/hub.c +--- linux-2.6.31.1/drivers/usb/core/hub.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/core/hub.c 2009-10-01 20:12:43.000000000 -0400 +@@ -3284,7 +3284,7 @@ static struct usb_device_id hub_id_table + .bDeviceClass = USB_CLASS_HUB}, + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, + .bInterfaceClass = USB_CLASS_HUB}, +- { } /* Terminating entry */ ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */ + }; + + MODULE_DEVICE_TABLE (usb, hub_id_table); +diff -urNp linux-2.6.31.1/drivers/usb/core/inode.c linux-2.6.31.1/drivers/usb/core/inode.c +--- linux-2.6.31.1/drivers/usb/core/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/core/inode.c 2009-10-01 20:12:43.000000000 -0400 +@@ -48,7 +48,7 @@ + #define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO) + #define USBFS_DEFAULT_LISTMODE S_IRUGO + +-static struct super_operations usbfs_ops; ++static const struct super_operations usbfs_ops; + static const struct file_operations default_file_operations; + static struct vfsmount *usbfs_mount; + static int usbfs_mount_count; /* = 0 */ +@@ -449,7 +449,7 @@ static const struct file_operations defa + .llseek = default_file_lseek, + }; + +-static struct super_operations usbfs_ops = { ++static const struct super_operations usbfs_ops = { + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, + .remount_fs = remount, +diff -urNp linux-2.6.31.1/drivers/usb/core/message.c linux-2.6.31.1/drivers/usb/core/message.c +--- linux-2.6.31.1/drivers/usb/core/message.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/core/message.c 2009-10-01 20:12:43.000000000 -0400 +@@ -926,8 +926,8 @@ char *usb_cache_string(struct usb_device + buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL); + if (buf) { + len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE); +- if (len > 0) { +- smallbuf = kmalloc(++len, GFP_KERNEL); ++ if (len++ > 0) { ++ smallbuf = kmalloc(len, GFP_KERNEL); + if (!smallbuf) + return buf; + memcpy(smallbuf, buf, len); +diff -urNp linux-2.6.31.1/drivers/usb/gadget/inode.c linux-2.6.31.1/drivers/usb/gadget/inode.c +--- linux-2.6.31.1/drivers/usb/gadget/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/gadget/inode.c 2009-10-01 20:12:43.000000000 -0400 +@@ -2033,7 +2033,7 @@ gadgetfs_create_file (struct super_block + return inode; + } + +-static struct super_operations gadget_fs_operations = { ++static const struct super_operations gadget_fs_operations = { + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, + }; +diff -urNp linux-2.6.31.1/drivers/usb/gadget/printer.c linux-2.6.31.1/drivers/usb/gadget/printer.c +--- linux-2.6.31.1/drivers/usb/gadget/printer.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/gadget/printer.c 2009-10-01 20:12:43.000000000 -0400 +@@ -875,7 +875,7 @@ printer_ioctl(struct file *fd, unsigned + } + + /* used after endpoint configuration */ +-static struct file_operations printer_io_operations = { ++static const struct file_operations printer_io_operations = { + .owner = THIS_MODULE, + .open = printer_open, + .read = printer_read, +diff -urNp linux-2.6.31.1/drivers/usb/host/ehci-pci.c linux-2.6.31.1/drivers/usb/host/ehci-pci.c +--- linux-2.6.31.1/drivers/usb/host/ehci-pci.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/host/ehci-pci.c 2009-10-01 20:12:43.000000000 -0400 +@@ -416,7 +416,7 @@ static const struct pci_device_id pci_id + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), + .driver_data = (unsigned long) &ehci_pci_hc_driver, + }, +- { /* end: all zeroes */ } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + MODULE_DEVICE_TABLE(pci, pci_ids); + +diff -urNp linux-2.6.31.1/drivers/usb/host/uhci-hcd.c linux-2.6.31.1/drivers/usb/host/uhci-hcd.c +--- linux-2.6.31.1/drivers/usb/host/uhci-hcd.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/host/uhci-hcd.c 2009-10-01 20:12:43.000000000 -0400 +@@ -927,7 +927,7 @@ static const struct pci_device_id uhci_p + /* handle any USB UHCI controller */ + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0), + .driver_data = (unsigned long) &uhci_driver, +- }, { /* end: all zeroes */ } ++ }, { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(pci, uhci_pci_ids); +diff -urNp linux-2.6.31.1/drivers/usb/host/whci/debug.c linux-2.6.31.1/drivers/usb/host/whci/debug.c +--- linux-2.6.31.1/drivers/usb/host/whci/debug.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/host/whci/debug.c 2009-10-01 20:12:43.000000000 -0400 +@@ -134,7 +134,7 @@ static int pzl_open(struct inode *inode, + return single_open(file, pzl_print, inode->i_private); + } + +-static struct file_operations di_fops = { ++static const struct file_operations di_fops = { + .open = di_open, + .read = seq_read, + .llseek = seq_lseek, +@@ -142,7 +142,7 @@ static struct file_operations di_fops = + .owner = THIS_MODULE, + }; + +-static struct file_operations asl_fops = { ++static const struct file_operations asl_fops = { + .open = asl_open, + .read = seq_read, + .llseek = seq_lseek, +@@ -150,7 +150,7 @@ static struct file_operations asl_fops = + .owner = THIS_MODULE, + }; + +-static struct file_operations pzl_fops = { ++static const struct file_operations pzl_fops = { + .open = pzl_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/drivers/usb/mon/mon_bin.c linux-2.6.31.1/drivers/usb/mon/mon_bin.c +--- linux-2.6.31.1/drivers/usb/mon/mon_bin.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/mon/mon_bin.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1184,7 +1184,7 @@ static int mon_bin_vma_fault(struct vm_a + return 0; + } + +-static struct vm_operations_struct mon_bin_vm_ops = { ++static const struct vm_operations_struct mon_bin_vm_ops = { + .open = mon_bin_vma_open, + .close = mon_bin_vma_close, + .fault = mon_bin_vma_fault, +diff -urNp linux-2.6.31.1/drivers/usb/storage/debug.h linux-2.6.31.1/drivers/usb/storage/debug.h +--- linux-2.6.31.1/drivers/usb/storage/debug.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/storage/debug.h 2009-10-01 20:12:43.000000000 -0400 +@@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char + #define US_DEBUGPX(x...) printk( x ) + #define US_DEBUG(x) x + #else +-#define US_DEBUGP(x...) +-#define US_DEBUGPX(x...) +-#define US_DEBUG(x) ++#define US_DEBUGP(x...) do {} while (0) ++#define US_DEBUGPX(x...) do {} while (0) ++#define US_DEBUG(x) do {} while (0) + #endif + + #endif +diff -urNp linux-2.6.31.1/drivers/usb/storage/usb.c linux-2.6.31.1/drivers/usb/storage/usb.c +--- linux-2.6.31.1/drivers/usb/storage/usb.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/storage/usb.c 2009-10-01 20:12:43.000000000 -0400 +@@ -118,7 +118,7 @@ MODULE_PARM_DESC(quirks, "supplemental l + + static struct us_unusual_dev us_unusual_dev_list[] = { + # include "unusual_devs.h" +- { } /* Terminating entry */ ++ { NULL, NULL, 0, 0, NULL } /* Terminating entry */ + }; + + #undef UNUSUAL_DEV +diff -urNp linux-2.6.31.1/drivers/usb/storage/usual-tables.c linux-2.6.31.1/drivers/usb/storage/usual-tables.c +--- linux-2.6.31.1/drivers/usb/storage/usual-tables.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/usb/storage/usual-tables.c 2009-10-01 20:12:43.000000000 -0400 +@@ -48,7 +48,7 @@ + + struct usb_device_id usb_storage_usb_ids[] = { + # include "unusual_devs.h" +- { } /* Terminating entry */ ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */ + }; + EXPORT_SYMBOL_GPL(usb_storage_usb_ids); + +diff -urNp linux-2.6.31.1/drivers/uwb/uwb-debug.c linux-2.6.31.1/drivers/uwb/uwb-debug.c +--- linux-2.6.31.1/drivers/uwb/uwb-debug.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/uwb/uwb-debug.c 2009-10-01 20:12:43.000000000 -0400 +@@ -205,7 +205,7 @@ static ssize_t command_write(struct file + return ret < 0 ? ret : len; + } + +-static struct file_operations command_fops = { ++static const struct file_operations command_fops = { + .open = command_open, + .write = command_write, + .read = NULL, +@@ -255,7 +255,7 @@ static int reservations_open(struct inod + return single_open(file, reservations_print, inode->i_private); + } + +-static struct file_operations reservations_fops = { ++static const struct file_operations reservations_fops = { + .open = reservations_open, + .read = seq_read, + .llseek = seq_lseek, +@@ -283,7 +283,7 @@ static int drp_avail_open(struct inode * + return single_open(file, drp_avail_print, inode->i_private); + } + +-static struct file_operations drp_avail_fops = { ++static const struct file_operations drp_avail_fops = { + .open = drp_avail_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/drivers/uwb/wlp/messages.c linux-2.6.31.1/drivers/uwb/wlp/messages.c +--- linux-2.6.31.1/drivers/uwb/wlp/messages.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/uwb/wlp/messages.c 2009-10-01 20:12:43.000000000 -0400 +@@ -903,7 +903,7 @@ int wlp_parse_f0(struct wlp *wlp, struct + size_t len = skb->len; + size_t used; + ssize_t result; +- struct wlp_nonce enonce, rnonce; ++ struct wlp_nonce enonce = {{0}}, rnonce = {{0}}; + enum wlp_assc_error assc_err; + char enonce_buf[WLP_WSS_NONCE_STRSIZE]; + char rnonce_buf[WLP_WSS_NONCE_STRSIZE]; +diff -urNp linux-2.6.31.1/drivers/video/fb_defio.c linux-2.6.31.1/drivers/video/fb_defio.c +--- linux-2.6.31.1/drivers/video/fb_defio.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/video/fb_defio.c 2009-10-01 20:12:43.000000000 -0400 +@@ -125,7 +125,7 @@ page_already_added: + return 0; + } + +-static struct vm_operations_struct fb_deferred_io_vm_ops = { ++static const struct vm_operations_struct fb_deferred_io_vm_ops = { + .fault = fb_deferred_io_fault, + .page_mkwrite = fb_deferred_io_mkwrite, + }; +diff -urNp linux-2.6.31.1/drivers/video/fbmem.c linux-2.6.31.1/drivers/video/fbmem.c +--- linux-2.6.31.1/drivers/video/fbmem.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/video/fbmem.c 2009-10-01 20:12:43.000000000 -0400 +@@ -403,7 +403,7 @@ static void fb_do_show_logo(struct fb_in + image->dx += image->width + 8; + } + } else if (rotate == FB_ROTATE_UD) { +- for (x = 0; x < num && image->dx >= 0; x++) { ++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) { + info->fbops->fb_imageblit(info, image); + image->dx -= image->width + 8; + } +@@ -415,7 +415,7 @@ static void fb_do_show_logo(struct fb_in + image->dy += image->height + 8; + } + } else if (rotate == FB_ROTATE_CCW) { +- for (x = 0; x < num && image->dy >= 0; x++) { ++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) { + info->fbops->fb_imageblit(info, image); + image->dy -= image->height + 8; + } +@@ -1108,7 +1108,7 @@ static long do_fb_ioctl(struct fb_info * + return -EFAULT; + if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) + return -EINVAL; +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) ++ if (con2fb.framebuffer >= FB_MAX) + return -EINVAL; + if (!registered_fb[con2fb.framebuffer]) + request_module("fb%d", con2fb.framebuffer); +diff -urNp linux-2.6.31.1/drivers/video/fbmon.c linux-2.6.31.1/drivers/video/fbmon.c +--- linux-2.6.31.1/drivers/video/fbmon.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/video/fbmon.c 2009-10-01 20:12:43.000000000 -0400 +@@ -45,7 +45,7 @@ + #ifdef DEBUG + #define DPRINTK(fmt, args...) printk(fmt,## args) + #else +-#define DPRINTK(fmt, args...) ++#define DPRINTK(fmt, args...) do {} while (0) + #endif + + #define FBMON_FIX_HEADER 1 +diff -urNp linux-2.6.31.1/drivers/video/i810/i810_accel.c linux-2.6.31.1/drivers/video/i810/i810_accel.c +--- linux-2.6.31.1/drivers/video/i810/i810_accel.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/video/i810/i810_accel.c 2009-10-01 20:12:43.000000000 -0400 +@@ -73,6 +73,7 @@ static inline int wait_for_space(struct + } + } + printk("ringbuffer lockup!!!\n"); ++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space); + i810_report_error(mmio); + par->dev_flags |= LOCKUP; + info->pixmap.scan_align = 1; +diff -urNp linux-2.6.31.1/drivers/video/i810/i810_main.c linux-2.6.31.1/drivers/video/i810/i810_main.c +--- linux-2.6.31.1/drivers/video/i810/i810_main.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/video/i810/i810_main.c 2009-10-01 20:12:43.000000000 -0400 +@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, +- { 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, + }; + + static struct pci_driver i810fb_driver = { +diff -urNp linux-2.6.31.1/drivers/video/modedb.c linux-2.6.31.1/drivers/video/modedb.c +--- linux-2.6.31.1/drivers/video/modedb.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/video/modedb.c 2009-10-01 20:12:43.000000000 -0400 +@@ -38,240 +38,240 @@ static const struct fb_videomode modedb[ + { + /* 640x400 @ 70 Hz, 31.5 kHz hsync */ + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 640x480 @ 60 Hz, 31.5 kHz hsync */ + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 800x600 @ 56 Hz, 35.15 kHz hsync */ + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */ + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, +- 0, FB_VMODE_INTERLACED ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 640x400 @ 85 Hz, 37.86 kHz hsync */ + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, +- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 640x480 @ 72 Hz, 36.5 kHz hsync */ + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 640x480 @ 75 Hz, 37.50 kHz hsync */ + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 800x600 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 640x480 @ 85 Hz, 43.27 kHz hsync */ + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ + NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, +- 0, FB_VMODE_INTERLACED ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 800x600 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 640x480 @ 100 Hz, 53.01 kHz hsync */ + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */ + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 800x600 @ 85 Hz, 55.84 kHz hsync */ + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, +- 0, FB_VMODE_INTERLACED ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 800x600 @ 100 Hz, 64.02 kHz hsync */ + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */ + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */ + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */ + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ + NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ + NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */ + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */ + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */ + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */ + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */ + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1024x768 @ 100Hz, 80.21 kHz hsync */ + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */ + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */ + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */ + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */ + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */ + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */ + NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */ + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */ + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */ + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 512x384 @ 78 Hz, 31.50 kHz hsync */ + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 512x384 @ 85 Hz, 34.38 kHz hsync */ + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */ + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */ + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 320x240 @ 72 Hz, 36.5 kHz hsync */ + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */ + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 400x300 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 400x300 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */ + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 480x300 @ 60 Hz, 37.8 kHz hsync */ + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 480x300 @ 63 Hz, 39.6 kHz hsync */ + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 480x300 @ 72 Hz, 48.0 kHz hsync */ + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, +- 0, FB_VMODE_DOUBLE ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN + }, { + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */ + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, +- FB_VMODE_NONINTERLACED ++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ + NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6, +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */ + NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, +- 0, FB_VMODE_NONINTERLACED ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 720x576i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */ + NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5, +- 0, FB_VMODE_INTERLACED ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN + }, { + /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */ + NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5, +- 0, FB_VMODE_INTERLACED ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN + }, + }; + +diff -urNp linux-2.6.31.1/drivers/video/omap/dispc.c linux-2.6.31.1/drivers/video/omap/dispc.c +--- linux-2.6.31.1/drivers/video/omap/dispc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/video/omap/dispc.c 2009-10-01 20:12:43.000000000 -0400 +@@ -1013,7 +1013,7 @@ static void mmap_user_close(struct vm_ar + atomic_dec(&dispc.map_count[plane]); + } + +-static struct vm_operations_struct mmap_user_ops = { ++static const struct vm_operations_struct mmap_user_ops = { + .open = mmap_user_open, + .close = mmap_user_close, + }; +diff -urNp linux-2.6.31.1/drivers/video/uvesafb.c linux-2.6.31.1/drivers/video/uvesafb.c +--- linux-2.6.31.1/drivers/video/uvesafb.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/video/uvesafb.c 2009-10-01 20:12:43.000000000 -0400 +@@ -18,6 +18,7 @@ + #include <linux/fb.h> + #include <linux/io.h> + #include <linux/mutex.h> ++#include <linux/moduleloader.h> + #include <video/edid.h> + #include <video/uvesafb.h> + #ifdef CONFIG_X86 +@@ -118,7 +119,7 @@ static int uvesafb_helper_start(void) + NULL, + }; + +- return call_usermodehelper(v86d_path, argv, envp, 1); ++ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC); + } + + /* +@@ -566,10 +567,34 @@ static int __devinit uvesafb_vbe_getpmi( + if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) { + par->pmi_setpal = par->ypan = 0; + } else { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++#ifdef CONFIG_MODULES ++ unsigned long cr0; ++ ++ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx); ++#endif ++ if (!par->pmi_code) { ++ par->pmi_setpal = par->ypan = 0; ++ return 0; ++ } ++#endif ++ + par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4) + + task->t.regs.edi); ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ pax_open_kernel(cr0); ++ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx); ++ pax_close_kernel(cr0); ++ ++ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]); ++ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]); ++#else + par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1]; + par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2]; ++#endif ++ + printk(KERN_INFO "uvesafb: protected mode interface info at " + "%04x:%04x\n", + (u16)task->t.regs.es, (u16)task->t.regs.edi); +@@ -1825,6 +1850,11 @@ out: + if (par->vbe_modes) + kfree(par->vbe_modes); + ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ if (par->pmi_code) ++ module_free_exec(NULL, par->pmi_code); ++#endif ++ + framebuffer_release(info); + return err; + } +@@ -1851,6 +1881,12 @@ static int uvesafb_remove(struct platfor + kfree(par->vbe_state_orig); + if (par->vbe_state_saved) + kfree(par->vbe_state_saved); ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ if (par->pmi_code) ++ module_free_exec(NULL, par->pmi_code); ++#endif ++ + } + + framebuffer_release(info); +diff -urNp linux-2.6.31.1/drivers/video/vesafb.c linux-2.6.31.1/drivers/video/vesafb.c +--- linux-2.6.31.1/drivers/video/vesafb.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/drivers/video/vesafb.c 2009-10-01 20:12:43.000000000 -0400 +@@ -9,6 +9,7 @@ + */ + + #include <linux/module.h> ++#include <linux/moduleloader.h> + #include <linux/kernel.h> + #include <linux/errno.h> + #include <linux/string.h> +@@ -53,8 +54,8 @@ static int vram_remap __initdata; /* + static int vram_total __initdata; /* Set total amount of memory */ + static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ + static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ +-static void (*pmi_start)(void) __read_mostly; +-static void (*pmi_pal) (void) __read_mostly; ++static void (*pmi_start)(void) __read_only; ++static void (*pmi_pal) (void) __read_only; + static int depth __read_mostly; + static int vga_compat __read_mostly; + /* --------------------------------------------------------------------- */ +@@ -233,6 +234,7 @@ static int __init vesafb_probe(struct pl + unsigned int size_vmode; + unsigned int size_remap; + unsigned int size_total; ++ void *pmi_code = NULL; + + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) + return -ENODEV; +@@ -275,10 +277,6 @@ static int __init vesafb_probe(struct pl + size_remap = size_total; + vesafb_fix.smem_len = size_remap; + +-#ifndef __i386__ +- screen_info.vesapm_seg = 0; +-#endif +- + if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) { + printk(KERN_WARNING + "vesafb: cannot reserve video memory at 0x%lx\n", +@@ -315,9 +313,21 @@ static int __init vesafb_probe(struct pl + printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); + ++#ifdef __i386__ ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ pmi_code = module_alloc_exec(screen_info.vesapm_size); ++ if (!pmi_code) ++#elif !defined(CONFIG_PAX_KERNEXEC) ++ if (0) ++#endif ++ ++#endif ++ screen_info.vesapm_seg = 0; ++ + if (screen_info.vesapm_seg) { +- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n", +- screen_info.vesapm_seg,screen_info.vesapm_off); ++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n", ++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size); + } + + if (screen_info.vesapm_seg < 0xc000) +@@ -325,9 +335,29 @@ static int __init vesafb_probe(struct pl + + if (ypan || pmi_setpal) { + unsigned short *pmi_base; +- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); +- pmi_start = (void*)((char*)pmi_base + pmi_base[1]); +- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]); ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ unsigned long cr0; ++#endif ++ ++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ pax_open_kernel(cr0); ++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size); ++#else ++ pmi_code = pmi_base; ++#endif ++ ++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]); ++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]); ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ pmi_start = ktva_ktla(pmi_start); ++ pmi_pal = ktva_ktla(pmi_pal); ++ pax_close_kernel(cr0); ++#endif ++ + printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal); + if (pmi_base[3]) { + printk(KERN_INFO "vesafb: pmi: ports = "); +@@ -469,6 +499,11 @@ static int __init vesafb_probe(struct pl + info->node, info->fix.id); + return 0; + err: ++ ++#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) ++ module_free_exec(NULL, pmi_code); ++#endif ++ + if (info->screen_base) + iounmap(info->screen_base); + framebuffer_release(info); +diff -urNp linux-2.6.31.1/fs/9p/vfs_inode.c linux-2.6.31.1/fs/9p/vfs_inode.c +--- linux-2.6.31.1/fs/9p/vfs_inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/9p/vfs_inode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1025,7 +1025,7 @@ static void *v9fs_vfs_follow_link(struct + static void + v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) + { +- char *s = nd_get_link(nd); ++ const char *s = nd_get_link(nd); + + P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, + IS_ERR(s) ? "<error>" : s); +diff -urNp linux-2.6.31.1/fs/afs/proc.c linux-2.6.31.1/fs/afs/proc.c +--- linux-2.6.31.1/fs/afs/proc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/afs/proc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -28,7 +28,7 @@ static int afs_proc_cells_show(struct se + static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf, + size_t size, loff_t *_pos); + +-static struct seq_operations afs_proc_cells_ops = { ++static const struct seq_operations afs_proc_cells_ops = { + .start = afs_proc_cells_start, + .next = afs_proc_cells_next, + .stop = afs_proc_cells_stop, +@@ -70,7 +70,7 @@ static void *afs_proc_cell_volumes_next( + static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v); + static int afs_proc_cell_volumes_show(struct seq_file *m, void *v); + +-static struct seq_operations afs_proc_cell_volumes_ops = { ++static const struct seq_operations afs_proc_cell_volumes_ops = { + .start = afs_proc_cell_volumes_start, + .next = afs_proc_cell_volumes_next, + .stop = afs_proc_cell_volumes_stop, +@@ -95,7 +95,7 @@ static void *afs_proc_cell_vlservers_nex + static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v); + static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v); + +-static struct seq_operations afs_proc_cell_vlservers_ops = { ++static const struct seq_operations afs_proc_cell_vlservers_ops = { + .start = afs_proc_cell_vlservers_start, + .next = afs_proc_cell_vlservers_next, + .stop = afs_proc_cell_vlservers_stop, +@@ -119,7 +119,7 @@ static void *afs_proc_cell_servers_next( + static void afs_proc_cell_servers_stop(struct seq_file *p, void *v); + static int afs_proc_cell_servers_show(struct seq_file *m, void *v); + +-static struct seq_operations afs_proc_cell_servers_ops = { ++static const struct seq_operations afs_proc_cell_servers_ops = { + .start = afs_proc_cell_servers_start, + .next = afs_proc_cell_servers_next, + .stop = afs_proc_cell_servers_stop, +diff -urNp linux-2.6.31.1/fs/aio.c linux-2.6.31.1/fs/aio.c +--- linux-2.6.31.1/fs/aio.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/aio.c 2009-10-01 20:12:44.000000000 -0400 +@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx + size += sizeof(struct io_event) * nr_events; + nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT; + +- if (nr_pages < 0) ++ if (nr_pages <= 0) + return -EINVAL; + + nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event); +diff -urNp linux-2.6.31.1/fs/autofs/root.c linux-2.6.31.1/fs/autofs/root.c +--- linux-2.6.31.1/fs/autofs/root.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/autofs/root.c 2009-10-01 20:12:44.000000000 -0400 +@@ -299,7 +299,8 @@ static int autofs_root_symlink(struct in + set_bit(n,sbi->symlink_bitmap); + sl = &sbi->symlink[n]; + sl->len = strlen(symname); +- sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL); ++ slsize = sl->len+1; ++ sl->data = kmalloc(slsize, GFP_KERNEL); + if (!sl->data) { + clear_bit(n,sbi->symlink_bitmap); + unlock_kernel(); +diff -urNp linux-2.6.31.1/fs/autofs4/symlink.c linux-2.6.31.1/fs/autofs4/symlink.c +--- linux-2.6.31.1/fs/autofs4/symlink.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/autofs4/symlink.c 2009-10-01 20:12:44.000000000 -0400 +@@ -15,7 +15,7 @@ + static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) + { + struct autofs_info *ino = autofs4_dentry_ino(dentry); +- nd_set_link(nd, (char *)ino->u.symlink); ++ nd_set_link(nd, ino->u.symlink); + return NULL; + } + +diff -urNp linux-2.6.31.1/fs/befs/linuxvfs.c linux-2.6.31.1/fs/befs/linuxvfs.c +--- linux-2.6.31.1/fs/befs/linuxvfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/befs/linuxvfs.c 2009-10-01 20:12:44.000000000 -0400 +@@ -493,7 +493,7 @@ static void befs_put_link(struct dentry + { + befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); + if (befs_ino->i_flags & BEFS_LONG_SYMLINK) { +- char *link = nd_get_link(nd); ++ const char *link = nd_get_link(nd); + if (!IS_ERR(link)) + kfree(link); + } +diff -urNp linux-2.6.31.1/fs/binfmt_aout.c linux-2.6.31.1/fs/binfmt_aout.c +--- linux-2.6.31.1/fs/binfmt_aout.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/binfmt_aout.c 2009-10-01 20:12:44.000000000 -0400 +@@ -16,6 +16,7 @@ + #include <linux/string.h> + #include <linux/fs.h> + #include <linux/file.h> ++#include <linux/security.h> + #include <linux/stat.h> + #include <linux/fcntl.h> + #include <linux/ptrace.h> +@@ -113,10 +114,12 @@ static int aout_core_dump(long signr, st + + /* If the size of the dump file exceeds the rlimit, then see what would happen + if we wrote the stack, but not the data area. */ ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1); + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit) + dump.u_dsize = 0; + + /* Make sure we have enough room to write the stack and data areas. */ ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1); + if ((dump.u_ssize + 1) * PAGE_SIZE > limit) + dump.u_ssize = 0; + +@@ -249,6 +252,8 @@ static int load_aout_binary(struct linux + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; + if (rlim >= RLIM_INFINITY) + rlim = ~0; ++ ++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1); + if (ex.a_data + ex.a_bss > rlim) + return -ENOMEM; + +@@ -276,6 +281,27 @@ static int load_aout_binary(struct linux + install_exec_creds(bprm); + current->flags &= ~PF_FORKNOEXEC; + ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) ++ current->mm->pax_flags = 0UL; ++#endif ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) { ++ current->mm->pax_flags |= MF_PAX_PAGEEXEC; ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP) ++ current->mm->pax_flags |= MF_PAX_EMUTRAMP; ++#endif ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT)) ++ current->mm->pax_flags |= MF_PAX_MPROTECT; ++#endif ++ ++ } ++#endif ++ + if (N_MAGIC(ex) == OMAGIC) { + unsigned long text_addr, map_size; + loff_t pos; +@@ -348,7 +374,7 @@ static int load_aout_binary(struct linux + + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, +- PROT_READ | PROT_WRITE | PROT_EXEC, ++ PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, + fd_offset + ex.a_text); + up_write(¤t->mm->mmap_sem); +diff -urNp linux-2.6.31.1/fs/binfmt_elf.c linux-2.6.31.1/fs/binfmt_elf.c +--- linux-2.6.31.1/fs/binfmt_elf.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/binfmt_elf.c 2009-10-01 20:12:44.000000000 -0400 +@@ -35,6 +35,10 @@ + #include <asm/param.h> + #include <asm/page.h> + ++#ifdef CONFIG_PAX_SEGMEXEC ++#include <asm/desc.h> ++#endif ++ + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); + static int load_elf_library(struct file *); + static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, +@@ -50,6 +54,10 @@ static int elf_core_dump(long signr, str + #define elf_core_dump NULL + #endif + ++#ifdef CONFIG_PAX_MPROTECT ++static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags); ++#endif ++ + #if ELF_EXEC_PAGESIZE > PAGE_SIZE + #define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE + #else +@@ -69,6 +77,11 @@ static struct linux_binfmt elf_format = + .load_binary = load_elf_binary, + .load_shlib = load_elf_library, + .core_dump = elf_core_dump, ++ ++#ifdef CONFIG_PAX_MPROTECT ++ .handle_mprotect= elf_handle_mprotect, ++#endif ++ + .min_coredump = ELF_EXEC_PAGESIZE, + .hasvdso = 1 + }; +@@ -77,6 +90,8 @@ static struct linux_binfmt elf_format = + + static int set_brk(unsigned long start, unsigned long end) + { ++ unsigned long e = end; ++ + start = ELF_PAGEALIGN(start); + end = ELF_PAGEALIGN(end); + if (end > start) { +@@ -87,7 +102,7 @@ static int set_brk(unsigned long start, + if (BAD_ADDR(addr)) + return addr; + } +- current->mm->start_brk = current->mm->brk = end; ++ current->mm->start_brk = current->mm->brk = e; + return 0; + } + +@@ -148,7 +163,7 @@ create_elf_tables(struct linux_binprm *b + elf_addr_t __user *u_rand_bytes; + const char *k_platform = ELF_PLATFORM; + const char *k_base_platform = ELF_BASE_PLATFORM; +- unsigned char k_rand_bytes[16]; ++ u32 k_rand_bytes[4]; + int items; + elf_addr_t *elf_info; + int ei_index = 0; +@@ -195,6 +210,10 @@ create_elf_tables(struct linux_binprm *b + * Generate 16 random bytes for userspace PRNG seeding. + */ + get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes)); ++ srandom32(k_rand_bytes[0] ^ random32()); ++ srandom32(k_rand_bytes[1] ^ random32()); ++ srandom32(k_rand_bytes[2] ^ random32()); ++ srandom32(k_rand_bytes[3] ^ random32()); + u_rand_bytes = (elf_addr_t __user *) + STACK_ALLOC(p, sizeof(k_rand_bytes)); + if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes))) +@@ -385,10 +404,10 @@ static unsigned long load_elf_interp(str + { + struct elf_phdr *elf_phdata; + struct elf_phdr *eppnt; +- unsigned long load_addr = 0; ++ unsigned long load_addr = 0, pax_task_size = TASK_SIZE; + int load_addr_set = 0; + unsigned long last_bss = 0, elf_bss = 0; +- unsigned long error = ~0UL; ++ unsigned long error = -EINVAL; + unsigned long total_size; + int retval, i, size; + +@@ -434,6 +453,11 @@ static unsigned long load_elf_interp(str + goto out_close; + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++#endif ++ + eppnt = elf_phdata; + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { + if (eppnt->p_type == PT_LOAD) { +@@ -477,8 +501,8 @@ static unsigned long load_elf_interp(str + k = load_addr + eppnt->p_vaddr; + if (BAD_ADDR(k) || + eppnt->p_filesz > eppnt->p_memsz || +- eppnt->p_memsz > TASK_SIZE || +- TASK_SIZE - eppnt->p_memsz < k) { ++ eppnt->p_memsz > pax_task_size || ++ pax_task_size - eppnt->p_memsz < k) { + error = -ENOMEM; + goto out_close; + } +@@ -532,6 +556,177 @@ out: + return error; + } + ++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE) ++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata) ++{ ++ unsigned long pax_flags = 0UL; ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (elf_phdata->p_flags & PF_PAGEEXEC) ++ pax_flags |= MF_PAX_PAGEEXEC; ++#endif ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (elf_phdata->p_flags & PF_SEGMEXEC) ++ pax_flags |= MF_PAX_SEGMEXEC; ++#endif ++ ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC) ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { ++ if (nx_enabled) ++ pax_flags &= ~MF_PAX_SEGMEXEC; ++ else ++ pax_flags &= ~MF_PAX_PAGEEXEC; ++ } ++#endif ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ if (elf_phdata->p_flags & PF_EMUTRAMP) ++ pax_flags |= MF_PAX_EMUTRAMP; ++#endif ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if (elf_phdata->p_flags & PF_MPROTECT) ++ pax_flags |= MF_PAX_MPROTECT; ++#endif ++ ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) ++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP)) ++ pax_flags |= MF_PAX_RANDMMAP; ++#endif ++ ++ return pax_flags; ++} ++#endif ++ ++#ifdef CONFIG_PAX_PT_PAX_FLAGS ++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata) ++{ ++ unsigned long pax_flags = 0UL; ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC)) ++ pax_flags |= MF_PAX_PAGEEXEC; ++#endif ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC)) ++ pax_flags |= MF_PAX_SEGMEXEC; ++#endif ++ ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC) ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { ++ if (nx_enabled) ++ pax_flags &= ~MF_PAX_SEGMEXEC; ++ else ++ pax_flags &= ~MF_PAX_PAGEEXEC; ++ } ++#endif ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP)) ++ pax_flags |= MF_PAX_EMUTRAMP; ++#endif ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if (!(elf_phdata->p_flags & PF_NOMPROTECT)) ++ pax_flags |= MF_PAX_MPROTECT; ++#endif ++ ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) ++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP)) ++ pax_flags |= MF_PAX_RANDMMAP; ++#endif ++ ++ return pax_flags; ++} ++#endif ++ ++#ifdef CONFIG_PAX_EI_PAX ++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex) ++{ ++ unsigned long pax_flags = 0UL; ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC)) ++ pax_flags |= MF_PAX_PAGEEXEC; ++#endif ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) ++ pax_flags |= MF_PAX_SEGMEXEC; ++#endif ++ ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC) ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { ++ if (nx_enabled) ++ pax_flags &= ~MF_PAX_SEGMEXEC; ++ else ++ pax_flags &= ~MF_PAX_PAGEEXEC; ++ } ++#endif ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP)) ++ pax_flags |= MF_PAX_EMUTRAMP; ++#endif ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT)) ++ pax_flags |= MF_PAX_MPROTECT; ++#endif ++ ++#ifdef CONFIG_PAX_ASLR ++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP)) ++ pax_flags |= MF_PAX_RANDMMAP; ++#endif ++ ++ return pax_flags; ++} ++#endif ++ ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) ++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata) ++{ ++ unsigned long pax_flags = 0UL; ++ ++#ifdef CONFIG_PAX_PT_PAX_FLAGS ++ unsigned long i; ++#endif ++ ++#ifdef CONFIG_PAX_EI_PAX ++ pax_flags = pax_parse_ei_pax(elf_ex); ++#endif ++ ++#ifdef CONFIG_PAX_PT_PAX_FLAGS ++ for (i = 0UL; i < elf_ex->e_phnum; i++) ++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) { ++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) || ++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) || ++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) || ++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) || ++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP))) ++ return -EINVAL; ++ ++#ifdef CONFIG_PAX_SOFTMODE ++ if (pax_softmode) ++ pax_flags = pax_parse_softmode(&elf_phdata[i]); ++ else ++#endif ++ ++ pax_flags = pax_parse_hardmode(&elf_phdata[i]); ++ break; ++ } ++#endif ++ ++ if (0 > pax_check_flags(&pax_flags)) ++ return -EINVAL; ++ ++ current->mm->pax_flags = pax_flags; ++ return 0; ++} ++#endif ++ + /* + * These are the functions used to load ELF style executables and shared + * libraries. There is no binary dependent code anywhere else. +@@ -548,6 +743,11 @@ static unsigned long randomize_stack_top + { + unsigned int random_variable = 0; + ++#ifdef CONFIG_PAX_RANDUSTACK ++ if (randomize_va_space) ++ return stack_top - current->mm->delta_stack; ++#endif ++ + if ((current->flags & PF_RANDOMIZE) && + !(current->personality & ADDR_NO_RANDOMIZE)) { + random_variable = get_random_int() & STACK_RND_MASK; +@@ -566,7 +766,7 @@ static int load_elf_binary(struct linux_ + unsigned long load_addr = 0, load_bias = 0; + int load_addr_set = 0; + char * elf_interpreter = NULL; +- unsigned long error; ++ unsigned long error = 0; + struct elf_phdr *elf_ppnt, *elf_phdata; + unsigned long elf_bss, elf_brk; + int retval, i; +@@ -576,11 +776,11 @@ static int load_elf_binary(struct linux_ + unsigned long start_code, end_code, start_data, end_data; + unsigned long reloc_func_desc = 0; + int executable_stack = EXSTACK_DEFAULT; +- unsigned long def_flags = 0; + struct { + struct elfhdr elf_ex; + struct elfhdr interp_elf_ex; + } *loc; ++ unsigned long pax_task_size = TASK_SIZE; + + loc = kmalloc(sizeof(*loc), GFP_KERNEL); + if (!loc) { +@@ -742,11 +942,80 @@ static int load_elf_binary(struct linux_ + + /* OK, This is the point of no return */ + current->flags &= ~PF_FORKNOEXEC; +- current->mm->def_flags = def_flags; ++ ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) ++ current->mm->pax_flags = 0UL; ++#endif ++ ++#ifdef CONFIG_PAX_DLRESOLVE ++ current->mm->call_dl_resolve = 0UL; ++#endif ++ ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT) ++ current->mm->call_syscall = 0UL; ++#endif ++ ++#ifdef CONFIG_PAX_ASLR ++ current->mm->delta_mmap = 0UL; ++ current->mm->delta_stack = 0UL; ++#endif ++ ++ current->mm->def_flags = 0; ++ ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) ++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) { ++ send_sig(SIGKILL, current, 0); ++ goto out_free_dentry; ++ } ++#endif ++ ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS ++ pax_set_initial_flags(bprm); ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS) ++ if (pax_set_initial_flags_func) ++ (pax_set_initial_flags_func)(bprm); ++#endif ++ ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT ++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) { ++ current->mm->context.user_cs_limit = PAGE_SIZE; ++ current->mm->def_flags |= VM_PAGEEXEC; ++ } ++#endif ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { ++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE; ++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE; ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++ } ++#endif ++ ++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC) ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { ++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu()); ++ put_cpu(); ++ } ++#endif ++ ++#ifdef CONFIG_PAX_ASLR ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) { ++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT; ++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT; ++ } ++#endif + + /* Do this immediately, since STACK_TOP as used in setup_arg_pages + may depend on the personality. */ + SET_PERSONALITY(loc->elf_ex); ++ ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { ++ executable_stack = EXSTACK_DISABLE_X; ++ current->personality &= ~READ_IMPLIES_EXEC; ++ } else ++#endif ++ + if (elf_read_implies_exec(loc->elf_ex, executable_stack)) + current->personality |= READ_IMPLIES_EXEC; + +@@ -827,6 +1096,20 @@ static int load_elf_binary(struct linux_ + #else + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); + #endif ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ /* PaX: randomize base address at the default exe base if requested */ ++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) { ++#ifdef CONFIG_SPARC64 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1); ++#else ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT; ++#endif ++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias); ++ elf_flags |= MAP_FIXED; ++ } ++#endif ++ + } + + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, +@@ -859,9 +1142,9 @@ static int load_elf_binary(struct linux_ + * allowed task size. Note that p_filesz must always be + * <= p_memsz so it is only necessary to check p_memsz. + */ +- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz || +- elf_ppnt->p_memsz > TASK_SIZE || +- TASK_SIZE - elf_ppnt->p_memsz < k) { ++ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz || ++ elf_ppnt->p_memsz > pax_task_size || ++ pax_task_size - elf_ppnt->p_memsz < k) { + /* set_brk can never work. Avoid overflows. */ + send_sig(SIGKILL, current, 0); + retval = -EINVAL; +@@ -889,6 +1172,11 @@ static int load_elf_binary(struct linux_ + start_data += load_bias; + end_data += load_bias; + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) ++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4); ++#endif ++ + /* Calling set_brk effectively mmaps the pages that we need + * for the bss and break sections. We must do this before + * mapping in the interpreter, to make sure it doesn't wind +@@ -900,9 +1188,11 @@ static int load_elf_binary(struct linux_ + goto out_free_dentry; + } + if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { +- send_sig(SIGSEGV, current, 0); +- retval = -EFAULT; /* Nobody gets to see this, but.. */ +- goto out_free_dentry; ++ /* ++ * This bss-zeroing can fail if the ELF ++ * file specifies odd protections. So ++ * we don't check the return value ++ */ + } + + if (elf_interpreter) { +@@ -1135,8 +1425,10 @@ static int dump_seek(struct file *file, + unsigned long n = off; + if (n > PAGE_SIZE) + n = PAGE_SIZE; +- if (!dump_write(file, buf, n)) ++ if (!dump_write(file, buf, n)) { ++ free_page((unsigned long)buf); + return 0; ++ } + off -= n; + } + free_page((unsigned long)buf); +@@ -1148,7 +1440,7 @@ static int dump_seek(struct file *file, + * Decide what to dump of a segment, part, all or none. + */ + static unsigned long vma_dump_size(struct vm_area_struct *vma, +- unsigned long mm_flags) ++ unsigned long mm_flags, long signr) + { + #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type)) + +@@ -1182,7 +1474,7 @@ static unsigned long vma_dump_size(struc + if (vma->vm_file == NULL) + return 0; + +- if (FILTER(MAPPED_PRIVATE)) ++ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE)) + goto whole; + + /* +@@ -1278,8 +1570,11 @@ static int writenote(struct memelfnote * + #undef DUMP_WRITE + + #define DUMP_WRITE(addr, nr) \ ++ do { \ ++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \ + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ +- goto end_coredump; ++ goto end_coredump; \ ++ } while (0); + #define DUMP_SEEK(off) \ + if (!dump_seek(file, (off))) \ + goto end_coredump; +@@ -1991,7 +2286,7 @@ static int elf_core_dump(long signr, str + phdr.p_offset = offset; + phdr.p_vaddr = vma->vm_start; + phdr.p_paddr = 0; +- phdr.p_filesz = vma_dump_size(vma, mm_flags); ++ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr); + phdr.p_memsz = vma->vm_end - vma->vm_start; + offset += phdr.p_filesz; + phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; +@@ -2023,7 +2318,7 @@ static int elf_core_dump(long signr, str + unsigned long addr; + unsigned long end; + +- end = vma->vm_start + vma_dump_size(vma, mm_flags); ++ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr); + + for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { + struct page *page; +@@ -2043,6 +2338,7 @@ static int elf_core_dump(long signr, str + flush_cache_page(tmp_vma, addr, + page_to_pfn(page)); + kaddr = kmap(page); ++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1); + if ((size += PAGE_SIZE) > limit || + !dump_write(file, kaddr, + PAGE_SIZE)) { +@@ -2073,6 +2369,97 @@ out: + + #endif /* USE_ELF_CORE_DUMP */ + ++#ifdef CONFIG_PAX_MPROTECT ++/* PaX: non-PIC ELF libraries need relocations on their executable segments ++ * therefore we'll grant them VM_MAYWRITE once during their life. Similarly ++ * we'll remove VM_MAYWRITE for good on RELRO segments. ++ * ++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment ++ * basis because we want to allow the common case and not the special ones. ++ */ ++static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags) ++{ ++ struct elfhdr elf_h; ++ struct elf_phdr elf_p; ++ unsigned long i; ++ unsigned long oldflags; ++ bool is_textrel_rw, is_textrel_rx, is_relro; ++ ++ if (!(vma->vm_mm->pax_flags & MF_PAX_MPROTECT)) ++ return; ++ ++ oldflags = vma->vm_flags & (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ); ++ newflags &= VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ; ++ ++#ifdef CONFIG_PAX_NOELFRELOCS ++ is_textrel_rw = false; ++ is_textrel_rx = false; ++#else ++ /* possible TEXTREL */ ++ is_textrel_rw = vma->vm_file && !vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYREAD | VM_EXEC | VM_READ) && newflags == (VM_WRITE | VM_READ); ++ is_textrel_rx = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_WRITE | VM_READ) && newflags == (VM_EXEC | VM_READ); ++#endif ++ ++ /* possible RELRO */ ++ is_relro = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ) && newflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ); ++ ++ if (!is_textrel_rw && !is_textrel_rx && !is_relro) ++ return; ++ ++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) || ++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) || ++ ++#ifdef CONFIG_PAX_ETEXECRELOCS ++ ((is_textrel_rw || is_textrel_rx) && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) || ++#else ++ ((is_textrel_rw || is_textrel_rx) && elf_h.e_type != ET_DYN) || ++#endif ++ ++ (is_relro && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) || ++ !elf_check_arch(&elf_h) || ++ elf_h.e_phentsize != sizeof(struct elf_phdr) || ++ elf_h.e_phnum > 65536UL / sizeof(struct elf_phdr)) ++ return; ++ ++ for (i = 0UL; i < elf_h.e_phnum; i++) { ++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p))) ++ return; ++ switch (elf_p.p_type) { ++ case PT_DYNAMIC: ++ if (!is_textrel_rw && !is_textrel_rx) ++ continue; ++ i = 0UL; ++ while ((i+1) * sizeof(elf_dyn) <= elf_p.p_filesz) { ++ elf_dyn dyn; ++ ++ if (sizeof(dyn) != kernel_read(vma->vm_file, elf_p.p_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn))) ++ return; ++ if (dyn.d_tag == DT_NULL) ++ return; ++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) { ++ gr_log_textrel(vma); ++ if (is_textrel_rw) ++ vma->vm_flags |= VM_MAYWRITE; ++ else ++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */ ++ vma->vm_flags &= ~VM_MAYWRITE; ++ return; ++ } ++ i++; ++ } ++ return; ++ ++ case PT_GNU_RELRO: ++ if (!is_relro) ++ continue; ++ if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start) ++ vma->vm_flags &= ~VM_MAYWRITE; ++ return; ++ } ++ } ++} ++#endif ++ + static int __init init_elf_binfmt(void) + { + return register_binfmt(&elf_format); +diff -urNp linux-2.6.31.1/fs/binfmt_flat.c linux-2.6.31.1/fs/binfmt_flat.c +--- linux-2.6.31.1/fs/binfmt_flat.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/binfmt_flat.c 2009-10-01 20:12:44.000000000 -0400 +@@ -565,7 +565,9 @@ static int load_flat_file(struct linux_b + realdatastart = (unsigned long) -ENOMEM; + printk("Unable to allocate RAM for process data, errno %d\n", + (int)-realdatastart); ++ down_write(¤t->mm->mmap_sem); + do_munmap(current->mm, textpos, text_len); ++ up_write(¤t->mm->mmap_sem); + ret = realdatastart; + goto err; + } +@@ -589,8 +591,10 @@ static int load_flat_file(struct linux_b + } + if (result >= (unsigned long)-4096) { + printk("Unable to read data+bss, errno %d\n", (int)-result); ++ down_write(¤t->mm->mmap_sem); + do_munmap(current->mm, textpos, text_len); + do_munmap(current->mm, realdatastart, data_len + extra); ++ up_write(¤t->mm->mmap_sem); + ret = result; + goto err; + } +@@ -659,8 +663,10 @@ static int load_flat_file(struct linux_b + } + if (result >= (unsigned long)-4096) { + printk("Unable to read code+data+bss, errno %d\n",(int)-result); ++ down_write(¤t->mm->mmap_sem); + do_munmap(current->mm, textpos, text_len + data_len + extra + + MAX_SHARED_LIBS * sizeof(unsigned long)); ++ up_write(¤t->mm->mmap_sem); + ret = result; + goto err; + } +diff -urNp linux-2.6.31.1/fs/binfmt_misc.c linux-2.6.31.1/fs/binfmt_misc.c +--- linux-2.6.31.1/fs/binfmt_misc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/binfmt_misc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -693,7 +693,7 @@ static int bm_fill_super(struct super_bl + static struct tree_descr bm_files[] = { + [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, + [3] = {"register", &bm_register_operations, S_IWUSR}, +- /* last one */ {""} ++ /* last one */ {"", NULL, 0} + }; + int err = simple_fill_super(sb, 0x42494e4d, bm_files); + if (!err) +diff -urNp linux-2.6.31.1/fs/btrfs/ctree.h linux-2.6.31.1/fs/btrfs/ctree.h +--- linux-2.6.31.1/fs/btrfs/ctree.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/btrfs/ctree.h 2009-10-01 20:12:44.000000000 -0400 +@@ -2286,7 +2286,7 @@ int btrfs_sync_file(struct file *file, s + int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, + int skip_pinned); + int btrfs_check_file(struct btrfs_root *root, struct inode *inode); +-extern struct file_operations btrfs_file_operations; ++extern const struct file_operations btrfs_file_operations; + int btrfs_drop_extents(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct inode *inode, + u64 start, u64 end, u64 locked_end, +diff -urNp linux-2.6.31.1/fs/btrfs/disk-io.c linux-2.6.31.1/fs/btrfs/disk-io.c +--- linux-2.6.31.1/fs/btrfs/disk-io.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/btrfs/disk-io.c 2009-10-01 20:12:44.000000000 -0400 +@@ -772,7 +772,7 @@ static void btree_invalidatepage(struct + } + } + +-static struct address_space_operations btree_aops = { ++static const struct address_space_operations btree_aops = { + .readpage = btree_readpage, + .writepage = btree_writepage, + .writepages = btree_writepages, +diff -urNp linux-2.6.31.1/fs/btrfs/file.c linux-2.6.31.1/fs/btrfs/file.c +--- linux-2.6.31.1/fs/btrfs/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/btrfs/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1203,7 +1203,7 @@ out: + return ret > 0 ? EIO : ret; + } + +-static struct vm_operations_struct btrfs_file_vm_ops = { ++static const struct vm_operations_struct btrfs_file_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = btrfs_page_mkwrite, + }; +@@ -1215,7 +1215,7 @@ static int btrfs_file_mmap(struct file * + return 0; + } + +-struct file_operations btrfs_file_operations = { ++const struct file_operations btrfs_file_operations = { + .llseek = generic_file_llseek, + .read = do_sync_read, + .aio_read = generic_file_aio_read, +diff -urNp linux-2.6.31.1/fs/btrfs/inode.c linux-2.6.31.1/fs/btrfs/inode.c +--- linux-2.6.31.1/fs/btrfs/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/btrfs/inode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -55,14 +55,14 @@ struct btrfs_iget_args { + struct btrfs_root *root; + }; + +-static struct inode_operations btrfs_dir_inode_operations; +-static struct inode_operations btrfs_symlink_inode_operations; +-static struct inode_operations btrfs_dir_ro_inode_operations; +-static struct inode_operations btrfs_special_inode_operations; +-static struct inode_operations btrfs_file_inode_operations; +-static struct address_space_operations btrfs_aops; +-static struct address_space_operations btrfs_symlink_aops; +-static struct file_operations btrfs_dir_file_operations; ++static const struct inode_operations btrfs_dir_inode_operations; ++static const struct inode_operations btrfs_symlink_inode_operations; ++static const struct inode_operations btrfs_dir_ro_inode_operations; ++static const struct inode_operations btrfs_special_inode_operations; ++static const struct inode_operations btrfs_file_inode_operations; ++static const struct address_space_operations btrfs_aops; ++static const struct address_space_operations btrfs_symlink_aops; ++static const struct file_operations btrfs_dir_file_operations; + static struct extent_io_ops btrfs_extent_io_ops; + + static struct kmem_cache *btrfs_inode_cachep; +@@ -5201,7 +5201,7 @@ static int btrfs_permission(struct inode + return generic_permission(inode, mask, btrfs_check_acl); + } + +-static struct inode_operations btrfs_dir_inode_operations = { ++static const struct inode_operations btrfs_dir_inode_operations = { + .getattr = btrfs_getattr, + .lookup = btrfs_lookup, + .create = btrfs_create, +@@ -5219,11 +5219,11 @@ static struct inode_operations btrfs_dir + .removexattr = btrfs_removexattr, + .permission = btrfs_permission, + }; +-static struct inode_operations btrfs_dir_ro_inode_operations = { ++static const struct inode_operations btrfs_dir_ro_inode_operations = { + .lookup = btrfs_lookup, + .permission = btrfs_permission, + }; +-static struct file_operations btrfs_dir_file_operations = { ++static const struct file_operations btrfs_dir_file_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .readdir = btrfs_real_readdir, +@@ -5259,7 +5259,7 @@ static struct extent_io_ops btrfs_extent + * + * For now we're avoiding this by dropping bmap. + */ +-static struct address_space_operations btrfs_aops = { ++static const struct address_space_operations btrfs_aops = { + .readpage = btrfs_readpage, + .writepage = btrfs_writepage, + .writepages = btrfs_writepages, +@@ -5271,14 +5271,14 @@ static struct address_space_operations b + .set_page_dirty = btrfs_set_page_dirty, + }; + +-static struct address_space_operations btrfs_symlink_aops = { ++static const struct address_space_operations btrfs_symlink_aops = { + .readpage = btrfs_readpage, + .writepage = btrfs_writepage, + .invalidatepage = btrfs_invalidatepage, + .releasepage = btrfs_releasepage, + }; + +-static struct inode_operations btrfs_file_inode_operations = { ++static const struct inode_operations btrfs_file_inode_operations = { + .truncate = btrfs_truncate, + .getattr = btrfs_getattr, + .setattr = btrfs_setattr, +@@ -5290,7 +5290,7 @@ static struct inode_operations btrfs_fil + .fallocate = btrfs_fallocate, + .fiemap = btrfs_fiemap, + }; +-static struct inode_operations btrfs_special_inode_operations = { ++static const struct inode_operations btrfs_special_inode_operations = { + .getattr = btrfs_getattr, + .setattr = btrfs_setattr, + .permission = btrfs_permission, +@@ -5299,7 +5299,7 @@ static struct inode_operations btrfs_spe + .listxattr = btrfs_listxattr, + .removexattr = btrfs_removexattr, + }; +-static struct inode_operations btrfs_symlink_inode_operations = { ++static const struct inode_operations btrfs_symlink_inode_operations = { + .readlink = generic_readlink, + .follow_link = page_follow_link_light, + .put_link = page_put_link, +diff -urNp linux-2.6.31.1/fs/btrfs/super.c linux-2.6.31.1/fs/btrfs/super.c +--- linux-2.6.31.1/fs/btrfs/super.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/btrfs/super.c 2009-10-01 20:12:44.000000000 -0400 +@@ -51,7 +51,7 @@ + #include "export.h" + #include "compression.h" + +-static struct super_operations btrfs_super_ops; ++static const struct super_operations btrfs_super_ops; + + static void btrfs_put_super(struct super_block *sb) + { +@@ -675,7 +675,7 @@ static int btrfs_unfreeze(struct super_b + return 0; + } + +-static struct super_operations btrfs_super_ops = { ++static const struct super_operations btrfs_super_ops = { + .delete_inode = btrfs_delete_inode, + .put_super = btrfs_put_super, + .sync_fs = btrfs_sync_fs, +diff -urNp linux-2.6.31.1/fs/buffer.c linux-2.6.31.1/fs/buffer.c +--- linux-2.6.31.1/fs/buffer.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/buffer.c 2009-10-01 20:12:44.000000000 -0400 +@@ -25,6 +25,7 @@ + #include <linux/percpu.h> + #include <linux/slab.h> + #include <linux/capability.h> ++#include <linux/security.h> + #include <linux/blkdev.h> + #include <linux/file.h> + #include <linux/quotaops.h> +@@ -2233,6 +2234,7 @@ int generic_cont_expand_simple(struct in + + err = -EFBIG; + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; ++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1); + if (limit != RLIM_INFINITY && size > (loff_t)limit) { + send_sig(SIGXFSZ, current, 0); + goto out; +diff -urNp linux-2.6.31.1/fs/cifs/cifs_dfs_ref.c linux-2.6.31.1/fs/cifs/cifs_dfs_ref.c +--- linux-2.6.31.1/fs/cifs/cifs_dfs_ref.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/cifs/cifs_dfs_ref.c 2009-10-01 20:12:44.000000000 -0400 +@@ -385,7 +385,7 @@ out_err: + goto out; + } + +-struct inode_operations cifs_dfs_referral_inode_operations = { ++const struct inode_operations cifs_dfs_referral_inode_operations = { + .follow_link = cifs_dfs_follow_mountpoint, + }; + +diff -urNp linux-2.6.31.1/fs/cifs/cifsfs.h linux-2.6.31.1/fs/cifs/cifsfs.h +--- linux-2.6.31.1/fs/cifs/cifsfs.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/cifs/cifsfs.h 2009-10-01 20:12:44.000000000 -0400 +@@ -67,7 +67,7 @@ extern int cifs_setattr(struct dentry *, + + extern const struct inode_operations cifs_file_inode_ops; + extern const struct inode_operations cifs_symlink_inode_ops; +-extern struct inode_operations cifs_dfs_referral_inode_operations; ++extern const struct inode_operations cifs_dfs_referral_inode_operations; + + + /* Functions related to files and directories */ +diff -urNp linux-2.6.31.1/fs/cifs/cifs_uniupr.h linux-2.6.31.1/fs/cifs/cifs_uniupr.h +--- linux-2.6.31.1/fs/cifs/cifs_uniupr.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/cifs/cifs_uniupr.h 2009-10-01 20:12:44.000000000 -0400 +@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa + {0x0490, 0x04cc, UniCaseRangeU0490}, + {0x1e00, 0x1ffc, UniCaseRangeU1e00}, + {0xff40, 0xff5a, UniCaseRangeUff40}, +- {0} ++ {0, 0, NULL} + }; + #endif + +diff -urNp linux-2.6.31.1/fs/cifs/link.c linux-2.6.31.1/fs/cifs/link.c +--- linux-2.6.31.1/fs/cifs/link.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/cifs/link.c 2009-10-01 20:12:44.000000000 -0400 +@@ -215,7 +215,7 @@ cifs_symlink(struct inode *inode, struct + + void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie) + { +- char *p = nd_get_link(nd); ++ const char *p = nd_get_link(nd); + if (!IS_ERR(p)) + kfree(p); + } +diff -urNp linux-2.6.31.1/fs/compat_binfmt_elf.c linux-2.6.31.1/fs/compat_binfmt_elf.c +--- linux-2.6.31.1/fs/compat_binfmt_elf.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/compat_binfmt_elf.c 2009-10-01 20:12:44.000000000 -0400 +@@ -29,10 +29,12 @@ + #undef elfhdr + #undef elf_phdr + #undef elf_note ++#undef elf_dyn + #undef elf_addr_t + #define elfhdr elf32_hdr + #define elf_phdr elf32_phdr + #define elf_note elf32_note ++#define elf_dyn Elf32_Dyn + #define elf_addr_t Elf32_Addr + + /* +diff -urNp linux-2.6.31.1/fs/compat.c linux-2.6.31.1/fs/compat.c +--- linux-2.6.31.1/fs/compat.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/compat.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1417,14 +1417,12 @@ static int compat_copy_strings(int argc, + if (!kmapped_page || kpos != (pos & PAGE_MASK)) { + struct page *page; + +-#ifdef CONFIG_STACK_GROWSUP + ret = expand_stack_downwards(bprm->vma, pos); + if (ret < 0) { + /* We've exceed the stack rlimit. */ + ret = -E2BIG; + goto out; + } +-#endif + ret = get_user_pages(current, bprm->mm, pos, + 1, 1, 1, &page, NULL); + if (ret <= 0) { +@@ -1470,6 +1468,11 @@ int compat_do_execve(char * filename, + compat_uptr_t __user *envp, + struct pt_regs * regs) + { ++#ifdef CONFIG_GRKERNSEC ++ struct file *old_exec_file; ++ struct acl_subject_label *old_acl; ++ struct rlimit old_rlim[RLIM_NLIMITS]; ++#endif + struct linux_binprm *bprm; + struct file *file; + struct files_struct *displaced; +@@ -1506,6 +1509,14 @@ int compat_do_execve(char * filename, + bprm->filename = filename; + bprm->interp = filename; + ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->cred->user->processes), 1); ++ retval = -EAGAIN; ++ if (gr_handle_nproc()) ++ goto out_file; ++ retval = -EACCES; ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) ++ goto out_file; ++ + retval = bprm_mm_init(bprm); + if (retval) + goto out_file; +@@ -1535,9 +1546,40 @@ int compat_do_execve(char * filename, + if (retval < 0) + goto out; + ++ if (!gr_tpe_allow(file)) { ++ retval = -EACCES; ++ goto out; ++ } ++ ++ if (gr_check_crash_exec(file)) { ++ retval = -EACCES; ++ goto out; ++ } ++ ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); ++ ++ gr_handle_exec_args(bprm, (char __user * __user *)argv); ++ ++#ifdef CONFIG_GRKERNSEC ++ old_acl = current->acl; ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim)); ++ old_exec_file = current->exec_file; ++ get_file(file); ++ current->exec_file = file; ++#endif ++ ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt, ++ bprm->unsafe & LSM_UNSAFE_SHARE); ++ if (retval < 0) ++ goto out_fail; ++ + retval = search_binary_handler(bprm, regs); + if (retval < 0) +- goto out; ++ goto out_fail; ++#ifdef CONFIG_GRKERNSEC ++ if (old_exec_file) ++ fput(old_exec_file); ++#endif + + /* execve succeeded */ + current->fs->in_exec = 0; +@@ -1548,6 +1590,14 @@ int compat_do_execve(char * filename, + put_files_struct(displaced); + return retval; + ++out_fail: ++#ifdef CONFIG_GRKERNSEC ++ current->acl = old_acl; ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim)); ++ fput(current->exec_file); ++ current->exec_file = old_exec_file; ++#endif ++ + out: + if (bprm->mm) + mmput(bprm->mm); +diff -urNp linux-2.6.31.1/fs/compat_ioctl.c linux-2.6.31.1/fs/compat_ioctl.c +--- linux-2.6.31.1/fs/compat_ioctl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/compat_ioctl.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1827,15 +1827,15 @@ struct ioctl_trans { + }; + + #define HANDLE_IOCTL(cmd,handler) \ +- { (cmd), (ioctl_trans_handler_t)(handler) }, ++ { (cmd), (ioctl_trans_handler_t)(handler), NULL }, + + /* pointer to compatible structure or no argument */ + #define COMPATIBLE_IOCTL(cmd) \ +- { (cmd), do_ioctl32_pointer }, ++ { (cmd), do_ioctl32_pointer, NULL }, + + /* argument is an unsigned long integer, not a pointer */ + #define ULONG_IOCTL(cmd) \ +- { (cmd), (ioctl_trans_handler_t)sys_ioctl }, ++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL }, + + /* ioctl should not be warned about even if it's not implemented. + Valid reasons to use this: +diff -urNp linux-2.6.31.1/fs/debugfs/inode.c linux-2.6.31.1/fs/debugfs/inode.c +--- linux-2.6.31.1/fs/debugfs/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/debugfs/inode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -118,7 +118,7 @@ static inline int debugfs_positive(struc + + static int debug_fill_super(struct super_block *sb, void *data, int silent) + { +- static struct tree_descr debug_files[] = {{""}}; ++ static struct tree_descr debug_files[] = {{"", NULL, 0}}; + + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files); + } +diff -urNp linux-2.6.31.1/fs/dlm/debug_fs.c linux-2.6.31.1/fs/dlm/debug_fs.c +--- linux-2.6.31.1/fs/dlm/debug_fs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/dlm/debug_fs.c 2009-10-01 20:12:44.000000000 -0400 +@@ -386,9 +386,9 @@ static int table_seq_show(struct seq_fil + return rv; + } + +-static struct seq_operations format1_seq_ops; +-static struct seq_operations format2_seq_ops; +-static struct seq_operations format3_seq_ops; ++static const struct seq_operations format1_seq_ops; ++static const struct seq_operations format2_seq_ops; ++static const struct seq_operations format3_seq_ops; + + static void *table_seq_start(struct seq_file *seq, loff_t *pos) + { +@@ -534,21 +534,21 @@ static void table_seq_stop(struct seq_fi + } + } + +-static struct seq_operations format1_seq_ops = { ++static const struct seq_operations format1_seq_ops = { + .start = table_seq_start, + .next = table_seq_next, + .stop = table_seq_stop, + .show = table_seq_show, + }; + +-static struct seq_operations format2_seq_ops = { ++static const struct seq_operations format2_seq_ops = { + .start = table_seq_start, + .next = table_seq_next, + .stop = table_seq_stop, + .show = table_seq_show, + }; + +-static struct seq_operations format3_seq_ops = { ++static const struct seq_operations format3_seq_ops = { + .start = table_seq_start, + .next = table_seq_next, + .stop = table_seq_stop, +diff -urNp linux-2.6.31.1/fs/ecryptfs/ecryptfs_kernel.h linux-2.6.31.1/fs/ecryptfs/ecryptfs_kernel.h +--- linux-2.6.31.1/fs/ecryptfs/ecryptfs_kernel.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ecryptfs/ecryptfs_kernel.h 2009-10-01 20:12:44.000000000 -0400 +@@ -582,7 +582,7 @@ extern const struct inode_operations ecr + extern const struct inode_operations ecryptfs_symlink_iops; + extern const struct super_operations ecryptfs_sops; + extern const struct dentry_operations ecryptfs_dops; +-extern struct address_space_operations ecryptfs_aops; ++extern const struct address_space_operations ecryptfs_aops; + extern int ecryptfs_verbosity; + extern unsigned int ecryptfs_message_buf_len; + extern signed long ecryptfs_message_wait_timeout; +diff -urNp linux-2.6.31.1/fs/ecryptfs/mmap.c linux-2.6.31.1/fs/ecryptfs/mmap.c +--- linux-2.6.31.1/fs/ecryptfs/mmap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ecryptfs/mmap.c 2009-10-01 20:12:44.000000000 -0400 +@@ -545,7 +545,7 @@ static sector_t ecryptfs_bmap(struct add + return rc; + } + +-struct address_space_operations ecryptfs_aops = { ++const struct address_space_operations ecryptfs_aops = { + .writepage = ecryptfs_writepage, + .readpage = ecryptfs_readpage, + .write_begin = ecryptfs_write_begin, +diff -urNp linux-2.6.31.1/fs/exec.c linux-2.6.31.1/fs/exec.c +--- linux-2.6.31.1/fs/exec.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/exec.c 2009-10-01 20:12:44.000000000 -0400 +@@ -55,12 +55,24 @@ + #include <linux/kmod.h> + #include <linux/fsnotify.h> + #include <linux/fs_struct.h> ++#include <linux/random.h> ++#include <linux/seq_file.h> ++ ++#ifdef CONFIG_PAX_REFCOUNT ++#include <linux/kallsyms.h> ++#include <linux/kdebug.h> ++#endif + + #include <asm/uaccess.h> + #include <asm/mmu_context.h> + #include <asm/tlb.h> + #include "internal.h" + ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm); ++EXPORT_SYMBOL(pax_set_initial_flags_func); ++#endif ++ + int core_uses_pid; + char core_pattern[CORENAME_MAX_SIZE] = "core"; + int suid_dumpable = 0; +@@ -113,7 +125,7 @@ SYSCALL_DEFINE1(uselib, const char __use + goto out; + + file = do_filp_open(AT_FDCWD, tmp, +- O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, ++ O_LARGEFILE | O_RDONLY | FMODE_EXEC | FMODE_GREXEC, 0, + MAY_READ | MAY_EXEC | MAY_OPEN); + putname(tmp); + error = PTR_ERR(file); +@@ -161,18 +173,10 @@ static struct page *get_arg_page(struct + int write) + { + struct page *page; +- int ret; + +-#ifdef CONFIG_STACK_GROWSUP +- if (write) { +- ret = expand_stack_downwards(bprm->vma, pos); +- if (ret < 0) +- return NULL; +- } +-#endif +- ret = get_user_pages(current, bprm->mm, pos, +- 1, write, 1, &page, NULL); +- if (ret <= 0) ++ if (0 > expand_stack_downwards(bprm->vma, pos)) ++ return NULL; ++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL)) + return NULL; + + if (write) { +@@ -244,6 +248,11 @@ static int __bprm_mm_init(struct linux_b + vma->vm_end = STACK_TOP_MAX; + vma->vm_start = vma->vm_end - PAGE_SIZE; + vma->vm_flags = VM_STACK_FLAGS; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC); ++#endif ++ + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + err = insert_vm_struct(mm, vma); + if (err) +@@ -252,6 +261,12 @@ static int __bprm_mm_init(struct linux_b + mm->stack_vm = mm->total_vm = 1; + up_write(&mm->mmap_sem); + bprm->p = vma->vm_end - sizeof(void *); ++ ++#ifdef CONFIG_PAX_RANDUSTACK ++ if (randomize_va_space) ++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK; ++#endif ++ + return 0; + err: + up_write(&mm->mmap_sem); +@@ -503,7 +518,8 @@ static int shift_arg_pages(struct vm_are + unsigned long new_end = old_end - shift; + struct mmu_gather *tlb; + +- BUG_ON(new_start > new_end); ++ if (new_start >= new_end || new_start < mmap_min_addr) ++ return -EFAULT; + + /* + * ensure there are no vmas between where we want to go +@@ -512,6 +528,10 @@ static int shift_arg_pages(struct vm_are + if (vma != find_vma(mm, new_start)) + return -EFAULT; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ BUG_ON(pax_find_mirror_vma(vma)); ++#endif ++ + /* + * cover the whole range: [new_start, old_end) + */ +@@ -600,6 +620,14 @@ int setup_arg_pages(struct linux_binprm + bprm->exec -= stack_shift; + + down_write(&mm->mmap_sem); ++ ++ /* Move stack pages down in memory. */ ++ if (stack_shift) { ++ ret = shift_arg_pages(vma, stack_shift); ++ if (ret) ++ goto out_unlock; ++ } ++ + vm_flags = VM_STACK_FLAGS; + + /* +@@ -613,21 +641,24 @@ int setup_arg_pages(struct linux_binprm + vm_flags &= ~VM_EXEC; + vm_flags |= mm->def_flags; + ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { ++ vm_flags &= ~VM_EXEC; ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if (mm->pax_flags & MF_PAX_MPROTECT) ++ vm_flags &= ~VM_MAYEXEC; ++#endif ++ ++ } ++#endif ++ + ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end, + vm_flags); + if (ret) + goto out_unlock; + BUG_ON(prev != vma); + +- /* Move stack pages down in memory. */ +- if (stack_shift) { +- ret = shift_arg_pages(vma, stack_shift); +- if (ret) { +- up_write(&mm->mmap_sem); +- return ret; +- } +- } +- + #ifdef CONFIG_STACK_GROWSUP + stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE; + #else +@@ -639,7 +670,7 @@ int setup_arg_pages(struct linux_binprm + + out_unlock: + up_write(&mm->mmap_sem); +- return 0; ++ return ret; + } + EXPORT_SYMBOL(setup_arg_pages); + +@@ -651,7 +682,7 @@ struct file *open_exec(const char *name) + int err; + + file = do_filp_open(AT_FDCWD, name, +- O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, ++ O_LARGEFILE | O_RDONLY | FMODE_EXEC | FMODE_GREXEC, 0, + MAY_EXEC | MAY_OPEN); + if (IS_ERR(file)) + goto out; +@@ -1085,7 +1116,7 @@ int check_unsafe_exec(struct linux_binpr + } + rcu_read_unlock(); + +- if (p->fs->users > n_fs) { ++ if (atomic_read(&p->fs->users) > n_fs) { + bprm->unsafe |= LSM_UNSAFE_SHARE; + } else { + res = -EAGAIN; +@@ -1284,6 +1315,11 @@ int do_execve(char * filename, + char __user *__user *envp, + struct pt_regs * regs) + { ++#ifdef CONFIG_GRKERNSEC ++ struct file *old_exec_file; ++ struct acl_subject_label *old_acl; ++ struct rlimit old_rlim[RLIM_NLIMITS]; ++#endif + struct linux_binprm *bprm; + struct file *file; + struct files_struct *displaced; +@@ -1320,6 +1356,18 @@ int do_execve(char * filename, + bprm->filename = filename; + bprm->interp = filename; + ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->cred->user->processes), 1); ++ ++ if (gr_handle_nproc()) { ++ retval = -EAGAIN; ++ goto out_file; ++ } ++ ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) { ++ retval = -EACCES; ++ goto out_file; ++ } ++ + retval = bprm_mm_init(bprm); + if (retval) + goto out_file; +@@ -1349,10 +1397,41 @@ int do_execve(char * filename, + if (retval < 0) + goto out; + ++ if (!gr_tpe_allow(file)) { ++ retval = -EACCES; ++ goto out; ++ } ++ ++ if (gr_check_crash_exec(file)) { ++ retval = -EACCES; ++ goto out; ++ } ++ ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); ++ ++ gr_handle_exec_args(bprm, argv); ++ ++#ifdef CONFIG_GRKERNSEC ++ old_acl = current->acl; ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim)); ++ old_exec_file = current->exec_file; ++ get_file(file); ++ current->exec_file = file; ++#endif ++ ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt, ++ bprm->unsafe & LSM_UNSAFE_SHARE); ++ if (retval < 0) ++ goto out_fail; ++ + current->flags &= ~PF_KTHREAD; + retval = search_binary_handler(bprm,regs); + if (retval < 0) +- goto out; ++ goto out_fail; ++#ifdef CONFIG_GRKERNSEC ++ if (old_exec_file) ++ fput(old_exec_file); ++#endif + + /* execve succeeded */ + current->fs->in_exec = 0; +@@ -1363,6 +1442,14 @@ int do_execve(char * filename, + put_files_struct(displaced); + return retval; + ++out_fail: ++#ifdef CONFIG_GRKERNSEC ++ current->acl = old_acl; ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim)); ++ fput(current->exec_file); ++ current->exec_file = old_exec_file; ++#endif ++ + out: + if (bprm->mm) + mmput (bprm->mm); +@@ -1528,6 +1615,164 @@ out: + return ispipe; + } + ++int pax_check_flags(unsigned long *flags) ++{ ++ int retval = 0; ++ ++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC) ++ if (*flags & MF_PAX_SEGMEXEC) ++ { ++ *flags &= ~MF_PAX_SEGMEXEC; ++ retval = -EINVAL; ++ } ++#endif ++ ++ if ((*flags & MF_PAX_PAGEEXEC) ++ ++#ifdef CONFIG_PAX_PAGEEXEC ++ && (*flags & MF_PAX_SEGMEXEC) ++#endif ++ ++ ) ++ { ++ *flags &= ~MF_PAX_PAGEEXEC; ++ retval = -EINVAL; ++ } ++ ++ if ((*flags & MF_PAX_MPROTECT) ++ ++#ifdef CONFIG_PAX_MPROTECT ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) ++#endif ++ ++ ) ++ { ++ *flags &= ~MF_PAX_MPROTECT; ++ retval = -EINVAL; ++ } ++ ++ if ((*flags & MF_PAX_EMUTRAMP) ++ ++#ifdef CONFIG_PAX_EMUTRAMP ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) ++#endif ++ ++ ) ++ { ++ *flags &= ~MF_PAX_EMUTRAMP; ++ retval = -EINVAL; ++ } ++ ++ return retval; ++} ++ ++EXPORT_SYMBOL(pax_check_flags); ++ ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp) ++{ ++ struct task_struct *tsk = current; ++ struct mm_struct *mm = current->mm; ++ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL); ++ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL); ++ char *path_exec = NULL; ++ char *path_fault = NULL; ++ unsigned long start = 0UL, end = 0UL, offset = 0UL; ++ ++ if (buffer_exec && buffer_fault) { ++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL; ++ ++ down_read(&mm->mmap_sem); ++ vma = mm->mmap; ++ while (vma && (!vma_exec || !vma_fault)) { ++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) ++ vma_exec = vma; ++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end) ++ vma_fault = vma; ++ vma = vma->vm_next; ++ } ++ if (vma_exec) { ++ path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE); ++ if (IS_ERR(path_exec)) ++ path_exec = "<path too long>"; ++ else { ++ path_exec = mangle_path(buffer_exec, path_exec, "\t\n\"); ++ if (path_exec) { ++ *path_exec = 0; ++ path_exec = buffer_exec; ++ } else ++ path_exec = "<path too long>"; ++ } ++ } ++ if (vma_fault) { ++ start = vma_fault->vm_start; ++ end = vma_fault->vm_end; ++ offset = vma_fault->vm_pgoff << PAGE_SHIFT; ++ if (vma_fault->vm_file) { ++ path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE); ++ if (IS_ERR(path_fault)) ++ path_fault = "<path too long>"; ++ else { ++ path_fault = mangle_path(buffer_fault, path_fault, "\t\n\"); ++ if (path_fault) { ++ *path_fault = 0; ++ path_fault = buffer_fault; ++ } else ++ path_fault = "<path too long>"; ++ } ++ } else ++ path_fault = "<anonymous mapping>"; ++ } ++ up_read(&mm->mmap_sem); ++ } ++ if (tsk->signal->curr_ip) ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: execution attempt in: %s, %08lx-%08lx %08lx\n", NIPQUAD(tsk->signal->curr_ip), path_fault, start, end, offset); ++ else ++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset); ++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, " ++ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk), ++ task_uid(tsk), task_euid(tsk), pc, sp); ++ free_page((unsigned long)buffer_exec); ++ free_page((unsigned long)buffer_fault); ++ pax_report_insns(pc, sp); ++ do_coredump(SIGKILL, SIGKILL, regs); ++} ++#endif ++ ++#ifdef CONFIG_PAX_REFCOUNT ++void pax_report_refcount_overflow(struct pt_regs *regs) ++{ ++ if (current->signal->curr_ip) ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n", ++ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current_uid(), current_euid()); ++ else ++ printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n", ++ current->comm, task_pid_nr(current), current_uid(), current_euid()); ++ print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs)); ++ show_regs(regs); ++ force_sig_specific(SIGKILL, current); ++} ++#endif ++ ++#ifdef CONFIG_PAX_USERCOPY ++void pax_report_leak_to_user(const void *ptr, unsigned long len) ++{ ++ if (current->signal->curr_ip) ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: kernel memory leak attempt detected from %p (%lu bytes)\n", NIPQUAD(current->signal->curr_ip), ptr, len); ++ else ++ printk(KERN_ERR "PAX: kernel memory leak attempt detected from %p (%lu bytes)\n", ptr, len); ++ dump_stack(); ++ do_group_exit(SIGKILL); ++} ++ ++void pax_report_overflow_from_user(const void *ptr, unsigned long len) ++{ ++ printk(KERN_ERR "PAX: kernel memory overflow attempt detected to %p (%lu bytes)\n", ptr, len); ++ dump_stack(); ++ do_group_exit(SIGKILL); ++} ++#endif ++ + static int zap_process(struct task_struct *start) + { + struct task_struct *t; +@@ -1787,6 +2032,10 @@ void do_coredump(long signr, int exit_co + */ + clear_thread_flag(TIF_SIGPENDING); + ++ if (signr == SIGKILL || signr == SIGILL) ++ gr_handle_brute_attach(current); ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1); ++ + /* + * lock_kernel() because format_corename() is controlled by sysctl, which + * uses lock_kernel() +diff -urNp linux-2.6.31.1/fs/ext2/balloc.c linux-2.6.31.1/fs/ext2/balloc.c +--- linux-2.6.31.1/fs/ext2/balloc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ext2/balloc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e + + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) && + sbi->s_resuid != current_fsuid() && + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { + return 0; +diff -urNp linux-2.6.31.1/fs/ext3/balloc.c linux-2.6.31.1/fs/ext3/balloc.c +--- linux-2.6.31.1/fs/ext3/balloc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ext3/balloc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e + + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) && + sbi->s_resuid != current_fsuid() && + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { + return 0; +diff -urNp linux-2.6.31.1/fs/ext3/namei.c linux-2.6.31.1/fs/ext3/namei.c +--- linux-2.6.31.1/fs/ext3/namei.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ext3/namei.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1168,7 +1168,7 @@ static struct ext3_dir_entry_2 *do_split + char *data1 = (*bh)->b_data, *data2; + unsigned split, move, size; + struct ext3_dir_entry_2 *de = NULL, *de2; +- int err = 0, i; ++ int i, err = 0; + + bh2 = ext3_append (handle, dir, &newblock, &err); + if (!(bh2)) { +diff -urNp linux-2.6.31.1/fs/ext3/xattr.c linux-2.6.31.1/fs/ext3/xattr.c +--- linux-2.6.31.1/fs/ext3/xattr.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ext3/xattr.c 2009-10-01 20:12:44.000000000 -0400 +@@ -89,8 +89,8 @@ + printk("\n"); \ + } while (0) + #else +-# define ea_idebug(f...) +-# define ea_bdebug(f...) ++# define ea_idebug(f...) do {} while (0) ++# define ea_bdebug(f...) do {} while (0) + #endif + + static void ext3_xattr_cache_insert(struct buffer_head *); +diff -urNp linux-2.6.31.1/fs/ext4/balloc.c linux-2.6.31.1/fs/ext4/balloc.c +--- linux-2.6.31.1/fs/ext4/balloc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ext4/balloc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -573,7 +573,7 @@ int ext4_has_free_blocks(struct ext4_sb_ + /* Hm, nope. Are (enough) root reserved blocks available? */ + if (sbi->s_resuid == current_fsuid() || + ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) || +- capable(CAP_SYS_RESOURCE)) { ++ capable_nolog(CAP_SYS_RESOURCE)) { + if (free_blocks >= (nblocks + dirty_blocks)) + return 1; + } +diff -urNp linux-2.6.31.1/fs/ext4/file.c linux-2.6.31.1/fs/ext4/file.c +--- linux-2.6.31.1/fs/ext4/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ext4/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -130,7 +130,7 @@ force_commit: + return ret; + } + +-static struct vm_operations_struct ext4_file_vm_ops = { ++static const struct vm_operations_struct ext4_file_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = ext4_page_mkwrite, + }; +diff -urNp linux-2.6.31.1/fs/ext4/mballoc.c linux-2.6.31.1/fs/ext4/mballoc.c +--- linux-2.6.31.1/fs/ext4/mballoc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ext4/mballoc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -2205,7 +2205,7 @@ static void ext4_mb_seq_history_stop(str + { + } + +-static struct seq_operations ext4_mb_seq_history_ops = { ++static const struct seq_operations ext4_mb_seq_history_ops = { + .start = ext4_mb_seq_history_start, + .next = ext4_mb_seq_history_next, + .stop = ext4_mb_seq_history_stop, +@@ -2287,7 +2287,7 @@ static ssize_t ext4_mb_seq_history_write + return count; + } + +-static struct file_operations ext4_mb_seq_history_fops = { ++static const struct file_operations ext4_mb_seq_history_fops = { + .owner = THIS_MODULE, + .open = ext4_mb_seq_history_open, + .read = seq_read, +@@ -2366,7 +2366,7 @@ static void ext4_mb_seq_groups_stop(stru + { + } + +-static struct seq_operations ext4_mb_seq_groups_ops = { ++static const struct seq_operations ext4_mb_seq_groups_ops = { + .start = ext4_mb_seq_groups_start, + .next = ext4_mb_seq_groups_next, + .stop = ext4_mb_seq_groups_stop, +@@ -2387,7 +2387,7 @@ static int ext4_mb_seq_groups_open(struc + + } + +-static struct file_operations ext4_mb_seq_groups_fops = { ++static const struct file_operations ext4_mb_seq_groups_fops = { + .owner = THIS_MODULE, + .open = ext4_mb_seq_groups_open, + .read = seq_read, +diff -urNp linux-2.6.31.1/fs/ext4/namei.c linux-2.6.31.1/fs/ext4/namei.c +--- linux-2.6.31.1/fs/ext4/namei.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ext4/namei.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1203,7 +1203,7 @@ static struct ext4_dir_entry_2 *do_split + char *data1 = (*bh)->b_data, *data2; + unsigned split, move, size; + struct ext4_dir_entry_2 *de = NULL, *de2; +- int err = 0, i; ++ int i, err = 0; + + bh2 = ext4_append (handle, dir, &newblock, &err); + if (!(bh2)) { +diff -urNp linux-2.6.31.1/fs/fcntl.c linux-2.6.31.1/fs/fcntl.c +--- linux-2.6.31.1/fs/fcntl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/fcntl.c 2009-10-01 20:12:44.000000000 -0400 +@@ -271,6 +271,7 @@ static long do_fcntl(int fd, unsigned in + switch (cmd) { + case F_DUPFD: + case F_DUPFD_CLOEXEC: ++ gr_learn_resource(current, RLIMIT_NOFILE, arg, 0); + if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) + break; + err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0); +@@ -421,7 +422,8 @@ static inline int sigio_perm(struct task + ret = ((fown->euid == 0 || + fown->euid == cred->suid || fown->euid == cred->uid || + fown->uid == cred->suid || fown->uid == cred->uid) && +- !security_file_send_sigiotask(p, fown, sig)); ++ !security_file_send_sigiotask(p, fown, sig) && ++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p)); + rcu_read_unlock(); + return ret; + } +diff -urNp linux-2.6.31.1/fs/file.c linux-2.6.31.1/fs/file.c +--- linux-2.6.31.1/fs/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -13,6 +13,7 @@ + #include <linux/slab.h> + #include <linux/vmalloc.h> + #include <linux/file.h> ++#include <linux/security.h> + #include <linux/fdtable.h> + #include <linux/bitops.h> + #include <linux/interrupt.h> +@@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi + * N.B. For clone tasks sharing a files structure, this test + * will limit the total number of files that can be opened. + */ ++ ++ gr_learn_resource(current, RLIMIT_NOFILE, nr, 0); + if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) + return -EMFILE; + +diff -urNp linux-2.6.31.1/fs/fs_struct.c linux-2.6.31.1/fs/fs_struct.c +--- linux-2.6.31.1/fs/fs_struct.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/fs_struct.c 2009-10-01 20:12:44.000000000 -0400 +@@ -89,7 +89,7 @@ void exit_fs(struct task_struct *tsk) + task_lock(tsk); + write_lock(&fs->lock); + tsk->fs = NULL; +- kill = !--fs->users; ++ kill = !atomic_dec_return(&fs->users); + write_unlock(&fs->lock); + task_unlock(tsk); + if (kill) +@@ -102,7 +102,7 @@ struct fs_struct *copy_fs_struct(struct + struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL); + /* We don't need to lock fs - think why ;-) */ + if (fs) { +- fs->users = 1; ++ atomic_set(&fs->users, 1); + fs->in_exec = 0; + rwlock_init(&fs->lock); + fs->umask = old->umask; +@@ -127,7 +127,7 @@ int unshare_fs_struct(void) + + task_lock(current); + write_lock(&fs->lock); +- kill = !--fs->users; ++ kill = !atomic_dec_return(&fs->users); + current->fs = new_fs; + write_unlock(&fs->lock); + task_unlock(current); +@@ -147,7 +147,7 @@ EXPORT_SYMBOL(current_umask); + + /* to be mentioned only in INIT_TASK */ + struct fs_struct init_fs = { +- .users = 1, ++ .users = ATOMIC_INIT(1), + .lock = __RW_LOCK_UNLOCKED(init_fs.lock), + .umask = 0022, + }; +@@ -162,12 +162,12 @@ void daemonize_fs_struct(void) + task_lock(current); + + write_lock(&init_fs.lock); +- init_fs.users++; ++ atomic_inc(&init_fs.users); + write_unlock(&init_fs.lock); + + write_lock(&fs->lock); + current->fs = &init_fs; +- kill = !--fs->users; ++ kill = !atomic_dec_return(&fs->users); + write_unlock(&fs->lock); + + task_unlock(current); +diff -urNp linux-2.6.31.1/fs/fuse/control.c linux-2.6.31.1/fs/fuse/control.c +--- linux-2.6.31.1/fs/fuse/control.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/fuse/control.c 2009-10-01 20:12:44.000000000 -0400 +@@ -161,7 +161,7 @@ void fuse_ctl_remove_conn(struct fuse_co + + static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent) + { +- struct tree_descr empty_descr = {""}; ++ struct tree_descr empty_descr = {"", NULL, 0}; + struct fuse_conn *fc; + int err; + +diff -urNp linux-2.6.31.1/fs/fuse/dev.c linux-2.6.31.1/fs/fuse/dev.c +--- linux-2.6.31.1/fs/fuse/dev.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/fuse/dev.c 2009-10-01 20:12:44.000000000 -0400 +@@ -885,7 +885,7 @@ static int fuse_notify_inval_entry(struc + { + struct fuse_notify_inval_entry_out outarg; + int err = -EINVAL; +- char buf[FUSE_NAME_MAX+1]; ++ char *buf = NULL; + struct qstr name; + + if (size < sizeof(outarg)) +@@ -899,6 +899,11 @@ static int fuse_notify_inval_entry(struc + if (outarg.namelen > FUSE_NAME_MAX) + goto err; + ++ err = -ENOMEM; ++ buf = kmalloc(FUSE_NAME_MAX+1, GFP_KERNEL); ++ if (!buf) ++ goto err; ++ + name.name = buf; + name.len = outarg.namelen; + err = fuse_copy_one(cs, buf, outarg.namelen + 1); +@@ -910,17 +915,15 @@ static int fuse_notify_inval_entry(struc + + down_read(&fc->killsb); + err = -ENOENT; +- if (!fc->sb) +- goto err_unlock; +- +- err = fuse_reverse_inval_entry(fc->sb, outarg.parent, &name); +- +-err_unlock: ++ if (fc->sb) ++ err = fuse_reverse_inval_entry(fc->sb, outarg.parent, &name); + up_read(&fc->killsb); ++ kfree(buf); + return err; + + err: + fuse_copy_finish(cs); ++ kfree(buf); + return err; + } + +diff -urNp linux-2.6.31.1/fs/fuse/dir.c linux-2.6.31.1/fs/fuse/dir.c +--- linux-2.6.31.1/fs/fuse/dir.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/fuse/dir.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1122,7 +1122,7 @@ static char *read_link(struct dentry *de + return link; + } + +-static void free_link(char *link) ++static void free_link(const char *link) + { + if (!IS_ERR(link)) + free_page((unsigned long) link); +diff -urNp linux-2.6.31.1/fs/fuse/file.c linux-2.6.31.1/fs/fuse/file.c +--- linux-2.6.31.1/fs/fuse/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/fuse/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1313,7 +1313,7 @@ static int fuse_page_mkwrite(struct vm_a + return 0; + } + +-static struct vm_operations_struct fuse_file_vm_ops = { ++static const struct vm_operations_struct fuse_file_vm_ops = { + .close = fuse_vma_close, + .fault = filemap_fault, + .page_mkwrite = fuse_page_mkwrite, +diff -urNp linux-2.6.31.1/fs/gfs2/file.c linux-2.6.31.1/fs/gfs2/file.c +--- linux-2.6.31.1/fs/gfs2/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/gfs2/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -419,7 +419,7 @@ out: + return ret; + } + +-static struct vm_operations_struct gfs2_vm_ops = { ++static const struct vm_operations_struct gfs2_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = gfs2_page_mkwrite, + }; +diff -urNp linux-2.6.31.1/fs/hfs/inode.c linux-2.6.31.1/fs/hfs/inode.c +--- linux-2.6.31.1/fs/hfs/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/hfs/inode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -423,7 +423,7 @@ int hfs_write_inode(struct inode *inode, + + if (S_ISDIR(main_inode->i_mode)) { + if (fd.entrylength < sizeof(struct hfs_cat_dir)) +- /* panic? */; ++ {/* panic? */} + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, + sizeof(struct hfs_cat_dir)); + if (rec.type != HFS_CDR_DIR || +@@ -444,7 +444,7 @@ int hfs_write_inode(struct inode *inode, + sizeof(struct hfs_cat_file)); + } else { + if (fd.entrylength < sizeof(struct hfs_cat_file)) +- /* panic? */; ++ {/* panic? */} + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, + sizeof(struct hfs_cat_file)); + if (rec.type != HFS_CDR_FIL || +diff -urNp linux-2.6.31.1/fs/hfsplus/inode.c linux-2.6.31.1/fs/hfsplus/inode.c +--- linux-2.6.31.1/fs/hfsplus/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/hfsplus/inode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -406,7 +406,7 @@ int hfsplus_cat_read_inode(struct inode + struct hfsplus_cat_folder *folder = &entry.folder; + + if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) +- /* panic? */; ++ {/* panic? */} + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_folder)); + hfsplus_get_perms(inode, &folder->permissions, 1); +@@ -423,7 +423,7 @@ int hfsplus_cat_read_inode(struct inode + struct hfsplus_cat_file *file = &entry.file; + + if (fd->entrylength < sizeof(struct hfsplus_cat_file)) +- /* panic? */; ++ {/* panic? */} + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_file)); + +@@ -479,7 +479,7 @@ int hfsplus_cat_write_inode(struct inode + struct hfsplus_cat_folder *folder = &entry.folder; + + if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) +- /* panic? */; ++ {/* panic? */} + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, + sizeof(struct hfsplus_cat_folder)); + /* simple node checks? */ +@@ -501,7 +501,7 @@ int hfsplus_cat_write_inode(struct inode + struct hfsplus_cat_file *file = &entry.file; + + if (fd.entrylength < sizeof(struct hfsplus_cat_file)) +- /* panic? */; ++ {/* panic? */} + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, + sizeof(struct hfsplus_cat_file)); + hfsplus_inode_write_fork(inode, &file->data_fork); +diff -urNp linux-2.6.31.1/fs/jbd2/journal.c linux-2.6.31.1/fs/jbd2/journal.c +--- linux-2.6.31.1/fs/jbd2/journal.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/jbd2/journal.c 2009-10-01 20:12:44.000000000 -0400 +@@ -768,7 +768,7 @@ static void jbd2_seq_history_stop(struct + { + } + +-static struct seq_operations jbd2_seq_history_ops = { ++static const struct seq_operations jbd2_seq_history_ops = { + .start = jbd2_seq_history_start, + .next = jbd2_seq_history_next, + .stop = jbd2_seq_history_stop, +@@ -818,7 +818,7 @@ static int jbd2_seq_history_release(stru + return seq_release(inode, file); + } + +-static struct file_operations jbd2_seq_history_fops = { ++static const struct file_operations jbd2_seq_history_fops = { + .owner = THIS_MODULE, + .open = jbd2_seq_history_open, + .read = seq_read, +@@ -872,7 +872,7 @@ static void jbd2_seq_info_stop(struct se + { + } + +-static struct seq_operations jbd2_seq_info_ops = { ++static const struct seq_operations jbd2_seq_info_ops = { + .start = jbd2_seq_info_start, + .next = jbd2_seq_info_next, + .stop = jbd2_seq_info_stop, +@@ -920,7 +920,7 @@ static int jbd2_seq_info_release(struct + return seq_release(inode, file); + } + +-static struct file_operations jbd2_seq_info_fops = { ++static const struct file_operations jbd2_seq_info_fops = { + .owner = THIS_MODULE, + .open = jbd2_seq_info_open, + .read = seq_read, +diff -urNp linux-2.6.31.1/fs/jffs2/debug.h linux-2.6.31.1/fs/jffs2/debug.h +--- linux-2.6.31.1/fs/jffs2/debug.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/jffs2/debug.h 2009-10-01 20:12:44.000000000 -0400 +@@ -52,13 +52,13 @@ + #if CONFIG_JFFS2_FS_DEBUG > 0 + #define D1(x) x + #else +-#define D1(x) ++#define D1(x) do {} while (0); + #endif + + #if CONFIG_JFFS2_FS_DEBUG > 1 + #define D2(x) x + #else +-#define D2(x) ++#define D2(x) do {} while (0); + #endif + + /* The prefixes of JFFS2 messages */ +@@ -114,73 +114,73 @@ + #ifdef JFFS2_DBG_READINODE_MESSAGES + #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_readinode(fmt, ...) ++#define dbg_readinode(fmt, ...) do {} while (0) + #endif + #ifdef JFFS2_DBG_READINODE2_MESSAGES + #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_readinode2(fmt, ...) ++#define dbg_readinode2(fmt, ...) do {} while (0) + #endif + + /* Fragtree build debugging messages */ + #ifdef JFFS2_DBG_FRAGTREE_MESSAGES + #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_fragtree(fmt, ...) ++#define dbg_fragtree(fmt, ...) do {} while (0) + #endif + #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES + #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_fragtree2(fmt, ...) ++#define dbg_fragtree2(fmt, ...) do {} while (0) + #endif + + /* Directory entry list manilulation debugging messages */ + #ifdef JFFS2_DBG_DENTLIST_MESSAGES + #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_dentlist(fmt, ...) ++#define dbg_dentlist(fmt, ...) do {} while (0) + #endif + + /* Print the messages about manipulating node_refs */ + #ifdef JFFS2_DBG_NODEREF_MESSAGES + #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_noderef(fmt, ...) ++#define dbg_noderef(fmt, ...) do {} while (0) + #endif + + /* Manipulations with the list of inodes (JFFS2 inocache) */ + #ifdef JFFS2_DBG_INOCACHE_MESSAGES + #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_inocache(fmt, ...) ++#define dbg_inocache(fmt, ...) do {} while (0) + #endif + + /* Summary debugging messages */ + #ifdef JFFS2_DBG_SUMMARY_MESSAGES + #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_summary(fmt, ...) ++#define dbg_summary(fmt, ...) do {} while (0) + #endif + + /* File system build messages */ + #ifdef JFFS2_DBG_FSBUILD_MESSAGES + #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_fsbuild(fmt, ...) ++#define dbg_fsbuild(fmt, ...) do {} while (0) + #endif + + /* Watch the object allocations */ + #ifdef JFFS2_DBG_MEMALLOC_MESSAGES + #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_memalloc(fmt, ...) ++#define dbg_memalloc(fmt, ...) do {} while (0) + #endif + + /* Watch the XATTR subsystem */ + #ifdef JFFS2_DBG_XATTR_MESSAGES + #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) + #else +-#define dbg_xattr(fmt, ...) ++#define dbg_xattr(fmt, ...) do {} while (0) + #endif + + /* "Sanity" checks */ +diff -urNp linux-2.6.31.1/fs/jffs2/erase.c linux-2.6.31.1/fs/jffs2/erase.c +--- linux-2.6.31.1/fs/jffs2/erase.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/jffs2/erase.c 2009-10-01 20:12:44.000000000 -0400 +@@ -434,7 +434,8 @@ static void jffs2_mark_erased_block(stru + struct jffs2_unknown_node marker = { + .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK), + .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), +- .totlen = cpu_to_je32(c->cleanmarker_size) ++ .totlen = cpu_to_je32(c->cleanmarker_size), ++ .hdr_crc = cpu_to_je32(0) + }; + + jffs2_prealloc_raw_node_refs(c, jeb, 1); +diff -urNp linux-2.6.31.1/fs/jffs2/summary.h linux-2.6.31.1/fs/jffs2/summary.h +--- linux-2.6.31.1/fs/jffs2/summary.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/jffs2/summary.h 2009-10-01 20:12:44.000000000 -0400 +@@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_ + + #define jffs2_sum_active() (0) + #define jffs2_sum_init(a) (0) +-#define jffs2_sum_exit(a) +-#define jffs2_sum_disable_collecting(a) ++#define jffs2_sum_exit(a) do {} while (0) ++#define jffs2_sum_disable_collecting(a) do {} while (0) + #define jffs2_sum_is_disabled(a) (0) +-#define jffs2_sum_reset_collected(a) ++#define jffs2_sum_reset_collected(a) do {} while (0) + #define jffs2_sum_add_kvec(a,b,c,d) (0) +-#define jffs2_sum_move_collected(a,b) ++#define jffs2_sum_move_collected(a,b) do {} while (0) + #define jffs2_sum_write_sumnode(a) (0) +-#define jffs2_sum_add_padding_mem(a,b) +-#define jffs2_sum_add_inode_mem(a,b,c) +-#define jffs2_sum_add_dirent_mem(a,b,c) +-#define jffs2_sum_add_xattr_mem(a,b,c) +-#define jffs2_sum_add_xref_mem(a,b,c) ++#define jffs2_sum_add_padding_mem(a,b) do {} while (0) ++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0) ++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0) ++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0) ++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0) + #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0) + + #endif /* CONFIG_JFFS2_SUMMARY */ +diff -urNp linux-2.6.31.1/fs/jffs2/wbuf.c linux-2.6.31.1/fs/jffs2/wbuf.c +--- linux-2.6.31.1/fs/jffs2/wbuf.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/jffs2/wbuf.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1012,7 +1012,8 @@ static const struct jffs2_unknown_node o + { + .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK), + .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), +- .totlen = constant_cpu_to_je32(8) ++ .totlen = constant_cpu_to_je32(8), ++ .hdr_crc = constant_cpu_to_je32(0) + }; + + /* +diff -urNp linux-2.6.31.1/fs/locks.c linux-2.6.31.1/fs/locks.c +--- linux-2.6.31.1/fs/locks.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/locks.c 2009-10-01 20:12:44.000000000 -0400 +@@ -2007,16 +2007,16 @@ void locks_remove_flock(struct file *fil + return; + + if (filp->f_op && filp->f_op->flock) { +- struct file_lock fl = { ++ struct file_lock flock = { + .fl_pid = current->tgid, + .fl_file = filp, + .fl_flags = FL_FLOCK, + .fl_type = F_UNLCK, + .fl_end = OFFSET_MAX, + }; +- filp->f_op->flock(filp, F_SETLKW, &fl); +- if (fl.fl_ops && fl.fl_ops->fl_release_private) +- fl.fl_ops->fl_release_private(&fl); ++ filp->f_op->flock(filp, F_SETLKW, &flock); ++ if (flock.fl_ops && flock.fl_ops->fl_release_private) ++ flock.fl_ops->fl_release_private(&flock); + } + + lock_kernel(); +diff -urNp linux-2.6.31.1/fs/namei.c linux-2.6.31.1/fs/namei.c +--- linux-2.6.31.1/fs/namei.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/namei.c 2009-10-01 20:12:44.000000000 -0400 +@@ -631,7 +631,7 @@ static __always_inline int __do_follow_l + cookie = dentry->d_inode->i_op->follow_link(dentry, nd); + error = PTR_ERR(cookie); + if (!IS_ERR(cookie)) { +- char *s = nd_get_link(nd); ++ const char *s = nd_get_link(nd); + error = 0; + if (s) + error = __vfs_follow_link(nd, s); +@@ -662,6 +662,13 @@ static inline int do_follow_link(struct + err = security_inode_follow_link(path->dentry, nd); + if (err) + goto loop; ++ ++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode, ++ path->dentry->d_inode, path->dentry, nd->path.mnt)) { ++ err = -EACCES; ++ goto loop; ++ } ++ + current->link_count++; + current->total_link_count++; + nd->depth++; +@@ -1005,11 +1012,18 @@ return_reval: + break; + } + return_base: ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) { ++ path_put(&nd->path); ++ return -ENOENT; ++ } + return 0; + out_dput: + path_put_conditional(&next, nd); + break; + } ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) ++ err = -ENOENT; ++ + path_put(&nd->path); + return_err: + return err; +@@ -1608,12 +1622,19 @@ static int __open_namei_create(struct na + int error; + struct dentry *dir = nd->path.dentry; + ++ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) { ++ error = -EACCES; ++ goto out_unlock; ++ } ++ + if (!IS_POSIXACL(dir->d_inode)) + mode &= ~current_umask(); + error = security_path_mknod(&nd->path, path->dentry, mode, 0); + if (error) + goto out_unlock; + error = vfs_create(dir->d_inode, path->dentry, mode, nd); ++ if (!error) ++ gr_handle_create(path->dentry, nd->path.mnt); + out_unlock: + mutex_unlock(&dir->d_inode->i_mutex); + dput(nd->path.dentry); +@@ -1696,6 +1717,17 @@ struct file *do_filp_open(int dfd, const + &nd, flag); + if (error) + return ERR_PTR(error); ++ ++ if (gr_handle_rawio(nd.path.dentry->d_inode)) { ++ error = -EPERM; ++ goto exit; ++ } ++ ++ if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) { ++ error = -EACCES; ++ goto exit; ++ } ++ + goto ok; + } + +@@ -1782,6 +1814,20 @@ do_last: + /* + * It already exists. + */ ++ ++ if (gr_handle_rawio(path.dentry->d_inode)) { ++ error = -EPERM; ++ goto exit_mutex_unlock; ++ } ++ if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) { ++ error = -EACCES; ++ goto exit_mutex_unlock; ++ } ++ if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) { ++ error = -EACCES; ++ goto exit_mutex_unlock; ++ } ++ + mutex_unlock(&dir->d_inode->i_mutex); + audit_inode(pathname, path.dentry); + +@@ -1874,6 +1920,13 @@ do_link: + error = security_inode_follow_link(path.dentry, &nd); + if (error) + goto exit_dput; ++ ++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode, ++ path.dentry, nd.path.mnt)) { ++ error = -EACCES; ++ goto exit_dput; ++ } ++ + error = __do_follow_link(&path, &nd); + if (error) { + /* Does someone understand code flow here? Or it is only +@@ -2048,6 +2101,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const + error = may_mknod(mode); + if (error) + goto out_dput; ++ ++ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) { ++ error = -EPERM; ++ goto out_dput; ++ } ++ ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) { ++ error = -EACCES; ++ goto out_dput; ++ } ++ + error = mnt_want_write(nd.path.mnt); + if (error) + goto out_dput; +@@ -2068,6 +2132,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const + } + out_drop_write: + mnt_drop_write(nd.path.mnt); ++ ++ if (!error) ++ gr_handle_create(dentry, nd.path.mnt); + out_dput: + dput(dentry); + out_unlock: +@@ -2121,6 +2188,11 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const + if (IS_ERR(dentry)) + goto out_unlock; + ++ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) { ++ error = -EACCES; ++ goto out_dput; ++ } ++ + if (!IS_POSIXACL(nd.path.dentry->d_inode)) + mode &= ~current_umask(); + error = mnt_want_write(nd.path.mnt); +@@ -2132,6 +2204,10 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); + out_drop_write: + mnt_drop_write(nd.path.mnt); ++ ++ if (!error) ++ gr_handle_create(dentry, nd.path.mnt); ++ + out_dput: + dput(dentry); + out_unlock: +@@ -2213,6 +2289,8 @@ static long do_rmdir(int dfd, const char + char * name; + struct dentry *dentry; + struct nameidata nd; ++ ino_t saved_ino = 0; ++ dev_t saved_dev = 0; + + error = user_path_parent(dfd, pathname, &nd, &name); + if (error) +@@ -2237,6 +2315,19 @@ static long do_rmdir(int dfd, const char + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto exit2; ++ ++ if (dentry->d_inode != NULL) { ++ if (dentry->d_inode->i_nlink <= 1) { ++ saved_ino = dentry->d_inode->i_ino; ++ saved_dev = dentry->d_inode->i_sb->s_dev; ++ } ++ ++ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) { ++ error = -EACCES; ++ goto exit3; ++ } ++ } ++ + error = mnt_want_write(nd.path.mnt); + if (error) + goto exit3; +@@ -2244,6 +2335,8 @@ static long do_rmdir(int dfd, const char + if (error) + goto exit4; + error = vfs_rmdir(nd.path.dentry->d_inode, dentry); ++ if (!error && (saved_dev || saved_ino)) ++ gr_handle_delete(saved_ino, saved_dev); + exit4: + mnt_drop_write(nd.path.mnt); + exit3: +@@ -2305,6 +2398,8 @@ static long do_unlinkat(int dfd, const c + struct dentry *dentry; + struct nameidata nd; + struct inode *inode = NULL; ++ ino_t saved_ino = 0; ++ dev_t saved_dev = 0; + + error = user_path_parent(dfd, pathname, &nd, &name); + if (error) +@@ -2324,8 +2419,19 @@ static long do_unlinkat(int dfd, const c + if (nd.last.name[nd.last.len]) + goto slashes; + inode = dentry->d_inode; +- if (inode) ++ if (inode) { ++ if (inode->i_nlink <= 1) { ++ saved_ino = inode->i_ino; ++ saved_dev = inode->i_sb->s_dev; ++ } ++ + atomic_inc(&inode->i_count); ++ ++ if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) { ++ error = -EACCES; ++ goto exit2; ++ } ++ } + error = mnt_want_write(nd.path.mnt); + if (error) + goto exit2; +@@ -2333,6 +2439,8 @@ static long do_unlinkat(int dfd, const c + if (error) + goto exit3; + error = vfs_unlink(nd.path.dentry->d_inode, dentry); ++ if (!error && (saved_ino || saved_dev)) ++ gr_handle_delete(saved_ino, saved_dev); + exit3: + mnt_drop_write(nd.path.mnt); + exit2: +@@ -2411,6 +2519,11 @@ SYSCALL_DEFINE3(symlinkat, const char __ + if (IS_ERR(dentry)) + goto out_unlock; + ++ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) { ++ error = -EACCES; ++ goto out_dput; ++ } ++ + error = mnt_want_write(nd.path.mnt); + if (error) + goto out_dput; +@@ -2418,6 +2531,8 @@ SYSCALL_DEFINE3(symlinkat, const char __ + if (error) + goto out_drop_write; + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); ++ if (!error) ++ gr_handle_create(dentry, nd.path.mnt); + out_drop_write: + mnt_drop_write(nd.path.mnt); + out_dput: +@@ -2511,6 +2626,20 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con + error = PTR_ERR(new_dentry); + if (IS_ERR(new_dentry)) + goto out_unlock; ++ ++ if (gr_handle_hardlink(old_path.dentry, old_path.mnt, ++ old_path.dentry->d_inode, ++ old_path.dentry->d_inode->i_mode, to)) { ++ error = -EACCES; ++ goto out_dput; ++ } ++ ++ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt, ++ old_path.dentry, old_path.mnt, to)) { ++ error = -EACCES; ++ goto out_dput; ++ } ++ + error = mnt_want_write(nd.path.mnt); + if (error) + goto out_dput; +@@ -2518,6 +2647,8 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con + if (error) + goto out_drop_write; + error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); ++ if (!error) ++ gr_handle_create(new_dentry, nd.path.mnt); + out_drop_write: + mnt_drop_write(nd.path.mnt); + out_dput: +@@ -2751,6 +2882,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c + if (new_dentry == trap) + goto exit5; + ++ error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt, ++ old_dentry, old_dir->d_inode, oldnd.path.mnt, ++ to); ++ if (error) ++ goto exit5; ++ + error = mnt_want_write(oldnd.path.mnt); + if (error) + goto exit5; +@@ -2760,6 +2897,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c + goto exit6; + error = vfs_rename(old_dir->d_inode, old_dentry, + new_dir->d_inode, new_dentry); ++ if (!error) ++ gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry, ++ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0); + exit6: + mnt_drop_write(oldnd.path.mnt); + exit5: +diff -urNp linux-2.6.31.1/fs/namespace.c linux-2.6.31.1/fs/namespace.c +--- linux-2.6.31.1/fs/namespace.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/namespace.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1083,6 +1083,9 @@ static int do_umount(struct vfsmount *mn + if (!(sb->s_flags & MS_RDONLY)) + retval = do_remount_sb(sb, MS_RDONLY, NULL, 0); + up_write(&sb->s_umount); ++ ++ gr_log_remount(mnt->mnt_devname, retval); ++ + return retval; + } + +@@ -1104,6 +1107,9 @@ static int do_umount(struct vfsmount *mn + security_sb_umount_busy(mnt); + up_write(&namespace_sem); + release_mounts(&umount_list); ++ ++ gr_log_unmount(mnt->mnt_devname, retval); ++ + return retval; + } + +@@ -1940,6 +1946,11 @@ long do_mount(char *dev_name, char *dir_ + if (retval) + goto dput_out; + ++ if (gr_handle_chroot_mount(path.dentry, path.mnt, dev_name)) { ++ retval = -EPERM; ++ goto dput_out; ++ } ++ + if (flags & MS_REMOUNT) + retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, + data_page); +@@ -1954,6 +1965,9 @@ long do_mount(char *dev_name, char *dir_ + dev_name, data_page); + dput_out: + path_put(&path); ++ ++ gr_log_mount(dev_name, dir_name, retval); ++ + return retval; + } + +@@ -2158,6 +2172,12 @@ SYSCALL_DEFINE2(pivot_root, const char _ + goto out1; + } + ++ if (gr_handle_chroot_pivot()) { ++ error = -EPERM; ++ path_put(&old); ++ goto out1; ++ } ++ + read_lock(¤t->fs->lock); + root = current->fs->root; + path_get(¤t->fs->root); +diff -urNp linux-2.6.31.1/fs/nfs/client.c linux-2.6.31.1/fs/nfs/client.c +--- linux-2.6.31.1/fs/nfs/client.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nfs/client.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1533,7 +1533,7 @@ static void *nfs_server_list_next(struct + static void nfs_server_list_stop(struct seq_file *p, void *v); + static int nfs_server_list_show(struct seq_file *m, void *v); + +-static struct seq_operations nfs_server_list_ops = { ++static const struct seq_operations nfs_server_list_ops = { + .start = nfs_server_list_start, + .next = nfs_server_list_next, + .stop = nfs_server_list_stop, +@@ -1554,7 +1554,7 @@ static void *nfs_volume_list_next(struct + static void nfs_volume_list_stop(struct seq_file *p, void *v); + static int nfs_volume_list_show(struct seq_file *m, void *v); + +-static struct seq_operations nfs_volume_list_ops = { ++static const struct seq_operations nfs_volume_list_ops = { + .start = nfs_volume_list_start, + .next = nfs_volume_list_next, + .stop = nfs_volume_list_stop, +diff -urNp linux-2.6.31.1/fs/nfs/file.c linux-2.6.31.1/fs/nfs/file.c +--- linux-2.6.31.1/fs/nfs/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nfs/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -59,7 +59,7 @@ static int nfs_lock(struct file *filp, i + static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); + static int nfs_setlease(struct file *file, long arg, struct file_lock **fl); + +-static struct vm_operations_struct nfs_file_vm_ops; ++static const struct vm_operations_struct nfs_file_vm_ops; + + const struct file_operations nfs_file_operations = { + .llseek = nfs_file_llseek, +@@ -526,7 +526,7 @@ out_unlock: + return VM_FAULT_SIGBUS; + } + +-static struct vm_operations_struct nfs_file_vm_ops = { ++static const struct vm_operations_struct nfs_file_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = nfs_vm_page_mkwrite, + }; +diff -urNp linux-2.6.31.1/fs/nfs/nfs4proc.c linux-2.6.31.1/fs/nfs/nfs4proc.c +--- linux-2.6.31.1/fs/nfs/nfs4proc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nfs/nfs4proc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1123,7 +1123,7 @@ static int _nfs4_do_open_reclaim(struct + static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state) + { + struct nfs_server *server = NFS_SERVER(state->inode); +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = _nfs4_do_open_reclaim(ctx, state); +@@ -1165,7 +1165,7 @@ static int _nfs4_open_delegation_recall( + + int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + struct nfs_server *server = NFS_SERVER(state->inode); + int err; + do { +@@ -1481,7 +1481,7 @@ static int _nfs4_open_expired(struct nfs + static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) + { + struct nfs_server *server = NFS_SERVER(state->inode); +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + + do { +@@ -1579,7 +1579,7 @@ out_err: + + static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, int flags, struct iattr *sattr, struct rpc_cred *cred) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + struct nfs4_state *res; + int status; + +@@ -1670,7 +1670,7 @@ static int nfs4_do_setattr(struct inode + struct nfs4_state *state) + { + struct nfs_server *server = NFS_SERVER(inode); +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(server, +@@ -2014,7 +2014,7 @@ static int _nfs4_server_capabilities(str + + int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(server, +@@ -2048,7 +2048,7 @@ static int _nfs4_lookup_root(struct nfs_ + static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_fsinfo *info) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(server, +@@ -2137,7 +2137,7 @@ static int _nfs4_proc_getattr(struct nfs + + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(server, +@@ -2225,7 +2225,7 @@ static int nfs4_proc_lookupfh(struct nfs + struct qstr *name, struct nfs_fh *fhandle, + struct nfs_fattr *fattr) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr); +@@ -2254,7 +2254,7 @@ static int _nfs4_proc_lookup(struct inod + + static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(dir), +@@ -2318,7 +2318,7 @@ static int _nfs4_proc_access(struct inod + + static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(inode), +@@ -2374,7 +2374,7 @@ static int _nfs4_proc_readlink(struct in + static int nfs4_proc_readlink(struct inode *inode, struct page *page, + unsigned int pgbase, unsigned int pglen) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(inode), +@@ -2472,7 +2472,7 @@ static int _nfs4_proc_remove(struct inod + + static int nfs4_proc_remove(struct inode *dir, struct qstr *name) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(dir), +@@ -2546,7 +2546,7 @@ static int _nfs4_proc_rename(struct inod + static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, + struct inode *new_dir, struct qstr *new_name) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(old_dir), +@@ -2593,7 +2593,7 @@ static int _nfs4_proc_link(struct inode + + static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(inode), +@@ -2685,7 +2685,7 @@ out: + static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, + struct page *page, unsigned int len, struct iattr *sattr) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(dir), +@@ -2716,7 +2716,7 @@ out: + static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, + struct iattr *sattr) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(dir), +@@ -2765,7 +2765,7 @@ static int _nfs4_proc_readdir(struct den + static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, + u64 cookie, struct page *page, unsigned int count, int plus) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode), +@@ -2813,7 +2813,7 @@ out: + static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, + struct iattr *sattr, dev_t rdev) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(dir), +@@ -2845,7 +2845,7 @@ static int _nfs4_proc_statfs(struct nfs_ + + static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(server, +@@ -2876,7 +2876,7 @@ static int _nfs4_do_fsinfo(struct nfs_se + + static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + + do { +@@ -2922,7 +2922,7 @@ static int _nfs4_proc_pathconf(struct nf + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, + struct nfs_pathconf *pathconf) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + + do { +@@ -3224,7 +3224,7 @@ out_free: + + static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + ssize_t ret; + do { + ret = __nfs4_get_acl_uncached(inode, buf, buflen); +@@ -3280,7 +3280,7 @@ static int __nfs4_proc_set_acl(struct in + + static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = nfs4_handle_exception(NFS_SERVER(inode), +@@ -3545,7 +3545,7 @@ out: + int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync) + { + struct nfs_server *server = NFS_SERVER(inode); +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + do { + err = _nfs4_proc_delegreturn(inode, cred, stateid, issync); +@@ -3618,7 +3618,7 @@ out: + + static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + + do { +@@ -3992,7 +3992,7 @@ static int _nfs4_do_setlk(struct nfs4_st + static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request) + { + struct nfs_server *server = NFS_SERVER(state->inode); +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + + do { +@@ -4010,7 +4010,7 @@ static int nfs4_lock_reclaim(struct nfs4 + static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request) + { + struct nfs_server *server = NFS_SERVER(state->inode); +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + + err = nfs4_set_lock_state(state, request); +@@ -4065,7 +4065,7 @@ out: + + static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) + { +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + + do { +@@ -4125,7 +4125,7 @@ nfs4_proc_lock(struct file *filp, int cm + int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) + { + struct nfs_server *server = NFS_SERVER(state->inode); +- struct nfs4_exception exception = { }; ++ struct nfs4_exception exception = {0, 0}; + int err; + + err = nfs4_set_lock_state(state, fl); +diff -urNp linux-2.6.31.1/fs/nfsd/export.c linux-2.6.31.1/fs/nfsd/export.c +--- linux-2.6.31.1/fs/nfsd/export.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nfsd/export.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1505,7 +1505,7 @@ static int e_show(struct seq_file *m, vo + return svc_export_show(m, &svc_export_cache, cp); + } + +-struct seq_operations nfs_exports_op = { ++const struct seq_operations nfs_exports_op = { + .start = e_start, + .next = e_next, + .stop = e_stop, +diff -urNp linux-2.6.31.1/fs/nfsd/nfsctl.c linux-2.6.31.1/fs/nfsd/nfsctl.c +--- linux-2.6.31.1/fs/nfsd/nfsctl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nfsd/nfsctl.c 2009-10-01 20:12:44.000000000 -0400 +@@ -174,7 +174,7 @@ static const struct file_operations expo + + extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); + +-static struct file_operations pool_stats_operations = { ++static const struct file_operations pool_stats_operations = { + .open = nfsd_pool_stats_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/fs/nilfs2/btnode.c linux-2.6.31.1/fs/nilfs2/btnode.c +--- linux-2.6.31.1/fs/nilfs2/btnode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nilfs2/btnode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -46,7 +46,7 @@ void nilfs_btnode_cache_init_once(struct + INIT_LIST_HEAD(&btnc->i_mmap_nonlinear); + } + +-static struct address_space_operations def_btnode_aops = { ++static const struct address_space_operations def_btnode_aops = { + .sync_page = block_sync_page, + }; + +diff -urNp linux-2.6.31.1/fs/nilfs2/dir.c linux-2.6.31.1/fs/nilfs2/dir.c +--- linux-2.6.31.1/fs/nilfs2/dir.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nilfs2/dir.c 2009-10-01 20:12:44.000000000 -0400 +@@ -697,7 +697,7 @@ not_empty: + return 0; + } + +-struct file_operations nilfs_dir_operations = { ++const struct file_operations nilfs_dir_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .readdir = nilfs_readdir, +diff -urNp linux-2.6.31.1/fs/nilfs2/file.c linux-2.6.31.1/fs/nilfs2/file.c +--- linux-2.6.31.1/fs/nilfs2/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nilfs2/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -117,7 +117,7 @@ static int nilfs_page_mkwrite(struct vm_ + return 0; + } + +-struct vm_operations_struct nilfs_file_vm_ops = { ++const struct vm_operations_struct nilfs_file_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = nilfs_page_mkwrite, + }; +@@ -134,7 +134,7 @@ static int nilfs_file_mmap(struct file * + * We have mostly NULL's here: the current defaults are ok for + * the nilfs filesystem. + */ +-struct file_operations nilfs_file_operations = { ++const struct file_operations nilfs_file_operations = { + .llseek = generic_file_llseek, + .read = do_sync_read, + .write = do_sync_write, +@@ -151,7 +151,7 @@ struct file_operations nilfs_file_operat + .splice_read = generic_file_splice_read, + }; + +-struct inode_operations nilfs_file_inode_operations = { ++const struct inode_operations nilfs_file_inode_operations = { + .truncate = nilfs_truncate, + .setattr = nilfs_setattr, + .permission = nilfs_permission, +diff -urNp linux-2.6.31.1/fs/nilfs2/gcinode.c linux-2.6.31.1/fs/nilfs2/gcinode.c +--- linux-2.6.31.1/fs/nilfs2/gcinode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nilfs2/gcinode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -52,7 +52,7 @@ + #include "dat.h" + #include "ifile.h" + +-static struct address_space_operations def_gcinode_aops = { ++static const struct address_space_operations def_gcinode_aops = { + .sync_page = block_sync_page, + }; + +diff -urNp linux-2.6.31.1/fs/nilfs2/inode.c linux-2.6.31.1/fs/nilfs2/inode.c +--- linux-2.6.31.1/fs/nilfs2/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nilfs2/inode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -238,7 +238,7 @@ nilfs_direct_IO(int rw, struct kiocb *io + return size; + } + +-struct address_space_operations nilfs_aops = { ++const struct address_space_operations nilfs_aops = { + .writepage = nilfs_writepage, + .readpage = nilfs_readpage, + .sync_page = block_sync_page, +diff -urNp linux-2.6.31.1/fs/nilfs2/mdt.c linux-2.6.31.1/fs/nilfs2/mdt.c +--- linux-2.6.31.1/fs/nilfs2/mdt.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nilfs2/mdt.c 2009-10-01 20:12:44.000000000 -0400 +@@ -430,7 +430,7 @@ nilfs_mdt_write_page(struct page *page, + } + + +-static struct address_space_operations def_mdt_aops = { ++static const struct address_space_operations def_mdt_aops = { + .writepage = nilfs_mdt_write_page, + .sync_page = block_sync_page, + }; +diff -urNp linux-2.6.31.1/fs/nilfs2/namei.c linux-2.6.31.1/fs/nilfs2/namei.c +--- linux-2.6.31.1/fs/nilfs2/namei.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nilfs2/namei.c 2009-10-01 20:12:44.000000000 -0400 +@@ -448,7 +448,7 @@ out: + return err; + } + +-struct inode_operations nilfs_dir_inode_operations = { ++const struct inode_operations nilfs_dir_inode_operations = { + .create = nilfs_create, + .lookup = nilfs_lookup, + .link = nilfs_link, +@@ -462,12 +462,12 @@ struct inode_operations nilfs_dir_inode_ + .permission = nilfs_permission, + }; + +-struct inode_operations nilfs_special_inode_operations = { ++const struct inode_operations nilfs_special_inode_operations = { + .setattr = nilfs_setattr, + .permission = nilfs_permission, + }; + +-struct inode_operations nilfs_symlink_inode_operations = { ++const struct inode_operations nilfs_symlink_inode_operations = { + .readlink = generic_readlink, + .follow_link = page_follow_link_light, + .put_link = page_put_link, +diff -urNp linux-2.6.31.1/fs/nilfs2/nilfs.h linux-2.6.31.1/fs/nilfs2/nilfs.h +--- linux-2.6.31.1/fs/nilfs2/nilfs.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nilfs2/nilfs.h 2009-10-01 20:12:44.000000000 -0400 +@@ -294,13 +294,13 @@ void nilfs_clear_gcdat_inode(struct the_ + /* + * Inodes and files operations + */ +-extern struct file_operations nilfs_dir_operations; +-extern struct inode_operations nilfs_file_inode_operations; +-extern struct file_operations nilfs_file_operations; +-extern struct address_space_operations nilfs_aops; +-extern struct inode_operations nilfs_dir_inode_operations; +-extern struct inode_operations nilfs_special_inode_operations; +-extern struct inode_operations nilfs_symlink_inode_operations; ++extern const struct file_operations nilfs_dir_operations; ++extern const struct inode_operations nilfs_file_inode_operations; ++extern const struct file_operations nilfs_file_operations; ++extern const struct address_space_operations nilfs_aops; ++extern const struct inode_operations nilfs_dir_inode_operations; ++extern const struct inode_operations nilfs_special_inode_operations; ++extern const struct inode_operations nilfs_symlink_inode_operations; + + /* + * filesystem type +diff -urNp linux-2.6.31.1/fs/nilfs2/super.c linux-2.6.31.1/fs/nilfs2/super.c +--- linux-2.6.31.1/fs/nilfs2/super.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nilfs2/super.c 2009-10-01 20:12:44.000000000 -0400 +@@ -529,7 +529,7 @@ static int nilfs_statfs(struct dentry *d + return 0; + } + +-static struct super_operations nilfs_sops = { ++static const struct super_operations nilfs_sops = { + .alloc_inode = nilfs_alloc_inode, + .destroy_inode = nilfs_destroy_inode, + .dirty_inode = nilfs_dirty_inode, +diff -urNp linux-2.6.31.1/fs/nls/nls_base.c linux-2.6.31.1/fs/nls/nls_base.c +--- linux-2.6.31.1/fs/nls/nls_base.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/nls/nls_base.c 2009-10-01 20:12:44.000000000 -0400 +@@ -41,7 +41,7 @@ static const struct utf8_table utf8_tabl + {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */}, + {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */}, + {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */}, +- {0, /* end of table */} ++ {0, 0, 0, 0, 0, /* end of table */} + }; + + #define UNICODE_MAX 0x0010ffff +diff -urNp linux-2.6.31.1/fs/ntfs/file.c linux-2.6.31.1/fs/ntfs/file.c +--- linux-2.6.31.1/fs/ntfs/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ntfs/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_ + #endif /* NTFS_RW */ + }; + +-const struct file_operations ntfs_empty_file_ops = {}; ++const struct file_operations ntfs_empty_file_ops; + +-const struct inode_operations ntfs_empty_inode_ops = {}; ++const struct inode_operations ntfs_empty_inode_ops; +diff -urNp linux-2.6.31.1/fs/ocfs2/cluster/heartbeat.c linux-2.6.31.1/fs/ocfs2/cluster/heartbeat.c +--- linux-2.6.31.1/fs/ocfs2/cluster/heartbeat.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ocfs2/cluster/heartbeat.c 2009-10-01 20:12:44.000000000 -0400 +@@ -966,7 +966,7 @@ static ssize_t o2hb_debug_read(struct fi + } + #endif /* CONFIG_DEBUG_FS */ + +-static struct file_operations o2hb_debug_fops = { ++static const struct file_operations o2hb_debug_fops = { + .open = o2hb_debug_open, + .release = o2hb_debug_release, + .read = o2hb_debug_read, +diff -urNp linux-2.6.31.1/fs/ocfs2/cluster/netdebug.c linux-2.6.31.1/fs/ocfs2/cluster/netdebug.c +--- linux-2.6.31.1/fs/ocfs2/cluster/netdebug.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ocfs2/cluster/netdebug.c 2009-10-01 20:12:44.000000000 -0400 +@@ -163,7 +163,7 @@ static void nst_seq_stop(struct seq_file + { + } + +-static struct seq_operations nst_seq_ops = { ++static const struct seq_operations nst_seq_ops = { + .start = nst_seq_start, + .next = nst_seq_next, + .stop = nst_seq_stop, +@@ -207,7 +207,7 @@ static int nst_fop_release(struct inode + return seq_release_private(inode, file); + } + +-static struct file_operations nst_seq_fops = { ++static const struct file_operations nst_seq_fops = { + .open = nst_fop_open, + .read = seq_read, + .llseek = seq_lseek, +@@ -344,7 +344,7 @@ static void sc_seq_stop(struct seq_file + { + } + +-static struct seq_operations sc_seq_ops = { ++static const struct seq_operations sc_seq_ops = { + .start = sc_seq_start, + .next = sc_seq_next, + .stop = sc_seq_stop, +@@ -388,7 +388,7 @@ static int sc_fop_release(struct inode * + return seq_release_private(inode, file); + } + +-static struct file_operations sc_seq_fops = { ++static const struct file_operations sc_seq_fops = { + .open = sc_fop_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/fs/ocfs2/dlm/dlmdebug.c linux-2.6.31.1/fs/ocfs2/dlm/dlmdebug.c +--- linux-2.6.31.1/fs/ocfs2/dlm/dlmdebug.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ocfs2/dlm/dlmdebug.c 2009-10-01 20:12:44.000000000 -0400 +@@ -479,7 +479,7 @@ bail: + return -ENOMEM; + } + +-static struct file_operations debug_purgelist_fops = { ++static const struct file_operations debug_purgelist_fops = { + .open = debug_purgelist_open, + .release = debug_buffer_release, + .read = debug_buffer_read, +@@ -539,7 +539,7 @@ bail: + return -ENOMEM; + } + +-static struct file_operations debug_mle_fops = { ++static const struct file_operations debug_mle_fops = { + .open = debug_mle_open, + .release = debug_buffer_release, + .read = debug_buffer_read, +@@ -683,7 +683,7 @@ static int lockres_seq_show(struct seq_f + return 0; + } + +-static struct seq_operations debug_lockres_ops = { ++static const struct seq_operations debug_lockres_ops = { + .start = lockres_seq_start, + .stop = lockres_seq_stop, + .next = lockres_seq_next, +@@ -742,7 +742,7 @@ static int debug_lockres_release(struct + return seq_release_private(inode, file); + } + +-static struct file_operations debug_lockres_fops = { ++static const struct file_operations debug_lockres_fops = { + .open = debug_lockres_open, + .release = debug_lockres_release, + .read = seq_read, +@@ -926,7 +926,7 @@ bail: + return -ENOMEM; + } + +-static struct file_operations debug_state_fops = { ++static const struct file_operations debug_state_fops = { + .open = debug_state_open, + .release = debug_buffer_release, + .read = debug_buffer_read, +diff -urNp linux-2.6.31.1/fs/ocfs2/localalloc.c linux-2.6.31.1/fs/ocfs2/localalloc.c +--- linux-2.6.31.1/fs/ocfs2/localalloc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ocfs2/localalloc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1186,7 +1186,7 @@ static int ocfs2_local_alloc_slide_windo + goto bail; + } + +- atomic_inc(&osb->alloc_stats.moves); ++ atomic_inc_unchecked(&osb->alloc_stats.moves); + + status = 0; + bail: +diff -urNp linux-2.6.31.1/fs/ocfs2/mmap.c linux-2.6.31.1/fs/ocfs2/mmap.c +--- linux-2.6.31.1/fs/ocfs2/mmap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ocfs2/mmap.c 2009-10-01 20:12:44.000000000 -0400 +@@ -202,7 +202,7 @@ out: + return ret; + } + +-static struct vm_operations_struct ocfs2_file_vm_ops = { ++static const struct vm_operations_struct ocfs2_file_vm_ops = { + .fault = ocfs2_fault, + .page_mkwrite = ocfs2_page_mkwrite, + }; +diff -urNp linux-2.6.31.1/fs/ocfs2/ocfs2.h linux-2.6.31.1/fs/ocfs2/ocfs2.h +--- linux-2.6.31.1/fs/ocfs2/ocfs2.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ocfs2/ocfs2.h 2009-10-01 20:12:44.000000000 -0400 +@@ -191,11 +191,11 @@ enum ocfs2_vol_state + + struct ocfs2_alloc_stats + { +- atomic_t moves; +- atomic_t local_data; +- atomic_t bitmap_data; +- atomic_t bg_allocs; +- atomic_t bg_extends; ++ atomic_unchecked_t moves; ++ atomic_unchecked_t local_data; ++ atomic_unchecked_t bitmap_data; ++ atomic_unchecked_t bg_allocs; ++ atomic_unchecked_t bg_extends; + }; + + enum ocfs2_local_alloc_state +diff -urNp linux-2.6.31.1/fs/ocfs2/suballoc.c linux-2.6.31.1/fs/ocfs2/suballoc.c +--- linux-2.6.31.1/fs/ocfs2/suballoc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ocfs2/suballoc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -620,7 +620,7 @@ static int ocfs2_reserve_suballoc_bits(s + mlog_errno(status); + goto bail; + } +- atomic_inc(&osb->alloc_stats.bg_extends); ++ atomic_inc_unchecked(&osb->alloc_stats.bg_extends); + + /* You should never ask for this much metadata */ + BUG_ON(bits_wanted > +@@ -1650,7 +1650,7 @@ int ocfs2_claim_metadata(struct ocfs2_su + mlog_errno(status); + goto bail; + } +- atomic_inc(&osb->alloc_stats.bg_allocs); ++ atomic_inc_unchecked(&osb->alloc_stats.bg_allocs); + + *blkno_start = bg_blkno + (u64) *suballoc_bit_start; + ac->ac_bits_given += (*num_bits); +@@ -1724,7 +1724,7 @@ int ocfs2_claim_new_inode(struct ocfs2_s + mlog_errno(status); + goto bail; + } +- atomic_inc(&osb->alloc_stats.bg_allocs); ++ atomic_inc_unchecked(&osb->alloc_stats.bg_allocs); + + BUG_ON(num_bits != 1); + +@@ -1826,7 +1826,7 @@ int __ocfs2_claim_clusters(struct ocfs2_ + cluster_start, + num_clusters); + if (!status) +- atomic_inc(&osb->alloc_stats.local_data); ++ atomic_inc_unchecked(&osb->alloc_stats.local_data); + } else { + if (min_clusters > (osb->bitmap_cpg - 1)) { + /* The only paths asking for contiguousness +@@ -1854,7 +1854,7 @@ int __ocfs2_claim_clusters(struct ocfs2_ + ocfs2_desc_bitmap_to_cluster_off(ac->ac_inode, + bg_blkno, + bg_bit_off); +- atomic_inc(&osb->alloc_stats.bitmap_data); ++ atomic_inc_unchecked(&osb->alloc_stats.bitmap_data); + } + } + if (status < 0) { +diff -urNp linux-2.6.31.1/fs/ocfs2/super.c linux-2.6.31.1/fs/ocfs2/super.c +--- linux-2.6.31.1/fs/ocfs2/super.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ocfs2/super.c 2009-10-01 20:12:44.000000000 -0400 +@@ -284,11 +284,11 @@ static int ocfs2_osb_dump(struct ocfs2_s + "%10s => GlobalAllocs: %d LocalAllocs: %d " + "SubAllocs: %d LAWinMoves: %d SAExtends: %d\n", + "Stats", +- atomic_read(&osb->alloc_stats.bitmap_data), +- atomic_read(&osb->alloc_stats.local_data), +- atomic_read(&osb->alloc_stats.bg_allocs), +- atomic_read(&osb->alloc_stats.moves), +- atomic_read(&osb->alloc_stats.bg_extends)); ++ atomic_read_unchecked(&osb->alloc_stats.bitmap_data), ++ atomic_read_unchecked(&osb->alloc_stats.local_data), ++ atomic_read_unchecked(&osb->alloc_stats.bg_allocs), ++ atomic_read_unchecked(&osb->alloc_stats.moves), ++ atomic_read_unchecked(&osb->alloc_stats.bg_extends)); + + out += snprintf(buf + out, len - out, + "%10s => State: %u Descriptor: %llu Size: %u bits " +@@ -373,7 +373,7 @@ static ssize_t ocfs2_debug_read(struct f + } + #endif /* CONFIG_DEBUG_FS */ + +-static struct file_operations ocfs2_osb_debug_fops = { ++static const struct file_operations ocfs2_osb_debug_fops = { + .open = ocfs2_osb_debug_open, + .release = ocfs2_debug_release, + .read = ocfs2_debug_read, +@@ -1991,11 +1991,11 @@ static int ocfs2_initialize_super(struct + spin_lock_init(&osb->osb_xattr_lock); + ocfs2_init_inode_steal_slot(osb); + +- atomic_set(&osb->alloc_stats.moves, 0); +- atomic_set(&osb->alloc_stats.local_data, 0); +- atomic_set(&osb->alloc_stats.bitmap_data, 0); +- atomic_set(&osb->alloc_stats.bg_allocs, 0); +- atomic_set(&osb->alloc_stats.bg_extends, 0); ++ atomic_set_unchecked(&osb->alloc_stats.moves, 0); ++ atomic_set_unchecked(&osb->alloc_stats.local_data, 0); ++ atomic_set_unchecked(&osb->alloc_stats.bitmap_data, 0); ++ atomic_set_unchecked(&osb->alloc_stats.bg_allocs, 0); ++ atomic_set_unchecked(&osb->alloc_stats.bg_extends, 0); + + /* Copy the blockcheck stats from the superblock probe */ + osb->osb_ecc_stats = *stats; +diff -urNp linux-2.6.31.1/fs/omfs/dir.c linux-2.6.31.1/fs/omfs/dir.c +--- linux-2.6.31.1/fs/omfs/dir.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/omfs/dir.c 2009-10-01 20:12:44.000000000 -0400 +@@ -489,7 +489,7 @@ out: + return ret; + } + +-struct inode_operations omfs_dir_inops = { ++const struct inode_operations omfs_dir_inops = { + .lookup = omfs_lookup, + .mkdir = omfs_mkdir, + .rename = omfs_rename, +@@ -498,7 +498,7 @@ struct inode_operations omfs_dir_inops = + .rmdir = omfs_rmdir, + }; + +-struct file_operations omfs_dir_operations = { ++const struct file_operations omfs_dir_operations = { + .read = generic_read_dir, + .readdir = omfs_readdir, + .llseek = generic_file_llseek, +diff -urNp linux-2.6.31.1/fs/omfs/file.c linux-2.6.31.1/fs/omfs/file.c +--- linux-2.6.31.1/fs/omfs/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/omfs/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -322,7 +322,7 @@ static sector_t omfs_bmap(struct address + return generic_block_bmap(mapping, block, omfs_get_block); + } + +-struct file_operations omfs_file_operations = { ++const struct file_operations omfs_file_operations = { + .llseek = generic_file_llseek, + .read = do_sync_read, + .write = do_sync_write, +@@ -333,11 +333,11 @@ struct file_operations omfs_file_operati + .splice_read = generic_file_splice_read, + }; + +-struct inode_operations omfs_file_inops = { ++const struct inode_operations omfs_file_inops = { + .truncate = omfs_truncate + }; + +-struct address_space_operations omfs_aops = { ++const struct address_space_operations omfs_aops = { + .readpage = omfs_readpage, + .readpages = omfs_readpages, + .writepage = omfs_writepage, +diff -urNp linux-2.6.31.1/fs/omfs/inode.c linux-2.6.31.1/fs/omfs/inode.c +--- linux-2.6.31.1/fs/omfs/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/omfs/inode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -278,7 +278,7 @@ static int omfs_statfs(struct dentry *de + return 0; + } + +-static struct super_operations omfs_sops = { ++static const struct super_operations omfs_sops = { + .write_inode = omfs_write_inode, + .delete_inode = omfs_delete_inode, + .put_super = omfs_put_super, +diff -urNp linux-2.6.31.1/fs/omfs/omfs.h linux-2.6.31.1/fs/omfs/omfs.h +--- linux-2.6.31.1/fs/omfs/omfs.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/omfs/omfs.h 2009-10-01 20:12:44.000000000 -0400 +@@ -44,16 +44,16 @@ extern int omfs_allocate_range(struct su + extern int omfs_clear_range(struct super_block *sb, u64 block, int count); + + /* dir.c */ +-extern struct file_operations omfs_dir_operations; +-extern struct inode_operations omfs_dir_inops; ++extern const struct file_operations omfs_dir_operations; ++extern const struct inode_operations omfs_dir_inops; + extern int omfs_make_empty(struct inode *inode, struct super_block *sb); + extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header, + u64 fsblock); + + /* file.c */ +-extern struct file_operations omfs_file_operations; +-extern struct inode_operations omfs_file_inops; +-extern struct address_space_operations omfs_aops; ++extern const struct file_operations omfs_file_operations; ++extern const struct inode_operations omfs_file_inops; ++extern const struct address_space_operations omfs_aops; + extern void omfs_make_empty_table(struct buffer_head *bh, int offset); + extern int omfs_shrink_inode(struct inode *inode); + +diff -urNp linux-2.6.31.1/fs/open.c linux-2.6.31.1/fs/open.c +--- linux-2.6.31.1/fs/open.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/open.c 2009-10-01 20:12:44.000000000 -0400 +@@ -206,6 +206,9 @@ int do_truncate(struct dentry *dentry, l + if (length < 0) + return -EINVAL; + ++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt)) ++ return -EACCES; ++ + newattrs.ia_size = length; + newattrs.ia_valid = ATTR_SIZE | time_attrs; + if (filp) { +@@ -510,6 +513,9 @@ SYSCALL_DEFINE3(faccessat, int, dfd, con + if (__mnt_is_readonly(path.mnt)) + res = -EROFS; + ++ if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode)) ++ res = -EACCES; ++ + out_path_release: + path_put(&path); + out: +@@ -536,6 +542,8 @@ SYSCALL_DEFINE1(chdir, const char __user + if (error) + goto dput_and_out; + ++ gr_log_chdir(path.dentry, path.mnt); ++ + set_fs_pwd(current->fs, &path); + + dput_and_out: +@@ -562,6 +570,13 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd + goto out_putf; + + error = inode_permission(inode, MAY_EXEC | MAY_ACCESS); ++ ++ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt)) ++ error = -EPERM; ++ ++ if (!error) ++ gr_log_chdir(file->f_path.dentry, file->f_path.mnt); ++ + if (!error) + set_fs_pwd(current->fs, &file->f_path); + out_putf: +@@ -587,7 +602,18 @@ SYSCALL_DEFINE1(chroot, const char __use + if (!capable(CAP_SYS_CHROOT)) + goto dput_and_out; + ++ if (gr_handle_chroot_chroot(path.dentry, path.mnt)) ++ goto dput_and_out; ++ ++ if (gr_handle_chroot_caps(&path)) { ++ error = -ENOMEM; ++ goto dput_and_out; ++ } ++ + set_fs_root(current->fs, &path); ++ ++ gr_handle_chroot_chdir(&path); ++ + error = 0; + dput_and_out: + path_put(&path); +@@ -615,13 +641,28 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd + err = mnt_want_write_file(file); + if (err) + goto out_putf; ++ ++ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) { ++ err = -EACCES; ++ goto out_drop_write; ++ } ++ + mutex_lock(&inode->i_mutex); + if (mode == (mode_t) -1) + mode = inode->i_mode; ++ ++ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) { ++ err = -EPERM; ++ mutex_unlock(&inode->i_mutex); ++ goto out_drop_write; ++ } ++ + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; + err = notify_change(dentry, &newattrs); + mutex_unlock(&inode->i_mutex); ++ ++out_drop_write: + mnt_drop_write(file->f_path.mnt); + out_putf: + fput(file); +@@ -644,13 +685,28 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons + error = mnt_want_write(path.mnt); + if (error) + goto dput_and_out; ++ ++ if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) { ++ error = -EACCES; ++ goto out_drop_write; ++ } ++ + mutex_lock(&inode->i_mutex); + if (mode == (mode_t) -1) + mode = inode->i_mode; ++ ++ if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) { ++ error = -EACCES; ++ mutex_unlock(&inode->i_mutex); ++ goto out_drop_write; ++ } ++ + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; + error = notify_change(path.dentry, &newattrs); + mutex_unlock(&inode->i_mutex); ++ ++out_drop_write: + mnt_drop_write(path.mnt); + dput_and_out: + path_put(&path); +@@ -663,12 +719,15 @@ SYSCALL_DEFINE2(chmod, const char __user + return sys_fchmodat(AT_FDCWD, filename, mode); + } + +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group) ++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt) + { + struct inode *inode = dentry->d_inode; + int error; + struct iattr newattrs; + ++ if (!gr_acl_handle_chown(dentry, mnt)) ++ return -EACCES; ++ + newattrs.ia_valid = ATTR_CTIME; + if (user != (uid_t) -1) { + newattrs.ia_valid |= ATTR_UID; +@@ -699,7 +758,7 @@ SYSCALL_DEFINE3(chown, const char __user + error = mnt_want_write(path.mnt); + if (error) + goto out_release; +- error = chown_common(path.dentry, user, group); ++ error = chown_common(path.dentry, user, group, path.mnt); + mnt_drop_write(path.mnt); + out_release: + path_put(&path); +@@ -724,7 +783,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, cons + error = mnt_want_write(path.mnt); + if (error) + goto out_release; +- error = chown_common(path.dentry, user, group); ++ error = chown_common(path.dentry, user, group, path.mnt); + mnt_drop_write(path.mnt); + out_release: + path_put(&path); +@@ -743,7 +802,7 @@ SYSCALL_DEFINE3(lchown, const char __use + error = mnt_want_write(path.mnt); + if (error) + goto out_release; +- error = chown_common(path.dentry, user, group); ++ error = chown_common(path.dentry, user, group, path.mnt); + mnt_drop_write(path.mnt); + out_release: + path_put(&path); +@@ -766,7 +825,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd + goto out_fput; + dentry = file->f_path.dentry; + audit_inode(NULL, dentry); +- error = chown_common(dentry, user, group); ++ error = chown_common(dentry, user, group, file->f_path.mnt); + mnt_drop_write(file->f_path.mnt); + out_fput: + fput(file); +diff -urNp linux-2.6.31.1/fs/pipe.c linux-2.6.31.1/fs/pipe.c +--- linux-2.6.31.1/fs/pipe.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/pipe.c 2009-10-01 20:12:44.000000000 -0400 +@@ -886,7 +886,7 @@ void free_pipe_info(struct inode *inode) + inode->i_pipe = NULL; + } + +-static struct vfsmount *pipe_mnt __read_mostly; ++struct vfsmount *pipe_mnt __read_mostly; + static int pipefs_delete_dentry(struct dentry *dentry) + { + /* +diff -urNp linux-2.6.31.1/fs/proc/array.c linux-2.6.31.1/fs/proc/array.c +--- linux-2.6.31.1/fs/proc/array.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/array.c 2009-10-01 20:12:44.000000000 -0400 +@@ -321,6 +321,21 @@ static inline void task_context_switch_c + p->nivcsw); + } + ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) ++static inline void task_pax(struct seq_file *m, struct task_struct *p) ++{ ++ if (p->mm) ++ seq_printf(m, "PaX:\t%c%c%c%c%c\n", ++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p', ++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e', ++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm', ++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r', ++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's'); ++ else ++ seq_printf(m, "PaX:\t-----\n"); ++} ++#endif ++ + int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *task) + { +@@ -340,9 +355,20 @@ int proc_pid_status(struct seq_file *m, + task_show_regs(m, task); + #endif + task_context_switch_counts(m, task); ++ ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) ++ task_pax(m, task); ++#endif ++ + return 0; + } + ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \ ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \ ++ _mm->pax_flags & MF_PAX_SEGMEXEC)) ++#endif ++ + static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *task, int whole) + { +@@ -439,6 +465,19 @@ static int do_task_stat(struct seq_file + gtime = task_gtime(task); + } + ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ if (PAX_RAND_FLAGS(mm)) { ++ eip = 0; ++ esp = 0; ++ wchan = 0; ++ } ++#endif ++#ifdef CONFIG_GRKERNSEC_HIDESYM ++ wchan = 0; ++ eip =0; ++ esp =0; ++#endif ++ + /* scale priority and nice values from timeslices to -20..20 */ + /* to make it look like a "normal" Unix priority/nice value */ + priority = task_prio(task); +@@ -479,9 +518,15 @@ static int do_task_stat(struct seq_file + vsize, + mm ? get_mm_rss(mm) : 0, + rsslim, ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0), ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0), ++ PAX_RAND_FLAGS(mm) ? 0 : ((permitted && mm) ? mm->start_stack : 0), ++#else + mm ? mm->start_code : 0, + mm ? mm->end_code : 0, + (permitted && mm) ? mm->start_stack : 0, ++#endif + esp, + eip, + /* The signal information here is obsolete. +@@ -534,3 +579,10 @@ int proc_pid_statm(struct seq_file *m, s + + return 0; + } ++ ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR ++int proc_pid_ipaddr(struct task_struct *task, char *buffer) ++{ ++ return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip)); ++} ++#endif +diff -urNp linux-2.6.31.1/fs/proc/base.c linux-2.6.31.1/fs/proc/base.c +--- linux-2.6.31.1/fs/proc/base.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/base.c 2009-10-01 20:12:44.000000000 -0400 +@@ -213,6 +213,9 @@ static int check_mem_permission(struct t + if (task == current) + return 0; + ++ if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task)) ++ return -EPERM; ++ + /* + * If current is actively ptrace'ing, and would also be + * permitted to freshly attach with ptrace now, permit it. +@@ -260,6 +263,9 @@ static int proc_pid_cmdline(struct task_ + if (!mm->arg_end) + goto out_mm; /* Shh! No looking before we're done */ + ++ if (gr_acl_handle_procpidmem(task)) ++ goto out_mm; ++ + len = mm->arg_end - mm->arg_start; + + if (len > PAGE_SIZE) +@@ -287,12 +293,26 @@ out: + return res; + } + ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \ ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \ ++ _mm->pax_flags & MF_PAX_SEGMEXEC)) ++#endif ++ + static int proc_pid_auxv(struct task_struct *task, char *buffer) + { + int res = 0; + struct mm_struct *mm = get_task_mm(task); + if (mm) { + unsigned int nwords = 0; ++ ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ if (PAX_RAND_FLAGS(mm)) { ++ mmput(mm); ++ return res; ++ } ++#endif ++ + do { + nwords += 2; + } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ +@@ -328,7 +348,7 @@ static int proc_pid_wchan(struct task_st + } + #endif /* CONFIG_KALLSYMS */ + +-#ifdef CONFIG_STACKTRACE ++#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM) + + #define MAX_STACK_TRACE_DEPTH 64 + +@@ -521,7 +541,7 @@ static int proc_pid_limits(struct task_s + return count; + } + +-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK ++#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP) + static int proc_pid_syscall(struct task_struct *task, char *buffer) + { + long nr; +@@ -935,6 +955,9 @@ static ssize_t environ_read(struct file + if (!task) + goto out_no_task; + ++ if (gr_acl_handle_procpidmem(task)) ++ goto out; ++ + if (!ptrace_may_access(task, PTRACE_MODE_READ)) + goto out; + +@@ -1438,7 +1461,11 @@ static struct inode *proc_pid_make_inode + rcu_read_lock(); + cred = __task_cred(task); + inode->i_uid = cred->euid; ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; ++#else + inode->i_gid = cred->egid; ++#endif + rcu_read_unlock(); + } + security_task_to_inode(task, inode); +@@ -1456,6 +1483,9 @@ static int pid_getattr(struct vfsmount * + struct inode *inode = dentry->d_inode; + struct task_struct *task; + const struct cred *cred; ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ const struct cred *tmpcred = current_cred(); ++#endif + + generic_fillattr(inode, stat); + +@@ -1463,12 +1493,34 @@ static int pid_getattr(struct vfsmount * + stat->uid = 0; + stat->gid = 0; + task = pid_task(proc_pid(inode), PIDTYPE_PID); ++ ++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) { ++ rcu_read_unlock(); ++ return -ENOENT; ++ } ++ + if (task) { ++ cred = __task_cred(task); ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ if (!tmpcred->uid || (tmpcred->uid == cred->uid) ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP ++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID) ++#endif ++ ) ++#endif + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) || ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) || ++#endif + task_dumpable(task)) { +- cred = __task_cred(task); + stat->uid = cred->euid; ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP ++ stat->gid = CONFIG_GRKERNSEC_PROC_GID; ++#else + stat->gid = cred->egid; ++#endif + } + } + rcu_read_unlock(); +@@ -1500,11 +1552,20 @@ static int pid_revalidate(struct dentry + + if (task) { + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) || ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) || ++#endif + task_dumpable(task)) { + rcu_read_lock(); + cred = __task_cred(task); + inode->i_uid = cred->euid; ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; ++#else + inode->i_gid = cred->egid; ++#endif + rcu_read_unlock(); + } else { + inode->i_uid = 0; +@@ -1625,7 +1686,8 @@ static int proc_fd_info(struct inode *in + int fd = proc_fd(inode); + + if (task) { +- files = get_files_struct(task); ++ if (!gr_acl_handle_procpidmem(task)) ++ files = get_files_struct(task); + put_task_struct(task); + } + if (files) { +@@ -1877,12 +1939,22 @@ static const struct file_operations proc + static int proc_fd_permission(struct inode *inode, int mask) + { + int rv; ++ struct task_struct *task; + + rv = generic_permission(inode, mask, NULL); +- if (rv == 0) +- return 0; ++ + if (task_pid(current) == proc_pid(inode)) + rv = 0; ++ ++ task = get_proc_task(inode); ++ if (task == NULL) ++ return rv; ++ ++ if (gr_acl_handle_procpidmem(task)) ++ rv = -EACCES; ++ ++ put_task_struct(task); ++ + return rv; + } + +@@ -1991,6 +2063,9 @@ static struct dentry *proc_pident_lookup + if (!task) + goto out_no_task; + ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)) ++ goto out; ++ + /* + * Yes, it does not scale. And it should not. Don't add + * new entries into /proc/<tgid>/ without very good reasons. +@@ -2035,6 +2110,9 @@ static int proc_pident_readdir(struct fi + if (!task) + goto out_no_task; + ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)) ++ goto out; ++ + ret = 0; + i = filp->f_pos; + switch (i) { +@@ -2401,6 +2479,9 @@ static struct dentry *proc_base_lookup(s + if (p > last) + goto out; + ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)) ++ goto out; ++ + error = proc_base_instantiate(dir, dentry, task, p); + + out: +@@ -2487,7 +2568,7 @@ static const struct pid_entry tgid_base_ + #ifdef CONFIG_SCHED_DEBUG + REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), + #endif +-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK ++#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP) + INF("syscall", S_IRUSR, proc_pid_syscall), + #endif + INF("cmdline", S_IRUGO, proc_pid_cmdline), +@@ -2515,7 +2596,7 @@ static const struct pid_entry tgid_base_ + #ifdef CONFIG_KALLSYMS + INF("wchan", S_IRUGO, proc_pid_wchan), + #endif +-#ifdef CONFIG_STACKTRACE ++#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM) + ONE("stack", S_IRUSR, proc_pid_stack), + #endif + #ifdef CONFIG_SCHEDSTATS +@@ -2545,6 +2626,9 @@ static const struct pid_entry tgid_base_ + #ifdef CONFIG_TASK_IO_ACCOUNTING + INF("io", S_IRUGO, proc_tgid_io_accounting), + #endif ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR ++ INF("ipaddr", S_IRUSR, proc_pid_ipaddr), ++#endif + }; + + static int proc_tgid_base_readdir(struct file * filp, +@@ -2674,7 +2758,14 @@ static struct dentry *proc_pid_instantia + if (!inode) + goto out; + ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR; ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP; ++#else + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; ++#endif + inode->i_op = &proc_tgid_base_inode_operations; + inode->i_fop = &proc_tgid_base_operations; + inode->i_flags|=S_IMMUTABLE; +@@ -2716,7 +2807,11 @@ struct dentry *proc_pid_lookup(struct in + if (!task) + goto out; + ++ if (gr_check_hidden_task(task)) ++ goto out_put_task; ++ + result = proc_pid_instantiate(dir, dentry, task, NULL); ++out_put_task: + put_task_struct(task); + out: + return result; +@@ -2781,6 +2876,10 @@ int proc_pid_readdir(struct file * filp, + { + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; + struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ const struct cred *tmpcred = current_cred(); ++ const struct cred *itercred; ++#endif + struct tgid_iter iter; + struct pid_namespace *ns; + +@@ -2799,6 +2898,20 @@ int proc_pid_readdir(struct file * filp, + for (iter = next_tgid(ns, iter); + iter.task; + iter.tgid += 1, iter = next_tgid(ns, iter)) { ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ itercred = __task_cred(iter.task); ++#endif ++ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task) ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ || (tmpcred->uid && (itercred->uid != tmpcred->uid) ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP ++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID) ++#endif ++ ) ++#endif ++ ) ++ continue; ++ + filp->f_pos = iter.tgid + TGID_OFFSET; + if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) { + put_task_struct(iter.task); +@@ -2826,7 +2939,7 @@ static const struct pid_entry tid_base_s + #ifdef CONFIG_SCHED_DEBUG + REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), + #endif +-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK ++#if defined(CONFIG_HAVE_ARCH_TRACEHOOK) && !defined(CONFIG_GRKERNSEC_PROC_MEMMAP) + INF("syscall", S_IRUSR, proc_pid_syscall), + #endif + INF("cmdline", S_IRUGO, proc_pid_cmdline), +@@ -2853,7 +2966,7 @@ static const struct pid_entry tid_base_s + #ifdef CONFIG_KALLSYMS + INF("wchan", S_IRUGO, proc_pid_wchan), + #endif +-#ifdef CONFIG_STACKTRACE ++#if defined(CONFIG_STACKTRACE) && !defined(CONFIG_GRKERNSEC_HIDESYM) + ONE("stack", S_IRUSR, proc_pid_stack), + #endif + #ifdef CONFIG_SCHEDSTATS +diff -urNp linux-2.6.31.1/fs/proc/cmdline.c linux-2.6.31.1/fs/proc/cmdline.c +--- linux-2.6.31.1/fs/proc/cmdline.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/cmdline.c 2009-10-01 20:12:44.000000000 -0400 +@@ -23,7 +23,11 @@ static const struct file_operations cmdl + + static int __init proc_cmdline_init(void) + { ++#ifdef CONFIG_GRKERNSEC_PROC_ADD ++ proc_create_grsec("cmdline", 0, NULL, &cmdline_proc_fops); ++#else + proc_create("cmdline", 0, NULL, &cmdline_proc_fops); ++#endif + return 0; + } + module_init(proc_cmdline_init); +diff -urNp linux-2.6.31.1/fs/proc/devices.c linux-2.6.31.1/fs/proc/devices.c +--- linux-2.6.31.1/fs/proc/devices.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/devices.c 2009-10-01 20:12:44.000000000 -0400 +@@ -64,7 +64,11 @@ static const struct file_operations proc + + static int __init proc_devices_init(void) + { ++#ifdef CONFIG_GRKERNSEC_PROC_ADD ++ proc_create_grsec("devices", 0, NULL, &proc_devinfo_operations); ++#else + proc_create("devices", 0, NULL, &proc_devinfo_operations); ++#endif + return 0; + } + module_init(proc_devices_init); +diff -urNp linux-2.6.31.1/fs/proc/inode.c linux-2.6.31.1/fs/proc/inode.c +--- linux-2.6.31.1/fs/proc/inode.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/inode.c 2009-10-01 20:12:44.000000000 -0400 +@@ -457,7 +457,11 @@ struct inode *proc_get_inode(struct supe + if (de->mode) { + inode->i_mode = de->mode; + inode->i_uid = de->uid; ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; ++#else + inode->i_gid = de->gid; ++#endif + } + if (de->size) + inode->i_size = de->size; +diff -urNp linux-2.6.31.1/fs/proc/internal.h linux-2.6.31.1/fs/proc/internal.h +--- linux-2.6.31.1/fs/proc/internal.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/internal.h 2009-10-01 20:12:44.000000000 -0400 +@@ -51,6 +51,9 @@ extern int proc_pid_status(struct seq_fi + struct pid *pid, struct task_struct *task); + extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *task); ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR ++extern int proc_pid_ipaddr(struct task_struct *task, char *buffer); ++#endif + extern loff_t mem_lseek(struct file *file, loff_t offset, int orig); + + extern const struct file_operations proc_maps_operations; +diff -urNp linux-2.6.31.1/fs/proc/Kconfig linux-2.6.31.1/fs/proc/Kconfig +--- linux-2.6.31.1/fs/proc/Kconfig 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/Kconfig 2009-10-01 20:12:44.000000000 -0400 +@@ -30,12 +30,12 @@ config PROC_FS + + config PROC_KCORE + bool "/proc/kcore support" if !ARM +- depends on PROC_FS && MMU ++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD + + config PROC_VMCORE + bool "/proc/vmcore support (EXPERIMENTAL)" +- depends on PROC_FS && CRASH_DUMP +- default y ++ depends on PROC_FS && CRASH_DUMP && !GRKERNSEC ++ default n + help + Exports the dump image of crashed kernel in ELF format. + +@@ -59,8 +59,8 @@ config PROC_SYSCTL + limited in memory. + + config PROC_PAGE_MONITOR +- default y +- depends on PROC_FS && MMU ++ default n ++ depends on PROC_FS && MMU && !GRKERNSEC + bool "Enable /proc page monitoring" if EMBEDDED + help + Various /proc files exist to monitor process memory utilization: +diff -urNp linux-2.6.31.1/fs/proc/kcore.c linux-2.6.31.1/fs/proc/kcore.c +--- linux-2.6.31.1/fs/proc/kcore.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/kcore.c 2009-10-01 20:12:44.000000000 -0400 +@@ -404,10 +404,12 @@ read_kcore(struct file *file, char __use + + static int __init proc_kcore_init(void) + { ++#if !defined(CONFIG_GRKERNSEC_PROC_ADD) && !defined(CONFIG_GRKERNSEC_HIDESYM) + proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations); + if (proc_root_kcore) + proc_root_kcore->size = + (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; ++#endif + return 0; + } + module_init(proc_kcore_init); +diff -urNp linux-2.6.31.1/fs/proc/nommu.c linux-2.6.31.1/fs/proc/nommu.c +--- linux-2.6.31.1/fs/proc/nommu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/nommu.c 2009-10-01 20:12:44.000000000 -0400 +@@ -67,7 +67,7 @@ static int nommu_region_show(struct seq_ + if (len < 1) + len = 1; + seq_printf(m, "%*c", len, ' '); +- seq_path(m, &file->f_path, ""); ++ seq_path(m, &file->f_path, "\n\"); + } + + seq_putc(m, '\n'); +@@ -109,7 +109,7 @@ static void *nommu_region_list_next(stru + return rb_next((struct rb_node *) v); + } + +-static struct seq_operations proc_nommu_region_list_seqop = { ++static const struct seq_operations proc_nommu_region_list_seqop = { + .start = nommu_region_list_start, + .next = nommu_region_list_next, + .stop = nommu_region_list_stop, +diff -urNp linux-2.6.31.1/fs/proc/proc_net.c linux-2.6.31.1/fs/proc/proc_net.c +--- linux-2.6.31.1/fs/proc/proc_net.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/proc_net.c 2009-10-01 20:12:44.000000000 -0400 +@@ -104,6 +104,17 @@ static struct net *get_proc_task_net(str + struct task_struct *task; + struct nsproxy *ns; + struct net *net = NULL; ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ const struct cred *cred = current_cred(); ++#endif ++ ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ if (cred->fsuid) ++ return net; ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ if (cred->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)) ++ return net; ++#endif + + rcu_read_lock(); + task = pid_task(proc_pid(dir), PIDTYPE_PID); +diff -urNp linux-2.6.31.1/fs/proc/proc_sysctl.c linux-2.6.31.1/fs/proc/proc_sysctl.c +--- linux-2.6.31.1/fs/proc/proc_sysctl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/proc_sysctl.c 2009-10-01 20:12:44.000000000 -0400 +@@ -7,6 +7,8 @@ + #include <linux/security.h> + #include "internal.h" + ++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op); ++ + static const struct dentry_operations proc_sys_dentry_operations; + static const struct file_operations proc_sys_file_operations; + static const struct inode_operations proc_sys_inode_operations; +@@ -109,6 +111,9 @@ static struct dentry *proc_sys_lookup(st + if (!p) + goto out; + ++ if (gr_handle_sysctl(p, MAY_EXEC)) ++ goto out; ++ + err = ERR_PTR(-ENOMEM); + inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p); + if (h) +@@ -228,6 +233,9 @@ static int scan(struct ctl_table_header + if (*pos < file->f_pos) + continue; + ++ if (gr_handle_sysctl(table, 0)) ++ continue; ++ + res = proc_sys_fill_cache(file, dirent, filldir, head, table); + if (res) + return res; +@@ -344,6 +352,9 @@ static int proc_sys_getattr(struct vfsmo + if (IS_ERR(head)) + return PTR_ERR(head); + ++ if (table && gr_handle_sysctl(table, MAY_EXEC)) ++ return -ENOENT; ++ + generic_fillattr(inode, stat); + if (table) + stat->mode = (stat->mode & S_IFMT) | table->mode; +diff -urNp linux-2.6.31.1/fs/proc/root.c linux-2.6.31.1/fs/proc/root.c +--- linux-2.6.31.1/fs/proc/root.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/root.c 2009-10-01 20:12:44.000000000 -0400 +@@ -134,7 +134,15 @@ void __init proc_root_init(void) + #ifdef CONFIG_PROC_DEVICETREE + proc_device_tree_init(); + #endif ++#ifdef CONFIG_GRKERNSEC_PROC_ADD ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL); ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL); ++#endif ++#else + proc_mkdir("bus", NULL); ++#endif + proc_sys_init(); + } + +diff -urNp linux-2.6.31.1/fs/proc/task_mmu.c linux-2.6.31.1/fs/proc/task_mmu.c +--- linux-2.6.31.1/fs/proc/task_mmu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/task_mmu.c 2009-10-01 20:12:44.000000000 -0400 +@@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct + "VmStk:\t%8lu kB\n" + "VmExe:\t%8lu kB\n" + "VmLib:\t%8lu kB\n" +- "VmPTE:\t%8lu kB\n", +- hiwater_vm << (PAGE_SHIFT-10), ++ "VmPTE:\t%8lu kB\n" ++ ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT ++ "CsBase:\t%8lx\nCsLim:\t%8lx\n" ++#endif ++ ++ ,hiwater_vm << (PAGE_SHIFT-10), + (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), + mm->locked_vm << (PAGE_SHIFT-10), + hiwater_rss << (PAGE_SHIFT-10), + total_rss << (PAGE_SHIFT-10), + data << (PAGE_SHIFT-10), + mm->stack_vm << (PAGE_SHIFT-10), text, lib, +- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); ++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10 ++ ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT ++ , mm->context.user_cs_base, mm->context.user_cs_limit ++#endif ++ ++ ); + } + + unsigned long task_vsize(struct mm_struct *mm) +@@ -199,6 +210,12 @@ static int do_maps_open(struct inode *in + return ret; + } + ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \ ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \ ++ _mm->pax_flags & MF_PAX_SEGMEXEC)) ++#endif ++ + static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) + { + struct mm_struct *mm = vma->vm_mm; +@@ -217,13 +234,22 @@ static void show_map_vma(struct seq_file + } + + seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start, ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end, ++#else + vma->vm_start, + vma->vm_end, ++#endif + flags & VM_READ ? 'r' : '-', + flags & VM_WRITE ? 'w' : '-', + flags & VM_EXEC ? 'x' : '-', + flags & VM_MAYSHARE ? 's' : 'p', ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ PAX_RAND_FLAGS(mm) ? 0UL : pgoff, ++#else + pgoff, ++#endif + MAJOR(dev), MINOR(dev), ino, &len); + + /* +@@ -232,16 +258,16 @@ static void show_map_vma(struct seq_file + */ + if (file) { + pad_len_spaces(m, len); +- seq_path(m, &file->f_path, "\n"); ++ seq_path(m, &file->f_path, "\n\"); + } else { + const char *name = arch_vma_name(vma); + if (!name) { + if (mm) { +- if (vma->vm_start <= mm->start_brk && +- vma->vm_end >= mm->brk) { ++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { + name = "[heap]"; +- } else if (vma->vm_start <= mm->start_stack && +- vma->vm_end >= mm->start_stack) { ++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) || ++ (vma->vm_start <= mm->start_stack && ++ vma->vm_end >= mm->start_stack)) { + name = "[stack]"; + } + } else { +@@ -384,9 +410,16 @@ static int show_smap(struct seq_file *m, + }; + + memset(&mss, 0, sizeof mss); +- mss.vma = vma; +- if (vma->vm_mm && !is_vm_hugetlb_page(vma)) +- walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk); ++ ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ if (!PAX_RAND_FLAGS(vma->vm_mm)) { ++#endif ++ mss.vma = vma; ++ if (vma->vm_mm && !is_vm_hugetlb_page(vma)) ++ walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk); ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ } ++#endif + + show_map_vma(m, vma); + +@@ -402,7 +435,11 @@ static int show_smap(struct seq_file *m, + "Swap: %8lu kB\n" + "KernelPageSize: %8lu kB\n" + "MMUPageSize: %8lu kB\n", ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10, ++#else + (vma->vm_end - vma->vm_start) >> 10, ++#endif + mss.resident >> 10, + (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), + mss.shared_clean >> 10, +diff -urNp linux-2.6.31.1/fs/proc/task_nommu.c linux-2.6.31.1/fs/proc/task_nommu.c +--- linux-2.6.31.1/fs/proc/task_nommu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/proc/task_nommu.c 2009-10-01 20:12:44.000000000 -0400 +@@ -50,7 +50,7 @@ void task_mem(struct seq_file *m, struct + else + bytes += kobjsize(mm); + +- if (current->fs && current->fs->users > 1) ++ if (current->fs && atomic_read(¤t->fs->users) > 1) + sbytes += kobjsize(current->fs); + else + bytes += kobjsize(current->fs); +@@ -154,7 +154,7 @@ static int nommu_vma_show(struct seq_fil + if (len < 1) + len = 1; + seq_printf(m, "%*c", len, ' '); +- seq_path(m, &file->f_path, ""); ++ seq_path(m, &file->f_path, "\n\"); + } + + seq_putc(m, '\n'); +diff -urNp linux-2.6.31.1/fs/readdir.c linux-2.6.31.1/fs/readdir.c +--- linux-2.6.31.1/fs/readdir.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/readdir.c 2009-10-01 20:12:44.000000000 -0400 +@@ -16,6 +16,7 @@ + #include <linux/security.h> + #include <linux/syscalls.h> + #include <linux/unistd.h> ++#include <linux/namei.h> + + #include <asm/uaccess.h> + +@@ -67,6 +68,7 @@ struct old_linux_dirent { + + struct readdir_callback { + struct old_linux_dirent __user * dirent; ++ struct file * file; + int result; + }; + +@@ -84,6 +86,10 @@ static int fillonedir(void * __buf, cons + buf->result = -EOVERFLOW; + return -EOVERFLOW; + } ++ ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino)) ++ return 0; ++ + buf->result++; + dirent = buf->dirent; + if (!access_ok(VERIFY_WRITE, dirent, +@@ -116,6 +122,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned in + + buf.result = 0; + buf.dirent = dirent; ++ buf.file = file; + + error = vfs_readdir(file, fillonedir, &buf); + if (buf.result) +@@ -142,6 +149,7 @@ struct linux_dirent { + struct getdents_callback { + struct linux_dirent __user * current_dir; + struct linux_dirent __user * previous; ++ struct file * file; + int count; + int error; + }; +@@ -162,6 +170,10 @@ static int filldir(void * __buf, const c + buf->error = -EOVERFLOW; + return -EOVERFLOW; + } ++ ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino)) ++ return 0; ++ + dirent = buf->previous; + if (dirent) { + if (__put_user(offset, &dirent->d_off)) +@@ -209,6 +221,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, + buf.previous = NULL; + buf.count = count; + buf.error = 0; ++ buf.file = file; + + error = vfs_readdir(file, filldir, &buf); + if (error >= 0) +@@ -228,6 +241,7 @@ out: + struct getdents_callback64 { + struct linux_dirent64 __user * current_dir; + struct linux_dirent64 __user * previous; ++ struct file *file; + int count; + int error; + }; +@@ -242,6 +256,10 @@ static int filldir64(void * __buf, const + buf->error = -EINVAL; /* only used if we fail.. */ + if (reclen > buf->count) + return -EINVAL; ++ ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino)) ++ return 0; ++ + dirent = buf->previous; + if (dirent) { + if (__put_user(offset, &dirent->d_off)) +@@ -289,6 +307,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int + + buf.current_dir = dirent; + buf.previous = NULL; ++ buf.file = file; + buf.count = count; + buf.error = 0; + +diff -urNp linux-2.6.31.1/fs/reiserfs/do_balan.c linux-2.6.31.1/fs/reiserfs/do_balan.c +--- linux-2.6.31.1/fs/reiserfs/do_balan.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/reiserfs/do_balan.c 2009-10-01 20:12:44.000000000 -0400 +@@ -2058,7 +2058,7 @@ void do_balance(struct tree_balance *tb, + return; + } + +- atomic_inc(&(fs_generation(tb->tb_sb))); ++ atomic_inc_unchecked(&(fs_generation(tb->tb_sb))); + do_balance_starts(tb); + + /* balance leaf returns 0 except if combining L R and S into +diff -urNp linux-2.6.31.1/fs/reiserfs/procfs.c linux-2.6.31.1/fs/reiserfs/procfs.c +--- linux-2.6.31.1/fs/reiserfs/procfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/reiserfs/procfs.c 2009-10-01 20:12:44.000000000 -0400 +@@ -123,7 +123,7 @@ static int show_super(struct seq_file *m + "SMALL_TAILS " : "NO_TAILS ", + replay_only(sb) ? "REPLAY_ONLY " : "", + convert_reiserfs(sb) ? "CONV " : "", +- atomic_read(&r->s_generation_counter), ++ atomic_read_unchecked(&r->s_generation_counter), + SF(s_disk_reads), SF(s_disk_writes), SF(s_fix_nodes), + SF(s_do_balance), SF(s_unneeded_left_neighbor), + SF(s_good_search_by_key_reada), SF(s_bmaps), +diff -urNp linux-2.6.31.1/fs/romfs/super.c linux-2.6.31.1/fs/romfs/super.c +--- linux-2.6.31.1/fs/romfs/super.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/romfs/super.c 2009-10-01 20:12:44.000000000 -0400 +@@ -284,7 +284,7 @@ static const struct file_operations romf + .readdir = romfs_readdir, + }; + +-static struct inode_operations romfs_dir_inode_operations = { ++static const struct inode_operations romfs_dir_inode_operations = { + .lookup = romfs_lookup, + }; + +diff -urNp linux-2.6.31.1/fs/select.c linux-2.6.31.1/fs/select.c +--- linux-2.6.31.1/fs/select.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/select.c 2009-10-01 20:12:44.000000000 -0400 +@@ -19,6 +19,7 @@ + #include <linux/module.h> + #include <linux/slab.h> + #include <linux/poll.h> ++#include <linux/security.h> + #include <linux/personality.h> /* for STICKY_TIMEOUTS */ + #include <linux/file.h> + #include <linux/fdtable.h> +@@ -814,6 +815,7 @@ int do_sys_poll(struct pollfd __user *uf + struct poll_list *walk = head; + unsigned long todo = nfds; + ++ gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1); + if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur) + return -EINVAL; + +diff -urNp linux-2.6.31.1/fs/seq_file.c linux-2.6.31.1/fs/seq_file.c +--- linux-2.6.31.1/fs/seq_file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/seq_file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -76,7 +76,8 @@ static int traverse(struct seq_file *m, + return 0; + } + if (!m->buf) { +- m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); ++ m->size = PAGE_SIZE; ++ m->buf = kmalloc(m->size, GFP_KERNEL); + if (!m->buf) + return -ENOMEM; + } +@@ -116,7 +117,8 @@ static int traverse(struct seq_file *m, + Eoverflow: + m->op->stop(m, p); + kfree(m->buf); +- m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); ++ m->size <<= 1; ++ m->buf = kmalloc(m->size, GFP_KERNEL); + return !m->buf ? -ENOMEM : -EAGAIN; + } + +@@ -169,7 +171,8 @@ ssize_t seq_read(struct file *file, char + m->version = file->f_version; + /* grab buffer if we didn't have one */ + if (!m->buf) { +- m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); ++ m->size = PAGE_SIZE; ++ m->buf = kmalloc(m->size, GFP_KERNEL); + if (!m->buf) + goto Enomem; + } +@@ -210,7 +213,8 @@ ssize_t seq_read(struct file *file, char + goto Fill; + m->op->stop(m, p); + kfree(m->buf); +- m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); ++ m->size <<= 1; ++ m->buf = kmalloc(m->size, GFP_KERNEL); + if (!m->buf) + goto Enomem; + m->count = 0; +diff -urNp linux-2.6.31.1/fs/smbfs/symlink.c linux-2.6.31.1/fs/smbfs/symlink.c +--- linux-2.6.31.1/fs/smbfs/symlink.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/smbfs/symlink.c 2009-10-01 20:12:44.000000000 -0400 +@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent + + static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p) + { +- char *s = nd_get_link(nd); ++ const char *s = nd_get_link(nd); + if (!IS_ERR(s)) + __putname(s); + } +diff -urNp linux-2.6.31.1/fs/squashfs/super.c linux-2.6.31.1/fs/squashfs/super.c +--- linux-2.6.31.1/fs/squashfs/super.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/squashfs/super.c 2009-10-01 20:12:44.000000000 -0400 +@@ -44,7 +44,7 @@ + #include "squashfs.h" + + static struct file_system_type squashfs_fs_type; +-static struct super_operations squashfs_super_ops; ++static const struct super_operations squashfs_super_ops; + + static int supported_squashfs_filesystem(short major, short minor, short comp) + { +@@ -444,7 +444,7 @@ static struct file_system_type squashfs_ + .fs_flags = FS_REQUIRES_DEV + }; + +-static struct super_operations squashfs_super_ops = { ++static const struct super_operations squashfs_super_ops = { + .alloc_inode = squashfs_alloc_inode, + .destroy_inode = squashfs_destroy_inode, + .statfs = squashfs_statfs, +diff -urNp linux-2.6.31.1/fs/sysfs/bin.c linux-2.6.31.1/fs/sysfs/bin.c +--- linux-2.6.31.1/fs/sysfs/bin.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/sysfs/bin.c 2009-10-01 20:12:44.000000000 -0400 +@@ -40,7 +40,7 @@ struct bin_buffer { + struct mutex mutex; + void *buffer; + int mmapped; +- struct vm_operations_struct *vm_ops; ++ const struct vm_operations_struct *vm_ops; + struct file *file; + struct hlist_node list; + }; +@@ -331,7 +331,7 @@ static int bin_migrate(struct vm_area_st + } + #endif + +-static struct vm_operations_struct bin_vm_ops = { ++static const struct vm_operations_struct bin_vm_ops = { + .open = bin_vma_open, + .close = bin_vma_close, + .fault = bin_fault, +diff -urNp linux-2.6.31.1/fs/sysfs/symlink.c linux-2.6.31.1/fs/sysfs/symlink.c +--- linux-2.6.31.1/fs/sysfs/symlink.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/sysfs/symlink.c 2009-10-01 20:12:44.000000000 -0400 +@@ -203,7 +203,7 @@ static void *sysfs_follow_link(struct de + + static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) + { +- char *page = nd_get_link(nd); ++ const char *page = nd_get_link(nd); + if (!IS_ERR(page)) + free_page((unsigned long)page); + } +diff -urNp linux-2.6.31.1/fs/ubifs/file.c linux-2.6.31.1/fs/ubifs/file.c +--- linux-2.6.31.1/fs/ubifs/file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/ubifs/file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1536,7 +1536,7 @@ out_unlock: + return err; + } + +-static struct vm_operations_struct ubifs_file_vm_ops = { ++static const struct vm_operations_struct ubifs_file_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = ubifs_vm_page_mkwrite, + }; +diff -urNp linux-2.6.31.1/fs/udf/balloc.c linux-2.6.31.1/fs/udf/balloc.c +--- linux-2.6.31.1/fs/udf/balloc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/udf/balloc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -172,9 +172,7 @@ static void udf_bitmap_free_blocks(struc + + mutex_lock(&sbi->s_alloc_mutex); + partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; +- if (bloc->logicalBlockNum < 0 || +- (bloc->logicalBlockNum + count) > +- partmap->s_partition_len) { ++ if ((bloc->logicalBlockNum + count) > partmap->s_partition_len) { + udf_debug("%d < %d || %d + %d > %d\n", + bloc->logicalBlockNum, 0, bloc->logicalBlockNum, + count, partmap->s_partition_len); +@@ -436,9 +434,7 @@ static void udf_table_free_blocks(struct + + mutex_lock(&sbi->s_alloc_mutex); + partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; +- if (bloc->logicalBlockNum < 0 || +- (bloc->logicalBlockNum + count) > +- partmap->s_partition_len) { ++ if ((bloc->logicalBlockNum + count) > partmap->s_partition_len) { + udf_debug("%d < %d || %d + %d > %d\n", + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, + partmap->s_partition_len); +diff -urNp linux-2.6.31.1/fs/utimes.c linux-2.6.31.1/fs/utimes.c +--- linux-2.6.31.1/fs/utimes.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/utimes.c 2009-10-01 20:12:44.000000000 -0400 +@@ -1,6 +1,7 @@ + #include <linux/compiler.h> + #include <linux/file.h> + #include <linux/fs.h> ++#include <linux/security.h> + #include <linux/linkage.h> + #include <linux/mount.h> + #include <linux/namei.h> +@@ -101,6 +102,12 @@ static int utimes_common(struct path *pa + goto mnt_drop_write_and_out; + } + } ++ ++ if (!gr_acl_handle_utime(path->dentry, path->mnt)) { ++ error = -EACCES; ++ goto mnt_drop_write_and_out; ++ } ++ + mutex_lock(&inode->i_mutex); + error = notify_change(path->dentry, &newattrs); + mutex_unlock(&inode->i_mutex); +diff -urNp linux-2.6.31.1/fs/xfs/linux-2.6/xfs_file.c linux-2.6.31.1/fs/xfs/linux-2.6/xfs_file.c +--- linux-2.6.31.1/fs/xfs/linux-2.6/xfs_file.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/xfs/linux-2.6/xfs_file.c 2009-10-01 20:12:44.000000000 -0400 +@@ -42,7 +42,7 @@ + + #include <linux/dcache.h> + +-static struct vm_operations_struct xfs_file_vm_ops; ++static const struct vm_operations_struct xfs_file_vm_ops; + + STATIC ssize_t + xfs_file_aio_read( +@@ -271,7 +271,7 @@ const struct file_operations xfs_dir_fil + .fsync = xfs_file_fsync, + }; + +-static struct vm_operations_struct xfs_file_vm_ops = { ++static const struct vm_operations_struct xfs_file_vm_ops = { + .fault = filemap_fault, + .page_mkwrite = xfs_vm_page_mkwrite, + }; +diff -urNp linux-2.6.31.1/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.31.1/fs/xfs/linux-2.6/xfs_iops.c +--- linux-2.6.31.1/fs/xfs/linux-2.6/xfs_iops.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/xfs/linux-2.6/xfs_iops.c 2009-10-01 20:12:44.000000000 -0400 +@@ -478,7 +478,7 @@ xfs_vn_put_link( + struct nameidata *nd, + void *p) + { +- char *s = nd_get_link(nd); ++ const char *s = nd_get_link(nd); + + if (!IS_ERR(s)) + kfree(s); +diff -urNp linux-2.6.31.1/fs/xfs/linux-2.6/xfs_super.c linux-2.6.31.1/fs/xfs/linux-2.6/xfs_super.c +--- linux-2.6.31.1/fs/xfs/linux-2.6/xfs_super.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/xfs/linux-2.6/xfs_super.c 2009-10-01 20:12:44.000000000 -0400 +@@ -67,7 +67,7 @@ + #include <linux/freezer.h> + #include <linux/parser.h> + +-static struct super_operations xfs_super_operations; ++static const struct super_operations xfs_super_operations; + static kmem_zone_t *xfs_ioend_zone; + mempool_t *xfs_ioend_pool; + +@@ -1532,7 +1532,7 @@ xfs_fs_get_sb( + mnt); + } + +-static struct super_operations xfs_super_operations = { ++static const struct super_operations xfs_super_operations = { + .alloc_inode = xfs_fs_alloc_inode, + .destroy_inode = xfs_fs_destroy_inode, + .write_inode = xfs_fs_write_inode, +diff -urNp linux-2.6.31.1/fs/xfs/xfs_bmap.c linux-2.6.31.1/fs/xfs/xfs_bmap.c +--- linux-2.6.31.1/fs/xfs/xfs_bmap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/fs/xfs/xfs_bmap.c 2009-10-01 20:12:44.000000000 -0400 +@@ -360,7 +360,7 @@ xfs_bmap_validate_ret( + int nmap, + int ret_nmap); + #else +-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) ++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0) + #endif /* DEBUG */ + + #if defined(XFS_RW_TRACE) +diff -urNp linux-2.6.31.1/grsecurity/gracl_alloc.c linux-2.6.31.1/grsecurity/gracl_alloc.c +--- linux-2.6.31.1/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/gracl_alloc.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,105 @@ ++#include <linux/kernel.h> ++#include <linux/mm.h> ++#include <linux/slab.h> ++#include <linux/vmalloc.h> ++#include <linux/gracl.h> ++#include <linux/grsecurity.h> ++ ++static unsigned long alloc_stack_next = 1; ++static unsigned long alloc_stack_size = 1; ++static void **alloc_stack; ++ ++static __inline__ int ++alloc_pop(void) ++{ ++ if (alloc_stack_next == 1) ++ return 0; ++ ++ kfree(alloc_stack[alloc_stack_next - 2]); ++ ++ alloc_stack_next--; ++ ++ return 1; ++} ++ ++static __inline__ int ++alloc_push(void *buf) ++{ ++ if (alloc_stack_next >= alloc_stack_size) ++ return 1; ++ ++ alloc_stack[alloc_stack_next - 1] = buf; ++ ++ alloc_stack_next++; ++ ++ return 0; ++} ++ ++void * ++acl_alloc(unsigned long len) ++{ ++ void *ret = NULL; ++ ++ if (!len || len > PAGE_SIZE) ++ goto out; ++ ++ ret = kmalloc(len, GFP_KERNEL); ++ ++ if (ret) { ++ if (alloc_push(ret)) { ++ kfree(ret); ++ ret = NULL; ++ } ++ } ++ ++out: ++ return ret; ++} ++ ++void * ++acl_alloc_num(unsigned long num, unsigned long len) ++{ ++ if (!len || (num > (PAGE_SIZE / len))) ++ return NULL; ++ ++ return acl_alloc(num * len); ++} ++ ++void ++acl_free_all(void) ++{ ++ if (gr_acl_is_enabled() || !alloc_stack) ++ return; ++ ++ while (alloc_pop()) ; ++ ++ if (alloc_stack) { ++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE) ++ kfree(alloc_stack); ++ else ++ vfree(alloc_stack); ++ } ++ ++ alloc_stack = NULL; ++ alloc_stack_size = 1; ++ alloc_stack_next = 1; ++ ++ return; ++} ++ ++int ++acl_alloc_stack_init(unsigned long size) ++{ ++ if ((size * sizeof (void *)) <= PAGE_SIZE) ++ alloc_stack = ++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL); ++ else ++ alloc_stack = (void **) vmalloc(size * sizeof (void *)); ++ ++ alloc_stack_size = size; ++ ++ if (!alloc_stack) ++ return 0; ++ else ++ return 1; ++} +diff -urNp linux-2.6.31.1/grsecurity/gracl.c linux-2.6.31.1/grsecurity/gracl.c +--- linux-2.6.31.1/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/gracl.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,3912 @@ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/mm.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++#include <linux/namei.h> ++#include <linux/mount.h> ++#include <linux/tty.h> ++#include <linux/proc_fs.h> ++#include <linux/smp_lock.h> ++#include <linux/slab.h> ++#include <linux/vmalloc.h> ++#include <linux/types.h> ++#include <linux/sysctl.h> ++#include <linux/netdevice.h> ++#include <linux/ptrace.h> ++#include <linux/gracl.h> ++#include <linux/gralloc.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++#include <linux/pid_namespace.h> ++#include <linux/fdtable.h> ++#include <linux/percpu.h> ++ ++#include <asm/uaccess.h> ++#include <asm/errno.h> ++#include <asm/mman.h> ++ ++static struct acl_role_db acl_role_set; ++static struct name_db name_set; ++static struct inodev_db inodev_set; ++ ++/* for keeping track of userspace pointers used for subjects, so we ++ can share references in the kernel as well ++*/ ++ ++static struct dentry *real_root; ++static struct vfsmount *real_root_mnt; ++ ++static struct acl_subj_map_db subj_map_set; ++ ++static struct acl_role_label *default_role; ++ ++static u16 acl_sp_role_value; ++ ++extern char *gr_shared_page[4]; ++static DECLARE_MUTEX(gr_dev_sem); ++DEFINE_RWLOCK(gr_inode_lock); ++ ++struct gr_arg *gr_usermode; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++static unsigned int gr_status __read_only = GR_STATUS_INIT; ++#else ++static unsigned int gr_status = GR_STATUS_INIT; ++#endif ++ ++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum); ++extern void gr_clear_learn_entries(void); ++ ++#ifdef CONFIG_GRKERNSEC_RESLOG ++extern void gr_log_resource(const struct task_struct *task, ++ const int res, const unsigned long wanted, const int gt); ++#endif ++ ++unsigned char *gr_system_salt; ++unsigned char *gr_system_sum; ++ ++static struct sprole_pw **acl_special_roles = NULL; ++static __u16 num_sprole_pws = 0; ++ ++static struct acl_role_label *kernel_role = NULL; ++ ++static unsigned int gr_auth_attempts = 0; ++static unsigned long gr_auth_expires = 0UL; ++ ++extern struct vfsmount *sock_mnt; ++extern struct vfsmount *pipe_mnt; ++extern struct vfsmount *shm_mnt; ++static struct acl_object_label *fakefs_obj; ++ ++extern int gr_init_uidset(void); ++extern void gr_free_uidset(void); ++extern void gr_remove_uid(uid_t uid); ++extern int gr_find_uid(uid_t uid); ++ ++__inline__ int ++gr_acl_is_enabled(void) ++{ ++ return (gr_status & GR_READY); ++} ++ ++char gr_roletype_to_char(void) ++{ ++ switch (current->role->roletype & ++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP | ++ GR_ROLE_SPECIAL)) { ++ case GR_ROLE_DEFAULT: ++ return 'D'; ++ case GR_ROLE_USER: ++ return 'U'; ++ case GR_ROLE_GROUP: ++ return 'G'; ++ case GR_ROLE_SPECIAL: ++ return 'S'; ++ } ++ ++ return 'X'; ++} ++ ++__inline__ int ++gr_acl_tpe_check(void) ++{ ++ if (unlikely(!(gr_status & GR_READY))) ++ return 0; ++ if (current->role->roletype & GR_ROLE_TPE) ++ return 1; ++ else ++ return 0; ++} ++ ++int ++gr_handle_rawio(const struct inode *inode) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS ++ if (inode && S_ISBLK(inode->i_mode) && ++ grsec_enable_chroot_caps && proc_is_chrooted(current) && ++ !capable(CAP_SYS_RAWIO)) ++ return 1; ++#endif ++ return 0; ++} ++ ++static int ++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb) ++{ ++ int i; ++ unsigned long *l1; ++ unsigned long *l2; ++ unsigned char *c1; ++ unsigned char *c2; ++ int num_longs; ++ ++ if (likely(lena != lenb)) ++ return 0; ++ ++ l1 = (unsigned long *)a; ++ l2 = (unsigned long *)b; ++ ++ num_longs = lena / sizeof(unsigned long); ++ ++ for (i = num_longs; i--; l1++, l2++) { ++ if (unlikely(*l1 != *l2)) ++ return 0; ++ } ++ ++ c1 = (unsigned char *) l1; ++ c2 = (unsigned char *) l2; ++ ++ i = lena - (num_longs * sizeof(unsigned long)); ++ ++ for (; i--; c1++, c2++) { ++ if (unlikely(*c1 != *c2)) ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt, ++ struct dentry *root, struct vfsmount *rootmnt, ++ char *buffer, int buflen) ++{ ++ char * end = buffer+buflen; ++ char * retval; ++ int namelen; ++ ++ *--end = '\0'; ++ buflen--; ++ ++ if (buflen < 1) ++ goto Elong; ++ /* Get '/' right */ ++ retval = end-1; ++ *retval = '/'; ++ ++ for (;;) { ++ struct dentry * parent; ++ ++ if (dentry == root && vfsmnt == rootmnt) ++ break; ++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { ++ /* Global root? */ ++ spin_lock(&vfsmount_lock); ++ if (vfsmnt->mnt_parent == vfsmnt) { ++ spin_unlock(&vfsmount_lock); ++ goto global_root; ++ } ++ dentry = vfsmnt->mnt_mountpoint; ++ vfsmnt = vfsmnt->mnt_parent; ++ spin_unlock(&vfsmount_lock); ++ continue; ++ } ++ parent = dentry->d_parent; ++ prefetch(parent); ++ namelen = dentry->d_name.len; ++ buflen -= namelen + 1; ++ if (buflen < 0) ++ goto Elong; ++ end -= namelen; ++ memcpy(end, dentry->d_name.name, namelen); ++ *--end = '/'; ++ retval = end; ++ dentry = parent; ++ } ++ ++ return retval; ++ ++global_root: ++ namelen = dentry->d_name.len; ++ buflen -= namelen; ++ if (buflen < 0) ++ goto Elong; ++ retval -= namelen-1; /* hit the slash */ ++ memcpy(retval, dentry->d_name.name, namelen); ++ return retval; ++Elong: ++ return ERR_PTR(-ENAMETOOLONG); ++} ++ ++static char * ++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt, ++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen) ++{ ++ char *retval; ++ ++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen); ++ if (unlikely(IS_ERR(retval))) ++ retval = strcpy(buf, "<path too long>"); ++ else if (unlikely(retval[1] == '/' && retval[2] == '\0')) ++ retval[1] = '\0'; ++ ++ return retval; ++} ++ ++static char * ++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt, ++ char *buf, int buflen) ++{ ++ char *res; ++ ++ /* we can use real_root, real_root_mnt, because this is only called ++ by the RBAC system */ ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen); ++ ++ return res; ++} ++ ++static char * ++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt, ++ char *buf, int buflen) ++{ ++ char *res; ++ struct dentry *root; ++ struct vfsmount *rootmnt; ++ struct task_struct *reaper = &init_task; ++ ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */ ++ read_lock(&reaper->fs->lock); ++ root = dget(reaper->fs->root.dentry); ++ rootmnt = mntget(reaper->fs->root.mnt); ++ read_unlock(&reaper->fs->lock); ++ ++ spin_lock(&dcache_lock); ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen); ++ spin_unlock(&dcache_lock); ++ ++ dput(root); ++ mntput(rootmnt); ++ return res; ++} ++ ++static char * ++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ char *ret; ++ spin_lock(&dcache_lock); ++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()), ++ PAGE_SIZE); ++ spin_unlock(&dcache_lock); ++ return ret; ++} ++ ++char * ++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()), ++ PAGE_SIZE); ++} ++ ++char * ++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()), ++ PAGE_SIZE); ++} ++ ++char * ++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()), ++ PAGE_SIZE); ++} ++ ++char * ++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()), ++ PAGE_SIZE); ++} ++ ++char * ++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()), ++ PAGE_SIZE); ++} ++ ++__inline__ __u32 ++to_gr_audit(const __u32 reqmode) ++{ ++ /* masks off auditable permission flags, then shifts them to create ++ auditing flags, and adds the special case of append auditing if ++ we're requesting write */ ++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0)); ++} ++ ++struct acl_subject_label * ++lookup_subject_map(const struct acl_subject_label *userp) ++{ ++ unsigned int index = shash(userp, subj_map_set.s_size); ++ struct subject_map *match; ++ ++ match = subj_map_set.s_hash[index]; ++ ++ while (match && match->user != userp) ++ match = match->next; ++ ++ if (match != NULL) ++ return match->kernel; ++ else ++ return NULL; ++} ++ ++static void ++insert_subj_map_entry(struct subject_map *subjmap) ++{ ++ unsigned int index = shash(subjmap->user, subj_map_set.s_size); ++ struct subject_map **curr; ++ ++ subjmap->prev = NULL; ++ ++ curr = &subj_map_set.s_hash[index]; ++ if (*curr != NULL) ++ (*curr)->prev = subjmap; ++ ++ subjmap->next = *curr; ++ *curr = subjmap; ++ ++ return; ++} ++ ++static struct acl_role_label * ++lookup_acl_role_label(const struct task_struct *task, const uid_t uid, ++ const gid_t gid) ++{ ++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size); ++ struct acl_role_label *match; ++ struct role_allowed_ip *ipp; ++ unsigned int x; ++ ++ match = acl_role_set.r_hash[index]; ++ ++ while (match) { ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) { ++ for (x = 0; x < match->domain_child_num; x++) { ++ if (match->domain_children[x] == uid) ++ goto found; ++ } ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER) ++ break; ++ match = match->next; ++ } ++found: ++ if (match == NULL) { ++ try_group: ++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size); ++ match = acl_role_set.r_hash[index]; ++ ++ while (match) { ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) { ++ for (x = 0; x < match->domain_child_num; x++) { ++ if (match->domain_children[x] == gid) ++ goto found2; ++ } ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP) ++ break; ++ match = match->next; ++ } ++found2: ++ if (match == NULL) ++ match = default_role; ++ if (match->allowed_ips == NULL) ++ return match; ++ else { ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { ++ if (likely ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) == ++ (ntohl(ipp->addr) & ipp->netmask))) ++ return match; ++ } ++ match = default_role; ++ } ++ } else if (match->allowed_ips == NULL) { ++ return match; ++ } else { ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { ++ if (likely ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) == ++ (ntohl(ipp->addr) & ipp->netmask))) ++ return match; ++ } ++ goto try_group; ++ } ++ ++ return match; ++} ++ ++struct acl_subject_label * ++lookup_acl_subj_label(const ino_t ino, const dev_t dev, ++ const struct acl_role_label *role) ++{ ++ unsigned int index = fhash(ino, dev, role->subj_hash_size); ++ struct acl_subject_label *match; ++ ++ match = role->subj_hash[index]; ++ ++ while (match && (match->inode != ino || match->device != dev || ++ (match->mode & GR_DELETED))) { ++ match = match->next; ++ } ++ ++ if (match && !(match->mode & GR_DELETED)) ++ return match; ++ else ++ return NULL; ++} ++ ++struct acl_subject_label * ++lookup_acl_subj_label_deleted(const ino_t ino, const dev_t dev, ++ const struct acl_role_label *role) ++{ ++ unsigned int index = fhash(ino, dev, role->subj_hash_size); ++ struct acl_subject_label *match; ++ ++ match = role->subj_hash[index]; ++ ++ while (match && (match->inode != ino || match->device != dev || ++ !(match->mode & GR_DELETED))) { ++ match = match->next; ++ } ++ ++ if (match && (match->mode & GR_DELETED)) ++ return match; ++ else ++ return NULL; ++} ++ ++static struct acl_object_label * ++lookup_acl_obj_label(const ino_t ino, const dev_t dev, ++ const struct acl_subject_label *subj) ++{ ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size); ++ struct acl_object_label *match; ++ ++ match = subj->obj_hash[index]; ++ ++ while (match && (match->inode != ino || match->device != dev || ++ (match->mode & GR_DELETED))) { ++ match = match->next; ++ } ++ ++ if (match && !(match->mode & GR_DELETED)) ++ return match; ++ else ++ return NULL; ++} ++ ++static struct acl_object_label * ++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev, ++ const struct acl_subject_label *subj) ++{ ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size); ++ struct acl_object_label *match; ++ ++ match = subj->obj_hash[index]; ++ ++ while (match && (match->inode != ino || match->device != dev || ++ !(match->mode & GR_DELETED))) { ++ match = match->next; ++ } ++ ++ if (match && (match->mode & GR_DELETED)) ++ return match; ++ ++ match = subj->obj_hash[index]; ++ ++ while (match && (match->inode != ino || match->device != dev || ++ (match->mode & GR_DELETED))) { ++ match = match->next; ++ } ++ ++ if (match && !(match->mode & GR_DELETED)) ++ return match; ++ else ++ return NULL; ++} ++ ++static struct name_entry * ++lookup_name_entry(const char *name) ++{ ++ unsigned int len = strlen(name); ++ unsigned int key = full_name_hash(name, len); ++ unsigned int index = key % name_set.n_size; ++ struct name_entry *match; ++ ++ match = name_set.n_hash[index]; ++ ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len))) ++ match = match->next; ++ ++ return match; ++} ++ ++static struct name_entry * ++lookup_name_entry_create(const char *name) ++{ ++ unsigned int len = strlen(name); ++ unsigned int key = full_name_hash(name, len); ++ unsigned int index = key % name_set.n_size; ++ struct name_entry *match; ++ ++ match = name_set.n_hash[index]; ++ ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) || ++ !match->deleted)) ++ match = match->next; ++ ++ if (match && match->deleted) ++ return match; ++ ++ match = name_set.n_hash[index]; ++ ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) || ++ match->deleted)) ++ match = match->next; ++ ++ if (match && !match->deleted) ++ return match; ++ else ++ return NULL; ++} ++ ++static struct inodev_entry * ++lookup_inodev_entry(const ino_t ino, const dev_t dev) ++{ ++ unsigned int index = fhash(ino, dev, inodev_set.i_size); ++ struct inodev_entry *match; ++ ++ match = inodev_set.i_hash[index]; ++ ++ while (match && (match->nentry->inode != ino || match->nentry->device != dev)) ++ match = match->next; ++ ++ return match; ++} ++ ++static void ++insert_inodev_entry(struct inodev_entry *entry) ++{ ++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device, ++ inodev_set.i_size); ++ struct inodev_entry **curr; ++ ++ entry->prev = NULL; ++ ++ curr = &inodev_set.i_hash[index]; ++ if (*curr != NULL) ++ (*curr)->prev = entry; ++ ++ entry->next = *curr; ++ *curr = entry; ++ ++ return; ++} ++ ++static void ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid) ++{ ++ unsigned int index = ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size); ++ struct acl_role_label **curr; ++ ++ role->prev = NULL; ++ ++ curr = &acl_role_set.r_hash[index]; ++ if (*curr != NULL) ++ (*curr)->prev = role; ++ ++ role->next = *curr; ++ *curr = role; ++ ++ return; ++} ++ ++static void ++insert_acl_role_label(struct acl_role_label *role) ++{ ++ int i; ++ ++ if (role->roletype & GR_ROLE_DOMAIN) { ++ for (i = 0; i < role->domain_child_num; i++) ++ __insert_acl_role_label(role, role->domain_children[i]); ++ } else ++ __insert_acl_role_label(role, role->uidgid); ++} ++ ++static int ++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted) ++{ ++ struct name_entry **curr, *nentry; ++ struct inodev_entry *ientry; ++ unsigned int len = strlen(name); ++ unsigned int key = full_name_hash(name, len); ++ unsigned int index = key % name_set.n_size; ++ ++ curr = &name_set.n_hash[index]; ++ ++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len))) ++ curr = &((*curr)->next); ++ ++ if (*curr != NULL) ++ return 1; ++ ++ nentry = acl_alloc(sizeof (struct name_entry)); ++ if (nentry == NULL) ++ return 0; ++ ientry = acl_alloc(sizeof (struct inodev_entry)); ++ if (ientry == NULL) ++ return 0; ++ ientry->nentry = nentry; ++ ++ nentry->key = key; ++ nentry->name = name; ++ nentry->inode = inode; ++ nentry->device = device; ++ nentry->len = len; ++ nentry->deleted = deleted; ++ ++ nentry->prev = NULL; ++ curr = &name_set.n_hash[index]; ++ if (*curr != NULL) ++ (*curr)->prev = nentry; ++ nentry->next = *curr; ++ *curr = nentry; ++ ++ /* insert us into the table searchable by inode/dev */ ++ insert_inodev_entry(ientry); ++ ++ return 1; ++} ++ ++static void ++insert_acl_obj_label(struct acl_object_label *obj, ++ struct acl_subject_label *subj) ++{ ++ unsigned int index = ++ fhash(obj->inode, obj->device, subj->obj_hash_size); ++ struct acl_object_label **curr; ++ ++ ++ obj->prev = NULL; ++ ++ curr = &subj->obj_hash[index]; ++ if (*curr != NULL) ++ (*curr)->prev = obj; ++ ++ obj->next = *curr; ++ *curr = obj; ++ ++ return; ++} ++ ++static void ++insert_acl_subj_label(struct acl_subject_label *obj, ++ struct acl_role_label *role) ++{ ++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size); ++ struct acl_subject_label **curr; ++ ++ obj->prev = NULL; ++ ++ curr = &role->subj_hash[index]; ++ if (*curr != NULL) ++ (*curr)->prev = obj; ++ ++ obj->next = *curr; ++ *curr = obj; ++ ++ return; ++} ++ ++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */ ++ ++static void * ++create_table(__u32 * len, int elementsize) ++{ ++ unsigned int table_sizes[] = { ++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, ++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143, ++ 4194301, 8388593, 16777213, 33554393, 67108859 ++ }; ++ void *newtable = NULL; ++ unsigned int pwr = 0; ++ ++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) && ++ table_sizes[pwr] <= *len) ++ pwr++; ++ ++ if (table_sizes[pwr] <= *len || (table_sizes[pwr] > ULONG_MAX / elementsize)) ++ return newtable; ++ ++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE) ++ newtable = ++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL); ++ else ++ newtable = vmalloc(table_sizes[pwr] * elementsize); ++ ++ *len = table_sizes[pwr]; ++ ++ return newtable; ++} ++ ++static int ++init_variables(const struct gr_arg *arg) ++{ ++ struct task_struct *reaper = &init_task; ++ unsigned int stacksize; ++ ++ subj_map_set.s_size = arg->role_db.num_subjects; ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children; ++ name_set.n_size = arg->role_db.num_objects; ++ inodev_set.i_size = arg->role_db.num_objects; ++ ++ if (!subj_map_set.s_size || !acl_role_set.r_size || ++ !name_set.n_size || !inodev_set.i_size) ++ return 1; ++ ++ if (!gr_init_uidset()) ++ return 1; ++ ++ /* set up the stack that holds allocation info */ ++ ++ stacksize = arg->role_db.num_pointers + 5; ++ ++ if (!acl_alloc_stack_init(stacksize)) ++ return 1; ++ ++ /* grab reference for the real root dentry and vfsmount */ ++ read_lock(&reaper->fs->lock); ++ real_root_mnt = mntget(reaper->fs->root.mnt); ++ real_root = dget(reaper->fs->root.dentry); ++ read_unlock(&reaper->fs->lock); ++ ++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label)); ++ if (fakefs_obj == NULL) ++ return 1; ++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC; ++ ++ subj_map_set.s_hash = ++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *)); ++ acl_role_set.r_hash = ++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *)); ++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *)); ++ inodev_set.i_hash = ++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *)); ++ ++ if (!subj_map_set.s_hash || !acl_role_set.r_hash || ++ !name_set.n_hash || !inodev_set.i_hash) ++ return 1; ++ ++ memset(subj_map_set.s_hash, 0, ++ sizeof(struct subject_map *) * subj_map_set.s_size); ++ memset(acl_role_set.r_hash, 0, ++ sizeof (struct acl_role_label *) * acl_role_set.r_size); ++ memset(name_set.n_hash, 0, ++ sizeof (struct name_entry *) * name_set.n_size); ++ memset(inodev_set.i_hash, 0, ++ sizeof (struct inodev_entry *) * inodev_set.i_size); ++ ++ return 0; ++} ++ ++/* free information not needed after startup ++ currently contains user->kernel pointer mappings for subjects ++*/ ++ ++static void ++free_init_variables(void) ++{ ++ __u32 i; ++ ++ if (subj_map_set.s_hash) { ++ for (i = 0; i < subj_map_set.s_size; i++) { ++ if (subj_map_set.s_hash[i]) { ++ kfree(subj_map_set.s_hash[i]); ++ subj_map_set.s_hash[i] = NULL; ++ } ++ } ++ ++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <= ++ PAGE_SIZE) ++ kfree(subj_map_set.s_hash); ++ else ++ vfree(subj_map_set.s_hash); ++ } ++ ++ return; ++} ++ ++static void ++free_variables(void) ++{ ++ struct acl_subject_label *s; ++ struct acl_role_label *r; ++ struct task_struct *task, *task2; ++ unsigned int i, x; ++ ++ gr_clear_learn_entries(); ++ ++ read_lock(&tasklist_lock); ++ do_each_thread(task2, task) { ++ task->acl_sp_role = 0; ++ task->acl_role_id = 0; ++ task->acl = NULL; ++ task->role = NULL; ++ } while_each_thread(task2, task); ++ read_unlock(&tasklist_lock); ++ ++ /* release the reference to the real root dentry and vfsmount */ ++ if (real_root) ++ dput(real_root); ++ real_root = NULL; ++ if (real_root_mnt) ++ mntput(real_root_mnt); ++ real_root_mnt = NULL; ++ ++ /* free all object hash tables */ ++ ++ FOR_EACH_ROLE_START(r, i) ++ if (r->subj_hash == NULL) ++ break; ++ FOR_EACH_SUBJECT_START(r, s, x) ++ if (s->obj_hash == NULL) ++ break; ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE) ++ kfree(s->obj_hash); ++ else ++ vfree(s->obj_hash); ++ FOR_EACH_SUBJECT_END(s, x) ++ FOR_EACH_NESTED_SUBJECT_START(r, s) ++ if (s->obj_hash == NULL) ++ break; ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE) ++ kfree(s->obj_hash); ++ else ++ vfree(s->obj_hash); ++ FOR_EACH_NESTED_SUBJECT_END(s) ++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE) ++ kfree(r->subj_hash); ++ else ++ vfree(r->subj_hash); ++ r->subj_hash = NULL; ++ FOR_EACH_ROLE_END(r,i) ++ ++ acl_free_all(); ++ ++ if (acl_role_set.r_hash) { ++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <= ++ PAGE_SIZE) ++ kfree(acl_role_set.r_hash); ++ else ++ vfree(acl_role_set.r_hash); ++ } ++ if (name_set.n_hash) { ++ if ((name_set.n_size * sizeof (struct name_entry *)) <= ++ PAGE_SIZE) ++ kfree(name_set.n_hash); ++ else ++ vfree(name_set.n_hash); ++ } ++ ++ if (inodev_set.i_hash) { ++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <= ++ PAGE_SIZE) ++ kfree(inodev_set.i_hash); ++ else ++ vfree(inodev_set.i_hash); ++ } ++ ++ gr_free_uidset(); ++ ++ memset(&name_set, 0, sizeof (struct name_db)); ++ memset(&inodev_set, 0, sizeof (struct inodev_db)); ++ memset(&acl_role_set, 0, sizeof (struct acl_role_db)); ++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db)); ++ ++ default_role = NULL; ++ ++ return; ++} ++ ++static __u32 ++count_user_objs(struct acl_object_label *userp) ++{ ++ struct acl_object_label o_tmp; ++ __u32 num = 0; ++ ++ while (userp) { ++ if (copy_from_user(&o_tmp, userp, ++ sizeof (struct acl_object_label))) ++ break; ++ ++ userp = o_tmp.prev; ++ num++; ++ } ++ ++ return num; ++} ++ ++static struct acl_subject_label * ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role); ++ ++static int ++copy_user_glob(struct acl_object_label *obj) ++{ ++ struct acl_object_label *g_tmp, **guser; ++ unsigned int len; ++ char *tmp; ++ ++ if (obj->globbed == NULL) ++ return 0; ++ ++ guser = &obj->globbed; ++ while (*guser) { ++ g_tmp = (struct acl_object_label *) ++ acl_alloc(sizeof (struct acl_object_label)); ++ if (g_tmp == NULL) ++ return -ENOMEM; ++ ++ if (copy_from_user(g_tmp, *guser, ++ sizeof (struct acl_object_label))) ++ return -EFAULT; ++ ++ len = strnlen_user(g_tmp->filename, PATH_MAX); ++ ++ if (!len || len >= PATH_MAX) ++ return -EINVAL; ++ ++ if ((tmp = (char *) acl_alloc(len)) == NULL) ++ return -ENOMEM; ++ ++ if (copy_from_user(tmp, g_tmp->filename, len)) ++ return -EFAULT; ++ tmp[len-1] = '\0'; ++ g_tmp->filename = tmp; ++ ++ *guser = g_tmp; ++ guser = &(g_tmp->next); ++ } ++ ++ return 0; ++} ++ ++static int ++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj, ++ struct acl_role_label *role) ++{ ++ struct acl_object_label *o_tmp; ++ unsigned int len; ++ int ret; ++ char *tmp; ++ ++ while (userp) { ++ if ((o_tmp = (struct acl_object_label *) ++ acl_alloc(sizeof (struct acl_object_label))) == NULL) ++ return -ENOMEM; ++ ++ if (copy_from_user(o_tmp, userp, ++ sizeof (struct acl_object_label))) ++ return -EFAULT; ++ ++ userp = o_tmp->prev; ++ ++ len = strnlen_user(o_tmp->filename, PATH_MAX); ++ ++ if (!len || len >= PATH_MAX) ++ return -EINVAL; ++ ++ if ((tmp = (char *) acl_alloc(len)) == NULL) ++ return -ENOMEM; ++ ++ if (copy_from_user(tmp, o_tmp->filename, len)) ++ return -EFAULT; ++ tmp[len-1] = '\0'; ++ o_tmp->filename = tmp; ++ ++ insert_acl_obj_label(o_tmp, subj); ++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode, ++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0)) ++ return -ENOMEM; ++ ++ ret = copy_user_glob(o_tmp); ++ if (ret) ++ return ret; ++ ++ if (o_tmp->nested) { ++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role); ++ if (IS_ERR(o_tmp->nested)) ++ return PTR_ERR(o_tmp->nested); ++ ++ /* insert into nested subject list */ ++ o_tmp->nested->next = role->hash->first; ++ role->hash->first = o_tmp->nested; ++ } ++ } ++ ++ return 0; ++} ++ ++static __u32 ++count_user_subjs(struct acl_subject_label *userp) ++{ ++ struct acl_subject_label s_tmp; ++ __u32 num = 0; ++ ++ while (userp) { ++ if (copy_from_user(&s_tmp, userp, ++ sizeof (struct acl_subject_label))) ++ break; ++ ++ userp = s_tmp.prev; ++ /* do not count nested subjects against this count, since ++ they are not included in the hash table, but are ++ attached to objects. We have already counted ++ the subjects in userspace for the allocation ++ stack ++ */ ++ if (!(s_tmp.mode & GR_NESTED)) ++ num++; ++ } ++ ++ return num; ++} ++ ++static int ++copy_user_allowedips(struct acl_role_label *rolep) ++{ ++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast; ++ ++ ruserip = rolep->allowed_ips; ++ ++ while (ruserip) { ++ rlast = rtmp; ++ ++ if ((rtmp = (struct role_allowed_ip *) ++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL) ++ return -ENOMEM; ++ ++ if (copy_from_user(rtmp, ruserip, ++ sizeof (struct role_allowed_ip))) ++ return -EFAULT; ++ ++ ruserip = rtmp->prev; ++ ++ if (!rlast) { ++ rtmp->prev = NULL; ++ rolep->allowed_ips = rtmp; ++ } else { ++ rlast->next = rtmp; ++ rtmp->prev = rlast; ++ } ++ ++ if (!ruserip) ++ rtmp->next = NULL; ++ } ++ ++ return 0; ++} ++ ++static int ++copy_user_transitions(struct acl_role_label *rolep) ++{ ++ struct role_transition *rusertp, *rtmp = NULL, *rlast; ++ ++ unsigned int len; ++ char *tmp; ++ ++ rusertp = rolep->transitions; ++ ++ while (rusertp) { ++ rlast = rtmp; ++ ++ if ((rtmp = (struct role_transition *) ++ acl_alloc(sizeof (struct role_transition))) == NULL) ++ return -ENOMEM; ++ ++ if (copy_from_user(rtmp, rusertp, ++ sizeof (struct role_transition))) ++ return -EFAULT; ++ ++ rusertp = rtmp->prev; ++ ++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN); ++ ++ if (!len || len >= GR_SPROLE_LEN) ++ return -EINVAL; ++ ++ if ((tmp = (char *) acl_alloc(len)) == NULL) ++ return -ENOMEM; ++ ++ if (copy_from_user(tmp, rtmp->rolename, len)) ++ return -EFAULT; ++ tmp[len-1] = '\0'; ++ rtmp->rolename = tmp; ++ ++ if (!rlast) { ++ rtmp->prev = NULL; ++ rolep->transitions = rtmp; ++ } else { ++ rlast->next = rtmp; ++ rtmp->prev = rlast; ++ } ++ ++ if (!rusertp) ++ rtmp->next = NULL; ++ } ++ ++ return 0; ++} ++ ++static struct acl_subject_label * ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role) ++{ ++ struct acl_subject_label *s_tmp = NULL, *s_tmp2; ++ unsigned int len; ++ char *tmp; ++ __u32 num_objs; ++ struct acl_ip_label **i_tmp, *i_utmp2; ++ struct gr_hash_struct ghash; ++ struct subject_map *subjmap; ++ unsigned int i_num; ++ int err; ++ ++ s_tmp = lookup_subject_map(userp); ++ ++ /* we've already copied this subject into the kernel, just return ++ the reference to it, and don't copy it over again ++ */ ++ if (s_tmp) ++ return(s_tmp); ++ ++ if ((s_tmp = (struct acl_subject_label *) ++ acl_alloc(sizeof (struct acl_subject_label))) == NULL) ++ return ERR_PTR(-ENOMEM); ++ ++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL); ++ if (subjmap == NULL) ++ return ERR_PTR(-ENOMEM); ++ ++ subjmap->user = userp; ++ subjmap->kernel = s_tmp; ++ insert_subj_map_entry(subjmap); ++ ++ if (copy_from_user(s_tmp, userp, ++ sizeof (struct acl_subject_label))) ++ return ERR_PTR(-EFAULT); ++ ++ len = strnlen_user(s_tmp->filename, PATH_MAX); ++ ++ if (!len || len >= PATH_MAX) ++ return ERR_PTR(-EINVAL); ++ ++ if ((tmp = (char *) acl_alloc(len)) == NULL) ++ return ERR_PTR(-ENOMEM); ++ ++ if (copy_from_user(tmp, s_tmp->filename, len)) ++ return ERR_PTR(-EFAULT); ++ tmp[len-1] = '\0'; ++ s_tmp->filename = tmp; ++ ++ if (!strcmp(s_tmp->filename, "/")) ++ role->root_label = s_tmp; ++ ++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct))) ++ return ERR_PTR(-EFAULT); ++ ++ /* copy user and group transition tables */ ++ ++ if (s_tmp->user_trans_num) { ++ uid_t *uidlist; ++ ++ uidlist = (uid_t *)acl_alloc_num(s_tmp->user_trans_num, sizeof(uid_t)); ++ if (uidlist == NULL) ++ return ERR_PTR(-ENOMEM); ++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t))) ++ return ERR_PTR(-EFAULT); ++ ++ s_tmp->user_transitions = uidlist; ++ } ++ ++ if (s_tmp->group_trans_num) { ++ gid_t *gidlist; ++ ++ gidlist = (gid_t *)acl_alloc_num(s_tmp->group_trans_num, sizeof(gid_t)); ++ if (gidlist == NULL) ++ return ERR_PTR(-ENOMEM); ++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t))) ++ return ERR_PTR(-EFAULT); ++ ++ s_tmp->group_transitions = gidlist; ++ } ++ ++ /* set up object hash table */ ++ num_objs = count_user_objs(ghash.first); ++ ++ s_tmp->obj_hash_size = num_objs; ++ s_tmp->obj_hash = ++ (struct acl_object_label **) ++ create_table(&(s_tmp->obj_hash_size), sizeof(void *)); ++ ++ if (!s_tmp->obj_hash) ++ return ERR_PTR(-ENOMEM); ++ ++ memset(s_tmp->obj_hash, 0, ++ s_tmp->obj_hash_size * ++ sizeof (struct acl_object_label *)); ++ ++ /* add in objects */ ++ err = copy_user_objs(ghash.first, s_tmp, role); ++ ++ if (err) ++ return ERR_PTR(err); ++ ++ /* set pointer for parent subject */ ++ if (s_tmp->parent_subject) { ++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role); ++ ++ if (IS_ERR(s_tmp2)) ++ return s_tmp2; ++ ++ s_tmp->parent_subject = s_tmp2; ++ } ++ ++ /* add in ip acls */ ++ ++ if (!s_tmp->ip_num) { ++ s_tmp->ips = NULL; ++ goto insert; ++ } ++ ++ i_tmp = ++ (struct acl_ip_label **) acl_alloc_num(s_tmp->ip_num, ++ sizeof (struct acl_ip_label *)); ++ ++ if (!i_tmp) ++ return ERR_PTR(-ENOMEM); ++ ++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) { ++ *(i_tmp + i_num) = ++ (struct acl_ip_label *) ++ acl_alloc(sizeof (struct acl_ip_label)); ++ if (!*(i_tmp + i_num)) ++ return ERR_PTR(-ENOMEM); ++ ++ if (copy_from_user ++ (&i_utmp2, s_tmp->ips + i_num, ++ sizeof (struct acl_ip_label *))) ++ return ERR_PTR(-EFAULT); ++ ++ if (copy_from_user ++ (*(i_tmp + i_num), i_utmp2, ++ sizeof (struct acl_ip_label))) ++ return ERR_PTR(-EFAULT); ++ ++ if ((*(i_tmp + i_num))->iface == NULL) ++ continue; ++ ++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ); ++ if (!len || len >= IFNAMSIZ) ++ return ERR_PTR(-EINVAL); ++ tmp = acl_alloc(len); ++ if (tmp == NULL) ++ return ERR_PTR(-ENOMEM); ++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len)) ++ return ERR_PTR(-EFAULT); ++ (*(i_tmp + i_num))->iface = tmp; ++ } ++ ++ s_tmp->ips = i_tmp; ++ ++insert: ++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode, ++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0)) ++ return ERR_PTR(-ENOMEM); ++ ++ return s_tmp; ++} ++ ++static int ++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role) ++{ ++ struct acl_subject_label s_pre; ++ struct acl_subject_label * ret; ++ int err; ++ ++ while (userp) { ++ if (copy_from_user(&s_pre, userp, ++ sizeof (struct acl_subject_label))) ++ return -EFAULT; ++ ++ /* do not add nested subjects here, add ++ while parsing objects ++ */ ++ ++ if (s_pre.mode & GR_NESTED) { ++ userp = s_pre.prev; ++ continue; ++ } ++ ++ ret = do_copy_user_subj(userp, role); ++ ++ err = PTR_ERR(ret); ++ if (IS_ERR(ret)) ++ return err; ++ ++ insert_acl_subj_label(ret, role); ++ ++ userp = s_pre.prev; ++ } ++ ++ return 0; ++} ++ ++static int ++copy_user_acl(struct gr_arg *arg) ++{ ++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2; ++ struct sprole_pw *sptmp; ++ struct gr_hash_struct *ghash; ++ uid_t *domainlist; ++ unsigned int r_num; ++ unsigned int len; ++ char *tmp; ++ int err = 0; ++ __u16 i; ++ __u32 num_subjs; ++ ++ /* we need a default and kernel role */ ++ if (arg->role_db.num_roles < 2) ++ return -EINVAL; ++ ++ /* copy special role authentication info from userspace */ ++ ++ num_sprole_pws = arg->num_sprole_pws; ++ acl_special_roles = (struct sprole_pw **) acl_alloc_num(num_sprole_pws, sizeof(struct sprole_pw *)); ++ ++ if (!acl_special_roles) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ ++ for (i = 0; i < num_sprole_pws; i++) { ++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw)); ++ if (!sptmp) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ if (copy_from_user(sptmp, arg->sprole_pws + i, ++ sizeof (struct sprole_pw))) { ++ err = -EFAULT; ++ goto cleanup; ++ } ++ ++ len = ++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN); ++ ++ if (!len || len >= GR_SPROLE_LEN) { ++ err = -EINVAL; ++ goto cleanup; ++ } ++ ++ if ((tmp = (char *) acl_alloc(len)) == NULL) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ ++ if (copy_from_user(tmp, sptmp->rolename, len)) { ++ err = -EFAULT; ++ goto cleanup; ++ } ++ tmp[len-1] = '\0'; ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG ++ printk(KERN_ALERT "Copying special role %s\n", tmp); ++#endif ++ sptmp->rolename = tmp; ++ acl_special_roles[i] = sptmp; ++ } ++ ++ r_utmp = (struct acl_role_label **) arg->role_db.r_table; ++ ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) { ++ r_tmp = acl_alloc(sizeof (struct acl_role_label)); ++ ++ if (!r_tmp) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ ++ if (copy_from_user(&r_utmp2, r_utmp + r_num, ++ sizeof (struct acl_role_label *))) { ++ err = -EFAULT; ++ goto cleanup; ++ } ++ ++ if (copy_from_user(r_tmp, r_utmp2, ++ sizeof (struct acl_role_label))) { ++ err = -EFAULT; ++ goto cleanup; ++ } ++ ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN); ++ ++ if (!len || len >= PATH_MAX) { ++ err = -EINVAL; ++ goto cleanup; ++ } ++ ++ if ((tmp = (char *) acl_alloc(len)) == NULL) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ if (copy_from_user(tmp, r_tmp->rolename, len)) { ++ err = -EFAULT; ++ goto cleanup; ++ } ++ tmp[len-1] = '\0'; ++ r_tmp->rolename = tmp; ++ ++ if (!strcmp(r_tmp->rolename, "default") ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) { ++ default_role = r_tmp; ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) { ++ kernel_role = r_tmp; ++ } ++ ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) { ++ err = -EFAULT; ++ goto cleanup; ++ } ++ ++ r_tmp->hash = ghash; ++ ++ num_subjs = count_user_subjs(r_tmp->hash->first); ++ ++ r_tmp->subj_hash_size = num_subjs; ++ r_tmp->subj_hash = ++ (struct acl_subject_label **) ++ create_table(&(r_tmp->subj_hash_size), sizeof(void *)); ++ ++ if (!r_tmp->subj_hash) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ ++ err = copy_user_allowedips(r_tmp); ++ if (err) ++ goto cleanup; ++ ++ /* copy domain info */ ++ if (r_tmp->domain_children != NULL) { ++ domainlist = acl_alloc_num(r_tmp->domain_child_num, sizeof(uid_t)); ++ if (domainlist == NULL) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) { ++ err = -EFAULT; ++ goto cleanup; ++ } ++ r_tmp->domain_children = domainlist; ++ } ++ ++ err = copy_user_transitions(r_tmp); ++ if (err) ++ goto cleanup; ++ ++ memset(r_tmp->subj_hash, 0, ++ r_tmp->subj_hash_size * ++ sizeof (struct acl_subject_label *)); ++ ++ err = copy_user_subjs(r_tmp->hash->first, r_tmp); ++ ++ if (err) ++ goto cleanup; ++ ++ /* set nested subject list to null */ ++ r_tmp->hash->first = NULL; ++ ++ insert_acl_role_label(r_tmp); ++ } ++ ++ goto return_err; ++ cleanup: ++ free_variables(); ++ return_err: ++ return err; ++ ++} ++ ++static int ++gracl_init(struct gr_arg *args) ++{ ++ int error = 0; ++ ++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN); ++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN); ++ ++ if (init_variables(args)) { ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION); ++ error = -ENOMEM; ++ free_variables(); ++ goto out; ++ } ++ ++ error = copy_user_acl(args); ++ free_init_variables(); ++ if (error) { ++ free_variables(); ++ goto out; ++ } ++ ++ if ((error = gr_set_acls(0))) { ++ free_variables(); ++ goto out; ++ } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ { ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++ gr_status |= GR_READY; ++ pax_close_kernel(cr0); ++ } ++#else ++ gr_status |= GR_READY; ++#endif ++ ++ out: ++ return error; ++} ++ ++/* derived from glibc fnmatch() 0: match, 1: no match*/ ++ ++static int ++glob_match(const char *p, const char *n) ++{ ++ char c; ++ ++ while ((c = *p++) != '\0') { ++ switch (c) { ++ case '?': ++ if (*n == '\0') ++ return 1; ++ else if (*n == '/') ++ return 1; ++ break; ++ case '\': ++ if (*n != c) ++ return 1; ++ break; ++ case '*': ++ for (c = *p++; c == '?' || c == '*'; c = *p++) { ++ if (*n == '/') ++ return 1; ++ else if (c == '?') { ++ if (*n == '\0') ++ return 1; ++ else ++ ++n; ++ } ++ } ++ if (c == '\0') { ++ return 0; ++ } else { ++ const char *endp; ++ ++ if ((endp = strchr(n, '/')) == NULL) ++ endp = n + strlen(n); ++ ++ if (c == '[') { ++ for (--p; n < endp; ++n) ++ if (!glob_match(p, n)) ++ return 0; ++ } else if (c == '/') { ++ while (*n != '\0' && *n != '/') ++ ++n; ++ if (*n == '/' && !glob_match(p, n + 1)) ++ return 0; ++ } else { ++ for (--p; n < endp; ++n) ++ if (*n == c && !glob_match(p, n)) ++ return 0; ++ } ++ ++ return 1; ++ } ++ case '[': ++ { ++ int not; ++ char cold; ++ ++ if (*n == '\0' || *n == '/') ++ return 1; ++ ++ not = (*p == '!' || *p == '^'); ++ if (not) ++ ++p; ++ ++ c = *p++; ++ for (;;) { ++ unsigned char fn = (unsigned char)*n; ++ ++ if (c == '\0') ++ return 1; ++ else { ++ if (c == fn) ++ goto matched; ++ cold = c; ++ c = *p++; ++ ++ if (c == '-' && *p != ']') { ++ unsigned char cend = *p++; ++ ++ if (cend == '\0') ++ return 1; ++ ++ if (cold <= fn && fn <= cend) ++ goto matched; ++ ++ c = *p++; ++ } ++ } ++ ++ if (c == ']') ++ break; ++ } ++ if (!not) ++ return 1; ++ break; ++ matched: ++ while (c != ']') { ++ if (c == '\0') ++ return 1; ++ ++ c = *p++; ++ } ++ if (not) ++ return 1; ++ } ++ break; ++ default: ++ if (c != *n) ++ return 1; ++ } ++ ++ ++n; ++ } ++ ++ if (*n == '\0') ++ return 0; ++ ++ if (*n == '/') ++ return 0; ++ ++ return 1; ++} ++ ++static struct acl_object_label * ++chk_glob_label(struct acl_object_label *globbed, ++ struct dentry *dentry, struct vfsmount *mnt, char **path) ++{ ++ struct acl_object_label *tmp; ++ ++ if (*path == NULL) ++ *path = gr_to_filename_nolock(dentry, mnt); ++ ++ tmp = globbed; ++ ++ while (tmp) { ++ if (!glob_match(tmp->filename, *path)) ++ return tmp; ++ tmp = tmp->next; ++ } ++ ++ return NULL; ++} ++ ++static struct acl_object_label * ++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt, ++ const ino_t curr_ino, const dev_t curr_dev, ++ const struct acl_subject_label *subj, char **path, const int checkglob) ++{ ++ struct acl_subject_label *tmpsubj; ++ struct acl_object_label *retval; ++ struct acl_object_label *retval2; ++ ++ tmpsubj = (struct acl_subject_label *) subj; ++ read_lock(&gr_inode_lock); ++ do { ++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj); ++ if (retval) { ++ if (checkglob && retval->globbed) { ++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry, ++ (struct vfsmount *)orig_mnt, path); ++ if (retval2) ++ retval = retval2; ++ } ++ break; ++ } ++ } while ((tmpsubj = tmpsubj->parent_subject)); ++ read_unlock(&gr_inode_lock); ++ ++ return retval; ++} ++ ++static __inline__ struct acl_object_label * ++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt, ++ const struct dentry *curr_dentry, ++ const struct acl_subject_label *subj, char **path, const int checkglob) ++{ ++ return __full_lookup(orig_dentry, orig_mnt, ++ curr_dentry->d_inode->i_ino, ++ curr_dentry->d_inode->i_sb->s_dev, subj, path, checkglob); ++} ++ ++static struct acl_object_label * ++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, ++ const struct acl_subject_label *subj, char *path, const int checkglob) ++{ ++ struct dentry *dentry = (struct dentry *) l_dentry; ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt; ++ struct acl_object_label *retval; ++ ++ spin_lock(&dcache_lock); ++ ++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt || ++ /* ignore Eric Biederman */ ++ IS_PRIVATE(l_dentry->d_inode))) { ++ retval = fakefs_obj; ++ goto out; ++ } ++ ++ for (;;) { ++ if (dentry == real_root && mnt == real_root_mnt) ++ break; ++ ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) { ++ if (mnt->mnt_parent == mnt) ++ break; ++ ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob); ++ if (retval != NULL) ++ goto out; ++ ++ dentry = mnt->mnt_mountpoint; ++ mnt = mnt->mnt_parent; ++ continue; ++ } ++ ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob); ++ if (retval != NULL) ++ goto out; ++ ++ dentry = dentry->d_parent; ++ } ++ ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path, checkglob); ++ ++ if (retval == NULL) ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path, checkglob); ++out: ++ spin_unlock(&dcache_lock); ++ return retval; ++} ++ ++static __inline__ struct acl_object_label * ++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, ++ const struct acl_subject_label *subj) ++{ ++ char *path = NULL; ++ return __chk_obj_label(l_dentry, l_mnt, subj, path, 1); ++} ++ ++static __inline__ struct acl_object_label * ++chk_obj_label_noglob(const struct dentry *l_dentry, const struct vfsmount *l_mnt, ++ const struct acl_subject_label *subj) ++{ ++ char *path = NULL; ++ return __chk_obj_label(l_dentry, l_mnt, subj, path, 0); ++} ++ ++static __inline__ struct acl_object_label * ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, ++ const struct acl_subject_label *subj, char *path) ++{ ++ return __chk_obj_label(l_dentry, l_mnt, subj, path, 1); ++} ++ ++static struct acl_subject_label * ++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, ++ const struct acl_role_label *role) ++{ ++ struct dentry *dentry = (struct dentry *) l_dentry; ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt; ++ struct acl_subject_label *retval; ++ ++ spin_lock(&dcache_lock); ++ ++ for (;;) { ++ if (dentry == real_root && mnt == real_root_mnt) ++ break; ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) { ++ if (mnt->mnt_parent == mnt) ++ break; ++ ++ read_lock(&gr_inode_lock); ++ retval = ++ lookup_acl_subj_label(dentry->d_inode->i_ino, ++ dentry->d_inode->i_sb->s_dev, role); ++ read_unlock(&gr_inode_lock); ++ if (retval != NULL) ++ goto out; ++ ++ dentry = mnt->mnt_mountpoint; ++ mnt = mnt->mnt_parent; ++ continue; ++ } ++ ++ read_lock(&gr_inode_lock); ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino, ++ dentry->d_inode->i_sb->s_dev, role); ++ read_unlock(&gr_inode_lock); ++ if (retval != NULL) ++ goto out; ++ ++ dentry = dentry->d_parent; ++ } ++ ++ read_lock(&gr_inode_lock); ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino, ++ dentry->d_inode->i_sb->s_dev, role); ++ read_unlock(&gr_inode_lock); ++ ++ if (unlikely(retval == NULL)) { ++ read_lock(&gr_inode_lock); ++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino, ++ real_root->d_inode->i_sb->s_dev, role); ++ read_unlock(&gr_inode_lock); ++ } ++out: ++ spin_unlock(&dcache_lock); ++ ++ return retval; ++} ++ ++static void ++gr_log_learn(const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode) ++{ ++ struct task_struct *task = current; ++ const struct cred *cred = current_cred(); ++ ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype, ++ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry, ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename, ++ 1UL, 1UL, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip)); ++ ++ return; ++} ++ ++static void ++gr_log_learn_sysctl(const char *path, const __u32 mode) ++{ ++ struct task_struct *task = current; ++ const struct cred *cred = current_cred(); ++ ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype, ++ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry, ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename, ++ 1UL, 1UL, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip)); ++ ++ return; ++} ++ ++static void ++gr_log_learn_id_change(const char type, const unsigned int real, ++ const unsigned int effective, const unsigned int fs) ++{ ++ struct task_struct *task = current; ++ const struct cred *cred = current_cred(); ++ ++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype, ++ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry, ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename, ++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip)); ++ ++ return; ++} ++ ++__u32 ++gr_check_link(const struct dentry * new_dentry, ++ const struct dentry * parent_dentry, ++ const struct vfsmount * parent_mnt, ++ const struct dentry * old_dentry, const struct vfsmount * old_mnt) ++{ ++ struct acl_object_label *obj; ++ __u32 oldmode, newmode; ++ __u32 needmode; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return (GR_CREATE | GR_LINK); ++ ++ obj = chk_obj_label(old_dentry, old_mnt, current->acl); ++ oldmode = obj->mode; ++ ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) ++ oldmode |= (GR_CREATE | GR_LINK); ++ ++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS; ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID)) ++ needmode |= GR_SETID | GR_AUDIT_SETID; ++ ++ newmode = ++ gr_check_create(new_dentry, parent_dentry, parent_mnt, ++ oldmode | needmode); ++ ++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC | ++ GR_SETID | GR_READ | GR_FIND | GR_DELETE | ++ GR_INHERIT | GR_AUDIT_INHERIT); ++ ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID)) ++ goto bad; ++ ++ if ((oldmode & needmode) != needmode) ++ goto bad; ++ ++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS); ++ if ((newmode & needmode) != needmode) ++ goto bad; ++ ++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK)) ++ return newmode; ++bad: ++ needmode = oldmode; ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID)) ++ needmode |= GR_SETID; ++ ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) { ++ gr_log_learn(old_dentry, old_mnt, needmode); ++ return (GR_CREATE | GR_LINK); ++ } else if (newmode & GR_SUPPRESS) ++ return GR_SUPPRESS; ++ else ++ return 0; ++} ++ ++__u32 ++gr_search_file(const struct dentry * dentry, const __u32 mode, ++ const struct vfsmount * mnt) ++{ ++ __u32 retval = mode; ++ struct acl_subject_label *curracl; ++ struct acl_object_label *currobj; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return (mode & ~GR_AUDITS); ++ ++ curracl = current->acl; ++ ++ currobj = chk_obj_label(dentry, mnt, curracl); ++ retval = currobj->mode & mode; ++ ++ if (unlikely ++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE) ++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) { ++ __u32 new_mode = mode; ++ ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); ++ ++ retval = new_mode; ++ ++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN) ++ new_mode |= GR_INHERIT; ++ ++ if (!(mode & GR_NOLEARN)) ++ gr_log_learn(dentry, mnt, new_mode); ++ } ++ ++ return retval; ++} ++ ++__u32 ++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent, ++ const struct vfsmount * mnt, const __u32 mode) ++{ ++ struct name_entry *match; ++ struct acl_object_label *matchpo; ++ struct acl_subject_label *curracl; ++ char *path; ++ __u32 retval; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return (mode & ~GR_AUDITS); ++ ++ preempt_disable(); ++ path = gr_to_filename_rbac(new_dentry, mnt); ++ match = lookup_name_entry_create(path); ++ ++ if (!match) ++ goto check_parent; ++ ++ curracl = current->acl; ++ ++ read_lock(&gr_inode_lock); ++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl); ++ read_unlock(&gr_inode_lock); ++ ++ if (matchpo) { ++ if ((matchpo->mode & mode) != ++ (mode & ~(GR_AUDITS | GR_SUPPRESS)) ++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) { ++ __u32 new_mode = mode; ++ ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); ++ ++ gr_log_learn(new_dentry, mnt, new_mode); ++ ++ preempt_enable(); ++ return new_mode; ++ } ++ preempt_enable(); ++ return (matchpo->mode & mode); ++ } ++ ++ check_parent: ++ curracl = current->acl; ++ ++ matchpo = chk_obj_create_label(parent, mnt, curracl, path); ++ retval = matchpo->mode & mode; ++ ++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))) ++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) { ++ __u32 new_mode = mode; ++ ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); ++ ++ gr_log_learn(new_dentry, mnt, new_mode); ++ preempt_enable(); ++ return new_mode; ++ } ++ ++ preempt_enable(); ++ return retval; ++} ++ ++int ++gr_check_hidden_task(const struct task_struct *task) ++{ ++ if (unlikely(!(gr_status & GR_READY))) ++ return 0; ++ ++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW)) ++ return 1; ++ ++ return 0; ++} ++ ++int ++gr_check_protected_task(const struct task_struct *task) ++{ ++ if (unlikely(!(gr_status & GR_READY) || !task)) ++ return 0; ++ ++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) && ++ task->acl != current->acl) ++ return 1; ++ ++ return 0; ++} ++ ++void ++gr_copy_label(struct task_struct *tsk) ++{ ++ tsk->signal->used_accept = 0; ++ tsk->acl_sp_role = 0; ++ tsk->acl_role_id = current->acl_role_id; ++ tsk->acl = current->acl; ++ tsk->role = current->role; ++ tsk->signal->curr_ip = current->signal->curr_ip; ++ if (current->exec_file) ++ get_file(current->exec_file); ++ tsk->exec_file = current->exec_file; ++ tsk->is_writable = current->is_writable; ++ if (unlikely(current->signal->used_accept)) ++ current->signal->curr_ip = 0; ++ ++ return; ++} ++ ++static void ++gr_set_proc_res(struct task_struct *task) ++{ ++ struct acl_subject_label *proc; ++ unsigned short i; ++ ++ proc = task->acl; ++ ++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN)) ++ return; ++ ++ for (i = 0; i < RLIM_NLIMITS; i++) { ++ if (!(proc->resmask & (1 << i))) ++ continue; ++ ++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur; ++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max; ++ } ++ ++ return; ++} ++ ++int ++gr_check_user_change(int real, int effective, int fs) ++{ ++ unsigned int i; ++ __u16 num; ++ uid_t *uidlist; ++ int curuid; ++ int realok = 0; ++ int effectiveok = 0; ++ int fsok = 0; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return 0; ++ ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) ++ gr_log_learn_id_change('u', real, effective, fs); ++ ++ num = current->acl->user_trans_num; ++ uidlist = current->acl->user_transitions; ++ ++ if (uidlist == NULL) ++ return 0; ++ ++ if (real == -1) ++ realok = 1; ++ if (effective == -1) ++ effectiveok = 1; ++ if (fs == -1) ++ fsok = 1; ++ ++ if (current->acl->user_trans_type & GR_ID_ALLOW) { ++ for (i = 0; i < num; i++) { ++ curuid = (int)uidlist[i]; ++ if (real == curuid) ++ realok = 1; ++ if (effective == curuid) ++ effectiveok = 1; ++ if (fs == curuid) ++ fsok = 1; ++ } ++ } else if (current->acl->user_trans_type & GR_ID_DENY) { ++ for (i = 0; i < num; i++) { ++ curuid = (int)uidlist[i]; ++ if (real == curuid) ++ break; ++ if (effective == curuid) ++ break; ++ if (fs == curuid) ++ break; ++ } ++ /* not in deny list */ ++ if (i == num) { ++ realok = 1; ++ effectiveok = 1; ++ fsok = 1; ++ } ++ } ++ ++ if (realok && effectiveok && fsok) ++ return 0; ++ else { ++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real); ++ return 1; ++ } ++} ++ ++int ++gr_check_group_change(int real, int effective, int fs) ++{ ++ unsigned int i; ++ __u16 num; ++ gid_t *gidlist; ++ int curgid; ++ int realok = 0; ++ int effectiveok = 0; ++ int fsok = 0; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return 0; ++ ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) ++ gr_log_learn_id_change('g', real, effective, fs); ++ ++ num = current->acl->group_trans_num; ++ gidlist = current->acl->group_transitions; ++ ++ if (gidlist == NULL) ++ return 0; ++ ++ if (real == -1) ++ realok = 1; ++ if (effective == -1) ++ effectiveok = 1; ++ if (fs == -1) ++ fsok = 1; ++ ++ if (current->acl->group_trans_type & GR_ID_ALLOW) { ++ for (i = 0; i < num; i++) { ++ curgid = (int)gidlist[i]; ++ if (real == curgid) ++ realok = 1; ++ if (effective == curgid) ++ effectiveok = 1; ++ if (fs == curgid) ++ fsok = 1; ++ } ++ } else if (current->acl->group_trans_type & GR_ID_DENY) { ++ for (i = 0; i < num; i++) { ++ curgid = (int)gidlist[i]; ++ if (real == curgid) ++ break; ++ if (effective == curgid) ++ break; ++ if (fs == curgid) ++ break; ++ } ++ /* not in deny list */ ++ if (i == num) { ++ realok = 1; ++ effectiveok = 1; ++ fsok = 1; ++ } ++ } ++ ++ if (realok && effectiveok && fsok) ++ return 0; ++ else { ++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real); ++ return 1; ++ } ++} ++ ++void ++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid) ++{ ++ struct acl_role_label *role = task->role; ++ struct acl_subject_label *subj = NULL; ++ struct acl_object_label *obj; ++ struct file *filp; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return; ++ ++ filp = task->exec_file; ++ ++ /* kernel process, we'll give them the kernel role */ ++ if (unlikely(!filp)) { ++ task->role = kernel_role; ++ task->acl = kernel_role->root_label; ++ return; ++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL)) ++ role = lookup_acl_role_label(task, uid, gid); ++ ++ /* perform subject lookup in possibly new role ++ we can use this result below in the case where role == task->role ++ */ ++ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role); ++ ++ /* if we changed uid/gid, but result in the same role ++ and are using inheritance, don't lose the inherited subject ++ if current subject is other than what normal lookup ++ would result in, we arrived via inheritance, don't ++ lose subject ++ */ ++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) && ++ (subj == task->acl))) ++ task->acl = subj; ++ ++ task->role = role; ++ ++ task->is_writable = 0; ++ ++ /* ignore additional mmap checks for processes that are writable ++ by the default ACL */ ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label); ++ if (unlikely(obj->mode & GR_WRITE)) ++ task->is_writable = 1; ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label); ++ if (unlikely(obj->mode & GR_WRITE)) ++ task->is_writable = 1; ++ ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); ++#endif ++ ++ gr_set_proc_res(task); ++ ++ return; ++} ++ ++int ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt, ++ const int unsafe_share) ++{ ++ struct task_struct *task = current; ++ struct acl_subject_label *newacl; ++ struct acl_object_label *obj; ++ __u32 retmode; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return 0; ++ ++ newacl = chk_subj_label(dentry, mnt, task->role); ++ ++ task_lock(task); ++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode & ++ GR_POVERRIDE) && (task->acl != newacl) && ++ !(task->role->roletype & GR_ROLE_GOD) && ++ !gr_search_file(dentry, GR_PTRACERD, mnt) && ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ++ || unsafe_share) { ++ task_unlock(task); ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt); ++ return -EACCES; ++ } ++ task_unlock(task); ++ ++ obj = chk_obj_label(dentry, mnt, task->acl); ++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT); ++ ++ if (!(task->acl->mode & GR_INHERITLEARN) && ++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) { ++ if (obj->nested) ++ task->acl = obj->nested; ++ else ++ task->acl = newacl; ++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT) ++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt); ++ ++ task->is_writable = 0; ++ ++ /* ignore additional mmap checks for processes that are writable ++ by the default ACL */ ++ obj = chk_obj_label(dentry, mnt, default_role->root_label); ++ if (unlikely(obj->mode & GR_WRITE)) ++ task->is_writable = 1; ++ obj = chk_obj_label(dentry, mnt, task->role->root_label); ++ if (unlikely(obj->mode & GR_WRITE)) ++ task->is_writable = 1; ++ ++ gr_set_proc_res(task); ++ ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); ++#endif ++ return 0; ++} ++ ++/* always called with valid inodev ptr */ ++static void ++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev) ++{ ++ struct acl_object_label *matchpo; ++ struct acl_subject_label *matchps; ++ struct acl_subject_label *subj; ++ struct acl_role_label *role; ++ unsigned int i, x; ++ ++ FOR_EACH_ROLE_START(role, i) ++ FOR_EACH_SUBJECT_START(role, subj, x) ++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL) ++ matchpo->mode |= GR_DELETED; ++ FOR_EACH_SUBJECT_END(subj,x) ++ FOR_EACH_NESTED_SUBJECT_START(role, subj) ++ if (subj->inode == ino && subj->device == dev) ++ subj->mode |= GR_DELETED; ++ FOR_EACH_NESTED_SUBJECT_END(subj) ++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL) ++ matchps->mode |= GR_DELETED; ++ FOR_EACH_ROLE_END(role,i) ++ ++ inodev->nentry->deleted = 1; ++ ++ return; ++} ++ ++void ++gr_handle_delete(const ino_t ino, const dev_t dev) ++{ ++ struct inodev_entry *inodev; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return; ++ ++ write_lock(&gr_inode_lock); ++ inodev = lookup_inodev_entry(ino, dev); ++ if (inodev != NULL) ++ do_handle_delete(inodev, ino, dev); ++ write_unlock(&gr_inode_lock); ++ ++ return; ++} ++ ++static void ++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice, ++ const ino_t newinode, const dev_t newdevice, ++ struct acl_subject_label *subj) ++{ ++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size); ++ struct acl_object_label *match; ++ ++ match = subj->obj_hash[index]; ++ ++ while (match && (match->inode != oldinode || ++ match->device != olddevice || ++ !(match->mode & GR_DELETED))) ++ match = match->next; ++ ++ if (match && (match->inode == oldinode) ++ && (match->device == olddevice) ++ && (match->mode & GR_DELETED)) { ++ if (match->prev == NULL) { ++ subj->obj_hash[index] = match->next; ++ if (match->next != NULL) ++ match->next->prev = NULL; ++ } else { ++ match->prev->next = match->next; ++ if (match->next != NULL) ++ match->next->prev = match->prev; ++ } ++ match->prev = NULL; ++ match->next = NULL; ++ match->inode = newinode; ++ match->device = newdevice; ++ match->mode &= ~GR_DELETED; ++ ++ insert_acl_obj_label(match, subj); ++ } ++ ++ return; ++} ++ ++static void ++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice, ++ const ino_t newinode, const dev_t newdevice, ++ struct acl_role_label *role) ++{ ++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size); ++ struct acl_subject_label *match; ++ ++ match = role->subj_hash[index]; ++ ++ while (match && (match->inode != oldinode || ++ match->device != olddevice || ++ !(match->mode & GR_DELETED))) ++ match = match->next; ++ ++ if (match && (match->inode == oldinode) ++ && (match->device == olddevice) ++ && (match->mode & GR_DELETED)) { ++ if (match->prev == NULL) { ++ role->subj_hash[index] = match->next; ++ if (match->next != NULL) ++ match->next->prev = NULL; ++ } else { ++ match->prev->next = match->next; ++ if (match->next != NULL) ++ match->next->prev = match->prev; ++ } ++ match->prev = NULL; ++ match->next = NULL; ++ match->inode = newinode; ++ match->device = newdevice; ++ match->mode &= ~GR_DELETED; ++ ++ insert_acl_subj_label(match, role); ++ } ++ ++ return; ++} ++ ++static void ++update_inodev_entry(const ino_t oldinode, const dev_t olddevice, ++ const ino_t newinode, const dev_t newdevice) ++{ ++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size); ++ struct inodev_entry *match; ++ ++ match = inodev_set.i_hash[index]; ++ ++ while (match && (match->nentry->inode != oldinode || ++ match->nentry->device != olddevice || !match->nentry->deleted)) ++ match = match->next; ++ ++ if (match && (match->nentry->inode == oldinode) ++ && (match->nentry->device == olddevice) && ++ match->nentry->deleted) { ++ if (match->prev == NULL) { ++ inodev_set.i_hash[index] = match->next; ++ if (match->next != NULL) ++ match->next->prev = NULL; ++ } else { ++ match->prev->next = match->next; ++ if (match->next != NULL) ++ match->next->prev = match->prev; ++ } ++ match->prev = NULL; ++ match->next = NULL; ++ match->nentry->inode = newinode; ++ match->nentry->device = newdevice; ++ match->nentry->deleted = 0; ++ ++ insert_inodev_entry(match); ++ } ++ ++ return; ++} ++ ++static void ++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry, ++ const struct vfsmount *mnt) ++{ ++ struct acl_subject_label *subj; ++ struct acl_role_label *role; ++ unsigned int i, x; ++ ++ FOR_EACH_ROLE_START(role, i) ++ update_acl_subj_label(matchn->inode, matchn->device, ++ dentry->d_inode->i_ino, ++ dentry->d_inode->i_sb->s_dev, role); ++ ++ FOR_EACH_NESTED_SUBJECT_START(role, subj) ++ if ((subj->inode == dentry->d_inode->i_ino) && ++ (subj->device == dentry->d_inode->i_sb->s_dev)) { ++ subj->inode = dentry->d_inode->i_ino; ++ subj->device = dentry->d_inode->i_sb->s_dev; ++ } ++ FOR_EACH_NESTED_SUBJECT_END(subj) ++ FOR_EACH_SUBJECT_START(role, subj, x) ++ update_acl_obj_label(matchn->inode, matchn->device, ++ dentry->d_inode->i_ino, ++ dentry->d_inode->i_sb->s_dev, subj); ++ FOR_EACH_SUBJECT_END(subj,x) ++ FOR_EACH_ROLE_END(role,i) ++ ++ update_inodev_entry(matchn->inode, matchn->device, ++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev); ++ ++ return; ++} ++ ++void ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ struct name_entry *matchn; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return; ++ ++ preempt_disable(); ++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt)); ++ ++ if (unlikely((unsigned long)matchn)) { ++ write_lock(&gr_inode_lock); ++ do_handle_create(matchn, dentry, mnt); ++ write_unlock(&gr_inode_lock); ++ } ++ preempt_enable(); ++ ++ return; ++} ++ ++void ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir, ++ struct dentry *old_dentry, ++ struct dentry *new_dentry, ++ struct vfsmount *mnt, const __u8 replace) ++{ ++ struct name_entry *matchn; ++ struct inodev_entry *inodev; ++ ++ /* vfs_rename swaps the name and parent link for old_dentry and ++ new_dentry ++ at this point, old_dentry has the new name, parent link, and inode ++ for the renamed file ++ if a file is being replaced by a rename, new_dentry has the inode ++ and name for the replaced file ++ */ ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return; ++ ++ preempt_disable(); ++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt)); ++ ++ /* we wouldn't have to check d_inode if it weren't for ++ NFS silly-renaming ++ */ ++ ++ write_lock(&gr_inode_lock); ++ if (unlikely(replace && new_dentry->d_inode)) { ++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino, ++ new_dentry->d_inode->i_sb->s_dev); ++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1)) ++ do_handle_delete(inodev, new_dentry->d_inode->i_ino, ++ new_dentry->d_inode->i_sb->s_dev); ++ } ++ ++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino, ++ old_dentry->d_inode->i_sb->s_dev); ++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1)) ++ do_handle_delete(inodev, old_dentry->d_inode->i_ino, ++ old_dentry->d_inode->i_sb->s_dev); ++ ++ if (unlikely((unsigned long)matchn)) ++ do_handle_create(matchn, old_dentry, mnt); ++ ++ write_unlock(&gr_inode_lock); ++ preempt_enable(); ++ ++ return; ++} ++ ++static int ++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt, ++ unsigned char **sum) ++{ ++ struct acl_role_label *r; ++ struct role_allowed_ip *ipp; ++ struct role_transition *trans; ++ unsigned int i; ++ int found = 0; ++ ++ /* check transition table */ ++ ++ for (trans = current->role->transitions; trans; trans = trans->next) { ++ if (!strcmp(rolename, trans->rolename)) { ++ found = 1; ++ break; ++ } ++ } ++ ++ if (!found) ++ return 0; ++ ++ /* handle special roles that do not require authentication ++ and check ip */ ++ ++ FOR_EACH_ROLE_START(r, i) ++ if (!strcmp(rolename, r->rolename) && ++ (r->roletype & GR_ROLE_SPECIAL)) { ++ found = 0; ++ if (r->allowed_ips != NULL) { ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) { ++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) == ++ (ntohl(ipp->addr) & ipp->netmask)) ++ found = 1; ++ } ++ } else ++ found = 2; ++ if (!found) ++ return 0; ++ ++ if (((mode == GR_SPROLE) && (r->roletype & GR_ROLE_NOPW)) || ++ ((mode == GR_SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) { ++ *salt = NULL; ++ *sum = NULL; ++ return 1; ++ } ++ } ++ FOR_EACH_ROLE_END(r,i) ++ ++ for (i = 0; i < num_sprole_pws; i++) { ++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) { ++ *salt = acl_special_roles[i]->salt; ++ *sum = acl_special_roles[i]->sum; ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static void ++assign_special_role(char *rolename) ++{ ++ struct acl_object_label *obj; ++ struct acl_role_label *r; ++ struct acl_role_label *assigned = NULL; ++ struct task_struct *tsk; ++ struct file *filp; ++ unsigned int i; ++ ++ FOR_EACH_ROLE_START(r, i) ++ if (!strcmp(rolename, r->rolename) && ++ (r->roletype & GR_ROLE_SPECIAL)) ++ assigned = r; ++ FOR_EACH_ROLE_END(r,i) ++ ++ if (!assigned) ++ return; ++ ++ read_lock(&tasklist_lock); ++ read_lock(&grsec_exec_file_lock); ++ ++ tsk = current->parent; ++ if (tsk == NULL) ++ goto out_unlock; ++ ++ filp = tsk->exec_file; ++ if (filp == NULL) ++ goto out_unlock; ++ ++ tsk->is_writable = 0; ++ ++ tsk->acl_sp_role = 1; ++ tsk->acl_role_id = ++acl_sp_role_value; ++ tsk->role = assigned; ++ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role); ++ ++ /* ignore additional mmap checks for processes that are writable ++ by the default ACL */ ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label); ++ if (unlikely(obj->mode & GR_WRITE)) ++ tsk->is_writable = 1; ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label); ++ if (unlikely(obj->mode & GR_WRITE)) ++ tsk->is_writable = 1; ++ ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid); ++#endif ++ ++out_unlock: ++ read_unlock(&grsec_exec_file_lock); ++ read_unlock(&tasklist_lock); ++ return; ++} ++ ++int gr_check_secure_terminal(struct task_struct *task) ++{ ++ struct task_struct *p, *p2, *p3; ++ struct files_struct *files; ++ struct fdtable *fdt; ++ struct file *our_file = NULL, *file; ++ int i; ++ ++ if (task->signal->tty == NULL) ++ return 1; ++ ++ files = get_files_struct(task); ++ if (files != NULL) { ++ rcu_read_lock(); ++ fdt = files_fdtable(files); ++ for (i=0; i < fdt->max_fds; i++) { ++ file = fcheck_files(files, i); ++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) { ++ get_file(file); ++ our_file = file; ++ } ++ } ++ rcu_read_unlock(); ++ put_files_struct(files); ++ } ++ ++ if (our_file == NULL) ++ return 1; ++ ++ read_lock(&tasklist_lock); ++ do_each_thread(p2, p) { ++ files = get_files_struct(p); ++ if (files == NULL || ++ (p->signal && p->signal->tty == task->signal->tty)) { ++ if (files != NULL) ++ put_files_struct(files); ++ continue; ++ } ++ rcu_read_lock(); ++ fdt = files_fdtable(files); ++ for (i=0; i < fdt->max_fds; i++) { ++ file = fcheck_files(files, i); ++ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) && ++ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) { ++ p3 = task; ++ while (p3->pid > 0) { ++ if (p3 == p) ++ break; ++ p3 = p3->parent; ++ } ++ if (p3 == p) ++ break; ++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p); ++ gr_handle_alertkill(p); ++ rcu_read_unlock(); ++ put_files_struct(files); ++ read_unlock(&tasklist_lock); ++ fput(our_file); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ put_files_struct(files); ++ } while_each_thread(p2, p); ++ read_unlock(&tasklist_lock); ++ ++ fput(our_file); ++ return 1; ++} ++ ++ssize_t ++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos) ++{ ++ struct gr_arg_wrapper uwrap; ++ unsigned char *sprole_salt; ++ unsigned char *sprole_sum; ++ int error = sizeof (struct gr_arg_wrapper); ++ int error2 = 0; ++ ++ down(&gr_dev_sem); ++ ++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) { ++ error = -EPERM; ++ goto out; ++ } ++ ++ if (count != sizeof (struct gr_arg_wrapper)) { ++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper)); ++ error = -EINVAL; ++ goto out; ++ } ++ ++ ++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) { ++ gr_auth_expires = 0; ++ gr_auth_attempts = 0; ++ } ++ ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) { ++ error = -EFAULT; ++ goto out; ++ } ++ ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) { ++ error = -EINVAL; ++ goto out; ++ } ++ ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) { ++ error = -EFAULT; ++ goto out; ++ } ++ ++ if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_SPROLEPAM && ++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES && ++ time_after(gr_auth_expires, get_seconds())) { ++ error = -EBUSY; ++ goto out; ++ } ++ ++ /* if non-root trying to do anything other than use a special role, ++ do not attempt authentication, do not count towards authentication ++ locking ++ */ ++ ++ if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_STATUS && ++ gr_usermode->mode != GR_UNSPROLE && gr_usermode->mode != GR_SPROLEPAM && ++ current_uid()) { ++ error = -EPERM; ++ goto out; ++ } ++ ++ /* ensure pw and special role name are null terminated */ ++ ++ gr_usermode->pw[GR_PW_LEN - 1] = '\0'; ++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0'; ++ ++ /* Okay. ++ * We have our enough of the argument structure..(we have yet ++ * to copy_from_user the tables themselves) . Copy the tables ++ * only if we need them, i.e. for loading operations. */ ++ ++ switch (gr_usermode->mode) { ++ case GR_STATUS: ++ if (gr_status & GR_READY) { ++ error = 1; ++ if (!gr_check_secure_terminal(current)) ++ error = 3; ++ } else ++ error = 2; ++ goto out; ++ case GR_SHUTDOWN: ++ if ((gr_status & GR_READY) ++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { ++#ifdef CONFIG_PAX_KERNEXEC ++ { ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++ gr_status &= ~GR_READY; ++ pax_close_kernel(cr0); ++ } ++#else ++ gr_status &= ~GR_READY; ++#endif ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG); ++ free_variables(); ++ memset(gr_usermode, 0, sizeof (struct gr_arg)); ++ memset(gr_system_salt, 0, GR_SALT_LEN); ++ memset(gr_system_sum, 0, GR_SHA_LEN); ++ } else if (gr_status & GR_READY) { ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG); ++ error = -EPERM; ++ } else { ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG); ++ error = -EAGAIN; ++ } ++ break; ++ case GR_ENABLE: ++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode))) ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION); ++ else { ++ if (gr_status & GR_READY) ++ error = -EAGAIN; ++ else ++ error = error2; ++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION); ++ } ++ break; ++ case GR_RELOAD: ++ if (!(gr_status & GR_READY)) { ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION); ++ error = -EAGAIN; ++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { ++ lock_kernel(); ++#ifdef CONFIG_PAX_KERNEXEC ++ { ++ unsigned long cr0; ++ ++ pax_open_kernel(cr0); ++ gr_status &= ~GR_READY; ++ pax_close_kernel(cr0); ++ } ++#else ++ gr_status &= ~GR_READY; ++#endif ++ free_variables(); ++ if (!(error2 = gracl_init(gr_usermode))) { ++ unlock_kernel(); ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION); ++ } else { ++ unlock_kernel(); ++ error = error2; ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION); ++ } ++ } else { ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION); ++ error = -EPERM; ++ } ++ break; ++ case GR_SEGVMOD: ++ if (unlikely(!(gr_status & GR_READY))) { ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG); ++ error = -EAGAIN; ++ break; ++ } ++ ++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG); ++ if (gr_usermode->segv_device && gr_usermode->segv_inode) { ++ struct acl_subject_label *segvacl; ++ segvacl = ++ lookup_acl_subj_label(gr_usermode->segv_inode, ++ gr_usermode->segv_device, ++ current->role); ++ if (segvacl) { ++ segvacl->crashes = 0; ++ segvacl->expires = 0; ++ } ++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) { ++ gr_remove_uid(gr_usermode->segv_uid); ++ } ++ } else { ++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG); ++ error = -EPERM; ++ } ++ break; ++ case GR_SPROLE: ++ case GR_SPROLEPAM: ++ if (unlikely(!(gr_status & GR_READY))) { ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG); ++ error = -EAGAIN; ++ break; ++ } ++ ++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) { ++ current->role->expires = 0; ++ current->role->auth_attempts = 0; ++ } ++ ++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES && ++ time_after(current->role->expires, get_seconds())) { ++ error = -EBUSY; ++ goto out; ++ } ++ ++ if (lookup_special_role_auth ++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum) ++ && ((!sprole_salt && !sprole_sum) ++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) { ++ char *p = ""; ++ assign_special_role(gr_usermode->sp_role); ++ read_lock(&tasklist_lock); ++ if (current->parent) ++ p = current->parent->role->rolename; ++ read_unlock(&tasklist_lock); ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG, ++ p, acl_sp_role_value); ++ } else { ++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role); ++ error = -EPERM; ++ if(!(current->role->auth_attempts++)) ++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT; ++ ++ goto out; ++ } ++ break; ++ case GR_UNSPROLE: ++ if (unlikely(!(gr_status & GR_READY))) { ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG); ++ error = -EAGAIN; ++ break; ++ } ++ ++ if (current->role->roletype & GR_ROLE_SPECIAL) { ++ char *p = ""; ++ int i = 0; ++ ++ read_lock(&tasklist_lock); ++ if (current->parent) { ++ p = current->parent->role->rolename; ++ i = current->parent->acl_role_id; ++ } ++ read_unlock(&tasklist_lock); ++ ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i); ++ gr_set_acls(1); ++ } else { ++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename); ++ error = -EPERM; ++ goto out; ++ } ++ break; ++ default: ++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode); ++ error = -EINVAL; ++ break; ++ } ++ ++ if (error != -EPERM) ++ goto out; ++ ++ if(!(gr_auth_attempts++)) ++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT; ++ ++ out: ++ up(&gr_dev_sem); ++ return error; ++} ++ ++int ++gr_set_acls(const int type) ++{ ++ struct acl_object_label *obj; ++ struct task_struct *task, *task2; ++ struct file *filp; ++ struct acl_role_label *role = current->role; ++ __u16 acl_role_id = current->acl_role_id; ++ const struct cred *cred; ++ char *tmpname; ++ struct name_entry *nmatch; ++ struct acl_subject_label *tmpsubj; ++ ++ read_lock(&tasklist_lock); ++ read_lock(&grsec_exec_file_lock); ++ do_each_thread(task2, task) { ++ /* check to see if we're called from the exit handler, ++ if so, only replace ACLs that have inherited the admin ++ ACL */ ++ ++ if (type && (task->role != role || ++ task->acl_role_id != acl_role_id)) ++ continue; ++ ++ task->acl_role_id = 0; ++ task->acl_sp_role = 0; ++ ++ if ((filp = task->exec_file)) { ++ cred = __task_cred(task); ++ task->role = lookup_acl_role_label(task, cred->uid, cred->gid); ++ ++ /* the following is to apply the correct subject ++ on binaries running when the RBAC system ++ is enabled, when the binaries have been ++ replaced or deleted since their execution ++ ----- ++ when the RBAC system starts, the inode/dev ++ from exec_file will be one the RBAC system ++ is unaware of. It only knows the inode/dev ++ of the present file on disk, or the absence ++ of it. ++ */ ++ preempt_disable(); ++ tmpname = gr_to_filename_rbac(filp->f_path.dentry, filp->f_path.mnt); ++ ++ nmatch = lookup_name_entry(tmpname); ++ preempt_enable(); ++ tmpsubj = NULL; ++ if (nmatch) { ++ if (nmatch->deleted) ++ tmpsubj = lookup_acl_subj_label_deleted(nmatch->inode, nmatch->device, task->role); ++ else ++ tmpsubj = lookup_acl_subj_label(nmatch->inode, nmatch->device, task->role); ++ if (tmpsubj != NULL) ++ task->acl = tmpsubj; ++ } ++ if (tmpsubj == NULL) ++ task->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, ++ task->role); ++ if (task->acl) { ++ struct acl_subject_label *curr; ++ curr = task->acl; ++ ++ task->is_writable = 0; ++ /* ignore additional mmap checks for processes that are writable ++ by the default ACL */ ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label); ++ if (unlikely(obj->mode & GR_WRITE)) ++ task->is_writable = 1; ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label); ++ if (unlikely(obj->mode & GR_WRITE)) ++ task->is_writable = 1; ++ ++ gr_set_proc_res(task); ++ ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); ++#endif ++ } else { ++ read_unlock(&grsec_exec_file_lock); ++ read_unlock(&tasklist_lock); ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid); ++ return 1; ++ } ++ } else { ++ // it's a kernel process ++ task->role = kernel_role; ++ task->acl = kernel_role->root_label; ++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN ++ task->acl->mode &= ~GR_PROCFIND; ++#endif ++ } ++ } while_each_thread(task2, task); ++ read_unlock(&grsec_exec_file_lock); ++ read_unlock(&tasklist_lock); ++ return 0; ++} ++ ++void ++gr_learn_resource(const struct task_struct *task, ++ const int res, const unsigned long wanted, const int gt) ++{ ++ struct acl_subject_label *acl; ++ const struct cred *cred; ++ ++ if (unlikely((gr_status & GR_READY) && ++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN)))) ++ goto skip_reslog; ++ ++#ifdef CONFIG_GRKERNSEC_RESLOG ++ gr_log_resource(task, res, wanted, gt); ++#endif ++ skip_reslog: ++ ++ if (unlikely(!(gr_status & GR_READY) || !wanted || res >= GR_NLIMITS)) ++ return; ++ ++ acl = task->acl; ++ ++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) || ++ !(acl->resmask & (1 << (unsigned short) res)))) ++ return; ++ ++ if (wanted >= acl->res[res].rlim_cur) { ++ unsigned long res_add; ++ ++ res_add = wanted; ++ switch (res) { ++ case RLIMIT_CPU: ++ res_add += GR_RLIM_CPU_BUMP; ++ break; ++ case RLIMIT_FSIZE: ++ res_add += GR_RLIM_FSIZE_BUMP; ++ break; ++ case RLIMIT_DATA: ++ res_add += GR_RLIM_DATA_BUMP; ++ break; ++ case RLIMIT_STACK: ++ res_add += GR_RLIM_STACK_BUMP; ++ break; ++ case RLIMIT_CORE: ++ res_add += GR_RLIM_CORE_BUMP; ++ break; ++ case RLIMIT_RSS: ++ res_add += GR_RLIM_RSS_BUMP; ++ break; ++ case RLIMIT_NPROC: ++ res_add += GR_RLIM_NPROC_BUMP; ++ break; ++ case RLIMIT_NOFILE: ++ res_add += GR_RLIM_NOFILE_BUMP; ++ break; ++ case RLIMIT_MEMLOCK: ++ res_add += GR_RLIM_MEMLOCK_BUMP; ++ break; ++ case RLIMIT_AS: ++ res_add += GR_RLIM_AS_BUMP; ++ break; ++ case RLIMIT_LOCKS: ++ res_add += GR_RLIM_LOCKS_BUMP; ++ break; ++ case RLIMIT_SIGPENDING: ++ res_add += GR_RLIM_SIGPENDING_BUMP; ++ break; ++ case RLIMIT_MSGQUEUE: ++ res_add += GR_RLIM_MSGQUEUE_BUMP; ++ break; ++ case RLIMIT_NICE: ++ res_add += GR_RLIM_NICE_BUMP; ++ break; ++ case RLIMIT_RTPRIO: ++ res_add += GR_RLIM_RTPRIO_BUMP; ++ break; ++ case RLIMIT_RTTIME: ++ res_add += GR_RLIM_RTTIME_BUMP; ++ break; ++ } ++ ++ acl->res[res].rlim_cur = res_add; ++ ++ if (wanted > acl->res[res].rlim_max) ++ acl->res[res].rlim_max = res_add; ++ ++ /* only log the subject filename, since resource logging is supported for ++ single-subject learning only */ ++ cred = __task_cred(task); ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, ++ task->role->roletype, cred->uid, cred->gid, acl->filename, ++ acl->filename, acl->res[res].rlim_cur, acl->res[res].rlim_max, ++ "", (unsigned long) res, NIPQUAD(task->signal->curr_ip)); ++ } ++ ++ return; ++} ++ ++#if defined(CONFIG_PAX_HAVE_ACL_FLAGS) && (defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)) ++void ++pax_set_initial_flags(struct linux_binprm *bprm) ++{ ++ struct task_struct *task = current; ++ struct acl_subject_label *proc; ++ unsigned long flags; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return; ++ ++ flags = pax_get_flags(task); ++ ++ proc = task->acl; ++ ++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC) ++ flags &= ~MF_PAX_PAGEEXEC; ++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC) ++ flags &= ~MF_PAX_SEGMEXEC; ++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP) ++ flags &= ~MF_PAX_RANDMMAP; ++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP) ++ flags &= ~MF_PAX_EMUTRAMP; ++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT) ++ flags &= ~MF_PAX_MPROTECT; ++ ++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC) ++ flags |= MF_PAX_PAGEEXEC; ++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC) ++ flags |= MF_PAX_SEGMEXEC; ++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP) ++ flags |= MF_PAX_RANDMMAP; ++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP) ++ flags |= MF_PAX_EMUTRAMP; ++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT) ++ flags |= MF_PAX_MPROTECT; ++ ++ pax_set_flags(task, flags); ++ ++ return; ++} ++#endif ++ ++#ifdef CONFIG_SYSCTL ++/* Eric Biederman likes breaking userland ABI and every inode-based security ++ system to save 35kb of memory */ ++ ++/* we modify the passed in filename, but adjust it back before returning */ ++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len) ++{ ++ struct name_entry *nmatch; ++ char *p, *lastp = NULL; ++ struct acl_object_label *obj = NULL, *tmp; ++ struct acl_subject_label *tmpsubj; ++ char c = '\0'; ++ ++ read_lock(&gr_inode_lock); ++ ++ p = name + len - 1; ++ do { ++ nmatch = lookup_name_entry(name); ++ if (lastp != NULL) ++ *lastp = c; ++ ++ if (nmatch == NULL) ++ goto next_component; ++ tmpsubj = current->acl; ++ do { ++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj); ++ if (obj != NULL) { ++ tmp = obj->globbed; ++ while (tmp) { ++ if (!glob_match(tmp->filename, name)) { ++ obj = tmp; ++ goto found_obj; ++ } ++ tmp = tmp->next; ++ } ++ goto found_obj; ++ } ++ } while ((tmpsubj = tmpsubj->parent_subject)); ++next_component: ++ /* end case */ ++ if (p == name) ++ break; ++ ++ while (*p != '/') ++ p--; ++ if (p == name) ++ lastp = p + 1; ++ else { ++ lastp = p; ++ p--; ++ } ++ c = *lastp; ++ *lastp = '\0'; ++ } while (1); ++found_obj: ++ read_unlock(&gr_inode_lock); ++ /* obj returned will always be non-null */ ++ return obj; ++} ++ ++/* returns 0 when allowing, non-zero on error ++ op of 0 is used for readdir, so we don't log the names of hidden files ++*/ ++__u32 ++gr_handle_sysctl(const struct ctl_table *table, const int op) ++{ ++ ctl_table *tmp; ++ const char *proc_sys = "/proc/sys"; ++ char *path; ++ struct acl_object_label *obj; ++ unsigned short len = 0, pos = 0, depth = 0, i; ++ __u32 err = 0; ++ __u32 mode = 0; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return 0; ++ ++ /* for now, ignore operations on non-sysctl entries if it's not a ++ readdir*/ ++ if (table->child != NULL && op != 0) ++ return 0; ++ ++ mode |= GR_FIND; ++ /* it's only a read if it's an entry, read on dirs is for readdir */ ++ if (op & MAY_READ) ++ mode |= GR_READ; ++ if (op & MAY_WRITE) ++ mode |= GR_WRITE; ++ ++ preempt_disable(); ++ ++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id()); ++ ++ /* it's only a read/write if it's an actual entry, not a dir ++ (which are opened for readdir) ++ */ ++ ++ /* convert the requested sysctl entry into a pathname */ ++ ++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) { ++ len += strlen(tmp->procname); ++ len++; ++ depth++; ++ } ++ ++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) { ++ /* deny */ ++ goto out; ++ } ++ ++ memset(path, 0, PAGE_SIZE); ++ ++ memcpy(path, proc_sys, strlen(proc_sys)); ++ ++ pos += strlen(proc_sys); ++ ++ for (; depth > 0; depth--) { ++ path[pos] = '/'; ++ pos++; ++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) { ++ if (depth == i) { ++ memcpy(path + pos, tmp->procname, ++ strlen(tmp->procname)); ++ pos += strlen(tmp->procname); ++ } ++ i++; ++ } ++ } ++ ++ obj = gr_lookup_by_name(path, pos); ++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS); ++ ++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) && ++ ((err & mode) != mode))) { ++ __u32 new_mode = mode; ++ ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); ++ ++ err = 0; ++ gr_log_learn_sysctl(path, new_mode); ++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) { ++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path); ++ err = -ENOENT; ++ } else if (!(err & GR_FIND)) { ++ err = -ENOENT; ++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) { ++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied", ++ path, (mode & GR_READ) ? " reading" : "", ++ (mode & GR_WRITE) ? " writing" : ""); ++ err = -EACCES; ++ } else if ((err & mode) != mode) { ++ err = -EACCES; ++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) { ++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful", ++ path, (mode & GR_READ) ? " reading" : "", ++ (mode & GR_WRITE) ? " writing" : ""); ++ err = 0; ++ } else ++ err = 0; ++ ++ out: ++ preempt_enable(); ++ ++ return err; ++} ++#endif ++ ++int ++gr_handle_proc_ptrace(struct task_struct *task) ++{ ++ struct file *filp; ++ struct task_struct *tmp = task; ++ struct task_struct *curtemp = current; ++ __u32 retmode; ++ ++#ifndef CONFIG_GRKERNSEC_HARDEN_PTRACE ++ if (unlikely(!(gr_status & GR_READY))) ++ return 0; ++#endif ++ ++ read_lock(&tasklist_lock); ++ read_lock(&grsec_exec_file_lock); ++ filp = task->exec_file; ++ ++ while (tmp->pid > 0) { ++ if (tmp == curtemp) ++ break; ++ tmp = tmp->parent; ++ } ++ ++ if (!filp || (tmp->pid == 0 && ((grsec_enable_harden_ptrace && current_uid() && !(gr_status & GR_READY)) || ++ ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE))))) { ++ read_unlock(&grsec_exec_file_lock); ++ read_unlock(&tasklist_lock); ++ return 1; ++ } ++ ++#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE ++ if (!(gr_status & GR_READY)) { ++ read_unlock(&grsec_exec_file_lock); ++ read_unlock(&tasklist_lock); ++ return 0; ++ } ++#endif ++ ++ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt); ++ read_unlock(&grsec_exec_file_lock); ++ read_unlock(&tasklist_lock); ++ ++ if (retmode & GR_NOPTRACE) ++ return 1; ++ ++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD) ++ && (current->acl != task->acl || (current->acl != current->role->root_label ++ && current->pid != task->pid))) ++ return 1; ++ ++ return 0; ++} ++ ++int ++gr_handle_ptrace(struct task_struct *task, const long request) ++{ ++ struct task_struct *tmp = task; ++ struct task_struct *curtemp = current; ++ __u32 retmode; ++ ++#ifndef CONFIG_GRKERNSEC_HARDEN_PTRACE ++ if (unlikely(!(gr_status & GR_READY))) ++ return 0; ++#endif ++ ++ read_lock(&tasklist_lock); ++ while (tmp->pid > 0) { ++ if (tmp == curtemp) ++ break; ++ tmp = tmp->parent; ++ } ++ ++ if (tmp->pid == 0 && ((grsec_enable_harden_ptrace && current_uid() && !(gr_status & GR_READY)) || ++ ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE)))) { ++ read_unlock(&tasklist_lock); ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); ++ return 1; ++ } ++ read_unlock(&tasklist_lock); ++ ++#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE ++ if (!(gr_status & GR_READY)) ++ return 0; ++#endif ++ ++ read_lock(&grsec_exec_file_lock); ++ if (unlikely(!task->exec_file)) { ++ read_unlock(&grsec_exec_file_lock); ++ return 0; ++ } ++ ++ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt); ++ read_unlock(&grsec_exec_file_lock); ++ ++ if (retmode & GR_NOPTRACE) { ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); ++ return 1; ++ } ++ ++ if (retmode & GR_PTRACERD) { ++ switch (request) { ++ case PTRACE_POKETEXT: ++ case PTRACE_POKEDATA: ++ case PTRACE_POKEUSR: ++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64) ++ case PTRACE_SETREGS: ++ case PTRACE_SETFPREGS: ++#endif ++#ifdef CONFIG_X86 ++ case PTRACE_SETFPXREGS: ++#endif ++#ifdef CONFIG_ALTIVEC ++ case PTRACE_SETVRREGS: ++#endif ++ return 1; ++ default: ++ return 0; ++ } ++ } else if (!(current->acl->mode & GR_POVERRIDE) && ++ !(current->role->roletype & GR_ROLE_GOD) && ++ (current->acl != task->acl)) { ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int is_writable_mmap(const struct file *filp) ++{ ++ struct task_struct *task = current; ++ struct acl_object_label *obj, *obj2; ++ ++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) && ++ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) { ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label); ++ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, ++ task->role->root_label); ++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) { ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt); ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++int ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot) ++{ ++ __u32 mode; ++ ++ if (unlikely(!file || !(prot & PROT_EXEC))) ++ return 1; ++ ++ if (is_writable_mmap(file)) ++ return 0; ++ ++ mode = ++ gr_search_file(file->f_path.dentry, ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, ++ file->f_path.mnt); ++ ++ if (!gr_tpe_allow(file)) ++ return 0; ++ ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) { ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt); ++ return 0; ++ } else if (unlikely(!(mode & GR_EXEC))) { ++ return 0; ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) { ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt); ++ return 1; ++ } ++ ++ return 1; ++} ++ ++int ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot) ++{ ++ __u32 mode; ++ ++ if (unlikely(!file || !(prot & PROT_EXEC))) ++ return 1; ++ ++ if (is_writable_mmap(file)) ++ return 0; ++ ++ mode = ++ gr_search_file(file->f_path.dentry, ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, ++ file->f_path.mnt); ++ ++ if (!gr_tpe_allow(file)) ++ return 0; ++ ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) { ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt); ++ return 0; ++ } else if (unlikely(!(mode & GR_EXEC))) { ++ return 0; ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) { ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt); ++ return 1; ++ } ++ ++ return 1; ++} ++ ++void ++gr_acl_handle_psacct(struct task_struct *task, const long code) ++{ ++ unsigned long runtime; ++ unsigned long cputime; ++ unsigned int wday, cday; ++ __u8 whr, chr; ++ __u8 wmin, cmin; ++ __u8 wsec, csec; ++ struct timespec timeval; ++ ++ if (unlikely(!(gr_status & GR_READY) || !task->acl || ++ !(task->acl->mode & GR_PROCACCT))) ++ return; ++ ++ do_posix_clock_monotonic_gettime(&timeval); ++ runtime = timeval.tv_sec - task->start_time.tv_sec; ++ wday = runtime / (3600 * 24); ++ runtime -= wday * (3600 * 24); ++ whr = runtime / 3600; ++ runtime -= whr * 3600; ++ wmin = runtime / 60; ++ runtime -= wmin * 60; ++ wsec = runtime; ++ ++ cputime = (task->utime + task->stime) / HZ; ++ cday = cputime / (3600 * 24); ++ cputime -= cday * (3600 * 24); ++ chr = cputime / 3600; ++ cputime -= chr * 3600; ++ cmin = cputime / 60; ++ cputime -= cmin * 60; ++ csec = cputime; ++ ++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code); ++ ++ return; ++} ++ ++void gr_set_kernel_label(struct task_struct *task) ++{ ++ if (gr_status & GR_READY) { ++ task->role = kernel_role; ++ task->acl = kernel_role->root_label; ++ } ++ return; ++} ++ ++#ifdef CONFIG_TASKSTATS ++int gr_is_taskstats_denied(int pid) ++{ ++ struct task_struct *task; ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ const struct cred *cred; ++#endif ++ int ret = 0; ++ ++ /* restrict taskstats viewing to un-chrooted root users ++ who have the 'view' subject flag if the RBAC system is enabled ++ */ ++ ++ read_lock(&tasklist_lock); ++ task = find_task_by_vpid(pid); ++ if (task) { ++ task_lock(task); ++#ifdef CONFIG_GRKERNSEC_CHROOT ++ if (proc_is_chrooted(task)) ++ ret = -EACCES; ++#endif ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ cred = __task_cred(task); ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ if (cred->uid != 0) ++ ret = -EACCES; ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ if (cred->uid != 0 && !groups_search(cred->group_info, CONFIG_GRKERNSEC_PROC_GID)) ++ ret = -EACCES; ++#endif ++#endif ++ if (gr_status & GR_READY) { ++ if (!(task->acl->mode & GR_VIEW)) ++ ret = -EACCES; ++ } ++ ++ task_unlock(task); ++ } else ++ ret = -ENOENT; ++ ++ read_unlock(&tasklist_lock); ++ ++ return ret; ++} ++#endif ++ ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino) ++{ ++ struct task_struct *task = current; ++ struct dentry *dentry = file->f_path.dentry; ++ struct vfsmount *mnt = file->f_path.mnt; ++ struct acl_object_label *obj, *tmp; ++ struct acl_subject_label *subj; ++ unsigned int bufsize; ++ int is_not_root; ++ char *path; ++ ++ if (unlikely(!(gr_status & GR_READY))) ++ return 1; ++ ++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN)) ++ return 1; ++ ++ /* ignore Eric Biederman */ ++ if (IS_PRIVATE(dentry->d_inode)) ++ return 1; ++ ++ subj = task->acl; ++ do { ++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj); ++ if (obj != NULL) ++ return (obj->mode & GR_FIND) ? 1 : 0; ++ } while ((subj = subj->parent_subject)); ++ ++ /* this is purely an optimization since we're looking for an object ++ for the directory we're doing a readdir on ++ if it's possible for any globbed object to match the entry we're ++ filling into the directory, then the object we find here will be ++ an anchor point with attached globbed objects ++ */ ++ obj = chk_obj_label_noglob(dentry, mnt, task->acl); ++ if (obj->globbed == NULL) ++ return (obj->mode & GR_FIND) ? 1 : 0; ++ ++ is_not_root = ((obj->filename[0] == '/') && ++ (obj->filename[1] == '\0')) ? 0 : 1; ++ bufsize = PAGE_SIZE - namelen - is_not_root; ++ ++ /* check bufsize > PAGE_SIZE || bufsize == 0 */ ++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1))) ++ return 1; ++ ++ preempt_disable(); ++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()), ++ bufsize); ++ ++ bufsize = strlen(path); ++ ++ /* if base is "/", don't append an additional slash */ ++ if (is_not_root) ++ *(path + bufsize) = '/'; ++ memcpy(path + bufsize + is_not_root, name, namelen); ++ *(path + bufsize + namelen + is_not_root) = '\0'; ++ ++ tmp = obj->globbed; ++ while (tmp) { ++ if (!glob_match(tmp->filename, path)) { ++ preempt_enable(); ++ return (tmp->mode & GR_FIND) ? 1 : 0; ++ } ++ tmp = tmp->next; ++ } ++ preempt_enable(); ++ return (obj->mode & GR_FIND) ? 1 : 0; ++} ++ ++EXPORT_SYMBOL(gr_learn_resource); ++EXPORT_SYMBOL(gr_set_kernel_label); ++#ifdef CONFIG_SECURITY ++EXPORT_SYMBOL(gr_check_user_change); ++EXPORT_SYMBOL(gr_check_group_change); ++#endif ++ +diff -urNp linux-2.6.31.1/grsecurity/gracl_cap.c linux-2.6.31.1/grsecurity/gracl_cap.c +--- linux-2.6.31.1/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/gracl_cap.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,131 @@ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/gracl.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++static const char *captab_log[] = { ++ "CAP_CHOWN", ++ "CAP_DAC_OVERRIDE", ++ "CAP_DAC_READ_SEARCH", ++ "CAP_FOWNER", ++ "CAP_FSETID", ++ "CAP_KILL", ++ "CAP_SETGID", ++ "CAP_SETUID", ++ "CAP_SETPCAP", ++ "CAP_LINUX_IMMUTABLE", ++ "CAP_NET_BIND_SERVICE", ++ "CAP_NET_BROADCAST", ++ "CAP_NET_ADMIN", ++ "CAP_NET_RAW", ++ "CAP_IPC_LOCK", ++ "CAP_IPC_OWNER", ++ "CAP_SYS_MODULE", ++ "CAP_SYS_RAWIO", ++ "CAP_SYS_CHROOT", ++ "CAP_SYS_PTRACE", ++ "CAP_SYS_PACCT", ++ "CAP_SYS_ADMIN", ++ "CAP_SYS_BOOT", ++ "CAP_SYS_NICE", ++ "CAP_SYS_RESOURCE", ++ "CAP_SYS_TIME", ++ "CAP_SYS_TTY_CONFIG", ++ "CAP_MKNOD", ++ "CAP_LEASE", ++ "CAP_AUDIT_WRITE", ++ "CAP_AUDIT_CONTROL", ++ "CAP_SETFCAP", ++ "CAP_MAC_OVERRIDE", ++ "CAP_MAC_ADMIN" ++}; ++ ++EXPORT_SYMBOL(gr_is_capable); ++EXPORT_SYMBOL(gr_is_capable_nolog); ++ ++int ++gr_is_capable(const int cap) ++{ ++ struct task_struct *task = current; ++ const struct cred *cred = current_cred(); ++ struct acl_subject_label *curracl; ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set; ++ ++ if (!gr_acl_is_enabled()) ++ return 1; ++ ++ curracl = task->acl; ++ ++ cap_drop = curracl->cap_lower; ++ cap_mask = curracl->cap_mask; ++ ++ while ((curracl = curracl->parent_subject)) { ++ /* if the cap isn't specified in the current computed mask but is specified in the ++ current level subject, and is lowered in the current level subject, then add ++ it to the set of dropped capabilities ++ otherwise, add the current level subject's mask to the current computed mask ++ */ ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) { ++ cap_raise(cap_mask, cap); ++ if (cap_raised(curracl->cap_lower, cap)) ++ cap_raise(cap_drop, cap); ++ } ++ } ++ ++ if (!cap_raised(cap_drop, cap)) ++ return 1; ++ ++ curracl = task->acl; ++ ++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) ++ && cap_raised(cred->cap_effective, cap)) { ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, ++ task->role->roletype, cred->uid, ++ cred->gid, task->exec_file ? ++ gr_to_filename(task->exec_file->f_path.dentry, ++ task->exec_file->f_path.mnt) : curracl->filename, ++ curracl->filename, 0UL, ++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip)); ++ return 1; ++ } ++ ++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(cred->cap_effective, cap)) ++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]); ++ return 0; ++} ++ ++int ++gr_is_capable_nolog(const int cap) ++{ ++ struct acl_subject_label *curracl; ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set; ++ ++ if (!gr_acl_is_enabled()) ++ return 1; ++ ++ curracl = current->acl; ++ ++ cap_drop = curracl->cap_lower; ++ cap_mask = curracl->cap_mask; ++ ++ while ((curracl = curracl->parent_subject)) { ++ /* if the cap isn't specified in the current computed mask but is specified in the ++ current level subject, and is lowered in the current level subject, then add ++ it to the set of dropped capabilities ++ otherwise, add the current level subject's mask to the current computed mask ++ */ ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) { ++ cap_raise(cap_mask, cap); ++ if (cap_raised(curracl->cap_lower, cap)) ++ cap_raise(cap_drop, cap); ++ } ++ } ++ ++ if (!cap_raised(cap_drop, cap)) ++ return 1; ++ ++ return 0; ++} ++ +diff -urNp linux-2.6.31.1/grsecurity/gracl_fs.c linux-2.6.31.1/grsecurity/gracl_fs.c +--- linux-2.6.31.1/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/gracl_fs.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,424 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/types.h> ++#include <linux/fs.h> ++#include <linux/file.h> ++#include <linux/stat.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++#include <linux/gracl.h> ++ ++__u32 ++gr_acl_handle_hidden_file(const struct dentry * dentry, ++ const struct vfsmount * mnt) ++{ ++ __u32 mode; ++ ++ if (unlikely(!dentry->d_inode)) ++ return GR_FIND; ++ ++ mode = ++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt); ++ ++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) { ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt); ++ return mode; ++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) { ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt); ++ return 0; ++ } else if (unlikely(!(mode & GR_FIND))) ++ return 0; ++ ++ return GR_FIND; ++} ++ ++__u32 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, ++ const int fmode) ++{ ++ __u32 reqmode = GR_FIND; ++ __u32 mode; ++ ++ if (unlikely(!dentry->d_inode)) ++ return reqmode; ++ ++ if (unlikely(fmode & O_APPEND)) ++ reqmode |= GR_APPEND; ++ else if (unlikely(fmode & FMODE_WRITE)) ++ reqmode |= GR_WRITE; ++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) ++ reqmode |= GR_READ; ++ if ((fmode & FMODE_GREXEC) && (fmode & FMODE_EXEC)) ++ reqmode &= ~GR_READ; ++ mode = ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, ++ mnt); ++ ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, ++ reqmode & GR_READ ? " reading" : "", ++ reqmode & GR_WRITE ? " writing" : reqmode & ++ GR_APPEND ? " appending" : ""); ++ return reqmode; ++ } else ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) ++ { ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, ++ reqmode & GR_READ ? " reading" : "", ++ reqmode & GR_WRITE ? " writing" : reqmode & ++ GR_APPEND ? " appending" : ""); ++ return 0; ++ } else if (unlikely((mode & reqmode) != reqmode)) ++ return 0; ++ ++ return reqmode; ++} ++ ++__u32 ++gr_acl_handle_creat(const struct dentry * dentry, ++ const struct dentry * p_dentry, ++ const struct vfsmount * p_mnt, const int fmode, ++ const int imode) ++{ ++ __u32 reqmode = GR_WRITE | GR_CREATE; ++ __u32 mode; ++ ++ if (unlikely(fmode & O_APPEND)) ++ reqmode |= GR_APPEND; ++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) ++ reqmode |= GR_READ; ++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID)))) ++ reqmode |= GR_SETID; ++ ++ mode = ++ gr_check_create(dentry, p_dentry, p_mnt, ++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); ++ ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt, ++ reqmode & GR_READ ? " reading" : "", ++ reqmode & GR_WRITE ? " writing" : reqmode & ++ GR_APPEND ? " appending" : ""); ++ return reqmode; ++ } else ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) ++ { ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt, ++ reqmode & GR_READ ? " reading" : "", ++ reqmode & GR_WRITE ? " writing" : reqmode & ++ GR_APPEND ? " appending" : ""); ++ return 0; ++ } else if (unlikely((mode & reqmode) != reqmode)) ++ return 0; ++ ++ return reqmode; ++} ++ ++__u32 ++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt, ++ const int fmode) ++{ ++ __u32 mode, reqmode = GR_FIND; ++ ++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode)) ++ reqmode |= GR_EXEC; ++ if (fmode & S_IWOTH) ++ reqmode |= GR_WRITE; ++ if (fmode & S_IROTH) ++ reqmode |= GR_READ; ++ ++ mode = ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, ++ mnt); ++ ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { ++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt, ++ reqmode & GR_READ ? " reading" : "", ++ reqmode & GR_WRITE ? " writing" : "", ++ reqmode & GR_EXEC ? " executing" : ""); ++ return reqmode; ++ } else ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) ++ { ++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt, ++ reqmode & GR_READ ? " reading" : "", ++ reqmode & GR_WRITE ? " writing" : "", ++ reqmode & GR_EXEC ? " executing" : ""); ++ return 0; ++ } else if (unlikely((mode & reqmode) != reqmode)) ++ return 0; ++ ++ return reqmode; ++} ++ ++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt) ++{ ++ __u32 mode; ++ ++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); ++ ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt); ++ return mode; ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt); ++ return 0; ++ } else if (unlikely((mode & (reqmode)) != (reqmode))) ++ return 0; ++ ++ return (reqmode); ++} ++ ++__u32 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt) ++{ ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG); ++} ++ ++__u32 ++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG); ++} ++ ++__u32 ++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG); ++} ++ ++__u32 ++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG); ++} ++ ++__u32 ++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt, ++ mode_t mode) ++{ ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode))) ++ return 1; ++ ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) { ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID, ++ GR_FCHMOD_ACL_MSG); ++ } else { ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG); ++ } ++} ++ ++__u32 ++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt, ++ mode_t mode) ++{ ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) { ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID, ++ GR_CHMOD_ACL_MSG); ++ } else { ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG); ++ } ++} ++ ++__u32 ++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG); ++} ++ ++__u32 ++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG); ++} ++ ++__u32 ++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE, ++ GR_UNIXCONNECT_ACL_MSG); ++} ++ ++/* hardlinks require at minimum create permission, ++ any additional privilege required is based on the ++ privilege of the file being linked to ++*/ ++__u32 ++gr_acl_handle_link(const struct dentry * new_dentry, ++ const struct dentry * parent_dentry, ++ const struct vfsmount * parent_mnt, ++ const struct dentry * old_dentry, ++ const struct vfsmount * old_mnt, const char *to) ++{ ++ __u32 mode; ++ __u32 needmode = GR_CREATE | GR_LINK; ++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK; ++ ++ mode = ++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry, ++ old_mnt); ++ ++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) { ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to); ++ return mode; ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) { ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to); ++ return 0; ++ } else if (unlikely((mode & needmode) != needmode)) ++ return 0; ++ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_symlink(const struct dentry * new_dentry, ++ const struct dentry * parent_dentry, ++ const struct vfsmount * parent_mnt, const char *from) ++{ ++ __u32 needmode = GR_WRITE | GR_CREATE; ++ __u32 mode; ++ ++ mode = ++ gr_check_create(new_dentry, parent_dentry, parent_mnt, ++ GR_CREATE | GR_AUDIT_CREATE | ++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS); ++ ++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) { ++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt); ++ return mode; ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) { ++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt); ++ return 0; ++ } else if (unlikely((mode & needmode) != needmode)) ++ return 0; ++ ++ return (GR_WRITE | GR_CREATE); ++} ++ ++static __u32 generic_fs_create_handler(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, __u32 reqmode, const char *fmt) ++{ ++ __u32 mode; ++ ++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); ++ ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt); ++ return mode; ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt); ++ return 0; ++ } else if (unlikely((mode & (reqmode)) != (reqmode))) ++ return 0; ++ ++ return (reqmode); ++} ++ ++__u32 ++gr_acl_handle_mknod(const struct dentry * new_dentry, ++ const struct dentry * parent_dentry, ++ const struct vfsmount * parent_mnt, ++ const int mode) ++{ ++ __u32 reqmode = GR_WRITE | GR_CREATE; ++ if (unlikely(mode & (S_ISUID | S_ISGID))) ++ reqmode |= GR_SETID; ++ ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, ++ reqmode, GR_MKNOD_ACL_MSG); ++} ++ ++__u32 ++gr_acl_handle_mkdir(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt) ++{ ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, ++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG); ++} ++ ++#define RENAME_CHECK_SUCCESS(old, new) \ ++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \ ++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ))) ++ ++int ++gr_acl_handle_rename(struct dentry *new_dentry, ++ struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ struct dentry *old_dentry, ++ struct inode *old_parent_inode, ++ struct vfsmount *old_mnt, const char *newname) ++{ ++ __u32 comp1, comp2; ++ int error = 0; ++ ++ if (unlikely(!gr_acl_is_enabled())) ++ return 0; ++ ++ if (!new_dentry->d_inode) { ++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt, ++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ | ++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS); ++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE | ++ GR_DELETE | GR_AUDIT_DELETE | ++ GR_AUDIT_READ | GR_AUDIT_WRITE | ++ GR_SUPPRESS, old_mnt); ++ } else { ++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE | ++ GR_CREATE | GR_DELETE | ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | ++ GR_AUDIT_READ | GR_AUDIT_WRITE | ++ GR_SUPPRESS, parent_mnt); ++ comp2 = ++ gr_search_file(old_dentry, ++ GR_READ | GR_WRITE | GR_AUDIT_READ | ++ GR_DELETE | GR_AUDIT_DELETE | ++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt); ++ } ++ ++ if (RENAME_CHECK_SUCCESS(comp1, comp2) && ++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS))) ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname); ++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS) ++ && !(comp2 & GR_SUPPRESS)) { ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname); ++ error = -EACCES; ++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2))) ++ error = -EACCES; ++ ++ return error; ++} ++ ++void ++gr_acl_handle_exit(void) ++{ ++ u16 id; ++ char *rolename; ++ struct file *exec_file; ++ ++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) { ++ id = current->acl_role_id; ++ rolename = current->role->rolename; ++ gr_set_acls(1); ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id); ++ } ++ ++ write_lock(&grsec_exec_file_lock); ++ exec_file = current->exec_file; ++ current->exec_file = NULL; ++ write_unlock(&grsec_exec_file_lock); ++ ++ if (exec_file) ++ fput(exec_file); ++} ++ ++int ++gr_acl_handle_procpidmem(const struct task_struct *task) ++{ ++ if (unlikely(!gr_acl_is_enabled())) ++ return 0; ++ ++ if (task != current && task->acl->mode & GR_PROTPROCFD) ++ return -EACCES; ++ ++ return 0; ++} +diff -urNp linux-2.6.31.1/grsecurity/gracl_ip.c linux-2.6.31.1/grsecurity/gracl_ip.c +--- linux-2.6.31.1/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/gracl_ip.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,340 @@ ++#include <linux/kernel.h> ++#include <asm/uaccess.h> ++#include <asm/errno.h> ++#include <net/sock.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++#include <linux/net.h> ++#include <linux/in.h> ++#include <linux/skbuff.h> ++#include <linux/ip.h> ++#include <linux/udp.h> ++#include <linux/smp_lock.h> ++#include <linux/types.h> ++#include <linux/sched.h> ++#include <linux/netdevice.h> ++#include <linux/inetdevice.h> ++#include <linux/gracl.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++#define GR_BIND 0x01 ++#define GR_CONNECT 0x02 ++#define GR_INVERT 0x04 ++#define GR_BINDOVERRIDE 0x08 ++#define GR_CONNECTOVERRIDE 0x10 ++ ++static const char * gr_protocols[256] = { ++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt", ++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet", ++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1", ++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp", ++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++", ++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre", ++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile", ++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63", ++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv", ++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", ++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", ++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp", ++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim", ++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip", ++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp", ++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup", ++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135", ++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143", ++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151", ++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159", ++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167", ++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175", ++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183", ++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191", ++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199", ++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207", ++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215", ++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223", ++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231", ++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239", ++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247", ++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255", ++ }; ++ ++static const char * gr_socktypes[11] = { ++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", ++ "unknown:7", "unknown:8", "unknown:9", "packet" ++ }; ++ ++const char * ++gr_proto_to_name(unsigned char proto) ++{ ++ return gr_protocols[proto]; ++} ++ ++const char * ++gr_socktype_to_name(unsigned char type) ++{ ++ return gr_socktypes[type]; ++} ++ ++int ++gr_search_socket(const int domain, const int type, const int protocol) ++{ ++ struct acl_subject_label *curr; ++ const struct cred *cred = current_cred(); ++ ++ if (unlikely(!gr_acl_is_enabled())) ++ goto exit; ++ ++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET) ++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255)) ++ goto exit; // let the kernel handle it ++ ++ curr = current->acl; ++ ++ if (!curr->ips) ++ goto exit; ++ ++ if ((curr->ip_type & (1 << type)) && ++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32)))) ++ goto exit; ++ ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) { ++ /* we don't place acls on raw sockets , and sometimes ++ dgram/ip sockets are opened for ioctl and not ++ bind/connect, so we'll fake a bind learn log */ ++ if (type == SOCK_RAW || type == SOCK_PACKET) { ++ __u32 fakeip = 0; ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename, ++ current->role->roletype, cred->uid, ++ cred->gid, current->exec_file ? ++ gr_to_filename(current->exec_file->f_path.dentry, ++ current->exec_file->f_path.mnt) : ++ curr->filename, curr->filename, ++ NIPQUAD(fakeip), 0, type, ++ protocol, GR_CONNECT, ++NIPQUAD(current->signal->curr_ip)); ++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) { ++ __u32 fakeip = 0; ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename, ++ current->role->roletype, cred->uid, ++ cred->gid, current->exec_file ? ++ gr_to_filename(current->exec_file->f_path.dentry, ++ current->exec_file->f_path.mnt) : ++ curr->filename, curr->filename, ++ NIPQUAD(fakeip), 0, type, ++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip)); ++ } ++ /* we'll log when they use connect or bind */ ++ goto exit; ++ } ++ ++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", ++ gr_socktype_to_name(type), gr_proto_to_name(protocol)); ++ ++ return 0; ++ exit: ++ return 1; ++} ++ ++int check_ip_policy(struct acl_ip_label *ip, __u32 ip_addr, __u16 ip_port, __u8 protocol, const int mode, const int type, __u32 our_addr, __u32 our_netmask) ++{ ++ if ((ip->mode & mode) && ++ (ip_port >= ip->low) && ++ (ip_port <= ip->high) && ++ ((ntohl(ip_addr) & our_netmask) == ++ (ntohl(our_addr) & our_netmask)) ++ && (ip->proto[protocol / 32] & (1 << (protocol % 32))) ++ && (ip->type & (1 << type))) { ++ if (ip->mode & GR_INVERT) ++ return 2; // specifically denied ++ else ++ return 1; // allowed ++ } ++ ++ return 0; // not specifically allowed, may continue parsing ++} ++ ++static int ++gr_search_connectbind(const int full_mode, struct sock *sk, ++ struct sockaddr_in *addr, const int type) ++{ ++ char iface[IFNAMSIZ] = {0}; ++ struct acl_subject_label *curr; ++ struct acl_ip_label *ip; ++ struct inet_sock *isk; ++ struct net_device *dev; ++ struct in_device *idev; ++ unsigned long i; ++ int ret; ++ int mode = full_mode & (GR_BIND | GR_CONNECT); ++ __u32 ip_addr = 0; ++ __u32 our_addr; ++ __u32 our_netmask; ++ char *p; ++ __u16 ip_port = 0; ++ const struct cred *cred = current_cred(); ++ ++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET)) ++ return 0; ++ ++ curr = current->acl; ++ isk = inet_sk(sk); ++ ++ /* INADDR_ANY overriding for binds, inaddr_any_override is already in network order */ ++ if ((full_mode & GR_BINDOVERRIDE) && addr->sin_addr.s_addr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0) ++ addr->sin_addr.s_addr = curr->inaddr_any_override; ++ if ((full_mode & GR_CONNECT) && isk->saddr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0) { ++ struct sockaddr_in saddr; ++ int err; ++ ++ saddr.sin_family = AF_INET; ++ saddr.sin_addr.s_addr = curr->inaddr_any_override; ++ saddr.sin_port = isk->sport; ++ ++ err = security_socket_bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)); ++ if (err) ++ return err; ++ ++ err = sk->sk_socket->ops->bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)); ++ if (err) ++ return err; ++ } ++ ++ if (!curr->ips) ++ return 0; ++ ++ ip_addr = addr->sin_addr.s_addr; ++ ip_port = ntohs(addr->sin_port); ++ ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) { ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename, ++ current->role->roletype, cred->uid, ++ cred->gid, current->exec_file ? ++ gr_to_filename(current->exec_file->f_path.dentry, ++ current->exec_file->f_path.mnt) : ++ curr->filename, curr->filename, ++ NIPQUAD(ip_addr), ip_port, type, ++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip)); ++ return 0; ++ } ++ ++ for (i = 0; i < curr->ip_num; i++) { ++ ip = *(curr->ips + i); ++ if (ip->iface != NULL) { ++ strncpy(iface, ip->iface, IFNAMSIZ - 1); ++ p = strchr(iface, ':'); ++ if (p != NULL) ++ *p = '\0'; ++ dev = dev_get_by_name(sock_net(sk), iface); ++ if (dev == NULL) ++ continue; ++ idev = in_dev_get(dev); ++ if (idev == NULL) { ++ dev_put(dev); ++ continue; ++ } ++ rcu_read_lock(); ++ for_ifa(idev) { ++ if (!strcmp(ip->iface, ifa->ifa_label)) { ++ our_addr = ifa->ifa_address; ++ our_netmask = 0xffffffff; ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask); ++ if (ret == 1) { ++ rcu_read_unlock(); ++ in_dev_put(idev); ++ dev_put(dev); ++ return 0; ++ } else if (ret == 2) { ++ rcu_read_unlock(); ++ in_dev_put(idev); ++ dev_put(dev); ++ goto denied; ++ } ++ } ++ } endfor_ifa(idev); ++ rcu_read_unlock(); ++ in_dev_put(idev); ++ dev_put(dev); ++ } else { ++ our_addr = ip->addr; ++ our_netmask = ip->netmask; ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask); ++ if (ret == 1) ++ return 0; ++ else if (ret == 2) ++ goto denied; ++ } ++ } ++ ++denied: ++ if (mode == GR_BIND) ++ gr_log_int5_str2(GR_DONT_AUDIT, GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol)); ++ else if (mode == GR_CONNECT) ++ gr_log_int5_str2(GR_DONT_AUDIT, GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol)); ++ ++ return -EACCES; ++} ++ ++int ++gr_search_connect(struct socket *sock, struct sockaddr_in *addr) ++{ ++ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sock->sk, addr, sock->type); ++} ++ ++int ++gr_search_bind(struct socket *sock, struct sockaddr_in *addr) ++{ ++ return gr_search_connectbind(GR_BIND | GR_BINDOVERRIDE, sock->sk, addr, sock->type); ++} ++ ++int gr_search_listen(struct socket *sock) ++{ ++ struct sock *sk = sock->sk; ++ struct sockaddr_in addr; ++ ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr; ++ addr.sin_port = inet_sk(sk)->sport; ++ ++ return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type); ++} ++ ++int gr_search_accept(struct socket *sock) ++{ ++ struct sock *sk = sock->sk; ++ struct sockaddr_in addr; ++ ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr; ++ addr.sin_port = inet_sk(sk)->sport; ++ ++ return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type); ++} ++ ++int ++gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr) ++{ ++ if (addr) ++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM); ++ else { ++ struct sockaddr_in sin; ++ const struct inet_sock *inet = inet_sk(sk); ++ ++ sin.sin_addr.s_addr = inet->daddr; ++ sin.sin_port = inet->dport; ++ ++ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM); ++ } ++} ++ ++int ++gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb) ++{ ++ struct sockaddr_in sin; ++ ++ if (unlikely(skb->len < sizeof (struct udphdr))) ++ return 0; // skip this packet ++ ++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr; ++ sin.sin_port = udp_hdr(skb)->source; ++ ++ return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM); ++} +diff -urNp linux-2.6.31.1/grsecurity/gracl_learn.c linux-2.6.31.1/grsecurity/gracl_learn.c +--- linux-2.6.31.1/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/gracl_learn.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,211 @@ ++#include <linux/kernel.h> ++#include <linux/mm.h> ++#include <linux/sched.h> ++#include <linux/poll.h> ++#include <linux/smp_lock.h> ++#include <linux/string.h> ++#include <linux/file.h> ++#include <linux/types.h> ++#include <linux/vmalloc.h> ++#include <linux/grinternal.h> ++ ++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf, ++ size_t count, loff_t *ppos); ++extern int gr_acl_is_enabled(void); ++ ++static DECLARE_WAIT_QUEUE_HEAD(learn_wait); ++static int gr_learn_attached; ++ ++/* use a 512k buffer */ ++#define LEARN_BUFFER_SIZE (512 * 1024) ++ ++static DEFINE_SPINLOCK(gr_learn_lock); ++static DECLARE_MUTEX(gr_learn_user_sem); ++ ++/* we need to maintain two buffers, so that the kernel context of grlearn ++ uses a semaphore around the userspace copying, and the other kernel contexts ++ use a spinlock when copying into the buffer, since they cannot sleep ++*/ ++static char *learn_buffer; ++static char *learn_buffer_user; ++static int learn_buffer_len; ++static int learn_buffer_user_len; ++ ++static ssize_t ++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos) ++{ ++ DECLARE_WAITQUEUE(wait, current); ++ ssize_t retval = 0; ++ ++ add_wait_queue(&learn_wait, &wait); ++ set_current_state(TASK_INTERRUPTIBLE); ++ do { ++ down(&gr_learn_user_sem); ++ spin_lock(&gr_learn_lock); ++ if (learn_buffer_len) ++ break; ++ spin_unlock(&gr_learn_lock); ++ up(&gr_learn_user_sem); ++ if (file->f_flags & O_NONBLOCK) { ++ retval = -EAGAIN; ++ goto out; ++ } ++ if (signal_pending(current)) { ++ retval = -ERESTARTSYS; ++ goto out; ++ } ++ ++ schedule(); ++ } while (1); ++ ++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len); ++ learn_buffer_user_len = learn_buffer_len; ++ retval = learn_buffer_len; ++ learn_buffer_len = 0; ++ ++ spin_unlock(&gr_learn_lock); ++ ++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len)) ++ retval = -EFAULT; ++ ++ up(&gr_learn_user_sem); ++out: ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&learn_wait, &wait); ++ return retval; ++} ++ ++static unsigned int ++poll_learn(struct file * file, poll_table * wait) ++{ ++ poll_wait(file, &learn_wait, wait); ++ ++ if (learn_buffer_len) ++ return (POLLIN | POLLRDNORM); ++ ++ return 0; ++} ++ ++void ++gr_clear_learn_entries(void) ++{ ++ char *tmp; ++ ++ down(&gr_learn_user_sem); ++ if (learn_buffer != NULL) { ++ spin_lock(&gr_learn_lock); ++ tmp = learn_buffer; ++ learn_buffer = NULL; ++ spin_unlock(&gr_learn_lock); ++ vfree(learn_buffer); ++ } ++ if (learn_buffer_user != NULL) { ++ vfree(learn_buffer_user); ++ learn_buffer_user = NULL; ++ } ++ learn_buffer_len = 0; ++ up(&gr_learn_user_sem); ++ ++ return; ++} ++ ++void ++gr_add_learn_entry(const char *fmt, ...) ++{ ++ va_list args; ++ unsigned int len; ++ ++ if (!gr_learn_attached) ++ return; ++ ++ spin_lock(&gr_learn_lock); ++ ++ /* leave a gap at the end so we know when it's "full" but don't have to ++ compute the exact length of the string we're trying to append ++ */ ++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) { ++ spin_unlock(&gr_learn_lock); ++ wake_up_interruptible(&learn_wait); ++ return; ++ } ++ if (learn_buffer == NULL) { ++ spin_unlock(&gr_learn_lock); ++ return; ++ } ++ ++ va_start(args, fmt); ++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args); ++ va_end(args); ++ ++ learn_buffer_len += len + 1; ++ ++ spin_unlock(&gr_learn_lock); ++ wake_up_interruptible(&learn_wait); ++ ++ return; ++} ++ ++static int ++open_learn(struct inode *inode, struct file *file) ++{ ++ if (file->f_mode & FMODE_READ && gr_learn_attached) ++ return -EBUSY; ++ if (file->f_mode & FMODE_READ) { ++ int retval = 0; ++ down(&gr_learn_user_sem); ++ if (learn_buffer == NULL) ++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE); ++ if (learn_buffer_user == NULL) ++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE); ++ if (learn_buffer == NULL) { ++ retval = -ENOMEM; ++ goto out_error; ++ } ++ if (learn_buffer_user == NULL) { ++ retval = -ENOMEM; ++ goto out_error; ++ } ++ learn_buffer_len = 0; ++ learn_buffer_user_len = 0; ++ gr_learn_attached = 1; ++out_error: ++ up(&gr_learn_user_sem); ++ return retval; ++ } ++ return 0; ++} ++ ++static int ++close_learn(struct inode *inode, struct file *file) ++{ ++ char *tmp; ++ ++ if (file->f_mode & FMODE_READ) { ++ down(&gr_learn_user_sem); ++ if (learn_buffer != NULL) { ++ spin_lock(&gr_learn_lock); ++ tmp = learn_buffer; ++ learn_buffer = NULL; ++ spin_unlock(&gr_learn_lock); ++ vfree(tmp); ++ } ++ if (learn_buffer_user != NULL) { ++ vfree(learn_buffer_user); ++ learn_buffer_user = NULL; ++ } ++ learn_buffer_len = 0; ++ learn_buffer_user_len = 0; ++ gr_learn_attached = 0; ++ up(&gr_learn_user_sem); ++ } ++ ++ return 0; ++} ++ ++const struct file_operations grsec_fops = { ++ .read = read_learn, ++ .write = write_grsec_handler, ++ .open = open_learn, ++ .release = close_learn, ++ .poll = poll_learn, ++}; +diff -urNp linux-2.6.31.1/grsecurity/gracl_res.c linux-2.6.31.1/grsecurity/gracl_res.c +--- linux-2.6.31.1/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/gracl_res.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,58 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/gracl.h> ++#include <linux/grinternal.h> ++ ++static const char *restab_log[] = { ++ [RLIMIT_CPU] = "RLIMIT_CPU", ++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE", ++ [RLIMIT_DATA] = "RLIMIT_DATA", ++ [RLIMIT_STACK] = "RLIMIT_STACK", ++ [RLIMIT_CORE] = "RLIMIT_CORE", ++ [RLIMIT_RSS] = "RLIMIT_RSS", ++ [RLIMIT_NPROC] = "RLIMIT_NPROC", ++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE", ++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK", ++ [RLIMIT_AS] = "RLIMIT_AS", ++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS", ++ [RLIMIT_SIGPENDING] = "RLIMIT_SIGPENDING", ++ [RLIMIT_MSGQUEUE] = "RLIMIT_MSGQUEUE", ++ [RLIMIT_NICE] = "RLIMIT_NICE", ++ [RLIMIT_RTPRIO] = "RLIMIT_RTPRIO", ++ [RLIMIT_RTTIME] = "RLIMIT_RTTIME", ++ [GR_CRASH_RES] = "RLIMIT_CRASH" ++}; ++ ++void ++gr_log_resource(const struct task_struct *task, ++ const int res, const unsigned long wanted, const int gt) ++{ ++ const struct cred *cred = __task_cred(task); ++ ++ if (res == RLIMIT_NPROC && ++ (cap_raised(cred->cap_effective, CAP_SYS_ADMIN) || ++ cap_raised(cred->cap_effective, CAP_SYS_RESOURCE))) ++ return; ++ else if (res == RLIMIT_MEMLOCK && ++ cap_raised(cred->cap_effective, CAP_IPC_LOCK)) ++ return; ++ else if (res == RLIMIT_NICE && cap_raised(cred->cap_effective, CAP_SYS_NICE)) ++ return; ++ ++ if (!gr_acl_is_enabled() && !grsec_resource_logging) ++ return; ++ ++ // not yet supported resource ++ if (!restab_log[res]) ++ return; ++ ++ preempt_disable(); ++ ++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) || ++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) && ++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY)) ++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur); ++ preempt_enable_no_resched(); ++ ++ return; ++} +diff -urNp linux-2.6.31.1/grsecurity/gracl_segv.c linux-2.6.31.1/grsecurity/gracl_segv.c +--- linux-2.6.31.1/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/gracl_segv.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,307 @@ ++#include <linux/kernel.h> ++#include <linux/mm.h> ++#include <asm/uaccess.h> ++#include <asm/errno.h> ++#include <asm/mman.h> ++#include <net/sock.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++#include <linux/net.h> ++#include <linux/in.h> ++#include <linux/smp_lock.h> ++#include <linux/slab.h> ++#include <linux/types.h> ++#include <linux/sched.h> ++#include <linux/timer.h> ++#include <linux/gracl.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++static struct crash_uid *uid_set; ++static unsigned short uid_used; ++static DEFINE_SPINLOCK(gr_uid_lock); ++extern rwlock_t gr_inode_lock; ++extern struct acl_subject_label * ++ lookup_acl_subj_label(const ino_t inode, const dev_t dev, ++ struct acl_role_label *role); ++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t); ++ ++int ++gr_init_uidset(void) ++{ ++ uid_set = ++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL); ++ uid_used = 0; ++ ++ return uid_set ? 1 : 0; ++} ++ ++void ++gr_free_uidset(void) ++{ ++ if (uid_set) ++ kfree(uid_set); ++ ++ return; ++} ++ ++int ++gr_find_uid(const uid_t uid) ++{ ++ struct crash_uid *tmp = uid_set; ++ uid_t buid; ++ int low = 0, high = uid_used - 1, mid; ++ ++ while (high >= low) { ++ mid = (low + high) >> 1; ++ buid = tmp[mid].uid; ++ if (buid == uid) ++ return mid; ++ if (buid > uid) ++ high = mid - 1; ++ if (buid < uid) ++ low = mid + 1; ++ } ++ ++ return -1; ++} ++ ++static __inline__ void ++gr_insertsort(void) ++{ ++ unsigned short i, j; ++ struct crash_uid index; ++ ++ for (i = 1; i < uid_used; i++) { ++ index = uid_set[i]; ++ j = i; ++ while ((j > 0) && uid_set[j - 1].uid > index.uid) { ++ uid_set[j] = uid_set[j - 1]; ++ j--; ++ } ++ uid_set[j] = index; ++ } ++ ++ return; ++} ++ ++static __inline__ void ++gr_insert_uid(const uid_t uid, const unsigned long expires) ++{ ++ int loc; ++ ++ if (uid_used == GR_UIDTABLE_MAX) ++ return; ++ ++ loc = gr_find_uid(uid); ++ ++ if (loc >= 0) { ++ uid_set[loc].expires = expires; ++ return; ++ } ++ ++ uid_set[uid_used].uid = uid; ++ uid_set[uid_used].expires = expires; ++ uid_used++; ++ ++ gr_insertsort(); ++ ++ return; ++} ++ ++void ++gr_remove_uid(const unsigned short loc) ++{ ++ unsigned short i; ++ ++ for (i = loc + 1; i < uid_used; i++) ++ uid_set[i - 1] = uid_set[i]; ++ ++ uid_used--; ++ ++ return; ++} ++ ++int ++gr_check_crash_uid(const uid_t uid) ++{ ++ int loc; ++ int ret = 0; ++ ++ if (unlikely(!gr_acl_is_enabled())) ++ return 0; ++ ++ spin_lock(&gr_uid_lock); ++ loc = gr_find_uid(uid); ++ ++ if (loc < 0) ++ goto out_unlock; ++ ++ if (time_before_eq(uid_set[loc].expires, get_seconds())) ++ gr_remove_uid(loc); ++ else ++ ret = 1; ++ ++out_unlock: ++ spin_unlock(&gr_uid_lock); ++ return ret; ++} ++ ++static __inline__ int ++proc_is_setxid(const struct cred *cred) ++{ ++ if (cred->uid != cred->euid || cred->uid != cred->suid || ++ cred->uid != cred->fsuid) ++ return 1; ++ if (cred->gid != cred->egid || cred->gid != cred->sgid || ++ cred->gid != cred->fsgid) ++ return 1; ++ ++ return 0; ++} ++static __inline__ int ++gr_fake_force_sig(int sig, struct task_struct *t) ++{ ++ unsigned long int flags; ++ int ret, blocked, ignored; ++ struct k_sigaction *action; ++ ++ spin_lock_irqsave(&t->sighand->siglock, flags); ++ action = &t->sighand->action[sig-1]; ++ ignored = action->sa.sa_handler == SIG_IGN; ++ blocked = sigismember(&t->blocked, sig); ++ if (blocked || ignored) { ++ action->sa.sa_handler = SIG_DFL; ++ if (blocked) { ++ sigdelset(&t->blocked, sig); ++ recalc_sigpending_and_wake(t); ++ } ++ } ++ if (action->sa.sa_handler == SIG_DFL) ++ t->signal->flags &= ~SIGNAL_UNKILLABLE; ++ ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t); ++ ++ spin_unlock_irqrestore(&t->sighand->siglock, flags); ++ ++ return ret; ++} ++ ++void ++gr_handle_crash(struct task_struct *task, const int sig) ++{ ++ struct acl_subject_label *curr; ++ struct acl_subject_label *curr2; ++ struct task_struct *tsk, *tsk2; ++ const struct cred *cred = __task_cred(task); ++ const struct cred *cred2; ++ ++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL) ++ return; ++ ++ if (unlikely(!gr_acl_is_enabled())) ++ return; ++ ++ curr = task->acl; ++ ++ if (!(curr->resmask & (1 << GR_CRASH_RES))) ++ return; ++ ++ if (time_before_eq(curr->expires, get_seconds())) { ++ curr->expires = 0; ++ curr->crashes = 0; ++ } ++ ++ curr->crashes++; ++ ++ if (!curr->expires) ++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max; ++ ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) && ++ time_after(curr->expires, get_seconds())) { ++ if (cred->uid && proc_is_setxid(cred)) { ++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max); ++ spin_lock(&gr_uid_lock); ++ gr_insert_uid(cred->uid, curr->expires); ++ spin_unlock(&gr_uid_lock); ++ curr->expires = 0; ++ curr->crashes = 0; ++ read_lock(&tasklist_lock); ++ do_each_thread(tsk2, tsk) { ++ cred2 = __task_cred(tsk); ++ if (tsk != task && cred2->uid == cred->uid) ++ gr_fake_force_sig(SIGKILL, tsk); ++ } while_each_thread(tsk2, tsk); ++ read_unlock(&tasklist_lock); ++ } else { ++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max); ++ read_lock(&tasklist_lock); ++ do_each_thread(tsk2, tsk) { ++ if (likely(tsk != task)) { ++ curr2 = tsk->acl; ++ ++ if (curr2->device == curr->device && ++ curr2->inode == curr->inode) ++ gr_fake_force_sig(SIGKILL, tsk); ++ } ++ } while_each_thread(tsk2, tsk); ++ read_unlock(&tasklist_lock); ++ } ++ } ++ ++ return; ++} ++ ++int ++gr_check_crash_exec(const struct file *filp) ++{ ++ struct acl_subject_label *curr; ++ ++ if (unlikely(!gr_acl_is_enabled())) ++ return 0; ++ ++ read_lock(&gr_inode_lock); ++ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino, ++ filp->f_path.dentry->d_inode->i_sb->s_dev, ++ current->role); ++ read_unlock(&gr_inode_lock); ++ ++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) || ++ (!curr->crashes && !curr->expires)) ++ return 0; ++ ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) && ++ time_after(curr->expires, get_seconds())) ++ return 1; ++ else if (time_before_eq(curr->expires, get_seconds())) { ++ curr->crashes = 0; ++ curr->expires = 0; ++ } ++ ++ return 0; ++} ++ ++void ++gr_handle_alertkill(struct task_struct *task) ++{ ++ struct acl_subject_label *curracl; ++ __u32 curr_ip; ++ struct task_struct *p, *p2; ++ ++ if (unlikely(!gr_acl_is_enabled())) ++ return; ++ ++ curracl = task->acl; ++ curr_ip = task->signal->curr_ip; ++ ++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) { ++ read_lock(&tasklist_lock); ++ do_each_thread(p2, p) { ++ if (p->signal->curr_ip == curr_ip) ++ gr_fake_force_sig(SIGKILL, p); ++ } while_each_thread(p2, p); ++ read_unlock(&tasklist_lock); ++ } else if (curracl->mode & GR_KILLPROC) ++ gr_fake_force_sig(SIGKILL, task); ++ ++ return; ++} +diff -urNp linux-2.6.31.1/grsecurity/gracl_shm.c linux-2.6.31.1/grsecurity/gracl_shm.c +--- linux-2.6.31.1/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/gracl_shm.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,37 @@ ++#include <linux/kernel.h> ++#include <linux/mm.h> ++#include <linux/sched.h> ++#include <linux/file.h> ++#include <linux/ipc.h> ++#include <linux/gracl.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++int ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, ++ const time_t shm_createtime, const uid_t cuid, const int shmid) ++{ ++ struct task_struct *task; ++ ++ if (!gr_acl_is_enabled()) ++ return 1; ++ ++ read_lock(&tasklist_lock); ++ ++ task = find_task_by_vpid(shm_cprid); ++ ++ if (unlikely(!task)) ++ task = find_task_by_vpid(shm_lapid); ++ ++ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) || ++ (task->pid == shm_lapid)) && ++ (task->acl->mode & GR_PROTSHM) && ++ (task->acl != current->acl))) { ++ read_unlock(&tasklist_lock); ++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid); ++ return 0; ++ } ++ read_unlock(&tasklist_lock); ++ ++ return 1; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_chdir.c linux-2.6.31.1/grsecurity/grsec_chdir.c +--- linux-2.6.31.1/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_chdir.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,19 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/fs.h> ++#include <linux/file.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++void ++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR ++ if ((grsec_enable_chdir && grsec_enable_group && ++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir && ++ !grsec_enable_group)) { ++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt); ++ } ++#endif ++ return; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_chroot.c linux-2.6.31.1/grsecurity/grsec_chroot.c +--- linux-2.6.31.1/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_chroot.c 2009-10-01 21:52:18.000000000 -0400 +@@ -0,0 +1,348 @@ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++#include <linux/mount.h> ++#include <linux/types.h> ++#include <linux/pid_namespace.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++int ++gr_handle_chroot_unix(const pid_t pid) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX ++ struct pid *spid = NULL; ++ ++ if (unlikely(!grsec_enable_chroot_unix)) ++ return 1; ++ ++ if (likely(!proc_is_chrooted(current))) ++ return 1; ++ ++ read_lock(&tasklist_lock); ++ ++ spid = find_vpid(pid); ++ if (spid) { ++ struct task_struct *p; ++ p = pid_task(spid, PIDTYPE_PID); ++ task_lock(p); ++ if (unlikely(!have_same_root(current, p))) { ++ task_unlock(p); ++ read_unlock(&tasklist_lock); ++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG); ++ return 0; ++ } ++ task_unlock(p); ++ } ++ read_unlock(&tasklist_lock); ++#endif ++ return 1; ++} ++ ++int ++gr_handle_chroot_nice(void) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE ++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) { ++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG); ++ return -EPERM; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE ++ if (grsec_enable_chroot_nice && (niceval < task_nice(p)) ++ && proc_is_chrooted(current)) { ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid); ++ return -EACCES; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_chroot_rawio(const struct inode *inode) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS ++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) && ++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO)) ++ return 1; ++#endif ++ return 0; ++} ++ ++int ++gr_pid_is_chrooted(struct task_struct *p) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK ++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL) ++ return 0; ++ ++ task_lock(p); ++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) || ++ !have_same_root(current, p)) { ++ task_unlock(p); ++ return 1; ++ } ++ task_unlock(p); ++#endif ++ return 0; ++} ++ ++EXPORT_SYMBOL(gr_pid_is_chrooted); ++ ++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR) ++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt) ++{ ++ struct dentry *dentry = (struct dentry *)u_dentry; ++ struct vfsmount *mnt = (struct vfsmount *)u_mnt; ++ struct dentry *realroot; ++ struct vfsmount *realrootmnt; ++ struct dentry *currentroot; ++ struct vfsmount *currentmnt; ++ struct task_struct *reaper = &init_task; ++ int ret = 1; ++ ++ read_lock(&reaper->fs->lock); ++ realrootmnt = mntget(reaper->fs->root.mnt); ++ realroot = dget(reaper->fs->root.dentry); ++ read_unlock(&reaper->fs->lock); ++ ++ read_lock(¤t->fs->lock); ++ currentmnt = mntget(current->fs->root.mnt); ++ currentroot = dget(current->fs->root.dentry); ++ read_unlock(¤t->fs->lock); ++ ++ spin_lock(&dcache_lock); ++ for (;;) { ++ if (unlikely((dentry == realroot && mnt == realrootmnt) ++ || (dentry == currentroot && mnt == currentmnt))) ++ break; ++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) { ++ if (mnt->mnt_parent == mnt) ++ break; ++ dentry = mnt->mnt_mountpoint; ++ mnt = mnt->mnt_parent; ++ continue; ++ } ++ dentry = dentry->d_parent; ++ } ++ spin_unlock(&dcache_lock); ++ ++ dput(currentroot); ++ mntput(currentmnt); ++ ++ /* access is outside of chroot */ ++ if (dentry == realroot && mnt == realrootmnt) ++ ret = 0; ++ ++ dput(realroot); ++ mntput(realrootmnt); ++ return ret; ++} ++#endif ++ ++int ++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR ++ if (!grsec_enable_chroot_fchdir) ++ return 1; ++ ++ if (!proc_is_chrooted(current)) ++ return 1; ++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) { ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt); ++ return 0; ++ } ++#endif ++ return 1; ++} ++ ++int ++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid, ++ const time_t shm_createtime) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT ++ struct pid *pid = NULL; ++ time_t starttime; ++ ++ if (unlikely(!grsec_enable_chroot_shmat)) ++ return 1; ++ ++ if (likely(!proc_is_chrooted(current))) ++ return 1; ++ ++ read_lock(&tasklist_lock); ++ ++ pid = find_vpid(shm_cprid); ++ if (pid) { ++ struct task_struct *p; ++ p = pid_task(pid, PIDTYPE_PID); ++ task_lock(p); ++ starttime = p->start_time.tv_sec; ++ if (unlikely(!have_same_root(current, p) && ++ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) { ++ task_unlock(p); ++ read_unlock(&tasklist_lock); ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG); ++ return 0; ++ } ++ task_unlock(p); ++ } else { ++ pid = find_vpid(shm_lapid); ++ if (pid) { ++ struct task_struct *p; ++ p = pid_task(pid, PIDTYPE_PID); ++ task_lock(p); ++ if (unlikely(!have_same_root(current, p))) { ++ task_unlock(p); ++ read_unlock(&tasklist_lock); ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG); ++ return 0; ++ } ++ task_unlock(p); ++ } ++ } ++ ++ read_unlock(&tasklist_lock); ++#endif ++ return 1; ++} ++ ++void ++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG ++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current)) ++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt); ++#endif ++ return; ++} ++ ++int ++gr_handle_chroot_mknod(const struct dentry *dentry, ++ const struct vfsmount *mnt, const int mode) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD ++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && ++ proc_is_chrooted(current)) { ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt); ++ return -EPERM; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_chroot_mount(const struct dentry *dentry, ++ const struct vfsmount *mnt, const char *dev_name) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT ++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) { ++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt); ++ return -EPERM; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_chroot_pivot(void) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT ++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) { ++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG); ++ return -EPERM; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE ++ if (grsec_enable_chroot_double && proc_is_chrooted(current) && ++ !gr_is_outside_chroot(dentry, mnt)) { ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt); ++ return -EPERM; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_chroot_caps(struct path *path) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS ++ if (grsec_enable_chroot_caps && current->pid > 1 && current->fs != NULL && ++ (init_task.fs->root.dentry != path->dentry) && ++ (current->nsproxy->mnt_ns->root->mnt_root != path->dentry)) { ++ ++ kernel_cap_t chroot_caps = GR_CHROOT_CAPS; ++ const struct cred *old = current_cred(); ++ struct cred *new = prepare_creds(); ++ if (new == NULL) ++ return 1; ++ ++ new->cap_permitted = cap_drop(old->cap_permitted, ++ chroot_caps); ++ new->cap_inheritable = cap_drop(old->cap_inheritable, ++ chroot_caps); ++ new->cap_effective = cap_drop(old->cap_effective, ++ chroot_caps); ++ ++ commit_creds(new); ++ ++ return 0; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_chroot_sysctl(const int op) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL ++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current) ++ && (op & MAY_WRITE)) ++ return -EACCES; ++#endif ++ return 0; ++} ++ ++void ++gr_handle_chroot_chdir(struct path *path) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR ++ if (grsec_enable_chroot_chdir) ++ set_fs_pwd(current->fs, path); ++#endif ++ return; ++} ++ ++int ++gr_handle_chroot_chmod(const struct dentry *dentry, ++ const struct vfsmount *mnt, const int mode) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD ++ if (grsec_enable_chroot_chmod && ++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) && ++ proc_is_chrooted(current)) { ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt); ++ return -EPERM; ++ } ++#endif ++ return 0; ++} ++ ++#ifdef CONFIG_SECURITY ++EXPORT_SYMBOL(gr_handle_chroot_caps); ++#endif +diff -urNp linux-2.6.31.1/grsecurity/grsec_disabled.c linux-2.6.31.1/grsecurity/grsec_disabled.c +--- linux-2.6.31.1/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_disabled.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,426 @@ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++#include <linux/kdev_t.h> ++#include <linux/net.h> ++#include <linux/in.h> ++#include <linux/ip.h> ++#include <linux/skbuff.h> ++#include <linux/sysctl.h> ++ ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS ++void ++pax_set_initial_flags(struct linux_binprm *bprm) ++{ ++ return; ++} ++#endif ++ ++#ifdef CONFIG_SYSCTL ++__u32 ++gr_handle_sysctl(const struct ctl_table * table, const int op) ++{ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_TASKSTATS ++int gr_is_taskstats_denied(int pid) ++{ ++ return 0; ++} ++#endif ++ ++int ++gr_acl_is_enabled(void) ++{ ++ return 0; ++} ++ ++int ++gr_handle_rawio(const struct inode *inode) ++{ ++ return 0; ++} ++ ++void ++gr_acl_handle_psacct(struct task_struct *task, const long code) ++{ ++ return; ++} ++ ++int ++gr_handle_ptrace(struct task_struct *task, const long request) ++{ ++ return 0; ++} ++ ++int ++gr_handle_proc_ptrace(struct task_struct *task) ++{ ++ return 0; ++} ++ ++void ++gr_learn_resource(const struct task_struct *task, ++ const int res, const unsigned long wanted, const int gt) ++{ ++ return; ++} ++ ++int ++gr_set_acls(const int type) ++{ ++ return 0; ++} ++ ++int ++gr_check_hidden_task(const struct task_struct *tsk) ++{ ++ return 0; ++} ++ ++int ++gr_check_protected_task(const struct task_struct *task) ++{ ++ return 0; ++} ++ ++void ++gr_copy_label(struct task_struct *tsk) ++{ ++ return; ++} ++ ++void ++gr_set_pax_flags(struct task_struct *task) ++{ ++ return; ++} ++ ++int ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt, ++ const int unsafe_share) ++{ ++ return 0; ++} ++ ++void ++gr_handle_delete(const ino_t ino, const dev_t dev) ++{ ++ return; ++} ++ ++void ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++ return; ++} ++ ++void ++gr_handle_crash(struct task_struct *task, const int sig) ++{ ++ return; ++} ++ ++int ++gr_check_crash_exec(const struct file *filp) ++{ ++ return 0; ++} ++ ++int ++gr_check_crash_uid(const uid_t uid) ++{ ++ return 0; ++} ++ ++void ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir, ++ struct dentry *old_dentry, ++ struct dentry *new_dentry, ++ struct vfsmount *mnt, const __u8 replace) ++{ ++ return; ++} ++ ++int ++gr_search_socket(const int family, const int type, const int protocol) ++{ ++ return 1; ++} ++ ++int ++gr_search_connectbind(const int mode, const struct socket *sock, ++ const struct sockaddr_in *addr) ++{ ++ return 0; ++} ++ ++int ++gr_is_capable(const int cap) ++{ ++ return 1; ++} ++ ++int ++gr_is_capable_nolog(const int cap) ++{ ++ return 1; ++} ++ ++void ++gr_handle_alertkill(struct task_struct *task) ++{ ++ return; ++} ++ ++__u32 ++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_hidden_file(const struct dentry * dentry, ++ const struct vfsmount * mnt) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, ++ const int fmode) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt) ++{ ++ return 1; ++} ++ ++int ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot, ++ unsigned int *vm_flags) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_truncate(const struct dentry * dentry, ++ const struct vfsmount * mnt) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_access(const struct dentry * dentry, ++ const struct vfsmount * mnt, const int fmode) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt, ++ mode_t mode) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt, ++ mode_t mode) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt) ++{ ++ return 1; ++} ++ ++void ++grsecurity_init(void) ++{ ++ return; ++} ++ ++__u32 ++gr_acl_handle_mknod(const struct dentry * new_dentry, ++ const struct dentry * parent_dentry, ++ const struct vfsmount * parent_mnt, ++ const int mode) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_mkdir(const struct dentry * new_dentry, ++ const struct dentry * parent_dentry, ++ const struct vfsmount * parent_mnt) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_symlink(const struct dentry * new_dentry, ++ const struct dentry * parent_dentry, ++ const struct vfsmount * parent_mnt, const char *from) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_link(const struct dentry * new_dentry, ++ const struct dentry * parent_dentry, ++ const struct vfsmount * parent_mnt, ++ const struct dentry * old_dentry, ++ const struct vfsmount * old_mnt, const char *to) ++{ ++ return 1; ++} ++ ++int ++gr_acl_handle_rename(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ const struct dentry *old_dentry, ++ const struct inode *old_parent_inode, ++ const struct vfsmount *old_mnt, const char *newname) ++{ ++ return 0; ++} ++ ++int ++gr_acl_handle_filldir(const struct file *file, const char *name, ++ const int namelen, const ino_t ino) ++{ ++ return 1; ++} ++ ++int ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, ++ const time_t shm_createtime, const uid_t cuid, const int shmid) ++{ ++ return 1; ++} ++ ++int ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr) ++{ ++ return 0; ++} ++ ++int ++gr_search_accept(const struct socket *sock) ++{ ++ return 0; ++} ++ ++int ++gr_search_listen(const struct socket *sock) ++{ ++ return 0; ++} ++ ++int ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr) ++{ ++ return 0; ++} ++ ++__u32 ++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt) ++{ ++ return 1; ++} ++ ++__u32 ++gr_acl_handle_creat(const struct dentry * dentry, ++ const struct dentry * p_dentry, ++ const struct vfsmount * p_mnt, const int fmode, ++ const int imode) ++{ ++ return 1; ++} ++ ++void ++gr_acl_handle_exit(void) ++{ ++ return; ++} ++ ++int ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot) ++{ ++ return 1; ++} ++ ++void ++gr_set_role_label(const uid_t uid, const gid_t gid) ++{ ++ return; ++} ++ ++int ++gr_acl_handle_procpidmem(const struct task_struct *task) ++{ ++ return 0; ++} ++ ++int ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb) ++{ ++ return 0; ++} ++ ++int ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr) ++{ ++ return 0; ++} ++ ++void ++gr_set_kernel_label(struct task_struct *task) ++{ ++ return; ++} ++ ++int ++gr_check_user_change(int real, int effective, int fs) ++{ ++ return 0; ++} ++ ++int ++gr_check_group_change(int real, int effective, int fs) ++{ ++ return 0; ++} ++ ++ ++EXPORT_SYMBOL(gr_is_capable); ++EXPORT_SYMBOL(gr_is_capable_nolog); ++EXPORT_SYMBOL(gr_learn_resource); ++EXPORT_SYMBOL(gr_set_kernel_label); ++#ifdef CONFIG_SECURITY ++EXPORT_SYMBOL(gr_check_user_change); ++EXPORT_SYMBOL(gr_check_group_change); ++#endif +diff -urNp linux-2.6.31.1/grsecurity/grsec_exec.c linux-2.6.31.1/grsecurity/grsec_exec.c +--- linux-2.6.31.1/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_exec.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,89 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/file.h> ++#include <linux/binfmts.h> ++#include <linux/smp_lock.h> ++#include <linux/fs.h> ++#include <linux/types.h> ++#include <linux/grdefs.h> ++#include <linux/grinternal.h> ++#include <linux/capability.h> ++ ++#include <asm/uaccess.h> ++ ++#ifdef CONFIG_GRKERNSEC_EXECLOG ++static char gr_exec_arg_buf[132]; ++static DECLARE_MUTEX(gr_exec_arg_sem); ++#endif ++ ++int ++gr_handle_nproc(void) ++{ ++#ifdef CONFIG_GRKERNSEC_EXECVE ++ const struct cred *cred = current_cred(); ++ if (grsec_enable_execve && cred->user && ++ (atomic_read(&cred->user->processes) > ++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) && ++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) { ++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG); ++ return -EAGAIN; ++ } ++#endif ++ return 0; ++} ++ ++void ++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv) ++{ ++#ifdef CONFIG_GRKERNSEC_EXECLOG ++ char *grarg = gr_exec_arg_buf; ++ unsigned int i, x, execlen = 0; ++ char c; ++ ++ if (!((grsec_enable_execlog && grsec_enable_group && ++ in_group_p(grsec_audit_gid)) ++ || (grsec_enable_execlog && !grsec_enable_group))) ++ return; ++ ++ down(&gr_exec_arg_sem); ++ memset(grarg, 0, sizeof(gr_exec_arg_buf)); ++ ++ if (unlikely(argv == NULL)) ++ goto log; ++ ++ for (i = 0; i < bprm->argc && execlen < 128; i++) { ++ const char __user *p; ++ unsigned int len; ++ ++ if (copy_from_user(&p, argv + i, sizeof(p))) ++ goto log; ++ if (!p) ++ goto log; ++ len = strnlen_user(p, 128 - execlen); ++ if (len > 128 - execlen) ++ len = 128 - execlen; ++ else if (len > 0) ++ len--; ++ if (copy_from_user(grarg + execlen, p, len)) ++ goto log; ++ ++ /* rewrite unprintable characters */ ++ for (x = 0; x < len; x++) { ++ c = *(grarg + execlen + x); ++ if (c < 32 || c > 126) ++ *(grarg + execlen + x) = ' '; ++ } ++ ++ execlen += len; ++ *(grarg + execlen) = ' '; ++ *(grarg + execlen + 1) = '\0'; ++ execlen++; ++ } ++ ++ log: ++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry, ++ bprm->file->f_path.mnt, grarg); ++ up(&gr_exec_arg_sem); ++#endif ++ return; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_fifo.c linux-2.6.31.1/grsecurity/grsec_fifo.c +--- linux-2.6.31.1/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_fifo.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,24 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/fs.h> ++#include <linux/file.h> ++#include <linux/grinternal.h> ++ ++int ++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt, ++ const struct dentry *dir, const int flag, const int acc_mode) ++{ ++#ifdef CONFIG_GRKERNSEC_FIFO ++ const struct cred *cred = current_cred(); ++ ++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) && ++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) && ++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) && ++ (cred->fsuid != dentry->d_inode->i_uid)) { ++ if (!generic_permission(dentry->d_inode, acc_mode, NULL)) ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid); ++ return -EACCES; ++ } ++#endif ++ return 0; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_fork.c linux-2.6.31.1/grsecurity/grsec_fork.c +--- linux-2.6.31.1/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_fork.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,15 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++#include <linux/errno.h> ++ ++void ++gr_log_forkfail(const int retval) ++{ ++#ifdef CONFIG_GRKERNSEC_FORKFAIL ++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR) ++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval); ++#endif ++ return; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_init.c linux-2.6.31.1/grsecurity/grsec_init.c +--- linux-2.6.31.1/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_init.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,230 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/mm.h> ++#include <linux/smp_lock.h> ++#include <linux/gracl.h> ++#include <linux/slab.h> ++#include <linux/vmalloc.h> ++#include <linux/percpu.h> ++ ++int grsec_enable_link; ++int grsec_enable_dmesg; ++int grsec_enable_harden_ptrace; ++int grsec_enable_fifo; ++int grsec_enable_execve; ++int grsec_enable_execlog; ++int grsec_enable_signal; ++int grsec_enable_forkfail; ++int grsec_enable_time; ++int grsec_enable_audit_textrel; ++int grsec_enable_group; ++int grsec_audit_gid; ++int grsec_enable_chdir; ++int grsec_enable_mount; ++int grsec_enable_chroot_findtask; ++int grsec_enable_chroot_mount; ++int grsec_enable_chroot_shmat; ++int grsec_enable_chroot_fchdir; ++int grsec_enable_chroot_double; ++int grsec_enable_chroot_pivot; ++int grsec_enable_chroot_chdir; ++int grsec_enable_chroot_chmod; ++int grsec_enable_chroot_mknod; ++int grsec_enable_chroot_nice; ++int grsec_enable_chroot_execlog; ++int grsec_enable_chroot_caps; ++int grsec_enable_chroot_sysctl; ++int grsec_enable_chroot_unix; ++int grsec_enable_tpe; ++int grsec_tpe_gid; ++int grsec_enable_tpe_all; ++int grsec_enable_socket_all; ++int grsec_socket_all_gid; ++int grsec_enable_socket_client; ++int grsec_socket_client_gid; ++int grsec_enable_socket_server; ++int grsec_socket_server_gid; ++int grsec_resource_logging; ++int grsec_lock; ++ ++DEFINE_SPINLOCK(grsec_alert_lock); ++unsigned long grsec_alert_wtime = 0; ++unsigned long grsec_alert_fyet = 0; ++ ++DEFINE_SPINLOCK(grsec_audit_lock); ++ ++DEFINE_RWLOCK(grsec_exec_file_lock); ++ ++char *gr_shared_page[4]; ++ ++char *gr_alert_log_fmt; ++char *gr_audit_log_fmt; ++char *gr_alert_log_buf; ++char *gr_audit_log_buf; ++ ++extern struct gr_arg *gr_usermode; ++extern unsigned char *gr_system_salt; ++extern unsigned char *gr_system_sum; ++ ++void __init ++grsecurity_init(void) ++{ ++ int j; ++ /* create the per-cpu shared pages */ ++ ++#ifdef CONFIG_X86 ++ memset((char *)(0x41a + PAGE_OFFSET), 0, 36); ++#endif ++ ++ for (j = 0; j < 4; j++) { ++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(unsigned long long)); ++ if (gr_shared_page[j] == NULL) { ++ panic("Unable to allocate grsecurity shared page"); ++ return; ++ } ++ } ++ ++ /* allocate log buffers */ ++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL); ++ if (!gr_alert_log_fmt) { ++ panic("Unable to allocate grsecurity alert log format buffer"); ++ return; ++ } ++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL); ++ if (!gr_audit_log_fmt) { ++ panic("Unable to allocate grsecurity audit log format buffer"); ++ return; ++ } ++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL); ++ if (!gr_alert_log_buf) { ++ panic("Unable to allocate grsecurity alert log buffer"); ++ return; ++ } ++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL); ++ if (!gr_audit_log_buf) { ++ panic("Unable to allocate grsecurity audit log buffer"); ++ return; ++ } ++ ++ /* allocate memory for authentication structure */ ++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL); ++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL); ++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL); ++ ++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) { ++ panic("Unable to allocate grsecurity authentication structure"); ++ return; ++ } ++ ++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON) ++#ifndef CONFIG_GRKERNSEC_SYSCTL ++ grsec_lock = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL ++ grsec_enable_audit_textrel = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP ++ grsec_enable_group = 1; ++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID; ++#endif ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR ++ grsec_enable_chdir = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE ++ grsec_enable_harden_ptrace = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT ++ grsec_enable_mount = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_LINK ++ grsec_enable_link = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_DMESG ++ grsec_enable_dmesg = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_FIFO ++ grsec_enable_fifo = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_EXECVE ++ grsec_enable_execve = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_EXECLOG ++ grsec_enable_execlog = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_SIGNAL ++ grsec_enable_signal = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_FORKFAIL ++ grsec_enable_forkfail = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_TIME ++ grsec_enable_time = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_RESLOG ++ grsec_resource_logging = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK ++ grsec_enable_chroot_findtask = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX ++ grsec_enable_chroot_unix = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT ++ grsec_enable_chroot_mount = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR ++ grsec_enable_chroot_fchdir = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT ++ grsec_enable_chroot_shmat = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE ++ grsec_enable_chroot_double = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT ++ grsec_enable_chroot_pivot = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR ++ grsec_enable_chroot_chdir = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD ++ grsec_enable_chroot_chmod = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD ++ grsec_enable_chroot_mknod = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE ++ grsec_enable_chroot_nice = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG ++ grsec_enable_chroot_execlog = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS ++ grsec_enable_chroot_caps = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL ++ grsec_enable_chroot_sysctl = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_TPE ++ grsec_enable_tpe = 1; ++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID; ++#ifdef CONFIG_GRKERNSEC_TPE_ALL ++ grsec_enable_tpe_all = 1; ++#endif ++#endif ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL ++ grsec_enable_socket_all = 1; ++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID; ++#endif ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT ++ grsec_enable_socket_client = 1; ++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID; ++#endif ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER ++ grsec_enable_socket_server = 1; ++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID; ++#endif ++#endif ++ ++ return; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_link.c linux-2.6.31.1/grsecurity/grsec_link.c +--- linux-2.6.31.1/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_link.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,43 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/fs.h> ++#include <linux/file.h> ++#include <linux/grinternal.h> ++ ++int ++gr_handle_follow_link(const struct inode *parent, ++ const struct inode *inode, ++ const struct dentry *dentry, const struct vfsmount *mnt) ++{ ++#ifdef CONFIG_GRKERNSEC_LINK ++ const struct cred *cred = current_cred(); ++ ++ if (grsec_enable_link && S_ISLNK(inode->i_mode) && ++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) && ++ (parent->i_mode & S_IWOTH) && (cred->fsuid != inode->i_uid)) { ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid); ++ return -EACCES; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_hardlink(const struct dentry *dentry, ++ const struct vfsmount *mnt, ++ struct inode *inode, const int mode, const char *to) ++{ ++#ifdef CONFIG_GRKERNSEC_LINK ++ const struct cred *cred = current_cred(); ++ ++ if (grsec_enable_link && cred->fsuid != inode->i_uid && ++ (!S_ISREG(mode) || (mode & S_ISUID) || ++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) || ++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) && ++ !capable(CAP_FOWNER) && cred->uid) { ++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to); ++ return -EPERM; ++ } ++#endif ++ return 0; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_log.c linux-2.6.31.1/grsecurity/grsec_log.c +--- linux-2.6.31.1/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_log.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,294 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/file.h> ++#include <linux/tty.h> ++#include <linux/fs.h> ++#include <linux/grinternal.h> ++ ++#define BEGIN_LOCKS(x) \ ++ read_lock(&tasklist_lock); \ ++ read_lock(&grsec_exec_file_lock); \ ++ if (x != GR_DO_AUDIT) \ ++ spin_lock(&grsec_alert_lock); \ ++ else \ ++ spin_lock(&grsec_audit_lock) ++ ++#define END_LOCKS(x) \ ++ if (x != GR_DO_AUDIT) \ ++ spin_unlock(&grsec_alert_lock); \ ++ else \ ++ spin_unlock(&grsec_audit_lock); \ ++ read_unlock(&grsec_exec_file_lock); \ ++ read_unlock(&tasklist_lock); \ ++ if (x == GR_DONT_AUDIT) \ ++ gr_handle_alertkill(current) ++ ++enum { ++ FLOODING, ++ NO_FLOODING ++}; ++ ++extern char *gr_alert_log_fmt; ++extern char *gr_audit_log_fmt; ++extern char *gr_alert_log_buf; ++extern char *gr_audit_log_buf; ++ ++static int gr_log_start(int audit) ++{ ++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT; ++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt; ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; ++ ++ if (audit == GR_DO_AUDIT) ++ goto set_fmt; ++ ++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { ++ grsec_alert_wtime = jiffies; ++ grsec_alert_fyet = 0; ++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { ++ grsec_alert_fyet++; ++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { ++ grsec_alert_wtime = jiffies; ++ grsec_alert_fyet++; ++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); ++ return FLOODING; ++ } else return FLOODING; ++ ++set_fmt: ++ memset(buf, 0, PAGE_SIZE); ++ if (current->signal->curr_ip && gr_acl_is_enabled()) { ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) "); ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename); ++ } else if (current->signal->curr_ip) { ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: "); ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip)); ++ } else if (gr_acl_is_enabled()) { ++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) "); ++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename); ++ } else { ++ sprintf(fmt, "%s%s", loglevel, "grsec: "); ++ strcpy(buf, fmt); ++ } ++ ++ return NO_FLOODING; ++} ++ ++static void gr_log_middle(int audit, const char *msg, va_list ap) ++ __attribute__ ((format (printf, 2, 0))); ++ ++static void gr_log_middle(int audit, const char *msg, va_list ap) ++{ ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; ++ unsigned int len = strlen(buf); ++ ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap); ++ ++ return; ++} ++ ++static void gr_log_middle_varargs(int audit, const char *msg, ...) ++ __attribute__ ((format (printf, 2, 3))); ++ ++static void gr_log_middle_varargs(int audit, const char *msg, ...) ++{ ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; ++ unsigned int len = strlen(buf); ++ va_list ap; ++ ++ va_start(ap, msg); ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap); ++ va_end(ap); ++ ++ return; ++} ++ ++static void gr_log_end(int audit) ++{ ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; ++ unsigned int len = strlen(buf); ++ ++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current, current_cred(), __task_cred(current->parent))); ++ printk("%s\n", buf); ++ ++ return; ++} ++ ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...) ++{ ++ int logtype; ++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied"; ++ char *str1, *str2, *str3; ++ void *voidptr; ++ int num1, num2; ++ unsigned long ulong1, ulong2; ++ struct dentry *dentry; ++ struct vfsmount *mnt; ++ struct file *file; ++ struct task_struct *task; ++ const struct cred *cred, *pcred; ++ va_list ap; ++ ++ BEGIN_LOCKS(audit); ++ logtype = gr_log_start(audit); ++ if (logtype == FLOODING) { ++ END_LOCKS(audit); ++ return; ++ } ++ va_start(ap, argtypes); ++ switch (argtypes) { ++ case GR_TTYSNIFF: ++ task = va_arg(ap, struct task_struct *); ++ gr_log_middle_varargs(audit, msg, NIPQUAD(task->signal->curr_ip), gr_task_fullpath0(task), task->comm, task->pid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid); ++ break; ++ case GR_SYSCTL_HIDDEN: ++ str1 = va_arg(ap, char *); ++ gr_log_middle_varargs(audit, msg, result, str1); ++ break; ++ case GR_RBAC: ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt)); ++ break; ++ case GR_RBAC_STR: ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ str1 = va_arg(ap, char *); ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1); ++ break; ++ case GR_STR_RBAC: ++ str1 = va_arg(ap, char *); ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt)); ++ break; ++ case GR_RBAC_MODE2: ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ str1 = va_arg(ap, char *); ++ str2 = va_arg(ap, char *); ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2); ++ break; ++ case GR_RBAC_MODE3: ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ str1 = va_arg(ap, char *); ++ str2 = va_arg(ap, char *); ++ str3 = va_arg(ap, char *); ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3); ++ break; ++ case GR_FILENAME: ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt)); ++ break; ++ case GR_STR_FILENAME: ++ str1 = va_arg(ap, char *); ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt)); ++ break; ++ case GR_FILENAME_STR: ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ str1 = va_arg(ap, char *); ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1); ++ break; ++ case GR_FILENAME_TWO_INT: ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ num1 = va_arg(ap, int); ++ num2 = va_arg(ap, int); ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2); ++ break; ++ case GR_FILENAME_TWO_INT_STR: ++ dentry = va_arg(ap, struct dentry *); ++ mnt = va_arg(ap, struct vfsmount *); ++ num1 = va_arg(ap, int); ++ num2 = va_arg(ap, int); ++ str1 = va_arg(ap, char *); ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1); ++ break; ++ case GR_TEXTREL: ++ file = va_arg(ap, struct file *); ++ ulong1 = va_arg(ap, unsigned long); ++ ulong2 = va_arg(ap, unsigned long); ++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2); ++ break; ++ case GR_PTRACE: ++ task = va_arg(ap, struct task_struct *); ++ gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_path.dentry, task->exec_file->f_path.mnt) : "(none)", task->comm, task->pid); ++ break; ++ case GR_RESOURCE: ++ task = va_arg(ap, struct task_struct *); ++ cred = __task_cred(task); ++ pcred = __task_cred(task->parent); ++ ulong1 = va_arg(ap, unsigned long); ++ str1 = va_arg(ap, char *); ++ ulong2 = va_arg(ap, unsigned long); ++ gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid); ++ break; ++ case GR_CAP: ++ task = va_arg(ap, struct task_struct *); ++ cred = __task_cred(task); ++ pcred = __task_cred(task->parent); ++ str1 = va_arg(ap, char *); ++ gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid); ++ break; ++ case GR_SIG: ++ str1 = va_arg(ap, char *); ++ voidptr = va_arg(ap, void *); ++ gr_log_middle_varargs(audit, msg, str1, voidptr); ++ break; ++ case GR_SIG2: ++ task = va_arg(ap, struct task_struct *); ++ cred = __task_cred(task); ++ pcred = __task_cred(task->parent); ++ num1 = va_arg(ap, int); ++ gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid); ++ break; ++ case GR_CRASH1: ++ task = va_arg(ap, struct task_struct *); ++ cred = __task_cred(task); ++ pcred = __task_cred(task->parent); ++ ulong1 = va_arg(ap, unsigned long); ++ gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid, cred->uid, ulong1); ++ break; ++ case GR_CRASH2: ++ task = va_arg(ap, struct task_struct *); ++ cred = __task_cred(task); ++ pcred = __task_cred(task->parent); ++ ulong1 = va_arg(ap, unsigned long); ++ gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, cred->uid, cred->euid, cred->gid, cred->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, pcred->uid, pcred->euid, pcred->gid, pcred->egid, ulong1); ++ break; ++ case GR_PSACCT: ++ { ++ unsigned int wday, cday; ++ __u8 whr, chr; ++ __u8 wmin, cmin; ++ __u8 wsec, csec; ++ char cur_tty[64] = { 0 }; ++ char parent_tty[64] = { 0 }; ++ ++ task = va_arg(ap, struct task_struct *); ++ wday = va_arg(ap, unsigned int); ++ cday = va_arg(ap, unsigned int); ++ whr = va_arg(ap, int); ++ chr = va_arg(ap, int); ++ wmin = va_arg(ap, int); ++ cmin = va_arg(ap, int); ++ wsec = va_arg(ap, int); ++ csec = va_arg(ap, int); ++ ulong1 = va_arg(ap, unsigned long); ++ cred = __task_cred(task); ++ pcred = __task_cred(task->parent); ++ ++ gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, NIPQUAD(task->signal->curr_ip), tty_name(task->signal->tty, cur_tty), cred->uid, cred->euid, cred->gid, cred->egid, wday, whr, wmin, wsec, cday, chr, cmin, csec, (task->flags & PF_SIGNALED) ? "killed by signal" : "exited", ulong1, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, NIPQUAD(task->parent->signal->curr_ip), tty_name(task->parent->signal->tty, parent_tty), pcred->uid, pcred->euid, pcred->gid, pcred->egid); ++ } ++ break; ++ default: ++ gr_log_middle(audit, msg, ap); ++ } ++ va_end(ap); ++ gr_log_end(audit); ++ END_LOCKS(audit); ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_mem.c linux-2.6.31.1/grsecurity/grsec_mem.c +--- linux-2.6.31.1/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_mem.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,79 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/mm.h> ++#include <linux/mman.h> ++#include <linux/grinternal.h> ++ ++void ++gr_handle_ioperm(void) ++{ ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG); ++ return; ++} ++ ++void ++gr_handle_iopl(void) ++{ ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG); ++ return; ++} ++ ++void ++gr_handle_mem_write(void) ++{ ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG); ++ return; ++} ++ ++void ++gr_handle_kmem_write(void) ++{ ++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG); ++ return; ++} ++ ++void ++gr_handle_open_port(void) ++{ ++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG); ++ return; ++} ++ ++int ++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma) ++{ ++ unsigned long start, end; ++ ++ start = offset; ++ end = start + vma->vm_end - vma->vm_start; ++ ++ if (start > end) { ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG); ++ return -EPERM; ++ } ++ ++ /* allowed ranges : ISA I/O BIOS */ ++ if ((start >= __pa(high_memory)) ++#if defined(CONFIG_X86) || defined(CONFIG_PPC) ++ || (start >= 0x000a0000 && end <= 0x00100000) ++ || (start >= 0x00000000 && end <= 0x00001000) ++#endif ++ ) ++ return 0; ++ ++ if (vma->vm_flags & VM_WRITE) { ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG); ++ return -EPERM; ++ } else ++ vma->vm_flags &= ~VM_MAYWRITE; ++ ++ return 0; ++} ++ ++void ++gr_log_nonroot_mod_load(const char *modname) ++{ ++ gr_log_str(GR_DONT_AUDIT, GR_NONROOT_MODLOAD_MSG, modname); ++ return; ++} ++ +diff -urNp linux-2.6.31.1/grsecurity/grsec_mount.c linux-2.6.31.1/grsecurity/grsec_mount.c +--- linux-2.6.31.1/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_mount.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,34 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++void ++gr_log_remount(const char *devname, const int retval) ++{ ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT ++ if (grsec_enable_mount && (retval >= 0)) ++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none"); ++#endif ++ return; ++} ++ ++void ++gr_log_unmount(const char *devname, const int retval) ++{ ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT ++ if (grsec_enable_mount && (retval >= 0)) ++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none"); ++#endif ++ return; ++} ++ ++void ++gr_log_mount(const char *from, const char *to, const int retval) ++{ ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT ++ if (grsec_enable_mount && (retval >= 0)) ++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to); ++#endif ++ return; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_sig.c linux-2.6.31.1/grsecurity/grsec_sig.c +--- linux-2.6.31.1/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_sig.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,65 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/delay.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++char *signames[] = { ++ [SIGSEGV] = "Segmentation fault", ++ [SIGILL] = "Illegal instruction", ++ [SIGABRT] = "Abort", ++ [SIGBUS] = "Invalid alignment/Bus error" ++}; ++ ++void ++gr_log_signal(const int sig, const void *addr, const struct task_struct *t) ++{ ++#ifdef CONFIG_GRKERNSEC_SIGNAL ++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) || ++ (sig == SIGABRT) || (sig == SIGBUS))) { ++ if (t->pid == current->pid) { ++ gr_log_sig_addr(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, signames[sig], addr); ++ } else { ++ gr_log_sig_task(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig); ++ } ++ } ++#endif ++ return; ++} ++ ++int ++gr_handle_signal(const struct task_struct *p, const int sig) ++{ ++#ifdef CONFIG_GRKERNSEC ++ if (current->pid > 1 && gr_check_protected_task(p)) { ++ gr_log_sig_task(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig); ++ return -EPERM; ++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) { ++ return -EPERM; ++ } ++#endif ++ return 0; ++} ++ ++void gr_handle_brute_attach(struct task_struct *p) ++{ ++#ifdef CONFIG_GRKERNSEC_BRUTE ++ read_lock(&tasklist_lock); ++ read_lock(&grsec_exec_file_lock); ++ if (p->parent && p->parent->exec_file == p->exec_file) ++ p->parent->brute = 1; ++ read_unlock(&grsec_exec_file_lock); ++ read_unlock(&tasklist_lock); ++#endif ++ return; ++} ++ ++void gr_handle_brute_check(void) ++{ ++#ifdef CONFIG_GRKERNSEC_BRUTE ++ if (current->brute) ++ msleep(30 * 1000); ++#endif ++ return; ++} ++ +diff -urNp linux-2.6.31.1/grsecurity/grsec_sock.c linux-2.6.31.1/grsecurity/grsec_sock.c +--- linux-2.6.31.1/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_sock.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,269 @@ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/file.h> ++#include <linux/net.h> ++#include <linux/in.h> ++#include <linux/ip.h> ++#include <net/sock.h> ++#include <net/inet_sock.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++#include <linux/gracl.h> ++ ++kernel_cap_t gr_cap_rtnetlink(struct sock *sock); ++EXPORT_SYMBOL(gr_cap_rtnetlink); ++ ++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb); ++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr); ++ ++EXPORT_SYMBOL(gr_search_udp_recvmsg); ++EXPORT_SYMBOL(gr_search_udp_sendmsg); ++ ++#ifdef CONFIG_UNIX_MODULE ++EXPORT_SYMBOL(gr_acl_handle_unix); ++EXPORT_SYMBOL(gr_acl_handle_mknod); ++EXPORT_SYMBOL(gr_handle_chroot_unix); ++EXPORT_SYMBOL(gr_handle_create); ++#endif ++ ++#ifdef CONFIG_GRKERNSEC ++#define gr_conn_table_size 32749 ++struct conn_table_entry { ++ struct conn_table_entry *next; ++ struct signal_struct *sig; ++}; ++ ++struct conn_table_entry *gr_conn_table[gr_conn_table_size]; ++DEFINE_SPINLOCK(gr_conn_table_lock); ++ ++extern const char * gr_socktype_to_name(unsigned char type); ++extern const char * gr_proto_to_name(unsigned char proto); ++ ++static __inline__ int ++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size) ++{ ++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size); ++} ++ ++static __inline__ int ++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, ++ __u16 sport, __u16 dport) ++{ ++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr && ++ sig->gr_sport == sport && sig->gr_dport == dport)) ++ return 1; ++ else ++ return 0; ++} ++ ++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent) ++{ ++ struct conn_table_entry **match; ++ unsigned int index; ++ ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr, ++ sig->gr_sport, sig->gr_dport, ++ gr_conn_table_size); ++ ++ newent->sig = sig; ++ ++ match = &gr_conn_table[index]; ++ newent->next = *match; ++ *match = newent; ++ ++ return; ++} ++ ++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig) ++{ ++ struct conn_table_entry *match, *last = NULL; ++ unsigned int index; ++ ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr, ++ sig->gr_sport, sig->gr_dport, ++ gr_conn_table_size); ++ ++ match = gr_conn_table[index]; ++ while (match && !conn_match(match->sig, ++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport, ++ sig->gr_dport)) { ++ last = match; ++ match = match->next; ++ } ++ ++ if (match) { ++ if (last) ++ last->next = match->next; ++ else ++ gr_conn_table[index] = NULL; ++ kfree(match); ++ } ++ ++ return; ++} ++ ++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr, ++ __u16 sport, __u16 dport) ++{ ++ struct conn_table_entry *match; ++ unsigned int index; ++ ++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size); ++ ++ match = gr_conn_table[index]; ++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport)) ++ match = match->next; ++ ++ if (match) ++ return match->sig; ++ else ++ return NULL; ++} ++ ++#endif ++ ++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet) ++{ ++#ifdef CONFIG_GRKERNSEC ++ struct signal_struct *sig = task->signal; ++ struct conn_table_entry *newent; ++ ++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC); ++ if (newent == NULL) ++ return; ++ /* no bh lock needed since we are called with bh disabled */ ++ spin_lock(&gr_conn_table_lock); ++ gr_del_task_from_ip_table_nolock(sig); ++ sig->gr_saddr = inet->rcv_saddr; ++ sig->gr_daddr = inet->daddr; ++ sig->gr_sport = inet->sport; ++ sig->gr_dport = inet->dport; ++ gr_add_to_task_ip_table_nolock(sig, newent); ++ spin_unlock(&gr_conn_table_lock); ++#endif ++ return; ++} ++ ++void gr_del_task_from_ip_table(struct task_struct *task) ++{ ++#ifdef CONFIG_GRKERNSEC ++ spin_lock_bh(&gr_conn_table_lock); ++ gr_del_task_from_ip_table_nolock(task->signal); ++ spin_unlock_bh(&gr_conn_table_lock); ++#endif ++ return; ++} ++ ++void ++gr_attach_curr_ip(const struct sock *sk) ++{ ++#ifdef CONFIG_GRKERNSEC ++ struct signal_struct *p, *set; ++ const struct inet_sock *inet = inet_sk(sk); ++ ++ if (unlikely(sk->sk_protocol != IPPROTO_TCP)) ++ return; ++ ++ set = current->signal; ++ ++ spin_lock_bh(&gr_conn_table_lock); ++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr, ++ inet->dport, inet->sport); ++ if (unlikely(p != NULL)) { ++ set->curr_ip = p->curr_ip; ++ set->used_accept = 1; ++ gr_del_task_from_ip_table_nolock(p); ++ spin_unlock_bh(&gr_conn_table_lock); ++ return; ++ } ++ spin_unlock_bh(&gr_conn_table_lock); ++ ++ set->curr_ip = inet->daddr; ++ set->used_accept = 1; ++#endif ++ return; ++} ++ ++int ++gr_handle_sock_all(const int family, const int type, const int protocol) ++{ ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL ++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) && ++ (family != AF_UNIX) && (family != AF_LOCAL)) { ++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol)); ++ return -EACCES; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_sock_server(const struct sockaddr *sck) ++{ ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER ++ if (grsec_enable_socket_server && ++ in_group_p(grsec_socket_server_gid) && ++ sck && (sck->sa_family != AF_UNIX) && ++ (sck->sa_family != AF_LOCAL)) { ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG); ++ return -EACCES; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_sock_server_other(const struct sock *sck) ++{ ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER ++ if (grsec_enable_socket_server && ++ in_group_p(grsec_socket_server_gid) && ++ sck && (sck->sk_family != AF_UNIX) && ++ (sck->sk_family != AF_LOCAL)) { ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG); ++ return -EACCES; ++ } ++#endif ++ return 0; ++} ++ ++int ++gr_handle_sock_client(const struct sockaddr *sck) ++{ ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT ++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) && ++ sck && (sck->sa_family != AF_UNIX) && ++ (sck->sa_family != AF_LOCAL)) { ++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG); ++ return -EACCES; ++ } ++#endif ++ return 0; ++} ++ ++kernel_cap_t ++gr_cap_rtnetlink(struct sock *sock) ++{ ++#ifdef CONFIG_GRKERNSEC ++ if (!gr_acl_is_enabled()) ++ return current_cap(); ++ else if (sock->sk_protocol == NETLINK_ISCSI && ++ cap_raised(current_cap(), CAP_SYS_ADMIN) && ++ gr_is_capable(CAP_SYS_ADMIN)) ++ return current_cap(); ++ else if (sock->sk_protocol == NETLINK_AUDIT && ++ cap_raised(current_cap(), CAP_AUDIT_WRITE) && ++ gr_is_capable(CAP_AUDIT_WRITE) && ++ cap_raised(current_cap(), CAP_AUDIT_CONTROL) && ++ gr_is_capable(CAP_AUDIT_CONTROL)) ++ return current_cap(); ++ else if (cap_raised(current_cap(), CAP_NET_ADMIN) && ++ gr_is_capable(CAP_NET_ADMIN)) ++ return current_cap(); ++ else ++ return __cap_empty_set; ++#else ++ return current_cap(); ++#endif ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_sysctl.c linux-2.6.31.1/grsecurity/grsec_sysctl.c +--- linux-2.6.31.1/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_sysctl.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,403 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/sysctl.h> ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++int ++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op) ++{ ++#ifdef CONFIG_GRKERNSEC_SYSCTL ++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) { ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name); ++ return -EACCES; ++ } ++#endif ++ return 0; ++} ++ ++#if defined(CONFIG_GRKERNSEC_SYSCTL) ++ctl_table grsecurity_table[] = { ++#ifdef CONFIG_GRKERNSEC_SYSCTL ++#ifdef CONFIG_GRKERNSEC_LINK ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "linking_restrictions", ++ .data = &grsec_enable_link, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_FIFO ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "fifo_restrictions", ++ .data = &grsec_enable_fifo, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_EXECVE ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "execve_limiting", ++ .data = &grsec_enable_execve, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_EXECLOG ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "exec_logging", ++ .data = &grsec_enable_execlog, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_SIGNAL ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "signal_logging", ++ .data = &grsec_enable_signal, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_FORKFAIL ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "forkfail_logging", ++ .data = &grsec_enable_forkfail, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_TIME ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "timechange_logging", ++ .data = &grsec_enable_time, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_deny_shmat", ++ .data = &grsec_enable_chroot_shmat, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_deny_unix", ++ .data = &grsec_enable_chroot_unix, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_deny_mount", ++ .data = &grsec_enable_chroot_mount, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_deny_fchdir", ++ .data = &grsec_enable_chroot_fchdir, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_deny_chroot", ++ .data = &grsec_enable_chroot_double, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_deny_pivot", ++ .data = &grsec_enable_chroot_pivot, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_enforce_chdir", ++ .data = &grsec_enable_chroot_chdir, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_deny_chmod", ++ .data = &grsec_enable_chroot_chmod, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_deny_mknod", ++ .data = &grsec_enable_chroot_mknod, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_restrict_nice", ++ .data = &grsec_enable_chroot_nice, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_execlog", ++ .data = &grsec_enable_chroot_execlog, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_caps", ++ .data = &grsec_enable_chroot_caps, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_deny_sysctl", ++ .data = &grsec_enable_chroot_sysctl, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_TPE ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "tpe", ++ .data = &grsec_enable_tpe, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "tpe_gid", ++ .data = &grsec_tpe_gid, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_TPE_ALL ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "tpe_restrict_all", ++ .data = &grsec_enable_tpe_all, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "socket_all", ++ .data = &grsec_enable_socket_all, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "socket_all_gid", ++ .data = &grsec_socket_all_gid, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "socket_client", ++ .data = &grsec_enable_socket_client, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "socket_client_gid", ++ .data = &grsec_socket_client_gid, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "socket_server", ++ .data = &grsec_enable_socket_server, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "socket_server_gid", ++ .data = &grsec_socket_server_gid, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "audit_group", ++ .data = &grsec_enable_group, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "audit_gid", ++ .data = &grsec_audit_gid, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "audit_chdir", ++ .data = &grsec_enable_chdir, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "audit_mount", ++ .data = &grsec_enable_mount, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "audit_textrel", ++ .data = &grsec_enable_audit_textrel, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_DMESG ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "dmesg", ++ .data = &grsec_enable_dmesg, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "chroot_findtask", ++ .data = &grsec_enable_chroot_findtask, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_RESLOG ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "resource_logging", ++ .data = &grsec_resource_logging, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "harden_ptrace", ++ .data = &grsec_enable_harden_ptrace, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "grsec_lock", ++ .data = &grsec_lock, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++ { .ctl_name = 0 } ++}; ++#endif +diff -urNp linux-2.6.31.1/grsecurity/grsec_textrel.c linux-2.6.31.1/grsecurity/grsec_textrel.c +--- linux-2.6.31.1/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_textrel.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,16 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/mm.h> ++#include <linux/file.h> ++#include <linux/grinternal.h> ++#include <linux/grsecurity.h> ++ ++void ++gr_log_textrel(struct vm_area_struct * vma) ++{ ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL ++ if (grsec_enable_audit_textrel) ++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff); ++#endif ++ return; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_time.c linux-2.6.31.1/grsecurity/grsec_time.c +--- linux-2.6.31.1/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_time.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,13 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/grinternal.h> ++ ++void ++gr_log_timechange(void) ++{ ++#ifdef CONFIG_GRKERNSEC_TIME ++ if (grsec_enable_time) ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG); ++#endif ++ return; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsec_tpe.c linux-2.6.31.1/grsecurity/grsec_tpe.c +--- linux-2.6.31.1/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsec_tpe.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,38 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++#include <linux/grinternal.h> ++ ++extern int gr_acl_tpe_check(void); ++ ++int ++gr_tpe_allow(const struct file *file) ++{ ++#ifdef CONFIG_GRKERNSEC ++ struct inode *inode = file->f_path.dentry->d_parent->d_inode; ++ const struct cred *cred = current_cred(); ++ ++ if (cred->uid && ((grsec_enable_tpe && ++#ifdef CONFIG_GRKERNSEC_TPE_INVERT ++ !in_group_p(grsec_tpe_gid) ++#else ++ in_group_p(grsec_tpe_gid) ++#endif ++ ) || gr_acl_tpe_check()) && ++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) || ++ (inode->i_mode & S_IWOTH))))) { ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt); ++ return 0; ++ } ++#ifdef CONFIG_GRKERNSEC_TPE_ALL ++ if (cred->uid && grsec_enable_tpe && grsec_enable_tpe_all && ++ ((inode->i_uid && (inode->i_uid != cred->uid)) || ++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) { ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt); ++ return 0; ++ } ++#endif ++#endif ++ return 1; ++} +diff -urNp linux-2.6.31.1/grsecurity/grsum.c linux-2.6.31.1/grsecurity/grsum.c +--- linux-2.6.31.1/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/grsum.c 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,59 @@ ++#include <linux/err.h> ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/mm.h> ++#include <linux/scatterlist.h> ++#include <linux/crypto.h> ++#include <linux/gracl.h> ++ ++ ++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE) ++#error "crypto and sha256 must be built into the kernel" ++#endif ++ ++int ++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum) ++{ ++ char *p; ++ struct crypto_hash *tfm; ++ struct hash_desc desc; ++ struct scatterlist sg; ++ unsigned char temp_sum[GR_SHA_LEN]; ++ volatile int retval = 0; ++ volatile int dummy = 0; ++ unsigned int i; ++ ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tfm)) { ++ /* should never happen, since sha256 should be built in */ ++ return 1; ++ } ++ ++ desc.tfm = tfm; ++ desc.flags = 0; ++ ++ crypto_hash_init(&desc); ++ ++ p = salt; ++ sg_set_buf(&sg, p, GR_SALT_LEN); ++ crypto_hash_update(&desc, &sg, sg.length); ++ ++ p = entry->pw; ++ sg_set_buf(&sg, p, strlen(p)); ++ ++ crypto_hash_update(&desc, &sg, sg.length); ++ ++ crypto_hash_final(&desc, temp_sum); ++ ++ memset(entry->pw, 0, GR_PW_LEN); ++ ++ for (i = 0; i < GR_SHA_LEN; i++) ++ if (sum[i] != temp_sum[i]) ++ retval = 1; ++ else ++ dummy = 1; // waste a cycle ++ ++ crypto_free_hash(tfm); ++ ++ return retval; ++} +diff -urNp linux-2.6.31.1/grsecurity/Kconfig linux-2.6.31.1/grsecurity/Kconfig +--- linux-2.6.31.1/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/Kconfig 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,908 @@ ++# ++# grecurity configuration ++# ++ ++menu "Grsecurity" ++ ++config GRKERNSEC ++ bool "Grsecurity" ++ select CRYPTO ++ select CRYPTO_SHA256 ++ help ++ If you say Y here, you will be able to configure many features ++ that will enhance the security of your system. It is highly ++ recommended that you say Y here and read through the help ++ for each option so that you fully understand the features and ++ can evaluate their usefulness for your machine. ++ ++choice ++ prompt "Security Level" ++ depends on GRKERNSEC ++ default GRKERNSEC_CUSTOM ++ ++config GRKERNSEC_LOW ++ bool "Low" ++ select GRKERNSEC_LINK ++ select GRKERNSEC_FIFO ++ select GRKERNSEC_EXECVE ++ select GRKERNSEC_RANDNET ++ select GRKERNSEC_DMESG ++ select GRKERNSEC_CHROOT ++ select GRKERNSEC_CHROOT_CHDIR ++ ++ help ++ If you choose this option, several of the grsecurity options will ++ be enabled that will give you greater protection against a number ++ of attacks, while assuring that none of your software will have any ++ conflicts with the additional security measures. If you run a lot ++ of unusual software, or you are having problems with the higher ++ security levels, you should say Y here. With this option, the ++ following features are enabled: ++ ++ - Linking restrictions ++ - FIFO restrictions ++ - Enforcing RLIMIT_NPROC on execve ++ - Restricted dmesg ++ - Enforced chdir("/") on chroot ++ - Runtime module disabling ++ ++config GRKERNSEC_MEDIUM ++ bool "Medium" ++ select PAX ++ select PAX_EI_PAX ++ select PAX_PT_PAX_FLAGS ++ select PAX_HAVE_ACL_FLAGS ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR) ++ select GRKERNSEC_CHROOT ++ select GRKERNSEC_CHROOT_SYSCTL ++ select GRKERNSEC_LINK ++ select GRKERNSEC_FIFO ++ select GRKERNSEC_EXECVE ++ select GRKERNSEC_DMESG ++ select GRKERNSEC_RANDNET ++ select GRKERNSEC_FORKFAIL ++ select GRKERNSEC_TIME ++ select GRKERNSEC_SIGNAL ++ select GRKERNSEC_CHROOT ++ select GRKERNSEC_CHROOT_UNIX ++ select GRKERNSEC_CHROOT_MOUNT ++ select GRKERNSEC_CHROOT_PIVOT ++ select GRKERNSEC_CHROOT_DOUBLE ++ select GRKERNSEC_CHROOT_CHDIR ++ select GRKERNSEC_CHROOT_MKNOD ++ select GRKERNSEC_PROC ++ select GRKERNSEC_PROC_USERGROUP ++ select PAX_RANDUSTACK ++ select PAX_ASLR ++ select PAX_RANDMMAP ++ select PAX_REFCOUNT if (X86 || SPARC64) ++ select PAX_USERCOPY if ((X86 || SPARC32 || SPARC64 || PPC32 || PPC64) && (SLAB || SLUB || SLOB)) ++ ++ help ++ If you say Y here, several features in addition to those included ++ in the low additional security level will be enabled. These ++ features provide even more security to your system, though in rare ++ cases they may be incompatible with very old or poorly written ++ software. If you enable this option, make sure that your auth ++ service (identd) is running as gid 1001. With this option, ++ the following features (in addition to those provided in the ++ low additional security level) will be enabled: ++ ++ - Failed fork logging ++ - Time change logging ++ - Signal logging ++ - Deny mounts in chroot ++ - Deny double chrooting ++ - Deny sysctl writes in chroot ++ - Deny mknod in chroot ++ - Deny access to abstract AF_UNIX sockets out of chroot ++ - Deny pivot_root in chroot ++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port ++ - /proc restrictions with special GID set to 10 (usually wheel) ++ - Address Space Layout Randomization (ASLR) ++ - Prevent exploitation of most refcount overflows ++ - Bounds checking of copying between the kernel and userland ++ ++config GRKERNSEC_HIGH ++ bool "High" ++ select GRKERNSEC_LINK ++ select GRKERNSEC_FIFO ++ select GRKERNSEC_EXECVE ++ select GRKERNSEC_DMESG ++ select GRKERNSEC_FORKFAIL ++ select GRKERNSEC_TIME ++ select GRKERNSEC_SIGNAL ++ select GRKERNSEC_CHROOT ++ select GRKERNSEC_CHROOT_SHMAT ++ select GRKERNSEC_CHROOT_UNIX ++ select GRKERNSEC_CHROOT_MOUNT ++ select GRKERNSEC_CHROOT_FCHDIR ++ select GRKERNSEC_CHROOT_PIVOT ++ select GRKERNSEC_CHROOT_DOUBLE ++ select GRKERNSEC_CHROOT_CHDIR ++ select GRKERNSEC_CHROOT_MKNOD ++ select GRKERNSEC_CHROOT_CAPS ++ select GRKERNSEC_CHROOT_SYSCTL ++ select GRKERNSEC_CHROOT_FINDTASK ++ select GRKERNSEC_PROC ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR) ++ select GRKERNSEC_HIDESYM ++ select GRKERNSEC_BRUTE ++ select GRKERNSEC_PROC_USERGROUP ++ select GRKERNSEC_KMEM ++ select GRKERNSEC_RESLOG ++ select GRKERNSEC_RANDNET ++ select GRKERNSEC_PROC_ADD ++ select GRKERNSEC_CHROOT_CHMOD ++ select GRKERNSEC_CHROOT_NICE ++ select GRKERNSEC_AUDIT_MOUNT ++ select GRKERNSEC_MODHARDEN if (MODULES) ++ select GRKERNSEC_HARDEN_PTRACE ++ select PAX ++ select PAX_RANDUSTACK ++ select PAX_ASLR ++ select PAX_RANDMMAP ++ select PAX_NOEXEC ++ select PAX_MPROTECT ++ select PAX_EI_PAX ++ select PAX_PT_PAX_FLAGS ++ select PAX_HAVE_ACL_FLAGS ++ select PAX_KERNEXEC if (X86 && (!X86_32 || X86_WP_WORKS_OK)) ++ select PAX_MEMORY_UDEREF if (X86_32) ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64) ++ select PAX_SEGMEXEC if (X86_32) ++ select PAX_PAGEEXEC ++ select PAX_EMUPLT if (ALPHA || PARISC || SPARC32 || SPARC64) ++ select PAX_EMUTRAMP if (PARISC) ++ select PAX_EMUSIGRT if (PARISC) ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC) ++ select PAX_REFCOUNT if (X86 || SPARC64) ++ select PAX_USERCOPY if ((X86 || PPC32 || PPC64 || SPARC32 || SPARC64) && (SLAB || SLUB || SLOB)) ++ help ++ If you say Y here, many of the features of grsecurity will be ++ enabled, which will protect you against many kinds of attacks ++ against your system. The heightened security comes at a cost ++ of an increased chance of incompatibilities with rare software ++ on your machine. Since this security level enables PaX, you should ++ view <http://pax.grsecurity.net> and read about the PaX ++ project. While you are there, download chpax and run it on ++ binaries that cause problems with PaX. Also remember that ++ since the /proc restrictions are enabled, you must run your ++ identd as gid 1001. This security level enables the following ++ features in addition to those listed in the low and medium ++ security levels: ++ ++ - Additional /proc restrictions ++ - Chmod restrictions in chroot ++ - No signals, ptrace, or viewing of processes outside of chroot ++ - Capability restrictions in chroot ++ - Deny fchdir out of chroot ++ - Priority restrictions in chroot ++ - Segmentation-based implementation of PaX ++ - Mprotect restrictions ++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat] ++ - Kernel stack randomization ++ - Mount/unmount/remount logging ++ - Kernel symbol hiding ++ - Prevention of memory exhaustion-based exploits ++ - Hardening of module auto-loading ++ - Ptrace restrictions ++ ++config GRKERNSEC_CUSTOM ++ bool "Custom" ++ help ++ If you say Y here, you will be able to configure every grsecurity ++ option, which allows you to enable many more features that aren't ++ covered in the basic security levels. These additional features ++ include TPE, socket restrictions, and the sysctl system for ++ grsecurity. It is advised that you read through the help for ++ each option to determine its usefulness in your situation. ++ ++endchoice ++ ++menu "Address Space Protection" ++depends on GRKERNSEC ++ ++config GRKERNSEC_KMEM ++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port" ++ help ++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to ++ be written to via mmap or otherwise to modify the running kernel. ++ /dev/port will also not be allowed to be opened. If you have module ++ support disabled, enabling this will close up four ways that are ++ currently used to insert malicious code into the running kernel. ++ Even with all these features enabled, we still highly recommend that ++ you use the RBAC system, as it is still possible for an attacker to ++ modify the running kernel through privileged I/O granted by ioperm/iopl. ++ If you are not using XFree86, you may be able to stop this additional ++ case by enabling the 'Disable privileged I/O' option. Though nothing ++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem, ++ but only to video memory, which is the only writing we allow in this ++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will ++ not be allowed to mprotect it with PROT_WRITE later. ++ It is highly recommended that you say Y here if you meet all the ++ conditions above. ++ ++config GRKERNSEC_IO ++ bool "Disable privileged I/O" ++ depends on X86 ++ select RTC_CLASS ++ select RTC_INTF_DEV ++ select RTC_DRV_CMOS ++ ++ help ++ If you say Y here, all ioperm and iopl calls will return an error. ++ Ioperm and iopl can be used to modify the running kernel. ++ Unfortunately, some programs need this access to operate properly, ++ the most notable of which are XFree86 and hwclock. hwclock can be ++ remedied by having RTC support in the kernel, so real-time ++ clock support is enabled if this option is enabled, to ensure ++ that hwclock operates correctly. XFree86 still will not ++ operate correctly with this option enabled, so DO NOT CHOOSE Y ++ IF YOU USE XFree86. If you use XFree86 and you still want to ++ protect your kernel against modification, use the RBAC system. ++ ++config GRKERNSEC_PROC_MEMMAP ++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]" ++ default y if (PAX_NOEXEC || PAX_ASLR) ++ depends on PAX_NOEXEC || PAX_ASLR ++ help ++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will ++ give no information about the addresses of its mappings if ++ PaX features that rely on random addresses are enabled on the task. ++ If you use PaX it is greatly recommended that you say Y here as it ++ closes up a hole that makes the full ASLR useless for suid ++ binaries. ++ ++config GRKERNSEC_BRUTE ++ bool "Deter exploit bruteforcing" ++ help ++ If you say Y here, attempts to bruteforce exploits against forking ++ daemons such as apache or sshd will be deterred. When a child of a ++ forking daemon is killed by PaX or crashes due to an illegal ++ instruction, the parent process will be delayed 30 seconds upon every ++ subsequent fork until the administrator is able to assess the ++ situation and restart the daemon. It is recommended that you also ++ enable signal logging in the auditing section so that logs are ++ generated when a process performs an illegal instruction. ++ ++config GRKERNSEC_MODHARDEN ++ bool "Harden module auto-loading" ++ depends on MODULES ++ help ++ If you say Y here, module auto-loading in response to use of some ++ feature implemented by an unloaded module will be restricted to ++ root users. Enabling this option helps defend against attacks ++ by unprivileged users who abuse the auto-loading behavior to ++ cause a vulnerable module to load that is then exploited. ++ ++ If this option prevents a legitimate use of auto-loading for a ++ non-root user, the administrator can execute modprobe manually ++ with the exact name of the module mentioned in the alert log. ++ Alternatively, the administrator can add the module to the list ++ of modules loaded at boot by modifying init scripts. ++ ++ Modification of init scripts will most likely be needed on ++ Ubuntu servers with encrypted home directory support enabled, ++ as the first non-root user logging in will cause the ecb(aes), ++ ecb(aes)-all, cbc(aes), and cbc(aes)-all modules to be loaded. ++ ++config GRKERNSEC_HIDESYM ++ bool "Hide kernel symbols" ++ help ++ If you say Y here, getting information on loaded modules, and ++ displaying all kernel symbols through a syscall will be restricted ++ to users with CAP_SYS_MODULE. For software compatibility reasons, ++ /proc/kallsyms will be restricted to the root user. The RBAC ++ system can hide that entry even from root. Note that this option ++ is only effective provided the following conditions are met: ++ 1) The kernel using grsecurity is not precompiled by some distribution ++ 2) You are using the RBAC system and hiding other files such as your ++ kernel image and System.map. Alternatively, enabling this option ++ causes the permissions on /boot, /lib/modules, and the kernel ++ source directory to change at compile time to prevent ++ reading by non-root users. ++ If the above conditions are met, this option will aid in providing a ++ useful protection against local kernel exploitation of overflows ++ and arbitrary read/write vulnerabilities. ++ ++endmenu ++menu "Role Based Access Control Options" ++depends on GRKERNSEC ++ ++config GRKERNSEC_NO_RBAC ++ bool "Disable RBAC system" ++ help ++ If you say Y here, the /dev/grsec device will be removed from the kernel, ++ preventing the RBAC system from being enabled. You should only say Y ++ here if you have no intention of using the RBAC system, so as to prevent ++ an attacker with root access from misusing the RBAC system to hide files ++ and processes when loadable module support and /dev/[k]mem have been ++ locked down. ++ ++config GRKERNSEC_ACL_HIDEKERN ++ bool "Hide kernel processes" ++ help ++ If you say Y here, all kernel threads will be hidden to all ++ processes but those whose subject has the "view hidden processes" ++ flag. ++ ++config GRKERNSEC_ACL_MAXTRIES ++ int "Maximum tries before password lockout" ++ default 3 ++ help ++ This option enforces the maximum number of times a user can attempt ++ to authorize themselves with the grsecurity RBAC system before being ++ denied the ability to attempt authorization again for a specified time. ++ The lower the number, the harder it will be to brute-force a password. ++ ++config GRKERNSEC_ACL_TIMEOUT ++ int "Time to wait after max password tries, in seconds" ++ default 30 ++ help ++ This option specifies the time the user must wait after attempting to ++ authorize to the RBAC system with the maximum number of invalid ++ passwords. The higher the number, the harder it will be to brute-force ++ a password. ++ ++endmenu ++menu "Filesystem Protections" ++depends on GRKERNSEC ++ ++config GRKERNSEC_PROC ++ bool "Proc restrictions" ++ help ++ If you say Y here, the permissions of the /proc filesystem ++ will be altered to enhance system security and privacy. You MUST ++ choose either a user only restriction or a user and group restriction. ++ Depending upon the option you choose, you can either restrict users to ++ see only the processes they themselves run, or choose a group that can ++ view all processes and files normally restricted to root if you choose ++ the "restrict to user only" option. NOTE: If you're running identd as ++ a non-root user, you will have to run it as the group you specify here. ++ ++config GRKERNSEC_PROC_USER ++ bool "Restrict /proc to user only" ++ depends on GRKERNSEC_PROC ++ help ++ If you say Y here, non-root users will only be able to view their own ++ processes, and restricts them from viewing network-related information, ++ and viewing kernel symbol and module information. ++ ++config GRKERNSEC_PROC_USERGROUP ++ bool "Allow special group" ++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER ++ help ++ If you say Y here, you will be able to select a group that will be ++ able to view all processes, network-related information, and ++ kernel and symbol information. This option is useful if you want ++ to run identd as a non-root user. ++ ++config GRKERNSEC_PROC_GID ++ int "GID for special group" ++ depends on GRKERNSEC_PROC_USERGROUP ++ default 1001 ++ ++config GRKERNSEC_PROC_ADD ++ bool "Additional restrictions" ++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP ++ help ++ If you say Y here, additional restrictions will be placed on ++ /proc that keep normal users from viewing device information and ++ slabinfo information that could be useful for exploits. ++ ++config GRKERNSEC_LINK ++ bool "Linking restrictions" ++ help ++ If you say Y here, /tmp race exploits will be prevented, since users ++ will no longer be able to follow symlinks owned by other users in ++ world-writable +t directories (i.e. /tmp), unless the owner of the ++ symlink is the owner of the directory. users will also not be ++ able to hardlink to files they do not own. If the sysctl option is ++ enabled, a sysctl option with name "linking_restrictions" is created. ++ ++config GRKERNSEC_FIFO ++ bool "FIFO restrictions" ++ help ++ If you say Y here, users will not be able to write to FIFOs they don't ++ own in world-writable +t directories (i.e. /tmp), unless the owner of ++ the FIFO is the same owner of the directory it's held in. If the sysctl ++ option is enabled, a sysctl option with name "fifo_restrictions" is ++ created. ++ ++config GRKERNSEC_CHROOT ++ bool "Chroot jail restrictions" ++ help ++ If you say Y here, you will be able to choose several options that will ++ make breaking out of a chrooted jail much more difficult. If you ++ encounter no software incompatibilities with the following options, it ++ is recommended that you enable each one. ++ ++config GRKERNSEC_CHROOT_MOUNT ++ bool "Deny mounts" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, processes inside a chroot will not be able to ++ mount or remount filesystems. If the sysctl option is enabled, a ++ sysctl option with name "chroot_deny_mount" is created. ++ ++config GRKERNSEC_CHROOT_DOUBLE ++ bool "Deny double-chroots" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, processes inside a chroot will not be able to chroot ++ again outside the chroot. This is a widely used method of breaking ++ out of a chroot jail and should not be allowed. If the sysctl ++ option is enabled, a sysctl option with name ++ "chroot_deny_chroot" is created. ++ ++config GRKERNSEC_CHROOT_PIVOT ++ bool "Deny pivot_root in chroot" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, processes inside a chroot will not be able to use ++ a function called pivot_root() that was introduced in Linux 2.3.41. It ++ works similar to chroot in that it changes the root filesystem. This ++ function could be misused in a chrooted process to attempt to break out ++ of the chroot, and therefore should not be allowed. If the sysctl ++ option is enabled, a sysctl option with name "chroot_deny_pivot" is ++ created. ++ ++config GRKERNSEC_CHROOT_CHDIR ++ bool "Enforce chdir("/") on all chroots" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, the current working directory of all newly-chrooted ++ applications will be set to the the root directory of the chroot. ++ The man page on chroot(2) states: ++ Note that this call does not change the current working ++ directory, so that `.' can be outside the tree rooted at ++ `/'. In particular, the super-user can escape from a ++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'. ++ ++ It is recommended that you say Y here, since it's not known to break ++ any software. If the sysctl option is enabled, a sysctl option with ++ name "chroot_enforce_chdir" is created. ++ ++config GRKERNSEC_CHROOT_CHMOD ++ bool "Deny (f)chmod +s" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, processes inside a chroot will not be able to chmod ++ or fchmod files to make them have suid or sgid bits. This protects ++ against another published method of breaking a chroot. If the sysctl ++ option is enabled, a sysctl option with name "chroot_deny_chmod" is ++ created. ++ ++config GRKERNSEC_CHROOT_FCHDIR ++ bool "Deny fchdir out of chroot" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, a well-known method of breaking chroots by fchdir'ing ++ to a file descriptor of the chrooting process that points to a directory ++ outside the filesystem will be stopped. If the sysctl option ++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created. ++ ++config GRKERNSEC_CHROOT_MKNOD ++ bool "Deny mknod" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, processes inside a chroot will not be allowed to ++ mknod. The problem with using mknod inside a chroot is that it ++ would allow an attacker to create a device entry that is the same ++ as one on the physical root of your system, which could range from ++ anything from the console device to a device for your harddrive (which ++ they could then use to wipe the drive or steal data). It is recommended ++ that you say Y here, unless you run into software incompatibilities. ++ If the sysctl option is enabled, a sysctl option with name ++ "chroot_deny_mknod" is created. ++ ++config GRKERNSEC_CHROOT_SHMAT ++ bool "Deny shmat() out of chroot" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, processes inside a chroot will not be able to attach ++ to shared memory segments that were created outside of the chroot jail. ++ It is recommended that you say Y here. If the sysctl option is enabled, ++ a sysctl option with name "chroot_deny_shmat" is created. ++ ++config GRKERNSEC_CHROOT_UNIX ++ bool "Deny access to abstract AF_UNIX sockets out of chroot" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, processes inside a chroot will not be able to ++ connect to abstract (meaning not belonging to a filesystem) Unix ++ domain sockets that were bound outside of a chroot. It is recommended ++ that you say Y here. If the sysctl option is enabled, a sysctl option ++ with name "chroot_deny_unix" is created. ++ ++config GRKERNSEC_CHROOT_FINDTASK ++ bool "Protect outside processes" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, processes inside a chroot will not be able to ++ kill, send signals with fcntl, ptrace, capget, getpgid, setpgid, ++ getsid, or view any process outside of the chroot. If the sysctl ++ option is enabled, a sysctl option with name "chroot_findtask" is ++ created. ++ ++config GRKERNSEC_CHROOT_NICE ++ bool "Restrict priority changes" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, processes inside a chroot will not be able to raise ++ the priority of processes in the chroot, or alter the priority of ++ processes outside the chroot. This provides more security than simply ++ removing CAP_SYS_NICE from the process' capability set. If the ++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice" ++ is created. ++ ++config GRKERNSEC_CHROOT_SYSCTL ++ bool "Deny sysctl writes" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, an attacker in a chroot will not be able to ++ write to sysctl entries, either by sysctl(2) or through a /proc ++ interface. It is strongly recommended that you say Y here. If the ++ sysctl option is enabled, a sysctl option with name ++ "chroot_deny_sysctl" is created. ++ ++config GRKERNSEC_CHROOT_CAPS ++ bool "Capability restrictions" ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, the capabilities on all root processes within a ++ chroot jail will be lowered to stop module insertion, raw i/o, ++ system and net admin tasks, rebooting the system, modifying immutable ++ files, modifying IPC owned by another, and changing the system time. ++ This is left an option because it can break some apps. Disable this ++ if your chrooted apps are having problems performing those kinds of ++ tasks. If the sysctl option is enabled, a sysctl option with ++ name "chroot_caps" is created. ++ ++endmenu ++menu "Kernel Auditing" ++depends on GRKERNSEC ++ ++config GRKERNSEC_AUDIT_GROUP ++ bool "Single group for auditing" ++ help ++ If you say Y here, the exec, chdir, and (un)mount logging features ++ will only operate on a group you specify. This option is recommended ++ if you only want to watch certain users instead of having a large ++ amount of logs from the entire system. If the sysctl option is enabled, ++ a sysctl option with name "audit_group" is created. ++ ++config GRKERNSEC_AUDIT_GID ++ int "GID for auditing" ++ depends on GRKERNSEC_AUDIT_GROUP ++ default 1007 ++ ++config GRKERNSEC_EXECLOG ++ bool "Exec logging" ++ help ++ If you say Y here, all execve() calls will be logged (since the ++ other exec*() calls are frontends to execve(), all execution ++ will be logged). Useful for shell-servers that like to keep track ++ of their users. If the sysctl option is enabled, a sysctl option with ++ name "exec_logging" is created. ++ WARNING: This option when enabled will produce a LOT of logs, especially ++ on an active system. ++ ++config GRKERNSEC_RESLOG ++ bool "Resource logging" ++ help ++ If you say Y here, all attempts to overstep resource limits will ++ be logged with the resource name, the requested size, and the current ++ limit. It is highly recommended that you say Y here. If the sysctl ++ option is enabled, a sysctl option with name "resource_logging" is ++ created. If the RBAC system is enabled, the sysctl value is ignored. ++ ++config GRKERNSEC_CHROOT_EXECLOG ++ bool "Log execs within chroot" ++ help ++ If you say Y here, all executions inside a chroot jail will be logged ++ to syslog. This can cause a large amount of logs if certain ++ applications (eg. djb's daemontools) are installed on the system, and ++ is therefore left as an option. If the sysctl option is enabled, a ++ sysctl option with name "chroot_execlog" is created. ++ ++config GRKERNSEC_AUDIT_CHDIR ++ bool "Chdir logging" ++ help ++ If you say Y here, all chdir() calls will be logged. If the sysctl ++ option is enabled, a sysctl option with name "audit_chdir" is created. ++ ++config GRKERNSEC_AUDIT_MOUNT ++ bool "(Un)Mount logging" ++ help ++ If you say Y here, all mounts and unmounts will be logged. If the ++ sysctl option is enabled, a sysctl option with name "audit_mount" is ++ created. ++ ++config GRKERNSEC_SIGNAL ++ bool "Signal logging" ++ help ++ If you say Y here, certain important signals will be logged, such as ++ SIGSEGV, which will as a result inform you of when a error in a program ++ occurred, which in some cases could mean a possible exploit attempt. ++ If the sysctl option is enabled, a sysctl option with name ++ "signal_logging" is created. ++ ++config GRKERNSEC_FORKFAIL ++ bool "Fork failure logging" ++ help ++ If you say Y here, all failed fork() attempts will be logged. ++ This could suggest a fork bomb, or someone attempting to overstep ++ their process limit. If the sysctl option is enabled, a sysctl option ++ with name "forkfail_logging" is created. ++ ++config GRKERNSEC_TIME ++ bool "Time change logging" ++ help ++ If you say Y here, any changes of the system clock will be logged. ++ If the sysctl option is enabled, a sysctl option with name ++ "timechange_logging" is created. ++ ++config GRKERNSEC_PROC_IPADDR ++ bool "/proc/<pid>/ipaddr support" ++ help ++ If you say Y here, a new entry will be added to each /proc/<pid> ++ directory that contains the IP address of the person using the task. ++ The IP is carried across local TCP and AF_UNIX stream sockets. ++ This information can be useful for IDS/IPSes to perform remote response ++ to a local attack. The entry is readable by only the owner of the ++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via ++ the RBAC system), and thus does not create privacy concerns. ++ ++config GRKERNSEC_AUDIT_TEXTREL ++ bool 'ELF text relocations logging (READ HELP)' ++ depends on PAX_MPROTECT ++ help ++ If you say Y here, text relocations will be logged with the filename ++ of the offending library or binary. The purpose of the feature is ++ to help Linux distribution developers get rid of libraries and ++ binaries that need text relocations which hinder the future progress ++ of PaX. Only Linux distribution developers should say Y here, and ++ never on a production machine, as this option creates an information ++ leak that could aid an attacker in defeating the randomization of ++ a single memory region. If the sysctl option is enabled, a sysctl ++ option with name "audit_textrel" is created. ++ ++endmenu ++ ++menu "Executable Protections" ++depends on GRKERNSEC ++ ++config GRKERNSEC_EXECVE ++ bool "Enforce RLIMIT_NPROC on execs" ++ help ++ If you say Y here, users with a resource limit on processes will ++ have the value checked during execve() calls. The current system ++ only checks the system limit during fork() calls. If the sysctl option ++ is enabled, a sysctl option with name "execve_limiting" is created. ++ ++config GRKERNSEC_DMESG ++ bool "Dmesg(8) restriction" ++ help ++ If you say Y here, non-root users will not be able to use dmesg(8) ++ to view up to the last 4kb of messages in the kernel's log buffer. ++ If the sysctl option is enabled, a sysctl option with name "dmesg" is ++ created. ++ ++config GRKERNSEC_HARDEN_PTRACE ++ bool "Deter ptrace-based process snooping" ++ help ++ If you say Y here, TTY sniffers and other malicious monitoring ++ programs implemented through ptrace will be defeated. If you ++ have been using the RBAC system, this option has already been ++ enabled for several years for all users, with the ability to make ++ fine-grained exceptions. ++ ++ This option only affects the ability of non-root users to ptrace ++ processes that are not a descendent of the ptracing process. ++ This means that strace ./binary and gdb ./binary will still work, ++ but attaching to arbitrary processes will not. If the sysctl ++ option is enabled, a sysctl option with name "harden_ptrace" is ++ created. ++ ++config GRKERNSEC_TPE ++ bool "Trusted Path Execution (TPE)" ++ help ++ If you say Y here, you will be able to choose a gid to add to the ++ supplementary groups of users you want to mark as "untrusted." ++ These users will not be able to execute any files that are not in ++ root-owned directories writable only by root. If the sysctl option ++ is enabled, a sysctl option with name "tpe" is created. ++ ++config GRKERNSEC_TPE_ALL ++ bool "Partially restrict non-root users" ++ depends on GRKERNSEC_TPE ++ help ++ If you say Y here, All non-root users other than the ones in the ++ group specified in the main TPE option will only be allowed to ++ execute files in directories they own that are not group or ++ world-writable, or in directories owned by root and writable only by ++ root. If the sysctl option is enabled, a sysctl option with name ++ "tpe_restrict_all" is created. ++ ++config GRKERNSEC_TPE_INVERT ++ bool "Invert GID option" ++ depends on GRKERNSEC_TPE ++ help ++ If you say Y here, the group you specify in the TPE configuration will ++ decide what group TPE restrictions will be *disabled* for. This ++ option is useful if you want TPE restrictions to be applied to most ++ users on the system. ++ ++config GRKERNSEC_TPE_GID ++ int "GID for untrusted users" ++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT ++ default 1005 ++ help ++ If you have selected the "Invert GID option" above, setting this ++ GID determines what group TPE restrictions will be *disabled* for. ++ If you have not selected the "Invert GID option" above, setting this ++ GID determines what group TPE restrictions will be *enabled* for. ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid" ++ is created. ++ ++config GRKERNSEC_TPE_GID ++ int "GID for trusted users" ++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT ++ default 1005 ++ help ++ If you have selected the "Invert GID option" above, setting this ++ GID determines what group TPE restrictions will be *disabled* for. ++ If you have not selected the "Invert GID option" above, setting this ++ GID determines what group TPE restrictions will be *enabled* for. ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid" ++ is created. ++ ++endmenu ++menu "Network Protections" ++depends on GRKERNSEC ++ ++config GRKERNSEC_RANDNET ++ bool "Larger entropy pools" ++ help ++ If you say Y here, the entropy pools used for many features of Linux ++ and grsecurity will be doubled in size. Since several grsecurity ++ features use additional randomness, it is recommended that you say Y ++ here. Saying Y here has a similar effect as modifying ++ /proc/sys/kernel/random/poolsize. ++ ++config GRKERNSEC_BLACKHOLE ++ bool "TCP/UDP blackhole" ++ help ++ If you say Y here, neither TCP resets nor ICMP ++ destination-unreachable packets will be sent in response to packets ++ send to ports for which no associated listening process exists. ++ This feature supports both IPV4 and IPV6 and exempts the ++ loopback interface from blackholing. Enabling this feature ++ makes a host more resilient to DoS attacks and reduces network ++ visibility against scanners. ++ ++config GRKERNSEC_SOCKET ++ bool "Socket restrictions" ++ help ++ If you say Y here, you will be able to choose from several options. ++ If you assign a GID on your system and add it to the supplementary ++ groups of users you want to restrict socket access to, this patch ++ will perform up to three things, based on the option(s) you choose. ++ ++config GRKERNSEC_SOCKET_ALL ++ bool "Deny any sockets to group" ++ depends on GRKERNSEC_SOCKET ++ help ++ If you say Y here, you will be able to choose a GID of whose users will ++ be unable to connect to other hosts from your machine or run server ++ applications from your machine. If the sysctl option is enabled, a ++ sysctl option with name "socket_all" is created. ++ ++config GRKERNSEC_SOCKET_ALL_GID ++ int "GID to deny all sockets for" ++ depends on GRKERNSEC_SOCKET_ALL ++ default 1004 ++ help ++ Here you can choose the GID to disable socket access for. Remember to ++ add the users you want socket access disabled for to the GID ++ specified here. If the sysctl option is enabled, a sysctl option ++ with name "socket_all_gid" is created. ++ ++config GRKERNSEC_SOCKET_CLIENT ++ bool "Deny client sockets to group" ++ depends on GRKERNSEC_SOCKET ++ help ++ If you say Y here, you will be able to choose a GID of whose users will ++ be unable to connect to other hosts from your machine, but will be ++ able to run servers. If this option is enabled, all users in the group ++ you specify will have to use passive mode when initiating ftp transfers ++ from the shell on your machine. If the sysctl option is enabled, a ++ sysctl option with name "socket_client" is created. ++ ++config GRKERNSEC_SOCKET_CLIENT_GID ++ int "GID to deny client sockets for" ++ depends on GRKERNSEC_SOCKET_CLIENT ++ default 1003 ++ help ++ Here you can choose the GID to disable client socket access for. ++ Remember to add the users you want client socket access disabled for to ++ the GID specified here. If the sysctl option is enabled, a sysctl ++ option with name "socket_client_gid" is created. ++ ++config GRKERNSEC_SOCKET_SERVER ++ bool "Deny server sockets to group" ++ depends on GRKERNSEC_SOCKET ++ help ++ If you say Y here, you will be able to choose a GID of whose users will ++ be unable to run server applications from your machine. If the sysctl ++ option is enabled, a sysctl option with name "socket_server" is created. ++ ++config GRKERNSEC_SOCKET_SERVER_GID ++ int "GID to deny server sockets for" ++ depends on GRKERNSEC_SOCKET_SERVER ++ default 1002 ++ help ++ Here you can choose the GID to disable server socket access for. ++ Remember to add the users you want server socket access disabled for to ++ the GID specified here. If the sysctl option is enabled, a sysctl ++ option with name "socket_server_gid" is created. ++ ++endmenu ++menu "Sysctl support" ++depends on GRKERNSEC && SYSCTL ++ ++config GRKERNSEC_SYSCTL ++ bool "Sysctl support" ++ help ++ If you say Y here, you will be able to change the options that ++ grsecurity runs with at bootup, without having to recompile your ++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity ++ to enable (1) or disable (0) various features. All the sysctl entries ++ are mutable until the "grsec_lock" entry is set to a non-zero value. ++ All features enabled in the kernel configuration are disabled at boot ++ if you do not say Y to the "Turn on features by default" option. ++ All options should be set at startup, and the grsec_lock entry should ++ be set to a non-zero value after all the options are set. ++ *THIS IS EXTREMELY IMPORTANT* ++ ++config GRKERNSEC_SYSCTL_ON ++ bool "Turn on features by default" ++ depends on GRKERNSEC_SYSCTL ++ help ++ If you say Y here, instead of having all features enabled in the ++ kernel configuration disabled at boot time, the features will be ++ enabled at boot time. It is recommended you say Y here unless ++ there is some reason you would want all sysctl-tunable features to ++ be disabled by default. As mentioned elsewhere, it is important ++ to enable the grsec_lock entry once you have finished modifying ++ the sysctl entries. ++ ++endmenu ++menu "Logging Options" ++depends on GRKERNSEC ++ ++config GRKERNSEC_FLOODTIME ++ int "Seconds in between log messages (minimum)" ++ default 10 ++ help ++ This option allows you to enforce the number of seconds between ++ grsecurity log messages. The default should be suitable for most ++ people, however, if you choose to change it, choose a value small enough ++ to allow informative logs to be produced, but large enough to ++ prevent flooding. ++ ++config GRKERNSEC_FLOODBURST ++ int "Number of messages in a burst (maximum)" ++ default 4 ++ help ++ This option allows you to choose the maximum number of messages allowed ++ within the flood time interval you chose in a separate option. The ++ default should be suitable for most people, however if you find that ++ many of your logs are being interpreted as flooding, you may want to ++ raise this value. ++ ++endmenu ++ ++endmenu +diff -urNp linux-2.6.31.1/grsecurity/Makefile linux-2.6.31.1/grsecurity/Makefile +--- linux-2.6.31.1/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/grsecurity/Makefile 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,29 @@ ++# grsecurity's ACL system was originally written in 2001 by Michael Dalton ++# during 2001-2009 it has been completely redesigned by Brad Spengler ++# into an RBAC system ++# ++# All code in this directory and various hooks inserted throughout the kernel ++# are copyright Brad Spengler - Open Source Security, Inc., and released ++# under the GPL v2 or higher ++ ++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \ ++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \ ++ grsec_time.o grsec_tpe.o grsec_link.o grsec_textrel.o ++ ++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \ ++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \ ++ gracl_learn.o grsec_log.o ++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o ++ ++ifndef CONFIG_GRKERNSEC ++obj-y += grsec_disabled.o ++endif ++ ++ifdef CONFIG_GRKERNSEC_HIDESYM ++extra-y := grsec_hidesym.o ++$(obj)/grsec_hidesym.o: ++ @-chmod -f 500 /boot ++ @-chmod -f 500 /lib/modules ++ @-chmod -f 700 . ++ @echo ' grsec: protected kernel image paths' ++endif +diff -urNp linux-2.6.31.1/include/asm-generic/atomic.h linux-2.6.31.1/include/asm-generic/atomic.h +--- linux-2.6.31.1/include/asm-generic/atomic.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/asm-generic/atomic.h 2009-10-01 20:12:44.000000000 -0400 +@@ -36,6 +36,15 @@ + #define atomic_read(v) ((v)->counter) + + /** ++ * atomic_read_unchecked - read atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * ++ * Atomically reads the value of @v. Note that the guaranteed ++ * useful range of an atomic_unchecked_t is only 24 bits. ++ */ ++#define atomic_read_unchecked(v) ((v)->counter) ++ ++/** + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value +@@ -45,6 +54,16 @@ + */ + #define atomic_set(v, i) (((v)->counter) = (i)) + ++/** ++ * atomic_set_unchecked - set atomic variable ++ * @v: pointer of type atomic_unchecked_t ++ * @i: required value ++ * ++ * Atomically sets the value of @v to @i. Note that the guaranteed ++ * useful range of an atomic_unchecked_t is only 24 bits. ++ */ ++#define atomic_set_unchecked(v, i) (((v)->counter) = (i)) ++ + #include <asm/system.h> + + /** +@@ -101,16 +120,31 @@ static inline void atomic_add(int i, ato + atomic_add_return(i, v); + } + ++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_add_return(i, (atomic_t *)v); ++} ++ + static inline void atomic_sub(int i, atomic_t *v) + { + atomic_sub_return(i, v); + } + ++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v) ++{ ++ atomic_sub_return(i, (atomic_t *)v); ++} ++ + static inline void atomic_inc(atomic_t *v) + { + atomic_add_return(1, v); + } + ++static inline void atomic_inc_unchecked(atomic_unchecked_t *v) ++{ ++ atomic_add_return(1, (atomic_t *)v); ++} ++ + static inline void atomic_dec(atomic_t *v) + { + atomic_sub_return(1, v); +diff -urNp linux-2.6.31.1/include/asm-generic/futex.h linux-2.6.31.1/include/asm-generic/futex.h +--- linux-2.6.31.1/include/asm-generic/futex.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/asm-generic/futex.h 2009-10-01 20:12:44.000000000 -0400 +@@ -6,7 +6,7 @@ + #include <asm/errno.h> + + static inline int +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) + { + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; +@@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op, + } + + static inline int +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval) + { + return -ENOSYS; + } +diff -urNp linux-2.6.31.1/include/asm-generic/int-l64.h linux-2.6.31.1/include/asm-generic/int-l64.h +--- linux-2.6.31.1/include/asm-generic/int-l64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/asm-generic/int-l64.h 2009-10-01 20:12:44.000000000 -0400 +@@ -46,6 +46,8 @@ typedef unsigned int u32; + typedef signed long s64; + typedef unsigned long u64; + ++typedef unsigned int intoverflow_t __attribute__ ((mode(TI))); ++ + #define S8_C(x) x + #define U8_C(x) x ## U + #define S16_C(x) x +diff -urNp linux-2.6.31.1/include/asm-generic/int-ll64.h linux-2.6.31.1/include/asm-generic/int-ll64.h +--- linux-2.6.31.1/include/asm-generic/int-ll64.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/asm-generic/int-ll64.h 2009-10-01 20:12:44.000000000 -0400 +@@ -51,6 +51,8 @@ typedef unsigned int u32; + typedef signed long long s64; + typedef unsigned long long u64; + ++typedef unsigned long long intoverflow_t; ++ + #define S8_C(x) x + #define U8_C(x) x ## U + #define S16_C(x) x +diff -urNp linux-2.6.31.1/include/asm-generic/kmap_types.h linux-2.6.31.1/include/asm-generic/kmap_types.h +--- linux-2.6.31.1/include/asm-generic/kmap_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/asm-generic/kmap_types.h 2009-10-01 20:12:44.000000000 -0400 +@@ -27,7 +27,8 @@ D(15) KM_UML_USERCOPY, /* UML specific, + D(16) KM_IRQ_PTE, + D(17) KM_NMI, + D(18) KM_NMI_PTE, +-D(19) KM_TYPE_NR ++D(19) KM_CLEARPAGE, ++D(20) KM_TYPE_NR + }; + + #undef D +diff -urNp linux-2.6.31.1/include/asm-generic/vmlinux.lds.h linux-2.6.31.1/include/asm-generic/vmlinux.lds.h +--- linux-2.6.31.1/include/asm-generic/vmlinux.lds.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/asm-generic/vmlinux.lds.h 2009-10-01 20:12:44.000000000 -0400 +@@ -201,6 +201,7 @@ + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start_rodata) = .; \ + *(.rodata) *(.rodata.*) \ ++ *(.data.read_only) \ + *(__vermagic) /* Kernel version magic */ \ + *(__markers_strings) /* Markers: strings */ \ + *(__tracepoints_strings)/* Tracepoints: strings */ \ +@@ -641,22 +642,24 @@ + * section in the linker script will go there too. @phdr should have + * a leading colon. + * +- * Note that this macros defines __per_cpu_load as an absolute symbol. ++ * Note that this macros defines per_cpu_load as an absolute symbol. + * If there is no need to put the percpu section at a predetermined + * address, use PERCPU(). + */ + #define PERCPU_VADDR(vaddr, phdr) \ +- VMLINUX_SYMBOL(__per_cpu_load) = .; \ +- .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \ ++ per_cpu_load = .; \ ++ .data.percpu vaddr : AT(VMLINUX_SYMBOL(per_cpu_load) \ + - LOAD_OFFSET) { \ ++ VMLINUX_SYMBOL(__per_cpu_load) = . + per_cpu_load; \ + VMLINUX_SYMBOL(__per_cpu_start) = .; \ + *(.data.percpu.first) \ +- *(.data.percpu.page_aligned) \ + *(.data.percpu) \ ++ . = ALIGN(PAGE_SIZE); \ ++ *(.data.percpu.page_aligned) \ + *(.data.percpu.shared_aligned) \ + VMLINUX_SYMBOL(__per_cpu_end) = .; \ + } phdr \ +- . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu); ++ . = VMLINUX_SYMBOL(per_cpu_load) + SIZEOF(.data.percpu); + + /** + * PERCPU - define output section for percpu area, simple version +diff -urNp linux-2.6.31.1/include/drm/drm_pciids.h linux-2.6.31.1/include/drm/drm_pciids.h +--- linux-2.6.31.1/include/drm/drm_pciids.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/drm/drm_pciids.h 2009-10-01 20:12:44.000000000 -0400 +@@ -375,7 +375,7 @@ + {0x1002, 0x9712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define r128_PCI_IDS \ + {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +@@ -415,14 +415,14 @@ + {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define mga_PCI_IDS \ + {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \ + {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \ + {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \ + {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define mach64_PCI_IDS \ + {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +@@ -445,7 +445,7 @@ + {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define sisdrv_PCI_IDS \ + {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +@@ -456,7 +456,7 @@ + {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ + {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define tdfx_PCI_IDS \ + {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +@@ -465,7 +465,7 @@ + {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define viadrv_PCI_IDS \ + {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +@@ -477,14 +477,14 @@ + {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \ + {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define i810_PCI_IDS \ + {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define i830_PCI_IDS \ + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +@@ -492,11 +492,11 @@ + {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x358e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define gamma_PCI_IDS \ + {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define savage_PCI_IDS \ + {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \ +@@ -522,10 +522,10 @@ + {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \ + {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \ + {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define ffb_PCI_IDS \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} + + #define i915_PCI_IDS \ + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ +@@ -557,4 +557,4 @@ + {0x8086, 0x35e8, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0x0042, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0x0046, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ +- {0, 0, 0} ++ {0, 0, 0, 0, 0, 0} +diff -urNp linux-2.6.31.1/include/drm/drmP.h linux-2.6.31.1/include/drm/drmP.h +--- linux-2.6.31.1/include/drm/drmP.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/drm/drmP.h 2009-10-01 20:12:44.000000000 -0400 +@@ -787,7 +787,7 @@ struct drm_driver { + void (*gem_free_object) (struct drm_gem_object *obj); + + /* Driver private ops for this object */ +- struct vm_operations_struct *gem_vm_ops; ++ const struct vm_operations_struct *gem_vm_ops; + + int major; + int minor; +@@ -890,7 +890,7 @@ struct drm_device { + + /** \name Usage Counters */ + /*@{ */ +- int open_count; /**< Outstanding files open */ ++ atomic_t open_count; /**< Outstanding files open */ + atomic_t ioctl_count; /**< Outstanding IOCTLs pending */ + atomic_t vma_count; /**< Outstanding vma areas open */ + int buf_use; /**< Buffers in use -- cannot alloc */ +@@ -901,7 +901,7 @@ struct drm_device { + /*@{ */ + unsigned long counters; + enum drm_stat_type types[15]; +- atomic_t counts[15]; ++ atomic_unchecked_t counts[15]; + /*@} */ + + struct list_head filelist; +diff -urNp linux-2.6.31.1/include/linux/agp_backend.h linux-2.6.31.1/include/linux/agp_backend.h +--- linux-2.6.31.1/include/linux/agp_backend.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/agp_backend.h 2009-10-01 20:12:44.000000000 -0400 +@@ -53,7 +53,7 @@ struct agp_kern_info { + int current_memory; + bool cant_use_aperture; + unsigned long page_mask; +- struct vm_operations_struct *vm_ops; ++ const struct vm_operations_struct *vm_ops; + }; + + /* +diff -urNp linux-2.6.31.1/include/linux/a.out.h linux-2.6.31.1/include/linux/a.out.h +--- linux-2.6.31.1/include/linux/a.out.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/a.out.h 2009-10-01 20:12:44.000000000 -0400 +@@ -39,6 +39,14 @@ enum machine_type { + M_MIPS2 = 152 /* MIPS R6000/R4000 binary */ + }; + ++/* Constants for the N_FLAGS field */ ++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ ++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */ ++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */ ++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */ ++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */ ++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ ++ + #if !defined (N_MAGIC) + #define N_MAGIC(exec) ((exec).a_info & 0xffff) + #endif +diff -urNp linux-2.6.31.1/include/linux/atmdev.h linux-2.6.31.1/include/linux/atmdev.h +--- linux-2.6.31.1/include/linux/atmdev.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/atmdev.h 2009-10-01 20:12:44.000000000 -0400 +@@ -237,7 +237,7 @@ struct compat_atm_iobuf { + #endif + + struct k_atm_aal_stats { +-#define __HANDLE_ITEM(i) atomic_t i ++#define __HANDLE_ITEM(i) atomic_unchecked_t i + __AAL_STAT_ITEMS + #undef __HANDLE_ITEM + }; +diff -urNp linux-2.6.31.1/include/linux/binfmts.h linux-2.6.31.1/include/linux/binfmts.h +--- linux-2.6.31.1/include/linux/binfmts.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/binfmts.h 2009-10-01 20:12:44.000000000 -0400 +@@ -78,6 +78,7 @@ struct linux_binfmt { + int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); + int (*load_shlib)(struct file *); + int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); ++ void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags); + unsigned long min_coredump; /* minimal dump size */ + int hasvdso; + }; +diff -urNp linux-2.6.31.1/include/linux/cache.h linux-2.6.31.1/include/linux/cache.h +--- linux-2.6.31.1/include/linux/cache.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/cache.h 2009-10-01 20:12:44.000000000 -0400 +@@ -16,6 +16,10 @@ + #define __read_mostly + #endif + ++#ifndef __read_only ++#define __read_only __read_mostly ++#endif ++ + #ifndef ____cacheline_aligned + #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES))) + #endif +diff -urNp linux-2.6.31.1/include/linux/capability.h linux-2.6.31.1/include/linux/capability.h +--- linux-2.6.31.1/include/linux/capability.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/capability.h 2009-10-01 20:12:44.000000000 -0400 +@@ -563,6 +563,7 @@ extern const kernel_cap_t __cap_init_eff + (security_real_capable_noaudit((t), (cap)) == 0) + + extern int capable(int cap); ++int capable_nolog(int cap); + + /* audit system wants to get cap info from files as well */ + struct dentry; +diff -urNp linux-2.6.31.1/include/linux/cgroup.h linux-2.6.31.1/include/linux/cgroup.h +--- linux-2.6.31.1/include/linux/cgroup.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/cgroup.h 2009-10-01 20:12:44.000000000 -0400 +@@ -37,7 +37,7 @@ extern void cgroup_exit(struct task_stru + extern int cgroupstats_build(struct cgroupstats *stats, + struct dentry *dentry); + +-extern struct file_operations proc_cgroup_operations; ++extern const struct file_operations proc_cgroup_operations; + + /* Define the enumeration of all cgroup subsystems */ + #define SUBSYS(_x) _x ## _subsys_id, +diff -urNp linux-2.6.31.1/include/linux/compiler-gcc4.h linux-2.6.31.1/include/linux/compiler-gcc4.h +--- linux-2.6.31.1/include/linux/compiler-gcc4.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/compiler-gcc4.h 2009-10-01 20:12:44.000000000 -0400 +@@ -36,4 +36,8 @@ + the kernel context */ + #define __cold __attribute__((__cold__)) + ++#define __alloc_size(...) __attribute((alloc_size(__VA_ARGS__))) ++#define __bos(ptr, arg) __builtin_object_size((ptr), (arg)) ++#define __bos0(ptr) __bos((ptr), 0) ++#define __bos1(ptr) __bos((ptr), 1) + #endif +diff -urNp linux-2.6.31.1/include/linux/compiler.h linux-2.6.31.1/include/linux/compiler.h +--- linux-2.6.31.1/include/linux/compiler.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/compiler.h 2009-10-01 20:12:44.000000000 -0400 +@@ -256,6 +256,22 @@ void ftrace_likely_update(struct ftrace_ + #define __cold + #endif + ++#ifndef __alloc_size ++#define __alloc_size ++#endif ++ ++#ifndef __bos ++#define __bos ++#endif ++ ++#ifndef __bos0 ++#define __bos0 ++#endif ++ ++#ifndef __bos1 ++#define __bos1 ++#endif ++ + /* Simple shorthand for a section definition */ + #ifndef __section + # define __section(S) __attribute__ ((__section__(#S))) +diff -urNp linux-2.6.31.1/include/linux/cpumask.h linux-2.6.31.1/include/linux/cpumask.h +--- linux-2.6.31.1/include/linux/cpumask.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/cpumask.h 2009-10-01 20:12:44.000000000 -0400 +@@ -142,7 +142,6 @@ + #include <linux/bitmap.h> + + typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; +-extern cpumask_t _unused_cpumask_arg_; + + #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS + #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst)) +diff -urNp linux-2.6.31.1/include/linux/decompress/mm.h linux-2.6.31.1/include/linux/decompress/mm.h +--- linux-2.6.31.1/include/linux/decompress/mm.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/decompress/mm.h 2009-10-01 20:12:44.000000000 -0400 +@@ -68,7 +68,7 @@ static void free(void *where) + * warnings when not needed (indeed large_malloc / large_free are not + * needed by inflate */ + +-#define malloc(a) kmalloc(a, GFP_KERNEL) ++#define malloc(a) kmalloc((a), GFP_KERNEL) + #define free(a) kfree(a) + + #define large_malloc(a) vmalloc(a) +diff -urNp linux-2.6.31.1/include/linux/elf.h linux-2.6.31.1/include/linux/elf.h +--- linux-2.6.31.1/include/linux/elf.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/elf.h 2009-10-01 20:12:44.000000000 -0400 +@@ -49,6 +49,17 @@ typedef __s64 Elf64_Sxword; + #define PT_GNU_EH_FRAME 0x6474e550 + + #define PT_GNU_STACK (PT_LOOS + 0x474e551) ++#define PT_GNU_RELRO (PT_LOOS + 0x474e552) ++ ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580) ++ ++/* Constants for the e_flags field */ ++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ ++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */ ++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */ ++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */ ++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */ ++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ + + /* These constants define the different elf file types */ + #define ET_NONE 0 +@@ -84,6 +95,8 @@ typedef __s64 Elf64_Sxword; + #define DT_DEBUG 21 + #define DT_TEXTREL 22 + #define DT_JMPREL 23 ++#define DT_FLAGS 30 ++ #define DF_TEXTREL 0x00000004 + #define DT_ENCODING 32 + #define OLD_DT_LOOS 0x60000000 + #define DT_LOOS 0x6000000d +@@ -230,6 +243,19 @@ typedef struct elf64_hdr { + #define PF_W 0x2 + #define PF_X 0x1 + ++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */ ++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */ ++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */ ++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */ ++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */ ++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */ ++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */ ++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */ ++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */ ++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */ ++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */ ++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */ ++ + typedef struct elf32_phdr{ + Elf32_Word p_type; + Elf32_Off p_offset; +@@ -322,6 +348,8 @@ typedef struct elf64_shdr { + #define EI_OSABI 7 + #define EI_PAD 8 + ++#define EI_PAX 14 ++ + #define ELFMAG0 0x7f /* EI_MAG */ + #define ELFMAG1 'E' + #define ELFMAG2 'L' +@@ -385,6 +413,7 @@ extern Elf32_Dyn _DYNAMIC []; + #define elf_phdr elf32_phdr + #define elf_note elf32_note + #define elf_addr_t Elf32_Off ++#define elf_dyn Elf32_Dyn + + #else + +@@ -393,6 +422,7 @@ extern Elf64_Dyn _DYNAMIC []; + #define elf_phdr elf64_phdr + #define elf_note elf64_note + #define elf_addr_t Elf64_Off ++#define elf_dyn Elf64_Dyn + + #endif + +diff -urNp linux-2.6.31.1/include/linux/fs.h linux-2.6.31.1/include/linux/fs.h +--- linux-2.6.31.1/include/linux/fs.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/fs.h 2009-10-01 20:12:44.000000000 -0400 +@@ -87,6 +87,10 @@ struct inodes_stat_t { + */ + #define FMODE_NOCMTIME ((__force fmode_t)2048) + ++/* Hack for grsec so as not to require read permission simply to execute ++ a binary */ ++#define FMODE_GREXEC ((__force fmode_t)8192) ++ + /* + * The below are the various read and write types that we support. Some of + * them include behavioral modifiers that send information down to the +@@ -2430,7 +2434,7 @@ static int __fops ## _open(struct inode + __simple_attr_check_format(__fmt, 0ull); \ + return simple_attr_open(inode, file, __get, __set, __fmt); \ + } \ +-static struct file_operations __fops = { \ ++static const struct file_operations __fops = { \ + .owner = THIS_MODULE, \ + .open = __fops ## _open, \ + .release = simple_attr_release, \ +diff -urNp linux-2.6.31.1/include/linux/fs_struct.h linux-2.6.31.1/include/linux/fs_struct.h +--- linux-2.6.31.1/include/linux/fs_struct.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/fs_struct.h 2009-10-01 20:12:44.000000000 -0400 +@@ -4,7 +4,7 @@ + #include <linux/path.h> + + struct fs_struct { +- int users; ++ atomic_t users; + rwlock_t lock; + int umask; + int in_exec; +diff -urNp linux-2.6.31.1/include/linux/genhd.h linux-2.6.31.1/include/linux/genhd.h +--- linux-2.6.31.1/include/linux/genhd.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/genhd.h 2009-10-01 20:12:44.000000000 -0400 +@@ -161,7 +161,7 @@ struct gendisk { + + struct timer_rand_state *random; + +- atomic_t sync_io; /* RAID */ ++ atomic_unchecked_t sync_io; /* RAID */ + struct work_struct async_notify; + #ifdef CONFIG_BLK_DEV_INTEGRITY + struct blk_integrity *integrity; +diff -urNp linux-2.6.31.1/include/linux/gracl.h linux-2.6.31.1/include/linux/gracl.h +--- linux-2.6.31.1/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/include/linux/gracl.h 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,318 @@ ++#ifndef GR_ACL_H ++#define GR_ACL_H ++ ++#include <linux/grdefs.h> ++#include <linux/resource.h> ++#include <linux/capability.h> ++#include <linux/dcache.h> ++#include <asm/resource.h> ++ ++/* Major status information */ ++ ++#define GR_VERSION "grsecurity 2.1.14" ++#define GRSECURITY_VERSION 0x2114 ++ ++enum { ++ GR_SHUTDOWN = 0, ++ GR_ENABLE = 1, ++ GR_SPROLE = 2, ++ GR_RELOAD = 3, ++ GR_SEGVMOD = 4, ++ GR_STATUS = 5, ++ GR_UNSPROLE = 6, ++ GR_PASSSET = 7, ++ GR_SPROLEPAM = 8, ++}; ++ ++/* Password setup definitions ++ * kernel/grhash.c */ ++enum { ++ GR_PW_LEN = 128, ++ GR_SALT_LEN = 16, ++ GR_SHA_LEN = 32, ++}; ++ ++enum { ++ GR_SPROLE_LEN = 64, ++}; ++ ++#define GR_NLIMITS 32 ++ ++/* Begin Data Structures */ ++ ++struct sprole_pw { ++ unsigned char *rolename; ++ unsigned char salt[GR_SALT_LEN]; ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */ ++}; ++ ++struct name_entry { ++ __u32 key; ++ ino_t inode; ++ dev_t device; ++ char *name; ++ __u16 len; ++ __u8 deleted; ++ struct name_entry *prev; ++ struct name_entry *next; ++}; ++ ++struct inodev_entry { ++ struct name_entry *nentry; ++ struct inodev_entry *prev; ++ struct inodev_entry *next; ++}; ++ ++struct acl_role_db { ++ struct acl_role_label **r_hash; ++ __u32 r_size; ++}; ++ ++struct inodev_db { ++ struct inodev_entry **i_hash; ++ __u32 i_size; ++}; ++ ++struct name_db { ++ struct name_entry **n_hash; ++ __u32 n_size; ++}; ++ ++struct crash_uid { ++ uid_t uid; ++ unsigned long expires; ++}; ++ ++struct gr_hash_struct { ++ void **table; ++ void **nametable; ++ void *first; ++ __u32 table_size; ++ __u32 used_size; ++ int type; ++}; ++ ++/* Userspace Grsecurity ACL data structures */ ++ ++struct acl_subject_label { ++ char *filename; ++ ino_t inode; ++ dev_t device; ++ __u32 mode; ++ kernel_cap_t cap_mask; ++ kernel_cap_t cap_lower; ++ ++ struct rlimit res[GR_NLIMITS]; ++ __u32 resmask; ++ ++ __u8 user_trans_type; ++ __u8 group_trans_type; ++ uid_t *user_transitions; ++ gid_t *group_transitions; ++ __u16 user_trans_num; ++ __u16 group_trans_num; ++ ++ __u32 ip_proto[8]; ++ __u32 ip_type; ++ struct acl_ip_label **ips; ++ __u32 ip_num; ++ __u32 inaddr_any_override; ++ ++ __u32 crashes; ++ unsigned long expires; ++ ++ struct acl_subject_label *parent_subject; ++ struct gr_hash_struct *hash; ++ struct acl_subject_label *prev; ++ struct acl_subject_label *next; ++ ++ struct acl_object_label **obj_hash; ++ __u32 obj_hash_size; ++ __u16 pax_flags; ++}; ++ ++struct role_allowed_ip { ++ __u32 addr; ++ __u32 netmask; ++ ++ struct role_allowed_ip *prev; ++ struct role_allowed_ip *next; ++}; ++ ++struct role_transition { ++ char *rolename; ++ ++ struct role_transition *prev; ++ struct role_transition *next; ++}; ++ ++struct acl_role_label { ++ char *rolename; ++ uid_t uidgid; ++ __u16 roletype; ++ ++ __u16 auth_attempts; ++ unsigned long expires; ++ ++ struct acl_subject_label *root_label; ++ struct gr_hash_struct *hash; ++ ++ struct acl_role_label *prev; ++ struct acl_role_label *next; ++ ++ struct role_transition *transitions; ++ struct role_allowed_ip *allowed_ips; ++ uid_t *domain_children; ++ __u16 domain_child_num; ++ ++ struct acl_subject_label **subj_hash; ++ __u32 subj_hash_size; ++}; ++ ++struct user_acl_role_db { ++ struct acl_role_label **r_table; ++ __u32 num_pointers; /* Number of allocations to track */ ++ __u32 num_roles; /* Number of roles */ ++ __u32 num_domain_children; /* Number of domain children */ ++ __u32 num_subjects; /* Number of subjects */ ++ __u32 num_objects; /* Number of objects */ ++}; ++ ++struct acl_object_label { ++ char *filename; ++ ino_t inode; ++ dev_t device; ++ __u32 mode; ++ ++ struct acl_subject_label *nested; ++ struct acl_object_label *globbed; ++ ++ /* next two structures not used */ ++ ++ struct acl_object_label *prev; ++ struct acl_object_label *next; ++}; ++ ++struct acl_ip_label { ++ char *iface; ++ __u32 addr; ++ __u32 netmask; ++ __u16 low, high; ++ __u8 mode; ++ __u32 type; ++ __u32 proto[8]; ++ ++ /* next two structures not used */ ++ ++ struct acl_ip_label *prev; ++ struct acl_ip_label *next; ++}; ++ ++struct gr_arg { ++ struct user_acl_role_db role_db; ++ unsigned char pw[GR_PW_LEN]; ++ unsigned char salt[GR_SALT_LEN]; ++ unsigned char sum[GR_SHA_LEN]; ++ unsigned char sp_role[GR_SPROLE_LEN]; ++ struct sprole_pw *sprole_pws; ++ dev_t segv_device; ++ ino_t segv_inode; ++ uid_t segv_uid; ++ __u16 num_sprole_pws; ++ __u16 mode; ++}; ++ ++struct gr_arg_wrapper { ++ struct gr_arg *arg; ++ __u32 version; ++ __u32 size; ++}; ++ ++struct subject_map { ++ struct acl_subject_label *user; ++ struct acl_subject_label *kernel; ++ struct subject_map *prev; ++ struct subject_map *next; ++}; ++ ++struct acl_subj_map_db { ++ struct subject_map **s_hash; ++ __u32 s_size; ++}; ++ ++/* End Data Structures Section */ ++ ++/* Hash functions generated by empirical testing by Brad Spengler ++ Makes good use of the low bits of the inode. Generally 0-1 times ++ in loop for successful match. 0-3 for unsuccessful match. ++ Shift/add algorithm with modulus of table size and an XOR*/ ++ ++static __inline__ unsigned int ++rhash(const uid_t uid, const __u16 type, const unsigned int sz) ++{ ++ return (((uid << type) + (uid ^ type)) % sz); ++} ++ ++ static __inline__ unsigned int ++shash(const struct acl_subject_label *userp, const unsigned int sz) ++{ ++ return ((const unsigned long)userp % sz); ++} ++ ++static __inline__ unsigned int ++fhash(const ino_t ino, const dev_t dev, const unsigned int sz) ++{ ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz); ++} ++ ++static __inline__ unsigned int ++nhash(const char *name, const __u16 len, const unsigned int sz) ++{ ++ return full_name_hash((const unsigned char *)name, len) % sz; ++} ++ ++#define FOR_EACH_ROLE_START(role,iter) \ ++ role = NULL; \ ++ iter = 0; \ ++ while (iter < acl_role_set.r_size) { \ ++ if (role == NULL) \ ++ role = acl_role_set.r_hash[iter]; \ ++ if (role == NULL) { \ ++ iter++; \ ++ continue; \ ++ } ++ ++#define FOR_EACH_ROLE_END(role,iter) \ ++ role = role->next; \ ++ if (role == NULL) \ ++ iter++; \ ++ } ++ ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \ ++ subj = NULL; \ ++ iter = 0; \ ++ while (iter < role->subj_hash_size) { \ ++ if (subj == NULL) \ ++ subj = role->subj_hash[iter]; \ ++ if (subj == NULL) { \ ++ iter++; \ ++ continue; \ ++ } ++ ++#define FOR_EACH_SUBJECT_END(subj,iter) \ ++ subj = subj->next; \ ++ if (subj == NULL) \ ++ iter++; \ ++ } ++ ++ ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \ ++ subj = role->hash->first; \ ++ while (subj != NULL) { ++ ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \ ++ subj = subj->next; \ ++ } ++ ++#endif ++ +diff -urNp linux-2.6.31.1/include/linux/gralloc.h linux-2.6.31.1/include/linux/gralloc.h +--- linux-2.6.31.1/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/include/linux/gralloc.h 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,9 @@ ++#ifndef __GRALLOC_H ++#define __GRALLOC_H ++ ++void acl_free_all(void); ++int acl_alloc_stack_init(unsigned long size); ++void *acl_alloc(unsigned long len); ++void *acl_alloc_num(unsigned long num, unsigned long len); ++ ++#endif +diff -urNp linux-2.6.31.1/include/linux/grdefs.h linux-2.6.31.1/include/linux/grdefs.h +--- linux-2.6.31.1/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/include/linux/grdefs.h 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,136 @@ ++#ifndef GRDEFS_H ++#define GRDEFS_H ++ ++/* Begin grsecurity status declarations */ ++ ++enum { ++ GR_READY = 0x01, ++ GR_STATUS_INIT = 0x00 // disabled state ++}; ++ ++/* Begin ACL declarations */ ++ ++/* Role flags */ ++ ++enum { ++ GR_ROLE_USER = 0x0001, ++ GR_ROLE_GROUP = 0x0002, ++ GR_ROLE_DEFAULT = 0x0004, ++ GR_ROLE_SPECIAL = 0x0008, ++ GR_ROLE_AUTH = 0x0010, ++ GR_ROLE_NOPW = 0x0020, ++ GR_ROLE_GOD = 0x0040, ++ GR_ROLE_LEARN = 0x0080, ++ GR_ROLE_TPE = 0x0100, ++ GR_ROLE_DOMAIN = 0x0200, ++ GR_ROLE_PAM = 0x0400 ++}; ++ ++/* ACL Subject and Object mode flags */ ++enum { ++ GR_DELETED = 0x80000000 ++}; ++ ++/* ACL Object-only mode flags */ ++enum { ++ GR_READ = 0x00000001, ++ GR_APPEND = 0x00000002, ++ GR_WRITE = 0x00000004, ++ GR_EXEC = 0x00000008, ++ GR_FIND = 0x00000010, ++ GR_INHERIT = 0x00000020, ++ GR_SETID = 0x00000040, ++ GR_CREATE = 0x00000080, ++ GR_DELETE = 0x00000100, ++ GR_LINK = 0x00000200, ++ GR_AUDIT_READ = 0x00000400, ++ GR_AUDIT_APPEND = 0x00000800, ++ GR_AUDIT_WRITE = 0x00001000, ++ GR_AUDIT_EXEC = 0x00002000, ++ GR_AUDIT_FIND = 0x00004000, ++ GR_AUDIT_INHERIT= 0x00008000, ++ GR_AUDIT_SETID = 0x00010000, ++ GR_AUDIT_CREATE = 0x00020000, ++ GR_AUDIT_DELETE = 0x00040000, ++ GR_AUDIT_LINK = 0x00080000, ++ GR_PTRACERD = 0x00100000, ++ GR_NOPTRACE = 0x00200000, ++ GR_SUPPRESS = 0x00400000, ++ GR_NOLEARN = 0x00800000 ++}; ++ ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \ ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \ ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK) ++ ++/* ACL subject-only mode flags */ ++enum { ++ GR_KILL = 0x00000001, ++ GR_VIEW = 0x00000002, ++ GR_PROTECTED = 0x00000004, ++ GR_LEARN = 0x00000008, ++ GR_OVERRIDE = 0x00000010, ++ /* just a placeholder, this mode is only used in userspace */ ++ GR_DUMMY = 0x00000020, ++ GR_PROTSHM = 0x00000040, ++ GR_KILLPROC = 0x00000080, ++ GR_KILLIPPROC = 0x00000100, ++ /* just a placeholder, this mode is only used in userspace */ ++ GR_NOTROJAN = 0x00000200, ++ GR_PROTPROCFD = 0x00000400, ++ GR_PROCACCT = 0x00000800, ++ GR_RELAXPTRACE = 0x00001000, ++ GR_NESTED = 0x00002000, ++ GR_INHERITLEARN = 0x00004000, ++ GR_PROCFIND = 0x00008000, ++ GR_POVERRIDE = 0x00010000, ++ GR_KERNELAUTH = 0x00020000, ++}; ++ ++enum { ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001, ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002, ++ GR_PAX_ENABLE_MPROTECT = 0x0004, ++ GR_PAX_ENABLE_RANDMMAP = 0x0008, ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010, ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100, ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200, ++ GR_PAX_DISABLE_MPROTECT = 0x0400, ++ GR_PAX_DISABLE_RANDMMAP = 0x0800, ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000, ++}; ++ ++enum { ++ GR_ID_USER = 0x01, ++ GR_ID_GROUP = 0x02, ++}; ++ ++enum { ++ GR_ID_ALLOW = 0x01, ++ GR_ID_DENY = 0x02, ++}; ++ ++#define GR_CRASH_RES 31 ++#define GR_UIDTABLE_MAX 500 ++ ++/* begin resource learning section */ ++enum { ++ GR_RLIM_CPU_BUMP = 60, ++ GR_RLIM_FSIZE_BUMP = 50000, ++ GR_RLIM_DATA_BUMP = 10000, ++ GR_RLIM_STACK_BUMP = 1000, ++ GR_RLIM_CORE_BUMP = 10000, ++ GR_RLIM_RSS_BUMP = 500000, ++ GR_RLIM_NPROC_BUMP = 1, ++ GR_RLIM_NOFILE_BUMP = 5, ++ GR_RLIM_MEMLOCK_BUMP = 50000, ++ GR_RLIM_AS_BUMP = 500000, ++ GR_RLIM_LOCKS_BUMP = 2, ++ GR_RLIM_SIGPENDING_BUMP = 5, ++ GR_RLIM_MSGQUEUE_BUMP = 10000, ++ GR_RLIM_NICE_BUMP = 1, ++ GR_RLIM_RTPRIO_BUMP = 1, ++ GR_RLIM_RTTIME_BUMP = 1000000 ++}; ++ ++#endif +diff -urNp linux-2.6.31.1/include/linux/grinternal.h linux-2.6.31.1/include/linux/grinternal.h +--- linux-2.6.31.1/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/include/linux/grinternal.h 2009-10-01 21:50:27.000000000 -0400 +@@ -0,0 +1,211 @@ ++#ifndef __GRINTERNAL_H ++#define __GRINTERNAL_H ++ ++#ifdef CONFIG_GRKERNSEC ++ ++#include <linux/fs.h> ++#include <linux/mnt_namespace.h> ++#include <linux/nsproxy.h> ++#include <linux/gracl.h> ++#include <linux/grdefs.h> ++#include <linux/grmsg.h> ++ ++void gr_add_learn_entry(const char *fmt, ...) ++ __attribute__ ((format (printf, 1, 2))); ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode, ++ const struct vfsmount *mnt); ++__u32 gr_check_create(const struct dentry *new_dentry, ++ const struct dentry *parent, ++ const struct vfsmount *mnt, const __u32 mode); ++int gr_check_protected_task(const struct task_struct *task); ++__u32 to_gr_audit(const __u32 reqmode); ++int gr_set_acls(const int type); ++ ++int gr_acl_is_enabled(void); ++char gr_roletype_to_char(void); ++ ++void gr_handle_alertkill(struct task_struct *task); ++char *gr_to_filename(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++char *gr_to_filename1(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++char *gr_to_filename2(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++char *gr_to_filename3(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++ ++extern int grsec_enable_harden_ptrace; ++extern int grsec_enable_link; ++extern int grsec_enable_fifo; ++extern int grsec_enable_execve; ++extern int grsec_enable_shm; ++extern int grsec_enable_execlog; ++extern int grsec_enable_signal; ++extern int grsec_enable_forkfail; ++extern int grsec_enable_time; ++extern int grsec_enable_chroot_shmat; ++extern int grsec_enable_chroot_findtask; ++extern int grsec_enable_chroot_mount; ++extern int grsec_enable_chroot_double; ++extern int grsec_enable_chroot_pivot; ++extern int grsec_enable_chroot_chdir; ++extern int grsec_enable_chroot_chmod; ++extern int grsec_enable_chroot_mknod; ++extern int grsec_enable_chroot_fchdir; ++extern int grsec_enable_chroot_nice; ++extern int grsec_enable_chroot_execlog; ++extern int grsec_enable_chroot_caps; ++extern int grsec_enable_chroot_sysctl; ++extern int grsec_enable_chroot_unix; ++extern int grsec_enable_tpe; ++extern int grsec_tpe_gid; ++extern int grsec_enable_tpe_all; ++extern int grsec_enable_sidcaps; ++extern int grsec_enable_socket_all; ++extern int grsec_socket_all_gid; ++extern int grsec_enable_socket_client; ++extern int grsec_socket_client_gid; ++extern int grsec_enable_socket_server; ++extern int grsec_socket_server_gid; ++extern int grsec_audit_gid; ++extern int grsec_enable_group; ++extern int grsec_enable_audit_textrel; ++extern int grsec_enable_mount; ++extern int grsec_enable_chdir; ++extern int grsec_resource_logging; ++extern int grsec_lock; ++ ++extern spinlock_t grsec_alert_lock; ++extern unsigned long grsec_alert_wtime; ++extern unsigned long grsec_alert_fyet; ++ ++extern spinlock_t grsec_audit_lock; ++ ++extern rwlock_t grsec_exec_file_lock; ++ ++#define gr_task_fullpath(tsk) (tsk->exec_file ? \ ++ gr_to_filename2(tsk->exec_file->f_path.dentry, \ ++ tsk->exec_file->f_vfsmnt) : "/") ++ ++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \ ++ gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \ ++ tsk->parent->exec_file->f_vfsmnt) : "/") ++ ++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \ ++ gr_to_filename(tsk->exec_file->f_path.dentry, \ ++ tsk->exec_file->f_vfsmnt) : "/") ++ ++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \ ++ gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \ ++ tsk->parent->exec_file->f_vfsmnt) : "/") ++ ++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \ ++ ((init_task.fs->root.dentry != tsk_a->fs->root.dentry) && \ ++ (tsk_a->nsproxy->mnt_ns->root->mnt_root != \ ++ tsk_a->fs->root.dentry))) ++ ++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \ ++ (tsk_a->fs->root.dentry == tsk_b->fs->root.dentry)) ++ ++#define DEFAULTSECARGS(task, cred, pcred) gr_task_fullpath(task), task->comm, \ ++ task->pid, cred->uid, \ ++ cred->euid, cred->gid, cred->egid, \ ++ gr_parent_task_fullpath(task), \ ++ task->parent->comm, task->parent->pid, \ ++ pcred->uid, pcred->euid, \ ++ pcred->gid, pcred->egid ++ ++#define GR_CHROOT_CAPS {{ \ ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \ ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \ ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \ ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \ ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \ ++ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }} ++ ++#define security_learn(normal_msg,args...) \ ++({ \ ++ read_lock(&grsec_exec_file_lock); \ ++ gr_add_learn_entry(normal_msg "\n", ## args); \ ++ read_unlock(&grsec_exec_file_lock); \ ++}) ++ ++enum { ++ GR_DO_AUDIT, ++ GR_DONT_AUDIT, ++ GR_DONT_AUDIT_GOOD ++}; ++ ++enum { ++ GR_TTYSNIFF, ++ GR_RBAC, ++ GR_RBAC_STR, ++ GR_STR_RBAC, ++ GR_RBAC_MODE2, ++ GR_RBAC_MODE3, ++ GR_FILENAME, ++ GR_SYSCTL_HIDDEN, ++ GR_NOARGS, ++ GR_ONE_INT, ++ GR_ONE_INT_TWO_STR, ++ GR_ONE_STR, ++ GR_STR_INT, ++ GR_TWO_INT, ++ GR_THREE_INT, ++ GR_FIVE_INT_TWO_STR, ++ GR_TWO_STR, ++ GR_THREE_STR, ++ GR_FOUR_STR, ++ GR_STR_FILENAME, ++ GR_FILENAME_STR, ++ GR_FILENAME_TWO_INT, ++ GR_FILENAME_TWO_INT_STR, ++ GR_TEXTREL, ++ GR_PTRACE, ++ GR_RESOURCE, ++ GR_CAP, ++ GR_SIG, ++ GR_SIG2, ++ GR_CRASH1, ++ GR_CRASH2, ++ GR_PSACCT ++}; ++ ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str) ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task) ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt) ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str) ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt) ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2) ++#define gr_log_fs_rbac_mode3(audit, msg, dentry, mnt, str1, str2, str3) gr_log_varargs(audit, msg, GR_RBAC_MODE3, dentry, mnt, str1, str2, str3) ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt) ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS) ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num) ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2) ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str) ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num) ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2) ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3) ++#define gr_log_int5_str2(audit, msg, num1, num2, str1, str2) gr_log_varargs(audit, msg, GR_FIVE_INT_TWO_STR, num1, num2, str1, str2) ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2) ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3) ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4) ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt) ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str) ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2) ++#define gr_log_fs_int2_str(audit, msg, dentry, mnt, num1, num2, str) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT_STR, dentry, mnt, num1, num2, str) ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2) ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task) ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2) ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str) ++#define gr_log_sig_addr(audit, msg, str, addr) gr_log_varargs(audit, msg, GR_SIG, str, addr) ++#define gr_log_sig_task(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG2, task, num) ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong) ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1) ++#define gr_log_procacct(audit, msg, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) gr_log_varargs(audit, msg, GR_PSACCT, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) ++ ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...); ++ ++#endif ++ ++#endif +diff -urNp linux-2.6.31.1/include/linux/grmsg.h linux-2.6.31.1/include/linux/grmsg.h +--- linux-2.6.31.1/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/include/linux/grmsg.h 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,103 @@ ++#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u" ++#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u" ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " ++#define GR_STOPMOD_MSG "denied modification of module state by " ++#define GR_IOPERM_MSG "denied use of ioperm() by " ++#define GR_IOPL_MSG "denied use of iopl() by " ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by " ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " ++#define GR_KMEM_MSG "denied write of /dev/kmem by " ++#define GR_PORT_OPEN_MSG "denied open of /dev/port by " ++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by " ++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by " ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " ++#define GR_LEARN_AUDIT_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%lu\t%lu\t%.4095s\t%lu\t%u.%u.%u.%u" ++#define GR_ID_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%c\t%d\t%d\t%d\t%u.%u.%u.%u" ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by " ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by " ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against " ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " ++#define GR_NPROC_MSG "denied overstep of process limit by " ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by " ++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds" ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds" ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by " ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by " ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by " ++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by " ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by " ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " ++#define GR_INITF_ACL_MSG "init_variables() failed %s by " ++#define GR_DISABLED_ACL_MSG "Error loading %s, trying to run kernel with acls disabled. To disable acls at startup use <kernel image name> gracl=off from your boot loader" ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by " ++#define GR_SHUTS_ACL_MSG "shutdown auth success for " ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for " ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by " ++#define GR_ENABLEF_ACL_MSG "unable to load %s for " ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system" ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by " ++#define GR_RELOADF_ACL_MSG "failed reload of %s for " ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for " ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " ++#define GR_SPROLEF_ACL_MSG "special role %s failure for " ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for " ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " ++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " ++#define GR_INVMODE_ACL_MSG "invalid mode %d by " ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by " ++#define GR_FAILFORK_MSG "failed fork with errno %d by " ++#define GR_NICE_CHROOT_MSG "denied priority change by " ++#define GR_UNISIGLOG_MSG "%.32s occurred at %p in " ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by " ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by " ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " ++#define GR_TIME_MSG "time set by " ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by " ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by " ++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by " ++#define GR_BIND_MSG "denied bind() by " ++#define GR_CONNECT_MSG "denied connect() by " ++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " ++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " ++#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%u.%u.%u.%u\t%u\t%u\t%u\t%u\t%u.%u.%u.%u" ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " ++#define GR_CAP_ACL_MSG "use of %s denied for " ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for " ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for " ++#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by " ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by " ++#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by " ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by " ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for " ++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " ++#define GR_NONROOT_MODLOAD_MSG "denied kernel module auto-load of %.64s by " +diff -urNp linux-2.6.31.1/include/linux/grsecurity.h linux-2.6.31.1/include/linux/grsecurity.h +--- linux-2.6.31.1/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/include/linux/grsecurity.h 2009-10-01 20:12:44.000000000 -0400 +@@ -0,0 +1,197 @@ ++#ifndef GR_SECURITY_H ++#define GR_SECURITY_H ++#include <linux/fs.h> ++#include <linux/fs_struct.h> ++#include <linux/binfmts.h> ++#include <linux/gracl.h> ++ ++/* notify of brain-dead configs */ ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) ++#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled." ++#endif ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS) ++#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled." ++#endif ++#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS) ++#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled." ++#endif ++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP) ++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled." ++#endif ++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR) ++#error "CONFIG_PAX enabled, but no PaX options are enabled." ++#endif ++ ++void gr_handle_brute_attach(struct task_struct *p); ++void gr_handle_brute_check(void); ++ ++char gr_roletype_to_char(void); ++ ++int gr_check_user_change(int real, int effective, int fs); ++int gr_check_group_change(int real, int effective, int fs); ++ ++void gr_del_task_from_ip_table(struct task_struct *p); ++ ++int gr_pid_is_chrooted(struct task_struct *p); ++int gr_handle_chroot_nice(void); ++int gr_handle_chroot_sysctl(const int op); ++int gr_handle_chroot_setpriority(struct task_struct *p, ++ const int niceval); ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt); ++int gr_handle_chroot_chroot(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++int gr_handle_chroot_caps(struct path *path); ++void gr_handle_chroot_chdir(struct path *path); ++int gr_handle_chroot_chmod(const struct dentry *dentry, ++ const struct vfsmount *mnt, const int mode); ++int gr_handle_chroot_mknod(const struct dentry *dentry, ++ const struct vfsmount *mnt, const int mode); ++int gr_handle_chroot_mount(const struct dentry *dentry, ++ const struct vfsmount *mnt, ++ const char *dev_name); ++int gr_handle_chroot_pivot(void); ++int gr_handle_chroot_unix(const pid_t pid); ++ ++int gr_handle_rawio(const struct inode *inode); ++int gr_handle_nproc(void); ++ ++void gr_handle_ioperm(void); ++void gr_handle_iopl(void); ++ ++int gr_tpe_allow(const struct file *file); ++ ++int gr_random_pid(void); ++ ++void gr_log_forkfail(const int retval); ++void gr_log_timechange(void); ++void gr_log_signal(const int sig, const void *addr, const struct task_struct *t); ++void gr_log_chdir(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_log_chroot_exec(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv); ++void gr_log_remount(const char *devname, const int retval); ++void gr_log_unmount(const char *devname, const int retval); ++void gr_log_mount(const char *from, const char *to, const int retval); ++void gr_log_textrel(struct vm_area_struct *vma); ++ ++int gr_handle_follow_link(const struct inode *parent, ++ const struct inode *inode, ++ const struct dentry *dentry, ++ const struct vfsmount *mnt); ++int gr_handle_fifo(const struct dentry *dentry, ++ const struct vfsmount *mnt, ++ const struct dentry *dir, const int flag, ++ const int acc_mode); ++int gr_handle_hardlink(const struct dentry *dentry, ++ const struct vfsmount *mnt, ++ struct inode *inode, ++ const int mode, const char *to); ++ ++int gr_is_capable(const int cap); ++int gr_is_capable_nolog(const int cap); ++void gr_learn_resource(const struct task_struct *task, const int limit, ++ const unsigned long wanted, const int gt); ++void gr_copy_label(struct task_struct *tsk); ++void gr_handle_crash(struct task_struct *task, const int sig); ++int gr_handle_signal(const struct task_struct *p, const int sig); ++int gr_check_crash_uid(const uid_t uid); ++int gr_check_protected_task(const struct task_struct *task); ++int gr_acl_handle_mmap(const struct file *file, ++ const unsigned long prot); ++int gr_acl_handle_mprotect(const struct file *file, ++ const unsigned long prot); ++int gr_check_hidden_task(const struct task_struct *tsk); ++__u32 gr_acl_handle_truncate(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_utime(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_access(const struct dentry *dentry, ++ const struct vfsmount *mnt, const int fmode); ++__u32 gr_acl_handle_fchmod(const struct dentry *dentry, ++ const struct vfsmount *mnt, mode_t mode); ++__u32 gr_acl_handle_chmod(const struct dentry *dentry, ++ const struct vfsmount *mnt, mode_t mode); ++__u32 gr_acl_handle_chown(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++int gr_handle_ptrace(struct task_struct *task, const long request); ++int gr_handle_proc_ptrace(struct task_struct *task); ++__u32 gr_acl_handle_execve(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++int gr_check_crash_exec(const struct file *filp); ++int gr_acl_is_enabled(void); ++void gr_set_kernel_label(struct task_struct *task); ++void gr_set_role_label(struct task_struct *task, const uid_t uid, ++ const gid_t gid); ++int gr_set_proc_label(const struct dentry *dentry, ++ const struct vfsmount *mnt, ++ const int unsafe_share); ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_open(const struct dentry *dentry, ++ const struct vfsmount *mnt, const int fmode); ++__u32 gr_acl_handle_creat(const struct dentry *dentry, ++ const struct dentry *p_dentry, ++ const struct vfsmount *p_mnt, const int fmode, ++ const int imode); ++void gr_handle_create(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ const int mode); ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt); ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_handle_delete(const ino_t ino, const dev_t dev); ++__u32 gr_acl_handle_unlink(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ const char *from); ++__u32 gr_acl_handle_link(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ const struct dentry *old_dentry, ++ const struct vfsmount *old_mnt, const char *to); ++int gr_acl_handle_rename(struct dentry *new_dentry, ++ struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ struct dentry *old_dentry, ++ struct inode *old_parent_inode, ++ struct vfsmount *old_mnt, const char *newname); ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir, ++ struct dentry *old_dentry, ++ struct dentry *new_dentry, ++ struct vfsmount *mnt, const __u8 replace); ++__u32 gr_check_link(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ const struct dentry *old_dentry, ++ const struct vfsmount *old_mnt); ++int gr_acl_handle_filldir(const struct file *file, const char *name, ++ const unsigned int namelen, const ino_t ino); ++ ++__u32 gr_acl_handle_unix(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_acl_handle_exit(void); ++void gr_acl_handle_psacct(struct task_struct *task, const long code); ++int gr_acl_handle_procpidmem(const struct task_struct *task); ++ ++#ifdef CONFIG_GRKERNSEC ++void gr_log_nonroot_mod_load(const char *modname); ++void gr_handle_mem_write(void); ++void gr_handle_kmem_write(void); ++void gr_handle_open_port(void); ++int gr_handle_mem_mmap(const unsigned long offset, ++ struct vm_area_struct *vma); ++ ++extern int grsec_enable_dmesg; ++extern int grsec_enable_randsrc; ++extern int grsec_enable_shm; ++#endif ++ ++#endif +diff -urNp linux-2.6.31.1/include/linux/hdpu_features.h linux-2.6.31.1/include/linux/hdpu_features.h +--- linux-2.6.31.1/include/linux/hdpu_features.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/hdpu_features.h 2009-10-01 20:12:44.000000000 -0400 +@@ -3,7 +3,7 @@ + struct cpustate_t { + spinlock_t lock; + int excl; +- int open_count; ++ atomic_t open_count; + unsigned char cached_val; + int inited; + unsigned long *set_addr; +diff -urNp linux-2.6.31.1/include/linux/highmem.h linux-2.6.31.1/include/linux/highmem.h +--- linux-2.6.31.1/include/linux/highmem.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/highmem.h 2009-10-01 20:12:44.000000000 -0400 +@@ -137,6 +137,18 @@ static inline void clear_highpage(struct + kunmap_atomic(kaddr, KM_USER0); + } + ++static inline void sanitize_highpage(struct page *page) ++{ ++ void *kaddr; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ kaddr = kmap_atomic(page, KM_CLEARPAGE); ++ clear_page(kaddr); ++ kunmap_atomic(kaddr, KM_CLEARPAGE); ++ local_irq_restore(flags); ++} ++ + static inline void zero_user_segments(struct page *page, + unsigned start1, unsigned end1, + unsigned start2, unsigned end2) +diff -urNp linux-2.6.31.1/include/linux/hugetlb.h linux-2.6.31.1/include/linux/hugetlb.h +--- linux-2.6.31.1/include/linux/hugetlb.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/hugetlb.h 2009-10-01 20:12:44.000000000 -0400 +@@ -146,7 +146,7 @@ static inline struct hugetlbfs_sb_info * + } + + extern const struct file_operations hugetlbfs_file_operations; +-extern struct vm_operations_struct hugetlb_vm_ops; ++extern const struct vm_operations_struct hugetlb_vm_ops; + struct file *hugetlb_file_setup(const char *name, size_t size, int acct, + struct user_struct **user); + int hugetlb_get_quota(struct address_space *mapping, long delta); +diff -urNp linux-2.6.31.1/include/linux/jbd2.h linux-2.6.31.1/include/linux/jbd2.h +--- linux-2.6.31.1/include/linux/jbd2.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/jbd2.h 2009-10-01 20:12:44.000000000 -0400 +@@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug; + } \ + } while (0) + #else +-#define jbd_debug(f, a...) /**/ ++#define jbd_debug(f, a...) do {} while (0) + #endif + + static inline void *jbd2_alloc(size_t size, gfp_t flags) +diff -urNp linux-2.6.31.1/include/linux/jbd.h linux-2.6.31.1/include/linux/jbd.h +--- linux-2.6.31.1/include/linux/jbd.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/jbd.h 2009-10-01 20:12:44.000000000 -0400 +@@ -66,7 +66,7 @@ extern u8 journal_enable_debug; + } \ + } while (0) + #else +-#define jbd_debug(f, a...) /**/ ++#define jbd_debug(f, a...) do {} while (0) + #endif + + static inline void *jbd_alloc(size_t size, gfp_t flags) +diff -urNp linux-2.6.31.1/include/linux/kallsyms.h linux-2.6.31.1/include/linux/kallsyms.h +--- linux-2.6.31.1/include/linux/kallsyms.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/kallsyms.h 2009-10-01 20:12:44.000000000 -0400 +@@ -15,7 +15,8 @@ + + struct module; + +-#ifdef CONFIG_KALLSYMS ++#ifndef __INCLUDED_BY_HIDESYM ++#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_GRKERNSEC_HIDESYM) + /* Lookup the address for a symbol. Returns 0 if not found. */ + unsigned long kallsyms_lookup_name(const char *name); + +@@ -92,6 +93,9 @@ static inline int lookup_symbol_attrs(un + /* Stupid that this does nothing, but I didn't create this mess. */ + #define __print_symbol(fmt, addr) + #endif /*CONFIG_KALLSYMS*/ ++#else /* when included by kallsyms.c, with HIDESYM enabled */ ++extern void __print_symbol(const char *fmt, unsigned long address); ++#endif + + /* This macro allows us to keep printk typechecking */ + static void __check_printsym_format(const char *fmt, ...) +diff -urNp linux-2.6.31.1/include/linux/kvm_host.h linux-2.6.31.1/include/linux/kvm_host.h +--- linux-2.6.31.1/include/linux/kvm_host.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/kvm_host.h 2009-10-01 20:12:44.000000000 -0400 +@@ -173,7 +173,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vc + void vcpu_load(struct kvm_vcpu *vcpu); + void vcpu_put(struct kvm_vcpu *vcpu); + +-int kvm_init(void *opaque, unsigned int vcpu_size, ++int kvm_init(const void *opaque, unsigned int vcpu_size, + struct module *module); + void kvm_exit(void); + +@@ -280,7 +280,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug( + struct kvm_guest_debug *dbg); + int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); + +-int kvm_arch_init(void *opaque); ++int kvm_arch_init(const void *opaque); + void kvm_arch_exit(void); + + int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu); +diff -urNp linux-2.6.31.1/include/linux/libata.h linux-2.6.31.1/include/linux/libata.h +--- linux-2.6.31.1/include/linux/libata.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/libata.h 2009-10-01 20:12:44.000000000 -0400 +@@ -64,11 +64,11 @@ + #ifdef ATA_VERBOSE_DEBUG + #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) + #else +-#define VPRINTK(fmt, args...) ++#define VPRINTK(fmt, args...) do {} while (0) + #endif /* ATA_VERBOSE_DEBUG */ + #else +-#define DPRINTK(fmt, args...) +-#define VPRINTK(fmt, args...) ++#define DPRINTK(fmt, args...) do {} while (0) ++#define VPRINTK(fmt, args...) do {} while (0) + #endif /* ATA_DEBUG */ + + #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args) +diff -urNp linux-2.6.31.1/include/linux/mm.h linux-2.6.31.1/include/linux/mm.h +--- linux-2.6.31.1/include/linux/mm.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/mm.h 2009-10-01 20:12:44.000000000 -0400 +@@ -104,6 +104,10 @@ extern unsigned int kobjsize(const void + #define VM_SAO 0x20000000 /* Strong Access Ordering (powerpc) */ + #define VM_PFN_AT_MMAP 0x40000000 /* PFNMAP vma that is fully mapped at mmap time */ + ++#ifdef CONFIG_PAX_PAGEEXEC ++#define VM_PAGEEXEC 0x80000000 /* vma->vm_page_prot needs special handling */ ++#endif ++ + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS + #endif +@@ -871,6 +875,8 @@ struct shrinker { + extern void register_shrinker(struct shrinker *); + extern void unregister_shrinker(struct shrinker *); + ++pgprot_t vm_get_page_prot(unsigned long vm_flags); ++ + int vma_wants_writenotify(struct vm_area_struct *vma); + + extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl); +@@ -1141,6 +1147,7 @@ out: + } + + extern int do_munmap(struct mm_struct *, unsigned long, size_t); ++extern int __do_munmap(struct mm_struct *, unsigned long, size_t); + + extern unsigned long do_brk(unsigned long, unsigned long); + +@@ -1195,6 +1202,10 @@ extern struct vm_area_struct * find_vma( + extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr, + struct vm_area_struct **pprev); + ++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma); ++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma); ++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl); ++ + /* Look up the first VMA which intersects the interval start_addr..end_addr-1, + NULL if none. Assume start_addr < end_addr. */ + static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr) +@@ -1211,7 +1222,6 @@ static inline unsigned long vma_pages(st + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + } + +-pgprot_t vm_get_page_prot(unsigned long vm_flags); + struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr); + int remap_pfn_range(struct vm_area_struct *, unsigned long addr, + unsigned long pfn, unsigned long size, pgprot_t); +@@ -1303,5 +1313,12 @@ void vmemmap_populate_print_last(void); + extern int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim, + size_t size); + extern void refund_locked_memory(struct mm_struct *mm, size_t size); ++ ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT ++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot); ++#else ++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {} ++#endif ++ + #endif /* __KERNEL__ */ + #endif /* _LINUX_MM_H */ +diff -urNp linux-2.6.31.1/include/linux/mm_types.h linux-2.6.31.1/include/linux/mm_types.h +--- linux-2.6.31.1/include/linux/mm_types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/mm_types.h 2009-10-01 20:12:44.000000000 -0400 +@@ -171,7 +171,7 @@ struct vm_area_struct { + struct anon_vma *anon_vma; /* Serialized by page_table_lock */ + + /* Function pointers to deal with this struct. */ +- struct vm_operations_struct * vm_ops; ++ const struct vm_operations_struct * vm_ops; + + /* Information about our backing store: */ + unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE +@@ -186,6 +186,8 @@ struct vm_area_struct { + #ifdef CONFIG_NUMA + struct mempolicy *vm_policy; /* NUMA policy for the VMA */ + #endif ++ ++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */ + }; + + struct core_thread { +@@ -286,6 +288,24 @@ struct mm_struct { + #ifdef CONFIG_MMU_NOTIFIER + struct mmu_notifier_mm *mmu_notifier_mm; + #endif ++ ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) ++ unsigned long pax_flags; ++#endif ++ ++#ifdef CONFIG_PAX_DLRESOLVE ++ unsigned long call_dl_resolve; ++#endif ++ ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT) ++ unsigned long call_syscall; ++#endif ++ ++#ifdef CONFIG_PAX_ASLR ++ unsigned long delta_mmap; /* randomized offset */ ++ unsigned long delta_stack; /* randomized offset */ ++#endif ++ + }; + + /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ +diff -urNp linux-2.6.31.1/include/linux/mod_devicetable.h linux-2.6.31.1/include/linux/mod_devicetable.h +--- linux-2.6.31.1/include/linux/mod_devicetable.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/mod_devicetable.h 2009-10-01 20:12:44.000000000 -0400 +@@ -12,7 +12,7 @@ + typedef unsigned long kernel_ulong_t; + #endif + +-#define PCI_ANY_ID (~0) ++#define PCI_ANY_ID ((__u16)~0) + + struct pci_device_id { + __u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/ +@@ -131,7 +131,7 @@ struct usb_device_id { + #define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 + #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 + +-#define HID_ANY_ID (~0) ++#define HID_ANY_ID (~0U) + + struct hid_device_id { + __u16 bus; +diff -urNp linux-2.6.31.1/include/linux/module.h linux-2.6.31.1/include/linux/module.h +--- linux-2.6.31.1/include/linux/module.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/module.h 2009-10-01 20:12:44.000000000 -0400 +@@ -283,16 +283,16 @@ struct module + int (*init)(void); + + /* If this is non-NULL, vfree after init() returns */ +- void *module_init; ++ void *module_init_rx, *module_init_rw; + + /* Here is the actual code + data, vfree'd on unload. */ +- void *module_core; ++ void *module_core_rx, *module_core_rw; + + /* Here are the sizes of the init and core sections */ +- unsigned int init_size, core_size; ++ unsigned int init_size_rw, core_size_rw; + + /* The size of the executable code in each section. */ +- unsigned int init_text_size, core_text_size; ++ unsigned int init_size_rx, core_size_rx; + + /* Arch-specific module values */ + struct mod_arch_specific arch; +@@ -389,16 +389,46 @@ struct module *__module_address(unsigned + bool is_module_address(unsigned long addr); + bool is_module_text_address(unsigned long addr); + ++static inline int within_module_range(unsigned long addr, void *start, unsigned long size) ++{ ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ if (ktla_ktva(addr) >= (unsigned long)start && ++ ktla_ktva(addr) < (unsigned long)start + size) ++ return 1; ++#endif ++ ++ return ((void *)addr >= start && (void *)addr < start + size); ++} ++ ++static inline int within_module_core_rx(unsigned long addr, struct module *mod) ++{ ++ return within_module_range(addr, mod->module_core_rx, mod->core_size_rx); ++} ++ ++static inline int within_module_core_rw(unsigned long addr, struct module *mod) ++{ ++ return within_module_range(addr, mod->module_core_rw, mod->core_size_rw); ++} ++ ++static inline int within_module_init_rx(unsigned long addr, struct module *mod) ++{ ++ return within_module_range(addr, mod->module_init_rx, mod->init_size_rx); ++} ++ ++static inline int within_module_init_rw(unsigned long addr, struct module *mod) ++{ ++ return within_module_range(addr, mod->module_init_rw, mod->init_size_rw); ++} ++ + static inline int within_module_core(unsigned long addr, struct module *mod) + { +- return (unsigned long)mod->module_core <= addr && +- addr < (unsigned long)mod->module_core + mod->core_size; ++ return within_module_core_rx(addr, mod) || within_module_core_rw(addr, mod); + } + + static inline int within_module_init(unsigned long addr, struct module *mod) + { +- return (unsigned long)mod->module_init <= addr && +- addr < (unsigned long)mod->module_init + mod->init_size; ++ return within_module_init_rx(addr, mod) || within_module_init_rw(addr, mod); + } + + /* Search for module by name: must hold module_mutex. */ +@@ -451,7 +481,11 @@ void symbol_put_addr(void *addr); + static inline local_t *__module_ref_addr(struct module *mod, int cpu) + { + #ifdef CONFIG_SMP ++#ifdef CONFIG_X86_32 ++ return (local_t *) (mod->refptr + __per_cpu_offset[cpu]); ++#else + return (local_t *) (mod->refptr + per_cpu_offset(cpu)); ++#endif + #else + return &mod->ref; + #endif +diff -urNp linux-2.6.31.1/include/linux/moduleloader.h linux-2.6.31.1/include/linux/moduleloader.h +--- linux-2.6.31.1/include/linux/moduleloader.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/moduleloader.h 2009-10-01 20:12:44.000000000 -0400 +@@ -20,9 +20,21 @@ unsigned int arch_mod_section_prepend(st + sections. Returns NULL on failure. */ + void *module_alloc(unsigned long size); + ++#ifdef CONFIG_PAX_KERNEXEC ++void *module_alloc_exec(unsigned long size); ++#else ++#define module_alloc_exec(x) module_alloc(x) ++#endif ++ + /* Free memory returned from module_alloc. */ + void module_free(struct module *mod, void *module_region); + ++#ifdef CONFIG_PAX_KERNEXEC ++void module_free_exec(struct module *mod, void *module_region); ++#else ++#define module_free_exec(x, y) module_free(x, y) ++#endif ++ + /* Apply the given relocation to the (simplified) ELF. Return -error + or 0. */ + int apply_relocate(Elf_Shdr *sechdrs, +diff -urNp linux-2.6.31.1/include/linux/moduleparam.h linux-2.6.31.1/include/linux/moduleparam.h +--- linux-2.6.31.1/include/linux/moduleparam.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/moduleparam.h 2009-10-01 20:12:44.000000000 -0400 +@@ -37,7 +37,6 @@ typedef int (*param_set_fn)(const char * + typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp); + + /* Flag bits for kernel_param.flags */ +-#define KPARAM_KMALLOCED 1 + #define KPARAM_ISBOOL 2 + + struct kernel_param { +diff -urNp linux-2.6.31.1/include/linux/namei.h linux-2.6.31.1/include/linux/namei.h +--- linux-2.6.31.1/include/linux/namei.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/namei.h 2009-10-01 20:12:44.000000000 -0400 +@@ -22,7 +22,7 @@ struct nameidata { + unsigned int flags; + int last_type; + unsigned depth; +- char *saved_names[MAX_NESTED_LINKS + 1]; ++ const char *saved_names[MAX_NESTED_LINKS + 1]; + + /* Intent data */ + union { +@@ -84,12 +84,12 @@ extern int follow_up(struct path *); + extern struct dentry *lock_rename(struct dentry *, struct dentry *); + extern void unlock_rename(struct dentry *, struct dentry *); + +-static inline void nd_set_link(struct nameidata *nd, char *path) ++static inline void nd_set_link(struct nameidata *nd, const char *path) + { + nd->saved_names[nd->depth] = path; + } + +-static inline char *nd_get_link(struct nameidata *nd) ++static inline const char *nd_get_link(struct nameidata *nd) + { + return nd->saved_names[nd->depth]; + } +diff -urNp linux-2.6.31.1/include/linux/nfsd/nfsd.h linux-2.6.31.1/include/linux/nfsd/nfsd.h +--- linux-2.6.31.1/include/linux/nfsd/nfsd.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/nfsd/nfsd.h 2009-10-01 20:12:44.000000000 -0400 +@@ -57,7 +57,7 @@ extern u32 nfsd_supported_minorversion + extern struct mutex nfsd_mutex; + extern struct svc_serv *nfsd_serv; + +-extern struct seq_operations nfs_exports_op; ++extern const struct seq_operations nfs_exports_op; + + /* + * Function prototypes. +diff -urNp linux-2.6.31.1/include/linux/nodemask.h linux-2.6.31.1/include/linux/nodemask.h +--- linux-2.6.31.1/include/linux/nodemask.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/nodemask.h 2009-10-01 20:12:44.000000000 -0400 +@@ -464,11 +464,11 @@ static inline int num_node_state(enum no + + #define any_online_node(mask) \ + ({ \ +- int node; \ +- for_each_node_mask(node, (mask)) \ +- if (node_online(node)) \ ++ int __node; \ ++ for_each_node_mask(__node, (mask)) \ ++ if (node_online(__node)) \ + break; \ +- node; \ ++ __node; \ + }) + + #define num_online_nodes() num_node_state(N_ONLINE) +diff -urNp linux-2.6.31.1/include/linux/oprofile.h linux-2.6.31.1/include/linux/oprofile.h +--- linux-2.6.31.1/include/linux/oprofile.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/oprofile.h 2009-10-01 20:12:44.000000000 -0400 +@@ -128,7 +128,7 @@ int oprofilefs_create_ro_ulong(struct su + + /** Create a file for read-only access to an atomic_t. */ + int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, +- char const * name, atomic_t * val); ++ char const * name, atomic_unchecked_t * val); + + /** create a directory */ + struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root, +diff -urNp linux-2.6.31.1/include/linux/poison.h linux-2.6.31.1/include/linux/poison.h +--- linux-2.6.31.1/include/linux/poison.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/poison.h 2009-10-01 20:12:44.000000000 -0400 +@@ -7,8 +7,8 @@ + * under normal circumstances, used to verify that nobody uses + * non-initialized list entries. + */ +-#define LIST_POISON1 ((void *) 0x00100100) +-#define LIST_POISON2 ((void *) 0x00200200) ++#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL) ++#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL) + + /********** include/linux/timer.h **********/ + /* +diff -urNp linux-2.6.31.1/include/linux/proc_fs.h linux-2.6.31.1/include/linux/proc_fs.h +--- linux-2.6.31.1/include/linux/proc_fs.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/proc_fs.h 2009-10-01 20:12:44.000000000 -0400 +@@ -146,6 +146,19 @@ static inline struct proc_dir_entry *pro + return proc_create_data(name, mode, parent, proc_fops, NULL); + } + ++static inline struct proc_dir_entry *proc_create_grsec(const char *name, mode_t mode, ++ struct proc_dir_entry *parent, const struct file_operations *proc_fops) ++{ ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ return proc_create_data(name, S_IRUSR, parent, proc_fops, NULL); ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ return proc_create_data(name, S_IRUSR | S_IRGRP, parent, proc_fops, NULL); ++#else ++ return proc_create_data(name, mode, parent, proc_fops, NULL); ++#endif ++} ++ ++ + static inline struct proc_dir_entry *create_proc_read_entry(const char *name, + mode_t mode, struct proc_dir_entry *base, + read_proc_t *read_proc, void * data) +diff -urNp linux-2.6.31.1/include/linux/random.h linux-2.6.31.1/include/linux/random.h +--- linux-2.6.31.1/include/linux/random.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/random.h 2009-10-01 20:12:44.000000000 -0400 +@@ -74,6 +74,11 @@ unsigned long randomize_range(unsigned l + u32 random32(void); + void srandom32(u32 seed); + ++static inline unsigned long pax_get_random_long(void) ++{ ++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0); ++} ++ + #endif /* __KERNEL___ */ + + #endif /* _LINUX_RANDOM_H */ +diff -urNp linux-2.6.31.1/include/linux/reiserfs_fs.h linux-2.6.31.1/include/linux/reiserfs_fs.h +--- linux-2.6.31.1/include/linux/reiserfs_fs.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/reiserfs_fs.h 2009-10-01 20:12:44.000000000 -0400 +@@ -1326,7 +1326,7 @@ static inline loff_t max_reiserfs_offset + #define REISERFS_USER_MEM 1 /* reiserfs user memory mode */ + + #define fs_generation(s) (REISERFS_SB(s)->s_generation_counter) +-#define get_generation(s) atomic_read (&fs_generation(s)) ++#define get_generation(s) atomic_read_unchecked (&fs_generation(s)) + #define FILESYSTEM_CHANGED_TB(tb) (get_generation((tb)->tb_sb) != (tb)->fs_gen) + #define __fs_changed(gen,s) (gen != get_generation (s)) + #define fs_changed(gen,s) ({cond_resched(); __fs_changed(gen, s);}) +diff -urNp linux-2.6.31.1/include/linux/reiserfs_fs_sb.h linux-2.6.31.1/include/linux/reiserfs_fs_sb.h +--- linux-2.6.31.1/include/linux/reiserfs_fs_sb.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/reiserfs_fs_sb.h 2009-10-01 20:12:44.000000000 -0400 +@@ -377,7 +377,7 @@ struct reiserfs_sb_info { + /* Comment? -Hans */ + wait_queue_head_t s_wait; + /* To be obsoleted soon by per buffer seals.. -Hans */ +- atomic_t s_generation_counter; // increased by one every time the ++ atomic_unchecked_t s_generation_counter; // increased by one every time the + // tree gets re-balanced + unsigned long s_properties; /* File system properties. Currently holds + on-disk FS format */ +diff -urNp linux-2.6.31.1/include/linux/sched.h linux-2.6.31.1/include/linux/sched.h +--- linux-2.6.31.1/include/linux/sched.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/sched.h 2009-10-01 20:12:44.000000000 -0400 +@@ -99,6 +99,7 @@ struct bio; + struct fs_struct; + struct bts_context; + struct perf_counter_context; ++struct linux_binprm; + + /* + * List of flags we want to share for kernel threads, +@@ -629,6 +630,15 @@ struct signal_struct { + unsigned audit_tty; + struct tty_audit_buf *tty_audit_buf; + #endif ++ ++#ifdef CONFIG_GRKERNSEC ++ u32 curr_ip; ++ u32 gr_saddr; ++ u32 gr_daddr; ++ u16 gr_sport; ++ u16 gr_dport; ++ u8 used_accept:1; ++#endif + }; + + /* Context switch must be unlocked if interrupts are to be enabled */ +@@ -1165,7 +1175,7 @@ struct sched_rt_entity { + + struct task_struct { + volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ +- void *stack; ++ struct thread_info *stack; + atomic_t usage; + unsigned int flags; /* per process flags, defined below */ + unsigned int ptrace; +@@ -1269,8 +1279,8 @@ struct task_struct { + struct list_head thread_group; + + struct completion *vfork_done; /* for vfork() */ +- int __user *set_child_tid; /* CLONE_CHILD_SETTID */ +- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ ++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */ ++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ + + cputime_t utime, stime, utimescaled, stimescaled; + cputime_t gtime; +@@ -1284,15 +1294,6 @@ struct task_struct { + struct task_cputime cputime_expires; + struct list_head cpu_timers[3]; + +-/* process credentials */ +- const struct cred *real_cred; /* objective and real subjective task +- * credentials (COW) */ +- const struct cred *cred; /* effective (overridable) subjective task +- * credentials (COW) */ +- struct mutex cred_guard_mutex; /* guard against foreign influences on +- * credential calculations +- * (notably. ptrace) */ +- + char comm[TASK_COMM_LEN]; /* executable name excluding path + - access with [gs]et_task_comm (which lock + it with task_lock()) +@@ -1429,6 +1430,16 @@ struct task_struct { + struct mutex perf_counter_mutex; + struct list_head perf_counter_list; + #endif ++ ++/* process credentials */ ++ const struct cred *real_cred; /* objective and real subjective task ++ * credentials (COW) */ ++ const struct cred *cred; /* effective (overridable) subjective task ++ * credentials (COW) */ ++ struct mutex cred_guard_mutex; /* guard against foreign influences on ++ * credential calculations ++ * (notably. ptrace) */ ++ + #ifdef CONFIG_NUMA + struct mempolicy *mempolicy; /* Protected by alloc_lock */ + short il_next; +@@ -1480,8 +1491,66 @@ struct task_struct { + /* bitmask of trace recursion */ + unsigned long trace_recursion; + #endif /* CONFIG_TRACING */ ++ ++#ifdef CONFIG_GRKERNSEC ++ /* grsecurity */ ++ struct acl_subject_label *acl; ++ struct acl_role_label *role; ++ struct file *exec_file; ++ u16 acl_role_id; ++ u8 acl_sp_role; ++ u8 is_writable; ++ u8 brute; ++#endif ++ + }; + ++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */ ++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */ ++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */ ++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */ ++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */ ++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */ ++ ++#ifdef CONFIG_PAX_SOFTMODE ++extern unsigned int pax_softmode; ++#endif ++ ++extern int pax_check_flags(unsigned long *); ++ ++/* if tsk != current then task_lock must be held on it */ ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) ++static inline unsigned long pax_get_flags(struct task_struct *tsk) ++{ ++ if (likely(tsk->mm)) ++ return tsk->mm->pax_flags; ++ else ++ return 0UL; ++} ++ ++/* if tsk != current then task_lock must be held on it */ ++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags) ++{ ++ if (likely(tsk->mm)) { ++ tsk->mm->pax_flags = flags; ++ return 0; ++ } ++ return -EINVAL; ++} ++#endif ++ ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS ++extern void pax_set_initial_flags(struct linux_binprm *bprm); ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS) ++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm); ++#endif ++ ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp); ++void pax_report_insns(void *pc, void *sp); ++void pax_report_refcount_overflow(struct pt_regs *regs); ++void pax_report_leak_to_user(const void *ptr, unsigned long len); ++void pax_report_overflow_from_user(const void *ptr, unsigned long len); ++ + /* Future-safe accessor for struct task_struct's cpus_allowed. */ + #define tsk_cpumask(tsk) (&(tsk)->cpus_allowed) + +@@ -2046,7 +2115,7 @@ extern void __cleanup_sighand(struct sig + extern void exit_itimers(struct signal_struct *); + extern void flush_itimer_signals(void); + +-extern NORET_TYPE void do_group_exit(int); ++extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET; + + extern void daemonize(const char *, ...); + extern int allow_signal(int); +@@ -2159,8 +2228,8 @@ static inline void unlock_task_sighand(s + + #ifndef __HAVE_THREAD_FUNCTIONS + +-#define task_thread_info(task) ((struct thread_info *)(task)->stack) +-#define task_stack_page(task) ((task)->stack) ++#define task_thread_info(task) ((task)->stack) ++#define task_stack_page(task) ((void *)(task)->stack) + + static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org) + { +@@ -2175,7 +2244,7 @@ static inline unsigned long *end_of_stac + + #endif + +-static inline int object_is_on_stack(void *obj) ++static inline int object_is_on_stack(const void *obj) + { + void *stack = task_stack_page(current); + +diff -urNp linux-2.6.31.1/include/linux/screen_info.h linux-2.6.31.1/include/linux/screen_info.h +--- linux-2.6.31.1/include/linux/screen_info.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/screen_info.h 2009-10-01 20:12:44.000000000 -0400 +@@ -42,7 +42,8 @@ struct screen_info { + __u16 pages; /* 0x32 */ + __u16 vesa_attributes; /* 0x34 */ + __u32 capabilities; /* 0x36 */ +- __u8 _reserved[6]; /* 0x3a */ ++ __u16 vesapm_size; /* 0x3a */ ++ __u8 _reserved[4]; /* 0x3c */ + } __attribute__((packed)); + + #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ +diff -urNp linux-2.6.31.1/include/linux/security.h linux-2.6.31.1/include/linux/security.h +--- linux-2.6.31.1/include/linux/security.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/security.h 2009-10-01 20:12:44.000000000 -0400 +@@ -34,6 +34,7 @@ + #include <linux/key.h> + #include <linux/xfrm.h> + #include <linux/gfp.h> ++#include <linux/grsecurity.h> + #include <net/flow.h> + + /* Maximum number of letters for an LSM name string */ +diff -urNp linux-2.6.31.1/include/linux/shm.h linux-2.6.31.1/include/linux/shm.h +--- linux-2.6.31.1/include/linux/shm.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/shm.h 2009-10-01 20:12:44.000000000 -0400 +@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke + pid_t shm_cprid; + pid_t shm_lprid; + struct user_struct *mlock_user; ++#ifdef CONFIG_GRKERNSEC ++ time_t shm_createtime; ++ pid_t shm_lapid; ++#endif + }; + + /* shm_mode upper byte flags */ +diff -urNp linux-2.6.31.1/include/linux/slab.h linux-2.6.31.1/include/linux/slab.h +--- linux-2.6.31.1/include/linux/slab.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/slab.h 2009-10-01 20:12:44.000000000 -0400 +@@ -82,10 +82,9 @@ + * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can. + * Both make kfree a no-op. + */ +-#define ZERO_SIZE_PTR ((void *)16) ++#define ZERO_SIZE_PTR ((void *)-1024L) + +-#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \ +- (unsigned long)ZERO_SIZE_PTR) ++#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR) + + /* + * struct kmem_cache related prototypes +@@ -138,6 +137,7 @@ void * __must_check krealloc(const void + void kfree(const void *); + void kzfree(const void *); + size_t ksize(const void *); ++void check_object_size(const void *ptr, unsigned long n, bool to); + + /* + * Allocator specific definitions. These are mainly used to establish optimized +@@ -328,4 +328,37 @@ static inline void *kzalloc_node(size_t + + void __init kmem_cache_init_late(void); + ++#define kmalloc(x, y) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "kmalloc size overflow\n"))\ ++ ___retval = NULL; \ ++ else \ ++ ___retval = kmalloc((size_t)___x, (y)); \ ++ ___retval; \ ++}) ++ ++#define kmalloc_node(x, y, z) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "kmalloc_node size overflow\n"))\ ++ ___retval = NULL; \ ++ else \ ++ ___retval = kmalloc_node((size_t)___x, (y), (z));\ ++ ___retval; \ ++}) ++ ++#define kzalloc(x, y) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "kzalloc size overflow\n"))\ ++ ___retval = NULL; \ ++ else \ ++ ___retval = kzalloc((size_t)___x, (y)); \ ++ ___retval; \ ++}) ++ + #endif /* _LINUX_SLAB_H */ +diff -urNp linux-2.6.31.1/include/linux/slub_def.h linux-2.6.31.1/include/linux/slub_def.h +--- linux-2.6.31.1/include/linux/slub_def.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/slub_def.h 2009-10-01 20:12:44.000000000 -0400 +@@ -86,7 +86,7 @@ struct kmem_cache { + struct kmem_cache_order_objects max; + struct kmem_cache_order_objects min; + gfp_t allocflags; /* gfp flags to use on each alloc */ +- int refcount; /* Refcount for slab cache destroy */ ++ atomic_t refcount; /* Refcount for slab cache destroy */ + void (*ctor)(void *); + int inuse; /* Offset to metadata */ + int align; /* Alignment */ +diff -urNp linux-2.6.31.1/include/linux/sonet.h linux-2.6.31.1/include/linux/sonet.h +--- linux-2.6.31.1/include/linux/sonet.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/sonet.h 2009-10-01 20:12:44.000000000 -0400 +@@ -61,7 +61,7 @@ struct sonet_stats { + #include <asm/atomic.h> + + struct k_sonet_stats { +-#define __HANDLE_ITEM(i) atomic_t i ++#define __HANDLE_ITEM(i) atomic_unchecked_t i + __SONET_ITEMS + #undef __HANDLE_ITEM + }; +diff -urNp linux-2.6.31.1/include/linux/sysctl.h linux-2.6.31.1/include/linux/sysctl.h +--- linux-2.6.31.1/include/linux/sysctl.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/sysctl.h 2009-10-01 20:12:44.000000000 -0400 +@@ -165,7 +165,11 @@ enum + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */ + }; + +- ++#ifdef CONFIG_PAX_SOFTMODE ++enum { ++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */ ++}; ++#endif + + /* CTL_VM names: */ + enum +diff -urNp linux-2.6.31.1/include/linux/thread_info.h linux-2.6.31.1/include/linux/thread_info.h +--- linux-2.6.31.1/include/linux/thread_info.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/thread_info.h 2009-10-01 20:12:44.000000000 -0400 +@@ -23,7 +23,7 @@ struct restart_block { + }; + /* For futex_wait and futex_wait_requeue_pi */ + struct { +- u32 *uaddr; ++ u32 __user *uaddr; + u32 val; + u32 flags; + u32 bitset; +diff -urNp linux-2.6.31.1/include/linux/tty_ldisc.h linux-2.6.31.1/include/linux/tty_ldisc.h +--- linux-2.6.31.1/include/linux/tty_ldisc.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/tty_ldisc.h 2009-10-01 20:12:44.000000000 -0400 +@@ -139,7 +139,7 @@ struct tty_ldisc_ops { + + struct module *owner; + +- int refcount; ++ atomic_t refcount; + }; + + struct tty_ldisc { +diff -urNp linux-2.6.31.1/include/linux/types.h linux-2.6.31.1/include/linux/types.h +--- linux-2.6.31.1/include/linux/types.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/types.h 2009-10-01 20:12:44.000000000 -0400 +@@ -191,10 +191,26 @@ typedef struct { + volatile int counter; + } atomic_t; + ++#ifdef CONFIG_PAX_REFCOUNT ++typedef struct { ++ volatile int counter; ++} atomic_unchecked_t; ++#else ++typedef atomic_t atomic_unchecked_t; ++#endif ++ + #ifdef CONFIG_64BIT + typedef struct { + volatile long counter; + } atomic64_t; ++ ++#ifdef CONFIG_PAX_REFCOUNT ++typedef struct { ++ volatile long counter; ++} atomic64_unchecked_t; ++#else ++typedef atomic64_t atomic64_unchecked_t; ++#endif + #endif + + struct ustat { +diff -urNp linux-2.6.31.1/include/linux/uaccess.h linux-2.6.31.1/include/linux/uaccess.h +--- linux-2.6.31.1/include/linux/uaccess.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/uaccess.h 2009-10-01 20:12:44.000000000 -0400 +@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_ + long ret; \ + mm_segment_t old_fs = get_fs(); \ + \ +- set_fs(KERNEL_DS); \ + pagefault_disable(); \ ++ set_fs(KERNEL_DS); \ + ret = __copy_from_user_inatomic(&(retval), (__force typeof(retval) __user *)(addr), sizeof(retval)); \ +- pagefault_enable(); \ + set_fs(old_fs); \ ++ pagefault_enable(); \ + ret; \ + }) + +diff -urNp linux-2.6.31.1/include/linux/vmalloc.h linux-2.6.31.1/include/linux/vmalloc.h +--- linux-2.6.31.1/include/linux/vmalloc.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/linux/vmalloc.h 2009-10-01 20:12:44.000000000 -0400 +@@ -13,6 +13,11 @@ struct vm_area_struct; /* vma defining + #define VM_MAP 0x00000004 /* vmap()ed pages */ + #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */ + #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */ ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++#define VM_KERNEXEC 0x00000020 /* allocate from executable kernel memory range */ ++#endif ++ + /* bits [20..32] reserved for arch specific ioremap internals */ + + /* +@@ -115,4 +120,81 @@ extern rwlock_t vmlist_lock; + extern struct vm_struct *vmlist; + extern __init void vm_area_register_early(struct vm_struct *vm, size_t align); + ++#define vmalloc(x) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "vmalloc size overflow\n")) \ ++ ___retval = NULL; \ ++ else \ ++ ___retval = vmalloc((unsigned long)___x); \ ++ ___retval; \ ++}) ++ ++#define __vmalloc(x, y, z) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "__vmalloc size overflow\n"))\ ++ ___retval = NULL; \ ++ else \ ++ ___retval = __vmalloc((unsigned long)___x, (y), (z));\ ++ ___retval; \ ++}) ++ ++#define vmalloc_user(x) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "vmalloc_user size overflow\n"))\ ++ ___retval = NULL; \ ++ else \ ++ ___retval = vmalloc_user((unsigned long)___x); \ ++ ___retval; \ ++}) ++ ++#define vmalloc_exec(x) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "vmalloc_exec size overflow\n"))\ ++ ___retval = NULL; \ ++ else \ ++ ___retval = vmalloc_exec((unsigned long)___x); \ ++ ___retval; \ ++}) ++ ++#define vmalloc_node(x, y) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "vmalloc_node size overflow\n"))\ ++ ___retval = NULL; \ ++ else \ ++ ___retval = vmalloc_node((unsigned long)___x, (y));\ ++ ___retval; \ ++}) ++ ++#define vmalloc_32(x) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "vmalloc_32 size overflow\n"))\ ++ ___retval = NULL; \ ++ else \ ++ ___retval = vmalloc_32((unsigned long)___x); \ ++ ___retval; \ ++}) ++ ++#define vmalloc_32_user(x) \ ++({ \ ++ void *___retval; \ ++ intoverflow_t ___x = (intoverflow_t)x; \ ++ if (WARN(___x > ULONG_MAX, "vmalloc_32_user size overflow\n"))\ ++ ___retval = NULL; \ ++ else \ ++ ___retval = vmalloc_32_user((unsigned long)___x);\ ++ ___retval; \ ++}) ++ + #endif /* _LINUX_VMALLOC_H */ +diff -urNp linux-2.6.31.1/include/net/irda/ircomm_tty.h linux-2.6.31.1/include/net/irda/ircomm_tty.h +--- linux-2.6.31.1/include/net/irda/ircomm_tty.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/net/irda/ircomm_tty.h 2009-10-01 20:12:44.000000000 -0400 +@@ -105,8 +105,8 @@ struct ircomm_tty_cb { + unsigned short close_delay; + unsigned short closing_wait; /* time to wait before closing */ + +- int open_count; +- int blocked_open; /* # of blocked opens */ ++ atomic_t open_count; ++ atomic_t blocked_open; /* # of blocked opens */ + + /* Protect concurent access to : + * o self->open_count +diff -urNp linux-2.6.31.1/include/net/sctp/sctp.h linux-2.6.31.1/include/net/sctp/sctp.h +--- linux-2.6.31.1/include/net/sctp/sctp.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/net/sctp/sctp.h 2009-10-01 20:12:44.000000000 -0400 +@@ -305,8 +305,8 @@ extern int sctp_debug_flag; + + #else /* SCTP_DEBUG */ + +-#define SCTP_DEBUG_PRINTK(whatever...) +-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) ++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0) ++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0) + #define SCTP_ENABLE_DEBUG + #define SCTP_DISABLE_DEBUG + #define SCTP_ASSERT(expr, str, func) +diff -urNp linux-2.6.31.1/include/sound/core.h linux-2.6.31.1/include/sound/core.h +--- linux-2.6.31.1/include/sound/core.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/sound/core.h 2009-10-01 20:12:44.000000000 -0400 +@@ -430,7 +430,7 @@ static inline int __snd_bug_on(int cond) + */ + #define snd_printdd(format, args...) snd_printk(format, ##args) + #else +-#define snd_printdd(format, args...) /* nothing */ ++#define snd_printdd(format, args...) do {} while (0) + #endif + + +diff -urNp linux-2.6.31.1/include/video/uvesafb.h linux-2.6.31.1/include/video/uvesafb.h +--- linux-2.6.31.1/include/video/uvesafb.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/include/video/uvesafb.h 2009-10-01 20:12:44.000000000 -0400 +@@ -177,6 +177,7 @@ struct uvesafb_par { + u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */ + u8 pmi_setpal; /* PMI for palette changes */ + u16 *pmi_base; /* protected mode interface location */ ++ u8 *pmi_code; /* protected mode code location */ + void *pmi_start; + void *pmi_pal; + u8 *vbe_state_orig; /* +diff -urNp linux-2.6.31.1/init/do_mounts.c linux-2.6.31.1/init/do_mounts.c +--- linux-2.6.31.1/init/do_mounts.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/init/do_mounts.c 2009-10-01 20:12:44.000000000 -0400 +@@ -216,11 +216,11 @@ static void __init get_fs_names(char *pa + + static int __init do_mount_root(char *name, char *fs, int flags, void *data) + { +- int err = sys_mount(name, "/root", fs, flags, data); ++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data); + if (err) + return err; + +- sys_chdir("/root"); ++ sys_chdir((char __user *)"/root"); + ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev; + printk("VFS: Mounted root (%s filesystem)%s on device %u:%u.\n", + current->fs->pwd.mnt->mnt_sb->s_type->name, +@@ -311,18 +311,18 @@ void __init change_floppy(char *fmt, ... + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); ++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0); + if (fd >= 0) { + sys_ioctl(fd, FDEJECT, 0); + sys_close(fd); + } + printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); +- fd = sys_open("/dev/console", O_RDWR, 0); ++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0); + if (fd >= 0) { + sys_ioctl(fd, TCGETS, (long)&termios); + termios.c_lflag &= ~ICANON; + sys_ioctl(fd, TCSETSF, (long)&termios); +- sys_read(fd, &c, 1); ++ sys_read(fd, (char __user *)&c, 1); + termios.c_lflag |= ICANON; + sys_ioctl(fd, TCSETSF, (long)&termios); + sys_close(fd); +@@ -415,7 +415,7 @@ void __init prepare_namespace(void) + + mount_root(); + out: +- sys_mount(".", "/", NULL, MS_MOVE, NULL); +- sys_chroot("."); ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL); ++ sys_chroot((char __user *)"."); + } + +diff -urNp linux-2.6.31.1/init/do_mounts.h linux-2.6.31.1/init/do_mounts.h +--- linux-2.6.31.1/init/do_mounts.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/init/do_mounts.h 2009-10-01 20:12:44.000000000 -0400 +@@ -15,15 +15,15 @@ extern int root_mountflags; + + static inline int create_dev(char *name, dev_t dev) + { +- sys_unlink(name); +- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); ++ sys_unlink((char __user *)name); ++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev)); + } + + #if BITS_PER_LONG == 32 + static inline u32 bstat(char *name) + { + struct stat64 stat; +- if (sys_stat64(name, &stat) != 0) ++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0) + return 0; + if (!S_ISBLK(stat.st_mode)) + return 0; +diff -urNp linux-2.6.31.1/init/do_mounts_initrd.c linux-2.6.31.1/init/do_mounts_initrd.c +--- linux-2.6.31.1/init/do_mounts_initrd.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/init/do_mounts_initrd.c 2009-10-01 20:12:44.000000000 -0400 +@@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel + sys_close(old_fd);sys_close(root_fd); + sys_close(0);sys_close(1);sys_close(2); + sys_setsid(); +- (void) sys_open("/dev/console",O_RDWR,0); ++ (void) sys_open((const char __user *)"/dev/console",O_RDWR,0); + (void) sys_dup(0); + (void) sys_dup(0); + return kernel_execve(shell, argv, envp_init); +@@ -47,13 +47,13 @@ static void __init handle_initrd(void) + create_dev("/dev/root.old", Root_RAM0); + /* mount initrd on rootfs' /root */ + mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); +- sys_mkdir("/old", 0700); +- root_fd = sys_open("/", 0, 0); +- old_fd = sys_open("/old", 0, 0); ++ sys_mkdir((const char __user *)"/old", 0700); ++ root_fd = sys_open((const char __user *)"/", 0, 0); ++ old_fd = sys_open((const char __user *)"/old", 0, 0); + /* move initrd over / and chdir/chroot in initrd root */ +- sys_chdir("/root"); +- sys_mount(".", "/", NULL, MS_MOVE, NULL); +- sys_chroot("."); ++ sys_chdir((const char __user *)"/root"); ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL); ++ sys_chroot((const char __user *)"."); + + /* + * In case that a resume from disk is carried out by linuxrc or one of +@@ -70,15 +70,15 @@ static void __init handle_initrd(void) + + /* move initrd to rootfs' /old */ + sys_fchdir(old_fd); +- sys_mount("/", ".", NULL, MS_MOVE, NULL); ++ sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL); + /* switch root and cwd back to / of rootfs */ + sys_fchdir(root_fd); +- sys_chroot("."); ++ sys_chroot((const char __user *)"."); + sys_close(old_fd); + sys_close(root_fd); + + if (new_decode_dev(real_root_dev) == Root_RAM0) { +- sys_chdir("/old"); ++ sys_chdir((const char __user *)"/old"); + return; + } + +@@ -86,17 +86,17 @@ static void __init handle_initrd(void) + mount_root(); + + printk(KERN_NOTICE "Trying to move old root to /initrd ... "); +- error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); ++ error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL); + if (!error) + printk("okay\n"); + else { +- int fd = sys_open("/dev/root.old", O_RDWR, 0); ++ int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0); + if (error == -ENOENT) + printk("/initrd does not exist. Ignored.\n"); + else + printk("failed\n"); + printk(KERN_NOTICE "Unmounting old root\n"); +- sys_umount("/old", MNT_DETACH); ++ sys_umount((char __user *)"/old", MNT_DETACH); + printk(KERN_NOTICE "Trying to free ramdisk memory ... "); + if (fd < 0) { + error = fd; +@@ -119,11 +119,11 @@ int __init initrd_load(void) + * mounted in the normal path. + */ + if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) { +- sys_unlink("/initrd.image"); ++ sys_unlink((const char __user *)"/initrd.image"); + handle_initrd(); + return 1; + } + } +- sys_unlink("/initrd.image"); ++ sys_unlink((const char __user *)"/initrd.image"); + return 0; + } +diff -urNp linux-2.6.31.1/init/do_mounts_md.c linux-2.6.31.1/init/do_mounts_md.c +--- linux-2.6.31.1/init/do_mounts_md.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/init/do_mounts_md.c 2009-10-01 20:12:44.000000000 -0400 +@@ -170,7 +170,7 @@ static void __init md_setup_drive(void) + partitioned ? "_d" : "", minor, + md_setup_args[ent].device_names); + +- fd = sys_open(name, 0, 0); ++ fd = sys_open((char __user *)name, 0, 0); + if (fd < 0) { + printk(KERN_ERR "md: open failed - cannot start " + "array %s\n", name); +@@ -233,7 +233,7 @@ static void __init md_setup_drive(void) + * array without it + */ + sys_close(fd); +- fd = sys_open(name, 0, 0); ++ fd = sys_open((char __user *)name, 0, 0); + sys_ioctl(fd, BLKRRPART, 0); + } + sys_close(fd); +@@ -283,7 +283,7 @@ static void __init autodetect_raid(void) + + wait_for_device_probe(); + +- fd = sys_open("/dev/md0", 0, 0); ++ fd = sys_open((char __user *)"/dev/md0", 0, 0); + if (fd >= 0) { + sys_ioctl(fd, RAID_AUTORUN, raid_autopart); + sys_close(fd); +diff -urNp linux-2.6.31.1/init/initramfs.c linux-2.6.31.1/init/initramfs.c +--- linux-2.6.31.1/init/initramfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/init/initramfs.c 2009-10-01 20:12:44.000000000 -0400 +@@ -271,7 +271,7 @@ static int __init maybe_link(void) + if (nlink >= 2) { + char *old = find_link(major, minor, ino, mode, collected); + if (old) +- return (sys_link(old, collected) < 0) ? -1 : 1; ++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1; + } + return 0; + } +@@ -280,11 +280,11 @@ static void __init clean_path(char *path + { + struct stat st; + +- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) { ++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) { + if (S_ISDIR(st.st_mode)) +- sys_rmdir(path); ++ sys_rmdir((char __user *)path); + else +- sys_unlink(path); ++ sys_unlink((char __user *)path); + } + } + +@@ -305,7 +305,7 @@ static int __init do_name(void) + int openflags = O_WRONLY|O_CREAT; + if (ml != 1) + openflags |= O_TRUNC; +- wfd = sys_open(collected, openflags, mode); ++ wfd = sys_open((char __user *)collected, openflags, mode); + + if (wfd >= 0) { + sys_fchown(wfd, uid, gid); +@@ -317,16 +317,16 @@ static int __init do_name(void) + } + } + } else if (S_ISDIR(mode)) { +- sys_mkdir(collected, mode); +- sys_chown(collected, uid, gid); +- sys_chmod(collected, mode); ++ sys_mkdir((char __user *)collected, mode); ++ sys_chown((char __user *)collected, uid, gid); ++ sys_chmod((char __user *)collected, mode); + dir_add(collected, mtime); + } else if (S_ISBLK(mode) || S_ISCHR(mode) || + S_ISFIFO(mode) || S_ISSOCK(mode)) { + if (maybe_link() == 0) { +- sys_mknod(collected, mode, rdev); +- sys_chown(collected, uid, gid); +- sys_chmod(collected, mode); ++ sys_mknod((char __user *)collected, mode, rdev); ++ sys_chown((char __user *)collected, uid, gid); ++ sys_chmod((char __user *)collected, mode); + do_utime(collected, mtime); + } + } +@@ -336,7 +336,7 @@ static int __init do_name(void) + static int __init do_copy(void) + { + if (count >= body_len) { +- sys_write(wfd, victim, body_len); ++ sys_write(wfd, (char __user *)victim, body_len); + sys_close(wfd); + do_utime(vcollected, mtime); + kfree(vcollected); +@@ -344,7 +344,7 @@ static int __init do_copy(void) + state = SkipIt; + return 0; + } else { +- sys_write(wfd, victim, count); ++ sys_write(wfd, (char __user *)victim, count); + body_len -= count; + eat(count); + return 1; +@@ -355,8 +355,8 @@ static int __init do_symlink(void) + { + collected[N_ALIGN(name_len) + body_len] = '\0'; + clean_path(collected, 0); +- sys_symlink(collected + N_ALIGN(name_len), collected); +- sys_lchown(collected, uid, gid); ++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected); ++ sys_lchown((char __user *)collected, uid, gid); + do_utime(collected, mtime); + state = SkipIt; + next_state = Reset; +diff -urNp linux-2.6.31.1/init/Kconfig linux-2.6.31.1/init/Kconfig +--- linux-2.6.31.1/init/Kconfig 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/init/Kconfig 2009-10-01 20:12:44.000000000 -0400 +@@ -1014,7 +1014,7 @@ config STRIP_ASM_SYMS + + config COMPAT_BRK + bool "Disable heap randomization" +- default y ++ default n + help + Randomizing heap placement makes heap exploits harder, but it + also breaks ancient binaries (including anything libc5 based). +@@ -1101,9 +1101,9 @@ config HAVE_GENERIC_DMA_COHERENT + + config SLABINFO + bool +- depends on PROC_FS ++ depends on PROC_FS && !GRKERNSEC_PROC_ADD + depends on SLAB || SLUB_DEBUG +- default y ++ default n + + config RT_MUTEXES + boolean +diff -urNp linux-2.6.31.1/init/main.c linux-2.6.31.1/init/main.c +--- linux-2.6.31.1/init/main.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/init/main.c 2009-10-01 20:12:44.000000000 -0400 +@@ -96,6 +96,7 @@ static inline void mark_rodata_ro(void) + #ifdef CONFIG_TC + extern void tc_init(void); + #endif ++extern void grsecurity_init(void); + + enum system_states system_state __read_mostly; + EXPORT_SYMBOL(system_state); +@@ -182,6 +183,35 @@ static int __init set_reset_devices(char + + __setup("reset_devices", set_reset_devices); + ++#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32) ++static int __init setup_pax_nouderef(char *str) ++{ ++ unsigned int cpu; ++ ++ for (cpu = 0; cpu < NR_CPUS; cpu++) { ++ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].type = 3; ++ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].limit = 0xf; ++ } ++ asm("mov %0, %%ds" : : "r" (__KERNEL_DS) : "memory"); ++ asm("mov %0, %%es" : : "r" (__KERNEL_DS) : "memory"); ++ asm("mov %0, %%ss" : : "r" (__KERNEL_DS) : "memory"); ++ ++ return 0; ++} ++early_param("pax_nouderef", setup_pax_nouderef); ++#endif ++ ++#ifdef CONFIG_PAX_SOFTMODE ++unsigned int pax_softmode; ++ ++static int __init setup_pax_softmode(char *str) ++{ ++ get_option(&str, &pax_softmode); ++ return 1; ++} ++__setup("pax_softmode=", setup_pax_softmode); ++#endif ++ + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; + char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; + static const char *panic_later, *panic_param; +@@ -375,7 +405,7 @@ static void __init setup_nr_cpu_ids(void + } + + #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA +-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; ++unsigned long __per_cpu_offset[NR_CPUS] __read_only; + + EXPORT_SYMBOL(__per_cpu_offset); + +@@ -741,6 +771,7 @@ int do_one_initcall(initcall_t fn) + { + int count = preempt_count(); + ktime_t calltime, delta, rettime; ++ const char *msg1 = "", *msg2 = ""; + + if (initcall_debug) { + call.caller = task_pid_nr(current); +@@ -768,15 +799,15 @@ int do_one_initcall(initcall_t fn) + sprintf(msgbuf, "error code %d ", ret.result); + + if (preempt_count() != count) { +- strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf)); ++ msg1 = " preemption imbalance"; + preempt_count() = count; + } + if (irqs_disabled()) { +- strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf)); ++ msg2 = " disabled interrupts"; + local_irq_enable(); + } +- if (msgbuf[0]) { +- printk("initcall %pF returned with %s\n", fn, msgbuf); ++ if (msgbuf[0] || *msg1 || *msg2) { ++ printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2); + } + + return ret.result; +@@ -923,6 +954,8 @@ static int __init kernel_init(void * unu + prepare_namespace(); + } + ++ grsecurity_init(); ++ + /* + * Ok, we have completed the initial bootup, and + * we're essentially up and running. Get rid of the +diff -urNp linux-2.6.31.1/init/noinitramfs.c linux-2.6.31.1/init/noinitramfs.c +--- linux-2.6.31.1/init/noinitramfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/init/noinitramfs.c 2009-10-01 20:12:44.000000000 -0400 +@@ -29,7 +29,7 @@ static int __init default_rootfs(void) + { + int err; + +- err = sys_mkdir("/dev", 0755); ++ err = sys_mkdir((const char __user *)"/dev", 0755); + if (err < 0) + goto out; + +@@ -39,7 +39,7 @@ static int __init default_rootfs(void) + if (err < 0) + goto out; + +- err = sys_mkdir("/root", 0700); ++ err = sys_mkdir((const char __user *)"/root", 0700); + if (err < 0) + goto out; + +diff -urNp linux-2.6.31.1/ipc/ipc_sysctl.c linux-2.6.31.1/ipc/ipc_sysctl.c +--- linux-2.6.31.1/ipc/ipc_sysctl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/ipc/ipc_sysctl.c 2009-10-01 20:12:44.000000000 -0400 +@@ -267,7 +267,7 @@ static struct ctl_table ipc_kern_table[] + .extra1 = &zero, + .extra2 = &one, + }, +- {} ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + + static struct ctl_table ipc_root_table[] = { +@@ -277,7 +277,7 @@ static struct ctl_table ipc_root_table[] + .mode = 0555, + .child = ipc_kern_table, + }, +- {} ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + + static int __init ipc_sysctl_init(void) +diff -urNp linux-2.6.31.1/ipc/mqueue.c linux-2.6.31.1/ipc/mqueue.c +--- linux-2.6.31.1/ipc/mqueue.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/ipc/mqueue.c 2009-10-01 20:12:44.000000000 -0400 +@@ -77,7 +77,7 @@ struct mqueue_inode_info { + + static const struct inode_operations mqueue_dir_inode_operations; + static const struct file_operations mqueue_file_operations; +-static struct super_operations mqueue_super_ops; ++static const struct super_operations mqueue_super_ops; + static void remove_notification(struct mqueue_inode_info *info); + + static struct kmem_cache *mqueue_inode_cachep; +@@ -150,6 +150,7 @@ static struct inode *mqueue_get_inode(st + mq_bytes = (mq_msg_tblsz + + (info->attr.mq_maxmsg * info->attr.mq_msgsize)); + ++ gr_learn_resource(current, RLIMIT_MSGQUEUE, u->mq_bytes + mq_bytes, 1); + spin_lock(&mq_lock); + if (u->mq_bytes + mq_bytes < u->mq_bytes || + u->mq_bytes + mq_bytes > +@@ -1224,7 +1225,7 @@ static const struct file_operations mque + .read = mqueue_read_file, + }; + +-static struct super_operations mqueue_super_ops = { ++static const struct super_operations mqueue_super_ops = { + .alloc_inode = mqueue_alloc_inode, + .destroy_inode = mqueue_destroy_inode, + .statfs = simple_statfs, +diff -urNp linux-2.6.31.1/ipc/shm.c linux-2.6.31.1/ipc/shm.c +--- linux-2.6.31.1/ipc/shm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/ipc/shm.c 2009-10-01 20:12:44.000000000 -0400 +@@ -55,7 +55,7 @@ struct shm_file_data { + #define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data)) + + static const struct file_operations shm_file_operations; +-static struct vm_operations_struct shm_vm_ops; ++static const struct vm_operations_struct shm_vm_ops; + + #define shm_ids(ns) ((ns)->ids[IPC_SHM_IDS]) + +@@ -70,6 +70,14 @@ static void shm_destroy (struct ipc_name + static int sysvipc_shm_proc_show(struct seq_file *s, void *it); + #endif + ++#ifdef CONFIG_GRKERNSEC ++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, ++ const time_t shm_createtime, const uid_t cuid, ++ const int shmid); ++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid, ++ const time_t shm_createtime); ++#endif ++ + void shm_init_ns(struct ipc_namespace *ns) + { + ns->shm_ctlmax = SHMMAX; +@@ -312,7 +320,7 @@ static const struct file_operations shm_ + .get_unmapped_area = shm_get_unmapped_area, + }; + +-static struct vm_operations_struct shm_vm_ops = { ++static const struct vm_operations_struct shm_vm_ops = { + .open = shm_open, /* callback for a new vm-area open */ + .close = shm_close, /* callback for when the vm-area is released */ + .fault = shm_fault, +@@ -395,6 +403,14 @@ static int newseg(struct ipc_namespace * + shp->shm_lprid = 0; + shp->shm_atim = shp->shm_dtim = 0; + shp->shm_ctim = get_seconds(); ++#ifdef CONFIG_GRKERNSEC ++ { ++ struct timespec timeval; ++ do_posix_clock_monotonic_gettime(&timeval); ++ ++ shp->shm_createtime = timeval.tv_sec; ++ } ++#endif + shp->shm_segsz = size; + shp->shm_nattch = 0; + shp->shm_file = file; +@@ -878,9 +894,21 @@ long do_shmat(int shmid, char __user *sh + if (err) + goto out_unlock; + ++#ifdef CONFIG_GRKERNSEC ++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime, ++ shp->shm_perm.cuid, shmid) || ++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) { ++ err = -EACCES; ++ goto out_unlock; ++ } ++#endif ++ + path.dentry = dget(shp->shm_file->f_path.dentry); + path.mnt = shp->shm_file->f_path.mnt; + shp->shm_nattch++; ++#ifdef CONFIG_GRKERNSEC ++ shp->shm_lapid = current->pid; ++#endif + size = i_size_read(path.dentry->d_inode); + shm_unlock(shp); + +diff -urNp linux-2.6.31.1/ipc/util.c linux-2.6.31.1/ipc/util.c +--- linux-2.6.31.1/ipc/util.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/ipc/util.c 2009-10-01 20:12:44.000000000 -0400 +@@ -942,7 +942,7 @@ static int sysvipc_proc_show(struct seq_ + return iface->show(s, it); + } + +-static struct seq_operations sysvipc_proc_seqops = { ++static const struct seq_operations sysvipc_proc_seqops = { + .start = sysvipc_proc_start, + .stop = sysvipc_proc_stop, + .next = sysvipc_proc_next, +diff -urNp linux-2.6.31.1/kernel/acct.c linux-2.6.31.1/kernel/acct.c +--- linux-2.6.31.1/kernel/acct.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/acct.c 2009-10-01 20:12:44.000000000 -0400 +@@ -574,7 +574,7 @@ static void do_acct_process(struct bsd_a + */ + flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; +- file->f_op->write(file, (char *)&ac, ++ file->f_op->write(file, (char __user *)&ac, + sizeof(acct_t), &file->f_pos); + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim; + set_fs(fs); +diff -urNp linux-2.6.31.1/kernel/capability.c linux-2.6.31.1/kernel/capability.c +--- linux-2.6.31.1/kernel/capability.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/capability.c 2009-10-01 20:12:44.000000000 -0400 +@@ -306,10 +306,21 @@ int capable(int cap) + BUG(); + } + +- if (security_capable(cap) == 0) { ++ if (security_capable(cap) == 0 && gr_is_capable(cap)) { + current->flags |= PF_SUPERPRIV; + return 1; + } + return 0; + } ++ ++int capable_nolog(int cap) ++{ ++ if (security_capable(cap) == 0 && gr_is_capable_nolog(cap)) { ++ current->flags |= PF_SUPERPRIV; ++ return 1; ++ } ++ return 0; ++} ++ + EXPORT_SYMBOL(capable); ++EXPORT_SYMBOL(capable_nolog); +diff -urNp linux-2.6.31.1/kernel/cgroup.c linux-2.6.31.1/kernel/cgroup.c +--- linux-2.6.31.1/kernel/cgroup.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/cgroup.c 2009-10-01 20:12:44.000000000 -0400 +@@ -596,8 +596,8 @@ void cgroup_unlock(void) + static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode); + static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry); + static int cgroup_populate_dir(struct cgroup *cgrp); +-static struct inode_operations cgroup_dir_inode_operations; +-static struct file_operations proc_cgroupstats_operations; ++static const struct inode_operations cgroup_dir_inode_operations; ++static const struct file_operations proc_cgroupstats_operations; + + static struct backing_dev_info cgroup_backing_dev_info = { + .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, +@@ -960,7 +960,7 @@ static int cgroup_remount(struct super_b + return ret; + } + +-static struct super_operations cgroup_ops = { ++static const struct super_operations cgroup_ops = { + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, + .show_options = cgroup_show_options, +@@ -1643,7 +1643,7 @@ static int cgroup_seqfile_release(struct + return single_release(inode, file); + } + +-static struct file_operations cgroup_seqfile_operations = { ++static const struct file_operations cgroup_seqfile_operations = { + .read = seq_read, + .write = cgroup_file_write, + .llseek = seq_lseek, +@@ -1702,7 +1702,7 @@ static int cgroup_rename(struct inode *o + return simple_rename(old_dir, old_dentry, new_dir, new_dentry); + } + +-static struct file_operations cgroup_file_operations = { ++static const struct file_operations cgroup_file_operations = { + .read = cgroup_file_read, + .write = cgroup_file_write, + .llseek = generic_file_llseek, +@@ -1710,7 +1710,7 @@ static struct file_operations cgroup_fil + .release = cgroup_file_release, + }; + +-static struct inode_operations cgroup_dir_inode_operations = { ++static const struct inode_operations cgroup_dir_inode_operations = { + .lookup = simple_lookup, + .mkdir = cgroup_mkdir, + .rmdir = cgroup_rmdir, +@@ -2313,7 +2313,7 @@ static int cgroup_tasks_show(struct seq_ + return seq_printf(s, "%d\n", *(int *)v); + } + +-static struct seq_operations cgroup_tasks_seq_operations = { ++static const struct seq_operations cgroup_tasks_seq_operations = { + .start = cgroup_tasks_start, + .stop = cgroup_tasks_stop, + .next = cgroup_tasks_next, +@@ -2350,7 +2350,7 @@ static int cgroup_tasks_release(struct i + return seq_release(inode, file); + } + +-static struct file_operations cgroup_tasks_operations = { ++static const struct file_operations cgroup_tasks_operations = { + .read = seq_read, + .llseek = seq_lseek, + .write = cgroup_file_write, +@@ -3016,7 +3016,7 @@ static int cgroup_open(struct inode *ino + return single_open(file, proc_cgroup_show, pid); + } + +-struct file_operations proc_cgroup_operations = { ++const struct file_operations proc_cgroup_operations = { + .open = cgroup_open, + .read = seq_read, + .llseek = seq_lseek, +@@ -3045,7 +3045,7 @@ static int cgroupstats_open(struct inode + return single_open(file, proc_cgroupstats_show, NULL); + } + +-static struct file_operations proc_cgroupstats_operations = { ++static const struct file_operations proc_cgroupstats_operations = { + .open = cgroupstats_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/kernel/configs.c linux-2.6.31.1/kernel/configs.c +--- linux-2.6.31.1/kernel/configs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/configs.c 2009-10-01 20:12:44.000000000 -0400 +@@ -73,8 +73,19 @@ static int __init ikconfig_init(void) + struct proc_dir_entry *entry; + + /* create the current config file */ ++#if defined(CONFIG_GRKERNSEC_PROC_ADD) || defined(CONFIG_GRKERNSEC_HIDESYM) ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_HIDESYM) ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL, ++ &ikconfig_file_ops); ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL, ++ &ikconfig_file_ops); ++#endif ++#else + entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL, + &ikconfig_file_ops); ++#endif ++ + if (!entry) + return -ENOMEM; + +diff -urNp linux-2.6.31.1/kernel/cpu.c linux-2.6.31.1/kernel/cpu.c +--- linux-2.6.31.1/kernel/cpu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/cpu.c 2009-10-01 20:12:44.000000000 -0400 +@@ -19,7 +19,7 @@ + /* Serializes the updates to cpu_online_mask, cpu_present_mask */ + static DEFINE_MUTEX(cpu_add_remove_lock); + +-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain); ++static RAW_NOTIFIER_HEAD(cpu_chain); + + /* If set, cpu_up and cpu_down will return -EBUSY and do nothing. + * Should always be manipulated under cpu_add_remove_lock +diff -urNp linux-2.6.31.1/kernel/cred.c linux-2.6.31.1/kernel/cred.c +--- linux-2.6.31.1/kernel/cred.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/cred.c 2009-10-01 20:12:44.000000000 -0400 +@@ -366,6 +366,8 @@ int commit_creds(struct cred *new) + + get_cred(new); /* we will require a ref for the subj creds too */ + ++ gr_set_role_label(task, new->uid, new->gid); ++ + /* dumpability changes */ + if (old->euid != new->euid || + old->egid != new->egid || +diff -urNp linux-2.6.31.1/kernel/exit.c linux-2.6.31.1/kernel/exit.c +--- linux-2.6.31.1/kernel/exit.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/exit.c 2009-10-01 20:12:44.000000000 -0400 +@@ -56,6 +56,10 @@ + #include <asm/mmu_context.h> + #include "cred-internals.h" + ++#ifdef CONFIG_GRKERNSEC ++extern rwlock_t grsec_exec_file_lock; ++#endif ++ + static void exit_mm(struct task_struct * tsk); + + static void __unhash_process(struct task_struct *p) +@@ -167,6 +171,8 @@ void release_task(struct task_struct * p + struct task_struct *leader; + int zap_leader; + repeat: ++ gr_del_task_from_ip_table(p); ++ + tracehook_prepare_release_task(p); + /* don't need to get the RCU readlock here - the process is dead and + * can't be modifying its own credentials */ +@@ -334,11 +340,22 @@ static void reparent_to_kthreadd(void) + { + write_lock_irq(&tasklist_lock); + ++#ifdef CONFIG_GRKERNSEC ++ write_lock(&grsec_exec_file_lock); ++ if (current->exec_file) { ++ fput(current->exec_file); ++ current->exec_file = NULL; ++ } ++ write_unlock(&grsec_exec_file_lock); ++#endif ++ + ptrace_unlink(current); + /* Reparent to init */ + current->real_parent = current->parent = kthreadd_task; + list_move_tail(¤t->sibling, ¤t->real_parent->children); + ++ gr_set_kernel_label(current); ++ + /* Set the exit signal to SIGCHLD so we signal init on exit */ + current->exit_signal = SIGCHLD; + +@@ -426,6 +443,17 @@ void daemonize(const char *name, ...) + vsnprintf(current->comm, sizeof(current->comm), name, args); + va_end(args); + ++#ifdef CONFIG_GRKERNSEC ++ write_lock(&grsec_exec_file_lock); ++ if (current->exec_file) { ++ fput(current->exec_file); ++ current->exec_file = NULL; ++ } ++ write_unlock(&grsec_exec_file_lock); ++#endif ++ ++ gr_set_kernel_label(current); ++ + /* + * If we were started as result of loading a module, close all of the + * user space pages. We don't need them, and if we didn't close them +@@ -953,6 +981,9 @@ NORET_TYPE void do_exit(long code) + tsk->exit_code = code; + taskstats_exit(tsk, group_dead); + ++ gr_acl_handle_psacct(tsk, code); ++ gr_acl_handle_exit(); ++ + exit_mm(tsk); + + if (group_dead) +@@ -1171,7 +1202,7 @@ static int wait_task_zombie(struct wait_ + + if (unlikely(wo->wo_flags & WNOWAIT)) { + int exit_code = p->exit_code; +- int why, status; ++ int why; + + get_task_struct(p); + read_unlock(&tasklist_lock); +diff -urNp linux-2.6.31.1/kernel/fork.c linux-2.6.31.1/kernel/fork.c +--- linux-2.6.31.1/kernel/fork.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/fork.c 2009-10-01 20:12:45.000000000 -0400 +@@ -244,7 +244,7 @@ static struct task_struct *dup_task_stru + *stackend = STACK_END_MAGIC; /* for overflow detection */ + + #ifdef CONFIG_CC_STACKPROTECTOR +- tsk->stack_canary = get_random_int(); ++ tsk->stack_canary = pax_get_random_long(); + #endif + + /* One for us, one for whoever does the "release_task()" (usually parent) */ +@@ -281,8 +281,8 @@ static int dup_mmap(struct mm_struct *mm + mm->locked_vm = 0; + mm->mmap = NULL; + mm->mmap_cache = NULL; +- mm->free_area_cache = oldmm->mmap_base; +- mm->cached_hole_size = ~0UL; ++ mm->free_area_cache = oldmm->free_area_cache; ++ mm->cached_hole_size = oldmm->cached_hole_size; + mm->map_count = 0; + cpumask_clear(mm_cpumask(mm)); + mm->mm_rb = RB_ROOT; +@@ -319,6 +319,7 @@ static int dup_mmap(struct mm_struct *mm + tmp->vm_flags &= ~VM_LOCKED; + tmp->vm_mm = mm; + tmp->vm_next = NULL; ++ tmp->vm_mirror = NULL; + anon_vma_link(tmp); + file = tmp->vm_file; + if (file) { +@@ -366,6 +367,31 @@ static int dup_mmap(struct mm_struct *mm + if (retval) + goto out; + } ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) { ++ struct vm_area_struct *mpnt_m; ++ ++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) { ++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm); ++ ++ if (!mpnt->vm_mirror) ++ continue; ++ ++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) { ++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt); ++ mpnt->vm_mirror = mpnt_m; ++ } else { ++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm); ++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror; ++ mpnt_m->vm_mirror->vm_mirror = mpnt_m; ++ mpnt->vm_mirror->vm_mirror = mpnt; ++ } ++ } ++ BUG_ON(mpnt_m); ++ } ++#endif ++ + /* a new mm has just been created */ + arch_dup_mmap(oldmm, mm); + retval = 0; +@@ -546,9 +572,11 @@ void mm_release(struct task_struct *tsk, + #ifdef CONFIG_FUTEX + if (unlikely(tsk->robust_list)) + exit_robust_list(tsk); ++ tsk->robust_list = NULL; + #ifdef CONFIG_COMPAT + if (unlikely(tsk->compat_robust_list)) + compat_exit_robust_list(tsk); ++ tsk->compat_robust_list = NULL; + #endif + #endif + +@@ -567,6 +595,7 @@ void mm_release(struct task_struct *tsk, + * the value intact in a core dump, and to save the unnecessary + * trouble otherwise. Userland only wants this done for a sys_exit. + */ ++ + if (tsk->clear_child_tid) { + if (!(tsk->flags & PF_SIGNALED) && + atomic_read(&mm->mm_users) > 1) { +@@ -576,7 +605,7 @@ void mm_release(struct task_struct *tsk, + */ + put_user(0, tsk->clear_child_tid); + sys_futex(tsk->clear_child_tid, FUTEX_WAKE, +- 1, NULL, NULL, 0); ++ 1, NULL, NULL, 0); + } + tsk->clear_child_tid = NULL; + } +@@ -694,7 +723,7 @@ static int copy_fs(unsigned long clone_f + write_unlock(&fs->lock); + return -EAGAIN; + } +- fs->users++; ++ atomic_inc(&fs->users); + write_unlock(&fs->lock); + return 0; + } +@@ -977,6 +1006,9 @@ static struct task_struct *copy_process( + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); + #endif + retval = -EAGAIN; ++ ++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->real_cred->user->processes), 0); ++ + if (atomic_read(&p->real_cred->user->processes) >= + p->signal->rlim[RLIMIT_NPROC].rlim_cur) { + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && +@@ -1133,6 +1165,8 @@ static struct task_struct *copy_process( + goto bad_fork_free_pid; + } + ++ gr_copy_label(p); ++ + p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; + /* + * Clear TID on mm_release()? +@@ -1302,6 +1336,8 @@ bad_fork_cleanup_count: + bad_fork_free: + free_task(p); + fork_out: ++ gr_log_forkfail(retval); ++ + return ERR_PTR(retval); + } + +@@ -1395,6 +1431,8 @@ long do_fork(unsigned long clone_flags, + if (clone_flags & CLONE_PARENT_SETTID) + put_user(nr, parent_tidptr); + ++ gr_handle_brute_check(); ++ + if (clone_flags & CLONE_VFORK) { + p->vfork_done = &vfork; + init_completion(&vfork); +@@ -1527,7 +1565,7 @@ static int unshare_fs(unsigned long unsh + return 0; + + /* don't need lock here; in the worst case we'll do useless copy */ +- if (fs->users == 1) ++ if (atomic_read(&fs->users) == 1) + return 0; + + *new_fsp = copy_fs_struct(fs); +@@ -1650,7 +1688,7 @@ SYSCALL_DEFINE1(unshare, unsigned long, + fs = current->fs; + write_lock(&fs->lock); + current->fs = new_fs; +- if (--fs->users) ++ if (atomic_dec_return(&fs->users)) + new_fs = NULL; + else + new_fs = fs; +diff -urNp linux-2.6.31.1/kernel/futex.c linux-2.6.31.1/kernel/futex.c +--- linux-2.6.31.1/kernel/futex.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/futex.c 2009-10-01 20:12:45.000000000 -0400 +@@ -218,6 +218,11 @@ get_futex_key(u32 __user *uaddr, int fsh + struct page *page; + int err; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE) ++ return -EFAULT; ++#endif ++ + /* + * The futex address must be "naturally" aligned. + */ +@@ -1788,7 +1793,7 @@ static int futex_wait(u32 __user *uaddr, + + restart = ¤t_thread_info()->restart_block; + restart->fn = futex_wait_restart; +- restart->futex.uaddr = (u32 *)uaddr; ++ restart->futex.uaddr = uaddr; + restart->futex.val = val; + restart->futex.time = abs_time->tv64; + restart->futex.bitset = bitset; +@@ -2403,7 +2408,7 @@ retry: + */ + static inline int fetch_robust_entry(struct robust_list __user **entry, + struct robust_list __user * __user *head, +- int *pi) ++ unsigned int *pi) + { + unsigned long uentry; + +diff -urNp linux-2.6.31.1/kernel/gcov/base.c linux-2.6.31.1/kernel/gcov/base.c +--- linux-2.6.31.1/kernel/gcov/base.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/gcov/base.c 2009-10-01 20:12:45.000000000 -0400 +@@ -102,11 +102,6 @@ void gcov_enable_events(void) + } + + #ifdef CONFIG_MODULES +-static inline int within(void *addr, void *start, unsigned long size) +-{ +- return ((addr >= start) && (addr < start + size)); +-} +- + /* Update list and generate events when modules are unloaded. */ + static int gcov_module_notifier(struct notifier_block *nb, unsigned long event, + void *data) +@@ -121,7 +116,7 @@ static int gcov_module_notifier(struct n + prev = NULL; + /* Remove entries located in module from linked list. */ + for (info = gcov_info_head; info; info = info->next) { +- if (within(info, mod->module_core, mod->core_size)) { ++ if (within_module_core_rw((unsigned long)info, mod)) { + if (prev) + prev->next = info->next; + else +diff -urNp linux-2.6.31.1/kernel/kallsyms.c linux-2.6.31.1/kernel/kallsyms.c +--- linux-2.6.31.1/kernel/kallsyms.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/kallsyms.c 2009-10-01 20:12:45.000000000 -0400 +@@ -11,6 +11,9 @@ + * Changed the compression method from stem compression to "table lookup" + * compression (see scripts/kallsyms.c for a more complete description) + */ ++#ifdef CONFIG_GRKERNSEC_HIDESYM ++#define __INCLUDED_BY_HIDESYM 1 ++#endif + #include <linux/kallsyms.h> + #include <linux/module.h> + #include <linux/init.h> +@@ -51,6 +54,9 @@ extern const unsigned long kallsyms_mark + + static inline int is_kernel_inittext(unsigned long addr) + { ++ if (system_state != SYSTEM_BOOTING) ++ return 0; ++ + if (addr >= (unsigned long)_sinittext + && addr <= (unsigned long)_einittext) + return 1; +@@ -66,6 +72,16 @@ static inline int is_kernel_text(unsigne + + static inline int is_kernel(unsigned long addr) + { ++ ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES) ++ if ((unsigned long)&MODULES_EXEC_VADDR <= ktla_ktva(addr) && ++ ktla_ktva(addr) < (unsigned long)&MODULES_EXEC_END) ++ return 0; ++#endif ++ ++ if (is_kernel_inittext(addr)) ++ return 1; ++ + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end) + return 1; + return in_gate_area_no_task(addr); +@@ -412,7 +428,6 @@ static unsigned long get_ksymbol_core(st + + static void reset_iter(struct kallsym_iter *iter, loff_t new_pos) + { +- iter->name[0] = '\0'; + iter->nameoff = get_symbol_offset(new_pos); + iter->pos = new_pos; + } +@@ -500,7 +515,7 @@ static int kallsyms_open(struct inode *i + struct kallsym_iter *iter; + int ret; + +- iter = kmalloc(sizeof(*iter), GFP_KERNEL); ++ iter = kzalloc(sizeof(*iter), GFP_KERNEL); + if (!iter) + return -ENOMEM; + reset_iter(iter, 0); +@@ -522,7 +537,15 @@ static const struct file_operations kall + + static int __init kallsyms_init(void) + { ++#if defined(CONFIG_GRKERNSEC_PROC_ADD) || defined(CONFIG_GRKERNSEC_HIDESYM) ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_HIDESYM) ++ proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations); ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations); ++#endif ++#else + proc_create("kallsyms", 0444, NULL, &kallsyms_operations); ++#endif + return 0; + } + device_initcall(kallsyms_init); +diff -urNp linux-2.6.31.1/kernel/kmod.c linux-2.6.31.1/kernel/kmod.c +--- linux-2.6.31.1/kernel/kmod.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/kmod.c 2009-10-01 20:12:45.000000000 -0400 +@@ -84,6 +84,18 @@ int __request_module(bool wait, const ch + if (ret >= MODULE_NAME_LEN) + return -ENAMETOOLONG; + ++#ifdef CONFIG_GRKERNSEC_MODHARDEN ++ /* we could do a tighter check here, but some distros ++ are taking it upon themselves to remove CAP_SYS_MODULE ++ from even root-running apps which cause modules to be ++ auto-loaded ++ */ ++ if (current_uid()) { ++ gr_log_nonroot_mod_load(module_name); ++ return -EPERM; ++ } ++#endif ++ + /* If modprobe needs a service that is in a module, we get a recursive + * loop. Limit the number of running kmod threads to max_threads/2 or + * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method +diff -urNp linux-2.6.31.1/kernel/kprobes.c linux-2.6.31.1/kernel/kprobes.c +--- linux-2.6.31.1/kernel/kprobes.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/kprobes.c 2009-10-01 20:12:45.000000000 -0400 +@@ -184,7 +184,7 @@ static kprobe_opcode_t __kprobes *__get_ + * kernel image and loaded module images reside. This is required + * so x86_64 can correctly handle the %rip-relative fixups. + */ +- kip->insns = module_alloc(PAGE_SIZE); ++ kip->insns = module_alloc_exec(PAGE_SIZE); + if (!kip->insns) { + kfree(kip); + return NULL; +@@ -225,7 +225,7 @@ static int __kprobes collect_one_slot(st + hlist_add_head(&kip->hlist, + &kprobe_insn_pages); + } else { +- module_free(NULL, kip->insns); ++ module_free_exec(NULL, kip->insns); + kfree(kip); + } + return 1; +@@ -1329,7 +1329,7 @@ static int __kprobes show_kprobe_addr(st + return 0; + } + +-static struct seq_operations kprobes_seq_ops = { ++static const struct seq_operations kprobes_seq_ops = { + .start = kprobe_seq_start, + .next = kprobe_seq_next, + .stop = kprobe_seq_stop, +@@ -1341,7 +1341,7 @@ static int __kprobes kprobes_open(struct + return seq_open(filp, &kprobes_seq_ops); + } + +-static struct file_operations debugfs_kprobes_operations = { ++static const struct file_operations debugfs_kprobes_operations = { + .open = kprobes_open, + .read = seq_read, + .llseek = seq_lseek, +@@ -1523,7 +1523,7 @@ static ssize_t write_enabled_file_bool(s + return count; + } + +-static struct file_operations fops_kp = { ++static const struct file_operations fops_kp = { + .read = read_enabled_file_bool, + .write = write_enabled_file_bool, + }; +diff -urNp linux-2.6.31.1/kernel/lockdep.c linux-2.6.31.1/kernel/lockdep.c +--- linux-2.6.31.1/kernel/lockdep.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/lockdep.c 2009-10-01 20:12:45.000000000 -0400 +@@ -630,6 +630,10 @@ static int static_obj(void *obj) + int i; + #endif + ++#ifdef CONFIG_PAX_KERNEXEC ++ start = (unsigned long )&_sdata; ++#endif ++ + /* + * static variable? + */ +@@ -641,9 +645,12 @@ static int static_obj(void *obj) + * percpu var? + */ + for_each_possible_cpu(i) { ++#ifdef CONFIG_X86_32 ++ start = per_cpu_offset(i); ++#else + start = (unsigned long) &__per_cpu_start + per_cpu_offset(i); +- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM +- + per_cpu_offset(i); ++#endif ++ end = start + PERCPU_ENOUGH_ROOM; + + if ((addr >= start) && (addr < end)) + return 1; +diff -urNp linux-2.6.31.1/kernel/lockdep_proc.c linux-2.6.31.1/kernel/lockdep_proc.c +--- linux-2.6.31.1/kernel/lockdep_proc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/lockdep_proc.c 2009-10-01 20:12:45.000000000 -0400 +@@ -670,7 +670,7 @@ static int ls_show(struct seq_file *m, v + return 0; + } + +-static struct seq_operations lockstat_ops = { ++static const struct seq_operations lockstat_ops = { + .start = ls_start, + .next = ls_next, + .stop = ls_stop, +diff -urNp linux-2.6.31.1/kernel/module.c linux-2.6.31.1/kernel/module.c +--- linux-2.6.31.1/kernel/module.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/module.c 2009-10-01 20:12:45.000000000 -0400 +@@ -47,6 +47,11 @@ + #include <linux/rculist.h> + #include <asm/uaccess.h> + #include <asm/cacheflush.h> ++ ++#ifdef CONFIG_PAX_KERNEXEC ++#include <asm/desc.h> ++#endif ++ + #include <linux/license.h> + #include <asm/sections.h> + #include <linux/tracepoint.h> +@@ -83,7 +88,8 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq + static BLOCKING_NOTIFIER_HEAD(module_notify_list); + + /* Bounds of module allocation, for speeding __module_address */ +-static unsigned long module_addr_min = -1UL, module_addr_max = 0; ++static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0; ++static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0; + + int register_module_notifier(struct notifier_block * nb) + { +@@ -239,7 +245,7 @@ bool each_symbol(bool (*fn)(const struct + return true; + + list_for_each_entry_rcu(mod, &modules, list) { +- struct symsearch arr[] = { ++ struct symsearch modarr[] = { + { mod->syms, mod->syms + mod->num_syms, mod->crcs, + NOT_GPL_ONLY, false }, + { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms, +@@ -261,7 +267,7 @@ bool each_symbol(bool (*fn)(const struct + #endif + }; + +- if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data)) ++ if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data)) + return true; + } + return false; +@@ -436,7 +442,7 @@ static void *percpu_modalloc(unsigned lo + void *ptr; + int cpu; + +- if (align > PAGE_SIZE) { ++ if (align-1 >= PAGE_SIZE) { + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", + name, align, PAGE_SIZE); + align = PAGE_SIZE; +@@ -549,7 +555,11 @@ static void percpu_modcopy(void *pcpudes + int cpu; + + for_each_possible_cpu(cpu) ++#ifdef CONFIG_X86_32 ++ memcpy(pcpudest + __per_cpu_offset[cpu], from, size); ++#else + memcpy(pcpudest + per_cpu_offset(cpu), from, size); ++#endif + } + + #else /* ... !CONFIG_SMP */ +@@ -1513,7 +1523,8 @@ static void free_module(struct module *m + destroy_params(mod->kp, mod->num_kp); + + /* This may be NULL, but that's OK */ +- module_free(mod, mod->module_init); ++ module_free(mod, mod->module_init_rw); ++ module_free_exec(mod, mod->module_init_rx); + kfree(mod->args); + if (mod->percpu) + percpu_modfree(mod->percpu); +@@ -1522,10 +1533,12 @@ static void free_module(struct module *m + percpu_modfree(mod->refptr); + #endif + /* Free lock-classes: */ +- lockdep_free_key_range(mod->module_core, mod->core_size); ++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx); ++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw); + + /* Finally, free the core (containing the module structure) */ +- module_free(mod, mod->module_core); ++ module_free_exec(mod, mod->module_core_rx); ++ module_free(mod, mod->module_core_rw); + } + + void *__symbol_get(const char *symbol) +@@ -1593,6 +1606,10 @@ static int simplify_symbols(Elf_Shdr *se + int ret = 0; + const struct kernel_symbol *ksym; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + for (i = 1; i < n; i++) { + switch (sym[i].st_shndx) { + case SHN_COMMON: +@@ -1615,7 +1632,17 @@ static int simplify_symbols(Elf_Shdr *se + strtab + sym[i].st_name, mod); + /* Ok if resolved. */ + if (ksym) { ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + sym[i].st_value = ksym->value; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + break; + } + +@@ -1634,7 +1661,17 @@ static int simplify_symbols(Elf_Shdr *se + secbase = (unsigned long)mod->percpu; + else + secbase = sechdrs[sym[i].st_shndx].sh_addr; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + sym[i].st_value += secbase; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + break; + } + } +@@ -1695,11 +1732,12 @@ static void layout_sections(struct modul + || s->sh_entsize != ~0UL + || strstarts(secstrings + s->sh_name, ".init")) + continue; +- s->sh_entsize = get_offset(mod, &mod->core_size, s, i); ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC)) ++ s->sh_entsize = get_offset(mod, &mod->core_size_rw, s, i); ++ else ++ s->sh_entsize = get_offset(mod, &mod->core_size_rx, s, i); + DEBUGP("\t%s\n", secstrings + s->sh_name); + } +- if (m == 0) +- mod->core_text_size = mod->core_size; + } + + DEBUGP("Init section allocation order:\n"); +@@ -1712,12 +1750,13 @@ static void layout_sections(struct modul + || s->sh_entsize != ~0UL + || !strstarts(secstrings + s->sh_name, ".init")) + continue; +- s->sh_entsize = (get_offset(mod, &mod->init_size, s, i) +- | INIT_OFFSET_MASK); ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC)) ++ s->sh_entsize = get_offset(mod, &mod->init_size_rw, s, i); ++ else ++ s->sh_entsize = get_offset(mod, &mod->init_size_rx, s, i); ++ s->sh_entsize |= INIT_OFFSET_MASK; + DEBUGP("\t%s\n", secstrings + s->sh_name); + } +- if (m == 0) +- mod->init_text_size = mod->init_size; + } + } + +@@ -1856,14 +1895,31 @@ static void add_kallsyms(struct module * + { + unsigned int i; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + mod->symtab = (void *)sechdrs[symindex].sh_addr; + mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym); + mod->strtab = (void *)sechdrs[strindex].sh_addr; + + /* Set types up while we still have access to sections. */ +- for (i = 0; i < mod->num_symtab; i++) +- mod->symtab[i].st_info +- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); ++ ++ for (i = 0; i < mod->num_symtab; i++) { ++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ mod->symtab[i].st_info = type; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ ++ } ++ + } + #else + static inline void add_kallsyms(struct module *mod, +@@ -1884,16 +1940,30 @@ static void dynamic_debug_setup(struct _ + #endif + } + +-static void *module_alloc_update_bounds(unsigned long size) ++static void *module_alloc_update_bounds_rw(unsigned long size) + { + void *ret = module_alloc(size); + + if (ret) { + /* Update module bounds. */ +- if ((unsigned long)ret < module_addr_min) +- module_addr_min = (unsigned long)ret; +- if ((unsigned long)ret + size > module_addr_max) +- module_addr_max = (unsigned long)ret + size; ++ if ((unsigned long)ret < module_addr_min_rw) ++ module_addr_min_rw = (unsigned long)ret; ++ if ((unsigned long)ret + size > module_addr_max_rw) ++ module_addr_max_rw = (unsigned long)ret + size; ++ } ++ return ret; ++} ++ ++static void *module_alloc_update_bounds_rx(unsigned long size) ++{ ++ void *ret = module_alloc_exec(size); ++ ++ if (ret) { ++ /* Update module bounds. */ ++ if ((unsigned long)ret < module_addr_min_rx) ++ module_addr_min_rx = (unsigned long)ret; ++ if ((unsigned long)ret + size > module_addr_max_rx) ++ module_addr_max_rx = (unsigned long)ret + size; + } + return ret; + } +@@ -1905,8 +1975,8 @@ static void kmemleak_load_module(struct + unsigned int i; + + /* only scan the sections containing data */ +- kmemleak_scan_area(mod->module_core, (unsigned long)mod - +- (unsigned long)mod->module_core, ++ kmemleak_scan_area(mod->module_core_rw, (unsigned long)mod - ++ (unsigned long)mod->module_core_rw, + sizeof(struct module), GFP_KERNEL); + + for (i = 1; i < hdr->e_shnum; i++) { +@@ -1916,8 +1986,8 @@ static void kmemleak_load_module(struct + && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0) + continue; + +- kmemleak_scan_area(mod->module_core, sechdrs[i].sh_addr - +- (unsigned long)mod->module_core, ++ kmemleak_scan_area(mod->module_core_rw, sechdrs[i].sh_addr - ++ (unsigned long)mod->module_core_rw, + sechdrs[i].sh_size, GFP_KERNEL); + } + } +@@ -1947,6 +2017,10 @@ static noinline struct module *load_modu + void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ + mm_segment_t old_fs; + ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif ++ + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", + umod, len, uargs); + if (len < sizeof(*hdr)) +@@ -2097,7 +2171,7 @@ static noinline struct module *load_modu + layout_sections(mod, hdr, sechdrs, secstrings); + + /* Do the allocs. */ +- ptr = module_alloc_update_bounds(mod->core_size); ++ ptr = module_alloc_update_bounds_rw(mod->core_size_rw); + /* + * The pointer to this block is stored in the module structure + * which is inside the block. Just mark it as not being a +@@ -2108,23 +2182,61 @@ static noinline struct module *load_modu + err = -ENOMEM; + goto free_percpu; + } +- memset(ptr, 0, mod->core_size); +- mod->module_core = ptr; ++ memset(ptr, 0, mod->core_size_rw); ++ mod->module_core_rw = ptr; + +- ptr = module_alloc_update_bounds(mod->init_size); ++ ptr = module_alloc_update_bounds_rw(mod->init_size_rw); + /* + * The pointer to this block is stored in the module structure + * which is inside the block. This block doesn't need to be + * scanned as it contains data and code that will be freed + * after the module is initialized. + */ +- kmemleak_ignore(ptr); +- if (!ptr && mod->init_size) { ++ kmemleak_not_leak(ptr); ++ if (!ptr && mod->init_size_rw) { + err = -ENOMEM; +- goto free_core; ++ goto free_core_rw; + } +- memset(ptr, 0, mod->init_size); +- mod->module_init = ptr; ++ memset(ptr, 0, mod->init_size_rw); ++ mod->module_init_rw = ptr; ++ ++ ptr = module_alloc_update_bounds_rx(mod->core_size_rx); ++ kmemleak_not_leak(ptr); ++ if (!ptr) { ++ err = -ENOMEM; ++ goto free_init_rw; ++ } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ memset(ptr, 0, mod->core_size_rx); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ ++ mod->module_core_rx = ptr; ++ ++ ptr = module_alloc_update_bounds_rx(mod->init_size_rx); ++ kmemleak_not_leak(ptr); ++ if (!ptr && mod->init_size_rx) { ++ err = -ENOMEM; ++ goto free_core_rx; ++ } ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ ++ memset(ptr, 0, mod->init_size_rx); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ ++ mod->module_init_rx = ptr; + + /* Transfer each section which specifies SHF_ALLOC */ + DEBUGP("final section addresses:\n"); +@@ -2134,17 +2246,41 @@ static noinline struct module *load_modu + if (!(sechdrs[i].sh_flags & SHF_ALLOC)) + continue; + +- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) +- dest = mod->module_init +- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); +- else +- dest = mod->module_core + sechdrs[i].sh_entsize; ++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) { ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC)) ++ dest = mod->module_init_rw ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); ++ else ++ dest = mod->module_init_rx ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); ++ } else { ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC)) ++ dest = mod->module_core_rw + sechdrs[i].sh_entsize; ++ else ++ dest = mod->module_core_rx + sechdrs[i].sh_entsize; ++ } ++ ++ if (sechdrs[i].sh_type != SHT_NOBITS) { + +- if (sechdrs[i].sh_type != SHT_NOBITS) +- memcpy(dest, (void *)sechdrs[i].sh_addr, +- sechdrs[i].sh_size); ++#ifdef CONFIG_PAX_KERNEXEC ++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) { ++ pax_open_kernel(cr0); ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size); ++ pax_close_kernel(cr0); ++ } else ++#endif ++ ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size); ++ } + /* Update sh_addr to point to copy in image. */ +- sechdrs[i].sh_addr = (unsigned long)dest; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ if (sechdrs[i].sh_flags & SHF_EXECINSTR) ++ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest); ++ else ++#endif ++ ++ sechdrs[i].sh_addr = (unsigned long)dest; + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); + } + /* Module has been moved. */ +@@ -2156,7 +2292,7 @@ static noinline struct module *load_modu + mod->name); + if (!mod->refptr) { + err = -ENOMEM; +- goto free_init; ++ goto free_init_rx; + } + #endif + /* Now we've moved module, initialize linked lists, etc. */ +@@ -2269,8 +2405,8 @@ static noinline struct module *load_modu + + /* Now do relocations. */ + for (i = 1; i < hdr->e_shnum; i++) { +- const char *strtab = (char *)sechdrs[strindex].sh_addr; + unsigned int info = sechdrs[i].sh_info; ++ strtab = (char *)sechdrs[strindex].sh_addr; + + /* Not a valid relocation section? */ + if (info >= hdr->e_shnum) +@@ -2328,12 +2464,12 @@ static noinline struct module *load_modu + * Do it before processing of module parameters, so the module + * can provide parameter accessor functions of its own. + */ +- if (mod->module_init) +- flush_icache_range((unsigned long)mod->module_init, +- (unsigned long)mod->module_init +- + mod->init_size); +- flush_icache_range((unsigned long)mod->module_core, +- (unsigned long)mod->module_core + mod->core_size); ++ if (mod->module_init_rx) ++ flush_icache_range((unsigned long)mod->module_init_rx, ++ (unsigned long)mod->module_init_rx ++ + mod->init_size_rx); ++ flush_icache_range((unsigned long)mod->module_core_rx, ++ (unsigned long)mod->module_core_rx + mod->core_size_rx); + + set_fs(old_fs); + +@@ -2378,12 +2514,16 @@ static noinline struct module *load_modu + free_unload: + module_unload_free(mod); + #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) +- free_init: ++ free_init_rx: + percpu_modfree(mod->refptr); + #endif +- module_free(mod, mod->module_init); +- free_core: +- module_free(mod, mod->module_core); ++ module_free_exec(mod, mod->module_init_rx); ++ free_core_rx: ++ module_free_exec(mod, mod->module_core_rx); ++ free_init_rw: ++ module_free(mod, mod->module_init_rw); ++ free_core_rw: ++ module_free(mod, mod->module_core_rw); + /* mod will be freed with core. Don't access it beyond this line! */ + free_percpu: + if (percpu) +@@ -2479,10 +2619,12 @@ SYSCALL_DEFINE3(init_module, void __user + /* Drop initial reference. */ + module_put(mod); + trim_init_extable(mod); +- module_free(mod, mod->module_init); +- mod->module_init = NULL; +- mod->init_size = 0; +- mod->init_text_size = 0; ++ module_free(mod, mod->module_init_rw); ++ module_free_exec(mod, mod->module_init_rx); ++ mod->module_init_rw = NULL; ++ mod->module_init_rx = NULL; ++ mod->init_size_rw = 0; ++ mod->init_size_rx = 0; + mutex_unlock(&module_mutex); + + return 0; +@@ -2513,10 +2655,16 @@ static const char *get_ksymbol(struct mo + unsigned long nextval; + + /* At worse, next value is at end of module */ +- if (within_module_init(addr, mod)) +- nextval = (unsigned long)mod->module_init+mod->init_text_size; ++ if (within_module_init_rx(addr, mod)) ++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx; ++ else if (within_module_init_rw(addr, mod)) ++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw; ++ else if (within_module_core_rx(addr, mod)) ++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx; ++ else if (within_module_core_rw(addr, mod)) ++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw; + else +- nextval = (unsigned long)mod->module_core+mod->core_text_size; ++ return NULL; + + /* Scan for closest preceeding symbol, and next symbol. (ELF + starts real symbols at 1). */ +@@ -2762,7 +2910,7 @@ static int m_show(struct seq_file *m, vo + char buf[8]; + + seq_printf(m, "%s %u", +- mod->name, mod->init_size + mod->core_size); ++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw); + print_unload_info(m, mod); + + /* Informative for users. */ +@@ -2771,7 +2919,7 @@ static int m_show(struct seq_file *m, vo + mod->state == MODULE_STATE_COMING ? "Loading": + "Live"); + /* Used by oprofile and other similar tools. */ +- seq_printf(m, " 0x%p", mod->module_core); ++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw); + + /* Taints info */ + if (mod->taints) +@@ -2807,7 +2955,17 @@ static const struct file_operations proc + + static int __init proc_modules_init(void) + { ++#ifndef CONFIG_GRKERNSEC_HIDESYM ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ proc_create("modules", S_IRUSR, NULL, &proc_modules_operations); ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ proc_create("modules", S_IRUSR | S_IRGRP, NULL, &proc_modules_operations); ++#else + proc_create("modules", 0, NULL, &proc_modules_operations); ++#endif ++#else ++ proc_create("modules", S_IRUSR, NULL, &proc_modules_operations); ++#endif + return 0; + } + module_init(proc_modules_init); +@@ -2866,12 +3024,12 @@ struct module *__module_address(unsigned + { + struct module *mod; + +- if (addr < module_addr_min || addr > module_addr_max) ++ if ((addr < module_addr_min_rx || addr > module_addr_max_rx) && ++ (addr < module_addr_min_rw || addr > module_addr_max_rw)) + return NULL; + + list_for_each_entry_rcu(mod, &modules, list) +- if (within_module_core(addr, mod) +- || within_module_init(addr, mod)) ++ if (within_module_init(addr, mod) || within_module_core(addr, mod)) + return mod; + return NULL; + } +@@ -2905,11 +3063,20 @@ bool is_module_text_address(unsigned lon + */ + struct module *__module_text_address(unsigned long addr) + { +- struct module *mod = __module_address(addr); ++ struct module *mod; ++ ++#ifdef CONFIG_X86_32 ++ addr = ktla_ktva(addr); ++#endif ++ ++ if (addr < module_addr_min_rx || addr > module_addr_max_rx) ++ return NULL; ++ ++ mod = __module_address(addr); ++ + if (mod) { + /* Make sure it's within the text section. */ +- if (!within(addr, mod->module_init, mod->init_text_size) +- && !within(addr, mod->module_core, mod->core_text_size)) ++ if (!within_module_init_rx(addr, mod) && !within_module_core_rx(addr, mod)) + mod = NULL; + } + return mod; +diff -urNp linux-2.6.31.1/kernel/panic.c linux-2.6.31.1/kernel/panic.c +--- linux-2.6.31.1/kernel/panic.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/panic.c 2009-10-01 20:12:45.000000000 -0400 +@@ -391,7 +391,8 @@ EXPORT_SYMBOL(warn_slowpath_null); + */ + void __stack_chk_fail(void) + { +- panic("stack-protector: Kernel stack is corrupted in: %p\n", ++ dump_stack(); ++ panic("stack-protector: Kernel stack is corrupted in: %pS\n", + __builtin_return_address(0)); + } + EXPORT_SYMBOL(__stack_chk_fail); +diff -urNp linux-2.6.31.1/kernel/params.c linux-2.6.31.1/kernel/params.c +--- linux-2.6.31.1/kernel/params.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/params.c 2009-10-01 20:12:45.000000000 -0400 +@@ -217,13 +217,9 @@ int param_set_charp(const char *val, str + return -ENOSPC; + } + +- if (kp->flags & KPARAM_KMALLOCED) +- kfree(*(char **)kp->arg); +- + /* This is a hack. We can't need to strdup in early boot, and we + * don't need to; this mangled commandline is preserved. */ + if (slab_is_available()) { +- kp->flags |= KPARAM_KMALLOCED; + *(char **)kp->arg = kstrdup(val, GFP_KERNEL); + if (!kp->arg) + return -ENOMEM; +@@ -607,7 +603,7 @@ void destroy_params(const struct kernel_ + unsigned int i; + + for (i = 0; i < num; i++) +- if (params[i].flags & KPARAM_KMALLOCED) ++ if (params[i].set == param_set_charp) + kfree(*(char **)params[i].arg); + } + +diff -urNp linux-2.6.31.1/kernel/perf_counter.c linux-2.6.31.1/kernel/perf_counter.c +--- linux-2.6.31.1/kernel/perf_counter.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/perf_counter.c 2009-10-01 20:12:45.000000000 -0400 +@@ -2231,7 +2231,7 @@ static void perf_mmap_close(struct vm_ar + } + } + +-static struct vm_operations_struct perf_mmap_vmops = { ++static const struct vm_operations_struct perf_mmap_vmops = { + .open = perf_mmap_open, + .close = perf_mmap_close, + .fault = perf_mmap_fault, +@@ -4181,7 +4181,7 @@ static int perf_copy_attr(struct perf_co + end = PTR_ALIGN((void __user *)uattr + size, + sizeof(unsigned long)); + +- for (; addr < end; addr += sizeof(unsigned long)) { ++ for (; addr < end; addr++) { + ret = get_user(val, addr); + if (ret) + return ret; +diff -urNp linux-2.6.31.1/kernel/pid.c linux-2.6.31.1/kernel/pid.c +--- linux-2.6.31.1/kernel/pid.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/pid.c 2009-10-01 20:12:45.000000000 -0400 +@@ -33,6 +33,7 @@ + #include <linux/rculist.h> + #include <linux/bootmem.h> + #include <linux/hash.h> ++#include <linux/security.h> + #include <linux/pid_namespace.h> + #include <linux/init_task.h> + #include <linux/syscalls.h> +@@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT + + int pid_max = PID_MAX_DEFAULT; + +-#define RESERVED_PIDS 300 ++#define RESERVED_PIDS 500 + + int pid_max_min = RESERVED_PIDS + 1; + int pid_max_max = PID_MAX_LIMIT; +@@ -380,7 +381,14 @@ EXPORT_SYMBOL(pid_task); + */ + struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) + { +- return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID); ++ struct task_struct *task; ++ ++ task = pid_task(find_pid_ns(nr, ns), PIDTYPE_PID); ++ ++ if (gr_pid_is_chrooted(task)) ++ return NULL; ++ ++ return task; + } + + struct task_struct *find_task_by_vpid(pid_t vnr) +diff -urNp linux-2.6.31.1/kernel/posix-cpu-timers.c linux-2.6.31.1/kernel/posix-cpu-timers.c +--- linux-2.6.31.1/kernel/posix-cpu-timers.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/posix-cpu-timers.c 2009-10-01 20:12:45.000000000 -0400 +@@ -6,6 +6,7 @@ + #include <linux/posix-timers.h> + #include <linux/errno.h> + #include <linux/math64.h> ++#include <linux/security.h> + #include <asm/uaccess.h> + #include <linux/kernel_stat.h> + +@@ -1041,6 +1042,7 @@ static void check_thread_timers(struct t + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); + return; + } ++ gr_learn_resource(tsk, RLIMIT_RTTIME, tsk->rt.timeout, 1); + if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) { + /* + * At the soft limit, send a SIGXCPU every second. +@@ -1196,6 +1198,7 @@ static void check_process_timers(struct + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); + return; + } ++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 0); + if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) { + /* + * At the soft limit, send a SIGXCPU every second. +diff -urNp linux-2.6.31.1/kernel/power/poweroff.c linux-2.6.31.1/kernel/power/poweroff.c +--- linux-2.6.31.1/kernel/power/poweroff.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/power/poweroff.c 2009-10-01 20:12:45.000000000 -0400 +@@ -37,7 +37,7 @@ static struct sysrq_key_op sysrq_powerof + .enable_mask = SYSRQ_ENABLE_BOOT, + }; + +-static int pm_sysrq_init(void) ++static int __init pm_sysrq_init(void) + { + register_sysrq_key('o', &sysrq_poweroff_op); + return 0; +diff -urNp linux-2.6.31.1/kernel/power/process.c linux-2.6.31.1/kernel/power/process.c +--- linux-2.6.31.1/kernel/power/process.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/power/process.c 2009-10-01 20:12:45.000000000 -0400 +@@ -36,12 +36,15 @@ static int try_to_freeze_tasks(bool sig_ + struct timeval start, end; + u64 elapsed_csecs64; + unsigned int elapsed_csecs; ++ bool timedout = false; + + do_gettimeofday(&start); + + end_time = jiffies + TIMEOUT; + do { + todo = 0; ++ if (time_after(jiffies, end_time)) ++ timedout = true; + read_lock(&tasklist_lock); + do_each_thread(g, p) { + if (frozen(p) || !freezeable(p)) +@@ -56,15 +59,17 @@ static int try_to_freeze_tasks(bool sig_ + * It is "frozen enough". If the task does wake + * up, it will immediately call try_to_freeze. + */ +- if (!task_is_stopped_or_traced(p) && +- !freezer_should_skip(p)) ++ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) { + todo++; ++ if (timedout) { ++ printk(KERN_ERR "Task refusing to freeze:\n"); ++ sched_show_task(p); ++ } ++ } + } while_each_thread(g, p); + read_unlock(&tasklist_lock); + yield(); /* Yield is okay here */ +- if (time_after(jiffies, end_time)) +- break; +- } while (todo); ++ } while (todo && !timedout); + + do_gettimeofday(&end); + elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); +diff -urNp linux-2.6.31.1/kernel/printk.c linux-2.6.31.1/kernel/printk.c +--- linux-2.6.31.1/kernel/printk.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/printk.c 2009-10-01 20:12:45.000000000 -0400 +@@ -272,6 +272,11 @@ int do_syslog(int type, char __user *buf + char c; + int error = 0; + ++#ifdef CONFIG_GRKERNSEC_DMESG ++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN)) ++ return -EPERM; ++#endif ++ + error = security_syslog(type); + if (error) + return error; +diff -urNp linux-2.6.31.1/kernel/ptrace.c linux-2.6.31.1/kernel/ptrace.c +--- linux-2.6.31.1/kernel/ptrace.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/ptrace.c 2009-10-01 20:12:45.000000000 -0400 +@@ -141,7 +141,7 @@ int __ptrace_may_access(struct task_stru + cred->gid != tcred->egid || + cred->gid != tcred->sgid || + cred->gid != tcred->gid) && +- !capable(CAP_SYS_PTRACE)) { ++ !capable_nolog(CAP_SYS_PTRACE)) { + rcu_read_unlock(); + return -EPERM; + } +@@ -149,7 +149,7 @@ int __ptrace_may_access(struct task_stru + smp_rmb(); + if (task->mm) + dumpable = get_dumpable(task->mm); +- if (!dumpable && !capable(CAP_SYS_PTRACE)) ++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE)) + return -EPERM; + + return security_ptrace_may_access(task, mode); +@@ -199,7 +199,7 @@ int ptrace_attach(struct task_struct *ta + goto unlock_tasklist; + + task->ptrace = PT_PTRACED; +- if (capable(CAP_SYS_PTRACE)) ++ if (capable_nolog(CAP_SYS_PTRACE)) + task->ptrace |= PT_PTRACE_CAP; + + __ptrace_link(task, current); +@@ -633,6 +633,11 @@ SYSCALL_DEFINE4(ptrace, long, request, l + if (ret < 0) + goto out_put_task_struct; + ++ if (gr_handle_ptrace(child, request)) { ++ ret = -EPERM; ++ goto out_put_task_struct; ++ } ++ + ret = arch_ptrace(child, request, addr, data); + + out_put_task_struct: +diff -urNp linux-2.6.31.1/kernel/rcupreempt_trace.c linux-2.6.31.1/kernel/rcupreempt_trace.c +--- linux-2.6.31.1/kernel/rcupreempt_trace.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/rcupreempt_trace.c 2009-10-01 20:12:45.000000000 -0400 +@@ -261,17 +261,17 @@ static ssize_t rcuctrs_read(struct file + return bcount; + } + +-static struct file_operations rcustats_fops = { ++static const struct file_operations rcustats_fops = { + .owner = THIS_MODULE, + .read = rcustats_read, + }; + +-static struct file_operations rcugp_fops = { ++static const struct file_operations rcugp_fops = { + .owner = THIS_MODULE, + .read = rcugp_read, + }; + +-static struct file_operations rcuctrs_fops = { ++static const struct file_operations rcuctrs_fops = { + .owner = THIS_MODULE, + .read = rcuctrs_read, + }; +diff -urNp linux-2.6.31.1/kernel/rcutree_trace.c linux-2.6.31.1/kernel/rcutree_trace.c +--- linux-2.6.31.1/kernel/rcutree_trace.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/rcutree_trace.c 2009-10-01 20:12:45.000000000 -0400 +@@ -88,7 +88,7 @@ static int rcudata_open(struct inode *in + return single_open(file, show_rcudata, NULL); + } + +-static struct file_operations rcudata_fops = { ++static const struct file_operations rcudata_fops = { + .owner = THIS_MODULE, + .open = rcudata_open, + .read = seq_read, +@@ -136,7 +136,7 @@ static int rcudata_csv_open(struct inode + return single_open(file, show_rcudata_csv, NULL); + } + +-static struct file_operations rcudata_csv_fops = { ++static const struct file_operations rcudata_csv_fops = { + .owner = THIS_MODULE, + .open = rcudata_csv_open, + .read = seq_read, +@@ -183,7 +183,7 @@ static int rcuhier_open(struct inode *in + return single_open(file, show_rcuhier, NULL); + } + +-static struct file_operations rcuhier_fops = { ++static const struct file_operations rcuhier_fops = { + .owner = THIS_MODULE, + .open = rcuhier_open, + .read = seq_read, +@@ -205,7 +205,7 @@ static int rcugp_open(struct inode *inod + return single_open(file, show_rcugp, NULL); + } + +-static struct file_operations rcugp_fops = { ++static const struct file_operations rcugp_fops = { + .owner = THIS_MODULE, + .open = rcugp_open, + .read = seq_read, +@@ -255,7 +255,7 @@ static int rcu_pending_open(struct inode + return single_open(file, show_rcu_pending, NULL); + } + +-static struct file_operations rcu_pending_fops = { ++static const struct file_operations rcu_pending_fops = { + .owner = THIS_MODULE, + .open = rcu_pending_open, + .read = seq_read, +diff -urNp linux-2.6.31.1/kernel/relay.c linux-2.6.31.1/kernel/relay.c +--- linux-2.6.31.1/kernel/relay.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/relay.c 2009-10-01 20:12:45.000000000 -0400 +@@ -60,7 +60,7 @@ static int relay_buf_fault(struct vm_are + /* + * vm_ops for relay file mappings. + */ +-static struct vm_operations_struct relay_file_mmap_ops = { ++static const struct vm_operations_struct relay_file_mmap_ops = { + .fault = relay_buf_fault, + .close = relay_file_mmap_close, + }; +@@ -1292,7 +1292,7 @@ static int subbuf_splice_actor(struct fi + return 0; + + ret = *nonpad_ret = splice_to_pipe(pipe, &spd); +- if (ret < 0 || ret < total_len) ++ if ((int)ret < 0 || ret < total_len) + return ret; + + if (read_start + ret == nonpad_end) +diff -urNp linux-2.6.31.1/kernel/resource.c linux-2.6.31.1/kernel/resource.c +--- linux-2.6.31.1/kernel/resource.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/resource.c 2009-10-01 20:12:45.000000000 -0400 +@@ -132,8 +132,18 @@ static const struct file_operations proc + + static int __init ioresources_init(void) + { ++#ifdef CONFIG_GRKERNSEC_PROC_ADD ++#ifdef CONFIG_GRKERNSEC_PROC_USER ++ proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations); ++ proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations); ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++ proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations); ++ proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations); ++#endif ++#else + proc_create("ioports", 0, NULL, &proc_ioports_operations); + proc_create("iomem", 0, NULL, &proc_iomem_operations); ++#endif + return 0; + } + __initcall(ioresources_init); +diff -urNp linux-2.6.31.1/kernel/sched.c linux-2.6.31.1/kernel/sched.c +--- linux-2.6.31.1/kernel/sched.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/sched.c 2009-10-01 20:12:45.000000000 -0400 +@@ -820,7 +820,7 @@ static int sched_feat_open(struct inode + return single_open(filp, sched_feat_show, NULL); + } + +-static struct file_operations sched_feat_fops = { ++static const struct file_operations sched_feat_fops = { + .open = sched_feat_open, + .write = sched_feat_write, + .read = seq_read, +@@ -5978,6 +5978,8 @@ int can_nice(const struct task_struct *p + /* convert nice value [19,-20] to rlimit style value [1,40] */ + int nice_rlim = 20 - nice; + ++ gr_learn_resource(p, RLIMIT_NICE, nice_rlim, 1); ++ + return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur || + capable(CAP_SYS_NICE)); + } +@@ -6011,7 +6013,8 @@ SYSCALL_DEFINE1(nice, int, increment) + if (nice > 19) + nice = 19; + +- if (increment < 0 && !can_nice(current, nice)) ++ if (increment < 0 && (!can_nice(current, nice) || ++ gr_handle_chroot_nice())) + return -EPERM; + + retval = security_task_setnice(current, nice); +@@ -6153,6 +6156,8 @@ recheck: + if (rt_policy(policy)) { + unsigned long rlim_rtprio; + ++ gr_learn_resource(p, RLIMIT_RTPRIO, param->sched_priority, 1); ++ + if (!lock_task_sighand(p, &flags)) + return -ESRCH; + rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur; +@@ -7300,7 +7305,7 @@ static struct ctl_table sd_ctl_dir[] = { + .procname = "sched_domain", + .mode = 0555, + }, +- {0, }, ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + + static struct ctl_table sd_ctl_root[] = { +@@ -7310,7 +7315,7 @@ static struct ctl_table sd_ctl_root[] = + .mode = 0555, + .child = sd_ctl_dir, + }, +- {0, }, ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + + static struct ctl_table *sd_alloc_ctl_entry(int n) +diff -urNp linux-2.6.31.1/kernel/signal.c linux-2.6.31.1/kernel/signal.c +--- linux-2.6.31.1/kernel/signal.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/signal.c 2009-10-01 20:12:45.000000000 -0400 +@@ -207,6 +207,9 @@ static struct sigqueue *__sigqueue_alloc + */ + user = get_uid(__task_cred(t)->user); + atomic_inc(&user->sigpending); ++ ++ if (!override_rlimit) ++ gr_learn_resource(t, RLIMIT_SIGPENDING, atomic_read(&user->sigpending), 1); + if (override_rlimit || + atomic_read(&user->sigpending) <= + t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) +@@ -625,6 +628,9 @@ static int check_kill_permission(int sig + } + } + ++ if (gr_handle_signal(t, sig)) ++ return -EPERM; ++ + return security_task_kill(t, info, sig, 0); + } + +@@ -939,8 +945,8 @@ static void print_fatal_signal(struct pt + for (i = 0; i < 16; i++) { + unsigned char insn; + +- __get_user(insn, (unsigned char *)(regs->ip + i)); +- printk("%02x ", insn); ++ if (!get_user(insn, (unsigned char __user *)(regs->ip + i))) ++ printk("%02x ", insn); + } + } + #endif +@@ -965,7 +971,7 @@ __group_send_sig_info(int sig, struct si + return send_signal(sig, info, p, 1); + } + +-static int ++int + specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) + { + return send_signal(sig, info, t, 0); +@@ -1005,6 +1011,9 @@ force_sig_info(int sig, struct siginfo * + ret = specific_send_sig_info(sig, info, t); + spin_unlock_irqrestore(&t->sighand->siglock, flags); + ++ gr_log_signal(sig, !is_si_special(info) ? info->si_addr : NULL, t); ++ gr_handle_crash(t, sig); ++ + return ret; + } + +@@ -1079,6 +1088,8 @@ int group_send_sig_info(int sig, struct + ret = __group_send_sig_info(sig, info, p); + unlock_task_sighand(p, &flags); + } ++ if (!ret) ++ gr_log_signal(sig, !is_si_special(info) ? info->si_addr : NULL, p); + } + + return ret; +diff -urNp linux-2.6.31.1/kernel/sys.c linux-2.6.31.1/kernel/sys.c +--- linux-2.6.31.1/kernel/sys.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/sys.c 2009-10-01 20:12:45.000000000 -0400 +@@ -133,6 +133,12 @@ static int set_one_prio(struct task_stru + error = -EACCES; + goto out; + } ++ ++ if (gr_handle_chroot_setpriority(p, niceval)) { ++ error = -EACCES; ++ goto out; ++ } ++ + no_nice = security_task_setnice(p, niceval); + if (no_nice) { + error = no_nice; +@@ -509,6 +515,9 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, g + goto error; + } + ++ if (gr_check_group_change(new->gid, new->egid, -1)) ++ goto error; ++ + if (rgid != (gid_t) -1 || + (egid != (gid_t) -1 && egid != old->gid)) + new->sgid = new->egid; +@@ -542,6 +551,10 @@ SYSCALL_DEFINE1(setgid, gid_t, gid) + goto error; + + retval = -EPERM; ++ ++ if (gr_check_group_change(gid, gid, gid)) ++ goto error; ++ + if (capable(CAP_SETGID)) + new->gid = new->egid = new->sgid = new->fsgid = gid; + else if (gid == old->gid || gid == old->sgid) +@@ -632,6 +645,9 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, u + goto error; + } + ++ if (gr_check_user_change(new->uid, new->euid, -1)) ++ goto error; ++ + if (new->uid != old->uid) { + retval = set_user(new); + if (retval < 0) +@@ -680,6 +696,12 @@ SYSCALL_DEFINE1(setuid, uid_t, uid) + goto error; + + retval = -EPERM; ++ ++ if (gr_check_crash_uid(uid)) ++ goto error; ++ if (gr_check_user_change(uid, uid, uid)) ++ goto error; ++ + if (capable(CAP_SETUID)) { + new->suid = new->uid = uid; + if (uid != old->uid) { +@@ -737,6 +759,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, + goto error; + } + ++ if (gr_check_user_change(ruid, euid, -1)) ++ goto error; ++ + if (ruid != (uid_t) -1) { + new->uid = ruid; + if (ruid != old->uid) { +@@ -805,6 +830,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, + goto error; + } + ++ if (gr_check_group_change(rgid, egid, -1)) ++ goto error; ++ + if (rgid != (gid_t) -1) + new->gid = rgid; + if (egid != (gid_t) -1) +@@ -854,6 +882,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid) + if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS) < 0) + goto error; + ++ if (gr_check_user_change(-1, -1, uid)) ++ goto error; ++ + if (uid == old->uid || uid == old->euid || + uid == old->suid || uid == old->fsuid || + capable(CAP_SETUID)) { +@@ -894,6 +925,9 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid) + if (gid == old->gid || gid == old->egid || + gid == old->sgid || gid == old->fsgid || + capable(CAP_SETGID)) { ++ if (gr_check_group_change(-1, -1, gid)) ++ goto error; ++ + if (gid != old_fsgid) { + new->fsgid = gid; + goto change_okay; +@@ -1443,7 +1477,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsi + error = get_dumpable(me->mm); + break; + case PR_SET_DUMPABLE: +- if (arg2 < 0 || arg2 > 1) { ++ if (arg2 > 1) { + error = -EINVAL; + break; + } +diff -urNp linux-2.6.31.1/kernel/sysctl.c linux-2.6.31.1/kernel/sysctl.c +--- linux-2.6.31.1/kernel/sysctl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/sysctl.c 2009-10-01 20:12:45.000000000 -0400 +@@ -65,6 +65,13 @@ + static int deprecated_sysctl_warning(struct __sysctl_args *args); + + #if defined(CONFIG_SYSCTL) ++#include <linux/grsecurity.h> ++#include <linux/grinternal.h> ++ ++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op); ++extern int gr_handle_sysctl_mod(const char *dirname, const char *name, ++ const int op); ++extern int gr_handle_chroot_sysctl(const int op); + + /* External variables not in a header file. */ + extern int C_A_D; +@@ -163,6 +170,7 @@ static int proc_do_cad_pid(struct ctl_ta + static int proc_taint(struct ctl_table *table, int write, struct file *filp, + void __user *buffer, size_t *lenp, loff_t *ppos); + #endif ++extern ctl_table grsecurity_table[]; + + static struct ctl_table root_table[]; + static struct ctl_table_root sysctl_table_root; +@@ -195,6 +203,21 @@ extern struct ctl_table epoll_table[]; + int sysctl_legacy_va_layout; + #endif + ++#ifdef CONFIG_PAX_SOFTMODE ++static ctl_table pax_table[] = { ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "softmode", ++ .data = &pax_softmode, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++ ++ { .ctl_name = 0 } ++}; ++#endif ++ + extern int prove_locking; + extern int lock_stat; + +@@ -246,6 +269,24 @@ static int max_wakeup_granularity_ns = N + #endif + + static struct ctl_table kern_table[] = { ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP) ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "grsecurity", ++ .mode = 0500, ++ .child = grsecurity_table, ++ }, ++#endif ++ ++#ifdef CONFIG_PAX_SOFTMODE ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "pax", ++ .mode = 0500, ++ .child = pax_table, ++ }, ++#endif ++ + #ifdef CONFIG_SCHED_DEBUG + { + .ctl_name = CTL_UNNUMBERED, +@@ -1734,6 +1775,8 @@ static int do_sysctl_strategy(struct ctl + return 0; + } + ++static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op); ++ + static int parse_table(int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, +@@ -1752,7 +1795,7 @@ repeat: + if (n == table->ctl_name) { + int error; + if (table->child) { +- if (sysctl_perm(root, table, MAY_EXEC)) ++ if (sysctl_perm_nochk(root, table, MAY_EXEC)) + return -EPERM; + name++; + nlen--; +@@ -1837,6 +1880,33 @@ int sysctl_perm(struct ctl_table_root *r + int error; + int mode; + ++ if (table->parent != NULL && table->parent->procname != NULL && ++ table->procname != NULL && ++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op)) ++ return -EACCES; ++ if (gr_handle_chroot_sysctl(op)) ++ return -EACCES; ++ error = gr_handle_sysctl(table, op); ++ if (error) ++ return error; ++ ++ error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC)); ++ if (error) ++ return error; ++ ++ if (root->permissions) ++ mode = root->permissions(root, current->nsproxy, table); ++ else ++ mode = table->mode; ++ ++ return test_perm(mode, op); ++} ++ ++int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op) ++{ ++ int error; ++ int mode; ++ + error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC)); + if (error) + return error; +diff -urNp linux-2.6.31.1/kernel/taskstats.c linux-2.6.31.1/kernel/taskstats.c +--- linux-2.6.31.1/kernel/taskstats.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/taskstats.c 2009-10-01 20:12:45.000000000 -0400 +@@ -26,9 +26,12 @@ + #include <linux/cgroup.h> + #include <linux/fs.h> + #include <linux/file.h> ++#include <linux/grsecurity.h> + #include <net/genetlink.h> + #include <asm/atomic.h> + ++extern int gr_is_taskstats_denied(int pid); ++ + /* + * Maximum length of a cpumask that can be specified in + * the TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK attribute +@@ -433,6 +436,9 @@ static int taskstats_user_cmd(struct sk_ + size_t size; + cpumask_var_t mask; + ++ if (gr_is_taskstats_denied(current->pid)) ++ return -EACCES; ++ + if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + return -ENOMEM; + +diff -urNp linux-2.6.31.1/kernel/time/tick-broadcast.c linux-2.6.31.1/kernel/time/tick-broadcast.c +--- linux-2.6.31.1/kernel/time/tick-broadcast.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/time/tick-broadcast.c 2009-10-01 20:12:45.000000000 -0400 +@@ -116,7 +116,7 @@ int tick_device_uses_broadcast(struct cl + * then clear the broadcast bit. + */ + if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) { +- int cpu = smp_processor_id(); ++ cpu = smp_processor_id(); + + cpumask_clear_cpu(cpu, tick_get_broadcast_mask()); + tick_broadcast_clear_oneshot(cpu); +diff -urNp linux-2.6.31.1/kernel/time/timer_list.c linux-2.6.31.1/kernel/time/timer_list.c +--- linux-2.6.31.1/kernel/time/timer_list.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/time/timer_list.c 2009-10-01 20:12:45.000000000 -0400 +@@ -275,7 +275,7 @@ static int timer_list_open(struct inode + return single_open(filp, timer_list_show, NULL); + } + +-static struct file_operations timer_list_fops = { ++static const struct file_operations timer_list_fops = { + .open = timer_list_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/kernel/time/timer_stats.c linux-2.6.31.1/kernel/time/timer_stats.c +--- linux-2.6.31.1/kernel/time/timer_stats.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/time/timer_stats.c 2009-10-01 20:12:45.000000000 -0400 +@@ -395,7 +395,7 @@ static int tstats_open(struct inode *ino + return single_open(filp, tstats_show, NULL); + } + +-static struct file_operations tstats_fops = { ++static const struct file_operations tstats_fops = { + .open = tstats_open, + .read = seq_read, + .write = tstats_write, +diff -urNp linux-2.6.31.1/kernel/time.c linux-2.6.31.1/kernel/time.c +--- linux-2.6.31.1/kernel/time.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/time.c 2009-10-01 20:12:45.000000000 -0400 +@@ -94,6 +94,9 @@ SYSCALL_DEFINE1(stime, time_t __user *, + return err; + + do_settimeofday(&tv); ++ ++ gr_log_timechange(); ++ + return 0; + } + +@@ -202,6 +205,8 @@ SYSCALL_DEFINE2(settimeofday, struct tim + return -EFAULT; + } + ++ gr_log_timechange(); ++ + return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL); + } + +@@ -240,7 +245,7 @@ EXPORT_SYMBOL(current_fs_time); + * Avoid unnecessary multiplications/divisions in the + * two most common HZ cases: + */ +-unsigned int inline jiffies_to_msecs(const unsigned long j) ++inline unsigned int jiffies_to_msecs(const unsigned long j) + { + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + return (MSEC_PER_SEC / HZ) * j; +@@ -256,7 +261,7 @@ unsigned int inline jiffies_to_msecs(con + } + EXPORT_SYMBOL(jiffies_to_msecs); + +-unsigned int inline jiffies_to_usecs(const unsigned long j) ++inline unsigned int jiffies_to_usecs(const unsigned long j) + { + #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) + return (USEC_PER_SEC / HZ) * j; +diff -urNp linux-2.6.31.1/kernel/trace/ftrace.c linux-2.6.31.1/kernel/trace/ftrace.c +--- linux-2.6.31.1/kernel/trace/ftrace.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/trace/ftrace.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1567,7 +1567,7 @@ static int t_show(struct seq_file *m, vo + return 0; + } + +-static struct seq_operations show_ftrace_seq_ops = { ++static const struct seq_operations show_ftrace_seq_ops = { + .start = t_start, + .next = t_next, + .stop = t_stop, +@@ -2565,7 +2565,7 @@ static int g_show(struct seq_file *m, vo + return 0; + } + +-static struct seq_operations ftrace_graph_seq_ops = { ++static const struct seq_operations ftrace_graph_seq_ops = { + .start = g_start, + .next = g_next, + .stop = g_stop, +diff -urNp linux-2.6.31.1/kernel/trace/Kconfig linux-2.6.31.1/kernel/trace/Kconfig +--- linux-2.6.31.1/kernel/trace/Kconfig 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/trace/Kconfig 2009-10-01 20:12:45.000000000 -0400 +@@ -111,6 +111,7 @@ if FTRACE + config FUNCTION_TRACER + bool "Kernel Function Tracer" + depends on HAVE_FUNCTION_TRACER ++ depends on !PAX_KERNEXEC + select FRAME_POINTER + select KALLSYMS + select GENERIC_TRACER +@@ -326,6 +327,7 @@ config POWER_TRACER + config STACK_TRACER + bool "Trace max stack" + depends on HAVE_FUNCTION_TRACER ++ depends on !PAX_KERNEXEC + select FUNCTION_TRACER + select STACKTRACE + select KALLSYMS +diff -urNp linux-2.6.31.1/kernel/trace/trace.c linux-2.6.31.1/kernel/trace/trace.c +--- linux-2.6.31.1/kernel/trace/trace.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/trace/trace.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1885,7 +1885,7 @@ static int s_show(struct seq_file *m, vo + return 0; + } + +-static struct seq_operations tracer_seq_ops = { ++static const struct seq_operations tracer_seq_ops = { + .start = s_start, + .next = s_next, + .stop = s_stop, +@@ -2097,7 +2097,7 @@ static int t_show(struct seq_file *m, vo + return 0; + } + +-static struct seq_operations show_traces_seq_ops = { ++static const struct seq_operations show_traces_seq_ops = { + .start = t_start, + .next = t_next, + .stop = t_stop, +diff -urNp linux-2.6.31.1/kernel/trace/trace_output.c linux-2.6.31.1/kernel/trace/trace_output.c +--- linux-2.6.31.1/kernel/trace/trace_output.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/trace/trace_output.c 2009-10-01 20:12:45.000000000 -0400 +@@ -234,7 +234,7 @@ int trace_seq_path(struct trace_seq *s, + return 0; + p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len); + if (!IS_ERR(p)) { +- p = mangle_path(s->buffer + s->len, p, "\n"); ++ p = mangle_path(s->buffer + s->len, p, "\n\"); + if (p) { + s->len = p - s->buffer; + return 1; +diff -urNp linux-2.6.31.1/kernel/utsname_sysctl.c linux-2.6.31.1/kernel/utsname_sysctl.c +--- linux-2.6.31.1/kernel/utsname_sysctl.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/kernel/utsname_sysctl.c 2009-10-01 20:12:45.000000000 -0400 +@@ -123,7 +123,7 @@ static struct ctl_table uts_kern_table[] + .proc_handler = proc_do_uts_string, + .strategy = sysctl_uts_string, + }, +- {} ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + + static struct ctl_table uts_root_table[] = { +@@ -133,7 +133,7 @@ static struct ctl_table uts_root_table[] + .mode = 0555, + .child = uts_kern_table, + }, +- {} ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } + }; + + static int __init utsname_sysctl_init(void) +diff -urNp linux-2.6.31.1/lib/inflate.c linux-2.6.31.1/lib/inflate.c +--- linux-2.6.31.1/lib/inflate.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/lib/inflate.c 2009-10-01 20:12:45.000000000 -0400 +@@ -266,7 +266,7 @@ static void free(void *where) + malloc_ptr = free_mem_ptr; + } + #else +-#define malloc(a) kmalloc(a, GFP_KERNEL) ++#define malloc(a) kmalloc((a), GFP_KERNEL) + #define free(a) kfree(a) + #endif + +diff -urNp linux-2.6.31.1/lib/Kconfig.debug linux-2.6.31.1/lib/Kconfig.debug +--- linux-2.6.31.1/lib/Kconfig.debug 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/lib/Kconfig.debug 2009-10-01 20:12:45.000000000 -0400 +@@ -866,7 +866,7 @@ config LATENCYTOP + select STACKTRACE + select SCHEDSTATS + select SCHED_DEBUG +- depends on HAVE_LATENCYTOP_SUPPORT ++ depends on HAVE_LATENCYTOP_SUPPORT && !GRKERNSEC_HIDESYM + help + Enable this option if you want to use the LatencyTOP tool + to find out which userspace is blocking on what kernel operations. +diff -urNp linux-2.6.31.1/lib/parser.c linux-2.6.31.1/lib/parser.c +--- linux-2.6.31.1/lib/parser.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/lib/parser.c 2009-10-01 20:12:45.000000000 -0400 +@@ -126,7 +126,7 @@ static int match_number(substring_t *s, + char *buf; + int ret; + +- buf = kmalloc(s->to - s->from + 1, GFP_KERNEL); ++ buf = kmalloc((s->to - s->from) + 1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + memcpy(buf, s->from, s->to - s->from); +diff -urNp linux-2.6.31.1/lib/radix-tree.c linux-2.6.31.1/lib/radix-tree.c +--- linux-2.6.31.1/lib/radix-tree.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/lib/radix-tree.c 2009-10-01 20:12:45.000000000 -0400 +@@ -81,7 +81,7 @@ struct radix_tree_preload { + int nr; + struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH]; + }; +-static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; ++static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads); + + static inline gfp_t root_gfp_mask(struct radix_tree_root *root) + { +diff -urNp linux-2.6.31.1/lib/random32.c linux-2.6.31.1/lib/random32.c +--- linux-2.6.31.1/lib/random32.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/lib/random32.c 2009-10-01 20:12:45.000000000 -0400 +@@ -61,7 +61,7 @@ static u32 __random32(struct rnd_state * + */ + static inline u32 __seed(u32 x, u32 m) + { +- return (x < m) ? x + m : x; ++ return (x <= m) ? x + m + 1 : x; + } + + /** +diff -urNp linux-2.6.31.1/localversion-grsec linux-2.6.31.1/localversion-grsec +--- linux-2.6.31.1/localversion-grsec 1969-12-31 19:00:00.000000000 -0500 ++++ linux-2.6.31.1/localversion-grsec 2009-10-01 20:12:45.000000000 -0400 +@@ -0,0 +1 @@ ++-grsec +diff -urNp linux-2.6.31.1/Makefile linux-2.6.31.1/Makefile +--- linux-2.6.31.1/Makefile 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/Makefile 2009-10-01 20:12:45.000000000 -0400 +@@ -221,8 +221,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" + + HOSTCC = gcc + HOSTCXX = g++ +-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer +-HOSTCXXFLAGS = -O2 ++HOSTCFLAGS = -Wall -W -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-delete-null-pointer-checks ++HOSTCXXFLAGS = -O2 -fno-delete-null-pointer-checks + + # Decide whether to build built-in, modular, or both. + # Normally, just do built-in. +@@ -639,7 +639,7 @@ export mod_strip_cmd + + + ifeq ($(KBUILD_EXTMOD),) +-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ ++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/ + + vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ + $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ +diff -urNp linux-2.6.31.1/mm/filemap.c linux-2.6.31.1/mm/filemap.c +--- linux-2.6.31.1/mm/filemap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/filemap.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1648,7 +1648,7 @@ page_not_uptodate: + } + EXPORT_SYMBOL(filemap_fault); + +-struct vm_operations_struct generic_file_vm_ops = { ++const struct vm_operations_struct generic_file_vm_ops = { + .fault = filemap_fault, + }; + +@@ -1659,7 +1659,7 @@ int generic_file_mmap(struct file * file + struct address_space *mapping = file->f_mapping; + + if (!mapping->a_ops->readpage) +- return -ENOEXEC; ++ return -ENODEV; + file_accessed(file); + vma->vm_ops = &generic_file_vm_ops; + vma->vm_flags |= VM_CAN_NONLINEAR; +@@ -2019,6 +2019,7 @@ inline int generic_write_checks(struct f + *pos = i_size_read(inode); + + if (limit != RLIM_INFINITY) { ++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0); + if (*pos >= limit) { + send_sig(SIGXFSZ, current, 0); + return -EFBIG; +diff -urNp linux-2.6.31.1/mm/filemap_xip.c linux-2.6.31.1/mm/filemap_xip.c +--- linux-2.6.31.1/mm/filemap_xip.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/filemap_xip.c 2009-10-01 20:12:45.000000000 -0400 +@@ -296,7 +296,7 @@ out: + } + } + +-static struct vm_operations_struct xip_file_vm_ops = { ++static const struct vm_operations_struct xip_file_vm_ops = { + .fault = xip_file_fault, + }; + +diff -urNp linux-2.6.31.1/mm/fremap.c linux-2.6.31.1/mm/fremap.c +--- linux-2.6.31.1/mm/fremap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/fremap.c 2009-10-01 20:12:45.000000000 -0400 +@@ -153,6 +153,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsign + retry: + vma = find_vma(mm, start); + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) ++ goto out; ++#endif ++ + /* + * Make sure the vma is shared, that it supports prefaulting, + * and that the remapped range is valid and fully within +diff -urNp linux-2.6.31.1/mm/highmem.c linux-2.6.31.1/mm/highmem.c +--- linux-2.6.31.1/mm/highmem.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/highmem.c 2009-10-01 20:12:45.000000000 -0400 +@@ -94,6 +94,9 @@ static void flush_all_zero_pkmaps(void) + + for (i = 0; i < LAST_PKMAP; i++) { + struct page *page; ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif + + /* + * zero means we don't have anything to do, +@@ -116,9 +119,18 @@ static void flush_all_zero_pkmaps(void) + * So no dangers, even with speculative execution. + */ + page = pte_page(pkmap_page_table[i]); ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + pte_clear(&init_mm, (unsigned long)page_address(page), + &pkmap_page_table[i]); + ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ + set_page_address(page, NULL); + need_flush = 1; + } +@@ -140,6 +152,9 @@ static inline unsigned long map_new_virt + { + unsigned long vaddr; + int count; ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif + + start: + count = LAST_PKMAP; +@@ -177,8 +192,14 @@ start: + } + } + vaddr = PKMAP_ADDR(last_pkmap_nr); ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif + set_pte_at(&init_mm, vaddr, + &(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot)); ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif + + pkmap_count[last_pkmap_nr] = 1; + set_page_address(page, (void *)vaddr); +diff -urNp linux-2.6.31.1/mm/hugetlb.c linux-2.6.31.1/mm/hugetlb.c +--- linux-2.6.31.1/mm/hugetlb.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/hugetlb.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1689,7 +1689,7 @@ static int hugetlb_vm_op_fault(struct vm + return 0; + } + +-struct vm_operations_struct hugetlb_vm_ops = { ++const struct vm_operations_struct hugetlb_vm_ops = { + .fault = hugetlb_vm_op_fault, + .open = hugetlb_vm_op_open, + .close = hugetlb_vm_op_close, +@@ -1892,6 +1892,26 @@ static int unmap_ref_private(struct mm_s + return 1; + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m) ++{ ++ struct mm_struct *mm = vma->vm_mm; ++ struct vm_area_struct *vma_m; ++ unsigned long address_m; ++ pte_t *ptep_m; ++ ++ vma_m = pax_find_mirror_vma(vma); ++ if (!vma_m) ++ return; ++ ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); ++ address_m = address + SEGMEXEC_TASK_SIZE; ++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK); ++ get_page(page_m); ++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0)); ++} ++#endif ++ + static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long address, pte_t *ptep, pte_t pte, + struct page *pagecache_page) +@@ -1963,6 +1983,11 @@ retry_avoidcopy: + huge_ptep_clear_flush(vma, address, ptep); + set_huge_pte_at(mm, address, ptep, + make_huge_pte(vma, new_page, 1)); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ pax_mirror_huge_pte(vma, address, new_page); ++#endif ++ + /* Make the old page be freed below */ + new_page = old_page; + } +@@ -2072,6 +2097,10 @@ retry: + && (vma->vm_flags & VM_SHARED))); + set_huge_pte_at(mm, address, ptep, new_pte); + ++#ifdef CONFIG_PAX_SEGMEXEC ++ pax_mirror_huge_pte(vma, address, page); ++#endif ++ + if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) { + /* Optimization, do the COW without a second fault */ + ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page); +@@ -2100,6 +2129,28 @@ int hugetlb_fault(struct mm_struct *mm, + static DEFINE_MUTEX(hugetlb_instantiation_mutex); + struct hstate *h = hstate_vma(vma); + ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m; ++ ++ vma_m = pax_find_mirror_vma(vma); ++ if (vma_m) { ++ unsigned long address_m; ++ ++ if (vma->vm_start > vma_m->vm_start) { ++ address_m = address; ++ address -= SEGMEXEC_TASK_SIZE; ++ vma = vma_m; ++ h = hstate_vma(vma); ++ } else ++ address_m = address + SEGMEXEC_TASK_SIZE; ++ ++ if (!huge_pte_alloc(mm, address_m, huge_page_size(h))) ++ return VM_FAULT_OOM; ++ address_m &= HPAGE_MASK; ++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL); ++ } ++#endif ++ + ptep = huge_pte_alloc(mm, address, huge_page_size(h)); + if (!ptep) + return VM_FAULT_OOM; +diff -urNp linux-2.6.31.1/mm/Kconfig linux-2.6.31.1/mm/Kconfig +--- linux-2.6.31.1/mm/Kconfig 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/Kconfig 2009-10-01 20:12:45.000000000 -0400 +@@ -216,7 +216,7 @@ config MMU_NOTIFIER + + config DEFAULT_MMAP_MIN_ADDR + int "Low address space to protect from user allocation" +- default 4096 ++ default 65536 + help + This is the portion of low virtual memory which should be protected + from userspace allocation. Keeping a user from writing to low pages +diff -urNp linux-2.6.31.1/mm/madvise.c linux-2.6.31.1/mm/madvise.c +--- linux-2.6.31.1/mm/madvise.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/madvise.c 2009-10-01 20:12:45.000000000 -0400 +@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a + pgoff_t pgoff; + int new_flags = vma->vm_flags; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m; ++#endif ++ + switch (behavior) { + case MADV_NORMAL: + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ; +@@ -92,6 +96,13 @@ success: + /* + * vm_flags is protected by the mmap_sem held in write mode. + */ ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ vma_m = pax_find_mirror_vma(vma); ++ if (vma_m) ++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT); ++#endif ++ + vma->vm_flags = new_flags; + + out: +@@ -235,6 +246,17 @@ madvise_vma(struct vm_area_struct *vma, + + case MADV_DONTNEED: + error = madvise_dontneed(vma, prev, start, end); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (!error) { ++ struct vm_area_struct *vma_m, *prev_m; ++ ++ vma_m = pax_find_mirror_vma(vma); ++ if (vma_m) ++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE); ++ } ++#endif ++ + break; + + default: +@@ -328,6 +350,16 @@ SYSCALL_DEFINE3(madvise, unsigned long, + if (end < start) + goto out; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { ++ if (end > SEGMEXEC_TASK_SIZE) ++ goto out; ++ } else ++#endif ++ ++ if (end > TASK_SIZE) ++ goto out; ++ + error = 0; + if (end == start) + goto out; +diff -urNp linux-2.6.31.1/mm/memory.c linux-2.6.31.1/mm/memory.c +--- linux-2.6.31.1/mm/memory.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/memory.c 2009-10-01 20:12:45.000000000 -0400 +@@ -47,6 +47,7 @@ + #include <linux/pagemap.h> + #include <linux/rmap.h> + #include <linux/module.h> ++#include <linux/security.h> + #include <linux/delayacct.h> + #include <linux/init.h> + #include <linux/writeback.h> +@@ -1228,11 +1229,11 @@ int __get_user_pages(struct task_struct + vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE); + i = 0; + +- do { ++ while (nr_pages) { + struct vm_area_struct *vma; + unsigned int foll_flags; + +- vma = find_extend_vma(mm, start); ++ vma = find_vma(mm, start); + if (!vma && in_gate_area(tsk, start)) { + unsigned long pg = start & PAGE_MASK; + struct vm_area_struct *gate_vma = get_gate_vma(tsk); +@@ -1274,7 +1275,7 @@ int __get_user_pages(struct task_struct + continue; + } + +- if (!vma || ++ if (!vma || start < vma->vm_start || + (vma->vm_flags & (VM_IO | VM_PFNMAP)) || + (!ignore && !(vm_flags & vma->vm_flags))) + return i ? : -EFAULT; +@@ -1360,7 +1361,7 @@ int __get_user_pages(struct task_struct + start += PAGE_SIZE; + nr_pages--; + } while (nr_pages && start < vma->vm_end); +- } while (nr_pages); ++ } + return i; + } + +@@ -1926,6 +1927,186 @@ static inline void cow_user_page(struct + copy_user_highpage(dst, src, va, vma); + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd) ++{ ++ struct mm_struct *mm = vma->vm_mm; ++ spinlock_t *ptl; ++ pte_t *pte, entry; ++ ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl); ++ entry = *pte; ++ if (!pte_present(entry)) { ++ if (!pte_none(entry)) { ++ BUG_ON(pte_file(entry)); ++ free_swap_and_cache(pte_to_swp_entry(entry)); ++ pte_clear_not_present_full(mm, address, pte, 0); ++ } ++ } else { ++ struct page *page; ++ ++ flush_cache_page(vma, address, pte_pfn(entry)); ++ entry = ptep_clear_flush(vma, address, pte); ++ BUG_ON(pte_dirty(entry)); ++ page = vm_normal_page(vma, address, entry); ++ if (page) { ++ update_hiwater_rss(mm); ++ if (PageAnon(page)) ++ dec_mm_counter(mm, anon_rss); ++ else ++ dec_mm_counter(mm, file_rss); ++ page_remove_rmap(page); ++ page_cache_release(page); ++ } ++ } ++ pte_unmap_unlock(pte, ptl); ++} ++ ++/* PaX: if vma is mirrored, synchronize the mirror's PTE ++ * ++ * the ptl of the lower mapped page is held on entry and is not released on exit ++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc) ++ */ ++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl) ++{ ++ struct mm_struct *mm = vma->vm_mm; ++ unsigned long address_m; ++ spinlock_t *ptl_m; ++ struct vm_area_struct *vma_m; ++ pmd_t *pmd_m; ++ pte_t *pte_m, entry_m; ++ ++ BUG_ON(!page_m || !PageAnon(page_m)); ++ ++ vma_m = pax_find_mirror_vma(vma); ++ if (!vma_m) ++ return; ++ ++ BUG_ON(!PageLocked(page_m)); ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); ++ address_m = address + SEGMEXEC_TASK_SIZE; ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m); ++ pte_m = pte_offset_map_nested(pmd_m, address_m); ++ ptl_m = pte_lockptr(mm, pmd_m); ++ if (ptl != ptl_m) { ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING); ++ if (!pte_none(*pte_m)) ++ goto out; ++ } ++ ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot); ++ page_cache_get(page_m); ++ page_add_anon_rmap(page_m, vma_m, address_m); ++ inc_mm_counter(mm, anon_rss); ++ set_pte_at(mm, address_m, pte_m, entry_m); ++ update_mmu_cache(vma_m, address_m, entry_m); ++out: ++ if (ptl != ptl_m) ++ spin_unlock(ptl_m); ++ pte_unmap_nested(pte_m); ++ unlock_page(page_m); ++} ++ ++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl) ++{ ++ struct mm_struct *mm = vma->vm_mm; ++ unsigned long address_m; ++ spinlock_t *ptl_m; ++ struct vm_area_struct *vma_m; ++ pmd_t *pmd_m; ++ pte_t *pte_m, entry_m; ++ ++ BUG_ON(!page_m || PageAnon(page_m)); ++ ++ vma_m = pax_find_mirror_vma(vma); ++ if (!vma_m) ++ return; ++ ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); ++ address_m = address + SEGMEXEC_TASK_SIZE; ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m); ++ pte_m = pte_offset_map_nested(pmd_m, address_m); ++ ptl_m = pte_lockptr(mm, pmd_m); ++ if (ptl != ptl_m) { ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING); ++ if (!pte_none(*pte_m)) ++ goto out; ++ } ++ ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot); ++ page_cache_get(page_m); ++ page_add_file_rmap(page_m); ++ inc_mm_counter(mm, file_rss); ++ set_pte_at(mm, address_m, pte_m, entry_m); ++ update_mmu_cache(vma_m, address_m, entry_m); ++out: ++ if (ptl != ptl_m) ++ spin_unlock(ptl_m); ++ pte_unmap_nested(pte_m); ++} ++ ++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl) ++{ ++ struct mm_struct *mm = vma->vm_mm; ++ unsigned long address_m; ++ spinlock_t *ptl_m; ++ struct vm_area_struct *vma_m; ++ pmd_t *pmd_m; ++ pte_t *pte_m, entry_m; ++ ++ vma_m = pax_find_mirror_vma(vma); ++ if (!vma_m) ++ return; ++ ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); ++ address_m = address + SEGMEXEC_TASK_SIZE; ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m); ++ pte_m = pte_offset_map_nested(pmd_m, address_m); ++ ptl_m = pte_lockptr(mm, pmd_m); ++ if (ptl != ptl_m) { ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING); ++ if (!pte_none(*pte_m)) ++ goto out; ++ } ++ ++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot); ++ set_pte_at(mm, address_m, pte_m, entry_m); ++out: ++ if (ptl != ptl_m) ++ spin_unlock(ptl_m); ++ pte_unmap_nested(pte_m); ++} ++ ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl) ++{ ++ struct page *page_m; ++ pte_t entry; ++ ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC)) ++ goto out; ++ ++ entry = *pte; ++ page_m = vm_normal_page(vma, address, entry); ++ if (!page_m) ++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl); ++ else if (PageAnon(page_m)) { ++ if (pax_find_mirror_vma(vma)) { ++ pte_unmap_unlock(pte, ptl); ++ lock_page(page_m); ++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl); ++ if (pte_same(entry, *pte)) ++ pax_mirror_anon_pte(vma, address, page_m, ptl); ++ else ++ unlock_page(page_m); ++ } ++ } else ++ pax_mirror_file_pte(vma, address, page_m, ptl); ++ ++out: ++ pte_unmap_unlock(pte, ptl); ++} ++#endif ++ + /* + * This routine handles present pages, when users try to write + * to a shared page. It is done by copying the page to a new address +@@ -2098,6 +2279,12 @@ gotten: + */ + page_table = pte_offset_map_lock(mm, pmd, address, &ptl); + if (likely(pte_same(*page_table, orig_pte))) { ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (pax_find_mirror_vma(vma)) ++ BUG_ON(!trylock_page(new_page)); ++#endif ++ + if (old_page) { + if (!PageAnon(old_page)) { + dec_mm_counter(mm, file_rss); +@@ -2144,6 +2331,10 @@ gotten: + page_remove_rmap(old_page); + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++ pax_mirror_anon_pte(vma, address, new_page, ptl); ++#endif ++ + /* Free the old page.. */ + new_page = old_page; + ret |= VM_FAULT_WRITE; +@@ -2425,6 +2616,7 @@ int vmtruncate(struct inode * inode, lof + unsigned long limit; + + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; ++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1); + if (limit != RLIM_INFINITY && offset > limit) + goto out_sig; + if (offset > inode->i_sb->s_maxbytes) +@@ -2587,6 +2779,11 @@ static int do_swap_page(struct mm_struct + swap_free(entry); + if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page)) + try_to_free_swap(page); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((flags & FAULT_FLAG_WRITE) || !pax_find_mirror_vma(vma)) ++#endif ++ + unlock_page(page); + + if (flags & FAULT_FLAG_WRITE) { +@@ -2598,6 +2795,11 @@ static int do_swap_page(struct mm_struct + + /* No need to invalidate - it was non-present before */ + update_mmu_cache(vma, address, pte); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ pax_mirror_anon_pte(vma, address, page, ptl); ++#endif ++ + unlock: + pte_unmap_unlock(page_table, ptl); + out: +@@ -2643,12 +2845,23 @@ static int do_anonymous_page(struct mm_s + page_table = pte_offset_map_lock(mm, pmd, address, &ptl); + if (!pte_none(*page_table)) + goto release; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (pax_find_mirror_vma(vma)) ++ BUG_ON(!trylock_page(page)); ++#endif ++ + inc_mm_counter(mm, anon_rss); + page_add_new_anon_rmap(page, vma, address); + set_pte_at(mm, address, page_table, entry); + + /* No need to invalidate - it was non-present before */ + update_mmu_cache(vma, address, entry); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ pax_mirror_anon_pte(vma, address, page, ptl); ++#endif ++ + unlock: + pte_unmap_unlock(page_table, ptl); + return 0; +@@ -2785,6 +2998,12 @@ static int __do_fault(struct mm_struct * + */ + /* Only go through if we didn't race with anybody else... */ + if (likely(pte_same(*page_table, orig_pte))) { ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (anon && pax_find_mirror_vma(vma)) ++ BUG_ON(!trylock_page(page)); ++#endif ++ + flush_icache_page(vma, page); + entry = mk_pte(page, vma->vm_page_prot); + if (flags & FAULT_FLAG_WRITE) +@@ -2804,6 +3023,14 @@ static int __do_fault(struct mm_struct * + + /* no need to invalidate: a not-present page won't be cached */ + update_mmu_cache(vma, address, entry); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (anon) ++ pax_mirror_anon_pte(vma, address, page, ptl); ++ else ++ pax_mirror_file_pte(vma, address, page, ptl); ++#endif ++ + } else { + if (charged) + mem_cgroup_uncharge_page(page); +@@ -2951,6 +3178,12 @@ static inline int handle_pte_fault(struc + if (flags & FAULT_FLAG_WRITE) + flush_tlb_page(vma, address); + } ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ pax_mirror_pte(vma, address, pte, pmd, ptl); ++ return 0; ++#endif ++ + unlock: + pte_unmap_unlock(pte, ptl); + return 0; +@@ -2967,6 +3200,10 @@ int handle_mm_fault(struct mm_struct *mm + pmd_t *pmd; + pte_t *pte; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m; ++#endif ++ + __set_current_state(TASK_RUNNING); + + count_vm_event(PGFAULT); +@@ -2974,6 +3211,34 @@ int handle_mm_fault(struct mm_struct *mm + if (unlikely(is_vm_hugetlb_page(vma))) + return hugetlb_fault(mm, vma, address, flags); + ++#ifdef CONFIG_PAX_SEGMEXEC ++ vma_m = pax_find_mirror_vma(vma); ++ if (vma_m) { ++ unsigned long address_m; ++ pgd_t *pgd_m; ++ pud_t *pud_m; ++ pmd_t *pmd_m; ++ ++ if (vma->vm_start > vma_m->vm_start) { ++ address_m = address; ++ address -= SEGMEXEC_TASK_SIZE; ++ vma = vma_m; ++ } else ++ address_m = address + SEGMEXEC_TASK_SIZE; ++ ++ pgd_m = pgd_offset(mm, address_m); ++ pud_m = pud_alloc(mm, pgd_m, address_m); ++ if (!pud_m) ++ return VM_FAULT_OOM; ++ pmd_m = pmd_alloc(mm, pud_m, address_m); ++ if (!pmd_m) ++ return VM_FAULT_OOM; ++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m)) ++ return VM_FAULT_OOM; ++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m); ++ } ++#endif ++ + pgd = pgd_offset(mm, address); + pud = pud_alloc(mm, pgd, address); + if (!pud) +@@ -3071,7 +3336,7 @@ static int __init gate_vma_init(void) + gate_vma.vm_start = FIXADDR_USER_START; + gate_vma.vm_end = FIXADDR_USER_END; + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; +- gate_vma.vm_page_prot = __P101; ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags); + /* + * Make sure the vDSO gets into every core dump. + * Dumping its contents makes post-mortem fully interpretable later +diff -urNp linux-2.6.31.1/mm/mempolicy.c linux-2.6.31.1/mm/mempolicy.c +--- linux-2.6.31.1/mm/mempolicy.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/mempolicy.c 2009-10-01 20:12:45.000000000 -0400 +@@ -573,6 +573,10 @@ static int mbind_range(struct vm_area_st + struct vm_area_struct *next; + int err; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m; ++#endif ++ + err = 0; + for (; vma && vma->vm_start < end; vma = next) { + next = vma->vm_next; +@@ -584,6 +588,16 @@ static int mbind_range(struct vm_area_st + err = policy_vma(vma, new); + if (err) + break; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ vma_m = pax_find_mirror_vma(vma); ++ if (vma_m) { ++ err = policy_vma(vma_m, new); ++ if (err) ++ break; ++ } ++#endif ++ + } + return err; + } +@@ -1002,6 +1016,17 @@ static long do_mbind(unsigned long start + + if (end < start) + return -EINVAL; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) { ++ if (end > SEGMEXEC_TASK_SIZE) ++ return -EINVAL; ++ } else ++#endif ++ ++ if (end > TASK_SIZE) ++ return -EINVAL; ++ + if (end == start) + return 0; + +@@ -1206,6 +1231,14 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi + if (!mm) + return -EINVAL; + ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ if (mm != current->mm && ++ (mm->pax_flags & MF_PAX_RANDMMAP || mm->pax_flags & MF_PAX_SEGMEXEC)) { ++ err = -EPERM; ++ goto out; ++ } ++#endif ++ + /* + * Check if this process has the right to modify the specified + * process. The right exists if the process has administrative +@@ -1215,8 +1248,7 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pi + rcu_read_lock(); + tcred = __task_cred(task); + if (cred->euid != tcred->suid && cred->euid != tcred->uid && +- cred->uid != tcred->suid && cred->uid != tcred->uid && +- !capable(CAP_SYS_NICE)) { ++ cred->uid != tcred->suid && !capable(CAP_SYS_NICE)) { + rcu_read_unlock(); + err = -EPERM; + goto out; +@@ -2385,7 +2417,7 @@ int show_numa_map(struct seq_file *m, vo + + if (file) { + seq_printf(m, " file="); +- seq_path(m, &file->f_path, "\n\t= "); ++ seq_path(m, &file->f_path, "\n\t\= "); + } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { + seq_printf(m, " heap"); + } else if (vma->vm_start <= mm->start_stack && +diff -urNp linux-2.6.31.1/mm/migrate.c linux-2.6.31.1/mm/migrate.c +--- linux-2.6.31.1/mm/migrate.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/migrate.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1087,6 +1087,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, + if (!mm) + return -EINVAL; + ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ if (mm != current->mm && ++ (mm->pax_flags & MF_PAX_RANDMMAP || mm->pax_flags & MF_PAX_SEGMEXEC)) { ++ err = -EPERM; ++ goto out; ++ } ++#endif ++ + /* + * Check if this process has the right to modify the specified + * process. The right exists if the process has administrative +@@ -1096,8 +1104,7 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, + rcu_read_lock(); + tcred = __task_cred(task); + if (cred->euid != tcred->suid && cred->euid != tcred->uid && +- cred->uid != tcred->suid && cred->uid != tcred->uid && +- !capable(CAP_SYS_NICE)) { ++ cred->uid != tcred->suid && !capable(CAP_SYS_NICE)) { + rcu_read_unlock(); + err = -EPERM; + goto out; +diff -urNp linux-2.6.31.1/mm/mlock.c linux-2.6.31.1/mm/mlock.c +--- linux-2.6.31.1/mm/mlock.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/mlock.c 2009-10-01 20:12:45.000000000 -0400 +@@ -13,6 +13,7 @@ + #include <linux/pagemap.h> + #include <linux/mempolicy.h> + #include <linux/syscalls.h> ++#include <linux/security.h> + #include <linux/sched.h> + #include <linux/module.h> + #include <linux/rmap.h> +@@ -431,6 +432,17 @@ static int do_mlock(unsigned long start, + return -EINVAL; + if (end == start) + return 0; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { ++ if (end > SEGMEXEC_TASK_SIZE) ++ return -EINVAL; ++ } else ++#endif ++ ++ if (end > TASK_SIZE) ++ return -EINVAL; ++ + vma = find_vma_prev(current->mm, start, &prev); + if (!vma || vma->vm_start > start) + return -ENOMEM; +@@ -490,6 +502,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st + lock_limit >>= PAGE_SHIFT; + + /* check against resource limits */ ++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1); + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK)) + error = do_mlock(start, len, 1); + up_write(¤t->mm->mmap_sem); +@@ -511,10 +524,10 @@ SYSCALL_DEFINE2(munlock, unsigned long, + static int do_mlockall(int flags) + { + struct vm_area_struct * vma, * prev = NULL; +- unsigned int def_flags = 0; ++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED; + + if (flags & MCL_FUTURE) +- def_flags = VM_LOCKED; ++ def_flags |= VM_LOCKED; + current->mm->def_flags = def_flags; + if (flags == MCL_FUTURE) + goto out; +@@ -522,6 +535,12 @@ static int do_mlockall(int flags) + for (vma = current->mm->mmap; vma ; vma = prev->vm_next) { + unsigned int newflags; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) ++ break; ++#endif ++ ++ BUG_ON(vma->vm_end > TASK_SIZE); + newflags = vma->vm_flags | VM_LOCKED; + if (!(flags & MCL_CURRENT)) + newflags &= ~VM_LOCKED; +@@ -553,6 +572,7 @@ SYSCALL_DEFINE1(mlockall, int, flags) + lock_limit >>= PAGE_SHIFT; + + ret = -ENOMEM; ++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1); + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) || + capable(CAP_IPC_LOCK)) + ret = do_mlockall(flags); +diff -urNp linux-2.6.31.1/mm/mmap.c linux-2.6.31.1/mm/mmap.c +--- linux-2.6.31.1/mm/mmap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/mmap.c 2009-10-01 20:12:45.000000000 -0400 +@@ -45,6 +45,16 @@ + #define arch_rebalance_pgtables(addr, len) (addr) + #endif + ++static inline void verify_mm_writelocked(struct mm_struct *mm) ++{ ++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX) ++ if (unlikely(down_read_trylock(&mm->mmap_sem))) { ++ up_read(&mm->mmap_sem); ++ BUG(); ++ } ++#endif ++} ++ + static void unmap_region(struct mm_struct *mm, + struct vm_area_struct *vma, struct vm_area_struct *prev, + unsigned long start, unsigned long end); +@@ -70,16 +80,25 @@ static void unmap_region(struct mm_struc + * x: (no) no x: (no) yes x: (no) yes x: (yes) yes + * + */ +-pgprot_t protection_map[16] = { ++pgprot_t protection_map[16] __read_only = { + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111 + }; + + pgprot_t vm_get_page_prot(unsigned long vm_flags) + { +- return __pgprot(pgprot_val(protection_map[vm_flags & ++ pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags & + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) | + pgprot_val(arch_vm_get_page_prot(vm_flags))); ++ ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) ++ if (!nx_enabled && ++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC && ++ (vm_flags & (VM_READ | VM_WRITE))) ++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot))))); ++#endif ++ ++ return prot; + } + EXPORT_SYMBOL(vm_get_page_prot); + +@@ -231,6 +250,7 @@ static struct vm_area_struct *remove_vma + struct vm_area_struct *next = vma->vm_next; + + might_sleep(); ++ BUG_ON(vma->vm_mirror); + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); + if (vma->vm_file) { +@@ -267,6 +287,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) + * not page aligned -Ram Gupta + */ + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; ++ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1); + if (rlim < RLIM_INFINITY && (brk - mm->start_brk) + + (mm->end_data - mm->start_data) > rlim) + goto out; +@@ -696,6 +717,12 @@ static int + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags, + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff) + { ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE) ++ return 0; ++#endif ++ + if (is_mergeable_vma(vma, file, vm_flags) && + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) { + if (vma->vm_pgoff == vm_pgoff) +@@ -715,6 +742,12 @@ static int + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff) + { ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE) ++ return 0; ++#endif ++ + if (is_mergeable_vma(vma, file, vm_flags) && + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) { + pgoff_t vm_pglen; +@@ -757,12 +790,19 @@ can_vma_merge_after(struct vm_area_struc + struct vm_area_struct *vma_merge(struct mm_struct *mm, + struct vm_area_struct *prev, unsigned long addr, + unsigned long end, unsigned long vm_flags, +- struct anon_vma *anon_vma, struct file *file, ++ struct anon_vma *anon_vma, struct file *file, + pgoff_t pgoff, struct mempolicy *policy) + { + pgoff_t pglen = (end - addr) >> PAGE_SHIFT; + struct vm_area_struct *area, *next; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE; ++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL; ++ ++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end); ++#endif ++ + /* + * We later require that vma->vm_flags == vm_flags, + * so this tests vma->vm_flags & VM_SPECIAL, too. +@@ -778,6 +818,15 @@ struct vm_area_struct *vma_merge(struct + if (next && next->vm_end == end) /* cases 6, 7, 8 */ + next = next->vm_next; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (prev) ++ prev_m = pax_find_mirror_vma(prev); ++ if (area) ++ area_m = pax_find_mirror_vma(area); ++ if (next) ++ next_m = pax_find_mirror_vma(next); ++#endif ++ + /* + * Can it merge with the predecessor? + */ +@@ -797,9 +846,24 @@ struct vm_area_struct *vma_merge(struct + /* cases 1, 6 */ + vma_adjust(prev, prev->vm_start, + next->vm_end, prev->vm_pgoff, NULL); +- } else /* cases 2, 5, 7 */ ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (prev_m) ++ vma_adjust(prev_m, prev_m->vm_start, ++ next_m->vm_end, prev_m->vm_pgoff, NULL); ++#endif ++ ++ } else { /* cases 2, 5, 7 */ + vma_adjust(prev, prev->vm_start, + end, prev->vm_pgoff, NULL); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (prev_m) ++ vma_adjust(prev_m, prev_m->vm_start, ++ end_m, prev_m->vm_pgoff, NULL); ++#endif ++ ++ } + return prev; + } + +@@ -810,12 +874,27 @@ struct vm_area_struct *vma_merge(struct + mpol_equal(policy, vma_policy(next)) && + can_vma_merge_before(next, vm_flags, + anon_vma, file, pgoff+pglen)) { +- if (prev && addr < prev->vm_end) /* case 4 */ ++ if (prev && addr < prev->vm_end) { /* case 4 */ + vma_adjust(prev, prev->vm_start, + addr, prev->vm_pgoff, NULL); +- else /* cases 3, 8 */ ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (prev_m) ++ vma_adjust(prev_m, prev_m->vm_start, ++ addr_m, prev_m->vm_pgoff, NULL); ++#endif ++ ++ } else { /* cases 3, 8 */ + vma_adjust(area, addr, next->vm_end, + next->vm_pgoff - pglen, NULL); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (area_m) ++ vma_adjust(area_m, addr_m, next_m->vm_end, ++ next_m->vm_pgoff - pglen, NULL); ++#endif ++ ++ } + return area; + } + +@@ -890,14 +969,11 @@ none: + void vm_stat_account(struct mm_struct *mm, unsigned long flags, + struct file *file, long pages) + { +- const unsigned long stack_flags +- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN); +- + if (file) { + mm->shared_vm += pages; + if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC) + mm->exec_vm += pages; +- } else if (flags & stack_flags) ++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN)) + mm->stack_vm += pages; + if (flags & (VM_RESERVED|VM_IO)) + mm->reserved_vm += pages; +@@ -924,7 +1000,7 @@ unsigned long do_mmap_pgoff(struct file + * (the exception is when the underlying filesystem is noexec + * mounted, in which case we dont add PROT_EXEC.) + */ +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC)) + if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC))) + prot |= PROT_EXEC; + +@@ -934,15 +1010,15 @@ unsigned long do_mmap_pgoff(struct file + if (!(flags & MAP_FIXED)) + addr = round_hint_to_min(addr); + +- error = arch_mmap_check(addr, len, flags); +- if (error) +- return error; +- + /* Careful about overflows.. */ + len = PAGE_ALIGN(len); + if (!len || len > TASK_SIZE) + return -ENOMEM; + ++ error = arch_mmap_check(addr, len, flags); ++ if (error) ++ return error; ++ + /* offset overflow? */ + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff) + return -EOVERFLOW; +@@ -954,7 +1030,7 @@ unsigned long do_mmap_pgoff(struct file + /* Obtain the address to map to. we verify (or select) it and ensure + * that it represents a valid section of the address space. + */ +- addr = get_unmapped_area(file, addr, len, pgoff, flags); ++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0)); + if (addr & ~PAGE_MASK) + return addr; + +@@ -965,6 +1041,26 @@ unsigned long do_mmap_pgoff(struct file + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) | + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; + ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if (mm->pax_flags & MF_PAX_MPROTECT) { ++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC) ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC); ++ else ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE); ++ } ++#endif ++ ++ } ++#endif ++ ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file) ++ vm_flags &= ~VM_PAGEEXEC; ++#endif ++ + if (flags & MAP_LOCKED) { + if (!can_do_mlock()) + return -EPERM; +@@ -978,6 +1074,7 @@ unsigned long do_mmap_pgoff(struct file + locked += mm->locked_vm; + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit >>= PAGE_SHIFT; ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1); + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) + return -EAGAIN; + } +@@ -1051,6 +1148,9 @@ unsigned long do_mmap_pgoff(struct file + if (error) + return error; + ++ if (!gr_acl_handle_mmap(file, prot)) ++ return -EACCES; ++ + return mmap_region(file, addr, len, flags, vm_flags, pgoff); + } + EXPORT_SYMBOL(do_mmap_pgoff); +@@ -1063,10 +1163,10 @@ EXPORT_SYMBOL(do_mmap_pgoff); + */ + int vma_wants_writenotify(struct vm_area_struct *vma) + { +- unsigned int vm_flags = vma->vm_flags; ++ unsigned long vm_flags = vma->vm_flags; + + /* If it was private or non-writable, the write bit is already clear */ +- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED))) ++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED)) + return 0; + + /* The backer wishes to know when pages are first written to? */ +@@ -1115,14 +1215,24 @@ unsigned long mmap_region(struct file *f + unsigned long charged = 0; + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m = NULL; ++#endif ++ ++ /* ++ * mm->mmap_sem is required to protect against another thread ++ * changing the mappings in case we sleep. ++ */ ++ verify_mm_writelocked(mm); ++ + /* Clear old maps */ + error = -ENOMEM; +-munmap_back: + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); + if (vma && vma->vm_start < addr + len) { + if (do_munmap(mm, addr, len)) + return -ENOMEM; +- goto munmap_back; ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); ++ BUG_ON(vma && vma->vm_start < addr + len); + } + + /* Check against address space limit. */ +@@ -1171,6 +1281,16 @@ munmap_back: + goto unacct_error; + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) { ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); ++ if (!vma_m) { ++ error = -ENOMEM; ++ goto free_vma; ++ } ++ } ++#endif ++ + vma->vm_mm = mm; + vma->vm_start = addr; + vma->vm_end = addr + len; +@@ -1193,6 +1313,19 @@ munmap_back: + error = file->f_op->mmap(file, vma); + if (error) + goto unmap_and_free_vma; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (vma_m && (vm_flags & VM_EXECUTABLE)) ++ added_exe_file_vma(mm); ++#endif ++ ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) { ++ vma->vm_flags |= VM_PAGEEXEC; ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); ++ } ++#endif ++ + if (vm_flags & VM_EXECUTABLE) + added_exe_file_vma(mm); + } else if (vm_flags & VM_SHARED) { +@@ -1216,6 +1349,11 @@ munmap_back: + vma_link(mm, vma, prev, rb_link, rb_parent); + file = vma->vm_file; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (vma_m) ++ pax_mirror_vma(vma_m, vma); ++#endif ++ + /* Once vma denies write, undo our temporary denial count */ + if (correct_wcount) + atomic_inc(&inode->i_writecount); +@@ -1224,6 +1362,7 @@ out: + + mm->total_vm += len >> PAGE_SHIFT; + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); ++ track_exec_limit(mm, addr, addr + len, vm_flags); + if (vm_flags & VM_LOCKED) { + /* + * makes pages present; downgrades, drops, reacquires mmap_sem +@@ -1246,6 +1385,12 @@ unmap_and_free_vma: + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); + charged = 0; + free_vma: ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (vma_m) ++ kmem_cache_free(vm_area_cachep, vma_m); ++#endif ++ + kmem_cache_free(vm_area_cachep, vma); + unacct_error: + if (charged) +@@ -1279,6 +1424,10 @@ arch_get_unmapped_area(struct file *filp + if (flags & MAP_FIXED) + return addr; + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ + if (addr) { + addr = PAGE_ALIGN(addr); + vma = find_vma(mm, addr); +@@ -1287,10 +1436,10 @@ arch_get_unmapped_area(struct file *filp + return addr; + } + if (len > mm->cached_hole_size) { +- start_addr = addr = mm->free_area_cache; ++ start_addr = addr = mm->free_area_cache; + } else { +- start_addr = addr = TASK_UNMAPPED_BASE; +- mm->cached_hole_size = 0; ++ start_addr = addr = mm->mmap_base; ++ mm->cached_hole_size = 0; + } + + full_search: +@@ -1301,9 +1450,8 @@ full_search: + * Start a new search - just in case we missed + * some holes. + */ +- if (start_addr != TASK_UNMAPPED_BASE) { +- addr = TASK_UNMAPPED_BASE; +- start_addr = addr; ++ if (start_addr != mm->mmap_base) { ++ start_addr = addr = mm->mmap_base; + mm->cached_hole_size = 0; + goto full_search; + } +@@ -1325,10 +1473,16 @@ full_search: + + void arch_unmap_area(struct mm_struct *mm, unsigned long addr) + { ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr) ++ return; ++#endif ++ + /* + * Is this a new hole at the lowest possible address? + */ +- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) { ++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) { + mm->free_area_cache = addr; + mm->cached_hole_size = ~0UL; + } +@@ -1346,7 +1500,7 @@ arch_get_unmapped_area_topdown(struct fi + { + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; +- unsigned long addr = addr0; ++ unsigned long base = mm->mmap_base, addr = addr0; + + /* requested length too big for entire address space */ + if (len > TASK_SIZE) +@@ -1355,6 +1509,10 @@ arch_get_unmapped_area_topdown(struct fi + if (flags & MAP_FIXED) + return addr; + ++#ifdef CONFIG_PAX_RANDMMAP ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) ++#endif ++ + /* requesting a specific address */ + if (addr) { + addr = PAGE_ALIGN(addr); +@@ -1412,13 +1570,21 @@ bottomup: + * can happen with large stack limits and large mmap() + * allocations. + */ ++ mm->mmap_base = TASK_UNMAPPED_BASE; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base += mm->delta_mmap; ++#endif ++ ++ mm->free_area_cache = mm->mmap_base; + mm->cached_hole_size = ~0UL; +- mm->free_area_cache = TASK_UNMAPPED_BASE; + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); + /* + * Restore the topdown base: + */ +- mm->free_area_cache = mm->mmap_base; ++ mm->mmap_base = base; ++ mm->free_area_cache = base; + mm->cached_hole_size = ~0UL; + + return addr; +@@ -1427,6 +1593,12 @@ bottomup: + + void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr) + { ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr) ++ return; ++#endif ++ + /* + * Is this a new hole at the highest possible address? + */ +@@ -1434,8 +1606,10 @@ void arch_unmap_area_topdown(struct mm_s + mm->free_area_cache = addr; + + /* dont allow allocations above current base */ +- if (mm->free_area_cache > mm->mmap_base) ++ if (mm->free_area_cache > mm->mmap_base) { + mm->free_area_cache = mm->mmap_base; ++ mm->cached_hole_size = ~0UL; ++ } + } + + unsigned long +@@ -1535,6 +1709,27 @@ out: + return prev ? prev->vm_next : vma; + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma) ++{ ++ struct vm_area_struct *vma_m; ++ ++ BUG_ON(!vma || vma->vm_start >= vma->vm_end); ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) { ++ BUG_ON(vma->vm_mirror); ++ return NULL; ++ } ++ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end); ++ vma_m = vma->vm_mirror; ++ BUG_ON(!vma_m || vma_m->vm_mirror != vma); ++ BUG_ON(vma->vm_file != vma_m->vm_file); ++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start); ++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma); ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED)); ++ return vma_m; ++} ++#endif ++ + /* + * Verify that the stack growth is acceptable and + * update accounting. This is shared with both the +@@ -1551,6 +1746,7 @@ static int acct_stack_growth(struct vm_a + return -ENOMEM; + + /* Stack limit test */ ++ gr_learn_resource(current, RLIMIT_STACK, size, 1); + if (size > rlim[RLIMIT_STACK].rlim_cur) + return -ENOMEM; + +@@ -1560,6 +1756,7 @@ static int acct_stack_growth(struct vm_a + unsigned long limit; + locked = mm->locked_vm + grow; + limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1); + if (locked > limit && !capable(CAP_IPC_LOCK)) + return -ENOMEM; + } +@@ -1595,35 +1792,40 @@ static + #endif + int expand_upwards(struct vm_area_struct *vma, unsigned long address) + { +- int error; ++ int error, locknext; + + if (!(vma->vm_flags & VM_GROWSUP)) + return -EFAULT; + ++ /* Also guard against wrapping around to address 0. */ ++ if (address < PAGE_ALIGN(address+1)) ++ address = PAGE_ALIGN(address+1); ++ else ++ return -ENOMEM; ++ + /* + * We must make sure the anon_vma is allocated + * so that the anon_vma locking is not a noop. + */ + if (unlikely(anon_vma_prepare(vma))) + return -ENOMEM; ++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN); ++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next))) ++ return -ENOMEM; + anon_vma_lock(vma); ++ if (locknext) ++ anon_vma_lock(vma->vm_next); + + /* + * vma->vm_start/vm_end cannot change under us because the caller + * is required to hold the mmap_sem in read mode. We need the +- * anon_vma lock to serialize against concurrent expand_stacks. +- * Also guard against wrapping around to address 0. ++ * anon_vma locks to serialize against concurrent expand_stacks ++ * and expand_upwards. + */ +- if (address < PAGE_ALIGN(address+4)) +- address = PAGE_ALIGN(address+4); +- else { +- anon_vma_unlock(vma); +- return -ENOMEM; +- } + error = 0; + + /* Somebody else might have raced and expanded it already */ +- if (address > vma->vm_end) { ++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) { + unsigned long size, grow; + + size = address - vma->vm_start; +@@ -1633,6 +1835,8 @@ int expand_upwards(struct vm_area_struct + if (!error) + vma->vm_end = address; + } ++ if (locknext) ++ anon_vma_unlock(vma->vm_next); + anon_vma_unlock(vma); + return error; + } +@@ -1644,7 +1848,8 @@ int expand_upwards(struct vm_area_struct + static int expand_downwards(struct vm_area_struct *vma, + unsigned long address) + { +- int error; ++ int error, lockprev = 0; ++ struct vm_area_struct *prev = NULL; + + /* + * We must make sure the anon_vma is allocated +@@ -1658,6 +1863,15 @@ static int expand_downwards(struct vm_ar + if (error) + return error; + ++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64) ++ find_vma_prev(vma->vm_mm, address, &prev); ++ lockprev = prev && (prev->vm_flags & VM_GROWSUP); ++#endif ++ if (lockprev && unlikely(anon_vma_prepare(prev))) ++ return -ENOMEM; ++ if (lockprev) ++ anon_vma_lock(prev); ++ + anon_vma_lock(vma); + + /* +@@ -1667,9 +1881,15 @@ static int expand_downwards(struct vm_ar + */ + + /* Somebody else might have raced and expanded it already */ +- if (address < vma->vm_start) { ++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) { + unsigned long size, grow; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m; ++ ++ vma_m = pax_find_mirror_vma(vma); ++#endif ++ + size = vma->vm_end - address; + grow = (vma->vm_start - address) >> PAGE_SHIFT; + +@@ -1677,9 +1897,20 @@ static int expand_downwards(struct vm_ar + if (!error) { + vma->vm_start = address; + vma->vm_pgoff -= grow; ++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (vma_m) { ++ vma_m->vm_start -= grow << PAGE_SHIFT; ++ vma_m->vm_pgoff -= grow; ++ } ++#endif ++ + } + } + anon_vma_unlock(vma); ++ if (lockprev) ++ anon_vma_unlock(prev); + return error; + } + +@@ -1755,6 +1986,13 @@ static void remove_vma_list(struct mm_st + do { + long nrpages = vma_pages(vma); + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) { ++ vma = remove_vma(vma); ++ continue; ++ } ++#endif ++ + mm->total_vm -= nrpages; + vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); + vma = remove_vma(vma); +@@ -1799,6 +2037,16 @@ detach_vmas_to_be_unmapped(struct mm_str + + insertion_point = (prev ? &prev->vm_next : &mm->mmap); + do { ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (vma->vm_mirror) { ++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma); ++ vma->vm_mirror->vm_mirror = NULL; ++ vma->vm_mirror->vm_flags &= ~VM_EXEC; ++ vma->vm_mirror = NULL; ++ } ++#endif ++ + rb_erase(&vma->vm_rb, &mm->mm_rb); + mm->map_count--; + tail_vma = vma; +@@ -1818,6 +2066,108 @@ detach_vmas_to_be_unmapped(struct mm_str + * Split a vma into two pieces at address 'addr', a new vma is allocated + * either for the first part or the tail. + */ ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, ++ unsigned long addr, int new_below) ++{ ++ struct mempolicy *pol; ++ struct vm_area_struct *new, *vma_m, *new_m = NULL; ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE; ++ ++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK)) ++ return -EINVAL; ++ ++ vma_m = pax_find_mirror_vma(vma); ++ if (vma_m) { ++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE); ++ if (mm->map_count >= sysctl_max_map_count-1) ++ return -ENOMEM; ++ } else if (mm->map_count >= sysctl_max_map_count) ++ return -ENOMEM; ++ ++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); ++ if (!new) ++ return -ENOMEM; ++ ++ if (vma_m) { ++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); ++ if (!new_m) { ++ kmem_cache_free(vm_area_cachep, new); ++ return -ENOMEM; ++ } ++ } ++ ++ /* most fields are the same, copy all, and then fixup */ ++ *new = *vma; ++ ++ if (new_below) ++ new->vm_end = addr; ++ else { ++ new->vm_start = addr; ++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT); ++ } ++ ++ if (vma_m) { ++ *new_m = *vma_m; ++ new_m->vm_mirror = new; ++ new->vm_mirror = new_m; ++ ++ if (new_below) ++ new_m->vm_end = addr_m; ++ else { ++ new_m->vm_start = addr_m; ++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT); ++ } ++ } ++ ++ pol = mpol_dup(vma_policy(vma)); ++ if (IS_ERR(pol)) { ++ if (new_m) ++ kmem_cache_free(vm_area_cachep, new_m); ++ kmem_cache_free(vm_area_cachep, new); ++ return PTR_ERR(pol); ++ } ++ vma_set_policy(new, pol); ++ ++ if (new->vm_file) { ++ get_file(new->vm_file); ++ if (vma->vm_flags & VM_EXECUTABLE) ++ added_exe_file_vma(mm); ++ } ++ ++ if (new->vm_ops && new->vm_ops->open) ++ new->vm_ops->open(new); ++ ++ if (new_below) ++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff + ++ ((addr - new->vm_start) >> PAGE_SHIFT), new); ++ else ++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); ++ ++ if (vma_m) { ++ mpol_get(pol); ++ vma_set_policy(new_m, pol); ++ ++ if (new_m->vm_file) { ++ get_file(new_m->vm_file); ++ if (vma_m->vm_flags & VM_EXECUTABLE) ++ added_exe_file_vma(mm); ++ } ++ ++ if (new_m->vm_ops && new_m->vm_ops->open) ++ new_m->vm_ops->open(new_m); ++ ++ if (new_below) ++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff + ++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m); ++ else ++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m); ++ } ++ ++ return 0; ++} ++#else + int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, + unsigned long addr, int new_below) + { +@@ -1869,17 +2219,37 @@ int split_vma(struct mm_struct * mm, str + + return 0; + } ++#endif + + /* Munmap is split into 2 main parts -- this part which finds + * what needs doing, and the areas themselves, which do the + * work. This now handles partial unmappings. + * Jeremy Fitzhardinge <jeremy@goop.org> + */ ++#ifdef CONFIG_PAX_SEGMEXEC + int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) + { ++ int ret = __do_munmap(mm, start, len); ++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC)) ++ return ret; ++ ++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len); ++} ++ ++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len) ++#else ++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) ++#endif ++{ + unsigned long end; + struct vm_area_struct *vma, *prev, *last; + ++ /* ++ * mm->mmap_sem is required to protect against another thread ++ * changing the mappings in case we sleep. ++ */ ++ verify_mm_writelocked(mm); ++ + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start) + return -EINVAL; + +@@ -1943,6 +2313,8 @@ int do_munmap(struct mm_struct *mm, unsi + /* Fix up all other VM information */ + remove_vma_list(mm, vma); + ++ track_exec_limit(mm, start, end, 0UL); ++ + return 0; + } + +@@ -1955,22 +2327,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, a + + profile_munmap(addr); + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)) ++ return -EINVAL; ++#endif ++ + down_write(&mm->mmap_sem); + ret = do_munmap(mm, addr, len); + up_write(&mm->mmap_sem); + return ret; + } + +-static inline void verify_mm_writelocked(struct mm_struct *mm) +-{ +-#ifdef CONFIG_DEBUG_VM +- if (unlikely(down_read_trylock(&mm->mmap_sem))) { +- WARN_ON(1); +- up_read(&mm->mmap_sem); +- } +-#endif +-} +- + /* + * this is really a simplified "do_mmap". it only handles + * anonymous maps. eventually we may be able to do some +@@ -1984,6 +2352,11 @@ unsigned long do_brk(unsigned long addr, + struct rb_node ** rb_link, * rb_parent; + pgoff_t pgoff = addr >> PAGE_SHIFT; + int error; ++ unsigned long charged; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m = NULL; ++#endif + + len = PAGE_ALIGN(len); + if (!len) +@@ -2001,19 +2374,34 @@ unsigned long do_brk(unsigned long addr, + + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; + ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { ++ flags &= ~VM_EXEC; ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if (mm->pax_flags & MF_PAX_MPROTECT) ++ flags &= ~VM_MAYEXEC; ++#endif ++ ++ } ++#endif ++ + error = arch_mmap_check(addr, len, flags); + if (error) + return error; + ++ charged = len >> PAGE_SHIFT; ++ + /* + * mlock MCL_FUTURE? + */ + if (mm->def_flags & VM_LOCKED) { + unsigned long locked, lock_limit; +- locked = len >> PAGE_SHIFT; ++ locked = charged; + locked += mm->locked_vm; + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit >>= PAGE_SHIFT; ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1); + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) + return -EAGAIN; + } +@@ -2027,22 +2415,22 @@ unsigned long do_brk(unsigned long addr, + /* + * Clear old maps. this also does some error checking for us + */ +- munmap_back: + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); + if (vma && vma->vm_start < addr + len) { + if (do_munmap(mm, addr, len)) + return -ENOMEM; +- goto munmap_back; ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); ++ BUG_ON(vma && vma->vm_start < addr + len); + } + + /* Check against address space limits *after* clearing old maps... */ +- if (!may_expand_vm(mm, len >> PAGE_SHIFT)) ++ if (!may_expand_vm(mm, charged)) + return -ENOMEM; + + if (mm->map_count > sysctl_max_map_count) + return -ENOMEM; + +- if (security_vm_enough_memory(len >> PAGE_SHIFT)) ++ if (security_vm_enough_memory(charged)) + return -ENOMEM; + + /* Can we just expand an old private anonymous mapping? */ +@@ -2056,10 +2444,21 @@ unsigned long do_brk(unsigned long addr, + */ + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); + if (!vma) { +- vm_unacct_memory(len >> PAGE_SHIFT); ++ vm_unacct_memory(charged); + return -ENOMEM; + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) { ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); ++ if (!vma_m) { ++ kmem_cache_free(vm_area_cachep, vma); ++ vm_unacct_memory(charged); ++ return -ENOMEM; ++ } ++ } ++#endif ++ + vma->vm_mm = mm; + vma->vm_start = addr; + vma->vm_end = addr + len; +@@ -2068,11 +2467,12 @@ unsigned long do_brk(unsigned long addr, + vma->vm_page_prot = vm_get_page_prot(flags); + vma_link(mm, vma, prev, rb_link, rb_parent); + out: +- mm->total_vm += len >> PAGE_SHIFT; ++ mm->total_vm += charged; + if (flags & VM_LOCKED) { + if (!mlock_vma_pages_range(vma, addr, addr + len)) +- mm->locked_vm += (len >> PAGE_SHIFT); ++ mm->locked_vm += charged; + } ++ track_exec_limit(mm, addr, addr + len, flags); + return addr; + } + +@@ -2118,8 +2518,10 @@ void exit_mmap(struct mm_struct *mm) + * Walk the list again, actually closing and freeing it, + * with preemption enabled, without holding any MM locks. + */ +- while (vma) ++ while (vma) { ++ vma->vm_mirror = NULL; + vma = remove_vma(vma); ++ } + + BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT); + } +@@ -2133,6 +2535,10 @@ int insert_vm_struct(struct mm_struct * + struct vm_area_struct * __vma, * prev; + struct rb_node ** rb_link, * rb_parent; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m = NULL; ++#endif ++ + /* + * The vm_pgoff of a purely anonymous vma should be irrelevant + * until its first write fault, when page's anon_vma and index +@@ -2155,7 +2561,22 @@ int insert_vm_struct(struct mm_struct * + if ((vma->vm_flags & VM_ACCOUNT) && + security_vm_enough_memory_mm(mm, vma_pages(vma))) + return -ENOMEM; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) { ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); ++ if (!vma_m) ++ return -ENOMEM; ++ } ++#endif ++ + vma_link(mm, vma, prev, rb_link, rb_parent); ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (vma_m) ++ pax_mirror_vma(vma_m, vma); ++#endif ++ + return 0; + } + +@@ -2173,6 +2594,8 @@ struct vm_area_struct *copy_vma(struct v + struct rb_node **rb_link, *rb_parent; + struct mempolicy *pol; + ++ BUG_ON(vma->vm_mirror); ++ + /* + * If anonymous vma has not yet been faulted, update new pgoff + * to match new location, to increase its chance of merging. +@@ -2216,6 +2639,35 @@ struct vm_area_struct *copy_vma(struct v + return new_vma; + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma) ++{ ++ struct vm_area_struct *prev_m; ++ struct rb_node **rb_link_m, *rb_parent_m; ++ struct mempolicy *pol_m; ++ ++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)); ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror); ++ BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m))); ++ *vma_m = *vma; ++ pol_m = vma_policy(vma_m); ++ mpol_get(pol_m); ++ vma_set_policy(vma_m, pol_m); ++ vma_m->vm_start += SEGMEXEC_TASK_SIZE; ++ vma_m->vm_end += SEGMEXEC_TASK_SIZE; ++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED); ++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags); ++ if (vma_m->vm_file) ++ get_file(vma_m->vm_file); ++ if (vma_m->vm_ops && vma_m->vm_ops->open) ++ vma_m->vm_ops->open(vma_m); ++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m); ++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m); ++ vma_m->vm_mirror = vma; ++ vma->vm_mirror = vma_m; ++} ++#endif ++ + /* + * Return true if the calling process may expand its vm space by the passed + * number of pages +@@ -2226,7 +2678,7 @@ int may_expand_vm(struct mm_struct *mm, + unsigned long lim; + + lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; +- ++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1); + if (cur + npages > lim) + return 0; + return 1; +@@ -2267,7 +2719,7 @@ static void special_mapping_close(struct + { + } + +-static struct vm_operations_struct special_mapping_vmops = { ++static const struct vm_operations_struct special_mapping_vmops = { + .close = special_mapping_close, + .fault = special_mapping_fault, + }; +@@ -2295,6 +2747,15 @@ int install_special_mapping(struct mm_st + vma->vm_start = addr; + vma->vm_end = addr + len; + ++#ifdef CONFIG_PAX_MPROTECT ++ if (mm->pax_flags & MF_PAX_MPROTECT) { ++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC) ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC); ++ else ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE); ++ } ++#endif ++ + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND; + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + +diff -urNp linux-2.6.31.1/mm/mprotect.c linux-2.6.31.1/mm/mprotect.c +--- linux-2.6.31.1/mm/mprotect.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/mprotect.c 2009-10-01 20:12:45.000000000 -0400 +@@ -24,10 +24,16 @@ + #include <linux/mmu_notifier.h> + #include <linux/migrate.h> + #include <linux/perf_counter.h> ++ ++#ifdef CONFIG_PAX_MPROTECT ++#include <linux/elf.h> ++#endif ++ + #include <asm/uaccess.h> + #include <asm/pgtable.h> + #include <asm/cacheflush.h> + #include <asm/tlbflush.h> ++#include <asm/mmu_context.h> + + #ifndef pgprot_modify + static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) +@@ -132,6 +138,48 @@ static void change_protection(struct vm_ + flush_tlb_range(vma, start, end); + } + ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT ++/* called while holding the mmap semaphor for writing except stack expansion */ ++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) ++{ ++ unsigned long oldlimit, newlimit = 0UL; ++ ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled) ++ return; ++ ++ spin_lock(&mm->page_table_lock); ++ oldlimit = mm->context.user_cs_limit; ++ if ((prot & VM_EXEC) && oldlimit < end) ++ /* USER_CS limit moved up */ ++ newlimit = end; ++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end) ++ /* USER_CS limit moved down */ ++ newlimit = start; ++ ++ if (newlimit) { ++ mm->context.user_cs_limit = newlimit; ++ ++#ifdef CONFIG_SMP ++ wmb(); ++ cpus_clear(mm->context.cpu_user_cs_mask); ++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask); ++#endif ++ ++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id()); ++ } ++ spin_unlock(&mm->page_table_lock); ++ if (newlimit == end) { ++ struct vm_area_struct *vma = find_vma(mm, oldlimit); ++ ++ for (; vma && vma->vm_start < end; vma = vma->vm_next) ++ if (is_vm_hugetlb_page(vma)) ++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot); ++ else ++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma)); ++ } ++} ++#endif ++ + int + mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, + unsigned long start, unsigned long end, unsigned long newflags) +@@ -144,6 +192,14 @@ mprotect_fixup(struct vm_area_struct *vm + int error; + int dirty_accountable = 0; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m = NULL; ++ unsigned long start_m, end_m; ++ ++ start_m = start + SEGMEXEC_TASK_SIZE; ++ end_m = end + SEGMEXEC_TASK_SIZE; ++#endif ++ + if (newflags == oldflags) { + *pprev = vma; + return 0; +@@ -165,6 +221,38 @@ mprotect_fixup(struct vm_area_struct *vm + } + } + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) { ++ if (start != vma->vm_start) { ++ error = split_vma(mm, vma, start, 1); ++ if (error) ++ goto fail; ++ BUG_ON(!*pprev || (*pprev)->vm_next == vma); ++ *pprev = (*pprev)->vm_next; ++ } ++ ++ if (end != vma->vm_end) { ++ error = split_vma(mm, vma, end, 0); ++ if (error) ++ goto fail; ++ } ++ ++ if (pax_find_mirror_vma(vma)) { ++ error = __do_munmap(mm, start_m, end_m - start_m); ++ if (error) ++ goto fail; ++ } else { ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); ++ if (!vma_m) { ++ error = -ENOMEM; ++ goto fail; ++ } ++ vma->vm_flags = newflags; ++ pax_mirror_vma(vma_m, vma); ++ } ++ } ++#endif ++ + /* + * First try to merge with previous and/or next vma. + */ +@@ -196,8 +284,14 @@ success: + * held in write mode. + */ + vma->vm_flags = newflags; ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if (current->binfmt && current->binfmt->handle_mprotect) ++ current->binfmt->handle_mprotect(vma, newflags); ++#endif ++ + vma->vm_page_prot = pgprot_modify(vma->vm_page_prot, +- vm_get_page_prot(newflags)); ++ vm_get_page_prot(vma->vm_flags)); + + if (vma_wants_writenotify(vma)) { + vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED); +@@ -238,6 +332,17 @@ SYSCALL_DEFINE3(mprotect, unsigned long, + end = start + len; + if (end <= start) + return -ENOMEM; ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { ++ if (end > SEGMEXEC_TASK_SIZE) ++ return -EINVAL; ++ } else ++#endif ++ ++ if (end > TASK_SIZE) ++ return -EINVAL; ++ + if (!arch_validate_prot(prot)) + return -EINVAL; + +@@ -245,7 +350,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long, + /* + * Does the application expect PROT_READ to imply PROT_EXEC: + */ +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC)) + prot |= PROT_EXEC; + + vm_flags = calc_vm_prot_bits(prot); +@@ -277,6 +382,16 @@ SYSCALL_DEFINE3(mprotect, unsigned long, + if (start > vma->vm_start) + prev = vma; + ++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) { ++ error = -EACCES; ++ goto out; ++ } ++ ++#ifdef CONFIG_PAX_MPROTECT ++ if (current->binfmt && current->binfmt->handle_mprotect) ++ current->binfmt->handle_mprotect(vma, vm_flags); ++#endif ++ + for (nstart = start ; ; ) { + unsigned long newflags; + +@@ -301,6 +416,9 @@ SYSCALL_DEFINE3(mprotect, unsigned long, + if (error) + goto out; + perf_counter_mmap(vma); ++ ++ track_exec_limit(current->mm, nstart, tmp, vm_flags); ++ + nstart = tmp; + + if (nstart < prev->vm_end) +diff -urNp linux-2.6.31.1/mm/mremap.c linux-2.6.31.1/mm/mremap.c +--- linux-2.6.31.1/mm/mremap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/mremap.c 2009-10-01 20:12:45.000000000 -0400 +@@ -113,6 +113,12 @@ static void move_ptes(struct vm_area_str + continue; + pte = ptep_clear_flush(vma, old_addr, old_pte); + pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr); ++ ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT ++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC) ++ pte = pte_exprotect(pte); ++#endif ++ + set_pte_at(mm, new_addr, new_pte, pte); + } + +@@ -262,6 +268,7 @@ unsigned long do_mremap(unsigned long ad + struct vm_area_struct *vma; + unsigned long ret = -EINVAL; + unsigned long charged = 0; ++ unsigned long pax_task_size = TASK_SIZE; + + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) + goto out; +@@ -280,6 +287,15 @@ unsigned long do_mremap(unsigned long ad + if (!new_len) + goto out; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) ++ pax_task_size = SEGMEXEC_TASK_SIZE; ++#endif ++ ++ if (new_len > pax_task_size || addr > pax_task_size-new_len || ++ old_len > pax_task_size || addr > pax_task_size-old_len) ++ goto out; ++ + /* new_addr is only valid if MREMAP_FIXED is specified */ + if (flags & MREMAP_FIXED) { + if (new_addr & ~PAGE_MASK) +@@ -287,16 +303,13 @@ unsigned long do_mremap(unsigned long ad + if (!(flags & MREMAP_MAYMOVE)) + goto out; + +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len) ++ if (new_addr > pax_task_size - new_len) + goto out; + + /* Check if the location we're moving into overlaps the + * old location at all, and fail if it does. + */ +- if ((new_addr <= addr) && (new_addr+new_len) > addr) +- goto out; +- +- if ((addr <= new_addr) && (addr+old_len) > new_addr) ++ if (addr + old_len > new_addr && new_addr + new_len > addr) + goto out; + + ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); +@@ -334,6 +347,14 @@ unsigned long do_mremap(unsigned long ad + ret = -EINVAL; + goto out; + } ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ if (pax_find_mirror_vma(vma)) { ++ ret = -EINVAL; ++ goto out; ++ } ++#endif ++ + /* We can't remap across vm area boundaries */ + if (old_len > vma->vm_end - addr) + goto out; +@@ -367,7 +388,7 @@ unsigned long do_mremap(unsigned long ad + if (old_len == vma->vm_end - addr && + !((flags & MREMAP_FIXED) && (addr != new_addr)) && + (old_len != new_len || !(flags & MREMAP_MAYMOVE))) { +- unsigned long max_addr = TASK_SIZE; ++ unsigned long max_addr = pax_task_size; + if (vma->vm_next) + max_addr = vma->vm_next->vm_start; + /* can we just expand the current mapping? */ +@@ -385,6 +406,7 @@ unsigned long do_mremap(unsigned long ad + addr + new_len); + } + ret = addr; ++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags); + goto out; + } + } +@@ -395,8 +417,8 @@ unsigned long do_mremap(unsigned long ad + */ + ret = -ENOMEM; + if (flags & MREMAP_MAYMOVE) { ++ unsigned long map_flags = 0; + if (!(flags & MREMAP_FIXED)) { +- unsigned long map_flags = 0; + if (vma->vm_flags & VM_MAYSHARE) + map_flags |= MAP_SHARED; + +@@ -411,7 +433,12 @@ unsigned long do_mremap(unsigned long ad + if (ret) + goto out; + } ++ map_flags = vma->vm_flags; + ret = move_vma(vma, addr, old_len, new_len, new_addr); ++ if (!(ret & ~PAGE_MASK)) { ++ track_exec_limit(current->mm, addr, addr + old_len, 0UL); ++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags); ++ } + } + out: + if (ret & ~PAGE_MASK) +diff -urNp linux-2.6.31.1/mm/nommu.c linux-2.6.31.1/mm/nommu.c +--- linux-2.6.31.1/mm/nommu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/nommu.c 2009-10-01 20:12:45.000000000 -0400 +@@ -79,7 +79,7 @@ static struct kmem_cache *vm_region_jar; + struct rb_root nommu_region_tree = RB_ROOT; + DECLARE_RWSEM(nommu_region_sem); + +-struct vm_operations_struct generic_file_vm_ops = { ++const struct vm_operations_struct generic_file_vm_ops = { + }; + + /* +@@ -780,15 +780,6 @@ struct vm_area_struct *find_vma(struct m + EXPORT_SYMBOL(find_vma); + + /* +- * find a VMA +- * - we don't extend stack VMAs under NOMMU conditions +- */ +-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr) +-{ +- return find_vma(mm, addr); +-} +- +-/* + * expand a stack to a given address + * - not supported under NOMMU conditions + */ +diff -urNp linux-2.6.31.1/mm/page_alloc.c linux-2.6.31.1/mm/page_alloc.c +--- linux-2.6.31.1/mm/page_alloc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/page_alloc.c 2009-10-01 20:12:45.000000000 -0400 +@@ -559,6 +559,10 @@ static void __free_pages_ok(struct page + int bad = 0; + int wasMlocked = TestClearPageMlocked(page); + ++#ifdef CONFIG_PAX_MEMORY_SANITIZE ++ unsigned long index = 1UL << order; ++#endif ++ + kmemcheck_free_shadow(page, order); + + for (i = 0 ; i < (1 << order) ; ++i) +@@ -571,6 +575,12 @@ static void __free_pages_ok(struct page + debug_check_no_obj_freed(page_address(page), + PAGE_SIZE << order); + } ++ ++#ifdef CONFIG_PAX_MEMORY_SANITIZE ++ for (; index; --index) ++ sanitize_highpage(page + index - 1); ++#endif ++ + arch_free_page(page, order); + kernel_map_pages(page, 1 << order, 0); + +@@ -662,8 +672,10 @@ static int prep_new_page(struct page *pa + arch_alloc_page(page, order); + kernel_map_pages(page, 1 << order, 1); + ++#ifndef CONFIG_PAX_MEMORY_SANITIZE + if (gfp_flags & __GFP_ZERO) + prep_zero_page(page, order, gfp_flags); ++#endif + + if (order && (gfp_flags & __GFP_COMP)) + prep_compound_page(page, order); +@@ -1039,6 +1051,11 @@ static void free_hot_cold_page(struct pa + debug_check_no_locks_freed(page_address(page), PAGE_SIZE); + debug_check_no_obj_freed(page_address(page), PAGE_SIZE); + } ++ ++#ifdef CONFIG_PAX_MEMORY_SANITIZE ++ sanitize_highpage(page); ++#endif ++ + arch_free_page(page, 0); + kernel_map_pages(page, 1, 0); + +diff -urNp linux-2.6.31.1/mm/percpu.c linux-2.6.31.1/mm/percpu.c +--- linux-2.6.31.1/mm/percpu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/percpu.c 2009-10-01 20:12:45.000000000 -0400 +@@ -105,7 +105,7 @@ static int pcpu_nr_slots __read_mostly; + static size_t pcpu_chunk_struct_size __read_mostly; + + /* the address of the first chunk which starts with the kernel static area */ +-void *pcpu_base_addr __read_mostly; ++void *pcpu_base_addr __read_only; + EXPORT_SYMBOL_GPL(pcpu_base_addr); + + /* +diff -urNp linux-2.6.31.1/mm/rmap.c linux-2.6.31.1/mm/rmap.c +--- linux-2.6.31.1/mm/rmap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/rmap.c 2009-10-01 20:12:45.000000000 -0400 +@@ -103,6 +103,10 @@ int anon_vma_prepare(struct vm_area_stru + struct mm_struct *mm = vma->vm_mm; + struct anon_vma *allocated; + ++#ifdef CONFIG_PAX_SEGMEXEC ++ struct vm_area_struct *vma_m; ++#endif ++ + anon_vma = find_mergeable_anon_vma(vma); + allocated = NULL; + if (!anon_vma) { +@@ -116,6 +120,15 @@ int anon_vma_prepare(struct vm_area_stru + /* page_table_lock to protect against threads */ + spin_lock(&mm->page_table_lock); + if (likely(!vma->anon_vma)) { ++ ++#ifdef CONFIG_PAX_SEGMEXEC ++ vma_m = pax_find_mirror_vma(vma); ++ if (vma_m) { ++ vma_m->anon_vma = anon_vma; ++ __anon_vma_link(vma_m); ++ } ++#endif ++ + vma->anon_vma = anon_vma; + list_add_tail(&vma->anon_vma_node, &anon_vma->head); + allocated = NULL; +diff -urNp linux-2.6.31.1/mm/shmem.c linux-2.6.31.1/mm/shmem.c +--- linux-2.6.31.1/mm/shmem.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/shmem.c 2009-10-01 20:12:45.000000000 -0400 +@@ -31,7 +31,7 @@ + #include <linux/swap.h> + #include <linux/ima.h> + +-static struct vfsmount *shm_mnt; ++struct vfsmount *shm_mnt; + + #ifdef CONFIG_SHMEM + /* +@@ -219,7 +219,7 @@ static const struct file_operations shme + static const struct inode_operations shmem_inode_operations; + static const struct inode_operations shmem_dir_inode_operations; + static const struct inode_operations shmem_special_inode_operations; +-static struct vm_operations_struct shmem_vm_ops; ++static const struct vm_operations_struct shmem_vm_ops; + + static struct backing_dev_info shmem_backing_dev_info __read_mostly = { + .ra_pages = 0, /* No readahead */ +@@ -2497,7 +2497,7 @@ static const struct super_operations shm + .put_super = shmem_put_super, + }; + +-static struct vm_operations_struct shmem_vm_ops = { ++static const struct vm_operations_struct shmem_vm_ops = { + .fault = shmem_fault, + #ifdef CONFIG_NUMA + .set_policy = shmem_set_policy, +diff -urNp linux-2.6.31.1/mm/slab.c linux-2.6.31.1/mm/slab.c +--- linux-2.6.31.1/mm/slab.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/slab.c 2009-10-01 20:12:45.000000000 -0400 +@@ -308,7 +308,7 @@ struct kmem_list3 { + * Need this for bootstrapping a per node allocator. + */ + #define NUM_INIT_LISTS (3 * MAX_NUMNODES) +-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS]; ++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS]; + #define CACHE_CACHE 0 + #define SIZE_AC MAX_NUMNODES + #define SIZE_L3 (2 * MAX_NUMNODES) +@@ -558,7 +558,7 @@ static inline void *index_to_obj(struct + * reciprocal_divide(offset, cache->reciprocal_buffer_size) + */ + static inline unsigned int obj_to_index(const struct kmem_cache *cache, +- const struct slab *slab, void *obj) ++ const struct slab *slab, const void *obj) + { + u32 offset = (obj - slab->s_mem); + return reciprocal_divide(offset, cache->reciprocal_buffer_size); +@@ -584,14 +584,14 @@ struct cache_names { + static struct cache_names __initdata cache_names[] = { + #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" }, + #include <linux/kmalloc_sizes.h> +- {NULL,} ++ {NULL, NULL} + #undef CACHE + }; + + static struct arraycache_init initarray_cache __initdata = +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} }; ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} }; + static struct arraycache_init initarray_generic = +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} }; ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} }; + + /* internal cache of cache description objs */ + static struct kmem_cache cache_cache = { +@@ -4473,15 +4473,64 @@ static const struct file_operations proc + + static int __init slab_proc_init(void) + { ++#if !defined(CONFIG_GRKERNSEC_PROC_ADD) + proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations); + #ifdef CONFIG_DEBUG_SLAB_LEAK + proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations); + #endif ++#endif + return 0; + } + module_init(slab_proc_init); + #endif + ++void check_object_size(const void *ptr, unsigned long n, bool to) ++{ ++ ++#ifdef CONFIG_PAX_USERCOPY ++ struct kmem_cache *cachep; ++ struct slab *slabp; ++ struct page *page; ++ unsigned int objnr; ++ unsigned long offset; ++ ++ if (!n) ++ return; ++ ++ if (ZERO_OR_NULL_PTR(ptr)) ++ goto report; ++ ++ if (!virt_addr_valid(ptr)) ++ return; ++ ++ page = virt_to_head_page(ptr); ++ ++ /* XXX: can get a little tighter with this stack check */ ++ if (!PageSlab(page) && object_is_on_stack(ptr) && ++ (n > ((unsigned long)task_stack_page(current) + THREAD_SIZE - ++ (unsigned long)ptr))) ++ goto report; ++ else ++ return; ++ ++ cachep = page_get_cache(page); ++ slabp = page_get_slab(page); ++ objnr = obj_to_index(cachep, slabp, ptr); ++ BUG_ON(objnr >= cachep->num); ++ offset = ptr - index_to_obj(cachep, slabp, objnr) - obj_offset(cachep); ++ if (offset <= obj_size(cachep) && n <= obj_size(cachep) - offset) ++ return; ++ ++report: ++ if (to) ++ pax_report_leak_to_user(ptr, n); ++ else ++ pax_report_overflow_from_user(ptr, n); ++#endif ++ ++} ++EXPORT_SYMBOL(check_object_size); ++ + /** + * ksize - get the actual amount of memory allocated for a given object + * @objp: Pointer to the object +diff -urNp linux-2.6.31.1/mm/slob.c linux-2.6.31.1/mm/slob.c +--- linux-2.6.31.1/mm/slob.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/slob.c 2009-10-01 20:12:45.000000000 -0400 +@@ -29,7 +29,7 @@ + * If kmalloc is asked for objects of PAGE_SIZE or larger, it calls + * alloc_pages() directly, allocating compound pages so the page order + * does not have to be separately tracked, and also stores the exact +- * allocation size in page->private so that it can be used to accurately ++ * allocation size in slob_page->size so that it can be used to accurately + * provide ksize(). These objects are detected in kfree() because slob_page() + * is false for them. + * +@@ -58,6 +58,7 @@ + */ + + #include <linux/kernel.h> ++#include <linux/sched.h> + #include <linux/slab.h> + #include <linux/mm.h> + #include <linux/swap.h> /* struct reclaim_state */ +@@ -100,7 +101,8 @@ struct slob_page { + unsigned long flags; /* mandatory */ + atomic_t _count; /* mandatory */ + slobidx_t units; /* free units left in page */ +- unsigned long pad[2]; ++ unsigned long pad[1]; ++ unsigned long size; /* size when >=PAGE_SIZE */ + slob_t *free; /* first free slob_t in page */ + struct list_head list; /* linked list of free pages */ + }; +@@ -133,7 +135,7 @@ static LIST_HEAD(free_slob_large); + */ + static inline int is_slob_page(struct slob_page *sp) + { +- return PageSlab((struct page *)sp); ++ return PageSlab((struct page *)sp) && !sp->size; + } + + static inline void set_slob_page(struct slob_page *sp) +@@ -148,7 +150,7 @@ static inline void clear_slob_page(struc + + static inline struct slob_page *slob_page(const void *addr) + { +- return (struct slob_page *)virt_to_page(addr); ++ return (struct slob_page *)virt_to_head_page(addr); + } + + /* +@@ -208,7 +210,7 @@ static void set_slob(slob_t *s, slobidx_ + /* + * Return the size of a slob block. + */ +-static slobidx_t slob_units(slob_t *s) ++static slobidx_t slob_units(const slob_t *s) + { + if (s->units > 0) + return s->units; +@@ -218,7 +220,7 @@ static slobidx_t slob_units(slob_t *s) + /* + * Return the next free slob block pointer after this one. + */ +-static slob_t *slob_next(slob_t *s) ++static slob_t *slob_next(const slob_t *s) + { + slob_t *base = (slob_t *)((unsigned long)s & PAGE_MASK); + slobidx_t next; +@@ -233,7 +235,7 @@ static slob_t *slob_next(slob_t *s) + /* + * Returns true if s is the last free block in its page. + */ +-static int slob_last(slob_t *s) ++static int slob_last(const slob_t *s) + { + return !((unsigned long)slob_next(s) & ~PAGE_MASK); + } +@@ -252,6 +254,7 @@ static void *slob_new_pages(gfp_t gfp, i + if (!page) + return NULL; + ++ set_slob_page(page); + return page_address(page); + } + +@@ -368,11 +371,11 @@ static void *slob_alloc(size_t size, gfp + if (!b) + return NULL; + sp = slob_page(b); +- set_slob_page(sp); + + spin_lock_irqsave(&slob_lock, flags); + sp->units = SLOB_UNITS(PAGE_SIZE); + sp->free = b; ++ sp->size = 0; + INIT_LIST_HEAD(&sp->list); + set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE)); + set_slob_page_free(sp, slob_list); +@@ -475,10 +478,9 @@ out: + #define ARCH_SLAB_MINALIGN __alignof__(unsigned long) + #endif + +-void *__kmalloc_node(size_t size, gfp_t gfp, int node) ++static void *__kmalloc_node_align(size_t size, gfp_t gfp, int node, int align) + { +- unsigned int *m; +- int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); ++ slob_t *m; + void *ret; + + lockdep_trace_alloc(gfp); +@@ -491,7 +493,10 @@ void *__kmalloc_node(size_t size, gfp_t + + if (!m) + return NULL; +- *m = size; ++ BUILD_BUG_ON(ARCH_KMALLOC_MINALIGN < 2 * SLOB_UNIT); ++ BUILD_BUG_ON(ARCH_SLAB_MINALIGN < 2 * SLOB_UNIT); ++ m[0].units = size; ++ m[1].units = align; + ret = (void *)m + align; + + trace_kmalloc_node(_RET_IP_, ret, +@@ -501,9 +506,9 @@ void *__kmalloc_node(size_t size, gfp_t + + ret = slob_new_pages(gfp | __GFP_COMP, get_order(size), node); + if (ret) { +- struct page *page; +- page = virt_to_page(ret); +- page->private = size; ++ struct slob_page *sp; ++ sp = slob_page(ret); ++ sp->size = size; + } + + trace_kmalloc_node(_RET_IP_, ret, +@@ -513,6 +518,13 @@ void *__kmalloc_node(size_t size, gfp_t + kmemleak_alloc(ret, size, 1, gfp); + return ret; + } ++ ++void *__kmalloc_node(size_t size, gfp_t gfp, int node) ++{ ++ int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); ++ ++ return __kmalloc_node_align(size, gfp, node, align); ++} + EXPORT_SYMBOL(__kmalloc_node); + + void kfree(const void *block) +@@ -528,13 +540,86 @@ void kfree(const void *block) + sp = slob_page(block); + if (is_slob_page(sp)) { + int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); +- unsigned int *m = (unsigned int *)(block - align); +- slob_free(m, *m + align); +- } else ++ slob_t *m = (slob_t *)(block - align); ++ slob_free(m, m[0].units + align); ++ } else { ++ clear_slob_page(sp); ++ free_slob_page(sp); ++ sp->size = 0; + put_page(&sp->page); ++ } + } + EXPORT_SYMBOL(kfree); + ++void check_object_size(const void *ptr, unsigned long n, bool to) ++{ ++ ++#ifdef CONFIG_PAX_USERCOPY ++ struct slob_page *sp; ++ const slob_t *free; ++ const void *base; ++ ++ if (!n) ++ return; ++ ++ if (ZERO_OR_NULL_PTR(ptr)) ++ goto report; ++ ++ if (!virt_addr_valid(ptr)) ++ return; ++ ++ sp = slob_page(ptr); ++ /* XXX: can get a little tighter with this stack check */ ++ if (!PageSlobPage((struct page*)sp) && object_is_on_stack(ptr) && ++ (n > ((unsigned long)task_stack_page(current) + THREAD_SIZE - ++ (unsigned long)ptr))) ++ goto report; ++ else ++ return; ++ ++ if (sp->size) { ++ base = page_address(&sp->page); ++ if (base <= ptr && n <= sp->size - (ptr - base)) ++ return; ++ goto report; ++ } ++ ++ /* some tricky double walking to find the chunk */ ++ base = (void *)((unsigned long)ptr & PAGE_MASK); ++ free = sp->free; ++ ++ while (!slob_last(free) && (void *)free <= ptr) { ++ base = free + slob_units(free); ++ free = slob_next(free); ++ } ++ ++ while (base < (void *)free) { ++ slobidx_t m = ((slob_t *)base)[0].units, align = ((slob_t *)base)[1].units; ++ int size = SLOB_UNIT * SLOB_UNITS(m + align); ++ int offset; ++ ++ if (ptr < base + align) ++ goto report; ++ ++ offset = ptr - base - align; ++ if (offset < m) { ++ if (n <= m - offset) ++ return; ++ goto report; ++ } ++ base += size; ++ } ++ ++report: ++ if (to) ++ pax_report_leak_to_user(ptr, n); ++ else ++ pax_report_overflow_from_user(ptr, n); ++#endif ++ ++} ++EXPORT_SYMBOL(check_object_size); ++ + /* can't use ksize for kmem_cache_alloc memory, only kmalloc */ + size_t ksize(const void *block) + { +@@ -547,10 +632,10 @@ size_t ksize(const void *block) + sp = slob_page(block); + if (is_slob_page(sp)) { + int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); +- unsigned int *m = (unsigned int *)(block - align); +- return SLOB_UNITS(*m) * SLOB_UNIT; ++ slob_t *m = (slob_t *)(block - align); ++ return SLOB_UNITS(m[0].units) * SLOB_UNIT; + } else +- return sp->page.private; ++ return sp->size; + } + EXPORT_SYMBOL(ksize); + +@@ -605,17 +690,25 @@ void *kmem_cache_alloc_node(struct kmem_ + { + void *b; + ++#ifdef CONFIG_PAX_USERCOPY ++ b = __kmalloc_node_align(c->size, flags, node, c->align); ++#else + if (c->size < PAGE_SIZE) { + b = slob_alloc(c->size, flags, c->align, node); + trace_kmem_cache_alloc_node(_RET_IP_, b, c->size, + SLOB_UNITS(c->size) * SLOB_UNIT, + flags, node); + } else { ++ struct slob_page *sp; ++ + b = slob_new_pages(flags, get_order(c->size), node); ++ sp = slob_page(b); ++ sp->size = c->size; + trace_kmem_cache_alloc_node(_RET_IP_, b, c->size, + PAGE_SIZE << get_order(c->size), + flags, node); + } ++#endif + + if (c->ctor) + c->ctor(b); +@@ -627,10 +720,16 @@ EXPORT_SYMBOL(kmem_cache_alloc_node); + + static void __kmem_cache_free(void *b, int size) + { +- if (size < PAGE_SIZE) ++ struct slob_page *sp = slob_page(b); ++ ++ if (is_slob_page(sp)) + slob_free(b, size); +- else ++ else { ++ clear_slob_page(sp); ++ free_slob_page(sp); ++ sp->size = 0; + slob_free_pages(b, get_order(size)); ++ } + } + + static void kmem_rcu_free(struct rcu_head *head) +@@ -643,15 +742,24 @@ static void kmem_rcu_free(struct rcu_hea + + void kmem_cache_free(struct kmem_cache *c, void *b) + { ++ int size = c->size; ++ ++#ifdef CONFIG_PAX_USERCOPY ++ if (size + c->align < PAGE_SIZE) { ++ size += c->align; ++ b -= c->align; ++ } ++#endif ++ + kmemleak_free_recursive(b, c->flags); + if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) { + struct slob_rcu *slob_rcu; +- slob_rcu = b + (c->size - sizeof(struct slob_rcu)); ++ slob_rcu = b + (size - sizeof(struct slob_rcu)); + INIT_RCU_HEAD(&slob_rcu->head); +- slob_rcu->size = c->size; ++ slob_rcu->size = size; + call_rcu(&slob_rcu->head, kmem_rcu_free); + } else { +- __kmem_cache_free(b, c->size); ++ __kmem_cache_free(b, size); + } + + trace_kmem_cache_free(_RET_IP_, b); +diff -urNp linux-2.6.31.1/mm/slub.c linux-2.6.31.1/mm/slub.c +--- linux-2.6.31.1/mm/slub.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/slub.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1915,7 +1915,7 @@ static int slub_min_objects; + * Merge control. If this is set then no merging of slab caches will occur. + * (Could be removed. This was introduced to pacify the merge skeptics.) + */ +-static int slub_nomerge; ++static int slub_nomerge = 1; + + /* + * Calculate the order of allocation given an slab object size. +@@ -2458,7 +2458,7 @@ static int kmem_cache_open(struct kmem_c + * list to avoid pounding the page allocator excessively. + */ + set_min_partial(s, ilog2(s->size)); +- s->refcount = 1; ++ atomic_set(&s->refcount, 1); + #ifdef CONFIG_NUMA + s->remote_node_defrag_ratio = 1000; + #endif +@@ -2595,8 +2595,7 @@ static inline int kmem_cache_close(struc + void kmem_cache_destroy(struct kmem_cache *s) + { + down_write(&slub_lock); +- s->refcount--; +- if (!s->refcount) { ++ if (atomic_dec_and_test(&s->refcount)) { + list_del(&s->list); + up_write(&slub_lock); + if (kmem_cache_close(s)) { +@@ -2875,6 +2874,48 @@ void *__kmalloc_node(size_t size, gfp_t + EXPORT_SYMBOL(__kmalloc_node); + #endif + ++void check_object_size(const void *ptr, unsigned long n, bool to) ++{ ++ ++#ifdef CONFIG_PAX_USERCOPY ++ struct page *page; ++ struct kmem_cache *s; ++ unsigned long offset; ++ ++ if (!n) ++ return; ++ ++ if (ZERO_OR_NULL_PTR(ptr)) ++ goto report; ++ ++ if (!virt_addr_valid(ptr)) ++ return; ++ ++ page = get_object_page(ptr); ++ ++ /* XXX: can get a little tighter with this stack check */ ++ if (!page && object_is_on_stack(ptr) && ++ (n > ((unsigned long)task_stack_page(current) + THREAD_SIZE - ++ (unsigned long)ptr))) ++ goto report; ++ else ++ return; ++ ++ s = page->slab; ++ offset = (ptr - page_address(page)) % s->size; ++ if (offset <= s->objsize && n <= s->objsize - offset) ++ return; ++ ++report: ++ if (to) ++ pax_report_leak_to_user(ptr, n); ++ else ++ pax_report_overflow_from_user(ptr, n); ++#endif ++ ++} ++EXPORT_SYMBOL(check_object_size); ++ + size_t ksize(const void *object) + { + struct page *page; +@@ -3146,7 +3187,7 @@ void __init kmem_cache_init(void) + */ + create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node", + sizeof(struct kmem_cache_node), GFP_NOWAIT); +- kmalloc_caches[0].refcount = -1; ++ atomic_set(&kmalloc_caches[0].refcount, -1); + caches++; + + hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI); +@@ -3240,7 +3281,7 @@ static int slab_unmergeable(struct kmem_ + /* + * We may have set a slab to be unmergeable during bootstrap. + */ +- if (s->refcount < 0) ++ if (atomic_read(&s->refcount) < 0) + return 1; + + return 0; +@@ -3297,7 +3338,7 @@ struct kmem_cache *kmem_cache_create(con + if (s) { + int cpu; + +- s->refcount++; ++ atomic_inc(&s->refcount); + /* + * Adjust the object sizes so that we clear + * the complete object on kzalloc. +@@ -3316,7 +3357,7 @@ struct kmem_cache *kmem_cache_create(con + + if (sysfs_slab_alias(s, name)) { + down_write(&slub_lock); +- s->refcount--; ++ atomic_dec(&s->refcount); + up_write(&slub_lock); + goto err; + } +@@ -4045,7 +4086,7 @@ SLAB_ATTR_RO(ctor); + + static ssize_t aliases_show(struct kmem_cache *s, char *buf) + { +- return sprintf(buf, "%d\n", s->refcount - 1); ++ return sprintf(buf, "%d\n", atomic_read(&s->refcount) - 1); + } + SLAB_ATTR_RO(aliases); + +@@ -4726,7 +4767,9 @@ static const struct file_operations proc + + static int __init slab_proc_init(void) + { ++#if !defined(CONFIG_GRKERNSEC_PROC_ADD) + proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations); ++#endif + return 0; + } + module_init(slab_proc_init); +diff -urNp linux-2.6.31.1/mm/util.c linux-2.6.31.1/mm/util.c +--- linux-2.6.31.1/mm/util.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/util.c 2009-10-01 20:12:45.000000000 -0400 +@@ -224,6 +224,12 @@ EXPORT_SYMBOL(strndup_user); + void arch_pick_mmap_layout(struct mm_struct *mm) + { + mm->mmap_base = TASK_UNMAPPED_BASE; ++ ++#ifdef CONFIG_PAX_RANDMMAP ++ if (mm->pax_flags & MF_PAX_RANDMMAP) ++ mm->mmap_base += mm->delta_mmap; ++#endif ++ + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; + } +diff -urNp linux-2.6.31.1/mm/vmalloc.c linux-2.6.31.1/mm/vmalloc.c +--- linux-2.6.31.1/mm/vmalloc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/mm/vmalloc.c 2009-10-01 20:12:45.000000000 -0400 +@@ -91,6 +91,11 @@ static int vmap_pte_range(pmd_t *pmd, un + unsigned long end, pgprot_t prot, struct page **pages, int *nr) + { + pte_t *pte; ++ int ret = -ENOMEM; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ unsigned long cr0; ++#endif + + /* + * nr is a running index into the array which helps higher level +@@ -100,17 +105,33 @@ static int vmap_pte_range(pmd_t *pmd, un + pte = pte_alloc_kernel(pmd, addr); + if (!pte) + return -ENOMEM; ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_open_kernel(cr0); ++#endif ++ + do { + struct page *page = pages[*nr]; + +- if (WARN_ON(!pte_none(*pte))) +- return -EBUSY; +- if (WARN_ON(!page)) +- return -ENOMEM; ++ if (WARN_ON(!pte_none(*pte))) { ++ ret = -EBUSY; ++ goto out; ++ } ++ if (WARN_ON(!page)) { ++ ret = -ENOMEM; ++ goto out; ++ } + set_pte_at(&init_mm, addr, pte, mk_pte(page, prot)); + (*nr)++; + } while (pte++, addr += PAGE_SIZE, addr != end); +- return 0; ++ ret = 0; ++out: ++ ++#ifdef CONFIG_PAX_KERNEXEC ++ pax_close_kernel(cr0); ++#endif ++ ++ return ret; + } + + static int vmap_pmd_range(pud_t *pud, unsigned long addr, +@@ -1132,6 +1153,16 @@ static struct vm_struct *__get_vm_area_n + unsigned long align = 1; + + BUG_ON(in_interrupt()); ++ ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++ if (flags & VM_KERNEXEC) { ++ if (start != VMALLOC_START || end != VMALLOC_END) ++ return NULL; ++ start = (unsigned long)&MODULES_EXEC_VADDR; ++ end = (unsigned long)&MODULES_EXEC_END; ++ } ++#endif ++ + if (flags & VM_IOREMAP) { + int bit = fls(size); + +@@ -1371,6 +1402,11 @@ void *vmap(struct page **pages, unsigned + if (count > num_physpages) + return NULL; + ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++ if (!(pgprot_val(prot) & _PAGE_NX)) ++ flags |= VM_KERNEXEC; ++#endif ++ + area = get_vm_area_caller((count << PAGE_SHIFT), flags, + __builtin_return_address(0)); + if (!area) +@@ -1478,6 +1514,13 @@ static void *__vmalloc_node(unsigned lon + if (!size || (size >> PAGE_SHIFT) > num_physpages) + return NULL; + ++#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++ if (!(pgprot_val(prot) & _PAGE_NX)) ++ area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END, ++ node, gfp_mask, caller); ++ else ++#endif ++ + area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END, + node, gfp_mask, caller); + +@@ -1496,6 +1539,7 @@ static void *__vmalloc_node(unsigned lon + return addr; + } + ++#undef __vmalloc + void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) + { + return __vmalloc_node(size, gfp_mask, prot, -1, +@@ -1512,6 +1556,7 @@ EXPORT_SYMBOL(__vmalloc); + * For tight control over page level allocator and protection flags + * use __vmalloc() instead. + */ ++#undef vmalloc + void *vmalloc(unsigned long size) + { + return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, +@@ -1526,6 +1571,7 @@ EXPORT_SYMBOL(vmalloc); + * The resulting memory area is zeroed so it can be mapped to userspace + * without leaking data. + */ ++#undef vmalloc_user + void *vmalloc_user(unsigned long size) + { + struct vm_struct *area; +@@ -1552,6 +1598,7 @@ EXPORT_SYMBOL(vmalloc_user); + * For tight control over page level allocator and protection flags + * use __vmalloc() instead. + */ ++#undef vmalloc_node + void *vmalloc_node(unsigned long size, int node) + { + return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, +@@ -1574,10 +1621,10 @@ EXPORT_SYMBOL(vmalloc_node); + * For tight control over page level allocator and protection flags + * use __vmalloc() instead. + */ +- ++#undef vmalloc_exec + void *vmalloc_exec(unsigned long size) + { +- return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, ++ return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC, + -1, __builtin_return_address(0)); + } + +@@ -1596,6 +1643,7 @@ void *vmalloc_exec(unsigned long size) + * Allocate enough 32bit PA addressable pages to cover @size from the + * page level allocator and map them into contiguous kernel virtual space. + */ ++#undef vmalloc_32 + void *vmalloc_32(unsigned long size) + { + return __vmalloc_node(size, GFP_VMALLOC32, PAGE_KERNEL, +@@ -1610,6 +1658,7 @@ EXPORT_SYMBOL(vmalloc_32); + * The resulting memory area is 32bit addressable and zeroed so it can be + * mapped to userspace without leaking data. + */ ++#undef vmalloc_32_user + void *vmalloc_32_user(unsigned long size) + { + struct vm_struct *area; +diff -urNp linux-2.6.31.1/net/atm/atm_misc.c linux-2.6.31.1/net/atm/atm_misc.c +--- linux-2.6.31.1/net/atm/atm_misc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/atm/atm_misc.c 2009-10-01 20:12:45.000000000 -0400 +@@ -19,7 +19,7 @@ int atm_charge(struct atm_vcc *vcc,int t + if (atomic_read(&sk_atm(vcc)->sk_rmem_alloc) <= sk_atm(vcc)->sk_rcvbuf) + return 1; + atm_return(vcc,truesize); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + return 0; + } + +@@ -41,7 +41,7 @@ struct sk_buff *atm_alloc_charge(struct + } + } + atm_return(vcc,guess); +- atomic_inc(&vcc->stats->rx_drop); ++ atomic_inc_unchecked(&vcc->stats->rx_drop); + return NULL; + } + +@@ -88,7 +88,7 @@ int atm_pcr_goal(const struct atm_trafpr + + void sonet_copy_stats(struct k_sonet_stats *from,struct sonet_stats *to) + { +-#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i) ++#define __HANDLE_ITEM(i) to->i = atomic_read_unchecked(&from->i) + __SONET_ITEMS + #undef __HANDLE_ITEM + } +@@ -96,7 +96,7 @@ void sonet_copy_stats(struct k_sonet_sta + + void sonet_subtract_stats(struct k_sonet_stats *from,struct sonet_stats *to) + { +-#define __HANDLE_ITEM(i) atomic_sub(to->i,&from->i) ++#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i,&from->i) + __SONET_ITEMS + #undef __HANDLE_ITEM + } +diff -urNp linux-2.6.31.1/net/atm/proc.c linux-2.6.31.1/net/atm/proc.c +--- linux-2.6.31.1/net/atm/proc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/atm/proc.c 2009-10-01 20:12:45.000000000 -0400 +@@ -43,9 +43,9 @@ static void add_stats(struct seq_file *s + const struct k_atm_aal_stats *stats) + { + seq_printf(seq, "%s ( %d %d %d %d %d )", aal, +- atomic_read(&stats->tx),atomic_read(&stats->tx_err), +- atomic_read(&stats->rx),atomic_read(&stats->rx_err), +- atomic_read(&stats->rx_drop)); ++ atomic_read_unchecked(&stats->tx),atomic_read_unchecked(&stats->tx_err), ++ atomic_read_unchecked(&stats->rx),atomic_read_unchecked(&stats->rx_err), ++ atomic_read_unchecked(&stats->rx_drop)); + } + + static void atm_dev_info(struct seq_file *seq, const struct atm_dev *dev) +diff -urNp linux-2.6.31.1/net/atm/resources.c linux-2.6.31.1/net/atm/resources.c +--- linux-2.6.31.1/net/atm/resources.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/atm/resources.c 2009-10-01 20:12:45.000000000 -0400 +@@ -161,7 +161,7 @@ void atm_dev_deregister(struct atm_dev * + static void copy_aal_stats(struct k_atm_aal_stats *from, + struct atm_aal_stats *to) + { +-#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i) ++#define __HANDLE_ITEM(i) to->i = atomic_read_unchecked(&from->i) + __AAL_STAT_ITEMS + #undef __HANDLE_ITEM + } +@@ -170,7 +170,7 @@ static void copy_aal_stats(struct k_atm_ + static void subtract_aal_stats(struct k_atm_aal_stats *from, + struct atm_aal_stats *to) + { +-#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i) ++#define __HANDLE_ITEM(i) atomic_sub_unchecked(to->i, &from->i) + __AAL_STAT_ITEMS + #undef __HANDLE_ITEM + } +diff -urNp linux-2.6.31.1/net/bridge/br_stp_if.c linux-2.6.31.1/net/bridge/br_stp_if.c +--- linux-2.6.31.1/net/bridge/br_stp_if.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/bridge/br_stp_if.c 2009-10-01 20:12:45.000000000 -0400 +@@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg + char *envp[] = { NULL }; + + if (br->stp_enabled == BR_USER_STP) { +- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1); ++ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); + printk(KERN_INFO "%s: userspace STP stopped, return code %d\n", + br->dev->name, r); + +diff -urNp linux-2.6.31.1/net/core/flow.c linux-2.6.31.1/net/core/flow.c +--- linux-2.6.31.1/net/core/flow.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/core/flow.c 2009-10-01 20:12:45.000000000 -0400 +@@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT( + + static u32 flow_hash_shift; + #define flow_hash_size (1 << flow_hash_shift) +-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL }; ++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables); + + #define flow_table(cpu) (per_cpu(flow_tables, cpu)) + +@@ -52,7 +52,7 @@ struct flow_percpu_info { + u32 hash_rnd; + int count; + }; +-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 }; ++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info); + + #define flow_hash_rnd_recalc(cpu) \ + (per_cpu(flow_hash_info, cpu).hash_rnd_recalc) +@@ -69,7 +69,7 @@ struct flow_flush_info { + atomic_t cpuleft; + struct completion completion; + }; +-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL }; ++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets); + + #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu)) + +diff -urNp linux-2.6.31.1/net/dccp/ccids/ccid3.c linux-2.6.31.1/net/dccp/ccids/ccid3.c +--- linux-2.6.31.1/net/dccp/ccids/ccid3.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/dccp/ccids/ccid3.c 2009-10-01 20:12:45.000000000 -0400 +@@ -43,7 +43,7 @@ + static int ccid3_debug; + #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a) + #else +-#define ccid3_pr_debug(format, a...) ++#define ccid3_pr_debug(format, a...) do {} while (0) + #endif + + /* +diff -urNp linux-2.6.31.1/net/dccp/dccp.h linux-2.6.31.1/net/dccp/dccp.h +--- linux-2.6.31.1/net/dccp/dccp.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/dccp/dccp.h 2009-10-01 20:12:45.000000000 -0400 +@@ -44,9 +44,9 @@ extern int dccp_debug; + #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a) + #define dccp_debug(fmt, a...) dccp_pr_debug_cat(KERN_DEBUG fmt, ##a) + #else +-#define dccp_pr_debug(format, a...) +-#define dccp_pr_debug_cat(format, a...) +-#define dccp_debug(format, a...) ++#define dccp_pr_debug(format, a...) do {} while (0) ++#define dccp_pr_debug_cat(format, a...) do {} while (0) ++#define dccp_debug(format, a...) do {} while (0) + #endif + + extern struct inet_hashinfo dccp_hashinfo; +diff -urNp linux-2.6.31.1/net/ipv4/inet_hashtables.c linux-2.6.31.1/net/ipv4/inet_hashtables.c +--- linux-2.6.31.1/net/ipv4/inet_hashtables.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv4/inet_hashtables.c 2009-10-01 20:12:45.000000000 -0400 +@@ -18,11 +18,14 @@ + #include <linux/sched.h> + #include <linux/slab.h> + #include <linux/wait.h> ++#include <linux/security.h> + + #include <net/inet_connection_sock.h> + #include <net/inet_hashtables.h> + #include <net/ip.h> + ++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet); ++ + /* + * Allocate and initialize a new local port bind bucket. + * The bindhash mutex for snum's hash chain must be held here. +@@ -490,6 +493,8 @@ ok: + } + spin_unlock(&head->lock); + ++ gr_update_task_in_ip_table(current, inet_sk(sk)); ++ + if (tw) { + inet_twsk_deschedule(tw, death_row); + inet_twsk_put(tw); +diff -urNp linux-2.6.31.1/net/ipv4/netfilter/nf_nat_snmp_basic.c linux-2.6.31.1/net/ipv4/netfilter/nf_nat_snmp_basic.c +--- linux-2.6.31.1/net/ipv4/netfilter/nf_nat_snmp_basic.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv4/netfilter/nf_nat_snmp_basic.c 2009-10-01 20:12:45.000000000 -0400 +@@ -397,7 +397,7 @@ static unsigned char asn1_octets_decode( + + *len = 0; + +- *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC); ++ *octets = kmalloc((eoc - ctx->pointer), GFP_ATOMIC); + if (*octets == NULL) { + if (net_ratelimit()) + printk("OOM in bsalg (%d)\n", __LINE__); +diff -urNp linux-2.6.31.1/net/ipv4/tcp_ipv4.c linux-2.6.31.1/net/ipv4/tcp_ipv4.c +--- linux-2.6.31.1/net/ipv4/tcp_ipv4.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv4/tcp_ipv4.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1504,6 +1504,9 @@ int tcp_v4_do_rcv(struct sock *sk, struc + return 0; + + reset: ++#ifdef CONFIG_GRKERNSEC_BLACKHOLE ++ if (!skb->dev || (skb->dev->flags & IFF_LOOPBACK)) ++#endif + tcp_v4_send_reset(rsk, skb); + discard: + kfree_skb(skb); +@@ -1612,6 +1615,9 @@ no_tcp_socket: + bad_packet: + TCP_INC_STATS_BH(net, TCP_MIB_INERRS); + } else { ++#ifdef CONFIG_GRKERNSEC_BLACKHOLE ++ if (skb->dev->flags & IFF_LOOPBACK) ++#endif + tcp_v4_send_reset(NULL, skb); + } + +diff -urNp linux-2.6.31.1/net/ipv4/tcp_minisocks.c linux-2.6.31.1/net/ipv4/tcp_minisocks.c +--- linux-2.6.31.1/net/ipv4/tcp_minisocks.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv4/tcp_minisocks.c 2009-10-01 20:12:45.000000000 -0400 +@@ -695,8 +695,11 @@ listen_overflow: + + embryonic_reset: + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); ++ ++#ifndef CONFIG_GRKERNSEC_BLACKHOLE + if (!(flg & TCP_FLAG_RST)) + req->rsk_ops->send_reset(sk, skb); ++#endif + + inet_csk_reqsk_queue_drop(sk, req, prev); + return NULL; +diff -urNp linux-2.6.31.1/net/ipv4/udp.c linux-2.6.31.1/net/ipv4/udp.c +--- linux-2.6.31.1/net/ipv4/udp.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv4/udp.c 2009-10-01 20:12:45.000000000 -0400 +@@ -86,6 +86,7 @@ + #include <linux/types.h> + #include <linux/fcntl.h> + #include <linux/module.h> ++#include <linux/security.h> + #include <linux/socket.h> + #include <linux/sockios.h> + #include <linux/igmp.h> +@@ -369,6 +370,9 @@ found: + return s; + } + ++extern int gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb); ++extern int gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr); ++ + /* + * This routine is called by the ICMP module when it gets some + * sort of error condition. If err < 0 then the socket should +@@ -631,9 +635,18 @@ int udp_sendmsg(struct kiocb *iocb, stru + dport = usin->sin_port; + if (dport == 0) + return -EINVAL; ++ ++ err = gr_search_udp_sendmsg(sk, usin); ++ if (err) ++ return err; + } else { + if (sk->sk_state != TCP_ESTABLISHED) + return -EDESTADDRREQ; ++ ++ err = gr_search_udp_sendmsg(sk, NULL); ++ if (err) ++ return err; ++ + daddr = inet->daddr; + dport = inet->dport; + /* Open fast path for connected socket. +@@ -903,6 +916,10 @@ try_again: + if (!skb) + goto out; + ++ err = gr_search_udp_recvmsg(sk, skb); ++ if (err) ++ goto out_free; ++ + ulen = skb->len - sizeof(struct udphdr); + copied = len; + if (copied > ulen) +@@ -1293,6 +1310,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, + goto csum_error; + + UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); ++#ifdef CONFIG_GRKERNSEC_BLACKHOLE ++ if (skb->dev->flags & IFF_LOOPBACK) ++#endif + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); + + /* +diff -urNp linux-2.6.31.1/net/ipv6/exthdrs.c linux-2.6.31.1/net/ipv6/exthdrs.c +--- linux-2.6.31.1/net/ipv6/exthdrs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv6/exthdrs.c 2009-10-01 20:12:45.000000000 -0400 +@@ -630,7 +630,7 @@ static struct tlvtype_proc tlvprochopopt + .type = IPV6_TLV_JUMBO, + .func = ipv6_hop_jumbo, + }, +- { -1, } ++ { -1, NULL } + }; + + int ipv6_parse_hopopts(struct sk_buff *skb) +diff -urNp linux-2.6.31.1/net/ipv6/ip6mr.c linux-2.6.31.1/net/ipv6/ip6mr.c +--- linux-2.6.31.1/net/ipv6/ip6mr.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv6/ip6mr.c 2009-10-01 20:12:45.000000000 -0400 +@@ -204,7 +204,7 @@ static int ip6mr_vif_seq_show(struct seq + return 0; + } + +-static struct seq_operations ip6mr_vif_seq_ops = { ++static const struct seq_operations ip6mr_vif_seq_ops = { + .start = ip6mr_vif_seq_start, + .next = ip6mr_vif_seq_next, + .stop = ip6mr_vif_seq_stop, +@@ -217,7 +217,7 @@ static int ip6mr_vif_open(struct inode * + sizeof(struct ipmr_vif_iter)); + } + +-static struct file_operations ip6mr_vif_fops = { ++static const struct file_operations ip6mr_vif_fops = { + .owner = THIS_MODULE, + .open = ip6mr_vif_open, + .read = seq_read, +@@ -328,7 +328,7 @@ static int ipmr_mfc_seq_show(struct seq_ + return 0; + } + +-static struct seq_operations ipmr_mfc_seq_ops = { ++static const struct seq_operations ipmr_mfc_seq_ops = { + .start = ipmr_mfc_seq_start, + .next = ipmr_mfc_seq_next, + .stop = ipmr_mfc_seq_stop, +@@ -341,7 +341,7 @@ static int ipmr_mfc_open(struct inode *i + sizeof(struct ipmr_mfc_iter)); + } + +-static struct file_operations ip6mr_mfc_fops = { ++static const struct file_operations ip6mr_mfc_fops = { + .owner = THIS_MODULE, + .open = ipmr_mfc_open, + .read = seq_read, +diff -urNp linux-2.6.31.1/net/ipv6/raw.c linux-2.6.31.1/net/ipv6/raw.c +--- linux-2.6.31.1/net/ipv6/raw.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv6/raw.c 2009-10-01 20:12:45.000000000 -0400 +@@ -600,7 +600,7 @@ out: + return err; + } + +-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, ++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length, + struct flowi *fl, struct rt6_info *rt, + unsigned int flags) + { +diff -urNp linux-2.6.31.1/net/ipv6/tcp_ipv6.c linux-2.6.31.1/net/ipv6/tcp_ipv6.c +--- linux-2.6.31.1/net/ipv6/tcp_ipv6.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv6/tcp_ipv6.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1577,6 +1577,9 @@ static int tcp_v6_do_rcv(struct sock *sk + return 0; + + reset: ++#ifdef CONFIG_GRKERNSEC_BLACKHOLE ++ if (!skb->dev || (skb->dev->flags & IFF_LOOPBACK)) ++#endif + tcp_v6_send_reset(sk, skb); + discard: + if (opt_skb) +@@ -1699,6 +1702,9 @@ no_tcp_socket: + bad_packet: + TCP_INC_STATS_BH(net, TCP_MIB_INERRS); + } else { ++#ifdef CONFIG_GRKERNSEC_BLACKHOLE ++ if (skb->dev->flags & IFF_LOOPBACK) ++#endif + tcp_v6_send_reset(NULL, skb); + } + +diff -urNp linux-2.6.31.1/net/ipv6/udp.c linux-2.6.31.1/net/ipv6/udp.c +--- linux-2.6.31.1/net/ipv6/udp.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/ipv6/udp.c 2009-10-01 20:12:45.000000000 -0400 +@@ -589,6 +589,9 @@ int __udp6_lib_rcv(struct sk_buff *skb, + UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, + proto == IPPROTO_UDPLITE); + ++#ifdef CONFIG_GRKERNSEC_BLACKHOLE ++ if (skb->dev->flags & IFF_LOOPBACK) ++#endif + icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); + + kfree_skb(skb); +diff -urNp linux-2.6.31.1/net/irda/ircomm/ircomm_tty.c linux-2.6.31.1/net/irda/ircomm/ircomm_tty.c +--- linux-2.6.31.1/net/irda/ircomm/ircomm_tty.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/irda/ircomm/ircomm_tty.c 2009-10-01 20:12:45.000000000 -0400 +@@ -280,16 +280,16 @@ static int ircomm_tty_block_til_ready(st + add_wait_queue(&self->open_wait, &wait); + + IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n", +- __FILE__,__LINE__, tty->driver->name, self->open_count ); ++ __FILE__,__LINE__, tty->driver->name, atomic_read(&self->open_count) ); + + /* As far as I can see, we protect open_count - Jean II */ + spin_lock_irqsave(&self->spinlock, flags); + if (!tty_hung_up_p(filp)) { + extra_count = 1; +- self->open_count--; ++ atomic_dec(&self->open_count); + } + spin_unlock_irqrestore(&self->spinlock, flags); +- self->blocked_open++; ++ atomic_inc(&self->blocked_open); + + while (1) { + if (tty->termios->c_cflag & CBAUD) { +@@ -329,7 +329,7 @@ static int ircomm_tty_block_til_ready(st + } + + IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n", +- __FILE__,__LINE__, tty->driver->name, self->open_count ); ++ __FILE__,__LINE__, tty->driver->name, atomic_read(&self->open_count) ); + + schedule(); + } +@@ -340,13 +340,13 @@ static int ircomm_tty_block_til_ready(st + if (extra_count) { + /* ++ is not atomic, so this should be protected - Jean II */ + spin_lock_irqsave(&self->spinlock, flags); +- self->open_count++; ++ atomic_inc(&self->open_count); + spin_unlock_irqrestore(&self->spinlock, flags); + } +- self->blocked_open--; ++ atomic_dec(&self->blocked_open); + + IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n", +- __FILE__,__LINE__, tty->driver->name, self->open_count); ++ __FILE__,__LINE__, tty->driver->name, atomic_read(&self->open_count)); + + if (!retval) + self->flags |= ASYNC_NORMAL_ACTIVE; +@@ -415,14 +415,14 @@ static int ircomm_tty_open(struct tty_st + } + /* ++ is not atomic, so this should be protected - Jean II */ + spin_lock_irqsave(&self->spinlock, flags); +- self->open_count++; ++ atomic_inc(&self->open_count); + + tty->driver_data = self; + self->tty = tty; + spin_unlock_irqrestore(&self->spinlock, flags); + + IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, +- self->line, self->open_count); ++ self->line, atomic_read(&self->open_count)); + + /* Not really used by us, but lets do it anyway */ + self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0; +@@ -511,7 +511,7 @@ static void ircomm_tty_close(struct tty_ + return; + } + +- if ((tty->count == 1) && (self->open_count != 1)) { ++ if ((tty->count == 1) && (atomic_read(&self->open_count) != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. state->count should always +@@ -521,16 +521,16 @@ static void ircomm_tty_close(struct tty_ + */ + IRDA_DEBUG(0, "%s(), bad serial port count; " + "tty->count is 1, state->count is %d\n", __func__ , +- self->open_count); +- self->open_count = 1; ++ atomic_read(&self->open_count)); ++ atomic_set(&self->open_count, 1); + } + +- if (--self->open_count < 0) { ++ if (atomic_dec_return(&self->open_count) < 0) { + IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n", +- __func__, self->line, self->open_count); +- self->open_count = 0; ++ __func__, self->line, atomic_read(&self->open_count)); ++ atomic_set(&self->open_count, 0); + } +- if (self->open_count) { ++ if (atomic_read(&self->open_count)) { + spin_unlock_irqrestore(&self->spinlock, flags); + + IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ ); +@@ -562,7 +562,7 @@ static void ircomm_tty_close(struct tty_ + tty->closing = 0; + self->tty = NULL; + +- if (self->blocked_open) { ++ if (atomic_read(&self->blocked_open)) { + if (self->close_delay) + schedule_timeout_interruptible(self->close_delay); + wake_up_interruptible(&self->open_wait); +@@ -1017,7 +1017,7 @@ static void ircomm_tty_hangup(struct tty + spin_lock_irqsave(&self->spinlock, flags); + self->flags &= ~ASYNC_NORMAL_ACTIVE; + self->tty = NULL; +- self->open_count = 0; ++ atomic_set(&self->open_count, 0); + spin_unlock_irqrestore(&self->spinlock, flags); + + wake_up_interruptible(&self->open_wait); +@@ -1369,7 +1369,7 @@ static void ircomm_tty_line_info(struct + seq_putc(m, '\n'); + + seq_printf(m, "Role: %s\n", self->client ? "client" : "server"); +- seq_printf(m, "Open count: %d\n", self->open_count); ++ seq_printf(m, "Open count: %d\n", atomic_read(&self->open_count)); + seq_printf(m, "Max data size: %d\n", self->max_data_size); + seq_printf(m, "Max header size: %d\n", self->max_header_size); + +diff -urNp linux-2.6.31.1/net/key/af_key.c linux-2.6.31.1/net/key/af_key.c +--- linux-2.6.31.1/net/key/af_key.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/key/af_key.c 2009-10-01 20:12:45.000000000 -0400 +@@ -3705,7 +3705,7 @@ static void pfkey_seq_stop(struct seq_fi + read_unlock(&pfkey_table_lock); + } + +-static struct seq_operations pfkey_seq_ops = { ++static const struct seq_operations pfkey_seq_ops = { + .start = pfkey_seq_start, + .next = pfkey_seq_next, + .stop = pfkey_seq_stop, +@@ -3718,7 +3718,7 @@ static int pfkey_seq_open(struct inode * + sizeof(struct seq_net_private)); + } + +-static struct file_operations pfkey_proc_ops = { ++static const struct file_operations pfkey_proc_ops = { + .open = pfkey_seq_open, + .read = seq_read, + .llseek = seq_lseek, +diff -urNp linux-2.6.31.1/net/mac80211/ieee80211_i.h linux-2.6.31.1/net/mac80211/ieee80211_i.h +--- linux-2.6.31.1/net/mac80211/ieee80211_i.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/mac80211/ieee80211_i.h 2009-10-01 20:12:45.000000000 -0400 +@@ -609,7 +609,7 @@ struct ieee80211_local { + spinlock_t queue_stop_reason_lock; + + struct net_device *mdev; /* wmaster# - "master" 802.11 device */ +- int open_count; ++ atomic_t open_count; + int monitors, cooked_mntrs; + /* number of interfaces with corresponding FIF_ flags */ + int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss; +diff -urNp linux-2.6.31.1/net/mac80211/iface.c linux-2.6.31.1/net/mac80211/iface.c +--- linux-2.6.31.1/net/mac80211/iface.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/mac80211/iface.c 2009-10-01 20:12:45.000000000 -0400 +@@ -164,7 +164,7 @@ static int ieee80211_open(struct net_dev + break; + } + +- if (local->open_count == 0) { ++ if (atomic_read(&local->open_count) == 0) { + res = drv_start(local); + if (res) + goto err_del_bss; +@@ -198,7 +198,7 @@ static int ieee80211_open(struct net_dev + * Validate the MAC address for this device. + */ + if (!is_valid_ether_addr(dev->dev_addr)) { +- if (!local->open_count) ++ if (!atomic_read(&local->open_count)) + drv_stop(local); + return -EADDRNOTAVAIL; + } +@@ -281,7 +281,7 @@ static int ieee80211_open(struct net_dev + } + } + +- if (local->open_count == 0) { ++ if (atomic_read(&local->open_count) == 0) { + res = dev_open(local->mdev); + WARN_ON(res); + if (res) +@@ -303,7 +303,7 @@ static int ieee80211_open(struct net_dev + + hw_reconf_flags |= __ieee80211_recalc_idle(local); + +- local->open_count++; ++ atomic_inc(&local->open_count); + if (hw_reconf_flags) { + ieee80211_hw_config(local, hw_reconf_flags); + /* +@@ -331,7 +331,7 @@ static int ieee80211_open(struct net_dev + err_del_interface: + drv_remove_interface(local, &conf); + err_stop: +- if (!local->open_count) ++ if (!atomic_read(&local->open_count)) + drv_stop(local); + err_del_bss: + sdata->bss = NULL; +@@ -429,7 +429,7 @@ static int ieee80211_stop(struct net_dev + WARN_ON(!list_empty(&sdata->u.ap.vlans)); + } + +- local->open_count--; ++ atomic_dec(&local->open_count); + + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: +@@ -554,7 +554,7 @@ static int ieee80211_stop(struct net_dev + + ieee80211_recalc_ps(local, -1); + +- if (local->open_count == 0) { ++ if (atomic_read(&local->open_count) == 0) { + if (netif_running(local->mdev)) + dev_close(local->mdev); + +diff -urNp linux-2.6.31.1/net/mac80211/main.c linux-2.6.31.1/net/mac80211/main.c +--- linux-2.6.31.1/net/mac80211/main.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/mac80211/main.c 2009-10-01 20:12:45.000000000 -0400 +@@ -193,7 +193,7 @@ int ieee80211_hw_config(struct ieee80211 + local->hw.conf.power_level = power; + } + +- if (changed && local->open_count) { ++ if (changed && atomic_read(&local->open_count)) { + ret = drv_config(local, changed); + /* + * Goal: +diff -urNp linux-2.6.31.1/net/mac80211/pm.c linux-2.6.31.1/net/mac80211/pm.c +--- linux-2.6.31.1/net/mac80211/pm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/mac80211/pm.c 2009-10-01 20:12:45.000000000 -0400 +@@ -103,7 +103,7 @@ int __ieee80211_suspend(struct ieee80211 + } + + /* stop hardware - this must stop RX */ +- if (local->open_count) { ++ if (atomic_read(&local->open_count)) { + ieee80211_led_radio(local, false); + drv_stop(local); + } +diff -urNp linux-2.6.31.1/net/mac80211/rate.c linux-2.6.31.1/net/mac80211/rate.c +--- linux-2.6.31.1/net/mac80211/rate.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/mac80211/rate.c 2009-10-01 20:12:45.000000000 -0400 +@@ -258,7 +258,7 @@ int ieee80211_init_rate_ctrl_alg(struct + struct rate_control_ref *ref, *old; + + ASSERT_RTNL(); +- if (local->open_count || netif_running(local->mdev)) ++ if (atomic_read(&local->open_count) || netif_running(local->mdev)) + return -EBUSY; + + ref = rate_control_alloc(name, local); +diff -urNp linux-2.6.31.1/net/mac80211/rc80211_minstrel_debugfs.c linux-2.6.31.1/net/mac80211/rc80211_minstrel_debugfs.c +--- linux-2.6.31.1/net/mac80211/rc80211_minstrel_debugfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/mac80211/rc80211_minstrel_debugfs.c 2009-10-01 20:12:45.000000000 -0400 +@@ -139,7 +139,7 @@ minstrel_stats_release(struct inode *ino + return 0; + } + +-static struct file_operations minstrel_stat_fops = { ++static const struct file_operations minstrel_stat_fops = { + .owner = THIS_MODULE, + .open = minstrel_stats_open, + .read = minstrel_stats_read, +diff -urNp linux-2.6.31.1/net/mac80211/rc80211_pid_debugfs.c linux-2.6.31.1/net/mac80211/rc80211_pid_debugfs.c +--- linux-2.6.31.1/net/mac80211/rc80211_pid_debugfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/mac80211/rc80211_pid_debugfs.c 2009-10-01 20:12:45.000000000 -0400 +@@ -198,7 +198,7 @@ static ssize_t rate_control_pid_events_r + + #undef RC_PID_PRINT_BUF_SIZE + +-static struct file_operations rc_pid_fop_events = { ++static const struct file_operations rc_pid_fop_events = { + .owner = THIS_MODULE, + .read = rate_control_pid_events_read, + .poll = rate_control_pid_events_poll, +diff -urNp linux-2.6.31.1/net/mac80211/util.c linux-2.6.31.1/net/mac80211/util.c +--- linux-2.6.31.1/net/mac80211/util.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/mac80211/util.c 2009-10-01 20:12:45.000000000 -0400 +@@ -991,7 +991,7 @@ int ieee80211_reconfig(struct ieee80211_ + local->suspended = false; + + /* restart hardware */ +- if (local->open_count) { ++ if (atomic_read(&local->open_count)) { + res = drv_start(local); + + ieee80211_led_radio(local, true); +diff -urNp linux-2.6.31.1/net/packet/af_packet.c linux-2.6.31.1/net/packet/af_packet.c +--- linux-2.6.31.1/net/packet/af_packet.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/packet/af_packet.c 2009-10-01 20:12:45.000000000 -0400 +@@ -2086,7 +2086,7 @@ static void packet_mm_close(struct vm_ar + atomic_dec(&pkt_sk(sk)->mapped); + } + +-static struct vm_operations_struct packet_mmap_ops = { ++static const struct vm_operations_struct packet_mmap_ops = { + .open = packet_mm_open, + .close =packet_mm_close, + }; +diff -urNp linux-2.6.31.1/net/sctp/socket.c linux-2.6.31.1/net/sctp/socket.c +--- linux-2.6.31.1/net/sctp/socket.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/sctp/socket.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1471,7 +1471,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc + struct sctp_sndrcvinfo *sinfo; + struct sctp_initmsg *sinit; + sctp_assoc_t associd = 0; +- sctp_cmsgs_t cmsgs = { NULL }; ++ sctp_cmsgs_t cmsgs = { NULL, NULL }; + int err; + sctp_scope_t scope; + long timeo; +@@ -5790,7 +5790,6 @@ pp_found: + */ + int reuse = sk->sk_reuse; + struct sock *sk2; +- struct hlist_node *node; + + SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n"); + if (pp->fastreuse && sk->sk_reuse && +diff -urNp linux-2.6.31.1/net/socket.c linux-2.6.31.1/net/socket.c +--- linux-2.6.31.1/net/socket.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/socket.c 2009-10-01 20:12:45.000000000 -0400 +@@ -86,6 +86,7 @@ + #include <linux/audit.h> + #include <linux/wireless.h> + #include <linux/nsproxy.h> ++#include <linux/in.h> + + #include <asm/uaccess.h> + #include <asm/unistd.h> +@@ -96,6 +97,21 @@ + #include <net/sock.h> + #include <linux/netfilter.h> + ++extern void gr_attach_curr_ip(const struct sock *sk); ++extern int gr_handle_sock_all(const int family, const int type, ++ const int protocol); ++extern int gr_handle_sock_server(const struct sockaddr *sck); ++extern int gr_handle_sock_server_other(const struct socket *sck); ++extern int gr_handle_sock_client(const struct sockaddr *sck); ++extern int gr_search_connect(struct socket * sock, ++ struct sockaddr_in * addr); ++extern int gr_search_bind(struct socket * sock, ++ struct sockaddr_in * addr); ++extern int gr_search_listen(struct socket * sock); ++extern int gr_search_accept(struct socket * sock); ++extern int gr_search_socket(const int domain, const int type, ++ const int protocol); ++ + static int sock_no_open(struct inode *irrelevant, struct file *dontcare); + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); +@@ -285,7 +301,7 @@ static int init_inodecache(void) + return 0; + } + +-static struct super_operations sockfs_ops = { ++static const struct super_operations sockfs_ops = { + .alloc_inode = sock_alloc_inode, + .destroy_inode =sock_destroy_inode, + .statfs = simple_statfs, +@@ -299,7 +315,7 @@ static int sockfs_get_sb(struct file_sys + mnt); + } + +-static struct vfsmount *sock_mnt __read_mostly; ++struct vfsmount *sock_mnt __read_mostly; + + static struct file_system_type sock_fs_type = { + .name = "sockfs", +@@ -1283,6 +1299,16 @@ SYSCALL_DEFINE3(socket, int, family, int + if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) + flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; + ++ if(!gr_search_socket(family, type, protocol)) { ++ retval = -EACCES; ++ goto out; ++ } ++ ++ if (gr_handle_sock_all(family, type, protocol)) { ++ retval = -EACCES; ++ goto out; ++ } ++ + retval = sock_create(family, type, protocol, &sock); + if (retval < 0) + goto out; +@@ -1415,6 +1441,14 @@ SYSCALL_DEFINE3(bind, int, fd, struct so + if (sock) { + err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address); + if (err >= 0) { ++ if (gr_handle_sock_server((struct sockaddr *)&address)) { ++ err = -EACCES; ++ goto error; ++ } ++ err = gr_search_bind(sock, (struct sockaddr_in *)&address); ++ if (err) ++ goto error; ++ + err = security_socket_bind(sock, + (struct sockaddr *)&address, + addrlen); +@@ -1423,6 +1457,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct so + (struct sockaddr *) + &address, addrlen); + } ++error: + fput_light(sock->file, fput_needed); + } + return err; +@@ -1446,10 +1481,20 @@ SYSCALL_DEFINE2(listen, int, fd, int, ba + if ((unsigned)backlog > somaxconn) + backlog = somaxconn; + ++ if (gr_handle_sock_server_other(sock)) { ++ err = -EPERM; ++ goto error; ++ } ++ ++ err = gr_search_listen(sock); ++ if (err) ++ goto error; ++ + err = security_socket_listen(sock, backlog); + if (!err) + err = sock->ops->listen(sock, backlog); + ++error: + fput_light(sock->file, fput_needed); + } + return err; +@@ -1492,6 +1537,18 @@ SYSCALL_DEFINE4(accept4, int, fd, struct + newsock->type = sock->type; + newsock->ops = sock->ops; + ++ if (gr_handle_sock_server_other(sock)) { ++ err = -EPERM; ++ sock_release(newsock); ++ goto out_put; ++ } ++ ++ err = gr_search_accept(sock); ++ if (err) { ++ sock_release(newsock); ++ goto out_put; ++ } ++ + /* + * We don't need try_module_get here, as the listening socket (sock) + * has the protocol module (sock->ops->owner) held. +@@ -1534,6 +1591,8 @@ SYSCALL_DEFINE4(accept4, int, fd, struct + fd_install(newfd, newfile); + err = newfd; + ++ gr_attach_curr_ip(newsock->sk); ++ + out_put: + fput_light(sock->file, fput_needed); + out: +@@ -1571,6 +1630,7 @@ SYSCALL_DEFINE3(connect, int, fd, struct + int, addrlen) + { + struct socket *sock; ++ struct sockaddr *sck; + struct sockaddr_storage address; + int err, fput_needed; + +@@ -1581,6 +1641,17 @@ SYSCALL_DEFINE3(connect, int, fd, struct + if (err < 0) + goto out_put; + ++ sck = (struct sockaddr *)&address; ++ ++ if (gr_handle_sock_client(sck)) { ++ err = -EACCES; ++ goto out_put; ++ } ++ ++ err = gr_search_connect(sock, (struct sockaddr_in *)sck); ++ if (err) ++ goto out_put; ++ + err = + security_socket_connect(sock, (struct sockaddr *)&address, addrlen); + if (err) +diff -urNp linux-2.6.31.1/net/sunrpc/rpc_pipe.c linux-2.6.31.1/net/sunrpc/rpc_pipe.c +--- linux-2.6.31.1/net/sunrpc/rpc_pipe.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/sunrpc/rpc_pipe.c 2009-10-01 20:12:45.000000000 -0400 +@@ -858,7 +858,7 @@ EXPORT_SYMBOL_GPL(rpc_unlink); + /* + * populate the filesystem + */ +-static struct super_operations s_ops = { ++static const struct super_operations s_ops = { + .alloc_inode = rpc_alloc_inode, + .destroy_inode = rpc_destroy_inode, + .statfs = simple_statfs, +diff -urNp linux-2.6.31.1/net/unix/af_unix.c linux-2.6.31.1/net/unix/af_unix.c +--- linux-2.6.31.1/net/unix/af_unix.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/unix/af_unix.c 2009-10-01 20:12:45.000000000 -0400 +@@ -734,6 +734,12 @@ static struct sock *unix_find_other(stru + err = -ECONNREFUSED; + if (!S_ISSOCK(inode->i_mode)) + goto put_fail; ++ ++ if (!gr_acl_handle_unix(path.dentry, path.mnt)) { ++ err = -EACCES; ++ goto put_fail; ++ } ++ + u = unix_find_socket_byinode(net, inode); + if (!u) + goto put_fail; +@@ -754,6 +760,13 @@ static struct sock *unix_find_other(stru + if (u) { + struct dentry *dentry; + dentry = unix_sk(u)->dentry; ++ ++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) { ++ err = -EPERM; ++ sock_put(u); ++ goto fail; ++ } ++ + if (dentry) + touch_atime(unix_sk(u)->mnt, dentry); + } else +@@ -839,11 +852,18 @@ static int unix_bind(struct socket *sock + err = security_path_mknod(&nd.path, dentry, mode, 0); + if (err) + goto out_mknod_drop_write; ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) { ++ err = -EACCES; ++ goto out_mknod_drop_write; ++ } + err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); + out_mknod_drop_write: + mnt_drop_write(nd.path.mnt); + if (err) + goto out_mknod_dput; ++ ++ gr_handle_create(dentry, nd.path.mnt); ++ + mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + dput(nd.path.dentry); + nd.path.dentry = dentry; +@@ -861,6 +881,10 @@ out_mknod_drop_write: + goto out_unlock; + } + ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX ++ sk->sk_peercred.pid = current->pid; ++#endif ++ + list = &unix_socket_table[addr->hash]; + } else { + list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; +diff -urNp linux-2.6.31.1/net/xfrm/xfrm_proc.c linux-2.6.31.1/net/xfrm/xfrm_proc.c +--- linux-2.6.31.1/net/xfrm/xfrm_proc.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/net/xfrm/xfrm_proc.c 2009-10-01 20:12:45.000000000 -0400 +@@ -60,7 +60,7 @@ static int xfrm_statistics_seq_open(stru + return single_open_net(inode, file, xfrm_statistics_seq_show); + } + +-static struct file_operations xfrm_statistics_seq_fops = { ++static const struct file_operations xfrm_statistics_seq_fops = { + .owner = THIS_MODULE, + .open = xfrm_statistics_seq_open, + .read = seq_read, +diff -urNp linux-2.6.31.1/samples/markers/marker-example.c linux-2.6.31.1/samples/markers/marker-example.c +--- linux-2.6.31.1/samples/markers/marker-example.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/samples/markers/marker-example.c 2009-10-01 20:12:45.000000000 -0400 +@@ -26,7 +26,7 @@ static int my_open(struct inode *inode, + return -EPERM; + } + +-static struct file_operations mark_ops = { ++static const struct file_operations mark_ops = { + .open = my_open, + }; + +diff -urNp linux-2.6.31.1/samples/tracepoints/tracepoint-sample.c linux-2.6.31.1/samples/tracepoints/tracepoint-sample.c +--- linux-2.6.31.1/samples/tracepoints/tracepoint-sample.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/samples/tracepoints/tracepoint-sample.c 2009-10-01 20:12:45.000000000 -0400 +@@ -28,7 +28,7 @@ static int my_open(struct inode *inode, + return -EPERM; + } + +-static struct file_operations mark_ops = { ++static const struct file_operations mark_ops = { + .open = my_open, + }; + +diff -urNp linux-2.6.31.1/scripts/basic/fixdep.c linux-2.6.31.1/scripts/basic/fixdep.c +--- linux-2.6.31.1/scripts/basic/fixdep.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/basic/fixdep.c 2009-10-01 20:12:45.000000000 -0400 +@@ -224,9 +224,9 @@ void use_config(char *m, int slen) + + void parse_config_file(char *map, size_t len) + { +- int *end = (int *) (map + len); ++ unsigned int *end = (unsigned int *) (map + len); + /* start at +1, so that p can never be < map */ +- int *m = (int *) map + 1; ++ unsigned int *m = (unsigned int *) map + 1; + char *p, *q; + + for (; m < end; m++) { +@@ -373,7 +373,7 @@ void print_deps(void) + void traps(void) + { + static char test[] __attribute__((aligned(sizeof(int)))) = "CONF"; +- int *p = (int *)test; ++ unsigned int *p = (unsigned int *)test; + + if (*p != INT_CONF) { + fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n", +diff -urNp linux-2.6.31.1/scripts/kallsyms.c linux-2.6.31.1/scripts/kallsyms.c +--- linux-2.6.31.1/scripts/kallsyms.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/kallsyms.c 2009-10-01 20:12:45.000000000 -0400 +@@ -43,10 +43,10 @@ struct text_range { + + static unsigned long long _text; + static struct text_range text_ranges[] = { +- { "_stext", "_etext" }, +- { "_sinittext", "_einittext" }, +- { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */ +- { "_stext_l2", "_etext_l2" }, /* Blackfin on-chip L2 SRAM */ ++ { "_stext", "_etext", 0, 0 }, ++ { "_sinittext", "_einittext", 0, 0 }, ++ { "_stext_l1", "_etext_l1", 0, 0 }, /* Blackfin on-chip L1 inst SRAM */ ++ { "_stext_l2", "_etext_l2", 0, 0 }, /* Blackfin on-chip L2 SRAM */ + }; + #define text_range_text (&text_ranges[0]) + #define text_range_inittext (&text_ranges[1]) +diff -urNp linux-2.6.31.1/scripts/kconfig/lkc.h linux-2.6.31.1/scripts/kconfig/lkc.h +--- linux-2.6.31.1/scripts/kconfig/lkc.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/kconfig/lkc.h 2009-10-01 20:12:45.000000000 -0400 +@@ -97,7 +97,7 @@ void menu_add_expr(enum prop_type type, + void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); + void menu_add_option(int token, char *arg); + void menu_finalize(struct menu *parent); +-void menu_set_type(int type); ++void menu_set_type(unsigned int type); + + /* util.c */ + struct file *file_lookup(const char *name); +diff -urNp linux-2.6.31.1/scripts/kconfig/mconf.c linux-2.6.31.1/scripts/kconfig/mconf.c +--- linux-2.6.31.1/scripts/kconfig/mconf.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/kconfig/mconf.c 2009-10-01 20:12:45.000000000 -0400 +@@ -361,7 +361,7 @@ static char filename[PATH_MAX+1]; + static void set_config_filename(const char *config_filename) + { + static char menu_backtitle[PATH_MAX+128]; +- int size; ++ unsigned int size; + struct symbol *sym; + + sym = sym_lookup("KERNELVERSION", 0); +diff -urNp linux-2.6.31.1/scripts/kconfig/menu.c linux-2.6.31.1/scripts/kconfig/menu.c +--- linux-2.6.31.1/scripts/kconfig/menu.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/kconfig/menu.c 2009-10-01 20:12:45.000000000 -0400 +@@ -104,7 +104,7 @@ void menu_add_dep(struct expr *dep) + current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); + } + +-void menu_set_type(int type) ++void menu_set_type(unsigned int type) + { + struct symbol *sym = current_entry->sym; + +diff -urNp linux-2.6.31.1/scripts/mod/file2alias.c linux-2.6.31.1/scripts/mod/file2alias.c +--- linux-2.6.31.1/scripts/mod/file2alias.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/mod/file2alias.c 2009-10-01 20:12:45.000000000 -0400 +@@ -72,7 +72,7 @@ static void device_id_check(const char * + unsigned long size, unsigned long id_size, + void *symval) + { +- int i; ++ unsigned int i; + + if (size % id_size || size < id_size) { + if (cross_build != 0) +@@ -102,7 +102,7 @@ static void device_id_check(const char * + /* USB is special because the bcdDevice can be matched against a numeric range */ + /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */ + static void do_usb_entry(struct usb_device_id *id, +- unsigned int bcdDevice_initial, int bcdDevice_initial_digits, ++ unsigned int bcdDevice_initial, unsigned int bcdDevice_initial_digits, + unsigned char range_lo, unsigned char range_hi, + struct module *mod) + { +@@ -368,7 +368,7 @@ static void do_pnp_device_entry(void *sy + for (i = 0; i < count; i++) { + const char *id = (char *)devs[i].id; + char acpi_id[sizeof(devs[0].id)]; +- int j; ++ unsigned int j; + + buf_printf(&mod->dev_table_buf, + "MODULE_ALIAS("pnp:d%s*");\n", id); +@@ -398,7 +398,7 @@ static void do_pnp_card_entries(void *sy + + for (j = 0; j < PNP_MAX_DEVICES; j++) { + const char *id = (char *)card->devs[j].id; +- int i2, j2; ++ unsigned int i2, j2; + int dup = 0; + + if (!id[0]) +@@ -424,7 +424,7 @@ static void do_pnp_card_entries(void *sy + /* add an individual alias for every device entry */ + if (!dup) { + char acpi_id[sizeof(card->devs[0].id)]; +- int k; ++ unsigned int k; + + buf_printf(&mod->dev_table_buf, + "MODULE_ALIAS("pnp:d%s*");\n", id); +@@ -690,7 +690,7 @@ static void dmi_ascii_filter(char *d, co + static int do_dmi_entry(const char *filename, struct dmi_system_id *id, + char *alias) + { +- int i, j; ++ unsigned int i, j; + + sprintf(alias, "dmi*"); + +diff -urNp linux-2.6.31.1/scripts/mod/modpost.c linux-2.6.31.1/scripts/mod/modpost.c +--- linux-2.6.31.1/scripts/mod/modpost.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/mod/modpost.c 2009-10-01 20:12:45.000000000 -0400 +@@ -835,6 +835,7 @@ enum mismatch { + INIT_TO_EXIT, + EXIT_TO_INIT, + EXPORT_TO_INIT_EXIT, ++ DATA_TO_TEXT + }; + + struct sectioncheck { +@@ -920,6 +921,12 @@ const struct sectioncheck sectioncheck[] + .fromsec = { "__ksymtab*", NULL }, + .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, + .mismatch = EXPORT_TO_INIT_EXIT ++}, ++/* Do not reference code from writable data */ ++{ ++ .fromsec = { DATA_SECTIONS, NULL }, ++ .tosec = { TEXT_SECTIONS, NULL }, ++ .mismatch = DATA_TO_TEXT + } + }; + +@@ -1024,10 +1031,10 @@ static Elf_Sym *find_elf_symbol(struct e + continue; + if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) + continue; +- if (sym->st_value == addr) +- return sym; + /* Find a symbol nearby - addr are maybe negative */ + d = sym->st_value - addr; ++ if (d == 0) ++ return sym; + if (d < 0) + d = addr - sym->st_value; + if (d < distance) { +@@ -1268,6 +1275,14 @@ static void report_sec_mismatch(const ch + "Fix this by removing the %sannotation of %s " + "or drop the export.\n", + tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); ++ case DATA_TO_TEXT: ++/* ++ fprintf(stderr, ++ "The variable %s references\n" ++ "the %s %s%s%s\n", ++ fromsym, to, sec2annotation(tosec), tosym, to_p); ++*/ ++ break; + case NO_MISMATCH: + /* To get warnings on missing members */ + break; +@@ -1651,7 +1666,7 @@ void __attribute__((format(printf, 2, 3) + va_end(ap); + } + +-void buf_write(struct buffer *buf, const char *s, int len) ++void buf_write(struct buffer *buf, const char *s, unsigned int len) + { + if (buf->size - buf->pos < len) { + buf->size += len + SZ; +@@ -1863,7 +1878,7 @@ static void write_if_changed(struct buff + if (fstat(fileno(file), &st) < 0) + goto close_write; + +- if (st.st_size != b->pos) ++ if (st.st_size != (off_t)b->pos) + goto close_write; + + tmp = NOFAIL(malloc(b->pos)); +diff -urNp linux-2.6.31.1/scripts/mod/modpost.h linux-2.6.31.1/scripts/mod/modpost.h +--- linux-2.6.31.1/scripts/mod/modpost.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/mod/modpost.h 2009-10-01 20:12:45.000000000 -0400 +@@ -92,15 +92,15 @@ void *do_nofail(void *ptr, const char *e + + struct buffer { + char *p; +- int pos; +- int size; ++ unsigned int pos; ++ unsigned int size; + }; + + void __attribute__((format(printf, 2, 3))) + buf_printf(struct buffer *buf, const char *fmt, ...); + + void +-buf_write(struct buffer *buf, const char *s, int len); ++buf_write(struct buffer *buf, const char *s, unsigned int len); + + struct module { + struct module *next; +diff -urNp linux-2.6.31.1/scripts/mod/sumversion.c linux-2.6.31.1/scripts/mod/sumversion.c +--- linux-2.6.31.1/scripts/mod/sumversion.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/mod/sumversion.c 2009-10-01 20:12:45.000000000 -0400 +@@ -457,7 +457,7 @@ static void write_version(const char *fi + goto out; + } + +- if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { ++ if (write(fd, sum, strlen(sum)+1) != (ssize_t)strlen(sum)+1) { + warn("writing sum in %s failed: %s\n", + filename, strerror(errno)); + goto out; +diff -urNp linux-2.6.31.1/scripts/pnmtologo.c linux-2.6.31.1/scripts/pnmtologo.c +--- linux-2.6.31.1/scripts/pnmtologo.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/scripts/pnmtologo.c 2009-10-01 20:12:45.000000000 -0400 +@@ -237,14 +237,14 @@ static void write_header(void) + fprintf(out, " * Linux logo %s\n", logoname); + fputs(" */\n\n", out); + fputs("#include <linux/linux_logo.h>\n\n", out); +- fprintf(out, "static unsigned char %s_data[] __initdata = {\n", ++ fprintf(out, "static unsigned char %s_data[] = {\n", + logoname); + } + + static void write_footer(void) + { + fputs("\n};\n\n", out); +- fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname); ++ fprintf(out, "const struct linux_logo %s = {\n", logoname); + fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]); + fprintf(out, "\t.width\t\t= %d,\n", logo_width); + fprintf(out, "\t.height\t\t= %d,\n", logo_height); +@@ -374,7 +374,7 @@ static void write_logo_clut224(void) + fputs("\n};\n\n", out); + + /* write logo clut */ +- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n", ++ fprintf(out, "static unsigned char %s_clut[] = {\n", + logoname); + write_hex_cnt = 0; + for (i = 0; i < logo_clutsize; i++) { +diff -urNp linux-2.6.31.1/security/commoncap.c linux-2.6.31.1/security/commoncap.c +--- linux-2.6.31.1/security/commoncap.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/security/commoncap.c 2009-10-01 20:12:45.000000000 -0400 +@@ -27,7 +27,7 @@ + #include <linux/sched.h> + #include <linux/prctl.h> + #include <linux/securebits.h> +- ++#include <net/sock.h> + /* + * If a non-root user executes a setuid-root binary in + * !secure(SECURE_NOROOT) mode, then we raise capabilities. +@@ -50,9 +50,11 @@ static void warn_setuid_and_fcaps_mixed( + } + } + ++extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk); ++ + int cap_netlink_send(struct sock *sk, struct sk_buff *skb) + { +- NETLINK_CB(skb).eff_cap = current_cap(); ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk); + return 0; + } + +diff -urNp linux-2.6.31.1/security/integrity/ima/ima_fs.c linux-2.6.31.1/security/integrity/ima/ima_fs.c +--- linux-2.6.31.1/security/integrity/ima/ima_fs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/security/integrity/ima/ima_fs.c 2009-10-01 20:12:45.000000000 -0400 +@@ -43,7 +43,7 @@ static ssize_t ima_show_htable_violation + return ima_show_htable_value(buf, count, ppos, &ima_htable.violations); + } + +-static struct file_operations ima_htable_violations_ops = { ++static const struct file_operations ima_htable_violations_ops = { + .read = ima_show_htable_violations + }; + +@@ -55,7 +55,7 @@ static ssize_t ima_show_measurements_cou + + } + +-static struct file_operations ima_measurements_count_ops = { ++static const struct file_operations ima_measurements_count_ops = { + .read = ima_show_measurements_count + }; + +@@ -146,7 +146,7 @@ static int ima_measurements_show(struct + return 0; + } + +-static struct seq_operations ima_measurments_seqops = { ++static const struct seq_operations ima_measurments_seqops = { + .start = ima_measurements_start, + .next = ima_measurements_next, + .stop = ima_measurements_stop, +@@ -158,7 +158,7 @@ static int ima_measurements_open(struct + return seq_open(file, &ima_measurments_seqops); + } + +-static struct file_operations ima_measurements_ops = { ++static const struct file_operations ima_measurements_ops = { + .open = ima_measurements_open, + .read = seq_read, + .llseek = seq_lseek, +@@ -221,7 +221,7 @@ static int ima_ascii_measurements_show(s + return 0; + } + +-static struct seq_operations ima_ascii_measurements_seqops = { ++static const struct seq_operations ima_ascii_measurements_seqops = { + .start = ima_measurements_start, + .next = ima_measurements_next, + .stop = ima_measurements_stop, +@@ -233,7 +233,7 @@ static int ima_ascii_measurements_open(s + return seq_open(file, &ima_ascii_measurements_seqops); + } + +-static struct file_operations ima_ascii_measurements_ops = { ++static const struct file_operations ima_ascii_measurements_ops = { + .open = ima_ascii_measurements_open, + .read = seq_read, + .llseek = seq_lseek, +@@ -313,7 +313,7 @@ static int ima_release_policy(struct ino + return 0; + } + +-static struct file_operations ima_measure_policy_ops = { ++static const struct file_operations ima_measure_policy_ops = { + .open = ima_open_policy, + .write = ima_write_policy, + .release = ima_release_policy +diff -urNp linux-2.6.31.1/security/Kconfig linux-2.6.31.1/security/Kconfig +--- linux-2.6.31.1/security/Kconfig 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/security/Kconfig 2009-10-01 20:12:45.000000000 -0400 +@@ -4,6 +4,465 @@ + + menu "Security options" + ++source grsecurity/Kconfig ++ ++menu "PaX" ++ ++config PAX ++ bool "Enable various PaX features" ++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86) ++ help ++ This allows you to enable various PaX features. PaX adds ++ intrusion prevention mechanisms to the kernel that reduce ++ the risks posed by exploitable memory corruption bugs. ++ ++menu "PaX Control" ++ depends on PAX ++ ++config PAX_SOFTMODE ++ bool 'Support soft mode' ++ help ++ Enabling this option will allow you to run PaX in soft mode, that ++ is, PaX features will not be enforced by default, only on executables ++ marked explicitly. You must also enable PT_PAX_FLAGS support as it ++ is the only way to mark executables for soft mode use. ++ ++ Soft mode can be activated by using the "pax_softmode=1" kernel command ++ line option on boot. Furthermore you can control various PaX features ++ at runtime via the entries in /proc/sys/kernel/pax. ++ ++config PAX_EI_PAX ++ bool 'Use legacy ELF header marking' ++ help ++ Enabling this option will allow you to control PaX features on ++ a per executable basis via the 'chpax' utility available at ++ http://pax.grsecurity.net/. The control flags will be read from ++ an otherwise reserved part of the ELF header. This marking has ++ numerous drawbacks (no support for soft-mode, toolchain does not ++ know about the non-standard use of the ELF header) therefore it ++ has been deprecated in favour of PT_PAX_FLAGS support. ++ ++ If you have applications not marked by the PT_PAX_FLAGS ELF ++ program header then you MUST enable this option otherwise they ++ will not get any protection. ++ ++ Note that if you enable PT_PAX_FLAGS marking support as well, ++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks. ++ ++config PAX_PT_PAX_FLAGS ++ bool 'Use ELF program header marking' ++ help ++ Enabling this option will allow you to control PaX features on ++ a per executable basis via the 'paxctl' utility available at ++ http://pax.grsecurity.net/. The control flags will be read from ++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking ++ has the benefits of supporting both soft mode and being fully ++ integrated into the toolchain (the binutils patch is available ++ from http://pax.grsecurity.net). ++ ++ If you have applications not marked by the PT_PAX_FLAGS ELF ++ program header then you MUST enable the EI_PAX marking support ++ otherwise they will not get any protection. ++ ++ Note that if you enable the legacy EI_PAX marking support as well, ++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks. ++ ++choice ++ prompt 'MAC system integration' ++ default PAX_HAVE_ACL_FLAGS ++ help ++ Mandatory Access Control systems have the option of controlling ++ PaX flags on a per executable basis, choose the method supported ++ by your particular system. ++ ++ - "none": if your MAC system does not interact with PaX, ++ - "direct": if your MAC system defines pax_set_initial_flags() itself, ++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback. ++ ++ NOTE: this option is for developers/integrators only. ++ ++ config PAX_NO_ACL_FLAGS ++ bool 'none' ++ ++ config PAX_HAVE_ACL_FLAGS ++ bool 'direct' ++ ++ config PAX_HOOK_ACL_FLAGS ++ bool 'hook' ++endchoice ++ ++endmenu ++ ++menu "Non-executable pages" ++ depends on PAX ++ ++config PAX_NOEXEC ++ bool "Enforce non-executable pages" ++ depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86) ++ help ++ By design some architectures do not allow for protecting memory ++ pages against execution or even if they do, Linux does not make ++ use of this feature. In practice this means that if a page is ++ readable (such as the stack or heap) it is also executable. ++ ++ There is a well known exploit technique that makes use of this ++ fact and a common programming mistake where an attacker can ++ introduce code of his choice somewhere in the attacked program's ++ memory (typically the stack or the heap) and then execute it. ++ ++ If the attacked program was running with different (typically ++ higher) privileges than that of the attacker, then he can elevate ++ his own privilege level (e.g. get a root shell, write to files for ++ which he does not have write access to, etc). ++ ++ Enabling this option will let you choose from various features ++ that prevent the injection and execution of 'foreign' code in ++ a program. ++ ++ This will also break programs that rely on the old behaviour and ++ expect that dynamically allocated memory via the malloc() family ++ of functions is executable (which it is not). Notable examples ++ are the XFree86 4.x server, the java runtime and wine. ++ ++config PAX_PAGEEXEC ++ bool "Paging based non-executable pages" ++ depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7) ++ help ++ This implementation is based on the paging feature of the CPU. ++ On i386 without hardware non-executable bit support there is a ++ variable but usually low performance impact, however on Intel's ++ P4 core based CPUs it is very high so you should not enable this ++ for kernels meant to be used on such CPUs. ++ ++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386 ++ with hardware non-executable bit support there is no performance ++ impact, on ppc the impact is negligible. ++ ++ Note that several architectures require various emulations due to ++ badly designed userland ABIs, this will cause a performance impact ++ but will disappear as soon as userland is fixed. For example, ppc ++ userland MUST have been built with secure-plt by a recent toolchain. ++ ++config PAX_SEGMEXEC ++ bool "Segmentation based non-executable pages" ++ depends on PAX_NOEXEC && X86_32 ++ help ++ This implementation is based on the segmentation feature of the ++ CPU and has a very small performance impact, however applications ++ will be limited to a 1.5 GB address space instead of the normal ++ 3 GB. ++ ++config PAX_EMUTRAMP ++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || X86) ++ default y if PARISC ++ help ++ There are some programs and libraries that for one reason or ++ another attempt to execute special small code snippets from ++ non-executable memory pages. Most notable examples are the ++ signal handler return code generated by the kernel itself and ++ the GCC trampolines. ++ ++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then ++ such programs will no longer work under your kernel. ++ ++ As a remedy you can say Y here and use the 'chpax' or 'paxctl' ++ utilities to enable trampoline emulation for the affected programs ++ yet still have the protection provided by the non-executable pages. ++ ++ On parisc you MUST enable this option and EMUSIGRT as well, otherwise ++ your system will not even boot. ++ ++ Alternatively you can say N here and use the 'chpax' or 'paxctl' ++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC ++ for the affected files. ++ ++ NOTE: enabling this feature *may* open up a loophole in the ++ protection provided by non-executable pages that an attacker ++ could abuse. Therefore the best solution is to not have any ++ files on your system that would require this option. This can ++ be achieved by not using libc5 (which relies on the kernel ++ signal handler return code) and not using or rewriting programs ++ that make use of the nested function implementation of GCC. ++ Skilled users can just fix GCC itself so that it implements ++ nested function calls in a way that does not interfere with PaX. ++ ++config PAX_EMUSIGRT ++ bool "Automatically emulate sigreturn trampolines" ++ depends on PAX_EMUTRAMP && PARISC ++ default y ++ help ++ Enabling this option will have the kernel automatically detect ++ and emulate signal return trampolines executing on the stack ++ that would otherwise lead to task termination. ++ ++ This solution is intended as a temporary one for users with ++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17, ++ Modula-3 runtime, etc) or executables linked to such, basically ++ everything that does not specify its own SA_RESTORER function in ++ normal executable memory like glibc 2.1+ does. ++ ++ On parisc you MUST enable this option, otherwise your system will ++ not even boot. ++ ++ NOTE: this feature cannot be disabled on a per executable basis ++ and since it *does* open up a loophole in the protection provided ++ by non-executable pages, the best solution is to not have any ++ files on your system that would require this option. ++ ++config PAX_MPROTECT ++ bool "Restrict mprotect()" ++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) ++ help ++ Enabling this option will prevent programs from ++ - changing the executable status of memory pages that were ++ not originally created as executable, ++ - making read-only executable pages writable again, ++ - creating executable pages from anonymous memory. ++ ++ You should say Y here to complete the protection provided by ++ the enforcement of non-executable pages. ++ ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control ++ this feature on a per file basis. ++ ++config PAX_NOELFRELOCS ++ bool "Disallow ELF text relocations" ++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || PPC || X86) ++ help ++ Non-executable pages and mprotect() restrictions are effective ++ in preventing the introduction of new executable code into an ++ attacked task's address space. There remain only two venues ++ for this kind of attack: if the attacker can execute already ++ existing code in the attacked task then he can either have it ++ create and mmap() a file containing his code or have it mmap() ++ an already existing ELF library that does not have position ++ independent code in it and use mprotect() on it to make it ++ writable and copy his code there. While protecting against ++ the former approach is beyond PaX, the latter can be prevented ++ by having only PIC ELF libraries on one's system (which do not ++ need to relocate their code). If you are sure this is your case, ++ then enable this option otherwise be careful as you may not even ++ be able to boot or log on your system (for example, some PAM ++ modules are erroneously compiled as non-PIC by default). ++ ++ NOTE: if you are using dynamic ELF executables (as suggested ++ when using ASLR) then you must have made sure that you linked ++ your files using the PIC version of crt1 (the et_dyn.tar.gz package ++ referenced there has already been updated to support this). ++ ++config PAX_ETEXECRELOCS ++ bool "Allow ELF ET_EXEC text relocations" ++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC) ++ default y ++ help ++ On some architectures there are incorrectly created applications ++ that require text relocations and would not work without enabling ++ this option. If you are an alpha, ia64 or parisc user, you should ++ enable this option and disable it once you have made sure that ++ none of your applications need it. ++ ++config PAX_EMUPLT ++ bool "Automatically emulate ELF PLT" ++ depends on PAX_MPROTECT && (ALPHA || PARISC || SPARC32 || SPARC64) ++ default y ++ help ++ Enabling this option will have the kernel automatically detect ++ and emulate the Procedure Linkage Table entries in ELF files. ++ On some architectures such entries are in writable memory, and ++ become non-executable leading to task termination. Therefore ++ it is mandatory that you enable this option on alpha, parisc, ++ sparc and sparc64, otherwise your system would not even boot. ++ ++ NOTE: this feature *does* open up a loophole in the protection ++ provided by the non-executable pages, therefore the proper ++ solution is to modify the toolchain to produce a PLT that does ++ not need to be writable. ++ ++config PAX_DLRESOLVE ++ bool 'Emulate old glibc resolver stub' ++ depends on PAX_EMUPLT && (SPARC32 || SPARC64) ++ default n ++ help ++ This option is needed if userland has an old glibc (before 2.4) ++ that puts a 'save' instruction into the runtime generated resolver ++ stub that needs special emulation. ++ ++config PAX_KERNEXEC ++ bool "Enforce non-executable kernel pages" ++ depends on PAX_NOEXEC && X86 && (!X86_32 || X86_WP_WORKS_OK) ++ help ++ This is the kernel land equivalent of PAGEEXEC and MPROTECT, ++ that is, enabling this option will make it harder to inject ++ and execute 'foreign' code in kernel memory itself. ++ ++endmenu ++ ++menu "Address Space Layout Randomization" ++ depends on PAX ++ ++config PAX_ASLR ++ bool "Address Space Layout Randomization" ++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS ++ help ++ Many if not most exploit techniques rely on the knowledge of ++ certain addresses in the attacked program. The following options ++ will allow the kernel to apply a certain amount of randomization ++ to specific parts of the program thereby forcing an attacker to ++ guess them in most cases. Any failed guess will most likely crash ++ the attacked program which allows the kernel to detect such attempts ++ and react on them. PaX itself provides no reaction mechanisms, ++ instead it is strongly encouraged that you make use of Nergal's ++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's ++ (http://www.grsecurity.net/) built-in crash detection features or ++ develop one yourself. ++ ++ By saying Y here you can choose to randomize the following areas: ++ - top of the task's kernel stack ++ - top of the task's userland stack ++ - base address for mmap() requests that do not specify one ++ (this includes all libraries) ++ - base address of the main executable ++ ++ It is strongly recommended to say Y here as address space layout ++ randomization has negligible impact on performance yet it provides ++ a very effective protection. ++ ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control ++ this feature on a per file basis. ++ ++config PAX_RANDKSTACK ++ bool "Randomize kernel stack base" ++ depends on PAX_ASLR && X86_TSC && X86_32 ++ help ++ By saying Y here the kernel will randomize every task's kernel ++ stack on every system call. This will not only force an attacker ++ to guess it but also prevent him from making use of possible ++ leaked information about it. ++ ++ Since the kernel stack is a rather scarce resource, randomization ++ may cause unexpected stack overflows, therefore you should very ++ carefully test your system. Note that once enabled in the kernel ++ configuration, this feature cannot be disabled on a per file basis. ++ ++config PAX_RANDUSTACK ++ bool "Randomize user stack base" ++ depends on PAX_ASLR ++ help ++ By saying Y here the kernel will randomize every task's userland ++ stack. The randomization is done in two steps where the second ++ one may apply a big amount of shift to the top of the stack and ++ cause problems for programs that want to use lots of memory (more ++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is). ++ For this reason the second step can be controlled by 'chpax' or ++ 'paxctl' on a per file basis. ++ ++config PAX_RANDMMAP ++ bool "Randomize mmap() base" ++ depends on PAX_ASLR ++ help ++ By saying Y here the kernel will use a randomized base address for ++ mmap() requests that do not specify one themselves. As a result ++ all dynamically loaded libraries will appear at random addresses ++ and therefore be harder to exploit by a technique where an attacker ++ attempts to execute library code for his purposes (e.g. spawn a ++ shell from an exploited program that is running at an elevated ++ privilege level). ++ ++ Furthermore, if a program is relinked as a dynamic ELF file, its ++ base address will be randomized as well, completing the full ++ randomization of the address space layout. Attacking such programs ++ becomes a guess game. You can find an example of doing this at ++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at ++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz . ++ ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this ++ feature on a per file basis. ++ ++endmenu ++ ++menu "Miscellaneous hardening features" ++ ++config PAX_MEMORY_SANITIZE ++ bool "Sanitize all freed memory" ++ help ++ By saying Y here the kernel will erase memory pages as soon as they ++ are freed. This in turn reduces the lifetime of data stored in the ++ pages, making it less likely that sensitive information such as ++ passwords, cryptographic secrets, etc stay in memory for too long. ++ ++ This is especially useful for programs whose runtime is short, long ++ lived processes and the kernel itself benefit from this as long as ++ they operate on whole memory pages and ensure timely freeing of pages ++ that may hold sensitive information. ++ ++ The tradeoff is performance impact, on a single CPU system kernel ++ compilation sees a 3% slowdown, other systems and workloads may vary ++ and you are advised to test this feature on your expected workload ++ before deploying it. ++ ++ Note that this feature does not protect data stored in live pages, ++ e.g., process memory swapped to disk may stay there for a long time. ++ ++config PAX_MEMORY_UDEREF ++ bool "Prevent invalid userland pointer dereference" ++ depends on X86_32 && !UML_X86 ++ help ++ By saying Y here the kernel will be prevented from dereferencing ++ userland pointers in contexts where the kernel expects only kernel ++ pointers. This is both a useful runtime debugging feature and a ++ security measure that prevents exploiting a class of kernel bugs. ++ ++ The tradeoff is that some virtualization solutions may experience ++ a huge slowdown and therefore you should not enable this feature ++ for kernels meant to run in such environments. Whether a given VM ++ solution is affected or not is best determined by simply trying it ++ out, the performance impact will be obvious right on boot as this ++ mechanism engages from very early on. A good rule of thumb is that ++ VMs running on CPUs without hardware virtualization support (i.e., ++ the majority of IA-32 CPUs) will likely experience the slowdown. ++ ++config PAX_REFCOUNT ++ bool "Prevent various kernel object reference counter overflows" ++ depends on GRKERNSEC && (X86 || SPARC64) ++ help ++ By saying Y here the kernel will detect and prevent overflowing ++ various (but not all) kinds of object reference counters. Such ++ overflows can normally occur due to bugs only and are often, if ++ not always, exploitable. ++ ++ The tradeoff is that data structures protected by an overflowed ++ refcount will never be freed and therefore will leak memory. Note ++ that this leak also happens even without this protection but in ++ that case the overflow can eventually trigger the freeing of the ++ data structure while it is still being used elsewhere, resulting ++ in the exploitable situation that this feature prevents. ++ ++ Since this has a negligible performance impact, you should enable ++ this feature. ++ ++config PAX_USERCOPY ++ bool "Bounds check heap object copies between kernel and userland" ++ depends on X86 || PPC32 || PPC64 || SPARC32 || SPARC64 ++ depends on GRKERNSEC && (SLAB || SLUB || SLOB) ++ help ++ By saying Y here the kernel will enforce the size of heap objects ++ when they are copied in either direction between the kernel and ++ userland, even if only a part of the heap object is copied. ++ ++ Specifically, this checking prevents information leaking from the ++ kernel heap during kernel to userland copies (if the kernel heap ++ object is otherwise fully initialized) and prevents kernel heap ++ overflows during userland to kernel copies. ++ ++ Note that the current implementation provides the strictest checks ++ for the SLUB allocator. ++ ++ Since this has a negligible performance impact, you should enable ++ this feature. ++endmenu ++ ++endmenu ++ + config KEYS + bool "Enable access key retention support" + help +diff -urNp linux-2.6.31.1/security/min_addr.c linux-2.6.31.1/security/min_addr.c +--- linux-2.6.31.1/security/min_addr.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/security/min_addr.c 2009-10-01 20:12:45.000000000 -0400 +@@ -14,6 +14,7 @@ unsigned long dac_mmap_min_addr = CONFIG + */ + static void update_mmap_min_addr(void) + { ++#ifndef SPARC + #ifdef CONFIG_LSM_MMAP_MIN_ADDR + if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR) + mmap_min_addr = dac_mmap_min_addr; +@@ -22,6 +23,7 @@ static void update_mmap_min_addr(void) + #else + mmap_min_addr = dac_mmap_min_addr; + #endif ++#endif + } + + /* +diff -urNp linux-2.6.31.1/security/smack/smackfs.c linux-2.6.31.1/security/smack/smackfs.c +--- linux-2.6.31.1/security/smack/smackfs.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/security/smack/smackfs.c 2009-10-01 20:12:45.000000000 -0400 +@@ -187,7 +187,7 @@ static void load_seq_stop(struct seq_fil + /* No-op */ + } + +-static struct seq_operations load_seq_ops = { ++static const struct seq_operations load_seq_ops = { + .start = load_seq_start, + .next = load_seq_next, + .show = load_seq_show, +@@ -503,7 +503,7 @@ static void cipso_seq_stop(struct seq_fi + /* No-op */ + } + +-static struct seq_operations cipso_seq_ops = { ++static const struct seq_operations cipso_seq_ops = { + .start = cipso_seq_start, + .stop = cipso_seq_stop, + .next = cipso_seq_next, +@@ -697,7 +697,7 @@ static void netlbladdr_seq_stop(struct s + /* No-op */ + } + +-static struct seq_operations netlbladdr_seq_ops = { ++static const struct seq_operations netlbladdr_seq_ops = { + .start = netlbladdr_seq_start, + .stop = netlbladdr_seq_stop, + .next = netlbladdr_seq_next, +diff -urNp linux-2.6.31.1/sound/aoa/codecs/onyx.c linux-2.6.31.1/sound/aoa/codecs/onyx.c +--- linux-2.6.31.1/sound/aoa/codecs/onyx.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/aoa/codecs/onyx.c 2009-10-01 20:12:45.000000000 -0400 +@@ -53,7 +53,7 @@ struct onyx { + spdif_locked:1, + analog_locked:1, + original_mute:2; +- int open_count; ++ atomic_t open_count; + struct codec_info *codec_info; + + /* mutex serializes concurrent access to the device +@@ -752,7 +752,7 @@ static int onyx_open(struct codec_info_i + struct onyx *onyx = cii->codec_data; + + mutex_lock(&onyx->mutex); +- onyx->open_count++; ++ atomic_inc(&onyx->open_count); + mutex_unlock(&onyx->mutex); + + return 0; +@@ -764,8 +764,7 @@ static int onyx_close(struct codec_info_ + struct onyx *onyx = cii->codec_data; + + mutex_lock(&onyx->mutex); +- onyx->open_count--; +- if (!onyx->open_count) ++ if (atomic_dec_and_test(&onyx->open_count)) + onyx->spdif_locked = onyx->analog_locked = 0; + mutex_unlock(&onyx->mutex); + +diff -urNp linux-2.6.31.1/sound/core/oss/pcm_oss.c linux-2.6.31.1/sound/core/oss/pcm_oss.c +--- linux-2.6.31.1/sound/core/oss/pcm_oss.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/core/oss/pcm_oss.c 2009-10-01 20:12:45.000000000 -0400 +@@ -2943,8 +2943,8 @@ static void snd_pcm_oss_proc_done(struct + } + } + #else /* !CONFIG_SND_VERBOSE_PROCFS */ +-#define snd_pcm_oss_proc_init(pcm) +-#define snd_pcm_oss_proc_done(pcm) ++#define snd_pcm_oss_proc_init(pcm) do {} while (0) ++#define snd_pcm_oss_proc_done(pcm) do {} while (0) + #endif /* CONFIG_SND_VERBOSE_PROCFS */ + + /* +diff -urNp linux-2.6.31.1/sound/core/seq/seq_lock.h linux-2.6.31.1/sound/core/seq/seq_lock.h +--- linux-2.6.31.1/sound/core/seq/seq_lock.h 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/core/seq/seq_lock.h 2009-10-01 20:12:45.000000000 -0400 +@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo + #else /* SMP || CONFIG_SND_DEBUG */ + + typedef spinlock_t snd_use_lock_t; /* dummy */ +-#define snd_use_lock_init(lockp) /**/ +-#define snd_use_lock_use(lockp) /**/ +-#define snd_use_lock_free(lockp) /**/ +-#define snd_use_lock_sync(lockp) /**/ ++#define snd_use_lock_init(lockp) do {} while (0) ++#define snd_use_lock_use(lockp) do {} while (0) ++#define snd_use_lock_free(lockp) do {} while (0) ++#define snd_use_lock_sync(lockp) do {} while (0) + + #endif /* SMP || CONFIG_SND_DEBUG */ + +diff -urNp linux-2.6.31.1/sound/drivers/mts64.c linux-2.6.31.1/sound/drivers/mts64.c +--- linux-2.6.31.1/sound/drivers/mts64.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/drivers/mts64.c 2009-10-01 20:12:45.000000000 -0400 +@@ -65,7 +65,7 @@ struct mts64 { + struct pardevice *pardev; + int pardev_claimed; + +- int open_count; ++ atomic_t open_count; + int current_midi_output_port; + int current_midi_input_port; + u8 mode[MTS64_NUM_INPUT_PORTS]; +@@ -695,7 +695,7 @@ static int snd_mts64_rawmidi_open(struct + { + struct mts64 *mts = substream->rmidi->private_data; + +- if (mts->open_count == 0) { ++ if (atomic_read(&mts->open_count) == 0) { + /* We don't need a spinlock here, because this is just called + if the device has not been opened before. + So there aren't any IRQs from the device */ +@@ -703,7 +703,7 @@ static int snd_mts64_rawmidi_open(struct + + msleep(50); + } +- ++(mts->open_count); ++ atomic_inc(&mts->open_count); + + return 0; + } +@@ -713,8 +713,7 @@ static int snd_mts64_rawmidi_close(struc + struct mts64 *mts = substream->rmidi->private_data; + unsigned long flags; + +- --(mts->open_count); +- if (mts->open_count == 0) { ++ if (atomic_dec_return(&mts->open_count) == 0) { + /* We need the spinlock_irqsave here because we can still + have IRQs at this point */ + spin_lock_irqsave(&mts->lock, flags); +@@ -723,8 +722,8 @@ static int snd_mts64_rawmidi_close(struc + + msleep(500); + +- } else if (mts->open_count < 0) +- mts->open_count = 0; ++ } else if (atomic_read(&mts->open_count) < 0) ++ atomic_set(&mts->open_count, 0); + + return 0; + } +diff -urNp linux-2.6.31.1/sound/drivers/portman2x4.c linux-2.6.31.1/sound/drivers/portman2x4.c +--- linux-2.6.31.1/sound/drivers/portman2x4.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/drivers/portman2x4.c 2009-10-01 20:12:45.000000000 -0400 +@@ -83,7 +83,7 @@ struct portman { + struct pardevice *pardev; + int pardev_claimed; + +- int open_count; ++ atomic_t open_count; + int mode[PORTMAN_NUM_INPUT_PORTS]; + struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS]; + }; +diff -urNp linux-2.6.31.1/sound/pci/ac97/ac97_patch.c linux-2.6.31.1/sound/pci/ac97/ac97_patch.c +--- linux-2.6.31.1/sound/pci/ac97/ac97_patch.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/pci/ac97/ac97_patch.c 2009-10-01 20:12:45.000000000 -0400 +@@ -1501,7 +1501,7 @@ static const struct snd_ac97_res_table a + { AC97_VIDEO, 0x9f1f }, + { AC97_AUX, 0x9f1f }, + { AC97_PCM, 0x9f1f }, +- { } /* terminator */ ++ { 0, 0 } /* terminator */ + }; + + static int patch_ad1819(struct snd_ac97 * ac97) +@@ -3876,7 +3876,7 @@ static struct snd_ac97_res_table lm4550_ + { AC97_AUX, 0x1f1f }, + { AC97_PCM, 0x1f1f }, + { AC97_REC_GAIN, 0x0f0f }, +- { } /* terminator */ ++ { 0, 0 } /* terminator */ + }; + + static int patch_lm4550(struct snd_ac97 *ac97) +diff -urNp linux-2.6.31.1/sound/pci/ens1370.c linux-2.6.31.1/sound/pci/ens1370.c +--- linux-2.6.31.1/sound/pci/ens1370.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/pci/ens1370.c 2009-10-01 20:12:45.000000000 -0400 +@@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci + { PCI_VDEVICE(ENSONIQ, 0x5880), 0, }, /* ES1373 - CT5880 */ + { PCI_VDEVICE(ECTIVA, 0x8938), 0, }, /* Ectiva EV1938 */ + #endif +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(pci, snd_audiopci_ids); +diff -urNp linux-2.6.31.1/sound/pci/intel8x0.c linux-2.6.31.1/sound/pci/intel8x0.c +--- linux-2.6.31.1/sound/pci/intel8x0.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/pci/intel8x0.c 2009-10-01 20:12:45.000000000 -0400 +@@ -444,7 +444,7 @@ static struct pci_device_id snd_intel8x0 + { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */ + { PCI_VDEVICE(AMD, 0x7445), DEVICE_INTEL }, /* AMD768 */ + { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids); +@@ -2105,7 +2105,7 @@ static struct ac97_quirk ac97_quirks[] _ + .type = AC97_TUNE_HP_ONLY + }, + #endif +- { } /* terminator */ ++ { 0, 0, 0, 0, NULL, 0 } /* terminator */ + }; + + static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, +diff -urNp linux-2.6.31.1/sound/pci/intel8x0m.c linux-2.6.31.1/sound/pci/intel8x0m.c +--- linux-2.6.31.1/sound/pci/intel8x0m.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/pci/intel8x0m.c 2009-10-01 20:12:45.000000000 -0400 +@@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0 + { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */ + { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ + #endif +- { 0, } ++ { 0, 0, 0, 0, 0, 0, 0 } + }; + + MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids); +@@ -1264,7 +1264,7 @@ static struct shortname_table { + { 0x5455, "ALi M5455" }, + { 0x746d, "AMD AMD8111" }, + #endif +- { 0 }, ++ { 0, NULL }, + }; + + static int __devinit snd_intel8x0m_probe(struct pci_dev *pci, +diff -urNp linux-2.6.31.1/sound/usb/usx2y/us122l.c linux-2.6.31.1/sound/usb/usx2y/us122l.c +--- linux-2.6.31.1/sound/usb/usx2y/us122l.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/usb/usx2y/us122l.c 2009-10-01 20:12:45.000000000 -0400 +@@ -154,7 +154,7 @@ static void usb_stream_hwdep_vm_close(st + snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count)); + } + +-static struct vm_operations_struct usb_stream_hwdep_vm_ops = { ++static const struct vm_operations_struct usb_stream_hwdep_vm_ops = { + .open = usb_stream_hwdep_vm_open, + .fault = usb_stream_hwdep_vm_fault, + .close = usb_stream_hwdep_vm_close, +diff -urNp linux-2.6.31.1/sound/usb/usx2y/usX2Yhwdep.c linux-2.6.31.1/sound/usb/usx2y/usX2Yhwdep.c +--- linux-2.6.31.1/sound/usb/usx2y/usX2Yhwdep.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/usb/usx2y/usX2Yhwdep.c 2009-10-01 20:12:45.000000000 -0400 +@@ -53,7 +53,7 @@ static int snd_us428ctls_vm_fault(struct + return 0; + } + +-static struct vm_operations_struct us428ctls_vm_ops = { ++static const struct vm_operations_struct us428ctls_vm_ops = { + .fault = snd_us428ctls_vm_fault, + }; + +diff -urNp linux-2.6.31.1/sound/usb/usx2y/usx2yhwdeppcm.c linux-2.6.31.1/sound/usb/usx2y/usx2yhwdeppcm.c +--- linux-2.6.31.1/sound/usb/usx2y/usx2yhwdeppcm.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/sound/usb/usx2y/usx2yhwdeppcm.c 2009-10-01 20:12:45.000000000 -0400 +@@ -697,7 +697,7 @@ static int snd_usX2Y_hwdep_pcm_vm_fault( + } + + +-static struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = { ++static const struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = { + .open = snd_usX2Y_hwdep_pcm_vm_open, + .close = snd_usX2Y_hwdep_pcm_vm_close, + .fault = snd_usX2Y_hwdep_pcm_vm_fault, +diff -urNp linux-2.6.31.1/usr/gen_init_cpio.c linux-2.6.31.1/usr/gen_init_cpio.c +--- linux-2.6.31.1/usr/gen_init_cpio.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/usr/gen_init_cpio.c 2009-10-01 20:12:45.000000000 -0400 +@@ -299,7 +299,7 @@ static int cpio_mkfile(const char *name, + int retval; + int rc = -1; + int namesize; +- int i; ++ unsigned int i; + + mode |= S_IFREG; + +@@ -383,9 +383,10 @@ static char *cpio_replace_env(char *new_ + *env_var = *expanded = '\0'; + strncat(env_var, start + 2, end - start - 2); + strncat(expanded, new_location, start - new_location); +- strncat(expanded, getenv(env_var), PATH_MAX); +- strncat(expanded, end + 1, PATH_MAX); ++ strncat(expanded, getenv(env_var), PATH_MAX - strlen(expanded)); ++ strncat(expanded, end + 1, PATH_MAX - strlen(expanded)); + strncpy(new_location, expanded, PATH_MAX); ++ new_location[PATH_MAX] = 0; + } else + break; + } +diff -urNp linux-2.6.31.1/virt/kvm/kvm_main.c linux-2.6.31.1/virt/kvm/kvm_main.c +--- linux-2.6.31.1/virt/kvm/kvm_main.c 2009-09-24 11:45:25.000000000 -0400 ++++ linux-2.6.31.1/virt/kvm/kvm_main.c 2009-10-01 20:12:45.000000000 -0400 +@@ -2353,6 +2353,9 @@ static struct miscdevice kvm_dev = { + KVM_MINOR, + "kvm", + &kvm_chardev_ops, ++ {NULL, NULL}, ++ NULL, ++ NULL + }; + + static void hardware_enable(void *junk) +@@ -2512,7 +2515,7 @@ static int vcpu_stat_get(void *_offset, + + DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n"); + +-static struct file_operations *stat_fops[] = { ++static const struct file_operations *stat_fops[] = { + [KVM_STAT_VCPU] = &vcpu_stat_fops, + [KVM_STAT_VM] = &vm_stat_fops, + }; +@@ -2584,7 +2587,7 @@ static void kvm_sched_out(struct preempt + kvm_arch_vcpu_put(vcpu); + } + +-int kvm_init(void *opaque, unsigned int vcpu_size, ++int kvm_init(const void *opaque, unsigned int vcpu_size, + struct module *module) + { + int r; diff --git a/pkgs/core/kernel/patches/linux-2.6.31.1-disable-compat_vdso-1.patch.off b/pkgs/core/kernel/patches/linux-2.6.31.1-disable-compat_vdso-1.patch.off new file mode 100644 index 0000000..3780030 --- /dev/null +++ b/pkgs/core/kernel/patches/linux-2.6.31.1-disable-compat_vdso-1.patch.off @@ -0,0 +1,74 @@ +From: Gordon Malm <gengor@gentoo.org> +From: Kerin Millar <kerframil@gmail.com> + +COMPAT_VDSO is inappropriate for any modern Hardened Gentoo system. It +conflicts with various parts of PaX, crashing the system if enabled +while PaX's NOEXEC or UDEREF features are active. Moreover, it prevents +a number of important PaX options from appearing in the configuration +menu, including all PaX NOEXEC implementations. Unfortunately, the +reason for the disappearance of these PaX configuration options is +often far from obvious to inexperienced users. + +Therefore, we disable the COMPAT_VDSO menu entry entirely. However, +COMPAT_VDSO operation can still be enabled via bootparam and sysctl +interfaces. Consequently, we must also disable the ability to select +COMPAT_VDSO operation at boot or runtime. Here we patch the kernel so +that selecting COMPAT_VDSO operation at boot/runtime has no effect if +conflicting PaX options are enabled, leaving VDSO_ENABLED operation +intact. + +Closes bug: http://bugs.gentoo.org/show_bug.cgi?id=210138 + +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -1215,16 +1215,7 @@ config HOTPLUG_CPU + + config COMPAT_VDSO + def_bool n +- prompt "Compat VDSO support" + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC +- help +- Map the 32-bit VDSO to the predictable old-style address too. +- ---help--- +- Say N here if you are running a sufficiently recent glibc +- version (2.3.3 or later), to remove the high-mapped +- VDSO mapping and to exclusively use the randomized VDSO. +- +- If unsure, say Y. + + endmenu + +--- a/arch/x86/vdso/vdso32-setup.c ++++ b/arch/x86/vdso/vdso32-setup.c +@@ -333,17 +333,21 @@ int arch_setup_additional_pages(struct l + + map_compat_vdso(compat); + ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF) + if (compat) + addr = VDSO_HIGH_BASE; + else { ++#endif + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE); + if (IS_ERR_VALUE(addr)) { + ret = addr; + goto up_fail; + } ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF) + } + + if (compat_uses_vma || !compat) { ++#endif + /* + * MAYWRITE to allow gdb to COW and set breakpoints + * +@@ -361,7 +365,9 @@ int arch_setup_additional_pages(struct l + + if (ret) + goto up_fail; ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF) + } ++#endif + + current->mm->context.vdso = addr; + current_thread_info()->sysenter_return = diff --git a/pkgs/core/kernel/patches/linux-2.6.31.1-scsi.h-fix-1.patch b/pkgs/core/kernel/patches/linux-2.6.31.1-scsi.h-fix-1.patch new file mode 100644 index 0000000..7ff5ef0 --- /dev/null +++ b/pkgs/core/kernel/patches/linux-2.6.31.1-scsi.h-fix-1.patch @@ -0,0 +1,19 @@ +diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h +index 084478e..dfcfaab 100644 +--- a/include/scsi/scsi.h ++++ b/include/scsi/scsi.h +@@ -142,10 +142,10 @@ struct scsi_cmnd; + + /* defined in T10 SCSI Primary Commands-2 (SPC2) */ + struct scsi_varlen_cdb_hdr { +- u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */ +- u8 control; +- u8 misc[5]; +- u8 additional_cdb_length; /* total cdb length - 8 */ ++ __u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */ ++ __u8 control; ++ __u8 misc[5]; ++ __u8 additional_cdb_length; /* total cdb length - 8 */ + __be16 service_action; + /* service specific data follows */ + }; diff --git a/pkgs/core/kernel/patches/reiser4-for-2.6.31.1.patch b/pkgs/core/kernel/patches/reiser4-for-2.6.31.1.patch new file mode 100644 index 0000000..a4dca5f --- /dev/null +++ b/pkgs/core/kernel/patches/reiser4-for-2.6.31.1.patch @@ -0,0 +1,78369 @@ +diff -urN linux-2.6.30.orig/Documentation/Changes linux-2.6.30/Documentation/Changes +--- linux-2.6.30.orig/Documentation/Changes 2009-03-24 00:12:14.000000000 +0100 ++++ linux-2.6.30/Documentation/Changes 2009-06-22 16:08:11.000000000 +0200 +@@ -36,6 +36,7 @@ + o e2fsprogs 1.41.4 # e2fsck -V + o jfsutils 1.1.3 # fsck.jfs -V + o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs ++o reiser4progs 1.0.0 # fsck.reiser4 -V + o xfsprogs 2.6.0 # xfs_db -V + o squashfs-tools 4.0 # mksquashfs -version + o btrfs-progs 0.18 # btrfsck +@@ -147,6 +148,13 @@ + versions of mkreiserfs, resize_reiserfs, debugreiserfs and + reiserfsck. These utils work on both i386 and alpha platforms. + ++Reiser4progs ++------------ ++ ++The reiser4progs package contains utilities for the reiser4 file system. ++Detailed instructions are provided in the README file located at: ++<ftp://ftp.namesys.com/pub/reiser4progs/README>. ++ + Xfsprogs + -------- + +@@ -325,6 +333,10 @@ + ------------- + o <http://www.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.6.3.tar.gz> + ++Reiser4progs ++------------ ++o <ftp://ftp.namesys.com/pub/reiser4progs/> ++ + Xfsprogs + -------- + o <ftp://oss.sgi.com/projects/xfs/download/> +diff -urN linux-2.6.30.orig/Documentation/filesystems/reiser4.txt linux-2.6.30/Documentation/filesystems/reiser4.txt +--- linux-2.6.30.orig/Documentation/filesystems/reiser4.txt 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/Documentation/filesystems/reiser4.txt 2009-06-22 16:08:11.000000000 +0200 +@@ -0,0 +1,75 @@ ++Reiser4 filesystem ++================== ++Reiser4 is a file system based on dancing tree algorithms, and is ++described at http://www.namesys.com ++ ++ ++References ++========== ++web page http://namesys.com/v4/v4.html ++source code ftp://ftp.namesys.com/pub/reiser4-for-2.6/ ++userland tools ftp://ftp.namesys.com/pub/reiser4progs/ ++install page http://www.namesys.com/install_v4.html ++ ++Compile options ++=============== ++Enable reiser4 debug mode ++ This checks everything imaginable while reiser4 ++ runs ++ ++Mount options ++============= ++tmgr.atom_max_size=N ++ Atoms containing more than N blocks will be forced to commit. ++ N is decimal. ++ Default is nr_free_pagecache_pages() / 2 at mount time. ++ ++tmgr.atom_max_age=N ++ Atoms older than N seconds will be forced to commit. N is decimal. ++ Default is 600. ++ ++tmgr.atom_max_flushers=N ++ Limit of concurrent flushers for one atom. 0 means no limit. ++ Default is 0. ++ ++tree.cbk_cache.nr_slots=N ++ Number of slots in the cbk cache. ++ ++flush.relocate_threshold=N ++ If flush finds more than N adjacent dirty leaf-level blocks it ++ will force them to be relocated. ++ Default is 64. ++ ++flush.relocate_distance=N ++ If flush finds can find a block allocation closer than at most ++ N from the preceder it will relocate to that position. ++ Default is 64. ++ ++flush.scan_maxnodes=N ++ The maximum number of nodes to scan left on a level during ++ flush. ++ Default is 10000. ++ ++optimal_io_size=N ++ Preferred IO size. This value is used to set st_blksize of ++ struct stat. ++ Default is 65536. ++ ++bsdgroups ++ Turn on BSD-style gid assignment. ++ ++32bittimes ++ By default file in reiser4 have 64 bit timestamps. Files ++ created when filesystem is mounted with 32bittimes mount ++ option will get 32 bit timestamps. ++ ++mtflush ++ Turn off concurrent flushing. ++ ++nopseudo ++ Disable pseudo files support. See ++ http://namesys.com/v4/pseudo.html for more about pseudo files. ++ ++dont_load_bitmap ++ Don't load all bitmap blocks at mount time, it is useful for ++ machines with tiny RAM and large disks. +diff -urN linux-2.6.30.orig/fs/fs-writeback.c linux-2.6.30/fs/fs-writeback.c +--- linux-2.6.30.orig/fs/fs-writeback.c 2009-06-23 00:20:39.000000000 +0200 ++++ linux-2.6.30/fs/fs-writeback.c 2009-06-22 16:08:13.000000000 +0200 +@@ -593,7 +593,10 @@ + static void sync_sb_inodes(struct super_block *sb, + struct writeback_control *wbc) + { +- generic_sync_sb_inodes(sb, wbc); ++ if (sb->s_op->sync_inodes) ++ sb->s_op->sync_inodes(sb, wbc); ++ else ++ generic_sync_sb_inodes(sb, wbc); + } + + /* +diff -urN linux-2.6.30.orig/fs/Kconfig linux-2.6.30/fs/Kconfig +--- linux-2.6.30.orig/fs/Kconfig 2009-06-23 00:20:39.000000000 +0200 ++++ linux-2.6.30/fs/Kconfig 2009-06-22 16:08:13.000000000 +0200 +@@ -27,6 +27,7 @@ + default y if EXT4_FS=y && EXT4_FS_XATTR + default m if EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4_FS_XATTR + ++source "fs/reiser4/Kconfig" + source "fs/reiserfs/Kconfig" + source "fs/jfs/Kconfig" + +diff -urN linux-2.6.30.orig/fs/Makefile linux-2.6.30/fs/Makefile +--- linux-2.6.30.orig/fs/Makefile 2009-06-23 00:20:39.000000000 +0200 ++++ linux-2.6.30/fs/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -65,6 +65,7 @@ + # Do not add any filesystems before this line + obj-$(CONFIG_FSCACHE) += fscache/ + obj-$(CONFIG_REISERFS_FS) += reiserfs/ ++obj-$(CONFIG_REISER4_FS) += reiser4/ + obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 + obj-$(CONFIG_EXT2_FS) += ext2/ + # We place ext4 after ext2 so plain ext2 root fs's are mounted using ext2 +diff -urN linux-2.6.30.orig/fs/reiser4/as_ops.c linux-2.6.30/fs/reiser4/as_ops.c +--- linux-2.6.30.orig/fs/reiser4/as_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/as_ops.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,337 @@ ++/* Copyright 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Interface to VFS. Reiser4 address_space_operations are defined here. */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "coord.h" ++#include "plugin/item/item.h" ++#include "plugin/file/file.h" ++#include "plugin/security/perm.h" ++#include "plugin/disk_format/disk_format.h" ++#include "plugin/plugin.h" ++#include "plugin/plugin_set.h" ++#include "plugin/object.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree.h" ++#include "vfs_ops.h" ++#include "inode.h" ++#include "page_cache.h" ++#include "ktxnmgrd.h" ++#include "super.h" ++#include "reiser4.h" ++#include "entd.h" ++ ++#include <linux/profile.h> ++#include <linux/types.h> ++#include <linux/mount.h> ++#include <linux/vfs.h> ++#include <linux/mm.h> ++#include <linux/buffer_head.h> ++#include <linux/dcache.h> ++#include <linux/list.h> ++#include <linux/pagemap.h> ++#include <linux/slab.h> ++#include <linux/seq_file.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/writeback.h> ++#include <linux/backing-dev.h> ++#include <linux/quotaops.h> ++#include <linux/security.h> ++ ++/* address space operations */ ++ ++/** ++ * reiser4_set_page_dirty - set dirty bit, tag in page tree, dirty accounting ++ * @page: page to be dirtied ++ * ++ * Operation of struct address_space_operations. This implementation is used by ++ * unix and cryptcompress file plugins. ++ * ++ * This is called when reiser4 page gets dirtied outside of reiser4, for ++ * example, when dirty bit is moved from pte to physical page. ++ * ++ * Tags page in the mapping's page tree with special tag so that it is possible ++ * to do all the reiser4 specific work wrt dirty pages (jnode creation, ++ * capturing by an atom) later because it can not be done in the contexts where ++ * set_page_dirty is called. ++ */ ++int reiser4_set_page_dirty(struct page *page) ++{ ++ /* this page can be unformatted only */ ++ assert("vs-1734", (page->mapping && ++ page->mapping->host && ++ reiser4_get_super_fake(page->mapping->host->i_sb) != ++ page->mapping->host && ++ reiser4_get_cc_fake(page->mapping->host->i_sb) != ++ page->mapping->host && ++ reiser4_get_bitmap_fake(page->mapping->host->i_sb) != ++ page->mapping->host)); ++ return __set_page_dirty_nobuffers(page); ++} ++ ++/* ->invalidatepage method for reiser4 */ ++ ++/* ++ * this is called for each truncated page from ++ * truncate_inode_pages()->truncate_{complete,partial}_page(). ++ * ++ * At the moment of call, page is under lock, and outstanding io (if any) has ++ * completed. ++ */ ++ ++/** ++ * reiser4_invalidatepage ++ * @page: page to invalidate ++ * @offset: starting offset for partial invalidation ++ * ++ */ ++void reiser4_invalidatepage(struct page *page, unsigned long offset) ++{ ++ int ret = 0; ++ reiser4_context *ctx; ++ struct inode *inode; ++ jnode *node; ++ ++ /* ++ * This is called to truncate file's page. ++ * ++ * Originally, reiser4 implemented truncate in a standard way ++ * (vmtruncate() calls ->invalidatepage() on all truncated pages ++ * first, then file system ->truncate() call-back is invoked). ++ * ++ * This lead to the problem when ->invalidatepage() was called on a ++ * page with jnode that was captured into atom in ASTAGE_PRE_COMMIT ++ * process. That is, truncate was bypassing transactions. To avoid ++ * this, try_capture_page_to_invalidate() call was added here. ++ * ++ * After many troubles with vmtruncate() based truncate (including ++ * races with flush, tail conversion, etc.) it was re-written in the ++ * top-to-bottom style: items are killed in reiser4_cut_tree_object() ++ * and pages belonging to extent are invalidated in kill_hook_extent(). ++ * So probably now additional call to capture is not needed here. ++ */ ++ ++ assert("nikita-3137", PageLocked(page)); ++ assert("nikita-3138", !PageWriteback(page)); ++ inode = page->mapping->host; ++ ++ /* ++ * ->invalidatepage() should only be called for the unformatted ++ * jnodes. Destruction of all other types of jnodes is performed ++ * separately. But, during some corner cases (like handling errors ++ * during mount) it is simpler to let ->invalidatepage to be called on ++ * them. Check for this, and do nothing. ++ */ ++ if (reiser4_get_super_fake(inode->i_sb) == inode) ++ return; ++ if (reiser4_get_cc_fake(inode->i_sb) == inode) ++ return; ++ if (reiser4_get_bitmap_fake(inode->i_sb) == inode) ++ return; ++ assert("vs-1426", PagePrivate(page)); ++ assert("vs-1427", ++ page->mapping == jnode_get_mapping(jnode_by_page(page))); ++ assert("", jprivate(page) != NULL); ++ assert("", ergo(inode_file_plugin(inode) != ++ file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID), ++ offset == 0)); ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return; ++ ++ node = jprivate(page); ++ spin_lock_jnode(node); ++ if (!(node->state & ((1 << JNODE_DIRTY) | (1 << JNODE_FLUSH_QUEUED) | ++ (1 << JNODE_WRITEBACK) | (1 << JNODE_OVRWR)))) { ++ /* there is not need to capture */ ++ jref(node); ++ JF_SET(node, JNODE_HEARD_BANSHEE); ++ page_clear_jnode(page, node); ++ reiser4_uncapture_jnode(node); ++ unhash_unformatted_jnode(node); ++ jput(node); ++ reiser4_exit_context(ctx); ++ return; ++ } ++ spin_unlock_jnode(node); ++ ++ /* capture page being truncated. */ ++ ret = try_capture_page_to_invalidate(page); ++ if (ret != 0) ++ warning("nikita-3141", "Cannot capture: %i", ret); ++ ++ if (offset == 0) { ++ /* remove jnode from transaction and detach it from page. */ ++ jref(node); ++ JF_SET(node, JNODE_HEARD_BANSHEE); ++ /* page cannot be detached from jnode concurrently, because it ++ * is locked */ ++ reiser4_uncapture_page(page); ++ ++ /* this detaches page from jnode, so that jdelete will not try ++ * to lock page which is already locked */ ++ spin_lock_jnode(node); ++ page_clear_jnode(page, node); ++ spin_unlock_jnode(node); ++ unhash_unformatted_jnode(node); ++ ++ jput(node); ++ } ++ ++ reiser4_exit_context(ctx); ++} ++ ++/* help function called from reiser4_releasepage(). It returns true if jnode ++ * can be detached from its page and page released. */ ++int jnode_is_releasable(jnode * node/* node to check */) ++{ ++ assert("nikita-2781", node != NULL); ++ assert_spin_locked(&(node->guard)); ++ assert_spin_locked(&(node->load)); ++ ++ /* is some thread is currently using jnode page, later cannot be ++ * detached */ ++ if (atomic_read(&node->d_count) != 0) ++ return 0; ++ ++ assert("vs-1214", !jnode_is_loaded(node)); ++ ++ /* ++ * can only release page if real block number is assigned to it. Simple ++ * check for ->atom wouldn't do, because it is possible for node to be ++ * clean, not it atom yet, and still having fake block number. For ++ * example, node just created in jinit_new(). ++ */ ++ if (reiser4_blocknr_is_fake(jnode_get_block(node))) ++ return 0; ++ ++ /* ++ * pages prepared for write can not be released anyway, so avoid ++ * detaching jnode from the page ++ */ ++ if (JF_ISSET(node, JNODE_WRITE_PREPARED)) ++ return 0; ++ ++ /* ++ * dirty jnode cannot be released. It can however be submitted to disk ++ * as part of early flushing, but only after getting flush-prepped. ++ */ ++ if (JF_ISSET(node, JNODE_DIRTY)) ++ return 0; ++ ++ /* overwrite set is only written by log writer. */ ++ if (JF_ISSET(node, JNODE_OVRWR)) ++ return 0; ++ ++ /* jnode is already under writeback */ ++ if (JF_ISSET(node, JNODE_WRITEBACK)) ++ return 0; ++ ++ /* don't flush bitmaps or journal records */ ++ if (!jnode_is_znode(node) && !jnode_is_unformatted(node)) ++ return 0; ++ ++ return 1; ++} ++ ++/* ++ * ->releasepage method for reiser4 ++ * ++ * This is called by VM scanner when it comes across clean page. What we have ++ * to do here is to check whether page can really be released (freed that is) ++ * and if so, detach jnode from it and remove page from the page cache. ++ * ++ * Check for releasability is done by releasable() function. ++ */ ++int reiser4_releasepage(struct page *page, gfp_t gfp UNUSED_ARG) ++{ ++ jnode *node; ++ ++ assert("nikita-2257", PagePrivate(page)); ++ assert("nikita-2259", PageLocked(page)); ++ assert("nikita-2892", !PageWriteback(page)); ++ assert("nikita-3019", reiser4_schedulable()); ++ ++ /* NOTE-NIKITA: this can be called in the context of reiser4 call. It ++ is not clear what to do in this case. A lot of deadlocks seems be ++ possible. */ ++ ++ node = jnode_by_page(page); ++ assert("nikita-2258", node != NULL); ++ assert("reiser4-4", page->mapping != NULL); ++ assert("reiser4-5", page->mapping->host != NULL); ++ ++ if (PageDirty(page)) ++ return 0; ++ ++ /* extra page reference is used by reiser4 to protect ++ * jnode<->page link from this ->releasepage(). */ ++ if (page_count(page) > 3) ++ return 0; ++ ++ /* releasable() needs jnode lock, because it looks at the jnode fields ++ * and we need jload_lock here to avoid races with jload(). */ ++ spin_lock_jnode(node); ++ spin_lock(&(node->load)); ++ if (jnode_is_releasable(node)) { ++ struct address_space *mapping; ++ ++ mapping = page->mapping; ++ jref(node); ++ /* there is no need to synchronize against ++ * jnode_extent_write() here, because pages seen by ++ * jnode_extent_write() are !releasable(). */ ++ page_clear_jnode(page, node); ++ spin_unlock(&(node->load)); ++ spin_unlock_jnode(node); ++ ++ /* we are under memory pressure so release jnode also. */ ++ jput(node); ++ ++ return 1; ++ } else { ++ spin_unlock(&(node->load)); ++ spin_unlock_jnode(node); ++ assert("nikita-3020", reiser4_schedulable()); ++ return 0; ++ } ++} ++ ++int reiser4_readpage(struct file *file, struct page *page) ++{ ++ assert("edward-1533", PageLocked(page)); ++ assert("edward-1534", !PageUptodate(page)); ++ assert("edward-1535", page->mapping && page->mapping->host); ++ ++ return inode_file_plugin(page->mapping->host)->readpage(file, page); ++} ++ ++int reiser4_readpages(struct file *file, struct address_space *mapping, ++ struct list_head *pages, unsigned nr_pages) ++{ ++ return inode_file_plugin(mapping->host)->readpages(file, mapping, ++ pages, nr_pages); ++} ++ ++int reiser4_writepages(struct address_space *mapping, ++ struct writeback_control *wbc) ++{ ++ return inode_file_plugin(mapping->host)->writepages(mapping, wbc); ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/block_alloc.c linux-2.6.30/fs/reiser4/block_alloc.c +--- linux-2.6.30.orig/fs/reiser4/block_alloc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/block_alloc.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1142 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++reiser4/README */ ++ ++#include "debug.h" ++#include "dformat.h" ++#include "plugin/plugin.h" ++#include "txnmgr.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree.h" ++#include "super.h" ++ ++#include <linux/types.h> /* for __u?? */ ++#include <linux/fs.h> /* for struct super_block */ ++#include <linux/spinlock.h> ++ ++/* THE REISER4 DISK SPACE RESERVATION SCHEME. */ ++ ++/* We need to be able to reserve enough disk space to ensure that an atomic ++ operation will have enough disk space to flush (see flush.c and ++ http://namesys.com/v4/v4.html) and commit it once it is started. ++ ++ In our design a call for reserving disk space may fail but not an actual ++ block allocation. ++ ++ All free blocks, already allocated blocks, and all kinds of reserved blocks ++ are counted in different per-fs block counters. ++ ++ A reiser4 super block's set of block counters currently is: ++ ++ free -- free blocks, ++ used -- already allocated blocks, ++ ++ grabbed -- initially reserved for performing an fs operation, those blocks ++ are taken from free blocks, then grabbed disk space leaks from grabbed ++ blocks counter to other counters like "fake allocated", "flush ++ reserved", "used", the rest of not used grabbed space is returned to ++ free space at the end of fs operation; ++ ++ fake allocated -- counts all nodes without real disk block numbers assigned, ++ we have separate accounting for formatted and unformatted ++ nodes (for easier debugging); ++ ++ flush reserved -- disk space needed for flushing and committing an atom. ++ Each dirty already allocated block could be written as a ++ part of atom's overwrite set or as a part of atom's ++ relocate set. In both case one additional block is needed, ++ it is used as a wandered block if we do overwrite or as a ++ new location for a relocated block. ++ ++ In addition, blocks in some states are counted on per-thread and per-atom ++ basis. A reiser4 context has a counter of blocks grabbed by this transaction ++ and the sb's grabbed blocks counter is a sum of grabbed blocks counter values ++ of each reiser4 context. Each reiser4 atom has a counter of "flush reserved" ++ blocks, which are reserved for flush processing and atom commit. */ ++ ++/* AN EXAMPLE: suppose we insert new item to the reiser4 tree. We estimate ++ number of blocks to grab for most expensive case of balancing when the leaf ++ node we insert new item to gets split and new leaf node is allocated. ++ ++ So, we need to grab blocks for ++ ++ 1) one block for possible dirtying the node we insert an item to. That block ++ would be used for node relocation at flush time or for allocating of a ++ wandered one, it depends what will be a result (what set, relocate or ++ overwrite the node gets assigned to) of the node processing by the flush ++ algorithm. ++ ++ 2) one block for either allocating a new node, or dirtying of right or left ++ clean neighbor, only one case may happen. ++ ++ VS-FIXME-HANS: why can only one case happen? I would expect to see dirtying ++ of left neighbor, right neighbor, current node, and creation of new node. ++ Have I forgotten something? email me. ++ ++ These grabbed blocks are counted in both reiser4 context "grabbed blocks" ++ counter and in the fs-wide one (both ctx->grabbed_blocks and ++ sbinfo->blocks_grabbed get incremented by 2), sb's free blocks counter is ++ decremented by 2. ++ ++ Suppose both two blocks were spent for dirtying of an already allocated clean ++ node (one block went from "grabbed" to "flush reserved") and for new block ++ allocating (one block went from "grabbed" to "fake allocated formatted"). ++ ++ Inserting of a child pointer to the parent node caused parent node to be ++ split, the balancing code takes care about this grabbing necessary space ++ immediately by calling reiser4_grab with BA_RESERVED flag set which means ++ "can use the 5% reserved disk space". ++ ++ At this moment insertion completes and grabbed blocks (if they were not used) ++ should be returned to the free space counter. ++ ++ However the atom life-cycle is not completed. The atom had one "flush ++ reserved" block added by our insertion and the new fake allocated node is ++ counted as a "fake allocated formatted" one. The atom has to be fully ++ processed by flush before commit. Suppose that the flush moved the first, ++ already allocated node to the atom's overwrite list, the new fake allocated ++ node, obviously, went into the atom relocate set. The reiser4 flush ++ allocates the new node using one unit from "fake allocated formatted" ++ counter, the log writer uses one from "flush reserved" for wandered block ++ allocation. ++ ++ And, it is not the end. When the wandered block is deallocated after the ++ atom gets fully played (see wander.c for term description), the disk space ++ occupied for it is returned to free blocks. */ ++ ++/* BLOCK NUMBERS */ ++ ++/* Any reiser4 node has a block number assigned to it. We use these numbers for ++ indexing in hash tables, so if a block has not yet been assigned a location ++ on disk we need to give it a temporary fake block number. ++ ++ Current implementation of reiser4 uses 64-bit integers for block numbers. We ++ use highest bit in 64-bit block number to distinguish fake and real block ++ numbers. So, only 63 bits may be used to addressing of real device ++ blocks. That "fake" block numbers space is divided into subspaces of fake ++ block numbers for data blocks and for shadow (working) bitmap blocks. ++ ++ Fake block numbers for data blocks are generated by a cyclic counter, which ++ gets incremented after each real block allocation. We assume that it is ++ impossible to overload this counter during one transaction life. */ ++ ++/* Initialize a blocknr hint. */ ++void reiser4_blocknr_hint_init(reiser4_blocknr_hint * hint) ++{ ++ memset(hint, 0, sizeof(reiser4_blocknr_hint)); ++} ++ ++/* Release any resources of a blocknr hint. */ ++void reiser4_blocknr_hint_done(reiser4_blocknr_hint * hint UNUSED_ARG) ++{ ++/* No resources should be freed in current blocknr_hint implementation. */ ++} ++ ++/* see above for explanation of fake block number. */ ++/* Audited by: green(2002.06.11) */ ++int reiser4_blocknr_is_fake(const reiser4_block_nr * da) ++{ ++ /* The reason for not simply returning result of '&' operation is that ++ while return value is (possibly 32bit) int, the reiser4_block_nr is ++ at least 64 bits long, and high bit (which is the only possible ++ non zero bit after the masking) would be stripped off */ ++ return (*da & REISER4_FAKE_BLOCKNR_BIT_MASK) ? 1 : 0; ++} ++ ++/* Static functions for <reiser4 super block>/<reiser4 context> block counters ++ arithmetic. Mostly, they are isolated to not to code same assertions in ++ several places. */ ++static void sub_from_ctx_grabbed(reiser4_context * ctx, __u64 count) ++{ ++ BUG_ON(ctx->grabbed_blocks < count); ++ assert("zam-527", ctx->grabbed_blocks >= count); ++ ctx->grabbed_blocks -= count; ++} ++ ++static void add_to_ctx_grabbed(reiser4_context * ctx, __u64 count) ++{ ++ ctx->grabbed_blocks += count; ++} ++ ++static void sub_from_sb_grabbed(reiser4_super_info_data * sbinfo, __u64 count) ++{ ++ assert("zam-525", sbinfo->blocks_grabbed >= count); ++ sbinfo->blocks_grabbed -= count; ++} ++ ++/* Decrease the counter of block reserved for flush in super block. */ ++static void ++sub_from_sb_flush_reserved(reiser4_super_info_data * sbinfo, __u64 count) ++{ ++ assert("vpf-291", sbinfo->blocks_flush_reserved >= count); ++ sbinfo->blocks_flush_reserved -= count; ++} ++ ++static void ++sub_from_sb_fake_allocated(reiser4_super_info_data * sbinfo, __u64 count, ++ reiser4_ba_flags_t flags) ++{ ++ if (flags & BA_FORMATTED) { ++ assert("zam-806", sbinfo->blocks_fake_allocated >= count); ++ sbinfo->blocks_fake_allocated -= count; ++ } else { ++ assert("zam-528", ++ sbinfo->blocks_fake_allocated_unformatted >= count); ++ sbinfo->blocks_fake_allocated_unformatted -= count; ++ } ++} ++ ++static void sub_from_sb_used(reiser4_super_info_data * sbinfo, __u64 count) ++{ ++ assert("zam-530", ++ sbinfo->blocks_used >= count + sbinfo->min_blocks_used); ++ sbinfo->blocks_used -= count; ++} ++ ++static void ++sub_from_cluster_reserved(reiser4_super_info_data * sbinfo, __u64 count) ++{ ++ assert("edward-501", sbinfo->blocks_clustered >= count); ++ sbinfo->blocks_clustered -= count; ++} ++ ++/* Increase the counter of block reserved for flush in atom. */ ++static void add_to_atom_flush_reserved_nolock(txn_atom * atom, __u32 count) ++{ ++ assert("zam-772", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ atom->flush_reserved += count; ++} ++ ++/* Decrease the counter of block reserved for flush in atom. */ ++static void sub_from_atom_flush_reserved_nolock(txn_atom * atom, __u32 count) ++{ ++ assert("zam-774", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ assert("nikita-2790", atom->flush_reserved >= count); ++ atom->flush_reserved -= count; ++} ++ ++/* super block has 6 counters: free, used, grabbed, fake allocated ++ (formatted and unformatted) and flush reserved. Their sum must be ++ number of blocks on a device. This function checks this */ ++int reiser4_check_block_counters(const struct super_block *super) ++{ ++ __u64 sum; ++ ++ sum = reiser4_grabbed_blocks(super) + reiser4_free_blocks(super) + ++ reiser4_data_blocks(super) + reiser4_fake_allocated(super) + ++ reiser4_fake_allocated_unformatted(super) + reiser4_flush_reserved(super) + ++ reiser4_clustered_blocks(super); ++ if (reiser4_block_count(super) != sum) { ++ printk("super block counters: " ++ "used %llu, free %llu, " ++ "grabbed %llu, fake allocated (formatetd %llu, unformatted %llu), " ++ "reserved %llu, clustered %llu, sum %llu, must be (block count) %llu\n", ++ (unsigned long long)reiser4_data_blocks(super), ++ (unsigned long long)reiser4_free_blocks(super), ++ (unsigned long long)reiser4_grabbed_blocks(super), ++ (unsigned long long)reiser4_fake_allocated(super), ++ (unsigned long long) ++ reiser4_fake_allocated_unformatted(super), ++ (unsigned long long)reiser4_flush_reserved(super), ++ (unsigned long long)reiser4_clustered_blocks(super), ++ (unsigned long long)sum, ++ (unsigned long long)reiser4_block_count(super)); ++ return 0; ++ } ++ return 1; ++} ++ ++/* Adjust "working" free blocks counter for number of blocks we are going to ++ allocate. Record number of grabbed blocks in fs-wide and per-thread ++ counters. This function should be called before bitmap scanning or ++ allocating fake block numbers ++ ++ @super -- pointer to reiser4 super block; ++ @count -- number of blocks we reserve; ++ ++ @return -- 0 if success, -ENOSPC, if all ++ free blocks are preserved or already allocated. ++*/ ++ ++static int ++reiser4_grab(reiser4_context * ctx, __u64 count, reiser4_ba_flags_t flags) ++{ ++ __u64 free_blocks; ++ int ret = 0, use_reserved = flags & BA_RESERVED; ++ reiser4_super_info_data *sbinfo; ++ ++ assert("vs-1276", ctx == get_current_context()); ++ ++ /* Do not grab anything on ro-mounted fs. */ ++ if (rofs_super(ctx->super)) { ++ ctx->grab_enabled = 0; ++ return 0; ++ } ++ ++ sbinfo = get_super_private(ctx->super); ++ ++ spin_lock_reiser4_super(sbinfo); ++ ++ free_blocks = sbinfo->blocks_free; ++ ++ if ((use_reserved && free_blocks < count) || ++ (!use_reserved && free_blocks < count + sbinfo->blocks_reserved)) { ++ ret = RETERR(-ENOSPC); ++ goto unlock_and_ret; ++ } ++ ++ add_to_ctx_grabbed(ctx, count); ++ ++ sbinfo->blocks_grabbed += count; ++ sbinfo->blocks_free -= count; ++ ++#if REISER4_DEBUG ++ if (ctx->grabbed_initially == 0) ++ ctx->grabbed_initially = count; ++#endif ++ ++ assert("nikita-2986", reiser4_check_block_counters(ctx->super)); ++ ++ /* disable grab space in current context */ ++ ctx->grab_enabled = 0; ++ ++unlock_and_ret: ++ spin_unlock_reiser4_super(sbinfo); ++ ++ return ret; ++} ++ ++int reiser4_grab_space(__u64 count, reiser4_ba_flags_t flags) ++{ ++ int ret; ++ reiser4_context *ctx; ++ ++ assert("nikita-2964", ergo(flags & BA_CAN_COMMIT, ++ lock_stack_isclean(get_current_lock_stack ++ ()))); ++ ctx = get_current_context(); ++ if (!(flags & BA_FORCE) && !is_grab_enabled(ctx)) ++ return 0; ++ ++ ret = reiser4_grab(ctx, count, flags); ++ if (ret == -ENOSPC) { ++ ++ /* Trying to commit the all transactions if BA_CAN_COMMIT flag ++ present */ ++ if (flags & BA_CAN_COMMIT) { ++ txnmgr_force_commit_all(ctx->super, 0); ++ ctx->grab_enabled = 1; ++ ret = reiser4_grab(ctx, count, flags); ++ } ++ } ++ /* ++ * allocation from reserved pool cannot fail. This is severe error. ++ */ ++ assert("nikita-3005", ergo(flags & BA_RESERVED, ret == 0)); ++ return ret; ++} ++ ++/* ++ * SPACE RESERVED FOR UNLINK/TRUNCATE ++ * ++ * Unlink and truncate require space in transaction (to update stat data, at ++ * least). But we don't want rm(1) to fail with "No space on device" error. ++ * ++ * Solution is to reserve 5% of disk space for truncates and ++ * unlinks. Specifically, normal space grabbing requests don't grab space from ++ * reserved area. Only requests with BA_RESERVED bit in flags are allowed to ++ * drain it. Per super block delete mutex is used to allow only one ++ * thread at a time to grab from reserved area. ++ * ++ * Grabbing from reserved area should always be performed with BA_CAN_COMMIT ++ * flag. ++ * ++ */ ++ ++int reiser4_grab_reserved(struct super_block *super, ++ __u64 count, reiser4_ba_flags_t flags) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(super); ++ ++ assert("nikita-3175", flags & BA_CAN_COMMIT); ++ ++ /* Check the delete mutex already taken by us, we assume that ++ * reading of machine word is atomic. */ ++ if (sbinfo->delete_mutex_owner == current) { ++ if (reiser4_grab_space ++ (count, (flags | BA_RESERVED) & ~BA_CAN_COMMIT)) { ++ warning("zam-1003", ++ "nested call of grab_reserved fails count=(%llu)", ++ (unsigned long long)count); ++ reiser4_release_reserved(super); ++ return RETERR(-ENOSPC); ++ } ++ return 0; ++ } ++ ++ if (reiser4_grab_space(count, flags)) { ++ mutex_lock(&sbinfo->delete_mutex); ++ assert("nikita-2929", sbinfo->delete_mutex_owner == NULL); ++ sbinfo->delete_mutex_owner = current; ++ ++ if (reiser4_grab_space(count, flags | BA_RESERVED)) { ++ warning("zam-833", ++ "reserved space is not enough (%llu)", ++ (unsigned long long)count); ++ reiser4_release_reserved(super); ++ return RETERR(-ENOSPC); ++ } ++ } ++ return 0; ++} ++ ++void reiser4_release_reserved(struct super_block *super) ++{ ++ reiser4_super_info_data *info; ++ ++ info = get_super_private(super); ++ if (info->delete_mutex_owner == current) { ++ info->delete_mutex_owner = NULL; ++ mutex_unlock(&info->delete_mutex); ++ } ++} ++ ++static reiser4_super_info_data *grabbed2fake_allocated_head(int count) ++{ ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ ctx = get_current_context(); ++ sub_from_ctx_grabbed(ctx, count); ++ ++ sbinfo = get_super_private(ctx->super); ++ spin_lock_reiser4_super(sbinfo); ++ ++ sub_from_sb_grabbed(sbinfo, count); ++ /* return sbinfo locked */ ++ return sbinfo; ++} ++ ++/* is called after @count fake block numbers are allocated and pointer to ++ those blocks are inserted into tree. */ ++static void grabbed2fake_allocated_formatted(void) ++{ ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = grabbed2fake_allocated_head(1); ++ sbinfo->blocks_fake_allocated++; ++ ++ assert("vs-922", reiser4_check_block_counters(reiser4_get_current_sb())); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++/** ++ * grabbed2fake_allocated_unformatted ++ * @count: ++ * ++ */ ++static void grabbed2fake_allocated_unformatted(int count) ++{ ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = grabbed2fake_allocated_head(count); ++ sbinfo->blocks_fake_allocated_unformatted += count; ++ ++ assert("vs-9221", reiser4_check_block_counters(reiser4_get_current_sb())); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++void grabbed2cluster_reserved(int count) ++{ ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ ctx = get_current_context(); ++ sub_from_ctx_grabbed(ctx, count); ++ ++ sbinfo = get_super_private(ctx->super); ++ spin_lock_reiser4_super(sbinfo); ++ ++ sub_from_sb_grabbed(sbinfo, count); ++ sbinfo->blocks_clustered += count; ++ ++ assert("edward-504", reiser4_check_block_counters(ctx->super)); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++void cluster_reserved2grabbed(int count) ++{ ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ ctx = get_current_context(); ++ ++ sbinfo = get_super_private(ctx->super); ++ spin_lock_reiser4_super(sbinfo); ++ ++ sub_from_cluster_reserved(sbinfo, count); ++ sbinfo->blocks_grabbed += count; ++ ++ assert("edward-505", reiser4_check_block_counters(ctx->super)); ++ ++ spin_unlock_reiser4_super(sbinfo); ++ add_to_ctx_grabbed(ctx, count); ++} ++ ++void cluster_reserved2free(int count) ++{ ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ cluster_reserved2grabbed(count); ++ grabbed2free(ctx, sbinfo, count); ++} ++ ++static DEFINE_SPINLOCK(fake_lock); ++static reiser4_block_nr fake_gen = 0; ++ ++/** ++ * assign_fake_blocknr ++ * @blocknr: ++ * @count: ++ * ++ * Obtain a fake block number for new node which will be used to refer to ++ * this newly allocated node until real allocation is done. ++ */ ++static void assign_fake_blocknr(reiser4_block_nr *blocknr, int count) ++{ ++ spin_lock(&fake_lock); ++ *blocknr = fake_gen; ++ fake_gen += count; ++ spin_unlock(&fake_lock); ++ ++ BUG_ON(*blocknr & REISER4_BLOCKNR_STATUS_BIT_MASK); ++ /**blocknr &= ~REISER4_BLOCKNR_STATUS_BIT_MASK;*/ ++ *blocknr |= REISER4_UNALLOCATED_STATUS_VALUE; ++ assert("zam-394", zlook(current_tree, blocknr) == NULL); ++} ++ ++int assign_fake_blocknr_formatted(reiser4_block_nr * blocknr) ++{ ++ assign_fake_blocknr(blocknr, 1); ++ grabbed2fake_allocated_formatted(); ++ return 0; ++} ++ ++/** ++ * fake_blocknrs_unformatted ++ * @count: number of fake numbers to get ++ * ++ * Allocates @count fake block numbers which will be assigned to jnodes ++ */ ++reiser4_block_nr fake_blocknr_unformatted(int count) ++{ ++ reiser4_block_nr blocknr; ++ ++ assign_fake_blocknr(&blocknr, count); ++ grabbed2fake_allocated_unformatted(count); ++ ++ return blocknr; ++} ++ ++/* adjust sb block counters, if real (on-disk) block allocation immediately ++ follows grabbing of free disk space. */ ++static void grabbed2used(reiser4_context *ctx, reiser4_super_info_data *sbinfo, ++ __u64 count) ++{ ++ sub_from_ctx_grabbed(ctx, count); ++ ++ spin_lock_reiser4_super(sbinfo); ++ ++ sub_from_sb_grabbed(sbinfo, count); ++ sbinfo->blocks_used += count; ++ ++ assert("nikita-2679", reiser4_check_block_counters(ctx->super)); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++/* adjust sb block counters when @count unallocated blocks get mapped to disk */ ++static void fake_allocated2used(reiser4_super_info_data *sbinfo, __u64 count, ++ reiser4_ba_flags_t flags) ++{ ++ spin_lock_reiser4_super(sbinfo); ++ ++ sub_from_sb_fake_allocated(sbinfo, count, flags); ++ sbinfo->blocks_used += count; ++ ++ assert("nikita-2680", ++ reiser4_check_block_counters(reiser4_get_current_sb())); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++static void flush_reserved2used(txn_atom * atom, __u64 count) ++{ ++ reiser4_super_info_data *sbinfo; ++ ++ assert("zam-787", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ ++ sub_from_atom_flush_reserved_nolock(atom, (__u32) count); ++ ++ sbinfo = get_current_super_private(); ++ spin_lock_reiser4_super(sbinfo); ++ ++ sub_from_sb_flush_reserved(sbinfo, count); ++ sbinfo->blocks_used += count; ++ ++ assert("zam-789", ++ reiser4_check_block_counters(reiser4_get_current_sb())); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++/* update the per fs blocknr hint default value. */ ++void ++update_blocknr_hint_default(const struct super_block *s, ++ const reiser4_block_nr * block) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(s); ++ ++ assert("nikita-3342", !reiser4_blocknr_is_fake(block)); ++ ++ spin_lock_reiser4_super(sbinfo); ++ if (*block < sbinfo->block_count) { ++ sbinfo->blocknr_hint_default = *block; ++ } else { ++ warning("zam-676", ++ "block number %llu is too large to be used in a blocknr hint\n", ++ (unsigned long long)*block); ++ dump_stack(); ++ DEBUGON(1); ++ } ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++/* get current value of the default blocknr hint. */ ++void get_blocknr_hint_default(reiser4_block_nr * result) ++{ ++ reiser4_super_info_data *sbinfo = get_current_super_private(); ++ ++ spin_lock_reiser4_super(sbinfo); ++ *result = sbinfo->blocknr_hint_default; ++ assert("zam-677", *result < sbinfo->block_count); ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++/* Allocate "real" disk blocks by calling a proper space allocation plugin ++ * method. Blocks are allocated in one contiguous disk region. The plugin ++ * independent part accounts blocks by subtracting allocated amount from grabbed ++ * or fake block counter and add the same amount to the counter of allocated ++ * blocks. ++ * ++ * @hint -- a reiser4 blocknr hint object which contains further block ++ * allocation hints and parameters (search start, a stage of block ++ * which will be mapped to disk, etc.), ++ * @blk -- an out parameter for the beginning of the allocated region, ++ * @len -- in/out parameter, it should contain the maximum number of allocated ++ * blocks, after block allocation completes, it contains the length of ++ * allocated disk region. ++ * @flags -- see reiser4_ba_flags_t description. ++ * ++ * @return -- 0 if success, error code otherwise. ++ */ ++int ++reiser4_alloc_blocks(reiser4_blocknr_hint * hint, reiser4_block_nr * blk, ++ reiser4_block_nr * len, reiser4_ba_flags_t flags) ++{ ++ __u64 needed = *len; ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ int ret; ++ ++ assert("zam-986", hint != NULL); ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ /* For write-optimized data we use default search start value, which is ++ * close to last write location. */ ++ if (flags & BA_USE_DEFAULT_SEARCH_START) ++ get_blocknr_hint_default(&hint->blk); ++ ++ /* VITALY: allocator should grab this for internal/tx-lists/similar ++ only. */ ++/* VS-FIXME-HANS: why is this comment above addressed to vitaly (from vitaly)?*/ ++ if (hint->block_stage == BLOCK_NOT_COUNTED) { ++ ret = reiser4_grab_space_force(*len, flags); ++ if (ret != 0) ++ return ret; ++ } ++ ++ ret = ++ sa_alloc_blocks(reiser4_get_space_allocator(ctx->super), ++ hint, (int)needed, blk, len); ++ ++ if (!ret) { ++ assert("zam-680", *blk < reiser4_block_count(ctx->super)); ++ assert("zam-681", ++ *blk + *len <= reiser4_block_count(ctx->super)); ++ ++ if (flags & BA_PERMANENT) { ++ /* we assume that current atom exists at this moment */ ++ txn_atom *atom = get_current_atom_locked(); ++ atom->nr_blocks_allocated += *len; ++ spin_unlock_atom(atom); ++ } ++ ++ switch (hint->block_stage) { ++ case BLOCK_NOT_COUNTED: ++ case BLOCK_GRABBED: ++ grabbed2used(ctx, sbinfo, *len); ++ break; ++ case BLOCK_UNALLOCATED: ++ fake_allocated2used(sbinfo, *len, flags); ++ break; ++ case BLOCK_FLUSH_RESERVED: ++ { ++ txn_atom *atom = get_current_atom_locked(); ++ flush_reserved2used(atom, *len); ++ spin_unlock_atom(atom); ++ } ++ break; ++ default: ++ impossible("zam-531", "wrong block stage"); ++ } ++ } else { ++ assert("zam-821", ++ ergo(hint->max_dist == 0 ++ && !hint->backward, ret != -ENOSPC)); ++ if (hint->block_stage == BLOCK_NOT_COUNTED) ++ grabbed2free(ctx, sbinfo, needed); ++ } ++ ++ return ret; ++} ++ ++/* used -> fake_allocated -> grabbed -> free */ ++ ++/* adjust sb block counters when @count unallocated blocks get unmapped from ++ disk */ ++static void ++used2fake_allocated(reiser4_super_info_data * sbinfo, __u64 count, ++ int formatted) ++{ ++ spin_lock_reiser4_super(sbinfo); ++ ++ if (formatted) ++ sbinfo->blocks_fake_allocated += count; ++ else ++ sbinfo->blocks_fake_allocated_unformatted += count; ++ ++ sub_from_sb_used(sbinfo, count); ++ ++ assert("nikita-2681", ++ reiser4_check_block_counters(reiser4_get_current_sb())); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++static void ++used2flush_reserved(reiser4_super_info_data * sbinfo, txn_atom * atom, ++ __u64 count, reiser4_ba_flags_t flags UNUSED_ARG) ++{ ++ assert("nikita-2791", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ ++ add_to_atom_flush_reserved_nolock(atom, (__u32) count); ++ ++ spin_lock_reiser4_super(sbinfo); ++ ++ sbinfo->blocks_flush_reserved += count; ++ /*add_to_sb_flush_reserved(sbinfo, count); */ ++ sub_from_sb_used(sbinfo, count); ++ ++ assert("nikita-2681", ++ reiser4_check_block_counters(reiser4_get_current_sb())); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++/* disk space, virtually used by fake block numbers is counted as "grabbed" ++ again. */ ++static void ++fake_allocated2grabbed(reiser4_context * ctx, reiser4_super_info_data * sbinfo, ++ __u64 count, reiser4_ba_flags_t flags) ++{ ++ add_to_ctx_grabbed(ctx, count); ++ ++ spin_lock_reiser4_super(sbinfo); ++ ++ assert("nikita-2682", reiser4_check_block_counters(ctx->super)); ++ ++ sbinfo->blocks_grabbed += count; ++ sub_from_sb_fake_allocated(sbinfo, count, flags & BA_FORMATTED); ++ ++ assert("nikita-2683", reiser4_check_block_counters(ctx->super)); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++void fake_allocated2free(__u64 count, reiser4_ba_flags_t flags) ++{ ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ fake_allocated2grabbed(ctx, sbinfo, count, flags); ++ grabbed2free(ctx, sbinfo, count); ++} ++ ++void grabbed2free_mark(__u64 mark) ++{ ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ assert("nikita-3007", (__s64) mark >= 0); ++ assert("nikita-3006", ctx->grabbed_blocks >= mark); ++ grabbed2free(ctx, sbinfo, ctx->grabbed_blocks - mark); ++} ++ ++/** ++ * grabbed2free - adjust grabbed and free block counters ++ * @ctx: context to update grabbed block counter of ++ * @sbinfo: super block to update grabbed and free block counters of ++ * @count: number of blocks to adjust counters by ++ * ++ * Decreases context's and per filesystem's counters of grabbed ++ * blocks. Increases per filesystem's counter of free blocks. ++ */ ++void grabbed2free(reiser4_context *ctx, reiser4_super_info_data *sbinfo, ++ __u64 count) ++{ ++ sub_from_ctx_grabbed(ctx, count); ++ ++ spin_lock_reiser4_super(sbinfo); ++ ++ sub_from_sb_grabbed(sbinfo, count); ++ sbinfo->blocks_free += count; ++ assert("nikita-2684", reiser4_check_block_counters(ctx->super)); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++void grabbed2flush_reserved_nolock(txn_atom * atom, __u64 count) ++{ ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ assert("vs-1095", atom); ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ sub_from_ctx_grabbed(ctx, count); ++ ++ add_to_atom_flush_reserved_nolock(atom, count); ++ ++ spin_lock_reiser4_super(sbinfo); ++ ++ sbinfo->blocks_flush_reserved += count; ++ sub_from_sb_grabbed(sbinfo, count); ++ ++ assert("vpf-292", reiser4_check_block_counters(ctx->super)); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++void grabbed2flush_reserved(__u64 count) ++{ ++ txn_atom *atom = get_current_atom_locked(); ++ ++ grabbed2flush_reserved_nolock(atom, count); ++ ++ spin_unlock_atom(atom); ++} ++ ++void flush_reserved2grabbed(txn_atom * atom, __u64 count) ++{ ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ assert("nikita-2788", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ add_to_ctx_grabbed(ctx, count); ++ ++ sub_from_atom_flush_reserved_nolock(atom, (__u32) count); ++ ++ spin_lock_reiser4_super(sbinfo); ++ ++ sbinfo->blocks_grabbed += count; ++ sub_from_sb_flush_reserved(sbinfo, count); ++ ++ assert("vpf-292", reiser4_check_block_counters(ctx->super)); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++/** ++ * all_grabbed2free - releases all blocks grabbed in context ++ * ++ * Decreases context's and super block's grabbed block counters by number of ++ * blocks grabbed by current context and increases super block's free block ++ * counter correspondingly. ++ */ ++void all_grabbed2free(void) ++{ ++ reiser4_context *ctx = get_current_context(); ++ ++ grabbed2free(ctx, get_super_private(ctx->super), ctx->grabbed_blocks); ++} ++ ++/* adjust sb block counters if real (on-disk) blocks do not become unallocated ++ after freeing, @count blocks become "grabbed". */ ++static void ++used2grabbed(reiser4_context * ctx, reiser4_super_info_data * sbinfo, ++ __u64 count) ++{ ++ add_to_ctx_grabbed(ctx, count); ++ ++ spin_lock_reiser4_super(sbinfo); ++ ++ sbinfo->blocks_grabbed += count; ++ sub_from_sb_used(sbinfo, count); ++ ++ assert("nikita-2685", reiser4_check_block_counters(ctx->super)); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++/* this used to be done through used2grabbed and grabbed2free*/ ++static void used2free(reiser4_super_info_data * sbinfo, __u64 count) ++{ ++ spin_lock_reiser4_super(sbinfo); ++ ++ sbinfo->blocks_free += count; ++ sub_from_sb_used(sbinfo, count); ++ ++ assert("nikita-2685", ++ reiser4_check_block_counters(reiser4_get_current_sb())); ++ ++ spin_unlock_reiser4_super(sbinfo); ++} ++ ++#if REISER4_DEBUG ++ ++/* check "allocated" state of given block range */ ++static void ++reiser4_check_blocks(const reiser4_block_nr * start, ++ const reiser4_block_nr * len, int desired) ++{ ++ sa_check_blocks(start, len, desired); ++} ++ ++/* check "allocated" state of given block */ ++void reiser4_check_block(const reiser4_block_nr * block, int desired) ++{ ++ const reiser4_block_nr one = 1; ++ ++ reiser4_check_blocks(block, &one, desired); ++} ++ ++#endif ++ ++/* Blocks deallocation function may do an actual deallocation through space ++ plugin allocation or store deleted block numbers in atom's delete_set data ++ structure depend on @defer parameter. */ ++ ++/* if BA_DEFER bit is not turned on, @target_stage means the stage of blocks ++ which will be deleted from WORKING bitmap. They might be just unmapped from ++ disk, or freed but disk space is still grabbed by current thread, or these ++ blocks must not be counted in any reiser4 sb block counters, ++ see block_stage_t comment */ ++ ++/* BA_FORMATTED bit is only used when BA_DEFER in not present: it is used to ++ distinguish blocks allocated for unformatted and formatted nodes */ ++ ++int ++reiser4_dealloc_blocks(const reiser4_block_nr * start, ++ const reiser4_block_nr * len, ++ block_stage_t target_stage, reiser4_ba_flags_t flags) ++{ ++ txn_atom *atom = NULL; ++ int ret; ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ if (REISER4_DEBUG) { ++ assert("zam-431", *len != 0); ++ assert("zam-432", *start != 0); ++ assert("zam-558", !reiser4_blocknr_is_fake(start)); ++ ++ spin_lock_reiser4_super(sbinfo); ++ assert("zam-562", *start < sbinfo->block_count); ++ spin_unlock_reiser4_super(sbinfo); ++ } ++ ++ if (flags & BA_DEFER) { ++ blocknr_set_entry *bsep = NULL; ++ ++ /* storing deleted block numbers in a blocknr set ++ datastructure for further actual deletion */ ++ do { ++ atom = get_current_atom_locked(); ++ assert("zam-430", atom != NULL); ++ ++ ret = ++ blocknr_set_add_extent(atom, &atom->delete_set, ++ &bsep, start, len); ++ ++ if (ret == -ENOMEM) ++ return ret; ++ ++ /* This loop might spin at most two times */ ++ } while (ret == -E_REPEAT); ++ ++ assert("zam-477", ret == 0); ++ assert("zam-433", atom != NULL); ++ ++ spin_unlock_atom(atom); ++ ++ } else { ++ assert("zam-425", get_current_super_private() != NULL); ++ sa_dealloc_blocks(reiser4_get_space_allocator(ctx->super), ++ *start, *len); ++ ++ if (flags & BA_PERMANENT) { ++ /* These blocks were counted as allocated, we have to ++ * revert it back if allocation is discarded. */ ++ txn_atom *atom = get_current_atom_locked(); ++ atom->nr_blocks_allocated -= *len; ++ spin_unlock_atom(atom); ++ } ++ ++ switch (target_stage) { ++ case BLOCK_NOT_COUNTED: ++ assert("vs-960", flags & BA_FORMATTED); ++ /* VITALY: This is what was grabbed for ++ internal/tx-lists/similar only */ ++ used2free(sbinfo, *len); ++ break; ++ ++ case BLOCK_GRABBED: ++ used2grabbed(ctx, sbinfo, *len); ++ break; ++ ++ case BLOCK_UNALLOCATED: ++ used2fake_allocated(sbinfo, *len, flags & BA_FORMATTED); ++ break; ++ ++ case BLOCK_FLUSH_RESERVED:{ ++ txn_atom *atom; ++ ++ atom = get_current_atom_locked(); ++ used2flush_reserved(sbinfo, atom, *len, ++ flags & BA_FORMATTED); ++ spin_unlock_atom(atom); ++ break; ++ } ++ default: ++ impossible("zam-532", "wrong block stage"); ++ } ++ } ++ ++ return 0; ++} ++ ++/* wrappers for block allocator plugin methods */ ++int reiser4_pre_commit_hook(void) ++{ ++ assert("zam-502", get_current_super_private() != NULL); ++ sa_pre_commit_hook(); ++ return 0; ++} ++ ++/* an actor which applies delete set to block allocator data */ ++static int ++apply_dset(txn_atom * atom UNUSED_ARG, const reiser4_block_nr * a, ++ const reiser4_block_nr * b, void *data UNUSED_ARG) ++{ ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ __u64 len = 1; ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ assert("zam-877", atom->stage >= ASTAGE_PRE_COMMIT); ++ assert("zam-552", sbinfo != NULL); ++ ++ if (b != NULL) ++ len = *b; ++ ++ if (REISER4_DEBUG) { ++ spin_lock_reiser4_super(sbinfo); ++ ++ assert("zam-554", *a < reiser4_block_count(ctx->super)); ++ assert("zam-555", *a + len <= reiser4_block_count(ctx->super)); ++ ++ spin_unlock_reiser4_super(sbinfo); ++ } ++ ++ sa_dealloc_blocks(&sbinfo->space_allocator, *a, len); ++ /* adjust sb block counters */ ++ used2free(sbinfo, len); ++ return 0; ++} ++ ++void reiser4_post_commit_hook(void) ++{ ++ txn_atom *atom; ++ ++ atom = get_current_atom_locked(); ++ assert("zam-452", atom->stage == ASTAGE_POST_COMMIT); ++ spin_unlock_atom(atom); ++ ++ /* do the block deallocation which was deferred ++ until commit is done */ ++ blocknr_set_iterator(atom, &atom->delete_set, apply_dset, NULL, 1); ++ ++ assert("zam-504", get_current_super_private() != NULL); ++ sa_post_commit_hook(); ++} ++ ++void reiser4_post_write_back_hook(void) ++{ ++ assert("zam-504", get_current_super_private() != NULL); ++ ++ sa_post_commit_hook(); ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/block_alloc.h linux-2.6.30/fs/reiser4/block_alloc.h +--- linux-2.6.30.orig/fs/reiser4/block_alloc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/block_alloc.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,177 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#if !defined(__FS_REISER4_BLOCK_ALLOC_H__) ++#define __FS_REISER4_BLOCK_ALLOC_H__ ++ ++#include "dformat.h" ++#include "forward.h" ++ ++#include <linux/types.h> /* for __u?? */ ++#include <linux/fs.h> ++ ++/* Mask when is applied to given block number shows is that block number is a ++ fake one */ ++#define REISER4_FAKE_BLOCKNR_BIT_MASK 0x8000000000000000ULL ++/* Mask which isolates a type of object this fake block number was assigned ++ to */ ++#define REISER4_BLOCKNR_STATUS_BIT_MASK 0xC000000000000000ULL ++ ++/*result after applying the REISER4_BLOCKNR_STATUS_BIT_MASK should be compared ++ against these two values to understand is the object unallocated or bitmap ++ shadow object (WORKING BITMAP block, look at the plugin/space/bitmap.c) */ ++#define REISER4_UNALLOCATED_STATUS_VALUE 0xC000000000000000ULL ++#define REISER4_BITMAP_BLOCKS_STATUS_VALUE 0x8000000000000000ULL ++ ++/* specification how block allocation was counted in sb block counters */ ++typedef enum { ++ BLOCK_NOT_COUNTED = 0, /* reiser4 has no info about this block yet */ ++ BLOCK_GRABBED = 1, /* free space grabbed for further allocation ++ of this block */ ++ BLOCK_FLUSH_RESERVED = 2, /* block is reserved for flush needs. */ ++ BLOCK_UNALLOCATED = 3, /* block is used for existing in-memory object ++ ( unallocated formatted or unformatted ++ node) */ ++ BLOCK_ALLOCATED = 4 /* block is mapped to disk, real on-disk block ++ number assigned */ ++} block_stage_t; ++ ++/* a hint for block allocator */ ++struct reiser4_blocknr_hint { ++ /* FIXME: I think we want to add a longterm lock on the bitmap block ++ here. This is to prevent jnode_flush() calls from interleaving ++ allocations on the same bitmap, once a hint is established. */ ++ ++ /* search start hint */ ++ reiser4_block_nr blk; ++ /* if not zero, it is a region size we search for free blocks in */ ++ reiser4_block_nr max_dist; ++ /* level for allocation, may be useful have branch-level and higher ++ write-optimized. */ ++ tree_level level; ++ /* block allocator assumes that blocks, which will be mapped to disk, ++ are in this specified block_stage */ ++ block_stage_t block_stage; ++ /* If direction = 1 allocate blocks in backward direction from the end ++ * of disk to the beginning of disk. */ ++ unsigned int backward:1; ++ ++}; ++ ++/* These flags control block allocation/deallocation behavior */ ++enum reiser4_ba_flags { ++ /* do allocatations from reserved (5%) area */ ++ BA_RESERVED = (1 << 0), ++ ++ /* block allocator can do commit trying to recover free space */ ++ BA_CAN_COMMIT = (1 << 1), ++ ++ /* if operation will be applied to formatted block */ ++ BA_FORMATTED = (1 << 2), ++ ++ /* defer actual block freeing until transaction commit */ ++ BA_DEFER = (1 << 3), ++ ++ /* allocate blocks for permanent fs objects (formatted or unformatted), ++ not wandered of log blocks */ ++ BA_PERMANENT = (1 << 4), ++ ++ /* grab space even it was disabled */ ++ BA_FORCE = (1 << 5), ++ ++ /* use default start value for free blocks search. */ ++ BA_USE_DEFAULT_SEARCH_START = (1 << 6) ++}; ++ ++typedef enum reiser4_ba_flags reiser4_ba_flags_t; ++ ++extern void reiser4_blocknr_hint_init(reiser4_blocknr_hint * hint); ++extern void reiser4_blocknr_hint_done(reiser4_blocknr_hint * hint); ++extern void update_blocknr_hint_default(const struct super_block *, ++ const reiser4_block_nr *); ++extern void get_blocknr_hint_default(reiser4_block_nr *); ++ ++extern reiser4_block_nr reiser4_fs_reserved_space(struct super_block *super); ++ ++int assign_fake_blocknr_formatted(reiser4_block_nr *); ++reiser4_block_nr fake_blocknr_unformatted(int); ++ ++/* free -> grabbed -> fake_allocated -> used */ ++ ++int reiser4_grab_space(__u64 count, reiser4_ba_flags_t flags); ++void all_grabbed2free(void); ++void grabbed2free(reiser4_context * , reiser4_super_info_data * , __u64 count); ++void fake_allocated2free(__u64 count, reiser4_ba_flags_t flags); ++void grabbed2flush_reserved_nolock(txn_atom * atom, __u64 count); ++void grabbed2flush_reserved(__u64 count); ++int reiser4_alloc_blocks(reiser4_blocknr_hint * hint, ++ reiser4_block_nr * start, ++ reiser4_block_nr * len, reiser4_ba_flags_t flags); ++int reiser4_dealloc_blocks(const reiser4_block_nr *, ++ const reiser4_block_nr *, ++ block_stage_t, reiser4_ba_flags_t flags); ++ ++static inline int reiser4_alloc_block(reiser4_blocknr_hint * hint, ++ reiser4_block_nr * start, ++ reiser4_ba_flags_t flags) ++{ ++ reiser4_block_nr one = 1; ++ return reiser4_alloc_blocks(hint, start, &one, flags); ++} ++ ++static inline int reiser4_dealloc_block(const reiser4_block_nr * block, ++ block_stage_t stage, ++ reiser4_ba_flags_t flags) ++{ ++ const reiser4_block_nr one = 1; ++ return reiser4_dealloc_blocks(block, &one, stage, flags); ++} ++ ++#define reiser4_grab_space_force(count, flags) \ ++ reiser4_grab_space(count, flags | BA_FORCE) ++ ++extern void grabbed2free_mark(__u64 mark); ++extern int reiser4_grab_reserved(struct super_block *, ++ __u64, reiser4_ba_flags_t); ++extern void reiser4_release_reserved(struct super_block *super); ++ ++/* grabbed -> fake_allocated */ ++ ++/* fake_allocated -> used */ ++ ++/* used -> fake_allocated -> grabbed -> free */ ++ ++extern void flush_reserved2grabbed(txn_atom * atom, __u64 count); ++ ++extern int reiser4_blocknr_is_fake(const reiser4_block_nr * da); ++ ++extern void grabbed2cluster_reserved(int count); ++extern void cluster_reserved2grabbed(int count); ++extern void cluster_reserved2free(int count); ++ ++extern int reiser4_check_block_counters(const struct super_block *); ++ ++#if REISER4_DEBUG ++ ++extern void reiser4_check_block(const reiser4_block_nr *, int); ++ ++#else ++ ++# define reiser4_check_block(beg, val) noop ++ ++#endif ++ ++extern int reiser4_pre_commit_hook(void); ++extern void reiser4_post_commit_hook(void); ++extern void reiser4_post_write_back_hook(void); ++ ++#endif /* __FS_REISER4_BLOCK_ALLOC_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/blocknrset.c linux-2.6.30/fs/reiser4/blocknrset.c +--- linux-2.6.30.orig/fs/reiser4/blocknrset.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/blocknrset.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,371 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++reiser4/README */ ++ ++/* This file contains code for various block number sets used by the atom to ++ track the deleted set and wandered block mappings. */ ++ ++#include "debug.h" ++#include "dformat.h" ++#include "txnmgr.h" ++#include "context.h" ++ ++#include <linux/slab.h> ++ ++/* The proposed data structure for storing unordered block number sets is a ++ list of elements, each of which contains an array of block number or/and ++ array of block number pairs. That element called blocknr_set_entry is used ++ to store block numbers from the beginning and for extents from the end of ++ the data field (char data[...]). The ->nr_blocks and ->nr_pairs fields ++ count numbers of blocks and extents. ++ ++ +------------------- blocknr_set_entry->data ------------------+ ++ |block1|block2| ... <free space> ... |pair3|pair2|pair1| ++ +------------------------------------------------------------+ ++ ++ When current blocknr_set_entry is full, allocate a new one. */ ++ ++/* Usage examples: blocknr sets are used in reiser4 for storing atom's delete ++ * set (single blocks and block extents), in that case blocknr pair represent an ++ * extent; atom's wandered map is also stored as a blocknr set, blocknr pairs ++ * there represent a (real block) -> (wandered block) mapping. */ ++ ++/* Protection: blocknr sets belong to reiser4 atom, and ++ * their modifications are performed with the atom lock held */ ++ ++/* The total size of a blocknr_set_entry. */ ++#define BLOCKNR_SET_ENTRY_SIZE 128 ++ ++/* The number of blocks that can fit the blocknr data area. */ ++#define BLOCKNR_SET_ENTRIES_NUMBER \ ++ ((BLOCKNR_SET_ENTRY_SIZE - \ ++ 2 * sizeof(unsigned) - \ ++ sizeof(struct list_head)) / \ ++ sizeof(reiser4_block_nr)) ++ ++/* An entry of the blocknr_set */ ++struct blocknr_set_entry { ++ unsigned nr_singles; ++ unsigned nr_pairs; ++ struct list_head link; ++ reiser4_block_nr entries[BLOCKNR_SET_ENTRIES_NUMBER]; ++}; ++ ++/* A pair of blocks as recorded in the blocknr_set_entry data. */ ++struct blocknr_pair { ++ reiser4_block_nr a; ++ reiser4_block_nr b; ++}; ++ ++/* Return the number of blocknr slots available in a blocknr_set_entry. */ ++/* Audited by: green(2002.06.11) */ ++static unsigned bse_avail(blocknr_set_entry * bse) ++{ ++ unsigned used = bse->nr_singles + 2 * bse->nr_pairs; ++ ++ assert("jmacd-5088", BLOCKNR_SET_ENTRIES_NUMBER >= used); ++ cassert(sizeof(blocknr_set_entry) == BLOCKNR_SET_ENTRY_SIZE); ++ ++ return BLOCKNR_SET_ENTRIES_NUMBER - used; ++} ++ ++/* Initialize a blocknr_set_entry. */ ++static void bse_init(blocknr_set_entry *bse) ++{ ++ bse->nr_singles = 0; ++ bse->nr_pairs = 0; ++ INIT_LIST_HEAD(&bse->link); ++} ++ ++/* Allocate and initialize a blocknr_set_entry. */ ++/* Audited by: green(2002.06.11) */ ++static blocknr_set_entry *bse_alloc(void) ++{ ++ blocknr_set_entry *e; ++ ++ if ((e = (blocknr_set_entry *) kmalloc(sizeof(blocknr_set_entry), ++ reiser4_ctx_gfp_mask_get())) == NULL) ++ return NULL; ++ ++ bse_init(e); ++ ++ return e; ++} ++ ++/* Free a blocknr_set_entry. */ ++/* Audited by: green(2002.06.11) */ ++static void bse_free(blocknr_set_entry * bse) ++{ ++ kfree(bse); ++} ++ ++/* Add a block number to a blocknr_set_entry */ ++/* Audited by: green(2002.06.11) */ ++static void ++bse_put_single(blocknr_set_entry * bse, const reiser4_block_nr * block) ++{ ++ assert("jmacd-5099", bse_avail(bse) >= 1); ++ ++ bse->entries[bse->nr_singles++] = *block; ++} ++ ++/* Get a pair of block numbers */ ++/* Audited by: green(2002.06.11) */ ++static inline struct blocknr_pair *bse_get_pair(blocknr_set_entry * bse, ++ unsigned pno) ++{ ++ assert("green-1", BLOCKNR_SET_ENTRIES_NUMBER >= 2 * (pno + 1)); ++ ++ return (struct blocknr_pair *) (bse->entries + ++ BLOCKNR_SET_ENTRIES_NUMBER - ++ 2 * (pno + 1)); ++} ++ ++/* Add a pair of block numbers to a blocknr_set_entry */ ++/* Audited by: green(2002.06.11) */ ++static void ++bse_put_pair(blocknr_set_entry * bse, const reiser4_block_nr * a, ++ const reiser4_block_nr * b) ++{ ++ struct blocknr_pair *pair; ++ ++ assert("jmacd-5100", bse_avail(bse) >= 2 && a != NULL && b != NULL); ++ ++ pair = bse_get_pair(bse, bse->nr_pairs++); ++ ++ pair->a = *a; ++ pair->b = *b; ++} ++ ++/* Add either a block or pair of blocks to the block number set. The first ++ blocknr (@a) must be non-NULL. If @b is NULL a single blocknr is added, if ++ @b is non-NULL a pair is added. The block number set belongs to atom, and ++ the call is made with the atom lock held. There may not be enough space in ++ the current blocknr_set_entry. If new_bsep points to a non-NULL ++ blocknr_set_entry then it will be added to the blocknr_set and new_bsep ++ will be set to NULL. If new_bsep contains NULL then the atom lock will be ++ released and a new bse will be allocated in new_bsep. E_REPEAT will be ++ returned with the atom unlocked for the operation to be tried again. If ++ the operation succeeds, 0 is returned. If new_bsep is non-NULL and not ++ used during the call, it will be freed automatically. */ ++static int blocknr_set_add(txn_atom *atom, struct list_head *bset, ++ blocknr_set_entry **new_bsep, const reiser4_block_nr *a, ++ const reiser4_block_nr *b) ++{ ++ blocknr_set_entry *bse; ++ unsigned entries_needed; ++ ++ assert("jmacd-5101", a != NULL); ++ ++ entries_needed = (b == NULL) ? 1 : 2; ++ if (list_empty(bset) || ++ bse_avail(list_entry(bset->next, blocknr_set_entry, link)) < entries_needed) { ++ /* See if a bse was previously allocated. */ ++ if (*new_bsep == NULL) { ++ spin_unlock_atom(atom); ++ *new_bsep = bse_alloc(); ++ return (*new_bsep != NULL) ? -E_REPEAT : ++ RETERR(-ENOMEM); ++ } ++ ++ /* Put it on the head of the list. */ ++ list_add(&((*new_bsep)->link), bset); ++ ++ *new_bsep = NULL; ++ } ++ ++ /* Add the single or pair. */ ++ bse = list_entry(bset->next, blocknr_set_entry, link); ++ if (b == NULL) { ++ bse_put_single(bse, a); ++ } else { ++ bse_put_pair(bse, a, b); ++ } ++ ++ /* If new_bsep is non-NULL then there was an allocation race, free this ++ copy. */ ++ if (*new_bsep != NULL) { ++ bse_free(*new_bsep); ++ *new_bsep = NULL; ++ } ++ ++ return 0; ++} ++ ++/* Add an extent to the block set. If the length is 1, it is treated as a ++ single block (e.g., reiser4_set_add_block). */ ++/* Audited by: green(2002.06.11) */ ++/* Auditor note: Entire call chain cannot hold any spinlocks, because ++ kmalloc might schedule. The only exception is atom spinlock, which is ++ properly freed. */ ++int ++blocknr_set_add_extent(txn_atom * atom, ++ struct list_head *bset, ++ blocknr_set_entry ** new_bsep, ++ const reiser4_block_nr * start, ++ const reiser4_block_nr * len) ++{ ++ assert("jmacd-5102", start != NULL && len != NULL && *len > 0); ++ return blocknr_set_add(atom, bset, new_bsep, start, ++ *len == 1 ? NULL : len); ++} ++ ++/* Add a block pair to the block set. It adds exactly a pair, which is checked ++ * by an assertion that both arguments are not null.*/ ++/* Audited by: green(2002.06.11) */ ++/* Auditor note: Entire call chain cannot hold any spinlocks, because ++ kmalloc might schedule. The only exception is atom spinlock, which is ++ properly freed. */ ++int ++blocknr_set_add_pair(txn_atom * atom, ++ struct list_head *bset, ++ blocknr_set_entry ** new_bsep, const reiser4_block_nr * a, ++ const reiser4_block_nr * b) ++{ ++ assert("jmacd-5103", a != NULL && b != NULL); ++ return blocknr_set_add(atom, bset, new_bsep, a, b); ++} ++ ++/* Initialize a blocknr_set. */ ++void blocknr_set_init(struct list_head *bset) ++{ ++ INIT_LIST_HEAD(bset); ++} ++ ++/* Release the entries of a blocknr_set. */ ++void blocknr_set_destroy(struct list_head *bset) ++{ ++ blocknr_set_entry *bse; ++ ++ while (!list_empty(bset)) { ++ bse = list_entry(bset->next, blocknr_set_entry, link); ++ list_del_init(&bse->link); ++ bse_free(bse); ++ } ++} ++ ++/* Merge blocknr_set entries out of @from into @into. */ ++/* Audited by: green(2002.06.11) */ ++/* Auditor comments: This merge does not know if merged sets contain ++ blocks pairs (As for wandered sets) or extents, so it cannot really merge ++ overlapping ranges if there is some. So I believe it may lead to ++ some blocks being presented several times in one blocknr_set. To help ++ debugging such problems it might help to check for duplicate entries on ++ actual processing of this set. Testing this kind of stuff right here is ++ also complicated by the fact that these sets are not sorted and going ++ through whole set on each element addition is going to be CPU-heavy task */ ++void blocknr_set_merge(struct list_head *from, struct list_head *into) ++{ ++ blocknr_set_entry *bse_into = NULL; ++ ++ /* If @from is empty, no work to perform. */ ++ if (list_empty(from)) ++ return; ++ /* If @into is not empty, try merging partial-entries. */ ++ if (!list_empty(into)) { ++ ++ /* Neither set is empty, pop the front to members and try to ++ combine them. */ ++ blocknr_set_entry *bse_from; ++ unsigned into_avail; ++ ++ bse_into = list_entry(into->next, blocknr_set_entry, link); ++ list_del_init(&bse_into->link); ++ bse_from = list_entry(from->next, blocknr_set_entry, link); ++ list_del_init(&bse_from->link); ++ ++ /* Combine singles. */ ++ for (into_avail = bse_avail(bse_into); ++ into_avail != 0 && bse_from->nr_singles != 0; ++ into_avail -= 1) { ++ bse_put_single(bse_into, ++ &bse_from->entries[--bse_from-> ++ nr_singles]); ++ } ++ ++ /* Combine pairs. */ ++ for (; into_avail > 1 && bse_from->nr_pairs != 0; ++ into_avail -= 2) { ++ struct blocknr_pair *pair = ++ bse_get_pair(bse_from, --bse_from->nr_pairs); ++ bse_put_pair(bse_into, &pair->a, &pair->b); ++ } ++ ++ /* If bse_from is empty, delete it now. */ ++ if (bse_avail(bse_from) == BLOCKNR_SET_ENTRIES_NUMBER) { ++ bse_free(bse_from); ++ } else { ++ /* Otherwise, bse_into is full or nearly full (e.g., ++ it could have one slot avail and bse_from has one ++ pair left). Push it back onto the list. bse_from ++ becomes bse_into, which will be the new partial. */ ++ list_add(&bse_into->link, into); ++ bse_into = bse_from; ++ } ++ } ++ ++ /* Splice lists together. */ ++ list_splice_init(from, into->prev); ++ ++ /* Add the partial entry back to the head of the list. */ ++ if (bse_into != NULL) ++ list_add(&bse_into->link, into); ++} ++ ++/* Iterate over all blocknr set elements. */ ++int blocknr_set_iterator(txn_atom *atom, struct list_head *bset, ++ blocknr_set_actor_f actor, void *data, int delete) ++{ ++ ++ blocknr_set_entry *entry; ++ ++ assert("zam-429", atom != NULL); ++ assert("zam-430", atom_is_protected(atom)); ++ assert("zam-431", bset != 0); ++ assert("zam-432", actor != NULL); ++ ++ entry = list_entry(bset->next, blocknr_set_entry, link); ++ while (bset != &entry->link) { ++ blocknr_set_entry *tmp = list_entry(entry->link.next, blocknr_set_entry, link); ++ unsigned int i; ++ int ret; ++ ++ for (i = 0; i < entry->nr_singles; i++) { ++ ret = actor(atom, &entry->entries[i], NULL, data); ++ ++ /* We can't break a loop if delete flag is set. */ ++ if (ret != 0 && !delete) ++ return ret; ++ } ++ ++ for (i = 0; i < entry->nr_pairs; i++) { ++ struct blocknr_pair *ab; ++ ++ ab = bse_get_pair(entry, i); ++ ++ ret = actor(atom, &ab->a, &ab->b, data); ++ ++ if (ret != 0 && !delete) ++ return ret; ++ } ++ ++ if (delete) { ++ list_del(&entry->link); ++ bse_free(entry); ++ } ++ ++ entry = tmp; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/carry.c linux-2.6.30/fs/reiser4/carry.c +--- linux-2.6.30.orig/fs/reiser4/carry.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/carry.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1398 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++/* Functions to "carry" tree modification(s) upward. */ ++/* Tree is modified one level at a time. As we modify a level we accumulate a ++ set of changes that need to be propagated to the next level. We manage ++ node locking such that any searches that collide with carrying are ++ restarted, from the root if necessary. ++ ++ Insertion of a new item may result in items being moved among nodes and ++ this requires the delimiting key to be updated at the least common parent ++ of the nodes modified to preserve search tree invariants. Also, insertion ++ may require allocation of a new node. A pointer to the new node has to be ++ inserted into some node on the parent level, etc. ++ ++ Tree carrying is meant to be analogous to arithmetic carrying. ++ ++ A carry operation is always associated with some node (&carry_node). ++ ++ Carry process starts with some initial set of operations to be performed ++ and an initial set of already locked nodes. Operations are performed one ++ by one. Performing each single operation has following possible effects: ++ ++ - content of carry node associated with operation is modified ++ - new carry nodes are locked and involved into carry process on this level ++ - new carry operations are posted to the next level ++ ++ After all carry operations on this level are done, process is repeated for ++ the accumulated sequence on carry operations for the next level. This ++ starts by trying to lock (in left to right order) all carry nodes ++ associated with carry operations on the parent level. After this, we decide ++ whether more nodes are required on the left of already locked set. If so, ++ all locks taken on the parent level are released, new carry nodes are ++ added, and locking process repeats. ++ ++ It may happen that balancing process fails owing to unrecoverable error on ++ some of upper levels of a tree (possible causes are io error, failure to ++ allocate new node, etc.). In this case we should unmount the filesystem, ++ rebooting if it is the root, and possibly advise the use of fsck. ++ ++ USAGE: ++ ++ int some_tree_operation( znode *node, ... ) ++ { ++ // Allocate on a stack pool of carry objects: operations and nodes. ++ // Most carry processes will only take objects from here, without ++ // dynamic allocation. ++ ++I feel uneasy about this pool. It adds to code complexity, I understand why it ++exists, but.... -Hans ++ ++ carry_pool pool; ++ carry_level lowest_level; ++ carry_op *op; ++ ++ init_carry_pool( &pool ); ++ init_carry_level( &lowest_level, &pool ); ++ ++ // operation may be one of: ++ // COP_INSERT --- insert new item into node ++ // COP_CUT --- remove part of or whole node ++ // COP_PASTE --- increase size of item ++ // COP_DELETE --- delete pointer from parent node ++ // COP_UPDATE --- update delimiting key in least ++ // common ancestor of two ++ ++ op = reiser4_post_carry( &lowest_level, operation, node, 0 ); ++ if( IS_ERR( op ) || ( op == NULL ) ) { ++ handle error ++ } else { ++ // fill in remaining fields in @op, according to carry.h:carry_op ++ result = carry(&lowest_level, NULL); ++ } ++ done_carry_pool(&pool); ++ } ++ ++ When you are implementing node plugin method that participates in carry ++ (shifting, insertion, deletion, etc.), do the following: ++ ++ int foo_node_method(znode * node, ..., carry_level * todo) ++ { ++ carry_op *op; ++ ++ .... ++ ++ // note, that last argument to reiser4_post_carry() is non-null ++ // here, because @op is to be applied to the parent of @node, rather ++ // than to the @node itself as in the previous case. ++ ++ op = node_post_carry(todo, operation, node, 1); ++ // fill in remaining fields in @op, according to carry.h:carry_op ++ ++ .... ++ ++ } ++ ++ BATCHING: ++ ++ One of the main advantages of level-by-level balancing implemented here is ++ ability to batch updates on a parent level and to peform them more ++ efficiently as a result. ++ ++ Description To Be Done (TBD). ++ ++ DIFFICULTIES AND SUBTLE POINTS: ++ ++ 1. complex plumbing is required, because: ++ ++ a. effective allocation through pools is needed ++ ++ b. target of operation is not exactly known when operation is ++ posted. This is worked around through bitfields in &carry_node and ++ logic in lock_carry_node() ++ ++ c. of interaction with locking code: node should be added into sibling ++ list when pointer to it is inserted into its parent, which is some time ++ after node was created. Between these moments, node is somewhat in ++ suspended state and is only registered in the carry lists ++ ++ 2. whole balancing logic is implemented here, in particular, insertion ++ logic is coded in make_space(). ++ ++ 3. special cases like insertion (reiser4_add_tree_root()) or deletion ++ (reiser4_kill_tree_root()) of tree root and morphing of paste into insert ++ (insert_paste()) have to be handled. ++ ++ 4. there is non-trivial interdependency between allocation of new nodes ++ and almost everything else. This is mainly due to the (1.c) above. I shall ++ write about this later. ++ ++*/ ++ ++#include "forward.h" ++#include "debug.h" ++#include "key.h" ++#include "coord.h" ++#include "plugin/item/item.h" ++#include "plugin/item/extent.h" ++#include "plugin/node/node.h" ++#include "jnode.h" ++#include "znode.h" ++#include "tree_mod.h" ++#include "tree_walk.h" ++#include "block_alloc.h" ++#include "pool.h" ++#include "tree.h" ++#include "carry.h" ++#include "carry_ops.h" ++#include "super.h" ++#include "reiser4.h" ++ ++#include <linux/types.h> ++ ++/* level locking/unlocking */ ++static int lock_carry_level(carry_level * level); ++static void unlock_carry_level(carry_level * level, int failure); ++static void done_carry_level(carry_level * level); ++static void unlock_carry_node(carry_level * level, carry_node * node, int fail); ++ ++int lock_carry_node(carry_level * level, carry_node * node); ++int lock_carry_node_tail(carry_node * node); ++ ++/* carry processing proper */ ++static int carry_on_level(carry_level * doing, carry_level * todo); ++ ++static carry_op *add_op(carry_level * level, pool_ordering order, ++ carry_op * reference); ++ ++/* handlers for carry operations. */ ++ ++static void fatal_carry_error(carry_level * doing, int ecode); ++static int add_new_root(carry_level * level, carry_node * node, znode * fake); ++ ++static void print_level(const char *prefix, carry_level * level); ++ ++#if REISER4_DEBUG ++typedef enum { ++ CARRY_TODO, ++ CARRY_DOING ++} carry_queue_state; ++static int carry_level_invariant(carry_level * level, carry_queue_state state); ++#endif ++ ++/* main entry point for tree balancing. ++ ++ Tree carry performs operations from @doing and while doing so accumulates ++ information about operations to be performed on the next level ("carried" ++ to the parent level). Carried operations are performed, causing possibly ++ more operations to be carried upward etc. carry() takes care about ++ locking and pinning znodes while operating on them. ++ ++ For usage, see comment at the top of fs/reiser4/carry.c ++ ++*/ ++int reiser4_carry(carry_level * doing /* set of carry operations to be ++ * performed */ , ++ carry_level * done /* set of nodes, already performed ++ * at the previous level. ++ * NULL in most cases */) ++{ ++ int result = 0; ++ /* queue of new requests */ ++ carry_level *todo; ++ ON_DEBUG(STORE_COUNTERS); ++ ++ assert("nikita-888", doing != NULL); ++ BUG_ON(done != NULL); ++ ++ todo = doing + 1; ++ init_carry_level(todo, doing->pool); ++ ++ /* queue of requests preformed on the previous level */ ++ done = todo + 1; ++ init_carry_level(done, doing->pool); ++ ++ /* iterate until there is nothing more to do */ ++ while (result == 0 && doing->ops_num > 0) { ++ carry_level *tmp; ++ ++ /* at this point @done is locked. */ ++ /* repeat lock/do/unlock while ++ ++ (1) lock_carry_level() fails due to deadlock avoidance, or ++ ++ (2) carry_on_level() decides that more nodes have to ++ be involved. ++ ++ (3) some unexpected error occurred while balancing on the ++ upper levels. In this case all changes are rolled back. ++ ++ */ ++ while (1) { ++ result = lock_carry_level(doing); ++ if (result == 0) { ++ /* perform operations from @doing and ++ accumulate new requests in @todo */ ++ result = carry_on_level(doing, todo); ++ if (result == 0) ++ break; ++ else if (result != -E_REPEAT || ++ !doing->restartable) { ++ warning("nikita-1043", ++ "Fatal error during carry: %i", ++ result); ++ print_level("done", done); ++ print_level("doing", doing); ++ print_level("todo", todo); ++ /* do some rough stuff like aborting ++ all pending transcrashes and thus ++ pushing tree back to the consistent ++ state. Alternatvely, just panic. ++ */ ++ fatal_carry_error(doing, result); ++ return result; ++ } ++ } else if (result != -E_REPEAT) { ++ fatal_carry_error(doing, result); ++ return result; ++ } ++ unlock_carry_level(doing, 1); ++ } ++ /* at this point @done can be safely unlocked */ ++ done_carry_level(done); ++ ++ /* cyclically shift queues */ ++ tmp = done; ++ done = doing; ++ doing = todo; ++ todo = tmp; ++ init_carry_level(todo, doing->pool); ++ ++ /* give other threads chance to run */ ++ reiser4_preempt_point(); ++ } ++ done_carry_level(done); ++ ++ /* all counters, but x_refs should remain the same. x_refs can change ++ owing to transaction manager */ ++ ON_DEBUG(CHECK_COUNTERS); ++ return result; ++} ++ ++/* perform carry operations on given level. ++ ++ Optimizations proposed by pooh: ++ ++ (1) don't lock all nodes from queue at the same time. Lock nodes lazily as ++ required; ++ ++ (2) unlock node if there are no more operations to be performed upon it and ++ node didn't add any operation to @todo. This can be implemented by ++ attaching to each node two counters: counter of operaions working on this ++ node and counter and operations carried upward from this node. ++ ++*/ ++static int carry_on_level(carry_level * doing /* queue of carry operations to ++ * do on this level */ , ++ carry_level * todo /* queue where new carry ++ * operations to be performed on ++ * the * parent level are ++ * accumulated during @doing ++ * processing. */ ) ++{ ++ int result; ++ int (*f) (carry_op *, carry_level *, carry_level *); ++ carry_op *op; ++ carry_op *tmp_op; ++ ++ assert("nikita-1034", doing != NULL); ++ assert("nikita-1035", todo != NULL); ++ ++ /* @doing->nodes are locked. */ ++ ++ /* This function can be split into two phases: analysis and modification ++ ++ Analysis calculates precisely what items should be moved between ++ nodes. This information is gathered in some structures attached to ++ each carry_node in a @doing queue. Analysis also determines whether ++ new nodes are to be allocated etc. ++ ++ After analysis is completed, actual modification is performed. Here ++ we can take advantage of "batch modification": if there are several ++ operations acting on the same node, modifications can be performed ++ more efficiently when batched together. ++ ++ Above is an optimization left for the future. ++ */ ++ /* Important, but delayed optimization: it's possible to batch ++ operations together and perform them more efficiently as a ++ result. For example, deletion of several neighboring items from a ++ node can be converted to a single ->cut() operation. ++ ++ Before processing queue, it should be scanned and "mergeable" ++ operations merged. ++ */ ++ result = 0; ++ for_all_ops(doing, op, tmp_op) { ++ carry_opcode opcode; ++ ++ assert("nikita-1041", op != NULL); ++ opcode = op->op; ++ assert("nikita-1042", op->op < COP_LAST_OP); ++ f = op_dispatch_table[op->op].handler; ++ result = f(op, doing, todo); ++ /* locking can fail with -E_REPEAT. Any different error is fatal ++ and will be handled by fatal_carry_error() sledgehammer. ++ */ ++ if (result != 0) ++ break; ++ } ++ if (result == 0) { ++ carry_plugin_info info; ++ carry_node *scan; ++ carry_node *tmp_scan; ++ ++ info.doing = doing; ++ info.todo = todo; ++ ++ assert("nikita-3002", ++ carry_level_invariant(doing, CARRY_DOING)); ++ for_all_nodes(doing, scan, tmp_scan) { ++ znode *node; ++ ++ node = reiser4_carry_real(scan); ++ assert("nikita-2547", node != NULL); ++ if (node_is_empty(node)) { ++ result = ++ node_plugin_by_node(node)-> ++ prepare_removal(node, &info); ++ if (result != 0) ++ break; ++ } ++ } ++ } ++ return result; ++} ++ ++/* post carry operation ++ ++ This is main function used by external carry clients: node layout plugins ++ and tree operations to create new carry operation to be performed on some ++ level. ++ ++ New operation will be included in the @level queue. To actually perform it, ++ call carry( level, ... ). This function takes write lock on @node. Carry ++ manages all its locks by itself, don't worry about this. ++ ++ This function adds operation and node at the end of the queue. It is up to ++ caller to guarantee proper ordering of node queue. ++ ++*/ ++carry_op * reiser4_post_carry(carry_level * level /* queue where new operation ++ * is to be posted at */ , ++ carry_opcode op /* opcode of operation */ , ++ znode * node /* node on which this operation ++ * will operate */ , ++ int apply_to_parent_p /* whether operation will ++ * operate directly on @node ++ * or on it parent. */) ++{ ++ carry_op *result; ++ carry_node *child; ++ ++ assert("nikita-1046", level != NULL); ++ assert("nikita-1788", znode_is_write_locked(node)); ++ ++ result = add_op(level, POOLO_LAST, NULL); ++ if (IS_ERR(result)) ++ return result; ++ child = reiser4_add_carry(level, POOLO_LAST, NULL); ++ if (IS_ERR(child)) { ++ reiser4_pool_free(&level->pool->op_pool, &result->header); ++ return (carry_op *) child; ++ } ++ result->node = child; ++ result->op = op; ++ child->parent = apply_to_parent_p; ++ if (ZF_ISSET(node, JNODE_ORPHAN)) ++ child->left_before = 1; ++ child->node = node; ++ return result; ++} ++ ++/* initialize carry queue */ ++void init_carry_level(carry_level * level /* level to initialize */ , ++ carry_pool * pool /* pool @level will allocate objects ++ * from */ ) ++{ ++ assert("nikita-1045", level != NULL); ++ assert("nikita-967", pool != NULL); ++ ++ memset(level, 0, sizeof *level); ++ level->pool = pool; ++ ++ INIT_LIST_HEAD(&level->nodes); ++ INIT_LIST_HEAD(&level->ops); ++} ++ ++/* allocate carry pool and initialize pools within queue */ ++carry_pool *init_carry_pool(int size) ++{ ++ carry_pool *pool; ++ ++ assert("", size >= sizeof(carry_pool) + 3 * sizeof(carry_level)); ++ pool = kmalloc(size, reiser4_ctx_gfp_mask_get()); ++ if (pool == NULL) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ ++ reiser4_init_pool(&pool->op_pool, sizeof(carry_op), CARRIES_POOL_SIZE, ++ (char *)pool->op); ++ reiser4_init_pool(&pool->node_pool, sizeof(carry_node), ++ NODES_LOCKED_POOL_SIZE, (char *)pool->node); ++ return pool; ++} ++ ++/* finish with queue pools */ ++void done_carry_pool(carry_pool * pool/* pool to destroy */) ++{ ++ reiser4_done_pool(&pool->op_pool); ++ reiser4_done_pool(&pool->node_pool); ++ kfree(pool); ++} ++ ++/* add new carry node to the @level. ++ ++ Returns pointer to the new carry node allocated from pool. It's up to ++ callers to maintain proper order in the @level. Assumption is that if carry ++ nodes on one level are already sorted and modifications are peroformed from ++ left to right, carry nodes added on the parent level will be ordered ++ automatically. To control ordering use @order and @reference parameters. ++ ++*/ ++carry_node *reiser4_add_carry_skip(carry_level * level /* &carry_level to add ++ * node to */ , ++ pool_ordering order /* where to insert: ++ * at the beginning of ++ * @level, ++ * before @reference, ++ * after @reference, ++ * at the end of @level ++ */ , ++ carry_node * reference/* reference node for ++ * insertion */) ++{ ++ ON_DEBUG(carry_node * orig_ref = reference); ++ ++ if (order == POOLO_BEFORE) { ++ reference = find_left_carry(reference, level); ++ if (reference == NULL) ++ reference = list_entry(level->nodes.next, carry_node, ++ header.level_linkage); ++ else ++ reference = list_entry(reference->header.level_linkage.next, ++ carry_node, header.level_linkage); ++ } else if (order == POOLO_AFTER) { ++ reference = find_right_carry(reference, level); ++ if (reference == NULL) ++ reference = list_entry(level->nodes.prev, carry_node, ++ header.level_linkage); ++ else ++ reference = list_entry(reference->header.level_linkage.prev, ++ carry_node, header.level_linkage); ++ } ++ assert("nikita-2209", ++ ergo(orig_ref != NULL, ++ reiser4_carry_real(reference) == ++ reiser4_carry_real(orig_ref))); ++ return reiser4_add_carry(level, order, reference); ++} ++ ++carry_node *reiser4_add_carry(carry_level * level, /* carry_level to add ++ node to */ ++ pool_ordering order, /* where to insert: ++ * at the beginning of ++ * @level; ++ * before @reference; ++ * after @reference; ++ * at the end of @level ++ */ ++ carry_node * reference /* reference node for ++ * insertion */) ++{ ++ carry_node *result; ++ ++ result = ++ (carry_node *) reiser4_add_obj(&level->pool->node_pool, ++ &level->nodes, ++ order, &reference->header); ++ if (!IS_ERR(result) && (result != NULL)) ++ ++level->nodes_num; ++ return result; ++} ++ ++/** ++ * add new carry operation to the @level. ++ * ++ * Returns pointer to the new carry operations allocated from pool. It's up to ++ * callers to maintain proper order in the @level. To control ordering use ++ * @order and @reference parameters. ++ */ ++static carry_op *add_op(carry_level * level, /* &carry_level to add node to */ ++ pool_ordering order, /* where to insert: ++ * at the beginning of @level; ++ * before @reference; ++ * after @reference; ++ * at the end of @level */ ++ carry_op * reference /* reference node for insertion */) ++{ ++ carry_op *result; ++ ++ result = ++ (carry_op *) reiser4_add_obj(&level->pool->op_pool, &level->ops, ++ order, &reference->header); ++ if (!IS_ERR(result) && (result != NULL)) ++ ++level->ops_num; ++ return result; ++} ++ ++/** ++ * Return node on the right of which @node was created. ++ * ++ * Each node is created on the right of some existing node (or it is new root, ++ * which is special case not handled here). ++ * ++ * @node is new node created on some level, but not yet inserted into its ++ * parent, it has corresponding bit (JNODE_ORPHAN) set in zstate. ++ */ ++static carry_node *find_begetting_brother(carry_node * node,/* node to start ++ search from */ ++ carry_level * kin UNUSED_ARG ++ /* level to scan */) ++{ ++ carry_node *scan; ++ ++ assert("nikita-1614", node != NULL); ++ assert("nikita-1615", kin != NULL); ++ assert("nikita-1616", LOCK_CNT_GTZ(rw_locked_tree)); ++ assert("nikita-1619", ergo(reiser4_carry_real(node) != NULL, ++ ZF_ISSET(reiser4_carry_real(node), ++ JNODE_ORPHAN))); ++ for (scan = node;; ++ scan = list_entry(scan->header.level_linkage.prev, carry_node, ++ header.level_linkage)) { ++ assert("nikita-1617", &kin->nodes != &scan->header.level_linkage); ++ if ((scan->node != node->node) && ++ !ZF_ISSET(scan->node, JNODE_ORPHAN)) { ++ assert("nikita-1618", reiser4_carry_real(scan) != NULL); ++ break; ++ } ++ } ++ return scan; ++} ++ ++static cmp_t ++carry_node_cmp(carry_level * level, carry_node * n1, carry_node * n2) ++{ ++ assert("nikita-2199", n1 != NULL); ++ assert("nikita-2200", n2 != NULL); ++ ++ if (n1 == n2) ++ return EQUAL_TO; ++ while (1) { ++ n1 = carry_node_next(n1); ++ if (carry_node_end(level, n1)) ++ return GREATER_THAN; ++ if (n1 == n2) ++ return LESS_THAN; ++ } ++ impossible("nikita-2201", "End of level reached"); ++} ++ ++carry_node *find_carry_node(carry_level * level, const znode * node) ++{ ++ carry_node *scan; ++ carry_node *tmp_scan; ++ ++ assert("nikita-2202", level != NULL); ++ assert("nikita-2203", node != NULL); ++ ++ for_all_nodes(level, scan, tmp_scan) { ++ if (reiser4_carry_real(scan) == node) ++ return scan; ++ } ++ return NULL; ++} ++ ++znode *reiser4_carry_real(const carry_node * node) ++{ ++ assert("nikita-3061", node != NULL); ++ ++ return node->lock_handle.node; ++} ++ ++carry_node *insert_carry_node(carry_level * doing, carry_level * todo, ++ const znode * node) ++{ ++ carry_node *base; ++ carry_node *scan; ++ carry_node *tmp_scan; ++ carry_node *proj; ++ ++ base = find_carry_node(doing, node); ++ assert("nikita-2204", base != NULL); ++ ++ for_all_nodes(todo, scan, tmp_scan) { ++ proj = find_carry_node(doing, scan->node); ++ assert("nikita-2205", proj != NULL); ++ if (carry_node_cmp(doing, proj, base) != LESS_THAN) ++ break; ++ } ++ return scan; ++} ++ ++static carry_node *add_carry_atplace(carry_level * doing, carry_level * todo, ++ znode * node) ++{ ++ carry_node *reference; ++ ++ assert("nikita-2994", doing != NULL); ++ assert("nikita-2995", todo != NULL); ++ assert("nikita-2996", node != NULL); ++ ++ reference = insert_carry_node(doing, todo, node); ++ assert("nikita-2997", reference != NULL); ++ ++ return reiser4_add_carry(todo, POOLO_BEFORE, reference); ++} ++ ++/* like reiser4_post_carry(), but designed to be called from node plugin ++ methods. This function is different from reiser4_post_carry() in that it ++ finds proper place to insert node in the queue. */ ++carry_op *node_post_carry(carry_plugin_info * info /* carry parameters ++ * passed down to node ++ * plugin */ , ++ carry_opcode op /* opcode of operation */ , ++ znode * node /* node on which this ++ * operation will operate */ , ++ int apply_to_parent_p /* whether operation will ++ * operate directly on @node ++ * or on it parent. */ ) ++{ ++ carry_op *result; ++ carry_node *child; ++ ++ assert("nikita-2207", info != NULL); ++ assert("nikita-2208", info->todo != NULL); ++ ++ if (info->doing == NULL) ++ return reiser4_post_carry(info->todo, op, node, ++ apply_to_parent_p); ++ ++ result = add_op(info->todo, POOLO_LAST, NULL); ++ if (IS_ERR(result)) ++ return result; ++ child = add_carry_atplace(info->doing, info->todo, node); ++ if (IS_ERR(child)) { ++ reiser4_pool_free(&info->todo->pool->op_pool, &result->header); ++ return (carry_op *) child; ++ } ++ result->node = child; ++ result->op = op; ++ child->parent = apply_to_parent_p; ++ if (ZF_ISSET(node, JNODE_ORPHAN)) ++ child->left_before = 1; ++ child->node = node; ++ return result; ++} ++ ++/* lock all carry nodes in @level */ ++static int lock_carry_level(carry_level * level/* level to lock */) ++{ ++ int result; ++ carry_node *node; ++ carry_node *tmp_node; ++ ++ assert("nikita-881", level != NULL); ++ assert("nikita-2229", carry_level_invariant(level, CARRY_TODO)); ++ ++ /* lock nodes from left to right */ ++ result = 0; ++ for_all_nodes(level, node, tmp_node) { ++ result = lock_carry_node(level, node); ++ if (result != 0) ++ break; ++ } ++ return result; ++} ++ ++/* Synchronize delimiting keys between @node and its left neighbor. ++ ++ To reduce contention on dk key and simplify carry code, we synchronize ++ delimiting keys only when carry ultimately leaves tree level (carrying ++ changes upward) and unlocks nodes at this level. ++ ++ This function first finds left neighbor of @node and then updates left ++ neighbor's right delimiting key to conincide with least key in @node. ++ ++*/ ++ ++ON_DEBUG(extern atomic_t delim_key_version; ++ ) ++ ++static void sync_dkeys(znode * spot/* node to update */) ++{ ++ reiser4_key pivot; ++ reiser4_tree *tree; ++ ++ assert("nikita-1610", spot != NULL); ++ assert("nikita-1612", LOCK_CNT_NIL(rw_locked_dk)); ++ ++ tree = znode_get_tree(spot); ++ read_lock_tree(tree); ++ write_lock_dk(tree); ++ ++ assert("nikita-2192", znode_is_loaded(spot)); ++ ++ /* sync left delimiting key of @spot with key in its leftmost item */ ++ if (node_is_empty(spot)) ++ pivot = *znode_get_rd_key(spot); ++ else ++ leftmost_key_in_node(spot, &pivot); ++ ++ znode_set_ld_key(spot, &pivot); ++ ++ /* there can be sequence of empty nodes pending removal on the left of ++ @spot. Scan them and update their left and right delimiting keys to ++ match left delimiting key of @spot. Also, update right delimiting ++ key of first non-empty left neighbor. ++ */ ++ while (1) { ++ if (!ZF_ISSET(spot, JNODE_LEFT_CONNECTED)) ++ break; ++ ++ spot = spot->left; ++ if (spot == NULL) ++ break; ++ ++ znode_set_rd_key(spot, &pivot); ++ /* don't sink into the domain of another balancing */ ++ if (!znode_is_write_locked(spot)) ++ break; ++ if (ZF_ISSET(spot, JNODE_HEARD_BANSHEE)) ++ znode_set_ld_key(spot, &pivot); ++ else ++ break; ++ } ++ ++ write_unlock_dk(tree); ++ read_unlock_tree(tree); ++} ++ ++/* unlock all carry nodes in @level */ ++static void unlock_carry_level(carry_level * level /* level to unlock */ , ++ int failure /* true if unlocking owing to ++ * failure */ ) ++{ ++ carry_node *node; ++ carry_node *tmp_node; ++ ++ assert("nikita-889", level != NULL); ++ ++ if (!failure) { ++ znode *spot; ++ ++ spot = NULL; ++ /* update delimiting keys */ ++ for_all_nodes(level, node, tmp_node) { ++ if (reiser4_carry_real(node) != spot) { ++ spot = reiser4_carry_real(node); ++ sync_dkeys(spot); ++ } ++ } ++ } ++ ++ /* nodes can be unlocked in arbitrary order. In preemptible ++ environment it's better to unlock in reverse order of locking, ++ though. ++ */ ++ for_all_nodes_back(level, node, tmp_node) { ++ /* all allocated nodes should be already linked to their ++ parents at this moment. */ ++ assert("nikita-1631", ++ ergo(!failure, !ZF_ISSET(reiser4_carry_real(node), ++ JNODE_ORPHAN))); ++ ON_DEBUG(check_dkeys(reiser4_carry_real(node))); ++ unlock_carry_node(level, node, failure); ++ } ++ level->new_root = NULL; ++} ++ ++/* finish with @level ++ ++ Unlock nodes and release all allocated resources */ ++static void done_carry_level(carry_level * level/* level to finish */) ++{ ++ carry_node *node; ++ carry_node *tmp_node; ++ carry_op *op; ++ carry_op *tmp_op; ++ ++ assert("nikita-1076", level != NULL); ++ ++ unlock_carry_level(level, 0); ++ for_all_nodes(level, node, tmp_node) { ++ assert("nikita-2113", list_empty_careful(&node->lock_handle.locks_link)); ++ assert("nikita-2114", list_empty_careful(&node->lock_handle.owners_link)); ++ reiser4_pool_free(&level->pool->node_pool, &node->header); ++ } ++ for_all_ops(level, op, tmp_op) ++ reiser4_pool_free(&level->pool->op_pool, &op->header); ++} ++ ++/* helper function to complete locking of carry node ++ ++ Finish locking of carry node. There are several ways in which new carry ++ node can be added into carry level and locked. Normal is through ++ lock_carry_node(), but also from find_{left|right}_neighbor(). This ++ function factors out common final part of all locking scenarios. It ++ supposes that @node -> lock_handle is lock handle for lock just taken and ++ fills ->real_node from this lock handle. ++ ++*/ ++int lock_carry_node_tail(carry_node * node/* node to complete locking of */) ++{ ++ assert("nikita-1052", node != NULL); ++ assert("nikita-1187", reiser4_carry_real(node) != NULL); ++ assert("nikita-1188", !node->unlock); ++ ++ node->unlock = 1; ++ /* Load node content into memory and install node plugin by ++ looking at the node header. ++ ++ Most of the time this call is cheap because the node is ++ already in memory. ++ ++ Corresponding zrelse() is in unlock_carry_node() ++ */ ++ return zload(reiser4_carry_real(node)); ++} ++ ++/* lock carry node ++ ++ "Resolve" node to real znode, lock it and mark as locked. ++ This requires recursive locking of znodes. ++ ++ When operation is posted to the parent level, node it will be applied to is ++ not yet known. For example, when shifting data between two nodes, ++ delimiting has to be updated in parent or parents of nodes involved. But ++ their parents is not yet locked and, moreover said nodes can be reparented ++ by concurrent balancing. ++ ++ To work around this, carry operation is applied to special "carry node" ++ rather than to the znode itself. Carry node consists of some "base" or ++ "reference" znode and flags indicating how to get to the target of carry ++ operation (->real_node field of carry_node) from base. ++ ++*/ ++int lock_carry_node(carry_level * level /* level @node is in */ , ++ carry_node * node/* node to lock */) ++{ ++ int result; ++ znode *reference_point; ++ lock_handle lh; ++ lock_handle tmp_lh; ++ reiser4_tree *tree; ++ ++ assert("nikita-887", level != NULL); ++ assert("nikita-882", node != NULL); ++ ++ result = 0; ++ reference_point = node->node; ++ init_lh(&lh); ++ init_lh(&tmp_lh); ++ if (node->left_before) { ++ /* handling of new nodes, allocated on the previous level: ++ ++ some carry ops were propably posted from the new node, but ++ this node neither has parent pointer set, nor is ++ connected. This will be done in ->create_hook() for ++ internal item. ++ ++ No then less, parent of new node has to be locked. To do ++ this, first go to the "left" in the carry order. This ++ depends on the decision to always allocate new node on the ++ right of existing one. ++ ++ Loop handles case when multiple nodes, all orphans, were ++ inserted. ++ ++ Strictly speaking, taking tree lock is not necessary here, ++ because all nodes scanned by loop in ++ find_begetting_brother() are write-locked by this thread, ++ and thus, their sibling linkage cannot change. ++ ++ */ ++ tree = znode_get_tree(reference_point); ++ read_lock_tree(tree); ++ reference_point = find_begetting_brother(node, level)->node; ++ read_unlock_tree(tree); ++ assert("nikita-1186", reference_point != NULL); ++ } ++ if (node->parent && (result == 0)) { ++ result = ++ reiser4_get_parent(&tmp_lh, reference_point, ++ ZNODE_WRITE_LOCK); ++ if (result != 0) { ++ ; /* nothing */ ++ } else if (znode_get_level(tmp_lh.node) == 0) { ++ assert("nikita-1347", znode_above_root(tmp_lh.node)); ++ result = add_new_root(level, node, tmp_lh.node); ++ if (result == 0) { ++ reference_point = level->new_root; ++ move_lh(&lh, &node->lock_handle); ++ } ++ } else if ((level->new_root != NULL) ++ && (level->new_root != ++ znode_parent_nolock(reference_point))) { ++ /* parent of node exists, but this level aready ++ created different new root, so */ ++ warning("nikita-1109", ++ /* it should be "radicis", but tradition is ++ tradition. do banshees read latin? */ ++ "hodie natus est radici frater"); ++ result = -EIO; ++ } else { ++ move_lh(&lh, &tmp_lh); ++ reference_point = lh.node; ++ } ++ } ++ if (node->left && (result == 0)) { ++ assert("nikita-1183", node->parent); ++ assert("nikita-883", reference_point != NULL); ++ result = ++ reiser4_get_left_neighbor(&tmp_lh, reference_point, ++ ZNODE_WRITE_LOCK, ++ GN_CAN_USE_UPPER_LEVELS); ++ if (result == 0) { ++ done_lh(&lh); ++ move_lh(&lh, &tmp_lh); ++ reference_point = lh.node; ++ } ++ } ++ if (!node->parent && !node->left && !node->left_before) { ++ result = ++ longterm_lock_znode(&lh, reference_point, ZNODE_WRITE_LOCK, ++ ZNODE_LOCK_HIPRI); ++ } ++ if (result == 0) { ++ move_lh(&node->lock_handle, &lh); ++ result = lock_carry_node_tail(node); ++ } ++ done_lh(&tmp_lh); ++ done_lh(&lh); ++ return result; ++} ++ ++/* release a lock on &carry_node. ++ ++ Release if necessary lock on @node. This opearion is pair of ++ lock_carry_node() and is idempotent: you can call it more than once on the ++ same node. ++ ++*/ ++static void ++unlock_carry_node(carry_level * level, ++ carry_node * node /* node to be released */ , ++ int failure /* 0 if node is unlocked due ++ * to some error */ ) ++{ ++ znode *real_node; ++ ++ assert("nikita-884", node != NULL); ++ ++ real_node = reiser4_carry_real(node); ++ /* pair to zload() in lock_carry_node_tail() */ ++ zrelse(real_node); ++ if (node->unlock && (real_node != NULL)) { ++ assert("nikita-899", real_node == node->lock_handle.node); ++ longterm_unlock_znode(&node->lock_handle); ++ } ++ if (failure) { ++ if (node->deallocate && (real_node != NULL)) { ++ /* free node in bitmap ++ ++ Prepare node for removal. Last zput() will finish ++ with it. ++ */ ++ ZF_SET(real_node, JNODE_HEARD_BANSHEE); ++ } ++ if (node->free) { ++ assert("nikita-2177", ++ list_empty_careful(&node->lock_handle.locks_link)); ++ assert("nikita-2112", ++ list_empty_careful(&node->lock_handle.owners_link)); ++ reiser4_pool_free(&level->pool->node_pool, ++ &node->header); ++ } ++ } ++} ++ ++/* fatal_carry_error() - all-catching error handling function ++ ++ It is possible that carry faces unrecoverable error, like unability to ++ insert pointer at the internal level. Our simple solution is just panic in ++ this situation. More sophisticated things like attempt to remount ++ file-system as read-only can be implemented without much difficlties. ++ ++ It is believed, that: ++ ++ 1. in stead of panicking, all current transactions can be aborted rolling ++ system back to the consistent state. ++ ++Umm, if you simply panic without doing anything more at all, then all current ++transactions are aborted and the system is rolled back to a consistent state, ++by virtue of the design of the transactional mechanism. Well, wait, let's be ++precise. If an internal node is corrupted on disk due to hardware failure, ++then there may be no consistent state that can be rolled back to, so instead ++we should say that it will rollback the transactions, which barring other ++factors means rolling back to a consistent state. ++ ++# Nikita: there is a subtle difference between panic and aborting ++# transactions: machine doesn't reboot. Processes aren't killed. Processes ++# don't using reiser4 (not that we care about such processes), or using other ++# reiser4 mounts (about them we do care) will simply continue to run. With ++# some luck, even application using aborted file system can survive: it will ++# get some error, like EBADF, from each file descriptor on failed file system, ++# but applications that do care about tolerance will cope with this (squid ++# will). ++ ++It would be a nice feature though to support rollback without rebooting ++followed by remount, but this can wait for later versions. ++ ++ 2. once isolated transactions will be implemented it will be possible to ++ roll back offending transaction. ++ ++2. is additional code complexity of inconsistent value (it implies that a ++broken tree should be kept in operation), so we must think about it more ++before deciding if it should be done. -Hans ++ ++*/ ++static void fatal_carry_error(carry_level * doing UNUSED_ARG /* carry level ++ * where ++ * unrecoverable ++ * error ++ * occurred */ , ++ int ecode/* error code */) ++{ ++ assert("nikita-1230", doing != NULL); ++ assert("nikita-1231", ecode < 0); ++ ++ reiser4_panic("nikita-1232", "Carry failed: %i", ecode); ++} ++ ++/** ++ * Add new root to the tree ++ * ++ * This function itself only manages changes in carry structures and delegates ++ * all hard work (allocation of znode for new root, changes of parent and ++ * sibling pointers) to the reiser4_add_tree_root(). ++ * ++ * Locking: old tree root is locked by carry at this point. Fake znode is also ++ * locked. ++ */ ++static int add_new_root(carry_level * level,/* carry level in context of which ++ * operation is performed */ ++ carry_node * node, /* carry node for existing root */ ++ znode * fake /* "fake" znode already locked by ++ * us */) ++{ ++ int result; ++ ++ assert("nikita-1104", level != NULL); ++ assert("nikita-1105", node != NULL); ++ ++ assert("nikita-1403", znode_is_write_locked(node->node)); ++ assert("nikita-1404", znode_is_write_locked(fake)); ++ ++ /* trying to create new root. */ ++ /* @node is root and it's already locked by us. This ++ means that nobody else can be trying to add/remove ++ tree root right now. ++ */ ++ if (level->new_root == NULL) ++ level->new_root = reiser4_add_tree_root(node->node, fake); ++ if (!IS_ERR(level->new_root)) { ++ assert("nikita-1210", znode_is_root(level->new_root)); ++ node->deallocate = 1; ++ result = ++ longterm_lock_znode(&node->lock_handle, level->new_root, ++ ZNODE_WRITE_LOCK, ZNODE_LOCK_LOPRI); ++ if (result == 0) ++ zput(level->new_root); ++ } else { ++ result = PTR_ERR(level->new_root); ++ level->new_root = NULL; ++ } ++ return result; ++} ++ ++/* allocate new znode and add the operation that inserts the ++ pointer to it into the parent node into the todo level ++ ++ Allocate new znode, add it into carry queue and post into @todo queue ++ request to add pointer to new node into its parent. ++ ++ This is carry related routing that calls reiser4_new_node() to allocate new ++ node. ++*/ ++carry_node *add_new_znode(znode * brother /* existing left neighbor of new ++ * node */ , ++ carry_node * ref /* carry node after which new ++ * carry node is to be inserted ++ * into queue. This affects ++ * locking. */ , ++ carry_level * doing /* carry queue where new node is ++ * to be added */ , ++ carry_level * todo /* carry queue where COP_INSERT ++ * operation to add pointer to ++ * new node will ne added */ ) ++{ ++ carry_node *fresh; ++ znode *new_znode; ++ carry_op *add_pointer; ++ carry_plugin_info info; ++ ++ assert("nikita-1048", brother != NULL); ++ assert("nikita-1049", todo != NULL); ++ ++ /* There is a lot of possible variations here: to what parent ++ new node will be attached and where. For simplicity, always ++ do the following: ++ ++ (1) new node and @brother will have the same parent. ++ ++ (2) new node is added on the right of @brother ++ ++ */ ++ ++ fresh = reiser4_add_carry_skip(doing, ++ ref ? POOLO_AFTER : POOLO_LAST, ref); ++ if (IS_ERR(fresh)) ++ return fresh; ++ ++ fresh->deallocate = 1; ++ fresh->free = 1; ++ ++ new_znode = reiser4_new_node(brother, znode_get_level(brother)); ++ if (IS_ERR(new_znode)) ++ /* @fresh will be deallocated automatically by error ++ handling code in the caller. */ ++ return (carry_node *) new_znode; ++ ++ /* new_znode returned znode with x_count 1. Caller has to decrease ++ it. make_space() does. */ ++ ++ ZF_SET(new_znode, JNODE_ORPHAN); ++ fresh->node = new_znode; ++ ++ while (ZF_ISSET(reiser4_carry_real(ref), JNODE_ORPHAN)) { ++ ref = carry_node_prev(ref); ++ assert("nikita-1606", !carry_node_end(doing, ref)); ++ } ++ ++ info.todo = todo; ++ info.doing = doing; ++ add_pointer = node_post_carry(&info, COP_INSERT, ++ reiser4_carry_real(ref), 1); ++ if (IS_ERR(add_pointer)) { ++ /* no need to deallocate @new_znode here: it will be ++ deallocated during carry error handling. */ ++ return (carry_node *) add_pointer; ++ } ++ ++ add_pointer->u.insert.type = COPT_CHILD; ++ add_pointer->u.insert.child = fresh; ++ add_pointer->u.insert.brother = brother; ++ /* initially new node spawns empty key range */ ++ write_lock_dk(znode_get_tree(brother)); ++ znode_set_ld_key(new_znode, ++ znode_set_rd_key(new_znode, ++ znode_get_rd_key(brother))); ++ write_unlock_dk(znode_get_tree(brother)); ++ return fresh; ++} ++ ++/* DEBUGGING FUNCTIONS. ++ ++ Probably we also should leave them on even when ++ debugging is turned off to print dumps at errors. ++*/ ++#if REISER4_DEBUG ++static int carry_level_invariant(carry_level * level, carry_queue_state state) ++{ ++ carry_node *node; ++ carry_node *tmp_node; ++ ++ if (level == NULL) ++ return 0; ++ ++ if (level->track_type != 0 && ++ level->track_type != CARRY_TRACK_NODE && ++ level->track_type != CARRY_TRACK_CHANGE) ++ return 0; ++ ++ /* check that nodes are in ascending order */ ++ for_all_nodes(level, node, tmp_node) { ++ znode *left; ++ znode *right; ++ ++ reiser4_key lkey; ++ reiser4_key rkey; ++ ++ if (node != carry_node_front(level)) { ++ if (state == CARRY_TODO) { ++ right = node->node; ++ left = carry_node_prev(node)->node; ++ } else { ++ right = reiser4_carry_real(node); ++ left = reiser4_carry_real(carry_node_prev(node)); ++ } ++ if (right == NULL || left == NULL) ++ continue; ++ if (node_is_empty(right) || node_is_empty(left)) ++ continue; ++ if (!keyle(leftmost_key_in_node(left, &lkey), ++ leftmost_key_in_node(right, &rkey))) { ++ warning("", "wrong key order"); ++ return 0; ++ } ++ } ++ } ++ return 1; ++} ++#endif ++ ++/* get symbolic name for boolean */ ++static const char *tf(int boolean/* truth value */) ++{ ++ return boolean ? "t" : "f"; ++} ++ ++/* symbolic name for carry operation */ ++static const char *carry_op_name(carry_opcode op/* carry opcode */) ++{ ++ switch (op) { ++ case COP_INSERT: ++ return "COP_INSERT"; ++ case COP_DELETE: ++ return "COP_DELETE"; ++ case COP_CUT: ++ return "COP_CUT"; ++ case COP_PASTE: ++ return "COP_PASTE"; ++ case COP_UPDATE: ++ return "COP_UPDATE"; ++ case COP_EXTENT: ++ return "COP_EXTENT"; ++ case COP_INSERT_FLOW: ++ return "COP_INSERT_FLOW"; ++ default:{ ++ /* not mt safe, but who cares? */ ++ static char buf[20]; ++ ++ sprintf(buf, "unknown op: %x", op); ++ return buf; ++ } ++ } ++} ++ ++/* dump information about carry node */ ++static void print_carry(const char *prefix /* prefix to print */ , ++ carry_node * node/* node to print */) ++{ ++ if (node == NULL) { ++ printk("%s: null\n", prefix); ++ return; ++ } ++ printk ++ ("%s: %p parent: %s, left: %s, unlock: %s, free: %s, dealloc: %s\n", ++ prefix, node, tf(node->parent), tf(node->left), tf(node->unlock), ++ tf(node->free), tf(node->deallocate)); ++} ++ ++/* dump information about carry operation */ ++static void print_op(const char *prefix /* prefix to print */ , ++ carry_op * op/* operation to print */) ++{ ++ if (op == NULL) { ++ printk("%s: null\n", prefix); ++ return; ++ } ++ printk("%s: %p carry_opcode: %s\n", prefix, op, carry_op_name(op->op)); ++ print_carry("\tnode", op->node); ++ switch (op->op) { ++ case COP_INSERT: ++ case COP_PASTE: ++ print_coord("\tcoord", ++ op->u.insert.d ? op->u.insert.d->coord : NULL, 0); ++ reiser4_print_key("\tkey", ++ op->u.insert.d ? op->u.insert.d->key : NULL); ++ print_carry("\tchild", op->u.insert.child); ++ break; ++ case COP_DELETE: ++ print_carry("\tchild", op->u.delete.child); ++ break; ++ case COP_CUT: ++ if (op->u.cut_or_kill.is_cut) { ++ print_coord("\tfrom", ++ op->u.cut_or_kill.u.kill->params.from, 0); ++ print_coord("\tto", op->u.cut_or_kill.u.kill->params.to, ++ 0); ++ } else { ++ print_coord("\tfrom", ++ op->u.cut_or_kill.u.cut->params.from, 0); ++ print_coord("\tto", op->u.cut_or_kill.u.cut->params.to, ++ 0); ++ } ++ break; ++ case COP_UPDATE: ++ print_carry("\tleft", op->u.update.left); ++ break; ++ default: ++ /* do nothing */ ++ break; ++ } ++} ++ ++/* dump information about all nodes and operations in a @level */ ++static void print_level(const char *prefix /* prefix to print */ , ++ carry_level * level/* level to print */) ++{ ++ carry_node *node; ++ carry_node *tmp_node; ++ carry_op *op; ++ carry_op *tmp_op; ++ ++ if (level == NULL) { ++ printk("%s: null\n", prefix); ++ return; ++ } ++ printk("%s: %p, restartable: %s\n", ++ prefix, level, tf(level->restartable)); ++ ++ for_all_nodes(level, node, tmp_node) ++ print_carry("\tcarry node", node); ++ for_all_ops(level, op, tmp_op) ++ print_op("\tcarry op", op); ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/carry.h linux-2.6.30/fs/reiser4/carry.h +--- linux-2.6.30.orig/fs/reiser4/carry.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/carry.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,445 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* Functions and data types to "carry" tree modification(s) upward. ++ See fs/reiser4/carry.c for details. */ ++ ++#if !defined(__FS_REISER4_CARRY_H__) ++#define __FS_REISER4_CARRY_H__ ++ ++#include "forward.h" ++#include "debug.h" ++#include "pool.h" ++#include "znode.h" ++ ++#include <linux/types.h> ++ ++/* &carry_node - "location" of carry node. ++ ++ "location" of node that is involved or going to be involved into ++ carry process. Node where operation will be carried to on the ++ parent level cannot be recorded explicitly. Operation will be carried ++ usually to the parent of some node (where changes are performed at ++ the current level) or, to the left neighbor of its parent. But while ++ modifications are performed at the current level, parent may ++ change. So, we have to allow some indirection (or, positevly, ++ flexibility) in locating carry nodes. ++ ++*/ ++typedef struct carry_node { ++ /* pool linkage */ ++ struct reiser4_pool_header header; ++ ++ /* base node from which real_node is calculated. See ++ fs/reiser4/carry.c:lock_carry_node(). */ ++ znode *node; ++ ++ /* how to get ->real_node */ ++ /* to get ->real_node obtain parent of ->node */ ++ __u32 parent:1; ++ /* to get ->real_node obtain left neighbor of parent of ++ ->node */ ++ __u32 left:1; ++ __u32 left_before:1; ++ ++ /* locking */ ++ ++ /* this node was locked by carry process and should be ++ unlocked when carry leaves a level */ ++ __u32 unlock:1; ++ ++ /* disk block for this node was allocated by carry process and ++ should be deallocated when carry leaves a level */ ++ __u32 deallocate:1; ++ /* this carry node was allocated by carry process and should be ++ freed when carry leaves a level */ ++ __u32 free:1; ++ ++ /* type of lock we want to take on this node */ ++ lock_handle lock_handle; ++} carry_node; ++ ++/* &carry_opcode - elementary operations that can be carried upward ++ ++ Operations that carry() can handle. This list is supposed to be ++ expanded. ++ ++ Each carry operation (cop) is handled by appropriate function defined ++ in fs/reiser4/carry.c. For example COP_INSERT is handled by ++ fs/reiser4/carry.c:carry_insert() etc. These functions in turn ++ call plugins of nodes affected by operation to modify nodes' content ++ and to gather operations to be performed on the next level. ++ ++*/ ++typedef enum { ++ /* insert new item into node. */ ++ COP_INSERT, ++ /* delete pointer from parent node */ ++ COP_DELETE, ++ /* remove part of or whole node. */ ++ COP_CUT, ++ /* increase size of item. */ ++ COP_PASTE, ++ /* insert extent (that is sequence of unformatted nodes). */ ++ COP_EXTENT, ++ /* update delimiting key in least common ancestor of two ++ nodes. This is performed when items are moved between two ++ nodes. ++ */ ++ COP_UPDATE, ++ /* insert flow */ ++ COP_INSERT_FLOW, ++ COP_LAST_OP, ++} carry_opcode; ++ ++#define CARRY_FLOW_NEW_NODES_LIMIT 20 ++ ++/* mode (or subtype) of COP_{INSERT|PASTE} operation. Specifies how target ++ item is determined. */ ++typedef enum { ++ /* target item is one containing pointer to the ->child node */ ++ COPT_CHILD, ++ /* target item is given explicitly by @coord */ ++ COPT_ITEM_DATA, ++ /* target item is given by key */ ++ COPT_KEY, ++ /* see insert_paste_common() for more comments on this. */ ++ COPT_PASTE_RESTARTED, ++} cop_insert_pos_type; ++ ++/* flags to cut and delete */ ++typedef enum { ++ /* don't kill node even if it became completely empty as results of ++ * cut. This is needed for eottl handling. See carry_extent() for ++ * details. */ ++ DELETE_RETAIN_EMPTY = (1 << 0) ++} cop_delete_flag; ++ ++/* ++ * carry() implements "lock handle tracking" feature. ++ * ++ * Callers supply carry with node where to perform initial operation and lock ++ * handle on this node. Trying to optimize node utilization carry may actually ++ * move insertion point to different node. Callers expect that lock handle ++ * will rebe transferred to the new node also. ++ * ++ */ ++typedef enum { ++ /* transfer lock handle along with insertion point */ ++ CARRY_TRACK_CHANGE = 1, ++ /* acquire new lock handle to the node where insertion point is. This ++ * is used when carry() client doesn't initially possess lock handle ++ * on the insertion point node, for example, by extent insertion ++ * code. See carry_extent(). */ ++ CARRY_TRACK_NODE = 2 ++} carry_track_type; ++ ++/* data supplied to COP_{INSERT|PASTE} by callers */ ++typedef struct carry_insert_data { ++ /* position where new item is to be inserted */ ++ coord_t *coord; ++ /* new item description */ ++ reiser4_item_data * data; ++ /* key of new item */ ++ const reiser4_key * key; ++} carry_insert_data; ++ ++/* cut and kill are similar, so carry_cut_data and carry_kill_data share the ++ below structure of parameters */ ++struct cut_kill_params { ++ /* coord where cut starts (inclusive) */ ++ coord_t *from; ++ /* coord where cut stops (inclusive, this item/unit will also be ++ * cut) */ ++ coord_t *to; ++ /* starting key. This is necessary when item and unit pos don't ++ * uniquely identify what portion or tree to remove. For example, this ++ * indicates what portion of extent unit will be affected. */ ++ const reiser4_key * from_key; ++ /* exclusive stop key */ ++ const reiser4_key * to_key; ++ /* if this is not NULL, smallest actually removed key is stored ++ * here. */ ++ reiser4_key *smallest_removed; ++ /* kill_node_content() is called for file truncate */ ++ int truncate; ++}; ++ ++struct carry_cut_data { ++ struct cut_kill_params params; ++}; ++ ++struct carry_kill_data { ++ struct cut_kill_params params; ++ /* parameter to be passed to the ->kill_hook() method of item ++ * plugin */ ++ /*void *iplug_params; *//* FIXME: unused currently */ ++ /* if not NULL---inode whose items are being removed. This is needed ++ * for ->kill_hook() of extent item to update VM structures when ++ * removing pages. */ ++ struct inode *inode; ++ /* sibling list maintenance is complicated by existence of eottl. When ++ * eottl whose left and right neighbors are formatted leaves is ++ * removed, one has to connect said leaves in the sibling list. This ++ * cannot be done when extent removal is just started as locking rules ++ * require sibling list update to happen atomically with removal of ++ * extent item. Therefore: 1. pointers to left and right neighbors ++ * have to be passed down to the ->kill_hook() of extent item, and ++ * 2. said neighbors have to be locked. */ ++ lock_handle *left; ++ lock_handle *right; ++ /* flags modifying behavior of kill. Currently, it may have ++ DELETE_RETAIN_EMPTY set. */ ++ unsigned flags; ++ char *buf; ++}; ++ ++/* &carry_tree_op - operation to "carry" upward. ++ ++ Description of an operation we want to "carry" to the upper level of ++ a tree: e.g, when we insert something and there is not enough space ++ we allocate a new node and "carry" the operation of inserting a ++ pointer to the new node to the upper level, on removal of empty node, ++ we carry up operation of removing appropriate entry from parent. ++ ++ There are two types of carry ops: when adding or deleting node we ++ node at the parent level where appropriate modification has to be ++ performed is known in advance. When shifting items between nodes ++ (split, merge), delimiting key should be changed in the least common ++ parent of the nodes involved that is not known in advance. ++ ++ For the operations of the first type we store in &carry_op pointer to ++ the &carry_node at the parent level. For the operation of the second ++ type we store &carry_node or parents of the left and right nodes ++ modified and keep track of them upward until they coincide. ++ ++*/ ++typedef struct carry_op { ++ /* pool linkage */ ++ struct reiser4_pool_header header; ++ carry_opcode op; ++ /* node on which operation is to be performed: ++ ++ for insert, paste: node where new item is to be inserted ++ ++ for delete: node where pointer is to be deleted ++ ++ for cut: node to cut from ++ ++ for update: node where delimiting key is to be modified ++ ++ for modify: parent of modified node ++ ++ */ ++ carry_node *node; ++ union { ++ struct { ++ /* (sub-)type of insertion/paste. Taken from ++ cop_insert_pos_type. */ ++ __u8 type; ++ /* various operation flags. Taken from ++ cop_insert_flag. */ ++ __u8 flags; ++ carry_insert_data *d; ++ carry_node *child; ++ znode *brother; ++ } insert, paste, extent; ++ ++ struct { ++ int is_cut; ++ union { ++ carry_kill_data *kill; ++ carry_cut_data *cut; ++ } u; ++ } cut_or_kill; ++ ++ struct { ++ carry_node *left; ++ } update; ++ struct { ++ /* changed child */ ++ carry_node *child; ++ /* bitmask of changes. See &cop_modify_flag */ ++ __u32 flag; ++ } modify; ++ struct { ++ /* flags to deletion operation. Are taken from ++ cop_delete_flag */ ++ __u32 flags; ++ /* child to delete from parent. If this is ++ NULL, delete op->node. */ ++ carry_node *child; ++ } delete; ++ struct { ++ /* various operation flags. Taken from ++ cop_insert_flag. */ ++ __u32 flags; ++ flow_t *flow; ++ coord_t *insert_point; ++ reiser4_item_data *data; ++ /* flow insertion is limited by number of new blocks ++ added in that operation which do not get any data ++ but part of flow. This limit is set by macro ++ CARRY_FLOW_NEW_NODES_LIMIT. This field stores number ++ of nodes added already during one carry_flow */ ++ int new_nodes; ++ } insert_flow; ++ } u; ++} carry_op; ++ ++/* &carry_op_pool - preallocated pool of carry operations, and nodes */ ++typedef struct carry_pool { ++ carry_op op[CARRIES_POOL_SIZE]; ++ struct reiser4_pool op_pool; ++ carry_node node[NODES_LOCKED_POOL_SIZE]; ++ struct reiser4_pool node_pool; ++} carry_pool; ++ ++/* &carry_tree_level - carry process on given level ++ ++ Description of balancing process on the given level. ++ ++ No need for locking here, as carry_tree_level is essentially per ++ thread thing (for now). ++ ++*/ ++struct carry_level { ++ /* this level may be restarted */ ++ __u32 restartable:1; ++ /* list of carry nodes on this level, ordered by key order */ ++ struct list_head nodes; ++ struct list_head ops; ++ /* pool where new objects are allocated from */ ++ carry_pool *pool; ++ int ops_num; ++ int nodes_num; ++ /* new root created on this level, if any */ ++ znode *new_root; ++ /* This is set by caller (insert_by_key(), rreiser4_esize_item(), etc.) ++ when they want ->tracked to automagically wander to the node where ++ insertion point moved after insert or paste. ++ */ ++ carry_track_type track_type; ++ /* lock handle supplied by user that we are tracking. See ++ above. */ ++ lock_handle *tracked; ++}; ++ ++/* information carry passes to plugin methods that may add new operations to ++ the @todo queue */ ++struct carry_plugin_info { ++ carry_level *doing; ++ carry_level *todo; ++}; ++ ++int reiser4_carry(carry_level * doing, carry_level * done); ++ ++carry_node *reiser4_add_carry(carry_level * level, pool_ordering order, ++ carry_node * reference); ++carry_node *reiser4_add_carry_skip(carry_level * level, pool_ordering order, ++ carry_node * reference); ++ ++extern carry_node *insert_carry_node(carry_level * doing, ++ carry_level * todo, const znode * node); ++ ++extern carry_pool *init_carry_pool(int); ++extern void done_carry_pool(carry_pool * pool); ++ ++extern void init_carry_level(carry_level * level, carry_pool * pool); ++ ++extern carry_op *reiser4_post_carry(carry_level * level, carry_opcode op, ++ znode * node, int apply_to_parent); ++extern carry_op *node_post_carry(carry_plugin_info * info, carry_opcode op, ++ znode * node, int apply_to_parent_p); ++ ++carry_node *add_new_znode(znode * brother, carry_node * reference, ++ carry_level * doing, carry_level * todo); ++ ++carry_node *find_carry_node(carry_level * level, const znode * node); ++ ++extern znode *reiser4_carry_real(const carry_node * node); ++ ++/* helper macros to iterate over carry queues */ ++ ++#define carry_node_next(node) \ ++ list_entry((node)->header.level_linkage.next, carry_node, \ ++ header.level_linkage) ++ ++#define carry_node_prev(node) \ ++ list_entry((node)->header.level_linkage.prev, carry_node, \ ++ header.level_linkage) ++ ++#define carry_node_front(level) \ ++ list_entry((level)->nodes.next, carry_node, header.level_linkage) ++ ++#define carry_node_back(level) \ ++ list_entry((level)->nodes.prev, carry_node, header.level_linkage) ++ ++#define carry_node_end(level, node) \ ++ (&(level)->nodes == &(node)->header.level_linkage) ++ ++/* macro to iterate over all operations in a @level */ ++#define for_all_ops(level /* carry level (of type carry_level *) */, \ ++ op /* pointer to carry operation, modified by loop (of \ ++ * type carry_op *) */, \ ++ tmp /* pointer to carry operation (of type carry_op *), \ ++ * used to make iterator stable in the face of \ ++ * deletions from the level */ ) \ ++for (op = list_entry(level->ops.next, carry_op, header.level_linkage), \ ++ tmp = list_entry(op->header.level_linkage.next, carry_op, header.level_linkage); \ ++ &op->header.level_linkage != &level->ops; \ ++ op = tmp, \ ++ tmp = list_entry(op->header.level_linkage.next, carry_op, header.level_linkage)) ++ ++#if 0 ++for (op = (carry_op *) pool_level_list_front(&level->ops), \ ++ tmp = (carry_op *) pool_level_list_next(&op->header) ; \ ++ !pool_level_list_end(&level->ops, &op->header) ; \ ++ op = tmp, tmp = (carry_op *) pool_level_list_next(&op->header)) ++#endif ++ ++/* macro to iterate over all nodes in a @level */ \ ++#define for_all_nodes(level /* carry level (of type carry_level *) */, \ ++ node /* pointer to carry node, modified by loop (of \ ++ * type carry_node *) */, \ ++ tmp /* pointer to carry node (of type carry_node *), \ ++ * used to make iterator stable in the face of * \ ++ * deletions from the level */ ) \ ++for (node = list_entry(level->nodes.next, carry_node, header.level_linkage), \ ++ tmp = list_entry(node->header.level_linkage.next, carry_node, header.level_linkage); \ ++ &node->header.level_linkage != &level->nodes; \ ++ node = tmp, \ ++ tmp = list_entry(node->header.level_linkage.next, carry_node, header.level_linkage)) ++ ++#if 0 ++for (node = carry_node_front(level), \ ++ tmp = carry_node_next(node) ; !carry_node_end(level, node) ; \ ++ node = tmp, tmp = carry_node_next(node)) ++#endif ++ ++/* macro to iterate over all nodes in a @level in reverse order ++ ++ This is used, because nodes are unlocked in reversed order of locking */ ++#define for_all_nodes_back(level /* carry level (of type carry_level *) */, \ ++ node /* pointer to carry node, modified by loop \ ++ * (of type carry_node *) */, \ ++ tmp /* pointer to carry node (of type carry_node \ ++ * *), used to make iterator stable in the \ ++ * face of deletions from the level */ ) \ ++for (node = carry_node_back(level), \ ++ tmp = carry_node_prev(node) ; !carry_node_end(level, node) ; \ ++ node = tmp, tmp = carry_node_prev(node)) ++ ++/* __FS_REISER4_CARRY_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/carry_ops.c linux-2.6.30/fs/reiser4/carry_ops.c +--- linux-2.6.30.orig/fs/reiser4/carry_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/carry_ops.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,2132 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* implementation of carry operations */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "key.h" ++#include "coord.h" ++#include "plugin/item/item.h" ++#include "plugin/node/node.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree_walk.h" ++#include "pool.h" ++#include "tree_mod.h" ++#include "carry.h" ++#include "carry_ops.h" ++#include "tree.h" ++#include "super.h" ++#include "reiser4.h" ++ ++#include <linux/types.h> ++#include <linux/err.h> ++ ++static int carry_shift_data(sideof side, coord_t *insert_coord, znode * node, ++ carry_level * doing, carry_level * todo, ++ unsigned int including_insert_coord_p); ++ ++extern int lock_carry_node(carry_level * level, carry_node * node); ++extern int lock_carry_node_tail(carry_node * node); ++ ++/* find left neighbor of a carry node ++ ++ Look for left neighbor of @node and add it to the @doing queue. See ++ comments in the body. ++ ++*/ ++static carry_node *find_left_neighbor(carry_op * op /* node to find left ++ * neighbor of */ , ++ carry_level * doing/* level to scan */) ++{ ++ int result; ++ carry_node *node; ++ carry_node *left; ++ int flags; ++ reiser4_tree *tree; ++ ++ node = op->node; ++ ++ tree = current_tree; ++ read_lock_tree(tree); ++ /* first, check whether left neighbor is already in a @doing queue */ ++ if (reiser4_carry_real(node)->left != NULL) { ++ /* NOTE: there is locking subtlety here. Look into ++ * find_right_neighbor() for more info */ ++ if (find_carry_node(doing, ++ reiser4_carry_real(node)->left) != NULL) { ++ read_unlock_tree(tree); ++ left = node; ++ do { ++ left = list_entry(left->header.level_linkage.prev, ++ carry_node, header.level_linkage); ++ assert("nikita-3408", !carry_node_end(doing, ++ left)); ++ } while (reiser4_carry_real(left) == ++ reiser4_carry_real(node)); ++ return left; ++ } ++ } ++ read_unlock_tree(tree); ++ ++ left = reiser4_add_carry_skip(doing, POOLO_BEFORE, node); ++ if (IS_ERR(left)) ++ return left; ++ ++ left->node = node->node; ++ left->free = 1; ++ ++ flags = GN_TRY_LOCK; ++ if (!op->u.insert.flags & COPI_LOAD_LEFT) ++ flags |= GN_NO_ALLOC; ++ ++ /* then, feeling lucky, peek left neighbor in the cache. */ ++ result = reiser4_get_left_neighbor(&left->lock_handle, ++ reiser4_carry_real(node), ++ ZNODE_WRITE_LOCK, flags); ++ if (result == 0) { ++ /* ok, node found and locked. */ ++ result = lock_carry_node_tail(left); ++ if (result != 0) ++ left = ERR_PTR(result); ++ } else if (result == -E_NO_NEIGHBOR || result == -ENOENT) { ++ /* node is leftmost node in a tree, or neighbor wasn't in ++ cache, or there is an extent on the left. */ ++ reiser4_pool_free(&doing->pool->node_pool, &left->header); ++ left = NULL; ++ } else if (doing->restartable) { ++ /* if left neighbor is locked, and level is restartable, add ++ new node to @doing and restart. */ ++ assert("nikita-913", node->parent != 0); ++ assert("nikita-914", node->node != NULL); ++ left->left = 1; ++ left->free = 0; ++ left = ERR_PTR(-E_REPEAT); ++ } else { ++ /* left neighbor is locked, level cannot be restarted. Just ++ ignore left neighbor. */ ++ reiser4_pool_free(&doing->pool->node_pool, &left->header); ++ left = NULL; ++ } ++ return left; ++} ++ ++/* find right neighbor of a carry node ++ ++ Look for right neighbor of @node and add it to the @doing queue. See ++ comments in the body. ++ ++*/ ++static carry_node *find_right_neighbor(carry_op * op /* node to find right ++ * neighbor of */ , ++ carry_level * doing/* level to scan */) ++{ ++ int result; ++ carry_node *node; ++ carry_node *right; ++ lock_handle lh; ++ int flags; ++ reiser4_tree *tree; ++ ++ init_lh(&lh); ++ ++ node = op->node; ++ ++ tree = current_tree; ++ read_lock_tree(tree); ++ /* first, check whether right neighbor is already in a @doing queue */ ++ if (reiser4_carry_real(node)->right != NULL) { ++ /* ++ * Tree lock is taken here anyway, because, even if _outcome_ ++ * of (find_carry_node() != NULL) doesn't depends on ++ * concurrent updates to ->right, find_carry_node() cannot ++ * work with second argument NULL. Hence, following comment is ++ * of historic importance only. ++ * ++ * Subtle: ++ * ++ * Q: why don't we need tree lock here, looking for the right ++ * neighbor? ++ * ++ * A: even if value of node->real_node->right were changed ++ * during find_carry_node() execution, outcome of execution ++ * wouldn't change, because (in short) other thread cannot add ++ * elements to the @doing, and if node->real_node->right ++ * already was in @doing, value of node->real_node->right ++ * couldn't change, because node cannot be inserted between ++ * locked neighbors. ++ */ ++ if (find_carry_node(doing, ++ reiser4_carry_real(node)->right) != NULL) { ++ read_unlock_tree(tree); ++ /* ++ * What we are doing here (this is also applicable to ++ * the find_left_neighbor()). ++ * ++ * tree_walk.c code requires that insertion of a ++ * pointer to a child, modification of parent pointer ++ * in the child, and insertion of the child into ++ * sibling list are atomic (see ++ * plugin/item/internal.c:create_hook_internal()). ++ * ++ * carry allocates new node long before pointer to it ++ * is inserted into parent and, actually, long before ++ * parent is even known. Such allocated-but-orphaned ++ * nodes are only trackable through carry level lists. ++ * ++ * Situation that is handled here is following: @node ++ * has valid ->right pointer, but there is ++ * allocated-but-orphaned node in the carry queue that ++ * is logically between @node and @node->right. Here ++ * we are searching for it. Critical point is that ++ * this is only possible if @node->right is also in ++ * the carry queue (this is checked above), because ++ * this is the only way new orphaned node could be ++ * inserted between them (before inserting new node, ++ * make_space() first tries to shift to the right, so, ++ * right neighbor will be locked and queued). ++ * ++ */ ++ right = node; ++ do { ++ right = list_entry(right->header.level_linkage.next, ++ carry_node, header.level_linkage); ++ assert("nikita-3408", !carry_node_end(doing, ++ right)); ++ } while (reiser4_carry_real(right) == ++ reiser4_carry_real(node)); ++ return right; ++ } ++ } ++ read_unlock_tree(tree); ++ ++ flags = GN_CAN_USE_UPPER_LEVELS; ++ if (!op->u.insert.flags & COPI_LOAD_RIGHT) ++ flags = GN_NO_ALLOC; ++ ++ /* then, try to lock right neighbor */ ++ init_lh(&lh); ++ result = reiser4_get_right_neighbor(&lh, ++ reiser4_carry_real(node), ++ ZNODE_WRITE_LOCK, flags); ++ if (result == 0) { ++ /* ok, node found and locked. */ ++ right = reiser4_add_carry_skip(doing, POOLO_AFTER, node); ++ if (!IS_ERR(right)) { ++ right->node = lh.node; ++ move_lh(&right->lock_handle, &lh); ++ right->free = 1; ++ result = lock_carry_node_tail(right); ++ if (result != 0) ++ right = ERR_PTR(result); ++ } ++ } else if ((result == -E_NO_NEIGHBOR) || (result == -ENOENT)) { ++ /* node is rightmost node in a tree, or neighbor wasn't in ++ cache, or there is an extent on the right. */ ++ right = NULL; ++ } else ++ right = ERR_PTR(result); ++ done_lh(&lh); ++ return right; ++} ++ ++/* how much free space in a @node is needed for @op ++ ++ How much space in @node is required for completion of @op, where @op is ++ insert or paste operation. ++*/ ++static unsigned int space_needed_for_op(znode * node /* znode data are ++ * inserted or ++ * pasted in */ , ++ carry_op * op /* carry ++ operation */ ) ++{ ++ assert("nikita-919", op != NULL); ++ ++ switch (op->op) { ++ default: ++ impossible("nikita-1701", "Wrong opcode"); ++ case COP_INSERT: ++ return space_needed(node, NULL, op->u.insert.d->data, 1); ++ case COP_PASTE: ++ return space_needed(node, op->u.insert.d->coord, ++ op->u.insert.d->data, 0); ++ } ++} ++ ++/* how much space in @node is required to insert or paste @data at ++ @coord. */ ++unsigned int space_needed(const znode * node /* node data are inserted or ++ * pasted in */ , ++ const coord_t *coord /* coord where data are ++ * inserted or pasted ++ * at */ , ++ const reiser4_item_data * data /* data to insert or ++ * paste */ , ++ int insertion/* non-0 is inserting, 0---paste */) ++{ ++ int result; ++ item_plugin *iplug; ++ ++ assert("nikita-917", node != NULL); ++ assert("nikita-918", node_plugin_by_node(node) != NULL); ++ assert("vs-230", !insertion || (coord == NULL)); ++ ++ result = 0; ++ iplug = data->iplug; ++ if (iplug->b.estimate != NULL) { ++ /* ask item plugin how much space is needed to insert this ++ item */ ++ result += iplug->b.estimate(insertion ? NULL : coord, data); ++ } else { ++ /* reasonable default */ ++ result += data->length; ++ } ++ if (insertion) { ++ node_plugin *nplug; ++ ++ nplug = node->nplug; ++ /* and add node overhead */ ++ if (nplug->item_overhead != NULL) ++ result += nplug->item_overhead(node, NULL); ++ } ++ return result; ++} ++ ++/* find &coord in parent where pointer to new child is to be stored. */ ++static int find_new_child_coord(carry_op * op /* COP_INSERT carry operation to ++ * insert pointer to new ++ * child */ ) ++{ ++ int result; ++ znode *node; ++ znode *child; ++ ++ assert("nikita-941", op != NULL); ++ assert("nikita-942", op->op == COP_INSERT); ++ ++ node = reiser4_carry_real(op->node); ++ assert("nikita-943", node != NULL); ++ assert("nikita-944", node_plugin_by_node(node) != NULL); ++ ++ child = reiser4_carry_real(op->u.insert.child); ++ result = ++ find_new_child_ptr(node, child, op->u.insert.brother, ++ op->u.insert.d->coord); ++ ++ build_child_ptr_data(child, op->u.insert.d->data); ++ return result; ++} ++ ++/* additional amount of free space in @node required to complete @op */ ++static int free_space_shortage(znode * node /* node to check */ , ++ carry_op * op/* operation being performed */) ++{ ++ assert("nikita-1061", node != NULL); ++ assert("nikita-1062", op != NULL); ++ ++ switch (op->op) { ++ default: ++ impossible("nikita-1702", "Wrong opcode"); ++ case COP_INSERT: ++ case COP_PASTE: ++ return space_needed_for_op(node, op) - znode_free_space(node); ++ case COP_EXTENT: ++ /* when inserting extent shift data around until insertion ++ point is utmost in the node. */ ++ if (coord_wrt(op->u.insert.d->coord) == COORD_INSIDE) ++ return +1; ++ else ++ return -1; ++ } ++} ++ ++/* helper function: update node pointer in operation after insertion ++ point was probably shifted into @target. */ ++static znode *sync_op(carry_op * op, carry_node * target) ++{ ++ znode *insertion_node; ++ ++ /* reget node from coord: shift might move insertion coord to ++ the neighbor */ ++ insertion_node = op->u.insert.d->coord->node; ++ /* if insertion point was actually moved into new node, ++ update carry node pointer in operation. */ ++ if (insertion_node != reiser4_carry_real(op->node)) { ++ op->node = target; ++ assert("nikita-2540", ++ reiser4_carry_real(target) == insertion_node); ++ } ++ assert("nikita-2541", ++ reiser4_carry_real(op->node) == op->u.insert.d->coord->node); ++ return insertion_node; ++} ++ ++/* ++ * complete make_space() call: update tracked lock handle if necessary. See ++ * comments for fs/reiser4/carry.h:carry_track_type ++ */ ++static int ++make_space_tail(carry_op * op, carry_level * doing, znode * orig_node) ++{ ++ int result; ++ carry_track_type tracking; ++ znode *node; ++ ++ tracking = doing->track_type; ++ node = op->u.insert.d->coord->node; ++ ++ if (tracking == CARRY_TRACK_NODE || ++ (tracking == CARRY_TRACK_CHANGE && node != orig_node)) { ++ /* inserting or pasting into node different from ++ original. Update lock handle supplied by caller. */ ++ assert("nikita-1417", doing->tracked != NULL); ++ done_lh(doing->tracked); ++ init_lh(doing->tracked); ++ result = longterm_lock_znode(doing->tracked, node, ++ ZNODE_WRITE_LOCK, ++ ZNODE_LOCK_HIPRI); ++ } else ++ result = 0; ++ return result; ++} ++ ++/* This is insertion policy function. It shifts data to the left and right ++ neighbors of insertion coord and allocates new nodes until there is enough ++ free space to complete @op. ++ ++ See comments in the body. ++ ++ Assumes that the node format favors insertions at the right end of the node ++ as node40 does. ++ ++ See carry_flow() on detail about flow insertion ++*/ ++static int make_space(carry_op * op /* carry operation, insert or paste */ , ++ carry_level * doing /* current carry queue */ , ++ carry_level * todo/* carry queue on the parent level */) ++{ ++ znode *node; ++ int result; ++ int not_enough_space; ++ int blk_alloc; ++ znode *orig_node; ++ __u32 flags; ++ ++ coord_t *coord; ++ ++ assert("nikita-890", op != NULL); ++ assert("nikita-891", todo != NULL); ++ assert("nikita-892", ++ op->op == COP_INSERT || ++ op->op == COP_PASTE || op->op == COP_EXTENT); ++ assert("nikita-1607", ++ reiser4_carry_real(op->node) == op->u.insert.d->coord->node); ++ ++ flags = op->u.insert.flags; ++ ++ /* NOTE check that new node can only be allocated after checking left ++ * and right neighbors. This is necessary for proper work of ++ * find_{left,right}_neighbor(). */ ++ assert("nikita-3410", ergo(flags & COPI_DONT_ALLOCATE, ++ flags & COPI_DONT_SHIFT_LEFT)); ++ assert("nikita-3411", ergo(flags & COPI_DONT_ALLOCATE, ++ flags & COPI_DONT_SHIFT_RIGHT)); ++ ++ coord = op->u.insert.d->coord; ++ orig_node = node = coord->node; ++ ++ assert("nikita-908", node != NULL); ++ assert("nikita-909", node_plugin_by_node(node) != NULL); ++ ++ result = 0; ++ /* If there is not enough space in a node, try to shift something to ++ the left neighbor. This is a bit tricky, as locking to the left is ++ low priority. This is handled by restart logic in carry(). ++ */ ++ not_enough_space = free_space_shortage(node, op); ++ if (not_enough_space <= 0) ++ /* it is possible that carry was called when there actually ++ was enough space in the node. For example, when inserting ++ leftmost item so that delimiting keys have to be updated. ++ */ ++ return make_space_tail(op, doing, orig_node); ++ if (!(flags & COPI_DONT_SHIFT_LEFT)) { ++ carry_node *left; ++ /* make note in statistics of an attempt to move ++ something into the left neighbor */ ++ left = find_left_neighbor(op, doing); ++ if (unlikely(IS_ERR(left))) { ++ if (PTR_ERR(left) == -E_REPEAT) ++ return -E_REPEAT; ++ else { ++ /* some error other than restart request ++ occurred. This shouldn't happen. Issue a ++ warning and continue as if left neighbor ++ weren't existing. ++ */ ++ warning("nikita-924", ++ "Error accessing left neighbor: %li", ++ PTR_ERR(left)); ++ } ++ } else if (left != NULL) { ++ ++ /* shift everything possible on the left of and ++ including insertion coord into the left neighbor */ ++ result = carry_shift_data(LEFT_SIDE, coord, ++ reiser4_carry_real(left), ++ doing, todo, ++ flags & COPI_GO_LEFT); ++ ++ /* reget node from coord: shift_left() might move ++ insertion coord to the left neighbor */ ++ node = sync_op(op, left); ++ ++ not_enough_space = free_space_shortage(node, op); ++ /* There is not enough free space in @node, but ++ may be, there is enough free space in ++ @left. Various balancing decisions are valid here. ++ The same for the shifiting to the right. ++ */ ++ } ++ } ++ /* If there still is not enough space, shift to the right */ ++ if (not_enough_space > 0 && !(flags & COPI_DONT_SHIFT_RIGHT)) { ++ carry_node *right; ++ ++ right = find_right_neighbor(op, doing); ++ if (IS_ERR(right)) { ++ warning("nikita-1065", ++ "Error accessing right neighbor: %li", ++ PTR_ERR(right)); ++ } else if (right != NULL) { ++ /* node containing insertion point, and its right ++ neighbor node are write locked by now. ++ ++ shift everything possible on the right of but ++ excluding insertion coord into the right neighbor ++ */ ++ result = carry_shift_data(RIGHT_SIDE, coord, ++ reiser4_carry_real(right), ++ doing, todo, ++ flags & COPI_GO_RIGHT); ++ /* reget node from coord: shift_right() might move ++ insertion coord to the right neighbor */ ++ node = sync_op(op, right); ++ not_enough_space = free_space_shortage(node, op); ++ } ++ } ++ /* If there is still not enough space, allocate new node(s). ++ ++ We try to allocate new blocks if COPI_DONT_ALLOCATE is not set in ++ the carry operation flags (currently this is needed during flush ++ only). ++ */ ++ for (blk_alloc = 0; ++ not_enough_space > 0 && result == 0 && blk_alloc < 2 && ++ !(flags & COPI_DONT_ALLOCATE); ++blk_alloc) { ++ carry_node *fresh; /* new node we are allocating */ ++ coord_t coord_shadow; /* remembered insertion point before ++ * shifting data into new node */ ++ carry_node *node_shadow; /* remembered insertion node ++ * before shifting */ ++ unsigned int gointo; /* whether insertion point should move ++ * into newly allocated node */ ++ ++ /* allocate new node on the right of @node. Znode and disk ++ fake block number for new node are allocated. ++ ++ add_new_znode() posts carry operation COP_INSERT with ++ COPT_CHILD option to the parent level to add ++ pointer to newly created node to its parent. ++ ++ Subtle point: if several new nodes are required to complete ++ insertion operation at this level, they will be inserted ++ into their parents in the order of creation, which means ++ that @node will be valid "cookie" at the time of insertion. ++ ++ */ ++ fresh = add_new_znode(node, op->node, doing, todo); ++ if (IS_ERR(fresh)) ++ return PTR_ERR(fresh); ++ ++ /* Try to shift into new node. */ ++ result = lock_carry_node(doing, fresh); ++ zput(reiser4_carry_real(fresh)); ++ if (result != 0) { ++ warning("nikita-947", ++ "Cannot lock new node: %i", result); ++ return result; ++ } ++ ++ /* both nodes are write locked by now. ++ ++ shift everything possible on the right of and ++ including insertion coord into the right neighbor. ++ */ ++ coord_dup(&coord_shadow, op->u.insert.d->coord); ++ node_shadow = op->node; ++ /* move insertion point into newly created node if: ++ ++ . insertion point is rightmost in the source node, or ++ . this is not the first node we are allocating in a row. ++ */ ++ gointo = ++ (blk_alloc > 0) || ++ coord_is_after_rightmost(op->u.insert.d->coord); ++ ++ if (gointo && ++ op->op == COP_PASTE && ++ coord_is_existing_item(op->u.insert.d->coord) && ++ is_solid_item((item_plugin_by_coord(op->u.insert.d->coord)))) { ++ /* paste into solid (atomic) item, which can contain ++ only one unit, so we need to shift it right, where ++ insertion point supposed to be */ ++ ++ assert("edward-1444", op->u.insert.d->data->iplug == ++ item_plugin_by_id(STATIC_STAT_DATA_ID)); ++ assert("edward-1445", ++ op->u.insert.d->data->length > ++ node_plugin_by_node(coord->node)->free_space ++ (coord->node)); ++ ++ op->u.insert.d->coord->between = BEFORE_UNIT; ++ } ++ ++ result = carry_shift_data(RIGHT_SIDE, coord, ++ reiser4_carry_real(fresh), ++ doing, todo, gointo); ++ /* if insertion point was actually moved into new node, ++ update carry node pointer in operation. */ ++ node = sync_op(op, fresh); ++ not_enough_space = free_space_shortage(node, op); ++ if ((not_enough_space > 0) && (node != coord_shadow.node)) { ++ /* there is not enough free in new node. Shift ++ insertion point back to the @shadow_node so that ++ next new node would be inserted between ++ @shadow_node and @fresh. ++ */ ++ coord_normalize(&coord_shadow); ++ coord_dup(coord, &coord_shadow); ++ node = coord->node; ++ op->node = node_shadow; ++ if (1 || (flags & COPI_STEP_BACK)) { ++ /* still not enough space?! Maybe there is ++ enough space in the source node (i.e., node ++ data are moved from) now. ++ */ ++ not_enough_space = ++ free_space_shortage(node, op); ++ } ++ } ++ } ++ if (not_enough_space > 0) { ++ if (!(flags & COPI_DONT_ALLOCATE)) ++ warning("nikita-948", "Cannot insert new item"); ++ result = -E_NODE_FULL; ++ } ++ assert("nikita-1622", ergo(result == 0, ++ reiser4_carry_real(op->node) == coord->node)); ++ assert("nikita-2616", coord == op->u.insert.d->coord); ++ if (result == 0) ++ result = make_space_tail(op, doing, orig_node); ++ return result; ++} ++ ++/* insert_paste_common() - common part of insert and paste operations ++ ++ This function performs common part of COP_INSERT and COP_PASTE. ++ ++ There are two ways in which insertion/paste can be requested: ++ ++ . by directly supplying reiser4_item_data. In this case, op -> ++ u.insert.type is set to COPT_ITEM_DATA. ++ ++ . by supplying child pointer to which is to inserted into parent. In this ++ case op -> u.insert.type == COPT_CHILD. ++ ++ . by supplying key of new item/unit. This is currently only used during ++ extent insertion ++ ++ This is required, because when new node is allocated we don't know at what ++ position pointer to it is to be stored in the parent. Actually, we don't ++ even know what its parent will be, because parent can be re-balanced ++ concurrently and new node re-parented, and because parent can be full and ++ pointer to the new node will go into some other node. ++ ++ insert_paste_common() resolves pointer to child node into position in the ++ parent by calling find_new_child_coord(), that fills ++ reiser4_item_data. After this, insertion/paste proceeds uniformly. ++ ++ Another complication is with finding free space during pasting. It may ++ happen that while shifting items to the neighbors and newly allocated ++ nodes, insertion coord can no longer be in the item we wanted to paste ++ into. At this point, paste becomes (morphs) into insert. Moreover free ++ space analysis has to be repeated, because amount of space required for ++ insertion is different from that of paste (item header overhead, etc). ++ ++ This function "unifies" different insertion modes (by resolving child ++ pointer or key into insertion coord), and then calls make_space() to free ++ enough space in the node by shifting data to the left and right and by ++ allocating new nodes if necessary. Carry operation knows amount of space ++ required for its completion. After enough free space is obtained, caller of ++ this function (carry_{insert,paste,etc.}) performs actual insertion/paste ++ by calling item plugin method. ++ ++*/ ++static int insert_paste_common(carry_op * op /* carry operation being ++ * performed */ , ++ carry_level * doing /* current carry level */ , ++ carry_level * todo /* next carry level */ , ++ carry_insert_data * cdata /* pointer to ++ * cdata */ , ++ coord_t *coord /* insertion/paste coord */ , ++ reiser4_item_data * data /* data to be ++ * inserted/pasted */ ) ++{ ++ assert("nikita-981", op != NULL); ++ assert("nikita-980", todo != NULL); ++ assert("nikita-979", (op->op == COP_INSERT) || (op->op == COP_PASTE) ++ || (op->op == COP_EXTENT)); ++ ++ if (op->u.insert.type == COPT_PASTE_RESTARTED) { ++ /* nothing to do. Fall through to make_space(). */ ++ ; ++ } else if (op->u.insert.type == COPT_KEY) { ++ node_search_result intra_node; ++ znode *node; ++ /* Problem with doing batching at the lowest level, is that ++ operations here are given by coords where modification is ++ to be performed, and one modification can invalidate coords ++ of all following operations. ++ ++ So, we are implementing yet another type for operation that ++ will use (the only) "locator" stable across shifting of ++ data between nodes, etc.: key (COPT_KEY). ++ ++ This clause resolves key to the coord in the node. ++ ++ But node can change also. Probably some pieces have to be ++ added to the lock_carry_node(), to lock node by its key. ++ ++ */ ++ /* NOTE-NIKITA Lookup bias is fixed to FIND_EXACT. Complain ++ if you need something else. */ ++ op->u.insert.d->coord = coord; ++ node = reiser4_carry_real(op->node); ++ intra_node = node_plugin_by_node(node)->lookup ++ (node, op->u.insert.d->key, FIND_EXACT, ++ op->u.insert.d->coord); ++ if ((intra_node != NS_FOUND) && (intra_node != NS_NOT_FOUND)) { ++ warning("nikita-1715", "Intra node lookup failure: %i", ++ intra_node); ++ return intra_node; ++ } ++ } else if (op->u.insert.type == COPT_CHILD) { ++ /* if we are asked to insert pointer to the child into ++ internal node, first convert pointer to the child into ++ coord within parent node. ++ */ ++ znode *child; ++ int result; ++ ++ op->u.insert.d = cdata; ++ op->u.insert.d->coord = coord; ++ op->u.insert.d->data = data; ++ op->u.insert.d->coord->node = reiser4_carry_real(op->node); ++ result = find_new_child_coord(op); ++ child = reiser4_carry_real(op->u.insert.child); ++ if (result != NS_NOT_FOUND) { ++ warning("nikita-993", ++ "Cannot find a place for child pointer: %i", ++ result); ++ return result; ++ } ++ /* This only happens when we did multiple insertions at ++ the previous level, trying to insert single item and ++ it so happened, that insertion of pointers to all new ++ nodes before this one already caused parent node to ++ split (may be several times). ++ ++ I am going to come up with better solution. ++ ++ You are not expected to understand this. ++ -- v6root/usr/sys/ken/slp.c ++ ++ Basically, what happens here is the following: carry came ++ to the parent level and is about to insert internal item ++ pointing to the child node that it just inserted in the ++ level below. Position where internal item is to be inserted ++ was found by find_new_child_coord() above, but node of the ++ current carry operation (that is, parent node of child ++ inserted on the previous level), was determined earlier in ++ the lock_carry_level/lock_carry_node. It could so happen ++ that other carry operations already performed on the parent ++ level already split parent node, so that insertion point ++ moved into another node. Handle this by creating new carry ++ node for insertion point if necessary. ++ */ ++ if (reiser4_carry_real(op->node) != ++ op->u.insert.d->coord->node) { ++ pool_ordering direction; ++ znode *z1; ++ znode *z2; ++ reiser4_key k1; ++ reiser4_key k2; ++ ++ /* ++ * determine in what direction insertion point ++ * moved. Do this by comparing delimiting keys. ++ */ ++ z1 = op->u.insert.d->coord->node; ++ z2 = reiser4_carry_real(op->node); ++ if (keyle(leftmost_key_in_node(z1, &k1), ++ leftmost_key_in_node(z2, &k2))) ++ /* insertion point moved to the left */ ++ direction = POOLO_BEFORE; ++ else ++ /* insertion point moved to the right */ ++ direction = POOLO_AFTER; ++ ++ op->node = reiser4_add_carry_skip(doing, ++ direction, op->node); ++ if (IS_ERR(op->node)) ++ return PTR_ERR(op->node); ++ op->node->node = op->u.insert.d->coord->node; ++ op->node->free = 1; ++ result = lock_carry_node(doing, op->node); ++ if (result != 0) ++ return result; ++ } ++ ++ /* ++ * set up key of an item being inserted: we are inserting ++ * internal item and its key is (by the very definition of ++ * search tree) is leftmost key in the child node. ++ */ ++ write_lock_dk(znode_get_tree(child)); ++ op->u.insert.d->key = leftmost_key_in_node(child, ++ znode_get_ld_key(child)); ++ write_unlock_dk(znode_get_tree(child)); ++ op->u.insert.d->data->arg = op->u.insert.brother; ++ } else { ++ assert("vs-243", op->u.insert.d->coord != NULL); ++ op->u.insert.d->coord->node = reiser4_carry_real(op->node); ++ } ++ ++ /* find free space. */ ++ return make_space(op, doing, todo); ++} ++ ++/* handle carry COP_INSERT operation. ++ ++ Insert new item into node. New item can be given in one of two ways: ++ ++ - by passing &tree_coord and &reiser4_item_data as part of @op. This is ++ only applicable at the leaf/twig level. ++ ++ - by passing a child node pointer to which is to be inserted by this ++ operation. ++ ++*/ ++static int carry_insert(carry_op * op /* operation to perform */ , ++ carry_level * doing /* queue of operations @op ++ * is part of */ , ++ carry_level * todo /* queue where new operations ++ * are accumulated */ ) ++{ ++ znode *node; ++ carry_insert_data cdata; ++ coord_t coord; ++ reiser4_item_data data; ++ carry_plugin_info info; ++ int result; ++ ++ assert("nikita-1036", op != NULL); ++ assert("nikita-1037", todo != NULL); ++ assert("nikita-1038", op->op == COP_INSERT); ++ ++ coord_init_zero(&coord); ++ ++ /* perform common functionality of insert and paste. */ ++ result = insert_paste_common(op, doing, todo, &cdata, &coord, &data); ++ if (result != 0) ++ return result; ++ ++ node = op->u.insert.d->coord->node; ++ assert("nikita-1039", node != NULL); ++ assert("nikita-1040", node_plugin_by_node(node) != NULL); ++ ++ assert("nikita-949", ++ space_needed_for_op(node, op) <= znode_free_space(node)); ++ ++ /* ask node layout to create new item. */ ++ info.doing = doing; ++ info.todo = todo; ++ result = node_plugin_by_node(node)->create_item ++ (op->u.insert.d->coord, op->u.insert.d->key, op->u.insert.d->data, ++ &info); ++ doing->restartable = 0; ++ znode_make_dirty(node); ++ ++ return result; ++} ++ ++/* ++ * Flow insertion code. COP_INSERT_FLOW is special tree operation that is ++ * supplied with a "flow" (that is, a stream of data) and inserts it into tree ++ * by slicing into multiple items. ++ */ ++ ++#define flow_insert_point(op) ((op)->u.insert_flow.insert_point) ++#define flow_insert_flow(op) ((op)->u.insert_flow.flow) ++#define flow_insert_data(op) ((op)->u.insert_flow.data) ++ ++static size_t item_data_overhead(carry_op * op) ++{ ++ if (flow_insert_data(op)->iplug->b.estimate == NULL) ++ return 0; ++ return (flow_insert_data(op)->iplug->b. ++ estimate(NULL /* estimate insertion */ , flow_insert_data(op)) - ++ flow_insert_data(op)->length); ++} ++ ++/* FIXME-VS: this is called several times during one make_flow_for_insertion ++ and it will always return the same result. Some optimization could be made ++ by calculating this value once at the beginning and passing it around. That ++ would reduce some flexibility in future changes ++*/ ++static int can_paste(coord_t *, const reiser4_key *, const reiser4_item_data *); ++static size_t flow_insertion_overhead(carry_op * op) ++{ ++ znode *node; ++ size_t insertion_overhead; ++ ++ node = flow_insert_point(op)->node; ++ insertion_overhead = 0; ++ if (node->nplug->item_overhead && ++ !can_paste(flow_insert_point(op), &flow_insert_flow(op)->key, ++ flow_insert_data(op))) ++ insertion_overhead = ++ node->nplug->item_overhead(node, NULL) + ++ item_data_overhead(op); ++ return insertion_overhead; ++} ++ ++/* how many bytes of flow does fit to the node */ ++static int what_can_fit_into_node(carry_op * op) ++{ ++ size_t free, overhead; ++ ++ overhead = flow_insertion_overhead(op); ++ free = znode_free_space(flow_insert_point(op)->node); ++ if (free <= overhead) ++ return 0; ++ free -= overhead; ++ /* FIXME: flow->length is loff_t only to not get overflowed in case of ++ expandign truncate */ ++ if (free < op->u.insert_flow.flow->length) ++ return free; ++ return (int)op->u.insert_flow.flow->length; ++} ++ ++/* in make_space_for_flow_insertion we need to check either whether whole flow ++ fits into a node or whether minimal fraction of flow fits into a node */ ++static int enough_space_for_whole_flow(carry_op * op) ++{ ++ return (unsigned)what_can_fit_into_node(op) == ++ op->u.insert_flow.flow->length; ++} ++ ++#define MIN_FLOW_FRACTION 1 ++static int enough_space_for_min_flow_fraction(carry_op * op) ++{ ++ assert("vs-902", coord_is_after_rightmost(flow_insert_point(op))); ++ ++ return what_can_fit_into_node(op) >= MIN_FLOW_FRACTION; ++} ++ ++/* this returns 0 if left neighbor was obtained successfully and everything ++ upto insertion point including it were shifted and left neighbor still has ++ some free space to put minimal fraction of flow into it */ ++static int ++make_space_by_shift_left(carry_op * op, carry_level * doing, carry_level * todo) ++{ ++ carry_node *left; ++ znode *orig; ++ ++ left = find_left_neighbor(op, doing); ++ if (unlikely(IS_ERR(left))) { ++ warning("vs-899", ++ "make_space_by_shift_left: " ++ "error accessing left neighbor: %li", PTR_ERR(left)); ++ return 1; ++ } ++ if (left == NULL) ++ /* left neighbor either does not exist or is unformatted ++ node */ ++ return 1; ++ ++ orig = flow_insert_point(op)->node; ++ /* try to shift content of node @orig from its head upto insert point ++ including insertion point into the left neighbor */ ++ carry_shift_data(LEFT_SIDE, flow_insert_point(op), ++ reiser4_carry_real(left), doing, todo, ++ 1/* including insert point */); ++ if (reiser4_carry_real(left) != flow_insert_point(op)->node) { ++ /* insertion point did not move */ ++ return 1; ++ } ++ ++ /* insertion point is set after last item in the node */ ++ assert("vs-900", coord_is_after_rightmost(flow_insert_point(op))); ++ ++ if (!enough_space_for_min_flow_fraction(op)) { ++ /* insertion point node does not have enough free space to put ++ even minimal portion of flow into it, therefore, move ++ insertion point back to orig node (before first item) */ ++ coord_init_before_first_item(flow_insert_point(op), orig); ++ return 1; ++ } ++ ++ /* part of flow is to be written to the end of node */ ++ op->node = left; ++ return 0; ++} ++ ++/* this returns 0 if right neighbor was obtained successfully and everything to ++ the right of insertion point was shifted to it and node got enough free ++ space to put minimal fraction of flow into it */ ++static int ++make_space_by_shift_right(carry_op * op, carry_level * doing, ++ carry_level * todo) ++{ ++ carry_node *right; ++ ++ right = find_right_neighbor(op, doing); ++ if (unlikely(IS_ERR(right))) { ++ warning("nikita-1065", "shift_right_excluding_insert_point: " ++ "error accessing right neighbor: %li", PTR_ERR(right)); ++ return 1; ++ } ++ if (right) { ++ /* shift everything possible on the right of but excluding ++ insertion coord into the right neighbor */ ++ carry_shift_data(RIGHT_SIDE, flow_insert_point(op), ++ reiser4_carry_real(right), doing, todo, ++ 0/* not including insert point */); ++ } else { ++ /* right neighbor either does not exist or is unformatted ++ node */ ++ ; ++ } ++ if (coord_is_after_rightmost(flow_insert_point(op))) { ++ if (enough_space_for_min_flow_fraction(op)) { ++ /* part of flow is to be written to the end of node */ ++ return 0; ++ } ++ } ++ ++ /* new node is to be added if insert point node did not get enough ++ space for whole flow */ ++ return 1; ++} ++ ++/* this returns 0 when insert coord is set at the node end and fraction of flow ++ fits into that node */ ++static int ++make_space_by_new_nodes(carry_op * op, carry_level * doing, carry_level * todo) ++{ ++ int result; ++ znode *node; ++ carry_node *new; ++ ++ node = flow_insert_point(op)->node; ++ ++ if (op->u.insert_flow.new_nodes == CARRY_FLOW_NEW_NODES_LIMIT) ++ return RETERR(-E_NODE_FULL); ++ /* add new node after insert point node */ ++ new = add_new_znode(node, op->node, doing, todo); ++ if (unlikely(IS_ERR(new))) ++ return PTR_ERR(new); ++ result = lock_carry_node(doing, new); ++ zput(reiser4_carry_real(new)); ++ if (unlikely(result)) ++ return result; ++ op->u.insert_flow.new_nodes++; ++ if (!coord_is_after_rightmost(flow_insert_point(op))) { ++ carry_shift_data(RIGHT_SIDE, flow_insert_point(op), ++ reiser4_carry_real(new), doing, todo, ++ 0/* not including insert point */); ++ assert("vs-901", ++ coord_is_after_rightmost(flow_insert_point(op))); ++ ++ if (enough_space_for_min_flow_fraction(op)) ++ return 0; ++ if (op->u.insert_flow.new_nodes == CARRY_FLOW_NEW_NODES_LIMIT) ++ return RETERR(-E_NODE_FULL); ++ ++ /* add one more new node */ ++ new = add_new_znode(node, op->node, doing, todo); ++ if (unlikely(IS_ERR(new))) ++ return PTR_ERR(new); ++ result = lock_carry_node(doing, new); ++ zput(reiser4_carry_real(new)); ++ if (unlikely(result)) ++ return result; ++ op->u.insert_flow.new_nodes++; ++ } ++ ++ /* move insertion point to new node */ ++ coord_init_before_first_item(flow_insert_point(op), ++ reiser4_carry_real(new)); ++ op->node = new; ++ return 0; ++} ++ ++static int ++make_space_for_flow_insertion(carry_op * op, carry_level * doing, ++ carry_level * todo) ++{ ++ __u32 flags = op->u.insert_flow.flags; ++ ++ if (enough_space_for_whole_flow(op)) { ++ /* whole flow fits into insert point node */ ++ return 0; ++ } ++ ++ if (!(flags & COPI_DONT_SHIFT_LEFT) ++ && (make_space_by_shift_left(op, doing, todo) == 0)) { ++ /* insert point is shifted to left neighbor of original insert ++ point node and is set after last unit in that node. It has ++ enough space to fit at least minimal fraction of flow. */ ++ return 0; ++ } ++ ++ if (enough_space_for_whole_flow(op)) { ++ /* whole flow fits into insert point node */ ++ return 0; ++ } ++ ++ if (!(flags & COPI_DONT_SHIFT_RIGHT) ++ && (make_space_by_shift_right(op, doing, todo) == 0)) { ++ /* insert point is still set to the same node, but there is ++ nothing to the right of insert point. */ ++ return 0; ++ } ++ ++ if (enough_space_for_whole_flow(op)) { ++ /* whole flow fits into insert point node */ ++ return 0; ++ } ++ ++ return make_space_by_new_nodes(op, doing, todo); ++} ++ ++/* implements COP_INSERT_FLOW operation */ ++static int ++carry_insert_flow(carry_op * op, carry_level * doing, carry_level * todo) ++{ ++ int result; ++ flow_t *f; ++ coord_t *insert_point; ++ node_plugin *nplug; ++ carry_plugin_info info; ++ znode *orig_node; ++ lock_handle *orig_lh; ++ ++ f = op->u.insert_flow.flow; ++ result = 0; ++ ++ /* carry system needs this to work */ ++ info.doing = doing; ++ info.todo = todo; ++ ++ orig_node = flow_insert_point(op)->node; ++ orig_lh = doing->tracked; ++ ++ while (f->length) { ++ result = make_space_for_flow_insertion(op, doing, todo); ++ if (result) ++ break; ++ ++ insert_point = flow_insert_point(op); ++ nplug = node_plugin_by_node(insert_point->node); ++ ++ /* compose item data for insertion/pasting */ ++ flow_insert_data(op)->data = f->data; ++ flow_insert_data(op)->length = what_can_fit_into_node(op); ++ ++ if (can_paste(insert_point, &f->key, flow_insert_data(op))) { ++ /* insert point is set to item of file we are writing to ++ and we have to append to it */ ++ assert("vs-903", insert_point->between == AFTER_UNIT); ++ nplug->change_item_size(insert_point, ++ flow_insert_data(op)->length); ++ flow_insert_data(op)->iplug->b.paste(insert_point, ++ flow_insert_data ++ (op), &info); ++ } else { ++ /* new item must be inserted */ ++ pos_in_node_t new_pos; ++ flow_insert_data(op)->length += item_data_overhead(op); ++ ++ /* FIXME-VS: this is because node40_create_item changes ++ insert_point for obscure reasons */ ++ switch (insert_point->between) { ++ case AFTER_ITEM: ++ new_pos = insert_point->item_pos + 1; ++ break; ++ case EMPTY_NODE: ++ new_pos = 0; ++ break; ++ case BEFORE_ITEM: ++ assert("vs-905", insert_point->item_pos == 0); ++ new_pos = 0; ++ break; ++ default: ++ impossible("vs-906", ++ "carry_insert_flow: invalid coord"); ++ new_pos = 0; ++ break; ++ } ++ ++ nplug->create_item(insert_point, &f->key, ++ flow_insert_data(op), &info); ++ coord_set_item_pos(insert_point, new_pos); ++ } ++ coord_init_after_item_end(insert_point); ++ doing->restartable = 0; ++ znode_make_dirty(insert_point->node); ++ ++ move_flow_forward(f, (unsigned)flow_insert_data(op)->length); ++ } ++ ++ if (orig_node != flow_insert_point(op)->node) { ++ /* move lock to new insert point */ ++ done_lh(orig_lh); ++ init_lh(orig_lh); ++ result = ++ longterm_lock_znode(orig_lh, flow_insert_point(op)->node, ++ ZNODE_WRITE_LOCK, ZNODE_LOCK_HIPRI); ++ } ++ ++ return result; ++} ++ ++/* implements COP_DELETE operation ++ ++ Remove pointer to @op -> u.delete.child from it's parent. ++ ++ This function also handles killing of a tree root is last pointer from it ++ was removed. This is complicated by our handling of "twig" level: root on ++ twig level is never killed. ++ ++*/ ++static int carry_delete(carry_op * op /* operation to be performed */ , ++ carry_level * doing UNUSED_ARG /* current carry ++ * level */ , ++ carry_level * todo/* next carry level */) ++{ ++ int result; ++ coord_t coord; ++ coord_t coord2; ++ znode *parent; ++ znode *child; ++ carry_plugin_info info; ++ reiser4_tree *tree; ++ ++ /* ++ * This operation is called to delete internal item pointing to the ++ * child node that was removed by carry from the tree on the previous ++ * tree level. ++ */ ++ ++ assert("nikita-893", op != NULL); ++ assert("nikita-894", todo != NULL); ++ assert("nikita-895", op->op == COP_DELETE); ++ ++ coord_init_zero(&coord); ++ coord_init_zero(&coord2); ++ ++ parent = reiser4_carry_real(op->node); ++ child = op->u.delete.child ? ++ reiser4_carry_real(op->u.delete.child) : op->node->node; ++ tree = znode_get_tree(child); ++ read_lock_tree(tree); ++ ++ /* ++ * @parent was determined when carry entered parent level ++ * (lock_carry_level/lock_carry_node). Since then, actual parent of ++ * @child node could change due to other carry operations performed on ++ * the parent level. Check for this. ++ */ ++ ++ if (znode_parent(child) != parent) { ++ /* NOTE-NIKITA add stat counter for this. */ ++ parent = znode_parent(child); ++ assert("nikita-2581", find_carry_node(doing, parent)); ++ } ++ read_unlock_tree(tree); ++ ++ assert("nikita-1213", znode_get_level(parent) > LEAF_LEVEL); ++ ++ /* Twig level horrors: tree should be of height at least 2. So, last ++ pointer from the root at twig level is preserved even if child is ++ empty. This is ugly, but so it was architectured. ++ */ ++ ++ if (znode_is_root(parent) && ++ znode_get_level(parent) <= REISER4_MIN_TREE_HEIGHT && ++ node_num_items(parent) == 1) { ++ /* Delimiting key manipulations. */ ++ write_lock_dk(tree); ++ znode_set_ld_key(child, znode_set_ld_key(parent, reiser4_min_key())); ++ znode_set_rd_key(child, znode_set_rd_key(parent, reiser4_max_key())); ++ ZF_SET(child, JNODE_DKSET); ++ write_unlock_dk(tree); ++ ++ /* @child escaped imminent death! */ ++ ZF_CLR(child, JNODE_HEARD_BANSHEE); ++ return 0; ++ } ++ ++ /* convert child pointer to the coord_t */ ++ result = find_child_ptr(parent, child, &coord); ++ if (result != NS_FOUND) { ++ warning("nikita-994", "Cannot find child pointer: %i", result); ++ print_coord_content("coord", &coord); ++ return result; ++ } ++ ++ coord_dup(&coord2, &coord); ++ info.doing = doing; ++ info.todo = todo; ++ { ++ /* ++ * Actually kill internal item: prepare structure with ++ * arguments for ->cut_and_kill() method... ++ */ ++ ++ struct carry_kill_data kdata; ++ kdata.params.from = &coord; ++ kdata.params.to = &coord2; ++ kdata.params.from_key = NULL; ++ kdata.params.to_key = NULL; ++ kdata.params.smallest_removed = NULL; ++ kdata.params.truncate = 1; ++ kdata.flags = op->u.delete.flags; ++ kdata.inode = NULL; ++ kdata.left = NULL; ++ kdata.right = NULL; ++ kdata.buf = NULL; ++ /* ... and call it. */ ++ result = node_plugin_by_node(parent)->cut_and_kill(&kdata, ++ &info); ++ } ++ doing->restartable = 0; ++ ++ /* check whether root should be killed violently */ ++ if (znode_is_root(parent) && ++ /* don't kill roots at and lower than twig level */ ++ znode_get_level(parent) > REISER4_MIN_TREE_HEIGHT && ++ node_num_items(parent) == 1) ++ result = reiser4_kill_tree_root(coord.node); ++ ++ return result < 0 ? : 0; ++} ++ ++/* implements COP_CUT opration ++ ++ Cuts part or whole content of node. ++ ++*/ ++static int carry_cut(carry_op * op /* operation to be performed */ , ++ carry_level * doing /* current carry level */ , ++ carry_level * todo/* next carry level */) ++{ ++ int result; ++ carry_plugin_info info; ++ node_plugin *nplug; ++ ++ assert("nikita-896", op != NULL); ++ assert("nikita-897", todo != NULL); ++ assert("nikita-898", op->op == COP_CUT); ++ ++ info.doing = doing; ++ info.todo = todo; ++ ++ nplug = node_plugin_by_node(reiser4_carry_real(op->node)); ++ if (op->u.cut_or_kill.is_cut) ++ result = nplug->cut(op->u.cut_or_kill.u.cut, &info); ++ else ++ result = nplug->cut_and_kill(op->u.cut_or_kill.u.kill, &info); ++ ++ doing->restartable = 0; ++ return result < 0 ? : 0; ++} ++ ++/* helper function for carry_paste(): returns true if @op can be continued as ++ paste */ ++static int ++can_paste(coord_t *icoord, const reiser4_key * key, ++ const reiser4_item_data * data) ++{ ++ coord_t circa; ++ item_plugin *new_iplug; ++ item_plugin *old_iplug; ++ int result = 0; /* to keep gcc shut */ ++ ++ assert("", icoord->between != AT_UNIT); ++ ++ /* obviously, one cannot paste when node is empty---there is nothing ++ to paste into. */ ++ if (node_is_empty(icoord->node)) ++ return 0; ++ /* if insertion point is at the middle of the item, then paste */ ++ if (!coord_is_between_items(icoord)) ++ return 1; ++ coord_dup(&circa, icoord); ++ circa.between = AT_UNIT; ++ ++ old_iplug = item_plugin_by_coord(&circa); ++ new_iplug = data->iplug; ++ ++ /* check whether we can paste to the item @icoord is "at" when we ++ ignore ->between field */ ++ if (old_iplug == new_iplug && item_can_contain_key(&circa, key, data)) ++ result = 1; ++ else if (icoord->between == BEFORE_UNIT ++ || icoord->between == BEFORE_ITEM) { ++ /* otherwise, try to glue to the item at the left, if any */ ++ coord_dup(&circa, icoord); ++ if (coord_set_to_left(&circa)) { ++ result = 0; ++ coord_init_before_item(icoord); ++ } else { ++ old_iplug = item_plugin_by_coord(&circa); ++ result = (old_iplug == new_iplug) ++ && item_can_contain_key(icoord, key, data); ++ if (result) { ++ coord_dup(icoord, &circa); ++ icoord->between = AFTER_UNIT; ++ } ++ } ++ } else if (icoord->between == AFTER_UNIT ++ || icoord->between == AFTER_ITEM) { ++ coord_dup(&circa, icoord); ++ /* otherwise, try to glue to the item at the right, if any */ ++ if (coord_set_to_right(&circa)) { ++ result = 0; ++ coord_init_after_item(icoord); ++ } else { ++ int (*cck) (const coord_t *, const reiser4_key *, ++ const reiser4_item_data *); ++ ++ old_iplug = item_plugin_by_coord(&circa); ++ ++ cck = old_iplug->b.can_contain_key; ++ if (cck == NULL) ++ /* item doesn't define ->can_contain_key ++ method? So it is not expandable. */ ++ result = 0; ++ else { ++ result = (old_iplug == new_iplug) ++ && cck(&circa /*icoord */ , key, data); ++ if (result) { ++ coord_dup(icoord, &circa); ++ icoord->between = BEFORE_UNIT; ++ } ++ } ++ } ++ } else ++ impossible("nikita-2513", "Nothing works"); ++ if (result) { ++ if (icoord->between == BEFORE_ITEM) { ++ assert("vs-912", icoord->unit_pos == 0); ++ icoord->between = BEFORE_UNIT; ++ } else if (icoord->between == AFTER_ITEM) { ++ coord_init_after_item_end(icoord); ++ } ++ } ++ return result; ++} ++ ++/* implements COP_PASTE operation ++ ++ Paste data into existing item. This is complicated by the fact that after ++ we shifted something to the left or right neighbors trying to free some ++ space, item we were supposed to paste into can be in different node than ++ insertion coord. If so, we are no longer doing paste, but insert. See ++ comments in insert_paste_common(). ++ ++*/ ++static int carry_paste(carry_op * op /* operation to be performed */ , ++ carry_level * doing UNUSED_ARG /* current carry ++ * level */ , ++ carry_level * todo/* next carry level */) ++{ ++ znode *node; ++ carry_insert_data cdata; ++ coord_t dcoord; ++ reiser4_item_data data; ++ int result; ++ int real_size; ++ item_plugin *iplug; ++ carry_plugin_info info; ++ coord_t *coord; ++ ++ assert("nikita-982", op != NULL); ++ assert("nikita-983", todo != NULL); ++ assert("nikita-984", op->op == COP_PASTE); ++ ++ coord_init_zero(&dcoord); ++ ++ result = insert_paste_common(op, doing, todo, &cdata, &dcoord, &data); ++ if (result != 0) ++ return result; ++ ++ coord = op->u.insert.d->coord; ++ ++ /* handle case when op -> u.insert.coord doesn't point to the item ++ of required type. restart as insert. */ ++ if (!can_paste(coord, op->u.insert.d->key, op->u.insert.d->data)) { ++ op->op = COP_INSERT; ++ op->u.insert.type = COPT_PASTE_RESTARTED; ++ result = op_dispatch_table[COP_INSERT].handler(op, doing, todo); ++ ++ return result; ++ } ++ ++ node = coord->node; ++ iplug = item_plugin_by_coord(coord); ++ assert("nikita-992", iplug != NULL); ++ ++ assert("nikita-985", node != NULL); ++ assert("nikita-986", node_plugin_by_node(node) != NULL); ++ ++ assert("nikita-987", ++ space_needed_for_op(node, op) <= znode_free_space(node)); ++ ++ assert("nikita-1286", coord_is_existing_item(coord)); ++ ++ /* ++ * if item is expanded as a result of this operation, we should first ++ * change item size, than call ->b.paste item method. If item is ++ * shrunk, it should be done other way around: first call ->b.paste ++ * method, then reduce item size. ++ */ ++ ++ real_size = space_needed_for_op(node, op); ++ if (real_size > 0) ++ node->nplug->change_item_size(coord, real_size); ++ ++ doing->restartable = 0; ++ info.doing = doing; ++ info.todo = todo; ++ ++ result = iplug->b.paste(coord, op->u.insert.d->data, &info); ++ ++ if (real_size < 0) ++ node->nplug->change_item_size(coord, real_size); ++ ++ /* if we pasted at the beginning of the item, update item's key. */ ++ if (coord->unit_pos == 0 && coord->between != AFTER_UNIT) ++ node->nplug->update_item_key(coord, op->u.insert.d->key, &info); ++ ++ znode_make_dirty(node); ++ return result; ++} ++ ++/* handle carry COP_EXTENT operation. */ ++static int carry_extent(carry_op * op /* operation to perform */ , ++ carry_level * doing /* queue of operations @op ++ * is part of */ , ++ carry_level * todo /* queue where new operations ++ * are accumulated */ ) ++{ ++ znode *node; ++ carry_insert_data cdata; ++ coord_t coord; ++ reiser4_item_data data; ++ carry_op *delete_dummy; ++ carry_op *insert_extent; ++ int result; ++ carry_plugin_info info; ++ ++ assert("nikita-1751", op != NULL); ++ assert("nikita-1752", todo != NULL); ++ assert("nikita-1753", op->op == COP_EXTENT); ++ ++ /* extent insertion overview: ++ ++ extents live on the TWIG LEVEL, which is level one above the leaf ++ one. This complicates extent insertion logic somewhat: it may ++ happen (and going to happen all the time) that in logical key ++ ordering extent has to be placed between items I1 and I2, located ++ at the leaf level, but I1 and I2 are in the same formatted leaf ++ node N1. To insert extent one has to ++ ++ (1) reach node N1 and shift data between N1, its neighbors and ++ possibly newly allocated nodes until I1 and I2 fall into different ++ nodes. Since I1 and I2 are still neighboring items in logical key ++ order, they will be necessary utmost items in their respective ++ nodes. ++ ++ (2) After this new extent item is inserted into node on the twig ++ level. ++ ++ Fortunately this process can reuse almost all code from standard ++ insertion procedure (viz. make_space() and insert_paste_common()), ++ due to the following observation: make_space() only shifts data up ++ to and excluding or including insertion point. It never ++ "over-moves" through insertion point. Thus, one can use ++ make_space() to perform step (1). All required for this is just to ++ instruct free_space_shortage() to keep make_space() shifting data ++ until insertion point is at the node border. ++ ++ */ ++ ++ /* perform common functionality of insert and paste. */ ++ result = insert_paste_common(op, doing, todo, &cdata, &coord, &data); ++ if (result != 0) ++ return result; ++ ++ node = op->u.extent.d->coord->node; ++ assert("nikita-1754", node != NULL); ++ assert("nikita-1755", node_plugin_by_node(node) != NULL); ++ assert("nikita-1700", coord_wrt(op->u.extent.d->coord) != COORD_INSIDE); ++ ++ /* NOTE-NIKITA add some checks here. Not assertions, -EIO. Check that ++ extent fits between items. */ ++ ++ info.doing = doing; ++ info.todo = todo; ++ ++ /* there is another complication due to placement of extents on the ++ twig level: extents are "rigid" in the sense that key-range ++ occupied by extent cannot grow indefinitely to the right as it is ++ for the formatted leaf nodes. Because of this when search finds two ++ adjacent extents on the twig level, it has to "drill" to the leaf ++ level, creating new node. Here we are removing this node. ++ */ ++ if (node_is_empty(node)) { ++ delete_dummy = node_post_carry(&info, COP_DELETE, node, 1); ++ if (IS_ERR(delete_dummy)) ++ return PTR_ERR(delete_dummy); ++ delete_dummy->u.delete.child = NULL; ++ delete_dummy->u.delete.flags = DELETE_RETAIN_EMPTY; ++ ZF_SET(node, JNODE_HEARD_BANSHEE); ++ } ++ ++ /* proceed with inserting extent item into parent. We are definitely ++ inserting rather than pasting if we get that far. */ ++ insert_extent = node_post_carry(&info, COP_INSERT, node, 1); ++ if (IS_ERR(insert_extent)) ++ /* @delete_dummy will be automatically destroyed on the level ++ exiting */ ++ return PTR_ERR(insert_extent); ++ /* NOTE-NIKITA insertion by key is simplest option here. Another ++ possibility is to insert on the left or right of already existing ++ item. ++ */ ++ insert_extent->u.insert.type = COPT_KEY; ++ insert_extent->u.insert.d = op->u.extent.d; ++ assert("nikita-1719", op->u.extent.d->key != NULL); ++ insert_extent->u.insert.d->data->arg = op->u.extent.d->coord; ++ insert_extent->u.insert.flags = ++ znode_get_tree(node)->carry.new_extent_flags; ++ ++ /* ++ * if carry was asked to track lock handle we should actually track ++ * lock handle on the twig node rather than on the leaf where ++ * operation was started from. Transfer tracked lock handle. ++ */ ++ if (doing->track_type) { ++ assert("nikita-3242", doing->tracked != NULL); ++ assert("nikita-3244", todo->tracked == NULL); ++ todo->tracked = doing->tracked; ++ todo->track_type = CARRY_TRACK_NODE; ++ doing->tracked = NULL; ++ doing->track_type = 0; ++ } ++ ++ return 0; ++} ++ ++/* update key in @parent between pointers to @left and @right. ++ ++ Find coords of @left and @right and update delimiting key between them. ++ This is helper function called by carry_update(). Finds position of ++ internal item involved. Updates item key. Updates delimiting keys of child ++ nodes involved. ++*/ ++static int update_delimiting_key(znode * parent /* node key is updated ++ * in */ , ++ znode * left /* child of @parent */ , ++ znode * right /* child of @parent */ , ++ carry_level * doing /* current carry ++ * level */ , ++ carry_level * todo /* parent carry ++ * level */ , ++ const char **error_msg /* place to ++ * store error ++ * message */ ) ++{ ++ coord_t left_pos; ++ coord_t right_pos; ++ int result; ++ reiser4_key ldkey; ++ carry_plugin_info info; ++ ++ assert("nikita-1177", right != NULL); ++ /* find position of right left child in a parent */ ++ result = find_child_ptr(parent, right, &right_pos); ++ if (result != NS_FOUND) { ++ *error_msg = "Cannot find position of right child"; ++ return result; ++ } ++ ++ if ((left != NULL) && !coord_is_leftmost_unit(&right_pos)) { ++ /* find position of the left child in a parent */ ++ result = find_child_ptr(parent, left, &left_pos); ++ if (result != NS_FOUND) { ++ *error_msg = "Cannot find position of left child"; ++ return result; ++ } ++ assert("nikita-1355", left_pos.node != NULL); ++ } else ++ left_pos.node = NULL; ++ ++ /* check that they are separated by exactly one key and are basically ++ sane */ ++ if (REISER4_DEBUG) { ++ if ((left_pos.node != NULL) ++ && !coord_is_existing_unit(&left_pos)) { ++ *error_msg = "Left child is bastard"; ++ return RETERR(-EIO); ++ } ++ if (!coord_is_existing_unit(&right_pos)) { ++ *error_msg = "Right child is bastard"; ++ return RETERR(-EIO); ++ } ++ if (left_pos.node != NULL && ++ !coord_are_neighbors(&left_pos, &right_pos)) { ++ *error_msg = "Children are not direct siblings"; ++ return RETERR(-EIO); ++ } ++ } ++ *error_msg = NULL; ++ ++ info.doing = doing; ++ info.todo = todo; ++ ++ /* ++ * If child node is not empty, new key of internal item is a key of ++ * leftmost item in the child node. If the child is empty, take its ++ * right delimiting key as a new key of the internal item. Precise key ++ * in the latter case is not important per se, because the child (and ++ * the internal item) are going to be killed shortly anyway, but we ++ * have to preserve correct order of keys in the parent node. ++ */ ++ ++ if (!ZF_ISSET(right, JNODE_HEARD_BANSHEE)) ++ leftmost_key_in_node(right, &ldkey); ++ else { ++ read_lock_dk(znode_get_tree(parent)); ++ ldkey = *znode_get_rd_key(right); ++ read_unlock_dk(znode_get_tree(parent)); ++ } ++ node_plugin_by_node(parent)->update_item_key(&right_pos, &ldkey, &info); ++ doing->restartable = 0; ++ znode_make_dirty(parent); ++ return 0; ++} ++ ++/* implements COP_UPDATE opration ++ ++ Update delimiting keys. ++ ++*/ ++static int carry_update(carry_op * op /* operation to be performed */ , ++ carry_level * doing /* current carry level */ , ++ carry_level * todo/* next carry level */) ++{ ++ int result; ++ carry_node *missing UNUSED_ARG; ++ znode *left; ++ znode *right; ++ carry_node *lchild; ++ carry_node *rchild; ++ const char *error_msg; ++ reiser4_tree *tree; ++ ++ /* ++ * This operation is called to update key of internal item. This is ++ * necessary when carry shifted of cut data on the child ++ * level. Arguments of this operation are: ++ * ++ * @right --- child node. Operation should update key of internal ++ * item pointing to @right. ++ * ++ * @left --- left neighbor of @right. This parameter is optional. ++ */ ++ ++ assert("nikita-902", op != NULL); ++ assert("nikita-903", todo != NULL); ++ assert("nikita-904", op->op == COP_UPDATE); ++ ++ lchild = op->u.update.left; ++ rchild = op->node; ++ ++ if (lchild != NULL) { ++ assert("nikita-1001", lchild->parent); ++ assert("nikita-1003", !lchild->left); ++ left = reiser4_carry_real(lchild); ++ } else ++ left = NULL; ++ ++ tree = znode_get_tree(rchild->node); ++ read_lock_tree(tree); ++ right = znode_parent(rchild->node); ++ read_unlock_tree(tree); ++ ++ if (right != NULL) { ++ result = update_delimiting_key(right, ++ lchild ? lchild->node : NULL, ++ rchild->node, ++ doing, todo, &error_msg); ++ } else { ++ error_msg = "Cannot find node to update key in"; ++ result = RETERR(-EIO); ++ } ++ /* operation will be reposted to the next level by the ++ ->update_item_key() method of node plugin, if necessary. */ ++ ++ if (result != 0) { ++ warning("nikita-999", "Error updating delimiting key: %s (%i)", ++ error_msg ? : "", result); ++ } ++ return result; ++} ++ ++/* move items from @node during carry */ ++static int carry_shift_data(sideof side /* in what direction to move data */ , ++ coord_t *insert_coord /* coord where new item ++ * is to be inserted */, ++ znode * node /* node which data are moved from */ , ++ carry_level * doing /* active carry queue */ , ++ carry_level * todo /* carry queue where new ++ * operations are to be put ++ * in */ , ++ unsigned int including_insert_coord_p ++ /* true if @insertion_coord can be moved */ ) ++{ ++ int result; ++ znode *source; ++ carry_plugin_info info; ++ node_plugin *nplug; ++ ++ source = insert_coord->node; ++ ++ info.doing = doing; ++ info.todo = todo; ++ ++ nplug = node_plugin_by_node(node); ++ result = nplug->shift(insert_coord, node, ++ (side == LEFT_SIDE) ? SHIFT_LEFT : SHIFT_RIGHT, 0, ++ (int)including_insert_coord_p, &info); ++ /* the only error ->shift() method of node plugin can return is ++ -ENOMEM due to carry node/operation allocation. */ ++ assert("nikita-915", result >= 0 || result == -ENOMEM); ++ if (result > 0) { ++ /* ++ * if some number of bytes was actually shifted, mark nodes ++ * dirty, and carry level as non-restartable. ++ */ ++ doing->restartable = 0; ++ znode_make_dirty(source); ++ znode_make_dirty(node); ++ } ++ ++ assert("nikita-2077", coord_check(insert_coord)); ++ return 0; ++} ++ ++typedef carry_node *(*carry_iterator) (carry_node * node); ++static carry_node *find_dir_carry(carry_node * node, carry_level * level, ++ carry_iterator iterator); ++ ++static carry_node *pool_level_list_prev(carry_node *node) ++{ ++ return list_entry(node->header.level_linkage.prev, carry_node, header.level_linkage); ++} ++ ++/* look for the left neighbor of given carry node in a carry queue. ++ ++ This is used by find_left_neighbor(), but I am not sure that this ++ really gives any advantage. More statistics required. ++ ++*/ ++carry_node *find_left_carry(carry_node * node /* node to find left neighbor ++ * of */ , ++ carry_level * level/* level to scan */) ++{ ++ return find_dir_carry(node, level, ++ (carry_iterator) pool_level_list_prev); ++} ++ ++static carry_node *pool_level_list_next(carry_node *node) ++{ ++ return list_entry(node->header.level_linkage.next, carry_node, header.level_linkage); ++} ++ ++/* look for the right neighbor of given carry node in a ++ carry queue. ++ ++ This is used by find_right_neighbor(), but I am not sure that this ++ really gives any advantage. More statistics required. ++ ++*/ ++carry_node *find_right_carry(carry_node * node /* node to find right neighbor ++ * of */ , ++ carry_level * level/* level to scan */) ++{ ++ return find_dir_carry(node, level, ++ (carry_iterator) pool_level_list_next); ++} ++ ++/* look for the left or right neighbor of given carry node in a carry ++ queue. ++ ++ Helper function used by find_{left|right}_carry(). ++*/ ++static carry_node *find_dir_carry(carry_node * node /* node to start ++ * scanning from */ , ++ carry_level * level /* level to scan */ , ++ carry_iterator iterator /* operation to ++ * move to the ++ * next node */) ++{ ++ carry_node *neighbor; ++ ++ assert("nikita-1059", node != NULL); ++ assert("nikita-1060", level != NULL); ++ ++ /* scan list of carry nodes on this list dir-ward, skipping all ++ carry nodes referencing the same znode. */ ++ neighbor = node; ++ while (1) { ++ neighbor = iterator(neighbor); ++ if (carry_node_end(level, neighbor)) ++ /* list head is reached */ ++ return NULL; ++ if (reiser4_carry_real(neighbor) != reiser4_carry_real(node)) ++ return neighbor; ++ } ++} ++ ++/* ++ * Memory reservation estimation. ++ * ++ * Carry process proceeds through tree levels upwards. Carry assumes that it ++ * takes tree in consistent state (e.g., that search tree invariants hold), ++ * and leaves tree consistent after it finishes. This means that when some ++ * error occurs carry cannot simply return if there are pending carry ++ * operations. Generic solution for this problem is carry-undo either as ++ * transaction manager feature (requiring checkpoints and isolation), or ++ * through some carry specific mechanism. ++ * ++ * Our current approach is to panic if carry hits an error while tree is ++ * inconsistent. Unfortunately -ENOMEM can easily be triggered. To work around ++ * this "memory reservation" mechanism was added. ++ * ++ * Memory reservation is implemented by perthread-pages.diff patch from ++ * core-patches. Its API is defined in <linux/gfp.h> ++ * ++ * int perthread_pages_reserve(int nrpages, gfp_t gfp); ++ * void perthread_pages_release(int nrpages); ++ * int perthread_pages_count(void); ++ * ++ * carry estimates its worst case memory requirements at the entry, reserved ++ * enough memory, and released unused pages before returning. ++ * ++ * Code below estimates worst case memory requirements for a given carry ++ * queue. This is dome by summing worst case memory requirements for each ++ * operation in the queue. ++ * ++ */ ++ ++/* ++ * Memory memory requirements of many operations depends on the tree ++ * height. For example, item insertion requires new node to be inserted at ++ * each tree level in the worst case. What tree height should be used for ++ * estimation? Current tree height is wrong, because tree height can change ++ * between the time when estimation was done and the time when operation is ++ * actually performed. Maximal possible tree height (REISER4_MAX_ZTREE_HEIGHT) ++ * is also not desirable, because it would lead to the huge over-estimation ++ * all the time. Plausible solution is "capped tree height": if current tree ++ * height is less than some TREE_HEIGHT_CAP constant, capped tree height is ++ * TREE_HEIGHT_CAP, otherwise it's current tree height. Idea behind this is ++ * that if tree height is TREE_HEIGHT_CAP or larger, it's extremely unlikely ++ * to be increased even more during short interval of time. ++ */ ++#define TREE_HEIGHT_CAP (5) ++ ++/* return capped tree height for the @tree. See comment above. */ ++static int cap_tree_height(reiser4_tree * tree) ++{ ++ return max_t(int, tree->height, TREE_HEIGHT_CAP); ++} ++ ++/* return capped tree height for the current tree. */ ++static int capped_height(void) ++{ ++ return cap_tree_height(current_tree); ++} ++ ++/* return number of pages required to store given number of bytes */ ++static int bytes_to_pages(int bytes) ++{ ++ return (bytes + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; ++} ++ ++/* how many pages are required to allocate znodes during item insertion. */ ++static int carry_estimate_znodes(void) ++{ ++ /* ++ * Note, that there we have some problem here: there is no way to ++ * reserve pages specifically for the given slab. This means that ++ * these pages can be hijacked for some other end. ++ */ ++ ++ /* in the worst case we need 3 new znode on each tree level */ ++ return bytes_to_pages(capped_height() * sizeof(znode) * 3); ++} ++ ++/* ++ * how many pages are required to load bitmaps. One bitmap per level. ++ */ ++static int carry_estimate_bitmaps(void) ++{ ++ if (reiser4_is_set(reiser4_get_current_sb(), REISER4_DONT_LOAD_BITMAP)) { ++ int bytes; ++ ++ bytes = capped_height() * (0 + /* bnode should be added, but ++ * it is private to bitmap.c, ++ * skip for now. */ ++ 2 * sizeof(jnode)); ++ /* working and commit jnodes */ ++ return bytes_to_pages(bytes) + 2; /* and their contents */ ++ } else ++ /* bitmaps were pre-loaded during mount */ ++ return 0; ++} ++ ++/* worst case item insertion memory requirements */ ++static int carry_estimate_insert(carry_op * op, carry_level * level) ++{ ++ return carry_estimate_bitmaps() + carry_estimate_znodes() + 1 + ++ /* new atom */ ++ capped_height() + /* new block on each level */ ++ 1 + /* and possibly extra new block at the leaf level */ ++ 3; /* loading of leaves into memory */ ++} ++ ++/* worst case item deletion memory requirements */ ++static int carry_estimate_delete(carry_op * op, carry_level * level) ++{ ++ return carry_estimate_bitmaps() + carry_estimate_znodes() + 1 + ++ /* new atom */ ++ 3; /* loading of leaves into memory */ ++} ++ ++/* worst case tree cut memory requirements */ ++static int carry_estimate_cut(carry_op * op, carry_level * level) ++{ ++ return carry_estimate_bitmaps() + carry_estimate_znodes() + 1 + ++ /* new atom */ ++ 3; /* loading of leaves into memory */ ++} ++ ++/* worst case memory requirements of pasting into item */ ++static int carry_estimate_paste(carry_op * op, carry_level * level) ++{ ++ return carry_estimate_bitmaps() + carry_estimate_znodes() + 1 + ++ /* new atom */ ++ capped_height() + /* new block on each level */ ++ 1 + /* and possibly extra new block at the leaf level */ ++ 3; /* loading of leaves into memory */ ++} ++ ++/* worst case memory requirements of extent insertion */ ++static int carry_estimate_extent(carry_op * op, carry_level * level) ++{ ++ return carry_estimate_insert(op, level) + /* insert extent */ ++ carry_estimate_delete(op, level); /* kill leaf */ ++} ++ ++/* worst case memory requirements of key update */ ++static int carry_estimate_update(carry_op * op, carry_level * level) ++{ ++ return 0; ++} ++ ++/* worst case memory requirements of flow insertion */ ++static int carry_estimate_insert_flow(carry_op * op, carry_level * level) ++{ ++ int newnodes; ++ ++ newnodes = min(bytes_to_pages(op->u.insert_flow.flow->length), ++ CARRY_FLOW_NEW_NODES_LIMIT); ++ /* ++ * roughly estimate insert_flow as a sequence of insertions. ++ */ ++ return newnodes * carry_estimate_insert(op, level); ++} ++ ++/* This is dispatch table for carry operations. It can be trivially ++ abstracted into useful plugin: tunable balancing policy is a good ++ thing. */ ++carry_op_handler op_dispatch_table[COP_LAST_OP] = { ++ [COP_INSERT] = { ++ .handler = carry_insert, ++ .estimate = carry_estimate_insert} ++ , ++ [COP_DELETE] = { ++ .handler = carry_delete, ++ .estimate = carry_estimate_delete} ++ , ++ [COP_CUT] = { ++ .handler = carry_cut, ++ .estimate = carry_estimate_cut} ++ , ++ [COP_PASTE] = { ++ .handler = carry_paste, ++ .estimate = carry_estimate_paste} ++ , ++ [COP_EXTENT] = { ++ .handler = carry_extent, ++ .estimate = carry_estimate_extent} ++ , ++ [COP_UPDATE] = { ++ .handler = carry_update, ++ .estimate = carry_estimate_update} ++ , ++ [COP_INSERT_FLOW] = { ++ .handler = carry_insert_flow, ++ .estimate = carry_estimate_insert_flow} ++}; ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/carry_ops.h linux-2.6.30/fs/reiser4/carry_ops.h +--- linux-2.6.30.orig/fs/reiser4/carry_ops.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/carry_ops.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,43 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* implementation of carry operations. See carry_ops.c for details. */ ++ ++#if !defined(__CARRY_OPS_H__) ++#define __CARRY_OPS_H__ ++ ++#include "forward.h" ++#include "znode.h" ++#include "carry.h" ++ ++/* carry operation handlers */ ++typedef struct carry_op_handler { ++ /* perform operation */ ++ int (*handler) (carry_op * op, carry_level * doing, carry_level * todo); ++ /* estimate memory requirements for @op */ ++ int (*estimate) (carry_op * op, carry_level * level); ++} carry_op_handler; ++ ++/* This is dispatch table for carry operations. It can be trivially ++ abstracted into useful plugin: tunable balancing policy is a good ++ thing. */ ++extern carry_op_handler op_dispatch_table[COP_LAST_OP]; ++ ++unsigned int space_needed(const znode * node, const coord_t *coord, ++ const reiser4_item_data * data, int inserting); ++extern carry_node *find_left_carry(carry_node * node, carry_level * level); ++extern carry_node *find_right_carry(carry_node * node, carry_level * level); ++ ++/* __CARRY_OPS_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/context.c linux-2.6.30/fs/reiser4/context.c +--- linux-2.6.30.orig/fs/reiser4/context.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/context.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,289 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Manipulation of reiser4_context */ ++ ++/* ++ * global context used during system call. Variable of this type is allocated ++ * on the stack at the beginning of the reiser4 part of the system call and ++ * pointer to it is stored in the current->fs_context. This allows us to avoid ++ * passing pointer to current transaction and current lockstack (both in ++ * one-to-one mapping with threads) all over the call chain. ++ * ++ * It's kind of like those global variables the prof used to tell you not to ++ * use in CS1, except thread specific.;-) Nikita, this was a good idea. ++ * ++ * In some situations it is desirable to have ability to enter reiser4_context ++ * more than once for the same thread (nested contexts). For example, there ++ * are some functions that can be called either directly from VFS/VM or from ++ * already active reiser4 context (->writepage, for example). ++ * ++ * In such situations "child" context acts like dummy: all activity is ++ * actually performed in the top level context, and get_current_context() ++ * always returns top level context. ++ * Of course, reiser4_init_context()/reiser4_done_context() have to be properly ++ * nested any way. ++ * ++ * Note that there is an important difference between reiser4 uses ++ * ->fs_context and the way other file systems use it. Other file systems ++ * (ext3 and reiserfs) use ->fs_context only for the duration of _transaction_ ++ * (this is why ->fs_context was initially called ->journal_info). This means, ++ * that when ext3 or reiserfs finds that ->fs_context is not NULL on the entry ++ * to the file system, they assume that some transaction is already underway, ++ * and usually bail out, because starting nested transaction would most likely ++ * lead to the deadlock. This gives false positives with reiser4, because we ++ * set ->fs_context before starting transaction. ++ */ ++ ++#include "debug.h" ++#include "super.h" ++#include "context.h" ++ ++#include <linux/writeback.h> /* balance_dirty_pages() */ ++#include <linux/hardirq.h> ++ ++static void _reiser4_init_context(reiser4_context * context, ++ struct super_block *super) ++{ ++ memset(context, 0, sizeof(*context)); ++ ++ context->super = super; ++ context->magic = context_magic; ++ context->outer = current->journal_info; ++ current->journal_info = (void *)context; ++ context->nr_children = 0; ++ context->gfp_mask = GFP_KERNEL; ++ ++ init_lock_stack(&context->stack); ++ ++ reiser4_txn_begin(context); ++ ++ /* initialize head of tap list */ ++ INIT_LIST_HEAD(&context->taps); ++#if REISER4_DEBUG ++ context->task = current; ++#endif ++ grab_space_enable(); ++} ++ ++/* initialize context and bind it to the current thread ++ ++ This function should be called at the beginning of reiser4 part of ++ syscall. ++*/ ++reiser4_context * reiser4_init_context(struct super_block *super) ++{ ++ reiser4_context *context; ++ ++ assert("nikita-2662", !in_interrupt() && !in_irq()); ++ assert("nikita-3357", super != NULL); ++ assert("nikita-3358", super->s_op == NULL || is_reiser4_super(super)); ++ ++ context = get_current_context_check(); ++ if (context && context->super == super) { ++ context = (reiser4_context *) current->journal_info; ++ context->nr_children++; ++ return context; ++ } ++ ++ context = kmalloc(sizeof(*context), GFP_KERNEL); ++ if (context == NULL) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ ++ _reiser4_init_context(context, super); ++ return context; ++} ++ ++/* this is used in scan_mgr which is called with spinlock held and in ++ reiser4_fill_super magic */ ++void init_stack_context(reiser4_context *context, struct super_block *super) ++{ ++ assert("nikita-2662", !in_interrupt() && !in_irq()); ++ assert("nikita-3357", super != NULL); ++ assert("nikita-3358", super->s_op == NULL || is_reiser4_super(super)); ++ assert("vs-12", !is_in_reiser4_context()); ++ ++ _reiser4_init_context(context, super); ++ context->on_stack = 1; ++ return; ++} ++ ++/* cast lock stack embedded into reiser4 context up to its container */ ++reiser4_context *get_context_by_lock_stack(lock_stack * owner) ++{ ++ return container_of(owner, reiser4_context, stack); ++} ++ ++/* true if there is already _any_ reiser4 context for the current thread */ ++int is_in_reiser4_context(void) ++{ ++ reiser4_context *ctx; ++ ++ ctx = current->journal_info; ++ return ctx != NULL && ((unsigned long)ctx->magic) == context_magic; ++} ++ ++/* ++ * call balance dirty pages for the current context. ++ * ++ * File system is expected to call balance_dirty_pages_ratelimited() whenever ++ * it dirties a page. reiser4 does this for unformatted nodes (that is, during ++ * write---this covers vast majority of all dirty traffic), but we cannot do ++ * this immediately when formatted node is dirtied, because long term lock is ++ * usually held at that time. To work around this, dirtying of formatted node ++ * simply increases ->nr_marked_dirty counter in the current reiser4 ++ * context. When we are about to leave this context, ++ * balance_dirty_pages_ratelimited() is called, if necessary. ++ * ++ * This introduces another problem: sometimes we do not want to run ++ * balance_dirty_pages_ratelimited() when leaving a context, for example ++ * because some important lock (like ->i_mutex on the parent directory) is ++ * held. To achieve this, ->nobalance flag can be set in the current context. ++ */ ++static void balance_dirty_pages_at(reiser4_context *context) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(context->super); ++ ++ /* ++ * call balance_dirty_pages_ratelimited() to process formatted nodes ++ * dirtied during this system call. Do that only if we are not in mount ++ * and there were nodes dirtied in this context and we are not in ++ * writepage (to avoid deadlock) and not in pdflush ++ */ ++ if (sbinfo != NULL && sbinfo->fake != NULL && ++ context->nr_marked_dirty != 0 && ++ !(current->flags & PF_MEMALLOC) && ++ !current_is_pdflush()) ++ balance_dirty_pages_ratelimited(sbinfo->fake->i_mapping); ++} ++ ++/* release resources associated with context. ++ ++ This function should be called at the end of "session" with reiser4, ++ typically just before leaving reiser4 driver back to VFS. ++ ++ This is good place to put some degugging consistency checks, like that ++ thread released all locks and closed transcrash etc. ++ ++*/ ++static void reiser4_done_context(reiser4_context * context) ++ /* context being released */ ++{ ++ assert("nikita-860", context != NULL); ++ assert("nikita-859", context->magic == context_magic); ++ assert("vs-646", (reiser4_context *) current->journal_info == context); ++ assert("zam-686", !in_interrupt() && !in_irq()); ++ ++ /* only do anything when leaving top-level reiser4 context. All nested ++ * contexts are just dummies. */ ++ if (context->nr_children == 0) { ++ assert("jmacd-673", context->trans == NULL); ++ assert("jmacd-1002", lock_stack_isclean(&context->stack)); ++ assert("nikita-1936", reiser4_no_counters_are_held()); ++ assert("nikita-2626", list_empty_careful(reiser4_taps_list())); ++ assert("zam-1004", ergo(get_super_private(context->super), ++ get_super_private(context->super)->delete_mutex_owner != ++ current)); ++ ++ /* release all grabbed but as yet unused blocks */ ++ if (context->grabbed_blocks != 0) ++ all_grabbed2free(); ++ ++ /* ++ * synchronize against longterm_unlock_znode(): ++ * wake_up_requestor() wakes up requestors without holding ++ * zlock (otherwise they will immediately bump into that lock ++ * after wake up on another CPU). To work around (rare) ++ * situation where requestor has been woken up asynchronously ++ * and managed to run until completion (and destroy its ++ * context and lock stack) before wake_up_requestor() called ++ * wake_up() on it, wake_up_requestor() synchronize on lock ++ * stack spin lock. It has actually been observed that spin ++ * lock _was_ locked at this point, because ++ * wake_up_requestor() took interrupt. ++ */ ++ spin_lock_stack(&context->stack); ++ spin_unlock_stack(&context->stack); ++ ++ assert("zam-684", context->nr_children == 0); ++ /* restore original ->fs_context value */ ++ current->journal_info = context->outer; ++ if (context->on_stack == 0) ++ kfree(context); ++ } else { ++ context->nr_children--; ++#if REISER4_DEBUG ++ assert("zam-685", context->nr_children >= 0); ++#endif ++ } ++} ++ ++/* ++ * exit reiser4 context. Call balance_dirty_pages_at() if necessary. Close ++ * transaction. Call done_context() to do context related book-keeping. ++ */ ++void reiser4_exit_context(reiser4_context * context) ++{ ++ assert("nikita-3021", reiser4_schedulable()); ++ ++ if (context->nr_children == 0) { ++ if (!context->nobalance) { ++ reiser4_txn_restart(context); ++ balance_dirty_pages_at(context); ++ } ++ ++ /* if filesystem is mounted with -o sync or -o dirsync - commit ++ transaction. FIXME: TXNH_DONT_COMMIT is used to avoid ++ commiting on exit_context when inode semaphore is held and ++ to have ktxnmgrd to do commit instead to get better ++ concurrent filesystem accesses. But, when one mounts with -o ++ sync, he cares more about reliability than about ++ performance. So, for now we have this simple mount -o sync ++ support. */ ++ if (context->super->s_flags & (MS_SYNCHRONOUS | MS_DIRSYNC)) { ++ txn_atom *atom; ++ ++ atom = get_current_atom_locked_nocheck(); ++ if (atom) { ++ atom->flags |= ATOM_FORCE_COMMIT; ++ context->trans->flags &= ~TXNH_DONT_COMMIT; ++ spin_unlock_atom(atom); ++ } ++ } ++ reiser4_txn_end(context); ++ } ++ reiser4_done_context(context); ++} ++ ++void reiser4_ctx_gfp_mask_set(void) ++{ ++ reiser4_context *ctx; ++ ++ ctx = get_current_context(); ++ if (ctx->entd == 0 && ++ list_empty(&ctx->stack.locks) && ++ ctx->trans->atom == NULL) ++ ctx->gfp_mask = GFP_KERNEL; ++ else ++ ctx->gfp_mask = GFP_NOFS; ++} ++ ++void reiser4_ctx_gfp_mask_force(gfp_t mask) ++{ ++ reiser4_context *ctx; ++ ctx = get_current_context(); ++ ++ assert("edward-1454", ctx != NULL); ++ ++ ctx->gfp_mask = mask; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 120 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/context.h linux-2.6.30/fs/reiser4/context.h +--- linux-2.6.30.orig/fs/reiser4/context.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/context.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,228 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Reiser4 context. See context.c for details. */ ++ ++#if !defined( __REISER4_CONTEXT_H__ ) ++#define __REISER4_CONTEXT_H__ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "tap.h" ++#include "lock.h" ++ ++#include <linux/types.h> /* for __u?? */ ++#include <linux/fs.h> /* for struct super_block */ ++#include <linux/spinlock.h> ++#include <linux/sched.h> /* for struct task_struct */ ++ ++/* reiser4 per-thread context */ ++struct reiser4_context { ++ /* magic constant. For identification of reiser4 contexts. */ ++ __u32 magic; ++ ++ /* current lock stack. See lock.[ch]. This is where list of all ++ locks taken by current thread is kept. This is also used in ++ deadlock detection. */ ++ lock_stack stack; ++ ++ /* current transcrash. */ ++ txn_handle *trans; ++ /* transaction handle embedded into reiser4_context. ->trans points ++ * here by default. */ ++ txn_handle trans_in_ctx; ++ ++ /* super block we are working with. To get the current tree ++ use &get_super_private (reiser4_get_current_sb ())->tree. */ ++ struct super_block *super; ++ ++ /* parent fs activation */ ++ struct fs_activation *outer; ++ ++ /* per-thread grabbed (for further allocation) blocks counter */ ++ reiser4_block_nr grabbed_blocks; ++ ++ /* list of taps currently monitored. See tap.c */ ++ struct list_head taps; ++ ++ /* grabbing space is enabled */ ++ unsigned int grab_enabled:1; ++ /* should be set when we are write dirty nodes to disk in jnode_flush or ++ * reiser4_write_logs() */ ++ unsigned int writeout_mode:1; ++ /* true, if current thread is an ent thread */ ++ unsigned int entd:1; ++ /* true, if balance_dirty_pages() should not be run when leaving this ++ * context. This is used to avoid lengthly balance_dirty_pages() ++ * operation when holding some important resource, like directory ++ * ->i_mutex */ ++ unsigned int nobalance:1; ++ ++ /* this bit is used on reiser4_done_context to decide whether context is ++ kmalloc-ed and has to be kfree-ed */ ++ unsigned int on_stack:1; ++ ++ /* count non-trivial jnode_set_dirty() calls */ ++ unsigned long nr_marked_dirty; ++ ++ /* reiser4_sync_inodes calls (via generic_sync_sb_inodes) ++ * reiser4_writepages for each of dirty inodes. Reiser4_writepages ++ * captures pages. When number of pages captured in one ++ * reiser4_sync_inodes reaches some threshold - some atoms get ++ * flushed */ ++ int nr_captured; ++ int nr_children; /* number of child contexts */ ++#if REISER4_DEBUG ++ /* debugging information about reiser4 locks held by the current ++ * thread */ ++ reiser4_lock_cnt_info locks; ++ struct task_struct *task; /* so we can easily find owner of the stack */ ++ ++ /* ++ * disk space grabbing debugging support ++ */ ++ /* how many disk blocks were grabbed by the first call to ++ * reiser4_grab_space() in this context */ ++ reiser4_block_nr grabbed_initially; ++ ++ /* list of all threads doing flush currently */ ++ struct list_head flushers_link; ++ /* information about last error encountered by reiser4 */ ++ err_site err; ++#endif ++ void *vp; ++ gfp_t gfp_mask; ++}; ++ ++extern reiser4_context *get_context_by_lock_stack(lock_stack *); ++ ++/* Debugging helps. */ ++#if REISER4_DEBUG ++extern void print_contexts(void); ++#endif ++ ++#define current_tree (&(get_super_private(reiser4_get_current_sb())->tree)) ++#define current_blocksize reiser4_get_current_sb()->s_blocksize ++#define current_blocksize_bits reiser4_get_current_sb()->s_blocksize_bits ++ ++extern reiser4_context *reiser4_init_context(struct super_block *); ++extern void init_stack_context(reiser4_context *, struct super_block *); ++extern void reiser4_exit_context(reiser4_context *); ++ ++/* magic constant we store in reiser4_context allocated at the stack. Used to ++ catch accesses to staled or uninitialized contexts. */ ++#define context_magic ((__u32) 0x4b1b5d0b) ++ ++extern int is_in_reiser4_context(void); ++ ++/* ++ * return reiser4_context for the thread @tsk ++ */ ++static inline reiser4_context *get_context(const struct task_struct *tsk) ++{ ++ assert("vs-1682", ++ ((reiser4_context *) tsk->journal_info)->magic == context_magic); ++ return (reiser4_context *) tsk->journal_info; ++} ++ ++/* ++ * return reiser4 context of the current thread, or NULL if there is none. ++ */ ++static inline reiser4_context *get_current_context_check(void) ++{ ++ if (is_in_reiser4_context()) ++ return get_context(current); ++ else ++ return NULL; ++} ++ ++static inline reiser4_context *get_current_context(void); /* __attribute__((const)); */ ++ ++/* return context associated with current thread */ ++static inline reiser4_context *get_current_context(void) ++{ ++ return get_context(current); ++} ++ ++static inline gfp_t reiser4_ctx_gfp_mask_get(void) ++{ ++ reiser4_context *ctx; ++ ++ ctx = get_current_context_check(); ++ return (ctx == NULL) ? GFP_KERNEL : ctx->gfp_mask; ++} ++ ++void reiser4_ctx_gfp_mask_set(void); ++void reiser4_ctx_gfp_mask_force (gfp_t mask); ++ ++/* ++ * true if current thread is in the write-out mode. Thread enters write-out ++ * mode during jnode_flush and reiser4_write_logs(). ++ */ ++static inline int is_writeout_mode(void) ++{ ++ return get_current_context()->writeout_mode; ++} ++ ++/* ++ * enter write-out mode ++ */ ++static inline void writeout_mode_enable(void) ++{ ++ assert("zam-941", !get_current_context()->writeout_mode); ++ get_current_context()->writeout_mode = 1; ++} ++ ++/* ++ * leave write-out mode ++ */ ++static inline void writeout_mode_disable(void) ++{ ++ assert("zam-942", get_current_context()->writeout_mode); ++ get_current_context()->writeout_mode = 0; ++} ++ ++static inline void grab_space_enable(void) ++{ ++ get_current_context()->grab_enabled = 1; ++} ++ ++static inline void grab_space_disable(void) ++{ ++ get_current_context()->grab_enabled = 0; ++} ++ ++static inline void grab_space_set_enabled(int enabled) ++{ ++ get_current_context()->grab_enabled = enabled; ++} ++ ++static inline int is_grab_enabled(reiser4_context * ctx) ++{ ++ return ctx->grab_enabled; ++} ++ ++/* mark transaction handle in @ctx as TXNH_DONT_COMMIT, so that no commit or ++ * flush would be performed when it is closed. This is necessary when handle ++ * has to be closed under some coarse semaphore, like i_mutex of ++ * directory. Commit will be performed by ktxnmgrd. */ ++static inline void context_set_commit_async(reiser4_context * context) ++{ ++ context->nobalance = 1; ++ context->trans->flags |= TXNH_DONT_COMMIT; ++} ++ ++/* __REISER4_CONTEXT_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/coord.c linux-2.6.30/fs/reiser4/coord.c +--- linux-2.6.30.orig/fs/reiser4/coord.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/coord.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,928 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "tree.h" ++#include "plugin/item/item.h" ++#include "znode.h" ++#include "coord.h" ++ ++/* Internal constructor. */ ++static inline void ++coord_init_values(coord_t *coord, const znode * node, pos_in_node_t item_pos, ++ pos_in_node_t unit_pos, between_enum between) ++{ ++ coord->node = (znode *) node; ++ coord_set_item_pos(coord, item_pos); ++ coord->unit_pos = unit_pos; ++ coord->between = between; ++ ON_DEBUG(coord->plug_v = 0); ++ ON_DEBUG(coord->body_v = 0); ++ ++ /*ON_TRACE (TRACE_COORDS, "init coord %p node %p: %u %u %s\n", coord, ++ node, item_pos, unit_pos, coord_tween_tostring (between)); */ ++} ++ ++/* after shifting of node content, coord previously set properly may become ++ invalid, try to "normalize" it. */ ++void coord_normalize(coord_t *coord) ++{ ++ znode *node; ++ ++ node = coord->node; ++ assert("vs-683", node); ++ ++ coord_clear_iplug(coord); ++ ++ if (node_is_empty(node)) { ++ coord_init_first_unit(coord, node); ++ } else if ((coord->between == AFTER_ITEM) ++ || (coord->between == AFTER_UNIT)) { ++ return; ++ } else if (coord->item_pos == coord_num_items(coord) ++ && coord->between == BEFORE_ITEM) { ++ coord_dec_item_pos(coord); ++ coord->between = AFTER_ITEM; ++ } else if (coord->unit_pos == coord_num_units(coord) ++ && coord->between == BEFORE_UNIT) { ++ coord->unit_pos--; ++ coord->between = AFTER_UNIT; ++ } else if (coord->item_pos == coord_num_items(coord) ++ && coord->unit_pos == 0 && coord->between == BEFORE_UNIT) { ++ coord_dec_item_pos(coord); ++ coord->unit_pos = 0; ++ coord->between = AFTER_ITEM; ++ } ++} ++ ++/* Copy a coordinate. */ ++void coord_dup(coord_t *coord, const coord_t *old_coord) ++{ ++ assert("jmacd-9800", coord_check(old_coord)); ++ coord_dup_nocheck(coord, old_coord); ++} ++ ++/* Copy a coordinate without check. Useful when old_coord->node is not ++ loaded. As in cbk_tree_lookup -> connect_znode -> connect_one_side */ ++void coord_dup_nocheck(coord_t *coord, const coord_t *old_coord) ++{ ++ coord->node = old_coord->node; ++ coord_set_item_pos(coord, old_coord->item_pos); ++ coord->unit_pos = old_coord->unit_pos; ++ coord->between = old_coord->between; ++ coord->iplugid = old_coord->iplugid; ++ ON_DEBUG(coord->plug_v = old_coord->plug_v); ++ ON_DEBUG(coord->body_v = old_coord->body_v); ++} ++ ++/* Initialize an invalid coordinate. */ ++void coord_init_invalid(coord_t *coord, const znode * node) ++{ ++ coord_init_values(coord, node, 0, 0, INVALID_COORD); ++} ++ ++void coord_init_first_unit_nocheck(coord_t *coord, const znode * node) ++{ ++ coord_init_values(coord, node, 0, 0, AT_UNIT); ++} ++ ++/* Initialize a coordinate to point at the first unit of the first item. If the ++ node is empty, it is positioned at the EMPTY_NODE. */ ++void coord_init_first_unit(coord_t *coord, const znode * node) ++{ ++ int is_empty = node_is_empty(node); ++ ++ coord_init_values(coord, node, 0, 0, (is_empty ? EMPTY_NODE : AT_UNIT)); ++ ++ assert("jmacd-9801", coord_check(coord)); ++} ++ ++/* Initialize a coordinate to point at the last unit of the last item. If the ++ node is empty, it is positioned at the EMPTY_NODE. */ ++void coord_init_last_unit(coord_t *coord, const znode * node) ++{ ++ int is_empty = node_is_empty(node); ++ ++ coord_init_values(coord, node, ++ (is_empty ? 0 : node_num_items(node) - 1), 0, ++ (is_empty ? EMPTY_NODE : AT_UNIT)); ++ if (!is_empty) ++ coord->unit_pos = coord_last_unit_pos(coord); ++ assert("jmacd-9802", coord_check(coord)); ++} ++ ++/* Initialize a coordinate to before the first item. If the node is empty, it is ++ positioned at the EMPTY_NODE. */ ++void coord_init_before_first_item(coord_t *coord, const znode * node) ++{ ++ int is_empty = node_is_empty(node); ++ ++ coord_init_values(coord, node, 0, 0, ++ (is_empty ? EMPTY_NODE : BEFORE_UNIT)); ++ ++ assert("jmacd-9803", coord_check(coord)); ++} ++ ++/* Initialize a coordinate to after the last item. If the node is empty, it is ++ positioned at the EMPTY_NODE. */ ++void coord_init_after_last_item(coord_t *coord, const znode * node) ++{ ++ int is_empty = node_is_empty(node); ++ ++ coord_init_values(coord, node, ++ (is_empty ? 0 : node_num_items(node) - 1), 0, ++ (is_empty ? EMPTY_NODE : AFTER_ITEM)); ++ ++ assert("jmacd-9804", coord_check(coord)); ++} ++ ++/* Initialize a coordinate to after last unit in the item. Coord must be set ++ already to existing item */ ++void coord_init_after_item_end(coord_t *coord) ++{ ++ coord->between = AFTER_UNIT; ++ coord->unit_pos = coord_last_unit_pos(coord); ++} ++ ++/* Initialize a coordinate to before the item. Coord must be set already to ++ existing item */ ++void coord_init_before_item(coord_t *coord) ++{ ++ coord->unit_pos = 0; ++ coord->between = BEFORE_ITEM; ++} ++ ++/* Initialize a coordinate to after the item. Coord must be set already to ++ existing item */ ++void coord_init_after_item(coord_t *coord) ++{ ++ coord->unit_pos = 0; ++ coord->between = AFTER_ITEM; ++} ++ ++/* Initialize a coordinate by 0s. Used in places where init_coord was used and ++ it was not clear how actually */ ++void coord_init_zero(coord_t *coord) ++{ ++ memset(coord, 0, sizeof(*coord)); ++} ++ ++/* Return the number of units at the present item. ++ Asserts coord_is_existing_item(). */ ++unsigned coord_num_units(const coord_t *coord) ++{ ++ assert("jmacd-9806", coord_is_existing_item(coord)); ++ ++ return item_plugin_by_coord(coord)->b.nr_units(coord); ++} ++ ++/* Returns true if the coord was initializewd by coord_init_invalid (). */ ++/* Audited by: green(2002.06.15) */ ++int coord_is_invalid(const coord_t *coord) ++{ ++ return coord->between == INVALID_COORD; ++} ++ ++/* Returns true if the coordinate is positioned at an existing item, not before ++ or after an item. It may be placed at, before, or after any unit within the ++ item, whether existing or not. */ ++int coord_is_existing_item(const coord_t *coord) ++{ ++ switch (coord->between) { ++ case EMPTY_NODE: ++ case BEFORE_ITEM: ++ case AFTER_ITEM: ++ case INVALID_COORD: ++ return 0; ++ ++ case BEFORE_UNIT: ++ case AT_UNIT: ++ case AFTER_UNIT: ++ return coord->item_pos < coord_num_items(coord); ++ } ++ ++ impossible("jmacd-9900", "unreachable coord: %p", coord); ++ return 0; ++} ++ ++/* Returns true if the coordinate is positioned at an existing unit, not before ++ or after a unit. */ ++/* Audited by: green(2002.06.15) */ ++int coord_is_existing_unit(const coord_t *coord) ++{ ++ switch (coord->between) { ++ case EMPTY_NODE: ++ case BEFORE_UNIT: ++ case AFTER_UNIT: ++ case BEFORE_ITEM: ++ case AFTER_ITEM: ++ case INVALID_COORD: ++ return 0; ++ ++ case AT_UNIT: ++ return (coord->item_pos < coord_num_items(coord) ++ && coord->unit_pos < coord_num_units(coord)); ++ } ++ ++ impossible("jmacd-9902", "unreachable"); ++ return 0; ++} ++ ++/* Returns true if the coordinate is positioned at the first unit of the first ++ item. Not true for empty nodes nor coordinates positioned before the first ++ item. */ ++/* Audited by: green(2002.06.15) */ ++int coord_is_leftmost_unit(const coord_t *coord) ++{ ++ return (coord->between == AT_UNIT && coord->item_pos == 0 ++ && coord->unit_pos == 0); ++} ++ ++#if REISER4_DEBUG ++/* For assertions only, checks for a valid coordinate. */ ++int coord_check(const coord_t *coord) ++{ ++ if (coord->node == NULL) ++ return 0; ++ if (znode_above_root(coord->node)) ++ return 1; ++ ++ switch (coord->between) { ++ default: ++ case INVALID_COORD: ++ return 0; ++ case EMPTY_NODE: ++ if (!node_is_empty(coord->node)) ++ return 0; ++ return coord->item_pos == 0 && coord->unit_pos == 0; ++ ++ case BEFORE_UNIT: ++ case AFTER_UNIT: ++ if (node_is_empty(coord->node) && (coord->item_pos == 0) ++ && (coord->unit_pos == 0)) ++ return 1; ++ case AT_UNIT: ++ break; ++ case AFTER_ITEM: ++ case BEFORE_ITEM: ++ /* before/after item should not set unit_pos. */ ++ if (coord->unit_pos != 0) ++ return 0; ++ break; ++ } ++ ++ if (coord->item_pos >= node_num_items(coord->node)) ++ return 0; ++ ++ /* FIXME-VS: we are going to check unit_pos. This makes no sense when ++ between is set either AFTER_ITEM or BEFORE_ITEM */ ++ if (coord->between == AFTER_ITEM || coord->between == BEFORE_ITEM) ++ return 1; ++ ++ if (coord_is_iplug_set(coord) && ++ coord->unit_pos > ++ item_plugin_by_coord(coord)->b.nr_units(coord) - 1) ++ return 0; ++ return 1; ++} ++#endif ++ ++/* Adjust coordinate boundaries based on the number of items prior to ++ coord_next/prev. Returns 1 if the new position is does not exist. */ ++static int coord_adjust_items(coord_t *coord, unsigned items, int is_next) ++{ ++ /* If the node is invalid, leave it. */ ++ if (coord->between == INVALID_COORD) ++ return 1; ++ ++ /* If the node is empty, set it appropriately. */ ++ if (items == 0) { ++ coord->between = EMPTY_NODE; ++ coord_set_item_pos(coord, 0); ++ coord->unit_pos = 0; ++ return 1; ++ } ++ ++ /* If it was empty and it no longer is, set to BEFORE/AFTER_ITEM. */ ++ if (coord->between == EMPTY_NODE) { ++ coord->between = (is_next ? BEFORE_ITEM : AFTER_ITEM); ++ coord_set_item_pos(coord, 0); ++ coord->unit_pos = 0; ++ return 0; ++ } ++ ++ /* If the item_pos is out-of-range, set it appropriatly. */ ++ if (coord->item_pos >= items) { ++ coord->between = AFTER_ITEM; ++ coord_set_item_pos(coord, items - 1); ++ coord->unit_pos = 0; ++ /* If is_next, return 1 (can't go any further). */ ++ return is_next; ++ } ++ ++ return 0; ++} ++ ++/* Advances the coordinate by one unit to the right. If empty, no change. If ++ coord_is_rightmost_unit, advances to AFTER THE LAST ITEM. Returns 0 if new ++ position is an existing unit. */ ++int coord_next_unit(coord_t *coord) ++{ ++ unsigned items = coord_num_items(coord); ++ ++ if (coord_adjust_items(coord, items, 1) == 1) ++ return 1; ++ ++ switch (coord->between) { ++ case BEFORE_UNIT: ++ /* Now it is positioned at the same unit. */ ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case AFTER_UNIT: ++ case AT_UNIT: ++ /* If it was at or after a unit and there are more units in this ++ item, advance to the next one. */ ++ if (coord->unit_pos < coord_last_unit_pos(coord)) { ++ coord->unit_pos += 1; ++ coord->between = AT_UNIT; ++ return 0; ++ } ++ ++ /* Otherwise, it is crossing an item boundary and treated as if ++ it was after the current item. */ ++ coord->between = AFTER_ITEM; ++ coord->unit_pos = 0; ++ /* FALLTHROUGH */ ++ ++ case AFTER_ITEM: ++ /* Check for end-of-node. */ ++ if (coord->item_pos == items - 1) ++ return 1; ++ ++ coord_inc_item_pos(coord); ++ coord->unit_pos = 0; ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case BEFORE_ITEM: ++ /* The adjust_items checks ensure that we are valid here. */ ++ coord->unit_pos = 0; ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case INVALID_COORD: ++ case EMPTY_NODE: ++ /* Handled in coord_adjust_items(). */ ++ break; ++ } ++ ++ impossible("jmacd-9902", "unreachable"); ++ return 0; ++} ++ ++/* Advances the coordinate by one item to the right. If empty, no change. If ++ coord_is_rightmost_unit, advances to AFTER THE LAST ITEM. Returns 0 if new ++ position is an existing item. */ ++int coord_next_item(coord_t *coord) ++{ ++ unsigned items = coord_num_items(coord); ++ ++ if (coord_adjust_items(coord, items, 1) == 1) ++ return 1; ++ ++ switch (coord->between) { ++ case AFTER_UNIT: ++ case AT_UNIT: ++ case BEFORE_UNIT: ++ case AFTER_ITEM: ++ /* Check for end-of-node. */ ++ if (coord->item_pos == items - 1) { ++ coord->between = AFTER_ITEM; ++ coord->unit_pos = 0; ++ coord_clear_iplug(coord); ++ return 1; ++ } ++ ++ /* Anywhere in an item, go to the next one. */ ++ coord->between = AT_UNIT; ++ coord_inc_item_pos(coord); ++ coord->unit_pos = 0; ++ return 0; ++ ++ case BEFORE_ITEM: ++ /* The out-of-range check ensures that we are valid here. */ ++ coord->unit_pos = 0; ++ coord->between = AT_UNIT; ++ return 0; ++ case INVALID_COORD: ++ case EMPTY_NODE: ++ /* Handled in coord_adjust_items(). */ ++ break; ++ } ++ ++ impossible("jmacd-9903", "unreachable"); ++ return 0; ++} ++ ++/* Advances the coordinate by one unit to the left. If empty, no change. If ++ coord_is_leftmost_unit, advances to BEFORE THE FIRST ITEM. Returns 0 if new ++ position is an existing unit. */ ++int coord_prev_unit(coord_t *coord) ++{ ++ unsigned items = coord_num_items(coord); ++ ++ if (coord_adjust_items(coord, items, 0) == 1) ++ return 1; ++ ++ switch (coord->between) { ++ case AT_UNIT: ++ case BEFORE_UNIT: ++ if (coord->unit_pos > 0) { ++ coord->unit_pos -= 1; ++ coord->between = AT_UNIT; ++ return 0; ++ } ++ ++ if (coord->item_pos == 0) { ++ coord->between = BEFORE_ITEM; ++ return 1; ++ } ++ ++ coord_dec_item_pos(coord); ++ coord->unit_pos = coord_last_unit_pos(coord); ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case AFTER_UNIT: ++ /* What if unit_pos is out-of-range? */ ++ assert("jmacd-5442", ++ coord->unit_pos <= coord_last_unit_pos(coord)); ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case BEFORE_ITEM: ++ if (coord->item_pos == 0) ++ return 1; ++ ++ coord_dec_item_pos(coord); ++ /* FALLTHROUGH */ ++ ++ case AFTER_ITEM: ++ coord->between = AT_UNIT; ++ coord->unit_pos = coord_last_unit_pos(coord); ++ return 0; ++ ++ case INVALID_COORD: ++ case EMPTY_NODE: ++ break; ++ } ++ ++ impossible("jmacd-9904", "unreachable"); ++ return 0; ++} ++ ++/* Advances the coordinate by one item to the left. If empty, no change. If ++ coord_is_leftmost_unit, advances to BEFORE THE FIRST ITEM. Returns 0 if new ++ position is an existing item. */ ++int coord_prev_item(coord_t *coord) ++{ ++ unsigned items = coord_num_items(coord); ++ ++ if (coord_adjust_items(coord, items, 0) == 1) ++ return 1; ++ ++ switch (coord->between) { ++ case AT_UNIT: ++ case AFTER_UNIT: ++ case BEFORE_UNIT: ++ case BEFORE_ITEM: ++ ++ if (coord->item_pos == 0) { ++ coord->between = BEFORE_ITEM; ++ coord->unit_pos = 0; ++ return 1; ++ } ++ ++ coord_dec_item_pos(coord); ++ coord->unit_pos = 0; ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case AFTER_ITEM: ++ coord->between = AT_UNIT; ++ coord->unit_pos = 0; ++ return 0; ++ ++ case INVALID_COORD: ++ case EMPTY_NODE: ++ break; ++ } ++ ++ impossible("jmacd-9905", "unreachable"); ++ return 0; ++} ++ ++/* Calls either coord_init_first_unit or coord_init_last_unit depending on ++ sideof argument. */ ++void coord_init_sideof_unit(coord_t *coord, const znode * node, sideof dir) ++{ ++ assert("jmacd-9821", dir == LEFT_SIDE || dir == RIGHT_SIDE); ++ if (dir == LEFT_SIDE) { ++ coord_init_first_unit(coord, node); ++ } else { ++ coord_init_last_unit(coord, node); ++ } ++} ++ ++/* Calls either coord_is_before_leftmost or coord_is_after_rightmost depending ++ on sideof argument. */ ++/* Audited by: green(2002.06.15) */ ++int coord_is_after_sideof_unit(coord_t *coord, sideof dir) ++{ ++ assert("jmacd-9822", dir == LEFT_SIDE || dir == RIGHT_SIDE); ++ if (dir == LEFT_SIDE) { ++ return coord_is_before_leftmost(coord); ++ } else { ++ return coord_is_after_rightmost(coord); ++ } ++} ++ ++/* Calls either coord_next_unit or coord_prev_unit depending on sideof argument. ++ */ ++/* Audited by: green(2002.06.15) */ ++int coord_sideof_unit(coord_t *coord, sideof dir) ++{ ++ assert("jmacd-9823", dir == LEFT_SIDE || dir == RIGHT_SIDE); ++ if (dir == LEFT_SIDE) { ++ return coord_prev_unit(coord); ++ } else { ++ return coord_next_unit(coord); ++ } ++} ++ ++#if REISER4_DEBUG ++int coords_equal(const coord_t *c1, const coord_t *c2) ++{ ++ assert("nikita-2840", c1 != NULL); ++ assert("nikita-2841", c2 != NULL); ++ ++ return ++ c1->node == c2->node && ++ c1->item_pos == c2->item_pos && ++ c1->unit_pos == c2->unit_pos && c1->between == c2->between; ++} ++#endif /* REISER4_DEBUG */ ++ ++/* If coord_is_after_rightmost return NCOORD_ON_THE_RIGHT, if ++ coord_is_after_leftmost return NCOORD_ON_THE_LEFT, otherwise return ++ NCOORD_INSIDE. */ ++/* Audited by: green(2002.06.15) */ ++coord_wrt_node coord_wrt(const coord_t *coord) ++{ ++ if (coord_is_before_leftmost(coord)) ++ return COORD_ON_THE_LEFT; ++ ++ if (coord_is_after_rightmost(coord)) ++ return COORD_ON_THE_RIGHT; ++ ++ return COORD_INSIDE; ++} ++ ++/* Returns true if the coordinate is positioned after the last item or after the ++ last unit of the last item or it is an empty node. */ ++/* Audited by: green(2002.06.15) */ ++int coord_is_after_rightmost(const coord_t *coord) ++{ ++ assert("jmacd-7313", coord_check(coord)); ++ ++ switch (coord->between) { ++ case INVALID_COORD: ++ case AT_UNIT: ++ case BEFORE_UNIT: ++ case BEFORE_ITEM: ++ return 0; ++ ++ case EMPTY_NODE: ++ return 1; ++ ++ case AFTER_ITEM: ++ return (coord->item_pos == node_num_items(coord->node) - 1); ++ ++ case AFTER_UNIT: ++ return ((coord->item_pos == node_num_items(coord->node) - 1) && ++ coord->unit_pos == coord_last_unit_pos(coord)); ++ } ++ ++ impossible("jmacd-9908", "unreachable"); ++ return 0; ++} ++ ++/* Returns true if the coordinate is positioned before the first item or it is ++ an empty node. */ ++int coord_is_before_leftmost(const coord_t *coord) ++{ ++ /* FIXME-VS: coord_check requires node to be loaded whereas it is not ++ necessary to check if coord is set before leftmost ++ assert ("jmacd-7313", coord_check (coord)); */ ++ switch (coord->between) { ++ case INVALID_COORD: ++ case AT_UNIT: ++ case AFTER_ITEM: ++ case AFTER_UNIT: ++ return 0; ++ ++ case EMPTY_NODE: ++ return 1; ++ ++ case BEFORE_ITEM: ++ case BEFORE_UNIT: ++ return (coord->item_pos == 0) && (coord->unit_pos == 0); ++ } ++ ++ impossible("jmacd-9908", "unreachable"); ++ return 0; ++} ++ ++/* Returns true if the coordinate is positioned after a item, before a item, ++ after the last unit of an item, before the first unit of an item, or at an ++ empty node. */ ++/* Audited by: green(2002.06.15) */ ++int coord_is_between_items(const coord_t *coord) ++{ ++ assert("jmacd-7313", coord_check(coord)); ++ ++ switch (coord->between) { ++ case INVALID_COORD: ++ case AT_UNIT: ++ return 0; ++ ++ case AFTER_ITEM: ++ case BEFORE_ITEM: ++ case EMPTY_NODE: ++ return 1; ++ ++ case BEFORE_UNIT: ++ return coord->unit_pos == 0; ++ ++ case AFTER_UNIT: ++ return coord->unit_pos == coord_last_unit_pos(coord); ++ } ++ ++ impossible("jmacd-9908", "unreachable"); ++ return 0; ++} ++ ++#if REISER4_DEBUG ++/* Returns true if the coordinates are positioned at adjacent units, regardless ++ of before-after or item boundaries. */ ++int coord_are_neighbors(coord_t *c1, coord_t *c2) ++{ ++ coord_t *left; ++ coord_t *right; ++ ++ assert("nikita-1241", c1 != NULL); ++ assert("nikita-1242", c2 != NULL); ++ assert("nikita-1243", c1->node == c2->node); ++ assert("nikita-1244", coord_is_existing_unit(c1)); ++ assert("nikita-1245", coord_is_existing_unit(c2)); ++ ++ left = right = NULL; ++ switch (coord_compare(c1, c2)) { ++ case COORD_CMP_ON_LEFT: ++ left = c1; ++ right = c2; ++ break; ++ case COORD_CMP_ON_RIGHT: ++ left = c2; ++ right = c1; ++ break; ++ case COORD_CMP_SAME: ++ return 0; ++ default: ++ wrong_return_value("nikita-1246", "compare_coords()"); ++ } ++ assert("vs-731", left && right); ++ if (left->item_pos == right->item_pos) { ++ return left->unit_pos + 1 == right->unit_pos; ++ } else if (left->item_pos + 1 == right->item_pos) { ++ return (left->unit_pos == coord_last_unit_pos(left)) ++ && (right->unit_pos == 0); ++ } else { ++ return 0; ++ } ++} ++#endif /* REISER4_DEBUG */ ++ ++/* Assuming two coordinates are positioned in the same node, return ++ COORD_CMP_ON_RIGHT, COORD_CMP_ON_LEFT, or COORD_CMP_SAME depending on c1's ++ position relative to c2. */ ++/* Audited by: green(2002.06.15) */ ++coord_cmp coord_compare(coord_t *c1, coord_t *c2) ++{ ++ assert("vs-209", c1->node == c2->node); ++ assert("vs-194", coord_is_existing_unit(c1) ++ && coord_is_existing_unit(c2)); ++ ++ if (c1->item_pos > c2->item_pos) ++ return COORD_CMP_ON_RIGHT; ++ if (c1->item_pos < c2->item_pos) ++ return COORD_CMP_ON_LEFT; ++ if (c1->unit_pos > c2->unit_pos) ++ return COORD_CMP_ON_RIGHT; ++ if (c1->unit_pos < c2->unit_pos) ++ return COORD_CMP_ON_LEFT; ++ return COORD_CMP_SAME; ++} ++ ++/* If the coordinate is between items, shifts it to the right. Returns 0 on ++ success and non-zero if there is no position to the right. */ ++int coord_set_to_right(coord_t *coord) ++{ ++ unsigned items = coord_num_items(coord); ++ ++ if (coord_adjust_items(coord, items, 1) == 1) ++ return 1; ++ ++ switch (coord->between) { ++ case AT_UNIT: ++ return 0; ++ ++ case BEFORE_ITEM: ++ case BEFORE_UNIT: ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case AFTER_UNIT: ++ if (coord->unit_pos < coord_last_unit_pos(coord)) { ++ coord->unit_pos += 1; ++ coord->between = AT_UNIT; ++ return 0; ++ } else { ++ ++ coord->unit_pos = 0; ++ ++ if (coord->item_pos == items - 1) { ++ coord->between = AFTER_ITEM; ++ return 1; ++ } ++ ++ coord_inc_item_pos(coord); ++ coord->between = AT_UNIT; ++ return 0; ++ } ++ ++ case AFTER_ITEM: ++ if (coord->item_pos == items - 1) ++ return 1; ++ ++ coord_inc_item_pos(coord); ++ coord->unit_pos = 0; ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case EMPTY_NODE: ++ return 1; ++ ++ case INVALID_COORD: ++ break; ++ } ++ ++ impossible("jmacd-9920", "unreachable"); ++ return 0; ++} ++ ++/* If the coordinate is between items, shifts it to the left. Returns 0 on ++ success and non-zero if there is no position to the left. */ ++int coord_set_to_left(coord_t *coord) ++{ ++ unsigned items = coord_num_items(coord); ++ ++ if (coord_adjust_items(coord, items, 0) == 1) ++ return 1; ++ ++ switch (coord->between) { ++ case AT_UNIT: ++ return 0; ++ ++ case AFTER_UNIT: ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case AFTER_ITEM: ++ coord->between = AT_UNIT; ++ coord->unit_pos = coord_last_unit_pos(coord); ++ return 0; ++ ++ case BEFORE_UNIT: ++ if (coord->unit_pos > 0) { ++ coord->unit_pos -= 1; ++ coord->between = AT_UNIT; ++ return 0; ++ } else { ++ ++ if (coord->item_pos == 0) { ++ coord->between = BEFORE_ITEM; ++ return 1; ++ } ++ ++ coord->unit_pos = coord_last_unit_pos(coord); ++ coord_dec_item_pos(coord); ++ coord->between = AT_UNIT; ++ return 0; ++ } ++ ++ case BEFORE_ITEM: ++ if (coord->item_pos == 0) ++ return 1; ++ ++ coord_dec_item_pos(coord); ++ coord->unit_pos = coord_last_unit_pos(coord); ++ coord->between = AT_UNIT; ++ return 0; ++ ++ case EMPTY_NODE: ++ return 1; ++ ++ case INVALID_COORD: ++ break; ++ } ++ ++ impossible("jmacd-9920", "unreachable"); ++ return 0; ++} ++ ++static const char *coord_tween_tostring(between_enum n) ++{ ++ switch (n) { ++ case BEFORE_UNIT: ++ return "before unit"; ++ case BEFORE_ITEM: ++ return "before item"; ++ case AT_UNIT: ++ return "at unit"; ++ case AFTER_UNIT: ++ return "after unit"; ++ case AFTER_ITEM: ++ return "after item"; ++ case EMPTY_NODE: ++ return "empty node"; ++ case INVALID_COORD: ++ return "invalid"; ++ default: ++ { ++ static char buf[30]; ++ ++ sprintf(buf, "unknown: %i", n); ++ return buf; ++ } ++ } ++} ++ ++void print_coord(const char *mes, const coord_t *coord, int node) ++{ ++ if (coord == NULL) { ++ printk("%s: null\n", mes); ++ return; ++ } ++ printk("%s: item_pos = %d, unit_pos %d, tween=%s, iplug=%d\n", ++ mes, coord->item_pos, coord->unit_pos, ++ coord_tween_tostring(coord->between), coord->iplugid); ++} ++ ++int ++item_utmost_child_real_block(const coord_t *coord, sideof side, ++ reiser4_block_nr * blk) ++{ ++ return item_plugin_by_coord(coord)->f.utmost_child_real_block(coord, ++ side, ++ blk); ++} ++ ++int item_utmost_child(const coord_t *coord, sideof side, jnode ** child) ++{ ++ return item_plugin_by_coord(coord)->f.utmost_child(coord, side, child); ++} ++ ++/* @count bytes of flow @f got written, update correspondingly f->length, ++ f->data and f->key */ ++void move_flow_forward(flow_t *f, unsigned count) ++{ ++ if (f->data) ++ f->data += count; ++ f->length -= count; ++ set_key_offset(&f->key, get_key_offset(&f->key) + count); ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/coord.h linux-2.6.30/fs/reiser4/coord.h +--- linux-2.6.30.orig/fs/reiser4/coord.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/coord.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,399 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* Coords */ ++ ++#if !defined(__REISER4_COORD_H__) ++#define __REISER4_COORD_H__ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++ ++/* insertions happen between coords in the tree, so we need some means ++ of specifying the sense of betweenness. */ ++typedef enum { ++ BEFORE_UNIT, /* Note: we/init_coord depends on this value being zero. */ ++ AT_UNIT, ++ AFTER_UNIT, ++ BEFORE_ITEM, ++ AFTER_ITEM, ++ INVALID_COORD, ++ EMPTY_NODE, ++} between_enum; ++ ++/* location of coord w.r.t. its node */ ++typedef enum { ++ COORD_ON_THE_LEFT = -1, ++ COORD_ON_THE_RIGHT = +1, ++ COORD_INSIDE = 0 ++} coord_wrt_node; ++ ++typedef enum { ++ COORD_CMP_SAME = 0, COORD_CMP_ON_LEFT = -1, COORD_CMP_ON_RIGHT = +1 ++} coord_cmp; ++ ++struct coord { ++ /* node in a tree */ ++ /* 0 */ znode *node; ++ ++ /* position of item within node */ ++ /* 4 */ pos_in_node_t item_pos; ++ /* position of unit within item */ ++ /* 6 */ pos_in_node_t unit_pos; ++ /* optimization: plugin of item is stored in coord_t. Until this was ++ implemented, item_plugin_by_coord() was major CPU consumer. ->iplugid ++ is invalidated (set to 0xff) on each modification of ->item_pos, ++ and all such modifications are funneled through coord_*_item_pos() ++ functions below. ++ */ ++ /* 8 */ char iplugid; ++ /* position of coord w.r.t. to neighboring items and/or units. ++ Values are taken from &between_enum above. ++ */ ++ /* 9 */ char between; ++ /* padding. It will be added by the compiler anyway to conform to the ++ * C language alignment requirements. We keep it here to be on the ++ * safe side and to have a clear picture of the memory layout of this ++ * structure. */ ++ /* 10 */ __u16 pad; ++ /* 12 */ int offset; ++#if REISER4_DEBUG ++ unsigned long plug_v; ++ unsigned long body_v; ++#endif ++}; ++ ++#define INVALID_PLUGID ((char)((1 << 8) - 1)) ++#define INVALID_OFFSET -1 ++ ++static inline void coord_clear_iplug(coord_t *coord) ++{ ++ assert("nikita-2835", coord != NULL); ++ coord->iplugid = INVALID_PLUGID; ++ coord->offset = INVALID_OFFSET; ++} ++ ++static inline int coord_is_iplug_set(const coord_t *coord) ++{ ++ assert("nikita-2836", coord != NULL); ++ return coord->iplugid != INVALID_PLUGID; ++} ++ ++static inline void coord_set_item_pos(coord_t *coord, pos_in_node_t pos) ++{ ++ assert("nikita-2478", coord != NULL); ++ coord->item_pos = pos; ++ coord_clear_iplug(coord); ++} ++ ++static inline void coord_dec_item_pos(coord_t *coord) ++{ ++ assert("nikita-2480", coord != NULL); ++ --coord->item_pos; ++ coord_clear_iplug(coord); ++} ++ ++static inline void coord_inc_item_pos(coord_t *coord) ++{ ++ assert("nikita-2481", coord != NULL); ++ ++coord->item_pos; ++ coord_clear_iplug(coord); ++} ++ ++static inline void coord_add_item_pos(coord_t *coord, int delta) ++{ ++ assert("nikita-2482", coord != NULL); ++ coord->item_pos += delta; ++ coord_clear_iplug(coord); ++} ++ ++static inline void coord_invalid_item_pos(coord_t *coord) ++{ ++ assert("nikita-2832", coord != NULL); ++ coord->item_pos = (unsigned short)~0; ++ coord_clear_iplug(coord); ++} ++ ++/* Reverse a direction. */ ++static inline sideof sideof_reverse(sideof side) ++{ ++ return side == LEFT_SIDE ? RIGHT_SIDE : LEFT_SIDE; ++} ++ ++/* NOTE: There is a somewhat odd mixture of the following opposed terms: ++ ++ "first" and "last" ++ "next" and "prev" ++ "before" and "after" ++ "leftmost" and "rightmost" ++ ++ But I think the chosen names are decent the way they are. ++*/ ++ ++/* COORD INITIALIZERS */ ++ ++/* Initialize an invalid coordinate. */ ++extern void coord_init_invalid(coord_t *coord, const znode * node); ++ ++extern void coord_init_first_unit_nocheck(coord_t *coord, const znode * node); ++ ++/* Initialize a coordinate to point at the first unit of the first item. If the ++ node is empty, it is positioned at the EMPTY_NODE. */ ++extern void coord_init_first_unit(coord_t *coord, const znode * node); ++ ++/* Initialize a coordinate to point at the last unit of the last item. If the ++ node is empty, it is positioned at the EMPTY_NODE. */ ++extern void coord_init_last_unit(coord_t *coord, const znode * node); ++ ++/* Initialize a coordinate to before the first item. If the node is empty, it is ++ positioned at the EMPTY_NODE. */ ++extern void coord_init_before_first_item(coord_t *coord, const znode * node); ++ ++/* Initialize a coordinate to after the last item. If the node is empty, it is ++ positioned at the EMPTY_NODE. */ ++extern void coord_init_after_last_item(coord_t *coord, const znode * node); ++ ++/* Initialize a coordinate to after last unit in the item. Coord must be set ++ already to existing item */ ++void coord_init_after_item_end(coord_t *coord); ++ ++/* Initialize a coordinate to before the item. Coord must be set already to ++ existing item */ ++void coord_init_before_item(coord_t *); ++/* Initialize a coordinate to after the item. Coord must be set already to ++ existing item */ ++void coord_init_after_item(coord_t *); ++ ++/* Calls either coord_init_first_unit or coord_init_last_unit depending on ++ sideof argument. */ ++extern void coord_init_sideof_unit(coord_t *coord, const znode * node, ++ sideof dir); ++ ++/* Initialize a coordinate by 0s. Used in places where init_coord was used and ++ it was not clear how actually ++ FIXME-VS: added by vs (2002, june, 8) */ ++extern void coord_init_zero(coord_t *coord); ++ ++/* COORD METHODS */ ++ ++/* after shifting of node content, coord previously set properly may become ++ invalid, try to "normalize" it. */ ++void coord_normalize(coord_t *coord); ++ ++/* Copy a coordinate. */ ++extern void coord_dup(coord_t *coord, const coord_t *old_coord); ++ ++/* Copy a coordinate without check. */ ++void coord_dup_nocheck(coord_t *coord, const coord_t *old_coord); ++ ++unsigned coord_num_units(const coord_t *coord); ++ ++/* Return the last valid unit number at the present item (i.e., ++ coord_num_units() - 1). */ ++static inline unsigned coord_last_unit_pos(const coord_t *coord) ++{ ++ return coord_num_units(coord) - 1; ++} ++ ++#if REISER4_DEBUG ++/* For assertions only, checks for a valid coordinate. */ ++extern int coord_check(const coord_t *coord); ++ ++extern unsigned long znode_times_locked(const znode * z); ++ ++static inline void coord_update_v(coord_t *coord) ++{ ++ coord->plug_v = coord->body_v = znode_times_locked(coord->node); ++} ++#endif ++ ++extern int coords_equal(const coord_t *c1, const coord_t *c2); ++ ++extern void print_coord(const char *mes, const coord_t *coord, int print_node); ++ ++/* If coord_is_after_rightmost return NCOORD_ON_THE_RIGHT, if ++ coord_is_after_leftmost return NCOORD_ON_THE_LEFT, otherwise return ++ NCOORD_INSIDE. */ ++extern coord_wrt_node coord_wrt(const coord_t *coord); ++ ++/* Returns true if the coordinates are positioned at adjacent units, regardless ++ of before-after or item boundaries. */ ++extern int coord_are_neighbors(coord_t *c1, coord_t *c2); ++ ++/* Assuming two coordinates are positioned in the same node, return ++ NCOORD_CMP_ON_RIGHT, NCOORD_CMP_ON_LEFT, or NCOORD_CMP_SAME depending on c1's ++ position relative to c2. */ ++extern coord_cmp coord_compare(coord_t *c1, coord_t *c2); ++ ++/* COORD PREDICATES */ ++ ++/* Returns true if the coord was initializewd by coord_init_invalid (). */ ++extern int coord_is_invalid(const coord_t *coord); ++ ++/* Returns true if the coordinate is positioned at an existing item, not before ++ or after an item. It may be placed at, before, or after any unit within the ++ item, whether existing or not. If this is true you can call methods of the ++ item plugin. */ ++extern int coord_is_existing_item(const coord_t *coord); ++ ++/* Returns true if the coordinate is positioned after a item, before a item, ++ after the last unit of an item, before the first unit of an item, or at an ++ empty node. */ ++extern int coord_is_between_items(const coord_t *coord); ++ ++/* Returns true if the coordinate is positioned at an existing unit, not before ++ or after a unit. */ ++extern int coord_is_existing_unit(const coord_t *coord); ++ ++/* Returns true if the coordinate is positioned at an empty node. */ ++extern int coord_is_empty(const coord_t *coord); ++ ++/* Returns true if the coordinate is positioned at the first unit of the first ++ item. Not true for empty nodes nor coordinates positioned before the first ++ item. */ ++extern int coord_is_leftmost_unit(const coord_t *coord); ++ ++/* Returns true if the coordinate is positioned after the last item or after the ++ last unit of the last item or it is an empty node. */ ++extern int coord_is_after_rightmost(const coord_t *coord); ++ ++/* Returns true if the coordinate is positioned before the first item or it is ++ an empty node. */ ++extern int coord_is_before_leftmost(const coord_t *coord); ++ ++/* Calls either coord_is_before_leftmost or coord_is_after_rightmost depending ++ on sideof argument. */ ++extern int coord_is_after_sideof_unit(coord_t *coord, sideof dir); ++ ++/* COORD MODIFIERS */ ++ ++/* Advances the coordinate by one unit to the right. If empty, no change. If ++ coord_is_rightmost_unit, advances to AFTER THE LAST ITEM. Returns 0 if new ++ position is an existing unit. */ ++extern int coord_next_unit(coord_t *coord); ++ ++/* Advances the coordinate by one item to the right. If empty, no change. If ++ coord_is_rightmost_unit, advances to AFTER THE LAST ITEM. Returns 0 if new ++ position is an existing item. */ ++extern int coord_next_item(coord_t *coord); ++ ++/* Advances the coordinate by one unit to the left. If empty, no change. If ++ coord_is_leftmost_unit, advances to BEFORE THE FIRST ITEM. Returns 0 if new ++ position is an existing unit. */ ++extern int coord_prev_unit(coord_t *coord); ++ ++/* Advances the coordinate by one item to the left. If empty, no change. If ++ coord_is_leftmost_unit, advances to BEFORE THE FIRST ITEM. Returns 0 if new ++ position is an existing item. */ ++extern int coord_prev_item(coord_t *coord); ++ ++/* If the coordinate is between items, shifts it to the right. Returns 0 on ++ success and non-zero if there is no position to the right. */ ++extern int coord_set_to_right(coord_t *coord); ++ ++/* If the coordinate is between items, shifts it to the left. Returns 0 on ++ success and non-zero if there is no position to the left. */ ++extern int coord_set_to_left(coord_t *coord); ++ ++/* If the coordinate is at an existing unit, set to after that unit. Returns 0 ++ on success and non-zero if the unit did not exist. */ ++extern int coord_set_after_unit(coord_t *coord); ++ ++/* Calls either coord_next_unit or coord_prev_unit depending on sideof ++ argument. */ ++extern int coord_sideof_unit(coord_t *coord, sideof dir); ++ ++/* iterate over all units in @node */ ++#define for_all_units(coord, node) \ ++ for (coord_init_before_first_item((coord), (node)) ; \ ++ coord_next_unit(coord) == 0 ;) ++ ++/* iterate over all items in @node */ ++#define for_all_items(coord, node) \ ++ for (coord_init_before_first_item((coord), (node)) ; \ ++ coord_next_item(coord) == 0 ;) ++ ++/* COORD/ITEM METHODS */ ++ ++extern int item_utmost_child_real_block(const coord_t *coord, sideof side, ++ reiser4_block_nr * blk); ++extern int item_utmost_child(const coord_t *coord, sideof side, ++ jnode ** child); ++ ++/* a flow is a sequence of bytes being written to or read from the tree. The ++ tree will slice the flow into items while storing it into nodes, but all of ++ that is hidden from anything outside the tree. */ ++ ++struct flow { ++ reiser4_key key; /* key of start of flow's sequence of bytes */ ++ loff_t length; /* length of flow's sequence of bytes */ ++ char *data; /* start of flow's sequence of bytes */ ++ int user; /* if 1 data is user space, 0 - kernel space */ ++ rw_op op; /* NIKITA-FIXME-HANS: comment is where? */ ++}; ++ ++void move_flow_forward(flow_t *f, unsigned count); ++ ++/* &reiser4_item_data - description of data to be inserted or pasted ++ ++ Q: articulate the reasons for the difference between this and flow. ++ ++ A: Becides flow we insert into tree other things: stat data, directory ++ entry, etc. To insert them into tree one has to provide this structure. If ++ one is going to insert flow - he can use insert_flow, where this structure ++ does not have to be created ++*/ ++struct reiser4_item_data { ++ /* actual data to be inserted. If NULL, ->create_item() will not ++ do xmemcpy itself, leaving this up to the caller. This can ++ save some amount of unnecessary memory copying, for example, ++ during insertion of stat data. ++ ++ */ ++ char *data; ++ /* 1 if 'char * data' contains pointer to user space and 0 if it is ++ kernel space */ ++ int user; ++ /* amount of data we are going to insert or paste */ ++ int length; ++ /* "Arg" is opaque data that is passed down to the ++ ->create_item() method of node layout, which in turn ++ hands it to the ->create_hook() of item being created. This ++ arg is currently used by: ++ ++ . ->create_hook() of internal item ++ (fs/reiser4/plugin/item/internal.c:internal_create_hook()), ++ . ->paste() method of directory item. ++ . ->create_hook() of extent item ++ ++ For internal item, this is left "brother" of new node being ++ inserted and it is used to add new node into sibling list ++ after parent to it was just inserted into parent. ++ ++ While ->arg does look somewhat of unnecessary compication, ++ it actually saves a lot of headache in many places, because ++ all data necessary to insert or paste new data into tree are ++ collected in one place, and this eliminates a lot of extra ++ argument passing and storing everywhere. ++ ++ */ ++ void *arg; ++ /* plugin of item we are inserting */ ++ item_plugin *iplug; ++}; ++ ++/* __REISER4_COORD_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/debug.c linux-2.6.30/fs/reiser4/debug.c +--- linux-2.6.30.orig/fs/reiser4/debug.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/debug.c 2009-06-22 18:11:49.000000000 +0200 +@@ -0,0 +1,308 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Debugging facilities. */ ++ ++/* ++ * This file contains generic debugging functions used by reiser4. Roughly ++ * following: ++ * ++ * panicking: reiser4_do_panic(), reiser4_print_prefix(). ++ * ++ * locking: ++ * reiser4_schedulable(), reiser4_lock_counters(), print_lock_counters(), ++ * reiser4_no_counters_are_held(), reiser4_commit_check_locks() ++ * ++ * error code monitoring (see comment before RETERR macro): ++ * reiser4_return_err(), reiser4_report_err(). ++ * ++ * stack back-tracing: fill_backtrace() ++ * ++ * miscellaneous: reiser4_preempt_point(), call_on_each_assert(), ++ * reiser4_debugtrap(). ++ * ++ */ ++ ++#include "reiser4.h" ++#include "context.h" ++#include "super.h" ++#include "txnmgr.h" ++#include "znode.h" ++ ++#include <linux/sysfs.h> ++#include <linux/slab.h> ++#include <linux/types.h> ++#include <linux/fs.h> ++#include <linux/spinlock.h> ++#include <linux/kallsyms.h> ++#include <linux/vmalloc.h> ++#include <linux/ctype.h> ++#include <linux/sysctl.h> ++#include <linux/hardirq.h> ++ ++#if 0 ++#if REISER4_DEBUG ++static void reiser4_report_err(void); ++#else ++#define reiser4_report_err() noop ++#endif ++#endif /* 0 */ ++ ++/* ++ * global buffer where message given to reiser4_panic is formatted. ++ */ ++static char panic_buf[REISER4_PANIC_MSG_BUFFER_SIZE]; ++ ++/* ++ * lock protecting consistency of panic_buf under concurrent panics ++ */ ++static DEFINE_SPINLOCK(panic_guard); ++ ++/* Your best friend. Call it on each occasion. This is called by ++ fs/reiser4/debug.h:reiser4_panic(). */ ++void reiser4_do_panic(const char *format/* format string */ , ... /* rest */) ++{ ++ static int in_panic = 0; ++ va_list args; ++ ++ /* ++ * check for recursive panic. ++ */ ++ if (in_panic == 0) { ++ in_panic = 1; ++ ++ spin_lock(&panic_guard); ++ va_start(args, format); ++ vsnprintf(panic_buf, sizeof(panic_buf), format, args); ++ va_end(args); ++ printk(KERN_EMERG "reiser4 panicked cowardly: %s", panic_buf); ++ spin_unlock(&panic_guard); ++ ++ /* ++ * if kernel debugger is configured---drop in. Early dropping ++ * into kgdb is not always convenient, because panic message ++ * is not yet printed most of the times. But: ++ * ++ * (1) message can be extracted from printk_buf[] ++ * (declared static inside of printk()), and ++ * ++ * (2) sometimes serial/kgdb combo dies while printing ++ * long panic message, so it's more prudent to break into ++ * debugger earlier. ++ * ++ */ ++ DEBUGON(1); ++ } ++ /* to make gcc happy about noreturn attribute */ ++ panic("%s", panic_buf); ++} ++ ++#if 0 ++void ++reiser4_print_prefix(const char *level, int reperr, const char *mid, ++ const char *function, const char *file, int lineno) ++{ ++ const char *comm; ++ int pid; ++ ++ if (unlikely(in_interrupt() || in_irq())) { ++ comm = "interrupt"; ++ pid = 0; ++ } else { ++ comm = current->comm; ++ pid = current->pid; ++ } ++ printk("%sreiser4[%.16s(%i)]: %s (%s:%i)[%s]:\n", ++ level, comm, pid, function, file, lineno, mid); ++ if (reperr) ++ reiser4_report_err(); ++} ++#endif /* 0 */ ++ ++/* Preemption point: this should be called periodically during long running ++ operations (carry, allocate, and squeeze are best examples) */ ++int reiser4_preempt_point(void) ++{ ++ assert("nikita-3008", reiser4_schedulable()); ++ cond_resched(); ++ return signal_pending(current); ++} ++ ++#if REISER4_DEBUG ++/* Debugging aid: return struct where information about locks taken by current ++ thread is accumulated. This can be used to formulate lock ordering ++ constraints and various assertions. ++ ++*/ ++reiser4_lock_cnt_info *reiser4_lock_counters(void) ++{ ++ reiser4_context *ctx = get_current_context(); ++ assert("jmacd-1123", ctx != NULL); ++ return &ctx->locks; ++} ++ ++/* ++ * print human readable information about locks held by the reiser4 context. ++ */ ++static void print_lock_counters(const char *prefix, ++ const reiser4_lock_cnt_info * info) ++{ ++ printk("%s: jnode: %i, tree: %i (r:%i,w:%i), dk: %i (r:%i,w:%i)\n" ++ "jload: %i, " ++ "txnh: %i, atom: %i, stack: %i, txnmgr: %i, " ++ "ktxnmgrd: %i, fq: %i\n" ++ "inode: %i, " ++ "cbk_cache: %i (r:%i,w%i), " ++ "eflush: %i, " ++ "zlock: %i,\n" ++ "spin: %i, long: %i inode_sem: (r:%i,w:%i)\n" ++ "d: %i, x: %i, t: %i\n", prefix, ++ info->spin_locked_jnode, ++ info->rw_locked_tree, info->read_locked_tree, ++ info->write_locked_tree, ++ info->rw_locked_dk, info->read_locked_dk, info->write_locked_dk, ++ info->spin_locked_jload, ++ info->spin_locked_txnh, ++ info->spin_locked_atom, info->spin_locked_stack, ++ info->spin_locked_txnmgr, info->spin_locked_ktxnmgrd, ++ info->spin_locked_fq, ++ info->spin_locked_inode, ++ info->rw_locked_cbk_cache, ++ info->read_locked_cbk_cache, ++ info->write_locked_cbk_cache, ++ info->spin_locked_super_eflush, ++ info->spin_locked_zlock, ++ info->spin_locked, ++ info->long_term_locked_znode, ++ info->inode_sem_r, info->inode_sem_w, ++ info->d_refs, info->x_refs, info->t_refs); ++} ++ ++/* check that no spinlocks are held */ ++int reiser4_schedulable(void) ++{ ++ if (get_current_context_check() != NULL) { ++ if (!LOCK_CNT_NIL(spin_locked)) { ++ print_lock_counters("in atomic", reiser4_lock_counters()); ++ return 0; ++ } ++ } ++ might_sleep(); ++ return 1; ++} ++/* ++ * return true, iff no locks are held. ++ */ ++int reiser4_no_counters_are_held(void) ++{ ++ reiser4_lock_cnt_info *counters; ++ ++ counters = reiser4_lock_counters(); ++ return ++ (counters->spin_locked_zlock == 0) && ++ (counters->spin_locked_jnode == 0) && ++ (counters->rw_locked_tree == 0) && ++ (counters->read_locked_tree == 0) && ++ (counters->write_locked_tree == 0) && ++ (counters->rw_locked_dk == 0) && ++ (counters->read_locked_dk == 0) && ++ (counters->write_locked_dk == 0) && ++ (counters->spin_locked_txnh == 0) && ++ (counters->spin_locked_atom == 0) && ++ (counters->spin_locked_stack == 0) && ++ (counters->spin_locked_txnmgr == 0) && ++ (counters->spin_locked_inode == 0) && ++ (counters->spin_locked == 0) && ++ (counters->long_term_locked_znode == 0) && ++ (counters->inode_sem_r == 0) && ++ (counters->inode_sem_w == 0) && (counters->d_refs == 0); ++} ++ ++/* ++ * return true, iff transaction commit can be done under locks held by the ++ * current thread. ++ */ ++int reiser4_commit_check_locks(void) ++{ ++ reiser4_lock_cnt_info *counters; ++ int inode_sem_r; ++ int inode_sem_w; ++ int result; ++ ++ /* ++ * inode's read/write semaphore is the only reiser4 lock that can be ++ * held during commit. ++ */ ++ ++ counters = reiser4_lock_counters(); ++ inode_sem_r = counters->inode_sem_r; ++ inode_sem_w = counters->inode_sem_w; ++ ++ counters->inode_sem_r = counters->inode_sem_w = 0; ++ result = reiser4_no_counters_are_held(); ++ counters->inode_sem_r = inode_sem_r; ++ counters->inode_sem_w = inode_sem_w; ++ return result; ++} ++ ++/* ++ * fill "error site" in the current reiser4 context. See comment before RETERR ++ * macro for more details. ++ */ ++void reiser4_return_err(int code, const char *file, int line) ++{ ++ if (code < 0 && is_in_reiser4_context()) { ++ reiser4_context *ctx = get_current_context(); ++ ++ if (ctx != NULL) { ++ ctx->err.code = code; ++ ctx->err.file = file; ++ ctx->err.line = line; ++ } ++ } ++} ++ ++#if 0 ++/* ++ * report error information recorder by reiser4_return_err(). ++ */ ++static void reiser4_report_err(void) ++{ ++ reiser4_context *ctx = get_current_context_check(); ++ ++ if (ctx != NULL) { ++ if (ctx->err.code != 0) { ++ printk("code: %i at %s:%i\n", ++ ctx->err.code, ctx->err.file, ctx->err.line); ++ } ++ } ++} ++#endif /* 0 */ ++ ++#endif /* REISER4_DEBUG */ ++ ++#if KERNEL_DEBUGGER ++ ++/* ++ * this functions just drops into kernel debugger. It is a convenient place to ++ * put breakpoint in. ++ */ ++void reiser4_debugtrap(void) ++{ ++ /* do nothing. Put break point here. */ ++#if defined(CONFIG_KGDB) && !defined(CONFIG_REISER4_FS_MODULE) ++ extern void kgdb_breakpoint(void); ++ kgdb_breakpoint(); ++#endif ++} ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/debug.h linux-2.6.30/fs/reiser4/debug.h +--- linux-2.6.30.orig/fs/reiser4/debug.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/debug.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,351 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* Declarations of debug macros. */ ++ ++#if !defined(__FS_REISER4_DEBUG_H__) ++#define __FS_REISER4_DEBUG_H__ ++ ++#include "forward.h" ++#include "reiser4.h" ++ ++/* generic function to produce formatted output, decorating it with ++ whatever standard prefixes/postfixes we want. "Fun" is a function ++ that will be actually called, can be printk, panic etc. ++ This is for use by other debugging macros, not by users. */ ++#define DCALL(lev, fun, reperr, label, format, ...) \ ++({ \ ++ fun(lev "reiser4[%.16s(%i)]: %s (%s:%i)[%s]:\n" format "\n" , \ ++ current->comm, current->pid, __FUNCTION__, \ ++ __FILE__, __LINE__, label, ## __VA_ARGS__); \ ++}) ++ ++/* ++ * cause kernel to crash ++ */ ++#define reiser4_panic(mid, format, ...) \ ++ DCALL("", reiser4_do_panic, 1, mid, format , ## __VA_ARGS__) ++ ++/* print message with indication of current process, file, line and ++ function */ ++#define reiser4_log(label, format, ...) \ ++ DCALL(KERN_DEBUG, printk, 0, label, format , ## __VA_ARGS__) ++ ++/* Assertion checked during compilation. ++ If "cond" is false (0) we get duplicate case label in switch. ++ Use this to check something like famous ++ cassert (sizeof(struct reiserfs_journal_commit) == 4096) ; ++ in 3.x journal.c. If cassertion fails you get compiler error, ++ so no "maintainer-id". ++*/ ++#define cassert(cond) ({ switch (-1) { case (cond): case 0: break; } }) ++ ++#define noop do {; } while (0) ++ ++#if REISER4_DEBUG ++/* version of info that only actually prints anything when _d_ebugging ++ is on */ ++#define dinfo(format, ...) printk(format , ## __VA_ARGS__) ++/* macro to catch logical errors. Put it into `default' clause of ++ switch() statement. */ ++#define impossible(label, format, ...) \ ++ reiser4_panic(label, "impossible: " format , ## __VA_ARGS__) ++/* assert assures that @cond is true. If it is not, reiser4_panic() is ++ called. Use this for checking logical consistency and _never_ call ++ this to check correctness of external data: disk blocks and user-input . */ ++#define assert(label, cond) \ ++({ \ ++ /* call_on_each_assert(); */ \ ++ if (cond) { \ ++ /* put negated check to avoid using !(cond) that would lose \ ++ * warnings for things like assert(a = b); */ \ ++ ; \ ++ } else { \ ++ DEBUGON(1); \ ++ reiser4_panic(label, "assertion failed: %s", #cond); \ ++ } \ ++}) ++ ++/* like assertion, but @expr is evaluated even if REISER4_DEBUG is off. */ ++#define check_me(label, expr) assert(label, (expr)) ++ ++#define ON_DEBUG(exp) exp ++ ++extern int reiser4_schedulable(void); ++extern void call_on_each_assert(void); ++ ++#else ++ ++#define dinfo(format, args...) noop ++#define impossible(label, format, args...) noop ++#define assert(label, cond) noop ++#define check_me(label, expr) ((void) (expr)) ++#define ON_DEBUG(exp) ++#define reiser4_schedulable() might_sleep() ++ ++/* REISER4_DEBUG */ ++#endif ++ ++#if REISER4_DEBUG ++/* per-thread information about lock acquired by this thread. Used by lock ++ * ordering checking in spin_macros.h */ ++typedef struct reiser4_lock_cnt_info { ++ int rw_locked_tree; ++ int read_locked_tree; ++ int write_locked_tree; ++ ++ int rw_locked_dk; ++ int read_locked_dk; ++ int write_locked_dk; ++ ++ int rw_locked_cbk_cache; ++ int read_locked_cbk_cache; ++ int write_locked_cbk_cache; ++ ++ int spin_locked_zlock; ++ int spin_locked_jnode; ++ int spin_locked_jload; ++ int spin_locked_txnh; ++ int spin_locked_atom; ++ int spin_locked_stack; ++ int spin_locked_txnmgr; ++ int spin_locked_ktxnmgrd; ++ int spin_locked_fq; ++ int spin_locked_inode; ++ int spin_locked_super_eflush; ++ int spin_locked; ++ int long_term_locked_znode; ++ ++ int inode_sem_r; ++ int inode_sem_w; ++ ++ int d_refs; ++ int x_refs; ++ int t_refs; ++} reiser4_lock_cnt_info; ++ ++extern struct reiser4_lock_cnt_info *reiser4_lock_counters(void); ++#define IN_CONTEXT(a, b) (is_in_reiser4_context() ? (a) : (b)) ++ ++/* increment lock-counter @counter, if present */ ++#define LOCK_CNT_INC(counter) \ ++ IN_CONTEXT(++(reiser4_lock_counters()->counter), 0) ++ ++/* decrement lock-counter @counter, if present */ ++#define LOCK_CNT_DEC(counter) \ ++ IN_CONTEXT(--(reiser4_lock_counters()->counter), 0) ++ ++/* check that lock-counter is zero. This is for use in assertions */ ++#define LOCK_CNT_NIL(counter) \ ++ IN_CONTEXT(reiser4_lock_counters()->counter == 0, 1) ++ ++/* check that lock-counter is greater than zero. This is for use in ++ * assertions */ ++#define LOCK_CNT_GTZ(counter) \ ++ IN_CONTEXT(reiser4_lock_counters()->counter > 0, 1) ++#define LOCK_CNT_LT(counter,n) \ ++ IN_CONTEXT(reiser4_lock_counters()->counter < n, 1) ++ ++#else /* REISER4_DEBUG */ ++ ++/* no-op versions on the above */ ++ ++typedef struct reiser4_lock_cnt_info { ++} reiser4_lock_cnt_info; ++ ++#define reiser4_lock_counters() ((reiser4_lock_cnt_info *)NULL) ++#define LOCK_CNT_INC(counter) noop ++#define LOCK_CNT_DEC(counter) noop ++#define LOCK_CNT_NIL(counter) (1) ++#define LOCK_CNT_GTZ(counter) (1) ++#define LOCK_CNT_LT(counter, n) (1) ++ ++#endif /* REISER4_DEBUG */ ++ ++#define assert_spin_not_locked(lock) BUG_ON(0) ++#define assert_rw_write_locked(lock) BUG_ON(0) ++#define assert_rw_read_locked(lock) BUG_ON(0) ++#define assert_rw_locked(lock) BUG_ON(0) ++#define assert_rw_not_write_locked(lock) BUG_ON(0) ++#define assert_rw_not_read_locked(lock) BUG_ON(0) ++#define assert_rw_not_locked(lock) BUG_ON(0) ++ ++/* flags controlling debugging behavior. Are set through debug_flags=N mount ++ option. */ ++typedef enum { ++ /* print a lot of information during panic. When this is on all jnodes ++ * are listed. This can be *very* large output. Usually you don't want ++ * this. Especially over serial line. */ ++ REISER4_VERBOSE_PANIC = 0x00000001, ++ /* print a lot of information during umount */ ++ REISER4_VERBOSE_UMOUNT = 0x00000002, ++ /* print gathered statistics on umount */ ++ REISER4_STATS_ON_UMOUNT = 0x00000004, ++ /* check node consistency */ ++ REISER4_CHECK_NODE = 0x00000008 ++} reiser4_debug_flags; ++ ++extern int is_in_reiser4_context(void); ++ ++/* ++ * evaluate expression @e only if with reiser4 context ++ */ ++#define ON_CONTEXT(e) do { \ ++ if (is_in_reiser4_context()) { \ ++ e; \ ++ } } while (0) ++ ++/* ++ * evaluate expression @e only when within reiser4_context and debugging is ++ * on. ++ */ ++#define ON_DEBUG_CONTEXT(e) ON_DEBUG(ON_CONTEXT(e)) ++ ++/* ++ * complain about unexpected function result and crash. Used in "default" ++ * branches of switch statements and alike to assert that invalid results are ++ * not silently ignored. ++ */ ++#define wrong_return_value(label, function) \ ++ impossible(label, "wrong return value from " function) ++ ++/* Issue different types of reiser4 messages to the console */ ++#define warning(label, format, ...) \ ++ DCALL(KERN_WARNING, \ ++ printk, 1, label, "WARNING: " format , ## __VA_ARGS__) ++#define notice(label, format, ...) \ ++ DCALL(KERN_NOTICE, \ ++ printk, 1, label, "NOTICE: " format , ## __VA_ARGS__) ++ ++/* mark not yet implemented functionality */ ++#define not_yet(label, format, ...) \ ++ reiser4_panic(label, "NOT YET IMPLEMENTED: " format , ## __VA_ARGS__) ++ ++extern void reiser4_do_panic(const char *format, ...) ++ __attribute__ ((noreturn, format(printf, 1, 2))); ++ ++extern int reiser4_preempt_point(void); ++extern void reiser4_print_stats(void); ++ ++#if REISER4_DEBUG ++extern int reiser4_no_counters_are_held(void); ++extern int reiser4_commit_check_locks(void); ++#else ++#define reiser4_no_counters_are_held() (1) ++#define reiser4_commit_check_locks() (1) ++#endif ++ ++/* true if @i is power-of-two. Useful for rate-limited warnings, etc. */ ++#define IS_POW(i) \ ++({ \ ++ typeof(i) __i; \ ++ \ ++ __i = (i); \ ++ !(__i & (__i - 1)); \ ++}) ++ ++#define KERNEL_DEBUGGER (1) ++ ++#if KERNEL_DEBUGGER ++ ++extern void reiser4_debugtrap(void); ++ ++/* ++ * Check condition @cond and drop into kernel debugger (kgdb) if it's true. If ++ * kgdb is not compiled in, do nothing. ++ */ ++#define DEBUGON(cond) \ ++({ \ ++ if (unlikely(cond)) \ ++ reiser4_debugtrap(); \ ++}) ++#else ++#define DEBUGON(cond) noop ++#endif ++ ++/* ++ * Error code tracing facility. (Idea is borrowed from XFS code.) ++ * ++ * Suppose some strange and/or unexpected code is returned from some function ++ * (for example, write(2) returns -EEXIST). It is possible to place a ++ * breakpoint in the reiser4_write(), but it is too late here. How to find out ++ * in what particular place -EEXIST was generated first? ++ * ++ * In reiser4 all places where actual error codes are produced (that is, ++ * statements of the form ++ * ++ * return -EFOO; // (1), or ++ * ++ * result = -EFOO; // (2) ++ * ++ * are replaced with ++ * ++ * return RETERR(-EFOO); // (1a), and ++ * ++ * result = RETERR(-EFOO); // (2a) respectively ++ * ++ * RETERR() macro fills a backtrace in reiser4_context. This back-trace is ++ * printed in error and warning messages. Moreover, it's possible to put a ++ * conditional breakpoint in reiser4_return_err (low-level function called ++ * by RETERR() to do the actual work) to break into debugger immediately ++ * when particular error happens. ++ * ++ */ ++ ++#if REISER4_DEBUG ++ ++/* ++ * data-type to store information about where error happened ("error site"). ++ */ ++typedef struct err_site { ++ int code; /* error code */ ++ const char *file; /* source file, filled by __FILE__ */ ++ int line; /* source file line, filled by __LINE__ */ ++} err_site; ++ ++extern void reiser4_return_err(int code, const char *file, int line); ++ ++/* ++ * fill &get_current_context()->err_site with error information. ++ */ ++#define RETERR(code) \ ++({ \ ++ typeof(code) __code; \ ++ \ ++ __code = (code); \ ++ reiser4_return_err(__code, __FILE__, __LINE__); \ ++ __code; \ ++}) ++ ++#else ++ ++/* ++ * no-op versions of the above ++ */ ++ ++typedef struct err_site { ++} err_site; ++#define RETERR(code) code ++#endif ++ ++#if REISER4_LARGE_KEY ++/* ++ * conditionally compile arguments only if REISER4_LARGE_KEY is on. ++ */ ++#define ON_LARGE_KEY(...) __VA_ARGS__ ++#else ++#define ON_LARGE_KEY(...) ++#endif ++ ++/* __FS_REISER4_DEBUG_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/dformat.h linux-2.6.30/fs/reiser4/dformat.h +--- linux-2.6.30.orig/fs/reiser4/dformat.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/dformat.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,71 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* Formats of on-disk data and conversion functions. */ ++ ++/* put all item formats in the files describing the particular items, ++ our model is, everything you need to do to add an item to reiser4, ++ (excepting the changes to the plugin that uses the item which go ++ into the file defining that plugin), you put into one file. */ ++/* Data on disk are stored in little-endian format. ++ To declare fields of on-disk structures, use d8, d16, d32 and d64. ++ d??tocpu() and cputod??() to convert. */ ++ ++#if !defined(__FS_REISER4_DFORMAT_H__) ++#define __FS_REISER4_DFORMAT_H__ ++ ++#include <asm/byteorder.h> ++#include <asm/unaligned.h> ++#include <linux/types.h> ++ ++typedef __u8 d8; ++typedef __le16 d16; ++typedef __le32 d32; ++typedef __le64 d64; ++ ++#define PACKED __attribute__((packed)) ++ ++/* data-type for block number */ ++typedef __u64 reiser4_block_nr; ++ ++/* data-type for block number on disk, disk format */ ++typedef __le64 reiser4_dblock_nr; ++ ++/** ++ * disk_addr_eq - compare disk addresses ++ * @b1: pointer to block number ot compare ++ * @b2: pointer to block number ot compare ++ * ++ * Returns true if if disk addresses are the same ++ */ ++static inline int disk_addr_eq(const reiser4_block_nr * b1, ++ const reiser4_block_nr * b2) ++{ ++ assert("nikita-1033", b1 != NULL); ++ assert("nikita-1266", b2 != NULL); ++ ++ return !memcmp(b1, b2, sizeof *b1); ++} ++ ++/* structure of master reiser4 super block */ ++typedef struct reiser4_master_sb { ++ char magic[16]; /* "ReIsEr4" */ ++ __le16 disk_plugin_id; /* id of disk layout plugin */ ++ __le16 blocksize; ++ char uuid[16]; /* unique id */ ++ char label[16]; /* filesystem label */ ++ __le64 diskmap; /* location of the diskmap. 0 if not present */ ++} reiser4_master_sb; ++ ++/* __FS_REISER4_DFORMAT_H__ */ ++#endif ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/dscale.c linux-2.6.30/fs/reiser4/dscale.c +--- linux-2.6.30.orig/fs/reiser4/dscale.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/dscale.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,192 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Scalable on-disk integers */ ++ ++/* ++ * Various on-disk structures contain integer-like structures. Stat-data ++ * contain [yes, "data" is plural, check the dictionary] file size, link ++ * count; extent unit contains extent width etc. To accommodate for general ++ * case enough space is reserved to keep largest possible value. 64 bits in ++ * all cases above. But in overwhelming majority of cases numbers actually ++ * stored in these fields will be comparatively small and reserving 8 bytes is ++ * a waste of precious disk bandwidth. ++ * ++ * Scalable integers are one way to solve this problem. dscale_write() ++ * function stores __u64 value in the given area consuming from 1 to 9 bytes, ++ * depending on the magnitude of the value supplied. dscale_read() reads value ++ * previously stored by dscale_write(). ++ * ++ * dscale_write() produces format not completely unlike of UTF: two highest ++ * bits of the first byte are used to store "tag". One of 4 possible tag ++ * values is chosen depending on the number being encoded: ++ * ++ * 0 ... 0x3f => 0 [table 1] ++ * 0x40 ... 0x3fff => 1 ++ * 0x4000 ... 0x3fffffff => 2 ++ * 0x40000000 ... 0xffffffffffffffff => 3 ++ * ++ * (see dscale_range() function) ++ * ++ * Values in the range 0x40000000 ... 0xffffffffffffffff require 8 full bytes ++ * to be stored, so in this case there is no place in the first byte to store ++ * tag. For such values tag is stored in an extra 9th byte. ++ * ++ * As _highest_ bits are used for the test (which is natural) scaled integers ++ * are stored in BIG-ENDIAN format in contrast with the rest of reiser4 which ++ * uses LITTLE-ENDIAN. ++ * ++ */ ++ ++#include "debug.h" ++#include "dscale.h" ++ ++/* return tag of scaled integer stored at @address */ ++static int gettag(const unsigned char *address) ++{ ++ /* tag is stored in two highest bits */ ++ return (*address) >> 6; ++} ++ ++/* clear tag from value. Clear tag embedded into @value. */ ++static void cleartag(__u64 *value, int tag) ++{ ++ /* ++ * W-w-what ?! ++ * ++ * Actually, this is rather simple: @value passed here was read by ++ * dscale_read(), converted from BIG-ENDIAN, and padded to __u64 by ++ * zeroes. Tag is still stored in the highest (arithmetically) ++ * non-zero bits of @value, but relative position of tag within __u64 ++ * depends on @tag. ++ * ++ * For example if @tag is 0, it's stored 2 highest bits of lowest ++ * byte, and its offset (counting from lowest bit) is 8 - 2 == 6 bits. ++ * ++ * If tag is 1, it's stored in two highest bits of 2nd lowest byte, ++ * and it's offset if (2 * 8) - 2 == 14 bits. ++ * ++ * See table 1 above for details. ++ * ++ * All these cases are captured by the formula: ++ */ ++ *value &= ~(3 << (((1 << tag) << 3) - 2)); ++ /* ++ * That is, clear two (3 == 0t11) bits at the offset ++ * ++ * 8 * (2 ^ tag) - 2, ++ * ++ * that is, two highest bits of (2 ^ tag)-th byte of @value. ++ */ ++} ++ ++/* return tag for @value. See table 1 above for details. */ ++static int dscale_range(__u64 value) ++{ ++ if (value > 0x3fffffff) ++ return 3; ++ if (value > 0x3fff) ++ return 2; ++ if (value > 0x3f) ++ return 1; ++ return 0; ++} ++ ++/* restore value stored at @adderss by dscale_write() and return number of ++ * bytes consumed */ ++int dscale_read(unsigned char *address, __u64 *value) ++{ ++ int tag; ++ ++ /* read tag */ ++ tag = gettag(address); ++ switch (tag) { ++ case 3: ++ /* In this case tag is stored in an extra byte, skip this byte ++ * and decode value stored in the next 8 bytes.*/ ++ *value = __be64_to_cpu(get_unaligned((__be64 *)(address + 1))); ++ /* worst case: 8 bytes for value itself plus one byte for ++ * tag. */ ++ return 9; ++ case 0: ++ *value = get_unaligned(address); ++ break; ++ case 1: ++ *value = __be16_to_cpu(get_unaligned((__be16 *)address)); ++ break; ++ case 2: ++ *value = __be32_to_cpu(get_unaligned((__be32 *)address)); ++ break; ++ default: ++ return RETERR(-EIO); ++ } ++ /* clear tag embedded into @value */ ++ cleartag(value, tag); ++ /* number of bytes consumed is (2 ^ tag)---see table 1. */ ++ return 1 << tag; ++} ++ ++/* number of bytes consumed */ ++int dscale_bytes_to_read(unsigned char *address) ++{ ++ int tag; ++ ++ tag = gettag(address); ++ switch (tag) { ++ case 0: ++ case 1: ++ case 2: ++ return 1 << tag; ++ case 3: ++ return 9; ++ default: ++ return RETERR(-EIO); ++ } ++} ++ ++/* store @value at @address and return number of bytes consumed */ ++int dscale_write(unsigned char *address, __u64 value) ++{ ++ int tag; ++ int shift; ++ __be64 v; ++ unsigned char *valarr; ++ ++ tag = dscale_range(value); ++ v = __cpu_to_be64(value); ++ valarr = (unsigned char *)&v; ++ shift = (tag == 3) ? 1 : 0; ++ memcpy(address + shift, valarr + sizeof v - (1 << tag), 1 << tag); ++ *address |= (tag << 6); ++ return shift + (1 << tag); ++} ++ ++/* number of bytes required to store @value */ ++int dscale_bytes_to_write(__u64 value) ++{ ++ int bytes; ++ ++ bytes = 1 << dscale_range(value); ++ if (bytes == 8) ++ ++bytes; ++ return bytes; ++} ++ ++/* returns true if @value and @other require the same number of bytes to be ++ * stored. Used by detect when data structure (like stat-data) has to be ++ * expanded or contracted. */ ++int dscale_fit(__u64 value, __u64 other) ++{ ++ return dscale_range(value) == dscale_range(other); ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/dscale.h linux-2.6.30/fs/reiser4/dscale.h +--- linux-2.6.30.orig/fs/reiser4/dscale.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/dscale.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,28 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Scalable on-disk integers. See dscale.h for details. */ ++ ++#if !defined(__FS_REISER4_DSCALE_H__) ++#define __FS_REISER4_DSCALE_H__ ++ ++#include "dformat.h" ++ ++extern int dscale_read(unsigned char *address, __u64 *value); ++extern int dscale_write(unsigned char *address, __u64 value); ++extern int dscale_bytes_to_read(unsigned char *address); ++extern int dscale_bytes_to_write(__u64 value); ++extern int dscale_fit(__u64 value, __u64 other); ++ ++/* __FS_REISER4_DSCALE_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/entd.c linux-2.6.30/fs/reiser4/entd.c +--- linux-2.6.30.orig/fs/reiser4/entd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/entd.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,335 @@ ++/* Copyright 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Ent daemon. */ ++ ++#include "debug.h" ++#include "txnmgr.h" ++#include "tree.h" ++#include "entd.h" ++#include "super.h" ++#include "context.h" ++#include "reiser4.h" ++#include "vfs_ops.h" ++#include "page_cache.h" ++#include "inode.h" ++ ++#include <linux/sched.h> /* struct task_struct */ ++#include <linux/suspend.h> ++#include <linux/kernel.h> ++#include <linux/writeback.h> ++#include <linux/time.h> /* INITIAL_JIFFIES */ ++#include <linux/backing-dev.h> /* bdi_write_congested */ ++#include <linux/wait.h> ++#include <linux/kthread.h> ++#include <linux/freezer.h> ++ ++#define DEF_PRIORITY 12 ++#define MAX_ENTD_ITERS 10 ++ ++static void entd_flush(struct super_block *, struct wbq *); ++static int entd(void *arg); ++ ++/* ++ * set ->comm field of end thread to make its state visible to the user level ++ */ ++#define entd_set_comm(state) \ ++ snprintf(current->comm, sizeof(current->comm), \ ++ "ent:%s%s", super->s_id, (state)) ++ ++/** ++ * reiser4_init_entd - initialize entd context and start kernel daemon ++ * @super: super block to start ent thread for ++ * ++ * Creates entd contexts, starts kernel thread and waits until it ++ * initializes. ++ */ ++int reiser4_init_entd(struct super_block *super) ++{ ++ entd_context *ctx; ++ ++ assert("nikita-3104", super != NULL); ++ ++ ctx = get_entd_context(super); ++ ++ memset(ctx, 0, sizeof *ctx); ++ spin_lock_init(&ctx->guard); ++ init_waitqueue_head(&ctx->wait); ++#if REISER4_DEBUG ++ INIT_LIST_HEAD(&ctx->flushers_list); ++#endif ++ /* lists of writepage requests */ ++ INIT_LIST_HEAD(&ctx->todo_list); ++ INIT_LIST_HEAD(&ctx->done_list); ++ /* start entd */ ++ ctx->tsk = kthread_run(entd, super, "ent:%s", super->s_id); ++ if (IS_ERR(ctx->tsk)) ++ return PTR_ERR(ctx->tsk); ++ return 0; ++} ++ ++static void put_wbq(struct wbq *rq) ++{ ++ iput(rq->mapping->host); ++ complete(&rq->completion); ++} ++ ++/* ent should be locked */ ++static struct wbq *__get_wbq(entd_context * ent) ++{ ++ struct wbq *wbq; ++ ++ if (list_empty(&ent->todo_list)) ++ return NULL; ++ ++ ent->nr_todo_reqs--; ++ wbq = list_entry(ent->todo_list.next, struct wbq, link); ++ list_del_init(&wbq->link); ++ return wbq; ++} ++ ++/* ent thread function */ ++static int entd(void *arg) ++{ ++ struct super_block *super; ++ entd_context *ent; ++ int done = 0; ++ ++ super = arg; ++ /* do_fork() just copies task_struct into the new ++ thread. ->fs_context shouldn't be copied of course. This shouldn't ++ be a problem for the rest of the code though. ++ */ ++ current->journal_info = NULL; ++ ++ ent = get_entd_context(super); ++ ++ while (!done) { ++ try_to_freeze(); ++ ++ spin_lock(&ent->guard); ++ while (ent->nr_todo_reqs != 0) { ++ struct wbq *rq; ++ ++ assert("", list_empty(&ent->done_list)); ++ ++ /* take request from the queue head */ ++ rq = __get_wbq(ent); ++ assert("", rq != NULL); ++ ent->cur_request = rq; ++ spin_unlock(&ent->guard); ++ ++ entd_set_comm("!"); ++ entd_flush(super, rq); ++ ++ put_wbq(rq); ++ ++ /* ++ * wakeup all requestors and iput their inodes ++ */ ++ spin_lock(&ent->guard); ++ while (!list_empty(&ent->done_list)) { ++ rq = list_entry(ent->done_list.next, struct wbq, link); ++ list_del_init(&rq->link); ++ ent->nr_done_reqs--; ++ spin_unlock(&ent->guard); ++ assert("", rq->written == 1); ++ put_wbq(rq); ++ spin_lock(&ent->guard); ++ } ++ } ++ spin_unlock(&ent->guard); ++ ++ entd_set_comm("."); ++ ++ { ++ DEFINE_WAIT(__wait); ++ ++ do { ++ prepare_to_wait(&ent->wait, &__wait, TASK_INTERRUPTIBLE); ++ if (kthread_should_stop()) { ++ done = 1; ++ break; ++ } ++ if (ent->nr_todo_reqs != 0) ++ break; ++ schedule(); ++ } while (0); ++ finish_wait(&ent->wait, &__wait); ++ } ++ } ++ BUG_ON(ent->nr_todo_reqs != 0); ++ return 0; ++} ++ ++/** ++ * reiser4_done_entd - stop entd kernel thread ++ * @super: super block to stop ent thread for ++ * ++ * It is called on umount. Sends stop signal to entd and wait until it handles ++ * it. ++ */ ++void reiser4_done_entd(struct super_block *super) ++{ ++ entd_context *ent; ++ ++ assert("nikita-3103", super != NULL); ++ ++ ent = get_entd_context(super); ++ assert("zam-1055", ent->tsk != NULL); ++ kthread_stop(ent->tsk); ++} ++ ++/* called at the beginning of jnode_flush to register flusher thread with ent ++ * daemon */ ++void reiser4_enter_flush(struct super_block *super) ++{ ++ entd_context *ent; ++ ++ assert("zam-1029", super != NULL); ++ ent = get_entd_context(super); ++ ++ assert("zam-1030", ent != NULL); ++ ++ spin_lock(&ent->guard); ++ ent->flushers++; ++#if REISER4_DEBUG ++ list_add(&get_current_context()->flushers_link, &ent->flushers_list); ++#endif ++ spin_unlock(&ent->guard); ++} ++ ++/* called at the end of jnode_flush */ ++void reiser4_leave_flush(struct super_block *super) ++{ ++ entd_context *ent; ++ int wake_up_ent; ++ ++ assert("zam-1027", super != NULL); ++ ent = get_entd_context(super); ++ ++ assert("zam-1028", ent != NULL); ++ ++ spin_lock(&ent->guard); ++ ent->flushers--; ++ wake_up_ent = (ent->flushers == 0 && ent->nr_todo_reqs != 0); ++#if REISER4_DEBUG ++ list_del_init(&get_current_context()->flushers_link); ++#endif ++ spin_unlock(&ent->guard); ++ if (wake_up_ent) ++ wake_up_process(ent->tsk); ++} ++ ++#define ENTD_CAPTURE_APAGE_BURST SWAP_CLUSTER_MAX ++ ++static void entd_flush(struct super_block *super, struct wbq *rq) ++{ ++ reiser4_context ctx; ++ int tmp; ++ ++ init_stack_context(&ctx, super); ++ ctx.entd = 1; ++ ctx.gfp_mask = GFP_NOFS; ++ ++ rq->wbc->range_start = page_offset(rq->page); ++ rq->wbc->range_end = rq->wbc->range_start + ++ (ENTD_CAPTURE_APAGE_BURST << PAGE_CACHE_SHIFT); ++ tmp = rq->wbc->nr_to_write; ++ rq->mapping->a_ops->writepages(rq->mapping, rq->wbc); ++ ++ if (rq->wbc->nr_to_write > 0) { ++ rq->wbc->range_start = 0; ++ rq->wbc->range_end = LLONG_MAX; ++ generic_sync_sb_inodes(super, rq->wbc); ++ } ++ rq->wbc->nr_to_write = ENTD_CAPTURE_APAGE_BURST; ++ reiser4_writeout(super, rq->wbc); ++ ++ context_set_commit_async(&ctx); ++ reiser4_exit_context(&ctx); ++} ++ ++/** ++ * write_page_by_ent - ask entd thread to flush this page as part of slum ++ * @page: page to be written ++ * @wbc: writeback control passed to reiser4_writepage ++ * ++ * Creates a request, puts it on entd list of requests, wakeups entd if ++ * necessary, waits until entd completes with the request. ++ */ ++int write_page_by_ent(struct page *page, struct writeback_control *wbc) ++{ ++ struct super_block *sb; ++ struct inode *inode; ++ entd_context *ent; ++ struct wbq rq; ++ ++ assert("", PageLocked(page)); ++ assert("", page->mapping != NULL); ++ ++ sb = page->mapping->host->i_sb; ++ ent = get_entd_context(sb); ++ assert("", ent && ent->done == 0); ++ ++ /* ++ * we are going to unlock page and ask ent thread to write the ++ * page. Re-dirty page before unlocking so that if ent thread fails to ++ * write it - it will remain dirty ++ */ ++ set_page_dirty_notag(page); ++ ++ /* ++ * pin inode in memory, unlock page, entd_flush will iput. We can not ++ * iput here becasue we can not allow delete_inode to be called here ++ */ ++ inode = igrab(page->mapping->host); ++ unlock_page(page); ++ if (inode == NULL) ++ /* inode is getting freed */ ++ return 0; ++ ++ /* init wbq */ ++ INIT_LIST_HEAD(&rq.link); ++ rq.magic = WBQ_MAGIC; ++ rq.wbc = wbc; ++ rq.page = page; ++ rq.mapping = inode->i_mapping; ++ rq.node = NULL; ++ rq.written = 0; ++ init_completion(&rq.completion); ++ ++ /* add request to entd's list of writepage requests */ ++ spin_lock(&ent->guard); ++ ent->nr_todo_reqs++; ++ list_add_tail(&rq.link, &ent->todo_list); ++ if (ent->nr_todo_reqs == 1) ++ wake_up_process(ent->tsk); ++ ++ spin_unlock(&ent->guard); ++ ++ /* wait until entd finishes */ ++ wait_for_completion(&rq.completion); ++ ++ if (rq.written) ++ /* Eventually ENTD has written the page to disk. */ ++ return 0; ++ return 0; ++} ++ ++int wbq_available(void) ++{ ++ struct super_block *sb = reiser4_get_current_sb(); ++ entd_context *ent = get_entd_context(sb); ++ return ent->nr_todo_reqs; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/entd.h linux-2.6.30/fs/reiser4/entd.h +--- linux-2.6.30.orig/fs/reiser4/entd.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/entd.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,90 @@ ++/* Copyright 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Ent daemon. */ ++ ++#ifndef __ENTD_H__ ++#define __ENTD_H__ ++ ++#include "context.h" ++ ++#include <linux/fs.h> ++#include <linux/completion.h> ++#include <linux/wait.h> ++#include <linux/spinlock.h> ++#include <linux/sched.h> /* for struct task_struct */ ++ ++#define WBQ_MAGIC 0x7876dc76 ++ ++/* write-back request. */ ++struct wbq { ++ int magic; ++ struct list_head link; /* list head of this list is in entd context */ ++ struct writeback_control *wbc; ++ struct page *page; ++ struct address_space *mapping; ++ struct completion completion; ++ jnode *node; /* set if ent thread captured requested page */ ++ int written; /* set if ent thread wrote requested page */ ++}; ++ ++/* ent-thread context. This is used to synchronize starting/stopping ent ++ * threads. */ ++typedef struct entd_context { ++ /* wait queue that ent thread waits on for more work. It's ++ * signaled by write_page_by_ent(). */ ++ wait_queue_head_t wait; ++ /* spinlock protecting other fields */ ++ spinlock_t guard; ++ /* ent thread */ ++ struct task_struct *tsk; ++ /* set to indicate that ent thread should leave. */ ++ int done; ++ /* counter of active flushers */ ++ int flushers; ++ /* ++ * when reiser4_writepage asks entd to write a page - it adds struct ++ * wbq to this list ++ */ ++ struct list_head todo_list; ++ /* number of elements on the above list */ ++ int nr_todo_reqs; ++ ++ struct wbq *cur_request; ++ /* ++ * when entd writes a page it moves write-back request from todo_list ++ * to done_list. This list is used at the end of entd iteration to ++ * wakeup requestors and iput inodes. ++ */ ++ struct list_head done_list; ++ /* number of elements on the above list */ ++ int nr_done_reqs; ++ ++#if REISER4_DEBUG ++ /* list of all active flushers */ ++ struct list_head flushers_list; ++#endif ++} entd_context; ++ ++extern int reiser4_init_entd(struct super_block *); ++extern void reiser4_done_entd(struct super_block *); ++ ++extern void reiser4_enter_flush(struct super_block *); ++extern void reiser4_leave_flush(struct super_block *); ++ ++extern int write_page_by_ent(struct page *, struct writeback_control *); ++extern int wbq_available(void); ++extern void ent_writes_page(struct super_block *, struct page *); ++ ++extern jnode *get_jnode_by_wbq(struct super_block *, struct wbq *); ++/* __ENTD_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/eottl.c linux-2.6.30/fs/reiser4/eottl.c +--- linux-2.6.30.orig/fs/reiser4/eottl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/eottl.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,510 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "key.h" ++#include "coord.h" ++#include "plugin/item/item.h" ++#include "plugin/node/node.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree_walk.h" ++#include "tree_mod.h" ++#include "carry.h" ++#include "tree.h" ++#include "super.h" ++ ++#include <linux/types.h> /* for __u?? */ ++ ++/* ++ * Extents on the twig level (EOTTL) handling. ++ * ++ * EOTTL poses some problems to the tree traversal, that are better explained ++ * by example. ++ * ++ * Suppose we have block B1 on the twig level with the following items: ++ * ++ * 0. internal item I0 with key (0:0:0:0) (locality, key-type, object-id, ++ * offset) ++ * 1. extent item E1 with key (1:4:100:0), having 10 blocks of 4k each ++ * 2. internal item I2 with key (10:0:0:0) ++ * ++ * We are trying to insert item with key (5:0:0:0). Lookup finds node B1, and ++ * then intra-node lookup is done. This lookup finished on the E1, because the ++ * key we are looking for is larger than the key of E1 and is smaller than key ++ * the of I2. ++ * ++ * Here search is stuck. ++ * ++ * After some thought it is clear what is wrong here: extents on the twig level ++ * break some basic property of the *search* tree (on the pretext, that they ++ * restore property of balanced tree). ++ * ++ * Said property is the following: if in the internal node of the search tree ++ * we have [ ... Key1 Pointer Key2 ... ] then, all data that are or will be ++ * keyed in the tree with the Key such that Key1 <= Key < Key2 are accessible ++ * through the Pointer. ++ * ++ * This is not true, when Pointer is Extent-Pointer, simply because extent ++ * cannot expand indefinitely to the right to include any item with ++ * ++ * Key1 <= Key <= Key2. ++ * ++ * For example, our E1 extent is only responsible for the data with keys ++ * ++ * (1:4:100:0) <= key <= (1:4:100:0xffffffffffffffff), and ++ * ++ * so, key range ++ * ++ * ( (1:4:100:0xffffffffffffffff), (10:0:0:0) ) ++ * ++ * is orphaned: there is no way to get there from the tree root. ++ * ++ * In other words, extent pointers are different than normal child pointers as ++ * far as search tree is concerned, and this creates such problems. ++ * ++ * Possible solution for this problem is to insert our item into node pointed ++ * to by I2. There are some problems through: ++ * ++ * (1) I2 can be in a different node. ++ * (2) E1 can be immediately followed by another extent E2. ++ * ++ * (1) is solved by calling reiser4_get_right_neighbor() and accounting ++ * for locks/coords as necessary. ++ * ++ * (2) is more complex. Solution here is to insert new empty leaf node and ++ * insert internal item between E1 and E2 pointing to said leaf node. This is ++ * further complicated by possibility that E2 is in a different node, etc. ++ * ++ * Problems: ++ * ++ * (1) if there was internal item I2 immediately on the right of an extent E1 ++ * we and we decided to insert new item S1 into node N2 pointed to by I2, then ++ * key of S1 will be less than smallest key in the N2. Normally, search key ++ * checks that key we are looking for is in the range of keys covered by the ++ * node key is being looked in. To work around of this situation, while ++ * preserving useful consistency check new flag CBK_TRUST_DK was added to the ++ * cbk falgs bitmask. This flag is automatically set on entrance to the ++ * coord_by_key() and is only cleared when we are about to enter situation ++ * described above. ++ * ++ * (2) If extent E1 is immediately followed by another extent E2 and we are ++ * searching for the key that is between E1 and E2 we only have to insert new ++ * empty leaf node when coord_by_key was called for insertion, rather than just ++ * for lookup. To distinguish these cases, new flag CBK_FOR_INSERT was added to ++ * the cbk falgs bitmask. This flag is automatically set by coord_by_key calls ++ * performed by insert_by_key() and friends. ++ * ++ * (3) Insertion of new empty leaf node (possibly) requires balancing. In any ++ * case it requires modification of node content which is only possible under ++ * write lock. It may well happen that we only have read lock on the node where ++ * new internal pointer is to be inserted (common case: lookup of non-existent ++ * stat-data that fells between two extents). If only read lock is held, tree ++ * traversal is restarted with lock_level modified so that next time we hit ++ * this problem, write lock will be held. Once we have write lock, balancing ++ * will be performed. ++ */ ++ ++/** ++ * is_next_item_internal - check whether next item is internal ++ * @coord: coordinate of extent item in twig node ++ * @key: search key ++ * @lh: twig node lock handle ++ * ++ * Looks at the unit next to @coord. If it is an internal one - 1 is returned, ++ * @coord is set to that unit. If that unit is in right neighbor, @lh is moved ++ * to that node, @coord is set to its first unit. If next item is not internal ++ * or does not exist then 0 is returned, @coord and @lh are left unchanged. 2 ++ * is returned if search restart has to be done. ++ */ ++static int ++is_next_item_internal(coord_t *coord, const reiser4_key * key, ++ lock_handle * lh) ++{ ++ coord_t next; ++ lock_handle rn; ++ int result; ++ ++ coord_dup(&next, coord); ++ if (coord_next_unit(&next) == 0) { ++ /* next unit is in this node */ ++ if (item_is_internal(&next)) { ++ coord_dup(coord, &next); ++ return 1; ++ } ++ assert("vs-3", item_is_extent(&next)); ++ return 0; ++ } ++ ++ /* ++ * next unit either does not exist or is in right neighbor. If it is in ++ * right neighbor we have to check right delimiting key because ++ * concurrent thread could get their first and insert item with a key ++ * smaller than @key ++ */ ++ read_lock_dk(current_tree); ++ result = keycmp(key, znode_get_rd_key(coord->node)); ++ read_unlock_dk(current_tree); ++ assert("vs-6", result != EQUAL_TO); ++ if (result == GREATER_THAN) ++ return 2; ++ ++ /* lock right neighbor */ ++ init_lh(&rn); ++ result = reiser4_get_right_neighbor(&rn, coord->node, ++ znode_is_wlocked(coord->node) ? ++ ZNODE_WRITE_LOCK : ZNODE_READ_LOCK, ++ GN_CAN_USE_UPPER_LEVELS); ++ if (result == -E_NO_NEIGHBOR) { ++ /* we are on the rightmost edge of the tree */ ++ done_lh(&rn); ++ return 0; ++ } ++ ++ if (result) { ++ assert("vs-4", result < 0); ++ done_lh(&rn); ++ return result; ++ } ++ ++ /* ++ * check whether concurrent thread managed to insert item with a key ++ * smaller than @key ++ */ ++ read_lock_dk(current_tree); ++ result = keycmp(key, znode_get_ld_key(rn.node)); ++ read_unlock_dk(current_tree); ++ assert("vs-6", result != EQUAL_TO); ++ if (result == GREATER_THAN) { ++ done_lh(&rn); ++ return 2; ++ } ++ ++ result = zload(rn.node); ++ if (result) { ++ assert("vs-5", result < 0); ++ done_lh(&rn); ++ return result; ++ } ++ ++ coord_init_first_unit(&next, rn.node); ++ if (item_is_internal(&next)) { ++ /* ++ * next unit is in right neighbor and it is an unit of internal ++ * item. Unlock coord->node. Move @lh to right neighbor. @coord ++ * is set to the first unit of right neighbor. ++ */ ++ coord_dup(coord, &next); ++ zrelse(rn.node); ++ done_lh(lh); ++ move_lh(lh, &rn); ++ return 1; ++ } ++ ++ /* ++ * next unit is unit of extent item. Return without chaning @lh and ++ * @coord. ++ */ ++ assert("vs-6", item_is_extent(&next)); ++ zrelse(rn.node); ++ done_lh(&rn); ++ return 0; ++} ++ ++/** ++ * rd_key - calculate key of an item next to the given one ++ * @coord: position in a node ++ * @key: storage for result key ++ * ++ * @coord is set between items or after the last item in a node. Calculate key ++ * of item to the right of @coord. ++ */ ++static reiser4_key *rd_key(const coord_t *coord, reiser4_key *key) ++{ ++ coord_t dup; ++ ++ assert("nikita-2281", coord_is_between_items(coord)); ++ coord_dup(&dup, coord); ++ ++ if (coord_set_to_right(&dup) == 0) ++ /* next item is in this node. Return its key. */ ++ unit_key_by_coord(&dup, key); ++ else { ++ /* ++ * next item either does not exist or is in right ++ * neighbor. Return znode's right delimiting key. ++ */ ++ read_lock_dk(current_tree); ++ *key = *znode_get_rd_key(coord->node); ++ read_unlock_dk(current_tree); ++ } ++ return key; ++} ++ ++/** ++ * add_empty_leaf - insert empty leaf between two extents ++ * @insert_coord: position in twig node between two extents ++ * @lh: twig node lock handle ++ * @key: left delimiting key of new node ++ * @rdkey: right delimiting key of new node ++ * ++ * Inserts empty leaf node between two extent items. It is necessary when we ++ * have to insert an item on leaf level between two extents (items on the twig ++ * level). ++ */ ++static int ++add_empty_leaf(coord_t *insert_coord, lock_handle *lh, ++ const reiser4_key *key, const reiser4_key *rdkey) ++{ ++ int result; ++ carry_pool *pool; ++ carry_level *todo; ++ reiser4_item_data *item; ++ carry_insert_data *cdata; ++ carry_op *op; ++ znode *node; ++ reiser4_tree *tree; ++ ++ assert("vs-49827", znode_contains_key_lock(insert_coord->node, key)); ++ tree = znode_get_tree(insert_coord->node); ++ node = reiser4_new_node(insert_coord->node, LEAF_LEVEL); ++ if (IS_ERR(node)) ++ return PTR_ERR(node); ++ ++ /* setup delimiting keys for node being inserted */ ++ write_lock_dk(tree); ++ znode_set_ld_key(node, key); ++ znode_set_rd_key(node, rdkey); ++ ON_DEBUG(node->creator = current); ++ ON_DEBUG(node->first_key = *key); ++ write_unlock_dk(tree); ++ ++ ZF_SET(node, JNODE_ORPHAN); ++ ++ /* ++ * allocate carry_pool, 3 carry_level-s, reiser4_item_data and ++ * carry_insert_data ++ */ ++ pool = init_carry_pool(sizeof(*pool) + 3 * sizeof(*todo) + ++ sizeof(*item) + sizeof(*cdata)); ++ if (IS_ERR(pool)) ++ return PTR_ERR(pool); ++ todo = (carry_level *) (pool + 1); ++ init_carry_level(todo, pool); ++ ++ item = (reiser4_item_data *) (todo + 3); ++ cdata = (carry_insert_data *) (item + 1); ++ ++ op = reiser4_post_carry(todo, COP_INSERT, insert_coord->node, 0); ++ if (!IS_ERR(op)) { ++ cdata->coord = insert_coord; ++ cdata->key = key; ++ cdata->data = item; ++ op->u.insert.d = cdata; ++ op->u.insert.type = COPT_ITEM_DATA; ++ build_child_ptr_data(node, item); ++ item->arg = NULL; ++ /* have @insert_coord to be set at inserted item after ++ insertion is done */ ++ todo->track_type = CARRY_TRACK_CHANGE; ++ todo->tracked = lh; ++ ++ result = reiser4_carry(todo, NULL); ++ if (result == 0) { ++ /* ++ * pin node in memory. This is necessary for ++ * znode_make_dirty() below. ++ */ ++ result = zload(node); ++ if (result == 0) { ++ lock_handle local_lh; ++ ++ /* ++ * if we inserted new child into tree we have ++ * to mark it dirty so that flush will be able ++ * to process it. ++ */ ++ init_lh(&local_lh); ++ result = longterm_lock_znode(&local_lh, node, ++ ZNODE_WRITE_LOCK, ++ ZNODE_LOCK_LOPRI); ++ if (result == 0) { ++ znode_make_dirty(node); ++ ++ /* ++ * when internal item pointing to @node ++ * was inserted into twig node ++ * create_hook_internal did not connect ++ * it properly because its right ++ * neighbor was not known. Do it ++ * here ++ */ ++ write_lock_tree(tree); ++ assert("nikita-3312", ++ znode_is_right_connected(node)); ++ assert("nikita-2984", ++ node->right == NULL); ++ ZF_CLR(node, JNODE_RIGHT_CONNECTED); ++ write_unlock_tree(tree); ++ result = ++ connect_znode(insert_coord, node); ++ ON_DEBUG(if (result == 0) check_dkeys(node);); ++ ++ done_lh(lh); ++ move_lh(lh, &local_lh); ++ assert("vs-1676", node_is_empty(node)); ++ coord_init_first_unit(insert_coord, ++ node); ++ } else { ++ warning("nikita-3136", ++ "Cannot lock child"); ++ } ++ done_lh(&local_lh); ++ zrelse(node); ++ } ++ } ++ } else ++ result = PTR_ERR(op); ++ zput(node); ++ done_carry_pool(pool); ++ return result; ++} ++ ++/** ++ * handle_eottl - handle extent-on-the-twig-level cases in tree traversal ++ * @h: search handle ++ * @outcome: flag saying whether search has to restart or is done ++ * ++ * Handles search on twig level. If this function completes search itself then ++ * it returns 1. If search has to go one level down then 0 is returned. If ++ * error happens then LOOKUP_DONE is returned via @outcome and error code is ++ * saved in @h->result. ++ */ ++int handle_eottl(cbk_handle *h, int *outcome) ++{ ++ int result; ++ reiser4_key key; ++ coord_t *coord; ++ ++ coord = h->coord; ++ ++ if (h->level != TWIG_LEVEL || ++ (coord_is_existing_item(coord) && item_is_internal(coord))) { ++ /* Continue to traverse tree downward. */ ++ return 0; ++ } ++ ++ /* ++ * make sure that @h->coord is set to twig node and that it is either ++ * set to extent item or after extent item ++ */ ++ assert("vs-356", h->level == TWIG_LEVEL); ++ assert("vs-357", ({ ++ coord_t lcoord; ++ coord_dup(&lcoord, coord); ++ check_me("vs-733", coord_set_to_left(&lcoord) == 0); ++ item_is_extent(&lcoord); ++ } ++ )); ++ ++ if (*outcome == NS_FOUND) { ++ /* we have found desired key on twig level in extent item */ ++ h->result = CBK_COORD_FOUND; ++ *outcome = LOOKUP_DONE; ++ return 1; ++ } ++ ++ if (!(h->flags & CBK_FOR_INSERT)) { ++ /* tree traversal is not for insertion. Just return ++ CBK_COORD_NOTFOUND. */ ++ h->result = CBK_COORD_NOTFOUND; ++ *outcome = LOOKUP_DONE; ++ return 1; ++ } ++ ++ /* take a look at the item to the right of h -> coord */ ++ result = is_next_item_internal(coord, h->key, h->active_lh); ++ if (unlikely(result < 0)) { ++ h->error = "get_right_neighbor failed"; ++ h->result = result; ++ *outcome = LOOKUP_DONE; ++ return 1; ++ } ++ if (result == 0) { ++ /* ++ * item to the right is also an extent one. Allocate a new node ++ * and insert pointer to it after item h -> coord. ++ * ++ * This is a result of extents being located at the twig ++ * level. For explanation, see comment just above ++ * is_next_item_internal(). ++ */ ++ znode *loaded; ++ ++ if (cbk_lock_mode(h->level, h) != ZNODE_WRITE_LOCK) { ++ /* ++ * we got node read locked, restart coord_by_key to ++ * have write lock on twig level ++ */ ++ h->lock_level = TWIG_LEVEL; ++ h->lock_mode = ZNODE_WRITE_LOCK; ++ *outcome = LOOKUP_REST; ++ return 1; ++ } ++ ++ loaded = coord->node; ++ result = ++ add_empty_leaf(coord, h->active_lh, h->key, ++ rd_key(coord, &key)); ++ if (result) { ++ h->error = "could not add empty leaf"; ++ h->result = result; ++ *outcome = LOOKUP_DONE; ++ return 1; ++ } ++ /* added empty leaf is locked (h->active_lh), its parent node ++ is unlocked, h->coord is set as EMPTY */ ++ assert("vs-13", coord->between == EMPTY_NODE); ++ assert("vs-14", znode_is_write_locked(coord->node)); ++ assert("vs-15", ++ WITH_DATA(coord->node, node_is_empty(coord->node))); ++ assert("vs-16", jnode_is_leaf(ZJNODE(coord->node))); ++ assert("vs-17", coord->node == h->active_lh->node); ++ *outcome = LOOKUP_DONE; ++ h->result = CBK_COORD_NOTFOUND; ++ return 1; ++ } else if (result == 1) { ++ /* ++ * this is special case mentioned in the comment on ++ * tree.h:cbk_flags. We have found internal item immediately on ++ * the right of extent, and we are going to insert new item ++ * there. Key of item we are going to insert is smaller than ++ * leftmost key in the node pointed to by said internal item ++ * (otherwise search wouldn't come to the extent in the first ++ * place). ++ * ++ * This is a result of extents being located at the twig ++ * level. For explanation, see comment just above ++ * is_next_item_internal(). ++ */ ++ h->flags &= ~CBK_TRUST_DK; ++ } else { ++ assert("vs-8", result == 2); ++ *outcome = LOOKUP_REST; ++ return 1; ++ } ++ assert("vs-362", WITH_DATA(coord->node, item_is_internal(coord))); ++ return 0; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 120 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/estimate.c linux-2.6.30/fs/reiser4/estimate.c +--- linux-2.6.30.orig/fs/reiser4/estimate.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/estimate.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,129 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++#include "debug.h" ++#include "dformat.h" ++#include "tree.h" ++#include "carry.h" ++#include "inode.h" ++#include "plugin/cluster.h" ++#include "plugin/item/ctail.h" ++ ++/* This returns how many nodes might get dirty and added nodes if @children ++ nodes are dirtied ++ ++ Amount of internals which will get dirty or get allocated we estimate as 5% ++ of the childs + 1 balancing. 1 balancing is 2 neighbours, 2 new blocks and ++ the current block on the leaf level, 2 neighbour nodes + the current (or 1 ++ neighbour and 1 new and the current) on twig level, 2 neighbour nodes on ++ upper levels and 1 for a new root. So 5 for leaf level, 3 for twig level, ++ 2 on upper + 1 for root. ++ ++ Do not calculate the current node of the lowest level here - this is overhead ++ only. ++ ++ children is almost always 1 here. Exception is flow insertion ++*/ ++static reiser4_block_nr ++max_balance_overhead(reiser4_block_nr childen, tree_level tree_height) ++{ ++ reiser4_block_nr ten_percent; ++ ++ ten_percent = ((103 * childen) >> 10); ++ ++ /* If we have too many balancings at the time, tree height can raise on ++ more then 1. Assume that if tree_height is 5, it can raise on 1 only. ++ */ ++ return ((tree_height < 5 ? 5 : tree_height) * 2 + (4 + ten_percent)); ++} ++ ++/* this returns maximal possible number of nodes which can be modified plus ++ number of new nodes which can be required to perform insertion of one item ++ into the tree */ ++/* it is only called when tree height changes, or gets initialized */ ++reiser4_block_nr calc_estimate_one_insert(tree_level height) ++{ ++ return 1 + max_balance_overhead(1, height); ++} ++ ++reiser4_block_nr estimate_one_insert_item(reiser4_tree * tree) ++{ ++ return tree->estimate_one_insert; ++} ++ ++/* this returns maximal possible number of nodes which can be modified plus ++ number of new nodes which can be required to perform insertion of one unit ++ into an item in the tree */ ++reiser4_block_nr estimate_one_insert_into_item(reiser4_tree * tree) ++{ ++ /* estimate insert into item just like item insertion */ ++ return tree->estimate_one_insert; ++} ++ ++reiser4_block_nr estimate_one_item_removal(reiser4_tree * tree) ++{ ++ /* on item removal reiser4 does not try to pack nodes more complact, so, ++ only one node may be dirtied on leaf level */ ++ return tree->estimate_one_insert; ++} ++ ++/* on leaf level insert_flow may add CARRY_FLOW_NEW_NODES_LIMIT new nodes and ++ dirty 3 existing nodes (insert point and both its neighbors). ++ Max_balance_overhead should estimate number of blocks which may change/get ++ added on internal levels */ ++reiser4_block_nr estimate_insert_flow(tree_level height) ++{ ++ return 3 + CARRY_FLOW_NEW_NODES_LIMIT + max_balance_overhead(3 + ++ CARRY_FLOW_NEW_NODES_LIMIT, ++ height); ++} ++ ++/* returnes max number of nodes can be occupied by disk cluster */ ++static reiser4_block_nr estimate_cluster(struct inode *inode, int unprepped) ++{ ++ int per_cluster; ++ per_cluster = (unprepped ? 1 : cluster_nrpages(inode)); ++ return 3 + per_cluster + ++ max_balance_overhead(3 + per_cluster, ++ REISER4_MAX_ZTREE_HEIGHT); ++} ++ ++/* how many nodes might get dirty and added ++ during insertion of a disk cluster */ ++reiser4_block_nr estimate_insert_cluster(struct inode *inode) ++{ ++ return estimate_cluster(inode, 1); /* 24 */ ++} ++ ++/* how many nodes might get dirty and added ++ during update of a (prepped or unprepped) disk cluster */ ++reiser4_block_nr estimate_update_cluster(struct inode *inode) ++{ ++ return estimate_cluster(inode, 0); /* 44, for 64K-cluster */ ++} ++ ++/* How many nodes occupied by a disk cluster might get dirty. ++ Note that this estimation is not precise (i.e. disk cluster ++ can occupy more nodes). ++ Q: Why we don't use precise estimation? ++ A: 1.Because precise estimation is fairly bad: 65536 nodes ++ for 64K logical cluster, it means 256M of dead space on ++ a partition ++ 2.It is a very rare case when disk cluster occupies more ++ nodes then this estimation returns. ++*/ ++reiser4_block_nr estimate_dirty_cluster(struct inode *inode) ++{ ++ return cluster_nrpages(inode) + 4; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/export_ops.c linux-2.6.30/fs/reiser4/export_ops.c +--- linux-2.6.30.orig/fs/reiser4/export_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/export_ops.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,328 @@ ++/* Copyright 2005 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#include "inode.h" ++#include "plugin/plugin.h" ++ ++/* ++ * Supported file-handle types ++ */ ++typedef enum { ++ FH_WITH_PARENT = 0x10, /* file handle with parent */ ++ FH_WITHOUT_PARENT = 0x11 /* file handle without parent */ ++} reiser4_fhtype; ++ ++#define NFSERROR (255) ++ ++/* initialize place-holder for object */ ++static void object_on_wire_init(reiser4_object_on_wire *o) ++{ ++ o->plugin = NULL; ++} ++ ++/* finish with @o */ ++static void object_on_wire_done(reiser4_object_on_wire *o) ++{ ++ if (o->plugin != NULL) ++ o->plugin->wire.done(o); ++} ++ ++/* ++ * read serialized object identity from @addr and store information about ++ * object in @obj. This is dual to encode_inode(). ++ */ ++static char *decode_inode(struct super_block *s, char *addr, ++ reiser4_object_on_wire * obj) ++{ ++ file_plugin *fplug; ++ ++ /* identifier of object plugin is stored in the first two bytes, ++ * followed by... */ ++ fplug = file_plugin_by_disk_id(reiser4_get_tree(s), (d16 *) addr); ++ if (fplug != NULL) { ++ addr += sizeof(d16); ++ obj->plugin = fplug; ++ assert("nikita-3520", fplug->wire.read != NULL); ++ /* plugin specific encoding of object identity. */ ++ addr = fplug->wire.read(addr, obj); ++ } else ++ addr = ERR_PTR(RETERR(-EINVAL)); ++ return addr; ++} ++ ++static struct dentry *reiser4_get_dentry(struct super_block *super, ++ void *data); ++/** ++ * reiser4_decode_fh: decode on-wire object - helper function ++ * for fh_to_dentry, fh_to_parent export operations; ++ * @super: super block; ++ * @addr: onwire object to be decoded; ++ * ++ * Returns dentry referring to the object being decoded. ++ */ ++static struct dentry *reiser4_decode_fh(struct super_block * super, ++ char * addr) ++{ ++ reiser4_object_on_wire object; ++ ++ object_on_wire_init(&object); ++ ++ addr = decode_inode(super, addr, &object); ++ if (!IS_ERR(addr)) { ++ struct dentry *d; ++ d = reiser4_get_dentry(super, &object); ++ if (d != NULL && !IS_ERR(d)) ++ /* FIXME check for -ENOMEM */ ++ reiser4_get_dentry_fsdata(d)->stateless = 1; ++ addr = (char *)d; ++ } ++ object_on_wire_done(&object); ++ return (void *)addr; ++} ++ ++static struct dentry *reiser4_fh_to_dentry(struct super_block *sb, ++ struct fid *fid, ++ int fh_len, int fh_type) ++{ ++ reiser4_context *ctx; ++ struct dentry *d; ++ ++ assert("edward-1536", ++ fh_type == FH_WITH_PARENT || fh_type == FH_WITHOUT_PARENT); ++ ++ ctx = reiser4_init_context(sb); ++ if (IS_ERR(ctx)) ++ return (struct dentry *)ctx; ++ ++ d = reiser4_decode_fh(sb, (char *)fid->raw); ++ ++ reiser4_exit_context(ctx); ++ return d; ++} ++ ++static struct dentry *reiser4_fh_to_parent(struct super_block *sb, ++ struct fid *fid, ++ int fh_len, int fh_type) ++{ ++ char * addr; ++ struct dentry * d; ++ reiser4_context *ctx; ++ file_plugin *fplug; ++ ++ if (fh_type == FH_WITHOUT_PARENT) ++ return NULL; ++ assert("edward-1537", fh_type == FH_WITH_PARENT); ++ ++ ctx = reiser4_init_context(sb); ++ if (IS_ERR(ctx)) ++ return (struct dentry *)ctx; ++ addr = (char *)fid->raw; ++ /* extract 2-bytes file plugin id */ ++ fplug = file_plugin_by_disk_id(reiser4_get_tree(sb), (d16 *)addr); ++ if (fplug == NULL) { ++ d = ERR_PTR(RETERR(-EINVAL)); ++ goto exit; ++ } ++ addr += sizeof(d16); ++ /* skip previously encoded object */ ++ addr = fplug->wire.read(addr, NULL /* skip */); ++ if (IS_ERR(addr)) { ++ d = (struct dentry *)addr; ++ goto exit; ++ } ++ /* @extract and decode parent object */ ++ d = reiser4_decode_fh(sb, addr); ++ exit: ++ reiser4_exit_context(ctx); ++ return d; ++} ++ ++/* ++ * Object serialization support. ++ * ++ * To support knfsd file system provides export_operations that are used to ++ * construct and interpret NFS file handles. As a generalization of this, ++ * reiser4 object plugins have serialization support: it provides methods to ++ * create on-wire representation of identity of reiser4 object, and ++ * re-create/locate object given its on-wire identity. ++ * ++ */ ++ ++/* ++ * return number of bytes that on-wire representation of @inode's identity ++ * consumes. ++ */ ++static int encode_inode_size(struct inode *inode) ++{ ++ assert("nikita-3514", inode != NULL); ++ assert("nikita-3515", inode_file_plugin(inode) != NULL); ++ assert("nikita-3516", inode_file_plugin(inode)->wire.size != NULL); ++ ++ return inode_file_plugin(inode)->wire.size(inode) + sizeof(d16); ++} ++ ++/* ++ * store on-wire representation of @inode's identity at the area beginning at ++ * @start. ++ */ ++static char *encode_inode(struct inode *inode, char *start) ++{ ++ assert("nikita-3517", inode != NULL); ++ assert("nikita-3518", inode_file_plugin(inode) != NULL); ++ assert("nikita-3519", inode_file_plugin(inode)->wire.write != NULL); ++ ++ /* ++ * first, store two-byte identifier of object plugin, then ++ */ ++ save_plugin_id(file_plugin_to_plugin(inode_file_plugin(inode)), ++ (d16 *) start); ++ start += sizeof(d16); ++ /* ++ * call plugin to serialize object's identity ++ */ ++ return inode_file_plugin(inode)->wire.write(inode, start); ++} ++ ++/* this returns number of 32 bit long numbers encoded in @lenp. 255 is ++ * returned if file handle can not be stored */ ++/** ++ * reiser4_encode_fh - encode_fh of export operations ++ * @dentry: ++ * @fh: ++ * @lenp: ++ * @need_parent: ++ * ++ */ ++static int ++reiser4_encode_fh(struct dentry *dentry, __u32 *fh, int *lenp, ++ int need_parent) ++{ ++ struct inode *inode; ++ struct inode *parent; ++ char *addr; ++ int need; ++ int delta; ++ int result; ++ reiser4_context *ctx; ++ ++ /* ++ * knfsd asks as to serialize object in @dentry, and, optionally its ++ * parent (if need_parent != 0). ++ * ++ * encode_inode() and encode_inode_size() is used to build ++ * representation of object and its parent. All hard work is done by ++ * object plugins. ++ */ ++ inode = dentry->d_inode; ++ parent = dentry->d_parent->d_inode; ++ ++ addr = (char *)fh; ++ ++ need = encode_inode_size(inode); ++ if (need < 0) ++ return NFSERROR; ++ if (need_parent) { ++ delta = encode_inode_size(parent); ++ if (delta < 0) ++ return NFSERROR; ++ need += delta; ++ } ++ ++ ctx = reiser4_init_context(dentry->d_inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ if (need <= sizeof(__u32) * (*lenp)) { ++ addr = encode_inode(inode, addr); ++ if (need_parent) ++ addr = encode_inode(parent, addr); ++ ++ /* store in lenp number of 32bit words required for file ++ * handle. */ ++ *lenp = (need + sizeof(__u32) - 1) >> 2; ++ result = need_parent ? FH_WITH_PARENT : FH_WITHOUT_PARENT; ++ } else ++ /* no enough space in file handle */ ++ result = NFSERROR; ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/** ++ * reiser4_get_dentry_parent - get_parent of export operations ++ * @child: ++ * ++ */ ++static struct dentry *reiser4_get_dentry_parent(struct dentry *child) ++{ ++ struct inode *dir; ++ dir_plugin *dplug; ++ struct dentry *result; ++ reiser4_context *ctx; ++ ++ assert("nikita-3527", child != NULL); ++ ++ dir = child->d_inode; ++ assert("nikita-3529", dir != NULL); ++ ++ ctx = reiser4_init_context(dir->i_sb); ++ if (IS_ERR(ctx)) ++ return (void *)ctx; ++ ++ dplug = inode_dir_plugin(dir); ++ assert("nikita-3531", ergo(dplug != NULL, dplug->get_parent != NULL)); ++ ++ if (unlikely(dplug == NULL)) { ++ reiser4_exit_context(ctx); ++ return ERR_PTR(RETERR(-ENOTDIR)); ++ } ++ result = dplug->get_parent(dir); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/** ++ * reiser4_get_dentry - get_dentry of export operations ++ * @super: ++ * @data: ++ * ++ * ++ */ ++static struct dentry *reiser4_get_dentry(struct super_block *super, void *data) ++{ ++ reiser4_object_on_wire *o; ++ ++ assert("nikita-3522", super != NULL); ++ assert("nikita-3523", data != NULL); ++ /* ++ * this is only supposed to be called by ++ * ++ * reiser4_decode_fh->find_exported_dentry ++ * ++ * so, reiser4_context should be here already. ++ */ ++ assert("nikita-3526", is_in_reiser4_context()); ++ ++ o = (reiser4_object_on_wire *)data; ++ assert("nikita-3524", o->plugin != NULL); ++ assert("nikita-3525", o->plugin->wire.get != NULL); ++ ++ return o->plugin->wire.get(super, o); ++} ++ ++struct export_operations reiser4_export_operations = { ++ .encode_fh = reiser4_encode_fh, ++ .fh_to_dentry = reiser4_fh_to_dentry, ++ .fh_to_parent = reiser4_fh_to_parent, ++ .get_parent = reiser4_get_dentry_parent, ++}; ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/flush.c linux-2.6.30/fs/reiser4/flush.c +--- linux-2.6.30.orig/fs/reiser4/flush.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/flush.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,3703 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* The design document for this file is at http://www.namesys.com/v4/v4.html. */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "coord.h" ++#include "plugin/item/item.h" ++#include "plugin/plugin.h" ++#include "plugin/object.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree_walk.h" ++#include "carry.h" ++#include "tree.h" ++#include "vfs_ops.h" ++#include "inode.h" ++#include "page_cache.h" ++#include "wander.h" ++#include "super.h" ++#include "entd.h" ++#include "reiser4.h" ++#include "flush.h" ++#include "writeout.h" ++ ++#include <asm/atomic.h> ++#include <linux/fs.h> /* for struct super_block */ ++#include <linux/mm.h> /* for struct page */ ++#include <linux/bio.h> /* for struct bio */ ++#include <linux/pagemap.h> ++#include <linux/blkdev.h> ++ ++/* IMPLEMENTATION NOTES */ ++ ++/* PARENT-FIRST: Some terminology: A parent-first traversal is a way of ++ assigning a total order to the nodes of the tree in which the parent is ++ placed before its children, which are ordered (recursively) in left-to-right ++ order. When we speak of a "parent-first preceder", it describes the node that ++ "came before in forward parent-first order". When we speak of a "parent-first ++ follower", it describes the node that "comes next in parent-first order" ++ (alternatively the node that "came before in reverse parent-first order"). ++ ++ The following pseudo-code prints the nodes of a tree in forward parent-first ++ order: ++ ++ void parent_first (node) ++ { ++ print_node (node); ++ if (node->level > leaf) { ++ for (i = 0; i < num_children; i += 1) { ++ parent_first (node->child[i]); ++ } ++ } ++ } ++*/ ++ ++/* JUST WHAT ARE WE TRYING TO OPTIMIZE, HERE? The idea is to optimize block ++ allocation so that a left-to-right scan of the tree's data (i.e., the leaves ++ in left-to-right order) can be accomplished with sequential reads, which ++ results in reading nodes in their parent-first order. This is a ++ read-optimization aspect of the flush algorithm, and there is also a ++ write-optimization aspect, which is that we wish to make large sequential ++ writes to the disk by allocating or reallocating blocks so that they can be ++ written in sequence. Sometimes the read-optimization and write-optimization ++ goals conflict with each other, as we discuss in more detail below. ++*/ ++ ++/* STATE BITS: The flush code revolves around the state of the jnodes it covers. ++ Here are the relevant jnode->state bits and their relevence to flush: ++ ++ JNODE_DIRTY: If a node is dirty, it must be flushed. But in order to be ++ written it must be allocated first. In order to be considered allocated, ++ the jnode must have exactly one of { JNODE_OVRWR, JNODE_RELOC } set. These ++ two bits are exclusive, and all dirtied jnodes eventually have one of these ++ bits set during each transaction. ++ ++ JNODE_CREATED: The node was freshly created in its transaction and has no ++ previous block address, so it is unconditionally assigned to be relocated, ++ although this is mainly for code-convenience. It is not being 'relocated' ++ from anything, but in almost every regard it is treated as part of the ++ relocate set. The JNODE_CREATED bit remains set even after JNODE_RELOC is ++ set, so the actual relocate can be distinguished from the ++ created-and-allocated set easily: relocate-set members (belonging to the ++ preserve-set) have (JNODE_RELOC) set and created-set members which have no ++ previous location to preserve have (JNODE_RELOC | JNODE_CREATED) set. ++ ++ JNODE_OVRWR: The node belongs to atom's overwrite set. The flush algorithm ++ made the decision to maintain the pre-existing location for this node and ++ it will be written to the wandered-log. ++ ++ JNODE_RELOC: The flush algorithm made the decision to relocate this block ++ (if it was not created, see note above). A block with JNODE_RELOC set is ++ eligible for early-flushing and may be submitted during flush_empty_queues. ++ When the JNODE_RELOC bit is set on a znode, the parent node's internal item ++ is modified and the znode is rehashed. ++ ++ JNODE_SQUEEZABLE: Before shifting everything left, the flush algorithm ++ scans the node and calls plugin->f.squeeze() method for its items. By this ++ technology we update disk clusters of cryptcompress objects. Also if ++ leftmost point that was found by flush scan has this flag (races with ++ write(), rare case) the flush algorythm makes the decision to pass it to ++ squalloc() in spite of its flushprepped status for squeezing, not for ++ repeated allocation. ++ ++ JNODE_FLUSH_QUEUED: This bit is set when a call to flush enters the jnode ++ into its flush queue. This means the jnode is not on any clean or dirty ++ list, instead it is moved to one of the flush queue (see flush_queue.h) ++ object private list. This prevents multiple concurrent flushes from ++ attempting to start flushing from the same node. ++ ++ (DEAD STATE BIT) JNODE_FLUSH_BUSY: This bit was set during the bottom-up ++ squeeze-and-allocate on a node while its children are actively being ++ squeezed and allocated. This flag was created to avoid submitting a write ++ request for a node while its children are still being allocated and ++ squeezed. Then flush queue was re-implemented to allow unlimited number of ++ nodes be queued. This flag support was commented out in source code because ++ we decided that there was no reason to submit queued nodes before ++ jnode_flush() finishes. However, current code calls fq_write() during a ++ slum traversal and may submit "busy nodes" to disk. Probably we can ++ re-enable the JNODE_FLUSH_BUSY bit support in future. ++ ++ With these state bits, we describe a test used frequently in the code below, ++ jnode_is_flushprepped()(and the spin-lock-taking jnode_check_flushprepped()). ++ The test for "flushprepped" returns true if any of the following are true: ++ ++ - The node is not dirty ++ - The node has JNODE_RELOC set ++ - The node has JNODE_OVRWR set ++ ++ If either the node is not dirty or it has already been processed by flush ++ (and assigned JNODE_OVRWR or JNODE_RELOC), then it is prepped. If ++ jnode_is_flushprepped() returns true then flush has work to do on that node. ++*/ ++ ++/* FLUSH_PREP_ONCE_PER_TRANSACTION: Within a single transaction a node is never ++ flushprepped twice (unless an explicit call to flush_unprep is made as ++ described in detail below). For example a node is dirtied, allocated, and ++ then early-flushed to disk and set clean. Before the transaction commits, the ++ page is dirtied again and, due to memory pressure, the node is flushed again. ++ The flush algorithm will not relocate the node to a new disk location, it ++ will simply write it to the same, previously relocated position again. ++*/ ++ ++/* THE BOTTOM-UP VS. TOP-DOWN ISSUE: This code implements a bottom-up algorithm ++ where we start at a leaf node and allocate in parent-first order by iterating ++ to the right. At each step of the iteration, we check for the right neighbor. ++ Before advancing to the right neighbor, we check if the current position and ++ the right neighbor share the same parent. If they do not share the same ++ parent, the parent is allocated before the right neighbor. ++ ++ This process goes recursively up the tree and squeeze nodes level by level as ++ long as the right neighbor and the current position have different parents, ++ then it allocates the right-neighbors-with-different-parents on the way back ++ down. This process is described in more detail in ++ flush_squalloc_changed_ancestor and the recursive function ++ squalloc_one_changed_ancestor. But the purpose here is not to discuss the ++ specifics of the bottom-up approach as it is to contrast the bottom-up and ++ top-down approaches. ++ ++ The top-down algorithm was implemented earlier (April-May 2002). In the ++ top-down approach, we find a starting point by scanning left along each level ++ past dirty nodes, then going up and repeating the process until the left node ++ and the parent node are clean. We then perform a parent-first traversal from ++ the starting point, which makes allocating in parent-first order trivial. ++ After one subtree has been allocated in this manner, we move to the right, ++ try moving upward, then repeat the parent-first traversal. ++ ++ Both approaches have problems that need to be addressed. Both are ++ approximately the same amount of code, but the bottom-up approach has ++ advantages in the order it acquires locks which, at the very least, make it ++ the better approach. At first glance each one makes the other one look ++ simpler, so it is important to remember a few of the problems with each one. ++ ++ Main problem with the top-down approach: When you encounter a clean child ++ during the parent-first traversal, what do you do? You would like to avoid ++ searching through a large tree of nodes just to find a few dirty leaves at ++ the bottom, and there is not an obvious solution. One of the advantages of ++ the top-down approach is that during the parent-first traversal you check ++ every child of a parent to see if it is dirty. In this way, the top-down ++ approach easily handles the main problem of the bottom-up approach: ++ unallocated children. ++ ++ The unallocated children problem is that before writing a node to disk we ++ must make sure that all of its children are allocated. Otherwise, the writing ++ the node means extra I/O because the node will have to be written again when ++ the child is finally allocated. ++ ++ WE HAVE NOT YET ELIMINATED THE UNALLOCATED CHILDREN PROBLEM. Except for bugs, ++ this should not cause any file system corruption, it only degrades I/O ++ performance because a node may be written when it is sure to be written at ++ least one more time in the same transaction when the remaining children are ++ allocated. What follows is a description of how we will solve the problem. ++*/ ++ ++/* HANDLING UNALLOCATED CHILDREN: During flush we may allocate a parent node, ++ then proceeding in parent first order, allocate some of its left-children, ++ then encounter a clean child in the middle of the parent. We do not allocate ++ the clean child, but there may remain unallocated (dirty) children to the ++ right of the clean child. If we were to stop flushing at this moment and ++ write everything to disk, the parent might still contain unallocated ++ children. ++ ++ We could try to allocate all the descendents of every node that we allocate, ++ but this is not necessary. Doing so could result in allocating the entire ++ tree: if the root node is allocated then every unallocated node would have to ++ be allocated before flushing. Actually, we do not have to write a node just ++ because we allocate it. It is possible to allocate but not write a node ++ during flush, when it still has unallocated children. However, this approach ++ is probably not optimal for the following reason. ++ ++ The flush algorithm is designed to allocate nodes in parent-first order in an ++ attempt to optimize reads that occur in the same order. Thus we are ++ read-optimizing for a left-to-right scan through all the leaves in the ++ system, and we are hoping to write-optimize at the same time because those ++ nodes will be written together in batch. What happens, however, if we assign ++ a block number to a node in its read-optimized order but then avoid writing ++ it because it has unallocated children? In that situation, we lose out on the ++ write-optimization aspect because a node will have to be written again to the ++ its location on the device, later, which likely means seeking back to that ++ location. ++ ++ So there are tradeoffs. We can choose either: ++ ++ A. Allocate all unallocated children to preserve both write-optimization and ++ read-optimization, but this is not always desirable because it may mean ++ having to allocate and flush very many nodes at once. ++ ++ B. Defer writing nodes with unallocated children, keep their read-optimized ++ locations, but sacrifice write-optimization because those nodes will be ++ written again. ++ ++ C. Defer writing nodes with unallocated children, but do not keep their ++ read-optimized locations. Instead, choose to write-optimize them later, when ++ they are written. To facilitate this, we "undo" the read-optimized allocation ++ that was given to the node so that later it can be write-optimized, thus ++ "unpreparing" the flush decision. This is a case where we disturb the ++ FLUSH_PREP_ONCE_PER_TRANSACTION rule described above. By a call to ++ flush_unprep() we will: if the node was wandered, unset the JNODE_OVRWR bit; ++ if the node was relocated, unset the JNODE_RELOC bit, non-deferred-deallocate ++ its block location, and set the JNODE_CREATED bit, effectively setting the ++ node back to an unallocated state. ++ ++ We will take the following approach in v4.0: for twig nodes we will always ++ finish allocating unallocated children (A). For nodes with (level > TWIG) ++ we will defer writing and choose write-optimization (C). ++ ++ To summarize, there are several parts to a solution that avoids the problem ++ with unallocated children: ++ ++ FIXME-ZAM: Still no one approach is implemented to eliminate the ++ "UNALLOCATED CHILDREN" problem because there was an experiment which was done ++ showed that we have 1-2 nodes with unallocated children for thousands of ++ written nodes. The experiment was simple like coping/deletion of linux kernel ++ sources. However the problem can arise in more complex tests. I think we have ++ jnode_io_hook to insert a check for unallocated children and see what kind of ++ problem we have. ++ ++ 1. When flush reaches a stopping point (e.g. a clean node) it should continue ++ calling squeeze-and-allocate on any remaining unallocated children. ++ FIXME: Difficulty to implement: should be simple -- amounts to adding a while ++ loop to jnode_flush, see comments in that function. ++ ++ 2. When flush reaches flush_empty_queue(), some of the (level > TWIG) nodes ++ may still have unallocated children. If the twig level has unallocated ++ children it is an assertion failure. If a higher-level node has unallocated ++ children, then it should be explicitly de-allocated by a call to ++ flush_unprep(). ++ FIXME: Difficulty to implement: should be simple. ++ ++ 3. (CPU-Optimization) Checking whether a node has unallocated children may ++ consume more CPU cycles than we would like, and it is possible (but medium ++ complexity) to optimize this somewhat in the case where large sub-trees are ++ flushed. The following observation helps: if both the left- and ++ right-neighbor of a node are processed by the flush algorithm then the node ++ itself is guaranteed to have all of its children allocated. However, the cost ++ of this check may not be so expensive after all: it is not needed for leaves ++ and flush can guarantee this property for twigs. That leaves only (level > ++ TWIG) nodes that have to be checked, so this optimization only helps if at ++ least three (level > TWIG) nodes are flushed in one pass, and the savings ++ will be very small unless there are many more (level > TWIG) nodes. But if ++ there are many (level > TWIG) nodes then the number of blocks being written ++ will be very large, so the savings may be insignificant. That said, the idea ++ is to maintain both the left and right edges of nodes that are processed in ++ flush. When flush_empty_queue() is called, a relatively simple test will ++ tell whether the (level > TWIG) node is on the edge. If it is on the edge, ++ the slow check is necessary, but if it is in the interior then it can be ++ assumed to have all of its children allocated. FIXME: medium complexity to ++ implement, but simple to verify given that we must have a slow check anyway. ++ ++ 4. (Optional) This part is optional, not for v4.0--flush should work ++ independently of whether this option is used or not. Called RAPID_SCAN, the ++ idea is to amend the left-scan operation to take unallocated children into ++ account. Normally, the left-scan operation goes left as long as adjacent ++ nodes are dirty up until some large maximum value (FLUSH_SCAN_MAXNODES) at ++ which point it stops and begins flushing. But scan-left may stop at a ++ position where there are unallocated children to the left with the same ++ parent. When RAPID_SCAN is enabled, the ordinary scan-left operation stops ++ after FLUSH_RELOCATE_THRESHOLD, which is much smaller than ++ FLUSH_SCAN_MAXNODES, then procedes with a rapid scan. The rapid scan skips ++ all the interior children of a node--if the leftmost child of a twig is ++ dirty, check its left neighbor (the rightmost child of the twig to the left). ++ If the left neighbor of the leftmost child is also dirty, then continue the ++ scan at the left twig and repeat. This option will cause flush to allocate ++ more twigs in a single pass, but it also has the potential to write many more ++ nodes than would otherwise be written without the RAPID_SCAN option. ++ RAPID_SCAN was partially implemented, code removed August 12, 2002 by JMACD. ++*/ ++ ++/* FLUSH CALLED ON NON-LEAF LEVEL. Most of our design considerations assume that ++ the starting point for flush is a leaf node, but actually the flush code ++ cares very little about whether or not this is true. It is possible that all ++ the leaf nodes are flushed and dirty parent nodes still remain, in which case ++ jnode_flush() is called on a non-leaf argument. Flush doesn't care--it treats ++ the argument node as if it were a leaf, even when it is not. This is a simple ++ approach, and there may be a more optimal policy but until a problem with ++ this approach is discovered, simplest is probably best. ++ ++ NOTE: In this case, the ordering produced by flush is parent-first only if ++ you ignore the leaves. This is done as a matter of simplicity and there is ++ only one (shaky) justification. When an atom commits, it flushes all leaf ++ level nodes first, followed by twigs, and so on. With flushing done in this ++ order, if flush is eventually called on a non-leaf node it means that ++ (somehow) we reached a point where all leaves are clean and only internal ++ nodes need to be flushed. If that it the case, then it means there were no ++ leaves that were the parent-first preceder/follower of the parent. This is ++ expected to be a rare case, which is why we do nothing special about it. ++ However, memory pressure may pass an internal node to flush when there are ++ still dirty leaf nodes that need to be flushed, which could prove our ++ original assumptions "inoperative". If this needs to be fixed, then ++ scan_left/right should have special checks for the non-leaf levels. For ++ example, instead of passing from a node to the left neighbor, it should pass ++ from the node to the left neighbor's rightmost descendent (if dirty). ++ ++*/ ++ ++/* UNIMPLEMENTED AS YET: REPACKING AND RESIZING. We walk the tree in 4MB-16MB ++ chunks, dirtying everything and putting it into a transaction. We tell the ++ allocator to allocate the blocks as far as possible towards one end of the ++ logical device--the left (starting) end of the device if we are walking from ++ left to right, the right end of the device if we are walking from right to ++ left. We then make passes in alternating directions, and as we do this the ++ device becomes sorted such that tree order and block number order fully ++ correlate. ++ ++ Resizing is done by shifting everything either all the way to the left or all ++ the way to the right, and then reporting the last block. ++*/ ++ ++/* RELOCATE DECISIONS: The code makes a decision to relocate in several places. ++ This descibes the policy from the highest level: ++ ++ The FLUSH_RELOCATE_THRESHOLD parameter: If we count this many consecutive ++ nodes on the leaf level during flush-scan (right, left), then we ++ unconditionally decide to relocate leaf nodes. ++ ++ Otherwise, there are two contexts in which we make a decision to relocate: ++ ++ 1. The REVERSE PARENT-FIRST context: Implemented in reverse_relocate_test(). ++ During the initial stages of flush, after scan-right completes, we want to ++ ask the question: should we relocate this leaf node and thus dirty the parent ++ node. Then if the node is a leftmost child its parent is its own parent-first ++ preceder, thus we repeat the question at the next level up, and so on. In ++ these cases we are moving in the reverse-parent first direction. ++ ++ There is another case which is considered the reverse direction, which comes ++ at the end of a twig in reverse_relocate_end_of_twig(). As we finish ++ processing a twig we may reach a point where there is a clean twig to the ++ right with a dirty leftmost child. In this case, we may wish to relocate the ++ child by testing if it should be relocated relative to its parent. ++ ++ 2. The FORWARD PARENT-FIRST context: Testing for forward relocation is done ++ in allocate_znode. What distinguishes the forward parent-first case from the ++ reverse-parent first case is that the preceder has already been allocated in ++ the forward case, whereas in the reverse case we don't know what the preceder ++ is until we finish "going in reverse". That simplifies the forward case ++ considerably, and there we actually use the block allocator to determine ++ whether, e.g., a block closer to the preceder is available. ++*/ ++ ++/* SQUEEZE_LEFT_EDGE: Unimplemented idea for future consideration. The idea is, ++ once we finish scan-left and find a starting point, if the parent's left ++ neighbor is dirty then squeeze the parent's left neighbor and the parent. ++ This may change the flush-starting-node's parent. Repeat until the child's ++ parent is stable. If the child is a leftmost child, repeat this left-edge ++ squeezing operation at the next level up. Note that we cannot allocate ++ extents during this or they will be out of parent-first order. There is also ++ some difficult coordinate maintenence issues. We can't do a tree search to ++ find coordinates again (because we hold locks), we have to determine them ++ from the two nodes being squeezed. Looks difficult, but has potential to ++ increase space utilization. */ ++ ++/* Flush-scan helper functions. */ ++static void scan_init(flush_scan * scan); ++static void scan_done(flush_scan * scan); ++ ++/* Flush-scan algorithm. */ ++static int scan_left(flush_scan * scan, flush_scan * right, jnode * node, ++ unsigned limit); ++static int scan_right(flush_scan * scan, jnode * node, unsigned limit); ++static int scan_common(flush_scan * scan, flush_scan * other); ++static int scan_formatted(flush_scan * scan); ++static int scan_unformatted(flush_scan * scan, flush_scan * other); ++static int scan_by_coord(flush_scan * scan); ++ ++/* Initial flush-point ancestor allocation. */ ++static int alloc_pos_and_ancestors(flush_pos_t *pos); ++static int alloc_one_ancestor(const coord_t *coord, flush_pos_t *pos); ++static int set_preceder(const coord_t *coord_in, flush_pos_t *pos); ++ ++/* Main flush algorithm. ++ Note on abbreviation: "squeeze and allocate" == "squalloc". */ ++static int squalloc(flush_pos_t *pos); ++ ++/* Flush squeeze implementation. */ ++static int squeeze_right_non_twig(znode * left, znode * right); ++static int shift_one_internal_unit(znode * left, znode * right); ++ ++/* Flush reverse parent-first relocation routines. */ ++static int reverse_relocate_if_close_enough(const reiser4_block_nr * pblk, ++ const reiser4_block_nr * nblk); ++static int reverse_relocate_test(jnode * node, const coord_t *parent_coord, ++ flush_pos_t *pos); ++static int reverse_relocate_check_dirty_parent(jnode * node, ++ const coord_t *parent_coord, ++ flush_pos_t *pos); ++ ++/* Flush allocate write-queueing functions: */ ++static int allocate_znode(znode * node, const coord_t *parent_coord, ++ flush_pos_t *pos); ++static int allocate_znode_update(znode * node, const coord_t *parent_coord, ++ flush_pos_t *pos); ++static int lock_parent_and_allocate_znode(znode *, flush_pos_t *); ++ ++/* Flush helper functions: */ ++static int jnode_lock_parent_coord(jnode * node, ++ coord_t *coord, ++ lock_handle * parent_lh, ++ load_count * parent_zh, ++ znode_lock_mode mode, int try); ++static int neighbor_in_slum(znode * node, lock_handle * right_lock, sideof side, ++ znode_lock_mode mode, int check_dirty, int expected); ++static int znode_same_parents(znode * a, znode * b); ++ ++static int znode_check_flushprepped(znode * node) ++{ ++ return jnode_check_flushprepped(ZJNODE(node)); ++} ++ ++/* Flush position functions */ ++static void pos_init(flush_pos_t *pos); ++static int pos_valid(flush_pos_t *pos); ++static void pos_done(flush_pos_t *pos); ++static int pos_stop(flush_pos_t *pos); ++ ++/* check that @org is first jnode extent unit, if extent is unallocated, ++ * because all jnodes of unallocated extent are dirty and of the same atom. */ ++#define checkchild(scan) \ ++assert("nikita-3435", \ ++ ergo(scan->direction == LEFT_SIDE && \ ++ (scan->parent_coord.node->level == TWIG_LEVEL) && \ ++ jnode_is_unformatted(scan->node) && \ ++ extent_is_unallocated(&scan->parent_coord), \ ++ extent_unit_index(&scan->parent_coord) == index_jnode(scan->node))) ++ ++/* This flush_cnt variable is used to track the number of concurrent flush ++ operations, useful for debugging. It is initialized in txnmgr.c out of ++ laziness (because flush has no static initializer function...) */ ++ON_DEBUG(atomic_t flush_cnt; ++ ) ++ ++/* check fs backing device for write congestion */ ++static int check_write_congestion(void) ++{ ++ struct super_block *sb; ++ struct backing_dev_info *bdi; ++ ++ sb = reiser4_get_current_sb(); ++ bdi = reiser4_get_super_fake(sb)->i_mapping->backing_dev_info; ++ return bdi_write_congested(bdi); ++} ++ ++/* conditionally write flush queue */ ++static int write_prepped_nodes(flush_pos_t *pos) ++{ ++ int ret; ++ ++ assert("zam-831", pos); ++ assert("zam-832", pos->fq); ++ ++ if (!(pos->flags & JNODE_FLUSH_WRITE_BLOCKS)) ++ return 0; ++ ++ if (check_write_congestion()) ++ return 0; ++ ++ ret = reiser4_write_fq(pos->fq, pos->nr_written, ++ WRITEOUT_SINGLE_STREAM | WRITEOUT_FOR_PAGE_RECLAIM); ++ return ret; ++} ++ ++/* Proper release all flush pos. resources then move flush position to new ++ locked node */ ++static void move_flush_pos(flush_pos_t *pos, lock_handle * new_lock, ++ load_count * new_load, const coord_t *new_coord) ++{ ++ assert("zam-857", new_lock->node == new_load->node); ++ ++ if (new_coord) { ++ assert("zam-858", new_coord->node == new_lock->node); ++ coord_dup(&pos->coord, new_coord); ++ } else { ++ coord_init_first_unit(&pos->coord, new_lock->node); ++ } ++ ++ if (pos->child) { ++ jput(pos->child); ++ pos->child = NULL; ++ } ++ ++ move_load_count(&pos->load, new_load); ++ done_lh(&pos->lock); ++ move_lh(&pos->lock, new_lock); ++} ++ ++/* delete empty node which link from the parent still exists. */ ++static int delete_empty_node(znode * node) ++{ ++ reiser4_key smallest_removed; ++ ++ assert("zam-1019", node != NULL); ++ assert("zam-1020", node_is_empty(node)); ++ assert("zam-1023", znode_is_wlocked(node)); ++ ++ return reiser4_delete_node(node, &smallest_removed, NULL, 1); ++} ++ ++/* Prepare flush position for alloc_pos_and_ancestors() and squalloc() */ ++static int prepare_flush_pos(flush_pos_t *pos, jnode * org) ++{ ++ int ret; ++ load_count load; ++ lock_handle lock; ++ ++ init_lh(&lock); ++ init_load_count(&load); ++ ++ if (jnode_is_znode(org)) { ++ ret = longterm_lock_znode(&lock, JZNODE(org), ++ ZNODE_WRITE_LOCK, ZNODE_LOCK_HIPRI); ++ if (ret) ++ return ret; ++ ++ ret = incr_load_count_znode(&load, JZNODE(org)); ++ if (ret) ++ return ret; ++ ++ pos->state = ++ (jnode_get_level(org) == ++ LEAF_LEVEL) ? POS_ON_LEAF : POS_ON_INTERNAL; ++ move_flush_pos(pos, &lock, &load, NULL); ++ } else { ++ coord_t parent_coord; ++ ret = jnode_lock_parent_coord(org, &parent_coord, &lock, ++ &load, ZNODE_WRITE_LOCK, 0); ++ if (ret) ++ goto done; ++ if (!item_is_extent(&parent_coord)) { ++ /* file was converted to tail, org became HB, we found ++ internal item */ ++ ret = -EAGAIN; ++ goto done; ++ } ++ ++ pos->state = POS_ON_EPOINT; ++ move_flush_pos(pos, &lock, &load, &parent_coord); ++ pos->child = jref(org); ++ if (extent_is_unallocated(&parent_coord) ++ && extent_unit_index(&parent_coord) != index_jnode(org)) { ++ /* @org is not first child of its parent unit. This may ++ happen because longerm lock of its parent node was ++ released between scan_left and scan_right. For now ++ work around this having flush to repeat */ ++ ret = -EAGAIN; ++ } ++ } ++ ++done: ++ done_load_count(&load); ++ done_lh(&lock); ++ return ret; ++} ++ ++/* TODO LIST (no particular order): */ ++/* I have labelled most of the legitimate FIXME comments in this file with ++ letters to indicate which issue they relate to. There are a few miscellaneous ++ FIXMEs with specific names mentioned instead that need to be ++ inspected/resolved. */ ++/* B. There is an issue described in reverse_relocate_test having to do with an ++ imprecise is_preceder? check having to do with partially-dirty extents. The ++ code that sets preceder hints and computes the preceder is basically ++ untested. Careful testing needs to be done that preceder calculations are ++ done correctly, since if it doesn't affect correctness we will not catch this ++ stuff during regular testing. */ ++/* C. EINVAL, E_DEADLOCK, E_NO_NEIGHBOR, ENOENT handling. It is unclear which of ++ these are considered expected but unlikely conditions. Flush currently ++ returns 0 (i.e., success but no progress, i.e., restart) whenever it receives ++ any of these in jnode_flush(). Many of the calls that may produce one of ++ these return values (i.e., longterm_lock_znode, reiser4_get_parent, ++ reiser4_get_neighbor, ...) check some of these values themselves and, for ++ instance, stop flushing instead of resulting in a restart. If any of these ++ results are true error conditions then flush will go into a busy-loop, as we ++ noticed during testing when a corrupt tree caused find_child_ptr to return ++ ENOENT. It needs careful thought and testing of corner conditions. ++*/ ++/* D. Atomicity of flush_prep against deletion and flush concurrency. Suppose a ++ created block is assigned a block number then early-flushed to disk. It is ++ dirtied again and flush is called again. Concurrently, that block is deleted, ++ and the de-allocation of its block number does not need to be deferred, since ++ it is not part of the preserve set (i.e., it didn't exist before the ++ transaction). I think there may be a race condition where flush writes the ++ dirty, created block after the non-deferred deallocated block number is ++ re-allocated, making it possible to write deleted data on top of non-deleted ++ data. Its just a theory, but it needs to be thought out. */ ++/* F. bio_alloc() failure is not handled gracefully. */ ++/* G. Unallocated children. */ ++/* H. Add a WANDERED_LIST to the atom to clarify the placement of wandered ++ blocks. */ ++/* I. Rename flush-scan to scan-point, (flush-pos to flush-point?) */ ++ ++/* JNODE_FLUSH: MAIN ENTRY POINT */ ++/* This is the main entry point for flushing a jnode and its dirty neighborhood ++ (dirty neighborhood is named "slum"). Jnode_flush() is called if reiser4 has ++ to write dirty blocks to disk, it happens when Linux VM decides to reduce ++ number of dirty pages or as a part of transaction commit. ++ ++ Our objective here is to prep and flush the slum the jnode belongs to. We ++ want to squish the slum together, and allocate the nodes in it as we squish ++ because allocation of children affects squishing of parents. ++ ++ The "argument" @node tells flush where to start. From there, flush finds the ++ left edge of the slum, and calls squalloc (in which nodes are squeezed and ++ allocated). To find a "better place" to start squalloc first we perform a ++ flush_scan. ++ ++ Flush-scanning may be performed in both left and right directions, but for ++ different purposes. When scanning to the left, we are searching for a node ++ that precedes a sequence of parent-first-ordered nodes which we will then ++ flush in parent-first order. During flush-scanning, we also take the ++ opportunity to count the number of consecutive leaf nodes. If this number is ++ past some threshold (FLUSH_RELOCATE_THRESHOLD), then we make a decision to ++ reallocate leaf nodes (thus favoring write-optimization). ++ ++ Since the flush argument node can be anywhere in a sequence of dirty leaves, ++ there may also be dirty nodes to the right of the argument. If the scan-left ++ operation does not count at least FLUSH_RELOCATE_THRESHOLD nodes then we ++ follow it with a right-scan operation to see whether there is, in fact, ++ enough nodes to meet the relocate threshold. Each right- and left-scan ++ operation uses a single flush_scan object. ++ ++ After left-scan and possibly right-scan, we prepare a flush_position object ++ with the starting flush point or parent coordinate, which was determined ++ using scan-left. ++ ++ Next we call the main flush routine, squalloc, which iterates along the leaf ++ level, squeezing and allocating nodes (and placing them into the flush ++ queue). ++ ++ After squalloc returns we take extra steps to ensure that all the children ++ of the final twig node are allocated--this involves repeating squalloc ++ until we finish at a twig with no unallocated children. ++ ++ Finally, we call flush_empty_queue to submit write-requests to disk. If we ++ encounter any above-twig nodes during flush_empty_queue that still have ++ unallocated children, we flush_unprep them. ++ ++ Flush treats several "failure" cases as non-failures, essentially causing ++ them to start over. E_DEADLOCK is one example. ++ FIXME:(C) EINVAL, E_NO_NEIGHBOR, ENOENT: these should probably be handled ++ properly rather than restarting, but there are a bunch of cases to audit. ++*/ ++ ++static int ++jnode_flush(jnode * node, long nr_to_write, long *nr_written, ++ flush_queue_t *fq, int flags) ++{ ++ long ret = 0; ++ flush_scan *right_scan; ++ flush_scan *left_scan; ++ flush_pos_t *flush_pos; ++ int todo; ++ struct super_block *sb; ++ reiser4_super_info_data *sbinfo; ++ jnode *leftmost_in_slum = NULL; ++ ++ assert("jmacd-76619", lock_stack_isclean(get_current_lock_stack())); ++ assert("nikita-3022", reiser4_schedulable()); ++ ++ assert("nikita-3185", ++ get_current_super_private()->delete_mutex_owner != current); ++ ++ /* allocate right_scan, left_scan and flush_pos */ ++ right_scan = ++ kmalloc(2 * sizeof(*right_scan) + sizeof(*flush_pos), ++ reiser4_ctx_gfp_mask_get()); ++ if (right_scan == NULL) ++ return RETERR(-ENOMEM); ++ left_scan = right_scan + 1; ++ flush_pos = (flush_pos_t *) (left_scan + 1); ++ ++ sb = reiser4_get_current_sb(); ++ sbinfo = get_super_private(sb); ++ ++ /* Flush-concurrency debug code */ ++#if REISER4_DEBUG ++ atomic_inc(&flush_cnt); ++#endif ++ ++ reiser4_enter_flush(sb); ++ ++ /* Initialize a flush position. */ ++ pos_init(flush_pos); ++ ++ flush_pos->nr_written = nr_written; ++ flush_pos->fq = fq; ++ flush_pos->flags = flags; ++ flush_pos->nr_to_write = nr_to_write; ++ ++ scan_init(right_scan); ++ scan_init(left_scan); ++ ++ /* First scan left and remember the leftmost scan position. If the ++ leftmost position is unformatted we remember its parent_coord. We ++ scan until counting FLUSH_SCAN_MAXNODES. ++ ++ If starting @node is unformatted, at the beginning of left scan its ++ parent (twig level node, containing extent item) will be long term ++ locked and lock handle will be stored in the ++ @right_scan->parent_lock. This lock is used to start the rightward ++ scan without redoing the tree traversal (necessary to find parent) ++ and, hence, is kept during leftward scan. As a result, we have to ++ use try-lock when taking long term locks during the leftward scan. ++ */ ++ ret = scan_left(left_scan, right_scan, ++ node, sbinfo->flush.scan_maxnodes); ++ if (ret != 0) ++ goto failed; ++ ++ leftmost_in_slum = jref(left_scan->node); ++ scan_done(left_scan); ++ ++ /* Then possibly go right to decide if we will use a policy of ++ relocating leaves. This is only done if we did not scan past (and ++ count) enough nodes during the leftward scan. If we do scan right, ++ we only care to go far enough to establish that at least ++ FLUSH_RELOCATE_THRESHOLD number of nodes are being flushed. The scan ++ limit is the difference between left_scan.count and the threshold. */ ++ ++ todo = sbinfo->flush.relocate_threshold - left_scan->count; ++ /* scan right is inherently deadlock prone, because we are ++ * (potentially) holding a lock on the twig node at this moment. ++ * FIXME: this is incorrect comment: lock is not held */ ++ if (todo > 0) { ++ ret = scan_right(right_scan, node, (unsigned)todo); ++ if (ret != 0) ++ goto failed; ++ } ++ ++ /* Only the right-scan count is needed, release any rightward locks ++ right away. */ ++ scan_done(right_scan); ++ ++ /* ... and the answer is: we should relocate leaf nodes if at least ++ FLUSH_RELOCATE_THRESHOLD nodes were found. */ ++ flush_pos->leaf_relocate = JF_ISSET(node, JNODE_REPACK) || ++ (left_scan->count + right_scan->count >= ++ sbinfo->flush.relocate_threshold); ++ ++ /* Funny business here. We set the 'point' in the flush_position at ++ prior to starting squalloc regardless of whether the first point is ++ formatted or unformatted. Without this there would be an invariant, ++ in the rest of the code, that if the flush_position is unformatted ++ then flush_position->point is NULL and ++ flush_position->parent_{lock,coord} is set, and if the flush_position ++ is formatted then flush_position->point is non-NULL and no parent ++ info is set. ++ ++ This seems lazy, but it makes the initial calls to ++ reverse_relocate_test (which ask "is it the pos->point the leftmost ++ child of its parent") much easier because we know the first child ++ already. Nothing is broken by this, but the reasoning is subtle. ++ Holding an extra reference on a jnode during flush can cause us to ++ see nodes with HEARD_BANSHEE during squalloc, because nodes are not ++ removed from sibling lists until they have zero reference count. ++ Flush would never observe a HEARD_BANSHEE node on the left-edge of ++ flush, nodes are only deleted to the right. So if nothing is broken, ++ why fix it? ++ ++ NOTE-NIKITA actually, flush can meet HEARD_BANSHEE node at any ++ point and in any moment, because of the concurrent file system ++ activity (for example, truncate). */ ++ ++ /* Check jnode state after flush_scan completed. Having a lock on this ++ node or its parent (in case of unformatted) helps us in case of ++ concurrent flushing. */ ++ if (jnode_check_flushprepped(leftmost_in_slum) ++ && !jnode_convertible(leftmost_in_slum)) { ++ ret = 0; ++ goto failed; ++ } ++ ++ /* Now setup flush_pos using scan_left's endpoint. */ ++ ret = prepare_flush_pos(flush_pos, leftmost_in_slum); ++ if (ret) ++ goto failed; ++ ++ if (znode_get_level(flush_pos->coord.node) == LEAF_LEVEL ++ && node_is_empty(flush_pos->coord.node)) { ++ znode *empty = flush_pos->coord.node; ++ ++ assert("zam-1022", !ZF_ISSET(empty, JNODE_HEARD_BANSHEE)); ++ ret = delete_empty_node(empty); ++ goto failed; ++ } ++ ++ if (jnode_check_flushprepped(leftmost_in_slum) ++ && !jnode_convertible(leftmost_in_slum)) { ++ ret = 0; ++ goto failed; ++ } ++ ++ /* Set pos->preceder and (re)allocate pos and its ancestors if it is ++ needed */ ++ ret = alloc_pos_and_ancestors(flush_pos); ++ if (ret) ++ goto failed; ++ ++ /* Do the main rightward-bottom-up squeeze and allocate loop. */ ++ ret = squalloc(flush_pos); ++ pos_stop(flush_pos); ++ if (ret) ++ goto failed; ++ ++ /* FIXME_NFQUCMPD: Here, handle the twig-special case for unallocated ++ children. First, the pos_stop() and pos_valid() routines should be ++ modified so that pos_stop() sets a flush_position->stop flag to 1 ++ without releasing the current position immediately--instead release ++ it in pos_done(). This is a better implementation than the current ++ one anyway. ++ ++ It is not clear that all fields of the flush_position should not be ++ released, but at the very least the parent_lock, parent_coord, and ++ parent_load should remain held because they are hold the last twig ++ when pos_stop() is called. ++ ++ When we reach this point in the code, if the parent_coord is set to ++ after the last item then we know that flush reached the end of a twig ++ (and according to the new flush queueing design, we will return now). ++ If parent_coord is not past the last item, we should check if the ++ current twig has any unallocated children to the right (we are not ++ concerned with unallocated children to the left--in that case the ++ twig itself should not have been allocated). If the twig has ++ unallocated children to the right, set the parent_coord to that ++ position and then repeat the call to squalloc. ++ ++ Testing for unallocated children may be defined in two ways: if any ++ internal item has a fake block number, it is unallocated; if any ++ extent item is unallocated then all of its children are unallocated. ++ But there is a more aggressive approach: if there are any dirty ++ children of the twig to the right of the current position, we may ++ wish to relocate those nodes now. Checking for potential relocation ++ is more expensive as it requires knowing whether there are any dirty ++ children that are not unallocated. The extent_needs_allocation should ++ be used after setting the correct preceder. ++ ++ When we reach the end of a twig at this point in the code, if the ++ flush can continue (when the queue is ready) it will need some ++ information on the future starting point. That should be stored away ++ in the flush_handle using a seal, I believe. Holding a jref() on the ++ future starting point may break other code that deletes that node. ++ */ ++ ++ /* FIXME_NFQUCMPD: Also, we don't want to do any flushing when flush is ++ called above the twig level. If the VM calls flush above the twig ++ level, do nothing and return (but figure out why this happens). The ++ txnmgr should be modified to only flush its leaf-level dirty list. ++ This will do all the necessary squeeze and allocate steps but leave ++ unallocated branches and possibly unallocated twigs (when the twig's ++ leftmost child is not dirty). After flushing the leaf level, the ++ remaining unallocated nodes should be given write-optimized ++ locations. (Possibly, the remaining unallocated twigs should be ++ allocated just before their leftmost child.) ++ */ ++ ++ /* Any failure reaches this point. */ ++failed: ++ ++ switch (ret) { ++ case -E_REPEAT: ++ case -EINVAL: ++ case -E_DEADLOCK: ++ case -E_NO_NEIGHBOR: ++ case -ENOENT: ++ /* FIXME(C): Except for E_DEADLOCK, these should probably be ++ handled properly in each case. They already are handled in ++ many cases. */ ++ /* Something bad happened, but difficult to avoid... Try again! ++ */ ++ ret = 0; ++ } ++ ++ if (leftmost_in_slum) ++ jput(leftmost_in_slum); ++ ++ pos_done(flush_pos); ++ scan_done(left_scan); ++ scan_done(right_scan); ++ kfree(right_scan); ++ ++ ON_DEBUG(atomic_dec(&flush_cnt)); ++ ++ reiser4_leave_flush(sb); ++ ++ return ret; ++} ++ ++/* The reiser4 flush subsystem can be turned into "rapid flush mode" means that ++ * flusher should submit all prepped nodes immediately without keeping them in ++ * flush queues for long time. The reason for rapid flush mode is to free ++ * memory as fast as possible. */ ++ ++#if REISER4_USE_RAPID_FLUSH ++ ++/** ++ * submit all prepped nodes if rapid flush mode is set, ++ * turn rapid flush mode off. ++ */ ++ ++static int rapid_flush(flush_pos_t *pos) ++{ ++ if (!wbq_available()) ++ return 0; ++ ++ return write_prepped_nodes(pos); ++} ++ ++#else ++ ++#define rapid_flush(pos) (0) ++ ++#endif /* REISER4_USE_RAPID_FLUSH */ ++ ++static jnode *find_flush_start_jnode(jnode *start, txn_atom * atom, ++ flush_queue_t *fq, int *nr_queued, ++ int flags) ++{ ++ jnode * node; ++ ++ if (start != NULL) { ++ spin_lock_jnode(start); ++ if (!jnode_is_flushprepped(start)) { ++ assert("zam-1056", start->atom == atom); ++ node = start; ++ goto enter; ++ } ++ spin_unlock_jnode(start); ++ } ++ /* ++ * In this loop we process all already prepped (RELOC or OVRWR) and ++ * dirtied again nodes. The atom spin lock is not released until all ++ * dirty nodes processed or not prepped node found in the atom dirty ++ * lists. ++ */ ++ while ((node = find_first_dirty_jnode(atom, flags))) { ++ spin_lock_jnode(node); ++enter: ++ assert("zam-881", JF_ISSET(node, JNODE_DIRTY)); ++ assert("zam-898", !JF_ISSET(node, JNODE_OVRWR)); ++ ++ if (JF_ISSET(node, JNODE_WRITEBACK)) { ++ /* move node to the end of atom's writeback list */ ++ list_move_tail(&node->capture_link, ATOM_WB_LIST(atom)); ++ ++ /* ++ * jnode is not necessarily on dirty list: if it was ++ * dirtied when it was on flush queue - it does not get ++ * moved to dirty list ++ */ ++ ON_DEBUG(count_jnode(atom, node, NODE_LIST(node), ++ WB_LIST, 1)); ++ ++ } else if (jnode_is_znode(node) ++ && znode_above_root(JZNODE(node))) { ++ /* ++ * A special case for znode-above-root. The above-root ++ * (fake) znode is captured and dirtied when the tree ++ * height changes or when the root node is relocated. ++ * This causes atoms to fuse so that changes at the root ++ * are serialized. However, this node is never flushed. ++ * This special case used to be in lock.c to prevent the ++ * above-root node from ever being captured, but now ++ * that it is captured we simply prevent it from ++ * flushing. The log-writer code relies on this to ++ * properly log superblock modifications of the tree ++ * height. ++ */ ++ jnode_make_wander_nolock(node); ++ } else if (JF_ISSET(node, JNODE_RELOC)) { ++ queue_jnode(fq, node); ++ ++(*nr_queued); ++ } else ++ break; ++ ++ spin_unlock_jnode(node); ++ } ++ return node; ++} ++ ++/* Flush some nodes of current atom, usually slum, return -E_REPEAT if there are ++ * more nodes to flush, return 0 if atom's dirty lists empty and keep current ++ * atom locked, return other errors as they are. */ ++int ++flush_current_atom(int flags, long nr_to_write, long *nr_submitted, ++ txn_atom ** atom, jnode *start) ++{ ++ reiser4_super_info_data *sinfo = get_current_super_private(); ++ flush_queue_t *fq = NULL; ++ jnode *node; ++ int nr_queued; ++ int ret; ++ ++ assert("zam-889", atom != NULL && *atom != NULL); ++ assert_spin_locked(&((*atom)->alock)); ++ assert("zam-892", get_current_context()->trans->atom == *atom); ++ ++ nr_to_write = LONG_MAX; ++ while (1) { ++ ret = reiser4_fq_by_atom(*atom, &fq); ++ if (ret != -E_REPEAT) ++ break; ++ *atom = get_current_atom_locked(); ++ } ++ if (ret) ++ return ret; ++ ++ assert_spin_locked(&((*atom)->alock)); ++ ++ /* parallel flushers limit */ ++ if (sinfo->tmgr.atom_max_flushers != 0) { ++ while ((*atom)->nr_flushers >= sinfo->tmgr.atom_max_flushers) { ++ /* An reiser4_atom_send_event() call is inside ++ reiser4_fq_put_nolock() which is called when flush is ++ finished and nr_flushers is decremented. */ ++ reiser4_atom_wait_event(*atom); ++ *atom = get_current_atom_locked(); ++ } ++ } ++ ++ /* count ourself as a flusher */ ++ (*atom)->nr_flushers++; ++ ++ writeout_mode_enable(); ++ ++ nr_queued = 0; ++ node = find_flush_start_jnode(start, *atom, fq, &nr_queued, flags); ++ ++ if (node == NULL) { ++ if (nr_queued == 0) { ++ (*atom)->nr_flushers--; ++ reiser4_fq_put_nolock(fq); ++ reiser4_atom_send_event(*atom); ++ /* current atom remains locked */ ++ writeout_mode_disable(); ++ return 0; ++ } ++ spin_unlock_atom(*atom); ++ } else { ++ jref(node); ++ BUG_ON((*atom)->super != node->tree->super); ++ spin_unlock_atom(*atom); ++ spin_unlock_jnode(node); ++ BUG_ON(nr_to_write == 0); ++ ret = jnode_flush(node, nr_to_write, nr_submitted, fq, flags); ++ jput(node); ++ } ++ ++ ret = ++ reiser4_write_fq(fq, nr_submitted, ++ WRITEOUT_SINGLE_STREAM | WRITEOUT_FOR_PAGE_RECLAIM); ++ ++ *atom = get_current_atom_locked(); ++ (*atom)->nr_flushers--; ++ reiser4_fq_put_nolock(fq); ++ reiser4_atom_send_event(*atom); ++ spin_unlock_atom(*atom); ++ ++ writeout_mode_disable(); ++ ++ if (ret == 0) ++ ret = -E_REPEAT; ++ ++ return ret; ++} ++ ++/* REVERSE PARENT-FIRST RELOCATION POLICIES */ ++ ++/* This implements the is-it-close-enough-to-its-preceder? test for relocation ++ in the reverse parent-first relocate context. Here all we know is the ++ preceder and the block number. Since we are going in reverse, the preceder ++ may still be relocated as well, so we can't ask the block allocator "is there ++ a closer block available to relocate?" here. In the _forward_ parent-first ++ relocate context (not here) we actually call the block allocator to try and ++ find a closer location. */ ++static int ++reverse_relocate_if_close_enough(const reiser4_block_nr * pblk, ++ const reiser4_block_nr * nblk) ++{ ++ reiser4_block_nr dist; ++ ++ assert("jmacd-7710", *pblk != 0 && *nblk != 0); ++ assert("jmacd-7711", !reiser4_blocknr_is_fake(pblk)); ++ assert("jmacd-7712", !reiser4_blocknr_is_fake(nblk)); ++ ++ /* Distance is the absolute value. */ ++ dist = (*pblk > *nblk) ? (*pblk - *nblk) : (*nblk - *pblk); ++ ++ /* If the block is less than FLUSH_RELOCATE_DISTANCE blocks away from ++ its preceder block, do not relocate. */ ++ if (dist <= get_current_super_private()->flush.relocate_distance) ++ return 0; ++ ++ return 1; ++} ++ ++/* This function is a predicate that tests for relocation. Always called in the ++ reverse-parent-first context, when we are asking whether the current node ++ should be relocated in order to expand the flush by dirtying the parent level ++ (and thus proceeding to flush that level). When traversing in the forward ++ parent-first direction (not here), relocation decisions are handled in two ++ places: allocate_znode() and extent_needs_allocation(). */ ++static int ++reverse_relocate_test(jnode * node, const coord_t *parent_coord, ++ flush_pos_t *pos) ++{ ++ reiser4_block_nr pblk = 0; ++ reiser4_block_nr nblk = 0; ++ ++ assert("jmacd-8989", !jnode_is_root(node)); ++ ++ /* ++ * This function is called only from the ++ * reverse_relocate_check_dirty_parent() and only if the parent ++ * node is clean. This implies that the parent has the real (i.e., not ++ * fake) block number, and, so does the child, because otherwise the ++ * parent would be dirty. ++ */ ++ ++ /* New nodes are treated as if they are being relocated. */ ++ if (JF_ISSET(node, JNODE_CREATED) || ++ (pos->leaf_relocate && jnode_get_level(node) == LEAF_LEVEL)) ++ return 1; ++ ++ /* Find the preceder. FIXME(B): When the child is an unformatted, ++ previously existing node, the coord may be leftmost even though the ++ child is not the parent-first preceder of the parent. If the first ++ dirty node appears somewhere in the middle of the first extent unit, ++ this preceder calculation is wrong. ++ Needs more logic in here. */ ++ if (coord_is_leftmost_unit(parent_coord)) { ++ pblk = *znode_get_block(parent_coord->node); ++ } else { ++ pblk = pos->preceder.blk; ++ } ++ check_preceder(pblk); ++ ++ /* If (pblk == 0) then the preceder isn't allocated or isn't known: ++ relocate. */ ++ if (pblk == 0) ++ return 1; ++ ++ nblk = *jnode_get_block(node); ++ ++ if (reiser4_blocknr_is_fake(&nblk)) ++ /* child is unallocated, mark parent dirty */ ++ return 1; ++ ++ return reverse_relocate_if_close_enough(&pblk, &nblk); ++} ++ ++/* This function calls reverse_relocate_test to make a reverse-parent-first ++ relocation decision and then, if yes, it marks the parent dirty. */ ++static int ++reverse_relocate_check_dirty_parent(jnode * node, const coord_t *parent_coord, ++ flush_pos_t *pos) ++{ ++ int ret; ++ ++ if (!JF_ISSET(ZJNODE(parent_coord->node), JNODE_DIRTY)) { ++ ++ ret = reverse_relocate_test(node, parent_coord, pos); ++ if (ret < 0) ++ return ret; ++ ++ /* FIXME-ZAM ++ if parent is already relocated - we do not want to grab space, ++ right? */ ++ if (ret == 1) { ++ int grabbed; ++ ++ grabbed = get_current_context()->grabbed_blocks; ++ if (reiser4_grab_space_force((__u64) 1, BA_RESERVED) != ++ 0) ++ reiser4_panic("umka-1250", ++ "No space left during flush."); ++ ++ assert("jmacd-18923", ++ znode_is_write_locked(parent_coord->node)); ++ znode_make_dirty(parent_coord->node); ++ grabbed2free_mark(grabbed); ++ } ++ } ++ ++ return 0; ++} ++ ++/* INITIAL ALLOCATE ANCESTORS STEP (REVERSE PARENT-FIRST ALLOCATION BEFORE ++ FORWARD PARENT-FIRST LOOP BEGINS) */ ++ ++/* Get the leftmost child for given coord. */ ++static int get_leftmost_child_of_unit(const coord_t *coord, jnode ** child) ++{ ++ int ret; ++ ++ ret = item_utmost_child(coord, LEFT_SIDE, child); ++ ++ if (ret) ++ return ret; ++ ++ if (IS_ERR(*child)) ++ return PTR_ERR(*child); ++ ++ return 0; ++} ++ ++/* This step occurs after the left- and right-scans are completed, before ++ starting the forward parent-first traversal. Here we attempt to allocate ++ ancestors of the starting flush point, which means continuing in the reverse ++ parent-first direction to the parent, grandparent, and so on (as long as the ++ child is a leftmost child). This routine calls a recursive process, ++ alloc_one_ancestor, which does the real work, except there is special-case ++ handling here for the first ancestor, which may be a twig. At each level ++ (here and alloc_one_ancestor), we check for relocation and then, if the child ++ is a leftmost child, repeat at the next level. On the way back down (the ++ recursion), we allocate the ancestors in parent-first order. */ ++static int alloc_pos_and_ancestors(flush_pos_t *pos) ++{ ++ int ret = 0; ++ lock_handle plock; ++ load_count pload; ++ coord_t pcoord; ++ ++ if (znode_check_flushprepped(pos->lock.node)) ++ return 0; ++ ++ coord_init_invalid(&pcoord, NULL); ++ init_lh(&plock); ++ init_load_count(&pload); ++ ++ if (pos->state == POS_ON_EPOINT) { ++ /* a special case for pos on twig level, where we already have ++ a lock on parent node. */ ++ /* The parent may not be dirty, in which case we should decide ++ whether to relocate the child now. If decision is made to ++ relocate the child, the parent is marked dirty. */ ++ ret = ++ reverse_relocate_check_dirty_parent(pos->child, &pos->coord, ++ pos); ++ if (ret) ++ goto exit; ++ ++ /* FIXME_NFQUCMPD: We only need to allocate the twig (if child ++ is leftmost) and the leaf/child, so recursion is not needed. ++ Levels above the twig will be allocated for ++ write-optimization before the transaction commits. */ ++ ++ /* Do the recursive step, allocating zero or more of our ++ * ancestors. */ ++ ret = alloc_one_ancestor(&pos->coord, pos); ++ ++ } else { ++ if (!znode_is_root(pos->lock.node)) { ++ /* all formatted nodes except tree root */ ++ ret = ++ reiser4_get_parent(&plock, pos->lock.node, ++ ZNODE_WRITE_LOCK); ++ if (ret) ++ goto exit; ++ ++ ret = incr_load_count_znode(&pload, plock.node); ++ if (ret) ++ goto exit; ++ ++ ret = ++ find_child_ptr(plock.node, pos->lock.node, &pcoord); ++ if (ret) ++ goto exit; ++ ++ ret = ++ reverse_relocate_check_dirty_parent(ZJNODE ++ (pos->lock. ++ node), &pcoord, ++ pos); ++ if (ret) ++ goto exit; ++ ++ ret = alloc_one_ancestor(&pcoord, pos); ++ if (ret) ++ goto exit; ++ } ++ ++ ret = allocate_znode(pos->lock.node, &pcoord, pos); ++ } ++exit: ++ done_load_count(&pload); ++ done_lh(&plock); ++ return ret; ++} ++ ++/* This is the recursive step described in alloc_pos_and_ancestors, above. ++ Ignoring the call to set_preceder, which is the next function described, this ++ checks if the child is a leftmost child and returns if it is not. If the ++ child is a leftmost child it checks for relocation, possibly dirtying the ++ parent. Then it performs the recursive step. */ ++static int alloc_one_ancestor(const coord_t *coord, flush_pos_t *pos) ++{ ++ int ret = 0; ++ lock_handle alock; ++ load_count aload; ++ coord_t acoord; ++ ++ /* As we ascend at the left-edge of the region to flush, take this ++ opportunity at the twig level to find our parent-first preceder ++ unless we have already set it. */ ++ if (pos->preceder.blk == 0) { ++ ret = set_preceder(coord, pos); ++ if (ret != 0) ++ return ret; ++ } ++ ++ /* If the ancestor is clean or already allocated, or if the child is not ++ a leftmost child, stop going up, even leaving coord->node not ++ flushprepped. */ ++ if (znode_check_flushprepped(coord->node) ++ || !coord_is_leftmost_unit(coord)) ++ return 0; ++ ++ init_lh(&alock); ++ init_load_count(&aload); ++ coord_init_invalid(&acoord, NULL); ++ ++ /* Only ascend to the next level if it is a leftmost child, but ++ write-lock the parent in case we will relocate the child. */ ++ if (!znode_is_root(coord->node)) { ++ ++ ret = ++ jnode_lock_parent_coord(ZJNODE(coord->node), &acoord, ++ &alock, &aload, ZNODE_WRITE_LOCK, ++ 0); ++ if (ret != 0) { ++ /* FIXME(C): check EINVAL, E_DEADLOCK */ ++ goto exit; ++ } ++ ++ ret = ++ reverse_relocate_check_dirty_parent(ZJNODE(coord->node), ++ &acoord, pos); ++ if (ret != 0) ++ goto exit; ++ ++ /* Recursive call. */ ++ if (!znode_check_flushprepped(acoord.node)) { ++ ret = alloc_one_ancestor(&acoord, pos); ++ if (ret) ++ goto exit; ++ } ++ } ++ ++ /* Note: we call allocate with the parent write-locked (except at the ++ root) in case we relocate the child, in which case it will modify the ++ parent during this call. */ ++ ret = allocate_znode(coord->node, &acoord, pos); ++ ++exit: ++ done_load_count(&aload); ++ done_lh(&alock); ++ return ret; ++} ++ ++/* During the reverse parent-first alloc_pos_and_ancestors process described ++ above there is a call to this function at the twig level. During ++ alloc_pos_and_ancestors we may ask: should this node be relocated (in reverse ++ parent-first context)? We repeat this process as long as the child is the ++ leftmost child, eventually reaching an ancestor of the flush point that is ++ not a leftmost child. The preceder of that ancestors, which is not a leftmost ++ child, is actually on the leaf level. The preceder of that block is the ++ left-neighbor of the flush point. The preceder of that block is the rightmost ++ child of the twig on the left. So, when alloc_pos_and_ancestors passes upward ++ through the twig level, it stops momentarily to remember the block of the ++ rightmost child of the twig on the left and sets it to the flush_position's ++ preceder_hint. ++ ++ There is one other place where we may set the flush_position's preceder hint, ++ which is during scan-left. ++*/ ++static int set_preceder(const coord_t *coord_in, flush_pos_t *pos) ++{ ++ int ret; ++ coord_t coord; ++ lock_handle left_lock; ++ load_count left_load; ++ ++ coord_dup(&coord, coord_in); ++ ++ init_lh(&left_lock); ++ init_load_count(&left_load); ++ ++ /* FIXME(B): Same FIXME as in "Find the preceder" in ++ reverse_relocate_test. coord_is_leftmost_unit is not the right test ++ if the unformatted child is in the middle of the first extent unit.*/ ++ if (!coord_is_leftmost_unit(&coord)) { ++ coord_prev_unit(&coord); ++ } else { ++ ret = ++ reiser4_get_left_neighbor(&left_lock, coord.node, ++ ZNODE_READ_LOCK, GN_SAME_ATOM); ++ if (ret) { ++ /* If we fail for any reason it doesn't matter because ++ the preceder is only a hint. We are low-priority at ++ this point, so this must be the case. */ ++ if (ret == -E_REPEAT || ret == -E_NO_NEIGHBOR || ++ ret == -ENOENT || ret == -EINVAL ++ || ret == -E_DEADLOCK) ++ ret = 0; ++ goto exit; ++ } ++ ++ ret = incr_load_count_znode(&left_load, left_lock.node); ++ if (ret) ++ goto exit; ++ ++ coord_init_last_unit(&coord, left_lock.node); ++ } ++ ++ ret = ++ item_utmost_child_real_block(&coord, RIGHT_SIDE, ++ &pos->preceder.blk); ++exit: ++ check_preceder(pos->preceder.blk); ++ done_load_count(&left_load); ++ done_lh(&left_lock); ++ return ret; ++} ++ ++/* MAIN SQUEEZE AND ALLOCATE LOOP (THREE BIG FUNCTIONS) */ ++ ++/* This procedure implements the outer loop of the flush algorithm. To put this ++ in context, here is the general list of steps taken by the flush routine as a ++ whole: ++ ++ 1. Scan-left ++ 2. Scan-right (maybe) ++ 3. Allocate initial flush position and its ancestors ++ 4. <handle extents> ++ 5. <squeeze and next position and its ancestors to-the-right, ++ then update position to-the-right> ++ 6. <repeat from #4 until flush is stopped> ++ ++ This procedure implements the loop in steps 4 through 6 in the above listing. ++ ++ Step 4: if the current flush position is an extent item (position on the twig ++ level), it allocates the extent (allocate_extent_item_in_place) then shifts ++ to the next coordinate. If the next coordinate's leftmost child needs ++ flushprep, we will continue. If the next coordinate is an internal item, we ++ descend back to the leaf level, otherwise we repeat a step #4 (labeled ++ ALLOC_EXTENTS below). If the "next coordinate" brings us past the end of the ++ twig level, then we call reverse_relocate_end_of_twig to possibly dirty the ++ next (right) twig, prior to step #5 which moves to the right. ++ ++ Step 5: calls squalloc_changed_ancestors, which initiates a recursive call up ++ the tree to allocate any ancestors of the next-right flush position that are ++ not also ancestors of the current position. Those ancestors (in top-down ++ order) are the next in parent-first order. We squeeze adjacent nodes on the ++ way up until the right node and current node share the same parent, then ++ allocate on the way back down. Finally, this step sets the flush position to ++ the next-right node. Then repeat steps 4 and 5. ++*/ ++ ++/* SQUEEZE CODE */ ++ ++/* squalloc_right_twig helper function, cut a range of extent items from ++ cut node to->node from the beginning up to coord @to. */ ++static int squalloc_right_twig_cut(coord_t *to, reiser4_key * to_key, ++ znode * left) ++{ ++ coord_t from; ++ reiser4_key from_key; ++ ++ coord_init_first_unit(&from, to->node); ++ item_key_by_coord(&from, &from_key); ++ ++ return cut_node_content(&from, to, &from_key, to_key, NULL); ++} ++ ++/* Copy as much of the leading extents from @right to @left, allocating ++ unallocated extents as they are copied. Returns SQUEEZE_TARGET_FULL or ++ SQUEEZE_SOURCE_EMPTY when no more can be shifted. If the next item is an ++ internal item it calls shift_one_internal_unit and may then return ++ SUBTREE_MOVED. */ ++static int squeeze_right_twig(znode * left, znode * right, flush_pos_t *pos) ++{ ++ int ret = SUBTREE_MOVED; ++ coord_t coord; /* used to iterate over items */ ++ reiser4_key stop_key; ++ ++ assert("jmacd-2008", !node_is_empty(right)); ++ coord_init_first_unit(&coord, right); ++ ++ /* FIXME: can be optimized to cut once */ ++ while (!node_is_empty(coord.node) && item_is_extent(&coord)) { ++ ON_DEBUG(void *vp); ++ ++ assert("vs-1468", coord_is_leftmost_unit(&coord)); ++ ON_DEBUG(vp = shift_check_prepare(left, coord.node)); ++ ++ /* stop_key is used to find what was copied and what to cut */ ++ stop_key = *reiser4_min_key(); ++ ret = squalloc_extent(left, &coord, pos, &stop_key); ++ if (ret != SQUEEZE_CONTINUE) { ++ ON_DEBUG(kfree(vp)); ++ break; ++ } ++ assert("vs-1465", !keyeq(&stop_key, reiser4_min_key())); ++ ++ /* Helper function to do the cutting. */ ++ set_key_offset(&stop_key, get_key_offset(&stop_key) - 1); ++ check_me("vs-1466", ++ squalloc_right_twig_cut(&coord, &stop_key, left) == 0); ++ ++ ON_DEBUG(shift_check(vp, left, coord.node)); ++ } ++ ++ if (node_is_empty(coord.node)) ++ ret = SQUEEZE_SOURCE_EMPTY; ++ ++ if (ret == SQUEEZE_TARGET_FULL) ++ goto out; ++ ++ if (node_is_empty(right)) { ++ /* The whole right node was copied into @left. */ ++ assert("vs-464", ret == SQUEEZE_SOURCE_EMPTY); ++ goto out; ++ } ++ ++ coord_init_first_unit(&coord, right); ++ ++ if (!item_is_internal(&coord)) { ++ /* we do not want to squeeze anything else to left neighbor ++ because "slum" is over */ ++ ret = SQUEEZE_TARGET_FULL; ++ goto out; ++ } ++ assert("jmacd-433", item_is_internal(&coord)); ++ ++ /* Shift an internal unit. The child must be allocated before shifting ++ any more extents, so we stop here. */ ++ ret = shift_one_internal_unit(left, right); ++ ++out: ++ assert("jmacd-8612", ret < 0 || ret == SQUEEZE_TARGET_FULL ++ || ret == SUBTREE_MOVED || ret == SQUEEZE_SOURCE_EMPTY); ++ ++ if (ret == SQUEEZE_TARGET_FULL) { ++ /* We submit prepped nodes here and expect that this @left twig ++ * will not be modified again during this jnode_flush() call. */ ++ int ret1; ++ ++ /* NOTE: seems like io is done under long term locks. */ ++ ret1 = write_prepped_nodes(pos); ++ if (ret1 < 0) ++ return ret1; ++ } ++ ++ return ret; ++} ++ ++#if REISER4_DEBUG ++static void item_convert_invariant(flush_pos_t *pos) ++{ ++ assert("edward-1225", coord_is_existing_item(&pos->coord)); ++ if (chaining_data_present(pos)) { ++ item_plugin *iplug = item_convert_plug(pos); ++ ++ assert("edward-1000", ++ iplug == item_plugin_by_coord(&pos->coord)); ++ assert("edward-1001", iplug->f.convert != NULL); ++ } else ++ assert("edward-1226", pos->child == NULL); ++} ++#else ++ ++#define item_convert_invariant(pos) noop ++ ++#endif ++ ++/* Scan node items starting from the first one and apply for each ++ item its flush ->convert() method (if any). This method may ++ resize/kill the item so the tree will be changed. ++*/ ++static int convert_node(flush_pos_t *pos, znode * node) ++{ ++ int ret = 0; ++ item_plugin *iplug; ++ ++ assert("edward-304", pos != NULL); ++ assert("edward-305", pos->child == NULL); ++ assert("edward-475", znode_convertible(node)); ++ assert("edward-669", znode_is_wlocked(node)); ++ assert("edward-1210", !node_is_empty(node)); ++ ++ if (znode_get_level(node) != LEAF_LEVEL) ++ /* unsupported */ ++ goto exit; ++ ++ coord_init_first_unit(&pos->coord, node); ++ ++ while (1) { ++ ret = 0; ++ coord_set_to_left(&pos->coord); ++ item_convert_invariant(pos); ++ ++ iplug = item_plugin_by_coord(&pos->coord); ++ assert("edward-844", iplug != NULL); ++ ++ if (iplug->f.convert) { ++ ret = iplug->f.convert(pos); ++ if (ret) ++ goto exit; ++ } ++ assert("edward-307", pos->child == NULL); ++ ++ if (coord_next_item(&pos->coord)) { ++ /* node is over */ ++ ++ if (!chaining_data_present(pos)) ++ /* finished this node */ ++ break; ++ if (should_chain_next_node(pos)) { ++ /* go to next node */ ++ move_chaining_data(pos, 0/* to next node */); ++ break; ++ } ++ /* repeat this node */ ++ move_chaining_data(pos, 1/* this node */); ++ continue; ++ } ++ /* Node is not over. ++ Check if there is attached convert data. ++ If so roll one item position back and repeat ++ on this node ++ */ ++ if (chaining_data_present(pos)) { ++ ++ if (iplug != item_plugin_by_coord(&pos->coord)) ++ set_item_convert_count(pos, 0); ++ ++ ret = coord_prev_item(&pos->coord); ++ assert("edward-1003", !ret); ++ ++ move_chaining_data(pos, 1/* this node */); ++ } ++ } ++ JF_CLR(ZJNODE(node), JNODE_CONVERTIBLE); ++ znode_make_dirty(node); ++exit: ++ assert("edward-1004", !ret); ++ return ret; ++} ++ ++/* Squeeze and allocate the right neighbor. This is called after @left and ++ its current children have been squeezed and allocated already. This ++ procedure's job is to squeeze and items from @right to @left. ++ ++ If at the leaf level, use the shift_everything_left memcpy-optimized ++ version of shifting (squeeze_right_leaf). ++ ++ If at the twig level, extents are allocated as they are shifted from @right ++ to @left (squalloc_right_twig). ++ ++ At any other level, shift one internal item and return to the caller ++ (squalloc_parent_first) so that the shifted-subtree can be processed in ++ parent-first order. ++ ++ When unit of internal item is moved, squeezing stops and SUBTREE_MOVED is ++ returned. When all content of @right is squeezed, SQUEEZE_SOURCE_EMPTY is ++ returned. If nothing can be moved into @left anymore, SQUEEZE_TARGET_FULL ++ is returned. ++*/ ++ ++static int squeeze_right_neighbor(flush_pos_t *pos, znode * left, ++ znode * right) ++{ ++ int ret; ++ ++ /* FIXME it is possible to see empty hasn't-heard-banshee node in a ++ * tree owing to error (for example, ENOSPC) in write */ ++ /* assert("jmacd-9321", !node_is_empty(left)); */ ++ assert("jmacd-9322", !node_is_empty(right)); ++ assert("jmacd-9323", znode_get_level(left) == znode_get_level(right)); ++ ++ switch (znode_get_level(left)) { ++ case TWIG_LEVEL: ++ /* Shift with extent allocating until either an internal item ++ is encountered or everything is shifted or no free space ++ left in @left */ ++ ret = squeeze_right_twig(left, right, pos); ++ break; ++ ++ default: ++ /* All other levels can use shift_everything until we implement ++ per-item flush plugins. */ ++ ret = squeeze_right_non_twig(left, right); ++ break; ++ } ++ ++ assert("jmacd-2011", (ret < 0 || ++ ret == SQUEEZE_SOURCE_EMPTY ++ || ret == SQUEEZE_TARGET_FULL ++ || ret == SUBTREE_MOVED)); ++ return ret; ++} ++ ++static int squeeze_right_twig_and_advance_coord(flush_pos_t *pos, ++ znode * right) ++{ ++ int ret; ++ ++ ret = squeeze_right_twig(pos->lock.node, right, pos); ++ if (ret < 0) ++ return ret; ++ if (ret > 0) { ++ coord_init_after_last_item(&pos->coord, pos->lock.node); ++ return ret; ++ } ++ ++ coord_init_last_unit(&pos->coord, pos->lock.node); ++ return 0; ++} ++ ++/* forward declaration */ ++static int squalloc_upper_levels(flush_pos_t *, znode *, znode *); ++ ++/* do a fast check for "same parents" condition before calling ++ * squalloc_upper_levels() */ ++static inline int check_parents_and_squalloc_upper_levels(flush_pos_t *pos, ++ znode * left, ++ znode * right) ++{ ++ if (znode_same_parents(left, right)) ++ return 0; ++ ++ return squalloc_upper_levels(pos, left, right); ++} ++ ++/* Check whether the parent of given @right node needs to be processes ++ ((re)allocated) prior to processing of the child. If @left and @right do not ++ share at least the parent of the @right is after the @left but before the ++ @right in parent-first order, we have to (re)allocate it before the @right ++ gets (re)allocated. */ ++static int squalloc_upper_levels(flush_pos_t *pos, znode * left, znode * right) ++{ ++ int ret; ++ ++ lock_handle left_parent_lock; ++ lock_handle right_parent_lock; ++ ++ load_count left_parent_load; ++ load_count right_parent_load; ++ ++ init_lh(&left_parent_lock); ++ init_lh(&right_parent_lock); ++ ++ init_load_count(&left_parent_load); ++ init_load_count(&right_parent_load); ++ ++ ret = reiser4_get_parent(&left_parent_lock, left, ZNODE_WRITE_LOCK); ++ if (ret) ++ goto out; ++ ++ ret = reiser4_get_parent(&right_parent_lock, right, ZNODE_WRITE_LOCK); ++ if (ret) ++ goto out; ++ ++ /* Check for same parents */ ++ if (left_parent_lock.node == right_parent_lock.node) ++ goto out; ++ ++ if (znode_check_flushprepped(right_parent_lock.node)) { ++ /* Keep parent-first order. In the order, the right parent node ++ stands before the @right node. If it is already allocated, ++ we set the preceder (next block search start point) to its ++ block number, @right node should be allocated after it. ++ ++ However, preceder is set only if the right parent is on twig ++ level. The explanation is the following: new branch nodes are ++ allocated over already allocated children while the tree ++ grows, it is difficult to keep tree ordered, we assume that ++ only leaves and twings are correctly allocated. So, only ++ twigs are used as a preceder for allocating of the rest of ++ the slum. */ ++ if (znode_get_level(right_parent_lock.node) == TWIG_LEVEL) { ++ pos->preceder.blk = ++ *znode_get_block(right_parent_lock.node); ++ check_preceder(pos->preceder.blk); ++ } ++ goto out; ++ } ++ ++ ret = incr_load_count_znode(&left_parent_load, left_parent_lock.node); ++ if (ret) ++ goto out; ++ ++ ret = incr_load_count_znode(&right_parent_load, right_parent_lock.node); ++ if (ret) ++ goto out; ++ ++ ret = ++ squeeze_right_neighbor(pos, left_parent_lock.node, ++ right_parent_lock.node); ++ /* We stop if error. We stop if some items/units were shifted (ret == 0) ++ * and thus @right changed its parent. It means we have not process ++ * right_parent node prior to processing of @right. Positive return ++ * values say that shifting items was not happen because of "empty ++ * source" or "target full" conditions. */ ++ if (ret <= 0) ++ goto out; ++ ++ /* parent(@left) and parent(@right) may have different parents also. We ++ * do a recursive call for checking that. */ ++ ret = ++ check_parents_and_squalloc_upper_levels(pos, left_parent_lock.node, ++ right_parent_lock.node); ++ if (ret) ++ goto out; ++ ++ /* allocate znode when going down */ ++ ret = lock_parent_and_allocate_znode(right_parent_lock.node, pos); ++ ++out: ++ done_load_count(&left_parent_load); ++ done_load_count(&right_parent_load); ++ ++ done_lh(&left_parent_lock); ++ done_lh(&right_parent_lock); ++ ++ return ret; ++} ++ ++/* Check the leftmost child "flushprepped" status, also returns true if child ++ * node was not found in cache. */ ++static int leftmost_child_of_unit_check_flushprepped(const coord_t *coord) ++{ ++ int ret; ++ int prepped; ++ ++ jnode *child; ++ ++ ret = get_leftmost_child_of_unit(coord, &child); ++ ++ if (ret) ++ return ret; ++ ++ if (child) { ++ prepped = jnode_check_flushprepped(child); ++ jput(child); ++ } else { ++ /* We consider not existing child as a node which slum ++ processing should not continue to. Not cached node is clean, ++ so it is flushprepped. */ ++ prepped = 1; ++ } ++ ++ return prepped; ++} ++ ++/* (re)allocate znode with automated getting parent node */ ++static int lock_parent_and_allocate_znode(znode * node, flush_pos_t *pos) ++{ ++ int ret; ++ lock_handle parent_lock; ++ load_count parent_load; ++ coord_t pcoord; ++ ++ assert("zam-851", znode_is_write_locked(node)); ++ ++ init_lh(&parent_lock); ++ init_load_count(&parent_load); ++ ++ ret = reiser4_get_parent(&parent_lock, node, ZNODE_WRITE_LOCK); ++ if (ret) ++ goto out; ++ ++ ret = incr_load_count_znode(&parent_load, parent_lock.node); ++ if (ret) ++ goto out; ++ ++ ret = find_child_ptr(parent_lock.node, node, &pcoord); ++ if (ret) ++ goto out; ++ ++ ret = allocate_znode(node, &pcoord, pos); ++ ++out: ++ done_load_count(&parent_load); ++ done_lh(&parent_lock); ++ return ret; ++} ++ ++/* Process nodes on leaf level until unformatted node or rightmost node in the ++ * slum reached. */ ++static int handle_pos_on_formatted(flush_pos_t *pos) ++{ ++ int ret; ++ lock_handle right_lock; ++ load_count right_load; ++ ++ init_lh(&right_lock); ++ init_load_count(&right_load); ++ ++ if (should_convert_node(pos, pos->lock.node)) { ++ ret = convert_node(pos, pos->lock.node); ++ if (ret) ++ return ret; ++ } ++ ++ while (1) { ++ int expected; ++ expected = should_convert_next_node(pos); ++ ret = neighbor_in_slum(pos->lock.node, &right_lock, RIGHT_SIDE, ++ ZNODE_WRITE_LOCK, !expected, expected); ++ if (ret) { ++ if (expected) ++ warning("edward-1495", ++ "Expected neighbor not found (ret = %d). Fsck?", ++ ret); ++ break; ++ } ++ ++ /* we don't prep(allocate) nodes for flushing twice. This can be ++ * suboptimal, or it can be optimal. For now we choose to live ++ * with the risk that it will be suboptimal because it would be ++ * quite complex to code it to be smarter. */ ++ if (znode_check_flushprepped(right_lock.node) ++ && !znode_convertible(right_lock.node)) { ++ assert("edward-1005", !should_convert_next_node(pos)); ++ pos_stop(pos); ++ break; ++ } ++ ++ ret = incr_load_count_znode(&right_load, right_lock.node); ++ if (ret) ++ break; ++ if (should_convert_node(pos, right_lock.node)) { ++ ret = convert_node(pos, right_lock.node); ++ if (ret) ++ break; ++ if (node_is_empty(right_lock.node)) { ++ /* node became empty after converting, repeat */ ++ done_load_count(&right_load); ++ done_lh(&right_lock); ++ continue; ++ } ++ } ++ ++ /* squeeze _before_ going upward. */ ++ ret = ++ squeeze_right_neighbor(pos, pos->lock.node, ++ right_lock.node); ++ if (ret < 0) ++ break; ++ ++ if (znode_check_flushprepped(right_lock.node)) { ++ if (should_convert_next_node(pos)) { ++ /* in spite of flushprepped status of the node, ++ its right slum neighbor should be converted*/ ++ assert("edward-953", convert_data(pos)); ++ assert("edward-954", item_convert_data(pos)); ++ ++ if (node_is_empty(right_lock.node)) { ++ done_load_count(&right_load); ++ done_lh(&right_lock); ++ } else ++ move_flush_pos(pos, &right_lock, ++ &right_load, NULL); ++ continue; ++ } ++ pos_stop(pos); ++ break; ++ } ++ ++ if (node_is_empty(right_lock.node)) { ++ /* repeat if right node was squeezed completely */ ++ done_load_count(&right_load); ++ done_lh(&right_lock); ++ continue; ++ } ++ ++ /* parent(right_lock.node) has to be processed before ++ * (right_lock.node) due to "parent-first" allocation order. */ ++ ret = ++ check_parents_and_squalloc_upper_levels(pos, pos->lock.node, ++ right_lock.node); ++ if (ret) ++ break; ++ /* (re)allocate _after_ going upward */ ++ ret = lock_parent_and_allocate_znode(right_lock.node, pos); ++ if (ret) ++ break; ++ if (should_terminate_squalloc(pos)) { ++ set_item_convert_count(pos, 0); ++ break; ++ } ++ ++ /* advance the flush position to the right neighbor */ ++ move_flush_pos(pos, &right_lock, &right_load, NULL); ++ ++ ret = rapid_flush(pos); ++ if (ret) ++ break; ++ } ++ check_convert_info(pos); ++ done_load_count(&right_load); ++ done_lh(&right_lock); ++ ++ /* This function indicates via pos whether to stop or go to twig or ++ * continue on current level. */ ++ return ret; ++ ++} ++ ++/* Process nodes on leaf level until unformatted node or rightmost node in the ++ * slum reached. */ ++static int handle_pos_on_leaf(flush_pos_t *pos) ++{ ++ int ret; ++ ++ assert("zam-845", pos->state == POS_ON_LEAF); ++ ++ ret = handle_pos_on_formatted(pos); ++ ++ if (ret == -E_NO_NEIGHBOR) { ++ /* cannot get right neighbor, go process extents. */ ++ pos->state = POS_TO_TWIG; ++ return 0; ++ } ++ ++ return ret; ++} ++ ++/* Process slum on level > 1 */ ++static int handle_pos_on_internal(flush_pos_t *pos) ++{ ++ assert("zam-850", pos->state == POS_ON_INTERNAL); ++ return handle_pos_on_formatted(pos); ++} ++ ++/* check whether squalloc should stop before processing given extent */ ++static int squalloc_extent_should_stop(flush_pos_t *pos) ++{ ++ assert("zam-869", item_is_extent(&pos->coord)); ++ ++ /* pos->child is a jnode handle_pos_on_extent() should start with in ++ * stead of the first child of the first extent unit. */ ++ if (pos->child) { ++ int prepped; ++ ++ assert("vs-1383", jnode_is_unformatted(pos->child)); ++ prepped = jnode_check_flushprepped(pos->child); ++ pos->pos_in_unit = ++ jnode_get_index(pos->child) - ++ extent_unit_index(&pos->coord); ++ assert("vs-1470", ++ pos->pos_in_unit < extent_unit_width(&pos->coord)); ++ assert("nikita-3434", ++ ergo(extent_is_unallocated(&pos->coord), ++ pos->pos_in_unit == 0)); ++ jput(pos->child); ++ pos->child = NULL; ++ ++ return prepped; ++ } ++ ++ pos->pos_in_unit = 0; ++ if (extent_is_unallocated(&pos->coord)) ++ return 0; ++ ++ return leftmost_child_of_unit_check_flushprepped(&pos->coord); ++} ++ ++/* Handle the case when regular reiser4 tree (znodes connected one to its ++ * neighbors by sibling pointers) is interrupted on leaf level by one or more ++ * unformatted nodes. By having a lock on twig level and use extent code ++ * routines to process unformatted nodes we swim around an irregular part of ++ * reiser4 tree. */ ++static int handle_pos_on_twig(flush_pos_t *pos) ++{ ++ int ret; ++ ++ assert("zam-844", pos->state == POS_ON_EPOINT); ++ assert("zam-843", item_is_extent(&pos->coord)); ++ ++ /* We decide should we continue slum processing with current extent ++ unit: if leftmost child of current extent unit is flushprepped ++ (i.e. clean or already processed by flush) we stop squalloc(). There ++ is a fast check for unallocated extents which we assume contain all ++ not flushprepped nodes. */ ++ /* FIXME: Here we implement simple check, we are only looking on the ++ leftmost child. */ ++ ret = squalloc_extent_should_stop(pos); ++ if (ret != 0) { ++ pos_stop(pos); ++ return ret; ++ } ++ ++ while (pos_valid(pos) && coord_is_existing_unit(&pos->coord) ++ && item_is_extent(&pos->coord)) { ++ ret = reiser4_alloc_extent(pos); ++ if (ret) ++ break; ++ coord_next_unit(&pos->coord); ++ } ++ ++ if (coord_is_after_rightmost(&pos->coord)) { ++ pos->state = POS_END_OF_TWIG; ++ return 0; ++ } ++ if (item_is_internal(&pos->coord)) { ++ pos->state = POS_TO_LEAF; ++ return 0; ++ } ++ ++ assert("zam-860", item_is_extent(&pos->coord)); ++ ++ /* "slum" is over */ ++ pos->state = POS_INVALID; ++ return 0; ++} ++ ++/* When we about to return flush position from twig to leaf level we can process ++ * the right twig node or move position to the leaf. This processes right twig ++ * if it is possible and jump to leaf level if not. */ ++static int handle_pos_end_of_twig(flush_pos_t *pos) ++{ ++ int ret; ++ lock_handle right_lock; ++ load_count right_load; ++ coord_t at_right; ++ jnode *child = NULL; ++ ++ assert("zam-848", pos->state == POS_END_OF_TWIG); ++ assert("zam-849", coord_is_after_rightmost(&pos->coord)); ++ ++ init_lh(&right_lock); ++ init_load_count(&right_load); ++ ++ /* We get a lock on the right twig node even it is not dirty because ++ * slum continues or discontinues on leaf level not on next twig. This ++ * lock on the right twig is needed for getting its leftmost child. */ ++ ret = ++ reiser4_get_right_neighbor(&right_lock, pos->lock.node, ++ ZNODE_WRITE_LOCK, GN_SAME_ATOM); ++ if (ret) ++ goto out; ++ ++ ret = incr_load_count_znode(&right_load, right_lock.node); ++ if (ret) ++ goto out; ++ ++ /* right twig could be not dirty */ ++ if (JF_ISSET(ZJNODE(right_lock.node), JNODE_DIRTY)) { ++ /* If right twig node is dirty we always attempt to squeeze it ++ * content to the left... */ ++became_dirty: ++ ret = ++ squeeze_right_twig_and_advance_coord(pos, right_lock.node); ++ if (ret <= 0) { ++ /* pos->coord is on internal item, go to leaf level, or ++ * we have an error which will be caught in squalloc() ++ */ ++ pos->state = POS_TO_LEAF; ++ goto out; ++ } ++ ++ /* If right twig was squeezed completely we wave to re-lock ++ * right twig. now it is done through the top-level squalloc ++ * routine. */ ++ if (node_is_empty(right_lock.node)) ++ goto out; ++ ++ /* ... and prep it if it is not yet prepped */ ++ if (!znode_check_flushprepped(right_lock.node)) { ++ /* As usual, process parent before ... */ ++ ret = ++ check_parents_and_squalloc_upper_levels(pos, ++ pos->lock. ++ node, ++ right_lock. ++ node); ++ if (ret) ++ goto out; ++ ++ /* ... processing the child */ ++ ret = ++ lock_parent_and_allocate_znode(right_lock.node, ++ pos); ++ if (ret) ++ goto out; ++ } ++ } else { ++ coord_init_first_unit(&at_right, right_lock.node); ++ ++ /* check first child of next twig, should we continue there ? */ ++ ret = get_leftmost_child_of_unit(&at_right, &child); ++ if (ret || child == NULL || jnode_check_flushprepped(child)) { ++ pos_stop(pos); ++ goto out; ++ } ++ ++ /* check clean twig for possible relocation */ ++ if (!znode_check_flushprepped(right_lock.node)) { ++ ret = ++ reverse_relocate_check_dirty_parent(child, ++ &at_right, pos); ++ if (ret) ++ goto out; ++ if (JF_ISSET(ZJNODE(right_lock.node), JNODE_DIRTY)) ++ goto became_dirty; ++ } ++ } ++ ++ assert("zam-875", znode_check_flushprepped(right_lock.node)); ++ ++ /* Update the preceder by a block number of just processed right twig ++ * node. The code above could miss the preceder updating because ++ * allocate_znode() could not be called for this node. */ ++ pos->preceder.blk = *znode_get_block(right_lock.node); ++ check_preceder(pos->preceder.blk); ++ ++ coord_init_first_unit(&at_right, right_lock.node); ++ assert("zam-868", coord_is_existing_unit(&at_right)); ++ ++ pos->state = item_is_extent(&at_right) ? POS_ON_EPOINT : POS_TO_LEAF; ++ move_flush_pos(pos, &right_lock, &right_load, &at_right); ++ ++out: ++ done_load_count(&right_load); ++ done_lh(&right_lock); ++ ++ if (child) ++ jput(child); ++ ++ return ret; ++} ++ ++/* Move the pos->lock to leaf node pointed by pos->coord, check should we ++ * continue there. */ ++static int handle_pos_to_leaf(flush_pos_t *pos) ++{ ++ int ret; ++ lock_handle child_lock; ++ load_count child_load; ++ jnode *child; ++ ++ assert("zam-846", pos->state == POS_TO_LEAF); ++ assert("zam-847", item_is_internal(&pos->coord)); ++ ++ init_lh(&child_lock); ++ init_load_count(&child_load); ++ ++ ret = get_leftmost_child_of_unit(&pos->coord, &child); ++ if (ret) ++ return ret; ++ if (child == NULL) { ++ pos_stop(pos); ++ return 0; ++ } ++ ++ if (jnode_check_flushprepped(child)) { ++ pos->state = POS_INVALID; ++ goto out; ++ } ++ ++ ret = ++ longterm_lock_znode(&child_lock, JZNODE(child), ZNODE_WRITE_LOCK, ++ ZNODE_LOCK_LOPRI); ++ if (ret) ++ goto out; ++ ++ ret = incr_load_count_znode(&child_load, JZNODE(child)); ++ if (ret) ++ goto out; ++ ++ ret = allocate_znode(JZNODE(child), &pos->coord, pos); ++ if (ret) ++ goto out; ++ ++ /* move flush position to leaf level */ ++ pos->state = POS_ON_LEAF; ++ move_flush_pos(pos, &child_lock, &child_load, NULL); ++ ++ if (node_is_empty(JZNODE(child))) { ++ ret = delete_empty_node(JZNODE(child)); ++ pos->state = POS_INVALID; ++ } ++out: ++ done_load_count(&child_load); ++ done_lh(&child_lock); ++ jput(child); ++ ++ return ret; ++} ++ ++/* move pos from leaf to twig, and move lock from leaf to twig. */ ++/* Move pos->lock to upper (twig) level */ ++static int handle_pos_to_twig(flush_pos_t *pos) ++{ ++ int ret; ++ ++ lock_handle parent_lock; ++ load_count parent_load; ++ coord_t pcoord; ++ ++ assert("zam-852", pos->state == POS_TO_TWIG); ++ ++ init_lh(&parent_lock); ++ init_load_count(&parent_load); ++ ++ ret = ++ reiser4_get_parent(&parent_lock, pos->lock.node, ZNODE_WRITE_LOCK); ++ if (ret) ++ goto out; ++ ++ ret = incr_load_count_znode(&parent_load, parent_lock.node); ++ if (ret) ++ goto out; ++ ++ ret = find_child_ptr(parent_lock.node, pos->lock.node, &pcoord); ++ if (ret) ++ goto out; ++ ++ assert("zam-870", item_is_internal(&pcoord)); ++ coord_next_item(&pcoord); ++ ++ if (coord_is_after_rightmost(&pcoord)) ++ pos->state = POS_END_OF_TWIG; ++ else if (item_is_extent(&pcoord)) ++ pos->state = POS_ON_EPOINT; ++ else { ++ /* Here we understand that getting -E_NO_NEIGHBOR in ++ * handle_pos_on_leaf() was because of just a reaching edge of ++ * slum */ ++ pos_stop(pos); ++ goto out; ++ } ++ ++ move_flush_pos(pos, &parent_lock, &parent_load, &pcoord); ++ ++out: ++ done_load_count(&parent_load); ++ done_lh(&parent_lock); ++ ++ return ret; ++} ++ ++typedef int (*pos_state_handle_t) (flush_pos_t *); ++static pos_state_handle_t flush_pos_handlers[] = { ++ /* process formatted nodes on leaf level, keep lock on a leaf node */ ++ [POS_ON_LEAF] = handle_pos_on_leaf, ++ /* process unformatted nodes, keep lock on twig node, pos->coord points ++ * to extent currently being processed */ ++ [POS_ON_EPOINT] = handle_pos_on_twig, ++ /* move a lock from leaf node to its parent for further processing of ++ unformatted nodes */ ++ [POS_TO_TWIG] = handle_pos_to_twig, ++ /* move a lock from twig to leaf level when a processing of unformatted ++ * nodes finishes, pos->coord points to the leaf node we jump to */ ++ [POS_TO_LEAF] = handle_pos_to_leaf, ++ /* after processing last extent in the twig node, attempting to shift ++ * items from the twigs right neighbor and process them while shifting*/ ++ [POS_END_OF_TWIG] = handle_pos_end_of_twig, ++ /* process formatted nodes on internal level, keep lock on an internal ++ node */ ++ [POS_ON_INTERNAL] = handle_pos_on_internal ++}; ++ ++/* Advance flush position horizontally, prepare for flushing ((re)allocate, ++ * squeeze, encrypt) nodes and their ancestors in "parent-first" order */ ++static int squalloc(flush_pos_t *pos) ++{ ++ int ret = 0; ++ ++ /* maybe needs to be made a case statement with handle_pos_on_leaf as ++ * first case, for greater CPU efficiency? Measure and see.... -Hans */ ++ while (pos_valid(pos)) { ++ ret = flush_pos_handlers[pos->state] (pos); ++ if (ret < 0) ++ break; ++ ++ ret = rapid_flush(pos); ++ if (ret) ++ break; ++ } ++ ++ /* any positive value or -E_NO_NEIGHBOR are legal return codes for ++ handle_pos* routines, -E_NO_NEIGHBOR means that slum edge was ++ reached */ ++ if (ret > 0 || ret == -E_NO_NEIGHBOR) ++ ret = 0; ++ ++ return ret; ++} ++ ++static void update_ldkey(znode * node) ++{ ++ reiser4_key ldkey; ++ ++ assert_rw_write_locked(&(znode_get_tree(node)->dk_lock)); ++ if (node_is_empty(node)) ++ return; ++ ++ znode_set_ld_key(node, leftmost_key_in_node(node, &ldkey)); ++} ++ ++/* this is to be called after calling of shift node's method to shift data from ++ @right to @left. It sets left delimiting keys of @left and @right to keys of ++ first items of @left and @right correspondingly and sets right delimiting key ++ of @left to first key of @right */ ++static void update_znode_dkeys(znode * left, znode * right) ++{ ++ assert_rw_write_locked(&(znode_get_tree(right)->dk_lock)); ++ assert("vs-1629", (znode_is_write_locked(left) && ++ znode_is_write_locked(right))); ++ ++ /* we need to update left delimiting of left if it was empty before ++ shift */ ++ update_ldkey(left); ++ update_ldkey(right); ++ if (node_is_empty(right)) ++ znode_set_rd_key(left, znode_get_rd_key(right)); ++ else ++ znode_set_rd_key(left, znode_get_ld_key(right)); ++} ++ ++/* try to shift everything from @right to @left. If everything was shifted - ++ @right is removed from the tree. Result is the number of bytes shifted. */ ++static int ++shift_everything_left(znode * right, znode * left, carry_level * todo) ++{ ++ coord_t from; ++ node_plugin *nplug; ++ carry_plugin_info info; ++ ++ coord_init_after_last_item(&from, right); ++ ++ nplug = node_plugin_by_node(right); ++ info.doing = NULL; ++ info.todo = todo; ++ return nplug->shift(&from, left, SHIFT_LEFT, ++ 1 /* delete @right if it becomes empty */ , ++ 1 ++ /* move coord @from to node @left if everything will ++ be shifted */ ++ , ++ &info); ++} ++ ++/* Shift as much as possible from @right to @left using the memcpy-optimized ++ shift_everything_left. @left and @right are formatted neighboring nodes on ++ leaf level. */ ++static int squeeze_right_non_twig(znode * left, znode * right) ++{ ++ int ret; ++ carry_pool *pool; ++ carry_level *todo; ++ ++ assert("nikita-2246", znode_get_level(left) == znode_get_level(right)); ++ ++ if (!JF_ISSET(ZJNODE(left), JNODE_DIRTY) || ++ !JF_ISSET(ZJNODE(right), JNODE_DIRTY)) ++ return SQUEEZE_TARGET_FULL; ++ ++ pool = init_carry_pool(sizeof(*pool) + 3 * sizeof(*todo)); ++ if (IS_ERR(pool)) ++ return PTR_ERR(pool); ++ todo = (carry_level *) (pool + 1); ++ init_carry_level(todo, pool); ++ ++ ret = shift_everything_left(right, left, todo); ++ if (ret > 0) { ++ /* something was shifted */ ++ reiser4_tree *tree; ++ __u64 grabbed; ++ ++ znode_make_dirty(left); ++ znode_make_dirty(right); ++ ++ /* update delimiting keys of nodes which participated in ++ shift. FIXME: it would be better to have this in shift ++ node's operation. But it can not be done there. Nobody ++ remembers why, though */ ++ tree = znode_get_tree(left); ++ write_lock_dk(tree); ++ update_znode_dkeys(left, right); ++ write_unlock_dk(tree); ++ ++ /* Carry is called to update delimiting key and, maybe, to ++ remove empty node. */ ++ grabbed = get_current_context()->grabbed_blocks; ++ ret = reiser4_grab_space_force(tree->height, BA_RESERVED); ++ assert("nikita-3003", ret == 0); /* reserved space is ++ exhausted. Ask Hans. */ ++ ret = reiser4_carry(todo, NULL/* previous level */); ++ grabbed2free_mark(grabbed); ++ } else { ++ /* Shifting impossible, we return appropriate result code */ ++ ret = ++ node_is_empty(right) ? SQUEEZE_SOURCE_EMPTY : ++ SQUEEZE_TARGET_FULL; ++ } ++ ++ done_carry_pool(pool); ++ ++ return ret; ++} ++ ++#if REISER4_DEBUG ++static int sibling_link_is_ok(const znode *left, const znode *right) ++{ ++ int result; ++ ++ read_lock_tree(znode_get_tree(left)); ++ result = (left->right == right && left == right->left); ++ read_unlock_tree(znode_get_tree(left)); ++ return result; ++} ++#endif ++ ++/* Shift first unit of first item if it is an internal one. Return ++ SQUEEZE_TARGET_FULL if it fails to shift an item, otherwise return ++ SUBTREE_MOVED. */ ++static int shift_one_internal_unit(znode * left, znode * right) ++{ ++ int ret; ++ carry_pool *pool; ++ carry_level *todo; ++ coord_t *coord; ++ carry_plugin_info *info; ++ int size, moved; ++ ++ assert("nikita-2247", znode_get_level(left) == znode_get_level(right)); ++ assert("nikita-2435", znode_is_write_locked(left)); ++ assert("nikita-2436", znode_is_write_locked(right)); ++ assert("nikita-2434", sibling_link_is_ok(left, right)); ++ ++ pool = init_carry_pool(sizeof(*pool) + 3 * sizeof(*todo) + ++ sizeof(*coord) + sizeof(*info) ++#if REISER4_DEBUG ++ + sizeof(*coord) + 2 * sizeof(reiser4_key) ++#endif ++ ); ++ if (IS_ERR(pool)) ++ return PTR_ERR(pool); ++ todo = (carry_level *) (pool + 1); ++ init_carry_level(todo, pool); ++ ++ coord = (coord_t *) (todo + 3); ++ coord_init_first_unit(coord, right); ++ info = (carry_plugin_info *) (coord + 1); ++ ++#if REISER4_DEBUG ++ if (!node_is_empty(left)) { ++ coord_t *last; ++ reiser4_key *right_key; ++ reiser4_key *left_key; ++ ++ last = (coord_t *) (info + 1); ++ right_key = (reiser4_key *) (last + 1); ++ left_key = right_key + 1; ++ coord_init_last_unit(last, left); ++ ++ assert("nikita-2463", ++ keyle(item_key_by_coord(last, left_key), ++ item_key_by_coord(coord, right_key))); ++ } ++#endif ++ ++ assert("jmacd-2007", item_is_internal(coord)); ++ ++ size = item_length_by_coord(coord); ++ info->todo = todo; ++ info->doing = NULL; ++ ++ ret = node_plugin_by_node(left)->shift(coord, left, SHIFT_LEFT, ++ 1 ++ /* delete @right if it becomes ++ empty */ ++ , ++ 0 ++ /* do not move coord @coord to ++ node @left */ ++ , ++ info); ++ ++ /* If shift returns positive, then we shifted the item. */ ++ assert("vs-423", ret <= 0 || size == ret); ++ moved = (ret > 0); ++ ++ if (moved) { ++ /* something was moved */ ++ reiser4_tree *tree; ++ int grabbed; ++ ++ znode_make_dirty(left); ++ znode_make_dirty(right); ++ tree = znode_get_tree(left); ++ write_lock_dk(tree); ++ update_znode_dkeys(left, right); ++ write_unlock_dk(tree); ++ ++ /* reserve space for delimiting keys after shifting */ ++ grabbed = get_current_context()->grabbed_blocks; ++ ret = reiser4_grab_space_force(tree->height, BA_RESERVED); ++ assert("nikita-3003", ret == 0); /* reserved space is ++ exhausted. Ask Hans. */ ++ ++ ret = reiser4_carry(todo, NULL/* previous level */); ++ grabbed2free_mark(grabbed); ++ } ++ ++ done_carry_pool(pool); ++ ++ if (ret != 0) { ++ /* Shift or carry operation failed. */ ++ assert("jmacd-7325", ret < 0); ++ return ret; ++ } ++ ++ return moved ? SUBTREE_MOVED : SQUEEZE_TARGET_FULL; ++} ++ ++/* Make the final relocate/wander decision during forward parent-first squalloc ++ for a znode. For unformatted nodes this is done in ++ plugin/item/extent.c:extent_needs_allocation(). */ ++static int ++allocate_znode_loaded(znode * node, ++ const coord_t *parent_coord, flush_pos_t *pos) ++{ ++ int ret; ++ reiser4_super_info_data *sbinfo = get_current_super_private(); ++ /* FIXME(D): We have the node write-locked and should have checked for ! ++ allocated() somewhere before reaching this point, but there can be a ++ race, so this assertion is bogus. */ ++ assert("jmacd-7987", !jnode_check_flushprepped(ZJNODE(node))); ++ assert("jmacd-7988", znode_is_write_locked(node)); ++ assert("jmacd-7989", coord_is_invalid(parent_coord) ++ || znode_is_write_locked(parent_coord->node)); ++ ++ if (ZF_ISSET(node, JNODE_REPACK) || ZF_ISSET(node, JNODE_CREATED) || ++ znode_is_root(node) || ++ /* We have enough nodes to relocate no matter what. */ ++ (pos->leaf_relocate != 0 && znode_get_level(node) == LEAF_LEVEL)) { ++ /* No need to decide with new nodes, they are treated the same ++ as relocate. If the root node is dirty, relocate. */ ++ if (pos->preceder.blk == 0) { ++ /* preceder is unknown and we have decided to relocate ++ node -- using of default value for search start is ++ better than search from block #0. */ ++ get_blocknr_hint_default(&pos->preceder.blk); ++ check_preceder(pos->preceder.blk); ++ } ++ ++ goto best_reloc; ++ ++ } else if (pos->preceder.blk == 0) { ++ /* If we don't know the preceder, leave it where it is. */ ++ jnode_make_wander(ZJNODE(node)); ++ } else { ++ /* Make a decision based on block distance. */ ++ reiser4_block_nr dist; ++ reiser4_block_nr nblk = *znode_get_block(node); ++ ++ assert("jmacd-6172", !reiser4_blocknr_is_fake(&nblk)); ++ assert("jmacd-6173", !reiser4_blocknr_is_fake(&pos->preceder.blk)); ++ assert("jmacd-6174", pos->preceder.blk != 0); ++ ++ if (pos->preceder.blk == nblk - 1) { ++ /* Ideal. */ ++ jnode_make_wander(ZJNODE(node)); ++ } else { ++ ++ dist = ++ (nblk < ++ pos->preceder.blk) ? (pos->preceder.blk - ++ nblk) : (nblk - ++ pos->preceder.blk); ++ ++ /* See if we can find a closer block ++ (forward direction only). */ ++ pos->preceder.max_dist = ++ min((reiser4_block_nr) sbinfo->flush. ++ relocate_distance, dist); ++ pos->preceder.level = znode_get_level(node); ++ ++ ret = allocate_znode_update(node, parent_coord, pos); ++ ++ pos->preceder.max_dist = 0; ++ ++ if (ret && (ret != -ENOSPC)) ++ return ret; ++ ++ if (ret == 0) { ++ /* Got a better allocation. */ ++ znode_make_reloc(node, pos->fq); ++ } else if (dist < sbinfo->flush.relocate_distance) { ++ /* The present allocation is good enough. */ ++ jnode_make_wander(ZJNODE(node)); ++ } else { ++ /* Otherwise, try to relocate to the best ++ position. */ ++best_reloc: ++ ret = ++ allocate_znode_update(node, parent_coord, ++ pos); ++ if (ret != 0) ++ return ret; ++ ++ /* set JNODE_RELOC bit _after_ node gets ++ allocated */ ++ znode_make_reloc(node, pos->fq); ++ } ++ } ++ } ++ ++ /* This is the new preceder. */ ++ pos->preceder.blk = *znode_get_block(node); ++ check_preceder(pos->preceder.blk); ++ pos->alloc_cnt += 1; ++ ++ assert("jmacd-4277", !reiser4_blocknr_is_fake(&pos->preceder.blk)); ++ ++ return 0; ++} ++ ++static int ++allocate_znode(znode * node, const coord_t *parent_coord, flush_pos_t *pos) ++{ ++ /* ++ * perform znode allocation with znode pinned in memory to avoid races ++ * with asynchronous emergency flush (which plays with ++ * JNODE_FLUSH_RESERVED bit). ++ */ ++ return WITH_DATA(node, allocate_znode_loaded(node, parent_coord, pos)); ++} ++ ++/* A subroutine of allocate_znode, this is called first to see if there is a ++ close position to relocate to. It may return ENOSPC if there is no close ++ position. If there is no close position it may not relocate. This takes care ++ of updating the parent node with the relocated block address. */ ++static int ++allocate_znode_update(znode * node, const coord_t *parent_coord, ++ flush_pos_t *pos) ++{ ++ int ret; ++ reiser4_block_nr blk; ++ lock_handle uber_lock; ++ int flush_reserved_used = 0; ++ int grabbed; ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ init_lh(&uber_lock); ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ grabbed = ctx->grabbed_blocks; ++ ++ /* discard e-flush allocation */ ++ ret = zload(node); ++ if (ret) ++ return ret; ++ ++ if (ZF_ISSET(node, JNODE_CREATED)) { ++ assert("zam-816", reiser4_blocknr_is_fake(znode_get_block(node))); ++ pos->preceder.block_stage = BLOCK_UNALLOCATED; ++ } else { ++ pos->preceder.block_stage = BLOCK_GRABBED; ++ ++ /* The disk space for relocating the @node is already reserved ++ * in "flush reserved" counter if @node is leaf, otherwise we ++ * grab space using BA_RESERVED (means grab space from whole ++ * disk not from only 95%). */ ++ if (znode_get_level(node) == LEAF_LEVEL) { ++ /* ++ * earlier (during do_jnode_make_dirty()) we decided ++ * that @node can possibly go into overwrite set and ++ * reserved block for its wandering location. ++ */ ++ txn_atom *atom = get_current_atom_locked(); ++ assert("nikita-3449", ++ ZF_ISSET(node, JNODE_FLUSH_RESERVED)); ++ flush_reserved2grabbed(atom, (__u64) 1); ++ spin_unlock_atom(atom); ++ /* ++ * we are trying to move node into relocate ++ * set. Allocation of relocated position "uses" ++ * reserved block. ++ */ ++ ZF_CLR(node, JNODE_FLUSH_RESERVED); ++ flush_reserved_used = 1; ++ } else { ++ ret = reiser4_grab_space_force((__u64) 1, BA_RESERVED); ++ if (ret != 0) ++ goto exit; ++ } ++ } ++ ++ /* We may do not use 5% of reserved disk space here and flush will not ++ pack tightly. */ ++ ret = reiser4_alloc_block(&pos->preceder, &blk, ++ BA_FORMATTED | BA_PERMANENT); ++ if (ret) ++ goto exit; ++ ++ if (!ZF_ISSET(node, JNODE_CREATED) && ++ (ret = ++ reiser4_dealloc_block(znode_get_block(node), 0, ++ BA_DEFER | BA_FORMATTED))) ++ goto exit; ++ ++ if (likely(!znode_is_root(node))) { ++ item_plugin *iplug; ++ ++ iplug = item_plugin_by_coord(parent_coord); ++ assert("nikita-2954", iplug->f.update != NULL); ++ iplug->f.update(parent_coord, &blk); ++ ++ znode_make_dirty(parent_coord->node); ++ ++ } else { ++ reiser4_tree *tree = znode_get_tree(node); ++ znode *uber; ++ ++ /* We take a longterm lock on the fake node in order to change ++ the root block number. This may cause atom fusion. */ ++ ret = get_uber_znode(tree, ZNODE_WRITE_LOCK, ZNODE_LOCK_HIPRI, ++ &uber_lock); ++ /* The fake node cannot be deleted, and we must have priority ++ here, and may not be confused with ENOSPC. */ ++ assert("jmacd-74412", ++ ret != -EINVAL && ret != -E_DEADLOCK && ret != -ENOSPC); ++ ++ if (ret) ++ goto exit; ++ ++ uber = uber_lock.node; ++ ++ write_lock_tree(tree); ++ tree->root_block = blk; ++ write_unlock_tree(tree); ++ ++ znode_make_dirty(uber); ++ } ++ ++ ret = znode_rehash(node, &blk); ++exit: ++ if (ret) { ++ /* Get flush reserved block back if something fails, because ++ * callers assume that on error block wasn't relocated and its ++ * flush reserved block wasn't used. */ ++ if (flush_reserved_used) { ++ /* ++ * ok, we failed to move node into relocate ++ * set. Restore status quo. ++ */ ++ grabbed2flush_reserved((__u64) 1); ++ ZF_SET(node, JNODE_FLUSH_RESERVED); ++ } ++ } ++ zrelse(node); ++ done_lh(&uber_lock); ++ grabbed2free_mark(grabbed); ++ return ret; ++} ++ ++/* JNODE INTERFACE */ ++ ++/* Lock a node (if formatted) and then get its parent locked, set the child's ++ coordinate in the parent. If the child is the root node, the above_root ++ znode is returned but the coord is not set. This function may cause atom ++ fusion, but it is only used for read locks (at this point) and therefore ++ fusion only occurs when the parent is already dirty. */ ++/* Hans adds this note: remember to ask how expensive this operation is vs. ++ storing parent pointer in jnodes. */ ++static int ++jnode_lock_parent_coord(jnode * node, ++ coord_t *coord, ++ lock_handle * parent_lh, ++ load_count * parent_zh, ++ znode_lock_mode parent_mode, int try) ++{ ++ int ret; ++ ++ assert("edward-53", jnode_is_unformatted(node) || jnode_is_znode(node)); ++ assert("edward-54", jnode_is_unformatted(node) ++ || znode_is_any_locked(JZNODE(node))); ++ ++ if (!jnode_is_znode(node)) { ++ reiser4_key key; ++ tree_level stop_level = TWIG_LEVEL; ++ lookup_bias bias = FIND_EXACT; ++ ++ assert("edward-168", !(jnode_get_type(node) == JNODE_BITMAP)); ++ ++ /* The case when node is not znode, but can have parent coord ++ (unformatted node, node which represents cluster page, ++ etc..). Generate a key for the appropriate entry, search ++ in the tree using coord_by_key, which handles locking for ++ us. */ ++ ++ /* ++ * nothing is locked at this moment, so, nothing prevents ++ * concurrent truncate from removing jnode from inode. To ++ * prevent this spin-lock jnode. jnode can be truncated just ++ * after call to the jnode_build_key(), but this is ok, ++ * because coord_by_key() will just fail to find appropriate ++ * extent. ++ */ ++ spin_lock_jnode(node); ++ if (!JF_ISSET(node, JNODE_HEARD_BANSHEE)) { ++ jnode_build_key(node, &key); ++ ret = 0; ++ } else ++ ret = RETERR(-ENOENT); ++ spin_unlock_jnode(node); ++ ++ if (ret != 0) ++ return ret; ++ ++ if (jnode_is_cluster_page(node)) ++ stop_level = LEAF_LEVEL; ++ ++ assert("jmacd-1812", coord != NULL); ++ ++ ret = coord_by_key(jnode_get_tree(node), &key, coord, parent_lh, ++ parent_mode, bias, stop_level, stop_level, ++ CBK_UNIQUE, NULL/*ra_info */); ++ switch (ret) { ++ case CBK_COORD_NOTFOUND: ++ assert("edward-1038", ++ ergo(jnode_is_cluster_page(node), ++ JF_ISSET(node, JNODE_HEARD_BANSHEE))); ++ if (!JF_ISSET(node, JNODE_HEARD_BANSHEE)) ++ warning("nikita-3177", "Parent not found"); ++ return ret; ++ case CBK_COORD_FOUND: ++ if (coord->between != AT_UNIT) { ++ /* FIXME: comment needed */ ++ done_lh(parent_lh); ++ if (!JF_ISSET(node, JNODE_HEARD_BANSHEE)) { ++ warning("nikita-3178", ++ "Found but not happy: %i", ++ coord->between); ++ } ++ return RETERR(-ENOENT); ++ } ++ ret = incr_load_count_znode(parent_zh, parent_lh->node); ++ if (ret != 0) ++ return ret; ++ /* if (jnode_is_cluster_page(node)) { ++ races with write() are possible ++ check_child_cluster (parent_lh->node); ++ } ++ */ ++ break; ++ default: ++ return ret; ++ } ++ ++ } else { ++ int flags; ++ znode *z; ++ ++ z = JZNODE(node); ++ /* Formatted node case: */ ++ assert("jmacd-2061", !znode_is_root(z)); ++ ++ flags = GN_ALLOW_NOT_CONNECTED; ++ if (try) ++ flags |= GN_TRY_LOCK; ++ ++ ret = ++ reiser4_get_parent_flags(parent_lh, z, parent_mode, flags); ++ if (ret != 0) ++ /* -E_REPEAT is ok here, it is handled by the caller. */ ++ return ret; ++ ++ /* Make the child's position "hint" up-to-date. (Unless above ++ root, which caller must check.) */ ++ if (coord != NULL) { ++ ++ ret = incr_load_count_znode(parent_zh, parent_lh->node); ++ if (ret != 0) { ++ warning("jmacd-976812386", ++ "incr_load_count_znode failed: %d", ++ ret); ++ return ret; ++ } ++ ++ ret = find_child_ptr(parent_lh->node, z, coord); ++ if (ret != 0) { ++ warning("jmacd-976812", ++ "find_child_ptr failed: %d", ret); ++ return ret; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++/* Get the (locked) next neighbor of a znode which is dirty and a member of the ++ same atom. If there is no next neighbor or the neighbor is not in memory or ++ if there is a neighbor but it is not dirty or not in the same atom, ++ -E_NO_NEIGHBOR is returned. In some cases the slum may include nodes which ++ are not dirty, if so @check_dirty should be 0 */ ++static int neighbor_in_slum(znode * node, /* starting point */ ++ lock_handle * lock, /* lock on starting point */ ++ sideof side, /* left or right direction we ++ seek the next node in */ ++ znode_lock_mode mode, /* kind of lock we want */ ++ int check_dirty, /* true if the neighbor should ++ be dirty */ ++ int use_upper_levels /* get neighbor by going though ++ upper levels */) ++{ ++ int ret; ++ int flags; ++ ++ assert("jmacd-6334", znode_is_connected(node)); ++ ++ flags = GN_SAME_ATOM | (side == LEFT_SIDE ? GN_GO_LEFT : 0); ++ if (use_upper_levels) ++ flags |= GN_CAN_USE_UPPER_LEVELS; ++ ++ ret = reiser4_get_neighbor(lock, node, mode, flags); ++ if (ret) { ++ /* May return -ENOENT or -E_NO_NEIGHBOR. */ ++ /* FIXME(C): check EINVAL, E_DEADLOCK */ ++ if (ret == -ENOENT) ++ ret = RETERR(-E_NO_NEIGHBOR); ++ return ret; ++ } ++ if (!check_dirty) ++ return 0; ++ /* Check dirty bit of locked znode, no races here */ ++ if (JF_ISSET(ZJNODE(lock->node), JNODE_DIRTY)) ++ return 0; ++ ++ done_lh(lock); ++ return RETERR(-E_NO_NEIGHBOR); ++} ++ ++/* Return true if two znodes have the same parent. This is called with both ++ nodes write-locked (for squeezing) so no tree lock is needed. */ ++static int znode_same_parents(znode * a, znode * b) ++{ ++ int result; ++ ++ assert("jmacd-7011", znode_is_write_locked(a)); ++ assert("jmacd-7012", znode_is_write_locked(b)); ++ ++ /* We lock the whole tree for this check.... I really don't like whole ++ * tree locks... -Hans */ ++ read_lock_tree(znode_get_tree(a)); ++ result = (znode_parent(a) == znode_parent(b)); ++ read_unlock_tree(znode_get_tree(a)); ++ return result; ++} ++ ++/* FLUSH SCAN */ ++ ++/* Initialize the flush_scan data structure. */ ++static void scan_init(flush_scan * scan) ++{ ++ memset(scan, 0, sizeof(*scan)); ++ init_lh(&scan->node_lock); ++ init_lh(&scan->parent_lock); ++ init_load_count(&scan->parent_load); ++ init_load_count(&scan->node_load); ++ coord_init_invalid(&scan->parent_coord, NULL); ++} ++ ++/* Release any resources held by the flush scan, e.g. release locks, ++ free memory, etc. */ ++static void scan_done(flush_scan * scan) ++{ ++ done_load_count(&scan->node_load); ++ if (scan->node != NULL) { ++ jput(scan->node); ++ scan->node = NULL; ++ } ++ done_load_count(&scan->parent_load); ++ done_lh(&scan->parent_lock); ++ done_lh(&scan->node_lock); ++} ++ ++/* Returns true if flush scanning is finished. */ ++int reiser4_scan_finished(flush_scan * scan) ++{ ++ return scan->stop || (scan->direction == RIGHT_SIDE && ++ scan->count >= scan->max_count); ++} ++ ++/* Return true if the scan should continue to the @tonode. True if the node ++ meets the same_slum_check condition. If not, deref the "left" node and stop ++ the scan. */ ++int reiser4_scan_goto(flush_scan * scan, jnode * tonode) ++{ ++ int go = same_slum_check(scan->node, tonode, 1, 0); ++ ++ if (!go) { ++ scan->stop = 1; ++ jput(tonode); ++ } ++ ++ return go; ++} ++ ++/* Set the current scan->node, refcount it, increment count by the @add_count ++ (number to count, e.g., skipped unallocated nodes), deref previous current, ++ and copy the current parent coordinate. */ ++int ++scan_set_current(flush_scan * scan, jnode * node, unsigned add_count, ++ const coord_t *parent) ++{ ++ /* Release the old references, take the new reference. */ ++ done_load_count(&scan->node_load); ++ ++ if (scan->node != NULL) ++ jput(scan->node); ++ scan->node = node; ++ scan->count += add_count; ++ ++ /* This next stmt is somewhat inefficient. The reiser4_scan_extent() ++ code could delay this update step until it finishes and update the ++ parent_coord only once. It did that before, but there was a bug and ++ this was the easiest way to make it correct. */ ++ if (parent != NULL) ++ coord_dup(&scan->parent_coord, parent); ++ ++ /* Failure may happen at the incr_load_count call, but the caller can ++ assume the reference is safely taken. */ ++ return incr_load_count_jnode(&scan->node_load, node); ++} ++ ++/* Return true if scanning in the leftward direction. */ ++int reiser4_scanning_left(flush_scan * scan) ++{ ++ return scan->direction == LEFT_SIDE; ++} ++ ++/* Performs leftward scanning starting from either kind of node. Counts the ++ starting node. The right-scan object is passed in for the left-scan in order ++ to copy the parent of an unformatted starting position. This way we avoid ++ searching for the unformatted node's parent when scanning in each direction. ++ If we search for the parent once it is set in both scan objects. The limit ++ parameter tells flush-scan when to stop. ++ ++ Rapid scanning is used only during scan_left, where we are interested in ++ finding the 'leftpoint' where we begin flushing. We are interested in ++ stopping at the left child of a twig that does not have a dirty left ++ neighbour. THIS IS A SPECIAL CASE. The problem is finding a way to flush only ++ those nodes without unallocated children, and it is difficult to solve in the ++ bottom-up flushing algorithm we are currently using. The problem can be ++ solved by scanning left at every level as we go upward, but this would ++ basically bring us back to using a top-down allocation strategy, which we ++ already tried (see BK history from May 2002), and has a different set of ++ problems. The top-down strategy makes avoiding unallocated children easier, ++ but makes it difficult to propertly flush dirty children with clean parents ++ that would otherwise stop the top-down flush, only later to dirty the parent ++ once the children are flushed. So we solve the problem in the bottom-up ++ algorithm with a special case for twigs and leaves only. ++ ++ The first step in solving the problem is this rapid leftward scan. After we ++ determine that there are at least enough nodes counted to qualify for ++ FLUSH_RELOCATE_THRESHOLD we are no longer interested in the exact count, we ++ are only interested in finding the best place to start the flush. ++ ++ We could choose one of two possibilities: ++ ++ 1. Stop at the leftmost child (of a twig) that does not have a dirty left ++ neighbor. This requires checking one leaf per rapid-scan twig ++ ++ 2. Stop at the leftmost child (of a twig) where there are no dirty children ++ of the twig to the left. This requires checking possibly all of the in-memory ++ children of each twig during the rapid scan. ++ ++ For now we implement the first policy. ++*/ ++static int ++scan_left(flush_scan * scan, flush_scan * right, jnode * node, unsigned limit) ++{ ++ int ret = 0; ++ ++ scan->max_count = limit; ++ scan->direction = LEFT_SIDE; ++ ++ ret = scan_set_current(scan, jref(node), 1, NULL); ++ if (ret != 0) ++ return ret; ++ ++ ret = scan_common(scan, right); ++ if (ret != 0) ++ return ret; ++ ++ /* Before rapid scanning, we need a lock on scan->node so that we can ++ get its parent, only if formatted. */ ++ if (jnode_is_znode(scan->node)) { ++ ret = longterm_lock_znode(&scan->node_lock, JZNODE(scan->node), ++ ZNODE_WRITE_LOCK, ZNODE_LOCK_LOPRI); ++ } ++ ++ /* Rapid_scan would go here (with limit set to FLUSH_RELOCATE_THRESHOLD) ++ */ ++ return ret; ++} ++ ++/* Performs rightward scanning... Does not count the starting node. The limit ++ parameter is described in scan_left. If the starting node is unformatted then ++ the parent_coord was already set during scan_left. The rapid_after parameter ++ is not used during right-scanning. ++ ++ scan_right is only called if the scan_left operation does not count at least ++ FLUSH_RELOCATE_THRESHOLD nodes for flushing. Otherwise, the limit parameter ++ is set to the difference between scan-left's count and ++ FLUSH_RELOCATE_THRESHOLD, meaning scan-right counts as high as ++ FLUSH_RELOCATE_THRESHOLD and then stops. */ ++static int scan_right(flush_scan * scan, jnode * node, unsigned limit) ++{ ++ int ret; ++ ++ scan->max_count = limit; ++ scan->direction = RIGHT_SIDE; ++ ++ ret = scan_set_current(scan, jref(node), 0, NULL); ++ if (ret != 0) ++ return ret; ++ ++ return scan_common(scan, NULL); ++} ++ ++/* Common code to perform left or right scanning. */ ++static int scan_common(flush_scan * scan, flush_scan * other) ++{ ++ int ret; ++ ++ assert("nikita-2376", scan->node != NULL); ++ assert("edward-54", jnode_is_unformatted(scan->node) ++ || jnode_is_znode(scan->node)); ++ ++ /* Special case for starting at an unformatted node. Optimization: we ++ only want to search for the parent (which requires a tree traversal) ++ once. Obviously, we shouldn't have to call it once for the left scan ++ and once for the right scan. For this reason, if we search for the ++ parent during scan-left we then duplicate the coord/lock/load into ++ the scan-right object. */ ++ if (jnode_is_unformatted(scan->node)) { ++ ret = scan_unformatted(scan, other); ++ if (ret != 0) ++ return ret; ++ } ++ /* This loop expects to start at a formatted position and performs ++ chaining of formatted regions */ ++ while (!reiser4_scan_finished(scan)) { ++ ++ ret = scan_formatted(scan); ++ if (ret != 0) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int scan_unformatted(flush_scan * scan, flush_scan * other) ++{ ++ int ret = 0; ++ int try = 0; ++ ++ if (!coord_is_invalid(&scan->parent_coord)) ++ goto scan; ++ ++ /* set parent coord from */ ++ if (!jnode_is_unformatted(scan->node)) { ++ /* formatted position */ ++ ++ lock_handle lock; ++ assert("edward-301", jnode_is_znode(scan->node)); ++ init_lh(&lock); ++ ++ /* ++ * when flush starts from unformatted node, first thing it ++ * does is tree traversal to find formatted parent of starting ++ * node. This parent is then kept lock across scans to the ++ * left and to the right. This means that during scan to the ++ * left we cannot take left-ward lock, because this is ++ * dead-lock prone. So, if we are scanning to the left and ++ * there is already lock held by this thread, ++ * jnode_lock_parent_coord() should use try-lock. ++ */ ++ try = reiser4_scanning_left(scan) ++ && !lock_stack_isclean(get_current_lock_stack()); ++ /* Need the node locked to get the parent lock, We have to ++ take write lock since there is at least one call path ++ where this znode is already write-locked by us. */ ++ ret = ++ longterm_lock_znode(&lock, JZNODE(scan->node), ++ ZNODE_WRITE_LOCK, ++ reiser4_scanning_left(scan) ? ++ ZNODE_LOCK_LOPRI : ++ ZNODE_LOCK_HIPRI); ++ if (ret != 0) ++ /* EINVAL or E_DEADLOCK here mean... try again! At this ++ point we've scanned too far and can't back out, just ++ start over. */ ++ return ret; ++ ++ ret = jnode_lock_parent_coord(scan->node, ++ &scan->parent_coord, ++ &scan->parent_lock, ++ &scan->parent_load, ++ ZNODE_WRITE_LOCK, try); ++ ++ /* FIXME(C): check EINVAL, E_DEADLOCK */ ++ done_lh(&lock); ++ if (ret == -E_REPEAT) { ++ scan->stop = 1; ++ return 0; ++ } ++ if (ret) ++ return ret; ++ ++ } else { ++ /* unformatted position */ ++ ++ ret = ++ jnode_lock_parent_coord(scan->node, &scan->parent_coord, ++ &scan->parent_lock, ++ &scan->parent_load, ++ ZNODE_WRITE_LOCK, try); ++ ++ if (IS_CBKERR(ret)) ++ return ret; ++ ++ if (ret == CBK_COORD_NOTFOUND) ++ /* FIXME(C): check EINVAL, E_DEADLOCK */ ++ return ret; ++ ++ /* parent was found */ ++ assert("jmacd-8661", other != NULL); ++ /* Duplicate the reference into the other flush_scan. */ ++ coord_dup(&other->parent_coord, &scan->parent_coord); ++ copy_lh(&other->parent_lock, &scan->parent_lock); ++ copy_load_count(&other->parent_load, &scan->parent_load); ++ } ++scan: ++ return scan_by_coord(scan); ++} ++ ++/* Performs left- or rightward scanning starting from a formatted node. Follow ++ left pointers under tree lock as long as: ++ ++ - node->left/right is non-NULL ++ - node->left/right is connected, dirty ++ - node->left/right belongs to the same atom ++ - scan has not reached maximum count ++*/ ++static int scan_formatted(flush_scan * scan) ++{ ++ int ret; ++ znode *neighbor = NULL; ++ ++ assert("jmacd-1401", !reiser4_scan_finished(scan)); ++ ++ do { ++ znode *node = JZNODE(scan->node); ++ ++ /* Node should be connected, but if not stop the scan. */ ++ if (!znode_is_connected(node)) { ++ scan->stop = 1; ++ break; ++ } ++ ++ /* Lock the tree, check-for and reference the next sibling. */ ++ read_lock_tree(znode_get_tree(node)); ++ ++ /* It may be that a node is inserted or removed between a node ++ and its left sibling while the tree lock is released, but the ++ flush-scan count does not need to be precise. Thus, we ++ release the tree lock as soon as we get the neighboring node. ++ */ ++ neighbor = ++ reiser4_scanning_left(scan) ? node->left : node->right; ++ if (neighbor != NULL) ++ zref(neighbor); ++ ++ read_unlock_tree(znode_get_tree(node)); ++ ++ /* If neighbor is NULL at the leaf level, need to check for an ++ unformatted sibling using the parent--break in any case. */ ++ if (neighbor == NULL) ++ break; ++ ++ /* Check the condition for going left, break if it is not met. ++ This also releases (jputs) the neighbor if false. */ ++ if (!reiser4_scan_goto(scan, ZJNODE(neighbor))) ++ break; ++ ++ /* Advance the flush_scan state to the left, repeat. */ ++ ret = scan_set_current(scan, ZJNODE(neighbor), 1, NULL); ++ if (ret != 0) ++ return ret; ++ ++ } while (!reiser4_scan_finished(scan)); ++ ++ /* If neighbor is NULL then we reached the end of a formatted region, or ++ else the sibling is out of memory, now check for an extent to the ++ left (as long as LEAF_LEVEL). */ ++ if (neighbor != NULL || jnode_get_level(scan->node) != LEAF_LEVEL ++ || reiser4_scan_finished(scan)) { ++ scan->stop = 1; ++ return 0; ++ } ++ /* Otherwise, calls scan_by_coord for the right(left)most item of the ++ left(right) neighbor on the parent level, then possibly continue. */ ++ ++ coord_init_invalid(&scan->parent_coord, NULL); ++ return scan_unformatted(scan, NULL); ++} ++ ++/* NOTE-EDWARD: ++ This scans adjacent items of the same type and calls scan flush plugin for ++ each one. Performs left(right)ward scanning starting from a (possibly) ++ unformatted node. If we start from unformatted node, then we continue only if ++ the next neighbor is also unformatted. When called from scan_formatted, we ++ skip first iteration (to make sure that right(left)most item of the ++ left(right) neighbor on the parent level is of the same type and set ++ appropriate coord). */ ++static int scan_by_coord(flush_scan * scan) ++{ ++ int ret = 0; ++ int scan_this_coord; ++ lock_handle next_lock; ++ load_count next_load; ++ coord_t next_coord; ++ jnode *child; ++ item_plugin *iplug; ++ ++ init_lh(&next_lock); ++ init_load_count(&next_load); ++ scan_this_coord = (jnode_is_unformatted(scan->node) ? 1 : 0); ++ ++ /* set initial item id */ ++ iplug = item_plugin_by_coord(&scan->parent_coord); ++ ++ for (; !reiser4_scan_finished(scan); scan_this_coord = 1) { ++ if (scan_this_coord) { ++ /* Here we expect that unit is scannable. it would not ++ * be so due to race with extent->tail conversion. */ ++ if (iplug->f.scan == NULL) { ++ scan->stop = 1; ++ ret = -E_REPEAT; ++ /* skip the check at the end. */ ++ goto race; ++ } ++ ++ ret = iplug->f.scan(scan); ++ if (ret != 0) ++ goto exit; ++ ++ if (reiser4_scan_finished(scan)) { ++ checkchild(scan); ++ break; ++ } ++ } else { ++ /* the same race against truncate as above is possible ++ * here, it seems */ ++ ++ /* NOTE-JMACD: In this case, apply the same end-of-node ++ logic but don't scan the first coordinate. */ ++ assert("jmacd-1231", ++ item_is_internal(&scan->parent_coord)); ++ } ++ ++ if (iplug->f.utmost_child == NULL ++ || znode_get_level(scan->parent_coord.node) != TWIG_LEVEL) { ++ /* stop this coord and continue on parrent level */ ++ ret = ++ scan_set_current(scan, ++ ZJNODE(zref ++ (scan->parent_coord.node)), ++ 1, NULL); ++ if (ret != 0) ++ goto exit; ++ break; ++ } ++ ++ /* Either way, the invariant is that scan->parent_coord is set ++ to the parent of scan->node. Now get the next unit. */ ++ coord_dup(&next_coord, &scan->parent_coord); ++ coord_sideof_unit(&next_coord, scan->direction); ++ ++ /* If off-the-end of the twig, try the next twig. */ ++ if (coord_is_after_sideof_unit(&next_coord, scan->direction)) { ++ /* We take the write lock because we may start flushing ++ * from this coordinate. */ ++ ret = neighbor_in_slum(next_coord.node, ++ &next_lock, ++ scan->direction, ++ ZNODE_WRITE_LOCK, ++ 1 /* check dirty */, ++ 0 /* don't go though upper ++ levels */); ++ if (ret == -E_NO_NEIGHBOR) { ++ scan->stop = 1; ++ ret = 0; ++ break; ++ } ++ ++ if (ret != 0) ++ goto exit; ++ ++ ret = incr_load_count_znode(&next_load, next_lock.node); ++ if (ret != 0) ++ goto exit; ++ ++ coord_init_sideof_unit(&next_coord, next_lock.node, ++ sideof_reverse(scan->direction)); ++ } ++ ++ iplug = item_plugin_by_coord(&next_coord); ++ ++ /* Get the next child. */ ++ ret = ++ iplug->f.utmost_child(&next_coord, ++ sideof_reverse(scan->direction), ++ &child); ++ if (ret != 0) ++ goto exit; ++ /* If the next child is not in memory, or, item_utmost_child ++ failed (due to race with unlink, most probably), stop ++ here. */ ++ if (child == NULL || IS_ERR(child)) { ++ scan->stop = 1; ++ checkchild(scan); ++ break; ++ } ++ ++ assert("nikita-2374", jnode_is_unformatted(child) ++ || jnode_is_znode(child)); ++ ++ /* See if it is dirty, part of the same atom. */ ++ if (!reiser4_scan_goto(scan, child)) { ++ checkchild(scan); ++ break; ++ } ++ ++ /* If so, make this child current. */ ++ ret = scan_set_current(scan, child, 1, &next_coord); ++ if (ret != 0) ++ goto exit; ++ ++ /* Now continue. If formatted we release the parent lock and ++ return, then proceed. */ ++ if (jnode_is_znode(child)) ++ break; ++ ++ /* Otherwise, repeat the above loop with next_coord. */ ++ if (next_load.node != NULL) { ++ done_lh(&scan->parent_lock); ++ move_lh(&scan->parent_lock, &next_lock); ++ move_load_count(&scan->parent_load, &next_load); ++ } ++ } ++ ++ assert("jmacd-6233", ++ reiser4_scan_finished(scan) || jnode_is_znode(scan->node)); ++exit: ++ checkchild(scan); ++race: /* skip the above check */ ++ if (jnode_is_znode(scan->node)) { ++ done_lh(&scan->parent_lock); ++ done_load_count(&scan->parent_load); ++ } ++ ++ done_load_count(&next_load); ++ done_lh(&next_lock); ++ return ret; ++} ++ ++/* FLUSH POS HELPERS */ ++ ++/* Initialize the fields of a flush_position. */ ++static void pos_init(flush_pos_t *pos) ++{ ++ memset(pos, 0, sizeof *pos); ++ ++ pos->state = POS_INVALID; ++ coord_init_invalid(&pos->coord, NULL); ++ init_lh(&pos->lock); ++ init_load_count(&pos->load); ++ ++ reiser4_blocknr_hint_init(&pos->preceder); ++} ++ ++/* The flush loop inside squalloc periodically checks pos_valid to determine ++ when "enough flushing" has been performed. This will return true until one ++ of the following conditions is met: ++ ++ 1. the number of flush-queued nodes has reached the kernel-supplied ++ "int *nr_to_flush" parameter, meaning we have flushed as many blocks as the ++ kernel requested. When flushing to commit, this parameter is NULL. ++ ++ 2. pos_stop() is called because squalloc discovers that the "next" node in ++ the flush order is either non-existant, not dirty, or not in the same atom. ++*/ ++ ++static int pos_valid(flush_pos_t *pos) ++{ ++ return pos->state != POS_INVALID; ++} ++ ++/* Release any resources of a flush_position. Called when jnode_flush ++ finishes. */ ++static void pos_done(flush_pos_t *pos) ++{ ++ pos_stop(pos); ++ reiser4_blocknr_hint_done(&pos->preceder); ++ if (convert_data(pos)) ++ free_convert_data(pos); ++} ++ ++/* Reset the point and parent. Called during flush subroutines to terminate the ++ squalloc loop. */ ++static int pos_stop(flush_pos_t *pos) ++{ ++ pos->state = POS_INVALID; ++ done_lh(&pos->lock); ++ done_load_count(&pos->load); ++ coord_init_invalid(&pos->coord, NULL); ++ ++ if (pos->child) { ++ jput(pos->child); ++ pos->child = NULL; ++ } ++ ++ return 0; ++} ++ ++/* Return the flush_position's block allocator hint. */ ++reiser4_blocknr_hint *reiser4_pos_hint(flush_pos_t *pos) ++{ ++ return &pos->preceder; ++} ++ ++flush_queue_t *reiser4_pos_fq(flush_pos_t *pos) ++{ ++ return pos->fq; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 90 ++ LocalWords: preceder ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/flush.h linux-2.6.30/fs/reiser4/flush.h +--- linux-2.6.30.orig/fs/reiser4/flush.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/flush.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,300 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* DECLARATIONS: */ ++ ++#if !defined(__REISER4_FLUSH_H__) ++#define __REISER4_FLUSH_H__ ++ ++#include "plugin/cluster.h" ++ ++/* The flush_scan data structure maintains the state of an in-progress ++ flush-scan on a single level of the tree. A flush-scan is used for counting ++ the number of adjacent nodes to flush, which is used to determine whether we ++ should relocate, and it is also used to find a starting point for flush. A ++ flush-scan object can scan in both right and left directions via the ++ scan_left() and scan_right() interfaces. The right- and left-variations are ++ similar but perform different functions. When scanning left we (optionally ++ perform rapid scanning and then) longterm-lock the endpoint node. When ++ scanning right we are simply counting the number of adjacent, dirty nodes. */ ++struct flush_scan { ++ ++ /* The current number of nodes scanned on this level. */ ++ unsigned count; ++ ++ /* There may be a maximum number of nodes for a scan on any single ++ level. When going leftward, max_count is determined by ++ FLUSH_SCAN_MAXNODES (see reiser4.h) */ ++ unsigned max_count; ++ ++ /* Direction: Set to one of the sideof enumeration: ++ { LEFT_SIDE, RIGHT_SIDE }. */ ++ sideof direction; ++ ++ /* Initially @stop is set to false then set true once some condition ++ stops the search (e.g., we found a clean node before reaching ++ max_count or we found a node belonging to another atom). */ ++ int stop; ++ ++ /* The current scan position. If @node is non-NULL then its reference ++ count has been incremented to reflect this reference. */ ++ jnode *node; ++ ++ /* A handle for zload/zrelse of current scan position node. */ ++ load_count node_load; ++ ++ /* During left-scan, if the final position (a.k.a. endpoint node) is ++ formatted the node is locked using this lock handle. The endpoint ++ needs to be locked for transfer to the flush_position object after ++ scanning finishes. */ ++ lock_handle node_lock; ++ ++ /* When the position is unformatted, its parent, coordinate, and parent ++ zload/zrelse handle. */ ++ lock_handle parent_lock; ++ coord_t parent_coord; ++ load_count parent_load; ++ ++ /* The block allocator preceder hint. Sometimes flush_scan determines ++ what the preceder is and if so it sets it here, after which it is ++ copied into the flush_position. Otherwise, the preceder is computed ++ later. */ ++ reiser4_block_nr preceder_blk; ++}; ++ ++struct convert_item_info { ++ dc_item_stat d_cur; /* disk cluster state of the current item */ ++ dc_item_stat d_next; /* disk cluster state of the next slum item */ ++ int cluster_shift; /* disk cluster shift */ ++ flow_t flow; /* disk cluster data */ ++}; ++ ++struct convert_info { ++ int count; /* for squalloc terminating */ ++ item_plugin *iplug; /* current item plugin */ ++ struct convert_item_info *itm; /* current item info */ ++ struct cluster_handle clust; /* transform cluster */ ++}; ++ ++typedef enum flush_position_state { ++ POS_INVALID, /* Invalid or stopped pos, do not continue slum ++ * processing */ ++ POS_ON_LEAF, /* pos points to already prepped, locked ++ * formatted node at leaf level */ ++ POS_ON_EPOINT, /* pos keeps a lock on twig level, "coord" field ++ * is used to traverse unformatted nodes */ ++ POS_TO_LEAF, /* pos is being moved to leaf level */ ++ POS_TO_TWIG, /* pos is being moved to twig level */ ++ POS_END_OF_TWIG, /* special case of POS_ON_TWIG, when coord is ++ * after rightmost unit of the current twig */ ++ POS_ON_INTERNAL /* same as POS_ON_LEAF, but points to internal ++ * node */ ++} flushpos_state_t; ++ ++/* An encapsulation of the current flush point and all the parameters that are ++ passed through the entire squeeze-and-allocate stage of the flush routine. ++ A single flush_position object is constructed after left- and right-scanning ++ finishes. */ ++struct flush_position { ++ flushpos_state_t state; ++ ++ coord_t coord; /* coord to traverse unformatted nodes */ ++ lock_handle lock; /* current lock we hold */ ++ load_count load; /* load status for current locked formatted node ++ */ ++ jnode *child; /* for passing a reference to unformatted child ++ * across pos state changes */ ++ ++ reiser4_blocknr_hint preceder; /* The flush 'hint' state. */ ++ int leaf_relocate; /* True if enough leaf-level nodes were ++ * found to suggest a relocate policy. */ ++ int alloc_cnt; /* The number of nodes allocated during squeeze ++ and allococate. */ ++ int prep_or_free_cnt; /* The number of nodes prepared for write ++ (allocate) or squeezed and freed. */ ++ flush_queue_t *fq; ++ long *nr_written; /* number of nodes submitted to disk */ ++ int flags; /* a copy of jnode_flush flags argument */ ++ ++ znode *prev_twig; /* previous parent pointer value, used to catch ++ * processing of new twig node */ ++ struct convert_info *sq; /* convert info */ ++ ++ unsigned long pos_in_unit; /* for extents only. Position ++ within an extent unit of first ++ jnode of slum */ ++ long nr_to_write; /* number of unformatted nodes to handle on ++ flush */ ++}; ++ ++static inline int item_convert_count(flush_pos_t *pos) ++{ ++ return pos->sq->count; ++} ++static inline void inc_item_convert_count(flush_pos_t *pos) ++{ ++ pos->sq->count++; ++} ++static inline void set_item_convert_count(flush_pos_t *pos, int count) ++{ ++ pos->sq->count = count; ++} ++static inline item_plugin *item_convert_plug(flush_pos_t *pos) ++{ ++ return pos->sq->iplug; ++} ++ ++static inline struct convert_info *convert_data(flush_pos_t *pos) ++{ ++ return pos->sq; ++} ++ ++static inline struct convert_item_info *item_convert_data(flush_pos_t *pos) ++{ ++ assert("edward-955", convert_data(pos)); ++ return pos->sq->itm; ++} ++ ++static inline struct tfm_cluster *tfm_cluster_sq(flush_pos_t *pos) ++{ ++ return &pos->sq->clust.tc; ++} ++ ++static inline struct tfm_stream *tfm_stream_sq(flush_pos_t *pos, ++ tfm_stream_id id) ++{ ++ assert("edward-854", pos->sq != NULL); ++ return get_tfm_stream(tfm_cluster_sq(pos), id); ++} ++ ++static inline int chaining_data_present(flush_pos_t *pos) ++{ ++ return convert_data(pos) && item_convert_data(pos); ++} ++ ++/* Returns true if next node contains next item of the disk cluster ++ so item convert data should be moved to the right slum neighbor. ++*/ ++static inline int should_chain_next_node(flush_pos_t *pos) ++{ ++ int result = 0; ++ ++ assert("edward-1007", chaining_data_present(pos)); ++ ++ switch (item_convert_data(pos)->d_next) { ++ case DC_CHAINED_ITEM: ++ result = 1; ++ break; ++ case DC_AFTER_CLUSTER: ++ break; ++ default: ++ impossible("edward-1009", "bad state of next slum item"); ++ } ++ return result; ++} ++ ++/* update item state in a disk cluster to assign conversion mode */ ++static inline void ++move_chaining_data(flush_pos_t *pos, int this_node/* where is next item */) ++{ ++ ++ assert("edward-1010", chaining_data_present(pos)); ++ ++ if (this_node == 0) { ++ /* next item is on the right neighbor */ ++ assert("edward-1011", ++ item_convert_data(pos)->d_cur == DC_FIRST_ITEM || ++ item_convert_data(pos)->d_cur == DC_CHAINED_ITEM); ++ assert("edward-1012", ++ item_convert_data(pos)->d_next == DC_CHAINED_ITEM); ++ ++ item_convert_data(pos)->d_cur = DC_CHAINED_ITEM; ++ item_convert_data(pos)->d_next = DC_INVALID_STATE; ++ } else { ++ /* next item is on the same node */ ++ assert("edward-1013", ++ item_convert_data(pos)->d_cur == DC_FIRST_ITEM || ++ item_convert_data(pos)->d_cur == DC_CHAINED_ITEM); ++ assert("edward-1227", ++ item_convert_data(pos)->d_next == DC_AFTER_CLUSTER || ++ item_convert_data(pos)->d_next == DC_INVALID_STATE); ++ ++ item_convert_data(pos)->d_cur = DC_AFTER_CLUSTER; ++ item_convert_data(pos)->d_next = DC_INVALID_STATE; ++ } ++} ++ ++static inline int should_convert_node(flush_pos_t *pos, znode * node) ++{ ++ return znode_convertible(node); ++} ++ ++/* true if there is attached convert item info */ ++static inline int should_convert_next_node(flush_pos_t *pos) ++{ ++ return convert_data(pos) && item_convert_data(pos); ++} ++ ++#define SQUALLOC_THRESHOLD 256 ++ ++static inline int should_terminate_squalloc(flush_pos_t *pos) ++{ ++ return convert_data(pos) && ++ !item_convert_data(pos) && ++ item_convert_count(pos) >= SQUALLOC_THRESHOLD; ++} ++ ++#if 1 ++#define check_convert_info(pos) \ ++do { \ ++ if (unlikely(should_convert_next_node(pos))) { \ ++ warning("edward-1006", "unprocessed chained data"); \ ++ printk("d_cur = %d, d_next = %d, flow.len = %llu\n", \ ++ item_convert_data(pos)->d_cur, \ ++ item_convert_data(pos)->d_next, \ ++ item_convert_data(pos)->flow.length); \ ++ } \ ++} while (0) ++#else ++#define check_convert_info(pos) ++#endif /* REISER4_DEBUG */ ++ ++void free_convert_data(flush_pos_t *pos); ++/* used in extent.c */ ++int scan_set_current(flush_scan * scan, jnode * node, unsigned add_size, ++ const coord_t *parent); ++int reiser4_scan_finished(flush_scan * scan); ++int reiser4_scanning_left(flush_scan * scan); ++int reiser4_scan_goto(flush_scan * scan, jnode * tonode); ++txn_atom *atom_locked_by_fq(flush_queue_t *fq); ++int reiser4_alloc_extent(flush_pos_t *flush_pos); ++squeeze_result squalloc_extent(znode *left, const coord_t *, flush_pos_t *, ++ reiser4_key *stop_key); ++extern int reiser4_init_fqs(void); ++extern void reiser4_done_fqs(void); ++ ++#if REISER4_DEBUG ++ ++extern void reiser4_check_fq(const txn_atom *atom); ++extern atomic_t flush_cnt; ++ ++#define check_preceder(blk) \ ++assert("nikita-2588", blk < reiser4_block_count(reiser4_get_current_sb())); ++extern void check_pos(flush_pos_t *pos); ++#else ++#define check_preceder(b) noop ++#define check_pos(pos) noop ++#endif ++ ++/* __REISER4_FLUSH_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 90 ++ LocalWords: preceder ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/flush_queue.c linux-2.6.30/fs/reiser4/flush_queue.c +--- linux-2.6.30.orig/fs/reiser4/flush_queue.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/flush_queue.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,678 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++#include "debug.h" ++#include "super.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "page_cache.h" ++#include "wander.h" ++#include "vfs_ops.h" ++#include "writeout.h" ++#include "flush.h" ++ ++#include <linux/bio.h> ++#include <linux/mm.h> ++#include <linux/pagemap.h> ++#include <linux/blkdev.h> ++#include <linux/writeback.h> ++ ++/* A flush queue object is an accumulator for keeping jnodes prepared ++ by the jnode_flush() function for writing to disk. Those "queued" jnodes are ++ kept on the flush queue until memory pressure or atom commit asks ++ flush queues to write some or all from their jnodes. */ ++ ++/* ++ LOCKING: ++ ++ fq->guard spin lock protects fq->atom pointer and nothing else. fq->prepped ++ list protected by atom spin lock. fq->prepped list uses the following ++ locking: ++ ++ two ways to protect fq->prepped list for read-only list traversal: ++ ++ 1. atom spin-lock atom. ++ 2. fq is IN_USE, atom->nr_running_queues increased. ++ ++ and one for list modification: ++ ++ 1. atom is spin-locked and one condition is true: fq is IN_USE or ++ atom->nr_running_queues == 0. ++ ++ The deadlock-safe order for flush queues and atoms is: first lock atom, then ++ lock flush queue, then lock jnode. ++*/ ++ ++#define fq_in_use(fq) ((fq)->state & FQ_IN_USE) ++#define fq_ready(fq) (!fq_in_use(fq)) ++ ++#define mark_fq_in_use(fq) do { (fq)->state |= FQ_IN_USE; } while (0) ++#define mark_fq_ready(fq) do { (fq)->state &= ~FQ_IN_USE; } while (0) ++ ++/* get lock on atom from locked flush queue object */ ++static txn_atom *atom_locked_by_fq_nolock(flush_queue_t *fq) ++{ ++ /* This code is similar to jnode_get_atom(), look at it for the ++ * explanation. */ ++ txn_atom *atom; ++ ++ assert_spin_locked(&(fq->guard)); ++ ++ while (1) { ++ atom = fq->atom; ++ if (atom == NULL) ++ break; ++ ++ if (spin_trylock_atom(atom)) ++ break; ++ ++ atomic_inc(&atom->refcount); ++ spin_unlock(&(fq->guard)); ++ spin_lock_atom(atom); ++ spin_lock(&(fq->guard)); ++ ++ if (fq->atom == atom) { ++ atomic_dec(&atom->refcount); ++ break; ++ } ++ ++ spin_unlock(&(fq->guard)); ++ atom_dec_and_unlock(atom); ++ spin_lock(&(fq->guard)); ++ } ++ ++ return atom; ++} ++ ++txn_atom *atom_locked_by_fq(flush_queue_t *fq) ++{ ++ txn_atom *atom; ++ ++ spin_lock(&(fq->guard)); ++ atom = atom_locked_by_fq_nolock(fq); ++ spin_unlock(&(fq->guard)); ++ return atom; ++} ++ ++static void init_fq(flush_queue_t *fq) ++{ ++ memset(fq, 0, sizeof *fq); ++ ++ atomic_set(&fq->nr_submitted, 0); ++ ++ INIT_LIST_HEAD(ATOM_FQ_LIST(fq)); ++ ++ init_waitqueue_head(&fq->wait); ++ spin_lock_init(&fq->guard); ++} ++ ++/* slab for flush queues */ ++static struct kmem_cache *fq_slab; ++ ++/** ++ * reiser4_init_fqs - create flush queue cache ++ * ++ * Initializes slab cache of flush queues. It is part of reiser4 module ++ * initialization. ++ */ ++int reiser4_init_fqs(void) ++{ ++ fq_slab = kmem_cache_create("fq", ++ sizeof(flush_queue_t), ++ 0, SLAB_HWCACHE_ALIGN, NULL); ++ if (fq_slab == NULL) ++ return RETERR(-ENOMEM); ++ return 0; ++} ++ ++/** ++ * reiser4_done_fqs - delete flush queue cache ++ * ++ * This is called on reiser4 module unloading or system shutdown. ++ */ ++void reiser4_done_fqs(void) ++{ ++ destroy_reiser4_cache(&fq_slab); ++} ++ ++/* create new flush queue object */ ++static flush_queue_t *create_fq(gfp_t gfp) ++{ ++ flush_queue_t *fq; ++ ++ fq = kmem_cache_alloc(fq_slab, gfp); ++ if (fq) ++ init_fq(fq); ++ ++ return fq; ++} ++ ++/* adjust atom's and flush queue's counters of queued nodes */ ++static void count_enqueued_node(flush_queue_t *fq) ++{ ++ ON_DEBUG(fq->atom->num_queued++); ++} ++ ++static void count_dequeued_node(flush_queue_t *fq) ++{ ++ assert("zam-993", fq->atom->num_queued > 0); ++ ON_DEBUG(fq->atom->num_queued--); ++} ++ ++/* attach flush queue object to the atom */ ++static void attach_fq(txn_atom *atom, flush_queue_t *fq) ++{ ++ assert_spin_locked(&(atom->alock)); ++ list_add(&fq->alink, &atom->flush_queues); ++ fq->atom = atom; ++ ON_DEBUG(atom->nr_flush_queues++); ++} ++ ++static void detach_fq(flush_queue_t *fq) ++{ ++ assert_spin_locked(&(fq->atom->alock)); ++ ++ spin_lock(&(fq->guard)); ++ list_del_init(&fq->alink); ++ assert("vs-1456", fq->atom->nr_flush_queues > 0); ++ ON_DEBUG(fq->atom->nr_flush_queues--); ++ fq->atom = NULL; ++ spin_unlock(&(fq->guard)); ++} ++ ++/* destroy flush queue object */ ++static void done_fq(flush_queue_t *fq) ++{ ++ assert("zam-763", list_empty_careful(ATOM_FQ_LIST(fq))); ++ assert("zam-766", atomic_read(&fq->nr_submitted) == 0); ++ ++ kmem_cache_free(fq_slab, fq); ++} ++ ++/* */ ++static void mark_jnode_queued(flush_queue_t *fq, jnode * node) ++{ ++ JF_SET(node, JNODE_FLUSH_QUEUED); ++ count_enqueued_node(fq); ++} ++ ++/* Putting jnode into the flush queue. Both atom and jnode should be ++ spin-locked. */ ++void queue_jnode(flush_queue_t *fq, jnode * node) ++{ ++ assert_spin_locked(&(node->guard)); ++ assert("zam-713", node->atom != NULL); ++ assert_spin_locked(&(node->atom->alock)); ++ assert("zam-716", fq->atom != NULL); ++ assert("zam-717", fq->atom == node->atom); ++ assert("zam-907", fq_in_use(fq)); ++ ++ assert("zam-714", JF_ISSET(node, JNODE_DIRTY)); ++ assert("zam-826", JF_ISSET(node, JNODE_RELOC)); ++ assert("vs-1481", !JF_ISSET(node, JNODE_FLUSH_QUEUED)); ++ assert("vs-1481", NODE_LIST(node) != FQ_LIST); ++ ++ mark_jnode_queued(fq, node); ++ list_move_tail(&node->capture_link, ATOM_FQ_LIST(fq)); ++ ++ ON_DEBUG(count_jnode(node->atom, node, NODE_LIST(node), ++ FQ_LIST, 1)); ++} ++ ++/* repeatable process for waiting io completion on a flush queue object */ ++static int wait_io(flush_queue_t *fq, int *nr_io_errors) ++{ ++ assert("zam-738", fq->atom != NULL); ++ assert_spin_locked(&(fq->atom->alock)); ++ assert("zam-736", fq_in_use(fq)); ++ assert("zam-911", list_empty_careful(ATOM_FQ_LIST(fq))); ++ ++ if (atomic_read(&fq->nr_submitted) != 0) { ++ struct super_block *super; ++ ++ spin_unlock_atom(fq->atom); ++ ++ assert("nikita-3013", reiser4_schedulable()); ++ ++ super = reiser4_get_current_sb(); ++ ++ /* FIXME: this is instead of blk_run_queues() */ ++ blk_run_address_space(reiser4_get_super_fake(super)->i_mapping); ++ ++ if (!(super->s_flags & MS_RDONLY)) ++ wait_event(fq->wait, ++ atomic_read(&fq->nr_submitted) == 0); ++ ++ /* Ask the caller to re-acquire the locks and call this ++ function again. Note: this technique is commonly used in ++ the txnmgr code. */ ++ return -E_REPEAT; ++ } ++ ++ *nr_io_errors += atomic_read(&fq->nr_errors); ++ return 0; ++} ++ ++/* wait on I/O completion, re-submit dirty nodes to write */ ++static int finish_fq(flush_queue_t *fq, int *nr_io_errors) ++{ ++ int ret; ++ txn_atom *atom = fq->atom; ++ ++ assert("zam-801", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ assert("zam-762", fq_in_use(fq)); ++ ++ ret = wait_io(fq, nr_io_errors); ++ if (ret) ++ return ret; ++ ++ detach_fq(fq); ++ done_fq(fq); ++ ++ reiser4_atom_send_event(atom); ++ ++ return 0; ++} ++ ++/* wait for all i/o for given atom to be completed, actually do one iteration ++ on that and return -E_REPEAT if there more iterations needed */ ++static int finish_all_fq(txn_atom * atom, int *nr_io_errors) ++{ ++ flush_queue_t *fq; ++ ++ assert_spin_locked(&(atom->alock)); ++ ++ if (list_empty_careful(&atom->flush_queues)) ++ return 0; ++ ++ list_for_each_entry(fq, &atom->flush_queues, alink) { ++ if (fq_ready(fq)) { ++ int ret; ++ ++ mark_fq_in_use(fq); ++ assert("vs-1247", fq->owner == NULL); ++ ON_DEBUG(fq->owner = current); ++ ret = finish_fq(fq, nr_io_errors); ++ ++ if (*nr_io_errors) ++ reiser4_handle_error(); ++ ++ if (ret) { ++ reiser4_fq_put(fq); ++ return ret; ++ } ++ ++ spin_unlock_atom(atom); ++ ++ return -E_REPEAT; ++ } ++ } ++ ++ /* All flush queues are in use; atom remains locked */ ++ return -EBUSY; ++} ++ ++/* wait all i/o for current atom */ ++int current_atom_finish_all_fq(void) ++{ ++ txn_atom *atom; ++ int nr_io_errors = 0; ++ int ret = 0; ++ ++ do { ++ while (1) { ++ atom = get_current_atom_locked(); ++ ret = finish_all_fq(atom, &nr_io_errors); ++ if (ret != -EBUSY) ++ break; ++ reiser4_atom_wait_event(atom); ++ } ++ } while (ret == -E_REPEAT); ++ ++ /* we do not need locked atom after this function finishes, SUCCESS or ++ -EBUSY are two return codes when atom remains locked after ++ finish_all_fq */ ++ if (!ret) ++ spin_unlock_atom(atom); ++ ++ assert_spin_not_locked(&(atom->alock)); ++ ++ if (ret) ++ return ret; ++ ++ if (nr_io_errors) ++ return RETERR(-EIO); ++ ++ return 0; ++} ++ ++/* change node->atom field for all jnode from given list */ ++static void ++scan_fq_and_update_atom_ref(struct list_head *list, txn_atom *atom) ++{ ++ jnode *cur; ++ ++ list_for_each_entry(cur, list, capture_link) { ++ spin_lock_jnode(cur); ++ cur->atom = atom; ++ spin_unlock_jnode(cur); ++ } ++} ++ ++/* support for atom fusion operation */ ++void reiser4_fuse_fq(txn_atom *to, txn_atom *from) ++{ ++ flush_queue_t *fq; ++ ++ assert_spin_locked(&(to->alock)); ++ assert_spin_locked(&(from->alock)); ++ ++ list_for_each_entry(fq, &from->flush_queues, alink) { ++ scan_fq_and_update_atom_ref(ATOM_FQ_LIST(fq), to); ++ spin_lock(&(fq->guard)); ++ fq->atom = to; ++ spin_unlock(&(fq->guard)); ++ } ++ ++ list_splice_init(&from->flush_queues, to->flush_queues.prev); ++ ++#if REISER4_DEBUG ++ to->num_queued += from->num_queued; ++ to->nr_flush_queues += from->nr_flush_queues; ++ from->nr_flush_queues = 0; ++#endif ++} ++ ++#if REISER4_DEBUG ++int atom_fq_parts_are_clean(txn_atom * atom) ++{ ++ assert("zam-915", atom != NULL); ++ return list_empty_careful(&atom->flush_queues); ++} ++#endif ++/* Bio i/o completion routine for reiser4 write operations. */ ++static void ++end_io_handler(struct bio *bio, int err) ++{ ++ int i; ++ int nr_errors = 0; ++ flush_queue_t *fq; ++ ++ assert("zam-958", bio->bi_rw & WRITE); ++ ++ if (err == -EOPNOTSUPP) ++ set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); ++ ++ /* we expect that bio->private is set to NULL or fq object which is used ++ * for synchronization and error counting. */ ++ fq = bio->bi_private; ++ /* Check all elements of io_vec for correct write completion. */ ++ for (i = 0; i < bio->bi_vcnt; i += 1) { ++ struct page *pg = bio->bi_io_vec[i].bv_page; ++ ++ if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { ++ SetPageError(pg); ++ nr_errors++; ++ } ++ ++ { ++ /* jnode WRITEBACK ("write is in progress bit") is ++ * atomically cleared here. */ ++ jnode *node; ++ ++ assert("zam-736", pg != NULL); ++ assert("zam-736", PagePrivate(pg)); ++ node = jprivate(pg); ++ ++ JF_CLR(node, JNODE_WRITEBACK); ++ } ++ ++ end_page_writeback(pg); ++ page_cache_release(pg); ++ } ++ ++ if (fq) { ++ /* count i/o error in fq object */ ++ atomic_add(nr_errors, &fq->nr_errors); ++ ++ /* If all write requests registered in this "fq" are done we up ++ * the waiter. */ ++ if (atomic_sub_and_test(bio->bi_vcnt, &fq->nr_submitted)) ++ wake_up(&fq->wait); ++ } ++ ++ bio_put(bio); ++} ++ ++/* Count I/O requests which will be submitted by @bio in given flush queues ++ @fq */ ++void add_fq_to_bio(flush_queue_t *fq, struct bio *bio) ++{ ++ bio->bi_private = fq; ++ bio->bi_end_io = end_io_handler; ++ ++ if (fq) ++ atomic_add(bio->bi_vcnt, &fq->nr_submitted); ++} ++ ++/* Move all queued nodes out from @fq->prepped list. */ ++static void release_prepped_list(flush_queue_t *fq) ++{ ++ txn_atom *atom; ++ ++ assert("zam-904", fq_in_use(fq)); ++ atom = atom_locked_by_fq(fq); ++ ++ while (!list_empty(ATOM_FQ_LIST(fq))) { ++ jnode *cur; ++ ++ cur = list_entry(ATOM_FQ_LIST(fq)->next, jnode, capture_link); ++ list_del_init(&cur->capture_link); ++ ++ count_dequeued_node(fq); ++ spin_lock_jnode(cur); ++ assert("nikita-3154", !JF_ISSET(cur, JNODE_OVRWR)); ++ assert("nikita-3154", JF_ISSET(cur, JNODE_RELOC)); ++ assert("nikita-3154", JF_ISSET(cur, JNODE_FLUSH_QUEUED)); ++ JF_CLR(cur, JNODE_FLUSH_QUEUED); ++ ++ if (JF_ISSET(cur, JNODE_DIRTY)) { ++ list_add_tail(&cur->capture_link, ++ ATOM_DIRTY_LIST(atom, ++ jnode_get_level(cur))); ++ ON_DEBUG(count_jnode(atom, cur, FQ_LIST, ++ DIRTY_LIST, 1)); ++ } else { ++ list_add_tail(&cur->capture_link, ++ ATOM_CLEAN_LIST(atom)); ++ ON_DEBUG(count_jnode(atom, cur, FQ_LIST, ++ CLEAN_LIST, 1)); ++ } ++ ++ spin_unlock_jnode(cur); ++ } ++ ++ if (--atom->nr_running_queues == 0) ++ reiser4_atom_send_event(atom); ++ ++ spin_unlock_atom(atom); ++} ++ ++/* Submit write requests for nodes on the already filled flush queue @fq. ++ ++ @fq: flush queue object which contains jnodes we can (and will) write. ++ @return: number of submitted blocks (>=0) if success, otherwise -- an error ++ code (<0). */ ++int reiser4_write_fq(flush_queue_t *fq, long *nr_submitted, int flags) ++{ ++ int ret; ++ txn_atom *atom; ++ ++ while (1) { ++ atom = atom_locked_by_fq(fq); ++ assert("zam-924", atom); ++ /* do not write fq in parallel. */ ++ if (atom->nr_running_queues == 0 ++ || !(flags & WRITEOUT_SINGLE_STREAM)) ++ break; ++ reiser4_atom_wait_event(atom); ++ } ++ ++ atom->nr_running_queues++; ++ spin_unlock_atom(atom); ++ ++ ret = write_jnode_list(ATOM_FQ_LIST(fq), fq, nr_submitted, flags); ++ release_prepped_list(fq); ++ ++ return ret; ++} ++ ++/* Getting flush queue object for exclusive use by one thread. May require ++ several iterations which is indicated by -E_REPEAT return code. ++ ++ This function does not contain code for obtaining an atom lock because an ++ atom lock is obtained by different ways in different parts of reiser4, ++ usually it is current atom, but we need a possibility for getting fq for the ++ atom of given jnode. */ ++static int fq_by_atom_gfp(txn_atom *atom, flush_queue_t **new_fq, gfp_t gfp) ++{ ++ flush_queue_t *fq; ++ ++ assert_spin_locked(&(atom->alock)); ++ ++ fq = list_entry(atom->flush_queues.next, flush_queue_t, alink); ++ while (&atom->flush_queues != &fq->alink) { ++ spin_lock(&(fq->guard)); ++ ++ if (fq_ready(fq)) { ++ mark_fq_in_use(fq); ++ assert("vs-1246", fq->owner == NULL); ++ ON_DEBUG(fq->owner = current); ++ spin_unlock(&(fq->guard)); ++ ++ if (*new_fq) ++ done_fq(*new_fq); ++ ++ *new_fq = fq; ++ ++ return 0; ++ } ++ ++ spin_unlock(&(fq->guard)); ++ ++ fq = list_entry(fq->alink.next, flush_queue_t, alink); ++ } ++ ++ /* Use previously allocated fq object */ ++ if (*new_fq) { ++ mark_fq_in_use(*new_fq); ++ assert("vs-1248", (*new_fq)->owner == 0); ++ ON_DEBUG((*new_fq)->owner = current); ++ attach_fq(atom, *new_fq); ++ ++ return 0; ++ } ++ ++ spin_unlock_atom(atom); ++ ++ *new_fq = create_fq(gfp); ++ ++ if (*new_fq == NULL) ++ return RETERR(-ENOMEM); ++ ++ return RETERR(-E_REPEAT); ++} ++ ++int reiser4_fq_by_atom(txn_atom * atom, flush_queue_t **new_fq) ++{ ++ return fq_by_atom_gfp(atom, new_fq, reiser4_ctx_gfp_mask_get()); ++} ++ ++/* A wrapper around reiser4_fq_by_atom for getting a flush queue ++ object for current atom, if success fq->atom remains locked. */ ++flush_queue_t *get_fq_for_current_atom(void) ++{ ++ flush_queue_t *fq = NULL; ++ txn_atom *atom; ++ int ret; ++ ++ do { ++ atom = get_current_atom_locked(); ++ ret = reiser4_fq_by_atom(atom, &fq); ++ } while (ret == -E_REPEAT); ++ ++ if (ret) ++ return ERR_PTR(ret); ++ return fq; ++} ++ ++/* Releasing flush queue object after exclusive use */ ++void reiser4_fq_put_nolock(flush_queue_t *fq) ++{ ++ assert("zam-747", fq->atom != NULL); ++ assert("zam-902", list_empty_careful(ATOM_FQ_LIST(fq))); ++ mark_fq_ready(fq); ++ assert("vs-1245", fq->owner == current); ++ ON_DEBUG(fq->owner = NULL); ++} ++ ++void reiser4_fq_put(flush_queue_t *fq) ++{ ++ txn_atom *atom; ++ ++ spin_lock(&(fq->guard)); ++ atom = atom_locked_by_fq_nolock(fq); ++ ++ assert("zam-746", atom != NULL); ++ ++ reiser4_fq_put_nolock(fq); ++ reiser4_atom_send_event(atom); ++ ++ spin_unlock(&(fq->guard)); ++ spin_unlock_atom(atom); ++} ++ ++/* A part of atom object initialization related to the embedded flush queue ++ list head */ ++ ++void init_atom_fq_parts(txn_atom *atom) ++{ ++ INIT_LIST_HEAD(&atom->flush_queues); ++} ++ ++#if REISER4_DEBUG ++ ++void reiser4_check_fq(const txn_atom *atom) ++{ ++ /* check number of nodes on all atom's flush queues */ ++ flush_queue_t *fq; ++ int count; ++ struct list_head *pos; ++ ++ count = 0; ++ list_for_each_entry(fq, &atom->flush_queues, alink) { ++ spin_lock(&(fq->guard)); ++ /* calculate number of jnodes on fq' list of prepped jnodes */ ++ list_for_each(pos, ATOM_FQ_LIST(fq)) ++ count++; ++ spin_unlock(&(fq->guard)); ++ } ++ if (count != atom->fq) ++ warning("", "fq counter %d, real %d\n", atom->fq, count); ++ ++} ++ ++#endif ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/forward.h linux-2.6.30/fs/reiser4/forward.h +--- linux-2.6.30.orig/fs/reiser4/forward.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/forward.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,256 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* Forward declarations. Thank you Kernighan. */ ++ ++#if !defined(__REISER4_FORWARD_H__) ++#define __REISER4_FORWARD_H__ ++ ++#include <asm/errno.h> ++#include <linux/types.h> ++ ++typedef struct zlock zlock; ++typedef struct lock_stack lock_stack; ++typedef struct lock_handle lock_handle; ++typedef struct znode znode; ++typedef struct flow flow_t; ++typedef struct coord coord_t; ++typedef struct tree_access_pointer tap_t; ++typedef struct reiser4_object_create_data reiser4_object_create_data; ++typedef union reiser4_plugin reiser4_plugin; ++typedef __u16 reiser4_plugin_id; ++typedef __u64 reiser4_plugin_groups; ++typedef struct item_plugin item_plugin; ++typedef struct jnode_plugin jnode_plugin; ++typedef struct reiser4_item_data reiser4_item_data; ++typedef union reiser4_key reiser4_key; ++typedef struct reiser4_tree reiser4_tree; ++typedef struct carry_cut_data carry_cut_data; ++typedef struct carry_kill_data carry_kill_data; ++typedef struct carry_tree_op carry_tree_op; ++typedef struct carry_tree_node carry_tree_node; ++typedef struct carry_plugin_info carry_plugin_info; ++typedef struct reiser4_journal reiser4_journal; ++typedef struct txn_atom txn_atom; ++typedef struct txn_handle txn_handle; ++typedef struct txn_mgr txn_mgr; ++typedef struct reiser4_dir_entry_desc reiser4_dir_entry_desc; ++typedef struct reiser4_context reiser4_context; ++typedef struct carry_level carry_level; ++typedef struct blocknr_set_entry blocknr_set_entry; ++/* super_block->s_fs_info points to this */ ++typedef struct reiser4_super_info_data reiser4_super_info_data; ++/* next two objects are fields of reiser4_super_info_data */ ++typedef struct reiser4_oid_allocator reiser4_oid_allocator; ++typedef struct reiser4_space_allocator reiser4_space_allocator; ++ ++typedef struct flush_scan flush_scan; ++typedef struct flush_position flush_pos_t; ++ ++typedef unsigned short pos_in_node_t; ++#define MAX_POS_IN_NODE 65535 ++ ++typedef struct jnode jnode; ++typedef struct reiser4_blocknr_hint reiser4_blocknr_hint; ++ ++typedef struct uf_coord uf_coord_t; ++typedef struct hint hint_t; ++ ++typedef struct ktxnmgrd_context ktxnmgrd_context; ++ ++struct inode; ++struct page; ++struct file; ++struct dentry; ++struct super_block; ++ ++/* return values of coord_by_key(). cbk == coord_by_key */ ++typedef enum { ++ CBK_COORD_FOUND = 0, ++ CBK_COORD_NOTFOUND = -ENOENT, ++} lookup_result; ++ ++/* results of lookup with directory file */ ++typedef enum { ++ FILE_NAME_FOUND = 0, ++ FILE_NAME_NOTFOUND = -ENOENT, ++ FILE_IO_ERROR = -EIO, /* FIXME: it seems silly to have special OOM, ++ IO_ERROR return codes for each search. */ ++ FILE_OOM = -ENOMEM /* FIXME: it seems silly to have special OOM, ++ IO_ERROR return codes for each search. */ ++} file_lookup_result; ++ ++/* behaviors of lookup. If coord we are looking for is actually in a tree, ++ both coincide. */ ++typedef enum { ++ /* search exactly for the coord with key given */ ++ FIND_EXACT, ++ /* search for coord with the maximal key not greater than one ++ given */ ++ FIND_MAX_NOT_MORE_THAN /*LEFT_SLANT_BIAS */ ++} lookup_bias; ++ ++typedef enum { ++ /* number of leaf level of the tree ++ The fake root has (tree_level=0). */ ++ LEAF_LEVEL = 1, ++ ++ /* number of level one above leaf level of the tree. ++ ++ It is supposed that internal tree used by reiser4 to store file ++ system data and meta data will have height 2 initially (when ++ created by mkfs). ++ */ ++ TWIG_LEVEL = 2, ++} tree_level; ++ ++/* The "real" maximum ztree height is the 0-origin size of any per-level ++ array, since the zero'th level is not used. */ ++#define REAL_MAX_ZTREE_HEIGHT (REISER4_MAX_ZTREE_HEIGHT-LEAF_LEVEL) ++ ++/* enumeration of possible mutual position of item and coord. This enum is ++ return type of ->is_in_item() item plugin method which see. */ ++typedef enum { ++ /* coord is on the left of an item */ ++ IP_ON_THE_LEFT, ++ /* coord is inside item */ ++ IP_INSIDE, ++ /* coord is inside item, but to the right of the rightmost unit of ++ this item */ ++ IP_RIGHT_EDGE, ++ /* coord is on the right of an item */ ++ IP_ON_THE_RIGHT ++} interposition; ++ ++/* type of lock to acquire on znode before returning it to caller */ ++typedef enum { ++ ZNODE_NO_LOCK = 0, ++ ZNODE_READ_LOCK = 1, ++ ZNODE_WRITE_LOCK = 2, ++} znode_lock_mode; ++ ++/* type of lock request */ ++typedef enum { ++ ZNODE_LOCK_LOPRI = 0, ++ ZNODE_LOCK_HIPRI = (1 << 0), ++ ++ /* By setting the ZNODE_LOCK_NONBLOCK flag in a lock request the call to ++ longterm_lock_znode will not sleep waiting for the lock to become ++ available. If the lock is unavailable, reiser4_znode_lock will ++ immediately return the value -E_REPEAT. */ ++ ZNODE_LOCK_NONBLOCK = (1 << 1), ++ /* An option for longterm_lock_znode which prevents atom fusion */ ++ ZNODE_LOCK_DONT_FUSE = (1 << 2) ++} znode_lock_request; ++ ++typedef enum { READ_OP = 0, WRITE_OP = 1 } rw_op; ++ ++/* used to specify direction of shift. These must be -1 and 1 */ ++typedef enum { ++ SHIFT_LEFT = 1, ++ SHIFT_RIGHT = -1 ++} shift_direction; ++ ++typedef enum { ++ LEFT_SIDE, ++ RIGHT_SIDE ++} sideof; ++ ++#define round_up(value, order) \ ++ ((typeof(value))(((long) (value) + (order) - 1U) & \ ++ ~((order) - 1))) ++ ++/* values returned by squalloc_right_neighbor and its auxiliary functions */ ++typedef enum { ++ /* unit of internal item is moved */ ++ SUBTREE_MOVED = 0, ++ /* nothing else can be squeezed into left neighbor */ ++ SQUEEZE_TARGET_FULL = 1, ++ /* all content of node is squeezed into its left neighbor */ ++ SQUEEZE_SOURCE_EMPTY = 2, ++ /* one more item is copied (this is only returned by ++ allocate_and_copy_extent to squalloc_twig)) */ ++ SQUEEZE_CONTINUE = 3 ++} squeeze_result; ++ ++/* Do not change items ids. If you do - there will be format change */ ++typedef enum { ++ STATIC_STAT_DATA_ID = 0x0, ++ SIMPLE_DIR_ENTRY_ID = 0x1, ++ COMPOUND_DIR_ID = 0x2, ++ NODE_POINTER_ID = 0x3, ++ EXTENT_POINTER_ID = 0x5, ++ FORMATTING_ID = 0x6, ++ CTAIL_ID = 0x7, ++ BLACK_BOX_ID = 0x8, ++ LAST_ITEM_ID = 0x9 ++} item_id; ++ ++/* Flags passed to jnode_flush() to allow it to distinguish default settings ++ based on whether commit() was called or VM memory pressure was applied. */ ++typedef enum { ++ /* submit flush queue to disk at jnode_flush completion */ ++ JNODE_FLUSH_WRITE_BLOCKS = 1, ++ ++ /* flush is called for commit */ ++ JNODE_FLUSH_COMMIT = 2, ++ /* not implemented */ ++ JNODE_FLUSH_MEMORY_FORMATTED = 4, ++ ++ /* not implemented */ ++ JNODE_FLUSH_MEMORY_UNFORMATTED = 8, ++} jnode_flush_flags; ++ ++/* Flags to insert/paste carry operations. Currently they only used in ++ flushing code, but in future, they can be used to optimize for repetitive ++ accesses. */ ++typedef enum { ++ /* carry is not allowed to shift data to the left when trying to find ++ free space */ ++ COPI_DONT_SHIFT_LEFT = (1 << 0), ++ /* carry is not allowed to shift data to the right when trying to find ++ free space */ ++ COPI_DONT_SHIFT_RIGHT = (1 << 1), ++ /* carry is not allowed to allocate new node(s) when trying to find ++ free space */ ++ COPI_DONT_ALLOCATE = (1 << 2), ++ /* try to load left neighbor if its not in a cache */ ++ COPI_LOAD_LEFT = (1 << 3), ++ /* try to load right neighbor if its not in a cache */ ++ COPI_LOAD_RIGHT = (1 << 4), ++ /* shift insertion point to the left neighbor */ ++ COPI_GO_LEFT = (1 << 5), ++ /* shift insertion point to the right neighbor */ ++ COPI_GO_RIGHT = (1 << 6), ++ /* try to step back into original node if insertion into new node ++ fails after shifting data there. */ ++ COPI_STEP_BACK = (1 << 7) ++} cop_insert_flag; ++ ++typedef enum { ++ SAFE_UNLINK, /* safe-link for unlink */ ++ SAFE_TRUNCATE /* safe-link for truncate */ ++} reiser4_safe_link_t; ++ ++/* this is to show on which list of atom jnode is */ ++typedef enum { ++ NOT_CAPTURED, ++ DIRTY_LIST, ++ CLEAN_LIST, ++ FQ_LIST, ++ WB_LIST, ++ OVRWR_LIST ++} atom_list; ++ ++/* __REISER4_FORWARD_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/fsdata.c linux-2.6.30/fs/reiser4/fsdata.c +--- linux-2.6.30.orig/fs/reiser4/fsdata.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/fsdata.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,804 @@ ++/* Copyright 2001, 2002, 2003, 2004, 2005 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#include "fsdata.h" ++#include "inode.h" ++ ++ ++/* cache or dir_cursors */ ++static struct kmem_cache *d_cursor_cache; ++ ++/* list of unused cursors */ ++static LIST_HEAD(cursor_cache); ++ ++/* number of cursors in list of ununsed cursors */ ++static unsigned long d_cursor_unused = 0; ++ ++/* spinlock protecting manipulations with dir_cursor's hash table and lists */ ++DEFINE_SPINLOCK(d_lock); ++ ++static reiser4_file_fsdata *create_fsdata(struct file *file); ++static int file_is_stateless(struct file *file); ++static void free_fsdata(reiser4_file_fsdata *fsdata); ++static void kill_cursor(dir_cursor *); ++ ++/** ++ * d_cursor_shrink - shrink callback for cache of dir_cursor-s ++ * @nr: number of objects to free ++ * @mask: GFP mask ++ * ++ * Shrinks d_cursor_cache. Scan LRU list of unused cursors, freeing requested ++ * number. Return number of still freeable cursors. ++ */ ++static int d_cursor_shrink(int nr, gfp_t mask) ++{ ++ if (nr != 0) { ++ dir_cursor *scan; ++ int killed; ++ ++ killed = 0; ++ spin_lock(&d_lock); ++ while (!list_empty(&cursor_cache)) { ++ scan = list_entry(cursor_cache.next, dir_cursor, alist); ++ assert("nikita-3567", scan->ref == 0); ++ kill_cursor(scan); ++ ++killed; ++ --nr; ++ if (nr == 0) ++ break; ++ } ++ spin_unlock(&d_lock); ++ } ++ return d_cursor_unused; ++} ++ ++/* ++ * actually, d_cursors are "priceless", because there is no way to ++ * recover information stored in them. On the other hand, we don't ++ * want to consume all kernel memory by them. As a compromise, just ++ * assign higher "seeks" value to d_cursor cache, so that it will be ++ * shrunk only if system is really tight on memory. ++ */ ++static struct shrinker d_cursor_shrinker = { ++ .shrink = d_cursor_shrink, ++ .seeks = DEFAULT_SEEKS << 3, ++}; ++ ++/** ++ * reiser4_init_d_cursor - create d_cursor cache ++ * ++ * Initializes slab cache of d_cursors. It is part of reiser4 module ++ * initialization. ++ */ ++int reiser4_init_d_cursor(void) ++{ ++ d_cursor_cache = kmem_cache_create("d_cursor", sizeof(dir_cursor), 0, ++ SLAB_HWCACHE_ALIGN, NULL); ++ if (d_cursor_cache == NULL) ++ return RETERR(-ENOMEM); ++ ++ register_shrinker(&d_cursor_shrinker); ++ return 0; ++} ++ ++/** ++ * reiser4_done_d_cursor - delete d_cursor cache and d_cursor shrinker ++ * ++ * This is called on reiser4 module unloading or system shutdown. ++ */ ++void reiser4_done_d_cursor(void) ++{ ++ unregister_shrinker(&d_cursor_shrinker); ++ ++ destroy_reiser4_cache(&d_cursor_cache); ++} ++ ++#define D_CURSOR_TABLE_SIZE (256) ++ ++static inline unsigned long ++d_cursor_hash(d_cursor_hash_table * table, const struct d_cursor_key *key) ++{ ++ assert("nikita-3555", IS_POW(D_CURSOR_TABLE_SIZE)); ++ return (key->oid + key->cid) & (D_CURSOR_TABLE_SIZE - 1); ++} ++ ++static inline int d_cursor_eq(const struct d_cursor_key *k1, ++ const struct d_cursor_key *k2) ++{ ++ return k1->cid == k2->cid && k1->oid == k2->oid; ++} ++ ++/* ++ * define functions to manipulate reiser4 super block's hash table of ++ * dir_cursors ++ */ ++#define KMALLOC(size) kmalloc((size), reiser4_ctx_gfp_mask_get()) ++#define KFREE(ptr, size) kfree(ptr) ++TYPE_SAFE_HASH_DEFINE(d_cursor, ++ dir_cursor, ++ struct d_cursor_key, ++ key, hash, d_cursor_hash, d_cursor_eq); ++#undef KFREE ++#undef KMALLOC ++ ++/** ++ * reiser4_init_super_d_info - initialize per-super-block d_cursor resources ++ * @super: super block to initialize ++ * ++ * Initializes per-super-block d_cursor's hash table and radix tree. It is part ++ * of mount. ++ */ ++int reiser4_init_super_d_info(struct super_block *super) ++{ ++ struct d_cursor_info *p; ++ ++ p = &get_super_private(super)->d_info; ++ ++ INIT_RADIX_TREE(&p->tree, reiser4_ctx_gfp_mask_get()); ++ return d_cursor_hash_init(&p->table, D_CURSOR_TABLE_SIZE); ++} ++ ++/** ++ * reiser4_done_super_d_info - release per-super-block d_cursor resources ++ * @super: super block being umounted ++ * ++ * It is called on umount. Kills all directory cursors attached to suoer block. ++ */ ++void reiser4_done_super_d_info(struct super_block *super) ++{ ++ struct d_cursor_info *d_info; ++ dir_cursor *cursor, *next; ++ ++ d_info = &get_super_private(super)->d_info; ++ for_all_in_htable(&d_info->table, d_cursor, cursor, next) ++ kill_cursor(cursor); ++ ++ BUG_ON(d_info->tree.rnode != NULL); ++ d_cursor_hash_done(&d_info->table); ++} ++ ++/** ++ * kill_cursor - free dir_cursor and reiser4_file_fsdata attached to it ++ * @cursor: cursor to free ++ * ++ * Removes reiser4_file_fsdata attached to @cursor from readdir list of ++ * reiser4_inode, frees that reiser4_file_fsdata. Removes @cursor from from ++ * indices, hash table, list of unused cursors and frees it. ++ */ ++static void kill_cursor(dir_cursor *cursor) ++{ ++ unsigned long index; ++ ++ assert("nikita-3566", cursor->ref == 0); ++ assert("nikita-3572", cursor->fsdata != NULL); ++ ++ index = (unsigned long)cursor->key.oid; ++ list_del_init(&cursor->fsdata->dir.linkage); ++ free_fsdata(cursor->fsdata); ++ cursor->fsdata = NULL; ++ ++ if (list_empty_careful(&cursor->list)) ++ /* this is last cursor for a file. Kill radix-tree entry */ ++ radix_tree_delete(&cursor->info->tree, index); ++ else { ++ void **slot; ++ ++ /* ++ * there are other cursors for the same oid. ++ */ ++ ++ /* ++ * if radix tree point to the cursor being removed, re-target ++ * radix tree slot to the next cursor in the (non-empty as was ++ * checked above) element of the circular list of all cursors ++ * for this oid. ++ */ ++ slot = radix_tree_lookup_slot(&cursor->info->tree, index); ++ assert("nikita-3571", *slot != NULL); ++ if (*slot == cursor) ++ *slot = list_entry(cursor->list.next, dir_cursor, list); ++ /* remove cursor from circular list */ ++ list_del_init(&cursor->list); ++ } ++ /* remove cursor from the list of unused cursors */ ++ list_del_init(&cursor->alist); ++ /* remove cursor from the hash table */ ++ d_cursor_hash_remove(&cursor->info->table, cursor); ++ /* and free it */ ++ kmem_cache_free(d_cursor_cache, cursor); ++ --d_cursor_unused; ++} ++ ++/* possible actions that can be performed on all cursors for the given file */ ++enum cursor_action { ++ /* ++ * load all detached state: this is called when stat-data is loaded ++ * from the disk to recover information about all pending readdirs ++ */ ++ CURSOR_LOAD, ++ /* ++ * detach all state from inode, leaving it in the cache. This is called ++ * when inode is removed form the memory by memory pressure ++ */ ++ CURSOR_DISPOSE, ++ /* ++ * detach cursors from the inode, and free them. This is called when ++ * inode is destroyed ++ */ ++ CURSOR_KILL ++}; ++ ++/* ++ * return d_cursor data for the file system @inode is in. ++ */ ++static inline struct d_cursor_info *d_info(struct inode *inode) ++{ ++ return &get_super_private(inode->i_sb)->d_info; ++} ++ ++/* ++ * lookup d_cursor in the per-super-block radix tree. ++ */ ++static inline dir_cursor *lookup(struct d_cursor_info *info, ++ unsigned long index) ++{ ++ return (dir_cursor *) radix_tree_lookup(&info->tree, index); ++} ++ ++/* ++ * attach @cursor to the radix tree. There may be multiple cursors for the ++ * same oid, they are chained into circular list. ++ */ ++static void bind_cursor(dir_cursor * cursor, unsigned long index) ++{ ++ dir_cursor *head; ++ ++ head = lookup(cursor->info, index); ++ if (head == NULL) { ++ /* this is the first cursor for this index */ ++ INIT_LIST_HEAD(&cursor->list); ++ radix_tree_insert(&cursor->info->tree, index, cursor); ++ } else { ++ /* some cursor already exists. Chain ours */ ++ list_add(&cursor->list, &head->list); ++ } ++} ++ ++/* ++ * detach fsdata (if detachable) from file descriptor, and put cursor on the ++ * "unused" list. Called when file descriptor is not longer in active use. ++ */ ++static void clean_fsdata(struct file *file) ++{ ++ dir_cursor *cursor; ++ reiser4_file_fsdata *fsdata; ++ ++ assert("nikita-3570", file_is_stateless(file)); ++ ++ fsdata = (reiser4_file_fsdata *) file->private_data; ++ if (fsdata != NULL) { ++ cursor = fsdata->cursor; ++ if (cursor != NULL) { ++ spin_lock(&d_lock); ++ --cursor->ref; ++ if (cursor->ref == 0) { ++ list_add_tail(&cursor->alist, &cursor_cache); ++ ++d_cursor_unused; ++ } ++ spin_unlock(&d_lock); ++ file->private_data = NULL; ++ } ++ } ++} ++ ++/* ++ * global counter used to generate "client ids". These ids are encoded into ++ * high bits of fpos. ++ */ ++static __u32 cid_counter = 0; ++#define CID_SHIFT (20) ++#define CID_MASK (0xfffffull) ++ ++static void free_file_fsdata_nolock(struct file *); ++ ++/** ++ * insert_cursor - allocate file_fsdata, insert cursor to tree and hash table ++ * @cursor: ++ * @file: ++ * @inode: ++ * ++ * Allocates reiser4_file_fsdata, attaches it to @cursor, inserts cursor to ++ * reiser4 super block's hash table and radix tree. ++ add detachable readdir ++ * state to the @f ++ */ ++static int insert_cursor(dir_cursor *cursor, struct file *file, ++ struct inode *inode) ++{ ++ int result; ++ reiser4_file_fsdata *fsdata; ++ ++ memset(cursor, 0, sizeof *cursor); ++ ++ /* this is either first call to readdir, or rewind. Anyway, create new ++ * cursor. */ ++ fsdata = create_fsdata(NULL); ++ if (fsdata != NULL) { ++ result = radix_tree_preload(reiser4_ctx_gfp_mask_get()); ++ if (result == 0) { ++ struct d_cursor_info *info; ++ oid_t oid; ++ ++ info = d_info(inode); ++ oid = get_inode_oid(inode); ++ /* cid occupies higher 12 bits of f->f_pos. Don't ++ * allow it to become negative: this confuses ++ * nfsd_readdir() */ ++ cursor->key.cid = (++cid_counter) & 0x7ff; ++ cursor->key.oid = oid; ++ cursor->fsdata = fsdata; ++ cursor->info = info; ++ cursor->ref = 1; ++ ++ spin_lock_inode(inode); ++ /* install cursor as @f's private_data, discarding old ++ * one if necessary */ ++#if REISER4_DEBUG ++ if (file->private_data) ++ warning("", "file has fsdata already"); ++#endif ++ clean_fsdata(file); ++ free_file_fsdata_nolock(file); ++ file->private_data = fsdata; ++ fsdata->cursor = cursor; ++ spin_unlock_inode(inode); ++ spin_lock(&d_lock); ++ /* insert cursor into hash table */ ++ d_cursor_hash_insert(&info->table, cursor); ++ /* and chain it into radix-tree */ ++ bind_cursor(cursor, (unsigned long)oid); ++ spin_unlock(&d_lock); ++ radix_tree_preload_end(); ++ file->f_pos = ((__u64) cursor->key.cid) << CID_SHIFT; ++ } ++ } else ++ result = RETERR(-ENOMEM); ++ return result; ++} ++ ++/** ++ * process_cursors - do action on each cursor attached to inode ++ * @inode: ++ * @act: action to do ++ * ++ * Finds all cursors of @inode in reiser4's super block radix tree of cursors ++ * and performs action specified by @act on each of cursors. ++ */ ++static void process_cursors(struct inode *inode, enum cursor_action act) ++{ ++ oid_t oid; ++ dir_cursor *start; ++ struct list_head *head; ++ reiser4_context *ctx; ++ struct d_cursor_info *info; ++ ++ /* this can be called by ++ * ++ * kswapd->...->prune_icache->..reiser4_destroy_inode ++ * ++ * without reiser4_context ++ */ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) { ++ warning("vs-23", "failed to init context"); ++ return; ++ } ++ ++ assert("nikita-3558", inode != NULL); ++ ++ info = d_info(inode); ++ oid = get_inode_oid(inode); ++ spin_lock_inode(inode); ++ head = get_readdir_list(inode); ++ spin_lock(&d_lock); ++ /* find any cursor for this oid: reference to it is hanging of radix ++ * tree */ ++ start = lookup(info, (unsigned long)oid); ++ if (start != NULL) { ++ dir_cursor *scan; ++ reiser4_file_fsdata *fsdata; ++ ++ /* process circular list of cursors for this oid */ ++ scan = start; ++ do { ++ dir_cursor *next; ++ ++ next = list_entry(scan->list.next, dir_cursor, list); ++ fsdata = scan->fsdata; ++ assert("nikita-3557", fsdata != NULL); ++ if (scan->key.oid == oid) { ++ switch (act) { ++ case CURSOR_DISPOSE: ++ list_del_init(&fsdata->dir.linkage); ++ break; ++ case CURSOR_LOAD: ++ list_add(&fsdata->dir.linkage, head); ++ break; ++ case CURSOR_KILL: ++ kill_cursor(scan); ++ break; ++ } ++ } ++ if (scan == next) ++ /* last cursor was just killed */ ++ break; ++ scan = next; ++ } while (scan != start); ++ } ++ spin_unlock(&d_lock); ++ /* check that we killed 'em all */ ++ assert("nikita-3568", ++ ergo(act == CURSOR_KILL, ++ list_empty_careful(get_readdir_list(inode)))); ++ assert("nikita-3569", ++ ergo(act == CURSOR_KILL, lookup(info, oid) == NULL)); ++ spin_unlock_inode(inode); ++ reiser4_exit_context(ctx); ++} ++ ++/** ++ * reiser4_dispose_cursors - removes cursors from inode's list ++ * @inode: inode to dispose cursors of ++ * ++ * For each of cursors corresponding to @inode - removes reiser4_file_fsdata ++ * attached to cursor from inode's readdir list. This is called when inode is ++ * removed from the memory by memory pressure. ++ */ ++void reiser4_dispose_cursors(struct inode *inode) ++{ ++ process_cursors(inode, CURSOR_DISPOSE); ++} ++ ++/** ++ * reiser4_load_cursors - attach cursors to inode ++ * @inode: inode to load cursors to ++ * ++ * For each of cursors corresponding to @inode - attaches reiser4_file_fsdata ++ * attached to cursor to inode's readdir list. This is done when inode is ++ * loaded into memory. ++ */ ++void reiser4_load_cursors(struct inode *inode) ++{ ++ process_cursors(inode, CURSOR_LOAD); ++} ++ ++/** ++ * reiser4_kill_cursors - kill all inode cursors ++ * @inode: inode to kill cursors of ++ * ++ * Frees all cursors for this inode. This is called when inode is destroyed. ++ */ ++void reiser4_kill_cursors(struct inode *inode) ++{ ++ process_cursors(inode, CURSOR_KILL); ++} ++ ++/** ++ * file_is_stateless - ++ * @file: ++ * ++ * true, if file descriptor @f is created by NFS server by "demand" to serve ++ * one file system operation. This means that there may be "detached state" ++ * for underlying inode. ++ */ ++static int file_is_stateless(struct file *file) ++{ ++ return reiser4_get_dentry_fsdata(file->f_dentry)->stateless; ++} ++ ++/** ++ * reiser4_get_dir_fpos - ++ * @dir: ++ * ++ * Calculates ->fpos from user-supplied cookie. Normally it is dir->f_pos, but ++ * in the case of stateless directory operation (readdir-over-nfs), client id ++ * was encoded in the high bits of cookie and should me masked off. ++ */ ++loff_t reiser4_get_dir_fpos(struct file *dir) ++{ ++ if (file_is_stateless(dir)) ++ return dir->f_pos & CID_MASK; ++ else ++ return dir->f_pos; ++} ++ ++/** ++ * reiser4_attach_fsdata - try to attach fsdata ++ * @file: ++ * @inode: ++ * ++ * Finds or creates cursor for readdir-over-nfs. ++ */ ++int reiser4_attach_fsdata(struct file *file, struct inode *inode) ++{ ++ loff_t pos; ++ int result; ++ dir_cursor *cursor; ++ ++ /* ++ * we are serialized by inode->i_mutex ++ */ ++ if (!file_is_stateless(file)) ++ return 0; ++ ++ pos = file->f_pos; ++ result = 0; ++ if (pos == 0) { ++ /* ++ * first call to readdir (or rewind to the beginning of ++ * directory) ++ */ ++ cursor = kmem_cache_alloc(d_cursor_cache, ++ reiser4_ctx_gfp_mask_get()); ++ if (cursor != NULL) ++ result = insert_cursor(cursor, file, inode); ++ else ++ result = RETERR(-ENOMEM); ++ } else { ++ /* try to find existing cursor */ ++ struct d_cursor_key key; ++ ++ key.cid = pos >> CID_SHIFT; ++ key.oid = get_inode_oid(inode); ++ spin_lock(&d_lock); ++ cursor = d_cursor_hash_find(&d_info(inode)->table, &key); ++ if (cursor != NULL) { ++ /* cursor was found */ ++ if (cursor->ref == 0) { ++ /* move it from unused list */ ++ list_del_init(&cursor->alist); ++ --d_cursor_unused; ++ } ++ ++cursor->ref; ++ } ++ spin_unlock(&d_lock); ++ if (cursor != NULL) { ++ spin_lock_inode(inode); ++ assert("nikita-3556", cursor->fsdata->back == NULL); ++ clean_fsdata(file); ++ free_file_fsdata_nolock(file); ++ file->private_data = cursor->fsdata; ++ spin_unlock_inode(inode); ++ } ++ } ++ return result; ++} ++ ++/** ++ * reiser4_detach_fsdata - ??? ++ * @file: ++ * ++ * detach fsdata, if necessary ++ */ ++void reiser4_detach_fsdata(struct file *file) ++{ ++ struct inode *inode; ++ ++ if (!file_is_stateless(file)) ++ return; ++ ++ inode = file->f_dentry->d_inode; ++ spin_lock_inode(inode); ++ clean_fsdata(file); ++ spin_unlock_inode(inode); ++} ++ ++/* slab for reiser4_dentry_fsdata */ ++static struct kmem_cache *dentry_fsdata_cache; ++ ++/** ++ * reiser4_init_dentry_fsdata - create cache of dentry_fsdata ++ * ++ * Initializes slab cache of structures attached to denty->d_fsdata. It is ++ * part of reiser4 module initialization. ++ */ ++int reiser4_init_dentry_fsdata(void) ++{ ++ dentry_fsdata_cache = kmem_cache_create("dentry_fsdata", ++ sizeof(struct reiser4_dentry_fsdata), ++ 0, ++ SLAB_HWCACHE_ALIGN | ++ SLAB_RECLAIM_ACCOUNT, ++ NULL); ++ if (dentry_fsdata_cache == NULL) ++ return RETERR(-ENOMEM); ++ return 0; ++} ++ ++/** ++ * reiser4_done_dentry_fsdata - delete cache of dentry_fsdata ++ * ++ * This is called on reiser4 module unloading or system shutdown. ++ */ ++void reiser4_done_dentry_fsdata(void) ++{ ++ destroy_reiser4_cache(&dentry_fsdata_cache); ++} ++ ++/** ++ * reiser4_get_dentry_fsdata - get fs-specific dentry data ++ * @dentry: queried dentry ++ * ++ * Allocates if necessary and returns per-dentry data that we attach to each ++ * dentry. ++ */ ++struct reiser4_dentry_fsdata *reiser4_get_dentry_fsdata(struct dentry *dentry) ++{ ++ assert("nikita-1365", dentry != NULL); ++ ++ if (dentry->d_fsdata == NULL) { ++ dentry->d_fsdata = kmem_cache_alloc(dentry_fsdata_cache, ++ reiser4_ctx_gfp_mask_get()); ++ if (dentry->d_fsdata == NULL) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ memset(dentry->d_fsdata, 0, ++ sizeof(struct reiser4_dentry_fsdata)); ++ } ++ return dentry->d_fsdata; ++} ++ ++/** ++ * reiser4_free_dentry_fsdata - detach and free dentry_fsdata ++ * @dentry: dentry to free fsdata of ++ * ++ * Detaches and frees fs-specific dentry data ++ */ ++void reiser4_free_dentry_fsdata(struct dentry *dentry) ++{ ++ if (dentry->d_fsdata != NULL) { ++ kmem_cache_free(dentry_fsdata_cache, dentry->d_fsdata); ++ dentry->d_fsdata = NULL; ++ } ++} ++ ++/* slab for reiser4_file_fsdata */ ++static struct kmem_cache *file_fsdata_cache; ++ ++/** ++ * reiser4_init_file_fsdata - create cache of reiser4_file_fsdata ++ * ++ * Initializes slab cache of structures attached to file->private_data. It is ++ * part of reiser4 module initialization. ++ */ ++int reiser4_init_file_fsdata(void) ++{ ++ file_fsdata_cache = kmem_cache_create("file_fsdata", ++ sizeof(reiser4_file_fsdata), ++ 0, ++ SLAB_HWCACHE_ALIGN | ++ SLAB_RECLAIM_ACCOUNT, NULL); ++ if (file_fsdata_cache == NULL) ++ return RETERR(-ENOMEM); ++ return 0; ++} ++ ++/** ++ * reiser4_done_file_fsdata - delete cache of reiser4_file_fsdata ++ * ++ * This is called on reiser4 module unloading or system shutdown. ++ */ ++void reiser4_done_file_fsdata(void) ++{ ++ destroy_reiser4_cache(&file_fsdata_cache); ++} ++ ++/** ++ * create_fsdata - allocate and initialize reiser4_file_fsdata ++ * @file: what to create file_fsdata for, may be NULL ++ * ++ * Allocates and initializes reiser4_file_fsdata structure. ++ */ ++static reiser4_file_fsdata *create_fsdata(struct file *file) ++{ ++ reiser4_file_fsdata *fsdata; ++ ++ fsdata = kmem_cache_alloc(file_fsdata_cache, ++ reiser4_ctx_gfp_mask_get()); ++ if (fsdata != NULL) { ++ memset(fsdata, 0, sizeof *fsdata); ++ fsdata->ra1.max_window_size = VM_MAX_READAHEAD * 1024; ++ fsdata->back = file; ++ INIT_LIST_HEAD(&fsdata->dir.linkage); ++ } ++ return fsdata; ++} ++ ++/** ++ * free_fsdata - free reiser4_file_fsdata ++ * @fsdata: object to free ++ * ++ * Dual to create_fsdata(). Free reiser4_file_fsdata. ++ */ ++static void free_fsdata(reiser4_file_fsdata *fsdata) ++{ ++ BUG_ON(fsdata == NULL); ++ kmem_cache_free(file_fsdata_cache, fsdata); ++} ++ ++/** ++ * reiser4_get_file_fsdata - get fs-specific file data ++ * @file: queried file ++ * ++ * Returns fs-specific data of @file. If it is NULL, allocates it and attaches ++ * to @file. ++ */ ++reiser4_file_fsdata *reiser4_get_file_fsdata(struct file *file) ++{ ++ assert("nikita-1603", file != NULL); ++ ++ if (file->private_data == NULL) { ++ reiser4_file_fsdata *fsdata; ++ struct inode *inode; ++ ++ fsdata = create_fsdata(file); ++ if (fsdata == NULL) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ ++ inode = file->f_dentry->d_inode; ++ spin_lock_inode(inode); ++ if (file->private_data == NULL) { ++ file->private_data = fsdata; ++ fsdata = NULL; ++ } ++ spin_unlock_inode(inode); ++ if (fsdata != NULL) ++ /* other thread initialized ->fsdata */ ++ kmem_cache_free(file_fsdata_cache, fsdata); ++ } ++ assert("nikita-2665", file->private_data != NULL); ++ return file->private_data; ++} ++ ++/** ++ * free_file_fsdata_nolock - detach and free reiser4_file_fsdata ++ * @file: ++ * ++ * Detaches reiser4_file_fsdata from @file, removes reiser4_file_fsdata from ++ * readdir list, frees if it is not linked to d_cursor object. ++ */ ++static void free_file_fsdata_nolock(struct file *file) ++{ ++ reiser4_file_fsdata *fsdata; ++ ++ assert("", spin_inode_is_locked(file->f_dentry->d_inode)); ++ fsdata = file->private_data; ++ if (fsdata != NULL) { ++ list_del_init(&fsdata->dir.linkage); ++ if (fsdata->cursor == NULL) ++ free_fsdata(fsdata); ++ } ++ file->private_data = NULL; ++} ++ ++/** ++ * reiser4_free_file_fsdata - detach from struct file and free reiser4_file_fsdata ++ * @file: ++ * ++ * Spinlocks inode and calls free_file_fsdata_nolock to do the work. ++ */ ++void reiser4_free_file_fsdata(struct file *file) ++{ ++ spin_lock_inode(file->f_dentry->d_inode); ++ free_file_fsdata_nolock(file); ++ spin_unlock_inode(file->f_dentry->d_inode); ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/fsdata.h linux-2.6.30/fs/reiser4/fsdata.h +--- linux-2.6.30.orig/fs/reiser4/fsdata.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/fsdata.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,205 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#if !defined(__REISER4_FSDATA_H__) ++#define __REISER4_FSDATA_H__ ++ ++#include "debug.h" ++#include "kassign.h" ++#include "seal.h" ++#include "type_safe_hash.h" ++#include "plugin/file/file.h" ++#include "readahead.h" ++ ++/* ++ * comment about reiser4_dentry_fsdata ++ * ++ * ++ */ ++ ++/* ++ * locking: fields of per file descriptor readdir_pos and ->f_pos are ++ * protected by ->i_mutex on inode. Under this lock following invariant ++ * holds: ++ * ++ * file descriptor is "looking" at the entry_no-th directory entry from ++ * the beginning of directory. This entry has key dir_entry_key and is ++ * pos-th entry with duplicate-key sequence. ++ * ++ */ ++ ++/* logical position within directory */ ++struct dir_pos { ++ /* key of directory entry (actually, part of a key sufficient to ++ identify directory entry) */ ++ de_id dir_entry_key; ++ /* ordinal number of directory entry among all entries with the same ++ key. (Starting from 0.) */ ++ unsigned pos; ++}; ++ ++struct readdir_pos { ++ /* f_pos corresponding to this readdir position */ ++ __u64 fpos; ++ /* logical position within directory */ ++ struct dir_pos position; ++ /* logical number of directory entry within ++ directory */ ++ __u64 entry_no; ++}; ++ ++/* ++ * this is used to speed up lookups for directory entry: on initial call to ++ * ->lookup() seal and coord of directory entry (if found, that is) are stored ++ * in struct dentry and reused later to avoid tree traversals. ++ */ ++struct de_location { ++ /* seal covering directory entry */ ++ seal_t entry_seal; ++ /* coord of directory entry */ ++ coord_t entry_coord; ++ /* ordinal number of directory entry among all entries with the same ++ key. (Starting from 0.) */ ++ int pos; ++}; ++ ++/** ++ * reiser4_dentry_fsdata - reiser4-specific data attached to dentries ++ * ++ * This is allocated dynamically and released in d_op->d_release() ++ * ++ * Currently it only contains cached location (hint) of directory entry, but ++ * it is expected that other information will be accumulated here. ++ */ ++struct reiser4_dentry_fsdata { ++ /* ++ * here will go fields filled by ->lookup() to speedup next ++ * create/unlink, like blocknr of znode with stat-data, or key of ++ * stat-data. ++ */ ++ struct de_location dec; ++ int stateless; /* created through reiser4_decode_fh, needs ++ * special treatment in readdir. */ ++}; ++ ++extern int reiser4_init_dentry_fsdata(void); ++extern void reiser4_done_dentry_fsdata(void); ++extern struct reiser4_dentry_fsdata *reiser4_get_dentry_fsdata(struct dentry *); ++extern void reiser4_free_dentry_fsdata(struct dentry *dentry); ++ ++/** ++ * reiser4_file_fsdata - reiser4-specific data attached to file->private_data ++ * ++ * This is allocated dynamically and released in inode->i_fop->release ++ */ ++typedef struct reiser4_file_fsdata { ++ /* ++ * pointer back to the struct file which this reiser4_file_fsdata is ++ * part of ++ */ ++ struct file *back; ++ /* detached cursor for stateless readdir. */ ++ struct dir_cursor *cursor; ++ /* ++ * We need both directory and regular file parts here, because there ++ * are file system objects that are files and directories. ++ */ ++ struct { ++ /* ++ * position in directory. It is updated each time directory is ++ * modified ++ */ ++ struct readdir_pos readdir; ++ /* head of this list is reiser4_inode->lists.readdir_list */ ++ struct list_head linkage; ++ } dir; ++ /* hints to speed up operations with regular files: read and write. */ ++ struct { ++ hint_t hint; ++ } reg; ++ struct reiser4_file_ra_state ra1; ++ ++} reiser4_file_fsdata; ++ ++extern int reiser4_init_file_fsdata(void); ++extern void reiser4_done_file_fsdata(void); ++extern reiser4_file_fsdata *reiser4_get_file_fsdata(struct file *); ++extern void reiser4_free_file_fsdata(struct file *); ++ ++/* ++ * d_cursor is reiser4_file_fsdata not attached to struct file. d_cursors are ++ * used to address problem reiser4 has with readdir accesses via NFS. See ++ * plugin/file_ops_readdir.c for more details. ++ */ ++struct d_cursor_key{ ++ __u16 cid; ++ __u64 oid; ++}; ++ ++/* ++ * define structures d_cursor_hash_table d_cursor_hash_link which are used to ++ * maintain hash table of dir_cursor-s in reiser4's super block ++ */ ++typedef struct dir_cursor dir_cursor; ++TYPE_SAFE_HASH_DECLARE(d_cursor, dir_cursor); ++ ++struct dir_cursor { ++ int ref; ++ reiser4_file_fsdata *fsdata; ++ ++ /* link to reiser4 super block hash table of cursors */ ++ d_cursor_hash_link hash; ++ ++ /* ++ * this is to link cursors to reiser4 super block's radix tree of ++ * cursors if there are more than one cursor of the same objectid ++ */ ++ struct list_head list; ++ struct d_cursor_key key; ++ struct d_cursor_info *info; ++ /* list of unused cursors */ ++ struct list_head alist; ++}; ++ ++extern int reiser4_init_d_cursor(void); ++extern void reiser4_done_d_cursor(void); ++ ++extern int reiser4_init_super_d_info(struct super_block *); ++extern void reiser4_done_super_d_info(struct super_block *); ++ ++extern loff_t reiser4_get_dir_fpos(struct file *); ++extern int reiser4_attach_fsdata(struct file *, struct inode *); ++extern void reiser4_detach_fsdata(struct file *); ++ ++/* these are needed for "stateless" readdir. See plugin/file_ops_readdir.c for ++ more details */ ++void reiser4_dispose_cursors(struct inode *inode); ++void reiser4_load_cursors(struct inode *inode); ++void reiser4_kill_cursors(struct inode *inode); ++void reiser4_adjust_dir_file(struct inode *dir, const struct dentry *de, ++ int offset, int adj); ++ ++/* ++ * this structure is embedded to reise4_super_info_data. It maintains d_cursors ++ * (detached readdir state). See plugin/file_ops_readdir.c for more details. ++ */ ++struct d_cursor_info { ++ d_cursor_hash_table table; ++ struct radix_tree_root tree; ++}; ++ ++/* spinlock protecting readdir cursors */ ++extern spinlock_t d_lock; ++ ++/* __REISER4_FSDATA_H__ */ ++#endif ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 120 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/init_super.c linux-2.6.30/fs/reiser4/init_super.c +--- linux-2.6.30.orig/fs/reiser4/init_super.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/init_super.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,751 @@ ++/* Copyright by Hans Reiser, 2003 */ ++ ++#include "super.h" ++#include "inode.h" ++#include "plugin/plugin_set.h" ++ ++#include <linux/swap.h> ++ ++/** ++ * init_fs_info - allocate reiser4 specific super block ++ * @super: super block of filesystem ++ * ++ * Allocates and initialize reiser4_super_info_data, attaches it to ++ * super->s_fs_info, initializes structures maintaining d_cursor-s. ++ */ ++int reiser4_init_fs_info(struct super_block *super) ++{ ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = kzalloc(sizeof(reiser4_super_info_data), ++ reiser4_ctx_gfp_mask_get()); ++ if (!sbinfo) ++ return RETERR(-ENOMEM); ++ ++ super->s_fs_info = sbinfo; ++ super->s_op = NULL; ++ ++ ON_DEBUG(INIT_LIST_HEAD(&sbinfo->all_jnodes)); ++ ON_DEBUG(spin_lock_init(&sbinfo->all_guard)); ++ ++ mutex_init(&sbinfo->delete_mutex); ++ spin_lock_init(&(sbinfo->guard)); ++ ++ /* initialize per-super-block d_cursor resources */ ++ reiser4_init_super_d_info(super); ++ ++ return 0; ++} ++ ++/** ++ * reiser4_done_fs_info - free reiser4 specific super block ++ * @super: super block of filesystem ++ * ++ * Performs some sanity checks, releases structures maintaining d_cursor-s, ++ * frees reiser4_super_info_data. ++ */ ++void reiser4_done_fs_info(struct super_block *super) ++{ ++ assert("zam-990", super->s_fs_info != NULL); ++ ++ /* release per-super-block d_cursor resources */ ++ reiser4_done_super_d_info(super); ++ ++ /* make sure that there are not jnodes already */ ++ assert("", list_empty(&get_super_private(super)->all_jnodes)); ++ assert("", get_current_context()->trans->atom == NULL); ++ reiser4_check_block_counters(super); ++ kfree(super->s_fs_info); ++ super->s_fs_info = NULL; ++} ++ ++/* type of option parseable by parse_option() */ ++typedef enum { ++ /* value of option is arbitrary string */ ++ OPT_STRING, ++ ++ /* ++ * option specifies bit in a bitmask. When option is set - bit in ++ * sbinfo->fs_flags is set. Examples are bsdgroups, 32bittimes, mtflush, ++ * dont_load_bitmap, atomic_write. ++ */ ++ OPT_BIT, ++ ++ /* ++ * value of option should conform to sprintf() format. Examples are ++ * tmgr.atom_max_size=N, tmgr.atom_max_age=N ++ */ ++ OPT_FORMAT, ++ ++ /* ++ * option can take one of predefined values. Example is onerror=panic or ++ * onerror=remount-ro ++ */ ++ OPT_ONEOF, ++} opt_type_t; ++ ++#if 0 ++struct opt_bitmask_bit { ++ const char *bit_name; ++ int bit_nr; ++}; ++#endif ++ ++/* description of option parseable by parse_option() */ ++struct opt_desc { ++ /* option name. ++ ++ parsed portion of string has a form "name=value". ++ */ ++ const char *name; ++ /* type of option */ ++ opt_type_t type; ++ union { ++ /* where to store value of string option (type == OPT_STRING) */ ++ char **string; ++ /* description of bits for bit option (type == OPT_BIT) */ ++ struct { ++ int nr; ++ void *addr; ++ } bit; ++ /* description of format and targets for format option (type ++ == OPT_FORMAT) */ ++ struct { ++ const char *format; ++ int nr_args; ++ void *arg1; ++ void *arg2; ++ void *arg3; ++ void *arg4; ++ } f; ++ struct { ++ int *result; ++ const char *list[10]; ++ } oneof; ++ struct { ++ void *addr; ++ int nr_bits; ++ /* struct opt_bitmask_bit *bits; */ ++ } bitmask; ++ } u; ++}; ++ ++/** ++ * parse_option - parse one option ++ * @opt_strin: starting point of parsing ++ * @opt: option description ++ * ++ * foo=bar, ++ * ^ ^ ^ ++ * | | +-- replaced to '\0' ++ * | +-- val_start ++ * +-- opt_string ++ * Figures out option type and handles option correspondingly. ++ */ ++static int parse_option(char *opt_string, struct opt_desc *opt) ++{ ++ char *val_start; ++ int result; ++ const char *err_msg; ++ ++ /* NOTE-NIKITA think about using lib/cmdline.c functions here. */ ++ ++ val_start = strchr(opt_string, '='); ++ if (val_start != NULL) { ++ *val_start = '\0'; ++ ++val_start; ++ } ++ ++ err_msg = NULL; ++ result = 0; ++ switch (opt->type) { ++ case OPT_STRING: ++ if (val_start == NULL) { ++ err_msg = "String arg missing"; ++ result = RETERR(-EINVAL); ++ } else ++ *opt->u.string = val_start; ++ break; ++ case OPT_BIT: ++ if (val_start != NULL) ++ err_msg = "Value ignored"; ++ else ++ set_bit(opt->u.bit.nr, opt->u.bit.addr); ++ break; ++ case OPT_FORMAT: ++ if (val_start == NULL) { ++ err_msg = "Formatted arg missing"; ++ result = RETERR(-EINVAL); ++ break; ++ } ++ if (sscanf(val_start, opt->u.f.format, ++ opt->u.f.arg1, opt->u.f.arg2, opt->u.f.arg3, ++ opt->u.f.arg4) != opt->u.f.nr_args) { ++ err_msg = "Wrong conversion"; ++ result = RETERR(-EINVAL); ++ } ++ break; ++ case OPT_ONEOF: ++ { ++ int i = 0; ++ ++ if (val_start == NULL) { ++ err_msg = "Value is missing"; ++ result = RETERR(-EINVAL); ++ break; ++ } ++ err_msg = "Wrong option value"; ++ result = RETERR(-EINVAL); ++ while (opt->u.oneof.list[i]) { ++ if (!strcmp(opt->u.oneof.list[i], val_start)) { ++ result = 0; ++ err_msg = NULL; ++ *opt->u.oneof.result = i; ++ break; ++ } ++ i++; ++ } ++ break; ++ } ++ default: ++ wrong_return_value("nikita-2100", "opt -> type"); ++ break; ++ } ++ if (err_msg != NULL) { ++ warning("nikita-2496", "%s when parsing option "%s%s%s"", ++ err_msg, opt->name, val_start ? "=" : "", ++ val_start ? : ""); ++ } ++ return result; ++} ++ ++/** ++ * parse_options - parse reiser4 mount options ++ * @opt_string: starting point ++ * @opts: array of option description ++ * @nr_opts: number of elements in @opts ++ * ++ * Parses comma separated list of reiser4 mount options. ++ */ ++static int parse_options(char *opt_string, struct opt_desc *opts, int nr_opts) ++{ ++ int result; ++ ++ result = 0; ++ while ((result == 0) && opt_string && *opt_string) { ++ int j; ++ char *next; ++ ++ next = strchr(opt_string, ','); ++ if (next != NULL) { ++ *next = '\0'; ++ ++next; ++ } ++ for (j = 0; j < nr_opts; ++j) { ++ if (!strncmp(opt_string, opts[j].name, ++ strlen(opts[j].name))) { ++ result = parse_option(opt_string, &opts[j]); ++ break; ++ } ++ } ++ if (j == nr_opts) { ++ warning("nikita-2307", "Unrecognized option: "%s"", ++ opt_string); ++ /* traditionally, -EINVAL is returned on wrong mount ++ option */ ++ result = RETERR(-EINVAL); ++ } ++ opt_string = next; ++ } ++ return result; ++} ++ ++#define NUM_OPT(label, fmt, addr) \ ++ { \ ++ .name = (label), \ ++ .type = OPT_FORMAT, \ ++ .u = { \ ++ .f = { \ ++ .format = (fmt), \ ++ .nr_args = 1, \ ++ .arg1 = (addr), \ ++ .arg2 = NULL, \ ++ .arg3 = NULL, \ ++ .arg4 = NULL \ ++ } \ ++ } \ ++ } ++ ++#define SB_FIELD_OPT(field, fmt) NUM_OPT(#field, fmt, &sbinfo->field) ++ ++#define BIT_OPT(label, bitnr) \ ++ { \ ++ .name = label, \ ++ .type = OPT_BIT, \ ++ .u = { \ ++ .bit = { \ ++ .nr = bitnr, \ ++ .addr = &sbinfo->fs_flags \ ++ } \ ++ } \ ++ } ++ ++#define MAX_NR_OPTIONS (30) ++ ++/** ++ * reiser4_init_super_data - initialize reiser4 private super block ++ * @super: super block to initialize ++ * @opt_string: list of reiser4 mount options ++ * ++ * Sets various reiser4 parameters to default values. Parses mount options and ++ * overwrites default settings. ++ */ ++int reiser4_init_super_data(struct super_block *super, char *opt_string) ++{ ++ int result; ++ struct opt_desc *opts, *p; ++ reiser4_super_info_data *sbinfo = get_super_private(super); ++ ++ /* initialize super, export, dentry operations */ ++ sbinfo->ops.super = reiser4_super_operations; ++ sbinfo->ops.export = reiser4_export_operations; ++ sbinfo->ops.dentry = reiser4_dentry_operations; ++ super->s_op = &sbinfo->ops.super; ++ super->s_export_op = &sbinfo->ops.export; ++ ++ /* initialize transaction manager parameters to default values */ ++ sbinfo->tmgr.atom_max_size = totalram_pages / 4; ++ sbinfo->tmgr.atom_max_age = REISER4_ATOM_MAX_AGE / HZ; ++ sbinfo->tmgr.atom_min_size = 256; ++ sbinfo->tmgr.atom_max_flushers = ATOM_MAX_FLUSHERS; ++ ++ /* initialize cbk cache parameter */ ++ sbinfo->tree.cbk_cache.nr_slots = CBK_CACHE_SLOTS; ++ ++ /* initialize flush parameters */ ++ sbinfo->flush.relocate_threshold = FLUSH_RELOCATE_THRESHOLD; ++ sbinfo->flush.relocate_distance = FLUSH_RELOCATE_DISTANCE; ++ sbinfo->flush.written_threshold = FLUSH_WRITTEN_THRESHOLD; ++ sbinfo->flush.scan_maxnodes = FLUSH_SCAN_MAXNODES; ++ ++ sbinfo->optimal_io_size = REISER4_OPTIMAL_IO_SIZE; ++ ++ /* preliminary tree initializations */ ++ sbinfo->tree.super = super; ++ sbinfo->tree.carry.new_node_flags = REISER4_NEW_NODE_FLAGS; ++ sbinfo->tree.carry.new_extent_flags = REISER4_NEW_EXTENT_FLAGS; ++ sbinfo->tree.carry.paste_flags = REISER4_PASTE_FLAGS; ++ sbinfo->tree.carry.insert_flags = REISER4_INSERT_FLAGS; ++ rwlock_init(&(sbinfo->tree.tree_lock)); ++ spin_lock_init(&(sbinfo->tree.epoch_lock)); ++ ++ /* initialize default readahead params */ ++ sbinfo->ra_params.max = num_physpages / 4; ++ sbinfo->ra_params.flags = 0; ++ ++ /* allocate memory for structure describing reiser4 mount options */ ++ opts = kmalloc(sizeof(struct opt_desc) * MAX_NR_OPTIONS, ++ reiser4_ctx_gfp_mask_get()); ++ if (opts == NULL) ++ return RETERR(-ENOMEM); ++ ++ /* initialize structure describing reiser4 mount options */ ++ p = opts; ++ ++#if REISER4_DEBUG ++# define OPT_ARRAY_CHECK if ((p) > (opts) + MAX_NR_OPTIONS) { \ ++ warning("zam-1046", "opt array is overloaded"); break; \ ++ } ++#else ++# define OPT_ARRAY_CHECK noop ++#endif ++ ++#define PUSH_OPT(...) \ ++do { \ ++ struct opt_desc o = __VA_ARGS__; \ ++ OPT_ARRAY_CHECK; \ ++ *p ++ = o; \ ++} while (0) ++ ++#define PUSH_SB_FIELD_OPT(field, format) PUSH_OPT(SB_FIELD_OPT(field, format)) ++#define PUSH_BIT_OPT(name, bit) PUSH_OPT(BIT_OPT(name, bit)) ++ ++ /* ++ * tmgr.atom_max_size=N ++ * Atoms containing more than N blocks will be forced to commit. N is ++ * decimal. ++ */ ++ PUSH_SB_FIELD_OPT(tmgr.atom_max_size, "%u"); ++ /* ++ * tmgr.atom_max_age=N ++ * Atoms older than N seconds will be forced to commit. N is decimal. ++ */ ++ PUSH_SB_FIELD_OPT(tmgr.atom_max_age, "%u"); ++ /* ++ * tmgr.atom_min_size=N ++ * In committing an atom to free dirty pages, force the atom less than ++ * N in size to fuse with another one. ++ */ ++ PUSH_SB_FIELD_OPT(tmgr.atom_min_size, "%u"); ++ /* ++ * tmgr.atom_max_flushers=N ++ * limit of concurrent flushers for one atom. 0 means no limit. ++ */ ++ PUSH_SB_FIELD_OPT(tmgr.atom_max_flushers, "%u"); ++ /* ++ * tree.cbk_cache_slots=N ++ * Number of slots in the cbk cache. ++ */ ++ PUSH_SB_FIELD_OPT(tree.cbk_cache.nr_slots, "%u"); ++ /* ++ * If flush finds more than FLUSH_RELOCATE_THRESHOLD adjacent dirty ++ * leaf-level blocks it will force them to be relocated. ++ */ ++ PUSH_SB_FIELD_OPT(flush.relocate_threshold, "%u"); ++ /* ++ * If flush finds can find a block allocation closer than at most ++ * FLUSH_RELOCATE_DISTANCE from the preceder it will relocate to that ++ * position. ++ */ ++ PUSH_SB_FIELD_OPT(flush.relocate_distance, "%u"); ++ /* ++ * If we have written this much or more blocks before encountering busy ++ * jnode in flush list - abort flushing hoping that next time we get ++ * called this jnode will be clean already, and we will save some ++ * seeks. ++ */ ++ PUSH_SB_FIELD_OPT(flush.written_threshold, "%u"); ++ /* The maximum number of nodes to scan left on a level during flush. */ ++ PUSH_SB_FIELD_OPT(flush.scan_maxnodes, "%u"); ++ /* preferred IO size */ ++ PUSH_SB_FIELD_OPT(optimal_io_size, "%u"); ++ /* carry flags used for insertion of new nodes */ ++ PUSH_SB_FIELD_OPT(tree.carry.new_node_flags, "%u"); ++ /* carry flags used for insertion of new extents */ ++ PUSH_SB_FIELD_OPT(tree.carry.new_extent_flags, "%u"); ++ /* carry flags used for paste operations */ ++ PUSH_SB_FIELD_OPT(tree.carry.paste_flags, "%u"); ++ /* carry flags used for insert operations */ ++ PUSH_SB_FIELD_OPT(tree.carry.insert_flags, "%u"); ++ ++#ifdef CONFIG_REISER4_BADBLOCKS ++ /* ++ * Alternative master superblock location in case if it's original ++ * location is not writeable/accessable. This is offset in BYTES. ++ */ ++ PUSH_SB_FIELD_OPT(altsuper, "%lu"); ++#endif ++ ++ /* turn on BSD-style gid assignment */ ++ PUSH_BIT_OPT("bsdgroups", REISER4_BSD_GID); ++ /* turn on 32 bit times */ ++ PUSH_BIT_OPT("32bittimes", REISER4_32_BIT_TIMES); ++ /* ++ * Don't load all bitmap blocks at mount time, it is useful for ++ * machines with tiny RAM and large disks. ++ */ ++ PUSH_BIT_OPT("dont_load_bitmap", REISER4_DONT_LOAD_BITMAP); ++ /* disable transaction commits during write() */ ++ PUSH_BIT_OPT("atomic_write", REISER4_ATOMIC_WRITE); ++ /* disable use of write barriers in the reiser4 log writer. */ ++ PUSH_BIT_OPT("no_write_barrier", REISER4_NO_WRITE_BARRIER); ++ ++ PUSH_OPT( ++ { ++ /* ++ * tree traversal readahead parameters: ++ * -o readahead:MAXNUM:FLAGS ++ * MAXNUM - max number fo nodes to request readahead for: -1UL ++ * will set it to max_sane_readahead() ++ * FLAGS - combination of bits: RA_ADJCENT_ONLY, RA_ALL_LEVELS, ++ * CONTINUE_ON_PRESENT ++ */ ++ .name = "readahead", ++ .type = OPT_FORMAT, ++ .u = { ++ .f = { ++ .format = "%u:%u", ++ .nr_args = 2, ++ .arg1 = &sbinfo->ra_params.max, ++ .arg2 = &sbinfo->ra_params.flags, ++ .arg3 = NULL, ++ .arg4 = NULL ++ } ++ } ++ } ++ ); ++ ++ /* What to do in case of fs error */ ++ PUSH_OPT( ++ { ++ .name = "onerror", ++ .type = OPT_ONEOF, ++ .u = { ++ .oneof = { ++ .result = &sbinfo->onerror, ++ .list = { ++ "panic", "remount-ro", NULL ++ }, ++ } ++ } ++ } ++ ); ++ ++ /* modify default settings to values set by mount options */ ++ result = parse_options(opt_string, opts, p - opts); ++ kfree(opts); ++ if (result != 0) ++ return result; ++ ++ /* correct settings to sanity values */ ++ sbinfo->tmgr.atom_max_age *= HZ; ++ if (sbinfo->tmgr.atom_max_age <= 0) ++ /* overflow */ ++ sbinfo->tmgr.atom_max_age = REISER4_ATOM_MAX_AGE; ++ ++ /* round optimal io size up to 512 bytes */ ++ sbinfo->optimal_io_size >>= VFS_BLKSIZE_BITS; ++ sbinfo->optimal_io_size <<= VFS_BLKSIZE_BITS; ++ if (sbinfo->optimal_io_size == 0) { ++ warning("nikita-2497", "optimal_io_size is too small"); ++ return RETERR(-EINVAL); ++ } ++ return result; ++} ++ ++/** ++ * reiser4_init_read_super - read reiser4 master super block ++ * @super: super block to fill ++ * @silent: if 0 - print warnings ++ * ++ * Reads reiser4 master super block either from predefined location or from ++ * location specified by altsuper mount option, initializes disk format plugin. ++ */ ++int reiser4_init_read_super(struct super_block *super, int silent) ++{ ++ struct buffer_head *super_bh; ++ struct reiser4_master_sb *master_sb; ++ reiser4_super_info_data *sbinfo = get_super_private(super); ++ unsigned long blocksize; ++ ++ read_super_block: ++#ifdef CONFIG_REISER4_BADBLOCKS ++ if (sbinfo->altsuper) ++ /* ++ * read reiser4 master super block at position specified by ++ * mount option ++ */ ++ super_bh = sb_bread(super, ++ (sector_t)(sbinfo->altsuper / super->s_blocksize)); ++ else ++#endif ++ /* read reiser4 master super block at 16-th 4096 block */ ++ super_bh = sb_bread(super, ++ (sector_t)(REISER4_MAGIC_OFFSET / super->s_blocksize)); ++ if (!super_bh) ++ return RETERR(-EIO); ++ ++ master_sb = (struct reiser4_master_sb *)super_bh->b_data; ++ /* check reiser4 magic string */ ++ if (!strncmp(master_sb->magic, REISER4_SUPER_MAGIC_STRING, ++ sizeof(REISER4_SUPER_MAGIC_STRING))) { ++ /* reiser4 master super block contains filesystem blocksize */ ++ blocksize = le16_to_cpu(get_unaligned(&master_sb->blocksize)); ++ ++ if (blocksize != PAGE_CACHE_SIZE) { ++ /* ++ * currenly reiser4's blocksize must be equal to ++ * pagesize ++ */ ++ if (!silent) ++ warning("nikita-2609", ++ "%s: wrong block size %ld\n", super->s_id, ++ blocksize); ++ brelse(super_bh); ++ return RETERR(-EINVAL); ++ } ++ if (blocksize != super->s_blocksize) { ++ /* ++ * filesystem uses different blocksize. Reread master ++ * super block with correct blocksize ++ */ ++ brelse(super_bh); ++ if (!sb_set_blocksize(super, (int)blocksize)) ++ return RETERR(-EINVAL); ++ goto read_super_block; ++ } ++ ++ sbinfo->df_plug = ++ disk_format_plugin_by_id( ++ le16_to_cpu(get_unaligned(&master_sb->disk_plugin_id))); ++ if (sbinfo->df_plug == NULL) { ++ if (!silent) ++ warning("nikita-26091", ++ "%s: unknown disk format plugin %d\n", ++ super->s_id, ++ le16_to_cpu(get_unaligned(&master_sb->disk_plugin_id))); ++ brelse(super_bh); ++ return RETERR(-EINVAL); ++ } ++ sbinfo->diskmap_block = le64_to_cpu(get_unaligned(&master_sb->diskmap)); ++ brelse(super_bh); ++ return 0; ++ } ++ ++ /* there is no reiser4 on the device */ ++ if (!silent) ++ warning("nikita-2608", ++ "%s: wrong master super block magic", super->s_id); ++ brelse(super_bh); ++ return RETERR(-EINVAL); ++} ++ ++static struct { ++ reiser4_plugin_type type; ++ reiser4_plugin_id id; ++} default_plugins[PSET_LAST] = { ++ [PSET_FILE] = { ++ .type = REISER4_FILE_PLUGIN_TYPE, ++ .id = UNIX_FILE_PLUGIN_ID ++ }, ++ [PSET_DIR] = { ++ .type = REISER4_DIR_PLUGIN_TYPE, ++ .id = HASHED_DIR_PLUGIN_ID ++ }, ++ [PSET_HASH] = { ++ .type = REISER4_HASH_PLUGIN_TYPE, ++ .id = R5_HASH_ID ++ }, ++ [PSET_FIBRATION] = { ++ .type = REISER4_FIBRATION_PLUGIN_TYPE, ++ .id = FIBRATION_DOT_O ++ }, ++ [PSET_PERM] = { ++ .type = REISER4_PERM_PLUGIN_TYPE, ++ .id = NULL_PERM_ID ++ }, ++ [PSET_FORMATTING] = { ++ .type = REISER4_FORMATTING_PLUGIN_TYPE, ++ .id = SMALL_FILE_FORMATTING_ID ++ }, ++ [PSET_SD] = { ++ .type = REISER4_ITEM_PLUGIN_TYPE, ++ .id = STATIC_STAT_DATA_ID ++ }, ++ [PSET_DIR_ITEM] = { ++ .type = REISER4_ITEM_PLUGIN_TYPE, ++ .id = COMPOUND_DIR_ID ++ }, ++ [PSET_CIPHER] = { ++ .type = REISER4_CIPHER_PLUGIN_TYPE, ++ .id = NONE_CIPHER_ID ++ }, ++ [PSET_DIGEST] = { ++ .type = REISER4_DIGEST_PLUGIN_TYPE, ++ .id = SHA256_32_DIGEST_ID ++ }, ++ [PSET_COMPRESSION] = { ++ .type = REISER4_COMPRESSION_PLUGIN_TYPE, ++ .id = LZO1_COMPRESSION_ID ++ }, ++ [PSET_COMPRESSION_MODE] = { ++ .type = REISER4_COMPRESSION_MODE_PLUGIN_TYPE, ++ .id = CONVX_COMPRESSION_MODE_ID ++ }, ++ [PSET_CLUSTER] = { ++ .type = REISER4_CLUSTER_PLUGIN_TYPE, ++ .id = CLUSTER_64K_ID ++ }, ++ [PSET_CREATE] = { ++ .type = REISER4_FILE_PLUGIN_TYPE, ++ .id = UNIX_FILE_PLUGIN_ID ++ } ++}; ++ ++/* access to default plugin table */ ++reiser4_plugin *get_default_plugin(pset_member memb) ++{ ++ return plugin_by_id(default_plugins[memb].type, ++ default_plugins[memb].id); ++} ++ ++/** ++ * reiser4_init_root_inode - obtain inode of root directory ++ * @super: super block of filesystem ++ * ++ * Obtains inode of root directory (reading it from disk), initializes plugin ++ * set it was not initialized. ++ */ ++int reiser4_init_root_inode(struct super_block *super) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(super); ++ struct inode *inode; ++ int result = 0; ++ ++ inode = reiser4_iget(super, sbinfo->df_plug->root_dir_key(super), 0); ++ if (IS_ERR(inode)) ++ return RETERR(PTR_ERR(inode)); ++ ++ super->s_root = d_alloc_root(inode); ++ if (!super->s_root) { ++ iput(inode); ++ return RETERR(-ENOMEM); ++ } ++ ++ super->s_root->d_op = &sbinfo->ops.dentry; ++ ++ if (!is_inode_loaded(inode)) { ++ pset_member memb; ++ plugin_set *pset; ++ ++ pset = reiser4_inode_data(inode)->pset; ++ for (memb = 0; memb < PSET_LAST; ++memb) { ++ ++ if (aset_get(pset, memb) != NULL) ++ continue; ++ ++ result = grab_plugin_pset(inode, NULL, memb); ++ if (result != 0) ++ break; ++ ++ reiser4_inode_clr_flag(inode, REISER4_SDLEN_KNOWN); ++ } ++ ++ if (result == 0) { ++ if (REISER4_DEBUG) { ++ for (memb = 0; memb < PSET_LAST; ++memb) ++ assert("nikita-3500", ++ aset_get(pset, memb) != NULL); ++ } ++ } else ++ warning("nikita-3448", "Cannot set plugins of root: %i", ++ result); ++ reiser4_iget_complete(inode); ++ ++ /* As the default pset kept in the root dir may has been changed ++ (length is unknown), call update_sd. */ ++ if (!reiser4_inode_get_flag(inode, REISER4_SDLEN_KNOWN)) { ++ result = reiser4_grab_space( ++ inode_file_plugin(inode)->estimate.update(inode), ++ BA_CAN_COMMIT); ++ ++ if (result == 0) ++ result = reiser4_update_sd(inode); ++ ++ all_grabbed2free(); ++ } ++ } ++ ++ super->s_maxbytes = MAX_LFS_FILESIZE; ++ return result; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/inode.c linux-2.6.30/fs/reiser4/inode.c +--- linux-2.6.30.orig/fs/reiser4/inode.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/inode.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,711 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* Inode specific operations. */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "key.h" ++#include "kassign.h" ++#include "coord.h" ++#include "seal.h" ++#include "dscale.h" ++#include "plugin/item/item.h" ++#include "plugin/security/perm.h" ++#include "plugin/plugin.h" ++#include "plugin/object.h" ++#include "znode.h" ++#include "vfs_ops.h" ++#include "inode.h" ++#include "super.h" ++#include "reiser4.h" ++ ++#include <linux/fs.h> /* for struct super_block, address_space */ ++ ++/* return reiser4 internal tree which inode belongs to */ ++/* Audited by: green(2002.06.17) */ ++reiser4_tree *reiser4_tree_by_inode(const struct inode *inode/* inode queried*/) ++{ ++ assert("nikita-256", inode != NULL); ++ assert("nikita-257", inode->i_sb != NULL); ++ return reiser4_get_tree(inode->i_sb); ++} ++ ++/* return reiser4-specific inode flags */ ++static inline unsigned long *inode_flags(const struct inode *const inode) ++{ ++ assert("nikita-2842", inode != NULL); ++ return &reiser4_inode_data(inode)->flags; ++} ++ ++/* set reiser4-specific flag @f in @inode */ ++void reiser4_inode_set_flag(struct inode *inode, reiser4_file_plugin_flags f) ++{ ++ assert("nikita-2248", inode != NULL); ++ set_bit((int)f, inode_flags(inode)); ++} ++ ++/* clear reiser4-specific flag @f in @inode */ ++void reiser4_inode_clr_flag(struct inode *inode, reiser4_file_plugin_flags f) ++{ ++ assert("nikita-2250", inode != NULL); ++ clear_bit((int)f, inode_flags(inode)); ++} ++ ++/* true if reiser4-specific flag @f is set in @inode */ ++int reiser4_inode_get_flag(const struct inode *inode, ++ reiser4_file_plugin_flags f) ++{ ++ assert("nikita-2251", inode != NULL); ++ return test_bit((int)f, inode_flags(inode)); ++} ++ ++/* convert oid to inode number */ ++ino_t oid_to_ino(oid_t oid) ++{ ++ return (ino_t) oid; ++} ++ ++/* convert oid to user visible inode number */ ++ino_t oid_to_uino(oid_t oid) ++{ ++ /* reiser4 object is uniquely identified by oid which is 64 bit ++ quantity. Kernel in-memory inode is indexed (in the hash table) by ++ 32 bit i_ino field, but this is not a problem, because there is a ++ way to further distinguish inodes with identical inode numbers ++ (find_actor supplied to iget()). ++ ++ But user space expects unique 32 bit inode number. Obviously this ++ is impossible. Work-around is to somehow hash oid into user visible ++ inode number. ++ */ ++ oid_t max_ino = (ino_t) ~0; ++ ++ if (REISER4_INO_IS_OID || (oid <= max_ino)) ++ return oid; ++ else ++ /* this is remotely similar to algorithm used to find next pid ++ to use for process: after wrap-around start from some ++ offset rather than from 0. Idea is that there are some long ++ living objects with which we don't want to collide. ++ */ ++ return REISER4_UINO_SHIFT + ((oid - max_ino) & (max_ino >> 1)); ++} ++ ++/* check that "inode" is on reiser4 file-system */ ++int is_reiser4_inode(const struct inode *inode/* inode queried */) ++{ ++ return inode != NULL && is_reiser4_super(inode->i_sb); ++} ++ ++/* Maximal length of a name that can be stored in directory @inode. ++ ++ This is used in check during file creation and lookup. */ ++int reiser4_max_filename_len(const struct inode *inode/* inode queried */) ++{ ++ assert("nikita-287", is_reiser4_inode(inode)); ++ assert("nikita-1710", inode_dir_item_plugin(inode)); ++ if (inode_dir_item_plugin(inode)->s.dir.max_name_len) ++ return inode_dir_item_plugin(inode)->s.dir.max_name_len(inode); ++ else ++ return 255; ++} ++ ++#if REISER4_USE_COLLISION_LIMIT ++/* Maximal number of hash collisions for this directory. */ ++int max_hash_collisions(const struct inode *dir/* inode queried */) ++{ ++ assert("nikita-1711", dir != NULL); ++ return reiser4_inode_data(dir)->plugin.max_collisions; ++} ++#endif /* REISER4_USE_COLLISION_LIMIT */ ++ ++/* Install file, inode, and address_space operation on @inode, depending on ++ its mode. */ ++int setup_inode_ops(struct inode *inode /* inode to intialize */ , ++ reiser4_object_create_data * data /* parameters to create ++ * object */ ) ++{ ++ reiser4_super_info_data *sinfo; ++ file_plugin *fplug; ++ dir_plugin *dplug; ++ ++ fplug = inode_file_plugin(inode); ++ dplug = inode_dir_plugin(inode); ++ ++ sinfo = get_super_private(inode->i_sb); ++ ++ switch (inode->i_mode & S_IFMT) { ++ case S_IFSOCK: ++ case S_IFBLK: ++ case S_IFCHR: ++ case S_IFIFO: ++ { ++ dev_t rdev; /* to keep gcc happy */ ++ ++ assert("vs-46", fplug != NULL); ++ /* ugly hack with rdev */ ++ if (data == NULL) { ++ rdev = inode->i_rdev; ++ inode->i_rdev = 0; ++ } else ++ rdev = data->rdev; ++ inode->i_blocks = 0; ++ assert("vs-42", fplug->h.id == SPECIAL_FILE_PLUGIN_ID); ++ inode->i_op = file_plugins[fplug->h.id].inode_ops; ++ /* initialize inode->i_fop and inode->i_rdev for block ++ and char devices */ ++ init_special_inode(inode, inode->i_mode, rdev); ++ /* all address space operations are null */ ++ inode->i_mapping->a_ops = ++ file_plugins[fplug->h.id].as_ops; ++ break; ++ } ++ case S_IFLNK: ++ assert("vs-46", fplug != NULL); ++ assert("vs-42", fplug->h.id == SYMLINK_FILE_PLUGIN_ID); ++ inode->i_op = file_plugins[fplug->h.id].inode_ops; ++ inode->i_fop = NULL; ++ /* all address space operations are null */ ++ inode->i_mapping->a_ops = file_plugins[fplug->h.id].as_ops; ++ break; ++ case S_IFDIR: ++ assert("vs-46", dplug != NULL); ++ assert("vs-43", (dplug->h.id == HASHED_DIR_PLUGIN_ID || ++ dplug->h.id == SEEKABLE_HASHED_DIR_PLUGIN_ID)); ++ inode->i_op = dir_plugins[dplug->h.id].inode_ops; ++ inode->i_fop = dir_plugins[dplug->h.id].file_ops; ++ inode->i_mapping->a_ops = dir_plugins[dplug->h.id].as_ops; ++ break; ++ case S_IFREG: ++ assert("vs-46", fplug != NULL); ++ assert("vs-43", (fplug->h.id == UNIX_FILE_PLUGIN_ID || ++ fplug->h.id == CRYPTCOMPRESS_FILE_PLUGIN_ID)); ++ inode->i_op = file_plugins[fplug->h.id].inode_ops; ++ inode->i_fop = file_plugins[fplug->h.id].file_ops; ++ inode->i_mapping->a_ops = file_plugins[fplug->h.id].as_ops; ++ break; ++ default: ++ warning("nikita-291", "wrong file mode: %o for %llu", ++ inode->i_mode, ++ (unsigned long long)get_inode_oid(inode)); ++ reiser4_make_bad_inode(inode); ++ return RETERR(-EINVAL); ++ } ++ return 0; ++} ++ ++/* Initialize inode from disk data. Called with inode locked. ++ Return inode locked. */ ++static int init_inode(struct inode *inode /* inode to intialise */ , ++ coord_t *coord/* coord of stat data */) ++{ ++ int result; ++ item_plugin *iplug; ++ void *body; ++ int length; ++ reiser4_inode *state; ++ ++ assert("nikita-292", coord != NULL); ++ assert("nikita-293", inode != NULL); ++ ++ coord_clear_iplug(coord); ++ result = zload(coord->node); ++ if (result) ++ return result; ++ iplug = item_plugin_by_coord(coord); ++ body = item_body_by_coord(coord); ++ length = item_length_by_coord(coord); ++ ++ assert("nikita-295", iplug != NULL); ++ assert("nikita-296", body != NULL); ++ assert("nikita-297", length > 0); ++ ++ /* inode is under I_LOCK now */ ++ ++ state = reiser4_inode_data(inode); ++ /* call stat-data plugin method to load sd content into inode */ ++ result = iplug->s.sd.init_inode(inode, body, length); ++ set_plugin(&state->pset, PSET_SD, item_plugin_to_plugin(iplug)); ++ if (result == 0) { ++ result = setup_inode_ops(inode, NULL); ++ if (result == 0 && inode->i_sb->s_root && ++ inode->i_sb->s_root->d_inode) ++ result = finish_pset(inode); ++ } ++ zrelse(coord->node); ++ return result; ++} ++ ++/* read `inode' from the disk. This is what was previously in ++ reiserfs_read_inode2(). ++ ++ Must be called with inode locked. Return inode still locked. ++*/ ++static int read_inode(struct inode *inode /* inode to read from disk */ , ++ const reiser4_key * key /* key of stat data */ , ++ int silent) ++{ ++ int result; ++ lock_handle lh; ++ reiser4_inode *info; ++ coord_t coord; ++ ++ assert("nikita-298", inode != NULL); ++ assert("nikita-1945", !is_inode_loaded(inode)); ++ ++ info = reiser4_inode_data(inode); ++ assert("nikita-300", info->locality_id != 0); ++ ++ coord_init_zero(&coord); ++ init_lh(&lh); ++ /* locate stat-data in a tree and return znode locked */ ++ result = lookup_sd(inode, ZNODE_READ_LOCK, &coord, &lh, key, silent); ++ assert("nikita-301", !is_inode_loaded(inode)); ++ if (result == 0) { ++ /* use stat-data plugin to load sd into inode. */ ++ result = init_inode(inode, &coord); ++ if (result == 0) { ++ /* initialize stat-data seal */ ++ spin_lock_inode(inode); ++ reiser4_seal_init(&info->sd_seal, &coord, key); ++ info->sd_coord = coord; ++ spin_unlock_inode(inode); ++ ++ /* call file plugin's method to initialize plugin ++ * specific part of inode */ ++ if (inode_file_plugin(inode)->init_inode_data) ++ inode_file_plugin(inode)->init_inode_data(inode, ++ NULL, ++ 0); ++ /* load detached directory cursors for stateless ++ * directory readers (NFS). */ ++ reiser4_load_cursors(inode); ++ ++ /* Check the opened inode for consistency. */ ++ result = ++ get_super_private(inode->i_sb)->df_plug-> ++ check_open(inode); ++ } ++ } ++ /* lookup_sd() doesn't release coord because we want znode ++ stay read-locked while stat-data fields are accessed in ++ init_inode() */ ++ done_lh(&lh); ++ ++ if (result != 0) ++ reiser4_make_bad_inode(inode); ++ return result; ++} ++ ++/* initialise new reiser4 inode being inserted into hash table. */ ++static int init_locked_inode(struct inode *inode /* new inode */ , ++ void *opaque /* key of stat data passed to ++ * the iget5_locked as cookie */) ++{ ++ reiser4_key *key; ++ ++ assert("nikita-1995", inode != NULL); ++ assert("nikita-1996", opaque != NULL); ++ key = opaque; ++ set_inode_oid(inode, get_key_objectid(key)); ++ reiser4_inode_data(inode)->locality_id = get_key_locality(key); ++ return 0; ++} ++ ++/* reiser4_inode_find_actor() - "find actor" supplied by reiser4 to ++ iget5_locked(). ++ ++ This function is called by iget5_locked() to distinguish reiser4 inodes ++ having the same inode numbers. Such inodes can only exist due to some error ++ condition. One of them should be bad. Inodes with identical inode numbers ++ (objectids) are distinguished by their packing locality. ++ ++*/ ++static int reiser4_inode_find_actor(struct inode *inode /* inode from hash table ++ * to check */ , ++ void *opaque /* "cookie" passed to ++ * iget5_locked(). This ++ * is stat-data key */) ++{ ++ reiser4_key *key; ++ ++ key = opaque; ++ return ++ /* oid is unique, so first term is enough, actually. */ ++ get_inode_oid(inode) == get_key_objectid(key) && ++ /* ++ * also, locality should be checked, but locality is stored in ++ * the reiser4-specific part of the inode, and actor can be ++ * called against arbitrary inode that happened to be in this ++ * hash chain. Hence we first have to check that this is ++ * reiser4 inode at least. is_reiser4_inode() is probably too ++ * early to call, as inode may have ->i_op not yet ++ * initialised. ++ */ ++ is_reiser4_super(inode->i_sb) && ++ /* ++ * usually objectid is unique, but pseudo files use counter to ++ * generate objectid. All pseudo files are placed into special ++ * (otherwise unused) locality. ++ */ ++ reiser4_inode_data(inode)->locality_id == get_key_locality(key); ++} ++ ++/* hook for kmem_cache_create */ ++void loading_init_once(reiser4_inode * info) ++{ ++ mutex_init(&info->loading); ++} ++ ++/* for reiser4_alloc_inode */ ++void loading_alloc(reiser4_inode * info) ++{ ++ assert("vs-1717", !mutex_is_locked(&info->loading)); ++} ++ ++/* for reiser4_destroy */ ++void loading_destroy(reiser4_inode * info) ++{ ++ assert("vs-1717a", !mutex_is_locked(&info->loading)); ++} ++ ++static void loading_begin(reiser4_inode * info) ++{ ++ mutex_lock(&info->loading); ++} ++ ++static void loading_end(reiser4_inode * info) ++{ ++ mutex_unlock(&info->loading); ++} ++ ++/** ++ * reiser4_iget - obtain inode via iget5_locked, read from disk if necessary ++ * @super: super block of filesystem ++ * @key: key of inode's stat-data ++ * @silent: ++ * ++ * This is our helper function a la iget(). This is be called by ++ * lookup_common() and reiser4_read_super(). Return inode locked or error ++ * encountered. ++ */ ++struct inode *reiser4_iget(struct super_block *super, const reiser4_key *key, ++ int silent) ++{ ++ struct inode *inode; ++ int result; ++ reiser4_inode *info; ++ ++ assert("nikita-302", super != NULL); ++ assert("nikita-303", key != NULL); ++ ++ result = 0; ++ ++ /* call iget(). Our ->read_inode() is dummy, so this will either ++ find inode in cache or return uninitialised inode */ ++ inode = iget5_locked(super, ++ (unsigned long)get_key_objectid(key), ++ reiser4_inode_find_actor, ++ init_locked_inode, (reiser4_key *) key); ++ if (inode == NULL) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ if (is_bad_inode(inode)) { ++ warning("nikita-304", "Bad inode found"); ++ reiser4_print_key("key", key); ++ iput(inode); ++ return ERR_PTR(RETERR(-EIO)); ++ } ++ ++ info = reiser4_inode_data(inode); ++ ++ /* Reiser4 inode state bit REISER4_LOADED is used to distinguish fully ++ loaded and initialized inode from just allocated inode. If ++ REISER4_LOADED bit is not set, reiser4_iget() completes loading under ++ info->loading. The place in reiser4 which uses not initialized inode ++ is the reiser4 repacker, see repacker-related functions in ++ plugin/item/extent.c */ ++ if (!is_inode_loaded(inode)) { ++ loading_begin(info); ++ if (!is_inode_loaded(inode)) { ++ /* locking: iget5_locked returns locked inode */ ++ assert("nikita-1941", !is_inode_loaded(inode)); ++ assert("nikita-1949", ++ reiser4_inode_find_actor(inode, ++ (reiser4_key *) key)); ++ /* now, inode has objectid as ->i_ino and locality in ++ reiser4-specific part. This is enough for ++ read_inode() to read stat data from the disk */ ++ result = read_inode(inode, key, silent); ++ } else ++ loading_end(info); ++ } ++ ++ if (inode->i_state & I_NEW) ++ unlock_new_inode(inode); ++ ++ if (is_bad_inode(inode)) { ++ assert("vs-1717", result != 0); ++ loading_end(info); ++ iput(inode); ++ inode = ERR_PTR(result); ++ } else if (REISER4_DEBUG) { ++ reiser4_key found_key; ++ ++ assert("vs-1717", result == 0); ++ build_sd_key(inode, &found_key); ++ if (!keyeq(&found_key, key)) { ++ warning("nikita-305", "Wrong key in sd"); ++ reiser4_print_key("sought for", key); ++ reiser4_print_key("found", &found_key); ++ } ++ if (inode->i_nlink == 0) { ++ warning("nikita-3559", "Unlinked inode found: %llu\n", ++ (unsigned long long)get_inode_oid(inode)); ++ } ++ } ++ return inode; ++} ++ ++/* reiser4_iget() may return not fully initialized inode, this function should ++ * be called after one completes reiser4 inode initializing. */ ++void reiser4_iget_complete(struct inode *inode) ++{ ++ assert("zam-988", is_reiser4_inode(inode)); ++ ++ if (!is_inode_loaded(inode)) { ++ reiser4_inode_set_flag(inode, REISER4_LOADED); ++ loading_end(reiser4_inode_data(inode)); ++ } ++} ++ ++void reiser4_make_bad_inode(struct inode *inode) ++{ ++ assert("nikita-1934", inode != NULL); ++ ++ /* clear LOADED bit */ ++ reiser4_inode_clr_flag(inode, REISER4_LOADED); ++ make_bad_inode(inode); ++ return; ++} ++ ++file_plugin *inode_file_plugin(const struct inode *inode) ++{ ++ assert("nikita-1997", inode != NULL); ++ return reiser4_inode_data(inode)->pset->file; ++} ++ ++dir_plugin *inode_dir_plugin(const struct inode *inode) ++{ ++ assert("nikita-1998", inode != NULL); ++ return reiser4_inode_data(inode)->pset->dir; ++} ++ ++formatting_plugin *inode_formatting_plugin(const struct inode *inode) ++{ ++ assert("nikita-2000", inode != NULL); ++ return reiser4_inode_data(inode)->pset->formatting; ++} ++ ++hash_plugin *inode_hash_plugin(const struct inode *inode) ++{ ++ assert("nikita-2001", inode != NULL); ++ return reiser4_inode_data(inode)->pset->hash; ++} ++ ++fibration_plugin *inode_fibration_plugin(const struct inode *inode) ++{ ++ assert("nikita-2001", inode != NULL); ++ return reiser4_inode_data(inode)->pset->fibration; ++} ++ ++cipher_plugin *inode_cipher_plugin(const struct inode *inode) ++{ ++ assert("edward-36", inode != NULL); ++ return reiser4_inode_data(inode)->pset->cipher; ++} ++ ++compression_plugin *inode_compression_plugin(const struct inode *inode) ++{ ++ assert("edward-37", inode != NULL); ++ return reiser4_inode_data(inode)->pset->compression; ++} ++ ++compression_mode_plugin *inode_compression_mode_plugin(const struct inode * ++ inode) ++{ ++ assert("edward-1330", inode != NULL); ++ return reiser4_inode_data(inode)->pset->compression_mode; ++} ++ ++cluster_plugin *inode_cluster_plugin(const struct inode *inode) ++{ ++ assert("edward-1328", inode != NULL); ++ return reiser4_inode_data(inode)->pset->cluster; ++} ++ ++file_plugin *inode_create_plugin(const struct inode *inode) ++{ ++ assert("edward-1329", inode != NULL); ++ return reiser4_inode_data(inode)->pset->create; ++} ++ ++digest_plugin *inode_digest_plugin(const struct inode *inode) ++{ ++ assert("edward-86", inode != NULL); ++ return reiser4_inode_data(inode)->pset->digest; ++} ++ ++item_plugin *inode_sd_plugin(const struct inode *inode) ++{ ++ assert("vs-534", inode != NULL); ++ return reiser4_inode_data(inode)->pset->sd; ++} ++ ++item_plugin *inode_dir_item_plugin(const struct inode *inode) ++{ ++ assert("vs-534", inode != NULL); ++ return reiser4_inode_data(inode)->pset->dir_item; ++} ++ ++file_plugin *child_create_plugin(const struct inode *inode) ++{ ++ assert("edward-1329", inode != NULL); ++ return reiser4_inode_data(inode)->hset->create; ++} ++ ++void inode_set_extension(struct inode *inode, sd_ext_bits ext) ++{ ++ reiser4_inode *state; ++ ++ assert("nikita-2716", inode != NULL); ++ assert("nikita-2717", ext < LAST_SD_EXTENSION); ++ assert("nikita-3491", spin_inode_is_locked(inode)); ++ ++ state = reiser4_inode_data(inode); ++ state->extmask |= 1 << ext; ++ /* force re-calculation of stat-data length on next call to ++ update_sd(). */ ++ reiser4_inode_clr_flag(inode, REISER4_SDLEN_KNOWN); ++} ++ ++void inode_clr_extension(struct inode *inode, sd_ext_bits ext) ++{ ++ reiser4_inode *state; ++ ++ assert("vpf-1926", inode != NULL); ++ assert("vpf-1927", ext < LAST_SD_EXTENSION); ++ assert("vpf-1928", spin_inode_is_locked(inode)); ++ ++ state = reiser4_inode_data(inode); ++ state->extmask &= ~(1 << ext); ++ /* force re-calculation of stat-data length on next call to ++ update_sd(). */ ++ reiser4_inode_clr_flag(inode, REISER4_SDLEN_KNOWN); ++} ++ ++void inode_check_scale_nolock(struct inode *inode, __u64 old, __u64 new) ++{ ++ assert("edward-1287", inode != NULL); ++ if (!dscale_fit(old, new)) ++ reiser4_inode_clr_flag(inode, REISER4_SDLEN_KNOWN); ++ return; ++} ++ ++void inode_check_scale(struct inode *inode, __u64 old, __u64 new) ++{ ++ assert("nikita-2875", inode != NULL); ++ spin_lock_inode(inode); ++ inode_check_scale_nolock(inode, old, new); ++ spin_unlock_inode(inode); ++} ++ ++/* ++ * initialize ->ordering field of inode. This field defines how file stat-data ++ * and body is ordered within a tree with respect to other objects within the ++ * same parent directory. ++ */ ++void ++init_inode_ordering(struct inode *inode, ++ reiser4_object_create_data * crd, int create) ++{ ++ reiser4_key key; ++ ++ if (create) { ++ struct inode *parent; ++ ++ parent = crd->parent; ++ assert("nikita-3224", inode_dir_plugin(parent) != NULL); ++ inode_dir_plugin(parent)->build_entry_key(parent, ++ &crd->dentry->d_name, ++ &key); ++ } else { ++ coord_t *coord; ++ ++ coord = &reiser4_inode_data(inode)->sd_coord; ++ coord_clear_iplug(coord); ++ /* safe to use ->sd_coord, because node is under long term ++ * lock */ ++ WITH_DATA(coord->node, item_key_by_coord(coord, &key)); ++ } ++ ++ set_inode_ordering(inode, get_key_ordering(&key)); ++} ++ ++znode *inode_get_vroot(struct inode *inode) ++{ ++ reiser4_block_nr blk; ++ znode *result; ++ ++ spin_lock_inode(inode); ++ blk = reiser4_inode_data(inode)->vroot; ++ spin_unlock_inode(inode); ++ if (!disk_addr_eq(&UBER_TREE_ADDR, &blk)) ++ result = zlook(reiser4_tree_by_inode(inode), &blk); ++ else ++ result = NULL; ++ return result; ++} ++ ++void inode_set_vroot(struct inode *inode, znode *vroot) ++{ ++ spin_lock_inode(inode); ++ reiser4_inode_data(inode)->vroot = *znode_get_block(vroot); ++ spin_unlock_inode(inode); ++} ++ ++#if REISER4_DEBUG ++ ++void reiser4_inode_invariant(const struct inode *inode) ++{ ++ assert("nikita-3077", spin_inode_is_locked(inode)); ++} ++ ++int inode_has_no_jnodes(reiser4_inode * r4_inode) ++{ ++ return jnode_tree_by_reiser4_inode(r4_inode)->rnode == NULL && ++ r4_inode->nr_jnodes == 0; ++} ++ ++#endif ++ ++/* true if directory is empty (only contains dot and dotdot) */ ++/* FIXME: shouldn't it be dir plugin method? */ ++int is_dir_empty(const struct inode *dir) ++{ ++ assert("nikita-1976", dir != NULL); ++ ++ /* rely on our method to maintain directory i_size being equal to the ++ number of entries. */ ++ return dir->i_size <= 2 ? 0 : RETERR(-ENOTEMPTY); ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/inode.h linux-2.6.30/fs/reiser4/inode.h +--- linux-2.6.30.orig/fs/reiser4/inode.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/inode.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,453 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* Inode functions. */ ++ ++#if !defined(__REISER4_INODE_H__) ++#define __REISER4_INODE_H__ ++ ++#include "forward.h" ++#include "debug.h" ++#include "key.h" ++#include "seal.h" ++#include "plugin/plugin.h" ++#include "plugin/file/cryptcompress.h" ++#include "plugin/file/file.h" ++#include "plugin/dir/dir.h" ++#include "plugin/plugin_set.h" ++#include "plugin/security/perm.h" ++#include "vfs_ops.h" ++#include "jnode.h" ++#include "fsdata.h" ++ ++#include <linux/types.h> /* for __u?? , ino_t */ ++#include <linux/fs.h> /* for struct super_block, struct ++ * rw_semaphore, etc */ ++#include <linux/spinlock.h> ++#include <asm/types.h> ++ ++/* reiser4-specific inode flags. They are "transient" and are not ++ supposed to be stored on disk. Used to trace "state" of ++ inode ++*/ ++typedef enum { ++ /* this is light-weight inode, inheriting some state from its ++ parent */ ++ REISER4_LIGHT_WEIGHT = 0, ++ /* stat data wasn't yet created */ ++ REISER4_NO_SD = 1, ++ /* internal immutable flag. Currently is only used ++ to avoid race condition during file creation. ++ See comment in create_object(). */ ++ REISER4_IMMUTABLE = 2, ++ /* inode was read from storage */ ++ REISER4_LOADED = 3, ++ /* this bit is set for symlinks. inode->i_private points to target ++ name of symlink. */ ++ REISER4_GENERIC_PTR_USED = 4, ++ /* set if size of stat-data item for this inode is known. If this is ++ * set we can avoid recalculating size of stat-data on each update. */ ++ REISER4_SDLEN_KNOWN = 5, ++ /* reiser4_inode->crypt points to the crypto stat */ ++ REISER4_CRYPTO_STAT_LOADED = 6, ++ /* cryptcompress_inode_data points to the secret key */ ++ REISER4_SECRET_KEY_INSTALLED = 7, ++ /* File (possibly) has pages corresponding to the tail items, that ++ * were created by ->readpage. It is set by mmap_unix_file() and ++ * sendfile_unix_file(). This bit is inspected by write_unix_file and ++ * kill-hook of tail items. It is never cleared once set. This bit is ++ * modified and inspected under i_mutex. */ ++ REISER4_HAS_MMAP = 8, ++ REISER4_PART_MIXED = 9, ++ REISER4_PART_IN_CONV = 10, ++ /* This flag indicates that file plugin conversion is in progress */ ++ REISER4_FILE_CONV_IN_PROGRESS = 11 ++} reiser4_file_plugin_flags; ++ ++/* state associated with each inode. ++ reiser4 inode. ++ ++ NOTE-NIKITA In 2.5 kernels it is not necessary that all file-system inodes ++ be of the same size. File-system allocates inodes by itself through ++ s_op->allocate_inode() method. So, it is possible to adjust size of inode ++ at the time of its creation. ++ ++ Invariants involving parts of this data-type: ++ ++ [inode->eflushed] ++ ++*/ ++ ++typedef struct reiser4_inode reiser4_inode; ++/* return pointer to reiser4-specific part of inode */ ++static inline reiser4_inode *reiser4_inode_data(const struct inode *inode ++ /* inode queried */ ); ++ ++#if BITS_PER_LONG == 64 ++ ++#define REISER4_INO_IS_OID (1) ++typedef struct {; ++} oid_hi_t; ++ ++/* BITS_PER_LONG == 64 */ ++#else ++ ++#define REISER4_INO_IS_OID (0) ++typedef __u32 oid_hi_t; ++ ++/* BITS_PER_LONG == 64 */ ++#endif ++ ++struct reiser4_inode { ++ /* spin lock protecting fields of this structure. */ ++ spinlock_t guard; ++ /* main plugin set that control the file ++ (see comments in plugin/plugin_set.c) */ ++ plugin_set *pset; ++ /* plugin set for inheritance ++ (see comments in plugin/plugin_set.c) */ ++ plugin_set *hset; ++ /* high 32 bits of object id */ ++ oid_hi_t oid_hi; ++ /* seal for stat-data */ ++ seal_t sd_seal; ++ /* locality id for this file */ ++ oid_t locality_id; ++#if REISER4_LARGE_KEY ++ __u64 ordering; ++#endif ++ /* coord of stat-data in sealed node */ ++ coord_t sd_coord; ++ /* bit-mask of stat-data extentions used by this file */ ++ __u64 extmask; ++ /* bitmask of non-default plugins for this inode */ ++ __u16 plugin_mask; ++ /* bitmask of set heir plugins for this inode. */ ++ __u16 heir_mask; ++ union { ++ struct list_head readdir_list; ++ struct list_head not_used; ++ } lists; ++ /* per-inode flags. Filled by values of reiser4_file_plugin_flags */ ++ unsigned long flags; ++ union { ++ /* fields specific to unix_file plugin */ ++ struct unix_file_info unix_file_info; ++ /* fields specific to cryptcompress file plugin */ ++ struct cryptcompress_info cryptcompress_info; ++ } file_plugin_data; ++ ++ /* this semaphore is to serialize readers and writers of @pset->file ++ * when file plugin conversion is enabled ++ */ ++ struct rw_semaphore conv_sem; ++ ++ /* tree of jnodes. Phantom jnodes (ones not attched to any atom) are ++ tagged in that tree by EFLUSH_TAG_ANONYMOUS */ ++ struct radix_tree_root jnodes_tree; ++#if REISER4_DEBUG ++ /* number of unformatted node jnodes of this file in jnode hash table */ ++ unsigned long nr_jnodes; ++#endif ++ ++ /* block number of virtual root for this object. See comment above ++ * fs/reiser4/search.c:handle_vroot() */ ++ reiser4_block_nr vroot; ++ struct mutex loading; ++}; ++ ++void loading_init_once(reiser4_inode *); ++void loading_alloc(reiser4_inode *); ++void loading_destroy(reiser4_inode *); ++ ++struct reiser4_inode_object { ++ /* private part */ ++ reiser4_inode p; ++ /* generic fields not specific to reiser4, but used by VFS */ ++ struct inode vfs_inode; ++}; ++ ++/* return pointer to the reiser4 specific portion of @inode */ ++static inline reiser4_inode *reiser4_inode_data(const struct inode *inode ++ /* inode queried */ ) ++{ ++ assert("nikita-254", inode != NULL); ++ return &container_of(inode, struct reiser4_inode_object, vfs_inode)->p; ++} ++ ++static inline struct inode *inode_by_reiser4_inode(const reiser4_inode * ++ r4_inode /* inode queried */ ++ ) ++{ ++ return &container_of(r4_inode, struct reiser4_inode_object, ++ p)->vfs_inode; ++} ++ ++/* ++ * reiser4 inodes are identified by 64bit object-id (oid_t), but in struct ++ * inode ->i_ino field is of type ino_t (long) that can be either 32 or 64 ++ * bits. ++ * ++ * If ->i_ino is 32 bits we store remaining 32 bits in reiser4 specific part ++ * of inode, otherwise whole oid is stored in i_ino. ++ * ++ * Wrappers below ([sg]et_inode_oid()) are used to hide this difference. ++ */ ++ ++#define OID_HI_SHIFT (sizeof(ino_t) * 8) ++ ++#if REISER4_INO_IS_OID ++ ++static inline oid_t get_inode_oid(const struct inode *inode) ++{ ++ return inode->i_ino; ++} ++ ++static inline void set_inode_oid(struct inode *inode, oid_t oid) ++{ ++ inode->i_ino = oid; ++} ++ ++/* REISER4_INO_IS_OID */ ++#else ++ ++static inline oid_t get_inode_oid(const struct inode *inode) ++{ ++ return ++ ((__u64) reiser4_inode_data(inode)->oid_hi << OID_HI_SHIFT) | ++ inode->i_ino; ++} ++ ++static inline void set_inode_oid(struct inode *inode, oid_t oid) ++{ ++ assert("nikita-2519", inode != NULL); ++ inode->i_ino = (ino_t) (oid); ++ reiser4_inode_data(inode)->oid_hi = (oid) >> OID_HI_SHIFT; ++ assert("nikita-2521", get_inode_oid(inode) == (oid)); ++} ++ ++/* REISER4_INO_IS_OID */ ++#endif ++ ++static inline oid_t get_inode_locality(const struct inode *inode) ++{ ++ return reiser4_inode_data(inode)->locality_id; ++} ++ ++#if REISER4_LARGE_KEY ++static inline __u64 get_inode_ordering(const struct inode *inode) ++{ ++ return reiser4_inode_data(inode)->ordering; ++} ++ ++static inline void set_inode_ordering(const struct inode *inode, __u64 ordering) ++{ ++ reiser4_inode_data(inode)->ordering = ordering; ++} ++ ++#else ++ ++#define get_inode_ordering(inode) (0) ++#define set_inode_ordering(inode, val) noop ++ ++#endif ++ ++/* return inode in which @uf_info is embedded */ ++static inline struct inode * ++unix_file_info_to_inode(const struct unix_file_info *uf_info) ++{ ++ return &container_of(uf_info, struct reiser4_inode_object, ++ p.file_plugin_data.unix_file_info)->vfs_inode; ++} ++ ++extern ino_t oid_to_ino(oid_t oid) __attribute__ ((const)); ++extern ino_t oid_to_uino(oid_t oid) __attribute__ ((const)); ++ ++extern reiser4_tree *reiser4_tree_by_inode(const struct inode *inode); ++ ++#if REISER4_DEBUG ++extern void reiser4_inode_invariant(const struct inode *inode); ++extern int inode_has_no_jnodes(reiser4_inode *); ++#else ++#define reiser4_inode_invariant(inode) noop ++#endif ++ ++static inline int spin_inode_is_locked(const struct inode *inode) ++{ ++ assert_spin_locked(&reiser4_inode_data(inode)->guard); ++ return 1; ++} ++ ++/** ++ * spin_lock_inode - lock reiser4_inode' embedded spinlock ++ * @inode: inode to lock ++ * ++ * In debug mode it checks that lower priority locks are not held and ++ * increments reiser4_context's lock counters on which lock ordering checking ++ * is based. ++ */ ++static inline void spin_lock_inode(struct inode *inode) ++{ ++ assert("", LOCK_CNT_NIL(spin_locked)); ++ /* check lock ordering */ ++ assert_spin_not_locked(&d_lock); ++ ++ spin_lock(&reiser4_inode_data(inode)->guard); ++ ++ LOCK_CNT_INC(spin_locked_inode); ++ LOCK_CNT_INC(spin_locked); ++ ++ reiser4_inode_invariant(inode); ++} ++ ++/** ++ * spin_unlock_inode - unlock reiser4_inode' embedded spinlock ++ * @inode: inode to unlock ++ * ++ * In debug mode it checks that spinlock is held and decrements ++ * reiser4_context's lock counters on which lock ordering checking is based. ++ */ ++static inline void spin_unlock_inode(struct inode *inode) ++{ ++ assert_spin_locked(&reiser4_inode_data(inode)->guard); ++ assert("nikita-1375", LOCK_CNT_GTZ(spin_locked_inode)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ reiser4_inode_invariant(inode); ++ ++ LOCK_CNT_DEC(spin_locked_inode); ++ LOCK_CNT_DEC(spin_locked); ++ ++ spin_unlock(&reiser4_inode_data(inode)->guard); ++} ++ ++extern znode *inode_get_vroot(struct inode *inode); ++extern void inode_set_vroot(struct inode *inode, znode * vroot); ++ ++extern int reiser4_max_filename_len(const struct inode *inode); ++extern int max_hash_collisions(const struct inode *dir); ++extern void reiser4_unlock_inode(struct inode *inode); ++extern int is_reiser4_inode(const struct inode *inode); ++extern int setup_inode_ops(struct inode *inode, reiser4_object_create_data *); ++extern struct inode *reiser4_iget(struct super_block *super, ++ const reiser4_key * key, int silent); ++extern void reiser4_iget_complete(struct inode *inode); ++extern void reiser4_inode_set_flag(struct inode *inode, ++ reiser4_file_plugin_flags f); ++extern void reiser4_inode_clr_flag(struct inode *inode, ++ reiser4_file_plugin_flags f); ++extern int reiser4_inode_get_flag(const struct inode *inode, ++ reiser4_file_plugin_flags f); ++ ++/* has inode been initialized? */ ++static inline int ++is_inode_loaded(const struct inode *inode/* inode queried */) ++{ ++ assert("nikita-1120", inode != NULL); ++ return reiser4_inode_get_flag(inode, REISER4_LOADED); ++} ++ ++extern file_plugin *inode_file_plugin(const struct inode *inode); ++extern dir_plugin *inode_dir_plugin(const struct inode *inode); ++extern formatting_plugin *inode_formatting_plugin(const struct inode *inode); ++extern hash_plugin *inode_hash_plugin(const struct inode *inode); ++extern fibration_plugin *inode_fibration_plugin(const struct inode *inode); ++extern cipher_plugin *inode_cipher_plugin(const struct inode *inode); ++extern digest_plugin *inode_digest_plugin(const struct inode *inode); ++extern compression_plugin *inode_compression_plugin(const struct inode *inode); ++extern compression_mode_plugin *inode_compression_mode_plugin(const struct inode ++ *inode); ++extern cluster_plugin *inode_cluster_plugin(const struct inode *inode); ++extern file_plugin *inode_create_plugin(const struct inode *inode); ++extern item_plugin *inode_sd_plugin(const struct inode *inode); ++extern item_plugin *inode_dir_item_plugin(const struct inode *inode); ++extern file_plugin *child_create_plugin(const struct inode *inode); ++ ++extern void reiser4_make_bad_inode(struct inode *inode); ++ ++extern void inode_set_extension(struct inode *inode, sd_ext_bits ext); ++extern void inode_clr_extension(struct inode *inode, sd_ext_bits ext); ++extern void inode_check_scale(struct inode *inode, __u64 old, __u64 new); ++extern void inode_check_scale_nolock(struct inode *inode, __u64 old, __u64 new); ++ ++#define INODE_SET_SIZE(i, value) \ ++({ \ ++ struct inode *__i; \ ++ typeof(value) __v; \ ++ \ ++ __i = (i); \ ++ __v = (value); \ ++ inode_check_scale(__i, __i->i_size, __v); \ ++ i_size_write(__i, __v); \ ++}) ++ ++/* ++ * update field @field in inode @i to contain value @value. ++ */ ++#define INODE_SET_FIELD(i, field, value) \ ++({ \ ++ struct inode *__i; \ ++ typeof(value) __v; \ ++ \ ++ __i = (i); \ ++ __v = (value); \ ++ inode_check_scale(__i, __i->field, __v); \ ++ __i->field = __v; \ ++}) ++ ++#define INODE_INC_FIELD(i, field) \ ++({ \ ++ struct inode *__i; \ ++ \ ++ __i = (i); \ ++ inode_check_scale(__i, __i->field, __i->field + 1); \ ++ ++ __i->field; \ ++}) ++ ++#define INODE_DEC_FIELD(i, field) \ ++({ \ ++ struct inode *__i; \ ++ \ ++ __i = (i); \ ++ inode_check_scale(__i, __i->field, __i->field - 1); \ ++ -- __i->field; \ ++}) ++ ++/* See comment before reiser4_readdir_common() for description. */ ++static inline struct list_head *get_readdir_list(const struct inode *inode) ++{ ++ return &reiser4_inode_data(inode)->lists.readdir_list; ++} ++ ++extern void init_inode_ordering(struct inode *inode, ++ reiser4_object_create_data * crd, int create); ++ ++static inline struct radix_tree_root *jnode_tree_by_inode(struct inode *inode) ++{ ++ return &reiser4_inode_data(inode)->jnodes_tree; ++} ++ ++static inline struct radix_tree_root *jnode_tree_by_reiser4_inode(reiser4_inode ++ *r4_inode) ++{ ++ return &r4_inode->jnodes_tree; ++} ++ ++#if REISER4_DEBUG ++extern void print_inode(const char *prefix, const struct inode *i); ++#endif ++ ++int is_dir_empty(const struct inode *); ++ ++/* __REISER4_INODE_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/ioctl.h linux-2.6.30/fs/reiser4/ioctl.h +--- linux-2.6.30.orig/fs/reiser4/ioctl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/ioctl.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,41 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#if !defined(__REISER4_IOCTL_H__) ++#define __REISER4_IOCTL_H__ ++ ++#include <linux/fs.h> ++ ++/* ++ * ioctl(2) command used to "unpack" reiser4 file, that is, convert it into ++ * extents and fix in this state. This is used by applications that rely on ++ * ++ * . files being block aligned, and ++ * ++ * . files never migrating on disk ++ * ++ * for example, boot loaders (LILO) need this. ++ * ++ * This ioctl should be used as ++ * ++ * result = ioctl(fd, REISER4_IOC_UNPACK); ++ * ++ * File behind fd descriptor will be converted to the extents (if necessary), ++ * and its stat-data will be updated so that it will never be converted back ++ * into tails again. ++ */ ++#define REISER4_IOC_UNPACK _IOW(0xCD, 1, long) ++ ++/* __REISER4_IOCTL_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/jnode.c linux-2.6.30/fs/reiser4/jnode.c +--- linux-2.6.30.orig/fs/reiser4/jnode.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/jnode.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1923 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++/* Jnode manipulation functions. */ ++/* Jnode is entity used to track blocks with data and meta-data in reiser4. ++ ++ In particular, jnodes are used to track transactional information ++ associated with each block. Each znode contains jnode as ->zjnode field. ++ ++ Jnode stands for either Josh or Journal node. ++*/ ++ ++/* ++ * Taxonomy. ++ * ++ * Jnode represents block containing data or meta-data. There are jnodes ++ * for: ++ * ++ * unformatted blocks (jnodes proper). There are plans, however to ++ * have a handle per extent unit rather than per each unformatted ++ * block, because there are so many of them. ++ * ++ * For bitmaps. Each bitmap is actually represented by two jnodes--one ++ * for working and another for "commit" data, together forming bnode. ++ * ++ * For io-heads. These are used by log writer. ++ * ++ * For formatted nodes (znode). See comment at the top of znode.c for ++ * details specific to the formatted nodes (znodes). ++ * ++ * Node data. ++ * ++ * Jnode provides access to the data of node it represents. Data are ++ * stored in a page. Page is kept in a page cache. This means, that jnodes ++ * are highly interconnected with page cache and VM internals. ++ * ++ * jnode has a pointer to page (->pg) containing its data. Pointer to data ++ * themselves is cached in ->data field to avoid frequent calls to ++ * page_address(). ++ * ++ * jnode and page are attached to each other by jnode_attach_page(). This ++ * function places pointer to jnode in set_page_private(), sets PG_private ++ * flag and increments page counter. ++ * ++ * Opposite operation is performed by page_clear_jnode(). ++ * ++ * jnode->pg is protected by jnode spin lock, and page->private is ++ * protected by page lock. See comment at the top of page_cache.c for ++ * more. ++ * ++ * page can be detached from jnode for two reasons: ++ * ++ * . jnode is removed from a tree (file is truncated, of formatted ++ * node is removed by balancing). ++ * ++ * . during memory pressure, VM calls ->releasepage() method ++ * (reiser4_releasepage()) to evict page from memory. ++ * ++ * (there, of course, is also umount, but this is special case we are not ++ * concerned with here). ++ * ++ * To protect jnode page from eviction, one calls jload() function that ++ * "pins" page in memory (loading it if necessary), increments ++ * jnode->d_count, and kmap()s page. Page is unpinned through call to ++ * jrelse(). ++ * ++ * Jnode life cycle. ++ * ++ * jnode is created, placed in hash table, and, optionally, in per-inode ++ * radix tree. Page can be attached to jnode, pinned, released, etc. ++ * ++ * When jnode is captured into atom its reference counter is ++ * increased. While being part of an atom, jnode can be "early ++ * flushed". This means that as part of flush procedure, jnode is placed ++ * into "relocate set", and its page is submitted to the disk. After io ++ * completes, page can be detached, then loaded again, re-dirtied, etc. ++ * ++ * Thread acquired reference to jnode by calling jref() and releases it by ++ * jput(). When last reference is removed, jnode is still retained in ++ * memory (cached) if it has page attached, _unless_ it is scheduled for ++ * destruction (has JNODE_HEARD_BANSHEE bit set). ++ * ++ * Tree read-write lock was used as "existential" lock for jnodes. That is, ++ * jnode->x_count could be changed from 0 to 1 only under tree write lock, ++ * that is, tree lock protected unreferenced jnodes stored in the hash ++ * table, from recycling. ++ * ++ * This resulted in high contention on tree lock, because jref()/jput() is ++ * frequent operation. To ameliorate this problem, RCU is used: when jput() ++ * is just about to release last reference on jnode it sets JNODE_RIP bit ++ * on it, and then proceed with jnode destruction (removing jnode from hash ++ * table, cbk_cache, detaching page, etc.). All places that change jnode ++ * reference counter from 0 to 1 (jlookup(), zlook(), zget(), and ++ * cbk_cache_scan_slots()) check for JNODE_RIP bit (this is done by ++ * jnode_rip_check() function), and pretend that nothing was found in hash ++ * table if bit is set. ++ * ++ * jput defers actual return of jnode into slab cache to some later time ++ * (by call_rcu()), this guarantees that other threads can safely continue ++ * working with JNODE_RIP-ped jnode. ++ * ++ */ ++ ++#include "reiser4.h" ++#include "debug.h" ++#include "dformat.h" ++#include "jnode.h" ++#include "plugin/plugin_header.h" ++#include "plugin/plugin.h" ++#include "txnmgr.h" ++/*#include "jnode.h"*/ ++#include "znode.h" ++#include "tree.h" ++#include "tree_walk.h" ++#include "super.h" ++#include "inode.h" ++#include "page_cache.h" ++ ++#include <asm/uaccess.h> /* UML needs this for PAGE_OFFSET */ ++#include <linux/types.h> ++#include <linux/slab.h> ++#include <linux/pagemap.h> ++#include <linux/swap.h> ++#include <linux/fs.h> /* for struct address_space */ ++#include <linux/writeback.h> /* for inode_lock */ ++ ++static struct kmem_cache *_jnode_slab = NULL; ++ ++static void jnode_set_type(jnode * node, jnode_type type); ++static int jdelete(jnode * node); ++static int jnode_try_drop(jnode * node); ++ ++#if REISER4_DEBUG ++static int jnode_invariant(jnode * node, int tlocked, int jlocked); ++#endif ++ ++/* true if valid page is attached to jnode */ ++static inline int jnode_is_parsed(jnode * node) ++{ ++ return JF_ISSET(node, JNODE_PARSED); ++} ++ ++/* hash table support */ ++ ++/* compare two jnode keys for equality. Used by hash-table macros */ ++static inline int jnode_key_eq(const struct jnode_key *k1, ++ const struct jnode_key *k2) ++{ ++ assert("nikita-2350", k1 != NULL); ++ assert("nikita-2351", k2 != NULL); ++ ++ return (k1->index == k2->index && k1->objectid == k2->objectid); ++} ++ ++/* Hash jnode by its key (inode plus offset). Used by hash-table macros */ ++static inline __u32 jnode_key_hashfn(j_hash_table * table, ++ const struct jnode_key *key) ++{ ++ assert("nikita-2352", key != NULL); ++ assert("nikita-3346", IS_POW(table->_buckets)); ++ ++ /* yes, this is remarkable simply (where not stupid) hash function. */ ++ return (key->objectid + key->index) & (table->_buckets - 1); ++} ++ ++/* The hash table definition */ ++#define KMALLOC(size) reiser4_vmalloc(size) ++#define KFREE(ptr, size) vfree(ptr) ++TYPE_SAFE_HASH_DEFINE(j, jnode, struct jnode_key, key.j, link.j, ++ jnode_key_hashfn, jnode_key_eq); ++#undef KFREE ++#undef KMALLOC ++ ++/* call this to initialise jnode hash table */ ++int jnodes_tree_init(reiser4_tree * tree/* tree to initialise jnodes for */) ++{ ++ assert("nikita-2359", tree != NULL); ++ return j_hash_init(&tree->jhash_table, 16384); ++} ++ ++/* call this to destroy jnode hash table. This is called during umount. */ ++int jnodes_tree_done(reiser4_tree * tree/* tree to destroy jnodes for */) ++{ ++ j_hash_table *jtable; ++ jnode *node; ++ jnode *next; ++ ++ assert("nikita-2360", tree != NULL); ++ ++ /* ++ * Scan hash table and free all jnodes. ++ */ ++ jtable = &tree->jhash_table; ++ if (jtable->_table) { ++ for_all_in_htable(jtable, j, node, next) { ++ assert("nikita-2361", !atomic_read(&node->x_count)); ++ jdrop(node); ++ } ++ ++ j_hash_done(&tree->jhash_table); ++ } ++ return 0; ++} ++ ++/** ++ * init_jnodes - create jnode cache ++ * ++ * Initializes slab cache jnodes. It is part of reiser4 module initialization. ++ */ ++int init_jnodes(void) ++{ ++ assert("umka-168", _jnode_slab == NULL); ++ ++ _jnode_slab = kmem_cache_create("jnode", sizeof(jnode), 0, ++ SLAB_HWCACHE_ALIGN | ++ SLAB_RECLAIM_ACCOUNT, NULL); ++ if (_jnode_slab == NULL) ++ return RETERR(-ENOMEM); ++ ++ return 0; ++} ++ ++/** ++ * done_znodes - delete znode cache ++ * ++ * This is called on reiser4 module unloading or system shutdown. ++ */ ++void done_jnodes(void) ++{ ++ destroy_reiser4_cache(&_jnode_slab); ++} ++ ++/* Initialize a jnode. */ ++void jnode_init(jnode * node, reiser4_tree * tree, jnode_type type) ++{ ++ assert("umka-175", node != NULL); ++ ++ memset(node, 0, sizeof(jnode)); ++ ON_DEBUG(node->magic = JMAGIC); ++ jnode_set_type(node, type); ++ atomic_set(&node->d_count, 0); ++ atomic_set(&node->x_count, 0); ++ spin_lock_init(&node->guard); ++ spin_lock_init(&node->load); ++ node->atom = NULL; ++ node->tree = tree; ++ INIT_LIST_HEAD(&node->capture_link); ++ ++ ASSIGN_NODE_LIST(node, NOT_CAPTURED); ++ ++ INIT_RCU_HEAD(&node->rcu); ++ ++#if REISER4_DEBUG ++ { ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = get_super_private(tree->super); ++ spin_lock_irq(&sbinfo->all_guard); ++ list_add(&node->jnodes, &sbinfo->all_jnodes); ++ spin_unlock_irq(&sbinfo->all_guard); ++ } ++#endif ++} ++ ++#if REISER4_DEBUG ++/* ++ * Remove jnode from ->all_jnodes list. ++ */ ++static void jnode_done(jnode * node, reiser4_tree * tree) ++{ ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = get_super_private(tree->super); ++ ++ spin_lock_irq(&sbinfo->all_guard); ++ assert("nikita-2422", !list_empty(&node->jnodes)); ++ list_del_init(&node->jnodes); ++ spin_unlock_irq(&sbinfo->all_guard); ++} ++#endif ++ ++/* return already existing jnode of page */ ++jnode *jnode_by_page(struct page *pg) ++{ ++ assert("nikita-2066", pg != NULL); ++ assert("nikita-2400", PageLocked(pg)); ++ assert("nikita-2068", PagePrivate(pg)); ++ assert("nikita-2067", jprivate(pg) != NULL); ++ return jprivate(pg); ++} ++ ++/* exported functions to allocate/free jnode objects outside this file */ ++jnode *jalloc(void) ++{ ++ jnode *jal = kmem_cache_alloc(_jnode_slab, reiser4_ctx_gfp_mask_get()); ++ return jal; ++} ++ ++/* return jnode back to the slab allocator */ ++inline void jfree(jnode * node) ++{ ++ assert("zam-449", node != NULL); ++ ++ assert("nikita-2663", (list_empty_careful(&node->capture_link) && ++ NODE_LIST(node) == NOT_CAPTURED)); ++ assert("nikita-3222", list_empty(&node->jnodes)); ++ assert("nikita-3221", jnode_page(node) == NULL); ++ ++ /* not yet phash_jnode_destroy(node); */ ++ ++ kmem_cache_free(_jnode_slab, node); ++} ++ ++/* ++ * This function is supplied as RCU callback. It actually frees jnode when ++ * last reference to it is gone. ++ */ ++static void jnode_free_actor(struct rcu_head *head) ++{ ++ jnode *node; ++ jnode_type jtype; ++ ++ node = container_of(head, jnode, rcu); ++ jtype = jnode_get_type(node); ++ ++ ON_DEBUG(jnode_done(node, jnode_get_tree(node))); ++ ++ switch (jtype) { ++ case JNODE_IO_HEAD: ++ case JNODE_BITMAP: ++ case JNODE_UNFORMATTED_BLOCK: ++ jfree(node); ++ break; ++ case JNODE_FORMATTED_BLOCK: ++ zfree(JZNODE(node)); ++ break; ++ case JNODE_INODE: ++ default: ++ wrong_return_value("nikita-3197", "Wrong jnode type"); ++ } ++} ++ ++/* ++ * Free a jnode. Post a callback to be executed later through RCU when all ++ * references to @node are released. ++ */ ++static inline void jnode_free(jnode * node, jnode_type jtype) ++{ ++ if (jtype != JNODE_INODE) { ++ /*assert("nikita-3219", list_empty(&node->rcu.list)); */ ++ call_rcu(&node->rcu, jnode_free_actor); ++ } else ++ jnode_list_remove(node); ++} ++ ++/* allocate new unformatted jnode */ ++static jnode *jnew_unformatted(void) ++{ ++ jnode *jal; ++ ++ jal = jalloc(); ++ if (jal == NULL) ++ return NULL; ++ ++ jnode_init(jal, current_tree, JNODE_UNFORMATTED_BLOCK); ++ jal->key.j.mapping = NULL; ++ jal->key.j.index = (unsigned long)-1; ++ jal->key.j.objectid = 0; ++ return jal; ++} ++ ++/* look for jnode with given mapping and offset within hash table */ ++jnode *jlookup(reiser4_tree * tree, oid_t objectid, unsigned long index) ++{ ++ struct jnode_key jkey; ++ jnode *node; ++ ++ assert("nikita-2353", tree != NULL); ++ ++ jkey.objectid = objectid; ++ jkey.index = index; ++ ++ /* ++ * hash table is _not_ protected by any lock during lookups. All we ++ * have to do is to disable preemption to keep RCU happy. ++ */ ++ ++ rcu_read_lock(); ++ node = j_hash_find(&tree->jhash_table, &jkey); ++ if (node != NULL) { ++ /* protect @node from recycling */ ++ jref(node); ++ assert("nikita-2955", jnode_invariant(node, 0, 0)); ++ node = jnode_rip_check(tree, node); ++ } ++ rcu_read_unlock(); ++ return node; ++} ++ ++/* per inode radix tree of jnodes is protected by tree's read write spin lock */ ++static jnode *jfind_nolock(struct address_space *mapping, unsigned long index) ++{ ++ assert("vs-1694", mapping->host != NULL); ++ ++ return radix_tree_lookup(jnode_tree_by_inode(mapping->host), index); ++} ++ ++jnode *jfind(struct address_space *mapping, unsigned long index) ++{ ++ reiser4_tree *tree; ++ jnode *node; ++ ++ assert("vs-1694", mapping->host != NULL); ++ tree = reiser4_tree_by_inode(mapping->host); ++ ++ read_lock_tree(tree); ++ node = jfind_nolock(mapping, index); ++ if (node != NULL) ++ jref(node); ++ read_unlock_tree(tree); ++ return node; ++} ++ ++static void inode_attach_jnode(jnode * node) ++{ ++ struct inode *inode; ++ reiser4_inode *info; ++ struct radix_tree_root *rtree; ++ ++ assert_rw_write_locked(&(jnode_get_tree(node)->tree_lock)); ++ assert("zam-1043", node->key.j.mapping != NULL); ++ inode = node->key.j.mapping->host; ++ info = reiser4_inode_data(inode); ++ rtree = jnode_tree_by_reiser4_inode(info); ++ if (rtree->rnode == NULL) { ++ /* prevent inode from being pruned when it has jnodes attached ++ to it */ ++ spin_lock_irq(&inode->i_data.tree_lock); ++ inode->i_data.nrpages++; ++ spin_unlock_irq(&inode->i_data.tree_lock); ++ } ++ assert("zam-1049", equi(rtree->rnode != NULL, info->nr_jnodes != 0)); ++ check_me("zam-1045", ++ !radix_tree_insert(rtree, node->key.j.index, node)); ++ ON_DEBUG(info->nr_jnodes++); ++} ++ ++static void inode_detach_jnode(jnode * node) ++{ ++ struct inode *inode; ++ reiser4_inode *info; ++ struct radix_tree_root *rtree; ++ ++ assert_rw_write_locked(&(jnode_get_tree(node)->tree_lock)); ++ assert("zam-1044", node->key.j.mapping != NULL); ++ inode = node->key.j.mapping->host; ++ info = reiser4_inode_data(inode); ++ rtree = jnode_tree_by_reiser4_inode(info); ++ ++ assert("zam-1051", info->nr_jnodes != 0); ++ assert("zam-1052", rtree->rnode != NULL); ++ ON_DEBUG(info->nr_jnodes--); ++ ++ /* delete jnode from inode's radix tree of jnodes */ ++ check_me("zam-1046", radix_tree_delete(rtree, node->key.j.index)); ++ if (rtree->rnode == NULL) { ++ /* inode can be pruned now */ ++ spin_lock_irq(&inode->i_data.tree_lock); ++ inode->i_data.nrpages--; ++ spin_unlock_irq(&inode->i_data.tree_lock); ++ } ++} ++ ++/* put jnode into hash table (where they can be found by flush who does not know ++ mapping) and to inode's tree of jnodes (where they can be found (hopefully ++ faster) in places where mapping is known). Currently it is used by ++ fs/reiser4/plugin/item/extent_file_ops.c:index_extent_jnode when new jnode is ++ created */ ++static void ++hash_unformatted_jnode(jnode * node, struct address_space *mapping, ++ unsigned long index) ++{ ++ j_hash_table *jtable; ++ ++ assert("vs-1446", jnode_is_unformatted(node)); ++ assert("vs-1442", node->key.j.mapping == 0); ++ assert("vs-1443", node->key.j.objectid == 0); ++ assert("vs-1444", node->key.j.index == (unsigned long)-1); ++ assert_rw_write_locked(&(jnode_get_tree(node)->tree_lock)); ++ ++ node->key.j.mapping = mapping; ++ node->key.j.objectid = get_inode_oid(mapping->host); ++ node->key.j.index = index; ++ ++ jtable = &jnode_get_tree(node)->jhash_table; ++ ++ /* race with some other thread inserting jnode into the hash table is ++ * impossible, because we keep the page lock. */ ++ /* ++ * following assertion no longer holds because of RCU: it is possible ++ * jnode is in the hash table, but with JNODE_RIP bit set. ++ */ ++ /* assert("nikita-3211", j_hash_find(jtable, &node->key.j) == NULL); */ ++ j_hash_insert_rcu(jtable, node); ++ inode_attach_jnode(node); ++} ++ ++static void unhash_unformatted_node_nolock(jnode * node) ++{ ++ assert("vs-1683", node->key.j.mapping != NULL); ++ assert("vs-1684", ++ node->key.j.objectid == ++ get_inode_oid(node->key.j.mapping->host)); ++ ++ /* remove jnode from hash-table */ ++ j_hash_remove_rcu(&node->tree->jhash_table, node); ++ inode_detach_jnode(node); ++ node->key.j.mapping = NULL; ++ node->key.j.index = (unsigned long)-1; ++ node->key.j.objectid = 0; ++ ++} ++ ++/* remove jnode from hash table and from inode's tree of jnodes. This is used in ++ reiser4_invalidatepage and in kill_hook_extent -> truncate_inode_jnodes -> ++ reiser4_uncapture_jnode */ ++void unhash_unformatted_jnode(jnode * node) ++{ ++ assert("vs-1445", jnode_is_unformatted(node)); ++ ++ write_lock_tree(node->tree); ++ unhash_unformatted_node_nolock(node); ++ write_unlock_tree(node->tree); ++} ++ ++/* ++ * search hash table for a jnode with given oid and index. If not found, ++ * allocate new jnode, insert it, and also insert into radix tree for the ++ * given inode/mapping. ++ */ ++static jnode *find_get_jnode(reiser4_tree * tree, ++ struct address_space *mapping, ++ oid_t oid, unsigned long index) ++{ ++ jnode *result; ++ jnode *shadow; ++ int preload; ++ ++ result = jnew_unformatted(); ++ ++ if (unlikely(result == NULL)) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ ++ preload = radix_tree_preload(reiser4_ctx_gfp_mask_get()); ++ if (preload != 0) ++ return ERR_PTR(preload); ++ ++ write_lock_tree(tree); ++ shadow = jfind_nolock(mapping, index); ++ if (likely(shadow == NULL)) { ++ /* add new jnode to hash table and inode's radix tree of ++ * jnodes */ ++ jref(result); ++ hash_unformatted_jnode(result, mapping, index); ++ } else { ++ /* jnode is found in inode's radix tree of jnodes */ ++ jref(shadow); ++ jnode_free(result, JNODE_UNFORMATTED_BLOCK); ++ assert("vs-1498", shadow->key.j.mapping == mapping); ++ result = shadow; ++ } ++ write_unlock_tree(tree); ++ ++ assert("nikita-2955", ++ ergo(result != NULL, jnode_invariant(result, 0, 0))); ++ radix_tree_preload_end(); ++ return result; ++} ++ ++/* jget() (a la zget() but for unformatted nodes). Returns (and possibly ++ creates) jnode corresponding to page @pg. jnode is attached to page and ++ inserted into jnode hash-table. */ ++static jnode *do_jget(reiser4_tree * tree, struct page *pg) ++{ ++ /* ++ * There are two ways to create jnode: starting with pre-existing page ++ * and without page. ++ * ++ * When page already exists, jnode is created ++ * (jnode_of_page()->do_jget()) under page lock. This is done in ++ * ->writepage(), or when capturing anonymous page dirtied through ++ * mmap. ++ * ++ * Jnode without page is created by index_extent_jnode(). ++ * ++ */ ++ ++ jnode *result; ++ oid_t oid = get_inode_oid(pg->mapping->host); ++ ++ assert("umka-176", pg != NULL); ++ assert("nikita-2394", PageLocked(pg)); ++ ++ result = jprivate(pg); ++ if (likely(result != NULL)) ++ return jref(result); ++ ++ tree = reiser4_tree_by_page(pg); ++ ++ /* check hash-table first */ ++ result = jfind(pg->mapping, pg->index); ++ if (unlikely(result != NULL)) { ++ spin_lock_jnode(result); ++ jnode_attach_page(result, pg); ++ spin_unlock_jnode(result); ++ result->key.j.mapping = pg->mapping; ++ return result; ++ } ++ ++ /* since page is locked, jnode should be allocated with GFP_NOFS flag */ ++ reiser4_ctx_gfp_mask_force(GFP_NOFS); ++ result = find_get_jnode(tree, pg->mapping, oid, pg->index); ++ if (unlikely(IS_ERR(result))) ++ return result; ++ /* attach jnode to page */ ++ spin_lock_jnode(result); ++ jnode_attach_page(result, pg); ++ spin_unlock_jnode(result); ++ return result; ++} ++ ++/* ++ * return jnode for @pg, creating it if necessary. ++ */ ++jnode *jnode_of_page(struct page *pg) ++{ ++ jnode *result; ++ ++ assert("umka-176", pg != NULL); ++ assert("nikita-2394", PageLocked(pg)); ++ ++ result = do_jget(reiser4_tree_by_page(pg), pg); ++ ++ if (REISER4_DEBUG && !IS_ERR(result)) { ++ assert("nikita-3210", result == jprivate(pg)); ++ assert("nikita-2046", jnode_page(jprivate(pg)) == pg); ++ if (jnode_is_unformatted(jprivate(pg))) { ++ assert("nikita-2364", ++ jprivate(pg)->key.j.index == pg->index); ++ assert("nikita-2367", ++ jprivate(pg)->key.j.mapping == pg->mapping); ++ assert("nikita-2365", ++ jprivate(pg)->key.j.objectid == ++ get_inode_oid(pg->mapping->host)); ++ assert("vs-1200", ++ jprivate(pg)->key.j.objectid == ++ pg->mapping->host->i_ino); ++ assert("nikita-2356", ++ jnode_is_unformatted(jnode_by_page(pg))); ++ } ++ assert("nikita-2956", jnode_invariant(jprivate(pg), 0, 0)); ++ } ++ return result; ++} ++ ++/* attach page to jnode: set ->pg pointer in jnode, and ->private one in the ++ * page.*/ ++void jnode_attach_page(jnode * node, struct page *pg) ++{ ++ assert("nikita-2060", node != NULL); ++ assert("nikita-2061", pg != NULL); ++ ++ assert("nikita-2050", jprivate(pg) == 0ul); ++ assert("nikita-2393", !PagePrivate(pg)); ++ assert("vs-1741", node->pg == NULL); ++ ++ assert("nikita-2396", PageLocked(pg)); ++ assert_spin_locked(&(node->guard)); ++ ++ page_cache_get(pg); ++ set_page_private(pg, (unsigned long)node); ++ node->pg = pg; ++ SetPagePrivate(pg); ++} ++ ++/* Dual to jnode_attach_page: break a binding between page and jnode */ ++void page_clear_jnode(struct page *page, jnode * node) ++{ ++ assert("nikita-2424", page != NULL); ++ assert("nikita-2425", PageLocked(page)); ++ assert("nikita-2426", node != NULL); ++ assert_spin_locked(&(node->guard)); ++ assert("nikita-2428", PagePrivate(page)); ++ ++ assert("nikita-3551", !PageWriteback(page)); ++ ++ JF_CLR(node, JNODE_PARSED); ++ set_page_private(page, 0ul); ++ ClearPagePrivate(page); ++ node->pg = NULL; ++ page_cache_release(page); ++} ++ ++#if 0 ++/* it is only used in one place to handle error */ ++void ++page_detach_jnode(struct page *page, struct address_space *mapping, ++ unsigned long index) ++{ ++ assert("nikita-2395", page != NULL); ++ ++ lock_page(page); ++ if ((page->mapping == mapping) && (page->index == index) ++ && PagePrivate(page)) { ++ jnode *node; ++ ++ node = jprivate(page); ++ spin_lock_jnode(node); ++ page_clear_jnode(page, node); ++ spin_unlock_jnode(node); ++ } ++ unlock_page(page); ++} ++#endif /* 0 */ ++ ++/* return @node page locked. ++ ++ Locking ordering requires that one first takes page lock and afterwards ++ spin lock on node attached to this page. Sometimes it is necessary to go in ++ the opposite direction. This is done through standard trylock-and-release ++ loop. ++*/ ++static struct page *jnode_lock_page(jnode * node) ++{ ++ struct page *page; ++ ++ assert("nikita-2052", node != NULL); ++ assert("nikita-2401", LOCK_CNT_NIL(spin_locked_jnode)); ++ ++ while (1) { ++ ++ spin_lock_jnode(node); ++ page = jnode_page(node); ++ if (page == NULL) ++ break; ++ ++ /* no need to page_cache_get( page ) here, because page cannot ++ be evicted from memory without detaching it from jnode and ++ this requires spin lock on jnode that we already hold. ++ */ ++ if (trylock_page(page)) { ++ /* We won a lock on jnode page, proceed. */ ++ break; ++ } ++ ++ /* Page is locked by someone else. */ ++ page_cache_get(page); ++ spin_unlock_jnode(node); ++ wait_on_page_locked(page); ++ /* it is possible that page was detached from jnode and ++ returned to the free pool, or re-assigned while we were ++ waiting on locked bit. This will be rechecked on the next ++ loop iteration. ++ */ ++ page_cache_release(page); ++ ++ /* try again */ ++ } ++ return page; ++} ++ ++/* ++ * is JNODE_PARSED bit is not set, call ->parse() method of jnode, to verify ++ * validness of jnode content. ++ */ ++static inline int jparse(jnode * node) ++{ ++ int result; ++ ++ assert("nikita-2466", node != NULL); ++ ++ spin_lock_jnode(node); ++ if (likely(!jnode_is_parsed(node))) { ++ result = jnode_ops(node)->parse(node); ++ if (likely(result == 0)) ++ JF_SET(node, JNODE_PARSED); ++ } else ++ result = 0; ++ spin_unlock_jnode(node); ++ return result; ++} ++ ++/* Lock a page attached to jnode, create and attach page to jnode if it had no ++ * one. */ ++static struct page *jnode_get_page_locked(jnode * node, gfp_t gfp_flags) ++{ ++ struct page *page; ++ ++ spin_lock_jnode(node); ++ page = jnode_page(node); ++ ++ if (page == NULL) { ++ spin_unlock_jnode(node); ++ page = find_or_create_page(jnode_get_mapping(node), ++ jnode_get_index(node), gfp_flags); ++ if (page == NULL) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ } else { ++ if (trylock_page(page)) { ++ spin_unlock_jnode(node); ++ return page; ++ } ++ page_cache_get(page); ++ spin_unlock_jnode(node); ++ lock_page(page); ++ assert("nikita-3134", page->mapping == jnode_get_mapping(node)); ++ } ++ ++ spin_lock_jnode(node); ++ if (!jnode_page(node)) ++ jnode_attach_page(node, page); ++ spin_unlock_jnode(node); ++ ++ page_cache_release(page); ++ assert("zam-894", jnode_page(node) == page); ++ return page; ++} ++ ++/* Start read operation for jnode's page if page is not up-to-date. */ ++static int jnode_start_read(jnode * node, struct page *page) ++{ ++ assert("zam-893", PageLocked(page)); ++ ++ if (PageUptodate(page)) { ++ unlock_page(page); ++ return 0; ++ } ++ return reiser4_page_io(page, node, READ, reiser4_ctx_gfp_mask_get()); ++} ++ ++#if REISER4_DEBUG ++static void check_jload(jnode * node, struct page *page) ++{ ++ if (jnode_is_znode(node)) { ++ node40_header *nh; ++ znode *z; ++ ++ z = JZNODE(node); ++ if (znode_is_any_locked(z)) { ++ nh = (node40_header *) kmap(page); ++ /* this only works for node40-only file systems. For ++ * debugging. */ ++ assert("nikita-3253", ++ z->nr_items == le16_to_cpu(get_unaligned(&nh->nr_items))); ++ kunmap(page); ++ } ++ assert("nikita-3565", znode_invariant(z)); ++ } ++} ++#else ++#define check_jload(node, page) noop ++#endif ++ ++/* prefetch jnode to speed up next call to jload. Call this when you are going ++ * to call jload() shortly. This will bring appropriate portion of jnode into ++ * CPU cache. */ ++void jload_prefetch(jnode * node) ++{ ++ prefetchw(&node->x_count); ++} ++ ++/* load jnode's data into memory */ ++int jload_gfp(jnode * node /* node to load */ , ++ gfp_t gfp_flags /* allocation flags */ , ++ int do_kmap/* true if page should be kmapped */) ++{ ++ struct page *page; ++ int result = 0; ++ int parsed; ++ ++ assert("nikita-3010", reiser4_schedulable()); ++ ++ prefetchw(&node->pg); ++ ++ /* taking d-reference implies taking x-reference. */ ++ jref(node); ++ ++ /* ++ * acquiring d-reference to @jnode and check for JNODE_PARSED bit ++ * should be atomic, otherwise there is a race against ++ * reiser4_releasepage(). ++ */ ++ spin_lock(&(node->load)); ++ add_d_ref(node); ++ parsed = jnode_is_parsed(node); ++ spin_unlock(&(node->load)); ++ ++ if (unlikely(!parsed)) { ++ page = jnode_get_page_locked(node, gfp_flags); ++ if (unlikely(IS_ERR(page))) { ++ result = PTR_ERR(page); ++ goto failed; ++ } ++ ++ result = jnode_start_read(node, page); ++ if (unlikely(result != 0)) ++ goto failed; ++ ++ wait_on_page_locked(page); ++ if (unlikely(!PageUptodate(page))) { ++ result = RETERR(-EIO); ++ goto failed; ++ } ++ ++ if (do_kmap) ++ node->data = kmap(page); ++ ++ result = jparse(node); ++ if (unlikely(result != 0)) { ++ if (do_kmap) ++ kunmap(page); ++ goto failed; ++ } ++ check_jload(node, page); ++ } else { ++ page = jnode_page(node); ++ check_jload(node, page); ++ if (do_kmap) ++ node->data = kmap(page); ++ } ++ ++ if (!is_writeout_mode()) ++ /* We do not mark pages active if jload is called as a part of ++ * jnode_flush() or reiser4_write_logs(). Both jnode_flush() ++ * and write_logs() add no value to cached data, there is no ++ * sense to mark pages as active when they go to disk, it just ++ * confuses vm scanning routines because clean page could be ++ * moved out from inactive list as a result of this ++ * mark_page_accessed() call. */ ++ mark_page_accessed(page); ++ ++ return 0; ++ ++failed: ++ jrelse_tail(node); ++ return result; ++ ++} ++ ++/* start asynchronous reading for given jnode's page. */ ++int jstartio(jnode * node) ++{ ++ struct page *page; ++ ++ page = jnode_get_page_locked(node, reiser4_ctx_gfp_mask_get()); ++ if (IS_ERR(page)) ++ return PTR_ERR(page); ++ ++ return jnode_start_read(node, page); ++} ++ ++/* Initialize a node by calling appropriate plugin instead of reading ++ * node from disk as in jload(). */ ++int jinit_new(jnode * node, gfp_t gfp_flags) ++{ ++ struct page *page; ++ int result; ++ ++ jref(node); ++ add_d_ref(node); ++ ++ page = jnode_get_page_locked(node, gfp_flags); ++ if (IS_ERR(page)) { ++ result = PTR_ERR(page); ++ goto failed; ++ } ++ ++ SetPageUptodate(page); ++ unlock_page(page); ++ ++ node->data = kmap(page); ++ ++ if (!jnode_is_parsed(node)) { ++ jnode_plugin *jplug = jnode_ops(node); ++ spin_lock_jnode(node); ++ result = jplug->init(node); ++ spin_unlock_jnode(node); ++ if (result) { ++ kunmap(page); ++ goto failed; ++ } ++ JF_SET(node, JNODE_PARSED); ++ } ++ ++ return 0; ++ ++failed: ++ jrelse(node); ++ return result; ++} ++ ++/* release a reference to jnode acquired by jload(), decrement ->d_count */ ++void jrelse_tail(jnode * node/* jnode to release references to */) ++{ ++ assert("nikita-489", atomic_read(&node->d_count) > 0); ++ atomic_dec(&node->d_count); ++ /* release reference acquired in jload_gfp() or jinit_new() */ ++ jput(node); ++ if (jnode_is_unformatted(node) || jnode_is_znode(node)) ++ LOCK_CNT_DEC(d_refs); ++} ++ ++/* drop reference to node data. When last reference is dropped, data are ++ unloaded. */ ++void jrelse(jnode * node/* jnode to release references to */) ++{ ++ struct page *page; ++ ++ assert("nikita-487", node != NULL); ++ assert_spin_not_locked(&(node->guard)); ++ ++ page = jnode_page(node); ++ if (likely(page != NULL)) { ++ /* ++ * it is safe not to lock jnode here, because at this point ++ * @node->d_count is greater than zero (if jrelse() is used ++ * correctly, that is). JNODE_PARSED may be not set yet, if, ++ * for example, we got here as a result of error handling path ++ * in jload(). Anyway, page cannot be detached by ++ * reiser4_releasepage(). truncate will invalidate page ++ * regardless, but this should not be a problem. ++ */ ++ kunmap(page); ++ } ++ jrelse_tail(node); ++} ++ ++/* called from jput() to wait for io completion */ ++static void jnode_finish_io(jnode * node) ++{ ++ struct page *page; ++ ++ assert("nikita-2922", node != NULL); ++ ++ spin_lock_jnode(node); ++ page = jnode_page(node); ++ if (page != NULL) { ++ page_cache_get(page); ++ spin_unlock_jnode(node); ++ wait_on_page_writeback(page); ++ page_cache_release(page); ++ } else ++ spin_unlock_jnode(node); ++} ++ ++/* ++ * This is called by jput() when last reference to jnode is released. This is ++ * separate function, because we want fast path of jput() to be inline and, ++ * therefore, small. ++ */ ++void jput_final(jnode * node) ++{ ++ int r_i_p; ++ ++ /* A fast check for keeping node in cache. We always keep node in cache ++ * if its page is present and node was not marked for deletion */ ++ if (jnode_page(node) != NULL && !JF_ISSET(node, JNODE_HEARD_BANSHEE)) { ++ rcu_read_unlock(); ++ return; ++ } ++ r_i_p = !JF_TEST_AND_SET(node, JNODE_RIP); ++ /* ++ * if r_i_p is true, we were first to set JNODE_RIP on this node. In ++ * this case it is safe to access node after unlock. ++ */ ++ rcu_read_unlock(); ++ if (r_i_p) { ++ jnode_finish_io(node); ++ if (JF_ISSET(node, JNODE_HEARD_BANSHEE)) ++ /* node is removed from the tree. */ ++ jdelete(node); ++ else ++ jnode_try_drop(node); ++ } ++ /* if !r_i_p some other thread is already killing it */ ++} ++ ++int jwait_io(jnode * node, int rw) ++{ ++ struct page *page; ++ int result; ++ ++ assert("zam-447", node != NULL); ++ assert("zam-448", jnode_page(node) != NULL); ++ ++ page = jnode_page(node); ++ ++ result = 0; ++ if (rw == READ) { ++ wait_on_page_locked(page); ++ } else { ++ assert("nikita-2227", rw == WRITE); ++ wait_on_page_writeback(page); ++ } ++ if (PageError(page)) ++ result = RETERR(-EIO); ++ ++ return result; ++} ++ ++/* ++ * jnode types and plugins. ++ * ++ * jnode by itself is a "base type". There are several different jnode ++ * flavors, called "jnode types" (see jnode_type for a list). Sometimes code ++ * has to do different things based on jnode type. In the standard reiser4 way ++ * this is done by having jnode plugin (see fs/reiser4/plugin.h:jnode_plugin). ++ * ++ * Functions below deal with jnode types and define methods of jnode plugin. ++ * ++ */ ++ ++/* set jnode type. This is done during jnode initialization. */ ++static void jnode_set_type(jnode * node, jnode_type type) ++{ ++ static unsigned long type_to_mask[] = { ++ [JNODE_UNFORMATTED_BLOCK] = 1, ++ [JNODE_FORMATTED_BLOCK] = 0, ++ [JNODE_BITMAP] = 2, ++ [JNODE_IO_HEAD] = 6, ++ [JNODE_INODE] = 4 ++ }; ++ ++ assert("zam-647", type < LAST_JNODE_TYPE); ++ assert("nikita-2815", !jnode_is_loaded(node)); ++ assert("nikita-3386", node->state == 0); ++ ++ node->state |= (type_to_mask[type] << JNODE_TYPE_1); ++} ++ ++/* ->init() method of jnode plugin for jnodes that don't require plugin ++ * specific initialization. */ ++static int init_noinit(jnode * node UNUSED_ARG) ++{ ++ return 0; ++} ++ ++/* ->parse() method of jnode plugin for jnodes that don't require plugin ++ * specific pasring. */ ++static int parse_noparse(jnode * node UNUSED_ARG) ++{ ++ return 0; ++} ++ ++/* ->mapping() method for unformatted jnode */ ++struct address_space *mapping_jnode(const jnode * node) ++{ ++ struct address_space *map; ++ ++ assert("nikita-2713", node != NULL); ++ ++ /* mapping is stored in jnode */ ++ ++ map = node->key.j.mapping; ++ assert("nikita-2714", map != NULL); ++ assert("nikita-2897", is_reiser4_inode(map->host)); ++ assert("nikita-2715", get_inode_oid(map->host) == node->key.j.objectid); ++ return map; ++} ++ ++/* ->index() method for unformatted jnodes */ ++unsigned long index_jnode(const jnode * node) ++{ ++ /* index is stored in jnode */ ++ return node->key.j.index; ++} ++ ++/* ->remove() method for unformatted jnodes */ ++static inline void remove_jnode(jnode * node, reiser4_tree * tree) ++{ ++ /* remove jnode from hash table and radix tree */ ++ if (node->key.j.mapping) ++ unhash_unformatted_node_nolock(node); ++} ++ ++/* ->mapping() method for znodes */ ++static struct address_space *mapping_znode(const jnode * node) ++{ ++ /* all znodes belong to fake inode */ ++ return reiser4_get_super_fake(jnode_get_tree(node)->super)->i_mapping; ++} ++ ++/* ->index() method for znodes */ ++static unsigned long index_znode(const jnode * node) ++{ ++ unsigned long addr; ++ assert("nikita-3317", (1 << znode_shift_order) < sizeof(znode)); ++ ++ /* index of znode is just its address (shifted) */ ++ addr = (unsigned long)node; ++ return (addr - PAGE_OFFSET) >> znode_shift_order; ++} ++ ++/* ->mapping() method for bitmap jnode */ ++static struct address_space *mapping_bitmap(const jnode * node) ++{ ++ /* all bitmap blocks belong to special bitmap inode */ ++ return get_super_private(jnode_get_tree(node)->super)->bitmap-> ++ i_mapping; ++} ++ ++/* ->index() method for jnodes that are indexed by address */ ++static unsigned long index_is_address(const jnode * node) ++{ ++ unsigned long ind; ++ ++ ind = (unsigned long)node; ++ return ind - PAGE_OFFSET; ++} ++ ++/* resolve race with jput */ ++jnode *jnode_rip_sync(reiser4_tree *tree, jnode *node) ++{ ++ /* ++ * This is used as part of RCU-based jnode handling. ++ * ++ * jlookup(), zlook(), zget(), and cbk_cache_scan_slots() have to work ++ * with unreferenced jnodes (ones with ->x_count == 0). Hash table is ++ * not protected during this, so concurrent thread may execute ++ * zget-set-HEARD_BANSHEE-zput, or somehow else cause jnode to be ++ * freed in jput_final(). To avoid such races, jput_final() sets ++ * JNODE_RIP on jnode (under tree lock). All places that work with ++ * unreferenced jnodes call this function. It checks for JNODE_RIP bit ++ * (first without taking tree lock), and if this bit is set, released ++ * reference acquired by the current thread and returns NULL. ++ * ++ * As a result, if jnode is being concurrently freed, NULL is returned ++ * and caller should pretend that jnode wasn't found in the first ++ * place. ++ * ++ * Otherwise it's safe to release "rcu-read-lock" and continue with ++ * jnode. ++ */ ++ if (unlikely(JF_ISSET(node, JNODE_RIP))) { ++ read_lock_tree(tree); ++ if (JF_ISSET(node, JNODE_RIP)) { ++ dec_x_ref(node); ++ node = NULL; ++ } ++ read_unlock_tree(tree); ++ } ++ return node; ++} ++ ++reiser4_key *jnode_build_key(const jnode * node, reiser4_key * key) ++{ ++ struct inode *inode; ++ item_plugin *iplug; ++ loff_t off; ++ ++ assert("nikita-3092", node != NULL); ++ assert("nikita-3093", key != NULL); ++ assert("nikita-3094", jnode_is_unformatted(node)); ++ ++ off = ((loff_t) index_jnode(node)) << PAGE_CACHE_SHIFT; ++ inode = mapping_jnode(node)->host; ++ ++ if (node->parent_item_id != 0) ++ iplug = item_plugin_by_id(node->parent_item_id); ++ else ++ iplug = NULL; ++ ++ if (iplug != NULL && iplug->f.key_by_offset) ++ iplug->f.key_by_offset(inode, off, key); ++ else { ++ file_plugin *fplug; ++ ++ fplug = inode_file_plugin(inode); ++ assert("zam-1007", fplug != NULL); ++ assert("zam-1008", fplug->key_by_inode != NULL); ++ ++ fplug->key_by_inode(inode, off, key); ++ } ++ ++ return key; ++} ++ ++/* ->parse() method for formatted nodes */ ++static int parse_znode(jnode * node) ++{ ++ return zparse(JZNODE(node)); ++} ++ ++/* ->delete() method for formatted nodes */ ++static void delete_znode(jnode * node, reiser4_tree * tree) ++{ ++ znode *z; ++ ++ assert_rw_write_locked(&(tree->tree_lock)); ++ assert("vs-898", JF_ISSET(node, JNODE_HEARD_BANSHEE)); ++ ++ z = JZNODE(node); ++ assert("vs-899", z->c_count == 0); ++ ++ /* delete znode from sibling list. */ ++ sibling_list_remove(z); ++ ++ znode_remove(z, tree); ++} ++ ++/* ->remove() method for formatted nodes */ ++static int remove_znode(jnode * node, reiser4_tree * tree) ++{ ++ znode *z; ++ ++ assert_rw_write_locked(&(tree->tree_lock)); ++ z = JZNODE(node); ++ ++ if (z->c_count == 0) { ++ /* detach znode from sibling list. */ ++ sibling_list_drop(z); ++ /* this is called with tree spin-lock held, so call ++ znode_remove() directly (rather than znode_lock_remove()). */ ++ znode_remove(z, tree); ++ return 0; ++ } ++ return RETERR(-EBUSY); ++} ++ ++/* ->init() method for formatted nodes */ ++static int init_znode(jnode * node) ++{ ++ znode *z; ++ ++ z = JZNODE(node); ++ /* call node plugin to do actual initialization */ ++ return z->nplug->init(z); ++} ++ ++/* ->clone() method for formatted nodes */ ++static jnode *clone_formatted(jnode * node) ++{ ++ znode *clone; ++ ++ assert("vs-1430", jnode_is_znode(node)); ++ clone = zalloc(reiser4_ctx_gfp_mask_get()); ++ if (clone == NULL) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ zinit(clone, NULL, current_tree); ++ jnode_set_block(ZJNODE(clone), jnode_get_block(node)); ++ /* ZJNODE(clone)->key.z is not initialized */ ++ clone->level = JZNODE(node)->level; ++ ++ return ZJNODE(clone); ++} ++ ++/* jplug->clone for unformatted nodes */ ++static jnode *clone_unformatted(jnode * node) ++{ ++ jnode *clone; ++ ++ assert("vs-1431", jnode_is_unformatted(node)); ++ clone = jalloc(); ++ if (clone == NULL) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ ++ jnode_init(clone, current_tree, JNODE_UNFORMATTED_BLOCK); ++ jnode_set_block(clone, jnode_get_block(node)); ++ ++ return clone; ++ ++} ++ ++/* ++ * Setup jnode plugin methods for various jnode types. ++ */ ++jnode_plugin jnode_plugins[LAST_JNODE_TYPE] = { ++ [JNODE_UNFORMATTED_BLOCK] = { ++ .h = { ++ .type_id = REISER4_JNODE_PLUGIN_TYPE, ++ .id = JNODE_UNFORMATTED_BLOCK, ++ .pops = NULL, ++ .label = "unformatted", ++ .desc = "unformatted node", ++ .linkage = {NULL, NULL} ++ }, ++ .init = init_noinit, ++ .parse = parse_noparse, ++ .mapping = mapping_jnode, ++ .index = index_jnode, ++ .clone = clone_unformatted ++ }, ++ [JNODE_FORMATTED_BLOCK] = { ++ .h = { ++ .type_id = REISER4_JNODE_PLUGIN_TYPE, ++ .id = JNODE_FORMATTED_BLOCK, ++ .pops = NULL, ++ .label = "formatted", ++ .desc = "formatted tree node", ++ .linkage = {NULL, NULL} ++ }, ++ .init = init_znode, ++ .parse = parse_znode, ++ .mapping = mapping_znode, ++ .index = index_znode, ++ .clone = clone_formatted ++ }, ++ [JNODE_BITMAP] = { ++ .h = { ++ .type_id = REISER4_JNODE_PLUGIN_TYPE, ++ .id = JNODE_BITMAP, ++ .pops = NULL, ++ .label = "bitmap", ++ .desc = "bitmap node", ++ .linkage = {NULL, NULL} ++ }, ++ .init = init_noinit, ++ .parse = parse_noparse, ++ .mapping = mapping_bitmap, ++ .index = index_is_address, ++ .clone = NULL ++ }, ++ [JNODE_IO_HEAD] = { ++ .h = { ++ .type_id = REISER4_JNODE_PLUGIN_TYPE, ++ .id = JNODE_IO_HEAD, ++ .pops = NULL, ++ .label = "io head", ++ .desc = "io head", ++ .linkage = {NULL, NULL} ++ }, ++ .init = init_noinit, ++ .parse = parse_noparse, ++ .mapping = mapping_bitmap, ++ .index = index_is_address, ++ .clone = NULL ++ }, ++ [JNODE_INODE] = { ++ .h = { ++ .type_id = REISER4_JNODE_PLUGIN_TYPE, ++ .id = JNODE_INODE, ++ .pops = NULL, ++ .label = "inode", ++ .desc = "inode's builtin jnode", ++ .linkage = {NULL, NULL} ++ }, ++ .init = NULL, ++ .parse = NULL, ++ .mapping = NULL, ++ .index = NULL, ++ .clone = NULL ++ } ++}; ++ ++/* ++ * jnode destruction. ++ * ++ * Thread may use a jnode after it acquired a reference to it. References are ++ * counted in ->x_count field. Reference protects jnode from being ++ * recycled. This is different from protecting jnode data (that are stored in ++ * jnode page) from being evicted from memory. Data are protected by jload() ++ * and released by jrelse(). ++ * ++ * If thread already possesses a reference to the jnode it can acquire another ++ * one through jref(). Initial reference is obtained (usually) by locating ++ * jnode in some indexing structure that depends on jnode type: formatted ++ * nodes are kept in global hash table, where they are indexed by block ++ * number, and also in the cbk cache. Unformatted jnodes are also kept in hash ++ * table, which is indexed by oid and offset within file, and in per-inode ++ * radix tree. ++ * ++ * Reference to jnode is released by jput(). If last reference is released, ++ * jput_final() is called. This function determines whether jnode has to be ++ * deleted (this happens when corresponding node is removed from the file ++ * system, jnode is marked with JNODE_HEARD_BANSHEE bit in this case), or it ++ * should be just "removed" (deleted from memory). ++ * ++ * Jnode destruction is signally delicate dance because of locking and RCU. ++ */ ++ ++/* ++ * Returns true if jnode cannot be removed right now. This check is called ++ * under tree lock. If it returns true, jnode is irrevocably committed to be ++ * deleted/removed. ++ */ ++static inline int jnode_is_busy(const jnode * node, jnode_type jtype) ++{ ++ /* if other thread managed to acquire a reference to this jnode, don't ++ * free it. */ ++ if (atomic_read(&node->x_count) > 0) ++ return 1; ++ /* also, don't free znode that has children in memory */ ++ if (jtype == JNODE_FORMATTED_BLOCK && JZNODE(node)->c_count > 0) ++ return 1; ++ return 0; ++} ++ ++/* ++ * this is called as part of removing jnode. Based on jnode type, call ++ * corresponding function that removes jnode from indices and returns it back ++ * to the appropriate slab (through RCU). ++ */ ++static inline void ++jnode_remove(jnode * node, jnode_type jtype, reiser4_tree * tree) ++{ ++ switch (jtype) { ++ case JNODE_UNFORMATTED_BLOCK: ++ remove_jnode(node, tree); ++ break; ++ case JNODE_IO_HEAD: ++ case JNODE_BITMAP: ++ break; ++ case JNODE_INODE: ++ break; ++ case JNODE_FORMATTED_BLOCK: ++ remove_znode(node, tree); ++ break; ++ default: ++ wrong_return_value("nikita-3196", "Wrong jnode type"); ++ } ++} ++ ++/* ++ * this is called as part of deleting jnode. Based on jnode type, call ++ * corresponding function that removes jnode from indices and returns it back ++ * to the appropriate slab (through RCU). ++ * ++ * This differs from jnode_remove() only for formatted nodes---for them ++ * sibling list handling is different for removal and deletion. ++ */ ++static inline void ++jnode_delete(jnode * node, jnode_type jtype, reiser4_tree * tree UNUSED_ARG) ++{ ++ switch (jtype) { ++ case JNODE_UNFORMATTED_BLOCK: ++ remove_jnode(node, tree); ++ break; ++ case JNODE_IO_HEAD: ++ case JNODE_BITMAP: ++ break; ++ case JNODE_FORMATTED_BLOCK: ++ delete_znode(node, tree); ++ break; ++ case JNODE_INODE: ++ default: ++ wrong_return_value("nikita-3195", "Wrong jnode type"); ++ } ++} ++ ++#if REISER4_DEBUG ++/* ++ * remove jnode from the debugging list of all jnodes hanging off super-block. ++ */ ++void jnode_list_remove(jnode * node) ++{ ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = get_super_private(jnode_get_tree(node)->super); ++ ++ spin_lock_irq(&sbinfo->all_guard); ++ assert("nikita-2422", !list_empty(&node->jnodes)); ++ list_del_init(&node->jnodes); ++ spin_unlock_irq(&sbinfo->all_guard); ++} ++#endif ++ ++/* ++ * this is called by jput_final() to remove jnode when last reference to it is ++ * released. ++ */ ++static int jnode_try_drop(jnode * node) ++{ ++ int result; ++ reiser4_tree *tree; ++ jnode_type jtype; ++ ++ assert("nikita-2491", node != NULL); ++ assert("nikita-2583", JF_ISSET(node, JNODE_RIP)); ++ ++ tree = jnode_get_tree(node); ++ jtype = jnode_get_type(node); ++ ++ spin_lock_jnode(node); ++ write_lock_tree(tree); ++ /* ++ * if jnode has a page---leave it alone. Memory pressure will ++ * eventually kill page and jnode. ++ */ ++ if (jnode_page(node) != NULL) { ++ write_unlock_tree(tree); ++ spin_unlock_jnode(node); ++ JF_CLR(node, JNODE_RIP); ++ return RETERR(-EBUSY); ++ } ++ ++ /* re-check ->x_count under tree lock. */ ++ result = jnode_is_busy(node, jtype); ++ if (result == 0) { ++ assert("nikita-2582", !JF_ISSET(node, JNODE_HEARD_BANSHEE)); ++ assert("jmacd-511/b", atomic_read(&node->d_count) == 0); ++ ++ spin_unlock_jnode(node); ++ /* no page and no references---despatch him. */ ++ jnode_remove(node, jtype, tree); ++ write_unlock_tree(tree); ++ jnode_free(node, jtype); ++ } else { ++ /* busy check failed: reference was acquired by concurrent ++ * thread. */ ++ write_unlock_tree(tree); ++ spin_unlock_jnode(node); ++ JF_CLR(node, JNODE_RIP); ++ } ++ return result; ++} ++ ++/* jdelete() -- Delete jnode from the tree and file system */ ++static int jdelete(jnode * node/* jnode to finish with */) ++{ ++ struct page *page; ++ int result; ++ reiser4_tree *tree; ++ jnode_type jtype; ++ ++ assert("nikita-467", node != NULL); ++ assert("nikita-2531", JF_ISSET(node, JNODE_RIP)); ++ ++ jtype = jnode_get_type(node); ++ ++ page = jnode_lock_page(node); ++ assert_spin_locked(&(node->guard)); ++ ++ tree = jnode_get_tree(node); ++ ++ write_lock_tree(tree); ++ /* re-check ->x_count under tree lock. */ ++ result = jnode_is_busy(node, jtype); ++ if (likely(!result)) { ++ assert("nikita-2123", JF_ISSET(node, JNODE_HEARD_BANSHEE)); ++ assert("jmacd-511", atomic_read(&node->d_count) == 0); ++ ++ /* detach page */ ++ if (page != NULL) { ++ /* ++ * FIXME this is racy against jnode_extent_write(). ++ */ ++ page_clear_jnode(page, node); ++ } ++ spin_unlock_jnode(node); ++ /* goodbye */ ++ jnode_delete(node, jtype, tree); ++ write_unlock_tree(tree); ++ jnode_free(node, jtype); ++ /* @node is no longer valid pointer */ ++ if (page != NULL) ++ reiser4_drop_page(page); ++ } else { ++ /* busy check failed: reference was acquired by concurrent ++ * thread. */ ++ JF_CLR(node, JNODE_RIP); ++ write_unlock_tree(tree); ++ spin_unlock_jnode(node); ++ if (page != NULL) ++ unlock_page(page); ++ } ++ return result; ++} ++ ++/* drop jnode on the floor. ++ ++ Return value: ++ ++ -EBUSY: failed to drop jnode, because there are still references to it ++ ++ 0: successfully dropped jnode ++ ++*/ ++static int jdrop_in_tree(jnode * node, reiser4_tree * tree) ++{ ++ struct page *page; ++ jnode_type jtype; ++ int result; ++ ++ assert("zam-602", node != NULL); ++ assert_rw_not_read_locked(&(tree->tree_lock)); ++ assert_rw_not_write_locked(&(tree->tree_lock)); ++ assert("nikita-2403", !JF_ISSET(node, JNODE_HEARD_BANSHEE)); ++ ++ jtype = jnode_get_type(node); ++ ++ page = jnode_lock_page(node); ++ assert_spin_locked(&(node->guard)); ++ ++ write_lock_tree(tree); ++ ++ /* re-check ->x_count under tree lock. */ ++ result = jnode_is_busy(node, jtype); ++ if (!result) { ++ assert("nikita-2488", page == jnode_page(node)); ++ assert("nikita-2533", atomic_read(&node->d_count) == 0); ++ if (page != NULL) { ++ assert("nikita-2126", !PageDirty(page)); ++ assert("nikita-2127", PageUptodate(page)); ++ assert("nikita-2181", PageLocked(page)); ++ page_clear_jnode(page, node); ++ } ++ spin_unlock_jnode(node); ++ jnode_remove(node, jtype, tree); ++ write_unlock_tree(tree); ++ jnode_free(node, jtype); ++ if (page != NULL) ++ reiser4_drop_page(page); ++ } else { ++ /* busy check failed: reference was acquired by concurrent ++ * thread. */ ++ JF_CLR(node, JNODE_RIP); ++ write_unlock_tree(tree); ++ spin_unlock_jnode(node); ++ if (page != NULL) ++ unlock_page(page); ++ } ++ return result; ++} ++ ++/* This function frees jnode "if possible". In particular, [dcx]_count has to ++ be 0 (where applicable). */ ++void jdrop(jnode * node) ++{ ++ jdrop_in_tree(node, jnode_get_tree(node)); ++} ++ ++/* IO head jnode implementation; The io heads are simple j-nodes with limited ++ functionality (these j-nodes are not in any hash table) just for reading ++ from and writing to disk. */ ++ ++jnode *reiser4_alloc_io_head(const reiser4_block_nr * block) ++{ ++ jnode *jal = jalloc(); ++ ++ if (jal != NULL) { ++ jnode_init(jal, current_tree, JNODE_IO_HEAD); ++ jnode_set_block(jal, block); ++ } ++ ++ jref(jal); ++ ++ return jal; ++} ++ ++void reiser4_drop_io_head(jnode * node) ++{ ++ assert("zam-648", jnode_get_type(node) == JNODE_IO_HEAD); ++ ++ jput(node); ++ jdrop(node); ++} ++ ++/* protect keep jnode data from reiser4_releasepage() */ ++void pin_jnode_data(jnode * node) ++{ ++ assert("zam-671", jnode_page(node) != NULL); ++ page_cache_get(jnode_page(node)); ++} ++ ++/* make jnode data free-able again */ ++void unpin_jnode_data(jnode * node) ++{ ++ assert("zam-672", jnode_page(node) != NULL); ++ page_cache_release(jnode_page(node)); ++} ++ ++struct address_space *jnode_get_mapping(const jnode * node) ++{ ++ assert("nikita-3162", node != NULL); ++ return jnode_ops(node)->mapping(node); ++} ++ ++#if REISER4_DEBUG ++/* debugging aid: jnode invariant */ ++int jnode_invariant_f(const jnode * node, char const **msg) ++{ ++#define _ergo(ant, con) \ ++ ((*msg) = "{" #ant "} ergo {" #con "}", ergo((ant), (con))) ++#define _check(exp) ((*msg) = #exp, (exp)) ++ ++ return _check(node != NULL) && ++ /* [jnode-queued] */ ++ /* only relocated node can be queued, except that when znode ++ * is being deleted, its JNODE_RELOC bit is cleared */ ++ _ergo(JF_ISSET(node, JNODE_FLUSH_QUEUED), ++ JF_ISSET(node, JNODE_RELOC) || ++ JF_ISSET(node, JNODE_HEARD_BANSHEE)) && ++ _check(node->jnodes.prev != NULL) && ++ _check(node->jnodes.next != NULL) && ++ /* [jnode-dirty] invariant */ ++ /* dirty inode is part of atom */ ++ _ergo(JF_ISSET(node, JNODE_DIRTY), node->atom != NULL) && ++ /* [jnode-oid] invariant */ ++ /* for unformatted node ->objectid and ->mapping fields are ++ * consistent */ ++ _ergo(jnode_is_unformatted(node) && node->key.j.mapping != NULL, ++ node->key.j.objectid == ++ get_inode_oid(node->key.j.mapping->host)) && ++ /* [jnode-atom-valid] invariant */ ++ /* node atom has valid state */ ++ _ergo(node->atom != NULL, node->atom->stage != ASTAGE_INVALID) && ++ /* [jnode-page-binding] invariant */ ++ /* if node points to page, it points back to node */ ++ _ergo(node->pg != NULL, jprivate(node->pg) == node) && ++ /* [jnode-refs] invariant */ ++ /* only referenced jnode can be loaded */ ++ _check(atomic_read(&node->x_count) >= atomic_read(&node->d_count)); ++ ++} ++ ++static const char *jnode_type_name(jnode_type type) ++{ ++ switch (type) { ++ case JNODE_UNFORMATTED_BLOCK: ++ return "unformatted"; ++ case JNODE_FORMATTED_BLOCK: ++ return "formatted"; ++ case JNODE_BITMAP: ++ return "bitmap"; ++ case JNODE_IO_HEAD: ++ return "io head"; ++ case JNODE_INODE: ++ return "inode"; ++ case LAST_JNODE_TYPE: ++ return "last"; ++ default:{ ++ static char unknown[30]; ++ ++ sprintf(unknown, "unknown %i", type); ++ return unknown; ++ } ++ } ++} ++ ++#define jnode_state_name(node, flag) \ ++ (JF_ISSET((node), (flag)) ? ((#flag "|")+6) : "") ++ ++/* debugging aid: output human readable information about @node */ ++static void info_jnode(const char *prefix /* prefix to print */ , ++ const jnode * node/* node to print */) ++{ ++ assert("umka-068", prefix != NULL); ++ ++ if (node == NULL) { ++ printk("%s: null\n", prefix); ++ return; ++ } ++ ++ printk ++ ("%s: %p: state: %lx: [%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s], level: %i," ++ " block: %s, d_count: %d, x_count: %d, " ++ "pg: %p, atom: %p, lock: %i:%i, type: %s, ", prefix, node, ++ node->state, ++ jnode_state_name(node, JNODE_PARSED), ++ jnode_state_name(node, JNODE_HEARD_BANSHEE), ++ jnode_state_name(node, JNODE_LEFT_CONNECTED), ++ jnode_state_name(node, JNODE_RIGHT_CONNECTED), ++ jnode_state_name(node, JNODE_ORPHAN), ++ jnode_state_name(node, JNODE_CREATED), ++ jnode_state_name(node, JNODE_RELOC), ++ jnode_state_name(node, JNODE_OVRWR), ++ jnode_state_name(node, JNODE_DIRTY), ++ jnode_state_name(node, JNODE_IS_DYING), ++ jnode_state_name(node, JNODE_RIP), ++ jnode_state_name(node, JNODE_MISSED_IN_CAPTURE), ++ jnode_state_name(node, JNODE_WRITEBACK), ++ jnode_state_name(node, JNODE_NEW), ++ jnode_state_name(node, JNODE_DKSET), ++ jnode_state_name(node, JNODE_REPACK), ++ jnode_state_name(node, JNODE_CLUSTER_PAGE), ++ jnode_get_level(node), sprint_address(jnode_get_block(node)), ++ atomic_read(&node->d_count), atomic_read(&node->x_count), ++ jnode_page(node), node->atom, 0, 0, ++ jnode_type_name(jnode_get_type(node))); ++ if (jnode_is_unformatted(node)) { ++ printk("inode: %llu, index: %lu, ", ++ node->key.j.objectid, node->key.j.index); ++ } ++} ++ ++/* debugging aid: check znode invariant and panic if it doesn't hold */ ++static int jnode_invariant(jnode * node, int tlocked, int jlocked) ++{ ++ char const *failed_msg; ++ int result; ++ reiser4_tree *tree; ++ ++ tree = jnode_get_tree(node); ++ ++ assert("umka-063312", node != NULL); ++ assert("umka-064321", tree != NULL); ++ ++ if (!jlocked && !tlocked) ++ spin_lock_jnode((jnode *) node); ++ if (!tlocked) ++ read_lock_tree(jnode_get_tree(node)); ++ result = jnode_invariant_f(node, &failed_msg); ++ if (!result) { ++ info_jnode("corrupted node", node); ++ warning("jmacd-555", "Condition %s failed", failed_msg); ++ } ++ if (!tlocked) ++ read_unlock_tree(jnode_get_tree(node)); ++ if (!jlocked && !tlocked) ++ spin_unlock_jnode((jnode *) node); ++ return result; ++} ++ ++#endif /* REISER4_DEBUG */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/jnode.h linux-2.6.30/fs/reiser4/jnode.h +--- linux-2.6.30.orig/fs/reiser4/jnode.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/jnode.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,704 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Declaration of jnode. See jnode.c for details. */ ++ ++#ifndef __JNODE_H__ ++#define __JNODE_H__ ++ ++#include "forward.h" ++#include "type_safe_hash.h" ++#include "txnmgr.h" ++#include "key.h" ++#include "debug.h" ++#include "dformat.h" ++#include "page_cache.h" ++#include "context.h" ++ ++#include "plugin/plugin.h" ++ ++#include <linux/fs.h> ++#include <linux/mm.h> ++#include <linux/spinlock.h> ++#include <asm/atomic.h> ++#include <linux/bitops.h> ++#include <linux/list.h> ++#include <linux/rcupdate.h> ++ ++/* declare hash table of jnodes (jnodes proper, that is, unformatted ++ nodes) */ ++TYPE_SAFE_HASH_DECLARE(j, jnode); ++ ++/* declare hash table of znodes */ ++TYPE_SAFE_HASH_DECLARE(z, znode); ++ ++struct jnode_key { ++ __u64 objectid; ++ unsigned long index; ++ struct address_space *mapping; ++}; ++ ++/* ++ Jnode is the "base class" of other nodes in reiser4. It is also happens to ++ be exactly the node we use for unformatted tree nodes. ++ ++ Jnode provides following basic functionality: ++ ++ . reference counting and indexing. ++ ++ . integration with page cache. Jnode has ->pg reference to which page can ++ be attached. ++ ++ . interface to transaction manager. It is jnode that is kept in transaction ++ manager lists, attached to atoms, etc. (NOTE-NIKITA one may argue that this ++ means, there should be special type of jnode for inode.) ++ ++ Locking: ++ ++ Spin lock: the following fields are protected by the per-jnode spin lock: ++ ++ ->state ++ ->atom ++ ->capture_link ++ ++ Following fields are protected by the global tree lock: ++ ++ ->link ++ ->key.z (content of ->key.z is only changed in znode_rehash()) ++ ->key.j ++ ++ Atomic counters ++ ++ ->x_count ++ ->d_count ++ ++ ->pg, and ->data are protected by spin lock for unused jnode and are ++ immutable for used jnode (one for which fs/reiser4/vfs_ops.c:releasable() ++ is false). ++ ++ ->tree is immutable after creation ++ ++ Unclear ++ ++ ->blocknr: should be under jnode spin-lock, but current interface is based ++ on passing of block address. ++ ++ If you ever need to spin lock two nodes at once, do this in "natural" ++ memory order: lock znode with lower address first. (See lock_two_nodes().) ++ ++ Invariants involving this data-type: ++ ++ [jnode-dirty] ++ [jnode-refs] ++ [jnode-oid] ++ [jnode-queued] ++ [jnode-atom-valid] ++ [jnode-page-binding] ++*/ ++ ++struct jnode { ++#if REISER4_DEBUG ++#define JMAGIC 0x52654973 /* "ReIs" */ ++ int magic; ++#endif ++ /* FIRST CACHE LINE (16 bytes): data used by jload */ ++ ++ /* jnode's state: bitwise flags from the reiser4_jnode_state enum. */ ++ /* 0 */ unsigned long state; ++ ++ /* lock, protecting jnode's fields. */ ++ /* 4 */ spinlock_t load; ++ ++ /* counter of references to jnode itself. Increased on jref(). ++ Decreased on jput(). ++ */ ++ /* 8 */ atomic_t x_count; ++ ++ /* counter of references to jnode's data. Pin data page(s) in ++ memory while this is greater than 0. Increased on jload(). ++ Decreased on jrelse(). ++ */ ++ /* 12 */ atomic_t d_count; ++ ++ /* SECOND CACHE LINE: data used by hash table lookups */ ++ ++ /* 16 */ union { ++ /* znodes are hashed by block number */ ++ reiser4_block_nr z; ++ /* unformatted nodes are hashed by mapping plus offset */ ++ struct jnode_key j; ++ } key; ++ ++ /* THIRD CACHE LINE */ ++ ++ /* 32 */ union { ++ /* pointers to maintain hash-table */ ++ z_hash_link z; ++ j_hash_link j; ++ } link; ++ ++ /* pointer to jnode page. */ ++ /* 36 */ struct page *pg; ++ /* pointer to node itself. This is page_address(node->pg) when page is ++ attached to the jnode ++ */ ++ /* 40 */ void *data; ++ ++ /* 44 */ reiser4_tree *tree; ++ ++ /* FOURTH CACHE LINE: atom related fields */ ++ ++ /* 48 */ spinlock_t guard; ++ ++ /* atom the block is in, if any */ ++ /* 52 */ txn_atom *atom; ++ ++ /* capture list */ ++ /* 56 */ struct list_head capture_link; ++ ++ /* FIFTH CACHE LINE */ ++ ++ /* 64 */ struct rcu_head rcu; ++ /* crosses cache line */ ++ ++ /* SIXTH CACHE LINE */ ++ ++ /* the real blocknr (where io is going to/from) */ ++ /* 80 */ reiser4_block_nr blocknr; ++ /* Parent item type, unformatted and CRC need it for ++ * offset => key conversion. */ ++ /* NOTE: this parent_item_id looks like jnode type. */ ++ /* 88 */ reiser4_plugin_id parent_item_id; ++ /* 92 */ ++#if REISER4_DEBUG ++ /* list of all jnodes for debugging purposes. */ ++ struct list_head jnodes; ++ /* how many times this jnode was written in one transaction */ ++ int written; ++ /* this indicates which atom's list the jnode is on */ ++ atom_list list; ++#endif ++} __attribute__ ((aligned(16))); ++ ++/* ++ * jnode types. Enumeration of existing jnode types. ++ */ ++typedef enum { ++ JNODE_UNFORMATTED_BLOCK, /* unformatted block */ ++ JNODE_FORMATTED_BLOCK, /* formatted block, znode */ ++ JNODE_BITMAP, /* bitmap */ ++ JNODE_IO_HEAD, /* jnode representing a block in the ++ * wandering log */ ++ JNODE_INODE, /* jnode embedded into inode */ ++ LAST_JNODE_TYPE ++} jnode_type; ++ ++/* jnode states */ ++typedef enum { ++ /* jnode's page is loaded and data checked */ ++ JNODE_PARSED = 0, ++ /* node was deleted, not all locks on it were released. This ++ node is empty and is going to be removed from the tree ++ shortly. */ ++ JNODE_HEARD_BANSHEE = 1, ++ /* left sibling pointer is valid */ ++ JNODE_LEFT_CONNECTED = 2, ++ /* right sibling pointer is valid */ ++ JNODE_RIGHT_CONNECTED = 3, ++ ++ /* znode was just created and doesn't yet have a pointer from ++ its parent */ ++ JNODE_ORPHAN = 4, ++ ++ /* this node was created by its transaction and has not been assigned ++ a block address. */ ++ JNODE_CREATED = 5, ++ ++ /* this node is currently relocated */ ++ JNODE_RELOC = 6, ++ /* this node is currently wandered */ ++ JNODE_OVRWR = 7, ++ ++ /* this znode has been modified */ ++ JNODE_DIRTY = 8, ++ ++ /* znode lock is being invalidated */ ++ JNODE_IS_DYING = 9, ++ ++ /* THIS PLACE IS INTENTIONALLY LEFT BLANK */ ++ ++ /* jnode is queued for flushing. */ ++ JNODE_FLUSH_QUEUED = 12, ++ ++ /* In the following bits jnode type is encoded. */ ++ JNODE_TYPE_1 = 13, ++ JNODE_TYPE_2 = 14, ++ JNODE_TYPE_3 = 15, ++ ++ /* jnode is being destroyed */ ++ JNODE_RIP = 16, ++ ++ /* znode was not captured during locking (it might so be because ++ ->level != LEAF_LEVEL and lock_mode == READ_LOCK) */ ++ JNODE_MISSED_IN_CAPTURE = 17, ++ ++ /* write is in progress */ ++ JNODE_WRITEBACK = 18, ++ ++ /* FIXME: now it is used by crypto-compress plugin only */ ++ JNODE_NEW = 19, ++ ++ /* delimiting keys are already set for this znode. */ ++ JNODE_DKSET = 20, ++ ++ /* when this bit is set page and jnode can not be disconnected */ ++ JNODE_WRITE_PREPARED = 21, ++ ++ JNODE_CLUSTER_PAGE = 22, ++ /* Jnode is marked for repacking, that means the reiser4 flush and the ++ * block allocator should process this node special way */ ++ JNODE_REPACK = 23, ++ /* node should be converted by flush in squalloc phase */ ++ JNODE_CONVERTIBLE = 24, ++ /* ++ * When jnode is dirtied for the first time in given transaction, ++ * do_jnode_make_dirty() checks whether this jnode can possible became ++ * member of overwrite set. If so, this bit is set, and one block is ++ * reserved in the ->flush_reserved space of atom. ++ * ++ * This block is "used" (and JNODE_FLUSH_RESERVED bit is cleared) when ++ * ++ * (1) flush decides that we want this block to go into relocate ++ * set after all. ++ * ++ * (2) wandering log is allocated (by log writer) ++ * ++ * (3) extent is allocated ++ * ++ */ ++ JNODE_FLUSH_RESERVED = 29 ++} reiser4_jnode_state; ++ ++/* Macros for accessing the jnode state. */ ++ ++static inline void JF_CLR(jnode * j, int f) ++{ ++ assert("unknown-1", j->magic == JMAGIC); ++ clear_bit(f, &j->state); ++} ++static inline int JF_ISSET(const jnode * j, int f) ++{ ++ assert("unknown-2", j->magic == JMAGIC); ++ return test_bit(f, &((jnode *) j)->state); ++} ++static inline void JF_SET(jnode * j, int f) ++{ ++ assert("unknown-3", j->magic == JMAGIC); ++ set_bit(f, &j->state); ++} ++ ++static inline int JF_TEST_AND_SET(jnode * j, int f) ++{ ++ assert("unknown-4", j->magic == JMAGIC); ++ return test_and_set_bit(f, &j->state); ++} ++ ++static inline void spin_lock_jnode(jnode *node) ++{ ++ /* check that spinlocks of lower priorities are not held */ ++ assert("", (LOCK_CNT_NIL(rw_locked_tree) && ++ LOCK_CNT_NIL(spin_locked_txnh) && ++ LOCK_CNT_NIL(spin_locked_zlock) && ++ LOCK_CNT_NIL(rw_locked_dk) && ++ LOCK_CNT_LT(spin_locked_jnode, 2))); ++ ++ spin_lock(&(node->guard)); ++ ++ LOCK_CNT_INC(spin_locked_jnode); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline void spin_unlock_jnode(jnode *node) ++{ ++ assert_spin_locked(&(node->guard)); ++ assert("nikita-1375", LOCK_CNT_GTZ(spin_locked_jnode)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ LOCK_CNT_DEC(spin_locked_jnode); ++ LOCK_CNT_DEC(spin_locked); ++ ++ spin_unlock(&(node->guard)); ++} ++ ++static inline int jnode_is_in_deleteset(const jnode * node) ++{ ++ return JF_ISSET(node, JNODE_RELOC); ++} ++ ++extern int init_jnodes(void); ++extern void done_jnodes(void); ++ ++/* Jnode routines */ ++extern jnode *jalloc(void); ++extern void jfree(jnode * node) NONNULL; ++extern jnode *jclone(jnode *); ++extern jnode *jlookup(reiser4_tree * tree, ++ oid_t objectid, unsigned long ind) NONNULL; ++extern jnode *jfind(struct address_space *, unsigned long index) NONNULL; ++extern jnode *jnode_by_page(struct page *pg) NONNULL; ++extern jnode *jnode_of_page(struct page *pg) NONNULL; ++void jnode_attach_page(jnode * node, struct page *pg); ++ ++void unhash_unformatted_jnode(jnode *); ++extern jnode *page_next_jnode(jnode * node) NONNULL; ++extern void jnode_init(jnode * node, reiser4_tree * tree, jnode_type) NONNULL; ++extern void jnode_make_dirty(jnode * node) NONNULL; ++extern void jnode_make_clean(jnode * node) NONNULL; ++extern void jnode_make_wander_nolock(jnode * node) NONNULL; ++extern void jnode_make_wander(jnode *) NONNULL; ++extern void znode_make_reloc(znode * , flush_queue_t *) NONNULL; ++extern void unformatted_make_reloc(jnode *, flush_queue_t *) NONNULL; ++extern struct address_space *jnode_get_mapping(const jnode * node) NONNULL; ++ ++/** ++ * jnode_get_block ++ * @node: jnode to query ++ * ++ */ ++static inline const reiser4_block_nr *jnode_get_block(const jnode *node) ++{ ++ assert("nikita-528", node != NULL); ++ ++ return &node->blocknr; ++} ++ ++/** ++ * jnode_set_block ++ * @node: jnode to update ++ * @blocknr: new block nr ++ */ ++static inline void jnode_set_block(jnode *node, const reiser4_block_nr *blocknr) ++{ ++ assert("nikita-2020", node != NULL); ++ assert("umka-055", blocknr != NULL); ++ node->blocknr = *blocknr; ++} ++ ++ ++/* block number for IO. Usually this is the same as jnode_get_block(), unless ++ * jnode was emergency flushed---then block number chosen by eflush is ++ * used. */ ++static inline const reiser4_block_nr *jnode_get_io_block(jnode * node) ++{ ++ assert("nikita-2768", node != NULL); ++ assert_spin_locked(&(node->guard)); ++ ++ return jnode_get_block(node); ++} ++ ++/* Jnode flush interface. */ ++extern reiser4_blocknr_hint *reiser4_pos_hint(flush_pos_t *pos); ++extern flush_queue_t *reiser4_pos_fq(flush_pos_t *pos); ++ ++/* FIXME-VS: these are used in plugin/item/extent.c */ ++ ++/* does extent_get_block have to be called */ ++#define jnode_mapped(node) JF_ISSET (node, JNODE_MAPPED) ++#define jnode_set_mapped(node) JF_SET (node, JNODE_MAPPED) ++ ++/* the node should be converted during flush squalloc phase */ ++#define jnode_convertible(node) JF_ISSET (node, JNODE_CONVERTIBLE) ++#define jnode_set_convertible(node) JF_SET (node, JNODE_CONVERTIBLE) ++ ++/* Macros to convert from jnode to znode, znode to jnode. These are macros ++ because C doesn't allow overloading of const prototypes. */ ++#define ZJNODE(x) (&(x)->zjnode) ++#define JZNODE(x) \ ++({ \ ++ typeof(x) __tmp_x; \ ++ \ ++ __tmp_x = (x); \ ++ assert("jmacd-1300", jnode_is_znode(__tmp_x)); \ ++ (znode*) __tmp_x; \ ++}) ++ ++extern int jnodes_tree_init(reiser4_tree * tree); ++extern int jnodes_tree_done(reiser4_tree * tree); ++ ++#if REISER4_DEBUG ++ ++extern int znode_is_any_locked(const znode * node); ++extern void jnode_list_remove(jnode * node); ++ ++#else ++ ++#define jnode_list_remove(node) noop ++ ++#endif ++ ++int znode_is_root(const znode * node) NONNULL; ++ ++/* bump reference counter on @node */ ++static inline void add_x_ref(jnode * node/* node to increase x_count of */) ++{ ++ assert("nikita-1911", node != NULL); ++ ++ atomic_inc(&node->x_count); ++ LOCK_CNT_INC(x_refs); ++} ++ ++static inline void dec_x_ref(jnode * node) ++{ ++ assert("nikita-3215", node != NULL); ++ assert("nikita-3216", atomic_read(&node->x_count) > 0); ++ ++ atomic_dec(&node->x_count); ++ assert("nikita-3217", LOCK_CNT_GTZ(x_refs)); ++ LOCK_CNT_DEC(x_refs); ++} ++ ++/* jref() - increase counter of references to jnode/znode (x_count) */ ++static inline jnode *jref(jnode * node) ++{ ++ assert("jmacd-508", (node != NULL) && !IS_ERR(node)); ++ add_x_ref(node); ++ return node; ++} ++ ++/* get the page of jnode */ ++static inline struct page *jnode_page(const jnode * node) ++{ ++ return node->pg; ++} ++ ++/* return pointer to jnode data */ ++static inline char *jdata(const jnode * node) ++{ ++ assert("nikita-1415", node != NULL); ++ assert("nikita-3198", jnode_page(node) != NULL); ++ return node->data; ++} ++ ++static inline int jnode_is_loaded(const jnode * node) ++{ ++ assert("zam-506", node != NULL); ++ return atomic_read(&node->d_count) > 0; ++} ++ ++extern void page_clear_jnode(struct page *page, jnode * node) NONNULL; ++ ++static inline void jnode_set_reloc(jnode * node) ++{ ++ assert("nikita-2431", node != NULL); ++ assert("nikita-2432", !JF_ISSET(node, JNODE_OVRWR)); ++ JF_SET(node, JNODE_RELOC); ++} ++ ++/* jload/jwrite/junload give a bread/bwrite/brelse functionality for jnodes */ ++ ++extern int jload_gfp(jnode *, gfp_t, int do_kmap) NONNULL; ++ ++static inline int jload(jnode *node) ++{ ++ return jload_gfp(node, reiser4_ctx_gfp_mask_get(), 1); ++} ++ ++extern int jinit_new(jnode *, gfp_t) NONNULL; ++extern int jstartio(jnode *) NONNULL; ++ ++extern void jdrop(jnode *) NONNULL; ++extern int jwait_io(jnode *, int rw) NONNULL; ++ ++void jload_prefetch(jnode *); ++ ++extern jnode *reiser4_alloc_io_head(const reiser4_block_nr * block) NONNULL; ++extern void reiser4_drop_io_head(jnode * node) NONNULL; ++ ++static inline reiser4_tree *jnode_get_tree(const jnode * node) ++{ ++ assert("nikita-2691", node != NULL); ++ return node->tree; ++} ++ ++extern void pin_jnode_data(jnode *); ++extern void unpin_jnode_data(jnode *); ++ ++static inline jnode_type jnode_get_type(const jnode * node) ++{ ++ static const unsigned long state_mask = ++ (1 << JNODE_TYPE_1) | (1 << JNODE_TYPE_2) | (1 << JNODE_TYPE_3); ++ ++ static jnode_type mask_to_type[] = { ++ /* JNODE_TYPE_3 : JNODE_TYPE_2 : JNODE_TYPE_1 */ ++ ++ /* 000 */ ++ [0] = JNODE_FORMATTED_BLOCK, ++ /* 001 */ ++ [1] = JNODE_UNFORMATTED_BLOCK, ++ /* 010 */ ++ [2] = JNODE_BITMAP, ++ /* 011 */ ++ [3] = LAST_JNODE_TYPE, /*invalid */ ++ /* 100 */ ++ [4] = JNODE_INODE, ++ /* 101 */ ++ [5] = LAST_JNODE_TYPE, ++ /* 110 */ ++ [6] = JNODE_IO_HEAD, ++ /* 111 */ ++ [7] = LAST_JNODE_TYPE, /* invalid */ ++ }; ++ ++ return mask_to_type[(node->state & state_mask) >> JNODE_TYPE_1]; ++} ++ ++/* returns true if node is a znode */ ++static inline int jnode_is_znode(const jnode * node) ++{ ++ return jnode_get_type(node) == JNODE_FORMATTED_BLOCK; ++} ++ ++static inline int jnode_is_flushprepped(jnode * node) ++{ ++ assert("jmacd-78212", node != NULL); ++ assert_spin_locked(&(node->guard)); ++ return !JF_ISSET(node, JNODE_DIRTY) || JF_ISSET(node, JNODE_RELOC) || ++ JF_ISSET(node, JNODE_OVRWR); ++} ++ ++/* Return true if @node has already been processed by the squeeze and allocate ++ process. This implies the block address has been finalized for the ++ duration of this atom (or it is clean and will remain in place). If this ++ returns true you may use the block number as a hint. */ ++static inline int jnode_check_flushprepped(jnode * node) ++{ ++ int result; ++ ++ /* It must be clean or relocated or wandered. New allocations are set ++ * to relocate. */ ++ spin_lock_jnode(node); ++ result = jnode_is_flushprepped(node); ++ spin_unlock_jnode(node); ++ return result; ++} ++ ++/* returns true if node is unformatted */ ++static inline int jnode_is_unformatted(const jnode * node) ++{ ++ assert("jmacd-0123", node != NULL); ++ return jnode_get_type(node) == JNODE_UNFORMATTED_BLOCK; ++} ++ ++/* returns true if node represents a cluster cache page */ ++static inline int jnode_is_cluster_page(const jnode * node) ++{ ++ assert("edward-50", node != NULL); ++ return (JF_ISSET(node, JNODE_CLUSTER_PAGE)); ++} ++ ++/* returns true is node is builtin inode's jnode */ ++static inline int jnode_is_inode(const jnode * node) ++{ ++ assert("vs-1240", node != NULL); ++ return jnode_get_type(node) == JNODE_INODE; ++} ++ ++static inline jnode_plugin *jnode_ops_of(const jnode_type type) ++{ ++ assert("nikita-2367", type < LAST_JNODE_TYPE); ++ return jnode_plugin_by_id((reiser4_plugin_id) type); ++} ++ ++static inline jnode_plugin *jnode_ops(const jnode * node) ++{ ++ assert("nikita-2366", node != NULL); ++ ++ return jnode_ops_of(jnode_get_type(node)); ++} ++ ++/* Get the index of a block. */ ++static inline unsigned long jnode_get_index(jnode * node) ++{ ++ return jnode_ops(node)->index(node); ++} ++ ++/* return true if "node" is the root */ ++static inline int jnode_is_root(const jnode * node) ++{ ++ return jnode_is_znode(node) && znode_is_root(JZNODE(node)); ++} ++ ++extern struct address_space *mapping_jnode(const jnode * node); ++extern unsigned long index_jnode(const jnode * node); ++ ++static inline void jput(jnode * node); ++extern void jput_final(jnode * node); ++ ++/* bump data counter on @node */ ++static inline void add_d_ref(jnode * node/* node to increase d_count of */) ++{ ++ assert("nikita-1962", node != NULL); ++ ++ atomic_inc(&node->d_count); ++ if (jnode_is_unformatted(node) || jnode_is_znode(node)) ++ LOCK_CNT_INC(d_refs); ++} ++ ++/* jput() - decrement x_count reference counter on znode. ++ ++ Count may drop to 0, jnode stays in cache until memory pressure causes the ++ eviction of its page. The c_count variable also ensures that children are ++ pressured out of memory before the parent. The jnode remains hashed as ++ long as the VM allows its page to stay in memory. ++*/ ++static inline void jput(jnode * node) ++{ ++ assert("jmacd-509", node != NULL); ++ assert("jmacd-510", atomic_read(&node->x_count) > 0); ++ assert("zam-926", reiser4_schedulable()); ++ LOCK_CNT_DEC(x_refs); ++ ++ rcu_read_lock(); ++ /* ++ * we don't need any kind of lock here--jput_final() uses RCU. ++ */ ++ if (unlikely(atomic_dec_and_test(&node->x_count))) ++ jput_final(node); ++ else ++ rcu_read_unlock(); ++ assert("nikita-3473", reiser4_schedulable()); ++} ++ ++extern void jrelse(jnode * node); ++extern void jrelse_tail(jnode * node); ++ ++extern jnode *jnode_rip_sync(reiser4_tree * t, jnode * node); ++ ++/* resolve race with jput */ ++static inline jnode *jnode_rip_check(reiser4_tree * tree, jnode * node) ++{ ++ if (unlikely(JF_ISSET(node, JNODE_RIP))) ++ node = jnode_rip_sync(tree, node); ++ return node; ++} ++ ++extern reiser4_key *jnode_build_key(const jnode *node, reiser4_key * key); ++ ++#if REISER4_DEBUG ++extern int jnode_invariant_f(const jnode *node, char const **msg); ++#endif ++ ++extern jnode_plugin jnode_plugins[LAST_JNODE_TYPE]; ++ ++/* __JNODE_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/kassign.c linux-2.6.30/fs/reiser4/kassign.c +--- linux-2.6.30.orig/fs/reiser4/kassign.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/kassign.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,677 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Key assignment policy implementation */ ++ ++/* ++ * In reiser4 every piece of file system data and meta-data has a key. Keys ++ * are used to store information in and retrieve it from reiser4 internal ++ * tree. In addition to this, keys define _ordering_ of all file system ++ * information: things having close keys are placed into the same or ++ * neighboring (in the tree order) nodes of the tree. As our block allocator ++ * tries to respect tree order (see flush.c), keys also define order in which ++ * things are laid out on the disk, and hence, affect performance directly. ++ * ++ * Obviously, assignment of keys to data and meta-data should be consistent ++ * across whole file system. Algorithm that calculates a key for a given piece ++ * of data or meta-data is referred to as "key assignment". ++ * ++ * Key assignment is too expensive to be implemented as a plugin (that is, ++ * with an ability to support different key assignment schemas in the same ++ * compiled kernel image). As a compromise, all key-assignment functions and ++ * data-structures are collected in this single file, so that modifications to ++ * key assignment algorithm can be localized. Additional changes may be ++ * required in key.[ch]. ++ * ++ * Current default reiser4 key assignment algorithm is dubbed "Plan A". As one ++ * may guess, there is "Plan B" too. ++ * ++ */ ++ ++/* ++ * Additional complication with key assignment implementation is a requirement ++ * to support different key length. ++ */ ++ ++/* ++ * KEY ASSIGNMENT: PLAN A, LONG KEYS. ++ * ++ * DIRECTORY ITEMS ++ * ++ * | 60 | 4 | 7 |1| 56 | 64 | 64 | ++ * +--------------+---+---+-+-------------+------------------+-----------------+ ++ * | dirid | 0 | F |H| prefix-1 | prefix-2 | prefix-3/hash | ++ * +--------------+---+---+-+-------------+------------------+-----------------+ ++ * | | | | | ++ * | 8 bytes | 8 bytes | 8 bytes | 8 bytes | ++ * ++ * dirid objectid of directory this item is for ++ * ++ * F fibration, see fs/reiser4/plugin/fibration.[ch] ++ * ++ * H 1 if last 8 bytes of the key contain hash, ++ * 0 if last 8 bytes of the key contain prefix-3 ++ * ++ * prefix-1 first 7 characters of file name. ++ * Padded by zeroes if name is not long enough. ++ * ++ * prefix-2 next 8 characters of the file name. ++ * ++ * prefix-3 next 8 characters of the file name. ++ * ++ * hash hash of the rest of file name (i.e., portion of file ++ * name not included into prefix-1 and prefix-2). ++ * ++ * File names shorter than 23 (== 7 + 8 + 8) characters are completely encoded ++ * in the key. Such file names are called "short". They are distinguished by H ++ * bit set 0 in the key. ++ * ++ * Other file names are "long". For long name, H bit is 1, and first 15 (== 7 ++ * + 8) characters are encoded in prefix-1 and prefix-2 portions of the ++ * key. Last 8 bytes of the key are occupied by hash of the remaining ++ * characters of the name. ++ * ++ * This key assignment reaches following important goals: ++ * ++ * (1) directory entries are sorted in approximately lexicographical ++ * order. ++ * ++ * (2) collisions (when multiple directory items have the same key), while ++ * principally unavoidable in a tree with fixed length keys, are rare. ++ * ++ * STAT DATA ++ * ++ * | 60 | 4 | 64 | 4 | 60 | 64 | ++ * +--------------+---+-----------------+---+--------------+-----------------+ ++ * | locality id | 1 | ordering | 0 | objectid | 0 | ++ * +--------------+---+-----------------+---+--------------+-----------------+ ++ * | | | | | ++ * | 8 bytes | 8 bytes | 8 bytes | 8 bytes | ++ * ++ * locality id object id of a directory where first name was created for ++ * the object ++ * ++ * ordering copy of second 8-byte portion of the key of directory ++ * entry for the first name of this object. Ordering has a form ++ * { ++ * fibration :7; ++ * h :1; ++ * prefix1 :56; ++ * } ++ * see description of key for directory entry above. ++ * ++ * objectid object id for this object ++ * ++ * This key assignment policy is designed to keep stat-data in the same order ++ * as corresponding directory items, thus speeding up readdir/stat types of ++ * workload. ++ * ++ * FILE BODY ++ * ++ * | 60 | 4 | 64 | 4 | 60 | 64 | ++ * +--------------+---+-----------------+---+--------------+-----------------+ ++ * | locality id | 4 | ordering | 0 | objectid | offset | ++ * +--------------+---+-----------------+---+--------------+-----------------+ ++ * | | | | | ++ * | 8 bytes | 8 bytes | 8 bytes | 8 bytes | ++ * ++ * locality id object id of a directory where first name was created for ++ * the object ++ * ++ * ordering the same as in the key of stat-data for this object ++ * ++ * objectid object id for this object ++ * ++ * offset logical offset from the beginning of this file. ++ * Measured in bytes. ++ * ++ * ++ * KEY ASSIGNMENT: PLAN A, SHORT KEYS. ++ * ++ * DIRECTORY ITEMS ++ * ++ * | 60 | 4 | 7 |1| 56 | 64 | ++ * +--------------+---+---+-+-------------+-----------------+ ++ * | dirid | 0 | F |H| prefix-1 | prefix-2/hash | ++ * +--------------+---+---+-+-------------+-----------------+ ++ * | | | | ++ * | 8 bytes | 8 bytes | 8 bytes | ++ * ++ * dirid objectid of directory this item is for ++ * ++ * F fibration, see fs/reiser4/plugin/fibration.[ch] ++ * ++ * H 1 if last 8 bytes of the key contain hash, ++ * 0 if last 8 bytes of the key contain prefix-2 ++ * ++ * prefix-1 first 7 characters of file name. ++ * Padded by zeroes if name is not long enough. ++ * ++ * prefix-2 next 8 characters of the file name. ++ * ++ * hash hash of the rest of file name (i.e., portion of file ++ * name not included into prefix-1). ++ * ++ * File names shorter than 15 (== 7 + 8) characters are completely encoded in ++ * the key. Such file names are called "short". They are distinguished by H ++ * bit set in the key. ++ * ++ * Other file names are "long". For long name, H bit is 0, and first 7 ++ * characters are encoded in prefix-1 portion of the key. Last 8 bytes of the ++ * key are occupied by hash of the remaining characters of the name. ++ * ++ * STAT DATA ++ * ++ * | 60 | 4 | 4 | 60 | 64 | ++ * +--------------+---+---+--------------+-----------------+ ++ * | locality id | 1 | 0 | objectid | 0 | ++ * +--------------+---+---+--------------+-----------------+ ++ * | | | | ++ * | 8 bytes | 8 bytes | 8 bytes | ++ * ++ * locality id object id of a directory where first name was created for ++ * the object ++ * ++ * objectid object id for this object ++ * ++ * FILE BODY ++ * ++ * | 60 | 4 | 4 | 60 | 64 | ++ * +--------------+---+---+--------------+-----------------+ ++ * | locality id | 4 | 0 | objectid | offset | ++ * +--------------+---+---+--------------+-----------------+ ++ * | | | | ++ * | 8 bytes | 8 bytes | 8 bytes | ++ * ++ * locality id object id of a directory where first name was created for ++ * the object ++ * ++ * objectid object id for this object ++ * ++ * offset logical offset from the beginning of this file. ++ * Measured in bytes. ++ * ++ * ++ */ ++ ++#include "debug.h" ++#include "key.h" ++#include "kassign.h" ++#include "vfs_ops.h" ++#include "inode.h" ++#include "super.h" ++#include "dscale.h" ++ ++#include <linux/types.h> /* for __u?? */ ++#include <linux/fs.h> /* for struct super_block, etc */ ++ ++/* bitmask for H bit (see comment at the beginning of this file */ ++static const __u64 longname_mark = 0x0100000000000000ull; ++/* bitmask for F and H portions of the key. */ ++static const __u64 fibration_mask = 0xff00000000000000ull; ++ ++/* return true if name is not completely encoded in @key */ ++int is_longname_key(const reiser4_key * key) ++{ ++ __u64 highpart; ++ ++ assert("nikita-2863", key != NULL); ++ if (get_key_type(key) != KEY_FILE_NAME_MINOR) ++ reiser4_print_key("oops", key); ++ assert("nikita-2864", get_key_type(key) == KEY_FILE_NAME_MINOR); ++ ++ if (REISER4_LARGE_KEY) ++ highpart = get_key_ordering(key); ++ else ++ highpart = get_key_objectid(key); ++ ++ return (highpart & longname_mark) ? 1 : 0; ++} ++ ++/* return true if @name is too long to be completely encoded in the key */ ++int is_longname(const char *name UNUSED_ARG, int len) ++{ ++ if (REISER4_LARGE_KEY) ++ return len > 23; ++ else ++ return len > 15; ++} ++ ++/* code ascii string into __u64. ++ ++ Put characters of @name into result (@str) one after another starting ++ from @start_idx-th highest (arithmetically) byte. This produces ++ endian-safe encoding. memcpy(2) will not do. ++ ++*/ ++static __u64 pack_string(const char *name /* string to encode */ , ++ int start_idx /* highest byte in result from ++ * which to start encoding */ ) ++{ ++ unsigned i; ++ __u64 str; ++ ++ str = 0; ++ for (i = 0; (i < sizeof str - start_idx) && name[i]; ++i) { ++ str <<= 8; ++ str |= (unsigned char)name[i]; ++ } ++ str <<= (sizeof str - i - start_idx) << 3; ++ return str; ++} ++ ++/* opposite to pack_string(). Takes value produced by pack_string(), restores ++ * string encoded in it and stores result in @buf */ ++char *reiser4_unpack_string(__u64 value, char *buf) ++{ ++ do { ++ *buf = value >> (64 - 8); ++ if (*buf) ++ ++buf; ++ value <<= 8; ++ } while (value != 0); ++ *buf = 0; ++ return buf; ++} ++ ++/* obtain name encoded in @key and store it in @buf */ ++char *extract_name_from_key(const reiser4_key * key, char *buf) ++{ ++ char *c; ++ ++ assert("nikita-2868", !is_longname_key(key)); ++ ++ c = buf; ++ if (REISER4_LARGE_KEY) { ++ c = reiser4_unpack_string(get_key_ordering(key) & ++ ~fibration_mask, c); ++ c = reiser4_unpack_string(get_key_fulloid(key), c); ++ } else ++ c = reiser4_unpack_string(get_key_fulloid(key) & ++ ~fibration_mask, c); ++ reiser4_unpack_string(get_key_offset(key), c); ++ return buf; ++} ++ ++/** ++ * complete_entry_key - calculate entry key by name ++ * @dir: directory where entry is (or will be) in ++ * @name: name to calculate key of ++ * @len: lenth of name ++ * @result: place to store result in ++ * ++ * Sets fields of entry key @result which depend on file name. ++ * When REISER4_LARGE_KEY is defined three fields of @result are set: ordering, ++ * objectid and offset. Otherwise, objectid and offset are set. ++ */ ++void complete_entry_key(const struct inode *dir, const char *name, ++ int len, reiser4_key *result) ++{ ++#if REISER4_LARGE_KEY ++ __u64 ordering; ++ __u64 objectid; ++ __u64 offset; ++ ++ assert("nikita-1139", dir != NULL); ++ assert("nikita-1142", result != NULL); ++ assert("nikita-2867", strlen(name) == len); ++ ++ /* ++ * key allocation algorithm for directory entries in case of large ++ * keys: ++ * ++ * If name is not longer than 7 + 8 + 8 = 23 characters, put first 7 ++ * characters into ordering field of key, next 8 charactes (if any) ++ * into objectid field of key and next 8 ones (of any) into offset ++ * field of key ++ * ++ * If file name is longer than 23 characters, put first 7 characters ++ * into key's ordering, next 8 to objectid and hash of remaining ++ * characters into offset field. ++ * ++ * To distinguish above cases, in latter set up unused high bit in ++ * ordering field. ++ */ ++ ++ /* [0-6] characters to ordering */ ++ ordering = pack_string(name, 1); ++ if (len > 7) { ++ /* [7-14] characters to objectid */ ++ objectid = pack_string(name + 7, 0); ++ if (len > 15) { ++ if (len <= 23) { ++ /* [15-23] characters to offset */ ++ offset = pack_string(name + 15, 0); ++ } else { ++ /* note in a key the fact that offset contains ++ * hash */ ++ ordering |= longname_mark; ++ ++ /* offset is the hash of the file name's tail */ ++ offset = inode_hash_plugin(dir)->hash(name + 15, ++ len - 15); ++ } ++ } else { ++ offset = 0ull; ++ } ++ } else { ++ objectid = 0ull; ++ offset = 0ull; ++ } ++ ++ assert("nikita-3480", inode_fibration_plugin(dir) != NULL); ++ ordering |= inode_fibration_plugin(dir)->fibre(dir, name, len); ++ ++ set_key_ordering(result, ordering); ++ set_key_fulloid(result, objectid); ++ set_key_offset(result, offset); ++ return; ++ ++#else ++ __u64 objectid; ++ __u64 offset; ++ ++ assert("nikita-1139", dir != NULL); ++ assert("nikita-1142", result != NULL); ++ assert("nikita-2867", strlen(name) == len); ++ ++ /* ++ * key allocation algorithm for directory entries in case of not large ++ * keys: ++ * ++ * If name is not longer than 7 + 8 = 15 characters, put first 7 ++ * characters into objectid field of key, next 8 charactes (if any) ++ * into offset field of key ++ * ++ * If file name is longer than 15 characters, put first 7 characters ++ * into key's objectid, and hash of remaining characters into offset ++ * field. ++ * ++ * To distinguish above cases, in latter set up unused high bit in ++ * objectid field. ++ */ ++ ++ /* [0-6] characters to objectid */ ++ objectid = pack_string(name, 1); ++ if (len > 7) { ++ if (len <= 15) { ++ /* [7-14] characters to offset */ ++ offset = pack_string(name + 7, 0); ++ } else { ++ /* note in a key the fact that offset contains hash. */ ++ objectid |= longname_mark; ++ ++ /* offset is the hash of the file name. */ ++ offset = inode_hash_plugin(dir)->hash(name + 7, ++ len - 7); ++ } ++ } else ++ offset = 0ull; ++ ++ assert("nikita-3480", inode_fibration_plugin(dir) != NULL); ++ objectid |= inode_fibration_plugin(dir)->fibre(dir, name, len); ++ ++ set_key_fulloid(result, objectid); ++ set_key_offset(result, offset); ++ return; ++#endif /* ! REISER4_LARGE_KEY */ ++} ++ ++/* true, if @key is the key of "." */ ++int is_dot_key(const reiser4_key * key/* key to check */) ++{ ++ assert("nikita-1717", key != NULL); ++ assert("nikita-1718", get_key_type(key) == KEY_FILE_NAME_MINOR); ++ return ++ (get_key_ordering(key) == 0ull) && ++ (get_key_objectid(key) == 0ull) && (get_key_offset(key) == 0ull); ++} ++ ++/* build key for stat-data. ++ ++ return key of stat-data of this object. This should became sd plugin ++ method in the future. For now, let it be here. ++ ++*/ ++reiser4_key *build_sd_key(const struct inode *target /* inode of an object */ , ++ reiser4_key * result /* resulting key of @target ++ stat-data */ ) ++{ ++ assert("nikita-261", result != NULL); ++ ++ reiser4_key_init(result); ++ set_key_locality(result, reiser4_inode_data(target)->locality_id); ++ set_key_ordering(result, get_inode_ordering(target)); ++ set_key_objectid(result, get_inode_oid(target)); ++ set_key_type(result, KEY_SD_MINOR); ++ set_key_offset(result, (__u64) 0); ++ return result; ++} ++ ++/* encode part of key into &obj_key_id ++ ++ This encodes into @id part of @key sufficient to restore @key later, ++ given that latter is key of object (key of stat-data). ++ ++ See &obj_key_id ++*/ ++int build_obj_key_id(const reiser4_key * key /* key to encode */ , ++ obj_key_id * id/* id where key is encoded in */) ++{ ++ assert("nikita-1151", key != NULL); ++ assert("nikita-1152", id != NULL); ++ ++ memcpy(id, key, sizeof *id); ++ return 0; ++} ++ ++/* encode reference to @obj in @id. ++ ++ This is like build_obj_key_id() above, but takes inode as parameter. */ ++int build_inode_key_id(const struct inode *obj /* object to build key of */ , ++ obj_key_id * id/* result */) ++{ ++ reiser4_key sdkey; ++ ++ assert("nikita-1166", obj != NULL); ++ assert("nikita-1167", id != NULL); ++ ++ build_sd_key(obj, &sdkey); ++ build_obj_key_id(&sdkey, id); ++ return 0; ++} ++ ++/* decode @id back into @key ++ ++ Restore key of object stat-data from @id. This is dual to ++ build_obj_key_id() above. ++*/ ++int extract_key_from_id(const obj_key_id * id /* object key id to extract key ++ * from */ , ++ reiser4_key * key/* result */) ++{ ++ assert("nikita-1153", id != NULL); ++ assert("nikita-1154", key != NULL); ++ ++ reiser4_key_init(key); ++ memcpy(key, id, sizeof *id); ++ return 0; ++} ++ ++/* extract objectid of directory from key of directory entry within said ++ directory. ++ */ ++oid_t extract_dir_id_from_key(const reiser4_key * de_key /* key of ++ * directory ++ * entry */ ) ++{ ++ assert("nikita-1314", de_key != NULL); ++ return get_key_locality(de_key); ++} ++ ++/* encode into @id key of directory entry. ++ ++ Encode into @id information sufficient to later distinguish directory ++ entries within the same directory. This is not whole key, because all ++ directory entries within directory item share locality which is equal ++ to objectid of their directory. ++ ++*/ ++int build_de_id(const struct inode *dir /* inode of directory */ , ++ const struct qstr *name /* name to be given to @obj by ++ * directory entry being ++ * constructed */ , ++ de_id * id/* short key of directory entry */) ++{ ++ reiser4_key key; ++ ++ assert("nikita-1290", dir != NULL); ++ assert("nikita-1292", id != NULL); ++ ++ /* NOTE-NIKITA this is suboptimal. */ ++ inode_dir_plugin(dir)->build_entry_key(dir, name, &key); ++ return build_de_id_by_key(&key, id); ++} ++ ++/* encode into @id key of directory entry. ++ ++ Encode into @id information sufficient to later distinguish directory ++ entries within the same directory. This is not whole key, because all ++ directory entries within directory item share locality which is equal ++ to objectid of their directory. ++ ++*/ ++int build_de_id_by_key(const reiser4_key * entry_key /* full key of directory ++ * entry */ , ++ de_id * id/* short key of directory entry */) ++{ ++ memcpy(id, ((__u64 *) entry_key) + 1, sizeof *id); ++ return 0; ++} ++ ++/* restore from @id key of directory entry. ++ ++ Function dual to build_de_id(): given @id and locality, build full ++ key of directory entry within directory item. ++ ++*/ ++int extract_key_from_de_id(const oid_t locality /* locality of directory ++ * entry */ , ++ const de_id * id /* directory entry id */ , ++ reiser4_key * key/* result */) ++{ ++ /* no need to initialise key here: all fields are overwritten */ ++ memcpy(((__u64 *) key) + 1, id, sizeof *id); ++ set_key_locality(key, locality); ++ set_key_type(key, KEY_FILE_NAME_MINOR); ++ return 0; ++} ++ ++/* compare two &de_id's */ ++cmp_t de_id_cmp(const de_id * id1 /* first &de_id to compare */ , ++ const de_id * id2/* second &de_id to compare */) ++{ ++ /* NOTE-NIKITA ugly implementation */ ++ reiser4_key k1; ++ reiser4_key k2; ++ ++ extract_key_from_de_id((oid_t) 0, id1, &k1); ++ extract_key_from_de_id((oid_t) 0, id2, &k2); ++ return keycmp(&k1, &k2); ++} ++ ++/* compare &de_id with key */ ++cmp_t de_id_key_cmp(const de_id * id /* directory entry id to compare */ , ++ const reiser4_key * key/* key to compare */) ++{ ++ cmp_t result; ++ reiser4_key *k1; ++ ++ k1 = (reiser4_key *) (((unsigned long)id) - sizeof key->el[0]); ++ result = KEY_DIFF_EL(k1, key, 1); ++ if (result == EQUAL_TO) { ++ result = KEY_DIFF_EL(k1, key, 2); ++ if (REISER4_LARGE_KEY && result == EQUAL_TO) ++ result = KEY_DIFF_EL(k1, key, 3); ++ } ++ return result; ++} ++ ++/* ++ * return number of bytes necessary to encode @inode identity. ++ */ ++int inode_onwire_size(const struct inode *inode) ++{ ++ int result; ++ ++ result = dscale_bytes_to_write(get_inode_oid(inode)); ++ result += dscale_bytes_to_write(get_inode_locality(inode)); ++ ++ /* ++ * ordering is large (it usually has highest bits set), so it makes ++ * little sense to dscale it. ++ */ ++ if (REISER4_LARGE_KEY) ++ result += sizeof(get_inode_ordering(inode)); ++ return result; ++} ++ ++/* ++ * encode @inode identity at @start ++ */ ++char *build_inode_onwire(const struct inode *inode, char *start) ++{ ++ start += dscale_write(start, get_inode_locality(inode)); ++ start += dscale_write(start, get_inode_oid(inode)); ++ ++ if (REISER4_LARGE_KEY) { ++ put_unaligned(cpu_to_le64(get_inode_ordering(inode)), (__le64 *)start); ++ start += sizeof(get_inode_ordering(inode)); ++ } ++ return start; ++} ++ ++/* ++ * extract key that was previously encoded by build_inode_onwire() at @addr ++ */ ++char *extract_obj_key_id_from_onwire(char *addr, obj_key_id * key_id) ++{ ++ __u64 val; ++ ++ addr += dscale_read(addr, &val); ++ val = (val << KEY_LOCALITY_SHIFT) | KEY_SD_MINOR; ++ put_unaligned(cpu_to_le64(val), (__le64 *)key_id->locality); ++ addr += dscale_read(addr, &val); ++ put_unaligned(cpu_to_le64(val), (__le64 *)key_id->objectid); ++#if REISER4_LARGE_KEY ++ memcpy(&key_id->ordering, addr, sizeof key_id->ordering); ++ addr += sizeof key_id->ordering; ++#endif ++ return addr; ++} ++ ++/* ++ * skip a key that was previously encoded by build_inode_onwire() at @addr ++ * FIXME: handle IO errors. ++ */ ++char * locate_obj_key_id_onwire(char * addr) ++{ ++ /* locality */ ++ addr += dscale_bytes_to_read(addr); ++ /* objectid */ ++ addr += dscale_bytes_to_read(addr); ++#if REISER4_LARGE_KEY ++ addr += sizeof ((obj_key_id *)0)->ordering; ++#endif ++ return addr; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/kassign.h linux-2.6.30/fs/reiser4/kassign.h +--- linux-2.6.30.orig/fs/reiser4/kassign.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/kassign.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,111 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Key assignment policy interface. See kassign.c for details. */ ++ ++#if !defined(__KASSIGN_H__) ++#define __KASSIGN_H__ ++ ++#include "forward.h" ++#include "key.h" ++#include "dformat.h" ++ ++#include <linux/types.h> /* for __u?? */ ++#include <linux/fs.h> /* for struct super_block, etc */ ++#include <linux/dcache.h> /* for struct qstr */ ++ ++/* key assignment functions */ ++ ++/* Information from which key of file stat-data can be uniquely ++ restored. This depends on key assignment policy for ++ stat-data. Currently it's enough to store object id and locality id ++ (60+60==120) bits, because minor packing locality and offset of ++ stat-data key are always known constants: KEY_SD_MINOR and 0 ++ respectively. For simplicity 4 bits are wasted in each id, and just ++ two 64 bit integers are stored. ++ ++ This field has to be byte-aligned, because we don't want to waste ++ space in directory entries. There is another side of a coin of ++ course: we waste CPU and bus bandwidth in stead, by copying data back ++ and forth. ++ ++ Next optimization: &obj_key_id is mainly used to address stat data from ++ directory entries. Under the assumption that majority of files only have ++ only name (one hard link) from *the* parent directory it seems reasonable ++ to only store objectid of stat data and take its locality from key of ++ directory item. ++ ++ This requires some flag to be added to the &obj_key_id to distinguish ++ between these two cases. Remaining bits in flag byte are then asking to be ++ used to store file type. ++ ++ This optimization requires changes in directory item handling code. ++ ++*/ ++typedef struct obj_key_id { ++ d8 locality[sizeof(__u64)]; ++ ON_LARGE_KEY(d8 ordering[sizeof(__u64)]; ++ ) ++ d8 objectid[sizeof(__u64)]; ++} ++obj_key_id; ++ ++/* Information sufficient to uniquely identify directory entry within ++ compressed directory item. ++ ++ For alignment issues see &obj_key_id above. ++*/ ++typedef struct de_id { ++ ON_LARGE_KEY(d8 ordering[sizeof(__u64)];) ++ d8 objectid[sizeof(__u64)]; ++ d8 offset[sizeof(__u64)]; ++} ++de_id; ++ ++extern int inode_onwire_size(const struct inode *obj); ++extern char *build_inode_onwire(const struct inode *obj, char *area); ++extern char *locate_obj_key_id_onwire(char *area); ++extern char *extract_obj_key_id_from_onwire(char *area, obj_key_id * key_id); ++ ++extern int build_inode_key_id(const struct inode *obj, obj_key_id * id); ++extern int extract_key_from_id(const obj_key_id * id, reiser4_key * key); ++extern int build_obj_key_id(const reiser4_key * key, obj_key_id * id); ++extern oid_t extract_dir_id_from_key(const reiser4_key * de_key); ++extern int build_de_id(const struct inode *dir, const struct qstr *name, ++ de_id * id); ++extern int build_de_id_by_key(const reiser4_key * entry_key, de_id * id); ++extern int extract_key_from_de_id(const oid_t locality, const de_id * id, ++ reiser4_key * key); ++extern cmp_t de_id_cmp(const de_id * id1, const de_id * id2); ++extern cmp_t de_id_key_cmp(const de_id * id, const reiser4_key * key); ++ ++extern int build_readdir_key_common(struct file *dir, reiser4_key * result); ++extern void build_entry_key_common(const struct inode *dir, ++ const struct qstr *name, ++ reiser4_key * result); ++extern void build_entry_key_stable_entry(const struct inode *dir, ++ const struct qstr *name, ++ reiser4_key * result); ++extern int is_dot_key(const reiser4_key * key); ++extern reiser4_key *build_sd_key(const struct inode *target, ++ reiser4_key * result); ++ ++extern int is_longname_key(const reiser4_key * key); ++extern int is_longname(const char *name, int len); ++extern char *extract_name_from_key(const reiser4_key * key, char *buf); ++extern char *reiser4_unpack_string(__u64 value, char *buf); ++extern void complete_entry_key(const struct inode *dir, const char *name, ++ int len, reiser4_key *result); ++ ++/* __KASSIGN_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/Kconfig linux-2.6.30/fs/reiser4/Kconfig +--- linux-2.6.30.orig/fs/reiser4/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/Kconfig 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,34 @@ ++config REISER4_FS ++ tristate "Reiser4 (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ select ZLIB_INFLATE ++ select ZLIB_DEFLATE ++ select LZO_COMPRESS ++ select LZO_DECOMPRESS ++ select CRYPTO ++ help ++ Reiser4 is a filesystem that performs all filesystem operations ++ as atomic transactions, which means that it either performs a ++ write, or it does not, and in the event of a crash it does not ++ partially perform it or corrupt it. ++ ++ It stores files in dancing trees, which are like balanced trees but ++ faster. It packs small files together so that they share blocks ++ without wasting space. This means you can use it to store really ++ small files. It also means that it saves you disk space. It avoids ++ hassling you with anachronisms like having a maximum number of ++ inodes, and wasting space if you use less than that number. ++ ++ Reiser4 is a distinct filesystem type from reiserfs (V3). ++ It's therefore not possible to use reiserfs file systems ++ with reiser4. ++ ++ To learn more about reiser4, go to http://www.namesys.com ++ ++config REISER4_DEBUG ++ bool "Enable reiser4 debug mode" ++ depends on REISER4_FS ++ help ++ Don't use this unless you are debugging reiser4. ++ ++ If unsure, say N. +diff -urN linux-2.6.30.orig/fs/reiser4/key.c linux-2.6.30/fs/reiser4/key.c +--- linux-2.6.30.orig/fs/reiser4/key.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/key.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,138 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Key manipulations. */ ++ ++#include "debug.h" ++#include "key.h" ++#include "super.h" ++#include "reiser4.h" ++ ++#include <linux/types.h> /* for __u?? */ ++ ++/* Minimal possible key: all components are zero. It is presumed that this is ++ independent of key scheme. */ ++static const reiser4_key MINIMAL_KEY = { ++ .el = { ++ 0ull, ++ ON_LARGE_KEY(0ull,) ++ 0ull, ++ 0ull ++ } ++}; ++ ++/* Maximal possible key: all components are ~0. It is presumed that this is ++ independent of key scheme. */ ++static const reiser4_key MAXIMAL_KEY = { ++ .el = { ++ __constant_cpu_to_le64(~0ull), ++ ON_LARGE_KEY(__constant_cpu_to_le64(~0ull),) ++ __constant_cpu_to_le64(~0ull), ++ __constant_cpu_to_le64(~0ull) ++ } ++}; ++ ++/* Initialize key. */ ++void reiser4_key_init(reiser4_key * key/* key to init */) ++{ ++ assert("nikita-1169", key != NULL); ++ memset(key, 0, sizeof *key); ++} ++ ++/* minimal possible key in the tree. Return pointer to the static storage. */ ++const reiser4_key * reiser4_min_key(void) ++{ ++ return &MINIMAL_KEY; ++} ++ ++/* maximum possible key in the tree. Return pointer to the static storage. */ ++const reiser4_key * reiser4_max_key(void) ++{ ++ return &MAXIMAL_KEY; ++} ++ ++#if REISER4_DEBUG ++/* debugging aid: print symbolic name of key type */ ++static const char *type_name(unsigned int key_type/* key type */) ++{ ++ switch (key_type) { ++ case KEY_FILE_NAME_MINOR: ++ return "file name"; ++ case KEY_SD_MINOR: ++ return "stat data"; ++ case KEY_ATTR_NAME_MINOR: ++ return "attr name"; ++ case KEY_ATTR_BODY_MINOR: ++ return "attr body"; ++ case KEY_BODY_MINOR: ++ return "file body"; ++ default: ++ return "unknown"; ++ } ++} ++ ++/* debugging aid: print human readable information about key */ ++void reiser4_print_key(const char *prefix /* prefix to print */ , ++ const reiser4_key * key/* key to print */) ++{ ++ /* turn bold on */ ++ /* printf ("\033[1m"); */ ++ if (key == NULL) ++ printk("%s: null key\n", prefix); ++ else { ++ if (REISER4_LARGE_KEY) ++ printk("%s: (%Lx:%x:%Lx:%Lx:%Lx:%Lx)", prefix, ++ get_key_locality(key), ++ get_key_type(key), ++ get_key_ordering(key), ++ get_key_band(key), ++ get_key_objectid(key), get_key_offset(key)); ++ else ++ printk("%s: (%Lx:%x:%Lx:%Lx:%Lx)", prefix, ++ get_key_locality(key), ++ get_key_type(key), ++ get_key_band(key), ++ get_key_objectid(key), get_key_offset(key)); ++ /* ++ * if this is a key of directory entry, try to decode part of ++ * a name stored in the key, and output it. ++ */ ++ if (get_key_type(key) == KEY_FILE_NAME_MINOR) { ++ char buf[DE_NAME_BUF_LEN]; ++ char *c; ++ ++ c = buf; ++ c = reiser4_unpack_string(get_key_ordering(key), c); ++ reiser4_unpack_string(get_key_fulloid(key), c); ++ printk("[%s", buf); ++ if (is_longname_key(key)) ++ /* ++ * only part of the name is stored in the key. ++ */ ++ printk("...]\n"); ++ else { ++ /* ++ * whole name is stored in the key. ++ */ ++ reiser4_unpack_string(get_key_offset(key), buf); ++ printk("%s]\n", buf); ++ } ++ } else { ++ printk("[%s]\n", type_name(get_key_type(key))); ++ } ++ } ++ /* turn bold off */ ++ /* printf ("\033[m\017"); */ ++} ++ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/key.h linux-2.6.30/fs/reiser4/key.h +--- linux-2.6.30.orig/fs/reiser4/key.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/key.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,392 @@ ++/* Copyright 2000, 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Declarations of key-related data-structures and operations on keys. */ ++ ++#if !defined(__REISER4_KEY_H__) ++#define __REISER4_KEY_H__ ++ ++#include "dformat.h" ++#include "forward.h" ++#include "debug.h" ++ ++#include <linux/types.h> /* for __u?? */ ++ ++/* Operations on keys in reiser4 tree */ ++ ++/* No access to any of these fields shall be done except via a ++ wrapping macro/function, and that wrapping macro/function shall ++ convert to little endian order. Compare keys will consider cpu byte order. */ ++ ++/* A storage layer implementation difference between a regular unix file body ++ and its attributes is in the typedef below which causes all of the attributes ++ of a file to be near in key to all of the other attributes for all of the ++ files within that directory, and not near to the file itself. It is ++ interesting to consider whether this is the wrong approach, and whether there ++ should be no difference at all. For current usage patterns this choice is ++ probably the right one. */ ++ ++/* possible values for minor packing locality (4 bits required) */ ++typedef enum { ++ /* file name */ ++ KEY_FILE_NAME_MINOR = 0, ++ /* stat-data */ ++ KEY_SD_MINOR = 1, ++ /* file attribute name */ ++ KEY_ATTR_NAME_MINOR = 2, ++ /* file attribute value */ ++ KEY_ATTR_BODY_MINOR = 3, ++ /* file body (tail or extent) */ ++ KEY_BODY_MINOR = 4, ++} key_minor_locality; ++ ++/* Everything stored in the tree has a unique key, which means that the tree is ++ (logically) fully ordered by key. Physical order is determined by dynamic ++ heuristics that attempt to reflect key order when allocating available space, ++ and by the repacker. It is stylistically better to put aggregation ++ information into the key. Thus, if you want to segregate extents from tails, ++ it is better to give them distinct minor packing localities rather than ++ changing block_alloc.c to check the node type when deciding where to allocate ++ the node. ++ ++ The need to randomly displace new directories and large files disturbs this ++ symmetry unfortunately. However, it should be noted that this is a need that ++ is not clearly established given the existence of a repacker. Also, in our ++ current implementation tails have a different minor packing locality from ++ extents, and no files have both extents and tails, so maybe symmetry can be ++ had without performance cost after all. Symmetry is what we ship for now.... ++*/ ++ ++/* Arbitrary major packing localities can be assigned to objects using ++ the reiser4(filenameA/..packing<=some_number) system call. ++ ++ In reiser4, the creat() syscall creates a directory ++ ++ whose default flow (that which is referred to if the directory is ++ read as a file) is the traditional unix file body. ++ ++ whose directory plugin is the 'filedir' ++ ++ whose major packing locality is that of the parent of the object created. ++ ++ The static_stat item is a particular commonly used directory ++ compression (the one for normal unix files). ++ ++ The filedir plugin checks to see if the static_stat item exists. ++ There is a unique key for static_stat. If yes, then it uses the ++ static_stat item for all of the values that it contains. The ++ static_stat item contains a flag for each stat it contains which ++ indicates whether one should look outside the static_stat item for its ++ contents. ++*/ ++ ++/* offset of fields in reiser4_key. Value of each element of this enum ++ is index within key (thought as array of __u64's) where this field ++ is. */ ++typedef enum { ++ /* major "locale", aka dirid. Sits in 1st element */ ++ KEY_LOCALITY_INDEX = 0, ++ /* minor "locale", aka item type. Sits in 1st element */ ++ KEY_TYPE_INDEX = 0, ++ ON_LARGE_KEY(KEY_ORDERING_INDEX,) ++ /* "object band". Sits in 2nd element */ ++ KEY_BAND_INDEX, ++ /* objectid. Sits in 2nd element */ ++ KEY_OBJECTID_INDEX = KEY_BAND_INDEX, ++ /* full objectid. Sits in 2nd element */ ++ KEY_FULLOID_INDEX = KEY_BAND_INDEX, ++ /* Offset. Sits in 3rd element */ ++ KEY_OFFSET_INDEX, ++ /* Name hash. Sits in 3rd element */ ++ KEY_HASH_INDEX = KEY_OFFSET_INDEX, ++ KEY_CACHELINE_END = KEY_OFFSET_INDEX, ++ KEY_LAST_INDEX ++} reiser4_key_field_index; ++ ++/* key in reiser4 internal "balanced" tree. It is just array of three ++ 64bit integers in disk byte order (little-endian by default). This ++ array is actually indexed by reiser4_key_field. Each __u64 within ++ this array is called "element". Logical key component encoded within ++ elements are called "fields". ++ ++ We declare this as union with second component dummy to suppress ++ inconvenient array<->pointer casts implied in C. */ ++union reiser4_key { ++ __le64 el[KEY_LAST_INDEX]; ++ int pad; ++}; ++ ++/* bitmasks showing where within reiser4_key particular key is stored. */ ++/* major locality occupies higher 60 bits of the first element */ ++#define KEY_LOCALITY_MASK 0xfffffffffffffff0ull ++ ++/* minor locality occupies lower 4 bits of the first element */ ++#define KEY_TYPE_MASK 0xfull ++ ++/* controversial band occupies higher 4 bits of the 2nd element */ ++#define KEY_BAND_MASK 0xf000000000000000ull ++ ++/* objectid occupies lower 60 bits of the 2nd element */ ++#define KEY_OBJECTID_MASK 0x0fffffffffffffffull ++ ++/* full 64bit objectid*/ ++#define KEY_FULLOID_MASK 0xffffffffffffffffull ++ ++/* offset is just 3rd L.M.Nt itself */ ++#define KEY_OFFSET_MASK 0xffffffffffffffffull ++ ++/* ordering is whole second element */ ++#define KEY_ORDERING_MASK 0xffffffffffffffffull ++ ++/* how many bits key element should be shifted to left to get particular field ++ */ ++typedef enum { ++ KEY_LOCALITY_SHIFT = 4, ++ KEY_TYPE_SHIFT = 0, ++ KEY_BAND_SHIFT = 60, ++ KEY_OBJECTID_SHIFT = 0, ++ KEY_FULLOID_SHIFT = 0, ++ KEY_OFFSET_SHIFT = 0, ++ KEY_ORDERING_SHIFT = 0, ++} reiser4_key_field_shift; ++ ++static inline __u64 ++get_key_el(const reiser4_key * key, reiser4_key_field_index off) ++{ ++ assert("nikita-753", key != NULL); ++ assert("nikita-754", off < KEY_LAST_INDEX); ++ return le64_to_cpu(get_unaligned(&key->el[off])); ++} ++ ++static inline void ++set_key_el(reiser4_key * key, reiser4_key_field_index off, __u64 value) ++{ ++ assert("nikita-755", key != NULL); ++ assert("nikita-756", off < KEY_LAST_INDEX); ++ put_unaligned(cpu_to_le64(value), &key->el[off]); ++} ++ ++/* macro to define getter and setter functions for field F with type T */ ++#define DEFINE_KEY_FIELD(L, U, T) \ ++static inline T get_key_ ## L(const reiser4_key *key) \ ++{ \ ++ assert("nikita-750", key != NULL); \ ++ return (T) (get_key_el(key, KEY_ ## U ## _INDEX) & \ ++ KEY_ ## U ## _MASK) >> KEY_ ## U ## _SHIFT; \ ++} \ ++ \ ++static inline void set_key_ ## L(reiser4_key * key, T loc) \ ++{ \ ++ __u64 el; \ ++ \ ++ assert("nikita-752", key != NULL); \ ++ \ ++ el = get_key_el(key, KEY_ ## U ## _INDEX); \ ++ /* clear field bits in the key */ \ ++ el &= ~KEY_ ## U ## _MASK; \ ++ /* actually it should be \ ++ \ ++ el |= ( loc << KEY_ ## U ## _SHIFT ) & KEY_ ## U ## _MASK; \ ++ \ ++ but we trust user to never pass values that wouldn't fit \ ++ into field. Clearing extra bits is one operation, but this \ ++ function is time-critical. \ ++ But check this in assertion. */ \ ++ assert("nikita-759", ((loc << KEY_ ## U ## _SHIFT) & \ ++ ~KEY_ ## U ## _MASK) == 0); \ ++ el |= (loc << KEY_ ## U ## _SHIFT); \ ++ set_key_el(key, KEY_ ## U ## _INDEX, el); \ ++} ++ ++typedef __u64 oid_t; ++ ++/* define get_key_locality(), set_key_locality() */ ++DEFINE_KEY_FIELD(locality, LOCALITY, oid_t); ++/* define get_key_type(), set_key_type() */ ++DEFINE_KEY_FIELD(type, TYPE, key_minor_locality); ++/* define get_key_band(), set_key_band() */ ++DEFINE_KEY_FIELD(band, BAND, __u64); ++/* define get_key_objectid(), set_key_objectid() */ ++DEFINE_KEY_FIELD(objectid, OBJECTID, oid_t); ++/* define get_key_fulloid(), set_key_fulloid() */ ++DEFINE_KEY_FIELD(fulloid, FULLOID, oid_t); ++/* define get_key_offset(), set_key_offset() */ ++DEFINE_KEY_FIELD(offset, OFFSET, __u64); ++#if (REISER4_LARGE_KEY) ++/* define get_key_ordering(), set_key_ordering() */ ++DEFINE_KEY_FIELD(ordering, ORDERING, __u64); ++#else ++static inline __u64 get_key_ordering(const reiser4_key * key) ++{ ++ return 0; ++} ++ ++static inline void set_key_ordering(reiser4_key * key, __u64 val) ++{ ++} ++#endif ++ ++/* key comparison result */ ++typedef enum { LESS_THAN = -1, /* if first key is less than second */ ++ EQUAL_TO = 0, /* if keys are equal */ ++ GREATER_THAN = +1 /* if first key is greater than second */ ++} cmp_t; ++ ++void reiser4_key_init(reiser4_key * key); ++ ++/* minimal possible key in the tree. Return pointer to the static storage. */ ++extern const reiser4_key *reiser4_min_key(void); ++extern const reiser4_key *reiser4_max_key(void); ++ ++/* helper macro for keycmp() */ ++#define KEY_DIFF(k1, k2, field) \ ++({ \ ++ typeof(get_key_ ## field(k1)) f1; \ ++ typeof(get_key_ ## field(k2)) f2; \ ++ \ ++ f1 = get_key_ ## field(k1); \ ++ f2 = get_key_ ## field(k2); \ ++ \ ++ (f1 < f2) ? LESS_THAN : ((f1 == f2) ? EQUAL_TO : GREATER_THAN); \ ++}) ++ ++/* helper macro for keycmp() */ ++#define KEY_DIFF_EL(k1, k2, off) \ ++({ \ ++ __u64 e1; \ ++ __u64 e2; \ ++ \ ++ e1 = get_key_el(k1, off); \ ++ e2 = get_key_el(k2, off); \ ++ \ ++ (e1 < e2) ? LESS_THAN : ((e1 == e2) ? EQUAL_TO : GREATER_THAN); \ ++}) ++ ++/* compare `k1' and `k2'. This function is a heart of "key allocation ++ policy". All you need to implement new policy is to add yet another ++ clause here. */ ++static inline cmp_t keycmp(const reiser4_key * k1 /* first key to compare */ , ++ const reiser4_key * k2/* second key to compare */) ++{ ++ cmp_t result; ++ ++ /* ++ * This function is the heart of reiser4 tree-routines. Key comparison ++ * is among most heavily used operations in the file system. ++ */ ++ ++ assert("nikita-439", k1 != NULL); ++ assert("nikita-440", k2 != NULL); ++ ++ /* there is no actual branch here: condition is compile time constant ++ * and constant folding and propagation ensures that only one branch ++ * is actually compiled in. */ ++ ++ if (REISER4_PLANA_KEY_ALLOCATION) { ++ /* if physical order of fields in a key is identical ++ with logical order, we can implement key comparison ++ as three 64bit comparisons. */ ++ /* logical order of fields in plan-a: ++ locality->type->objectid->offset. */ ++ /* compare locality and type at once */ ++ result = KEY_DIFF_EL(k1, k2, 0); ++ if (result == EQUAL_TO) { ++ /* compare objectid (and band if it's there) */ ++ result = KEY_DIFF_EL(k1, k2, 1); ++ /* compare offset */ ++ if (result == EQUAL_TO) { ++ result = KEY_DIFF_EL(k1, k2, 2); ++ if (REISER4_LARGE_KEY && result == EQUAL_TO) ++ result = KEY_DIFF_EL(k1, k2, 3); ++ } ++ } ++ } else if (REISER4_3_5_KEY_ALLOCATION) { ++ result = KEY_DIFF(k1, k2, locality); ++ if (result == EQUAL_TO) { ++ result = KEY_DIFF(k1, k2, objectid); ++ if (result == EQUAL_TO) { ++ result = KEY_DIFF(k1, k2, type); ++ if (result == EQUAL_TO) ++ result = KEY_DIFF(k1, k2, offset); ++ } ++ } ++ } else ++ impossible("nikita-441", "Unknown key allocation scheme!"); ++ return result; ++} ++ ++/* true if @k1 equals @k2 */ ++static inline int keyeq(const reiser4_key * k1 /* first key to compare */ , ++ const reiser4_key * k2/* second key to compare */) ++{ ++ assert("nikita-1879", k1 != NULL); ++ assert("nikita-1880", k2 != NULL); ++ return !memcmp(k1, k2, sizeof *k1); ++} ++ ++/* true if @k1 is less than @k2 */ ++static inline int keylt(const reiser4_key * k1 /* first key to compare */ , ++ const reiser4_key * k2/* second key to compare */) ++{ ++ assert("nikita-1952", k1 != NULL); ++ assert("nikita-1953", k2 != NULL); ++ return keycmp(k1, k2) == LESS_THAN; ++} ++ ++/* true if @k1 is less than or equal to @k2 */ ++static inline int keyle(const reiser4_key * k1 /* first key to compare */ , ++ const reiser4_key * k2/* second key to compare */) ++{ ++ assert("nikita-1954", k1 != NULL); ++ assert("nikita-1955", k2 != NULL); ++ return keycmp(k1, k2) != GREATER_THAN; ++} ++ ++/* true if @k1 is greater than @k2 */ ++static inline int keygt(const reiser4_key * k1 /* first key to compare */ , ++ const reiser4_key * k2/* second key to compare */) ++{ ++ assert("nikita-1959", k1 != NULL); ++ assert("nikita-1960", k2 != NULL); ++ return keycmp(k1, k2) == GREATER_THAN; ++} ++ ++/* true if @k1 is greater than or equal to @k2 */ ++static inline int keyge(const reiser4_key * k1 /* first key to compare */ , ++ const reiser4_key * k2/* second key to compare */) ++{ ++ assert("nikita-1956", k1 != NULL); ++ assert("nikita-1957", k2 != NULL); /* October 4: sputnik launched ++ * November 3: Laika */ ++ return keycmp(k1, k2) != LESS_THAN; ++} ++ ++static inline void prefetchkey(reiser4_key * key) ++{ ++ prefetch(key); ++ prefetch(&key->el[KEY_CACHELINE_END]); ++} ++ ++/* (%Lx:%x:%Lx:%Lx:%Lx:%Lx) = ++ 1 + 16 + 1 + 1 + 1 + 1 + 1 + 16 + 1 + 16 + 1 + 16 + 1 */ ++/* size of a buffer suitable to hold human readable key representation */ ++#define KEY_BUF_LEN (80) ++ ++#if REISER4_DEBUG ++extern void reiser4_print_key(const char *prefix, const reiser4_key * key); ++#else ++#define reiser4_print_key(p, k) noop ++#endif ++ ++/* __FS_REISERFS_KEY_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/ktxnmgrd.c linux-2.6.30/fs/reiser4/ktxnmgrd.c +--- linux-2.6.30.orig/fs/reiser4/ktxnmgrd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/ktxnmgrd.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,215 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++/* Transaction manager daemon. */ ++ ++/* ++ * ktxnmgrd is a kernel daemon responsible for committing transactions. It is ++ * needed/important for the following reasons: ++ * ++ * 1. in reiser4 atom is not committed immediately when last transaction ++ * handle closes, unless atom is either too old or too large (see ++ * atom_should_commit()). This is done to avoid committing too frequently. ++ * because: ++ * ++ * 2. sometimes we don't want to commit atom when closing last transaction ++ * handle even if it is old and fat enough. For example, because we are at ++ * this point under directory semaphore, and committing would stall all ++ * accesses to this directory. ++ * ++ * ktxnmgrd binds its time sleeping on condition variable. When is awakes ++ * either due to (tunable) timeout or because it was explicitly woken up by ++ * call to ktxnmgrd_kick(), it scans list of all atoms and commits ones ++ * eligible. ++ * ++ */ ++ ++#include "debug.h" ++#include "txnmgr.h" ++#include "tree.h" ++#include "ktxnmgrd.h" ++#include "super.h" ++#include "reiser4.h" ++ ++#include <linux/sched.h> /* for struct task_struct */ ++#include <linux/wait.h> ++#include <linux/suspend.h> ++#include <linux/kernel.h> ++#include <linux/writeback.h> ++#include <linux/kthread.h> ++#include <linux/freezer.h> ++ ++static int scan_mgr(struct super_block *); ++ ++/* ++ * change current->comm so that ps, top, and friends will see changed ++ * state. This serves no useful purpose whatsoever, but also costs nothing. May ++ * be it will make lonely system administrator feeling less alone at 3 A.M. ++ */ ++#define set_comm(state) \ ++ snprintf(current->comm, sizeof(current->comm), \ ++ "%s:%s:%s", __FUNCTION__, (super)->s_id, (state)) ++ ++/** ++ * ktxnmgrd - kernel txnmgr daemon ++ * @arg: pointer to super block ++ * ++ * The background transaction manager daemon, started as a kernel thread during ++ * reiser4 initialization. ++ */ ++static int ktxnmgrd(void *arg) ++{ ++ struct super_block *super; ++ ktxnmgrd_context *ctx; ++ txn_mgr *mgr; ++ int done = 0; ++ ++ super = arg; ++ mgr = &get_super_private(super)->tmgr; ++ ++ /* ++ * do_fork() just copies task_struct into the new thread. ->fs_context ++ * shouldn't be copied of course. This shouldn't be a problem for the ++ * rest of the code though. ++ */ ++ current->journal_info = NULL; ++ ctx = mgr->daemon; ++ while (1) { ++ try_to_freeze(); ++ set_comm("wait"); ++ { ++ DEFINE_WAIT(__wait); ++ ++ prepare_to_wait(&ctx->wait, &__wait, ++ TASK_INTERRUPTIBLE); ++ if (kthread_should_stop()) ++ done = 1; ++ else ++ schedule_timeout(ctx->timeout); ++ finish_wait(&ctx->wait, &__wait); ++ } ++ if (done) ++ break; ++ set_comm("run"); ++ spin_lock(&ctx->guard); ++ /* ++ * wait timed out or ktxnmgrd was woken up by explicit request ++ * to commit something. Scan list of atoms in txnmgr and look ++ * for too old atoms. ++ */ ++ do { ++ ctx->rescan = 0; ++ scan_mgr(super); ++ spin_lock(&ctx->guard); ++ if (ctx->rescan) { ++ /* ++ * the list could be modified while ctx ++ * spinlock was released, we have to repeat ++ * scanning from the beginning ++ */ ++ break; ++ } ++ } while (ctx->rescan); ++ spin_unlock(&ctx->guard); ++ } ++ return 0; ++} ++ ++#undef set_comm ++ ++/** ++ * reiser4_init_ktxnmgrd - initialize ktxnmgrd context and start kernel daemon ++ * @super: pointer to super block ++ * ++ * Allocates and initializes ktxnmgrd_context, attaches it to transaction ++ * manager. Starts kernel txnmgr daemon. This is called on mount. ++ */ ++int reiser4_init_ktxnmgrd(struct super_block *super) ++{ ++ txn_mgr *mgr; ++ ktxnmgrd_context *ctx; ++ ++ mgr = &get_super_private(super)->tmgr; ++ ++ assert("zam-1014", mgr->daemon == NULL); ++ ++ ctx = kzalloc(sizeof(ktxnmgrd_context), reiser4_ctx_gfp_mask_get()); ++ if (!ctx) ++ return RETERR(-ENOMEM); ++ ++ assert("nikita-2442", ctx != NULL); ++ ++ init_waitqueue_head(&ctx->wait); ++ ++ /*kcond_init(&ctx->startup);*/ ++ spin_lock_init(&ctx->guard); ++ ctx->timeout = REISER4_TXNMGR_TIMEOUT; ++ ctx->rescan = 1; ++ mgr->daemon = ctx; ++ ++ ctx->tsk = kthread_run(ktxnmgrd, super, "ktxnmgrd"); ++ if (IS_ERR(ctx->tsk)) { ++ int ret = PTR_ERR(ctx->tsk); ++ mgr->daemon = NULL; ++ kfree(ctx); ++ return RETERR(ret); ++ } ++ return 0; ++} ++ ++void ktxnmgrd_kick(txn_mgr *mgr) ++{ ++ assert("nikita-3234", mgr != NULL); ++ assert("nikita-3235", mgr->daemon != NULL); ++ wake_up(&mgr->daemon->wait); ++} ++ ++int is_current_ktxnmgrd(void) ++{ ++ return (get_current_super_private()->tmgr.daemon->tsk == current); ++} ++ ++/** ++ * scan_mgr - commit atoms which are to be committed ++ * @super: super block to commit atoms of ++ * ++ * Commits old atoms. ++ */ ++static int scan_mgr(struct super_block *super) ++{ ++ int ret; ++ reiser4_context ctx; ++ ++ init_stack_context(&ctx, super); ++ ++ ret = commit_some_atoms(&get_super_private(super)->tmgr); ++ ++ reiser4_exit_context(&ctx); ++ return ret; ++} ++ ++/** ++ * reiser4_done_ktxnmgrd - stop kernel thread and frees ktxnmgrd context ++ * @mgr: ++ * ++ * This is called on umount. Stops ktxnmgrd and free t ++ */ ++void reiser4_done_ktxnmgrd(struct super_block *super) ++{ ++ txn_mgr *mgr; ++ ++ mgr = &get_super_private(super)->tmgr; ++ assert("zam-1012", mgr->daemon != NULL); ++ ++ kthread_stop(mgr->daemon->tsk); ++ kfree(mgr->daemon); ++ mgr->daemon = NULL; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 120 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/ktxnmgrd.h linux-2.6.30/fs/reiser4/ktxnmgrd.h +--- linux-2.6.30.orig/fs/reiser4/ktxnmgrd.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/ktxnmgrd.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,52 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Transaction manager daemon. See ktxnmgrd.c for comments. */ ++ ++#ifndef __KTXNMGRD_H__ ++#define __KTXNMGRD_H__ ++ ++#include "txnmgr.h" ++ ++#include <linux/fs.h> ++#include <linux/wait.h> ++#include <linux/completion.h> ++#include <linux/spinlock.h> ++#include <asm/atomic.h> ++#include <linux/sched.h> /* for struct task_struct */ ++ ++/* in this structure all data necessary to start up, shut down and communicate ++ * with ktxnmgrd are kept. */ ++struct ktxnmgrd_context { ++ /* wait queue head on which ktxnmgrd sleeps */ ++ wait_queue_head_t wait; ++ /* spin lock protecting all fields of this structure */ ++ spinlock_t guard; ++ /* timeout of sleeping on ->wait */ ++ signed long timeout; ++ /* kernel thread running ktxnmgrd */ ++ struct task_struct *tsk; ++ /* list of all file systems served by this ktxnmgrd */ ++ struct list_head queue; ++ /* should ktxnmgrd repeat scanning of atoms? */ ++ unsigned int rescan:1; ++}; ++ ++extern int reiser4_init_ktxnmgrd(struct super_block *); ++extern void reiser4_done_ktxnmgrd(struct super_block *); ++ ++extern void ktxnmgrd_kick(txn_mgr * mgr); ++extern int is_current_ktxnmgrd(void); ++ ++/* __KTXNMGRD_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/lock.c linux-2.6.30/fs/reiser4/lock.c +--- linux-2.6.30.orig/fs/reiser4/lock.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/lock.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1237 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Traditional deadlock avoidance is achieved by acquiring all locks in a single ++ order. V4 balances the tree from the bottom up, and searches the tree from ++ the top down, and that is really the way we want it, so tradition won't work ++ for us. ++ ++ Instead we have two lock orderings, a high priority lock ordering, and a low ++ priority lock ordering. Each node in the tree has a lock in its znode. ++ ++ Suppose we have a set of processes which lock (R/W) tree nodes. Each process ++ has a set (maybe empty) of already locked nodes ("process locked set"). Each ++ process may have a pending lock request to a node locked by another process. ++ Note: we lock and unlock, but do not transfer locks: it is possible ++ transferring locks instead would save some bus locking.... ++ ++ Deadlock occurs when we have a loop constructed from process locked sets and ++ lock request vectors. ++ ++ NOTE: The reiser4 "tree" is a tree on disk, but its cached representation in ++ memory is extended with "znodes" with which we connect nodes with their left ++ and right neighbors using sibling pointers stored in the znodes. When we ++ perform balancing operations we often go from left to right and from right to ++ left. ++ ++ +-P1-+ +-P3-+ ++ |+--+| V1 |+--+| ++ ||N1|| -------> ||N3|| ++ |+--+| |+--+| ++ +----+ +----+ ++ ^ | ++ |V2 |V3 ++ | v ++ +---------P2---------+ ++ |+--+ +--+| ++ ||N2| -------- |N4|| ++ |+--+ +--+| ++ +--------------------+ ++ ++ We solve this by ensuring that only low priority processes lock in top to ++ bottom order and from right to left, and high priority processes lock from ++ bottom to top and left to right. ++ ++ ZAM-FIXME-HANS: order not just node locks in this way, order atom locks, and ++ kill those damn busy loops. ++ ANSWER(ZAM): atom locks (which are introduced by ASTAGE_CAPTURE_WAIT atom ++ stage) cannot be ordered that way. There are no rules what nodes can belong ++ to the atom and what nodes cannot. We cannot define what is right or left ++ direction, what is top or bottom. We can take immediate parent or side ++ neighbor of one node, but nobody guarantees that, say, left neighbor node is ++ not a far right neighbor for other nodes from the same atom. It breaks ++ deadlock avoidance rules and hi-low priority locking cannot be applied for ++ atom locks. ++ ++ How does it help to avoid deadlocks ? ++ ++ Suppose we have a deadlock with n processes. Processes from one priority ++ class never deadlock because they take locks in one consistent ++ order. ++ ++ So, any possible deadlock loop must have low priority as well as high ++ priority processes. There are no other lock priority levels except low and ++ high. We know that any deadlock loop contains at least one node locked by a ++ low priority process and requested by a high priority process. If this ++ situation is caught and resolved it is sufficient to avoid deadlocks. ++ ++ V4 DEADLOCK PREVENTION ALGORITHM IMPLEMENTATION. ++ ++ The deadlock prevention algorithm is based on comparing ++ priorities of node owners (processes which keep znode locked) and ++ requesters (processes which want to acquire a lock on znode). We ++ implement a scheme where low-priority owners yield locks to ++ high-priority requesters. We created a signal passing system that ++ is used to ask low-priority processes to yield one or more locked ++ znodes. ++ ++ The condition when a znode needs to change its owners is described by the ++ following formula: ++ ++ ############################################# ++ # # ++ # (number of high-priority requesters) > 0 # ++ # AND # ++ # (numbers of high-priority owners) == 0 # ++ # # ++ ############################################# ++ ++ Note that a low-priority process delays node releasing if another ++ high-priority process owns this node. So, slightly more strictly speaking, ++ to have a deadlock capable cycle you must have a loop in which a high ++ priority process is waiting on a low priority process to yield a node, which ++ is slightly different from saying a high priority process is waiting on a ++ node owned by a low priority process. ++ ++ It is enough to avoid deadlocks if we prevent any low-priority process from ++ falling asleep if its locked set contains a node which satisfies the ++ deadlock condition. ++ ++ That condition is implicitly or explicitly checked in all places where new ++ high-priority requests may be added or removed from node request queue or ++ high-priority process takes or releases a lock on node. The main ++ goal of these checks is to never lose the moment when node becomes "has ++ wrong owners" and send "must-yield-this-lock" signals to its low-pri owners ++ at that time. ++ ++ The information about received signals is stored in the per-process ++ structure (lock stack) and analyzed before a low-priority process goes to ++ sleep but after a "fast" attempt to lock a node fails. Any signal wakes ++ sleeping process up and forces him to re-check lock status and received ++ signal info. If "must-yield-this-lock" signals were received the locking ++ primitive (longterm_lock_znode()) fails with -E_DEADLOCK error code. ++ ++ V4 LOCKING DRAWBACKS ++ ++ If we have already balanced on one level, and we are propagating our changes ++ upward to a higher level, it could be very messy to surrender all locks on ++ the lower level because we put so much computational work into it, and ++ reverting them to their state before they were locked might be very complex. ++ We also don't want to acquire all locks before performing balancing because ++ that would either be almost as much work as the balancing, or it would be ++ too conservative and lock too much. We want balancing to be done only at ++ high priority. Yet, we might want to go to the left one node and use some ++ of its empty space... So we make one attempt at getting the node to the left ++ using try_lock, and if it fails we do without it, because we didn't really ++ need it, it was only a nice to have. ++ ++ LOCK STRUCTURES DESCRIPTION ++ ++ The following data structures are used in the reiser4 locking ++ implementation: ++ ++ All fields related to long-term locking are stored in znode->lock. ++ ++ The lock stack is a per thread object. It owns all znodes locked by the ++ thread. One znode may be locked by several threads in case of read lock or ++ one znode may be write locked by one thread several times. The special link ++ objects (lock handles) support n<->m relation between znodes and lock ++ owners. ++ ++ <Thread 1> <Thread 2> ++ ++ +---------+ +---------+ ++ | LS1 | | LS2 | ++ +---------+ +---------+ ++ ^ ^ ++ |---------------+ +----------+ ++ v v v v ++ +---------+ +---------+ +---------+ +---------+ ++ | LH1 | | LH2 | | LH3 | | LH4 | ++ +---------+ +---------+ +---------+ +---------+ ++ ^ ^ ^ ^ ++ | +------------+ | ++ v v v ++ +---------+ +---------+ +---------+ ++ | Z1 | | Z2 | | Z3 | ++ +---------+ +---------+ +---------+ ++ ++ Thread 1 locked znodes Z1 and Z2, thread 2 locked znodes Z2 and Z3. The ++ picture above shows that lock stack LS1 has a list of 2 lock handles LH1 and ++ LH2, lock stack LS2 has a list with lock handles LH3 and LH4 on it. Znode ++ Z1 is locked by only one thread, znode has only one lock handle LH1 on its ++ list, similar situation is for Z3 which is locked by the thread 2 only. Z2 ++ is locked (for read) twice by different threads and two lock handles are on ++ its list. Each lock handle represents a single relation of a locking of a ++ znode by a thread. Locking of a znode is an establishing of a locking ++ relation between the lock stack and the znode by adding of a new lock handle ++ to a list of lock handles, the lock stack. The lock stack links all lock ++ handles for all znodes locked by the lock stack. The znode list groups all ++ lock handles for all locks stacks which locked the znode. ++ ++ Yet another relation may exist between znode and lock owners. If lock ++ procedure cannot immediately take lock on an object it adds the lock owner ++ on special `requestors' list belongs to znode. That list represents a ++ queue of pending lock requests. Because one lock owner may request only ++ only one lock object at a time, it is a 1->n relation between lock objects ++ and a lock owner implemented as it is described above. Full information ++ (priority, pointers to lock and link objects) about each lock request is ++ stored in lock owner structure in `request' field. ++ ++ SHORT_TERM LOCKING ++ ++ This is a list of primitive operations over lock stacks / lock handles / ++ znodes and locking descriptions for them. ++ ++ 1. locking / unlocking which is done by two list insertion/deletion, one ++ to/from znode's list of lock handles, another one is to/from lock stack's ++ list of lock handles. The first insertion is protected by ++ znode->lock.guard spinlock. The list owned by the lock stack can be ++ modified only by thread who owns the lock stack and nobody else can ++ modify/read it. There is nothing to be protected by a spinlock or ++ something else. ++ ++ 2. adding/removing a lock request to/from znode requesters list. The rule is ++ that znode->lock.guard spinlock should be taken for this. ++ ++ 3. we can traverse list of lock handles and use references to lock stacks who ++ locked given znode if znode->lock.guard spinlock is taken. ++ ++ 4. If a lock stack is associated with a znode as a lock requestor or lock ++ owner its existence is guaranteed by znode->lock.guard spinlock. Some its ++ (lock stack's) fields should be protected from being accessed in parallel ++ by two or more threads. Please look at lock_stack structure definition ++ for the info how those fields are protected. */ ++ ++/* Znode lock and capturing intertwining. */ ++/* In current implementation we capture formatted nodes before locking ++ them. Take a look on longterm lock znode, reiser4_try_capture() request ++ precedes locking requests. The longterm_lock_znode function unconditionally ++ captures znode before even checking of locking conditions. ++ ++ Another variant is to capture znode after locking it. It was not tested, but ++ at least one deadlock condition is supposed to be there. One thread has ++ locked a znode (Node-1) and calls reiser4_try_capture() for it. ++ reiser4_try_capture() sleeps because znode's atom has CAPTURE_WAIT state. ++ Second thread is a flushing thread, its current atom is the atom Node-1 ++ belongs to. Second thread wants to lock Node-1 and sleeps because Node-1 ++ is locked by the first thread. The described situation is a deadlock. */ ++ ++#include "debug.h" ++#include "txnmgr.h" ++#include "znode.h" ++#include "jnode.h" ++#include "tree.h" ++#include "plugin/node/node.h" ++#include "super.h" ++ ++#include <linux/spinlock.h> ++ ++#if REISER4_DEBUG ++static int request_is_deadlock_safe(znode * , znode_lock_mode, ++ znode_lock_request); ++#endif ++ ++/* Returns a lock owner associated with current thread */ ++lock_stack *get_current_lock_stack(void) ++{ ++ return &get_current_context()->stack; ++} ++ ++/* Wakes up all low priority owners informing them about possible deadlock */ ++static void wake_up_all_lopri_owners(znode * node) ++{ ++ lock_handle *handle; ++ ++ assert_spin_locked(&(node->lock.guard)); ++ list_for_each_entry(handle, &node->lock.owners, owners_link) { ++ assert("nikita-1832", handle->node == node); ++ /* count this signal in owner->nr_signaled */ ++ if (!handle->signaled) { ++ handle->signaled = 1; ++ atomic_inc(&handle->owner->nr_signaled); ++ /* Wake up a single process */ ++ reiser4_wake_up(handle->owner); ++ } ++ } ++} ++ ++/* Adds a lock to a lock owner, which means creating a link to the lock and ++ putting the link into the two lists all links are on (the doubly linked list ++ that forms the lock_stack, and the doubly linked list of links attached ++ to a lock. ++*/ ++static inline void ++link_object(lock_handle * handle, lock_stack * owner, znode * node) ++{ ++ assert("jmacd-810", handle->owner == NULL); ++ assert_spin_locked(&(node->lock.guard)); ++ ++ handle->owner = owner; ++ handle->node = node; ++ ++ assert("reiser4-4", ++ ergo(list_empty_careful(&owner->locks), owner->nr_locks == 0)); ++ ++ /* add lock handle to the end of lock_stack's list of locks */ ++ list_add_tail(&handle->locks_link, &owner->locks); ++ ON_DEBUG(owner->nr_locks++); ++ reiser4_ctx_gfp_mask_set(); ++ ++ /* add lock handle to the head of znode's list of owners */ ++ list_add(&handle->owners_link, &node->lock.owners); ++ handle->signaled = 0; ++} ++ ++/* Breaks a relation between a lock and its owner */ ++static inline void unlink_object(lock_handle * handle) ++{ ++ assert("zam-354", handle->owner != NULL); ++ assert("nikita-1608", handle->node != NULL); ++ assert_spin_locked(&(handle->node->lock.guard)); ++ assert("nikita-1829", handle->owner == get_current_lock_stack()); ++ assert("reiser4-5", handle->owner->nr_locks > 0); ++ ++ /* remove lock handle from lock_stack's list of locks */ ++ list_del(&handle->locks_link); ++ ON_DEBUG(handle->owner->nr_locks--); ++ reiser4_ctx_gfp_mask_set(); ++ assert("reiser4-6", ++ ergo(list_empty_careful(&handle->owner->locks), ++ handle->owner->nr_locks == 0)); ++ /* remove lock handle from znode's list of owners */ ++ list_del(&handle->owners_link); ++ /* indicates that lock handle is free now */ ++ handle->node = NULL; ++#if REISER4_DEBUG ++ INIT_LIST_HEAD(&handle->locks_link); ++ INIT_LIST_HEAD(&handle->owners_link); ++ handle->owner = NULL; ++#endif ++} ++ ++/* Actually locks an object knowing that we are able to do this */ ++static void lock_object(lock_stack * owner) ++{ ++ struct lock_request *request; ++ znode *node; ++ ++ request = &owner->request; ++ node = request->node; ++ assert_spin_locked(&(node->lock.guard)); ++ if (request->mode == ZNODE_READ_LOCK) { ++ node->lock.nr_readers++; ++ } else { ++ /* check that we don't switched from read to write lock */ ++ assert("nikita-1840", node->lock.nr_readers <= 0); ++ /* We allow recursive locking; a node can be locked several ++ times for write by same process */ ++ node->lock.nr_readers--; ++ } ++ ++ link_object(request->handle, owner, node); ++ ++ if (owner->curpri) ++ node->lock.nr_hipri_owners++; ++} ++ ++/* Check for recursive write locking */ ++static int recursive(lock_stack * owner) ++{ ++ int ret; ++ znode *node; ++ lock_handle *lh; ++ ++ node = owner->request.node; ++ ++ /* Owners list is not empty for a locked node */ ++ assert("zam-314", !list_empty_careful(&node->lock.owners)); ++ assert("nikita-1841", owner == get_current_lock_stack()); ++ assert_spin_locked(&(node->lock.guard)); ++ ++ lh = list_entry(node->lock.owners.next, lock_handle, owners_link); ++ ret = (lh->owner == owner); ++ ++ /* Recursive read locking should be done usual way */ ++ assert("zam-315", !ret || owner->request.mode == ZNODE_WRITE_LOCK); ++ /* mixing of read/write locks is not allowed */ ++ assert("zam-341", !ret || znode_is_wlocked(node)); ++ ++ return ret; ++} ++ ++#if REISER4_DEBUG ++/* Returns true if the lock is held by the calling thread. */ ++int znode_is_any_locked(const znode * node) ++{ ++ lock_handle *handle; ++ lock_stack *stack; ++ int ret; ++ ++ if (!znode_is_locked(node)) ++ return 0; ++ ++ stack = get_current_lock_stack(); ++ ++ spin_lock_stack(stack); ++ ++ ret = 0; ++ ++ list_for_each_entry(handle, &stack->locks, locks_link) { ++ if (handle->node == node) { ++ ret = 1; ++ break; ++ } ++ } ++ ++ spin_unlock_stack(stack); ++ ++ return ret; ++} ++ ++#endif ++ ++/* Returns true if a write lock is held by the calling thread. */ ++int znode_is_write_locked(const znode * node) ++{ ++ lock_stack *stack; ++ lock_handle *handle; ++ ++ assert("jmacd-8765", node != NULL); ++ ++ if (!znode_is_wlocked(node)) ++ return 0; ++ ++ stack = get_current_lock_stack(); ++ ++ /* ++ * When znode is write locked, all owner handles point to the same lock ++ * stack. Get pointer to lock stack from the first lock handle from ++ * znode's owner list ++ */ ++ handle = list_entry(node->lock.owners.next, lock_handle, owners_link); ++ ++ return (handle->owner == stack); ++} ++ ++/* This "deadlock" condition is the essential part of reiser4 locking ++ implementation. This condition is checked explicitly by calling ++ check_deadlock_condition() or implicitly in all places where znode lock ++ state (set of owners and request queue) is changed. Locking code is ++ designed to use this condition to trigger procedure of passing object from ++ low priority owner(s) to high priority one(s). ++ ++ The procedure results in passing an event (setting lock_handle->signaled ++ flag) and counting this event in nr_signaled field of owner's lock stack ++ object and wakeup owner's process. ++*/ ++static inline int check_deadlock_condition(znode * node) ++{ ++ assert_spin_locked(&(node->lock.guard)); ++ return node->lock.nr_hipri_requests > 0 ++ && node->lock.nr_hipri_owners == 0; ++} ++ ++static int check_livelock_condition(znode * node, znode_lock_mode mode) ++{ ++ zlock * lock = &node->lock; ++ ++ return mode == ZNODE_READ_LOCK && ++ lock->nr_readers >= 0 && lock->nr_hipri_write_requests > 0; ++} ++ ++/* checks lock/request compatibility */ ++static int can_lock_object(lock_stack * owner) ++{ ++ znode *node = owner->request.node; ++ ++ assert_spin_locked(&(node->lock.guard)); ++ ++ /* See if the node is disconnected. */ ++ if (unlikely(ZF_ISSET(node, JNODE_IS_DYING))) ++ return RETERR(-EINVAL); ++ ++ /* Do not ever try to take a lock if we are going in low priority ++ direction and a node have a high priority request without high ++ priority owners. */ ++ if (unlikely(!owner->curpri && check_deadlock_condition(node))) ++ return RETERR(-E_REPEAT); ++ if (unlikely(owner->curpri && ++ check_livelock_condition(node, owner->request.mode))) ++ return RETERR(-E_REPEAT); ++ if (unlikely(!is_lock_compatible(node, owner->request.mode))) ++ return RETERR(-E_REPEAT); ++ return 0; ++} ++ ++/* Setting of a high priority to the process. It clears "signaled" flags ++ because znode locked by high-priority process can't satisfy our "deadlock ++ condition". */ ++static void set_high_priority(lock_stack * owner) ++{ ++ assert("nikita-1846", owner == get_current_lock_stack()); ++ /* Do nothing if current priority is already high */ ++ if (!owner->curpri) { ++ /* We don't need locking for owner->locks list, because, this ++ * function is only called with the lock stack of the current ++ * thread, and no other thread can play with owner->locks list ++ * and/or change ->node pointers of lock handles in this list. ++ * ++ * (Interrupts also are not involved.) ++ */ ++ lock_handle *item = list_entry(owner->locks.next, lock_handle, ++ locks_link); ++ while (&owner->locks != &item->locks_link) { ++ znode *node = item->node; ++ ++ spin_lock_zlock(&node->lock); ++ ++ node->lock.nr_hipri_owners++; ++ ++ /* we can safely set signaled to zero, because ++ previous statement (nr_hipri_owners ++) guarantees ++ that signaled will be never set again. */ ++ item->signaled = 0; ++ spin_unlock_zlock(&node->lock); ++ ++ item = list_entry(item->locks_link.next, lock_handle, ++ locks_link); ++ } ++ owner->curpri = 1; ++ atomic_set(&owner->nr_signaled, 0); ++ } ++} ++ ++/* Sets a low priority to the process. */ ++static void set_low_priority(lock_stack * owner) ++{ ++ assert("nikita-3075", owner == get_current_lock_stack()); ++ /* Do nothing if current priority is already low */ ++ if (owner->curpri) { ++ /* scan all locks (lock handles) held by @owner, which is ++ actually current thread, and check whether we are reaching ++ deadlock possibility anywhere. ++ */ ++ lock_handle *handle = list_entry(owner->locks.next, lock_handle, ++ locks_link); ++ while (&owner->locks != &handle->locks_link) { ++ znode *node = handle->node; ++ spin_lock_zlock(&node->lock); ++ /* this thread just was hipri owner of @node, so ++ nr_hipri_owners has to be greater than zero. */ ++ assert("nikita-1835", node->lock.nr_hipri_owners > 0); ++ node->lock.nr_hipri_owners--; ++ /* If we have deadlock condition, adjust a nr_signaled ++ field. It is enough to set "signaled" flag only for ++ current process, other low-pri owners will be ++ signaled and waken up after current process unlocks ++ this object and any high-priority requestor takes ++ control. */ ++ if (check_deadlock_condition(node) ++ && !handle->signaled) { ++ handle->signaled = 1; ++ atomic_inc(&owner->nr_signaled); ++ } ++ spin_unlock_zlock(&node->lock); ++ handle = list_entry(handle->locks_link.next, ++ lock_handle, locks_link); ++ } ++ owner->curpri = 0; ++ } ++} ++ ++static void remove_lock_request(lock_stack * requestor) ++{ ++ zlock * lock = &requestor->request.node->lock; ++ ++ if (requestor->curpri) { ++ assert("nikita-1838", lock->nr_hipri_requests > 0); ++ lock->nr_hipri_requests--; ++ if (requestor->request.mode == ZNODE_WRITE_LOCK) ++ lock->nr_hipri_write_requests--; ++ } ++ list_del(&requestor->requestors_link); ++} ++ ++static void invalidate_all_lock_requests(znode * node) ++{ ++ lock_stack *requestor, *tmp; ++ ++ assert_spin_locked(&(node->lock.guard)); ++ ++ list_for_each_entry_safe(requestor, tmp, &node->lock.requestors, ++ requestors_link) { ++ remove_lock_request(requestor); ++ requestor->request.ret_code = -EINVAL; ++ reiser4_wake_up(requestor); ++ requestor->request.mode = ZNODE_NO_LOCK; ++ } ++} ++ ++static void dispatch_lock_requests(znode * node) ++{ ++ lock_stack *requestor, *tmp; ++ ++ assert_spin_locked(&(node->lock.guard)); ++ ++ list_for_each_entry_safe(requestor, tmp, &node->lock.requestors, ++ requestors_link) { ++ if (znode_is_write_locked(node)) ++ break; ++ if (!can_lock_object(requestor)) { ++ lock_object(requestor); ++ remove_lock_request(requestor); ++ requestor->request.ret_code = 0; ++ reiser4_wake_up(requestor); ++ requestor->request.mode = ZNODE_NO_LOCK; ++ } ++ } ++} ++ ++/* release long-term lock, acquired by longterm_lock_znode() */ ++void longterm_unlock_znode(lock_handle * handle) ++{ ++ znode *node = handle->node; ++ lock_stack *oldowner = handle->owner; ++ int hipri; ++ int readers; ++ int rdelta; ++ int youdie; ++ ++ /* ++ * this is time-critical and highly optimized code. Modify carefully. ++ */ ++ ++ assert("jmacd-1021", handle != NULL); ++ assert("jmacd-1022", handle->owner != NULL); ++ assert("nikita-1392", LOCK_CNT_GTZ(long_term_locked_znode)); ++ ++ assert("zam-130", oldowner == get_current_lock_stack()); ++ ++ LOCK_CNT_DEC(long_term_locked_znode); ++ ++ /* ++ * to minimize amount of operations performed under lock, pre-compute ++ * all variables used within critical section. This makes code ++ * obscure. ++ */ ++ ++ /* was this lock of hi or lo priority */ ++ hipri = oldowner->curpri ? 1 : 0; ++ /* number of readers */ ++ readers = node->lock.nr_readers; ++ /* +1 if write lock, -1 if read lock */ ++ rdelta = (readers > 0) ? -1 : +1; ++ /* true if node is to die and write lock is released */ ++ youdie = ZF_ISSET(node, JNODE_HEARD_BANSHEE) && (readers < 0); ++ ++ spin_lock_zlock(&node->lock); ++ ++ assert("zam-101", znode_is_locked(node)); ++ ++ /* Adjust a number of high priority owners of this lock */ ++ assert("nikita-1836", node->lock.nr_hipri_owners >= hipri); ++ node->lock.nr_hipri_owners -= hipri; ++ ++ /* Handle znode deallocation on last write-lock release. */ ++ if (znode_is_wlocked_once(node)) { ++ if (youdie) { ++ forget_znode(handle); ++ assert("nikita-2191", znode_invariant(node)); ++ zput(node); ++ return; ++ } ++ } ++ ++ if (handle->signaled) ++ atomic_dec(&oldowner->nr_signaled); ++ ++ /* Unlocking means owner<->object link deletion */ ++ unlink_object(handle); ++ ++ /* This is enough to be sure whether an object is completely ++ unlocked. */ ++ node->lock.nr_readers += rdelta; ++ ++ /* If the node is locked it must have an owners list. Likewise, if ++ the node is unlocked it must have an empty owners list. */ ++ assert("zam-319", equi(znode_is_locked(node), ++ !list_empty_careful(&node->lock.owners))); ++ ++#if REISER4_DEBUG ++ if (!znode_is_locked(node)) ++ ++node->times_locked; ++#endif ++ ++ /* If there are pending lock requests we wake up a requestor */ ++ if (!znode_is_wlocked(node)) ++ dispatch_lock_requests(node); ++ if (check_deadlock_condition(node)) ++ wake_up_all_lopri_owners(node); ++ spin_unlock_zlock(&node->lock); ++ ++ /* minus one reference from handle->node */ ++ assert("nikita-2190", znode_invariant(node)); ++ ON_DEBUG(check_lock_data()); ++ ON_DEBUG(check_lock_node_data(node)); ++ zput(node); ++} ++ ++/* final portion of longterm-lock */ ++static int ++lock_tail(lock_stack * owner, int ok, znode_lock_mode mode) ++{ ++ znode *node = owner->request.node; ++ ++ assert_spin_locked(&(node->lock.guard)); ++ ++ /* If we broke with (ok == 0) it means we can_lock, now do it. */ ++ if (ok == 0) { ++ lock_object(owner); ++ owner->request.mode = 0; ++ /* count a reference from lockhandle->node ++ ++ znode was already referenced at the entry to this function, ++ hence taking spin-lock here is not necessary (see comment ++ in the zref()). ++ */ ++ zref(node); ++ ++ LOCK_CNT_INC(long_term_locked_znode); ++ } ++ spin_unlock_zlock(&node->lock); ++ ON_DEBUG(check_lock_data()); ++ ON_DEBUG(check_lock_node_data(node)); ++ return ok; ++} ++ ++/* ++ * version of longterm_znode_lock() optimized for the most common case: read ++ * lock without any special flags. This is the kind of lock that any tree ++ * traversal takes on the root node of the tree, which is very frequent. ++ */ ++static int longterm_lock_tryfast(lock_stack * owner) ++{ ++ int result; ++ znode *node; ++ zlock *lock; ++ ++ node = owner->request.node; ++ lock = &node->lock; ++ ++ assert("nikita-3340", reiser4_schedulable()); ++ assert("nikita-3341", request_is_deadlock_safe(node, ++ ZNODE_READ_LOCK, ++ ZNODE_LOCK_LOPRI)); ++ spin_lock_zlock(lock); ++ result = can_lock_object(owner); ++ spin_unlock_zlock(lock); ++ ++ if (likely(result != -EINVAL)) { ++ spin_lock_znode(node); ++ result = reiser4_try_capture(ZJNODE(node), ZNODE_READ_LOCK, 0); ++ spin_unlock_znode(node); ++ spin_lock_zlock(lock); ++ if (unlikely(result != 0)) { ++ owner->request.mode = 0; ++ } else { ++ result = can_lock_object(owner); ++ if (unlikely(result == -E_REPEAT)) { ++ /* fall back to longterm_lock_znode() */ ++ spin_unlock_zlock(lock); ++ return 1; ++ } ++ } ++ return lock_tail(owner, result, ZNODE_READ_LOCK); ++ } else ++ return 1; ++} ++ ++/* locks given lock object */ ++int longterm_lock_znode( ++ /* local link object (allocated by lock owner ++ * thread, usually on its own stack) */ ++ lock_handle * handle, ++ /* znode we want to lock. */ ++ znode * node, ++ /* {ZNODE_READ_LOCK, ZNODE_WRITE_LOCK}; */ ++ znode_lock_mode mode, ++ /* {0, -EINVAL, -E_DEADLOCK}, see return codes ++ description. */ ++ znode_lock_request request) { ++ int ret; ++ int hipri = (request & ZNODE_LOCK_HIPRI) != 0; ++ int non_blocking = 0; ++ int has_atom; ++ txn_capture cap_flags; ++ zlock *lock; ++ txn_handle *txnh; ++ tree_level level; ++ ++ /* Get current process context */ ++ lock_stack *owner = get_current_lock_stack(); ++ ++ /* Check that the lock handle is initialized and isn't already being ++ * used. */ ++ assert("jmacd-808", handle->owner == NULL); ++ assert("nikita-3026", reiser4_schedulable()); ++ assert("nikita-3219", request_is_deadlock_safe(node, mode, request)); ++ assert("zam-1056", atomic_read(&ZJNODE(node)->x_count) > 0); ++ /* long term locks are not allowed in the VM contexts (->writepage(), ++ * prune_{d,i}cache()). ++ * ++ * FIXME this doesn't work due to unused-dentry-with-unlinked-inode ++ * bug caused by d_splice_alias() only working for directories. ++ */ ++ assert("nikita-3547", 1 || ((current->flags & PF_MEMALLOC) == 0)); ++ assert("zam-1055", mode != ZNODE_NO_LOCK); ++ ++ cap_flags = 0; ++ if (request & ZNODE_LOCK_NONBLOCK) { ++ cap_flags |= TXN_CAPTURE_NONBLOCKING; ++ non_blocking = 1; ++ } ++ ++ if (request & ZNODE_LOCK_DONT_FUSE) ++ cap_flags |= TXN_CAPTURE_DONT_FUSE; ++ ++ /* If we are changing our process priority we must adjust a number ++ of high priority owners for each znode that we already lock */ ++ if (hipri) { ++ set_high_priority(owner); ++ } else { ++ set_low_priority(owner); ++ } ++ ++ level = znode_get_level(node); ++ ++ /* Fill request structure with our values. */ ++ owner->request.mode = mode; ++ owner->request.handle = handle; ++ owner->request.node = node; ++ ++ txnh = get_current_context()->trans; ++ lock = &node->lock; ++ ++ if (mode == ZNODE_READ_LOCK && request == 0) { ++ ret = longterm_lock_tryfast(owner); ++ if (ret <= 0) ++ return ret; ++ } ++ ++ has_atom = (txnh->atom != NULL); ++ ++ /* Synchronize on node's zlock guard lock. */ ++ spin_lock_zlock(lock); ++ ++ if (znode_is_locked(node) && ++ mode == ZNODE_WRITE_LOCK && recursive(owner)) ++ return lock_tail(owner, 0, mode); ++ ++ for (;;) { ++ /* Check the lock's availability: if it is unavaiable we get ++ E_REPEAT, 0 indicates "can_lock", otherwise the node is ++ invalid. */ ++ ret = can_lock_object(owner); ++ ++ if (unlikely(ret == -EINVAL)) { ++ /* @node is dying. Leave it alone. */ ++ break; ++ } ++ ++ if (unlikely(ret == -E_REPEAT && non_blocking)) { ++ /* either locking of @node by the current thread will ++ * lead to the deadlock, or lock modes are ++ * incompatible. */ ++ break; ++ } ++ ++ assert("nikita-1844", (ret == 0) ++ || ((ret == -E_REPEAT) && !non_blocking)); ++ /* If we can get the lock... Try to capture first before ++ taking the lock. */ ++ ++ /* first handle commonest case where node and txnh are already ++ * in the same atom. */ ++ /* safe to do without taking locks, because: ++ * ++ * 1. read of aligned word is atomic with respect to writes to ++ * this word ++ * ++ * 2. false negatives are handled in reiser4_try_capture(). ++ * ++ * 3. false positives are impossible. ++ * ++ * PROOF: left as an exercise to the curious reader. ++ * ++ * Just kidding. Here is one: ++ * ++ * At the time T0 txnh->atom is stored in txnh_atom. ++ * ++ * At the time T1 node->atom is stored in node_atom. ++ * ++ * At the time T2 we observe that ++ * ++ * txnh_atom != NULL && node_atom == txnh_atom. ++ * ++ * Imagine that at this moment we acquire node and txnh spin ++ * lock in this order. Suppose that under spin lock we have ++ * ++ * node->atom != txnh->atom, (S1) ++ * ++ * at the time T3. ++ * ++ * txnh->atom != NULL still, because txnh is open by the ++ * current thread. ++ * ++ * Suppose node->atom == NULL, that is, node was un-captured ++ * between T1, and T3. But un-capturing of formatted node is ++ * always preceded by the call to reiser4_invalidate_lock(), ++ * which marks znode as JNODE_IS_DYING under zlock spin ++ * lock. Contradiction, because can_lock_object() above checks ++ * for JNODE_IS_DYING. Hence, node->atom != NULL at T3. ++ * ++ * Suppose that node->atom != node_atom, that is, atom, node ++ * belongs to was fused into another atom: node_atom was fused ++ * into node->atom. Atom of txnh was equal to node_atom at T2, ++ * which means that under spin lock, txnh->atom == node->atom, ++ * because txnh->atom can only follow fusion ++ * chain. Contradicts S1. ++ * ++ * The same for hypothesis txnh->atom != txnh_atom. Hence, ++ * node->atom == node_atom == txnh_atom == txnh->atom. Again ++ * contradicts S1. Hence S1 is false. QED. ++ * ++ */ ++ ++ if (likely(has_atom && ZJNODE(node)->atom == txnh->atom)) { ++ ; ++ } else { ++ /* ++ * unlock zlock spin lock here. It is possible for ++ * longterm_unlock_znode() to sneak in here, but there ++ * is no harm: reiser4_invalidate_lock() will mark znode ++ * as JNODE_IS_DYING and this will be noted by ++ * can_lock_object() below. ++ */ ++ spin_unlock_zlock(lock); ++ spin_lock_znode(node); ++ ret = reiser4_try_capture(ZJNODE(node), mode, ++ cap_flags); ++ spin_unlock_znode(node); ++ spin_lock_zlock(lock); ++ if (unlikely(ret != 0)) { ++ /* In the failure case, the txnmgr releases ++ the znode's lock (or in some cases, it was ++ released a while ago). There's no need to ++ reacquire it so we should return here, ++ avoid releasing the lock. */ ++ owner->request.mode = 0; ++ break; ++ } ++ ++ /* Check the lock's availability again -- this is ++ because under some circumstances the capture code ++ has to release and reacquire the znode spinlock. */ ++ ret = can_lock_object(owner); ++ } ++ ++ /* This time, a return of (ret == 0) means we can lock, so we ++ should break out of the loop. */ ++ if (likely(ret != -E_REPEAT || non_blocking)) ++ break; ++ ++ /* Lock is unavailable, we have to wait. */ ++ ret = reiser4_prepare_to_sleep(owner); ++ if (unlikely(ret != 0)) ++ break; ++ ++ assert_spin_locked(&(node->lock.guard)); ++ if (hipri) { ++ /* If we are going in high priority direction then ++ increase high priority requests counter for the ++ node */ ++ lock->nr_hipri_requests++; ++ if (mode == ZNODE_WRITE_LOCK) ++ lock->nr_hipri_write_requests++; ++ /* If there are no high priority owners for a node, ++ then immediately wake up low priority owners, so ++ they can detect possible deadlock */ ++ if (lock->nr_hipri_owners == 0) ++ wake_up_all_lopri_owners(node); ++ } ++ list_add_tail(&owner->requestors_link, &lock->requestors); ++ ++ /* Ok, here we have prepared a lock request, so unlock ++ a znode ... */ ++ spin_unlock_zlock(lock); ++ /* ... and sleep */ ++ reiser4_go_to_sleep(owner); ++ if (owner->request.mode == ZNODE_NO_LOCK) ++ goto request_is_done; ++ spin_lock_zlock(lock); ++ if (owner->request.mode == ZNODE_NO_LOCK) { ++ spin_unlock_zlock(lock); ++request_is_done: ++ if (owner->request.ret_code == 0) { ++ LOCK_CNT_INC(long_term_locked_znode); ++ zref(node); ++ } ++ return owner->request.ret_code; ++ } ++ remove_lock_request(owner); ++ } ++ ++ return lock_tail(owner, ret, mode); ++} ++ ++/* lock object invalidation means changing of lock object state to `INVALID' ++ and waiting for all other processes to cancel theirs lock requests. */ ++void reiser4_invalidate_lock(lock_handle * handle /* path to lock ++ * owner and lock ++ * object is being ++ * invalidated. */ ) ++{ ++ znode *node = handle->node; ++ lock_stack *owner = handle->owner; ++ ++ assert("zam-325", owner == get_current_lock_stack()); ++ assert("zam-103", znode_is_write_locked(node)); ++ assert("nikita-1393", !ZF_ISSET(node, JNODE_LEFT_CONNECTED)); ++ assert("nikita-1793", !ZF_ISSET(node, JNODE_RIGHT_CONNECTED)); ++ assert("nikita-1394", ZF_ISSET(node, JNODE_HEARD_BANSHEE)); ++ assert("nikita-3097", znode_is_wlocked_once(node)); ++ assert_spin_locked(&(node->lock.guard)); ++ ++ if (handle->signaled) ++ atomic_dec(&owner->nr_signaled); ++ ++ ZF_SET(node, JNODE_IS_DYING); ++ unlink_object(handle); ++ node->lock.nr_readers = 0; ++ ++ invalidate_all_lock_requests(node); ++ spin_unlock_zlock(&node->lock); ++} ++ ++/* Initializes lock_stack. */ ++void init_lock_stack(lock_stack * owner /* pointer to ++ * allocated ++ * structure. */ ) ++{ ++ INIT_LIST_HEAD(&owner->locks); ++ INIT_LIST_HEAD(&owner->requestors_link); ++ spin_lock_init(&owner->sguard); ++ owner->curpri = 1; ++ init_waitqueue_head(&owner->wait); ++} ++ ++/* Initializes lock object. */ ++void reiser4_init_lock(zlock * lock /* pointer on allocated ++ * uninitialized lock object ++ * structure. */ ) ++{ ++ memset(lock, 0, sizeof(zlock)); ++ spin_lock_init(&lock->guard); ++ INIT_LIST_HEAD(&lock->requestors); ++ INIT_LIST_HEAD(&lock->owners); ++} ++ ++/* Transfer a lock handle (presumably so that variables can be moved between ++ stack and heap locations). */ ++static void ++move_lh_internal(lock_handle * new, lock_handle * old, int unlink_old) ++{ ++ znode *node = old->node; ++ lock_stack *owner = old->owner; ++ int signaled; ++ ++ /* locks_list, modified by link_object() is not protected by ++ anything. This is valid because only current thread ever modifies ++ locks_list of its lock_stack. ++ */ ++ assert("nikita-1827", owner == get_current_lock_stack()); ++ assert("nikita-1831", new->owner == NULL); ++ ++ spin_lock_zlock(&node->lock); ++ ++ signaled = old->signaled; ++ if (unlink_old) { ++ unlink_object(old); ++ } else { ++ if (node->lock.nr_readers > 0) { ++ node->lock.nr_readers += 1; ++ } else { ++ node->lock.nr_readers -= 1; ++ } ++ if (signaled) ++ atomic_inc(&owner->nr_signaled); ++ if (owner->curpri) ++ node->lock.nr_hipri_owners += 1; ++ LOCK_CNT_INC(long_term_locked_znode); ++ ++ zref(node); ++ } ++ link_object(new, owner, node); ++ new->signaled = signaled; ++ ++ spin_unlock_zlock(&node->lock); ++} ++ ++void move_lh(lock_handle * new, lock_handle * old) ++{ ++ move_lh_internal(new, old, /*unlink_old */ 1); ++} ++ ++void copy_lh(lock_handle * new, lock_handle * old) ++{ ++ move_lh_internal(new, old, /*unlink_old */ 0); ++} ++ ++/* after getting -E_DEADLOCK we unlock znodes until this function returns false ++ */ ++int reiser4_check_deadlock(void) ++{ ++ lock_stack *owner = get_current_lock_stack(); ++ return atomic_read(&owner->nr_signaled) != 0; ++} ++ ++/* Before going to sleep we re-check "release lock" requests which might come ++ from threads with hi-pri lock priorities. */ ++int reiser4_prepare_to_sleep(lock_stack * owner) ++{ ++ assert("nikita-1847", owner == get_current_lock_stack()); ++ ++ /* We return -E_DEADLOCK if one or more "give me the lock" messages are ++ * counted in nr_signaled */ ++ if (unlikely(atomic_read(&owner->nr_signaled) != 0)) { ++ assert("zam-959", !owner->curpri); ++ return RETERR(-E_DEADLOCK); ++ } ++ return 0; ++} ++ ++/* Wakes up a single thread */ ++void __reiser4_wake_up(lock_stack * owner) ++{ ++ atomic_set(&owner->wakeup, 1); ++ wake_up(&owner->wait); ++} ++ ++/* Puts a thread to sleep */ ++void reiser4_go_to_sleep(lock_stack * owner) ++{ ++ /* Well, we might sleep here, so holding of any spinlocks is no-no */ ++ assert("nikita-3027", reiser4_schedulable()); ++ ++ wait_event(owner->wait, atomic_read(&owner->wakeup)); ++ atomic_set(&owner->wakeup, 0); ++} ++ ++int lock_stack_isclean(lock_stack * owner) ++{ ++ if (list_empty_careful(&owner->locks)) { ++ assert("zam-353", atomic_read(&owner->nr_signaled) == 0); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++#if REISER4_DEBUG ++ ++/* ++ * debugging functions ++ */ ++ ++static void list_check(struct list_head *head) ++{ ++ struct list_head *pos; ++ ++ list_for_each(pos, head) ++ assert("", (pos->prev != NULL && pos->next != NULL && ++ pos->prev->next == pos && pos->next->prev == pos)); ++} ++ ++/* check consistency of locking data-structures hanging of the @stack */ ++static void check_lock_stack(lock_stack * stack) ++{ ++ spin_lock_stack(stack); ++ /* check that stack->locks is not corrupted */ ++ list_check(&stack->locks); ++ spin_unlock_stack(stack); ++} ++ ++/* check consistency of locking data structures */ ++void check_lock_data(void) ++{ ++ check_lock_stack(&get_current_context()->stack); ++} ++ ++/* check consistency of locking data structures for @node */ ++void check_lock_node_data(znode * node) ++{ ++ spin_lock_zlock(&node->lock); ++ list_check(&node->lock.owners); ++ list_check(&node->lock.requestors); ++ spin_unlock_zlock(&node->lock); ++} ++ ++/* check that given lock request is dead lock safe. This check is, of course, ++ * not exhaustive. */ ++static int ++request_is_deadlock_safe(znode * node, znode_lock_mode mode, ++ znode_lock_request request) ++{ ++ lock_stack *owner; ++ ++ owner = get_current_lock_stack(); ++ /* ++ * check that hipri lock request is not issued when there are locked ++ * nodes at the higher levels. ++ */ ++ if (request & ZNODE_LOCK_HIPRI && !(request & ZNODE_LOCK_NONBLOCK) && ++ znode_get_level(node) != 0) { ++ lock_handle *item; ++ ++ list_for_each_entry(item, &owner->locks, locks_link) { ++ znode *other; ++ ++ other = item->node; ++ ++ if (znode_get_level(other) == 0) ++ continue; ++ if (znode_get_level(other) > znode_get_level(node)) ++ return 0; ++ } ++ } ++ return 1; ++} ++ ++#endif ++ ++/* return pointer to static storage with name of lock_mode. For ++ debugging */ ++const char *lock_mode_name(znode_lock_mode lock/* lock mode to get name of */) ++{ ++ if (lock == ZNODE_READ_LOCK) ++ return "read"; ++ else if (lock == ZNODE_WRITE_LOCK) ++ return "write"; ++ else { ++ static char buf[30]; ++ ++ sprintf(buf, "unknown: %i", lock); ++ return buf; ++ } ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 79 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/lock.h linux-2.6.30/fs/reiser4/lock.h +--- linux-2.6.30.orig/fs/reiser4/lock.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/lock.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,250 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Long term locking data structures. See lock.c for details. */ ++ ++#ifndef __LOCK_H__ ++#define __LOCK_H__ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "coord.h" ++#include "plugin/node/node.h" ++#include "txnmgr.h" ++#include "readahead.h" ++ ++#include <linux/types.h> ++#include <linux/spinlock.h> ++#include <linux/pagemap.h> /* for PAGE_CACHE_SIZE */ ++#include <asm/atomic.h> ++#include <linux/wait.h> ++ ++/* Per-znode lock object */ ++struct zlock { ++ spinlock_t guard; ++ /* The number of readers if positive; the number of recursively taken ++ write locks if negative. Protected by zlock spin lock. */ ++ int nr_readers; ++ /* A number of processes (lock_stacks) that have this object ++ locked with high priority */ ++ unsigned nr_hipri_owners; ++ /* A number of attempts to lock znode in high priority direction */ ++ unsigned nr_hipri_requests; ++ /* A linked list of lock_handle objects that contains pointers ++ for all lock_stacks which have this lock object locked */ ++ unsigned nr_hipri_write_requests; ++ struct list_head owners; ++ /* A linked list of lock_stacks that wait for this lock */ ++ struct list_head requestors; ++}; ++ ++static inline void spin_lock_zlock(zlock *lock) ++{ ++ /* check that zlock is not locked */ ++ assert("", LOCK_CNT_NIL(spin_locked_zlock)); ++ /* check that spinlocks of lower priorities are not held */ ++ assert("", LOCK_CNT_NIL(spin_locked_stack)); ++ ++ spin_lock(&lock->guard); ++ ++ LOCK_CNT_INC(spin_locked_zlock); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline void spin_unlock_zlock(zlock *lock) ++{ ++ assert("nikita-1375", LOCK_CNT_GTZ(spin_locked_zlock)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ LOCK_CNT_DEC(spin_locked_zlock); ++ LOCK_CNT_DEC(spin_locked); ++ ++ spin_unlock(&lock->guard); ++} ++ ++#define lock_is_locked(lock) ((lock)->nr_readers != 0) ++#define lock_is_rlocked(lock) ((lock)->nr_readers > 0) ++#define lock_is_wlocked(lock) ((lock)->nr_readers < 0) ++#define lock_is_wlocked_once(lock) ((lock)->nr_readers == -1) ++#define lock_can_be_rlocked(lock) ((lock)->nr_readers >= 0) ++#define lock_mode_compatible(lock, mode) \ ++ (((mode) == ZNODE_WRITE_LOCK && !lock_is_locked(lock)) || \ ++ ((mode) == ZNODE_READ_LOCK && lock_can_be_rlocked(lock))) ++ ++/* Since we have R/W znode locks we need additional bidirectional `link' ++ objects to implement n<->m relationship between lock owners and lock ++ objects. We call them `lock handles'. ++ ++ Locking: see lock.c/"SHORT-TERM LOCKING" ++*/ ++struct lock_handle { ++ /* This flag indicates that a signal to yield a lock was passed to ++ lock owner and counted in owner->nr_signalled ++ ++ Locking: this is accessed under spin lock on ->node. ++ */ ++ int signaled; ++ /* A link to owner of a lock */ ++ lock_stack *owner; ++ /* A link to znode locked */ ++ znode *node; ++ /* A list of all locks for a process */ ++ struct list_head locks_link; ++ /* A list of all owners for a znode */ ++ struct list_head owners_link; ++}; ++ ++struct lock_request { ++ /* A pointer to uninitialized link object */ ++ lock_handle *handle; ++ /* A pointer to the object we want to lock */ ++ znode *node; ++ /* Lock mode (ZNODE_READ_LOCK or ZNODE_WRITE_LOCK) */ ++ znode_lock_mode mode; ++ /* how dispatch_lock_requests() returns lock request result code */ ++ int ret_code; ++}; ++ ++/* A lock stack structure for accumulating locks owned by a process */ ++struct lock_stack { ++ /* A guard lock protecting a lock stack */ ++ spinlock_t sguard; ++ /* number of znodes which were requested by high priority processes */ ++ atomic_t nr_signaled; ++ /* Current priority of a process ++ ++ This is only accessed by the current thread and thus requires no ++ locking. ++ */ ++ int curpri; ++ /* A list of all locks owned by this process. Elements can be added to ++ * this list only by the current thread. ->node pointers in this list ++ * can be only changed by the current thread. */ ++ struct list_head locks; ++ /* When lock_stack waits for the lock, it puts itself on double-linked ++ requestors list of that lock */ ++ struct list_head requestors_link; ++ /* Current lock request info. ++ ++ This is only accessed by the current thread and thus requires no ++ locking. ++ */ ++ struct lock_request request; ++ /* the following two fields are the lock stack's ++ * synchronization object to use with the standard linux/wait.h ++ * interface. See reiser4_go_to_sleep and __reiser4_wake_up for ++ * usage details. */ ++ wait_queue_head_t wait; ++ atomic_t wakeup; ++#if REISER4_DEBUG ++ int nr_locks; /* number of lock handles in the above list */ ++#endif ++}; ++ ++/* ++ User-visible znode locking functions ++*/ ++ ++extern int longterm_lock_znode(lock_handle * handle, ++ znode * node, ++ znode_lock_mode mode, ++ znode_lock_request request); ++ ++extern void longterm_unlock_znode(lock_handle * handle); ++ ++extern int reiser4_check_deadlock(void); ++ ++extern lock_stack *get_current_lock_stack(void); ++ ++extern void init_lock_stack(lock_stack * owner); ++extern void reiser4_init_lock(zlock * lock); ++ ++static inline void init_lh(lock_handle *lh) ++{ ++#if REISER4_DEBUG ++ memset(lh, 0, sizeof *lh); ++ INIT_LIST_HEAD(&lh->locks_link); ++ INIT_LIST_HEAD(&lh->owners_link); ++#else ++ lh->node = NULL; ++#endif ++} ++ ++static inline void done_lh(lock_handle *lh) ++{ ++ assert("zam-342", lh != NULL); ++ if (lh->node != NULL) ++ longterm_unlock_znode(lh); ++} ++ ++extern void move_lh(lock_handle * new, lock_handle * old); ++extern void copy_lh(lock_handle * new, lock_handle * old); ++ ++extern int reiser4_prepare_to_sleep(lock_stack * owner); ++extern void reiser4_go_to_sleep(lock_stack * owner); ++extern void __reiser4_wake_up(lock_stack * owner); ++ ++extern int lock_stack_isclean(lock_stack * owner); ++ ++/* zlock object state check macros: only used in assertions. Both forms imply ++ that the lock is held by the current thread. */ ++extern int znode_is_write_locked(const znode *); ++extern void reiser4_invalidate_lock(lock_handle *); ++ ++/* lock ordering is: first take zlock spin lock, then lock stack spin lock */ ++#define spin_ordering_pred_stack(stack) \ ++ (LOCK_CNT_NIL(spin_locked_stack) && \ ++ LOCK_CNT_NIL(spin_locked_txnmgr) && \ ++ LOCK_CNT_NIL(spin_locked_inode) && \ ++ LOCK_CNT_NIL(rw_locked_cbk_cache) && \ ++ LOCK_CNT_NIL(spin_locked_super_eflush)) ++ ++static inline void spin_lock_stack(lock_stack *stack) ++{ ++ assert("", spin_ordering_pred_stack(stack)); ++ spin_lock(&(stack->sguard)); ++ LOCK_CNT_INC(spin_locked_stack); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline void spin_unlock_stack(lock_stack *stack) ++{ ++ assert_spin_locked(&(stack->sguard)); ++ assert("nikita-1375", LOCK_CNT_GTZ(spin_locked_stack)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ LOCK_CNT_DEC(spin_locked_stack); ++ LOCK_CNT_DEC(spin_locked); ++ spin_unlock(&(stack->sguard)); ++} ++ ++static inline void reiser4_wake_up(lock_stack * owner) ++{ ++ spin_lock_stack(owner); ++ __reiser4_wake_up(owner); ++ spin_unlock_stack(owner); ++} ++ ++const char *lock_mode_name(znode_lock_mode lock); ++ ++#if REISER4_DEBUG ++extern void check_lock_data(void); ++extern void check_lock_node_data(znode * node); ++#else ++#define check_lock_data() noop ++#define check_lock_node_data() noop ++#endif ++ ++/* __LOCK_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/Makefile linux-2.6.30/fs/reiser4/Makefile +--- linux-2.6.30.orig/fs/reiser4/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,98 @@ ++# ++# reiser4/Makefile ++# ++ ++obj-$(CONFIG_REISER4_FS) += reiser4.o ++ ++reiser4-y := \ ++ debug.o \ ++ jnode.o \ ++ znode.o \ ++ key.o \ ++ pool.o \ ++ tree_mod.o \ ++ estimate.o \ ++ carry.o \ ++ carry_ops.o \ ++ lock.o \ ++ tree.o \ ++ context.o \ ++ tap.o \ ++ coord.o \ ++ block_alloc.o \ ++ txnmgr.o \ ++ kassign.o \ ++ flush.o \ ++ wander.o \ ++ eottl.o \ ++ search.o \ ++ page_cache.o \ ++ seal.o \ ++ dscale.o \ ++ flush_queue.o \ ++ ktxnmgrd.o \ ++ blocknrset.o \ ++ super.o \ ++ super_ops.o \ ++ fsdata.o \ ++ export_ops.o \ ++ oid.o \ ++ tree_walk.o \ ++ inode.o \ ++ vfs_ops.o \ ++ as_ops.o \ ++ entd.o\ ++ readahead.o \ ++ status_flags.o \ ++ init_super.o \ ++ safe_link.o \ ++ \ ++ plugin/plugin.o \ ++ plugin/plugin_set.o \ ++ plugin/node/node.o \ ++ plugin/object.o \ ++ plugin/cluster.o \ ++ plugin/inode_ops.o \ ++ plugin/inode_ops_rename.o \ ++ plugin/file_ops.o \ ++ plugin/file_ops_readdir.o \ ++ plugin/file_plugin_common.o \ ++ plugin/file/file.o \ ++ plugin/file/tail_conversion.o \ ++ plugin/file/file_conversion.o \ ++ plugin/file/symlink.o \ ++ plugin/file/cryptcompress.o \ ++ plugin/dir_plugin_common.o \ ++ plugin/dir/hashed_dir.o \ ++ plugin/dir/seekable_dir.o \ ++ plugin/node/node40.o \ ++ \ ++ plugin/crypto/cipher.o \ ++ plugin/crypto/digest.o \ ++ \ ++ plugin/compress/compress.o \ ++ plugin/compress/compress_mode.o \ ++ \ ++ plugin/item/static_stat.o \ ++ plugin/item/sde.o \ ++ plugin/item/cde.o \ ++ plugin/item/blackbox.o \ ++ plugin/item/internal.o \ ++ plugin/item/tail.o \ ++ plugin/item/ctail.o \ ++ plugin/item/extent.o \ ++ plugin/item/extent_item_ops.o \ ++ plugin/item/extent_file_ops.o \ ++ plugin/item/extent_flush_ops.o \ ++ \ ++ plugin/hash.o \ ++ plugin/fibration.o \ ++ plugin/tail_policy.o \ ++ plugin/item/item.o \ ++ \ ++ plugin/security/perm.o \ ++ plugin/space/bitmap.o \ ++ \ ++ plugin/disk_format/disk_format40.o \ ++ plugin/disk_format/disk_format.o ++ +diff -urN linux-2.6.30.orig/fs/reiser4/oid.c linux-2.6.30/fs/reiser4/oid.c +--- linux-2.6.30.orig/fs/reiser4/oid.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/oid.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,141 @@ ++/* Copyright 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "debug.h" ++#include "super.h" ++#include "txnmgr.h" ++ ++/* we used to have oid allocation plugin. It was removed because it ++ was recognized as providing unneeded level of abstraction. If one ++ ever will find it useful - look at yet_unneeded_abstractions/oid ++*/ ++ ++/* ++ * initialize in-memory data for oid allocator at @super. @nr_files and @next ++ * are provided by disk format plugin that reads them from the disk during ++ * mount. ++ */ ++int oid_init_allocator(struct super_block *super, oid_t nr_files, oid_t next) ++{ ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = get_super_private(super); ++ ++ sbinfo->next_to_use = next; ++ sbinfo->oids_in_use = nr_files; ++ return 0; ++} ++ ++/* ++ * allocate oid and return it. ABSOLUTE_MAX_OID is returned when allocator ++ * runs out of oids. ++ */ ++oid_t oid_allocate(struct super_block *super) ++{ ++ reiser4_super_info_data *sbinfo; ++ oid_t oid; ++ ++ sbinfo = get_super_private(super); ++ ++ spin_lock_reiser4_super(sbinfo); ++ if (sbinfo->next_to_use != ABSOLUTE_MAX_OID) { ++ oid = sbinfo->next_to_use++; ++ sbinfo->oids_in_use++; ++ } else ++ oid = ABSOLUTE_MAX_OID; ++ spin_unlock_reiser4_super(sbinfo); ++ return oid; ++} ++ ++/* ++ * Tell oid allocator that @oid is now free. ++ */ ++int oid_release(struct super_block *super, oid_t oid UNUSED_ARG) ++{ ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = get_super_private(super); ++ ++ spin_lock_reiser4_super(sbinfo); ++ sbinfo->oids_in_use--; ++ spin_unlock_reiser4_super(sbinfo); ++ return 0; ++} ++ ++/* ++ * return next @oid that would be allocated (i.e., returned by oid_allocate()) ++ * without actually allocating it. This is used by disk format plugin to save ++ * oid allocator state on the disk. ++ */ ++oid_t oid_next(const struct super_block *super) ++{ ++ reiser4_super_info_data *sbinfo; ++ oid_t oid; ++ ++ sbinfo = get_super_private(super); ++ ++ spin_lock_reiser4_super(sbinfo); ++ oid = sbinfo->next_to_use; ++ spin_unlock_reiser4_super(sbinfo); ++ return oid; ++} ++ ++/* ++ * returns number of currently used oids. This is used by statfs(2) to report ++ * number of "inodes" and by disk format plugin to save oid allocator state on ++ * the disk. ++ */ ++long oids_used(const struct super_block *super) ++{ ++ reiser4_super_info_data *sbinfo; ++ oid_t used; ++ ++ sbinfo = get_super_private(super); ++ ++ spin_lock_reiser4_super(sbinfo); ++ used = sbinfo->oids_in_use; ++ spin_unlock_reiser4_super(sbinfo); ++ if (used < (__u64) ((long)~0) >> 1) ++ return (long)used; ++ else ++ return (long)-1; ++} ++ ++/* ++ * Count oid as allocated in atom. This is done after call to oid_allocate() ++ * at the point when we are irrevocably committed to creation of the new file ++ * (i.e., when oid allocation cannot be any longer rolled back due to some ++ * error). ++ */ ++void oid_count_allocated(void) ++{ ++ txn_atom *atom; ++ ++ atom = get_current_atom_locked(); ++ atom->nr_objects_created++; ++ spin_unlock_atom(atom); ++} ++ ++/* ++ * Count oid as free in atom. This is done after call to oid_release() at the ++ * point when we are irrevocably committed to the deletion of the file (i.e., ++ * when oid release cannot be any longer rolled back due to some error). ++ */ ++void oid_count_released(void) ++{ ++ txn_atom *atom; ++ ++ atom = get_current_atom_locked(); ++ atom->nr_objects_deleted++; ++ spin_unlock_atom(atom); ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/page_cache.c linux-2.6.30/fs/reiser4/page_cache.c +--- linux-2.6.30.orig/fs/reiser4/page_cache.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/page_cache.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,693 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Memory pressure hooks. Fake inodes handling. */ ++ ++/* GLOSSARY ++ ++ . Formatted and unformatted nodes. ++ Elements of reiser4 balanced tree to store data and metadata. ++ Unformatted nodes are pointed to by extent pointers. Such nodes ++ are used to store data of large objects. Unlike unformatted nodes, ++ formatted ones have associated format described by node4X plugin. ++ ++ . Jnode (or journal node) ++ The in-memory header which is used to track formatted and unformatted ++ nodes, bitmap nodes, etc. In particular, jnodes are used to track ++ transactional information associated with each block(see reiser4/jnode.c ++ for details). ++ ++ . Znode ++ The in-memory header which is used to track formatted nodes. Contains ++ embedded jnode (see reiser4/znode.c for details). ++*/ ++ ++/* We store all file system meta data (and data, of course) in the page cache. ++ ++ What does this mean? In stead of using bread/brelse we create special ++ "fake" inode (one per super block) and store content of formatted nodes ++ into pages bound to this inode in the page cache. In newer kernels bread() ++ already uses inode attached to block device (bd_inode). Advantage of having ++ our own fake inode is that we can install appropriate methods in its ++ address_space operations. Such methods are called by VM on memory pressure ++ (or during background page flushing) and we can use them to react ++ appropriately. ++ ++ In initial version we only support one block per page. Support for multiple ++ blocks per page is complicated by relocation. ++ ++ To each page, used by reiser4, jnode is attached. jnode is analogous to ++ buffer head. Difference is that jnode is bound to the page permanently: ++ jnode cannot be removed from memory until its backing page is. ++ ++ jnode contain pointer to page (->pg field) and page contain pointer to ++ jnode in ->private field. Pointer from jnode to page is protected to by ++ jnode's spinlock and pointer from page to jnode is protected by page lock ++ (PG_locked bit). Lock ordering is: first take page lock, then jnode spin ++ lock. To go into reverse direction use jnode_lock_page() function that uses ++ standard try-lock-and-release device. ++ ++ Properties: ++ ++ 1. when jnode-to-page mapping is established (by jnode_attach_page()), page ++ reference counter is increased. ++ ++ 2. when jnode-to-page mapping is destroyed (by page_clear_jnode(), page ++ reference counter is decreased. ++ ++ 3. on jload() reference counter on jnode page is increased, page is ++ kmapped and `referenced'. ++ ++ 4. on jrelse() inverse operations are performed. ++ ++ 5. kmapping/kunmapping of unformatted pages is done by read/write methods. ++ ++ DEADLOCKS RELATED TO MEMORY PRESSURE. [OUTDATED. Only interesting ++ historically.] ++ ++ [In the following discussion, `lock' invariably means long term lock on ++ znode.] (What about page locks?) ++ ++ There is some special class of deadlock possibilities related to memory ++ pressure. Locks acquired by other reiser4 threads are accounted for in ++ deadlock prevention mechanism (lock.c), but when ->vm_writeback() is ++ invoked additional hidden arc is added to the locking graph: thread that ++ tries to allocate memory waits for ->vm_writeback() to finish. If this ++ thread keeps lock and ->vm_writeback() tries to acquire this lock, deadlock ++ prevention is useless. ++ ++ Another related problem is possibility for ->vm_writeback() to run out of ++ memory itself. This is not a problem for ext2 and friends, because their ++ ->vm_writeback() don't allocate much memory, but reiser4 flush is ++ definitely able to allocate huge amounts of memory. ++ ++ It seems that there is no reliable way to cope with the problems above. In ++ stead it was decided that ->vm_writeback() (as invoked in the kswapd ++ context) wouldn't perform any flushing itself, but rather should just wake ++ up some auxiliary thread dedicated for this purpose (or, the same thread ++ that does periodic commit of old atoms (ktxnmgrd.c)). ++ ++ Details: ++ ++ 1. Page is called `reclaimable' against particular reiser4 mount F if this ++ page can be ultimately released by try_to_free_pages() under presumptions ++ that: ++ ++ a. ->vm_writeback() for F is no-op, and ++ ++ b. none of the threads accessing F are making any progress, and ++ ++ c. other reiser4 mounts obey the same memory reservation protocol as F ++ (described below). ++ ++ For example, clean un-pinned page, or page occupied by ext2 data are ++ reclaimable against any reiser4 mount. ++ ++ When there is more than one reiser4 mount in a system, condition (c) makes ++ reclaim-ability not easily verifiable beyond trivial cases mentioned above. ++ ++ THIS COMMENT IS VALID FOR "MANY BLOCKS ON PAGE" CASE ++ ++ Fake inode is used to bound formatted nodes and each node is indexed within ++ fake inode by its block number. If block size of smaller than page size, it ++ may so happen that block mapped to the page with formatted node is occupied ++ by unformatted node or is unallocated. This lead to some complications, ++ because flushing whole page can lead to an incorrect overwrite of ++ unformatted node that is moreover, can be cached in some other place as ++ part of the file body. To avoid this, buffers for unformatted nodes are ++ never marked dirty. Also pages in the fake are never marked dirty. This ++ rules out usage of ->writepage() as memory pressure hook. In stead ++ ->releasepage() is used. ++ ++ Josh is concerned that page->buffer is going to die. This should not pose ++ significant problem though, because we need to add some data structures to ++ the page anyway (jnode) and all necessary book keeping can be put there. ++ ++*/ ++ ++/* Life cycle of pages/nodes. ++ ++ jnode contains reference to page and page contains reference back to ++ jnode. This reference is counted in page ->count. Thus, page bound to jnode ++ cannot be released back into free pool. ++ ++ 1. Formatted nodes. ++ ++ 1. formatted node is represented by znode. When new znode is created its ++ ->pg pointer is NULL initially. ++ ++ 2. when node content is loaded into znode (by call to zload()) for the ++ first time following happens (in call to ->read_node() or ++ ->allocate_node()): ++ ++ 1. new page is added to the page cache. ++ ++ 2. this page is attached to znode and its ->count is increased. ++ ++ 3. page is kmapped. ++ ++ 3. if more calls to zload() follow (without corresponding zrelses), page ++ counter is left intact and in its stead ->d_count is increased in znode. ++ ++ 4. each call to zrelse decreases ->d_count. When ->d_count drops to zero ++ ->release_node() is called and page is kunmapped as result. ++ ++ 5. at some moment node can be captured by a transaction. Its ->x_count ++ is then increased by transaction manager. ++ ++ 6. if node is removed from the tree (empty node with JNODE_HEARD_BANSHEE ++ bit set) following will happen (also see comment at the top of znode.c): ++ ++ 1. when last lock is released, node will be uncaptured from ++ transaction. This released reference that transaction manager acquired ++ at the step 5. ++ ++ 2. when last reference is released, zput() detects that node is ++ actually deleted and calls ->delete_node() ++ operation. page_cache_delete_node() implementation detaches jnode from ++ page and releases page. ++ ++ 7. otherwise (node wasn't removed from the tree), last reference to ++ znode will be released after transaction manager committed transaction ++ node was in. This implies squallocing of this node (see ++ flush.c). Nothing special happens at this point. Znode is still in the ++ hash table and page is still attached to it. ++ ++ 8. znode is actually removed from the memory because of the memory ++ pressure, or during umount (znodes_tree_done()). Anyway, znode is ++ removed by the call to zdrop(). At this moment, page is detached from ++ znode and removed from the inode address space. ++ ++*/ ++ ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree.h" ++#include "vfs_ops.h" ++#include "inode.h" ++#include "super.h" ++#include "entd.h" ++#include "page_cache.h" ++#include "ktxnmgrd.h" ++ ++#include <linux/types.h> ++#include <linux/fs.h> ++#include <linux/mm.h> /* for struct page */ ++#include <linux/swap.h> /* for struct page */ ++#include <linux/pagemap.h> ++#include <linux/bio.h> ++#include <linux/writeback.h> ++#include <linux/blkdev.h> ++ ++static struct bio *page_bio(struct page *, jnode * , int rw, gfp_t gfp); ++ ++static struct address_space_operations formatted_fake_as_ops; ++ ++static const oid_t fake_ino = 0x1; ++static const oid_t bitmap_ino = 0x2; ++static const oid_t cc_ino = 0x3; ++ ++static void ++init_fake_inode(struct super_block *super, struct inode *fake, ++ struct inode **pfake) ++{ ++ assert("nikita-2168", fake->i_state & I_NEW); ++ fake->i_mapping->a_ops = &formatted_fake_as_ops; ++ *pfake = fake; ++ /* NOTE-NIKITA something else? */ ++ unlock_new_inode(fake); ++} ++ ++/** ++ * reiser4_init_formatted_fake - iget inodes for formatted nodes and bitmaps ++ * @super: super block to init fake inode for ++ * ++ * Initializes fake inode to which formatted nodes are bound in the page cache ++ * and inode for bitmaps. ++ */ ++int reiser4_init_formatted_fake(struct super_block *super) ++{ ++ struct inode *fake; ++ struct inode *bitmap; ++ struct inode *cc; ++ reiser4_super_info_data *sinfo; ++ ++ assert("nikita-1703", super != NULL); ++ ++ sinfo = get_super_private_nocheck(super); ++ fake = iget_locked(super, oid_to_ino(fake_ino)); ++ ++ if (fake != NULL) { ++ init_fake_inode(super, fake, &sinfo->fake); ++ ++ bitmap = iget_locked(super, oid_to_ino(bitmap_ino)); ++ if (bitmap != NULL) { ++ init_fake_inode(super, bitmap, &sinfo->bitmap); ++ ++ cc = iget_locked(super, oid_to_ino(cc_ino)); ++ if (cc != NULL) { ++ init_fake_inode(super, cc, &sinfo->cc); ++ return 0; ++ } else { ++ iput(sinfo->fake); ++ iput(sinfo->bitmap); ++ sinfo->fake = NULL; ++ sinfo->bitmap = NULL; ++ } ++ } else { ++ iput(sinfo->fake); ++ sinfo->fake = NULL; ++ } ++ } ++ return RETERR(-ENOMEM); ++} ++ ++/** ++ * reiser4_done_formatted_fake - release inode used by formatted nodes and bitmaps ++ * @super: super block to init fake inode for ++ * ++ * Releases inodes which were used as address spaces of bitmap and formatted ++ * nodes. ++ */ ++void reiser4_done_formatted_fake(struct super_block *super) ++{ ++ reiser4_super_info_data *sinfo; ++ ++ sinfo = get_super_private_nocheck(super); ++ ++ if (sinfo->fake != NULL) { ++ iput(sinfo->fake); ++ sinfo->fake = NULL; ++ } ++ ++ if (sinfo->bitmap != NULL) { ++ iput(sinfo->bitmap); ++ sinfo->bitmap = NULL; ++ } ++ ++ if (sinfo->cc != NULL) { ++ iput(sinfo->cc); ++ sinfo->cc = NULL; ++ } ++ return; ++} ++ ++void reiser4_wait_page_writeback(struct page *page) ++{ ++ assert("zam-783", PageLocked(page)); ++ ++ do { ++ unlock_page(page); ++ wait_on_page_writeback(page); ++ lock_page(page); ++ } while (PageWriteback(page)); ++} ++ ++/* return tree @page is in */ ++reiser4_tree *reiser4_tree_by_page(const struct page *page/* page to query */) ++{ ++ assert("nikita-2461", page != NULL); ++ return &get_super_private(page->mapping->host->i_sb)->tree; ++} ++ ++/* completion handler for single page bio-based read. ++ ++ mpage_end_io_read() would also do. But it's static. ++ ++*/ ++static void ++end_bio_single_page_read(struct bio *bio, int err UNUSED_ARG) ++{ ++ struct page *page; ++ ++ page = bio->bi_io_vec[0].bv_page; ++ ++ if (test_bit(BIO_UPTODATE, &bio->bi_flags)) { ++ SetPageUptodate(page); ++ } else { ++ ClearPageUptodate(page); ++ SetPageError(page); ++ } ++ unlock_page(page); ++ bio_put(bio); ++} ++ ++/* completion handler for single page bio-based write. ++ ++ mpage_end_io_write() would also do. But it's static. ++ ++*/ ++static void ++end_bio_single_page_write(struct bio *bio, int err UNUSED_ARG) ++{ ++ struct page *page; ++ ++ page = bio->bi_io_vec[0].bv_page; ++ ++ if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) ++ SetPageError(page); ++ end_page_writeback(page); ++ bio_put(bio); ++} ++ ++/* ->readpage() method for formatted nodes */ ++static int formatted_readpage(struct file *f UNUSED_ARG, ++ struct page *page/* page to read */) ++{ ++ assert("nikita-2412", PagePrivate(page) && jprivate(page)); ++ return reiser4_page_io(page, jprivate(page), READ, ++ reiser4_ctx_gfp_mask_get()); ++} ++ ++/** ++ * reiser4_page_io - submit single-page bio request ++ * @page: page to perform io for ++ * @node: jnode of page ++ * @rw: read or write ++ * @gfp: gfp mask for bio allocation ++ * ++ * Submits single page read or write. ++ */ ++int reiser4_page_io(struct page *page, jnode *node, int rw, gfp_t gfp) ++{ ++ struct bio *bio; ++ int result; ++ ++ assert("nikita-2094", page != NULL); ++ assert("nikita-2226", PageLocked(page)); ++ assert("nikita-2634", node != NULL); ++ assert("nikita-2893", rw == READ || rw == WRITE); ++ ++ if (rw) { ++ if (unlikely(page->mapping->host->i_sb->s_flags & MS_RDONLY)) { ++ unlock_page(page); ++ return 0; ++ } ++ } ++ ++ bio = page_bio(page, node, rw, gfp); ++ if (!IS_ERR(bio)) { ++ if (rw == WRITE) { ++ set_page_writeback(page); ++ unlock_page(page); ++ } ++ reiser4_submit_bio(rw, bio); ++ result = 0; ++ } else { ++ unlock_page(page); ++ result = PTR_ERR(bio); ++ } ++ ++ return result; ++} ++ ++/* helper function to construct bio for page */ ++static struct bio *page_bio(struct page *page, jnode * node, int rw, gfp_t gfp) ++{ ++ struct bio *bio; ++ assert("nikita-2092", page != NULL); ++ assert("nikita-2633", node != NULL); ++ ++ /* Simple implementation in the assumption that blocksize == pagesize. ++ ++ We only have to submit one block, but submit_bh() will allocate bio ++ anyway, so lets use all the bells-and-whistles of bio code. ++ */ ++ ++ bio = bio_alloc(gfp, 1); ++ if (bio != NULL) { ++ int blksz; ++ struct super_block *super; ++ reiser4_block_nr blocknr; ++ ++ super = page->mapping->host->i_sb; ++ assert("nikita-2029", super != NULL); ++ blksz = super->s_blocksize; ++ assert("nikita-2028", blksz == (int)PAGE_CACHE_SIZE); ++ ++ spin_lock_jnode(node); ++ blocknr = *jnode_get_io_block(node); ++ spin_unlock_jnode(node); ++ ++ assert("nikita-2275", blocknr != (reiser4_block_nr) 0); ++ assert("nikita-2276", !reiser4_blocknr_is_fake(&blocknr)); ++ ++ bio->bi_bdev = super->s_bdev; ++ /* fill bio->bi_sector before calling bio_add_page(), because ++ * q->merge_bvec_fn may want to inspect it (see ++ * drivers/md/linear.c:linear_mergeable_bvec() for example. */ ++ bio->bi_sector = blocknr * (blksz >> 9); ++ ++ if (!bio_add_page(bio, page, blksz, 0)) { ++ warning("nikita-3452", ++ "Single page bio cannot be constructed"); ++ return ERR_PTR(RETERR(-EINVAL)); ++ } ++ ++ /* bio -> bi_idx is filled by bio_init() */ ++ bio->bi_end_io = (rw == READ) ? ++ end_bio_single_page_read : end_bio_single_page_write; ++ ++ return bio; ++ } else ++ return ERR_PTR(RETERR(-ENOMEM)); ++} ++ ++#if 0 ++static int can_hit_entd(reiser4_context *ctx, struct super_block *s) ++{ ++ if (ctx == NULL || ((unsigned long)ctx->magic) != context_magic) ++ return 1; ++ if (ctx->super != s) ++ return 1; ++ if (get_super_private(s)->entd.tsk == current) ++ return 0; ++ if (!lock_stack_isclean(&ctx->stack)) ++ return 0; ++ if (ctx->trans->atom != NULL) ++ return 0; ++ return 1; ++} ++#endif ++ ++/** ++ * reiser4_writepage - writepage of struct address_space_operations ++ * @page: page to write ++ * @wbc: ++ * ++ * ++ */ ++/* Common memory pressure notification. */ ++int reiser4_writepage(struct page *page, ++ struct writeback_control *wbc) ++{ ++ struct super_block *s; ++ reiser4_context *ctx; ++ ++ assert("vs-828", PageLocked(page)); ++ ++ s = page->mapping->host->i_sb; ++ ctx = get_current_context_check(); ++ ++ /* assert("", can_hit_entd(ctx, s)); */ ++ return write_page_by_ent(page, wbc); ++} ++ ++/* ->set_page_dirty() method of formatted address_space */ ++static int formatted_set_page_dirty(struct page *page) ++{ ++ assert("nikita-2173", page != NULL); ++ BUG(); ++ return __set_page_dirty_nobuffers(page); ++} ++ ++/* writepages method of address space operations in reiser4 is used to involve ++ into transactions pages which are dirtied via mmap. Only regular files can ++ have such pages. Fake inode is used to access formatted nodes via page ++ cache. As formatted nodes can never be mmaped, fake inode's writepages has ++ nothing to do */ ++static int ++writepages_fake(struct address_space *mapping, struct writeback_control *wbc) ++{ ++ return 0; ++} ++ ++/* address space operations for the fake inode */ ++static struct address_space_operations formatted_fake_as_ops = { ++ /* Perform a writeback of a single page as a memory-freeing ++ * operation. */ ++ .writepage = reiser4_writepage, ++ /* this is called to read formatted node */ ++ .readpage = formatted_readpage, ++ /* ->sync_page() method of fake inode address space operations. Called ++ from wait_on_page() and lock_page(). ++ ++ This is most annoyingly misnomered method. Actually it is called ++ from wait_on_page_bit() and lock_page() and its purpose is to ++ actually start io by jabbing device drivers. ++ */ ++ .sync_page = block_sync_page, ++ /* Write back some dirty pages from this mapping. Called from sync. ++ called during sync (pdflush) */ ++ .writepages = writepages_fake, ++ /* Set a page dirty */ ++ .set_page_dirty = formatted_set_page_dirty, ++ /* used for read-ahead. Not applicable */ ++ .readpages = NULL, ++ .write_begin = NULL, ++ .write_end = NULL, ++ .bmap = NULL, ++ /* called just before page is being detached from inode mapping and ++ removed from memory. Called on truncate, cut/squeeze, and ++ umount. */ ++ .invalidatepage = reiser4_invalidatepage, ++ /* this is called by shrink_cache() so that file system can try to ++ release objects (jnodes, buffers, journal heads) attached to page ++ and, may be made page itself free-able. ++ */ ++ .releasepage = reiser4_releasepage, ++ .direct_IO = NULL ++}; ++ ++/* called just before page is released (no longer used by reiser4). Callers: ++ jdelete() and extent2tail(). */ ++void reiser4_drop_page(struct page *page) ++{ ++ assert("nikita-2181", PageLocked(page)); ++ clear_page_dirty_for_io(page); ++ ClearPageUptodate(page); ++#if defined(PG_skipped) ++ ClearPageSkipped(page); ++#endif ++ unlock_page(page); ++} ++ ++#define JNODE_GANG_SIZE (16) ++ ++/* find all jnodes from range specified and invalidate them */ ++static int ++truncate_jnodes_range(struct inode *inode, pgoff_t from, pgoff_t count) ++{ ++ reiser4_inode *info; ++ int truncated_jnodes; ++ reiser4_tree *tree; ++ unsigned long index; ++ unsigned long end; ++ ++ if (inode_file_plugin(inode) == ++ file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID)) ++ /* ++ * No need to get rid of jnodes here: if the single jnode of ++ * page cluster did not have page, then it was found and killed ++ * before in ++ * truncate_complete_page_cluster()->jput()->jput_final(), ++ * otherwise it will be dropped by reiser4_invalidatepage() ++ */ ++ return 0; ++ truncated_jnodes = 0; ++ ++ info = reiser4_inode_data(inode); ++ tree = reiser4_tree_by_inode(inode); ++ ++ index = from; ++ end = from + count; ++ ++ while (1) { ++ jnode *gang[JNODE_GANG_SIZE]; ++ int taken; ++ int i; ++ jnode *node; ++ ++ assert("nikita-3466", index <= end); ++ ++ read_lock_tree(tree); ++ taken = ++ radix_tree_gang_lookup(jnode_tree_by_reiser4_inode(info), ++ (void **)gang, index, ++ JNODE_GANG_SIZE); ++ for (i = 0; i < taken; ++i) { ++ node = gang[i]; ++ if (index_jnode(node) < end) ++ jref(node); ++ else ++ gang[i] = NULL; ++ } ++ read_unlock_tree(tree); ++ ++ for (i = 0; i < taken; ++i) { ++ node = gang[i]; ++ if (node != NULL) { ++ index = max(index, index_jnode(node)); ++ spin_lock_jnode(node); ++ assert("edward-1457", node->pg == NULL); ++ /* this is always called after ++ truncate_inode_pages_range(). Therefore, here ++ jnode can not have page. New pages can not be ++ created because truncate_jnodes_range goes ++ under exclusive access on file obtained, ++ where as new page creation requires ++ non-exclusive access obtained */ ++ JF_SET(node, JNODE_HEARD_BANSHEE); ++ reiser4_uncapture_jnode(node); ++ unhash_unformatted_jnode(node); ++ truncated_jnodes++; ++ jput(node); ++ } else ++ break; ++ } ++ if (i != taken || taken == 0) ++ break; ++ } ++ return truncated_jnodes; ++} ++ ++/* Truncating files in reiser4: problems and solutions. ++ ++ VFS calls fs's truncate after it has called truncate_inode_pages() ++ to get rid of pages corresponding to part of file being truncated. ++ In reiser4 it may cause existence of unallocated extents which do ++ not have jnodes. Flush code does not expect that. Solution of this ++ problem is straightforward. As vfs's truncate is implemented using ++ setattr operation, it seems reasonable to have ->setattr() that ++ will cut file body. However, flush code also does not expect dirty ++ pages without parent items, so it is impossible to cut all items, ++ then truncate all pages in two steps. We resolve this problem by ++ cutting items one-by-one. Each such fine-grained step performed ++ under longterm znode lock calls at the end ->kill_hook() method of ++ a killed item to remove its binded pages and jnodes. ++ ++ The following function is a common part of mentioned kill hooks. ++ Also, this is called before tail-to-extent conversion (to not manage ++ few copies of the data). ++*/ ++void reiser4_invalidate_pages(struct address_space *mapping, pgoff_t from, ++ unsigned long count, int even_cows) ++{ ++ loff_t from_bytes, count_bytes; ++ ++ if (count == 0) ++ return; ++ from_bytes = ((loff_t) from) << PAGE_CACHE_SHIFT; ++ count_bytes = ((loff_t) count) << PAGE_CACHE_SHIFT; ++ ++ unmap_mapping_range(mapping, from_bytes, count_bytes, even_cows); ++ truncate_inode_pages_range(mapping, from_bytes, ++ from_bytes + count_bytes - 1); ++ truncate_jnodes_range(mapping->host, from, count); ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 120 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/page_cache.h linux-2.6.30/fs/reiser4/page_cache.h +--- linux-2.6.30.orig/fs/reiser4/page_cache.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/page_cache.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,66 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++/* Memory pressure hooks. Fake inodes handling. See page_cache.c. */ ++ ++#if !defined(__REISER4_PAGE_CACHE_H__) ++#define __REISER4_PAGE_CACHE_H__ ++ ++#include "forward.h" ++#include "context.h" /* for reiser4_ctx_gfp_mask_get() */ ++ ++#include <linux/fs.h> /* for struct super_block, address_space */ ++#include <linux/mm.h> /* for struct page */ ++#include <linux/pagemap.h> /* for lock_page() */ ++#include <linux/vmalloc.h> /* for __vmalloc() */ ++ ++extern int reiser4_init_formatted_fake(struct super_block *); ++extern void reiser4_done_formatted_fake(struct super_block *); ++ ++extern reiser4_tree *reiser4_tree_by_page(const struct page *); ++ ++#define reiser4_submit_bio(rw, bio) submit_bio((rw), (bio)) ++ ++extern void reiser4_wait_page_writeback(struct page *); ++static inline void lock_and_wait_page_writeback(struct page *page) ++{ ++ lock_page(page); ++ if (unlikely(PageWriteback(page))) ++ reiser4_wait_page_writeback(page); ++} ++ ++#define jprivate(page) ((jnode *)page_private(page)) ++ ++extern int reiser4_page_io(struct page *, jnode *, int rw, gfp_t); ++extern void reiser4_drop_page(struct page *); ++extern void reiser4_invalidate_pages(struct address_space *, pgoff_t from, ++ unsigned long count, int even_cows); ++extern void capture_reiser4_inodes(struct super_block *, ++ struct writeback_control *); ++static inline void *reiser4_vmalloc(unsigned long size) ++{ ++ return __vmalloc(size, ++ reiser4_ctx_gfp_mask_get() | __GFP_HIGHMEM, ++ PAGE_KERNEL); ++} ++ ++#define PAGECACHE_TAG_REISER4_MOVED PAGECACHE_TAG_DIRTY ++ ++#if REISER4_DEBUG ++extern void print_page(const char *prefix, struct page *page); ++#else ++#define print_page(prf, p) noop ++#endif ++ ++/* __REISER4_PAGE_CACHE_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/cluster.c linux-2.6.30/fs/reiser4/plugin/cluster.c +--- linux-2.6.30.orig/fs/reiser4/plugin/cluster.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/cluster.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,72 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Contains reiser4 cluster plugins (see ++ http://www.namesys.com/cryptcompress_design.html ++ "Concepts of clustering" for details). */ ++ ++#include "plugin_header.h" ++#include "plugin.h" ++#include "../inode.h" ++ ++static int change_cluster(struct inode *inode, ++ reiser4_plugin * plugin, ++ pset_member memb) ++{ ++ assert("edward-1324", inode != NULL); ++ assert("edward-1325", plugin != NULL); ++ assert("edward-1326", is_reiser4_inode(inode)); ++ assert("edward-1327", plugin->h.type_id == REISER4_CLUSTER_PLUGIN_TYPE); ++ ++ /* Can't change the cluster plugin for already existent regular files */ ++ if (!plugin_of_group(inode_file_plugin(inode), REISER4_DIRECTORY_FILE)) ++ return RETERR(-EINVAL); ++ ++ /* If matches, nothing to change. */ ++ if (inode_hash_plugin(inode) != NULL && ++ inode_hash_plugin(inode)->h.id == plugin->h.id) ++ return 0; ++ ++ return aset_set_unsafe(&reiser4_inode_data(inode)->pset, ++ PSET_CLUSTER, plugin); ++} ++ ++static reiser4_plugin_ops cluster_plugin_ops = { ++ .init = NULL, ++ .load = NULL, ++ .save_len = NULL, ++ .save = NULL, ++ .change = &change_cluster ++}; ++ ++#define SUPPORT_CLUSTER(SHIFT, ID, LABEL, DESC) \ ++ [CLUSTER_ ## ID ## _ID] = { \ ++ .h = { \ ++ .type_id = REISER4_CLUSTER_PLUGIN_TYPE, \ ++ .id = CLUSTER_ ## ID ## _ID, \ ++ .pops = &cluster_plugin_ops, \ ++ .label = LABEL, \ ++ .desc = DESC, \ ++ .linkage = {NULL, NULL} \ ++ }, \ ++ .shift = SHIFT \ ++ } ++ ++cluster_plugin cluster_plugins[LAST_CLUSTER_ID] = { ++ SUPPORT_CLUSTER(16, 64K, "64K", "Large"), ++ SUPPORT_CLUSTER(15, 32K, "32K", "Big"), ++ SUPPORT_CLUSTER(14, 16K, "16K", "Average"), ++ SUPPORT_CLUSTER(13, 8K, "8K", "Small"), ++ SUPPORT_CLUSTER(12, 4K, "4K", "Minimal") ++}; ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/cluster.h linux-2.6.30/fs/reiser4/plugin/cluster.h +--- linux-2.6.30.orig/fs/reiser4/plugin/cluster.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/cluster.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,410 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* This file contains size/offset translators, modulators ++ and other helper functions. */ ++ ++#if !defined(__FS_REISER4_CLUSTER_H__) ++#define __FS_REISER4_CLUSTER_H__ ++ ++#include "../inode.h" ++ ++static inline int inode_cluster_shift(struct inode *inode) ++{ ++ assert("edward-92", inode != NULL); ++ assert("edward-93", reiser4_inode_data(inode) != NULL); ++ ++ return inode_cluster_plugin(inode)->shift; ++} ++ ++static inline unsigned cluster_nrpages_shift(struct inode *inode) ++{ ++ return inode_cluster_shift(inode) - PAGE_CACHE_SHIFT; ++} ++ ++/* cluster size in page units */ ++static inline unsigned cluster_nrpages(struct inode *inode) ++{ ++ return 1U << cluster_nrpages_shift(inode); ++} ++ ++static inline size_t inode_cluster_size(struct inode *inode) ++{ ++ assert("edward-96", inode != NULL); ++ ++ return 1U << inode_cluster_shift(inode); ++} ++ ++static inline cloff_t pg_to_clust(pgoff_t idx, struct inode *inode) ++{ ++ return idx >> cluster_nrpages_shift(inode); ++} ++ ++static inline pgoff_t clust_to_pg(cloff_t idx, struct inode *inode) ++{ ++ return idx << cluster_nrpages_shift(inode); ++} ++ ++static inline pgoff_t pg_to_clust_to_pg(pgoff_t idx, struct inode *inode) ++{ ++ return clust_to_pg(pg_to_clust(idx, inode), inode); ++} ++ ++static inline pgoff_t off_to_pg(loff_t off) ++{ ++ return (off >> PAGE_CACHE_SHIFT); ++} ++ ++static inline loff_t pg_to_off(pgoff_t idx) ++{ ++ return ((loff_t) (idx) << PAGE_CACHE_SHIFT); ++} ++ ++static inline cloff_t off_to_clust(loff_t off, struct inode *inode) ++{ ++ return off >> inode_cluster_shift(inode); ++} ++ ++static inline loff_t clust_to_off(cloff_t idx, struct inode *inode) ++{ ++ return (loff_t) idx << inode_cluster_shift(inode); ++} ++ ++static inline loff_t off_to_clust_to_off(loff_t off, struct inode *inode) ++{ ++ return clust_to_off(off_to_clust(off, inode), inode); ++} ++ ++static inline pgoff_t off_to_clust_to_pg(loff_t off, struct inode *inode) ++{ ++ return clust_to_pg(off_to_clust(off, inode), inode); ++} ++ ++static inline unsigned off_to_pgoff(loff_t off) ++{ ++ return off & (PAGE_CACHE_SIZE - 1); ++} ++ ++static inline unsigned off_to_cloff(loff_t off, struct inode *inode) ++{ ++ return off & ((loff_t) (inode_cluster_size(inode)) - 1); ++} ++ ++static inline pgoff_t offset_in_clust(struct page *page) ++{ ++ assert("edward-1488", page != NULL); ++ assert("edward-1489", page->mapping != NULL); ++ ++ return page_index(page) & ((cluster_nrpages(page->mapping->host)) - 1); ++} ++ ++static inline int first_page_in_cluster(struct page *page) ++{ ++ return offset_in_clust(page) == 0; ++} ++ ++static inline int last_page_in_cluster(struct page *page) ++{ ++ return offset_in_clust(page) == ++ cluster_nrpages(page->mapping->host) - 1; ++} ++ ++static inline unsigned ++pg_to_off_to_cloff(unsigned long idx, struct inode *inode) ++{ ++ return off_to_cloff(pg_to_off(idx), inode); ++} ++ ++/*********************** Size translators **************************/ ++ ++/* Translate linear size. ++ * New units are (1 << @blk_shift) times larger, then old ones. ++ * In other words, calculate number of logical blocks, occupied ++ * by @count elements ++ */ ++static inline unsigned long size_in_blocks(loff_t count, unsigned blkbits) ++{ ++ return (count + (1UL << blkbits) - 1) >> blkbits; ++} ++ ++/* size in pages */ ++static inline pgoff_t size_in_pages(loff_t size) ++{ ++ return size_in_blocks(size, PAGE_CACHE_SHIFT); ++} ++ ++/* size in logical clusters */ ++static inline cloff_t size_in_lc(loff_t size, struct inode *inode) ++{ ++ return size_in_blocks(size, inode_cluster_shift(inode)); ++} ++ ++/* size in pages to the size in page clusters */ ++static inline cloff_t sp_to_spcl(pgoff_t size, struct inode *inode) ++{ ++ return size_in_blocks(size, cluster_nrpages_shift(inode)); ++} ++ ++/*********************** Size modulators ***************************/ ++ ++/* ++ Modulate linear size by nominated block size and offset. ++ ++ The "finite" function (which is zero almost everywhere). ++ How much is a height of the figure at a position @pos, ++ when trying to construct rectangle of height (1 << @blkbits), ++ and square @size. ++ ++ ****** ++ ******* ++ ******* ++ ******* ++ ----------> pos ++*/ ++static inline unsigned __mbb(loff_t size, unsigned long pos, int blkbits) ++{ ++ unsigned end = size >> blkbits; ++ if (pos < end) ++ return 1U << blkbits; ++ if (unlikely(pos > end)) ++ return 0; ++ return size & ~(~0ull << blkbits); ++} ++ ++/* the same as above, but block size is page size */ ++static inline unsigned __mbp(loff_t size, pgoff_t pos) ++{ ++ return __mbb(size, pos, PAGE_CACHE_SHIFT); ++} ++ ++/* number of file's bytes in the nominated logical cluster */ ++static inline unsigned lbytes(cloff_t index, struct inode *inode) ++{ ++ return __mbb(i_size_read(inode), index, inode_cluster_shift(inode)); ++} ++ ++/* number of file's bytes in the nominated page */ ++static inline unsigned pbytes(pgoff_t index, struct inode *inode) ++{ ++ return __mbp(i_size_read(inode), index); ++} ++ ++/** ++ * number of pages occuped by @win->count bytes starting from ++ * @win->off at logical cluster defined by @win. This is exactly ++ * a number of pages to be modified and dirtied in any cluster operation. ++ */ ++static inline pgoff_t win_count_to_nrpages(struct reiser4_slide * win) ++{ ++ return ((win->off + win->count + ++ (1UL << PAGE_CACHE_SHIFT) - 1) >> PAGE_CACHE_SHIFT) - ++ off_to_pg(win->off); ++} ++ ++/* return true, if logical cluster is not occupied by the file */ ++static inline int new_logical_cluster(struct cluster_handle *clust, ++ struct inode *inode) ++{ ++ return clust_to_off(clust->index, inode) >= i_size_read(inode); ++} ++ ++/* return true, if pages @p1 and @p2 are of the same page cluster */ ++static inline int same_page_cluster(struct page *p1, struct page *p2) ++{ ++ assert("edward-1490", p1 != NULL); ++ assert("edward-1491", p2 != NULL); ++ assert("edward-1492", p1->mapping != NULL); ++ assert("edward-1493", p2->mapping != NULL); ++ ++ return (pg_to_clust(page_index(p1), p1->mapping->host) == ++ pg_to_clust(page_index(p2), p2->mapping->host)); ++} ++ ++static inline int cluster_is_complete(struct cluster_handle *clust, ++ struct inode *inode) ++{ ++ return clust->tc.lsize == inode_cluster_size(inode); ++} ++ ++static inline void reiser4_slide_init(struct reiser4_slide *win) ++{ ++ assert("edward-1084", win != NULL); ++ memset(win, 0, sizeof *win); ++} ++ ++static inline tfm_action ++cluster_get_tfm_act(struct tfm_cluster *tc) ++{ ++ assert("edward-1356", tc != NULL); ++ return tc->act; ++} ++ ++static inline void ++cluster_set_tfm_act(struct tfm_cluster *tc, tfm_action act) ++{ ++ assert("edward-1356", tc != NULL); ++ tc->act = act; ++} ++ ++static inline void cluster_init_act(struct cluster_handle *clust, ++ tfm_action act, ++ struct reiser4_slide *window) ++{ ++ assert("edward-84", clust != NULL); ++ memset(clust, 0, sizeof *clust); ++ cluster_set_tfm_act(&clust->tc, act); ++ clust->dstat = INVAL_DISK_CLUSTER; ++ clust->win = window; ++} ++ ++static inline void cluster_init_read(struct cluster_handle *clust, ++ struct reiser4_slide *window) ++{ ++ cluster_init_act(clust, TFMA_READ, window); ++} ++ ++static inline void cluster_init_write(struct cluster_handle *clust, ++ struct reiser4_slide *window) ++{ ++ cluster_init_act(clust, TFMA_WRITE, window); ++} ++ ++/* true if @p1 and @p2 are items of the same disk cluster */ ++static inline int same_disk_cluster(const coord_t *p1, const coord_t *p2) ++{ ++ /* drop this if you have other items to aggregate */ ++ assert("edward-1494", item_id_by_coord(p1) == CTAIL_ID); ++ ++ return item_plugin_by_coord(p1)->b.mergeable(p1, p2); ++} ++ ++static inline int dclust_get_extension_dsize(hint_t *hint) ++{ ++ return hint->ext_coord.extension.ctail.dsize; ++} ++ ++static inline void dclust_set_extension_dsize(hint_t *hint, int dsize) ++{ ++ hint->ext_coord.extension.ctail.dsize = dsize; ++} ++ ++static inline int dclust_get_extension_shift(hint_t *hint) ++{ ++ return hint->ext_coord.extension.ctail.shift; ++} ++ ++static inline int dclust_get_extension_ncount(hint_t *hint) ++{ ++ return hint->ext_coord.extension.ctail.ncount; ++} ++ ++static inline void dclust_inc_extension_ncount(hint_t *hint) ++{ ++ hint->ext_coord.extension.ctail.ncount++; ++} ++ ++static inline void dclust_init_extension(hint_t *hint) ++{ ++ memset(&hint->ext_coord.extension.ctail, 0, ++ sizeof(hint->ext_coord.extension.ctail)); ++} ++ ++static inline int hint_is_unprepped_dclust(hint_t *hint) ++{ ++ assert("edward-1451", hint_is_valid(hint)); ++ return dclust_get_extension_shift(hint) == (int)UCTAIL_SHIFT; ++} ++ ++static inline void coord_set_between_clusters(coord_t *coord) ++{ ++#if REISER4_DEBUG ++ int result; ++ result = zload(coord->node); ++ assert("edward-1296", !result); ++#endif ++ if (!coord_is_between_items(coord)) { ++ coord->between = AFTER_ITEM; ++ coord->unit_pos = 0; ++ } ++#if REISER4_DEBUG ++ zrelse(coord->node); ++#endif ++} ++ ++int reiser4_inflate_cluster(struct cluster_handle *, struct inode *); ++int find_disk_cluster(struct cluster_handle *, struct inode *, int read, ++ znode_lock_mode mode); ++int checkout_logical_cluster(struct cluster_handle *, jnode * , struct inode *); ++int reiser4_deflate_cluster(struct cluster_handle *, struct inode *); ++void truncate_complete_page_cluster(struct inode *inode, cloff_t start, ++ int even_cows); ++void invalidate_hint_cluster(struct cluster_handle *clust); ++int get_disk_cluster_locked(struct cluster_handle *clust, struct inode *inode, ++ znode_lock_mode lock_mode); ++void reset_cluster_params(struct cluster_handle *clust); ++int set_cluster_by_page(struct cluster_handle *clust, struct page *page, ++ int count); ++int prepare_page_cluster(struct inode *inode, struct cluster_handle *clust, ++ rw_op rw); ++void __put_page_cluster(int from, int count, struct page **pages, ++ struct inode *inode); ++void put_page_cluster(struct cluster_handle *clust, ++ struct inode *inode, rw_op rw); ++void put_cluster_handle(struct cluster_handle *clust); ++int grab_tfm_stream(struct inode *inode, struct tfm_cluster *tc, ++ tfm_stream_id id); ++int tfm_cluster_is_uptodate(struct tfm_cluster *tc); ++void tfm_cluster_set_uptodate(struct tfm_cluster *tc); ++void tfm_cluster_clr_uptodate(struct tfm_cluster *tc); ++ ++/* move cluster handle to the target position ++ specified by the page of index @pgidx */ ++static inline void move_cluster_forward(struct cluster_handle *clust, ++ struct inode *inode, ++ pgoff_t pgidx) ++{ ++ assert("edward-1297", clust != NULL); ++ assert("edward-1298", inode != NULL); ++ ++ reset_cluster_params(clust); ++ if (clust->index_valid && ++ /* Hole in the indices. Hint became invalid and can not be ++ used by find_cluster_item() even if seal/node versions ++ will coincide */ ++ pg_to_clust(pgidx, inode) != clust->index + 1) { ++ reiser4_unset_hint(clust->hint); ++ invalidate_hint_cluster(clust); ++ } ++ clust->index = pg_to_clust(pgidx, inode); ++ clust->index_valid = 1; ++} ++ ++static inline int alloc_clust_pages(struct cluster_handle *clust, ++ struct inode *inode) ++{ ++ assert("edward-791", clust != NULL); ++ assert("edward-792", inode != NULL); ++ clust->pages = ++ kmalloc(sizeof(*clust->pages) << inode_cluster_shift(inode), ++ reiser4_ctx_gfp_mask_get()); ++ if (!clust->pages) ++ return -ENOMEM; ++ return 0; ++} ++ ++static inline void free_clust_pages(struct cluster_handle *clust) ++{ ++ kfree(clust->pages); ++} ++ ++#endif /* __FS_REISER4_CLUSTER_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/compress/compress.c linux-2.6.30/fs/reiser4/plugin/compress/compress.c +--- linux-2.6.30.orig/fs/reiser4/plugin/compress/compress.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/compress/compress.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,355 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++/* reiser4 compression transform plugins */ ++ ++#include "../../debug.h" ++#include "../../inode.h" ++#include "../plugin.h" ++ ++#include <linux/lzo.h> ++#include <linux/zlib.h> ++#include <linux/types.h> ++#include <linux/hardirq.h> ++ ++static int change_compression(struct inode *inode, ++ reiser4_plugin * plugin, ++ pset_member memb) ++{ ++ assert("edward-1316", inode != NULL); ++ assert("edward-1317", plugin != NULL); ++ assert("edward-1318", is_reiser4_inode(inode)); ++ assert("edward-1319", ++ plugin->h.type_id == REISER4_COMPRESSION_PLUGIN_TYPE); ++ ++ /* cannot change compression plugin of already existing regular object */ ++ if (!plugin_of_group(inode_file_plugin(inode), REISER4_DIRECTORY_FILE)) ++ return RETERR(-EINVAL); ++ ++ /* If matches, nothing to change. */ ++ if (inode_hash_plugin(inode) != NULL && ++ inode_hash_plugin(inode)->h.id == plugin->h.id) ++ return 0; ++ ++ return aset_set_unsafe(&reiser4_inode_data(inode)->pset, ++ PSET_COMPRESSION, plugin); ++} ++ ++static reiser4_plugin_ops compression_plugin_ops = { ++ .init = NULL, ++ .load = NULL, ++ .save_len = NULL, ++ .save = NULL, ++ .change = &change_compression ++}; ++ ++/******************************************************************************/ ++/* gzip1 compression */ ++/******************************************************************************/ ++ ++#define GZIP1_DEF_LEVEL Z_BEST_SPEED ++#define GZIP1_DEF_WINBITS 15 ++#define GZIP1_DEF_MEMLEVEL MAX_MEM_LEVEL ++ ++static int gzip1_init(void) ++{ ++ return 0; ++} ++ ++static int gzip1_overrun(unsigned src_len UNUSED_ARG) ++{ ++ return 0; ++} ++ ++static coa_t gzip1_alloc(tfm_action act) ++{ ++ coa_t coa = NULL; ++ int ret = 0; ++ switch (act) { ++ case TFMA_WRITE: /* compress */ ++ coa = reiser4_vmalloc(zlib_deflate_workspacesize()); ++ if (!coa) { ++ ret = -ENOMEM; ++ break; ++ } ++ break; ++ case TFMA_READ: /* decompress */ ++ coa = reiser4_vmalloc(zlib_inflate_workspacesize()); ++ if (!coa) { ++ ret = -ENOMEM; ++ break; ++ } ++ break; ++ default: ++ impossible("edward-767", ++ "trying to alloc workspace for unknown tfm action"); ++ } ++ if (ret) { ++ warning("edward-768", ++ "alloc workspace for gzip1 (tfm action = %d) failed\n", ++ act); ++ return ERR_PTR(ret); ++ } ++ return coa; ++} ++ ++static void gzip1_free(coa_t coa, tfm_action act) ++{ ++ assert("edward-769", coa != NULL); ++ ++ switch (act) { ++ case TFMA_WRITE: /* compress */ ++ vfree(coa); ++ break; ++ case TFMA_READ: /* decompress */ ++ vfree(coa); ++ break; ++ default: ++ impossible("edward-770", "unknown tfm action"); ++ } ++ return; ++} ++ ++static int gzip1_min_size_deflate(void) ++{ ++ return 64; ++} ++ ++static void ++gzip1_compress(coa_t coa, __u8 * src_first, unsigned src_len, ++ __u8 * dst_first, unsigned *dst_len) ++{ ++ int ret = 0; ++ struct z_stream_s stream; ++ ++ assert("edward-842", coa != NULL); ++ assert("edward-875", src_len != 0); ++ ++ stream.workspace = coa; ++ ret = zlib_deflateInit2(&stream, GZIP1_DEF_LEVEL, Z_DEFLATED, ++ -GZIP1_DEF_WINBITS, GZIP1_DEF_MEMLEVEL, ++ Z_DEFAULT_STRATEGY); ++ if (ret != Z_OK) { ++ warning("edward-771", "zlib_deflateInit2 returned %d\n", ret); ++ goto rollback; ++ } ++ ret = zlib_deflateReset(&stream); ++ if (ret != Z_OK) { ++ warning("edward-772", "zlib_deflateReset returned %d\n", ret); ++ goto rollback; ++ } ++ stream.next_in = src_first; ++ stream.avail_in = src_len; ++ stream.next_out = dst_first; ++ stream.avail_out = *dst_len; ++ ++ ret = zlib_deflate(&stream, Z_FINISH); ++ if (ret != Z_STREAM_END) { ++ if (ret != Z_OK) ++ warning("edward-773", ++ "zlib_deflate returned %d\n", ret); ++ goto rollback; ++ } ++ *dst_len = stream.total_out; ++ return; ++ rollback: ++ *dst_len = src_len; ++ return; ++} ++ ++static void ++gzip1_decompress(coa_t coa, __u8 * src_first, unsigned src_len, ++ __u8 * dst_first, unsigned *dst_len) ++{ ++ int ret = 0; ++ struct z_stream_s stream; ++ ++ assert("edward-843", coa != NULL); ++ assert("edward-876", src_len != 0); ++ ++ stream.workspace = coa; ++ ret = zlib_inflateInit2(&stream, -GZIP1_DEF_WINBITS); ++ if (ret != Z_OK) { ++ warning("edward-774", "zlib_inflateInit2 returned %d\n", ret); ++ return; ++ } ++ ret = zlib_inflateReset(&stream); ++ if (ret != Z_OK) { ++ warning("edward-775", "zlib_inflateReset returned %d\n", ret); ++ return; ++ } ++ ++ stream.next_in = src_first; ++ stream.avail_in = src_len; ++ stream.next_out = dst_first; ++ stream.avail_out = *dst_len; ++ ++ ret = zlib_inflate(&stream, Z_SYNC_FLUSH); ++ /* ++ * Work around a bug in zlib, which sometimes wants to taste an extra ++ * byte when being used in the (undocumented) raw deflate mode. ++ * (From USAGI). ++ */ ++ if (ret == Z_OK && !stream.avail_in && stream.avail_out) { ++ u8 zerostuff = 0; ++ stream.next_in = &zerostuff; ++ stream.avail_in = 1; ++ ret = zlib_inflate(&stream, Z_FINISH); ++ } ++ if (ret != Z_STREAM_END) { ++ warning("edward-776", "zlib_inflate returned %d\n", ret); ++ return; ++ } ++ *dst_len = stream.total_out; ++ return; ++} ++ ++/******************************************************************************/ ++/* lzo1 compression */ ++/******************************************************************************/ ++ ++static int lzo1_init(void) ++{ ++ return 0; ++} ++ ++static int lzo1_overrun(unsigned in_len) ++{ ++ return in_len / 64 + 16 + 3; ++} ++ ++static coa_t lzo1_alloc(tfm_action act) ++{ ++ int ret = 0; ++ coa_t coa = NULL; ++ ++ switch (act) { ++ case TFMA_WRITE: /* compress */ ++ coa = reiser4_vmalloc(LZO1X_1_MEM_COMPRESS); ++ if (!coa) { ++ ret = -ENOMEM; ++ break; ++ } ++ case TFMA_READ: /* decompress */ ++ break; ++ default: ++ impossible("edward-877", ++ "trying to alloc workspace for unknown tfm action"); ++ } ++ if (ret) { ++ warning("edward-878", ++ "alloc workspace for lzo1 (tfm action = %d) failed\n", ++ act); ++ return ERR_PTR(ret); ++ } ++ return coa; ++} ++ ++static void lzo1_free(coa_t coa, tfm_action act) ++{ ++ assert("edward-879", coa != NULL); ++ ++ switch (act) { ++ case TFMA_WRITE: /* compress */ ++ vfree(coa); ++ break; ++ case TFMA_READ: /* decompress */ ++ impossible("edward-1304", ++ "trying to free non-allocated workspace"); ++ default: ++ impossible("edward-880", "unknown tfm action"); ++ } ++ return; ++} ++ ++static int lzo1_min_size_deflate(void) ++{ ++ return 256; ++} ++ ++static void ++lzo1_compress(coa_t coa, __u8 * src_first, unsigned src_len, ++ __u8 * dst_first, unsigned *dst_len) ++{ ++ int result; ++ ++ assert("edward-846", coa != NULL); ++ assert("edward-847", src_len != 0); ++ ++ result = lzo1x_1_compress(src_first, src_len, dst_first, dst_len, coa); ++ if (unlikely(result != LZO_E_OK)) { ++ warning("edward-849", "lzo1x_1_compress failed\n"); ++ goto out; ++ } ++ if (*dst_len >= src_len) { ++ //warning("edward-850", "lzo1x_1_compress: incompressible data\n"); ++ goto out; ++ } ++ return; ++ out: ++ *dst_len = src_len; ++ return; ++} ++ ++static void ++lzo1_decompress(coa_t coa, __u8 * src_first, unsigned src_len, ++ __u8 * dst_first, unsigned *dst_len) ++{ ++ int result; ++ ++ assert("edward-851", coa == NULL); ++ assert("edward-852", src_len != 0); ++ ++ result = lzo1x_decompress_safe(src_first, src_len, dst_first, dst_len); ++ if (result != LZO_E_OK) ++ warning("edward-853", "lzo1x_1_decompress failed\n"); ++ return; ++} ++ ++compression_plugin compression_plugins[LAST_COMPRESSION_ID] = { ++ [LZO1_COMPRESSION_ID] = { ++ .h = { ++ .type_id = REISER4_COMPRESSION_PLUGIN_TYPE, ++ .id = LZO1_COMPRESSION_ID, ++ .pops = &compression_plugin_ops, ++ .label = "lzo1", ++ .desc = "lzo1 compression transform", ++ .linkage = {NULL, NULL} ++ }, ++ .init = lzo1_init, ++ .overrun = lzo1_overrun, ++ .alloc = lzo1_alloc, ++ .free = lzo1_free, ++ .min_size_deflate = lzo1_min_size_deflate, ++ .checksum = reiser4_adler32, ++ .compress = lzo1_compress, ++ .decompress = lzo1_decompress ++ }, ++ [GZIP1_COMPRESSION_ID] = { ++ .h = { ++ .type_id = REISER4_COMPRESSION_PLUGIN_TYPE, ++ .id = GZIP1_COMPRESSION_ID, ++ .pops = &compression_plugin_ops, ++ .label = "gzip1", ++ .desc = "gzip1 compression transform", ++ .linkage = {NULL, NULL} ++ }, ++ .init = gzip1_init, ++ .overrun = gzip1_overrun, ++ .alloc = gzip1_alloc, ++ .free = gzip1_free, ++ .min_size_deflate = gzip1_min_size_deflate, ++ .checksum = reiser4_adler32, ++ .compress = gzip1_compress, ++ .decompress = gzip1_decompress ++ } ++}; ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/compress/compress.h linux-2.6.30/fs/reiser4/plugin/compress/compress.h +--- linux-2.6.30.orig/fs/reiser4/plugin/compress/compress.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/compress/compress.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,43 @@ ++#if !defined( __FS_REISER4_COMPRESS_H__ ) ++#define __FS_REISER4_COMPRESS_H__ ++ ++#include <linux/types.h> ++#include <linux/string.h> ++ ++/* transform direction */ ++typedef enum { ++ TFMA_READ, /* decrypt, decompress */ ++ TFMA_WRITE, /* encrypt, compress */ ++ TFMA_LAST ++} tfm_action; ++ ++/* supported compression algorithms */ ++typedef enum { ++ LZO1_COMPRESSION_ID, ++ GZIP1_COMPRESSION_ID, ++ LAST_COMPRESSION_ID, ++} reiser4_compression_id; ++ ++/* the same as pgoff, but units are page clusters */ ++typedef unsigned long cloff_t; ++ ++/* working data of a (de)compression algorithm */ ++typedef void *coa_t; ++ ++/* table for all supported (de)compression algorithms */ ++typedef coa_t coa_set[LAST_COMPRESSION_ID][TFMA_LAST]; ++ ++__u32 reiser4_adler32(char *data, __u32 len); ++ ++#endif /* __FS_REISER4_COMPRESS_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/compress/compress_mode.c linux-2.6.30/fs/reiser4/plugin/compress/compress_mode.c +--- linux-2.6.30.orig/fs/reiser4/plugin/compress/compress_mode.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/compress/compress_mode.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,162 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++/* This file contains Reiser4 compression mode plugins. ++ ++ Compression mode plugin is a set of handlers called by compressor ++ at flush time and represent some heuristics including the ones ++ which are to avoid compression of incompressible data, see ++ http://www.namesys.com/cryptcompress_design.html for more details. ++*/ ++#include "../../inode.h" ++#include "../plugin.h" ++ ++static int should_deflate_none(struct inode * inode, cloff_t index) ++{ ++ return 0; ++} ++ ++static int should_deflate_common(struct inode * inode, cloff_t index) ++{ ++ return compression_is_on(cryptcompress_inode_data(inode)); ++} ++ ++static int discard_hook_ultim(struct inode *inode, cloff_t index) ++{ ++ turn_off_compression(cryptcompress_inode_data(inode)); ++ return 0; ++} ++ ++static int discard_hook_lattd(struct inode *inode, cloff_t index) ++{ ++ struct cryptcompress_info * info = cryptcompress_inode_data(inode); ++ ++ assert("edward-1462", ++ get_lattice_factor(info) >= MIN_LATTICE_FACTOR && ++ get_lattice_factor(info) <= MAX_LATTICE_FACTOR); ++ ++ turn_off_compression(info); ++ if (get_lattice_factor(info) < MAX_LATTICE_FACTOR) ++ set_lattice_factor(info, get_lattice_factor(info) << 1); ++ return 0; ++} ++ ++static int accept_hook_lattd(struct inode *inode, cloff_t index) ++{ ++ turn_on_compression(cryptcompress_inode_data(inode)); ++ set_lattice_factor(cryptcompress_inode_data(inode), MIN_LATTICE_FACTOR); ++ return 0; ++} ++ ++/* Check on dynamic lattice, the adaptive compression modes which ++ defines the following behavior: ++ ++ Compression is on: try to compress everything and turn ++ it off, whenever cluster is incompressible. ++ ++ Compression is off: try to compress clusters of indexes ++ k * FACTOR (k = 0, 1, 2, ...) and turn it on, if some of ++ them is compressible. If incompressible, then increase FACTOR */ ++ ++/* check if @index belongs to one-dimensional lattice ++ of sparce factor @factor */ ++static int is_on_lattice(cloff_t index, int factor) ++{ ++ return (factor ? index % factor == 0: index == 0); ++} ++ ++static int should_deflate_lattd(struct inode * inode, cloff_t index) ++{ ++ return should_deflate_common(inode, index) || ++ is_on_lattice(index, ++ get_lattice_factor ++ (cryptcompress_inode_data(inode))); ++} ++ ++/* compression mode_plugins */ ++compression_mode_plugin compression_mode_plugins[LAST_COMPRESSION_MODE_ID] = { ++ [NONE_COMPRESSION_MODE_ID] = { ++ .h = { ++ .type_id = REISER4_COMPRESSION_MODE_PLUGIN_TYPE, ++ .id = NONE_COMPRESSION_MODE_ID, ++ .pops = NULL, ++ .label = "none", ++ .desc = "Compress nothing", ++ .linkage = {NULL, NULL} ++ }, ++ .should_deflate = should_deflate_none, ++ .accept_hook = NULL, ++ .discard_hook = NULL ++ }, ++ /* Check-on-dynamic-lattice adaptive compression mode */ ++ [LATTD_COMPRESSION_MODE_ID] = { ++ .h = { ++ .type_id = REISER4_COMPRESSION_MODE_PLUGIN_TYPE, ++ .id = LATTD_COMPRESSION_MODE_ID, ++ .pops = NULL, ++ .label = "lattd", ++ .desc = "Check on dynamic lattice", ++ .linkage = {NULL, NULL} ++ }, ++ .should_deflate = should_deflate_lattd, ++ .accept_hook = accept_hook_lattd, ++ .discard_hook = discard_hook_lattd ++ }, ++ /* Check-ultimately compression mode: ++ Turn off compression forever as soon as we meet ++ incompressible data */ ++ [ULTIM_COMPRESSION_MODE_ID] = { ++ .h = { ++ .type_id = REISER4_COMPRESSION_MODE_PLUGIN_TYPE, ++ .id = ULTIM_COMPRESSION_MODE_ID, ++ .pops = NULL, ++ .label = "ultim", ++ .desc = "Check ultimately", ++ .linkage = {NULL, NULL} ++ }, ++ .should_deflate = should_deflate_common, ++ .accept_hook = NULL, ++ .discard_hook = discard_hook_ultim ++ }, ++ /* Force-to-compress-everything compression mode */ ++ [FORCE_COMPRESSION_MODE_ID] = { ++ .h = { ++ .type_id = REISER4_COMPRESSION_MODE_PLUGIN_TYPE, ++ .id = FORCE_COMPRESSION_MODE_ID, ++ .pops = NULL, ++ .label = "force", ++ .desc = "Force to compress everything", ++ .linkage = {NULL, NULL} ++ }, ++ .should_deflate = NULL, ++ .accept_hook = NULL, ++ .discard_hook = NULL ++ }, ++ /* Convert-to-extent compression mode. ++ In this mode items will be converted to extents and management ++ will be passed to (classic) unix file plugin as soon as ->write() ++ detects that the first complete logical cluster (of index #0) is ++ incompressible. */ ++ [CONVX_COMPRESSION_MODE_ID] = { ++ .h = { ++ .type_id = REISER4_COMPRESSION_MODE_PLUGIN_TYPE, ++ .id = CONVX_COMPRESSION_MODE_ID, ++ .pops = NULL, ++ .label = "conv", ++ .desc = "Convert to extent", ++ .linkage = {NULL, NULL} ++ }, ++ .should_deflate = should_deflate_common, ++ .accept_hook = NULL, ++ .discard_hook = NULL ++ } ++}; ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/compress/Makefile linux-2.6.30/fs/reiser4/plugin/compress/Makefile +--- linux-2.6.30.orig/fs/reiser4/plugin/compress/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/compress/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,5 @@ ++obj-$(CONFIG_REISER4_FS) += compress_plugins.o ++ ++compress_plugins-objs := \ ++ compress.o \ ++ compress_mode.o +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/crypto/cipher.c linux-2.6.30/fs/reiser4/plugin/crypto/cipher.c +--- linux-2.6.30.orig/fs/reiser4/plugin/crypto/cipher.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/crypto/cipher.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,37 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, ++ licensing governed by reiser4/README */ ++/* Reiser4 cipher transform plugins */ ++ ++#include "../../debug.h" ++#include "../plugin.h" ++ ++cipher_plugin cipher_plugins[LAST_CIPHER_ID] = { ++ [NONE_CIPHER_ID] = { ++ .h = { ++ .type_id = REISER4_CIPHER_PLUGIN_TYPE, ++ .id = NONE_CIPHER_ID, ++ .pops = NULL, ++ .label = "none", ++ .desc = "no cipher transform", ++ .linkage = {NULL, NULL} ++ }, ++ .alloc = NULL, ++ .free = NULL, ++ .scale = NULL, ++ .align_stream = NULL, ++ .setkey = NULL, ++ .encrypt = NULL, ++ .decrypt = NULL ++ } ++}; ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/crypto/cipher.h linux-2.6.30/fs/reiser4/plugin/crypto/cipher.h +--- linux-2.6.30.orig/fs/reiser4/plugin/crypto/cipher.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/crypto/cipher.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,55 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++/* This file contains definitions for the objects operated ++ by reiser4 key manager, which is something like keyring ++ wrapped by appropriate reiser4 plugin */ ++ ++#if !defined( __FS_REISER4_CRYPT_H__ ) ++#define __FS_REISER4_CRYPT_H__ ++ ++#include <linux/crypto.h> ++ ++/* key info imported from user space */ ++struct reiser4_crypto_data { ++ int keysize; /* uninstantiated key size */ ++ __u8 * key; /* uninstantiated key */ ++ int keyid_size; /* size of passphrase */ ++ __u8 * keyid; /* passphrase */ ++}; ++ ++/* This object contains all needed infrastructure to implement ++ cipher transform. This is operated (allocating, inheriting, ++ validating, binding to host inode, etc..) by reiser4 key manager. ++ ++ This info can be allocated in two cases: ++ 1. importing a key from user space. ++ 2. reading inode from disk */ ++struct reiser4_crypto_info { ++ struct inode * host; ++ struct crypto_hash * digest; ++ struct crypto_blkcipher * cipher; ++#if 0 ++ cipher_key_plugin * kplug; /* key manager */ ++#endif ++ __u8 * keyid; /* key fingerprint, created by digest plugin, ++ using uninstantiated key and passphrase. ++ supposed to be stored in disk stat-data */ ++ int inst; /* this indicates if the cipher key is ++ instantiated (case 1 above) */ ++ int keysize; /* uninstantiated key size (bytes), supposed ++ to be stored in disk stat-data */ ++ int keyload_count; /* number of the objects which has this ++ crypto-stat attached */ ++}; ++ ++#endif /* __FS_REISER4_CRYPT_H__ */ ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/crypto/digest.c linux-2.6.30/fs/reiser4/plugin/crypto/digest.c +--- linux-2.6.30.orig/fs/reiser4/plugin/crypto/digest.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/crypto/digest.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,58 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* reiser4 digest transform plugin (is used by cryptcompress object plugin) */ ++/* EDWARD-FIXME-HANS: and it does what? a digest is a what? */ ++#include "../../debug.h" ++#include "../plugin_header.h" ++#include "../plugin.h" ++#include "../file/cryptcompress.h" ++ ++#include <linux/types.h> ++ ++extern digest_plugin digest_plugins[LAST_DIGEST_ID]; ++ ++static struct crypto_hash * alloc_sha256 (void) ++{ ++#if REISER4_SHA256 ++ return crypto_alloc_hash ("sha256", 0, CRYPTO_ALG_ASYNC); ++#else ++ warning("edward-1418", "sha256 unsupported"); ++ return ERR_PTR(-EINVAL); ++#endif ++} ++ ++static void free_sha256 (struct crypto_hash * tfm) ++{ ++#if REISER4_SHA256 ++ crypto_free_hash(tfm); ++#endif ++ return; ++} ++ ++/* digest plugins */ ++digest_plugin digest_plugins[LAST_DIGEST_ID] = { ++ [SHA256_32_DIGEST_ID] = { ++ .h = { ++ .type_id = REISER4_DIGEST_PLUGIN_TYPE, ++ .id = SHA256_32_DIGEST_ID, ++ .pops = NULL, ++ .label = "sha256_32", ++ .desc = "sha256_32 digest transform", ++ .linkage = {NULL, NULL} ++ }, ++ .fipsize = sizeof(__u32), ++ .alloc = alloc_sha256, ++ .free = free_sha256 ++ } ++}; ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/dir/dir.h linux-2.6.30/fs/reiser4/plugin/dir/dir.h +--- linux-2.6.30.orig/fs/reiser4/plugin/dir/dir.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/dir/dir.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,36 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* this file contains declarations of methods implementing directory plugins */ ++ ++#if !defined( __REISER4_DIR_H__ ) ++#define __REISER4_DIR_H__ ++ ++/*#include "../../key.h" ++ ++#include <linux/fs.h>*/ ++ ++/* declarations of functions implementing HASHED_DIR_PLUGIN_ID dir plugin */ ++ ++/* "hashed" directory methods of dir plugin */ ++void build_entry_key_hashed(const struct inode *, const struct qstr *, ++ reiser4_key *); ++ ++/* declarations of functions implementing SEEKABLE_HASHED_DIR_PLUGIN_ID dir plugin */ ++ ++/* "seekable" directory methods of dir plugin */ ++void build_entry_key_seekable(const struct inode *, const struct qstr *, ++ reiser4_key *); ++ ++/* __REISER4_DIR_H__ */ ++#endif ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/dir/hashed_dir.c linux-2.6.30/fs/reiser4/plugin/dir/hashed_dir.c +--- linux-2.6.30.orig/fs/reiser4/plugin/dir/hashed_dir.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/dir/hashed_dir.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,81 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Directory plugin using hashes (see fs/reiser4/plugin/hash.c) to map file ++ names to the files. */ ++ ++/* ++ * Hashed directory logically consists of persistent directory ++ * entries. Directory entry is a pair of a file name and a key of stat-data of ++ * a file that has this name in the given directory. ++ * ++ * Directory entries are stored in the tree in the form of directory ++ * items. Directory item should implement dir_entry_ops portion of item plugin ++ * interface (see plugin/item/item.h). Hashed directory interacts with ++ * directory item plugin exclusively through dir_entry_ops operations. ++ * ++ * Currently there are two implementations of directory items: "simple ++ * directory item" (plugin/item/sde.[ch]), and "compound directory item" ++ * (plugin/item/cde.[ch]) with the latter being the default. ++ * ++ * There is, however some delicate way through which directory code interferes ++ * with item plugin: key assignment policy. A key for a directory item is ++ * chosen by directory code, and as described in kassign.c, this key contains ++ * a portion of file name. Directory item uses this knowledge to avoid storing ++ * this portion of file name twice: in the key and in the directory item body. ++ * ++ */ ++ ++#include "../../inode.h" ++ ++void complete_entry_key(const struct inode *, const char *name, ++ int len, reiser4_key * result); ++ ++/* this is implementation of build_entry_key method of dir ++ plugin for HASHED_DIR_PLUGIN_ID ++ */ ++void build_entry_key_hashed(const struct inode *dir, /* directory where entry is ++ * (or will be) in.*/ ++ const struct qstr *qname, /* name of file referenced ++ * by this entry */ ++ reiser4_key * result /* resulting key of directory ++ * entry */ ) ++{ ++ const char *name; ++ int len; ++ ++ assert("nikita-1139", dir != NULL); ++ assert("nikita-1140", qname != NULL); ++ assert("nikita-1141", qname->name != NULL); ++ assert("nikita-1142", result != NULL); ++ ++ name = qname->name; ++ len = qname->len; ++ ++ assert("nikita-2867", strlen(name) == len); ++ ++ reiser4_key_init(result); ++ /* locality of directory entry's key is objectid of parent ++ directory */ ++ set_key_locality(result, get_inode_oid(dir)); ++ /* minor packing locality is constant */ ++ set_key_type(result, KEY_FILE_NAME_MINOR); ++ /* dot is special case---we always want it to be first entry in ++ a directory. Actually, we just want to have smallest ++ directory entry. ++ */ ++ if (len == 1 && name[0] == '.') ++ return; ++ ++ /* initialize part of entry key which depends on file name */ ++ complete_entry_key(dir, name, len, result); ++} ++ ++/* Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/dir/Makefile linux-2.6.30/fs/reiser4/plugin/dir/Makefile +--- linux-2.6.30.orig/fs/reiser4/plugin/dir/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/dir/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,5 @@ ++obj-$(CONFIG_REISER4_FS) += dir_plugins.o ++ ++dir_plugins-objs := \ ++ hashed_dir.o \ ++ seekable_dir.o +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/dir/seekable_dir.c linux-2.6.30/fs/reiser4/plugin/dir/seekable_dir.c +--- linux-2.6.30.orig/fs/reiser4/plugin/dir/seekable_dir.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/dir/seekable_dir.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* Copyright 2005 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#include "../../inode.h" ++ ++/* this is implementation of build_entry_key method of dir ++ plugin for SEEKABLE_HASHED_DIR_PLUGIN_ID ++ This is for directories where we want repeatable and restartable readdir() ++ even in case 32bit user level struct dirent (readdir(3)). ++*/ ++void ++build_entry_key_seekable(const struct inode *dir, const struct qstr *name, ++ reiser4_key * result) ++{ ++ oid_t objectid; ++ ++ assert("nikita-2283", dir != NULL); ++ assert("nikita-2284", name != NULL); ++ assert("nikita-2285", name->name != NULL); ++ assert("nikita-2286", result != NULL); ++ ++ reiser4_key_init(result); ++ /* locality of directory entry's key is objectid of parent ++ directory */ ++ set_key_locality(result, get_inode_oid(dir)); ++ /* minor packing locality is constant */ ++ set_key_type(result, KEY_FILE_NAME_MINOR); ++ /* dot is special case---we always want it to be first entry in ++ a directory. Actually, we just want to have smallest ++ directory entry. ++ */ ++ if ((name->len == 1) && (name->name[0] == '.')) ++ return; ++ ++ /* objectid of key is 31 lowest bits of hash. */ ++ objectid = ++ inode_hash_plugin(dir)->hash(name->name, ++ (int)name->len) & 0x7fffffff; ++ ++ assert("nikita-2303", !(objectid & ~KEY_OBJECTID_MASK)); ++ set_key_objectid(result, objectid); ++ ++ /* offset is always 0. */ ++ set_key_offset(result, (__u64) 0); ++ return; ++} +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/dir_plugin_common.c linux-2.6.30/fs/reiser4/plugin/dir_plugin_common.c +--- linux-2.6.30.orig/fs/reiser4/plugin/dir_plugin_common.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/dir_plugin_common.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,865 @@ ++/* Copyright 2005 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* this file contains typical implementations for most of methods of ++ directory plugin ++*/ ++ ++#include "../inode.h" ++ ++int reiser4_find_entry(struct inode *dir, struct dentry *name, ++ lock_handle * , znode_lock_mode, reiser4_dir_entry_desc *); ++int reiser4_lookup_name(struct inode *parent, struct dentry *dentry, ++ reiser4_key * key); ++void check_light_weight(struct inode *inode, struct inode *parent); ++ ++/* this is common implementation of get_parent method of dir plugin ++ this is used by NFS kernel server to "climb" up directory tree to ++ check permissions ++ */ ++struct dentry *get_parent_common(struct inode *child) ++{ ++ struct super_block *s; ++ struct inode *parent; ++ struct dentry dotdot; ++ struct dentry *dentry; ++ reiser4_key key; ++ int result; ++ ++ /* ++ * lookup dotdot entry. ++ */ ++ ++ s = child->i_sb; ++ memset(&dotdot, 0, sizeof(dotdot)); ++ dotdot.d_name.name = ".."; ++ dotdot.d_name.len = 2; ++ dotdot.d_op = &get_super_private(s)->ops.dentry; ++ ++ result = reiser4_lookup_name(child, &dotdot, &key); ++ if (result != 0) ++ return ERR_PTR(result); ++ ++ parent = reiser4_iget(s, &key, 1); ++ if (!IS_ERR(parent)) { ++ /* ++ * FIXME-NIKITA dubious: attributes are inherited from @child ++ * to @parent. But: ++ * ++ * (*) this is the only this we can do ++ * ++ * (*) attributes of light-weight object are inherited ++ * from a parent through which object was looked up first, ++ * so it is ambiguous anyway. ++ * ++ */ ++ check_light_weight(parent, child); ++ reiser4_iget_complete(parent); ++ dentry = d_obtain_alias(parent); ++ if (!IS_ERR(dentry)) ++ dentry->d_op = &get_super_private(s)->ops.dentry; ++ } else if (PTR_ERR(parent) == -ENOENT) ++ dentry = ERR_PTR(RETERR(-ESTALE)); ++ else ++ dentry = (void *)parent; ++ return dentry; ++} ++ ++/* this is common implementation of is_name_acceptable method of dir ++ plugin ++ */ ++int is_name_acceptable_common(const struct inode *inode, /* directory to check*/ ++ const char *name UNUSED_ARG, /* name to check */ ++ int len/* @name's length */) ++{ ++ assert("nikita-733", inode != NULL); ++ assert("nikita-734", name != NULL); ++ assert("nikita-735", len > 0); ++ ++ return len <= reiser4_max_filename_len(inode); ++} ++ ++/* there is no common implementation of build_entry_key method of dir ++ plugin. See plugin/dir/hashed_dir.c:build_entry_key_hashed() or ++ plugin/dir/seekable.c:build_entry_key_seekable() for example ++*/ ++ ++/* this is common implementation of build_readdir_key method of dir ++ plugin ++ see reiser4_readdir_common for more details ++*/ ++int build_readdir_key_common(struct file *dir /* directory being read */ , ++ reiser4_key * result/* where to store key */) ++{ ++ reiser4_file_fsdata *fdata; ++ struct inode *inode; ++ ++ assert("nikita-1361", dir != NULL); ++ assert("nikita-1362", result != NULL); ++ assert("nikita-1363", dir->f_dentry != NULL); ++ inode = dir->f_dentry->d_inode; ++ assert("nikita-1373", inode != NULL); ++ ++ fdata = reiser4_get_file_fsdata(dir); ++ if (IS_ERR(fdata)) ++ return PTR_ERR(fdata); ++ assert("nikita-1364", fdata != NULL); ++ return extract_key_from_de_id(get_inode_oid(inode), ++ &fdata->dir.readdir.position. ++ dir_entry_key, result); ++ ++} ++ ++void reiser4_adjust_dir_file(struct inode *, const struct dentry *, int offset, ++ int adj); ++ ++/* this is common implementation of add_entry method of dir plugin ++*/ ++int reiser4_add_entry_common(struct inode *object, /* directory to add new name ++ * in */ ++ struct dentry *where, /* new name */ ++ reiser4_object_create_data * data, /* parameters of ++ * new object */ ++ reiser4_dir_entry_desc * entry /* parameters of ++ * new directory ++ * entry */) ++{ ++ int result; ++ coord_t *coord; ++ lock_handle lh; ++ struct reiser4_dentry_fsdata *fsdata; ++ reiser4_block_nr reserve; ++ ++ assert("nikita-1114", object != NULL); ++ assert("nikita-1250", where != NULL); ++ ++ fsdata = reiser4_get_dentry_fsdata(where); ++ if (unlikely(IS_ERR(fsdata))) ++ return PTR_ERR(fsdata); ++ ++ reserve = inode_dir_plugin(object)->estimate.add_entry(object); ++ if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) ++ return RETERR(-ENOSPC); ++ ++ init_lh(&lh); ++ coord = &fsdata->dec.entry_coord; ++ coord_clear_iplug(coord); ++ ++ /* check for this entry in a directory. This is plugin method. */ ++ result = reiser4_find_entry(object, where, &lh, ZNODE_WRITE_LOCK, ++ entry); ++ if (likely(result == -ENOENT)) { ++ /* add new entry. Just pass control to the directory ++ item plugin. */ ++ assert("nikita-1709", inode_dir_item_plugin(object)); ++ assert("nikita-2230", coord->node == lh.node); ++ reiser4_seal_done(&fsdata->dec.entry_seal); ++ result = ++ inode_dir_item_plugin(object)->s.dir.add_entry(object, ++ coord, &lh, ++ where, ++ entry); ++ if (result == 0) { ++ reiser4_adjust_dir_file(object, where, ++ fsdata->dec.pos + 1, +1); ++ INODE_INC_FIELD(object, i_size); ++ } ++ } else if (result == 0) { ++ assert("nikita-2232", coord->node == lh.node); ++ result = RETERR(-EEXIST); ++ } ++ done_lh(&lh); ++ ++ return result; ++} ++ ++/** ++ * rem_entry - remove entry from directory item ++ * @dir: ++ * @dentry: ++ * @entry: ++ * @coord: ++ * @lh: ++ * ++ * Checks that coordinate @coord is set properly and calls item plugin ++ * method to cut entry. ++ */ ++static int ++rem_entry(struct inode *dir, struct dentry *dentry, ++ reiser4_dir_entry_desc * entry, coord_t *coord, lock_handle * lh) ++{ ++ item_plugin *iplug; ++ struct inode *child; ++ ++ iplug = inode_dir_item_plugin(dir); ++ child = dentry->d_inode; ++ assert("nikita-3399", child != NULL); ++ ++ /* check that we are really destroying an entry for @child */ ++ if (REISER4_DEBUG) { ++ int result; ++ reiser4_key key; ++ ++ result = iplug->s.dir.extract_key(coord, &key); ++ if (result != 0) ++ return result; ++ if (get_key_objectid(&key) != get_inode_oid(child)) { ++ warning("nikita-3397", ++ "rem_entry: %#llx != %#llx\n", ++ get_key_objectid(&key), ++ (unsigned long long)get_inode_oid(child)); ++ return RETERR(-EIO); ++ } ++ } ++ return iplug->s.dir.rem_entry(dir, &dentry->d_name, coord, lh, entry); ++} ++ ++/** ++ * reiser4_rem_entry_common - remove entry from a directory ++ * @dir: directory to remove entry from ++ * @where: name that is being removed ++ * @entry: description of entry being removed ++ * ++ * This is common implementation of rem_entry method of dir plugin. ++ */ ++int reiser4_rem_entry_common(struct inode *dir, ++ struct dentry *dentry, ++ reiser4_dir_entry_desc * entry) ++{ ++ int result; ++ coord_t *coord; ++ lock_handle lh; ++ struct reiser4_dentry_fsdata *fsdata; ++ __u64 tograb; ++ ++ assert("nikita-1124", dir != NULL); ++ assert("nikita-1125", dentry != NULL); ++ ++ tograb = inode_dir_plugin(dir)->estimate.rem_entry(dir); ++ result = reiser4_grab_space(tograb, BA_CAN_COMMIT | BA_RESERVED); ++ if (result != 0) ++ return RETERR(-ENOSPC); ++ ++ init_lh(&lh); ++ ++ /* check for this entry in a directory. This is plugin method. */ ++ result = reiser4_find_entry(dir, dentry, &lh, ZNODE_WRITE_LOCK, entry); ++ fsdata = reiser4_get_dentry_fsdata(dentry); ++ if (IS_ERR(fsdata)) { ++ done_lh(&lh); ++ return PTR_ERR(fsdata); ++ } ++ ++ coord = &fsdata->dec.entry_coord; ++ ++ assert("nikita-3404", ++ get_inode_oid(dentry->d_inode) != get_inode_oid(dir) || ++ dir->i_size <= 1); ++ ++ coord_clear_iplug(coord); ++ if (result == 0) { ++ /* remove entry. Just pass control to the directory item ++ plugin. */ ++ assert("vs-542", inode_dir_item_plugin(dir)); ++ reiser4_seal_done(&fsdata->dec.entry_seal); ++ reiser4_adjust_dir_file(dir, dentry, fsdata->dec.pos, -1); ++ result = ++ WITH_COORD(coord, ++ rem_entry(dir, dentry, entry, coord, &lh)); ++ if (result == 0) { ++ if (dir->i_size >= 1) ++ INODE_DEC_FIELD(dir, i_size); ++ else { ++ warning("nikita-2509", "Dir %llu is runt", ++ (unsigned long long) ++ get_inode_oid(dir)); ++ result = RETERR(-EIO); ++ } ++ ++ assert("nikita-3405", dentry->d_inode->i_nlink != 1 || ++ dentry->d_inode->i_size != 2 || ++ inode_dir_plugin(dentry->d_inode) == NULL); ++ } ++ } ++ done_lh(&lh); ++ ++ return result; ++} ++ ++static reiser4_block_nr estimate_init(struct inode *parent, ++ struct inode *object); ++static int create_dot_dotdot(struct inode *object, struct inode *parent); ++ ++/* this is common implementation of init method of dir plugin ++ create "." and ".." entries ++*/ ++int reiser4_dir_init_common(struct inode *object, /* new directory */ ++ struct inode *parent, /* parent directory */ ++ reiser4_object_create_data * data /* info passed ++ * to us, this ++ * is filled by ++ * reiser4() ++ * syscall in ++ * particular */) ++{ ++ reiser4_block_nr reserve; ++ ++ assert("nikita-680", object != NULL); ++ assert("nikita-681", S_ISDIR(object->i_mode)); ++ assert("nikita-682", parent != NULL); ++ assert("nikita-684", data != NULL); ++ assert("nikita-686", data->id == DIRECTORY_FILE_PLUGIN_ID); ++ assert("nikita-687", object->i_mode & S_IFDIR); ++ ++ reserve = estimate_init(parent, object); ++ if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) ++ return RETERR(-ENOSPC); ++ ++ return create_dot_dotdot(object, parent); ++} ++ ++/* this is common implementation of done method of dir plugin ++ remove "." entry ++*/ ++int reiser4_dir_done_common(struct inode *object/* object being deleted */) ++{ ++ int result; ++ reiser4_block_nr reserve; ++ struct dentry goodby_dots; ++ reiser4_dir_entry_desc entry; ++ ++ assert("nikita-1449", object != NULL); ++ ++ if (reiser4_inode_get_flag(object, REISER4_NO_SD)) ++ return 0; ++ ++ /* of course, this can be rewritten to sweep everything in one ++ reiser4_cut_tree(). */ ++ memset(&entry, 0, sizeof entry); ++ ++ /* FIXME: this done method is called from reiser4_delete_dir_common ++ * which reserved space already */ ++ reserve = inode_dir_plugin(object)->estimate.rem_entry(object); ++ if (reiser4_grab_space(reserve, BA_CAN_COMMIT | BA_RESERVED)) ++ return RETERR(-ENOSPC); ++ ++ memset(&goodby_dots, 0, sizeof goodby_dots); ++ entry.obj = goodby_dots.d_inode = object; ++ goodby_dots.d_name.name = "."; ++ goodby_dots.d_name.len = 1; ++ result = reiser4_rem_entry_common(object, &goodby_dots, &entry); ++ reiser4_free_dentry_fsdata(&goodby_dots); ++ if (unlikely(result != 0 && result != -ENOMEM && result != -ENOENT)) ++ warning("nikita-2252", "Cannot remove dot of %lli: %i", ++ (unsigned long long)get_inode_oid(object), result); ++ return 0; ++} ++ ++/* this is common implementation of attach method of dir plugin ++*/ ++int reiser4_attach_common(struct inode *child UNUSED_ARG, ++ struct inode *parent UNUSED_ARG) ++{ ++ assert("nikita-2647", child != NULL); ++ assert("nikita-2648", parent != NULL); ++ ++ return 0; ++} ++ ++/* this is common implementation of detach method of dir plugin ++ remove "..", decrease nlink on parent ++*/ ++int reiser4_detach_common(struct inode *object, struct inode *parent) ++{ ++ int result; ++ struct dentry goodby_dots; ++ reiser4_dir_entry_desc entry; ++ ++ assert("nikita-2885", object != NULL); ++ assert("nikita-2886", !reiser4_inode_get_flag(object, REISER4_NO_SD)); ++ ++ memset(&entry, 0, sizeof entry); ++ ++ /* NOTE-NIKITA this only works if @parent is -the- parent of ++ @object, viz. object whose key is stored in dotdot ++ entry. Wouldn't work with hard-links on directories. */ ++ memset(&goodby_dots, 0, sizeof goodby_dots); ++ entry.obj = goodby_dots.d_inode = parent; ++ goodby_dots.d_name.name = ".."; ++ goodby_dots.d_name.len = 2; ++ result = reiser4_rem_entry_common(object, &goodby_dots, &entry); ++ reiser4_free_dentry_fsdata(&goodby_dots); ++ if (result == 0) { ++ /* the dot should be the only entry remaining at this time... */ ++ assert("nikita-3400", ++ object->i_size == 1 && object->i_nlink <= 2); ++#if 0 ++ /* and, together with the only name directory can have, they ++ * provides for the last 2 remaining references. If we get ++ * here as part of error handling during mkdir, @object ++ * possibly has no name yet, so its nlink == 1. If we get here ++ * from rename (targeting empty directory), it has no name ++ * already, so its nlink == 1. */ ++ assert("nikita-3401", ++ object->i_nlink == 2 || object->i_nlink == 1); ++#endif ++ ++ /* decrement nlink of directory removed ".." pointed ++ to */ ++ reiser4_del_nlink(parent, NULL, 0); ++ } ++ return result; ++} ++ ++/* this is common implementation of estimate.add_entry method of ++ dir plugin ++ estimation of adding entry which supposes that entry is inserting a ++ unit into item ++*/ ++reiser4_block_nr estimate_add_entry_common(const struct inode *inode) ++{ ++ return estimate_one_insert_into_item(reiser4_tree_by_inode(inode)); ++} ++ ++/* this is common implementation of estimate.rem_entry method of dir ++ plugin ++*/ ++reiser4_block_nr estimate_rem_entry_common(const struct inode *inode) ++{ ++ return estimate_one_item_removal(reiser4_tree_by_inode(inode)); ++} ++ ++/* this is common implementation of estimate.unlink method of dir ++ plugin ++*/ ++reiser4_block_nr ++dir_estimate_unlink_common(const struct inode *parent, ++ const struct inode *object) ++{ ++ reiser4_block_nr res; ++ ++ /* hashed_rem_entry(object) */ ++ res = inode_dir_plugin(object)->estimate.rem_entry(object); ++ /* del_nlink(parent) */ ++ res += 2 * inode_file_plugin(parent)->estimate.update(parent); ++ ++ return res; ++} ++ ++/* ++ * helper for inode_ops ->lookup() and dir plugin's ->get_parent() ++ * methods: if @inode is a light-weight file, setup its credentials ++ * that are not stored in the stat-data in this case ++ */ ++void check_light_weight(struct inode *inode, struct inode *parent) ++{ ++ if (reiser4_inode_get_flag(inode, REISER4_LIGHT_WEIGHT)) { ++ inode->i_uid = parent->i_uid; ++ inode->i_gid = parent->i_gid; ++ /* clear light-weight flag. If inode would be read by any ++ other name, [ug]id wouldn't change. */ ++ reiser4_inode_clr_flag(inode, REISER4_LIGHT_WEIGHT); ++ } ++} ++ ++/* looks for name specified in @dentry in directory @parent and if name is ++ found - key of object found entry points to is stored in @entry->key */ ++int reiser4_lookup_name(struct inode *parent, /* inode of directory to lookup ++ * for name in */ ++ struct dentry *dentry, /* name to look for */ ++ reiser4_key * key/* place to store key */) ++{ ++ int result; ++ coord_t *coord; ++ lock_handle lh; ++ const char *name; ++ int len; ++ reiser4_dir_entry_desc entry; ++ struct reiser4_dentry_fsdata *fsdata; ++ ++ assert("nikita-1247", parent != NULL); ++ assert("nikita-1248", dentry != NULL); ++ assert("nikita-1123", dentry->d_name.name != NULL); ++ assert("vs-1486", ++ dentry->d_op == &get_super_private(parent->i_sb)->ops.dentry); ++ ++ name = dentry->d_name.name; ++ len = dentry->d_name.len; ++ ++ if (!inode_dir_plugin(parent)->is_name_acceptable(parent, name, len)) ++ /* some arbitrary error code to return */ ++ return RETERR(-ENAMETOOLONG); ++ ++ fsdata = reiser4_get_dentry_fsdata(dentry); ++ if (IS_ERR(fsdata)) ++ return PTR_ERR(fsdata); ++ ++ coord = &fsdata->dec.entry_coord; ++ coord_clear_iplug(coord); ++ init_lh(&lh); ++ ++ /* find entry in a directory. This is plugin method. */ ++ result = reiser4_find_entry(parent, dentry, &lh, ZNODE_READ_LOCK, ++ &entry); ++ if (result == 0) { ++ /* entry was found, extract object key from it. */ ++ result = ++ WITH_COORD(coord, ++ item_plugin_by_coord(coord)->s.dir. ++ extract_key(coord, key)); ++ } ++ done_lh(&lh); ++ return result; ++ ++} ++ ++/* helper for reiser4_dir_init_common(): estimate number of blocks to reserve */ ++static reiser4_block_nr ++estimate_init(struct inode *parent, struct inode *object) ++{ ++ reiser4_block_nr res = 0; ++ ++ assert("vpf-321", parent != NULL); ++ assert("vpf-322", object != NULL); ++ ++ /* hashed_add_entry(object) */ ++ res += inode_dir_plugin(object)->estimate.add_entry(object); ++ /* reiser4_add_nlink(object) */ ++ res += inode_file_plugin(object)->estimate.update(object); ++ /* hashed_add_entry(object) */ ++ res += inode_dir_plugin(object)->estimate.add_entry(object); ++ /* reiser4_add_nlink(parent) */ ++ res += inode_file_plugin(parent)->estimate.update(parent); ++ ++ return 0; ++} ++ ++/* helper function for reiser4_dir_init_common(). Create "." and ".." */ ++static int create_dot_dotdot(struct inode *object/* object to create dot and ++ * dotdot for */ , ++ struct inode *parent/* parent of @object */) ++{ ++ int result; ++ struct dentry dots_entry; ++ reiser4_dir_entry_desc entry; ++ ++ assert("nikita-688", object != NULL); ++ assert("nikita-689", S_ISDIR(object->i_mode)); ++ assert("nikita-691", parent != NULL); ++ ++ /* We store dot and dotdot as normal directory entries. This is ++ not necessary, because almost all information stored in them ++ is already in the stat-data of directory, the only thing ++ being missed is objectid of grand-parent directory that can ++ easily be added there as extension. ++ ++ But it is done the way it is done, because not storing dot ++ and dotdot will lead to the following complications: ++ ++ . special case handling in ->lookup(). ++ . addition of another extension to the sd. ++ . dependency on key allocation policy for stat data. ++ ++ */ ++ ++ memset(&entry, 0, sizeof entry); ++ memset(&dots_entry, 0, sizeof dots_entry); ++ entry.obj = dots_entry.d_inode = object; ++ dots_entry.d_name.name = "."; ++ dots_entry.d_name.len = 1; ++ result = reiser4_add_entry_common(object, &dots_entry, NULL, &entry); ++ reiser4_free_dentry_fsdata(&dots_entry); ++ ++ if (result == 0) { ++ result = reiser4_add_nlink(object, object, 0); ++ if (result == 0) { ++ entry.obj = dots_entry.d_inode = parent; ++ dots_entry.d_name.name = ".."; ++ dots_entry.d_name.len = 2; ++ result = reiser4_add_entry_common(object, ++ &dots_entry, NULL, &entry); ++ reiser4_free_dentry_fsdata(&dots_entry); ++ /* if creation of ".." failed, iput() will delete ++ object with ".". */ ++ if (result == 0) { ++ result = reiser4_add_nlink(parent, object, 0); ++ if (result != 0) ++ /* ++ * if we failed to bump i_nlink, try ++ * to remove ".." ++ */ ++ reiser4_detach_common(object, parent); ++ } ++ } ++ } ++ ++ if (result != 0) { ++ /* ++ * in the case of error, at least update stat-data so that, ++ * ->i_nlink updates are not lingering. ++ */ ++ reiser4_update_sd(object); ++ reiser4_update_sd(parent); ++ } ++ ++ return result; ++} ++ ++/* ++ * return 0 iff @coord contains a directory entry for the file with the name ++ * @name. ++ */ ++static int ++check_item(const struct inode *dir, const coord_t *coord, const char *name) ++{ ++ item_plugin *iplug; ++ char buf[DE_NAME_BUF_LEN]; ++ ++ iplug = item_plugin_by_coord(coord); ++ if (iplug == NULL) { ++ warning("nikita-1135", "Cannot get item plugin"); ++ print_coord("coord", coord, 1); ++ return RETERR(-EIO); ++ } else if (item_id_by_coord(coord) != ++ item_id_by_plugin(inode_dir_item_plugin(dir))) { ++ /* item id of current item does not match to id of items a ++ directory is built of */ ++ warning("nikita-1136", "Wrong item plugin"); ++ print_coord("coord", coord, 1); ++ return RETERR(-EIO); ++ } ++ assert("nikita-1137", iplug->s.dir.extract_name); ++ ++ /* Compare name stored in this entry with name we are looking for. ++ ++ NOTE-NIKITA Here should go code for support of something like ++ unicode, code tables, etc. ++ */ ++ return !!strcmp(name, iplug->s.dir.extract_name(coord, buf)); ++} ++ ++static int ++check_entry(const struct inode *dir, coord_t *coord, const struct qstr *name) ++{ ++ return WITH_COORD(coord, check_item(dir, coord, name->name)); ++} ++ ++/* ++ * argument package used by entry_actor to scan entries with identical keys. ++ */ ++struct entry_actor_args { ++ /* name we are looking for */ ++ const char *name; ++ /* key of directory entry. entry_actor() scans through sequence of ++ * items/units having the same key */ ++ reiser4_key *key; ++ /* how many entries with duplicate key was scanned so far. */ ++ int non_uniq; ++#if REISER4_USE_COLLISION_LIMIT ++ /* scan limit */ ++ int max_non_uniq; ++#endif ++ /* return parameter: set to true, if ->name wasn't found */ ++ int not_found; ++ /* what type of lock to take when moving to the next node during ++ * scan */ ++ znode_lock_mode mode; ++ ++ /* last coord that was visited during scan */ ++ coord_t last_coord; ++ /* last node locked during scan */ ++ lock_handle last_lh; ++ /* inode of directory */ ++ const struct inode *inode; ++}; ++ ++/* Function called by reiser4_find_entry() to look for given name ++ in the directory. */ ++static int entry_actor(reiser4_tree * tree UNUSED_ARG /* tree being scanned */ , ++ coord_t *coord /* current coord */ , ++ lock_handle * lh /* current lock handle */ , ++ void *entry_actor_arg/* argument to scan */) ++{ ++ reiser4_key unit_key; ++ struct entry_actor_args *args; ++ ++ assert("nikita-1131", tree != NULL); ++ assert("nikita-1132", coord != NULL); ++ assert("nikita-1133", entry_actor_arg != NULL); ++ ++ args = entry_actor_arg; ++ ++args->non_uniq; ++#if REISER4_USE_COLLISION_LIMIT ++ if (args->non_uniq > args->max_non_uniq) { ++ args->not_found = 1; ++ /* hash collision overflow. */ ++ return RETERR(-EBUSY); ++ } ++#endif ++ ++ /* ++ * did we just reach the end of the sequence of items/units with ++ * identical keys? ++ */ ++ if (!keyeq(args->key, unit_key_by_coord(coord, &unit_key))) { ++ assert("nikita-1791", ++ keylt(args->key, unit_key_by_coord(coord, &unit_key))); ++ args->not_found = 1; ++ args->last_coord.between = AFTER_UNIT; ++ return 0; ++ } ++ ++ coord_dup(&args->last_coord, coord); ++ /* ++ * did scan just moved to the next node? ++ */ ++ if (args->last_lh.node != lh->node) { ++ int lock_result; ++ ++ /* ++ * if so, lock new node with the mode requested by the caller ++ */ ++ done_lh(&args->last_lh); ++ assert("nikita-1896", znode_is_any_locked(lh->node)); ++ lock_result = longterm_lock_znode(&args->last_lh, lh->node, ++ args->mode, ZNODE_LOCK_HIPRI); ++ if (lock_result != 0) ++ return lock_result; ++ } ++ return check_item(args->inode, coord, args->name); ++} ++ ++/* Look for given @name within directory @dir. ++ ++ This is called during lookup, creation and removal of directory ++ entries and on reiser4_rename_common ++ ++ First calculate key that directory entry for @name would have. Search ++ for this key in the tree. If such key is found, scan all items with ++ the same key, checking name in each directory entry along the way. ++*/ ++int reiser4_find_entry(struct inode *dir, /* directory to scan */ ++ struct dentry *de, /* name to search for */ ++ lock_handle * lh, /* resulting lock handle */ ++ znode_lock_mode mode, /* required lock mode */ ++ reiser4_dir_entry_desc * entry /* parameters of found ++ directory entry */) ++{ ++ const struct qstr *name; ++ seal_t *seal; ++ coord_t *coord; ++ int result; ++ __u32 flags; ++ struct de_location *dec; ++ struct reiser4_dentry_fsdata *fsdata; ++ ++ assert("nikita-1130", lh != NULL); ++ assert("nikita-1128", dir != NULL); ++ ++ name = &de->d_name; ++ assert("nikita-1129", name != NULL); ++ ++ /* dentry private data don't require lock, because dentry ++ manipulations are protected by i_mutex on parent. ++ ++ This is not so for inodes, because there is no -the- parent in ++ inode case. ++ */ ++ fsdata = reiser4_get_dentry_fsdata(de); ++ if (IS_ERR(fsdata)) ++ return PTR_ERR(fsdata); ++ dec = &fsdata->dec; ++ ++ coord = &dec->entry_coord; ++ coord_clear_iplug(coord); ++ seal = &dec->entry_seal; ++ /* compose key of directory entry for @name */ ++ inode_dir_plugin(dir)->build_entry_key(dir, name, &entry->key); ++ ++ if (reiser4_seal_is_set(seal)) { ++ /* check seal */ ++ result = reiser4_seal_validate(seal, coord, &entry->key, ++ lh, mode, ZNODE_LOCK_LOPRI); ++ if (result == 0) { ++ /* key was found. Check that it is really item we are ++ looking for. */ ++ result = check_entry(dir, coord, name); ++ if (result == 0) ++ return 0; ++ } ++ } ++ flags = (mode == ZNODE_WRITE_LOCK) ? CBK_FOR_INSERT : 0; ++ /* ++ * find place in the tree where directory item should be located. ++ */ ++ result = reiser4_object_lookup(dir, &entry->key, coord, lh, mode, ++ FIND_EXACT, LEAF_LEVEL, LEAF_LEVEL, ++ flags, NULL/*ra_info */); ++ if (result == CBK_COORD_FOUND) { ++ struct entry_actor_args arg; ++ ++ /* fast path: no hash collisions */ ++ result = check_entry(dir, coord, name); ++ if (result == 0) { ++ reiser4_seal_init(seal, coord, &entry->key); ++ dec->pos = 0; ++ } else if (result > 0) { ++ /* Iterate through all units with the same keys. */ ++ arg.name = name->name; ++ arg.key = &entry->key; ++ arg.not_found = 0; ++ arg.non_uniq = 0; ++#if REISER4_USE_COLLISION_LIMIT ++ arg.max_non_uniq = max_hash_collisions(dir); ++ assert("nikita-2851", arg.max_non_uniq > 1); ++#endif ++ arg.mode = mode; ++ arg.inode = dir; ++ coord_init_zero(&arg.last_coord); ++ init_lh(&arg.last_lh); ++ ++ result = reiser4_iterate_tree ++ (reiser4_tree_by_inode(dir), ++ coord, lh, ++ entry_actor, &arg, mode, 1); ++ /* if end of the tree or extent was reached during ++ scanning. */ ++ if (arg.not_found || (result == -E_NO_NEIGHBOR)) { ++ /* step back */ ++ done_lh(lh); ++ ++ result = zload(arg.last_coord.node); ++ if (result == 0) { ++ coord_clear_iplug(&arg.last_coord); ++ coord_dup(coord, &arg.last_coord); ++ move_lh(lh, &arg.last_lh); ++ result = RETERR(-ENOENT); ++ zrelse(arg.last_coord.node); ++ --arg.non_uniq; ++ } ++ } ++ ++ done_lh(&arg.last_lh); ++ if (result == 0) ++ reiser4_seal_init(seal, coord, &entry->key); ++ ++ if (result == 0 || result == -ENOENT) { ++ assert("nikita-2580", arg.non_uniq > 0); ++ dec->pos = arg.non_uniq - 1; ++ } ++ } ++ } else ++ dec->pos = -1; ++ return result; ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/disk_format/disk_format40.c linux-2.6.30/fs/reiser4/plugin/disk_format/disk_format40.c +--- linux-2.6.30.orig/fs/reiser4/plugin/disk_format/disk_format40.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/disk_format/disk_format40.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,655 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "../../debug.h" ++#include "../../dformat.h" ++#include "../../key.h" ++#include "../node/node.h" ++#include "../space/space_allocator.h" ++#include "disk_format40.h" ++#include "../plugin.h" ++#include "../../txnmgr.h" ++#include "../../jnode.h" ++#include "../../tree.h" ++#include "../../super.h" ++#include "../../wander.h" ++#include "../../inode.h" ++#include "../../ktxnmgrd.h" ++#include "../../status_flags.h" ++ ++#include <linux/types.h> /* for __u?? */ ++#include <linux/fs.h> /* for struct super_block */ ++#include <linux/buffer_head.h> ++ ++/* reiser 4.0 default disk layout */ ++ ++/* Amount of free blocks needed to perform release_format40 when fs gets ++ mounted RW: 1 for SB, 1 for non-leaves in overwrite set, 2 for tx header ++ & tx record. */ ++#define RELEASE_RESERVED 4 ++ ++/* The greatest supported format40 version number */ ++#define FORMAT40_VERSION PLUGIN_LIBRARY_VERSION ++ ++/* This flag indicates that backup should be updated ++ (the update is performed by fsck) */ ++#define FORMAT40_UPDATE_BACKUP (1 << 31) ++ ++/* functions to access fields of format40_disk_super_block */ ++static __u64 get_format40_block_count(const format40_disk_super_block * sb) ++{ ++ return le64_to_cpu(get_unaligned(&sb->block_count)); ++} ++ ++static __u64 get_format40_free_blocks(const format40_disk_super_block * sb) ++{ ++ return le64_to_cpu(get_unaligned(&sb->free_blocks)); ++} ++ ++static __u64 get_format40_root_block(const format40_disk_super_block * sb) ++{ ++ return le64_to_cpu(get_unaligned(&sb->root_block)); ++} ++ ++static __u16 get_format40_tree_height(const format40_disk_super_block * sb) ++{ ++ return le16_to_cpu(get_unaligned(&sb->tree_height)); ++} ++ ++static __u64 get_format40_file_count(const format40_disk_super_block * sb) ++{ ++ return le64_to_cpu(get_unaligned(&sb->file_count)); ++} ++ ++static __u64 get_format40_oid(const format40_disk_super_block * sb) ++{ ++ return le64_to_cpu(get_unaligned(&sb->oid)); ++} ++ ++static __u32 get_format40_mkfs_id(const format40_disk_super_block * sb) ++{ ++ return le32_to_cpu(get_unaligned(&sb->mkfs_id)); ++} ++ ++static __u64 get_format40_flags(const format40_disk_super_block * sb) ++{ ++ return le64_to_cpu(get_unaligned(&sb->flags)); ++} ++ ++static __u32 get_format40_version(const format40_disk_super_block * sb) ++{ ++ return le32_to_cpu(get_unaligned(&sb->version)) & ++ ~FORMAT40_UPDATE_BACKUP; ++} ++ ++static int update_backup_version(const format40_disk_super_block * sb) ++{ ++ return (le32_to_cpu(get_unaligned(&sb->version)) & ++ FORMAT40_UPDATE_BACKUP); ++} ++ ++static int update_disk_version(const format40_disk_super_block * sb) ++{ ++ return (get_format40_version(sb) < FORMAT40_VERSION); ++} ++ ++static int incomplete_compatibility(const format40_disk_super_block * sb) ++{ ++ return (get_format40_version(sb) > FORMAT40_VERSION); ++} ++ ++static format40_super_info *get_sb_info(struct super_block *super) ++{ ++ return &get_super_private(super)->u.format40; ++} ++ ++static int consult_diskmap(struct super_block *s) ++{ ++ format40_super_info *info; ++ journal_location *jloc; ++ ++ info = get_sb_info(s); ++ jloc = &get_super_private(s)->jloc; ++ /* Default format-specific locations, if there is nothing in ++ * diskmap */ ++ jloc->footer = FORMAT40_JOURNAL_FOOTER_BLOCKNR; ++ jloc->header = FORMAT40_JOURNAL_HEADER_BLOCKNR; ++ info->loc.super = FORMAT40_OFFSET / s->s_blocksize; ++#ifdef CONFIG_REISER4_BADBLOCKS ++ reiser4_get_diskmap_value(FORMAT40_PLUGIN_DISKMAP_ID, FORMAT40_JF, ++ &jloc->footer); ++ reiser4_get_diskmap_value(FORMAT40_PLUGIN_DISKMAP_ID, FORMAT40_JH, ++ &jloc->header); ++ reiser4_get_diskmap_value(FORMAT40_PLUGIN_DISKMAP_ID, FORMAT40_SUPER, ++ &info->loc.super); ++#endif ++ return 0; ++} ++ ++/* find any valid super block of disk_format40 (even if the first ++ super block is destroyed), will change block numbers of actual journal header/footer (jf/jh) ++ if needed */ ++static struct buffer_head *find_a_disk_format40_super_block(struct super_block ++ *s) ++{ ++ struct buffer_head *super_bh; ++ format40_disk_super_block *disk_sb; ++ format40_super_info *info; ++ ++ assert("umka-487", s != NULL); ++ ++ info = get_sb_info(s); ++ ++ super_bh = sb_bread(s, info->loc.super); ++ if (super_bh == NULL) ++ return ERR_PTR(RETERR(-EIO)); ++ ++ disk_sb = (format40_disk_super_block *) super_bh->b_data; ++ if (strncmp(disk_sb->magic, FORMAT40_MAGIC, sizeof(FORMAT40_MAGIC))) { ++ brelse(super_bh); ++ return ERR_PTR(RETERR(-EINVAL)); ++ } ++ ++ reiser4_set_block_count(s, le64_to_cpu(get_unaligned(&disk_sb->block_count))); ++ reiser4_set_data_blocks(s, le64_to_cpu(get_unaligned(&disk_sb->block_count)) - ++ le64_to_cpu(get_unaligned(&disk_sb->free_blocks))); ++ reiser4_set_free_blocks(s, le64_to_cpu(get_unaligned(&disk_sb->free_blocks))); ++ ++ return super_bh; ++} ++ ++/* find the most recent version of super block. This is called after journal is ++ replayed */ ++static struct buffer_head *read_super_block(struct super_block *s UNUSED_ARG) ++{ ++ /* Here the most recent superblock copy has to be read. However, as ++ journal replay isn't complete, we are using ++ find_a_disk_format40_super_block() function. */ ++ return find_a_disk_format40_super_block(s); ++} ++ ++static int get_super_jnode(struct super_block *s) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(s); ++ jnode *sb_jnode; ++ int ret; ++ ++ sb_jnode = reiser4_alloc_io_head(&get_sb_info(s)->loc.super); ++ ++ ret = jload(sb_jnode); ++ ++ if (ret) { ++ reiser4_drop_io_head(sb_jnode); ++ return ret; ++ } ++ ++ pin_jnode_data(sb_jnode); ++ jrelse(sb_jnode); ++ ++ sbinfo->u.format40.sb_jnode = sb_jnode; ++ ++ return 0; ++} ++ ++static void done_super_jnode(struct super_block *s) ++{ ++ jnode *sb_jnode = get_super_private(s)->u.format40.sb_jnode; ++ ++ if (sb_jnode) { ++ unpin_jnode_data(sb_jnode); ++ reiser4_drop_io_head(sb_jnode); ++ } ++} ++ ++typedef enum format40_init_stage { ++ NONE_DONE = 0, ++ CONSULT_DISKMAP, ++ FIND_A_SUPER, ++ INIT_JOURNAL_INFO, ++ INIT_STATUS, ++ JOURNAL_REPLAY, ++ READ_SUPER, ++ KEY_CHECK, ++ INIT_OID, ++ INIT_TREE, ++ JOURNAL_RECOVER, ++ INIT_SA, ++ INIT_JNODE, ++ ALL_DONE ++} format40_init_stage; ++ ++static format40_disk_super_block *copy_sb(const struct buffer_head *super_bh) ++{ ++ format40_disk_super_block *sb_copy; ++ ++ sb_copy = kmalloc(sizeof(format40_disk_super_block), ++ reiser4_ctx_gfp_mask_get()); ++ if (sb_copy == NULL) ++ return ERR_PTR(RETERR(-ENOMEM)); ++ memcpy(sb_copy, ((format40_disk_super_block *) super_bh->b_data), ++ sizeof(format40_disk_super_block)); ++ return sb_copy; ++} ++ ++static int check_key_format(const format40_disk_super_block *sb_copy) ++{ ++ if (!equi(REISER4_LARGE_KEY, ++ get_format40_flags(sb_copy) & (1 << FORMAT40_LARGE_KEYS))) { ++ warning("nikita-3228", "Key format mismatch. " ++ "Only %s keys are supported.", ++ REISER4_LARGE_KEY ? "large" : "small"); ++ return RETERR(-EINVAL); ++ } ++ return 0; ++} ++ ++/** ++ * try_init_format40 ++ * @super: ++ * @stage: ++ * ++ */ ++static int try_init_format40(struct super_block *super, ++ format40_init_stage *stage) ++{ ++ int result; ++ struct buffer_head *super_bh; ++ reiser4_super_info_data *sbinfo; ++ format40_disk_super_block *sb_copy; ++ tree_level height; ++ reiser4_block_nr root_block; ++ node_plugin *nplug; ++ ++ assert("vs-475", super != NULL); ++ assert("vs-474", get_super_private(super)); ++ ++ *stage = NONE_DONE; ++ ++ result = consult_diskmap(super); ++ if (result) ++ return result; ++ *stage = CONSULT_DISKMAP; ++ ++ super_bh = find_a_disk_format40_super_block(super); ++ if (IS_ERR(super_bh)) ++ return PTR_ERR(super_bh); ++ brelse(super_bh); ++ *stage = FIND_A_SUPER; ++ ++ /* ok, we are sure that filesystem format is a format40 format */ ++ ++ /* map jnodes for journal control blocks (header, footer) to disk */ ++ result = reiser4_init_journal_info(super); ++ if (result) ++ return result; ++ *stage = INIT_JOURNAL_INFO; ++ ++ /* ok, we are sure that filesystem format is a format40 format */ ++ /* Now check it's state */ ++ result = reiser4_status_init(FORMAT40_STATUS_BLOCKNR); ++ if (result != 0 && result != -EINVAL) ++ /* -EINVAL means there is no magic, so probably just old ++ * fs. */ ++ return result; ++ *stage = INIT_STATUS; ++ ++ result = reiser4_status_query(NULL, NULL); ++ if (result == REISER4_STATUS_MOUNT_WARN) ++ notice("vpf-1363", "Warning: mounting %s with errors.", ++ super->s_id); ++ if (result == REISER4_STATUS_MOUNT_RO) ++ notice("vpf-1364", "Warning: mounting %s with fatal errors," ++ " forcing read-only mount.", super->s_id); ++ result = reiser4_journal_replay(super); ++ if (result) ++ return result; ++ *stage = JOURNAL_REPLAY; ++ ++ super_bh = read_super_block(super); ++ if (IS_ERR(super_bh)) ++ return PTR_ERR(super_bh); ++ *stage = READ_SUPER; ++ ++ /* allocate and make a copy of format40_disk_super_block */ ++ sb_copy = copy_sb(super_bh); ++ brelse(super_bh); ++ ++ if (IS_ERR(sb_copy)) ++ return PTR_ERR(sb_copy); ++ printk("reiser4: %s: found disk format 4.0.%u.\n", ++ super->s_id, ++ get_format40_version(sb_copy)); ++ if (incomplete_compatibility(sb_copy)) ++ printk("reiser4: Warning: The last completely supported " ++ "version of disk format40 is %u. Some objects of " ++ "the semantic tree can be unaccessible.\n", ++ FORMAT40_VERSION); ++ /* make sure that key format of kernel and filesystem match */ ++ result = check_key_format(sb_copy); ++ if (result) { ++ kfree(sb_copy); ++ return result; ++ } ++ *stage = KEY_CHECK; ++ ++ result = oid_init_allocator(super, get_format40_file_count(sb_copy), ++ get_format40_oid(sb_copy)); ++ if (result) { ++ kfree(sb_copy); ++ return result; ++ } ++ *stage = INIT_OID; ++ ++ /* get things necessary to init reiser4_tree */ ++ root_block = get_format40_root_block(sb_copy); ++ height = get_format40_tree_height(sb_copy); ++ nplug = node_plugin_by_id(NODE40_ID); ++ ++ /* initialize reiser4_super_info_data */ ++ sbinfo = get_super_private(super); ++ assert("", sbinfo->tree.super == super); ++ /* init reiser4_tree for the filesystem */ ++ result = reiser4_init_tree(&sbinfo->tree, &root_block, height, nplug); ++ if (result) { ++ kfree(sb_copy); ++ return result; ++ } ++ *stage = INIT_TREE; ++ ++ /* ++ * initialize reiser4_super_info_data with data from format40 super ++ * block ++ */ ++ sbinfo->default_uid = 0; ++ sbinfo->default_gid = 0; ++ sbinfo->mkfs_id = get_format40_mkfs_id(sb_copy); ++ /* number of blocks in filesystem and reserved space */ ++ reiser4_set_block_count(super, get_format40_block_count(sb_copy)); ++ sbinfo->blocks_free = get_format40_free_blocks(sb_copy); ++ sbinfo->version = get_format40_version(sb_copy); ++ kfree(sb_copy); ++ ++ if (update_backup_version(sb_copy)) ++ printk("reiser4: Warning: metadata backup is not updated. " ++ "Please run 'fsck.reiser4 --fix' on %s.\n", ++ super->s_id); ++ ++ sbinfo->fsuid = 0; ++ sbinfo->fs_flags |= (1 << REISER4_ADG); /* hard links for directories ++ * are not supported */ ++ sbinfo->fs_flags |= (1 << REISER4_ONE_NODE_PLUGIN); /* all nodes in ++ * layout 40 are ++ * of one ++ * plugin */ ++ /* sbinfo->tmgr is initialized already */ ++ ++ /* recover sb data which were logged separately from sb block */ ++ ++ /* NOTE-NIKITA: reiser4_journal_recover_sb_data() calls ++ * oid_init_allocator() and reiser4_set_free_blocks() with new ++ * data. What's the reason to call them above? */ ++ result = reiser4_journal_recover_sb_data(super); ++ if (result != 0) ++ return result; ++ *stage = JOURNAL_RECOVER; ++ ++ /* ++ * Set number of used blocks. The number of used blocks is not stored ++ * neither in on-disk super block nor in the journal footer blocks. At ++ * this moment actual values of total blocks and free block counters ++ * are set in the reiser4 super block (in-memory structure) and we can ++ * calculate number of used blocks from them. ++ */ ++ reiser4_set_data_blocks(super, ++ reiser4_block_count(super) - ++ reiser4_free_blocks(super)); ++ ++#if REISER4_DEBUG ++ sbinfo->min_blocks_used = 16 /* reserved area */ + ++ 2 /* super blocks */ + ++ 2 /* journal footer and header */ ; ++#endif ++ ++ /* init disk space allocator */ ++ result = sa_init_allocator(reiser4_get_space_allocator(super), ++ super, NULL); ++ if (result) ++ return result; ++ *stage = INIT_SA; ++ ++ result = get_super_jnode(super); ++ if (result == 0) ++ *stage = ALL_DONE; ++ return result; ++} ++ ++/* plugin->u.format.get_ready */ ++int init_format_format40(struct super_block *s, void *data UNUSED_ARG) ++{ ++ int result; ++ format40_init_stage stage; ++ ++ result = try_init_format40(s, &stage); ++ switch (stage) { ++ case ALL_DONE: ++ assert("nikita-3458", result == 0); ++ break; ++ case INIT_JNODE: ++ done_super_jnode(s); ++ case INIT_SA: ++ sa_destroy_allocator(reiser4_get_space_allocator(s), s); ++ case JOURNAL_RECOVER: ++ case INIT_TREE: ++ reiser4_done_tree(&get_super_private(s)->tree); ++ case INIT_OID: ++ case KEY_CHECK: ++ case READ_SUPER: ++ case JOURNAL_REPLAY: ++ case INIT_STATUS: ++ reiser4_status_finish(); ++ case INIT_JOURNAL_INFO: ++ reiser4_done_journal_info(s); ++ case FIND_A_SUPER: ++ case CONSULT_DISKMAP: ++ case NONE_DONE: ++ break; ++ default: ++ impossible("nikita-3457", "init stage: %i", stage); ++ } ++ ++ if (!rofs_super(s) && reiser4_free_blocks(s) < RELEASE_RESERVED) ++ return RETERR(-ENOSPC); ++ ++ return result; ++} ++ ++static void pack_format40_super(const struct super_block *s, char *data) ++{ ++ format40_disk_super_block *super_data = ++ (format40_disk_super_block *) data; ++ ++ reiser4_super_info_data *sbinfo = get_super_private(s); ++ ++ assert("zam-591", data != NULL); ++ ++ put_unaligned(cpu_to_le64(reiser4_free_committed_blocks(s)), ++ &super_data->free_blocks); ++ ++ put_unaligned(cpu_to_le64(sbinfo->tree.root_block), ++ &super_data->root_block); ++ ++ put_unaligned(cpu_to_le64(oid_next(s)), ++ &super_data->oid); ++ ++ put_unaligned(cpu_to_le64(oids_used(s)), ++ &super_data->file_count); ++ ++ put_unaligned(cpu_to_le16(sbinfo->tree.height), ++ &super_data->tree_height); ++ ++ if (update_disk_version(super_data)) { ++ __u32 version = FORMAT40_VERSION | FORMAT40_UPDATE_BACKUP; ++ ++ put_unaligned(cpu_to_le32(version), &super_data->version); ++ } ++} ++ ++/* plugin->u.format.log_super ++ return a jnode which should be added to transaction when the super block ++ gets logged */ ++jnode *log_super_format40(struct super_block *s) ++{ ++ jnode *sb_jnode; ++ ++ sb_jnode = get_super_private(s)->u.format40.sb_jnode; ++ ++ jload(sb_jnode); ++ ++ pack_format40_super(s, jdata(sb_jnode)); ++ ++ jrelse(sb_jnode); ++ ++ return sb_jnode; ++} ++ ++/* plugin->u.format.release */ ++int release_format40(struct super_block *s) ++{ ++ int ret; ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = get_super_private(s); ++ assert("zam-579", sbinfo != NULL); ++ ++ if (!rofs_super(s)) { ++ ret = reiser4_capture_super_block(s); ++ if (ret != 0) ++ warning("vs-898", ++ "reiser4_capture_super_block failed: %d", ++ ret); ++ ++ ret = txnmgr_force_commit_all(s, 1); ++ if (ret != 0) ++ warning("jmacd-74438", "txn_force failed: %d", ret); ++ ++ all_grabbed2free(); ++ } ++ ++ sa_destroy_allocator(&sbinfo->space_allocator, s); ++ reiser4_done_journal_info(s); ++ done_super_jnode(s); ++ ++ rcu_barrier(); ++ reiser4_done_tree(&sbinfo->tree); ++ /* call finish_rcu(), because some znode were "released" in ++ * reiser4_done_tree(). */ ++ rcu_barrier(); ++ ++ return 0; ++} ++ ++#define FORMAT40_ROOT_LOCALITY 41 ++#define FORMAT40_ROOT_OBJECTID 42 ++ ++/* plugin->u.format.root_dir_key */ ++const reiser4_key *root_dir_key_format40(const struct super_block *super ++ UNUSED_ARG) ++{ ++ static const reiser4_key FORMAT40_ROOT_DIR_KEY = { ++ .el = { ++ __constant_cpu_to_le64((FORMAT40_ROOT_LOCALITY << 4) | KEY_SD_MINOR), ++#if REISER4_LARGE_KEY ++ ON_LARGE_KEY(0ull,) ++#endif ++ __constant_cpu_to_le64(FORMAT40_ROOT_OBJECTID), ++ 0ull ++ } ++ }; ++ ++ return &FORMAT40_ROOT_DIR_KEY; ++} ++ ++/* plugin->u.format.check_open. ++ Check the opened object for validness. For now it checks for the valid oid & ++ locality only, can be improved later and it its work may depend on the mount ++ options. */ ++int check_open_format40(const struct inode *object) ++{ ++ oid_t max, oid; ++ ++ max = oid_next(object->i_sb) - 1; ++ ++ /* Check the oid. */ ++ oid = get_inode_oid(object); ++ if (oid > max) { ++ warning("vpf-1360", "The object with the oid %llu " ++ "greater then the max used oid %llu found.", ++ (unsigned long long)oid, (unsigned long long)max); ++ ++ return RETERR(-EIO); ++ } ++ ++ /* Check the locality. */ ++ oid = reiser4_inode_data(object)->locality_id; ++ if (oid > max) { ++ warning("vpf-1361", "The object with the locality %llu " ++ "greater then the max used oid %llu found.", ++ (unsigned long long)oid, (unsigned long long)max); ++ ++ return RETERR(-EIO); ++ } ++ ++ return 0; ++} ++ ++/* plugin->u.format.version_update. ++ Perform all version update operations from the on-disk ++ format40_disk_super_block.version on disk to FORMAT40_VERSION. ++ */ ++int version_update_format40(struct super_block *super) { ++ txn_handle * trans; ++ lock_handle lh; ++ txn_atom *atom; ++ int ret; ++ ++ /* Nothing to do if RO mount or the on-disk version is not less. */ ++ if (super->s_flags & MS_RDONLY) ++ return 0; ++ ++ if (get_super_private(super)->version >= FORMAT40_VERSION) ++ return 0; ++ ++ printk("reiser4: Updating disk format to 4.0.%u. The reiser4 metadata " ++ "backup is left unchanged. Please run 'fsck.reiser4 --fix' " ++ "on %s to update it too.\n", FORMAT40_VERSION, super->s_id); ++ ++ /* Mark the uber znode dirty to call log_super on write_logs. */ ++ init_lh(&lh); ++ ret = get_uber_znode(reiser4_get_tree(super), ZNODE_WRITE_LOCK, ++ ZNODE_LOCK_HIPRI, &lh); ++ if (ret != 0) ++ return ret; ++ ++ znode_make_dirty(lh.node); ++ done_lh(&lh); ++ ++ /* Update the backup blocks. */ ++ ++ /* Force write_logs immediately. */ ++ trans = get_current_context()->trans; ++ atom = get_current_atom_locked(); ++ assert("vpf-1906", atom != NULL); ++ ++ spin_lock_txnh(trans); ++ return force_commit_atom(trans); ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/disk_format/disk_format40.h linux-2.6.30/fs/reiser4/plugin/disk_format/disk_format40.h +--- linux-2.6.30.orig/fs/reiser4/plugin/disk_format/disk_format40.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/disk_format/disk_format40.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,109 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* this file contains: ++ - definition of ondisk super block of standart disk layout for ++ reiser 4.0 (layout 40) ++ - definition of layout 40 specific portion of in-core super block ++ - declarations of functions implementing methods of layout plugin ++ for layout 40 ++ - declarations of functions used to get/set fields in layout 40 super block ++*/ ++ ++#ifndef __DISK_FORMAT40_H__ ++#define __DISK_FORMAT40_H__ ++ ++/* magic for default reiser4 layout */ ++#define FORMAT40_MAGIC "ReIsEr40FoRmAt" ++#define FORMAT40_OFFSET (REISER4_MASTER_OFFSET + PAGE_CACHE_SIZE) ++ ++#include "../../dformat.h" ++ ++#include <linux/fs.h> /* for struct super_block */ ++ ++typedef enum { ++ FORMAT40_LARGE_KEYS ++} format40_flags; ++ ++/* ondisk super block for format 40. It is 512 bytes long */ ++typedef struct format40_disk_super_block { ++ /* 0 */ d64 block_count; ++ /* number of block in a filesystem */ ++ /* 8 */ d64 free_blocks; ++ /* number of free blocks */ ++ /* 16 */ d64 root_block; ++ /* filesystem tree root block */ ++ /* 24 */ d64 oid; ++ /* smallest free objectid */ ++ /* 32 */ d64 file_count; ++ /* number of files in a filesystem */ ++ /* 40 */ d64 flushes; ++ /* number of times super block was ++ flushed. Needed if format 40 ++ will have few super blocks */ ++ /* 48 */ d32 mkfs_id; ++ /* unique identifier of fs */ ++ /* 52 */ char magic[16]; ++ /* magic string ReIsEr40FoRmAt */ ++ /* 68 */ d16 tree_height; ++ /* height of filesystem tree */ ++ /* 70 */ d16 formatting_policy; ++ /* not used anymore */ ++ /* 72 */ d64 flags; ++ /* 80 */ d32 version; ++ /* on-disk format version number ++ initially assigned by mkfs as the greatest format40 ++ version number supported by reiser4progs and updated ++ in mount time in accordance with the greatest format40 ++ version number supported by kernel. ++ Is used by fsck to catch possible corruption and ++ for various compatibility issues */ ++ /* 84 */ char not_used[428]; ++} format40_disk_super_block; ++ ++/* format 40 specific part of reiser4_super_info_data */ ++typedef struct format40_super_info { ++/* format40_disk_super_block actual_sb; */ ++ jnode *sb_jnode; ++ struct { ++ reiser4_block_nr super; ++ } loc; ++} format40_super_info; ++ ++/* Defines for journal header and footer respectively. */ ++#define FORMAT40_JOURNAL_HEADER_BLOCKNR \ ++ ((REISER4_MASTER_OFFSET / PAGE_CACHE_SIZE) + 3) ++ ++#define FORMAT40_JOURNAL_FOOTER_BLOCKNR \ ++ ((REISER4_MASTER_OFFSET / PAGE_CACHE_SIZE) + 4) ++ ++#define FORMAT40_STATUS_BLOCKNR \ ++ ((REISER4_MASTER_OFFSET / PAGE_CACHE_SIZE) + 5) ++ ++/* Diskmap declarations */ ++#define FORMAT40_PLUGIN_DISKMAP_ID ((REISER4_FORMAT_PLUGIN_TYPE<<16) | (FORMAT40_ID)) ++#define FORMAT40_SUPER 1 ++#define FORMAT40_JH 2 ++#define FORMAT40_JF 3 ++ ++/* declarations of functions implementing methods of layout plugin for ++ format 40. The functions theirself are in disk_format40.c */ ++extern int init_format_format40(struct super_block *, void *data); ++extern const reiser4_key *root_dir_key_format40(const struct super_block *); ++extern int release_format40(struct super_block *s); ++extern jnode *log_super_format40(struct super_block *s); ++extern int check_open_format40(const struct inode *object); ++extern int version_update_format40(struct super_block *super); ++ ++/* __DISK_FORMAT40_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/disk_format/disk_format.c linux-2.6.30/fs/reiser4/plugin/disk_format/disk_format.c +--- linux-2.6.30.orig/fs/reiser4/plugin/disk_format/disk_format.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/disk_format/disk_format.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "../../debug.h" ++#include "../plugin_header.h" ++#include "disk_format40.h" ++#include "disk_format.h" ++#include "../plugin.h" ++ ++/* initialization of disk layout plugins */ ++disk_format_plugin format_plugins[LAST_FORMAT_ID] = { ++ [FORMAT40_ID] = { ++ .h = { ++ .type_id = REISER4_FORMAT_PLUGIN_TYPE, ++ .id = FORMAT40_ID, ++ .pops = NULL, ++ .label = "reiser40", ++ .desc = "standard disk layout for reiser40", ++ .linkage = {NULL, NULL} ++ }, ++ .init_format = init_format_format40, ++ .root_dir_key = root_dir_key_format40, ++ .release = release_format40, ++ .log_super = log_super_format40, ++ .check_open = check_open_format40, ++ .version_update = version_update_format40 ++ } ++}; ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/disk_format/disk_format.h linux-2.6.30/fs/reiser4/plugin/disk_format/disk_format.h +--- linux-2.6.30.orig/fs/reiser4/plugin/disk_format/disk_format.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/disk_format/disk_format.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,27 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* identifiers for disk layouts, they are also used as indexes in array of disk ++ plugins */ ++ ++#if !defined( __REISER4_DISK_FORMAT_H__ ) ++#define __REISER4_DISK_FORMAT_H__ ++ ++typedef enum { ++ /* standard reiser4 disk layout plugin id */ ++ FORMAT40_ID, ++ LAST_FORMAT_ID ++} disk_format_id; ++ ++/* __REISER4_DISK_FORMAT_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/disk_format/Makefile linux-2.6.30/fs/reiser4/plugin/disk_format/Makefile +--- linux-2.6.30.orig/fs/reiser4/plugin/disk_format/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/disk_format/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,5 @@ ++obj-$(CONFIG_REISER4_FS) += df_plugins.o ++ ++df_plugins-objs := \ ++ disk_format40.o \ ++ disk_format.o +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/fibration.c linux-2.6.30/fs/reiser4/plugin/fibration.c +--- linux-2.6.30.orig/fs/reiser4/plugin/fibration.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/fibration.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,175 @@ ++/* Copyright 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Directory fibrations */ ++ ++/* ++ * Suppose we have a directory tree with sources of some project. During ++ * compilation .o files are created within this tree. This makes access ++ * to the original source files less efficient, because source files are ++ * now "diluted" by object files: default directory plugin uses prefix ++ * of a file name as a part of the key for directory entry (and this ++ * part is also inherited by the key of file body). This means that ++ * foo.o will be located close to foo.c and foo.h in the tree. ++ * ++ * To avoid this effect directory plugin fill highest 7 (unused ++ * originally) bits of the second component of the directory entry key ++ * by bit-pattern depending on the file name (see ++ * fs/reiser4/kassign.c:build_entry_key_common()). These bits are called ++ * "fibre". Fibre of the file name key is inherited by key of stat data ++ * and keys of file body (in the case of REISER4_LARGE_KEY). ++ * ++ * Fibre for a given file is chosen by per-directory fibration ++ * plugin. Names within given fibre are ordered lexicographically. ++ */ ++ ++#include "../debug.h" ++#include "plugin_header.h" ++#include "plugin.h" ++#include "../super.h" ++#include "../inode.h" ++ ++#include <linux/types.h> ++ ++static const int fibre_shift = 57; ++ ++#define FIBRE_NO(n) (((__u64)(n)) << fibre_shift) ++ ++/* ++ * Trivial fibration: all files of directory are just ordered ++ * lexicographically. ++ */ ++static __u64 fibre_trivial(const struct inode *dir, const char *name, int len) ++{ ++ return FIBRE_NO(0); ++} ++ ++/* ++ * dot-o fibration: place .o files after all others. ++ */ ++static __u64 fibre_dot_o(const struct inode *dir, const char *name, int len) ++{ ++ /* special treatment for .*.o */ ++ if (len > 2 && name[len - 1] == 'o' && name[len - 2] == '.') ++ return FIBRE_NO(1); ++ else ++ return FIBRE_NO(0); ++} ++ ++/* ++ * ext.1 fibration: subdivide directory into 128 fibrations one for each ++ * 7bit extension character (file "foo.h" goes into fibre "h"), plus ++ * default fibre for the rest. ++ */ ++static __u64 fibre_ext_1(const struct inode *dir, const char *name, int len) ++{ ++ if (len > 2 && name[len - 2] == '.') ++ return FIBRE_NO(name[len - 1]); ++ else ++ return FIBRE_NO(0); ++} ++ ++/* ++ * ext.3 fibration: try to separate files with different 3-character ++ * extensions from each other. ++ */ ++static __u64 fibre_ext_3(const struct inode *dir, const char *name, int len) ++{ ++ if (len > 4 && name[len - 4] == '.') ++ return FIBRE_NO(name[len - 3] + name[len - 2] + name[len - 1]); ++ else ++ return FIBRE_NO(0); ++} ++ ++static int change_fibration(struct inode *inode, ++ reiser4_plugin * plugin, ++ pset_member memb) ++{ ++ int result; ++ ++ assert("nikita-3503", inode != NULL); ++ assert("nikita-3504", plugin != NULL); ++ ++ assert("nikita-3505", is_reiser4_inode(inode)); ++ assert("nikita-3506", inode_dir_plugin(inode) != NULL); ++ assert("nikita-3507", ++ plugin->h.type_id == REISER4_FIBRATION_PLUGIN_TYPE); ++ ++ result = 0; ++ if (inode_fibration_plugin(inode) == NULL || ++ inode_fibration_plugin(inode)->h.id != plugin->h.id) { ++ if (is_dir_empty(inode) == 0) ++ result = aset_set_unsafe(&reiser4_inode_data(inode)->pset, ++ PSET_FIBRATION, plugin); ++ else ++ result = RETERR(-ENOTEMPTY); ++ ++ } ++ return result; ++} ++ ++static reiser4_plugin_ops fibration_plugin_ops = { ++ .init = NULL, ++ .load = NULL, ++ .save_len = NULL, ++ .save = NULL, ++ .change = change_fibration ++}; ++ ++/* fibration plugins */ ++fibration_plugin fibration_plugins[LAST_FIBRATION_ID] = { ++ [FIBRATION_LEXICOGRAPHIC] = { ++ .h = { ++ .type_id = REISER4_FIBRATION_PLUGIN_TYPE, ++ .id = FIBRATION_LEXICOGRAPHIC, ++ .pops = &fibration_plugin_ops, ++ .label = "lexicographic", ++ .desc = "no fibration", ++ .linkage = {NULL, NULL} ++ }, ++ .fibre = fibre_trivial ++ }, ++ [FIBRATION_DOT_O] = { ++ .h = { ++ .type_id = REISER4_FIBRATION_PLUGIN_TYPE, ++ .id = FIBRATION_DOT_O, ++ .pops = &fibration_plugin_ops, ++ .label = "dot-o", ++ .desc = "fibrate .o files separately", ++ .linkage = {NULL, NULL} ++ }, ++ .fibre = fibre_dot_o ++ }, ++ [FIBRATION_EXT_1] = { ++ .h = { ++ .type_id = REISER4_FIBRATION_PLUGIN_TYPE, ++ .id = FIBRATION_EXT_1, ++ .pops = &fibration_plugin_ops, ++ .label = "ext-1", ++ .desc = "fibrate file by single character extension", ++ .linkage = {NULL, NULL} ++ }, ++ .fibre = fibre_ext_1 ++ }, ++ [FIBRATION_EXT_3] = { ++ .h = { ++ .type_id = REISER4_FIBRATION_PLUGIN_TYPE, ++ .id = FIBRATION_EXT_3, ++ .pops = &fibration_plugin_ops, ++ .label = "ext-3", ++ .desc = "fibrate file by three character extension", ++ .linkage = {NULL, NULL} ++ }, ++ .fibre = fibre_ext_3 ++ } ++}; ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/fibration.h linux-2.6.30/fs/reiser4/plugin/fibration.h +--- linux-2.6.30.orig/fs/reiser4/plugin/fibration.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/fibration.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,37 @@ ++/* Copyright 2004 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Fibration plugin used by hashed directory plugin to segment content ++ * of directory. See fs/reiser4/plugin/fibration.c for more on this. */ ++ ++#if !defined(__FS_REISER4_PLUGIN_FIBRATION_H__) ++#define __FS_REISER4_PLUGIN_FIBRATION_H__ ++ ++#include "plugin_header.h" ++ ++typedef struct fibration_plugin { ++ /* generic fields */ ++ plugin_header h; ++ ++ __u64(*fibre) (const struct inode *dir, const char *name, int len); ++} fibration_plugin; ++ ++typedef enum { ++ FIBRATION_LEXICOGRAPHIC, ++ FIBRATION_DOT_O, ++ FIBRATION_EXT_1, ++ FIBRATION_EXT_3, ++ LAST_FIBRATION_ID ++} reiser4_fibration_id; ++ ++/* __FS_REISER4_PLUGIN_FIBRATION_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file/cryptcompress.c linux-2.6.30/fs/reiser4/plugin/file/cryptcompress.c +--- linux-2.6.30.orig/fs/reiser4/plugin/file/cryptcompress.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file/cryptcompress.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,3807 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ reiser4/README */ ++/* ++ * Written by Edward Shishkin. ++ * ++ * Implementations of inode/file/address_space operations ++ * specific for cryptcompress file plugin which manages ++ * regular files built of compressed and(or) encrypted bodies. ++ * See http://dev.namesys.com/CryptcompressPlugin for details. ++ */ ++ ++#include "../../inode.h" ++#include "../cluster.h" ++#include "../object.h" ++#include "../../tree_walk.h" ++#include "cryptcompress.h" ++ ++#include <linux/pagevec.h> ++#include <asm/uaccess.h> ++#include <linux/swap.h> ++#include <linux/writeback.h> ++#include <linux/random.h> ++#include <linux/scatterlist.h> ++ ++/* ++ Managing primary and secondary caches by Reiser4 ++ cryptcompress file plugin. Synchronization scheme. ++ ++ ++ +------------------+ ++ +------------------->| tfm stream | ++ | | (compressed data)| ++ flush | +------------------+ ++ +-----------------+ | ++ |(->)longterm lock| V ++--+ writepages() | | +-***-+ reiser4 +---+ ++ | | +--+ | *** | storage tree | | ++ | | | +-***-+ (primary cache)| | ++u | write() (secondary| cache) V / | \ | | ++s | ----> +----+ +----+ +----+ +----+ +-***** ******* **----+ ----> | d | ++e | | | |page cluster | | | **disk cluster** | | i | ++r | <---- +----+ +----+ +----+ +----+ +-***** **********----+ <---- | s | ++ | read() ^ ^ | | k | ++ | | (->)longterm lock| | page_io()| | ++ | | +------+ | | ++--+ readpages() | | +---+ ++ | V ++ | +------------------+ ++ +--------------------| tfm stream | ++ | (plain text) | ++ +------------------+ ++*/ ++ ++/* get cryptcompress specific portion of inode */ ++struct cryptcompress_info *cryptcompress_inode_data(const struct inode *inode) ++{ ++ return &reiser4_inode_data(inode)->file_plugin_data.cryptcompress_info; ++} ++ ++/* plugin->u.file.init_inode_data */ ++void init_inode_data_cryptcompress(struct inode *inode, ++ reiser4_object_create_data * crd, ++ int create) ++{ ++ struct cryptcompress_info *data; ++ ++ data = cryptcompress_inode_data(inode); ++ assert("edward-685", data != NULL); ++ ++ memset(data, 0, sizeof(*data)); ++ ++ mutex_init(&data->checkin_mutex); ++ data->trunc_index = ULONG_MAX; ++ turn_on_compression(data); ++ set_lattice_factor(data, MIN_LATTICE_FACTOR); ++ init_inode_ordering(inode, crd, create); ++} ++ ++/* The following is a part of reiser4 cipher key manager ++ which is called when opening/creating a cryptcompress file */ ++ ++/* get/set cipher key info */ ++struct reiser4_crypto_info * inode_crypto_info (struct inode * inode) ++{ ++ assert("edward-90", inode != NULL); ++ assert("edward-91", reiser4_inode_data(inode) != NULL); ++ return cryptcompress_inode_data(inode)->crypt; ++} ++ ++static void set_inode_crypto_info (struct inode * inode, ++ struct reiser4_crypto_info * info) ++{ ++ cryptcompress_inode_data(inode)->crypt = info; ++} ++ ++/* allocate a cipher key info */ ++struct reiser4_crypto_info * reiser4_alloc_crypto_info (struct inode * inode) ++{ ++ struct reiser4_crypto_info *info; ++ int fipsize; ++ ++ info = kzalloc(sizeof(*info), reiser4_ctx_gfp_mask_get()); ++ if (!info) ++ return ERR_PTR(-ENOMEM); ++ ++ fipsize = inode_digest_plugin(inode)->fipsize; ++ info->keyid = kmalloc(fipsize, reiser4_ctx_gfp_mask_get()); ++ if (!info->keyid) { ++ kfree(info); ++ return ERR_PTR(-ENOMEM); ++ } ++ info->host = inode; ++ return info; ++} ++ ++#if 0 ++/* allocate/free low-level info for cipher and digest ++ transforms */ ++static int alloc_crypto_tfms(struct reiser4_crypto_info * info) ++{ ++ struct crypto_blkcipher * ctfm = NULL; ++ struct crypto_hash * dtfm = NULL; ++ cipher_plugin * cplug = inode_cipher_plugin(info->host); ++ digest_plugin * dplug = inode_digest_plugin(info->host); ++ ++ if (cplug->alloc) { ++ ctfm = cplug->alloc(); ++ if (IS_ERR(ctfm)) { ++ warning("edward-1364", ++ "Can not allocate info for %s\n", ++ cplug->h.desc); ++ return RETERR(PTR_ERR(ctfm)); ++ } ++ } ++ info_set_cipher(info, ctfm); ++ if (dplug->alloc) { ++ dtfm = dplug->alloc(); ++ if (IS_ERR(dtfm)) { ++ warning("edward-1365", ++ "Can not allocate info for %s\n", ++ dplug->h.desc); ++ goto unhappy_with_digest; ++ } ++ } ++ info_set_digest(info, dtfm); ++ return 0; ++ unhappy_with_digest: ++ if (cplug->free) { ++ cplug->free(ctfm); ++ info_set_cipher(info, NULL); ++ } ++ return RETERR(PTR_ERR(dtfm)); ++} ++#endif ++ ++static void ++free_crypto_tfms(struct reiser4_crypto_info * info) ++{ ++ assert("edward-1366", info != NULL); ++ if (!info_get_cipher(info)) { ++ assert("edward-1601", !info_get_digest(info)); ++ return; ++ } ++ inode_cipher_plugin(info->host)->free(info_get_cipher(info)); ++ info_set_cipher(info, NULL); ++ inode_digest_plugin(info->host)->free(info_get_digest(info)); ++ info_set_digest(info, NULL); ++ return; ++} ++ ++#if 0 ++/* create a key fingerprint for disk stat-data */ ++static int create_keyid (struct reiser4_crypto_info * info, ++ struct reiser4_crypto_data * data) ++{ ++ int ret = -ENOMEM; ++ size_t blk, pad; ++ __u8 * dmem; ++ __u8 * cmem; ++ struct hash_desc ddesc; ++ struct blkcipher_desc cdesc; ++ struct scatterlist sg; ++ ++ assert("edward-1367", info != NULL); ++ assert("edward-1368", info->keyid != NULL); ++ ++ ddesc.tfm = info_get_digest(info); ++ ddesc.flags = 0; ++ cdesc.tfm = info_get_cipher(info); ++ cdesc.flags = 0; ++ ++ dmem = kmalloc((size_t)crypto_hash_digestsize(ddesc.tfm), ++ reiser4_ctx_gfp_mask_get()); ++ if (!dmem) ++ goto exit1; ++ ++ blk = crypto_blkcipher_blocksize(cdesc.tfm); ++ ++ pad = data->keyid_size % blk; ++ pad = (pad ? blk - pad : 0); ++ ++ cmem = kmalloc((size_t)data->keyid_size + pad, ++ reiser4_ctx_gfp_mask_get()); ++ if (!cmem) ++ goto exit2; ++ memcpy(cmem, data->keyid, data->keyid_size); ++ memset(cmem + data->keyid_size, 0, pad); ++ ++ sg_init_one(&sg, cmem, data->keyid_size + pad); ++ ++ ret = crypto_blkcipher_encrypt(&cdesc, &sg, &sg, ++ data->keyid_size + pad); ++ if (ret) { ++ warning("edward-1369", ++ "encryption failed flags=%x\n", cdesc.flags); ++ goto exit3; ++ } ++ ret = crypto_hash_digest(&ddesc, &sg, sg.length, dmem); ++ if (ret) { ++ warning("edward-1602", ++ "digest failed flags=%x\n", ddesc.flags); ++ goto exit3; ++ } ++ memcpy(info->keyid, dmem, inode_digest_plugin(info->host)->fipsize); ++ exit3: ++ kfree(cmem); ++ exit2: ++ kfree(dmem); ++ exit1: ++ return ret; ++} ++#endif ++ ++static void destroy_keyid(struct reiser4_crypto_info * info) ++{ ++ assert("edward-1370", info != NULL); ++ assert("edward-1371", info->keyid != NULL); ++ kfree(info->keyid); ++ return; ++} ++ ++static void __free_crypto_info (struct inode * inode) ++{ ++ struct reiser4_crypto_info * info = inode_crypto_info(inode); ++ assert("edward-1372", info != NULL); ++ ++ free_crypto_tfms(info); ++ destroy_keyid(info); ++ kfree(info); ++} ++ ++#if 0 ++static void instantiate_crypto_info(struct reiser4_crypto_info * info) ++{ ++ assert("edward-1373", info != NULL); ++ assert("edward-1374", info->inst == 0); ++ info->inst = 1; ++} ++#endif ++ ++static void uninstantiate_crypto_info(struct reiser4_crypto_info * info) ++{ ++ assert("edward-1375", info != NULL); ++ info->inst = 0; ++} ++ ++#if 0 ++static int is_crypto_info_instantiated(struct reiser4_crypto_info * info) ++{ ++ return info->inst; ++} ++ ++static int inode_has_cipher_key(struct inode * inode) ++{ ++ assert("edward-1376", inode != NULL); ++ return inode_crypto_info(inode) && ++ is_crypto_info_instantiated(inode_crypto_info(inode)); ++} ++#endif ++ ++static void free_crypto_info (struct inode * inode) ++{ ++ uninstantiate_crypto_info(inode_crypto_info(inode)); ++ __free_crypto_info(inode); ++} ++ ++static int need_cipher(struct inode * inode) ++{ ++ return inode_cipher_plugin(inode) != ++ cipher_plugin_by_id(NONE_CIPHER_ID); ++} ++ ++/* Parse @data which contains a (uninstantiated) cipher key imported ++ from user space, create a low-level cipher info and attach it to ++ the @object. If success, then info contains an instantiated key */ ++#if 0 ++struct reiser4_crypto_info * create_crypto_info(struct inode * object, ++ struct reiser4_crypto_data * data) ++{ ++ int ret; ++ struct reiser4_crypto_info * info; ++ ++ assert("edward-1377", data != NULL); ++ assert("edward-1378", need_cipher(object)); ++ ++ if (inode_file_plugin(object) != ++ file_plugin_by_id(DIRECTORY_FILE_PLUGIN_ID)) ++ return ERR_PTR(-EINVAL); ++ ++ info = reiser4_alloc_crypto_info(object); ++ if (IS_ERR(info)) ++ return info; ++ ret = alloc_crypto_tfms(info); ++ if (ret) ++ goto err; ++ /* instantiating a key */ ++ ret = crypto_blkcipher_setkey(info_get_cipher(info), ++ data->key, ++ data->keysize); ++ if (ret) { ++ warning("edward-1379", ++ "setkey failed flags=%x", ++ crypto_blkcipher_get_flags(info_get_cipher(info))); ++ goto err; ++ } ++ info->keysize = data->keysize; ++ ret = create_keyid(info, data); ++ if (ret) ++ goto err; ++ instantiate_crypto_info(info); ++ return info; ++ err: ++ __free_crypto_info(object); ++ return ERR_PTR(ret); ++} ++#endif ++ ++/* increment/decrement a load counter when ++ attaching/detaching the crypto-stat to any object */ ++static void load_crypto_info(struct reiser4_crypto_info * info) ++{ ++ assert("edward-1380", info != NULL); ++ inc_keyload_count(info); ++} ++ ++static void unload_crypto_info(struct inode * inode) ++{ ++ struct reiser4_crypto_info * info = inode_crypto_info(inode); ++ assert("edward-1381", info->keyload_count > 0); ++ ++ dec_keyload_count(inode_crypto_info(inode)); ++ if (info->keyload_count == 0) ++ /* final release */ ++ free_crypto_info(inode); ++} ++ ++/* attach/detach an existing crypto-stat */ ++void reiser4_attach_crypto_info(struct inode * inode, ++ struct reiser4_crypto_info * info) ++{ ++ assert("edward-1382", inode != NULL); ++ assert("edward-1383", info != NULL); ++ assert("edward-1384", inode_crypto_info(inode) == NULL); ++ ++ set_inode_crypto_info(inode, info); ++ load_crypto_info(info); ++} ++ ++/* returns true, if crypto stat can be attached to the @host */ ++#if REISER4_DEBUG ++static int host_allows_crypto_info(struct inode * host) ++{ ++ int ret; ++ file_plugin * fplug = inode_file_plugin(host); ++ ++ switch (fplug->h.id) { ++ case CRYPTCOMPRESS_FILE_PLUGIN_ID: ++ ret = 1; ++ break; ++ default: ++ ret = 0; ++ } ++ return ret; ++} ++#endif /* REISER4_DEBUG */ ++ ++static void reiser4_detach_crypto_info(struct inode * inode) ++{ ++ assert("edward-1385", inode != NULL); ++ assert("edward-1386", host_allows_crypto_info(inode)); ++ ++ if (inode_crypto_info(inode)) ++ unload_crypto_info(inode); ++ set_inode_crypto_info(inode, NULL); ++} ++ ++#if 0 ++ ++/* compare fingerprints of @child and @parent */ ++static int keyid_eq(struct reiser4_crypto_info * child, ++ struct reiser4_crypto_info * parent) ++{ ++ return !memcmp(child->keyid, ++ parent->keyid, ++ info_digest_plugin(parent)->fipsize); ++} ++ ++/* check if a crypto-stat (which is bound to @parent) can be inherited */ ++int can_inherit_crypto_cryptcompress(struct inode *child, struct inode *parent) ++{ ++ if (!need_cipher(child)) ++ return 0; ++ /* the child is created */ ++ if (!inode_crypto_info(child)) ++ return 1; ++ /* the child is looked up */ ++ if (!inode_crypto_info(parent)) ++ return 0; ++ return (inode_cipher_plugin(child) == inode_cipher_plugin(parent) && ++ inode_digest_plugin(child) == inode_digest_plugin(parent) && ++ inode_crypto_info(child)->keysize == ++ inode_crypto_info(parent)->keysize && ++ keyid_eq(inode_crypto_info(child), inode_crypto_info(parent))); ++} ++#endif ++ ++/* helper functions for ->create() method of the cryptcompress plugin */ ++static int inode_set_crypto(struct inode * object) ++{ ++ reiser4_inode * info; ++ if (!inode_crypto_info(object)) { ++ if (need_cipher(object)) ++ return RETERR(-EINVAL); ++ /* the file is not to be encrypted */ ++ return 0; ++ } ++ info = reiser4_inode_data(object); ++ info->extmask |= (1 << CRYPTO_STAT); ++ return 0; ++} ++ ++static int inode_init_compression(struct inode * object) ++{ ++ int result = 0; ++ assert("edward-1461", object != NULL); ++ if (inode_compression_plugin(object)->init) ++ result = inode_compression_plugin(object)->init(); ++ return result; ++} ++ ++static int inode_check_cluster(struct inode * object) ++{ ++ assert("edward-696", object != NULL); ++ ++ if (unlikely(inode_cluster_size(object) < PAGE_CACHE_SIZE)) { ++ warning("edward-1320", "Can not support '%s' " ++ "logical clusters (less then page size)", ++ inode_cluster_plugin(object)->h.label); ++ return RETERR(-EINVAL); ++ } ++ if (unlikely(inode_cluster_shift(object)) >= BITS_PER_BYTE*sizeof(int)){ ++ warning("edward-1463", "Can not support '%s' " ++ "logical clusters (too big for transform)", ++ inode_cluster_plugin(object)->h.label); ++ return RETERR(-EINVAL); ++ } ++ return 0; ++} ++ ++/* plugin->destroy_inode() */ ++void destroy_inode_cryptcompress(struct inode * inode) ++{ ++ assert("edward-1464", INODE_PGCOUNT(inode) == 0); ++ reiser4_detach_crypto_info(inode); ++ return; ++} ++ ++/* plugin->create_object(): ++. install plugins ++. attach crypto info if specified ++. attach compression info if specified ++. attach cluster info ++*/ ++int create_object_cryptcompress(struct inode *object, struct inode *parent, ++ reiser4_object_create_data * data) ++{ ++ int result; ++ reiser4_inode *info; ++ ++ assert("edward-23", object != NULL); ++ assert("edward-24", parent != NULL); ++ assert("edward-30", data != NULL); ++ assert("edward-26", reiser4_inode_get_flag(object, REISER4_NO_SD)); ++ assert("edward-27", data->id == CRYPTCOMPRESS_FILE_PLUGIN_ID); ++ ++ info = reiser4_inode_data(object); ++ ++ assert("edward-29", info != NULL); ++ ++ /* set file bit */ ++ info->plugin_mask |= (1 << PSET_FILE); ++ ++ /* set crypto */ ++ result = inode_set_crypto(object); ++ if (result) ++ goto error; ++ /* set compression */ ++ result = inode_init_compression(object); ++ if (result) ++ goto error; ++ /* set cluster */ ++ result = inode_check_cluster(object); ++ if (result) ++ goto error; ++ ++ /* save everything in disk stat-data */ ++ result = write_sd_by_inode_common(object); ++ if (!result) ++ return 0; ++ error: ++ reiser4_detach_crypto_info(object); ++ return result; ++} ++ ++/* plugin->open() */ ++int open_cryptcompress(struct inode * inode, struct file * file) ++{ ++ return 0; ++} ++ ++/* returns a blocksize, the attribute of a cipher algorithm */ ++static unsigned int ++cipher_blocksize(struct inode * inode) ++{ ++ assert("edward-758", need_cipher(inode)); ++ assert("edward-1400", inode_crypto_info(inode) != NULL); ++ return crypto_blkcipher_blocksize ++ (info_get_cipher(inode_crypto_info(inode))); ++} ++ ++/* returns offset translated by scale factor of the crypto-algorithm */ ++static loff_t inode_scaled_offset (struct inode * inode, ++ const loff_t src_off /* input offset */) ++{ ++ assert("edward-97", inode != NULL); ++ ++ if (!need_cipher(inode) || ++ src_off == get_key_offset(reiser4_min_key()) || ++ src_off == get_key_offset(reiser4_max_key())) ++ return src_off; ++ ++ return inode_cipher_plugin(inode)->scale(inode, ++ cipher_blocksize(inode), ++ src_off); ++} ++ ++/* returns disk cluster size */ ++size_t inode_scaled_cluster_size(struct inode * inode) ++{ ++ assert("edward-110", inode != NULL); ++ ++ return inode_scaled_offset(inode, inode_cluster_size(inode)); ++} ++ ++/* set number of cluster pages */ ++static void set_cluster_nrpages(struct cluster_handle * clust, ++ struct inode *inode) ++{ ++ struct reiser4_slide * win; ++ ++ assert("edward-180", clust != NULL); ++ assert("edward-1040", inode != NULL); ++ ++ clust->old_nrpages = size_in_pages(lbytes(clust->index, inode)); ++ win = clust->win; ++ if (!win) { ++ clust->nr_pages = size_in_pages(lbytes(clust->index, inode)); ++ return; ++ } ++ assert("edward-1176", clust->op != LC_INVAL); ++ assert("edward-1064", win->off + win->count + win->delta != 0); ++ ++ if (win->stat == HOLE_WINDOW && ++ win->off == 0 && win->count == inode_cluster_size(inode)) { ++ /* special case: writing a "fake" logical cluster */ ++ clust->nr_pages = 0; ++ return; ++ } ++ clust->nr_pages = size_in_pages(max(win->off + win->count + win->delta, ++ lbytes(clust->index, inode))); ++ return; ++} ++ ++/* plugin->key_by_inode() ++ build key of a disk cluster */ ++int key_by_inode_cryptcompress(struct inode *inode, loff_t off, ++ reiser4_key * key) ++{ ++ assert("edward-64", inode != 0); ++ ++ if (likely(off != get_key_offset(reiser4_max_key()))) ++ off = off_to_clust_to_off(off, inode); ++ if (inode_crypto_info(inode)) ++ off = inode_scaled_offset(inode, off); ++ ++ key_by_inode_and_offset_common(inode, 0, key); ++ set_key_offset(key, (__u64)off); ++ return 0; ++} ++ ++/* plugin->flow_by_inode() */ ++/* flow is used to read/write disk clusters */ ++int flow_by_inode_cryptcompress(struct inode *inode, const char __user * buf, ++ int user, /* 1: @buf is of user space, ++ 0: kernel space */ ++ loff_t size, /* @buf size */ ++ loff_t off, /* offset to start io from */ ++ rw_op op, /* READ or WRITE */ ++ flow_t * f /* resulting flow */) ++{ ++ assert("edward-436", f != NULL); ++ assert("edward-149", inode != NULL); ++ assert("edward-150", inode_file_plugin(inode) != NULL); ++ assert("edward-1465", user == 0); /* we use flow to read/write ++ disk clusters located in ++ kernel space */ ++ f->length = size; ++ memcpy(&f->data, &buf, sizeof(buf)); ++ f->user = user; ++ f->op = op; ++ ++ return key_by_inode_cryptcompress(inode, off, &f->key); ++} ++ ++static int ++cryptcompress_hint_validate(hint_t * hint, const reiser4_key * key, ++ znode_lock_mode lock_mode) ++{ ++ coord_t *coord; ++ ++ assert("edward-704", hint != NULL); ++ assert("edward-1089", !hint_is_valid(hint)); ++ assert("edward-706", hint->lh.owner == NULL); ++ ++ coord = &hint->ext_coord.coord; ++ ++ if (!hint || !hint_is_set(hint) || hint->mode != lock_mode) ++ /* hint either not set or set by different operation */ ++ return RETERR(-E_REPEAT); ++ ++ if (get_key_offset(key) != hint->offset) ++ /* hint is set for different key */ ++ return RETERR(-E_REPEAT); ++ ++ assert("edward-707", reiser4_schedulable()); ++ ++ return reiser4_seal_validate(&hint->seal, &hint->ext_coord.coord, ++ key, &hint->lh, lock_mode, ++ ZNODE_LOCK_LOPRI); ++} ++ ++/* reserve disk space when writing a logical cluster */ ++static int reserve4cluster(struct inode *inode, struct cluster_handle *clust) ++{ ++ int result = 0; ++ ++ assert("edward-965", reiser4_schedulable()); ++ assert("edward-439", inode != NULL); ++ assert("edward-440", clust != NULL); ++ assert("edward-441", clust->pages != NULL); ++ ++ if (clust->nr_pages == 0) { ++ assert("edward-1152", clust->win != NULL); ++ assert("edward-1153", clust->win->stat == HOLE_WINDOW); ++ /* don't reserve disk space for fake logical cluster */ ++ return 0; ++ } ++ assert("edward-442", jprivate(clust->pages[0]) != NULL); ++ ++ result = reiser4_grab_space_force(estimate_insert_cluster(inode) + ++ estimate_update_cluster(inode), ++ BA_CAN_COMMIT); ++ if (result) ++ return result; ++ clust->reserved = 1; ++ grabbed2cluster_reserved(estimate_insert_cluster(inode) + ++ estimate_update_cluster(inode)); ++#if REISER4_DEBUG ++ clust->reserved_prepped = estimate_update_cluster(inode); ++ clust->reserved_unprepped = estimate_insert_cluster(inode); ++#endif ++ /* there can be space grabbed by txnmgr_force_commit_all */ ++ return 0; ++} ++ ++/* free reserved disk space if writing a logical cluster fails */ ++static void free_reserved4cluster(struct inode *inode, ++ struct cluster_handle *ch, int count) ++{ ++ assert("edward-967", ch->reserved == 1); ++ ++ cluster_reserved2free(count); ++ ch->reserved = 0; ++} ++ ++/* The core search procedure of the cryptcompress plugin. ++ If returned value is not cbk_errored, then current znode is locked */ ++static int find_cluster_item(hint_t * hint, ++ const reiser4_key * key, /* key of the item we are ++ looking for */ ++ znode_lock_mode lock_mode /* which lock */ , ++ ra_info_t * ra_info, lookup_bias bias, __u32 flags) ++{ ++ int result; ++ reiser4_key ikey; ++ int went_right = 0; ++ coord_t *coord = &hint->ext_coord.coord; ++ coord_t orig = *coord; ++ ++ assert("edward-152", hint != NULL); ++ ++ if (!hint_is_valid(hint)) { ++ result = cryptcompress_hint_validate(hint, key, lock_mode); ++ if (result == -E_REPEAT) ++ goto traverse_tree; ++ else if (result) { ++ assert("edward-1216", 0); ++ return result; ++ } ++ hint_set_valid(hint); ++ } ++ assert("edward-709", znode_is_any_locked(coord->node)); ++ ++ /* In-place lookup is going here, it means we just need to ++ check if next item of the @coord match to the @keyhint) */ ++ ++ if (equal_to_rdk(coord->node, key)) { ++ result = goto_right_neighbor(coord, &hint->lh); ++ if (result == -E_NO_NEIGHBOR) { ++ assert("edward-1217", 0); ++ return RETERR(-EIO); ++ } ++ if (result) ++ return result; ++ assert("edward-1218", equal_to_ldk(coord->node, key)); ++ went_right = 1; ++ } else { ++ coord->item_pos++; ++ coord->unit_pos = 0; ++ coord->between = AT_UNIT; ++ } ++ result = zload(coord->node); ++ if (result) ++ return result; ++ assert("edward-1219", !node_is_empty(coord->node)); ++ ++ if (!coord_is_existing_item(coord)) { ++ zrelse(coord->node); ++ goto not_found; ++ } ++ item_key_by_coord(coord, &ikey); ++ zrelse(coord->node); ++ if (!keyeq(key, &ikey)) ++ goto not_found; ++ /* Ok, item is found, update node counts */ ++ if (went_right) ++ dclust_inc_extension_ncount(hint); ++ return CBK_COORD_FOUND; ++ ++ not_found: ++ assert("edward-1220", coord->item_pos > 0); ++ //coord->item_pos--; ++ /* roll back */ ++ *coord = orig; ++ ON_DEBUG(coord_update_v(coord)); ++ return CBK_COORD_NOTFOUND; ++ ++ traverse_tree: ++ assert("edward-713", hint->lh.owner == NULL); ++ assert("edward-714", reiser4_schedulable()); ++ ++ reiser4_unset_hint(hint); ++ dclust_init_extension(hint); ++ coord_init_zero(coord); ++ result = coord_by_key(current_tree, key, coord, &hint->lh, ++ lock_mode, bias, LEAF_LEVEL, LEAF_LEVEL, ++ CBK_UNIQUE | flags, ra_info); ++ if (cbk_errored(result)) ++ return result; ++ if(result == CBK_COORD_FOUND) ++ dclust_inc_extension_ncount(hint); ++ hint_set_valid(hint); ++ return result; ++} ++ ++/* This function is called by deflate[inflate] manager when ++ creating a transformed/plain stream to check if we should ++ create/cut some overhead. If this returns true, then @oh ++ contains the size of this overhead. ++ */ ++static int need_cut_or_align(struct inode * inode, ++ struct cluster_handle * ch, rw_op rw, int * oh) ++{ ++ struct tfm_cluster * tc = &ch->tc; ++ switch (rw) { ++ case WRITE_OP: /* estimate align */ ++ *oh = tc->len % cipher_blocksize(inode); ++ if (*oh != 0) ++ return 1; ++ break; ++ case READ_OP: /* estimate cut */ ++ *oh = *(tfm_output_data(ch) + tc->len - 1); ++ break; ++ default: ++ impossible("edward-1401", "bad option"); ++ } ++ return (tc->len != tc->lsize); ++} ++ ++/* create/cut an overhead of transformed/plain stream */ ++static void align_or_cut_overhead(struct inode * inode, ++ struct cluster_handle * ch, rw_op rw) ++{ ++ unsigned int oh; ++ cipher_plugin * cplug = inode_cipher_plugin(inode); ++ ++ assert("edward-1402", need_cipher(inode)); ++ ++ if (!need_cut_or_align(inode, ch, rw, &oh)) ++ return; ++ switch (rw) { ++ case WRITE_OP: /* do align */ ++ ch->tc.len += ++ cplug->align_stream(tfm_input_data(ch) + ++ ch->tc.len, ch->tc.len, ++ cipher_blocksize(inode)); ++ *(tfm_input_data(ch) + ch->tc.len - 1) = ++ cipher_blocksize(inode) - oh; ++ break; ++ case READ_OP: /* do cut */ ++ assert("edward-1403", oh <= cipher_blocksize(inode)); ++ ch->tc.len -= oh; ++ break; ++ default: ++ impossible("edward-1404", "bad option"); ++ } ++ return; ++} ++ ++static unsigned max_cipher_overhead(struct inode * inode) ++{ ++ if (!need_cipher(inode) || !inode_cipher_plugin(inode)->align_stream) ++ return 0; ++ return cipher_blocksize(inode); ++} ++ ++static int deflate_overhead(struct inode *inode) ++{ ++ return (inode_compression_plugin(inode)-> ++ checksum ? DC_CHECKSUM_SIZE : 0); ++} ++ ++static unsigned deflate_overrun(struct inode * inode, int ilen) ++{ ++ return coa_overrun(inode_compression_plugin(inode), ilen); ++} ++ ++/* Estimating compressibility of a logical cluster by various ++ policies represented by compression mode plugin. ++ If this returns false, then compressor won't be called for ++ the cluster of index @index. ++*/ ++static int should_compress(struct tfm_cluster * tc, cloff_t index, ++ struct inode *inode) ++{ ++ compression_plugin *cplug = inode_compression_plugin(inode); ++ compression_mode_plugin *mplug = inode_compression_mode_plugin(inode); ++ ++ assert("edward-1321", tc->len != 0); ++ assert("edward-1322", cplug != NULL); ++ assert("edward-1323", mplug != NULL); ++ ++ return /* estimate by size */ ++ (cplug->min_size_deflate ? ++ tc->len >= cplug->min_size_deflate() : ++ 1) && ++ /* estimate by compression mode plugin */ ++ (mplug->should_deflate ? ++ mplug->should_deflate(inode, index) : ++ 1); ++} ++ ++/* Evaluating results of compression transform. ++ Returns true, if we need to accept this results */ ++static int save_compressed(int size_before, int size_after, struct inode *inode) ++{ ++ return (size_after + deflate_overhead(inode) + ++ max_cipher_overhead(inode) < size_before); ++} ++ ++/* Guess result of the evaluation above */ ++static int need_inflate(struct cluster_handle * ch, struct inode * inode, ++ int encrypted /* is cluster encrypted */ ) ++{ ++ struct tfm_cluster * tc = &ch->tc; ++ ++ assert("edward-142", tc != 0); ++ assert("edward-143", inode != NULL); ++ ++ return tc->len < ++ (encrypted ? ++ inode_scaled_offset(inode, tc->lsize) : ++ tc->lsize); ++} ++ ++/* If results of compression were accepted, then we add ++ a checksum to catch possible disk cluster corruption. ++ The following is a format of the data stored in disk clusters: ++ ++ data This is (transformed) logical cluster. ++ cipher_overhead This is created by ->align() method ++ of cipher plugin. May be absent. ++ checksum (4) This is created by ->checksum method ++ of compression plugin to check ++ integrity. May be absent. ++ ++ Crypto overhead format: ++ ++ data ++ control_byte (1) contains aligned overhead size: ++ 1 <= overhead <= cipher_blksize ++*/ ++/* Append a checksum at the end of a transformed stream */ ++static void dc_set_checksum(compression_plugin * cplug, struct tfm_cluster * tc) ++{ ++ __u32 checksum; ++ ++ assert("edward-1309", tc != NULL); ++ assert("edward-1310", tc->len > 0); ++ assert("edward-1311", cplug->checksum != NULL); ++ ++ checksum = cplug->checksum(tfm_stream_data(tc, OUTPUT_STREAM), tc->len); ++ put_unaligned(cpu_to_le32(checksum), ++ (d32 *)(tfm_stream_data(tc, OUTPUT_STREAM) + tc->len)); ++ tc->len += (int)DC_CHECKSUM_SIZE; ++} ++ ++/* Check a disk cluster checksum. ++ Returns 0 if checksum is correct, otherwise returns 1 */ ++static int dc_check_checksum(compression_plugin * cplug, struct tfm_cluster * tc) ++{ ++ assert("edward-1312", tc != NULL); ++ assert("edward-1313", tc->len > (int)DC_CHECKSUM_SIZE); ++ assert("edward-1314", cplug->checksum != NULL); ++ ++ if (cplug->checksum(tfm_stream_data(tc, INPUT_STREAM), ++ tc->len - (int)DC_CHECKSUM_SIZE) != ++ le32_to_cpu(get_unaligned((d32 *) ++ (tfm_stream_data(tc, INPUT_STREAM) ++ + tc->len - (int)DC_CHECKSUM_SIZE)))) { ++ warning("edward-156", ++ "Bad disk cluster checksum %d, (should be %d) Fsck?\n", ++ (int)le32_to_cpu ++ (get_unaligned((d32 *) ++ (tfm_stream_data(tc, INPUT_STREAM) + ++ tc->len - (int)DC_CHECKSUM_SIZE))), ++ (int)cplug->checksum ++ (tfm_stream_data(tc, INPUT_STREAM), ++ tc->len - (int)DC_CHECKSUM_SIZE)); ++ return 1; ++ } ++ tc->len -= (int)DC_CHECKSUM_SIZE; ++ return 0; ++} ++ ++/* get input/output stream for some transform action */ ++int grab_tfm_stream(struct inode * inode, struct tfm_cluster * tc, ++ tfm_stream_id id) ++{ ++ size_t size = inode_scaled_cluster_size(inode); ++ ++ assert("edward-901", tc != NULL); ++ assert("edward-1027", inode_compression_plugin(inode) != NULL); ++ ++ if (cluster_get_tfm_act(tc) == TFMA_WRITE) ++ size += deflate_overrun(inode, inode_cluster_size(inode)); ++ ++ if (!get_tfm_stream(tc, id) && id == INPUT_STREAM) ++ alternate_streams(tc); ++ if (!get_tfm_stream(tc, id)) ++ return alloc_tfm_stream(tc, size, id); ++ ++ assert("edward-902", tfm_stream_is_set(tc, id)); ++ ++ if (tfm_stream_size(tc, id) < size) ++ return realloc_tfm_stream(tc, size, id); ++ return 0; ++} ++ ++/* Common deflate manager */ ++int reiser4_deflate_cluster(struct cluster_handle * clust, struct inode * inode) ++{ ++ int result = 0; ++ int compressed = 0; ++ int encrypted = 0; ++ struct tfm_cluster * tc = &clust->tc; ++ compression_plugin * coplug; ++ ++ assert("edward-401", inode != NULL); ++ assert("edward-903", tfm_stream_is_set(tc, INPUT_STREAM)); ++ assert("edward-1348", cluster_get_tfm_act(tc) == TFMA_WRITE); ++ assert("edward-498", !tfm_cluster_is_uptodate(tc)); ++ ++ coplug = inode_compression_plugin(inode); ++ if (should_compress(tc, clust->index, inode)) { ++ /* try to compress, discard bad results */ ++ __u32 dst_len; ++ compression_mode_plugin * mplug = ++ inode_compression_mode_plugin(inode); ++ assert("edward-602", coplug != NULL); ++ assert("edward-1423", coplug->compress != NULL); ++ ++ result = grab_coa(tc, coplug); ++ if (result) { ++ warning("edward-1424", ++ "alloc_coa failed with ret=%d, skipped compression", ++ result); ++ goto cipher; ++ } ++ result = grab_tfm_stream(inode, tc, OUTPUT_STREAM); ++ if (result) { ++ warning("edward-1425", ++ "alloc stream failed with ret=%d, skipped compression", ++ result); ++ goto cipher; ++ } ++ dst_len = tfm_stream_size(tc, OUTPUT_STREAM); ++ coplug->compress(get_coa(tc, coplug->h.id, tc->act), ++ tfm_input_data(clust), tc->len, ++ tfm_output_data(clust), &dst_len); ++ /* make sure we didn't overwrite extra bytes */ ++ assert("edward-603", ++ dst_len <= tfm_stream_size(tc, OUTPUT_STREAM)); ++ ++ /* evaluate results of compression transform */ ++ if (save_compressed(tc->len, dst_len, inode)) { ++ /* good result, accept */ ++ tc->len = dst_len; ++ if (mplug->accept_hook != NULL) { ++ result = mplug->accept_hook(inode, clust->index); ++ if (result) ++ warning("edward-1426", ++ "accept_hook failed with ret=%d", ++ result); ++ } ++ compressed = 1; ++ } ++ else { ++ /* bad result, discard */ ++#if 0 ++ if (cluster_is_complete(clust, inode)) ++ warning("edward-1496", ++ "incompressible cluster %lu (inode %llu)", ++ clust->index, ++ (unsigned long long)get_inode_oid(inode)); ++#endif ++ if (mplug->discard_hook != NULL && ++ cluster_is_complete(clust, inode)) { ++ result = mplug->discard_hook(inode, ++ clust->index); ++ if (result) ++ warning("edward-1427", ++ "discard_hook failed with ret=%d", ++ result); ++ } ++ } ++ } ++ cipher: ++ if (need_cipher(inode)) { ++ cipher_plugin * ciplug; ++ struct blkcipher_desc desc; ++ struct scatterlist src; ++ struct scatterlist dst; ++ ++ ciplug = inode_cipher_plugin(inode); ++ desc.tfm = info_get_cipher(inode_crypto_info(inode)); ++ desc.flags = 0; ++ if (compressed) ++ alternate_streams(tc); ++ result = grab_tfm_stream(inode, tc, OUTPUT_STREAM); ++ if (result) ++ return result; ++ ++ align_or_cut_overhead(inode, clust, WRITE_OP); ++ sg_init_one(&src, tfm_input_data(clust), tc->len); ++ sg_init_one(&dst, tfm_output_data(clust), tc->len); ++ ++ result = crypto_blkcipher_encrypt(&desc, &dst, &src, tc->len); ++ if (result) { ++ warning("edward-1405", ++ "encryption failed flags=%x\n", desc.flags); ++ return result; ++ } ++ encrypted = 1; ++ } ++ if (compressed && coplug->checksum != NULL) ++ dc_set_checksum(coplug, tc); ++ if (!compressed && !encrypted) ++ alternate_streams(tc); ++ return result; ++} ++ ++/* Common inflate manager. */ ++int reiser4_inflate_cluster(struct cluster_handle * clust, struct inode * inode) ++{ ++ int result = 0; ++ int transformed = 0; ++ struct tfm_cluster * tc = &clust->tc; ++ compression_plugin * coplug; ++ ++ assert("edward-905", inode != NULL); ++ assert("edward-1178", clust->dstat == PREP_DISK_CLUSTER); ++ assert("edward-906", tfm_stream_is_set(&clust->tc, INPUT_STREAM)); ++ assert("edward-1349", tc->act == TFMA_READ); ++ assert("edward-907", !tfm_cluster_is_uptodate(tc)); ++ ++ /* Handle a checksum (if any) */ ++ coplug = inode_compression_plugin(inode); ++ if (need_inflate(clust, inode, need_cipher(inode)) && ++ coplug->checksum != NULL) { ++ result = dc_check_checksum(coplug, tc); ++ if (unlikely(result)) { ++ warning("edward-1460", ++ "Inode %llu: disk cluster %lu looks corrupted", ++ (unsigned long long)get_inode_oid(inode), ++ clust->index); ++ return RETERR(-EIO); ++ } ++ } ++ if (need_cipher(inode)) { ++ cipher_plugin * ciplug; ++ struct blkcipher_desc desc; ++ struct scatterlist src; ++ struct scatterlist dst; ++ ++ ciplug = inode_cipher_plugin(inode); ++ desc.tfm = info_get_cipher(inode_crypto_info(inode)); ++ desc.flags = 0; ++ result = grab_tfm_stream(inode, tc, OUTPUT_STREAM); ++ if (result) ++ return result; ++ assert("edward-909", tfm_cluster_is_set(tc)); ++ ++ sg_init_one(&src, tfm_input_data(clust), tc->len); ++ sg_init_one(&dst, tfm_output_data(clust), tc->len); ++ ++ result = crypto_blkcipher_decrypt(&desc, &dst, &src, tc->len); ++ if (result) { ++ warning("edward-1600", "decrypt failed flags=%x\n", ++ desc.flags); ++ return result; ++ } ++ align_or_cut_overhead(inode, clust, READ_OP); ++ transformed = 1; ++ } ++ if (need_inflate(clust, inode, 0)) { ++ unsigned dst_len = inode_cluster_size(inode); ++ if(transformed) ++ alternate_streams(tc); ++ ++ result = grab_tfm_stream(inode, tc, OUTPUT_STREAM); ++ if (result) ++ return result; ++ assert("edward-1305", coplug->decompress != NULL); ++ assert("edward-910", tfm_cluster_is_set(tc)); ++ ++ coplug->decompress(get_coa(tc, coplug->h.id, tc->act), ++ tfm_input_data(clust), tc->len, ++ tfm_output_data(clust), &dst_len); ++ /* check length */ ++ tc->len = dst_len; ++ assert("edward-157", dst_len == tc->lsize); ++ transformed = 1; ++ } ++ if (!transformed) ++ alternate_streams(tc); ++ return result; ++} ++ ++/* This is implementation of readpage method of struct ++ address_space_operations for cryptcompress plugin. */ ++int readpage_cryptcompress(struct file *file, struct page *page) ++{ ++ reiser4_context *ctx; ++ struct cluster_handle clust; ++ item_plugin *iplug; ++ int result; ++ ++ assert("edward-88", PageLocked(page)); ++ assert("vs-976", !PageUptodate(page)); ++ assert("edward-89", page->mapping && page->mapping->host); ++ ++ ctx = reiser4_init_context(page->mapping->host->i_sb); ++ if (IS_ERR(ctx)) { ++ unlock_page(page); ++ return PTR_ERR(ctx); ++ } ++ assert("edward-113", ++ ergo(file != NULL, ++ page->mapping == file->f_dentry->d_inode->i_mapping)); ++ ++ if (PageUptodate(page)) { ++ warning("edward-1338", "page is already uptodate\n"); ++ unlock_page(page); ++ reiser4_exit_context(ctx); ++ return 0; ++ } ++ cluster_init_read(&clust, NULL); ++ clust.file = file; ++ iplug = item_plugin_by_id(CTAIL_ID); ++ if (!iplug->s.file.readpage) { ++ unlock_page(page); ++ put_cluster_handle(&clust); ++ reiser4_exit_context(ctx); ++ return -EINVAL; ++ } ++ result = iplug->s.file.readpage(&clust, page); ++ ++ put_cluster_handle(&clust); ++ reiser4_txn_restart(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/* number of pages to check in */ ++static int get_new_nrpages(struct cluster_handle * clust) ++{ ++ switch (clust->op) { ++ case LC_APPOV: ++ return clust->nr_pages; ++ case LC_TRUNC: ++ assert("edward-1179", clust->win != NULL); ++ return size_in_pages(clust->win->off + clust->win->count); ++ default: ++ impossible("edward-1180", "bad page cluster option"); ++ return 0; ++ } ++} ++ ++static void set_cluster_pages_dirty(struct cluster_handle * clust, ++ struct inode * inode) ++{ ++ int i; ++ struct page *pg; ++ int nrpages = get_new_nrpages(clust); ++ ++ for (i = 0; i < nrpages; i++) { ++ ++ pg = clust->pages[i]; ++ assert("edward-968", pg != NULL); ++ lock_page(pg); ++ assert("edward-1065", PageUptodate(pg)); ++ set_page_dirty_notag(pg); ++ unlock_page(pg); ++ mark_page_accessed(pg); ++ } ++} ++ ++/* Grab a page cluster for read/write operations. ++ Attach a jnode for write operations (when preparing for modifications, which ++ are supposed to be committed). ++ ++ We allocate only one jnode per page cluster; this jnode is binded to the ++ first page of this cluster, so we have an extra-reference that will be put ++ as soon as jnode is evicted from memory), other references will be cleaned ++ up in flush time (assume that check in page cluster was successful). ++*/ ++int grab_page_cluster(struct inode * inode, ++ struct cluster_handle * clust, rw_op rw) ++{ ++ int i; ++ int result = 0; ++ jnode *node = NULL; ++ ++ assert("edward-182", clust != NULL); ++ assert("edward-183", clust->pages != NULL); ++ assert("edward-1466", clust->node == NULL); ++ assert("edward-1428", inode != NULL); ++ assert("edward-1429", inode->i_mapping != NULL); ++ assert("edward-184", clust->nr_pages <= cluster_nrpages(inode)); ++ ++ if (clust->nr_pages == 0) ++ return 0; ++ ++ for (i = 0; i < clust->nr_pages; i++) { ++ ++ assert("edward-1044", clust->pages[i] == NULL); ++ ++ clust->pages[i] = ++ find_or_create_page(inode->i_mapping, ++ clust_to_pg(clust->index, inode) + i, ++ reiser4_ctx_gfp_mask_get()); ++ if (!clust->pages[i]) { ++ result = RETERR(-ENOMEM); ++ break; ++ } ++ if (i == 0 && rw == WRITE_OP) { ++ node = jnode_of_page(clust->pages[i]); ++ if (IS_ERR(node)) { ++ result = PTR_ERR(node); ++ unlock_page(clust->pages[i]); ++ break; ++ } ++ JF_SET(node, JNODE_CLUSTER_PAGE); ++ assert("edward-920", jprivate(clust->pages[0])); ++ } ++ INODE_PGCOUNT_INC(inode); ++ unlock_page(clust->pages[i]); ++ } ++ if (unlikely(result)) { ++ while (i) { ++ put_cluster_page(clust->pages[--i]); ++ INODE_PGCOUNT_DEC(inode); ++ } ++ if (node && !IS_ERR(node)) ++ jput(node); ++ return result; ++ } ++ clust->node = node; ++ return 0; ++} ++ ++static void truncate_page_cluster_range(struct inode * inode, ++ struct page ** pages, ++ cloff_t index, ++ int from, int count, ++ int even_cows) ++{ ++ assert("edward-1467", count > 0); ++ reiser4_invalidate_pages(inode->i_mapping, ++ clust_to_pg(index, inode) + from, ++ count, even_cows); ++} ++ ++/* Put @count pages starting from @from offset */ ++void __put_page_cluster(int from, int count, ++ struct page ** pages, struct inode * inode) ++{ ++ int i; ++ assert("edward-1468", pages != NULL); ++ assert("edward-1469", inode != NULL); ++ assert("edward-1470", from >= 0 && count >= 0); ++ ++ for (i = 0; i < count; i++) { ++ assert("edward-1471", pages[from + i] != NULL); ++ assert("edward-1472", ++ pages[from + i]->index == pages[from]->index + i); ++ ++ put_cluster_page(pages[from + i]); ++ INODE_PGCOUNT_DEC(inode); ++ } ++} ++ ++/* ++ * This is dual to grab_page_cluster, ++ * however if @rw == WRITE_OP, then we call this function ++ * only if something is failed before checkin page cluster. ++ */ ++void put_page_cluster(struct cluster_handle * clust, ++ struct inode * inode, rw_op rw) ++{ ++ assert("edward-445", clust != NULL); ++ assert("edward-922", clust->pages != NULL); ++ assert("edward-446", ++ ergo(clust->nr_pages != 0, clust->pages[0] != NULL)); ++ ++ __put_page_cluster(0, clust->nr_pages, clust->pages, inode); ++ if (rw == WRITE_OP) { ++ if (unlikely(clust->node)) { ++ assert("edward-447", ++ clust->node == jprivate(clust->pages[0])); ++ jput(clust->node); ++ clust->node = NULL; ++ } ++ } ++} ++ ++#if REISER4_DEBUG ++int cryptcompress_inode_ok(struct inode *inode) ++{ ++ if (!(reiser4_inode_data(inode)->plugin_mask & (1 << PSET_FILE))) ++ return 0; ++ if (!cluster_shift_ok(inode_cluster_shift(inode))) ++ return 0; ++ return 1; ++} ++ ++static int window_ok(struct reiser4_slide * win, struct inode *inode) ++{ ++ assert("edward-1115", win != NULL); ++ assert("edward-1116", ergo(win->delta, win->stat == HOLE_WINDOW)); ++ ++ return (win->off != inode_cluster_size(inode)) && ++ (win->off + win->count + win->delta <= inode_cluster_size(inode)); ++} ++ ++static int cluster_ok(struct cluster_handle * clust, struct inode *inode) ++{ ++ assert("edward-279", clust != NULL); ++ ++ if (!clust->pages) ++ return 0; ++ return (clust->win ? window_ok(clust->win, inode) : 1); ++} ++#if 0 ++static int pages_truncate_ok(struct inode *inode, pgoff_t start) ++{ ++ int found; ++ struct page * page; ++ ++ found = find_get_pages(inode->i_mapping, start, 1, &page); ++ if (found) ++ put_cluster_page(page); ++ return !found; ++} ++#else ++#define pages_truncate_ok(inode, start) 1 ++#endif ++ ++static int jnode_truncate_ok(struct inode *inode, cloff_t index) ++{ ++ jnode *node; ++ node = jlookup(current_tree, get_inode_oid(inode), ++ clust_to_pg(index, inode)); ++ if (likely(!node)) ++ return 1; ++ jput(node); ++ return 0; ++} ++ ++static int find_fake_appended(struct inode *inode, cloff_t * index); ++ ++static int body_truncate_ok(struct inode *inode, cloff_t aidx) ++{ ++ int result; ++ cloff_t raidx; ++ ++ result = find_fake_appended(inode, &raidx); ++ return !result && (aidx == raidx); ++} ++#endif ++ ++/* guess next window stat */ ++static inline window_stat next_window_stat(struct reiser4_slide * win) ++{ ++ assert("edward-1130", win != NULL); ++ return ((win->stat == HOLE_WINDOW && win->delta == 0) ? ++ HOLE_WINDOW : DATA_WINDOW); ++} ++ ++/* guess and set next cluster index and window params */ ++static void move_update_window(struct inode * inode, ++ struct cluster_handle * clust, ++ loff_t file_off, loff_t to_file) ++{ ++ struct reiser4_slide * win; ++ ++ assert("edward-185", clust != NULL); ++ assert("edward-438", clust->pages != NULL); ++ assert("edward-281", cluster_ok(clust, inode)); ++ ++ win = clust->win; ++ if (!win) ++ return; ++ ++ switch (win->stat) { ++ case DATA_WINDOW: ++ /* increment */ ++ clust->index++; ++ win->stat = DATA_WINDOW; ++ win->off = 0; ++ win->count = min((loff_t)inode_cluster_size(inode), to_file); ++ break; ++ case HOLE_WINDOW: ++ switch (next_window_stat(win)) { ++ case HOLE_WINDOW: ++ /* skip */ ++ clust->index = off_to_clust(file_off, inode); ++ win->stat = HOLE_WINDOW; ++ win->off = 0; ++ win->count = off_to_cloff(file_off, inode); ++ win->delta = min((loff_t)(inode_cluster_size(inode) - ++ win->count), to_file); ++ break; ++ case DATA_WINDOW: ++ /* stay */ ++ win->stat = DATA_WINDOW; ++ /* off+count+delta=inv */ ++ win->off = win->off + win->count; ++ win->count = win->delta; ++ win->delta = 0; ++ break; ++ default: ++ impossible("edward-282", "wrong next window state"); ++ } ++ break; ++ default: ++ impossible("edward-283", "wrong current window state"); ++ } ++ assert("edward-1068", cluster_ok(clust, inode)); ++} ++ ++static int update_sd_cryptcompress(struct inode *inode) ++{ ++ int result = 0; ++ ++ assert("edward-978", reiser4_schedulable()); ++ ++ result = reiser4_grab_space_force(/* one for stat data update */ ++ estimate_update_common(inode), ++ BA_CAN_COMMIT); ++ if (result) ++ return result; ++ inode->i_ctime = inode->i_mtime = CURRENT_TIME; ++ result = reiser4_update_sd(inode); ++ ++ return result; ++} ++ ++static void uncapture_cluster_jnode(jnode * node) ++{ ++ txn_atom *atom; ++ ++ assert_spin_locked(&(node->guard)); ++ ++ atom = jnode_get_atom(node); ++ if (atom == NULL) { ++ assert("jmacd-7111", !JF_ISSET(node, JNODE_DIRTY)); ++ spin_unlock_jnode(node); ++ return; ++ } ++ reiser4_uncapture_block(node); ++ spin_unlock_atom(atom); ++ jput(node); ++} ++ ++static void put_found_pages(struct page **pages, int nr) ++{ ++ int i; ++ for (i = 0; i < nr; i++) { ++ assert("edward-1045", pages[i] != NULL); ++ put_cluster_page(pages[i]); ++ } ++} ++ ++/* Lifecycle of a logical cluster in the system. ++ * ++ * ++ * Logical cluster of a cryptcompress file is represented in the system by ++ * . page cluster (in memory, primary cache, contains plain text); ++ * . disk cluster (in memory, secondary cache, contains transformed text). ++ * Primary cache is to reduce number of transform operations (compression, ++ * encryption), i.e. to implement transform-caching strategy. ++ * Secondary cache is to reduce number of I/O operations, i.e. for usual ++ * write-caching strategy. Page cluster is a set of pages, i.e. mapping of ++ * a logical cluster to the primary cache. Disk cluster is a set of items ++ * of the same type defined by some reiser4 item plugin id. ++ * ++ * 1. Performing modifications ++ * ++ * Every modification of a cryptcompress file is considered as a set of ++ * operations performed on file's logical clusters. Every such "atomic" ++ * modification is truncate, append and(or) overwrite some bytes of a ++ * logical cluster performed in the primary cache with the following ++ * synchronization with the secondary cache (in flush time). Disk clusters, ++ * which live in the secondary cache, are supposed to be synchronized with ++ * disk. The mechanism of synchronization of primary and secondary caches ++ * includes so-called checkin/checkout technique described below. ++ * ++ * 2. Submitting modifications ++ * ++ * Each page cluster has associated jnode (a special in-memory header to ++ * keep a track of transactions in reiser4), which is attached to its first ++ * page when grabbing page cluster for modifications (see grab_page_cluster). ++ * Submitting modifications (see checkin_logical_cluster) is going per logical ++ * cluster and includes: ++ * . checkin_cluster_size; ++ * . checkin_page_cluster. ++ * checkin_cluster_size() is resolved to file size update (which completely ++ * defines new size of logical cluster (number of file's bytes in a logical ++ * cluster). ++ * checkin_page_cluster() captures jnode of a page cluster and installs ++ * jnode's dirty flag (if needed) to indicate that modifications are ++ * successfully checked in. ++ * ++ * 3. Checking out modifications ++ * ++ * Is going per logical cluster in flush time (see checkout_logical_cluster). ++ * This is the time of synchronizing primary and secondary caches. ++ * checkout_logical_cluster() includes: ++ * . checkout_page_cluster (retrieving checked in pages). ++ * . uncapture jnode (including clear dirty flag and unlock) ++ * ++ * 4. Committing modifications ++ * ++ * Proceeding a synchronization of primary and secondary caches. When checking ++ * out page cluster (the phase above) pages are locked/flushed/unlocked ++ * one-by-one in ascending order of their indexes to contiguous stream, which ++ * is supposed to be transformed (compressed, encrypted), chopped up into items ++ * and committed to disk as a disk cluster. ++ * ++ * 5. Managing page references ++ * ++ * Every checked in page have a special additional "control" reference, ++ * which is dropped at checkout. We need this to avoid unexpected evicting ++ * pages from memory before checkout. Control references are managed so ++ * they are not accumulated with every checkin: ++ * ++ * 0 ++ * checkin -> 1 ++ * 0 -> checkout ++ * checkin -> 1 ++ * checkin -> 1 ++ * checkin -> 1 ++ * 0 -> checkout ++ * ... ++ * ++ * Every page cluster has its own unique "cluster lock". Update/drop ++ * references are serialized via this lock. Number of checked in cluster ++ * pages is calculated by i_size under cluster lock. File size is updated ++ * at every checkin action also under cluster lock (except cases of ++ * appending/truncating fake logical clusters). ++ * ++ * Proof of correctness: ++ * ++ * Since we update file size under cluster lock, in the case of non-fake ++ * logical cluster with its lock held we do have expected number of checked ++ * in pages. On the other hand, append/truncate of fake logical clusters ++ * doesn't change number of checked in pages of any cluster. ++ * ++ * NOTE-EDWARD: As cluster lock we use guard (spinlock_t) of its jnode. ++ * Currently, I don't see any reason to create a special lock for those ++ * needs. ++ */ ++ ++static inline void lock_cluster(jnode * node) ++{ ++ spin_lock_jnode(node); ++} ++ ++static inline void unlock_cluster(jnode * node) ++{ ++ spin_unlock_jnode(node); ++} ++ ++static inline void unlock_cluster_uncapture(jnode * node) ++{ ++ uncapture_cluster_jnode(node); ++} ++ ++/* Set new file size by window. Cluster lock is required. */ ++static void checkin_file_size(struct cluster_handle * clust, ++ struct inode * inode) ++{ ++ loff_t new_size; ++ struct reiser4_slide * win; ++ ++ assert("edward-1181", clust != NULL); ++ assert("edward-1182", inode != NULL); ++ assert("edward-1473", clust->pages != NULL); ++ assert("edward-1474", clust->pages[0] != NULL); ++ assert("edward-1475", jprivate(clust->pages[0]) != NULL); ++ assert_spin_locked(&(jprivate(clust->pages[0])->guard)); ++ ++ ++ win = clust->win; ++ assert("edward-1183", win != NULL); ++ ++ new_size = clust_to_off(clust->index, inode) + win->off; ++ ++ switch (clust->op) { ++ case LC_APPOV: ++ if (new_size + win->count <= i_size_read(inode)) ++ /* overwrite only */ ++ return; ++ new_size += win->count; ++ break; ++ case LC_TRUNC: ++ break; ++ default: ++ impossible("edward-1184", "bad page cluster option"); ++ break; ++ } ++ inode_check_scale_nolock(inode, i_size_read(inode), new_size); ++ i_size_write(inode, new_size); ++ return; ++} ++ ++static inline void checkin_cluster_size(struct cluster_handle * clust, ++ struct inode * inode) ++{ ++ if (clust->win) ++ checkin_file_size(clust, inode); ++} ++ ++static int checkin_page_cluster(struct cluster_handle * clust, ++ struct inode * inode) ++{ ++ int result; ++ jnode * node; ++ int old_nrpages = clust->old_nrpages; ++ int new_nrpages = get_new_nrpages(clust); ++ ++ node = clust->node; ++ ++ assert("edward-221", node != NULL); ++ assert("edward-971", clust->reserved == 1); ++ assert("edward-1263", ++ clust->reserved_prepped == estimate_update_cluster(inode)); ++ assert("edward-1264", clust->reserved_unprepped == 0); ++ ++ if (JF_ISSET(node, JNODE_DIRTY)) { ++ /* ++ * page cluster was checked in, but not yet ++ * checked out, so release related resources ++ */ ++ free_reserved4cluster(inode, clust, ++ estimate_update_cluster(inode)); ++ __put_page_cluster(0, clust->old_nrpages, ++ clust->pages, inode); ++ } else { ++ result = capture_cluster_jnode(node); ++ if (unlikely(result)) { ++ unlock_cluster(node); ++ return result; ++ } ++ jnode_make_dirty_locked(node); ++ clust->reserved = 0; ++ } ++ unlock_cluster(node); ++ ++ if (new_nrpages < old_nrpages) { ++ /* truncate >= 1 complete pages */ ++ __put_page_cluster(new_nrpages, ++ old_nrpages - new_nrpages, ++ clust->pages, inode); ++ truncate_page_cluster_range(inode, ++ clust->pages, clust->index, ++ new_nrpages, ++ old_nrpages - new_nrpages, ++ 0); ++ } ++#if REISER4_DEBUG ++ clust->reserved_prepped -= estimate_update_cluster(inode); ++#endif ++ return 0; ++} ++ ++/* Submit modifications of a logical cluster */ ++static int checkin_logical_cluster(struct cluster_handle * clust, ++ struct inode *inode) ++{ ++ int result = 0; ++ jnode * node; ++ ++ node = clust->node; ++ ++ assert("edward-1035", node != NULL); ++ assert("edward-1029", clust != NULL); ++ assert("edward-1030", clust->reserved == 1); ++ assert("edward-1031", clust->nr_pages != 0); ++ assert("edward-1032", clust->pages != NULL); ++ assert("edward-1033", clust->pages[0] != NULL); ++ assert("edward-1446", jnode_is_cluster_page(node)); ++ assert("edward-1476", node == jprivate(clust->pages[0])); ++ ++ lock_cluster(node); ++ checkin_cluster_size(clust, inode); ++ /* this will unlock cluster */ ++ result = checkin_page_cluster(clust, inode); ++ jput(node); ++ clust->node = NULL; ++ return result; ++} ++ ++/* ++ * Retrieve size of logical cluster that was checked in at ++ * the latest modifying session (cluster lock is required) ++ */ ++static inline void checkout_cluster_size(struct cluster_handle * clust, ++ struct inode * inode) ++{ ++ struct tfm_cluster *tc = &clust->tc; ++ ++ tc->len = lbytes(clust->index, inode); ++ assert("edward-1478", tc->len != 0); ++} ++ ++/* ++ * Retrieve a page cluster with the latest submitted modifications ++ * and flush its pages to previously allocated contiguous stream. ++ */ ++static void checkout_page_cluster(struct cluster_handle * clust, ++ jnode * node, struct inode * inode) ++{ ++ int i; ++ int found; ++ int to_put; ++ struct tfm_cluster *tc = &clust->tc; ++ ++ /* find and put checked in pages: cluster is locked, ++ * so we must get expected number (to_put) of pages ++ */ ++ to_put = size_in_pages(lbytes(clust->index, inode)); ++ found = find_get_pages(inode->i_mapping, ++ clust_to_pg(clust->index, inode), ++ to_put, clust->pages); ++ BUG_ON(found != to_put); ++ ++ __put_page_cluster(0, to_put, clust->pages, inode); ++ unlock_cluster_uncapture(node); ++ ++ /* Flush found pages. ++ * ++ * Note, that we don't disable modifications while flushing, ++ * moreover, some found pages can be truncated, as we have ++ * released cluster lock. ++ */ ++ for (i = 0; i < found; i++) { ++ int in_page; ++ char * data; ++ assert("edward-1479", ++ clust->pages[i]->index == clust->pages[0]->index + i); ++ ++ lock_page(clust->pages[i]); ++ if (!PageUptodate(clust->pages[i])) { ++ /* page was truncated */ ++ assert("edward-1480", ++ i_size_read(inode) <= page_offset(clust->pages[i])); ++ assert("edward-1481", ++ clust->pages[i]->mapping != inode->i_mapping); ++ unlock_page(clust->pages[i]); ++ break; ++ } ++ /* Update the number of bytes in the logical cluster, ++ * as it could be partially truncated. Note, that only ++ * partial truncate is possible (complete truncate can ++ * not go here, as it is performed via ->kill_hook() ++ * called by cut_file_items(), and the last one must ++ * wait for znode locked with parent coord). ++ */ ++ checkout_cluster_size(clust, inode); ++ ++ /* this can be zero, as new file size is ++ checked in before truncating pages */ ++ in_page = __mbp(tc->len, i); ++ ++ data = kmap(clust->pages[i]); ++ memcpy(tfm_stream_data(tc, INPUT_STREAM) + pg_to_off(i), ++ data, in_page); ++ kunmap(clust->pages[i]); ++ ++ if (PageDirty(clust->pages[i])) ++ cancel_dirty_page(clust->pages[i], PAGE_CACHE_SIZE); ++ ++ unlock_page(clust->pages[i]); ++ ++ if (in_page < PAGE_CACHE_SIZE) ++ /* end of the file */ ++ break; ++ } ++ put_found_pages(clust->pages, found); /* find_get_pages */ ++ tc->lsize = tc->len; ++ return; ++} ++ ++/* Check out modifications of a logical cluster */ ++int checkout_logical_cluster(struct cluster_handle * clust, ++ jnode * node, struct inode *inode) ++{ ++ int result; ++ struct tfm_cluster *tc = &clust->tc; ++ ++ assert("edward-980", node != NULL); ++ assert("edward-236", inode != NULL); ++ assert("edward-237", clust != NULL); ++ assert("edward-240", !clust->win); ++ assert("edward-241", reiser4_schedulable()); ++ assert("edward-718", cryptcompress_inode_ok(inode)); ++ ++ result = grab_tfm_stream(inode, tc, INPUT_STREAM); ++ if (result) { ++ warning("edward-1430", "alloc stream failed with ret=%d", ++ result); ++ return RETERR(-E_REPEAT); ++ } ++ lock_cluster(node); ++ ++ if (unlikely(!JF_ISSET(node, JNODE_DIRTY))) { ++ /* race with another flush */ ++ warning("edward-982", ++ "checking out logical cluster %lu of inode %llu: " ++ "jnode is not dirty", clust->index, ++ (unsigned long long)get_inode_oid(inode)); ++ unlock_cluster(node); ++ return RETERR(-E_REPEAT); ++ } ++ cluster_reserved2grabbed(estimate_update_cluster(inode)); ++ ++ /* this will unlock cluster */ ++ checkout_page_cluster(clust, node, inode); ++ return 0; ++} ++ ++/* set hint for the cluster of the index @index */ ++static void set_hint_cluster(struct inode *inode, hint_t * hint, ++ cloff_t index, znode_lock_mode mode) ++{ ++ reiser4_key key; ++ assert("edward-722", cryptcompress_inode_ok(inode)); ++ assert("edward-723", ++ inode_file_plugin(inode) == ++ file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID)); ++ ++ inode_file_plugin(inode)->key_by_inode(inode, ++ clust_to_off(index, inode), ++ &key); ++ ++ reiser4_seal_init(&hint->seal, &hint->ext_coord.coord, &key); ++ hint->offset = get_key_offset(&key); ++ hint->mode = mode; ++} ++ ++void invalidate_hint_cluster(struct cluster_handle * clust) ++{ ++ assert("edward-1291", clust != NULL); ++ assert("edward-1292", clust->hint != NULL); ++ ++ done_lh(&clust->hint->lh); ++ hint_clr_valid(clust->hint); ++} ++ ++static void put_hint_cluster(struct cluster_handle * clust, ++ struct inode *inode, znode_lock_mode mode) ++{ ++ assert("edward-1286", clust != NULL); ++ assert("edward-1287", clust->hint != NULL); ++ ++ set_hint_cluster(inode, clust->hint, clust->index + 1, mode); ++ invalidate_hint_cluster(clust); ++} ++ ++static int balance_dirty_page_cluster(struct cluster_handle * clust, ++ struct inode *inode, loff_t off, ++ loff_t to_file, ++ int nr_dirtied) ++{ ++ int result; ++ struct cryptcompress_info * info; ++ ++ assert("edward-724", inode != NULL); ++ assert("edward-725", cryptcompress_inode_ok(inode)); ++ assert("edward-1547", ++ nr_dirtied != 0 && nr_dirtied <= cluster_nrpages(inode)); ++ ++ /* set next window params */ ++ move_update_window(inode, clust, off, to_file); ++ ++ result = update_sd_cryptcompress(inode); ++ if (result) ++ return result; ++ assert("edward-726", clust->hint->lh.owner == NULL); ++ info = cryptcompress_inode_data(inode); ++ ++ mutex_unlock(&info->checkin_mutex); ++ reiser4_txn_restart_current(); ++ balance_dirty_pages_ratelimited_nr(inode->i_mapping, nr_dirtied); ++ mutex_lock(&info->checkin_mutex); ++ return 0; ++} ++ ++/* set zeroes to the page cluster, proceed it, and maybe, try to capture ++ its pages */ ++static int write_hole(struct inode *inode, struct cluster_handle * clust, ++ loff_t file_off, loff_t to_file) ++{ ++ int result = 0; ++ unsigned cl_off, cl_count = 0; ++ unsigned to_pg, pg_off; ++ struct reiser4_slide * win; ++ ++ assert("edward-190", clust != NULL); ++ assert("edward-1069", clust->win != NULL); ++ assert("edward-191", inode != NULL); ++ assert("edward-727", cryptcompress_inode_ok(inode)); ++ assert("edward-1171", clust->dstat != INVAL_DISK_CLUSTER); ++ assert("edward-1154", ++ ergo(clust->dstat != FAKE_DISK_CLUSTER, clust->reserved == 1)); ++ ++ win = clust->win; ++ ++ assert("edward-1070", win != NULL); ++ assert("edward-201", win->stat == HOLE_WINDOW); ++ assert("edward-192", cluster_ok(clust, inode)); ++ ++ if (win->off == 0 && win->count == inode_cluster_size(inode)) { ++ /* This part of the hole will be represented by "fake" ++ * logical cluster, i.e. which doesn't have appropriate ++ * disk cluster until someone modify this logical cluster ++ * and make it dirty. ++ * So go forward here.. ++ */ ++ move_update_window(inode, clust, file_off, to_file); ++ return 0; ++ } ++ cl_count = win->count; /* number of zeroes to write */ ++ cl_off = win->off; ++ pg_off = off_to_pgoff(win->off); ++ ++ while (cl_count) { ++ struct page *page; ++ page = clust->pages[off_to_pg(cl_off)]; ++ ++ assert("edward-284", page != NULL); ++ ++ to_pg = min((typeof(pg_off))PAGE_CACHE_SIZE - pg_off, cl_count); ++ lock_page(page); ++ zero_user(page, pg_off, to_pg); ++ SetPageUptodate(page); ++ set_page_dirty_notag(page); ++ mark_page_accessed(page); ++ unlock_page(page); ++ ++ cl_off += to_pg; ++ cl_count -= to_pg; ++ pg_off = 0; ++ } ++ if (!win->delta) { ++ /* only zeroes in this window, try to capture ++ */ ++ result = checkin_logical_cluster(clust, inode); ++ if (result) ++ return result; ++ put_hint_cluster(clust, inode, ZNODE_WRITE_LOCK); ++ result = balance_dirty_page_cluster(clust, ++ inode, file_off, to_file, ++ win_count_to_nrpages(win)); ++ } else ++ move_update_window(inode, clust, file_off, to_file); ++ return result; ++} ++ ++/* ++ The main disk search procedure for cryptcompress plugin, which ++ . scans all items of disk cluster with the lock mode @mode ++ . maybe reads each one (if @read) ++ . maybe makes its znode dirty (if write lock mode was specified) ++ ++ NOTE-EDWARD: Callers should handle the case when disk cluster ++ is incomplete (-EIO) ++*/ ++int find_disk_cluster(struct cluster_handle * clust, ++ struct inode *inode, int read, znode_lock_mode mode) ++{ ++ flow_t f; ++ hint_t *hint; ++ int result = 0; ++ int was_grabbed; ++ ra_info_t ra_info; ++ file_plugin *fplug; ++ item_plugin *iplug; ++ struct tfm_cluster *tc; ++ struct cryptcompress_info * info; ++ ++ assert("edward-138", clust != NULL); ++ assert("edward-728", clust->hint != NULL); ++ assert("edward-226", reiser4_schedulable()); ++ assert("edward-137", inode != NULL); ++ assert("edward-729", cryptcompress_inode_ok(inode)); ++ ++ hint = clust->hint; ++ fplug = inode_file_plugin(inode); ++ was_grabbed = get_current_context()->grabbed_blocks; ++ info = cryptcompress_inode_data(inode); ++ tc = &clust->tc; ++ ++ assert("edward-462", !tfm_cluster_is_uptodate(tc)); ++ assert("edward-461", ergo(read, tfm_stream_is_set(tc, INPUT_STREAM))); ++ ++ dclust_init_extension(hint); ++ ++ /* set key of the first disk cluster item */ ++ fplug->flow_by_inode(inode, ++ (read ? (char __user *)tfm_stream_data(tc, INPUT_STREAM) : NULL), ++ 0 /* kernel space */ , ++ inode_scaled_cluster_size(inode), ++ clust_to_off(clust->index, inode), READ_OP, &f); ++ if (mode == ZNODE_WRITE_LOCK) { ++ /* reserve for flush to make dirty all the leaf nodes ++ which contain disk cluster */ ++ result = ++ reiser4_grab_space_force(estimate_dirty_cluster(inode), ++ BA_CAN_COMMIT); ++ if (result) ++ goto out; ++ } ++ ++ ra_info.key_to_stop = f.key; ++ set_key_offset(&ra_info.key_to_stop, get_key_offset(reiser4_max_key())); ++ ++ while (f.length) { ++ result = find_cluster_item(hint, &f.key, mode, ++ NULL, FIND_EXACT, ++ (mode == ZNODE_WRITE_LOCK ? ++ CBK_FOR_INSERT : 0)); ++ switch (result) { ++ case CBK_COORD_NOTFOUND: ++ result = 0; ++ if (inode_scaled_offset ++ (inode, clust_to_off(clust->index, inode)) == ++ get_key_offset(&f.key)) { ++ /* first item not found, this is treated ++ as disk cluster is absent */ ++ clust->dstat = FAKE_DISK_CLUSTER; ++ goto out; ++ } ++ /* we are outside the cluster, stop search here */ ++ assert("edward-146", ++ f.length != inode_scaled_cluster_size(inode)); ++ goto ok; ++ case CBK_COORD_FOUND: ++ assert("edward-148", ++ hint->ext_coord.coord.between == AT_UNIT); ++ assert("edward-460", ++ hint->ext_coord.coord.unit_pos == 0); ++ ++ coord_clear_iplug(&hint->ext_coord.coord); ++ result = zload_ra(hint->ext_coord.coord.node, &ra_info); ++ if (unlikely(result)) ++ goto out; ++ iplug = item_plugin_by_coord(&hint->ext_coord.coord); ++ assert("edward-147", ++ item_id_by_coord(&hint->ext_coord.coord) == ++ CTAIL_ID); ++ ++ result = iplug->s.file.read(NULL, &f, hint); ++ if (result) { ++ zrelse(hint->ext_coord.coord.node); ++ goto out; ++ } ++ if (mode == ZNODE_WRITE_LOCK) { ++ /* Don't make dirty more nodes then it was ++ estimated (see comments before ++ estimate_dirty_cluster). Missed nodes will be ++ read up in flush time if they are evicted from ++ memory */ ++ if (dclust_get_extension_ncount(hint) <= ++ estimate_dirty_cluster(inode)) ++ znode_make_dirty(hint->ext_coord.coord.node); ++ ++ znode_set_convertible(hint->ext_coord.coord. ++ node); ++ } ++ zrelse(hint->ext_coord.coord.node); ++ break; ++ default: ++ goto out; ++ } ++ } ++ ok: ++ /* at least one item was found */ ++ /* NOTE-EDWARD: Callers should handle the case ++ when disk cluster is incomplete (-EIO) */ ++ tc->len = inode_scaled_cluster_size(inode) - f.length; ++ tc->lsize = lbytes(clust->index, inode); ++ assert("edward-1196", tc->len > 0); ++ assert("edward-1406", tc->lsize > 0); ++ ++ if (hint_is_unprepped_dclust(clust->hint)) { ++ clust->dstat = UNPR_DISK_CLUSTER; ++ } else if (clust->index == info->trunc_index) { ++ clust->dstat = TRNC_DISK_CLUSTER; ++ } else { ++ clust->dstat = PREP_DISK_CLUSTER; ++ dclust_set_extension_dsize(clust->hint, tc->len); ++ } ++ out: ++ assert("edward-1339", ++ get_current_context()->grabbed_blocks >= was_grabbed); ++ grabbed2free(get_current_context(), ++ get_current_super_private(), ++ get_current_context()->grabbed_blocks - was_grabbed); ++ return result; ++} ++ ++int get_disk_cluster_locked(struct cluster_handle * clust, struct inode *inode, ++ znode_lock_mode lock_mode) ++{ ++ reiser4_key key; ++ ra_info_t ra_info; ++ ++ assert("edward-730", reiser4_schedulable()); ++ assert("edward-731", clust != NULL); ++ assert("edward-732", inode != NULL); ++ ++ if (hint_is_valid(clust->hint)) { ++ assert("edward-1293", clust->dstat != INVAL_DISK_CLUSTER); ++ assert("edward-1294", ++ znode_is_write_locked(clust->hint->lh.node)); ++ /* already have a valid locked position */ ++ return (clust->dstat == ++ FAKE_DISK_CLUSTER ? CBK_COORD_NOTFOUND : ++ CBK_COORD_FOUND); ++ } ++ key_by_inode_cryptcompress(inode, clust_to_off(clust->index, inode), ++ &key); ++ ra_info.key_to_stop = key; ++ set_key_offset(&ra_info.key_to_stop, get_key_offset(reiser4_max_key())); ++ ++ return find_cluster_item(clust->hint, &key, lock_mode, NULL, FIND_EXACT, ++ CBK_FOR_INSERT); ++} ++ ++/* Read needed cluster pages before modifying. ++ If success, @clust->hint contains locked position in the tree. ++ Also: ++ . find and set disk cluster state ++ . make disk cluster dirty if its state is not FAKE_DISK_CLUSTER. ++*/ ++static int read_some_cluster_pages(struct inode * inode, ++ struct cluster_handle * clust) ++{ ++ int i; ++ int result = 0; ++ item_plugin *iplug; ++ struct reiser4_slide * win = clust->win; ++ znode_lock_mode mode = ZNODE_WRITE_LOCK; ++ ++ iplug = item_plugin_by_id(CTAIL_ID); ++ ++ assert("edward-924", !tfm_cluster_is_uptodate(&clust->tc)); ++ ++#if REISER4_DEBUG ++ if (clust->nr_pages == 0) { ++ /* start write hole from fake disk cluster */ ++ assert("edward-1117", win != NULL); ++ assert("edward-1118", win->stat == HOLE_WINDOW); ++ assert("edward-1119", new_logical_cluster(clust, inode)); ++ } ++#endif ++ if (new_logical_cluster(clust, inode)) { ++ /* ++ new page cluster is about to be written, nothing to read, ++ */ ++ assert("edward-734", reiser4_schedulable()); ++ assert("edward-735", clust->hint->lh.owner == NULL); ++ ++ if (clust->nr_pages) { ++ int off; ++ struct page * pg; ++ assert("edward-1419", clust->pages != NULL); ++ pg = clust->pages[clust->nr_pages - 1]; ++ assert("edward-1420", pg != NULL); ++ off = off_to_pgoff(win->off+win->count+win->delta); ++ if (off) { ++ lock_page(pg); ++ zero_user_segment(pg, off, PAGE_CACHE_SIZE); ++ unlock_page(pg); ++ } ++ } ++ clust->dstat = FAKE_DISK_CLUSTER; ++ return 0; ++ } ++ /* ++ Here we should search for disk cluster to figure out its real state. ++ Also there is one more important reason to do disk search: we need ++ to make disk cluster _dirty_ if it exists ++ */ ++ ++ /* if windows is specified, read the only pages ++ that will be modified partially */ ++ ++ for (i = 0; i < clust->nr_pages; i++) { ++ struct page *pg = clust->pages[i]; ++ ++ lock_page(pg); ++ if (PageUptodate(pg)) { ++ unlock_page(pg); ++ continue; ++ } ++ unlock_page(pg); ++ ++ if (win && ++ i >= size_in_pages(win->off) && ++ i < off_to_pg(win->off + win->count + win->delta)) ++ /* page will be completely overwritten */ ++ continue; ++ ++ if (win && (i == clust->nr_pages - 1) && ++ /* the last page is ++ partially modified, ++ not uptodate .. */ ++ (size_in_pages(i_size_read(inode)) <= pg->index)) { ++ /* .. and appended, ++ so set zeroes to the rest */ ++ int offset; ++ lock_page(pg); ++ assert("edward-1260", ++ size_in_pages(win->off + win->count + ++ win->delta) - 1 == i); ++ ++ offset = ++ off_to_pgoff(win->off + win->count + win->delta); ++ zero_user_segment(pg, offset, PAGE_CACHE_SIZE); ++ unlock_page(pg); ++ /* still not uptodate */ ++ break; ++ } ++ lock_page(pg); ++ result = do_readpage_ctail(inode, clust, pg, mode); ++ ++ assert("edward-1526", ergo(!result, PageUptodate(pg))); ++ unlock_page(pg); ++ if (result) { ++ warning("edward-219", "do_readpage_ctail failed"); ++ goto out; ++ } ++ } ++ if (!tfm_cluster_is_uptodate(&clust->tc)) { ++ /* disk cluster unclaimed, but we need to make its znodes dirty ++ * to make flush update convert its content ++ */ ++ result = find_disk_cluster(clust, inode, ++ 0 /* do not read items */, ++ mode); ++ } ++ out: ++ tfm_cluster_clr_uptodate(&clust->tc); ++ return result; ++} ++ ++static int should_create_unprepped_cluster(struct cluster_handle * clust, ++ struct inode * inode) ++{ ++ assert("edward-737", clust != NULL); ++ ++ switch (clust->dstat) { ++ case PREP_DISK_CLUSTER: ++ case UNPR_DISK_CLUSTER: ++ return 0; ++ case FAKE_DISK_CLUSTER: ++ if (clust->win && ++ clust->win->stat == HOLE_WINDOW && clust->nr_pages == 0) { ++ assert("edward-1172", ++ new_logical_cluster(clust, inode)); ++ return 0; ++ } ++ return 1; ++ default: ++ impossible("edward-1173", "bad disk cluster state"); ++ return 0; ++ } ++} ++ ++static int cryptcompress_make_unprepped_cluster(struct cluster_handle * clust, ++ struct inode *inode) ++{ ++ int result; ++ ++ assert("edward-1123", reiser4_schedulable()); ++ assert("edward-737", clust != NULL); ++ assert("edward-738", inode != NULL); ++ assert("edward-739", cryptcompress_inode_ok(inode)); ++ assert("edward-1053", clust->hint != NULL); ++ ++ if (!should_create_unprepped_cluster(clust, inode)) { ++ if (clust->reserved) { ++ cluster_reserved2free(estimate_insert_cluster(inode)); ++#if REISER4_DEBUG ++ assert("edward-1267", ++ clust->reserved_unprepped == ++ estimate_insert_cluster(inode)); ++ clust->reserved_unprepped -= ++ estimate_insert_cluster(inode); ++#endif ++ } ++ return 0; ++ } ++ assert("edward-1268", clust->reserved); ++ cluster_reserved2grabbed(estimate_insert_cluster(inode)); ++#if REISER4_DEBUG ++ assert("edward-1441", ++ clust->reserved_unprepped == estimate_insert_cluster(inode)); ++ clust->reserved_unprepped -= estimate_insert_cluster(inode); ++#endif ++ result = ctail_insert_unprepped_cluster(clust, inode); ++ if (result) ++ return result; ++ ++ inode_add_bytes(inode, inode_cluster_size(inode)); ++ ++ assert("edward-743", cryptcompress_inode_ok(inode)); ++ assert("edward-744", znode_is_write_locked(clust->hint->lh.node)); ++ ++ clust->dstat = UNPR_DISK_CLUSTER; ++ return 0; ++} ++ ++/* . Grab page cluster for read, write, setattr, etc. operations; ++ * . Truncate its complete pages, if needed; ++ */ ++int prepare_page_cluster(struct inode * inode, struct cluster_handle * clust, ++ rw_op rw) ++{ ++ assert("edward-177", inode != NULL); ++ assert("edward-741", cryptcompress_inode_ok(inode)); ++ assert("edward-740", clust->pages != NULL); ++ ++ set_cluster_nrpages(clust, inode); ++ reset_cluster_pgset(clust, cluster_nrpages(inode)); ++ return grab_page_cluster(inode, clust, rw); ++} ++ ++/* Truncate complete page cluster of index @index. ++ * This is called by ->kill_hook() method of item ++ * plugin when deleting a disk cluster of such index. ++ */ ++void truncate_complete_page_cluster(struct inode *inode, cloff_t index, ++ int even_cows) ++{ ++ int found; ++ int nr_pages; ++ jnode *node; ++ struct page *pages[MAX_CLUSTER_NRPAGES]; ++ ++ node = jlookup(current_tree, get_inode_oid(inode), ++ clust_to_pg(index, inode)); ++ nr_pages = size_in_pages(lbytes(index, inode)); ++ assert("edward-1483", nr_pages != 0); ++ if (!node) ++ goto truncate; ++ found = find_get_pages(inode->i_mapping, ++ clust_to_pg(index, inode), ++ cluster_nrpages(inode), pages); ++ if (!found) { ++ assert("edward-1484", jnode_truncate_ok(inode, index)); ++ return; ++ } ++ lock_cluster(node); ++ ++ if (reiser4_inode_get_flag(inode, REISER4_FILE_CONV_IN_PROGRESS) ++ && index == 0) ++ /* converting to unix_file is in progress */ ++ JF_CLR(node, JNODE_CLUSTER_PAGE); ++ if (JF_ISSET(node, JNODE_DIRTY)) { ++ /* ++ * @nr_pages were checked in, but not yet checked out - ++ * we need to release them. (also there can be pages ++ * attached to page cache by read(), etc. - don't take ++ * them into account). ++ */ ++ assert("edward-1198", found >= nr_pages); ++ ++ /* free disk space grabbed for disk cluster converting */ ++ cluster_reserved2grabbed(estimate_update_cluster(inode)); ++ grabbed2free(get_current_context(), ++ get_current_super_private(), ++ estimate_update_cluster(inode)); ++ __put_page_cluster(0, nr_pages, pages, inode); ++ ++ /* This will clear dirty bit, uncapture and unlock jnode */ ++ unlock_cluster_uncapture(node); ++ } else ++ unlock_cluster(node); ++ jput(node); /* jlookup */ ++ put_found_pages(pages, found); /* find_get_pages */ ++ truncate: ++ if (reiser4_inode_get_flag(inode, REISER4_FILE_CONV_IN_PROGRESS) && ++ index == 0) ++ return; ++ truncate_page_cluster_range(inode, pages, index, 0, ++ cluster_nrpages(inode), ++ even_cows); ++ assert("edward-1201", ++ ergo(!reiser4_inode_get_flag(inode, ++ REISER4_FILE_CONV_IN_PROGRESS), ++ jnode_truncate_ok(inode, index))); ++ return; ++} ++ ++/* ++ * Set cluster handle @clust of a logical cluster before ++ * modifications which are supposed to be committed. ++ * ++ * . grab cluster pages; ++ * . reserve disk space; ++ * . maybe read pages from disk and set the disk cluster dirty; ++ * . maybe write hole and check in (partially zeroed) logical cluster; ++ * . create 'unprepped' disk cluster for new or fake logical one. ++ */ ++static int prepare_logical_cluster(struct inode *inode, ++ loff_t file_off, /* write position ++ in the file */ ++ loff_t to_file, /* bytes of users data ++ to write to the file */ ++ struct cluster_handle * clust, ++ logical_cluster_op op) ++{ ++ int result = 0; ++ struct reiser4_slide * win = clust->win; ++ ++ reset_cluster_params(clust); ++ cluster_set_tfm_act(&clust->tc, TFMA_READ); ++#if REISER4_DEBUG ++ clust->ctx = get_current_context(); ++#endif ++ assert("edward-1190", op != LC_INVAL); ++ ++ clust->op = op; ++ ++ result = prepare_page_cluster(inode, clust, WRITE_OP); ++ if (result) ++ return result; ++ assert("edward-1447", ++ ergo(clust->nr_pages != 0, jprivate(clust->pages[0]))); ++ assert("edward-1448", ++ ergo(clust->nr_pages != 0, ++ jnode_is_cluster_page(jprivate(clust->pages[0])))); ++ ++ result = reserve4cluster(inode, clust); ++ if (result) ++ goto err1; ++ result = read_some_cluster_pages(inode, clust); ++ if (result) { ++ free_reserved4cluster(inode, ++ clust, ++ estimate_update_cluster(inode) + ++ estimate_insert_cluster(inode)); ++ goto err1; ++ } ++ assert("edward-1124", clust->dstat != INVAL_DISK_CLUSTER); ++ ++ result = cryptcompress_make_unprepped_cluster(clust, inode); ++ if (result) ++ goto err2; ++ if (win && win->stat == HOLE_WINDOW) { ++ result = write_hole(inode, clust, file_off, to_file); ++ if (result) ++ goto err2; ++ } ++ return 0; ++ err2: ++ free_reserved4cluster(inode, clust, ++ estimate_update_cluster(inode)); ++ err1: ++ put_page_cluster(clust, inode, WRITE_OP); ++ assert("edward-1125", result == -ENOSPC); ++ return result; ++} ++ ++/* set window by two offsets */ ++static void set_window(struct cluster_handle * clust, ++ struct reiser4_slide * win, struct inode *inode, ++ loff_t o1, loff_t o2) ++{ ++ assert("edward-295", clust != NULL); ++ assert("edward-296", inode != NULL); ++ assert("edward-1071", win != NULL); ++ assert("edward-297", o1 <= o2); ++ ++ clust->index = off_to_clust(o1, inode); ++ ++ win->off = off_to_cloff(o1, inode); ++ win->count = min((loff_t)(inode_cluster_size(inode) - win->off), ++ o2 - o1); ++ win->delta = 0; ++ ++ clust->win = win; ++} ++ ++static int set_cluster_by_window(struct inode *inode, ++ struct cluster_handle * clust, ++ struct reiser4_slide * win, size_t length, ++ loff_t file_off) ++{ ++ int result; ++ ++ assert("edward-197", clust != NULL); ++ assert("edward-1072", win != NULL); ++ assert("edward-198", inode != NULL); ++ ++ result = alloc_cluster_pgset(clust, cluster_nrpages(inode)); ++ if (result) ++ return result; ++ ++ if (file_off > i_size_read(inode)) { ++ /* Uhmm, hole in cryptcompress file... */ ++ loff_t hole_size; ++ hole_size = file_off - inode->i_size; ++ ++ set_window(clust, win, inode, inode->i_size, file_off); ++ win->stat = HOLE_WINDOW; ++ if (win->off + hole_size < inode_cluster_size(inode)) ++ /* there is also user's data to append to the hole */ ++ win->delta = min(inode_cluster_size(inode) - ++ (win->off + win->count), length); ++ return 0; ++ } ++ set_window(clust, win, inode, file_off, file_off + length); ++ win->stat = DATA_WINDOW; ++ return 0; ++} ++ ++int set_cluster_by_page(struct cluster_handle * clust, struct page * page, ++ int count) ++{ ++ int result = 0; ++ int (*setting_actor)(struct cluster_handle * clust, int count); ++ ++ assert("edward-1358", clust != NULL); ++ assert("edward-1359", page != NULL); ++ assert("edward-1360", page->mapping != NULL); ++ assert("edward-1361", page->mapping->host != NULL); ++ ++ setting_actor = ++ (clust->pages ? reset_cluster_pgset : alloc_cluster_pgset); ++ result = setting_actor(clust, count); ++ clust->index = pg_to_clust(page->index, page->mapping->host); ++ return result; ++} ++ ++/* reset all the params that not get updated */ ++void reset_cluster_params(struct cluster_handle * clust) ++{ ++ assert("edward-197", clust != NULL); ++ ++ clust->dstat = INVAL_DISK_CLUSTER; ++ clust->tc.uptodate = 0; ++ clust->tc.len = 0; ++} ++ ++/* the heart of write_cryptcompress */ ++static loff_t do_write_cryptcompress(struct file *file, struct inode *inode, ++ const char __user *buf, size_t to_write, ++ loff_t pos, struct psched_context *cont) ++{ ++ int i; ++ hint_t *hint; ++ int result = 0; ++ size_t count; ++ struct reiser4_slide win; ++ struct cluster_handle clust; ++ struct cryptcompress_info * info; ++ ++ assert("edward-154", buf != NULL); ++ assert("edward-161", reiser4_schedulable()); ++ assert("edward-748", cryptcompress_inode_ok(inode)); ++ assert("edward-159", current_blocksize == PAGE_CACHE_SIZE); ++ assert("edward-1274", get_current_context()->grabbed_blocks == 0); ++ ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) ++ return RETERR(-ENOMEM); ++ ++ result = load_file_hint(file, hint); ++ if (result) { ++ kfree(hint); ++ return result; ++ } ++ count = to_write; ++ ++ reiser4_slide_init(&win); ++ cluster_init_read(&clust, &win); ++ clust.hint = hint; ++ info = cryptcompress_inode_data(inode); ++ ++ mutex_lock(&info->checkin_mutex); ++ ++ result = set_cluster_by_window(inode, &clust, &win, to_write, pos); ++ if (result) ++ goto out; ++ ++ if (next_window_stat(&win) == HOLE_WINDOW) { ++ /* write hole in this iteration ++ separated from the loop below */ ++ result = write_pschedule_hook(file, inode, ++ pos, ++ &clust, ++ cont); ++ if (result) ++ goto out; ++ result = prepare_logical_cluster(inode, pos, count, &clust, ++ LC_APPOV); ++ if (result) ++ goto out; ++ } ++ do { ++ const char __user * src; ++ unsigned page_off, to_page; ++ ++ assert("edward-750", reiser4_schedulable()); ++ ++ result = write_pschedule_hook(file, inode, ++ pos + to_write - count, ++ &clust, ++ cont); ++ if (result) ++ goto out; ++ if (cont->state == PSCHED_ASSIGNED_NEW) ++ /* done_lh was called in write_pschedule_hook */ ++ goto out_no_longterm_lock; ++ ++ result = prepare_logical_cluster(inode, pos, count, &clust, ++ LC_APPOV); ++ if (result) ++ goto out; ++ ++ assert("edward-751", cryptcompress_inode_ok(inode)); ++ assert("edward-204", win.stat == DATA_WINDOW); ++ assert("edward-1288", hint_is_valid(clust.hint)); ++ assert("edward-752", ++ znode_is_write_locked(hint->ext_coord.coord.node)); ++ put_hint_cluster(&clust, inode, ZNODE_WRITE_LOCK); ++ ++ /* set write position in page */ ++ page_off = off_to_pgoff(win.off); ++ ++ /* copy user's data to cluster pages */ ++ for (i = off_to_pg(win.off), src = buf; ++ i < size_in_pages(win.off + win.count); ++ i++, src += to_page) { ++ to_page = __mbp(win.off + win.count, i) - page_off; ++ assert("edward-1039", ++ page_off + to_page <= PAGE_CACHE_SIZE); ++ assert("edward-287", clust.pages[i] != NULL); ++ ++ fault_in_pages_readable(src, to_page); ++ ++ lock_page(clust.pages[i]); ++ result = ++ __copy_from_user((char *)kmap(clust.pages[i]) + ++ page_off, src, to_page); ++ kunmap(clust.pages[i]); ++ if (unlikely(result)) { ++ unlock_page(clust.pages[i]); ++ result = -EFAULT; ++ goto err2; ++ } ++ SetPageUptodate(clust.pages[i]); ++ set_page_dirty_notag(clust.pages[i]); ++ flush_dcache_page(clust.pages[i]); ++ mark_page_accessed(clust.pages[i]); ++ unlock_page(clust.pages[i]); ++ page_off = 0; ++ } ++ assert("edward-753", cryptcompress_inode_ok(inode)); ++ ++ result = checkin_logical_cluster(&clust, inode); ++ if (result) ++ goto err2; ++ ++ buf += win.count; ++ count -= win.count; ++ ++ result = balance_dirty_page_cluster(&clust, inode, 0, count, ++ win_count_to_nrpages(&win)); ++ if (result) ++ goto err1; ++ assert("edward-755", hint->lh.owner == NULL); ++ reset_cluster_params(&clust); ++ continue; ++ err2: ++ put_page_cluster(&clust, inode, WRITE_OP); ++ err1: ++ if (clust.reserved) ++ free_reserved4cluster(inode, ++ &clust, ++ estimate_update_cluster(inode)); ++ break; ++ } while (count); ++ out: ++ done_lh(&hint->lh); ++ save_file_hint(file, hint); ++ out_no_longterm_lock: ++ mutex_unlock(&info->checkin_mutex); ++ kfree(hint); ++ put_cluster_handle(&clust); ++ assert("edward-195", ++ ergo((to_write == count), ++ (result < 0 || cont->state == PSCHED_ASSIGNED_NEW))); ++ return (to_write - count) ? (to_write - count) : result; ++} ++ ++/** ++ * plugin->write() ++ * @file: file to write to ++ * @buf: address of user-space buffer ++ * @read_amount: number of bytes to write ++ * @off: position in file to write to ++ */ ++ssize_t write_cryptcompress(struct file *file, const char __user *buf, ++ size_t count, loff_t *off, ++ struct psched_context *cont) ++{ ++ ssize_t result; ++ struct inode *inode; ++ reiser4_context *ctx; ++ loff_t pos = *off; ++ struct cryptcompress_info *info; ++ ++ assert("edward-1449", cont->state == PSCHED_INVAL_STATE); ++ ++ inode = file->f_dentry->d_inode; ++ assert("edward-196", cryptcompress_inode_ok(inode)); ++ ++ info = cryptcompress_inode_data(inode); ++ ctx = get_current_context(); ++ ++ result = generic_write_checks(file, &pos, &count, 0); ++ if (unlikely(result != 0)) { ++ context_set_commit_async(ctx); ++ return result; ++ } ++ if (unlikely(count == 0)) ++ return 0; ++ result = file_remove_suid(file); ++ if (unlikely(result != 0)) { ++ context_set_commit_async(ctx); ++ return result; ++ } ++ /* remove_suid might create a transaction */ ++ reiser4_txn_restart(ctx); ++ ++ result = do_write_cryptcompress(file, inode, buf, count, pos, cont); ++ ++ if (unlikely(result < 0)) { ++ context_set_commit_async(ctx); ++ return result; ++ } ++ /* update position in a file */ ++ *off = pos + result; ++ return result; ++} ++ ++/* plugin->readpages */ ++int readpages_cryptcompress(struct file *file, struct address_space *mapping, ++ struct list_head *pages, unsigned nr_pages) ++{ ++ reiser4_context * ctx; ++ int ret; ++ ++ ctx = reiser4_init_context(mapping->host->i_sb); ++ if (IS_ERR(ctx)) { ++ ret = PTR_ERR(ctx); ++ goto err; ++ } ++ /* cryptcompress file can be built of ctail items only */ ++ ret = readpages_ctail(file, mapping, pages); ++ reiser4_txn_restart(ctx); ++ reiser4_exit_context(ctx); ++ if (ret) { ++err: ++ put_pages_list(pages); ++ } ++ return ret; ++} ++ ++static reiser4_block_nr cryptcompress_estimate_read(struct inode *inode) ++{ ++ /* reserve one block to update stat data item */ ++ assert("edward-1193", ++ inode_file_plugin(inode)->estimate.update == ++ estimate_update_common); ++ return estimate_update_common(inode); ++} ++ ++/** ++ * plugin->read ++ * @file: file to read from ++ * @buf: address of user-space buffer ++ * @read_amount: number of bytes to read ++ * @off: position in file to read from ++ */ ++ssize_t read_cryptcompress(struct file * file, char __user *buf, size_t size, ++ loff_t * off) ++{ ++ ssize_t result; ++ struct inode *inode; ++ reiser4_context *ctx; ++ struct cryptcompress_info *info; ++ reiser4_block_nr needed; ++ ++ inode = file->f_dentry->d_inode; ++ assert("edward-1194", !reiser4_inode_get_flag(inode, REISER4_NO_SD)); ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ info = cryptcompress_inode_data(inode); ++ needed = cryptcompress_estimate_read(inode); ++ ++ result = reiser4_grab_space(needed, BA_CAN_COMMIT); ++ if (result != 0) { ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ result = do_sync_read(file, buf, size, off); ++ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ ++ return result; ++} ++ ++/* Look for a disk cluster and keep lookup result in @found. ++ * If @index > 0, then find disk cluster of the index (@index - 1); ++ * If @index == 0, then find the rightmost disk cluster. ++ * Keep incremented index of the found disk cluster in @found. ++ * @found == 0 means that disk cluster was not found (in the last ++ * case (@index == 0) it means that file doesn't have disk clusters). ++ */ ++static int lookup_disk_cluster(struct inode *inode, cloff_t * found, ++ cloff_t index) ++{ ++ int result; ++ reiser4_key key; ++ loff_t offset; ++ hint_t *hint; ++ lock_handle *lh; ++ lookup_bias bias; ++ coord_t *coord; ++ item_plugin *iplug; ++ ++ assert("edward-1131", inode != NULL); ++ assert("edward-95", cryptcompress_inode_ok(inode)); ++ ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) ++ return RETERR(-ENOMEM); ++ hint_init_zero(hint); ++ lh = &hint->lh; ++ ++ bias = (index ? FIND_EXACT : FIND_MAX_NOT_MORE_THAN); ++ offset = ++ (index ? clust_to_off(index, inode) - ++ 1 : get_key_offset(reiser4_max_key())); ++ ++ key_by_inode_cryptcompress(inode, offset, &key); ++ ++ /* find the last item of this object */ ++ result = ++ find_cluster_item(hint, &key, ZNODE_READ_LOCK, NULL /* ra_info */, ++ bias, 0); ++ if (cbk_errored(result)) { ++ done_lh(lh); ++ kfree(hint); ++ return result; ++ } ++ if (result == CBK_COORD_NOTFOUND) { ++ /* no real disk clusters */ ++ done_lh(lh); ++ kfree(hint); ++ *found = 0; ++ return 0; ++ } ++ /* disk cluster is found */ ++ coord = &hint->ext_coord.coord; ++ coord_clear_iplug(coord); ++ result = zload(coord->node); ++ if (unlikely(result)) { ++ done_lh(lh); ++ kfree(hint); ++ return result; ++ } ++ iplug = item_plugin_by_coord(coord); ++ assert("edward-277", iplug == item_plugin_by_id(CTAIL_ID)); ++ assert("edward-1202", ctail_ok(coord)); ++ ++ item_key_by_coord(coord, &key); ++ *found = off_to_clust(get_key_offset(&key), inode) + 1; ++ ++ assert("edward-1132", ergo(index, index == *found)); ++ ++ zrelse(coord->node); ++ done_lh(lh); ++ kfree(hint); ++ return 0; ++} ++ ++static int find_fake_appended(struct inode *inode, cloff_t * index) ++{ ++ return lookup_disk_cluster(inode, index, ++ 0 /* find last real one */ ); ++} ++ ++/* Set left coord when unit is not found after node_lookup() ++ This takes into account that there can be holes in a sequence ++ of disk clusters */ ++ ++static void adjust_left_coord(coord_t * left_coord) ++{ ++ switch (left_coord->between) { ++ case AFTER_UNIT: ++ left_coord->between = AFTER_ITEM; ++ case AFTER_ITEM: ++ case BEFORE_UNIT: ++ break; ++ default: ++ impossible("edward-1204", "bad left coord to cut"); ++ } ++ return; ++} ++ ++#define CRC_CUT_TREE_MIN_ITERATIONS 64 ++ ++/* plugin->cut_tree_worker */ ++int cut_tree_worker_cryptcompress(tap_t * tap, const reiser4_key * from_key, ++ const reiser4_key * to_key, ++ reiser4_key * smallest_removed, ++ struct inode *object, int truncate, ++ int *progress) ++{ ++ lock_handle next_node_lock; ++ coord_t left_coord; ++ int result; ++ ++ assert("edward-1158", tap->coord->node != NULL); ++ assert("edward-1159", znode_is_write_locked(tap->coord->node)); ++ assert("edward-1160", znode_get_level(tap->coord->node) == LEAF_LEVEL); ++ ++ *progress = 0; ++ init_lh(&next_node_lock); ++ ++ while (1) { ++ znode *node; /* node from which items are cut */ ++ node_plugin *nplug; /* node plugin for @node */ ++ ++ node = tap->coord->node; ++ ++ /* Move next_node_lock to the next node on the left. */ ++ result = ++ reiser4_get_left_neighbor(&next_node_lock, node, ++ ZNODE_WRITE_LOCK, ++ GN_CAN_USE_UPPER_LEVELS); ++ if (result != 0 && result != -E_NO_NEIGHBOR) ++ break; ++ /* FIXME-EDWARD: Check can we delete the node as a whole. */ ++ result = reiser4_tap_load(tap); ++ if (result) ++ return result; ++ ++ /* Prepare the second (right) point for cut_node() */ ++ if (*progress) ++ coord_init_last_unit(tap->coord, node); ++ ++ else if (item_plugin_by_coord(tap->coord)->b.lookup == NULL) ++ /* set rightmost unit for the items without lookup method */ ++ tap->coord->unit_pos = coord_last_unit_pos(tap->coord); ++ ++ nplug = node->nplug; ++ ++ assert("edward-1161", nplug); ++ assert("edward-1162", nplug->lookup); ++ ++ /* left_coord is leftmost unit cut from @node */ ++ result = nplug->lookup(node, from_key, FIND_EXACT, &left_coord); ++ ++ if (IS_CBKERR(result)) ++ break; ++ ++ if (result == CBK_COORD_NOTFOUND) ++ adjust_left_coord(&left_coord); ++ ++ /* adjust coordinates so that they are set to existing units */ ++ if (coord_set_to_right(&left_coord) ++ || coord_set_to_left(tap->coord)) { ++ result = 0; ++ break; ++ } ++ ++ if (coord_compare(&left_coord, tap->coord) == ++ COORD_CMP_ON_RIGHT) { ++ /* keys from @from_key to @to_key are not in the tree */ ++ result = 0; ++ break; ++ } ++ ++ /* cut data from one node */ ++ *smallest_removed = *reiser4_min_key(); ++ result = kill_node_content(&left_coord, ++ tap->coord, ++ from_key, ++ to_key, ++ smallest_removed, ++ next_node_lock.node, ++ object, truncate); ++ reiser4_tap_relse(tap); ++ ++ if (result) ++ break; ++ ++ ++(*progress); ++ ++ /* Check whether all items with keys >= from_key were removed ++ * from the tree. */ ++ if (keyle(smallest_removed, from_key)) ++ /* result = 0; */ ++ break; ++ ++ if (next_node_lock.node == NULL) ++ break; ++ ++ result = reiser4_tap_move(tap, &next_node_lock); ++ done_lh(&next_node_lock); ++ if (result) ++ break; ++ ++ /* Break long cut_tree operation (deletion of a large file) if ++ * atom requires commit. */ ++ if (*progress > CRC_CUT_TREE_MIN_ITERATIONS ++ && current_atom_should_commit()) { ++ result = -E_REPEAT; ++ break; ++ } ++ } ++ done_lh(&next_node_lock); ++ return result; ++} ++ ++/* Append or expand hole in two steps: ++ * 1) set zeroes to the rightmost page of the rightmost non-fake ++ * logical cluster; ++ * 2) expand hole via fake logical clusters (just increase i_size) ++ */ ++static int cryptcompress_append_hole(struct inode *inode /* with old size */, ++ loff_t new_size) ++{ ++ int result = 0; ++ hint_t *hint; ++ lock_handle *lh; ++ loff_t hole_size; ++ int nr_zeroes; ++ struct reiser4_slide win; ++ struct cluster_handle clust; ++ ++ assert("edward-1133", inode->i_size < new_size); ++ assert("edward-1134", reiser4_schedulable()); ++ assert("edward-1135", cryptcompress_inode_ok(inode)); ++ assert("edward-1136", current_blocksize == PAGE_CACHE_SIZE); ++ assert("edward-1333", off_to_cloff(inode->i_size, inode) != 0); ++ ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) ++ return RETERR(-ENOMEM); ++ hint_init_zero(hint); ++ lh = &hint->lh; ++ ++ reiser4_slide_init(&win); ++ cluster_init_read(&clust, &win); ++ clust.hint = hint; ++ ++ result = alloc_cluster_pgset(&clust, cluster_nrpages(inode)); ++ if (result) ++ goto out; ++ if (off_to_cloff(inode->i_size, inode) == 0) ++ goto append_fake; ++ hole_size = new_size - inode->i_size; ++ nr_zeroes = ++ inode_cluster_size(inode) - off_to_cloff(inode->i_size, inode); ++ if (hole_size < nr_zeroes) ++ nr_zeroes = hole_size; ++ set_window(&clust, &win, inode, inode->i_size, ++ inode->i_size + nr_zeroes); ++ win.stat = HOLE_WINDOW; ++ ++ assert("edward-1137", ++ clust.index == off_to_clust(inode->i_size, inode)); ++ ++ result = prepare_logical_cluster(inode, 0, 0, &clust, LC_APPOV); ++ ++ assert("edward-1271", !result || result == -ENOSPC); ++ if (result) ++ goto out; ++ assert("edward-1139", ++ clust.dstat == PREP_DISK_CLUSTER || ++ clust.dstat == UNPR_DISK_CLUSTER); ++ ++ assert("edward-1431", hole_size >= nr_zeroes); ++ if (hole_size == nr_zeroes) ++ /* nothing to append anymore */ ++ goto out; ++ append_fake: ++ INODE_SET_SIZE(inode, new_size); ++ out: ++ done_lh(lh); ++ kfree(hint); ++ put_cluster_handle(&clust); ++ return result; ++} ++ ++static int update_cryptcompress_size(struct inode *inode, loff_t new_size, ++ int update_sd) ++{ ++ return (new_size & ((loff_t) (inode_cluster_size(inode)) - 1) ++ ? 0 : reiser4_update_file_size(inode, new_size, update_sd)); ++} ++ ++/* Prune cryptcompress file in two steps: ++ * 1) cut all nominated logical clusters except the leftmost one which ++ * is to be partially truncated. Note, that there can be "holes" ++ * represented by fake logical clusters. ++ * 2) set zeroes and capture leftmost partially truncated logical ++ * cluster, if it is not fake; otherwise prune fake logical cluster ++ * (just decrease i_size). ++ */ ++static int prune_cryptcompress(struct inode *inode, loff_t new_size, ++ int update_sd, cloff_t aidx) ++{ ++ int result = 0; ++ unsigned nr_zeroes; ++ loff_t to_prune; ++ loff_t old_size; ++ cloff_t ridx; ++ ++ hint_t *hint; ++ lock_handle *lh; ++ struct reiser4_slide win; ++ struct cluster_handle clust; ++ ++ assert("edward-1140", inode->i_size >= new_size); ++ assert("edward-1141", reiser4_schedulable()); ++ assert("edward-1142", cryptcompress_inode_ok(inode)); ++ assert("edward-1143", current_blocksize == PAGE_CACHE_SIZE); ++ ++ old_size = inode->i_size; ++ ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) ++ return RETERR(-ENOMEM); ++ hint_init_zero(hint); ++ lh = &hint->lh; ++ ++ reiser4_slide_init(&win); ++ cluster_init_read(&clust, &win); ++ clust.hint = hint; ++ ++ /* calculate index of the rightmost logical cluster ++ that will be completely truncated */ ++ ridx = size_in_lc(new_size, inode); ++ ++ /* truncate all disk clusters starting from @ridx */ ++ assert("edward-1174", ridx <= aidx); ++ old_size = inode->i_size; ++ if (ridx != aidx) { ++ struct cryptcompress_info * info; ++ info = cryptcompress_inode_data(inode); ++ result = cut_file_items(inode, ++ clust_to_off(ridx, inode), ++ update_sd, ++ clust_to_off(aidx, inode), ++ update_cryptcompress_size); ++ info->trunc_index = ULONG_MAX; ++ if (result) ++ goto out; ++ } ++ /* ++ * there can be pages of fake logical clusters, truncate them ++ */ ++ truncate_inode_pages(inode->i_mapping, clust_to_off(ridx, inode)); ++ assert("edward-1524", ++ pages_truncate_ok(inode, clust_to_pg(ridx, inode))); ++ /* ++ * now perform partial truncate of last logical cluster ++ */ ++ if (!off_to_cloff(new_size, inode)) { ++ /* no partial truncate is needed */ ++ assert("edward-1145", inode->i_size == new_size); ++ goto truncate_fake; ++ } ++ assert("edward-1146", new_size < inode->i_size); ++ ++ to_prune = inode->i_size - new_size; ++ ++ /* check if the last logical cluster is fake */ ++ result = lookup_disk_cluster(inode, &aidx, ridx); ++ if (result) ++ goto out; ++ if (!aidx) ++ /* yup, this is fake one */ ++ goto truncate_fake; ++ ++ assert("edward-1148", aidx == ridx); ++ ++ /* do partial truncate of the last page cluster, ++ and try to capture this one */ ++ result = alloc_cluster_pgset(&clust, cluster_nrpages(inode)); ++ if (result) ++ goto out; ++ nr_zeroes = (off_to_pgoff(new_size) ? ++ PAGE_CACHE_SIZE - off_to_pgoff(new_size) : 0); ++ set_window(&clust, &win, inode, new_size, new_size + nr_zeroes); ++ win.stat = HOLE_WINDOW; ++ ++ assert("edward-1149", clust.index == ridx - 1); ++ ++ result = prepare_logical_cluster(inode, 0, 0, &clust, LC_TRUNC); ++ if (result) ++ goto out; ++ assert("edward-1151", ++ clust.dstat == PREP_DISK_CLUSTER || ++ clust.dstat == UNPR_DISK_CLUSTER); ++ ++ assert("edward-1191", inode->i_size == new_size); ++ assert("edward-1206", body_truncate_ok(inode, ridx)); ++ truncate_fake: ++ /* drop all the pages that don't have jnodes (i.e. pages ++ which can not be truncated by cut_file_items() because ++ of holes represented by fake disk clusters) including ++ the pages of partially truncated cluster which was ++ released by prepare_logical_cluster() */ ++ INODE_SET_SIZE(inode, new_size); ++ truncate_inode_pages(inode->i_mapping, new_size); ++ out: ++ assert("edward-1334", !result || result == -ENOSPC); ++ assert("edward-1497", ++ pages_truncate_ok(inode, size_in_pages(new_size))); ++ ++ done_lh(lh); ++ kfree(hint); ++ put_cluster_handle(&clust); ++ return result; ++} ++ ++/* Prepare cryptcompress file for truncate: ++ * prune or append rightmost fake logical clusters (if any) ++ */ ++static int start_truncate_fake(struct inode *inode, cloff_t aidx, ++ loff_t new_size, int update_sd) ++{ ++ int result = 0; ++ int bytes; ++ ++ if (new_size > inode->i_size) { ++ /* append */ ++ if (inode->i_size < clust_to_off(aidx, inode)) ++ /* no fake bytes */ ++ return 0; ++ bytes = new_size - inode->i_size; ++ INODE_SET_SIZE(inode, inode->i_size + bytes); ++ } else { ++ /* prune */ ++ if (inode->i_size <= clust_to_off(aidx, inode)) ++ /* no fake bytes */ ++ return 0; ++ bytes = inode->i_size - ++ max(new_size, clust_to_off(aidx, inode)); ++ if (!bytes) ++ return 0; ++ INODE_SET_SIZE(inode, inode->i_size - bytes); ++ /* In the case of fake prune we need to drop page cluster. ++ There are only 2 cases for partially truncated page: ++ 1. If is is dirty, therefore it is anonymous ++ (was dirtied via mmap), and will be captured ++ later via ->capture(). ++ 2. If is clean, therefore it is filled by zeroes. ++ In both cases we don't need to make it dirty and ++ capture here. ++ */ ++ truncate_inode_pages(inode->i_mapping, inode->i_size); ++ } ++ if (update_sd) ++ result = update_sd_cryptcompress(inode); ++ return result; ++} ++ ++/** ++ * This is called in setattr_cryptcompress when it is used to truncate, ++ * and in delete_object_cryptcompress ++ */ ++static int cryptcompress_truncate(struct inode *inode, /* old size */ ++ loff_t new_size, /* new size */ ++ int update_sd) ++{ ++ int result; ++ cloff_t aidx; ++ ++ result = find_fake_appended(inode, &aidx); ++ if (result) ++ return result; ++ assert("edward-1208", ++ ergo(aidx > 0, inode->i_size > clust_to_off(aidx - 1, inode))); ++ ++ result = start_truncate_fake(inode, aidx, new_size, update_sd); ++ if (result) ++ return result; ++ if (inode->i_size == new_size) ++ /* nothing to truncate anymore */ ++ return 0; ++ result = (inode->i_size < new_size ? ++ cryptcompress_append_hole(inode, new_size) : ++ prune_cryptcompress(inode, new_size, update_sd, aidx)); ++ if (!result && update_sd) ++ result = update_sd_cryptcompress(inode); ++ return result; ++} ++ ++/** ++ * Capture a pager cluster. ++ * @clust must be set up by a caller. ++ */ ++static int capture_page_cluster(struct cluster_handle * clust, ++ struct inode * inode) ++{ ++ int result; ++ ++ assert("edward-1073", clust != NULL); ++ assert("edward-1074", inode != NULL); ++ assert("edward-1075", clust->dstat == INVAL_DISK_CLUSTER); ++ ++ result = prepare_logical_cluster(inode, 0, 0, clust, LC_APPOV); ++ if (result) ++ return result; ++ ++ set_cluster_pages_dirty(clust, inode); ++ result = checkin_logical_cluster(clust, inode); ++ put_hint_cluster(clust, inode, ZNODE_WRITE_LOCK); ++ if (unlikely(result)) ++ put_page_cluster(clust, inode, WRITE_OP); ++ return result; ++} ++ ++/* Starting from @index find tagged pages of the same page cluster. ++ * Clear the tag for each of them. Return number of found pages. ++ */ ++static int find_anon_page_cluster(struct address_space * mapping, ++ pgoff_t * index, struct page ** pages) ++{ ++ int i = 0; ++ int found; ++ spin_lock_irq(&mapping->tree_lock); ++ do { ++ /* looking for one page */ ++ found = radix_tree_gang_lookup_tag(&mapping->page_tree, ++ (void **)&pages[i], ++ *index, 1, ++ PAGECACHE_TAG_REISER4_MOVED); ++ if (!found) ++ break; ++ if (!same_page_cluster(pages[0], pages[i])) ++ break; ++ ++ /* found */ ++ page_cache_get(pages[i]); ++ *index = pages[i]->index + 1; ++ ++ radix_tree_tag_clear(&mapping->page_tree, ++ pages[i]->index, ++ PAGECACHE_TAG_REISER4_MOVED); ++ if (last_page_in_cluster(pages[i++])) ++ break; ++ } while (1); ++ spin_unlock_irq(&mapping->tree_lock); ++ return i; ++} ++ ++#define MAX_PAGES_TO_CAPTURE (1024) ++ ++/* Capture anonymous page clusters */ ++static int capture_anon_pages(struct address_space * mapping, pgoff_t * index, ++ int to_capture) ++{ ++ int count = 0; ++ int found = 0; ++ int result = 0; ++ hint_t *hint; ++ lock_handle *lh; ++ struct inode * inode; ++ struct cluster_handle clust; ++ struct page * pages[MAX_CLUSTER_NRPAGES]; ++ ++ assert("edward-1127", mapping != NULL); ++ assert("edward-1128", mapping->host != NULL); ++ assert("edward-1440", mapping->host->i_mapping == mapping); ++ ++ inode = mapping->host; ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) ++ return RETERR(-ENOMEM); ++ hint_init_zero(hint); ++ lh = &hint->lh; ++ ++ cluster_init_read(&clust, NULL); ++ clust.hint = hint; ++ ++ result = alloc_cluster_pgset(&clust, cluster_nrpages(inode)); ++ if (result) ++ goto out; ++ ++ while (to_capture > 0) { ++ found = find_anon_page_cluster(mapping, index, pages); ++ if (!found) { ++ *index = (pgoff_t) - 1; ++ break; ++ } ++ move_cluster_forward(&clust, inode, pages[0]->index); ++ result = capture_page_cluster(&clust, inode); ++ ++ put_found_pages(pages, found); /* find_anon_page_cluster */ ++ if (result) ++ break; ++ to_capture -= clust.nr_pages; ++ count += clust.nr_pages; ++ } ++ if (result) { ++ warning("edward-1077", ++ "Capture failed (inode %llu, result=%i, captured=%d)\n", ++ (unsigned long long)get_inode_oid(inode), result, count); ++ } else { ++ assert("edward-1078", ergo(found > 0, count > 0)); ++ if (to_capture <= 0) ++ /* there may be left more pages */ ++ __mark_inode_dirty(inode, I_DIRTY_PAGES); ++ result = count; ++ } ++ out: ++ done_lh(lh); ++ kfree(hint); ++ put_cluster_handle(&clust); ++ return result; ++} ++ ++/* Returns true if inode's mapping has dirty pages ++ which do not belong to any atom */ ++static int cryptcompress_inode_has_anon_pages(struct inode *inode) ++{ ++ int result; ++ spin_lock_irq(&inode->i_mapping->tree_lock); ++ result = radix_tree_tagged(&inode->i_mapping->page_tree, ++ PAGECACHE_TAG_REISER4_MOVED); ++ spin_unlock_irq(&inode->i_mapping->tree_lock); ++ return result; ++} ++ ++/* plugin->writepages */ ++int writepages_cryptcompress(struct address_space *mapping, ++ struct writeback_control *wbc) ++{ ++ int result = 0; ++ long to_capture; ++ pgoff_t nrpages; ++ pgoff_t index = 0; ++ struct inode *inode; ++ struct cryptcompress_info *info; ++ ++ inode = mapping->host; ++ if (!cryptcompress_inode_has_anon_pages(inode)) ++ goto end; ++ info = cryptcompress_inode_data(inode); ++ nrpages = size_in_pages(i_size_read(inode)); ++ ++ if (wbc->sync_mode != WB_SYNC_ALL) ++ to_capture = min(wbc->nr_to_write, (long)MAX_PAGES_TO_CAPTURE); ++ else ++ to_capture = MAX_PAGES_TO_CAPTURE; ++ do { ++ reiser4_context *ctx; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) { ++ result = PTR_ERR(ctx); ++ break; ++ } ++ /* avoid recursive calls to ->sync_inodes */ ++ ctx->nobalance = 1; ++ ++ assert("edward-1079", ++ lock_stack_isclean(get_current_lock_stack())); ++ ++ reiser4_txn_restart_current(); ++ ++ if (get_current_context()->entd) { ++ if (mutex_trylock(&info->checkin_mutex) == 0) { ++ /* the mutex might be occupied by ++ entd caller */ ++ result = RETERR(-EBUSY); ++ reiser4_exit_context(ctx); ++ break; ++ } ++ } else ++ mutex_lock(&info->checkin_mutex); ++ ++ result = capture_anon_pages(inode->i_mapping, &index, ++ to_capture); ++ mutex_unlock(&info->checkin_mutex); ++ ++ if (result < 0) { ++ reiser4_exit_context(ctx); ++ break; ++ } ++ wbc->nr_to_write -= result; ++ if (wbc->sync_mode != WB_SYNC_ALL) { ++ reiser4_exit_context(ctx); ++ break; ++ } ++ result = txnmgr_force_commit_all(inode->i_sb, 0); ++ reiser4_exit_context(ctx); ++ } while (result >= 0 && index < nrpages); ++ ++ end: ++ if (is_in_reiser4_context()) { ++ if (get_current_context()->nr_captured >= CAPTURE_APAGE_BURST) { ++ /* there are already pages to flush, flush them out, ++ do not delay until end of reiser4_sync_inodes */ ++ reiser4_writeout(inode->i_sb, wbc); ++ get_current_context()->nr_captured = 0; ++ } ++ } ++ return result; ++} ++ ++/* plugin->ioctl */ ++int ioctl_cryptcompress(struct inode *inode, struct file *filp, ++ unsigned int cmd, unsigned long arg) ++{ ++ return RETERR(-ENOSYS); ++} ++ ++/* plugin->mmap */ ++int mmap_cryptcompress(struct file *file, struct vm_area_struct *vma) ++{ ++ int result; ++ struct inode *inode; ++ reiser4_context *ctx; ++ ++ inode = file->f_dentry->d_inode; ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ /* ++ * generic_file_mmap will do update_atime. Grab space for stat data ++ * update. ++ */ ++ result = reiser4_grab_space_force ++ (inode_file_plugin(inode)->estimate.update(inode), ++ BA_CAN_COMMIT); ++ if (result) { ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ result = generic_file_mmap(file, vma); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/* plugin->delete_object */ ++int delete_object_cryptcompress(struct inode *inode) ++{ ++ int result; ++ struct cryptcompress_info * info; ++ ++ assert("edward-429", inode->i_nlink == 0); ++ ++ reiser4_txn_restart_current(); ++ info = cryptcompress_inode_data(inode); ++ ++ mutex_lock(&info->checkin_mutex); ++ result = cryptcompress_truncate(inode, 0, 0); ++ mutex_unlock(&info->checkin_mutex); ++ ++ if (result) { ++ warning("edward-430", ++ "cannot truncate cryptcompress file %lli: %i", ++ (unsigned long long)get_inode_oid(inode), ++ result); ++ } ++ truncate_inode_pages(inode->i_mapping, 0); ++ assert("edward-1487", pages_truncate_ok(inode, 0)); ++ /* and remove stat data */ ++ return reiser4_delete_object_common(inode); ++} ++ ++/* ++ * plugin->setattr ++ * This implements actual truncate (see comments in reiser4/page_cache.c) ++ */ ++int setattr_cryptcompress(struct dentry *dentry, struct iattr *attr) ++{ ++ int result; ++ struct inode *inode; ++ struct cryptcompress_info * info; ++ ++ inode = dentry->d_inode; ++ info = cryptcompress_inode_data(inode); ++ ++ if (attr->ia_valid & ATTR_SIZE) { ++ if (i_size_read(inode) != attr->ia_size) { ++ reiser4_context *ctx; ++ loff_t old_size; ++ ++ ctx = reiser4_init_context(dentry->d_inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ result = setattr_pschedule_hook(inode); ++ if (result) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ old_size = i_size_read(inode); ++ inode_check_scale(inode, old_size, attr->ia_size); ++ ++ mutex_lock(&info->checkin_mutex); ++ result = cryptcompress_truncate(inode, ++ attr->ia_size, ++ 1/* update sd */); ++ mutex_unlock(&info->checkin_mutex); ++ if (result) { ++ warning("edward-1192", ++ "truncate_cryptcompress failed: oid %lli, " ++ "old size %lld, new size %lld, retval %d", ++ (unsigned long long) ++ get_inode_oid(inode), old_size, ++ attr->ia_size, result); ++ } ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ } else ++ result = 0; ++ } else ++ result = reiser4_setattr_common(dentry, attr); ++ return result; ++} ++ ++/* plugin->release */ ++int release_cryptcompress(struct inode *inode, struct file *file) ++{ ++ reiser4_context *ctx = reiser4_init_context(inode->i_sb); ++ ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ reiser4_free_file_fsdata(file); ++ reiser4_exit_context(ctx); ++ return 0; ++} ++ ++/* plugin->prepare_write */ ++int write_begin_cryptcompress(struct file *file, struct page *page, ++ unsigned from, unsigned to) ++{ ++ return do_prepare_write(file, page, from, to); ++} ++ ++/* plugin->commit_write */ ++int write_end_cryptcompress(struct file *file, struct page *page, ++ unsigned from, unsigned to) ++{ ++ int ret; ++ hint_t *hint; ++ lock_handle *lh; ++ struct inode * inode; ++ struct cluster_handle clust; ++ ++ unlock_page(page); ++ ++ inode = page->mapping->host; ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) ++ return RETERR(-ENOMEM); ++ hint_init_zero(hint); ++ lh = &hint->lh; ++ ++ cluster_init_read(&clust, NULL); ++ clust.hint = hint; ++ ++ ret = alloc_cluster_pgset(&clust, cluster_nrpages(inode)); ++ if (ret) ++ goto out; ++ clust.index = pg_to_clust(page->index, inode); ++ ret = capture_page_cluster(&clust, inode); ++ if (ret) ++ warning("edward-1557", ++ "Capture failed (inode %llu, result=%i)", ++ (unsigned long long)get_inode_oid(inode), ret); ++ out: ++ done_lh(lh); ++ kfree(hint); ++ put_cluster_handle(&clust); ++ return ret; ++} ++ ++/* plugin->bmap */ ++sector_t bmap_cryptcompress(struct address_space *mapping, sector_t lblock) ++{ ++ return -EINVAL; ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file/cryptcompress.h linux-2.6.30/fs/reiser4/plugin/file/cryptcompress.h +--- linux-2.6.30.orig/fs/reiser4/plugin/file/cryptcompress.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file/cryptcompress.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,616 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++/* See http://www.namesys.com/cryptcompress_design.html */ ++ ++#if !defined( __FS_REISER4_CRYPTCOMPRESS_H__ ) ++#define __FS_REISER4_CRYPTCOMPRESS_H__ ++ ++#include "../../page_cache.h" ++#include "../compress/compress.h" ++#include "../crypto/cipher.h" ++ ++#include <linux/pagemap.h> ++ ++#define MIN_CLUSTER_SHIFT PAGE_CACHE_SHIFT ++#define MAX_CLUSTER_SHIFT 16 ++#define MAX_CLUSTER_NRPAGES (1U << MAX_CLUSTER_SHIFT >> PAGE_CACHE_SHIFT) ++#define DC_CHECKSUM_SIZE 4 ++ ++#define MIN_LATTICE_FACTOR 1 ++#define MAX_LATTICE_FACTOR 32 ++ ++/* this mask contains all non-standard plugins that might ++ be present in reiser4-specific part of inode managed by ++ cryptcompress file plugin */ ++#define cryptcompress_mask \ ++ ((1 << PSET_FILE) | \ ++ (1 << PSET_CLUSTER) | \ ++ (1 << PSET_CIPHER) | \ ++ (1 << PSET_DIGEST) | \ ++ (1 << PSET_COMPRESSION) | \ ++ (1 << PSET_COMPRESSION_MODE)) ++ ++#if REISER4_DEBUG ++static inline int cluster_shift_ok(int shift) ++{ ++ return (shift >= MIN_CLUSTER_SHIFT) && (shift <= MAX_CLUSTER_SHIFT); ++} ++#endif ++ ++#if REISER4_DEBUG ++#define INODE_PGCOUNT(inode) \ ++({ \ ++ assert("edward-1530", inode_file_plugin(inode) == \ ++ file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID)); \ ++ atomic_read(&cryptcompress_inode_data(inode)->pgcount); \ ++ }) ++#define INODE_PGCOUNT_INC(inode) \ ++do { \ ++ assert("edward-1531", inode_file_plugin(inode) == \ ++ file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID)); \ ++ atomic_inc(&cryptcompress_inode_data(inode)->pgcount); \ ++} while (0) ++#define INODE_PGCOUNT_DEC(inode) \ ++do { \ ++ if (inode_file_plugin(inode) == \ ++ file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID)) \ ++ atomic_dec(&cryptcompress_inode_data(inode)->pgcount); \ ++} while (0) ++#else ++#define INODE_PGCOUNT(inode) (0) ++#define INODE_PGCOUNT_INC(inode) ++#define INODE_PGCOUNT_DEC(inode) ++#endif /* REISER4_DEBUG */ ++ ++struct tfm_stream { ++ __u8 *data; ++ size_t size; ++}; ++ ++typedef enum { ++ INPUT_STREAM, ++ OUTPUT_STREAM, ++ LAST_STREAM ++} tfm_stream_id; ++ ++typedef struct tfm_stream * tfm_unit[LAST_STREAM]; ++ ++static inline __u8 *ts_data(struct tfm_stream * stm) ++{ ++ assert("edward-928", stm != NULL); ++ return stm->data; ++} ++ ++static inline size_t ts_size(struct tfm_stream * stm) ++{ ++ assert("edward-929", stm != NULL); ++ return stm->size; ++} ++ ++static inline void set_ts_size(struct tfm_stream * stm, size_t size) ++{ ++ assert("edward-930", stm != NULL); ++ ++ stm->size = size; ++} ++ ++static inline int alloc_ts(struct tfm_stream ** stm) ++{ ++ assert("edward-931", stm); ++ assert("edward-932", *stm == NULL); ++ ++ *stm = kzalloc(sizeof(**stm), reiser4_ctx_gfp_mask_get()); ++ if (!*stm) ++ return -ENOMEM; ++ return 0; ++} ++ ++static inline void free_ts(struct tfm_stream * stm) ++{ ++ assert("edward-933", !ts_data(stm)); ++ assert("edward-934", !ts_size(stm)); ++ ++ kfree(stm); ++} ++ ++static inline int alloc_ts_data(struct tfm_stream * stm, size_t size) ++{ ++ assert("edward-935", !ts_data(stm)); ++ assert("edward-936", !ts_size(stm)); ++ assert("edward-937", size != 0); ++ ++ stm->data = reiser4_vmalloc(size); ++ if (!stm->data) ++ return -ENOMEM; ++ set_ts_size(stm, size); ++ return 0; ++} ++ ++static inline void free_ts_data(struct tfm_stream * stm) ++{ ++ assert("edward-938", equi(ts_data(stm), ts_size(stm))); ++ ++ if (ts_data(stm)) ++ vfree(ts_data(stm)); ++ memset(stm, 0, sizeof *stm); ++} ++ ++/* Write modes for item conversion in flush convert phase */ ++typedef enum { ++ CRC_APPEND_ITEM = 1, ++ CRC_OVERWRITE_ITEM = 2, ++ CRC_CUT_ITEM = 3 ++} cryptcompress_write_mode_t; ++ ++typedef enum { ++ LC_INVAL = 0, /* invalid value */ ++ LC_APPOV = 1, /* append and/or overwrite */ ++ LC_TRUNC = 2 /* truncate */ ++} logical_cluster_op; ++ ++/* Transform cluster. ++ * Intermediate state between page cluster and disk cluster ++ * Is used for data transform (compression/encryption) ++ */ ++struct tfm_cluster { ++ coa_set coa; /* compression algorithms info */ ++ tfm_unit tun; /* plain and transformed streams */ ++ tfm_action act; ++ int uptodate; ++ int lsize; /* number of bytes in logical cluster */ ++ int len; /* length of the transform stream */ ++}; ++ ++static inline coa_t get_coa(struct tfm_cluster * tc, reiser4_compression_id id, ++ tfm_action act) ++{ ++ return tc->coa[id][act]; ++} ++ ++static inline void set_coa(struct tfm_cluster * tc, reiser4_compression_id id, ++ tfm_action act, coa_t coa) ++{ ++ tc->coa[id][act] = coa; ++} ++ ++static inline int alloc_coa(struct tfm_cluster * tc, compression_plugin * cplug) ++{ ++ coa_t coa; ++ ++ coa = cplug->alloc(tc->act); ++ if (IS_ERR(coa)) ++ return PTR_ERR(coa); ++ set_coa(tc, cplug->h.id, tc->act, coa); ++ return 0; ++} ++ ++static inline int ++grab_coa(struct tfm_cluster * tc, compression_plugin * cplug) ++{ ++ return (cplug->alloc && !get_coa(tc, cplug->h.id, tc->act) ? ++ alloc_coa(tc, cplug) : 0); ++} ++ ++static inline void free_coa_set(struct tfm_cluster * tc) ++{ ++ tfm_action j; ++ reiser4_compression_id i; ++ compression_plugin *cplug; ++ ++ assert("edward-810", tc != NULL); ++ ++ for (j = 0; j < TFMA_LAST; j++) ++ for (i = 0; i < LAST_COMPRESSION_ID; i++) { ++ if (!get_coa(tc, i, j)) ++ continue; ++ cplug = compression_plugin_by_id(i); ++ assert("edward-812", cplug->free != NULL); ++ cplug->free(get_coa(tc, i, j), j); ++ set_coa(tc, i, j, 0); ++ } ++ return; ++} ++ ++static inline struct tfm_stream * get_tfm_stream(struct tfm_cluster * tc, ++ tfm_stream_id id) ++{ ++ return tc->tun[id]; ++} ++ ++static inline void set_tfm_stream(struct tfm_cluster * tc, ++ tfm_stream_id id, struct tfm_stream * ts) ++{ ++ tc->tun[id] = ts; ++} ++ ++static inline __u8 *tfm_stream_data(struct tfm_cluster * tc, tfm_stream_id id) ++{ ++ return ts_data(get_tfm_stream(tc, id)); ++} ++ ++static inline void set_tfm_stream_data(struct tfm_cluster * tc, ++ tfm_stream_id id, __u8 * data) ++{ ++ get_tfm_stream(tc, id)->data = data; ++} ++ ++static inline size_t tfm_stream_size(struct tfm_cluster * tc, tfm_stream_id id) ++{ ++ return ts_size(get_tfm_stream(tc, id)); ++} ++ ++static inline void ++set_tfm_stream_size(struct tfm_cluster * tc, tfm_stream_id id, size_t size) ++{ ++ get_tfm_stream(tc, id)->size = size; ++} ++ ++static inline int ++alloc_tfm_stream(struct tfm_cluster * tc, size_t size, tfm_stream_id id) ++{ ++ assert("edward-939", tc != NULL); ++ assert("edward-940", !get_tfm_stream(tc, id)); ++ ++ tc->tun[id] = kzalloc(sizeof(struct tfm_stream), ++ reiser4_ctx_gfp_mask_get()); ++ if (!tc->tun[id]) ++ return -ENOMEM; ++ return alloc_ts_data(get_tfm_stream(tc, id), size); ++} ++ ++static inline int ++realloc_tfm_stream(struct tfm_cluster * tc, size_t size, tfm_stream_id id) ++{ ++ assert("edward-941", tfm_stream_size(tc, id) < size); ++ free_ts_data(get_tfm_stream(tc, id)); ++ return alloc_ts_data(get_tfm_stream(tc, id), size); ++} ++ ++static inline void free_tfm_stream(struct tfm_cluster * tc, tfm_stream_id id) ++{ ++ free_ts_data(get_tfm_stream(tc, id)); ++ free_ts(get_tfm_stream(tc, id)); ++ set_tfm_stream(tc, id, 0); ++} ++ ++static inline unsigned coa_overrun(compression_plugin * cplug, int ilen) ++{ ++ return (cplug->overrun != NULL ? cplug->overrun(ilen) : 0); ++} ++ ++static inline void free_tfm_unit(struct tfm_cluster * tc) ++{ ++ tfm_stream_id id; ++ for (id = 0; id < LAST_STREAM; id++) { ++ if (!get_tfm_stream(tc, id)) ++ continue; ++ free_tfm_stream(tc, id); ++ } ++} ++ ++static inline void put_tfm_cluster(struct tfm_cluster * tc) ++{ ++ assert("edward-942", tc != NULL); ++ free_coa_set(tc); ++ free_tfm_unit(tc); ++} ++ ++static inline int tfm_cluster_is_uptodate(struct tfm_cluster * tc) ++{ ++ assert("edward-943", tc != NULL); ++ assert("edward-944", tc->uptodate == 0 || tc->uptodate == 1); ++ return (tc->uptodate == 1); ++} ++ ++static inline void tfm_cluster_set_uptodate(struct tfm_cluster * tc) ++{ ++ assert("edward-945", tc != NULL); ++ assert("edward-946", tc->uptodate == 0 || tc->uptodate == 1); ++ tc->uptodate = 1; ++ return; ++} ++ ++static inline void tfm_cluster_clr_uptodate(struct tfm_cluster * tc) ++{ ++ assert("edward-947", tc != NULL); ++ assert("edward-948", tc->uptodate == 0 || tc->uptodate == 1); ++ tc->uptodate = 0; ++ return; ++} ++ ++static inline int tfm_stream_is_set(struct tfm_cluster * tc, tfm_stream_id id) ++{ ++ return (get_tfm_stream(tc, id) && ++ tfm_stream_data(tc, id) && tfm_stream_size(tc, id)); ++} ++ ++static inline int tfm_cluster_is_set(struct tfm_cluster * tc) ++{ ++ int i; ++ for (i = 0; i < LAST_STREAM; i++) ++ if (!tfm_stream_is_set(tc, i)) ++ return 0; ++ return 1; ++} ++ ++static inline void alternate_streams(struct tfm_cluster * tc) ++{ ++ struct tfm_stream *tmp = get_tfm_stream(tc, INPUT_STREAM); ++ ++ set_tfm_stream(tc, INPUT_STREAM, get_tfm_stream(tc, OUTPUT_STREAM)); ++ set_tfm_stream(tc, OUTPUT_STREAM, tmp); ++} ++ ++/* Set of states to indicate a kind of data ++ * that will be written to the window */ ++typedef enum { ++ DATA_WINDOW, /* user's data */ ++ HOLE_WINDOW /* zeroes (such kind of data can be written ++ * if we start to write from offset > i_size) */ ++} window_stat; ++ ++/* Window (of logical cluster size) discretely sliding along a file. ++ * Is used to locate hole region in a logical cluster to be properly ++ * represented on disk. ++ * We split a write to cryptcompress file into writes to its logical ++ * clusters. Before writing to a logical cluster we set a window, i.e. ++ * calculate values of the following fields: ++ */ ++struct reiser4_slide { ++ unsigned off; /* offset to write from */ ++ unsigned count; /* number of bytes to write */ ++ unsigned delta; /* number of bytes to append to the hole */ ++ window_stat stat; /* what kind of data will be written starting ++ from @off */ ++}; ++ ++/* Possible states of a disk cluster */ ++typedef enum { ++ INVAL_DISK_CLUSTER, /* unknown state */ ++ PREP_DISK_CLUSTER, /* disk cluster got converted by flush ++ * at least 1 time */ ++ UNPR_DISK_CLUSTER, /* disk cluster just created and should be ++ * converted by flush */ ++ FAKE_DISK_CLUSTER, /* disk cluster doesn't exist neither in memory ++ * nor on disk */ ++ TRNC_DISK_CLUSTER /* disk cluster is partially truncated */ ++} disk_cluster_stat; ++ ++/* The following structure represents various stages of the same logical ++ * cluster of index @index: ++ * . fixed slide ++ * . page cluster (stage in primary cache) ++ * . transform cluster (transition stage) ++ * . disk cluster (stage in secondary cache) ++ * This structure is used in transition and synchronizing operations, e.g. ++ * transform cluster is a transition state when synchronizing page cluster ++ * and disk cluster. ++ * FIXME: Encapsulate page cluster, disk cluster. ++ */ ++struct cluster_handle { ++ cloff_t index; /* offset in a file (unit is a cluster size) */ ++ int index_valid; /* for validating the index above, if needed */ ++ struct file *file; /* host file */ ++ ++ /* logical cluster */ ++ struct reiser4_slide *win; /* sliding window to locate holes */ ++ logical_cluster_op op; /* logical cluster operation (truncate or ++ append/overwrite) */ ++ /* transform cluster */ ++ struct tfm_cluster tc; /* contains all needed info to synchronize ++ page cluster and disk cluster) */ ++ /* page cluster */ ++ int nr_pages; /* number of pages of current checkin action */ ++ int old_nrpages; /* number of pages of last checkin action */ ++ struct page **pages; /* attached pages */ ++ jnode * node; /* jnode for capture */ ++ ++ /* disk cluster */ ++ hint_t *hint; /* current position in the tree */ ++ disk_cluster_stat dstat; /* state of the current disk cluster */ ++ int reserved; /* is space for disk cluster reserved */ ++#if REISER4_DEBUG ++ reiser4_context *ctx; ++ int reserved_prepped; ++ int reserved_unprepped; ++#endif ++ ++}; ++ ++static inline __u8 * tfm_input_data (struct cluster_handle * clust) ++{ ++ return tfm_stream_data(&clust->tc, INPUT_STREAM); ++} ++ ++static inline __u8 * tfm_output_data (struct cluster_handle * clust) ++{ ++ return tfm_stream_data(&clust->tc, OUTPUT_STREAM); ++} ++ ++static inline int reset_cluster_pgset(struct cluster_handle * clust, ++ int nrpages) ++{ ++ assert("edward-1057", clust->pages != NULL); ++ memset(clust->pages, 0, sizeof(*clust->pages) * nrpages); ++ return 0; ++} ++ ++static inline int alloc_cluster_pgset(struct cluster_handle * clust, ++ int nrpages) ++{ ++ assert("edward-949", clust != NULL); ++ assert("edward-1362", clust->pages == NULL); ++ assert("edward-950", nrpages != 0 && nrpages <= MAX_CLUSTER_NRPAGES); ++ ++ clust->pages = kzalloc(sizeof(*clust->pages) * nrpages, ++ reiser4_ctx_gfp_mask_get()); ++ if (!clust->pages) ++ return RETERR(-ENOMEM); ++ return 0; ++} ++ ++static inline void move_cluster_pgset(struct cluster_handle *clust, ++ struct page ***pages, int * nr_pages) ++{ ++ assert("edward-1545", clust != NULL && clust->pages != NULL); ++ assert("edward-1546", pages != NULL && *pages == NULL); ++ *pages = clust->pages; ++ *nr_pages = clust->nr_pages; ++ clust->pages = NULL; ++} ++ ++static inline void free_cluster_pgset(struct cluster_handle * clust) ++{ ++ assert("edward-951", clust->pages != NULL); ++ kfree(clust->pages); ++ clust->pages = NULL; ++} ++ ++static inline void put_cluster_handle(struct cluster_handle * clust) ++{ ++ assert("edward-435", clust != NULL); ++ ++ put_tfm_cluster(&clust->tc); ++ if (clust->pages) ++ free_cluster_pgset(clust); ++ memset(clust, 0, sizeof *clust); ++} ++ ++static inline void inc_keyload_count(struct reiser4_crypto_info * data) ++{ ++ assert("edward-1410", data != NULL); ++ data->keyload_count++; ++} ++ ++static inline void dec_keyload_count(struct reiser4_crypto_info * data) ++{ ++ assert("edward-1411", data != NULL); ++ assert("edward-1412", data->keyload_count > 0); ++ data->keyload_count--; ++} ++ ++static inline int capture_cluster_jnode(jnode * node) ++{ ++ return reiser4_try_capture(node, ZNODE_WRITE_LOCK, 0); ++} ++ ++/* cryptcompress specific part of reiser4_inode */ ++struct cryptcompress_info { ++ struct mutex checkin_mutex; /* This is to serialize ++ * checkin_logical_cluster operations */ ++ cloff_t trunc_index; /* Index of the leftmost truncated disk ++ * cluster (to resolve races with read) */ ++ struct reiser4_crypto_info *crypt; ++ /* ++ * the following 2 fields are controlled by compression mode plugin ++ */ ++ int compress_toggle; /* Current status of compressibility */ ++ int lattice_factor; /* Factor of dynamic lattice. FIXME: Have ++ * a compression_toggle to keep the factor ++ */ ++#if REISER4_DEBUG ++ atomic_t pgcount; /* number of grabbed pages */ ++#endif ++}; ++ ++static inline void set_compression_toggle (struct cryptcompress_info * info, int val) ++{ ++ info->compress_toggle = val; ++} ++ ++static inline int get_compression_toggle (struct cryptcompress_info * info) ++{ ++ return info->compress_toggle; ++} ++ ++static inline int compression_is_on(struct cryptcompress_info * info) ++{ ++ return get_compression_toggle(info) == 1; ++} ++ ++static inline void turn_on_compression(struct cryptcompress_info * info) ++{ ++ set_compression_toggle(info, 1); ++} ++ ++static inline void turn_off_compression(struct cryptcompress_info * info) ++{ ++ set_compression_toggle(info, 0); ++} ++ ++static inline void set_lattice_factor(struct cryptcompress_info * info, int val) ++{ ++ info->lattice_factor = val; ++} ++ ++static inline int get_lattice_factor(struct cryptcompress_info * info) ++{ ++ return info->lattice_factor; ++} ++ ++struct cryptcompress_info *cryptcompress_inode_data(const struct inode *); ++int equal_to_rdk(znode *, const reiser4_key *); ++int goto_right_neighbor(coord_t *, lock_handle *); ++int cryptcompress_inode_ok(struct inode *inode); ++int coord_is_unprepped_ctail(const coord_t * coord); ++extern int do_readpage_ctail(struct inode *, struct cluster_handle *, ++ struct page * page, znode_lock_mode mode); ++extern int ctail_insert_unprepped_cluster(struct cluster_handle * clust, ++ struct inode * inode); ++extern int readpages_cryptcompress(struct file*, struct address_space*, ++ struct list_head*, unsigned); ++int bind_cryptcompress(struct inode *child, struct inode *parent); ++void destroy_inode_cryptcompress(struct inode * inode); ++int grab_page_cluster(struct inode *inode, struct cluster_handle * clust, ++ rw_op rw); ++int write_pschedule_hook(struct file *file, struct inode * inode, ++ loff_t pos, struct cluster_handle * clust, ++ struct psched_context * cont); ++int setattr_pschedule_hook(struct inode * inode); ++struct reiser4_crypto_info * inode_crypto_info(struct inode * inode); ++void inherit_crypto_info_common(struct inode * parent, struct inode * object, ++ int (*can_inherit)(struct inode * child, ++ struct inode * parent)); ++void reiser4_attach_crypto_info(struct inode * inode, ++ struct reiser4_crypto_info * info); ++void change_crypto_info(struct inode * inode, struct reiser4_crypto_info * new); ++struct reiser4_crypto_info * reiser4_alloc_crypto_info (struct inode * inode); ++ ++static inline struct crypto_blkcipher * info_get_cipher(struct reiser4_crypto_info * info) ++{ ++ return info->cipher; ++} ++ ++static inline void info_set_cipher(struct reiser4_crypto_info * info, ++ struct crypto_blkcipher * tfm) ++{ ++ info->cipher = tfm; ++} ++ ++static inline struct crypto_hash * info_get_digest(struct reiser4_crypto_info * info) ++{ ++ return info->digest; ++} ++ ++static inline void info_set_digest(struct reiser4_crypto_info * info, ++ struct crypto_hash * tfm) ++{ ++ info->digest = tfm; ++} ++ ++static inline void put_cluster_page(struct page * page) ++{ ++ page_cache_release(page); ++} ++ ++#endif /* __FS_REISER4_CRYPTCOMPRESS_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file/file.c linux-2.6.30/fs/reiser4/plugin/file/file.c +--- linux-2.6.30.orig/fs/reiser4/plugin/file/file.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file/file.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,2687 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* ++ * this file contains implementations of inode/file/address_space/file plugin ++ * operations specific for "unix file plugin" (plugin id is ++ * UNIX_FILE_PLUGIN_ID). "Unix file" is either built of tail items only ++ * (FORMATTING_ID) or of extent items only (EXTENT_POINTER_ID) or empty (have ++ * no items but stat data) ++ */ ++ ++#include "../../inode.h" ++#include "../../super.h" ++#include "../../tree_walk.h" ++#include "../../carry.h" ++#include "../../page_cache.h" ++#include "../../ioctl.h" ++#include "../object.h" ++#include "../cluster.h" ++#include "../../safe_link.h" ++ ++#include <linux/writeback.h> ++#include <linux/pagevec.h> ++#include <linux/syscalls.h> ++ ++ ++static int unpack(struct file *file, struct inode *inode, int forever); ++static void drop_access(struct unix_file_info *); ++static int hint_validate(hint_t * hint, const reiser4_key * key, int check_key, ++ znode_lock_mode lock_mode); ++ ++/* Get exclusive access and make sure that file is not partially ++ * converted (It may happen that another process is doing tail ++ * conversion. If so, wait until it completes) ++ */ ++static inline void get_exclusive_access_careful(struct unix_file_info * uf_info, ++ struct inode *inode) ++{ ++ do { ++ get_exclusive_access(uf_info); ++ if (!reiser4_inode_get_flag(inode, REISER4_PART_IN_CONV)) ++ break; ++ drop_exclusive_access(uf_info); ++ schedule(); ++ } while (1); ++} ++ ++/* get unix file plugin specific portion of inode */ ++struct unix_file_info *unix_file_inode_data(const struct inode *inode) ++{ ++ return &reiser4_inode_data(inode)->file_plugin_data.unix_file_info; ++} ++ ++/** ++ * equal_to_rdk - compare key and znode's right delimiting key ++ * @node: node whose right delimiting key to compare with @key ++ * @key: key to compare with @node's right delimiting key ++ * ++ * Returns true if @key is equal to right delimiting key of @node. ++ */ ++int equal_to_rdk(znode *node, const reiser4_key *key) ++{ ++ int result; ++ ++ read_lock_dk(znode_get_tree(node)); ++ result = keyeq(key, znode_get_rd_key(node)); ++ read_unlock_dk(znode_get_tree(node)); ++ return result; ++} ++ ++#if REISER4_DEBUG ++ ++/** ++ * equal_to_ldk - compare key and znode's left delimiting key ++ * @node: node whose left delimiting key to compare with @key ++ * @key: key to compare with @node's left delimiting key ++ * ++ * Returns true if @key is equal to left delimiting key of @node. ++ */ ++int equal_to_ldk(znode *node, const reiser4_key *key) ++{ ++ int result; ++ ++ read_lock_dk(znode_get_tree(node)); ++ result = keyeq(key, znode_get_ld_key(node)); ++ read_unlock_dk(znode_get_tree(node)); ++ return result; ++} ++ ++/** ++ * check_coord - check whether coord corresponds to key ++ * @coord: coord to check ++ * @key: key @coord has to correspond to ++ * ++ * Returns true if @coord is set as if it was set as result of lookup with @key ++ * in coord->node. ++ */ ++static int check_coord(const coord_t *coord, const reiser4_key *key) ++{ ++ coord_t twin; ++ ++ node_plugin_by_node(coord->node)->lookup(coord->node, key, ++ FIND_MAX_NOT_MORE_THAN, &twin); ++ return coords_equal(coord, &twin); ++} ++ ++#endif /* REISER4_DEBUG */ ++ ++/** ++ * init_uf_coord - initialize extended coord ++ * @uf_coord: ++ * @lh: ++ * ++ * ++ */ ++void init_uf_coord(uf_coord_t *uf_coord, lock_handle *lh) ++{ ++ coord_init_zero(&uf_coord->coord); ++ coord_clear_iplug(&uf_coord->coord); ++ uf_coord->lh = lh; ++ init_lh(lh); ++ memset(&uf_coord->extension, 0, sizeof(uf_coord->extension)); ++ uf_coord->valid = 0; ++} ++ ++static void validate_extended_coord(uf_coord_t *uf_coord, loff_t offset) ++{ ++ assert("vs-1333", uf_coord->valid == 0); ++ ++ if (coord_is_between_items(&uf_coord->coord)) ++ return; ++ ++ assert("vs-1348", ++ item_plugin_by_coord(&uf_coord->coord)->s.file. ++ init_coord_extension); ++ ++ item_body_by_coord(&uf_coord->coord); ++ item_plugin_by_coord(&uf_coord->coord)->s.file. ++ init_coord_extension(uf_coord, offset); ++} ++ ++/** ++ * goto_right_neighbor - lock right neighbor, drop current node lock ++ * @coord: ++ * @lh: ++ * ++ * Obtain lock on right neighbor and drop lock on current node. ++ */ ++int goto_right_neighbor(coord_t *coord, lock_handle *lh) ++{ ++ int result; ++ lock_handle lh_right; ++ ++ assert("vs-1100", znode_is_locked(coord->node)); ++ ++ init_lh(&lh_right); ++ result = reiser4_get_right_neighbor(&lh_right, coord->node, ++ znode_is_wlocked(coord->node) ? ++ ZNODE_WRITE_LOCK : ZNODE_READ_LOCK, ++ GN_CAN_USE_UPPER_LEVELS); ++ if (result) { ++ done_lh(&lh_right); ++ return result; ++ } ++ ++ /* ++ * we hold two longterm locks on neighboring nodes. Unlock left of ++ * them ++ */ ++ done_lh(lh); ++ ++ coord_init_first_unit_nocheck(coord, lh_right.node); ++ move_lh(lh, &lh_right); ++ ++ return 0; ++ ++} ++ ++/** ++ * set_file_state ++ * @uf_info: ++ * @cbk_result: ++ * @level: ++ * ++ * This is to be used by find_file_item and in find_file_state to ++ * determine real state of file ++ */ ++static void set_file_state(struct unix_file_info *uf_info, int cbk_result, ++ tree_level level) ++{ ++ if (cbk_errored(cbk_result)) ++ /* error happened in find_file_item */ ++ return; ++ ++ assert("vs-1164", level == LEAF_LEVEL || level == TWIG_LEVEL); ++ ++ if (uf_info->container == UF_CONTAINER_UNKNOWN) { ++ if (cbk_result == CBK_COORD_NOTFOUND) ++ uf_info->container = UF_CONTAINER_EMPTY; ++ else if (level == LEAF_LEVEL) ++ uf_info->container = UF_CONTAINER_TAILS; ++ else ++ uf_info->container = UF_CONTAINER_EXTENTS; ++ } else { ++ /* ++ * file state is known, check whether it is set correctly if ++ * file is not being tail converted ++ */ ++ if (!reiser4_inode_get_flag(unix_file_info_to_inode(uf_info), ++ REISER4_PART_IN_CONV)) { ++ assert("vs-1162", ++ ergo(level == LEAF_LEVEL && ++ cbk_result == CBK_COORD_FOUND, ++ uf_info->container == UF_CONTAINER_TAILS)); ++ assert("vs-1165", ++ ergo(level == TWIG_LEVEL && ++ cbk_result == CBK_COORD_FOUND, ++ uf_info->container == UF_CONTAINER_EXTENTS)); ++ } ++ } ++} ++ ++int find_file_item_nohint(coord_t *coord, lock_handle *lh, ++ const reiser4_key *key, znode_lock_mode lock_mode, ++ struct inode *inode) ++{ ++ return reiser4_object_lookup(inode, key, coord, lh, lock_mode, ++ FIND_MAX_NOT_MORE_THAN, ++ TWIG_LEVEL, LEAF_LEVEL, ++ (lock_mode == ZNODE_READ_LOCK) ? CBK_UNIQUE : ++ (CBK_UNIQUE | CBK_FOR_INSERT), ++ NULL /* ra_info */ ); ++} ++ ++/** ++ * find_file_item - look for file item in the tree ++ * @hint: provides coordinate, lock handle, seal ++ * @key: key for search ++ * @mode: mode of lock to put on returned node ++ * @ra_info: ++ * @inode: ++ * ++ * This finds position in the tree corresponding to @key. It first tries to use ++ * @hint's seal if it is set. ++ */ ++int find_file_item(hint_t *hint, const reiser4_key *key, ++ znode_lock_mode lock_mode, ++ struct inode *inode) ++{ ++ int result; ++ coord_t *coord; ++ lock_handle *lh; ++ ++ assert("nikita-3030", reiser4_schedulable()); ++ assert("vs-1707", hint != NULL); ++ assert("vs-47", inode != NULL); ++ ++ coord = &hint->ext_coord.coord; ++ lh = hint->ext_coord.lh; ++ init_lh(lh); ++ ++ result = hint_validate(hint, key, 1 /* check key */, lock_mode); ++ if (!result) { ++ if (coord->between == AFTER_UNIT && ++ equal_to_rdk(coord->node, key)) { ++ result = goto_right_neighbor(coord, lh); ++ if (result == -E_NO_NEIGHBOR) ++ return RETERR(-EIO); ++ if (result) ++ return result; ++ assert("vs-1152", equal_to_ldk(coord->node, key)); ++ /* ++ * we moved to different node. Invalidate coord ++ * extension, zload is necessary to init it again ++ */ ++ hint->ext_coord.valid = 0; ++ } ++ ++ set_file_state(unix_file_inode_data(inode), CBK_COORD_FOUND, ++ znode_get_level(coord->node)); ++ ++ return CBK_COORD_FOUND; ++ } ++ ++ coord_init_zero(coord); ++ result = find_file_item_nohint(coord, lh, key, lock_mode, inode); ++ set_file_state(unix_file_inode_data(inode), result, ++ znode_get_level(coord->node)); ++ ++ /* FIXME: we might already have coord extension initialized */ ++ hint->ext_coord.valid = 0; ++ return result; ++} ++ ++/* plugin->u.file.write_flowom = NULL ++ plugin->u.file.read_flow = NULL */ ++ ++void hint_init_zero(hint_t * hint) ++{ ++ memset(hint, 0, sizeof(*hint)); ++ init_lh(&hint->lh); ++ hint->ext_coord.lh = &hint->lh; ++} ++ ++static int find_file_state(struct inode *inode, struct unix_file_info *uf_info) ++{ ++ int result; ++ reiser4_key key; ++ coord_t coord; ++ lock_handle lh; ++ ++ assert("vs-1628", ea_obtained(uf_info)); ++ ++ if (uf_info->container == UF_CONTAINER_UNKNOWN) { ++ key_by_inode_and_offset_common(inode, 0, &key); ++ init_lh(&lh); ++ result = find_file_item_nohint(&coord, &lh, &key, ++ ZNODE_READ_LOCK, inode); ++ set_file_state(uf_info, result, znode_get_level(coord.node)); ++ done_lh(&lh); ++ if (!cbk_errored(result)) ++ result = 0; ++ } else ++ result = 0; ++ assert("vs-1074", ++ ergo(result == 0, uf_info->container != UF_CONTAINER_UNKNOWN)); ++ reiser4_txn_restart_current(); ++ return result; ++} ++ ++/** ++ * Estimate and reserve space needed to truncate page ++ * which gets partially truncated: one block for page ++ * itself, stat-data update (estimate_one_insert_into_item) ++ * and one item insertion (estimate_one_insert_into_item) ++ * which may happen if page corresponds to hole extent and ++ * unallocated one will have to be created ++ */ ++static int reserve_partial_page(reiser4_tree * tree) ++{ ++ grab_space_enable(); ++ return reiser4_grab_reserved(reiser4_get_current_sb(), ++ 1 + ++ 2 * estimate_one_insert_into_item(tree), ++ BA_CAN_COMMIT); ++} ++ ++/* estimate and reserve space needed to cut one item and update one stat data */ ++static int reserve_cut_iteration(reiser4_tree * tree) ++{ ++ __u64 estimate = estimate_one_item_removal(tree) ++ + estimate_one_insert_into_item(tree); ++ ++ assert("nikita-3172", lock_stack_isclean(get_current_lock_stack())); ++ ++ grab_space_enable(); ++ /* We need to double our estimate now that we can delete more than one ++ node. */ ++ return reiser4_grab_reserved(reiser4_get_current_sb(), estimate * 2, ++ BA_CAN_COMMIT); ++} ++ ++int reiser4_update_file_size(struct inode *inode, loff_t new_size, ++ int update_sd) ++{ ++ int result = 0; ++ ++ INODE_SET_SIZE(inode, new_size); ++ if (update_sd) { ++ inode->i_ctime = inode->i_mtime = CURRENT_TIME; ++ result = reiser4_update_sd(inode); ++ } ++ return result; ++} ++ ++/** ++ * Cut file items one by one starting from the last one until ++ * new file size (inode->i_size) is reached. Reserve space ++ * and update file stat data on every single cut from the tree ++ */ ++int cut_file_items(struct inode *inode, loff_t new_size, ++ int update_sd, loff_t cur_size, ++ int (*update_actor) (struct inode *, loff_t, int)) ++{ ++ reiser4_key from_key, to_key; ++ reiser4_key smallest_removed; ++ file_plugin *fplug = inode_file_plugin(inode); ++ int result; ++ int progress = 0; ++ ++ assert("vs-1248", ++ fplug == file_plugin_by_id(UNIX_FILE_PLUGIN_ID) || ++ fplug == file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID)); ++ ++ fplug->key_by_inode(inode, new_size, &from_key); ++ to_key = from_key; ++ set_key_offset(&to_key, cur_size - 1 /*get_key_offset(reiser4_max_key()) */ ); ++ /* this loop normally runs just once */ ++ while (1) { ++ result = reserve_cut_iteration(reiser4_tree_by_inode(inode)); ++ if (result) ++ break; ++ ++ result = reiser4_cut_tree_object(current_tree, &from_key, &to_key, ++ &smallest_removed, inode, 1, ++ &progress); ++ if (result == -E_REPEAT) { ++ /** ++ * -E_REPEAT is a signal to interrupt a long ++ * file truncation process ++ */ ++ if (progress) { ++ result = update_actor(inode, ++ get_key_offset(&smallest_removed), ++ update_sd); ++ if (result) ++ break; ++ } ++ /* the below does up(sbinfo->delete_mutex). ++ * Do not get folled */ ++ reiser4_release_reserved(inode->i_sb); ++ /** ++ * reiser4_cut_tree_object() was interrupted probably ++ * because current atom requires commit, we have to ++ * release transaction handle to allow atom commit. ++ */ ++ reiser4_txn_restart_current(); ++ continue; ++ } ++ if (result ++ && !(result == CBK_COORD_NOTFOUND && new_size == 0 ++ && inode->i_size == 0)) ++ break; ++ ++ set_key_offset(&smallest_removed, new_size); ++ /* Final sd update after the file gets its correct size */ ++ result = update_actor(inode, get_key_offset(&smallest_removed), ++ update_sd); ++ break; ++ } ++ ++ /* the below does up(sbinfo->delete_mutex). Do not get folled */ ++ reiser4_release_reserved(inode->i_sb); ++ ++ return result; ++} ++ ++int find_or_create_extent(struct page *page); ++ ++/* part of truncate_file_body: it is called when truncate is used to make file ++ shorter */ ++static int shorten_file(struct inode *inode, loff_t new_size) ++{ ++ int result; ++ struct page *page; ++ int padd_from; ++ unsigned long index; ++ struct unix_file_info *uf_info; ++ ++ /* ++ * all items of ordinary reiser4 file are grouped together. That is why ++ * we can use reiser4_cut_tree. Plan B files (for instance) can not be ++ * truncated that simply ++ */ ++ result = cut_file_items(inode, new_size, 1 /*update_sd */ , ++ get_key_offset(reiser4_max_key()), ++ reiser4_update_file_size); ++ if (result) ++ return result; ++ ++ uf_info = unix_file_inode_data(inode); ++ assert("vs-1105", new_size == inode->i_size); ++ if (new_size == 0) { ++ uf_info->container = UF_CONTAINER_EMPTY; ++ return 0; ++ } ++ ++ result = find_file_state(inode, uf_info); ++ if (result) ++ return result; ++ if (uf_info->container == UF_CONTAINER_TAILS) ++ /* ++ * No need to worry about zeroing last page after new file ++ * end ++ */ ++ return 0; ++ ++ padd_from = inode->i_size & (PAGE_CACHE_SIZE - 1); ++ if (!padd_from) ++ /* file is truncated to page boundary */ ++ return 0; ++ ++ result = reserve_partial_page(reiser4_tree_by_inode(inode)); ++ if (result) { ++ reiser4_release_reserved(inode->i_sb); ++ return result; ++ } ++ ++ /* last page is partially truncated - zero its content */ ++ index = (inode->i_size >> PAGE_CACHE_SHIFT); ++ page = read_mapping_page(inode->i_mapping, index, NULL); ++ if (IS_ERR(page)) { ++ /* ++ * the below does up(sbinfo->delete_mutex). Do not get ++ * confused ++ */ ++ reiser4_release_reserved(inode->i_sb); ++ if (likely(PTR_ERR(page) == -EINVAL)) { ++ /* looks like file is built of tail items */ ++ return 0; ++ } ++ return PTR_ERR(page); ++ } ++ wait_on_page_locked(page); ++ if (!PageUptodate(page)) { ++ page_cache_release(page); ++ /* ++ * the below does up(sbinfo->delete_mutex). Do not get ++ * confused ++ */ ++ reiser4_release_reserved(inode->i_sb); ++ return RETERR(-EIO); ++ } ++ ++ /* ++ * if page correspons to hole extent unit - unallocated one will be ++ * created here. This is not necessary ++ */ ++ result = find_or_create_extent(page); ++ ++ /* ++ * FIXME: cut_file_items has already updated inode. Probably it would ++ * be better to update it here when file is really truncated ++ */ ++ if (result) { ++ page_cache_release(page); ++ /* ++ * the below does up(sbinfo->delete_mutex). Do not get ++ * confused ++ */ ++ reiser4_release_reserved(inode->i_sb); ++ return result; ++ } ++ ++ lock_page(page); ++ assert("vs-1066", PageLocked(page)); ++ zero_user_segment(page, padd_from, PAGE_CACHE_SIZE); ++ unlock_page(page); ++ page_cache_release(page); ++ /* the below does up(sbinfo->delete_mutex). Do not get confused */ ++ reiser4_release_reserved(inode->i_sb); ++ return 0; ++} ++ ++/** ++ * should_have_notail ++ * @uf_info: ++ * @new_size: ++ * ++ * Calls formatting plugin to see whether file of size @new_size has to be ++ * stored in unformatted nodes or in tail items. 0 is returned for later case. ++ */ ++static int should_have_notail(const struct unix_file_info *uf_info, loff_t new_size) ++{ ++ if (!uf_info->tplug) ++ return 1; ++ return !uf_info->tplug->have_tail(unix_file_info_to_inode(uf_info), ++ new_size); ++ ++} ++ ++/** ++ * truncate_file_body - change length of file ++ * @inode: inode of file ++ * @new_size: new file length ++ * ++ * Adjusts items file @inode is built of to match @new_size. It may either cut ++ * items or add them to represent a hole at the end of file. The caller has to ++ * obtain exclusive access to the file. ++ */ ++static int truncate_file_body(struct inode *inode, struct iattr *attr) ++{ ++ int result; ++ loff_t new_size = attr->ia_size; ++ ++ if (inode->i_size < new_size) { ++ /* expanding truncate */ ++ struct unix_file_info *uf_info = unix_file_inode_data(inode); ++ ++ result = find_file_state(inode, uf_info); ++ if (result) ++ return result; ++ ++ if (should_have_notail(uf_info, new_size)) { ++ /* ++ * file of size @new_size has to be built of ++ * extents. If it is built of tails - convert to ++ * extents ++ */ ++ if (uf_info->container == UF_CONTAINER_TAILS) { ++ /* ++ * if file is being convered by another process ++ * - wait until it completes ++ */ ++ while (1) { ++ if (reiser4_inode_get_flag(inode, ++ REISER4_PART_IN_CONV)) { ++ drop_exclusive_access(uf_info); ++ schedule(); ++ get_exclusive_access(uf_info); ++ continue; ++ } ++ break; ++ } ++ ++ if (uf_info->container == UF_CONTAINER_TAILS) { ++ result = tail2extent(uf_info); ++ if (result) ++ return result; ++ } ++ } ++ result = reiser4_write_extent(NULL, inode, NULL, ++ 0, &new_size); ++ if (result) ++ return result; ++ uf_info->container = UF_CONTAINER_EXTENTS; ++ } else { ++ if (uf_info->container == UF_CONTAINER_EXTENTS) { ++ result = reiser4_write_extent(NULL, inode, NULL, ++ 0, &new_size); ++ if (result) ++ return result; ++ } else { ++ result = reiser4_write_tail(NULL, inode, NULL, ++ 0, &new_size); ++ if (result) ++ return result; ++ uf_info->container = UF_CONTAINER_TAILS; ++ } ++ } ++ BUG_ON(result > 0); ++ result = reiser4_update_file_size(inode, new_size, 1); ++ BUG_ON(result != 0); ++ } else ++ result = shorten_file(inode, new_size); ++ return result; ++} ++ ++/* plugin->u.write_sd_by_inode = write_sd_by_inode_common */ ++ ++/** ++ * load_file_hint - copy hint from struct file to local variable ++ * @file: file to get hint from ++ * @hint: structure to fill ++ * ++ * Reiser4 specific portion of struct file may contain information (hint) ++ * stored on exiting from previous read or write. That information includes ++ * seal of znode and coord within that znode where previous read or write ++ * stopped. This function copies that information to @hint if it was stored or ++ * initializes @hint by 0s otherwise. ++ */ ++int load_file_hint(struct file *file, hint_t *hint) ++{ ++ reiser4_file_fsdata *fsdata; ++ ++ if (file) { ++ fsdata = reiser4_get_file_fsdata(file); ++ if (IS_ERR(fsdata)) ++ return PTR_ERR(fsdata); ++ ++ spin_lock_inode(file->f_dentry->d_inode); ++ if (reiser4_seal_is_set(&fsdata->reg.hint.seal)) { ++ *hint = fsdata->reg.hint; ++ init_lh(&hint->lh); ++ hint->ext_coord.lh = &hint->lh; ++ spin_unlock_inode(file->f_dentry->d_inode); ++ /* ++ * force re-validation of the coord on the first ++ * iteration of the read/write loop. ++ */ ++ hint->ext_coord.valid = 0; ++ assert("nikita-19892", coords_equal(&hint->seal.coord1, ++ &hint->ext_coord. ++ coord)); ++ return 0; ++ } ++ memset(&fsdata->reg.hint, 0, sizeof(hint_t)); ++ spin_unlock_inode(file->f_dentry->d_inode); ++ } ++ hint_init_zero(hint); ++ return 0; ++} ++ ++/** ++ * save_file_hint - copy hint to reiser4 private struct file's part ++ * @file: file to save hint in ++ * @hint: hint to save ++ * ++ * This copies @hint to reiser4 private part of struct file. It can help ++ * speedup future accesses to the file. ++ */ ++void save_file_hint(struct file *file, const hint_t *hint) ++{ ++ reiser4_file_fsdata *fsdata; ++ ++ assert("edward-1337", hint != NULL); ++ ++ if (!file || !reiser4_seal_is_set(&hint->seal)) ++ return; ++ fsdata = reiser4_get_file_fsdata(file); ++ assert("vs-965", !IS_ERR(fsdata)); ++ assert("nikita-19891", ++ coords_equal(&hint->seal.coord1, &hint->ext_coord.coord)); ++ assert("vs-30", hint->lh.owner == NULL); ++ spin_lock_inode(file->f_dentry->d_inode); ++ fsdata->reg.hint = *hint; ++ spin_unlock_inode(file->f_dentry->d_inode); ++ return; ++} ++ ++void reiser4_unset_hint(hint_t * hint) ++{ ++ assert("vs-1315", hint); ++ hint->ext_coord.valid = 0; ++ reiser4_seal_done(&hint->seal); ++ done_lh(&hint->lh); ++} ++ ++/* coord must be set properly. So, that reiser4_set_hint ++ has nothing to do */ ++void reiser4_set_hint(hint_t * hint, const reiser4_key * key, ++ znode_lock_mode mode) ++{ ++ ON_DEBUG(coord_t * coord = &hint->ext_coord.coord); ++ assert("vs-1207", WITH_DATA(coord->node, check_coord(coord, key))); ++ ++ reiser4_seal_init(&hint->seal, &hint->ext_coord.coord, key); ++ hint->offset = get_key_offset(key); ++ hint->mode = mode; ++ done_lh(&hint->lh); ++} ++ ++int hint_is_set(const hint_t * hint) ++{ ++ return reiser4_seal_is_set(&hint->seal); ++} ++ ++#if REISER4_DEBUG ++static int all_but_offset_key_eq(const reiser4_key * k1, const reiser4_key * k2) ++{ ++ return (get_key_locality(k1) == get_key_locality(k2) && ++ get_key_type(k1) == get_key_type(k2) && ++ get_key_band(k1) == get_key_band(k2) && ++ get_key_ordering(k1) == get_key_ordering(k2) && ++ get_key_objectid(k1) == get_key_objectid(k2)); ++} ++#endif ++ ++static int ++hint_validate(hint_t * hint, const reiser4_key * key, int check_key, ++ znode_lock_mode lock_mode) ++{ ++ if (!hint || !hint_is_set(hint) || hint->mode != lock_mode) ++ /* hint either not set or set by different operation */ ++ return RETERR(-E_REPEAT); ++ ++ assert("vs-1277", all_but_offset_key_eq(key, &hint->seal.key)); ++ ++ if (check_key && get_key_offset(key) != hint->offset) ++ /* hint is set for different key */ ++ return RETERR(-E_REPEAT); ++ ++ assert("vs-31", hint->ext_coord.lh == &hint->lh); ++ return reiser4_seal_validate(&hint->seal, &hint->ext_coord.coord, key, ++ hint->ext_coord.lh, lock_mode, ++ ZNODE_LOCK_LOPRI); ++} ++ ++/** ++ * Look for place at twig level for extent corresponding to page, ++ * call extent's writepage method to create unallocated extent if ++ * it does not exist yet, initialize jnode, capture page ++ */ ++int find_or_create_extent(struct page *page) ++{ ++ int result; ++ struct inode *inode; ++ int plugged_hole; ++ ++ jnode *node; ++ ++ assert("vs-1065", page->mapping && page->mapping->host); ++ inode = page->mapping->host; ++ ++ lock_page(page); ++ node = jnode_of_page(page); ++ if (IS_ERR(node)) { ++ unlock_page(page); ++ return PTR_ERR(node); ++ } ++ JF_SET(node, JNODE_WRITE_PREPARED); ++ unlock_page(page); ++ ++ if (node->blocknr == 0) { ++ plugged_hole = 0; ++ result = reiser4_update_extent(inode, node, page_offset(page), ++ &plugged_hole); ++ if (result) { ++ JF_CLR(node, JNODE_WRITE_PREPARED); ++ jput(node); ++ warning("edward-1549", ++ "reiser4_update_extent failed: %d", result); ++ return result; ++ } ++ if (plugged_hole) ++ reiser4_update_sd(inode); ++ } else { ++ spin_lock_jnode(node); ++ result = reiser4_try_capture(node, ZNODE_WRITE_LOCK, 0); ++ BUG_ON(result != 0); ++ jnode_make_dirty_locked(node); ++ spin_unlock_jnode(node); ++ } ++ ++ BUG_ON(node->atom == NULL); ++ JF_CLR(node, JNODE_WRITE_PREPARED); ++ jput(node); ++ ++ if (get_current_context()->entd) { ++ entd_context *ent = get_entd_context(node->tree->super); ++ ++ if (ent->cur_request->page == page) ++ ent->cur_request->node = node; ++ } ++ return 0; ++} ++ ++/** ++ * has_anonymous_pages - check whether inode has pages dirtied via mmap ++ * @inode: inode to check ++ * ++ * Returns true if inode's mapping has dirty pages which do not belong to any ++ * atom. Those are either tagged PAGECACHE_TAG_REISER4_MOVED in mapping's page ++ * tree or were eflushed and can be found via jnodes tagged ++ * EFLUSH_TAG_ANONYMOUS in radix tree of jnodes. ++ */ ++static int has_anonymous_pages(struct inode *inode) ++{ ++ int result; ++ ++ spin_lock_irq(&inode->i_mapping->tree_lock); ++ result = radix_tree_tagged(&inode->i_mapping->page_tree, PAGECACHE_TAG_REISER4_MOVED); ++ spin_unlock_irq(&inode->i_mapping->tree_lock); ++ return result; ++} ++ ++/** ++ * capture_page_and_create_extent - ++ * @page: page to be captured ++ * ++ * Grabs space for extent creation and stat data update and calls function to ++ * do actual work. ++ */ ++static int capture_page_and_create_extent(struct page *page) ++{ ++ int result; ++ struct inode *inode; ++ ++ assert("vs-1084", page->mapping && page->mapping->host); ++ inode = page->mapping->host; ++ assert("vs-1139", ++ unix_file_inode_data(inode)->container == UF_CONTAINER_EXTENTS); ++ /* page belongs to file */ ++ assert("vs-1393", ++ inode->i_size > page_offset(page)); ++ ++ /* page capture may require extent creation (if it does not exist yet) ++ and stat data's update (number of blocks changes on extent ++ creation) */ ++ grab_space_enable(); ++ result = reiser4_grab_space(2 * estimate_one_insert_into_item ++ (reiser4_tree_by_inode(inode)), ++ BA_CAN_COMMIT); ++ if (likely(!result)) ++ result = find_or_create_extent(page); ++ ++ if (result != 0) ++ SetPageError(page); ++ return result; ++} ++ ++/* plugin->write_end() */ ++int write_end_unix_file(struct file *file, struct page *page, ++ unsigned from, unsigned to) ++{ ++ unlock_page(page); ++ return capture_page_and_create_extent(page); ++} ++ ++/* ++ * Support for "anonymous" pages and jnodes. ++ * ++ * When file is write-accessed through mmap pages can be dirtied from the user ++ * level. In this case kernel is not notified until one of following happens: ++ * ++ * (1) msync() ++ * ++ * (2) truncate() (either explicit or through unlink) ++ * ++ * (3) VM scanner starts reclaiming mapped pages, dirtying them before ++ * starting write-back. ++ * ++ * As a result of (3) ->writepage may be called on a dirty page without ++ * jnode. Such page is called "anonymous" in reiser4. Certain work-loads ++ * (iozone) generate huge number of anonymous pages. ++ * ++ * reiser4_sync_sb() method tries to insert anonymous pages into ++ * tree. This is done by capture_anonymous_*() functions below. ++ */ ++ ++/** ++ * capture_anonymous_page - involve page into transaction ++ * @pg: page to deal with ++ * ++ * Takes care that @page has corresponding metadata in the tree, creates jnode ++ * for @page and captures it. On success 1 is returned. ++ */ ++static int capture_anonymous_page(struct page *page) ++{ ++ int result; ++ ++ if (PageWriteback(page)) ++ /* FIXME: do nothing? */ ++ return 0; ++ ++ result = capture_page_and_create_extent(page); ++ if (result == 0) { ++ result = 1; ++ } else ++ warning("nikita-3329", ++ "Cannot capture anon page: %i", result); ++ ++ return result; ++} ++ ++/** ++ * capture_anonymous_pages - find and capture pages dirtied via mmap ++ * @mapping: address space where to look for pages ++ * @index: start index ++ * @to_capture: maximum number of pages to capture ++ * ++ * Looks for pages tagged REISER4_MOVED starting from the *@index-th page, ++ * captures (involves into atom) them, returns number of captured pages, ++ * updates @index to next page after the last captured one. ++ */ ++static int ++capture_anonymous_pages(struct address_space *mapping, pgoff_t *index, ++ unsigned int to_capture) ++{ ++ int result; ++ struct pagevec pvec; ++ unsigned int i, count; ++ int nr; ++ ++ pagevec_init(&pvec, 0); ++ count = min(pagevec_space(&pvec), to_capture); ++ nr = 0; ++ ++ /* find pages tagged MOVED */ ++ spin_lock_irq(&mapping->tree_lock); ++ pvec.nr = radix_tree_gang_lookup_tag(&mapping->page_tree, ++ (void **)pvec.pages, *index, count, ++ PAGECACHE_TAG_REISER4_MOVED); ++ if (pagevec_count(&pvec) == 0) { ++ /* ++ * there are no pages tagged MOVED in mapping->page_tree ++ * starting from *index ++ */ ++ spin_unlock_irq(&mapping->tree_lock); ++ *index = (pgoff_t)-1; ++ return 0; ++ } ++ ++ /* clear MOVED tag for all found pages */ ++ for (i = 0; i < pagevec_count(&pvec); i++) { ++ page_cache_get(pvec.pages[i]); ++ radix_tree_tag_clear(&mapping->page_tree, pvec.pages[i]->index, ++ PAGECACHE_TAG_REISER4_MOVED); ++ } ++ spin_unlock_irq(&mapping->tree_lock); ++ ++ ++ *index = pvec.pages[i - 1]->index + 1; ++ ++ for (i = 0; i < pagevec_count(&pvec); i++) { ++ result = capture_anonymous_page(pvec.pages[i]); ++ if (result == 1) ++ nr++; ++ else { ++ if (result < 0) { ++ warning("vs-1454", ++ "failed to capture page: " ++ "result=%d, captured=%d)\n", ++ result, i); ++ ++ /* ++ * set MOVED tag to all pages which left not ++ * captured ++ */ ++ spin_lock_irq(&mapping->tree_lock); ++ for (; i < pagevec_count(&pvec); i ++) { ++ radix_tree_tag_set(&mapping->page_tree, ++ pvec.pages[i]->index, ++ PAGECACHE_TAG_REISER4_MOVED); ++ } ++ spin_unlock_irq(&mapping->tree_lock); ++ ++ pagevec_release(&pvec); ++ return result; ++ } else { ++ /* ++ * result == 0. capture_anonymous_page returns ++ * 0 for Writeback-ed page. Set MOVED tag on ++ * that page ++ */ ++ spin_lock_irq(&mapping->tree_lock); ++ radix_tree_tag_set(&mapping->page_tree, ++ pvec.pages[i]->index, ++ PAGECACHE_TAG_REISER4_MOVED); ++ spin_unlock_irq(&mapping->tree_lock); ++ if (i == 0) ++ *index = pvec.pages[0]->index; ++ else ++ *index = pvec.pages[i - 1]->index + 1; ++ } ++ } ++ } ++ pagevec_release(&pvec); ++ return nr; ++} ++ ++/** ++ * capture_anonymous_jnodes - find and capture anonymous jnodes ++ * @mapping: address space where to look for jnodes ++ * @from: start index ++ * @to: end index ++ * @to_capture: maximum number of jnodes to capture ++ * ++ * Looks for jnodes tagged EFLUSH_TAG_ANONYMOUS in inode's tree of jnodes in ++ * the range of indexes @from-@to and captures them, returns number of captured ++ * jnodes, updates @from to next jnode after the last captured one. ++ */ ++static int ++capture_anonymous_jnodes(struct address_space *mapping, ++ pgoff_t *from, pgoff_t to, int to_capture) ++{ ++ *from = to; ++ return 0; ++} ++ ++/* ++ * Commit atom of the jnode of a page. ++ */ ++static int sync_page(struct page *page) ++{ ++ int result; ++ do { ++ jnode *node; ++ txn_atom *atom; ++ ++ lock_page(page); ++ node = jprivate(page); ++ if (node != NULL) { ++ spin_lock_jnode(node); ++ atom = jnode_get_atom(node); ++ spin_unlock_jnode(node); ++ } else ++ atom = NULL; ++ unlock_page(page); ++ result = reiser4_sync_atom(atom); ++ } while (result == -E_REPEAT); ++ /* ++ * ZAM-FIXME-HANS: document the logic of this loop, is it just to ++ * handle the case where more pages get added to the atom while we are ++ * syncing it? ++ */ ++ assert("nikita-3485", ergo(result == 0, ++ get_current_context()->trans->atom == NULL)); ++ return result; ++} ++ ++/* ++ * Commit atoms of pages on @pages list. ++ * call sync_page for each page from mapping's page tree ++ */ ++static int sync_page_list(struct inode *inode) ++{ ++ int result; ++ struct address_space *mapping; ++ unsigned long from; /* start index for radix_tree_gang_lookup */ ++ unsigned int found; /* return value for radix_tree_gang_lookup */ ++ ++ mapping = inode->i_mapping; ++ from = 0; ++ result = 0; ++ spin_lock_irq(&mapping->tree_lock); ++ while (result == 0) { ++ struct page *page; ++ ++ found = ++ radix_tree_gang_lookup(&mapping->page_tree, (void **)&page, ++ from, 1); ++ assert("edward-1550", found < 2); ++ if (found == 0) ++ break; ++ /** ++ * page may not leave radix tree because it is protected from ++ * truncating by inode->i_mutex locked by sys_fsync ++ */ ++ page_cache_get(page); ++ spin_unlock_irq(&mapping->tree_lock); ++ ++ from = page->index + 1; ++ ++ result = sync_page(page); ++ ++ page_cache_release(page); ++ spin_lock_irq(&mapping->tree_lock); ++ } ++ ++ spin_unlock_irq(&mapping->tree_lock); ++ return result; ++} ++ ++static int commit_file_atoms(struct inode *inode) ++{ ++ int result; ++ struct unix_file_info *uf_info; ++ ++ uf_info = unix_file_inode_data(inode); ++ ++ get_exclusive_access(uf_info); ++ /* ++ * find what items file is made from ++ */ ++ result = find_file_state(inode, uf_info); ++ drop_exclusive_access(uf_info); ++ if (result != 0) ++ return result; ++ ++ /* ++ * file state cannot change because we are under ->i_mutex ++ */ ++ switch (uf_info->container) { ++ case UF_CONTAINER_EXTENTS: ++ /* find_file_state might open join an atom */ ++ reiser4_txn_restart_current(); ++ result = ++ /* ++ * when we are called by ++ * filemap_fdatawrite-> ++ * do_writepages()-> ++ * reiser4_writepages() ++ * ++ * inode->i_mapping->dirty_pages are spices into ++ * ->io_pages, leaving ->dirty_pages dirty. ++ * ++ * When we are called from ++ * reiser4_fsync()->sync_unix_file(), we have to ++ * commit atoms of all pages on the ->dirty_list. ++ * ++ * So for simplicity we just commit ->io_pages and ++ * ->dirty_pages. ++ */ ++ sync_page_list(inode); ++ break; ++ case UF_CONTAINER_TAILS: ++ /* ++ * NOTE-NIKITA probably we can be smarter for tails. For now ++ * just commit all existing atoms. ++ */ ++ result = txnmgr_force_commit_all(inode->i_sb, 0); ++ break; ++ case UF_CONTAINER_EMPTY: ++ result = 0; ++ break; ++ case UF_CONTAINER_UNKNOWN: ++ default: ++ result = -EIO; ++ break; ++ } ++ ++ /* ++ * commit current transaction: there can be captured nodes from ++ * find_file_state() and finish_conversion(). ++ */ ++ reiser4_txn_restart_current(); ++ return result; ++} ++ ++/** ++ * writepages_unix_file - writepages of struct address_space_operations ++ * @mapping: ++ * @wbc: ++ * ++ * This captures anonymous pages and anonymous jnodes. Anonymous pages are ++ * pages which are dirtied via mmapping. Anonymous jnodes are ones which were ++ * created by reiser4_writepage. ++ */ ++int writepages_unix_file(struct address_space *mapping, ++ struct writeback_control *wbc) ++{ ++ int result; ++ struct unix_file_info *uf_info; ++ pgoff_t pindex, jindex, nr_pages; ++ long to_capture; ++ struct inode *inode; ++ ++ inode = mapping->host; ++ if (!has_anonymous_pages(inode)) { ++ result = 0; ++ goto end; ++ } ++ jindex = pindex = wbc->range_start >> PAGE_CACHE_SHIFT; ++ result = 0; ++ nr_pages = size_in_pages(i_size_read(inode)); ++ ++ uf_info = unix_file_inode_data(inode); ++ ++ do { ++ reiser4_context *ctx; ++ ++ if (wbc->sync_mode != WB_SYNC_ALL) ++ to_capture = min(wbc->nr_to_write, CAPTURE_APAGE_BURST); ++ else ++ to_capture = CAPTURE_APAGE_BURST; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) { ++ result = PTR_ERR(ctx); ++ break; ++ } ++ /* avoid recursive calls to ->sync_inodes */ ++ ctx->nobalance = 1; ++ assert("zam-760", lock_stack_isclean(get_current_lock_stack())); ++ assert("edward-1551", LOCK_CNT_NIL(inode_sem_w)); ++ assert("edward-1552", LOCK_CNT_NIL(inode_sem_r)); ++ ++ reiser4_txn_restart_current(); ++ ++ /* we have to get nonexclusive access to the file */ ++ if (get_current_context()->entd) { ++ /* ++ * use nonblocking version of nonexclusive_access to ++ * avoid deadlock which might look like the following: ++ * process P1 holds NEA on file F1 and called entd to ++ * reclaim some memory. Entd works for P1 and is going ++ * to capture pages of file F2. To do that entd has to ++ * get NEA to F2. F2 is held by process P2 which also ++ * called entd. But entd is serving P1 at the moment ++ * and P2 has to wait. Process P3 trying to get EA to ++ * file F2. Existence of pending EA request to file F2 ++ * makes impossible for entd to get NEA to file ++ * F2. Neither of these process can continue. Using ++ * nonblocking version of gettign NEA is supposed to ++ * avoid this deadlock. ++ */ ++ if (try_to_get_nonexclusive_access(uf_info) == 0) { ++ result = RETERR(-EBUSY); ++ reiser4_exit_context(ctx); ++ break; ++ } ++ } else ++ get_nonexclusive_access(uf_info); ++ ++ while (to_capture > 0) { ++ pgoff_t start; ++ ++ assert("vs-1727", jindex <= pindex); ++ if (pindex == jindex) { ++ start = pindex; ++ result = ++ capture_anonymous_pages(inode->i_mapping, ++ &pindex, ++ to_capture); ++ if (result <= 0) ++ break; ++ to_capture -= result; ++ wbc->nr_to_write -= result; ++ if (start + result == pindex) { ++ jindex = pindex; ++ continue; ++ } ++ if (to_capture <= 0) ++ break; ++ } ++ /* deal with anonymous jnodes between jindex and pindex */ ++ result = ++ capture_anonymous_jnodes(inode->i_mapping, &jindex, ++ pindex, to_capture); ++ if (result < 0) ++ break; ++ to_capture -= result; ++ get_current_context()->nr_captured += result; ++ ++ if (jindex == (pgoff_t) - 1) { ++ assert("vs-1728", pindex == (pgoff_t) - 1); ++ break; ++ } ++ } ++ if (to_capture <= 0) ++ /* there may be left more pages */ ++ __mark_inode_dirty(inode, I_DIRTY_PAGES); ++ ++ drop_nonexclusive_access(uf_info); ++ if (result < 0) { ++ /* error happened */ ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ if (wbc->sync_mode != WB_SYNC_ALL) { ++ reiser4_exit_context(ctx); ++ return 0; ++ } ++ result = commit_file_atoms(inode); ++ reiser4_exit_context(ctx); ++ if (pindex >= nr_pages && jindex == pindex) ++ break; ++ } while (1); ++ ++ end: ++ if (is_in_reiser4_context()) { ++ if (get_current_context()->nr_captured >= CAPTURE_APAGE_BURST) { ++ /* ++ * there are already pages to flush, flush them out, do ++ * not delay until end of reiser4_sync_inodes ++ */ ++ reiser4_writeout(inode->i_sb, wbc); ++ get_current_context()->nr_captured = 0; ++ } ++ } ++ return result; ++} ++ ++/** ++ * readpage_unix_file_nolock - readpage of struct address_space_operations ++ * @file: ++ * @page: ++ * ++ * Compose a key and search for item containing information about @page ++ * data. If item is found - its readpage method is called. ++ */ ++int readpage_unix_file(struct file *file, struct page *page) ++{ ++ reiser4_context *ctx; ++ int result; ++ struct inode *inode; ++ reiser4_key key; ++ item_plugin *iplug; ++ hint_t *hint; ++ lock_handle *lh; ++ coord_t *coord; ++ ++ assert("vs-1062", PageLocked(page)); ++ assert("vs-976", !PageUptodate(page)); ++ assert("vs-1061", page->mapping && page->mapping->host); ++ ++ if (page->mapping->host->i_size <= page_offset(page)) { ++ /* page is out of file */ ++ zero_user(page, 0, PAGE_CACHE_SIZE); ++ SetPageUptodate(page); ++ unlock_page(page); ++ return 0; ++ } ++ ++ inode = page->mapping->host; ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) { ++ unlock_page(page); ++ return PTR_ERR(ctx); ++ } ++ ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) { ++ unlock_page(page); ++ reiser4_exit_context(ctx); ++ return RETERR(-ENOMEM); ++ } ++ ++ result = load_file_hint(file, hint); ++ if (result) { ++ kfree(hint); ++ unlock_page(page); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ lh = &hint->lh; ++ ++ /* get key of first byte of the page */ ++ key_by_inode_and_offset_common(inode, page_offset(page), &key); ++ ++ /* look for file metadata corresponding to first byte of page */ ++ page_cache_get(page); ++ unlock_page(page); ++ result = find_file_item(hint, &key, ZNODE_READ_LOCK, inode); ++ lock_page(page); ++ page_cache_release(page); ++ ++ if (page->mapping == NULL) { ++ /* ++ * readpage allows truncate to run concurrently. Page was ++ * truncated while it was not locked ++ */ ++ done_lh(lh); ++ kfree(hint); ++ unlock_page(page); ++ reiser4_txn_restart(ctx); ++ reiser4_exit_context(ctx); ++ return -EINVAL; ++ } ++ ++ if (result != CBK_COORD_FOUND || hint->ext_coord.coord.between != AT_UNIT) { ++ if (result == CBK_COORD_FOUND && ++ hint->ext_coord.coord.between != AT_UNIT) ++ /* file is truncated */ ++ result = -EINVAL; ++ done_lh(lh); ++ kfree(hint); ++ unlock_page(page); ++ reiser4_txn_restart(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ /* ++ * item corresponding to page is found. It can not be removed because ++ * znode lock is held ++ */ ++ if (PageUptodate(page)) { ++ done_lh(lh); ++ kfree(hint); ++ unlock_page(page); ++ reiser4_txn_restart(ctx); ++ reiser4_exit_context(ctx); ++ return 0; ++ } ++ ++ coord = &hint->ext_coord.coord; ++ result = zload(coord->node); ++ if (result) { ++ done_lh(lh); ++ kfree(hint); ++ unlock_page(page); ++ reiser4_txn_restart(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ validate_extended_coord(&hint->ext_coord, page_offset(page)); ++ ++ if (!coord_is_existing_unit(coord)) { ++ /* this indicates corruption */ ++ warning("vs-280", ++ "Looking for page %lu of file %llu (size %lli). " ++ "No file items found (%d). File is corrupted?\n", ++ page->index, (unsigned long long)get_inode_oid(inode), ++ inode->i_size, result); ++ zrelse(coord->node); ++ done_lh(lh); ++ kfree(hint); ++ unlock_page(page); ++ reiser4_txn_restart(ctx); ++ reiser4_exit_context(ctx); ++ return RETERR(-EIO); ++ } ++ ++ /* ++ * get plugin of found item or use plugin if extent if there are no ++ * one ++ */ ++ iplug = item_plugin_by_coord(coord); ++ if (iplug->s.file.readpage) ++ result = iplug->s.file.readpage(coord, page); ++ else ++ result = RETERR(-EINVAL); ++ ++ if (!result) { ++ set_key_offset(&key, ++ (loff_t) (page->index + 1) << PAGE_CACHE_SHIFT); ++ /* FIXME should call reiser4_set_hint() */ ++ reiser4_unset_hint(hint); ++ } else { ++ unlock_page(page); ++ reiser4_unset_hint(hint); ++ } ++ assert("vs-979", ++ ergo(result == 0, (PageLocked(page) || PageUptodate(page)))); ++ assert("vs-9791", ergo(result != 0, !PageLocked(page))); ++ ++ zrelse(coord->node); ++ done_lh(lh); ++ ++ save_file_hint(file, hint); ++ kfree(hint); ++ ++ /* ++ * FIXME: explain why it is needed. HINT: page allocation in write can ++ * not be done when atom is not NULL because reiser4_writepage can not ++ * kick entd and have to eflush ++ */ ++ reiser4_txn_restart(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++struct uf_readpages_context { ++ lock_handle lh; ++ coord_t coord; ++}; ++ ++/* A callback function for readpages_unix_file/read_cache_pages. ++ * If the file is build of tails, then return error (-ENOENT). ++ * ++ * @data -- a pointer to reiser4_readpages_context object, ++ * to save the twig lock and the coord between ++ * read_cache_page iterations. ++ * @page -- page to start read. ++ */ ++static int uf_readpages_filler(void * data, struct page * page) ++{ ++ struct uf_readpages_context *rc = data; ++ jnode * node; ++ int ret = 0; ++ reiser4_extent *ext; ++ __u64 ext_index; ++ int cbk_done = 0; ++ struct address_space * mapping = page->mapping; ++ ++ if (PageUptodate(page)) { ++ unlock_page(page); ++ return 0; ++ } ++ page_cache_get(page); ++ ++ if (rc->lh.node == 0) { ++ /* no twig lock - have to do tree search. */ ++ reiser4_key key; ++ repeat: ++ unlock_page(page); ++ key_by_inode_and_offset_common( ++ mapping->host, page_offset(page), &key); ++ ret = coord_by_key( ++ &get_super_private(mapping->host->i_sb)->tree, ++ &key, &rc->coord, &rc->lh, ++ ZNODE_READ_LOCK, FIND_EXACT, ++ TWIG_LEVEL, TWIG_LEVEL, CBK_UNIQUE, NULL); ++ if (unlikely(ret)) ++ goto exit; ++ lock_page(page); ++ if (PageUptodate(page)) ++ goto unlock; ++ cbk_done = 1; ++ } ++ ret = zload(rc->coord.node); ++ if (unlikely(ret)) ++ goto unlock; ++ if (!coord_is_existing_item(&rc->coord) || ++ !item_is_extent(&rc->coord)) { ++ zrelse(rc->coord.node); ++ ret = RETERR(-EIO); ++ goto unlock; ++ } ++ ext = extent_by_coord(&rc->coord); ++ ext_index = extent_unit_index(&rc->coord); ++ if (page->index < ext_index || ++ page->index >= ext_index + extent_get_width(ext)) { ++ /* the page index doesn't belong to the extent unit ++ which the coord points to - release the lock and ++ repeat with tree search. */ ++ zrelse(rc->coord.node); ++ done_lh(&rc->lh); ++ /* we can be here after a CBK call only in case of ++ corruption of the tree or the tree lookup algorithm bug. */ ++ if (unlikely(cbk_done)) { ++ ret = RETERR(-EIO); ++ goto unlock; ++ } ++ goto repeat; ++ } ++ node = jnode_of_page(page); ++ if (unlikely(IS_ERR(node))) { ++ zrelse(rc->coord.node); ++ ret = PTR_ERR(node); ++ goto unlock; ++ } ++ ret = reiser4_do_readpage_extent(ext, page->index - ext_index, page); ++ jput(node); ++ zrelse(rc->coord.node); ++ if (likely(!ret)) ++ goto exit; ++ unlock: ++ unlock_page(page); ++ exit: ++ page_cache_release(page); ++ return ret; ++} ++ ++/** ++ * readpages_unix_file - called by the readahead code, starts reading for each ++ * page of given list of pages ++ */ ++int readpages_unix_file( ++ struct file *file, struct address_space *mapping, ++ struct list_head *pages, unsigned nr_pages) ++{ ++ reiser4_context *ctx; ++ struct uf_readpages_context rc; ++ int ret; ++ ++ ctx = reiser4_init_context(mapping->host->i_sb); ++ if (IS_ERR(ctx)) { ++ put_pages_list(pages); ++ return PTR_ERR(ctx); ++ } ++ init_lh(&rc.lh); ++ ret = read_cache_pages(mapping, pages, uf_readpages_filler, &rc); ++ done_lh(&rc.lh); ++ context_set_commit_async(ctx); ++ /* close the transaction to protect further page allocation from deadlocks */ ++ reiser4_txn_restart(ctx); ++ reiser4_exit_context(ctx); ++ return ret; ++} ++ ++static reiser4_block_nr unix_file_estimate_read(struct inode *inode, ++ loff_t count UNUSED_ARG) ++{ ++ /* We should reserve one block, because of updating of the stat data ++ item */ ++ assert("vs-1249", ++ inode_file_plugin(inode)->estimate.update == ++ estimate_update_common); ++ return estimate_update_common(inode); ++} ++ ++/* this is called with nonexclusive access obtained, file's container can not change */ ++static ssize_t read_file(hint_t *hint, struct file *file, /* file to read from to */ ++ char __user *buf, /* address of user-space buffer */ ++ size_t count, /* number of bytes to read */ ++ loff_t *off) ++{ ++ int result; ++ struct inode *inode; ++ flow_t flow; ++ int (*read_f) (struct file *, flow_t *, hint_t *); ++ coord_t *coord; ++ znode *loaded; ++ ++ inode = file->f_dentry->d_inode; ++ ++ /* build flow */ ++ assert("vs-1250", ++ inode_file_plugin(inode)->flow_by_inode == ++ flow_by_inode_unix_file); ++ result = ++ flow_by_inode_unix_file(inode, buf, 1 /* user space */ , count, ++ *off, READ_OP, &flow); ++ if (unlikely(result)) ++ return result; ++ ++ /* get seal and coord sealed with it from reiser4 private data ++ of struct file. The coord will tell us where our last read ++ of this file finished, and the seal will help to determine ++ if that location is still valid. ++ */ ++ coord = &hint->ext_coord.coord; ++ while (flow.length && result == 0) { ++ result = ++ find_file_item(hint, &flow.key, ZNODE_READ_LOCK, inode); ++ if (cbk_errored(result)) ++ /* error happened */ ++ break; ++ ++ if (coord->between != AT_UNIT) { ++ /* there were no items corresponding to given offset */ ++ done_lh(hint->ext_coord.lh); ++ break; ++ } ++ ++ loaded = coord->node; ++ result = zload(loaded); ++ if (unlikely(result)) { ++ done_lh(hint->ext_coord.lh); ++ break; ++ } ++ ++ if (hint->ext_coord.valid == 0) ++ validate_extended_coord(&hint->ext_coord, ++ get_key_offset(&flow.key)); ++ ++ assert("vs-4", hint->ext_coord.valid == 1); ++ assert("vs-33", hint->ext_coord.lh == &hint->lh); ++ /* call item's read method */ ++ read_f = item_plugin_by_coord(coord)->s.file.read; ++ result = read_f(file, &flow, hint); ++ zrelse(loaded); ++ done_lh(hint->ext_coord.lh); ++ } ++ ++ return (count - flow.length) ? (count - flow.length) : result; ++} ++ ++static ssize_t read_unix_file_container_tails(struct file*, char __user*, size_t, loff_t*); ++ ++/** ++ * read_unix_file - read of struct file_operations ++ * @file: file to read from ++ * @buf: address of user-space buffer ++ * @read_amount: number of bytes to read ++ * @off: position in file to read from ++ * ++ * This is implementation of vfs's read method of struct file_operations for ++ * unix file plugin. ++ */ ++ssize_t read_unix_file(struct file *file, char __user *buf, size_t read_amount, ++ loff_t *off) ++{ ++ reiser4_context *ctx; ++ ssize_t result; ++ struct inode *inode; ++ struct unix_file_info *uf_info; ++ ++ if (unlikely(read_amount == 0)) ++ return 0; ++ ++ assert("umka-072", file != NULL); ++ assert("umka-074", off != NULL); ++ inode = file->f_dentry->d_inode; ++ assert("vs-972", !reiser4_inode_get_flag(inode, REISER4_NO_SD)); ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ uf_info = unix_file_inode_data(inode); ++ if (uf_info->container == UF_CONTAINER_UNKNOWN) { ++ get_exclusive_access(uf_info); ++ result = find_file_state(inode, uf_info); ++ if (unlikely(result != 0)) ++ goto out; ++ } else ++ get_nonexclusive_access(uf_info); ++ result = reiser4_grab_space_force(unix_file_estimate_read(inode, read_amount), ++ BA_CAN_COMMIT); ++ if (unlikely(result != 0)) ++ goto out; ++ if (uf_info->container == UF_CONTAINER_EXTENTS){ ++ result = do_sync_read(file, buf, read_amount, off); ++ } else if (uf_info->container == UF_CONTAINER_TAILS || ++ reiser4_inode_get_flag(inode, REISER4_PART_IN_CONV) || ++ reiser4_inode_get_flag(inode, REISER4_PART_MIXED)) { ++ result = read_unix_file_container_tails(file, buf, read_amount, off); ++ } else { ++ assert("zam-1085", uf_info->container == UF_CONTAINER_EMPTY); ++ result = 0; ++ } ++out: ++ drop_access(uf_info); ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++static ssize_t read_unix_file_container_tails( ++ struct file *file, char __user *buf, size_t read_amount, loff_t *off) ++{ ++ int result; ++ struct inode *inode; ++ hint_t *hint; ++ struct unix_file_info *uf_info; ++ size_t count, read, left; ++ loff_t size; ++ ++ assert("umka-072", file != NULL); ++ assert("umka-074", off != NULL); ++ inode = file->f_dentry->d_inode; ++ assert("vs-972", !reiser4_inode_get_flag(inode, REISER4_NO_SD)); ++ ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) ++ return RETERR(-ENOMEM); ++ ++ result = load_file_hint(file, hint); ++ if (result) { ++ kfree(hint); ++ return result; ++ } ++ ++ left = read_amount; ++ count = 0; ++ uf_info = unix_file_inode_data(inode); ++ while (left > 0) { ++ reiser4_txn_restart_current(); ++ size = i_size_read(inode); ++ if (*off >= size) ++ /* position to read from is past the end of file */ ++ break; ++ if (*off + left > size) ++ left = size - *off; ++ /* faultin user page */ ++ result = fault_in_pages_writeable(buf, left > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : left); ++ if (result) ++ return RETERR(-EFAULT); ++ ++ read = read_file(hint, file, buf, ++ left > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : left, ++ off); ++ if (read < 0) { ++ result = read; ++ break; ++ } ++ left -= read; ++ buf += read; ++ ++ /* update position in a file */ ++ *off += read; ++ /* total number of read bytes */ ++ count += read; ++ } ++ done_lh(&hint->lh); ++ save_file_hint(file, hint); ++ kfree(hint); ++ if (count) ++ file_accessed(file); ++ /* return number of read bytes or error code if nothing is read */ ++ return count ? count : result; ++} ++ ++/* This function takes care about @file's pages. First of all it checks if ++ filesystems readonly and if so gets out. Otherwise, it throws out all ++ pages of file if it was mapped for read and going to be mapped for write ++ and consists of tails. This is done in order to not manage few copies ++ of the data (first in page cache and second one in tails them selves) ++ for the case of mapping files consisting tails. ++ ++ Here also tail2extent conversion is performed if it is allowed and file ++ is going to be written or mapped for write. This functions may be called ++ from write_unix_file() or mmap_unix_file(). */ ++static int check_pages_unix_file(struct file *file, struct inode *inode) ++{ ++ reiser4_invalidate_pages(inode->i_mapping, 0, ++ (inode->i_size + PAGE_CACHE_SIZE - ++ 1) >> PAGE_CACHE_SHIFT, 0); ++ return unpack(file, inode, 0 /* not forever */ ); ++} ++ ++/** ++ * mmap_unix_file - mmap of struct file_operations ++ * @file: file to mmap ++ * @vma: ++ * ++ * This is implementation of vfs's mmap method of struct file_operations for ++ * unix file plugin. It converts file to extent if necessary. Sets ++ * reiser4_inode's flag - REISER4_HAS_MMAP. ++ */ ++int mmap_unix_file(struct file *file, struct vm_area_struct *vma) ++{ ++ reiser4_context *ctx; ++ int result; ++ struct inode *inode; ++ struct unix_file_info *uf_info; ++ reiser4_block_nr needed; ++ ++ inode = file->f_dentry->d_inode; ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ uf_info = unix_file_inode_data(inode); ++ ++ get_exclusive_access_careful(uf_info, inode); ++ ++ if (!IS_RDONLY(inode) && (vma->vm_flags & (VM_MAYWRITE | VM_SHARED))) { ++ /* ++ * we need file built of extent items. If it is still built of ++ * tail items we have to convert it. Find what items the file ++ * is built of ++ */ ++ result = find_file_state(inode, uf_info); ++ if (result != 0) { ++ drop_exclusive_access(uf_info); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ assert("vs-1648", (uf_info->container == UF_CONTAINER_TAILS || ++ uf_info->container == UF_CONTAINER_EXTENTS || ++ uf_info->container == UF_CONTAINER_EMPTY)); ++ if (uf_info->container == UF_CONTAINER_TAILS) { ++ /* ++ * invalidate all pages and convert file from tails to ++ * extents ++ */ ++ result = check_pages_unix_file(file, inode); ++ if (result) { ++ drop_exclusive_access(uf_info); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ } ++ } ++ ++ /* ++ * generic_file_mmap will do update_atime. Grab space for stat data ++ * update. ++ */ ++ needed = inode_file_plugin(inode)->estimate.update(inode); ++ result = reiser4_grab_space_force(needed, BA_CAN_COMMIT); ++ if (result) { ++ drop_exclusive_access(uf_info); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ result = generic_file_mmap(file, vma); ++ if (result == 0) { ++ /* mark file as having mapping. */ ++ reiser4_inode_set_flag(inode, REISER4_HAS_MMAP); ++ } ++ ++ drop_exclusive_access(uf_info); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/** ++ * find_first_item ++ * @inode: ++ * ++ * Finds file item which is responsible for first byte in the file. ++ */ ++static int find_first_item(struct inode *inode) ++{ ++ coord_t coord; ++ lock_handle lh; ++ reiser4_key key; ++ int result; ++ ++ coord_init_zero(&coord); ++ init_lh(&lh); ++ inode_file_plugin(inode)->key_by_inode(inode, 0, &key); ++ result = find_file_item_nohint(&coord, &lh, &key, ZNODE_READ_LOCK, ++ inode); ++ if (result == CBK_COORD_FOUND) { ++ if (coord.between == AT_UNIT) { ++ result = zload(coord.node); ++ if (result == 0) { ++ result = item_id_by_coord(&coord); ++ zrelse(coord.node); ++ if (result != EXTENT_POINTER_ID && ++ result != FORMATTING_ID) ++ result = RETERR(-EIO); ++ } ++ } else ++ result = RETERR(-EIO); ++ } ++ done_lh(&lh); ++ return result; ++} ++ ++/** ++ * open_unix_file ++ * @inode: ++ * @file: ++ * ++ * If filesystem is not readonly - complete uncompleted tail conversion if ++ * there was one ++ */ ++int open_unix_file(struct inode *inode, struct file *file) ++{ ++ int result; ++ reiser4_context *ctx; ++ struct unix_file_info *uf_info; ++ ++ if (IS_RDONLY(inode)) ++ return 0; ++ ++ if (!reiser4_inode_get_flag(inode, REISER4_PART_MIXED)) ++ return 0; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ uf_info = unix_file_inode_data(inode); ++ ++ get_exclusive_access_careful(uf_info, inode); ++ ++ if (!reiser4_inode_get_flag(inode, REISER4_PART_MIXED)) { ++ /* ++ * other process completed the conversion ++ */ ++ drop_exclusive_access(uf_info); ++ reiser4_exit_context(ctx); ++ return 0; ++ } ++ ++ /* ++ * file left in semi converted state after unclean shutdown or another ++ * thread is doing conversion and dropped exclusive access which doing ++ * balance dirty pages. Complete the conversion ++ */ ++ result = find_first_item(inode); ++ if (result == EXTENT_POINTER_ID) ++ /* ++ * first item is extent, therefore there was incomplete ++ * tail2extent conversion. Complete it ++ */ ++ result = tail2extent(unix_file_inode_data(inode)); ++ else if (result == FORMATTING_ID) ++ /* ++ * first item is formatting item, therefore there was ++ * incomplete extent2tail conversion. Complete it ++ */ ++ result = extent2tail(file, unix_file_inode_data(inode)); ++ else ++ result = -EIO; ++ ++ assert("vs-1712", ++ ergo(result == 0, ++ (!reiser4_inode_get_flag(inode, REISER4_PART_MIXED) && ++ !reiser4_inode_get_flag(inode, REISER4_PART_IN_CONV)))); ++ drop_exclusive_access(uf_info); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++#define NEITHER_OBTAINED 0 ++#define EA_OBTAINED 1 ++#define NEA_OBTAINED 2 ++ ++static void drop_access(struct unix_file_info *uf_info) ++{ ++ if (uf_info->exclusive_use) ++ drop_exclusive_access(uf_info); ++ else ++ drop_nonexclusive_access(uf_info); ++} ++ ++#define debug_wuf(format, ...) printk("%s: %d: %s: " format "\n", \ ++ __FILE__, __LINE__, __FUNCTION__, ## __VA_ARGS__) ++ ++/** ++ * write_unix_file - private ->write() method of unix_file plugin. ++ * ++ * @file: file to write to ++ * @buf: address of user-space buffer ++ * @count: number of bytes to write ++ * @pos: position in file to write to ++ * @cont: unused argument, as we don't perform plugin conversion when being ++ * managed by unix_file plugin. ++ */ ++ssize_t write_unix_file(struct file *file, const char __user *buf, ++ size_t count, loff_t *pos, struct psched_context *cont) ++{ ++ int result; ++ reiser4_context *ctx; ++ struct inode *inode; ++ struct unix_file_info *uf_info; ++ ssize_t written; ++ int try_free_space; ++ int to_write = PAGE_CACHE_SIZE * WRITE_GRANULARITY; ++ size_t left; ++ ssize_t (*write_op)(struct file *, struct inode *, ++ const char __user *, size_t, ++ loff_t *pos); ++ int ea; ++ loff_t new_size; ++ ++ ctx = get_current_context(); ++ inode = file->f_dentry->d_inode; ++ ++ assert("vs-947", !reiser4_inode_get_flag(inode, REISER4_NO_SD)); ++ assert("vs-9471", (!reiser4_inode_get_flag(inode, REISER4_PART_MIXED))); ++ ++ /* check amount of bytes to write and writing position */ ++ result = generic_write_checks(file, pos, &count, 0); ++ if (result) { ++ context_set_commit_async(ctx); ++ return result; ++ } ++ ++ result = file_remove_suid(file); ++ if (result) { ++ context_set_commit_async(ctx); ++ return result; ++ } ++ /* remove_suid might create a transaction */ ++ reiser4_txn_restart(ctx); ++ ++ uf_info = unix_file_inode_data(inode); ++ ++ current->backing_dev_info = inode->i_mapping->backing_dev_info; ++ written = 0; ++ try_free_space = 0; ++ left = count; ++ ea = NEITHER_OBTAINED; ++ ++ new_size = i_size_read(inode); ++ if (*pos + count > new_size) ++ new_size = *pos + count; ++ ++ while (left) { ++ if (left < to_write) ++ to_write = left; ++ ++ if (uf_info->container == UF_CONTAINER_EMPTY) { ++ get_exclusive_access(uf_info); ++ ea = EA_OBTAINED; ++ if (uf_info->container != UF_CONTAINER_EMPTY) { ++ /* file is made not empty by another process */ ++ drop_exclusive_access(uf_info); ++ ea = NEITHER_OBTAINED; ++ continue; ++ } ++ } else if (uf_info->container == UF_CONTAINER_UNKNOWN) { ++ /* ++ * get exclusive access directly just to not have to ++ * re-obtain it if file will appear empty ++ */ ++ get_exclusive_access(uf_info); ++ ea = EA_OBTAINED; ++ result = find_file_state(inode, uf_info); ++ if (result) { ++ drop_exclusive_access(uf_info); ++ ea = NEITHER_OBTAINED; ++ break; ++ } ++ } else { ++ get_nonexclusive_access(uf_info); ++ ea = NEA_OBTAINED; ++ } ++ ++ /* either EA or NEA is obtained. Choose item write method */ ++ if (uf_info->container == UF_CONTAINER_EXTENTS) { ++ /* file is built of extent items */ ++ write_op = reiser4_write_extent; ++ } else if (uf_info->container == UF_CONTAINER_EMPTY) { ++ /* file is empty */ ++ if (should_have_notail(uf_info, new_size)) ++ write_op = reiser4_write_extent; ++ else ++ write_op = reiser4_write_tail; ++ } else { ++ /* file is built of tail items */ ++ if (should_have_notail(uf_info, new_size)) { ++ if (ea == NEA_OBTAINED) { ++ drop_nonexclusive_access(uf_info); ++ get_exclusive_access(uf_info); ++ ea = EA_OBTAINED; ++ } ++ if (uf_info->container == UF_CONTAINER_TAILS) { ++ /* ++ * if file is being convered by another ++ * process - wait until it completes ++ */ ++ while (1) { ++ if (reiser4_inode_get_flag(inode, ++ REISER4_PART_IN_CONV)) { ++ drop_exclusive_access(uf_info); ++ schedule(); ++ get_exclusive_access(uf_info); ++ continue; ++ } ++ break; ++ } ++ if (uf_info->container == UF_CONTAINER_TAILS) { ++ result = tail2extent(uf_info); ++ if (result) { ++ drop_exclusive_access(uf_info); ++ context_set_commit_async(ctx); ++ break; ++ } ++ } ++ } ++ drop_exclusive_access(uf_info); ++ ea = NEITHER_OBTAINED; ++ continue; ++ } ++ write_op = reiser4_write_tail; ++ } ++ ++ written = write_op(file, inode, buf, to_write, pos); ++ if (written == -ENOSPC && try_free_space) { ++ drop_access(uf_info); ++ txnmgr_force_commit_all(inode->i_sb, 0); ++ try_free_space = 0; ++ continue; ++ } ++ if (written < 0) { ++ drop_access(uf_info); ++ result = written; ++ break; ++ } ++ /* something is written. */ ++ if (uf_info->container == UF_CONTAINER_EMPTY) { ++ assert("edward-1553", ea == EA_OBTAINED); ++ uf_info->container = ++ (write_op == reiser4_write_extent) ? ++ UF_CONTAINER_EXTENTS : UF_CONTAINER_TAILS; ++ } else { ++ assert("edward-1554", ergo(uf_info->container == UF_CONTAINER_EXTENTS, ++ write_op == reiser4_write_extent)); ++ assert("edward-1555", ergo(uf_info->container == UF_CONTAINER_TAILS, ++ write_op == reiser4_write_tail)); ++ } ++ if (*pos + written > inode->i_size) ++ INODE_SET_FIELD(inode, i_size, *pos + written); ++ file_update_time(file); ++ result = reiser4_update_sd(inode); ++ if (result) { ++ current->backing_dev_info = NULL; ++ drop_access(uf_info); ++ context_set_commit_async(ctx); ++ break; ++ } ++ drop_access(uf_info); ++ ea = NEITHER_OBTAINED; ++ reiser4_txn_restart(ctx); ++ current->journal_info = NULL; ++ /* ++ * tell VM how many pages were dirtied. Maybe number of pages ++ * which were dirty already should not be counted ++ */ ++ balance_dirty_pages_ratelimited_nr(inode->i_mapping, ++ (written + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE); ++ current->journal_info = ctx; ++ ++ left -= written; ++ buf += written; ++ *pos += written; ++ } ++ if (result == 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { ++ reiser4_txn_restart_current(); ++ grab_space_enable(); ++ result = reiser4_sync_file_common(file, file->f_dentry, ++ 0 /* data and stat data */); ++ if (result) ++ warning("reiser4-7", "failed to sync file %llu", ++ (unsigned long long)get_inode_oid(inode)); ++ } ++ ++ current->backing_dev_info = NULL; ++ ++ /* ++ * return number of written bytes or error code if nothing is ++ * written. Note, that it does not work correctly in case when ++ * sync_unix_file returns error ++ */ ++ return (count - left) ? (count - left) : result; ++} ++ ++/** ++ * release_unix_file - release of struct file_operations ++ * @inode: inode of released file ++ * @file: file to release ++ * ++ * Implementation of release method of struct file_operations for unix file ++ * plugin. If last reference to indode is released - convert all extent items ++ * into tail items if necessary. Frees reiser4 specific file data. ++ */ ++int release_unix_file(struct inode *inode, struct file *file) ++{ ++ reiser4_context *ctx; ++ struct unix_file_info *uf_info; ++ int result; ++ int in_reiser4; ++ ++ in_reiser4 = is_in_reiser4_context(); ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ result = 0; ++ if (in_reiser4 == 0) { ++ uf_info = unix_file_inode_data(inode); ++ ++ get_exclusive_access_careful(uf_info, inode); ++ if (atomic_read(&file->f_dentry->d_count) == 1 && ++ uf_info->container == UF_CONTAINER_EXTENTS && ++ !should_have_notail(uf_info, inode->i_size) && ++ !rofs_inode(inode)) { ++ result = extent2tail(file, uf_info); ++ if (result != 0) { ++ context_set_commit_async(ctx); ++ warning("nikita-3233", ++ "Failed (%d) to convert in %s (%llu)", ++ result, __FUNCTION__, ++ (unsigned long long) ++ get_inode_oid(inode)); ++ } ++ } ++ drop_exclusive_access(uf_info); ++ } else { ++ /* ++ we are within reiser4 context already. How latter is ++ possible? Simple: ++ ++ (gdb) bt ++ #0 get_exclusive_access () ++ #2 0xc01e56d3 in release_unix_file () ++ #3 0xc01c3643 in reiser4_release () ++ #4 0xc014cae0 in __fput () ++ #5 0xc013ffc3 in remove_vm_struct () ++ #6 0xc0141786 in exit_mmap () ++ #7 0xc0118480 in mmput () ++ #8 0xc0133205 in oom_kill () ++ #9 0xc01332d1 in out_of_memory () ++ #10 0xc013bc1d in try_to_free_pages () ++ #11 0xc013427b in __alloc_pages () ++ #12 0xc013f058 in do_anonymous_page () ++ #13 0xc013f19d in do_no_page () ++ #14 0xc013f60e in handle_mm_fault () ++ #15 0xc01131e5 in do_page_fault () ++ #16 0xc0104935 in error_code () ++ #17 0xc025c0c6 in __copy_to_user_ll () ++ #18 0xc01d496f in reiser4_read_tail () ++ #19 0xc01e4def in read_unix_file () ++ #20 0xc01c3504 in reiser4_read () ++ #21 0xc014bd4f in vfs_read () ++ #22 0xc014bf66 in sys_read () ++ */ ++ warning("vs-44", "out of memory?"); ++ } ++ ++ reiser4_free_file_fsdata(file); ++ ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++static void set_file_notail(struct inode *inode) ++{ ++ reiser4_inode *state; ++ formatting_plugin *tplug; ++ ++ state = reiser4_inode_data(inode); ++ tplug = formatting_plugin_by_id(NEVER_TAILS_FORMATTING_ID); ++ force_plugin_pset(inode, PSET_FORMATTING, (reiser4_plugin *)tplug); ++} ++ ++/* if file is built of tails - convert it to extents */ ++static int unpack(struct file *filp, struct inode *inode, int forever) ++{ ++ int result = 0; ++ struct unix_file_info *uf_info; ++ ++ uf_info = unix_file_inode_data(inode); ++ assert("vs-1628", ea_obtained(uf_info)); ++ ++ result = find_file_state(inode, uf_info); ++ if (result) ++ return result; ++ assert("vs-1074", uf_info->container != UF_CONTAINER_UNKNOWN); ++ ++ if (uf_info->container == UF_CONTAINER_TAILS) { ++ /* ++ * if file is being convered by another process - wait until it ++ * completes ++ */ ++ while (1) { ++ if (reiser4_inode_get_flag(inode, ++ REISER4_PART_IN_CONV)) { ++ drop_exclusive_access(uf_info); ++ schedule(); ++ get_exclusive_access(uf_info); ++ continue; ++ } ++ break; ++ } ++ if (uf_info->container == UF_CONTAINER_TAILS) { ++ result = tail2extent(uf_info); ++ if (result) ++ return result; ++ } ++ } ++ if (forever) { ++ /* safe new formatting plugin in stat data */ ++ __u64 tograb; ++ ++ set_file_notail(inode); ++ ++ grab_space_enable(); ++ tograb = inode_file_plugin(inode)->estimate.update(inode); ++ result = reiser4_grab_space(tograb, BA_CAN_COMMIT); ++ result = reiser4_update_sd(inode); ++ } ++ ++ return result; ++} ++ ++/* implentation of vfs' ioctl method of struct file_operations for unix file ++ plugin ++*/ ++int ++ioctl_unix_file(struct inode *inode, struct file *filp, ++ unsigned int cmd, unsigned long arg UNUSED_ARG) ++{ ++ reiser4_context *ctx; ++ int result; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ switch (cmd) { ++ case REISER4_IOC_UNPACK: ++ get_exclusive_access(unix_file_inode_data(inode)); ++ result = unpack(filp, inode, 1 /* forever */ ); ++ drop_exclusive_access(unix_file_inode_data(inode)); ++ break; ++ ++ default: ++ result = RETERR(-ENOSYS); ++ break; ++ } ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/* implentation of vfs' bmap method of struct address_space_operations for unix ++ file plugin ++*/ ++sector_t bmap_unix_file(struct address_space * mapping, sector_t lblock) ++{ ++ reiser4_context *ctx; ++ sector_t result; ++ reiser4_key key; ++ coord_t coord; ++ lock_handle lh; ++ struct inode *inode; ++ item_plugin *iplug; ++ sector_t block; ++ ++ inode = mapping->host; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ key_by_inode_and_offset_common(inode, ++ (loff_t) lblock * current_blocksize, ++ &key); ++ ++ init_lh(&lh); ++ result = ++ find_file_item_nohint(&coord, &lh, &key, ZNODE_READ_LOCK, inode); ++ if (cbk_errored(result)) { ++ done_lh(&lh); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ result = zload(coord.node); ++ if (result) { ++ done_lh(&lh); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ iplug = item_plugin_by_coord(&coord); ++ if (iplug->s.file.get_block) { ++ result = iplug->s.file.get_block(&coord, lblock, &block); ++ if (result == 0) ++ result = block; ++ } else ++ result = RETERR(-EINVAL); ++ ++ zrelse(coord.node); ++ done_lh(&lh); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/** ++ * flow_by_inode_unix_file - initizlize structure flow ++ * @inode: inode of file for which read or write is abou ++ * @buf: buffer to perform read to or write from ++ * @user: flag showing whether @buf is user space or kernel space ++ * @size: size of buffer @buf ++ * @off: start offset fro read or write ++ * @op: READ or WRITE ++ * @flow: ++ * ++ * Initializes fields of @flow: key, size of data, i/o mode (read or write). ++ */ ++int flow_by_inode_unix_file(struct inode *inode, ++ const char __user *buf, int user, ++ loff_t size, loff_t off, ++ rw_op op, flow_t *flow) ++{ ++ assert("nikita-1100", inode != NULL); ++ ++ flow->length = size; ++ memcpy(&flow->data, &buf, sizeof(buf)); ++ flow->user = user; ++ flow->op = op; ++ assert("nikita-1931", inode_file_plugin(inode) != NULL); ++ assert("nikita-1932", ++ inode_file_plugin(inode)->key_by_inode == ++ key_by_inode_and_offset_common); ++ /* calculate key of write position and insert it into flow->key */ ++ return key_by_inode_and_offset_common(inode, off, &flow->key); ++} ++ ++/* plugin->u.file.set_plug_in_sd = NULL ++ plugin->u.file.set_plug_in_inode = NULL ++ plugin->u.file.create_blank_sd = NULL */ ++/* plugin->u.file.delete */ ++/* ++ plugin->u.file.add_link = reiser4_add_link_common ++ plugin->u.file.rem_link = NULL */ ++ ++/* plugin->u.file.owns_item ++ this is common_file_owns_item with assertion */ ++/* Audited by: green(2002.06.15) */ ++int ++owns_item_unix_file(const struct inode *inode /* object to check against */ , ++ const coord_t * coord /* coord to check */ ) ++{ ++ int result; ++ ++ result = owns_item_common(inode, coord); ++ if (!result) ++ return 0; ++ if (!plugin_of_group(item_plugin_by_coord(coord), ++ UNIX_FILE_METADATA_ITEM_TYPE)) ++ return 0; ++ assert("vs-547", ++ item_id_by_coord(coord) == EXTENT_POINTER_ID || ++ item_id_by_coord(coord) == FORMATTING_ID); ++ return 1; ++} ++ ++static int setattr_truncate(struct inode *inode, struct iattr *attr) ++{ ++ int result; ++ int s_result; ++ loff_t old_size; ++ reiser4_tree *tree; ++ ++ inode_check_scale(inode, inode->i_size, attr->ia_size); ++ ++ old_size = inode->i_size; ++ tree = reiser4_tree_by_inode(inode); ++ ++ result = safe_link_grab(tree, BA_CAN_COMMIT); ++ if (result == 0) ++ result = safe_link_add(inode, SAFE_TRUNCATE); ++ if (result == 0) ++ result = truncate_file_body(inode, attr); ++ if (result) ++ warning("vs-1588", "truncate_file failed: oid %lli, " ++ "old size %lld, new size %lld, retval %d", ++ (unsigned long long)get_inode_oid(inode), ++ old_size, attr->ia_size, result); ++ ++ s_result = safe_link_grab(tree, BA_CAN_COMMIT); ++ if (s_result == 0) ++ s_result = ++ safe_link_del(tree, get_inode_oid(inode), SAFE_TRUNCATE); ++ if (s_result != 0) { ++ warning("nikita-3417", "Cannot kill safelink %lli: %i", ++ (unsigned long long)get_inode_oid(inode), s_result); ++ } ++ safe_link_release(tree); ++ return result; ++} ++ ++/* plugin->u.file.setattr method */ ++/* This calls inode_setattr and if truncate is in effect it also takes ++ exclusive inode access to avoid races */ ++int setattr_unix_file(struct dentry *dentry, /* Object to change attributes */ ++ struct iattr *attr /* change description */ ) ++{ ++ int result; ++ ++ if (attr->ia_valid & ATTR_SIZE) { ++ reiser4_context *ctx; ++ struct unix_file_info *uf_info; ++ ++ /* truncate does reservation itself and requires exclusive ++ access obtained */ ++ ctx = reiser4_init_context(dentry->d_inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ uf_info = unix_file_inode_data(dentry->d_inode); ++ get_exclusive_access_careful(uf_info, dentry->d_inode); ++ result = setattr_truncate(dentry->d_inode, attr); ++ drop_exclusive_access(uf_info); ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ } else ++ result = reiser4_setattr_common(dentry, attr); ++ ++ return result; ++} ++ ++/* plugin->u.file.init_inode_data */ ++void ++init_inode_data_unix_file(struct inode *inode, ++ reiser4_object_create_data * crd, int create) ++{ ++ struct unix_file_info *data; ++ ++ data = unix_file_inode_data(inode); ++ data->container = create ? UF_CONTAINER_EMPTY : UF_CONTAINER_UNKNOWN; ++ init_rwsem(&data->latch); ++ data->tplug = inode_formatting_plugin(inode); ++ data->exclusive_use = 0; ++ ++#if REISER4_DEBUG ++ data->ea_owner = NULL; ++ atomic_set(&data->nr_neas, 0); ++#endif ++ init_inode_ordering(inode, crd, create); ++} ++ ++/** ++ * delete_unix_file - delete_object of file_plugin ++ * @inode: inode to be deleted ++ * ++ * Truncates file to length 0, removes stat data and safe link. ++ */ ++int delete_object_unix_file(struct inode *inode) ++{ ++ struct unix_file_info *uf_info; ++ int result; ++ ++ if (reiser4_inode_get_flag(inode, REISER4_NO_SD)) ++ return 0; ++ ++ /* truncate file bogy first */ ++ uf_info = unix_file_inode_data(inode); ++ get_exclusive_access(uf_info); ++ result = shorten_file(inode, 0 /* size */ ); ++ drop_exclusive_access(uf_info); ++ ++ if (result) ++ warning("edward-1556", ++ "failed to truncate file (%llu) on removal: %d", ++ get_inode_oid(inode), result); ++ ++ /* remove stat data and safe link */ ++ return reiser4_delete_object_common(inode); ++} ++ ++/* plugin->write_begin() */ ++int write_begin_unix_file(struct file *file, struct page *page, ++ unsigned from, unsigned to) ++{ ++ int ret; ++ struct unix_file_info *info; ++ ++ info = unix_file_inode_data(file->f_dentry->d_inode); ++ get_exclusive_access(info); ++ ret = find_file_state(file->f_dentry->d_inode, info); ++ if (likely(ret == 0)) { ++ if (info->container == UF_CONTAINER_TAILS) ++ ret = -EINVAL; ++ else ++ ret = do_prepare_write(file, page, from, to); ++ } ++ drop_exclusive_access(info); ++ return ret; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file/file_conversion.c linux-2.6.30/fs/reiser4/plugin/file/file_conversion.c +--- linux-2.6.30.orig/fs/reiser4/plugin/file/file_conversion.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file/file_conversion.c 2009-06-22 16:44:21.000000000 +0200 +@@ -0,0 +1,779 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, ++ licensing governed by reiser4/README */ ++ ++/** ++ * This file contains plugin schedule hooks, and plugin conversion methods. ++ * ++ * Plugin schedule hook makes a decision (at plugin schedule point) about the ++ * most reasonable plugins for managing a regular file. Usually such decisions ++ * is made by some O(1)-heuristic. ++ * ++ * By default we assign a unix_file plugin id when writing incompressible file ++ * managed by cryptcompress plugin id. Currently used heuristic for estimating ++ * compressibility is very simple: if first complete logical cluster (64K by ++ * default) of a file is incompressible, then we make a decision, that the whole ++ * file is incompressible (*). ++ * ++ * To enable a conversion we install a special "magic" compression mode plugin ++ * (CONVX_COMPRESSION_MODE_ID, see plugin/compress/compress_mode.c for details) ++ * at file creation time (**). ++ * ++ * Note, that we don't perform back conversion (unix_file->cryptcompress) ++ * because of compatibility reasons (see http://dev.namesys.com/Version4.X.Y ++ * for details). ++ * ++ * The conversion is accompanied by rebuilding disk structures of a file, so it ++ * is important to protect them from being interacted with other plugins which ++ * don't expect them to be in such inconsistent state. For this to be protected ++ * we serialize readers and writers of a file's conversion set (FCS). ++ * ++ * We define FCS as a file plugin installed in inode's pset plus file's data ++ * and metadata that this file plugin manipulates with (items, etc). ++ * Note, that FCS is defined per file. ++ * FCS reader is defined as a set of instruction of the following type: ++ * {inode_file_plugin(inode)->method()} (I.e. retrieving a file plugin id ++ * conjoined with all method's instructions should be atomic). ++ * FCS writer is a set of instructions that perform file plugin conversion ++ * (convert items, update pset, etc). ++ * Example: ++ * reiser4_write_careful() supplied to VFS as a ->write() file operation is ++ * composed of the following (optional) instructions: ++ * 1 2 3 ++ * *********************** ####### --------------------------------------------> ++ * ++ * 1) "****" are instructions performed on behalf of cryptcompress file plugin; ++ * 2) "####" is a FCS writer (performing a conversion cryptcompress->unix_file); ++ * 3) "----" are instructions performed on behalf of unix_file plugin; ++ * Here (1) and (3) are FCS readers. ++ * ++ * In this example FCS readers and writers are already serialized (by design), ++ * however there can be readers and writers executing at the same time in ++ * different contexts, so we need a common mechanism of serialization. ++ * ++ * Currently serialization of FCS readers and writers is performed via acquiring ++ * a special per-inode rw-semaphore (conv_sem). And yes, {down, up}_read is for ++ * FCS readers, and {down, up}_write is for FCS writers, see the macros below ++ * for passive/active protection. ++ * ++ * --- ++ * (*) This heuristic can be changed to a better one (benchmarking is needed). ++ * (**) Such technique allows to keep enable/disable state on disk. ++ */ ++ ++#include "../../inode.h" ++#include "../cluster.h" ++#include "file.h" ++ ++#define conversion_enabled(inode) \ ++ (inode_compression_mode_plugin(inode) == \ ++ compression_mode_plugin_by_id(CONVX_COMPRESSION_MODE_ID)) ++ ++/** ++ * Located sections (readers and writers of @pset) are not permanently ++ * critical: cryptcompress file can be converted only if the conversion ++ * is enabled (see the macrio above). Also we don't perform back ++ * conversion. The following helper macro is a sanity check to decide ++ * if we need the protection (locks are always additional overheads). ++ */ ++#define should_protect(inode) \ ++ (inode_file_plugin(inode) == \ ++ file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID) && \ ++ conversion_enabled(inode)) ++/** ++ * To avoid confusion with read/write file operations, we'll speak about ++ * "passive" protection for FCS readers and "active" protection for FCS ++ * writers. All methods with active or passive protection have suffix ++ * "careful". ++ */ ++/** ++ * Macros for passive protection. ++ * ++ * Construct invariant operation to be supplied to VFS. ++ * The macro accepts the following lexemes: ++ * @type - type of the value represented by the compound statement; ++ * @method - name of an operation to be supplied to VFS (reiser4 file ++ * plugin also should contain a method with such name). ++ */ ++#define PROT_PASSIVE(type, method, args) \ ++({ \ ++ type _result; \ ++ struct rw_semaphore * guard = \ ++ &reiser4_inode_data(inode)->conv_sem; \ ++ \ ++ if (should_protect(inode)) { \ ++ down_read(guard); \ ++ if (!should_protect(inode)) \ ++ up_read(guard); \ ++ } \ ++ _result = inode_file_plugin(inode)->method args; \ ++ if (should_protect(inode)) \ ++ up_read(guard); \ ++ _result; \ ++}) ++ ++#define PROT_PASSIVE_VOID(method, args) \ ++({ \ ++ struct rw_semaphore * guard = \ ++ &reiser4_inode_data(inode)->conv_sem; \ ++ \ ++ if (should_protect(inode)) { \ ++ down_read(guard); \ ++ if (!should_protect(inode)) \ ++ up_read(guard); \ ++ } \ ++ inode_file_plugin(inode)->method args; \ ++ \ ++ if (should_protect(inode)) \ ++ up_read(guard); \ ++}) ++ ++/* Pass management to the unix-file plugin with "notail" policy */ ++static int __cryptcompress2unixfile(struct file *file, struct inode * inode) ++{ ++ int result; ++ reiser4_inode *info; ++ struct unix_file_info * uf; ++ info = reiser4_inode_data(inode); ++ ++ result = aset_set_unsafe(&info->pset, ++ PSET_FILE, ++ (reiser4_plugin *) ++ file_plugin_by_id(UNIX_FILE_PLUGIN_ID)); ++ if (result) ++ return result; ++ result = aset_set_unsafe(&info->pset, ++ PSET_FORMATTING, ++ (reiser4_plugin *) ++ formatting_plugin_by_id(NEVER_TAILS_FORMATTING_ID)); ++ if (result) ++ return result; ++ /* get rid of non-standard plugins */ ++ info->plugin_mask &= ~cryptcompress_mask; ++ /* get rid of plugin stat-data extension */ ++ info->extmask &= ~(1 << PLUGIN_STAT); ++ ++ reiser4_inode_clr_flag(inode, REISER4_SDLEN_KNOWN); ++ ++ /* FIXME use init_inode_data_unix_file() instead, ++ but aviod init_inode_ordering() */ ++ /* Init unix-file specific part of inode */ ++ uf = unix_file_inode_data(inode); ++ uf->container = UF_CONTAINER_UNKNOWN; ++ init_rwsem(&uf->latch); ++ uf->tplug = inode_formatting_plugin(inode); ++ uf->exclusive_use = 0; ++#if REISER4_DEBUG ++ uf->ea_owner = NULL; ++ atomic_set(&uf->nr_neas, 0); ++#endif ++ /** ++ * we was carefull for file_ops, inode_ops and as_ops ++ * to be invariant for plugin conversion, so there is ++ * no need to update ones already installed in the ++ * vfs's residence. ++ */ ++ return 0; ++} ++ ++#if REISER4_DEBUG ++static int disabled_conversion_inode_ok(struct inode * inode) ++{ ++ __u64 extmask = reiser4_inode_data(inode)->extmask; ++ __u16 plugin_mask = reiser4_inode_data(inode)->plugin_mask; ++ ++ return ((extmask & (1 << LIGHT_WEIGHT_STAT)) && ++ (extmask & (1 << UNIX_STAT)) && ++ (extmask & (1 << LARGE_TIMES_STAT)) && ++ (extmask & (1 << PLUGIN_STAT)) && ++ (plugin_mask & (1 << PSET_COMPRESSION_MODE))); ++} ++#endif ++ ++/** ++ * Disable future attempts to schedule/convert file plugin. ++ * This function is called by plugin schedule hooks. ++ * ++ * To disable conversion we assign any compression mode plugin id ++ * different from CONVX_COMPRESSION_MODE_ID. ++ */ ++static int disable_conversion(struct inode * inode) ++{ ++ int result; ++ result = ++ force_plugin_pset(inode, ++ PSET_COMPRESSION_MODE, ++ (reiser4_plugin *)compression_mode_plugin_by_id ++ (LATTD_COMPRESSION_MODE_ID)); ++ assert("edward-1500", ++ ergo(!result, disabled_conversion_inode_ok(inode))); ++ return result; ++} ++ ++/** ++ * Check if we really have achieved plugin scheduling point ++ */ ++static int check_psched_point(struct inode * inode, ++ loff_t pos /* position in the ++ file to write from */, ++ struct cluster_handle * clust, ++ struct psched_context * cont) ++{ ++ assert("edward-1505", conversion_enabled(inode)); ++ /* ++ * if file size is more then cluster size, then compressible ++ * status must be figured out (i.e. compression was disabled, ++ * or file plugin was converted to unix_file) ++ */ ++ assert("edward-1506", inode->i_size <= inode_cluster_size(inode)); ++ ++ if (pos > inode->i_size) ++ /* first logical cluster will contain a (partial) hole */ ++ return disable_conversion(inode); ++ if (pos < inode_cluster_size(inode)) ++ /* writing to the first logical cluster */ ++ return 0; ++ /* ++ * here we have: ++ * cluster_size <= pos <= i_size <= cluster_size, ++ * and, hence, pos == i_size == cluster_size ++ */ ++ assert("edward-1498", ++ pos == inode->i_size && ++ pos == inode_cluster_size(inode)); ++ assert("edward-1539", cont != NULL); ++ assert("edward-1540", cont->state == PSCHED_INVAL_STATE); ++ ++ cont->state = PSCHED_SCHED_POINT; ++ return 0; ++} ++ ++static void start_check_compressibility(struct inode * inode, ++ struct cluster_handle * clust, ++ hint_t * hint) ++{ ++ assert("edward-1507", clust->index == 1); ++ assert("edward-1508", !tfm_cluster_is_uptodate(&clust->tc)); ++ assert("edward-1509", cluster_get_tfm_act(&clust->tc) == TFMA_READ); ++ ++ hint_init_zero(hint); ++ clust->hint = hint; ++ clust->index --; ++ clust->nr_pages = size_in_pages(lbytes(clust->index, inode)); ++ ++ /* first logical cluster (of index #0) must be complete */ ++ assert("edward-1510", lbytes(clust->index, inode) == ++ inode_cluster_size(inode)); ++} ++ ++static void finish_check_compressibility(struct inode * inode, ++ struct cluster_handle * clust, ++ hint_t * hint) ++{ ++ reiser4_unset_hint(clust->hint); ++ clust->hint = hint; ++ clust->index ++; ++} ++ ++#if REISER4_DEBUG ++static int prepped_dclust_ok(hint_t * hint) ++{ ++ reiser4_key key; ++ coord_t * coord = &hint->ext_coord.coord; ++ ++ item_key_by_coord(coord, &key); ++ return (item_id_by_coord(coord) == CTAIL_ID && ++ !coord_is_unprepped_ctail(coord) && ++ (get_key_offset(&key) + nr_units_ctail(coord) == ++ dclust_get_extension_dsize(hint))); ++} ++#endif ++ ++#define fifty_persent(size) (size >> 1) ++/* evaluation of data compressibility */ ++#define data_is_compressible(osize, isize) \ ++ (osize < fifty_persent(isize)) ++ ++/** ++ * A simple O(1)-heuristic for compressibility. ++ * This is called not more then one time per file's life. ++ * Read first logical cluster (of index #0) and estimate its compressibility. ++ * Save estimation result in @cont. ++ */ ++static int read_check_compressibility(struct inode * inode, ++ struct cluster_handle * clust, ++ struct psched_context * cont) ++{ ++ int i; ++ int result; ++ __u32 dst_len; ++ hint_t tmp_hint; ++ hint_t * cur_hint = clust->hint; ++ assert("edward-1541", cont->state == PSCHED_SCHED_POINT); ++ ++ start_check_compressibility(inode, clust, &tmp_hint); ++ ++ reset_cluster_pgset(clust, cluster_nrpages(inode)); ++ result = grab_page_cluster(inode, clust, READ_OP); ++ if (result) ++ return result; ++ /* Read page cluster here */ ++ for (i = 0; i < clust->nr_pages; i++) { ++ struct page *page = clust->pages[i]; ++ lock_page(page); ++ result = do_readpage_ctail(inode, clust, page, ++ ZNODE_READ_LOCK); ++ unlock_page(page); ++ if (result) ++ goto error; ++ } ++ tfm_cluster_clr_uptodate(&clust->tc); ++ ++ cluster_set_tfm_act(&clust->tc, TFMA_WRITE); ++ ++ if (hint_is_valid(&tmp_hint) && !hint_is_unprepped_dclust(&tmp_hint)) { ++ /* lenght of compressed data is known, no need to compress */ ++ assert("edward-1511", ++ znode_is_any_locked(tmp_hint.lh.node)); ++ assert("edward-1512", ++ WITH_DATA(tmp_hint.ext_coord.coord.node, ++ prepped_dclust_ok(&tmp_hint))); ++ dst_len = dclust_get_extension_dsize(&tmp_hint); ++ } ++ else { ++ struct tfm_cluster * tc = &clust->tc; ++ compression_plugin * cplug = inode_compression_plugin(inode); ++ result = grab_tfm_stream(inode, tc, INPUT_STREAM); ++ if (result) ++ goto error; ++ for (i = 0; i < clust->nr_pages; i++) { ++ char *data; ++ lock_page(clust->pages[i]); ++ BUG_ON(!PageUptodate(clust->pages[i])); ++ data = kmap(clust->pages[i]); ++ memcpy(tfm_stream_data(tc, INPUT_STREAM) + pg_to_off(i), ++ data, PAGE_CACHE_SIZE); ++ kunmap(clust->pages[i]); ++ unlock_page(clust->pages[i]); ++ } ++ result = grab_tfm_stream(inode, tc, OUTPUT_STREAM); ++ if (result) ++ goto error; ++ result = grab_coa(tc, cplug); ++ if (result) ++ goto error; ++ tc->len = tc->lsize = lbytes(clust->index, inode); ++ assert("edward-1513", tc->len == inode_cluster_size(inode)); ++ dst_len = tfm_stream_size(tc, OUTPUT_STREAM); ++ cplug->compress(get_coa(tc, cplug->h.id, tc->act), ++ tfm_input_data(clust), tc->len, ++ tfm_output_data(clust), &dst_len); ++ assert("edward-1514", ++ dst_len <= tfm_stream_size(tc, OUTPUT_STREAM)); ++ } ++ finish_check_compressibility(inode, clust, cur_hint); ++ cont->state = ++ (data_is_compressible(dst_len, inode_cluster_size(inode)) ? ++ PSCHED_REMAINS_OLD : ++ PSCHED_ASSIGNED_NEW); ++ return 0; ++ error: ++ put_page_cluster(clust, inode, READ_OP); ++ return result; ++} ++ ++/* Cut disk cluster of index @idx */ ++static int cut_disk_cluster(struct inode * inode, cloff_t idx) ++{ ++ reiser4_key from, to; ++ assert("edward-1515", inode_file_plugin(inode) == ++ file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID)); ++ key_by_inode_cryptcompress(inode, clust_to_off(idx, inode), &from); ++ to = from; ++ set_key_offset(&to, ++ get_key_offset(&from) + inode_cluster_size(inode) - 1); ++ return reiser4_cut_tree(reiser4_tree_by_inode(inode), ++ &from, &to, inode, 0); ++} ++ ++static int reserve_cryptcompress2unixfile(struct inode *inode) ++{ ++ reiser4_block_nr unformatted_nodes; ++ reiser4_tree *tree; ++ ++ tree = reiser4_tree_by_inode(inode); ++ ++ /* number of unformatted nodes which will be created */ ++ unformatted_nodes = cluster_nrpages(inode); /* N */ ++ ++ /* ++ * space required for one iteration of extent->tail conversion: ++ * ++ * 1. kill ctail items ++ * ++ * 2. insert N unformatted nodes ++ * ++ * 3. insert N (worst-case single-block ++ * extents) extent units. ++ * ++ * 4. drilling to the leaf level by coord_by_key() ++ * ++ * 5. possible update of stat-data ++ * ++ */ ++ grab_space_enable(); ++ return reiser4_grab_space ++ (2 * tree->height + ++ unformatted_nodes + ++ unformatted_nodes * estimate_one_insert_into_item(tree) + ++ 1 + estimate_one_insert_item(tree) + ++ inode_file_plugin(inode)->estimate.update(inode), ++ BA_CAN_COMMIT); ++} ++ ++/** ++ * Convert cryptcompress file plugin to unix_file plugin. ++ */ ++static int cryptcompress2unixfile(struct file * file, struct inode * inode, ++ struct psched_context * cont) ++{ ++ int i; ++ int result = 0; ++ struct cryptcompress_info *cr_info; ++ struct unix_file_info *uf_info; ++ assert("edward-1516", cont->pages[0]->index == 0); ++ ++ /* release all cryptcompress-specific resources */ ++ cr_info = cryptcompress_inode_data(inode); ++ result = reserve_cryptcompress2unixfile(inode); ++ if (result) ++ goto out; ++ /* tell kill_hook to not truncate pages */ ++ reiser4_inode_set_flag(inode, REISER4_FILE_CONV_IN_PROGRESS); ++ result = cut_disk_cluster(inode, 0); ++ if (result) ++ goto out; ++ /* captured jnode of cluster and assotiated resources (pages, ++ reserved disk space) were released by ->kill_hook() method ++ of the item plugin */ ++ ++ result = __cryptcompress2unixfile(file, inode); ++ if (result) ++ goto out; ++ /* At this point file is managed by unix file plugin */ ++ ++ uf_info = unix_file_inode_data(inode); ++ ++ assert("edward-1518", ++ ergo(jprivate(cont->pages[0]), ++ !jnode_is_cluster_page(jprivate(cont->pages[0])))); ++ for(i = 0; i < cont->nr_pages; i++) { ++ assert("edward-1519", cont->pages[i]); ++ assert("edward-1520", PageUptodate(cont->pages[i])); ++ ++ result = find_or_create_extent(cont->pages[i]); ++ if (result) ++ break; ++ } ++ if (unlikely(result)) ++ goto out; ++ uf_info->container = UF_CONTAINER_EXTENTS; ++ result = reiser4_update_sd(inode); ++ out: ++ all_grabbed2free(); ++ return result; ++} ++ ++#define convert_file_plugin cryptcompress2unixfile ++ ++/** ++ * This is called by ->write() method of a cryptcompress file plugin. ++ * Make a decision about the most reasonable file plugin id to manage ++ * the file. ++ */ ++int write_pschedule_hook(struct file * file, struct inode * inode, ++ loff_t pos, struct cluster_handle * clust, ++ struct psched_context * cont) ++{ ++ int result; ++ if (!conversion_enabled(inode)) ++ return 0; ++ result = check_psched_point(inode, pos, clust, cont); ++ if (result || cont->state != PSCHED_SCHED_POINT) ++ return result; ++ result = read_check_compressibility(inode, clust, cont); ++ if (result) ++ return result; ++ if (cont->state == PSCHED_REMAINS_OLD) { ++ put_page_cluster(clust, inode, READ_OP); ++ return disable_conversion(inode); ++ } ++ assert("edward-1543", cont->state == PSCHED_ASSIGNED_NEW); ++ /* ++ * page cluster is grabbed and uptodate. It will be ++ * released with a pgset after plugin conversion is ++ * finished, see put_psched_context(). ++ */ ++ reiser4_unset_hint(clust->hint); ++ move_cluster_pgset(clust, &cont->pages, &cont->nr_pages); ++ return 0; ++} ++ ++/** ++ * This is called by ->setattr() method of cryptcompress file plugin. ++ */ ++int setattr_pschedule_hook(struct inode * inode) ++{ ++ if (conversion_enabled(inode)) ++ return disable_conversion(inode); ++ return 0; ++} ++ ++static inline void init_psched_context(struct psched_context * cont) ++{ ++ memset(cont, 0, sizeof(*cont)); ++} ++ ++static inline void done_psched_context(struct psched_context * cont, ++ struct inode * inode) ++{ ++ if (cont->pages) { ++ __put_page_cluster(0, cont->nr_pages, cont->pages, inode); ++ kfree(cont->pages); ++ } ++} ++/** ++ * Here are wrappers with "protection", aka Reiser4 "careful" methods. ++ * They are used by vfs (as methods of file_ops, inode_ops or as_ops), ++ * which is not aware of plugin conversion performed by Reiser4. ++ */ ++ ++/* ++ * Wrappers with active protection for: ++ * ++ * ->write(); ++ */ ++ ++/* ++ * ->write() file operation supplied to VFS. ++ * Write a file in 3 steps (some of them can be optional). ++ */ ++ssize_t reiser4_write_careful(struct file *file, const char __user *buf, ++ size_t count, loff_t *off) ++{ ++ int result; ++ reiser4_context *ctx; ++ ssize_t written_old = 0; /* bytes written with initial plugin */ ++ ssize_t written_new = 0; /* bytes written with new plugin */ ++ struct psched_context cont; ++ struct inode * inode = file->f_dentry->d_inode; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ init_psched_context(&cont); ++ mutex_lock(&inode->i_mutex); ++ /** ++ * First step. ++ * Start write with initial file plugin. ++ * Keep a plugin schedule status at @cont (if any). ++ */ ++ written_old = inode_file_plugin(inode)->write(file, ++ buf, ++ count, ++ off, ++ &cont); ++ if (cont.state != PSCHED_ASSIGNED_NEW || written_old < 0) ++ goto exit; ++ /** ++ * Second step. ++ * New file plugin has been scheduled. ++ * Perform conversion to the new plugin. ++ */ ++ down_read(&reiser4_inode_data(inode)->conv_sem); ++ result = convert_file_plugin(file, inode, &cont); ++ up_read(&reiser4_inode_data(inode)->conv_sem); ++ if (result) { ++ warning("edward-1544", ++ "Inode %llu: file plugin conversion failed (%d)", ++ (unsigned long long)get_inode_oid(inode), ++ result); ++ context_set_commit_async(ctx); ++ goto exit; ++ } ++ reiser4_txn_restart(ctx); ++ /** ++ * Third step: ++ * Finish write with the new file plugin. ++ */ ++ assert("edward-1536", ++ inode_file_plugin(inode) == ++ file_plugin_by_id(UNIX_FILE_PLUGIN_ID)); ++ ++ written_new = inode_file_plugin(inode)->write(file, ++ buf + written_old, ++ count - written_old, ++ off, ++ NULL); ++ exit: ++ mutex_unlock(&inode->i_mutex); ++ done_psched_context(&cont, inode); ++ reiser4_exit_context(ctx); ++ ++ return written_old + (written_new < 0 ? 0 : written_new); ++} ++ ++/* Wrappers with passive protection for: ++ * ++ * ->open(); ++ * ->read(); ++ * ->ioctl(); ++ * ->mmap(); ++ * ->release(); ++ * ->bmap(). ++ */ ++ ++int reiser4_open_careful(struct inode *inode, struct file *file) ++{ ++ return PROT_PASSIVE(int, open, (inode, file)); ++} ++ ++ssize_t reiser4_read_careful(struct file * file, char __user * buf, ++ size_t size, loff_t * off) ++{ ++ struct inode * inode = file->f_dentry->d_inode; ++ return PROT_PASSIVE(ssize_t, read, (file, buf, size, off)); ++} ++ ++int reiser4_ioctl_careful(struct inode *inode, struct file *filp, ++ unsigned int cmd, unsigned long arg) ++{ ++ return PROT_PASSIVE(int, ioctl, (inode, filp, cmd, arg)); ++} ++ ++int reiser4_mmap_careful(struct file *file, struct vm_area_struct *vma) ++{ ++ struct inode *inode = file->f_dentry->d_inode; ++ return PROT_PASSIVE(int, mmap, (file, vma)); ++} ++ ++int reiser4_release_careful(struct inode *inode, struct file *file) ++{ ++ return PROT_PASSIVE(int, release, (inode, file)); ++} ++ ++sector_t reiser4_bmap_careful(struct address_space * mapping, sector_t lblock) ++{ ++ struct inode *inode = mapping->host; ++ return PROT_PASSIVE(sector_t, bmap, (mapping, lblock)); ++} ++ ++/** ++ * NOTE: The following two methods are ++ * used only for loopback functionality. ++ * reiser4_write_end() can not cope with ++ * short writes for now. ++ */ ++int reiser4_write_begin_careful(struct file *file, ++ struct address_space *mapping, ++ loff_t pos, ++ unsigned len, ++ unsigned flags, ++ struct page **pagep, ++ void **fsdata) ++{ ++ int ret = 0; ++ unsigned start, end; ++ struct page *page; ++ pgoff_t index; ++ reiser4_context *ctx; ++ struct inode * inode = file->f_dentry->d_inode; ++ ++ index = pos >> PAGE_CACHE_SHIFT; ++ start = pos & (PAGE_CACHE_SIZE - 1); ++ end = start + len; ++ ++ page = grab_cache_page_write_begin(mapping, index, ++ flags & AOP_FLAG_NOFS); ++ *pagep = page; ++ if (!page) ++ return -ENOMEM; ++ ++ ctx = reiser4_init_context(file->f_dentry->d_inode->i_sb); ++ if (IS_ERR(ctx)) { ++ ret = PTR_ERR(ctx); ++ goto out; ++ } ++ ret = PROT_PASSIVE(int, write_begin, (file, page, start, end)); ++ ++ /* don't commit transaction under inode semaphore */ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ out: ++ if (unlikely(ret)) { ++ unlock_page(page); ++ page_cache_release(page); ++ } ++ return ret; ++} ++ ++int reiser4_write_end_careful(struct file *file, ++ struct address_space *mapping, ++ loff_t pos, ++ unsigned len, ++ unsigned copied, ++ struct page *page, ++ void *fsdata) ++{ ++ int ret; ++ reiser4_context *ctx; ++ unsigned start, end; ++ struct inode *inode = page->mapping->host; ++ ++ assert("umka-3101", file != NULL); ++ assert("umka-3102", page != NULL); ++ assert("umka-3093", PageLocked(page)); ++ ++ start = pos & (PAGE_CACHE_SIZE - 1); ++ end = start + len; ++ ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ ++ ctx = reiser4_init_context(page->mapping->host->i_sb); ++ if (IS_ERR(ctx)){ ++ unlock_page(page); ++ ret = PTR_ERR(ctx); ++ goto out; ++ } ++ ret = PROT_PASSIVE(int, write_end, (file, page, start, end)); ++ ++ /* don't commit transaction under inode semaphore */ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ out: ++ page_cache_release(page); ++ if (!ret) ++ ret = copied; ++ return ret; ++} ++ ++/* ++ * Wrappers without protection for: ++ * ++ * ->setattr() ++ */ ++int reiser4_setattr(struct dentry *dentry, struct iattr *attr) ++{ ++ return inode_file_plugin(dentry->d_inode)->setattr(dentry, attr); ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file/file.h linux-2.6.30/fs/reiser4/plugin/file/file.h +--- linux-2.6.30.orig/fs/reiser4/plugin/file/file.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file/file.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,336 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* this file contains declarations of methods implementing ++ file plugins (UNIX_FILE_PLUGIN_ID, CRYPTCOMPRESS_FILE_PLUGIN_ID ++ and SYMLINK_FILE_PLUGIN_ID) */ ++ ++#if !defined( __REISER4_FILE_H__ ) ++#define __REISER4_FILE_H__ ++ ++/* possible states when scheduling a new file plugin */ ++typedef enum { ++ PSCHED_INVAL_STATE, /* invalid state */ ++ PSCHED_SCHED_POINT, /* scheduling point has been achieved */ ++ PSCHED_REMAINS_OLD, /* made a decision to be managed by old plugin */ ++ PSCHED_ASSIGNED_NEW /* new plugin has been scheduled */ ++} psched_state; ++ ++struct psched_context { ++ int nr_pages; ++ struct page **pages; ++ psched_state state; ++}; ++ ++/** ++ * Declarations of common/careful/generic methods. ++ * Suppose ->foo() is a vs method (of f_ops, i_ops, or a_ops); ++ * Then common reiser4 method for foo looks like reiser4_foo_common; ++ * careful method looks like reiser4_foo_careful; ++ * generic method looks like reiser4_foo. ++ * ++ * Common method is a simple instruction set eligible for more ++ * then one plugin id. ++ * ++ * Generic method looks at the plugin installed in inode's ++ * plugin set and calls its appropriate method. ++ * ++ * Careful method looks like generic method with protected pset ++ * (see plugin/file/file_conversion.c for details). ++ */ ++ ++/* inode operations */ ++int reiser4_setattr(struct dentry *, struct iattr *); ++ ++/* file operations */ ++ssize_t reiser4_read_careful(struct file *, char __user *buf, ++ size_t count, loff_t *off); ++ssize_t reiser4_write_careful(struct file *, const char __user *buf, ++ size_t count, loff_t * off); ++int reiser4_ioctl_careful(struct inode *inode, struct file *filp, ++ unsigned int cmd, unsigned long arg); ++int reiser4_mmap_careful(struct file *, struct vm_area_struct *); ++int reiser4_open_careful(struct inode *inode, struct file *file); ++int reiser4_release_careful(struct inode *, struct file *); ++int reiser4_sync_file_common(struct file *, struct dentry *, int datasync); ++ ++/* address space operations */ ++int reiser4_readpage(struct file *, struct page *); ++int reiser4_readpages(struct file*, struct address_space*, struct list_head*, ++ unsigned); ++int reiser4_writepages(struct address_space *, struct writeback_control *); ++int reiser4_write_begin_careful(struct file *file, ++ struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned flags, ++ struct page **pagep, void **fsdata); ++int reiser4_write_end_careful(struct file *file, ++ struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned copied, ++ struct page *page, void *fsdata); ++sector_t reiser4_bmap_careful(struct address_space *, sector_t lblock); ++ ++/* ++ * Private methods of unix-file plugin ++ * (UNIX_FILE_PLUGIN_ID) ++ */ ++ ++/* private inode operations */ ++int setattr_unix_file(struct dentry *, struct iattr *); ++ ++/* private file operations */ ++ ++ssize_t read_unix_file(struct file *, char __user *buf, size_t read_amount, ++ loff_t *off); ++ssize_t write_unix_file(struct file *, const char __user *buf, size_t write_amount, ++ loff_t * off, struct psched_context * cont); ++int ioctl_unix_file(struct inode *, struct file *, unsigned int cmd, ++ unsigned long arg); ++int mmap_unix_file(struct file *, struct vm_area_struct *); ++int open_unix_file(struct inode *, struct file *); ++int release_unix_file(struct inode *, struct file *); ++ ++/* private address space operations */ ++int readpage_unix_file(struct file *, struct page *); ++int readpages_unix_file(struct file*, struct address_space*, struct list_head*, ++ unsigned); ++int writepages_unix_file(struct address_space *, struct writeback_control *); ++int write_begin_unix_file(struct file *file, struct page *page, ++ unsigned from, unsigned to); ++int write_end_unix_file(struct file *file, struct page *page, ++ unsigned from, unsigned to); ++sector_t bmap_unix_file(struct address_space *, sector_t lblock); ++ ++/* other private methods */ ++int delete_object_unix_file(struct inode *); ++int flow_by_inode_unix_file(struct inode *, const char __user *buf, ++ int user, loff_t, loff_t, rw_op, flow_t *); ++int owns_item_unix_file(const struct inode *, const coord_t *); ++void init_inode_data_unix_file(struct inode *, reiser4_object_create_data *, ++ int create); ++ ++/* ++ * Private methods of cryptcompress file plugin ++ * (CRYPTCOMPRESS_FILE_PLUGIN_ID) ++ */ ++ ++/* private inode operations */ ++int setattr_cryptcompress(struct dentry *, struct iattr *); ++ ++/* private file operations */ ++ssize_t read_cryptcompress(struct file *, char __user *buf, ++ size_t count, loff_t *off); ++ssize_t write_cryptcompress(struct file *, const char __user *buf, ++ size_t count, loff_t * off, ++ struct psched_context *cont); ++int ioctl_cryptcompress(struct inode *, struct file *, unsigned int cmd, ++ unsigned long arg); ++int mmap_cryptcompress(struct file *, struct vm_area_struct *); ++int open_cryptcompress(struct inode *, struct file *); ++int release_cryptcompress(struct inode *, struct file *); ++ ++/* private address space operations */ ++int readpage_cryptcompress(struct file *, struct page *); ++int readpages_cryptcompress(struct file*, struct address_space*, ++ struct list_head*, unsigned); ++int writepages_cryptcompress(struct address_space *, ++ struct writeback_control *); ++int write_begin_cryptcompress(struct file *file, struct page *page, ++ unsigned from, unsigned to); ++int write_end_cryptcompress(struct file *file, struct page *page, ++ unsigned from, unsigned to); ++sector_t bmap_cryptcompress(struct address_space *, sector_t lblock); ++ ++/* other private methods */ ++int flow_by_inode_cryptcompress(struct inode *, const char __user *buf, ++ int user, loff_t, loff_t, rw_op, flow_t *); ++int key_by_inode_cryptcompress(struct inode *, loff_t off, reiser4_key *); ++int create_object_cryptcompress(struct inode *, struct inode *, ++ reiser4_object_create_data *); ++int delete_object_cryptcompress(struct inode *); ++void init_inode_data_cryptcompress(struct inode *, reiser4_object_create_data *, ++ int create); ++int cut_tree_worker_cryptcompress(tap_t *, const reiser4_key * from_key, ++ const reiser4_key * to_key, ++ reiser4_key * smallest_removed, ++ struct inode *object, int truncate, ++ int *progress); ++void destroy_inode_cryptcompress(struct inode *); ++ ++/* ++ * Private methods of symlink file plugin ++ * (SYMLINK_FILE_PLUGIN_ID) ++ */ ++int reiser4_create_symlink(struct inode *symlink, struct inode *dir, ++ reiser4_object_create_data *); ++void destroy_inode_symlink(struct inode *); ++ ++/* ++ * all the write into unix file is performed by item write method. Write method ++ * of unix file plugin only decides which item plugin (extent or tail) and in ++ * which mode (one from the enum below) to call ++ */ ++typedef enum { ++ FIRST_ITEM = 1, ++ APPEND_ITEM = 2, ++ OVERWRITE_ITEM = 3 ++} write_mode_t; ++ ++/* unix file may be in one the following states */ ++typedef enum { ++ UF_CONTAINER_UNKNOWN = 0, ++ UF_CONTAINER_TAILS = 1, ++ UF_CONTAINER_EXTENTS = 2, ++ UF_CONTAINER_EMPTY = 3 ++} file_container_t; ++ ++struct formatting_plugin; ++struct inode; ++ ++/* unix file plugin specific part of reiser4 inode */ ++struct unix_file_info { ++ /* ++ * this read-write lock protects file containerization change. Accesses ++ * which do not change file containerization (see file_container_t) ++ * (read, readpage, writepage, write (until tail conversion is ++ * involved)) take read-lock. Accesses which modify file ++ * containerization (truncate, conversion from tail to extent and back) ++ * take write-lock. ++ */ ++ struct rw_semaphore latch; ++ /* this enum specifies which items are used to build the file */ ++ file_container_t container; ++ /* ++ * plugin which controls when file is to be converted to extents and ++ * back to tail ++ */ ++ struct formatting_plugin *tplug; ++ /* if this is set, file is in exclusive use */ ++ int exclusive_use; ++#if REISER4_DEBUG ++ /* pointer to task struct of thread owning exclusive access to file */ ++ void *ea_owner; ++ atomic_t nr_neas; ++ void *last_reader; ++#endif ++}; ++ ++struct unix_file_info *unix_file_inode_data(const struct inode *inode); ++void get_exclusive_access(struct unix_file_info *); ++void drop_exclusive_access(struct unix_file_info *); ++void get_nonexclusive_access(struct unix_file_info *); ++void drop_nonexclusive_access(struct unix_file_info *); ++int try_to_get_nonexclusive_access(struct unix_file_info *); ++int find_file_item(hint_t *, const reiser4_key *, znode_lock_mode, ++ struct inode *); ++int find_file_item_nohint(coord_t *, lock_handle *, ++ const reiser4_key *, znode_lock_mode, ++ struct inode *); ++ ++int load_file_hint(struct file *, hint_t *); ++void save_file_hint(struct file *, const hint_t *); ++ ++#include "../item/extent.h" ++#include "../item/tail.h" ++#include "../item/ctail.h" ++ ++struct uf_coord { ++ coord_t coord; ++ lock_handle *lh; ++ int valid; ++ union { ++ struct extent_coord_extension extent; ++ struct tail_coord_extension tail; ++ struct ctail_coord_extension ctail; ++ } extension; ++}; ++ ++#include "../../forward.h" ++#include "../../seal.h" ++#include "../../lock.h" ++ ++/* ++ * This structure is used to speed up file operations (reads and writes). A ++ * hint is a suggestion about where a key resolved to last time. A seal ++ * indicates whether a node has been modified since a hint was last recorded. ++ * You check the seal, and if the seal is still valid, you can use the hint ++ * without traversing the tree again. ++ */ ++struct hint { ++ seal_t seal; /* a seal over last file item accessed */ ++ uf_coord_t ext_coord; ++ loff_t offset; ++ znode_lock_mode mode; ++ lock_handle lh; ++}; ++ ++static inline int hint_is_valid(hint_t * hint) ++{ ++ return hint->ext_coord.valid; ++} ++ ++static inline void hint_set_valid(hint_t * hint) ++{ ++ hint->ext_coord.valid = 1; ++} ++ ++static inline void hint_clr_valid(hint_t * hint) ++{ ++ hint->ext_coord.valid = 0; ++} ++ ++int load_file_hint(struct file *, hint_t *); ++void save_file_hint(struct file *, const hint_t *); ++void hint_init_zero(hint_t *); ++void reiser4_set_hint(hint_t *, const reiser4_key *, znode_lock_mode); ++int hint_is_set(const hint_t *); ++void reiser4_unset_hint(hint_t *); ++ ++int reiser4_update_file_size(struct inode *, loff_t, int update_sd); ++int cut_file_items(struct inode *, loff_t new_size, ++ int update_sd, loff_t cur_size, ++ int (*update_actor) (struct inode *, loff_t, int)); ++#if REISER4_DEBUG ++ ++/* return 1 is exclusive access is obtained, 0 - otherwise */ ++static inline int ea_obtained(struct unix_file_info * uf_info) ++{ ++ int ret; ++ ++ ret = down_read_trylock(&uf_info->latch); ++ if (ret) ++ up_read(&uf_info->latch); ++ return !ret; ++} ++ ++#endif ++ ++#define WRITE_GRANULARITY 32 ++ ++int tail2extent(struct unix_file_info *); ++int extent2tail(struct file *, struct unix_file_info *); ++ ++int goto_right_neighbor(coord_t *, lock_handle *); ++int find_or_create_extent(struct page *); ++int equal_to_ldk(znode *, const reiser4_key *); ++ ++void init_uf_coord(uf_coord_t *uf_coord, lock_handle *lh); ++ ++static inline int cbk_errored(int cbk_result) ++{ ++ return (cbk_result != CBK_COORD_NOTFOUND ++ && cbk_result != CBK_COORD_FOUND); ++} ++ ++/* __REISER4_FILE_H__ */ ++#endif ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file/Makefile linux-2.6.30/fs/reiser4/plugin/file/Makefile +--- linux-2.6.30.orig/fs/reiser4/plugin/file/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,7 @@ ++obj-$(CONFIG_REISER4_FS) += file_plugins.o ++ ++file_plugins-objs := \ ++ file.o \ ++ tail_conversion.o \ ++ symlink.o \ ++ cryptcompress.o +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file/symfile.c linux-2.6.30/fs/reiser4/plugin/file/symfile.c +--- linux-2.6.30.orig/fs/reiser4/plugin/file/symfile.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file/symfile.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,87 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Symfiles are a generalization of Unix symlinks. ++ ++ A symfile when read behaves as though you took its contents and ++ substituted them into the reiser4 naming system as the right hand side ++ of an assignment, and then read that which you had assigned to it. ++ ++ A key issue for symfiles is how to implement writes through to ++ subfiles. In general, one must have some method of determining what ++ of that which is written to the symfile is written to what subfile. ++ This can be done by use of custom plugin methods written by users, or ++ by using a few general methods we provide for those willing to endure ++ the insertion of delimiters into what is read. ++ ++ Writing to symfiles without delimiters to denote what is written to ++ what subfile is not supported by any plugins we provide in this ++ release. Our most sophisticated support for writes is that embodied ++ by the invert plugin (see invert.c). ++ ++ A read only version of the /etc/passwd file might be ++ constructed as a symfile whose contents are as follows: ++ ++ /etc/passwd/userlines/* ++ ++ or ++ ++ /etc/passwd/userlines/demidov+/etc/passwd/userlines/edward+/etc/passwd/userlines/reiser+/etc/passwd/userlines/root ++ ++ or ++ ++ /etc/passwd/userlines/(demidov+edward+reiser+root) ++ ++ A symfile with contents ++ ++ /filenameA+"(some text stored in the uninvertable symfile)+/filenameB ++ ++ will return when read ++ ++ The contents of filenameAsome text stored in the uninvertable symfileThe contents of filenameB ++ ++ and write of what has been read will not be possible to implement as ++ an identity operation because there are no delimiters denoting the ++ boundaries of what is to be written to what subfile. ++ ++ Note that one could make this a read/write symfile if one specified ++ delimiters, and the write method understood those delimiters delimited ++ what was written to subfiles. ++ ++ So, specifying the symfile in a manner that allows writes: ++ ++ /etc/passwd/userlines/demidov+"( ++ )+/etc/passwd/userlines/edward+"( ++ )+/etc/passwd/userlines/reiser+"( ++ )+/etc/passwd/userlines/root+"( ++ ) ++ ++ or ++ ++ /etc/passwd/userlines/(demidov+"( ++ )+edward+"( ++ )+reiser+"( ++ )+root+"( ++ )) ++ ++ and the file demidov might be specified as: ++ ++ /etc/passwd/userlines/demidov/username+"(:)+/etc/passwd/userlines/demidov/password+"(:)+/etc/passwd/userlines/demidov/userid+"(:)+/etc/passwd/userlines/demidov/groupid+"(:)+/etc/passwd/userlines/demidov/gecos+"(:)+/etc/passwd/userlines/demidov/home+"(:)+/etc/passwd/userlines/demidov/shell ++ ++ or ++ ++ /etc/passwd/userlines/demidov/(username+"(:)+password+"(:)+userid+"(:)+groupid+"(:)+gecos+"(:)+home+"(:)+shell) ++ ++ Notice that if the file demidov has a carriage return in it, the ++ parsing fails, but then if you put carriage returns in the wrong place ++ in a normal /etc/passwd file it breaks things also. ++ ++ Note that it is forbidden to have no text between two interpolations ++ if one wants to be able to define what parts of a write go to what ++ subfiles referenced in an interpolation. ++ ++ If one wants to be able to add new lines by writing to the file, one ++ must either write a custom plugin for /etc/passwd that knows how to ++ name an added line, or one must use an invert, or one must use a more ++ sophisticated symfile syntax that we are not planning to write for ++ version 4.0. ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file/symlink.c linux-2.6.30/fs/reiser4/plugin/file/symlink.c +--- linux-2.6.30.orig/fs/reiser4/plugin/file/symlink.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file/symlink.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,95 @@ ++/* Copyright 2002, 2003, 2005 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "../../inode.h" ++ ++#include <linux/types.h> ++#include <linux/fs.h> ++ ++/* file plugin methods specific for symlink files ++ (SYMLINK_FILE_PLUGIN_ID) */ ++ ++/* this is implementation of create_object method of file plugin for ++ SYMLINK_FILE_PLUGIN_ID ++ */ ++ ++/** ++ * reiser4_create_symlink - create_object of file plugin for SYMLINK_FILE_PLUGIN_ID ++ * @symlink: inode of symlink object ++ * @dir: inode of parent directory ++ * @info: parameters of new object ++ * ++ * Inserts stat data with symlink extension where into the tree. ++ */ ++int reiser4_create_symlink(struct inode *symlink, ++ struct inode *dir UNUSED_ARG, ++ reiser4_object_create_data *data /* info passed to us ++ * this is filled by ++ * reiser4() syscall ++ * in particular */) ++{ ++ int result; ++ ++ assert("nikita-680", symlink != NULL); ++ assert("nikita-681", S_ISLNK(symlink->i_mode)); ++ assert("nikita-685", reiser4_inode_get_flag(symlink, REISER4_NO_SD)); ++ assert("nikita-682", dir != NULL); ++ assert("nikita-684", data != NULL); ++ assert("nikita-686", data->id == SYMLINK_FILE_PLUGIN_ID); ++ ++ /* ++ * stat data of symlink has symlink extension in which we store ++ * symlink content, that is, path symlink is pointing to. ++ */ ++ reiser4_inode_data(symlink)->extmask |= (1 << SYMLINK_STAT); ++ ++ assert("vs-838", symlink->i_private == NULL); ++ symlink->i_private = (void *)data->name; ++ ++ assert("vs-843", symlink->i_size == 0); ++ INODE_SET_FIELD(symlink, i_size, strlen(data->name)); ++ ++ /* insert stat data appended with data->name */ ++ result = inode_file_plugin(symlink)->write_sd_by_inode(symlink); ++ if (result) { ++ /* FIXME-VS: Make sure that symlink->i_private is not attached ++ to kmalloced data */ ++ INODE_SET_FIELD(symlink, i_size, 0); ++ } else { ++ assert("vs-849", symlink->i_private ++ && reiser4_inode_get_flag(symlink, ++ REISER4_GENERIC_PTR_USED)); ++ assert("vs-850", ++ !memcmp((char *)symlink->i_private, data->name, ++ (size_t) symlink->i_size + 1)); ++ } ++ return result; ++} ++ ++/* this is implementation of destroy_inode method of file plugin for ++ SYMLINK_FILE_PLUGIN_ID ++ */ ++void destroy_inode_symlink(struct inode *inode) ++{ ++ assert("edward-799", ++ inode_file_plugin(inode) == ++ file_plugin_by_id(SYMLINK_FILE_PLUGIN_ID)); ++ assert("edward-800", !is_bad_inode(inode) && is_inode_loaded(inode)); ++ assert("edward-801", reiser4_inode_get_flag(inode, ++ REISER4_GENERIC_PTR_USED)); ++ assert("vs-839", S_ISLNK(inode->i_mode)); ++ ++ kfree(inode->i_private); ++ inode->i_private = NULL; ++ reiser4_inode_clr_flag(inode, REISER4_GENERIC_PTR_USED); ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file/tail_conversion.c linux-2.6.30/fs/reiser4/plugin/file/tail_conversion.c +--- linux-2.6.30.orig/fs/reiser4/plugin/file/tail_conversion.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file/tail_conversion.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,737 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "../../inode.h" ++#include "../../super.h" ++#include "../../page_cache.h" ++#include "../../carry.h" ++#include "../../safe_link.h" ++#include "../../vfs_ops.h" ++ ++#include <linux/writeback.h> ++ ++/* this file contains: ++ tail2extent and extent2tail */ ++ ++/* exclusive access to a file is acquired when file state changes: tail2extent, empty2tail, extent2tail, etc */ ++void get_exclusive_access(struct unix_file_info * uf_info) ++{ ++ assert("nikita-3028", reiser4_schedulable()); ++ assert("nikita-3047", LOCK_CNT_NIL(inode_sem_w)); ++ assert("nikita-3048", LOCK_CNT_NIL(inode_sem_r)); ++ /* ++ * "deadlock avoidance": sometimes we commit a transaction under ++ * rw-semaphore on a file. Such commit can deadlock with another ++ * thread that captured some block (hence preventing atom from being ++ * committed) and waits on rw-semaphore. ++ */ ++ reiser4_txn_restart_current(); ++ LOCK_CNT_INC(inode_sem_w); ++ down_write(&uf_info->latch); ++ uf_info->exclusive_use = 1; ++ assert("vs-1713", uf_info->ea_owner == NULL); ++ assert("vs-1713", atomic_read(&uf_info->nr_neas) == 0); ++ ON_DEBUG(uf_info->ea_owner = current); ++} ++ ++void drop_exclusive_access(struct unix_file_info * uf_info) ++{ ++ assert("vs-1714", uf_info->ea_owner == current); ++ assert("vs-1715", atomic_read(&uf_info->nr_neas) == 0); ++ ON_DEBUG(uf_info->ea_owner = NULL); ++ uf_info->exclusive_use = 0; ++ up_write(&uf_info->latch); ++ assert("nikita-3049", LOCK_CNT_NIL(inode_sem_r)); ++ assert("nikita-3049", LOCK_CNT_GTZ(inode_sem_w)); ++ LOCK_CNT_DEC(inode_sem_w); ++ reiser4_txn_restart_current(); ++} ++ ++/** ++ * nea_grabbed - do something when file semaphore is down_read-ed ++ * @uf_info: ++ * ++ * This is called when nonexclisive access is obtained on file. All it does is ++ * for debugging purposes. ++ */ ++static void nea_grabbed(struct unix_file_info *uf_info) ++{ ++#if REISER4_DEBUG ++ LOCK_CNT_INC(inode_sem_r); ++ assert("vs-1716", uf_info->ea_owner == NULL); ++ atomic_inc(&uf_info->nr_neas); ++ uf_info->last_reader = current; ++#endif ++} ++ ++/** ++ * get_nonexclusive_access - get nonexclusive access to a file ++ * @uf_info: unix file specific part of inode to obtain access to ++ * ++ * Nonexclusive access is obtained on a file before read, write, readpage. ++ */ ++void get_nonexclusive_access(struct unix_file_info *uf_info) ++{ ++ assert("nikita-3029", reiser4_schedulable()); ++ assert("nikita-3361", get_current_context()->trans->atom == NULL); ++ ++ down_read(&uf_info->latch); ++ nea_grabbed(uf_info); ++} ++ ++/** ++ * try_to_get_nonexclusive_access - try to get nonexclusive access to a file ++ * @uf_info: unix file specific part of inode to obtain access to ++ * ++ * Non-blocking version of nonexclusive access obtaining. ++ */ ++int try_to_get_nonexclusive_access(struct unix_file_info *uf_info) ++{ ++ int result; ++ ++ result = down_read_trylock(&uf_info->latch); ++ if (result) ++ nea_grabbed(uf_info); ++ return result; ++} ++ ++void drop_nonexclusive_access(struct unix_file_info * uf_info) ++{ ++ assert("vs-1718", uf_info->ea_owner == NULL); ++ assert("vs-1719", atomic_read(&uf_info->nr_neas) > 0); ++ ON_DEBUG(atomic_dec(&uf_info->nr_neas)); ++ ++ up_read(&uf_info->latch); ++ ++ LOCK_CNT_DEC(inode_sem_r); ++ reiser4_txn_restart_current(); ++} ++ ++/* part of tail2extent. Cut all items covering @count bytes starting from ++ @offset */ ++/* Audited by: green(2002.06.15) */ ++static int cut_formatting_items(struct inode *inode, loff_t offset, int count) ++{ ++ reiser4_key from, to; ++ ++ /* AUDIT: How about putting an assertion here, what would check ++ all provided range is covered by tail items only? */ ++ /* key of first byte in the range to be cut */ ++ inode_file_plugin(inode)->key_by_inode(inode, offset, &from); ++ ++ /* key of last byte in that range */ ++ to = from; ++ set_key_offset(&to, (__u64) (offset + count - 1)); ++ ++ /* cut everything between those keys */ ++ return reiser4_cut_tree(reiser4_tree_by_inode(inode), &from, &to, ++ inode, 0); ++} ++ ++static void release_all_pages(struct page **pages, unsigned nr_pages) ++{ ++ unsigned i; ++ ++ for (i = 0; i < nr_pages; i++) { ++ if (pages[i] == NULL) { ++#if REISER4_DEBUG ++ unsigned j; ++ for (j = i + 1; j < nr_pages; j++) ++ assert("vs-1620", pages[j] == NULL); ++#endif ++ break; ++ } ++ page_cache_release(pages[i]); ++ pages[i] = NULL; ++ } ++} ++ ++/* part of tail2extent. replace tail items with extent one. Content of tail ++ items (@count bytes) being cut are copied already into ++ pages. extent_writepage method is called to create extents corresponding to ++ those pages */ ++static int replace(struct inode *inode, struct page **pages, unsigned nr_pages, int count) ++{ ++ int result; ++ unsigned i; ++ STORE_COUNTERS; ++ ++ if (nr_pages == 0) ++ return 0; ++ ++ assert("vs-596", pages[0]); ++ ++ /* cut copied items */ ++ result = cut_formatting_items(inode, page_offset(pages[0]), count); ++ if (result) ++ return result; ++ ++ CHECK_COUNTERS; ++ ++ /* put into tree replacement for just removed items: extent item, namely */ ++ for (i = 0; i < nr_pages; i++) { ++ result = add_to_page_cache_lru(pages[i], inode->i_mapping, ++ pages[i]->index, ++ mapping_gfp_mask(inode-> ++ i_mapping)); ++ if (result) ++ break; ++ unlock_page(pages[i]); ++ result = find_or_create_extent(pages[i]); ++ if (result) ++ break; ++ SetPageUptodate(pages[i]); ++ } ++ return result; ++} ++ ++#define TAIL2EXTENT_PAGE_NUM 3 /* number of pages to fill before cutting tail ++ * items */ ++ ++static int reserve_tail2extent_iteration(struct inode *inode) ++{ ++ reiser4_block_nr unformatted_nodes; ++ reiser4_tree *tree; ++ ++ tree = reiser4_tree_by_inode(inode); ++ ++ /* number of unformatted nodes which will be created */ ++ unformatted_nodes = TAIL2EXTENT_PAGE_NUM; ++ ++ /* ++ * space required for one iteration of extent->tail conversion: ++ * ++ * 1. kill N tail items ++ * ++ * 2. insert TAIL2EXTENT_PAGE_NUM unformatted nodes ++ * ++ * 3. insert TAIL2EXTENT_PAGE_NUM (worst-case single-block ++ * extents) extent units. ++ * ++ * 4. drilling to the leaf level by coord_by_key() ++ * ++ * 5. possible update of stat-data ++ * ++ */ ++ grab_space_enable(); ++ return reiser4_grab_space ++ (2 * tree->height + ++ TAIL2EXTENT_PAGE_NUM + ++ TAIL2EXTENT_PAGE_NUM * estimate_one_insert_into_item(tree) + ++ 1 + estimate_one_insert_item(tree) + ++ inode_file_plugin(inode)->estimate.update(inode), BA_CAN_COMMIT); ++} ++ ++/* clear stat data's flag indicating that conversion is being converted */ ++static int complete_conversion(struct inode *inode) ++{ ++ int result; ++ ++ grab_space_enable(); ++ result = ++ reiser4_grab_space(inode_file_plugin(inode)->estimate.update(inode), ++ BA_CAN_COMMIT); ++ if (result == 0) { ++ reiser4_inode_clr_flag(inode, REISER4_PART_MIXED); ++ result = reiser4_update_sd(inode); ++ } ++ if (result) ++ warning("vs-1696", "Failed to clear converting bit of %llu: %i", ++ (unsigned long long)get_inode_oid(inode), result); ++ return 0; ++} ++ ++/** ++ * find_start ++ * @inode: ++ * @id: ++ * @offset: ++ * ++ * this is used by tail2extent and extent2tail to detect where previous ++ * uncompleted conversion stopped ++ */ ++static int find_start(struct inode *inode, reiser4_plugin_id id, __u64 *offset) ++{ ++ int result; ++ lock_handle lh; ++ coord_t coord; ++ struct unix_file_info *ufo; ++ int found; ++ reiser4_key key; ++ ++ ufo = unix_file_inode_data(inode); ++ init_lh(&lh); ++ result = 0; ++ found = 0; ++ inode_file_plugin(inode)->key_by_inode(inode, *offset, &key); ++ do { ++ init_lh(&lh); ++ result = find_file_item_nohint(&coord, &lh, &key, ++ ZNODE_READ_LOCK, inode); ++ ++ if (result == CBK_COORD_FOUND) { ++ if (coord.between == AT_UNIT) { ++ /*coord_clear_iplug(&coord); */ ++ result = zload(coord.node); ++ if (result == 0) { ++ if (item_id_by_coord(&coord) == id) ++ found = 1; ++ else ++ item_plugin_by_coord(&coord)->s. ++ file.append_key(&coord, ++ &key); ++ zrelse(coord.node); ++ } ++ } else ++ result = RETERR(-ENOENT); ++ } ++ done_lh(&lh); ++ } while (result == 0 && !found); ++ *offset = get_key_offset(&key); ++ return result; ++} ++ ++/** ++ * tail2extent ++ * @uf_info: ++ * ++ * ++ */ ++int tail2extent(struct unix_file_info *uf_info) ++{ ++ int result; ++ reiser4_key key; /* key of next byte to be moved to page */ ++ char *p_data; /* data of page */ ++ unsigned page_off = 0, /* offset within the page where to copy data */ ++ count; /* number of bytes of item which can be ++ * copied to page */ ++ struct page *pages[TAIL2EXTENT_PAGE_NUM]; ++ struct page *page; ++ int done; /* set to 1 when all file is read */ ++ char *item; ++ int i; ++ struct inode *inode; ++ int first_iteration; ++ int bytes; ++ __u64 offset; ++ ++ assert("nikita-3362", ea_obtained(uf_info)); ++ inode = unix_file_info_to_inode(uf_info); ++ assert("nikita-3412", !IS_RDONLY(inode)); ++ assert("vs-1649", uf_info->container != UF_CONTAINER_EXTENTS); ++ assert("", !reiser4_inode_get_flag(inode, REISER4_PART_IN_CONV)); ++ ++ offset = 0; ++ first_iteration = 1; ++ result = 0; ++ if (reiser4_inode_get_flag(inode, REISER4_PART_MIXED)) { ++ /* ++ * file is marked on disk as there was a conversion which did ++ * not complete due to either crash or some error. Find which ++ * offset tail conversion stopped at ++ */ ++ result = find_start(inode, FORMATTING_ID, &offset); ++ if (result == -ENOENT) { ++ /* no tail items found, everything is converted */ ++ uf_info->container = UF_CONTAINER_EXTENTS; ++ complete_conversion(inode); ++ return 0; ++ } else if (result != 0) ++ /* some other error */ ++ return result; ++ first_iteration = 0; ++ } ++ ++ reiser4_inode_set_flag(inode, REISER4_PART_IN_CONV); ++ ++ /* get key of first byte of a file */ ++ inode_file_plugin(inode)->key_by_inode(inode, offset, &key); ++ ++ done = 0; ++ while (done == 0) { ++ memset(pages, 0, sizeof(pages)); ++ result = reserve_tail2extent_iteration(inode); ++ if (result != 0) { ++ reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV); ++ goto out; ++ } ++ if (first_iteration) { ++ reiser4_inode_set_flag(inode, REISER4_PART_MIXED); ++ reiser4_update_sd(inode); ++ first_iteration = 0; ++ } ++ bytes = 0; ++ for (i = 0; i < sizeof_array(pages) && done == 0; i++) { ++ assert("vs-598", ++ (get_key_offset(&key) & ~PAGE_CACHE_MASK) == 0); ++ page = alloc_page(reiser4_ctx_gfp_mask_get()); ++ if (!page) { ++ result = RETERR(-ENOMEM); ++ goto error; ++ } ++ ++ page->index = ++ (unsigned long)(get_key_offset(&key) >> ++ PAGE_CACHE_SHIFT); ++ /* ++ * usually when one is going to longterm lock znode (as ++ * find_file_item does, for instance) he must not hold ++ * locked pages. However, there is an exception for ++ * case tail2extent. Pages appearing here are not ++ * reachable to everyone else, they are clean, they do ++ * not have jnodes attached so keeping them locked do ++ * not risk deadlock appearance ++ */ ++ assert("vs-983", !PagePrivate(page)); ++ reiser4_invalidate_pages(inode->i_mapping, page->index, ++ 1, 0); ++ ++ for (page_off = 0; page_off < PAGE_CACHE_SIZE;) { ++ coord_t coord; ++ lock_handle lh; ++ ++ /* get next item */ ++ /* FIXME: we might want to readahead here */ ++ init_lh(&lh); ++ result = ++ find_file_item_nohint(&coord, &lh, &key, ++ ZNODE_READ_LOCK, ++ inode); ++ if (result != CBK_COORD_FOUND) { ++ /* ++ * error happened of not items of file ++ * were found ++ */ ++ done_lh(&lh); ++ page_cache_release(page); ++ goto error; ++ } ++ ++ if (coord.between == AFTER_UNIT) { ++ /* ++ * end of file is reached. Padd page ++ * with zeros ++ */ ++ done_lh(&lh); ++ done = 1; ++ p_data = kmap_atomic(page, KM_USER0); ++ memset(p_data + page_off, 0, ++ PAGE_CACHE_SIZE - page_off); ++ kunmap_atomic(p_data, KM_USER0); ++ break; ++ } ++ ++ result = zload(coord.node); ++ if (result) { ++ page_cache_release(page); ++ done_lh(&lh); ++ goto error; ++ } ++ assert("vs-856", coord.between == AT_UNIT); ++ item = ((char *)item_body_by_coord(&coord)) + ++ coord.unit_pos; ++ ++ /* how many bytes to copy */ ++ count = ++ item_length_by_coord(&coord) - ++ coord.unit_pos; ++ /* limit length of copy to end of page */ ++ if (count > PAGE_CACHE_SIZE - page_off) ++ count = PAGE_CACHE_SIZE - page_off; ++ ++ /* ++ * copy item (as much as will fit starting from ++ * the beginning of the item) into the page ++ */ ++ p_data = kmap_atomic(page, KM_USER0); ++ memcpy(p_data + page_off, item, count); ++ kunmap_atomic(p_data, KM_USER0); ++ ++ page_off += count; ++ bytes += count; ++ set_key_offset(&key, ++ get_key_offset(&key) + count); ++ ++ zrelse(coord.node); ++ done_lh(&lh); ++ } /* end of loop which fills one page by content of ++ * formatting items */ ++ ++ if (page_off) { ++ /* something was copied into page */ ++ pages[i] = page; ++ } else { ++ page_cache_release(page); ++ assert("vs-1648", done == 1); ++ break; ++ } ++ } /* end of loop through pages of one conversion iteration */ ++ ++ if (i > 0) { ++ result = replace(inode, pages, i, bytes); ++ release_all_pages(pages, sizeof_array(pages)); ++ if (result) ++ goto error; ++ /* ++ * We have to drop exclusive access to avoid deadlock ++ * which may happen because called by reiser4_writepages ++ * capture_unix_file requires to get non-exclusive ++ * access to a file. It is safe to drop EA in the middle ++ * of tail2extent conversion because write_unix_file, ++ * setattr_unix_file(truncate), mmap_unix_file, ++ * release_unix_file(extent2tail) checks if conversion ++ * is not in progress (see comments before ++ * get_exclusive_access_careful(). ++ * Other processes that acquire non-exclusive access ++ * (read_unix_file, reiser4_writepages, etc) should work ++ * on partially converted files. ++ */ ++ drop_exclusive_access(uf_info); ++ /* throttle the conversion */ ++ reiser4_throttle_write(inode); ++ get_exclusive_access(uf_info); ++ ++ /* ++ * nobody is allowed to complete conversion but a ++ * process which started it ++ */ ++ assert("", reiser4_inode_get_flag(inode, ++ REISER4_PART_MIXED)); ++ } ++ } ++ if (result == 0) { ++ /* file is converted to extent items */ ++ reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV); ++ assert("vs-1697", reiser4_inode_get_flag(inode, ++ REISER4_PART_MIXED)); ++ ++ uf_info->container = UF_CONTAINER_EXTENTS; ++ complete_conversion(inode); ++ } else { ++ /* ++ * conversion is not complete. Inode was already marked as ++ * REISER4_PART_MIXED and stat-data were updated at the first ++ * iteration of the loop above. ++ */ ++ error: ++ release_all_pages(pages, sizeof_array(pages)); ++ reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV); ++ warning("edward-1548", "Partial conversion of %llu: %i", ++ (unsigned long long)get_inode_oid(inode), result); ++ } ++ ++ out: ++ /* this flag should be cleared, otherwise get_exclusive_access_careful() ++ will fall into infinite loop */ ++ assert("edward-1549", !reiser4_inode_get_flag(inode, ++ REISER4_PART_IN_CONV)); ++ return result; ++} ++ ++static int reserve_extent2tail_iteration(struct inode *inode) ++{ ++ reiser4_tree *tree; ++ ++ tree = reiser4_tree_by_inode(inode); ++ /* ++ * reserve blocks for (in this order): ++ * ++ * 1. removal of extent item ++ * ++ * 2. insertion of tail by insert_flow() ++ * ++ * 3. drilling to the leaf level by coord_by_key() ++ * ++ * 4. possible update of stat-data ++ */ ++ grab_space_enable(); ++ return reiser4_grab_space ++ (estimate_one_item_removal(tree) + ++ estimate_insert_flow(tree->height) + ++ 1 + estimate_one_insert_item(tree) + ++ inode_file_plugin(inode)->estimate.update(inode), BA_CAN_COMMIT); ++} ++ ++/* for every page of file: read page, cut part of extent pointing to this page, ++ put data of page tree by tail item */ ++int extent2tail(struct file * file, struct unix_file_info *uf_info) ++{ ++ int result; ++ struct inode *inode; ++ struct page *page; ++ unsigned long num_pages, i; ++ unsigned long start_page; ++ reiser4_key from; ++ reiser4_key to; ++ unsigned count; ++ __u64 offset; ++ ++ assert("nikita-3362", ea_obtained(uf_info)); ++ inode = unix_file_info_to_inode(uf_info); ++ assert("nikita-3412", !IS_RDONLY(inode)); ++ assert("vs-1649", uf_info->container != UF_CONTAINER_TAILS); ++ assert("", !reiser4_inode_get_flag(inode, REISER4_PART_IN_CONV)); ++ ++ offset = 0; ++ if (reiser4_inode_get_flag(inode, REISER4_PART_MIXED)) { ++ /* ++ * file is marked on disk as there was a conversion which did ++ * not complete due to either crash or some error. Find which ++ * offset tail conversion stopped at ++ */ ++ result = find_start(inode, EXTENT_POINTER_ID, &offset); ++ if (result == -ENOENT) { ++ /* no extent found, everything is converted */ ++ uf_info->container = UF_CONTAINER_TAILS; ++ complete_conversion(inode); ++ return 0; ++ } else if (result != 0) ++ /* some other error */ ++ return result; ++ } ++ ++ reiser4_inode_set_flag(inode, REISER4_PART_IN_CONV); ++ ++ /* number of pages in the file */ ++ num_pages = ++ (inode->i_size + - offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; ++ start_page = offset >> PAGE_CACHE_SHIFT; ++ ++ inode_file_plugin(inode)->key_by_inode(inode, offset, &from); ++ to = from; ++ ++ result = 0; ++ for (i = 0; i < num_pages; i++) { ++ __u64 start_byte; ++ ++ result = reserve_extent2tail_iteration(inode); ++ if (result != 0) ++ break; ++ if (i == 0 && offset == 0) { ++ reiser4_inode_set_flag(inode, REISER4_PART_MIXED); ++ reiser4_update_sd(inode); ++ } ++ ++ page = read_mapping_page(inode->i_mapping, ++ (unsigned)(i + start_page), NULL); ++ if (IS_ERR(page)) { ++ result = PTR_ERR(page); ++ break; ++ } ++ ++ wait_on_page_locked(page); ++ ++ if (!PageUptodate(page)) { ++ page_cache_release(page); ++ result = RETERR(-EIO); ++ break; ++ } ++ ++ /* cut part of file we have read */ ++ start_byte = (__u64) ((i + start_page) << PAGE_CACHE_SHIFT); ++ set_key_offset(&from, start_byte); ++ set_key_offset(&to, start_byte + PAGE_CACHE_SIZE - 1); ++ /* ++ * reiser4_cut_tree_object() returns -E_REPEAT to allow atom ++ * commits during over-long truncates. But ++ * extent->tail conversion should be performed in one ++ * transaction. ++ */ ++ result = reiser4_cut_tree(reiser4_tree_by_inode(inode), &from, ++ &to, inode, 0); ++ ++ if (result) { ++ page_cache_release(page); ++ break; ++ } ++ ++ /* put page data into tree via tail_write */ ++ count = PAGE_CACHE_SIZE; ++ if ((i == (num_pages - 1)) && ++ (inode->i_size & ~PAGE_CACHE_MASK)) ++ /* last page can be incompleted */ ++ count = (inode->i_size & ~PAGE_CACHE_MASK); ++ while (count) { ++ loff_t pos = start_byte; ++ ++ assert("edward-1537", ++ file != NULL && file->f_dentry != NULL); ++ assert("edward-1538", ++ file->f_dentry->d_inode == inode); ++ ++ result = reiser4_write_tail(file, inode, ++ (char __user *)kmap(page), ++ count, &pos); ++ reiser4_free_file_fsdata(file); ++ if (result <= 0) { ++ warning("", "reiser4_write_tail failed"); ++ page_cache_release(page); ++ reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV); ++ return result; ++ } ++ count -= result; ++ } ++ ++ /* release page */ ++ lock_page(page); ++ /* page is already detached from jnode and mapping. */ ++ assert("vs-1086", page->mapping == NULL); ++ assert("nikita-2690", ++ (!PagePrivate(page) && jprivate(page) == 0)); ++ /* waiting for writeback completion with page lock held is ++ * perfectly valid. */ ++ wait_on_page_writeback(page); ++ reiser4_drop_page(page); ++ /* release reference taken by read_cache_page() above */ ++ page_cache_release(page); ++ ++ drop_exclusive_access(uf_info); ++ /* throttle the conversion */ ++ reiser4_throttle_write(inode); ++ get_exclusive_access(uf_info); ++ /* ++ * nobody is allowed to complete conversion but a process which ++ * started it ++ */ ++ assert("", reiser4_inode_get_flag(inode, REISER4_PART_MIXED)); ++ } ++ ++ reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV); ++ ++ if (i == num_pages) { ++ /* file is converted to formatted items */ ++ assert("vs-1698", reiser4_inode_get_flag(inode, ++ REISER4_PART_MIXED)); ++ assert("vs-1260", ++ inode_has_no_jnodes(reiser4_inode_data(inode))); ++ ++ uf_info->container = UF_CONTAINER_TAILS; ++ complete_conversion(inode); ++ return 0; ++ } ++ /* ++ * conversion is not complete. Inode was already marked as ++ * REISER4_PART_MIXED and stat-data were updated at the first ++ * iteration of the loop above. ++ */ ++ warning("nikita-2282", ++ "Partial conversion of %llu: %lu of %lu: %i", ++ (unsigned long long)get_inode_oid(inode), i, ++ num_pages, result); ++ ++ /* this flag should be cleared, otherwise get_exclusive_access_careful() ++ will fall into infinite loop */ ++ assert("edward-1550", !reiser4_inode_get_flag(inode, ++ REISER4_PART_IN_CONV)); ++ return result; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file_ops.c linux-2.6.30/fs/reiser4/plugin/file_ops.c +--- linux-2.6.30.orig/fs/reiser4/plugin/file_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file_ops.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,162 @@ ++/* Copyright 2005 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* this file contains typical implementations for some of methods of ++ struct file_operations and of struct address_space_operations ++*/ ++ ++#include "../inode.h" ++#include "object.h" ++ ++/* file operations */ ++ ++/* implementation of vfs's llseek method of struct file_operations for ++ typical directory can be found in readdir_common.c ++*/ ++loff_t reiser4_llseek_dir_common(struct file *, loff_t, int origin); ++ ++/* implementation of vfs's readdir method of struct file_operations for ++ typical directory can be found in readdir_common.c ++*/ ++int reiser4_readdir_common(struct file *, void *dirent, filldir_t); ++ ++/** ++ * reiser4_release_dir_common - release of struct file_operations ++ * @inode: inode of released file ++ * @file: file to release ++ * ++ * Implementation of release method of struct file_operations for typical ++ * directory. All it does is freeing of reiser4 specific file data. ++*/ ++int reiser4_release_dir_common(struct inode *inode, struct file *file) ++{ ++ reiser4_context *ctx; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ reiser4_free_file_fsdata(file); ++ reiser4_exit_context(ctx); ++ return 0; ++} ++ ++/* this is common implementation of vfs's fsync method of struct ++ file_operations ++*/ ++int reiser4_sync_common(struct file *file, struct dentry *dentry, int datasync) ++{ ++ reiser4_context *ctx; ++ int result; ++ ++ ctx = reiser4_init_context(dentry->d_inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ result = txnmgr_force_commit_all(dentry->d_inode->i_sb, 0); ++ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/* ++ * common sync method for regular files. ++ * ++ * We are trying to be smart here. Instead of committing all atoms (original ++ * solution), we scan dirty pages of this file and commit all atoms they are ++ * part of. ++ * ++ * Situation is complicated by anonymous pages: i.e., extent-less pages ++ * dirtied through mmap. Fortunately sys_fsync() first calls ++ * filemap_fdatawrite() that will ultimately call reiser4_writepages(), insert ++ * all missing extents and capture anonymous pages. ++ */ ++int reiser4_sync_file_common(struct file *file, ++ struct dentry *dentry, int datasync) ++{ ++ reiser4_context *ctx; ++ txn_atom *atom; ++ reiser4_block_nr reserve; ++ ++ ctx = reiser4_init_context(dentry->d_inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ reserve = estimate_update_common(dentry->d_inode); ++ if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) { ++ reiser4_exit_context(ctx); ++ return RETERR(-ENOSPC); ++ } ++ write_sd_by_inode_common(dentry->d_inode); ++ ++ atom = get_current_atom_locked(); ++ spin_lock_txnh(ctx->trans); ++ force_commit_atom(ctx->trans); ++ reiser4_exit_context(ctx); ++ return 0; ++} ++ ++ ++/* address space operations */ ++ ++ ++/* this is helper for plugin->write_begin() */ ++int do_prepare_write(struct file *file, struct page *page, unsigned from, ++ unsigned to) ++{ ++ int result; ++ file_plugin *fplug; ++ struct inode *inode; ++ ++ assert("umka-3099", file != NULL); ++ assert("umka-3100", page != NULL); ++ assert("umka-3095", PageLocked(page)); ++ ++ if (to - from == PAGE_CACHE_SIZE || PageUptodate(page)) ++ return 0; ++ ++ inode = page->mapping->host; ++ fplug = inode_file_plugin(inode); ++ ++ if (page->mapping->a_ops->readpage == NULL) ++ return RETERR(-EINVAL); ++ ++ result = page->mapping->a_ops->readpage(file, page); ++ if (result != 0) { ++ SetPageError(page); ++ ClearPageUptodate(page); ++ /* All reiser4 readpage() implementations should return the ++ * page locked in case of error. */ ++ assert("nikita-3472", PageLocked(page)); ++ } else { ++ /* ++ * ->readpage() either: ++ * ++ * 1. starts IO against @page. @page is locked for IO in ++ * this case. ++ * ++ * 2. doesn't start IO. @page is unlocked. ++ * ++ * In either case, page should be locked. ++ */ ++ lock_page(page); ++ /* ++ * IO (if any) is completed at this point. Check for IO ++ * errors. ++ */ ++ if (!PageUptodate(page)) ++ result = RETERR(-EIO); ++ } ++ assert("umka-3098", PageLocked(page)); ++ return result; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file_ops_readdir.c linux-2.6.30/fs/reiser4/plugin/file_ops_readdir.c +--- linux-2.6.30.orig/fs/reiser4/plugin/file_ops_readdir.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file_ops_readdir.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,658 @@ ++/* Copyright 2005 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#include "../inode.h" ++ ++/* return true, iff @coord points to the valid directory item that is part of ++ * @inode directory. */ ++static int is_valid_dir_coord(struct inode *inode, coord_t *coord) ++{ ++ return plugin_of_group(item_plugin_by_coord(coord), ++ DIR_ENTRY_ITEM_TYPE) && ++ inode_file_plugin(inode)->owns_item(inode, coord); ++} ++ ++/* compare two logical positions within the same directory */ ++static cmp_t dir_pos_cmp(const struct dir_pos *p1, const struct dir_pos *p2) ++{ ++ cmp_t result; ++ ++ assert("nikita-2534", p1 != NULL); ++ assert("nikita-2535", p2 != NULL); ++ ++ result = de_id_cmp(&p1->dir_entry_key, &p2->dir_entry_key); ++ if (result == EQUAL_TO) { ++ int diff; ++ ++ diff = p1->pos - p2->pos; ++ result = ++ (diff < 0) ? LESS_THAN : (diff ? GREATER_THAN : EQUAL_TO); ++ } ++ return result; ++} ++ ++/* see comment before reiser4_readdir_common() for overview of why "adjustment" ++ * is necessary. */ ++static void ++adjust_dir_pos(struct file *dir, struct readdir_pos *readdir_spot, ++ const struct dir_pos *mod_point, int adj) ++{ ++ struct dir_pos *pos; ++ ++ /* ++ * new directory entry was added (adj == +1) or removed (adj == -1) at ++ * the @mod_point. Directory file descriptor @dir is doing readdir and ++ * is currently positioned at @readdir_spot. Latter has to be updated ++ * to maintain stable readdir. ++ */ ++ /* directory is positioned to the beginning. */ ++ if (readdir_spot->entry_no == 0) ++ return; ++ ++ pos = &readdir_spot->position; ++ switch (dir_pos_cmp(mod_point, pos)) { ++ case LESS_THAN: ++ /* @mod_pos is _before_ @readdir_spot, that is, entry was ++ * added/removed on the left (in key order) of current ++ * position. */ ++ /* logical number of directory entry readdir is "looking" at ++ * changes */ ++ readdir_spot->entry_no += adj; ++ assert("nikita-2577", ++ ergo(dir != NULL, reiser4_get_dir_fpos(dir) + adj >= 0)); ++ if (de_id_cmp(&pos->dir_entry_key, ++ &mod_point->dir_entry_key) == EQUAL_TO) { ++ assert("nikita-2575", mod_point->pos < pos->pos); ++ /* ++ * if entry added/removed has the same key as current ++ * for readdir, update counter of duplicate keys in ++ * @readdir_spot. ++ */ ++ pos->pos += adj; ++ } ++ break; ++ case GREATER_THAN: ++ /* directory is modified after @pos: nothing to do. */ ++ break; ++ case EQUAL_TO: ++ /* cannot insert an entry readdir is looking at, because it ++ already exists. */ ++ assert("nikita-2576", adj < 0); ++ /* directory entry to which @pos points to is being ++ removed. ++ ++ NOTE-NIKITA: Right thing to do is to update @pos to point ++ to the next entry. This is complex (we are under spin-lock ++ for one thing). Just rewind it to the beginning. Next ++ readdir will have to scan the beginning of ++ directory. Proper solution is to use semaphore in ++ spin lock's stead and use rewind_right() here. ++ ++ NOTE-NIKITA: now, semaphore is used, so... ++ */ ++ memset(readdir_spot, 0, sizeof *readdir_spot); ++ } ++} ++ ++/* scan all file-descriptors for this directory and adjust their ++ positions respectively. Should be used by implementations of ++ add_entry and rem_entry of dir plugin */ ++void reiser4_adjust_dir_file(struct inode *dir, const struct dentry *de, ++ int offset, int adj) ++{ ++ reiser4_file_fsdata *scan; ++ struct dir_pos mod_point; ++ ++ assert("nikita-2536", dir != NULL); ++ assert("nikita-2538", de != NULL); ++ assert("nikita-2539", adj != 0); ++ ++ build_de_id(dir, &de->d_name, &mod_point.dir_entry_key); ++ mod_point.pos = offset; ++ ++ spin_lock_inode(dir); ++ ++ /* ++ * new entry was added/removed in directory @dir. Scan all file ++ * descriptors for @dir that are currently involved into @readdir and ++ * update them. ++ */ ++ ++ list_for_each_entry(scan, get_readdir_list(dir), dir.linkage) ++ adjust_dir_pos(scan->back, &scan->dir.readdir, &mod_point, adj); ++ ++ spin_unlock_inode(dir); ++} ++ ++/* ++ * traverse tree to start/continue readdir from the readdir position @pos. ++ */ ++static int dir_go_to(struct file *dir, struct readdir_pos *pos, tap_t *tap) ++{ ++ reiser4_key key; ++ int result; ++ struct inode *inode; ++ ++ assert("nikita-2554", pos != NULL); ++ ++ inode = dir->f_dentry->d_inode; ++ result = inode_dir_plugin(inode)->build_readdir_key(dir, &key); ++ if (result != 0) ++ return result; ++ result = reiser4_object_lookup(inode, ++ &key, ++ tap->coord, ++ tap->lh, ++ tap->mode, ++ FIND_EXACT, ++ LEAF_LEVEL, LEAF_LEVEL, ++ 0, &tap->ra_info); ++ if (result == CBK_COORD_FOUND) ++ result = rewind_right(tap, (int)pos->position.pos); ++ else { ++ tap->coord->node = NULL; ++ done_lh(tap->lh); ++ result = RETERR(-EIO); ++ } ++ return result; ++} ++ ++/* ++ * handling of non-unique keys: calculate at what ordinal position within ++ * sequence of directory items with identical keys @pos is. ++ */ ++static int set_pos(struct inode *inode, struct readdir_pos *pos, tap_t *tap) ++{ ++ int result; ++ coord_t coord; ++ lock_handle lh; ++ tap_t scan; ++ de_id *did; ++ reiser4_key de_key; ++ ++ coord_init_zero(&coord); ++ init_lh(&lh); ++ reiser4_tap_init(&scan, &coord, &lh, ZNODE_READ_LOCK); ++ reiser4_tap_copy(&scan, tap); ++ reiser4_tap_load(&scan); ++ pos->position.pos = 0; ++ ++ did = &pos->position.dir_entry_key; ++ ++ if (is_valid_dir_coord(inode, scan.coord)) { ++ ++ build_de_id_by_key(unit_key_by_coord(scan.coord, &de_key), did); ++ ++ while (1) { ++ ++ result = go_prev_unit(&scan); ++ if (result != 0) ++ break; ++ ++ if (!is_valid_dir_coord(inode, scan.coord)) { ++ result = -EINVAL; ++ break; ++ } ++ ++ /* get key of directory entry */ ++ unit_key_by_coord(scan.coord, &de_key); ++ if (de_id_key_cmp(did, &de_key) != EQUAL_TO) { ++ /* duplicate-sequence is over */ ++ break; ++ } ++ pos->position.pos++; ++ } ++ } else ++ result = RETERR(-ENOENT); ++ reiser4_tap_relse(&scan); ++ reiser4_tap_done(&scan); ++ return result; ++} ++ ++/* ++ * "rewind" directory to @offset, i.e., set @pos and @tap correspondingly. ++ */ ++static int dir_rewind(struct file *dir, struct readdir_pos *pos, tap_t *tap) ++{ ++ __u64 destination; ++ __s64 shift; ++ int result; ++ struct inode *inode; ++ loff_t dirpos; ++ ++ assert("nikita-2553", dir != NULL); ++ assert("nikita-2548", pos != NULL); ++ assert("nikita-2551", tap->coord != NULL); ++ assert("nikita-2552", tap->lh != NULL); ++ ++ dirpos = reiser4_get_dir_fpos(dir); ++ shift = dirpos - pos->fpos; ++ /* this is logical directory entry within @dir which we are rewinding ++ * to */ ++ destination = pos->entry_no + shift; ++ ++ inode = dir->f_dentry->d_inode; ++ if (dirpos < 0) ++ return RETERR(-EINVAL); ++ else if (destination == 0ll || dirpos == 0) { ++ /* rewind to the beginning of directory */ ++ memset(pos, 0, sizeof *pos); ++ return dir_go_to(dir, pos, tap); ++ } else if (destination >= inode->i_size) ++ return RETERR(-ENOENT); ++ ++ if (shift < 0) { ++ /* I am afraid of negative numbers */ ++ shift = -shift; ++ /* rewinding to the left */ ++ if (shift <= (int)pos->position.pos) { ++ /* destination is within sequence of entries with ++ duplicate keys. */ ++ result = dir_go_to(dir, pos, tap); ++ } else { ++ shift -= pos->position.pos; ++ while (1) { ++ /* repetitions: deadlock is possible when ++ going to the left. */ ++ result = dir_go_to(dir, pos, tap); ++ if (result == 0) { ++ result = rewind_left(tap, shift); ++ if (result == -E_DEADLOCK) { ++ reiser4_tap_done(tap); ++ continue; ++ } ++ } ++ break; ++ } ++ } ++ } else { ++ /* rewinding to the right */ ++ result = dir_go_to(dir, pos, tap); ++ if (result == 0) ++ result = rewind_right(tap, shift); ++ } ++ if (result == 0) { ++ result = set_pos(inode, pos, tap); ++ if (result == 0) { ++ /* update pos->position.pos */ ++ pos->entry_no = destination; ++ pos->fpos = dirpos; ++ } ++ } ++ return result; ++} ++ ++/* ++ * Function that is called by common_readdir() on each directory entry while ++ * doing readdir. ->filldir callback may block, so we had to release long term ++ * lock while calling it. To avoid repeating tree traversal, seal is used. If ++ * seal is broken, we return -E_REPEAT. Node is unlocked in this case. ++ * ++ * Whether node is unlocked in case of any other error is undefined. It is ++ * guaranteed to be still locked if success (0) is returned. ++ * ++ * When ->filldir() wants no more, feed_entry() returns 1, and node is ++ * unlocked. ++ */ ++static int ++feed_entry(struct file *f, struct readdir_pos *pos, tap_t *tap, ++ filldir_t filldir, void *dirent) ++{ ++ item_plugin *iplug; ++ char *name; ++ reiser4_key sd_key; ++ int result; ++ char buf[DE_NAME_BUF_LEN]; ++ char name_buf[32]; ++ char *local_name; ++ unsigned file_type; ++ seal_t seal; ++ coord_t *coord; ++ reiser4_key entry_key; ++ ++ coord = tap->coord; ++ iplug = item_plugin_by_coord(coord); ++ ++ /* pointer to name within the node */ ++ name = iplug->s.dir.extract_name(coord, buf); ++ assert("nikita-1371", name != NULL); ++ ++ /* key of object the entry points to */ ++ if (iplug->s.dir.extract_key(coord, &sd_key) != 0) ++ return RETERR(-EIO); ++ ++ /* we must release longterm znode lock before calling filldir to avoid ++ deadlock which may happen if filldir causes page fault. So, copy ++ name to intermediate buffer */ ++ if (strlen(name) + 1 > sizeof(name_buf)) { ++ local_name = kmalloc(strlen(name) + 1, ++ reiser4_ctx_gfp_mask_get()); ++ if (local_name == NULL) ++ return RETERR(-ENOMEM); ++ } else ++ local_name = name_buf; ++ ++ strcpy(local_name, name); ++ file_type = iplug->s.dir.extract_file_type(coord); ++ ++ unit_key_by_coord(coord, &entry_key); ++ reiser4_seal_init(&seal, coord, &entry_key); ++ ++ longterm_unlock_znode(tap->lh); ++ ++ /* ++ * send information about directory entry to the ->filldir() filler ++ * supplied to us by caller (VFS). ++ * ++ * ->filldir is entitled to do weird things. For example, ->filldir ++ * supplied by knfsd re-enters file system. Make sure no locks are ++ * held. ++ */ ++ assert("nikita-3436", lock_stack_isclean(get_current_lock_stack())); ++ ++ reiser4_txn_restart_current(); ++ result = filldir(dirent, name, (int)strlen(name), ++ /* offset of this entry */ ++ f->f_pos, ++ /* inode number of object bounden by this entry */ ++ oid_to_uino(get_key_objectid(&sd_key)), file_type); ++ if (local_name != name_buf) ++ kfree(local_name); ++ if (result < 0) ++ /* ->filldir() is satisfied. (no space in buffer, IOW) */ ++ result = 1; ++ else ++ result = reiser4_seal_validate(&seal, coord, &entry_key, ++ tap->lh, tap->mode, ++ ZNODE_LOCK_HIPRI); ++ return result; ++} ++ ++static void move_entry(struct readdir_pos *pos, coord_t *coord) ++{ ++ reiser4_key de_key; ++ de_id *did; ++ ++ /* update @pos */ ++ ++pos->entry_no; ++ did = &pos->position.dir_entry_key; ++ ++ /* get key of directory entry */ ++ unit_key_by_coord(coord, &de_key); ++ ++ if (de_id_key_cmp(did, &de_key) == EQUAL_TO) ++ /* we are within sequence of directory entries ++ with duplicate keys. */ ++ ++pos->position.pos; ++ else { ++ pos->position.pos = 0; ++ build_de_id_by_key(&de_key, did); ++ } ++ ++pos->fpos; ++} ++ ++/* ++ * STATELESS READDIR ++ * ++ * readdir support in reiser4 relies on ability to update readdir_pos embedded ++ * into reiser4_file_fsdata on each directory modification (name insertion and ++ * removal), see reiser4_readdir_common() function below. This obviously doesn't ++ * work when reiser4 is accessed over NFS, because NFS doesn't keep any state ++ * across client READDIR requests for the same directory. ++ * ++ * To address this we maintain a "pool" of detached reiser4_file_fsdata ++ * (d_cursor). Whenever NFS readdir request comes, we detect this, and try to ++ * find detached reiser4_file_fsdata corresponding to previous readdir ++ * request. In other words, additional state is maintained on the ++ * server. (This is somewhat contrary to the design goals of NFS protocol.) ++ * ++ * To efficiently detect when our ->readdir() method is called by NFS server, ++ * dentry is marked as "stateless" in reiser4_decode_fh() (this is checked by ++ * file_is_stateless() function). ++ * ++ * To find out d_cursor in the pool, we encode client id (cid) in the highest ++ * bits of NFS readdir cookie: when first readdir request comes to the given ++ * directory from the given client, cookie is set to 0. This situation is ++ * detected, global cid_counter is incremented, and stored in highest bits of ++ * all direntry offsets returned to the client, including last one. As the ++ * only valid readdir cookie is one obtained as direntry->offset, we are ++ * guaranteed that next readdir request (continuing current one) will have ++ * current cid in the highest bits of starting readdir cookie. All d_cursors ++ * are hashed into per-super-block hash table by (oid, cid) key. ++ * ++ * In addition d_cursors are placed into per-super-block radix tree where they ++ * are keyed by oid alone. This is necessary to efficiently remove them during ++ * rmdir. ++ * ++ * At last, currently unused d_cursors are linked into special list. This list ++ * is used d_cursor_shrink to reclaim d_cursors on memory pressure. ++ * ++ */ ++ ++/* ++ * prepare for readdir. ++ */ ++static int dir_readdir_init(struct file *f, tap_t *tap, ++ struct readdir_pos **pos) ++{ ++ struct inode *inode; ++ reiser4_file_fsdata *fsdata; ++ int result; ++ ++ assert("nikita-1359", f != NULL); ++ inode = f->f_dentry->d_inode; ++ assert("nikita-1360", inode != NULL); ++ ++ if (!S_ISDIR(inode->i_mode)) ++ return RETERR(-ENOTDIR); ++ ++ /* try to find detached readdir state */ ++ result = reiser4_attach_fsdata(f, inode); ++ if (result != 0) ++ return result; ++ ++ fsdata = reiser4_get_file_fsdata(f); ++ assert("nikita-2571", fsdata != NULL); ++ if (IS_ERR(fsdata)) ++ return PTR_ERR(fsdata); ++ ++ /* add file descriptor to the readdir list hanging of directory ++ * inode. This list is used to scan "readdirs-in-progress" while ++ * inserting or removing names in the directory. */ ++ spin_lock_inode(inode); ++ if (list_empty_careful(&fsdata->dir.linkage)) ++ list_add(&fsdata->dir.linkage, get_readdir_list(inode)); ++ *pos = &fsdata->dir.readdir; ++ spin_unlock_inode(inode); ++ ++ /* move @tap to the current position */ ++ return dir_rewind(f, *pos, tap); ++} ++ ++/* this is implementation of vfs's llseek method of struct file_operations for ++ typical directory ++ See comment before reiser4_readdir_common() for explanation. ++*/ ++loff_t reiser4_llseek_dir_common(struct file *file, loff_t off, int origin) ++{ ++ reiser4_context *ctx; ++ loff_t result; ++ struct inode *inode; ++ ++ inode = file->f_dentry->d_inode; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ mutex_lock(&inode->i_mutex); ++ ++ /* update ->f_pos */ ++ result = default_llseek(file, off, origin); ++ if (result >= 0) { ++ int ff; ++ coord_t coord; ++ lock_handle lh; ++ tap_t tap; ++ struct readdir_pos *pos; ++ ++ coord_init_zero(&coord); ++ init_lh(&lh); ++ reiser4_tap_init(&tap, &coord, &lh, ZNODE_READ_LOCK); ++ ++ ff = dir_readdir_init(file, &tap, &pos); ++ reiser4_detach_fsdata(file); ++ if (ff != 0) ++ result = (loff_t) ff; ++ reiser4_tap_done(&tap); ++ } ++ reiser4_detach_fsdata(file); ++ mutex_unlock(&inode->i_mutex); ++ ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/* this is common implementation of vfs's readdir method of struct ++ file_operations ++ ++ readdir problems: ++ ++ readdir(2)/getdents(2) interface is based on implicit assumption that ++ readdir can be restarted from any particular point by supplying file system ++ with off_t-full of data. That is, file system fills ->d_off field in struct ++ dirent and later user passes ->d_off to the seekdir(3), which is, actually, ++ implemented by glibc as lseek(2) on directory. ++ ++ Reiser4 cannot restart readdir from 64 bits of data, because two last ++ components of the key of directory entry are unknown, which given 128 bits: ++ locality and type fields in the key of directory entry are always known, to ++ start readdir() from given point objectid and offset fields have to be ++ filled. ++ ++ Traditional UNIX API for scanning through directory ++ (readdir/seekdir/telldir/opendir/closedir/rewindir/getdents) is based on the ++ assumption that directory is structured very much like regular file, in ++ particular, it is implied that each name within given directory (directory ++ entry) can be uniquely identified by scalar offset and that such offset is ++ stable across the life-time of the name is identifies. ++ ++ This is manifestly not so for reiser4. In reiser4 the only stable unique ++ identifies for the directory entry is its key that doesn't fit into ++ seekdir/telldir API. ++ ++ solution: ++ ++ Within each file descriptor participating in readdir-ing of directory ++ plugin/dir/dir.h:readdir_pos is maintained. This structure keeps track of ++ the "current" directory entry that file descriptor looks at. It contains a ++ key of directory entry (plus some additional info to deal with non-unique ++ keys that we wouldn't dwell onto here) and a logical position of this ++ directory entry starting from the beginning of the directory, that is ++ ordinal number of this entry in the readdir order. ++ ++ Obviously this logical position is not stable in the face of directory ++ modifications. To work around this, on each addition or removal of directory ++ entry all file descriptors for directory inode are scanned and their ++ readdir_pos are updated accordingly (adjust_dir_pos()). ++*/ ++int reiser4_readdir_common(struct file *f /* directory file being read */, ++ void *dirent /* opaque data passed to us by VFS */, ++ filldir_t filld /* filler function passed to us ++ * by VFS */) ++{ ++ reiser4_context *ctx; ++ int result; ++ struct inode *inode; ++ coord_t coord; ++ lock_handle lh; ++ tap_t tap; ++ struct readdir_pos *pos; ++ ++ assert("nikita-1359", f != NULL); ++ inode = f->f_dentry->d_inode; ++ assert("nikita-1360", inode != NULL); ++ ++ if (!S_ISDIR(inode->i_mode)) ++ return RETERR(-ENOTDIR); ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ coord_init_zero(&coord); ++ init_lh(&lh); ++ reiser4_tap_init(&tap, &coord, &lh, ZNODE_READ_LOCK); ++ ++ reiser4_readdir_readahead_init(inode, &tap); ++ ++repeat: ++ result = dir_readdir_init(f, &tap, &pos); ++ if (result == 0) { ++ result = reiser4_tap_load(&tap); ++ /* scan entries one by one feeding them to @filld */ ++ while (result == 0) { ++ coord_t *coord; ++ ++ coord = tap.coord; ++ assert("nikita-2572", coord_is_existing_unit(coord)); ++ assert("nikita-3227", is_valid_dir_coord(inode, coord)); ++ ++ result = feed_entry(f, pos, &tap, filld, dirent); ++ if (result > 0) { ++ break; ++ } else if (result == 0) { ++ ++f->f_pos; ++ result = go_next_unit(&tap); ++ if (result == -E_NO_NEIGHBOR || ++ result == -ENOENT) { ++ result = 0; ++ break; ++ } else if (result == 0) { ++ if (is_valid_dir_coord(inode, coord)) ++ move_entry(pos, coord); ++ else ++ break; ++ } ++ } else if (result == -E_REPEAT) { ++ /* feed_entry() had to restart. */ ++ ++f->f_pos; ++ reiser4_tap_relse(&tap); ++ goto repeat; ++ } else ++ warning("vs-1617", ++ "reiser4_readdir_common: unexpected error %d", ++ result); ++ } ++ reiser4_tap_relse(&tap); ++ ++ if (result >= 0) ++ f->f_version = inode->i_version; ++ } else if (result == -E_NO_NEIGHBOR || result == -ENOENT) ++ result = 0; ++ reiser4_tap_done(&tap); ++ reiser4_detach_fsdata(f); ++ ++ /* try to update directory's atime */ ++ if (reiser4_grab_space_force(inode_file_plugin(inode)->estimate.update(inode), ++ BA_CAN_COMMIT) != 0) ++ warning("", "failed to update atime on readdir: %llu", ++ get_inode_oid(inode)); ++ else ++ file_accessed(f); ++ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ ++ return (result <= 0) ? result : 0; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/file_plugin_common.c linux-2.6.30/fs/reiser4/plugin/file_plugin_common.c +--- linux-2.6.30.orig/fs/reiser4/plugin/file_plugin_common.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/file_plugin_common.c 2009-06-22 17:27:31.000000000 +0200 +@@ -0,0 +1,1008 @@ ++/* Copyright 2005 by Hans Reiser, licensing governed by ++ reiser4/README */ ++ ++/* this file contains typical implementations for most of methods of ++ file plugin ++*/ ++ ++#include "../inode.h" ++#include "object.h" ++#include "../safe_link.h" ++ ++#include <linux/quotaops.h> ++ ++static int insert_new_sd(struct inode *inode); ++static int update_sd(struct inode *inode); ++ ++/* this is common implementation of write_sd_by_inode method of file plugin ++ either insert stat data or update it ++ */ ++int write_sd_by_inode_common(struct inode *inode/* object to save */) ++{ ++ int result; ++ ++ assert("nikita-730", inode != NULL); ++ ++ if (reiser4_inode_get_flag(inode, REISER4_NO_SD)) ++ /* object doesn't have stat-data yet */ ++ result = insert_new_sd(inode); ++ else ++ result = update_sd(inode); ++ if (result != 0 && result != -ENAMETOOLONG && result != -ENOMEM) ++ /* Don't issue warnings about "name is too long" */ ++ warning("nikita-2221", "Failed to save sd for %llu: %i", ++ (unsigned long long)get_inode_oid(inode), result); ++ return result; ++} ++ ++/* this is common implementation of key_by_inode method of file plugin ++ */ ++int ++key_by_inode_and_offset_common(struct inode *inode, loff_t off, ++ reiser4_key * key) ++{ ++ reiser4_key_init(key); ++ set_key_locality(key, reiser4_inode_data(inode)->locality_id); ++ set_key_ordering(key, get_inode_ordering(inode)); ++ set_key_objectid(key, get_inode_oid(inode)); /*FIXME: inode->i_ino */ ++ set_key_type(key, KEY_BODY_MINOR); ++ set_key_offset(key, (__u64) off); ++ return 0; ++} ++ ++/* this is common implementation of set_plug_in_inode method of file plugin ++ */ ++int set_plug_in_inode_common(struct inode *object /* inode to set plugin on */ , ++ struct inode *parent /* parent object */ , ++ reiser4_object_create_data * data /* creational ++ * data */ ) ++{ ++ __u64 mask; ++ ++ object->i_mode = data->mode; ++ /* this should be plugin decision */ ++ object->i_uid = current->cred->fsuid; ++ object->i_mtime = object->i_atime = object->i_ctime = CURRENT_TIME; ++ ++ /* support for BSD style group-id assignment. See mount's manual page ++ description of bsdgroups ext2 mount options for more details */ ++ if (reiser4_is_set(object->i_sb, REISER4_BSD_GID)) ++ object->i_gid = parent->i_gid; ++ else if (parent->i_mode & S_ISGID) { ++ /* parent directory has sguid bit */ ++ object->i_gid = parent->i_gid; ++ if (S_ISDIR(object->i_mode)) ++ /* sguid is inherited by sub-directories */ ++ object->i_mode |= S_ISGID; ++ } else ++ object->i_gid = current->cred->fsgid; ++ ++ /* this object doesn't have stat-data yet */ ++ reiser4_inode_set_flag(object, REISER4_NO_SD); ++#if 0 ++ /* this is now called after all inode plugins are initialized: ++ do_create_vfs_child after adjust_to_parent */ ++ /* setup inode and file-operations for this inode */ ++ setup_inode_ops(object, data); ++#endif ++ object->i_nlink = 0; ++ reiser4_seal_init(&reiser4_inode_data(object)->sd_seal, NULL, NULL); ++ mask = (1 << UNIX_STAT) | (1 << LIGHT_WEIGHT_STAT); ++ if (!reiser4_is_set(object->i_sb, REISER4_32_BIT_TIMES)) ++ mask |= (1 << LARGE_TIMES_STAT); ++ ++ reiser4_inode_data(object)->extmask = mask; ++ return 0; ++} ++ ++/* this is common implementation of adjust_to_parent method of file plugin for ++ regular files ++ */ ++int adjust_to_parent_common(struct inode *object /* new object */ , ++ struct inode *parent /* parent directory */ , ++ struct inode *root/* root directory */) ++{ ++ assert("nikita-2165", object != NULL); ++ if (parent == NULL) ++ parent = root; ++ assert("nikita-2069", parent != NULL); ++ ++ /* ++ * inherit missing plugins from parent ++ */ ++ ++ grab_plugin_pset(object, parent, PSET_FILE); ++ grab_plugin_pset(object, parent, PSET_SD); ++ grab_plugin_pset(object, parent, PSET_FORMATTING); ++ grab_plugin_pset(object, parent, PSET_PERM); ++ return 0; ++} ++ ++/* this is common implementation of adjust_to_parent method of file plugin for ++ typical directories ++ */ ++int adjust_to_parent_common_dir(struct inode *object /* new object */ , ++ struct inode *parent /* parent directory */ , ++ struct inode *root/* root directory */) ++{ ++ int result = 0; ++ pset_member memb; ++ ++ assert("nikita-2166", object != NULL); ++ if (parent == NULL) ++ parent = root; ++ assert("nikita-2167", parent != NULL); ++ ++ /* ++ * inherit missing plugins from parent ++ */ ++ for (memb = 0; memb < PSET_LAST; ++memb) { ++ result = grab_plugin_pset(object, parent, memb); ++ if (result != 0) ++ break; ++ } ++ return result; ++} ++ ++int adjust_to_parent_cryptcompress(struct inode *object /* new object */ , ++ struct inode *parent /* parent directory */, ++ struct inode *root/* root directory */) ++{ ++ int result; ++ result = adjust_to_parent_common(object, parent, root); ++ if (result) ++ return result; ++ assert("edward-1416", parent != NULL); ++ ++ grab_plugin_pset(object, parent, PSET_CLUSTER); ++ grab_plugin_pset(object, parent, PSET_CIPHER); ++ grab_plugin_pset(object, parent, PSET_DIGEST); ++ grab_plugin_pset(object, parent, PSET_COMPRESSION); ++ grab_plugin_pset(object, parent, PSET_COMPRESSION_MODE); ++ ++ return 0; ++} ++ ++/* this is common implementation of create_object method of file plugin ++ */ ++int reiser4_create_object_common(struct inode *object, struct inode *parent, ++ reiser4_object_create_data * data) ++{ ++ reiser4_block_nr reserve; ++ assert("nikita-744", object != NULL); ++ assert("nikita-745", parent != NULL); ++ assert("nikita-747", data != NULL); ++ assert("nikita-748", reiser4_inode_get_flag(object, REISER4_NO_SD)); ++ ++ reserve = estimate_create_common(object); ++ if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) ++ return RETERR(-ENOSPC); ++ return write_sd_by_inode_common(object); ++} ++ ++static int common_object_delete_no_reserve(struct inode *inode); ++ ++/** ++ * reiser4_delete_object_common - delete_object of file_plugin ++ * @inode: inode to be deleted ++ * ++ * This is common implementation of delete_object method of file_plugin. It ++ * applies to object its deletion consists of removing two items - stat data ++ * and safe-link. ++ */ ++int reiser4_delete_object_common(struct inode *inode) ++{ ++ int result; ++ ++ assert("nikita-1477", inode != NULL); ++ /* FIXME: if file body deletion failed (i/o error, for instance), ++ inode->i_size can be != 0 here */ ++ assert("nikita-3420", inode->i_size == 0 || S_ISLNK(inode->i_mode)); ++ assert("nikita-3421", inode->i_nlink == 0); ++ ++ if (!reiser4_inode_get_flag(inode, REISER4_NO_SD)) { ++ reiser4_block_nr reserve; ++ ++ /* grab space which is needed to remove 2 items from the tree: ++ stat data and safe-link */ ++ reserve = 2 * ++ estimate_one_item_removal(reiser4_tree_by_inode(inode)); ++ if (reiser4_grab_space_force(reserve, ++ BA_RESERVED | BA_CAN_COMMIT)) ++ return RETERR(-ENOSPC); ++ result = common_object_delete_no_reserve(inode); ++ } else ++ result = 0; ++ return result; ++} ++ ++/** ++ * reiser4_delete_dir_common - delete_object of file_plugin ++ * @inode: inode to be deleted ++ * ++ * This is common implementation of delete_object method of file_plugin for ++ * typical directory. It calls done method of dir_plugin to remove "." and ++ * removes stat data and safe-link. ++ */ ++int reiser4_delete_dir_common(struct inode *inode) ++{ ++ int result; ++ dir_plugin *dplug; ++ ++ assert("", (get_current_context() && ++ get_current_context()->trans->atom == NULL)); ++ ++ dplug = inode_dir_plugin(inode); ++ assert("vs-1101", dplug && dplug->done); ++ ++ /* kill cursors which might be attached to inode */ ++ reiser4_kill_cursors(inode); ++ ++ /* grab space enough for removing two items */ ++ if (reiser4_grab_space ++ (2 * estimate_one_item_removal(reiser4_tree_by_inode(inode)), ++ BA_RESERVED | BA_CAN_COMMIT)) ++ return RETERR(-ENOSPC); ++ ++ result = dplug->done(inode); ++ if (!result) ++ result = common_object_delete_no_reserve(inode); ++ return result; ++} ++ ++/* this is common implementation of add_link method of file plugin ++ */ ++int reiser4_add_link_common(struct inode *object, struct inode *parent) ++{ ++ /* ++ * increment ->i_nlink and update ->i_ctime ++ */ ++ ++ INODE_INC_FIELD(object, i_nlink); ++ object->i_ctime = CURRENT_TIME; ++ return 0; ++} ++ ++/* this is common implementation of rem_link method of file plugin ++ */ ++int reiser4_rem_link_common(struct inode *object, struct inode *parent) ++{ ++ assert("nikita-2021", object != NULL); ++ assert("nikita-2163", object->i_nlink > 0); ++ ++ /* ++ * decrement ->i_nlink and update ->i_ctime ++ */ ++ ++ INODE_DEC_FIELD(object, i_nlink); ++ object->i_ctime = CURRENT_TIME; ++ return 0; ++} ++ ++/* this is common implementation of rem_link method of file plugin for typical ++ directory ++*/ ++int rem_link_common_dir(struct inode *object, struct inode *parent UNUSED_ARG) ++{ ++ assert("nikita-20211", object != NULL); ++ assert("nikita-21631", object->i_nlink > 0); ++ ++ /* ++ * decrement ->i_nlink and update ->i_ctime ++ */ ++ INODE_DEC_FIELD(object, i_nlink); ++ if (object->i_nlink == 1) ++ INODE_DEC_FIELD(object, i_nlink); ++ object->i_ctime = CURRENT_TIME; ++ return 0; ++} ++ ++/* this is common implementation of owns_item method of file plugin ++ compare objectids of keys in inode and coord */ ++int owns_item_common(const struct inode *inode, /* object to check ++ * against */ ++ const coord_t *coord/* coord to check */) ++{ ++ reiser4_key item_key; ++ reiser4_key file_key; ++ ++ assert("nikita-760", inode != NULL); ++ assert("nikita-761", coord != NULL); ++ ++ return coord_is_existing_item(coord) && ++ (get_key_objectid(build_sd_key(inode, &file_key)) == ++ get_key_objectid(item_key_by_coord(coord, &item_key))); ++} ++ ++/* this is common implementation of owns_item method of file plugin ++ for typical directory ++*/ ++int owns_item_common_dir(const struct inode *inode,/* object to check against */ ++ const coord_t *coord/* coord of item to check */) ++{ ++ reiser4_key item_key; ++ ++ assert("nikita-1335", inode != NULL); ++ assert("nikita-1334", coord != NULL); ++ ++ if (plugin_of_group(item_plugin_by_coord(coord), DIR_ENTRY_ITEM_TYPE)) ++ return get_key_locality(item_key_by_coord(coord, &item_key)) == ++ get_inode_oid(inode); ++ else ++ return owns_item_common(inode, coord); ++} ++ ++/* this is common implementation of can_add_link method of file plugin ++ checks whether yet another hard links to this object can be added ++*/ ++int can_add_link_common(const struct inode *object/* object to check */) ++{ ++ assert("nikita-732", object != NULL); ++ ++ /* inode->i_nlink is unsigned int, so just check for integer ++ overflow */ ++ return object->i_nlink + 1 != 0; ++} ++ ++/* this is common implementation of can_rem_link method of file plugin for ++ typical directory ++*/ ++int can_rem_link_common_dir(const struct inode *inode) ++{ ++ /* is_dir_empty() returns 0 is dir is empty */ ++ return !is_dir_empty(inode); ++} ++ ++/* this is common implementation of detach method of file plugin for typical ++ directory ++*/ ++int reiser4_detach_common_dir(struct inode *child, struct inode *parent) ++{ ++ dir_plugin *dplug; ++ ++ dplug = inode_dir_plugin(child); ++ assert("nikita-2883", dplug != NULL); ++ assert("nikita-2884", dplug->detach != NULL); ++ return dplug->detach(child, parent); ++} ++ ++/* this is common implementation of bind method of file plugin for typical ++ directory ++*/ ++int reiser4_bind_common_dir(struct inode *child, struct inode *parent) ++{ ++ dir_plugin *dplug; ++ ++ dplug = inode_dir_plugin(child); ++ assert("nikita-2646", dplug != NULL); ++ return dplug->attach(child, parent); ++} ++ ++static int process_truncate(struct inode *, __u64 size); ++ ++/* this is common implementation of safelink method of file plugin ++ */ ++int safelink_common(struct inode *object, reiser4_safe_link_t link, __u64 value) ++{ ++ int result; ++ ++ assert("vs-1705", get_current_context()->trans->atom == NULL); ++ if (link == SAFE_UNLINK) ++ /* nothing to do. iput() in the caller (process_safelink) will ++ * finish with file */ ++ result = 0; ++ else if (link == SAFE_TRUNCATE) ++ result = process_truncate(object, value); ++ else { ++ warning("nikita-3438", "Unrecognized safe-link type: %i", link); ++ result = RETERR(-EIO); ++ } ++ return result; ++} ++ ++/* this is common implementation of estimate.create method of file plugin ++ can be used when object creation involves insertion of one item (usually stat ++ data) into tree ++*/ ++reiser4_block_nr estimate_create_common(const struct inode *object) ++{ ++ return estimate_one_insert_item(reiser4_tree_by_inode(object)); ++} ++ ++/* this is common implementation of estimate.create method of file plugin for ++ typical directory ++ can be used when directory creation involves insertion of two items (usually ++ stat data and item containing "." and "..") into tree ++*/ ++reiser4_block_nr estimate_create_common_dir(const struct inode *object) ++{ ++ return 2 * estimate_one_insert_item(reiser4_tree_by_inode(object)); ++} ++ ++/* this is common implementation of estimate.update method of file plugin ++ can be used when stat data update does not do more than inserting a unit ++ into a stat data item which is probably true for most cases ++*/ ++reiser4_block_nr estimate_update_common(const struct inode *inode) ++{ ++ return estimate_one_insert_into_item(reiser4_tree_by_inode(inode)); ++} ++ ++/* this is common implementation of estimate.unlink method of file plugin ++ */ ++reiser4_block_nr ++estimate_unlink_common(const struct inode *object UNUSED_ARG, ++ const struct inode *parent UNUSED_ARG) ++{ ++ return 0; ++} ++ ++/* this is common implementation of estimate.unlink method of file plugin for ++ typical directory ++*/ ++reiser4_block_nr ++estimate_unlink_common_dir(const struct inode *object, ++ const struct inode *parent) ++{ ++ dir_plugin *dplug; ++ ++ dplug = inode_dir_plugin(object); ++ assert("nikita-2888", dplug != NULL); ++ assert("nikita-2887", dplug->estimate.unlink != NULL); ++ return dplug->estimate.unlink(object, parent); ++} ++ ++char *wire_write_common(struct inode *inode, char *start) ++{ ++ return build_inode_onwire(inode, start); ++} ++ ++char *wire_read_common(char *addr, reiser4_object_on_wire * obj) ++{ ++ if (!obj) ++ return locate_obj_key_id_onwire(addr); ++ return extract_obj_key_id_from_onwire(addr, &obj->u.std.key_id); ++} ++ ++struct dentry *wire_get_common(struct super_block *sb, ++ reiser4_object_on_wire * obj) ++{ ++ struct inode *inode; ++ struct dentry *dentry; ++ reiser4_key key; ++ ++ extract_key_from_id(&obj->u.std.key_id, &key); ++ inode = reiser4_iget(sb, &key, 1); ++ if (!IS_ERR(inode)) { ++ reiser4_iget_complete(inode); ++ dentry = d_obtain_alias(inode); ++ if (!IS_ERR(dentry)) ++ dentry->d_op = &get_super_private(sb)->ops.dentry; ++ } else if (PTR_ERR(inode) == -ENOENT) ++ /* ++ * inode wasn't found at the key encoded in the file ++ * handle. Hence, file handle is stale. ++ */ ++ dentry = ERR_PTR(RETERR(-ESTALE)); ++ else ++ dentry = (void *)inode; ++ return dentry; ++} ++ ++int wire_size_common(struct inode *inode) ++{ ++ return inode_onwire_size(inode); ++} ++ ++void wire_done_common(reiser4_object_on_wire * obj) ++{ ++ /* nothing to do */ ++} ++ ++/* helper function to print errors */ ++static void key_warning(const reiser4_key * key /* key to print */ , ++ const struct inode *inode, ++ int code/* error code to print */) ++{ ++ assert("nikita-716", key != NULL); ++ ++ if (code != -ENOMEM) { ++ warning("nikita-717", "Error for inode %llu (%i)", ++ (unsigned long long)get_key_objectid(key), code); ++ reiser4_print_key("for key", key); ++ } ++} ++ ++/* NIKITA-FIXME-HANS: perhaps this function belongs in another file? */ ++#if REISER4_DEBUG ++static void ++check_inode_seal(const struct inode *inode, ++ const coord_t *coord, const reiser4_key * key) ++{ ++ reiser4_key unit_key; ++ ++ unit_key_by_coord(coord, &unit_key); ++ assert("nikita-2752", ++ WITH_DATA_RET(coord->node, 1, keyeq(key, &unit_key))); ++ assert("nikita-2753", get_inode_oid(inode) == get_key_objectid(key)); ++} ++ ++static void check_sd_coord(coord_t *coord, const reiser4_key * key) ++{ ++ reiser4_key ukey; ++ ++ coord_clear_iplug(coord); ++ if (zload(coord->node)) ++ return; ++ ++ if (!coord_is_existing_unit(coord) || ++ !item_plugin_by_coord(coord) || ++ !keyeq(unit_key_by_coord(coord, &ukey), key) || ++ (znode_get_level(coord->node) != LEAF_LEVEL) || ++ !item_is_statdata(coord)) { ++ warning("nikita-1901", "Conspicuous seal"); ++ reiser4_print_key("key", key); ++ print_coord("coord", coord, 1); ++ impossible("nikita-2877", "no way"); ++ } ++ zrelse(coord->node); ++} ++ ++#else ++#define check_inode_seal(inode, coord, key) noop ++#define check_sd_coord(coord, key) noop ++#endif ++ ++/* insert new stat-data into tree. Called with inode state ++ locked. Return inode state locked. */ ++static int insert_new_sd(struct inode *inode/* inode to create sd for */) ++{ ++ int result; ++ reiser4_key key; ++ coord_t coord; ++ reiser4_item_data data; ++ char *area; ++ reiser4_inode *ref; ++ lock_handle lh; ++ oid_t oid; ++ ++ assert("nikita-723", inode != NULL); ++ assert("nikita-3406", reiser4_inode_get_flag(inode, REISER4_NO_SD)); ++ ++ ref = reiser4_inode_data(inode); ++ spin_lock_inode(inode); ++ ++ if (ref->plugin_mask != 0) ++ /* inode has non-standard plugins */ ++ inode_set_extension(inode, PLUGIN_STAT); ++ /* ++ * prepare specification of new item to be inserted ++ */ ++ ++ data.iplug = inode_sd_plugin(inode); ++ data.length = data.iplug->s.sd.save_len(inode); ++ spin_unlock_inode(inode); ++ ++ data.data = NULL; ++ data.user = 0; ++/* could be optimized for case where there is only one node format in ++ * use in the filesystem, probably there are lots of such ++ * places we could optimize for only one node layout.... -Hans */ ++ if (data.length > reiser4_tree_by_inode(inode)->nplug->max_item_size()) { ++ /* This is silly check, but we don't know actual node where ++ insertion will go into. */ ++ return RETERR(-ENAMETOOLONG); ++ } ++ oid = oid_allocate(inode->i_sb); ++/* NIKITA-FIXME-HANS: what is your opinion on whether this error check should be ++ * encapsulated into oid_allocate? */ ++ if (oid == ABSOLUTE_MAX_OID) ++ return RETERR(-EOVERFLOW); ++ ++ set_inode_oid(inode, oid); ++ ++ coord_init_zero(&coord); ++ init_lh(&lh); ++ ++ result = insert_by_key(reiser4_tree_by_inode(inode), ++ build_sd_key(inode, &key), &data, &coord, &lh, ++ /* stat data lives on a leaf level */ ++ LEAF_LEVEL, CBK_UNIQUE); ++ ++ /* we don't want to re-check that somebody didn't insert ++ stat-data while we were doing io, because if it did, ++ insert_by_key() returned error. */ ++ /* but what _is_ possible is that plugin for inode's stat-data, ++ list of non-standard plugins or their state would change ++ during io, so that stat-data wouldn't fit into sd. To avoid ++ this race we keep inode_state lock. This lock has to be ++ taken each time you access inode in a way that would cause ++ changes in sd size: changing plugins etc. ++ */ ++ ++ if (result == IBK_INSERT_OK) { ++ coord_clear_iplug(&coord); ++ result = zload(coord.node); ++ if (result == 0) { ++ /* have we really inserted stat data? */ ++ assert("nikita-725", item_is_statdata(&coord)); ++ ++ /* inode was just created. It is inserted into hash ++ table, but no directory entry was yet inserted into ++ parent. So, inode is inaccessible through ++ ->lookup(). All places that directly grab inode ++ from hash-table (like old knfsd), should check ++ IMMUTABLE flag that is set by common_create_child. ++ */ ++ assert("nikita-3240", data.iplug != NULL); ++ assert("nikita-3241", data.iplug->s.sd.save != NULL); ++ area = item_body_by_coord(&coord); ++ result = data.iplug->s.sd.save(inode, &area); ++ znode_make_dirty(coord.node); ++ if (result == 0) { ++ /* object has stat-data now */ ++ reiser4_inode_clr_flag(inode, REISER4_NO_SD); ++ reiser4_inode_set_flag(inode, ++ REISER4_SDLEN_KNOWN); ++ /* initialise stat-data seal */ ++ reiser4_seal_init(&ref->sd_seal, &coord, &key); ++ ref->sd_coord = coord; ++ check_inode_seal(inode, &coord, &key); ++ } else if (result != -ENOMEM) ++ /* ++ * convert any other error code to -EIO to ++ * avoid confusing user level with unexpected ++ * errors. ++ */ ++ result = RETERR(-EIO); ++ zrelse(coord.node); ++ } ++ } ++ done_lh(&lh); ++ ++ if (result != 0) ++ key_warning(&key, inode, result); ++ else ++ oid_count_allocated(); ++ ++ return result; ++} ++ ++/* find sd of inode in a tree, deal with errors */ ++int lookup_sd(struct inode *inode /* inode to look sd for */ , ++ znode_lock_mode lock_mode /* lock mode */ , ++ coord_t *coord /* resulting coord */ , ++ lock_handle * lh /* resulting lock handle */ , ++ const reiser4_key * key /* resulting key */ , ++ int silent) ++{ ++ int result; ++ __u32 flags; ++ ++ assert("nikita-1692", inode != NULL); ++ assert("nikita-1693", coord != NULL); ++ assert("nikita-1694", key != NULL); ++ ++ /* look for the object's stat data in a tree. ++ This returns in "node" pointer to a locked znode and in "pos" ++ position of an item found in node. Both are only valid if ++ coord_found is returned. */ ++ flags = (lock_mode == ZNODE_WRITE_LOCK) ? CBK_FOR_INSERT : 0; ++ flags |= CBK_UNIQUE; ++ /* ++ * traverse tree to find stat data. We cannot use vroot here, because ++ * it only covers _body_ of the file, and stat data don't belong ++ * there. ++ */ ++ result = coord_by_key(reiser4_tree_by_inode(inode), ++ key, ++ coord, ++ lh, ++ lock_mode, ++ FIND_EXACT, LEAF_LEVEL, LEAF_LEVEL, flags, NULL); ++ if (REISER4_DEBUG && result == 0) ++ check_sd_coord(coord, key); ++ ++ if (result != 0 && !silent) ++ key_warning(key, inode, result); ++ return result; ++} ++ ++static int ++locate_inode_sd(struct inode *inode, ++ reiser4_key * key, coord_t *coord, lock_handle * lh) ++{ ++ reiser4_inode *state; ++ seal_t seal; ++ int result; ++ ++ assert("nikita-3483", inode != NULL); ++ ++ state = reiser4_inode_data(inode); ++ spin_lock_inode(inode); ++ *coord = state->sd_coord; ++ coord_clear_iplug(coord); ++ seal = state->sd_seal; ++ spin_unlock_inode(inode); ++ ++ build_sd_key(inode, key); ++ if (reiser4_seal_is_set(&seal)) { ++ /* first, try to use seal */ ++ result = reiser4_seal_validate(&seal, ++ coord, ++ key, ++ lh, ZNODE_WRITE_LOCK, ++ ZNODE_LOCK_LOPRI); ++ if (result == 0) ++ check_sd_coord(coord, key); ++ } else ++ result = -E_REPEAT; ++ ++ if (result != 0) { ++ coord_init_zero(coord); ++ result = lookup_sd(inode, ZNODE_WRITE_LOCK, coord, lh, key, 0); ++ } ++ return result; ++} ++ ++#if REISER4_DEBUG ++static int all_but_offset_key_eq(const reiser4_key * k1, const reiser4_key * k2) ++{ ++ return (get_key_locality(k1) == get_key_locality(k2) && ++ get_key_type(k1) == get_key_type(k2) && ++ get_key_band(k1) == get_key_band(k2) && ++ get_key_ordering(k1) == get_key_ordering(k2) && ++ get_key_objectid(k1) == get_key_objectid(k2)); ++} ++ ++#include "../tree_walk.h" ++ ++/* make some checks before and after stat-data resize operation */ ++static int check_sd_resize(struct inode *inode, coord_t *coord, ++ int length, int progress/* 1 means after resize */) ++{ ++ int ret = 0; ++ lock_handle left_lock; ++ coord_t left_coord; ++ reiser4_key left_key; ++ reiser4_key key; ++ ++ if (inode_file_plugin(inode) != ++ file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID)) ++ return 0; ++ if (!length) ++ return 0; ++ if (coord->item_pos != 0) ++ return 0; ++ ++ init_lh(&left_lock); ++ ret = reiser4_get_left_neighbor(&left_lock, ++ coord->node, ++ ZNODE_WRITE_LOCK, ++ GN_CAN_USE_UPPER_LEVELS); ++ if (ret == -E_REPEAT || ret == -E_NO_NEIGHBOR || ++ ret == -ENOENT || ret == -EINVAL ++ || ret == -E_DEADLOCK) { ++ ret = 0; ++ goto exit; ++ } ++ ret = zload(left_lock.node); ++ if (ret) ++ goto exit; ++ coord_init_last_unit(&left_coord, left_lock.node); ++ item_key_by_coord(&left_coord, &left_key); ++ item_key_by_coord(coord, &key); ++ ++ if (all_but_offset_key_eq(&key, &left_key)) ++ /* corruption occured */ ++ ret = 1; ++ zrelse(left_lock.node); ++ exit: ++ done_lh(&left_lock); ++ return ret; ++} ++#endif ++ ++/* update stat-data at @coord */ ++static int ++update_sd_at(struct inode *inode, coord_t *coord, reiser4_key * key, ++ lock_handle * lh) ++{ ++ int result; ++ reiser4_item_data data; ++ char *area; ++ reiser4_inode *state; ++ znode *loaded; ++ ++ state = reiser4_inode_data(inode); ++ ++ coord_clear_iplug(coord); ++ result = zload(coord->node); ++ if (result != 0) ++ return result; ++ loaded = coord->node; ++ ++ spin_lock_inode(inode); ++ assert("nikita-728", inode_sd_plugin(inode) != NULL); ++ data.iplug = inode_sd_plugin(inode); ++ ++ /* if inode has non-standard plugins, add appropriate stat data ++ * extension */ ++ if (state->extmask & (1 << PLUGIN_STAT)) { ++ if (state->plugin_mask == 0) ++ inode_clr_extension(inode, PLUGIN_STAT); ++ } else if (state->plugin_mask != 0) ++ inode_set_extension(inode, PLUGIN_STAT); ++ ++ if (state->extmask & (1 << HEIR_STAT)) { ++ if (state->heir_mask == 0) ++ inode_clr_extension(inode, HEIR_STAT); ++ } else if (state->heir_mask != 0) ++ inode_set_extension(inode, HEIR_STAT); ++ ++ /* data.length is how much space to add to (or remove ++ from if negative) sd */ ++ if (!reiser4_inode_get_flag(inode, REISER4_SDLEN_KNOWN)) { ++ /* recalculate stat-data length */ ++ data.length = ++ data.iplug->s.sd.save_len(inode) - ++ item_length_by_coord(coord); ++ reiser4_inode_set_flag(inode, REISER4_SDLEN_KNOWN); ++ } else ++ data.length = 0; ++ spin_unlock_inode(inode); ++ ++ /* if on-disk stat data is of different length than required ++ for this inode, resize it */ ++ ++ if (data.length != 0) { ++ data.data = NULL; ++ data.user = 0; ++ ++ assert("edward-1441", ++ !check_sd_resize(inode, coord, ++ data.length, 0/* before resize */)); ++ ++ /* insertion code requires that insertion point (coord) was ++ * between units. */ ++ coord->between = AFTER_UNIT; ++ result = reiser4_resize_item(coord, &data, key, lh, ++ COPI_DONT_SHIFT_LEFT); ++ if (result != 0) { ++ key_warning(key, inode, result); ++ zrelse(loaded); ++ return result; ++ } ++ if (loaded != coord->node) { ++ /* reiser4_resize_item moved coord to another node. ++ Zload it */ ++ zrelse(loaded); ++ coord_clear_iplug(coord); ++ result = zload(coord->node); ++ if (result != 0) ++ return result; ++ loaded = coord->node; ++ } ++ assert("edward-1442", ++ !check_sd_resize(inode, coord, ++ data.length, 1/* after resize */)); ++ } ++ area = item_body_by_coord(coord); ++ spin_lock_inode(inode); ++ result = data.iplug->s.sd.save(inode, &area); ++ znode_make_dirty(coord->node); ++ ++ /* re-initialise stat-data seal */ ++ ++ /* ++ * coord.between was possibly skewed from AT_UNIT when stat-data size ++ * was changed and new extensions were pasted into item. ++ */ ++ coord->between = AT_UNIT; ++ reiser4_seal_init(&state->sd_seal, coord, key); ++ state->sd_coord = *coord; ++ spin_unlock_inode(inode); ++ check_inode_seal(inode, coord, key); ++ zrelse(loaded); ++ return result; ++} ++ ++/* Update existing stat-data in a tree. Called with inode state locked. Return ++ inode state locked. */ ++static int update_sd(struct inode *inode/* inode to update sd for */) ++{ ++ int result; ++ reiser4_key key; ++ coord_t coord; ++ lock_handle lh; ++ ++ assert("nikita-726", inode != NULL); ++ ++ /* no stat-data, nothing to update?! */ ++ assert("nikita-3482", !reiser4_inode_get_flag(inode, REISER4_NO_SD)); ++ ++ init_lh(&lh); ++ ++ result = locate_inode_sd(inode, &key, &coord, &lh); ++ if (result == 0) ++ result = update_sd_at(inode, &coord, &key, &lh); ++ done_lh(&lh); ++ ++ return result; ++} ++ ++/* helper for reiser4_delete_object_common and reiser4_delete_dir_common. ++ Remove object stat data. Space for that must be reserved by caller before ++*/ ++static int ++common_object_delete_no_reserve(struct inode *inode/* object to remove */) ++{ ++ int result; ++ ++ assert("nikita-1477", inode != NULL); ++ ++ if (!reiser4_inode_get_flag(inode, REISER4_NO_SD)) { ++ reiser4_key sd_key; ++ ++ vfs_dq_free_inode(inode); ++ vfs_dq_drop(inode); ++ ++ build_sd_key(inode, &sd_key); ++ result = ++ reiser4_cut_tree(reiser4_tree_by_inode(inode), ++ &sd_key, &sd_key, NULL, 0); ++ if (result == 0) { ++ reiser4_inode_set_flag(inode, REISER4_NO_SD); ++ result = oid_release(inode->i_sb, get_inode_oid(inode)); ++ if (result == 0) { ++ oid_count_released(); ++ ++ result = safe_link_del(reiser4_tree_by_inode(inode), ++ get_inode_oid(inode), ++ SAFE_UNLINK); ++ } ++ } ++ } else ++ result = 0; ++ return result; ++} ++ ++/* helper for safelink_common */ ++static int process_truncate(struct inode *inode, __u64 size) ++{ ++ int result; ++ struct iattr attr; ++ file_plugin *fplug; ++ reiser4_context *ctx; ++ struct dentry dentry; ++ ++ assert("vs-21", is_in_reiser4_context()); ++ ctx = reiser4_init_context(inode->i_sb); ++ assert("vs-22", !IS_ERR(ctx)); ++ ++ attr.ia_size = size; ++ attr.ia_valid = ATTR_SIZE | ATTR_CTIME; ++ fplug = inode_file_plugin(inode); ++ ++ mutex_lock(&inode->i_mutex); ++ assert("vs-1704", get_current_context()->trans->atom == NULL); ++ dentry.d_inode = inode; ++ result = inode->i_op->setattr(&dentry, &attr); ++ mutex_unlock(&inode->i_mutex); ++ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ ++ return result; ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/hash.c linux-2.6.30/fs/reiser4/plugin/hash.c +--- linux-2.6.30.orig/fs/reiser4/plugin/hash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/hash.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,352 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Hash functions */ ++ ++#include "../debug.h" ++#include "plugin_header.h" ++#include "plugin.h" ++#include "../super.h" ++#include "../inode.h" ++ ++#include <linux/types.h> ++ ++/* old rupasov (yura) hash */ ++static __u64 hash_rupasov(const unsigned char *name /* name to hash */ , ++ int len/* @name's length */) ++{ ++ int i; ++ int j; ++ int pow; ++ __u64 a; ++ __u64 c; ++ ++ assert("nikita-672", name != NULL); ++ assert("nikita-673", len >= 0); ++ ++ for (pow = 1, i = 1; i < len; ++i) ++ pow = pow * 10; ++ ++ if (len == 1) ++ a = name[0] - 48; ++ else ++ a = (name[0] - 48) * pow; ++ ++ for (i = 1; i < len; ++i) { ++ c = name[i] - 48; ++ for (pow = 1, j = i; j < len - 1; ++j) ++ pow = pow * 10; ++ a = a + c * pow; ++ } ++ for (; i < 40; ++i) { ++ c = '0' - 48; ++ for (pow = 1, j = i; j < len - 1; ++j) ++ pow = pow * 10; ++ a = a + c * pow; ++ } ++ ++ for (; i < 256; ++i) { ++ c = i; ++ for (pow = 1, j = i; j < len - 1; ++j) ++ pow = pow * 10; ++ a = a + c * pow; ++ } ++ ++ a = a << 7; ++ return a; ++} ++ ++/* r5 hash */ ++static __u64 hash_r5(const unsigned char *name /* name to hash */ , ++ int len UNUSED_ARG/* @name's length */) ++{ ++ __u64 a = 0; ++ ++ assert("nikita-674", name != NULL); ++ assert("nikita-675", len >= 0); ++ ++ while (*name) { ++ a += *name << 4; ++ a += *name >> 4; ++ a *= 11; ++ name++; ++ } ++ return a; ++} ++ ++/* Keyed 32-bit hash function using TEA in a Davis-Meyer function ++ H0 = Key ++ Hi = E Mi(Hi-1) + Hi-1 ++ ++ (see Applied Cryptography, 2nd edition, p448). ++ ++ Jeremy Fitzhardinge <jeremy@zip.com.au> 1998 ++ ++ Jeremy has agreed to the contents of reiserfs/README. -Hans ++ ++ This code was blindly upgraded to __u64 by s/__u32/__u64/g. ++*/ ++static __u64 hash_tea(const unsigned char *name /* name to hash */ , ++ int len/* @name's length */) ++{ ++ __u64 k[] = { 0x9464a485u, 0x542e1a94u, 0x3e846bffu, 0xb75bcfc3u }; ++ ++ __u64 h0 = k[0], h1 = k[1]; ++ __u64 a, b, c, d; ++ __u64 pad; ++ int i; ++ ++ assert("nikita-676", name != NULL); ++ assert("nikita-677", len >= 0); ++ ++#define DELTA 0x9E3779B9u ++#define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */ ++#define PARTROUNDS 6 /* 6 gets complete mixing */ ++ ++/* a, b, c, d - data; h0, h1 - accumulated hash */ ++#define TEACORE(rounds) \ ++ do { \ ++ __u64 sum = 0; \ ++ int n = rounds; \ ++ __u64 b0, b1; \ ++ \ ++ b0 = h0; \ ++ b1 = h1; \ ++ \ ++ do { \ ++ sum += DELTA; \ ++ b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); \ ++ b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); \ ++ } while (--n); \ ++ \ ++ h0 += b0; \ ++ h1 += b1; \ ++ } while (0) ++ ++ pad = (__u64) len | ((__u64) len << 8); ++ pad |= pad << 16; ++ ++ while (len >= 16) { ++ a = (__u64) name[0] | (__u64) name[1] << 8 | (__u64) name[2] << ++ 16 | (__u64) name[3] << 24; ++ b = (__u64) name[4] | (__u64) name[5] << 8 | (__u64) name[6] << ++ 16 | (__u64) name[7] << 24; ++ c = (__u64) name[8] | (__u64) name[9] << 8 | (__u64) name[10] << ++ 16 | (__u64) name[11] << 24; ++ d = (__u64) name[12] | (__u64) name[13] << 8 | (__u64) name[14] ++ << 16 | (__u64) name[15] << 24; ++ ++ TEACORE(PARTROUNDS); ++ ++ len -= 16; ++ name += 16; ++ } ++ ++ if (len >= 12) { ++ /* assert(len < 16); */ ++ if (len >= 16) ++ *(int *)0 = 0; ++ ++ a = (__u64) name[0] | (__u64) name[1] << 8 | (__u64) name[2] << ++ 16 | (__u64) name[3] << 24; ++ b = (__u64) name[4] | (__u64) name[5] << 8 | (__u64) name[6] << ++ 16 | (__u64) name[7] << 24; ++ c = (__u64) name[8] | (__u64) name[9] << 8 | (__u64) name[10] << ++ 16 | (__u64) name[11] << 24; ++ ++ d = pad; ++ for (i = 12; i < len; i++) { ++ d <<= 8; ++ d |= name[i]; ++ } ++ } else if (len >= 8) { ++ /* assert(len < 12); */ ++ if (len >= 12) ++ *(int *)0 = 0; ++ a = (__u64) name[0] | (__u64) name[1] << 8 | (__u64) name[2] << ++ 16 | (__u64) name[3] << 24; ++ b = (__u64) name[4] | (__u64) name[5] << 8 | (__u64) name[6] << ++ 16 | (__u64) name[7] << 24; ++ ++ c = d = pad; ++ for (i = 8; i < len; i++) { ++ c <<= 8; ++ c |= name[i]; ++ } ++ } else if (len >= 4) { ++ /* assert(len < 8); */ ++ if (len >= 8) ++ *(int *)0 = 0; ++ a = (__u64) name[0] | (__u64) name[1] << 8 | (__u64) name[2] << ++ 16 | (__u64) name[3] << 24; ++ ++ b = c = d = pad; ++ for (i = 4; i < len; i++) { ++ b <<= 8; ++ b |= name[i]; ++ } ++ } else { ++ /* assert(len < 4); */ ++ if (len >= 4) ++ *(int *)0 = 0; ++ a = b = c = d = pad; ++ for (i = 0; i < len; i++) { ++ a <<= 8; ++ a |= name[i]; ++ } ++ } ++ ++ TEACORE(FULLROUNDS); ++ ++/* return 0;*/ ++ return h0 ^ h1; ++ ++} ++ ++/* classical 64 bit Fowler/Noll/Vo-1 (FNV-1) hash. ++ ++ See http://www.isthe.com/chongo/tech/comp/fnv/ for details. ++ ++ Excerpts: ++ ++ FNV hashes are designed to be fast while maintaining a low collision ++ rate. ++ ++ [This version also seems to preserve lexicographical order locally.] ++ ++ FNV hash algorithms and source code have been released into the public ++ domain. ++ ++*/ ++static __u64 hash_fnv1(const unsigned char *name /* name to hash */ , ++ int len UNUSED_ARG/* @name's length */) ++{ ++ unsigned long long a = 0xcbf29ce484222325ull; ++ const unsigned long long fnv_64_prime = 0x100000001b3ull; ++ ++ assert("nikita-678", name != NULL); ++ assert("nikita-679", len >= 0); ++ ++ /* FNV-1 hash each octet in the buffer */ ++ for (; *name; ++name) { ++ /* multiply by the 32 bit FNV magic prime mod 2^64 */ ++ a *= fnv_64_prime; ++ /* xor the bottom with the current octet */ ++ a ^= (unsigned long long)(*name); ++ } ++ /* return our new hash value */ ++ return a; ++} ++ ++/* degenerate hash function used to simplify testing of non-unique key ++ handling */ ++static __u64 hash_deg(const unsigned char *name UNUSED_ARG /* name to hash */ , ++ int len UNUSED_ARG/* @name's length */) ++{ ++ return 0xc0c0c0c010101010ull; ++} ++ ++static int change_hash(struct inode *inode, ++ reiser4_plugin * plugin, ++ pset_member memb) ++{ ++ int result; ++ ++ assert("nikita-3503", inode != NULL); ++ assert("nikita-3504", plugin != NULL); ++ ++ assert("nikita-3505", is_reiser4_inode(inode)); ++ assert("nikita-3507", plugin->h.type_id == REISER4_HASH_PLUGIN_TYPE); ++ ++ if (!plugin_of_group(inode_file_plugin(inode), REISER4_DIRECTORY_FILE)) ++ return RETERR(-EINVAL); ++ ++ result = 0; ++ if (inode_hash_plugin(inode) == NULL || ++ inode_hash_plugin(inode)->h.id != plugin->h.id) { ++ if (is_dir_empty(inode) == 0) ++ result = aset_set_unsafe(&reiser4_inode_data(inode)->pset, ++ PSET_HASH, plugin); ++ else ++ result = RETERR(-ENOTEMPTY); ++ ++ } ++ return result; ++} ++ ++static reiser4_plugin_ops hash_plugin_ops = { ++ .init = NULL, ++ .load = NULL, ++ .save_len = NULL, ++ .save = NULL, ++ .change = change_hash ++}; ++ ++/* hash plugins */ ++hash_plugin hash_plugins[LAST_HASH_ID] = { ++ [RUPASOV_HASH_ID] = { ++ .h = { ++ .type_id = REISER4_HASH_PLUGIN_TYPE, ++ .id = RUPASOV_HASH_ID, ++ .pops = &hash_plugin_ops, ++ .label = "rupasov", ++ .desc = "Original Yura's hash", ++ .linkage = {NULL, NULL} ++ }, ++ .hash = hash_rupasov ++ }, ++ [R5_HASH_ID] = { ++ .h = { ++ .type_id = REISER4_HASH_PLUGIN_TYPE, ++ .id = R5_HASH_ID, ++ .pops = &hash_plugin_ops, ++ .label = "r5", ++ .desc = "r5 hash", ++ .linkage = {NULL, NULL} ++ }, ++ .hash = hash_r5 ++ }, ++ [TEA_HASH_ID] = { ++ .h = { ++ .type_id = REISER4_HASH_PLUGIN_TYPE, ++ .id = TEA_HASH_ID, ++ .pops = &hash_plugin_ops, ++ .label = "tea", ++ .desc = "tea hash", ++ .linkage = {NULL, NULL} ++ }, ++ .hash = hash_tea ++ }, ++ [FNV1_HASH_ID] = { ++ .h = { ++ .type_id = REISER4_HASH_PLUGIN_TYPE, ++ .id = FNV1_HASH_ID, ++ .pops = &hash_plugin_ops, ++ .label = "fnv1", ++ .desc = "fnv1 hash", ++ .linkage = {NULL, NULL} ++ }, ++ .hash = hash_fnv1 ++ }, ++ [DEGENERATE_HASH_ID] = { ++ .h = { ++ .type_id = REISER4_HASH_PLUGIN_TYPE, ++ .id = DEGENERATE_HASH_ID, ++ .pops = &hash_plugin_ops, ++ .label = "degenerate hash", ++ .desc = "Degenerate hash: only for testing", ++ .linkage = {NULL, NULL} ++ }, ++ .hash = hash_deg ++ } ++}; ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/inode_ops.c linux-2.6.30/fs/reiser4/plugin/inode_ops.c +--- linux-2.6.30.orig/fs/reiser4/plugin/inode_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/inode_ops.c 2009-06-22 17:27:31.000000000 +0200 +@@ -0,0 +1,906 @@ ++/* ++ * Copyright 2005 by Hans Reiser, licensing governed by reiser4/README ++ */ ++ ++/* ++ * this file contains typical implementations for most of methods of struct ++ * inode_operations ++ */ ++ ++#include "../inode.h" ++#include "../safe_link.h" ++ ++#include <linux/quotaops.h> ++#include <linux/namei.h> ++ ++static int create_vfs_object(struct inode *parent, struct dentry *dentry, ++ reiser4_object_create_data *data); ++ ++/** ++ * reiser4_create_common - create of inode operations ++ * @parent: inode of parent directory ++ * @dentry: dentry of new object to create ++ * @mode: the permissions to use ++ * @nameidata: ++ * ++ * This is common implementation of vfs's create method of struct ++ * inode_operations. ++ * Creates regular file using file plugin from parent directory plugin set. ++ */ ++int reiser4_create_common(struct inode *parent, struct dentry *dentry, ++ int mode, struct nameidata *nameidata) ++{ ++ reiser4_object_create_data data; ++ file_plugin *fplug; ++ ++ memset(&data, 0, sizeof data); ++ data.mode = S_IFREG | mode; ++ fplug = child_create_plugin(parent) ? : inode_create_plugin(parent); ++ if (!plugin_of_group(fplug, REISER4_REGULAR_FILE)) { ++ warning("vpf-1900", "'%s' is not a regular file plugin.", ++ fplug->h.label); ++ return RETERR(-EIO); ++ } ++ data.id = fplug->h.id; ++ return create_vfs_object(parent, dentry, &data); ++} ++ ++int reiser4_lookup_name(struct inode *dir, struct dentry *, reiser4_key *); ++void check_light_weight(struct inode *inode, struct inode *parent); ++ ++/** ++ * reiser4_lookup_common - lookup of inode operations ++ * @parent: inode of directory to lookup into ++ * @dentry: name to look for ++ * @nameidata: ++ * ++ * This is common implementation of vfs's lookup method of struct ++ * inode_operations. ++ */ ++struct dentry *reiser4_lookup_common(struct inode *parent, ++ struct dentry *dentry, ++ struct nameidata *nameidata) ++{ ++ reiser4_context *ctx; ++ int result; ++ struct dentry *new; ++ struct inode *inode; ++ reiser4_dir_entry_desc entry; ++ ++ ctx = reiser4_init_context(parent->i_sb); ++ if (IS_ERR(ctx)) ++ return (struct dentry *)ctx; ++ ++ /* set up operations on dentry. */ ++ dentry->d_op = &get_super_private(parent->i_sb)->ops.dentry; ++ ++ result = reiser4_lookup_name(parent, dentry, &entry.key); ++ if (result) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ if (result == -ENOENT) { ++ /* object not found */ ++ if (!IS_DEADDIR(parent)) ++ d_add(dentry, NULL); ++ return NULL; ++ } ++ return ERR_PTR(result); ++ } ++ ++ inode = reiser4_iget(parent->i_sb, &entry.key, 0); ++ if (IS_ERR(inode)) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return ERR_PTR(PTR_ERR(inode)); ++ } ++ ++ /* success */ ++ check_light_weight(inode, parent); ++ new = d_splice_alias(inode, dentry); ++ reiser4_iget_complete(inode); ++ ++ /* prevent balance_dirty_pages() from being called: we don't want to ++ * do this under directory i_mutex. */ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return new; ++} ++ ++static reiser4_block_nr common_estimate_link(struct inode *parent, ++ struct inode *object); ++int reiser4_update_dir(struct inode *); ++ ++/** ++ * reiser4_link_common - link of inode operations ++ * @existing: dentry of object which is to get new name ++ * @parent: directory where new name is to be created ++ * @newname: new name ++ * ++ * This is common implementation of vfs's link method of struct ++ * inode_operations. ++ */ ++int reiser4_link_common(struct dentry *existing, struct inode *parent, ++ struct dentry *newname) ++{ ++ reiser4_context *ctx; ++ int result; ++ struct inode *object; ++ dir_plugin *parent_dplug; ++ reiser4_dir_entry_desc entry; ++ reiser4_object_create_data data; ++ reiser4_block_nr reserve; ++ ++ ctx = reiser4_init_context(parent->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ assert("nikita-1431", existing != NULL); ++ assert("nikita-1432", parent != NULL); ++ assert("nikita-1433", newname != NULL); ++ ++ object = existing->d_inode; ++ assert("nikita-1434", object != NULL); ++ ++ /* check for race with create_object() */ ++ if (reiser4_inode_get_flag(object, REISER4_IMMUTABLE)) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return RETERR(-E_REPEAT); ++ } ++ ++ parent_dplug = inode_dir_plugin(parent); ++ ++ memset(&entry, 0, sizeof entry); ++ entry.obj = object; ++ ++ data.mode = object->i_mode; ++ data.id = inode_file_plugin(object)->h.id; ++ ++ reserve = common_estimate_link(parent, existing->d_inode); ++ if ((__s64) reserve < 0) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return reserve; ++ } ++ ++ if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return RETERR(-ENOSPC); ++ } ++ ++ /* ++ * Subtle race handling: sys_link() doesn't take i_mutex on @parent. It ++ * means that link(2) can race against unlink(2) or rename(2), and ++ * inode is dead (->i_nlink == 0) when reiser4_link() is entered. ++ * ++ * For such inode we have to undo special processing done in ++ * reiser4_unlink() viz. creation of safe-link. ++ */ ++ if (unlikely(object->i_nlink == 0)) { ++ result = safe_link_del(reiser4_tree_by_inode(object), ++ get_inode_oid(object), SAFE_UNLINK); ++ if (result != 0) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ } ++ ++ /* increment nlink of @existing and update its stat data */ ++ result = reiser4_add_nlink(object, parent, 1); ++ if (result == 0) { ++ /* add entry to the parent */ ++ result = ++ parent_dplug->add_entry(parent, newname, &data, &entry); ++ if (result != 0) { ++ /* failed to add entry to the parent, decrement nlink ++ of @existing */ ++ reiser4_del_nlink(object, parent, 1); ++ /* ++ * now, if that failed, we have a file with too big ++ * nlink---space leak, much better than directory ++ * entry pointing to nowhere ++ */ ++ } ++ } ++ if (result == 0) { ++ atomic_inc(&object->i_count); ++ /* ++ * Upon successful completion, link() shall mark for update ++ * the st_ctime field of the file. Also, the st_ctime and ++ * st_mtime fields of the directory that contains the new ++ * entry shall be marked for update. --SUS ++ */ ++ result = reiser4_update_dir(parent); ++ } ++ if (result == 0) ++ d_instantiate(newname, existing->d_inode); ++ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++static int unlink_check_and_grab(struct inode *parent, struct dentry *victim); ++ ++/** ++ * reiser4_unlink_common - unlink of inode operations ++ * @parent: inode of directory to remove name from ++ * @victim: name to be removed ++ * ++ * This is common implementation of vfs's unlink method of struct ++ * inode_operations. ++ */ ++int reiser4_unlink_common(struct inode *parent, struct dentry *victim) ++{ ++ reiser4_context *ctx; ++ int result; ++ struct inode *object; ++ file_plugin *fplug; ++ ++ ctx = reiser4_init_context(parent->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ object = victim->d_inode; ++ fplug = inode_file_plugin(object); ++ assert("nikita-2882", fplug->detach != NULL); ++ ++ result = unlink_check_and_grab(parent, victim); ++ if (result != 0) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ result = fplug->detach(object, parent); ++ if (result == 0) { ++ dir_plugin *parent_dplug; ++ reiser4_dir_entry_desc entry; ++ ++ parent_dplug = inode_dir_plugin(parent); ++ memset(&entry, 0, sizeof entry); ++ ++ /* first, delete directory entry */ ++ result = parent_dplug->rem_entry(parent, victim, &entry); ++ if (result == 0) { ++ /* ++ * if name was removed successfully, we _have_ to ++ * return 0 from this function, because upper level ++ * caller (vfs_{rmdir,unlink}) expect this. ++ * ++ * now that directory entry is removed, update ++ * stat-data ++ */ ++ reiser4_del_nlink(object, parent, 1); ++ /* ++ * Upon successful completion, unlink() shall mark for ++ * update the st_ctime and st_mtime fields of the ++ * parent directory. Also, if the file's link count is ++ * not 0, the st_ctime field of the file shall be ++ * marked for update. --SUS ++ */ ++ reiser4_update_dir(parent); ++ /* add safe-link for this file */ ++ if (object->i_nlink == 0) ++ safe_link_add(object, SAFE_UNLINK); ++ } ++ } ++ ++ if (unlikely(result != 0)) { ++ if (result != -ENOMEM) ++ warning("nikita-3398", "Cannot unlink %llu (%i)", ++ (unsigned long long)get_inode_oid(object), ++ result); ++ /* if operation failed commit pending inode modifications to ++ * the stat-data */ ++ reiser4_update_sd(object); ++ reiser4_update_sd(parent); ++ } ++ ++ reiser4_release_reserved(object->i_sb); ++ ++ /* @object's i_ctime was updated by ->rem_link() method(). */ ++ ++ /* @victim can be already removed from the disk by this time. Inode is ++ then marked so that iput() wouldn't try to remove stat data. But ++ inode itself is still there. ++ */ ++ ++ /* ++ * we cannot release directory semaphore here, because name has ++ * already been deleted, but dentry (@victim) still exists. Prevent ++ * balance_dirty_pages() from being called on exiting this context: we ++ * don't want to do this under directory i_mutex. ++ */ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/** ++ * reiser4_symlink_common - symlink of inode operations ++ * @parent: inode of parent directory ++ * @dentry: dentry of object to be created ++ * @linkname: string symlink is to contain ++ * ++ * This is common implementation of vfs's symlink method of struct ++ * inode_operations. ++ * Creates object using file plugin SYMLINK_FILE_PLUGIN_ID. ++ */ ++int reiser4_symlink_common(struct inode *parent, struct dentry *dentry, ++ const char *linkname) ++{ ++ reiser4_object_create_data data; ++ ++ memset(&data, 0, sizeof data); ++ data.name = linkname; ++ data.id = SYMLINK_FILE_PLUGIN_ID; ++ data.mode = S_IFLNK | S_IRWXUGO; ++ return create_vfs_object(parent, dentry, &data); ++} ++ ++/** ++ * reiser4_mkdir_common - mkdir of inode operations ++ * @parent: inode of parent directory ++ * @dentry: dentry of object to be created ++ * @mode: the permissions to use ++ * ++ * This is common implementation of vfs's mkdir method of struct ++ * inode_operations. ++ * Creates object using file plugin DIRECTORY_FILE_PLUGIN_ID. ++ */ ++int reiser4_mkdir_common(struct inode *parent, struct dentry *dentry, int mode) ++{ ++ reiser4_object_create_data data; ++ ++ memset(&data, 0, sizeof data); ++ data.mode = S_IFDIR | mode; ++ data.id = DIRECTORY_FILE_PLUGIN_ID; ++ return create_vfs_object(parent, dentry, &data); ++} ++ ++/** ++ * reiser4_mknod_common - mknod of inode operations ++ * @parent: inode of parent directory ++ * @dentry: dentry of object to be created ++ * @mode: the permissions to use and file type ++ * @rdev: minor and major of new device file ++ * ++ * This is common implementation of vfs's mknod method of struct ++ * inode_operations. ++ * Creates object using file plugin SPECIAL_FILE_PLUGIN_ID. ++ */ ++int reiser4_mknod_common(struct inode *parent, struct dentry *dentry, ++ int mode, dev_t rdev) ++{ ++ reiser4_object_create_data data; ++ ++ memset(&data, 0, sizeof data); ++ data.mode = mode; ++ data.rdev = rdev; ++ data.id = SPECIAL_FILE_PLUGIN_ID; ++ return create_vfs_object(parent, dentry, &data); ++} ++ ++/* ++ * implementation of vfs's rename method of struct inode_operations for typical ++ * directory is in inode_ops_rename.c ++ */ ++ ++/** ++ * reiser4_follow_link_common - follow_link of inode operations ++ * @dentry: dentry of symlink ++ * @data: ++ * ++ * This is common implementation of vfs's followlink method of struct ++ * inode_operations. ++ * Assumes that inode's i_private points to the content of symbolic link. ++ */ ++void *reiser4_follow_link_common(struct dentry *dentry, struct nameidata *nd) ++{ ++ assert("vs-851", S_ISLNK(dentry->d_inode->i_mode)); ++ ++ if (!dentry->d_inode->i_private ++ || !reiser4_inode_get_flag(dentry->d_inode, ++ REISER4_GENERIC_PTR_USED)) ++ return ERR_PTR(RETERR(-EINVAL)); ++ nd_set_link(nd, dentry->d_inode->i_private); ++ return NULL; ++} ++ ++/** ++ * reiser4_permission_common - permission of inode operations ++ * @inode: inode to check permissions for ++ * @mask: mode bits to check permissions for ++ * @nameidata: ++ * ++ * Uses generic function to check for rwx permissions. ++ */ ++int reiser4_permission_common(struct inode *inode, int mask) ++{ ++ return generic_permission(inode, mask, NULL); ++} ++ ++static int setattr_reserve(reiser4_tree *); ++ ++/* this is common implementation of vfs's setattr method of struct ++ inode_operations ++*/ ++int reiser4_setattr_common(struct dentry *dentry, struct iattr *attr) ++{ ++ reiser4_context *ctx; ++ struct inode *inode; ++ int result; ++ ++ inode = dentry->d_inode; ++ result = inode_change_ok(inode, attr); ++ if (result) ++ return result; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ assert("nikita-3119", !(attr->ia_valid & ATTR_SIZE)); ++ ++ /* ++ * grab disk space and call standard inode_setattr(). ++ */ ++ result = setattr_reserve(reiser4_tree_by_inode(inode)); ++ if (!result) { ++ if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ++ || (attr->ia_valid & ATTR_GID ++ && attr->ia_gid != inode->i_gid)) { ++ result = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; ++ if (result) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ } ++ result = inode_setattr(inode, attr); ++ if (!result) ++ reiser4_update_sd(inode); ++ } ++ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/* this is common implementation of vfs's getattr method of struct ++ inode_operations ++*/ ++int reiser4_getattr_common(struct vfsmount *mnt UNUSED_ARG, ++ struct dentry *dentry, struct kstat *stat) ++{ ++ struct inode *obj; ++ ++ assert("nikita-2298", dentry != NULL); ++ assert("nikita-2299", stat != NULL); ++ assert("nikita-2300", dentry->d_inode != NULL); ++ ++ obj = dentry->d_inode; ++ ++ stat->dev = obj->i_sb->s_dev; ++ stat->ino = oid_to_uino(get_inode_oid(obj)); ++ stat->mode = obj->i_mode; ++ /* don't confuse userland with huge nlink. This is not entirely ++ * correct, because nlink_t is not necessary 16 bit signed. */ ++ stat->nlink = min(obj->i_nlink, (typeof(obj->i_nlink)) 0x7fff); ++ stat->uid = obj->i_uid; ++ stat->gid = obj->i_gid; ++ stat->rdev = obj->i_rdev; ++ stat->atime = obj->i_atime; ++ stat->mtime = obj->i_mtime; ++ stat->ctime = obj->i_ctime; ++ stat->size = obj->i_size; ++ stat->blocks = ++ (inode_get_bytes(obj) + VFS_BLKSIZE - 1) >> VFS_BLKSIZE_BITS; ++ /* "preferred" blocksize for efficient file system I/O */ ++ stat->blksize = get_super_private(obj->i_sb)->optimal_io_size; ++ ++ return 0; ++} ++ ++/* Estimate the maximum amount of nodes which might be allocated or changed on ++ typical new object creation. Typical creation consists of calling create ++ method of file plugin, adding directory entry to parent and update parent ++ directory's stat data. ++*/ ++static reiser4_block_nr estimate_create_vfs_object(struct inode *parent, ++ /* parent object */ ++ struct inode *object ++ /* object */) ++{ ++ assert("vpf-309", parent != NULL); ++ assert("vpf-307", object != NULL); ++ ++ return ++ /* object creation estimation */ ++ inode_file_plugin(object)->estimate.create(object) + ++ /* stat data of parent directory estimation */ ++ inode_file_plugin(parent)->estimate.update(parent) + ++ /* adding entry estimation */ ++ inode_dir_plugin(parent)->estimate.add_entry(parent) + ++ /* to undo in the case of failure */ ++ inode_dir_plugin(parent)->estimate.rem_entry(parent); ++} ++ ++/* Create child in directory. ++ ++ . get object's plugin ++ . get fresh inode ++ . initialize inode ++ . add object's stat-data ++ . initialize object's directory ++ . add entry to the parent ++ . instantiate dentry ++ ++*/ ++static int do_create_vfs_child(reiser4_object_create_data * data,/* parameters ++ of new ++ object */ ++ struct inode **retobj) ++{ ++ int result; ++ ++ struct dentry *dentry; /* parent object */ ++ struct inode *parent; /* new name */ ++ ++ dir_plugin *par_dir; /* directory plugin on the parent */ ++ dir_plugin *obj_dir; /* directory plugin on the new object */ ++ file_plugin *obj_plug; /* object plugin on the new object */ ++ struct inode *object; /* new object */ ++ reiser4_block_nr reserve; ++ ++ reiser4_dir_entry_desc entry; /* new directory entry */ ++ ++ assert("nikita-1420", data != NULL); ++ parent = data->parent; ++ dentry = data->dentry; ++ ++ assert("nikita-1418", parent != NULL); ++ assert("nikita-1419", dentry != NULL); ++ ++ /* check, that name is acceptable for parent */ ++ par_dir = inode_dir_plugin(parent); ++ if (par_dir->is_name_acceptable && ++ !par_dir->is_name_acceptable(parent, ++ dentry->d_name.name, ++ (int)dentry->d_name.len)) ++ return RETERR(-ENAMETOOLONG); ++ ++ result = 0; ++ obj_plug = file_plugin_by_id((int)data->id); ++ if (obj_plug == NULL) { ++ warning("nikita-430", "Cannot find plugin %i", data->id); ++ return RETERR(-ENOENT); ++ } ++ object = new_inode(parent->i_sb); ++ if (object == NULL) ++ return RETERR(-ENOMEM); ++ /* we'll update i_nlink below */ ++ object->i_nlink = 0; ++ /* new_inode() initializes i_ino to "arbitrary" value. Reset it to 0, ++ * to simplify error handling: if some error occurs before i_ino is ++ * initialized with oid, i_ino should already be set to some ++ * distinguished value. */ ++ object->i_ino = 0; ++ ++ /* So that on error iput will be called. */ ++ *retobj = object; ++ ++ if (vfs_dq_alloc_inode(object)) { ++ vfs_dq_drop(object); ++ object->i_flags |= S_NOQUOTA; ++ return RETERR(-EDQUOT); ++ } ++ ++ memset(&entry, 0, sizeof entry); ++ entry.obj = object; ++ ++ set_plugin(&reiser4_inode_data(object)->pset, PSET_FILE, ++ file_plugin_to_plugin(obj_plug)); ++ result = obj_plug->set_plug_in_inode(object, parent, data); ++ if (result) { ++ warning("nikita-431", "Cannot install plugin %i on %llx", ++ data->id, (unsigned long long)get_inode_oid(object)); ++ vfs_dq_free_inode(object); ++ object->i_flags |= S_NOQUOTA; ++ return result; ++ } ++ ++ /* reget plugin after installation */ ++ obj_plug = inode_file_plugin(object); ++ ++ if (obj_plug->create_object == NULL) { ++ vfs_dq_free_inode(object); ++ object->i_flags |= S_NOQUOTA; ++ return RETERR(-EPERM); ++ } ++ ++ /* if any of hash, tail, sd or permission plugins for newly created ++ object are not set yet set them here inheriting them from parent ++ directory ++ */ ++ assert("nikita-2070", obj_plug->adjust_to_parent != NULL); ++ result = obj_plug->adjust_to_parent(object, ++ parent, ++ object->i_sb->s_root->d_inode); ++ if (result == 0) ++ result = finish_pset(object); ++ if (result != 0) { ++ warning("nikita-432", "Cannot inherit from %llx to %llx", ++ (unsigned long long)get_inode_oid(parent), ++ (unsigned long long)get_inode_oid(object)); ++ vfs_dq_free_inode(object); ++ object->i_flags |= S_NOQUOTA; ++ return result; ++ } ++ ++ /* setup inode and file-operations for this inode */ ++ setup_inode_ops(object, data); ++ ++ /* call file plugin's method to initialize plugin specific part of ++ * inode */ ++ if (obj_plug->init_inode_data) ++ obj_plug->init_inode_data(object, data, 1/*create */); ++ ++ /* obtain directory plugin (if any) for new object. */ ++ obj_dir = inode_dir_plugin(object); ++ if (obj_dir != NULL && obj_dir->init == NULL) { ++ vfs_dq_free_inode(object); ++ object->i_flags |= S_NOQUOTA; ++ return RETERR(-EPERM); ++ } ++ ++ reiser4_inode_data(object)->locality_id = get_inode_oid(parent); ++ ++ reserve = estimate_create_vfs_object(parent, object); ++ if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) { ++ vfs_dq_free_inode(object); ++ object->i_flags |= S_NOQUOTA; ++ return RETERR(-ENOSPC); ++ } ++ ++ /* mark inode `immutable'. We disable changes to the file being ++ created until valid directory entry for it is inserted. Otherwise, ++ if file were expanded and insertion of directory entry fails, we ++ have to remove file, but we only alloted enough space in ++ transaction to remove _empty_ file. 3.x code used to remove stat ++ data in different transaction thus possibly leaking disk space on ++ crash. This all only matters if it's possible to access file ++ without name, for example, by inode number ++ */ ++ reiser4_inode_set_flag(object, REISER4_IMMUTABLE); ++ ++ /* create empty object, this includes allocation of new objectid. For ++ directories this implies creation of dot and dotdot */ ++ assert("nikita-2265", reiser4_inode_get_flag(object, REISER4_NO_SD)); ++ ++ /* mark inode as `loaded'. From this point onward ++ reiser4_delete_inode() will try to remove its stat-data. */ ++ reiser4_inode_set_flag(object, REISER4_LOADED); ++ ++ result = obj_plug->create_object(object, parent, data); ++ if (result != 0) { ++ reiser4_inode_clr_flag(object, REISER4_IMMUTABLE); ++ if (result != -ENAMETOOLONG && result != -ENOMEM) ++ warning("nikita-2219", ++ "Failed to create sd for %llu", ++ (unsigned long long)get_inode_oid(object)); ++ vfs_dq_free_inode(object); ++ object->i_flags |= S_NOQUOTA; ++ return result; ++ } ++ ++ if (obj_dir != NULL) ++ result = obj_dir->init(object, parent, data); ++ if (result == 0) { ++ assert("nikita-434", !reiser4_inode_get_flag(object, ++ REISER4_NO_SD)); ++ /* insert inode into VFS hash table */ ++ insert_inode_hash(object); ++ /* create entry */ ++ result = par_dir->add_entry(parent, dentry, data, &entry); ++ if (result == 0) { ++ result = reiser4_add_nlink(object, parent, 0); ++ /* If O_CREAT is set and the file did not previously ++ exist, upon successful completion, open() shall ++ mark for update the st_atime, st_ctime, and ++ st_mtime fields of the file and the st_ctime and ++ st_mtime fields of the parent directory. --SUS ++ */ ++ /* @object times are already updated by ++ reiser4_add_nlink() */ ++ if (result == 0) ++ reiser4_update_dir(parent); ++ if (result != 0) ++ /* cleanup failure to add nlink */ ++ par_dir->rem_entry(parent, dentry, &entry); ++ } ++ if (result != 0) ++ /* cleanup failure to add entry */ ++ obj_plug->detach(object, parent); ++ } else if (result != -ENOMEM) ++ warning("nikita-2219", "Failed to initialize dir for %llu: %i", ++ (unsigned long long)get_inode_oid(object), result); ++ ++ /* ++ * update stat-data, committing all pending modifications to the inode ++ * fields. ++ */ ++ reiser4_update_sd(object); ++ if (result != 0) { ++ vfs_dq_free_inode(object); ++ object->i_flags |= S_NOQUOTA; ++ /* if everything was ok (result == 0), parent stat-data is ++ * already updated above (update_parent_dir()) */ ++ reiser4_update_sd(parent); ++ /* failure to create entry, remove object */ ++ obj_plug->delete_object(object); ++ } ++ ++ /* file has name now, clear immutable flag */ ++ reiser4_inode_clr_flag(object, REISER4_IMMUTABLE); ++ ++ /* on error, iput() will call ->delete_inode(). We should keep track ++ of the existence of stat-data for this inode and avoid attempt to ++ remove it in reiser4_delete_inode(). This is accomplished through ++ REISER4_NO_SD bit in inode.u.reiser4_i.plugin.flags ++ */ ++ return result; ++} ++ ++/* this is helper for common implementations of reiser4_mkdir, reiser4_create, ++ reiser4_mknod and reiser4_symlink ++*/ ++static int ++create_vfs_object(struct inode *parent, ++ struct dentry *dentry, reiser4_object_create_data * data) ++{ ++ reiser4_context *ctx; ++ int result; ++ struct inode *child; ++ ++ ctx = reiser4_init_context(parent->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ context_set_commit_async(ctx); ++ ++ data->parent = parent; ++ data->dentry = dentry; ++ child = NULL; ++ result = do_create_vfs_child(data, &child); ++ if (unlikely(result != 0)) { ++ if (child != NULL) { ++ reiser4_make_bad_inode(child); ++ iput(child); ++ } ++ } else ++ d_instantiate(dentry, child); ++ ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++/** ++ * helper for link_common. Estimate disk space necessary to add a link ++ * from @parent to @object ++ */ ++static reiser4_block_nr common_estimate_link(struct inode *parent /* parent ++ * directory ++ */, ++ struct inode *object /* object to ++ * which new ++ * link is ++ * being ++ * created */) ++{ ++ reiser4_block_nr res = 0; ++ file_plugin *fplug; ++ dir_plugin *dplug; ++ ++ assert("vpf-317", object != NULL); ++ assert("vpf-318", parent != NULL); ++ ++ fplug = inode_file_plugin(object); ++ dplug = inode_dir_plugin(parent); ++ /* VS-FIXME-HANS: why do we do fplug->estimate.update(object) twice ++ * instead of multiplying by 2? */ ++ /* reiser4_add_nlink(object) */ ++ res += fplug->estimate.update(object); ++ /* add_entry(parent) */ ++ res += dplug->estimate.add_entry(parent); ++ /* reiser4_del_nlink(object) */ ++ res += fplug->estimate.update(object); ++ /* update_dir(parent) */ ++ res += inode_file_plugin(parent)->estimate.update(parent); ++ /* safe-link */ ++ res += estimate_one_item_removal(reiser4_tree_by_inode(object)); ++ ++ return res; ++} ++ ++/* Estimate disk space necessary to remove a link between @parent and ++ @object. ++*/ ++static reiser4_block_nr estimate_unlink(struct inode *parent /* parent ++ * directory */, ++ struct inode *object /* object to which ++ * new link is ++ * being created ++ */) ++{ ++ reiser4_block_nr res = 0; ++ file_plugin *fplug; ++ dir_plugin *dplug; ++ ++ assert("vpf-317", object != NULL); ++ assert("vpf-318", parent != NULL); ++ ++ fplug = inode_file_plugin(object); ++ dplug = inode_dir_plugin(parent); ++ ++ /* rem_entry(parent) */ ++ res += dplug->estimate.rem_entry(parent); ++ /* reiser4_del_nlink(object) */ ++ res += fplug->estimate.update(object); ++ /* update_dir(parent) */ ++ res += inode_file_plugin(parent)->estimate.update(parent); ++ /* fplug->unlink */ ++ res += fplug->estimate.unlink(object, parent); ++ /* safe-link */ ++ res += estimate_one_insert_item(reiser4_tree_by_inode(object)); ++ ++ return res; ++} ++ ++/* helper for reiser4_unlink_common. Estimate and grab space for unlink. */ ++static int unlink_check_and_grab(struct inode *parent, struct dentry *victim) ++{ ++ file_plugin *fplug; ++ struct inode *child; ++ int result; ++ ++ result = 0; ++ child = victim->d_inode; ++ fplug = inode_file_plugin(child); ++ ++ /* check for race with create_object() */ ++ if (reiser4_inode_get_flag(child, REISER4_IMMUTABLE)) ++ return RETERR(-E_REPEAT); ++ /* object being deleted should have stat data */ ++ assert("vs-949", !reiser4_inode_get_flag(child, REISER4_NO_SD)); ++ ++ /* ask object plugin */ ++ if (fplug->can_rem_link != NULL && !fplug->can_rem_link(child)) ++ return RETERR(-ENOTEMPTY); ++ ++ result = (int)estimate_unlink(parent, child); ++ if (result < 0) ++ return result; ++ ++ return reiser4_grab_reserved(child->i_sb, result, BA_CAN_COMMIT); ++} ++ ++/* helper for reiser4_setattr_common */ ++static int setattr_reserve(reiser4_tree * tree) ++{ ++ assert("vs-1096", is_grab_enabled(get_current_context())); ++ return reiser4_grab_space(estimate_one_insert_into_item(tree), ++ BA_CAN_COMMIT); ++} ++ ++/* helper function. Standards require that for many file-system operations ++ on success ctime and mtime of parent directory is to be updated. */ ++int reiser4_update_dir(struct inode *dir) ++{ ++ assert("nikita-2525", dir != NULL); ++ ++ dir->i_ctime = dir->i_mtime = CURRENT_TIME; ++ return reiser4_update_sd(dir); ++} +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/inode_ops_rename.c linux-2.6.30/fs/reiser4/plugin/inode_ops_rename.c +--- linux-2.6.30.orig/fs/reiser4/plugin/inode_ops_rename.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/inode_ops_rename.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,925 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#include "../inode.h" ++#include "../safe_link.h" ++ ++static const char *possible_leak = "Possible disk space leak."; ++ ++/* re-bind existing name at @from_coord in @from_dir to point to @to_inode. ++ ++ Helper function called from hashed_rename() */ ++static int replace_name(struct inode *to_inode, /* inode where @from_coord is ++ * to be re-targeted at */ ++ struct inode *from_dir, /* directory where @from_coord ++ * lives */ ++ struct inode *from_inode, /* inode @from_coord ++ * originally point to */ ++ coord_t *from_coord, /* where directory entry is in ++ * the tree */ ++ lock_handle * from_lh/* lock handle on @from_coord */) ++{ ++ item_plugin *from_item; ++ int result; ++ znode *node; ++ ++ coord_clear_iplug(from_coord); ++ node = from_coord->node; ++ result = zload(node); ++ if (result != 0) ++ return result; ++ from_item = item_plugin_by_coord(from_coord); ++ if (plugin_of_group(item_plugin_by_coord(from_coord), ++ DIR_ENTRY_ITEM_TYPE)) { ++ reiser4_key to_key; ++ ++ build_sd_key(to_inode, &to_key); ++ ++ /* everything is found and prepared to change directory entry ++ at @from_coord to point to @to_inode. ++ ++ @to_inode is just about to get new name, so bump its link ++ counter. ++ ++ */ ++ result = reiser4_add_nlink(to_inode, from_dir, 0); ++ if (result != 0) { ++ /* Don't issue warning: this may be plain -EMLINK */ ++ zrelse(node); ++ return result; ++ } ++ ++ result = ++ from_item->s.dir.update_key(from_coord, &to_key, from_lh); ++ if (result != 0) { ++ reiser4_del_nlink(to_inode, from_dir, 0); ++ zrelse(node); ++ return result; ++ } ++ ++ /* @from_inode just lost its name, he-he. ++ ++ If @from_inode was directory, it contained dotdot pointing ++ to @from_dir. @from_dir i_nlink will be decreased when ++ iput() will be called on @from_inode. ++ ++ If file-system is not ADG (hard-links are ++ supported on directories), iput(from_inode) will not remove ++ @from_inode, and thus above is incorrect, but hard-links on ++ directories are problematic in many other respects. ++ */ ++ result = reiser4_del_nlink(from_inode, from_dir, 0); ++ if (result != 0) { ++ warning("nikita-2330", ++ "Cannot remove link from source: %i. %s", ++ result, possible_leak); ++ } ++ /* Has to return success, because entry is already ++ * modified. */ ++ result = 0; ++ ++ /* NOTE-NIKITA consider calling plugin method in stead of ++ accessing inode fields directly. */ ++ from_dir->i_mtime = CURRENT_TIME; ++ } else { ++ warning("nikita-2326", "Unexpected item type"); ++ result = RETERR(-EIO); ++ } ++ zrelse(node); ++ return result; ++} ++ ++/* add new entry pointing to @inode into @dir at @coord, locked by @lh ++ ++ Helper function used by hashed_rename(). */ ++static int add_name(struct inode *inode, /* inode where @coord is to be ++ * re-targeted at */ ++ struct inode *dir, /* directory where @coord lives */ ++ struct dentry *name, /* new name */ ++ coord_t *coord, /* where directory entry is in the tree ++ */ ++ lock_handle * lh, /* lock handle on @coord */ ++ int is_dir/* true, if @inode is directory */) ++{ ++ int result; ++ reiser4_dir_entry_desc entry; ++ ++ assert("nikita-2333", lh->node == coord->node); ++ assert("nikita-2334", is_dir == S_ISDIR(inode->i_mode)); ++ ++ memset(&entry, 0, sizeof entry); ++ entry.obj = inode; ++ /* build key of directory entry description */ ++ inode_dir_plugin(dir)->build_entry_key(dir, &name->d_name, &entry.key); ++ ++ /* ext2 does this in different order: first inserts new entry, ++ then increases directory nlink. We don't want do this, ++ because reiser4_add_nlink() calls ->add_link() plugin ++ method that can fail for whatever reason, leaving as with ++ cleanup problems. ++ */ ++ /* @inode is getting new name */ ++ reiser4_add_nlink(inode, dir, 0); ++ /* create @new_name in @new_dir pointing to ++ @old_inode */ ++ result = WITH_COORD(coord, ++ inode_dir_item_plugin(dir)->s.dir.add_entry(dir, ++ coord, ++ lh, ++ name, ++ &entry)); ++ if (result != 0) { ++ int result2; ++ result2 = reiser4_del_nlink(inode, dir, 0); ++ if (result2 != 0) { ++ warning("nikita-2327", ++ "Cannot drop link on %lli %i. %s", ++ (unsigned long long)get_inode_oid(inode), ++ result2, possible_leak); ++ } ++ } else ++ INODE_INC_FIELD(dir, i_size); ++ return result; ++} ++ ++static reiser4_block_nr estimate_rename(struct inode *old_dir, /* directory ++ * where @old is ++ * located */ ++ struct dentry *old_name,/* old name */ ++ struct inode *new_dir, /* directory ++ * where @new is ++ * located */ ++ struct dentry *new_name /* new name */) ++{ ++ reiser4_block_nr res1, res2; ++ dir_plugin * p_parent_old, *p_parent_new; ++ file_plugin * p_child_old, *p_child_new; ++ ++ assert("vpf-311", old_dir != NULL); ++ assert("vpf-312", new_dir != NULL); ++ assert("vpf-313", old_name != NULL); ++ assert("vpf-314", new_name != NULL); ++ ++ p_parent_old = inode_dir_plugin(old_dir); ++ p_parent_new = inode_dir_plugin(new_dir); ++ p_child_old = inode_file_plugin(old_name->d_inode); ++ if (new_name->d_inode) ++ p_child_new = inode_file_plugin(new_name->d_inode); ++ else ++ p_child_new = NULL; ++ ++ /* find_entry - can insert one leaf. */ ++ res1 = res2 = 1; ++ ++ /* replace_name */ ++ { ++ /* reiser4_add_nlink(p_child_old) and ++ * reiser4_del_nlink(p_child_old) */ ++ res1 += 2 * p_child_old->estimate.update(old_name->d_inode); ++ /* update key */ ++ res1 += 1; ++ /* reiser4_del_nlink(p_child_new) */ ++ if (p_child_new) ++ res1 += p_child_new->estimate.update(new_name->d_inode); ++ } ++ ++ /* else add_name */ ++ { ++ /* reiser4_add_nlink(p_parent_new) and ++ * reiser4_del_nlink(p_parent_new) */ ++ res2 += ++ 2 * inode_file_plugin(new_dir)->estimate.update(new_dir); ++ /* reiser4_add_nlink(p_parent_old) */ ++ res2 += p_child_old->estimate.update(old_name->d_inode); ++ /* add_entry(p_parent_new) */ ++ res2 += p_parent_new->estimate.add_entry(new_dir); ++ /* reiser4_del_nlink(p_parent_old) */ ++ res2 += p_child_old->estimate.update(old_name->d_inode); ++ } ++ ++ res1 = res1 < res2 ? res2 : res1; ++ ++ /* reiser4_write_sd(p_parent_new) */ ++ res1 += inode_file_plugin(new_dir)->estimate.update(new_dir); ++ ++ /* reiser4_write_sd(p_child_new) */ ++ if (p_child_new) ++ res1 += p_child_new->estimate.update(new_name->d_inode); ++ ++ /* hashed_rem_entry(p_parent_old) */ ++ res1 += p_parent_old->estimate.rem_entry(old_dir); ++ ++ /* reiser4_del_nlink(p_child_old) */ ++ res1 += p_child_old->estimate.update(old_name->d_inode); ++ ++ /* replace_name */ ++ { ++ /* reiser4_add_nlink(p_parent_dir_new) */ ++ res1 += inode_file_plugin(new_dir)->estimate.update(new_dir); ++ /* update_key */ ++ res1 += 1; ++ /* reiser4_del_nlink(p_parent_new) */ ++ res1 += inode_file_plugin(new_dir)->estimate.update(new_dir); ++ /* reiser4_del_nlink(p_parent_old) */ ++ res1 += inode_file_plugin(old_dir)->estimate.update(old_dir); ++ } ++ ++ /* reiser4_write_sd(p_parent_old) */ ++ res1 += inode_file_plugin(old_dir)->estimate.update(old_dir); ++ ++ /* reiser4_write_sd(p_child_old) */ ++ res1 += p_child_old->estimate.update(old_name->d_inode); ++ ++ return res1; ++} ++ ++static int hashed_rename_estimate_and_grab(struct inode *old_dir, /* directory ++ * where @old ++ * is located ++ */ ++ struct dentry *old_name,/* old name ++ */ ++ struct inode *new_dir, /* directory ++ * where @new ++ * is located ++ */ ++ struct dentry *new_name /* new name ++ */) ++{ ++ reiser4_block_nr reserve; ++ ++ reserve = estimate_rename(old_dir, old_name, new_dir, new_name); ++ ++ if (reiser4_grab_space(reserve, BA_CAN_COMMIT)) ++ return RETERR(-ENOSPC); ++ ++ return 0; ++} ++ ++/* check whether @old_inode and @new_inode can be moved within file system ++ * tree. This singles out attempts to rename pseudo-files, for example. */ ++static int can_rename(struct inode *old_dir, struct inode *old_inode, ++ struct inode *new_dir, struct inode *new_inode) ++{ ++ file_plugin *fplug; ++ dir_plugin *dplug; ++ ++ assert("nikita-3370", old_inode != NULL); ++ ++ dplug = inode_dir_plugin(new_dir); ++ fplug = inode_file_plugin(old_inode); ++ ++ if (dplug == NULL) ++ return RETERR(-ENOTDIR); ++ else if (new_dir->i_op->create == NULL) ++ return RETERR(-EPERM); ++ else if (!fplug->can_add_link(old_inode)) ++ return RETERR(-EMLINK); ++ else if (new_inode != NULL) { ++ fplug = inode_file_plugin(new_inode); ++ if (fplug->can_rem_link != NULL && ++ !fplug->can_rem_link(new_inode)) ++ return RETERR(-EBUSY); ++ } ++ return 0; ++} ++ ++int reiser4_find_entry(struct inode *, struct dentry *, lock_handle * , ++ znode_lock_mode, reiser4_dir_entry_desc *); ++int reiser4_update_dir(struct inode *); ++ ++/* this is common implementation of vfs's rename method of struct ++ inode_operations ++ See comments in the body. ++ ++ It is arguable that this function can be made generic so, that it ++ will be applicable to any kind of directory plugin that deals with ++ directories composed out of directory entries. The only obstacle ++ here is that we don't have any data-type to represent directory ++ entry. This should be re-considered when more than one different ++ directory plugin will be implemented. ++*/ ++int reiser4_rename_common(struct inode *old_dir /* directory where @old ++ * is located */ , ++ struct dentry *old_name /* old name */ , ++ struct inode *new_dir /* directory where @new ++ * is located */ , ++ struct dentry *new_name/* new name */) ++{ ++ /* From `The Open Group Base Specifications Issue 6' ++ ++ If either the old or new argument names a symbolic link, rename() ++ shall operate on the symbolic link itself, and shall not resolve ++ the last component of the argument. If the old argument and the new ++ argument resolve to the same existing file, rename() shall return ++ successfully and perform no other action. ++ ++ [this is done by VFS: vfs_rename()] ++ ++ If the old argument points to the pathname of a file that is not a ++ directory, the new argument shall not point to the pathname of a ++ directory. ++ ++ [checked by VFS: vfs_rename->may_delete()] ++ ++ If the link named by the new argument exists, it shall ++ be removed and old renamed to new. In this case, a link named new ++ shall remain visible to other processes throughout the renaming ++ operation and refer either to the file referred to by new or old ++ before the operation began. ++ ++ [we should assure this] ++ ++ Write access permission is required for ++ both the directory containing old and the directory containing new. ++ ++ [checked by VFS: vfs_rename->may_delete(), may_create()] ++ ++ If the old argument points to the pathname of a directory, the new ++ argument shall not point to the pathname of a file that is not a ++ directory. ++ ++ [checked by VFS: vfs_rename->may_delete()] ++ ++ If the directory named by the new argument exists, it ++ shall be removed and old renamed to new. In this case, a link named ++ new shall exist throughout the renaming operation and shall refer ++ either to the directory referred to by new or old before the ++ operation began. ++ ++ [we should assure this] ++ ++ If new names an existing directory, it shall be ++ required to be an empty directory. ++ ++ [we should check this] ++ ++ If the old argument points to a pathname of a symbolic link, the ++ symbolic link shall be renamed. If the new argument points to a ++ pathname of a symbolic link, the symbolic link shall be removed. ++ ++ The new pathname shall not contain a path prefix that names ++ old. Write access permission is required for the directory ++ containing old and the directory containing new. If the old ++ argument points to the pathname of a directory, write access ++ permission may be required for the directory named by old, and, if ++ it exists, the directory named by new. ++ ++ [checked by VFS: vfs_rename(), vfs_rename_dir()] ++ ++ If the link named by the new argument exists and the file's link ++ count becomes 0 when it is removed and no process has the file ++ open, the space occupied by the file shall be freed and the file ++ shall no longer be accessible. If one or more processes have the ++ file open when the last link is removed, the link shall be removed ++ before rename() returns, but the removal of the file contents shall ++ be postponed until all references to the file are closed. ++ ++ [iput() handles this, but we can do this manually, a la ++ reiser4_unlink()] ++ ++ Upon successful completion, rename() shall mark for update the ++ st_ctime and st_mtime fields of the parent directory of each file. ++ ++ [N/A] ++ ++ */ ++ reiser4_context *ctx; ++ int result; ++ int is_dir; /* is @old_name directory */ ++ ++ struct inode *old_inode; ++ struct inode *new_inode; ++ coord_t *new_coord; ++ ++ struct reiser4_dentry_fsdata *new_fsdata; ++ dir_plugin *dplug; ++ file_plugin *fplug; ++ ++ reiser4_dir_entry_desc *old_entry, *new_entry, *dotdot_entry; ++ lock_handle * new_lh, *dotdot_lh; ++ struct dentry *dotdot_name; ++ struct reiser4_dentry_fsdata *dataonstack; ++ ++ ctx = reiser4_init_context(old_dir->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ old_entry = kzalloc(3 * sizeof(*old_entry) + 2 * sizeof(*new_lh) + ++ sizeof(*dotdot_name) + sizeof(*dataonstack), ++ reiser4_ctx_gfp_mask_get()); ++ if (!old_entry) { ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return RETERR(-ENOMEM); ++ } ++ ++ new_entry = old_entry + 1; ++ dotdot_entry = old_entry + 2; ++ new_lh = (lock_handle *)(old_entry + 3); ++ dotdot_lh = new_lh + 1; ++ dotdot_name = (struct dentry *)(new_lh + 2); ++ dataonstack = (struct reiser4_dentry_fsdata *)(dotdot_name + 1); ++ ++ assert("nikita-2318", old_dir != NULL); ++ assert("nikita-2319", new_dir != NULL); ++ assert("nikita-2320", old_name != NULL); ++ assert("nikita-2321", new_name != NULL); ++ ++ old_inode = old_name->d_inode; ++ new_inode = new_name->d_inode; ++ ++ dplug = inode_dir_plugin(old_dir); ++ fplug = NULL; ++ ++ new_fsdata = reiser4_get_dentry_fsdata(new_name); ++ if (IS_ERR(new_fsdata)) { ++ kfree(old_entry); ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return PTR_ERR(new_fsdata); ++ } ++ ++ new_coord = &new_fsdata->dec.entry_coord; ++ coord_clear_iplug(new_coord); ++ ++ is_dir = S_ISDIR(old_inode->i_mode); ++ ++ assert("nikita-3461", old_inode->i_nlink >= 1 + !!is_dir); ++ ++ /* if target is existing directory and it's not empty---return error. ++ ++ This check is done specifically, because is_dir_empty() requires ++ tree traversal and have to be done before locks are taken. ++ */ ++ if (is_dir && new_inode != NULL && is_dir_empty(new_inode) != 0) { ++ kfree(old_entry); ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return RETERR(-ENOTEMPTY); ++ } ++ ++ result = can_rename(old_dir, old_inode, new_dir, new_inode); ++ if (result != 0) { ++ kfree(old_entry); ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ result = hashed_rename_estimate_and_grab(old_dir, old_name, ++ new_dir, new_name); ++ if (result != 0) { ++ kfree(old_entry); ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ init_lh(new_lh); ++ ++ /* find entry for @new_name */ ++ result = reiser4_find_entry(new_dir, new_name, new_lh, ZNODE_WRITE_LOCK, ++ new_entry); ++ ++ if (IS_CBKERR(result)) { ++ done_lh(new_lh); ++ kfree(old_entry); ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++ } ++ ++ reiser4_seal_done(&new_fsdata->dec.entry_seal); ++ ++ /* add or replace name for @old_inode as @new_name */ ++ if (new_inode != NULL) { ++ /* target (@new_name) exists. */ ++ /* Not clear what to do with objects that are ++ both directories and files at the same time. */ ++ if (result == CBK_COORD_FOUND) { ++ result = replace_name(old_inode, ++ new_dir, ++ new_inode, new_coord, new_lh); ++ if (result == 0) ++ fplug = inode_file_plugin(new_inode); ++ } else if (result == CBK_COORD_NOTFOUND) { ++ /* VFS told us that @new_name is bound to existing ++ inode, but we failed to find directory entry. */ ++ warning("nikita-2324", "Target not found"); ++ result = RETERR(-ENOENT); ++ } ++ } else { ++ /* target (@new_name) doesn't exists. */ ++ if (result == CBK_COORD_NOTFOUND) ++ result = add_name(old_inode, ++ new_dir, ++ new_name, new_coord, new_lh, is_dir); ++ else if (result == CBK_COORD_FOUND) { ++ /* VFS told us that @new_name is "negative" dentry, ++ but we found directory entry. */ ++ warning("nikita-2331", "Target found unexpectedly"); ++ result = RETERR(-EIO); ++ } ++ } ++ ++ assert("nikita-3462", ergo(result == 0, ++ old_inode->i_nlink >= 2 + !!is_dir)); ++ ++ /* We are done with all modifications to the @new_dir, release lock on ++ node. */ ++ done_lh(new_lh); ++ ++ if (fplug != NULL) { ++ /* detach @new_inode from name-space */ ++ result = fplug->detach(new_inode, new_dir); ++ if (result != 0) ++ warning("nikita-2330", "Cannot detach %lli: %i. %s", ++ (unsigned long long)get_inode_oid(new_inode), ++ result, possible_leak); ++ } ++ ++ if (new_inode != NULL) ++ reiser4_update_sd(new_inode); ++ ++ if (result == 0) { ++ old_entry->obj = old_inode; ++ ++ dplug->build_entry_key(old_dir, ++ &old_name->d_name, &old_entry->key); ++ ++ /* At this stage new name was introduced for ++ @old_inode. @old_inode, @new_dir, and @new_inode i_nlink ++ counters were updated. ++ ++ We want to remove @old_name now. If @old_inode wasn't ++ directory this is simple. ++ */ ++ result = dplug->rem_entry(old_dir, old_name, old_entry); ++ if (result != 0 && result != -ENOMEM) { ++ warning("nikita-2335", ++ "Cannot remove old name: %i", result); ++ } else { ++ result = reiser4_del_nlink(old_inode, old_dir, 0); ++ if (result != 0 && result != -ENOMEM) { ++ warning("nikita-2337", ++ "Cannot drop link on old: %i", result); ++ } ++ } ++ ++ if (result == 0 && is_dir) { ++ /* @old_inode is directory. We also have to update ++ dotdot entry. */ ++ coord_t *dotdot_coord; ++ ++ memset(dataonstack, 0, sizeof dataonstack); ++ memset(dotdot_entry, 0, sizeof dotdot_entry); ++ dotdot_entry->obj = old_dir; ++ memset(dotdot_name, 0, sizeof dotdot_name); ++ dotdot_name->d_name.name = ".."; ++ dotdot_name->d_name.len = 2; ++ /* ++ * allocate ->d_fsdata on the stack to avoid using ++ * reiser4_get_dentry_fsdata(). Locking is not needed, ++ * because dentry is private to the current thread. ++ */ ++ dotdot_name->d_fsdata = dataonstack; ++ init_lh(dotdot_lh); ++ ++ dotdot_coord = &dataonstack->dec.entry_coord; ++ coord_clear_iplug(dotdot_coord); ++ ++ result = reiser4_find_entry(old_inode, dotdot_name, ++ dotdot_lh, ZNODE_WRITE_LOCK, ++ dotdot_entry); ++ if (result == 0) { ++ /* replace_name() decreases i_nlink on ++ * @old_dir */ ++ result = replace_name(new_dir, ++ old_inode, ++ old_dir, ++ dotdot_coord, dotdot_lh); ++ } else ++ result = RETERR(-EIO); ++ done_lh(dotdot_lh); ++ } ++ } ++ reiser4_update_dir(new_dir); ++ reiser4_update_dir(old_dir); ++ reiser4_update_sd(old_inode); ++ if (result == 0) { ++ file_plugin *fplug; ++ ++ if (new_inode != NULL) { ++ /* add safe-link for target file (in case we removed ++ * last reference to the poor fellow */ ++ fplug = inode_file_plugin(new_inode); ++ if (new_inode->i_nlink == 0) ++ result = safe_link_add(new_inode, SAFE_UNLINK); ++ } ++ } ++ kfree(old_entry); ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++} ++ ++#if 0 ++int reiser4_rename_common(struct inode *old_dir /* directory where @old ++ * is located */ , ++ struct dentry *old_name /* old name */ , ++ struct inode *new_dir /* directory where @new ++ * is located */ , ++ struct dentry *new_name/* new name */) ++{ ++ /* From `The Open Group Base Specifications Issue 6' ++ ++ If either the old or new argument names a symbolic link, rename() ++ shall operate on the symbolic link itself, and shall not resolve ++ the last component of the argument. If the old argument and the new ++ argument resolve to the same existing file, rename() shall return ++ successfully and perform no other action. ++ ++ [this is done by VFS: vfs_rename()] ++ ++ If the old argument points to the pathname of a file that is not a ++ directory, the new argument shall not point to the pathname of a ++ directory. ++ ++ [checked by VFS: vfs_rename->may_delete()] ++ ++ If the link named by the new argument exists, it shall ++ be removed and old renamed to new. In this case, a link named new ++ shall remain visible to other processes throughout the renaming ++ operation and refer either to the file referred to by new or old ++ before the operation began. ++ ++ [we should assure this] ++ ++ Write access permission is required for ++ both the directory containing old and the directory containing new. ++ ++ [checked by VFS: vfs_rename->may_delete(), may_create()] ++ ++ If the old argument points to the pathname of a directory, the new ++ argument shall not point to the pathname of a file that is not a ++ directory. ++ ++ [checked by VFS: vfs_rename->may_delete()] ++ ++ If the directory named by the new argument exists, it ++ shall be removed and old renamed to new. In this case, a link named ++ new shall exist throughout the renaming operation and shall refer ++ either to the directory referred to by new or old before the ++ operation began. ++ ++ [we should assure this] ++ ++ If new names an existing directory, it shall be ++ required to be an empty directory. ++ ++ [we should check this] ++ ++ If the old argument points to a pathname of a symbolic link, the ++ symbolic link shall be renamed. If the new argument points to a ++ pathname of a symbolic link, the symbolic link shall be removed. ++ ++ The new pathname shall not contain a path prefix that names ++ old. Write access permission is required for the directory ++ containing old and the directory containing new. If the old ++ argument points to the pathname of a directory, write access ++ permission may be required for the directory named by old, and, if ++ it exists, the directory named by new. ++ ++ [checked by VFS: vfs_rename(), vfs_rename_dir()] ++ ++ If the link named by the new argument exists and the file's link ++ count becomes 0 when it is removed and no process has the file ++ open, the space occupied by the file shall be freed and the file ++ shall no longer be accessible. If one or more processes have the ++ file open when the last link is removed, the link shall be removed ++ before rename() returns, but the removal of the file contents shall ++ be postponed until all references to the file are closed. ++ ++ [iput() handles this, but we can do this manually, a la ++ reiser4_unlink()] ++ ++ Upon successful completion, rename() shall mark for update the ++ st_ctime and st_mtime fields of the parent directory of each file. ++ ++ [N/A] ++ ++ */ ++ reiser4_context *ctx; ++ int result; ++ int is_dir; /* is @old_name directory */ ++ struct inode *old_inode; ++ struct inode *new_inode; ++ reiser4_dir_entry_desc old_entry; ++ reiser4_dir_entry_desc new_entry; ++ coord_t *new_coord; ++ struct reiser4_dentry_fsdata *new_fsdata; ++ lock_handle new_lh; ++ dir_plugin *dplug; ++ file_plugin *fplug; ++ ++ ctx = reiser4_init_context(old_dir->i_sb); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ assert("nikita-2318", old_dir != NULL); ++ assert("nikita-2319", new_dir != NULL); ++ assert("nikita-2320", old_name != NULL); ++ assert("nikita-2321", new_name != NULL); ++ ++ old_inode = old_name->d_inode; ++ new_inode = new_name->d_inode; ++ ++ dplug = inode_dir_plugin(old_dir); ++ fplug = NULL; ++ ++ new_fsdata = reiser4_get_dentry_fsdata(new_name); ++ if (IS_ERR(new_fsdata)) { ++ result = PTR_ERR(new_fsdata); ++ goto exit; ++ } ++ ++ new_coord = &new_fsdata->dec.entry_coord; ++ coord_clear_iplug(new_coord); ++ ++ is_dir = S_ISDIR(old_inode->i_mode); ++ ++ assert("nikita-3461", old_inode->i_nlink >= 1 + !!is_dir); ++ ++ /* if target is existing directory and it's not empty---return error. ++ ++ This check is done specifically, because is_dir_empty() requires ++ tree traversal and have to be done before locks are taken. ++ */ ++ if (is_dir && new_inode != NULL && is_dir_empty(new_inode) != 0) ++ return RETERR(-ENOTEMPTY); ++ ++ result = can_rename(old_dir, old_inode, new_dir, new_inode); ++ if (result != 0) ++ goto exit; ++ ++ result = hashed_rename_estimate_and_grab(old_dir, old_name, ++ new_dir, new_name); ++ if (result != 0) ++ goto exit; ++ ++ init_lh(&new_lh); ++ ++ /* find entry for @new_name */ ++ result = reiser4_find_entry(new_dir, new_name, &new_lh, ++ ZNODE_WRITE_LOCK, &new_entry); ++ ++ if (IS_CBKERR(result)) { ++ done_lh(&new_lh); ++ goto exit; ++ } ++ ++ reiser4_seal_done(&new_fsdata->dec.entry_seal); ++ ++ /* add or replace name for @old_inode as @new_name */ ++ if (new_inode != NULL) { ++ /* target (@new_name) exists. */ ++ /* Not clear what to do with objects that are ++ both directories and files at the same time. */ ++ if (result == CBK_COORD_FOUND) { ++ result = replace_name(old_inode, ++ new_dir, ++ new_inode, new_coord, &new_lh); ++ if (result == 0) ++ fplug = inode_file_plugin(new_inode); ++ } else if (result == CBK_COORD_NOTFOUND) { ++ /* VFS told us that @new_name is bound to existing ++ inode, but we failed to find directory entry. */ ++ warning("nikita-2324", "Target not found"); ++ result = RETERR(-ENOENT); ++ } ++ } else { ++ /* target (@new_name) doesn't exists. */ ++ if (result == CBK_COORD_NOTFOUND) ++ result = add_name(old_inode, ++ new_dir, ++ new_name, new_coord, &new_lh, is_dir); ++ else if (result == CBK_COORD_FOUND) { ++ /* VFS told us that @new_name is "negative" dentry, ++ but we found directory entry. */ ++ warning("nikita-2331", "Target found unexpectedly"); ++ result = RETERR(-EIO); ++ } ++ } ++ ++ assert("nikita-3462", ergo(result == 0, ++ old_inode->i_nlink >= 2 + !!is_dir)); ++ ++ /* We are done with all modifications to the @new_dir, release lock on ++ node. */ ++ done_lh(&new_lh); ++ ++ if (fplug != NULL) { ++ /* detach @new_inode from name-space */ ++ result = fplug->detach(new_inode, new_dir); ++ if (result != 0) ++ warning("nikita-2330", "Cannot detach %lli: %i. %s", ++ (unsigned long long)get_inode_oid(new_inode), ++ result, possible_leak); ++ } ++ ++ if (new_inode != NULL) ++ reiser4_update_sd(new_inode); ++ ++ if (result == 0) { ++ memset(&old_entry, 0, sizeof old_entry); ++ old_entry.obj = old_inode; ++ ++ dplug->build_entry_key(old_dir, ++ &old_name->d_name, &old_entry.key); ++ ++ /* At this stage new name was introduced for ++ @old_inode. @old_inode, @new_dir, and @new_inode i_nlink ++ counters were updated. ++ ++ We want to remove @old_name now. If @old_inode wasn't ++ directory this is simple. ++ */ ++ result = dplug->rem_entry(old_dir, old_name, &old_entry); ++ /*result = rem_entry_hashed(old_dir, old_name, &old_entry); */ ++ if (result != 0 && result != -ENOMEM) { ++ warning("nikita-2335", ++ "Cannot remove old name: %i", result); ++ } else { ++ result = reiser4_del_nlink(old_inode, old_dir, 0); ++ if (result != 0 && result != -ENOMEM) { ++ warning("nikita-2337", ++ "Cannot drop link on old: %i", result); ++ } ++ } ++ ++ if (result == 0 && is_dir) { ++ /* @old_inode is directory. We also have to update ++ dotdot entry. */ ++ coord_t *dotdot_coord; ++ lock_handle dotdot_lh; ++ struct dentry dotdot_name; ++ reiser4_dir_entry_desc dotdot_entry; ++ struct reiser4_dentry_fsdata dataonstack; ++ struct reiser4_dentry_fsdata *fsdata; ++ ++ memset(&dataonstack, 0, sizeof dataonstack); ++ memset(&dotdot_entry, 0, sizeof dotdot_entry); ++ dotdot_entry.obj = old_dir; ++ memset(&dotdot_name, 0, sizeof dotdot_name); ++ dotdot_name.d_name.name = ".."; ++ dotdot_name.d_name.len = 2; ++ /* ++ * allocate ->d_fsdata on the stack to avoid using ++ * reiser4_get_dentry_fsdata(). Locking is not needed, ++ * because dentry is private to the current thread. ++ */ ++ dotdot_name.d_fsdata = &dataonstack; ++ init_lh(&dotdot_lh); ++ ++ fsdata = &dataonstack; ++ dotdot_coord = &fsdata->dec.entry_coord; ++ coord_clear_iplug(dotdot_coord); ++ ++ result = reiser4_find_entry(old_inode, ++ &dotdot_name, ++ &dotdot_lh, ++ ZNODE_WRITE_LOCK, ++ &dotdot_entry); ++ if (result == 0) { ++ /* replace_name() decreases i_nlink on ++ * @old_dir */ ++ result = replace_name(new_dir, ++ old_inode, ++ old_dir, ++ dotdot_coord, &dotdot_lh); ++ } else ++ result = RETERR(-EIO); ++ done_lh(&dotdot_lh); ++ } ++ } ++ reiser4_update_dir(new_dir); ++ reiser4_update_dir(old_dir); ++ reiser4_update_sd(old_inode); ++ if (result == 0) { ++ file_plugin *fplug; ++ ++ if (new_inode != NULL) { ++ /* add safe-link for target file (in case we removed ++ * last reference to the poor fellow */ ++ fplug = inode_file_plugin(new_inode); ++ if (new_inode->i_nlink == 0) ++ result = safe_link_add(new_inode, SAFE_UNLINK); ++ } ++ } ++exit: ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++ return result; ++} ++#endif +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/acl.h linux-2.6.30/fs/reiser4/plugin/item/acl.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/acl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/acl.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,66 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Directory entry. */ ++ ++#if !defined( __FS_REISER4_PLUGIN_DIRECTORY_ENTRY_H__ ) ++#define __FS_REISER4_PLUGIN_DIRECTORY_ENTRY_H__ ++ ++#include "../../forward.h" ++#include "../../dformat.h" ++#include "../../kassign.h" ++#include "../../key.h" ++ ++#include <linux/fs.h> ++#include <linux/dcache.h> /* for struct dentry */ ++ ++typedef struct directory_entry_format { ++ /* key of object stat-data. It's not necessary to store whole ++ key here, because it's always key of stat-data, so minor ++ packing locality and offset can be omitted here. But this ++ relies on particular key allocation scheme for stat-data, so, ++ for extensibility sake, whole key can be stored here. ++ ++ We store key as array of bytes, because we don't want 8-byte ++ alignment of dir entries. ++ */ ++ obj_key_id id; ++ /* file name. Null terminated string. */ ++ d8 name[0]; ++} directory_entry_format; ++ ++void print_de(const char *prefix, coord_t * coord); ++int extract_key_de(const coord_t * coord, reiser4_key * key); ++int update_key_de(const coord_t * coord, const reiser4_key * key, ++ lock_handle * lh); ++char *extract_name_de(const coord_t * coord, char *buf); ++unsigned extract_file_type_de(const coord_t * coord); ++int add_entry_de(struct inode *dir, coord_t * coord, ++ lock_handle * lh, const struct dentry *name, ++ reiser4_dir_entry_desc * entry); ++int rem_entry_de(struct inode *dir, const struct qstr *name, coord_t * coord, ++ lock_handle * lh, reiser4_dir_entry_desc * entry); ++int max_name_len_de(const struct inode *dir); ++ ++int de_rem_and_shrink(struct inode *dir, coord_t * coord, int length); ++ ++char *extract_dent_name(const coord_t * coord, ++ directory_entry_format * dent, char *buf); ++ ++#if REISER4_LARGE_KEY ++#define DE_NAME_BUF_LEN (24) ++#else ++#define DE_NAME_BUF_LEN (16) ++#endif ++ ++/* __FS_REISER4_PLUGIN_DIRECTORY_ENTRY_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/blackbox.c linux-2.6.30/fs/reiser4/plugin/item/blackbox.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/blackbox.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/blackbox.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,142 @@ ++/* Copyright 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Black box item implementation */ ++ ++#include "../../forward.h" ++#include "../../debug.h" ++#include "../../dformat.h" ++#include "../../kassign.h" ++#include "../../coord.h" ++#include "../../tree.h" ++#include "../../lock.h" ++ ++#include "blackbox.h" ++#include "item.h" ++#include "../plugin.h" ++ ++int ++store_black_box(reiser4_tree * tree, ++ const reiser4_key * key, void *data, int length) ++{ ++ int result; ++ reiser4_item_data idata; ++ coord_t coord; ++ lock_handle lh; ++ ++ memset(&idata, 0, sizeof idata); ++ ++ idata.data = data; ++ idata.user = 0; ++ idata.length = length; ++ idata.iplug = item_plugin_by_id(BLACK_BOX_ID); ++ ++ init_lh(&lh); ++ result = insert_by_key(tree, key, ++ &idata, &coord, &lh, LEAF_LEVEL, CBK_UNIQUE); ++ ++ assert("nikita-3413", ++ ergo(result == 0, ++ WITH_COORD(&coord, ++ item_length_by_coord(&coord) == length))); ++ ++ done_lh(&lh); ++ return result; ++} ++ ++int ++load_black_box(reiser4_tree * tree, ++ reiser4_key * key, void *data, int length, int exact) ++{ ++ int result; ++ coord_t coord; ++ lock_handle lh; ++ ++ init_lh(&lh); ++ result = coord_by_key(tree, key, ++ &coord, &lh, ZNODE_READ_LOCK, ++ exact ? FIND_EXACT : FIND_MAX_NOT_MORE_THAN, ++ LEAF_LEVEL, LEAF_LEVEL, CBK_UNIQUE, NULL); ++ ++ if (result == 0) { ++ int ilen; ++ ++ result = zload(coord.node); ++ if (result == 0) { ++ ilen = item_length_by_coord(&coord); ++ if (ilen <= length) { ++ memcpy(data, item_body_by_coord(&coord), ilen); ++ unit_key_by_coord(&coord, key); ++ } else if (exact) { ++ /* ++ * item is larger than buffer provided by the ++ * user. Only issue a warning if @exact is ++ * set. If @exact is false, we are iterating ++ * over all safe-links and here we are reaching ++ * the end of the iteration. ++ */ ++ warning("nikita-3415", ++ "Wrong black box length: %i > %i", ++ ilen, length); ++ result = RETERR(-EIO); ++ } ++ zrelse(coord.node); ++ } ++ } ++ ++ done_lh(&lh); ++ return result; ++ ++} ++ ++int ++update_black_box(reiser4_tree * tree, ++ const reiser4_key * key, void *data, int length) ++{ ++ int result; ++ coord_t coord; ++ lock_handle lh; ++ ++ init_lh(&lh); ++ result = coord_by_key(tree, key, ++ &coord, &lh, ZNODE_READ_LOCK, ++ FIND_EXACT, ++ LEAF_LEVEL, LEAF_LEVEL, CBK_UNIQUE, NULL); ++ if (result == 0) { ++ int ilen; ++ ++ result = zload(coord.node); ++ if (result == 0) { ++ ilen = item_length_by_coord(&coord); ++ if (length <= ilen) { ++ memcpy(item_body_by_coord(&coord), data, ++ length); ++ } else { ++ warning("nikita-3437", ++ "Wrong black box length: %i < %i", ++ ilen, length); ++ result = RETERR(-EIO); ++ } ++ zrelse(coord.node); ++ } ++ } ++ ++ done_lh(&lh); ++ return result; ++ ++} ++ ++int kill_black_box(reiser4_tree * tree, const reiser4_key * key) ++{ ++ return reiser4_cut_tree(tree, key, key, NULL, 1); ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/blackbox.h linux-2.6.30/fs/reiser4/plugin/item/blackbox.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/blackbox.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/blackbox.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,33 @@ ++/* Copyright 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* "Black box" entry to fixed-width contain user supplied data */ ++ ++#if !defined( __FS_REISER4_BLACK_BOX_H__ ) ++#define __FS_REISER4_BLACK_BOX_H__ ++ ++#include "../../forward.h" ++#include "../../dformat.h" ++#include "../../kassign.h" ++#include "../../key.h" ++ ++extern int store_black_box(reiser4_tree * tree, ++ const reiser4_key * key, void *data, int length); ++extern int load_black_box(reiser4_tree * tree, ++ reiser4_key * key, void *data, int length, int exact); ++extern int kill_black_box(reiser4_tree * tree, const reiser4_key * key); ++extern int update_black_box(reiser4_tree * tree, ++ const reiser4_key * key, void *data, int length); ++ ++/* __FS_REISER4_BLACK_BOX_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/cde.c linux-2.6.30/fs/reiser4/plugin/item/cde.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/cde.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/cde.c 2009-06-22 17:27:31.000000000 +0200 +@@ -0,0 +1,1008 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Directory entry implementation */ ++ ++/* DESCRIPTION: ++ ++ This is "compound" directory item plugin implementation. This directory ++ item type is compound (as opposed to the "simple directory item" in ++ fs/reiser4/plugin/item/sde.[ch]), because it consists of several directory ++ entries. ++ ++ The reason behind this decision is disk space efficiency: all directory ++ entries inside the same directory have identical fragment in their ++ keys. This, of course, depends on key assignment policy. In our default key ++ assignment policy, all directory entries have the same locality which is ++ equal to the object id of their directory. ++ ++ Composing directory item out of several directory entries for the same ++ directory allows us to store said key fragment only once. That is, this is ++ some ad hoc form of key compression (stem compression) that is implemented ++ here, because general key compression is not supposed to be implemented in ++ v4.0. ++ ++ Another decision that was made regarding all directory item plugins, is ++ that they will store entry keys unaligned. This is for that sake of disk ++ space efficiency again. ++ ++ In should be noted, that storing keys unaligned increases CPU consumption, ++ at least on some architectures. ++ ++ Internal on-disk structure of the compound directory item is the following: ++ ++ HEADER cde_item_format. Here number of entries is stored. ++ ENTRY_HEADER_0 cde_unit_header. Here part of entry key and ++ ENTRY_HEADER_1 offset of entry body are stored. ++ ENTRY_HEADER_2 (basically two last parts of key) ++ ... ++ ENTRY_HEADER_N ++ ENTRY_BODY_0 directory_entry_format. Here part of stat data key and ++ ENTRY_BODY_1 NUL-terminated name are stored. ++ ENTRY_BODY_2 (part of statadta key in the ++ sence that since all SDs have ++ zero offset, this offset is not ++ stored on disk). ++ ... ++ ENTRY_BODY_N ++ ++ When it comes to the balancing, each directory entry in compound directory ++ item is unit, that is, something that can be cut from one item and pasted ++ into another item of the same type. Handling of unit cut and paste is major ++ reason for the complexity of code below. ++ ++*/ ++ ++#include "../../forward.h" ++#include "../../debug.h" ++#include "../../dformat.h" ++#include "../../kassign.h" ++#include "../../key.h" ++#include "../../coord.h" ++#include "sde.h" ++#include "cde.h" ++#include "item.h" ++#include "../node/node.h" ++#include "../plugin.h" ++#include "../../znode.h" ++#include "../../carry.h" ++#include "../../tree.h" ++#include "../../inode.h" ++ ++#include <linux/fs.h> /* for struct inode */ ++#include <linux/dcache.h> /* for struct dentry */ ++#include <linux/quotaops.h> ++ ++#if 0 ++#define CHECKME(coord) \ ++({ \ ++ const char *message; \ ++ coord_t dup; \ ++ \ ++ coord_dup_nocheck(&dup, (coord)); \ ++ dup.unit_pos = 0; \ ++ assert("nikita-2871", cde_check(&dup, &message) == 0); \ ++}) ++#else ++#define CHECKME(coord) noop ++#endif ++ ++/* return body of compound directory item at @coord */ ++static inline cde_item_format *formatted_at(const coord_t * coord) ++{ ++ assert("nikita-1282", coord != NULL); ++ return item_body_by_coord(coord); ++} ++ ++/* return entry header at @coord */ ++static inline cde_unit_header *header_at(const coord_t * ++ coord /* coord of item */ , ++ int idx /* index of unit */ ) ++{ ++ assert("nikita-1283", coord != NULL); ++ return &formatted_at(coord)->entry[idx]; ++} ++ ++/* return number of units in compound directory item at @coord */ ++static int units(const coord_t * coord /* coord of item */ ) ++{ ++ return le16_to_cpu(get_unaligned(&formatted_at(coord)->num_of_entries)); ++} ++ ++/* return offset of the body of @idx-th entry in @coord */ ++static unsigned int offset_of(const coord_t * coord /* coord of item */ , ++ int idx /* index of unit */ ) ++{ ++ if (idx < units(coord)) ++ return le16_to_cpu(get_unaligned(&header_at(coord, idx)->offset)); ++ else if (idx == units(coord)) ++ return item_length_by_coord(coord); ++ else ++ impossible("nikita-1308", "Wrong idx"); ++ return 0; ++} ++ ++/* set offset of the body of @idx-th entry in @coord */ ++static void set_offset(const coord_t * coord /* coord of item */ , ++ int idx /* index of unit */ , ++ unsigned int offset /* new offset */ ) ++{ ++ put_unaligned(cpu_to_le16((__u16) offset), &header_at(coord, idx)->offset); ++} ++ ++static void adj_offset(const coord_t * coord /* coord of item */ , ++ int idx /* index of unit */ , ++ int delta /* offset change */ ) ++{ ++ d16 *doffset; ++ __u16 offset; ++ ++ doffset = &header_at(coord, idx)->offset; ++ offset = le16_to_cpu(get_unaligned(doffset)); ++ offset += delta; ++ put_unaligned(cpu_to_le16((__u16) offset), doffset); ++} ++ ++/* return pointer to @offset-th byte from the beginning of @coord */ ++static char *address(const coord_t * coord /* coord of item */ , ++ int offset) ++{ ++ return ((char *)item_body_by_coord(coord)) + offset; ++} ++ ++/* return pointer to the body of @idx-th entry in @coord */ ++static directory_entry_format *entry_at(const coord_t * coord /* coord of ++ * item */ , ++ int idx /* index of unit */ ) ++{ ++ return (directory_entry_format *) address(coord, ++ (int)offset_of(coord, idx)); ++} ++ ++/* return number of unit referenced by @coord */ ++static int idx_of(const coord_t * coord /* coord of item */ ) ++{ ++ assert("nikita-1285", coord != NULL); ++ return coord->unit_pos; ++} ++ ++/* find position where entry with @entry_key would be inserted into @coord */ ++static int find(const coord_t * coord /* coord of item */ , ++ const reiser4_key * entry_key /* key to look for */ , ++ cmp_t * last /* result of last comparison */ ) ++{ ++ int entries; ++ ++ int left; ++ int right; ++ ++ cde_unit_header *header; ++ ++ assert("nikita-1295", coord != NULL); ++ assert("nikita-1296", entry_key != NULL); ++ assert("nikita-1297", last != NULL); ++ ++ entries = units(coord); ++ left = 0; ++ right = entries - 1; ++ while (right - left >= REISER4_SEQ_SEARCH_BREAK) { ++ int median; ++ ++ median = (left + right) >> 1; ++ ++ header = header_at(coord, median); ++ *last = de_id_key_cmp(&header->hash, entry_key); ++ switch (*last) { ++ case LESS_THAN: ++ left = median; ++ break; ++ case GREATER_THAN: ++ right = median; ++ break; ++ case EQUAL_TO:{ ++ do { ++ median--; ++ header--; ++ } while (median >= 0 && ++ de_id_key_cmp(&header->hash, ++ entry_key) == EQUAL_TO); ++ return median + 1; ++ } ++ } ++ } ++ header = header_at(coord, left); ++ for (; left < entries; ++left, ++header) { ++ prefetch(header + 1); ++ *last = de_id_key_cmp(&header->hash, entry_key); ++ if (*last != LESS_THAN) ++ break; ++ } ++ if (left < entries) ++ return left; ++ else ++ return RETERR(-ENOENT); ++ ++} ++ ++/* expand @coord as to accommodate for insertion of @no new entries starting ++ from @pos, with total bodies size @size. */ ++static int expand_item(const coord_t * coord /* coord of item */ , ++ int pos /* unit position */ , int no /* number of new ++ * units*/ , ++ int size /* total size of new units' data */ , ++ unsigned int data_size /* free space already reserved ++ * in the item for insertion */ ) ++{ ++ int entries; ++ cde_unit_header *header; ++ char *dent; ++ int i; ++ ++ assert("nikita-1310", coord != NULL); ++ assert("nikita-1311", pos >= 0); ++ assert("nikita-1312", no > 0); ++ assert("nikita-1313", data_size >= no * sizeof(directory_entry_format)); ++ assert("nikita-1343", ++ item_length_by_coord(coord) >= ++ (int)(size + data_size + no * sizeof *header)); ++ ++ entries = units(coord); ++ ++ if (pos == entries) ++ dent = address(coord, size); ++ else ++ dent = (char *)entry_at(coord, pos); ++ /* place where new header will be in */ ++ header = header_at(coord, pos); ++ /* free space for new entry headers */ ++ memmove(header + no, header, ++ (unsigned)(address(coord, size) - (char *)header)); ++ /* if adding to the end initialise first new header */ ++ if (pos == entries) { ++ set_offset(coord, pos, (unsigned)size); ++ } ++ ++ /* adjust entry pointer and size */ ++ dent = dent + no * sizeof *header; ++ size += no * sizeof *header; ++ /* free space for new entries */ ++ memmove(dent + data_size, dent, ++ (unsigned)(address(coord, size) - dent)); ++ ++ /* increase counter */ ++ entries += no; ++ put_unaligned(cpu_to_le16((__u16) entries), &formatted_at(coord)->num_of_entries); ++ ++ /* [ 0 ... pos ] entries were shifted by no * ( sizeof *header ) ++ bytes. */ ++ for (i = 0; i <= pos; ++i) ++ adj_offset(coord, i, no * sizeof *header); ++ /* [ pos + no ... +\infty ) entries were shifted by ( no * ++ sizeof *header + data_size ) bytes */ ++ for (i = pos + no; i < entries; ++i) ++ adj_offset(coord, i, no * sizeof *header + data_size); ++ return 0; ++} ++ ++/* insert new @entry into item */ ++static int expand(const coord_t * coord /* coord of item */ , ++ struct cde_entry * entry /* entry to insert */ , ++ int len /* length of @entry data */ , ++ int *pos /* position to insert */ , ++ reiser4_dir_entry_desc * dir_entry /* parameters for new ++ * entry */ ) ++{ ++ cmp_t cmp_res; ++ int datasize; ++ ++ *pos = find(coord, &dir_entry->key, &cmp_res); ++ if (*pos < 0) ++ *pos = units(coord); ++ ++ datasize = sizeof(directory_entry_format); ++ if (is_longname(entry->name->name, entry->name->len)) ++ datasize += entry->name->len + 1; ++ ++ expand_item(coord, *pos, 1, item_length_by_coord(coord) - len, ++ datasize); ++ return 0; ++} ++ ++/* paste body of @entry into item */ ++static int paste_entry(const coord_t * coord /* coord of item */ , ++ struct cde_entry * entry /* new entry */ , ++ int pos /* position to insert */ , ++ reiser4_dir_entry_desc * dir_entry /* parameters for ++ * new entry */ ) ++{ ++ cde_unit_header *header; ++ directory_entry_format *dent; ++ const char *name; ++ int len; ++ ++ header = header_at(coord, pos); ++ dent = entry_at(coord, pos); ++ ++ build_de_id_by_key(&dir_entry->key, &header->hash); ++ build_inode_key_id(entry->obj, &dent->id); ++ /* AUDIT unsafe strcpy() operation! It should be replaced with ++ much less CPU hungry ++ memcpy( ( char * ) dent -> name, entry -> name -> name , entry -> name -> len ); ++ ++ Also a more major thing is that there should be a way to figure out ++ amount of space in dent -> name and be able to check that we are ++ not going to overwrite more than we supposed to */ ++ name = entry->name->name; ++ len = entry->name->len; ++ if (is_longname(name, len)) { ++ strcpy((unsigned char *)dent->name, name); ++ put_unaligned(0, &dent->name[len]); ++ } ++ return 0; ++} ++ ++/* estimate how much space is necessary in item to insert/paste set of entries ++ described in @data. */ ++int estimate_cde(const coord_t * coord /* coord of item */ , ++ const reiser4_item_data * data /* parameters for new item */ ) ++{ ++ struct cde_entry_data *e; ++ int result; ++ int i; ++ ++ e = (struct cde_entry_data *) data->data; ++ ++ assert("nikita-1288", e != NULL); ++ assert("nikita-1289", e->num_of_entries >= 0); ++ ++ if (coord == NULL) ++ /* insert */ ++ result = sizeof(cde_item_format); ++ else ++ /* paste */ ++ result = 0; ++ ++ result += e->num_of_entries * ++ (sizeof(cde_unit_header) + sizeof(directory_entry_format)); ++ for (i = 0; i < e->num_of_entries; ++i) { ++ const char *name; ++ int len; ++ ++ name = e->entry[i].name->name; ++ len = e->entry[i].name->len; ++ assert("nikita-2054", strlen(name) == len); ++ if (is_longname(name, len)) ++ result += len + 1; ++ } ++ ((reiser4_item_data *) data)->length = result; ++ return result; ++} ++ ++/* ->nr_units() method for this item plugin. */ ++pos_in_node_t nr_units_cde(const coord_t * coord /* coord of item */ ) ++{ ++ return units(coord); ++} ++ ++/* ->unit_key() method for this item plugin. */ ++reiser4_key *unit_key_cde(const coord_t * coord /* coord of item */ , ++ reiser4_key * key /* resulting key */ ) ++{ ++ assert("nikita-1452", coord != NULL); ++ assert("nikita-1345", idx_of(coord) < units(coord)); ++ assert("nikita-1346", key != NULL); ++ ++ item_key_by_coord(coord, key); ++ extract_key_from_de_id(extract_dir_id_from_key(key), ++ &header_at(coord, idx_of(coord))->hash, key); ++ return key; ++} ++ ++/* mergeable_cde(): implementation of ->mergeable() item method. ++ ++ Two directory items are mergeable iff they are from the same ++ directory. That simple. ++ ++*/ ++int mergeable_cde(const coord_t * p1 /* coord of first item */ , ++ const coord_t * p2 /* coord of second item */ ) ++{ ++ reiser4_key k1; ++ reiser4_key k2; ++ ++ assert("nikita-1339", p1 != NULL); ++ assert("nikita-1340", p2 != NULL); ++ ++ return ++ (item_plugin_by_coord(p1) == item_plugin_by_coord(p2)) && ++ (extract_dir_id_from_key(item_key_by_coord(p1, &k1)) == ++ extract_dir_id_from_key(item_key_by_coord(p2, &k2))); ++ ++} ++ ++/* ->max_key_inside() method for this item plugin. */ ++reiser4_key *max_key_inside_cde(const coord_t * coord /* coord of item */ , ++ reiser4_key * result /* resulting key */ ) ++{ ++ assert("nikita-1342", coord != NULL); ++ ++ item_key_by_coord(coord, result); ++ set_key_ordering(result, get_key_ordering(reiser4_max_key())); ++ set_key_fulloid(result, get_key_fulloid(reiser4_max_key())); ++ set_key_offset(result, get_key_offset(reiser4_max_key())); ++ return result; ++} ++ ++/* @data contains data which are to be put into tree */ ++int can_contain_key_cde(const coord_t * coord /* coord of item */ , ++ const reiser4_key * key /* key to check */ , ++ const reiser4_item_data * data /* parameters of new ++ * item/unit being ++ * created */ ) ++{ ++ reiser4_key item_key; ++ ++ /* FIXME-VS: do not rely on anything but iplug field of @data. Only ++ data->iplug is initialized */ ++ assert("vs-457", data && data->iplug); ++/* assert( "vs-553", data -> user == 0 );*/ ++ item_key_by_coord(coord, &item_key); ++ ++ return (item_plugin_by_coord(coord) == data->iplug) && ++ (extract_dir_id_from_key(&item_key) == ++ extract_dir_id_from_key(key)); ++} ++ ++#if REISER4_DEBUG ++/* cde_check ->check() method for compressed directory items ++ ++ used for debugging, every item should have here the most complete ++ possible check of the consistency of the item that the inventor can ++ construct ++*/ ++int reiser4_check_cde(const coord_t * coord /* coord of item to check */, ++ const char **error /* where to store error message */) ++{ ++ int i; ++ int result; ++ char *item_start; ++ char *item_end; ++ reiser4_key key; ++ ++ coord_t c; ++ ++ assert("nikita-1357", coord != NULL); ++ assert("nikita-1358", error != NULL); ++ ++ if (!ergo(coord->item_pos != 0, ++ is_dot_key(item_key_by_coord(coord, &key)))) { ++ *error = "CDE doesn't start with dot"; ++ return -1; ++ } ++ item_start = item_body_by_coord(coord); ++ item_end = item_start + item_length_by_coord(coord); ++ ++ coord_dup(&c, coord); ++ result = 0; ++ for (i = 0; i < units(coord); ++i) { ++ directory_entry_format *entry; ++ ++ if ((char *)(header_at(coord, i) + 1) > ++ item_end - units(coord) * sizeof *entry) { ++ *error = "CDE header is out of bounds"; ++ result = -1; ++ break; ++ } ++ entry = entry_at(coord, i); ++ if ((char *)entry < item_start + sizeof(cde_item_format)) { ++ *error = "CDE header is too low"; ++ result = -1; ++ break; ++ } ++ if ((char *)(entry + 1) > item_end) { ++ *error = "CDE header is too high"; ++ result = -1; ++ break; ++ } ++ } ++ ++ return result; ++} ++#endif ++ ++/* ->init() method for this item plugin. */ ++int init_cde(coord_t * coord /* coord of item */ , ++ coord_t * from UNUSED_ARG, reiser4_item_data * data /* structure used for insertion */ ++ UNUSED_ARG) ++{ ++ put_unaligned(cpu_to_le16(0), &formatted_at(coord)->num_of_entries); ++ return 0; ++} ++ ++/* ->lookup() method for this item plugin. */ ++lookup_result lookup_cde(const reiser4_key * key /* key to search for */ , ++ lookup_bias bias /* search bias */ , ++ coord_t * coord /* coord of item to lookup in */ ) ++{ ++ cmp_t last_comp; ++ int pos; ++ ++ reiser4_key utmost_key; ++ ++ assert("nikita-1293", coord != NULL); ++ assert("nikita-1294", key != NULL); ++ ++ CHECKME(coord); ++ ++ if (keygt(item_key_by_coord(coord, &utmost_key), key)) { ++ coord->unit_pos = 0; ++ coord->between = BEFORE_UNIT; ++ return CBK_COORD_NOTFOUND; ++ } ++ pos = find(coord, key, &last_comp); ++ if (pos >= 0) { ++ coord->unit_pos = (int)pos; ++ switch (last_comp) { ++ case EQUAL_TO: ++ coord->between = AT_UNIT; ++ return CBK_COORD_FOUND; ++ case GREATER_THAN: ++ coord->between = BEFORE_UNIT; ++ return RETERR(-ENOENT); ++ case LESS_THAN: ++ default: ++ impossible("nikita-1298", "Broken find"); ++ return RETERR(-EIO); ++ } ++ } else { ++ coord->unit_pos = units(coord) - 1; ++ coord->between = AFTER_UNIT; ++ return (bias == ++ FIND_MAX_NOT_MORE_THAN) ? CBK_COORD_FOUND : ++ CBK_COORD_NOTFOUND; ++ } ++} ++ ++/* ->paste() method for this item plugin. */ ++int paste_cde(coord_t * coord /* coord of item */ , ++ reiser4_item_data * data /* parameters of new unit being ++ * inserted */ , ++ carry_plugin_info * info UNUSED_ARG /* todo carry queue */ ) ++{ ++ struct cde_entry_data *e; ++ int result; ++ int i; ++ ++ CHECKME(coord); ++ e = (struct cde_entry_data *) data->data; ++ ++ result = 0; ++ for (i = 0; i < e->num_of_entries; ++i) { ++ int pos; ++ int phantom_size; ++ ++ phantom_size = data->length; ++ if (units(coord) == 0) ++ phantom_size -= sizeof(cde_item_format); ++ ++ result = ++ expand(coord, e->entry + i, phantom_size, &pos, data->arg); ++ if (result != 0) ++ break; ++ result = paste_entry(coord, e->entry + i, pos, data->arg); ++ if (result != 0) ++ break; ++ } ++ CHECKME(coord); ++ return result; ++} ++ ++/* amount of space occupied by all entries starting from @idx both headers and ++ bodies. */ ++static unsigned int part_size(const coord_t * coord /* coord of item */ , ++ int idx /* index of unit */ ) ++{ ++ assert("nikita-1299", coord != NULL); ++ assert("nikita-1300", idx < (int)units(coord)); ++ ++ return sizeof(cde_item_format) + ++ (idx + 1) * sizeof(cde_unit_header) + offset_of(coord, ++ idx + 1) - ++ offset_of(coord, 0); ++} ++ ++/* how many but not more than @want units of @source can be merged with ++ item in @target node. If pend == append - we try to append last item ++ of @target by first units of @source. If pend == prepend - we try to ++ "prepend" first item in @target by last units of @source. @target ++ node has @free_space bytes of free space. Total size of those units ++ are returned via @size */ ++int can_shift_cde(unsigned free_space /* free space in item */ , ++ coord_t * coord /* coord of source item */ , ++ znode * target /* target node */ , ++ shift_direction pend /* shift direction */ , ++ unsigned *size /* resulting number of shifted bytes */ , ++ unsigned want /* maximal number of bytes to shift */ ) ++{ ++ int shift; ++ ++ CHECKME(coord); ++ if (want == 0) { ++ *size = 0; ++ return 0; ++ } ++ ++ /* pend == SHIFT_LEFT <==> shifting to the left */ ++ if (pend == SHIFT_LEFT) { ++ for (shift = min((int)want - 1, units(coord)); shift >= 0; ++ --shift) { ++ *size = part_size(coord, shift); ++ if (target != NULL) ++ *size -= sizeof(cde_item_format); ++ if (*size <= free_space) ++ break; ++ } ++ shift = shift + 1; ++ } else { ++ int total_size; ++ ++ assert("nikita-1301", pend == SHIFT_RIGHT); ++ ++ total_size = item_length_by_coord(coord); ++ for (shift = units(coord) - want - 1; shift < units(coord) - 1; ++ ++shift) { ++ *size = total_size - part_size(coord, shift); ++ if (target == NULL) ++ *size += sizeof(cde_item_format); ++ if (*size <= free_space) ++ break; ++ } ++ shift = units(coord) - shift - 1; ++ } ++ if (shift == 0) ++ *size = 0; ++ CHECKME(coord); ++ return shift; ++} ++ ++/* ->copy_units() method for this item plugin. */ ++void copy_units_cde(coord_t * target /* coord of target item */ , ++ coord_t * source /* coord of source item */ , ++ unsigned from /* starting unit */ , ++ unsigned count /* how many units to copy */ , ++ shift_direction where_is_free_space /* shift direction */ , ++ unsigned free_space /* free space in item */ ) ++{ ++ char *header_from; ++ char *header_to; ++ ++ char *entry_from; ++ char *entry_to; ++ ++ int pos_in_target; ++ int data_size; ++ int data_delta; ++ int i; ++ ++ assert("nikita-1303", target != NULL); ++ assert("nikita-1304", source != NULL); ++ assert("nikita-1305", (int)from < units(source)); ++ assert("nikita-1307", (int)(from + count) <= units(source)); ++ ++ if (where_is_free_space == SHIFT_LEFT) { ++ assert("nikita-1453", from == 0); ++ pos_in_target = units(target); ++ } else { ++ assert("nikita-1309", (int)(from + count) == units(source)); ++ pos_in_target = 0; ++ memmove(item_body_by_coord(target), ++ (char *)item_body_by_coord(target) + free_space, ++ item_length_by_coord(target) - free_space); ++ } ++ ++ CHECKME(target); ++ CHECKME(source); ++ ++ /* expand @target */ ++ data_size = ++ offset_of(source, (int)(from + count)) - offset_of(source, ++ (int)from); ++ ++ if (units(target) == 0) ++ free_space -= sizeof(cde_item_format); ++ ++ expand_item(target, pos_in_target, (int)count, ++ (int)(item_length_by_coord(target) - free_space), ++ (unsigned)data_size); ++ ++ /* copy first @count units of @source into @target */ ++ data_delta = ++ offset_of(target, pos_in_target) - offset_of(source, (int)from); ++ ++ /* copy entries */ ++ entry_from = (char *)entry_at(source, (int)from); ++ entry_to = (char *)entry_at(source, (int)(from + count)); ++ memmove(entry_at(target, pos_in_target), entry_from, ++ (unsigned)(entry_to - entry_from)); ++ ++ /* copy headers */ ++ header_from = (char *)header_at(source, (int)from); ++ header_to = (char *)header_at(source, (int)(from + count)); ++ memmove(header_at(target, pos_in_target), header_from, ++ (unsigned)(header_to - header_from)); ++ ++ /* update offsets */ ++ for (i = pos_in_target; i < (int)(pos_in_target + count); ++i) ++ adj_offset(target, i, data_delta); ++ CHECKME(target); ++ CHECKME(source); ++} ++ ++/* ->cut_units() method for this item plugin. */ ++int cut_units_cde(coord_t * coord /* coord of item */ , ++ pos_in_node_t from /* start unit pos */ , ++ pos_in_node_t to /* stop unit pos */ , ++ struct carry_cut_data *cdata UNUSED_ARG, ++ reiser4_key * smallest_removed, reiser4_key * new_first) ++{ ++ char *header_from; ++ char *header_to; ++ ++ char *entry_from; ++ char *entry_to; ++ ++ int size; ++ int entry_delta; ++ int header_delta; ++ int i; ++ ++ unsigned count; ++ ++ CHECKME(coord); ++ ++ count = to - from + 1; ++ ++ assert("nikita-1454", coord != NULL); ++ assert("nikita-1455", (int)(from + count) <= units(coord)); ++ ++ if (smallest_removed) ++ unit_key_by_coord(coord, smallest_removed); ++ ++ if (new_first) { ++ coord_t next; ++ ++ /* not everything is cut from item head */ ++ assert("vs-1527", from == 0); ++ assert("vs-1528", to < units(coord) - 1); ++ ++ coord_dup(&next, coord); ++ next.unit_pos++; ++ unit_key_by_coord(&next, new_first); ++ } ++ ++ size = item_length_by_coord(coord); ++ if (count == (unsigned)units(coord)) { ++ return size; ++ } ++ ++ header_from = (char *)header_at(coord, (int)from); ++ header_to = (char *)header_at(coord, (int)(from + count)); ++ ++ entry_from = (char *)entry_at(coord, (int)from); ++ entry_to = (char *)entry_at(coord, (int)(from + count)); ++ ++ /* move headers */ ++ memmove(header_from, header_to, ++ (unsigned)(address(coord, size) - header_to)); ++ ++ header_delta = header_to - header_from; ++ ++ entry_from -= header_delta; ++ entry_to -= header_delta; ++ size -= header_delta; ++ ++ /* copy entries */ ++ memmove(entry_from, entry_to, ++ (unsigned)(address(coord, size) - entry_to)); ++ ++ entry_delta = entry_to - entry_from; ++ size -= entry_delta; ++ ++ /* update offsets */ ++ ++ for (i = 0; i < (int)from; ++i) ++ adj_offset(coord, i, -header_delta); ++ ++ for (i = from; i < units(coord) - (int)count; ++i) ++ adj_offset(coord, i, -header_delta - entry_delta); ++ ++ put_unaligned(cpu_to_le16((__u16) units(coord) - count), ++ &formatted_at(coord)->num_of_entries); ++ ++ if (from == 0) { ++ /* entries from head was removed - move remaining to right */ ++ memmove((char *)item_body_by_coord(coord) + ++ header_delta + entry_delta, item_body_by_coord(coord), ++ (unsigned)size); ++ if (REISER4_DEBUG) ++ memset(item_body_by_coord(coord), 0, ++ (unsigned)header_delta + entry_delta); ++ } else { ++ /* freed space is already at the end of item */ ++ if (REISER4_DEBUG) ++ memset((char *)item_body_by_coord(coord) + size, 0, ++ (unsigned)header_delta + entry_delta); ++ } ++ ++ return header_delta + entry_delta; ++} ++ ++int kill_units_cde(coord_t * coord /* coord of item */ , ++ pos_in_node_t from /* start unit pos */ , ++ pos_in_node_t to /* stop unit pos */ , ++ struct carry_kill_data *kdata UNUSED_ARG, ++ reiser4_key * smallest_removed, reiser4_key * new_first) ++{ ++ return cut_units_cde(coord, from, to, NULL, smallest_removed, new_first); ++} ++ ++/* ->s.dir.extract_key() method for this item plugin. */ ++int extract_key_cde(const coord_t * coord /* coord of item */ , ++ reiser4_key * key /* resulting key */ ) ++{ ++ directory_entry_format *dent; ++ ++ assert("nikita-1155", coord != NULL); ++ assert("nikita-1156", key != NULL); ++ ++ dent = entry_at(coord, idx_of(coord)); ++ return extract_key_from_id(&dent->id, key); ++} ++ ++int ++update_key_cde(const coord_t * coord, const reiser4_key * key, ++ lock_handle * lh UNUSED_ARG) ++{ ++ directory_entry_format *dent; ++ obj_key_id obj_id; ++ int result; ++ ++ assert("nikita-2344", coord != NULL); ++ assert("nikita-2345", key != NULL); ++ ++ dent = entry_at(coord, idx_of(coord)); ++ result = build_obj_key_id(key, &obj_id); ++ if (result == 0) { ++ dent->id = obj_id; ++ znode_make_dirty(coord->node); ++ } ++ return 0; ++} ++ ++/* ->s.dir.extract_name() method for this item plugin. */ ++char *extract_name_cde(const coord_t * coord /* coord of item */ , char *buf) ++{ ++ directory_entry_format *dent; ++ ++ assert("nikita-1157", coord != NULL); ++ ++ dent = entry_at(coord, idx_of(coord)); ++ return extract_dent_name(coord, dent, buf); ++} ++ ++static int cde_bytes(int pasting, const reiser4_item_data * data) ++{ ++ int result; ++ ++ result = data->length; ++ if (!pasting) ++ result -= sizeof(cde_item_format); ++ return result; ++} ++ ++/* ->s.dir.add_entry() method for this item plugin */ ++int add_entry_cde(struct inode *dir /* directory object */ , ++ coord_t * coord /* coord of item */ , ++ lock_handle * lh /* lock handle for insertion */ , ++ const struct dentry *name /* name to insert */ , ++ reiser4_dir_entry_desc * dir_entry /* parameters of new ++ * directory entry */ ) ++{ ++ reiser4_item_data data; ++ struct cde_entry entry; ++ struct cde_entry_data edata; ++ int result; ++ ++ assert("nikita-1656", coord->node == lh->node); ++ assert("nikita-1657", znode_is_write_locked(coord->node)); ++ ++ edata.num_of_entries = 1; ++ edata.entry = &entry; ++ ++ entry.dir = dir; ++ entry.obj = dir_entry->obj; ++ entry.name = &name->d_name; ++ ++ data.data = (char *)&edata; ++ data.user = 0; /* &edata is not user space */ ++ data.iplug = item_plugin_by_id(COMPOUND_DIR_ID); ++ data.arg = dir_entry; ++ assert("nikita-1302", data.iplug != NULL); ++ ++ result = is_dot_key(&dir_entry->key); ++ data.length = estimate_cde(result ? coord : NULL, &data); ++ ++ /* NOTE-NIKITA quota plugin? */ ++ if (vfs_dq_alloc_space_nodirty(dir, cde_bytes(result, &data))) ++ return RETERR(-EDQUOT); ++ ++ if (result) ++ result = insert_by_coord(coord, &data, &dir_entry->key, lh, 0); ++ else ++ result = reiser4_resize_item(coord, &data, &dir_entry->key, ++ lh, 0); ++ return result; ++} ++ ++/* ->s.dir.rem_entry() */ ++int rem_entry_cde(struct inode *dir /* directory of item */ , ++ const struct qstr *name, coord_t * coord /* coord of item */ , ++ lock_handle * lh UNUSED_ARG /* lock handle for ++ * removal */ , ++ reiser4_dir_entry_desc * entry UNUSED_ARG /* parameters of ++ * directory entry ++ * being removed */ ) ++{ ++ coord_t shadow; ++ int result; ++ int length; ++ ON_DEBUG(char buf[DE_NAME_BUF_LEN]); ++ ++ assert("nikita-2870", strlen(name->name) == name->len); ++ assert("nikita-2869", ++ !strcmp(name->name, extract_name_cde(coord, buf))); ++ ++ length = sizeof(directory_entry_format) + sizeof(cde_unit_header); ++ if (is_longname(name->name, name->len)) ++ length += name->len + 1; ++ ++ if (inode_get_bytes(dir) < length) { ++ warning("nikita-2628", "Dir is broke: %llu: %llu", ++ (unsigned long long)get_inode_oid(dir), ++ inode_get_bytes(dir)); ++ ++ return RETERR(-EIO); ++ } ++ ++ /* cut_node() is supposed to take pointers to _different_ ++ coords, because it will modify them without respect to ++ possible aliasing. To work around this, create temporary copy ++ of @coord. ++ */ ++ coord_dup(&shadow, coord); ++ result = ++ kill_node_content(coord, &shadow, NULL, NULL, NULL, NULL, NULL, 0); ++ if (result == 0) { ++ /* NOTE-NIKITA quota plugin? */ ++ vfs_dq_free_space_nodirty(dir, length); ++ } ++ return result; ++} ++ ++/* ->s.dir.max_name_len() method for this item plugin */ ++int max_name_len_cde(const struct inode *dir /* directory */ ) ++{ ++ return ++ reiser4_tree_by_inode(dir)->nplug->max_item_size() - ++ sizeof(directory_entry_format) - sizeof(cde_item_format) - ++ sizeof(cde_unit_header) - 2; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/cde.h linux-2.6.30/fs/reiser4/plugin/item/cde.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/cde.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/cde.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,87 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Compound directory item. See cde.c for description. */ ++ ++#if !defined( __FS_REISER4_PLUGIN_COMPRESSED_DE_H__ ) ++#define __FS_REISER4_PLUGIN_COMPRESSED_DE_H__ ++ ++#include "../../forward.h" ++#include "../../kassign.h" ++#include "../../dformat.h" ++ ++#include <linux/fs.h> /* for struct inode */ ++#include <linux/dcache.h> /* for struct dentry, etc */ ++ ++typedef struct cde_unit_header { ++ de_id hash; ++ d16 offset; ++} cde_unit_header; ++ ++typedef struct cde_item_format { ++ d16 num_of_entries; ++ cde_unit_header entry[0]; ++} cde_item_format; ++ ++struct cde_entry { ++ const struct inode *dir; ++ const struct inode *obj; ++ const struct qstr *name; ++}; ++ ++struct cde_entry_data { ++ int num_of_entries; ++ struct cde_entry *entry; ++}; ++ ++/* plugin->item.b.* */ ++reiser4_key *max_key_inside_cde(const coord_t * coord, reiser4_key * result); ++int can_contain_key_cde(const coord_t * coord, const reiser4_key * key, ++ const reiser4_item_data *); ++int mergeable_cde(const coord_t * p1, const coord_t * p2); ++pos_in_node_t nr_units_cde(const coord_t * coord); ++reiser4_key *unit_key_cde(const coord_t * coord, reiser4_key * key); ++int estimate_cde(const coord_t * coord, const reiser4_item_data * data); ++void print_cde(const char *prefix, coord_t * coord); ++int init_cde(coord_t * coord, coord_t * from, reiser4_item_data * data); ++lookup_result lookup_cde(const reiser4_key * key, lookup_bias bias, ++ coord_t * coord); ++int paste_cde(coord_t * coord, reiser4_item_data * data, ++ carry_plugin_info * info UNUSED_ARG); ++int can_shift_cde(unsigned free_space, coord_t * coord, znode * target, ++ shift_direction pend, unsigned *size, unsigned want); ++void copy_units_cde(coord_t * target, coord_t * source, unsigned from, ++ unsigned count, shift_direction where_is_free_space, ++ unsigned free_space); ++int cut_units_cde(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ struct carry_cut_data *, reiser4_key * smallest_removed, ++ reiser4_key * new_first); ++int kill_units_cde(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ struct carry_kill_data *, reiser4_key * smallest_removed, ++ reiser4_key * new_first); ++void print_cde(const char *prefix, coord_t * coord); ++int reiser4_check_cde(const coord_t * coord, const char **error); ++ ++/* plugin->u.item.s.dir.* */ ++int extract_key_cde(const coord_t * coord, reiser4_key * key); ++int update_key_cde(const coord_t * coord, const reiser4_key * key, ++ lock_handle * lh); ++char *extract_name_cde(const coord_t * coord, char *buf); ++int add_entry_cde(struct inode *dir, coord_t * coord, ++ lock_handle * lh, const struct dentry *name, ++ reiser4_dir_entry_desc * entry); ++int rem_entry_cde(struct inode *dir, const struct qstr *name, coord_t * coord, ++ lock_handle * lh, reiser4_dir_entry_desc * entry); ++int max_name_len_cde(const struct inode *dir); ++ ++/* __FS_REISER4_PLUGIN_COMPRESSED_DE_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/ctail.c linux-2.6.30/fs/reiser4/plugin/item/ctail.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/ctail.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/ctail.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1613 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* ctails (aka "clustered tails") are items for cryptcompress objects */ ++ ++/* DESCRIPTION: ++ ++Each cryptcompress object is stored on disk as a set of clusters sliced ++into ctails. ++ ++Internal on-disk structure: ++ ++ HEADER (1) Here stored disk cluster shift ++ BODY ++*/ ++ ++#include "../../forward.h" ++#include "../../debug.h" ++#include "../../dformat.h" ++#include "../../kassign.h" ++#include "../../key.h" ++#include "../../coord.h" ++#include "item.h" ++#include "../node/node.h" ++#include "../plugin.h" ++#include "../object.h" ++#include "../../znode.h" ++#include "../../carry.h" ++#include "../../tree.h" ++#include "../../inode.h" ++#include "../../super.h" ++#include "../../context.h" ++#include "../../page_cache.h" ++#include "../cluster.h" ++#include "../../flush.h" ++#include "../../tree_walk.h" ++ ++#include <linux/pagevec.h> ++#include <linux/swap.h> ++#include <linux/fs.h> ++ ++/* return body of ctail item at @coord */ ++static ctail_item_format *ctail_formatted_at(const coord_t * coord) ++{ ++ assert("edward-60", coord != NULL); ++ return item_body_by_coord(coord); ++} ++ ++static int cluster_shift_by_coord(const coord_t * coord) ++{ ++ return get_unaligned(&ctail_formatted_at(coord)->cluster_shift); ++} ++ ++static inline void dclust_set_extension_shift(hint_t * hint) ++{ ++ assert("edward-1270", ++ item_id_by_coord(&hint->ext_coord.coord) == CTAIL_ID); ++ hint->ext_coord.extension.ctail.shift = ++ cluster_shift_by_coord(&hint->ext_coord.coord); ++} ++ ++static loff_t off_by_coord(const coord_t * coord) ++{ ++ reiser4_key key; ++ return get_key_offset(item_key_by_coord(coord, &key)); ++} ++ ++int coord_is_unprepped_ctail(const coord_t * coord) ++{ ++ assert("edward-1233", coord != NULL); ++ assert("edward-1234", item_id_by_coord(coord) == CTAIL_ID); ++ assert("edward-1235", ++ ergo((int)cluster_shift_by_coord(coord) == (int)UCTAIL_SHIFT, ++ nr_units_ctail(coord) == (pos_in_node_t) UCTAIL_NR_UNITS)); ++ ++ return (int)cluster_shift_by_coord(coord) == (int)UCTAIL_SHIFT; ++} ++ ++static cloff_t clust_by_coord(const coord_t * coord, struct inode *inode) ++{ ++ int shift; ++ ++ if (inode != NULL) { ++ shift = inode_cluster_shift(inode); ++ assert("edward-1236", ++ ergo(!coord_is_unprepped_ctail(coord), ++ shift == cluster_shift_by_coord(coord))); ++ } else { ++ assert("edward-1237", !coord_is_unprepped_ctail(coord)); ++ shift = cluster_shift_by_coord(coord); ++ } ++ return off_by_coord(coord) >> shift; ++} ++ ++static int disk_cluster_size(const coord_t * coord) ++{ ++ assert("edward-1156", ++ item_plugin_by_coord(coord) == item_plugin_by_id(CTAIL_ID)); ++ /* calculation of disk cluster size ++ is meaninless if ctail is unprepped */ ++ assert("edward-1238", !coord_is_unprepped_ctail(coord)); ++ ++ return 1 << cluster_shift_by_coord(coord); ++} ++ ++/* true if the key is of first disk cluster item */ ++static int is_disk_cluster_key(const reiser4_key * key, const coord_t * coord) ++{ ++ assert("edward-1239", item_id_by_coord(coord) == CTAIL_ID); ++ ++ return coord_is_unprepped_ctail(coord) || ++ ((get_key_offset(key) & ++ ((loff_t) disk_cluster_size(coord) - 1)) == 0); ++} ++ ++static char *first_unit(coord_t * coord) ++{ ++ /* FIXME: warning: pointer of type `void *' used in arithmetic */ ++ return (char *)item_body_by_coord(coord) + sizeof(ctail_item_format); ++} ++ ++/* plugin->u.item.b.max_key_inside : ++ tail_max_key_inside */ ++ ++/* plugin->u.item.b.can_contain_key */ ++int ++can_contain_key_ctail(const coord_t * coord, const reiser4_key * key, ++ const reiser4_item_data * data) ++{ ++ reiser4_key item_key; ++ ++ if (item_plugin_by_coord(coord) != data->iplug) ++ return 0; ++ ++ item_key_by_coord(coord, &item_key); ++ if (get_key_locality(key) != get_key_locality(&item_key) || ++ get_key_objectid(key) != get_key_objectid(&item_key)) ++ return 0; ++ if (get_key_offset(&item_key) + nr_units_ctail(coord) != ++ get_key_offset(key)) ++ return 0; ++ if (is_disk_cluster_key(key, coord)) ++ return 0; ++ return 1; ++} ++ ++/* plugin->u.item.b.mergeable */ ++int mergeable_ctail(const coord_t * p1, const coord_t * p2) ++{ ++ reiser4_key key1, key2; ++ ++ assert("edward-62", item_id_by_coord(p1) == CTAIL_ID); ++ assert("edward-61", plugin_of_group(item_plugin_by_coord(p1), ++ UNIX_FILE_METADATA_ITEM_TYPE)); ++ ++ if (item_id_by_coord(p2) != CTAIL_ID) { ++ /* second item is of another type */ ++ return 0; ++ } ++ ++ item_key_by_coord(p1, &key1); ++ item_key_by_coord(p2, &key2); ++ if (get_key_locality(&key1) != get_key_locality(&key2) || ++ get_key_objectid(&key1) != get_key_objectid(&key2) || ++ get_key_type(&key1) != get_key_type(&key2)) { ++ /* items of different objects */ ++ return 0; ++ } ++ if (get_key_offset(&key1) + nr_units_ctail(p1) != get_key_offset(&key2)) ++ /* not adjacent items */ ++ return 0; ++ if (is_disk_cluster_key(&key2, p2)) ++ return 0; ++ return 1; ++} ++ ++/* plugin->u.item.b.nr_units */ ++pos_in_node_t nr_units_ctail(const coord_t * coord) ++{ ++ return (item_length_by_coord(coord) - ++ sizeof(ctail_formatted_at(coord)->cluster_shift)); ++} ++ ++/* plugin->u.item.b.estimate: ++ estimate how much space is needed to insert/paste @data->length bytes ++ into ctail at @coord */ ++int estimate_ctail(const coord_t * coord /* coord of item */ , ++ const reiser4_item_data * ++ data /* parameters for new item */ ) ++{ ++ if (coord == NULL) ++ /* insert */ ++ return (sizeof(ctail_item_format) + data->length); ++ else ++ /* paste */ ++ return data->length; ++} ++ ++/* ->init() method for this item plugin. */ ++int init_ctail(coord_t * to /* coord of item */ , ++ coord_t * from /* old_item */ , ++ reiser4_item_data * data /* structure used for insertion */ ) ++{ ++ int cluster_shift; /* cpu value to convert */ ++ ++ if (data) { ++ assert("edward-463", data->length > sizeof(ctail_item_format)); ++ cluster_shift = *((int *)(data->arg)); ++ data->length -= sizeof(ctail_item_format); ++ } else { ++ assert("edward-464", from != NULL); ++ assert("edward-855", ctail_ok(from)); ++ cluster_shift = (int)(cluster_shift_by_coord(from)); ++ } ++ put_unaligned((d8)cluster_shift, &ctail_formatted_at(to)->cluster_shift); ++ assert("edward-856", ctail_ok(to)); ++ return 0; ++} ++ ++/* plugin->u.item.b.lookup: ++ NULL: We are looking for item keys only */ ++ ++#if REISER4_DEBUG ++int ctail_ok(const coord_t * coord) ++{ ++ return coord_is_unprepped_ctail(coord) || ++ cluster_shift_ok(cluster_shift_by_coord(coord)); ++} ++ ++/* plugin->u.item.b.check */ ++int check_ctail(const coord_t * coord, const char **error) ++{ ++ if (!ctail_ok(coord)) { ++ if (error) ++ *error = "bad cluster shift in ctail"; ++ return 1; ++ } ++ return 0; ++} ++#endif ++ ++/* plugin->u.item.b.paste */ ++int ++paste_ctail(coord_t * coord, reiser4_item_data * data, ++ carry_plugin_info * info UNUSED_ARG) ++{ ++ unsigned old_nr_units; ++ ++ assert("edward-268", data->data != NULL); ++ /* copy only from kernel space */ ++ assert("edward-66", data->user == 0); ++ ++ old_nr_units = ++ item_length_by_coord(coord) - sizeof(ctail_item_format) - ++ data->length; ++ ++ /* ctail items never get pasted in the middle */ ++ ++ if (coord->unit_pos == 0 && coord->between == AT_UNIT) { ++ ++ /* paste at the beginning when create new item */ ++ assert("edward-450", ++ item_length_by_coord(coord) == ++ data->length + sizeof(ctail_item_format)); ++ assert("edward-451", old_nr_units == 0); ++ } else if (coord->unit_pos == old_nr_units - 1 ++ && coord->between == AFTER_UNIT) { ++ ++ /* paste at the end */ ++ coord->unit_pos++; ++ } else ++ impossible("edward-453", "bad paste position"); ++ ++ memcpy(first_unit(coord) + coord->unit_pos, data->data, data->length); ++ ++ assert("edward-857", ctail_ok(coord)); ++ ++ return 0; ++} ++ ++/* plugin->u.item.b.fast_paste */ ++ ++/* plugin->u.item.b.can_shift ++ number of units is returned via return value, number of bytes via @size. For ++ ctail items they coincide */ ++int ++can_shift_ctail(unsigned free_space, coord_t * source, ++ znode * target, shift_direction direction UNUSED_ARG, ++ unsigned *size /* number of bytes */ , unsigned want) ++{ ++ /* make sure that that we do not want to shift more than we have */ ++ assert("edward-68", want > 0 && want <= nr_units_ctail(source)); ++ ++ *size = min(want, free_space); ++ ++ if (!target) { ++ /* new item will be created */ ++ if (*size <= sizeof(ctail_item_format)) { ++ *size = 0; ++ return 0; ++ } ++ return *size - sizeof(ctail_item_format); ++ } ++ return *size; ++} ++ ++/* plugin->u.item.b.copy_units ++ cooperates with ->can_shift() */ ++void ++copy_units_ctail(coord_t * target, coord_t * source, ++ unsigned from, unsigned count /* units */ , ++ shift_direction where_is_free_space, ++ unsigned free_space /* bytes */ ) ++{ ++ /* make sure that item @target is expanded already */ ++ assert("edward-69", (unsigned)item_length_by_coord(target) >= count); ++ assert("edward-70", free_space == count || free_space == count + 1); ++ ++ assert("edward-858", ctail_ok(source)); ++ ++ if (where_is_free_space == SHIFT_LEFT) { ++ /* append item @target with @count first bytes of @source: ++ this restriction came from ordinary tails */ ++ assert("edward-71", from == 0); ++ assert("edward-860", ctail_ok(target)); ++ ++ memcpy(first_unit(target) + nr_units_ctail(target) - count, ++ first_unit(source), count); ++ } else { ++ /* target item is moved to right already */ ++ reiser4_key key; ++ ++ assert("edward-72", nr_units_ctail(source) == from + count); ++ ++ if (free_space == count) { ++ init_ctail(target, source, NULL); ++ } else { ++ /* new item has been created */ ++ assert("edward-862", ctail_ok(target)); ++ } ++ memcpy(first_unit(target), first_unit(source) + from, count); ++ ++ assert("edward-863", ctail_ok(target)); ++ ++ /* new units are inserted before first unit in an item, ++ therefore, we have to update item key */ ++ item_key_by_coord(source, &key); ++ set_key_offset(&key, get_key_offset(&key) + from); ++ ++ node_plugin_by_node(target->node)->update_item_key(target, &key, ++ NULL /*info */); ++ } ++} ++ ++/* plugin->u.item.b.create_hook */ ++int create_hook_ctail(const coord_t * coord, void *arg) ++{ ++ assert("edward-864", znode_is_loaded(coord->node)); ++ ++ znode_set_convertible(coord->node); ++ return 0; ++} ++ ++/* plugin->u.item.b.kill_hook */ ++int kill_hook_ctail(const coord_t * coord, pos_in_node_t from, ++ pos_in_node_t count, carry_kill_data * kdata) ++{ ++ struct inode *inode; ++ ++ assert("edward-1157", item_id_by_coord(coord) == CTAIL_ID); ++ assert("edward-291", znode_is_write_locked(coord->node)); ++ ++ inode = kdata->inode; ++ if (inode) { ++ reiser4_key key; ++ struct cryptcompress_info * info; ++ cloff_t index; ++ ++ item_key_by_coord(coord, &key); ++ info = cryptcompress_inode_data(inode); ++ index = off_to_clust(get_key_offset(&key), inode); ++ ++ if (from == 0) { ++ info->trunc_index = index; ++ if (is_disk_cluster_key(&key, coord)) { ++ /* ++ * first item of disk cluster is to be killed ++ */ ++ truncate_complete_page_cluster( ++ inode, index, kdata->params.truncate); ++ inode_sub_bytes(inode, ++ inode_cluster_size(inode)); ++ } ++ } ++ } ++ return 0; ++} ++ ++/* for shift_hook_ctail(), ++ return true if the first disk cluster item has dirty child ++*/ ++static int ctail_convertible(const coord_t * coord) ++{ ++ int result; ++ reiser4_key key; ++ jnode *child = NULL; ++ ++ assert("edward-477", coord != NULL); ++ assert("edward-478", item_id_by_coord(coord) == CTAIL_ID); ++ ++ if (coord_is_unprepped_ctail(coord)) ++ /* unprepped ctail should be converted */ ++ return 1; ++ ++ item_key_by_coord(coord, &key); ++ child = jlookup(current_tree, ++ get_key_objectid(&key), ++ off_to_pg(off_by_coord(coord))); ++ if (!child) ++ return 0; ++ result = JF_ISSET(child, JNODE_DIRTY); ++ jput(child); ++ return result; ++} ++ ++/* FIXME-EDWARD */ ++/* plugin->u.item.b.shift_hook */ ++int shift_hook_ctail(const coord_t * item /* coord of item */ , ++ unsigned from UNUSED_ARG /* start unit */ , ++ unsigned count UNUSED_ARG /* stop unit */ , ++ znode * old_node /* old parent */ ) ++{ ++ assert("edward-479", item != NULL); ++ assert("edward-480", item->node != old_node); ++ ++ if (!znode_convertible(old_node) || znode_convertible(item->node)) ++ return 0; ++ if (ctail_convertible(item)) ++ znode_set_convertible(item->node); ++ return 0; ++} ++ ++static int ++cut_or_kill_ctail_units(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ int cut, void *p, reiser4_key * smallest_removed, ++ reiser4_key * new_first) ++{ ++ pos_in_node_t count; /* number of units to cut */ ++ char *item; ++ ++ count = to - from + 1; ++ item = item_body_by_coord(coord); ++ ++ assert("edward-74", ergo(from != 0, to == coord_last_unit_pos(coord))); ++ ++ if (smallest_removed) { ++ /* store smallest key removed */ ++ item_key_by_coord(coord, smallest_removed); ++ set_key_offset(smallest_removed, ++ get_key_offset(smallest_removed) + from); ++ } ++ ++ if (new_first) { ++ assert("vs-1531", from == 0); ++ ++ item_key_by_coord(coord, new_first); ++ set_key_offset(new_first, ++ get_key_offset(new_first) + from + count); ++ } ++ ++ if (!cut) ++ kill_hook_ctail(coord, from, 0, (struct carry_kill_data *)p); ++ ++ if (from == 0) { ++ if (count != nr_units_ctail(coord)) { ++ /* part of item is removed, so move free space at the beginning ++ of the item and update item key */ ++ reiser4_key key; ++ memcpy(item + to + 1, item, sizeof(ctail_item_format)); ++ item_key_by_coord(coord, &key); ++ set_key_offset(&key, get_key_offset(&key) + count); ++ node_plugin_by_node(coord->node)->update_item_key(coord, ++ &key, ++ NULL); ++ } else { ++ /* cut_units should not be called to cut evrything */ ++ assert("vs-1532", ergo(cut, 0)); ++ /* whole item is cut, so more then amount of space occupied ++ by units got freed */ ++ count += sizeof(ctail_item_format); ++ } ++ if (REISER4_DEBUG) ++ memset(item, 0, count); ++ } else if (REISER4_DEBUG) ++ memset(item + sizeof(ctail_item_format) + from, 0, count); ++ return count; ++} ++ ++/* plugin->u.item.b.cut_units */ ++int ++cut_units_ctail(coord_t * item, pos_in_node_t from, pos_in_node_t to, ++ carry_cut_data * cdata, reiser4_key * smallest_removed, ++ reiser4_key * new_first) ++{ ++ return cut_or_kill_ctail_units(item, from, to, 1, NULL, ++ smallest_removed, new_first); ++} ++ ++/* plugin->u.item.b.kill_units */ ++int ++kill_units_ctail(coord_t * item, pos_in_node_t from, pos_in_node_t to, ++ struct carry_kill_data *kdata, reiser4_key * smallest_removed, ++ reiser4_key * new_first) ++{ ++ return cut_or_kill_ctail_units(item, from, to, 0, kdata, ++ smallest_removed, new_first); ++} ++ ++/* plugin->u.item.s.file.read */ ++int read_ctail(struct file *file UNUSED_ARG, flow_t * f, hint_t * hint) ++{ ++ uf_coord_t *uf_coord; ++ coord_t *coord; ++ ++ uf_coord = &hint->ext_coord; ++ coord = &uf_coord->coord; ++ assert("edward-127", f->user == 0); ++ assert("edward-129", coord && coord->node); ++ assert("edward-130", coord_is_existing_unit(coord)); ++ assert("edward-132", znode_is_loaded(coord->node)); ++ ++ /* start read only from the beginning of ctail */ ++ assert("edward-133", coord->unit_pos == 0); ++ /* read only whole ctails */ ++ assert("edward-135", nr_units_ctail(coord) <= f->length); ++ ++ assert("edward-136", reiser4_schedulable()); ++ assert("edward-886", ctail_ok(coord)); ++ ++ if (f->data) ++ memcpy(f->data, (char *)first_unit(coord), ++ (size_t) nr_units_ctail(coord)); ++ ++ dclust_set_extension_shift(hint); ++ mark_page_accessed(znode_page(coord->node)); ++ move_flow_forward(f, nr_units_ctail(coord)); ++ ++ return 0; ++} ++ ++/** ++ * Prepare transform stream with plain text for page ++ * @page taking into account synchronization issues. ++ */ ++static int ctail_read_disk_cluster(struct cluster_handle * clust, ++ struct inode * inode, struct page * page, ++ znode_lock_mode mode) ++{ ++ int result; ++ ++ assert("edward-1450", mode == ZNODE_READ_LOCK || ZNODE_WRITE_LOCK); ++ assert("edward-671", clust->hint != NULL); ++ assert("edward-140", clust->dstat == INVAL_DISK_CLUSTER); ++ assert("edward-672", cryptcompress_inode_ok(inode)); ++ assert("edward-1527", PageLocked(page)); ++ ++ unlock_page(page); ++ ++ /* set input stream */ ++ result = grab_tfm_stream(inode, &clust->tc, INPUT_STREAM); ++ if (result) { ++ lock_page(page); ++ return result; ++ } ++ result = find_disk_cluster(clust, inode, 1 /* read items */, mode); ++ lock_page(page); ++ if (result) ++ return result; ++ /* ++ * at this point we have locked position in the tree ++ */ ++ assert("edward-1528", znode_is_any_locked(clust->hint->lh.node)); ++ ++ if (page->mapping != inode->i_mapping) { ++ /* page was truncated */ ++ reiser4_unset_hint(clust->hint); ++ reset_cluster_params(clust); ++ return AOP_TRUNCATED_PAGE; ++ } ++ if (PageUptodate(page)) { ++ /* disk cluster can be obsolete, don't use it! */ ++ reiser4_unset_hint(clust->hint); ++ reset_cluster_params(clust); ++ return 0; ++ } ++ if (clust->dstat == FAKE_DISK_CLUSTER || ++ clust->dstat == UNPR_DISK_CLUSTER || ++ clust->dstat == TRNC_DISK_CLUSTER) { ++ /* ++ * this information about disk cluster will be valid ++ * as long as we keep the position in the tree locked ++ */ ++ tfm_cluster_set_uptodate(&clust->tc); ++ return 0; ++ } ++ /* now prepare output stream.. */ ++ result = grab_coa(&clust->tc, inode_compression_plugin(inode)); ++ if (result) ++ return result; ++ /* ..and fill this with plain text */ ++ result = reiser4_inflate_cluster(clust, inode); ++ if (result) ++ return result; ++ /* ++ * The stream is ready! It won't be obsolete as ++ * long as we keep last disk cluster item locked. ++ */ ++ tfm_cluster_set_uptodate(&clust->tc); ++ return 0; ++} ++ ++/* ++ * fill one page with plain text. ++ */ ++int do_readpage_ctail(struct inode * inode, struct cluster_handle * clust, ++ struct page *page, znode_lock_mode mode) ++{ ++ int ret; ++ unsigned cloff; ++ char *data; ++ size_t to_page; ++ struct tfm_cluster * tc = &clust->tc; ++ ++ assert("edward-212", PageLocked(page)); ++ ++ if (unlikely(page->mapping != inode->i_mapping)) ++ return AOP_TRUNCATED_PAGE; ++ if (PageUptodate(page)) ++ goto exit; ++ to_page = pbytes(page_index(page), inode); ++ if (to_page == 0) { ++ zero_user(page, 0, PAGE_CACHE_SIZE); ++ SetPageUptodate(page); ++ goto exit; ++ } ++ if (!tfm_cluster_is_uptodate(&clust->tc)) { ++ clust->index = pg_to_clust(page->index, inode); ++ ++ /* this will unlock/lock the page */ ++ ret = ctail_read_disk_cluster(clust, inode, page, mode); ++ ++ assert("edward-212", PageLocked(page)); ++ if (ret) ++ return ret; ++ ++ /* refresh bytes */ ++ to_page = pbytes(page_index(page), inode); ++ if (to_page == 0) { ++ zero_user(page, 0, PAGE_CACHE_SIZE); ++ SetPageUptodate(page); ++ goto exit; ++ } ++ } ++ if (PageUptodate(page)) ++ /* somebody else fill it already */ ++ goto exit; ++ ++ assert("edward-119", tfm_cluster_is_uptodate(tc)); ++ assert("edward-1529", znode_is_any_locked(clust->hint->lh.node)); ++ ++ switch (clust->dstat) { ++ case UNPR_DISK_CLUSTER: ++ BUG_ON(1); ++ case TRNC_DISK_CLUSTER: ++ /* ++ * Race with truncate! ++ * We resolve it in favour of the last one (the only way, ++ * as in this case plain text is unrecoverable) ++ */ ++ case FAKE_DISK_CLUSTER: ++ /* fill the page by zeroes */ ++ zero_user(page, 0, PAGE_CACHE_SIZE); ++ SetPageUptodate(page); ++ break; ++ case PREP_DISK_CLUSTER: ++ /* fill page by transformed stream with plain text */ ++ assert("edward-1058", !PageUptodate(page)); ++ assert("edward-120", tc->len <= inode_cluster_size(inode)); ++ ++ /* page index in this logical cluster */ ++ cloff = pg_to_off_to_cloff(page->index, inode); ++ ++ data = kmap(page); ++ memcpy(data, tfm_stream_data(tc, OUTPUT_STREAM) + cloff, to_page); ++ memset(data + to_page, 0, (size_t) PAGE_CACHE_SIZE - to_page); ++ flush_dcache_page(page); ++ kunmap(page); ++ SetPageUptodate(page); ++ break; ++ default: ++ impossible("edward-1169", "bad disk cluster state"); ++ } ++ exit: ++ return 0; ++} ++ ++/* plugin->u.item.s.file.readpage */ ++int readpage_ctail(void *vp, struct page *page) ++{ ++ int result; ++ hint_t * hint; ++ struct cluster_handle * clust = vp; ++ ++ assert("edward-114", clust != NULL); ++ assert("edward-115", PageLocked(page)); ++ assert("edward-116", !PageUptodate(page)); ++ assert("edward-118", page->mapping && page->mapping->host); ++ assert("edward-867", !tfm_cluster_is_uptodate(&clust->tc)); ++ ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) { ++ unlock_page(page); ++ return RETERR(-ENOMEM); ++ } ++ clust->hint = hint; ++ result = load_file_hint(clust->file, hint); ++ if (result) { ++ kfree(hint); ++ unlock_page(page); ++ return result; ++ } ++ assert("vs-25", hint->ext_coord.lh == &hint->lh); ++ ++ result = do_readpage_ctail(page->mapping->host, clust, page, ++ ZNODE_READ_LOCK); ++ assert("edward-213", PageLocked(page)); ++ assert("edward-1163", ergo(!result, PageUptodate(page))); ++ ++ unlock_page(page); ++ done_lh(&hint->lh); ++ hint->ext_coord.valid = 0; ++ save_file_hint(clust->file, hint); ++ kfree(hint); ++ tfm_cluster_clr_uptodate(&clust->tc); ++ ++ return result; ++} ++ ++/* Helper function for ->readpages() */ ++static int ctail_read_page_cluster(struct cluster_handle * clust, ++ struct inode *inode) ++{ ++ int i; ++ int result; ++ assert("edward-779", clust != NULL); ++ assert("edward-1059", clust->win == NULL); ++ assert("edward-780", inode != NULL); ++ ++ result = prepare_page_cluster(inode, clust, READ_OP); ++ if (result) ++ return result; ++ ++ assert("edward-781", !tfm_cluster_is_uptodate(&clust->tc)); ++ ++ for (i = 0; i < clust->nr_pages; i++) { ++ struct page *page = clust->pages[i]; ++ lock_page(page); ++ result = do_readpage_ctail(inode, clust, page, ZNODE_READ_LOCK); ++ unlock_page(page); ++ if (result) ++ break; ++ } ++ tfm_cluster_clr_uptodate(&clust->tc); ++ put_page_cluster(clust, inode, READ_OP); ++ return result; ++} ++ ++/* filler for read_cache_pages() */ ++static int ctail_readpages_filler(void * data, struct page * page) ++{ ++ int ret = 0; ++ struct cluster_handle * clust = data; ++ struct inode * inode = clust->file->f_dentry->d_inode; ++ ++ assert("edward-1525", page->mapping == inode->i_mapping); ++ ++ if (PageUptodate(page)) { ++ unlock_page(page); ++ return 0; ++ } ++ if (pbytes(page_index(page), inode) == 0) { ++ zero_user(page, 0, PAGE_CACHE_SIZE); ++ SetPageUptodate(page); ++ unlock_page(page); ++ return 0; ++ } ++ move_cluster_forward(clust, inode, page->index); ++ unlock_page(page); ++ /* ++ * read the whole page cluster ++ */ ++ ret = ctail_read_page_cluster(clust, inode); ++ ++ assert("edward-869", !tfm_cluster_is_uptodate(&clust->tc)); ++ return ret; ++} ++ ++/* ++ * We populate a bit more then upper readahead suggests: ++ * with each nominated page we read the whole page cluster ++ * this page belongs to. ++ */ ++int readpages_ctail(struct file *file, struct address_space *mapping, ++ struct list_head *pages) ++{ ++ int ret = 0; ++ hint_t *hint; ++ struct cluster_handle clust; ++ struct inode *inode = mapping->host; ++ ++ assert("edward-1521", inode == file->f_dentry->d_inode); ++ ++ cluster_init_read(&clust, NULL); ++ clust.file = file; ++ hint = kmalloc(sizeof(*hint), reiser4_ctx_gfp_mask_get()); ++ if (hint == NULL) { ++ warning("vs-28", "failed to allocate hint"); ++ ret = RETERR(-ENOMEM); ++ goto exit1; ++ } ++ clust.hint = hint; ++ ret = load_file_hint(clust.file, hint); ++ if (ret) { ++ warning("edward-1522", "failed to load hint"); ++ goto exit2; ++ } ++ assert("vs-26", hint->ext_coord.lh == &hint->lh); ++ ret = alloc_cluster_pgset(&clust, cluster_nrpages(inode)); ++ if (ret) { ++ warning("edward-1523", "failed to alloc pgset"); ++ goto exit3; ++ } ++ ret = read_cache_pages(mapping, pages, ctail_readpages_filler, &clust); ++ ++ assert("edward-870", !tfm_cluster_is_uptodate(&clust.tc)); ++ exit3: ++ done_lh(&hint->lh); ++ save_file_hint(file, hint); ++ hint->ext_coord.valid = 0; ++ exit2: ++ kfree(hint); ++ exit1: ++ put_cluster_handle(&clust); ++ return ret; ++} ++ ++/* ++ plugin->u.item.s.file.append_key ++ key of the first item of the next disk cluster ++*/ ++reiser4_key *append_key_ctail(const coord_t * coord, reiser4_key * key) ++{ ++ assert("edward-1241", item_id_by_coord(coord) == CTAIL_ID); ++ assert("edward-1242", cluster_shift_ok(cluster_shift_by_coord(coord))); ++ ++ item_key_by_coord(coord, key); ++ set_key_offset(key, ((__u64) (clust_by_coord(coord, NULL)) + 1) ++ << cluster_shift_by_coord(coord)); ++ return key; ++} ++ ++static int insert_unprepped_ctail(struct cluster_handle * clust, ++ struct inode *inode) ++{ ++ int result; ++ char buf[UCTAIL_NR_UNITS]; ++ reiser4_item_data data; ++ reiser4_key key; ++ int shift = (int)UCTAIL_SHIFT; ++ ++ memset(buf, 0, (size_t) UCTAIL_NR_UNITS); ++ result = key_by_inode_cryptcompress(inode, ++ clust_to_off(clust->index, inode), ++ &key); ++ if (result) ++ return result; ++ data.user = 0; ++ data.iplug = item_plugin_by_id(CTAIL_ID); ++ data.arg = &shift; ++ data.length = sizeof(ctail_item_format) + (size_t) UCTAIL_NR_UNITS; ++ data.data = buf; ++ ++ result = insert_by_coord(&clust->hint->ext_coord.coord, ++ &data, &key, clust->hint->ext_coord.lh, 0); ++ return result; ++} ++ ++static int ++insert_cryptcompress_flow(coord_t * coord, lock_handle * lh, flow_t * f, ++ int cluster_shift) ++{ ++ int result; ++ carry_pool *pool; ++ carry_level *lowest_level; ++ reiser4_item_data *data; ++ carry_op *op; ++ ++ pool = ++ init_carry_pool(sizeof(*pool) + 3 * sizeof(*lowest_level) + ++ sizeof(*data)); ++ if (IS_ERR(pool)) ++ return PTR_ERR(pool); ++ lowest_level = (carry_level *) (pool + 1); ++ init_carry_level(lowest_level, pool); ++ data = (reiser4_item_data *) (lowest_level + 3); ++ ++ assert("edward-466", coord->between == AFTER_ITEM ++ || coord->between == AFTER_UNIT || coord->between == BEFORE_ITEM ++ || coord->between == EMPTY_NODE ++ || coord->between == BEFORE_UNIT); ++ ++ if (coord->between == AFTER_UNIT) { ++ coord->unit_pos = 0; ++ coord->between = AFTER_ITEM; ++ } ++ op = reiser4_post_carry(lowest_level, COP_INSERT_FLOW, coord->node, ++ 0 /* operate directly on coord -> node */); ++ if (IS_ERR(op) || (op == NULL)) { ++ done_carry_pool(pool); ++ return RETERR(op ? PTR_ERR(op) : -EIO); ++ } ++ data->user = 0; ++ data->iplug = item_plugin_by_id(CTAIL_ID); ++ data->arg = &cluster_shift; ++ ++ data->length = 0; ++ data->data = NULL; ++ ++ op->u.insert_flow.flags = COPI_DONT_SHIFT_LEFT | COPI_DONT_SHIFT_RIGHT; ++ op->u.insert_flow.insert_point = coord; ++ op->u.insert_flow.flow = f; ++ op->u.insert_flow.data = data; ++ op->u.insert_flow.new_nodes = 0; ++ ++ lowest_level->track_type = CARRY_TRACK_CHANGE; ++ lowest_level->tracked = lh; ++ ++ result = reiser4_carry(lowest_level, NULL); ++ done_carry_pool(pool); ++ ++ return result; ++} ++ ++/* Implementation of CRC_APPEND_ITEM mode of ctail conversion */ ++static int insert_cryptcompress_flow_in_place(coord_t * coord, ++ lock_handle * lh, flow_t * f, ++ int cluster_shift) ++{ ++ int ret; ++ coord_t pos; ++ lock_handle lock; ++ ++ assert("edward-484", ++ coord->between == AT_UNIT || coord->between == AFTER_ITEM); ++ assert("edward-485", item_id_by_coord(coord) == CTAIL_ID); ++ ++ coord_dup(&pos, coord); ++ pos.unit_pos = 0; ++ pos.between = AFTER_ITEM; ++ ++ init_lh(&lock); ++ copy_lh(&lock, lh); ++ ++ ret = insert_cryptcompress_flow(&pos, &lock, f, cluster_shift); ++ done_lh(&lock); ++ assert("edward-1347", znode_is_write_locked(lh->node)); ++ assert("edward-1228", !ret); ++ return ret; ++} ++ ++/* Implementation of CRC_OVERWRITE_ITEM mode of ctail conversion */ ++static int overwrite_ctail(coord_t * coord, flow_t * f) ++{ ++ unsigned count; ++ ++ assert("edward-269", f->user == 0); ++ assert("edward-270", f->data != NULL); ++ assert("edward-271", f->length > 0); ++ assert("edward-272", coord_is_existing_unit(coord)); ++ assert("edward-273", coord->unit_pos == 0); ++ assert("edward-274", znode_is_write_locked(coord->node)); ++ assert("edward-275", reiser4_schedulable()); ++ assert("edward-467", item_id_by_coord(coord) == CTAIL_ID); ++ assert("edward-1243", ctail_ok(coord)); ++ ++ count = nr_units_ctail(coord); ++ ++ if (count > f->length) ++ count = f->length; ++ memcpy(first_unit(coord), f->data, count); ++ move_flow_forward(f, count); ++ coord->unit_pos += count; ++ return 0; ++} ++ ++/* Implementation of CRC_CUT_ITEM mode of ctail conversion: ++ cut ctail (part or whole) starting from next unit position */ ++static int cut_ctail(coord_t * coord) ++{ ++ coord_t stop; ++ ++ assert("edward-435", coord->between == AT_UNIT && ++ coord->item_pos < coord_num_items(coord) && ++ coord->unit_pos <= coord_num_units(coord)); ++ ++ if (coord->unit_pos == coord_num_units(coord)) ++ /* nothing to cut */ ++ return 0; ++ coord_dup(&stop, coord); ++ stop.unit_pos = coord_last_unit_pos(coord); ++ ++ return cut_node_content(coord, &stop, NULL, NULL, NULL); ++} ++ ++int ctail_insert_unprepped_cluster(struct cluster_handle * clust, ++ struct inode * inode) ++{ ++ int result; ++ assert("edward-1244", inode != NULL); ++ assert("edward-1245", clust->hint != NULL); ++ assert("edward-1246", clust->dstat == FAKE_DISK_CLUSTER); ++ assert("edward-1247", clust->reserved == 1); ++ ++ result = get_disk_cluster_locked(clust, inode, ZNODE_WRITE_LOCK); ++ if (cbk_errored(result)) ++ return result; ++ assert("edward-1249", result == CBK_COORD_NOTFOUND); ++ assert("edward-1250", znode_is_write_locked(clust->hint->lh.node)); ++ ++ assert("edward-1295", ++ clust->hint->ext_coord.lh->node == ++ clust->hint->ext_coord.coord.node); ++ ++ coord_set_between_clusters(&clust->hint->ext_coord.coord); ++ ++ result = insert_unprepped_ctail(clust, inode); ++ all_grabbed2free(); ++ ++ assert("edward-1251", !result); ++ assert("edward-1252", cryptcompress_inode_ok(inode)); ++ assert("edward-1253", znode_is_write_locked(clust->hint->lh.node)); ++ assert("edward-1254", ++ reiser4_clustered_blocks(reiser4_get_current_sb())); ++ assert("edward-1255", ++ znode_convertible(clust->hint->ext_coord.coord.node)); ++ ++ return result; ++} ++ ++static int do_convert_ctail(flush_pos_t * pos, cryptcompress_write_mode_t mode) ++{ ++ int result = 0; ++ struct convert_item_info * info; ++ ++ assert("edward-468", pos != NULL); ++ assert("edward-469", pos->sq != NULL); ++ assert("edward-845", item_convert_data(pos) != NULL); ++ ++ info = item_convert_data(pos); ++ assert("edward-679", info->flow.data != NULL); ++ ++ switch (mode) { ++ case CRC_APPEND_ITEM: ++ assert("edward-1229", info->flow.length != 0); ++ assert("edward-1256", ++ cluster_shift_ok(cluster_shift_by_coord(&pos->coord))); ++ result = ++ insert_cryptcompress_flow_in_place(&pos->coord, ++ &pos->lock, ++ &info->flow, ++ info->cluster_shift); ++ break; ++ case CRC_OVERWRITE_ITEM: ++ assert("edward-1230", info->flow.length != 0); ++ overwrite_ctail(&pos->coord, &info->flow); ++ if (info->flow.length != 0) ++ break; ++ case CRC_CUT_ITEM: ++ assert("edward-1231", info->flow.length == 0); ++ result = cut_ctail(&pos->coord); ++ break; ++ default: ++ result = RETERR(-EIO); ++ impossible("edward-244", "bad convert mode"); ++ } ++ return result; ++} ++ ++/* plugin->u.item.f.scan */ ++int scan_ctail(flush_scan * scan) ++{ ++ int result = 0; ++ struct page *page; ++ struct inode *inode; ++ jnode *node = scan->node; ++ ++ assert("edward-227", scan->node != NULL); ++ assert("edward-228", jnode_is_cluster_page(scan->node)); ++ assert("edward-639", znode_is_write_locked(scan->parent_lock.node)); ++ ++ page = jnode_page(node); ++ inode = page->mapping->host; ++ ++ if (!reiser4_scanning_left(scan)) ++ return result; ++ if (!ZF_ISSET(scan->parent_lock.node, JNODE_DIRTY)) ++ znode_make_dirty(scan->parent_lock.node); ++ ++ if (!znode_convertible(scan->parent_lock.node)) { ++ if (JF_ISSET(scan->node, JNODE_DIRTY)) ++ znode_set_convertible(scan->parent_lock.node); ++ else { ++ warning("edward-681", ++ "cluster page is already processed"); ++ return -EAGAIN; ++ } ++ } ++ return result; ++} ++ ++/* If true, this function attaches children */ ++static int should_attach_convert_idata(flush_pos_t * pos) ++{ ++ int result; ++ assert("edward-431", pos != NULL); ++ assert("edward-432", pos->child == NULL); ++ assert("edward-619", znode_is_write_locked(pos->coord.node)); ++ assert("edward-470", ++ item_plugin_by_coord(&pos->coord) == ++ item_plugin_by_id(CTAIL_ID)); ++ ++ /* check for leftmost child */ ++ utmost_child_ctail(&pos->coord, LEFT_SIDE, &pos->child); ++ ++ if (!pos->child) ++ return 0; ++ spin_lock_jnode(pos->child); ++ result = (JF_ISSET(pos->child, JNODE_DIRTY) && ++ pos->child->atom == ZJNODE(pos->coord.node)->atom); ++ spin_unlock_jnode(pos->child); ++ if (!result && pos->child) { ++ /* existing child isn't to attach, clear up this one */ ++ jput(pos->child); ++ pos->child = NULL; ++ } ++ return result; ++} ++ ++/** ++ * Collect all needed information about the object here, ++ * as in-memory inode can be evicted from memory before ++ * disk update completion. ++ */ ++static int init_convert_data_ctail(struct convert_item_info * idata, ++ struct inode *inode) ++{ ++ assert("edward-813", idata != NULL); ++ assert("edward-814", inode != NULL); ++ ++ idata->cluster_shift = inode_cluster_shift(inode); ++ idata->d_cur = DC_FIRST_ITEM; ++ idata->d_next = DC_INVALID_STATE; ++ ++ return 0; ++} ++ ++static int alloc_item_convert_data(struct convert_info * sq) ++{ ++ assert("edward-816", sq != NULL); ++ assert("edward-817", sq->itm == NULL); ++ ++ sq->itm = kmalloc(sizeof(*sq->itm), reiser4_ctx_gfp_mask_get()); ++ if (sq->itm == NULL) ++ return RETERR(-ENOMEM); ++ return 0; ++} ++ ++static void free_item_convert_data(struct convert_info * sq) ++{ ++ assert("edward-818", sq != NULL); ++ assert("edward-819", sq->itm != NULL); ++ assert("edward-820", sq->iplug != NULL); ++ ++ kfree(sq->itm); ++ sq->itm = NULL; ++ return; ++} ++ ++static int alloc_convert_data(flush_pos_t * pos) ++{ ++ assert("edward-821", pos != NULL); ++ assert("edward-822", pos->sq == NULL); ++ ++ pos->sq = kmalloc(sizeof(*pos->sq), reiser4_ctx_gfp_mask_get()); ++ if (!pos->sq) ++ return RETERR(-ENOMEM); ++ memset(pos->sq, 0, sizeof(*pos->sq)); ++ cluster_init_write(&pos->sq->clust, NULL); ++ return 0; ++} ++ ++void free_convert_data(flush_pos_t * pos) ++{ ++ struct convert_info *sq; ++ ++ assert("edward-823", pos != NULL); ++ assert("edward-824", pos->sq != NULL); ++ ++ sq = pos->sq; ++ if (sq->itm) ++ free_item_convert_data(sq); ++ put_cluster_handle(&sq->clust); ++ kfree(pos->sq); ++ pos->sq = NULL; ++ return; ++} ++ ++static int init_item_convert_data(flush_pos_t * pos, struct inode *inode) ++{ ++ struct convert_info *sq; ++ ++ assert("edward-825", pos != NULL); ++ assert("edward-826", pos->sq != NULL); ++ assert("edward-827", item_convert_data(pos) != NULL); ++ assert("edward-828", inode != NULL); ++ ++ sq = pos->sq; ++ ++ memset(sq->itm, 0, sizeof(*sq->itm)); ++ ++ /* iplug->init_convert_data() */ ++ return init_convert_data_ctail(sq->itm, inode); ++} ++ ++/* create and attach disk cluster info used by 'convert' phase of the flush ++ squalloc() */ ++static int attach_convert_idata(flush_pos_t * pos, struct inode *inode) ++{ ++ int ret = 0; ++ struct convert_item_info *info; ++ struct cluster_handle *clust; ++ file_plugin *fplug = inode_file_plugin(inode); ++ compression_plugin *cplug = inode_compression_plugin(inode); ++ ++ assert("edward-248", pos != NULL); ++ assert("edward-249", pos->child != NULL); ++ assert("edward-251", inode != NULL); ++ assert("edward-682", cryptcompress_inode_ok(inode)); ++ assert("edward-252", ++ fplug == file_plugin_by_id(CRYPTCOMPRESS_FILE_PLUGIN_ID)); ++ assert("edward-473", ++ item_plugin_by_coord(&pos->coord) == ++ item_plugin_by_id(CTAIL_ID)); ++ ++ if (!pos->sq) { ++ ret = alloc_convert_data(pos); ++ if (ret) ++ return ret; ++ } ++ clust = &pos->sq->clust; ++ ret = grab_coa(&clust->tc, cplug); ++ if (ret) ++ goto err; ++ ret = set_cluster_by_page(clust, ++ jnode_page(pos->child), ++ MAX_CLUSTER_NRPAGES); ++ if (ret) ++ goto err; ++ ++ assert("edward-829", pos->sq != NULL); ++ assert("edward-250", item_convert_data(pos) == NULL); ++ ++ pos->sq->iplug = item_plugin_by_id(CTAIL_ID); ++ ++ ret = alloc_item_convert_data(pos->sq); ++ if (ret) ++ goto err; ++ ret = init_item_convert_data(pos, inode); ++ if (ret) ++ goto err; ++ info = item_convert_data(pos); ++ ++ ret = checkout_logical_cluster(clust, pos->child, inode); ++ if (ret) ++ goto err; ++ ++ reiser4_deflate_cluster(clust, inode); ++ inc_item_convert_count(pos); ++ ++ /* prepare flow for insertion */ ++ fplug->flow_by_inode(inode, ++ (const char __user *)tfm_stream_data(&clust->tc, OUTPUT_STREAM), ++ 0 /* kernel space */ , ++ clust->tc.len, ++ clust_to_off(clust->index, inode), ++ WRITE_OP, &info->flow); ++ jput(pos->child); ++ return 0; ++ err: ++ jput(pos->child); ++ free_convert_data(pos); ++ return ret; ++} ++ ++/* clear up disk cluster info */ ++static void detach_convert_idata(struct convert_info * sq) ++{ ++ struct convert_item_info *info; ++ ++ assert("edward-253", sq != NULL); ++ assert("edward-840", sq->itm != NULL); ++ ++ info = sq->itm; ++ assert("edward-1212", info->flow.length == 0); ++ ++ free_item_convert_data(sq); ++ return; ++} ++ ++/* plugin->u.item.f.utmost_child */ ++ ++/* This function sets leftmost child for a first cluster item, ++ if the child exists, and NULL in other cases. ++ NOTE-EDWARD: Do not call this for RIGHT_SIDE */ ++ ++int utmost_child_ctail(const coord_t * coord, sideof side, jnode ** child) ++{ ++ reiser4_key key; ++ ++ item_key_by_coord(coord, &key); ++ ++ assert("edward-257", coord != NULL); ++ assert("edward-258", child != NULL); ++ assert("edward-259", side == LEFT_SIDE); ++ assert("edward-260", ++ item_plugin_by_coord(coord) == item_plugin_by_id(CTAIL_ID)); ++ ++ if (!is_disk_cluster_key(&key, coord)) ++ *child = NULL; ++ else ++ *child = jlookup(current_tree, ++ get_key_objectid(item_key_by_coord ++ (coord, &key)), ++ off_to_pg(get_key_offset(&key))); ++ return 0; ++} ++ ++/* Returns true if @p2 is the next item to @p1 ++ in the _same_ disk cluster. ++ Disk cluster is a set of items. If ->clustered() != NULL, ++ with each item the whole disk cluster should be read/modified ++*/ ++ ++/* Go rightward and check for next disk cluster item, set ++ * d_next to DC_CHAINED_ITEM, if the last one exists. ++ * If the current position is last item, go to right neighbor. ++ * Skip empty nodes. Note, that right neighbors may be not in ++ * the slum because of races. If so, make it dirty and ++ * convertible. ++ */ ++static int next_item_dc_stat(flush_pos_t * pos) ++{ ++ int ret = 0; ++ int stop = 0; ++ znode *cur; ++ coord_t coord; ++ lock_handle lh; ++ lock_handle right_lock; ++ ++ assert("edward-1232", !node_is_empty(pos->coord.node)); ++ assert("edward-1014", ++ pos->coord.item_pos < coord_num_items(&pos->coord)); ++ assert("edward-1015", chaining_data_present(pos)); ++ assert("edward-1017", ++ item_convert_data(pos)->d_next == DC_INVALID_STATE); ++ ++ item_convert_data(pos)->d_next = DC_AFTER_CLUSTER; ++ ++ if (item_convert_data(pos)->d_cur == DC_AFTER_CLUSTER) ++ return ret; ++ if (pos->coord.item_pos < coord_num_items(&pos->coord) - 1) ++ return ret; ++ ++ /* Check next slum item. ++ * Note, that it can not be killed by concurrent truncate, ++ * as the last one will want the lock held by us. ++ */ ++ init_lh(&right_lock); ++ cur = pos->coord.node; ++ ++ while (!stop) { ++ init_lh(&lh); ++ ret = reiser4_get_right_neighbor(&lh, ++ cur, ++ ZNODE_WRITE_LOCK, ++ GN_CAN_USE_UPPER_LEVELS); ++ if (ret) ++ break; ++ ret = zload(lh.node); ++ if (ret) { ++ done_lh(&lh); ++ break; ++ } ++ coord_init_before_first_item(&coord, lh.node); ++ ++ if (node_is_empty(lh.node)) { ++ znode_make_dirty(lh.node); ++ znode_set_convertible(lh.node); ++ stop = 0; ++ } else if (same_disk_cluster(&pos->coord, &coord)) { ++ ++ item_convert_data(pos)->d_next = DC_CHAINED_ITEM; ++ ++ if (!ZF_ISSET(lh.node, JNODE_DIRTY)) { ++ /* ++ warning("edward-1024", ++ "next slum item mergeable, " ++ "but znode %p isn't dirty\n", ++ lh.node); ++ */ ++ znode_make_dirty(lh.node); ++ } ++ if (!znode_convertible(lh.node)) { ++ /* ++ warning("edward-1272", ++ "next slum item mergeable, " ++ "but znode %p isn't convertible\n", ++ lh.node); ++ */ ++ znode_set_convertible(lh.node); ++ } ++ stop = 1; ++ } else ++ stop = 1; ++ zrelse(lh.node); ++ done_lh(&right_lock); ++ copy_lh(&right_lock, &lh); ++ done_lh(&lh); ++ cur = right_lock.node; ++ } ++ done_lh(&right_lock); ++ ++ if (ret == -E_NO_NEIGHBOR) ++ ret = 0; ++ return ret; ++} ++ ++static int ++assign_convert_mode(struct convert_item_info * idata, ++ cryptcompress_write_mode_t * mode) ++{ ++ int result = 0; ++ ++ assert("edward-1025", idata != NULL); ++ ++ if (idata->flow.length) { ++ /* append or overwrite */ ++ switch (idata->d_cur) { ++ case DC_FIRST_ITEM: ++ case DC_CHAINED_ITEM: ++ *mode = CRC_OVERWRITE_ITEM; ++ break; ++ case DC_AFTER_CLUSTER: ++ *mode = CRC_APPEND_ITEM; ++ break; ++ default: ++ impossible("edward-1018", "wrong current item state"); ++ } ++ } else { ++ /* cut or invalidate */ ++ switch (idata->d_cur) { ++ case DC_FIRST_ITEM: ++ case DC_CHAINED_ITEM: ++ *mode = CRC_CUT_ITEM; ++ break; ++ case DC_AFTER_CLUSTER: ++ result = 1; ++ break; ++ default: ++ impossible("edward-1019", "wrong current item state"); ++ } ++ } ++ return result; ++} ++ ++/* plugin->u.item.f.convert */ ++/* write ctail in guessed mode */ ++int convert_ctail(flush_pos_t * pos) ++{ ++ int result; ++ int nr_items; ++ cryptcompress_write_mode_t mode = CRC_OVERWRITE_ITEM; ++ ++ assert("edward-1020", pos != NULL); ++ assert("edward-1213", coord_num_items(&pos->coord) != 0); ++ assert("edward-1257", item_id_by_coord(&pos->coord) == CTAIL_ID); ++ assert("edward-1258", ctail_ok(&pos->coord)); ++ assert("edward-261", pos->coord.node != NULL); ++ ++ nr_items = coord_num_items(&pos->coord); ++ if (!chaining_data_present(pos)) { ++ if (should_attach_convert_idata(pos)) { ++ /* attach convert item info */ ++ struct inode *inode; ++ ++ assert("edward-264", pos->child != NULL); ++ assert("edward-265", jnode_page(pos->child) != NULL); ++ assert("edward-266", ++ jnode_page(pos->child)->mapping != NULL); ++ ++ inode = jnode_page(pos->child)->mapping->host; ++ ++ assert("edward-267", inode != NULL); ++ ++ /* attach item convert info by child and put the last one */ ++ result = attach_convert_idata(pos, inode); ++ pos->child = NULL; ++ if (result == -E_REPEAT) { ++ /* jnode became clean, or there is no dirty ++ pages (nothing to update in disk cluster) */ ++ warning("edward-1021", ++ "convert_ctail: nothing to attach"); ++ return 0; ++ } ++ if (result != 0) ++ return result; ++ } else ++ /* unconvertible */ ++ return 0; ++ } else { ++ /* use old convert info */ ++ ++ struct convert_item_info *idata; ++ ++ idata = item_convert_data(pos); ++ ++ result = assign_convert_mode(idata, &mode); ++ if (result) { ++ /* disk cluster is over, ++ nothing to update anymore */ ++ detach_convert_idata(pos->sq); ++ return 0; ++ } ++ } ++ ++ assert("edward-433", chaining_data_present(pos)); ++ assert("edward-1022", ++ pos->coord.item_pos < coord_num_items(&pos->coord)); ++ ++ /* check if next item is of current disk cluster */ ++ result = next_item_dc_stat(pos); ++ if (result) { ++ detach_convert_idata(pos->sq); ++ return result; ++ } ++ result = do_convert_ctail(pos, mode); ++ if (result) { ++ detach_convert_idata(pos->sq); ++ return result; ++ } ++ switch (mode) { ++ case CRC_CUT_ITEM: ++ assert("edward-1214", item_convert_data(pos)->flow.length == 0); ++ assert("edward-1215", ++ coord_num_items(&pos->coord) == nr_items || ++ coord_num_items(&pos->coord) == nr_items - 1); ++ if (item_convert_data(pos)->d_next == DC_CHAINED_ITEM) ++ break; ++ if (coord_num_items(&pos->coord) != nr_items) { ++ /* the item was killed, no more chained items */ ++ detach_convert_idata(pos->sq); ++ if (!node_is_empty(pos->coord.node)) ++ /* make sure the next item will be scanned */ ++ coord_init_before_item(&pos->coord); ++ break; ++ } ++ case CRC_APPEND_ITEM: ++ assert("edward-434", item_convert_data(pos)->flow.length == 0); ++ detach_convert_idata(pos->sq); ++ break; ++ case CRC_OVERWRITE_ITEM: ++ if (coord_is_unprepped_ctail(&pos->coord)) { ++ /* convert unpprepped ctail to prepped one */ ++ assert("edward-1259", ++ cluster_shift_ok(item_convert_data(pos)-> ++ cluster_shift)); ++ put_unaligned((d8)item_convert_data(pos)->cluster_shift, ++ &ctail_formatted_at(&pos->coord)-> ++ cluster_shift); ++ } ++ break; ++ } ++ return result; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/ctail.h linux-2.6.30/fs/reiser4/plugin/item/ctail.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/ctail.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/ctail.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,102 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Ctail items are fragments (or bodies) of special tipe to provide ++ optimal storage of encrypted and(or) compressed files. */ ++ ++ ++#if !defined( __FS_REISER4_CTAIL_H__ ) ++#define __FS_REISER4_CTAIL_H__ ++ ++/* Disk format of ctail item */ ++typedef struct ctail_item_format { ++ /* packed shift; ++ if its value is different from UCTAIL_SHIFT (see below), then ++ size of disk cluster is calculated as (1 << cluster_shift) */ ++ d8 cluster_shift; ++ /* ctail body */ ++ d8 body[0]; ++} __attribute__ ((packed)) ctail_item_format; ++ ++/* "Unprepped" disk cluster is represented by a single ctail item ++ with the following "magic" attributes: */ ++/* "magic" cluster_shift */ ++#define UCTAIL_SHIFT 0xff ++/* How many units unprepped ctail item has */ ++#define UCTAIL_NR_UNITS 1 ++ ++/* The following is a set of various item states in a disk cluster. ++ Disk cluster is a set of items whose keys belong to the interval ++ [dc_key , dc_key + disk_cluster_size - 1] */ ++typedef enum { ++ DC_INVALID_STATE = 0, ++ DC_FIRST_ITEM = 1, ++ DC_CHAINED_ITEM = 2, ++ DC_AFTER_CLUSTER = 3 ++} dc_item_stat; ++ ++/* ctail-specific extension. ++ In particular this describes parameters of disk cluster an item belongs to */ ++struct ctail_coord_extension { ++ int shift; /* this contains cluster_shift extracted from ++ ctail_item_format (above), or UCTAIL_SHIFT ++ (the last one is the "magic" of unprepped disk clusters)*/ ++ int dsize; /* size of a prepped disk cluster */ ++ int ncount; /* count of nodes occupied by a disk cluster */ ++}; ++ ++struct cut_list; ++ ++/* plugin->item.b.* */ ++int can_contain_key_ctail(const coord_t *, const reiser4_key *, ++ const reiser4_item_data *); ++int mergeable_ctail(const coord_t * p1, const coord_t * p2); ++pos_in_node_t nr_units_ctail(const coord_t * coord); ++int estimate_ctail(const coord_t * coord, const reiser4_item_data * data); ++void print_ctail(const char *prefix, coord_t * coord); ++lookup_result lookup_ctail(const reiser4_key *, lookup_bias, coord_t *); ++ ++int paste_ctail(coord_t * coord, reiser4_item_data * data, ++ carry_plugin_info * info UNUSED_ARG); ++int init_ctail(coord_t *, coord_t *, reiser4_item_data *); ++int can_shift_ctail(unsigned free_space, coord_t * coord, ++ znode * target, shift_direction pend, unsigned *size, ++ unsigned want); ++void copy_units_ctail(coord_t * target, coord_t * source, unsigned from, ++ unsigned count, shift_direction where_is_free_space, ++ unsigned free_space); ++int cut_units_ctail(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ carry_cut_data *, reiser4_key * smallest_removed, ++ reiser4_key * new_first); ++int kill_units_ctail(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ carry_kill_data *, reiser4_key * smallest_removed, ++ reiser4_key * new_first); ++int ctail_ok(const coord_t * coord); ++int check_ctail(const coord_t * coord, const char **error); ++ ++/* plugin->u.item.s.* */ ++int read_ctail(struct file *, flow_t *, hint_t *); ++int readpage_ctail(void *, struct page *); ++int readpages_ctail(struct file *, struct address_space *, struct list_head *); ++reiser4_key *append_key_ctail(const coord_t *, reiser4_key *); ++int create_hook_ctail(const coord_t * coord, void *arg); ++int kill_hook_ctail(const coord_t *, pos_in_node_t, pos_in_node_t, ++ carry_kill_data *); ++int shift_hook_ctail(const coord_t *, unsigned, unsigned, znode *); ++ ++/* plugin->u.item.f */ ++int utmost_child_ctail(const coord_t *, sideof, jnode **); ++int scan_ctail(flush_scan *); ++int convert_ctail(flush_pos_t *); ++size_t inode_scaled_cluster_size(struct inode *); ++ ++#endif /* __FS_REISER4_CTAIL_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/extent.c linux-2.6.30/fs/reiser4/plugin/item/extent.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/extent.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/extent.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,197 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "item.h" ++#include "../../key.h" ++#include "../../super.h" ++#include "../../carry.h" ++#include "../../inode.h" ++#include "../../page_cache.h" ++#include "../../flush.h" ++#include "../object.h" ++ ++/* prepare structure reiser4_item_data. It is used to put one extent unit into tree */ ++/* Audited by: green(2002.06.13) */ ++reiser4_item_data *init_new_extent(reiser4_item_data * data, void *ext_unit, ++ int nr_extents) ++{ ++ data->data = ext_unit; ++ /* data->data is kernel space */ ++ data->user = 0; ++ data->length = sizeof(reiser4_extent) * nr_extents; ++ data->arg = NULL; ++ data->iplug = item_plugin_by_id(EXTENT_POINTER_ID); ++ return data; ++} ++ ++/* how many bytes are addressed by @nr first extents of the extent item */ ++reiser4_block_nr reiser4_extent_size(const coord_t * coord, pos_in_node_t nr) ++{ ++ pos_in_node_t i; ++ reiser4_block_nr blocks; ++ reiser4_extent *ext; ++ ++ ext = item_body_by_coord(coord); ++ assert("vs-263", nr <= nr_units_extent(coord)); ++ ++ blocks = 0; ++ for (i = 0; i < nr; i++, ext++) { ++ blocks += extent_get_width(ext); ++ } ++ ++ return blocks * current_blocksize; ++} ++ ++extent_state state_of_extent(reiser4_extent * ext) ++{ ++ switch ((int)extent_get_start(ext)) { ++ case 0: ++ return HOLE_EXTENT; ++ case 1: ++ return UNALLOCATED_EXTENT; ++ default: ++ break; ++ } ++ return ALLOCATED_EXTENT; ++} ++ ++int extent_is_unallocated(const coord_t * item) ++{ ++ assert("jmacd-5133", item_is_extent(item)); ++ ++ return state_of_extent(extent_by_coord(item)) == UNALLOCATED_EXTENT; ++} ++ ++/* set extent's start and width */ ++void reiser4_set_extent(reiser4_extent * ext, reiser4_block_nr start, ++ reiser4_block_nr width) ++{ ++ extent_set_start(ext, start); ++ extent_set_width(ext, width); ++} ++ ++/** ++ * reiser4_replace_extent - replace extent and paste 1 or 2 after it ++ * @un_extent: coordinate of extent to be overwritten ++ * @lh: need better comment ++ * @key: need better comment ++ * @exts_to_add: data prepared for insertion into tree ++ * @replace: need better comment ++ * @flags: need better comment ++ * @return_insert_position: need better comment ++ * ++ * Overwrites one extent, pastes 1 or 2 more ones after overwritten one. If ++ * @return_inserted_position is 1 - @un_extent and @lh are returned set to ++ * first of newly inserted units, if it is 0 - @un_extent and @lh are returned ++ * set to extent which was overwritten. ++ */ ++int reiser4_replace_extent(struct replace_handle *h, ++ int return_inserted_position) ++{ ++ int result; ++ znode *orig_znode; ++ /*ON_DEBUG(reiser4_extent orig_ext);*/ /* this is for debugging */ ++ ++ assert("vs-990", coord_is_existing_unit(h->coord)); ++ assert("vs-1375", znode_is_write_locked(h->coord->node)); ++ assert("vs-1426", extent_get_width(&h->overwrite) != 0); ++ assert("vs-1427", extent_get_width(&h->new_extents[0]) != 0); ++ assert("vs-1427", ergo(h->nr_new_extents == 2, ++ extent_get_width(&h->new_extents[1]) != 0)); ++ ++ /* compose structure for paste */ ++ init_new_extent(&h->item, &h->new_extents[0], h->nr_new_extents); ++ ++ coord_dup(&h->coord_after, h->coord); ++ init_lh(&h->lh_after); ++ copy_lh(&h->lh_after, h->lh); ++ reiser4_tap_init(&h->watch, &h->coord_after, &h->lh_after, ZNODE_WRITE_LOCK); ++ reiser4_tap_monitor(&h->watch); ++ ++ ON_DEBUG(h->orig_ext = *extent_by_coord(h->coord)); ++ orig_znode = h->coord->node; ++ ++#if REISER4_DEBUG ++ /* make sure that key is set properly */ ++ unit_key_by_coord(h->coord, &h->tmp); ++ set_key_offset(&h->tmp, ++ get_key_offset(&h->tmp) + ++ extent_get_width(&h->overwrite) * current_blocksize); ++ assert("vs-1080", keyeq(&h->tmp, &h->paste_key)); ++#endif ++ ++ /* set insert point after unit to be replaced */ ++ h->coord->between = AFTER_UNIT; ++ ++ result = insert_into_item(h->coord, return_inserted_position ? h->lh : NULL, ++ &h->paste_key, &h->item, h->flags); ++ if (!result) { ++ /* now we have to replace the unit after which new units were ++ inserted. Its position is tracked by @watch */ ++ reiser4_extent *ext; ++ znode *node; ++ ++ node = h->coord_after.node; ++ if (node != orig_znode) { ++ coord_clear_iplug(&h->coord_after); ++ result = zload(node); ++ } ++ ++ if (likely(!result)) { ++ ext = extent_by_coord(&h->coord_after); ++ ++ assert("vs-987", znode_is_loaded(node)); ++ assert("vs-988", !memcmp(ext, &h->orig_ext, sizeof(*ext))); ++ ++ /* overwrite extent unit */ ++ memcpy(ext, &h->overwrite, sizeof(reiser4_extent)); ++ znode_make_dirty(node); ++ ++ if (node != orig_znode) ++ zrelse(node); ++ ++ if (return_inserted_position == 0) { ++ /* coord and lh are to be set to overwritten ++ extent */ ++ assert("vs-1662", ++ WITH_DATA(node, !memcmp(&h->overwrite, ++ extent_by_coord( ++ &h->coord_after), ++ sizeof(reiser4_extent)))); ++ ++ *h->coord = h->coord_after; ++ done_lh(h->lh); ++ copy_lh(h->lh, &h->lh_after); ++ } else { ++ /* h->coord and h->lh are to be set to first of ++ inserted units */ ++ assert("vs-1663", ++ WITH_DATA(h->coord->node, ++ !memcmp(&h->new_extents[0], ++ extent_by_coord(h->coord), ++ sizeof(reiser4_extent)))); ++ assert("vs-1664", h->lh->node == h->coord->node); ++ } ++ } ++ } ++ reiser4_tap_done(&h->watch); ++ ++ return result; ++} ++ ++lock_handle *znode_lh(znode *node) ++{ ++ assert("vs-1371", znode_is_write_locked(node)); ++ assert("vs-1372", znode_is_wlocked_once(node)); ++ return list_entry(node->lock.owners.next, lock_handle, owners_link); ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/extent_file_ops.c linux-2.6.30/fs/reiser4/plugin/item/extent_file_ops.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/extent_file_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/extent_file_ops.c 2009-06-22 17:27:31.000000000 +0200 +@@ -0,0 +1,1453 @@ ++/* COPYRIGHT 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "item.h" ++#include "../../inode.h" ++#include "../../page_cache.h" ++#include "../object.h" ++ ++#include <linux/quotaops.h> ++#include <linux/swap.h> ++ ++static inline reiser4_extent *ext_by_offset(const znode *node, int offset) ++{ ++ reiser4_extent *ext; ++ ++ ext = (reiser4_extent *) (zdata(node) + offset); ++ return ext; ++} ++ ++/** ++ * check_uf_coord - verify coord extension ++ * @uf_coord: ++ * @key: ++ * ++ * Makes sure that all fields of @uf_coord are set properly. If @key is ++ * specified - check whether @uf_coord is set correspondingly. ++ */ ++static void check_uf_coord(const uf_coord_t *uf_coord, const reiser4_key *key) ++{ ++#if REISER4_DEBUG ++ const coord_t *coord; ++ const struct extent_coord_extension *ext_coord; ++ reiser4_extent *ext; ++ ++ coord = &uf_coord->coord; ++ ext_coord = &uf_coord->extension.extent; ++ ext = ext_by_offset(coord->node, uf_coord->extension.extent.ext_offset); ++ ++ assert("", ++ WITH_DATA(coord->node, ++ (uf_coord->valid == 1 && ++ coord_is_iplug_set(coord) && ++ item_is_extent(coord) && ++ ext_coord->nr_units == nr_units_extent(coord) && ++ ext == extent_by_coord(coord) && ++ ext_coord->width == extent_get_width(ext) && ++ coord->unit_pos < ext_coord->nr_units && ++ ext_coord->pos_in_unit < ext_coord->width && ++ memcmp(ext, &ext_coord->extent, ++ sizeof(reiser4_extent)) == 0))); ++ if (key) { ++ reiser4_key coord_key; ++ ++ unit_key_by_coord(&uf_coord->coord, &coord_key); ++ set_key_offset(&coord_key, ++ get_key_offset(&coord_key) + ++ (uf_coord->extension.extent. ++ pos_in_unit << PAGE_CACHE_SHIFT)); ++ assert("", keyeq(key, &coord_key)); ++ } ++#endif ++} ++ ++static inline reiser4_extent *ext_by_ext_coord(const uf_coord_t *uf_coord) ++{ ++ check_uf_coord(uf_coord, NULL); ++ ++ return ext_by_offset(uf_coord->coord.node, ++ uf_coord->extension.extent.ext_offset); ++} ++ ++#if REISER4_DEBUG ++ ++/** ++ * offset_is_in_unit ++ * ++ * ++ * ++ */ ++/* return 1 if offset @off is inside of extent unit pointed to by @coord. Set ++ pos_in_unit inside of unit correspondingly */ ++static int offset_is_in_unit(const coord_t *coord, loff_t off) ++{ ++ reiser4_key unit_key; ++ __u64 unit_off; ++ reiser4_extent *ext; ++ ++ ext = extent_by_coord(coord); ++ ++ unit_key_extent(coord, &unit_key); ++ unit_off = get_key_offset(&unit_key); ++ if (off < unit_off) ++ return 0; ++ if (off >= (unit_off + (current_blocksize * extent_get_width(ext)))) ++ return 0; ++ return 1; ++} ++ ++static int ++coord_matches_key_extent(const coord_t * coord, const reiser4_key * key) ++{ ++ reiser4_key item_key; ++ ++ assert("vs-771", coord_is_existing_unit(coord)); ++ assert("vs-1258", keylt(key, append_key_extent(coord, &item_key))); ++ assert("vs-1259", keyge(key, item_key_by_coord(coord, &item_key))); ++ ++ return offset_is_in_unit(coord, get_key_offset(key)); ++} ++ ++#endif ++ ++/** ++ * can_append - ++ * @key: ++ * @coord: ++ * ++ * Returns 1 if @key is equal to an append key of item @coord is set to ++ */ ++static int can_append(const reiser4_key *key, const coord_t *coord) ++{ ++ reiser4_key append_key; ++ ++ return keyeq(key, append_key_extent(coord, &append_key)); ++} ++ ++/** ++ * append_hole ++ * @coord: ++ * @lh: ++ * @key: ++ * ++ */ ++static int append_hole(coord_t *coord, lock_handle *lh, ++ const reiser4_key *key) ++{ ++ reiser4_key append_key; ++ reiser4_block_nr hole_width; ++ reiser4_extent *ext, new_ext; ++ reiser4_item_data idata; ++ ++ /* last item of file may have to be appended with hole */ ++ assert("vs-708", znode_get_level(coord->node) == TWIG_LEVEL); ++ assert("vs-714", item_id_by_coord(coord) == EXTENT_POINTER_ID); ++ ++ /* key of first byte which is not addressed by this extent */ ++ append_key_extent(coord, &append_key); ++ ++ assert("", keyle(&append_key, key)); ++ ++ /* ++ * extent item has to be appended with hole. Calculate length of that ++ * hole ++ */ ++ hole_width = ((get_key_offset(key) - get_key_offset(&append_key) + ++ current_blocksize - 1) >> current_blocksize_bits); ++ assert("vs-954", hole_width > 0); ++ ++ /* set coord after last unit */ ++ coord_init_after_item_end(coord); ++ ++ /* get last extent in the item */ ++ ext = extent_by_coord(coord); ++ if (state_of_extent(ext) == HOLE_EXTENT) { ++ /* ++ * last extent of a file is hole extent. Widen that extent by ++ * @hole_width blocks. Note that we do not worry about ++ * overflowing - extent width is 64 bits ++ */ ++ reiser4_set_extent(ext, HOLE_EXTENT_START, ++ extent_get_width(ext) + hole_width); ++ znode_make_dirty(coord->node); ++ return 0; ++ } ++ ++ /* append last item of the file with hole extent unit */ ++ assert("vs-713", (state_of_extent(ext) == ALLOCATED_EXTENT || ++ state_of_extent(ext) == UNALLOCATED_EXTENT)); ++ ++ reiser4_set_extent(&new_ext, HOLE_EXTENT_START, hole_width); ++ init_new_extent(&idata, &new_ext, 1); ++ return insert_into_item(coord, lh, &append_key, &idata, 0); ++} ++ ++/** ++ * check_jnodes ++ * @twig: longterm locked twig node ++ * @key: ++ * ++ */ ++static void check_jnodes(znode *twig, const reiser4_key *key, int count) ++{ ++#if REISER4_DEBUG ++ coord_t c; ++ reiser4_key node_key, jnode_key; ++ ++ jnode_key = *key; ++ ++ assert("", twig != NULL); ++ assert("", znode_get_level(twig) == TWIG_LEVEL); ++ assert("", znode_is_write_locked(twig)); ++ ++ zload(twig); ++ /* get the smallest key in twig node */ ++ coord_init_first_unit(&c, twig); ++ unit_key_by_coord(&c, &node_key); ++ assert("", keyle(&node_key, &jnode_key)); ++ ++ coord_init_last_unit(&c, twig); ++ unit_key_by_coord(&c, &node_key); ++ if (item_plugin_by_coord(&c)->s.file.append_key) ++ item_plugin_by_coord(&c)->s.file.append_key(&c, &node_key); ++ set_key_offset(&jnode_key, ++ get_key_offset(&jnode_key) + (loff_t)count * PAGE_CACHE_SIZE - 1); ++ assert("", keylt(&jnode_key, &node_key)); ++ zrelse(twig); ++#endif ++} ++ ++/** ++ * append_last_extent - append last file item ++ * @uf_coord: coord to start insertion from ++ * @jnodes: array of jnodes ++ * @count: number of jnodes in the array ++ * ++ * There is already at least one extent item of file @inode in the tree. Append ++ * the last of them with unallocated extent unit of width @count. Assign ++ * fake block numbers to jnodes corresponding to the inserted extent. ++ */ ++static int append_last_extent(uf_coord_t *uf_coord, const reiser4_key *key, ++ jnode **jnodes, int count) ++{ ++ int result; ++ reiser4_extent new_ext; ++ reiser4_item_data idata; ++ coord_t *coord; ++ struct extent_coord_extension *ext_coord; ++ reiser4_extent *ext; ++ reiser4_block_nr block; ++ jnode *node; ++ int i; ++ ++ coord = &uf_coord->coord; ++ ext_coord = &uf_coord->extension.extent; ++ ext = ext_by_ext_coord(uf_coord); ++ ++ /* check correctness of position in the item */ ++ assert("vs-228", coord->unit_pos == coord_last_unit_pos(coord)); ++ assert("vs-1311", coord->between == AFTER_UNIT); ++ assert("vs-1302", ext_coord->pos_in_unit == ext_coord->width - 1); ++ ++ if (!can_append(key, coord)) { ++ /* hole extent has to be inserted */ ++ result = append_hole(coord, uf_coord->lh, key); ++ uf_coord->valid = 0; ++ return result; ++ } ++ ++ if (count == 0) ++ return 0; ++ ++ assert("", get_key_offset(key) == (loff_t)index_jnode(jnodes[0]) * PAGE_CACHE_SIZE); ++ ++ result = vfs_dq_alloc_block_nodirty(mapping_jnode(jnodes[0])->host, ++ count); ++ BUG_ON(result != 0); ++ ++ switch (state_of_extent(ext)) { ++ case UNALLOCATED_EXTENT: ++ /* ++ * last extent unit of the file is unallocated one. Increase ++ * its width by @count ++ */ ++ reiser4_set_extent(ext, UNALLOCATED_EXTENT_START, ++ extent_get_width(ext) + count); ++ znode_make_dirty(coord->node); ++ ++ /* update coord extension */ ++ ext_coord->width += count; ++ ON_DEBUG(extent_set_width ++ (&uf_coord->extension.extent.extent, ++ ext_coord->width)); ++ break; ++ ++ case HOLE_EXTENT: ++ case ALLOCATED_EXTENT: ++ /* ++ * last extent unit of the file is either hole or allocated ++ * one. Append one unallocated extent of width @count ++ */ ++ reiser4_set_extent(&new_ext, UNALLOCATED_EXTENT_START, count); ++ init_new_extent(&idata, &new_ext, 1); ++ result = insert_into_item(coord, uf_coord->lh, key, &idata, 0); ++ uf_coord->valid = 0; ++ if (result) ++ return result; ++ break; ++ ++ default: ++ return RETERR(-EIO); ++ } ++ ++ /* ++ * make sure that we hold long term locked twig node containing all ++ * jnodes we are about to capture ++ */ ++ check_jnodes(uf_coord->lh->node, key, count); ++ ++ /* ++ * assign fake block numbers to all jnodes. FIXME: make sure whether ++ * twig node containing inserted extent item is locked ++ */ ++ block = fake_blocknr_unformatted(count); ++ for (i = 0; i < count; i ++, block ++) { ++ node = jnodes[i]; ++ spin_lock_jnode(node); ++ JF_SET(node, JNODE_CREATED); ++ jnode_set_block(node, &block); ++ result = reiser4_try_capture(node, ZNODE_WRITE_LOCK, 0); ++ BUG_ON(result != 0); ++ jnode_make_dirty_locked(node); ++ spin_unlock_jnode(node); ++ } ++ return count; ++} ++ ++/** ++ * insert_first_hole - inser hole extent into tree ++ * @coord: ++ * @lh: ++ * @key: ++ * ++ * ++ */ ++static int insert_first_hole(coord_t *coord, lock_handle *lh, ++ const reiser4_key *key) ++{ ++ reiser4_extent new_ext; ++ reiser4_item_data idata; ++ reiser4_key item_key; ++ reiser4_block_nr hole_width; ++ ++ /* @coord must be set for inserting of new item */ ++ assert("vs-711", coord_is_between_items(coord)); ++ ++ item_key = *key; ++ set_key_offset(&item_key, 0ull); ++ ++ hole_width = ((get_key_offset(key) + current_blocksize - 1) >> ++ current_blocksize_bits); ++ assert("vs-710", hole_width > 0); ++ ++ /* compose body of hole extent and insert item into tree */ ++ reiser4_set_extent(&new_ext, HOLE_EXTENT_START, hole_width); ++ init_new_extent(&idata, &new_ext, 1); ++ return insert_extent_by_coord(coord, &idata, &item_key, lh); ++} ++ ++ ++/** ++ * insert_first_extent - insert first file item ++ * @inode: inode of file ++ * @uf_coord: coord to start insertion from ++ * @jnodes: array of jnodes ++ * @count: number of jnodes in the array ++ * @inode: ++ * ++ * There are no items of file @inode in the tree yet. Insert unallocated extent ++ * of width @count into tree or hole extent if writing not to the ++ * beginning. Assign fake block numbers to jnodes corresponding to the inserted ++ * unallocated extent. Returns number of jnodes or error code. ++ */ ++static int insert_first_extent(uf_coord_t *uf_coord, const reiser4_key *key, ++ jnode **jnodes, int count, ++ struct inode *inode) ++{ ++ int result; ++ int i; ++ reiser4_extent new_ext; ++ reiser4_item_data idata; ++ reiser4_block_nr block; ++ struct unix_file_info *uf_info; ++ jnode *node; ++ ++ /* first extent insertion starts at leaf level */ ++ assert("vs-719", znode_get_level(uf_coord->coord.node) == LEAF_LEVEL); ++ assert("vs-711", coord_is_between_items(&uf_coord->coord)); ++ ++ if (get_key_offset(key) != 0) { ++ result = insert_first_hole(&uf_coord->coord, uf_coord->lh, key); ++ uf_coord->valid = 0; ++ uf_info = unix_file_inode_data(inode); ++ ++ /* ++ * first item insertion is only possible when writing to empty ++ * file or performing tail conversion ++ */ ++ assert("", (uf_info->container == UF_CONTAINER_EMPTY || ++ (reiser4_inode_get_flag(inode, ++ REISER4_PART_MIXED) && ++ reiser4_inode_get_flag(inode, ++ REISER4_PART_IN_CONV)))); ++ /* if file was empty - update its state */ ++ if (result == 0 && uf_info->container == UF_CONTAINER_EMPTY) ++ uf_info->container = UF_CONTAINER_EXTENTS; ++ return result; ++ } ++ ++ if (count == 0) ++ return 0; ++ ++ result = vfs_dq_alloc_block_nodirty(mapping_jnode(jnodes[0])->host, ++ count); ++ BUG_ON(result != 0); ++ ++ /* ++ * prepare for tree modification: compose body of item and item data ++ * structure needed for insertion ++ */ ++ reiser4_set_extent(&new_ext, UNALLOCATED_EXTENT_START, count); ++ init_new_extent(&idata, &new_ext, 1); ++ ++ /* insert extent item into the tree */ ++ result = insert_extent_by_coord(&uf_coord->coord, &idata, key, ++ uf_coord->lh); ++ if (result) ++ return result; ++ ++ /* ++ * make sure that we hold long term locked twig node containing all ++ * jnodes we are about to capture ++ */ ++ check_jnodes(uf_coord->lh->node, key, count); ++ /* ++ * assign fake block numbers to all jnodes, capture and mark them dirty ++ */ ++ block = fake_blocknr_unformatted(count); ++ for (i = 0; i < count; i ++, block ++) { ++ node = jnodes[i]; ++ spin_lock_jnode(node); ++ JF_SET(node, JNODE_CREATED); ++ jnode_set_block(node, &block); ++ result = reiser4_try_capture(node, ZNODE_WRITE_LOCK, 0); ++ BUG_ON(result != 0); ++ jnode_make_dirty_locked(node); ++ spin_unlock_jnode(node); ++ } ++ ++ /* ++ * invalidate coordinate, research must be performed to continue ++ * because write will continue on twig level ++ */ ++ uf_coord->valid = 0; ++ return count; ++} ++ ++/** ++ * plug_hole - replace hole extent with unallocated and holes ++ * @uf_coord: ++ * @key: ++ * @node: ++ * @h: structure containing coordinate, lock handle, key, etc ++ * ++ * Creates an unallocated extent of width 1 within a hole. In worst case two ++ * additional extents can be created. ++ */ ++static int plug_hole(uf_coord_t *uf_coord, const reiser4_key *key, int *how) ++{ ++ struct replace_handle rh; ++ reiser4_extent *ext; ++ reiser4_block_nr width, pos_in_unit; ++ coord_t *coord; ++ struct extent_coord_extension *ext_coord; ++ int return_inserted_position; ++ ++ check_uf_coord(uf_coord, key); ++ ++ rh.coord = coord_by_uf_coord(uf_coord); ++ rh.lh = uf_coord->lh; ++ rh.flags = 0; ++ ++ coord = coord_by_uf_coord(uf_coord); ++ ext_coord = ext_coord_by_uf_coord(uf_coord); ++ ext = ext_by_ext_coord(uf_coord); ++ ++ width = ext_coord->width; ++ pos_in_unit = ext_coord->pos_in_unit; ++ ++ *how = 0; ++ if (width == 1) { ++ reiser4_set_extent(ext, UNALLOCATED_EXTENT_START, 1); ++ znode_make_dirty(coord->node); ++ /* update uf_coord */ ++ ON_DEBUG(ext_coord->extent = *ext); ++ *how = 1; ++ return 0; ++ } else if (pos_in_unit == 0) { ++ /* we deal with first element of extent */ ++ if (coord->unit_pos) { ++ /* there is an extent to the left */ ++ if (state_of_extent(ext - 1) == UNALLOCATED_EXTENT) { ++ /* ++ * left neighboring unit is an unallocated ++ * extent. Increase its width and decrease ++ * width of hole ++ */ ++ extent_set_width(ext - 1, ++ extent_get_width(ext - 1) + 1); ++ extent_set_width(ext, width - 1); ++ znode_make_dirty(coord->node); ++ ++ /* update coord extension */ ++ coord->unit_pos--; ++ ext_coord->width = extent_get_width(ext - 1); ++ ext_coord->pos_in_unit = ext_coord->width - 1; ++ ext_coord->ext_offset -= sizeof(reiser4_extent); ++ ON_DEBUG(ext_coord->extent = ++ *extent_by_coord(coord)); ++ *how = 2; ++ return 0; ++ } ++ } ++ /* extent for replace */ ++ reiser4_set_extent(&rh.overwrite, UNALLOCATED_EXTENT_START, 1); ++ /* extent to be inserted */ ++ reiser4_set_extent(&rh.new_extents[0], HOLE_EXTENT_START, ++ width - 1); ++ rh.nr_new_extents = 1; ++ ++ /* have reiser4_replace_extent to return with @coord and ++ @uf_coord->lh set to unit which was replaced */ ++ return_inserted_position = 0; ++ *how = 3; ++ } else if (pos_in_unit == width - 1) { ++ /* we deal with last element of extent */ ++ if (coord->unit_pos < nr_units_extent(coord) - 1) { ++ /* there is an extent unit to the right */ ++ if (state_of_extent(ext + 1) == UNALLOCATED_EXTENT) { ++ /* ++ * right neighboring unit is an unallocated ++ * extent. Increase its width and decrease ++ * width of hole ++ */ ++ extent_set_width(ext + 1, ++ extent_get_width(ext + 1) + 1); ++ extent_set_width(ext, width - 1); ++ znode_make_dirty(coord->node); ++ ++ /* update coord extension */ ++ coord->unit_pos++; ++ ext_coord->width = extent_get_width(ext + 1); ++ ext_coord->pos_in_unit = 0; ++ ext_coord->ext_offset += sizeof(reiser4_extent); ++ ON_DEBUG(ext_coord->extent = ++ *extent_by_coord(coord)); ++ *how = 4; ++ return 0; ++ } ++ } ++ /* extent for replace */ ++ reiser4_set_extent(&rh.overwrite, HOLE_EXTENT_START, width - 1); ++ /* extent to be inserted */ ++ reiser4_set_extent(&rh.new_extents[0], UNALLOCATED_EXTENT_START, ++ 1); ++ rh.nr_new_extents = 1; ++ ++ /* have reiser4_replace_extent to return with @coord and ++ @uf_coord->lh set to unit which was inserted */ ++ return_inserted_position = 1; ++ *how = 5; ++ } else { ++ /* extent for replace */ ++ reiser4_set_extent(&rh.overwrite, HOLE_EXTENT_START, ++ pos_in_unit); ++ /* extents to be inserted */ ++ reiser4_set_extent(&rh.new_extents[0], UNALLOCATED_EXTENT_START, ++ 1); ++ reiser4_set_extent(&rh.new_extents[1], HOLE_EXTENT_START, ++ width - pos_in_unit - 1); ++ rh.nr_new_extents = 2; ++ ++ /* have reiser4_replace_extent to return with @coord and ++ @uf_coord->lh set to first of units which were inserted */ ++ return_inserted_position = 1; ++ *how = 6; ++ } ++ unit_key_by_coord(coord, &rh.paste_key); ++ set_key_offset(&rh.paste_key, get_key_offset(&rh.paste_key) + ++ extent_get_width(&rh.overwrite) * current_blocksize); ++ ++ uf_coord->valid = 0; ++ return reiser4_replace_extent(&rh, return_inserted_position); ++} ++ ++/** ++ * overwrite_one_block - ++ * @uf_coord: ++ * @key: ++ * @node: ++ * ++ * If @node corresponds to hole extent - create unallocated extent for it and ++ * assign fake block number. If @node corresponds to allocated extent - assign ++ * block number of jnode ++ */ ++static int overwrite_one_block(uf_coord_t *uf_coord, const reiser4_key *key, ++ jnode *node, int *hole_plugged) ++{ ++ int result; ++ struct extent_coord_extension *ext_coord; ++ reiser4_extent *ext; ++ reiser4_block_nr block; ++ int how; ++ ++ assert("vs-1312", uf_coord->coord.between == AT_UNIT); ++ ++ result = 0; ++ ext_coord = ext_coord_by_uf_coord(uf_coord); ++ ext = ext_by_ext_coord(uf_coord); ++ assert("", state_of_extent(ext) != UNALLOCATED_EXTENT); ++ ++ switch (state_of_extent(ext)) { ++ case ALLOCATED_EXTENT: ++ block = extent_get_start(ext) + ext_coord->pos_in_unit; ++ break; ++ ++ case HOLE_EXTENT: ++ result = vfs_dq_alloc_block_nodirty(mapping_jnode(node)->host, ++ 1); ++ BUG_ON(result != 0); ++ result = plug_hole(uf_coord, key, &how); ++ if (result) ++ return result; ++ block = fake_blocknr_unformatted(1); ++ if (hole_plugged) ++ *hole_plugged = 1; ++ JF_SET(node, JNODE_CREATED); ++ break; ++ ++ default: ++ return RETERR(-EIO); ++ } ++ ++ jnode_set_block(node, &block); ++ return 0; ++} ++ ++/** ++ * move_coord - move coordinate forward ++ * @uf_coord: ++ * ++ * Move coordinate one data block pointer forward. Return 1 if coord is set to ++ * the last one already or is invalid. ++ */ ++static int move_coord(uf_coord_t *uf_coord) ++{ ++ struct extent_coord_extension *ext_coord; ++ ++ if (uf_coord->valid == 0) ++ return 1; ++ ext_coord = &uf_coord->extension.extent; ++ ext_coord->pos_in_unit ++; ++ if (ext_coord->pos_in_unit < ext_coord->width) ++ /* coordinate moved within the unit */ ++ return 0; ++ ++ /* end of unit is reached. Try to move to next unit */ ++ ext_coord->pos_in_unit = 0; ++ uf_coord->coord.unit_pos ++; ++ if (uf_coord->coord.unit_pos < ext_coord->nr_units) { ++ /* coordinate moved to next unit */ ++ ext_coord->ext_offset += sizeof(reiser4_extent); ++ ext_coord->width = ++ extent_get_width(ext_by_offset ++ (uf_coord->coord.node, ++ ext_coord->ext_offset)); ++ ON_DEBUG(ext_coord->extent = ++ *ext_by_offset(uf_coord->coord.node, ++ ext_coord->ext_offset)); ++ return 0; ++ } ++ /* end of item is reached */ ++ uf_coord->valid = 0; ++ return 1; ++} ++ ++/** ++ * overwrite_extent - ++ * @inode: ++ * ++ * Returns number of handled jnodes. ++ */ ++static int overwrite_extent(uf_coord_t *uf_coord, const reiser4_key *key, ++ jnode **jnodes, int count, int *plugged_hole) ++{ ++ int result; ++ reiser4_key k; ++ int i; ++ jnode *node; ++ ++ k = *key; ++ for (i = 0; i < count; i ++) { ++ node = jnodes[i]; ++ if (*jnode_get_block(node) == 0) { ++ result = overwrite_one_block(uf_coord, &k, node, plugged_hole); ++ if (result) ++ return result; ++ } ++ /* ++ * make sure that we hold long term locked twig node containing ++ * all jnodes we are about to capture ++ */ ++ check_jnodes(uf_coord->lh->node, &k, 1); ++ /* ++ * assign fake block numbers to all jnodes, capture and mark ++ * them dirty ++ */ ++ spin_lock_jnode(node); ++ result = reiser4_try_capture(node, ZNODE_WRITE_LOCK, 0); ++ BUG_ON(result != 0); ++ jnode_make_dirty_locked(node); ++ spin_unlock_jnode(node); ++ ++ if (uf_coord->valid == 0) ++ return i + 1; ++ ++ check_uf_coord(uf_coord, &k); ++ ++ if (move_coord(uf_coord)) { ++ /* ++ * failed to move to the next node pointer. Either end ++ * of file or end of twig node is reached. In the later ++ * case we might go to the right neighbor. ++ */ ++ uf_coord->valid = 0; ++ return i + 1; ++ } ++ set_key_offset(&k, get_key_offset(&k) + PAGE_CACHE_SIZE); ++ } ++ ++ return count; ++} ++ ++/** ++ * reiser4_update_extent ++ * @file: ++ * @jnodes: ++ * @count: ++ * @off: ++ * ++ */ ++int reiser4_update_extent(struct inode *inode, jnode *node, loff_t pos, ++ int *plugged_hole) ++{ ++ int result; ++ znode *loaded; ++ uf_coord_t uf_coord; ++ coord_t *coord; ++ lock_handle lh; ++ reiser4_key key; ++ ++ assert("", reiser4_lock_counters()->d_refs == 0); ++ ++ key_by_inode_and_offset_common(inode, pos, &key); ++ ++ init_uf_coord(&uf_coord, &lh); ++ coord = &uf_coord.coord; ++ result = find_file_item_nohint(coord, &lh, &key, ++ ZNODE_WRITE_LOCK, inode); ++ if (IS_CBKERR(result)) { ++ assert("", reiser4_lock_counters()->d_refs == 0); ++ return result; ++ } ++ ++ result = zload(coord->node); ++ BUG_ON(result != 0); ++ loaded = coord->node; ++ ++ if (coord->between == AFTER_UNIT) { ++ /* ++ * append existing extent item with unallocated extent of width ++ * nr_jnodes ++ */ ++ init_coord_extension_extent(&uf_coord, ++ get_key_offset(&key)); ++ result = append_last_extent(&uf_coord, &key, ++ &node, 1); ++ } else if (coord->between == AT_UNIT) { ++ /* ++ * overwrite ++ * not optimal yet. Will be optimized if new write will show ++ * performance win. ++ */ ++ init_coord_extension_extent(&uf_coord, ++ get_key_offset(&key)); ++ result = overwrite_extent(&uf_coord, &key, ++ &node, 1, plugged_hole); ++ } else { ++ /* ++ * there are no items of this file in the tree yet. Create ++ * first item of the file inserting one unallocated extent of ++ * width nr_jnodes ++ */ ++ result = insert_first_extent(&uf_coord, &key, &node, 1, inode); ++ } ++ assert("", result == 1 || result < 0); ++ zrelse(loaded); ++ done_lh(&lh); ++ assert("", reiser4_lock_counters()->d_refs == 0); ++ return (result == 1) ? 0 : result; ++} ++ ++/** ++ * update_extents ++ * @file: ++ * @jnodes: ++ * @count: ++ * @off: ++ * ++ */ ++static int update_extents(struct file *file, struct inode *inode, ++ jnode **jnodes, int count, loff_t pos) ++{ ++ struct hint hint; ++ reiser4_key key; ++ int result; ++ znode *loaded; ++ ++ result = load_file_hint(file, &hint); ++ BUG_ON(result != 0); ++ ++ if (count != 0) ++ /* ++ * count == 0 is special case: expanding truncate ++ */ ++ pos = (loff_t)index_jnode(jnodes[0]) << PAGE_CACHE_SHIFT; ++ key_by_inode_and_offset_common(inode, pos, &key); ++ ++ assert("", reiser4_lock_counters()->d_refs == 0); ++ ++ do { ++ result = find_file_item(&hint, &key, ZNODE_WRITE_LOCK, inode); ++ if (IS_CBKERR(result)) { ++ assert("", reiser4_lock_counters()->d_refs == 0); ++ return result; ++ } ++ ++ result = zload(hint.ext_coord.coord.node); ++ BUG_ON(result != 0); ++ loaded = hint.ext_coord.coord.node; ++ ++ if (hint.ext_coord.coord.between == AFTER_UNIT) { ++ /* ++ * append existing extent item with unallocated extent ++ * of width nr_jnodes ++ */ ++ if (hint.ext_coord.valid == 0) ++ /* NOTE: get statistics on this */ ++ init_coord_extension_extent(&hint.ext_coord, ++ get_key_offset(&key)); ++ result = append_last_extent(&hint.ext_coord, &key, ++ jnodes, count); ++ } else if (hint.ext_coord.coord.between == AT_UNIT) { ++ /* ++ * overwrite ++ * not optimal yet. Will be optimized if new write will ++ * show performance win. ++ */ ++ if (hint.ext_coord.valid == 0) ++ /* NOTE: get statistics on this */ ++ init_coord_extension_extent(&hint.ext_coord, ++ get_key_offset(&key)); ++ result = overwrite_extent(&hint.ext_coord, &key, ++ jnodes, count, NULL); ++ } else { ++ /* ++ * there are no items of this file in the tree ++ * yet. Create first item of the file inserting one ++ * unallocated extent of * width nr_jnodes ++ */ ++ result = insert_first_extent(&hint.ext_coord, &key, ++ jnodes, count, inode); ++ } ++ zrelse(loaded); ++ if (result < 0) { ++ done_lh(hint.ext_coord.lh); ++ break; ++ } ++ ++ jnodes += result; ++ count -= result; ++ set_key_offset(&key, get_key_offset(&key) + result * PAGE_CACHE_SIZE); ++ ++ /* seal and unlock znode */ ++ if (hint.ext_coord.valid) ++ reiser4_set_hint(&hint, &key, ZNODE_WRITE_LOCK); ++ else ++ reiser4_unset_hint(&hint); ++ ++ } while (count > 0); ++ ++ save_file_hint(file, &hint); ++ assert("", reiser4_lock_counters()->d_refs == 0); ++ return result; ++} ++ ++/** ++ * write_extent_reserve_space - reserve space for extent write operation ++ * @inode: ++ * ++ * Estimates and reserves space which may be required for writing ++ * WRITE_GRANULARITY pages of file. ++ */ ++static int write_extent_reserve_space(struct inode *inode) ++{ ++ __u64 count; ++ reiser4_tree *tree; ++ ++ /* ++ * to write WRITE_GRANULARITY pages to a file by extents we have to ++ * reserve disk space for: ++ ++ * 1. find_file_item may have to insert empty node to the tree (empty ++ * leaf node between two extent items). This requires 1 block and ++ * number of blocks which are necessary to perform insertion of an ++ * internal item into twig level. ++ ++ * 2. for each of written pages there might be needed 1 block and ++ * number of blocks which might be necessary to perform insertion of or ++ * paste to an extent item. ++ ++ * 3. stat data update ++ */ ++ tree = reiser4_tree_by_inode(inode); ++ count = estimate_one_insert_item(tree) + ++ WRITE_GRANULARITY * (1 + estimate_one_insert_into_item(tree)) + ++ estimate_one_insert_item(tree); ++ grab_space_enable(); ++ return reiser4_grab_space(count, 0 /* flags */); ++} ++ ++/* ++ * filemap_copy_from_user no longer exists in generic code, because it ++ * is deadlocky (copying from user while holding the page lock is bad). ++ * As a temporary fix for reiser4, just define it here. ++ */ ++static inline size_t ++filemap_copy_from_user(struct page *page, unsigned long offset, ++ const char __user *buf, unsigned bytes) ++{ ++ char *kaddr; ++ int left; ++ ++ kaddr = kmap_atomic(page, KM_USER0); ++ left = __copy_from_user_inatomic_nocache(kaddr + offset, buf, bytes); ++ kunmap_atomic(kaddr, KM_USER0); ++ ++ if (left != 0) { ++ /* Do it the slow way */ ++ kaddr = kmap(page); ++ left = __copy_from_user_nocache(kaddr + offset, buf, bytes); ++ kunmap(page); ++ } ++ return bytes - left; ++} ++ ++/** ++ * reiser4_write_extent - write method of extent item plugin ++ * @file: file to write to ++ * @buf: address of user-space buffer ++ * @count: number of bytes to write ++ * @pos: position in file to write to ++ * ++ */ ++ssize_t reiser4_write_extent(struct file *file, struct inode * inode, ++ const char __user *buf, size_t count, loff_t *pos) ++{ ++ int have_to_update_extent; ++ int nr_pages, nr_dirty; ++ struct page *page; ++ jnode *jnodes[WRITE_GRANULARITY + 1]; ++ unsigned long index; ++ unsigned long end; ++ int i; ++ int to_page, page_off; ++ size_t left, written; ++ int result = 0; ++ ++ if (write_extent_reserve_space(inode)) ++ return RETERR(-ENOSPC); ++ ++ if (count == 0) { ++ /* truncate case */ ++ update_extents(file, inode, jnodes, 0, *pos); ++ return 0; ++ } ++ ++ BUG_ON(get_current_context()->trans->atom != NULL); ++ ++ left = count; ++ index = *pos >> PAGE_CACHE_SHIFT; ++ /* calculate number of pages which are to be written */ ++ end = ((*pos + count - 1) >> PAGE_CACHE_SHIFT); ++ nr_pages = end - index + 1; ++ nr_dirty = 0; ++ assert("", nr_pages <= WRITE_GRANULARITY + 1); ++ ++ /* get pages and jnodes */ ++ for (i = 0; i < nr_pages; i ++) { ++ page = find_or_create_page(inode->i_mapping, index + i, ++ reiser4_ctx_gfp_mask_get()); ++ if (page == NULL) { ++ nr_pages = i; ++ result = RETERR(-ENOMEM); ++ goto out; ++ } ++ ++ jnodes[i] = jnode_of_page(page); ++ if (IS_ERR(jnodes[i])) { ++ unlock_page(page); ++ page_cache_release(page); ++ nr_pages = i; ++ result = RETERR(-ENOMEM); ++ goto out; ++ } ++ /* prevent jnode and page from disconnecting */ ++ JF_SET(jnodes[i], JNODE_WRITE_PREPARED); ++ unlock_page(page); ++ } ++ ++ BUG_ON(get_current_context()->trans->atom != NULL); ++ ++ have_to_update_extent = 0; ++ ++ page_off = (*pos & (PAGE_CACHE_SIZE - 1)); ++ for (i = 0; i < nr_pages; i ++) { ++ to_page = PAGE_CACHE_SIZE - page_off; ++ if (to_page > left) ++ to_page = left; ++ page = jnode_page(jnodes[i]); ++ if (page_offset(page) < inode->i_size && ++ !PageUptodate(page) && to_page != PAGE_CACHE_SIZE) { ++ /* ++ * the above is not optimal for partial write to last ++ * page of file when file size is not at boundary of ++ * page ++ */ ++ lock_page(page); ++ if (!PageUptodate(page)) { ++ result = readpage_unix_file(NULL, page); ++ BUG_ON(result != 0); ++ /* wait for read completion */ ++ lock_page(page); ++ BUG_ON(!PageUptodate(page)); ++ } else ++ result = 0; ++ unlock_page(page); ++ } ++ ++ BUG_ON(get_current_context()->trans->atom != NULL); ++ fault_in_pages_readable(buf, to_page); ++ BUG_ON(get_current_context()->trans->atom != NULL); ++ ++ lock_page(page); ++ if (!PageUptodate(page) && to_page != PAGE_CACHE_SIZE) ++ zero_user_segments(page, 0, page_off, ++ page_off + to_page, ++ PAGE_CACHE_SIZE); ++ ++ written = filemap_copy_from_user(page, page_off, buf, to_page); ++ if (unlikely(written != to_page)) { ++ unlock_page(page); ++ result = RETERR(-EFAULT); ++ break; ++ } ++ ++ flush_dcache_page(page); ++ set_page_dirty_notag(page); ++ unlock_page(page); ++ nr_dirty++; ++ ++ mark_page_accessed(page); ++ SetPageUptodate(page); ++ ++ if (jnodes[i]->blocknr == 0) ++ have_to_update_extent ++; ++ ++ page_off = 0; ++ buf += to_page; ++ left -= to_page; ++ BUG_ON(get_current_context()->trans->atom != NULL); ++ } ++ ++ if (have_to_update_extent) { ++ update_extents(file, inode, jnodes, nr_dirty, *pos); ++ } else { ++ for (i = 0; i < nr_dirty; i ++) { ++ int ret; ++ spin_lock_jnode(jnodes[i]); ++ ret = reiser4_try_capture(jnodes[i], ++ ZNODE_WRITE_LOCK, 0); ++ BUG_ON(ret != 0); ++ jnode_make_dirty_locked(jnodes[i]); ++ spin_unlock_jnode(jnodes[i]); ++ } ++ } ++out: ++ for (i = 0; i < nr_pages; i ++) { ++ page_cache_release(jnode_page(jnodes[i])); ++ JF_CLR(jnodes[i], JNODE_WRITE_PREPARED); ++ jput(jnodes[i]); ++ } ++ ++ /* the only errors handled so far is ENOMEM and ++ EFAULT on copy_from_user */ ++ ++ return (count - left) ? (count - left) : result; ++} ++ ++int reiser4_do_readpage_extent(reiser4_extent * ext, reiser4_block_nr pos, ++ struct page *page) ++{ ++ jnode *j; ++ struct address_space *mapping; ++ unsigned long index; ++ oid_t oid; ++ reiser4_block_nr block; ++ ++ mapping = page->mapping; ++ oid = get_inode_oid(mapping->host); ++ index = page->index; ++ ++ switch (state_of_extent(ext)) { ++ case HOLE_EXTENT: ++ /* ++ * it is possible to have hole page with jnode, if page was ++ * eflushed previously. ++ */ ++ j = jfind(mapping, index); ++ if (j == NULL) { ++ zero_user(page, 0, PAGE_CACHE_SIZE); ++ SetPageUptodate(page); ++ unlock_page(page); ++ return 0; ++ } ++ spin_lock_jnode(j); ++ if (!jnode_page(j)) { ++ jnode_attach_page(j, page); ++ } else { ++ BUG_ON(jnode_page(j) != page); ++ assert("vs-1504", jnode_page(j) == page); ++ } ++ block = *jnode_get_io_block(j); ++ spin_unlock_jnode(j); ++ if (block == 0) { ++ zero_user(page, 0, PAGE_CACHE_SIZE); ++ SetPageUptodate(page); ++ unlock_page(page); ++ jput(j); ++ return 0; ++ } ++ break; ++ ++ case ALLOCATED_EXTENT: ++ j = jnode_of_page(page); ++ if (IS_ERR(j)) ++ return PTR_ERR(j); ++ if (*jnode_get_block(j) == 0) { ++ reiser4_block_nr blocknr; ++ ++ blocknr = extent_get_start(ext) + pos; ++ jnode_set_block(j, &blocknr); ++ } else ++ assert("vs-1403", ++ j->blocknr == extent_get_start(ext) + pos); ++ break; ++ ++ case UNALLOCATED_EXTENT: ++ j = jfind(mapping, index); ++ assert("nikita-2688", j); ++ assert("vs-1426", jnode_page(j) == NULL); ++ ++ spin_lock_jnode(j); ++ jnode_attach_page(j, page); ++ spin_unlock_jnode(j); ++ break; ++ ++ default: ++ warning("vs-957", "wrong extent\n"); ++ return RETERR(-EIO); ++ } ++ ++ BUG_ON(j == 0); ++ reiser4_page_io(page, j, READ, reiser4_ctx_gfp_mask_get()); ++ jput(j); ++ return 0; ++} ++ ++/* Implements plugin->u.item.s.file.read operation for extent items. */ ++int reiser4_read_extent(struct file *file, flow_t *flow, hint_t *hint) ++{ ++ int result; ++ struct page *page; ++ unsigned long cur_page, next_page; ++ unsigned long page_off, count; ++ struct address_space *mapping; ++ loff_t file_off; ++ uf_coord_t *uf_coord; ++ coord_t *coord; ++ struct extent_coord_extension *ext_coord; ++ unsigned long nr_pages; ++ char *kaddr; ++ ++ assert("vs-1353", current_blocksize == PAGE_CACHE_SIZE); ++ assert("vs-572", flow->user == 1); ++ assert("vs-1351", flow->length > 0); ++ ++ uf_coord = &hint->ext_coord; ++ ++ check_uf_coord(uf_coord, NULL); ++ assert("vs-33", uf_coord->lh == &hint->lh); ++ ++ coord = &uf_coord->coord; ++ assert("vs-1119", znode_is_rlocked(coord->node)); ++ assert("vs-1120", znode_is_loaded(coord->node)); ++ assert("vs-1256", coord_matches_key_extent(coord, &flow->key)); ++ ++ mapping = file->f_dentry->d_inode->i_mapping; ++ ext_coord = &uf_coord->extension.extent; ++ ++ /* offset in a file to start read from */ ++ file_off = get_key_offset(&flow->key); ++ /* offset within the page to start read from */ ++ page_off = (unsigned long)(file_off & (PAGE_CACHE_SIZE - 1)); ++ /* bytes which can be read from the page which contains file_off */ ++ count = PAGE_CACHE_SIZE - page_off; ++ ++ /* index of page containing offset read is to start from */ ++ cur_page = (unsigned long)(file_off >> PAGE_CACHE_SHIFT); ++ next_page = cur_page; ++ /* number of pages flow spans over */ ++ nr_pages = ++ ((file_off + flow->length + PAGE_CACHE_SIZE - ++ 1) >> PAGE_CACHE_SHIFT) - cur_page; ++ ++ /* we start having twig node read locked. However, we do not want to ++ keep that lock all the time readahead works. So, set a sel and ++ release twig node. */ ++ reiser4_set_hint(hint, &flow->key, ZNODE_READ_LOCK); ++ /* &hint->lh is done-ed */ ++ ++ do { ++ reiser4_txn_restart_current(); ++ page = read_mapping_page(mapping, cur_page, file); ++ if (IS_ERR(page)) ++ return PTR_ERR(page); ++ lock_page(page); ++ if (!PageUptodate(page)) { ++ unlock_page(page); ++ page_cache_release(page); ++ warning("jmacd-97178", "extent_read: page is not up to date"); ++ return RETERR(-EIO); ++ } ++ mark_page_accessed(page); ++ unlock_page(page); ++ ++ /* If users can be writing to this page using arbitrary virtual ++ addresses, take care about potential aliasing before reading ++ the page on the kernel side. ++ */ ++ if (mapping_writably_mapped(mapping)) ++ flush_dcache_page(page); ++ ++ assert("nikita-3034", reiser4_schedulable()); ++ ++ /* number of bytes which are to be read from the page */ ++ if (count > flow->length) ++ count = flow->length; ++ ++ result = fault_in_pages_writeable(flow->data, count); ++ if (result) { ++ page_cache_release(page); ++ return RETERR(-EFAULT); ++ } ++ ++ kaddr = kmap_atomic(page, KM_USER0); ++ result = __copy_to_user_inatomic(flow->data, ++ kaddr + page_off, count); ++ kunmap_atomic(kaddr, KM_USER0); ++ if (result != 0) { ++ kaddr = kmap(page); ++ result = __copy_to_user(flow->data, kaddr + page_off, count); ++ kunmap(page); ++ if (unlikely(result)) ++ return RETERR(-EFAULT); ++ } ++ ++ page_cache_release(page); ++ ++ /* increase key (flow->key), update user area pointer (flow->data) */ ++ move_flow_forward(flow, count); ++ ++ page_off = 0; ++ cur_page ++; ++ count = PAGE_CACHE_SIZE; ++ nr_pages--; ++ } while (flow->length); ++ ++ return 0; ++} ++ ++/* ++ plugin->s.file.readpage ++ reiser4_read->unix_file_read->page_cache_readahead->reiser4_readpage->unix_file_readpage->extent_readpage ++ or ++ filemap_fault->reiser4_readpage->readpage_unix_file->->readpage_extent ++ ++ At the beginning: coord->node is read locked, zloaded, page is ++ locked, coord is set to existing unit inside of extent item (it is not necessary that coord matches to page->index) ++*/ ++int reiser4_readpage_extent(void *vp, struct page *page) ++{ ++ uf_coord_t *uf_coord = vp; ++ ON_DEBUG(coord_t * coord = &uf_coord->coord); ++ ON_DEBUG(reiser4_key key); ++ ++ assert("vs-1040", PageLocked(page)); ++ assert("vs-1050", !PageUptodate(page)); ++ assert("vs-1039", page->mapping && page->mapping->host); ++ ++ assert("vs-1044", znode_is_loaded(coord->node)); ++ assert("vs-758", item_is_extent(coord)); ++ assert("vs-1046", coord_is_existing_unit(coord)); ++ assert("vs-1045", znode_is_rlocked(coord->node)); ++ assert("vs-1047", ++ page->mapping->host->i_ino == ++ get_key_objectid(item_key_by_coord(coord, &key))); ++ check_uf_coord(uf_coord, NULL); ++ ++ return reiser4_do_readpage_extent( ++ ext_by_ext_coord(uf_coord), ++ uf_coord->extension.extent.pos_in_unit, page); ++} ++ ++/** ++ * get_block_address_extent ++ * @coord: ++ * @block: ++ * @result: ++ * ++ * ++ */ ++int get_block_address_extent(const coord_t *coord, sector_t block, ++ sector_t *result) ++{ ++ reiser4_extent *ext; ++ ++ if (!coord_is_existing_unit(coord)) ++ return RETERR(-EINVAL); ++ ++ ext = extent_by_coord(coord); ++ ++ if (state_of_extent(ext) != ALLOCATED_EXTENT) ++ /* FIXME: bad things may happen if it is unallocated extent */ ++ *result = 0; ++ else { ++ reiser4_key key; ++ ++ unit_key_by_coord(coord, &key); ++ assert("vs-1645", ++ block >= get_key_offset(&key) >> current_blocksize_bits); ++ assert("vs-1646", ++ block < ++ (get_key_offset(&key) >> current_blocksize_bits) + ++ extent_get_width(ext)); ++ *result = ++ extent_get_start(ext) + (block - ++ (get_key_offset(&key) >> ++ current_blocksize_bits)); ++ } ++ return 0; ++} ++ ++/* ++ plugin->u.item.s.file.append_key ++ key of first byte which is the next to last byte by addressed by this extent ++*/ ++reiser4_key *append_key_extent(const coord_t * coord, reiser4_key * key) ++{ ++ item_key_by_coord(coord, key); ++ set_key_offset(key, ++ get_key_offset(key) + reiser4_extent_size(coord, ++ nr_units_extent ++ (coord))); ++ ++ assert("vs-610", get_key_offset(key) ++ && (get_key_offset(key) & (current_blocksize - 1)) == 0); ++ return key; ++} ++ ++/* plugin->u.item.s.file.init_coord_extension */ ++void init_coord_extension_extent(uf_coord_t * uf_coord, loff_t lookuped) ++{ ++ coord_t *coord; ++ struct extent_coord_extension *ext_coord; ++ reiser4_key key; ++ loff_t offset; ++ ++ assert("vs-1295", uf_coord->valid == 0); ++ ++ coord = &uf_coord->coord; ++ assert("vs-1288", coord_is_iplug_set(coord)); ++ assert("vs-1327", znode_is_loaded(coord->node)); ++ ++ if (coord->between != AFTER_UNIT && coord->between != AT_UNIT) ++ return; ++ ++ ext_coord = &uf_coord->extension.extent; ++ ext_coord->nr_units = nr_units_extent(coord); ++ ext_coord->ext_offset = ++ (char *)extent_by_coord(coord) - zdata(coord->node); ++ ext_coord->width = extent_get_width(extent_by_coord(coord)); ++ ON_DEBUG(ext_coord->extent = *extent_by_coord(coord)); ++ uf_coord->valid = 1; ++ ++ /* pos_in_unit is the only uninitialized field in extended coord */ ++ if (coord->between == AFTER_UNIT) { ++ assert("vs-1330", ++ coord->unit_pos == nr_units_extent(coord) - 1); ++ ++ ext_coord->pos_in_unit = ext_coord->width - 1; ++ } else { ++ /* AT_UNIT */ ++ unit_key_by_coord(coord, &key); ++ offset = get_key_offset(&key); ++ ++ assert("vs-1328", offset <= lookuped); ++ assert("vs-1329", ++ lookuped < ++ offset + ext_coord->width * current_blocksize); ++ ext_coord->pos_in_unit = ++ ((lookuped - offset) >> current_blocksize_bits); ++ } ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/extent_flush_ops.c linux-2.6.30/fs/reiser4/plugin/item/extent_flush_ops.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/extent_flush_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/extent_flush_ops.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1028 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "item.h" ++#include "../../tree.h" ++#include "../../jnode.h" ++#include "../../super.h" ++#include "../../flush.h" ++#include "../../carry.h" ++#include "../object.h" ++ ++#include <linux/pagemap.h> ++ ++static reiser4_block_nr extent_unit_start(const coord_t * item); ++ ++/* Return either first or last extent (depending on @side) of the item ++ @coord is set to. Set @pos_in_unit either to first or to last block ++ of extent. */ ++static reiser4_extent *extent_utmost_ext(const coord_t * coord, sideof side, ++ reiser4_block_nr * pos_in_unit) ++{ ++ reiser4_extent *ext; ++ ++ if (side == LEFT_SIDE) { ++ /* get first extent of item */ ++ ext = extent_item(coord); ++ *pos_in_unit = 0; ++ } else { ++ /* get last extent of item and last position within it */ ++ assert("vs-363", side == RIGHT_SIDE); ++ ext = extent_item(coord) + coord_last_unit_pos(coord); ++ *pos_in_unit = extent_get_width(ext) - 1; ++ } ++ ++ return ext; ++} ++ ++/* item_plugin->f.utmost_child */ ++/* Return the child. Coord is set to extent item. Find jnode corresponding ++ either to first or to last unformatted node pointed by the item */ ++int utmost_child_extent(const coord_t * coord, sideof side, jnode ** childp) ++{ ++ reiser4_extent *ext; ++ reiser4_block_nr pos_in_unit; ++ ++ ext = extent_utmost_ext(coord, side, &pos_in_unit); ++ ++ switch (state_of_extent(ext)) { ++ case HOLE_EXTENT: ++ *childp = NULL; ++ return 0; ++ case ALLOCATED_EXTENT: ++ case UNALLOCATED_EXTENT: ++ break; ++ default: ++ /* this should never happen */ ++ assert("vs-1417", 0); ++ } ++ ++ { ++ reiser4_key key; ++ reiser4_tree *tree; ++ unsigned long index; ++ ++ if (side == LEFT_SIDE) { ++ /* get key of first byte addressed by the extent */ ++ item_key_by_coord(coord, &key); ++ } else { ++ /* get key of byte which next after last byte addressed by the extent */ ++ append_key_extent(coord, &key); ++ } ++ ++ assert("vs-544", ++ (get_key_offset(&key) >> PAGE_CACHE_SHIFT) < ~0ul); ++ /* index of first or last (depending on @side) page addressed ++ by the extent */ ++ index = ++ (unsigned long)(get_key_offset(&key) >> PAGE_CACHE_SHIFT); ++ if (side == RIGHT_SIDE) ++ index--; ++ ++ tree = coord->node->zjnode.tree; ++ *childp = jlookup(tree, get_key_objectid(&key), index); ++ } ++ ++ return 0; ++} ++ ++/* item_plugin->f.utmost_child_real_block */ ++/* Return the child's block, if allocated. */ ++int ++utmost_child_real_block_extent(const coord_t * coord, sideof side, ++ reiser4_block_nr * block) ++{ ++ reiser4_extent *ext; ++ ++ ext = extent_by_coord(coord); ++ ++ switch (state_of_extent(ext)) { ++ case ALLOCATED_EXTENT: ++ *block = extent_get_start(ext); ++ if (side == RIGHT_SIDE) ++ *block += extent_get_width(ext) - 1; ++ break; ++ case HOLE_EXTENT: ++ case UNALLOCATED_EXTENT: ++ *block = 0; ++ break; ++ default: ++ /* this should never happen */ ++ assert("vs-1418", 0); ++ } ++ ++ return 0; ++} ++ ++/* item_plugin->f.scan */ ++/* Performs leftward scanning starting from an unformatted node and its parent coordinate. ++ This scan continues, advancing the parent coordinate, until either it encounters a ++ formatted child or it finishes scanning this node. ++ ++ If unallocated, the entire extent must be dirty and in the same atom. (Actually, I'm ++ not sure this is last property (same atom) is enforced, but it should be the case since ++ one atom must write the parent and the others must read the parent, thus fusing?). In ++ any case, the code below asserts this case for unallocated extents. Unallocated ++ extents are thus optimized because we can skip to the endpoint when scanning. ++ ++ It returns control to reiser4_scan_extent, handles these terminating conditions, ++ e.g., by loading the next twig. ++*/ ++int reiser4_scan_extent(flush_scan * scan) ++{ ++ coord_t coord; ++ jnode *neighbor; ++ unsigned long scan_index, unit_index, unit_width, scan_max, scan_dist; ++ reiser4_block_nr unit_start; ++ __u64 oid; ++ reiser4_key key; ++ int ret = 0, allocated, incr; ++ reiser4_tree *tree; ++ ++ if (!JF_ISSET(scan->node, JNODE_DIRTY)) { ++ scan->stop = 1; ++ return 0; /* Race with truncate, this node is already ++ * truncated. */ ++ } ++ ++ coord_dup(&coord, &scan->parent_coord); ++ ++ assert("jmacd-1404", !reiser4_scan_finished(scan)); ++ assert("jmacd-1405", jnode_get_level(scan->node) == LEAF_LEVEL); ++ assert("jmacd-1406", jnode_is_unformatted(scan->node)); ++ ++ /* The scan_index variable corresponds to the current page index of the ++ unformatted block scan position. */ ++ scan_index = index_jnode(scan->node); ++ ++ assert("jmacd-7889", item_is_extent(&coord)); ++ ++ repeat: ++ /* objectid of file */ ++ oid = get_key_objectid(item_key_by_coord(&coord, &key)); ++ ++ allocated = !extent_is_unallocated(&coord); ++ /* Get the values of this extent unit: */ ++ unit_index = extent_unit_index(&coord); ++ unit_width = extent_unit_width(&coord); ++ unit_start = extent_unit_start(&coord); ++ ++ assert("jmacd-7187", unit_width > 0); ++ assert("jmacd-7188", scan_index >= unit_index); ++ assert("jmacd-7189", scan_index <= unit_index + unit_width - 1); ++ ++ /* Depending on the scan direction, we set different maximum values for scan_index ++ (scan_max) and the number of nodes that would be passed if the scan goes the ++ entire way (scan_dist). Incr is an integer reflecting the incremental ++ direction of scan_index. */ ++ if (reiser4_scanning_left(scan)) { ++ scan_max = unit_index; ++ scan_dist = scan_index - unit_index; ++ incr = -1; ++ } else { ++ scan_max = unit_index + unit_width - 1; ++ scan_dist = scan_max - unit_index; ++ incr = +1; ++ } ++ ++ tree = coord.node->zjnode.tree; ++ ++ /* If the extent is allocated we have to check each of its blocks. If the extent ++ is unallocated we can skip to the scan_max. */ ++ if (allocated) { ++ do { ++ neighbor = jlookup(tree, oid, scan_index); ++ if (neighbor == NULL) ++ goto stop_same_parent; ++ ++ if (scan->node != neighbor ++ && !reiser4_scan_goto(scan, neighbor)) { ++ /* @neighbor was jput() by reiser4_scan_goto */ ++ goto stop_same_parent; ++ } ++ ++ ret = scan_set_current(scan, neighbor, 1, &coord); ++ if (ret != 0) { ++ goto exit; ++ } ++ ++ /* reference to @neighbor is stored in @scan, no need ++ to jput(). */ ++ scan_index += incr; ++ ++ } while (incr + scan_max != scan_index); ++ ++ } else { ++ /* Optimized case for unallocated extents, skip to the end. */ ++ neighbor = jlookup(tree, oid, scan_max /*index */ ); ++ if (neighbor == NULL) { ++ /* Race with truncate */ ++ scan->stop = 1; ++ ret = 0; ++ goto exit; ++ } ++ ++ assert("zam-1043", ++ reiser4_blocknr_is_fake(jnode_get_block(neighbor))); ++ ++ ret = scan_set_current(scan, neighbor, scan_dist, &coord); ++ if (ret != 0) { ++ goto exit; ++ } ++ } ++ ++ if (coord_sideof_unit(&coord, scan->direction) == 0 ++ && item_is_extent(&coord)) { ++ /* Continue as long as there are more extent units. */ ++ ++ scan_index = ++ extent_unit_index(&coord) + ++ (reiser4_scanning_left(scan) ? ++ extent_unit_width(&coord) - 1 : 0); ++ goto repeat; ++ } ++ ++ if (0) { ++ stop_same_parent: ++ ++ /* If we are scanning left and we stop in the middle of an allocated ++ extent, we know the preceder immediately.. */ ++ /* middle of extent is (scan_index - unit_index) != 0. */ ++ if (reiser4_scanning_left(scan) && ++ (scan_index - unit_index) != 0) { ++ /* FIXME(B): Someone should step-through and verify that this preceder ++ calculation is indeed correct. */ ++ /* @unit_start is starting block (number) of extent ++ unit. Flush stopped at the @scan_index block from ++ the beginning of the file, which is (scan_index - ++ unit_index) block within extent. ++ */ ++ if (unit_start) { ++ /* skip preceder update when we are at hole */ ++ scan->preceder_blk = ++ unit_start + scan_index - unit_index; ++ check_preceder(scan->preceder_blk); ++ } ++ } ++ ++ /* In this case, we leave coord set to the parent of scan->node. */ ++ scan->stop = 1; ++ ++ } else { ++ /* In this case, we are still scanning, coord is set to the next item which is ++ either off-the-end of the node or not an extent. */ ++ assert("jmacd-8912", scan->stop == 0); ++ assert("jmacd-7812", ++ (coord_is_after_sideof_unit(&coord, scan->direction) ++ || !item_is_extent(&coord))); ++ } ++ ++ ret = 0; ++ exit: ++ return ret; ++} ++ ++/* ask block allocator for some blocks */ ++static void extent_allocate_blocks(reiser4_blocknr_hint *preceder, ++ reiser4_block_nr wanted_count, ++ reiser4_block_nr *first_allocated, ++ reiser4_block_nr *allocated, ++ block_stage_t block_stage) ++{ ++ *allocated = wanted_count; ++ preceder->max_dist = 0; /* scan whole disk, if needed */ ++ ++ /* that number of blocks (wanted_count) is either in UNALLOCATED or in GRABBED */ ++ preceder->block_stage = block_stage; ++ ++ /* FIXME: we do not handle errors here now */ ++ check_me("vs-420", ++ reiser4_alloc_blocks(preceder, first_allocated, allocated, ++ BA_PERMANENT) == 0); ++ /* update flush_pos's preceder to last allocated block number */ ++ preceder->blk = *first_allocated + *allocated - 1; ++} ++ ++/* when on flush time unallocated extent is to be replaced with allocated one it may happen that one unallocated extent ++ will have to be replaced with set of allocated extents. In this case insert_into_item will be called which may have ++ to add new nodes into tree. Space for that is taken from inviolable reserve (5%). */ ++static reiser4_block_nr reserve_replace(void) ++{ ++ reiser4_block_nr grabbed, needed; ++ ++ grabbed = get_current_context()->grabbed_blocks; ++ needed = estimate_one_insert_into_item(current_tree); ++ check_me("vpf-340", !reiser4_grab_space_force(needed, BA_RESERVED)); ++ return grabbed; ++} ++ ++static void free_replace_reserved(reiser4_block_nr grabbed) ++{ ++ reiser4_context *ctx; ++ ++ ctx = get_current_context(); ++ grabbed2free(ctx, get_super_private(ctx->super), ++ ctx->grabbed_blocks - grabbed); ++} ++ ++/* Block offset of first block addressed by unit */ ++__u64 extent_unit_index(const coord_t * item) ++{ ++ reiser4_key key; ++ ++ assert("vs-648", coord_is_existing_unit(item)); ++ unit_key_by_coord(item, &key); ++ return get_key_offset(&key) >> current_blocksize_bits; ++} ++ ++/* AUDIT shouldn't return value be of reiser4_block_nr type? ++ Josh's answer: who knows? Is a "number of blocks" the same type as "block offset"? */ ++__u64 extent_unit_width(const coord_t * item) ++{ ++ assert("vs-649", coord_is_existing_unit(item)); ++ return width_by_coord(item); ++} ++ ++/* Starting block location of this unit */ ++static reiser4_block_nr extent_unit_start(const coord_t * item) ++{ ++ return extent_get_start(extent_by_coord(item)); ++} ++ ++/** ++ * split_allocated_extent - ++ * @coord: ++ * @pos_in_unit: ++ * ++ * replace allocated extent with two allocated extents ++ */ ++static int split_allocated_extent(coord_t *coord, reiser4_block_nr pos_in_unit) ++{ ++ int result; ++ struct replace_handle *h; ++ reiser4_extent *ext; ++ reiser4_block_nr grabbed; ++ ++ ext = extent_by_coord(coord); ++ assert("vs-1410", state_of_extent(ext) == ALLOCATED_EXTENT); ++ assert("vs-1411", extent_get_width(ext) > pos_in_unit); ++ ++ h = kmalloc(sizeof(*h), reiser4_ctx_gfp_mask_get()); ++ if (h == NULL) ++ return RETERR(-ENOMEM); ++ h->coord = coord; ++ h->lh = znode_lh(coord->node); ++ h->pkey = &h->key; ++ unit_key_by_coord(coord, h->pkey); ++ set_key_offset(h->pkey, ++ (get_key_offset(h->pkey) + ++ pos_in_unit * current_blocksize)); ++ reiser4_set_extent(&h->overwrite, extent_get_start(ext), ++ pos_in_unit); ++ reiser4_set_extent(&h->new_extents[0], ++ extent_get_start(ext) + pos_in_unit, ++ extent_get_width(ext) - pos_in_unit); ++ h->nr_new_extents = 1; ++ h->flags = COPI_DONT_SHIFT_LEFT; ++ h->paste_key = h->key; ++ ++ /* reserve space for extent unit paste, @grabbed is reserved before */ ++ grabbed = reserve_replace(); ++ result = reiser4_replace_extent(h, 0 /* leave @coord set to overwritten ++ extent */); ++ /* restore reserved */ ++ free_replace_reserved(grabbed); ++ kfree(h); ++ return result; ++} ++ ++/* replace extent @ext by extent @replace. Try to merge @replace with previous extent of the item (if there is ++ one). Return 1 if it succeeded, 0 - otherwise */ ++static int try_to_merge_with_left(coord_t *coord, reiser4_extent *ext, ++ reiser4_extent *replace) ++{ ++ assert("vs-1415", extent_by_coord(coord) == ext); ++ ++ if (coord->unit_pos == 0 ++ || state_of_extent(ext - 1) != ALLOCATED_EXTENT) ++ /* @ext either does not exist or is not allocated extent */ ++ return 0; ++ if (extent_get_start(ext - 1) + extent_get_width(ext - 1) != ++ extent_get_start(replace)) ++ return 0; ++ ++ /* we can glue, widen previous unit */ ++ extent_set_width(ext - 1, ++ extent_get_width(ext - 1) + extent_get_width(replace)); ++ ++ if (extent_get_width(ext) != extent_get_width(replace)) { ++ /* make current extent narrower */ ++ if (state_of_extent(ext) == ALLOCATED_EXTENT) ++ extent_set_start(ext, ++ extent_get_start(ext) + ++ extent_get_width(replace)); ++ extent_set_width(ext, ++ extent_get_width(ext) - ++ extent_get_width(replace)); ++ } else { ++ /* current extent completely glued with its left neighbor, remove it */ ++ coord_t from, to; ++ ++ coord_dup(&from, coord); ++ from.unit_pos = nr_units_extent(coord) - 1; ++ coord_dup(&to, &from); ++ ++ /* currently cut from extent can cut either from the beginning or from the end. Move place which got ++ freed after unit removal to end of item */ ++ memmove(ext, ext + 1, ++ (from.unit_pos - ++ coord->unit_pos) * sizeof(reiser4_extent)); ++ /* wipe part of item which is going to be cut, so that node_check will not be confused */ ++ cut_node_content(&from, &to, NULL, NULL, NULL); ++ } ++ znode_make_dirty(coord->node); ++ /* move coord back */ ++ coord->unit_pos--; ++ return 1; ++} ++ ++/** ++ * conv_extent - replace extent with 2 ones ++ * @coord: coordinate of extent to be replaced ++ * @replace: extent to overwrite the one @coord is set to ++ * ++ * Overwrites extent @coord is set to and paste one extent unit after ++ * overwritten one if @replace is shorter than initial extent ++ */ ++static int conv_extent(coord_t *coord, reiser4_extent *replace) ++{ ++ int result; ++ struct replace_handle *h; ++ reiser4_extent *ext; ++ reiser4_block_nr start, width, new_width; ++ reiser4_block_nr grabbed; ++ extent_state state; ++ ++ ext = extent_by_coord(coord); ++ state = state_of_extent(ext); ++ start = extent_get_start(ext); ++ width = extent_get_width(ext); ++ new_width = extent_get_width(replace); ++ ++ assert("vs-1458", (state == UNALLOCATED_EXTENT || ++ state == ALLOCATED_EXTENT)); ++ assert("vs-1459", width >= new_width); ++ ++ if (try_to_merge_with_left(coord, ext, replace)) { ++ /* merged @replace with left neighbor. Current unit is either ++ removed or narrowed */ ++ return 0; ++ } ++ ++ if (width == new_width) { ++ /* replace current extent with @replace */ ++ *ext = *replace; ++ znode_make_dirty(coord->node); ++ return 0; ++ } ++ ++ h = kmalloc(sizeof(*h), reiser4_ctx_gfp_mask_get()); ++ if (h == NULL) ++ return RETERR(-ENOMEM); ++ h->coord = coord; ++ h->lh = znode_lh(coord->node); ++ h->pkey = &h->key; ++ unit_key_by_coord(coord, h->pkey); ++ set_key_offset(h->pkey, ++ (get_key_offset(h->pkey) + new_width * current_blocksize)); ++ h->overwrite = *replace; ++ ++ /* replace @ext with @replace and padding extent */ ++ reiser4_set_extent(&h->new_extents[0], ++ (state == ALLOCATED_EXTENT) ? ++ (start + new_width) : ++ UNALLOCATED_EXTENT_START, ++ width - new_width); ++ h->nr_new_extents = 1; ++ h->flags = COPI_DONT_SHIFT_LEFT; ++ h->paste_key = h->key; ++ ++ /* reserve space for extent unit paste, @grabbed is reserved before */ ++ grabbed = reserve_replace(); ++ result = reiser4_replace_extent(h, 0 /* leave @coord set to overwritten ++ extent */); ++ ++ /* restore reserved */ ++ free_replace_reserved(grabbed); ++ kfree(h); ++ return result; ++} ++ ++/** ++ * assign_real_blocknrs ++ * @flush_pos: ++ * @oid: objectid of file jnodes to assign block number to belongs to ++ * @index: first jnode on the range ++ * @count: number of jnodes to assign block numbers to ++ * @first: start of allocated block range ++ * ++ * Assigns block numbers to each of @count jnodes. Index of first jnode is ++ * @index. Jnodes get lookuped with jlookup. ++ */ ++static void assign_real_blocknrs(flush_pos_t *flush_pos, oid_t oid, ++ unsigned long index, reiser4_block_nr count, ++ reiser4_block_nr first) ++{ ++ unsigned long i; ++ reiser4_tree *tree; ++ txn_atom *atom; ++ int nr; ++ ++ atom = atom_locked_by_fq(flush_pos->fq); ++ assert("vs-1468", atom); ++ BUG_ON(atom == NULL); ++ ++ nr = 0; ++ tree = current_tree; ++ for (i = 0; i < count; ++i, ++index) { ++ jnode *node; ++ ++ node = jlookup(tree, oid, index); ++ assert("", node != NULL); ++ BUG_ON(node == NULL); ++ ++ spin_lock_jnode(node); ++ assert("", !jnode_is_flushprepped(node)); ++ assert("vs-1475", node->atom == atom); ++ assert("vs-1476", atomic_read(&node->x_count) > 0); ++ ++ JF_CLR(node, JNODE_FLUSH_RESERVED); ++ jnode_set_block(node, &first); ++ unformatted_make_reloc(node, flush_pos->fq); ++ ON_DEBUG(count_jnode(node->atom, node, NODE_LIST(node), ++ FQ_LIST, 0)); ++ spin_unlock_jnode(node); ++ first++; ++ ++ atomic_dec(&node->x_count); ++ nr ++; ++ } ++ ++ spin_unlock_atom(atom); ++ return; ++} ++ ++/** ++ * make_node_ovrwr - assign node to overwrite set ++ * @jnodes: overwrite set list head ++ * @node: jnode to belong to overwrite set ++ * ++ * Sets OVRWR jnode state bit and puts @node to the end of list head @jnodes ++ * which is an accumulator for nodes before they get to overwrite set list of ++ * atom. ++ */ ++static void make_node_ovrwr(struct list_head *jnodes, jnode *node) ++{ ++ spin_lock_jnode(node); ++ ++ assert("zam-917", !JF_ISSET(node, JNODE_RELOC)); ++ assert("zam-918", !JF_ISSET(node, JNODE_OVRWR)); ++ ++ JF_SET(node, JNODE_OVRWR); ++ list_move_tail(&node->capture_link, jnodes); ++ ON_DEBUG(count_jnode(node->atom, node, DIRTY_LIST, OVRWR_LIST, 0)); ++ ++ spin_unlock_jnode(node); ++} ++ ++/** ++ * mark_jnodes_overwrite - put bunch of jnodes to overwrite set ++ * @flush_pos: flush position ++ * @oid: objectid of file jnodes belong to ++ * @index: starting index ++ * @width: extent width ++ * ++ * Puts nodes of one extent (file objectid @oid, extent width @width) to atom's ++ * overwrite set. Starting from the one with index @index. If end of slum is ++ * detected (node is not found or flushprepped) - stop iterating and set flush ++ * position's state to POS_INVALID. ++ */ ++static void mark_jnodes_overwrite(flush_pos_t *flush_pos, oid_t oid, ++ unsigned long index, reiser4_block_nr width) ++{ ++ unsigned long i; ++ reiser4_tree *tree; ++ jnode *node; ++ txn_atom *atom; ++ LIST_HEAD(jnodes); ++ ++ tree = current_tree; ++ ++ atom = atom_locked_by_fq(reiser4_pos_fq(flush_pos)); ++ assert("vs-1478", atom); ++ ++ for (i = flush_pos->pos_in_unit; i < width; i++, index++) { ++ node = jlookup(tree, oid, index); ++ if (!node) { ++ flush_pos->state = POS_INVALID; ++ break; ++ } ++ if (jnode_check_flushprepped(node)) { ++ flush_pos->state = POS_INVALID; ++ atomic_dec(&node->x_count); ++ break; ++ } ++ if (node->atom != atom) { ++ flush_pos->state = POS_INVALID; ++ atomic_dec(&node->x_count); ++ break; ++ } ++ make_node_ovrwr(&jnodes, node); ++ atomic_dec(&node->x_count); ++ } ++ ++ list_splice_init(&jnodes, ATOM_OVRWR_LIST(atom)->prev); ++ spin_unlock_atom(atom); ++} ++ ++/** ++ * allocated_extent_slum_size ++ * @flush_pos: ++ * @oid: ++ * @index: ++ * @count: ++ * ++ * ++ */ ++static int allocated_extent_slum_size(flush_pos_t *flush_pos, oid_t oid, ++ unsigned long index, unsigned long count) ++{ ++ unsigned long i; ++ reiser4_tree *tree; ++ txn_atom *atom; ++ int nr; ++ ++ atom = atom_locked_by_fq(reiser4_pos_fq(flush_pos)); ++ assert("vs-1468", atom); ++ ++ nr = 0; ++ tree = current_tree; ++ for (i = 0; i < count; ++i, ++index) { ++ jnode *node; ++ ++ node = jlookup(tree, oid, index); ++ if (!node) ++ break; ++ ++ if (jnode_check_flushprepped(node)) { ++ atomic_dec(&node->x_count); ++ break; ++ } ++ ++ if (node->atom != atom) { ++ /* ++ * this is possible on overwrite: extent_write may ++ * capture several unformatted nodes without capturing ++ * any formatted nodes. ++ */ ++ atomic_dec(&node->x_count); ++ break; ++ } ++ ++ assert("vs-1476", atomic_read(&node->x_count) > 1); ++ atomic_dec(&node->x_count); ++ nr ++; ++ } ++ ++ spin_unlock_atom(atom); ++ return nr; ++} ++ ++/** ++ * alloc_extent ++ * @flush_pos: ++ * ++ * ++ * this is called by handle_pos_on_twig to proceed extent unit flush_pos->coord ++ * is set to. It is to prepare for flushing sequence of not flushprepped nodes ++ * (slum). It supposes that slum starts at flush_pos->pos_in_unit position ++ * within the extent. Slum gets to relocate set if flush_pos->leaf_relocate is ++ * set to 1 and to overwrite set otherwise ++ */ ++int reiser4_alloc_extent(flush_pos_t *flush_pos) ++{ ++ coord_t *coord; ++ reiser4_extent *ext; ++ reiser4_extent replace_ext; ++ oid_t oid; ++ reiser4_block_nr protected; ++ reiser4_block_nr start; ++ __u64 index; ++ __u64 width; ++ extent_state state; ++ int result; ++ reiser4_block_nr first_allocated; ++ __u64 allocated; ++ reiser4_key key; ++ block_stage_t block_stage; ++ ++ assert("vs-1468", flush_pos->state == POS_ON_EPOINT); ++ assert("vs-1469", coord_is_existing_unit(&flush_pos->coord) ++ && item_is_extent(&flush_pos->coord)); ++ ++ coord = &flush_pos->coord; ++ ++ ext = extent_by_coord(coord); ++ state = state_of_extent(ext); ++ if (state == HOLE_EXTENT) { ++ flush_pos->state = POS_INVALID; ++ return 0; ++ } ++ ++ item_key_by_coord(coord, &key); ++ oid = get_key_objectid(&key); ++ index = extent_unit_index(coord) + flush_pos->pos_in_unit; ++ start = extent_get_start(ext); ++ width = extent_get_width(ext); ++ ++ assert("vs-1457", width > flush_pos->pos_in_unit); ++ ++ if (flush_pos->leaf_relocate || state == UNALLOCATED_EXTENT) { ++ /* relocate */ ++ if (flush_pos->pos_in_unit) { ++ /* split extent unit into two */ ++ result = ++ split_allocated_extent(coord, ++ flush_pos->pos_in_unit); ++ flush_pos->pos_in_unit = 0; ++ return result; ++ } ++ ++ /* limit number of nodes to allocate */ ++ if (flush_pos->nr_to_write < width) ++ width = flush_pos->nr_to_write; ++ ++ if (state == ALLOCATED_EXTENT) { ++ /* ++ * all protected nodes are not flushprepped, therefore ++ * they are counted as flush_reserved ++ */ ++ block_stage = BLOCK_FLUSH_RESERVED; ++ protected = allocated_extent_slum_size(flush_pos, oid, ++ index, width); ++ if (protected == 0) { ++ flush_pos->state = POS_INVALID; ++ flush_pos->pos_in_unit = 0; ++ return 0; ++ } ++ } else { ++ block_stage = BLOCK_UNALLOCATED; ++ protected = width; ++ } ++ ++ /* ++ * look at previous unit if possible. If it is allocated, make ++ * preceder more precise ++ */ ++ if (coord->unit_pos && ++ (state_of_extent(ext - 1) == ALLOCATED_EXTENT)) ++ reiser4_pos_hint(flush_pos)->blk = ++ extent_get_start(ext - 1) + ++ extent_get_width(ext - 1); ++ ++ /* allocate new block numbers for protected nodes */ ++ extent_allocate_blocks(reiser4_pos_hint(flush_pos), ++ protected, ++ &first_allocated, &allocated, ++ block_stage); ++ ++ if (state == ALLOCATED_EXTENT) ++ /* ++ * on relocating - free nodes which are going to be ++ * relocated ++ */ ++ reiser4_dealloc_blocks(&start, &allocated, ++ BLOCK_ALLOCATED, BA_DEFER); ++ ++ /* assign new block numbers to protected nodes */ ++ assign_real_blocknrs(flush_pos, oid, index, allocated, first_allocated); ++ ++ /* prepare extent which will replace current one */ ++ reiser4_set_extent(&replace_ext, first_allocated, allocated); ++ ++ /* adjust extent item */ ++ result = conv_extent(coord, &replace_ext); ++ if (result != 0 && result != -ENOMEM) { ++ warning("vs-1461", ++ "Failed to allocate extent. Should not happen\n"); ++ return result; ++ } ++ ++ /* ++ * break flush: we prepared for flushing as many blocks as we ++ * were asked for ++ */ ++ if (flush_pos->nr_to_write == allocated) ++ flush_pos->state = POS_INVALID; ++ } else { ++ /* overwrite */ ++ mark_jnodes_overwrite(flush_pos, oid, index, width); ++ } ++ flush_pos->pos_in_unit = 0; ++ return 0; ++} ++ ++/* if @key is glueable to the item @coord is set to */ ++static int must_insert(const coord_t *coord, const reiser4_key *key) ++{ ++ reiser4_key last; ++ ++ if (item_id_by_coord(coord) == EXTENT_POINTER_ID ++ && keyeq(append_key_extent(coord, &last), key)) ++ return 0; ++ return 1; ++} ++ ++/* copy extent @copy to the end of @node. It may have to either insert new item after the last one, or append last item, ++ or modify last unit of last item to have greater width */ ++static int put_unit_to_end(znode *node, const reiser4_key *key, ++ reiser4_extent *copy_ext) ++{ ++ int result; ++ coord_t coord; ++ cop_insert_flag flags; ++ reiser4_extent *last_ext; ++ reiser4_item_data data; ++ ++ /* set coord after last unit in an item */ ++ coord_init_last_unit(&coord, node); ++ coord.between = AFTER_UNIT; ++ ++ flags = ++ COPI_DONT_SHIFT_LEFT | COPI_DONT_SHIFT_RIGHT | COPI_DONT_ALLOCATE; ++ if (must_insert(&coord, key)) { ++ result = ++ insert_by_coord(&coord, init_new_extent(&data, copy_ext, 1), ++ key, NULL /*lh */ , flags); ++ ++ } else { ++ /* try to glue with last unit */ ++ last_ext = extent_by_coord(&coord); ++ if (state_of_extent(last_ext) && ++ extent_get_start(last_ext) + extent_get_width(last_ext) == ++ extent_get_start(copy_ext)) { ++ /* widen last unit of node */ ++ extent_set_width(last_ext, ++ extent_get_width(last_ext) + ++ extent_get_width(copy_ext)); ++ znode_make_dirty(node); ++ return 0; ++ } ++ ++ /* FIXME: put an assertion here that we can not merge last unit in @node and new unit */ ++ result = ++ insert_into_item(&coord, NULL /*lh */ , key, ++ init_new_extent(&data, copy_ext, 1), ++ flags); ++ } ++ ++ assert("vs-438", result == 0 || result == -E_NODE_FULL); ++ return result; ++} ++ ++/* @coord is set to extent unit */ ++squeeze_result squalloc_extent(znode *left, const coord_t *coord, ++ flush_pos_t *flush_pos, ++ reiser4_key *stop_key) ++{ ++ reiser4_extent *ext; ++ __u64 index; ++ __u64 width; ++ reiser4_block_nr start; ++ extent_state state; ++ oid_t oid; ++ reiser4_block_nr first_allocated; ++ __u64 allocated; ++ __u64 protected; ++ reiser4_extent copy_extent; ++ reiser4_key key; ++ int result; ++ block_stage_t block_stage; ++ ++ assert("vs-1457", flush_pos->pos_in_unit == 0); ++ assert("vs-1467", coord_is_leftmost_unit(coord)); ++ assert("vs-1467", item_is_extent(coord)); ++ ++ ext = extent_by_coord(coord); ++ index = extent_unit_index(coord); ++ start = extent_get_start(ext); ++ width = extent_get_width(ext); ++ state = state_of_extent(ext); ++ unit_key_by_coord(coord, &key); ++ oid = get_key_objectid(&key); ++ ++ if ((flush_pos->leaf_relocate && state == ALLOCATED_EXTENT) || ++ (state == UNALLOCATED_EXTENT)) { ++ /* relocate */ ++ if (state == ALLOCATED_EXTENT) { ++ /* all protected nodes are not flushprepped, therefore ++ * they are counted as flush_reserved */ ++ block_stage = BLOCK_FLUSH_RESERVED; ++ protected = allocated_extent_slum_size(flush_pos, oid, ++ index, width); ++ if (protected == 0) { ++ flush_pos->state = POS_INVALID; ++ flush_pos->pos_in_unit = 0; ++ return 0; ++ } ++ } else { ++ block_stage = BLOCK_UNALLOCATED; ++ protected = width; ++ } ++ ++ /* ++ * look at previous unit if possible. If it is allocated, make ++ * preceder more precise ++ */ ++ if (coord->unit_pos && ++ (state_of_extent(ext - 1) == ALLOCATED_EXTENT)) ++ reiser4_pos_hint(flush_pos)->blk = ++ extent_get_start(ext - 1) + ++ extent_get_width(ext - 1); ++ ++ /* allocate new block numbers for protected nodes */ ++ extent_allocate_blocks(reiser4_pos_hint(flush_pos), ++ protected, ++ &first_allocated, &allocated, ++ block_stage); ++ ++ /* prepare extent which will be copied to left */ ++ reiser4_set_extent(©_extent, first_allocated, allocated); ++ ++ result = put_unit_to_end(left, &key, ©_extent); ++ if (result == -E_NODE_FULL) { ++ int target_block_stage; ++ ++ /* free blocks which were just allocated */ ++ target_block_stage = ++ (state == ++ ALLOCATED_EXTENT) ? BLOCK_FLUSH_RESERVED : ++ BLOCK_UNALLOCATED; ++ reiser4_dealloc_blocks(&first_allocated, &allocated, ++ target_block_stage, ++ BA_PERMANENT); ++ ++ /* rewind the preceder. */ ++ flush_pos->preceder.blk = first_allocated; ++ check_preceder(flush_pos->preceder.blk); ++ ++ return SQUEEZE_TARGET_FULL; ++ } ++ ++ if (state == ALLOCATED_EXTENT) { ++ /* free nodes which were relocated */ ++ reiser4_dealloc_blocks(&start, &allocated, ++ BLOCK_ALLOCATED, BA_DEFER); ++ } ++ ++ /* assign new block numbers to protected nodes */ ++ assign_real_blocknrs(flush_pos, oid, index, allocated, ++ first_allocated); ++ ++ set_key_offset(&key, ++ get_key_offset(&key) + ++ (allocated << current_blocksize_bits)); ++ } else { ++ /* ++ * overwrite: try to copy unit as it is to left neighbor and ++ * make all first not flushprepped nodes overwrite nodes ++ */ ++ reiser4_set_extent(©_extent, start, width); ++ result = put_unit_to_end(left, &key, ©_extent); ++ if (result == -E_NODE_FULL) ++ return SQUEEZE_TARGET_FULL; ++ ++ if (state != HOLE_EXTENT) ++ mark_jnodes_overwrite(flush_pos, oid, index, width); ++ set_key_offset(&key, ++ get_key_offset(&key) + ++ (width << current_blocksize_bits)); ++ } ++ *stop_key = key; ++ return SQUEEZE_CONTINUE; ++} ++ ++int key_by_offset_extent(struct inode *inode, loff_t off, reiser4_key * key) ++{ ++ return key_by_inode_and_offset_common(inode, off, key); ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/extent.h linux-2.6.30/fs/reiser4/plugin/item/extent.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/extent.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/extent.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,231 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#ifndef __REISER4_EXTENT_H__ ++#define __REISER4_EXTENT_H__ ++ ++/* on disk extent */ ++typedef struct { ++ reiser4_dblock_nr start; ++ reiser4_dblock_nr width; ++} reiser4_extent; ++ ++struct extent_stat { ++ int unallocated_units; ++ int unallocated_blocks; ++ int allocated_units; ++ int allocated_blocks; ++ int hole_units; ++ int hole_blocks; ++}; ++ ++/* extents in an extent item can be either holes, or unallocated or allocated ++ extents */ ++typedef enum { ++ HOLE_EXTENT, ++ UNALLOCATED_EXTENT, ++ ALLOCATED_EXTENT ++} extent_state; ++ ++#define HOLE_EXTENT_START 0 ++#define UNALLOCATED_EXTENT_START 1 ++#define UNALLOCATED_EXTENT_START2 2 ++ ++struct extent_coord_extension { ++ reiser4_block_nr pos_in_unit; ++ reiser4_block_nr width; /* width of current unit */ ++ pos_in_node_t nr_units; /* number of units */ ++ int ext_offset; /* offset from the beginning of zdata() */ ++ unsigned long expected_page; ++#if REISER4_DEBUG ++ reiser4_extent extent; ++#endif ++}; ++ ++/* macros to set/get fields of on-disk extent */ ++static inline reiser4_block_nr extent_get_start(const reiser4_extent * ext) ++{ ++ return le64_to_cpu(ext->start); ++} ++ ++static inline reiser4_block_nr extent_get_width(const reiser4_extent * ext) ++{ ++ return le64_to_cpu(ext->width); ++} ++ ++extern __u64 reiser4_current_block_count(void); ++ ++static inline void ++extent_set_start(reiser4_extent * ext, reiser4_block_nr start) ++{ ++ cassert(sizeof(ext->start) == 8); ++ assert("nikita-2510", ++ ergo(start > 1, start < reiser4_current_block_count())); ++ put_unaligned(cpu_to_le64(start), &ext->start); ++} ++ ++static inline void ++extent_set_width(reiser4_extent * ext, reiser4_block_nr width) ++{ ++ cassert(sizeof(ext->width) == 8); ++ assert("", width > 0); ++ put_unaligned(cpu_to_le64(width), &ext->width); ++ assert("nikita-2511", ++ ergo(extent_get_start(ext) > 1, ++ extent_get_start(ext) + width <= ++ reiser4_current_block_count())); ++} ++ ++#define extent_item(coord) \ ++({ \ ++ assert("nikita-3143", item_is_extent(coord)); \ ++ ((reiser4_extent *)item_body_by_coord (coord)); \ ++}) ++ ++#define extent_by_coord(coord) \ ++({ \ ++ assert("nikita-3144", item_is_extent(coord)); \ ++ (extent_item (coord) + (coord)->unit_pos); \ ++}) ++ ++#define width_by_coord(coord) \ ++({ \ ++ assert("nikita-3145", item_is_extent(coord)); \ ++ extent_get_width (extent_by_coord(coord)); \ ++}) ++ ++struct carry_cut_data; ++struct carry_kill_data; ++ ++/* plugin->u.item.b.* */ ++reiser4_key *max_key_inside_extent(const coord_t *, reiser4_key *); ++int can_contain_key_extent(const coord_t * coord, const reiser4_key * key, ++ const reiser4_item_data *); ++int mergeable_extent(const coord_t * p1, const coord_t * p2); ++pos_in_node_t nr_units_extent(const coord_t *); ++lookup_result lookup_extent(const reiser4_key *, lookup_bias, coord_t *); ++void init_coord_extent(coord_t *); ++int init_extent(coord_t *, reiser4_item_data *); ++int paste_extent(coord_t *, reiser4_item_data *, carry_plugin_info *); ++int can_shift_extent(unsigned free_space, ++ coord_t * source, znode * target, shift_direction, ++ unsigned *size, unsigned want); ++void copy_units_extent(coord_t * target, coord_t * source, unsigned from, ++ unsigned count, shift_direction where_is_free_space, ++ unsigned free_space); ++int kill_hook_extent(const coord_t *, pos_in_node_t from, pos_in_node_t count, ++ struct carry_kill_data *); ++int create_hook_extent(const coord_t * coord, void *arg); ++int cut_units_extent(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ struct carry_cut_data *, reiser4_key * smallest_removed, ++ reiser4_key * new_first); ++int kill_units_extent(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ struct carry_kill_data *, reiser4_key * smallest_removed, ++ reiser4_key * new_first); ++reiser4_key *unit_key_extent(const coord_t *, reiser4_key *); ++reiser4_key *max_unit_key_extent(const coord_t *, reiser4_key *); ++void print_extent(const char *, coord_t *); ++int utmost_child_extent(const coord_t * coord, sideof side, jnode ** child); ++int utmost_child_real_block_extent(const coord_t * coord, sideof side, ++ reiser4_block_nr * block); ++void item_stat_extent(const coord_t * coord, void *vp); ++int reiser4_check_extent(const coord_t * coord, const char **error); ++ ++/* plugin->u.item.s.file.* */ ++ssize_t reiser4_write_extent(struct file *, struct inode * inode, ++ const char __user *, size_t, loff_t *); ++int reiser4_read_extent(struct file *, flow_t *, hint_t *); ++int reiser4_readpage_extent(void *, struct page *); ++int reiser4_do_readpage_extent(reiser4_extent*, reiser4_block_nr, struct page*); ++reiser4_key *append_key_extent(const coord_t *, reiser4_key *); ++void init_coord_extension_extent(uf_coord_t *, loff_t offset); ++int get_block_address_extent(const coord_t *, sector_t block, ++ sector_t * result); ++ ++/* these are used in flush.c ++ FIXME-VS: should they be somewhere in item_plugin? */ ++int allocate_extent_item_in_place(coord_t *, lock_handle *, flush_pos_t * pos); ++int allocate_and_copy_extent(znode * left, coord_t * right, flush_pos_t * pos, ++ reiser4_key * stop_key); ++ ++int extent_is_unallocated(const coord_t * item); /* True if this extent is unallocated (i.e., not a hole, not allocated). */ ++__u64 extent_unit_index(const coord_t * item); /* Block offset of this unit. */ ++__u64 extent_unit_width(const coord_t * item); /* Number of blocks in this unit. */ ++ ++/* plugin->u.item.f. */ ++int reiser4_scan_extent(flush_scan * scan); ++extern int key_by_offset_extent(struct inode *, loff_t, reiser4_key *); ++ ++reiser4_item_data *init_new_extent(reiser4_item_data * data, void *ext_unit, ++ int nr_extents); ++reiser4_block_nr reiser4_extent_size(const coord_t * coord, pos_in_node_t nr); ++extent_state state_of_extent(reiser4_extent * ext); ++void reiser4_set_extent(reiser4_extent *, reiser4_block_nr start, ++ reiser4_block_nr width); ++int reiser4_update_extent(struct inode *, jnode *, loff_t pos, ++ int *plugged_hole); ++ ++#include "../../coord.h" ++#include "../../lock.h" ++#include "../../tap.h" ++ ++struct replace_handle { ++ /* these are to be set before calling reiser4_replace_extent */ ++ coord_t *coord; ++ lock_handle *lh; ++ reiser4_key key; ++ reiser4_key *pkey; ++ reiser4_extent overwrite; ++ reiser4_extent new_extents[2]; ++ int nr_new_extents; ++ unsigned flags; ++ ++ /* these are used by reiser4_replace_extent */ ++ reiser4_item_data item; ++ coord_t coord_after; ++ lock_handle lh_after; ++ tap_t watch; ++ reiser4_key paste_key; ++#if REISER4_DEBUG ++ reiser4_extent orig_ext; ++ reiser4_key tmp; ++#endif ++}; ++ ++/* this structure is kmalloced before calling make_extent to avoid excessive ++ stack consumption on plug_hole->reiser4_replace_extent */ ++struct make_extent_handle { ++ uf_coord_t *uf_coord; ++ reiser4_block_nr blocknr; ++ int created; ++ struct inode *inode; ++ union { ++ struct { ++ } append; ++ struct replace_handle replace; ++ } u; ++}; ++ ++int reiser4_replace_extent(struct replace_handle *, ++ int return_inserted_position); ++lock_handle *znode_lh(znode *); ++ ++/* the reiser4 repacker support */ ++struct repacker_cursor; ++extern int process_extent_backward_for_repacking(tap_t *, ++ struct repacker_cursor *); ++extern int mark_extent_for_repacking(tap_t *, int); ++ ++#define coord_by_uf_coord(uf_coord) (&((uf_coord)->coord)) ++#define ext_coord_by_uf_coord(uf_coord) (&((uf_coord)->extension.extent)) ++ ++/* __REISER4_EXTENT_H__ */ ++#endif ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/extent_item_ops.c linux-2.6.30/fs/reiser4/plugin/item/extent_item_ops.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/extent_item_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/extent_item_ops.c 2009-06-22 17:27:31.000000000 +0200 +@@ -0,0 +1,889 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "item.h" ++#include "../../inode.h" ++#include "../../tree_walk.h" /* check_sibling_list() */ ++#include "../../page_cache.h" ++#include "../../carry.h" ++ ++#include <linux/quotaops.h> ++ ++/* item_plugin->b.max_key_inside */ ++reiser4_key *max_key_inside_extent(const coord_t * coord, reiser4_key * key) ++{ ++ item_key_by_coord(coord, key); ++ set_key_offset(key, get_key_offset(reiser4_max_key())); ++ return key; ++} ++ ++/* item_plugin->b.can_contain_key ++ this checks whether @key of @data is matching to position set by @coord */ ++int ++can_contain_key_extent(const coord_t * coord, const reiser4_key * key, ++ const reiser4_item_data * data) ++{ ++ reiser4_key item_key; ++ ++ if (item_plugin_by_coord(coord) != data->iplug) ++ return 0; ++ ++ item_key_by_coord(coord, &item_key); ++ if (get_key_locality(key) != get_key_locality(&item_key) || ++ get_key_objectid(key) != get_key_objectid(&item_key) || ++ get_key_ordering(key) != get_key_ordering(&item_key)) ++ return 0; ++ ++ return 1; ++} ++ ++/* item_plugin->b.mergeable ++ first item is of extent type */ ++/* Audited by: green(2002.06.13) */ ++int mergeable_extent(const coord_t * p1, const coord_t * p2) ++{ ++ reiser4_key key1, key2; ++ ++ assert("vs-299", item_id_by_coord(p1) == EXTENT_POINTER_ID); ++ /* FIXME-VS: Which is it? Assert or return 0 */ ++ if (item_id_by_coord(p2) != EXTENT_POINTER_ID) { ++ return 0; ++ } ++ ++ item_key_by_coord(p1, &key1); ++ item_key_by_coord(p2, &key2); ++ if (get_key_locality(&key1) != get_key_locality(&key2) || ++ get_key_objectid(&key1) != get_key_objectid(&key2) || ++ get_key_ordering(&key1) != get_key_ordering(&key2) || ++ get_key_type(&key1) != get_key_type(&key2)) ++ return 0; ++ if (get_key_offset(&key1) + ++ reiser4_extent_size(p1, nr_units_extent(p1)) != ++ get_key_offset(&key2)) ++ return 0; ++ return 1; ++} ++ ++/* item_plugin->b.nr_units */ ++pos_in_node_t nr_units_extent(const coord_t * coord) ++{ ++ /* length of extent item has to be multiple of extent size */ ++ assert("vs-1424", ++ (item_length_by_coord(coord) % sizeof(reiser4_extent)) == 0); ++ return item_length_by_coord(coord) / sizeof(reiser4_extent); ++} ++ ++/* item_plugin->b.lookup */ ++lookup_result ++lookup_extent(const reiser4_key * key, lookup_bias bias UNUSED_ARG, ++ coord_t * coord) ++{ /* znode and item_pos are ++ set to an extent item to ++ look through */ ++ reiser4_key item_key; ++ reiser4_block_nr lookuped, offset; ++ unsigned i, nr_units; ++ reiser4_extent *ext; ++ unsigned blocksize; ++ unsigned char blocksize_bits; ++ ++ item_key_by_coord(coord, &item_key); ++ offset = get_key_offset(&item_key); ++ ++ /* key we are looking for must be greater than key of item @coord */ ++ assert("vs-414", keygt(key, &item_key)); ++ ++ assert("umka-99945", ++ !keygt(key, max_key_inside_extent(coord, &item_key))); ++ ++ ext = extent_item(coord); ++ assert("vs-1350", (char *)ext == (zdata(coord->node) + coord->offset)); ++ ++ blocksize = current_blocksize; ++ blocksize_bits = current_blocksize_bits; ++ ++ /* offset we are looking for */ ++ lookuped = get_key_offset(key); ++ ++ nr_units = nr_units_extent(coord); ++ /* go through all extents until the one which address given offset */ ++ for (i = 0; i < nr_units; i++, ext++) { ++ offset += (extent_get_width(ext) << blocksize_bits); ++ if (offset > lookuped) { ++ /* desired byte is somewhere in this extent */ ++ coord->unit_pos = i; ++ coord->between = AT_UNIT; ++ return CBK_COORD_FOUND; ++ } ++ } ++ ++ /* set coord after last unit */ ++ coord->unit_pos = nr_units - 1; ++ coord->between = AFTER_UNIT; ++ return CBK_COORD_FOUND; ++} ++ ++/* item_plugin->b.paste ++ item @coord is set to has been appended with @data->length of free ++ space. data->data contains data to be pasted into the item in position ++ @coord->in_item.unit_pos. It must fit into that free space. ++ @coord must be set between units. ++*/ ++int ++paste_extent(coord_t * coord, reiser4_item_data * data, ++ carry_plugin_info * info UNUSED_ARG) ++{ ++ unsigned old_nr_units; ++ reiser4_extent *ext; ++ int item_length; ++ ++ ext = extent_item(coord); ++ item_length = item_length_by_coord(coord); ++ old_nr_units = (item_length - data->length) / sizeof(reiser4_extent); ++ ++ /* this is also used to copy extent into newly created item, so ++ old_nr_units could be 0 */ ++ assert("vs-260", item_length >= data->length); ++ ++ /* make sure that coord is set properly */ ++ assert("vs-35", ++ ((!coord_is_existing_unit(coord)) ++ || (!old_nr_units && !coord->unit_pos))); ++ ++ /* first unit to be moved */ ++ switch (coord->between) { ++ case AFTER_UNIT: ++ coord->unit_pos++; ++ case BEFORE_UNIT: ++ coord->between = AT_UNIT; ++ break; ++ case AT_UNIT: ++ assert("vs-331", !old_nr_units && !coord->unit_pos); ++ break; ++ default: ++ impossible("vs-330", "coord is set improperly"); ++ } ++ ++ /* prepare space for new units */ ++ memmove(ext + coord->unit_pos + data->length / sizeof(reiser4_extent), ++ ext + coord->unit_pos, ++ (old_nr_units - coord->unit_pos) * sizeof(reiser4_extent)); ++ ++ /* copy new data from kernel space */ ++ assert("vs-556", data->user == 0); ++ memcpy(ext + coord->unit_pos, data->data, (unsigned)data->length); ++ ++ /* after paste @coord is set to first of pasted units */ ++ assert("vs-332", coord_is_existing_unit(coord)); ++ assert("vs-333", ++ !memcmp(data->data, extent_by_coord(coord), ++ (unsigned)data->length)); ++ return 0; ++} ++ ++/* item_plugin->b.can_shift */ ++int ++can_shift_extent(unsigned free_space, coord_t * source, ++ znode * target UNUSED_ARG, shift_direction pend UNUSED_ARG, ++ unsigned *size, unsigned want) ++{ ++ *size = item_length_by_coord(source); ++ if (*size > free_space) ++ /* never split a unit of extent item */ ++ *size = free_space - free_space % sizeof(reiser4_extent); ++ ++ /* we can shift *size bytes, calculate how many do we want to shift */ ++ if (*size > want * sizeof(reiser4_extent)) ++ *size = want * sizeof(reiser4_extent); ++ ++ if (*size % sizeof(reiser4_extent) != 0) ++ impossible("vs-119", "Wrong extent size: %i %zd", *size, ++ sizeof(reiser4_extent)); ++ return *size / sizeof(reiser4_extent); ++ ++} ++ ++/* item_plugin->b.copy_units */ ++void ++copy_units_extent(coord_t * target, coord_t * source, ++ unsigned from, unsigned count, ++ shift_direction where_is_free_space, unsigned free_space) ++{ ++ char *from_ext, *to_ext; ++ ++ assert("vs-217", free_space == count * sizeof(reiser4_extent)); ++ ++ from_ext = item_body_by_coord(source); ++ to_ext = item_body_by_coord(target); ++ ++ if (where_is_free_space == SHIFT_LEFT) { ++ assert("vs-215", from == 0); ++ ++ /* At this moment, item length was already updated in the item ++ header by shifting code, hence nr_units_extent() will ++ return "new" number of units---one we obtain after copying ++ units. ++ */ ++ to_ext += ++ (nr_units_extent(target) - count) * sizeof(reiser4_extent); ++ } else { ++ reiser4_key key; ++ coord_t coord; ++ ++ assert("vs-216", ++ from + count == coord_last_unit_pos(source) + 1); ++ ++ from_ext += item_length_by_coord(source) - free_space; ++ ++ /* new units are inserted before first unit in an item, ++ therefore, we have to update item key */ ++ coord = *source; ++ coord.unit_pos = from; ++ unit_key_extent(&coord, &key); ++ ++ node_plugin_by_node(target->node)->update_item_key(target, &key, ++ NULL /*info */); ++ } ++ ++ memcpy(to_ext, from_ext, free_space); ++} ++ ++/* item_plugin->b.create_hook ++ @arg is znode of leaf node for which we need to update right delimiting key */ ++int create_hook_extent(const coord_t * coord, void *arg) ++{ ++ coord_t *child_coord; ++ znode *node; ++ reiser4_key key; ++ reiser4_tree *tree; ++ ++ if (!arg) ++ return 0; ++ ++ child_coord = arg; ++ tree = znode_get_tree(coord->node); ++ ++ assert("nikita-3246", znode_get_level(child_coord->node) == LEAF_LEVEL); ++ ++ write_lock_tree(tree); ++ write_lock_dk(tree); ++ /* find a node on the left level for which right delimiting key has to ++ be updated */ ++ if (coord_wrt(child_coord) == COORD_ON_THE_LEFT) { ++ assert("vs-411", znode_is_left_connected(child_coord->node)); ++ node = child_coord->node->left; ++ } else { ++ assert("vs-412", coord_wrt(child_coord) == COORD_ON_THE_RIGHT); ++ node = child_coord->node; ++ assert("nikita-3314", node != NULL); ++ } ++ ++ if (node != NULL) { ++ znode_set_rd_key(node, item_key_by_coord(coord, &key)); ++ ++ assert("nikita-3282", check_sibling_list(node)); ++ /* break sibling links */ ++ if (ZF_ISSET(node, JNODE_RIGHT_CONNECTED) && node->right) { ++ ON_DEBUG(node->right->left_version = ++ atomic_inc_return(&delim_key_version); ++ node->right_version = ++ atomic_inc_return(&delim_key_version);); ++ ++ node->right->left = NULL; ++ node->right = NULL; ++ } ++ } ++ write_unlock_dk(tree); ++ write_unlock_tree(tree); ++ return 0; ++} ++ ++#define ITEM_TAIL_KILLED 0 ++#define ITEM_HEAD_KILLED 1 ++#define ITEM_KILLED 2 ++ ++/* item_plugin->b.kill_hook ++ this is called when @count units starting from @from-th one are going to be removed ++ */ ++int ++kill_hook_extent(const coord_t * coord, pos_in_node_t from, pos_in_node_t count, ++ struct carry_kill_data *kdata) ++{ ++ reiser4_extent *ext; ++ reiser4_block_nr start, length; ++ const reiser4_key *pfrom_key, *pto_key; ++ struct inode *inode; ++ reiser4_tree *tree; ++ pgoff_t from_off, to_off, offset, skip; ++ int retval; ++ ++ /* these are located in memory kmalloc-ed by kill_node_content */ ++ reiser4_key *min_item_key, *max_item_key, *from_key, *to_key, *key; ++ coord_t *dup, *next; ++ ++ assert("zam-811", znode_is_write_locked(coord->node)); ++ assert("nikita-3315", kdata != NULL); ++ assert("vs-34", kdata->buf != NULL); ++ ++ /* map structures to kdata->buf */ ++ min_item_key = (reiser4_key *) (kdata->buf); ++ max_item_key = min_item_key + 1; ++ from_key = max_item_key + 1; ++ to_key = from_key + 1; ++ key = to_key + 1; ++ dup = (coord_t *) (key + 1); ++ next = dup + 1; ++ ++ item_key_by_coord(coord, min_item_key); ++ max_item_key_by_coord(coord, max_item_key); ++ ++ if (kdata->params.from_key) { ++ pfrom_key = kdata->params.from_key; ++ pto_key = kdata->params.to_key; ++ } else { ++ assert("vs-1549", from == coord->unit_pos); ++ unit_key_by_coord(coord, from_key); ++ pfrom_key = from_key; ++ ++ coord_dup(dup, coord); ++ dup->unit_pos = from + count - 1; ++ max_unit_key_by_coord(dup, to_key); ++ pto_key = to_key; ++ } ++ ++ if (!keylt(pto_key, max_item_key)) { ++ if (!keygt(pfrom_key, min_item_key)) { ++ znode *left, *right; ++ ++ /* item is to be removed completely */ ++ assert("nikita-3316", kdata->left != NULL ++ && kdata->right != NULL); ++ ++ left = kdata->left->node; ++ right = kdata->right->node; ++ ++ tree = current_tree; ++ /* we have to do two things: ++ * ++ * 1. link left and right formatted neighbors of ++ * extent being removed, and ++ * ++ * 2. update their delimiting keys. ++ * ++ * atomicity of these operations is protected by ++ * taking dk-lock and tree-lock. ++ */ ++ /* if neighbors of item being removed are znodes - ++ * link them */ ++ write_lock_tree(tree); ++ write_lock_dk(tree); ++ link_left_and_right(left, right); ++ if (left) { ++ /* update right delimiting key of left ++ * neighbor of extent item */ ++ /*coord_t next; ++ reiser4_key key; */ ++ ++ coord_dup(next, coord); ++ ++ if (coord_next_item(next)) ++ *key = *znode_get_rd_key(coord->node); ++ else ++ item_key_by_coord(next, key); ++ znode_set_rd_key(left, key); ++ } ++ write_unlock_dk(tree); ++ write_unlock_tree(tree); ++ ++ from_off = ++ get_key_offset(min_item_key) >> PAGE_CACHE_SHIFT; ++ to_off = ++ (get_key_offset(max_item_key) + ++ 1) >> PAGE_CACHE_SHIFT; ++ retval = ITEM_KILLED; ++ } else { ++ /* tail of item is to be removed */ ++ from_off = ++ (get_key_offset(pfrom_key) + PAGE_CACHE_SIZE - ++ 1) >> PAGE_CACHE_SHIFT; ++ to_off = ++ (get_key_offset(max_item_key) + ++ 1) >> PAGE_CACHE_SHIFT; ++ retval = ITEM_TAIL_KILLED; ++ } ++ } else { ++ /* head of item is to be removed */ ++ assert("vs-1571", keyeq(pfrom_key, min_item_key)); ++ assert("vs-1572", ++ (get_key_offset(pfrom_key) & (PAGE_CACHE_SIZE - 1)) == ++ 0); ++ assert("vs-1573", ++ ((get_key_offset(pto_key) + 1) & (PAGE_CACHE_SIZE - ++ 1)) == 0); ++ ++ if (kdata->left->node) { ++ /* update right delimiting key of left neighbor of extent item */ ++ /*reiser4_key key; */ ++ ++ *key = *pto_key; ++ set_key_offset(key, get_key_offset(pto_key) + 1); ++ ++ write_lock_dk(current_tree); ++ znode_set_rd_key(kdata->left->node, key); ++ write_unlock_dk(current_tree); ++ } ++ ++ from_off = get_key_offset(pfrom_key) >> PAGE_CACHE_SHIFT; ++ to_off = (get_key_offset(pto_key) + 1) >> PAGE_CACHE_SHIFT; ++ retval = ITEM_HEAD_KILLED; ++ } ++ ++ inode = kdata->inode; ++ assert("vs-1545", inode != NULL); ++ if (inode != NULL) ++ /* take care of pages and jnodes corresponding to part of item being killed */ ++ reiser4_invalidate_pages(inode->i_mapping, from_off, ++ to_off - from_off, ++ kdata->params.truncate); ++ ++ ext = extent_item(coord) + from; ++ offset = ++ (get_key_offset(min_item_key) + ++ reiser4_extent_size(coord, from)) >> PAGE_CACHE_SHIFT; ++ ++ assert("vs-1551", from_off >= offset); ++ assert("vs-1552", from_off - offset <= extent_get_width(ext)); ++ skip = from_off - offset; ++ offset = from_off; ++ ++ while (offset < to_off) { ++ length = extent_get_width(ext) - skip; ++ if (state_of_extent(ext) == HOLE_EXTENT) { ++ skip = 0; ++ offset += length; ++ ext++; ++ continue; ++ } ++ ++ if (offset + length > to_off) { ++ length = to_off - offset; ++ } ++ ++ vfs_dq_free_block_nodirty(inode, length); ++ ++ if (state_of_extent(ext) == UNALLOCATED_EXTENT) { ++ /* some jnodes corresponding to this unallocated extent */ ++ fake_allocated2free(length, 0 /* unformatted */ ); ++ ++ skip = 0; ++ offset += length; ++ ext++; ++ continue; ++ } ++ ++ assert("vs-1218", state_of_extent(ext) == ALLOCATED_EXTENT); ++ ++ if (length != 0) { ++ start = extent_get_start(ext) + skip; ++ ++ /* BA_DEFER bit parameter is turned on because blocks which get freed are not safe to be freed ++ immediately */ ++ reiser4_dealloc_blocks(&start, &length, ++ 0 /* not used */ , ++ BA_DEFER ++ /* unformatted with defer */ ); ++ } ++ skip = 0; ++ offset += length; ++ ext++; ++ } ++ return retval; ++} ++ ++/* item_plugin->b.kill_units */ ++int ++kill_units_extent(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ struct carry_kill_data *kdata, reiser4_key * smallest_removed, ++ reiser4_key * new_first) ++{ ++ reiser4_extent *ext; ++ reiser4_key item_key; ++ pos_in_node_t count; ++ reiser4_key from_key, to_key; ++ const reiser4_key *pfrom_key, *pto_key; ++ loff_t off; ++ int result; ++ ++ assert("vs-1541", ++ ((kdata->params.from_key == NULL && kdata->params.to_key == NULL) ++ || (kdata->params.from_key != NULL ++ && kdata->params.to_key != NULL))); ++ ++ if (kdata->params.from_key) { ++ pfrom_key = kdata->params.from_key; ++ pto_key = kdata->params.to_key; ++ } else { ++ coord_t dup; ++ ++ /* calculate key range of kill */ ++ assert("vs-1549", from == coord->unit_pos); ++ unit_key_by_coord(coord, &from_key); ++ pfrom_key = &from_key; ++ ++ coord_dup(&dup, coord); ++ dup.unit_pos = to; ++ max_unit_key_by_coord(&dup, &to_key); ++ pto_key = &to_key; ++ } ++ ++ item_key_by_coord(coord, &item_key); ++ ++#if REISER4_DEBUG ++ { ++ reiser4_key max_item_key; ++ ++ max_item_key_by_coord(coord, &max_item_key); ++ ++ if (new_first) { ++ /* head of item is to be cut */ ++ assert("vs-1542", keyeq(pfrom_key, &item_key)); ++ assert("vs-1538", keylt(pto_key, &max_item_key)); ++ } else { ++ /* tail of item is to be cut */ ++ assert("vs-1540", keygt(pfrom_key, &item_key)); ++ assert("vs-1543", !keylt(pto_key, &max_item_key)); ++ } ++ } ++#endif ++ ++ if (smallest_removed) ++ *smallest_removed = *pfrom_key; ++ ++ if (new_first) { ++ /* item head is cut. Item key will change. This new key is calculated here */ ++ assert("vs-1556", ++ (get_key_offset(pto_key) & (PAGE_CACHE_SIZE - 1)) == ++ (PAGE_CACHE_SIZE - 1)); ++ *new_first = *pto_key; ++ set_key_offset(new_first, get_key_offset(new_first) + 1); ++ } ++ ++ count = to - from + 1; ++ result = kill_hook_extent(coord, from, count, kdata); ++ if (result == ITEM_TAIL_KILLED) { ++ assert("vs-1553", ++ get_key_offset(pfrom_key) >= ++ get_key_offset(&item_key) + ++ reiser4_extent_size(coord, from)); ++ off = ++ get_key_offset(pfrom_key) - ++ (get_key_offset(&item_key) + ++ reiser4_extent_size(coord, from)); ++ if (off) { ++ /* unit @from is to be cut partially. Its width decreases */ ++ ext = extent_item(coord) + from; ++ extent_set_width(ext, ++ (off + PAGE_CACHE_SIZE - ++ 1) >> PAGE_CACHE_SHIFT); ++ count--; ++ } ++ } else { ++ __u64 max_to_offset; ++ __u64 rest; ++ ++ assert("vs-1575", result == ITEM_HEAD_KILLED); ++ assert("", from == 0); ++ assert("", ++ ((get_key_offset(pto_key) + 1) & (PAGE_CACHE_SIZE - ++ 1)) == 0); ++ assert("", ++ get_key_offset(pto_key) + 1 > ++ get_key_offset(&item_key) + ++ reiser4_extent_size(coord, to)); ++ max_to_offset = ++ get_key_offset(&item_key) + ++ reiser4_extent_size(coord, to + 1) - 1; ++ assert("", get_key_offset(pto_key) <= max_to_offset); ++ ++ rest = ++ (max_to_offset - ++ get_key_offset(pto_key)) >> PAGE_CACHE_SHIFT; ++ if (rest) { ++ /* unit @to is to be cut partially */ ++ ext = extent_item(coord) + to; ++ ++ assert("", extent_get_width(ext) > rest); ++ ++ if (state_of_extent(ext) == ALLOCATED_EXTENT) ++ extent_set_start(ext, ++ extent_get_start(ext) + ++ (extent_get_width(ext) - ++ rest)); ++ ++ extent_set_width(ext, rest); ++ count--; ++ } ++ } ++ return count * sizeof(reiser4_extent); ++} ++ ++/* item_plugin->b.cut_units ++ this is too similar to kill_units_extent */ ++int ++cut_units_extent(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ struct carry_cut_data *cdata, reiser4_key * smallest_removed, ++ reiser4_key * new_first) ++{ ++ reiser4_extent *ext; ++ reiser4_key item_key; ++ pos_in_node_t count; ++ reiser4_key from_key, to_key; ++ const reiser4_key *pfrom_key, *pto_key; ++ loff_t off; ++ ++ assert("vs-1541", ++ ((cdata->params.from_key == NULL && cdata->params.to_key == NULL) ++ || (cdata->params.from_key != NULL ++ && cdata->params.to_key != NULL))); ++ ++ if (cdata->params.from_key) { ++ pfrom_key = cdata->params.from_key; ++ pto_key = cdata->params.to_key; ++ } else { ++ coord_t dup; ++ ++ /* calculate key range of kill */ ++ coord_dup(&dup, coord); ++ dup.unit_pos = from; ++ unit_key_by_coord(&dup, &from_key); ++ ++ dup.unit_pos = to; ++ max_unit_key_by_coord(&dup, &to_key); ++ ++ pfrom_key = &from_key; ++ pto_key = &to_key; ++ } ++ ++ assert("vs-1555", ++ (get_key_offset(pfrom_key) & (PAGE_CACHE_SIZE - 1)) == 0); ++ assert("vs-1556", ++ (get_key_offset(pto_key) & (PAGE_CACHE_SIZE - 1)) == ++ (PAGE_CACHE_SIZE - 1)); ++ ++ item_key_by_coord(coord, &item_key); ++ ++#if REISER4_DEBUG ++ { ++ reiser4_key max_item_key; ++ ++ assert("vs-1584", ++ get_key_locality(pfrom_key) == ++ get_key_locality(&item_key)); ++ assert("vs-1585", ++ get_key_type(pfrom_key) == get_key_type(&item_key)); ++ assert("vs-1586", ++ get_key_objectid(pfrom_key) == ++ get_key_objectid(&item_key)); ++ assert("vs-1587", ++ get_key_ordering(pfrom_key) == ++ get_key_ordering(&item_key)); ++ ++ max_item_key_by_coord(coord, &max_item_key); ++ ++ if (new_first != NULL) { ++ /* head of item is to be cut */ ++ assert("vs-1542", keyeq(pfrom_key, &item_key)); ++ assert("vs-1538", keylt(pto_key, &max_item_key)); ++ } else { ++ /* tail of item is to be cut */ ++ assert("vs-1540", keygt(pfrom_key, &item_key)); ++ assert("vs-1543", keyeq(pto_key, &max_item_key)); ++ } ++ } ++#endif ++ ++ if (smallest_removed) ++ *smallest_removed = *pfrom_key; ++ ++ if (new_first) { ++ /* item head is cut. Item key will change. This new key is calculated here */ ++ *new_first = *pto_key; ++ set_key_offset(new_first, get_key_offset(new_first) + 1); ++ } ++ ++ count = to - from + 1; ++ ++ assert("vs-1553", ++ get_key_offset(pfrom_key) >= ++ get_key_offset(&item_key) + reiser4_extent_size(coord, from)); ++ off = ++ get_key_offset(pfrom_key) - (get_key_offset(&item_key) + ++ reiser4_extent_size(coord, from)); ++ if (off) { ++ /* tail of unit @from is to be cut partially. Its width decreases */ ++ assert("vs-1582", new_first == NULL); ++ ext = extent_item(coord) + from; ++ extent_set_width(ext, off >> PAGE_CACHE_SHIFT); ++ count--; ++ } ++ ++ assert("vs-1554", ++ get_key_offset(pto_key) <= ++ get_key_offset(&item_key) + ++ reiser4_extent_size(coord, to + 1) - 1); ++ off = ++ (get_key_offset(&item_key) + ++ reiser4_extent_size(coord, to + 1) - 1) - ++ get_key_offset(pto_key); ++ if (off) { ++ /* @to_key is smaller than max key of unit @to. Unit @to will not be removed. It gets start increased ++ and width decreased. */ ++ assert("vs-1583", (off & (PAGE_CACHE_SIZE - 1)) == 0); ++ ext = extent_item(coord) + to; ++ if (state_of_extent(ext) == ALLOCATED_EXTENT) ++ extent_set_start(ext, ++ extent_get_start(ext) + ++ (extent_get_width(ext) - ++ (off >> PAGE_CACHE_SHIFT))); ++ ++ extent_set_width(ext, (off >> PAGE_CACHE_SHIFT)); ++ count--; ++ } ++ return count * sizeof(reiser4_extent); ++} ++ ++/* item_plugin->b.unit_key */ ++reiser4_key *unit_key_extent(const coord_t * coord, reiser4_key * key) ++{ ++ assert("vs-300", coord_is_existing_unit(coord)); ++ ++ item_key_by_coord(coord, key); ++ set_key_offset(key, ++ (get_key_offset(key) + ++ reiser4_extent_size(coord, coord->unit_pos))); ++ ++ return key; ++} ++ ++/* item_plugin->b.max_unit_key */ ++reiser4_key *max_unit_key_extent(const coord_t * coord, reiser4_key * key) ++{ ++ assert("vs-300", coord_is_existing_unit(coord)); ++ ++ item_key_by_coord(coord, key); ++ set_key_offset(key, ++ (get_key_offset(key) + ++ reiser4_extent_size(coord, coord->unit_pos + 1) - 1)); ++ return key; ++} ++ ++/* item_plugin->b.estimate ++ item_plugin->b.item_data_by_flow */ ++ ++#if REISER4_DEBUG ++ ++/* item_plugin->b.check ++ used for debugging, every item should have here the most complete ++ possible check of the consistency of the item that the inventor can ++ construct ++*/ ++int reiser4_check_extent(const coord_t * coord /* coord of item to check */, ++ const char **error /* where to store error message */) ++{ ++ reiser4_extent *ext, *first; ++ unsigned i, j; ++ reiser4_block_nr start, width, blk_cnt; ++ unsigned num_units; ++ reiser4_tree *tree; ++ oid_t oid; ++ reiser4_key key; ++ coord_t scan; ++ ++ assert("vs-933", REISER4_DEBUG); ++ ++ if (znode_get_level(coord->node) != TWIG_LEVEL) { ++ *error = "Extent on the wrong level"; ++ return -1; ++ } ++ if (item_length_by_coord(coord) % sizeof(reiser4_extent) != 0) { ++ *error = "Wrong item size"; ++ return -1; ++ } ++ ext = first = extent_item(coord); ++ blk_cnt = reiser4_block_count(reiser4_get_current_sb()); ++ num_units = coord_num_units(coord); ++ tree = znode_get_tree(coord->node); ++ item_key_by_coord(coord, &key); ++ oid = get_key_objectid(&key); ++ coord_dup(&scan, coord); ++ ++ for (i = 0; i < num_units; ++i, ++ext) { ++ __u64 index; ++ ++ scan.unit_pos = i; ++ index = extent_unit_index(&scan); ++ ++#if 0 ++ /* check that all jnodes are present for the unallocated ++ * extent */ ++ if (state_of_extent(ext) == UNALLOCATED_EXTENT) { ++ for (j = 0; j < extent_get_width(ext); j++) { ++ jnode *node; ++ ++ node = jlookup(tree, oid, index + j); ++ if (node == NULL) { ++ print_coord("scan", &scan, 0); ++ *error = "Jnode missing"; ++ return -1; ++ } ++ jput(node); ++ } ++ } ++#endif ++ ++ start = extent_get_start(ext); ++ if (start < 2) ++ continue; ++ /* extent is allocated one */ ++ width = extent_get_width(ext); ++ if (start >= blk_cnt) { ++ *error = "Start too large"; ++ return -1; ++ } ++ if (start + width > blk_cnt) { ++ *error = "End too large"; ++ return -1; ++ } ++ /* make sure that this extent does not overlap with other ++ allocated extents extents */ ++ for (j = 0; j < i; j++) { ++ if (state_of_extent(first + j) != ALLOCATED_EXTENT) ++ continue; ++ if (! ++ ((extent_get_start(ext) >= ++ extent_get_start(first + j) + ++ extent_get_width(first + j)) ++ || (extent_get_start(ext) + ++ extent_get_width(ext) <= ++ extent_get_start(first + j)))) { ++ *error = "Extent overlaps with others"; ++ return -1; ++ } ++ } ++ ++ } ++ ++ return 0; ++} ++ ++#endif /* REISER4_DEBUG */ ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/internal.c linux-2.6.30/fs/reiser4/plugin/item/internal.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/internal.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/internal.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,404 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Implementation of internal-item plugin methods. */ ++ ++#include "../../forward.h" ++#include "../../debug.h" ++#include "../../dformat.h" ++#include "../../key.h" ++#include "../../coord.h" ++#include "internal.h" ++#include "item.h" ++#include "../node/node.h" ++#include "../plugin.h" ++#include "../../jnode.h" ++#include "../../znode.h" ++#include "../../tree_walk.h" ++#include "../../tree_mod.h" ++#include "../../tree.h" ++#include "../../super.h" ++#include "../../block_alloc.h" ++ ++/* see internal.h for explanation */ ++ ++/* plugin->u.item.b.mergeable */ ++int mergeable_internal(const coord_t * p1 UNUSED_ARG /* first item */ , ++ const coord_t * p2 UNUSED_ARG /* second item */ ) ++{ ++ /* internal items are not mergeable */ ++ return 0; ++} ++ ++/* ->lookup() method for internal items */ ++lookup_result lookup_internal(const reiser4_key * key /* key to look up */ , ++ lookup_bias bias UNUSED_ARG /* lookup bias */ , ++ coord_t * coord /* coord of item */ ) ++{ ++ reiser4_key ukey; ++ ++ switch (keycmp(unit_key_by_coord(coord, &ukey), key)) { ++ default: ++ impossible("", "keycmp()?!"); ++ case LESS_THAN: ++ /* FIXME-VS: AFTER_ITEM used to be here. But with new coord ++ item plugin can not be taken using coord set this way */ ++ assert("vs-681", coord->unit_pos == 0); ++ coord->between = AFTER_UNIT; ++ case EQUAL_TO: ++ return CBK_COORD_FOUND; ++ case GREATER_THAN: ++ return CBK_COORD_NOTFOUND; ++ } ++} ++ ++/* return body of internal item at @coord */ ++static internal_item_layout *internal_at(const coord_t * coord /* coord of ++ * item */ ) ++{ ++ assert("nikita-607", coord != NULL); ++ assert("nikita-1650", ++ item_plugin_by_coord(coord) == ++ item_plugin_by_id(NODE_POINTER_ID)); ++ return (internal_item_layout *) item_body_by_coord(coord); ++} ++ ++void reiser4_update_internal(const coord_t * coord, ++ const reiser4_block_nr * blocknr) ++{ ++ internal_item_layout *item = internal_at(coord); ++ assert("nikita-2959", reiser4_blocknr_is_sane(blocknr)); ++ ++ put_unaligned(cpu_to_le64(*blocknr), &item->pointer); ++} ++ ++/* return child block number stored in the internal item at @coord */ ++static reiser4_block_nr pointer_at(const coord_t * coord /* coord of item */ ) ++{ ++ assert("nikita-608", coord != NULL); ++ return le64_to_cpu(get_unaligned(&internal_at(coord)->pointer)); ++} ++ ++/* get znode pointed to by internal @item */ ++static znode *znode_at(const coord_t * item /* coord of item */ , ++ znode * parent /* parent node */ ) ++{ ++ return child_znode(item, parent, 1, 0); ++} ++ ++/* store pointer from internal item into "block". Implementation of ++ ->down_link() method */ ++void down_link_internal(const coord_t * coord /* coord of item */ , ++ const reiser4_key * key UNUSED_ARG /* key to get ++ * pointer for */ , ++ reiser4_block_nr * block /* resulting block number */ ) ++{ ++ ON_DEBUG(reiser4_key item_key); ++ ++ assert("nikita-609", coord != NULL); ++ assert("nikita-611", block != NULL); ++ assert("nikita-612", (key == NULL) || ++ /* twig horrors */ ++ (znode_get_level(coord->node) == TWIG_LEVEL) ++ || keyle(item_key_by_coord(coord, &item_key), key)); ++ ++ *block = pointer_at(coord); ++ assert("nikita-2960", reiser4_blocknr_is_sane(block)); ++} ++ ++/* Get the child's block number, or 0 if the block is unallocated. */ ++int ++utmost_child_real_block_internal(const coord_t * coord, sideof side UNUSED_ARG, ++ reiser4_block_nr * block) ++{ ++ assert("jmacd-2059", coord != NULL); ++ ++ *block = pointer_at(coord); ++ assert("nikita-2961", reiser4_blocknr_is_sane(block)); ++ ++ if (reiser4_blocknr_is_fake(block)) { ++ *block = 0; ++ } ++ ++ return 0; ++} ++ ++/* Return the child. */ ++int ++utmost_child_internal(const coord_t * coord, sideof side UNUSED_ARG, ++ jnode ** childp) ++{ ++ reiser4_block_nr block = pointer_at(coord); ++ znode *child; ++ ++ assert("jmacd-2059", childp != NULL); ++ assert("nikita-2962", reiser4_blocknr_is_sane(&block)); ++ ++ child = zlook(znode_get_tree(coord->node), &block); ++ ++ if (IS_ERR(child)) { ++ return PTR_ERR(child); ++ } ++ ++ *childp = ZJNODE(child); ++ ++ return 0; ++} ++ ++#if REISER4_DEBUG ++ ++static void check_link(znode * left, znode * right) ++{ ++ znode *scan; ++ ++ for (scan = left; scan != right; scan = scan->right) { ++ if (ZF_ISSET(scan, JNODE_RIP)) ++ break; ++ if (znode_is_right_connected(scan) && scan->right != NULL) { ++ if (ZF_ISSET(scan->right, JNODE_RIP)) ++ break; ++ assert("nikita-3285", ++ znode_is_left_connected(scan->right)); ++ assert("nikita-3265", ++ ergo(scan != left, ++ ZF_ISSET(scan, JNODE_HEARD_BANSHEE))); ++ assert("nikita-3284", scan->right->left == scan); ++ } else ++ break; ++ } ++} ++ ++int check__internal(const coord_t * coord, const char **error) ++{ ++ reiser4_block_nr blk; ++ znode *child; ++ coord_t cpy; ++ ++ blk = pointer_at(coord); ++ if (!reiser4_blocknr_is_sane(&blk)) { ++ *error = "Invalid pointer"; ++ return -1; ++ } ++ coord_dup(&cpy, coord); ++ child = znode_at(&cpy, cpy.node); ++ if (child != NULL) { ++ znode *left_child; ++ znode *right_child; ++ ++ left_child = right_child = NULL; ++ ++ assert("nikita-3256", znode_invariant(child)); ++ if (coord_prev_item(&cpy) == 0 && item_is_internal(&cpy)) { ++ left_child = znode_at(&cpy, cpy.node); ++ if (left_child != NULL) { ++ read_lock_tree(znode_get_tree(child)); ++ check_link(left_child, child); ++ read_unlock_tree(znode_get_tree(child)); ++ zput(left_child); ++ } ++ } ++ coord_dup(&cpy, coord); ++ if (coord_next_item(&cpy) == 0 && item_is_internal(&cpy)) { ++ right_child = znode_at(&cpy, cpy.node); ++ if (right_child != NULL) { ++ read_lock_tree(znode_get_tree(child)); ++ check_link(child, right_child); ++ read_unlock_tree(znode_get_tree(child)); ++ zput(right_child); ++ } ++ } ++ zput(child); ++ } ++ return 0; ++} ++ ++#endif /* REISER4_DEBUG */ ++ ++/* return true only if this item really points to "block" */ ++/* Audited by: green(2002.06.14) */ ++int has_pointer_to_internal(const coord_t * coord /* coord of item */ , ++ const reiser4_block_nr * block /* block number to ++ * check */ ) ++{ ++ assert("nikita-613", coord != NULL); ++ assert("nikita-614", block != NULL); ++ ++ return pointer_at(coord) == *block; ++} ++ ++/* hook called by ->create_item() method of node plugin after new internal ++ item was just created. ++ ++ This is point where pointer to new node is inserted into tree. Initialize ++ parent pointer in child znode, insert child into sibling list and slum. ++ ++*/ ++int create_hook_internal(const coord_t * item /* coord of item */ , ++ void *arg /* child's left neighbor, if any */ ) ++{ ++ znode *child; ++ __u64 child_ptr; ++ ++ assert("nikita-1252", item != NULL); ++ assert("nikita-1253", item->node != NULL); ++ assert("nikita-1181", znode_get_level(item->node) > LEAF_LEVEL); ++ assert("nikita-1450", item->unit_pos == 0); ++ ++ /* ++ * preparing to item insertion build_child_ptr_data sets pointer to ++ * data to be inserted to jnode's blocknr which is in cpu byte ++ * order. Node's create_item simply copied those data. As result we ++ * have child pointer in cpu's byte order. Convert content of internal ++ * item to little endian byte order. ++ */ ++ child_ptr = get_unaligned((__u64 *)item_body_by_coord(item)); ++ reiser4_update_internal(item, &child_ptr); ++ ++ child = znode_at(item, item->node); ++ if (child != NULL && !IS_ERR(child)) { ++ znode *left; ++ int result = 0; ++ reiser4_tree *tree; ++ ++ left = arg; ++ tree = znode_get_tree(item->node); ++ write_lock_tree(tree); ++ write_lock_dk(tree); ++ assert("nikita-1400", (child->in_parent.node == NULL) ++ || (znode_above_root(child->in_parent.node))); ++ ++item->node->c_count; ++ coord_to_parent_coord(item, &child->in_parent); ++ sibling_list_insert_nolock(child, left); ++ ++ assert("nikita-3297", ZF_ISSET(child, JNODE_ORPHAN)); ++ ZF_CLR(child, JNODE_ORPHAN); ++ ++ if ((left != NULL) && !keyeq(znode_get_rd_key(left), ++ znode_get_rd_key(child))) { ++ znode_set_rd_key(child, znode_get_rd_key(left)); ++ } ++ write_unlock_dk(tree); ++ write_unlock_tree(tree); ++ zput(child); ++ return result; ++ } else { ++ if (child == NULL) ++ child = ERR_PTR(-EIO); ++ return PTR_ERR(child); ++ } ++} ++ ++/* hook called by ->cut_and_kill() method of node plugin just before internal ++ item is removed. ++ ++ This is point where empty node is removed from the tree. Clear parent ++ pointer in child, and mark node for pending deletion. ++ ++ Node will be actually deleted later and in several installations: ++ ++ . when last lock on this node will be released, node will be removed from ++ the sibling list and its lock will be invalidated ++ ++ . when last reference to this node will be dropped, bitmap will be updated ++ and node will be actually removed from the memory. ++ ++*/ ++int kill_hook_internal(const coord_t * item /* coord of item */ , ++ pos_in_node_t from UNUSED_ARG /* start unit */ , ++ pos_in_node_t count UNUSED_ARG /* stop unit */ , ++ struct carry_kill_data *p UNUSED_ARG) ++{ ++ znode *child; ++ int result = 0; ++ ++ assert("nikita-1222", item != NULL); ++ assert("nikita-1224", from == 0); ++ assert("nikita-1225", count == 1); ++ ++ child = znode_at(item, item->node); ++ if (child == NULL) ++ return 0; ++ if (IS_ERR(child)) ++ return PTR_ERR(child); ++ result = zload(child); ++ if (result) { ++ zput(child); ++ return result; ++ } ++ if (node_is_empty(child)) { ++ reiser4_tree *tree; ++ ++ assert("nikita-1397", znode_is_write_locked(child)); ++ assert("nikita-1398", child->c_count == 0); ++ assert("nikita-2546", ZF_ISSET(child, JNODE_HEARD_BANSHEE)); ++ ++ tree = znode_get_tree(item->node); ++ write_lock_tree(tree); ++ init_parent_coord(&child->in_parent, NULL); ++ --item->node->c_count; ++ write_unlock_tree(tree); ++ } else { ++ warning("nikita-1223", ++ "Cowardly refuse to remove link to non-empty node"); ++ result = RETERR(-EIO); ++ } ++ zrelse(child); ++ zput(child); ++ return result; ++} ++ ++/* hook called by ->shift() node plugin method when iternal item was just ++ moved from one node to another. ++ ++ Update parent pointer in child and c_counts in old and new parent ++ ++*/ ++int shift_hook_internal(const coord_t * item /* coord of item */ , ++ unsigned from UNUSED_ARG /* start unit */ , ++ unsigned count UNUSED_ARG /* stop unit */ , ++ znode * old_node /* old parent */ ) ++{ ++ znode *child; ++ znode *new_node; ++ reiser4_tree *tree; ++ ++ assert("nikita-1276", item != NULL); ++ assert("nikita-1277", from == 0); ++ assert("nikita-1278", count == 1); ++ assert("nikita-1451", item->unit_pos == 0); ++ ++ new_node = item->node; ++ assert("nikita-2132", new_node != old_node); ++ tree = znode_get_tree(item->node); ++ child = child_znode(item, old_node, 1, 0); ++ if (child == NULL) ++ return 0; ++ if (!IS_ERR(child)) { ++ write_lock_tree(tree); ++ ++new_node->c_count; ++ assert("nikita-1395", znode_parent(child) == old_node); ++ assert("nikita-1396", old_node->c_count > 0); ++ coord_to_parent_coord(item, &child->in_parent); ++ assert("nikita-1781", znode_parent(child) == new_node); ++ assert("nikita-1782", ++ check_tree_pointer(item, child) == NS_FOUND); ++ --old_node->c_count; ++ write_unlock_tree(tree); ++ zput(child); ++ return 0; ++ } else ++ return PTR_ERR(child); ++} ++ ++/* plugin->u.item.b.max_key_inside - not defined */ ++ ++/* plugin->u.item.b.nr_units - item.c:single_unit */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/internal.h linux-2.6.30/fs/reiser4/plugin/item/internal.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/internal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/internal.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,57 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++/* Internal item contains down-link to the child of the internal/twig ++ node in a tree. It is internal items that are actually used during ++ tree traversal. */ ++ ++#if !defined( __FS_REISER4_PLUGIN_ITEM_INTERNAL_H__ ) ++#define __FS_REISER4_PLUGIN_ITEM_INTERNAL_H__ ++ ++#include "../../forward.h" ++#include "../../dformat.h" ++ ++/* on-disk layout of internal item */ ++typedef struct internal_item_layout { ++ /* 0 */ reiser4_dblock_nr pointer; ++ /* 4 */ ++} internal_item_layout; ++ ++struct cut_list; ++ ++int mergeable_internal(const coord_t * p1, const coord_t * p2); ++lookup_result lookup_internal(const reiser4_key * key, lookup_bias bias, ++ coord_t * coord); ++/* store pointer from internal item into "block". Implementation of ++ ->down_link() method */ ++extern void down_link_internal(const coord_t * coord, const reiser4_key * key, ++ reiser4_block_nr * block); ++extern int has_pointer_to_internal(const coord_t * coord, ++ const reiser4_block_nr * block); ++extern int create_hook_internal(const coord_t * item, void *arg); ++extern int kill_hook_internal(const coord_t * item, pos_in_node_t from, ++ pos_in_node_t count, struct carry_kill_data *); ++extern int shift_hook_internal(const coord_t * item, unsigned from, ++ unsigned count, znode * old_node); ++extern void reiser4_print_internal(const char *prefix, coord_t * coord); ++ ++extern int utmost_child_internal(const coord_t * coord, sideof side, ++ jnode ** child); ++int utmost_child_real_block_internal(const coord_t * coord, sideof side, ++ reiser4_block_nr * block); ++ ++extern void reiser4_update_internal(const coord_t * coord, ++ const reiser4_block_nr * blocknr); ++/* FIXME: reiserfs has check_internal */ ++extern int check__internal(const coord_t * coord, const char **error); ++ ++/* __FS_REISER4_PLUGIN_ITEM_INTERNAL_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/item.c linux-2.6.30/fs/reiser4/plugin/item/item.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/item.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/item.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,719 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* definition of item plugins. */ ++ ++#include "../../forward.h" ++#include "../../debug.h" ++#include "../../key.h" ++#include "../../coord.h" ++#include "../plugin_header.h" ++#include "sde.h" ++#include "internal.h" ++#include "item.h" ++#include "static_stat.h" ++#include "../plugin.h" ++#include "../../znode.h" ++#include "../../tree.h" ++#include "../../context.h" ++#include "ctail.h" ++ ++/* return pointer to item body */ ++void item_body_by_coord_hard(coord_t * coord /* coord to query */ ) ++{ ++ assert("nikita-324", coord != NULL); ++ assert("nikita-325", coord->node != NULL); ++ assert("nikita-326", znode_is_loaded(coord->node)); ++ assert("nikita-3200", coord->offset == INVALID_OFFSET); ++ ++ coord->offset = ++ node_plugin_by_node(coord->node)->item_by_coord(coord) - ++ zdata(coord->node); ++ ON_DEBUG(coord->body_v = coord->node->times_locked); ++} ++ ++void *item_body_by_coord_easy(const coord_t * coord /* coord to query */ ) ++{ ++ return zdata(coord->node) + coord->offset; ++} ++ ++#if REISER4_DEBUG ++ ++int item_body_is_valid(const coord_t * coord) ++{ ++ return ++ coord->offset == ++ node_plugin_by_node(coord->node)->item_by_coord(coord) - ++ zdata(coord->node); ++} ++ ++#endif ++ ++/* return length of item at @coord */ ++pos_in_node_t item_length_by_coord(const coord_t * coord /* coord to query */ ) ++{ ++ int len; ++ ++ assert("nikita-327", coord != NULL); ++ assert("nikita-328", coord->node != NULL); ++ assert("nikita-329", znode_is_loaded(coord->node)); ++ ++ len = node_plugin_by_node(coord->node)->length_by_coord(coord); ++ return len; ++} ++ ++void obtain_item_plugin(const coord_t * coord) ++{ ++ assert("nikita-330", coord != NULL); ++ assert("nikita-331", coord->node != NULL); ++ assert("nikita-332", znode_is_loaded(coord->node)); ++ ++ coord_set_iplug((coord_t *) coord, ++ node_plugin_by_node(coord->node)-> ++ plugin_by_coord(coord)); ++ assert("nikita-2479", ++ coord_iplug(coord) == ++ node_plugin_by_node(coord->node)->plugin_by_coord(coord)); ++} ++ ++/* return id of item */ ++/* Audited by: green(2002.06.15) */ ++item_id item_id_by_coord(const coord_t * coord /* coord to query */ ) ++{ ++ assert("vs-539", coord != NULL); ++ assert("vs-538", coord->node != NULL); ++ assert("vs-537", znode_is_loaded(coord->node)); ++ assert("vs-536", item_plugin_by_coord(coord) != NULL); ++ assert("vs-540", ++ item_id_by_plugin(item_plugin_by_coord(coord)) < LAST_ITEM_ID); ++ ++ return item_id_by_plugin(item_plugin_by_coord(coord)); ++} ++ ++/* return key of item at @coord */ ++/* Audited by: green(2002.06.15) */ ++reiser4_key *item_key_by_coord(const coord_t * coord /* coord to query */ , ++ reiser4_key * key /* result */ ) ++{ ++ assert("nikita-338", coord != NULL); ++ assert("nikita-339", coord->node != NULL); ++ assert("nikita-340", znode_is_loaded(coord->node)); ++ ++ return node_plugin_by_node(coord->node)->key_at(coord, key); ++} ++ ++/* this returns max key in the item */ ++reiser4_key *max_item_key_by_coord(const coord_t * coord /* coord to query */ , ++ reiser4_key * key /* result */ ) ++{ ++ coord_t last; ++ ++ assert("nikita-338", coord != NULL); ++ assert("nikita-339", coord->node != NULL); ++ assert("nikita-340", znode_is_loaded(coord->node)); ++ ++ /* make coord pointing to last item's unit */ ++ coord_dup(&last, coord); ++ last.unit_pos = coord_num_units(&last) - 1; ++ assert("vs-1560", coord_is_existing_unit(&last)); ++ ++ max_unit_key_by_coord(&last, key); ++ return key; ++} ++ ++/* return key of unit at @coord */ ++reiser4_key *unit_key_by_coord(const coord_t * coord /* coord to query */ , ++ reiser4_key * key /* result */ ) ++{ ++ assert("nikita-772", coord != NULL); ++ assert("nikita-774", coord->node != NULL); ++ assert("nikita-775", znode_is_loaded(coord->node)); ++ ++ if (item_plugin_by_coord(coord)->b.unit_key != NULL) ++ return item_plugin_by_coord(coord)->b.unit_key(coord, key); ++ else ++ return item_key_by_coord(coord, key); ++} ++ ++/* return the biggest key contained the unit @coord */ ++reiser4_key *max_unit_key_by_coord(const coord_t * coord /* coord to query */ , ++ reiser4_key * key /* result */ ) ++{ ++ assert("nikita-772", coord != NULL); ++ assert("nikita-774", coord->node != NULL); ++ assert("nikita-775", znode_is_loaded(coord->node)); ++ ++ if (item_plugin_by_coord(coord)->b.max_unit_key != NULL) ++ return item_plugin_by_coord(coord)->b.max_unit_key(coord, key); ++ else ++ return unit_key_by_coord(coord, key); ++} ++ ++/* ->max_key_inside() method for items consisting of exactly one key (like ++ stat-data) */ ++static reiser4_key *max_key_inside_single_key(const coord_t * ++ coord /* coord of item */ , ++ reiser4_key * ++ result /* resulting key */ ) ++{ ++ assert("nikita-604", coord != NULL); ++ ++ /* coord -> key is starting key of this item and it has to be already ++ filled in */ ++ return unit_key_by_coord(coord, result); ++} ++ ++/* ->nr_units() method for items consisting of exactly one unit always */ ++pos_in_node_t ++nr_units_single_unit(const coord_t * coord UNUSED_ARG /* coord of item */ ) ++{ ++ return 1; ++} ++ ++static int ++paste_no_paste(coord_t * coord UNUSED_ARG, ++ reiser4_item_data * data UNUSED_ARG, ++ carry_plugin_info * info UNUSED_ARG) ++{ ++ return 0; ++} ++ ++/* default ->fast_paste() method */ ++static int ++agree_to_fast_op(const coord_t * coord UNUSED_ARG /* coord of item */ ) ++{ ++ return 1; ++} ++ ++int item_can_contain_key(const coord_t * item /* coord of item */ , ++ const reiser4_key * key /* key to check */ , ++ const reiser4_item_data * data /* parameters of item ++ * being created */ ) ++{ ++ item_plugin *iplug; ++ reiser4_key min_key_in_item; ++ reiser4_key max_key_in_item; ++ ++ assert("nikita-1658", item != NULL); ++ assert("nikita-1659", key != NULL); ++ ++ iplug = item_plugin_by_coord(item); ++ if (iplug->b.can_contain_key != NULL) ++ return iplug->b.can_contain_key(item, key, data); ++ else { ++ assert("nikita-1681", iplug->b.max_key_inside != NULL); ++ item_key_by_coord(item, &min_key_in_item); ++ iplug->b.max_key_inside(item, &max_key_in_item); ++ ++ /* can contain key if ++ min_key_in_item <= key && ++ key <= max_key_in_item ++ */ ++ return keyle(&min_key_in_item, key) ++ && keyle(key, &max_key_in_item); ++ } ++} ++ ++/* mergeable method for non mergeable items */ ++static int ++not_mergeable(const coord_t * i1 UNUSED_ARG, const coord_t * i2 UNUSED_ARG) ++{ ++ return 0; ++} ++ ++/* return 0 if @item1 and @item2 are not mergeable, !0 - otherwise */ ++int are_items_mergeable(const coord_t * i1 /* coord of first item */ , ++ const coord_t * i2 /* coord of second item */ ) ++{ ++ item_plugin *iplug; ++ reiser4_key k1; ++ reiser4_key k2; ++ ++ assert("nikita-1336", i1 != NULL); ++ assert("nikita-1337", i2 != NULL); ++ ++ iplug = item_plugin_by_coord(i1); ++ assert("nikita-1338", iplug != NULL); ++ ++ /* NOTE-NIKITA are_items_mergeable() is also called by assertions in ++ shifting code when nodes are in "suspended" state. */ ++ assert("nikita-1663", ++ keyle(item_key_by_coord(i1, &k1), item_key_by_coord(i2, &k2))); ++ ++ if (iplug->b.mergeable != NULL) { ++ return iplug->b.mergeable(i1, i2); ++ } else if (iplug->b.max_key_inside != NULL) { ++ iplug->b.max_key_inside(i1, &k1); ++ item_key_by_coord(i2, &k2); ++ ++ /* mergeable if ->max_key_inside() >= key of i2; */ ++ return keyge(iplug->b.max_key_inside(i1, &k1), ++ item_key_by_coord(i2, &k2)); ++ } else { ++ item_key_by_coord(i1, &k1); ++ item_key_by_coord(i2, &k2); ++ ++ return ++ (get_key_locality(&k1) == get_key_locality(&k2)) && ++ (get_key_objectid(&k1) == get_key_objectid(&k2)) ++ && (iplug == item_plugin_by_coord(i2)); ++ } ++} ++ ++int item_is_extent(const coord_t * item) ++{ ++ assert("vs-482", coord_is_existing_item(item)); ++ return item_id_by_coord(item) == EXTENT_POINTER_ID; ++} ++ ++int item_is_tail(const coord_t * item) ++{ ++ assert("vs-482", coord_is_existing_item(item)); ++ return item_id_by_coord(item) == FORMATTING_ID; ++} ++ ++#if REISER4_DEBUG ++ ++int item_is_statdata(const coord_t * item) ++{ ++ assert("vs-516", coord_is_existing_item(item)); ++ return plugin_of_group(item_plugin_by_coord(item), STAT_DATA_ITEM_TYPE); ++} ++ ++int item_is_ctail(const coord_t * item) ++{ ++ assert("edward-xx", coord_is_existing_item(item)); ++ return item_id_by_coord(item) == CTAIL_ID; ++} ++ ++#endif /* REISER4_DEBUG */ ++ ++static int change_item(struct inode *inode, ++ reiser4_plugin * plugin, ++ pset_member memb) ++{ ++ /* cannot change constituent item (sd, or dir_item) */ ++ return RETERR(-EINVAL); ++} ++ ++static reiser4_plugin_ops item_plugin_ops = { ++ .init = NULL, ++ .load = NULL, ++ .save_len = NULL, ++ .save = NULL, ++ .change = change_item ++}; ++ ++item_plugin item_plugins[LAST_ITEM_ID] = { ++ [STATIC_STAT_DATA_ID] = { ++ .h = { ++ .type_id = REISER4_ITEM_PLUGIN_TYPE, ++ .id = STATIC_STAT_DATA_ID, ++ .groups = (1 << STAT_DATA_ITEM_TYPE), ++ .pops = &item_plugin_ops, ++ .label = "sd", ++ .desc = "stat-data", ++ .linkage = {NULL, NULL} ++ }, ++ .b = { ++ .max_key_inside = max_key_inside_single_key, ++ .can_contain_key = NULL, ++ .mergeable = not_mergeable, ++ .nr_units = nr_units_single_unit, ++ .lookup = NULL, ++ .init = NULL, ++ .paste = paste_no_paste, ++ .fast_paste = NULL, ++ .can_shift = NULL, ++ .copy_units = NULL, ++ .create_hook = NULL, ++ .kill_hook = NULL, ++ .shift_hook = NULL, ++ .cut_units = NULL, ++ .kill_units = NULL, ++ .unit_key = NULL, ++ .max_unit_key = NULL, ++ .estimate = NULL, ++ .item_data_by_flow = NULL, ++#if REISER4_DEBUG ++ .check = NULL ++#endif ++ }, ++ .f = { ++ .utmost_child = NULL, ++ .utmost_child_real_block = NULL, ++ .update = NULL, ++ .scan = NULL, ++ .convert = NULL ++ }, ++ .s = { ++ .sd = { ++ .init_inode = init_inode_static_sd, ++ .save_len = save_len_static_sd, ++ .save = save_static_sd ++ } ++ } ++ }, ++ [SIMPLE_DIR_ENTRY_ID] = { ++ .h = { ++ .type_id = REISER4_ITEM_PLUGIN_TYPE, ++ .id = SIMPLE_DIR_ENTRY_ID, ++ .groups = (1 << DIR_ENTRY_ITEM_TYPE), ++ .pops = &item_plugin_ops, ++ .label = "de", ++ .desc = "directory entry", ++ .linkage = {NULL, NULL} ++ }, ++ .b = { ++ .max_key_inside = max_key_inside_single_key, ++ .can_contain_key = NULL, ++ .mergeable = NULL, ++ .nr_units = nr_units_single_unit, ++ .lookup = NULL, ++ .init = NULL, ++ .paste = NULL, ++ .fast_paste = NULL, ++ .can_shift = NULL, ++ .copy_units = NULL, ++ .create_hook = NULL, ++ .kill_hook = NULL, ++ .shift_hook = NULL, ++ .cut_units = NULL, ++ .kill_units = NULL, ++ .unit_key = NULL, ++ .max_unit_key = NULL, ++ .estimate = NULL, ++ .item_data_by_flow = NULL, ++#if REISER4_DEBUG ++ .check = NULL ++#endif ++ }, ++ .f = { ++ .utmost_child = NULL, ++ .utmost_child_real_block = NULL, ++ .update = NULL, ++ .scan = NULL, ++ .convert = NULL ++ }, ++ .s = { ++ .dir = { ++ .extract_key = extract_key_de, ++ .update_key = update_key_de, ++ .extract_name = extract_name_de, ++ .extract_file_type = extract_file_type_de, ++ .add_entry = add_entry_de, ++ .rem_entry = rem_entry_de, ++ .max_name_len = max_name_len_de ++ } ++ } ++ }, ++ [COMPOUND_DIR_ID] = { ++ .h = { ++ .type_id = REISER4_ITEM_PLUGIN_TYPE, ++ .id = COMPOUND_DIR_ID, ++ .groups = (1 << DIR_ENTRY_ITEM_TYPE), ++ .pops = &item_plugin_ops, ++ .label = "cde", ++ .desc = "compressed directory entry", ++ .linkage = {NULL, NULL} ++ }, ++ .b = { ++ .max_key_inside = max_key_inside_cde, ++ .can_contain_key = can_contain_key_cde, ++ .mergeable = mergeable_cde, ++ .nr_units = nr_units_cde, ++ .lookup = lookup_cde, ++ .init = init_cde, ++ .paste = paste_cde, ++ .fast_paste = agree_to_fast_op, ++ .can_shift = can_shift_cde, ++ .copy_units = copy_units_cde, ++ .create_hook = NULL, ++ .kill_hook = NULL, ++ .shift_hook = NULL, ++ .cut_units = cut_units_cde, ++ .kill_units = kill_units_cde, ++ .unit_key = unit_key_cde, ++ .max_unit_key = unit_key_cde, ++ .estimate = estimate_cde, ++ .item_data_by_flow = NULL, ++#if REISER4_DEBUG ++ .check = reiser4_check_cde ++#endif ++ }, ++ .f = { ++ .utmost_child = NULL, ++ .utmost_child_real_block = NULL, ++ .update = NULL, ++ .scan = NULL, ++ .convert = NULL ++ }, ++ .s = { ++ .dir = { ++ .extract_key = extract_key_cde, ++ .update_key = update_key_cde, ++ .extract_name = extract_name_cde, ++ .extract_file_type = extract_file_type_de, ++ .add_entry = add_entry_cde, ++ .rem_entry = rem_entry_cde, ++ .max_name_len = max_name_len_cde ++ } ++ } ++ }, ++ [NODE_POINTER_ID] = { ++ .h = { ++ .type_id = REISER4_ITEM_PLUGIN_TYPE, ++ .id = NODE_POINTER_ID, ++ .groups = (1 << INTERNAL_ITEM_TYPE), ++ .pops = NULL, ++ .label = "internal", ++ .desc = "internal item", ++ .linkage = {NULL, NULL} ++ }, ++ .b = { ++ .max_key_inside = NULL, ++ .can_contain_key = NULL, ++ .mergeable = mergeable_internal, ++ .nr_units = nr_units_single_unit, ++ .lookup = lookup_internal, ++ .init = NULL, ++ .paste = NULL, ++ .fast_paste = NULL, ++ .can_shift = NULL, ++ .copy_units = NULL, ++ .create_hook = create_hook_internal, ++ .kill_hook = kill_hook_internal, ++ .shift_hook = shift_hook_internal, ++ .cut_units = NULL, ++ .kill_units = NULL, ++ .unit_key = NULL, ++ .max_unit_key = NULL, ++ .estimate = NULL, ++ .item_data_by_flow = NULL, ++#if REISER4_DEBUG ++ .check = check__internal ++#endif ++ }, ++ .f = { ++ .utmost_child = utmost_child_internal, ++ .utmost_child_real_block = ++ utmost_child_real_block_internal, ++ .update = reiser4_update_internal, ++ .scan = NULL, ++ .convert = NULL ++ }, ++ .s = { ++ .internal = { ++ .down_link = down_link_internal, ++ .has_pointer_to = has_pointer_to_internal ++ } ++ } ++ }, ++ [EXTENT_POINTER_ID] = { ++ .h = { ++ .type_id = REISER4_ITEM_PLUGIN_TYPE, ++ .id = EXTENT_POINTER_ID, ++ .groups = (1 << UNIX_FILE_METADATA_ITEM_TYPE), ++ .pops = NULL, ++ .label = "extent", ++ .desc = "extent item", ++ .linkage = {NULL, NULL} ++ }, ++ .b = { ++ .max_key_inside = max_key_inside_extent, ++ .can_contain_key = can_contain_key_extent, ++ .mergeable = mergeable_extent, ++ .nr_units = nr_units_extent, ++ .lookup = lookup_extent, ++ .init = NULL, ++ .paste = paste_extent, ++ .fast_paste = agree_to_fast_op, ++ .can_shift = can_shift_extent, ++ .create_hook = create_hook_extent, ++ .copy_units = copy_units_extent, ++ .kill_hook = kill_hook_extent, ++ .shift_hook = NULL, ++ .cut_units = cut_units_extent, ++ .kill_units = kill_units_extent, ++ .unit_key = unit_key_extent, ++ .max_unit_key = max_unit_key_extent, ++ .estimate = NULL, ++ .item_data_by_flow = NULL, ++#if REISER4_DEBUG ++ .check = reiser4_check_extent ++#endif ++ }, ++ .f = { ++ .utmost_child = utmost_child_extent, ++ .utmost_child_real_block = ++ utmost_child_real_block_extent, ++ .update = NULL, ++ .scan = reiser4_scan_extent, ++ .convert = NULL, ++ .key_by_offset = key_by_offset_extent ++ }, ++ .s = { ++ .file = { ++ .write = reiser4_write_extent, ++ .read = reiser4_read_extent, ++ .readpage = reiser4_readpage_extent, ++ .get_block = get_block_address_extent, ++ .append_key = append_key_extent, ++ .init_coord_extension = ++ init_coord_extension_extent ++ } ++ } ++ }, ++ [FORMATTING_ID] = { ++ .h = { ++ .type_id = REISER4_ITEM_PLUGIN_TYPE, ++ .id = FORMATTING_ID, ++ .groups = (1 << UNIX_FILE_METADATA_ITEM_TYPE), ++ .pops = NULL, ++ .label = "body", ++ .desc = "body (or tail?) item", ++ .linkage = {NULL, NULL} ++ }, ++ .b = { ++ .max_key_inside = max_key_inside_tail, ++ .can_contain_key = can_contain_key_tail, ++ .mergeable = mergeable_tail, ++ .nr_units = nr_units_tail, ++ .lookup = lookup_tail, ++ .init = NULL, ++ .paste = paste_tail, ++ .fast_paste = agree_to_fast_op, ++ .can_shift = can_shift_tail, ++ .create_hook = NULL, ++ .copy_units = copy_units_tail, ++ .kill_hook = kill_hook_tail, ++ .shift_hook = NULL, ++ .cut_units = cut_units_tail, ++ .kill_units = kill_units_tail, ++ .unit_key = unit_key_tail, ++ .max_unit_key = unit_key_tail, ++ .estimate = NULL, ++ .item_data_by_flow = NULL, ++#if REISER4_DEBUG ++ .check = NULL ++#endif ++ }, ++ .f = { ++ .utmost_child = NULL, ++ .utmost_child_real_block = NULL, ++ .update = NULL, ++ .scan = NULL, ++ .convert = NULL ++ }, ++ .s = { ++ .file = { ++ .write = reiser4_write_tail, ++ .read = reiser4_read_tail, ++ .readpage = readpage_tail, ++ .get_block = get_block_address_tail, ++ .append_key = append_key_tail, ++ .init_coord_extension = ++ init_coord_extension_tail ++ } ++ } ++ }, ++ [CTAIL_ID] = { ++ .h = { ++ .type_id = REISER4_ITEM_PLUGIN_TYPE, ++ .id = CTAIL_ID, ++ .groups = (1 << UNIX_FILE_METADATA_ITEM_TYPE), ++ .pops = NULL, ++ .label = "ctail", ++ .desc = "cryptcompress tail item", ++ .linkage = {NULL, NULL} ++ }, ++ .b = { ++ .max_key_inside = max_key_inside_tail, ++ .can_contain_key = can_contain_key_ctail, ++ .mergeable = mergeable_ctail, ++ .nr_units = nr_units_ctail, ++ .lookup = NULL, ++ .init = init_ctail, ++ .paste = paste_ctail, ++ .fast_paste = agree_to_fast_op, ++ .can_shift = can_shift_ctail, ++ .create_hook = create_hook_ctail, ++ .copy_units = copy_units_ctail, ++ .kill_hook = kill_hook_ctail, ++ .shift_hook = shift_hook_ctail, ++ .cut_units = cut_units_ctail, ++ .kill_units = kill_units_ctail, ++ .unit_key = unit_key_tail, ++ .max_unit_key = unit_key_tail, ++ .estimate = estimate_ctail, ++ .item_data_by_flow = NULL, ++#if REISER4_DEBUG ++ .check = check_ctail ++#endif ++ }, ++ .f = { ++ .utmost_child = utmost_child_ctail, ++ /* FIXME-EDWARD: write this */ ++ .utmost_child_real_block = NULL, ++ .update = NULL, ++ .scan = scan_ctail, ++ .convert = convert_ctail ++ }, ++ .s = { ++ .file = { ++ .write = NULL, ++ .read = read_ctail, ++ .readpage = readpage_ctail, ++ .get_block = get_block_address_tail, ++ .append_key = append_key_ctail, ++ .init_coord_extension = ++ init_coord_extension_tail ++ } ++ } ++ }, ++ [BLACK_BOX_ID] = { ++ .h = { ++ .type_id = REISER4_ITEM_PLUGIN_TYPE, ++ .id = BLACK_BOX_ID, ++ .groups = (1 << OTHER_ITEM_TYPE), ++ .pops = NULL, ++ .label = "blackbox", ++ .desc = "black box item", ++ .linkage = {NULL, NULL} ++ }, ++ .b = { ++ .max_key_inside = NULL, ++ .can_contain_key = NULL, ++ .mergeable = not_mergeable, ++ .nr_units = nr_units_single_unit, ++ /* to need for ->lookup method */ ++ .lookup = NULL, ++ .init = NULL, ++ .paste = NULL, ++ .fast_paste = NULL, ++ .can_shift = NULL, ++ .copy_units = NULL, ++ .create_hook = NULL, ++ .kill_hook = NULL, ++ .shift_hook = NULL, ++ .cut_units = NULL, ++ .kill_units = NULL, ++ .unit_key = NULL, ++ .max_unit_key = NULL, ++ .estimate = NULL, ++ .item_data_by_flow = NULL, ++#if REISER4_DEBUG ++ .check = NULL ++#endif ++ } ++ } ++}; ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/item.h linux-2.6.30/fs/reiser4/plugin/item/item.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/item.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/item.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,398 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* first read balance.c comments before reading this */ ++ ++/* An item_plugin implements all of the operations required for ++ balancing that are item specific. */ ++ ++/* an item plugin also implements other operations that are specific to that ++ item. These go into the item specific operations portion of the item ++ handler, and all of the item specific portions of the item handler are put ++ into a union. */ ++ ++#if !defined( __REISER4_ITEM_H__ ) ++#define __REISER4_ITEM_H__ ++ ++#include "../../forward.h" ++#include "../plugin_header.h" ++#include "../../dformat.h" ++#include "../../seal.h" ++#include "../../plugin/file/file.h" ++ ++#include <linux/fs.h> /* for struct file, struct inode */ ++#include <linux/mm.h> /* for struct page */ ++#include <linux/dcache.h> /* for struct dentry */ ++ ++typedef enum { ++ STAT_DATA_ITEM_TYPE, ++ DIR_ENTRY_ITEM_TYPE, ++ INTERNAL_ITEM_TYPE, ++ UNIX_FILE_METADATA_ITEM_TYPE, ++ OTHER_ITEM_TYPE ++} item_type_id; ++ ++/* this is the part of each item plugin that all items are expected to ++ support or at least explicitly fail to support by setting the ++ pointer to null. */ ++struct balance_ops { ++ /* operations called by balancing ++ ++ It is interesting to consider that some of these item ++ operations could be given sources or targets that are not ++ really items in nodes. This could be ok/useful. ++ ++ */ ++ /* maximal key that can _possibly_ be occupied by this item ++ ++ When inserting, and node ->lookup() method (called by ++ coord_by_key()) reaches an item after binary search, ++ the ->max_key_inside() item plugin method is used to determine ++ whether new item should pasted into existing item ++ (new_key<=max_key_inside()) or new item has to be created ++ (new_key>max_key_inside()). ++ ++ For items that occupy exactly one key (like stat-data) ++ this method should return this key. For items that can ++ grow indefinitely (extent, directory item) this should ++ return reiser4_max_key(). ++ ++ For example extent with the key ++ ++ (LOCALITY,4,OBJID,STARTING-OFFSET), and length BLK blocks, ++ ++ ->max_key_inside is (LOCALITY,4,OBJID,0xffffffffffffffff), and ++ */ ++ reiser4_key *(*max_key_inside) (const coord_t *, reiser4_key *); ++ ++ /* true if item @coord can merge data at @key. */ ++ int (*can_contain_key) (const coord_t *, const reiser4_key *, ++ const reiser4_item_data *); ++ /* mergeable() - check items for mergeability ++ ++ Optional method. Returns true if two items can be merged. ++ ++ */ ++ int (*mergeable) (const coord_t *, const coord_t *); ++ ++ /* number of atomic things in an item. ++ NOTE FOR CONTRIBUTORS: use a generic method ++ nr_units_single_unit() for solid (atomic) items, as ++ tree operations use it as a criterion of solidness ++ (see is_solid_item macro) */ ++ pos_in_node_t(*nr_units) (const coord_t *); ++ ++ /* search within item for a unit within the item, and return a ++ pointer to it. This can be used to calculate how many ++ bytes to shrink an item if you use pointer arithmetic and ++ compare to the start of the item body if the item's data ++ are continuous in the node, if the item's data are not ++ continuous in the node, all sorts of other things are maybe ++ going to break as well. */ ++ lookup_result(*lookup) (const reiser4_key *, lookup_bias, coord_t *); ++ /* method called by ode_plugin->create_item() to initialise new ++ item */ ++ int (*init) (coord_t * target, coord_t * from, ++ reiser4_item_data * data); ++ /* method called (e.g., by reiser4_resize_item()) to place new data ++ into item when it grows */ ++ int (*paste) (coord_t *, reiser4_item_data *, carry_plugin_info *); ++ /* return true if paste into @coord is allowed to skip ++ carry. That is, if such paste would require any changes ++ at the parent level ++ */ ++ int (*fast_paste) (const coord_t *); ++ /* how many but not more than @want units of @source can be ++ shifted into @target node. If pend == append - we try to ++ append last item of @target by first units of @source. If ++ pend == prepend - we try to "prepend" first item in @target ++ by last units of @source. @target node has @free_space ++ bytes of free space. Total size of those units are returned ++ via @size. ++ ++ @target is not NULL if shifting to the mergeable item and ++ NULL is new item will be created during shifting. ++ */ ++ int (*can_shift) (unsigned free_space, coord_t *, ++ znode *, shift_direction, unsigned *size, ++ unsigned want); ++ ++ /* starting off @from-th unit of item @source append or ++ prepend @count units to @target. @target has been already ++ expanded by @free_space bytes. That must be exactly what is ++ needed for those items in @target. If @where_is_free_space ++ == SHIFT_LEFT - free space is at the end of @target item, ++ othersize - it is in the beginning of it. */ ++ void (*copy_units) (coord_t *, coord_t *, ++ unsigned from, unsigned count, ++ shift_direction where_is_free_space, ++ unsigned free_space); ++ ++ int (*create_hook) (const coord_t *, void *); ++ /* do whatever is necessary to do when @count units starting ++ from @from-th one are removed from the tree */ ++ /* FIXME-VS: this is used to be here for, in particular, ++ extents and items of internal type to free blocks they point ++ to at the same time with removing items from a ++ tree. Problems start, however, when dealloc_block fails due ++ to some reason. Item gets removed, but blocks it pointed to ++ are not freed. It is not clear how to fix this for items of ++ internal type because a need to remove internal item may ++ appear in the middle of balancing, and there is no way to ++ undo changes made. OTOH, if space allocator involves ++ balancing to perform dealloc_block - this will probably ++ break balancing due to deadlock issues ++ */ ++ int (*kill_hook) (const coord_t *, pos_in_node_t from, ++ pos_in_node_t count, struct carry_kill_data *); ++ int (*shift_hook) (const coord_t *, unsigned from, unsigned count, ++ znode * _node); ++ ++ /* unit @*from contains @from_key. unit @*to contains @to_key. Cut all keys between @from_key and @to_key ++ including boundaries. When units are cut from item beginning - move space which gets freed to head of ++ item. When units are cut from item end - move freed space to item end. When units are cut from the middle of ++ item - move freed space to item head. Return amount of space which got freed. Save smallest removed key in ++ @smallest_removed if it is not 0. Save new first item key in @new_first_key if it is not 0 ++ */ ++ int (*cut_units) (coord_t *, pos_in_node_t from, pos_in_node_t to, ++ struct carry_cut_data *, ++ reiser4_key * smallest_removed, ++ reiser4_key * new_first_key); ++ ++ /* like cut_units, except that these units are removed from the ++ tree, not only from a node */ ++ int (*kill_units) (coord_t *, pos_in_node_t from, pos_in_node_t to, ++ struct carry_kill_data *, ++ reiser4_key * smallest_removed, ++ reiser4_key * new_first); ++ ++ /* if @key_of_coord == 1 - returned key of coord, otherwise - ++ key of unit is returned. If @coord is not set to certain ++ unit - ERR_PTR(-ENOENT) is returned */ ++ reiser4_key *(*unit_key) (const coord_t *, reiser4_key *); ++ reiser4_key *(*max_unit_key) (const coord_t *, reiser4_key *); ++ /* estimate how much space is needed for paste @data into item at ++ @coord. if @coord==0 - estimate insertion, otherwise - estimate ++ pasting ++ */ ++ int (*estimate) (const coord_t *, const reiser4_item_data *); ++ ++ /* converts flow @f to item data. @coord == 0 on insert */ ++ int (*item_data_by_flow) (const coord_t *, const flow_t *, ++ reiser4_item_data *); ++ ++ /*void (*show) (struct seq_file *, coord_t *); */ ++ ++#if REISER4_DEBUG ++ /* used for debugging, every item should have here the most ++ complete possible check of the consistency of the item that ++ the inventor can construct */ ++ int (*check) (const coord_t *, const char **error); ++#endif ++ ++}; ++ ++struct flush_ops { ++ /* return the right or left child of @coord, only if it is in memory */ ++ int (*utmost_child) (const coord_t *, sideof side, jnode ** child); ++ ++ /* return whether the right or left child of @coord has a non-fake ++ block number. */ ++ int (*utmost_child_real_block) (const coord_t *, sideof side, ++ reiser4_block_nr *); ++ /* relocate child at @coord to the @block */ ++ void (*update) (const coord_t *, const reiser4_block_nr *); ++ /* count unformatted nodes per item for leave relocation policy, etc.. */ ++ int (*scan) (flush_scan * scan); ++ /* convert item by flush */ ++ int (*convert) (flush_pos_t * pos); ++ /* backward mapping from jnode offset to a key. */ ++ int (*key_by_offset) (struct inode *, loff_t, reiser4_key *); ++}; ++ ++/* operations specific to the directory item */ ++struct dir_entry_iops { ++ /* extract stat-data key from directory entry at @coord and place it ++ into @key. */ ++ int (*extract_key) (const coord_t *, reiser4_key * key); ++ /* update object key in item. */ ++ int (*update_key) (const coord_t *, const reiser4_key *, lock_handle *); ++ /* extract name from directory entry at @coord and return it */ ++ char *(*extract_name) (const coord_t *, char *buf); ++ /* extract file type (DT_* stuff) from directory entry at @coord and ++ return it */ ++ unsigned (*extract_file_type) (const coord_t *); ++ int (*add_entry) (struct inode * dir, ++ coord_t *, lock_handle *, ++ const struct dentry * name, ++ reiser4_dir_entry_desc * entry); ++ int (*rem_entry) (struct inode * dir, const struct qstr * name, ++ coord_t *, lock_handle *, ++ reiser4_dir_entry_desc * entry); ++ int (*max_name_len) (const struct inode * dir); ++}; ++ ++/* operations specific to items regular (unix) file metadata are built of */ ++struct file_iops{ ++ int (*write) (struct file *, struct inode *, ++ const char __user *, size_t, loff_t *pos); ++ int (*read) (struct file *, flow_t *, hint_t *); ++ int (*readpage) (void *, struct page *); ++ int (*get_block) (const coord_t *, sector_t, sector_t *); ++ /* ++ * key of first byte which is not addressed by the item @coord is set ++ * to. ++ * For example, for extent item with the key ++ * ++ * (LOCALITY,4,OBJID,STARTING-OFFSET), and length BLK blocks, ++ * ++ * ->append_key is ++ * ++ * (LOCALITY,4,OBJID,STARTING-OFFSET + BLK * block_size) ++ */ ++ reiser4_key *(*append_key) (const coord_t *, reiser4_key *); ++ ++ void (*init_coord_extension) (uf_coord_t *, loff_t); ++}; ++ ++/* operations specific to items of stat data type */ ++struct sd_iops { ++ int (*init_inode) (struct inode * inode, char *sd, int len); ++ int (*save_len) (struct inode * inode); ++ int (*save) (struct inode * inode, char **area); ++}; ++ ++/* operations specific to internal item */ ++struct internal_iops{ ++ /* all tree traversal want to know from internal item is where ++ to go next. */ ++ void (*down_link) (const coord_t * coord, ++ const reiser4_key * key, reiser4_block_nr * block); ++ /* check that given internal item contains given pointer. */ ++ int (*has_pointer_to) (const coord_t * coord, ++ const reiser4_block_nr * block); ++}; ++ ++struct item_plugin { ++ /* generic fields */ ++ plugin_header h; ++ /* methods common for all item types */ ++ struct balance_ops b; /* balance operations */ ++ struct flush_ops f; /* flush operates with items via this methods */ ++ ++ /* methods specific to particular type of item */ ++ union { ++ struct dir_entry_iops dir; ++ struct file_iops file; ++ struct sd_iops sd; ++ struct internal_iops internal; ++ } s; ++}; ++ ++#define is_solid_item(iplug) ((iplug)->b.nr_units == nr_units_single_unit) ++ ++static inline item_id item_id_by_plugin(item_plugin * plugin) ++{ ++ return plugin->h.id; ++} ++ ++static inline char get_iplugid(item_plugin * iplug) ++{ ++ assert("nikita-2838", iplug != NULL); ++ assert("nikita-2839", iplug->h.id < 0xff); ++ return (char)item_id_by_plugin(iplug); ++} ++ ++extern unsigned long znode_times_locked(const znode * z); ++ ++static inline void coord_set_iplug(coord_t * coord, item_plugin * iplug) ++{ ++ assert("nikita-2837", coord != NULL); ++ assert("nikita-2838", iplug != NULL); ++ coord->iplugid = get_iplugid(iplug); ++ ON_DEBUG(coord->plug_v = znode_times_locked(coord->node)); ++} ++ ++static inline item_plugin *coord_iplug(const coord_t * coord) ++{ ++ assert("nikita-2833", coord != NULL); ++ assert("nikita-2834", coord->iplugid != INVALID_PLUGID); ++ assert("nikita-3549", coord->plug_v == znode_times_locked(coord->node)); ++ return (item_plugin *) plugin_by_id(REISER4_ITEM_PLUGIN_TYPE, ++ coord->iplugid); ++} ++ ++extern int item_can_contain_key(const coord_t * item, const reiser4_key * key, ++ const reiser4_item_data *); ++extern int are_items_mergeable(const coord_t * i1, const coord_t * i2); ++extern int item_is_extent(const coord_t *); ++extern int item_is_tail(const coord_t *); ++extern int item_is_statdata(const coord_t * item); ++extern int item_is_ctail(const coord_t *); ++ ++extern pos_in_node_t item_length_by_coord(const coord_t * coord); ++extern pos_in_node_t nr_units_single_unit(const coord_t * coord); ++extern item_id item_id_by_coord(const coord_t * coord /* coord to query */ ); ++extern reiser4_key *item_key_by_coord(const coord_t * coord, reiser4_key * key); ++extern reiser4_key *max_item_key_by_coord(const coord_t *, reiser4_key *); ++extern reiser4_key *unit_key_by_coord(const coord_t * coord, reiser4_key * key); ++extern reiser4_key *max_unit_key_by_coord(const coord_t * coord, ++ reiser4_key * key); ++extern void obtain_item_plugin(const coord_t * coord); ++ ++#if defined(REISER4_DEBUG) ++extern int znode_is_loaded(const znode * node); ++#endif ++ ++/* return plugin of item at @coord */ ++static inline item_plugin *item_plugin_by_coord(const coord_t * ++ coord /* coord to query */ ) ++{ ++ assert("nikita-330", coord != NULL); ++ assert("nikita-331", coord->node != NULL); ++ assert("nikita-332", znode_is_loaded(coord->node)); ++ ++ if (unlikely(!coord_is_iplug_set(coord))) ++ obtain_item_plugin(coord); ++ return coord_iplug(coord); ++} ++ ++/* this returns true if item is of internal type */ ++static inline int item_is_internal(const coord_t * item) ++{ ++ assert("vs-483", coord_is_existing_item(item)); ++ return plugin_of_group(item_plugin_by_coord(item), INTERNAL_ITEM_TYPE); ++} ++ ++extern void item_body_by_coord_hard(coord_t * coord); ++extern void *item_body_by_coord_easy(const coord_t * coord); ++#if REISER4_DEBUG ++extern int item_body_is_valid(const coord_t * coord); ++#endif ++ ++/* return pointer to item body */ ++static inline void *item_body_by_coord(const coord_t * ++ coord /* coord to query */ ) ++{ ++ assert("nikita-324", coord != NULL); ++ assert("nikita-325", coord->node != NULL); ++ assert("nikita-326", znode_is_loaded(coord->node)); ++ ++ if (coord->offset == INVALID_OFFSET) ++ item_body_by_coord_hard((coord_t *) coord); ++ assert("nikita-3201", item_body_is_valid(coord)); ++ assert("nikita-3550", coord->body_v == znode_times_locked(coord->node)); ++ return item_body_by_coord_easy(coord); ++} ++ ++/* __REISER4_ITEM_H__ */ ++#endif ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/Makefile linux-2.6.30/fs/reiser4/plugin/item/Makefile +--- linux-2.6.30.orig/fs/reiser4/plugin/item/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,18 @@ ++obj-$(CONFIG_REISER4_FS) += item_plugins.o ++ ++item_plugins-objs := \ ++ item.o \ ++ static_stat.o \ ++ sde.o \ ++ cde.o \ ++ blackbox.o \ ++ internal.o \ ++ tail.o \ ++ ctail.o \ ++ extent.o \ ++ extent_item_ops.o \ ++ extent_file_ops.o \ ++ extent_flush_ops.o ++ ++ ++ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/sde.c linux-2.6.30/fs/reiser4/plugin/item/sde.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/sde.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/sde.c 2009-06-22 17:27:31.000000000 +0200 +@@ -0,0 +1,190 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Directory entry implementation */ ++#include "../../forward.h" ++#include "../../debug.h" ++#include "../../dformat.h" ++#include "../../kassign.h" ++#include "../../coord.h" ++#include "sde.h" ++#include "item.h" ++#include "../plugin.h" ++#include "../../znode.h" ++#include "../../carry.h" ++#include "../../tree.h" ++#include "../../inode.h" ++ ++#include <linux/fs.h> /* for struct inode */ ++#include <linux/dcache.h> /* for struct dentry */ ++#include <linux/quotaops.h> ++ ++/* ->extract_key() method of simple directory item plugin. */ ++int extract_key_de(const coord_t * coord /* coord of item */ , ++ reiser4_key * key /* resulting key */ ) ++{ ++ directory_entry_format *dent; ++ ++ assert("nikita-1458", coord != NULL); ++ assert("nikita-1459", key != NULL); ++ ++ dent = (directory_entry_format *) item_body_by_coord(coord); ++ assert("nikita-1158", item_length_by_coord(coord) >= (int)sizeof *dent); ++ return extract_key_from_id(&dent->id, key); ++} ++ ++int ++update_key_de(const coord_t * coord, const reiser4_key * key, ++ lock_handle * lh UNUSED_ARG) ++{ ++ directory_entry_format *dent; ++ obj_key_id obj_id; ++ int result; ++ ++ assert("nikita-2342", coord != NULL); ++ assert("nikita-2343", key != NULL); ++ ++ dent = (directory_entry_format *) item_body_by_coord(coord); ++ result = build_obj_key_id(key, &obj_id); ++ if (result == 0) { ++ dent->id = obj_id; ++ znode_make_dirty(coord->node); ++ } ++ return 0; ++} ++ ++char *extract_dent_name(const coord_t * coord, directory_entry_format * dent, ++ char *buf) ++{ ++ reiser4_key key; ++ ++ unit_key_by_coord(coord, &key); ++ if (get_key_type(&key) != KEY_FILE_NAME_MINOR) ++ reiser4_print_address("oops", znode_get_block(coord->node)); ++ if (!is_longname_key(&key)) { ++ if (is_dot_key(&key)) ++ return (char *)"."; ++ else ++ return extract_name_from_key(&key, buf); ++ } else ++ return (char *)dent->name; ++} ++ ++/* ->extract_name() method of simple directory item plugin. */ ++char *extract_name_de(const coord_t * coord /* coord of item */ , char *buf) ++{ ++ directory_entry_format *dent; ++ ++ assert("nikita-1460", coord != NULL); ++ ++ dent = (directory_entry_format *) item_body_by_coord(coord); ++ return extract_dent_name(coord, dent, buf); ++} ++ ++/* ->extract_file_type() method of simple directory item plugin. */ ++unsigned extract_file_type_de(const coord_t * coord UNUSED_ARG /* coord of ++ * item */ ) ++{ ++ assert("nikita-1764", coord != NULL); ++ /* we don't store file type in the directory entry yet. ++ ++ But see comments at kassign.h:obj_key_id ++ */ ++ return DT_UNKNOWN; ++} ++ ++int add_entry_de(struct inode *dir /* directory of item */ , ++ coord_t * coord /* coord of item */ , ++ lock_handle * lh /* insertion lock handle */ , ++ const struct dentry *de /* name to add */ , ++ reiser4_dir_entry_desc * entry /* parameters of new directory ++ * entry */ ) ++{ ++ reiser4_item_data data; ++ directory_entry_format *dent; ++ int result; ++ const char *name; ++ int len; ++ int longname; ++ ++ name = de->d_name.name; ++ len = de->d_name.len; ++ assert("nikita-1163", strlen(name) == len); ++ ++ longname = is_longname(name, len); ++ ++ data.length = sizeof *dent; ++ if (longname) ++ data.length += len + 1; ++ data.data = NULL; ++ data.user = 0; ++ data.iplug = item_plugin_by_id(SIMPLE_DIR_ENTRY_ID); ++ ++ /* NOTE-NIKITA quota plugin */ ++ if (vfs_dq_alloc_space_nodirty(dir, data.length)) ++ return -EDQUOT; ++ ++ result = insert_by_coord(coord, &data, &entry->key, lh, 0 /*flags */ ); ++ if (result != 0) ++ return result; ++ ++ dent = (directory_entry_format *) item_body_by_coord(coord); ++ build_inode_key_id(entry->obj, &dent->id); ++ if (longname) { ++ memcpy(dent->name, name, len); ++ put_unaligned(0, &dent->name[len]); ++ } ++ return 0; ++} ++ ++int rem_entry_de(struct inode *dir /* directory of item */ , ++ const struct qstr *name UNUSED_ARG, ++ coord_t * coord /* coord of item */ , ++ lock_handle * lh UNUSED_ARG /* lock handle for ++ * removal */ , ++ reiser4_dir_entry_desc * entry UNUSED_ARG /* parameters of ++ * directory entry ++ * being removed */ ) ++{ ++ coord_t shadow; ++ int result; ++ int length; ++ ++ length = item_length_by_coord(coord); ++ if (inode_get_bytes(dir) < length) { ++ warning("nikita-2627", "Dir is broke: %llu: %llu", ++ (unsigned long long)get_inode_oid(dir), ++ inode_get_bytes(dir)); ++ ++ return RETERR(-EIO); ++ } ++ ++ /* cut_node() is supposed to take pointers to _different_ ++ coords, because it will modify them without respect to ++ possible aliasing. To work around this, create temporary copy ++ of @coord. ++ */ ++ coord_dup(&shadow, coord); ++ result = ++ kill_node_content(coord, &shadow, NULL, NULL, NULL, NULL, NULL, 0); ++ if (result == 0) { ++ /* NOTE-NIKITA quota plugin */ ++ vfs_dq_free_space_nodirty(dir, length); ++ } ++ return result; ++} ++ ++int max_name_len_de(const struct inode *dir) ++{ ++ return reiser4_tree_by_inode(dir)->nplug->max_item_size() - ++ sizeof(directory_entry_format) - 2; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/sde.h linux-2.6.30/fs/reiser4/plugin/item/sde.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/sde.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/sde.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,66 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Directory entry. */ ++ ++#if !defined( __FS_REISER4_PLUGIN_DIRECTORY_ENTRY_H__ ) ++#define __FS_REISER4_PLUGIN_DIRECTORY_ENTRY_H__ ++ ++#include "../../forward.h" ++#include "../../dformat.h" ++#include "../../kassign.h" ++#include "../../key.h" ++ ++#include <linux/fs.h> ++#include <linux/dcache.h> /* for struct dentry */ ++ ++typedef struct directory_entry_format { ++ /* key of object stat-data. It's not necessary to store whole ++ key here, because it's always key of stat-data, so minor ++ packing locality and offset can be omitted here. But this ++ relies on particular key allocation scheme for stat-data, so, ++ for extensibility sake, whole key can be stored here. ++ ++ We store key as array of bytes, because we don't want 8-byte ++ alignment of dir entries. ++ */ ++ obj_key_id id; ++ /* file name. Null terminated string. */ ++ d8 name[0]; ++} directory_entry_format; ++ ++void print_de(const char *prefix, coord_t * coord); ++int extract_key_de(const coord_t * coord, reiser4_key * key); ++int update_key_de(const coord_t * coord, const reiser4_key * key, ++ lock_handle * lh); ++char *extract_name_de(const coord_t * coord, char *buf); ++unsigned extract_file_type_de(const coord_t * coord); ++int add_entry_de(struct inode *dir, coord_t * coord, ++ lock_handle * lh, const struct dentry *name, ++ reiser4_dir_entry_desc * entry); ++int rem_entry_de(struct inode *dir, const struct qstr *name, coord_t * coord, ++ lock_handle * lh, reiser4_dir_entry_desc * entry); ++int max_name_len_de(const struct inode *dir); ++ ++int de_rem_and_shrink(struct inode *dir, coord_t * coord, int length); ++ ++char *extract_dent_name(const coord_t * coord, ++ directory_entry_format * dent, char *buf); ++ ++#if REISER4_LARGE_KEY ++#define DE_NAME_BUF_LEN (24) ++#else ++#define DE_NAME_BUF_LEN (16) ++#endif ++ ++/* __FS_REISER4_PLUGIN_DIRECTORY_ENTRY_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/static_stat.c linux-2.6.30/fs/reiser4/plugin/item/static_stat.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/static_stat.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/static_stat.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1107 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* stat data manipulation. */ ++ ++#include "../../forward.h" ++#include "../../super.h" ++#include "../../vfs_ops.h" ++#include "../../inode.h" ++#include "../../debug.h" ++#include "../../dformat.h" ++#include "../object.h" ++#include "../plugin.h" ++#include "../plugin_header.h" ++#include "static_stat.h" ++#include "item.h" ++ ++#include <linux/types.h> ++#include <linux/fs.h> ++ ++/* see static_stat.h for explanation */ ++ ++/* helper function used while we are dumping/loading inode/plugin state ++ to/from the stat-data. */ ++ ++static void move_on(int *length /* space remaining in stat-data */ , ++ char **area /* current coord in stat data */ , ++ int size_of /* how many bytes to move forward */ ) ++{ ++ assert("nikita-615", length != NULL); ++ assert("nikita-616", area != NULL); ++ ++ *length -= size_of; ++ *area += size_of; ++ ++ assert("nikita-617", *length >= 0); ++} ++ ++/* helper function used while loading inode/plugin state from stat-data. ++ Complain if there is less space in stat-data than was expected. ++ Can only happen on disk corruption. */ ++static int not_enough_space(struct inode *inode /* object being processed */ , ++ const char *where /* error message */ ) ++{ ++ assert("nikita-618", inode != NULL); ++ ++ warning("nikita-619", "Not enough space in %llu while loading %s", ++ (unsigned long long)get_inode_oid(inode), where); ++ ++ return RETERR(-EINVAL); ++} ++ ++/* helper function used while loading inode/plugin state from ++ stat-data. Call it if invalid plugin id was found. */ ++static int unknown_plugin(reiser4_plugin_id id /* invalid id */ , ++ struct inode *inode /* object being processed */ ) ++{ ++ warning("nikita-620", "Unknown plugin %i in %llu", ++ id, (unsigned long long)get_inode_oid(inode)); ++ ++ return RETERR(-EINVAL); ++} ++ ++/* this is installed as ->init_inode() method of ++ item_plugins[ STATIC_STAT_DATA_IT ] (fs/reiser4/plugin/item/item.c). ++ Copies data from on-disk stat-data format into inode. ++ Handles stat-data extensions. */ ++/* was sd_load */ ++int init_inode_static_sd(struct inode *inode /* object being processed */ , ++ char *sd /* stat-data body */ , ++ int len /* length of stat-data */ ) ++{ ++ int result; ++ int bit; ++ int chunk; ++ __u16 mask; ++ __u64 bigmask; ++ reiser4_stat_data_base *sd_base; ++ reiser4_inode *state; ++ ++ assert("nikita-625", inode != NULL); ++ assert("nikita-626", sd != NULL); ++ ++ result = 0; ++ sd_base = (reiser4_stat_data_base *) sd; ++ state = reiser4_inode_data(inode); ++ mask = le16_to_cpu(get_unaligned(&sd_base->extmask)); ++ bigmask = mask; ++ reiser4_inode_set_flag(inode, REISER4_SDLEN_KNOWN); ++ ++ move_on(&len, &sd, sizeof *sd_base); ++ for (bit = 0, chunk = 0; ++ mask != 0 || bit <= LAST_IMPORTANT_SD_EXTENSION; ++ ++bit, mask >>= 1) { ++ if (((bit + 1) % 16) != 0) { ++ /* handle extension */ ++ sd_ext_plugin *sdplug; ++ ++ if (bit >= LAST_SD_EXTENSION) { ++ warning("vpf-1904", ++ "No such extension %i in inode %llu", ++ bit, ++ (unsigned long long) ++ get_inode_oid(inode)); ++ ++ result = RETERR(-EINVAL); ++ break; ++ } ++ ++ sdplug = sd_ext_plugin_by_id(bit); ++ if (sdplug == NULL) { ++ warning("nikita-627", ++ "No such extension %i in inode %llu", ++ bit, ++ (unsigned long long) ++ get_inode_oid(inode)); ++ ++ result = RETERR(-EINVAL); ++ break; ++ } ++ if (mask & 1) { ++ assert("nikita-628", sdplug->present); ++ /* alignment is not supported in node layout ++ plugin yet. ++ result = align( inode, &len, &sd, ++ sdplug -> alignment ); ++ if( result != 0 ) ++ return result; */ ++ result = sdplug->present(inode, &sd, &len); ++ } else if (sdplug->absent != NULL) ++ result = sdplug->absent(inode); ++ if (result) ++ break; ++ /* else, we are looking at the last bit in 16-bit ++ portion of bitmask */ ++ } else if (mask & 1) { ++ /* next portion of bitmask */ ++ if (len < (int)sizeof(d16)) { ++ warning("nikita-629", ++ "No space for bitmap in inode %llu", ++ (unsigned long long) ++ get_inode_oid(inode)); ++ ++ result = RETERR(-EINVAL); ++ break; ++ } ++ mask = le16_to_cpu(get_unaligned((d16 *)sd)); ++ bigmask <<= 16; ++ bigmask |= mask; ++ move_on(&len, &sd, sizeof(d16)); ++ ++chunk; ++ if (chunk == 3) { ++ if (!(mask & 0x8000)) { ++ /* clear last bit */ ++ mask &= ~0x8000; ++ continue; ++ } ++ /* too much */ ++ warning("nikita-630", ++ "Too many extensions in %llu", ++ (unsigned long long) ++ get_inode_oid(inode)); ++ ++ result = RETERR(-EINVAL); ++ break; ++ } ++ } else ++ /* bitmask exhausted */ ++ break; ++ } ++ state->extmask = bigmask; ++ /* common initialisations */ ++ if (len - (bit / 16 * sizeof(d16)) > 0) { ++ /* alignment in save_len_static_sd() is taken into account ++ -edward */ ++ warning("nikita-631", "unused space in inode %llu", ++ (unsigned long long)get_inode_oid(inode)); ++ } ++ ++ return result; ++} ++ ++/* estimates size of stat-data required to store inode. ++ Installed as ->save_len() method of ++ item_plugins[ STATIC_STAT_DATA_IT ] (fs/reiser4/plugin/item/item.c). */ ++/* was sd_len */ ++int save_len_static_sd(struct inode *inode /* object being processed */ ) ++{ ++ unsigned int result; ++ __u64 mask; ++ int bit; ++ ++ assert("nikita-632", inode != NULL); ++ ++ result = sizeof(reiser4_stat_data_base); ++ mask = reiser4_inode_data(inode)->extmask; ++ for (bit = 0; mask != 0; ++bit, mask >>= 1) { ++ if (mask & 1) { ++ sd_ext_plugin *sdplug; ++ ++ sdplug = sd_ext_plugin_by_id(bit); ++ assert("nikita-633", sdplug != NULL); ++ /* no aligment support ++ result += ++ round_up( result, sdplug -> alignment ) - result; */ ++ result += sdplug->save_len(inode); ++ } ++ } ++ result += bit / 16 * sizeof(d16); ++ return result; ++} ++ ++/* saves inode into stat-data. ++ Installed as ->save() method of ++ item_plugins[ STATIC_STAT_DATA_IT ] (fs/reiser4/plugin/item/item.c). */ ++/* was sd_save */ ++int save_static_sd(struct inode *inode /* object being processed */ , ++ char **area /* where to save stat-data */ ) ++{ ++ int result; ++ __u64 emask; ++ int bit; ++ unsigned int len; ++ reiser4_stat_data_base *sd_base; ++ ++ assert("nikita-634", inode != NULL); ++ assert("nikita-635", area != NULL); ++ ++ result = 0; ++ emask = reiser4_inode_data(inode)->extmask; ++ sd_base = (reiser4_stat_data_base *) * area; ++ put_unaligned(cpu_to_le16((__u16)(emask & 0xffff)), &sd_base->extmask); ++ /*cputod16((unsigned)(emask & 0xffff), &sd_base->extmask);*/ ++ ++ *area += sizeof *sd_base; ++ len = 0xffffffffu; ++ for (bit = 0; emask != 0; ++bit, emask >>= 1) { ++ if (emask & 1) { ++ if ((bit + 1) % 16 != 0) { ++ sd_ext_plugin *sdplug; ++ sdplug = sd_ext_plugin_by_id(bit); ++ assert("nikita-636", sdplug != NULL); ++ /* no alignment support yet ++ align( inode, &len, area, ++ sdplug -> alignment ); */ ++ result = sdplug->save(inode, area); ++ if (result) ++ break; ++ } else { ++ put_unaligned(cpu_to_le16((__u16)(emask & 0xffff)), ++ (d16 *)(*area)); ++ /*cputod16((unsigned)(emask & 0xffff), ++ (d16 *) * area);*/ ++ *area += sizeof(d16); ++ } ++ } ++ } ++ return result; ++} ++ ++/* stat-data extension handling functions. */ ++ ++static int present_lw_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */ , ++ int *len /* remaining length */ ) ++{ ++ if (*len >= (int)sizeof(reiser4_light_weight_stat)) { ++ reiser4_light_weight_stat *sd_lw; ++ ++ sd_lw = (reiser4_light_weight_stat *) * area; ++ ++ inode->i_mode = le16_to_cpu(get_unaligned(&sd_lw->mode)); ++ inode->i_nlink = le32_to_cpu(get_unaligned(&sd_lw->nlink)); ++ inode->i_size = le64_to_cpu(get_unaligned(&sd_lw->size)); ++ if ((inode->i_mode & S_IFMT) == (S_IFREG | S_IFIFO)) { ++ inode->i_mode &= ~S_IFIFO; ++ warning("", "partially converted file is encountered"); ++ reiser4_inode_set_flag(inode, REISER4_PART_MIXED); ++ } ++ move_on(len, area, sizeof *sd_lw); ++ return 0; ++ } else ++ return not_enough_space(inode, "lw sd"); ++} ++ ++static int save_len_lw_sd(struct inode *inode UNUSED_ARG /* object being ++ * processed */ ) ++{ ++ return sizeof(reiser4_light_weight_stat); ++} ++ ++static int save_lw_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */ ) ++{ ++ reiser4_light_weight_stat *sd; ++ mode_t delta; ++ ++ assert("nikita-2705", inode != NULL); ++ assert("nikita-2706", area != NULL); ++ assert("nikita-2707", *area != NULL); ++ ++ sd = (reiser4_light_weight_stat *) * area; ++ ++ delta = (reiser4_inode_get_flag(inode, ++ REISER4_PART_MIXED) ? S_IFIFO : 0); ++ put_unaligned(cpu_to_le16(inode->i_mode | delta), &sd->mode); ++ put_unaligned(cpu_to_le32(inode->i_nlink), &sd->nlink); ++ put_unaligned(cpu_to_le64((__u64) inode->i_size), &sd->size); ++ *area += sizeof *sd; ++ return 0; ++} ++ ++static int present_unix_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */ , ++ int *len /* remaining length */ ) ++{ ++ assert("nikita-637", inode != NULL); ++ assert("nikita-638", area != NULL); ++ assert("nikita-639", *area != NULL); ++ assert("nikita-640", len != NULL); ++ assert("nikita-641", *len > 0); ++ ++ if (*len >= (int)sizeof(reiser4_unix_stat)) { ++ reiser4_unix_stat *sd; ++ ++ sd = (reiser4_unix_stat *) * area; ++ ++ inode->i_uid = le32_to_cpu(get_unaligned(&sd->uid)); ++ inode->i_gid = le32_to_cpu(get_unaligned(&sd->gid)); ++ inode->i_atime.tv_sec = le32_to_cpu(get_unaligned(&sd->atime)); ++ inode->i_mtime.tv_sec = le32_to_cpu(get_unaligned(&sd->mtime)); ++ inode->i_ctime.tv_sec = le32_to_cpu(get_unaligned(&sd->ctime)); ++ if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) ++ inode->i_rdev = le64_to_cpu(get_unaligned(&sd->u.rdev)); ++ else ++ inode_set_bytes(inode, (loff_t) le64_to_cpu(get_unaligned(&sd->u.bytes))); ++ move_on(len, area, sizeof *sd); ++ return 0; ++ } else ++ return not_enough_space(inode, "unix sd"); ++} ++ ++static int absent_unix_sd(struct inode *inode /* object being processed */ ) ++{ ++ inode->i_uid = get_super_private(inode->i_sb)->default_uid; ++ inode->i_gid = get_super_private(inode->i_sb)->default_gid; ++ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; ++ inode_set_bytes(inode, inode->i_size); ++ /* mark inode as lightweight, so that caller (lookup_common) will ++ complete initialisation by copying [ug]id from a parent. */ ++ reiser4_inode_set_flag(inode, REISER4_LIGHT_WEIGHT); ++ return 0; ++} ++ ++/* Audited by: green(2002.06.14) */ ++static int save_len_unix_sd(struct inode *inode UNUSED_ARG /* object being ++ * processed */ ) ++{ ++ return sizeof(reiser4_unix_stat); ++} ++ ++static int save_unix_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */ ) ++{ ++ reiser4_unix_stat *sd; ++ ++ assert("nikita-642", inode != NULL); ++ assert("nikita-643", area != NULL); ++ assert("nikita-644", *area != NULL); ++ ++ sd = (reiser4_unix_stat *) * area; ++ put_unaligned(cpu_to_le32(inode->i_uid), &sd->uid); ++ put_unaligned(cpu_to_le32(inode->i_gid), &sd->gid); ++ put_unaligned(cpu_to_le32((__u32) inode->i_atime.tv_sec), &sd->atime); ++ put_unaligned(cpu_to_le32((__u32) inode->i_ctime.tv_sec), &sd->ctime); ++ put_unaligned(cpu_to_le32((__u32) inode->i_mtime.tv_sec), &sd->mtime); ++ if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) ++ put_unaligned(cpu_to_le64(inode->i_rdev), &sd->u.rdev); ++ else ++ put_unaligned(cpu_to_le64((__u64) inode_get_bytes(inode)), &sd->u.bytes); ++ *area += sizeof *sd; ++ return 0; ++} ++ ++static int ++present_large_times_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */ , ++ int *len /* remaining length */ ) ++{ ++ if (*len >= (int)sizeof(reiser4_large_times_stat)) { ++ reiser4_large_times_stat *sd_lt; ++ ++ sd_lt = (reiser4_large_times_stat *) * area; ++ ++ inode->i_atime.tv_nsec = le32_to_cpu(get_unaligned(&sd_lt->atime)); ++ inode->i_mtime.tv_nsec = le32_to_cpu(get_unaligned(&sd_lt->mtime)); ++ inode->i_ctime.tv_nsec = le32_to_cpu(get_unaligned(&sd_lt->ctime)); ++ ++ move_on(len, area, sizeof *sd_lt); ++ return 0; ++ } else ++ return not_enough_space(inode, "large times sd"); ++} ++ ++static int ++save_len_large_times_sd(struct inode *inode UNUSED_ARG ++ /* object being processed */ ) ++{ ++ return sizeof(reiser4_large_times_stat); ++} ++ ++static int ++save_large_times_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */ ) ++{ ++ reiser4_large_times_stat *sd; ++ ++ assert("nikita-2817", inode != NULL); ++ assert("nikita-2818", area != NULL); ++ assert("nikita-2819", *area != NULL); ++ ++ sd = (reiser4_large_times_stat *) * area; ++ ++ put_unaligned(cpu_to_le32((__u32) inode->i_atime.tv_nsec), &sd->atime); ++ put_unaligned(cpu_to_le32((__u32) inode->i_ctime.tv_nsec), &sd->ctime); ++ put_unaligned(cpu_to_le32((__u32) inode->i_mtime.tv_nsec), &sd->mtime); ++ ++ *area += sizeof *sd; ++ return 0; ++} ++ ++/* symlink stat data extension */ ++ ++/* allocate memory for symlink target and attach it to inode->i_private */ ++static int ++symlink_target_to_inode(struct inode *inode, const char *target, int len) ++{ ++ assert("vs-845", inode->i_private == NULL); ++ assert("vs-846", !reiser4_inode_get_flag(inode, ++ REISER4_GENERIC_PTR_USED)); ++ /* FIXME-VS: this is prone to deadlock. Not more than other similar ++ places, though */ ++ inode->i_private = kmalloc((size_t) len + 1, ++ reiser4_ctx_gfp_mask_get()); ++ if (!inode->i_private) ++ return RETERR(-ENOMEM); ++ ++ memcpy((char *)(inode->i_private), target, (size_t) len); ++ ((char *)(inode->i_private))[len] = 0; ++ reiser4_inode_set_flag(inode, REISER4_GENERIC_PTR_USED); ++ return 0; ++} ++ ++/* this is called on read_inode. There is nothing to do actually, but some ++ sanity checks */ ++static int present_symlink_sd(struct inode *inode, char **area, int *len) ++{ ++ int result; ++ int length; ++ reiser4_symlink_stat *sd; ++ ++ length = (int)inode->i_size; ++ /* ++ * *len is number of bytes in stat data item from *area to the end of ++ * item. It must be not less than size of symlink + 1 for ending 0 ++ */ ++ if (length > *len) ++ return not_enough_space(inode, "symlink"); ++ ++ if (*(*area + length) != 0) { ++ warning("vs-840", "Symlink is not zero terminated"); ++ return RETERR(-EIO); ++ } ++ ++ sd = (reiser4_symlink_stat *) * area; ++ result = symlink_target_to_inode(inode, sd->body, length); ++ ++ move_on(len, area, length + 1); ++ return result; ++} ++ ++static int save_len_symlink_sd(struct inode *inode) ++{ ++ return inode->i_size + 1; ++} ++ ++/* this is called on create and update stat data. Do nothing on update but ++ update @area */ ++static int save_symlink_sd(struct inode *inode, char **area) ++{ ++ int result; ++ int length; ++ reiser4_symlink_stat *sd; ++ ++ length = (int)inode->i_size; ++ /* inode->i_size must be set already */ ++ assert("vs-841", length); ++ ++ result = 0; ++ sd = (reiser4_symlink_stat *) * area; ++ if (!reiser4_inode_get_flag(inode, REISER4_GENERIC_PTR_USED)) { ++ const char *target; ++ ++ target = (const char *)(inode->i_private); ++ inode->i_private = NULL; ++ ++ result = symlink_target_to_inode(inode, target, length); ++ ++ /* copy symlink to stat data */ ++ memcpy(sd->body, target, (size_t) length); ++ (*area)[length] = 0; ++ } else { ++ /* there is nothing to do in update but move area */ ++ assert("vs-844", ++ !memcmp(inode->i_private, sd->body, ++ (size_t) length + 1)); ++ } ++ ++ *area += (length + 1); ++ return result; ++} ++ ++static int present_flags_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */ , ++ int *len /* remaining length */ ) ++{ ++ assert("nikita-645", inode != NULL); ++ assert("nikita-646", area != NULL); ++ assert("nikita-647", *area != NULL); ++ assert("nikita-648", len != NULL); ++ assert("nikita-649", *len > 0); ++ ++ if (*len >= (int)sizeof(reiser4_flags_stat)) { ++ reiser4_flags_stat *sd; ++ ++ sd = (reiser4_flags_stat *) * area; ++ inode->i_flags = le32_to_cpu(get_unaligned(&sd->flags)); ++ move_on(len, area, sizeof *sd); ++ return 0; ++ } else ++ return not_enough_space(inode, "generation and attrs"); ++} ++ ++/* Audited by: green(2002.06.14) */ ++static int save_len_flags_sd(struct inode *inode UNUSED_ARG /* object being ++ * processed */ ) ++{ ++ return sizeof(reiser4_flags_stat); ++} ++ ++static int save_flags_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */ ) ++{ ++ reiser4_flags_stat *sd; ++ ++ assert("nikita-650", inode != NULL); ++ assert("nikita-651", area != NULL); ++ assert("nikita-652", *area != NULL); ++ ++ sd = (reiser4_flags_stat *) * area; ++ put_unaligned(cpu_to_le32(inode->i_flags), &sd->flags); ++ *area += sizeof *sd; ++ return 0; ++} ++ ++static int absent_plugin_sd(struct inode *inode); ++static int present_plugin_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */ , ++ int *len /* remaining length */, ++ int is_pset /* 1 if plugin set, 0 if heir set. */) ++{ ++ reiser4_plugin_stat *sd; ++ reiser4_plugin *plugin; ++ reiser4_inode *info; ++ int i; ++ __u16 mask; ++ int result; ++ int num_of_plugins; ++ ++ assert("nikita-653", inode != NULL); ++ assert("nikita-654", area != NULL); ++ assert("nikita-655", *area != NULL); ++ assert("nikita-656", len != NULL); ++ assert("nikita-657", *len > 0); ++ ++ if (*len < (int)sizeof(reiser4_plugin_stat)) ++ return not_enough_space(inode, "plugin"); ++ ++ sd = (reiser4_plugin_stat *) * area; ++ info = reiser4_inode_data(inode); ++ ++ mask = 0; ++ num_of_plugins = le16_to_cpu(get_unaligned(&sd->plugins_no)); ++ move_on(len, area, sizeof *sd); ++ result = 0; ++ for (i = 0; i < num_of_plugins; ++i) { ++ reiser4_plugin_slot *slot; ++ reiser4_plugin_type type; ++ pset_member memb; ++ ++ slot = (reiser4_plugin_slot *) * area; ++ if (*len < (int)sizeof *slot) ++ return not_enough_space(inode, "additional plugin"); ++ ++ memb = le16_to_cpu(get_unaligned(&slot->pset_memb)); ++ type = aset_member_to_type_unsafe(memb); ++ ++ if (type == REISER4_PLUGIN_TYPES) { ++ warning("nikita-3502", ++ "wrong %s member (%i) for %llu", is_pset ? ++ "pset" : "hset", memb, ++ (unsigned long long)get_inode_oid(inode)); ++ return RETERR(-EINVAL); ++ } ++ plugin = plugin_by_disk_id(reiser4_tree_by_inode(inode), ++ type, &slot->id); ++ if (plugin == NULL) ++ return unknown_plugin(le16_to_cpu(get_unaligned(&slot->id)), inode); ++ ++ /* plugin is loaded into inode, mark this into inode's ++ bitmask of loaded non-standard plugins */ ++ if (!(mask & (1 << memb))) { ++ mask |= (1 << memb); ++ } else { ++ warning("nikita-658", "duplicate plugin for %llu", ++ (unsigned long long)get_inode_oid(inode)); ++ return RETERR(-EINVAL); ++ } ++ move_on(len, area, sizeof *slot); ++ /* load plugin data, if any */ ++ if (plugin->h.pops != NULL && plugin->h.pops->load) ++ result = plugin->h.pops->load(inode, plugin, area, len); ++ else ++ result = aset_set_unsafe(is_pset ? &info->pset : ++ &info->hset, memb, plugin); ++ if (result) ++ return result; ++ } ++ if (is_pset) { ++ /* if object plugin wasn't loaded from stat-data, guess it by ++ mode bits */ ++ plugin = file_plugin_to_plugin(inode_file_plugin(inode)); ++ if (plugin == NULL) ++ result = absent_plugin_sd(inode); ++ info->plugin_mask = mask; ++ } else ++ info->heir_mask = mask; ++ ++ return result; ++} ++ ++static int present_pset_sd(struct inode *inode, char **area, int *len) { ++ return present_plugin_sd(inode, area, len, 1 /* pset */); ++} ++ ++/* Determine object plugin for @inode based on i_mode. ++ ++ Many objects in reiser4 file system are controlled by standard object ++ plugins that emulate traditional unix objects: unix file, directory, symlink, fifo, and so on. ++ ++ For such files we don't explicitly store plugin id in object stat ++ data. Rather required plugin is guessed from mode bits, where file "type" ++ is encoded (see stat(2)). ++*/ ++static int ++guess_plugin_by_mode(struct inode *inode /* object to guess plugins for */ ) ++{ ++ int fplug_id; ++ int dplug_id; ++ reiser4_inode *info; ++ ++ assert("nikita-736", inode != NULL); ++ ++ dplug_id = fplug_id = -1; ++ ++ switch (inode->i_mode & S_IFMT) { ++ case S_IFSOCK: ++ case S_IFBLK: ++ case S_IFCHR: ++ case S_IFIFO: ++ fplug_id = SPECIAL_FILE_PLUGIN_ID; ++ break; ++ case S_IFLNK: ++ fplug_id = SYMLINK_FILE_PLUGIN_ID; ++ break; ++ case S_IFDIR: ++ fplug_id = DIRECTORY_FILE_PLUGIN_ID; ++ dplug_id = HASHED_DIR_PLUGIN_ID; ++ break; ++ default: ++ warning("nikita-737", "wrong file mode: %o", inode->i_mode); ++ return RETERR(-EIO); ++ case S_IFREG: ++ fplug_id = UNIX_FILE_PLUGIN_ID; ++ break; ++ } ++ info = reiser4_inode_data(inode); ++ set_plugin(&info->pset, PSET_FILE, (fplug_id >= 0) ? ++ plugin_by_id(REISER4_FILE_PLUGIN_TYPE, fplug_id) : NULL); ++ set_plugin(&info->pset, PSET_DIR, (dplug_id >= 0) ? ++ plugin_by_id(REISER4_DIR_PLUGIN_TYPE, dplug_id) : NULL); ++ return 0; ++} ++ ++/* Audited by: green(2002.06.14) */ ++static int absent_plugin_sd(struct inode *inode /* object being processed */ ) ++{ ++ int result; ++ ++ assert("nikita-659", inode != NULL); ++ ++ result = guess_plugin_by_mode(inode); ++ /* if mode was wrong, guess_plugin_by_mode() returns "regular file", ++ but setup_inode_ops() will call make_bad_inode(). ++ Another, more logical but bit more complex solution is to add ++ "bad-file plugin". */ ++ /* FIXME-VS: activate was called here */ ++ return result; ++} ++ ++/* helper function for plugin_sd_save_len(): calculate how much space ++ required to save state of given plugin */ ++/* Audited by: green(2002.06.14) */ ++static int len_for(reiser4_plugin * plugin /* plugin to save */ , ++ struct inode *inode /* object being processed */ , ++ pset_member memb, ++ int len, int is_pset) ++{ ++ reiser4_inode *info; ++ assert("nikita-661", inode != NULL); ++ ++ if (plugin == NULL) ++ return len; ++ ++ info = reiser4_inode_data(inode); ++ if (is_pset ? ++ info->plugin_mask & (1 << memb) : ++ info->heir_mask & (1 << memb)) { ++ len += sizeof(reiser4_plugin_slot); ++ if (plugin->h.pops && plugin->h.pops->save_len != NULL) { ++ /* non-standard plugin, call method */ ++ /* commented as it is incompatible with alignment ++ * policy in save_plug() -edward */ ++ /* len = round_up(len, plugin->h.pops->alignment); */ ++ len += plugin->h.pops->save_len(inode, plugin); ++ } ++ } ++ return len; ++} ++ ++/* calculate how much space is required to save state of all plugins, ++ associated with inode */ ++static int save_len_plugin_sd(struct inode *inode /* object being processed */, ++ int is_pset) ++{ ++ int len; ++ int last; ++ reiser4_inode *state; ++ pset_member memb; ++ ++ assert("nikita-663", inode != NULL); ++ ++ state = reiser4_inode_data(inode); ++ ++ /* common case: no non-standard plugins */ ++ if (is_pset ? state->plugin_mask == 0 : state->heir_mask == 0) ++ return 0; ++ len = sizeof(reiser4_plugin_stat); ++ last = PSET_LAST; ++ ++ for (memb = 0; memb < last; ++memb) { ++ len = len_for(aset_get(is_pset ? state->pset : state->hset, memb), ++ inode, memb, len, is_pset); ++ } ++ assert("nikita-664", len > (int)sizeof(reiser4_plugin_stat)); ++ return len; ++} ++ ++static int save_len_pset_sd(struct inode *inode) { ++ return save_len_plugin_sd(inode, 1 /* pset */); ++} ++ ++/* helper function for plugin_sd_save(): save plugin, associated with ++ inode. */ ++static int save_plug(reiser4_plugin * plugin /* plugin to save */ , ++ struct inode *inode /* object being processed */ , ++ int memb /* what element of pset is saved */ , ++ char **area /* position in stat-data */ , ++ int *count /* incremented if plugin were actually saved. */, ++ int is_pset /* 1 for plugin set, 0 for heir set */) ++{ ++ reiser4_plugin_slot *slot; ++ int fake_len; ++ int result; ++ ++ assert("nikita-665", inode != NULL); ++ assert("nikita-666", area != NULL); ++ assert("nikita-667", *area != NULL); ++ ++ if (plugin == NULL) ++ return 0; ++ ++ if (is_pset ? ++ !(reiser4_inode_data(inode)->plugin_mask & (1 << memb)) : ++ !(reiser4_inode_data(inode)->heir_mask & (1 << memb))) ++ return 0; ++ slot = (reiser4_plugin_slot *) * area; ++ put_unaligned(cpu_to_le16(memb), &slot->pset_memb); ++ put_unaligned(cpu_to_le16(plugin->h.id), &slot->id); ++ fake_len = (int)0xffff; ++ move_on(&fake_len, area, sizeof *slot); ++ ++*count; ++ result = 0; ++ if (plugin->h.pops != NULL) { ++ if (plugin->h.pops->save != NULL) ++ result = plugin->h.pops->save(inode, plugin, area); ++ } ++ return result; ++} ++ ++/* save state of all non-standard plugins associated with inode */ ++static int save_plugin_sd(struct inode *inode /* object being processed */ , ++ char **area /* position in stat-data */, ++ int is_pset /* 1 for pset, 0 for hset */) ++{ ++ int fake_len; ++ int result = 0; ++ int num_of_plugins; ++ reiser4_plugin_stat *sd; ++ reiser4_inode *state; ++ pset_member memb; ++ ++ assert("nikita-669", inode != NULL); ++ assert("nikita-670", area != NULL); ++ assert("nikita-671", *area != NULL); ++ ++ state = reiser4_inode_data(inode); ++ if (is_pset ? state->plugin_mask == 0 : state->heir_mask == 0) ++ return 0; ++ sd = (reiser4_plugin_stat *) * area; ++ fake_len = (int)0xffff; ++ move_on(&fake_len, area, sizeof *sd); ++ ++ num_of_plugins = 0; ++ for (memb = 0; memb < PSET_LAST; ++memb) { ++ result = save_plug(aset_get(is_pset ? state->pset : state->hset, ++ memb), ++ inode, memb, area, &num_of_plugins, is_pset); ++ if (result != 0) ++ break; ++ } ++ ++ put_unaligned(cpu_to_le16((__u16)num_of_plugins), &sd->plugins_no); ++ return result; ++} ++ ++static int save_pset_sd(struct inode *inode, char **area) { ++ return save_plugin_sd(inode, area, 1 /* pset */); ++} ++ ++static int present_hset_sd(struct inode *inode, char **area, int *len) { ++ return present_plugin_sd(inode, area, len, 0 /* hset */); ++} ++ ++static int save_len_hset_sd(struct inode *inode) { ++ return save_len_plugin_sd(inode, 0 /* pset */); ++} ++ ++static int save_hset_sd(struct inode *inode, char **area) { ++ return save_plugin_sd(inode, area, 0 /* hset */); ++} ++ ++/* helper function for crypto_sd_present(), crypto_sd_save. ++ Extract crypto info from stat-data and attach it to inode */ ++static int extract_crypto_info (struct inode * inode, ++ reiser4_crypto_stat * sd) ++{ ++ struct reiser4_crypto_info * info; ++ assert("edward-11", !inode_crypto_info(inode)); ++ assert("edward-1413", ++ !reiser4_inode_get_flag(inode, REISER4_CRYPTO_STAT_LOADED)); ++ /* create and attach a crypto-stat without secret key loaded */ ++ info = reiser4_alloc_crypto_info(inode); ++ if (IS_ERR(info)) ++ return PTR_ERR(info); ++ info->keysize = le16_to_cpu(get_unaligned(&sd->keysize)); ++ memcpy(info->keyid, sd->keyid, inode_digest_plugin(inode)->fipsize); ++ reiser4_attach_crypto_info(inode, info); ++ reiser4_inode_set_flag(inode, REISER4_CRYPTO_STAT_LOADED); ++ return 0; ++} ++ ++/* crypto stat-data extension */ ++ ++static int present_crypto_sd(struct inode *inode, char **area, int *len) ++{ ++ int result; ++ reiser4_crypto_stat *sd; ++ digest_plugin *dplug = inode_digest_plugin(inode); ++ ++ assert("edward-06", dplug != NULL); ++ assert("edward-684", dplug->fipsize); ++ assert("edward-07", area != NULL); ++ assert("edward-08", *area != NULL); ++ assert("edward-09", len != NULL); ++ assert("edward-10", *len > 0); ++ ++ if (*len < (int)sizeof(reiser4_crypto_stat)) { ++ return not_enough_space(inode, "crypto-sd"); ++ } ++ /* *len is number of bytes in stat data item from *area to the end of ++ item. It must be not less than size of this extension */ ++ assert("edward-75", sizeof(*sd) + dplug->fipsize <= *len); ++ ++ sd = (reiser4_crypto_stat *) * area; ++ result = extract_crypto_info(inode, sd); ++ move_on(len, area, sizeof(*sd) + dplug->fipsize); ++ ++ return result; ++} ++ ++static int save_len_crypto_sd(struct inode *inode) ++{ ++ return sizeof(reiser4_crypto_stat) + ++ inode_digest_plugin(inode)->fipsize; ++} ++ ++static int save_crypto_sd(struct inode *inode, char **area) ++{ ++ int result = 0; ++ reiser4_crypto_stat *sd; ++ struct reiser4_crypto_info * info = inode_crypto_info(inode); ++ digest_plugin *dplug = inode_digest_plugin(inode); ++ ++ assert("edward-12", dplug != NULL); ++ assert("edward-13", area != NULL); ++ assert("edward-14", *area != NULL); ++ assert("edward-15", info != NULL); ++ assert("edward-1414", info->keyid != NULL); ++ assert("edward-1415", info->keysize != 0); ++ assert("edward-76", reiser4_inode_data(inode) != NULL); ++ ++ if (!reiser4_inode_get_flag(inode, REISER4_CRYPTO_STAT_LOADED)) { ++ /* file is just created */ ++ sd = (reiser4_crypto_stat *) *area; ++ /* copy everything but private key to the disk stat-data */ ++ put_unaligned(cpu_to_le16(info->keysize), &sd->keysize); ++ memcpy(sd->keyid, info->keyid, (size_t) dplug->fipsize); ++ reiser4_inode_set_flag(inode, REISER4_CRYPTO_STAT_LOADED); ++ } ++ *area += (sizeof(*sd) + dplug->fipsize); ++ return result; ++} ++ ++static int eio(struct inode *inode, char **area, int *len) ++{ ++ return RETERR(-EIO); ++} ++ ++sd_ext_plugin sd_ext_plugins[LAST_SD_EXTENSION] = { ++ [LIGHT_WEIGHT_STAT] = { ++ .h = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .id = LIGHT_WEIGHT_STAT, ++ .pops = NULL, ++ .label = "light-weight sd", ++ .desc = "sd for light-weight files", ++ .linkage = {NULL,NULL} ++ }, ++ .present = present_lw_sd, ++ .absent = NULL, ++ .save_len = save_len_lw_sd, ++ .save = save_lw_sd, ++ .alignment = 8 ++ }, ++ [UNIX_STAT] = { ++ .h = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .id = UNIX_STAT, ++ .pops = NULL, ++ .label = "unix-sd", ++ .desc = "unix stat-data fields", ++ .linkage = {NULL,NULL} ++ }, ++ .present = present_unix_sd, ++ .absent = absent_unix_sd, ++ .save_len = save_len_unix_sd, ++ .save = save_unix_sd, ++ .alignment = 8 ++ }, ++ [LARGE_TIMES_STAT] = { ++ .h = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .id = LARGE_TIMES_STAT, ++ .pops = NULL, ++ .label = "64time-sd", ++ .desc = "nanosecond resolution for times", ++ .linkage = {NULL,NULL} ++ }, ++ .present = present_large_times_sd, ++ .absent = NULL, ++ .save_len = save_len_large_times_sd, ++ .save = save_large_times_sd, ++ .alignment = 8 ++ }, ++ [SYMLINK_STAT] = { ++ /* stat data of symlink has this extension */ ++ .h = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .id = SYMLINK_STAT, ++ .pops = NULL, ++ .label = "symlink-sd", ++ .desc = ++ "stat data is appended with symlink name", ++ .linkage = {NULL,NULL} ++ }, ++ .present = present_symlink_sd, ++ .absent = NULL, ++ .save_len = save_len_symlink_sd, ++ .save = save_symlink_sd, ++ .alignment = 8 ++ }, ++ [PLUGIN_STAT] = { ++ .h = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .id = PLUGIN_STAT, ++ .pops = NULL, ++ .label = "plugin-sd", ++ .desc = "plugin stat-data fields", ++ .linkage = {NULL,NULL} ++ }, ++ .present = present_pset_sd, ++ .absent = absent_plugin_sd, ++ .save_len = save_len_pset_sd, ++ .save = save_pset_sd, ++ .alignment = 8 ++ }, ++ [HEIR_STAT] = { ++ .h = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .id = HEIR_STAT, ++ .pops = NULL, ++ .label = "heir-plugin-sd", ++ .desc = "heir plugin stat-data fields", ++ .linkage = {NULL,NULL} ++ }, ++ .present = present_hset_sd, ++ .absent = NULL, ++ .save_len = save_len_hset_sd, ++ .save = save_hset_sd, ++ .alignment = 8 ++ }, ++ [FLAGS_STAT] = { ++ .h = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .id = FLAGS_STAT, ++ .pops = NULL, ++ .label = "flags-sd", ++ .desc = "inode bit flags", ++ .linkage = {NULL, NULL} ++ }, ++ .present = present_flags_sd, ++ .absent = NULL, ++ .save_len = save_len_flags_sd, ++ .save = save_flags_sd, ++ .alignment = 8 ++ }, ++ [CAPABILITIES_STAT] = { ++ .h = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .id = CAPABILITIES_STAT, ++ .pops = NULL, ++ .label = "capabilities-sd", ++ .desc = "capabilities", ++ .linkage = {NULL, NULL} ++ }, ++ .present = eio, ++ .absent = NULL, ++ .save_len = save_len_flags_sd, ++ .save = save_flags_sd, ++ .alignment = 8 ++ }, ++ [CRYPTO_STAT] = { ++ .h = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .id = CRYPTO_STAT, ++ .pops = NULL, ++ .label = "crypto-sd", ++ .desc = "secret key size and id", ++ .linkage = {NULL, NULL} ++ }, ++ .present = present_crypto_sd, ++ .absent = NULL, ++ .save_len = save_len_crypto_sd, ++ .save = save_crypto_sd, ++ .alignment = 8 ++ } ++}; ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/static_stat.h linux-2.6.30/fs/reiser4/plugin/item/static_stat.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/static_stat.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/static_stat.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,224 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* This describes the static_stat item, used to hold all information needed by the stat() syscall. ++ ++In the case where each file has not less than the fields needed by the ++stat() syscall, it is more compact to store those fields in this ++struct. ++ ++If this item does not exist, then all stats are dynamically resolved. ++At the moment, we either resolve all stats dynamically or all of them ++statically. If you think this is not fully optimal, and the rest of ++reiser4 is working, then fix it...:-) ++ ++*/ ++ ++#if !defined( __FS_REISER4_PLUGIN_ITEM_STATIC_STAT_H__ ) ++#define __FS_REISER4_PLUGIN_ITEM_STATIC_STAT_H__ ++ ++#include "../../forward.h" ++#include "../../dformat.h" ++ ++#include <linux/fs.h> /* for struct inode */ ++ ++/* Stat data layout: goals and implementation. ++ ++ We want to be able to have lightweight files which have complete flexibility in what semantic metadata is attached to ++ them, including not having semantic metadata attached to them. ++ ++ There is one problem with doing that, which is that if in fact you have exactly the same metadata for most files you ++ want to store, then it takes more space to store that metadata in a dynamically sized structure than in a statically ++ sized structure because the statically sized structure knows without recording it what the names and lengths of the ++ attributes are. ++ ++ This leads to a natural compromise, which is to special case those files which have simply the standard unix file ++ attributes, and only employ the full dynamic stat data mechanism for those files that differ from the standard unix ++ file in their use of file attributes. ++ ++ Yet this compromise deserves to be compromised a little. ++ ++ We accommodate the case where you have no more than the standard unix file attributes by using an "extension ++ bitmask": each bit in it indicates presence or absence of or particular stat data extension (see sd_ext_bits enum). ++ ++ If the first bit of the extension bitmask bit is 0, we have light-weight file whose attributes are either inherited ++ from parent directory (as uid, gid) or initialised to some sane values. ++ ++ To capitalize on existing code infrastructure, extensions are ++ implemented as plugins of type REISER4_SD_EXT_PLUGIN_TYPE. ++ Each stat-data extension plugin implements four methods: ++ ++ ->present() called by sd_load() when this extension is found in stat-data ++ ->absent() called by sd_load() when this extension is not found in stat-data ++ ->save_len() called by sd_len() to calculate total length of stat-data ++ ->save() called by sd_save() to store extension data into stat-data ++ ++ Implementation is in fs/reiser4/plugin/item/static_stat.c ++*/ ++ ++/* stat-data extension. Please order this by presumed frequency of use */ ++typedef enum { ++ /* support for light-weight files */ ++ LIGHT_WEIGHT_STAT, ++ /* data required to implement unix stat(2) call. Layout is in ++ reiser4_unix_stat. If this is not present, file is light-weight */ ++ UNIX_STAT, ++ /* this contains additional set of 32bit [anc]time fields to implement ++ nanosecond resolution. Layout is in reiser4_large_times_stat. Usage ++ if this extension is governed by 32bittimes mount option. */ ++ LARGE_TIMES_STAT, ++ /* stat data has link name included */ ++ SYMLINK_STAT, ++ /* on-disk slots of non-standard plugins for main plugin table ++ (@reiser4_inode->pset), that is, plugins that cannot be deduced ++ from file mode bits), for example, aggregation, interpolation etc. */ ++ PLUGIN_STAT, ++ /* this extension contains persistent inode flags. These flags are ++ single bits: immutable, append, only, etc. Layout is in ++ reiser4_flags_stat. */ ++ FLAGS_STAT, ++ /* this extension contains capabilities sets, associated with this ++ file. Layout is in reiser4_capabilities_stat */ ++ CAPABILITIES_STAT, ++ /* this extension contains size and public id of the secret key. ++ Layout is in reiser4_crypto_stat */ ++ CRYPTO_STAT, ++ /* on-disk slots of non-default plugins for inheritance, which ++ are extracted to special plugin table (@reiser4_inode->hset). ++ By default, children of the object will inherit plugins from ++ its main plugin table (pset). */ ++ HEIR_STAT, ++ LAST_SD_EXTENSION, ++ /* ++ * init_inode_static_sd() iterates over extension mask until all ++ * non-zero bits are processed. This means, that neither ->present(), ++ * nor ->absent() methods will be called for stat-data extensions that ++ * go after last present extension. But some basic extensions, we want ++ * either ->absent() or ->present() method to be called, because these ++ * extensions set up something in inode even when they are not ++ * present. This is what LAST_IMPORTANT_SD_EXTENSION is for: for all ++ * extensions before and including LAST_IMPORTANT_SD_EXTENSION either ++ * ->present(), or ->absent() method will be called, independently of ++ * what other extensions are present. ++ */ ++ LAST_IMPORTANT_SD_EXTENSION = PLUGIN_STAT ++} sd_ext_bits; ++ ++/* minimal stat-data. This allows to support light-weight files. */ ++typedef struct reiser4_stat_data_base { ++ /* 0 */ __le16 extmask; ++ /* 2 */ ++} PACKED reiser4_stat_data_base; ++ ++typedef struct reiser4_light_weight_stat { ++ /* 0 */ __le16 mode; ++ /* 2 */ __le32 nlink; ++ /* 6 */ __le64 size; ++ /* size in bytes */ ++ /* 14 */ ++} PACKED reiser4_light_weight_stat; ++ ++typedef struct reiser4_unix_stat { ++ /* owner id */ ++ /* 0 */ __le32 uid; ++ /* group id */ ++ /* 4 */ __le32 gid; ++ /* access time */ ++ /* 8 */ __le32 atime; ++ /* modification time */ ++ /* 12 */ __le32 mtime; ++ /* change time */ ++ /* 16 */ __le32 ctime; ++ union { ++ /* minor:major for device files */ ++ /* 20 */ __le64 rdev; ++ /* bytes used by file */ ++ /* 20 */ __le64 bytes; ++ } u; ++ /* 28 */ ++} PACKED reiser4_unix_stat; ++ ++/* symlink stored as part of inode */ ++typedef struct reiser4_symlink_stat { ++ char body[0]; ++} PACKED reiser4_symlink_stat; ++ ++typedef struct reiser4_plugin_slot { ++ /* 0 */ __le16 pset_memb; ++ /* 2 */ __le16 id; ++ /* 4 *//* here plugin stores its persistent state */ ++} PACKED reiser4_plugin_slot; ++ ++/* stat-data extension for files with non-standard plugin. */ ++typedef struct reiser4_plugin_stat { ++ /* number of additional plugins, associated with this object */ ++ /* 0 */ __le16 plugins_no; ++ /* 2 */ reiser4_plugin_slot slot[0]; ++ /* 2 */ ++} PACKED reiser4_plugin_stat; ++ ++/* stat-data extension for inode flags. Currently it is just fixed-width 32 ++ * bit mask. If need arise, this can be replaced with variable width ++ * bitmask. */ ++typedef struct reiser4_flags_stat { ++ /* 0 */ __le32 flags; ++ /* 4 */ ++} PACKED reiser4_flags_stat; ++ ++typedef struct reiser4_capabilities_stat { ++ /* 0 */ __le32 effective; ++ /* 8 */ __le32 permitted; ++ /* 16 */ ++} PACKED reiser4_capabilities_stat; ++ ++typedef struct reiser4_cluster_stat { ++/* this defines cluster size (an attribute of cryptcompress objects) as PAGE_SIZE << cluster shift */ ++ /* 0 */ d8 cluster_shift; ++ /* 1 */ ++} PACKED reiser4_cluster_stat; ++ ++typedef struct reiser4_crypto_stat { ++ /* secret key size, bits */ ++ /* 0 */ d16 keysize; ++ /* secret key id */ ++ /* 2 */ d8 keyid[0]; ++ /* 2 */ ++} PACKED reiser4_crypto_stat; ++ ++typedef struct reiser4_large_times_stat { ++ /* access time */ ++ /* 0 */ d32 atime; ++ /* modification time */ ++ /* 4 */ d32 mtime; ++ /* change time */ ++ /* 8 */ d32 ctime; ++ /* 12 */ ++} PACKED reiser4_large_times_stat; ++ ++/* this structure is filled by sd_item_stat */ ++typedef struct sd_stat { ++ int dirs; ++ int files; ++ int others; ++} sd_stat; ++ ++/* plugin->item.common.* */ ++extern void print_sd(const char *prefix, coord_t * coord); ++extern void item_stat_static_sd(const coord_t * coord, void *vp); ++ ++/* plugin->item.s.sd.* */ ++extern int init_inode_static_sd(struct inode *inode, char *sd, int len); ++extern int save_len_static_sd(struct inode *inode); ++extern int save_static_sd(struct inode *inode, char **area); ++ ++/* __FS_REISER4_PLUGIN_ITEM_STATIC_STAT_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/tail.c linux-2.6.30/fs/reiser4/plugin/item/tail.c +--- linux-2.6.30.orig/fs/reiser4/plugin/item/tail.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/tail.c 2009-06-22 17:36:20.000000000 +0200 +@@ -0,0 +1,807 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "item.h" ++#include "../../inode.h" ++#include "../../page_cache.h" ++#include "../../carry.h" ++#include "../../vfs_ops.h" ++ ++#include <linux/quotaops.h> ++#include <asm/uaccess.h> ++#include <linux/swap.h> ++#include <linux/writeback.h> ++ ++/* plugin->u.item.b.max_key_inside */ ++reiser4_key *max_key_inside_tail(const coord_t *coord, reiser4_key *key) ++{ ++ item_key_by_coord(coord, key); ++ set_key_offset(key, get_key_offset(reiser4_max_key())); ++ return key; ++} ++ ++/* plugin->u.item.b.can_contain_key */ ++int can_contain_key_tail(const coord_t *coord, const reiser4_key *key, ++ const reiser4_item_data *data) ++{ ++ reiser4_key item_key; ++ ++ if (item_plugin_by_coord(coord) != data->iplug) ++ return 0; ++ ++ item_key_by_coord(coord, &item_key); ++ if (get_key_locality(key) != get_key_locality(&item_key) || ++ get_key_objectid(key) != get_key_objectid(&item_key)) ++ return 0; ++ ++ return 1; ++} ++ ++/* plugin->u.item.b.mergeable ++ first item is of tail type */ ++/* Audited by: green(2002.06.14) */ ++int mergeable_tail(const coord_t *p1, const coord_t *p2) ++{ ++ reiser4_key key1, key2; ++ ++ assert("vs-535", plugin_of_group(item_plugin_by_coord(p1), ++ UNIX_FILE_METADATA_ITEM_TYPE)); ++ assert("vs-365", item_id_by_coord(p1) == FORMATTING_ID); ++ ++ if (item_id_by_coord(p2) != FORMATTING_ID) { ++ /* second item is of another type */ ++ return 0; ++ } ++ ++ item_key_by_coord(p1, &key1); ++ item_key_by_coord(p2, &key2); ++ if (get_key_locality(&key1) != get_key_locality(&key2) || ++ get_key_objectid(&key1) != get_key_objectid(&key2) ++ || get_key_type(&key1) != get_key_type(&key2)) { ++ /* items of different objects */ ++ return 0; ++ } ++ if (get_key_offset(&key1) + nr_units_tail(p1) != get_key_offset(&key2)) { ++ /* not adjacent items */ ++ return 0; ++ } ++ return 1; ++} ++ ++/* plugin->u.item.b.print ++ plugin->u.item.b.check */ ++ ++/* plugin->u.item.b.nr_units */ ++pos_in_node_t nr_units_tail(const coord_t * coord) ++{ ++ return item_length_by_coord(coord); ++} ++ ++/* plugin->u.item.b.lookup */ ++lookup_result ++lookup_tail(const reiser4_key * key, lookup_bias bias, coord_t * coord) ++{ ++ reiser4_key item_key; ++ __u64 lookuped, offset; ++ unsigned nr_units; ++ ++ item_key_by_coord(coord, &item_key); ++ offset = get_key_offset(item_key_by_coord(coord, &item_key)); ++ nr_units = nr_units_tail(coord); ++ ++ /* key we are looking for must be greater than key of item @coord */ ++ assert("vs-416", keygt(key, &item_key)); ++ ++ /* offset we are looking for */ ++ lookuped = get_key_offset(key); ++ ++ if (lookuped >= offset && lookuped < offset + nr_units) { ++ /* byte we are looking for is in this item */ ++ coord->unit_pos = lookuped - offset; ++ coord->between = AT_UNIT; ++ return CBK_COORD_FOUND; ++ } ++ ++ /* set coord after last unit */ ++ coord->unit_pos = nr_units - 1; ++ coord->between = AFTER_UNIT; ++ return bias == ++ FIND_MAX_NOT_MORE_THAN ? CBK_COORD_FOUND : CBK_COORD_NOTFOUND; ++} ++ ++/* plugin->u.item.b.paste */ ++int ++paste_tail(coord_t *coord, reiser4_item_data *data, ++ carry_plugin_info *info UNUSED_ARG) ++{ ++ unsigned old_item_length; ++ char *item; ++ ++ /* length the item had before resizing has been performed */ ++ old_item_length = item_length_by_coord(coord) - data->length; ++ ++ /* tail items never get pasted in the middle */ ++ assert("vs-363", ++ (coord->unit_pos == 0 && coord->between == BEFORE_UNIT) || ++ (coord->unit_pos == old_item_length - 1 && ++ coord->between == AFTER_UNIT) || ++ (coord->unit_pos == 0 && old_item_length == 0 ++ && coord->between == AT_UNIT)); ++ ++ item = item_body_by_coord(coord); ++ if (coord->unit_pos == 0) ++ /* make space for pasted data when pasting at the beginning of ++ the item */ ++ memmove(item + data->length, item, old_item_length); ++ ++ if (coord->between == AFTER_UNIT) ++ coord->unit_pos++; ++ ++ if (data->data) { ++ assert("vs-554", data->user == 0 || data->user == 1); ++ if (data->user) { ++ assert("nikita-3035", reiser4_schedulable()); ++ /* copy from user space */ ++ if (__copy_from_user(item + coord->unit_pos, ++ (const char __user *)data->data, ++ (unsigned)data->length)) ++ return RETERR(-EFAULT); ++ } else ++ /* copy from kernel space */ ++ memcpy(item + coord->unit_pos, data->data, ++ (unsigned)data->length); ++ } else { ++ memset(item + coord->unit_pos, 0, (unsigned)data->length); ++ } ++ return 0; ++} ++ ++/* plugin->u.item.b.fast_paste */ ++ ++/* plugin->u.item.b.can_shift ++ number of units is returned via return value, number of bytes via @size. For ++ tail items they coincide */ ++int ++can_shift_tail(unsigned free_space, coord_t * source UNUSED_ARG, ++ znode * target UNUSED_ARG, shift_direction direction UNUSED_ARG, ++ unsigned *size, unsigned want) ++{ ++ /* make sure that that we do not want to shift more than we have */ ++ assert("vs-364", want > 0 ++ && want <= (unsigned)item_length_by_coord(source)); ++ ++ *size = min(want, free_space); ++ return *size; ++} ++ ++/* plugin->u.item.b.copy_units */ ++void ++copy_units_tail(coord_t * target, coord_t * source, ++ unsigned from, unsigned count, ++ shift_direction where_is_free_space, ++ unsigned free_space UNUSED_ARG) ++{ ++ /* make sure that item @target is expanded already */ ++ assert("vs-366", (unsigned)item_length_by_coord(target) >= count); ++ assert("vs-370", free_space >= count); ++ ++ if (where_is_free_space == SHIFT_LEFT) { ++ /* append item @target with @count first bytes of @source */ ++ assert("vs-365", from == 0); ++ ++ memcpy((char *)item_body_by_coord(target) + ++ item_length_by_coord(target) - count, ++ (char *)item_body_by_coord(source), count); ++ } else { ++ /* target item is moved to right already */ ++ reiser4_key key; ++ ++ assert("vs-367", ++ (unsigned)item_length_by_coord(source) == from + count); ++ ++ memcpy((char *)item_body_by_coord(target), ++ (char *)item_body_by_coord(source) + from, count); ++ ++ /* new units are inserted before first unit in an item, ++ therefore, we have to update item key */ ++ item_key_by_coord(source, &key); ++ set_key_offset(&key, get_key_offset(&key) + from); ++ ++ node_plugin_by_node(target->node)->update_item_key(target, &key, ++ NULL /*info */); ++ } ++} ++ ++/* plugin->u.item.b.create_hook */ ++ ++/* item_plugin->b.kill_hook ++ this is called when @count units starting from @from-th one are going to be removed ++ */ ++int ++kill_hook_tail(const coord_t * coord, pos_in_node_t from, ++ pos_in_node_t count, struct carry_kill_data *kdata) ++{ ++ reiser4_key key; ++ loff_t start, end; ++ ++ assert("vs-1577", kdata); ++ assert("vs-1579", kdata->inode); ++ ++ item_key_by_coord(coord, &key); ++ start = get_key_offset(&key) + from; ++ end = start + count; ++ fake_kill_hook_tail(kdata->inode, start, end, kdata->params.truncate); ++ return 0; ++} ++ ++/* plugin->u.item.b.shift_hook */ ++ ++/* helper for kill_units_tail and cut_units_tail */ ++static int ++do_cut_or_kill(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ reiser4_key * smallest_removed, reiser4_key * new_first) ++{ ++ pos_in_node_t count; ++ ++ /* this method is only called to remove part of item */ ++ assert("vs-374", (to - from + 1) < item_length_by_coord(coord)); ++ /* tails items are never cut from the middle of an item */ ++ assert("vs-396", ergo(from != 0, to == coord_last_unit_pos(coord))); ++ assert("vs-1558", ergo(from == 0, to < coord_last_unit_pos(coord))); ++ ++ count = to - from + 1; ++ ++ if (smallest_removed) { ++ /* store smallest key removed */ ++ item_key_by_coord(coord, smallest_removed); ++ set_key_offset(smallest_removed, ++ get_key_offset(smallest_removed) + from); ++ } ++ if (new_first) { ++ /* head of item is cut */ ++ assert("vs-1529", from == 0); ++ ++ item_key_by_coord(coord, new_first); ++ set_key_offset(new_first, ++ get_key_offset(new_first) + from + count); ++ } ++ ++ if (REISER4_DEBUG) ++ memset((char *)item_body_by_coord(coord) + from, 0, count); ++ return count; ++} ++ ++/* plugin->u.item.b.cut_units */ ++int ++cut_units_tail(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ struct carry_cut_data *cdata UNUSED_ARG, ++ reiser4_key * smallest_removed, reiser4_key * new_first) ++{ ++ return do_cut_or_kill(coord, from, to, smallest_removed, new_first); ++} ++ ++/* plugin->u.item.b.kill_units */ ++int ++kill_units_tail(coord_t * coord, pos_in_node_t from, pos_in_node_t to, ++ struct carry_kill_data *kdata, reiser4_key * smallest_removed, ++ reiser4_key * new_first) ++{ ++ kill_hook_tail(coord, from, to - from + 1, kdata); ++ return do_cut_or_kill(coord, from, to, smallest_removed, new_first); ++} ++ ++/* plugin->u.item.b.unit_key */ ++reiser4_key *unit_key_tail(const coord_t * coord, reiser4_key * key) ++{ ++ assert("vs-375", coord_is_existing_unit(coord)); ++ ++ item_key_by_coord(coord, key); ++ set_key_offset(key, (get_key_offset(key) + coord->unit_pos)); ++ ++ return key; ++} ++ ++/* plugin->u.item.b.estimate ++ plugin->u.item.b.item_data_by_flow */ ++ ++/* tail redpage function. It is called from readpage_tail(). */ ++static int do_readpage_tail(uf_coord_t *uf_coord, struct page *page) ++{ ++ tap_t tap; ++ int result; ++ coord_t coord; ++ lock_handle lh; ++ int count, mapped; ++ struct inode *inode; ++ char *pagedata; ++ ++ /* saving passed coord in order to do not move it by tap. */ ++ init_lh(&lh); ++ copy_lh(&lh, uf_coord->lh); ++ inode = page->mapping->host; ++ coord_dup(&coord, &uf_coord->coord); ++ ++ reiser4_tap_init(&tap, &coord, &lh, ZNODE_READ_LOCK); ++ ++ if ((result = reiser4_tap_load(&tap))) ++ goto out_tap_done; ++ ++ /* lookup until page is filled up. */ ++ for (mapped = 0; mapped < PAGE_CACHE_SIZE; ) { ++ /* number of bytes to be copied to page */ ++ count = item_length_by_coord(&coord) - coord.unit_pos; ++ if (count > PAGE_CACHE_SIZE - mapped) ++ count = PAGE_CACHE_SIZE - mapped; ++ ++ /* attach @page to address space and get data address */ ++ pagedata = kmap_atomic(page, KM_USER0); ++ ++ /* copy tail item to page */ ++ memcpy(pagedata + mapped, ++ ((char *)item_body_by_coord(&coord) + coord.unit_pos), ++ count); ++ mapped += count; ++ ++ flush_dcache_page(page); ++ ++ /* dettach page from address space */ ++ kunmap_atomic(pagedata, KM_USER0); ++ ++ /* Getting next tail item. */ ++ if (mapped < PAGE_CACHE_SIZE) { ++ /* ++ * unlock page in order to avoid keep it locked ++ * during tree lookup, which takes long term locks ++ */ ++ unlock_page(page); ++ ++ /* getting right neighbour. */ ++ result = go_dir_el(&tap, RIGHT_SIDE, 0); ++ ++ /* lock page back */ ++ lock_page(page); ++ if (PageUptodate(page)) { ++ /* ++ * another thread read the page, we have ++ * nothing to do ++ */ ++ result = 0; ++ goto out_unlock_page; ++ } ++ ++ if (result) { ++ if (result == -E_NO_NEIGHBOR) { ++ /* ++ * rigth neighbor is not a formatted ++ * node ++ */ ++ result = 0; ++ goto done; ++ } else { ++ goto out_tap_relse; ++ } ++ } else { ++ if (!inode_file_plugin(inode)-> ++ owns_item(inode, &coord)) { ++ /* item of another file is found */ ++ result = 0; ++ goto done; ++ } ++ } ++ } ++ } ++ ++ done: ++ if (mapped != PAGE_CACHE_SIZE) ++ zero_user_segment(page, mapped, PAGE_CACHE_SIZE); ++ SetPageUptodate(page); ++ out_unlock_page: ++ unlock_page(page); ++ out_tap_relse: ++ reiser4_tap_relse(&tap); ++ out_tap_done: ++ reiser4_tap_done(&tap); ++ return result; ++} ++ ++/* ++ plugin->s.file.readpage ++ reiser4_read->unix_file_read->page_cache_readahead->reiser4_readpage->unix_file_readpage->readpage_tail ++ or ++ filemap_fault->reiser4_readpage->readpage_unix_file->->readpage_tail ++ ++ At the beginning: coord->node is read locked, zloaded, page is locked, coord is set to existing unit inside of tail ++ item. */ ++int readpage_tail(void *vp, struct page *page) ++{ ++ uf_coord_t *uf_coord = vp; ++ ON_DEBUG(coord_t * coord = &uf_coord->coord); ++ ON_DEBUG(reiser4_key key); ++ ++ assert("umka-2515", PageLocked(page)); ++ assert("umka-2516", !PageUptodate(page)); ++ assert("umka-2517", !jprivate(page) && !PagePrivate(page)); ++ assert("umka-2518", page->mapping && page->mapping->host); ++ ++ assert("umka-2519", znode_is_loaded(coord->node)); ++ assert("umka-2520", item_is_tail(coord)); ++ assert("umka-2521", coord_is_existing_unit(coord)); ++ assert("umka-2522", znode_is_rlocked(coord->node)); ++ assert("umka-2523", ++ page->mapping->host->i_ino == ++ get_key_objectid(item_key_by_coord(coord, &key))); ++ ++ return do_readpage_tail(uf_coord, page); ++} ++ ++/** ++ * overwrite_tail ++ * @flow: ++ * @coord: ++ * ++ * Overwrites tail item or its part by user data. Returns number of bytes ++ * written or error code. ++ */ ++static int overwrite_tail(flow_t *flow, coord_t *coord) ++{ ++ unsigned count; ++ ++ assert("vs-570", flow->user == 1); ++ assert("vs-946", flow->data); ++ assert("vs-947", coord_is_existing_unit(coord)); ++ assert("vs-948", znode_is_write_locked(coord->node)); ++ assert("nikita-3036", reiser4_schedulable()); ++ ++ count = item_length_by_coord(coord) - coord->unit_pos; ++ if (count > flow->length) ++ count = flow->length; ++ ++ if (__copy_from_user((char *)item_body_by_coord(coord) + coord->unit_pos, ++ (const char __user *)flow->data, count)) ++ return RETERR(-EFAULT); ++ ++ znode_make_dirty(coord->node); ++ return count; ++} ++ ++/** ++ * insert_first_tail ++ * @inode: ++ * @flow: ++ * @coord: ++ * @lh: ++ * ++ * Returns number of bytes written or error code. ++ */ ++static ssize_t insert_first_tail(struct inode *inode, flow_t *flow, ++ coord_t *coord, lock_handle *lh) ++{ ++ int result; ++ loff_t to_write; ++ struct unix_file_info *uf_info; ++ ++ if (get_key_offset(&flow->key) != 0) { ++ /* ++ * file is empty and we have to write not to the beginning of ++ * file. Create a hole at the beginning of file. On success ++ * insert_flow returns 0 as number of written bytes which is ++ * what we have to return on padding a file with holes ++ */ ++ flow->data = NULL; ++ flow->length = get_key_offset(&flow->key); ++ set_key_offset(&flow->key, 0); ++ /* ++ * holes in files built of tails are stored just like if there ++ * were real data which are all zeros. Therefore we have to ++ * allocate quota here as well ++ */ ++ if (vfs_dq_alloc_space_nodirty(inode, flow->length)) ++ return RETERR(-EDQUOT); ++ result = reiser4_insert_flow(coord, lh, flow); ++ if (flow->length) ++ vfs_dq_free_space_nodirty(inode, flow->length); ++ ++ uf_info = unix_file_inode_data(inode); ++ ++ /* ++ * first item insertion is only possible when writing to empty ++ * file or performing tail conversion ++ */ ++ assert("", (uf_info->container == UF_CONTAINER_EMPTY || ++ (reiser4_inode_get_flag(inode, ++ REISER4_PART_MIXED) && ++ reiser4_inode_get_flag(inode, ++ REISER4_PART_IN_CONV)))); ++ /* if file was empty - update its state */ ++ if (result == 0 && uf_info->container == UF_CONTAINER_EMPTY) ++ uf_info->container = UF_CONTAINER_TAILS; ++ return result; ++ } ++ ++ /* check quota before appending data */ ++ if (vfs_dq_alloc_space_nodirty(inode, flow->length)) ++ return RETERR(-EDQUOT); ++ ++ to_write = flow->length; ++ result = reiser4_insert_flow(coord, lh, flow); ++ if (flow->length) ++ vfs_dq_free_space_nodirty(inode, flow->length); ++ return (to_write - flow->length) ? (to_write - flow->length) : result; ++} ++ ++/** ++ * append_tail ++ * @inode: ++ * @flow: ++ * @coord: ++ * @lh: ++ * ++ * Returns number of bytes written or error code. ++ */ ++static ssize_t append_tail(struct inode *inode, ++ flow_t *flow, coord_t *coord, lock_handle *lh) ++{ ++ int result; ++ reiser4_key append_key; ++ loff_t to_write; ++ ++ if (!keyeq(&flow->key, append_key_tail(coord, &append_key))) { ++ flow->data = NULL; ++ flow->length = get_key_offset(&flow->key) - get_key_offset(&append_key); ++ set_key_offset(&flow->key, get_key_offset(&append_key)); ++ /* ++ * holes in files built of tails are stored just like if there ++ * were real data which are all zeros. Therefore we have to ++ * allocate quota here as well ++ */ ++ if (vfs_dq_alloc_space_nodirty(inode, flow->length)) ++ return RETERR(-EDQUOT); ++ result = reiser4_insert_flow(coord, lh, flow); ++ if (flow->length) ++ vfs_dq_free_space_nodirty(inode, flow->length); ++ return result; ++ } ++ ++ /* check quota before appending data */ ++ if (vfs_dq_alloc_space_nodirty(inode, flow->length)) ++ return RETERR(-EDQUOT); ++ ++ to_write = flow->length; ++ result = reiser4_insert_flow(coord, lh, flow); ++ if (flow->length) ++ vfs_dq_free_space_nodirty(inode, flow->length); ++ return (to_write - flow->length) ? (to_write - flow->length) : result; ++} ++ ++/** ++ * write_tail_reserve_space - reserve space for tail write operation ++ * @inode: ++ * ++ * Estimates and reserves space which may be required for writing one flow to a ++ * file ++ */ ++static int write_extent_reserve_space(struct inode *inode) ++{ ++ __u64 count; ++ reiser4_tree *tree; ++ ++ /* ++ * to write one flow to a file by tails we have to reserve disk space for: ++ ++ * 1. find_file_item may have to insert empty node to the tree (empty ++ * leaf node between two extent items). This requires 1 block and ++ * number of blocks which are necessary to perform insertion of an ++ * internal item into twig level. ++ * ++ * 2. flow insertion ++ * ++ * 3. stat data update ++ */ ++ tree = reiser4_tree_by_inode(inode); ++ count = estimate_one_insert_item(tree) + ++ estimate_insert_flow(tree->height) + ++ estimate_one_insert_item(tree); ++ grab_space_enable(); ++ return reiser4_grab_space(count, 0 /* flags */); ++} ++ ++#define PAGE_PER_FLOW 4 ++ ++static loff_t faultin_user_pages(const char __user *buf, size_t count) ++{ ++ loff_t faulted; ++ int to_fault; ++ ++ if (count > PAGE_PER_FLOW * PAGE_CACHE_SIZE) ++ count = PAGE_PER_FLOW * PAGE_CACHE_SIZE; ++ faulted = 0; ++ while (count > 0) { ++ to_fault = PAGE_CACHE_SIZE; ++ if (count < to_fault) ++ to_fault = count; ++ fault_in_pages_readable(buf + faulted, to_fault); ++ count -= to_fault; ++ faulted += to_fault; ++ } ++ return faulted; ++} ++ ++/** ++ * reiser4_write_tail - write method of tail item plugin ++ * @file: file to write to ++ * @buf: address of user-space buffer ++ * @count: number of bytes to write ++ * @pos: position in file to write to ++ * ++ * Returns number of written bytes or error code. ++ */ ++ssize_t reiser4_write_tail(struct file *file, struct inode * inode, ++ const char __user *buf, size_t count, loff_t *pos) ++{ ++ struct hint hint; ++ int result; ++ flow_t flow; ++ coord_t *coord; ++ lock_handle *lh; ++ znode *loaded; ++ ++ assert("edward-1548", inode != NULL); ++ ++ if (write_extent_reserve_space(inode)) ++ return RETERR(-ENOSPC); ++ ++ result = load_file_hint(file, &hint); ++ BUG_ON(result != 0); ++ ++ flow.length = faultin_user_pages(buf, count); ++ flow.user = 1; ++ memcpy(&flow.data, &buf, sizeof(buf)); ++ flow.op = WRITE_OP; ++ key_by_inode_and_offset_common(inode, *pos, &flow.key); ++ ++ result = find_file_item(&hint, &flow.key, ZNODE_WRITE_LOCK, inode); ++ if (IS_CBKERR(result)) ++ return result; ++ ++ coord = &hint.ext_coord.coord; ++ lh = hint.ext_coord.lh; ++ ++ result = zload(coord->node); ++ BUG_ON(result != 0); ++ loaded = coord->node; ++ ++ if (coord->between == AFTER_UNIT) { ++ /* append with data or hole */ ++ result = append_tail(inode, &flow, coord, lh); ++ } else if (coord->between == AT_UNIT) { ++ /* overwrite */ ++ result = overwrite_tail(&flow, coord); ++ } else { ++ /* no items of this file yet. insert data or hole */ ++ result = insert_first_tail(inode, &flow, coord, lh); ++ } ++ zrelse(loaded); ++ if (result < 0) { ++ done_lh(lh); ++ return result; ++ } ++ ++ /* seal and unlock znode */ ++ hint.ext_coord.valid = 0; ++ if (hint.ext_coord.valid) ++ reiser4_set_hint(&hint, &flow.key, ZNODE_WRITE_LOCK); ++ else ++ reiser4_unset_hint(&hint); ++ ++ save_file_hint(file, &hint); ++ return result; ++} ++ ++#if REISER4_DEBUG ++ ++static int ++coord_matches_key_tail(const coord_t * coord, const reiser4_key * key) ++{ ++ reiser4_key item_key; ++ ++ assert("vs-1356", coord_is_existing_unit(coord)); ++ assert("vs-1354", keylt(key, append_key_tail(coord, &item_key))); ++ assert("vs-1355", keyge(key, item_key_by_coord(coord, &item_key))); ++ return get_key_offset(key) == ++ get_key_offset(&item_key) + coord->unit_pos; ++ ++} ++ ++#endif ++ ++/* plugin->u.item.s.file.read */ ++int reiser4_read_tail(struct file *file UNUSED_ARG, flow_t *f, hint_t *hint) ++{ ++ unsigned count; ++ int item_length; ++ coord_t *coord; ++ uf_coord_t *uf_coord; ++ ++ uf_coord = &hint->ext_coord; ++ coord = &uf_coord->coord; ++ ++ assert("vs-571", f->user == 1); ++ assert("vs-571", f->data); ++ assert("vs-967", coord && coord->node); ++ assert("vs-1117", znode_is_rlocked(coord->node)); ++ assert("vs-1118", znode_is_loaded(coord->node)); ++ ++ assert("nikita-3037", reiser4_schedulable()); ++ assert("vs-1357", coord_matches_key_tail(coord, &f->key)); ++ ++ /* calculate number of bytes to read off the item */ ++ item_length = item_length_by_coord(coord); ++ count = item_length_by_coord(coord) - coord->unit_pos; ++ if (count > f->length) ++ count = f->length; ++ ++ /* user page has to be brought in so that major page fault does not ++ * occur here when longtem lock is held */ ++ if (__copy_to_user((char __user *)f->data, ++ ((char *)item_body_by_coord(coord) + coord->unit_pos), ++ count)) ++ return RETERR(-EFAULT); ++ ++ /* probably mark_page_accessed() should only be called if ++ * coord->unit_pos is zero. */ ++ mark_page_accessed(znode_page(coord->node)); ++ move_flow_forward(f, count); ++ ++ coord->unit_pos += count; ++ if (item_length == coord->unit_pos) { ++ coord->unit_pos--; ++ coord->between = AFTER_UNIT; ++ } ++ reiser4_set_hint(hint, &f->key, ZNODE_READ_LOCK); ++ return 0; ++} ++ ++/* ++ plugin->u.item.s.file.append_key ++ key of first byte which is the next to last byte by addressed by this item ++*/ ++reiser4_key *append_key_tail(const coord_t * coord, reiser4_key * key) ++{ ++ item_key_by_coord(coord, key); ++ set_key_offset(key, get_key_offset(key) + item_length_by_coord(coord)); ++ return key; ++} ++ ++/* plugin->u.item.s.file.init_coord_extension */ ++void init_coord_extension_tail(uf_coord_t * uf_coord, loff_t lookuped) ++{ ++ uf_coord->valid = 1; ++} ++ ++/* ++ plugin->u.item.s.file.get_block ++*/ ++int ++get_block_address_tail(const coord_t * coord, sector_t lblock, sector_t * block) ++{ ++ assert("nikita-3252", znode_get_level(coord->node) == LEAF_LEVEL); ++ ++ if (reiser4_blocknr_is_fake(znode_get_block(coord->node))) ++ /* if node has'nt obtainet its block number yet, return 0. ++ * Lets avoid upsetting users with some cosmic numbers beyond ++ * the device capacity.*/ ++ *block = 0; ++ else ++ *block = *znode_get_block(coord->node); ++ return 0; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/item/tail.h linux-2.6.30/fs/reiser4/plugin/item/tail.h +--- linux-2.6.30.orig/fs/reiser4/plugin/item/tail.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/item/tail.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,58 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#if !defined( __REISER4_TAIL_H__ ) ++#define __REISER4_TAIL_H__ ++ ++struct tail_coord_extension { ++ int not_used; ++}; ++ ++struct cut_list; ++ ++/* plugin->u.item.b.* */ ++reiser4_key *max_key_inside_tail(const coord_t *, reiser4_key *); ++int can_contain_key_tail(const coord_t * coord, const reiser4_key * key, ++ const reiser4_item_data *); ++int mergeable_tail(const coord_t * p1, const coord_t * p2); ++pos_in_node_t nr_units_tail(const coord_t *); ++lookup_result lookup_tail(const reiser4_key *, lookup_bias, coord_t *); ++int paste_tail(coord_t *, reiser4_item_data *, carry_plugin_info *); ++int can_shift_tail(unsigned free_space, coord_t * source, ++ znode * target, shift_direction, unsigned *size, ++ unsigned want); ++void copy_units_tail(coord_t * target, coord_t * source, unsigned from, ++ unsigned count, shift_direction, unsigned free_space); ++int kill_hook_tail(const coord_t *, pos_in_node_t from, pos_in_node_t count, ++ struct carry_kill_data *); ++int cut_units_tail(coord_t *, pos_in_node_t from, pos_in_node_t to, ++ struct carry_cut_data *, reiser4_key * smallest_removed, ++ reiser4_key * new_first); ++int kill_units_tail(coord_t *, pos_in_node_t from, pos_in_node_t to, ++ struct carry_kill_data *, reiser4_key * smallest_removed, ++ reiser4_key * new_first); ++reiser4_key *unit_key_tail(const coord_t *, reiser4_key *); ++ ++/* plugin->u.item.s.* */ ++ssize_t reiser4_write_tail(struct file *file, struct inode * inode, ++ const char __user *buf, size_t count, loff_t *pos); ++int reiser4_read_tail(struct file *, flow_t *, hint_t *); ++int readpage_tail(void *vp, struct page *page); ++reiser4_key *append_key_tail(const coord_t *, reiser4_key *); ++void init_coord_extension_tail(uf_coord_t *, loff_t offset); ++int get_block_address_tail(const coord_t *, sector_t, sector_t *); ++int item_balance_dirty_pages(struct address_space *, const flow_t *, ++ hint_t *, int back_to_dirty, int set_hint); ++ ++/* __REISER4_TAIL_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/Makefile linux-2.6.30/fs/reiser4/plugin/Makefile +--- linux-2.6.30.orig/fs/reiser4/plugin/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,26 @@ ++obj-$(CONFIG_REISER4_FS) += plugins.o ++ ++plugins-objs := \ ++ plugin.o \ ++ plugin_set.o \ ++ object.o \ ++ inode_ops.o \ ++ inode_ops_rename.o \ ++ file_ops.o \ ++ file_ops_readdir.o \ ++ file_plugin_common.o \ ++ dir_plugin_common.o \ ++ digest.o \ ++ hash.o \ ++ fibration.o \ ++ tail_policy.o \ ++ regular.o ++ ++obj-$(CONFIG_REISER4_FS) += item/ ++obj-$(CONFIG_REISER4_FS) += file/ ++obj-$(CONFIG_REISER4_FS) += dir/ ++obj-$(CONFIG_REISER4_FS) += node/ ++obj-$(CONFIG_REISER4_FS) += compress/ ++obj-$(CONFIG_REISER4_FS) += space/ ++obj-$(CONFIG_REISER4_FS) += disk_format/ ++obj-$(CONFIG_REISER4_FS) += security/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/node/Makefile linux-2.6.30/fs/reiser4/plugin/node/Makefile +--- linux-2.6.30.orig/fs/reiser4/plugin/node/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/node/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,5 @@ ++obj-$(CONFIG_REISER4_FS) += node_plugins.o ++ ++node_plugins-objs := \ ++ node.o \ ++ node40.o +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/node/node40.c linux-2.6.30/fs/reiser4/plugin/node/node40.c +--- linux-2.6.30.orig/fs/reiser4/plugin/node/node40.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/node/node40.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,2924 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "../../debug.h" ++#include "../../key.h" ++#include "../../coord.h" ++#include "../plugin_header.h" ++#include "../item/item.h" ++#include "node.h" ++#include "node40.h" ++#include "../plugin.h" ++#include "../../jnode.h" ++#include "../../znode.h" ++#include "../../pool.h" ++#include "../../carry.h" ++#include "../../tap.h" ++#include "../../tree.h" ++#include "../../super.h" ++#include "../../reiser4.h" ++ ++#include <asm/uaccess.h> ++#include <linux/types.h> ++#include <linux/prefetch.h> ++ ++/* leaf 40 format: ++ ++ [node header | item 0, item 1, .., item N-1 | free space | item_head N-1, .. item_head 1, item head 0 ] ++ plugin_id (16) key ++ free_space (16) pluginid (16) ++ free_space_start (16) offset (16) ++ level (8) ++ num_items (16) ++ magic (32) ++ flush_time (32) ++*/ ++/* NIKITA-FIXME-HANS: I told you guys not less than 10 times to not call it r4fs. Change to "ReIs". */ ++/* magic number that is stored in ->magic field of node header */ ++static const __u32 REISER4_NODE_MAGIC = 0x52344653; /* (*(__u32 *)"R4FS"); */ ++ ++static int prepare_for_update(znode * left, znode * right, ++ carry_plugin_info * info); ++ ++/* header of node of reiser40 format is at the beginning of node */ ++static inline node40_header *node40_node_header(const znode * node /* node to ++ * query */ ) ++{ ++ assert("nikita-567", node != NULL); ++ assert("nikita-568", znode_page(node) != NULL); ++ assert("nikita-569", zdata(node) != NULL); ++ return (node40_header *) zdata(node); ++} ++ ++/* functions to get/set fields of node40_header */ ++#define nh40_get_magic(nh) le32_to_cpu(get_unaligned(&(nh)->magic)) ++#define nh40_get_free_space(nh) le16_to_cpu(get_unaligned(&(nh)->free_space)) ++#define nh40_get_free_space_start(nh) le16_to_cpu(get_unaligned(&(nh)->free_space_start)) ++#define nh40_get_level(nh) get_unaligned(&(nh)->level) ++#define nh40_get_num_items(nh) le16_to_cpu(get_unaligned(&(nh)->nr_items)) ++#define nh40_get_flush_id(nh) le64_to_cpu(get_unaligned(&(nh)->flush_id)) ++ ++#define nh40_set_magic(nh, value) put_unaligned(cpu_to_le32(value), &(nh)->magic) ++#define nh40_set_free_space(nh, value) put_unaligned(cpu_to_le16(value), &(nh)->free_space) ++#define nh40_set_free_space_start(nh, value) put_unaligned(cpu_to_le16(value), &(nh)->free_space_start) ++#define nh40_set_level(nh, value) put_unaligned(value, &(nh)->level) ++#define nh40_set_num_items(nh, value) put_unaligned(cpu_to_le16(value), &(nh)->nr_items) ++#define nh40_set_mkfs_id(nh, value) put_unaligned(cpu_to_le32(value), &(nh)->mkfs_id) ++ ++/* plugin field of node header should be read/set by ++ plugin_by_disk_id/save_disk_plugin */ ++ ++/* array of item headers is at the end of node */ ++static inline item_header40 *node40_ih_at(const znode * node, unsigned pos) ++{ ++ return (item_header40 *) (zdata(node) + znode_size(node)) - pos - 1; ++} ++ ++/* ( page_address( node -> pg ) + PAGE_CACHE_SIZE ) - pos - 1 ++ */ ++static inline item_header40 *node40_ih_at_coord(const coord_t * coord) ++{ ++ return (item_header40 *) (zdata(coord->node) + ++ znode_size(coord->node)) - (coord->item_pos) - ++ 1; ++} ++ ++/* functions to get/set fields of item_header40 */ ++#define ih40_get_offset(ih) le16_to_cpu(get_unaligned(&(ih)->offset)) ++ ++#define ih40_set_offset(ih, value) put_unaligned(cpu_to_le16(value), &(ih)->offset) ++ ++/* plugin field of item header should be read/set by ++ plugin_by_disk_id/save_disk_plugin */ ++ ++/* plugin methods */ ++ ++/* plugin->u.node.item_overhead ++ look for description of this method in plugin/node/node.h */ ++size_t ++item_overhead_node40(const znode * node UNUSED_ARG, flow_t * f UNUSED_ARG) ++{ ++ return sizeof(item_header40); ++} ++ ++/* plugin->u.node.free_space ++ look for description of this method in plugin/node/node.h */ ++size_t free_space_node40(znode * node) ++{ ++ assert("nikita-577", node != NULL); ++ assert("nikita-578", znode_is_loaded(node)); ++ assert("nikita-579", zdata(node) != NULL); ++ ++ return nh40_get_free_space(node40_node_header(node)); ++} ++ ++/* private inline version of node40_num_of_items() for use in this file. This ++ is necessary, because address of node40_num_of_items() is taken and it is ++ never inlined as a result. */ ++static inline short node40_num_of_items_internal(const znode * node) ++{ ++ return nh40_get_num_items(node40_node_header(node)); ++} ++ ++#if REISER4_DEBUG ++static inline void check_num_items(const znode * node) ++{ ++ assert("nikita-2749", ++ node40_num_of_items_internal(node) == node->nr_items); ++ assert("nikita-2746", znode_is_write_locked(node)); ++} ++#else ++#define check_num_items(node) noop ++#endif ++ ++/* plugin->u.node.num_of_items ++ look for description of this method in plugin/node/node.h */ ++int num_of_items_node40(const znode * node) ++{ ++ return node40_num_of_items_internal(node); ++} ++ ++static void ++node40_set_num_items(znode * node, node40_header * nh, unsigned value) ++{ ++ assert("nikita-2751", node != NULL); ++ assert("nikita-2750", nh == node40_node_header(node)); ++ ++ check_num_items(node); ++ nh40_set_num_items(nh, value); ++ node->nr_items = value; ++ check_num_items(node); ++} ++ ++/* plugin->u.node.item_by_coord ++ look for description of this method in plugin/node/node.h */ ++char *item_by_coord_node40(const coord_t * coord) ++{ ++ item_header40 *ih; ++ char *p; ++ ++ /* @coord is set to existing item */ ++ assert("nikita-596", coord != NULL); ++ assert("vs-255", coord_is_existing_item(coord)); ++ ++ ih = node40_ih_at_coord(coord); ++ p = zdata(coord->node) + ih40_get_offset(ih); ++ return p; ++} ++ ++/* plugin->u.node.length_by_coord ++ look for description of this method in plugin/node/node.h */ ++int length_by_coord_node40(const coord_t * coord) ++{ ++ item_header40 *ih; ++ int result; ++ ++ /* @coord is set to existing item */ ++ assert("vs-256", coord != NULL); ++ assert("vs-257", coord_is_existing_item(coord)); ++ ++ ih = node40_ih_at_coord(coord); ++ if ((int)coord->item_pos == ++ node40_num_of_items_internal(coord->node) - 1) ++ result = ++ nh40_get_free_space_start(node40_node_header(coord->node)) - ++ ih40_get_offset(ih); ++ else ++ result = ih40_get_offset(ih - 1) - ih40_get_offset(ih); ++ ++ return result; ++} ++ ++static pos_in_node_t ++node40_item_length(const znode * node, pos_in_node_t item_pos) ++{ ++ item_header40 *ih; ++ pos_in_node_t result; ++ ++ /* @coord is set to existing item */ ++ assert("vs-256", node != NULL); ++ assert("vs-257", node40_num_of_items_internal(node) > item_pos); ++ ++ ih = node40_ih_at(node, item_pos); ++ if (item_pos == node40_num_of_items_internal(node) - 1) ++ result = ++ nh40_get_free_space_start(node40_node_header(node)) - ++ ih40_get_offset(ih); ++ else ++ result = ih40_get_offset(ih - 1) - ih40_get_offset(ih); ++ ++ return result; ++} ++ ++/* plugin->u.node.plugin_by_coord ++ look for description of this method in plugin/node/node.h */ ++item_plugin *plugin_by_coord_node40(const coord_t * coord) ++{ ++ item_header40 *ih; ++ item_plugin *result; ++ ++ /* @coord is set to existing item */ ++ assert("vs-258", coord != NULL); ++ assert("vs-259", coord_is_existing_item(coord)); ++ ++ ih = node40_ih_at_coord(coord); ++ /* pass NULL in stead of current tree. This is time critical call. */ ++ result = item_plugin_by_disk_id(NULL, &ih->plugin_id); ++ return result; ++} ++ ++/* plugin->u.node.key_at ++ look for description of this method in plugin/node/node.h */ ++reiser4_key *key_at_node40(const coord_t * coord, reiser4_key * key) ++{ ++ item_header40 *ih; ++ ++ assert("nikita-1765", coord_is_existing_item(coord)); ++ ++ /* @coord is set to existing item */ ++ ih = node40_ih_at_coord(coord); ++ memcpy(key, &ih->key, sizeof(reiser4_key)); ++ return key; ++} ++ ++/* VS-FIXME-HANS: please review whether the below are properly disabled when debugging is disabled */ ++ ++#define NODE_INCSTAT(n, counter) \ ++ reiser4_stat_inc_at_level(znode_get_level(n), node.lookup.counter) ++ ++#define NODE_ADDSTAT(n, counter, val) \ ++ reiser4_stat_add_at_level(znode_get_level(n), node.lookup.counter, val) ++ ++/* plugin->u.node.lookup ++ look for description of this method in plugin/node/node.h */ ++node_search_result lookup_node40(znode * node /* node to query */ , ++ const reiser4_key * key /* key to look for */ , ++ lookup_bias bias /* search bias */ , ++ coord_t * coord /* resulting coord */ ) ++{ ++ int left; ++ int right; ++ int found; ++ int items; ++ ++ item_header40 *lefth; ++ item_header40 *righth; ++ ++ item_plugin *iplug; ++ item_header40 *bstop; ++ item_header40 *ih; ++ cmp_t order; ++ ++ assert("nikita-583", node != NULL); ++ assert("nikita-584", key != NULL); ++ assert("nikita-585", coord != NULL); ++ assert("nikita-2693", znode_is_any_locked(node)); ++ cassert(REISER4_SEQ_SEARCH_BREAK > 2); ++ ++ items = node_num_items(node); ++ ++ if (unlikely(items == 0)) { ++ coord_init_first_unit(coord, node); ++ return NS_NOT_FOUND; ++ } ++ ++ /* binary search for item that can contain given key */ ++ left = 0; ++ right = items - 1; ++ coord->node = node; ++ coord_clear_iplug(coord); ++ found = 0; ++ ++ lefth = node40_ih_at(node, left); ++ righth = node40_ih_at(node, right); ++ ++ /* It is known that for small arrays sequential search is on average ++ more efficient than binary. This is because sequential search is ++ coded as tight loop that can be better optimized by compilers and ++ for small array size gain from this optimization makes sequential ++ search the winner. Another, maybe more important, reason for this, ++ is that sequential array is more CPU cache friendly, whereas binary ++ search effectively destroys CPU caching. ++ ++ Critical here is the notion of "smallness". Reasonable value of ++ REISER4_SEQ_SEARCH_BREAK can be found by playing with code in ++ fs/reiser4/ulevel/ulevel.c:test_search(). ++ ++ Don't try to further optimize sequential search by scanning from ++ right to left in attempt to use more efficient loop termination ++ condition (comparison with 0). This doesn't work. ++ ++ */ ++ ++ while (right - left >= REISER4_SEQ_SEARCH_BREAK) { ++ int median; ++ item_header40 *medianh; ++ ++ median = (left + right) / 2; ++ medianh = node40_ih_at(node, median); ++ ++ assert("nikita-1084", median >= 0); ++ assert("nikita-1085", median < items); ++ switch (keycmp(key, &medianh->key)) { ++ case LESS_THAN: ++ right = median; ++ righth = medianh; ++ break; ++ default: ++ wrong_return_value("nikita-586", "keycmp"); ++ case GREATER_THAN: ++ left = median; ++ lefth = medianh; ++ break; ++ case EQUAL_TO: ++ do { ++ --median; ++ /* headers are ordered from right to left */ ++ ++medianh; ++ } while (median >= 0 && keyeq(key, &medianh->key)); ++ right = left = median + 1; ++ ih = lefth = righth = medianh - 1; ++ found = 1; ++ break; ++ } ++ } ++ /* sequential scan. Item headers, and, therefore, keys are stored at ++ the rightmost part of a node from right to left. We are trying to ++ access memory from left to right, and hence, scan in _descending_ ++ order of item numbers. ++ */ ++ if (!found) { ++ for (left = right, ih = righth; left >= 0; ++ih, --left) { ++ cmp_t comparison; ++ ++ prefetchkey(&(ih + 1)->key); ++ comparison = keycmp(&ih->key, key); ++ if (comparison == GREATER_THAN) ++ continue; ++ if (comparison == EQUAL_TO) { ++ found = 1; ++ do { ++ --left; ++ ++ih; ++ } while (left >= 0 && keyeq(&ih->key, key)); ++ ++left; ++ --ih; ++ } else { ++ assert("nikita-1256", comparison == LESS_THAN); ++ } ++ break; ++ } ++ if (unlikely(left < 0)) ++ left = 0; ++ } ++ ++ assert("nikita-3212", right >= left); ++ assert("nikita-3214", ++ equi(found, keyeq(&node40_ih_at(node, left)->key, key))); ++ ++ coord_set_item_pos(coord, left); ++ coord->unit_pos = 0; ++ coord->between = AT_UNIT; ++ ++ /* key < leftmost key in a mode or node is corrupted and keys ++ are not sorted */ ++ bstop = node40_ih_at(node, (unsigned)left); ++ order = keycmp(&bstop->key, key); ++ if (unlikely(order == GREATER_THAN)) { ++ if (unlikely(left != 0)) { ++ /* screw up */ ++ warning("nikita-587", "Key less than %i key in a node", ++ left); ++ reiser4_print_key("key", key); ++ reiser4_print_key("min", &bstop->key); ++ print_coord_content("coord", coord); ++ return RETERR(-EIO); ++ } else { ++ coord->between = BEFORE_UNIT; ++ return NS_NOT_FOUND; ++ } ++ } ++ /* left <= key, ok */ ++ iplug = item_plugin_by_disk_id(znode_get_tree(node), &bstop->plugin_id); ++ ++ if (unlikely(iplug == NULL)) { ++ warning("nikita-588", "Unknown plugin %i", ++ le16_to_cpu(get_unaligned(&bstop->plugin_id))); ++ reiser4_print_key("key", key); ++ print_coord_content("coord", coord); ++ return RETERR(-EIO); ++ } ++ ++ coord_set_iplug(coord, iplug); ++ ++ /* if exact key from item header was found by binary search, no ++ further checks are necessary. */ ++ if (found) { ++ assert("nikita-1259", order == EQUAL_TO); ++ return NS_FOUND; ++ } ++ if (iplug->b.max_key_inside != NULL) { ++ reiser4_key max_item_key; ++ ++ /* key > max_item_key --- outside of an item */ ++ if (keygt(key, iplug->b.max_key_inside(coord, &max_item_key))) { ++ coord->unit_pos = 0; ++ coord->between = AFTER_ITEM; ++ /* FIXME-VS: key we are looking for does not fit into ++ found item. Return NS_NOT_FOUND then. Without that ++ the following case does not work: there is extent of ++ file 10000, 10001. File 10000, 10002 has been just ++ created. When writing to position 0 in that file - ++ traverse_tree will stop here on twig level. When we ++ want it to go down to leaf level ++ */ ++ return NS_NOT_FOUND; ++ } ++ } ++ ++ if (iplug->b.lookup != NULL) { ++ return iplug->b.lookup(key, bias, coord); ++ } else { ++ assert("nikita-1260", order == LESS_THAN); ++ coord->between = AFTER_UNIT; ++ return (bias == FIND_EXACT) ? NS_NOT_FOUND : NS_FOUND; ++ } ++} ++ ++#undef NODE_ADDSTAT ++#undef NODE_INCSTAT ++ ++/* plugin->u.node.estimate ++ look for description of this method in plugin/node/node.h */ ++size_t estimate_node40(znode * node) ++{ ++ size_t result; ++ ++ assert("nikita-597", node != NULL); ++ ++ result = free_space_node40(node) - sizeof(item_header40); ++ ++ return (result > 0) ? result : 0; ++} ++ ++/* plugin->u.node.check ++ look for description of this method in plugin/node/node.h */ ++int check_node40(const znode * node /* node to check */ , ++ __u32 flags /* check flags */ , ++ const char **error /* where to store error message */ ) ++{ ++ int nr_items; ++ int i; ++ reiser4_key prev; ++ unsigned old_offset; ++ tree_level level; ++ coord_t coord; ++ int result; ++ ++ assert("nikita-580", node != NULL); ++ assert("nikita-581", error != NULL); ++ assert("nikita-2948", znode_is_loaded(node)); ++ ++ if (ZF_ISSET(node, JNODE_HEARD_BANSHEE)) ++ return 0; ++ ++ assert("nikita-582", zdata(node) != NULL); ++ ++ nr_items = node40_num_of_items_internal(node); ++ if (nr_items < 0) { ++ *error = "Negative number of items"; ++ return -1; ++ } ++ ++ if (flags & REISER4_NODE_DKEYS) ++ prev = *znode_get_ld_key((znode *) node); ++ else ++ prev = *reiser4_min_key(); ++ ++ old_offset = 0; ++ coord_init_zero(&coord); ++ coord.node = (znode *) node; ++ coord.unit_pos = 0; ++ coord.between = AT_UNIT; ++ level = znode_get_level(node); ++ for (i = 0; i < nr_items; i++) { ++ item_header40 *ih; ++ reiser4_key unit_key; ++ unsigned j; ++ ++ ih = node40_ih_at(node, (unsigned)i); ++ coord_set_item_pos(&coord, i); ++ if ((ih40_get_offset(ih) >= ++ znode_size(node) - nr_items * sizeof(item_header40)) || ++ (ih40_get_offset(ih) < sizeof(node40_header))) { ++ *error = "Offset is out of bounds"; ++ return -1; ++ } ++ if (ih40_get_offset(ih) <= old_offset) { ++ *error = "Offsets are in wrong order"; ++ return -1; ++ } ++ if ((i == 0) && (ih40_get_offset(ih) != sizeof(node40_header))) { ++ *error = "Wrong offset of first item"; ++ return -1; ++ } ++ old_offset = ih40_get_offset(ih); ++ ++ if (keygt(&prev, &ih->key)) { ++ *error = "Keys are in wrong order"; ++ return -1; ++ } ++ if (!keyeq(&ih->key, unit_key_by_coord(&coord, &unit_key))) { ++ *error = "Wrong key of first unit"; ++ return -1; ++ } ++ prev = ih->key; ++ for (j = 0; j < coord_num_units(&coord); ++j) { ++ coord.unit_pos = j; ++ unit_key_by_coord(&coord, &unit_key); ++ if (keygt(&prev, &unit_key)) { ++ *error = "Unit keys are in wrong order"; ++ return -1; ++ } ++ prev = unit_key; ++ } ++ coord.unit_pos = 0; ++ if (level != TWIG_LEVEL && item_is_extent(&coord)) { ++ *error = "extent on the wrong level"; ++ return -1; ++ } ++ if (level == LEAF_LEVEL && item_is_internal(&coord)) { ++ *error = "internal item on the wrong level"; ++ return -1; ++ } ++ if (level != LEAF_LEVEL && ++ !item_is_internal(&coord) && !item_is_extent(&coord)) { ++ *error = "wrong item on the internal level"; ++ return -1; ++ } ++ if (level > TWIG_LEVEL && !item_is_internal(&coord)) { ++ *error = "non-internal item on the internal level"; ++ return -1; ++ } ++#if REISER4_DEBUG ++ if (item_plugin_by_coord(&coord)->b.check ++ && item_plugin_by_coord(&coord)->b.check(&coord, error)) ++ return -1; ++#endif ++ if (i) { ++ coord_t prev_coord; ++ /* two neighboring items can not be mergeable */ ++ coord_dup(&prev_coord, &coord); ++ coord_prev_item(&prev_coord); ++ if (are_items_mergeable(&prev_coord, &coord)) { ++ *error = "mergeable items in one node"; ++ return -1; ++ } ++ ++ } ++ } ++ ++ if ((flags & REISER4_NODE_DKEYS) && !node_is_empty(node)) { ++ coord_t coord; ++ item_plugin *iplug; ++ ++ coord_init_last_unit(&coord, node); ++ iplug = item_plugin_by_coord(&coord); ++ if ((item_is_extent(&coord) || item_is_tail(&coord)) && ++ iplug->s.file.append_key != NULL) { ++ reiser4_key mkey; ++ ++ iplug->s.file.append_key(&coord, &mkey); ++ set_key_offset(&mkey, get_key_offset(&mkey) - 1); ++ read_lock_dk(current_tree); ++ result = keygt(&mkey, znode_get_rd_key((znode *) node)); ++ read_unlock_dk(current_tree); ++ if (result) { ++ *error = "key of rightmost item is too large"; ++ return -1; ++ } ++ } ++ } ++ if (flags & REISER4_NODE_DKEYS) { ++ read_lock_tree(current_tree); ++ read_lock_dk(current_tree); ++ ++ flags |= REISER4_NODE_TREE_STABLE; ++ ++ if (keygt(&prev, znode_get_rd_key((znode *) node))) { ++ if (flags & REISER4_NODE_TREE_STABLE) { ++ *error = "Last key is greater than rdkey"; ++ read_unlock_dk(current_tree); ++ read_unlock_tree(current_tree); ++ return -1; ++ } ++ } ++ if (keygt ++ (znode_get_ld_key((znode *) node), ++ znode_get_rd_key((znode *) node))) { ++ *error = "ldkey is greater than rdkey"; ++ read_unlock_dk(current_tree); ++ read_unlock_tree(current_tree); ++ return -1; ++ } ++ if (ZF_ISSET(node, JNODE_LEFT_CONNECTED) && ++ (node->left != NULL) && ++ !ZF_ISSET(node->left, JNODE_HEARD_BANSHEE) && ++ ergo(flags & REISER4_NODE_TREE_STABLE, ++ !keyeq(znode_get_rd_key(node->left), ++ znode_get_ld_key((znode *) node))) ++ && ergo(!(flags & REISER4_NODE_TREE_STABLE), ++ keygt(znode_get_rd_key(node->left), ++ znode_get_ld_key((znode *) node)))) { ++ *error = "left rdkey or ldkey is wrong"; ++ read_unlock_dk(current_tree); ++ read_unlock_tree(current_tree); ++ return -1; ++ } ++ if (ZF_ISSET(node, JNODE_RIGHT_CONNECTED) && ++ (node->right != NULL) && ++ !ZF_ISSET(node->right, JNODE_HEARD_BANSHEE) && ++ ergo(flags & REISER4_NODE_TREE_STABLE, ++ !keyeq(znode_get_rd_key((znode *) node), ++ znode_get_ld_key(node->right))) ++ && ergo(!(flags & REISER4_NODE_TREE_STABLE), ++ keygt(znode_get_rd_key((znode *) node), ++ znode_get_ld_key(node->right)))) { ++ *error = "rdkey or right ldkey is wrong"; ++ read_unlock_dk(current_tree); ++ read_unlock_tree(current_tree); ++ return -1; ++ } ++ ++ read_unlock_dk(current_tree); ++ read_unlock_tree(current_tree); ++ } ++ ++ return 0; ++} ++ ++/* plugin->u.node.parse ++ look for description of this method in plugin/node/node.h */ ++int parse_node40(znode * node /* node to parse */ ) ++{ ++ node40_header *header; ++ int result; ++ d8 level; ++ ++ header = node40_node_header((znode *) node); ++ result = -EIO; ++ level = nh40_get_level(header); ++ if (unlikely(((__u8) znode_get_level(node)) != level)) ++ warning("nikita-494", "Wrong level found in node: %i != %i", ++ znode_get_level(node), level); ++ else if (unlikely(nh40_get_magic(header) != REISER4_NODE_MAGIC)) ++ warning("nikita-495", ++ "Wrong magic in tree node: want %x, got %x", ++ REISER4_NODE_MAGIC, nh40_get_magic(header)); ++ else { ++ node->nr_items = node40_num_of_items_internal(node); ++ result = 0; ++ } ++ return RETERR(result); ++} ++ ++/* plugin->u.node.init ++ look for description of this method in plugin/node/node.h */ ++int init_node40(znode * node /* node to initialise */ ) ++{ ++ node40_header *header; ++ ++ assert("nikita-570", node != NULL); ++ assert("nikita-572", zdata(node) != NULL); ++ ++ header = node40_node_header(node); ++ memset(header, 0, sizeof(node40_header)); ++ nh40_set_free_space(header, znode_size(node) - sizeof(node40_header)); ++ nh40_set_free_space_start(header, sizeof(node40_header)); ++ /* sane hypothesis: 0 in CPU format is 0 in disk format */ ++ /* items: 0 */ ++ save_plugin_id(node_plugin_to_plugin(node->nplug), ++ &header->common_header.plugin_id); ++ nh40_set_level(header, znode_get_level(node)); ++ nh40_set_magic(header, REISER4_NODE_MAGIC); ++ node->nr_items = 0; ++ nh40_set_mkfs_id(header, reiser4_mkfs_id(reiser4_get_current_sb())); ++ ++ /* flags: 0 */ ++ return 0; ++} ++ ++#ifdef GUESS_EXISTS ++int guess_node40(const znode * node /* node to guess plugin of */ ) ++{ ++ node40_header *nethack; ++ ++ assert("nikita-1058", node != NULL); ++ nethack = node40_node_header(node); ++ return ++ (nh40_get_magic(nethack) == REISER4_NODE_MAGIC) && ++ (plugin_by_disk_id(znode_get_tree(node), ++ REISER4_NODE_PLUGIN_TYPE, ++ &nethack->common_header.plugin_id)->h.id == ++ NODE40_ID); ++} ++#endif ++ ++/* plugin->u.node.chage_item_size ++ look for description of this method in plugin/node/node.h */ ++void change_item_size_node40(coord_t * coord, int by) ++{ ++ node40_header *nh; ++ item_header40 *ih; ++ char *item_data; ++ int item_length; ++ unsigned i; ++ ++ /* make sure that @item is coord of existing item */ ++ assert("vs-210", coord_is_existing_item(coord)); ++ ++ nh = node40_node_header(coord->node); ++ ++ item_data = item_by_coord_node40(coord); ++ item_length = length_by_coord_node40(coord); ++ ++ /* move item bodies */ ++ ih = node40_ih_at_coord(coord); ++ memmove(item_data + item_length + by, item_data + item_length, ++ nh40_get_free_space_start(node40_node_header(coord->node)) - ++ (ih40_get_offset(ih) + item_length)); ++ ++ /* update offsets of moved items */ ++ for (i = coord->item_pos + 1; i < nh40_get_num_items(nh); i++) { ++ ih = node40_ih_at(coord->node, i); ++ ih40_set_offset(ih, ih40_get_offset(ih) + by); ++ } ++ ++ /* update node header */ ++ nh40_set_free_space(nh, nh40_get_free_space(nh) - by); ++ nh40_set_free_space_start(nh, nh40_get_free_space_start(nh) + by); ++} ++ ++static int should_notify_parent(const znode * node) ++{ ++ /* FIXME_JMACD This looks equivalent to znode_is_root(), right? -josh */ ++ return !disk_addr_eq(znode_get_block(node), ++ &znode_get_tree(node)->root_block); ++} ++ ++/* plugin->u.node.create_item ++ look for description of this method in plugin/node/node.h */ ++int ++create_item_node40(coord_t *target, const reiser4_key *key, ++ reiser4_item_data *data, carry_plugin_info *info) ++{ ++ node40_header *nh; ++ item_header40 *ih; ++ unsigned offset; ++ unsigned i; ++ ++ nh = node40_node_header(target->node); ++ ++ assert("vs-212", coord_is_between_items(target)); ++ /* node must have enough free space */ ++ assert("vs-254", ++ free_space_node40(target->node) >= ++ data->length + sizeof(item_header40)); ++ assert("vs-1410", data->length >= 0); ++ ++ if (coord_set_to_right(target)) ++ /* there are not items to the right of @target, so, new item ++ will be inserted after last one */ ++ coord_set_item_pos(target, nh40_get_num_items(nh)); ++ ++ if (target->item_pos < nh40_get_num_items(nh)) { ++ /* there are items to be moved to prepare space for new ++ item */ ++ ih = node40_ih_at_coord(target); ++ /* new item will start at this offset */ ++ offset = ih40_get_offset(ih); ++ ++ memmove(zdata(target->node) + offset + data->length, ++ zdata(target->node) + offset, ++ nh40_get_free_space_start(nh) - offset); ++ /* update headers of moved items */ ++ for (i = target->item_pos; i < nh40_get_num_items(nh); i++) { ++ ih = node40_ih_at(target->node, i); ++ ih40_set_offset(ih, ih40_get_offset(ih) + data->length); ++ } ++ ++ /* @ih is set to item header of the last item, move item headers */ ++ memmove(ih - 1, ih, ++ sizeof(item_header40) * (nh40_get_num_items(nh) - ++ target->item_pos)); ++ } else { ++ /* new item will start at this offset */ ++ offset = nh40_get_free_space_start(nh); ++ } ++ ++ /* make item header for the new item */ ++ ih = node40_ih_at_coord(target); ++ memcpy(&ih->key, key, sizeof(reiser4_key)); ++ ih40_set_offset(ih, offset); ++ save_plugin_id(item_plugin_to_plugin(data->iplug), &ih->plugin_id); ++ ++ /* update node header */ ++ nh40_set_free_space(nh, ++ nh40_get_free_space(nh) - data->length - ++ sizeof(item_header40)); ++ nh40_set_free_space_start(nh, ++ nh40_get_free_space_start(nh) + data->length); ++ node40_set_num_items(target->node, nh, nh40_get_num_items(nh) + 1); ++ ++ /* FIXME: check how does create_item work when between is set to BEFORE_UNIT */ ++ target->unit_pos = 0; ++ target->between = AT_UNIT; ++ coord_clear_iplug(target); ++ ++ /* initialize item */ ++ if (data->iplug->b.init != NULL) { ++ data->iplug->b.init(target, NULL, data); ++ } ++ /* copy item body */ ++ if (data->iplug->b.paste != NULL) { ++ data->iplug->b.paste(target, data, info); ++ } else if (data->data != NULL) { ++ if (data->user) { ++ /* AUDIT: Are we really should not check that pointer ++ from userspace was valid and data bytes were ++ available? How will we return -EFAULT of some kind ++ without this check? */ ++ assert("nikita-3038", reiser4_schedulable()); ++ /* copy data from user space */ ++ __copy_from_user(zdata(target->node) + offset, ++ (const char __user *)data->data, ++ (unsigned)data->length); ++ } else ++ /* copy from kernel space */ ++ memcpy(zdata(target->node) + offset, data->data, ++ (unsigned)data->length); ++ } ++ ++ if (target->item_pos == 0) { ++ /* left delimiting key has to be updated */ ++ prepare_for_update(NULL, target->node, info); ++ } ++ ++ if (item_plugin_by_coord(target)->b.create_hook != NULL) { ++ item_plugin_by_coord(target)->b.create_hook(target, data->arg); ++ } ++ ++ return 0; ++} ++ ++/* plugin->u.node.update_item_key ++ look for description of this method in plugin/node/node.h */ ++void ++update_item_key_node40(coord_t * target, const reiser4_key * key, ++ carry_plugin_info * info) ++{ ++ item_header40 *ih; ++ ++ ih = node40_ih_at_coord(target); ++ memcpy(&ih->key, key, sizeof(reiser4_key)); ++ ++ if (target->item_pos == 0) { ++ prepare_for_update(NULL, target->node, info); ++ } ++} ++ ++/* this bits encode cut mode */ ++#define CMODE_TAIL 1 ++#define CMODE_WHOLE 2 ++#define CMODE_HEAD 4 ++ ++struct cut40_info { ++ int mode; ++ pos_in_node_t tail_removed; /* position of item which gets tail removed */ ++ pos_in_node_t first_removed; /* position of first the leftmost item among items removed completely */ ++ pos_in_node_t removed_count; /* number of items removed completely */ ++ pos_in_node_t head_removed; /* position of item which gets head removed */ ++ ++ pos_in_node_t freed_space_start; ++ pos_in_node_t freed_space_end; ++ pos_in_node_t first_moved; ++ pos_in_node_t head_removed_location; ++}; ++ ++static void init_cinfo(struct cut40_info *cinfo) ++{ ++ cinfo->mode = 0; ++ cinfo->tail_removed = MAX_POS_IN_NODE; ++ cinfo->first_removed = MAX_POS_IN_NODE; ++ cinfo->removed_count = MAX_POS_IN_NODE; ++ cinfo->head_removed = MAX_POS_IN_NODE; ++ cinfo->freed_space_start = MAX_POS_IN_NODE; ++ cinfo->freed_space_end = MAX_POS_IN_NODE; ++ cinfo->first_moved = MAX_POS_IN_NODE; ++ cinfo->head_removed_location = MAX_POS_IN_NODE; ++} ++ ++/* complete cut_node40/kill_node40 content by removing the gap created by */ ++static void compact(znode * node, struct cut40_info *cinfo) ++{ ++ node40_header *nh; ++ item_header40 *ih; ++ pos_in_node_t freed; ++ pos_in_node_t pos, nr_items; ++ ++ assert("vs-1526", (cinfo->freed_space_start != MAX_POS_IN_NODE && ++ cinfo->freed_space_end != MAX_POS_IN_NODE && ++ cinfo->first_moved != MAX_POS_IN_NODE)); ++ assert("vs-1523", cinfo->freed_space_end >= cinfo->freed_space_start); ++ ++ nh = node40_node_header(node); ++ nr_items = nh40_get_num_items(nh); ++ ++ /* remove gap made up by removal */ ++ memmove(zdata(node) + cinfo->freed_space_start, ++ zdata(node) + cinfo->freed_space_end, ++ nh40_get_free_space_start(nh) - cinfo->freed_space_end); ++ ++ /* update item headers of moved items - change their locations */ ++ pos = cinfo->first_moved; ++ ih = node40_ih_at(node, pos); ++ if (cinfo->head_removed_location != MAX_POS_IN_NODE) { ++ assert("vs-1580", pos == cinfo->head_removed); ++ ih40_set_offset(ih, cinfo->head_removed_location); ++ pos++; ++ ih--; ++ } ++ ++ freed = cinfo->freed_space_end - cinfo->freed_space_start; ++ for (; pos < nr_items; pos++, ih--) { ++ assert("vs-1581", ih == node40_ih_at(node, pos)); ++ ih40_set_offset(ih, ih40_get_offset(ih) - freed); ++ } ++ ++ /* free space start moved to right */ ++ nh40_set_free_space_start(nh, nh40_get_free_space_start(nh) - freed); ++ ++ if (cinfo->removed_count != MAX_POS_IN_NODE) { ++ /* number of items changed. Remove item headers of those items */ ++ ih = node40_ih_at(node, nr_items - 1); ++ memmove(ih + cinfo->removed_count, ih, ++ sizeof(item_header40) * (nr_items - ++ cinfo->removed_count - ++ cinfo->first_removed)); ++ freed += sizeof(item_header40) * cinfo->removed_count; ++ node40_set_num_items(node, nh, nr_items - cinfo->removed_count); ++ } ++ ++ /* total amount of free space increased */ ++ nh40_set_free_space(nh, nh40_get_free_space(nh) + freed); ++} ++ ++int shrink_item_node40(coord_t * coord, int delta) ++{ ++ node40_header *nh; ++ item_header40 *ih; ++ pos_in_node_t pos; ++ pos_in_node_t nr_items; ++ char *end; ++ znode *node; ++ int off; ++ ++ assert("nikita-3487", coord != NULL); ++ assert("nikita-3488", delta >= 0); ++ ++ node = coord->node; ++ nh = node40_node_header(node); ++ nr_items = nh40_get_num_items(nh); ++ ++ ih = node40_ih_at_coord(coord); ++ assert("nikita-3489", delta <= length_by_coord_node40(coord)); ++ off = ih40_get_offset(ih) + length_by_coord_node40(coord); ++ end = zdata(node) + off; ++ ++ /* remove gap made up by removal */ ++ memmove(end - delta, end, nh40_get_free_space_start(nh) - off); ++ ++ /* update item headers of moved items - change their locations */ ++ pos = coord->item_pos + 1; ++ ih = node40_ih_at(node, pos); ++ for (; pos < nr_items; pos++, ih--) { ++ assert("nikita-3490", ih == node40_ih_at(node, pos)); ++ ih40_set_offset(ih, ih40_get_offset(ih) - delta); ++ } ++ ++ /* free space start moved to left */ ++ nh40_set_free_space_start(nh, nh40_get_free_space_start(nh) - delta); ++ /* total amount of free space increased */ ++ nh40_set_free_space(nh, nh40_get_free_space(nh) + delta); ++ /* ++ * This method does _not_ changes number of items. Hence, it cannot ++ * make node empty. Also it doesn't remove items at all, which means ++ * that no keys have to be updated either. ++ */ ++ return 0; ++} ++ ++/* this is used by cut_node40 and kill_node40. It analyses input parameters and calculates cut mode. There are 2 types ++ of cut. First is when a unit is removed from the middle of an item. In this case this function returns 1. All the ++ rest fits into second case: 0 or 1 of items getting tail cut, 0 or more items removed completely and 0 or 1 item ++ getting head cut. Function returns 0 in this case */ ++static int ++parse_cut(struct cut40_info *cinfo, const struct cut_kill_params *params) ++{ ++ reiser4_key left_key, right_key; ++ reiser4_key min_from_key, max_to_key; ++ const reiser4_key *from_key, *to_key; ++ ++ init_cinfo(cinfo); ++ ++ /* calculate minimal key stored in first item of items to be cut (params->from) */ ++ item_key_by_coord(params->from, &min_from_key); ++ /* and max key stored in last item of items to be cut (params->to) */ ++ max_item_key_by_coord(params->to, &max_to_key); ++ ++ /* if cut key range is not defined in input parameters - define it using cut coord range */ ++ if (params->from_key == NULL) { ++ assert("vs-1513", params->to_key == NULL); ++ unit_key_by_coord(params->from, &left_key); ++ from_key = &left_key; ++ max_unit_key_by_coord(params->to, &right_key); ++ to_key = &right_key; ++ } else { ++ from_key = params->from_key; ++ to_key = params->to_key; ++ } ++ ++ if (params->from->item_pos == params->to->item_pos) { ++ if (keylt(&min_from_key, from_key) ++ && keylt(to_key, &max_to_key)) ++ return 1; ++ ++ if (keygt(from_key, &min_from_key)) { ++ /* tail of item is to be cut cut */ ++ cinfo->tail_removed = params->from->item_pos; ++ cinfo->mode |= CMODE_TAIL; ++ } else if (keylt(to_key, &max_to_key)) { ++ /* head of item is to be cut */ ++ cinfo->head_removed = params->from->item_pos; ++ cinfo->mode |= CMODE_HEAD; ++ } else { ++ /* item is removed completely */ ++ cinfo->first_removed = params->from->item_pos; ++ cinfo->removed_count = 1; ++ cinfo->mode |= CMODE_WHOLE; ++ } ++ } else { ++ cinfo->first_removed = params->from->item_pos + 1; ++ cinfo->removed_count = ++ params->to->item_pos - params->from->item_pos - 1; ++ ++ if (keygt(from_key, &min_from_key)) { ++ /* first item is not cut completely */ ++ cinfo->tail_removed = params->from->item_pos; ++ cinfo->mode |= CMODE_TAIL; ++ } else { ++ cinfo->first_removed--; ++ cinfo->removed_count++; ++ } ++ if (keylt(to_key, &max_to_key)) { ++ /* last item is not cut completely */ ++ cinfo->head_removed = params->to->item_pos; ++ cinfo->mode |= CMODE_HEAD; ++ } else { ++ cinfo->removed_count++; ++ } ++ if (cinfo->removed_count) ++ cinfo->mode |= CMODE_WHOLE; ++ } ++ ++ return 0; ++} ++ ++static void ++call_kill_hooks(znode * node, pos_in_node_t from, pos_in_node_t count, ++ carry_kill_data * kdata) ++{ ++ coord_t coord; ++ item_plugin *iplug; ++ pos_in_node_t pos; ++ ++ coord.node = node; ++ coord.unit_pos = 0; ++ coord.between = AT_UNIT; ++ for (pos = 0; pos < count; pos++) { ++ coord_set_item_pos(&coord, from + pos); ++ coord.unit_pos = 0; ++ coord.between = AT_UNIT; ++ iplug = item_plugin_by_coord(&coord); ++ if (iplug->b.kill_hook) { ++ iplug->b.kill_hook(&coord, 0, coord_num_units(&coord), ++ kdata); ++ } ++ } ++} ++ ++/* this is used to kill item partially */ ++static pos_in_node_t ++kill_units(coord_t * coord, pos_in_node_t from, pos_in_node_t to, void *data, ++ reiser4_key * smallest_removed, reiser4_key * new_first_key) ++{ ++ struct carry_kill_data *kdata; ++ item_plugin *iplug; ++ ++ kdata = data; ++ iplug = item_plugin_by_coord(coord); ++ ++ assert("vs-1524", iplug->b.kill_units); ++ return iplug->b.kill_units(coord, from, to, kdata, smallest_removed, ++ new_first_key); ++} ++ ++/* call item plugin to cut tail of file */ ++static pos_in_node_t ++kill_tail(coord_t * coord, void *data, reiser4_key * smallest_removed) ++{ ++ struct carry_kill_data *kdata; ++ pos_in_node_t to; ++ ++ kdata = data; ++ to = coord_last_unit_pos(coord); ++ return kill_units(coord, coord->unit_pos, to, kdata, smallest_removed, ++ NULL); ++} ++ ++/* call item plugin to cut head of item */ ++static pos_in_node_t ++kill_head(coord_t * coord, void *data, reiser4_key * smallest_removed, ++ reiser4_key * new_first_key) ++{ ++ return kill_units(coord, 0, coord->unit_pos, data, smallest_removed, ++ new_first_key); ++} ++ ++/* this is used to cut item partially */ ++static pos_in_node_t ++cut_units(coord_t * coord, pos_in_node_t from, pos_in_node_t to, void *data, ++ reiser4_key * smallest_removed, reiser4_key * new_first_key) ++{ ++ carry_cut_data *cdata; ++ item_plugin *iplug; ++ ++ cdata = data; ++ iplug = item_plugin_by_coord(coord); ++ assert("vs-302", iplug->b.cut_units); ++ return iplug->b.cut_units(coord, from, to, cdata, smallest_removed, ++ new_first_key); ++} ++ ++/* call item plugin to cut tail of file */ ++static pos_in_node_t ++cut_tail(coord_t * coord, void *data, reiser4_key * smallest_removed) ++{ ++ carry_cut_data *cdata; ++ pos_in_node_t to; ++ ++ cdata = data; ++ to = coord_last_unit_pos(cdata->params.from); ++ return cut_units(coord, coord->unit_pos, to, data, smallest_removed, NULL); ++} ++ ++/* call item plugin to cut head of item */ ++static pos_in_node_t ++cut_head(coord_t * coord, void *data, reiser4_key * smallest_removed, ++ reiser4_key * new_first_key) ++{ ++ return cut_units(coord, 0, coord->unit_pos, data, smallest_removed, ++ new_first_key); ++} ++ ++/* this returns 1 of key of first item changed, 0 - if it did not */ ++static int ++prepare_for_compact(struct cut40_info *cinfo, ++ const struct cut_kill_params *params, int is_cut, ++ void *data, carry_plugin_info * info) ++{ ++ znode *node; ++ item_header40 *ih; ++ pos_in_node_t freed; ++ pos_in_node_t item_pos; ++ coord_t coord; ++ reiser4_key new_first_key; ++ pos_in_node_t(*kill_units_f) (coord_t *, pos_in_node_t, pos_in_node_t, ++ void *, reiser4_key *, reiser4_key *); ++ pos_in_node_t(*kill_tail_f) (coord_t *, void *, reiser4_key *); ++ pos_in_node_t(*kill_head_f) (coord_t *, void *, reiser4_key *, ++ reiser4_key *); ++ int retval; ++ ++ retval = 0; ++ ++ node = params->from->node; ++ ++ assert("vs-184", node == params->to->node); ++ assert("vs-312", !node_is_empty(node)); ++ assert("vs-297", ++ coord_compare(params->from, params->to) != COORD_CMP_ON_RIGHT); ++ ++ if (is_cut) { ++ kill_units_f = cut_units; ++ kill_tail_f = cut_tail; ++ kill_head_f = cut_head; ++ } else { ++ kill_units_f = kill_units; ++ kill_tail_f = kill_tail; ++ kill_head_f = kill_head; ++ } ++ ++ if (parse_cut(cinfo, params) == 1) { ++ /* cut from the middle of item */ ++ freed = ++ kill_units_f(params->from, params->from->unit_pos, ++ params->to->unit_pos, data, ++ params->smallest_removed, NULL); ++ ++ item_pos = params->from->item_pos; ++ ih = node40_ih_at(node, item_pos); ++ cinfo->freed_space_start = ++ ih40_get_offset(ih) + node40_item_length(node, ++ item_pos) - freed; ++ cinfo->freed_space_end = cinfo->freed_space_start + freed; ++ cinfo->first_moved = item_pos + 1; ++ } else { ++ assert("vs-1521", (cinfo->tail_removed != MAX_POS_IN_NODE || ++ cinfo->first_removed != MAX_POS_IN_NODE || ++ cinfo->head_removed != MAX_POS_IN_NODE)); ++ ++ switch (cinfo->mode) { ++ case CMODE_TAIL: ++ /* one item gets cut partially from its end */ ++ assert("vs-1562", ++ cinfo->tail_removed == params->from->item_pos); ++ ++ freed = ++ kill_tail_f(params->from, data, ++ params->smallest_removed); ++ ++ item_pos = cinfo->tail_removed; ++ ih = node40_ih_at(node, item_pos); ++ cinfo->freed_space_start = ++ ih40_get_offset(ih) + node40_item_length(node, ++ item_pos) - ++ freed; ++ cinfo->freed_space_end = ++ cinfo->freed_space_start + freed; ++ cinfo->first_moved = cinfo->tail_removed + 1; ++ break; ++ ++ case CMODE_WHOLE: ++ /* one or more items get removed completely */ ++ assert("vs-1563", ++ cinfo->first_removed == params->from->item_pos); ++ assert("vs-1564", cinfo->removed_count > 0 ++ && cinfo->removed_count != MAX_POS_IN_NODE); ++ ++ /* call kill hook for all items removed completely */ ++ if (is_cut == 0) ++ call_kill_hooks(node, cinfo->first_removed, ++ cinfo->removed_count, data); ++ ++ item_pos = cinfo->first_removed; ++ ih = node40_ih_at(node, item_pos); ++ ++ if (params->smallest_removed) ++ memcpy(params->smallest_removed, &ih->key, ++ sizeof(reiser4_key)); ++ ++ cinfo->freed_space_start = ih40_get_offset(ih); ++ ++ item_pos += (cinfo->removed_count - 1); ++ ih -= (cinfo->removed_count - 1); ++ cinfo->freed_space_end = ++ ih40_get_offset(ih) + node40_item_length(node, ++ item_pos); ++ cinfo->first_moved = item_pos + 1; ++ if (cinfo->first_removed == 0) ++ /* key of first item of the node changes */ ++ retval = 1; ++ break; ++ ++ case CMODE_HEAD: ++ /* one item gets cut partially from its head */ ++ assert("vs-1565", ++ cinfo->head_removed == params->from->item_pos); ++ ++ freed = ++ kill_head_f(params->to, data, ++ params->smallest_removed, ++ &new_first_key); ++ ++ item_pos = cinfo->head_removed; ++ ih = node40_ih_at(node, item_pos); ++ cinfo->freed_space_start = ih40_get_offset(ih); ++ cinfo->freed_space_end = ih40_get_offset(ih) + freed; ++ cinfo->first_moved = cinfo->head_removed + 1; ++ ++ /* item head is removed, therefore, item key changed */ ++ coord.node = node; ++ coord_set_item_pos(&coord, item_pos); ++ coord.unit_pos = 0; ++ coord.between = AT_UNIT; ++ update_item_key_node40(&coord, &new_first_key, NULL); ++ if (item_pos == 0) ++ /* key of first item of the node changes */ ++ retval = 1; ++ break; ++ ++ case CMODE_TAIL | CMODE_WHOLE: ++ /* one item gets cut from its end and one or more items get removed completely */ ++ assert("vs-1566", ++ cinfo->tail_removed == params->from->item_pos); ++ assert("vs-1567", ++ cinfo->first_removed == cinfo->tail_removed + 1); ++ assert("vs-1564", cinfo->removed_count > 0 ++ && cinfo->removed_count != MAX_POS_IN_NODE); ++ ++ freed = ++ kill_tail_f(params->from, data, ++ params->smallest_removed); ++ ++ item_pos = cinfo->tail_removed; ++ ih = node40_ih_at(node, item_pos); ++ cinfo->freed_space_start = ++ ih40_get_offset(ih) + node40_item_length(node, ++ item_pos) - ++ freed; ++ ++ /* call kill hook for all items removed completely */ ++ if (is_cut == 0) ++ call_kill_hooks(node, cinfo->first_removed, ++ cinfo->removed_count, data); ++ ++ item_pos += cinfo->removed_count; ++ ih -= cinfo->removed_count; ++ cinfo->freed_space_end = ++ ih40_get_offset(ih) + node40_item_length(node, ++ item_pos); ++ cinfo->first_moved = item_pos + 1; ++ break; ++ ++ case CMODE_WHOLE | CMODE_HEAD: ++ /* one or more items get removed completely and one item gets cut partially from its head */ ++ assert("vs-1568", ++ cinfo->first_removed == params->from->item_pos); ++ assert("vs-1564", cinfo->removed_count > 0 ++ && cinfo->removed_count != MAX_POS_IN_NODE); ++ assert("vs-1569", ++ cinfo->head_removed == ++ cinfo->first_removed + cinfo->removed_count); ++ ++ /* call kill hook for all items removed completely */ ++ if (is_cut == 0) ++ call_kill_hooks(node, cinfo->first_removed, ++ cinfo->removed_count, data); ++ ++ item_pos = cinfo->first_removed; ++ ih = node40_ih_at(node, item_pos); ++ ++ if (params->smallest_removed) ++ memcpy(params->smallest_removed, &ih->key, ++ sizeof(reiser4_key)); ++ ++ freed = ++ kill_head_f(params->to, data, NULL, &new_first_key); ++ ++ cinfo->freed_space_start = ih40_get_offset(ih); ++ ++ ih = node40_ih_at(node, cinfo->head_removed); ++ /* this is the most complex case. Item which got head removed and items which are to be moved ++ intact change their location differently. */ ++ cinfo->freed_space_end = ih40_get_offset(ih) + freed; ++ cinfo->first_moved = cinfo->head_removed; ++ cinfo->head_removed_location = cinfo->freed_space_start; ++ ++ /* item head is removed, therefore, item key changed */ ++ coord.node = node; ++ coord_set_item_pos(&coord, cinfo->head_removed); ++ coord.unit_pos = 0; ++ coord.between = AT_UNIT; ++ update_item_key_node40(&coord, &new_first_key, NULL); ++ ++ assert("vs-1579", cinfo->first_removed == 0); ++ /* key of first item of the node changes */ ++ retval = 1; ++ break; ++ ++ case CMODE_TAIL | CMODE_HEAD: ++ /* one item get cut from its end and its neighbor gets cut from its tail */ ++ impossible("vs-1576", "this can not happen currently"); ++ break; ++ ++ case CMODE_TAIL | CMODE_WHOLE | CMODE_HEAD: ++ impossible("vs-1577", "this can not happen currently"); ++ break; ++ default: ++ impossible("vs-1578", "unexpected cut mode"); ++ break; ++ } ++ } ++ return retval; ++} ++ ++/* plugin->u.node.kill ++ return value is number of items removed completely */ ++int kill_node40(struct carry_kill_data *kdata, carry_plugin_info * info) ++{ ++ znode *node; ++ struct cut40_info cinfo; ++ int first_key_changed; ++ ++ node = kdata->params.from->node; ++ ++ first_key_changed = ++ prepare_for_compact(&cinfo, &kdata->params, 0 /* not cut */ , kdata, ++ info); ++ compact(node, &cinfo); ++ ++ if (info) { ++ /* it is not called by node40_shift, so we have to take care ++ of changes on upper levels */ ++ if (node_is_empty(node) ++ && !(kdata->flags & DELETE_RETAIN_EMPTY)) ++ /* all contents of node is deleted */ ++ prepare_removal_node40(node, info); ++ else if (first_key_changed) { ++ prepare_for_update(NULL, node, info); ++ } ++ } ++ ++ coord_clear_iplug(kdata->params.from); ++ coord_clear_iplug(kdata->params.to); ++ ++ znode_make_dirty(node); ++ return cinfo.removed_count == MAX_POS_IN_NODE ? 0 : cinfo.removed_count; ++} ++ ++/* plugin->u.node.cut ++ return value is number of items removed completely */ ++int cut_node40(struct carry_cut_data *cdata, carry_plugin_info * info) ++{ ++ znode *node; ++ struct cut40_info cinfo; ++ int first_key_changed; ++ ++ node = cdata->params.from->node; ++ ++ first_key_changed = ++ prepare_for_compact(&cinfo, &cdata->params, 1 /* not cut */ , cdata, ++ info); ++ compact(node, &cinfo); ++ ++ if (info) { ++ /* it is not called by node40_shift, so we have to take care ++ of changes on upper levels */ ++ if (node_is_empty(node)) ++ /* all contents of node is deleted */ ++ prepare_removal_node40(node, info); ++ else if (first_key_changed) { ++ prepare_for_update(NULL, node, info); ++ } ++ } ++ ++ coord_clear_iplug(cdata->params.from); ++ coord_clear_iplug(cdata->params.to); ++ ++ znode_make_dirty(node); ++ return cinfo.removed_count == MAX_POS_IN_NODE ? 0 : cinfo.removed_count; ++} ++ ++/* this structure is used by shift method of node40 plugin */ ++struct shift_params { ++ shift_direction pend; /* when @pend == append - we are shifting to ++ left, when @pend == prepend - to right */ ++ coord_t wish_stop; /* when shifting to left this is last unit we ++ want shifted, when shifting to right - this ++ is set to unit we want to start shifting ++ from */ ++ znode *target; ++ int everything; /* it is set to 1 if everything we have to shift is ++ shifted, 0 - otherwise */ ++ ++ /* FIXME-VS: get rid of read_stop */ ++ ++ /* these are set by estimate_shift */ ++ coord_t real_stop; /* this will be set to last unit which will be ++ really shifted */ ++ ++ /* coordinate in source node before operation of unit which becomes ++ first after shift to left of last after shift to right */ ++ union { ++ coord_t future_first; ++ coord_t future_last; ++ } u; ++ ++ unsigned merging_units; /* number of units of first item which have to ++ be merged with last item of target node */ ++ unsigned merging_bytes; /* number of bytes in those units */ ++ ++ unsigned entire; /* items shifted in their entirety */ ++ unsigned entire_bytes; /* number of bytes in those items */ ++ ++ unsigned part_units; /* number of units of partially copied item */ ++ unsigned part_bytes; /* number of bytes in those units */ ++ ++ unsigned shift_bytes; /* total number of bytes in items shifted (item ++ headers not included) */ ++ ++}; ++ ++static int item_creation_overhead(coord_t *item) ++{ ++ return node_plugin_by_coord(item)->item_overhead(item->node, NULL); ++} ++ ++/* how many units are there in @source starting from source->unit_pos ++ but not further than @stop_coord */ ++static int ++wanted_units(coord_t *source, coord_t *stop_coord, shift_direction pend) ++{ ++ if (pend == SHIFT_LEFT) { ++ assert("vs-181", source->unit_pos == 0); ++ } else { ++ assert("vs-182", ++ source->unit_pos == coord_last_unit_pos(source)); ++ } ++ ++ if (source->item_pos != stop_coord->item_pos) { ++ /* @source and @stop_coord are different items */ ++ return coord_last_unit_pos(source) + 1; ++ } ++ ++ if (pend == SHIFT_LEFT) { ++ return stop_coord->unit_pos + 1; ++ } else { ++ return source->unit_pos - stop_coord->unit_pos + 1; ++ } ++} ++ ++/* this calculates what can be copied from @shift->wish_stop.node to ++ @shift->target */ ++static void ++estimate_shift(struct shift_params *shift, const reiser4_context * ctx) ++{ ++ unsigned target_free_space, size; ++ pos_in_node_t stop_item; /* item which estimating should not consider */ ++ unsigned want; /* number of units of item we want shifted */ ++ coord_t source; /* item being estimated */ ++ item_plugin *iplug; ++ ++ /* shifting to left/right starts from first/last units of ++ @shift->wish_stop.node */ ++ if (shift->pend == SHIFT_LEFT) { ++ coord_init_first_unit(&source, shift->wish_stop.node); ++ } else { ++ coord_init_last_unit(&source, shift->wish_stop.node); ++ } ++ shift->real_stop = source; ++ ++ /* free space in target node and number of items in source */ ++ target_free_space = znode_free_space(shift->target); ++ ++ shift->everything = 0; ++ if (!node_is_empty(shift->target)) { ++ /* target node is not empty, check for boundary items ++ mergeability */ ++ coord_t to; ++ ++ /* item we try to merge @source with */ ++ if (shift->pend == SHIFT_LEFT) { ++ coord_init_last_unit(&to, shift->target); ++ } else { ++ coord_init_first_unit(&to, shift->target); ++ } ++ ++ if ((shift->pend == SHIFT_LEFT) ? are_items_mergeable(&to, ++ &source) : ++ are_items_mergeable(&source, &to)) { ++ /* how many units of @source do we want to merge to ++ item @to */ ++ want = ++ wanted_units(&source, &shift->wish_stop, ++ shift->pend); ++ ++ /* how many units of @source we can merge to item ++ @to */ ++ iplug = item_plugin_by_coord(&source); ++ if (iplug->b.can_shift != NULL) ++ shift->merging_units = ++ iplug->b.can_shift(target_free_space, ++ &source, shift->target, ++ shift->pend, &size, ++ want); ++ else { ++ shift->merging_units = 0; ++ size = 0; ++ } ++ shift->merging_bytes = size; ++ shift->shift_bytes += size; ++ /* update stop coord to be set to last unit of @source ++ we can merge to @target */ ++ if (shift->merging_units) ++ /* at least one unit can be shifted */ ++ shift->real_stop.unit_pos = ++ (shift->merging_units - source.unit_pos - ++ 1) * shift->pend; ++ else { ++ /* nothing can be shifted */ ++ if (shift->pend == SHIFT_LEFT) ++ coord_init_before_first_item(&shift-> ++ real_stop, ++ source. ++ node); ++ else ++ coord_init_after_last_item(&shift-> ++ real_stop, ++ source.node); ++ } ++ assert("nikita-2081", shift->real_stop.unit_pos + 1); ++ ++ if (shift->merging_units != want) { ++ /* we could not copy as many as we want, so, ++ there is no reason for estimating any ++ longer */ ++ return; ++ } ++ ++ target_free_space -= size; ++ coord_add_item_pos(&source, shift->pend); ++ } ++ } ++ ++ /* number of item nothing of which we want to shift */ ++ stop_item = shift->wish_stop.item_pos + shift->pend; ++ ++ /* calculate how many items can be copied into given free ++ space as whole */ ++ for (; source.item_pos != stop_item; ++ coord_add_item_pos(&source, shift->pend)) { ++ if (shift->pend == SHIFT_RIGHT) ++ source.unit_pos = coord_last_unit_pos(&source); ++ ++ /* how many units of @source do we want to copy */ ++ want = wanted_units(&source, &shift->wish_stop, shift->pend); ++ ++ if (want == coord_last_unit_pos(&source) + 1) { ++ /* we want this item to be copied entirely */ ++ size = ++ item_length_by_coord(&source) + ++ item_creation_overhead(&source); ++ if (size <= target_free_space) { ++ /* item fits into target node as whole */ ++ target_free_space -= size; ++ shift->shift_bytes += ++ size - item_creation_overhead(&source); ++ shift->entire_bytes += ++ size - item_creation_overhead(&source); ++ shift->entire++; ++ ++ /* update shift->real_stop coord to be set to ++ last unit of @source we can merge to ++ @target */ ++ shift->real_stop = source; ++ if (shift->pend == SHIFT_LEFT) ++ shift->real_stop.unit_pos = ++ coord_last_unit_pos(&shift-> ++ real_stop); ++ else ++ shift->real_stop.unit_pos = 0; ++ continue; ++ } ++ } ++ ++ /* we reach here only for an item which does not fit into ++ target node in its entirety. This item may be either ++ partially shifted, or not shifted at all. We will have to ++ create new item in target node, so decrease amout of free ++ space by an item creation overhead. We can reach here also ++ if stop coord is in this item */ ++ if (target_free_space >= ++ (unsigned)item_creation_overhead(&source)) { ++ target_free_space -= item_creation_overhead(&source); ++ iplug = item_plugin_by_coord(&source); ++ if (iplug->b.can_shift) { ++ shift->part_units = iplug->b.can_shift(target_free_space, ++ &source, ++ NULL, /* target */ ++ shift->pend, ++ &size, ++ want); ++ } else { ++ target_free_space = 0; ++ shift->part_units = 0; ++ size = 0; ++ } ++ } else { ++ target_free_space = 0; ++ shift->part_units = 0; ++ size = 0; ++ } ++ shift->part_bytes = size; ++ shift->shift_bytes += size; ++ ++ /* set @shift->real_stop to last unit of @source we can merge ++ to @shift->target */ ++ if (shift->part_units) { ++ shift->real_stop = source; ++ shift->real_stop.unit_pos = ++ (shift->part_units - source.unit_pos - ++ 1) * shift->pend; ++ assert("nikita-2082", shift->real_stop.unit_pos + 1); ++ } ++ ++ if (want != shift->part_units) ++ /* not everything wanted were shifted */ ++ return; ++ break; ++ } ++ ++ shift->everything = 1; ++} ++ ++static void ++copy_units(coord_t * target, coord_t * source, unsigned from, unsigned count, ++ shift_direction dir, unsigned free_space) ++{ ++ item_plugin *iplug; ++ ++ assert("nikita-1463", target != NULL); ++ assert("nikita-1464", source != NULL); ++ assert("nikita-1465", from + count <= coord_num_units(source)); ++ ++ iplug = item_plugin_by_coord(source); ++ assert("nikita-1468", iplug == item_plugin_by_coord(target)); ++ iplug->b.copy_units(target, source, from, count, dir, free_space); ++ ++ if (dir == SHIFT_RIGHT) { ++ /* FIXME-VS: this looks not necessary. update_item_key was ++ called already by copy_units method */ ++ reiser4_key split_key; ++ ++ assert("nikita-1469", target->unit_pos == 0); ++ ++ unit_key_by_coord(target, &split_key); ++ node_plugin_by_coord(target)->update_item_key(target, ++ &split_key, NULL); ++ } ++} ++ ++/* copy part of @shift->real_stop.node starting either from its beginning or ++ from its end and ending at @shift->real_stop to either the end or the ++ beginning of @shift->target */ ++static void copy(struct shift_params *shift) ++{ ++ node40_header *nh; ++ coord_t from; ++ coord_t to; ++ item_header40 *from_ih, *to_ih; ++ int free_space_start; ++ int new_items; ++ unsigned old_items; ++ int old_offset; ++ unsigned i; ++ ++ nh = node40_node_header(shift->target); ++ free_space_start = nh40_get_free_space_start(nh); ++ old_items = nh40_get_num_items(nh); ++ new_items = shift->entire + (shift->part_units ? 1 : 0); ++ assert("vs-185", ++ shift->shift_bytes == ++ shift->merging_bytes + shift->entire_bytes + shift->part_bytes); ++ ++ from = shift->wish_stop; ++ ++ coord_init_first_unit(&to, shift->target); ++ ++ /* NOTE:NIKITA->VS not sure what I am doing: shift->target is empty, ++ hence to.between is set to EMPTY_NODE above. Looks like we want it ++ to be AT_UNIT. ++ ++ Oh, wonders of ->betweeness... ++ ++ */ ++ to.between = AT_UNIT; ++ ++ if (shift->pend == SHIFT_LEFT) { ++ /* copying to left */ ++ ++ coord_set_item_pos(&from, 0); ++ from_ih = node40_ih_at(from.node, 0); ++ ++ coord_set_item_pos(&to, ++ node40_num_of_items_internal(to.node) - 1); ++ if (shift->merging_units) { ++ /* expand last item, so that plugin methods will see ++ correct data */ ++ free_space_start += shift->merging_bytes; ++ nh40_set_free_space_start(nh, ++ (unsigned)free_space_start); ++ nh40_set_free_space(nh, ++ nh40_get_free_space(nh) - ++ shift->merging_bytes); ++ ++ /* appending last item of @target */ ++ copy_units(&to, &from, 0, /* starting from 0-th unit */ ++ shift->merging_units, SHIFT_LEFT, ++ shift->merging_bytes); ++ coord_inc_item_pos(&from); ++ from_ih--; ++ coord_inc_item_pos(&to); ++ } ++ ++ to_ih = node40_ih_at(shift->target, old_items); ++ if (shift->entire) { ++ /* copy @entire items entirely */ ++ ++ /* copy item headers */ ++ memcpy(to_ih - shift->entire + 1, ++ from_ih - shift->entire + 1, ++ shift->entire * sizeof(item_header40)); ++ /* update item header offset */ ++ old_offset = ih40_get_offset(from_ih); ++ /* AUDIT: Looks like if we calculate old_offset + free_space_start here instead of just old_offset, we can perform one "add" operation less per each iteration */ ++ for (i = 0; i < shift->entire; i++, to_ih--, from_ih--) ++ ih40_set_offset(to_ih, ++ ih40_get_offset(from_ih) - ++ old_offset + free_space_start); ++ ++ /* copy item bodies */ ++ memcpy(zdata(shift->target) + free_space_start, zdata(from.node) + old_offset, /*ih40_get_offset (from_ih), */ ++ shift->entire_bytes); ++ ++ coord_add_item_pos(&from, (int)shift->entire); ++ coord_add_item_pos(&to, (int)shift->entire); ++ } ++ ++ nh40_set_free_space_start(nh, ++ free_space_start + ++ shift->shift_bytes - ++ shift->merging_bytes); ++ nh40_set_free_space(nh, ++ nh40_get_free_space(nh) - ++ (shift->shift_bytes - shift->merging_bytes + ++ sizeof(item_header40) * new_items)); ++ ++ /* update node header */ ++ node40_set_num_items(shift->target, nh, old_items + new_items); ++ assert("vs-170", ++ nh40_get_free_space(nh) < znode_size(shift->target)); ++ ++ if (shift->part_units) { ++ /* copy heading part (@part units) of @source item as ++ a new item into @target->node */ ++ ++ /* copy item header of partially copied item */ ++ coord_set_item_pos(&to, ++ node40_num_of_items_internal(to.node) ++ - 1); ++ memcpy(to_ih, from_ih, sizeof(item_header40)); ++ ih40_set_offset(to_ih, ++ nh40_get_free_space_start(nh) - ++ shift->part_bytes); ++ if (item_plugin_by_coord(&to)->b.init) ++ item_plugin_by_coord(&to)->b.init(&to, &from, ++ NULL); ++ copy_units(&to, &from, 0, shift->part_units, SHIFT_LEFT, ++ shift->part_bytes); ++ } ++ ++ } else { ++ /* copying to right */ ++ ++ coord_set_item_pos(&from, ++ node40_num_of_items_internal(from.node) - 1); ++ from_ih = node40_ih_at_coord(&from); ++ ++ coord_set_item_pos(&to, 0); ++ ++ /* prepare space for new items */ ++ memmove(zdata(to.node) + sizeof(node40_header) + ++ shift->shift_bytes, ++ zdata(to.node) + sizeof(node40_header), ++ free_space_start - sizeof(node40_header)); ++ /* update item headers of moved items */ ++ to_ih = node40_ih_at(to.node, 0); ++ /* first item gets @merging_bytes longer. free space appears ++ at its beginning */ ++ if (!node_is_empty(to.node)) ++ ih40_set_offset(to_ih, ++ ih40_get_offset(to_ih) + ++ shift->shift_bytes - ++ shift->merging_bytes); ++ ++ for (i = 1; i < old_items; i++) ++ ih40_set_offset(to_ih - i, ++ ih40_get_offset(to_ih - i) + ++ shift->shift_bytes); ++ ++ /* move item headers to make space for new items */ ++ memmove(to_ih - old_items + 1 - new_items, ++ to_ih - old_items + 1, ++ sizeof(item_header40) * old_items); ++ to_ih -= (new_items - 1); ++ ++ nh40_set_free_space_start(nh, ++ free_space_start + ++ shift->shift_bytes); ++ nh40_set_free_space(nh, ++ nh40_get_free_space(nh) - ++ (shift->shift_bytes + ++ sizeof(item_header40) * new_items)); ++ ++ /* update node header */ ++ node40_set_num_items(shift->target, nh, old_items + new_items); ++ assert("vs-170", ++ nh40_get_free_space(nh) < znode_size(shift->target)); ++ ++ if (shift->merging_units) { ++ coord_add_item_pos(&to, new_items); ++ to.unit_pos = 0; ++ to.between = AT_UNIT; ++ /* prepend first item of @to */ ++ copy_units(&to, &from, ++ coord_last_unit_pos(&from) - ++ shift->merging_units + 1, ++ shift->merging_units, SHIFT_RIGHT, ++ shift->merging_bytes); ++ coord_dec_item_pos(&from); ++ from_ih++; ++ } ++ ++ if (shift->entire) { ++ /* copy @entire items entirely */ ++ ++ /* copy item headers */ ++ memcpy(to_ih, from_ih, ++ shift->entire * sizeof(item_header40)); ++ ++ /* update item header offset */ ++ old_offset = ++ ih40_get_offset(from_ih + shift->entire - 1); ++ /* AUDIT: old_offset + sizeof (node40_header) + shift->part_bytes calculation can be taken off the loop. */ ++ for (i = 0; i < shift->entire; i++, to_ih++, from_ih++) ++ ih40_set_offset(to_ih, ++ ih40_get_offset(from_ih) - ++ old_offset + ++ sizeof(node40_header) + ++ shift->part_bytes); ++ /* copy item bodies */ ++ coord_add_item_pos(&from, -(int)(shift->entire - 1)); ++ memcpy(zdata(to.node) + sizeof(node40_header) + ++ shift->part_bytes, item_by_coord_node40(&from), ++ shift->entire_bytes); ++ coord_dec_item_pos(&from); ++ } ++ ++ if (shift->part_units) { ++ coord_set_item_pos(&to, 0); ++ to.unit_pos = 0; ++ to.between = AT_UNIT; ++ /* copy heading part (@part units) of @source item as ++ a new item into @target->node */ ++ ++ /* copy item header of partially copied item */ ++ memcpy(to_ih, from_ih, sizeof(item_header40)); ++ ih40_set_offset(to_ih, sizeof(node40_header)); ++ if (item_plugin_by_coord(&to)->b.init) ++ item_plugin_by_coord(&to)->b.init(&to, &from, ++ NULL); ++ copy_units(&to, &from, ++ coord_last_unit_pos(&from) - ++ shift->part_units + 1, shift->part_units, ++ SHIFT_RIGHT, shift->part_bytes); ++ } ++ } ++} ++ ++/* remove everything either before or after @fact_stop. Number of items ++ removed completely is returned */ ++static int delete_copied(struct shift_params *shift) ++{ ++ coord_t from; ++ coord_t to; ++ struct carry_cut_data cdata; ++ ++ if (shift->pend == SHIFT_LEFT) { ++ /* we were shifting to left, remove everything from the ++ beginning of @shift->wish_stop->node upto ++ @shift->wish_stop */ ++ coord_init_first_unit(&from, shift->real_stop.node); ++ to = shift->real_stop; ++ ++ /* store old coordinate of unit which will be first after ++ shift to left */ ++ shift->u.future_first = to; ++ coord_next_unit(&shift->u.future_first); ++ } else { ++ /* we were shifting to right, remove everything from ++ @shift->stop_coord upto to end of ++ @shift->stop_coord->node */ ++ from = shift->real_stop; ++ coord_init_last_unit(&to, from.node); ++ ++ /* store old coordinate of unit which will be last after ++ shift to right */ ++ shift->u.future_last = from; ++ coord_prev_unit(&shift->u.future_last); ++ } ++ ++ cdata.params.from = &from; ++ cdata.params.to = &to; ++ cdata.params.from_key = NULL; ++ cdata.params.to_key = NULL; ++ cdata.params.smallest_removed = NULL; ++ return cut_node40(&cdata, NULL); ++} ++ ++/* something was moved between @left and @right. Add carry operation to @info ++ list to have carry to update delimiting key between them */ ++static int ++prepare_for_update(znode * left, znode * right, carry_plugin_info * info) ++{ ++ carry_op *op; ++ carry_node *cn; ++ ++ if (info == NULL) ++ /* nowhere to send operation to. */ ++ return 0; ++ ++ if (!should_notify_parent(right)) ++ return 0; ++ ++ op = node_post_carry(info, COP_UPDATE, right, 1); ++ if (IS_ERR(op) || op == NULL) ++ return op ? PTR_ERR(op) : -EIO; ++ ++ if (left != NULL) { ++ carry_node *reference; ++ ++ if (info->doing) ++ reference = insert_carry_node(info->doing, ++ info->todo, left); ++ else ++ reference = op->node; ++ assert("nikita-2992", reference != NULL); ++ cn = reiser4_add_carry(info->todo, POOLO_BEFORE, reference); ++ if (IS_ERR(cn)) ++ return PTR_ERR(cn); ++ cn->parent = 1; ++ cn->node = left; ++ if (ZF_ISSET(left, JNODE_ORPHAN)) ++ cn->left_before = 1; ++ op->u.update.left = cn; ++ } else ++ op->u.update.left = NULL; ++ return 0; ++} ++ ++/* plugin->u.node.prepare_removal ++ to delete a pointer to @empty from the tree add corresponding carry ++ operation (delete) to @info list */ ++int prepare_removal_node40(znode * empty, carry_plugin_info * info) ++{ ++ carry_op *op; ++ reiser4_tree *tree; ++ ++ if (!should_notify_parent(empty)) ++ return 0; ++ /* already on a road to Styx */ ++ if (ZF_ISSET(empty, JNODE_HEARD_BANSHEE)) ++ return 0; ++ op = node_post_carry(info, COP_DELETE, empty, 1); ++ if (IS_ERR(op) || op == NULL) ++ return RETERR(op ? PTR_ERR(op) : -EIO); ++ ++ op->u.delete.child = NULL; ++ op->u.delete.flags = 0; ++ ++ /* fare thee well */ ++ tree = znode_get_tree(empty); ++ read_lock_tree(tree); ++ write_lock_dk(tree); ++ znode_set_ld_key(empty, znode_get_rd_key(empty)); ++ if (znode_is_left_connected(empty) && empty->left) ++ znode_set_rd_key(empty->left, znode_get_rd_key(empty)); ++ write_unlock_dk(tree); ++ read_unlock_tree(tree); ++ ++ ZF_SET(empty, JNODE_HEARD_BANSHEE); ++ return 0; ++} ++ ++/* something were shifted from @insert_coord->node to @shift->target, update ++ @insert_coord correspondingly */ ++static void ++adjust_coord(coord_t * insert_coord, struct shift_params *shift, int removed, ++ int including_insert_coord) ++{ ++ /* item plugin was invalidated by shifting */ ++ coord_clear_iplug(insert_coord); ++ ++ if (node_is_empty(shift->wish_stop.node)) { ++ assert("vs-242", shift->everything); ++ if (including_insert_coord) { ++ if (shift->pend == SHIFT_RIGHT) { ++ /* set @insert_coord before first unit of ++ @shift->target node */ ++ coord_init_before_first_item(insert_coord, ++ shift->target); ++ } else { ++ /* set @insert_coord after last in target node */ ++ coord_init_after_last_item(insert_coord, ++ shift->target); ++ } ++ } else { ++ /* set @insert_coord inside of empty node. There is ++ only one possible coord within an empty ++ node. init_first_unit will set that coord */ ++ coord_init_first_unit(insert_coord, ++ shift->wish_stop.node); ++ } ++ return; ++ } ++ ++ if (shift->pend == SHIFT_RIGHT) { ++ /* there was shifting to right */ ++ if (shift->everything) { ++ /* everything wanted was shifted */ ++ if (including_insert_coord) { ++ /* @insert_coord is set before first unit of ++ @to node */ ++ coord_init_before_first_item(insert_coord, ++ shift->target); ++ insert_coord->between = BEFORE_UNIT; ++ } else { ++ /* @insert_coord is set after last unit of ++ @insert->node */ ++ coord_init_last_unit(insert_coord, ++ shift->wish_stop.node); ++ insert_coord->between = AFTER_UNIT; ++ } ++ } ++ return; ++ } ++ ++ /* there was shifting to left */ ++ if (shift->everything) { ++ /* everything wanted was shifted */ ++ if (including_insert_coord) { ++ /* @insert_coord is set after last unit in @to node */ ++ coord_init_after_last_item(insert_coord, shift->target); ++ } else { ++ /* @insert_coord is set before first unit in the same ++ node */ ++ coord_init_before_first_item(insert_coord, ++ shift->wish_stop.node); ++ } ++ return; ++ } ++ ++ /* FIXME-VS: the code below is complicated because with between == ++ AFTER_ITEM unit_pos is set to 0 */ ++ ++ if (!removed) { ++ /* no items were shifted entirely */ ++ assert("vs-195", shift->merging_units == 0 ++ || shift->part_units == 0); ++ ++ if (shift->real_stop.item_pos == insert_coord->item_pos) { ++ if (shift->merging_units) { ++ if (insert_coord->between == AFTER_UNIT) { ++ assert("nikita-1441", ++ insert_coord->unit_pos >= ++ shift->merging_units); ++ insert_coord->unit_pos -= ++ shift->merging_units; ++ } else if (insert_coord->between == BEFORE_UNIT) { ++ assert("nikita-2090", ++ insert_coord->unit_pos > ++ shift->merging_units); ++ insert_coord->unit_pos -= ++ shift->merging_units; ++ } ++ ++ assert("nikita-2083", ++ insert_coord->unit_pos + 1); ++ } else { ++ if (insert_coord->between == AFTER_UNIT) { ++ assert("nikita-1442", ++ insert_coord->unit_pos >= ++ shift->part_units); ++ insert_coord->unit_pos -= ++ shift->part_units; ++ } else if (insert_coord->between == BEFORE_UNIT) { ++ assert("nikita-2089", ++ insert_coord->unit_pos > ++ shift->part_units); ++ insert_coord->unit_pos -= ++ shift->part_units; ++ } ++ ++ assert("nikita-2084", ++ insert_coord->unit_pos + 1); ++ } ++ } ++ return; ++ } ++ ++ /* we shifted to left and there was no enough space for everything */ ++ switch (insert_coord->between) { ++ case AFTER_UNIT: ++ case BEFORE_UNIT: ++ if (shift->real_stop.item_pos == insert_coord->item_pos) ++ insert_coord->unit_pos -= shift->part_units; ++ case AFTER_ITEM: ++ coord_add_item_pos(insert_coord, -removed); ++ break; ++ default: ++ impossible("nikita-2087", "not ready"); ++ } ++ assert("nikita-2085", insert_coord->unit_pos + 1); ++} ++ ++static int call_shift_hooks(struct shift_params *shift) ++{ ++ unsigned i, shifted; ++ coord_t coord; ++ item_plugin *iplug; ++ ++ assert("vs-275", !node_is_empty(shift->target)); ++ ++ /* number of items shift touches */ ++ shifted = ++ shift->entire + (shift->merging_units ? 1 : 0) + ++ (shift->part_units ? 1 : 0); ++ ++ if (shift->pend == SHIFT_LEFT) { ++ /* moved items are at the end */ ++ coord_init_last_unit(&coord, shift->target); ++ coord.unit_pos = 0; ++ ++ assert("vs-279", shift->pend == 1); ++ for (i = 0; i < shifted; i++) { ++ unsigned from, count; ++ ++ iplug = item_plugin_by_coord(&coord); ++ if (i == 0 && shift->part_units) { ++ assert("vs-277", ++ coord_num_units(&coord) == ++ shift->part_units); ++ count = shift->part_units; ++ from = 0; ++ } else if (i == shifted - 1 && shift->merging_units) { ++ count = shift->merging_units; ++ from = coord_num_units(&coord) - count; ++ } else { ++ count = coord_num_units(&coord); ++ from = 0; ++ } ++ ++ if (iplug->b.shift_hook) { ++ iplug->b.shift_hook(&coord, from, count, ++ shift->wish_stop.node); ++ } ++ coord_add_item_pos(&coord, -shift->pend); ++ } ++ } else { ++ /* moved items are at the beginning */ ++ coord_init_first_unit(&coord, shift->target); ++ ++ assert("vs-278", shift->pend == -1); ++ for (i = 0; i < shifted; i++) { ++ unsigned from, count; ++ ++ iplug = item_plugin_by_coord(&coord); ++ if (i == 0 && shift->part_units) { ++ assert("vs-277", ++ coord_num_units(&coord) == ++ shift->part_units); ++ count = coord_num_units(&coord); ++ from = 0; ++ } else if (i == shifted - 1 && shift->merging_units) { ++ count = shift->merging_units; ++ from = 0; ++ } else { ++ count = coord_num_units(&coord); ++ from = 0; ++ } ++ ++ if (iplug->b.shift_hook) { ++ iplug->b.shift_hook(&coord, from, count, ++ shift->wish_stop.node); ++ } ++ coord_add_item_pos(&coord, -shift->pend); ++ } ++ } ++ ++ return 0; ++} ++ ++/* shift to left is completed. Return 1 if unit @old was moved to left neighbor */ ++static int ++unit_moved_left(const struct shift_params *shift, const coord_t * old) ++{ ++ assert("vs-944", shift->real_stop.node == old->node); ++ ++ if (shift->real_stop.item_pos < old->item_pos) ++ return 0; ++ if (shift->real_stop.item_pos == old->item_pos) { ++ if (shift->real_stop.unit_pos < old->unit_pos) ++ return 0; ++ } ++ return 1; ++} ++ ++/* shift to right is completed. Return 1 if unit @old was moved to right ++ neighbor */ ++static int ++unit_moved_right(const struct shift_params *shift, const coord_t * old) ++{ ++ assert("vs-944", shift->real_stop.node == old->node); ++ ++ if (shift->real_stop.item_pos > old->item_pos) ++ return 0; ++ if (shift->real_stop.item_pos == old->item_pos) { ++ if (shift->real_stop.unit_pos > old->unit_pos) ++ return 0; ++ } ++ return 1; ++} ++ ++/* coord @old was set in node from which shift was performed. What was shifted ++ is stored in @shift. Update @old correspondingly to performed shift */ ++static coord_t *adjust_coord2(const struct shift_params *shift, ++ const coord_t * old, coord_t * new) ++{ ++ coord_clear_iplug(new); ++ new->between = old->between; ++ ++ coord_clear_iplug(new); ++ if (old->node == shift->target) { ++ if (shift->pend == SHIFT_LEFT) { ++ /* coord which is set inside of left neighbor does not ++ change during shift to left */ ++ coord_dup(new, old); ++ return new; ++ } ++ new->node = old->node; ++ coord_set_item_pos(new, ++ old->item_pos + shift->entire + ++ (shift->part_units ? 1 : 0)); ++ new->unit_pos = old->unit_pos; ++ if (old->item_pos == 0 && shift->merging_units) ++ new->unit_pos += shift->merging_units; ++ return new; ++ } ++ ++ assert("vs-977", old->node == shift->wish_stop.node); ++ if (shift->pend == SHIFT_LEFT) { ++ if (unit_moved_left(shift, old)) { ++ /* unit @old moved to left neighbor. Calculate its ++ coordinate there */ ++ new->node = shift->target; ++ coord_set_item_pos(new, ++ node_num_items(shift->target) - ++ shift->entire - ++ (shift->part_units ? 1 : 0) + ++ old->item_pos); ++ ++ new->unit_pos = old->unit_pos; ++ if (shift->merging_units) { ++ coord_dec_item_pos(new); ++ if (old->item_pos == 0) { ++ /* unit_pos only changes if item got ++ merged */ ++ new->unit_pos = ++ coord_num_units(new) - ++ (shift->merging_units - ++ old->unit_pos); ++ } ++ } ++ } else { ++ /* unit @old did not move to left neighbor. ++ ++ Use _nocheck, because @old is outside of its node. ++ */ ++ coord_dup_nocheck(new, old); ++ coord_add_item_pos(new, ++ -shift->u.future_first.item_pos); ++ if (new->item_pos == 0) ++ new->unit_pos -= shift->u.future_first.unit_pos; ++ } ++ } else { ++ if (unit_moved_right(shift, old)) { ++ /* unit @old moved to right neighbor */ ++ new->node = shift->target; ++ coord_set_item_pos(new, ++ old->item_pos - ++ shift->real_stop.item_pos); ++ if (new->item_pos == 0) { ++ /* unit @old might change unit pos */ ++ coord_set_item_pos(new, ++ old->unit_pos - ++ shift->real_stop.unit_pos); ++ } ++ } else { ++ /* unit @old did not move to right neighbor, therefore ++ it did not change */ ++ coord_dup(new, old); ++ } ++ } ++ coord_set_iplug(new, item_plugin_by_coord(new)); ++ return new; ++} ++ ++/* this is called when shift is completed (something of source node is copied ++ to target and deleted in source) to update all taps set in current ++ context */ ++static void update_taps(const struct shift_params *shift) ++{ ++ tap_t *tap; ++ coord_t new; ++ ++ for_all_taps(tap) { ++ /* update only taps set to nodes participating in shift */ ++ if (tap->coord->node == shift->wish_stop.node ++ || tap->coord->node == shift->target) ++ tap_to_coord(tap, ++ adjust_coord2(shift, tap->coord, &new)); ++ } ++} ++ ++#if REISER4_DEBUG ++ ++struct shift_check { ++ reiser4_key key; ++ __u16 plugin_id; ++ union { ++ __u64 bytes; ++ __u64 entries; ++ void *unused; ++ } u; ++}; ++ ++void *shift_check_prepare(const znode * left, const znode * right) ++{ ++ pos_in_node_t i, nr_items; ++ int mergeable; ++ struct shift_check *data; ++ item_header40 *ih; ++ ++ if (node_is_empty(left) || node_is_empty(right)) ++ mergeable = 0; ++ else { ++ coord_t l, r; ++ ++ coord_init_last_unit(&l, left); ++ coord_init_first_unit(&r, right); ++ mergeable = are_items_mergeable(&l, &r); ++ } ++ nr_items = ++ node40_num_of_items_internal(left) + ++ node40_num_of_items_internal(right) - (mergeable ? 1 : 0); ++ data = ++ kmalloc(sizeof(struct shift_check) * nr_items, ++ reiser4_ctx_gfp_mask_get()); ++ if (data != NULL) { ++ coord_t coord; ++ pos_in_node_t item_pos; ++ ++ coord_init_first_unit(&coord, left); ++ i = 0; ++ ++ for (item_pos = 0; ++ item_pos < node40_num_of_items_internal(left); ++ item_pos++) { ++ ++ coord_set_item_pos(&coord, item_pos); ++ ih = node40_ih_at_coord(&coord); ++ ++ data[i].key = ih->key; ++ data[i].plugin_id = le16_to_cpu(get_unaligned(&ih->plugin_id)); ++ switch (data[i].plugin_id) { ++ case CTAIL_ID: ++ case FORMATTING_ID: ++ data[i].u.bytes = coord_num_units(&coord); ++ break; ++ case EXTENT_POINTER_ID: ++ data[i].u.bytes = ++ reiser4_extent_size(&coord, ++ coord_num_units(&coord)); ++ break; ++ case COMPOUND_DIR_ID: ++ data[i].u.entries = coord_num_units(&coord); ++ break; ++ default: ++ data[i].u.unused = NULL; ++ break; ++ } ++ i++; ++ } ++ ++ coord_init_first_unit(&coord, right); ++ ++ if (mergeable) { ++ assert("vs-1609", i != 0); ++ ++ ih = node40_ih_at_coord(&coord); ++ ++ assert("vs-1589", ++ data[i - 1].plugin_id == ++ le16_to_cpu(get_unaligned(&ih->plugin_id))); ++ switch (data[i - 1].plugin_id) { ++ case CTAIL_ID: ++ case FORMATTING_ID: ++ data[i - 1].u.bytes += coord_num_units(&coord); ++ break; ++ case EXTENT_POINTER_ID: ++ data[i - 1].u.bytes += ++ reiser4_extent_size(&coord, ++ coord_num_units(&coord)); ++ break; ++ case COMPOUND_DIR_ID: ++ data[i - 1].u.entries += ++ coord_num_units(&coord); ++ break; ++ default: ++ impossible("vs-1605", "wrong mergeable item"); ++ break; ++ } ++ item_pos = 1; ++ } else ++ item_pos = 0; ++ for (; item_pos < node40_num_of_items_internal(right); ++ item_pos++) { ++ ++ assert("vs-1604", i < nr_items); ++ coord_set_item_pos(&coord, item_pos); ++ ih = node40_ih_at_coord(&coord); ++ ++ data[i].key = ih->key; ++ data[i].plugin_id = le16_to_cpu(get_unaligned(&ih->plugin_id)); ++ switch (data[i].plugin_id) { ++ case CTAIL_ID: ++ case FORMATTING_ID: ++ data[i].u.bytes = coord_num_units(&coord); ++ break; ++ case EXTENT_POINTER_ID: ++ data[i].u.bytes = ++ reiser4_extent_size(&coord, ++ coord_num_units(&coord)); ++ break; ++ case COMPOUND_DIR_ID: ++ data[i].u.entries = coord_num_units(&coord); ++ break; ++ default: ++ data[i].u.unused = NULL; ++ break; ++ } ++ i++; ++ } ++ assert("vs-1606", i == nr_items); ++ } ++ return data; ++} ++ ++void shift_check(void *vp, const znode * left, const znode * right) ++{ ++ pos_in_node_t i, nr_items; ++ coord_t coord; ++ __u64 last_bytes; ++ int mergeable; ++ item_header40 *ih; ++ pos_in_node_t item_pos; ++ struct shift_check *data; ++ ++ data = (struct shift_check *)vp; ++ ++ if (data == NULL) ++ return; ++ ++ if (node_is_empty(left) || node_is_empty(right)) ++ mergeable = 0; ++ else { ++ coord_t l, r; ++ ++ coord_init_last_unit(&l, left); ++ coord_init_first_unit(&r, right); ++ mergeable = are_items_mergeable(&l, &r); ++ } ++ ++ nr_items = ++ node40_num_of_items_internal(left) + ++ node40_num_of_items_internal(right) - (mergeable ? 1 : 0); ++ ++ i = 0; ++ last_bytes = 0; ++ ++ coord_init_first_unit(&coord, left); ++ ++ for (item_pos = 0; item_pos < node40_num_of_items_internal(left); ++ item_pos++) { ++ ++ coord_set_item_pos(&coord, item_pos); ++ ih = node40_ih_at_coord(&coord); ++ ++ assert("vs-1611", i == item_pos); ++ assert("vs-1590", keyeq(&ih->key, &data[i].key)); ++ assert("vs-1591", ++ le16_to_cpu(get_unaligned(&ih->plugin_id)) == data[i].plugin_id); ++ if ((i < (node40_num_of_items_internal(left) - 1)) ++ || !mergeable) { ++ switch (data[i].plugin_id) { ++ case CTAIL_ID: ++ case FORMATTING_ID: ++ assert("vs-1592", ++ data[i].u.bytes == ++ coord_num_units(&coord)); ++ break; ++ case EXTENT_POINTER_ID: ++ assert("vs-1593", ++ data[i].u.bytes == ++ reiser4_extent_size(&coord, ++ coord_num_units ++ (&coord))); ++ break; ++ case COMPOUND_DIR_ID: ++ assert("vs-1594", ++ data[i].u.entries == ++ coord_num_units(&coord)); ++ break; ++ default: ++ break; ++ } ++ } ++ if (item_pos == (node40_num_of_items_internal(left) - 1) ++ && mergeable) { ++ switch (data[i].plugin_id) { ++ case CTAIL_ID: ++ case FORMATTING_ID: ++ last_bytes = coord_num_units(&coord); ++ break; ++ case EXTENT_POINTER_ID: ++ last_bytes = ++ reiser4_extent_size(&coord, ++ coord_num_units(&coord)); ++ break; ++ case COMPOUND_DIR_ID: ++ last_bytes = coord_num_units(&coord); ++ break; ++ default: ++ impossible("vs-1595", "wrong mergeable item"); ++ break; ++ } ++ } ++ i++; ++ } ++ ++ coord_init_first_unit(&coord, right); ++ if (mergeable) { ++ ih = node40_ih_at_coord(&coord); ++ ++ assert("vs-1589", ++ data[i - 1].plugin_id == le16_to_cpu(get_unaligned(&ih->plugin_id))); ++ assert("vs-1608", last_bytes != 0); ++ switch (data[i - 1].plugin_id) { ++ case CTAIL_ID: ++ case FORMATTING_ID: ++ assert("vs-1596", ++ data[i - 1].u.bytes == ++ last_bytes + coord_num_units(&coord)); ++ break; ++ ++ case EXTENT_POINTER_ID: ++ assert("vs-1597", ++ data[i - 1].u.bytes == ++ last_bytes + reiser4_extent_size(&coord, ++ coord_num_units ++ (&coord))); ++ break; ++ ++ case COMPOUND_DIR_ID: ++ assert("vs-1598", ++ data[i - 1].u.bytes == ++ last_bytes + coord_num_units(&coord)); ++ break; ++ default: ++ impossible("vs-1599", "wrong mergeable item"); ++ break; ++ } ++ item_pos = 1; ++ } else ++ item_pos = 0; ++ ++ for (; item_pos < node40_num_of_items_internal(right); item_pos++) { ++ ++ coord_set_item_pos(&coord, item_pos); ++ ih = node40_ih_at_coord(&coord); ++ ++ assert("vs-1612", keyeq(&ih->key, &data[i].key)); ++ assert("vs-1613", ++ le16_to_cpu(get_unaligned(&ih->plugin_id)) == data[i].plugin_id); ++ switch (data[i].plugin_id) { ++ case CTAIL_ID: ++ case FORMATTING_ID: ++ assert("vs-1600", ++ data[i].u.bytes == coord_num_units(&coord)); ++ break; ++ case EXTENT_POINTER_ID: ++ assert("vs-1601", ++ data[i].u.bytes == ++ reiser4_extent_size(&coord, ++ coord_num_units ++ (&coord))); ++ break; ++ case COMPOUND_DIR_ID: ++ assert("vs-1602", ++ data[i].u.entries == coord_num_units(&coord)); ++ break; ++ default: ++ break; ++ } ++ i++; ++ } ++ ++ assert("vs-1603", i == nr_items); ++ kfree(data); ++} ++ ++#endif ++ ++/* plugin->u.node.shift ++ look for description of this method in plugin/node/node.h */ ++int shift_node40(coord_t * from, znode * to, shift_direction pend, int delete_child, /* if @from->node becomes empty - it will be ++ deleted from the tree if this is set to 1 */ ++ int including_stop_coord, carry_plugin_info * info) ++{ ++ struct shift_params shift; ++ int result; ++ znode *left, *right; ++ znode *source; ++ int target_empty; ++ ++ assert("nikita-2161", coord_check(from)); ++ ++ memset(&shift, 0, sizeof(shift)); ++ shift.pend = pend; ++ shift.wish_stop = *from; ++ shift.target = to; ++ ++ assert("nikita-1473", znode_is_write_locked(from->node)); ++ assert("nikita-1474", znode_is_write_locked(to)); ++ ++ source = from->node; ++ ++ /* set @shift.wish_stop to rightmost/leftmost unit among units we want ++ shifted */ ++ if (pend == SHIFT_LEFT) { ++ result = coord_set_to_left(&shift.wish_stop); ++ left = to; ++ right = from->node; ++ } else { ++ result = coord_set_to_right(&shift.wish_stop); ++ left = from->node; ++ right = to; ++ } ++ ++ if (result) { ++ /* move insertion coord even if there is nothing to move */ ++ if (including_stop_coord) { ++ /* move insertion coord (@from) */ ++ if (pend == SHIFT_LEFT) { ++ /* after last item in target node */ ++ coord_init_after_last_item(from, to); ++ } else { ++ /* before first item in target node */ ++ coord_init_before_first_item(from, to); ++ } ++ } ++ ++ if (delete_child && node_is_empty(shift.wish_stop.node)) ++ result = ++ prepare_removal_node40(shift.wish_stop.node, info); ++ else ++ result = 0; ++ /* there is nothing to shift */ ++ assert("nikita-2078", coord_check(from)); ++ return result; ++ } ++ ++ target_empty = node_is_empty(to); ++ ++ /* when first node plugin with item body compression is implemented, ++ this must be changed to call node specific plugin */ ++ ++ /* shift->stop_coord is updated to last unit which really will be ++ shifted */ ++ estimate_shift(&shift, get_current_context()); ++ if (!shift.shift_bytes) { ++ /* we could not shift anything */ ++ assert("nikita-2079", coord_check(from)); ++ return 0; ++ } ++ ++ copy(&shift); ++ ++ /* result value of this is important. It is used by adjust_coord below */ ++ result = delete_copied(&shift); ++ ++ assert("vs-1610", result >= 0); ++ assert("vs-1471", ++ ((reiser4_context *) current->journal_info)->magic == ++ context_magic); ++ ++ /* item which has been moved from one node to another might want to do ++ something on that event. This can be done by item's shift_hook ++ method, which will be now called for every moved items */ ++ call_shift_hooks(&shift); ++ ++ assert("vs-1472", ++ ((reiser4_context *) current->journal_info)->magic == ++ context_magic); ++ ++ update_taps(&shift); ++ ++ assert("vs-1473", ++ ((reiser4_context *) current->journal_info)->magic == ++ context_magic); ++ ++ /* adjust @from pointer in accordance with @including_stop_coord flag ++ and amount of data which was really shifted */ ++ adjust_coord(from, &shift, result, including_stop_coord); ++ ++ if (target_empty) ++ /* ++ * items were shifted into empty node. Update delimiting key. ++ */ ++ result = prepare_for_update(NULL, left, info); ++ ++ /* add update operation to @info, which is the list of operations to ++ be performed on a higher level */ ++ result = prepare_for_update(left, right, info); ++ if (!result && node_is_empty(source) && delete_child) { ++ /* all contents of @from->node is moved to @to and @from->node ++ has to be removed from the tree, so, on higher level we ++ will be removing the pointer to node @from->node */ ++ result = prepare_removal_node40(source, info); ++ } ++ assert("nikita-2080", coord_check(from)); ++ return result ? result : (int)shift.shift_bytes; ++} ++ ++/* plugin->u.node.fast_insert() ++ look for description of this method in plugin/node/node.h */ ++int fast_insert_node40(const coord_t * coord UNUSED_ARG /* node to query */ ) ++{ ++ return 1; ++} ++ ++/* plugin->u.node.fast_paste() ++ look for description of this method in plugin/node/node.h */ ++int fast_paste_node40(const coord_t * coord UNUSED_ARG /* node to query */ ) ++{ ++ return 1; ++} ++ ++/* plugin->u.node.fast_cut() ++ look for description of this method in plugin/node/node.h */ ++int fast_cut_node40(const coord_t * coord UNUSED_ARG /* node to query */ ) ++{ ++ return 1; ++} ++ ++/* plugin->u.node.modify - not defined */ ++ ++/* plugin->u.node.max_item_size */ ++int max_item_size_node40(void) ++{ ++ return reiser4_get_current_sb()->s_blocksize - sizeof(node40_header) - ++ sizeof(item_header40); ++} ++ ++/* plugin->u.node.set_item_plugin */ ++int set_item_plugin_node40(coord_t *coord, item_id id) ++{ ++ item_header40 *ih; ++ ++ ih = node40_ih_at_coord(coord); ++ put_unaligned(cpu_to_le16(id), &ih->plugin_id); ++ coord->iplugid = id; ++ return 0; ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/node/node40.h linux-2.6.30/fs/reiser4/plugin/node/node40.h +--- linux-2.6.30.orig/fs/reiser4/plugin/node/node40.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/node/node40.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,125 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#if !defined( __REISER4_NODE40_H__ ) ++#define __REISER4_NODE40_H__ ++ ++#include "../../forward.h" ++#include "../../dformat.h" ++#include "node.h" ++ ++#include <linux/types.h> ++ ++/* format of node header for 40 node layouts. Keep bloat out of this struct. */ ++typedef struct node40_header { ++ /* identifier of node plugin. Must be located at the very beginning ++ of a node. */ ++ common_node_header common_header; /* this is 16 bits */ ++ /* number of items. Should be first element in the node header, ++ because we haven't yet finally decided whether it shouldn't go into ++ common_header. ++ */ ++/* NIKITA-FIXME-HANS: Create a macro such that if there is only one ++ * node format at compile time, and it is this one, accesses do not function dereference when ++ * accessing these fields (and otherwise they do). Probably 80% of users will only have one node format at a time throughout the life of reiser4. */ ++ d16 nr_items; ++ /* free space in node measured in bytes */ ++ d16 free_space; ++ /* offset to start of free space in node */ ++ d16 free_space_start; ++ /* for reiser4_fsck. When information about what is a free ++ block is corrupted, and we try to recover everything even ++ if marked as freed, then old versions of data may ++ duplicate newer versions, and this field allows us to ++ restore the newer version. Also useful for when users ++ who don't have the new trashcan installed on their linux distro ++ delete the wrong files and send us desperate emails ++ offering $25 for them back. */ ++ ++ /* magic field we need to tell formatted nodes NIKITA-FIXME-HANS: improve this comment */ ++ d32 magic; ++ /* flushstamp is made of mk_id and write_counter. mk_id is an ++ id generated randomly at mkreiserfs time. So we can just ++ skip all nodes with different mk_id. write_counter is d64 ++ incrementing counter of writes on disk. It is used for ++ choosing the newest data at fsck time. NIKITA-FIXME-HANS: why was field name changed but not comment? */ ++ ++ d32 mkfs_id; ++ d64 flush_id; ++ /* node flags to be used by fsck (reiser4ck or reiser4fsck?) ++ and repacker NIKITA-FIXME-HANS: say more or reference elsewhere that says more */ ++ d16 flags; ++ ++ /* 1 is leaf level, 2 is twig level, root is the numerically ++ largest level */ ++ d8 level; ++ ++ d8 pad; ++} PACKED node40_header; ++ ++/* item headers are not standard across all node layouts, pass ++ pos_in_node to functions instead */ ++typedef struct item_header40 { ++ /* key of item */ ++ /* 0 */ reiser4_key key; ++ /* offset from start of a node measured in 8-byte chunks */ ++ /* 24 */ d16 offset; ++ /* 26 */ d16 flags; ++ /* 28 */ d16 plugin_id; ++} PACKED item_header40; ++ ++size_t item_overhead_node40(const znode * node, flow_t * aflow); ++size_t free_space_node40(znode * node); ++node_search_result lookup_node40(znode * node, const reiser4_key * key, ++ lookup_bias bias, coord_t * coord); ++int num_of_items_node40(const znode * node); ++char *item_by_coord_node40(const coord_t * coord); ++int length_by_coord_node40(const coord_t * coord); ++item_plugin *plugin_by_coord_node40(const coord_t * coord); ++reiser4_key *key_at_node40(const coord_t * coord, reiser4_key * key); ++size_t estimate_node40(znode * node); ++int check_node40(const znode * node, __u32 flags, const char **error); ++int parse_node40(znode * node); ++int init_node40(znode * node); ++#ifdef GUESS_EXISTS ++int guess_node40(const znode * node); ++#endif ++void change_item_size_node40(coord_t * coord, int by); ++int create_item_node40(coord_t * target, const reiser4_key * key, ++ reiser4_item_data * data, carry_plugin_info * info); ++void update_item_key_node40(coord_t * target, const reiser4_key * key, ++ carry_plugin_info * info); ++int kill_node40(struct carry_kill_data *, carry_plugin_info *); ++int cut_node40(struct carry_cut_data *, carry_plugin_info *); ++int shift_node40(coord_t * from, znode * to, shift_direction pend, ++ /* if @from->node becomes ++ empty - it will be deleted from ++ the tree if this is set to 1 ++ */ ++ int delete_child, int including_stop_coord, ++ carry_plugin_info * info); ++ ++int fast_insert_node40(const coord_t * coord); ++int fast_paste_node40(const coord_t * coord); ++int fast_cut_node40(const coord_t * coord); ++int max_item_size_node40(void); ++int prepare_removal_node40(znode * empty, carry_plugin_info * info); ++int set_item_plugin_node40(coord_t * coord, item_id id); ++int shrink_item_node40(coord_t * coord, int delta); ++ ++#if REISER4_DEBUG ++void *shift_check_prepare(const znode *left, const znode *right); ++void shift_check(void *vp, const znode *left, const znode *right); ++#endif ++ ++/* __REISER4_NODE40_H__ */ ++#endif ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/node/node.c linux-2.6.30/fs/reiser4/plugin/node/node.c +--- linux-2.6.30.orig/fs/reiser4/plugin/node/node.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/node/node.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,131 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Node plugin interface. ++ ++ Description: The tree provides the abstraction of flows, which it ++ internally fragments into items which it stores in nodes. ++ ++ A key_atom is a piece of data bound to a single key. ++ ++ For reasonable space efficiency to be achieved it is often ++ necessary to store key_atoms in the nodes in the form of items, where ++ an item is a sequence of key_atoms of the same or similar type. It is ++ more space-efficient, because the item can implement (very) ++ efficient compression of key_atom's bodies using internal knowledge ++ about their semantics, and it can often avoid having a key for each ++ key_atom. Each type of item has specific operations implemented by its ++ item handler (see balance.c). ++ ++ Rationale: the rest of the code (specifically balancing routines) ++ accesses leaf level nodes through this interface. This way we can ++ implement various block layouts and even combine various layouts ++ within the same tree. Balancing/allocating algorithms should not ++ care about peculiarities of splitting/merging specific item types, ++ but rather should leave that to the item's item handler. ++ ++ Items, including those that provide the abstraction of flows, have ++ the property that if you move them in part or in whole to another ++ node, the balancing code invokes their is_left_mergeable() ++ item_operation to determine if they are mergeable with their new ++ neighbor in the node you have moved them to. For some items the ++ is_left_mergeable() function always returns null. ++ ++ When moving the bodies of items from one node to another: ++ ++ if a partial item is shifted to another node the balancing code invokes ++ an item handler method to handle the item splitting. ++ ++ if the balancing code needs to merge with an item in the node it ++ is shifting to, it will invoke an item handler method to handle ++ the item merging. ++ ++ if it needs to move whole item bodies unchanged, the balancing code uses xmemcpy() ++ adjusting the item headers after the move is done using the node handler. ++*/ ++ ++#include "../../forward.h" ++#include "../../debug.h" ++#include "../../key.h" ++#include "../../coord.h" ++#include "../plugin_header.h" ++#include "../item/item.h" ++#include "node.h" ++#include "../plugin.h" ++#include "../../znode.h" ++#include "../../tree.h" ++#include "../../super.h" ++#include "../../reiser4.h" ++ ++/** ++ * leftmost_key_in_node - get the smallest key in node ++ * @node: ++ * @key: store result here ++ * ++ * Stores the leftmost key of @node in @key. ++ */ ++reiser4_key *leftmost_key_in_node(const znode *node, reiser4_key *key) ++{ ++ assert("nikita-1634", node != NULL); ++ assert("nikita-1635", key != NULL); ++ ++ if (!node_is_empty(node)) { ++ coord_t first_item; ++ ++ coord_init_first_unit(&first_item, (znode *) node); ++ item_key_by_coord(&first_item, key); ++ } else ++ *key = *reiser4_max_key(); ++ return key; ++} ++ ++node_plugin node_plugins[LAST_NODE_ID] = { ++ [NODE40_ID] = { ++ .h = { ++ .type_id = REISER4_NODE_PLUGIN_TYPE, ++ .id = NODE40_ID, ++ .pops = NULL, ++ .label = "unified", ++ .desc = "unified node layout", ++ .linkage = {NULL, NULL} ++ }, ++ .item_overhead = item_overhead_node40, ++ .free_space = free_space_node40, ++ .lookup = lookup_node40, ++ .num_of_items = num_of_items_node40, ++ .item_by_coord = item_by_coord_node40, ++ .length_by_coord = length_by_coord_node40, ++ .plugin_by_coord = plugin_by_coord_node40, ++ .key_at = key_at_node40, ++ .estimate = estimate_node40, ++ .check = check_node40, ++ .parse = parse_node40, ++ .init = init_node40, ++#ifdef GUESS_EXISTS ++ .guess = guess_node40, ++#endif ++ .change_item_size = change_item_size_node40, ++ .create_item = create_item_node40, ++ .update_item_key = update_item_key_node40, ++ .cut_and_kill = kill_node40, ++ .cut = cut_node40, ++ .shift = shift_node40, ++ .shrink_item = shrink_item_node40, ++ .fast_insert = fast_insert_node40, ++ .fast_paste = fast_paste_node40, ++ .fast_cut = fast_cut_node40, ++ .max_item_size = max_item_size_node40, ++ .prepare_removal = prepare_removal_node40, ++ .set_item_plugin = set_item_plugin_node40 ++ } ++}; ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/node/node.h linux-2.6.30/fs/reiser4/plugin/node/node.h +--- linux-2.6.30.orig/fs/reiser4/plugin/node/node.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/node/node.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,272 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* We need a definition of the default node layout here. */ ++ ++/* Generally speaking, it is best to have free space in the middle of the ++ node so that two sets of things can grow towards it, and to have the ++ item bodies on the left so that the last one of them grows into free ++ space. We optimize for the case where we append new items to the end ++ of the node, or grow the last item, because it hurts nothing to so ++ optimize and it is a common special case to do massive insertions in ++ increasing key order (and one of cases more likely to have a real user ++ notice the delay time for). ++ ++ formatted leaf default layout: (leaf1) ++ ++ |node header:item bodies:free space:key + pluginid + item offset| ++ ++ We grow towards the middle, optimizing layout for the case where we ++ append new items to the end of the node. The node header is fixed ++ length. Keys, and item offsets plus pluginids for the items ++ corresponding to them are in increasing key order, and are fixed ++ length. Item offsets are relative to start of node (16 bits creating ++ a node size limit of 64k, 12 bits might be a better choice....). Item ++ bodies are in decreasing key order. Item bodies have a variable size. ++ There is a one to one to one mapping of keys to item offsets to item ++ bodies. Item offsets consist of pointers to the zeroth byte of the ++ item body. Item length equals the start of the next item minus the ++ start of this item, except the zeroth item whose length equals the end ++ of the node minus the start of that item (plus a byte). In other ++ words, the item length is not recorded anywhere, and it does not need ++ to be since it is computable. ++ ++ Leaf variable length items and keys layout : (lvar) ++ ++ |node header:key offset + item offset + pluginid triplets:free space:key bodies:item bodies| ++ ++ We grow towards the middle, optimizing layout for the case where we ++ append new items to the end of the node. The node header is fixed ++ length. Keys and item offsets for the items corresponding to them are ++ in increasing key order, and keys are variable length. Item offsets ++ are relative to start of node (16 bits). Item bodies are in ++ decreasing key order. Item bodies have a variable size. There is a ++ one to one to one mapping of keys to item offsets to item bodies. ++ Item offsets consist of pointers to the zeroth byte of the item body. ++ Item length equals the start of the next item's key minus the start of ++ this item, except the zeroth item whose length equals the end of the ++ node minus the start of that item (plus a byte). ++ ++ leaf compressed keys layout: (lcomp) ++ ++ |node header:key offset + key inherit + item offset pairs:free space:key bodies:item bodies| ++ ++ We grow towards the middle, optimizing layout for the case where we ++ append new items to the end of the node. The node header is fixed ++ length. Keys and item offsets for the items corresponding to them are ++ in increasing key order, and keys are variable length. The "key ++ inherit" field indicates how much of the key prefix is identical to ++ the previous key (stem compression as described in "Managing ++ Gigabytes" is used). key_inherit is a one byte integer. The ++ intra-node searches performed through this layout are linear searches, ++ and this is theorized to not hurt performance much due to the high ++ cost of processor stalls on modern CPUs, and the small number of keys ++ in a single node. Item offsets are relative to start of node (16 ++ bits). Item bodies are in decreasing key order. Item bodies have a ++ variable size. There is a one to one to one mapping of keys to item ++ offsets to item bodies. Item offsets consist of pointers to the ++ zeroth byte of the item body. Item length equals the start of the ++ next item minus the start of this item, except the zeroth item whose ++ length equals the end of the node minus the start of that item (plus a ++ byte). In other words, item length and key length is not recorded ++ anywhere, and it does not need to be since it is computable. ++ ++ internal node default layout: (idef1) ++ ++ just like ldef1 except that item bodies are either blocknrs of ++ children or extents, and moving them may require updating parent ++ pointers in the nodes that they point to. ++*/ ++ ++/* There is an inherent 3-way tradeoff between optimizing and ++ exchanging disks between different architectures and code ++ complexity. This is optimal and simple and inexchangeable. ++ Someone else can do the code for exchanging disks and make it ++ complex. It would not be that hard. Using other than the PAGE_SIZE ++ might be suboptimal. ++*/ ++ ++#if !defined( __REISER4_NODE_H__ ) ++#define __REISER4_NODE_H__ ++ ++#define LEAF40_NODE_SIZE PAGE_CACHE_SIZE ++ ++#include "../../dformat.h" ++#include "../plugin_header.h" ++ ++#include <linux/types.h> ++ ++typedef enum { ++ NS_FOUND = 0, ++ NS_NOT_FOUND = -ENOENT ++} node_search_result; ++ ++/* Maximal possible space overhead for creation of new item in a node */ ++#define REISER4_NODE_MAX_OVERHEAD ( sizeof( reiser4_key ) + 32 ) ++ ++typedef enum { ++ REISER4_NODE_DKEYS = (1 << 0), ++ REISER4_NODE_TREE_STABLE = (1 << 1) ++} reiser4_node_check_flag; ++ ++/* cut and cut_and_kill have too long list of parameters. This structure is just to safe some space on stack */ ++struct cut_list { ++ coord_t *from; ++ coord_t *to; ++ const reiser4_key *from_key; ++ const reiser4_key *to_key; ++ reiser4_key *smallest_removed; ++ carry_plugin_info *info; ++ __u32 flags; ++ struct inode *inode; /* this is to pass list of eflushed jnodes down to extent_kill_hook */ ++ lock_handle *left; ++ lock_handle *right; ++}; ++ ++struct carry_cut_data; ++struct carry_kill_data; ++ ++/* The responsibility of the node plugin is to store and give access ++ to the sequence of items within the node. */ ++typedef struct node_plugin { ++ /* generic plugin fields */ ++ plugin_header h; ++ ++ /* calculates the amount of space that will be required to store an ++ item which is in addition to the space consumed by the item body. ++ (the space consumed by the item body can be gotten by calling ++ item->estimate) */ ++ size_t(*item_overhead) (const znode * node, flow_t * f); ++ ++ /* returns free space by looking into node (i.e., without using ++ znode->free_space). */ ++ size_t(*free_space) (znode * node); ++ /* search within the node for the one item which might ++ contain the key, invoking item->search_within to search within ++ that item to see if it is in there */ ++ node_search_result(*lookup) (znode * node, const reiser4_key * key, ++ lookup_bias bias, coord_t * coord); ++ /* number of items in node */ ++ int (*num_of_items) (const znode * node); ++ ++ /* store information about item in @coord in @data */ ++ /* break into several node ops, don't add any more uses of this before doing so */ ++ /*int ( *item_at )( const coord_t *coord, reiser4_item_data *data ); */ ++ char *(*item_by_coord) (const coord_t * coord); ++ int (*length_by_coord) (const coord_t * coord); ++ item_plugin *(*plugin_by_coord) (const coord_t * coord); ++ ++ /* store item key in @key */ ++ reiser4_key *(*key_at) (const coord_t * coord, reiser4_key * key); ++ /* conservatively estimate whether unit of what size can fit ++ into node. This estimation should be performed without ++ actually looking into the node's content (free space is saved in ++ znode). */ ++ size_t(*estimate) (znode * node); ++ ++ /* performs every consistency check the node plugin author could ++ imagine. Optional. */ ++ int (*check) (const znode * node, __u32 flags, const char **error); ++ ++ /* Called when node is read into memory and node plugin is ++ already detected. This should read some data into znode (like free ++ space counter) and, optionally, check data consistency. ++ */ ++ int (*parse) (znode * node); ++ /* This method is called on a new node to initialise plugin specific ++ data (header, etc.) */ ++ int (*init) (znode * node); ++ /* Check whether @node content conforms to this plugin format. ++ Probably only useful after support for old V3.x formats is added. ++ Uncomment after 4.0 only. ++ */ ++ /* int ( *guess )( const znode *node ); */ ++#if REISER4_DEBUG ++ void (*print) (const char *prefix, const znode * node, __u32 flags); ++#endif ++ /* change size of @item by @by bytes. @item->node has enough free ++ space. When @by > 0 - free space is appended to end of item. When ++ @by < 0 - item is truncated - it is assumed that last @by bytes if ++ the item are freed already */ ++ void (*change_item_size) (coord_t * item, int by); ++ ++ /* create new item @length bytes long in coord @target */ ++ int (*create_item) (coord_t * target, const reiser4_key * key, ++ reiser4_item_data * data, carry_plugin_info * info); ++ ++ /* update key of item. */ ++ void (*update_item_key) (coord_t * target, const reiser4_key * key, ++ carry_plugin_info * info); ++ ++ int (*cut_and_kill) (struct carry_kill_data *, carry_plugin_info *); ++ int (*cut) (struct carry_cut_data *, carry_plugin_info *); ++ ++ /* ++ * shrink item pointed to by @coord by @delta bytes. ++ */ ++ int (*shrink_item) (coord_t * coord, int delta); ++ ++ /* copy as much as possible but not more than up to @stop from ++ @stop->node to @target. If (pend == append) then data from beginning of ++ @stop->node are copied to the end of @target. If (pend == prepend) then ++ data from the end of @stop->node are copied to the beginning of ++ @target. Copied data are removed from @stop->node. Information ++ about what to do on upper level is stored in @todo */ ++ int (*shift) (coord_t * stop, znode * target, shift_direction pend, ++ int delete_node, int including_insert_coord, ++ carry_plugin_info * info); ++ /* return true if this node allows skip carry() in some situations ++ (see fs/reiser4/tree.c:insert_by_coord()). Reiser3.x format ++ emulation doesn't. ++ ++ This will speedup insertions that doesn't require updates to the ++ parent, by bypassing initialisation of carry() structures. It's ++ believed that majority of insertions will fit there. ++ ++ */ ++ int (*fast_insert) (const coord_t * coord); ++ int (*fast_paste) (const coord_t * coord); ++ int (*fast_cut) (const coord_t * coord); ++ /* this limits max size of item which can be inserted into a node and ++ number of bytes item in a node may be appended with */ ++ int (*max_item_size) (void); ++ int (*prepare_removal) (znode * empty, carry_plugin_info * info); ++ /* change plugin id of items which are in a node already. Currently it is Used in tail conversion for regular ++ * files */ ++ int (*set_item_plugin) (coord_t * coord, item_id); ++} node_plugin; ++ ++typedef enum { ++ /* standard unified node layout used for both leaf and internal ++ nodes */ ++ NODE40_ID, ++ LAST_NODE_ID ++} reiser4_node_id; ++ ++extern reiser4_key *leftmost_key_in_node(const znode * node, reiser4_key * key); ++#if REISER4_DEBUG ++extern void print_node_content(const char *prefix, const znode * node, ++ __u32 flags); ++#endif ++ ++extern void indent_znode(const znode * node); ++ ++typedef struct common_node_header { ++ /* ++ * identifier of node plugin. Must be located at the very beginning of ++ * a node. ++ */ ++ __le16 plugin_id; ++} common_node_header; ++ ++/* __REISER4_NODE_H__ */ ++#endif ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/object.c linux-2.6.30/fs/reiser4/plugin/object.c +--- linux-2.6.30.orig/fs/reiser4/plugin/object.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/object.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,531 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* ++ * Examples of object plugins: file, directory, symlink, special file. ++ * ++ * Plugins associated with inode: ++ * ++ * Plugin of inode is plugin referenced by plugin-id field of on-disk ++ * stat-data. How we store this plugin in in-core inode is not ++ * important. Currently pointers are used, another variant is to store offsets ++ * and do array lookup on each access. ++ * ++ * Now, each inode has one selected plugin: object plugin that ++ * determines what type of file this object is: directory, regular etc. ++ * ++ * This main plugin can use other plugins that are thus subordinated to ++ * it. Directory instance of object plugin uses hash; regular file ++ * instance uses tail policy plugin. ++ * ++ * Object plugin is either taken from id in stat-data or guessed from ++ * i_mode bits. Once it is established we ask it to install its ++ * subordinate plugins, by looking again in stat-data or inheriting them ++ * from parent. ++ * ++ * How new inode is initialized during ->read_inode(): ++ * 1 read stat-data and initialize inode fields: i_size, i_mode, ++ * i_generation, capabilities etc. ++ * 2 read plugin id from stat data or try to guess plugin id ++ * from inode->i_mode bits if plugin id is missing. ++ * 3 Call ->init_inode() method of stat-data plugin to initialise inode fields. ++ * ++ * NIKITA-FIXME-HANS: can you say a little about 1 being done before 3? What ++ * if stat data does contain i_size, etc., due to it being an unusual plugin? ++ * ++ * 4 Call ->activate() method of object's plugin. Plugin is either read from ++ * from stat-data or guessed from mode bits ++ * 5 Call ->inherit() method of object plugin to inherit as yet un initialized ++ * plugins from parent. ++ * ++ * Easy induction proves that on last step all plugins of inode would be ++ * initialized. ++ * ++ * When creating new object: ++ * 1 obtain object plugin id (see next period) ++ * NIKITA-FIXME-HANS: period? ++ * 2 ->install() this plugin ++ * 3 ->inherit() the rest from the parent ++ * ++ * We need some examples of creating an object with default and non-default ++ * plugin ids. Nikita, please create them. ++ */ ++ ++#include "../inode.h" ++ ++static int _bugop(void) ++{ ++ BUG_ON(1); ++ return 0; ++} ++ ++#define bugop ((void *)_bugop) ++ ++static int _dummyop(void) ++{ ++ return 0; ++} ++ ++#define dummyop ((void *)_dummyop) ++ ++static int change_file(struct inode *inode, ++ reiser4_plugin * plugin, ++ pset_member memb) ++{ ++ /* cannot change object plugin of already existing object */ ++ if (memb == PSET_FILE) ++ return RETERR(-EINVAL); ++ ++ /* Change PSET_CREATE */ ++ return aset_set_unsafe(&reiser4_inode_data(inode)->pset, memb, plugin); ++} ++ ++static reiser4_plugin_ops file_plugin_ops = { ++ .change = change_file ++}; ++ ++static struct inode_operations null_i_ops = {.create = NULL}; ++static struct file_operations null_f_ops = {.owner = NULL}; ++static struct address_space_operations null_a_ops = {.writepage = NULL}; ++ ++/* VFS methods for regular files */ ++static struct inode_operations regular_file_i_ops = { ++ .permission = reiser4_permission_common, ++ .setattr = reiser4_setattr, ++ .getattr = reiser4_getattr_common ++}; ++static struct file_operations regular_file_f_ops = { ++ .llseek = generic_file_llseek, ++ .read = reiser4_read_careful, ++ .write = reiser4_write_careful, ++ .aio_read = generic_file_aio_read, ++ .ioctl = reiser4_ioctl_careful, ++ .mmap = reiser4_mmap_careful, ++ .open = reiser4_open_careful, ++ .release = reiser4_release_careful, ++ .fsync = reiser4_sync_file_common, ++ .splice_read = generic_file_splice_read, ++ .splice_write = generic_file_splice_write ++}; ++static struct address_space_operations regular_file_a_ops = { ++ .writepage = reiser4_writepage, ++ .readpage = reiser4_readpage, ++ .sync_page = block_sync_page, ++ .writepages = reiser4_writepages, ++ .set_page_dirty = reiser4_set_page_dirty, ++ .readpages = reiser4_readpages, ++ .write_begin = reiser4_write_begin_careful, ++ .write_end = reiser4_write_end_careful, ++ .bmap = reiser4_bmap_careful, ++ .invalidatepage = reiser4_invalidatepage, ++ .releasepage = reiser4_releasepage ++}; ++ ++/* VFS methods for symlink files */ ++static struct inode_operations symlink_file_i_ops = { ++ .readlink = generic_readlink, ++ .follow_link = reiser4_follow_link_common, ++ .permission = reiser4_permission_common, ++ .setattr = reiser4_setattr_common, ++ .getattr = reiser4_getattr_common ++}; ++ ++/* VFS methods for special files */ ++static struct inode_operations special_file_i_ops = { ++ .permission = reiser4_permission_common, ++ .setattr = reiser4_setattr_common, ++ .getattr = reiser4_getattr_common ++}; ++ ++/* VFS methods for directories */ ++static struct inode_operations directory_i_ops = { ++ .create = reiser4_create_common, ++ .lookup = reiser4_lookup_common, ++ .link = reiser4_link_common, ++ .unlink = reiser4_unlink_common, ++ .symlink = reiser4_symlink_common, ++ .mkdir = reiser4_mkdir_common, ++ .rmdir = reiser4_unlink_common, ++ .mknod = reiser4_mknod_common, ++ .rename = reiser4_rename_common, ++ .permission = reiser4_permission_common, ++ .setattr = reiser4_setattr_common, ++ .getattr = reiser4_getattr_common ++}; ++static struct file_operations directory_f_ops = { ++ .llseek = reiser4_llseek_dir_common, ++ .read = generic_read_dir, ++ .readdir = reiser4_readdir_common, ++ .release = reiser4_release_dir_common, ++ .fsync = reiser4_sync_common ++}; ++static struct address_space_operations directory_a_ops = { ++ .writepage = bugop, ++ .sync_page = bugop, ++ .writepages = dummyop, ++ .set_page_dirty = bugop, ++ .readpages = bugop, ++ .write_begin = bugop, ++ .write_end = bugop, ++ .bmap = bugop, ++ .invalidatepage = bugop, ++ .releasepage = bugop ++}; ++ ++/* ++ * Definitions of object plugins. ++ */ ++ ++file_plugin file_plugins[LAST_FILE_PLUGIN_ID] = { ++ [UNIX_FILE_PLUGIN_ID] = { ++ .h = { ++ .type_id = REISER4_FILE_PLUGIN_TYPE, ++ .id = UNIX_FILE_PLUGIN_ID, ++ .groups = (1 << REISER4_REGULAR_FILE), ++ .pops = &file_plugin_ops, ++ .label = "reg", ++ .desc = "regular file", ++ .linkage = {NULL, NULL}, ++ }, ++ /* ++ * invariant vfs ops ++ */ ++ .inode_ops = ®ular_file_i_ops, ++ .file_ops = ®ular_file_f_ops, ++ .as_ops = ®ular_file_a_ops, ++ /* ++ * private i_ops ++ */ ++ .setattr = setattr_unix_file, ++ .open = open_unix_file, ++ .read = read_unix_file, ++ .write = write_unix_file, ++ .ioctl = ioctl_unix_file, ++ .mmap = mmap_unix_file, ++ .release = release_unix_file, ++ /* ++ * private f_ops ++ */ ++ .readpage = readpage_unix_file, ++ .readpages = readpages_unix_file, ++ .writepages = writepages_unix_file, ++ .write_begin = write_begin_unix_file, ++ .write_end = write_end_unix_file, ++ /* ++ * private a_ops ++ */ ++ .bmap = bmap_unix_file, ++ /* ++ * other private methods ++ */ ++ .write_sd_by_inode = write_sd_by_inode_common, ++ .flow_by_inode = flow_by_inode_unix_file, ++ .key_by_inode = key_by_inode_and_offset_common, ++ .set_plug_in_inode = set_plug_in_inode_common, ++ .adjust_to_parent = adjust_to_parent_common, ++ .create_object = reiser4_create_object_common, ++ .delete_object = delete_object_unix_file, ++ .add_link = reiser4_add_link_common, ++ .rem_link = reiser4_rem_link_common, ++ .owns_item = owns_item_unix_file, ++ .can_add_link = can_add_link_common, ++ .detach = dummyop, ++ .bind = dummyop, ++ .safelink = safelink_common, ++ .estimate = { ++ .create = estimate_create_common, ++ .update = estimate_update_common, ++ .unlink = estimate_unlink_common ++ }, ++ .init_inode_data = init_inode_data_unix_file, ++ .cut_tree_worker = cut_tree_worker_common, ++ .wire = { ++ .write = wire_write_common, ++ .read = wire_read_common, ++ .get = wire_get_common, ++ .size = wire_size_common, ++ .done = wire_done_common ++ } ++ }, ++ [DIRECTORY_FILE_PLUGIN_ID] = { ++ .h = { ++ .type_id = REISER4_FILE_PLUGIN_TYPE, ++ .id = DIRECTORY_FILE_PLUGIN_ID, ++ .groups = (1 << REISER4_DIRECTORY_FILE), ++ .pops = &file_plugin_ops, ++ .label = "dir", ++ .desc = "directory", ++ .linkage = {NULL, NULL} ++ }, ++ .inode_ops = &null_i_ops, ++ .file_ops = &null_f_ops, ++ .as_ops = &null_a_ops, ++ ++ .write_sd_by_inode = write_sd_by_inode_common, ++ .flow_by_inode = bugop, ++ .key_by_inode = bugop, ++ .set_plug_in_inode = set_plug_in_inode_common, ++ .adjust_to_parent = adjust_to_parent_common_dir, ++ .create_object = reiser4_create_object_common, ++ .delete_object = reiser4_delete_dir_common, ++ .add_link = reiser4_add_link_common, ++ .rem_link = rem_link_common_dir, ++ .owns_item = owns_item_common_dir, ++ .can_add_link = can_add_link_common, ++ .can_rem_link = can_rem_link_common_dir, ++ .detach = reiser4_detach_common_dir, ++ .bind = reiser4_bind_common_dir, ++ .safelink = safelink_common, ++ .estimate = { ++ .create = estimate_create_common_dir, ++ .update = estimate_update_common, ++ .unlink = estimate_unlink_common_dir ++ }, ++ .wire = { ++ .write = wire_write_common, ++ .read = wire_read_common, ++ .get = wire_get_common, ++ .size = wire_size_common, ++ .done = wire_done_common ++ }, ++ .init_inode_data = init_inode_ordering, ++ .cut_tree_worker = cut_tree_worker_common, ++ }, ++ [SYMLINK_FILE_PLUGIN_ID] = { ++ .h = { ++ .type_id = REISER4_FILE_PLUGIN_TYPE, ++ .id = SYMLINK_FILE_PLUGIN_ID, ++ .groups = (1 << REISER4_SYMLINK_FILE), ++ .pops = &file_plugin_ops, ++ .label = "symlink", ++ .desc = "symbolic link", ++ .linkage = {NULL,NULL} ++ }, ++ .inode_ops = &symlink_file_i_ops, ++ /* inode->i_fop of symlink is initialized ++ by NULL in setup_inode_ops */ ++ .file_ops = &null_f_ops, ++ .as_ops = &null_a_ops, ++ ++ .write_sd_by_inode = write_sd_by_inode_common, ++ .set_plug_in_inode = set_plug_in_inode_common, ++ .adjust_to_parent = adjust_to_parent_common, ++ .create_object = reiser4_create_symlink, ++ .delete_object = reiser4_delete_object_common, ++ .add_link = reiser4_add_link_common, ++ .rem_link = reiser4_rem_link_common, ++ .can_add_link = can_add_link_common, ++ .detach = dummyop, ++ .bind = dummyop, ++ .safelink = safelink_common, ++ .estimate = { ++ .create = estimate_create_common, ++ .update = estimate_update_common, ++ .unlink = estimate_unlink_common ++ }, ++ .init_inode_data = init_inode_ordering, ++ .cut_tree_worker = cut_tree_worker_common, ++ .destroy_inode = destroy_inode_symlink, ++ .wire = { ++ .write = wire_write_common, ++ .read = wire_read_common, ++ .get = wire_get_common, ++ .size = wire_size_common, ++ .done = wire_done_common ++ } ++ }, ++ [SPECIAL_FILE_PLUGIN_ID] = { ++ .h = { ++ .type_id = REISER4_FILE_PLUGIN_TYPE, ++ .id = SPECIAL_FILE_PLUGIN_ID, ++ .groups = (1 << REISER4_SPECIAL_FILE), ++ .pops = &file_plugin_ops, ++ .label = "special", ++ .desc = ++ "special: fifo, device or socket", ++ .linkage = {NULL, NULL} ++ }, ++ .inode_ops = &special_file_i_ops, ++ /* file_ops of special files (sockets, block, char, fifo) are ++ initialized by init_special_inode. */ ++ .file_ops = &null_f_ops, ++ .as_ops = &null_a_ops, ++ ++ .write_sd_by_inode = write_sd_by_inode_common, ++ .set_plug_in_inode = set_plug_in_inode_common, ++ .adjust_to_parent = adjust_to_parent_common, ++ .create_object = reiser4_create_object_common, ++ .delete_object = reiser4_delete_object_common, ++ .add_link = reiser4_add_link_common, ++ .rem_link = reiser4_rem_link_common, ++ .owns_item = owns_item_common, ++ .can_add_link = can_add_link_common, ++ .detach = dummyop, ++ .bind = dummyop, ++ .safelink = safelink_common, ++ .estimate = { ++ .create = estimate_create_common, ++ .update = estimate_update_common, ++ .unlink = estimate_unlink_common ++ }, ++ .init_inode_data = init_inode_ordering, ++ .cut_tree_worker = cut_tree_worker_common, ++ .wire = { ++ .write = wire_write_common, ++ .read = wire_read_common, ++ .get = wire_get_common, ++ .size = wire_size_common, ++ .done = wire_done_common ++ } ++ }, ++ [CRYPTCOMPRESS_FILE_PLUGIN_ID] = { ++ .h = { ++ .type_id = REISER4_FILE_PLUGIN_TYPE, ++ .id = CRYPTCOMPRESS_FILE_PLUGIN_ID, ++ .groups = (1 << REISER4_REGULAR_FILE), ++ .pops = &file_plugin_ops, ++ .label = "cryptcompress", ++ .desc = "cryptcompress file", ++ .linkage = {NULL, NULL} ++ }, ++ .inode_ops = ®ular_file_i_ops, ++ .file_ops = ®ular_file_f_ops, ++ .as_ops = ®ular_file_a_ops, ++ ++ .setattr = setattr_cryptcompress, ++ .open = open_cryptcompress, ++ .read = read_cryptcompress, ++ .write = write_cryptcompress, ++ .ioctl = ioctl_cryptcompress, ++ .mmap = mmap_cryptcompress, ++ .release = release_cryptcompress, ++ ++ .readpage = readpage_cryptcompress, ++ .readpages = readpages_cryptcompress, ++ .writepages = writepages_cryptcompress, ++ .write_begin = write_begin_cryptcompress, ++ .write_end = write_end_cryptcompress, ++ ++ .bmap = bmap_cryptcompress, ++ ++ .write_sd_by_inode = write_sd_by_inode_common, ++ .flow_by_inode = flow_by_inode_cryptcompress, ++ .key_by_inode = key_by_inode_cryptcompress, ++ .set_plug_in_inode = set_plug_in_inode_common, ++ .adjust_to_parent = adjust_to_parent_cryptcompress, ++ .create_object = create_object_cryptcompress, ++ .delete_object = delete_object_cryptcompress, ++ .add_link = reiser4_add_link_common, ++ .rem_link = reiser4_rem_link_common, ++ .owns_item = owns_item_common, ++ .can_add_link = can_add_link_common, ++ .detach = dummyop, ++ .bind = dummyop, ++ .safelink = safelink_common, ++ .estimate = { ++ .create = estimate_create_common, ++ .update = estimate_update_common, ++ .unlink = estimate_unlink_common ++ }, ++ .init_inode_data = init_inode_data_cryptcompress, ++ .cut_tree_worker = cut_tree_worker_cryptcompress, ++ .destroy_inode = destroy_inode_cryptcompress, ++ .wire = { ++ .write = wire_write_common, ++ .read = wire_read_common, ++ .get = wire_get_common, ++ .size = wire_size_common, ++ .done = wire_done_common ++ } ++ } ++}; ++ ++static int change_dir(struct inode *inode, ++ reiser4_plugin * plugin, ++ pset_member memb) ++{ ++ /* cannot change dir plugin of already existing object */ ++ return RETERR(-EINVAL); ++} ++ ++static reiser4_plugin_ops dir_plugin_ops = { ++ .change = change_dir ++}; ++ ++/* ++ * definition of directory plugins ++ */ ++ ++dir_plugin dir_plugins[LAST_DIR_ID] = { ++ /* standard hashed directory plugin */ ++ [HASHED_DIR_PLUGIN_ID] = { ++ .h = { ++ .type_id = REISER4_DIR_PLUGIN_TYPE, ++ .id = HASHED_DIR_PLUGIN_ID, ++ .pops = &dir_plugin_ops, ++ .label = "dir", ++ .desc = "hashed directory", ++ .linkage = {NULL, NULL} ++ }, ++ .inode_ops = &directory_i_ops, ++ .file_ops = &directory_f_ops, ++ .as_ops = &directory_a_ops, ++ ++ .get_parent = get_parent_common, ++ .is_name_acceptable = is_name_acceptable_common, ++ .build_entry_key = build_entry_key_hashed, ++ .build_readdir_key = build_readdir_key_common, ++ .add_entry = reiser4_add_entry_common, ++ .rem_entry = reiser4_rem_entry_common, ++ .init = reiser4_dir_init_common, ++ .done = reiser4_dir_done_common, ++ .attach = reiser4_attach_common, ++ .detach = reiser4_detach_common, ++ .estimate = { ++ .add_entry = estimate_add_entry_common, ++ .rem_entry = estimate_rem_entry_common, ++ .unlink = dir_estimate_unlink_common ++ } ++ }, ++ /* hashed directory for which seekdir/telldir are guaranteed to ++ * work. Brain-damage. */ ++ [SEEKABLE_HASHED_DIR_PLUGIN_ID] = { ++ .h = { ++ .type_id = REISER4_DIR_PLUGIN_TYPE, ++ .id = SEEKABLE_HASHED_DIR_PLUGIN_ID, ++ .pops = &dir_plugin_ops, ++ .label = "dir32", ++ .desc = "directory hashed with 31 bit hash", ++ .linkage = {NULL, NULL} ++ }, ++ .inode_ops = &directory_i_ops, ++ .file_ops = &directory_f_ops, ++ .as_ops = &directory_a_ops, ++ ++ .get_parent = get_parent_common, ++ .is_name_acceptable = is_name_acceptable_common, ++ .build_entry_key = build_entry_key_seekable, ++ .build_readdir_key = build_readdir_key_common, ++ .add_entry = reiser4_add_entry_common, ++ .rem_entry = reiser4_rem_entry_common, ++ .init = reiser4_dir_init_common, ++ .done = reiser4_dir_done_common, ++ .attach = reiser4_attach_common, ++ .detach = reiser4_detach_common, ++ .estimate = { ++ .add_entry = estimate_add_entry_common, ++ .rem_entry = estimate_rem_entry_common, ++ .unlink = dir_estimate_unlink_common ++ } ++ } ++}; ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/object.h linux-2.6.30/fs/reiser4/plugin/object.h +--- linux-2.6.30.orig/fs/reiser4/plugin/object.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/object.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,117 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Declaration of object plugin functions. */ ++ ++#if !defined(__FS_REISER4_PLUGIN_OBJECT_H__) ++#define __FS_REISER4_PLUGIN_OBJECT_H__ ++ ++#include "../type_safe_hash.h" ++ ++/* common implementations of inode operations */ ++int reiser4_create_common(struct inode *parent, struct dentry *dentry, ++ int mode, struct nameidata *); ++struct dentry *reiser4_lookup_common(struct inode *parent, ++ struct dentry *dentry, ++ struct nameidata *nameidata); ++int reiser4_link_common(struct dentry *existing, struct inode *parent, ++ struct dentry *newname); ++int reiser4_unlink_common(struct inode *parent, struct dentry *victim); ++int reiser4_mkdir_common(struct inode *parent, struct dentry *dentry, int mode); ++int reiser4_symlink_common(struct inode *parent, struct dentry *dentry, ++ const char *linkname); ++int reiser4_mknod_common(struct inode *parent, struct dentry *dentry, ++ int mode, dev_t rdev); ++int reiser4_rename_common(struct inode *old_dir, struct dentry *old_name, ++ struct inode *new_dir, struct dentry *new_name); ++void *reiser4_follow_link_common(struct dentry *, struct nameidata *data); ++int reiser4_permission_common(struct inode *, int mask); ++int reiser4_setattr_common(struct dentry *, struct iattr *); ++int reiser4_getattr_common(struct vfsmount *mnt, struct dentry *, ++ struct kstat *); ++ ++/* common implementations of file operations */ ++loff_t reiser4_llseek_dir_common(struct file *, loff_t off, int origin); ++int reiser4_readdir_common(struct file *, void *dirent, filldir_t); ++int reiser4_release_dir_common(struct inode *, struct file *); ++int reiser4_sync_common(struct file *, struct dentry *, int datasync); ++ ++ ++/* file plugin operations: common implementations */ ++int write_sd_by_inode_common(struct inode *); ++int key_by_inode_and_offset_common(struct inode *, loff_t, reiser4_key *); ++int set_plug_in_inode_common(struct inode *object, struct inode *parent, ++ reiser4_object_create_data *); ++int adjust_to_parent_common(struct inode *object, struct inode *parent, ++ struct inode *root); ++int adjust_to_parent_common_dir(struct inode *object, struct inode *parent, ++ struct inode *root); ++int adjust_to_parent_cryptcompress(struct inode *object, struct inode *parent, ++ struct inode *root); ++int reiser4_create_object_common(struct inode *object, struct inode *parent, ++ reiser4_object_create_data *); ++int reiser4_delete_object_common(struct inode *); ++int reiser4_delete_dir_common(struct inode *); ++int reiser4_add_link_common(struct inode *object, struct inode *parent); ++int reiser4_rem_link_common(struct inode *object, struct inode *parent); ++int rem_link_common_dir(struct inode *object, struct inode *parent); ++int owns_item_common(const struct inode *, const coord_t *); ++int owns_item_common_dir(const struct inode *, const coord_t *); ++int can_add_link_common(const struct inode *); ++int can_rem_link_common_dir(const struct inode *); ++int reiser4_detach_common_dir(struct inode *child, struct inode *parent); ++int reiser4_bind_common_dir(struct inode *child, struct inode *parent); ++int safelink_common(struct inode *, reiser4_safe_link_t, __u64 value); ++reiser4_block_nr estimate_create_common(const struct inode *); ++reiser4_block_nr estimate_create_common_dir(const struct inode *); ++reiser4_block_nr estimate_update_common(const struct inode *); ++reiser4_block_nr estimate_unlink_common(const struct inode *, ++ const struct inode *); ++reiser4_block_nr estimate_unlink_common_dir(const struct inode *, ++ const struct inode *); ++char *wire_write_common(struct inode *, char *start); ++char *wire_read_common(char *addr, reiser4_object_on_wire *); ++struct dentry *wire_get_common(struct super_block *, reiser4_object_on_wire *); ++int wire_size_common(struct inode *); ++void wire_done_common(reiser4_object_on_wire *); ++ ++/* dir plugin operations: common implementations */ ++struct dentry *get_parent_common(struct inode *child); ++int is_name_acceptable_common(const struct inode *, const char *name, int len); ++void build_entry_key_common(const struct inode *, ++ const struct qstr *qname, reiser4_key *); ++int build_readdir_key_common(struct file *dir, reiser4_key *); ++int reiser4_add_entry_common(struct inode *object, struct dentry *where, ++ reiser4_object_create_data * , reiser4_dir_entry_desc *); ++int reiser4_rem_entry_common(struct inode *object, struct dentry *where, ++ reiser4_dir_entry_desc *); ++int reiser4_dir_init_common(struct inode *object, struct inode *parent, ++ reiser4_object_create_data *); ++int reiser4_dir_done_common(struct inode *); ++int reiser4_attach_common(struct inode *child, struct inode *parent); ++int reiser4_detach_common(struct inode *object, struct inode *parent); ++reiser4_block_nr estimate_add_entry_common(const struct inode *); ++reiser4_block_nr estimate_rem_entry_common(const struct inode *); ++reiser4_block_nr dir_estimate_unlink_common(const struct inode *, ++ const struct inode *); ++ ++/* these are essential parts of common implementations, they are to make ++ customized implementations easier */ ++int do_prepare_write(struct file *, struct page *, unsigned from, unsigned to); ++ ++/* merely useful functions */ ++int lookup_sd(struct inode *, znode_lock_mode, coord_t *, lock_handle * , ++ const reiser4_key * , int silent); ++ ++/* __FS_REISER4_PLUGIN_OBJECT_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/plugin.c linux-2.6.30/fs/reiser4/plugin/plugin.c +--- linux-2.6.30.orig/fs/reiser4/plugin/plugin.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/plugin.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,560 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Basic plugin infrastructure, lookup etc. */ ++ ++/* PLUGINS: ++ ++ Plugins are internal Reiser4 "modules" or "objects" used to increase ++ extensibility and allow external users to easily adapt reiser4 to ++ their needs. ++ ++ Plugins are classified into several disjoint "types". Plugins ++ belonging to the particular plugin type are termed "instances" of ++ this type. Existing types are listed by enum reiser4_plugin_type ++ (see plugin/plugin_header.h) ++ ++NIKITA-FIXME-HANS: update this list, and review this entire comment for currency ++ ++ Object (file) plugin determines how given file-system object serves ++ standard VFS requests for read, write, seek, mmap etc. Instances of ++ file plugins are: regular file, directory, symlink. Another example ++ of file plugin is audit plugin, that optionally records accesses to ++ underlying object and forwards requests to it. ++ ++ Hash plugins compute hashes used by reiser4 to store and locate ++ files within directories. Instances of hash plugin type are: r5, ++ tea, rupasov. ++ ++ Tail plugins (or, more precisely, tail policy plugins) determine ++ when last part of the file should be stored in a formatted item. ++ ++ Scope and lookup: ++ ++ label such that pair ( type_label, plugin_label ) is unique. This ++ pair is a globally persistent and user-visible plugin ++ identifier. Internally kernel maintains plugins and plugin types in ++ arrays using an index into those arrays as plugin and plugin type ++ identifiers. File-system in turn, also maintains persistent ++ "dictionary" which is mapping from plugin label to numerical ++ identifier which is stored in file-system objects. That is, we ++ store the offset into the plugin array for that plugin type as the ++ plugin id in the stat data of the filesystem object. ++ ++ Internal kernel plugin type identifier (index in plugins[] array) is ++ of type reiser4_plugin_type. Set of available plugin types is ++ currently static, but dynamic loading doesn't seem to pose ++ insurmountable problems. ++ ++ Within each type plugins are addressed by the identifiers of type ++ reiser4_plugin_id (indices in reiser4_plugin_type_data.builtin[]). ++ Such identifiers are only required to be unique within one type, ++ not globally. ++ ++ Thus, plugin in memory is uniquely identified by the pair (type_id, ++ id). ++ ++ Usage: ++ ++ There exists only one instance of each plugin instance, but this ++ single instance can be associated with many entities (file-system ++ objects, items, nodes, transactions, file-descriptors etc.). Entity ++ to which plugin of given type is termed (due to the lack of ++ imagination) "subject" of this plugin type and, by abuse of ++ terminology, subject of particular instance of this type to which ++ it's attached currently. For example, inode is subject of object ++ plugin type. Inode representing directory is subject of directory ++ plugin, hash plugin type and some particular instance of hash plugin ++ type. Inode, representing regular file is subject of "regular file" ++ plugin, tail-policy plugin type etc. ++ ++ With each subject the plugin possibly stores some state. For example, ++ the state of a directory plugin (instance of object plugin type) is pointer ++ to hash plugin (if directories always use hashing that is). ++ ++ Interface: ++ ++ In addition to a scalar identifier, each plugin type and plugin ++ proper has a "label": short string and a "description"---longer ++ descriptive string. Labels and descriptions of plugin types are ++ hard-coded into plugins[] array, declared and defined in ++ plugin.c. Label and description of plugin are stored in .label and ++ .desc fields of reiser4_plugin_header respectively. It's possible to ++ locate plugin by the pair of labels. ++ ++ Features (not implemented): ++ ++ . user-level plugin manipulations: ++ + reiser4("filename/..file_plugin<='audit'"); ++ + write(open("filename/..file_plugin"), "audit", 8); ++ ++ . user level utilities lsplug and chplug to manipulate plugins. ++ Utilities are not of primary priority. Possibly they will be not ++ working on v4.0 ++ ++ NIKITA-FIXME-HANS: this should be a mkreiserfs option not a mount ++ option, do you agree? I don't think that specifying it at mount time, ++ and then changing it with each mount, is a good model for usage. ++ ++ . mount option "plug" to set-up plugins of root-directory. ++ "plug=foo:bar" will set "bar" as default plugin of type "foo". ++ ++ Limitations: ++ ++ . each plugin type has to provide at least one builtin ++ plugin. This is technical limitation and it can be lifted in the ++ future. ++ ++ TODO: ++ ++ New plugin types/plugings: ++ Things we should be able to separately choose to inherit: ++ ++ security plugins ++ ++ stat data ++ ++ file bodies ++ ++ file plugins ++ ++ dir plugins ++ ++ . perm:acl ++ ++ . audi---audit plugin intercepting and possibly logging all ++ accesses to object. Requires to put stub functions in file_operations ++ in stead of generic_file_*. ++ ++NIKITA-FIXME-HANS: why make overflows a plugin? ++ . over---handle hash overflows ++ ++ . sqnt---handle different access patterns and instruments read-ahead ++ ++NIKITA-FIXME-HANS: describe the line below in more detail. ++ ++ . hier---handle inheritance of plugins along file-system hierarchy ++ ++ Different kinds of inheritance: on creation vs. on access. ++ Compatible/incompatible plugins. ++ Inheritance for multi-linked files. ++ Layered plugins. ++ Notion of plugin context is abandoned. ++ ++Each file is associated ++ with one plugin and dependant plugins (hash, etc.) are stored as ++ main plugin state. Now, if we have plugins used for regular files ++ but not for directories, how such plugins would be inherited? ++ . always store them with directories also ++ ++NIKTIA-FIXME-HANS: Do the line above. It is not exclusive of doing ++the line below which is also useful. ++ ++ . use inheritance hierarchy, independent of file-system namespace ++*/ ++ ++#include "../debug.h" ++#include "../dformat.h" ++#include "plugin_header.h" ++#include "item/static_stat.h" ++#include "node/node.h" ++#include "security/perm.h" ++#include "space/space_allocator.h" ++#include "disk_format/disk_format.h" ++#include "plugin.h" ++#include "../reiser4.h" ++#include "../jnode.h" ++#include "../inode.h" ++ ++#include <linux/fs.h> /* for struct super_block */ ++ ++/* ++ * init_plugins - initialize plugin sub-system. ++ * Just call this once on reiser4 startup. ++ * ++ * Initializes plugin sub-system. It is part of reiser4 module ++ * initialization. For each plugin of each type init method is called and each ++ * plugin is put into list of plugins. ++ */ ++int init_plugins(void) ++{ ++ reiser4_plugin_type type_id; ++ ++ for (type_id = 0; type_id < REISER4_PLUGIN_TYPES; ++type_id) { ++ struct reiser4_plugin_type_data *ptype; ++ int i; ++ ++ ptype = &plugins[type_id]; ++ assert("nikita-3508", ptype->label != NULL); ++ assert("nikita-3509", ptype->type_id == type_id); ++ ++ INIT_LIST_HEAD(&ptype->plugins_list); ++/* NIKITA-FIXME-HANS: change builtin_num to some other name lacking the term ++ * builtin. */ ++ for (i = 0; i < ptype->builtin_num; ++i) { ++ reiser4_plugin *plugin; ++ ++ plugin = plugin_at(ptype, i); ++ ++ if (plugin->h.label == NULL) ++ /* uninitialized slot encountered */ ++ continue; ++ assert("nikita-3445", plugin->h.type_id == type_id); ++ plugin->h.id = i; ++ if (plugin->h.pops != NULL && ++ plugin->h.pops->init != NULL) { ++ int result; ++ ++ result = plugin->h.pops->init(plugin); ++ if (result != 0) ++ return result; ++ } ++ INIT_LIST_HEAD(&plugin->h.linkage); ++ list_add_tail(&plugin->h.linkage, &ptype->plugins_list); ++ } ++ } ++ return 0; ++} ++ ++/* true if plugin type id is valid */ ++int is_plugin_type_valid(reiser4_plugin_type type) ++{ ++ /* "type" is unsigned, so no comparison with 0 is ++ necessary */ ++ return (type < REISER4_PLUGIN_TYPES); ++} ++ ++/* true if plugin id is valid */ ++int is_plugin_id_valid(reiser4_plugin_type type, reiser4_plugin_id id) ++{ ++ assert("nikita-1653", is_plugin_type_valid(type)); ++ return id < plugins[type].builtin_num; ++} ++ ++/* return plugin by its @type and @id. ++ ++ Both arguments are checked for validness: this is supposed to be called ++ from user-level. ++ ++NIKITA-FIXME-HANS: Do you instead mean that this checks ids created in ++user space, and passed to the filesystem by use of method files? Your ++comment really confused me on the first reading.... ++ ++*/ ++reiser4_plugin *plugin_by_unsafe_id(reiser4_plugin_type type /* plugin type ++ * unchecked */, ++ reiser4_plugin_id id /* plugin id, ++ * unchecked */) ++{ ++ if (is_plugin_type_valid(type)) { ++ if (is_plugin_id_valid(type, id)) ++ return plugin_at(&plugins[type], id); ++ else ++ /* id out of bounds */ ++ warning("nikita-2913", ++ "Invalid plugin id: [%i:%i]", type, id); ++ } else ++ /* type_id out of bounds */ ++ warning("nikita-2914", "Invalid type_id: %i", type); ++ return NULL; ++} ++ ++/** ++ * save_plugin_id - store plugin id in disk format ++ * @plugin: plugin to convert ++ * @area: where to store result ++ * ++ * Puts id of @plugin in little endian format to address @area. ++ */ ++int save_plugin_id(reiser4_plugin *plugin /* plugin to convert */ , ++ d16 * area/* where to store result */) ++{ ++ assert("nikita-1261", plugin != NULL); ++ assert("nikita-1262", area != NULL); ++ ++ put_unaligned(cpu_to_le16(plugin->h.id), area); ++ return 0; ++} ++ ++/* list of all plugins of given type */ ++struct list_head *get_plugin_list(reiser4_plugin_type type) ++{ ++ assert("nikita-1056", is_plugin_type_valid(type)); ++ return &plugins[type].plugins_list; ++} ++ ++static void update_pset_mask(reiser4_inode * info, pset_member memb) ++{ ++ struct dentry *rootdir; ++ reiser4_inode *root; ++ ++ assert("edward-1443", memb != PSET_FILE); ++ ++ rootdir = inode_by_reiser4_inode(info)->i_sb->s_root; ++ if (rootdir != NULL) { ++ root = reiser4_inode_data(rootdir->d_inode); ++ /* ++ * if inode is different from the default one, or we are ++ * changing plugin of root directory, update plugin_mask ++ */ ++ if (aset_get(info->pset, memb) != ++ aset_get(root->pset, memb) || ++ info == root) ++ info->plugin_mask |= (1 << memb); ++ else ++ info->plugin_mask &= ~(1 << memb); ++ } ++} ++ ++/* Get specified plugin set member from parent, ++ or from fs-defaults (if no parent is given) and ++ install the result to pset of @self */ ++int grab_plugin_pset(struct inode *self, ++ struct inode *ancestor, ++ pset_member memb) ++{ ++ reiser4_plugin *plug; ++ reiser4_inode *info; ++ int result = 0; ++ ++ /* Do not grab if initialised already. */ ++ info = reiser4_inode_data(self); ++ if (aset_get(info->pset, memb) != NULL) ++ return 0; ++ if (ancestor) { ++ reiser4_inode *parent; ++ ++ parent = reiser4_inode_data(ancestor); ++ plug = aset_get(parent->hset, memb) ? : ++ aset_get(parent->pset, memb); ++ } else ++ plug = get_default_plugin(memb); ++ ++ result = set_plugin(&info->pset, memb, plug); ++ if (result == 0) { ++ if (!ancestor || self->i_sb->s_root->d_inode != self) ++ update_pset_mask(info, memb); ++ } ++ return result; ++} ++ ++/* Take missing pset members from root inode */ ++int finish_pset(struct inode *inode) ++{ ++ reiser4_plugin *plug; ++ reiser4_inode *root; ++ reiser4_inode *info; ++ pset_member memb; ++ int result = 0; ++ ++ root = reiser4_inode_data(inode->i_sb->s_root->d_inode); ++ info = reiser4_inode_data(inode); ++ ++ assert("edward-1455", root != NULL); ++ assert("edward-1456", info != NULL); ++ ++ /* file and directory plugins are already initialized. */ ++ for (memb = PSET_DIR + 1; memb < PSET_LAST; ++memb) { ++ ++ /* Do not grab if initialised already. */ ++ if (aset_get(info->pset, memb) != NULL) ++ continue; ++ ++ plug = aset_get(root->pset, memb); ++ result = set_plugin(&info->pset, memb, plug); ++ if (result != 0) ++ break; ++ } ++ if (result != 0) { ++ warning("nikita-3447", ++ "Cannot set up plugins for %lli", ++ (unsigned long long) ++ get_inode_oid(inode)); ++ } ++ return result; ++} ++ ++int force_plugin_pset(struct inode *self, pset_member memb, ++ reiser4_plugin * plug) ++{ ++ reiser4_inode *info; ++ int result = 0; ++ ++ if (!self->i_sb->s_root || self->i_sb->s_root->d_inode == self) { ++ /* Changing pset in the root object. */ ++ return RETERR(-EINVAL); ++ } ++ ++ info = reiser4_inode_data(self); ++ if (plug->h.pops != NULL && plug->h.pops->change != NULL) ++ result = plug->h.pops->change(self, plug, memb); ++ else ++ result = aset_set_unsafe(&info->pset, memb, plug); ++ if (result == 0) { ++ __u16 oldmask = info->plugin_mask; ++ ++ update_pset_mask(info, memb); ++ if (oldmask != info->plugin_mask) ++ reiser4_inode_clr_flag(self, REISER4_SDLEN_KNOWN); ++ } ++ return result; ++} ++ ++struct reiser4_plugin_type_data plugins[REISER4_PLUGIN_TYPES] = { ++ /* C90 initializers */ ++ [REISER4_FILE_PLUGIN_TYPE] = { ++ .type_id = REISER4_FILE_PLUGIN_TYPE, ++ .label = "file", ++ .desc = "Object plugins", ++ .builtin_num = sizeof_array(file_plugins), ++ .builtin = file_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(file_plugin) ++ }, ++ [REISER4_DIR_PLUGIN_TYPE] = { ++ .type_id = REISER4_DIR_PLUGIN_TYPE, ++ .label = "dir", ++ .desc = "Directory plugins", ++ .builtin_num = sizeof_array(dir_plugins), ++ .builtin = dir_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(dir_plugin) ++ }, ++ [REISER4_HASH_PLUGIN_TYPE] = { ++ .type_id = REISER4_HASH_PLUGIN_TYPE, ++ .label = "hash", ++ .desc = "Directory hashes", ++ .builtin_num = sizeof_array(hash_plugins), ++ .builtin = hash_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(hash_plugin) ++ }, ++ [REISER4_FIBRATION_PLUGIN_TYPE] = { ++ .type_id = ++ REISER4_FIBRATION_PLUGIN_TYPE, ++ .label = "fibration", ++ .desc = "Directory fibrations", ++ .builtin_num = sizeof_array(fibration_plugins), ++ .builtin = fibration_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(fibration_plugin) ++ }, ++ [REISER4_CIPHER_PLUGIN_TYPE] = { ++ .type_id = REISER4_CIPHER_PLUGIN_TYPE, ++ .label = "cipher", ++ .desc = "Cipher plugins", ++ .builtin_num = sizeof_array(cipher_plugins), ++ .builtin = cipher_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(cipher_plugin) ++ }, ++ [REISER4_DIGEST_PLUGIN_TYPE] = { ++ .type_id = REISER4_DIGEST_PLUGIN_TYPE, ++ .label = "digest", ++ .desc = "Digest plugins", ++ .builtin_num = sizeof_array(digest_plugins), ++ .builtin = digest_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(digest_plugin) ++ }, ++ [REISER4_COMPRESSION_PLUGIN_TYPE] = { ++ .type_id = REISER4_COMPRESSION_PLUGIN_TYPE, ++ .label = "compression", ++ .desc = "Compression plugins", ++ .builtin_num = sizeof_array(compression_plugins), ++ .builtin = compression_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(compression_plugin) ++ }, ++ [REISER4_FORMATTING_PLUGIN_TYPE] = { ++ .type_id = REISER4_FORMATTING_PLUGIN_TYPE, ++ .label = "formatting", ++ .desc = "Tail inlining policies", ++ .builtin_num = sizeof_array(formatting_plugins), ++ .builtin = formatting_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(formatting_plugin) ++ }, ++ [REISER4_PERM_PLUGIN_TYPE] = { ++ .type_id = REISER4_PERM_PLUGIN_TYPE, ++ .label = "perm", ++ .desc = "Permission checks", ++ .builtin_num = sizeof_array(perm_plugins), ++ .builtin = perm_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(perm_plugin) ++ }, ++ [REISER4_ITEM_PLUGIN_TYPE] = { ++ .type_id = REISER4_ITEM_PLUGIN_TYPE, ++ .label = "item", ++ .desc = "Item handlers", ++ .builtin_num = sizeof_array(item_plugins), ++ .builtin = item_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(item_plugin) ++ }, ++ [REISER4_NODE_PLUGIN_TYPE] = { ++ .type_id = REISER4_NODE_PLUGIN_TYPE, ++ .label = "node", ++ .desc = "node layout handlers", ++ .builtin_num = sizeof_array(node_plugins), ++ .builtin = node_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(node_plugin) ++ }, ++ [REISER4_SD_EXT_PLUGIN_TYPE] = { ++ .type_id = REISER4_SD_EXT_PLUGIN_TYPE, ++ .label = "sd_ext", ++ .desc = "Parts of stat-data", ++ .builtin_num = sizeof_array(sd_ext_plugins), ++ .builtin = sd_ext_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(sd_ext_plugin) ++ }, ++ [REISER4_FORMAT_PLUGIN_TYPE] = { ++ .type_id = REISER4_FORMAT_PLUGIN_TYPE, ++ .label = "disk_layout", ++ .desc = "defines filesystem on disk layout", ++ .builtin_num = sizeof_array(format_plugins), ++ .builtin = format_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(disk_format_plugin) ++ }, ++ [REISER4_JNODE_PLUGIN_TYPE] = { ++ .type_id = REISER4_JNODE_PLUGIN_TYPE, ++ .label = "jnode", ++ .desc = "defines kind of jnode", ++ .builtin_num = sizeof_array(jnode_plugins), ++ .builtin = jnode_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(jnode_plugin) ++ }, ++ [REISER4_COMPRESSION_MODE_PLUGIN_TYPE] = { ++ .type_id = REISER4_COMPRESSION_MODE_PLUGIN_TYPE, ++ .label = "compression_mode", ++ .desc = "Defines compression mode", ++ .builtin_num = sizeof_array(compression_mode_plugins), ++ .builtin = compression_mode_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(compression_mode_plugin) ++ }, ++ [REISER4_CLUSTER_PLUGIN_TYPE] = { ++ .type_id = REISER4_CLUSTER_PLUGIN_TYPE, ++ .label = "cluster", ++ .desc = "Defines cluster size", ++ .builtin_num = sizeof_array(cluster_plugins), ++ .builtin = cluster_plugins, ++ .plugins_list = {NULL, NULL}, ++ .size = sizeof(cluster_plugin) ++ } ++}; ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 120 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/plugin.h linux-2.6.30/fs/reiser4/plugin/plugin.h +--- linux-2.6.30.orig/fs/reiser4/plugin/plugin.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/plugin.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,942 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Basic plugin data-types. ++ see fs/reiser4/plugin/plugin.c for details */ ++ ++#if !defined(__FS_REISER4_PLUGIN_TYPES_H__) ++#define __FS_REISER4_PLUGIN_TYPES_H__ ++ ++#include "../forward.h" ++#include "../debug.h" ++#include "../dformat.h" ++#include "../key.h" ++#include "compress/compress.h" ++#include "crypto/cipher.h" ++#include "plugin_header.h" ++#include "item/static_stat.h" ++#include "item/internal.h" ++#include "item/sde.h" ++#include "item/cde.h" ++#include "item/item.h" ++#include "node/node.h" ++#include "node/node40.h" ++#include "security/perm.h" ++#include "fibration.h" ++ ++#include "space/bitmap.h" ++#include "space/space_allocator.h" ++ ++#include "disk_format/disk_format40.h" ++#include "disk_format/disk_format.h" ++ ++#include <linux/fs.h> /* for struct super_block, address_space */ ++#include <linux/mm.h> /* for struct page */ ++#include <linux/buffer_head.h> /* for struct buffer_head */ ++#include <linux/dcache.h> /* for struct dentry */ ++#include <linux/types.h> ++#include <linux/crypto.h> ++ ++typedef struct reiser4_object_on_wire reiser4_object_on_wire; ++ ++/* ++ * File plugin. Defines the set of methods that file plugins implement, some ++ * of which are optional. ++ * ++ * A file plugin offers to the caller an interface for IO ( writing to and/or ++ * reading from) to what the caller sees as one sequence of bytes. An IO to it ++ * may affect more than one physical sequence of bytes, or no physical sequence ++ * of bytes, it may affect sequences of bytes offered by other file plugins to ++ * the semantic layer, and the file plugin may invoke other plugins and ++ * delegate work to them, but its interface is structured for offering the ++ * caller the ability to read and/or write what the caller sees as being a ++ * single sequence of bytes. ++ * ++ * The file plugin must present a sequence of bytes to the caller, but it does ++ * not necessarily have to store a sequence of bytes, it does not necessarily ++ * have to support efficient tree traversal to any offset in the sequence of ++ * bytes (tail and extent items, whose keys contain offsets, do however provide ++ * efficient non-sequential lookup of any offset in the sequence of bytes). ++ * ++ * Directory plugins provide methods for selecting file plugins by resolving a ++ * name for them. ++ * ++ * The functionality other filesystems call an attribute, and rigidly tie ++ * together, we decompose into orthogonal selectable features of files. Using ++ * the terminology we will define next, an attribute is a perhaps constrained, ++ * perhaps static length, file whose parent has a uni-count-intra-link to it, ++ * which might be grandparent-major-packed, and whose parent has a deletion ++ * method that deletes it. ++ * ++ * File plugins can implement constraints. ++ * ++ * Files can be of variable length (e.g. regular unix files), or of static ++ * length (e.g. static sized attributes). ++ * ++ * An object may have many sequences of bytes, and many file plugins, but, it ++ * has exactly one objectid. It is usually desirable that an object has a ++ * deletion method which deletes every item with that objectid. Items cannot ++ * in general be found by just their objectids. This means that an object must ++ * have either a method built into its deletion plugin method for knowing what ++ * items need to be deleted, or links stored with the object that provide the ++ * plugin with a method for finding those items. Deleting a file within an ++ * object may or may not have the effect of deleting the entire object, ++ * depending on the file plugin's deletion method. ++ * ++ * LINK TAXONOMY: ++ * ++ * Many objects have a reference count, and when the reference count reaches 0 ++ * the object's deletion method is invoked. Some links embody a reference ++ * count increase ("countlinks"), and others do not ("nocountlinks"). ++ * ++ * Some links are bi-directional links ("bilinks"), and some are ++ * uni-directional("unilinks"). ++ * ++ * Some links are between parts of the same object ("intralinks"), and some are ++ * between different objects ("interlinks"). ++ * ++ * PACKING TAXONOMY: ++ * ++ * Some items of an object are stored with a major packing locality based on ++ * their object's objectid (e.g. unix directory items in plan A), and these are ++ * called "self-major-packed". ++ * ++ * Some items of an object are stored with a major packing locality based on ++ * their semantic parent object's objectid (e.g. unix file bodies in plan A), ++ * and these are called "parent-major-packed". ++ * ++ * Some items of an object are stored with a major packing locality based on ++ * their semantic grandparent, and these are called "grandparent-major-packed". ++ * Now carefully notice that we run into trouble with key length if we have to ++ * store a 8 byte major+minor grandparent based packing locality, an 8 byte ++ * parent objectid, an 8 byte attribute objectid, and an 8 byte offset, all in ++ * a 24 byte key. One of these fields must be sacrificed if an item is to be ++ * grandparent-major-packed, and which to sacrifice is left to the item author ++ * choosing to make the item grandparent-major-packed. You cannot make tail ++ * items and extent items grandparent-major-packed, though you could make them ++ * self-major-packed (usually they are parent-major-packed). ++ * ++ * In the case of ACLs (which are composed of fixed length ACEs which consist ++ * of {subject-type, subject, and permission bitmask} triples), it makes sense ++ * to not have an offset field in the ACE item key, and to allow duplicate keys ++ * for ACEs. Thus, the set of ACES for a given file is found by looking for a ++ * key consisting of the objectid of the grandparent (thus grouping all ACLs in ++ * a directory together), the minor packing locality of ACE, the objectid of ++ * the file, and 0. ++ * ++ * IO involves moving data from one location to another, which means that two ++ * locations must be specified, source and destination. ++ * ++ * This source and destination can be in the filesystem, or they can be a ++ * pointer in the user process address space plus a byte count. ++ * ++ * If both source and destination are in the filesystem, then at least one of ++ * them must be representable as a pure stream of bytes (which we call a flow, ++ * and define as a struct containing a key, a data pointer, and a length). ++ * This may mean converting one of them into a flow. We provide a generic ++ * cast_into_flow() method, which will work for any plugin supporting ++ * read_flow(), though it is inefficiently implemented in that it temporarily ++ * stores the flow in a buffer (Question: what to do with huge flows that ++ * cannot fit into memory? Answer: we must not convert them all at once. ) ++ * ++ * Performing a write requires resolving the write request into a flow defining ++ * the source, and a method that performs the write, and a key that defines ++ * where in the tree the write is to go. ++ * ++ * Performing a read requires resolving the read request into a flow defining ++ * the target, and a method that performs the read, and a key that defines ++ * where in the tree the read is to come from. ++ * ++ * There will exist file plugins which have no pluginid stored on the disk for ++ * them, and which are only invoked by other plugins. ++ */ ++ ++/* This should be incremented with each new contributed ++ pair (plugin type, plugin id). ++ NOTE: Make sure there is a release of reiser4progs ++ with the corresponding version number */ ++#define PLUGIN_LIBRARY_VERSION 0 ++ ++ /* enumeration of fields within plugin_set */ ++typedef enum { ++ PSET_FILE, ++ PSET_DIR, /* PSET_FILE and PSET_DIR should be first ++ * elements: inode.c:read_inode() depends on ++ * this. */ ++ PSET_PERM, ++ PSET_FORMATTING, ++ PSET_HASH, ++ PSET_FIBRATION, ++ PSET_SD, ++ PSET_DIR_ITEM, ++ PSET_CIPHER, ++ PSET_DIGEST, ++ PSET_COMPRESSION, ++ PSET_COMPRESSION_MODE, ++ PSET_CLUSTER, ++ PSET_CREATE, ++ PSET_LAST ++} pset_member; ++ ++/* builtin file-plugins */ ++typedef enum { ++ /* regular file */ ++ UNIX_FILE_PLUGIN_ID, ++ /* directory */ ++ DIRECTORY_FILE_PLUGIN_ID, ++ /* symlink */ ++ SYMLINK_FILE_PLUGIN_ID, ++ /* for objects completely handled by the VFS: fifos, devices, ++ sockets */ ++ SPECIAL_FILE_PLUGIN_ID, ++ /* regular cryptcompress file */ ++ CRYPTCOMPRESS_FILE_PLUGIN_ID, ++ /* number of file plugins. Used as size of arrays to hold ++ file plugins. */ ++ LAST_FILE_PLUGIN_ID ++} reiser4_file_id; ++ ++typedef struct file_plugin { ++ ++ /* generic fields */ ++ plugin_header h; ++ ++ /* VFS methods. ++ * Must be invariant with respect to plugin conversion. ++ * It can be achieved by using "common" methods, which ++ * are the same for all plugins that take participation in ++ * conversion, or by using "generic" or "careful" methods, ++ * which provide automatic redirection to proper private ++ * plugin methods ("careful" are the same as "generic", ++ * but with protection of pset and other disk structures ++ * from being rebuilt during conversion. ++ */ ++ struct inode_operations * inode_ops; ++ struct file_operations * file_ops; ++ struct address_space_operations * as_ops; ++ /** ++ * Private methods. These are optional. If used they will allow you ++ * to minimize the amount of code needed to implement a deviation ++ * from some other method that also uses them. ++ */ ++ /* ++ * private inode_ops ++ */ ++ int (*setattr)(struct dentry *, struct iattr *); ++ /* ++ * private file_ops ++ */ ++ /* do whatever is necessary to do when object is opened */ ++ int (*open) (struct inode *inode, struct file *file); ++ ssize_t (*read) (struct file *, char __user *buf, size_t read_amount, ++ loff_t *off); ++ /* write as much as possible bytes from nominated @write_amount ++ * before plugin scheduling is occurred. Save scheduling state ++ * in @cont */ ++ ssize_t (*write) (struct file *, const char __user *buf, ++ size_t write_amount, loff_t * off, ++ struct psched_context * cont); ++ int (*ioctl) (struct inode *inode, struct file *filp, ++ unsigned int cmd, unsigned long arg); ++ int (*mmap) (struct file *, struct vm_area_struct *); ++ int (*release) (struct inode *, struct file *); ++ /* ++ * private a_ops ++ */ ++ int (*readpage) (struct file *file, struct page *page); ++ int (*readpages)(struct file *file, struct address_space *mapping, ++ struct list_head *pages, unsigned nr_pages); ++ int (*writepages)(struct address_space *mapping, ++ struct writeback_control *wbc); ++ int (*write_begin)(struct file *file, struct page *page, ++ unsigned from, unsigned to); ++ int (*write_end)(struct file *file, struct page *page, ++ unsigned from, unsigned to); ++ sector_t (*bmap) (struct address_space * mapping, sector_t lblock); ++ /* other private methods */ ++ /* save inode cached stat-data onto disk. It was called ++ reiserfs_update_sd() in 3.x */ ++ int (*write_sd_by_inode) (struct inode *); ++ /* ++ * Construct flow into @flow according to user-supplied data. ++ * ++ * This is used by read/write methods to construct a flow to ++ * write/read. ->flow_by_inode() is plugin method, rather than single ++ * global implementation, because key in a flow used by plugin may ++ * depend on data in a @buf. ++ * ++ * NIKITA-FIXME-HANS: please create statistics on what functions are ++ * dereferenced how often for the mongo benchmark. You can supervise ++ * Elena doing this for you if that helps. Email me the list of the ++ * top 10, with their counts, and an estimate of the total number of ++ * CPU cycles spent dereferencing as a percentage of CPU cycles spent ++ * processing (non-idle processing). If the total percent is, say, ++ * less than 1%, it will make our coding discussions much easier, and ++ * keep me from questioning whether functions like the below are too ++ * frequently called to be dereferenced. If the total percent is more ++ * than 1%, perhaps private methods should be listed in a "required" ++ * comment at the top of each plugin (with stern language about how if ++ * the comment is missing it will not be accepted by the maintainer), ++ * and implemented using macros not dereferenced functions. How about ++ * replacing this whole private methods part of the struct with a ++ * thorough documentation of what the standard helper functions are for ++ * use in constructing plugins? I think users have been asking for ++ * that, though not in so many words. ++ */ ++ int (*flow_by_inode) (struct inode *, const char __user *buf, ++ int user, loff_t size, ++ loff_t off, rw_op op, flow_t *); ++ /* ++ * Return the key used to retrieve an offset of a file. It is used by ++ * default implementation of ->flow_by_inode() method ++ * (common_build_flow()) and, among other things, to get to the extent ++ * from jnode of unformatted node. ++ */ ++ int (*key_by_inode) (struct inode *, loff_t off, reiser4_key *); ++ ++ /* NIKITA-FIXME-HANS: this comment is not as clear to others as you ++ * think.... */ ++ /* ++ * set the plugin for a file. Called during file creation in creat() ++ * but not reiser4() unless an inode already exists for the file. ++ */ ++ int (*set_plug_in_inode) (struct inode *inode, struct inode *parent, ++ reiser4_object_create_data *); ++ ++ /* NIKITA-FIXME-HANS: comment and name seem to say different things, ++ * are you setting up the object itself also or just adjusting the ++ * parent?.... */ ++ /* set up plugins for new @object created in @parent. @root is root ++ directory. */ ++ int (*adjust_to_parent) (struct inode *object, struct inode *parent, ++ struct inode *root); ++ /* ++ * this does whatever is necessary to do when object is created. For ++ * instance, for unix files stat data is inserted. It is supposed to be ++ * called by create of struct inode_operations. ++ */ ++ int (*create_object) (struct inode *object, struct inode *parent, ++ reiser4_object_create_data *); ++ /* ++ * this method should check REISER4_NO_SD and set REISER4_NO_SD on ++ * success. Deletion of an object usually includes removal of items ++ * building file body (for directories this is removal of "." and "..") ++ * and removal of stat-data item. ++ */ ++ int (*delete_object) (struct inode *); ++ ++ /* add link from @parent to @object */ ++ int (*add_link) (struct inode *object, struct inode *parent); ++ ++ /* remove link from @parent to @object */ ++ int (*rem_link) (struct inode *object, struct inode *parent); ++ ++ /* ++ * return true if item addressed by @coord belongs to @inode. This is ++ * used by read/write to properly slice flow into items in presence of ++ * multiple key assignment policies, because items of a file are not ++ * necessarily contiguous in a key space, for example, in a plan-b. ++ */ ++ int (*owns_item) (const struct inode *, const coord_t *); ++ ++ /* checks whether yet another hard links to this object can be ++ added */ ++ int (*can_add_link) (const struct inode *); ++ ++ /* checks whether hard links to this object can be removed */ ++ int (*can_rem_link) (const struct inode *); ++ ++ /* not empty for DIRECTORY_FILE_PLUGIN_ID only currently. It calls ++ detach of directory plugin to remove ".." */ ++ int (*detach) (struct inode *child, struct inode *parent); ++ ++ /* called when @child was just looked up in the @parent. It is not ++ empty for DIRECTORY_FILE_PLUGIN_ID only where it calls attach of ++ directory plugin */ ++ int (*bind) (struct inode *child, struct inode *parent); ++ ++ /* process safe-link during mount */ ++ int (*safelink) (struct inode *object, reiser4_safe_link_t link, ++ __u64 value); ++ ++ /* The couple of estimate methods for all file operations */ ++ struct { ++ reiser4_block_nr(*create) (const struct inode *); ++ reiser4_block_nr(*update) (const struct inode *); ++ reiser4_block_nr(*unlink) (const struct inode *, ++ const struct inode *); ++ } estimate; ++ ++ /* ++ * reiser4 specific part of inode has a union of structures which are ++ * specific to a plugin. This method is called when inode is read ++ * (read_inode) and when file is created (common_create_child) so that ++ * file plugin could initialize its inode data ++ */ ++ void (*init_inode_data) (struct inode *, reiser4_object_create_data * , ++ int); ++ ++ /* ++ * This method performs progressive deletion of items and whole nodes ++ * from right to left. ++ * ++ * @tap: the point deletion process begins from, ++ * @from_key: the beginning of the deleted key range, ++ * @to_key: the end of the deleted key range, ++ * @smallest_removed: the smallest removed key, ++ * ++ * @return: 0 if success, error code otherwise, -E_REPEAT means that ++ * long cut_tree operation was interrupted for allowing atom commit . ++ */ ++ int (*cut_tree_worker) (tap_t *, const reiser4_key * from_key, ++ const reiser4_key * to_key, ++ reiser4_key * smallest_removed, struct inode *, ++ int, int *); ++ ++ /* called from ->destroy_inode() */ ++ void (*destroy_inode) (struct inode *); ++ ++ /* ++ * methods to serialize object identify. This is used, for example, by ++ * reiser4_{en,de}code_fh(). ++ */ ++ struct { ++ /* store object's identity at @area */ ++ char *(*write) (struct inode *inode, char *area); ++ /* parse object from wire to the @obj */ ++ char *(*read) (char *area, reiser4_object_on_wire * obj); ++ /* given object identity in @obj, find or create its dentry */ ++ struct dentry *(*get) (struct super_block *s, ++ reiser4_object_on_wire * obj); ++ /* how many bytes ->wire.write() consumes */ ++ int (*size) (struct inode *inode); ++ /* finish with object identify */ ++ void (*done) (reiser4_object_on_wire * obj); ++ } wire; ++} file_plugin; ++ ++extern file_plugin file_plugins[LAST_FILE_PLUGIN_ID]; ++ ++struct reiser4_object_on_wire { ++ file_plugin *plugin; ++ union { ++ struct { ++ obj_key_id key_id; ++ } std; ++ void *generic; ++ } u; ++}; ++ ++/* builtin dir-plugins */ ++typedef enum { ++ HASHED_DIR_PLUGIN_ID, ++ SEEKABLE_HASHED_DIR_PLUGIN_ID, ++ LAST_DIR_ID ++} reiser4_dir_id; ++ ++typedef struct dir_plugin { ++ /* generic fields */ ++ plugin_header h; ++ ++ struct inode_operations * inode_ops; ++ struct file_operations * file_ops; ++ struct address_space_operations * as_ops; ++ ++ /* ++ * private methods: These are optional. If used they will allow you to ++ * minimize the amount of code needed to implement a deviation from ++ * some other method that uses them. You could logically argue that ++ * they should be a separate type of plugin. ++ */ ++ ++ struct dentry *(*get_parent) (struct inode *childdir); ++ ++ /* ++ * check whether "name" is acceptable name to be inserted into this ++ * object. Optionally implemented by directory-like objects. Can check ++ * for maximal length, reserved symbols etc ++ */ ++ int (*is_name_acceptable) (const struct inode *inode, const char *name, ++ int len); ++ ++ void (*build_entry_key) (const struct inode *dir /* directory where ++ * entry is (or will ++ * be) in.*/ , ++ const struct qstr *name /* name of file ++ * referenced by this ++ * entry */ , ++ reiser4_key * result /* resulting key of ++ * directory entry */ ); ++ int (*build_readdir_key) (struct file *dir, reiser4_key * result); ++ int (*add_entry) (struct inode *object, struct dentry *where, ++ reiser4_object_create_data * data, ++ reiser4_dir_entry_desc * entry); ++ int (*rem_entry) (struct inode *object, struct dentry *where, ++ reiser4_dir_entry_desc * entry); ++ ++ /* ++ * initialize directory structure for newly created object. For normal ++ * unix directories, insert dot and dotdot. ++ */ ++ int (*init) (struct inode *object, struct inode *parent, ++ reiser4_object_create_data * data); ++ ++ /* destroy directory */ ++ int (*done) (struct inode *child); ++ ++ /* called when @subdir was just looked up in the @dir */ ++ int (*attach) (struct inode *subdir, struct inode *dir); ++ int (*detach) (struct inode *subdir, struct inode *dir); ++ ++ struct { ++ reiser4_block_nr(*add_entry) (const struct inode *); ++ reiser4_block_nr(*rem_entry) (const struct inode *); ++ reiser4_block_nr(*unlink) (const struct inode *, ++ const struct inode *); ++ } estimate; ++} dir_plugin; ++ ++extern dir_plugin dir_plugins[LAST_DIR_ID]; ++ ++typedef struct formatting_plugin { ++ /* generic fields */ ++ plugin_header h; ++ /* returns non-zero iff file's tail has to be stored ++ in a direct item. */ ++ int (*have_tail) (const struct inode *inode, loff_t size); ++} formatting_plugin; ++ ++typedef struct hash_plugin { ++ /* generic fields */ ++ plugin_header h; ++ /* computes hash of the given name */ ++ __u64(*hash) (const unsigned char *name, int len); ++} hash_plugin; ++ ++typedef struct cipher_plugin { ++ /* generic fields */ ++ plugin_header h; ++ struct crypto_blkcipher * (*alloc) (void); ++ void (*free) (struct crypto_blkcipher *tfm); ++ /* Offset translator. For each offset this returns (k * offset), where ++ k (k >= 1) is an expansion factor of the cipher algorithm. ++ For all symmetric algorithms k == 1. For asymmetric algorithms (which ++ inflate data) offset translation guarantees that all disk cluster's ++ units will have keys smaller then next cluster's one. ++ */ ++ loff_t(*scale) (struct inode *inode, size_t blocksize, loff_t src); ++ /* Cipher algorithms can accept data only by chunks of cipher block ++ size. This method is to align any flow up to cipher block size when ++ we pass it to cipher algorithm. To align means to append padding of ++ special format specific to the cipher algorithm */ ++ int (*align_stream) (__u8 *tail, int clust_size, int blocksize); ++ /* low-level key manager (check, install, etc..) */ ++ int (*setkey) (struct crypto_tfm *tfm, const __u8 *key, ++ unsigned int keylen); ++ /* main text processing procedures */ ++ void (*encrypt) (__u32 *expkey, __u8 *dst, const __u8 *src); ++ void (*decrypt) (__u32 *expkey, __u8 *dst, const __u8 *src); ++} cipher_plugin; ++ ++typedef struct digest_plugin { ++ /* generic fields */ ++ plugin_header h; ++ /* fingerprint size in bytes */ ++ int fipsize; ++ struct crypto_hash * (*alloc) (void); ++ void (*free) (struct crypto_hash *tfm); ++} digest_plugin; ++ ++typedef struct compression_plugin { ++ /* generic fields */ ++ plugin_header h; ++ int (*init) (void); ++ /* the maximum number of bytes the size of the "compressed" data can ++ * exceed the uncompressed data. */ ++ int (*overrun) (unsigned src_len); ++ coa_t(*alloc) (tfm_action act); ++ void (*free) (coa_t coa, tfm_action act); ++ /* minimal size of the flow we still try to compress */ ++ int (*min_size_deflate) (void); ++ __u32(*checksum) (char *data, __u32 length); ++ /* main transform procedures */ ++ void (*compress) (coa_t coa, __u8 *src_first, unsigned src_len, ++ __u8 *dst_first, unsigned *dst_len); ++ void (*decompress) (coa_t coa, __u8 *src_first, unsigned src_len, ++ __u8 *dst_first, unsigned *dst_len); ++} compression_plugin; ++ ++typedef struct compression_mode_plugin { ++ /* generic fields */ ++ plugin_header h; ++ /* this is called when estimating compressibility ++ of a logical cluster by its content */ ++ int (*should_deflate) (struct inode *inode, cloff_t index); ++ /* this is called when results of compression should be saved */ ++ int (*accept_hook) (struct inode *inode, cloff_t index); ++ /* this is called when results of compression should be discarded */ ++ int (*discard_hook) (struct inode *inode, cloff_t index); ++} compression_mode_plugin; ++ ++typedef struct cluster_plugin { ++ /* generic fields */ ++ plugin_header h; ++ int shift; ++} cluster_plugin; ++ ++typedef struct sd_ext_plugin { ++ /* generic fields */ ++ plugin_header h; ++ int (*present) (struct inode *inode, char **area, int *len); ++ int (*absent) (struct inode *inode); ++ int (*save_len) (struct inode *inode); ++ int (*save) (struct inode *inode, char **area); ++ /* alignment requirement for this stat-data part */ ++ int alignment; ++} sd_ext_plugin; ++ ++/* this plugin contains methods to allocate objectid for newly created files, ++ to deallocate objectid when file gets removed, to report number of used and ++ free objectids */ ++typedef struct oid_allocator_plugin { ++ /* generic fields */ ++ plugin_header h; ++ int (*init_oid_allocator) (reiser4_oid_allocator * map, __u64 nr_files, ++ __u64 oids); ++ /* used to report statfs->f_files */ ++ __u64(*oids_used) (reiser4_oid_allocator * map); ++ /* get next oid to use */ ++ __u64(*next_oid) (reiser4_oid_allocator * map); ++ /* used to report statfs->f_ffree */ ++ __u64(*oids_free) (reiser4_oid_allocator * map); ++ /* allocate new objectid */ ++ int (*allocate_oid) (reiser4_oid_allocator * map, oid_t *); ++ /* release objectid */ ++ int (*release_oid) (reiser4_oid_allocator * map, oid_t); ++ /* how many pages to reserve in transaction for allocation of new ++ objectid */ ++ int (*oid_reserve_allocate) (reiser4_oid_allocator * map); ++ /* how many pages to reserve in transaction for freeing of an ++ objectid */ ++ int (*oid_reserve_release) (reiser4_oid_allocator * map); ++ void (*print_info) (const char *, reiser4_oid_allocator *); ++} oid_allocator_plugin; ++ ++/* disk layout plugin: this specifies super block, journal, bitmap (if there ++ are any) locations, etc */ ++typedef struct disk_format_plugin { ++ /* generic fields */ ++ plugin_header h; ++ /* replay journal, initialize super_info_data, etc */ ++ int (*init_format) (struct super_block *, void *data); ++ ++ /* key of root directory stat data */ ++ const reiser4_key * (*root_dir_key) (const struct super_block *); ++ ++ int (*release) (struct super_block *); ++ jnode * (*log_super) (struct super_block *); ++ int (*check_open) (const struct inode *object); ++ int (*version_update) (struct super_block *); ++} disk_format_plugin; ++ ++struct jnode_plugin { ++ /* generic fields */ ++ plugin_header h; ++ int (*init) (jnode * node); ++ int (*parse) (jnode * node); ++ struct address_space *(*mapping) (const jnode * node); ++ unsigned long (*index) (const jnode * node); ++ jnode * (*clone) (jnode * node); ++}; ++ ++/* plugin instance. */ ++/* */ ++/* This is "wrapper" union for all types of plugins. Most of the code uses */ ++/* plugins of particular type (file_plugin, dir_plugin, etc.) rather than */ ++/* operates with pointers to reiser4_plugin. This union is only used in */ ++/* some generic code in plugin/plugin.c that operates on all */ ++/* plugins. Technically speaking purpose of this union is to add type */ ++/* safety to said generic code: each plugin type (file_plugin, for */ ++/* example), contains plugin_header as its first memeber. This first member */ ++/* is located at the same place in memory as .h member of */ ++/* reiser4_plugin. Generic code, obtains pointer to reiser4_plugin and */ ++/* looks in the .h which is header of plugin type located in union. This */ ++/* allows to avoid type-casts. */ ++union reiser4_plugin { ++ /* generic fields */ ++ plugin_header h; ++ /* file plugin */ ++ file_plugin file; ++ /* directory plugin */ ++ dir_plugin dir; ++ /* hash plugin, used by directory plugin */ ++ hash_plugin hash; ++ /* fibration plugin used by directory plugin */ ++ fibration_plugin fibration; ++ /* cipher transform plugin, used by file plugin */ ++ cipher_plugin cipher; ++ /* digest transform plugin, used by file plugin */ ++ digest_plugin digest; ++ /* compression transform plugin, used by file plugin */ ++ compression_plugin compression; ++ /* tail plugin, used by file plugin */ ++ formatting_plugin formatting; ++ /* permission plugin */ ++ perm_plugin perm; ++ /* node plugin */ ++ node_plugin node; ++ /* item plugin */ ++ item_plugin item; ++ /* stat-data extension plugin */ ++ sd_ext_plugin sd_ext; ++ /* disk layout plugin */ ++ disk_format_plugin format; ++ /* object id allocator plugin */ ++ oid_allocator_plugin oid_allocator; ++ /* plugin for different jnode types */ ++ jnode_plugin jnode; ++ /* compression mode plugin, used by object plugin */ ++ compression_mode_plugin compression_mode; ++ /* cluster plugin, used by object plugin */ ++ cluster_plugin clust; ++ /* place-holder for new plugin types that can be registered ++ dynamically, and used by other dynamically loaded plugins. */ ++ void *generic; ++}; ++ ++struct reiser4_plugin_ops { ++ /* called when plugin is initialized */ ++ int (*init) (reiser4_plugin * plugin); ++ /* called when plugin is unloaded */ ++ int (*done) (reiser4_plugin * plugin); ++ /* load given plugin from disk */ ++ int (*load) (struct inode *inode, ++ reiser4_plugin * plugin, char **area, int *len); ++ /* how many space is required to store this plugin's state ++ in stat-data */ ++ int (*save_len) (struct inode *inode, reiser4_plugin * plugin); ++ /* save persistent plugin-data to disk */ ++ int (*save) (struct inode *inode, reiser4_plugin * plugin, ++ char **area); ++ /* alignment requirement for on-disk state of this plugin ++ in number of bytes */ ++ int alignment; ++ /* install itself into given inode. This can return error ++ (e.g., you cannot change hash of non-empty directory). */ ++ int (*change) (struct inode *inode, reiser4_plugin * plugin, ++ pset_member memb); ++ /* install itself into given inode. This can return error ++ (e.g., you cannot change hash of non-empty directory). */ ++ int (*inherit) (struct inode *inode, struct inode *parent, ++ reiser4_plugin * plugin); ++}; ++ ++/* functions implemented in fs/reiser4/plugin/plugin.c */ ++ ++/* stores plugin reference in reiser4-specific part of inode */ ++extern int set_object_plugin(struct inode *inode, reiser4_plugin_id id); ++extern int init_plugins(void); ++ ++/* builtin plugins */ ++ ++/* builtin hash-plugins */ ++ ++typedef enum { ++ RUPASOV_HASH_ID, ++ R5_HASH_ID, ++ TEA_HASH_ID, ++ FNV1_HASH_ID, ++ DEGENERATE_HASH_ID, ++ LAST_HASH_ID ++} reiser4_hash_id; ++ ++/* builtin cipher plugins */ ++ ++typedef enum { ++ NONE_CIPHER_ID, ++ LAST_CIPHER_ID ++} reiser4_cipher_id; ++ ++/* builtin digest plugins */ ++ ++typedef enum { ++ SHA256_32_DIGEST_ID, ++ LAST_DIGEST_ID ++} reiser4_digest_id; ++ ++/* builtin compression mode plugins */ ++typedef enum { ++ NONE_COMPRESSION_MODE_ID, ++ LATTD_COMPRESSION_MODE_ID, ++ ULTIM_COMPRESSION_MODE_ID, ++ FORCE_COMPRESSION_MODE_ID, ++ CONVX_COMPRESSION_MODE_ID, ++ LAST_COMPRESSION_MODE_ID ++} reiser4_compression_mode_id; ++ ++/* builtin cluster plugins */ ++typedef enum { ++ CLUSTER_64K_ID, ++ CLUSTER_32K_ID, ++ CLUSTER_16K_ID, ++ CLUSTER_8K_ID, ++ CLUSTER_4K_ID, ++ LAST_CLUSTER_ID ++} reiser4_cluster_id; ++ ++/* builtin tail-plugins */ ++ ++typedef enum { ++ NEVER_TAILS_FORMATTING_ID, ++ ALWAYS_TAILS_FORMATTING_ID, ++ SMALL_FILE_FORMATTING_ID, ++ LAST_TAIL_FORMATTING_ID ++} reiser4_formatting_id; ++ ++/* data type used to pack parameters that we pass to vfs object creation ++ function create_object() */ ++struct reiser4_object_create_data { ++ /* plugin to control created object */ ++ reiser4_file_id id; ++ /* mode of regular file, directory or special file */ ++/* what happens if some other sort of perm plugin is in use? */ ++ int mode; ++ /* rdev of special file */ ++ dev_t rdev; ++ /* symlink target */ ++ const char *name; ++ /* add here something for non-standard objects you invent, like ++ query for interpolation file etc. */ ++ ++ struct reiser4_crypto_info *crypto; ++ ++ struct inode *parent; ++ struct dentry *dentry; ++}; ++ ++/* description of directory entry being created/destroyed/sought for ++ ++ It is passed down to the directory plugin and farther to the ++ directory item plugin methods. Creation of new directory is done in ++ several stages: first we search for an entry with the same name, then ++ create new one. reiser4_dir_entry_desc is used to store some information ++ collected at some stage of this process and required later: key of ++ item that we want to insert/delete and pointer to an object that will ++ be bound by the new directory entry. Probably some more fields will ++ be added there. ++ ++*/ ++struct reiser4_dir_entry_desc { ++ /* key of directory entry */ ++ reiser4_key key; ++ /* object bound by this entry. */ ++ struct inode *obj; ++}; ++ ++#define MAX_PLUGIN_TYPE_LABEL_LEN 32 ++#define MAX_PLUGIN_PLUG_LABEL_LEN 32 ++ ++#define PLUGIN_BY_ID(TYPE, ID, FIELD) \ ++static inline TYPE *TYPE ## _by_id(reiser4_plugin_id id) \ ++{ \ ++ reiser4_plugin *plugin = plugin_by_id(ID, id); \ ++ return plugin ? &plugin->FIELD : NULL; \ ++} \ ++static inline TYPE *TYPE ## _by_disk_id(reiser4_tree * tree, d16 *id) \ ++{ \ ++ reiser4_plugin *plugin = plugin_by_disk_id(tree, ID, id); \ ++ return plugin ? &plugin->FIELD : NULL; \ ++} \ ++static inline TYPE *TYPE ## _by_unsafe_id(reiser4_plugin_id id) \ ++{ \ ++ reiser4_plugin *plugin = plugin_by_unsafe_id(ID, id); \ ++ return plugin ? &plugin->FIELD : NULL; \ ++} \ ++static inline reiser4_plugin* TYPE ## _to_plugin(TYPE* plugin) \ ++{ \ ++ return (reiser4_plugin *) plugin; \ ++} \ ++static inline reiser4_plugin_id TYPE ## _id(TYPE* plugin) \ ++{ \ ++ return TYPE ## _to_plugin(plugin)->h.id; \ ++} \ ++typedef struct { int foo; } TYPE ## _plugin_dummy ++ ++PLUGIN_BY_ID(item_plugin, REISER4_ITEM_PLUGIN_TYPE, item); ++PLUGIN_BY_ID(file_plugin, REISER4_FILE_PLUGIN_TYPE, file); ++PLUGIN_BY_ID(dir_plugin, REISER4_DIR_PLUGIN_TYPE, dir); ++PLUGIN_BY_ID(node_plugin, REISER4_NODE_PLUGIN_TYPE, node); ++PLUGIN_BY_ID(sd_ext_plugin, REISER4_SD_EXT_PLUGIN_TYPE, sd_ext); ++PLUGIN_BY_ID(perm_plugin, REISER4_PERM_PLUGIN_TYPE, perm); ++PLUGIN_BY_ID(hash_plugin, REISER4_HASH_PLUGIN_TYPE, hash); ++PLUGIN_BY_ID(fibration_plugin, REISER4_FIBRATION_PLUGIN_TYPE, fibration); ++PLUGIN_BY_ID(cipher_plugin, REISER4_CIPHER_PLUGIN_TYPE, cipher); ++PLUGIN_BY_ID(digest_plugin, REISER4_DIGEST_PLUGIN_TYPE, digest); ++PLUGIN_BY_ID(compression_plugin, REISER4_COMPRESSION_PLUGIN_TYPE, compression); ++PLUGIN_BY_ID(formatting_plugin, REISER4_FORMATTING_PLUGIN_TYPE, formatting); ++PLUGIN_BY_ID(disk_format_plugin, REISER4_FORMAT_PLUGIN_TYPE, format); ++PLUGIN_BY_ID(jnode_plugin, REISER4_JNODE_PLUGIN_TYPE, jnode); ++PLUGIN_BY_ID(compression_mode_plugin, REISER4_COMPRESSION_MODE_PLUGIN_TYPE, ++ compression_mode); ++PLUGIN_BY_ID(cluster_plugin, REISER4_CLUSTER_PLUGIN_TYPE, clust); ++ ++extern int save_plugin_id(reiser4_plugin * plugin, d16 * area); ++ ++extern struct list_head *get_plugin_list(reiser4_plugin_type type_id); ++ ++#define for_all_plugins(ptype, plugin) \ ++for (plugin = list_entry(get_plugin_list(ptype)->next, reiser4_plugin, h.linkage); \ ++ get_plugin_list(ptype) != &plugin->h.linkage; \ ++ plugin = list_entry(plugin->h.linkage.next, reiser4_plugin, h.linkage)) ++ ++ ++extern int grab_plugin_pset(struct inode *self, struct inode *ancestor, ++ pset_member memb); ++extern int force_plugin_pset(struct inode *self, pset_member memb, ++ reiser4_plugin *plug); ++extern int finish_pset(struct inode *inode); ++ ++/* defined in fs/reiser4/plugin/object.c */ ++extern file_plugin file_plugins[LAST_FILE_PLUGIN_ID]; ++/* defined in fs/reiser4/plugin/object.c */ ++extern dir_plugin dir_plugins[LAST_DIR_ID]; ++/* defined in fs/reiser4/plugin/item/static_stat.c */ ++extern sd_ext_plugin sd_ext_plugins[LAST_SD_EXTENSION]; ++/* defined in fs/reiser4/plugin/hash.c */ ++extern hash_plugin hash_plugins[LAST_HASH_ID]; ++/* defined in fs/reiser4/plugin/fibration.c */ ++extern fibration_plugin fibration_plugins[LAST_FIBRATION_ID]; ++/* defined in fs/reiser4/plugin/crypt.c */ ++extern cipher_plugin cipher_plugins[LAST_CIPHER_ID]; ++/* defined in fs/reiser4/plugin/digest.c */ ++extern digest_plugin digest_plugins[LAST_DIGEST_ID]; ++/* defined in fs/reiser4/plugin/compress/compress.c */ ++extern compression_plugin compression_plugins[LAST_COMPRESSION_ID]; ++/* defined in fs/reiser4/plugin/compress/compression_mode.c */ ++extern compression_mode_plugin ++compression_mode_plugins[LAST_COMPRESSION_MODE_ID]; ++/* defined in fs/reiser4/plugin/cluster.c */ ++extern cluster_plugin cluster_plugins[LAST_CLUSTER_ID]; ++/* defined in fs/reiser4/plugin/tail.c */ ++extern formatting_plugin formatting_plugins[LAST_TAIL_FORMATTING_ID]; ++/* defined in fs/reiser4/plugin/security/security.c */ ++extern perm_plugin perm_plugins[LAST_PERM_ID]; ++/* defined in fs/reiser4/plugin/item/item.c */ ++extern item_plugin item_plugins[LAST_ITEM_ID]; ++/* defined in fs/reiser4/plugin/node/node.c */ ++extern node_plugin node_plugins[LAST_NODE_ID]; ++/* defined in fs/reiser4/plugin/disk_format/disk_format.c */ ++extern disk_format_plugin format_plugins[LAST_FORMAT_ID]; ++ ++/* __FS_REISER4_PLUGIN_TYPES_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/plugin_header.h linux-2.6.30/fs/reiser4/plugin/plugin_header.h +--- linux-2.6.30.orig/fs/reiser4/plugin/plugin_header.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/plugin_header.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,157 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* plugin header. Data structures required by all plugin types. */ ++ ++#if !defined(__PLUGIN_HEADER_H__) ++#define __PLUGIN_HEADER_H__ ++ ++/* plugin data-types and constants */ ++ ++#include "../debug.h" ++#include "../dformat.h" ++ ++/* Every plugin type can be considered as a class of virtual objects ++ {(type, i) | i = 0, 1, ...}, which has one the following categories ++ of virtualization: ++ A - no virtualization; ++ F - per-file virtualization; ++ S - per-superblock virtualization; ++ FIXME-EDWARD: Define every such category */ ++ ++/* Supported plugin types: (id, (virtualization category), short description) */ ++typedef enum { ++ REISER4_FILE_PLUGIN_TYPE, /* (F) service VFS enry-points */ ++ REISER4_DIR_PLUGIN_TYPE, /* (F) service VFS enry-points */ ++ REISER4_ITEM_PLUGIN_TYPE, /* (F) manage items */ ++ REISER4_NODE_PLUGIN_TYPE, /* (S) manage formatted nodes */ ++ REISER4_HASH_PLUGIN_TYPE, /* (F) compute hash */ ++ REISER4_FIBRATION_PLUGIN_TYPE, /* (F) directory fibrations */ ++ REISER4_FORMATTING_PLUGIN_TYPE, /* (F) tail-packing policy */ ++ REISER4_PERM_PLUGIN_TYPE, /* stub (vacancy) */ ++ REISER4_SD_EXT_PLUGIN_TYPE, /* (A) stat-data extensions */ ++ REISER4_FORMAT_PLUGIN_TYPE, /* (S) specify disk format */ ++ REISER4_JNODE_PLUGIN_TYPE, /* (A) in-memory node headers */ ++ REISER4_CIPHER_PLUGIN_TYPE, /* (F) cipher transform algs */ ++ REISER4_DIGEST_PLUGIN_TYPE, /* (F) digest transform algs */ ++ REISER4_COMPRESSION_PLUGIN_TYPE, /* (F) compression tfm algs */ ++ REISER4_COMPRESSION_MODE_PLUGIN_TYPE, /* (F) compression heuristic */ ++ REISER4_CLUSTER_PLUGIN_TYPE, /* (F) size of logical cluster */ ++ REISER4_PLUGIN_TYPES ++} reiser4_plugin_type; ++ ++/* Supported plugin groups */ ++typedef enum { ++ REISER4_DIRECTORY_FILE, ++ REISER4_REGULAR_FILE, ++ REISER4_SYMLINK_FILE, ++ REISER4_SPECIAL_FILE, ++} file_plugin_group; ++ ++struct reiser4_plugin_ops; ++/* generic plugin operations, supported by each ++ plugin type. */ ++typedef struct reiser4_plugin_ops reiser4_plugin_ops; ++ ++/* the common part of all plugin instances. */ ++typedef struct plugin_header { ++ /* plugin type */ ++ reiser4_plugin_type type_id; ++ /* id of this plugin */ ++ reiser4_plugin_id id; ++ /* bitmask of groups the plugin belongs to. */ ++ reiser4_plugin_groups groups; ++ /* plugin operations */ ++ reiser4_plugin_ops *pops; ++/* NIKITA-FIXME-HANS: usage of and access to label and desc is not commented and ++ * defined. */ ++ /* short label of this plugin */ ++ const char *label; ++ /* descriptive string.. */ ++ const char *desc; ++ /* list linkage */ ++ struct list_head linkage; ++} plugin_header; ++ ++#define plugin_of_group(plug, group) (plug->h.groups & (1 << group)) ++ ++/* PRIVATE INTERFACES */ ++/* NIKITA-FIXME-HANS: what is this for and why does it duplicate what is in ++ * plugin_header? */ ++/* plugin type representation. */ ++struct reiser4_plugin_type_data { ++ /* internal plugin type identifier. Should coincide with ++ index of this item in plugins[] array. */ ++ reiser4_plugin_type type_id; ++ /* short symbolic label of this plugin type. Should be no longer ++ than MAX_PLUGIN_TYPE_LABEL_LEN characters including '\0'. */ ++ const char *label; ++ /* plugin type description longer than .label */ ++ const char *desc; ++ ++/* NIKITA-FIXME-HANS: define built-in */ ++ /* number of built-in plugin instances of this type */ ++ int builtin_num; ++ /* array of built-in plugins */ ++ void *builtin; ++ struct list_head plugins_list; ++ size_t size; ++}; ++ ++extern struct reiser4_plugin_type_data plugins[REISER4_PLUGIN_TYPES]; ++ ++int is_plugin_type_valid(reiser4_plugin_type type); ++int is_plugin_id_valid(reiser4_plugin_type type, reiser4_plugin_id id); ++ ++static inline reiser4_plugin *plugin_at(struct reiser4_plugin_type_data *ptype, ++ int i) ++{ ++ char *builtin; ++ ++ builtin = ptype->builtin; ++ return (reiser4_plugin *) (builtin + i * ptype->size); ++} ++ ++/* return plugin by its @type_id and @id */ ++static inline reiser4_plugin *plugin_by_id(reiser4_plugin_type type, ++ reiser4_plugin_id id) ++{ ++ assert("nikita-1651", is_plugin_type_valid(type)); ++ assert("nikita-1652", is_plugin_id_valid(type, id)); ++ return plugin_at(&plugins[type], id); ++} ++ ++extern reiser4_plugin *plugin_by_unsafe_id(reiser4_plugin_type type_id, ++ reiser4_plugin_id id); ++ ++/** ++ * plugin_by_disk_id - get reiser4_plugin ++ * @type_id: plugin type id ++ * @did: plugin id in disk format ++ * ++ * Returns reiser4_plugin by plugin type id an dplugin_id. ++ */ ++static inline reiser4_plugin *plugin_by_disk_id(reiser4_tree * tree UNUSED_ARG, ++ reiser4_plugin_type type_id, ++ __le16 *plugin_id) ++{ ++ /* ++ * what we should do properly is to maintain within each file-system a ++ * dictionary that maps on-disk plugin ids to "universal" ids. This ++ * dictionary will be resolved on mount time, so that this function ++ * will perform just one additional array lookup. ++ */ ++ return plugin_by_unsafe_id(type_id, le16_to_cpu(*plugin_id)); ++} ++ ++/* __PLUGIN_HEADER_H__ */ ++#endif ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/plugin_set.c linux-2.6.30/fs/reiser4/plugin/plugin_set.c +--- linux-2.6.30.orig/fs/reiser4/plugin/plugin_set.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/plugin_set.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,380 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++/* This file contains Reiser4 plugin set operations */ ++ ++/* plugin sets ++ * ++ * Each file in reiser4 is controlled by a whole set of plugins (file plugin, ++ * directory plugin, hash plugin, tail policy plugin, security plugin, etc.) ++ * assigned (inherited, deduced from mode bits, etc.) at creation time. This ++ * set of plugins (so called pset) is described by structure plugin_set (see ++ * plugin/plugin_set.h), which contains pointers to all required plugins. ++ * ++ * Children can inherit some pset members from their parent, however sometimes ++ * it is useful to specify members different from parent ones. Since object's ++ * pset can not be easily changed without fatal consequences, we use for this ++ * purpose another special plugin table (so called hset, or heir set) described ++ * by the same structure. ++ * ++ * Inode only stores a pointers to pset and hset. Different inodes with the ++ * same set of pset (hset) members point to the same pset (hset). This is ++ * archived by storing psets and hsets in global hash table. Races are avoided ++ * by simple (and efficient so far) solution of never recycling psets, even ++ * when last inode pointing to it is destroyed. ++ */ ++ ++#include "../debug.h" ++#include "../super.h" ++#include "plugin_set.h" ++ ++#include <linux/slab.h> ++#include <linux/stddef.h> ++ ++/* slab for plugin sets */ ++static struct kmem_cache *plugin_set_slab; ++ ++static spinlock_t plugin_set_lock[8] __cacheline_aligned_in_smp = { ++ [0 ... 7] = SPIN_LOCK_UNLOCKED ++}; ++ ++/* hash table support */ ++ ++#define PS_TABLE_SIZE (32) ++ ++static inline plugin_set *cast_to(const unsigned long *a) ++{ ++ return container_of(a, plugin_set, hashval); ++} ++ ++static inline int pseq(const unsigned long *a1, const unsigned long *a2) ++{ ++ plugin_set *set1; ++ plugin_set *set2; ++ ++ /* make sure fields are not missed in the code below */ ++ cassert(sizeof *set1 == ++ sizeof set1->hashval + ++ sizeof set1->link + ++ sizeof set1->file + ++ sizeof set1->dir + ++ sizeof set1->perm + ++ sizeof set1->formatting + ++ sizeof set1->hash + ++ sizeof set1->fibration + ++ sizeof set1->sd + ++ sizeof set1->dir_item + ++ sizeof set1->cipher + ++ sizeof set1->digest + ++ sizeof set1->compression + ++ sizeof set1->compression_mode + ++ sizeof set1->cluster + ++ sizeof set1->create); ++ ++ set1 = cast_to(a1); ++ set2 = cast_to(a2); ++ return ++ set1->hashval == set2->hashval && ++ set1->file == set2->file && ++ set1->dir == set2->dir && ++ set1->perm == set2->perm && ++ set1->formatting == set2->formatting && ++ set1->hash == set2->hash && ++ set1->fibration == set2->fibration && ++ set1->sd == set2->sd && ++ set1->dir_item == set2->dir_item && ++ set1->cipher == set2->cipher && ++ set1->digest == set2->digest && ++ set1->compression == set2->compression && ++ set1->compression_mode == set2->compression_mode && ++ set1->cluster == set2->cluster && ++ set1->create == set2->create; ++} ++ ++#define HASH_FIELD(hash, set, field) \ ++({ \ ++ (hash) += (unsigned long)(set)->field >> 2; \ ++}) ++ ++static inline unsigned long calculate_hash(const plugin_set * set) ++{ ++ unsigned long result; ++ ++ result = 0; ++ HASH_FIELD(result, set, file); ++ HASH_FIELD(result, set, dir); ++ HASH_FIELD(result, set, perm); ++ HASH_FIELD(result, set, formatting); ++ HASH_FIELD(result, set, hash); ++ HASH_FIELD(result, set, fibration); ++ HASH_FIELD(result, set, sd); ++ HASH_FIELD(result, set, dir_item); ++ HASH_FIELD(result, set, cipher); ++ HASH_FIELD(result, set, digest); ++ HASH_FIELD(result, set, compression); ++ HASH_FIELD(result, set, compression_mode); ++ HASH_FIELD(result, set, cluster); ++ HASH_FIELD(result, set, create); ++ return result & (PS_TABLE_SIZE - 1); ++} ++ ++static inline unsigned long ++pshash(ps_hash_table * table, const unsigned long *a) ++{ ++ return *a; ++} ++ ++/* The hash table definition */ ++#define KMALLOC(size) kmalloc((size), reiser4_ctx_gfp_mask_get()) ++#define KFREE(ptr, size) kfree(ptr) ++TYPE_SAFE_HASH_DEFINE(ps, plugin_set, unsigned long, hashval, link, pshash, ++ pseq); ++#undef KFREE ++#undef KMALLOC ++ ++static ps_hash_table ps_table; ++static plugin_set empty_set = { ++ .hashval = 0, ++ .file = NULL, ++ .dir = NULL, ++ .perm = NULL, ++ .formatting = NULL, ++ .hash = NULL, ++ .fibration = NULL, ++ .sd = NULL, ++ .dir_item = NULL, ++ .cipher = NULL, ++ .digest = NULL, ++ .compression = NULL, ++ .compression_mode = NULL, ++ .cluster = NULL, ++ .create = NULL, ++ .link = {NULL} ++}; ++ ++plugin_set *plugin_set_get_empty(void) ++{ ++ return &empty_set; ++} ++ ++void plugin_set_put(plugin_set * set) ++{ ++} ++ ++static inline unsigned long *pset_field(plugin_set * set, int offset) ++{ ++ return (unsigned long *)(((char *)set) + offset); ++} ++ ++static int plugin_set_field(plugin_set ** set, const unsigned long val, ++ const int offset) ++{ ++ unsigned long *spot; ++ spinlock_t *lock; ++ plugin_set replica; ++ plugin_set *twin; ++ plugin_set *psal; ++ plugin_set *orig; ++ ++ assert("nikita-2902", set != NULL); ++ assert("nikita-2904", *set != NULL); ++ ++ spot = pset_field(*set, offset); ++ if (unlikely(*spot == val)) ++ return 0; ++ ++ replica = *(orig = *set); ++ *pset_field(&replica, offset) = val; ++ replica.hashval = calculate_hash(&replica); ++ rcu_read_lock(); ++ twin = ps_hash_find(&ps_table, &replica.hashval); ++ if (unlikely(twin == NULL)) { ++ rcu_read_unlock(); ++ psal = kmem_cache_alloc(plugin_set_slab, ++ reiser4_ctx_gfp_mask_get()); ++ if (psal == NULL) ++ return RETERR(-ENOMEM); ++ *psal = replica; ++ lock = &plugin_set_lock[replica.hashval & 7]; ++ spin_lock(lock); ++ twin = ps_hash_find(&ps_table, &replica.hashval); ++ if (likely(twin == NULL)) { ++ *set = psal; ++ ps_hash_insert_rcu(&ps_table, psal); ++ } else { ++ *set = twin; ++ kmem_cache_free(plugin_set_slab, psal); ++ } ++ spin_unlock(lock); ++ } else { ++ rcu_read_unlock(); ++ *set = twin; ++ } ++ return 0; ++} ++ ++static struct { ++ int offset; ++ reiser4_plugin_groups groups; ++ reiser4_plugin_type type; ++} pset_descr[PSET_LAST] = { ++ [PSET_FILE] = { ++ .offset = offsetof(plugin_set, file), ++ .type = REISER4_FILE_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_DIR] = { ++ .offset = offsetof(plugin_set, dir), ++ .type = REISER4_DIR_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_PERM] = { ++ .offset = offsetof(plugin_set, perm), ++ .type = REISER4_PERM_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_FORMATTING] = { ++ .offset = offsetof(plugin_set, formatting), ++ .type = REISER4_FORMATTING_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_HASH] = { ++ .offset = offsetof(plugin_set, hash), ++ .type = REISER4_HASH_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_FIBRATION] = { ++ .offset = offsetof(plugin_set, fibration), ++ .type = REISER4_FIBRATION_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_SD] = { ++ .offset = offsetof(plugin_set, sd), ++ .type = REISER4_ITEM_PLUGIN_TYPE, ++ .groups = (1 << STAT_DATA_ITEM_TYPE) ++ }, ++ [PSET_DIR_ITEM] = { ++ .offset = offsetof(plugin_set, dir_item), ++ .type = REISER4_ITEM_PLUGIN_TYPE, ++ .groups = (1 << DIR_ENTRY_ITEM_TYPE) ++ }, ++ [PSET_CIPHER] = { ++ .offset = offsetof(plugin_set, cipher), ++ .type = REISER4_CIPHER_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_DIGEST] = { ++ .offset = offsetof(plugin_set, digest), ++ .type = REISER4_DIGEST_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_COMPRESSION] = { ++ .offset = offsetof(plugin_set, compression), ++ .type = REISER4_COMPRESSION_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_COMPRESSION_MODE] = { ++ .offset = offsetof(plugin_set, compression_mode), ++ .type = REISER4_COMPRESSION_MODE_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_CLUSTER] = { ++ .offset = offsetof(plugin_set, cluster), ++ .type = REISER4_CLUSTER_PLUGIN_TYPE, ++ .groups = 0 ++ }, ++ [PSET_CREATE] = { ++ .offset = offsetof(plugin_set, create), ++ .type = REISER4_FILE_PLUGIN_TYPE, ++ .groups = (1 << REISER4_REGULAR_FILE) ++ } ++}; ++ ++#define DEFINE_PSET_OPS(PREFIX) \ ++ reiser4_plugin_type PREFIX##_member_to_type_unsafe(pset_member memb) \ ++{ \ ++ if (memb > PSET_LAST) \ ++ return REISER4_PLUGIN_TYPES; \ ++ return pset_descr[memb].type; \ ++} \ ++ \ ++int PREFIX##_set_unsafe(plugin_set ** set, pset_member memb, \ ++ reiser4_plugin * plugin) \ ++{ \ ++ assert("nikita-3492", set != NULL); \ ++ assert("nikita-3493", *set != NULL); \ ++ assert("nikita-3494", plugin != NULL); \ ++ assert("nikita-3495", 0 <= memb && memb < PSET_LAST); \ ++ assert("nikita-3496", plugin->h.type_id == pset_descr[memb].type); \ ++ \ ++ if (pset_descr[memb].groups) \ ++ if (!(pset_descr[memb].groups & plugin->h.groups)) \ ++ return -EINVAL; \ ++ \ ++ return plugin_set_field(set, \ ++ (unsigned long)plugin, pset_descr[memb].offset); \ ++} \ ++ \ ++reiser4_plugin *PREFIX##_get(plugin_set * set, pset_member memb) \ ++{ \ ++ assert("nikita-3497", set != NULL); \ ++ assert("nikita-3498", 0 <= memb && memb < PSET_LAST); \ ++ \ ++ return *(reiser4_plugin **) (((char *)set) + pset_descr[memb].offset); \ ++} ++ ++DEFINE_PSET_OPS(aset); ++ ++int set_plugin(plugin_set ** set, pset_member memb, reiser4_plugin * plugin) ++{ ++ return plugin_set_field(set, ++ (unsigned long)plugin, pset_descr[memb].offset); ++} ++ ++/** ++ * init_plugin_set - create plugin set cache and hash table ++ * ++ * Initializes slab cache of plugin_set-s and their hash table. It is part of ++ * reiser4 module initialization. ++ */ ++int init_plugin_set(void) ++{ ++ int result; ++ ++ result = ps_hash_init(&ps_table, PS_TABLE_SIZE); ++ if (result == 0) { ++ plugin_set_slab = kmem_cache_create("plugin_set", ++ sizeof(plugin_set), 0, ++ SLAB_HWCACHE_ALIGN, ++ NULL); ++ if (plugin_set_slab == NULL) ++ result = RETERR(-ENOMEM); ++ } ++ return result; ++} ++ ++/** ++ * done_plugin_set - delete plugin_set cache and plugin_set hash table ++ * ++ * This is called on reiser4 module unloading or system shutdown. ++ */ ++void done_plugin_set(void) ++{ ++ plugin_set *cur, *next; ++ ++ for_all_in_htable(&ps_table, ps, cur, next) { ++ ps_hash_remove(&ps_table, cur); ++ kmem_cache_free(plugin_set_slab, cur); ++ } ++ destroy_reiser4_cache(&plugin_set_slab); ++ ps_hash_done(&ps_table); ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 120 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/plugin_set.h linux-2.6.30/fs/reiser4/plugin/plugin_set.h +--- linux-2.6.30.orig/fs/reiser4/plugin/plugin_set.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/plugin_set.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,78 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Reiser4 plugin set definition. ++ See fs/reiser4/plugin/plugin_set.c for details */ ++ ++#if !defined(__PLUGIN_SET_H__) ++#define __PLUGIN_SET_H__ ++ ++#include "../type_safe_hash.h" ++#include "plugin.h" ++ ++#include <linux/rcupdate.h> ++ ++struct plugin_set; ++typedef struct plugin_set plugin_set; ++ ++TYPE_SAFE_HASH_DECLARE(ps, plugin_set); ++ ++struct plugin_set { ++ unsigned long hashval; ++ /* plugin of file */ ++ file_plugin *file; ++ /* plugin of dir */ ++ dir_plugin *dir; ++ /* perm plugin for this file */ ++ perm_plugin *perm; ++ /* tail policy plugin. Only meaningful for regular files */ ++ formatting_plugin *formatting; ++ /* hash plugin. Only meaningful for directories. */ ++ hash_plugin *hash; ++ /* fibration plugin. Only meaningful for directories. */ ++ fibration_plugin *fibration; ++ /* plugin of stat-data */ ++ item_plugin *sd; ++ /* plugin of items a directory is built of */ ++ item_plugin *dir_item; ++ /* cipher plugin */ ++ cipher_plugin *cipher; ++ /* digest plugin */ ++ digest_plugin *digest; ++ /* compression plugin */ ++ compression_plugin *compression; ++ /* compression mode plugin */ ++ compression_mode_plugin *compression_mode; ++ /* cluster plugin */ ++ cluster_plugin *cluster; ++ /* this specifies file plugin of regular children. ++ only meaningful for directories */ ++ file_plugin *create; ++ ps_hash_link link; ++}; ++ ++extern plugin_set *plugin_set_get_empty(void); ++extern void plugin_set_put(plugin_set * set); ++ ++extern int init_plugin_set(void); ++extern void done_plugin_set(void); ++ ++extern reiser4_plugin *aset_get(plugin_set * set, pset_member memb); ++extern int set_plugin(plugin_set ** set, pset_member memb, ++ reiser4_plugin * plugin); ++extern int aset_set_unsafe(plugin_set ** set, pset_member memb, ++ reiser4_plugin * plugin); ++extern reiser4_plugin_type aset_member_to_type_unsafe(pset_member memb); ++ ++/* __PLUGIN_SET_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/security/Makefile linux-2.6.30/fs/reiser4/plugin/security/Makefile +--- linux-2.6.30.orig/fs/reiser4/plugin/security/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/security/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,4 @@ ++obj-$(CONFIG_REISER4_FS) += security_plugins.o ++ ++security_plugins-objs := \ ++ perm.o +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/security/perm.c linux-2.6.30/fs/reiser4/plugin/security/perm.c +--- linux-2.6.30.orig/fs/reiser4/plugin/security/perm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/security/perm.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,33 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* ++ * This file contains implementation of permission plugins. ++ * See the comments in perm.h ++ */ ++ ++#include "../plugin.h" ++#include "../plugin_header.h" ++#include "../../debug.h" ++ ++perm_plugin perm_plugins[LAST_PERM_ID] = { ++ [NULL_PERM_ID] = { ++ .h = { ++ .type_id = REISER4_PERM_PLUGIN_TYPE, ++ .id = NULL_PERM_ID, ++ .pops = NULL, ++ .label = "null", ++ .desc = "stub permission plugin", ++ .linkage = {NULL, NULL} ++ } ++ } ++}; ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/security/perm.h linux-2.6.30/fs/reiser4/plugin/security/perm.h +--- linux-2.6.30.orig/fs/reiser4/plugin/security/perm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/security/perm.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Perm (short for "permissions") plugins common stuff. */ ++ ++#if !defined( __REISER4_PERM_H__ ) ++#define __REISER4_PERM_H__ ++ ++#include "../../forward.h" ++#include "../plugin_header.h" ++ ++#include <linux/types.h> ++ ++/* Definition of permission plugin */ ++/* NIKITA-FIXME-HANS: define what this is targeted for. ++ It does not seem to be intended for use with sys_reiser4. Explain. */ ++ ++/* NOTE-EDWARD: This seems to be intended for deprecated sys_reiser4. ++ Consider it like a temporary "seam" and reserved pset member. ++ If you have something usefull to add, then rename this plugin and add here */ ++typedef struct perm_plugin { ++ /* generic plugin fields */ ++ plugin_header h; ++} perm_plugin; ++ ++typedef enum { NULL_PERM_ID, LAST_PERM_ID } reiser4_perm_id; ++ ++/* __REISER4_PERM_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/space/bitmap.c linux-2.6.30/fs/reiser4/plugin/space/bitmap.c +--- linux-2.6.30.orig/fs/reiser4/plugin/space/bitmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/space/bitmap.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1585 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#include "../../debug.h" ++#include "../../dformat.h" ++#include "../../txnmgr.h" ++#include "../../jnode.h" ++#include "../../block_alloc.h" ++#include "../../tree.h" ++#include "../../super.h" ++#include "../plugin.h" ++#include "space_allocator.h" ++#include "bitmap.h" ++ ++#include <linux/types.h> ++#include <linux/fs.h> /* for struct super_block */ ++#include <linux/mutex.h> ++#include <asm/div64.h> ++ ++/* Proposed (but discarded) optimization: dynamic loading/unloading of bitmap ++ * blocks ++ ++ A useful optimization of reiser4 bitmap handling would be dynamic bitmap ++ blocks loading/unloading which is different from v3.x where all bitmap ++ blocks are loaded at mount time. ++ ++ To implement bitmap blocks unloading we need to count bitmap block usage ++ and detect currently unused blocks allowing them to be unloaded. It is not ++ a simple task since we allow several threads to modify one bitmap block ++ simultaneously. ++ ++ Briefly speaking, the following schema is proposed: we count in special ++ variable associated with each bitmap block. That is for counting of block ++ alloc/dealloc operations on that bitmap block. With a deferred block ++ deallocation feature of reiser4 all those operation will be represented in ++ atom dirty/deleted lists as jnodes for freshly allocated or deleted ++ nodes. ++ ++ So, we increment usage counter for each new node allocated or deleted, and ++ decrement it at atom commit one time for each node from the dirty/deleted ++ atom's list. Of course, freshly allocated node deletion and node reusing ++ from atom deleted (if we do so) list should decrement bitmap usage counter ++ also. ++ ++ This schema seems to be working but that reference counting is ++ not easy to debug. I think we should agree with Hans and do not implement ++ it in v4.0. Current code implements "on-demand" bitmap blocks loading only. ++ ++ For simplicity all bitmap nodes (both commit and working bitmap blocks) are ++ loaded into memory on fs mount time or each bitmap nodes are loaded at the ++ first access to it, the "dont_load_bitmap" mount option controls whether ++ bimtap nodes should be loaded at mount time. Dynamic unloading of bitmap ++ nodes currently is not supported. */ ++ ++#define CHECKSUM_SIZE 4 ++ ++#define BYTES_PER_LONG (sizeof(long)) ++ ++#if BITS_PER_LONG == 64 ++# define LONG_INT_SHIFT (6) ++#else ++# define LONG_INT_SHIFT (5) ++#endif ++ ++#define LONG_INT_MASK (BITS_PER_LONG - 1UL) ++ ++typedef unsigned long ulong_t; ++ ++#define bmap_size(blocksize) ((blocksize) - CHECKSUM_SIZE) ++#define bmap_bit_count(blocksize) (bmap_size(blocksize) << 3) ++ ++/* Block allocation/deallocation are done through special bitmap objects which ++ are allocated in an array at fs mount. */ ++struct bitmap_node { ++ struct mutex mutex; /* long term lock object */ ++ ++ jnode *wjnode; /* j-nodes for WORKING ... */ ++ jnode *cjnode; /* ... and COMMIT bitmap blocks */ ++ ++ bmap_off_t first_zero_bit; /* for skip_busy option implementation */ ++ ++ atomic_t loaded; /* a flag which shows that bnode is loaded ++ * already */ ++}; ++ ++static inline char *bnode_working_data(struct bitmap_node *bnode) ++{ ++ char *data; ++ ++ data = jdata(bnode->wjnode); ++ assert("zam-429", data != NULL); ++ ++ return data + CHECKSUM_SIZE; ++} ++ ++static inline char *bnode_commit_data(const struct bitmap_node *bnode) ++{ ++ char *data; ++ ++ data = jdata(bnode->cjnode); ++ assert("zam-430", data != NULL); ++ ++ return data + CHECKSUM_SIZE; ++} ++ ++static inline __u32 bnode_commit_crc(const struct bitmap_node *bnode) ++{ ++ char *data; ++ ++ data = jdata(bnode->cjnode); ++ assert("vpf-261", data != NULL); ++ ++ return le32_to_cpu(get_unaligned((d32 *)data)); ++} ++ ++static inline void bnode_set_commit_crc(struct bitmap_node *bnode, __u32 crc) ++{ ++ char *data; ++ ++ data = jdata(bnode->cjnode); ++ assert("vpf-261", data != NULL); ++ ++ put_unaligned(cpu_to_le32(crc), (d32 *)data); ++} ++ ++/* ZAM-FIXME-HANS: is the idea that this might be a union someday? having ++ * written the code, does this added abstraction still have */ ++/* ANSWER(Zam): No, the abstractions is in the level above (exact place is the ++ * reiser4_space_allocator structure) */ ++/* ZAM-FIXME-HANS: I don't understand your english in comment above. */ ++/* FIXME-HANS(Zam): I don't understand the questions like "might be a union ++ * someday?". What they about? If there is a reason to have a union, it should ++ * be a union, if not, it should not be a union. "..might be someday" means no ++ * reason. */ ++struct bitmap_allocator_data { ++ /* an array for bitmap blocks direct access */ ++ struct bitmap_node *bitmap; ++}; ++ ++#define get_barray(super) \ ++(((struct bitmap_allocator_data *)(get_super_private(super)->space_allocator.u.generic)) -> bitmap) ++ ++#define get_bnode(super, i) (get_barray(super) + i) ++ ++/* allocate and initialize jnode with JNODE_BITMAP type */ ++static jnode *bnew(void) ++{ ++ jnode *jal = jalloc(); ++ ++ if (jal) ++ jnode_init(jal, current_tree, JNODE_BITMAP); ++ ++ return jal; ++} ++ ++/* this file contains: ++ - bitmap based implementation of space allocation plugin ++ - all the helper functions like set bit, find_first_zero_bit, etc */ ++ ++/* Audited by: green(2002.06.12) */ ++static int find_next_zero_bit_in_word(ulong_t word, int start_bit) ++{ ++ ulong_t mask = 1UL << start_bit; ++ int i = start_bit; ++ ++ while ((word & mask) != 0) { ++ mask <<= 1; ++ if (++i >= BITS_PER_LONG) ++ break; ++ } ++ ++ return i; ++} ++ ++#include <linux/bitops.h> ++ ++#if BITS_PER_LONG == 64 ++ ++#define OFF(addr) (((ulong_t)(addr) & (BYTES_PER_LONG - 1)) << 3) ++#define BASE(addr) ((ulong_t*) ((ulong_t)(addr) & ~(BYTES_PER_LONG - 1))) ++ ++static inline void reiser4_set_bit(int nr, void *addr) ++{ ++ ext2_set_bit(nr + OFF(addr), BASE(addr)); ++} ++ ++static inline void reiser4_clear_bit(int nr, void *addr) ++{ ++ ext2_clear_bit(nr + OFF(addr), BASE(addr)); ++} ++ ++static inline int reiser4_test_bit(int nr, void *addr) ++{ ++ return ext2_test_bit(nr + OFF(addr), BASE(addr)); ++} ++static inline int reiser4_find_next_zero_bit(void *addr, int maxoffset, ++ int offset) ++{ ++ int off = OFF(addr); ++ ++ return ext2_find_next_zero_bit(BASE(addr), maxoffset + off, ++ offset + off) - off; ++} ++ ++#else ++ ++#define reiser4_set_bit(nr, addr) ext2_set_bit(nr, addr) ++#define reiser4_clear_bit(nr, addr) ext2_clear_bit(nr, addr) ++#define reiser4_test_bit(nr, addr) ext2_test_bit(nr, addr) ++ ++#define reiser4_find_next_zero_bit(addr, maxoffset, offset) \ ++ext2_find_next_zero_bit(addr, maxoffset, offset) ++#endif ++ ++/* Search for a set bit in the bit array [@start_offset, @max_offset[, offsets ++ * are counted from @addr, return the offset of the first bit if it is found, ++ * @maxoffset otherwise. */ ++static bmap_off_t __reiser4_find_next_set_bit(void *addr, bmap_off_t max_offset, ++ bmap_off_t start_offset) ++{ ++ ulong_t *base = addr; ++ /* start_offset is in bits, convert it to byte offset within bitmap. */ ++ int word_nr = start_offset >> LONG_INT_SHIFT; ++ /* bit number within the byte. */ ++ int bit_nr = start_offset & LONG_INT_MASK; ++ int max_word_nr = (max_offset - 1) >> LONG_INT_SHIFT; ++ ++ assert("zam-387", max_offset != 0); ++ ++ /* Unaligned @start_offset case. */ ++ if (bit_nr != 0) { ++ bmap_nr_t nr; ++ ++ nr = find_next_zero_bit_in_word(~(base[word_nr]), bit_nr); ++ ++ if (nr < BITS_PER_LONG) ++ return (word_nr << LONG_INT_SHIFT) + nr; ++ ++ ++word_nr; ++ } ++ ++ /* Fast scan trough aligned words. */ ++ while (word_nr <= max_word_nr) { ++ if (base[word_nr] != 0) { ++ return (word_nr << LONG_INT_SHIFT) ++ + find_next_zero_bit_in_word(~(base[word_nr]), 0); ++ } ++ ++ ++word_nr; ++ } ++ ++ return max_offset; ++} ++ ++#if BITS_PER_LONG == 64 ++ ++static bmap_off_t reiser4_find_next_set_bit(void *addr, bmap_off_t max_offset, ++ bmap_off_t start_offset) ++{ ++ bmap_off_t off = OFF(addr); ++ ++ return __reiser4_find_next_set_bit(BASE(addr), max_offset + off, ++ start_offset + off) - off; ++} ++ ++#else ++#define reiser4_find_next_set_bit(addr, max_offset, start_offset) \ ++ __reiser4_find_next_set_bit(addr, max_offset, start_offset) ++#endif ++ ++/* search for the first set bit in single word. */ ++static int find_last_set_bit_in_word(ulong_t word, int start_bit) ++{ ++ ulong_t bit_mask; ++ int nr = start_bit; ++ ++ assert("zam-965", start_bit < BITS_PER_LONG); ++ assert("zam-966", start_bit >= 0); ++ ++ bit_mask = (1UL << nr); ++ ++ while (bit_mask != 0) { ++ if (bit_mask & word) ++ return nr; ++ bit_mask >>= 1; ++ nr--; ++ } ++ return BITS_PER_LONG; ++} ++ ++/* Search bitmap for a set bit in backward direction from the end to the ++ * beginning of given region ++ * ++ * @result: result offset of the last set bit ++ * @addr: base memory address, ++ * @low_off: low end of the search region, edge bit included into the region, ++ * @high_off: high end of the search region, edge bit included into the region, ++ * ++ * @return: 0 - set bit was found, -1 otherwise. ++ */ ++static int ++reiser4_find_last_set_bit(bmap_off_t * result, void *addr, bmap_off_t low_off, ++ bmap_off_t high_off) ++{ ++ ulong_t *base = addr; ++ int last_word; ++ int first_word; ++ int last_bit; ++ int nr; ++ ++ assert("zam-962", high_off >= low_off); ++ ++ last_word = high_off >> LONG_INT_SHIFT; ++ last_bit = high_off & LONG_INT_MASK; ++ first_word = low_off >> LONG_INT_SHIFT; ++ ++ if (last_bit < BITS_PER_LONG) { ++ nr = find_last_set_bit_in_word(base[last_word], last_bit); ++ if (nr < BITS_PER_LONG) { ++ *result = (last_word << LONG_INT_SHIFT) + nr; ++ return 0; ++ } ++ --last_word; ++ } ++ while (last_word >= first_word) { ++ if (base[last_word] != 0x0) { ++ last_bit = ++ find_last_set_bit_in_word(base[last_word], ++ BITS_PER_LONG - 1); ++ assert("zam-972", last_bit < BITS_PER_LONG); ++ *result = (last_word << LONG_INT_SHIFT) + last_bit; ++ return 0; ++ } ++ --last_word; ++ } ++ ++ return -1; /* set bit not found */ ++} ++ ++/* Search bitmap for a clear bit in backward direction from the end to the ++ * beginning of given region */ ++static int ++reiser4_find_last_zero_bit(bmap_off_t * result, void *addr, bmap_off_t low_off, ++ bmap_off_t high_off) ++{ ++ ulong_t *base = addr; ++ int last_word; ++ int first_word; ++ int last_bit; ++ int nr; ++ ++ last_word = high_off >> LONG_INT_SHIFT; ++ last_bit = high_off & LONG_INT_MASK; ++ first_word = low_off >> LONG_INT_SHIFT; ++ ++ if (last_bit < BITS_PER_LONG) { ++ nr = find_last_set_bit_in_word(~base[last_word], last_bit); ++ if (nr < BITS_PER_LONG) { ++ *result = (last_word << LONG_INT_SHIFT) + nr; ++ return 0; ++ } ++ --last_word; ++ } ++ while (last_word >= first_word) { ++ if (base[last_word] != (ulong_t) (-1)) { ++ *result = (last_word << LONG_INT_SHIFT) + ++ find_last_set_bit_in_word(~base[last_word], ++ BITS_PER_LONG - 1); ++ return 0; ++ } ++ --last_word; ++ } ++ ++ return -1; /* zero bit not found */ ++} ++ ++/* Audited by: green(2002.06.12) */ ++static void reiser4_clear_bits(char *addr, bmap_off_t start, bmap_off_t end) ++{ ++ int first_byte; ++ int last_byte; ++ ++ unsigned char first_byte_mask = 0xFF; ++ unsigned char last_byte_mask = 0xFF; ++ ++ assert("zam-410", start < end); ++ ++ first_byte = start >> 3; ++ last_byte = (end - 1) >> 3; ++ ++ if (last_byte > first_byte + 1) ++ memset(addr + first_byte + 1, 0, ++ (size_t) (last_byte - first_byte - 1)); ++ ++ first_byte_mask >>= 8 - (start & 0x7); ++ last_byte_mask <<= ((end - 1) & 0x7) + 1; ++ ++ if (first_byte == last_byte) { ++ addr[first_byte] &= (first_byte_mask | last_byte_mask); ++ } else { ++ addr[first_byte] &= first_byte_mask; ++ addr[last_byte] &= last_byte_mask; ++ } ++} ++ ++/* Audited by: green(2002.06.12) */ ++/* ZAM-FIXME-HANS: comment this */ ++static void reiser4_set_bits(char *addr, bmap_off_t start, bmap_off_t end) ++{ ++ int first_byte; ++ int last_byte; ++ ++ unsigned char first_byte_mask = 0xFF; ++ unsigned char last_byte_mask = 0xFF; ++ ++ assert("zam-386", start < end); ++ ++ first_byte = start >> 3; ++ last_byte = (end - 1) >> 3; ++ ++ if (last_byte > first_byte + 1) ++ memset(addr + first_byte + 1, 0xFF, ++ (size_t) (last_byte - first_byte - 1)); ++ ++ first_byte_mask <<= start & 0x7; ++ last_byte_mask >>= 7 - ((end - 1) & 0x7); ++ ++ if (first_byte == last_byte) { ++ addr[first_byte] |= (first_byte_mask & last_byte_mask); ++ } else { ++ addr[first_byte] |= first_byte_mask; ++ addr[last_byte] |= last_byte_mask; ++ } ++} ++ ++#define ADLER_BASE 65521 ++#define ADLER_NMAX 5552 ++ ++/* Calculates the adler32 checksum for the data pointed by `data` of the ++ length `len`. This function was originally taken from zlib, version 1.1.3, ++ July 9th, 1998. ++ ++ Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++ Jean-loup Gailly Mark Adler ++ jloup@gzip.org madler@alumni.caltech.edu ++ ++ The above comment applies only to the reiser4_adler32 function. ++*/ ++ ++__u32 reiser4_adler32(char *data, __u32 len) ++{ ++ unsigned char *t = data; ++ __u32 s1 = 1; ++ __u32 s2 = 0; ++ int k; ++ ++ while (len > 0) { ++ k = len < ADLER_NMAX ? len : ADLER_NMAX; ++ len -= k; ++ ++ while (k--) { ++ s1 += *t++; ++ s2 += s1; ++ } ++ ++ s1 %= ADLER_BASE; ++ s2 %= ADLER_BASE; ++ } ++ return (s2 << 16) | s1; ++} ++ ++#define sb_by_bnode(bnode) \ ++ ((struct super_block *)jnode_get_tree(bnode->wjnode)->super) ++ ++static __u32 bnode_calc_crc(const struct bitmap_node *bnode, unsigned long size) ++{ ++ return reiser4_adler32(bnode_commit_data(bnode), bmap_size(size)); ++} ++ ++static int ++bnode_check_adler32(const struct bitmap_node *bnode, unsigned long size) ++{ ++ if (bnode_calc_crc(bnode, size) != bnode_commit_crc(bnode)) { ++ bmap_nr_t bmap; ++ ++ bmap = bnode - get_bnode(sb_by_bnode(bnode), 0); ++ ++ warning("vpf-263", ++ "Checksum for the bitmap block %llu is incorrect", ++ bmap); ++ ++ return RETERR(-EIO); ++ } ++ ++ return 0; ++} ++ ++#define REISER4_CHECK_BMAP_CRC (0) ++ ++#if REISER4_CHECK_BMAP_CRC ++static int bnode_check_crc(const struct bitmap_node *bnode) ++{ ++ return bnode_check_adler32(bnode, ++ bmap_size(sb_by_bnode(bnode)->s_blocksize)); ++} ++ ++/* REISER4_CHECK_BMAP_CRC */ ++#else ++ ++#define bnode_check_crc(bnode) (0) ++ ++/* REISER4_CHECK_BMAP_CRC */ ++#endif ++ ++/* Recalculates the adler32 checksum for only 1 byte change. ++ adler - previous adler checksum ++ old_data, data - old, new byte values. ++ tail == (chunk - offset) : length, checksum was calculated for, - offset of ++ the changed byte within this chunk. ++ This function can be used for checksum calculation optimisation. ++*/ ++ ++static __u32 ++adler32_recalc(__u32 adler, unsigned char old_data, unsigned char data, ++ __u32 tail) ++{ ++ __u32 delta = data - old_data + 2 * ADLER_BASE; ++ __u32 s1 = adler & 0xffff; ++ __u32 s2 = (adler >> 16) & 0xffff; ++ ++ s1 = (delta + s1) % ADLER_BASE; ++ s2 = (delta * tail + s2) % ADLER_BASE; ++ ++ return (s2 << 16) | s1; ++} ++ ++#define LIMIT(val, boundary) ((val) > (boundary) ? (boundary) : (val)) ++ ++/** ++ * get_nr_bitmap - calculate number of bitmap blocks ++ * @super: super block with initialized blocksize and block count ++ * ++ * Calculates number of bitmap blocks of a filesystem which uses bitmaps to ++ * maintain free disk space. It assumes that each bitmap addresses the same ++ * number of blocks which is calculated by bmap_block_count macro defined in ++ * above. Number of blocks in the filesystem has to be initialized in reiser4 ++ * private data of super block already so that it can be obtained via ++ * reiser4_block_count(). Unfortunately, number of blocks addressed by a bitmap ++ * is not power of 2 because 4 bytes are used for checksum. Therefore, we have ++ * to use special function to divide and modulo 64bits filesystem block ++ * counters. ++ * ++ * Example: suppose filesystem have 32768 blocks. Blocksize is 4096. Each bitmap ++ * block addresses (4096 - 4) * 8 = 32736 blocks. Number of bitmaps to address ++ * all 32768 blocks is calculated as (32768 - 1) / 32736 + 1 = 2. ++ */ ++static bmap_nr_t get_nr_bmap(const struct super_block *super) ++{ ++ u64 quotient; ++ ++ assert("zam-393", reiser4_block_count(super) != 0); ++ ++ quotient = reiser4_block_count(super) - 1; ++ do_div(quotient, bmap_bit_count(super->s_blocksize)); ++ return quotient + 1; ++} ++ ++/** ++ * parse_blocknr - calculate bitmap number and offset in it by block number ++ * @block: pointer to block number to calculate location in bitmap of ++ * @bmap: pointer where to store bitmap block number ++ * @offset: pointer where to store offset within bitmap block ++ * ++ * Calculates location of bit which is responsible for allocation/freeing of ++ * block @*block. That location is represented by bitmap block number and offset ++ * within that bitmap block. ++ */ ++static void ++parse_blocknr(const reiser4_block_nr *block, bmap_nr_t *bmap, ++ bmap_off_t *offset) ++{ ++ struct super_block *super = get_current_context()->super; ++ u64 quotient = *block; ++ ++ *offset = do_div(quotient, bmap_bit_count(super->s_blocksize)); ++ *bmap = quotient; ++ ++ assert("zam-433", *bmap < get_nr_bmap(super)); ++ assert("", *offset < bmap_bit_count(super->s_blocksize)); ++} ++ ++#if REISER4_DEBUG ++/* Audited by: green(2002.06.12) */ ++static void ++check_block_range(const reiser4_block_nr * start, const reiser4_block_nr * len) ++{ ++ struct super_block *sb = reiser4_get_current_sb(); ++ ++ assert("zam-436", sb != NULL); ++ ++ assert("zam-455", start != NULL); ++ assert("zam-437", *start != 0); ++ assert("zam-541", !reiser4_blocknr_is_fake(start)); ++ assert("zam-441", *start < reiser4_block_count(sb)); ++ ++ if (len != NULL) { ++ assert("zam-438", *len != 0); ++ assert("zam-442", *start + *len <= reiser4_block_count(sb)); ++ } ++} ++ ++static void check_bnode_loaded(const struct bitmap_node *bnode) ++{ ++ assert("zam-485", bnode != NULL); ++ assert("zam-483", jnode_page(bnode->wjnode) != NULL); ++ assert("zam-484", jnode_page(bnode->cjnode) != NULL); ++ assert("nikita-2820", jnode_is_loaded(bnode->wjnode)); ++ assert("nikita-2821", jnode_is_loaded(bnode->cjnode)); ++} ++ ++#else ++ ++# define check_block_range(start, len) do { /* nothing */} while(0) ++# define check_bnode_loaded(bnode) do { /* nothing */} while(0) ++ ++#endif ++ ++/* modify bnode->first_zero_bit (if we free bits before); bnode should be ++ spin-locked */ ++static inline void ++adjust_first_zero_bit(struct bitmap_node *bnode, bmap_off_t offset) ++{ ++ if (offset < bnode->first_zero_bit) ++ bnode->first_zero_bit = offset; ++} ++ ++/* return a physical disk address for logical bitmap number @bmap */ ++/* FIXME-VS: this is somehow related to disk layout? */ ++/* ZAM-FIXME-HANS: your answer is? Use not more than one function dereference ++ * per block allocation so that performance is not affected. Probably this ++ * whole file should be considered part of the disk layout plugin, and other ++ * disk layouts can use other defines and efficiency will not be significantly ++ * affected. */ ++ ++#define REISER4_FIRST_BITMAP_BLOCK \ ++ ((REISER4_MASTER_OFFSET / PAGE_CACHE_SIZE) + 2) ++ ++/* Audited by: green(2002.06.12) */ ++static void ++get_bitmap_blocknr(struct super_block *super, bmap_nr_t bmap, ++ reiser4_block_nr * bnr) ++{ ++ ++ assert("zam-390", bmap < get_nr_bmap(super)); ++ ++#ifdef CONFIG_REISER4_BADBLOCKS ++#define BITMAP_PLUGIN_DISKMAP_ID ((0xc0e1<<16) | (0xe0ff)) ++ /* Check if the diskmap have this already, first. */ ++ if (reiser4_get_diskmap_value(BITMAP_PLUGIN_DISKMAP_ID, bmap, bnr) == 0) ++ return; /* Found it in diskmap */ ++#endif ++ /* FIXME_ZAM: before discussing of disk layouts and disk format ++ plugins I implement bitmap location scheme which is close to scheme ++ used in reiser 3.6 */ ++ if (bmap == 0) { ++ *bnr = REISER4_FIRST_BITMAP_BLOCK; ++ } else { ++ *bnr = bmap * bmap_bit_count(super->s_blocksize); ++ } ++} ++ ++/* construct a fake block number for shadow bitmap (WORKING BITMAP) block */ ++/* Audited by: green(2002.06.12) */ ++static void get_working_bitmap_blocknr(bmap_nr_t bmap, reiser4_block_nr * bnr) ++{ ++ *bnr = ++ (reiser4_block_nr) ((bmap & ~REISER4_BLOCKNR_STATUS_BIT_MASK) | ++ REISER4_BITMAP_BLOCKS_STATUS_VALUE); ++} ++ ++/* bnode structure initialization */ ++static void ++init_bnode(struct bitmap_node *bnode, ++ struct super_block *super UNUSED_ARG, bmap_nr_t bmap UNUSED_ARG) ++{ ++ memset(bnode, 0, sizeof(struct bitmap_node)); ++ ++ mutex_init(&bnode->mutex); ++ atomic_set(&bnode->loaded, 0); ++} ++ ++static void release(jnode * node) ++{ ++ jrelse(node); ++ JF_SET(node, JNODE_HEARD_BANSHEE); ++ jput(node); ++} ++ ++/* This function is for internal bitmap.c use because it assumes that jnode is ++ in under full control of this thread */ ++static void done_bnode(struct bitmap_node *bnode) ++{ ++ if (bnode) { ++ atomic_set(&bnode->loaded, 0); ++ if (bnode->wjnode != NULL) ++ release(bnode->wjnode); ++ if (bnode->cjnode != NULL) ++ release(bnode->cjnode); ++ bnode->wjnode = bnode->cjnode = NULL; ++ } ++} ++ ++/* ZAM-FIXME-HANS: comment this. Called only by load_and_lock_bnode()*/ ++static int prepare_bnode(struct bitmap_node *bnode, jnode **cjnode_ret, ++ jnode **wjnode_ret) ++{ ++ struct super_block *super; ++ jnode *cjnode; ++ jnode *wjnode; ++ bmap_nr_t bmap; ++ int ret; ++ ++ super = reiser4_get_current_sb(); ++ ++ *wjnode_ret = wjnode = bnew(); ++ if (wjnode == NULL) { ++ *cjnode_ret = NULL; ++ return RETERR(-ENOMEM); ++ } ++ ++ *cjnode_ret = cjnode = bnew(); ++ if (cjnode == NULL) ++ return RETERR(-ENOMEM); ++ ++ bmap = bnode - get_bnode(super, 0); ++ ++ get_working_bitmap_blocknr(bmap, &wjnode->blocknr); ++ get_bitmap_blocknr(super, bmap, &cjnode->blocknr); ++ ++ jref(cjnode); ++ jref(wjnode); ++ ++ /* load commit bitmap */ ++ ret = jload_gfp(cjnode, GFP_NOFS, 1); ++ ++ if (ret) ++ goto error; ++ ++ /* allocate memory for working bitmap block. Note that for ++ * bitmaps jinit_new() doesn't actually modifies node content, ++ * so parallel calls to this are ok. */ ++ ret = jinit_new(wjnode, GFP_NOFS); ++ ++ if (ret != 0) { ++ jrelse(cjnode); ++ goto error; ++ } ++ ++ return 0; ++ ++ error: ++ jput(cjnode); ++ jput(wjnode); ++ *wjnode_ret = *cjnode_ret = NULL; ++ return ret; ++ ++} ++ ++/* Check the bnode data on read. */ ++static int check_struct_bnode(struct bitmap_node *bnode, __u32 blksize) ++{ ++ void *data; ++ int ret; ++ ++ /* Check CRC */ ++ ret = bnode_check_adler32(bnode, blksize); ++ ++ if (ret) { ++ return ret; ++ } ++ ++ data = jdata(bnode->cjnode) + CHECKSUM_SIZE; ++ ++ /* Check the very first bit -- it must be busy. */ ++ if (!reiser4_test_bit(0, data)) { ++ warning("vpf-1362", "The allocator block %llu is not marked " ++ "as used.", (unsigned long long)bnode->cjnode->blocknr); ++ ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* load bitmap blocks "on-demand" */ ++static int load_and_lock_bnode(struct bitmap_node *bnode) ++{ ++ int ret; ++ ++ jnode *cjnode; ++ jnode *wjnode; ++ ++ assert("nikita-3040", reiser4_schedulable()); ++ ++/* ZAM-FIXME-HANS: since bitmaps are never unloaded, this does not ++ * need to be atomic, right? Just leave a comment that if bitmaps were ++ * unloadable, this would need to be atomic. */ ++ if (atomic_read(&bnode->loaded)) { ++ /* bitmap is already loaded, nothing to do */ ++ check_bnode_loaded(bnode); ++ mutex_lock(&bnode->mutex); ++ assert("nikita-2827", atomic_read(&bnode->loaded)); ++ return 0; ++ } ++ ++ ret = prepare_bnode(bnode, &cjnode, &wjnode); ++ if (ret == 0) { ++ mutex_lock(&bnode->mutex); ++ ++ if (!atomic_read(&bnode->loaded)) { ++ assert("nikita-2822", cjnode != NULL); ++ assert("nikita-2823", wjnode != NULL); ++ assert("nikita-2824", jnode_is_loaded(cjnode)); ++ assert("nikita-2825", jnode_is_loaded(wjnode)); ++ ++ bnode->wjnode = wjnode; ++ bnode->cjnode = cjnode; ++ ++ ret = check_struct_bnode(bnode, current_blocksize); ++ if (!ret) { ++ cjnode = wjnode = NULL; ++ atomic_set(&bnode->loaded, 1); ++ /* working bitmap is initialized by on-disk ++ * commit bitmap. This should be performed ++ * under mutex. */ ++ memcpy(bnode_working_data(bnode), ++ bnode_commit_data(bnode), ++ bmap_size(current_blocksize)); ++ } else ++ mutex_unlock(&bnode->mutex); ++ } else ++ /* race: someone already loaded bitmap while we were ++ * busy initializing data. */ ++ check_bnode_loaded(bnode); ++ } ++ ++ if (wjnode != NULL) { ++ release(wjnode); ++ bnode->wjnode = NULL; ++ } ++ if (cjnode != NULL) { ++ release(cjnode); ++ bnode->cjnode = NULL; ++ } ++ ++ return ret; ++} ++ ++static void release_and_unlock_bnode(struct bitmap_node *bnode) ++{ ++ check_bnode_loaded(bnode); ++ mutex_unlock(&bnode->mutex); ++} ++ ++/* This function does all block allocation work but only for one bitmap ++ block.*/ ++/* FIXME_ZAM: It does not allow us to allocate block ranges across bitmap ++ block responsibility zone boundaries. This had no sense in v3.6 but may ++ have it in v4.x */ ++/* ZAM-FIXME-HANS: do you mean search one bitmap block forward? */ ++static int ++search_one_bitmap_forward(bmap_nr_t bmap, bmap_off_t * offset, ++ bmap_off_t max_offset, int min_len, int max_len) ++{ ++ struct super_block *super = get_current_context()->super; ++ struct bitmap_node *bnode = get_bnode(super, bmap); ++ ++ char *data; ++ ++ bmap_off_t search_end; ++ bmap_off_t start; ++ bmap_off_t end; ++ ++ int set_first_zero_bit = 0; ++ ++ int ret; ++ ++ assert("zam-364", min_len > 0); ++ assert("zam-365", max_len >= min_len); ++ assert("zam-366", *offset <= max_offset); ++ ++ ret = load_and_lock_bnode(bnode); ++ ++ if (ret) ++ return ret; ++ ++ data = bnode_working_data(bnode); ++ ++ start = *offset; ++ ++ if (bnode->first_zero_bit >= start) { ++ start = bnode->first_zero_bit; ++ set_first_zero_bit = 1; ++ } ++ ++ while (start + min_len < max_offset) { ++ ++ start = ++ reiser4_find_next_zero_bit((long *)data, max_offset, start); ++ if (set_first_zero_bit) { ++ bnode->first_zero_bit = start; ++ set_first_zero_bit = 0; ++ } ++ if (start >= max_offset) ++ break; ++ ++ search_end = LIMIT(start + max_len, max_offset); ++ end = ++ reiser4_find_next_set_bit((long *)data, search_end, start); ++ if (end >= start + min_len) { ++ /* we can't trust find_next_set_bit result if set bit ++ was not fount, result may be bigger than ++ max_offset */ ++ if (end > search_end) ++ end = search_end; ++ ++ ret = end - start; ++ *offset = start; ++ ++ reiser4_set_bits(data, start, end); ++ ++ /* FIXME: we may advance first_zero_bit if [start, ++ end] region overlaps the first_zero_bit point */ ++ ++ break; ++ } ++ ++ start = end + 1; ++ } ++ ++ release_and_unlock_bnode(bnode); ++ ++ return ret; ++} ++ ++static int ++search_one_bitmap_backward(bmap_nr_t bmap, bmap_off_t * start_offset, ++ bmap_off_t end_offset, int min_len, int max_len) ++{ ++ struct super_block *super = get_current_context()->super; ++ struct bitmap_node *bnode = get_bnode(super, bmap); ++ char *data; ++ bmap_off_t start; ++ int ret; ++ ++ assert("zam-958", min_len > 0); ++ assert("zam-959", max_len >= min_len); ++ assert("zam-960", *start_offset >= end_offset); ++ ++ ret = load_and_lock_bnode(bnode); ++ if (ret) ++ return ret; ++ ++ data = bnode_working_data(bnode); ++ start = *start_offset; ++ ++ while (1) { ++ bmap_off_t end, search_end; ++ ++ /* Find the beginning of the zero filled region */ ++ if (reiser4_find_last_zero_bit(&start, data, end_offset, start)) ++ break; ++ /* Is there more than `min_len' bits from `start' to ++ * `end_offset'? */ ++ if (start < end_offset + min_len - 1) ++ break; ++ ++ /* Do not search to `end_offset' if we need to find less than ++ * `max_len' zero bits. */ ++ if (end_offset + max_len - 1 < start) ++ search_end = start - max_len + 1; ++ else ++ search_end = end_offset; ++ ++ if (reiser4_find_last_set_bit(&end, data, search_end, start)) ++ end = search_end; ++ else ++ end++; ++ ++ if (end + min_len <= start + 1) { ++ if (end < search_end) ++ end = search_end; ++ ret = start - end + 1; ++ *start_offset = end; /* `end' is lowest offset */ ++ assert("zam-987", ++ reiser4_find_next_set_bit(data, start + 1, ++ end) >= start + 1); ++ reiser4_set_bits(data, end, start + 1); ++ break; ++ } ++ ++ if (end <= end_offset) ++ /* left search boundary reached. */ ++ break; ++ start = end - 1; ++ } ++ ++ release_and_unlock_bnode(bnode); ++ return ret; ++} ++ ++/* allocate contiguous range of blocks in bitmap */ ++static int bitmap_alloc_forward(reiser4_block_nr * start, ++ const reiser4_block_nr * end, int min_len, ++ int max_len) ++{ ++ bmap_nr_t bmap, end_bmap; ++ bmap_off_t offset, end_offset; ++ int len; ++ ++ reiser4_block_nr tmp; ++ ++ struct super_block *super = get_current_context()->super; ++ const bmap_off_t max_offset = bmap_bit_count(super->s_blocksize); ++ ++ parse_blocknr(start, &bmap, &offset); ++ ++ tmp = *end - 1; ++ parse_blocknr(&tmp, &end_bmap, &end_offset); ++ ++end_offset; ++ ++ assert("zam-358", end_bmap >= bmap); ++ assert("zam-359", ergo(end_bmap == bmap, end_offset >= offset)); ++ ++ for (; bmap < end_bmap; bmap++, offset = 0) { ++ len = ++ search_one_bitmap_forward(bmap, &offset, max_offset, ++ min_len, max_len); ++ if (len != 0) ++ goto out; ++ } ++ ++ len = ++ search_one_bitmap_forward(bmap, &offset, end_offset, min_len, ++ max_len); ++ out: ++ *start = bmap * max_offset + offset; ++ return len; ++} ++ ++/* allocate contiguous range of blocks in bitmap (from @start to @end in ++ * backward direction) */ ++static int bitmap_alloc_backward(reiser4_block_nr * start, ++ const reiser4_block_nr * end, int min_len, ++ int max_len) ++{ ++ bmap_nr_t bmap, end_bmap; ++ bmap_off_t offset, end_offset; ++ int len; ++ struct super_block *super = get_current_context()->super; ++ const bmap_off_t max_offset = bmap_bit_count(super->s_blocksize); ++ ++ parse_blocknr(start, &bmap, &offset); ++ parse_blocknr(end, &end_bmap, &end_offset); ++ ++ assert("zam-961", end_bmap <= bmap); ++ assert("zam-962", ergo(end_bmap == bmap, end_offset <= offset)); ++ ++ for (; bmap > end_bmap; bmap--, offset = max_offset - 1) { ++ len = ++ search_one_bitmap_backward(bmap, &offset, 0, min_len, ++ max_len); ++ if (len != 0) ++ goto out; ++ } ++ ++ len = ++ search_one_bitmap_backward(bmap, &offset, end_offset, min_len, ++ max_len); ++ out: ++ *start = bmap * max_offset + offset; ++ return len; ++} ++ ++/* plugin->u.space_allocator.alloc_blocks() */ ++static int alloc_blocks_forward(reiser4_blocknr_hint *hint, int needed, ++ reiser4_block_nr *start, reiser4_block_nr *len) ++{ ++ struct super_block *super = get_current_context()->super; ++ int actual_len; ++ ++ reiser4_block_nr search_start; ++ reiser4_block_nr search_end; ++ ++ assert("zam-398", super != NULL); ++ assert("zam-412", hint != NULL); ++ assert("zam-397", hint->blk <= reiser4_block_count(super)); ++ ++ if (hint->max_dist == 0) ++ search_end = reiser4_block_count(super); ++ else ++ search_end = ++ LIMIT(hint->blk + hint->max_dist, ++ reiser4_block_count(super)); ++ ++ /* We use @hint -> blk as a search start and search from it to the end ++ of the disk or in given region if @hint -> max_dist is not zero */ ++ search_start = hint->blk; ++ ++ actual_len = ++ bitmap_alloc_forward(&search_start, &search_end, 1, needed); ++ ++ /* There is only one bitmap search if max_dist was specified or first ++ pass was from the beginning of the bitmap. We also do one pass for ++ scanning bitmap in backward direction. */ ++ if (!(actual_len != 0 || hint->max_dist != 0 || search_start == 0)) { ++ /* next step is a scanning from 0 to search_start */ ++ search_end = search_start; ++ search_start = 0; ++ actual_len = ++ bitmap_alloc_forward(&search_start, &search_end, 1, needed); ++ } ++ if (actual_len == 0) ++ return RETERR(-ENOSPC); ++ if (actual_len < 0) ++ return RETERR(actual_len); ++ *len = actual_len; ++ *start = search_start; ++ return 0; ++} ++ ++static int alloc_blocks_backward(reiser4_blocknr_hint * hint, int needed, ++ reiser4_block_nr * start, ++ reiser4_block_nr * len) ++{ ++ reiser4_block_nr search_start; ++ reiser4_block_nr search_end; ++ int actual_len; ++ ++ ON_DEBUG(struct super_block *super = reiser4_get_current_sb()); ++ ++ assert("zam-969", super != NULL); ++ assert("zam-970", hint != NULL); ++ assert("zam-971", hint->blk <= reiser4_block_count(super)); ++ ++ search_start = hint->blk; ++ if (hint->max_dist == 0 || search_start <= hint->max_dist) ++ search_end = 0; ++ else ++ search_end = search_start - hint->max_dist; ++ ++ actual_len = ++ bitmap_alloc_backward(&search_start, &search_end, 1, needed); ++ if (actual_len == 0) ++ return RETERR(-ENOSPC); ++ if (actual_len < 0) ++ return RETERR(actual_len); ++ *len = actual_len; ++ *start = search_start; ++ return 0; ++} ++ ++/* plugin->u.space_allocator.alloc_blocks() */ ++int reiser4_alloc_blocks_bitmap(reiser4_space_allocator * allocator, ++ reiser4_blocknr_hint * hint, int needed, ++ reiser4_block_nr * start, reiser4_block_nr * len) ++{ ++ if (hint->backward) ++ return alloc_blocks_backward(hint, needed, start, len); ++ return alloc_blocks_forward(hint, needed, start, len); ++} ++ ++/* plugin->u.space_allocator.dealloc_blocks(). */ ++/* It just frees blocks in WORKING BITMAP. Usually formatted an unformatted ++ nodes deletion is deferred until transaction commit. However, deallocation ++ of temporary objects like wandered blocks and transaction commit records ++ requires immediate node deletion from WORKING BITMAP.*/ ++void reiser4_dealloc_blocks_bitmap(reiser4_space_allocator * allocator, ++ reiser4_block_nr start, reiser4_block_nr len) ++{ ++ struct super_block *super = reiser4_get_current_sb(); ++ ++ bmap_nr_t bmap; ++ bmap_off_t offset; ++ ++ struct bitmap_node *bnode; ++ int ret; ++ ++ assert("zam-468", len != 0); ++ check_block_range(&start, &len); ++ ++ parse_blocknr(&start, &bmap, &offset); ++ ++ assert("zam-469", offset + len <= bmap_bit_count(super->s_blocksize)); ++ ++ bnode = get_bnode(super, bmap); ++ ++ assert("zam-470", bnode != NULL); ++ ++ ret = load_and_lock_bnode(bnode); ++ assert("zam-481", ret == 0); ++ ++ reiser4_clear_bits(bnode_working_data(bnode), offset, ++ (bmap_off_t) (offset + len)); ++ ++ adjust_first_zero_bit(bnode, offset); ++ ++ release_and_unlock_bnode(bnode); ++} ++ ++/* plugin->u.space_allocator.check_blocks(). */ ++void reiser4_check_blocks_bitmap(const reiser4_block_nr * start, ++ const reiser4_block_nr * len, int desired) ++{ ++#if REISER4_DEBUG ++ struct super_block *super = reiser4_get_current_sb(); ++ ++ bmap_nr_t bmap; ++ bmap_off_t start_offset; ++ bmap_off_t end_offset; ++ ++ struct bitmap_node *bnode; ++ int ret; ++ ++ assert("zam-622", len != NULL); ++ check_block_range(start, len); ++ parse_blocknr(start, &bmap, &start_offset); ++ ++ end_offset = start_offset + *len; ++ assert("nikita-2214", end_offset <= bmap_bit_count(super->s_blocksize)); ++ ++ bnode = get_bnode(super, bmap); ++ ++ assert("nikita-2215", bnode != NULL); ++ ++ ret = load_and_lock_bnode(bnode); ++ assert("zam-626", ret == 0); ++ ++ assert("nikita-2216", jnode_is_loaded(bnode->wjnode)); ++ ++ if (desired) { ++ assert("zam-623", ++ reiser4_find_next_zero_bit(bnode_working_data(bnode), ++ end_offset, start_offset) ++ >= end_offset); ++ } else { ++ assert("zam-624", ++ reiser4_find_next_set_bit(bnode_working_data(bnode), ++ end_offset, start_offset) ++ >= end_offset); ++ } ++ ++ release_and_unlock_bnode(bnode); ++#endif ++} ++ ++/* conditional insertion of @node into atom's overwrite set if it was not there */ ++static void cond_add_to_overwrite_set(txn_atom * atom, jnode * node) ++{ ++ assert("zam-546", atom != NULL); ++ assert("zam-547", atom->stage == ASTAGE_PRE_COMMIT); ++ assert("zam-548", node != NULL); ++ ++ spin_lock_atom(atom); ++ spin_lock_jnode(node); ++ ++ if (node->atom == NULL) { ++ JF_SET(node, JNODE_OVRWR); ++ insert_into_atom_ovrwr_list(atom, node); ++ } else { ++ assert("zam-549", node->atom == atom); ++ } ++ ++ spin_unlock_jnode(node); ++ spin_unlock_atom(atom); ++} ++ ++/* an actor which applies delete set to COMMIT bitmap pages and link modified ++ pages in a single-linked list */ ++static int ++apply_dset_to_commit_bmap(txn_atom * atom, const reiser4_block_nr * start, ++ const reiser4_block_nr * len, void *data) ++{ ++ ++ bmap_nr_t bmap; ++ bmap_off_t offset; ++ int ret; ++ ++ long long *blocks_freed_p = data; ++ ++ struct bitmap_node *bnode; ++ ++ struct super_block *sb = reiser4_get_current_sb(); ++ ++ check_block_range(start, len); ++ ++ parse_blocknr(start, &bmap, &offset); ++ ++ /* FIXME-ZAM: we assume that all block ranges are allocated by this ++ bitmap-based allocator and each block range can't go over a zone of ++ responsibility of one bitmap block; same assumption is used in ++ other journal hooks in bitmap code. */ ++ bnode = get_bnode(sb, bmap); ++ assert("zam-448", bnode != NULL); ++ ++ /* it is safe to unlock atom with is in ASTAGE_PRE_COMMIT */ ++ assert("zam-767", atom->stage == ASTAGE_PRE_COMMIT); ++ ret = load_and_lock_bnode(bnode); ++ if (ret) ++ return ret; ++ ++ /* put bnode into atom's overwrite set */ ++ cond_add_to_overwrite_set(atom, bnode->cjnode); ++ ++ data = bnode_commit_data(bnode); ++ ++ ret = bnode_check_crc(bnode); ++ if (ret != 0) ++ return ret; ++ ++ if (len != NULL) { ++ /* FIXME-ZAM: a check that all bits are set should be there */ ++ assert("zam-443", ++ offset + *len <= bmap_bit_count(sb->s_blocksize)); ++ reiser4_clear_bits(data, offset, (bmap_off_t) (offset + *len)); ++ ++ (*blocks_freed_p) += *len; ++ } else { ++ reiser4_clear_bit(offset, data); ++ (*blocks_freed_p)++; ++ } ++ ++ bnode_set_commit_crc(bnode, bnode_calc_crc(bnode, sb->s_blocksize)); ++ ++ release_and_unlock_bnode(bnode); ++ ++ return 0; ++} ++ ++/* plugin->u.space_allocator.pre_commit_hook(). */ ++/* It just applies transaction changes to fs-wide COMMIT BITMAP, hoping the ++ rest is done by transaction manager (allocate wandered locations for COMMIT ++ BITMAP blocks, copy COMMIT BITMAP blocks data). */ ++/* Only one instance of this function can be running at one given time, because ++ only one transaction can be committed a time, therefore it is safe to access ++ some global variables without any locking */ ++ ++int reiser4_pre_commit_hook_bitmap(void) ++{ ++ struct super_block *super = reiser4_get_current_sb(); ++ txn_atom *atom; ++ ++ long long blocks_freed = 0; ++ ++ atom = get_current_atom_locked(); ++ assert("zam-876", atom->stage == ASTAGE_PRE_COMMIT); ++ spin_unlock_atom(atom); ++ ++ { /* scan atom's captured list and find all freshly allocated nodes, ++ * mark corresponded bits in COMMIT BITMAP as used */ ++ struct list_head *head = ATOM_CLEAN_LIST(atom); ++ jnode *node = list_entry(head->next, jnode, capture_link); ++ ++ while (head != &node->capture_link) { ++ /* we detect freshly allocated jnodes */ ++ if (JF_ISSET(node, JNODE_RELOC)) { ++ int ret; ++ bmap_nr_t bmap; ++ ++ bmap_off_t offset; ++ bmap_off_t index; ++ struct bitmap_node *bn; ++ __u32 size = bmap_size(super->s_blocksize); ++ __u32 crc; ++ char byte; ++ ++ assert("zam-559", !JF_ISSET(node, JNODE_OVRWR)); ++ assert("zam-460", ++ !reiser4_blocknr_is_fake(&node->blocknr)); ++ ++ parse_blocknr(&node->blocknr, &bmap, &offset); ++ bn = get_bnode(super, bmap); ++ ++ index = offset >> 3; ++ assert("vpf-276", index < size); ++ ++ ret = bnode_check_crc(bnode); ++ if (ret != 0) ++ return ret; ++ ++ check_bnode_loaded(bn); ++ load_and_lock_bnode(bn); ++ ++ byte = *(bnode_commit_data(bn) + index); ++ reiser4_set_bit(offset, bnode_commit_data(bn)); ++ ++ crc = adler32_recalc(bnode_commit_crc(bn), byte, ++ *(bnode_commit_data(bn) + ++ index), ++ size - index), ++ bnode_set_commit_crc(bn, crc); ++ ++ release_and_unlock_bnode(bn); ++ ++ ret = bnode_check_crc(bn); ++ if (ret != 0) ++ return ret; ++ ++ /* working of this depends on how it inserts ++ new j-node into clean list, because we are ++ scanning the same list now. It is OK, if ++ insertion is done to the list front */ ++ cond_add_to_overwrite_set(atom, bn->cjnode); ++ } ++ ++ node = list_entry(node->capture_link.next, jnode, capture_link); ++ } ++ } ++ ++ blocknr_set_iterator(atom, &atom->delete_set, apply_dset_to_commit_bmap, ++ &blocks_freed, 0); ++ ++ blocks_freed -= atom->nr_blocks_allocated; ++ ++ { ++ reiser4_super_info_data *sbinfo; ++ ++ sbinfo = get_super_private(super); ++ ++ spin_lock_reiser4_super(sbinfo); ++ sbinfo->blocks_free_committed += blocks_freed; ++ spin_unlock_reiser4_super(sbinfo); ++ } ++ ++ return 0; ++} ++ ++/* plugin->u.space_allocator.init_allocator ++ constructor of reiser4_space_allocator object. It is called on fs mount */ ++int reiser4_init_allocator_bitmap(reiser4_space_allocator * allocator, ++ struct super_block *super, void *arg) ++{ ++ struct bitmap_allocator_data *data = NULL; ++ bmap_nr_t bitmap_blocks_nr; ++ bmap_nr_t i; ++ ++ assert("nikita-3039", reiser4_schedulable()); ++ ++ /* getting memory for bitmap allocator private data holder */ ++ data = ++ kmalloc(sizeof(struct bitmap_allocator_data), ++ reiser4_ctx_gfp_mask_get()); ++ ++ if (data == NULL) ++ return RETERR(-ENOMEM); ++ ++ /* allocation and initialization for the array of bnodes */ ++ bitmap_blocks_nr = get_nr_bmap(super); ++ ++ /* FIXME-ZAM: it is not clear what to do with huge number of bitmaps ++ which is bigger than 2^32 (= 8 * 4096 * 4096 * 2^32 bytes = 5.76e+17, ++ may I never meet someone who still uses the ia32 architecture when ++ storage devices of that size enter the market, and wants to use ia32 ++ with that storage device, much less reiser4. ;-) -Hans). Kmalloc is not possible and, ++ probably, another dynamic data structure should replace a static ++ array of bnodes. */ ++ /*data->bitmap = reiser4_kmalloc((size_t) (sizeof (struct bitmap_node) * bitmap_blocks_nr), GFP_KERNEL); */ ++ data->bitmap = reiser4_vmalloc(sizeof(struct bitmap_node) * bitmap_blocks_nr); ++ if (data->bitmap == NULL) { ++ kfree(data); ++ return RETERR(-ENOMEM); ++ } ++ ++ for (i = 0; i < bitmap_blocks_nr; i++) ++ init_bnode(data->bitmap + i, super, i); ++ ++ allocator->u.generic = data; ++ ++#if REISER4_DEBUG ++ get_super_private(super)->min_blocks_used += bitmap_blocks_nr; ++#endif ++ ++ /* Load all bitmap blocks at mount time. */ ++ if (!test_bit ++ (REISER4_DONT_LOAD_BITMAP, &get_super_private(super)->fs_flags)) { ++ __u64 start_time, elapsed_time; ++ struct bitmap_node *bnode; ++ int ret; ++ ++ if (REISER4_DEBUG) ++ printk(KERN_INFO "loading reiser4 bitmap..."); ++ start_time = jiffies; ++ ++ for (i = 0; i < bitmap_blocks_nr; i++) { ++ bnode = data->bitmap + i; ++ ret = load_and_lock_bnode(bnode); ++ if (ret) { ++ reiser4_destroy_allocator_bitmap(allocator, ++ super); ++ return ret; ++ } ++ release_and_unlock_bnode(bnode); ++ } ++ ++ elapsed_time = jiffies - start_time; ++ if (REISER4_DEBUG) ++ printk("...done (%llu jiffies)\n", ++ (unsigned long long)elapsed_time); ++ } ++ ++ return 0; ++} ++ ++/* plugin->u.space_allocator.destroy_allocator ++ destructor. It is called on fs unmount */ ++int reiser4_destroy_allocator_bitmap(reiser4_space_allocator * allocator, ++ struct super_block *super) ++{ ++ bmap_nr_t bitmap_blocks_nr; ++ bmap_nr_t i; ++ ++ struct bitmap_allocator_data *data = allocator->u.generic; ++ ++ assert("zam-414", data != NULL); ++ assert("zam-376", data->bitmap != NULL); ++ ++ bitmap_blocks_nr = get_nr_bmap(super); ++ ++ for (i = 0; i < bitmap_blocks_nr; i++) { ++ struct bitmap_node *bnode = data->bitmap + i; ++ ++ mutex_lock(&bnode->mutex); ++ ++#if REISER4_DEBUG ++ if (atomic_read(&bnode->loaded)) { ++ jnode *wj = bnode->wjnode; ++ jnode *cj = bnode->cjnode; ++ ++ assert("zam-480", jnode_page(cj) != NULL); ++ assert("zam-633", jnode_page(wj) != NULL); ++ ++ assert("zam-634", ++ memcmp(jdata(wj), jdata(wj), ++ bmap_size(super->s_blocksize)) == 0); ++ ++ } ++#endif ++ done_bnode(bnode); ++ mutex_unlock(&bnode->mutex); ++ } ++ ++ vfree(data->bitmap); ++ kfree(data); ++ ++ allocator->u.generic = NULL; ++ ++ return 0; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * scroll-step: 1 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/space/bitmap.h linux-2.6.30/fs/reiser4/plugin/space/bitmap.h +--- linux-2.6.30.orig/fs/reiser4/plugin/space/bitmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/space/bitmap.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,47 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#if !defined (__REISER4_PLUGIN_SPACE_BITMAP_H__) ++#define __REISER4_PLUGIN_SPACE_BITMAP_H__ ++ ++#include "../../dformat.h" ++#include "../../block_alloc.h" ++ ++#include <linux/types.h> /* for __u?? */ ++#include <linux/fs.h> /* for struct super_block */ ++/* EDWARD-FIXME-HANS: write something as informative as the below for every .h file lacking it. */ ++/* declarations of functions implementing methods of space allocator plugin for ++ bitmap based allocator. The functions themselves are in bitmap.c */ ++extern int reiser4_init_allocator_bitmap(reiser4_space_allocator *, ++ struct super_block *, void *); ++extern int reiser4_destroy_allocator_bitmap(reiser4_space_allocator *, ++ struct super_block *); ++extern int reiser4_alloc_blocks_bitmap(reiser4_space_allocator *, ++ reiser4_blocknr_hint *, int needed, ++ reiser4_block_nr * start, ++ reiser4_block_nr * len); ++extern void reiser4_check_blocks_bitmap(const reiser4_block_nr *, ++ const reiser4_block_nr *, int); ++extern void reiser4_dealloc_blocks_bitmap(reiser4_space_allocator *, ++ reiser4_block_nr, ++ reiser4_block_nr); ++extern int reiser4_pre_commit_hook_bitmap(void); ++ ++#define reiser4_post_commit_hook_bitmap() do{}while(0) ++#define reiser4_post_write_back_hook_bitmap() do{}while(0) ++#define reiser4_print_info_bitmap(pref, al) do{}while(0) ++ ++typedef __u64 bmap_nr_t; ++typedef __u32 bmap_off_t; ++ ++#endif /* __REISER4_PLUGIN_SPACE_BITMAP_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/space/Makefile linux-2.6.30/fs/reiser4/plugin/space/Makefile +--- linux-2.6.30.orig/fs/reiser4/plugin/space/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/space/Makefile 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,4 @@ ++obj-$(CONFIG_REISER4_FS) += space_plugins.o ++ ++space_plugins-objs := \ ++ bitmap.o +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/space/space_allocator.h linux-2.6.30/fs/reiser4/plugin/space/space_allocator.h +--- linux-2.6.30.orig/fs/reiser4/plugin/space/space_allocator.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/space/space_allocator.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,80 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#ifndef __SPACE_ALLOCATOR_H__ ++#define __SPACE_ALLOCATOR_H__ ++ ++#include "../../forward.h" ++#include "bitmap.h" ++/* NIKITA-FIXME-HANS: surely this could use a comment. Something about how bitmap is the only space allocator for now, ++ * but... */ ++#define DEF_SPACE_ALLOCATOR(allocator) \ ++ \ ++static inline int sa_init_allocator (reiser4_space_allocator * al, struct super_block *s, void * opaque) \ ++{ \ ++ return reiser4_init_allocator_##allocator (al, s, opaque); \ ++} \ ++ \ ++static inline void sa_destroy_allocator (reiser4_space_allocator *al, struct super_block *s) \ ++{ \ ++ reiser4_destroy_allocator_##allocator (al, s); \ ++} \ ++ \ ++static inline int sa_alloc_blocks (reiser4_space_allocator *al, reiser4_blocknr_hint * hint, \ ++ int needed, reiser4_block_nr * start, reiser4_block_nr * len) \ ++{ \ ++ return reiser4_alloc_blocks_##allocator (al, hint, needed, start, len); \ ++} \ ++static inline void sa_dealloc_blocks (reiser4_space_allocator * al, reiser4_block_nr start, reiser4_block_nr len) \ ++{ \ ++ reiser4_dealloc_blocks_##allocator (al, start, len); \ ++} \ ++ \ ++static inline void sa_check_blocks (const reiser4_block_nr * start, const reiser4_block_nr * end, int desired) \ ++{ \ ++ reiser4_check_blocks_##allocator (start, end, desired); \ ++} \ ++ \ ++static inline void sa_pre_commit_hook (void) \ ++{ \ ++ reiser4_pre_commit_hook_##allocator (); \ ++} \ ++ \ ++static inline void sa_post_commit_hook (void) \ ++{ \ ++ reiser4_post_commit_hook_##allocator (); \ ++} \ ++ \ ++static inline void sa_post_write_back_hook (void) \ ++{ \ ++ reiser4_post_write_back_hook_##allocator(); \ ++} \ ++ \ ++static inline void sa_print_info(const char * prefix, reiser4_space_allocator * al) \ ++{ \ ++ reiser4_print_info_##allocator (prefix, al); \ ++} ++ ++DEF_SPACE_ALLOCATOR(bitmap) ++ ++/* this object is part of reiser4 private in-core super block */ ++struct reiser4_space_allocator { ++ union { ++ /* space allocators might use this pointer to reference their ++ * data. */ ++ void *generic; ++ } u; ++}; ++ ++/* __SPACE_ALLOCATOR_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/plugin/tail_policy.c linux-2.6.30/fs/reiser4/plugin/tail_policy.c +--- linux-2.6.30.orig/fs/reiser4/plugin/tail_policy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/plugin/tail_policy.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,113 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Formatting policy plugins */ ++ ++/* ++ * Formatting policy plugin is used by object plugin (of regular file) to ++ * convert file between two representations. ++ * ++ * Currently following policies are implemented: ++ * never store file in formatted nodes ++ * always store file in formatted nodes ++ * store file in formatted nodes if file is smaller than 4 blocks (default) ++ */ ++ ++#include "../tree.h" ++#include "../inode.h" ++#include "../super.h" ++#include "object.h" ++#include "plugin.h" ++#include "node/node.h" ++#include "plugin_header.h" ++ ++#include <linux/pagemap.h> ++#include <linux/fs.h> /* For struct inode */ ++ ++/** ++ * have_formatting_never - ++ * @inode: ++ * @size: ++ * ++ * ++ */ ++/* Never store file's tail as direct item */ ++/* Audited by: green(2002.06.12) */ ++static int have_formatting_never(const struct inode *inode UNUSED_ARG ++ /* inode to operate on */ , ++ loff_t size UNUSED_ARG/* new object size */) ++{ ++ return 0; ++} ++ ++/* Always store file's tail as direct item */ ++/* Audited by: green(2002.06.12) */ ++static int ++have_formatting_always(const struct inode *inode UNUSED_ARG ++ /* inode to operate on */ , ++ loff_t size UNUSED_ARG/* new object size */) ++{ ++ return 1; ++} ++ ++/* This function makes test if we should store file denoted @inode as tails only ++ or as extents only. */ ++static int ++have_formatting_default(const struct inode *inode UNUSED_ARG ++ /* inode to operate on */ , ++ loff_t size/* new object size */) ++{ ++ assert("umka-1253", inode != NULL); ++ ++ if (size > inode->i_sb->s_blocksize * 4) ++ return 0; ++ ++ return 1; ++} ++ ++/* tail plugins */ ++formatting_plugin formatting_plugins[LAST_TAIL_FORMATTING_ID] = { ++ [NEVER_TAILS_FORMATTING_ID] = { ++ .h = { ++ .type_id = REISER4_FORMATTING_PLUGIN_TYPE, ++ .id = NEVER_TAILS_FORMATTING_ID, ++ .pops = NULL, ++ .label = "never", ++ .desc = "Never store file's tail", ++ .linkage = {NULL, NULL} ++ }, ++ .have_tail = have_formatting_never ++ }, ++ [ALWAYS_TAILS_FORMATTING_ID] = { ++ .h = { ++ .type_id = REISER4_FORMATTING_PLUGIN_TYPE, ++ .id = ALWAYS_TAILS_FORMATTING_ID, ++ .pops = NULL, ++ .label = "always", ++ .desc = "Always store file's tail", ++ .linkage = {NULL, NULL} ++ }, ++ .have_tail = have_formatting_always ++ }, ++ [SMALL_FILE_FORMATTING_ID] = { ++ .h = { ++ .type_id = REISER4_FORMATTING_PLUGIN_TYPE, ++ .id = SMALL_FILE_FORMATTING_ID, ++ .pops = NULL, ++ .label = "4blocks", ++ .desc = "store files shorter than 4 blocks in tail items", ++ .linkage = {NULL, NULL} ++ }, ++ .have_tail = have_formatting_default ++ } ++}; ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/pool.c linux-2.6.30/fs/reiser4/pool.c +--- linux-2.6.30.orig/fs/reiser4/pool.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/pool.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,231 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Fast pool allocation. ++ ++ There are situations when some sub-system normally asks memory allocator ++ for only few objects, but under some circumstances could require much ++ more. Typical and actually motivating example is tree balancing. It needs ++ to keep track of nodes that were involved into it, and it is well-known ++ that in reasonable packed balanced tree most (92.938121%) percent of all ++ balancings end up after working with only few nodes (3.141592 on ++ average). But in rare cases balancing can involve much more nodes ++ (3*tree_height+1 in extremal situation). ++ ++ On the one hand, we don't want to resort to dynamic allocation (slab, ++ malloc(), etc.) to allocate data structures required to keep track of ++ nodes during balancing. On the other hand, we cannot statically allocate ++ required amount of space on the stack, because first: it is useless wastage ++ of precious resource, and second: this amount is unknown in advance (tree ++ height can change). ++ ++ Pools, implemented in this file are solution for this problem: ++ ++ - some configurable amount of objects is statically preallocated on the ++ stack ++ ++ - if this preallocated pool is exhausted and more objects is requested ++ they are allocated dynamically. ++ ++ Pools encapsulate distinction between statically and dynamically allocated ++ objects. Both allocation and recycling look exactly the same. ++ ++ To keep track of dynamically allocated objects, pool adds its own linkage ++ to each object. ++ ++ NOTE-NIKITA This linkage also contains some balancing-specific data. This ++ is not perfect. On the other hand, balancing is currently the only client ++ of pool code. ++ ++ NOTE-NIKITA Another desirable feature is to rewrite all pool manipulation ++ functions in the style of tslist/tshash, i.e., make them unreadable, but ++ type-safe. ++ ++*/ ++ ++#include "debug.h" ++#include "pool.h" ++#include "super.h" ++ ++#include <linux/types.h> ++#include <linux/err.h> ++ ++/* initialize new pool object @h */ ++static void reiser4_init_pool_obj(struct reiser4_pool_header *h) ++{ ++ INIT_LIST_HEAD(&h->usage_linkage); ++ INIT_LIST_HEAD(&h->level_linkage); ++ INIT_LIST_HEAD(&h->extra_linkage); ++} ++ ++/* initialize new pool */ ++void reiser4_init_pool(struct reiser4_pool *pool /* pool to initialize */ , ++ size_t obj_size /* size of objects in @pool */ , ++ int num_of_objs /* number of preallocated objects */ , ++ char *data/* area for preallocated objects */) ++{ ++ struct reiser4_pool_header *h; ++ int i; ++ ++ assert("nikita-955", pool != NULL); ++ assert("nikita-1044", obj_size > 0); ++ assert("nikita-956", num_of_objs >= 0); ++ assert("nikita-957", data != NULL); ++ ++ memset(pool, 0, sizeof *pool); ++ pool->obj_size = obj_size; ++ pool->data = data; ++ INIT_LIST_HEAD(&pool->free); ++ INIT_LIST_HEAD(&pool->used); ++ INIT_LIST_HEAD(&pool->extra); ++ memset(data, 0, obj_size * num_of_objs); ++ for (i = 0; i < num_of_objs; ++i) { ++ h = (struct reiser4_pool_header *) (data + i * obj_size); ++ reiser4_init_pool_obj(h); ++ /* add pool header to the end of pool's free list */ ++ list_add_tail(&h->usage_linkage, &pool->free); ++ } ++} ++ ++/* release pool resources ++ ++ Release all resources acquired by this pool, specifically, dynamically ++ allocated objects. ++ ++*/ ++void reiser4_done_pool(struct reiser4_pool *pool UNUSED_ARG) ++{ ++} ++ ++/* allocate carry object from @pool ++ ++ First, try to get preallocated object. If this fails, resort to dynamic ++ allocation. ++ ++*/ ++static void *reiser4_pool_alloc(struct reiser4_pool *pool) ++{ ++ struct reiser4_pool_header *result; ++ ++ assert("nikita-959", pool != NULL); ++ ++ if (!list_empty(&pool->free)) { ++ struct list_head *linkage; ++ ++ linkage = pool->free.next; ++ list_del(linkage); ++ INIT_LIST_HEAD(linkage); ++ result = list_entry(linkage, struct reiser4_pool_header, ++ usage_linkage); ++ BUG_ON(!list_empty(&result->level_linkage) || ++ !list_empty(&result->extra_linkage)); ++ } else { ++ /* pool is empty. Extra allocations don't deserve dedicated ++ slab to be served from, as they are expected to be rare. */ ++ result = kmalloc(pool->obj_size, reiser4_ctx_gfp_mask_get()); ++ if (result != 0) { ++ reiser4_init_pool_obj(result); ++ list_add(&result->extra_linkage, &pool->extra); ++ } else ++ return ERR_PTR(RETERR(-ENOMEM)); ++ BUG_ON(!list_empty(&result->usage_linkage) || ++ !list_empty(&result->level_linkage)); ++ } ++ ++pool->objs; ++ list_add(&result->usage_linkage, &pool->used); ++ memset(result + 1, 0, pool->obj_size - sizeof *result); ++ return result; ++} ++ ++/* return object back to the pool */ ++void reiser4_pool_free(struct reiser4_pool *pool, ++ struct reiser4_pool_header *h) ++{ ++ assert("nikita-961", h != NULL); ++ assert("nikita-962", pool != NULL); ++ ++ --pool->objs; ++ assert("nikita-963", pool->objs >= 0); ++ ++ list_del_init(&h->usage_linkage); ++ list_del_init(&h->level_linkage); ++ ++ if (list_empty(&h->extra_linkage)) ++ /* ++ * pool header is not an extra one. Push it onto free list ++ * using usage_linkage ++ */ ++ list_add(&h->usage_linkage, &pool->free); ++ else { ++ /* remove pool header from pool's extra list and kfree it */ ++ list_del(&h->extra_linkage); ++ kfree(h); ++ } ++} ++ ++/* add new object to the carry level list ++ ++ Carry level is FIFO most of the time, but not always. Complications arise ++ when make_space() function tries to go to the left neighbor and thus adds ++ carry node before existing nodes, and also, when updating delimiting keys ++ after moving data between two nodes, we want left node to be locked before ++ right node. ++ ++ Latter case is confusing at the first glance. Problem is that COP_UPDATE ++ opration that updates delimiting keys is sometimes called with two nodes ++ (when data are moved between two nodes) and sometimes with only one node ++ (when leftmost item is deleted in a node). In any case operation is ++ supplied with at least node whose left delimiting key is to be updated ++ (that is "right" node). ++ ++ @pool - from which to allocate new object; ++ @list - where to add object; ++ @reference - after (or before) which existing object to add ++*/ ++struct reiser4_pool_header *reiser4_add_obj(struct reiser4_pool *pool, ++ struct list_head *list, ++ pool_ordering order, ++ struct reiser4_pool_header *reference) ++{ ++ struct reiser4_pool_header *result; ++ ++ assert("nikita-972", pool != NULL); ++ ++ result = reiser4_pool_alloc(pool); ++ if (IS_ERR(result)) ++ return result; ++ ++ assert("nikita-973", result != NULL); ++ ++ switch (order) { ++ case POOLO_BEFORE: ++ __list_add(&result->level_linkage, ++ reference->level_linkage.prev, ++ &reference->level_linkage); ++ break; ++ case POOLO_AFTER: ++ __list_add(&result->level_linkage, ++ &reference->level_linkage, ++ reference->level_linkage.next); ++ break; ++ case POOLO_LAST: ++ list_add_tail(&result->level_linkage, list); ++ break; ++ case POOLO_FIRST: ++ list_add(&result->level_linkage, list); ++ break; ++ default: ++ wrong_return_value("nikita-927", "order"); ++ } ++ return result; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/pool.h linux-2.6.30/fs/reiser4/pool.h +--- linux-2.6.30.orig/fs/reiser4/pool.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/pool.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,57 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Fast pool allocation */ ++ ++#ifndef __REISER4_POOL_H__ ++#define __REISER4_POOL_H__ ++ ++#include <linux/types.h> ++ ++struct reiser4_pool { ++ size_t obj_size; ++ int objs; ++ char *data; ++ struct list_head free; ++ struct list_head used; ++ struct list_head extra; ++}; ++ ++struct reiser4_pool_header { ++ /* object is either on free or "used" lists */ ++ struct list_head usage_linkage; ++ struct list_head level_linkage; ++ struct list_head extra_linkage; ++}; ++ ++typedef enum { ++ POOLO_BEFORE, ++ POOLO_AFTER, ++ POOLO_LAST, ++ POOLO_FIRST ++} pool_ordering; ++ ++/* pool manipulation functions */ ++ ++extern void reiser4_init_pool(struct reiser4_pool *pool, size_t obj_size, ++ int num_of_objs, char *data); ++extern void reiser4_done_pool(struct reiser4_pool *pool); ++extern void reiser4_pool_free(struct reiser4_pool *pool, ++ struct reiser4_pool_header *h); ++struct reiser4_pool_header *reiser4_add_obj(struct reiser4_pool *pool, ++ struct list_head *list, ++ pool_ordering order, ++ struct reiser4_pool_header *reference); ++ ++/* __REISER4_POOL_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/readahead.c linux-2.6.30/fs/reiser4/readahead.c +--- linux-2.6.30.orig/fs/reiser4/readahead.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/readahead.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,140 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#include "forward.h" ++#include "tree.h" ++#include "tree_walk.h" ++#include "super.h" ++#include "inode.h" ++#include "key.h" ++#include "znode.h" ++ ++#include <linux/swap.h> /* for totalram_pages */ ++ ++void reiser4_init_ra_info(ra_info_t *rai) ++{ ++ rai->key_to_stop = *reiser4_min_key(); ++} ++ ++/* global formatted node readahead parameter. It can be set by mount option ++ * -o readahead:NUM:1 */ ++static inline int ra_adjacent_only(int flags) ++{ ++ return flags & RA_ADJACENT_ONLY; ++} ++ ++/* this is used by formatted_readahead to decide whether read for right neighbor ++ * of node is to be issued. It returns 1 if right neighbor's first key is less ++ * or equal to readahead's stop key */ ++static int should_readahead_neighbor(znode * node, ra_info_t *info) ++{ ++ int result; ++ ++ read_lock_dk(znode_get_tree(node)); ++ result = keyle(znode_get_rd_key(node), &info->key_to_stop); ++ read_unlock_dk(znode_get_tree(node)); ++ return result; ++} ++ ++#define LOW_MEM_PERCENTAGE (5) ++ ++static int low_on_memory(void) ++{ ++ unsigned int freepages; ++ ++ freepages = nr_free_pages(); ++ return freepages < (totalram_pages * LOW_MEM_PERCENTAGE / 100); ++} ++ ++/* start read for @node and for a few of its right neighbors */ ++void formatted_readahead(znode * node, ra_info_t *info) ++{ ++ struct formatted_ra_params *ra_params; ++ znode *cur; ++ int i; ++ int grn_flags; ++ lock_handle next_lh; ++ ++ /* do nothing if node block number has not been assigned to node (which ++ * means it is still in cache). */ ++ if (reiser4_blocknr_is_fake(znode_get_block(node))) ++ return; ++ ++ ra_params = get_current_super_ra_params(); ++ ++ if (znode_page(node) == NULL) ++ jstartio(ZJNODE(node)); ++ ++ if (znode_get_level(node) != LEAF_LEVEL) ++ return; ++ ++ /* don't waste memory for read-ahead when low on memory */ ++ if (low_on_memory()) ++ return; ++ ++ /* We can have locked nodes on upper tree levels, in this situation lock ++ priorities do not help to resolve deadlocks, we have to use TRY_LOCK ++ here. */ ++ grn_flags = (GN_CAN_USE_UPPER_LEVELS | GN_TRY_LOCK); ++ ++ i = 0; ++ cur = zref(node); ++ init_lh(&next_lh); ++ while (i < ra_params->max) { ++ const reiser4_block_nr * nextblk; ++ ++ if (!should_readahead_neighbor(cur, info)) ++ break; ++ ++ if (reiser4_get_right_neighbor ++ (&next_lh, cur, ZNODE_READ_LOCK, grn_flags)) ++ break; ++ ++ nextblk = znode_get_block(next_lh.node); ++ if (reiser4_blocknr_is_fake(nextblk) || ++ (ra_adjacent_only(ra_params->flags) ++ && *nextblk != *znode_get_block(cur) + 1)) ++ break; ++ ++ zput(cur); ++ cur = zref(next_lh.node); ++ done_lh(&next_lh); ++ if (znode_page(cur) == NULL) ++ jstartio(ZJNODE(cur)); ++ else ++ /* Do not scan read-ahead window if pages already ++ * allocated (and i/o already started). */ ++ break; ++ ++ i++; ++ } ++ zput(cur); ++ done_lh(&next_lh); ++} ++ ++void reiser4_readdir_readahead_init(struct inode *dir, tap_t *tap) ++{ ++ reiser4_key *stop_key; ++ ++ assert("nikita-3542", dir != NULL); ++ assert("nikita-3543", tap != NULL); ++ ++ stop_key = &tap->ra_info.key_to_stop; ++ /* initialize readdir readahead information: include into readahead ++ * stat data of all files of the directory */ ++ set_key_locality(stop_key, get_inode_oid(dir)); ++ set_key_type(stop_key, KEY_SD_MINOR); ++ set_key_ordering(stop_key, get_key_ordering(reiser4_max_key())); ++ set_key_objectid(stop_key, get_key_objectid(reiser4_max_key())); ++ set_key_offset(stop_key, get_key_offset(reiser4_max_key())); ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/readahead.h linux-2.6.30/fs/reiser4/readahead.h +--- linux-2.6.30.orig/fs/reiser4/readahead.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/readahead.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,52 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#ifndef __READAHEAD_H__ ++#define __READAHEAD_H__ ++ ++#include "key.h" ++ ++typedef enum { ++ RA_ADJACENT_ONLY = 1, /* only requests nodes which are adjacent. ++ Default is NO (not only adjacent) */ ++} ra_global_flags; ++ ++/* reiser4 super block has a field of this type. ++ It controls readahead during tree traversals */ ++struct formatted_ra_params { ++ unsigned long max; /* request not more than this amount of nodes. ++ Default is totalram_pages / 4 */ ++ int flags; ++}; ++ ++typedef struct { ++ reiser4_key key_to_stop; ++} ra_info_t; ++ ++void formatted_readahead(znode * , ra_info_t *); ++void reiser4_init_ra_info(ra_info_t *rai); ++ ++struct reiser4_file_ra_state { ++ loff_t start; /* Current window */ ++ loff_t size; ++ loff_t next_size; /* Next window size */ ++ loff_t ahead_start; /* Ahead window */ ++ loff_t ahead_size; ++ loff_t max_window_size; /* Maximum readahead window */ ++ loff_t slow_start; /* enlarging r/a size algorithm. */ ++}; ++ ++extern void reiser4_readdir_readahead_init(struct inode *dir, tap_t *tap); ++ ++/* __READAHEAD_H__ */ ++#endif ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/README linux-2.6.30/fs/reiser4/README +--- linux-2.6.30.orig/fs/reiser4/README 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/README 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,128 @@ ++[LICENSING] ++ ++Reiser4 is hereby licensed under the GNU General ++Public License version 2. ++ ++Source code files that contain the phrase "licensing governed by ++reiser4/README" are "governed files" throughout this file. Governed ++files are licensed under the GPL. The portions of them owned by Hans ++Reiser, or authorized to be licensed by him, have been in the past, ++and likely will be in the future, licensed to other parties under ++other licenses. If you add your code to governed files, and don't ++want it to be owned by Hans Reiser, put your copyright label on that ++code so the poor blight and his customers can keep things straight. ++All portions of governed files not labeled otherwise are owned by Hans ++Reiser, and by adding your code to it, widely distributing it to ++others or sending us a patch, and leaving the sentence in stating that ++licensing is governed by the statement in this file, you accept this. ++It will be a kindness if you identify whether Hans Reiser is allowed ++to license code labeled as owned by you on your behalf other than ++under the GPL, because he wants to know if it is okay to do so and put ++a check in the mail to you (for non-trivial improvements) when he ++makes his next sale. He makes no guarantees as to the amount if any, ++though he feels motivated to motivate contributors, and you can surely ++discuss this with him before or after contributing. You have the ++right to decline to allow him to license your code contribution other ++than under the GPL. ++ ++Further licensing options are available for commercial and/or other ++interests directly from Hans Reiser: reiser@namesys.com. If you interpret ++the GPL as not allowing those additional licensing options, you read ++it wrongly, and Richard Stallman agrees with me, when carefully read ++you can see that those restrictions on additional terms do not apply ++to the owner of the copyright, and my interpretation of this shall ++govern for this license. ++ ++[END LICENSING] ++ ++Reiser4 is a file system based on dancing tree algorithms, and is ++described at http://www.namesys.com ++ ++mkfs.reiser4 and other utilities are on our webpage or wherever your ++Linux provider put them. You really want to be running the latest ++version off the website if you use fsck. ++ ++Yes, if you update your reiser4 kernel module you do have to ++recompile your kernel, most of the time. The errors you get will be ++quite cryptic if your forget to do so. ++ ++Hideous Commercial Pitch: Spread your development costs across other OS ++vendors. Select from the best in the world, not the best in your ++building, by buying from third party OS component suppliers. Leverage ++the software component development power of the internet. Be the most ++aggressive in taking advantage of the commercial possibilities of ++decentralized internet development, and add value through your branded ++integration that you sell as an operating system. Let your competitors ++be the ones to compete against the entire internet by themselves. Be ++hip, get with the new economic trend, before your competitors do. Send ++email to reiser@namesys.com ++ ++Hans Reiser was the primary architect of Reiser4, but a whole team ++chipped their ideas in. He invested everything he had into Namesys ++for 5.5 dark years of no money before Reiser3 finally started to work well ++enough to bring in money. He owns the copyright. ++ ++DARPA was the primary sponsor of Reiser4. DARPA does not endorse ++Reiser4, it merely sponsors it. DARPA is, in solely Hans's personal ++opinion, unique in its willingness to invest into things more ++theoretical than the VC community can readily understand, and more ++longterm than allows them to be sure that they will be the ones to ++extract the economic benefits from. DARPA also integrated us into a ++security community that transformed our security worldview. ++ ++Vladimir Saveliev is our lead programmer, with us from the beginning, ++and he worked long hours writing the cleanest code. This is why he is ++now the lead programmer after years of commitment to our work. He ++always made the effort to be the best he could be, and to make his ++code the best that it could be. What resulted was quite remarkable. I ++don't think that money can ever motivate someone to work the way he ++did, he is one of the most selfless men I know. ++ ++Alexander Lyamin was our sysadmin, and helped to educate us in ++security issues. Moscow State University and IMT were very generous ++in the internet access they provided us, and in lots of other little ++ways that a generous institution can be. ++ ++Alexander Zarochentcev (sometimes known as zam, or sasha), wrote the ++locking code, the block allocator, and finished the flushing code. ++His code is always crystal clean and well structured. ++ ++Nikita Danilov wrote the core of the balancing code, the core of the ++plugins code, and the directory code. He worked a steady pace of long ++hours that produced a whole lot of well abstracted code. He is our ++senior computer scientist. ++ ++Vladimir Demidov wrote the parser. Writing an in kernel parser is ++something very few persons have the skills for, and it is thanks to ++him that we can say that the parser is really not so big compared to ++various bits of our other code, and making a parser work in the kernel ++was not so complicated as everyone would imagine mainly because it was ++him doing it... ++ ++Joshua McDonald wrote the transaction manager, and the flush code. ++The flush code unexpectedly turned out be extremely hairy for reasons ++you can read about on our web page, and he did a great job on an ++extremely difficult task. ++ ++Nina Reiser handled our accounting, government relations, and much ++more. ++ ++Ramon Reiser developed our website. ++ ++Beverly Palmer drew our graphics. ++ ++Vitaly Fertman developed librepair, userspace plugins repair code, fsck ++and worked with Umka on developing libreiser4 and userspace plugins. ++ ++Yury Umanets (aka Umka) developed libreiser4, userspace plugins and ++userspace tools (reiser4progs). ++ ++Oleg Drokin (aka Green) is the release manager who fixes everything. ++It is so nice to have someone like that on the team. He (plus Chris ++and Jeff) make it possible for the entire rest of the Namesys team to ++focus on Reiser4, and he fixed a whole lot of Reiser4 bugs also. It ++is just amazing to watch his talent for spotting bugs in action. ++ ++Edward Shishkin wrote cryptcompress file plugin (which manages files ++built of encrypted and(or) compressed bodies) and other plugins related ++to transparent encryption and compression support. +diff -urN linux-2.6.30.orig/fs/reiser4/reiser4.h linux-2.6.30/fs/reiser4/reiser4.h +--- linux-2.6.30.orig/fs/reiser4/reiser4.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/reiser4.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,259 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* definitions of common constants used by reiser4 */ ++ ++#if !defined( __REISER4_H__ ) ++#define __REISER4_H__ ++ ++#include <asm/param.h> /* for HZ */ ++#include <linux/errno.h> ++#include <linux/types.h> ++#include <linux/fs.h> ++#include <linux/hardirq.h> ++#include <linux/sched.h> ++ ++/* ++ * reiser4 compilation options. ++ */ ++ ++#if defined(CONFIG_REISER4_DEBUG) ++/* turn on assertion checks */ ++#define REISER4_DEBUG (1) ++#else ++#define REISER4_DEBUG (0) ++#endif ++ ++#define REISER4_SHA256 (0) ++ ++/* ++ * Turn on large keys mode. In his mode (which is default), reiser4 key has 4 ++ * 8-byte components. In the old "small key" mode, it's 3 8-byte ++ * components. Additional component, referred to as "ordering" is used to ++ * order items from which given object is composed of. As such, ordering is ++ * placed between locality and objectid. For directory item ordering contains ++ * initial prefix of the file name this item is for. This sorts all directory ++ * items within given directory lexicographically (but see ++ * fibration.[ch]). For file body and stat-data, ordering contains initial ++ * prefix of the name file was initially created with. In the common case ++ * (files with single name) this allows to order file bodies and stat-datas in ++ * the same order as their respective directory entries, thus speeding up ++ * readdir. ++ * ++ * Note, that kernel can only mount file system with the same key size as one ++ * it is compiled for, so flipping this option may render your data ++ * inaccessible. ++ */ ++#define REISER4_LARGE_KEY (1) ++/*#define REISER4_LARGE_KEY (0)*/ ++ ++/*#define GUESS_EXISTS 1*/ ++ ++/* ++ * PLEASE update fs/reiser4/kattr.c:show_options() when adding new compilation ++ * option ++ */ ++ ++extern const char *REISER4_SUPER_MAGIC_STRING; ++extern const int REISER4_MAGIC_OFFSET; /* offset to magic string from the ++ * beginning of device */ ++ ++/* here go tunable parameters that are not worth special entry in kernel ++ configuration */ ++ ++/* default number of slots in coord-by-key caches */ ++#define CBK_CACHE_SLOTS (16) ++/* how many elementary tree operation to carry on the next level */ ++#define CARRIES_POOL_SIZE (5) ++/* size of pool of preallocated nodes for carry process. */ ++#define NODES_LOCKED_POOL_SIZE (5) ++ ++#define REISER4_NEW_NODE_FLAGS (COPI_LOAD_LEFT | COPI_LOAD_RIGHT | COPI_GO_LEFT) ++#define REISER4_NEW_EXTENT_FLAGS (COPI_LOAD_LEFT | COPI_LOAD_RIGHT | COPI_GO_LEFT) ++#define REISER4_PASTE_FLAGS (COPI_GO_LEFT) ++#define REISER4_INSERT_FLAGS (COPI_GO_LEFT) ++ ++/* we are supporting reservation of disk space on uid basis */ ++#define REISER4_SUPPORT_UID_SPACE_RESERVATION (0) ++/* we are supporting reservation of disk space for groups */ ++#define REISER4_SUPPORT_GID_SPACE_RESERVATION (0) ++/* we are supporting reservation of disk space for root */ ++#define REISER4_SUPPORT_ROOT_SPACE_RESERVATION (0) ++/* we use rapid flush mode, see flush.c for comments. */ ++#define REISER4_USE_RAPID_FLUSH (1) ++ ++/* ++ * set this to 0 if you don't want to use wait-for-flush in ->writepage(). ++ */ ++#define REISER4_USE_ENTD (1) ++ ++/* key allocation is Plan-A */ ++#define REISER4_PLANA_KEY_ALLOCATION (1) ++/* key allocation follows good old 3.x scheme */ ++#define REISER4_3_5_KEY_ALLOCATION (0) ++ ++/* size of hash-table for znodes */ ++#define REISER4_ZNODE_HASH_TABLE_SIZE (1 << 13) ++ ++/* number of buckets in lnode hash-table */ ++#define LNODE_HTABLE_BUCKETS (1024) ++ ++/* some ridiculously high maximal limit on height of znode tree. This ++ is used in declaration of various per level arrays and ++ to allocate stattistics gathering array for per-level stats. */ ++#define REISER4_MAX_ZTREE_HEIGHT (8) ++ ++#define REISER4_PANIC_MSG_BUFFER_SIZE (1024) ++ ++/* If array contains less than REISER4_SEQ_SEARCH_BREAK elements then, ++ sequential search is on average faster than binary. This is because ++ of better optimization and because sequential search is more CPU ++ cache friendly. This number (25) was found by experiments on dual AMD ++ Athlon(tm), 1400MHz. ++ ++ NOTE: testing in kernel has shown that binary search is more effective than ++ implied by results of the user level benchmarking. Probably because in the ++ node keys are separated by other data. So value was adjusted after few ++ tests. More thorough tuning is needed. ++*/ ++#define REISER4_SEQ_SEARCH_BREAK (3) ++ ++/* don't allow tree to be lower than this */ ++#define REISER4_MIN_TREE_HEIGHT (TWIG_LEVEL) ++ ++/* NOTE NIKITA this is no longer used: maximal atom size is auto-adjusted to ++ * available memory. */ ++/* Default value of maximal atom size. Can be ovewritten by ++ tmgr.atom_max_size mount option. By default infinity. */ ++#define REISER4_ATOM_MAX_SIZE ((unsigned)(~0)) ++ ++/* Default value of maximal atom age (in jiffies). After reaching this age ++ atom will be forced to commit, either synchronously or asynchronously. Can ++ be overwritten by tmgr.atom_max_age mount option. */ ++#define REISER4_ATOM_MAX_AGE (600 * HZ) ++ ++/* sleeping period for ktxnmrgd */ ++#define REISER4_TXNMGR_TIMEOUT (5 * HZ) ++ ++/* timeout to wait for ent thread in writepage. Default: 3 milliseconds. */ ++#define REISER4_ENTD_TIMEOUT (3 * HZ / 1000) ++ ++/* start complaining after that many restarts in coord_by_key(). ++ ++ This either means incredibly heavy contention for this part of a tree, or ++ some corruption or bug. ++*/ ++#define REISER4_CBK_ITERATIONS_LIMIT (100) ++ ++/* return -EIO after that many iterations in coord_by_key(). ++ ++ I have witnessed more than 800 iterations (in 30 thread test) before cbk ++ finished. --nikita ++*/ ++#define REISER4_MAX_CBK_ITERATIONS 500000 ++ ++/* put a per-inode limit on maximal number of directory entries with identical ++ keys in hashed directory. ++ ++ Disable this until inheritance interfaces stabilize: we need some way to ++ set per directory limit. ++*/ ++#define REISER4_USE_COLLISION_LIMIT (0) ++ ++/* If flush finds more than FLUSH_RELOCATE_THRESHOLD adjacent dirty leaf-level ++ blocks it will force them to be relocated. */ ++#define FLUSH_RELOCATE_THRESHOLD 64 ++/* If flush finds can find a block allocation closer than at most ++ FLUSH_RELOCATE_DISTANCE from the preceder it will relocate to that position. ++ */ ++#define FLUSH_RELOCATE_DISTANCE 64 ++ ++/* If we have written this much or more blocks before encountering busy jnode ++ in flush list - abort flushing hoping that next time we get called ++ this jnode will be clean already, and we will save some seeks. */ ++#define FLUSH_WRITTEN_THRESHOLD 50 ++ ++/* The maximum number of nodes to scan left on a level during flush. */ ++#define FLUSH_SCAN_MAXNODES 10000 ++ ++/* per-atom limit of flushers */ ++#define ATOM_MAX_FLUSHERS (1) ++ ++/* default tracing buffer size */ ++#define REISER4_TRACE_BUF_SIZE (1 << 15) ++ ++/* what size units of IO we would like cp, etc., to use, in writing to ++ reiser4. In bytes. ++ ++ Can be overwritten by optimal_io_size mount option. ++*/ ++#define REISER4_OPTIMAL_IO_SIZE (64 * 1024) ++ ++/* see comments in inode.c:oid_to_uino() */ ++#define REISER4_UINO_SHIFT (1 << 30) ++ ++/* Mark function argument as unused to avoid compiler warnings. */ ++#define UNUSED_ARG __attribute__((unused)) ++ ++#if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3) ++#define NONNULL __attribute__((nonnull)) ++#else ++#define NONNULL ++#endif ++ ++/* master super block offset in bytes.*/ ++#define REISER4_MASTER_OFFSET 65536 ++ ++/* size of VFS block */ ++#define VFS_BLKSIZE 512 ++/* number of bits in size of VFS block (512==2^9) */ ++#define VFS_BLKSIZE_BITS 9 ++ ++#define REISER4_I reiser4_inode_data ++ ++/* implication */ ++#define ergo(antecedent, consequent) (!(antecedent) || (consequent)) ++/* logical equivalence */ ++#define equi(p1, p2) (ergo((p1), (p2)) && ergo((p2), (p1))) ++ ++#define sizeof_array(x) ((int) (sizeof(x) / sizeof(x[0]))) ++ ++#define NOT_YET (0) ++ ++/** Reiser4 specific error codes **/ ++ ++#define REISER4_ERROR_CODE_BASE 10000 ++ ++/* Neighbor is not available (side neighbor or parent) */ ++#define E_NO_NEIGHBOR (REISER4_ERROR_CODE_BASE) ++ ++/* Node was not found in cache */ ++#define E_NOT_IN_CACHE (REISER4_ERROR_CODE_BASE + 1) ++ ++/* node has no free space enough for completion of balancing operation */ ++#define E_NODE_FULL (REISER4_ERROR_CODE_BASE + 2) ++ ++/* repeat operation */ ++#define E_REPEAT (REISER4_ERROR_CODE_BASE + 3) ++ ++/* deadlock happens */ ++#define E_DEADLOCK (REISER4_ERROR_CODE_BASE + 4) ++ ++/* operation cannot be performed, because it would block and non-blocking mode ++ * was requested. */ ++#define E_BLOCK (REISER4_ERROR_CODE_BASE + 5) ++ ++/* wait some event (depends on context), then repeat */ ++#define E_WAIT (REISER4_ERROR_CODE_BASE + 6) ++ ++#endif /* __REISER4_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/safe_link.c linux-2.6.30/fs/reiser4/safe_link.c +--- linux-2.6.30.orig/fs/reiser4/safe_link.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/safe_link.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,354 @@ ++/* Copyright 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Safe-links. */ ++ ++/* ++ * Safe-links are used to maintain file system consistency during operations ++ * that spawns multiple transactions. For example: ++ * ++ * 1. Unlink. UNIX supports "open-but-unlinked" files, that is files ++ * without user-visible names in the file system, but still opened by some ++ * active process. What happens here is that unlink proper (i.e., removal ++ * of the last file name) and file deletion (truncate of file body to zero ++ * and deletion of stat-data, that happens when last file descriptor is ++ * closed), may belong to different transactions T1 and T2. If a crash ++ * happens after T1 commit, but before T2 commit, on-disk file system has ++ * a file without name, that is, disk space leak. ++ * ++ * 2. Truncate. Truncate of large file may spawn multiple transactions. If ++ * system crashes while truncate was in-progress, file is left partially ++ * truncated, which violates "atomicity guarantees" of reiser4, viz. that ++ * every system is atomic. ++ * ++ * Safe-links address both above cases. Basically, safe-link is a way post ++ * some operation to be executed during commit of some other transaction than ++ * current one. (Another way to look at the safe-link is to interpret it as a ++ * logical logging.) ++ * ++ * Specifically, at the beginning of unlink safe-link in inserted in the ++ * tree. This safe-link is normally removed by file deletion code (during ++ * transaction T2 in the above terms). Truncate also inserts safe-link that is ++ * normally removed when truncate operation is finished. ++ * ++ * This means, that in the case of "clean umount" there are no safe-links in ++ * the tree. If safe-links are observed during mount, it means that (a) system ++ * was terminated abnormally, and (b) safe-link correspond to the "pending" ++ * (i.e., not finished) operations that were in-progress during system ++ * termination. Each safe-link record enough information to complete ++ * corresponding operation, and mount simply "replays" them (hence, the ++ * analogy with the logical logging). ++ * ++ * Safe-links are implemented as blackbox items (see ++ * plugin/item/blackbox.[ch]). ++ * ++ * For the reference: ext3 also has similar mechanism, it's called "an orphan ++ * list" there. ++ */ ++ ++#include "safe_link.h" ++#include "debug.h" ++#include "inode.h" ++ ++#include "plugin/item/blackbox.h" ++ ++#include <linux/fs.h> ++ ++/* ++ * On-disk format of safe-link. ++ */ ++typedef struct safelink { ++ reiser4_key sdkey; /* key of stat-data for the file safe-link is ++ * for */ ++ d64 size; /* size to which file should be truncated */ ++} safelink_t; ++ ++/* ++ * locality where safe-link items are stored. Next to the objectid of root ++ * directory. ++ */ ++static oid_t safe_link_locality(reiser4_tree * tree) ++{ ++ return get_key_objectid(get_super_private(tree->super)->df_plug-> ++ root_dir_key(tree->super)) + 1; ++} ++ ++/* ++ Construct a key for the safe-link. Key has the following format: ++ ++| 60 | 4 | 64 | 4 | 60 | 64 | +++---------------+---+------------------+---+---------------+------------------+ ++| locality | 0 | 0 | 0 | objectid | link type | +++---------------+---+------------------+---+---------------+------------------+ ++| | | | | ++| 8 bytes | 8 bytes | 8 bytes | 8 bytes | ++ ++ This is in large keys format. In small keys format second 8 byte chunk is ++ out. Locality is a constant returned by safe_link_locality(). objectid is ++ an oid of a file on which operation protected by this safe-link is ++ performed. link-type is used to distinguish safe-links for different ++ operations. ++ ++ */ ++static reiser4_key *build_link_key(reiser4_tree * tree, oid_t oid, ++ reiser4_safe_link_t link, reiser4_key * key) ++{ ++ reiser4_key_init(key); ++ set_key_locality(key, safe_link_locality(tree)); ++ set_key_objectid(key, oid); ++ set_key_offset(key, link); ++ return key; ++} ++ ++/* ++ * how much disk space is necessary to insert and remove (in the ++ * error-handling path) safe-link. ++ */ ++static __u64 safe_link_tograb(reiser4_tree * tree) ++{ ++ return ++ /* insert safe link */ ++ estimate_one_insert_item(tree) + ++ /* remove safe link */ ++ estimate_one_item_removal(tree) + ++ /* drill to the leaf level during insertion */ ++ 1 + estimate_one_insert_item(tree) + ++ /* ++ * possible update of existing safe-link. Actually, if ++ * safe-link existed already (we failed to remove it), then no ++ * insertion is necessary, so this term is already "covered", ++ * but for simplicity let's left it. ++ */ ++ 1; ++} ++ ++/* ++ * grab enough disk space to insert and remove (in the error-handling path) ++ * safe-link. ++ */ ++int safe_link_grab(reiser4_tree * tree, reiser4_ba_flags_t flags) ++{ ++ int result; ++ ++ grab_space_enable(); ++ /* The sbinfo->delete_mutex can be taken here. ++ * safe_link_release() should be called before leaving reiser4 ++ * context. */ ++ result = ++ reiser4_grab_reserved(tree->super, safe_link_tograb(tree), flags); ++ grab_space_enable(); ++ return result; ++} ++ ++/* ++ * release unused disk space reserved by safe_link_grab(). ++ */ ++void safe_link_release(reiser4_tree * tree) ++{ ++ reiser4_release_reserved(tree->super); ++} ++ ++/* ++ * insert into tree safe-link for operation @link on inode @inode. ++ */ ++int safe_link_add(struct inode *inode, reiser4_safe_link_t link) ++{ ++ reiser4_key key; ++ safelink_t sl; ++ int length; ++ int result; ++ reiser4_tree *tree; ++ ++ build_sd_key(inode, &sl.sdkey); ++ length = sizeof sl.sdkey; ++ ++ if (link == SAFE_TRUNCATE) { ++ /* ++ * for truncate we have to store final file length also, ++ * expand item. ++ */ ++ length += sizeof(sl.size); ++ put_unaligned(cpu_to_le64(inode->i_size), &sl.size); ++ } ++ tree = reiser4_tree_by_inode(inode); ++ build_link_key(tree, get_inode_oid(inode), link, &key); ++ ++ result = store_black_box(tree, &key, &sl, length); ++ if (result == -EEXIST) ++ result = update_black_box(tree, &key, &sl, length); ++ return result; ++} ++ ++/* ++ * remove safe-link corresponding to the operation @link on inode @inode from ++ * the tree. ++ */ ++int safe_link_del(reiser4_tree * tree, oid_t oid, reiser4_safe_link_t link) ++{ ++ reiser4_key key; ++ ++ return kill_black_box(tree, build_link_key(tree, oid, link, &key)); ++} ++ ++/* ++ * in-memory structure to keep information extracted from safe-link. This is ++ * used to iterate over all safe-links. ++ */ ++struct safe_link_context { ++ reiser4_tree *tree; /* internal tree */ ++ reiser4_key key; /* safe-link key */ ++ reiser4_key sdkey; /* key of object stat-data */ ++ reiser4_safe_link_t link; /* safe-link type */ ++ oid_t oid; /* object oid */ ++ __u64 size; /* final size for truncate */ ++}; ++ ++/* ++ * start iterating over all safe-links. ++ */ ++static void safe_link_iter_begin(reiser4_tree * tree, ++ struct safe_link_context *ctx) ++{ ++ ctx->tree = tree; ++ reiser4_key_init(&ctx->key); ++ set_key_locality(&ctx->key, safe_link_locality(tree)); ++ set_key_objectid(&ctx->key, get_key_objectid(reiser4_max_key())); ++ set_key_offset(&ctx->key, get_key_offset(reiser4_max_key())); ++} ++ ++/* ++ * return next safe-link. ++ */ ++static int safe_link_iter_next(struct safe_link_context *ctx) ++{ ++ int result; ++ safelink_t sl; ++ ++ result = load_black_box(ctx->tree, &ctx->key, &sl, sizeof sl, 0); ++ if (result == 0) { ++ ctx->oid = get_key_objectid(&ctx->key); ++ ctx->link = get_key_offset(&ctx->key); ++ ctx->sdkey = sl.sdkey; ++ if (ctx->link == SAFE_TRUNCATE) ++ ctx->size = le64_to_cpu(get_unaligned(&sl.size)); ++ } ++ return result; ++} ++ ++/* ++ * check are there any more safe-links left in the tree. ++ */ ++static int safe_link_iter_finished(struct safe_link_context *ctx) ++{ ++ return get_key_locality(&ctx->key) != safe_link_locality(ctx->tree); ++} ++ ++/* ++ * finish safe-link iteration. ++ */ ++static void safe_link_iter_end(struct safe_link_context *ctx) ++{ ++ /* nothing special */ ++} ++ ++/* ++ * process single safe-link. ++ */ ++static int process_safelink(struct super_block *super, reiser4_safe_link_t link, ++ reiser4_key * sdkey, oid_t oid, __u64 size) ++{ ++ struct inode *inode; ++ int result; ++ ++ /* ++ * obtain object inode by reiser4_iget(), then call object plugin ++ * ->safelink() method to do actual work, then delete safe-link on ++ * success. ++ */ ++ inode = reiser4_iget(super, sdkey, 1); ++ if (!IS_ERR(inode)) { ++ file_plugin *fplug; ++ ++ fplug = inode_file_plugin(inode); ++ assert("nikita-3428", fplug != NULL); ++ assert("", oid == get_inode_oid(inode)); ++ if (fplug->safelink != NULL) { ++ /* reiser4_txn_restart_current is not necessary because ++ * mounting is signle thread. However, without it ++ * deadlock detection code will complain (see ++ * nikita-3361). */ ++ reiser4_txn_restart_current(); ++ result = fplug->safelink(inode, link, size); ++ } else { ++ warning("nikita-3430", ++ "Cannot handle safelink for %lli", ++ (unsigned long long)oid); ++ reiser4_print_key("key", sdkey); ++ result = 0; ++ } ++ if (result != 0) { ++ warning("nikita-3431", ++ "Error processing safelink for %lli: %i", ++ (unsigned long long)oid, result); ++ } ++ reiser4_iget_complete(inode); ++ iput(inode); ++ if (result == 0) { ++ result = safe_link_grab(reiser4_get_tree(super), ++ BA_CAN_COMMIT); ++ if (result == 0) ++ result = ++ safe_link_del(reiser4_get_tree(super), oid, ++ link); ++ safe_link_release(reiser4_get_tree(super)); ++ /* ++ * restart transaction: if there was large number of ++ * safe-links, their processing may fail to fit into ++ * single transaction. ++ */ ++ if (result == 0) ++ reiser4_txn_restart_current(); ++ } ++ } else ++ result = PTR_ERR(inode); ++ return result; ++} ++ ++/* ++ * iterate over all safe-links in the file-system processing them one by one. ++ */ ++int process_safelinks(struct super_block *super) ++{ ++ struct safe_link_context ctx; ++ int result; ++ ++ if (rofs_super(super)) ++ /* do nothing on the read-only file system */ ++ return 0; ++ safe_link_iter_begin(&get_super_private(super)->tree, &ctx); ++ result = 0; ++ do { ++ result = safe_link_iter_next(&ctx); ++ if (safe_link_iter_finished(&ctx) || result == -ENOENT) { ++ result = 0; ++ break; ++ } ++ if (result == 0) ++ result = process_safelink(super, ctx.link, ++ &ctx.sdkey, ctx.oid, ++ ctx.size); ++ } while (result == 0); ++ safe_link_iter_end(&ctx); ++ return result; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/safe_link.h linux-2.6.30/fs/reiser4/safe_link.h +--- linux-2.6.30.orig/fs/reiser4/safe_link.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/safe_link.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,29 @@ ++/* Copyright 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Safe-links. See safe_link.c for details. */ ++ ++#if !defined(__FS_SAFE_LINK_H__) ++#define __FS_SAFE_LINK_H__ ++ ++#include "tree.h" ++ ++int safe_link_grab(reiser4_tree * tree, reiser4_ba_flags_t flags); ++void safe_link_release(reiser4_tree * tree); ++int safe_link_add(struct inode *inode, reiser4_safe_link_t link); ++int safe_link_del(reiser4_tree *, oid_t oid, reiser4_safe_link_t link); ++ ++int process_safelinks(struct super_block *super); ++ ++/* __FS_SAFE_LINK_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/seal.c linux-2.6.30/fs/reiser4/seal.c +--- linux-2.6.30.orig/fs/reiser4/seal.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/seal.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,218 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++/* Seals implementation. */ ++/* Seals are "weak" tree pointers. They are analogous to tree coords in ++ allowing to bypass tree traversal. But normal usage of coords implies that ++ node pointed to by coord is locked, whereas seals don't keep a lock (or ++ even a reference) to znode. In stead, each znode contains a version number, ++ increased on each znode modification. This version number is copied into a ++ seal when seal is created. Later, one can "validate" seal by calling ++ reiser4_seal_validate(). If znode is in cache and its version number is ++ still the same, seal is "pristine" and coord associated with it can be ++ re-used immediately. ++ ++ If, on the other hand, znode is out of cache, or it is obviously different ++ one from the znode seal was initially attached to (for example, it is on ++ the different level, or is being removed from the tree), seal is ++ irreparably invalid ("burned") and tree traversal has to be repeated. ++ ++ Otherwise, there is some hope, that while znode was modified (and seal was ++ "broken" as a result), key attached to the seal is still in the node. This ++ is checked by first comparing this key with delimiting keys of node and, if ++ key is ok, doing intra-node lookup. ++ ++ Znode version is maintained in the following way: ++ ++ there is reiser4_tree.znode_epoch counter. Whenever new znode is created, ++ znode_epoch is incremented and its new value is stored in ->version field ++ of new znode. Whenever znode is dirtied (which means it was probably ++ modified), znode_epoch is also incremented and its new value is stored in ++ znode->version. This is done so, because just incrementing znode->version ++ on each update is not enough: it may so happen, that znode get deleted, new ++ znode is allocated for the same disk block and gets the same version ++ counter, tricking seal code into false positive. ++*/ ++ ++#include "forward.h" ++#include "debug.h" ++#include "key.h" ++#include "coord.h" ++#include "seal.h" ++#include "plugin/item/item.h" ++#include "plugin/node/node.h" ++#include "jnode.h" ++#include "znode.h" ++#include "super.h" ++ ++static znode *seal_node(const seal_t *seal); ++static int seal_matches(const seal_t *seal, znode * node); ++ ++/* initialise seal. This can be called several times on the same seal. @coord ++ and @key can be NULL. */ ++void reiser4_seal_init(seal_t *seal /* seal to initialise */ , ++ const coord_t *coord /* coord @seal will be ++ * attached to */ , ++ const reiser4_key * key UNUSED_ARG /* key @seal will be ++ * attached to */ ) ++{ ++ assert("nikita-1886", seal != NULL); ++ memset(seal, 0, sizeof *seal); ++ if (coord != NULL) { ++ znode *node; ++ ++ node = coord->node; ++ assert("nikita-1987", node != NULL); ++ spin_lock_znode(node); ++ seal->version = node->version; ++ assert("nikita-1988", seal->version != 0); ++ seal->block = *znode_get_block(node); ++#if REISER4_DEBUG ++ seal->coord1 = *coord; ++ if (key != NULL) ++ seal->key = *key; ++#endif ++ spin_unlock_znode(node); ++ } ++} ++ ++/* finish with seal */ ++void reiser4_seal_done(seal_t *seal/* seal to clear */) ++{ ++ assert("nikita-1887", seal != NULL); ++ seal->version = 0; ++} ++ ++/* true if seal was initialised */ ++int reiser4_seal_is_set(const seal_t *seal/* seal to query */) ++{ ++ assert("nikita-1890", seal != NULL); ++ return seal->version != 0; ++} ++ ++#if REISER4_DEBUG ++/* helper function for reiser4_seal_validate(). It checks that item at @coord ++ * has expected key. This is to detect cases where node was modified but wasn't ++ * marked dirty. */ ++static inline int check_seal_match(const coord_t *coord /* coord to check */ , ++ const reiser4_key * k/* expected key */) ++{ ++ reiser4_key ukey; ++ ++ return (coord->between != AT_UNIT) || ++ /* FIXME-VS: we only can compare keys for items whose units ++ represent exactly one key */ ++ ((coord_is_existing_unit(coord)) ++ && (item_is_extent(coord) ++ || keyeq(k, unit_key_by_coord(coord, &ukey)))) ++ || ((coord_is_existing_unit(coord)) && (item_is_ctail(coord)) ++ && keyge(k, unit_key_by_coord(coord, &ukey))); ++} ++#endif ++ ++/* this is used by reiser4_seal_validate. It accepts return value of ++ * longterm_lock_znode and returns 1 if it can be interpreted as seal ++ * validation failure. For instance, when longterm_lock_znode returns -EINVAL, ++ * reiser4_seal_validate returns -E_REPEAT and caller will call tre search. ++ * We cannot do this in longterm_lock_znode(), because sometimes we want to ++ * distinguish between -EINVAL and -E_REPEAT. */ ++static int should_repeat(int return_code) ++{ ++ return return_code == -EINVAL; ++} ++ ++/* (re-)validate seal. ++ ++ Checks whether seal is pristine, and try to revalidate it if possible. ++ ++ If seal was burned, or broken irreparably, return -E_REPEAT. ++ ++ NOTE-NIKITA currently reiser4_seal_validate() returns -E_REPEAT if key we are ++ looking for is in range of keys covered by the sealed node, but item wasn't ++ found by node ->lookup() method. Alternative is to return -ENOENT in this ++ case, but this would complicate callers logic. ++ ++*/ ++int reiser4_seal_validate(seal_t *seal /* seal to validate */, ++ coord_t *coord /* coord to validate against */, ++ const reiser4_key * key /* key to validate against */, ++ lock_handle * lh /* resulting lock handle */, ++ znode_lock_mode mode /* lock node */, ++ znode_lock_request request/* locking priority */) ++{ ++ znode *node; ++ int result; ++ ++ assert("nikita-1889", seal != NULL); ++ assert("nikita-1881", reiser4_seal_is_set(seal)); ++ assert("nikita-1882", key != NULL); ++ assert("nikita-1883", coord != NULL); ++ assert("nikita-1884", lh != NULL); ++ assert("nikita-1885", keyeq(&seal->key, key)); ++ assert("nikita-1989", coords_equal(&seal->coord1, coord)); ++ ++ /* obtain znode by block number */ ++ node = seal_node(seal); ++ if (node != NULL) { ++ /* znode was in cache, lock it */ ++ result = longterm_lock_znode(lh, node, mode, request); ++ zput(node); ++ if (result == 0) { ++ if (seal_matches(seal, node)) { ++ /* if seal version and znode version ++ coincide */ ++ ON_DEBUG(coord_update_v(coord)); ++ assert("nikita-1990", ++ node == seal->coord1.node); ++ assert("nikita-1898", ++ WITH_DATA_RET(coord->node, 1, ++ check_seal_match(coord, ++ key))); ++ } else ++ result = RETERR(-E_REPEAT); ++ } ++ if (result != 0) { ++ if (should_repeat(result)) ++ result = RETERR(-E_REPEAT); ++ /* unlock node on failure */ ++ done_lh(lh); ++ } ++ } else { ++ /* znode wasn't in cache */ ++ result = RETERR(-E_REPEAT); ++ } ++ return result; ++} ++ ++/* helpers functions */ ++ ++/* obtain reference to znode seal points to, if in cache */ ++static znode *seal_node(const seal_t *seal/* seal to query */) ++{ ++ assert("nikita-1891", seal != NULL); ++ return zlook(current_tree, &seal->block); ++} ++ ++/* true if @seal version and @node version coincide */ ++static int seal_matches(const seal_t *seal /* seal to check */ , ++ znode * node/* node to check */) ++{ ++ int result; ++ ++ assert("nikita-1991", seal != NULL); ++ assert("nikita-1993", node != NULL); ++ ++ spin_lock_znode(node); ++ result = (seal->version == node->version); ++ spin_unlock_znode(node); ++ return result; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/seal.h linux-2.6.30/fs/reiser4/seal.h +--- linux-2.6.30.orig/fs/reiser4/seal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/seal.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,49 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Declaration of seals: "weak" tree pointers. See seal.c for comments. */ ++ ++#ifndef __SEAL_H__ ++#define __SEAL_H__ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "coord.h" ++ ++/* for __u?? types */ ++/*#include <linux/types.h>*/ ++ ++/* seal. See comment at the top of seal.c */ ++typedef struct seal_s { ++ /* version of znode recorder at the time of seal creation */ ++ __u64 version; ++ /* block number of znode attached to this seal */ ++ reiser4_block_nr block; ++#if REISER4_DEBUG ++ /* coord this seal is attached to. For debugging. */ ++ coord_t coord1; ++ /* key this seal is attached to. For debugging. */ ++ reiser4_key key; ++#endif ++} seal_t; ++ ++extern void reiser4_seal_init(seal_t *, const coord_t *, const reiser4_key *); ++extern void reiser4_seal_done(seal_t *); ++extern int reiser4_seal_is_set(const seal_t *); ++extern int reiser4_seal_validate(seal_t *, coord_t *, ++ const reiser4_key *, lock_handle * , ++ znode_lock_mode mode, znode_lock_request request); ++ ++/* __SEAL_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/search.c linux-2.6.30/fs/reiser4/search.c +--- linux-2.6.30.orig/fs/reiser4/search.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/search.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1612 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "coord.h" ++#include "seal.h" ++#include "plugin/item/item.h" ++#include "plugin/node/node.h" ++#include "plugin/plugin.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree_walk.h" ++#include "tree.h" ++#include "reiser4.h" ++#include "super.h" ++#include "inode.h" ++ ++#include <linux/slab.h> ++ ++static const char *bias_name(lookup_bias bias); ++ ++/* tree searching algorithm, intranode searching algorithms are in ++ plugin/node/ */ ++ ++/* tree lookup cache ++ * ++ * The coord by key cache consists of small list of recently accessed nodes ++ * maintained according to the LRU discipline. Before doing real top-to-down ++ * tree traversal this cache is scanned for nodes that can contain key ++ * requested. ++ * ++ * The efficiency of coord cache depends heavily on locality of reference for ++ * tree accesses. Our user level simulations show reasonably good hit ratios ++ * for coord cache under most loads so far. ++ */ ++ ++/* Initialise coord cache slot */ ++static void cbk_cache_init_slot(cbk_cache_slot *slot) ++{ ++ assert("nikita-345", slot != NULL); ++ ++ INIT_LIST_HEAD(&slot->lru); ++ slot->node = NULL; ++} ++ ++/* Initialize coord cache */ ++int cbk_cache_init(cbk_cache * cache/* cache to init */) ++{ ++ int i; ++ ++ assert("nikita-346", cache != NULL); ++ ++ cache->slot = ++ kmalloc(sizeof(cbk_cache_slot) * cache->nr_slots, ++ reiser4_ctx_gfp_mask_get()); ++ if (cache->slot == NULL) ++ return RETERR(-ENOMEM); ++ ++ INIT_LIST_HEAD(&cache->lru); ++ for (i = 0; i < cache->nr_slots; ++i) { ++ cbk_cache_init_slot(cache->slot + i); ++ list_add_tail(&((cache->slot + i)->lru), &cache->lru); ++ } ++ rwlock_init(&cache->guard); ++ return 0; ++} ++ ++/* free cbk cache data */ ++void cbk_cache_done(cbk_cache * cache/* cache to release */) ++{ ++ assert("nikita-2493", cache != NULL); ++ if (cache->slot != NULL) { ++ kfree(cache->slot); ++ cache->slot = NULL; ++ } ++} ++ ++/* macro to iterate over all cbk cache slots */ ++#define for_all_slots(cache, slot) \ ++ for ((slot) = list_entry((cache)->lru.next, cbk_cache_slot, lru); \ ++ &(cache)->lru != &(slot)->lru; \ ++ (slot) = list_entry(slot->lru.next, cbk_cache_slot, lru)) ++ ++#if REISER4_DEBUG ++/* this function assures that [cbk-cache-invariant] invariant holds */ ++static int cbk_cache_invariant(const cbk_cache * cache) ++{ ++ cbk_cache_slot *slot; ++ int result; ++ int unused; ++ ++ if (cache->nr_slots == 0) ++ return 1; ++ ++ assert("nikita-2469", cache != NULL); ++ unused = 0; ++ result = 1; ++ read_lock(&((cbk_cache *)cache)->guard); ++ for_all_slots(cache, slot) { ++ /* in LRU first go all `used' slots followed by `unused' */ ++ if (unused && (slot->node != NULL)) ++ result = 0; ++ if (slot->node == NULL) ++ unused = 1; ++ else { ++ cbk_cache_slot *scan; ++ ++ /* all cached nodes are different */ ++ scan = slot; ++ while (result) { ++ scan = list_entry(scan->lru.next, ++ cbk_cache_slot, lru); ++ if (&cache->lru == &scan->lru) ++ break; ++ if (slot->node == scan->node) ++ result = 0; ++ } ++ } ++ if (!result) ++ break; ++ } ++ read_unlock(&((cbk_cache *)cache)->guard); ++ return result; ++} ++ ++#endif ++ ++/* Remove references, if any, to @node from coord cache */ ++void cbk_cache_invalidate(const znode * node /* node to remove from cache */ , ++ reiser4_tree * tree/* tree to remove node from */) ++{ ++ cbk_cache_slot *slot; ++ cbk_cache *cache; ++ int i; ++ ++ assert("nikita-350", node != NULL); ++ assert("nikita-1479", LOCK_CNT_GTZ(rw_locked_tree)); ++ ++ cache = &tree->cbk_cache; ++ assert("nikita-2470", cbk_cache_invariant(cache)); ++ ++ write_lock(&(cache->guard)); ++ for (i = 0, slot = cache->slot; i < cache->nr_slots; ++i, ++slot) { ++ if (slot->node == node) { ++ list_move_tail(&slot->lru, &cache->lru); ++ slot->node = NULL; ++ break; ++ } ++ } ++ write_unlock(&(cache->guard)); ++ assert("nikita-2471", cbk_cache_invariant(cache)); ++} ++ ++/* add to the cbk-cache in the "tree" information about "node". This ++ can actually be update of existing slot in a cache. */ ++static void cbk_cache_add(const znode * node/* node to add to the cache */) ++{ ++ cbk_cache *cache; ++ ++ cbk_cache_slot *slot; ++ int i; ++ ++ assert("nikita-352", node != NULL); ++ ++ cache = &znode_get_tree(node)->cbk_cache; ++ assert("nikita-2472", cbk_cache_invariant(cache)); ++ ++ if (cache->nr_slots == 0) ++ return; ++ ++ write_lock(&(cache->guard)); ++ /* find slot to update/add */ ++ for (i = 0, slot = cache->slot; i < cache->nr_slots; ++i, ++slot) { ++ /* oops, this node is already in a cache */ ++ if (slot->node == node) ++ break; ++ } ++ /* if all slots are used, reuse least recently used one */ ++ if (i == cache->nr_slots) { ++ slot = list_entry(cache->lru.prev, cbk_cache_slot, lru); ++ slot->node = (znode *) node; ++ } ++ list_move(&slot->lru, &cache->lru); ++ write_unlock(&(cache->guard)); ++ assert("nikita-2473", cbk_cache_invariant(cache)); ++} ++ ++static int setup_delimiting_keys(cbk_handle * h); ++static lookup_result coord_by_handle(cbk_handle * handle); ++static lookup_result traverse_tree(cbk_handle * h); ++static int cbk_cache_search(cbk_handle * h); ++ ++static level_lookup_result cbk_level_lookup(cbk_handle * h); ++static level_lookup_result cbk_node_lookup(cbk_handle * h); ++ ++/* helper functions */ ++ ++static void update_stale_dk(reiser4_tree * tree, znode * node); ++ ++/* release parent node during traversal */ ++static void put_parent(cbk_handle * h); ++/* check consistency of fields */ ++static int sanity_check(cbk_handle * h); ++/* release resources in handle */ ++static void hput(cbk_handle * h); ++ ++static level_lookup_result search_to_left(cbk_handle * h); ++ ++/* pack numerous (numberous I should say) arguments of coord_by_key() into ++ * cbk_handle */ ++static cbk_handle *cbk_pack(cbk_handle * handle, ++ reiser4_tree * tree, ++ const reiser4_key * key, ++ coord_t *coord, ++ lock_handle * active_lh, ++ lock_handle * parent_lh, ++ znode_lock_mode lock_mode, ++ lookup_bias bias, ++ tree_level lock_level, ++ tree_level stop_level, ++ __u32 flags, ra_info_t *info) ++{ ++ memset(handle, 0, sizeof *handle); ++ ++ handle->tree = tree; ++ handle->key = key; ++ handle->lock_mode = lock_mode; ++ handle->bias = bias; ++ handle->lock_level = lock_level; ++ handle->stop_level = stop_level; ++ handle->coord = coord; ++ /* set flags. See comment in tree.h:cbk_flags */ ++ handle->flags = flags | CBK_TRUST_DK | CBK_USE_CRABLOCK; ++ ++ handle->active_lh = active_lh; ++ handle->parent_lh = parent_lh; ++ handle->ra_info = info; ++ return handle; ++} ++ ++/* main tree lookup procedure ++ ++ Check coord cache. If key we are looking for is not found there, call cbk() ++ to do real tree traversal. ++ ++ As we have extents on the twig level, @lock_level and @stop_level can ++ be different from LEAF_LEVEL and each other. ++ ++ Thread cannot keep any reiser4 locks (tree, znode, dk spin-locks, or znode ++ long term locks) while calling this. ++*/ ++lookup_result coord_by_key(reiser4_tree * tree /* tree to perform search ++ * in. Usually this tree is ++ * part of file-system ++ * super-block */ , ++ const reiser4_key * key /* key to look for */ , ++ coord_t *coord /* where to store found ++ * position in a tree. Fields ++ * in "coord" are only valid if ++ * coord_by_key() returned ++ * "CBK_COORD_FOUND" */ , ++ lock_handle * lh, /* resulting lock handle */ ++ znode_lock_mode lock_mode /* type of lookup we ++ * want on node. Pass ++ * ZNODE_READ_LOCK here ++ * if you only want to ++ * read item found and ++ * ZNODE_WRITE_LOCK if ++ * you want to modify ++ * it */ , ++ lookup_bias bias /* what to return if coord ++ * with exactly the @key is ++ * not in the tree */ , ++ tree_level lock_level/* tree level where to start ++ * taking @lock type of ++ * locks */ , ++ tree_level stop_level/* tree level to stop. Pass ++ * LEAF_LEVEL or TWIG_LEVEL ++ * here Item being looked ++ * for has to be between ++ * @lock_level and ++ * @stop_level, inclusive */ , ++ __u32 flags /* search flags */ , ++ ra_info_t * ++ info ++ /* information about desired tree traversal ++ * readahead */ ++ ) ++{ ++ cbk_handle handle; ++ lock_handle parent_lh; ++ lookup_result result; ++ ++ init_lh(lh); ++ init_lh(&parent_lh); ++ ++ assert("nikita-3023", reiser4_schedulable()); ++ ++ assert("nikita-353", tree != NULL); ++ assert("nikita-354", key != NULL); ++ assert("nikita-355", coord != NULL); ++ assert("nikita-356", (bias == FIND_EXACT) ++ || (bias == FIND_MAX_NOT_MORE_THAN)); ++ assert("nikita-357", stop_level >= LEAF_LEVEL); ++ /* no locks can be held during tree traversal */ ++ assert("nikita-2104", lock_stack_isclean(get_current_lock_stack())); ++ ++ cbk_pack(&handle, ++ tree, ++ key, ++ coord, ++ lh, ++ &parent_lh, ++ lock_mode, bias, lock_level, stop_level, flags, info); ++ ++ result = coord_by_handle(&handle); ++ assert("nikita-3247", ++ ergo(!IS_CBKERR(result), coord->node == lh->node)); ++ return result; ++} ++ ++/* like coord_by_key(), but starts traversal from vroot of @object rather than ++ * from tree root. */ ++lookup_result reiser4_object_lookup(struct inode *object, ++ const reiser4_key * key, ++ coord_t *coord, ++ lock_handle * lh, ++ znode_lock_mode lock_mode, ++ lookup_bias bias, ++ tree_level lock_level, ++ tree_level stop_level, __u32 flags, ++ ra_info_t *info) ++{ ++ cbk_handle handle; ++ lock_handle parent_lh; ++ lookup_result result; ++ ++ init_lh(lh); ++ init_lh(&parent_lh); ++ ++ assert("nikita-3023", reiser4_schedulable()); ++ ++ assert("nikita-354", key != NULL); ++ assert("nikita-355", coord != NULL); ++ assert("nikita-356", (bias == FIND_EXACT) ++ || (bias == FIND_MAX_NOT_MORE_THAN)); ++ assert("nikita-357", stop_level >= LEAF_LEVEL); ++ /* no locks can be held during tree search by key */ ++ assert("nikita-2104", lock_stack_isclean(get_current_lock_stack())); ++ ++ cbk_pack(&handle, ++ object != NULL ? reiser4_tree_by_inode(object) : current_tree, ++ key, ++ coord, ++ lh, ++ &parent_lh, ++ lock_mode, bias, lock_level, stop_level, flags, info); ++ handle.object = object; ++ ++ result = coord_by_handle(&handle); ++ assert("nikita-3247", ++ ergo(!IS_CBKERR(result), coord->node == lh->node)); ++ return result; ++} ++ ++/* lookup by cbk_handle. Common part of coord_by_key() and ++ reiser4_object_lookup(). */ ++static lookup_result coord_by_handle(cbk_handle * handle) ++{ ++ /* ++ * first check cbk_cache (which is look-aside cache for our tree) and ++ * of this fails, start traversal. ++ */ ++ /* first check whether "key" is in cache of recent lookups. */ ++ if (cbk_cache_search(handle) == 0) ++ return handle->result; ++ else ++ return traverse_tree(handle); ++} ++ ++/* Execute actor for each item (or unit, depending on @through_units_p), ++ starting from @coord, right-ward, until either: ++ ++ - end of the tree is reached ++ - unformatted node is met ++ - error occurred ++ - @actor returns 0 or less ++ ++ Error code, or last actor return value is returned. ++ ++ This is used by plugin/dir/hashe_dir.c:reiser4_find_entry() to move through ++ sequence of entries with identical keys and alikes. ++*/ ++int reiser4_iterate_tree(reiser4_tree * tree /* tree to scan */ , ++ coord_t *coord /* coord to start from */ , ++ lock_handle * lh /* lock handle to start with and to ++ * update along the way */ , ++ tree_iterate_actor_t actor /* function to call on each ++ * item/unit */ , ++ void *arg /* argument to pass to @actor */ , ++ znode_lock_mode mode /* lock mode on scanned nodes */ , ++ int through_units_p /* call @actor on each item or on ++ * each unit */ ) ++{ ++ int result; ++ ++ assert("nikita-1143", tree != NULL); ++ assert("nikita-1145", coord != NULL); ++ assert("nikita-1146", lh != NULL); ++ assert("nikita-1147", actor != NULL); ++ ++ result = zload(coord->node); ++ coord_clear_iplug(coord); ++ if (result != 0) ++ return result; ++ if (!coord_is_existing_unit(coord)) { ++ zrelse(coord->node); ++ return -ENOENT; ++ } ++ while ((result = actor(tree, coord, lh, arg)) > 0) { ++ /* move further */ ++ if ((through_units_p && coord_next_unit(coord)) || ++ (!through_units_p && coord_next_item(coord))) { ++ do { ++ lock_handle couple; ++ ++ /* move to the next node */ ++ init_lh(&couple); ++ result = ++ reiser4_get_right_neighbor(&couple, ++ coord->node, ++ (int)mode, ++ GN_CAN_USE_UPPER_LEVELS); ++ zrelse(coord->node); ++ if (result == 0) { ++ ++ result = zload(couple.node); ++ if (result != 0) { ++ done_lh(&couple); ++ return result; ++ } ++ ++ coord_init_first_unit(coord, ++ couple.node); ++ done_lh(lh); ++ move_lh(lh, &couple); ++ } else ++ return result; ++ } while (node_is_empty(coord->node)); ++ } ++ ++ assert("nikita-1149", coord_is_existing_unit(coord)); ++ } ++ zrelse(coord->node); ++ return result; ++} ++ ++/* return locked uber znode for @tree */ ++int get_uber_znode(reiser4_tree * tree, znode_lock_mode mode, ++ znode_lock_request pri, lock_handle * lh) ++{ ++ int result; ++ ++ result = longterm_lock_znode(lh, tree->uber, mode, pri); ++ return result; ++} ++ ++/* true if @key is strictly within @node ++ ++ we are looking for possibly non-unique key and it is item is at the edge of ++ @node. May be it is in the neighbor. ++*/ ++static int znode_contains_key_strict(znode * node /* node to check key ++ * against */ , ++ const reiser4_key * ++ key /* key to check */ , ++ int isunique) ++{ ++ int answer; ++ ++ assert("nikita-1760", node != NULL); ++ assert("nikita-1722", key != NULL); ++ ++ if (keyge(key, &node->rd_key)) ++ return 0; ++ ++ answer = keycmp(&node->ld_key, key); ++ ++ if (isunique) ++ return answer != GREATER_THAN; ++ else ++ return answer == LESS_THAN; ++} ++ ++/* ++ * Virtual Root (vroot) code. ++ * ++ * For given file system object (e.g., regular file or directory) let's ++ * define its "virtual root" as lowest in the tree (that is, furtherest ++ * from the tree root) node such that all body items of said object are ++ * located in a tree rooted at this node. ++ * ++ * Once vroot of object is found all tree lookups for items within body of ++ * this object ("object lookups") can be started from its vroot rather ++ * than from real root. This has following advantages: ++ * ++ * 1. amount of nodes traversed during lookup (and, hence, amount of ++ * key comparisons made) decreases, and ++ * ++ * 2. contention on tree root is decreased. This latter was actually ++ * motivating reason behind vroot, because spin lock of root node, ++ * which is taken when acquiring long-term lock on root node is the ++ * hottest lock in the reiser4. ++ * ++ * How to find vroot. ++ * ++ * When vroot of object F is not yet determined, all object lookups start ++ * from the root of the tree. At each tree level during traversal we have ++ * a node N such that a key we are looking for (which is the key inside ++ * object's body) is located within N. In function handle_vroot() called ++ * from cbk_level_lookup() we check whether N is possible vroot for ++ * F. Check is trivial---if neither leftmost nor rightmost item of N ++ * belongs to F (and we already have helpful ->owns_item() method of ++ * object plugin for this), then N is possible vroot of F. This, of ++ * course, relies on the assumption that each object occupies contiguous ++ * range of keys in the tree. ++ * ++ * Thus, traversing tree downward and checking each node as we go, we can ++ * find lowest such node, which, by definition, is vroot. ++ * ++ * How to track vroot. ++ * ++ * Nohow. If actual vroot changes, next object lookup will just restart ++ * from the actual tree root, refreshing object's vroot along the way. ++ * ++ */ ++ ++/* ++ * Check whether @node is possible vroot of @object. ++ */ ++static void handle_vroot(struct inode *object, znode * node) ++{ ++ file_plugin *fplug; ++ coord_t coord; ++ ++ fplug = inode_file_plugin(object); ++ assert("nikita-3353", fplug != NULL); ++ assert("nikita-3354", fplug->owns_item != NULL); ++ ++ if (unlikely(node_is_empty(node))) ++ return; ++ ++ coord_init_first_unit(&coord, node); ++ /* ++ * if leftmost item of @node belongs to @object, we cannot be sure ++ * that @node is vroot of @object, because, some items of @object are ++ * probably in the sub-tree rooted at the left neighbor of @node. ++ */ ++ if (fplug->owns_item(object, &coord)) ++ return; ++ coord_init_last_unit(&coord, node); ++ /* mutatis mutandis for the rightmost item */ ++ if (fplug->owns_item(object, &coord)) ++ return; ++ /* otherwise, @node is possible vroot of @object */ ++ inode_set_vroot(object, node); ++} ++ ++/* ++ * helper function used by traverse tree to start tree traversal not from the ++ * tree root, but from @h->object's vroot, if possible. ++ */ ++static int prepare_object_lookup(cbk_handle * h) ++{ ++ znode *vroot; ++ int result; ++ ++ vroot = inode_get_vroot(h->object); ++ if (vroot == NULL) { ++ /* ++ * object doesn't have known vroot, start from real tree root. ++ */ ++ return LOOKUP_CONT; ++ } ++ ++ h->level = znode_get_level(vroot); ++ /* take a long-term lock on vroot */ ++ h->result = longterm_lock_znode(h->active_lh, vroot, ++ cbk_lock_mode(h->level, h), ++ ZNODE_LOCK_LOPRI); ++ result = LOOKUP_REST; ++ if (h->result == 0) { ++ int isunique; ++ int inside; ++ ++ isunique = h->flags & CBK_UNIQUE; ++ /* check that key is inside vroot */ ++ read_lock_dk(h->tree); ++ inside = (znode_contains_key_strict(vroot, h->key, isunique) && ++ !ZF_ISSET(vroot, JNODE_HEARD_BANSHEE)); ++ read_unlock_dk(h->tree); ++ if (inside) { ++ h->result = zload(vroot); ++ if (h->result == 0) { ++ /* search for key in vroot. */ ++ result = cbk_node_lookup(h); ++ zrelse(vroot); /*h->active_lh->node); */ ++ if (h->active_lh->node != vroot) { ++ result = LOOKUP_REST; ++ } else if (result == LOOKUP_CONT) { ++ move_lh(h->parent_lh, h->active_lh); ++ h->flags &= ~CBK_DKSET; ++ } ++ } ++ } ++ } ++ ++ zput(vroot); ++ ++ if (IS_CBKERR(h->result) || result == LOOKUP_REST) ++ hput(h); ++ return result; ++} ++ ++/* main function that handles common parts of tree traversal: starting ++ (fake znode handling), restarts, error handling, completion */ ++static lookup_result traverse_tree(cbk_handle * h/* search handle */) ++{ ++ int done; ++ int iterations; ++ int vroot_used; ++ ++ assert("nikita-365", h != NULL); ++ assert("nikita-366", h->tree != NULL); ++ assert("nikita-367", h->key != NULL); ++ assert("nikita-368", h->coord != NULL); ++ assert("nikita-369", (h->bias == FIND_EXACT) ++ || (h->bias == FIND_MAX_NOT_MORE_THAN)); ++ assert("nikita-370", h->stop_level >= LEAF_LEVEL); ++ assert("nikita-2949", !(h->flags & CBK_DKSET)); ++ assert("zam-355", lock_stack_isclean(get_current_lock_stack())); ++ ++ done = 0; ++ iterations = 0; ++ vroot_used = 0; ++ ++ /* loop for restarts */ ++restart: ++ ++ assert("nikita-3024", reiser4_schedulable()); ++ ++ h->result = CBK_COORD_FOUND; ++ /* connect_znode() needs it */ ++ h->ld_key = *reiser4_min_key(); ++ h->rd_key = *reiser4_max_key(); ++ h->flags |= CBK_DKSET; ++ h->error = NULL; ++ ++ if (!vroot_used && h->object != NULL) { ++ vroot_used = 1; ++ done = prepare_object_lookup(h); ++ if (done == LOOKUP_REST) ++ goto restart; ++ else if (done == LOOKUP_DONE) ++ return h->result; ++ } ++ if (h->parent_lh->node == NULL) { ++ done = ++ get_uber_znode(h->tree, ZNODE_READ_LOCK, ZNODE_LOCK_LOPRI, ++ h->parent_lh); ++ ++ assert("nikita-1637", done != -E_DEADLOCK); ++ ++ h->block = h->tree->root_block; ++ h->level = h->tree->height; ++ h->coord->node = h->parent_lh->node; ++ ++ if (done != 0) ++ return done; ++ } ++ ++ /* loop descending a tree */ ++ while (!done) { ++ ++ if (unlikely((iterations > REISER4_CBK_ITERATIONS_LIMIT) && ++ IS_POW(iterations))) { ++ warning("nikita-1481", "Too many iterations: %i", ++ iterations); ++ reiser4_print_key("key", h->key); ++ ++iterations; ++ } else if (unlikely(iterations > REISER4_MAX_CBK_ITERATIONS)) { ++ h->error = ++ "reiser-2018: Too many iterations. Tree corrupted, or (less likely) starvation occurring."; ++ h->result = RETERR(-EIO); ++ break; ++ } ++ switch (cbk_level_lookup(h)) { ++ case LOOKUP_CONT: ++ move_lh(h->parent_lh, h->active_lh); ++ continue; ++ default: ++ wrong_return_value("nikita-372", "cbk_level"); ++ case LOOKUP_DONE: ++ done = 1; ++ break; ++ case LOOKUP_REST: ++ hput(h); ++ /* deadlock avoidance is normal case. */ ++ if (h->result != -E_DEADLOCK) ++ ++iterations; ++ reiser4_preempt_point(); ++ goto restart; ++ } ++ } ++ /* that's all. The rest is error handling */ ++ if (unlikely(h->error != NULL)) { ++ warning("nikita-373", "%s: level: %i, " ++ "lock_level: %i, stop_level: %i " ++ "lock_mode: %s, bias: %s", ++ h->error, h->level, h->lock_level, h->stop_level, ++ lock_mode_name(h->lock_mode), bias_name(h->bias)); ++ reiser4_print_address("block", &h->block); ++ reiser4_print_key("key", h->key); ++ print_coord_content("coord", h->coord); ++ } ++ /* `unlikely' error case */ ++ if (unlikely(IS_CBKERR(h->result))) { ++ /* failure. do cleanup */ ++ hput(h); ++ } else { ++ assert("nikita-1605", WITH_DATA_RET ++ (h->coord->node, 1, ++ ergo((h->result == CBK_COORD_FOUND) && ++ (h->bias == FIND_EXACT) && ++ (!node_is_empty(h->coord->node)), ++ coord_is_existing_item(h->coord)))); ++ } ++ return h->result; ++} ++ ++/* find delimiting keys of child ++ ++ Determine left and right delimiting keys for child pointed to by ++ @parent_coord. ++ ++*/ ++static void find_child_delimiting_keys(znode * parent /* parent znode, passed ++ * locked */ , ++ const coord_t *parent_coord ++ /* coord where pointer ++ * to child is stored ++ */ , ++ reiser4_key * ld /* where to store left ++ * delimiting key */ , ++ reiser4_key * rd /* where to store right ++ * delimiting key */ ) ++{ ++ coord_t neighbor; ++ ++ assert("nikita-1484", parent != NULL); ++ assert_rw_locked(&(znode_get_tree(parent)->dk_lock)); ++ ++ coord_dup(&neighbor, parent_coord); ++ ++ if (neighbor.between == AT_UNIT) ++ /* imitate item ->lookup() behavior. */ ++ neighbor.between = AFTER_UNIT; ++ ++ if (coord_set_to_left(&neighbor) == 0) ++ unit_key_by_coord(&neighbor, ld); ++ else { ++ assert("nikita-14851", 0); ++ *ld = *znode_get_ld_key(parent); ++ } ++ ++ coord_dup(&neighbor, parent_coord); ++ if (neighbor.between == AT_UNIT) ++ neighbor.between = AFTER_UNIT; ++ if (coord_set_to_right(&neighbor) == 0) ++ unit_key_by_coord(&neighbor, rd); ++ else ++ *rd = *znode_get_rd_key(parent); ++} ++ ++/* ++ * setup delimiting keys for a child ++ * ++ * @parent parent node ++ * ++ * @coord location in @parent where pointer to @child is ++ * ++ * @child child node ++ */ ++int ++set_child_delimiting_keys(znode * parent, const coord_t *coord, znode * child) ++{ ++ reiser4_tree *tree; ++ ++ assert("nikita-2952", ++ znode_get_level(parent) == znode_get_level(coord->node)); ++ ++ /* fast check without taking dk lock. This is safe, because ++ * JNODE_DKSET is never cleared once set. */ ++ if (!ZF_ISSET(child, JNODE_DKSET)) { ++ tree = znode_get_tree(parent); ++ write_lock_dk(tree); ++ if (likely(!ZF_ISSET(child, JNODE_DKSET))) { ++ find_child_delimiting_keys(parent, coord, ++ &child->ld_key, ++ &child->rd_key); ++ ON_DEBUG(child->ld_key_version = ++ atomic_inc_return(&delim_key_version); ++ child->rd_key_version = ++ atomic_inc_return(&delim_key_version);); ++ ZF_SET(child, JNODE_DKSET); ++ } ++ write_unlock_dk(tree); ++ return 1; ++ } ++ return 0; ++} ++ ++/* Perform tree lookup at one level. This is called from cbk_traverse() ++ function that drives lookup through tree and calls cbk_node_lookup() to ++ perform lookup within one node. ++ ++ See comments in a code. ++*/ ++static level_lookup_result cbk_level_lookup(cbk_handle * h/* search handle */) ++{ ++ int ret; ++ int setdk; ++ int ldkeyset = 0; ++ reiser4_key ldkey; ++ reiser4_key key; ++ znode *active; ++ ++ assert("nikita-3025", reiser4_schedulable()); ++ ++ /* acquire reference to @active node */ ++ active = ++ zget(h->tree, &h->block, h->parent_lh->node, h->level, ++ reiser4_ctx_gfp_mask_get()); ++ ++ if (IS_ERR(active)) { ++ h->result = PTR_ERR(active); ++ return LOOKUP_DONE; ++ } ++ ++ /* lock @active */ ++ h->result = longterm_lock_znode(h->active_lh, ++ active, ++ cbk_lock_mode(h->level, h), ++ ZNODE_LOCK_LOPRI); ++ /* longterm_lock_znode() acquires additional reference to znode (which ++ will be later released by longterm_unlock_znode()). Release ++ reference acquired by zget(). ++ */ ++ zput(active); ++ if (unlikely(h->result != 0)) ++ goto fail_or_restart; ++ ++ setdk = 0; ++ /* if @active is accessed for the first time, setup delimiting keys on ++ it. Delimiting keys are taken from the parent node. See ++ setup_delimiting_keys() for details. ++ */ ++ if (h->flags & CBK_DKSET) { ++ setdk = setup_delimiting_keys(h); ++ h->flags &= ~CBK_DKSET; ++ } else { ++ znode *parent; ++ ++ parent = h->parent_lh->node; ++ h->result = zload(parent); ++ if (unlikely(h->result != 0)) ++ goto fail_or_restart; ++ ++ if (!ZF_ISSET(active, JNODE_DKSET)) ++ setdk = set_child_delimiting_keys(parent, ++ h->coord, active); ++ else { ++ read_lock_dk(h->tree); ++ find_child_delimiting_keys(parent, h->coord, &ldkey, ++ &key); ++ read_unlock_dk(h->tree); ++ ldkeyset = 1; ++ } ++ zrelse(parent); ++ } ++ ++ /* this is ugly kludge. Reminder: this is necessary, because ++ ->lookup() method returns coord with ->between field probably set ++ to something different from AT_UNIT. ++ */ ++ h->coord->between = AT_UNIT; ++ ++ if (znode_just_created(active) && (h->coord->node != NULL)) { ++ write_lock_tree(h->tree); ++ /* if we are going to load znode right now, setup ++ ->in_parent: coord where pointer to this node is stored in ++ parent. ++ */ ++ coord_to_parent_coord(h->coord, &active->in_parent); ++ write_unlock_tree(h->tree); ++ } ++ ++ /* check connectedness without holding tree lock---false negatives ++ * will be re-checked by connect_znode(), and false positives are ++ * impossible---@active cannot suddenly turn into unconnected ++ * state. */ ++ if (!znode_is_connected(active)) { ++ h->result = connect_znode(h->coord, active); ++ if (unlikely(h->result != 0)) { ++ put_parent(h); ++ goto fail_or_restart; ++ } ++ } ++ ++ jload_prefetch(ZJNODE(active)); ++ ++ if (setdk) ++ update_stale_dk(h->tree, active); ++ ++ /* put_parent() cannot be called earlier, because connect_znode() ++ assumes parent node is referenced; */ ++ put_parent(h); ++ ++ if ((!znode_contains_key_lock(active, h->key) && ++ (h->flags & CBK_TRUST_DK)) ++ || ZF_ISSET(active, JNODE_HEARD_BANSHEE)) { ++ /* 1. key was moved out of this node while this thread was ++ waiting for the lock. Restart. More elaborate solution is ++ to determine where key moved (to the left, or to the right) ++ and try to follow it through sibling pointers. ++ ++ 2. or, node itself is going to be removed from the ++ tree. Release lock and restart. ++ */ ++ h->result = -E_REPEAT; ++ } ++ if (h->result == -E_REPEAT) ++ return LOOKUP_REST; ++ ++ h->result = zload_ra(active, h->ra_info); ++ if (h->result) ++ return LOOKUP_DONE; ++ ++ /* sanity checks */ ++ if (sanity_check(h)) { ++ zrelse(active); ++ return LOOKUP_DONE; ++ } ++ ++ /* check that key of leftmost item in the @active is the same as in ++ * its parent */ ++ if (ldkeyset && !node_is_empty(active) && ++ !keyeq(leftmost_key_in_node(active, &key), &ldkey)) { ++ warning("vs-3533", "Keys are inconsistent. Fsck?"); ++ reiser4_print_key("inparent", &ldkey); ++ reiser4_print_key("inchild", &key); ++ h->result = RETERR(-EIO); ++ zrelse(active); ++ return LOOKUP_DONE; ++ } ++ ++ if (h->object != NULL) ++ handle_vroot(h->object, active); ++ ++ ret = cbk_node_lookup(h); ++ ++ /* h->active_lh->node might change, but active is yet to be zrelsed */ ++ zrelse(active); ++ ++ return ret; ++ ++fail_or_restart: ++ if (h->result == -E_DEADLOCK) ++ return LOOKUP_REST; ++ return LOOKUP_DONE; ++} ++ ++#if REISER4_DEBUG ++/* check left and right delimiting keys of a znode */ ++void check_dkeys(znode * node) ++{ ++ znode *left; ++ znode *right; ++ ++ read_lock_tree(current_tree); ++ read_lock_dk(current_tree); ++ ++ assert("vs-1710", znode_is_any_locked(node)); ++ assert("vs-1197", ++ !keygt(znode_get_ld_key(node), znode_get_rd_key(node))); ++ ++ left = node->left; ++ right = node->right; ++ ++ if (ZF_ISSET(node, JNODE_LEFT_CONNECTED) && ZF_ISSET(node, JNODE_DKSET) ++ && left != NULL && ZF_ISSET(left, JNODE_DKSET)) ++ /* check left neighbor. Note that left neighbor is not locked, ++ so it might get wrong delimiting keys therefore */ ++ assert("vs-1198", ++ (keyeq(znode_get_rd_key(left), znode_get_ld_key(node)) ++ || ZF_ISSET(left, JNODE_HEARD_BANSHEE))); ++ ++ if (ZF_ISSET(node, JNODE_RIGHT_CONNECTED) && ZF_ISSET(node, JNODE_DKSET) ++ && right != NULL && ZF_ISSET(right, JNODE_DKSET)) ++ /* check right neighbor. Note that right neighbor is not ++ locked, so it might get wrong delimiting keys therefore */ ++ assert("vs-1199", ++ (keyeq(znode_get_rd_key(node), znode_get_ld_key(right)) ++ || ZF_ISSET(right, JNODE_HEARD_BANSHEE))); ++ ++ read_unlock_dk(current_tree); ++ read_unlock_tree(current_tree); ++} ++#endif ++ ++/* true if @key is left delimiting key of @node */ ++static int key_is_ld(znode * node, const reiser4_key * key) ++{ ++ int ld; ++ ++ assert("nikita-1716", node != NULL); ++ assert("nikita-1758", key != NULL); ++ ++ read_lock_dk(znode_get_tree(node)); ++ assert("nikita-1759", znode_contains_key(node, key)); ++ ld = keyeq(znode_get_ld_key(node), key); ++ read_unlock_dk(znode_get_tree(node)); ++ return ld; ++} ++ ++/* Process one node during tree traversal. ++ ++ This is called by cbk_level_lookup(). */ ++static level_lookup_result cbk_node_lookup(cbk_handle * h/* search handle */) ++{ ++ /* node plugin of @active */ ++ node_plugin *nplug; ++ /* item plugin of item that was found */ ++ item_plugin *iplug; ++ /* search bias */ ++ lookup_bias node_bias; ++ /* node we are operating upon */ ++ znode *active; ++ /* tree we are searching in */ ++ reiser4_tree *tree; ++ /* result */ ++ int result; ++ ++ assert("nikita-379", h != NULL); ++ ++ active = h->active_lh->node; ++ tree = h->tree; ++ ++ nplug = active->nplug; ++ assert("nikita-380", nplug != NULL); ++ ++ ON_DEBUG(check_dkeys(active)); ++ ++ /* return item from "active" node with maximal key not greater than ++ "key" */ ++ node_bias = h->bias; ++ result = nplug->lookup(active, h->key, node_bias, h->coord); ++ if (unlikely(result != NS_FOUND && result != NS_NOT_FOUND)) { ++ /* error occurred */ ++ h->result = result; ++ return LOOKUP_DONE; ++ } ++ if (h->level == h->stop_level) { ++ /* welcome to the stop level */ ++ assert("nikita-381", h->coord->node == active); ++ if (result == NS_FOUND) { ++ /* success of tree lookup */ ++ if (!(h->flags & CBK_UNIQUE) ++ && key_is_ld(active, h->key)) ++ return search_to_left(h); ++ else ++ h->result = CBK_COORD_FOUND; ++ } else { ++ h->result = CBK_COORD_NOTFOUND; ++ } ++ if (!(h->flags & CBK_IN_CACHE)) ++ cbk_cache_add(active); ++ return LOOKUP_DONE; ++ } ++ ++ if (h->level > TWIG_LEVEL && result == NS_NOT_FOUND) { ++ h->error = "not found on internal node"; ++ h->result = result; ++ return LOOKUP_DONE; ++ } ++ ++ assert("vs-361", h->level > h->stop_level); ++ ++ if (handle_eottl(h, &result)) { ++ assert("vs-1674", (result == LOOKUP_DONE || ++ result == LOOKUP_REST)); ++ return result; ++ } ++ ++ /* go down to next level */ ++ check_me("vs-12", zload(h->coord->node) == 0); ++ assert("nikita-2116", item_is_internal(h->coord)); ++ iplug = item_plugin_by_coord(h->coord); ++ iplug->s.internal.down_link(h->coord, h->key, &h->block); ++ zrelse(h->coord->node); ++ --h->level; ++ return LOOKUP_CONT; /* continue */ ++} ++ ++/* scan cbk_cache slots looking for a match for @h */ ++static int cbk_cache_scan_slots(cbk_handle * h/* cbk handle */) ++{ ++ level_lookup_result llr; ++ znode *node; ++ reiser4_tree *tree; ++ cbk_cache_slot *slot; ++ cbk_cache *cache; ++ tree_level level; ++ int isunique; ++ const reiser4_key *key; ++ int result; ++ ++ assert("nikita-1317", h != NULL); ++ assert("nikita-1315", h->tree != NULL); ++ assert("nikita-1316", h->key != NULL); ++ ++ tree = h->tree; ++ cache = &tree->cbk_cache; ++ if (cache->nr_slots == 0) ++ /* size of cbk cache was set to 0 by mount time option. */ ++ return RETERR(-ENOENT); ++ ++ assert("nikita-2474", cbk_cache_invariant(cache)); ++ node = NULL; /* to keep gcc happy */ ++ level = h->level; ++ key = h->key; ++ isunique = h->flags & CBK_UNIQUE; ++ result = RETERR(-ENOENT); ++ ++ /* ++ * this is time-critical function and dragons had, hence, been settled ++ * here. ++ * ++ * Loop below scans cbk cache slots trying to find matching node with ++ * suitable range of delimiting keys and located at the h->level. ++ * ++ * Scan is done under cbk cache spin lock that protects slot->node ++ * pointers. If suitable node is found we want to pin it in ++ * memory. But slot->node can point to the node with x_count 0 ++ * (unreferenced). Such node can be recycled at any moment, or can ++ * already be in the process of being recycled (within jput()). ++ * ++ * As we found node in the cbk cache, it means that jput() hasn't yet ++ * called cbk_cache_invalidate(). ++ * ++ * We acquire reference to the node without holding tree lock, and ++ * later, check node's RIP bit. This avoids races with jput(). ++ */ ++ ++ rcu_read_lock(); ++ read_lock(&((cbk_cache *)cache)->guard); ++ ++ slot = list_entry(cache->lru.next, cbk_cache_slot, lru); ++ slot = list_entry(slot->lru.prev, cbk_cache_slot, lru); ++ BUG_ON(&slot->lru != &cache->lru);/*????*/ ++ while (1) { ++ ++ slot = list_entry(slot->lru.next, cbk_cache_slot, lru); ++ ++ if (&cache->lru != &slot->lru) ++ node = slot->node; ++ else ++ node = NULL; ++ ++ if (unlikely(node == NULL)) ++ break; ++ ++ /* ++ * this is (hopefully) the only place in the code where we are ++ * working with delimiting keys without holding dk lock. This ++ * is fine here, because this is only "guess" anyway---keys ++ * are rechecked under dk lock below. ++ */ ++ if (znode_get_level(node) == level && ++ /* reiser4_min_key < key < reiser4_max_key */ ++ znode_contains_key_strict(node, key, isunique)) { ++ zref(node); ++ result = 0; ++ spin_lock_prefetch(&tree->tree_lock); ++ break; ++ } ++ } ++ read_unlock(&((cbk_cache *)cache)->guard); ++ ++ assert("nikita-2475", cbk_cache_invariant(cache)); ++ ++ if (unlikely(result == 0 && ZF_ISSET(node, JNODE_RIP))) ++ result = -ENOENT; ++ ++ rcu_read_unlock(); ++ ++ if (result != 0) { ++ h->result = CBK_COORD_NOTFOUND; ++ return RETERR(-ENOENT); ++ } ++ ++ result = ++ longterm_lock_znode(h->active_lh, node, cbk_lock_mode(level, h), ++ ZNODE_LOCK_LOPRI); ++ zput(node); ++ if (result != 0) ++ return result; ++ result = zload(node); ++ if (result != 0) ++ return result; ++ ++ /* recheck keys */ ++ read_lock_dk(tree); ++ result = (znode_contains_key_strict(node, key, isunique) && ++ !ZF_ISSET(node, JNODE_HEARD_BANSHEE)); ++ read_unlock_dk(tree); ++ if (result) { ++ /* do lookup inside node */ ++ llr = cbk_node_lookup(h); ++ /* if cbk_node_lookup() wandered to another node (due to eottl ++ or non-unique keys), adjust @node */ ++ /*node = h->active_lh->node; */ ++ ++ if (llr != LOOKUP_DONE) { ++ /* restart or continue on the next level */ ++ result = RETERR(-ENOENT); ++ } else if (IS_CBKERR(h->result)) ++ /* io or oom */ ++ result = RETERR(-ENOENT); ++ else { ++ /* good. Either item found or definitely not found. */ ++ result = 0; ++ ++ write_lock(&(cache->guard)); ++ if (slot->node == h->active_lh->node) { ++ /* if this node is still in cbk cache---move ++ its slot to the head of the LRU list. */ ++ list_move(&slot->lru, &cache->lru); ++ } ++ write_unlock(&(cache->guard)); ++ } ++ } else { ++ /* race. While this thread was waiting for the lock, node was ++ rebalanced and item we are looking for, shifted out of it ++ (if it ever was here). ++ ++ Continuing scanning is almost hopeless: node key range was ++ moved to, is almost certainly at the beginning of the LRU ++ list at this time, because it's hot, but restarting ++ scanning from the very beginning is complex. Just return, ++ so that cbk() will be performed. This is not that ++ important, because such races should be rare. Are they? ++ */ ++ result = RETERR(-ENOENT); /* -ERAUGHT */ ++ } ++ zrelse(node); ++ assert("nikita-2476", cbk_cache_invariant(cache)); ++ return result; ++} ++ ++/* look for item with given key in the coord cache ++ ++ This function, called by coord_by_key(), scans "coord cache" (&cbk_cache) ++ which is a small LRU list of znodes accessed lately. For each znode in ++ znode in this list, it checks whether key we are looking for fits into key ++ range covered by this node. If so, and in addition, node lies at allowed ++ level (this is to handle extents on a twig level), node is locked, and ++ lookup inside it is performed. ++ ++ we need a measurement of the cost of this cache search compared to the cost ++ of coord_by_key. ++ ++*/ ++static int cbk_cache_search(cbk_handle * h/* cbk handle */) ++{ ++ int result = 0; ++ tree_level level; ++ ++ /* add CBK_IN_CACHE to the handle flags. This means that ++ * cbk_node_lookup() assumes that cbk_cache is scanned and would add ++ * found node to the cache. */ ++ h->flags |= CBK_IN_CACHE; ++ for (level = h->stop_level; level <= h->lock_level; ++level) { ++ h->level = level; ++ result = cbk_cache_scan_slots(h); ++ if (result != 0) { ++ done_lh(h->active_lh); ++ done_lh(h->parent_lh); ++ } else { ++ assert("nikita-1319", !IS_CBKERR(h->result)); ++ break; ++ } ++ } ++ h->flags &= ~CBK_IN_CACHE; ++ return result; ++} ++ ++/* type of lock we want to obtain during tree traversal. On stop level ++ we want type of lock user asked for, on upper levels: read lock. */ ++znode_lock_mode cbk_lock_mode(tree_level level, cbk_handle * h) ++{ ++ assert("nikita-382", h != NULL); ++ ++ return (level <= h->lock_level) ? h->lock_mode : ZNODE_READ_LOCK; ++} ++ ++/* update outdated delimiting keys */ ++static void stale_dk(reiser4_tree * tree, znode * node) ++{ ++ znode *right; ++ ++ read_lock_tree(tree); ++ write_lock_dk(tree); ++ right = node->right; ++ ++ if (ZF_ISSET(node, JNODE_RIGHT_CONNECTED) && ++ right && ZF_ISSET(right, JNODE_DKSET) && ++ !keyeq(znode_get_rd_key(node), znode_get_ld_key(right))) ++ znode_set_rd_key(node, znode_get_ld_key(right)); ++ ++ write_unlock_dk(tree); ++ read_unlock_tree(tree); ++} ++ ++/* check for possibly outdated delimiting keys, and update them if ++ * necessary. */ ++static void update_stale_dk(reiser4_tree * tree, znode * node) ++{ ++ znode *right; ++ reiser4_key rd; ++ ++ read_lock_tree(tree); ++ read_lock_dk(tree); ++ rd = *znode_get_rd_key(node); ++ right = node->right; ++ if (unlikely(ZF_ISSET(node, JNODE_RIGHT_CONNECTED) && ++ right && ZF_ISSET(right, JNODE_DKSET) && ++ !keyeq(&rd, znode_get_ld_key(right)))) { ++ assert("nikita-38211", ZF_ISSET(node, JNODE_DKSET)); ++ read_unlock_dk(tree); ++ read_unlock_tree(tree); ++ stale_dk(tree, node); ++ return; ++ } ++ read_unlock_dk(tree); ++ read_unlock_tree(tree); ++} ++ ++/* ++ * handle searches a the non-unique key. ++ * ++ * Suppose that we are looking for an item with possibly non-unique key 100. ++ * ++ * Root node contains two pointers: one to a node with left delimiting key 0, ++ * and another to a node with left delimiting key 100. Item we interested in ++ * may well happen in the sub-tree rooted at the first pointer. ++ * ++ * To handle this search_to_left() is called when search reaches stop ++ * level. This function checks it is _possible_ that item we are looking for ++ * is in the left neighbor (this can be done by comparing delimiting keys) and ++ * if so, tries to lock left neighbor (this is low priority lock, so it can ++ * deadlock, tree traversal is just restarted if it did) and then checks ++ * whether left neighbor actually contains items with our key. ++ * ++ * Note that this is done on the stop level only. It is possible to try such ++ * left-check on each level, but as duplicate keys are supposed to be rare ++ * (very unlikely that more than one node is completely filled with items with ++ * duplicate keys), it sis cheaper to scan to the left on the stop level once. ++ * ++ */ ++static level_lookup_result search_to_left(cbk_handle * h/* search handle */) ++{ ++ level_lookup_result result; ++ coord_t *coord; ++ znode *node; ++ znode *neighbor; ++ ++ lock_handle lh; ++ ++ assert("nikita-1761", h != NULL); ++ assert("nikita-1762", h->level == h->stop_level); ++ ++ init_lh(&lh); ++ coord = h->coord; ++ node = h->active_lh->node; ++ assert("nikita-1763", coord_is_leftmost_unit(coord)); ++ ++ h->result = ++ reiser4_get_left_neighbor(&lh, node, (int)h->lock_mode, ++ GN_CAN_USE_UPPER_LEVELS); ++ neighbor = NULL; ++ switch (h->result) { ++ case -E_DEADLOCK: ++ result = LOOKUP_REST; ++ break; ++ case 0:{ ++ node_plugin *nplug; ++ coord_t crd; ++ lookup_bias bias; ++ ++ neighbor = lh.node; ++ h->result = zload(neighbor); ++ if (h->result != 0) { ++ result = LOOKUP_DONE; ++ break; ++ } ++ ++ nplug = neighbor->nplug; ++ ++ coord_init_zero(&crd); ++ bias = h->bias; ++ h->bias = FIND_EXACT; ++ h->result = ++ nplug->lookup(neighbor, h->key, h->bias, &crd); ++ h->bias = bias; ++ ++ if (h->result == NS_NOT_FOUND) { ++ case -E_NO_NEIGHBOR: ++ h->result = CBK_COORD_FOUND; ++ if (!(h->flags & CBK_IN_CACHE)) ++ cbk_cache_add(node); ++ default: /* some other error */ ++ result = LOOKUP_DONE; ++ } else if (h->result == NS_FOUND) { ++ read_lock_dk(znode_get_tree(neighbor)); ++ h->rd_key = *znode_get_ld_key(node); ++ leftmost_key_in_node(neighbor, &h->ld_key); ++ read_unlock_dk(znode_get_tree(neighbor)); ++ h->flags |= CBK_DKSET; ++ ++ h->block = *znode_get_block(neighbor); ++ /* clear coord->node so that cbk_level_lookup() ++ wouldn't overwrite parent hint in neighbor. ++ ++ Parent hint was set up by ++ reiser4_get_left_neighbor() ++ */ ++ /* FIXME: why do we have to spinlock here? */ ++ write_lock_tree(znode_get_tree(neighbor)); ++ h->coord->node = NULL; ++ write_unlock_tree(znode_get_tree(neighbor)); ++ result = LOOKUP_CONT; ++ } else { ++ result = LOOKUP_DONE; ++ } ++ if (neighbor != NULL) ++ zrelse(neighbor); ++ } ++ } ++ done_lh(&lh); ++ return result; ++} ++ ++/* debugging aid: return symbolic name of search bias */ ++static const char *bias_name(lookup_bias bias/* bias to get name of */) ++{ ++ if (bias == FIND_EXACT) ++ return "exact"; ++ else if (bias == FIND_MAX_NOT_MORE_THAN) ++ return "left-slant"; ++/* else if( bias == RIGHT_SLANT_BIAS ) */ ++/* return "right-bias"; */ ++ else { ++ static char buf[30]; ++ ++ sprintf(buf, "unknown: %i", bias); ++ return buf; ++ } ++} ++ ++#if REISER4_DEBUG ++/* debugging aid: print human readable information about @p */ ++void print_coord_content(const char *prefix /* prefix to print */ , ++ coord_t *p/* coord to print */) ++{ ++ reiser4_key key; ++ ++ if (p == NULL) { ++ printk("%s: null\n", prefix); ++ return; ++ } ++ if ((p->node != NULL) && znode_is_loaded(p->node) ++ && coord_is_existing_item(p)) ++ printk("%s: data: %p, length: %i\n", prefix, ++ item_body_by_coord(p), item_length_by_coord(p)); ++ if (znode_is_loaded(p->node)) { ++ item_key_by_coord(p, &key); ++ reiser4_print_key(prefix, &key); ++ } ++} ++ ++/* debugging aid: print human readable information about @block */ ++void reiser4_print_address(const char *prefix /* prefix to print */ , ++ const reiser4_block_nr * block/* block number to print */) ++{ ++ printk("%s: %s\n", prefix, sprint_address(block)); ++} ++#endif ++ ++/* return string containing human readable representation of @block */ ++char *sprint_address(const reiser4_block_nr * ++ block/* block number to print */) ++{ ++ static char address[30]; ++ ++ if (block == NULL) ++ sprintf(address, "null"); ++ else if (reiser4_blocknr_is_fake(block)) ++ sprintf(address, "%llx", (unsigned long long)(*block)); ++ else ++ sprintf(address, "%llu", (unsigned long long)(*block)); ++ return address; ++} ++ ++/* release parent node during traversal */ ++static void put_parent(cbk_handle * h/* search handle */) ++{ ++ assert("nikita-383", h != NULL); ++ if (h->parent_lh->node != NULL) ++ longterm_unlock_znode(h->parent_lh); ++} ++ ++/* helper function used by coord_by_key(): release reference to parent znode ++ stored in handle before processing its child. */ ++static void hput(cbk_handle * h/* search handle */) ++{ ++ assert("nikita-385", h != NULL); ++ done_lh(h->parent_lh); ++ done_lh(h->active_lh); ++} ++ ++/* Helper function used by cbk(): update delimiting keys of child node (stored ++ in h->active_lh->node) using key taken from parent on the parent level. */ ++static int setup_delimiting_keys(cbk_handle * h/* search handle */) ++{ ++ znode *active; ++ reiser4_tree *tree; ++ ++ assert("nikita-1088", h != NULL); ++ ++ active = h->active_lh->node; ++ ++ /* fast check without taking dk lock. This is safe, because ++ * JNODE_DKSET is never cleared once set. */ ++ if (!ZF_ISSET(active, JNODE_DKSET)) { ++ tree = znode_get_tree(active); ++ write_lock_dk(tree); ++ if (!ZF_ISSET(active, JNODE_DKSET)) { ++ znode_set_ld_key(active, &h->ld_key); ++ znode_set_rd_key(active, &h->rd_key); ++ ZF_SET(active, JNODE_DKSET); ++ } ++ write_unlock_dk(tree); ++ return 1; ++ } ++ return 0; ++} ++ ++/* true if @block makes sense for the @tree. Used to detect corrupted node ++ * pointers */ ++static int ++block_nr_is_correct(reiser4_block_nr * block /* block number to check */ , ++ reiser4_tree * tree/* tree to check against */) ++{ ++ assert("nikita-757", block != NULL); ++ assert("nikita-758", tree != NULL); ++ ++ /* check to see if it exceeds the size of the device. */ ++ return reiser4_blocknr_is_sane_for(tree->super, block); ++} ++ ++/* check consistency of fields */ ++static int sanity_check(cbk_handle * h/* search handle */) ++{ ++ assert("nikita-384", h != NULL); ++ ++ if (h->level < h->stop_level) { ++ h->error = "Buried under leaves"; ++ h->result = RETERR(-EIO); ++ return LOOKUP_DONE; ++ } else if (!block_nr_is_correct(&h->block, h->tree)) { ++ h->error = "bad block number"; ++ h->result = RETERR(-EIO); ++ return LOOKUP_DONE; ++ } else ++ return 0; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/status_flags.c linux-2.6.30/fs/reiser4/status_flags.c +--- linux-2.6.30.orig/fs/reiser4/status_flags.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/status_flags.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,174 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Functions that deal with reiser4 status block, query status and update it, ++ * if needed */ ++ ++#include <linux/bio.h> ++#include <linux/highmem.h> ++#include <linux/fs.h> ++#include <linux/blkdev.h> ++#include "debug.h" ++#include "dformat.h" ++#include "status_flags.h" ++#include "super.h" ++ ++/* This is our end I/O handler that marks page uptodate if IO was successful. ++ It also unconditionally unlocks the page, so we can see that io was done. ++ We do not free bio, because we hope to reuse that. */ ++static void reiser4_status_endio(struct bio *bio, int err) ++{ ++ if (test_bit(BIO_UPTODATE, &bio->bi_flags)) { ++ SetPageUptodate(bio->bi_io_vec->bv_page); ++ } else { ++ ClearPageUptodate(bio->bi_io_vec->bv_page); ++ SetPageError(bio->bi_io_vec->bv_page); ++ } ++ unlock_page(bio->bi_io_vec->bv_page); ++} ++ ++/* Initialise status code. This is expected to be called from the disk format ++ code. block paremeter is where status block lives. */ ++int reiser4_status_init(reiser4_block_nr block) ++{ ++ struct super_block *sb = reiser4_get_current_sb(); ++ struct reiser4_status *statuspage; ++ struct bio *bio; ++ struct page *page; ++ ++ get_super_private(sb)->status_page = NULL; ++ get_super_private(sb)->status_bio = NULL; ++ ++ page = alloc_pages(reiser4_ctx_gfp_mask_get(), 0); ++ if (!page) ++ return -ENOMEM; ++ ++ bio = bio_alloc(reiser4_ctx_gfp_mask_get(), 1); ++ if (bio != NULL) { ++ bio->bi_sector = block * (sb->s_blocksize >> 9); ++ bio->bi_bdev = sb->s_bdev; ++ bio->bi_io_vec[0].bv_page = page; ++ bio->bi_io_vec[0].bv_len = sb->s_blocksize; ++ bio->bi_io_vec[0].bv_offset = 0; ++ bio->bi_vcnt = 1; ++ bio->bi_size = sb->s_blocksize; ++ bio->bi_end_io = reiser4_status_endio; ++ } else { ++ __free_pages(page, 0); ++ return -ENOMEM; ++ } ++ lock_page(page); ++ submit_bio(READ, bio); ++ blk_run_address_space(reiser4_get_super_fake(sb)->i_mapping); ++ wait_on_page_locked(page); ++ if (!PageUptodate(page)) { ++ warning("green-2007", ++ "I/O error while tried to read status page\n"); ++ return -EIO; ++ } ++ ++ statuspage = (struct reiser4_status *)kmap_atomic(page, KM_USER0); ++ if (memcmp ++ (statuspage->magic, REISER4_STATUS_MAGIC, ++ sizeof(REISER4_STATUS_MAGIC))) { ++ /* Magic does not match. */ ++ kunmap_atomic((char *)statuspage, KM_USER0); ++ warning("green-2008", "Wrong magic in status block\n"); ++ __free_pages(page, 0); ++ bio_put(bio); ++ return -EINVAL; ++ } ++ kunmap_atomic((char *)statuspage, KM_USER0); ++ ++ get_super_private(sb)->status_page = page; ++ get_super_private(sb)->status_bio = bio; ++ return 0; ++} ++ ++/* Query the status of fs. Returns if the FS can be safely mounted. ++ Also if "status" and "extended" parameters are given, it will fill ++ actual parts of status from disk there. */ ++int reiser4_status_query(u64 *status, u64 *extended) ++{ ++ struct super_block *sb = reiser4_get_current_sb(); ++ struct reiser4_status *statuspage; ++ int retval; ++ ++ if (!get_super_private(sb)->status_page) ++ /* No status page? */ ++ return REISER4_STATUS_MOUNT_UNKNOWN; ++ statuspage = (struct reiser4_status *) ++ kmap_atomic(get_super_private(sb)->status_page, KM_USER0); ++ switch ((long)le64_to_cpu(get_unaligned(&statuspage->status))) { ++ /* FIXME: this cast is a hack for 32 bit arches to work. */ ++ case REISER4_STATUS_OK: ++ retval = REISER4_STATUS_MOUNT_OK; ++ break; ++ case REISER4_STATUS_CORRUPTED: ++ retval = REISER4_STATUS_MOUNT_WARN; ++ break; ++ case REISER4_STATUS_DAMAGED: ++ case REISER4_STATUS_DESTROYED: ++ case REISER4_STATUS_IOERROR: ++ retval = REISER4_STATUS_MOUNT_RO; ++ break; ++ default: ++ retval = REISER4_STATUS_MOUNT_UNKNOWN; ++ break; ++ } ++ ++ if (status) ++ *status = le64_to_cpu(get_unaligned(&statuspage->status)); ++ if (extended) ++ *extended = le64_to_cpu(get_unaligned(&statuspage->extended_status)); ++ ++ kunmap_atomic((char *)statuspage, KM_USER0); ++ return retval; ++} ++ ++/* This function should be called when something bad happens (e.g. from ++ reiser4_panic). It fills the status structure and tries to push it to disk.*/ ++int reiser4_status_write(__u64 status, __u64 extended_status, char *message) ++{ ++ struct super_block *sb = reiser4_get_current_sb(); ++ struct reiser4_status *statuspage; ++ struct bio *bio = get_super_private(sb)->status_bio; ++ ++ if (!get_super_private(sb)->status_page) ++ /* No status page? */ ++ return -1; ++ statuspage = (struct reiser4_status *) ++ kmap_atomic(get_super_private(sb)->status_page, KM_USER0); ++ ++ put_unaligned(cpu_to_le64(status), &statuspage->status); ++ put_unaligned(cpu_to_le64(extended_status), &statuspage->extended_status); ++ strncpy(statuspage->texterror, message, REISER4_TEXTERROR_LEN); ++ ++ kunmap_atomic((char *)statuspage, KM_USER0); ++ bio->bi_bdev = sb->s_bdev; ++ bio->bi_io_vec[0].bv_page = get_super_private(sb)->status_page; ++ bio->bi_io_vec[0].bv_len = sb->s_blocksize; ++ bio->bi_io_vec[0].bv_offset = 0; ++ bio->bi_vcnt = 1; ++ bio->bi_size = sb->s_blocksize; ++ bio->bi_end_io = reiser4_status_endio; ++ lock_page(get_super_private(sb)->status_page); /* Safe as nobody should ++ * touch our page. */ ++ /* We can block now, but we have no other choice anyway */ ++ submit_bio(WRITE, bio); ++ blk_run_address_space(reiser4_get_super_fake(sb)->i_mapping); ++ return 0; /* We do not wait for io to finish. */ ++} ++ ++/* Frees the page with status and bio structure. Should be called by disk format ++ * at umount time */ ++int reiser4_status_finish(void) ++{ ++ struct super_block *sb = reiser4_get_current_sb(); ++ ++ __free_pages(get_super_private(sb)->status_page, 0); ++ get_super_private(sb)->status_page = NULL; ++ bio_put(get_super_private(sb)->status_bio); ++ get_super_private(sb)->status_bio = NULL; ++ return 0; ++} +diff -urN linux-2.6.30.orig/fs/reiser4/status_flags.h linux-2.6.30/fs/reiser4/status_flags.h +--- linux-2.6.30.orig/fs/reiser4/status_flags.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/status_flags.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,47 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Here we declare structures and flags that store reiser4 status on disk. ++ The status that helps us to find out if the filesystem is valid or if it ++ contains some critical, or not so critical errors */ ++ ++#if !defined(__REISER4_STATUS_FLAGS_H__) ++#define __REISER4_STATUS_FLAGS_H__ ++ ++#include "dformat.h" ++/* These are major status flags */ ++#define REISER4_STATUS_OK 0 ++#define REISER4_STATUS_CORRUPTED 0x1 ++#define REISER4_STATUS_DAMAGED 0x2 ++#define REISER4_STATUS_DESTROYED 0x4 ++#define REISER4_STATUS_IOERROR 0x8 ++ ++/* Return values for reiser4_status_query() */ ++#define REISER4_STATUS_MOUNT_OK 0 ++#define REISER4_STATUS_MOUNT_WARN 1 ++#define REISER4_STATUS_MOUNT_RO 2 ++#define REISER4_STATUS_MOUNT_UNKNOWN -1 ++ ++#define REISER4_TEXTERROR_LEN 256 ++ ++#define REISER4_STATUS_MAGIC "ReiSeR4StATusBl" ++/* We probably need to keep its size under sector size which is 512 bytes */ ++struct reiser4_status { ++ char magic[16]; ++ d64 status; /* Current FS state */ ++ d64 extended_status; /* Any additional info that might have sense in ++ * addition to "status". E.g. last sector where ++ * io error happened if status is ++ * "io error encountered" */ ++ d64 stacktrace[10]; /* Last ten functional calls made (addresses) */ ++ char texterror[REISER4_TEXTERROR_LEN]; /* Any error message if ++ * appropriate, otherwise filled ++ * with zeroes */ ++}; ++ ++int reiser4_status_init(reiser4_block_nr block); ++int reiser4_status_query(u64 *status, u64 *extended); ++int reiser4_status_write(u64 status, u64 extended_status, char *message); ++int reiser4_status_finish(void); ++ ++#endif +diff -urN linux-2.6.30.orig/fs/reiser4/super.c linux-2.6.30/fs/reiser4/super.c +--- linux-2.6.30.orig/fs/reiser4/super.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/super.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,306 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Super-block manipulations. */ ++ ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "plugin/security/perm.h" ++#include "plugin/space/space_allocator.h" ++#include "plugin/plugin.h" ++#include "tree.h" ++#include "vfs_ops.h" ++#include "super.h" ++#include "reiser4.h" ++ ++#include <linux/types.h> /* for __u?? */ ++#include <linux/fs.h> /* for struct super_block */ ++ ++static __u64 reserved_for_gid(const struct super_block *super, gid_t gid); ++static __u64 reserved_for_uid(const struct super_block *super, uid_t uid); ++static __u64 reserved_for_root(const struct super_block *super); ++ ++/* Return reiser4-specific part of super block */ ++reiser4_super_info_data *get_super_private_nocheck(const struct super_block *super) ++{ ++ return (reiser4_super_info_data *) super->s_fs_info; ++} ++ ++/* Return reiser4 fstype: value that is returned in ->f_type field by statfs() ++ */ ++long reiser4_statfs_type(const struct super_block *super UNUSED_ARG) ++{ ++ assert("nikita-448", super != NULL); ++ assert("nikita-449", is_reiser4_super(super)); ++ return (long)REISER4_SUPER_MAGIC; ++} ++ ++/* functions to read/modify fields of reiser4_super_info_data */ ++ ++/* get number of blocks in file system */ ++__u64 reiser4_block_count(const struct super_block *super /* super block ++ queried */ ) ++{ ++ assert("vs-494", super != NULL); ++ assert("vs-495", is_reiser4_super(super)); ++ return get_super_private(super)->block_count; ++} ++ ++#if REISER4_DEBUG ++/* ++ * number of blocks in the current file system ++ */ ++__u64 reiser4_current_block_count(void) ++{ ++ return get_current_super_private()->block_count; ++} ++#endif /* REISER4_DEBUG */ ++ ++/* set number of block in filesystem */ ++void reiser4_set_block_count(const struct super_block *super, __u64 nr) ++{ ++ assert("vs-501", super != NULL); ++ assert("vs-502", is_reiser4_super(super)); ++ get_super_private(super)->block_count = nr; ++ /* ++ * The proper calculation of the reserved space counter (%5 of device ++ * block counter) we need a 64 bit division which is missing in Linux ++ * on i386 platform. Because we do not need a precise calculation here ++ * we can replace a div64 operation by this combination of ++ * multiplication and shift: 51. / (2^10) == .0498 . ++ * FIXME: this is a bug. It comes up only for very small filesystems ++ * which probably are never used. Nevertheless, it is a bug. Number of ++ * reserved blocks must be not less than maximal number of blocks which ++ * get grabbed with BA_RESERVED. ++ */ ++ get_super_private(super)->blocks_reserved = ((nr * 51) >> 10); ++} ++ ++/* amount of blocks used (allocated for data) in file system */ ++__u64 reiser4_data_blocks(const struct super_block *super /* super block ++ queried */ ) ++{ ++ assert("nikita-452", super != NULL); ++ assert("nikita-453", is_reiser4_super(super)); ++ return get_super_private(super)->blocks_used; ++} ++ ++/* set number of block used in filesystem */ ++void reiser4_set_data_blocks(const struct super_block *super, __u64 nr) ++{ ++ assert("vs-503", super != NULL); ++ assert("vs-504", is_reiser4_super(super)); ++ get_super_private(super)->blocks_used = nr; ++} ++ ++/* amount of free blocks in file system */ ++__u64 reiser4_free_blocks(const struct super_block *super /* super block ++ queried */ ) ++{ ++ assert("nikita-454", super != NULL); ++ assert("nikita-455", is_reiser4_super(super)); ++ return get_super_private(super)->blocks_free; ++} ++ ++/* set number of blocks free in filesystem */ ++void reiser4_set_free_blocks(const struct super_block *super, __u64 nr) ++{ ++ assert("vs-505", super != NULL); ++ assert("vs-506", is_reiser4_super(super)); ++ get_super_private(super)->blocks_free = nr; ++} ++ ++/* get mkfs unique identifier */ ++__u32 reiser4_mkfs_id(const struct super_block *super /* super block ++ queried */ ) ++{ ++ assert("vpf-221", super != NULL); ++ assert("vpf-222", is_reiser4_super(super)); ++ return get_super_private(super)->mkfs_id; ++} ++ ++/* amount of free blocks in file system */ ++__u64 reiser4_free_committed_blocks(const struct super_block *super) ++{ ++ assert("vs-497", super != NULL); ++ assert("vs-498", is_reiser4_super(super)); ++ return get_super_private(super)->blocks_free_committed; ++} ++ ++/* amount of blocks in the file system reserved for @uid and @gid */ ++long reiser4_reserved_blocks(const struct super_block *super /* super block ++ queried */ , ++ uid_t uid /* user id */ , ++ gid_t gid/* group id */) ++{ ++ long reserved; ++ ++ assert("nikita-456", super != NULL); ++ assert("nikita-457", is_reiser4_super(super)); ++ ++ reserved = 0; ++ if (REISER4_SUPPORT_GID_SPACE_RESERVATION) ++ reserved += reserved_for_gid(super, gid); ++ if (REISER4_SUPPORT_UID_SPACE_RESERVATION) ++ reserved += reserved_for_uid(super, uid); ++ if (REISER4_SUPPORT_ROOT_SPACE_RESERVATION && (uid == 0)) ++ reserved += reserved_for_root(super); ++ return reserved; ++} ++ ++/* get/set value of/to grabbed blocks counter */ ++__u64 reiser4_grabbed_blocks(const struct super_block * super) ++{ ++ assert("zam-512", super != NULL); ++ assert("zam-513", is_reiser4_super(super)); ++ ++ return get_super_private(super)->blocks_grabbed; ++} ++ ++__u64 reiser4_flush_reserved(const struct super_block *super) ++{ ++ assert("vpf-285", super != NULL); ++ assert("vpf-286", is_reiser4_super(super)); ++ ++ return get_super_private(super)->blocks_flush_reserved; ++} ++ ++/* get/set value of/to counter of fake allocated formatted blocks */ ++__u64 reiser4_fake_allocated(const struct super_block *super) ++{ ++ assert("zam-516", super != NULL); ++ assert("zam-517", is_reiser4_super(super)); ++ ++ return get_super_private(super)->blocks_fake_allocated; ++} ++ ++/* get/set value of/to counter of fake allocated unformatted blocks */ ++__u64 reiser4_fake_allocated_unformatted(const struct super_block *super) ++{ ++ assert("zam-516", super != NULL); ++ assert("zam-517", is_reiser4_super(super)); ++ ++ return get_super_private(super)->blocks_fake_allocated_unformatted; ++} ++ ++/* get/set value of/to counter of clustered blocks */ ++__u64 reiser4_clustered_blocks(const struct super_block *super) ++{ ++ assert("edward-601", super != NULL); ++ assert("edward-602", is_reiser4_super(super)); ++ ++ return get_super_private(super)->blocks_clustered; ++} ++ ++/* space allocator used by this file system */ ++reiser4_space_allocator * reiser4_get_space_allocator(const struct super_block ++ *super) ++{ ++ assert("nikita-1965", super != NULL); ++ assert("nikita-1966", is_reiser4_super(super)); ++ return &get_super_private(super)->space_allocator; ++} ++ ++/* return fake inode used to bind formatted nodes in the page cache */ ++struct inode *reiser4_get_super_fake(const struct super_block *super) ++{ ++ assert("nikita-1757", super != NULL); ++ return get_super_private(super)->fake; ++} ++ ++/* return fake inode used to bind copied on capture nodes in the page cache */ ++struct inode *reiser4_get_cc_fake(const struct super_block *super) ++{ ++ assert("nikita-1757", super != NULL); ++ return get_super_private(super)->cc; ++} ++ ++/* return fake inode used to bind bitmaps and journlal heads */ ++struct inode *reiser4_get_bitmap_fake(const struct super_block *super) ++{ ++ assert("nikita-17571", super != NULL); ++ return get_super_private(super)->bitmap; ++} ++ ++/* tree used by this file system */ ++reiser4_tree *reiser4_get_tree(const struct super_block *super) ++{ ++ assert("nikita-460", super != NULL); ++ assert("nikita-461", is_reiser4_super(super)); ++ return &get_super_private(super)->tree; ++} ++ ++/* Check that @super is (looks like) reiser4 super block. This is mainly for ++ use in assertions. */ ++int is_reiser4_super(const struct super_block *super) ++{ ++ return ++ super != NULL && ++ get_super_private(super) != NULL && ++ super->s_op == &(get_super_private(super)->ops.super); ++} ++ ++int reiser4_is_set(const struct super_block *super, reiser4_fs_flag f) ++{ ++ return test_bit((int)f, &get_super_private(super)->fs_flags); ++} ++ ++/* amount of blocks reserved for given group in file system */ ++static __u64 reserved_for_gid(const struct super_block *super UNUSED_ARG, ++ gid_t gid UNUSED_ARG/* group id */) ++{ ++ return 0; ++} ++ ++/* amount of blocks reserved for given user in file system */ ++static __u64 reserved_for_uid(const struct super_block *super UNUSED_ARG, ++ uid_t uid UNUSED_ARG/* user id */) ++{ ++ return 0; ++} ++ ++/* amount of blocks reserved for super user in file system */ ++static __u64 reserved_for_root(const struct super_block *super UNUSED_ARG) ++{ ++ return 0; ++} ++ ++/* ++ * true if block number @blk makes sense for the file system at @super. ++ */ ++int ++reiser4_blocknr_is_sane_for(const struct super_block *super, ++ const reiser4_block_nr * blk) ++{ ++ reiser4_super_info_data *sbinfo; ++ ++ assert("nikita-2957", super != NULL); ++ assert("nikita-2958", blk != NULL); ++ ++ if (reiser4_blocknr_is_fake(blk)) ++ return 1; ++ ++ sbinfo = get_super_private(super); ++ return *blk < sbinfo->block_count; ++} ++ ++#if REISER4_DEBUG ++/* ++ * true, if block number @blk makes sense for the current file system ++ */ ++int reiser4_blocknr_is_sane(const reiser4_block_nr * blk) ++{ ++ return reiser4_blocknr_is_sane_for(reiser4_get_current_sb(), blk); ++} ++#endif /* REISER4_DEBUG */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/super.h linux-2.6.30/fs/reiser4/super.h +--- linux-2.6.30.orig/fs/reiser4/super.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/super.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,466 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Super-block functions. See super.c for details. */ ++ ++#if !defined(__REISER4_SUPER_H__) ++#define __REISER4_SUPER_H__ ++ ++#include <linux/exportfs.h> ++ ++#include "tree.h" ++#include "entd.h" ++#include "wander.h" ++#include "fsdata.h" ++#include "plugin/object.h" ++#include "plugin/space/space_allocator.h" ++ ++/* ++ * Flush algorithms parameters. ++ */ ++struct flush_params { ++ unsigned relocate_threshold; ++ unsigned relocate_distance; ++ unsigned written_threshold; ++ unsigned scan_maxnodes; ++}; ++ ++typedef enum { ++ /* ++ * True if this file system doesn't support hard-links (multiple names) ++ * for directories: this is default UNIX behavior. ++ * ++ * If hard-links on directoires are not allowed, file system is Acyclic ++ * Directed Graph (modulo dot, and dotdot, of course). ++ * ++ * This is used by reiser4_link(). ++ */ ++ REISER4_ADG = 0, ++ /* ++ * set if all nodes in internal tree have the same node layout plugin. ++ * If so, znode_guess_plugin() will return tree->node_plugin in stead ++ * of guessing plugin by plugin id stored in the node. ++ */ ++ REISER4_ONE_NODE_PLUGIN = 1, ++ /* if set, bsd gid assignment is supported. */ ++ REISER4_BSD_GID = 2, ++ /* [mac]_time are 32 bit in inode */ ++ REISER4_32_BIT_TIMES = 3, ++ /* load all bitmap blocks at mount time */ ++ REISER4_DONT_LOAD_BITMAP = 5, ++ /* enforce atomicity during write(2) */ ++ REISER4_ATOMIC_WRITE = 6, ++ /* don't use write barriers in the log writer code. */ ++ REISER4_NO_WRITE_BARRIER = 7 ++} reiser4_fs_flag; ++ ++/* ++ * VFS related operation vectors. ++ */ ++struct object_ops { ++ struct super_operations super; ++ struct dentry_operations dentry; ++ struct export_operations export; ++}; ++ ++/* reiser4-specific part of super block ++ ++ Locking ++ ++ Fields immutable after mount: ++ ++ ->oid* ++ ->space* ++ ->default_[ug]id ++ ->mkfs_id ++ ->trace_flags ++ ->debug_flags ++ ->fs_flags ++ ->df_plug ++ ->optimal_io_size ++ ->plug ++ ->flush ++ ->u (bad name) ++ ->txnmgr ++ ->ra_params ++ ->fsuid ++ ->journal_header ++ ->journal_footer ++ ++ Fields protected by ->lnode_guard ++ ++ ->lnode_htable ++ ++ Fields protected by per-super block spin lock ++ ++ ->block_count ++ ->blocks_used ++ ->blocks_free ++ ->blocks_free_committed ++ ->blocks_grabbed ++ ->blocks_fake_allocated_unformatted ++ ->blocks_fake_allocated ++ ->blocks_flush_reserved ++ ->eflushed ++ ->blocknr_hint_default ++ ++ After journal replaying during mount, ++ ++ ->last_committed_tx ++ ++ is protected by ->tmgr.commit_mutex ++ ++ Invariants involving this data-type: ++ ++ [sb-block-counts] ++ [sb-grabbed] ++ [sb-fake-allocated] ++*/ ++struct reiser4_super_info_data { ++ /* ++ * guard spinlock which protects reiser4 super block fields (currently ++ * blocks_free, blocks_free_committed) ++ */ ++ spinlock_t guard; ++ ++ /* next oid that will be returned by oid_allocate() */ ++ oid_t next_to_use; ++ /* total number of used oids */ ++ oid_t oids_in_use; ++ ++ /* space manager plugin */ ++ reiser4_space_allocator space_allocator; ++ ++ /* reiser4 internal tree */ ++ reiser4_tree tree; ++ ++ /* ++ * default user id used for light-weight files without their own ++ * stat-data. ++ */ ++ uid_t default_uid; ++ ++ /* ++ * default group id used for light-weight files without their own ++ * stat-data. ++ */ ++ gid_t default_gid; ++ ++ /* mkfs identifier generated at mkfs time. */ ++ __u32 mkfs_id; ++ /* amount of blocks in a file system */ ++ __u64 block_count; ++ ++ /* inviolable reserve */ ++ __u64 blocks_reserved; ++ ++ /* amount of blocks used by file system data and meta-data. */ ++ __u64 blocks_used; ++ ++ /* ++ * amount of free blocks. This is "working" free blocks counter. It is ++ * like "working" bitmap, please see block_alloc.c for description. ++ */ ++ __u64 blocks_free; ++ ++ /* ++ * free block count for fs committed state. This is "commit" version of ++ * free block counter. ++ */ ++ __u64 blocks_free_committed; ++ ++ /* ++ * number of blocks reserved for further allocation, for all ++ * threads. ++ */ ++ __u64 blocks_grabbed; ++ ++ /* number of fake allocated unformatted blocks in tree. */ ++ __u64 blocks_fake_allocated_unformatted; ++ ++ /* number of fake allocated formatted blocks in tree. */ ++ __u64 blocks_fake_allocated; ++ ++ /* number of blocks reserved for flush operations. */ ++ __u64 blocks_flush_reserved; ++ ++ /* number of blocks reserved for cluster operations. */ ++ __u64 blocks_clustered; ++ ++ /* unique file-system identifier */ ++ __u32 fsuid; ++ ++ /* On-disk format version. If does not equal to the disk_format ++ plugin version, some format updates (e.g. enlarging plugin ++ set, etc) may have place on mount. */ ++ int version; ++ ++ /* file-system wide flags. See reiser4_fs_flag enum */ ++ unsigned long fs_flags; ++ ++ /* transaction manager */ ++ txn_mgr tmgr; ++ ++ /* ent thread */ ++ entd_context entd; ++ ++ /* fake inode used to bind formatted nodes */ ++ struct inode *fake; ++ /* inode used to bind bitmaps (and journal heads) */ ++ struct inode *bitmap; ++ /* inode used to bind copied on capture nodes */ ++ struct inode *cc; ++ ++ /* disk layout plugin */ ++ disk_format_plugin *df_plug; ++ ++ /* disk layout specific part of reiser4 super info data */ ++ union { ++ format40_super_info format40; ++ } u; ++ ++ /* value we return in st_blksize on stat(2) */ ++ unsigned long optimal_io_size; ++ ++ /* parameters for the flush algorithm */ ++ struct flush_params flush; ++ ++ /* pointers to jnodes for journal header and footer */ ++ jnode *journal_header; ++ jnode *journal_footer; ++ ++ journal_location jloc; ++ ++ /* head block number of last committed transaction */ ++ __u64 last_committed_tx; ++ ++ /* ++ * we remember last written location for using as a hint for new block ++ * allocation ++ */ ++ __u64 blocknr_hint_default; ++ ++ /* committed number of files (oid allocator state variable ) */ ++ __u64 nr_files_committed; ++ ++ struct formatted_ra_params ra_params; ++ ++ /* ++ * A mutex for serializing cut tree operation if out-of-free-space: ++ * the only one cut_tree thread is allowed to grab space from reserved ++ * area (it is 5% of disk space) ++ */ ++ struct mutex delete_mutex; ++ /* task owning ->delete_mutex */ ++ struct task_struct *delete_mutex_owner; ++ ++ /* Diskmap's blocknumber */ ++ __u64 diskmap_block; ++ ++ /* What to do in case of error */ ++ int onerror; ++ ++ /* operations for objects on this file system */ ++ struct object_ops ops; ++ ++ /* ++ * structure to maintain d_cursors. See plugin/file_ops_readdir.c for ++ * more details ++ */ ++ struct d_cursor_info d_info; ++ ++#ifdef CONFIG_REISER4_BADBLOCKS ++ /* Alternative master superblock offset (in bytes) */ ++ unsigned long altsuper; ++#endif ++ struct repacker *repacker; ++ struct page *status_page; ++ struct bio *status_bio; ++ ++#if REISER4_DEBUG ++ /* ++ * minimum used blocks value (includes super blocks, bitmap blocks and ++ * other fs reserved areas), depends on fs format and fs size. ++ */ ++ __u64 min_blocks_used; ++ ++ /* ++ * when debugging is on, all jnodes (including znodes, bitmaps, etc.) ++ * are kept on a list anchored at sbinfo->all_jnodes. This list is ++ * protected by sbinfo->all_guard spin lock. This lock should be taken ++ * with _irq modifier, because it is also modified from interrupt ++ * contexts (by RCU). ++ */ ++ spinlock_t all_guard; ++ /* list of all jnodes */ ++ struct list_head all_jnodes; ++#endif ++ struct dentry *debugfs_root; ++}; ++ ++extern reiser4_super_info_data *get_super_private_nocheck(const struct ++ super_block * super); ++ ++/* Return reiser4-specific part of super block */ ++static inline reiser4_super_info_data *get_super_private(const struct ++ super_block * super) ++{ ++ assert("nikita-447", super != NULL); ++ ++ return (reiser4_super_info_data *) super->s_fs_info; ++} ++ ++/* get ent context for the @super */ ++static inline entd_context *get_entd_context(struct super_block *super) ++{ ++ return &get_super_private(super)->entd; ++} ++ ++/* "Current" super-block: main super block used during current system ++ call. Reference to this super block is stored in reiser4_context. */ ++static inline struct super_block *reiser4_get_current_sb(void) ++{ ++ return get_current_context()->super; ++} ++ ++/* Reiser4-specific part of "current" super-block: main super block used ++ during current system call. Reference to this super block is stored in ++ reiser4_context. */ ++static inline reiser4_super_info_data *get_current_super_private(void) ++{ ++ return get_super_private(reiser4_get_current_sb()); ++} ++ ++static inline struct formatted_ra_params *get_current_super_ra_params(void) ++{ ++ return &(get_current_super_private()->ra_params); ++} ++ ++/* ++ * true, if file system on @super is read-only ++ */ ++static inline int rofs_super(struct super_block *super) ++{ ++ return super->s_flags & MS_RDONLY; ++} ++ ++/* ++ * true, if @tree represents read-only file system ++ */ ++static inline int rofs_tree(reiser4_tree * tree) ++{ ++ return rofs_super(tree->super); ++} ++ ++/* ++ * true, if file system where @inode lives on, is read-only ++ */ ++static inline int rofs_inode(struct inode *inode) ++{ ++ return rofs_super(inode->i_sb); ++} ++ ++/* ++ * true, if file system where @node lives on, is read-only ++ */ ++static inline int rofs_jnode(jnode * node) ++{ ++ return rofs_tree(jnode_get_tree(node)); ++} ++ ++extern __u64 reiser4_current_block_count(void); ++ ++extern void build_object_ops(struct super_block *super, struct object_ops *ops); ++ ++#define REISER4_SUPER_MAGIC 0x52345362 /* (*(__u32 *)"R4Sb"); */ ++ ++static inline void spin_lock_reiser4_super(reiser4_super_info_data *sbinfo) ++{ ++ spin_lock(&(sbinfo->guard)); ++} ++ ++static inline void spin_unlock_reiser4_super(reiser4_super_info_data *sbinfo) ++{ ++ assert_spin_locked(&(sbinfo->guard)); ++ spin_unlock(&(sbinfo->guard)); ++} ++ ++extern __u64 reiser4_flush_reserved(const struct super_block *); ++extern int reiser4_is_set(const struct super_block *super, reiser4_fs_flag f); ++extern long reiser4_statfs_type(const struct super_block *super); ++extern __u64 reiser4_block_count(const struct super_block *super); ++extern void reiser4_set_block_count(const struct super_block *super, __u64 nr); ++extern __u64 reiser4_data_blocks(const struct super_block *super); ++extern void reiser4_set_data_blocks(const struct super_block *super, __u64 nr); ++extern __u64 reiser4_free_blocks(const struct super_block *super); ++extern void reiser4_set_free_blocks(const struct super_block *super, __u64 nr); ++extern __u32 reiser4_mkfs_id(const struct super_block *super); ++ ++extern __u64 reiser4_free_committed_blocks(const struct super_block *super); ++ ++extern __u64 reiser4_grabbed_blocks(const struct super_block *); ++extern __u64 reiser4_fake_allocated(const struct super_block *); ++extern __u64 reiser4_fake_allocated_unformatted(const struct super_block *); ++extern __u64 reiser4_clustered_blocks(const struct super_block *); ++ ++extern long reiser4_reserved_blocks(const struct super_block *super, uid_t uid, ++ gid_t gid); ++ ++extern reiser4_space_allocator * ++reiser4_get_space_allocator(const struct super_block *super); ++extern reiser4_oid_allocator * ++reiser4_get_oid_allocator(const struct super_block *super); ++extern struct inode *reiser4_get_super_fake(const struct super_block *super); ++extern struct inode *reiser4_get_cc_fake(const struct super_block *super); ++extern struct inode *reiser4_get_bitmap_fake(const struct super_block *super); ++extern reiser4_tree *reiser4_get_tree(const struct super_block *super); ++extern int is_reiser4_super(const struct super_block *super); ++ ++extern int reiser4_blocknr_is_sane(const reiser4_block_nr * blk); ++extern int reiser4_blocknr_is_sane_for(const struct super_block *super, ++ const reiser4_block_nr * blk); ++extern int reiser4_fill_super(struct super_block *s, void *data, int silent); ++extern int reiser4_done_super(struct super_block *s); ++ ++/* step of fill super */ ++extern int reiser4_init_fs_info(struct super_block *); ++extern void reiser4_done_fs_info(struct super_block *); ++extern int reiser4_init_super_data(struct super_block *, char *opt_string); ++extern int reiser4_init_read_super(struct super_block *, int silent); ++extern int reiser4_init_root_inode(struct super_block *); ++extern reiser4_plugin *get_default_plugin(pset_member memb); ++ ++/* Maximal possible object id. */ ++#define ABSOLUTE_MAX_OID ((oid_t)~0) ++ ++#define OIDS_RESERVED (1 << 16) ++int oid_init_allocator(struct super_block *, oid_t nr_files, oid_t next); ++oid_t oid_allocate(struct super_block *); ++int oid_release(struct super_block *, oid_t); ++oid_t oid_next(const struct super_block *); ++void oid_count_allocated(void); ++void oid_count_released(void); ++long oids_used(const struct super_block *); ++ ++#if REISER4_DEBUG ++void print_fs_info(const char *prefix, const struct super_block *); ++#endif ++ ++extern void destroy_reiser4_cache(struct kmem_cache **); ++ ++extern struct super_operations reiser4_super_operations; ++extern struct export_operations reiser4_export_operations; ++extern struct dentry_operations reiser4_dentry_operations; ++ ++/* __REISER4_SUPER_H__ */ ++#endif ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 120 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/super_ops.c linux-2.6.30/fs/reiser4/super_ops.c +--- linux-2.6.30.orig/fs/reiser4/super_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/super_ops.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,725 @@ ++/* Copyright 2005 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++#include "inode.h" ++#include "page_cache.h" ++#include "ktxnmgrd.h" ++#include "flush.h" ++#include "safe_link.h" ++ ++#include <linux/vfs.h> ++#include <linux/writeback.h> ++#include <linux/mount.h> ++#include <linux/seq_file.h> ++#include <linux/debugfs.h> ++ ++/* slab cache for inodes */ ++static struct kmem_cache *inode_cache; ++ ++static struct dentry *reiser4_debugfs_root = NULL; ++ ++/** ++ * init_once - constructor for reiser4 inodes ++ * @cache: cache @obj belongs to ++ * @obj: inode to be initialized ++ * ++ * Initialization function to be called when new page is allocated by reiser4 ++ * inode cache. It is set on inode cache creation. ++ */ ++static void init_once(void *obj) ++{ ++ struct reiser4_inode_object *info; ++ ++ info = obj; ++ ++ /* initialize vfs inode */ ++ inode_init_once(&info->vfs_inode); ++ ++ /* ++ * initialize reiser4 specific part fo inode. ++ * NOTE-NIKITA add here initializations for locks, list heads, ++ * etc. that will be added to our private inode part. ++ */ ++ INIT_LIST_HEAD(get_readdir_list(&info->vfs_inode)); ++ init_rwsem(&info->p.conv_sem); ++ /* init semaphore which is used during inode loading */ ++ loading_init_once(&info->p); ++ INIT_RADIX_TREE(jnode_tree_by_reiser4_inode(&info->p), ++ GFP_ATOMIC); ++#if REISER4_DEBUG ++ info->p.nr_jnodes = 0; ++#endif ++} ++ ++/** ++ * init_inodes - create znode cache ++ * ++ * Initializes slab cache of inodes. It is part of reiser4 module initialization ++ */ ++static int init_inodes(void) ++{ ++ inode_cache = kmem_cache_create("reiser4_inode", ++ sizeof(struct reiser4_inode_object), ++ 0, ++ SLAB_HWCACHE_ALIGN | ++ SLAB_RECLAIM_ACCOUNT, init_once); ++ if (inode_cache == NULL) ++ return RETERR(-ENOMEM); ++ return 0; ++} ++ ++/** ++ * done_inodes - delete inode cache ++ * ++ * This is called on reiser4 module unloading or system shutdown. ++ */ ++static void done_inodes(void) ++{ ++ destroy_reiser4_cache(&inode_cache); ++} ++ ++/** ++ * reiser4_alloc_inode - alloc_inode of super operations ++ * @super: super block new inode is allocated for ++ * ++ * Allocates new inode, initializes reiser4 specific part of it. ++ */ ++static struct inode *reiser4_alloc_inode(struct super_block *super) ++{ ++ struct reiser4_inode_object *obj; ++ ++ assert("nikita-1696", super != NULL); ++ obj = kmem_cache_alloc(inode_cache, reiser4_ctx_gfp_mask_get()); ++ if (obj != NULL) { ++ reiser4_inode *info; ++ ++ info = &obj->p; ++ ++ info->pset = plugin_set_get_empty(); ++ info->hset = plugin_set_get_empty(); ++ info->extmask = 0; ++ info->locality_id = 0ull; ++ info->plugin_mask = 0; ++ info->heir_mask = 0; ++#if !REISER4_INO_IS_OID ++ info->oid_hi = 0; ++#endif ++ reiser4_seal_init(&info->sd_seal, NULL, NULL); ++ coord_init_invalid(&info->sd_coord, NULL); ++ info->flags = 0; ++ spin_lock_init(&info->guard); ++ /* this deals with info's loading semaphore */ ++ loading_alloc(info); ++ info->vroot = UBER_TREE_ADDR; ++ return &obj->vfs_inode; ++ } else ++ return NULL; ++} ++ ++/** ++ * reiser4_destroy_inode - destroy_inode of super operations ++ * @inode: inode being destroyed ++ * ++ * Puts reiser4 specific portion of inode, frees memory occupied by inode. ++ */ ++static void reiser4_destroy_inode(struct inode *inode) ++{ ++ reiser4_inode *info; ++ ++ info = reiser4_inode_data(inode); ++ ++ assert("vs-1220", inode_has_no_jnodes(info)); ++ ++ if (!is_bad_inode(inode) && is_inode_loaded(inode)) { ++ file_plugin *fplug = inode_file_plugin(inode); ++ if (fplug->destroy_inode != NULL) ++ fplug->destroy_inode(inode); ++ } ++ reiser4_dispose_cursors(inode); ++ if (info->pset) ++ plugin_set_put(info->pset); ++ if (info->hset) ++ plugin_set_put(info->hset); ++ ++ /* ++ * cannot add similar assertion about ->i_list as prune_icache return ++ * inode into slab with dangling ->list.{next,prev}. This is safe, ++ * because they are re-initialized in the new_inode(). ++ */ ++ assert("nikita-2895", list_empty(&inode->i_dentry)); ++ assert("nikita-2896", hlist_unhashed(&inode->i_hash)); ++ assert("nikita-2898", list_empty_careful(get_readdir_list(inode))); ++ ++ /* this deals with info's loading semaphore */ ++ loading_destroy(info); ++ ++ kmem_cache_free(inode_cache, ++ container_of(info, struct reiser4_inode_object, p)); ++} ++ ++/** ++ * reiser4_dirty_inode - dirty_inode of super operations ++ * @inode: inode being dirtied ++ * ++ * Updates stat data. ++ */ ++static void reiser4_dirty_inode(struct inode *inode) ++{ ++ int result; ++ ++ if (!is_in_reiser4_context()) ++ return; ++ assert("", !IS_RDONLY(inode)); ++ assert("", (inode_file_plugin(inode)->estimate.update(inode) <= ++ get_current_context()->grabbed_blocks)); ++ ++ result = reiser4_update_sd(inode); ++ if (result) ++ warning("", "failed to dirty inode for %llu: %d", ++ get_inode_oid(inode), result); ++} ++ ++/** ++ * reiser4_delete_inode - delete_inode of super operations ++ * @inode: inode to delete ++ * ++ * Calls file plugin's delete_object method to delete object items from ++ * filesystem tree and calls clear_inode. ++ */ ++static void reiser4_delete_inode(struct inode *inode) ++{ ++ reiser4_context *ctx; ++ file_plugin *fplug; ++ ++ ctx = reiser4_init_context(inode->i_sb); ++ if (IS_ERR(ctx)) { ++ warning("vs-15", "failed to init context"); ++ return; ++ } ++ ++ if (is_inode_loaded(inode)) { ++ fplug = inode_file_plugin(inode); ++ if (fplug != NULL && fplug->delete_object != NULL) ++ fplug->delete_object(inode); ++ } ++ ++ truncate_inode_pages(&inode->i_data, 0); ++ inode->i_blocks = 0; ++ clear_inode(inode); ++ reiser4_exit_context(ctx); ++} ++ ++/** ++ * reiser4_put_super - put_super of super operations ++ * @super: super block to free ++ * ++ * Stops daemons, release resources, umounts in short. ++ */ ++static void reiser4_put_super(struct super_block *super) ++{ ++ reiser4_super_info_data *sbinfo; ++ reiser4_context *ctx; ++ ++ sbinfo = get_super_private(super); ++ assert("vs-1699", sbinfo); ++ ++ debugfs_remove(sbinfo->tmgr.debugfs_atom_count); ++ debugfs_remove(sbinfo->tmgr.debugfs_id_count); ++ debugfs_remove(sbinfo->debugfs_root); ++ ++ ctx = reiser4_init_context(super); ++ if (IS_ERR(ctx)) { ++ warning("vs-17", "failed to init context"); ++ return; ++ } ++ ++ /* have disk format plugin to free its resources */ ++ if (get_super_private(super)->df_plug->release) ++ get_super_private(super)->df_plug->release(super); ++ ++ reiser4_done_formatted_fake(super); ++ ++ /* stop daemons: ktxnmgr and entd */ ++ reiser4_done_entd(super); ++ reiser4_done_ktxnmgrd(super); ++ reiser4_done_txnmgr(&sbinfo->tmgr); ++ ++ reiser4_done_fs_info(super); ++ reiser4_exit_context(ctx); ++} ++ ++/** ++ * reiser4_write_super - write_super of super operations ++ * @super: super block to write ++ * ++ * Captures znode associated with super block, comit all transactions. ++ */ ++static void reiser4_write_super(struct super_block *super) ++{ ++ int ret; ++ reiser4_context *ctx; ++ ++ assert("vs-1700", !rofs_super(super)); ++ ++ ctx = reiser4_init_context(super); ++ if (IS_ERR(ctx)) { ++ warning("vs-16", "failed to init context"); ++ return; ++ } ++ ++ ret = reiser4_capture_super_block(super); ++ if (ret != 0) ++ warning("vs-1701", ++ "reiser4_capture_super_block failed in write_super: %d", ++ ret); ++ ret = txnmgr_force_commit_all(super, 0); ++ if (ret != 0) ++ warning("jmacd-77113", ++ "txn_force failed in write_super: %d", ret); ++ ++ super->s_dirt = 0; ++ ++ reiser4_exit_context(ctx); ++} ++ ++/** ++ * reiser4_statfs - statfs of super operations ++ * @super: super block of file system in queried ++ * @stafs: buffer to fill with statistics ++ * ++ * Returns information about filesystem. ++ */ ++static int reiser4_statfs(struct dentry *dentry, struct kstatfs *statfs) ++{ ++ sector_t total; ++ sector_t reserved; ++ sector_t free; ++ sector_t forroot; ++ sector_t deleted; ++ reiser4_context *ctx; ++ struct super_block *super = dentry->d_sb; ++ ++ assert("nikita-408", super != NULL); ++ assert("nikita-409", statfs != NULL); ++ ++ ctx = reiser4_init_context(super); ++ if (IS_ERR(ctx)) ++ return PTR_ERR(ctx); ++ ++ statfs->f_type = reiser4_statfs_type(super); ++ statfs->f_bsize = super->s_blocksize; ++ ++ /* ++ * 5% of total block space is reserved. This is needed for flush and ++ * for truncates (so that we are able to perform truncate/unlink even ++ * on the otherwise completely full file system). If this reservation ++ * is hidden from statfs(2), users will mistakenly guess that they ++ * have enough free space to complete some operation, which is ++ * frustrating. ++ * ++ * Another possible solution is to subtract ->blocks_reserved from ++ * ->f_bfree, but changing available space seems less intrusive than ++ * letting user to see 5% of disk space to be used directly after ++ * mkfs. ++ */ ++ total = reiser4_block_count(super); ++ reserved = get_super_private(super)->blocks_reserved; ++ deleted = txnmgr_count_deleted_blocks(); ++ free = reiser4_free_blocks(super) + deleted; ++ forroot = reiser4_reserved_blocks(super, 0, 0); ++ ++ /* ++ * These counters may be in inconsistent state because we take the ++ * values without keeping any global spinlock. Here we do a sanity ++ * check that free block counter does not exceed the number of all ++ * blocks. ++ */ ++ if (free > total) ++ free = total; ++ statfs->f_blocks = total - reserved; ++ /* make sure statfs->f_bfree is never larger than statfs->f_blocks */ ++ if (free > reserved) ++ free -= reserved; ++ else ++ free = 0; ++ statfs->f_bfree = free; ++ ++ if (free > forroot) ++ free -= forroot; ++ else ++ free = 0; ++ statfs->f_bavail = free; ++ ++ statfs->f_files = 0; ++ statfs->f_ffree = 0; ++ ++ /* maximal acceptable name length depends on directory plugin. */ ++ assert("nikita-3351", super->s_root->d_inode != NULL); ++ statfs->f_namelen = reiser4_max_filename_len(super->s_root->d_inode); ++ reiser4_exit_context(ctx); ++ return 0; ++} ++ ++/** ++ * reiser4_clear_inode - clear_inode of super operation ++ * @inode: inode about to destroy ++ * ++ * Does sanity checks: being destroyed should have all jnodes detached. ++ */ ++static void reiser4_clear_inode(struct inode *inode) ++{ ++#if REISER4_DEBUG ++ reiser4_inode *r4_inode; ++ ++ r4_inode = reiser4_inode_data(inode); ++ if (!inode_has_no_jnodes(r4_inode)) ++ warning("vs-1732", "reiser4 inode has %ld jnodes\n", ++ r4_inode->nr_jnodes); ++#endif ++} ++ ++/** ++ * reiser4_sync_inodes - sync_inodes of super operations ++ * @super: ++ * @wbc: ++ * ++ * This method is called by background and non-backgound writeback. Reiser4's ++ * implementation uses generic_sync_sb_inodes to call reiser4_writepages for ++ * each of dirty inodes. Reiser4_writepages handles pages dirtied via shared ++ * mapping - dirty pages get into atoms. Writeout is called to flush some ++ * atoms. ++ */ ++static void reiser4_sync_inodes(struct super_block *super, ++ struct writeback_control *wbc) ++{ ++ reiser4_context *ctx; ++ long to_write; ++ ++ if (wbc->for_kupdate) ++ /* reiser4 has its own means of periodical write-out */ ++ return; ++ ++ to_write = wbc->nr_to_write; ++ assert("vs-49", wbc->older_than_this == NULL); ++ ++ ctx = reiser4_init_context(super); ++ if (IS_ERR(ctx)) { ++ warning("vs-13", "failed to init context"); ++ return; ++ } ++ ++ /* ++ * call reiser4_writepages for each of dirty inodes to turn dirty pages ++ * into transactions if they were not yet. ++ */ ++ generic_sync_sb_inodes(super, wbc); ++ ++ /* flush goes here */ ++ wbc->nr_to_write = to_write; ++ reiser4_writeout(super, wbc); ++ ++ /* avoid recursive calls to ->sync_inodes */ ++ context_set_commit_async(ctx); ++ reiser4_exit_context(ctx); ++} ++ ++/** ++ * reiser4_show_options - show_options of super operations ++ * @m: file where to write information ++ * @mnt: mount structure ++ * ++ * Makes reiser4 mount options visible in /proc/mounts. ++ */ ++static int reiser4_show_options(struct seq_file *m, struct vfsmount *mnt) ++{ ++ struct super_block *super; ++ reiser4_super_info_data *sbinfo; ++ ++ super = mnt->mnt_sb; ++ sbinfo = get_super_private(super); ++ ++ seq_printf(m, ",atom_max_size=0x%x", sbinfo->tmgr.atom_max_size); ++ seq_printf(m, ",atom_max_age=0x%x", sbinfo->tmgr.atom_max_age); ++ seq_printf(m, ",atom_min_size=0x%x", sbinfo->tmgr.atom_min_size); ++ seq_printf(m, ",atom_max_flushers=0x%x", ++ sbinfo->tmgr.atom_max_flushers); ++ seq_printf(m, ",cbk_cache_slots=0x%x", ++ sbinfo->tree.cbk_cache.nr_slots); ++ ++ return 0; ++} ++ ++struct super_operations reiser4_super_operations = { ++ .alloc_inode = reiser4_alloc_inode, ++ .destroy_inode = reiser4_destroy_inode, ++ .dirty_inode = reiser4_dirty_inode, ++ .delete_inode = reiser4_delete_inode, ++ .put_super = reiser4_put_super, ++ .write_super = reiser4_write_super, ++ .statfs = reiser4_statfs, ++ .clear_inode = reiser4_clear_inode, ++ .sync_inodes = reiser4_sync_inodes, ++ .show_options = reiser4_show_options ++}; ++ ++/** ++ * fill_super - initialize super block on mount ++ * @super: super block to fill ++ * @data: reiser4 specific mount option ++ * @silent: ++ * ++ * This is to be called by reiser4_get_sb. Mounts filesystem. ++ */ ++static int fill_super(struct super_block *super, void *data, int silent) ++{ ++ reiser4_context ctx; ++ int result; ++ reiser4_super_info_data *sbinfo; ++ ++ assert("zam-989", super != NULL); ++ ++ super->s_op = NULL; ++ init_stack_context(&ctx, super); ++ ++ /* allocate reiser4 specific super block */ ++ if ((result = reiser4_init_fs_info(super)) != 0) ++ goto failed_init_sinfo; ++ ++ sbinfo = get_super_private(super); ++ /* initialize various reiser4 parameters, parse mount options */ ++ if ((result = reiser4_init_super_data(super, data)) != 0) ++ goto failed_init_super_data; ++ ++ /* read reiser4 master super block, initialize disk format plugin */ ++ if ((result = reiser4_init_read_super(super, silent)) != 0) ++ goto failed_init_read_super; ++ ++ /* initialize transaction manager */ ++ reiser4_init_txnmgr(&sbinfo->tmgr); ++ ++ /* initialize ktxnmgrd context and start kernel thread ktxnmrgd */ ++ if ((result = reiser4_init_ktxnmgrd(super)) != 0) ++ goto failed_init_ktxnmgrd; ++ ++ /* initialize entd context and start kernel thread entd */ ++ if ((result = reiser4_init_entd(super)) != 0) ++ goto failed_init_entd; ++ ++ /* initialize address spaces for formatted nodes and bitmaps */ ++ if ((result = reiser4_init_formatted_fake(super)) != 0) ++ goto failed_init_formatted_fake; ++ ++ /* initialize disk format plugin */ ++ if ((result = get_super_private(super)->df_plug->init_format(super, ++ data)) != 0) ++ goto failed_init_disk_format; ++ ++ /* ++ * There are some 'committed' versions of reiser4 super block counters, ++ * which correspond to reiser4 on-disk state. These counters are ++ * initialized here ++ */ ++ sbinfo->blocks_free_committed = sbinfo->blocks_free; ++ sbinfo->nr_files_committed = oids_used(super); ++ ++ /* get inode of root directory */ ++ if ((result = reiser4_init_root_inode(super)) != 0) ++ goto failed_init_root_inode; ++ ++ if ((result = get_super_private(super)->df_plug->version_update(super)) != 0) ++ goto failed_update_format_version; ++ ++ process_safelinks(super); ++ reiser4_exit_context(&ctx); ++ ++ sbinfo->debugfs_root = debugfs_create_dir(super->s_id, ++ reiser4_debugfs_root); ++ if (sbinfo->debugfs_root) { ++ sbinfo->tmgr.debugfs_atom_count = ++ debugfs_create_u32("atom_count", S_IFREG|S_IRUSR, ++ sbinfo->debugfs_root, ++ &sbinfo->tmgr.atom_count); ++ sbinfo->tmgr.debugfs_id_count = ++ debugfs_create_u32("id_count", S_IFREG|S_IRUSR, ++ sbinfo->debugfs_root, ++ &sbinfo->tmgr.id_count); ++ } ++ return 0; ++ ++ failed_update_format_version: ++ failed_init_root_inode: ++ if (sbinfo->df_plug->release) ++ sbinfo->df_plug->release(super); ++ failed_init_disk_format: ++ reiser4_done_formatted_fake(super); ++ failed_init_formatted_fake: ++ reiser4_done_entd(super); ++ failed_init_entd: ++ reiser4_done_ktxnmgrd(super); ++ failed_init_ktxnmgrd: ++ reiser4_done_txnmgr(&sbinfo->tmgr); ++ failed_init_read_super: ++ failed_init_super_data: ++ reiser4_done_fs_info(super); ++ failed_init_sinfo: ++ reiser4_exit_context(&ctx); ++ return result; ++} ++ ++/** ++ * reiser4_get_sb - get_sb of file_system_type operations ++ * @fs_type: ++ * @flags: mount flags MS_RDONLY, MS_VERBOSE, etc ++ * @dev_name: block device file name ++ * @data: specific mount options ++ * ++ * Reiser4 mount entry. ++ */ ++static int reiser4_get_sb(struct file_system_type *fs_type, int flags, ++ const char *dev_name, void *data, struct vfsmount *mnt) ++{ ++ return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); ++} ++ ++/* structure describing the reiser4 filesystem implementation */ ++static struct file_system_type reiser4_fs_type = { ++ .owner = THIS_MODULE, ++ .name = "reiser4", ++ .fs_flags = FS_REQUIRES_DEV, ++ .get_sb = reiser4_get_sb, ++ .kill_sb = kill_block_super, ++ .next = NULL ++}; ++ ++void destroy_reiser4_cache(struct kmem_cache **cachep) ++{ ++ BUG_ON(*cachep == NULL); ++ kmem_cache_destroy(*cachep); ++ *cachep = NULL; ++} ++ ++/** ++ * init_reiser4 - reiser4 initialization entry point ++ * ++ * Initializes reiser4 slabs, registers reiser4 filesystem type. It is called ++ * on kernel initialization or during reiser4 module load. ++ */ ++static int __init init_reiser4(void) ++{ ++ int result; ++ ++ printk(KERN_INFO ++ "Loading Reiser4. " ++ "See www.namesys.com for a description of Reiser4.\n"); ++ ++ /* initialize slab cache of inodes */ ++ if ((result = init_inodes()) != 0) ++ goto failed_inode_cache; ++ ++ /* initialize cache of znodes */ ++ if ((result = init_znodes()) != 0) ++ goto failed_init_znodes; ++ ++ /* initialize all plugins */ ++ if ((result = init_plugins()) != 0) ++ goto failed_init_plugins; ++ ++ /* initialize cache of plugin_set-s and plugin_set's hash table */ ++ if ((result = init_plugin_set()) != 0) ++ goto failed_init_plugin_set; ++ ++ /* initialize caches of txn_atom-s and txn_handle-s */ ++ if ((result = init_txnmgr_static()) != 0) ++ goto failed_init_txnmgr_static; ++ ++ /* initialize cache of jnodes */ ++ if ((result = init_jnodes()) != 0) ++ goto failed_init_jnodes; ++ ++ /* initialize cache of flush queues */ ++ if ((result = reiser4_init_fqs()) != 0) ++ goto failed_init_fqs; ++ ++ /* initialize cache of structures attached to dentry->d_fsdata */ ++ if ((result = reiser4_init_dentry_fsdata()) != 0) ++ goto failed_init_dentry_fsdata; ++ ++ /* initialize cache of structures attached to file->private_data */ ++ if ((result = reiser4_init_file_fsdata()) != 0) ++ goto failed_init_file_fsdata; ++ ++ /* ++ * initialize cache of d_cursors. See plugin/file_ops_readdir.c for ++ * more details ++ */ ++ if ((result = reiser4_init_d_cursor()) != 0) ++ goto failed_init_d_cursor; ++ ++ if ((result = register_filesystem(&reiser4_fs_type)) == 0) { ++ reiser4_debugfs_root = debugfs_create_dir("reiser4", NULL); ++ return 0; ++ } ++ ++ reiser4_done_d_cursor(); ++ failed_init_d_cursor: ++ reiser4_done_file_fsdata(); ++ failed_init_file_fsdata: ++ reiser4_done_dentry_fsdata(); ++ failed_init_dentry_fsdata: ++ reiser4_done_fqs(); ++ failed_init_fqs: ++ done_jnodes(); ++ failed_init_jnodes: ++ done_txnmgr_static(); ++ failed_init_txnmgr_static: ++ done_plugin_set(); ++ failed_init_plugin_set: ++ failed_init_plugins: ++ done_znodes(); ++ failed_init_znodes: ++ done_inodes(); ++ failed_inode_cache: ++ return result; ++} ++ ++/** ++ * done_reiser4 - reiser4 exit entry point ++ * ++ * Unregister reiser4 filesystem type, deletes caches. It is called on shutdown ++ * or at module unload. ++ */ ++static void __exit done_reiser4(void) ++{ ++ int result; ++ ++ debugfs_remove(reiser4_debugfs_root); ++ result = unregister_filesystem(&reiser4_fs_type); ++ BUG_ON(result != 0); ++ reiser4_done_d_cursor(); ++ reiser4_done_file_fsdata(); ++ reiser4_done_dentry_fsdata(); ++ reiser4_done_fqs(); ++ done_jnodes(); ++ done_txnmgr_static(); ++ done_plugin_set(); ++ done_znodes(); ++ destroy_reiser4_cache(&inode_cache); ++} ++ ++module_init(init_reiser4); ++module_exit(done_reiser4); ++ ++MODULE_DESCRIPTION("Reiser4 filesystem"); ++MODULE_AUTHOR("Hans Reiser <Reiser@Namesys.COM>"); ++ ++MODULE_LICENSE("GPL"); ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/tap.c linux-2.6.30/fs/reiser4/tap.c +--- linux-2.6.30.orig/fs/reiser4/tap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/tap.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,376 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* ++ Tree Access Pointer (tap). ++ ++ tap is data structure combining coord and lock handle (mostly). It is ++ useful when one has to scan tree nodes (for example, in readdir, or flush), ++ for tap functions allow to move tap in either direction transparently ++ crossing unit/item/node borders. ++ ++ Tap doesn't provide automatic synchronization of its fields as it is ++ supposed to be per-thread object. ++*/ ++ ++#include "forward.h" ++#include "debug.h" ++#include "coord.h" ++#include "tree.h" ++#include "context.h" ++#include "tap.h" ++#include "znode.h" ++#include "tree_walk.h" ++ ++#if REISER4_DEBUG ++static int tap_invariant(const tap_t *tap); ++static void tap_check(const tap_t *tap); ++#else ++#define tap_check(tap) noop ++#endif ++ ++/** load node tap is pointing to, if not loaded already */ ++int reiser4_tap_load(tap_t *tap) ++{ ++ tap_check(tap); ++ if (tap->loaded == 0) { ++ int result; ++ ++ result = zload_ra(tap->coord->node, &tap->ra_info); ++ if (result != 0) ++ return result; ++ coord_clear_iplug(tap->coord); ++ } ++ ++tap->loaded; ++ tap_check(tap); ++ return 0; ++} ++ ++/** release node tap is pointing to. Dual to tap_load() */ ++void reiser4_tap_relse(tap_t *tap) ++{ ++ tap_check(tap); ++ if (tap->loaded > 0) { ++ --tap->loaded; ++ if (tap->loaded == 0) ++ zrelse(tap->coord->node); ++ } ++ tap_check(tap); ++} ++ ++/** ++ * init tap to consist of @coord and @lh. Locks on nodes will be acquired with ++ * @mode ++ */ ++void reiser4_tap_init(tap_t *tap, coord_t *coord, lock_handle * lh, ++ znode_lock_mode mode) ++{ ++ tap->coord = coord; ++ tap->lh = lh; ++ tap->mode = mode; ++ tap->loaded = 0; ++ INIT_LIST_HEAD(&tap->linkage); ++ reiser4_init_ra_info(&tap->ra_info); ++} ++ ++/** add @tap to the per-thread list of all taps */ ++void reiser4_tap_monitor(tap_t *tap) ++{ ++ assert("nikita-2623", tap != NULL); ++ tap_check(tap); ++ list_add(&tap->linkage, reiser4_taps_list()); ++ tap_check(tap); ++} ++ ++/* duplicate @src into @dst. Copy lock handle. @dst is not initially ++ * loaded. */ ++void reiser4_tap_copy(tap_t *dst, tap_t *src) ++{ ++ assert("nikita-3193", src != NULL); ++ assert("nikita-3194", dst != NULL); ++ ++ *dst->coord = *src->coord; ++ if (src->lh->node) ++ copy_lh(dst->lh, src->lh); ++ dst->mode = src->mode; ++ dst->loaded = 0; ++ INIT_LIST_HEAD(&dst->linkage); ++ dst->ra_info = src->ra_info; ++} ++ ++/** finish with @tap */ ++void reiser4_tap_done(tap_t *tap) ++{ ++ assert("nikita-2565", tap != NULL); ++ tap_check(tap); ++ if (tap->loaded > 0) ++ zrelse(tap->coord->node); ++ done_lh(tap->lh); ++ tap->loaded = 0; ++ list_del_init(&tap->linkage); ++ tap->coord->node = NULL; ++} ++ ++/** ++ * move @tap to the new node, locked with @target. Load @target, if @tap was ++ * already loaded. ++ */ ++int reiser4_tap_move(tap_t *tap, lock_handle * target) ++{ ++ int result = 0; ++ ++ assert("nikita-2567", tap != NULL); ++ assert("nikita-2568", target != NULL); ++ assert("nikita-2570", target->node != NULL); ++ assert("nikita-2569", tap->coord->node == tap->lh->node); ++ ++ tap_check(tap); ++ if (tap->loaded > 0) ++ result = zload_ra(target->node, &tap->ra_info); ++ ++ if (result == 0) { ++ if (tap->loaded > 0) ++ zrelse(tap->coord->node); ++ done_lh(tap->lh); ++ copy_lh(tap->lh, target); ++ tap->coord->node = target->node; ++ coord_clear_iplug(tap->coord); ++ } ++ tap_check(tap); ++ return result; ++} ++ ++/** ++ * move @tap to @target. Acquire lock on @target, if @tap was already ++ * loaded. ++ */ ++static int tap_to(tap_t *tap, znode * target) ++{ ++ int result; ++ ++ assert("nikita-2624", tap != NULL); ++ assert("nikita-2625", target != NULL); ++ ++ tap_check(tap); ++ result = 0; ++ if (tap->coord->node != target) { ++ lock_handle here; ++ ++ init_lh(&here); ++ result = longterm_lock_znode(&here, target, ++ tap->mode, ZNODE_LOCK_HIPRI); ++ if (result == 0) { ++ result = reiser4_tap_move(tap, &here); ++ done_lh(&here); ++ } ++ } ++ tap_check(tap); ++ return result; ++} ++ ++/** ++ * move @tap to given @target, loading and locking @target->node if ++ * necessary ++ */ ++int tap_to_coord(tap_t *tap, coord_t *target) ++{ ++ int result; ++ ++ tap_check(tap); ++ result = tap_to(tap, target->node); ++ if (result == 0) ++ coord_dup(tap->coord, target); ++ tap_check(tap); ++ return result; ++} ++ ++/** return list of all taps */ ++struct list_head *reiser4_taps_list(void) ++{ ++ return &get_current_context()->taps; ++} ++ ++/** helper function for go_{next,prev}_{item,unit,node}() */ ++int go_dir_el(tap_t *tap, sideof dir, int units_p) ++{ ++ coord_t dup; ++ coord_t *coord; ++ int result; ++ ++ int (*coord_dir) (coord_t *); ++ int (*get_dir_neighbor) (lock_handle *, znode *, int, int); ++ void (*coord_init) (coord_t *, const znode *); ++ ON_DEBUG(int (*coord_check) (const coord_t *)); ++ ++ assert("nikita-2556", tap != NULL); ++ assert("nikita-2557", tap->coord != NULL); ++ assert("nikita-2558", tap->lh != NULL); ++ assert("nikita-2559", tap->coord->node != NULL); ++ ++ tap_check(tap); ++ if (dir == LEFT_SIDE) { ++ coord_dir = units_p ? coord_prev_unit : coord_prev_item; ++ get_dir_neighbor = reiser4_get_left_neighbor; ++ coord_init = coord_init_last_unit; ++ } else { ++ coord_dir = units_p ? coord_next_unit : coord_next_item; ++ get_dir_neighbor = reiser4_get_right_neighbor; ++ coord_init = coord_init_first_unit; ++ } ++ ON_DEBUG(coord_check = ++ units_p ? coord_is_existing_unit : coord_is_existing_item); ++ assert("nikita-2560", coord_check(tap->coord)); ++ ++ coord = tap->coord; ++ coord_dup(&dup, coord); ++ if (coord_dir(&dup) != 0) { ++ do { ++ /* move to the left neighboring node */ ++ lock_handle dup; ++ ++ init_lh(&dup); ++ result = ++ get_dir_neighbor(&dup, coord->node, (int)tap->mode, ++ GN_CAN_USE_UPPER_LEVELS); ++ if (result == 0) { ++ result = reiser4_tap_move(tap, &dup); ++ if (result == 0) ++ coord_init(tap->coord, dup.node); ++ done_lh(&dup); ++ } ++ /* skip empty nodes */ ++ } while ((result == 0) && node_is_empty(coord->node)); ++ } else { ++ result = 0; ++ coord_dup(coord, &dup); ++ } ++ assert("nikita-2564", ergo(!result, coord_check(tap->coord))); ++ tap_check(tap); ++ return result; ++} ++ ++/** ++ * move @tap to the next unit, transparently crossing item and node ++ * boundaries ++ */ ++int go_next_unit(tap_t *tap) ++{ ++ return go_dir_el(tap, RIGHT_SIDE, 1); ++} ++ ++/** ++ * move @tap to the previous unit, transparently crossing item and node ++ * boundaries ++ */ ++int go_prev_unit(tap_t *tap) ++{ ++ return go_dir_el(tap, LEFT_SIDE, 1); ++} ++ ++/** ++ * @shift times apply @actor to the @tap. This is used to move @tap by ++ * @shift units (or items, or nodes) in either direction. ++ */ ++static int rewind_to(tap_t *tap, go_actor_t actor, int shift) ++{ ++ int result; ++ ++ assert("nikita-2555", shift >= 0); ++ assert("nikita-2562", tap->coord->node == tap->lh->node); ++ ++ tap_check(tap); ++ result = reiser4_tap_load(tap); ++ if (result != 0) ++ return result; ++ ++ for (; shift > 0; --shift) { ++ result = actor(tap); ++ assert("nikita-2563", tap->coord->node == tap->lh->node); ++ if (result != 0) ++ break; ++ } ++ reiser4_tap_relse(tap); ++ tap_check(tap); ++ return result; ++} ++ ++/** move @tap @shift units rightward */ ++int rewind_right(tap_t *tap, int shift) ++{ ++ return rewind_to(tap, go_next_unit, shift); ++} ++ ++/** move @tap @shift units leftward */ ++int rewind_left(tap_t *tap, int shift) ++{ ++ return rewind_to(tap, go_prev_unit, shift); ++} ++ ++#if REISER4_DEBUG ++/** debugging function: print @tap content in human readable form */ ++static void print_tap(const char *prefix, const tap_t *tap) ++{ ++ if (tap == NULL) { ++ printk("%s: null tap\n", prefix); ++ return; ++ } ++ printk("%s: loaded: %i, in-list: %i, node: %p, mode: %s\n", prefix, ++ tap->loaded, (&tap->linkage == tap->linkage.next && ++ &tap->linkage == tap->linkage.prev), ++ tap->lh->node, ++ lock_mode_name(tap->mode)); ++ print_coord("\tcoord", tap->coord, 0); ++} ++ ++/** check [tap-sane] invariant */ ++static int tap_invariant(const tap_t *tap) ++{ ++ /* [tap-sane] invariant */ ++ ++ if (tap == NULL) ++ return 1; ++ /* tap->mode is one of ++ * ++ * {ZNODE_NO_LOCK, ZNODE_READ_LOCK, ZNODE_WRITE_LOCK}, and ++ */ ++ if (tap->mode != ZNODE_NO_LOCK && ++ tap->mode != ZNODE_READ_LOCK && tap->mode != ZNODE_WRITE_LOCK) ++ return 2; ++ /* tap->coord != NULL, and */ ++ if (tap->coord == NULL) ++ return 3; ++ /* tap->lh != NULL, and */ ++ if (tap->lh == NULL) ++ return 4; ++ /* tap->loaded > 0 => znode_is_loaded(tap->coord->node), and */ ++ if (!ergo(tap->loaded, znode_is_loaded(tap->coord->node))) ++ return 5; ++ /* tap->coord->node == tap->lh->node if tap->lh->node is not 0 */ ++ if (tap->lh->node != NULL && tap->coord->node != tap->lh->node) ++ return 6; ++ return 0; ++} ++ ++/** debugging function: check internal @tap consistency */ ++static void tap_check(const tap_t *tap) ++{ ++ int result; ++ ++ result = tap_invariant(tap); ++ if (result != 0) { ++ print_tap("broken", tap); ++ reiser4_panic("nikita-2831", "tap broken: %i\n", result); ++ } ++} ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/tap.h linux-2.6.30/fs/reiser4/tap.h +--- linux-2.6.30.orig/fs/reiser4/tap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/tap.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,70 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Tree Access Pointers. See tap.c for more details. */ ++ ++#if !defined(__REISER4_TAP_H__) ++#define __REISER4_TAP_H__ ++ ++#include "forward.h" ++#include "readahead.h" ++ ++/** ++ tree_access_pointer aka tap. Data structure combining coord_t and lock ++ handle. ++ Invariants involving this data-type, see doc/lock-ordering for details: ++ ++ [tap-sane] ++ */ ++struct tree_access_pointer { ++ /* coord tap is at */ ++ coord_t *coord; ++ /* lock handle on ->coord->node */ ++ lock_handle *lh; ++ /* mode of lock acquired by this tap */ ++ znode_lock_mode mode; ++ /* incremented by reiser4_tap_load(). ++ Decremented by reiser4_tap_relse(). */ ++ int loaded; ++ /* list of taps */ ++ struct list_head linkage; ++ /* read-ahead hint */ ++ ra_info_t ra_info; ++}; ++ ++typedef int (*go_actor_t) (tap_t *tap); ++ ++extern int reiser4_tap_load(tap_t *tap); ++extern void reiser4_tap_relse(tap_t *tap); ++extern void reiser4_tap_init(tap_t *tap, coord_t *coord, lock_handle * lh, ++ znode_lock_mode mode); ++extern void reiser4_tap_monitor(tap_t *tap); ++extern void reiser4_tap_copy(tap_t *dst, tap_t *src); ++extern void reiser4_tap_done(tap_t *tap); ++extern int reiser4_tap_move(tap_t *tap, lock_handle * target); ++extern int tap_to_coord(tap_t *tap, coord_t *target); ++ ++extern int go_dir_el(tap_t *tap, sideof dir, int units_p); ++extern int go_next_unit(tap_t *tap); ++extern int go_prev_unit(tap_t *tap); ++extern int rewind_right(tap_t *tap, int shift); ++extern int rewind_left(tap_t *tap, int shift); ++ ++extern struct list_head *reiser4_taps_list(void); ++ ++#define for_all_taps(tap) \ ++ for (tap = list_entry(reiser4_taps_list()->next, tap_t, linkage); \ ++ reiser4_taps_list() != &tap->linkage; \ ++ tap = list_entry(tap->linkage.next, tap_t, linkage)) ++ ++/* __REISER4_TAP_H__ */ ++#endif ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/tree.c linux-2.6.30/fs/reiser4/tree.c +--- linux-2.6.30.orig/fs/reiser4/tree.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/tree.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1878 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* ++ * KEYS IN A TREE. ++ * ++ * The tree consists of nodes located on the disk. Node in the tree is either ++ * formatted or unformatted. Formatted node is one that has structure ++ * understood by the tree balancing and traversal code. Formatted nodes are ++ * further classified into leaf and internal nodes. Latter distinctions is ++ * (almost) of only historical importance: general structure of leaves and ++ * internal nodes is the same in Reiser4. Unformatted nodes contain raw data ++ * that are part of bodies of ordinary files and attributes. ++ * ++ * Each node in the tree spawns some interval in the key space. Key ranges for ++ * all nodes in the tree are disjoint. Actually, this only holds in some weak ++ * sense, because of the non-unique keys: intersection of key ranges for ++ * different nodes is either empty, or consists of exactly one key. ++ * ++ * Formatted node consists of a sequence of items. Each item spawns some ++ * interval in key space. Key ranges for all items in a tree are disjoint, ++ * modulo non-unique keys again. Items within nodes are ordered in the key ++ * order of the smallest key in a item. ++ * ++ * Particular type of item can be further split into units. Unit is piece of ++ * item that can be cut from item and moved into another item of the same ++ * time. Units are used by balancing code to repack data during balancing. ++ * ++ * Unit can be further split into smaller entities (for example, extent unit ++ * represents several pages, and it is natural for extent code to operate on ++ * particular pages and even bytes within one unit), but this is of no ++ * relevance to the generic balancing and lookup code. ++ * ++ * Although item is said to "spawn" range or interval of keys, it is not ++ * necessary that item contains piece of data addressable by each and every ++ * key in this range. For example, compound directory item, consisting of ++ * units corresponding to directory entries and keyed by hashes of file names, ++ * looks more as having "discrete spectrum": only some disjoint keys inside ++ * range occupied by this item really address data. ++ * ++ * No than less, each item always has well-defined least (minimal) key, that ++ * is recorded in item header, stored in the node this item is in. Also, item ++ * plugin can optionally define method ->max_key_inside() returning maximal ++ * key that can _possibly_ be located within this item. This method is used ++ * (mainly) to determine when given piece of data should be merged into ++ * existing item, in stead of creating new one. Because of this, even though ++ * ->max_key_inside() can be larger that any key actually located in the item, ++ * intervals ++ * ++ * [ reiser4_min_key( item ), ->max_key_inside( item ) ] ++ * ++ * are still disjoint for all items within the _same_ node. ++ * ++ * In memory node is represented by znode. It plays several roles: ++ * ++ * . something locks are taken on ++ * ++ * . something tracked by transaction manager (this is going to change) ++ * ++ * . something used to access node data ++ * ++ * . something used to maintain tree structure in memory: sibling and ++ * parental linkage. ++ * ++ * . something used to organize nodes into "slums" ++ * ++ * More on znodes see in znode.[ch] ++ * ++ * DELIMITING KEYS ++ * ++ * To simplify balancing, allow some flexibility in locking and speed up ++ * important coord cache optimization, we keep delimiting keys of nodes in ++ * memory. Depending on disk format (implemented by appropriate node plugin) ++ * node on disk can record both left and right delimiting key, only one of ++ * them, or none. Still, our balancing and tree traversal code keep both ++ * delimiting keys for a node that is in memory stored in the znode. When ++ * node is first brought into memory during tree traversal, its left ++ * delimiting key is taken from its parent, and its right delimiting key is ++ * either next key in its parent, or is right delimiting key of parent if ++ * node is the rightmost child of parent. ++ * ++ * Physical consistency of delimiting key is protected by special dk ++ * read-write lock. That is, delimiting keys can only be inspected or ++ * modified under this lock. But dk lock is only sufficient for fast ++ * "pessimistic" check, because to simplify code and to decrease lock ++ * contention, balancing (carry) only updates delimiting keys right before ++ * unlocking all locked nodes on the given tree level. For example, ++ * coord-by-key cache scans LRU list of recently accessed znodes. For each ++ * node it first does fast check under dk spin lock. If key looked for is ++ * not between delimiting keys for this node, next node is inspected and so ++ * on. If key is inside of the key range, long term lock is taken on node ++ * and key range is rechecked. ++ * ++ * COORDINATES ++ * ++ * To find something in the tree, you supply a key, and the key is resolved ++ * by coord_by_key() into a coord (coordinate) that is valid as long as the ++ * node the coord points to remains locked. As mentioned above trees ++ * consist of nodes that consist of items that consist of units. A unit is ++ * the smallest and indivisible piece of tree as far as balancing and tree ++ * search are concerned. Each node, item, and unit can be addressed by ++ * giving its level in the tree and the key occupied by this entity. A node ++ * knows what the key ranges are of the items within it, and how to find its ++ * items and invoke their item handlers, but it does not know how to access ++ * individual units within its items except through the item handlers. ++ * coord is a structure containing a pointer to the node, the ordinal number ++ * of the item within this node (a sort of item offset), and the ordinal ++ * number of the unit within this item. ++ * ++ * TREE LOOKUP ++ * ++ * There are two types of access to the tree: lookup and modification. ++ * ++ * Lookup is a search for the key in the tree. Search can look for either ++ * exactly the key given to it, or for the largest key that is not greater ++ * than the key given to it. This distinction is determined by "bias" ++ * parameter of search routine (coord_by_key()). coord_by_key() either ++ * returns error (key is not in the tree, or some kind of external error ++ * occurred), or successfully resolves key into coord. ++ * ++ * This resolution is done by traversing tree top-to-bottom from root level ++ * to the desired level. On levels above twig level (level one above the ++ * leaf level) nodes consist exclusively of internal items. Internal item is ++ * nothing more than pointer to the tree node on the child level. On twig ++ * level nodes consist of internal items intermixed with extent ++ * items. Internal items form normal search tree structure used by traversal ++ * to descent through the tree. ++ * ++ * TREE LOOKUP OPTIMIZATIONS ++ * ++ * Tree lookup described above is expensive even if all nodes traversed are ++ * already in the memory: for each node binary search within it has to be ++ * performed and binary searches are CPU consuming and tend to destroy CPU ++ * caches. ++ * ++ * Several optimizations are used to work around this: ++ * ++ * . cbk_cache (look-aside cache for tree traversals, see search.c for ++ * details) ++ * ++ * . seals (see seal.[ch]) ++ * ++ * . vroot (see search.c) ++ * ++ * General search-by-key is layered thusly: ++ * ++ * [check seal, if any] --ok--> done ++ * | ++ * failed ++ * | ++ * V ++ * [vroot defined] --no--> node = tree_root ++ * | | ++ * yes | ++ * | | ++ * V | ++ * node = vroot | ++ * | | ++ * | | ++ * | | ++ * V V ++ * [check cbk_cache for key] --ok--> done ++ * | ++ * failed ++ * | ++ * V ++ * [start tree traversal from node] ++ * ++ */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "coord.h" ++#include "plugin/item/static_stat.h" ++#include "plugin/item/item.h" ++#include "plugin/node/node.h" ++#include "plugin/plugin.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree_walk.h" ++#include "carry.h" ++#include "carry_ops.h" ++#include "tap.h" ++#include "tree.h" ++#include "vfs_ops.h" ++#include "page_cache.h" ++#include "super.h" ++#include "reiser4.h" ++#include "inode.h" ++ ++#include <linux/fs.h> /* for struct super_block */ ++#include <linux/spinlock.h> ++ ++/* Disk address (block number) never ever used for any real tree node. This is ++ used as block number of "uber" znode. ++ ++ Invalid block addresses are 0 by tradition. ++ ++*/ ++const reiser4_block_nr UBER_TREE_ADDR = 0ull; ++ ++#define CUT_TREE_MIN_ITERATIONS 64 ++ ++static int find_child_by_addr(znode * parent, znode * child, coord_t *result); ++ ++/* return node plugin of coord->node */ ++node_plugin *node_plugin_by_coord(const coord_t *coord) ++{ ++ assert("vs-1", coord != NULL); ++ assert("vs-2", coord->node != NULL); ++ ++ return coord->node->nplug; ++} ++ ++/* insert item into tree. Fields of @coord are updated so that they can be ++ * used by consequent insert operation. */ ++insert_result insert_by_key(reiser4_tree * tree /* tree to insert new item ++ * into */ , ++ const reiser4_key * key /* key of new item */ , ++ reiser4_item_data * data /* parameters for item ++ * creation */ , ++ coord_t *coord /* resulting insertion coord */ , ++ lock_handle * lh /* resulting lock ++ * handle */ , ++ tree_level stop_level /* level where to insert */ , ++ __u32 flags/* insertion flags */) ++{ ++ int result; ++ ++ assert("nikita-358", tree != NULL); ++ assert("nikita-360", coord != NULL); ++ ++ result = coord_by_key(tree, key, coord, lh, ZNODE_WRITE_LOCK, ++ FIND_EXACT, stop_level, stop_level, ++ flags | CBK_FOR_INSERT, NULL/*ra_info */); ++ switch (result) { ++ default: ++ break; ++ case CBK_COORD_FOUND: ++ result = IBK_ALREADY_EXISTS; ++ break; ++ case CBK_COORD_NOTFOUND: ++ assert("nikita-2017", coord->node != NULL); ++ result = insert_by_coord(coord, data, key, lh, 0/*flags */); ++ break; ++ } ++ return result; ++} ++ ++/* insert item by calling carry. Helper function called if short-cut ++ insertion failed */ ++static insert_result insert_with_carry_by_coord(coord_t *coord, ++ /* coord where to insert */ ++ lock_handle * lh, ++ /* lock handle of insertion node */ ++ reiser4_item_data * data, ++ /* parameters of new item */ ++ const reiser4_key * key, ++ /* key of new item */ ++ carry_opcode cop, ++ /* carry operation to perform */ ++ cop_insert_flag flags ++ /* carry flags */ ) ++{ ++ int result; ++ carry_pool *pool; ++ carry_level *lowest_level; ++ carry_insert_data *cdata; ++ carry_op *op; ++ ++ assert("umka-314", coord != NULL); ++ ++ /* allocate carry_pool and 3 carry_level-s */ ++ pool = ++ init_carry_pool(sizeof(*pool) + 3 * sizeof(*lowest_level) + ++ sizeof(*cdata)); ++ if (IS_ERR(pool)) ++ return PTR_ERR(pool); ++ lowest_level = (carry_level *) (pool + 1); ++ init_carry_level(lowest_level, pool); ++ ++ op = reiser4_post_carry(lowest_level, cop, coord->node, 0); ++ if (IS_ERR(op) || (op == NULL)) { ++ done_carry_pool(pool); ++ return RETERR(op ? PTR_ERR(op) : -EIO); ++ } ++ cdata = (carry_insert_data *) (lowest_level + 3); ++ cdata->coord = coord; ++ cdata->data = data; ++ cdata->key = key; ++ op->u.insert.d = cdata; ++ if (flags == 0) ++ flags = znode_get_tree(coord->node)->carry.insert_flags; ++ op->u.insert.flags = flags; ++ op->u.insert.type = COPT_ITEM_DATA; ++ op->u.insert.child = NULL; ++ if (lh != NULL) { ++ assert("nikita-3245", lh->node == coord->node); ++ lowest_level->track_type = CARRY_TRACK_CHANGE; ++ lowest_level->tracked = lh; ++ } ++ ++ result = reiser4_carry(lowest_level, NULL); ++ done_carry_pool(pool); ++ ++ return result; ++} ++ ++/* form carry queue to perform paste of @data with @key at @coord, and launch ++ its execution by calling carry(). ++ ++ Instruct carry to update @lh it after balancing insertion coord moves into ++ different block. ++ ++*/ ++static int paste_with_carry(coord_t *coord, /* coord of paste */ ++ lock_handle * lh, /* lock handle of node ++ * where item is ++ * pasted */ ++ reiser4_item_data * data, /* parameters of new ++ * item */ ++ const reiser4_key * key, /* key of new item */ ++ unsigned flags/* paste flags */) ++{ ++ int result; ++ carry_pool *pool; ++ carry_level *lowest_level; ++ carry_insert_data *cdata; ++ carry_op *op; ++ ++ assert("umka-315", coord != NULL); ++ assert("umka-316", key != NULL); ++ ++ pool = ++ init_carry_pool(sizeof(*pool) + 3 * sizeof(*lowest_level) + ++ sizeof(*cdata)); ++ if (IS_ERR(pool)) ++ return PTR_ERR(pool); ++ lowest_level = (carry_level *) (pool + 1); ++ init_carry_level(lowest_level, pool); ++ ++ op = reiser4_post_carry(lowest_level, COP_PASTE, coord->node, 0); ++ if (IS_ERR(op) || (op == NULL)) { ++ done_carry_pool(pool); ++ return RETERR(op ? PTR_ERR(op) : -EIO); ++ } ++ cdata = (carry_insert_data *) (lowest_level + 3); ++ cdata->coord = coord; ++ cdata->data = data; ++ cdata->key = key; ++ op->u.paste.d = cdata; ++ if (flags == 0) ++ flags = znode_get_tree(coord->node)->carry.paste_flags; ++ op->u.paste.flags = flags; ++ op->u.paste.type = COPT_ITEM_DATA; ++ if (lh != NULL) { ++ lowest_level->track_type = CARRY_TRACK_CHANGE; ++ lowest_level->tracked = lh; ++ } ++ ++ result = reiser4_carry(lowest_level, NULL); ++ done_carry_pool(pool); ++ ++ return result; ++} ++ ++/* insert item at the given coord. ++ ++ First try to skip carry by directly calling ->create_item() method of node ++ plugin. If this is impossible (there is not enough free space in the node, ++ or leftmost item in the node is created), call insert_with_carry_by_coord() ++ that will do full carry(). ++ ++*/ ++insert_result insert_by_coord(coord_t *coord /* coord where to ++ * insert. coord->node has ++ * to be write locked by ++ * caller */ , ++ reiser4_item_data * data /* data to be ++ * inserted */ , ++ const reiser4_key * key /* key of new item */ , ++ lock_handle * lh /* lock handle of write ++ * lock on node */ , ++ __u32 flags/* insertion flags */) ++{ ++ unsigned item_size; ++ int result; ++ znode *node; ++ ++ assert("vs-247", coord != NULL); ++ assert("vs-248", data != NULL); ++ assert("vs-249", data->length >= 0); ++ assert("nikita-1191", znode_is_write_locked(coord->node)); ++ ++ node = coord->node; ++ coord_clear_iplug(coord); ++ result = zload(node); ++ if (result != 0) ++ return result; ++ ++ item_size = space_needed(node, NULL, data, 1); ++ if (item_size > znode_free_space(node) && ++ (flags & COPI_DONT_SHIFT_LEFT) && (flags & COPI_DONT_SHIFT_RIGHT) ++ && (flags & COPI_DONT_ALLOCATE)) { ++ /* we are forced to use free space of coord->node and new item ++ does not fit into it. ++ ++ Currently we get here only when we allocate and copy units ++ of extent item from a node to its left neighbor during ++ "squalloc"-ing. If @node (this is left neighbor) does not ++ have enough free space - we do not want to attempt any ++ shifting and allocations because we are in squeezing and ++ everything to the left of @node is tightly packed. ++ */ ++ result = -E_NODE_FULL; ++ } else if ((item_size <= znode_free_space(node)) && ++ !coord_is_before_leftmost(coord) && ++ (node_plugin_by_node(node)->fast_insert != NULL) ++ && node_plugin_by_node(node)->fast_insert(coord)) { ++ /* shortcut insertion without carry() overhead. ++ ++ Only possible if: ++ ++ - there is enough free space ++ ++ - insertion is not into the leftmost position in a node ++ (otherwise it would require updating of delimiting key in a ++ parent) ++ ++ - node plugin agrees with this ++ ++ */ ++ result = ++ node_plugin_by_node(node)->create_item(coord, key, data, ++ NULL); ++ znode_make_dirty(node); ++ } else { ++ /* otherwise do full-fledged carry(). */ ++ result = ++ insert_with_carry_by_coord(coord, lh, data, key, COP_INSERT, ++ flags); ++ } ++ zrelse(node); ++ return result; ++} ++ ++/* @coord is set to leaf level and @data is to be inserted to twig level */ ++insert_result ++insert_extent_by_coord(coord_t *coord, /* coord where to insert. ++ * coord->node has to be write ++ * locked by caller */ ++ reiser4_item_data *data,/* data to be inserted */ ++ const reiser4_key *key, /* key of new item */ ++ lock_handle *lh /* lock handle of write lock ++ on node */) ++{ ++ assert("vs-405", coord != NULL); ++ assert("vs-406", data != NULL); ++ assert("vs-407", data->length > 0); ++ assert("vs-408", znode_is_write_locked(coord->node)); ++ assert("vs-409", znode_get_level(coord->node) == LEAF_LEVEL); ++ ++ return insert_with_carry_by_coord(coord, lh, data, key, COP_EXTENT, ++ 0 /*flags */ ); ++} ++ ++/* Insert into the item at the given coord. ++ ++ First try to skip carry by directly calling ->paste() method of item ++ plugin. If this is impossible (there is not enough free space in the node, ++ or we are pasting into leftmost position in the node), call ++ paste_with_carry() that will do full carry(). ++ ++*/ ++/* paste_into_item */ ++int insert_into_item(coord_t * coord /* coord of pasting */ , ++ lock_handle * lh /* lock handle on node involved */ , ++ const reiser4_key * key /* key of unit being pasted */ , ++ reiser4_item_data * data /* parameters for new unit */ , ++ unsigned flags /* insert/paste flags */ ) ++{ ++ int result; ++ int size_change; ++ node_plugin *nplug; ++ item_plugin *iplug; ++ ++ assert("umka-317", coord != NULL); ++ assert("umka-318", key != NULL); ++ ++ iplug = item_plugin_by_coord(coord); ++ nplug = node_plugin_by_coord(coord); ++ ++ assert("nikita-1480", iplug == data->iplug); ++ ++ size_change = space_needed(coord->node, coord, data, 0); ++ if (size_change > (int)znode_free_space(coord->node) && ++ (flags & COPI_DONT_SHIFT_LEFT) && (flags & COPI_DONT_SHIFT_RIGHT) ++ && (flags & COPI_DONT_ALLOCATE)) { ++ /* we are forced to use free space of coord->node and new data ++ does not fit into it. */ ++ return -E_NODE_FULL; ++ } ++ ++ /* shortcut paste without carry() overhead. ++ ++ Only possible if: ++ ++ - there is enough free space ++ ++ - paste is not into the leftmost unit in a node (otherwise ++ it would require updating of delimiting key in a parent) ++ ++ - node plugin agrees with this ++ ++ - item plugin agrees with us ++ */ ++ if (size_change <= (int)znode_free_space(coord->node) && ++ (coord->item_pos != 0 || ++ coord->unit_pos != 0 || coord->between == AFTER_UNIT) && ++ coord->unit_pos != 0 && nplug->fast_paste != NULL && ++ nplug->fast_paste(coord) && ++ iplug->b.fast_paste != NULL && iplug->b.fast_paste(coord)) { ++ if (size_change > 0) ++ nplug->change_item_size(coord, size_change); ++ /* NOTE-NIKITA: huh? where @key is used? */ ++ result = iplug->b.paste(coord, data, NULL); ++ if (size_change < 0) ++ nplug->change_item_size(coord, size_change); ++ znode_make_dirty(coord->node); ++ } else ++ /* otherwise do full-fledged carry(). */ ++ result = paste_with_carry(coord, lh, data, key, flags); ++ return result; ++} ++ ++/* this either appends or truncates item @coord */ ++int reiser4_resize_item(coord_t * coord /* coord of item being resized */ , ++ reiser4_item_data * data /* parameters of resize */ , ++ reiser4_key * key /* key of new unit */ , ++ lock_handle * lh /* lock handle of node ++ * being modified */ , ++ cop_insert_flag flags /* carry flags */ ) ++{ ++ int result; ++ znode *node; ++ ++ assert("nikita-362", coord != NULL); ++ assert("nikita-363", data != NULL); ++ assert("vs-245", data->length != 0); ++ ++ node = coord->node; ++ coord_clear_iplug(coord); ++ result = zload(node); ++ if (result != 0) ++ return result; ++ ++ if (data->length < 0) ++ result = node_plugin_by_coord(coord)->shrink_item(coord, ++ -data->length); ++ else ++ result = insert_into_item(coord, lh, key, data, flags); ++ ++ zrelse(node); ++ return result; ++} ++ ++/* insert flow @f */ ++int reiser4_insert_flow(coord_t * coord, lock_handle * lh, flow_t * f) ++{ ++ int result; ++ carry_pool *pool; ++ carry_level *lowest_level; ++ reiser4_item_data *data; ++ carry_op *op; ++ ++ pool = ++ init_carry_pool(sizeof(*pool) + 3 * sizeof(*lowest_level) + ++ sizeof(*data)); ++ if (IS_ERR(pool)) ++ return PTR_ERR(pool); ++ lowest_level = (carry_level *) (pool + 1); ++ init_carry_level(lowest_level, pool); ++ ++ op = reiser4_post_carry(lowest_level, COP_INSERT_FLOW, coord->node, ++ 0 /* operate directly on coord -> node */ ); ++ if (IS_ERR(op) || (op == NULL)) { ++ done_carry_pool(pool); ++ return RETERR(op ? PTR_ERR(op) : -EIO); ++ } ++ ++ /* these are permanent during insert_flow */ ++ data = (reiser4_item_data *) (lowest_level + 3); ++ data->user = 1; ++ data->iplug = item_plugin_by_id(FORMATTING_ID); ++ data->arg = NULL; ++ /* data.length and data.data will be set before calling paste or ++ insert */ ++ data->length = 0; ++ data->data = NULL; ++ ++ op->u.insert_flow.flags = 0; ++ op->u.insert_flow.insert_point = coord; ++ op->u.insert_flow.flow = f; ++ op->u.insert_flow.data = data; ++ op->u.insert_flow.new_nodes = 0; ++ ++ lowest_level->track_type = CARRY_TRACK_CHANGE; ++ lowest_level->tracked = lh; ++ ++ result = reiser4_carry(lowest_level, NULL); ++ done_carry_pool(pool); ++ ++ return result; ++} ++ ++/* Given a coord in parent node, obtain a znode for the corresponding child */ ++znode *child_znode(const coord_t * parent_coord /* coord of pointer to ++ * child */ , ++ znode * parent /* parent of child */ , ++ int incore_p /* if !0 only return child if already in ++ * memory */ , ++ int setup_dkeys_p /* if !0 update delimiting keys of ++ * child */ ) ++{ ++ znode *child; ++ ++ assert("nikita-1374", parent_coord != NULL); ++ assert("nikita-1482", parent != NULL); ++#if REISER4_DEBUG ++ if (setup_dkeys_p) ++ assert_rw_not_locked(&(znode_get_tree(parent)->dk_lock)); ++#endif ++ assert("nikita-2947", znode_is_any_locked(parent)); ++ ++ if (znode_get_level(parent) <= LEAF_LEVEL) { ++ /* trying to get child of leaf node */ ++ warning("nikita-1217", "Child of maize?"); ++ return ERR_PTR(RETERR(-EIO)); ++ } ++ if (item_is_internal(parent_coord)) { ++ reiser4_block_nr addr; ++ item_plugin *iplug; ++ reiser4_tree *tree; ++ ++ iplug = item_plugin_by_coord(parent_coord); ++ assert("vs-512", iplug->s.internal.down_link); ++ iplug->s.internal.down_link(parent_coord, NULL, &addr); ++ ++ tree = znode_get_tree(parent); ++ if (incore_p) ++ child = zlook(tree, &addr); ++ else ++ child = ++ zget(tree, &addr, parent, ++ znode_get_level(parent) - 1, ++ reiser4_ctx_gfp_mask_get()); ++ if ((child != NULL) && !IS_ERR(child) && setup_dkeys_p) ++ set_child_delimiting_keys(parent, parent_coord, child); ++ } else { ++ warning("nikita-1483", "Internal item expected"); ++ child = ERR_PTR(RETERR(-EIO)); ++ } ++ return child; ++} ++ ++/* remove znode from transaction */ ++static void uncapture_znode(znode * node) ++{ ++ struct page *page; ++ ++ assert("zam-1001", ZF_ISSET(node, JNODE_HEARD_BANSHEE)); ++ ++ if (!reiser4_blocknr_is_fake(znode_get_block(node))) { ++ int ret; ++ ++ /* An already allocated block goes right to the atom's delete set. */ ++ ret = ++ reiser4_dealloc_block(znode_get_block(node), 0, ++ BA_DEFER | BA_FORMATTED); ++ if (ret) ++ warning("zam-942", ++ "can't add a block (%llu) number to atom's delete set\n", ++ (unsigned long long)(*znode_get_block(node))); ++ ++ spin_lock_znode(node); ++ /* Here we return flush reserved block which was reserved at the ++ * moment when this allocated node was marked dirty and still ++ * not used by flush in node relocation procedure. */ ++ if (ZF_ISSET(node, JNODE_FLUSH_RESERVED)) { ++ txn_atom *atom; ++ ++ atom = jnode_get_atom(ZJNODE(node)); ++ assert("zam-939", atom != NULL); ++ spin_unlock_znode(node); ++ flush_reserved2grabbed(atom, (__u64) 1); ++ spin_unlock_atom(atom); ++ } else ++ spin_unlock_znode(node); ++ } else { ++ /* znode has assigned block which is counted as "fake ++ allocated". Return it back to "free blocks") */ ++ fake_allocated2free((__u64) 1, BA_FORMATTED); ++ } ++ ++ /* ++ * uncapture page from transaction. There is a possibility of a race ++ * with ->releasepage(): reiser4_releasepage() detaches page from this ++ * jnode and we have nothing to uncapture. To avoid this, get ++ * reference of node->pg under jnode spin lock. reiser4_uncapture_page() ++ * will deal with released page itself. ++ */ ++ spin_lock_znode(node); ++ page = znode_page(node); ++ if (likely(page != NULL)) { ++ /* ++ * reiser4_uncapture_page() can only be called when we are sure ++ * that znode is pinned in memory, which we are, because ++ * forget_znode() is only called from longterm_unlock_znode(). ++ */ ++ page_cache_get(page); ++ spin_unlock_znode(node); ++ lock_page(page); ++ reiser4_uncapture_page(page); ++ unlock_page(page); ++ page_cache_release(page); ++ } else { ++ txn_atom *atom; ++ ++ /* handle "flush queued" znodes */ ++ while (1) { ++ atom = jnode_get_atom(ZJNODE(node)); ++ assert("zam-943", atom != NULL); ++ ++ if (!ZF_ISSET(node, JNODE_FLUSH_QUEUED) ++ || !atom->nr_running_queues) ++ break; ++ ++ spin_unlock_znode(node); ++ reiser4_atom_wait_event(atom); ++ spin_lock_znode(node); ++ } ++ ++ reiser4_uncapture_block(ZJNODE(node)); ++ spin_unlock_atom(atom); ++ zput(node); ++ } ++} ++ ++/* This is called from longterm_unlock_znode() when last lock is released from ++ the node that has been removed from the tree. At this point node is removed ++ from sibling list and its lock is invalidated. */ ++void forget_znode(lock_handle * handle) ++{ ++ znode *node; ++ reiser4_tree *tree; ++ ++ assert("umka-319", handle != NULL); ++ ++ node = handle->node; ++ tree = znode_get_tree(node); ++ ++ assert("vs-164", znode_is_write_locked(node)); ++ assert("nikita-1280", ZF_ISSET(node, JNODE_HEARD_BANSHEE)); ++ assert_rw_locked(&(node->lock.guard)); ++ ++ /* We assume that this node was detached from its parent before ++ * unlocking, it gives no way to reach this node from parent through a ++ * down link. The node should have no children and, thereby, can't be ++ * reached from them by their parent pointers. The only way to obtain a ++ * reference to the node is to use sibling pointers from its left and ++ * right neighbors. In the next several lines we remove the node from ++ * the sibling list. */ ++ ++ write_lock_tree(tree); ++ sibling_list_remove(node); ++ znode_remove(node, tree); ++ write_unlock_tree(tree); ++ ++ /* Here we set JNODE_DYING and cancel all pending lock requests. It ++ * forces all lock requestor threads to repeat iterations of getting ++ * lock on a child, neighbor or parent node. But, those threads can't ++ * come to this node again, because this node is no longer a child, ++ * neighbor or parent of any other node. This order of znode ++ * invalidation does not allow other threads to waste cpu time is a busy ++ * loop, trying to lock dying object. The exception is in the flush ++ * code when we take node directly from atom's capture list.*/ ++ reiser4_invalidate_lock(handle); ++ uncapture_znode(node); ++} ++ ++/* Check that internal item at @pointer really contains pointer to @child. */ ++int check_tree_pointer(const coord_t * pointer /* would-be pointer to ++ * @child */ , ++ const znode * child /* child znode */ ) ++{ ++ assert("nikita-1016", pointer != NULL); ++ assert("nikita-1017", child != NULL); ++ assert("nikita-1018", pointer->node != NULL); ++ ++ assert("nikita-1325", znode_is_any_locked(pointer->node)); ++ ++ assert("nikita-2985", ++ znode_get_level(pointer->node) == znode_get_level(child) + 1); ++ ++ coord_clear_iplug((coord_t *) pointer); ++ ++ if (coord_is_existing_unit(pointer)) { ++ item_plugin *iplug; ++ reiser4_block_nr addr; ++ ++ if (item_is_internal(pointer)) { ++ iplug = item_plugin_by_coord(pointer); ++ assert("vs-513", iplug->s.internal.down_link); ++ iplug->s.internal.down_link(pointer, NULL, &addr); ++ /* check that cached value is correct */ ++ if (disk_addr_eq(&addr, znode_get_block(child))) { ++ return NS_FOUND; ++ } ++ } ++ } ++ /* warning ("jmacd-1002", "tree pointer incorrect"); */ ++ return NS_NOT_FOUND; ++} ++ ++/* find coord of pointer to new @child in @parent. ++ ++ Find the &coord_t in the @parent where pointer to a given @child will ++ be in. ++ ++*/ ++int find_new_child_ptr(znode * parent /* parent znode, passed locked */ , ++ znode * ++ child UNUSED_ARG /* child znode, passed locked */ , ++ znode * left /* left brother of new node */ , ++ coord_t * result /* where result is stored in */ ) ++{ ++ int ret; ++ ++ assert("nikita-1486", parent != NULL); ++ assert("nikita-1487", child != NULL); ++ assert("nikita-1488", result != NULL); ++ ++ ret = find_child_ptr(parent, left, result); ++ if (ret != NS_FOUND) { ++ warning("nikita-1489", "Cannot find brother position: %i", ret); ++ return RETERR(-EIO); ++ } else { ++ result->between = AFTER_UNIT; ++ return RETERR(NS_NOT_FOUND); ++ } ++} ++ ++/* find coord of pointer to @child in @parent. ++ ++ Find the &coord_t in the @parent where pointer to a given @child is in. ++ ++*/ ++int find_child_ptr(znode * parent /* parent znode, passed locked */ , ++ znode * child /* child znode, passed locked */ , ++ coord_t * result /* where result is stored in */ ) ++{ ++ int lookup_res; ++ node_plugin *nplug; ++ /* left delimiting key of a child */ ++ reiser4_key ld; ++ reiser4_tree *tree; ++ ++ assert("nikita-934", parent != NULL); ++ assert("nikita-935", child != NULL); ++ assert("nikita-936", result != NULL); ++ assert("zam-356", znode_is_loaded(parent)); ++ ++ coord_init_zero(result); ++ result->node = parent; ++ ++ nplug = parent->nplug; ++ assert("nikita-939", nplug != NULL); ++ ++ tree = znode_get_tree(parent); ++ /* NOTE-NIKITA taking read-lock on tree here assumes that @result is ++ * not aliased to ->in_parent of some znode. Otherwise, ++ * parent_coord_to_coord() below would modify data protected by tree ++ * lock. */ ++ read_lock_tree(tree); ++ /* fast path. Try to use cached value. Lock tree to keep ++ node->pos_in_parent and pos->*_blocknr consistent. */ ++ if (child->in_parent.item_pos + 1 != 0) { ++ parent_coord_to_coord(&child->in_parent, result); ++ if (check_tree_pointer(result, child) == NS_FOUND) { ++ read_unlock_tree(tree); ++ return NS_FOUND; ++ } ++ ++ child->in_parent.item_pos = (unsigned short)~0; ++ } ++ read_unlock_tree(tree); ++ ++ /* is above failed, find some key from @child. We are looking for the ++ least key in a child. */ ++ read_lock_dk(tree); ++ ld = *znode_get_ld_key(child); ++ read_unlock_dk(tree); ++ /* ++ * now, lookup parent with key just found. Note, that left delimiting ++ * key doesn't identify node uniquely, because (in extremely rare ++ * case) two nodes can have equal left delimiting keys, if one of them ++ * is completely filled with directory entries that all happened to be ++ * hash collision. But, we check block number in check_tree_pointer() ++ * and, so, are safe. ++ */ ++ lookup_res = nplug->lookup(parent, &ld, FIND_EXACT, result); ++ /* update cached pos_in_node */ ++ if (lookup_res == NS_FOUND) { ++ write_lock_tree(tree); ++ coord_to_parent_coord(result, &child->in_parent); ++ write_unlock_tree(tree); ++ lookup_res = check_tree_pointer(result, child); ++ } ++ if (lookup_res == NS_NOT_FOUND) ++ lookup_res = find_child_by_addr(parent, child, result); ++ return lookup_res; ++} ++ ++/* find coord of pointer to @child in @parent by scanning ++ ++ Find the &coord_t in the @parent where pointer to a given @child ++ is in by scanning all internal items in @parent and comparing block ++ numbers in them with that of @child. ++ ++*/ ++static int find_child_by_addr(znode * parent /* parent znode, passed locked */ , ++ znode * child /* child znode, passed locked */ , ++ coord_t * result /* where result is stored in */ ) ++{ ++ int ret; ++ ++ assert("nikita-1320", parent != NULL); ++ assert("nikita-1321", child != NULL); ++ assert("nikita-1322", result != NULL); ++ ++ ret = NS_NOT_FOUND; ++ ++ for_all_units(result, parent) { ++ if (check_tree_pointer(result, child) == NS_FOUND) { ++ write_lock_tree(znode_get_tree(parent)); ++ coord_to_parent_coord(result, &child->in_parent); ++ write_unlock_tree(znode_get_tree(parent)); ++ ret = NS_FOUND; ++ break; ++ } ++ } ++ return ret; ++} ++ ++/* true, if @addr is "unallocated block number", which is just address, with ++ highest bit set. */ ++int is_disk_addr_unallocated(const reiser4_block_nr * addr /* address to ++ * check */ ) ++{ ++ assert("nikita-1766", addr != NULL); ++ cassert(sizeof(reiser4_block_nr) == 8); ++ return (*addr & REISER4_BLOCKNR_STATUS_BIT_MASK) == ++ REISER4_UNALLOCATED_STATUS_VALUE; ++} ++ ++/* returns true if removing bytes of given range of key [from_key, to_key] ++ causes removing of whole item @from */ ++static int ++item_removed_completely(coord_t * from, const reiser4_key * from_key, ++ const reiser4_key * to_key) ++{ ++ item_plugin *iplug; ++ reiser4_key key_in_item; ++ ++ assert("umka-325", from != NULL); ++ assert("", item_is_extent(from)); ++ ++ /* check first key just for case */ ++ item_key_by_coord(from, &key_in_item); ++ if (keygt(from_key, &key_in_item)) ++ return 0; ++ ++ /* check last key */ ++ iplug = item_plugin_by_coord(from); ++ assert("vs-611", iplug && iplug->s.file.append_key); ++ ++ iplug->s.file.append_key(from, &key_in_item); ++ set_key_offset(&key_in_item, get_key_offset(&key_in_item) - 1); ++ ++ if (keylt(to_key, &key_in_item)) ++ /* last byte is not removed */ ++ return 0; ++ return 1; ++} ++ ++/* helper function for prepare_twig_kill(): @left and @right are formatted ++ * neighbors of extent item being completely removed. Load and lock neighbors ++ * and store lock handles into @cdata for later use by kill_hook_extent() */ ++static int ++prepare_children(znode * left, znode * right, carry_kill_data * kdata) ++{ ++ int result; ++ int left_loaded; ++ int right_loaded; ++ ++ result = 0; ++ left_loaded = right_loaded = 0; ++ ++ if (left != NULL) { ++ result = zload(left); ++ if (result == 0) { ++ left_loaded = 1; ++ result = longterm_lock_znode(kdata->left, left, ++ ZNODE_READ_LOCK, ++ ZNODE_LOCK_LOPRI); ++ } ++ } ++ if (result == 0 && right != NULL) { ++ result = zload(right); ++ if (result == 0) { ++ right_loaded = 1; ++ result = longterm_lock_znode(kdata->right, right, ++ ZNODE_READ_LOCK, ++ ZNODE_LOCK_HIPRI | ++ ZNODE_LOCK_NONBLOCK); ++ } ++ } ++ if (result != 0) { ++ done_lh(kdata->left); ++ done_lh(kdata->right); ++ if (left_loaded != 0) ++ zrelse(left); ++ if (right_loaded != 0) ++ zrelse(right); ++ } ++ return result; ++} ++ ++static void done_children(carry_kill_data * kdata) ++{ ++ if (kdata->left != NULL && kdata->left->node != NULL) { ++ zrelse(kdata->left->node); ++ done_lh(kdata->left); ++ } ++ if (kdata->right != NULL && kdata->right->node != NULL) { ++ zrelse(kdata->right->node); ++ done_lh(kdata->right); ++ } ++} ++ ++/* part of cut_node. It is called when cut_node is called to remove or cut part ++ of extent item. When head of that item is removed - we have to update right ++ delimiting of left neighbor of extent. When item is removed completely - we ++ have to set sibling link between left and right neighbor of removed ++ extent. This may return -E_DEADLOCK because of trying to get left neighbor ++ locked. So, caller should repeat an attempt ++*/ ++/* Audited by: umka (2002.06.16) */ ++static int ++prepare_twig_kill(carry_kill_data * kdata, znode * locked_left_neighbor) ++{ ++ int result; ++ reiser4_key key; ++ lock_handle left_lh; ++ lock_handle right_lh; ++ coord_t left_coord; ++ coord_t *from; ++ znode *left_child; ++ znode *right_child; ++ reiser4_tree *tree; ++ int left_zloaded_here, right_zloaded_here; ++ ++ from = kdata->params.from; ++ assert("umka-326", from != NULL); ++ assert("umka-327", kdata->params.to != NULL); ++ ++ /* for one extent item only yet */ ++ assert("vs-591", item_is_extent(from)); ++ assert("vs-592", from->item_pos == kdata->params.to->item_pos); ++ ++ if ((kdata->params.from_key ++ && keygt(kdata->params.from_key, item_key_by_coord(from, &key))) ++ || from->unit_pos != 0) { ++ /* head of item @from is not removed, there is nothing to ++ worry about */ ++ return 0; ++ } ++ ++ result = 0; ++ left_zloaded_here = 0; ++ right_zloaded_here = 0; ++ ++ left_child = right_child = NULL; ++ ++ coord_dup(&left_coord, from); ++ init_lh(&left_lh); ++ init_lh(&right_lh); ++ if (coord_prev_unit(&left_coord)) { ++ /* @from is leftmost item in its node */ ++ if (!locked_left_neighbor) { ++ result = ++ reiser4_get_left_neighbor(&left_lh, from->node, ++ ZNODE_READ_LOCK, ++ GN_CAN_USE_UPPER_LEVELS); ++ switch (result) { ++ case 0: ++ break; ++ case -E_NO_NEIGHBOR: ++ /* there is no formatted node to the left of ++ from->node */ ++ warning("vs-605", ++ "extent item has smallest key in " ++ "the tree and it is about to be removed"); ++ return 0; ++ case -E_DEADLOCK: ++ /* need to restart */ ++ default: ++ return result; ++ } ++ ++ /* we have acquired left neighbor of from->node */ ++ result = zload(left_lh.node); ++ if (result) ++ goto done; ++ ++ locked_left_neighbor = left_lh.node; ++ } else { ++ /* squalloc_right_twig_cut should have supplied locked ++ * left neighbor */ ++ assert("vs-834", ++ znode_is_write_locked(locked_left_neighbor)); ++ result = zload(locked_left_neighbor); ++ if (result) ++ return result; ++ } ++ ++ left_zloaded_here = 1; ++ coord_init_last_unit(&left_coord, locked_left_neighbor); ++ } ++ ++ if (!item_is_internal(&left_coord)) { ++ /* what else but extent can be on twig level */ ++ assert("vs-606", item_is_extent(&left_coord)); ++ ++ /* there is no left formatted child */ ++ if (left_zloaded_here) ++ zrelse(locked_left_neighbor); ++ done_lh(&left_lh); ++ return 0; ++ } ++ ++ tree = znode_get_tree(left_coord.node); ++ left_child = child_znode(&left_coord, left_coord.node, 1, 0); ++ ++ if (IS_ERR(left_child)) { ++ result = PTR_ERR(left_child); ++ goto done; ++ } ++ ++ /* left child is acquired, calculate new right delimiting key for it ++ and get right child if it is necessary */ ++ if (item_removed_completely ++ (from, kdata->params.from_key, kdata->params.to_key)) { ++ /* try to get right child of removed item */ ++ coord_t right_coord; ++ ++ assert("vs-607", ++ kdata->params.to->unit_pos == ++ coord_last_unit_pos(kdata->params.to)); ++ coord_dup(&right_coord, kdata->params.to); ++ if (coord_next_unit(&right_coord)) { ++ /* @to is rightmost unit in the node */ ++ result = ++ reiser4_get_right_neighbor(&right_lh, from->node, ++ ZNODE_READ_LOCK, ++ GN_CAN_USE_UPPER_LEVELS); ++ switch (result) { ++ case 0: ++ result = zload(right_lh.node); ++ if (result) ++ goto done; ++ ++ right_zloaded_here = 1; ++ coord_init_first_unit(&right_coord, ++ right_lh.node); ++ item_key_by_coord(&right_coord, &key); ++ break; ++ ++ case -E_NO_NEIGHBOR: ++ /* there is no formatted node to the right of ++ from->node */ ++ read_lock_dk(tree); ++ key = *znode_get_rd_key(from->node); ++ read_unlock_dk(tree); ++ right_coord.node = NULL; ++ result = 0; ++ break; ++ default: ++ /* real error */ ++ goto done; ++ } ++ } else { ++ /* there is an item to the right of @from - take its key */ ++ item_key_by_coord(&right_coord, &key); ++ } ++ ++ /* try to get right child of @from */ ++ if (right_coord.node && /* there is right neighbor of @from */ ++ item_is_internal(&right_coord)) { /* it is internal item */ ++ right_child = child_znode(&right_coord, ++ right_coord.node, 1, 0); ++ ++ if (IS_ERR(right_child)) { ++ result = PTR_ERR(right_child); ++ goto done; ++ } ++ ++ } ++ /* whole extent is removed between znodes left_child and right_child. Prepare them for linking and ++ update of right delimiting key of left_child */ ++ result = prepare_children(left_child, right_child, kdata); ++ } else { ++ /* head of item @to is removed. left_child has to get right delimting key update. Prepare it for that */ ++ result = prepare_children(left_child, NULL, kdata); ++ } ++ ++ done: ++ if (right_child) ++ zput(right_child); ++ if (right_zloaded_here) ++ zrelse(right_lh.node); ++ done_lh(&right_lh); ++ ++ if (left_child) ++ zput(left_child); ++ if (left_zloaded_here) ++ zrelse(locked_left_neighbor); ++ done_lh(&left_lh); ++ return result; ++} ++ ++/* this is used to remove part of node content between coordinates @from and @to. Units to which @from and @to are set ++ are to be cut completely */ ++/* for try_to_merge_with_left, delete_copied, reiser4_delete_node */ ++int cut_node_content(coord_t * from, coord_t * to, const reiser4_key * from_key, /* first key to be removed */ ++ const reiser4_key * to_key, /* last key to be removed */ ++ reiser4_key * ++ smallest_removed /* smallest key actually removed */ ) ++{ ++ int result; ++ carry_pool *pool; ++ carry_level *lowest_level; ++ carry_cut_data *cut_data; ++ carry_op *op; ++ ++ assert("vs-1715", coord_compare(from, to) != COORD_CMP_ON_RIGHT); ++ ++ pool = ++ init_carry_pool(sizeof(*pool) + 3 * sizeof(*lowest_level) + ++ sizeof(*cut_data)); ++ if (IS_ERR(pool)) ++ return PTR_ERR(pool); ++ lowest_level = (carry_level *) (pool + 1); ++ init_carry_level(lowest_level, pool); ++ ++ op = reiser4_post_carry(lowest_level, COP_CUT, from->node, 0); ++ assert("vs-1509", op != 0); ++ if (IS_ERR(op)) { ++ done_carry_pool(pool); ++ return PTR_ERR(op); ++ } ++ ++ cut_data = (carry_cut_data *) (lowest_level + 3); ++ cut_data->params.from = from; ++ cut_data->params.to = to; ++ cut_data->params.from_key = from_key; ++ cut_data->params.to_key = to_key; ++ cut_data->params.smallest_removed = smallest_removed; ++ ++ op->u.cut_or_kill.is_cut = 1; ++ op->u.cut_or_kill.u.cut = cut_data; ++ ++ result = reiser4_carry(lowest_level, NULL); ++ done_carry_pool(pool); ++ ++ return result; ++} ++ ++/* cut part of the node ++ ++ Cut part or whole content of node. ++ ++ cut data between @from and @to of @from->node and call carry() to make ++ corresponding changes in the tree. @from->node may become empty. If so - ++ pointer to it will be removed. Neighboring nodes are not changed. Smallest ++ removed key is stored in @smallest_removed ++ ++*/ ++int kill_node_content(coord_t * from, /* coord of the first unit/item that will be eliminated */ ++ coord_t * to, /* coord of the last unit/item that will be eliminated */ ++ const reiser4_key * from_key, /* first key to be removed */ ++ const reiser4_key * to_key, /* last key to be removed */ ++ reiser4_key * smallest_removed, /* smallest key actually removed */ ++ znode * locked_left_neighbor, /* this is set when kill_node_content is called with left neighbor ++ * locked (in squalloc_right_twig_cut, namely) */ ++ struct inode *inode, /* inode of file whose item (or its part) is to be killed. This is necessary to ++ invalidate pages together with item pointing to them */ ++ int truncate) ++{ /* this call is made for file truncate) */ ++ int result; ++ carry_pool *pool; ++ carry_level *lowest_level; ++ carry_kill_data *kdata; ++ lock_handle *left_child; ++ lock_handle *right_child; ++ carry_op *op; ++ ++ assert("umka-328", from != NULL); ++ assert("vs-316", !node_is_empty(from->node)); ++ assert("nikita-1812", coord_is_existing_unit(from) ++ && coord_is_existing_unit(to)); ++ ++ /* allocate carry_pool, 3 carry_level-s, carry_kill_data and structures for kill_hook_extent */ ++ pool = init_carry_pool(sizeof(*pool) + 3 * sizeof(*lowest_level) + ++ sizeof(carry_kill_data) + ++ 2 * sizeof(lock_handle) + ++ 5 * sizeof(reiser4_key) + 2 * sizeof(coord_t)); ++ if (IS_ERR(pool)) ++ return PTR_ERR(pool); ++ ++ lowest_level = (carry_level *) (pool + 1); ++ init_carry_level(lowest_level, pool); ++ ++ kdata = (carry_kill_data *) (lowest_level + 3); ++ left_child = (lock_handle *) (kdata + 1); ++ right_child = left_child + 1; ++ ++ init_lh(left_child); ++ init_lh(right_child); ++ ++ kdata->params.from = from; ++ kdata->params.to = to; ++ kdata->params.from_key = from_key; ++ kdata->params.to_key = to_key; ++ kdata->params.smallest_removed = smallest_removed; ++ kdata->params.truncate = truncate; ++ kdata->flags = 0; ++ kdata->inode = inode; ++ kdata->left = left_child; ++ kdata->right = right_child; ++ /* memory for 5 reiser4_key and 2 coord_t will be used in kill_hook_extent */ ++ kdata->buf = (char *)(right_child + 1); ++ ++ if (znode_get_level(from->node) == TWIG_LEVEL && item_is_extent(from)) { ++ /* left child of extent item may have to get updated right ++ delimiting key and to get linked with right child of extent ++ @from if it will be removed completely */ ++ result = prepare_twig_kill(kdata, locked_left_neighbor); ++ if (result) { ++ done_children(kdata); ++ done_carry_pool(pool); ++ return result; ++ } ++ } ++ ++ op = reiser4_post_carry(lowest_level, COP_CUT, from->node, 0); ++ if (IS_ERR(op) || (op == NULL)) { ++ done_children(kdata); ++ done_carry_pool(pool); ++ return RETERR(op ? PTR_ERR(op) : -EIO); ++ } ++ ++ op->u.cut_or_kill.is_cut = 0; ++ op->u.cut_or_kill.u.kill = kdata; ++ ++ result = reiser4_carry(lowest_level, NULL); ++ ++ done_children(kdata); ++ done_carry_pool(pool); ++ return result; ++} ++ ++void ++fake_kill_hook_tail(struct inode *inode, loff_t start, loff_t end, int truncate) ++{ ++ if (reiser4_inode_get_flag(inode, REISER4_HAS_MMAP)) { ++ pgoff_t start_pg, end_pg; ++ ++ start_pg = start >> PAGE_CACHE_SHIFT; ++ end_pg = (end - 1) >> PAGE_CACHE_SHIFT; ++ ++ if ((start & (PAGE_CACHE_SIZE - 1)) == 0) { ++ /* ++ * kill up to the page boundary. ++ */ ++ assert("vs-123456", start_pg == end_pg); ++ reiser4_invalidate_pages(inode->i_mapping, start_pg, 1, ++ truncate); ++ } else if (start_pg != end_pg) { ++ /* ++ * page boundary is within killed portion of node. ++ */ ++ assert("vs-654321", end_pg - start_pg == 1); ++ reiser4_invalidate_pages(inode->i_mapping, end_pg, ++ end_pg - start_pg, 1); ++ } ++ } ++ inode_sub_bytes(inode, end - start); ++} ++ ++/** ++ * Delete whole @node from the reiser4 tree without loading it. ++ * ++ * @left: locked left neighbor, ++ * @node: node to be deleted, ++ * @smallest_removed: leftmost key of deleted node, ++ * @object: inode pointer, if we truncate a file body. ++ * @truncate: true if called for file truncate. ++ * ++ * @return: 0 if success, error code otherwise. ++ * ++ * NOTE: if @object!=NULL we assume that @smallest_removed != NULL and it ++ * contains the right value of the smallest removed key from the previous ++ * cut_worker() iteration. This is needed for proper accounting of ++ * "i_blocks" and "i_bytes" fields of the @object. ++ */ ++int reiser4_delete_node(znode * node, reiser4_key * smallest_removed, ++ struct inode *object, int truncate) ++{ ++ lock_handle parent_lock; ++ coord_t cut_from; ++ coord_t cut_to; ++ reiser4_tree *tree; ++ int ret; ++ ++ assert("zam-937", node != NULL); ++ assert("zam-933", znode_is_write_locked(node)); ++ assert("zam-999", smallest_removed != NULL); ++ ++ init_lh(&parent_lock); ++ ++ ret = reiser4_get_parent(&parent_lock, node, ZNODE_WRITE_LOCK); ++ if (ret) ++ return ret; ++ ++ assert("zam-934", !znode_above_root(parent_lock.node)); ++ ++ ret = zload(parent_lock.node); ++ if (ret) ++ goto failed_nozrelse; ++ ++ ret = find_child_ptr(parent_lock.node, node, &cut_from); ++ if (ret) ++ goto failed; ++ ++ /* decrement child counter and set parent pointer to NULL before ++ deleting the list from parent node because of checks in ++ internal_kill_item_hook (we can delete the last item from the parent ++ node, the parent node is going to be deleted and its c_count should ++ be zero). */ ++ ++ tree = znode_get_tree(node); ++ write_lock_tree(tree); ++ init_parent_coord(&node->in_parent, NULL); ++ --parent_lock.node->c_count; ++ write_unlock_tree(tree); ++ ++ assert("zam-989", item_is_internal(&cut_from)); ++ ++ /* @node should be deleted after unlocking. */ ++ ZF_SET(node, JNODE_HEARD_BANSHEE); ++ ++ /* remove a pointer from the parent node to the node being deleted. */ ++ coord_dup(&cut_to, &cut_from); ++ /* FIXME: shouldn't this be kill_node_content */ ++ ret = cut_node_content(&cut_from, &cut_to, NULL, NULL, NULL); ++ if (ret) ++ /* FIXME(Zam): Should we re-connect the node to its parent if ++ * cut_node fails? */ ++ goto failed; ++ ++ { ++ reiser4_tree *tree = current_tree; ++ __u64 start_offset = 0, end_offset = 0; ++ ++ read_lock_tree(tree); ++ write_lock_dk(tree); ++ if (object) { ++ /* We use @smallest_removed and the left delimiting of ++ * the current node for @object->i_blocks, i_bytes ++ * calculation. We assume that the items after the ++ * *@smallest_removed key have been deleted from the ++ * file body. */ ++ start_offset = get_key_offset(znode_get_ld_key(node)); ++ end_offset = get_key_offset(smallest_removed); ++ } ++ ++ assert("zam-1021", znode_is_connected(node)); ++ if (node->left) ++ znode_set_rd_key(node->left, znode_get_rd_key(node)); ++ ++ *smallest_removed = *znode_get_ld_key(node); ++ ++ write_unlock_dk(tree); ++ read_unlock_tree(tree); ++ ++ if (object) { ++ /* we used to perform actions which are to be performed on items on their removal from tree in ++ special item method - kill_hook. Here for optimization reasons we avoid reading node ++ containing item we remove and can not call item's kill hook. Instead we call function which ++ does exactly the same things as tail kill hook in assumption that node we avoid reading ++ contains only one item and that item is a tail one. */ ++ fake_kill_hook_tail(object, start_offset, end_offset, ++ truncate); ++ } ++ } ++ failed: ++ zrelse(parent_lock.node); ++ failed_nozrelse: ++ done_lh(&parent_lock); ++ ++ return ret; ++} ++ ++static int can_delete(const reiser4_key *key, znode *node) ++{ ++ int result; ++ ++ read_lock_dk(current_tree); ++ result = keyle(key, znode_get_ld_key(node)); ++ read_unlock_dk(current_tree); ++ return result; ++} ++ ++/** ++ * This subroutine is not optimal but implementation seems to ++ * be easier). ++ * ++ * @tap: the point deletion process begins from, ++ * @from_key: the beginning of the deleted key range, ++ * @to_key: the end of the deleted key range, ++ * @smallest_removed: the smallest removed key, ++ * @truncate: true if called for file truncate. ++ * @progress: return true if a progress in file items deletions was made, ++ * @smallest_removed value is actual in that case. ++ * ++ * @return: 0 if success, error code otherwise, -E_REPEAT means that long ++ * reiser4_cut_tree operation was interrupted for allowing atom commit. ++ */ ++int ++cut_tree_worker_common(tap_t * tap, const reiser4_key * from_key, ++ const reiser4_key * to_key, ++ reiser4_key * smallest_removed, struct inode *object, ++ int truncate, int *progress) ++{ ++ lock_handle next_node_lock; ++ coord_t left_coord; ++ int result; ++ ++ assert("zam-931", tap->coord->node != NULL); ++ assert("zam-932", znode_is_write_locked(tap->coord->node)); ++ ++ *progress = 0; ++ init_lh(&next_node_lock); ++ ++ while (1) { ++ znode *node; /* node from which items are cut */ ++ node_plugin *nplug; /* node plugin for @node */ ++ ++ node = tap->coord->node; ++ ++ /* Move next_node_lock to the next node on the left. */ ++ result = ++ reiser4_get_left_neighbor(&next_node_lock, node, ++ ZNODE_WRITE_LOCK, ++ GN_CAN_USE_UPPER_LEVELS); ++ if (result != 0 && result != -E_NO_NEIGHBOR) ++ break; ++ /* Check can we delete the node as a whole. */ ++ if (*progress && znode_get_level(node) == LEAF_LEVEL && ++ can_delete(from_key, node)) { ++ result = reiser4_delete_node(node, smallest_removed, ++ object, truncate); ++ } else { ++ result = reiser4_tap_load(tap); ++ if (result) ++ return result; ++ ++ /* Prepare the second (right) point for cut_node() */ ++ if (*progress) ++ coord_init_last_unit(tap->coord, node); ++ ++ else if (item_plugin_by_coord(tap->coord)->b.lookup == ++ NULL) ++ /* set rightmost unit for the items without lookup method */ ++ tap->coord->unit_pos = ++ coord_last_unit_pos(tap->coord); ++ ++ nplug = node->nplug; ++ ++ assert("vs-686", nplug); ++ assert("vs-687", nplug->lookup); ++ ++ /* left_coord is leftmost unit cut from @node */ ++ result = nplug->lookup(node, from_key, ++ FIND_MAX_NOT_MORE_THAN, ++ &left_coord); ++ ++ if (IS_CBKERR(result)) ++ break; ++ ++ /* adjust coordinates so that they are set to existing units */ ++ if (coord_set_to_right(&left_coord) ++ || coord_set_to_left(tap->coord)) { ++ result = 0; ++ break; ++ } ++ ++ if (coord_compare(&left_coord, tap->coord) == ++ COORD_CMP_ON_RIGHT) { ++ /* keys from @from_key to @to_key are not in the tree */ ++ result = 0; ++ break; ++ } ++ ++ if (left_coord.item_pos != tap->coord->item_pos) { ++ /* do not allow to cut more than one item. It is added to solve problem of truncating ++ partially converted files. If file is partially converted there may exist a twig node ++ containing both internal item or items pointing to leaf nodes with formatting items ++ and extent item. We do not want to kill internal items being at twig node here ++ because cut_tree_worker assumes killing them from level level */ ++ coord_dup(&left_coord, tap->coord); ++ assert("vs-1652", ++ coord_is_existing_unit(&left_coord)); ++ left_coord.unit_pos = 0; ++ } ++ ++ /* cut data from one node */ ++ /* *smallest_removed = *reiser4_min_key(); */ ++ result = ++ kill_node_content(&left_coord, tap->coord, from_key, ++ to_key, smallest_removed, ++ next_node_lock.node, object, ++ truncate); ++ reiser4_tap_relse(tap); ++ } ++ if (result) ++ break; ++ ++ ++(*progress); ++ ++ /* Check whether all items with keys >= from_key were removed ++ * from the tree. */ ++ if (keyle(smallest_removed, from_key)) ++ /* result = 0; */ ++ break; ++ ++ if (next_node_lock.node == NULL) ++ break; ++ ++ result = reiser4_tap_move(tap, &next_node_lock); ++ done_lh(&next_node_lock); ++ if (result) ++ break; ++ ++ /* Break long reiser4_cut_tree operation (deletion of a large ++ file) if atom requires commit. */ ++ if (*progress > CUT_TREE_MIN_ITERATIONS ++ && current_atom_should_commit()) { ++ result = -E_REPEAT; ++ break; ++ } ++ } ++ done_lh(&next_node_lock); ++ /* assert("vs-301", !keyeq(&smallest_removed, reiser4_min_key())); */ ++ return result; ++} ++ ++/* there is a fundamental problem with optimizing deletes: VFS does it ++ one file at a time. Another problem is that if an item can be ++ anything, then deleting items must be done one at a time. It just ++ seems clean to writes this to specify a from and a to key, and cut ++ everything between them though. */ ++ ++/* use this function with care if deleting more than what is part of a single file. */ ++/* do not use this when cutting a single item, it is suboptimal for that */ ++ ++/* You are encouraged to write plugin specific versions of this. It ++ cannot be optimal for all plugins because it works item at a time, ++ and some plugins could sometimes work node at a time. Regular files ++ however are not optimizable to work node at a time because of ++ extents needing to free the blocks they point to. ++ ++ Optimizations compared to v3 code: ++ ++ It does not balance (that task is left to memory pressure code). ++ ++ Nodes are deleted only if empty. ++ ++ Uses extents. ++ ++ Performs read-ahead of formatted nodes whose contents are part of ++ the deletion. ++*/ ++ ++/** ++ * Delete everything from the reiser4 tree between two keys: @from_key and ++ * @to_key. ++ * ++ * @from_key: the beginning of the deleted key range, ++ * @to_key: the end of the deleted key range, ++ * @smallest_removed: the smallest removed key, ++ * @object: owner of cutting items. ++ * @truncate: true if called for file truncate. ++ * @progress: return true if a progress in file items deletions was made, ++ * @smallest_removed value is actual in that case. ++ * ++ * @return: 0 if success, error code otherwise, -E_REPEAT means that long cut_tree ++ * operation was interrupted for allowing atom commit . ++ */ ++ ++int reiser4_cut_tree_object(reiser4_tree * tree, const reiser4_key * from_key, ++ const reiser4_key * to_key, ++ reiser4_key * smallest_removed_p, ++ struct inode *object, int truncate, int *progress) ++{ ++ lock_handle lock; ++ int result; ++ tap_t tap; ++ coord_t right_coord; ++ reiser4_key smallest_removed; ++ int (*cut_tree_worker) (tap_t *, const reiser4_key *, ++ const reiser4_key *, reiser4_key *, ++ struct inode *, int, int *); ++ STORE_COUNTERS; ++ ++ assert("umka-329", tree != NULL); ++ assert("umka-330", from_key != NULL); ++ assert("umka-331", to_key != NULL); ++ assert("zam-936", keyle(from_key, to_key)); ++ ++ if (smallest_removed_p == NULL) ++ smallest_removed_p = &smallest_removed; ++ ++ init_lh(&lock); ++ ++ do { ++ /* Find rightmost item to cut away from the tree. */ ++ result = reiser4_object_lookup(object, to_key, &right_coord, ++ &lock, ZNODE_WRITE_LOCK, ++ FIND_MAX_NOT_MORE_THAN, ++ TWIG_LEVEL, LEAF_LEVEL, ++ CBK_UNIQUE, NULL /*ra_info */); ++ if (result != CBK_COORD_FOUND) ++ break; ++ if (object == NULL ++ || inode_file_plugin(object)->cut_tree_worker == NULL) ++ cut_tree_worker = cut_tree_worker_common; ++ else ++ cut_tree_worker = ++ inode_file_plugin(object)->cut_tree_worker; ++ reiser4_tap_init(&tap, &right_coord, &lock, ZNODE_WRITE_LOCK); ++ result = ++ cut_tree_worker(&tap, from_key, to_key, smallest_removed_p, ++ object, truncate, progress); ++ reiser4_tap_done(&tap); ++ ++ reiser4_preempt_point(); ++ ++ } while (0); ++ ++ done_lh(&lock); ++ ++ if (result) { ++ switch (result) { ++ case -E_NO_NEIGHBOR: ++ result = 0; ++ break; ++ case -E_DEADLOCK: ++ result = -E_REPEAT; ++ case -E_REPEAT: ++ case -ENOMEM: ++ case -ENOENT: ++ break; ++ default: ++ warning("nikita-2861", "failure: %i", result); ++ } ++ } ++ ++ CHECK_COUNTERS; ++ return result; ++} ++ ++/* repeat reiser4_cut_tree_object until everything is deleted. ++ * unlike cut_file_items, it does not end current transaction if -E_REPEAT ++ * is returned by cut_tree_object. */ ++int reiser4_cut_tree(reiser4_tree * tree, const reiser4_key * from, ++ const reiser4_key * to, struct inode *inode, int truncate) ++{ ++ int result; ++ int progress; ++ ++ do { ++ result = reiser4_cut_tree_object(tree, from, to, NULL, ++ inode, truncate, &progress); ++ } while (result == -E_REPEAT); ++ ++ return result; ++} ++ ++/* finishing reiser4 initialization */ ++int reiser4_init_tree(reiser4_tree * tree /* pointer to structure being ++ * initialized */ , ++ const reiser4_block_nr * root_block /* address of a root block ++ * on a disk */ , ++ tree_level height /* height of a tree */ , ++ node_plugin * nplug /* default node plugin */ ) ++{ ++ int result; ++ ++ assert("nikita-306", tree != NULL); ++ assert("nikita-307", root_block != NULL); ++ assert("nikita-308", height > 0); ++ assert("nikita-309", nplug != NULL); ++ assert("zam-587", tree->super != NULL); ++ ++ tree->root_block = *root_block; ++ tree->height = height; ++ tree->estimate_one_insert = calc_estimate_one_insert(height); ++ tree->nplug = nplug; ++ ++ tree->znode_epoch = 1ull; ++ ++ cbk_cache_init(&tree->cbk_cache); ++ ++ result = znodes_tree_init(tree); ++ if (result == 0) ++ result = jnodes_tree_init(tree); ++ if (result == 0) { ++ tree->uber = zget(tree, &UBER_TREE_ADDR, NULL, 0, ++ reiser4_ctx_gfp_mask_get()); ++ if (IS_ERR(tree->uber)) { ++ result = PTR_ERR(tree->uber); ++ tree->uber = NULL; ++ } ++ } ++ return result; ++} ++ ++/* release resources associated with @tree */ ++void reiser4_done_tree(reiser4_tree * tree /* tree to release */ ) ++{ ++ if (tree == NULL) ++ return; ++ ++ if (tree->uber != NULL) { ++ zput(tree->uber); ++ tree->uber = NULL; ++ } ++ znodes_tree_done(tree); ++ jnodes_tree_done(tree); ++ cbk_cache_done(&tree->cbk_cache); ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/tree.h linux-2.6.30/fs/reiser4/tree.h +--- linux-2.6.30.orig/fs/reiser4/tree.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/tree.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,577 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Tree operations. See fs/reiser4/tree.c for comments */ ++ ++#if !defined( __REISER4_TREE_H__ ) ++#define __REISER4_TREE_H__ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "plugin/node/node.h" ++#include "plugin/plugin.h" ++#include "znode.h" ++#include "tap.h" ++ ++#include <linux/types.h> /* for __u?? */ ++#include <linux/fs.h> /* for struct super_block */ ++#include <linux/spinlock.h> ++#include <linux/sched.h> /* for struct task_struct */ ++ ++/* fictive block number never actually used */ ++extern const reiser4_block_nr UBER_TREE_ADDR; ++ ++/* &cbk_cache_slot - entry in a coord cache. ++ ++ This is entry in a coord_by_key (cbk) cache, represented by ++ &cbk_cache. ++ ++*/ ++typedef struct cbk_cache_slot { ++ /* cached node */ ++ znode *node; ++ /* linkage to the next cbk cache slot in a LRU order */ ++ struct list_head lru; ++} cbk_cache_slot; ++ ++/* &cbk_cache - coord cache. This is part of reiser4_tree. ++ ++ cbk_cache is supposed to speed up tree lookups by caching results of recent ++ successful lookups (we don't cache negative results as dentry cache ++ does). Cache consists of relatively small number of entries kept in a LRU ++ order. Each entry (&cbk_cache_slot) contains a pointer to znode, from ++ which we can obtain a range of keys that covered by this znode. Before ++ embarking into real tree traversal we scan cbk_cache slot by slot and for ++ each slot check whether key we are looking for is between minimal and ++ maximal keys for node pointed to by this slot. If no match is found, real ++ tree traversal is performed and if result is successful, appropriate entry ++ is inserted into cache, possibly pulling least recently used entry out of ++ it. ++ ++ Tree spin lock is used to protect coord cache. If contention for this ++ lock proves to be too high, more finer grained locking can be added. ++ ++ Invariants involving parts of this data-type: ++ ++ [cbk-cache-invariant] ++*/ ++typedef struct cbk_cache { ++ /* serializator */ ++ rwlock_t guard; ++ int nr_slots; ++ /* head of LRU list of cache slots */ ++ struct list_head lru; ++ /* actual array of slots */ ++ cbk_cache_slot *slot; ++} cbk_cache; ++ ++/* level_lookup_result - possible outcome of looking up key at some level. ++ This is used by coord_by_key when traversing tree downward. */ ++typedef enum { ++ /* continue to the next level */ ++ LOOKUP_CONT, ++ /* done. Either required item was found, or we can prove it ++ doesn't exist, or some error occurred. */ ++ LOOKUP_DONE, ++ /* restart traversal from the root. Infamous "repetition". */ ++ LOOKUP_REST ++} level_lookup_result; ++ ++/* This is representation of internal reiser4 tree where all file-system ++ data and meta-data are stored. This structure is passed to all tree ++ manipulation functions. It's different from the super block because: ++ we don't want to limit ourselves to strictly one to one mapping ++ between super blocks and trees, and, because they are logically ++ different: there are things in a super block that have no relation to ++ the tree (bitmaps, journalling area, mount options, etc.) and there ++ are things in a tree that bear no relation to the super block, like ++ tree of znodes. ++ ++ At this time, there is only one tree ++ per filesystem, and this struct is part of the super block. We only ++ call the super block the super block for historical reasons (most ++ other filesystems call the per filesystem metadata the super block). ++*/ ++ ++struct reiser4_tree { ++ /* block_nr == 0 is fake znode. Write lock it, while changing ++ tree height. */ ++ /* disk address of root node of a tree */ ++ reiser4_block_nr root_block; ++ ++ /* level of the root node. If this is 1, tree consists of root ++ node only */ ++ tree_level height; ++ ++ /* ++ * this is cached here avoid calling plugins through function ++ * dereference all the time. ++ */ ++ __u64 estimate_one_insert; ++ ++ /* cache of recent tree lookup results */ ++ cbk_cache cbk_cache; ++ ++ /* hash table to look up znodes by block number. */ ++ z_hash_table zhash_table; ++ z_hash_table zfake_table; ++ /* hash table to look up jnodes by inode and offset. */ ++ j_hash_table jhash_table; ++ ++ /* lock protecting: ++ - parent pointers, ++ - sibling pointers, ++ - znode hash table ++ - coord cache ++ */ ++ /* NOTE: The "giant" tree lock can be replaced by more spin locks, ++ hoping they will be less contented. We can use one spin lock per one ++ znode hash bucket. With adding of some code complexity, sibling ++ pointers can be protected by both znode spin locks. However it looks ++ more SMP scalable we should test this locking change on n-ways (n > ++ 4) SMP machines. Current 4-ways machine test does not show that tree ++ lock is contented and it is a bottleneck (2003.07.25). */ ++ ++ rwlock_t tree_lock; ++ ++ /* lock protecting delimiting keys */ ++ rwlock_t dk_lock; ++ ++ /* spin lock protecting znode_epoch */ ++ spinlock_t epoch_lock; ++ /* version stamp used to mark znode updates. See seal.[ch] for more ++ * information. */ ++ __u64 znode_epoch; ++ ++ znode *uber; ++ node_plugin *nplug; ++ struct super_block *super; ++ struct { ++ /* carry flags used for insertion of new nodes */ ++ __u32 new_node_flags; ++ /* carry flags used for insertion of new extents */ ++ __u32 new_extent_flags; ++ /* carry flags used for paste operations */ ++ __u32 paste_flags; ++ /* carry flags used for insert operations */ ++ __u32 insert_flags; ++ } carry; ++}; ++ ++extern int reiser4_init_tree(reiser4_tree * tree, ++ const reiser4_block_nr * root_block, ++ tree_level height, node_plugin * default_plugin); ++extern void reiser4_done_tree(reiser4_tree * tree); ++ ++/* cbk flags: options for coord_by_key() */ ++typedef enum { ++ /* coord_by_key() is called for insertion. This is necessary because ++ of extents being located at the twig level. For explanation, see ++ comment just above is_next_item_internal(). ++ */ ++ CBK_FOR_INSERT = (1 << 0), ++ /* coord_by_key() is called with key that is known to be unique */ ++ CBK_UNIQUE = (1 << 1), ++ /* coord_by_key() can trust delimiting keys. This options is not user ++ accessible. coord_by_key() will set it automatically. It will be ++ only cleared by special-case in extents-on-the-twig-level handling ++ where it is necessary to insert item with a key smaller than ++ leftmost key in a node. This is necessary because of extents being ++ located at the twig level. For explanation, see comment just above ++ is_next_item_internal(). ++ */ ++ CBK_TRUST_DK = (1 << 2), ++ CBK_READA = (1 << 3), /* original: readahead leaves which contain items of certain file */ ++ CBK_READDIR_RA = (1 << 4), /* readdir: readahead whole directory and all its stat datas */ ++ CBK_DKSET = (1 << 5), ++ CBK_EXTENDED_COORD = (1 << 6), /* coord_t is actually */ ++ CBK_IN_CACHE = (1 << 7), /* node is already in cache */ ++ CBK_USE_CRABLOCK = (1 << 8) /* use crab_lock in stead of long term ++ * lock */ ++} cbk_flags; ++ ++/* insertion outcome. IBK = insert by key */ ++typedef enum { ++ IBK_INSERT_OK = 0, ++ IBK_ALREADY_EXISTS = -EEXIST, ++ IBK_IO_ERROR = -EIO, ++ IBK_NO_SPACE = -E_NODE_FULL, ++ IBK_OOM = -ENOMEM ++} insert_result; ++ ++#define IS_CBKERR(err) ((err) != CBK_COORD_FOUND && (err) != CBK_COORD_NOTFOUND) ++ ++typedef int (*tree_iterate_actor_t) (reiser4_tree * tree, coord_t * coord, ++ lock_handle * lh, void *arg); ++extern int reiser4_iterate_tree(reiser4_tree * tree, coord_t * coord, ++ lock_handle * lh, ++ tree_iterate_actor_t actor, void *arg, ++ znode_lock_mode mode, int through_units_p); ++extern int get_uber_znode(reiser4_tree * tree, znode_lock_mode mode, ++ znode_lock_request pri, lock_handle * lh); ++ ++/* return node plugin of @node */ ++static inline node_plugin *node_plugin_by_node(const znode * ++ node /* node to query */ ) ++{ ++ assert("vs-213", node != NULL); ++ assert("vs-214", znode_is_loaded(node)); ++ ++ return node->nplug; ++} ++ ++/* number of items in @node */ ++static inline pos_in_node_t node_num_items(const znode * node) ++{ ++ assert("nikita-2754", znode_is_loaded(node)); ++ assert("nikita-2468", ++ node_plugin_by_node(node)->num_of_items(node) == node->nr_items); ++ ++ return node->nr_items; ++} ++ ++/* Return the number of items at the present node. Asserts coord->node != ++ NULL. */ ++static inline unsigned coord_num_items(const coord_t * coord) ++{ ++ assert("jmacd-9805", coord->node != NULL); ++ ++ return node_num_items(coord->node); ++} ++ ++/* true if @node is empty */ ++static inline int node_is_empty(const znode * node) ++{ ++ return node_num_items(node) == 0; ++} ++ ++typedef enum { ++ SHIFTED_SOMETHING = 0, ++ SHIFT_NO_SPACE = -E_NODE_FULL, ++ SHIFT_IO_ERROR = -EIO, ++ SHIFT_OOM = -ENOMEM, ++} shift_result; ++ ++extern node_plugin *node_plugin_by_coord(const coord_t * coord); ++extern int is_coord_in_node(const coord_t * coord); ++extern int key_in_node(const reiser4_key *, const coord_t *); ++extern void coord_item_move_to(coord_t * coord, int items); ++extern void coord_unit_move_to(coord_t * coord, int units); ++ ++/* there are two types of repetitive accesses (ra): intra-syscall ++ (local) and inter-syscall (global). Local ra is used when ++ during single syscall we add/delete several items and units in the ++ same place in a tree. Note that plan-A fragments local ra by ++ separating stat-data and file body in key-space. Global ra is ++ used when user does repetitive modifications in the same place in a ++ tree. ++ ++ Our ra implementation serves following purposes: ++ 1 it affects balancing decisions so that next operation in a row ++ can be performed faster; ++ 2 it affects lower-level read-ahead in page-cache; ++ 3 it allows to avoid unnecessary lookups by maintaining some state ++ across several operations (this is only for local ra); ++ 4 it leaves room for lazy-micro-balancing: when we start a sequence of ++ operations they are performed without actually doing any intra-node ++ shifts, until we finish sequence or scope of sequence leaves ++ current node, only then we really pack node (local ra only). ++*/ ++ ++/* another thing that can be useful is to keep per-tree and/or ++ per-process cache of recent lookups. This cache can be organised as a ++ list of block numbers of formatted nodes sorted by starting key in ++ this node. Balancings should invalidate appropriate parts of this ++ cache. ++*/ ++ ++lookup_result coord_by_key(reiser4_tree * tree, const reiser4_key * key, ++ coord_t * coord, lock_handle * handle, ++ znode_lock_mode lock, lookup_bias bias, ++ tree_level lock_level, tree_level stop_level, ++ __u32 flags, ra_info_t *); ++ ++lookup_result reiser4_object_lookup(struct inode *object, ++ const reiser4_key * key, ++ coord_t * coord, ++ lock_handle * lh, ++ znode_lock_mode lock_mode, ++ lookup_bias bias, ++ tree_level lock_level, ++ tree_level stop_level, ++ __u32 flags, ra_info_t * info); ++ ++insert_result insert_by_key(reiser4_tree * tree, const reiser4_key * key, ++ reiser4_item_data * data, coord_t * coord, ++ lock_handle * lh, ++ tree_level stop_level, __u32 flags); ++insert_result insert_by_coord(coord_t * coord, ++ reiser4_item_data * data, const reiser4_key * key, ++ lock_handle * lh, __u32); ++insert_result insert_extent_by_coord(coord_t * coord, ++ reiser4_item_data * data, ++ const reiser4_key * key, lock_handle * lh); ++int cut_node_content(coord_t * from, coord_t * to, const reiser4_key * from_key, ++ const reiser4_key * to_key, ++ reiser4_key * smallest_removed); ++int kill_node_content(coord_t * from, coord_t * to, ++ const reiser4_key * from_key, const reiser4_key * to_key, ++ reiser4_key * smallest_removed, ++ znode * locked_left_neighbor, struct inode *inode, ++ int truncate); ++ ++int reiser4_resize_item(coord_t * coord, reiser4_item_data * data, ++ reiser4_key * key, lock_handle * lh, cop_insert_flag); ++int insert_into_item(coord_t * coord, lock_handle * lh, const reiser4_key * key, ++ reiser4_item_data * data, unsigned); ++int reiser4_insert_flow(coord_t * coord, lock_handle * lh, flow_t * f); ++int find_new_child_ptr(znode * parent, znode * child, znode * left, ++ coord_t * result); ++ ++int shift_right_of_but_excluding_insert_coord(coord_t * insert_coord); ++int shift_left_of_and_including_insert_coord(coord_t * insert_coord); ++ ++void fake_kill_hook_tail(struct inode *, loff_t start, loff_t end, int); ++ ++extern int cut_tree_worker_common(tap_t *, const reiser4_key *, ++ const reiser4_key *, reiser4_key *, ++ struct inode *, int, int *); ++extern int reiser4_cut_tree_object(reiser4_tree *, const reiser4_key *, ++ const reiser4_key *, reiser4_key *, ++ struct inode *, int, int *); ++extern int reiser4_cut_tree(reiser4_tree * tree, const reiser4_key * from, ++ const reiser4_key * to, struct inode *, int); ++ ++extern int reiser4_delete_node(znode *, reiser4_key *, struct inode *, int); ++extern int check_tree_pointer(const coord_t * pointer, const znode * child); ++extern int find_new_child_ptr(znode * parent, znode * child UNUSED_ARG, ++ znode * left, coord_t * result); ++extern int find_child_ptr(znode * parent, znode * child, coord_t * result); ++extern int set_child_delimiting_keys(znode * parent, const coord_t * in_parent, ++ znode * child); ++extern znode *child_znode(const coord_t * in_parent, znode * parent, ++ int incore_p, int setup_dkeys_p); ++ ++extern int cbk_cache_init(cbk_cache * cache); ++extern void cbk_cache_done(cbk_cache * cache); ++extern void cbk_cache_invalidate(const znode * node, reiser4_tree * tree); ++ ++extern char *sprint_address(const reiser4_block_nr * block); ++ ++#if REISER4_DEBUG ++extern void print_coord_content(const char *prefix, coord_t * p); ++extern void reiser4_print_address(const char *prefix, ++ const reiser4_block_nr * block); ++extern void print_tree_rec(const char *prefix, reiser4_tree * tree, ++ __u32 flags); ++extern void check_dkeys(znode *node); ++#else ++#define print_coord_content(p, c) noop ++#define reiser4_print_address(p, b) noop ++#endif ++ ++extern void forget_znode(lock_handle * handle); ++extern int deallocate_znode(znode * node); ++ ++extern int is_disk_addr_unallocated(const reiser4_block_nr * addr); ++ ++/* struct used internally to pack all numerous arguments of tree lookup. ++ Used to avoid passing a lot of arguments to helper functions. */ ++typedef struct cbk_handle { ++ /* tree we are in */ ++ reiser4_tree *tree; ++ /* key we are going after */ ++ const reiser4_key *key; ++ /* coord we will store result in */ ++ coord_t *coord; ++ /* type of lock to take on target node */ ++ znode_lock_mode lock_mode; ++ /* lookup bias. See comments at the declaration of lookup_bias */ ++ lookup_bias bias; ++ /* lock level: level starting from which tree traversal starts taking ++ * write locks. */ ++ tree_level lock_level; ++ /* level where search will stop. Either item will be found between ++ lock_level and stop_level, or CBK_COORD_NOTFOUND will be ++ returned. ++ */ ++ tree_level stop_level; ++ /* level we are currently at */ ++ tree_level level; ++ /* block number of @active node. Tree traversal operates on two ++ nodes: active and parent. */ ++ reiser4_block_nr block; ++ /* put here error message to be printed by caller */ ++ const char *error; ++ /* result passed back to caller */ ++ lookup_result result; ++ /* lock handles for active and parent */ ++ lock_handle *parent_lh; ++ lock_handle *active_lh; ++ reiser4_key ld_key; ++ reiser4_key rd_key; ++ /* flags, passed to the cbk routine. Bits of this bitmask are defined ++ in tree.h:cbk_flags enum. */ ++ __u32 flags; ++ ra_info_t *ra_info; ++ struct inode *object; ++} cbk_handle; ++ ++extern znode_lock_mode cbk_lock_mode(tree_level level, cbk_handle * h); ++ ++/* eottl.c */ ++extern int handle_eottl(cbk_handle *h, int *outcome); ++ ++int lookup_multikey(cbk_handle * handle, int nr_keys); ++int lookup_couple(reiser4_tree * tree, ++ const reiser4_key * key1, const reiser4_key * key2, ++ coord_t * coord1, coord_t * coord2, ++ lock_handle * lh1, lock_handle * lh2, ++ znode_lock_mode lock_mode, lookup_bias bias, ++ tree_level lock_level, tree_level stop_level, __u32 flags, ++ int *result1, int *result2); ++ ++static inline void read_lock_tree(reiser4_tree *tree) ++{ ++ /* check that tree is not locked */ ++ assert("", (LOCK_CNT_NIL(rw_locked_tree) && ++ LOCK_CNT_NIL(read_locked_tree) && ++ LOCK_CNT_NIL(write_locked_tree))); ++ /* check that spinlocks of lower priorities are not held */ ++ assert("", (LOCK_CNT_NIL(spin_locked_txnh) && ++ LOCK_CNT_NIL(rw_locked_dk) && ++ LOCK_CNT_NIL(spin_locked_stack))); ++ ++ read_lock(&(tree->tree_lock)); ++ ++ LOCK_CNT_INC(read_locked_tree); ++ LOCK_CNT_INC(rw_locked_tree); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline void read_unlock_tree(reiser4_tree *tree) ++{ ++ assert("nikita-1375", LOCK_CNT_GTZ(read_locked_tree)); ++ assert("nikita-1376", LOCK_CNT_GTZ(rw_locked_tree)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ LOCK_CNT_DEC(read_locked_tree); ++ LOCK_CNT_DEC(rw_locked_tree); ++ LOCK_CNT_DEC(spin_locked); ++ ++ read_unlock(&(tree->tree_lock)); ++} ++ ++static inline void write_lock_tree(reiser4_tree *tree) ++{ ++ /* check that tree is not locked */ ++ assert("", (LOCK_CNT_NIL(rw_locked_tree) && ++ LOCK_CNT_NIL(read_locked_tree) && ++ LOCK_CNT_NIL(write_locked_tree))); ++ /* check that spinlocks of lower priorities are not held */ ++ assert("", (LOCK_CNT_NIL(spin_locked_txnh) && ++ LOCK_CNT_NIL(rw_locked_dk) && ++ LOCK_CNT_NIL(spin_locked_stack))); ++ ++ write_lock(&(tree->tree_lock)); ++ ++ LOCK_CNT_INC(write_locked_tree); ++ LOCK_CNT_INC(rw_locked_tree); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline void write_unlock_tree(reiser4_tree *tree) ++{ ++ assert("nikita-1375", LOCK_CNT_GTZ(write_locked_tree)); ++ assert("nikita-1376", LOCK_CNT_GTZ(rw_locked_tree)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ LOCK_CNT_DEC(write_locked_tree); ++ LOCK_CNT_DEC(rw_locked_tree); ++ LOCK_CNT_DEC(spin_locked); ++ ++ write_unlock(&(tree->tree_lock)); ++} ++ ++static inline void read_lock_dk(reiser4_tree *tree) ++{ ++ /* check that dk is not locked */ ++ assert("", (LOCK_CNT_NIL(rw_locked_dk) && ++ LOCK_CNT_NIL(read_locked_dk) && ++ LOCK_CNT_NIL(write_locked_dk))); ++ /* check that spinlocks of lower priorities are not held */ ++ assert("", LOCK_CNT_NIL(spin_locked_stack)); ++ ++ read_lock(&((tree)->dk_lock)); ++ ++ LOCK_CNT_INC(read_locked_dk); ++ LOCK_CNT_INC(rw_locked_dk); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline void read_unlock_dk(reiser4_tree *tree) ++{ ++ assert("nikita-1375", LOCK_CNT_GTZ(read_locked_dk)); ++ assert("nikita-1376", LOCK_CNT_GTZ(rw_locked_dk)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ LOCK_CNT_DEC(read_locked_dk); ++ LOCK_CNT_DEC(rw_locked_dk); ++ LOCK_CNT_DEC(spin_locked); ++ ++ read_unlock(&(tree->dk_lock)); ++} ++ ++static inline void write_lock_dk(reiser4_tree *tree) ++{ ++ /* check that dk is not locked */ ++ assert("", (LOCK_CNT_NIL(rw_locked_dk) && ++ LOCK_CNT_NIL(read_locked_dk) && ++ LOCK_CNT_NIL(write_locked_dk))); ++ /* check that spinlocks of lower priorities are not held */ ++ assert("", LOCK_CNT_NIL(spin_locked_stack)); ++ ++ write_lock(&((tree)->dk_lock)); ++ ++ LOCK_CNT_INC(write_locked_dk); ++ LOCK_CNT_INC(rw_locked_dk); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline void write_unlock_dk(reiser4_tree *tree) ++{ ++ assert("nikita-1375", LOCK_CNT_GTZ(write_locked_dk)); ++ assert("nikita-1376", LOCK_CNT_GTZ(rw_locked_dk)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ LOCK_CNT_DEC(write_locked_dk); ++ LOCK_CNT_DEC(rw_locked_dk); ++ LOCK_CNT_DEC(spin_locked); ++ ++ write_unlock(&(tree->dk_lock)); ++} ++ ++/* estimate api. Implementation is in estimate.c */ ++reiser4_block_nr estimate_one_insert_item(reiser4_tree *); ++reiser4_block_nr estimate_one_insert_into_item(reiser4_tree *); ++reiser4_block_nr estimate_insert_flow(tree_level); ++reiser4_block_nr estimate_one_item_removal(reiser4_tree *); ++reiser4_block_nr calc_estimate_one_insert(tree_level); ++reiser4_block_nr estimate_dirty_cluster(struct inode *); ++reiser4_block_nr estimate_insert_cluster(struct inode *); ++reiser4_block_nr estimate_update_cluster(struct inode *); ++ ++/* __REISER4_TREE_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/tree_mod.c linux-2.6.30/fs/reiser4/tree_mod.c +--- linux-2.6.30.orig/fs/reiser4/tree_mod.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/tree_mod.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,386 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* ++ * Functions to add/delete new nodes to/from the tree. ++ * ++ * Functions from this file are used by carry (see carry*) to handle: ++ * ++ * . insertion of new formatted node into tree ++ * ++ * . addition of new tree root, increasing tree height ++ * ++ * . removing tree root, decreasing tree height ++ * ++ */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "coord.h" ++#include "plugin/plugin.h" ++#include "jnode.h" ++#include "znode.h" ++#include "tree_mod.h" ++#include "block_alloc.h" ++#include "tree_walk.h" ++#include "tree.h" ++#include "super.h" ++ ++#include <linux/err.h> ++ ++static int add_child_ptr(znode * parent, znode * child); ++/* warning only issued if error is not -E_REPEAT */ ++#define ewarning( error, ... ) \ ++ if( ( error ) != -E_REPEAT ) \ ++ warning( __VA_ARGS__ ) ++ ++/* allocate new node on the @level and immediately on the right of @brother. */ ++znode * reiser4_new_node(znode * brother /* existing left neighbor ++ * of new node */, ++ tree_level level /* tree level at which new node is to ++ * be allocated */) ++{ ++ znode *result; ++ int retcode; ++ reiser4_block_nr blocknr; ++ ++ assert("nikita-930", brother != NULL); ++ assert("umka-264", level < REAL_MAX_ZTREE_HEIGHT); ++ ++ retcode = assign_fake_blocknr_formatted(&blocknr); ++ if (retcode == 0) { ++ result = ++ zget(znode_get_tree(brother), &blocknr, NULL, level, ++ reiser4_ctx_gfp_mask_get()); ++ if (IS_ERR(result)) { ++ ewarning(PTR_ERR(result), "nikita-929", ++ "Cannot allocate znode for carry: %li", ++ PTR_ERR(result)); ++ return result; ++ } ++ /* cheap test, can be executed even when debugging is off */ ++ if (!znode_just_created(result)) { ++ warning("nikita-2213", ++ "Allocated already existing block: %llu", ++ (unsigned long long)blocknr); ++ zput(result); ++ return ERR_PTR(RETERR(-EIO)); ++ } ++ ++ assert("nikita-931", result != NULL); ++ result->nplug = znode_get_tree(brother)->nplug; ++ assert("nikita-933", result->nplug != NULL); ++ ++ retcode = zinit_new(result, reiser4_ctx_gfp_mask_get()); ++ if (retcode == 0) { ++ ZF_SET(result, JNODE_CREATED); ++ zrelse(result); ++ } else { ++ zput(result); ++ result = ERR_PTR(retcode); ++ } ++ } else { ++ /* failure to allocate new node during balancing. ++ This should never happen. Ever. Returning -E_REPEAT ++ is not viable solution, because "out of disk space" ++ is not transient error that will go away by itself. ++ */ ++ ewarning(retcode, "nikita-928", ++ "Cannot allocate block for carry: %i", retcode); ++ result = ERR_PTR(retcode); ++ } ++ assert("nikita-1071", result != NULL); ++ return result; ++} ++ ++/* allocate new root and add it to the tree ++ ++ This helper function is called by add_new_root(). ++ ++*/ ++znode *reiser4_add_tree_root(znode * old_root /* existing tree root */ , ++ znode * fake /* "fake" znode */ ) ++{ ++ reiser4_tree *tree = znode_get_tree(old_root); ++ znode *new_root = NULL; /* to shut gcc up */ ++ int result; ++ ++ assert("nikita-1069", old_root != NULL); ++ assert("umka-262", fake != NULL); ++ assert("umka-263", tree != NULL); ++ ++ /* "fake" znode---one always hanging just above current root. This ++ node is locked when new root is created or existing root is ++ deleted. Downward tree traversal takes lock on it before taking ++ lock on a root node. This avoids race conditions with root ++ manipulations. ++ ++ */ ++ assert("nikita-1348", znode_above_root(fake)); ++ assert("nikita-1211", znode_is_root(old_root)); ++ ++ result = 0; ++ if (tree->height >= REAL_MAX_ZTREE_HEIGHT) { ++ warning("nikita-1344", "Tree is too tall: %i", tree->height); ++ /* ext2 returns -ENOSPC when it runs out of free inodes with a ++ following comment (fs/ext2/ialloc.c:441): Is it really ++ ENOSPC? ++ ++ -EXFULL? -EINVAL? ++ */ ++ result = RETERR(-ENOSPC); ++ } else { ++ /* Allocate block for new root. It's not that ++ important where it will be allocated, as root is ++ almost always in memory. Moreover, allocate on ++ flush can be going here. ++ */ ++ assert("nikita-1448", znode_is_root(old_root)); ++ new_root = reiser4_new_node(fake, tree->height + 1); ++ if (!IS_ERR(new_root) && (result = zload(new_root)) == 0) { ++ lock_handle rlh; ++ ++ init_lh(&rlh); ++ result = ++ longterm_lock_znode(&rlh, new_root, ++ ZNODE_WRITE_LOCK, ++ ZNODE_LOCK_LOPRI); ++ if (result == 0) { ++ parent_coord_t *in_parent; ++ ++ znode_make_dirty(fake); ++ ++ /* new root is a child of "fake" node */ ++ write_lock_tree(tree); ++ ++ ++tree->height; ++ ++ /* recalculate max balance overhead */ ++ tree->estimate_one_insert = ++ estimate_one_insert_item(tree); ++ ++ tree->root_block = *znode_get_block(new_root); ++ in_parent = &new_root->in_parent; ++ init_parent_coord(in_parent, fake); ++ /* manually insert new root into sibling ++ * list. With this all nodes involved into ++ * balancing are connected after balancing is ++ * done---useful invariant to check. */ ++ sibling_list_insert_nolock(new_root, NULL); ++ write_unlock_tree(tree); ++ ++ /* insert into new root pointer to the ++ @old_root. */ ++ assert("nikita-1110", ++ WITH_DATA(new_root, ++ node_is_empty(new_root))); ++ write_lock_dk(tree); ++ znode_set_ld_key(new_root, reiser4_min_key()); ++ znode_set_rd_key(new_root, reiser4_max_key()); ++ write_unlock_dk(tree); ++ if (REISER4_DEBUG) { ++ ZF_CLR(old_root, JNODE_LEFT_CONNECTED); ++ ZF_CLR(old_root, JNODE_RIGHT_CONNECTED); ++ ZF_SET(old_root, JNODE_ORPHAN); ++ } ++ result = add_child_ptr(new_root, old_root); ++ done_lh(&rlh); ++ } ++ zrelse(new_root); ++ } ++ } ++ if (result != 0) ++ new_root = ERR_PTR(result); ++ return new_root; ++} ++ ++/* build &reiser4_item_data for inserting child pointer ++ ++ Build &reiser4_item_data that can be later used to insert pointer to @child ++ in its parent. ++ ++*/ ++void build_child_ptr_data(znode * child /* node pointer to which will be ++ * inserted */ , ++ reiser4_item_data * data /* where to store result */ ) ++{ ++ assert("nikita-1116", child != NULL); ++ assert("nikita-1117", data != NULL); ++ ++ /* ++ * NOTE: use address of child's blocknr as address of data to be ++ * inserted. As result of this data gets into on-disk structure in cpu ++ * byte order. internal's create_hook converts it to little endian byte ++ * order. ++ */ ++ data->data = (char *)znode_get_block(child); ++ /* data -> data is kernel space */ ++ data->user = 0; ++ data->length = sizeof(reiser4_block_nr); ++ /* FIXME-VS: hardcoded internal item? */ ++ ++ /* AUDIT: Is it possible that "item_plugin_by_id" may find nothing? */ ++ data->iplug = item_plugin_by_id(NODE_POINTER_ID); ++} ++ ++/* add pointer to @child into empty @parent. ++ ++ This is used when pointer to old root is inserted into new root which is ++ empty. ++*/ ++static int add_child_ptr(znode * parent, znode * child) ++{ ++ coord_t coord; ++ reiser4_item_data data; ++ int result; ++ reiser4_key key; ++ ++ assert("nikita-1111", parent != NULL); ++ assert("nikita-1112", child != NULL); ++ assert("nikita-1115", ++ znode_get_level(parent) == znode_get_level(child) + 1); ++ ++ result = zload(parent); ++ if (result != 0) ++ return result; ++ assert("nikita-1113", node_is_empty(parent)); ++ coord_init_first_unit(&coord, parent); ++ ++ build_child_ptr_data(child, &data); ++ data.arg = NULL; ++ ++ read_lock_dk(znode_get_tree(parent)); ++ key = *znode_get_ld_key(child); ++ read_unlock_dk(znode_get_tree(parent)); ++ ++ result = node_plugin_by_node(parent)->create_item(&coord, &key, &data, ++ NULL); ++ znode_make_dirty(parent); ++ zrelse(parent); ++ return result; ++} ++ ++/* actually remove tree root */ ++static int reiser4_kill_root(reiser4_tree * tree /* tree from which root is ++ * being removed */, ++ znode * old_root /* root node that is being ++ * removed */ , ++ znode * new_root /* new root---sole child of ++ * @old_root */, ++ const reiser4_block_nr * new_root_blk /* disk address of ++ * @new_root */) ++{ ++ znode *uber; ++ int result; ++ lock_handle handle_for_uber; ++ ++ assert("umka-265", tree != NULL); ++ assert("nikita-1198", new_root != NULL); ++ assert("nikita-1199", ++ znode_get_level(new_root) + 1 == znode_get_level(old_root)); ++ ++ assert("nikita-1201", znode_is_write_locked(old_root)); ++ ++ assert("nikita-1203", ++ disk_addr_eq(new_root_blk, znode_get_block(new_root))); ++ ++ init_lh(&handle_for_uber); ++ /* obtain and lock "fake" znode protecting changes in tree height. */ ++ result = get_uber_znode(tree, ZNODE_WRITE_LOCK, ZNODE_LOCK_HIPRI, ++ &handle_for_uber); ++ if (result == 0) { ++ uber = handle_for_uber.node; ++ ++ znode_make_dirty(uber); ++ ++ /* don't take long term lock a @new_root. Take spinlock. */ ++ ++ write_lock_tree(tree); ++ ++ tree->root_block = *new_root_blk; ++ --tree->height; ++ ++ /* recalculate max balance overhead */ ++ tree->estimate_one_insert = estimate_one_insert_item(tree); ++ ++ assert("nikita-1202", ++ tree->height == znode_get_level(new_root)); ++ ++ /* new root is child on "fake" node */ ++ init_parent_coord(&new_root->in_parent, uber); ++ ++uber->c_count; ++ ++ /* sibling_list_insert_nolock(new_root, NULL); */ ++ write_unlock_tree(tree); ++ ++ /* reinitialise old root. */ ++ result = node_plugin_by_node(old_root)->init(old_root); ++ znode_make_dirty(old_root); ++ if (result == 0) { ++ assert("nikita-1279", node_is_empty(old_root)); ++ ZF_SET(old_root, JNODE_HEARD_BANSHEE); ++ old_root->c_count = 0; ++ } ++ } ++ done_lh(&handle_for_uber); ++ ++ return result; ++} ++ ++/* remove tree root ++ ++ This function removes tree root, decreasing tree height by one. Tree root ++ and its only child (that is going to become new tree root) are write locked ++ at the entry. ++ ++ To remove tree root we need to take lock on special "fake" znode that ++ protects changes of tree height. See comments in reiser4_add_tree_root() for ++ more on this. ++ ++ Also parent pointers have to be updated in ++ old and new root. To simplify code, function is split into two parts: outer ++ reiser4_kill_tree_root() collects all necessary arguments and calls ++ reiser4_kill_root() to do the actual job. ++ ++*/ ++int reiser4_kill_tree_root(znode * old_root /* tree root that we are ++ removing*/) ++{ ++ int result; ++ coord_t down_link; ++ znode *new_root; ++ reiser4_tree *tree; ++ ++ assert("umka-266", current_tree != NULL); ++ assert("nikita-1194", old_root != NULL); ++ assert("nikita-1196", znode_is_root(old_root)); ++ assert("nikita-1200", node_num_items(old_root) == 1); ++ assert("nikita-1401", znode_is_write_locked(old_root)); ++ ++ coord_init_first_unit(&down_link, old_root); ++ ++ tree = znode_get_tree(old_root); ++ new_root = child_znode(&down_link, old_root, 0, 1); ++ if (!IS_ERR(new_root)) { ++ result = ++ reiser4_kill_root(tree, old_root, new_root, ++ znode_get_block(new_root)); ++ zput(new_root); ++ } else ++ result = PTR_ERR(new_root); ++ ++ return result; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/tree_mod.h linux-2.6.30/fs/reiser4/tree_mod.h +--- linux-2.6.30.orig/fs/reiser4/tree_mod.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/tree_mod.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,29 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Functions to add/delete new nodes to/from the tree. See tree_mod.c for ++ * comments. */ ++ ++#if !defined( __REISER4_TREE_MOD_H__ ) ++#define __REISER4_TREE_MOD_H__ ++ ++#include "forward.h" ++ ++znode *reiser4_new_node(znode * brother, tree_level level); ++znode *reiser4_add_tree_root(znode * old_root, znode * fake); ++int reiser4_kill_tree_root(znode * old_root); ++void build_child_ptr_data(znode * child, reiser4_item_data * data); ++ ++/* __REISER4_TREE_MOD_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/tree_walk.c linux-2.6.30/fs/reiser4/tree_walk.c +--- linux-2.6.30.orig/fs/reiser4/tree_walk.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/tree_walk.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,927 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Routines and macros to: ++ ++ get_left_neighbor() ++ ++ get_right_neighbor() ++ ++ get_parent() ++ ++ get_first_child() ++ ++ get_last_child() ++ ++ various routines to walk the whole tree and do things to it like ++ repack it, or move it to tertiary storage. Please make them as ++ generic as is reasonable. ++ ++*/ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "coord.h" ++#include "plugin/item/item.h" ++#include "jnode.h" ++#include "znode.h" ++#include "tree_walk.h" ++#include "tree.h" ++#include "super.h" ++ ++/* These macros are used internally in tree_walk.c in attempt to make ++ lock_neighbor() code usable to build lock_parent(), lock_right_neighbor, ++ lock_left_neighbor */ ++#define GET_NODE_BY_PTR_OFFSET(node, off) (*(znode**)(((unsigned long)(node)) + (off))) ++#define FIELD_OFFSET(name) offsetof(znode, name) ++#define PARENT_PTR_OFFSET FIELD_OFFSET(in_parent.node) ++#define LEFT_PTR_OFFSET FIELD_OFFSET(left) ++#define RIGHT_PTR_OFFSET FIELD_OFFSET(right) ++ ++/* This is the generic procedure to get and lock `generic' neighbor (left or ++ right neighbor or parent). It implements common algorithm for all cases of ++ getting lock on neighbor node, only znode structure field is different in ++ each case. This is parameterized by ptr_offset argument, which is byte ++ offset for the pointer to the desired neighbor within the current node's ++ znode structure. This function should be called with the tree lock held */ ++static int lock_neighbor( ++ /* resulting lock handle */ ++ lock_handle * result, ++ /* znode to lock */ ++ znode * node, ++ /* pointer to neighbor (or parent) znode field offset, in bytes from ++ the base address of znode structure */ ++ int ptr_offset, ++ /* lock mode for longterm_lock_znode call */ ++ znode_lock_mode mode, ++ /* lock request for longterm_lock_znode call */ ++ znode_lock_request req, ++ /* GN_* flags */ ++ int flags, int rlocked) ++{ ++ reiser4_tree *tree = znode_get_tree(node); ++ znode *neighbor; ++ int ret; ++ ++ assert("umka-236", node != NULL); ++ assert("umka-237", tree != NULL); ++ assert_rw_locked(&(tree->tree_lock)); ++ ++ if (flags & GN_TRY_LOCK) ++ req |= ZNODE_LOCK_NONBLOCK; ++ if (flags & GN_SAME_ATOM) ++ req |= ZNODE_LOCK_DONT_FUSE; ++ ++ /* get neighbor's address by using of sibling link, quit while loop ++ (and return) if link is not available. */ ++ while (1) { ++ neighbor = GET_NODE_BY_PTR_OFFSET(node, ptr_offset); ++ ++ /* return -E_NO_NEIGHBOR if parent or side pointer is NULL or if ++ * node pointed by it is not connected. ++ * ++ * However, GN_ALLOW_NOT_CONNECTED option masks "connected" ++ * check and allows passing reference to not connected znode to ++ * subsequent longterm_lock_znode() call. This kills possible ++ * busy loop if we are trying to get longterm lock on locked but ++ * not yet connected parent node. */ ++ if (neighbor == NULL || !((flags & GN_ALLOW_NOT_CONNECTED) ++ || znode_is_connected(neighbor))) { ++ return RETERR(-E_NO_NEIGHBOR); ++ } ++ ++ /* protect it from deletion. */ ++ zref(neighbor); ++ ++ rlocked ? read_unlock_tree(tree) : write_unlock_tree(tree); ++ ++ ret = longterm_lock_znode(result, neighbor, mode, req); ++ ++ /* The lock handle obtains its own reference, release the one from above. */ ++ zput(neighbor); ++ ++ rlocked ? read_lock_tree(tree) : write_lock_tree(tree); ++ ++ /* restart if node we got reference to is being ++ invalidated. we should not get reference to this node ++ again. */ ++ if (ret == -EINVAL) ++ continue; ++ if (ret) ++ return ret; ++ ++ /* check if neighbor link still points to just locked znode; ++ the link could have been changed while the process slept. */ ++ if (neighbor == GET_NODE_BY_PTR_OFFSET(node, ptr_offset)) ++ return 0; ++ ++ /* znode was locked by mistake; unlock it and restart locking ++ process from beginning. */ ++ rlocked ? read_unlock_tree(tree) : write_unlock_tree(tree); ++ longterm_unlock_znode(result); ++ rlocked ? read_lock_tree(tree) : write_lock_tree(tree); ++ } ++} ++ ++/* get parent node with longterm lock, accepts GN* flags. */ ++int reiser4_get_parent_flags(lock_handle * lh /* resulting lock handle */ , ++ znode * node /* child node */ , ++ znode_lock_mode mode ++ /* type of lock: read or write */ , ++ int flags /* GN_* flags */ ) ++{ ++ int result; ++ ++ read_lock_tree(znode_get_tree(node)); ++ result = lock_neighbor(lh, node, PARENT_PTR_OFFSET, mode, ++ ZNODE_LOCK_HIPRI, flags, 1); ++ read_unlock_tree(znode_get_tree(node)); ++ return result; ++} ++ ++/* wrapper function to lock right or left neighbor depending on GN_GO_LEFT ++ bit in @flags parameter */ ++/* Audited by: umka (2002.06.14) */ ++static inline int ++lock_side_neighbor(lock_handle * result, ++ znode * node, znode_lock_mode mode, int flags, int rlocked) ++{ ++ int ret; ++ int ptr_offset; ++ znode_lock_request req; ++ ++ if (flags & GN_GO_LEFT) { ++ ptr_offset = LEFT_PTR_OFFSET; ++ req = ZNODE_LOCK_LOPRI; ++ } else { ++ ptr_offset = RIGHT_PTR_OFFSET; ++ req = ZNODE_LOCK_HIPRI; ++ } ++ ++ ret = ++ lock_neighbor(result, node, ptr_offset, mode, req, flags, rlocked); ++ ++ if (ret == -E_NO_NEIGHBOR) /* if we walk left or right -E_NO_NEIGHBOR does not ++ * guarantee that neighbor is absent in the ++ * tree; in this case we return -ENOENT -- ++ * means neighbor at least not found in ++ * cache */ ++ return RETERR(-ENOENT); ++ ++ return ret; ++} ++ ++#if REISER4_DEBUG ++ ++int check_sibling_list(znode * node) ++{ ++ znode *scan; ++ znode *next; ++ ++ assert("nikita-3283", LOCK_CNT_GTZ(write_locked_tree)); ++ ++ if (node == NULL) ++ return 1; ++ ++ if (ZF_ISSET(node, JNODE_RIP)) ++ return 1; ++ ++ assert("nikita-3270", node != NULL); ++ assert_rw_write_locked(&(znode_get_tree(node)->tree_lock)); ++ ++ for (scan = node; znode_is_left_connected(scan); scan = next) { ++ next = scan->left; ++ if (next != NULL && !ZF_ISSET(next, JNODE_RIP)) { ++ assert("nikita-3271", znode_is_right_connected(next)); ++ assert("nikita-3272", next->right == scan); ++ } else ++ break; ++ } ++ for (scan = node; znode_is_right_connected(scan); scan = next) { ++ next = scan->right; ++ if (next != NULL && !ZF_ISSET(next, JNODE_RIP)) { ++ assert("nikita-3273", znode_is_left_connected(next)); ++ assert("nikita-3274", next->left == scan); ++ } else ++ break; ++ } ++ return 1; ++} ++ ++#endif ++ ++/* Znode sibling pointers maintenence. */ ++ ++/* Znode sibling pointers are established between any neighbored nodes which are ++ in cache. There are two znode state bits (JNODE_LEFT_CONNECTED, ++ JNODE_RIGHT_CONNECTED), if left or right sibling pointer contains actual ++ value (even NULL), corresponded JNODE_*_CONNECTED bit is set. ++ ++ Reiser4 tree operations which may allocate new znodes (CBK, tree balancing) ++ take care about searching (hash table lookup may be required) of znode ++ neighbors, establishing sibling pointers between them and setting ++ JNODE_*_CONNECTED state bits. */ ++ ++/* adjusting of sibling pointers and `connected' states for two ++ neighbors; works if one neighbor is NULL (was not found). */ ++ ++/* FIXME-VS: this is unstatic-ed to use in tree.c in prepare_twig_cut */ ++void link_left_and_right(znode * left, znode * right) ++{ ++ assert("nikita-3275", check_sibling_list(left)); ++ assert("nikita-3275", check_sibling_list(right)); ++ ++ if (left != NULL) { ++ if (left->right == NULL) { ++ left->right = right; ++ ZF_SET(left, JNODE_RIGHT_CONNECTED); ++ ++ ON_DEBUG(left->right_version = ++ atomic_inc_return(&delim_key_version); ++ ); ++ ++ } else if (ZF_ISSET(left->right, JNODE_HEARD_BANSHEE) ++ && left->right != right) { ++ ++ ON_DEBUG(left->right->left_version = ++ atomic_inc_return(&delim_key_version); ++ left->right_version = ++ atomic_inc_return(&delim_key_version);); ++ ++ left->right->left = NULL; ++ left->right = right; ++ ZF_SET(left, JNODE_RIGHT_CONNECTED); ++ } else ++ /* ++ * there is a race condition in renew_sibling_link() ++ * and assertions below check that it is only one ++ * there. Thread T1 calls renew_sibling_link() without ++ * GN_NO_ALLOC flag. zlook() doesn't find neighbor ++ * node, but before T1 gets to the ++ * link_left_and_right(), another thread T2 creates ++ * neighbor node and connects it. check for ++ * left->right == NULL above protects T1 from ++ * overwriting correct left->right pointer installed ++ * by T2. ++ */ ++ assert("nikita-3302", ++ right == NULL || left->right == right); ++ } ++ if (right != NULL) { ++ if (right->left == NULL) { ++ right->left = left; ++ ZF_SET(right, JNODE_LEFT_CONNECTED); ++ ++ ON_DEBUG(right->left_version = ++ atomic_inc_return(&delim_key_version); ++ ); ++ ++ } else if (ZF_ISSET(right->left, JNODE_HEARD_BANSHEE) ++ && right->left != left) { ++ ++ ON_DEBUG(right->left->right_version = ++ atomic_inc_return(&delim_key_version); ++ right->left_version = ++ atomic_inc_return(&delim_key_version);); ++ ++ right->left->right = NULL; ++ right->left = left; ++ ZF_SET(right, JNODE_LEFT_CONNECTED); ++ ++ } else ++ assert("nikita-3303", ++ left == NULL || right->left == left); ++ } ++ assert("nikita-3275", check_sibling_list(left)); ++ assert("nikita-3275", check_sibling_list(right)); ++} ++ ++/* Audited by: umka (2002.06.14) */ ++static void link_znodes(znode * first, znode * second, int to_left) ++{ ++ if (to_left) ++ link_left_and_right(second, first); ++ else ++ link_left_and_right(first, second); ++} ++ ++/* getting of next (to left or to right, depend on gn_to_left bit in flags) ++ coord's unit position in horizontal direction, even across node ++ boundary. Should be called under tree lock, it protects nonexistence of ++ sibling link on parent level, if lock_side_neighbor() fails with ++ -ENOENT. */ ++static int far_next_coord(coord_t * coord, lock_handle * handle, int flags) ++{ ++ int ret; ++ znode *node; ++ reiser4_tree *tree; ++ ++ assert("umka-243", coord != NULL); ++ assert("umka-244", handle != NULL); ++ assert("zam-1069", handle->node == NULL); ++ ++ ret = ++ (flags & GN_GO_LEFT) ? coord_prev_unit(coord) : ++ coord_next_unit(coord); ++ if (!ret) ++ return 0; ++ ++ ret = ++ lock_side_neighbor(handle, coord->node, ZNODE_READ_LOCK, flags, 0); ++ if (ret) ++ return ret; ++ ++ node = handle->node; ++ tree = znode_get_tree(node); ++ write_unlock_tree(tree); ++ ++ coord_init_zero(coord); ++ ++ /* We avoid synchronous read here if it is specified by flag. */ ++ if ((flags & GN_ASYNC) && znode_page(handle->node) == NULL) { ++ ret = jstartio(ZJNODE(handle->node)); ++ if (!ret) ++ ret = -E_REPEAT; ++ goto error_locked; ++ } ++ ++ /* corresponded zrelse() should be called by the clients of ++ far_next_coord(), in place when this node gets unlocked. */ ++ ret = zload(handle->node); ++ if (ret) ++ goto error_locked; ++ ++ if (flags & GN_GO_LEFT) ++ coord_init_last_unit(coord, node); ++ else ++ coord_init_first_unit(coord, node); ++ ++ if (0) { ++ error_locked: ++ longterm_unlock_znode(handle); ++ } ++ write_lock_tree(tree); ++ return ret; ++} ++ ++/* Very significant function which performs a step in horizontal direction ++ when sibling pointer is not available. Actually, it is only function which ++ does it. ++ Note: this function does not restore locking status at exit, ++ caller should does care about proper unlocking and zrelsing */ ++static int ++renew_sibling_link(coord_t * coord, lock_handle * handle, znode * child, ++ tree_level level, int flags, int *nr_locked) ++{ ++ int ret; ++ int to_left = flags & GN_GO_LEFT; ++ reiser4_block_nr da; ++ /* parent of the neighbor node; we set it to parent until not sharing ++ of one parent between child and neighbor node is detected */ ++ znode *side_parent = coord->node; ++ reiser4_tree *tree = znode_get_tree(child); ++ znode *neighbor = NULL; ++ ++ assert("umka-245", coord != NULL); ++ assert("umka-246", handle != NULL); ++ assert("umka-247", child != NULL); ++ assert("umka-303", tree != NULL); ++ ++ init_lh(handle); ++ write_lock_tree(tree); ++ ret = far_next_coord(coord, handle, flags); ++ ++ if (ret) { ++ if (ret != -ENOENT) { ++ write_unlock_tree(tree); ++ return ret; ++ } ++ } else { ++ item_plugin *iplug; ++ ++ if (handle->node != NULL) { ++ (*nr_locked)++; ++ side_parent = handle->node; ++ } ++ ++ /* does coord object points to internal item? We do not ++ support sibling pointers between znode for formatted and ++ unformatted nodes and return -E_NO_NEIGHBOR in that case. */ ++ iplug = item_plugin_by_coord(coord); ++ if (!item_is_internal(coord)) { ++ link_znodes(child, NULL, to_left); ++ write_unlock_tree(tree); ++ /* we know there can't be formatted neighbor */ ++ return RETERR(-E_NO_NEIGHBOR); ++ } ++ write_unlock_tree(tree); ++ ++ iplug->s.internal.down_link(coord, NULL, &da); ++ ++ if (flags & GN_NO_ALLOC) { ++ neighbor = zlook(tree, &da); ++ } else { ++ neighbor = ++ zget(tree, &da, side_parent, level, ++ reiser4_ctx_gfp_mask_get()); ++ } ++ ++ if (IS_ERR(neighbor)) { ++ ret = PTR_ERR(neighbor); ++ return ret; ++ } ++ ++ if (neighbor) ++ /* update delimiting keys */ ++ set_child_delimiting_keys(coord->node, coord, neighbor); ++ ++ write_lock_tree(tree); ++ } ++ ++ if (likely(neighbor == NULL || ++ (znode_get_level(child) == znode_get_level(neighbor) ++ && child != neighbor))) ++ link_znodes(child, neighbor, to_left); ++ else { ++ warning("nikita-3532", ++ "Sibling nodes on the different levels: %i != %i\n", ++ znode_get_level(child), znode_get_level(neighbor)); ++ ret = RETERR(-EIO); ++ } ++ ++ write_unlock_tree(tree); ++ ++ /* if GN_NO_ALLOC isn't set we keep reference to neighbor znode */ ++ if (neighbor != NULL && (flags & GN_NO_ALLOC)) ++ /* atomic_dec(&ZJNODE(neighbor)->x_count); */ ++ zput(neighbor); ++ ++ return ret; ++} ++ ++/* This function is for establishing of one side relation. */ ++/* Audited by: umka (2002.06.14) */ ++static int connect_one_side(coord_t * coord, znode * node, int flags) ++{ ++ coord_t local; ++ lock_handle handle; ++ int nr_locked; ++ int ret; ++ ++ assert("umka-248", coord != NULL); ++ assert("umka-249", node != NULL); ++ ++ coord_dup_nocheck(&local, coord); ++ ++ init_lh(&handle); ++ ++ ret = ++ renew_sibling_link(&local, &handle, node, znode_get_level(node), ++ flags | GN_NO_ALLOC, &nr_locked); ++ ++ if (handle.node != NULL) { ++ /* complementary operations for zload() and lock() in far_next_coord() */ ++ zrelse(handle.node); ++ longterm_unlock_znode(&handle); ++ } ++ ++ /* we catch error codes which are not interesting for us because we ++ run renew_sibling_link() only for znode connection. */ ++ if (ret == -ENOENT || ret == -E_NO_NEIGHBOR) ++ return 0; ++ ++ return ret; ++} ++ ++/* if @child is not in `connected' state, performs hash searches for left and ++ right neighbor nodes and establishes horizontal sibling links */ ++/* Audited by: umka (2002.06.14), umka (2002.06.15) */ ++int connect_znode(coord_t * parent_coord, znode * child) ++{ ++ reiser4_tree *tree = znode_get_tree(child); ++ int ret = 0; ++ ++ assert("zam-330", parent_coord != NULL); ++ assert("zam-331", child != NULL); ++ assert("zam-332", parent_coord->node != NULL); ++ assert("umka-305", tree != NULL); ++ ++ /* it is trivial to `connect' root znode because it can't have ++ neighbors */ ++ if (znode_above_root(parent_coord->node)) { ++ child->left = NULL; ++ child->right = NULL; ++ ZF_SET(child, JNODE_LEFT_CONNECTED); ++ ZF_SET(child, JNODE_RIGHT_CONNECTED); ++ ++ ON_DEBUG(child->left_version = ++ atomic_inc_return(&delim_key_version); ++ child->right_version = ++ atomic_inc_return(&delim_key_version);); ++ ++ return 0; ++ } ++ ++ /* load parent node */ ++ coord_clear_iplug(parent_coord); ++ ret = zload(parent_coord->node); ++ ++ if (ret != 0) ++ return ret; ++ ++ /* protect `connected' state check by tree_lock */ ++ read_lock_tree(tree); ++ ++ if (!znode_is_right_connected(child)) { ++ read_unlock_tree(tree); ++ /* connect right (default is right) */ ++ ret = connect_one_side(parent_coord, child, GN_NO_ALLOC); ++ if (ret) ++ goto zrelse_and_ret; ++ ++ read_lock_tree(tree); ++ } ++ ++ ret = znode_is_left_connected(child); ++ ++ read_unlock_tree(tree); ++ ++ if (!ret) { ++ ret = ++ connect_one_side(parent_coord, child, ++ GN_NO_ALLOC | GN_GO_LEFT); ++ } else ++ ret = 0; ++ ++ zrelse_and_ret: ++ zrelse(parent_coord->node); ++ ++ return ret; ++} ++ ++/* this function is like renew_sibling_link() but allocates neighbor node if ++ it doesn't exist and `connects' it. It may require making two steps in ++ horizontal direction, first one for neighbor node finding/allocation, ++ second one is for finding neighbor of neighbor to connect freshly allocated ++ znode. */ ++/* Audited by: umka (2002.06.14), umka (2002.06.15) */ ++static int ++renew_neighbor(coord_t * coord, znode * node, tree_level level, int flags) ++{ ++ coord_t local; ++ lock_handle empty[2]; ++ reiser4_tree *tree = znode_get_tree(node); ++ znode *neighbor = NULL; ++ int nr_locked = 0; ++ int ret; ++ ++ assert("umka-250", coord != NULL); ++ assert("umka-251", node != NULL); ++ assert("umka-307", tree != NULL); ++ assert("umka-308", level <= tree->height); ++ ++ /* umka (2002.06.14) ++ Here probably should be a check for given "level" validness. ++ Something like assert("xxx-yyy", level < REAL_MAX_ZTREE_HEIGHT); ++ */ ++ ++ coord_dup(&local, coord); ++ ++ ret = ++ renew_sibling_link(&local, &empty[0], node, level, ++ flags & ~GN_NO_ALLOC, &nr_locked); ++ if (ret) ++ goto out; ++ ++ /* tree lock is not needed here because we keep parent node(s) locked ++ and reference to neighbor znode incremented */ ++ neighbor = (flags & GN_GO_LEFT) ? node->left : node->right; ++ ++ read_lock_tree(tree); ++ ret = znode_is_connected(neighbor); ++ read_unlock_tree(tree); ++ if (ret) { ++ ret = 0; ++ goto out; ++ } ++ ++ ret = ++ renew_sibling_link(&local, &empty[nr_locked], neighbor, level, ++ flags | GN_NO_ALLOC, &nr_locked); ++ /* second renew_sibling_link() call is used for znode connection only, ++ so we can live with these errors */ ++ if (-ENOENT == ret || -E_NO_NEIGHBOR == ret) ++ ret = 0; ++ ++ out: ++ ++ for (--nr_locked; nr_locked >= 0; --nr_locked) { ++ zrelse(empty[nr_locked].node); ++ longterm_unlock_znode(&empty[nr_locked]); ++ } ++ ++ if (neighbor != NULL) ++ /* decrement znode reference counter without actually ++ releasing it. */ ++ atomic_dec(&ZJNODE(neighbor)->x_count); ++ ++ return ret; ++} ++ ++/* ++ reiser4_get_neighbor() -- lock node's neighbor. ++ ++ reiser4_get_neighbor() locks node's neighbor (left or right one, depends on ++ given parameter) using sibling link to it. If sibling link is not available ++ (i.e. neighbor znode is not in cache) and flags allow read blocks, we go one ++ level up for information about neighbor's disk address. We lock node's ++ parent, if it is common parent for both 'node' and its neighbor, neighbor's ++ disk address is in next (to left or to right) down link from link that points ++ to original node. If not, we need to lock parent's neighbor, read its content ++ and take first(last) downlink with neighbor's disk address. That locking ++ could be done by using sibling link and lock_neighbor() function, if sibling ++ link exists. In another case we have to go level up again until we find ++ common parent or valid sibling link. Then go down ++ allocating/connecting/locking/reading nodes until neighbor of first one is ++ locked. ++ ++ @neighbor: result lock handle, ++ @node: a node which we lock neighbor of, ++ @lock_mode: lock mode {LM_READ, LM_WRITE}, ++ @flags: logical OR of {GN_*} (see description above) subset. ++ ++ @return: 0 if success, negative value if lock was impossible due to an error ++ or lack of neighbor node. ++*/ ++ ++/* Audited by: umka (2002.06.14), umka (2002.06.15) */ ++int ++reiser4_get_neighbor(lock_handle * neighbor, znode * node, ++ znode_lock_mode lock_mode, int flags) ++{ ++ reiser4_tree *tree = znode_get_tree(node); ++ lock_handle path[REAL_MAX_ZTREE_HEIGHT]; ++ ++ coord_t coord; ++ ++ tree_level base_level; ++ tree_level h = 0; ++ int ret; ++ ++ assert("umka-252", tree != NULL); ++ assert("umka-253", neighbor != NULL); ++ assert("umka-254", node != NULL); ++ ++ base_level = znode_get_level(node); ++ ++ assert("umka-310", base_level <= tree->height); ++ ++ coord_init_zero(&coord); ++ ++ again: ++ /* first, we try to use simple lock_neighbor() which requires sibling ++ link existence */ ++ read_lock_tree(tree); ++ ret = lock_side_neighbor(neighbor, node, lock_mode, flags, 1); ++ read_unlock_tree(tree); ++ if (!ret) { ++ /* load znode content if it was specified */ ++ if (flags & GN_LOAD_NEIGHBOR) { ++ ret = zload(node); ++ if (ret) ++ longterm_unlock_znode(neighbor); ++ } ++ return ret; ++ } ++ ++ /* only -ENOENT means we may look upward and try to connect ++ @node with its neighbor (if @flags allow us to do it) */ ++ if (ret != -ENOENT || !(flags & GN_CAN_USE_UPPER_LEVELS)) ++ return ret; ++ ++ /* before establishing of sibling link we lock parent node; it is ++ required by renew_neighbor() to work. */ ++ init_lh(&path[0]); ++ ret = reiser4_get_parent(&path[0], node, ZNODE_READ_LOCK); ++ if (ret) ++ return ret; ++ if (znode_above_root(path[0].node)) { ++ longterm_unlock_znode(&path[0]); ++ return RETERR(-E_NO_NEIGHBOR); ++ } ++ ++ while (1) { ++ znode *child = (h == 0) ? node : path[h - 1].node; ++ znode *parent = path[h].node; ++ ++ ret = zload(parent); ++ if (ret) ++ break; ++ ++ ret = find_child_ptr(parent, child, &coord); ++ ++ if (ret) { ++ zrelse(parent); ++ break; ++ } ++ ++ /* try to establish missing sibling link */ ++ ret = renew_neighbor(&coord, child, h + base_level, flags); ++ ++ zrelse(parent); ++ ++ switch (ret) { ++ case 0: ++ /* unlocking of parent znode prevents simple ++ deadlock situation */ ++ done_lh(&path[h]); ++ ++ /* depend on tree level we stay on we repeat first ++ locking attempt ... */ ++ if (h == 0) ++ goto again; ++ ++ /* ... or repeat establishing of sibling link at ++ one level below. */ ++ --h; ++ break; ++ ++ case -ENOENT: ++ /* sibling link is not available -- we go ++ upward. */ ++ init_lh(&path[h + 1]); ++ ret = ++ reiser4_get_parent(&path[h + 1], parent, ++ ZNODE_READ_LOCK); ++ if (ret) ++ goto fail; ++ ++h; ++ if (znode_above_root(path[h].node)) { ++ ret = RETERR(-E_NO_NEIGHBOR); ++ goto fail; ++ } ++ break; ++ ++ case -E_DEADLOCK: ++ /* there was lock request from hi-pri locker. if ++ it is possible we unlock last parent node and ++ re-lock it again. */ ++ for (; reiser4_check_deadlock(); h--) { ++ done_lh(&path[h]); ++ if (h == 0) ++ goto fail; ++ } ++ ++ break; ++ ++ default: /* other errors. */ ++ goto fail; ++ } ++ } ++ fail: ++ ON_DEBUG(check_lock_node_data(node)); ++ ON_DEBUG(check_lock_data()); ++ ++ /* unlock path */ ++ do { ++ /* FIXME-Zam: when we get here from case -E_DEADLOCK's goto ++ fail; path[0] is already done_lh-ed, therefore ++ longterm_unlock_znode(&path[h]); is not applicable */ ++ done_lh(&path[h]); ++ --h; ++ } while (h + 1 != 0); ++ ++ return ret; ++} ++ ++/* remove node from sibling list */ ++/* Audited by: umka (2002.06.14) */ ++void sibling_list_remove(znode * node) ++{ ++ reiser4_tree *tree; ++ ++ tree = znode_get_tree(node); ++ assert("umka-255", node != NULL); ++ assert_rw_write_locked(&(tree->tree_lock)); ++ assert("nikita-3275", check_sibling_list(node)); ++ ++ write_lock_dk(tree); ++ if (znode_is_right_connected(node) && node->right != NULL && ++ znode_is_left_connected(node) && node->left != NULL) { ++ assert("zam-32245", ++ keyeq(znode_get_rd_key(node), ++ znode_get_ld_key(node->right))); ++ znode_set_rd_key(node->left, znode_get_ld_key(node->right)); ++ } ++ write_unlock_dk(tree); ++ ++ if (znode_is_right_connected(node) && node->right != NULL) { ++ assert("zam-322", znode_is_left_connected(node->right)); ++ node->right->left = node->left; ++ ON_DEBUG(node->right->left_version = ++ atomic_inc_return(&delim_key_version); ++ ); ++ } ++ if (znode_is_left_connected(node) && node->left != NULL) { ++ assert("zam-323", znode_is_right_connected(node->left)); ++ node->left->right = node->right; ++ ON_DEBUG(node->left->right_version = ++ atomic_inc_return(&delim_key_version); ++ ); ++ } ++ ++ ZF_CLR(node, JNODE_LEFT_CONNECTED); ++ ZF_CLR(node, JNODE_RIGHT_CONNECTED); ++ ON_DEBUG(node->left = node->right = NULL; ++ node->left_version = atomic_inc_return(&delim_key_version); ++ node->right_version = atomic_inc_return(&delim_key_version);); ++ assert("nikita-3276", check_sibling_list(node)); ++} ++ ++/* disconnect node from sibling list */ ++void sibling_list_drop(znode * node) ++{ ++ znode *right; ++ znode *left; ++ ++ assert("nikita-2464", node != NULL); ++ assert("nikita-3277", check_sibling_list(node)); ++ ++ right = node->right; ++ if (right != NULL) { ++ assert("nikita-2465", znode_is_left_connected(right)); ++ right->left = NULL; ++ ON_DEBUG(right->left_version = ++ atomic_inc_return(&delim_key_version); ++ ); ++ } ++ left = node->left; ++ if (left != NULL) { ++ assert("zam-323", znode_is_right_connected(left)); ++ left->right = NULL; ++ ON_DEBUG(left->right_version = ++ atomic_inc_return(&delim_key_version); ++ ); ++ } ++ ZF_CLR(node, JNODE_LEFT_CONNECTED); ++ ZF_CLR(node, JNODE_RIGHT_CONNECTED); ++ ON_DEBUG(node->left = node->right = NULL; ++ node->left_version = atomic_inc_return(&delim_key_version); ++ node->right_version = atomic_inc_return(&delim_key_version);); ++} ++ ++/* Insert new node into sibling list. Regular balancing inserts new node ++ after (at right side) existing and locked node (@before), except one case ++ of adding new tree root node. @before should be NULL in that case. */ ++void sibling_list_insert_nolock(znode * new, znode * before) ++{ ++ assert("zam-334", new != NULL); ++ assert("nikita-3298", !znode_is_left_connected(new)); ++ assert("nikita-3299", !znode_is_right_connected(new)); ++ assert("nikita-3300", new->left == NULL); ++ assert("nikita-3301", new->right == NULL); ++ assert("nikita-3278", check_sibling_list(new)); ++ assert("nikita-3279", check_sibling_list(before)); ++ ++ if (before != NULL) { ++ assert("zam-333", znode_is_connected(before)); ++ new->right = before->right; ++ new->left = before; ++ ON_DEBUG(new->right_version = ++ atomic_inc_return(&delim_key_version); ++ new->left_version = ++ atomic_inc_return(&delim_key_version);); ++ if (before->right != NULL) { ++ before->right->left = new; ++ ON_DEBUG(before->right->left_version = ++ atomic_inc_return(&delim_key_version); ++ ); ++ } ++ before->right = new; ++ ON_DEBUG(before->right_version = ++ atomic_inc_return(&delim_key_version); ++ ); ++ } else { ++ new->right = NULL; ++ new->left = NULL; ++ ON_DEBUG(new->right_version = ++ atomic_inc_return(&delim_key_version); ++ new->left_version = ++ atomic_inc_return(&delim_key_version);); ++ } ++ ZF_SET(new, JNODE_LEFT_CONNECTED); ++ ZF_SET(new, JNODE_RIGHT_CONNECTED); ++ assert("nikita-3280", check_sibling_list(new)); ++ assert("nikita-3281", check_sibling_list(before)); ++} ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/tree_walk.h linux-2.6.30/fs/reiser4/tree_walk.h +--- linux-2.6.30.orig/fs/reiser4/tree_walk.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/tree_walk.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,125 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* definitions of reiser4 tree walk functions */ ++ ++#ifndef __FS_REISER4_TREE_WALK_H__ ++#define __FS_REISER4_TREE_WALK_H__ ++ ++#include "debug.h" ++#include "forward.h" ++ ++/* establishes horizontal links between cached znodes */ ++int connect_znode(coord_t * coord, znode * node); ++ ++/* tree traversal functions (reiser4_get_parent(), reiser4_get_neighbor()) ++ have the following common arguments: ++ ++ return codes: ++ ++ @return : 0 - OK, ++ ++ZAM-FIXME-HANS: wrong return code name. Change them all. ++ -ENOENT - neighbor is not in cache, what is detected by sibling ++ link absence. ++ ++ -E_NO_NEIGHBOR - we are sure that neighbor (or parent) node cannot be ++ found (because we are left-/right- most node of the ++ tree, for example). Also, this return code is for ++ reiser4_get_parent() when we see no parent link -- it ++ means that our node is root node. ++ ++ -E_DEADLOCK - deadlock detected (request from high-priority process ++ received), other error codes are conformed to ++ /usr/include/asm/errno.h . ++*/ ++ ++int ++reiser4_get_parent_flags(lock_handle * result, znode * node, ++ znode_lock_mode mode, int flags); ++ ++/* bits definition for reiser4_get_neighbor function `flags' arg. */ ++typedef enum { ++ /* If sibling pointer is NULL, this flag allows get_neighbor() to try to ++ * find not allocated not connected neigbor by going though upper ++ * levels */ ++ GN_CAN_USE_UPPER_LEVELS = 0x1, ++ /* locking left neighbor instead of right one */ ++ GN_GO_LEFT = 0x2, ++ /* automatically load neighbor node content */ ++ GN_LOAD_NEIGHBOR = 0x4, ++ /* return -E_REPEAT if can't lock */ ++ GN_TRY_LOCK = 0x8, ++ /* used internally in tree_walk.c, causes renew_sibling to not ++ allocate neighbor znode, but only search for it in znode cache */ ++ GN_NO_ALLOC = 0x10, ++ /* do not go across atom boundaries */ ++ GN_SAME_ATOM = 0x20, ++ /* allow to lock not connected nodes */ ++ GN_ALLOW_NOT_CONNECTED = 0x40, ++ /* Avoid synchronous jload, instead, call jstartio() and return -E_REPEAT. */ ++ GN_ASYNC = 0x80 ++} znode_get_neigbor_flags; ++ ++/* A commonly used wrapper for reiser4_get_parent_flags(). */ ++static inline int reiser4_get_parent(lock_handle * result, znode * node, ++ znode_lock_mode mode) ++{ ++ return reiser4_get_parent_flags(result, node, mode, ++ GN_ALLOW_NOT_CONNECTED); ++} ++ ++int reiser4_get_neighbor(lock_handle * neighbor, znode * node, ++ znode_lock_mode lock_mode, int flags); ++ ++/* there are wrappers for most common usages of reiser4_get_neighbor() */ ++static inline int ++reiser4_get_left_neighbor(lock_handle * result, znode * node, int lock_mode, ++ int flags) ++{ ++ return reiser4_get_neighbor(result, node, lock_mode, ++ flags | GN_GO_LEFT); ++} ++ ++static inline int ++reiser4_get_right_neighbor(lock_handle * result, znode * node, int lock_mode, ++ int flags) ++{ ++ ON_DEBUG(check_lock_node_data(node)); ++ ON_DEBUG(check_lock_data()); ++ return reiser4_get_neighbor(result, node, lock_mode, ++ flags & (~GN_GO_LEFT)); ++} ++ ++extern void sibling_list_remove(znode * node); ++extern void sibling_list_drop(znode * node); ++extern void sibling_list_insert_nolock(znode * new, znode * before); ++extern void link_left_and_right(znode * left, znode * right); ++ ++/* Functions called by tree_walk() when tree_walk() ... */ ++struct tree_walk_actor { ++ /* ... meets a formatted node, */ ++ int (*process_znode) (tap_t *, void *); ++ /* ... meets an extent, */ ++ int (*process_extent) (tap_t *, void *); ++ /* ... begins tree traversal or repeats it after -E_REPEAT was returned by ++ * node or extent processing functions. */ ++ int (*before) (void *); ++}; ++ ++#if REISER4_DEBUG ++int check_sibling_list(znode * node); ++#else ++#define check_sibling_list(n) (1) ++#endif ++ ++#endif /* __FS_REISER4_TREE_WALK_H__ */ ++ ++/* ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/txnmgr.c linux-2.6.30/fs/reiser4/txnmgr.c +--- linux-2.6.30.orig/fs/reiser4/txnmgr.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/txnmgr.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,3164 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Joshua MacDonald wrote the first draft of this code. */ ++ ++/* ZAM-LONGTERM-FIXME-HANS: The locking in this file is badly designed, and a ++filesystem scales only as well as its worst locking design. You need to ++substantially restructure this code. Josh was not as experienced a programmer ++as you. Particularly review how the locking style differs from what you did ++for znodes usingt hi-lo priority locking, and present to me an opinion on ++whether the differences are well founded. */ ++ ++/* I cannot help but to disagree with the sentiment above. Locking of ++ * transaction manager is _not_ badly designed, and, at the very least, is not ++ * the scaling bottleneck. Scaling bottleneck is _exactly_ hi-lo priority ++ * locking on znodes, especially on the root node of the tree. --nikita, ++ * 2003.10.13 */ ++ ++/* The txnmgr is a set of interfaces that keep track of atoms and transcrash handles. The ++ txnmgr processes capture_block requests and manages the relationship between jnodes and ++ atoms through the various stages of a transcrash, and it also oversees the fusion and ++ capture-on-copy processes. The main difficulty with this task is maintaining a ++ deadlock-free lock ordering between atoms and jnodes/handles. The reason for the ++ difficulty is that jnodes, handles, and atoms contain pointer circles, and the cycle ++ must be broken. The main requirement is that atom-fusion be deadlock free, so once you ++ hold the atom_lock you may then wait to acquire any jnode or handle lock. This implies ++ that any time you check the atom-pointer of a jnode or handle and then try to lock that ++ atom, you must use trylock() and possibly reverse the order. ++ ++ This code implements the design documented at: ++ ++ http://namesys.com/txn-doc.html ++ ++ZAM-FIXME-HANS: update v4.html to contain all of the information present in the above (but updated), and then remove the ++above document and reference the new. Be sure to provide some credit to Josh. I already have some writings on this ++topic in v4.html, but they are lacking in details present in the above. Cure that. Remember to write for the bright 12 ++year old --- define all technical terms used. ++ ++*/ ++ ++/* Thoughts on the external transaction interface: ++ ++ In the current code, a TRANSCRASH handle is created implicitly by reiser4_init_context() (which ++ creates state that lasts for the duration of a system call and is called at the start ++ of ReiserFS methods implementing VFS operations), and closed by reiser4_exit_context(), ++ occupying the scope of a single system call. We wish to give certain applications an ++ interface to begin and close (commit) transactions. Since our implementation of ++ transactions does not yet support isolation, allowing an application to open a ++ transaction implies trusting it to later close the transaction. Part of the ++ transaction interface will be aimed at enabling that trust, but the interface for ++ actually using transactions is fairly narrow. ++ ++ BEGIN_TRANSCRASH: Returns a transcrash identifier. It should be possible to translate ++ this identifier into a string that a shell-script could use, allowing you to start a ++ transaction by issuing a command. Once open, the transcrash should be set in the task ++ structure, and there should be options (I suppose) to allow it to be carried across ++ fork/exec. A transcrash has several options: ++ ++ - READ_FUSING or WRITE_FUSING: The default policy is for txn-capture to capture only ++ on writes (WRITE_FUSING) and allow "dirty reads". If the application wishes to ++ capture on reads as well, it should set READ_FUSING. ++ ++ - TIMEOUT: Since a non-isolated transcrash cannot be undone, every transcrash must ++ eventually close (or else the machine must crash). If the application dies an ++ unexpected death with an open transcrash, for example, or if it hangs for a long ++ duration, one solution (to avoid crashing the machine) is to simply close it anyway. ++ This is a dangerous option, but it is one way to solve the problem until isolated ++ transcrashes are available for untrusted applications. ++ ++ It seems to be what databases do, though it is unclear how one avoids a DoS attack ++ creating a vulnerability based on resource starvation. Guaranteeing that some ++ minimum amount of computational resources are made available would seem more correct ++ than guaranteeing some amount of time. When we again have someone to code the work, ++ this issue should be considered carefully. -Hans ++ ++ RESERVE_BLOCKS: A running transcrash should indicate to the transaction manager how ++ many dirty blocks it expects. The reserve_blocks interface should be called at a point ++ where it is safe for the application to fail, because the system may not be able to ++ grant the allocation and the application must be able to back-out. For this reason, ++ the number of reserve-blocks can also be passed as an argument to BEGIN_TRANSCRASH, but ++ the application may also wish to extend the allocation after beginning its transcrash. ++ ++ CLOSE_TRANSCRASH: The application closes the transcrash when it is finished making ++ modifications that require transaction protection. When isolated transactions are ++ supported the CLOSE operation is replaced by either COMMIT or ABORT. For example, if a ++ RESERVE_BLOCKS call fails for the application, it should "abort" by calling ++ CLOSE_TRANSCRASH, even though it really commits any changes that were made (which is ++ why, for safety, the application should call RESERVE_BLOCKS before making any changes). ++ ++ For actually implementing these out-of-system-call-scopped transcrashes, the ++ reiser4_context has a "txn_handle *trans" pointer that may be set to an open ++ transcrash. Currently there are no dynamically-allocated transcrashes, but there is a ++ "struct kmem_cache *_txnh_slab" created for that purpose in this file. ++*/ ++ ++/* Extending the other system call interfaces for future transaction features: ++ ++ Specialized applications may benefit from passing flags to the ordinary system call ++ interface such as read(), write(), or stat(). For example, the application specifies ++ WRITE_FUSING by default but wishes to add that a certain read() command should be ++ treated as READ_FUSING. But which read? Is it the directory-entry read, the stat-data ++ read, or the file-data read? These issues are straight-forward, but there are a lot of ++ them and adding the necessary flags-passing code will be tedious. ++ ++ When supporting isolated transactions, there is a corresponding READ_MODIFY_WRITE (RMW) ++ flag, which specifies that although it is a read operation being requested, a ++ write-lock should be taken. The reason is that read-locks are shared while write-locks ++ are exclusive, so taking a read-lock when a later-write is known in advance will often ++ leads to deadlock. If a reader knows it will write later, it should issue read ++ requests with the RMW flag set. ++*/ ++ ++/* ++ The znode/atom deadlock avoidance. ++ ++ FIXME(Zam): writing of this comment is in progress. ++ ++ The atom's special stage ASTAGE_CAPTURE_WAIT introduces a kind of atom's ++ long-term locking, which makes reiser4 locking scheme more complex. It had ++ deadlocks until we implement deadlock avoidance algorithms. That deadlocks ++ looked as the following: one stopped thread waits for a long-term lock on ++ znode, the thread who owns that lock waits when fusion with another atom will ++ be allowed. ++ ++ The source of the deadlocks is an optimization of not capturing index nodes ++ for read. Let's prove it. Suppose we have dumb node capturing scheme which ++ unconditionally captures each block before locking it. ++ ++ That scheme has no deadlocks. Let's begin with the thread which stage is ++ ASTAGE_CAPTURE_WAIT and it waits for a znode lock. The thread can't wait for ++ a capture because it's stage allows fusion with any atom except which are ++ being committed currently. A process of atom commit can't deadlock because ++ atom commit procedure does not acquire locks and does not fuse with other ++ atoms. Reiser4 does capturing right before going to sleep inside the ++ longtertm_lock_znode() function, it means the znode which we want to lock is ++ already captured and its atom is in ASTAGE_CAPTURE_WAIT stage. If we ++ continue the analysis we understand that no one process in the sequence may ++ waits atom fusion. Thereby there are no deadlocks of described kind. ++ ++ The capturing optimization makes the deadlocks possible. A thread can wait a ++ lock which owner did not captured that node. The lock owner's current atom ++ is not fused with the first atom and it does not get a ASTAGE_CAPTURE_WAIT ++ state. A deadlock is possible when that atom meets another one which is in ++ ASTAGE_CAPTURE_WAIT already. ++ ++ The deadlock avoidance scheme includes two algorithms: ++ ++ First algorithm is used when a thread captures a node which is locked but not ++ captured by another thread. Those nodes are marked MISSED_IN_CAPTURE at the ++ moment we skip their capturing. If such a node (marked MISSED_IN_CAPTURE) is ++ being captured by a thread with current atom is in ASTAGE_CAPTURE_WAIT, the ++ routine which forces all lock owners to join with current atom is executed. ++ ++ Second algorithm does not allow to skip capturing of already captured nodes. ++ ++ Both algorithms together prevent waiting a longterm lock without atom fusion ++ with atoms of all lock owners, which is a key thing for getting atom/znode ++ locking deadlocks. ++*/ ++ ++/* ++ * Transactions and mmap(2). ++ * ++ * 1. Transactions are not supported for accesses through mmap(2), because ++ * this would effectively amount to user-level transactions whose duration ++ * is beyond control of the kernel. ++ * ++ * 2. That said, we still want to preserve some decency with regard to ++ * mmap(2). During normal write(2) call, following sequence of events ++ * happens: ++ * ++ * 1. page is created; ++ * ++ * 2. jnode is created, dirtied and captured into current atom. ++ * ++ * 3. extent is inserted and modified. ++ * ++ * Steps (2) and (3) take place under long term lock on the twig node. ++ * ++ * When file is accessed through mmap(2) page is always created during ++ * page fault. ++ * After this (in reiser4_readpage()->reiser4_readpage_extent()): ++ * ++ * 1. if access is made to non-hole page new jnode is created, (if ++ * necessary) ++ * ++ * 2. if access is made to the hole page, jnode is not created (XXX ++ * not clear why). ++ * ++ * Also, even if page is created by write page fault it is not marked ++ * dirty immediately by handle_mm_fault(). Probably this is to avoid races ++ * with page write-out. ++ * ++ * Dirty bit installed by hardware is only transferred to the struct page ++ * later, when page is unmapped (in zap_pte_range(), or ++ * try_to_unmap_one()). ++ * ++ * So, with mmap(2) we have to handle following irksome situations: ++ * ++ * 1. there exists modified page (clean or dirty) without jnode ++ * ++ * 2. there exists modified page (clean or dirty) with clean jnode ++ * ++ * 3. clean page which is a part of atom can be transparently modified ++ * at any moment through mapping without becoming dirty. ++ * ++ * (1) and (2) can lead to the out-of-memory situation: ->writepage() ++ * doesn't know what to do with such pages and ->sync_sb()/->writepages() ++ * don't see them, because these methods operate on atoms. ++ * ++ * (3) can lead to the loss of data: suppose we have dirty page with dirty ++ * captured jnode captured by some atom. As part of early flush (for ++ * example) page was written out. Dirty bit was cleared on both page and ++ * jnode. After this page is modified through mapping, but kernel doesn't ++ * notice and just discards page and jnode as part of commit. (XXX ++ * actually it doesn't, because to reclaim page ->releasepage() has to be ++ * called and before this dirty bit will be transferred to the struct ++ * page). ++ * ++ */ ++ ++#include "debug.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree.h" ++#include "wander.h" ++#include "ktxnmgrd.h" ++#include "super.h" ++#include "page_cache.h" ++#include "reiser4.h" ++#include "vfs_ops.h" ++#include "inode.h" ++#include "flush.h" ++ ++#include <asm/atomic.h> ++#include <linux/types.h> ++#include <linux/fs.h> ++#include <linux/mm.h> ++#include <linux/slab.h> ++#include <linux/pagemap.h> ++#include <linux/writeback.h> ++#include <linux/swap.h> /* for totalram_pages */ ++ ++static void atom_free(txn_atom * atom); ++ ++static int commit_txnh(txn_handle * txnh); ++ ++static void wakeup_atom_waitfor_list(txn_atom * atom); ++static void wakeup_atom_waiting_list(txn_atom * atom); ++ ++static void capture_assign_txnh_nolock(txn_atom * atom, txn_handle * txnh); ++ ++static void capture_assign_block_nolock(txn_atom * atom, jnode * node); ++ ++static void fuse_not_fused_lock_owners(txn_handle * txnh, znode * node); ++ ++static int capture_init_fusion(jnode * node, txn_handle * txnh, ++ txn_capture mode); ++ ++static int capture_fuse_wait(txn_handle *, txn_atom *, txn_atom *, txn_capture); ++ ++static void capture_fuse_into(txn_atom * small, txn_atom * large); ++ ++void reiser4_invalidate_list(struct list_head *); ++ ++/* GENERIC STRUCTURES */ ++ ++typedef struct _txn_wait_links txn_wait_links; ++ ++struct _txn_wait_links { ++ lock_stack *_lock_stack; ++ struct list_head _fwaitfor_link; ++ struct list_head _fwaiting_link; ++ int (*waitfor_cb) (txn_atom * atom, struct _txn_wait_links * wlinks); ++ int (*waiting_cb) (txn_atom * atom, struct _txn_wait_links * wlinks); ++}; ++ ++/* FIXME: In theory, we should be using the slab cache init & destructor ++ methods instead of, e.g., jnode_init, etc. */ ++static struct kmem_cache *_atom_slab = NULL; ++/* this is for user-visible, cross system-call transactions. */ ++static struct kmem_cache *_txnh_slab = NULL; ++ ++/** ++ * init_txnmgr_static - create transaction manager slab caches ++ * ++ * Initializes caches of txn-atoms and txn_handle. It is part of reiser4 module ++ * initialization. ++ */ ++int init_txnmgr_static(void) ++{ ++ assert("jmacd-600", _atom_slab == NULL); ++ assert("jmacd-601", _txnh_slab == NULL); ++ ++ ON_DEBUG(atomic_set(&flush_cnt, 0)); ++ ++ _atom_slab = kmem_cache_create("txn_atom", sizeof(txn_atom), 0, ++ SLAB_HWCACHE_ALIGN | ++ SLAB_RECLAIM_ACCOUNT, NULL); ++ if (_atom_slab == NULL) ++ return RETERR(-ENOMEM); ++ ++ _txnh_slab = kmem_cache_create("txn_handle", sizeof(txn_handle), 0, ++ SLAB_HWCACHE_ALIGN, NULL); ++ if (_txnh_slab == NULL) { ++ kmem_cache_destroy(_atom_slab); ++ _atom_slab = NULL; ++ return RETERR(-ENOMEM); ++ } ++ ++ return 0; ++} ++ ++/** ++ * done_txnmgr_static - delete txn_atom and txn_handle caches ++ * ++ * This is called on reiser4 module unloading or system shutdown. ++ */ ++void done_txnmgr_static(void) ++{ ++ destroy_reiser4_cache(&_atom_slab); ++ destroy_reiser4_cache(&_txnh_slab); ++} ++ ++/** ++ * init_txnmgr - initialize a new transaction manager ++ * @mgr: pointer to transaction manager embedded in reiser4 super block ++ * ++ * This is called on mount. Makes necessary initializations. ++ */ ++void reiser4_init_txnmgr(txn_mgr *mgr) ++{ ++ assert("umka-169", mgr != NULL); ++ ++ mgr->atom_count = 0; ++ mgr->id_count = 1; ++ INIT_LIST_HEAD(&mgr->atoms_list); ++ spin_lock_init(&mgr->tmgr_lock); ++ mutex_init(&mgr->commit_mutex); ++} ++ ++/** ++ * reiser4_done_txnmgr - stop transaction manager ++ * @mgr: pointer to transaction manager embedded in reiser4 super block ++ * ++ * This is called on umount. Does sanity checks. ++ */ ++void reiser4_done_txnmgr(txn_mgr *mgr) ++{ ++ assert("umka-170", mgr != NULL); ++ assert("umka-1701", list_empty_careful(&mgr->atoms_list)); ++ assert("umka-1702", mgr->atom_count == 0); ++} ++ ++/* Initialize a transaction handle. */ ++/* Audited by: umka (2002.06.13) */ ++static void txnh_init(txn_handle * txnh, txn_mode mode) ++{ ++ assert("umka-171", txnh != NULL); ++ ++ txnh->mode = mode; ++ txnh->atom = NULL; ++ reiser4_ctx_gfp_mask_set(); ++ txnh->flags = 0; ++ spin_lock_init(&txnh->hlock); ++ INIT_LIST_HEAD(&txnh->txnh_link); ++} ++ ++#if REISER4_DEBUG ++/* Check if a transaction handle is clean. */ ++static int txnh_isclean(txn_handle * txnh) ++{ ++ assert("umka-172", txnh != NULL); ++ return txnh->atom == NULL && ++ LOCK_CNT_NIL(spin_locked_txnh); ++} ++#endif ++ ++/* Initialize an atom. */ ++static void atom_init(txn_atom * atom) ++{ ++ int level; ++ ++ assert("umka-173", atom != NULL); ++ ++ memset(atom, 0, sizeof(txn_atom)); ++ ++ atom->stage = ASTAGE_FREE; ++ atom->start_time = jiffies; ++ ++ for (level = 0; level < REAL_MAX_ZTREE_HEIGHT + 1; level += 1) ++ INIT_LIST_HEAD(ATOM_DIRTY_LIST(atom, level)); ++ ++ INIT_LIST_HEAD(ATOM_CLEAN_LIST(atom)); ++ INIT_LIST_HEAD(ATOM_OVRWR_LIST(atom)); ++ INIT_LIST_HEAD(ATOM_WB_LIST(atom)); ++ INIT_LIST_HEAD(&atom->inodes); ++ spin_lock_init(&(atom->alock)); ++ /* list of transaction handles */ ++ INIT_LIST_HEAD(&atom->txnh_list); ++ /* link to transaction manager's list of atoms */ ++ INIT_LIST_HEAD(&atom->atom_link); ++ INIT_LIST_HEAD(&atom->fwaitfor_list); ++ INIT_LIST_HEAD(&atom->fwaiting_list); ++ blocknr_set_init(&atom->delete_set); ++ blocknr_set_init(&atom->wandered_map); ++ ++ init_atom_fq_parts(atom); ++} ++ ++#if REISER4_DEBUG ++/* Check if an atom is clean. */ ++static int atom_isclean(txn_atom * atom) ++{ ++ int level; ++ ++ assert("umka-174", atom != NULL); ++ ++ for (level = 0; level < REAL_MAX_ZTREE_HEIGHT + 1; level += 1) { ++ if (!list_empty_careful(ATOM_DIRTY_LIST(atom, level))) { ++ return 0; ++ } ++ } ++ ++ return atom->stage == ASTAGE_FREE && ++ atom->txnh_count == 0 && ++ atom->capture_count == 0 && ++ atomic_read(&atom->refcount) == 0 && ++ (&atom->atom_link == atom->atom_link.next && ++ &atom->atom_link == atom->atom_link.prev) && ++ list_empty_careful(&atom->txnh_list) && ++ list_empty_careful(ATOM_CLEAN_LIST(atom)) && ++ list_empty_careful(ATOM_OVRWR_LIST(atom)) && ++ list_empty_careful(ATOM_WB_LIST(atom)) && ++ list_empty_careful(&atom->fwaitfor_list) && ++ list_empty_careful(&atom->fwaiting_list) && ++ atom_fq_parts_are_clean(atom); ++} ++#endif ++ ++/* Begin a transaction in this context. Currently this uses the reiser4_context's ++ trans_in_ctx, which means that transaction handles are stack-allocated. Eventually ++ this will be extended to allow transaction handles to span several contexts. */ ++/* Audited by: umka (2002.06.13) */ ++void reiser4_txn_begin(reiser4_context * context) ++{ ++ assert("jmacd-544", context->trans == NULL); ++ ++ context->trans = &context->trans_in_ctx; ++ ++ /* FIXME_LATER_JMACD Currently there's no way to begin a TXN_READ_FUSING ++ transcrash. Default should be TXN_WRITE_FUSING. Also, the _trans variable is ++ stack allocated right now, but we would like to allow for dynamically allocated ++ transcrashes that span multiple system calls. ++ */ ++ txnh_init(context->trans, TXN_WRITE_FUSING); ++} ++ ++/* Finish a transaction handle context. */ ++int reiser4_txn_end(reiser4_context * context) ++{ ++ long ret = 0; ++ txn_handle *txnh; ++ ++ assert("umka-283", context != NULL); ++ assert("nikita-3012", reiser4_schedulable()); ++ assert("vs-24", context == get_current_context()); ++ assert("nikita-2967", lock_stack_isclean(get_current_lock_stack())); ++ ++ txnh = context->trans; ++ if (txnh != NULL) { ++ if (txnh->atom != NULL) ++ ret = commit_txnh(txnh); ++ assert("jmacd-633", txnh_isclean(txnh)); ++ context->trans = NULL; ++ } ++ return ret; ++} ++ ++void reiser4_txn_restart(reiser4_context * context) ++{ ++ reiser4_txn_end(context); ++ reiser4_preempt_point(); ++ reiser4_txn_begin(context); ++} ++ ++void reiser4_txn_restart_current(void) ++{ ++ reiser4_txn_restart(get_current_context()); ++} ++ ++/* TXN_ATOM */ ++ ++/* Get the atom belonging to a txnh, which is not locked. Return txnh locked. Locks atom, if atom ++ is not NULL. This performs the necessary spin_trylock to break the lock-ordering cycle. May ++ return NULL. */ ++static txn_atom *txnh_get_atom(txn_handle * txnh) ++{ ++ txn_atom *atom; ++ ++ assert("umka-180", txnh != NULL); ++ assert_spin_not_locked(&(txnh->hlock)); ++ ++ while (1) { ++ spin_lock_txnh(txnh); ++ atom = txnh->atom; ++ ++ if (atom == NULL) ++ break; ++ ++ if (spin_trylock_atom(atom)) ++ break; ++ ++ atomic_inc(&atom->refcount); ++ ++ spin_unlock_txnh(txnh); ++ spin_lock_atom(atom); ++ spin_lock_txnh(txnh); ++ ++ if (txnh->atom == atom) { ++ atomic_dec(&atom->refcount); ++ break; ++ } ++ ++ spin_unlock_txnh(txnh); ++ atom_dec_and_unlock(atom); ++ } ++ ++ return atom; ++} ++ ++/* Get the current atom and spinlock it if current atom present. May return NULL */ ++txn_atom *get_current_atom_locked_nocheck(void) ++{ ++ reiser4_context *cx; ++ txn_atom *atom; ++ txn_handle *txnh; ++ ++ cx = get_current_context(); ++ assert("zam-437", cx != NULL); ++ ++ txnh = cx->trans; ++ assert("zam-435", txnh != NULL); ++ ++ atom = txnh_get_atom(txnh); ++ ++ spin_unlock_txnh(txnh); ++ return atom; ++} ++ ++/* Get the atom belonging to a jnode, which is initially locked. Return with ++ both jnode and atom locked. This performs the necessary spin_trylock to ++ break the lock-ordering cycle. Assumes the jnode is already locked, and ++ returns NULL if atom is not set. */ ++txn_atom *jnode_get_atom(jnode * node) ++{ ++ txn_atom *atom; ++ ++ assert("umka-181", node != NULL); ++ ++ while (1) { ++ assert_spin_locked(&(node->guard)); ++ ++ atom = node->atom; ++ /* node is not in any atom */ ++ if (atom == NULL) ++ break; ++ ++ /* If atom is not locked, grab the lock and return */ ++ if (spin_trylock_atom(atom)) ++ break; ++ ++ /* At least one jnode belongs to this atom it guarantees that ++ * atom->refcount > 0, we can safely increment refcount. */ ++ atomic_inc(&atom->refcount); ++ spin_unlock_jnode(node); ++ ++ /* re-acquire spin locks in the right order */ ++ spin_lock_atom(atom); ++ spin_lock_jnode(node); ++ ++ /* check if node still points to the same atom. */ ++ if (node->atom == atom) { ++ atomic_dec(&atom->refcount); ++ break; ++ } ++ ++ /* releasing of atom lock and reference requires not holding ++ * locks on jnodes. */ ++ spin_unlock_jnode(node); ++ ++ /* We do not sure that this atom has extra references except our ++ * one, so we should call proper function which may free atom if ++ * last reference is released. */ ++ atom_dec_and_unlock(atom); ++ ++ /* lock jnode again for getting valid node->atom pointer ++ * value. */ ++ spin_lock_jnode(node); ++ } ++ ++ return atom; ++} ++ ++/* Returns true if @node is dirty and part of the same atom as one of its neighbors. Used ++ by flush code to indicate whether the next node (in some direction) is suitable for ++ flushing. */ ++int ++same_slum_check(jnode * node, jnode * check, int alloc_check, int alloc_value) ++{ ++ int compat; ++ txn_atom *atom; ++ ++ assert("umka-182", node != NULL); ++ assert("umka-183", check != NULL); ++ ++ /* Not sure what this function is supposed to do if supplied with @check that is ++ neither formatted nor unformatted (bitmap or so). */ ++ assert("nikita-2373", jnode_is_znode(check) ++ || jnode_is_unformatted(check)); ++ ++ /* Need a lock on CHECK to get its atom and to check various state bits. ++ Don't need a lock on NODE once we get the atom lock. */ ++ /* It is not enough to lock two nodes and check (node->atom == ++ check->atom) because atom could be locked and being fused at that ++ moment, jnodes of the atom of that state (being fused) can point to ++ different objects, but the atom is the same. */ ++ spin_lock_jnode(check); ++ ++ atom = jnode_get_atom(check); ++ ++ if (atom == NULL) { ++ compat = 0; ++ } else { ++ compat = (node->atom == atom && JF_ISSET(check, JNODE_DIRTY)); ++ ++ if (compat && jnode_is_znode(check)) { ++ compat &= znode_is_connected(JZNODE(check)); ++ } ++ ++ if (compat && alloc_check) { ++ compat &= (alloc_value == jnode_is_flushprepped(check)); ++ } ++ ++ spin_unlock_atom(atom); ++ } ++ ++ spin_unlock_jnode(check); ++ ++ return compat; ++} ++ ++/* Decrement the atom's reference count and if it falls to zero, free it. */ ++void atom_dec_and_unlock(txn_atom * atom) ++{ ++ txn_mgr *mgr = &get_super_private(reiser4_get_current_sb())->tmgr; ++ ++ assert("umka-186", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ assert("zam-1039", atomic_read(&atom->refcount) > 0); ++ ++ if (atomic_dec_and_test(&atom->refcount)) { ++ /* take txnmgr lock and atom lock in proper order. */ ++ if (!spin_trylock_txnmgr(mgr)) { ++ /* This atom should exist after we re-acquire its ++ * spinlock, so we increment its reference counter. */ ++ atomic_inc(&atom->refcount); ++ spin_unlock_atom(atom); ++ spin_lock_txnmgr(mgr); ++ spin_lock_atom(atom); ++ ++ if (!atomic_dec_and_test(&atom->refcount)) { ++ spin_unlock_atom(atom); ++ spin_unlock_txnmgr(mgr); ++ return; ++ } ++ } ++ assert_spin_locked(&(mgr->tmgr_lock)); ++ atom_free(atom); ++ spin_unlock_txnmgr(mgr); ++ } else ++ spin_unlock_atom(atom); ++} ++ ++/* Create new atom and connect it to given transaction handle. This adds the ++ atom to the transaction manager's list and sets its reference count to 1, an ++ artificial reference which is kept until it commits. We play strange games ++ to avoid allocation under jnode & txnh spinlocks.*/ ++ ++static int atom_begin_and_assign_to_txnh(txn_atom ** atom_alloc, txn_handle * txnh) ++{ ++ txn_atom *atom; ++ txn_mgr *mgr; ++ ++ if (REISER4_DEBUG && rofs_tree(current_tree)) { ++ warning("nikita-3366", "Creating atom on rofs"); ++ dump_stack(); ++ } ++ ++ if (*atom_alloc == NULL) { ++ (*atom_alloc) = kmem_cache_alloc(_atom_slab, ++ reiser4_ctx_gfp_mask_get()); ++ ++ if (*atom_alloc == NULL) ++ return RETERR(-ENOMEM); ++ } ++ ++ /* and, also, txnmgr spin lock should be taken before jnode and txnh ++ locks. */ ++ mgr = &get_super_private(reiser4_get_current_sb())->tmgr; ++ spin_lock_txnmgr(mgr); ++ spin_lock_txnh(txnh); ++ ++ /* Check whether new atom still needed */ ++ if (txnh->atom != NULL) { ++ /* NOTE-NIKITA probably it is rather better to free ++ * atom_alloc here than thread it up to reiser4_try_capture() */ ++ ++ spin_unlock_txnh(txnh); ++ spin_unlock_txnmgr(mgr); ++ ++ return -E_REPEAT; ++ } ++ ++ atom = *atom_alloc; ++ *atom_alloc = NULL; ++ ++ atom_init(atom); ++ ++ assert("jmacd-17", atom_isclean(atom)); ++ ++ /* ++ * lock ordering is broken here. It is ok, as long as @atom is new ++ * and inaccessible for others. We can't use spin_lock_atom or ++ * spin_lock(&atom->alock) because they care about locking ++ * dependencies. spin_trylock_lock doesn't. ++ */ ++ check_me("", spin_trylock_atom(atom)); ++ ++ /* add atom to the end of transaction manager's list of atoms */ ++ list_add_tail(&atom->atom_link, &mgr->atoms_list); ++ atom->atom_id = mgr->id_count++; ++ mgr->atom_count += 1; ++ ++ /* Release txnmgr lock */ ++ spin_unlock_txnmgr(mgr); ++ ++ /* One reference until it commits. */ ++ atomic_inc(&atom->refcount); ++ atom->stage = ASTAGE_CAPTURE_FUSE; ++ atom->super = reiser4_get_current_sb(); ++ capture_assign_txnh_nolock(atom, txnh); ++ ++ spin_unlock_atom(atom); ++ spin_unlock_txnh(txnh); ++ ++ return -E_REPEAT; ++} ++ ++/* Return true if an atom is currently "open". */ ++static int atom_isopen(const txn_atom * atom) ++{ ++ assert("umka-185", atom != NULL); ++ ++ return atom->stage > 0 && atom->stage < ASTAGE_PRE_COMMIT; ++} ++ ++/* Return the number of pointers to this atom that must be updated during fusion. This ++ approximates the amount of work to be done. Fusion chooses the atom with fewer ++ pointers to fuse into the atom with more pointers. */ ++static int atom_pointer_count(const txn_atom * atom) ++{ ++ assert("umka-187", atom != NULL); ++ ++ /* This is a measure of the amount of work needed to fuse this atom ++ * into another. */ ++ return atom->txnh_count + atom->capture_count; ++} ++ ++/* Called holding the atom lock, this removes the atom from the transaction manager list ++ and frees it. */ ++static void atom_free(txn_atom * atom) ++{ ++ txn_mgr *mgr = &get_super_private(reiser4_get_current_sb())->tmgr; ++ ++ assert("umka-188", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ ++ /* Remove from the txn_mgr's atom list */ ++ assert_spin_locked(&(mgr->tmgr_lock)); ++ mgr->atom_count -= 1; ++ list_del_init(&atom->atom_link); ++ ++ /* Clean the atom */ ++ assert("jmacd-16", ++ (atom->stage == ASTAGE_INVALID || atom->stage == ASTAGE_DONE)); ++ atom->stage = ASTAGE_FREE; ++ ++ blocknr_set_destroy(&atom->delete_set); ++ blocknr_set_destroy(&atom->wandered_map); ++ ++ assert("jmacd-16", atom_isclean(atom)); ++ ++ spin_unlock_atom(atom); ++ ++ kmem_cache_free(_atom_slab, atom); ++} ++ ++static int atom_is_dotard(const txn_atom * atom) ++{ ++ return time_after(jiffies, atom->start_time + ++ get_current_super_private()->tmgr.atom_max_age); ++} ++ ++static int atom_can_be_committed(txn_atom * atom) ++{ ++ assert_spin_locked(&(atom->alock)); ++ assert("zam-885", atom->txnh_count > atom->nr_waiters); ++ return atom->txnh_count == atom->nr_waiters + 1; ++} ++ ++/* Return true if an atom should commit now. This is determined by aging, atom ++ size or atom flags. */ ++static int atom_should_commit(const txn_atom * atom) ++{ ++ assert("umka-189", atom != NULL); ++ return ++ (atom->flags & ATOM_FORCE_COMMIT) || ++ ((unsigned)atom_pointer_count(atom) > ++ get_current_super_private()->tmgr.atom_max_size) ++ || atom_is_dotard(atom); ++} ++ ++/* return 1 if current atom exists and requires commit. */ ++int current_atom_should_commit(void) ++{ ++ txn_atom *atom; ++ int result = 0; ++ ++ atom = get_current_atom_locked_nocheck(); ++ if (atom) { ++ result = atom_should_commit(atom); ++ spin_unlock_atom(atom); ++ } ++ return result; ++} ++ ++static int atom_should_commit_asap(const txn_atom * atom) ++{ ++ unsigned int captured; ++ unsigned int pinnedpages; ++ ++ assert("nikita-3309", atom != NULL); ++ ++ captured = (unsigned)atom->capture_count; ++ pinnedpages = (captured >> PAGE_CACHE_SHIFT) * sizeof(znode); ++ ++ return (pinnedpages > (totalram_pages >> 3)) || (atom->flushed > 100); ++} ++ ++static jnode *find_first_dirty_in_list(struct list_head *head, int flags) ++{ ++ jnode *first_dirty; ++ ++ list_for_each_entry(first_dirty, head, capture_link) { ++ if (!(flags & JNODE_FLUSH_COMMIT)) { ++ /* ++ * skip jnodes which "heard banshee" or having active ++ * I/O ++ */ ++ if (JF_ISSET(first_dirty, JNODE_HEARD_BANSHEE) || ++ JF_ISSET(first_dirty, JNODE_WRITEBACK)) ++ continue; ++ } ++ return first_dirty; ++ } ++ return NULL; ++} ++ ++/* Get first dirty node from the atom's dirty_nodes[n] lists; return NULL if atom has no dirty ++ nodes on atom's lists */ ++jnode *find_first_dirty_jnode(txn_atom * atom, int flags) ++{ ++ jnode *first_dirty; ++ tree_level level; ++ ++ assert_spin_locked(&(atom->alock)); ++ ++ /* The flush starts from LEAF_LEVEL (=1). */ ++ for (level = 1; level < REAL_MAX_ZTREE_HEIGHT + 1; level += 1) { ++ if (list_empty_careful(ATOM_DIRTY_LIST(atom, level))) ++ continue; ++ ++ first_dirty = ++ find_first_dirty_in_list(ATOM_DIRTY_LIST(atom, level), ++ flags); ++ if (first_dirty) ++ return first_dirty; ++ } ++ ++ /* znode-above-root is on the list #0. */ ++ return find_first_dirty_in_list(ATOM_DIRTY_LIST(atom, 0), flags); ++} ++ ++static void dispatch_wb_list(txn_atom * atom, flush_queue_t * fq) ++{ ++ jnode *cur; ++ ++ assert("zam-905", atom_is_protected(atom)); ++ ++ cur = list_entry(ATOM_WB_LIST(atom)->next, jnode, capture_link); ++ while (ATOM_WB_LIST(atom) != &cur->capture_link) { ++ jnode *next = list_entry(cur->capture_link.next, jnode, capture_link); ++ ++ spin_lock_jnode(cur); ++ if (!JF_ISSET(cur, JNODE_WRITEBACK)) { ++ if (JF_ISSET(cur, JNODE_DIRTY)) { ++ queue_jnode(fq, cur); ++ } else { ++ /* move jnode to atom's clean list */ ++ list_move_tail(&cur->capture_link, ++ ATOM_CLEAN_LIST(atom)); ++ } ++ } ++ spin_unlock_jnode(cur); ++ ++ cur = next; ++ } ++} ++ ++/* Scan current atom->writeback_nodes list, re-submit dirty and !writeback ++ * jnodes to disk. */ ++static int submit_wb_list(void) ++{ ++ int ret; ++ flush_queue_t *fq; ++ ++ fq = get_fq_for_current_atom(); ++ if (IS_ERR(fq)) ++ return PTR_ERR(fq); ++ ++ dispatch_wb_list(fq->atom, fq); ++ spin_unlock_atom(fq->atom); ++ ++ ret = reiser4_write_fq(fq, NULL, 1); ++ reiser4_fq_put(fq); ++ ++ return ret; ++} ++ ++/* Wait completion of all writes, re-submit atom writeback list if needed. */ ++static int current_atom_complete_writes(void) ++{ ++ int ret; ++ ++ /* Each jnode from that list was modified and dirtied when it had i/o ++ * request running already. After i/o completion we have to resubmit ++ * them to disk again.*/ ++ ret = submit_wb_list(); ++ if (ret < 0) ++ return ret; ++ ++ /* Wait all i/o completion */ ++ ret = current_atom_finish_all_fq(); ++ if (ret) ++ return ret; ++ ++ /* Scan wb list again; all i/o should be completed, we re-submit dirty ++ * nodes to disk */ ++ ret = submit_wb_list(); ++ if (ret < 0) ++ return ret; ++ ++ /* Wait all nodes we just submitted */ ++ return current_atom_finish_all_fq(); ++} ++ ++#if REISER4_DEBUG ++ ++static void reiser4_info_atom(const char *prefix, const txn_atom * atom) ++{ ++ if (atom == NULL) { ++ printk("%s: no atom\n", prefix); ++ return; ++ } ++ ++ printk("%s: refcount: %i id: %i flags: %x txnh_count: %i" ++ " capture_count: %i stage: %x start: %lu, flushed: %i\n", prefix, ++ atomic_read(&atom->refcount), atom->atom_id, atom->flags, ++ atom->txnh_count, atom->capture_count, atom->stage, ++ atom->start_time, atom->flushed); ++} ++ ++#else /* REISER4_DEBUG */ ++ ++static inline void reiser4_info_atom(const char *prefix, const txn_atom * atom) {} ++ ++#endif /* REISER4_DEBUG */ ++ ++#define TOOMANYFLUSHES (1 << 13) ++ ++/* Called with the atom locked and no open "active" transaction handlers except ++ ours, this function calls flush_current_atom() until all dirty nodes are ++ processed. Then it initiates commit processing. ++ ++ Called by the single remaining open "active" txnh, which is closing. Other ++ open txnhs belong to processes which wait atom commit in commit_txnh() ++ routine. They are counted as "waiters" in atom->nr_waiters. Therefore as ++ long as we hold the atom lock none of the jnodes can be captured and/or ++ locked. ++ ++ Return value is an error code if commit fails. ++*/ ++static int commit_current_atom(long *nr_submitted, txn_atom ** atom) ++{ ++ reiser4_super_info_data *sbinfo = get_current_super_private(); ++ long ret = 0; ++ /* how many times jnode_flush() was called as a part of attempt to ++ * commit this atom. */ ++ int flushiters; ++ ++ assert("zam-888", atom != NULL && *atom != NULL); ++ assert_spin_locked(&((*atom)->alock)); ++ assert("zam-887", get_current_context()->trans->atom == *atom); ++ assert("jmacd-151", atom_isopen(*atom)); ++ ++ assert("nikita-3184", ++ get_current_super_private()->delete_mutex_owner != current); ++ ++ for (flushiters = 0;; ++flushiters) { ++ ret = ++ flush_current_atom(JNODE_FLUSH_WRITE_BLOCKS | ++ JNODE_FLUSH_COMMIT, ++ LONG_MAX /* nr_to_write */ , ++ nr_submitted, atom, NULL); ++ if (ret != -E_REPEAT) ++ break; ++ ++ /* if atom's dirty list contains one znode which is ++ HEARD_BANSHEE and is locked we have to allow lock owner to ++ continue and uncapture that znode */ ++ reiser4_preempt_point(); ++ ++ *atom = get_current_atom_locked(); ++ if (flushiters > TOOMANYFLUSHES && IS_POW(flushiters)) { ++ warning("nikita-3176", ++ "Flushing like mad: %i", flushiters); ++ reiser4_info_atom("atom", *atom); ++ DEBUGON(flushiters > (1 << 20)); ++ } ++ } ++ ++ if (ret) ++ return ret; ++ ++ assert_spin_locked(&((*atom)->alock)); ++ ++ if (!atom_can_be_committed(*atom)) { ++ spin_unlock_atom(*atom); ++ return RETERR(-E_REPEAT); ++ } ++ ++ if ((*atom)->capture_count == 0) ++ goto done; ++ ++ /* Up to this point we have been flushing and after flush is called we ++ return -E_REPEAT. Now we can commit. We cannot return -E_REPEAT ++ at this point, commit should be successful. */ ++ reiser4_atom_set_stage(*atom, ASTAGE_PRE_COMMIT); ++ ON_DEBUG(((*atom)->committer = current)); ++ spin_unlock_atom(*atom); ++ ++ ret = current_atom_complete_writes(); ++ if (ret) ++ return ret; ++ ++ assert("zam-906", list_empty(ATOM_WB_LIST(*atom))); ++ ++ /* isolate critical code path which should be executed by only one ++ * thread using tmgr mutex */ ++ mutex_lock(&sbinfo->tmgr.commit_mutex); ++ ++ ret = reiser4_write_logs(nr_submitted); ++ if (ret < 0) ++ reiser4_panic("zam-597", "write log failed (%ld)\n", ret); ++ ++ /* The atom->ovrwr_nodes list is processed under commit mutex held ++ because of bitmap nodes which are captured by special way in ++ reiser4_pre_commit_hook_bitmap(), that way does not include ++ capture_fuse_wait() as a capturing of other nodes does -- the commit ++ mutex is used for transaction isolation instead. */ ++ reiser4_invalidate_list(ATOM_OVRWR_LIST(*atom)); ++ mutex_unlock(&sbinfo->tmgr.commit_mutex); ++ ++ reiser4_invalidate_list(ATOM_CLEAN_LIST(*atom)); ++ reiser4_invalidate_list(ATOM_WB_LIST(*atom)); ++ assert("zam-927", list_empty(&(*atom)->inodes)); ++ ++ spin_lock_atom(*atom); ++ done: ++ reiser4_atom_set_stage(*atom, ASTAGE_DONE); ++ ON_DEBUG((*atom)->committer = NULL); ++ ++ /* Atom's state changes, so wake up everybody waiting for this ++ event. */ ++ wakeup_atom_waiting_list(*atom); ++ ++ /* Decrement the "until commit" reference, at least one txnh (the caller) is ++ still open. */ ++ atomic_dec(&(*atom)->refcount); ++ ++ assert("jmacd-1070", atomic_read(&(*atom)->refcount) > 0); ++ assert("jmacd-1062", (*atom)->capture_count == 0); ++ BUG_ON((*atom)->capture_count != 0); ++ assert_spin_locked(&((*atom)->alock)); ++ ++ return ret; ++} ++ ++/* TXN_TXNH */ ++ ++/** ++ * force_commit_atom - commit current atom and wait commit completion ++ * @txnh: ++ * ++ * Commits current atom and wait commit completion; current atom and @txnh have ++ * to be spinlocked before call, this function unlocks them on exit. ++ */ ++int force_commit_atom(txn_handle *txnh) ++{ ++ txn_atom *atom; ++ ++ assert("zam-837", txnh != NULL); ++ assert_spin_locked(&(txnh->hlock)); ++ assert("nikita-2966", lock_stack_isclean(get_current_lock_stack())); ++ ++ atom = txnh->atom; ++ ++ assert("zam-834", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ ++ /* ++ * Set flags for atom and txnh: forcing atom commit and waiting for ++ * commit completion ++ */ ++ txnh->flags |= TXNH_WAIT_COMMIT; ++ atom->flags |= ATOM_FORCE_COMMIT; ++ ++ spin_unlock_txnh(txnh); ++ spin_unlock_atom(atom); ++ ++ /* commit is here */ ++ reiser4_txn_restart_current(); ++ return 0; ++} ++ ++/* Called to force commit of any outstanding atoms. @commit_all_atoms controls ++ * should we commit all atoms including new ones which are created after this ++ * functions is called. */ ++int txnmgr_force_commit_all(struct super_block *super, int commit_all_atoms) ++{ ++ int ret; ++ txn_atom *atom; ++ txn_mgr *mgr; ++ txn_handle *txnh; ++ unsigned long start_time = jiffies; ++ reiser4_context *ctx = get_current_context(); ++ ++ assert("nikita-2965", lock_stack_isclean(get_current_lock_stack())); ++ assert("nikita-3058", reiser4_commit_check_locks()); ++ ++ reiser4_txn_restart_current(); ++ ++ mgr = &get_super_private(super)->tmgr; ++ ++ txnh = ctx->trans; ++ ++ again: ++ ++ spin_lock_txnmgr(mgr); ++ ++ list_for_each_entry(atom, &mgr->atoms_list, atom_link) { ++ spin_lock_atom(atom); ++ ++ /* Commit any atom which can be committed. If @commit_new_atoms ++ * is not set we commit only atoms which were created before ++ * this call is started. */ ++ if (commit_all_atoms ++ || time_before_eq(atom->start_time, start_time)) { ++ if (atom->stage <= ASTAGE_POST_COMMIT) { ++ spin_unlock_txnmgr(mgr); ++ ++ if (atom->stage < ASTAGE_PRE_COMMIT) { ++ spin_lock_txnh(txnh); ++ /* Add force-context txnh */ ++ capture_assign_txnh_nolock(atom, txnh); ++ ret = force_commit_atom(txnh); ++ if (ret) ++ return ret; ++ } else ++ /* wait atom commit */ ++ reiser4_atom_wait_event(atom); ++ ++ goto again; ++ } ++ } ++ ++ spin_unlock_atom(atom); ++ } ++ ++#if REISER4_DEBUG ++ if (commit_all_atoms) { ++ reiser4_super_info_data *sbinfo = get_super_private(super); ++ spin_lock_reiser4_super(sbinfo); ++ assert("zam-813", ++ sbinfo->blocks_fake_allocated_unformatted == 0); ++ assert("zam-812", sbinfo->blocks_fake_allocated == 0); ++ spin_unlock_reiser4_super(sbinfo); ++ } ++#endif ++ ++ spin_unlock_txnmgr(mgr); ++ ++ return 0; ++} ++ ++/* check whether commit_some_atoms() can commit @atom. Locking is up to the ++ * caller */ ++static int atom_is_committable(txn_atom * atom) ++{ ++ return ++ atom->stage < ASTAGE_PRE_COMMIT && ++ atom->txnh_count == atom->nr_waiters && atom_should_commit(atom); ++} ++ ++/* called periodically from ktxnmgrd to commit old atoms. Releases ktxnmgrd spin ++ * lock at exit */ ++int commit_some_atoms(txn_mgr * mgr) ++{ ++ int ret = 0; ++ txn_atom *atom; ++ txn_handle *txnh; ++ reiser4_context *ctx; ++ struct list_head *pos, *tmp; ++ ++ ctx = get_current_context(); ++ assert("nikita-2444", ctx != NULL); ++ ++ txnh = ctx->trans; ++ spin_lock_txnmgr(mgr); ++ ++ /* ++ * this is to avoid gcc complain that atom might be used ++ * uninitialized ++ */ ++ atom = NULL; ++ ++ /* look for atom to commit */ ++ list_for_each_safe(pos, tmp, &mgr->atoms_list) { ++ atom = list_entry(pos, txn_atom, atom_link); ++ /* ++ * first test without taking atom spin lock, whether it is ++ * eligible for committing at all ++ */ ++ if (atom_is_committable(atom)) { ++ /* now, take spin lock and re-check */ ++ spin_lock_atom(atom); ++ if (atom_is_committable(atom)) ++ break; ++ spin_unlock_atom(atom); ++ } ++ } ++ ++ ret = (&mgr->atoms_list == pos); ++ spin_unlock_txnmgr(mgr); ++ ++ if (ret) { ++ /* nothing found */ ++ spin_unlock(&mgr->daemon->guard); ++ return 0; ++ } ++ ++ spin_lock_txnh(txnh); ++ ++ BUG_ON(atom == NULL); ++ /* Set the atom to force committing */ ++ atom->flags |= ATOM_FORCE_COMMIT; ++ ++ /* Add force-context txnh */ ++ capture_assign_txnh_nolock(atom, txnh); ++ ++ spin_unlock_txnh(txnh); ++ spin_unlock_atom(atom); ++ ++ /* we are about to release daemon spin lock, notify daemon it ++ has to rescan atoms */ ++ mgr->daemon->rescan = 1; ++ spin_unlock(&mgr->daemon->guard); ++ reiser4_txn_restart_current(); ++ return 0; ++} ++ ++static int txn_try_to_fuse_small_atom(txn_mgr * tmgr, txn_atom * atom) ++{ ++ int atom_stage; ++ txn_atom *atom_2; ++ int repeat; ++ ++ assert("zam-1051", atom->stage < ASTAGE_PRE_COMMIT); ++ ++ atom_stage = atom->stage; ++ repeat = 0; ++ ++ if (!spin_trylock_txnmgr(tmgr)) { ++ atomic_inc(&atom->refcount); ++ spin_unlock_atom(atom); ++ spin_lock_txnmgr(tmgr); ++ spin_lock_atom(atom); ++ repeat = 1; ++ if (atom->stage != atom_stage) { ++ spin_unlock_txnmgr(tmgr); ++ atom_dec_and_unlock(atom); ++ return -E_REPEAT; ++ } ++ atomic_dec(&atom->refcount); ++ } ++ ++ list_for_each_entry(atom_2, &tmgr->atoms_list, atom_link) { ++ if (atom == atom_2) ++ continue; ++ /* ++ * if trylock does not succeed we just do not fuse with that ++ * atom. ++ */ ++ if (spin_trylock_atom(atom_2)) { ++ if (atom_2->stage < ASTAGE_PRE_COMMIT) { ++ spin_unlock_txnmgr(tmgr); ++ capture_fuse_into(atom_2, atom); ++ /* all locks are lost we can only repeat here */ ++ return -E_REPEAT; ++ } ++ spin_unlock_atom(atom_2); ++ } ++ } ++ atom->flags |= ATOM_CANCEL_FUSION; ++ spin_unlock_txnmgr(tmgr); ++ if (repeat) { ++ spin_unlock_atom(atom); ++ return -E_REPEAT; ++ } ++ return 0; ++} ++ ++/* Calls jnode_flush for current atom if it exists; if not, just take another ++ atom and call jnode_flush() for him. If current transaction handle has ++ already assigned atom (current atom) we have to close current transaction ++ prior to switch to another atom or do something with current atom. This ++ code tries to flush current atom. ++ ++ flush_some_atom() is called as part of memory clearing process. It is ++ invoked from balance_dirty_pages(), pdflushd, and entd. ++ ++ If we can flush no nodes, atom is committed, because this frees memory. ++ ++ If atom is too large or too old it is committed also. ++*/ ++int ++flush_some_atom(jnode * start, long *nr_submitted, const struct writeback_control *wbc, ++ int flags) ++{ ++ reiser4_context *ctx = get_current_context(); ++ txn_mgr *tmgr = &get_super_private(ctx->super)->tmgr; ++ txn_handle *txnh = ctx->trans; ++ txn_atom *atom; ++ int ret; ++ ++ BUG_ON(wbc->nr_to_write == 0); ++ BUG_ON(*nr_submitted != 0); ++ assert("zam-1042", txnh != NULL); ++ repeat: ++ if (txnh->atom == NULL) { ++ /* current atom is not available, take first from txnmgr */ ++ spin_lock_txnmgr(tmgr); ++ ++ /* traverse the list of all atoms */ ++ list_for_each_entry(atom, &tmgr->atoms_list, atom_link) { ++ /* lock atom before checking its state */ ++ spin_lock_atom(atom); ++ ++ /* ++ * we need an atom which is not being committed and ++ * which has no flushers (jnode_flush() add one flusher ++ * at the beginning and subtract one at the end). ++ */ ++ if (atom->stage < ASTAGE_PRE_COMMIT && ++ atom->nr_flushers == 0) { ++ spin_lock_txnh(txnh); ++ capture_assign_txnh_nolock(atom, txnh); ++ spin_unlock_txnh(txnh); ++ ++ goto found; ++ } ++ ++ spin_unlock_atom(atom); ++ } ++ ++ /* ++ * Write throttling is case of no one atom can be ++ * flushed/committed. ++ */ ++ if (!current_is_pdflush() && !wbc->nonblocking) { ++ list_for_each_entry(atom, &tmgr->atoms_list, atom_link) { ++ spin_lock_atom(atom); ++ /* Repeat the check from the above. */ ++ if (atom->stage < ASTAGE_PRE_COMMIT ++ && atom->nr_flushers == 0) { ++ spin_lock_txnh(txnh); ++ capture_assign_txnh_nolock(atom, txnh); ++ spin_unlock_txnh(txnh); ++ ++ goto found; ++ } ++ if (atom->stage <= ASTAGE_POST_COMMIT) { ++ spin_unlock_txnmgr(tmgr); ++ /* ++ * we just wait until atom's flusher ++ * makes a progress in flushing or ++ * committing the atom ++ */ ++ reiser4_atom_wait_event(atom); ++ goto repeat; ++ } ++ spin_unlock_atom(atom); ++ } ++ } ++ spin_unlock_txnmgr(tmgr); ++ return 0; ++ found: ++ spin_unlock_txnmgr(tmgr); ++ } else ++ atom = get_current_atom_locked(); ++ ++ BUG_ON(atom->super != ctx->super); ++ assert("vs-35", atom->super == ctx->super); ++ if (start) { ++ spin_lock_jnode(start); ++ ret = (atom == start->atom) ? 1 : 0; ++ spin_unlock_jnode(start); ++ if (ret == 0) ++ start = NULL; ++ } ++ ret = flush_current_atom(flags, wbc->nr_to_write, nr_submitted, &atom, start); ++ if (ret == 0) { ++ /* flush_current_atom returns 0 only if it submitted for write ++ nothing */ ++ BUG_ON(*nr_submitted != 0); ++ if (*nr_submitted == 0 || atom_should_commit_asap(atom)) { ++ if (atom->capture_count < tmgr->atom_min_size && ++ !(atom->flags & ATOM_CANCEL_FUSION)) { ++ ret = txn_try_to_fuse_small_atom(tmgr, atom); ++ if (ret == -E_REPEAT) { ++ reiser4_preempt_point(); ++ goto repeat; ++ } ++ } ++ /* if early flushing could not make more nodes clean, ++ * or atom is too old/large, ++ * we force current atom to commit */ ++ /* wait for commit completion but only if this ++ * wouldn't stall pdflushd and ent thread. */ ++ if (!wbc->nonblocking && !ctx->entd) ++ txnh->flags |= TXNH_WAIT_COMMIT; ++ atom->flags |= ATOM_FORCE_COMMIT; ++ } ++ spin_unlock_atom(atom); ++ } else if (ret == -E_REPEAT) { ++ if (*nr_submitted == 0) { ++ /* let others who hampers flushing (hold longterm locks, ++ for instance) to free the way for flush */ ++ reiser4_preempt_point(); ++ goto repeat; ++ } ++ ret = 0; ++ } ++/* ++ if (*nr_submitted > wbc->nr_to_write) ++ warning("", "asked for %ld, written %ld\n", wbc->nr_to_write, *nr_submitted); ++*/ ++ reiser4_txn_restart(ctx); ++ ++ return ret; ++} ++ ++/* Remove processed nodes from atom's clean list (thereby remove them from transaction). */ ++void reiser4_invalidate_list(struct list_head *head) ++{ ++ while (!list_empty(head)) { ++ jnode *node; ++ ++ node = list_entry(head->next, jnode, capture_link); ++ spin_lock_jnode(node); ++ reiser4_uncapture_block(node); ++ jput(node); ++ } ++} ++ ++static void init_wlinks(txn_wait_links * wlinks) ++{ ++ wlinks->_lock_stack = get_current_lock_stack(); ++ INIT_LIST_HEAD(&wlinks->_fwaitfor_link); ++ INIT_LIST_HEAD(&wlinks->_fwaiting_link); ++ wlinks->waitfor_cb = NULL; ++ wlinks->waiting_cb = NULL; ++} ++ ++/* Add atom to the atom's waitfor list and wait for somebody to wake us up; */ ++void reiser4_atom_wait_event(txn_atom * atom) ++{ ++ txn_wait_links _wlinks; ++ ++ assert_spin_locked(&(atom->alock)); ++ assert("nikita-3156", ++ lock_stack_isclean(get_current_lock_stack()) || ++ atom->nr_running_queues > 0); ++ ++ init_wlinks(&_wlinks); ++ list_add_tail(&_wlinks._fwaitfor_link, &atom->fwaitfor_list); ++ atomic_inc(&atom->refcount); ++ spin_unlock_atom(atom); ++ ++ reiser4_prepare_to_sleep(_wlinks._lock_stack); ++ reiser4_go_to_sleep(_wlinks._lock_stack); ++ ++ spin_lock_atom(atom); ++ list_del(&_wlinks._fwaitfor_link); ++ atom_dec_and_unlock(atom); ++} ++ ++void reiser4_atom_set_stage(txn_atom * atom, txn_stage stage) ++{ ++ assert("nikita-3535", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ assert("nikita-3536", stage <= ASTAGE_INVALID); ++ /* Excelsior! */ ++ assert("nikita-3537", stage >= atom->stage); ++ if (atom->stage != stage) { ++ atom->stage = stage; ++ reiser4_atom_send_event(atom); ++ } ++} ++ ++/* wake all threads which wait for an event */ ++void reiser4_atom_send_event(txn_atom * atom) ++{ ++ assert_spin_locked(&(atom->alock)); ++ wakeup_atom_waitfor_list(atom); ++} ++ ++/* Informs txn manager code that owner of this txn_handle should wait atom commit completion (for ++ example, because it does fsync(2)) */ ++static int should_wait_commit(txn_handle * h) ++{ ++ return h->flags & TXNH_WAIT_COMMIT; ++} ++ ++typedef struct commit_data { ++ txn_atom *atom; ++ txn_handle *txnh; ++ long nr_written; ++ /* as an optimization we start committing atom by first trying to ++ * flush it few times without switching into ASTAGE_CAPTURE_WAIT. This ++ * allows to reduce stalls due to other threads waiting for atom in ++ * ASTAGE_CAPTURE_WAIT stage. ->preflush is counter of these ++ * preliminary flushes. */ ++ int preflush; ++ /* have we waited on atom. */ ++ int wait; ++ int failed; ++ int wake_ktxnmgrd_up; ++} commit_data; ++ ++/* ++ * Called from commit_txnh() repeatedly, until either error happens, or atom ++ * commits successfully. ++ */ ++static int try_commit_txnh(commit_data * cd) ++{ ++ int result; ++ ++ assert("nikita-2968", lock_stack_isclean(get_current_lock_stack())); ++ ++ /* Get the atom and txnh locked. */ ++ cd->atom = txnh_get_atom(cd->txnh); ++ assert("jmacd-309", cd->atom != NULL); ++ spin_unlock_txnh(cd->txnh); ++ ++ if (cd->wait) { ++ cd->atom->nr_waiters--; ++ cd->wait = 0; ++ } ++ ++ if (cd->atom->stage == ASTAGE_DONE) ++ return 0; ++ ++ if (cd->failed) ++ return 0; ++ ++ if (atom_should_commit(cd->atom)) { ++ /* if atom is _very_ large schedule it for commit as soon as ++ * possible. */ ++ if (atom_should_commit_asap(cd->atom)) { ++ /* ++ * When atom is in PRE_COMMIT or later stage following ++ * invariant (encoded in atom_can_be_committed()) ++ * holds: there is exactly one non-waiter transaction ++ * handle opened on this atom. When thread wants to ++ * wait until atom commits (for example sync()) it ++ * waits on atom event after increasing ++ * atom->nr_waiters (see blow in this function). It ++ * cannot be guaranteed that atom is already committed ++ * after receiving event, so loop has to be ++ * re-started. But if atom switched into PRE_COMMIT ++ * stage and became too large, we cannot change its ++ * state back to CAPTURE_WAIT (atom stage can only ++ * increase monotonically), hence this check. ++ */ ++ if (cd->atom->stage < ASTAGE_CAPTURE_WAIT) ++ reiser4_atom_set_stage(cd->atom, ++ ASTAGE_CAPTURE_WAIT); ++ cd->atom->flags |= ATOM_FORCE_COMMIT; ++ } ++ if (cd->txnh->flags & TXNH_DONT_COMMIT) { ++ /* ++ * this thread (transaction handle that is) doesn't ++ * want to commit atom. Notify waiters that handle is ++ * closed. This can happen, for example, when we are ++ * under VFS directory lock and don't want to commit ++ * atom right now to avoid stalling other threads ++ * working in the same directory. ++ */ ++ ++ /* Wake the ktxnmgrd up if the ktxnmgrd is needed to ++ * commit this atom: no atom waiters and only one ++ * (our) open transaction handle. */ ++ cd->wake_ktxnmgrd_up = ++ cd->atom->txnh_count == 1 && ++ cd->atom->nr_waiters == 0; ++ reiser4_atom_send_event(cd->atom); ++ result = 0; ++ } else if (!atom_can_be_committed(cd->atom)) { ++ if (should_wait_commit(cd->txnh)) { ++ /* sync(): wait for commit */ ++ cd->atom->nr_waiters++; ++ cd->wait = 1; ++ reiser4_atom_wait_event(cd->atom); ++ result = RETERR(-E_REPEAT); ++ } else { ++ result = 0; ++ } ++ } else if (cd->preflush > 0 && !is_current_ktxnmgrd()) { ++ /* ++ * optimization: flush atom without switching it into ++ * ASTAGE_CAPTURE_WAIT. ++ * ++ * But don't do this for ktxnmgrd, because ktxnmgrd ++ * should never block on atom fusion. ++ */ ++ result = flush_current_atom(JNODE_FLUSH_WRITE_BLOCKS, ++ LONG_MAX, &cd->nr_written, ++ &cd->atom, NULL); ++ if (result == 0) { ++ spin_unlock_atom(cd->atom); ++ cd->preflush = 0; ++ result = RETERR(-E_REPEAT); ++ } else /* Atoms wasn't flushed ++ * completely. Rinse. Repeat. */ ++ --cd->preflush; ++ } else { ++ /* We change atom state to ASTAGE_CAPTURE_WAIT to ++ prevent atom fusion and count ourself as an active ++ flusher */ ++ reiser4_atom_set_stage(cd->atom, ASTAGE_CAPTURE_WAIT); ++ cd->atom->flags |= ATOM_FORCE_COMMIT; ++ ++ result = ++ commit_current_atom(&cd->nr_written, &cd->atom); ++ if (result != 0 && result != -E_REPEAT) ++ cd->failed = 1; ++ } ++ } else ++ result = 0; ++ ++#if REISER4_DEBUG ++ if (result == 0) ++ assert_spin_locked(&(cd->atom->alock)); ++#endif ++ ++ /* perfectly valid assertion, except that when atom/txnh is not locked ++ * fusion can take place, and cd->atom points nowhere. */ ++ /* ++ assert("jmacd-1028", ergo(result != 0, spin_atom_is_not_locked(cd->atom))); ++ */ ++ return result; ++} ++ ++/* Called to commit a transaction handle. This decrements the atom's number of open ++ handles and if it is the last handle to commit and the atom should commit, initiates ++ atom commit. if commit does not fail, return number of written blocks */ ++static int commit_txnh(txn_handle * txnh) ++{ ++ commit_data cd; ++ assert("umka-192", txnh != NULL); ++ ++ memset(&cd, 0, sizeof cd); ++ cd.txnh = txnh; ++ cd.preflush = 10; ++ ++ /* calls try_commit_txnh() until either atom commits, or error ++ * happens */ ++ while (try_commit_txnh(&cd) != 0) ++ reiser4_preempt_point(); ++ ++ spin_lock_txnh(txnh); ++ ++ cd.atom->txnh_count -= 1; ++ txnh->atom = NULL; ++ /* remove transaction handle from atom's list of transaction handles */ ++ list_del_init(&txnh->txnh_link); ++ ++ spin_unlock_txnh(txnh); ++ atom_dec_and_unlock(cd.atom); ++ /* if we don't want to do a commit (TXNH_DONT_COMMIT is set, probably ++ * because it takes time) by current thread, we do that work ++ * asynchronously by ktxnmgrd daemon. */ ++ if (cd.wake_ktxnmgrd_up) ++ ktxnmgrd_kick(&get_current_super_private()->tmgr); ++ ++ return 0; ++} ++ ++/* TRY_CAPTURE */ ++ ++/* This routine attempts a single block-capture request. It may return -E_REPEAT if some ++ condition indicates that the request should be retried, and it may block if the ++ txn_capture mode does not include the TXN_CAPTURE_NONBLOCKING request flag. ++ ++ This routine encodes the basic logic of block capturing described by: ++ ++ http://namesys.com/v4/v4.html ++ ++ Our goal here is to ensure that any two blocks that contain dependent modifications ++ should commit at the same time. This function enforces this discipline by initiating ++ fusion whenever a transaction handle belonging to one atom requests to read or write a ++ block belonging to another atom (TXN_CAPTURE_WRITE or TXN_CAPTURE_READ_ATOMIC). ++ ++ In addition, this routine handles the initial assignment of atoms to blocks and ++ transaction handles. These are possible outcomes of this function: ++ ++ 1. The block and handle are already part of the same atom: return immediate success ++ ++ 2. The block is assigned but the handle is not: call capture_assign_txnh to assign ++ the handle to the block's atom. ++ ++ 3. The handle is assigned but the block is not: call capture_assign_block to assign ++ the block to the handle's atom. ++ ++ 4. Both handle and block are assigned, but to different atoms: call capture_init_fusion ++ to fuse atoms. ++ ++ 5. Neither block nor handle are assigned: create a new atom and assign them both. ++ ++ 6. A read request for a non-captured block: return immediate success. ++ ++ This function acquires and releases the handle's spinlock. This function is called ++ under the jnode lock and if the return value is 0, it returns with the jnode lock still ++ held. If the return is -E_REPEAT or some other error condition, the jnode lock is ++ released. The external interface (reiser4_try_capture) manages re-aquiring the jnode ++ lock in the failure case. ++*/ ++static int try_capture_block( ++ txn_handle * txnh, jnode * node, txn_capture mode, ++ txn_atom ** atom_alloc) ++{ ++ txn_atom *block_atom; ++ txn_atom *txnh_atom; ++ ++ /* Should not call capture for READ_NONCOM requests, handled in reiser4_try_capture. */ ++ assert("jmacd-567", CAPTURE_TYPE(mode) != TXN_CAPTURE_READ_NONCOM); ++ ++ /* FIXME-ZAM-HANS: FIXME_LATER_JMACD Should assert that atom->tree == ++ * node->tree somewhere. */ ++ assert("umka-194", txnh != NULL); ++ assert("umka-195", node != NULL); ++ ++ /* The jnode is already locked! Being called from reiser4_try_capture(). */ ++ assert_spin_locked(&(node->guard)); ++ block_atom = node->atom; ++ ++ /* Get txnh spinlock, this allows us to compare txn_atom pointers but it doesn't ++ let us touch the atoms themselves. */ ++ spin_lock_txnh(txnh); ++ txnh_atom = txnh->atom; ++ /* Process of capturing continues into one of four branches depends on ++ which atoms from (block atom (node->atom), current atom (txnh->atom)) ++ exist. */ ++ if (txnh_atom == NULL) { ++ if (block_atom == NULL) { ++ spin_unlock_txnh(txnh); ++ spin_unlock_jnode(node); ++ /* assign empty atom to the txnh and repeat */ ++ return atom_begin_and_assign_to_txnh(atom_alloc, txnh); ++ } else { ++ atomic_inc(&block_atom->refcount); ++ /* node spin-lock isn't needed anymore */ ++ spin_unlock_jnode(node); ++ if (!spin_trylock_atom(block_atom)) { ++ spin_unlock_txnh(txnh); ++ spin_lock_atom(block_atom); ++ spin_lock_txnh(txnh); ++ } ++ /* re-check state after getting txnh and the node ++ * atom spin-locked */ ++ if (node->atom != block_atom || txnh->atom != NULL) { ++ spin_unlock_txnh(txnh); ++ atom_dec_and_unlock(block_atom); ++ return RETERR(-E_REPEAT); ++ } ++ atomic_dec(&block_atom->refcount); ++ if (block_atom->stage > ASTAGE_CAPTURE_WAIT || ++ (block_atom->stage == ASTAGE_CAPTURE_WAIT && ++ block_atom->txnh_count != 0)) ++ return capture_fuse_wait(txnh, block_atom, NULL, mode); ++ capture_assign_txnh_nolock(block_atom, txnh); ++ spin_unlock_txnh(txnh); ++ spin_unlock_atom(block_atom); ++ return RETERR(-E_REPEAT); ++ } ++ } else { ++ /* It is time to perform deadlock prevention check over the ++ node we want to capture. It is possible this node was locked ++ for read without capturing it. The optimization which allows ++ to do it helps us in keeping atoms independent as long as ++ possible but it may cause lock/fuse deadlock problems. ++ ++ A number of similar deadlock situations with locked but not ++ captured nodes were found. In each situation there are two ++ or more threads: one of them does flushing while another one ++ does routine balancing or tree lookup. The flushing thread ++ (F) sleeps in long term locking request for node (N), another ++ thread (A) sleeps in trying to capture some node already ++ belonging the atom F, F has a state which prevents ++ immediately fusion . ++ ++ Deadlocks of this kind cannot happen if node N was properly ++ captured by thread A. The F thread fuse atoms before locking ++ therefore current atom of thread F and current atom of thread ++ A became the same atom and thread A may proceed. This does ++ not work if node N was not captured because the fusion of ++ atom does not happens. ++ ++ The following scheme solves the deadlock: If ++ longterm_lock_znode locks and does not capture a znode, that ++ znode is marked as MISSED_IN_CAPTURE. A node marked this way ++ is processed by the code below which restores the missed ++ capture and fuses current atoms of all the node lock owners ++ by calling the fuse_not_fused_lock_owners() function. */ ++ if (JF_ISSET(node, JNODE_MISSED_IN_CAPTURE)) { ++ JF_CLR(node, JNODE_MISSED_IN_CAPTURE); ++ if (jnode_is_znode(node) && znode_is_locked(JZNODE(node))) { ++ spin_unlock_txnh(txnh); ++ spin_unlock_jnode(node); ++ fuse_not_fused_lock_owners(txnh, JZNODE(node)); ++ return RETERR(-E_REPEAT); ++ } ++ } ++ if (block_atom == NULL) { ++ atomic_inc(&txnh_atom->refcount); ++ spin_unlock_txnh(txnh); ++ if (!spin_trylock_atom(txnh_atom)) { ++ spin_unlock_jnode(node); ++ spin_lock_atom(txnh_atom); ++ spin_lock_jnode(node); ++ } ++ if (txnh->atom != txnh_atom || node->atom != NULL ++ || JF_ISSET(node, JNODE_IS_DYING)) { ++ spin_unlock_jnode(node); ++ atom_dec_and_unlock(txnh_atom); ++ return RETERR(-E_REPEAT); ++ } ++ atomic_dec(&txnh_atom->refcount); ++ capture_assign_block_nolock(txnh_atom, node); ++ spin_unlock_atom(txnh_atom); ++ } else { ++ if (txnh_atom != block_atom) { ++ if (mode & TXN_CAPTURE_DONT_FUSE) { ++ spin_unlock_txnh(txnh); ++ spin_unlock_jnode(node); ++ /* we are in a "no-fusion" mode and @node is ++ * already part of transaction. */ ++ return RETERR(-E_NO_NEIGHBOR); ++ } ++ return capture_init_fusion(node, txnh, mode); ++ } ++ spin_unlock_txnh(txnh); ++ } ++ } ++ return 0; ++} ++ ++static txn_capture ++build_capture_mode(jnode * node, znode_lock_mode lock_mode, txn_capture flags) ++{ ++ txn_capture cap_mode; ++ ++ assert_spin_locked(&(node->guard)); ++ ++ /* FIXME_JMACD No way to set TXN_CAPTURE_READ_MODIFY yet. */ ++ ++ if (lock_mode == ZNODE_WRITE_LOCK) { ++ cap_mode = TXN_CAPTURE_WRITE; ++ } else if (node->atom != NULL) { ++ cap_mode = TXN_CAPTURE_WRITE; ++ } else if (0 && /* txnh->mode == TXN_READ_FUSING && */ ++ jnode_get_level(node) == LEAF_LEVEL) { ++ /* NOTE-NIKITA TXN_READ_FUSING is not currently used */ ++ /* We only need a READ_FUSING capture at the leaf level. This ++ is because the internal levels of the tree (twigs included) ++ are redundant from the point of the user that asked for a ++ read-fusing transcrash. The user only wants to read-fuse ++ atoms due to reading uncommitted data that another user has ++ written. It is the file system that reads/writes the ++ internal tree levels, the user only reads/writes leaves. */ ++ cap_mode = TXN_CAPTURE_READ_ATOMIC; ++ } else { ++ /* In this case (read lock at a non-leaf) there's no reason to ++ * capture. */ ++ /* cap_mode = TXN_CAPTURE_READ_NONCOM; */ ++ return 0; ++ } ++ ++ cap_mode |= (flags & (TXN_CAPTURE_NONBLOCKING | TXN_CAPTURE_DONT_FUSE)); ++ assert("nikita-3186", cap_mode != 0); ++ return cap_mode; ++} ++ ++/* This is an external interface to try_capture_block(), it calls ++ try_capture_block() repeatedly as long as -E_REPEAT is returned. ++ ++ @node: node to capture, ++ @lock_mode: read or write lock is used in capture mode calculation, ++ @flags: see txn_capture flags enumeration, ++ @can_coc : can copy-on-capture ++ ++ @return: 0 - node was successfully captured, -E_REPEAT - capture request ++ cannot be processed immediately as it was requested in flags, ++ < 0 - other errors. ++*/ ++int reiser4_try_capture(jnode *node, znode_lock_mode lock_mode, ++ txn_capture flags) ++{ ++ txn_atom *atom_alloc = NULL; ++ txn_capture cap_mode; ++ txn_handle *txnh = get_current_context()->trans; ++ int ret; ++ ++ assert_spin_locked(&(node->guard)); ++ ++ repeat: ++ if (JF_ISSET(node, JNODE_IS_DYING)) ++ return RETERR(-EINVAL); ++ if (node->atom != NULL && txnh->atom == node->atom) ++ return 0; ++ cap_mode = build_capture_mode(node, lock_mode, flags); ++ if (cap_mode == 0 || ++ (!(cap_mode & TXN_CAPTURE_WTYPES) && node->atom == NULL)) { ++ /* Mark this node as "MISSED". It helps in further deadlock ++ * analysis */ ++ if (jnode_is_znode(node)) ++ JF_SET(node, JNODE_MISSED_IN_CAPTURE); ++ return 0; ++ } ++ /* Repeat try_capture as long as -E_REPEAT is returned. */ ++ ret = try_capture_block(txnh, node, cap_mode, &atom_alloc); ++ /* Regardless of non_blocking: ++ ++ If ret == 0 then jnode is still locked. ++ If ret != 0 then jnode is unlocked. ++ */ ++#if REISER4_DEBUG ++ if (ret == 0) ++ assert_spin_locked(&(node->guard)); ++ else ++ assert_spin_not_locked(&(node->guard)); ++#endif ++ assert_spin_not_locked(&(txnh->guard)); ++ ++ if (ret == -E_REPEAT) { ++ /* E_REPEAT implies all locks were released, therefore we need ++ to take the jnode's lock again. */ ++ spin_lock_jnode(node); ++ ++ /* Although this may appear to be a busy loop, it is not. ++ There are several conditions that cause E_REPEAT to be ++ returned by the call to try_capture_block, all cases ++ indicating some kind of state change that means you should ++ retry the request and will get a different result. In some ++ cases this could be avoided with some extra code, but ++ generally it is done because the necessary locks were ++ released as a result of the operation and repeating is the ++ simplest thing to do (less bug potential). The cases are: ++ atom fusion returns E_REPEAT after it completes (jnode and ++ txnh were unlocked); race conditions in assign_block, ++ assign_txnh, and init_fusion return E_REPEAT (trylock ++ failure); after going to sleep in capture_fuse_wait ++ (request was blocked but may now succeed). I'm not quite ++ sure how capture_copy works yet, but it may also return ++ E_REPEAT. When the request is legitimately blocked, the ++ requestor goes to sleep in fuse_wait, so this is not a busy ++ loop. */ ++ /* NOTE-NIKITA: still don't understand: ++ ++ try_capture_block->capture_assign_txnh->spin_trylock_atom->E_REPEAT ++ ++ looks like busy loop? ++ */ ++ goto repeat; ++ } ++ ++ /* free extra atom object that was possibly allocated by ++ try_capture_block(). ++ ++ Do this before acquiring jnode spin lock to ++ minimize time spent under lock. --nikita */ ++ if (atom_alloc != NULL) { ++ kmem_cache_free(_atom_slab, atom_alloc); ++ } ++ ++ if (ret != 0) { ++ if (ret == -E_BLOCK) { ++ assert("nikita-3360", ++ cap_mode & TXN_CAPTURE_NONBLOCKING); ++ ret = -E_REPEAT; ++ } ++ ++ /* Failure means jnode is not locked. FIXME_LATER_JMACD May ++ want to fix the above code to avoid releasing the lock and ++ re-acquiring it, but there are cases were failure occurs ++ when the lock is not held, and those cases would need to be ++ modified to re-take the lock. */ ++ spin_lock_jnode(node); ++ } ++ ++ /* Jnode is still locked. */ ++ assert_spin_locked(&(node->guard)); ++ return ret; ++} ++ ++static void release_two_atoms(txn_atom *one, txn_atom *two) ++{ ++ spin_unlock_atom(one); ++ atom_dec_and_unlock(two); ++ spin_lock_atom(one); ++ atom_dec_and_unlock(one); ++} ++ ++/* This function sets up a call to try_capture_block and repeats as long as -E_REPEAT is ++ returned by that routine. The txn_capture request mode is computed here depending on ++ the transaction handle's type and the lock request. This is called from the depths of ++ the lock manager with the jnode lock held and it always returns with the jnode lock ++ held. ++*/ ++ ++/* fuse all 'active' atoms of lock owners of given node. */ ++static void fuse_not_fused_lock_owners(txn_handle * txnh, znode * node) ++{ ++ lock_handle *lh; ++ int repeat; ++ txn_atom *atomh, *atomf; ++ reiser4_context *me = get_current_context(); ++ reiser4_context *ctx = NULL; ++ ++ assert_spin_not_locked(&(ZJNODE(node)->guard)); ++ assert_spin_not_locked(&(txnh->hlock)); ++ ++ repeat: ++ repeat = 0; ++ atomh = txnh_get_atom(txnh); ++ spin_unlock_txnh(txnh); ++ assert("zam-692", atomh != NULL); ++ ++ spin_lock_zlock(&node->lock); ++ /* inspect list of lock owners */ ++ list_for_each_entry(lh, &node->lock.owners, owners_link) { ++ ctx = get_context_by_lock_stack(lh->owner); ++ if (ctx == me) ++ continue; ++ /* below we use two assumptions to avoid addition spin-locks ++ for checking the condition : ++ ++ 1) if the lock stack has lock, the transaction should be ++ opened, i.e. ctx->trans != NULL; ++ ++ 2) reading of well-aligned ctx->trans->atom is atomic, if it ++ equals to the address of spin-locked atomh, we take that ++ the atoms are the same, nothing has to be captured. */ ++ if (atomh != ctx->trans->atom) { ++ reiser4_wake_up(lh->owner); ++ repeat = 1; ++ break; ++ } ++ } ++ if (repeat) { ++ if (!spin_trylock_txnh(ctx->trans)) { ++ spin_unlock_zlock(&node->lock); ++ spin_unlock_atom(atomh); ++ goto repeat; ++ } ++ atomf = ctx->trans->atom; ++ if (atomf == NULL) { ++ capture_assign_txnh_nolock(atomh, ctx->trans); ++ /* release zlock lock _after_ assigning the atom to the ++ * transaction handle, otherwise the lock owner thread ++ * may unlock all znodes, exit kernel context and here ++ * we would access an invalid transaction handle. */ ++ spin_unlock_zlock(&node->lock); ++ spin_unlock_atom(atomh); ++ spin_unlock_txnh(ctx->trans); ++ goto repeat; ++ } ++ assert("zam-1059", atomf != atomh); ++ spin_unlock_zlock(&node->lock); ++ atomic_inc(&atomh->refcount); ++ atomic_inc(&atomf->refcount); ++ spin_unlock_txnh(ctx->trans); ++ if (atomf > atomh) { ++ spin_lock_atom_nested(atomf); ++ } else { ++ spin_unlock_atom(atomh); ++ spin_lock_atom(atomf); ++ spin_lock_atom_nested(atomh); ++ } ++ if (atomh == atomf || !atom_isopen(atomh) || !atom_isopen(atomf)) { ++ release_two_atoms(atomf, atomh); ++ goto repeat; ++ } ++ atomic_dec(&atomh->refcount); ++ atomic_dec(&atomf->refcount); ++ capture_fuse_into(atomf, atomh); ++ goto repeat; ++ } ++ spin_unlock_zlock(&node->lock); ++ spin_unlock_atom(atomh); ++} ++ ++/* This is the interface to capture unformatted nodes via their struct page ++ reference. Currently it is only used in reiser4_invalidatepage */ ++int try_capture_page_to_invalidate(struct page *pg) ++{ ++ int ret; ++ jnode *node; ++ ++ assert("umka-292", pg != NULL); ++ assert("nikita-2597", PageLocked(pg)); ++ ++ if (IS_ERR(node = jnode_of_page(pg))) { ++ return PTR_ERR(node); ++ } ++ ++ spin_lock_jnode(node); ++ unlock_page(pg); ++ ++ ret = reiser4_try_capture(node, ZNODE_WRITE_LOCK, 0); ++ spin_unlock_jnode(node); ++ jput(node); ++ lock_page(pg); ++ return ret; ++} ++ ++/* This informs the transaction manager when a node is deleted. Add the block to the ++ atom's delete set and uncapture the block. ++ ++VS-FIXME-HANS: this E_REPEAT paradigm clutters the code and creates a need for ++explanations. find all the functions that use it, and unless there is some very ++good reason to use it (I have not noticed one so far and I doubt it exists, but maybe somewhere somehow....), ++move the loop to inside the function. ++ ++VS-FIXME-HANS: can this code be at all streamlined? In particular, can you lock and unlock the jnode fewer times? ++ */ ++void reiser4_uncapture_page(struct page *pg) ++{ ++ jnode *node; ++ txn_atom *atom; ++ ++ assert("umka-199", pg != NULL); ++ assert("nikita-3155", PageLocked(pg)); ++ ++ clear_page_dirty_for_io(pg); ++ ++ reiser4_wait_page_writeback(pg); ++ ++ node = jprivate(pg); ++ BUG_ON(node == NULL); ++ ++ spin_lock_jnode(node); ++ ++ atom = jnode_get_atom(node); ++ if (atom == NULL) { ++ assert("jmacd-7111", !JF_ISSET(node, JNODE_DIRTY)); ++ spin_unlock_jnode(node); ++ return; ++ } ++ ++ /* We can remove jnode from transaction even if it is on flush queue ++ * prepped list, we only need to be sure that flush queue is not being ++ * written by reiser4_write_fq(). reiser4_write_fq() does not use atom ++ * spin lock for protection of the prepped nodes list, instead ++ * write_fq() increments atom's nr_running_queues counters for the time ++ * when prepped list is not protected by spin lock. Here we check this ++ * counter if we want to remove jnode from flush queue and, if the ++ * counter is not zero, wait all reiser4_write_fq() for this atom to ++ * complete. This is not significant overhead. */ ++ while (JF_ISSET(node, JNODE_FLUSH_QUEUED) && atom->nr_running_queues) { ++ spin_unlock_jnode(node); ++ /* ++ * at this moment we want to wait for "atom event", viz. wait ++ * until @node can be removed from flush queue. But ++ * reiser4_atom_wait_event() cannot be called with page locked, ++ * because it deadlocks with jnode_extent_write(). Unlock page, ++ * after making sure (through page_cache_get()) that it cannot ++ * be released from memory. ++ */ ++ page_cache_get(pg); ++ unlock_page(pg); ++ reiser4_atom_wait_event(atom); ++ lock_page(pg); ++ /* ++ * page may has been detached by ->writepage()->releasepage(). ++ */ ++ reiser4_wait_page_writeback(pg); ++ spin_lock_jnode(node); ++ page_cache_release(pg); ++ atom = jnode_get_atom(node); ++/* VS-FIXME-HANS: improve the commenting in this function */ ++ if (atom == NULL) { ++ spin_unlock_jnode(node); ++ return; ++ } ++ } ++ reiser4_uncapture_block(node); ++ spin_unlock_atom(atom); ++ jput(node); ++} ++ ++/* this is used in extent's kill hook to uncapture and unhash jnodes attached to ++ * inode's tree of jnodes */ ++void reiser4_uncapture_jnode(jnode * node) ++{ ++ txn_atom *atom; ++ ++ assert_spin_locked(&(node->guard)); ++ assert("", node->pg == 0); ++ ++ atom = jnode_get_atom(node); ++ if (atom == NULL) { ++ assert("jmacd-7111", !JF_ISSET(node, JNODE_DIRTY)); ++ spin_unlock_jnode(node); ++ return; ++ } ++ ++ reiser4_uncapture_block(node); ++ spin_unlock_atom(atom); ++ jput(node); ++} ++ ++/* No-locking version of assign_txnh. Sets the transaction handle's atom pointer, ++ increases atom refcount and txnh_count, adds to txnh_list. */ ++static void capture_assign_txnh_nolock(txn_atom *atom, txn_handle *txnh) ++{ ++ assert("umka-200", atom != NULL); ++ assert("umka-201", txnh != NULL); ++ ++ assert_spin_locked(&(txnh->hlock)); ++ assert_spin_locked(&(atom->alock)); ++ assert("jmacd-824", txnh->atom == NULL); ++ assert("nikita-3540", atom_isopen(atom)); ++ BUG_ON(txnh->atom != NULL); ++ ++ atomic_inc(&atom->refcount); ++ txnh->atom = atom; ++ reiser4_ctx_gfp_mask_set(); ++ list_add_tail(&txnh->txnh_link, &atom->txnh_list); ++ atom->txnh_count += 1; ++} ++ ++/* No-locking version of assign_block. Sets the block's atom pointer, references the ++ block, adds it to the clean or dirty capture_jnode list, increments capture_count. */ ++static void capture_assign_block_nolock(txn_atom *atom, jnode *node) ++{ ++ assert("umka-202", atom != NULL); ++ assert("umka-203", node != NULL); ++ assert_spin_locked(&(node->guard)); ++ assert_spin_locked(&(atom->alock)); ++ assert("jmacd-323", node->atom == NULL); ++ BUG_ON(!list_empty_careful(&node->capture_link)); ++ assert("nikita-3470", !JF_ISSET(node, JNODE_DIRTY)); ++ ++ /* Pointer from jnode to atom is not counted in atom->refcount. */ ++ node->atom = atom; ++ ++ list_add_tail(&node->capture_link, ATOM_CLEAN_LIST(atom)); ++ atom->capture_count += 1; ++ /* reference to jnode is acquired by atom. */ ++ jref(node); ++ ++ ON_DEBUG(count_jnode(atom, node, NOT_CAPTURED, CLEAN_LIST, 1)); ++ ++ LOCK_CNT_INC(t_refs); ++} ++ ++/* common code for dirtying both unformatted jnodes and formatted znodes. */ ++static void do_jnode_make_dirty(jnode * node, txn_atom * atom) ++{ ++ assert_spin_locked(&(node->guard)); ++ assert_spin_locked(&(atom->alock)); ++ assert("jmacd-3981", !JF_ISSET(node, JNODE_DIRTY)); ++ ++ JF_SET(node, JNODE_DIRTY); ++ ++ get_current_context()->nr_marked_dirty++; ++ ++ /* We grab2flush_reserve one additional block only if node was ++ not CREATED and jnode_flush did not sort it into neither ++ relocate set nor overwrite one. If node is in overwrite or ++ relocate set we assume that atom's flush reserved counter was ++ already adjusted. */ ++ if (!JF_ISSET(node, JNODE_CREATED) && !JF_ISSET(node, JNODE_RELOC) ++ && !JF_ISSET(node, JNODE_OVRWR) && jnode_is_leaf(node) ++ && !jnode_is_cluster_page(node)) { ++ assert("vs-1093", !reiser4_blocknr_is_fake(&node->blocknr)); ++ assert("vs-1506", *jnode_get_block(node) != 0); ++ grabbed2flush_reserved_nolock(atom, (__u64) 1); ++ JF_SET(node, JNODE_FLUSH_RESERVED); ++ } ++ ++ if (!JF_ISSET(node, JNODE_FLUSH_QUEUED)) { ++ /* If the atom is not set yet, it will be added to the appropriate list in ++ capture_assign_block_nolock. */ ++ /* Sometimes a node is set dirty before being captured -- the case for new ++ jnodes. In that case the jnode will be added to the appropriate list ++ in capture_assign_block_nolock. Another reason not to re-link jnode is ++ that jnode is on a flush queue (see flush.c for details) */ ++ ++ int level = jnode_get_level(node); ++ ++ assert("nikita-3152", !JF_ISSET(node, JNODE_OVRWR)); ++ assert("zam-654", atom->stage < ASTAGE_PRE_COMMIT); ++ assert("nikita-2607", 0 <= level); ++ assert("nikita-2606", level <= REAL_MAX_ZTREE_HEIGHT); ++ ++ /* move node to atom's dirty list */ ++ list_move_tail(&node->capture_link, ATOM_DIRTY_LIST(atom, level)); ++ ON_DEBUG(count_jnode ++ (atom, node, NODE_LIST(node), DIRTY_LIST, 1)); ++ } ++} ++ ++/* Set the dirty status for this (spin locked) jnode. */ ++void jnode_make_dirty_locked(jnode * node) ++{ ++ assert("umka-204", node != NULL); ++ assert_spin_locked(&(node->guard)); ++ ++ if (REISER4_DEBUG && rofs_jnode(node)) { ++ warning("nikita-3365", "Dirtying jnode on rofs"); ++ dump_stack(); ++ } ++ ++ /* Fast check for already dirty node */ ++ if (!JF_ISSET(node, JNODE_DIRTY)) { ++ txn_atom *atom; ++ ++ atom = jnode_get_atom(node); ++ assert("vs-1094", atom); ++ /* Check jnode dirty status again because node spin lock might ++ * be released inside jnode_get_atom(). */ ++ if (likely(!JF_ISSET(node, JNODE_DIRTY))) ++ do_jnode_make_dirty(node, atom); ++ spin_unlock_atom(atom); ++ } ++} ++ ++/* Set the dirty status for this znode. */ ++void znode_make_dirty(znode * z) ++{ ++ jnode *node; ++ struct page *page; ++ ++ assert("umka-204", z != NULL); ++ assert("nikita-3290", znode_above_root(z) || znode_is_loaded(z)); ++ assert("nikita-3560", znode_is_write_locked(z)); ++ ++ node = ZJNODE(z); ++ /* znode is longterm locked, we can check dirty bit without spinlock */ ++ if (JF_ISSET(node, JNODE_DIRTY)) { ++ /* znode is dirty already. All we have to do is to change znode version */ ++ z->version = znode_build_version(jnode_get_tree(node)); ++ return; ++ } ++ ++ spin_lock_jnode(node); ++ jnode_make_dirty_locked(node); ++ page = jnode_page(node); ++ if (page != NULL) { ++ /* this is useful assertion (allows one to check that no ++ * modifications are lost due to update of in-flight page), ++ * but it requires locking on page to check PG_writeback ++ * bit. */ ++ /* assert("nikita-3292", ++ !PageWriteback(page) || ZF_ISSET(z, JNODE_WRITEBACK)); */ ++ page_cache_get(page); ++ ++ /* jnode lock is not needed for the rest of ++ * znode_set_dirty(). */ ++ spin_unlock_jnode(node); ++ /* reiser4 file write code calls set_page_dirty for ++ * unformatted nodes, for formatted nodes we do it here. */ ++ set_page_dirty_notag(page); ++ page_cache_release(page); ++ /* bump version counter in znode */ ++ z->version = znode_build_version(jnode_get_tree(node)); ++ } else { ++ assert("zam-596", znode_above_root(JZNODE(node))); ++ spin_unlock_jnode(node); ++ } ++ ++ assert("nikita-1900", znode_is_write_locked(z)); ++ assert("jmacd-9777", node->atom != NULL); ++} ++ ++int reiser4_sync_atom(txn_atom * atom) ++{ ++ int result; ++ txn_handle *txnh; ++ ++ txnh = get_current_context()->trans; ++ ++ result = 0; ++ if (atom != NULL) { ++ if (atom->stage < ASTAGE_PRE_COMMIT) { ++ spin_lock_txnh(txnh); ++ capture_assign_txnh_nolock(atom, txnh); ++ result = force_commit_atom(txnh); ++ } else if (atom->stage < ASTAGE_POST_COMMIT) { ++ /* wait atom commit */ ++ reiser4_atom_wait_event(atom); ++ /* try once more */ ++ result = RETERR(-E_REPEAT); ++ } else ++ spin_unlock_atom(atom); ++ } ++ return result; ++} ++ ++#if REISER4_DEBUG ++ ++/* move jnode form one list to another ++ call this after atom->capture_count is updated */ ++void ++count_jnode(txn_atom * atom, jnode * node, atom_list old_list, ++ atom_list new_list, int check_lists) ++{ ++ struct list_head *pos; ++ ++ assert("zam-1018", atom_is_protected(atom)); ++ assert_spin_locked(&(node->guard)); ++ assert("", NODE_LIST(node) == old_list); ++ ++ switch (NODE_LIST(node)) { ++ case NOT_CAPTURED: ++ break; ++ case DIRTY_LIST: ++ assert("", atom->dirty > 0); ++ atom->dirty--; ++ break; ++ case CLEAN_LIST: ++ assert("", atom->clean > 0); ++ atom->clean--; ++ break; ++ case FQ_LIST: ++ assert("", atom->fq > 0); ++ atom->fq--; ++ break; ++ case WB_LIST: ++ assert("", atom->wb > 0); ++ atom->wb--; ++ break; ++ case OVRWR_LIST: ++ assert("", atom->ovrwr > 0); ++ atom->ovrwr--; ++ break; ++ default: ++ impossible("", ""); ++ } ++ ++ switch (new_list) { ++ case NOT_CAPTURED: ++ break; ++ case DIRTY_LIST: ++ atom->dirty++; ++ break; ++ case CLEAN_LIST: ++ atom->clean++; ++ break; ++ case FQ_LIST: ++ atom->fq++; ++ break; ++ case WB_LIST: ++ atom->wb++; ++ break; ++ case OVRWR_LIST: ++ atom->ovrwr++; ++ break; ++ default: ++ impossible("", ""); ++ } ++ ASSIGN_NODE_LIST(node, new_list); ++ if (0 && check_lists) { ++ int count; ++ tree_level level; ++ ++ count = 0; ++ ++ /* flush queue list */ ++ /* reiser4_check_fq(atom); */ ++ ++ /* dirty list */ ++ count = 0; ++ for (level = 0; level < REAL_MAX_ZTREE_HEIGHT + 1; level += 1) { ++ list_for_each(pos, ATOM_DIRTY_LIST(atom, level)) ++ count++; ++ } ++ if (count != atom->dirty) ++ warning("", "dirty counter %d, real %d\n", atom->dirty, ++ count); ++ ++ /* clean list */ ++ count = 0; ++ list_for_each(pos, ATOM_CLEAN_LIST(atom)) ++ count++; ++ if (count != atom->clean) ++ warning("", "clean counter %d, real %d\n", atom->clean, ++ count); ++ ++ /* wb list */ ++ count = 0; ++ list_for_each(pos, ATOM_WB_LIST(atom)) ++ count++; ++ if (count != atom->wb) ++ warning("", "wb counter %d, real %d\n", atom->wb, ++ count); ++ ++ /* overwrite list */ ++ count = 0; ++ list_for_each(pos, ATOM_OVRWR_LIST(atom)) ++ count++; ++ ++ if (count != atom->ovrwr) ++ warning("", "ovrwr counter %d, real %d\n", atom->ovrwr, ++ count); ++ } ++ assert("vs-1624", atom->num_queued == atom->fq); ++ if (atom->capture_count != ++ atom->dirty + atom->clean + atom->ovrwr + atom->wb + atom->fq) { ++ printk ++ ("count %d, dirty %d clean %d ovrwr %d wb %d fq %d\n", ++ atom->capture_count, atom->dirty, atom->clean, atom->ovrwr, ++ atom->wb, atom->fq); ++ assert("vs-1622", ++ atom->capture_count == ++ atom->dirty + atom->clean + atom->ovrwr + atom->wb + ++ atom->fq); ++ } ++} ++ ++#endif ++ ++/* Make node OVRWR and put it on atom->overwrite_nodes list, atom lock and jnode ++ * lock should be taken before calling this function. */ ++void jnode_make_wander_nolock(jnode * node) ++{ ++ txn_atom *atom; ++ ++ assert("nikita-2431", node != NULL); ++ assert("nikita-2432", !JF_ISSET(node, JNODE_RELOC)); ++ assert("nikita-3153", JF_ISSET(node, JNODE_DIRTY)); ++ assert("zam-897", !JF_ISSET(node, JNODE_FLUSH_QUEUED)); ++ assert("nikita-3367", !reiser4_blocknr_is_fake(jnode_get_block(node))); ++ ++ atom = node->atom; ++ ++ assert("zam-895", atom != NULL); ++ assert("zam-894", atom_is_protected(atom)); ++ ++ JF_SET(node, JNODE_OVRWR); ++ /* move node to atom's overwrite list */ ++ list_move_tail(&node->capture_link, ATOM_OVRWR_LIST(atom)); ++ ON_DEBUG(count_jnode(atom, node, DIRTY_LIST, OVRWR_LIST, 1)); ++} ++ ++/* Same as jnode_make_wander_nolock, but all necessary locks are taken inside ++ * this function. */ ++void jnode_make_wander(jnode * node) ++{ ++ txn_atom *atom; ++ ++ spin_lock_jnode(node); ++ atom = jnode_get_atom(node); ++ assert("zam-913", atom != NULL); ++ assert("zam-914", !JF_ISSET(node, JNODE_RELOC)); ++ ++ jnode_make_wander_nolock(node); ++ spin_unlock_atom(atom); ++ spin_unlock_jnode(node); ++} ++ ++/* this just sets RELOC bit */ ++static void jnode_make_reloc_nolock(flush_queue_t * fq, jnode * node) ++{ ++ assert_spin_locked(&(node->guard)); ++ assert("zam-916", JF_ISSET(node, JNODE_DIRTY)); ++ assert("zam-917", !JF_ISSET(node, JNODE_RELOC)); ++ assert("zam-918", !JF_ISSET(node, JNODE_OVRWR)); ++ assert("zam-920", !JF_ISSET(node, JNODE_FLUSH_QUEUED)); ++ assert("nikita-3367", !reiser4_blocknr_is_fake(jnode_get_block(node))); ++ jnode_set_reloc(node); ++} ++ ++/* Make znode RELOC and put it on flush queue */ ++void znode_make_reloc(znode * z, flush_queue_t * fq) ++{ ++ jnode *node; ++ txn_atom *atom; ++ ++ node = ZJNODE(z); ++ spin_lock_jnode(node); ++ ++ atom = jnode_get_atom(node); ++ assert("zam-919", atom != NULL); ++ ++ jnode_make_reloc_nolock(fq, node); ++ queue_jnode(fq, node); ++ ++ spin_unlock_atom(atom); ++ spin_unlock_jnode(node); ++ ++} ++ ++/* Make unformatted node RELOC and put it on flush queue */ ++void unformatted_make_reloc(jnode *node, flush_queue_t *fq) ++{ ++ assert("vs-1479", jnode_is_unformatted(node)); ++ ++ jnode_make_reloc_nolock(fq, node); ++ queue_jnode(fq, node); ++} ++ ++int reiser4_capture_super_block(struct super_block *s) ++{ ++ int result; ++ znode *uber; ++ lock_handle lh; ++ ++ init_lh(&lh); ++ result = get_uber_znode(reiser4_get_tree(s), ++ ZNODE_WRITE_LOCK, ZNODE_LOCK_LOPRI, &lh); ++ if (result) ++ return result; ++ ++ uber = lh.node; ++ /* Grabbing one block for superblock */ ++ result = reiser4_grab_space_force((__u64) 1, BA_RESERVED); ++ if (result != 0) ++ return result; ++ ++ znode_make_dirty(uber); ++ ++ done_lh(&lh); ++ return 0; ++} ++ ++/* Wakeup every handle on the atom's WAITFOR list */ ++static void wakeup_atom_waitfor_list(txn_atom * atom) ++{ ++ txn_wait_links *wlinks; ++ ++ assert("umka-210", atom != NULL); ++ ++ /* atom is locked */ ++ list_for_each_entry(wlinks, &atom->fwaitfor_list, _fwaitfor_link) { ++ if (wlinks->waitfor_cb == NULL || ++ wlinks->waitfor_cb(atom, wlinks)) ++ /* Wake up. */ ++ reiser4_wake_up(wlinks->_lock_stack); ++ } ++} ++ ++/* Wakeup every handle on the atom's WAITING list */ ++static void wakeup_atom_waiting_list(txn_atom * atom) ++{ ++ txn_wait_links *wlinks; ++ ++ assert("umka-211", atom != NULL); ++ ++ /* atom is locked */ ++ list_for_each_entry(wlinks, &atom->fwaiting_list, _fwaiting_link) { ++ if (wlinks->waiting_cb == NULL || ++ wlinks->waiting_cb(atom, wlinks)) ++ /* Wake up. */ ++ reiser4_wake_up(wlinks->_lock_stack); ++ } ++} ++ ++/* helper function used by capture_fuse_wait() to avoid "spurious wake-ups" */ ++static int wait_for_fusion(txn_atom * atom, txn_wait_links * wlinks) ++{ ++ assert("nikita-3330", atom != NULL); ++ assert_spin_locked(&(atom->alock)); ++ ++ /* atom->txnh_count == 1 is for waking waiters up if we are releasing ++ * last transaction handle. */ ++ return atom->stage != ASTAGE_CAPTURE_WAIT || atom->txnh_count == 1; ++} ++ ++/* The general purpose of this function is to wait on the first of two possible events. ++ The situation is that a handle (and its atom atomh) is blocked trying to capture a ++ block (i.e., node) but the node's atom (atomf) is in the CAPTURE_WAIT state. The ++ handle's atom (atomh) is not in the CAPTURE_WAIT state. However, atomh could fuse with ++ another atom or, due to age, enter the CAPTURE_WAIT state itself, at which point it ++ needs to unblock the handle to avoid deadlock. When the txnh is unblocked it will ++ proceed and fuse the two atoms in the CAPTURE_WAIT state. ++ ++ In other words, if either atomh or atomf change state, the handle will be awakened, ++ thus there are two lists per atom: WAITING and WAITFOR. ++ ++ This is also called by capture_assign_txnh with (atomh == NULL) to wait for atomf to ++ close but it is not assigned to an atom of its own. ++ ++ Lock ordering in this method: all four locks are held: JNODE_LOCK, TXNH_LOCK, ++ BOTH_ATOM_LOCKS. Result: all four locks are released. ++*/ ++static int capture_fuse_wait(txn_handle * txnh, txn_atom * atomf, ++ txn_atom * atomh, txn_capture mode) ++{ ++ int ret; ++ txn_wait_links wlinks; ++ ++ assert("umka-213", txnh != NULL); ++ assert("umka-214", atomf != NULL); ++ ++ if ((mode & TXN_CAPTURE_NONBLOCKING) != 0) { ++ spin_unlock_txnh(txnh); ++ spin_unlock_atom(atomf); ++ ++ if (atomh) { ++ spin_unlock_atom(atomh); ++ } ++ ++ return RETERR(-E_BLOCK); ++ } ++ ++ /* Initialize the waiting list links. */ ++ init_wlinks(&wlinks); ++ ++ /* Add txnh to atomf's waitfor list, unlock atomf. */ ++ list_add_tail(&wlinks._fwaitfor_link, &atomf->fwaitfor_list); ++ wlinks.waitfor_cb = wait_for_fusion; ++ atomic_inc(&atomf->refcount); ++ spin_unlock_atom(atomf); ++ ++ if (atomh) { ++ /* Add txnh to atomh's waiting list, unlock atomh. */ ++ list_add_tail(&wlinks._fwaiting_link, &atomh->fwaiting_list); ++ atomic_inc(&atomh->refcount); ++ spin_unlock_atom(atomh); ++ } ++ ++ /* Go to sleep. */ ++ spin_unlock_txnh(txnh); ++ ++ ret = reiser4_prepare_to_sleep(wlinks._lock_stack); ++ if (ret == 0) { ++ reiser4_go_to_sleep(wlinks._lock_stack); ++ ret = RETERR(-E_REPEAT); ++ } ++ ++ /* Remove from the waitfor list. */ ++ spin_lock_atom(atomf); ++ ++ list_del(&wlinks._fwaitfor_link); ++ atom_dec_and_unlock(atomf); ++ ++ if (atomh) { ++ /* Remove from the waiting list. */ ++ spin_lock_atom(atomh); ++ list_del(&wlinks._fwaiting_link); ++ atom_dec_and_unlock(atomh); ++ } ++ return ret; ++} ++ ++static void lock_two_atoms(txn_atom * one, txn_atom * two) ++{ ++ assert("zam-1067", one != two); ++ ++ /* lock the atom with lesser address first */ ++ if (one < two) { ++ spin_lock_atom(one); ++ spin_lock_atom_nested(two); ++ } else { ++ spin_lock_atom(two); ++ spin_lock_atom_nested(one); ++ } ++} ++ ++/* Perform the necessary work to prepare for fusing two atoms, which involves ++ * acquiring two atom locks in the proper order. If one of the node's atom is ++ * blocking fusion (i.e., it is in the CAPTURE_WAIT stage) and the handle's ++ * atom is not then the handle's request is put to sleep. If the node's atom ++ * is committing, then the node can be copy-on-captured. Otherwise, pick the ++ * atom with fewer pointers to be fused into the atom with more pointer and ++ * call capture_fuse_into. ++ */ ++static int capture_init_fusion(jnode *node, txn_handle *txnh, txn_capture mode) ++{ ++ txn_atom * txnh_atom = txnh->atom; ++ txn_atom * block_atom = node->atom; ++ ++ atomic_inc(&txnh_atom->refcount); ++ atomic_inc(&block_atom->refcount); ++ ++ spin_unlock_txnh(txnh); ++ spin_unlock_jnode(node); ++ ++ lock_two_atoms(txnh_atom, block_atom); ++ ++ if (txnh->atom != txnh_atom || node->atom != block_atom ) { ++ release_two_atoms(txnh_atom, block_atom); ++ return RETERR(-E_REPEAT); ++ } ++ ++ atomic_dec(&txnh_atom->refcount); ++ atomic_dec(&block_atom->refcount); ++ ++ assert ("zam-1066", atom_isopen(txnh_atom)); ++ ++ if (txnh_atom->stage >= block_atom->stage || ++ (block_atom->stage == ASTAGE_CAPTURE_WAIT && block_atom->txnh_count == 0)) { ++ capture_fuse_into(txnh_atom, block_atom); ++ return RETERR(-E_REPEAT); ++ } ++ spin_lock_txnh(txnh); ++ return capture_fuse_wait(txnh, block_atom, txnh_atom, mode); ++} ++ ++/* This function splices together two jnode lists (small and large) and sets all jnodes in ++ the small list to point to the large atom. Returns the length of the list. */ ++static int ++capture_fuse_jnode_lists(txn_atom *large, struct list_head *large_head, ++ struct list_head *small_head) ++{ ++ int count = 0; ++ jnode *node; ++ ++ assert("umka-218", large != NULL); ++ assert("umka-219", large_head != NULL); ++ assert("umka-220", small_head != NULL); ++ /* small atom should be locked also. */ ++ assert_spin_locked(&(large->alock)); ++ ++ /* For every jnode on small's capture list... */ ++ list_for_each_entry(node, small_head, capture_link) { ++ count += 1; ++ ++ /* With the jnode lock held, update atom pointer. */ ++ spin_lock_jnode(node); ++ node->atom = large; ++ spin_unlock_jnode(node); ++ } ++ ++ /* Splice the lists. */ ++ list_splice_init(small_head, large_head->prev); ++ ++ return count; ++} ++ ++/* This function splices together two txnh lists (small and large) and sets all txn handles in ++ the small list to point to the large atom. Returns the length of the list. */ ++static int ++capture_fuse_txnh_lists(txn_atom *large, struct list_head *large_head, ++ struct list_head *small_head) ++{ ++ int count = 0; ++ txn_handle *txnh; ++ ++ assert("umka-221", large != NULL); ++ assert("umka-222", large_head != NULL); ++ assert("umka-223", small_head != NULL); ++ ++ /* Adjust every txnh to the new atom. */ ++ list_for_each_entry(txnh, small_head, txnh_link) { ++ count += 1; ++ ++ /* With the txnh lock held, update atom pointer. */ ++ spin_lock_txnh(txnh); ++ txnh->atom = large; ++ spin_unlock_txnh(txnh); ++ } ++ ++ /* Splice the txn_handle list. */ ++ list_splice_init(small_head, large_head->prev); ++ ++ return count; ++} ++ ++/* This function fuses two atoms. The captured nodes and handles belonging to SMALL are ++ added to LARGE and their ->atom pointers are all updated. The associated counts are ++ updated as well, and any waiting handles belonging to either are awakened. Finally the ++ smaller atom's refcount is decremented. ++*/ ++static void capture_fuse_into(txn_atom * small, txn_atom * large) ++{ ++ int level; ++ unsigned zcount = 0; ++ unsigned tcount = 0; ++ ++ assert("umka-224", small != NULL); ++ assert("umka-225", small != NULL); ++ ++ assert_spin_locked(&(large->alock)); ++ assert_spin_locked(&(small->alock)); ++ ++ assert("jmacd-201", atom_isopen(small)); ++ assert("jmacd-202", atom_isopen(large)); ++ ++ /* Splice and update the per-level dirty jnode lists */ ++ for (level = 0; level < REAL_MAX_ZTREE_HEIGHT + 1; level += 1) { ++ zcount += ++ capture_fuse_jnode_lists(large, ++ ATOM_DIRTY_LIST(large, level), ++ ATOM_DIRTY_LIST(small, level)); ++ } ++ ++ /* Splice and update the [clean,dirty] jnode and txnh lists */ ++ zcount += ++ capture_fuse_jnode_lists(large, ATOM_CLEAN_LIST(large), ++ ATOM_CLEAN_LIST(small)); ++ zcount += ++ capture_fuse_jnode_lists(large, ATOM_OVRWR_LIST(large), ++ ATOM_OVRWR_LIST(small)); ++ zcount += ++ capture_fuse_jnode_lists(large, ATOM_WB_LIST(large), ++ ATOM_WB_LIST(small)); ++ zcount += ++ capture_fuse_jnode_lists(large, &large->inodes, &small->inodes); ++ tcount += ++ capture_fuse_txnh_lists(large, &large->txnh_list, ++ &small->txnh_list); ++ ++ /* Check our accounting. */ ++ assert("jmacd-1063", ++ zcount + small->num_queued == small->capture_count); ++ assert("jmacd-1065", tcount == small->txnh_count); ++ ++ /* sum numbers of waiters threads */ ++ large->nr_waiters += small->nr_waiters; ++ small->nr_waiters = 0; ++ ++ /* splice flush queues */ ++ reiser4_fuse_fq(large, small); ++ ++ /* update counter of jnode on every atom' list */ ++ ON_DEBUG(large->dirty += small->dirty; ++ small->dirty = 0; ++ large->clean += small->clean; ++ small->clean = 0; ++ large->ovrwr += small->ovrwr; ++ small->ovrwr = 0; ++ large->wb += small->wb; ++ small->wb = 0; ++ large->fq += small->fq; ++ small->fq = 0;); ++ ++ /* count flushers in result atom */ ++ large->nr_flushers += small->nr_flushers; ++ small->nr_flushers = 0; ++ ++ /* update counts of flushed nodes */ ++ large->flushed += small->flushed; ++ small->flushed = 0; ++ ++ /* Transfer list counts to large. */ ++ large->txnh_count += small->txnh_count; ++ large->capture_count += small->capture_count; ++ ++ /* Add all txnh references to large. */ ++ atomic_add(small->txnh_count, &large->refcount); ++ atomic_sub(small->txnh_count, &small->refcount); ++ ++ /* Reset small counts */ ++ small->txnh_count = 0; ++ small->capture_count = 0; ++ ++ /* Assign the oldest start_time, merge flags. */ ++ large->start_time = min(large->start_time, small->start_time); ++ large->flags |= small->flags; ++ ++ /* Merge blocknr sets. */ ++ blocknr_set_merge(&small->delete_set, &large->delete_set); ++ blocknr_set_merge(&small->wandered_map, &large->wandered_map); ++ ++ /* Merge allocated/deleted file counts */ ++ large->nr_objects_deleted += small->nr_objects_deleted; ++ large->nr_objects_created += small->nr_objects_created; ++ ++ small->nr_objects_deleted = 0; ++ small->nr_objects_created = 0; ++ ++ /* Merge allocated blocks counts */ ++ large->nr_blocks_allocated += small->nr_blocks_allocated; ++ ++ large->nr_running_queues += small->nr_running_queues; ++ small->nr_running_queues = 0; ++ ++ /* Merge blocks reserved for overwrite set. */ ++ large->flush_reserved += small->flush_reserved; ++ small->flush_reserved = 0; ++ ++ if (large->stage < small->stage) { ++ /* Large only needs to notify if it has changed state. */ ++ reiser4_atom_set_stage(large, small->stage); ++ wakeup_atom_waiting_list(large); ++ } ++ ++ reiser4_atom_set_stage(small, ASTAGE_INVALID); ++ ++ /* Notify any waiters--small needs to unload its wait lists. Waiters ++ actually remove themselves from the list before returning from the ++ fuse_wait function. */ ++ wakeup_atom_waiting_list(small); ++ ++ /* Unlock atoms */ ++ spin_unlock_atom(large); ++ atom_dec_and_unlock(small); ++} ++ ++/* TXNMGR STUFF */ ++ ++/* Release a block from the atom, reversing the effects of being captured, ++ do not release atom's reference to jnode due to holding spin-locks. ++ Currently this is only called when the atom commits. ++ ++ NOTE: this function does not release a (journal) reference to jnode ++ due to locking optimizations, you should call jput() somewhere after ++ calling reiser4_uncapture_block(). */ ++void reiser4_uncapture_block(jnode * node) ++{ ++ txn_atom *atom; ++ ++ assert("umka-226", node != NULL); ++ atom = node->atom; ++ assert("umka-228", atom != NULL); ++ ++ assert("jmacd-1021", node->atom == atom); ++ assert_spin_locked(&(node->guard)); ++ assert("jmacd-1023", atom_is_protected(atom)); ++ ++ JF_CLR(node, JNODE_DIRTY); ++ JF_CLR(node, JNODE_RELOC); ++ JF_CLR(node, JNODE_OVRWR); ++ JF_CLR(node, JNODE_CREATED); ++ JF_CLR(node, JNODE_WRITEBACK); ++ JF_CLR(node, JNODE_REPACK); ++ ++ list_del_init(&node->capture_link); ++ if (JF_ISSET(node, JNODE_FLUSH_QUEUED)) { ++ assert("zam-925", atom_isopen(atom)); ++ assert("vs-1623", NODE_LIST(node) == FQ_LIST); ++ ON_DEBUG(atom->num_queued--); ++ JF_CLR(node, JNODE_FLUSH_QUEUED); ++ } ++ atom->capture_count -= 1; ++ ON_DEBUG(count_jnode(atom, node, NODE_LIST(node), NOT_CAPTURED, 1)); ++ node->atom = NULL; ++ ++ spin_unlock_jnode(node); ++ LOCK_CNT_DEC(t_refs); ++} ++ ++/* Unconditional insert of jnode into atom's overwrite list. Currently used in ++ bitmap-based allocator code for adding modified bitmap blocks the ++ transaction. @atom and @node are spin locked */ ++void insert_into_atom_ovrwr_list(txn_atom * atom, jnode * node) ++{ ++ assert("zam-538", atom_is_protected(atom)); ++ assert_spin_locked(&(node->guard)); ++ assert("zam-899", JF_ISSET(node, JNODE_OVRWR)); ++ assert("zam-543", node->atom == NULL); ++ assert("vs-1433", !jnode_is_unformatted(node) && !jnode_is_znode(node)); ++ ++ list_add(&node->capture_link, ATOM_OVRWR_LIST(atom)); ++ jref(node); ++ node->atom = atom; ++ atom->capture_count++; ++ ON_DEBUG(count_jnode(atom, node, NODE_LIST(node), OVRWR_LIST, 1)); ++} ++ ++static int count_deleted_blocks_actor(txn_atom * atom, ++ const reiser4_block_nr * a, ++ const reiser4_block_nr * b, void *data) ++{ ++ reiser4_block_nr *counter = data; ++ ++ assert("zam-995", data != NULL); ++ assert("zam-996", a != NULL); ++ if (b == NULL) ++ *counter += 1; ++ else ++ *counter += *b; ++ return 0; ++} ++ ++reiser4_block_nr txnmgr_count_deleted_blocks(void) ++{ ++ reiser4_block_nr result; ++ txn_mgr *tmgr = &get_super_private(reiser4_get_current_sb())->tmgr; ++ txn_atom *atom; ++ ++ result = 0; ++ ++ spin_lock_txnmgr(tmgr); ++ list_for_each_entry(atom, &tmgr->atoms_list, atom_link) { ++ spin_lock_atom(atom); ++ if (atom_isopen(atom)) ++ blocknr_set_iterator( ++ atom, &atom->delete_set, ++ count_deleted_blocks_actor, &result, 0); ++ spin_unlock_atom(atom); ++ } ++ spin_unlock_txnmgr(tmgr); ++ ++ return result; ++} ++ ++/* ++ * Local variables: ++ * c-indentation-style: "K&R" ++ * mode-name: "LC" ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * fill-column: 79 ++ * End: ++ */ +diff -urN linux-2.6.30.orig/fs/reiser4/txnmgr.h linux-2.6.30/fs/reiser4/txnmgr.h +--- linux-2.6.30.orig/fs/reiser4/txnmgr.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/txnmgr.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,701 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* data-types and function declarations for transaction manager. See txnmgr.c ++ * for details. */ ++ ++#ifndef __REISER4_TXNMGR_H__ ++#define __REISER4_TXNMGR_H__ ++ ++#include "forward.h" ++#include "dformat.h" ++ ++#include <linux/fs.h> ++#include <linux/mm.h> ++#include <linux/types.h> ++#include <linux/spinlock.h> ++#include <asm/atomic.h> ++#include <linux/wait.h> ++ ++/* TYPE DECLARATIONS */ ++ ++/* This enumeration describes the possible types of a capture request (reiser4_try_capture). ++ A capture request dynamically assigns a block to the calling thread's transaction ++ handle. */ ++typedef enum { ++ /* A READ_ATOMIC request indicates that a block will be read and that the caller's ++ atom should fuse in order to ensure that the block commits atomically with the ++ caller. */ ++ TXN_CAPTURE_READ_ATOMIC = (1 << 0), ++ ++ /* A READ_NONCOM request indicates that a block will be read and that the caller is ++ willing to read a non-committed block without causing atoms to fuse. */ ++ TXN_CAPTURE_READ_NONCOM = (1 << 1), ++ ++ /* A READ_MODIFY request indicates that a block will be read but that the caller ++ wishes for the block to be captured as it will be written. This capture request ++ mode is not currently used, but eventually it will be useful for preventing ++ deadlock in read-modify-write cycles. */ ++ TXN_CAPTURE_READ_MODIFY = (1 << 2), ++ ++ /* A WRITE capture request indicates that a block will be modified and that atoms ++ should fuse to make the commit atomic. */ ++ TXN_CAPTURE_WRITE = (1 << 3), ++ ++ /* CAPTURE_TYPES is a mask of the four above capture types, used to separate the ++ exclusive type designation from extra bits that may be supplied -- see ++ below. */ ++ TXN_CAPTURE_TYPES = (TXN_CAPTURE_READ_ATOMIC | ++ TXN_CAPTURE_READ_NONCOM | TXN_CAPTURE_READ_MODIFY | ++ TXN_CAPTURE_WRITE), ++ ++ /* A subset of CAPTURE_TYPES, CAPTURE_WTYPES is a mask of request types that ++ indicate modification will occur. */ ++ TXN_CAPTURE_WTYPES = (TXN_CAPTURE_READ_MODIFY | TXN_CAPTURE_WRITE), ++ ++ /* An option to reiser4_try_capture, NONBLOCKING indicates that the caller would ++ prefer not to sleep waiting for an aging atom to commit. */ ++ TXN_CAPTURE_NONBLOCKING = (1 << 4), ++ ++ /* An option to reiser4_try_capture to prevent atom fusion, just simple ++ capturing is allowed */ ++ TXN_CAPTURE_DONT_FUSE = (1 << 5) ++ ++ /* This macro selects only the exclusive capture request types, stripping out any ++ options that were supplied (i.e., NONBLOCKING). */ ++#define CAPTURE_TYPE(x) ((x) & TXN_CAPTURE_TYPES) ++} txn_capture; ++ ++/* There are two kinds of transaction handle: WRITE_FUSING and READ_FUSING, the only ++ difference is in the handling of read requests. A WRITE_FUSING transaction handle ++ defaults read capture requests to TXN_CAPTURE_READ_NONCOM whereas a READ_FUSIONG ++ transaction handle defaults to TXN_CAPTURE_READ_ATOMIC. */ ++typedef enum { ++ TXN_WRITE_FUSING = (1 << 0), ++ TXN_READ_FUSING = (1 << 1) | TXN_WRITE_FUSING, /* READ implies WRITE */ ++} txn_mode; ++ ++/* Every atom has a stage, which is one of these exclusive values: */ ++typedef enum { ++ /* Initially an atom is free. */ ++ ASTAGE_FREE = 0, ++ ++ /* An atom begins by entering the CAPTURE_FUSE stage, where it proceeds to capture ++ blocks and fuse with other atoms. */ ++ ASTAGE_CAPTURE_FUSE = 1, ++ ++ /* We need to have a ASTAGE_CAPTURE_SLOW in which an atom fuses with one node for every X nodes it flushes to disk where X > 1. */ ++ ++ /* When an atom reaches a certain age it must do all it can to commit. An atom in ++ the CAPTURE_WAIT stage refuses new transaction handles and prevents fusion from ++ atoms in the CAPTURE_FUSE stage. */ ++ ASTAGE_CAPTURE_WAIT = 2, ++ ++ /* Waiting for I/O before commit. Copy-on-capture (see ++ http://namesys.com/v4/v4.html). */ ++ ASTAGE_PRE_COMMIT = 3, ++ ++ /* Post-commit overwrite I/O. Steal-on-capture. */ ++ ASTAGE_POST_COMMIT = 4, ++ ++ /* Atom which waits for the removal of the last reference to (it? ) to ++ * be deleted from memory */ ++ ASTAGE_DONE = 5, ++ ++ /* invalid atom. */ ++ ASTAGE_INVALID = 6, ++ ++} txn_stage; ++ ++/* Certain flags may be set in the txn_atom->flags field. */ ++typedef enum { ++ /* Indicates that the atom should commit as soon as possible. */ ++ ATOM_FORCE_COMMIT = (1 << 0), ++ /* to avoid endless loop, mark the atom (which was considered as too ++ * small) after failed attempt to fuse it. */ ++ ATOM_CANCEL_FUSION = (1 << 1) ++} txn_flags; ++ ++/* Flags for controlling commit_txnh */ ++typedef enum { ++ /* Wait commit atom completion in commit_txnh */ ++ TXNH_WAIT_COMMIT = 0x2, ++ /* Don't commit atom when this handle is closed */ ++ TXNH_DONT_COMMIT = 0x4 ++} txn_handle_flags_t; ++ ++/* TYPE DEFINITIONS */ ++ ++/* A note on lock ordering: the handle & jnode spinlock protects reading of their ->atom ++ fields, so typically an operation on the atom through either of these objects must (1) ++ lock the object, (2) read the atom pointer, (3) lock the atom. ++ ++ During atom fusion, the process holds locks on both atoms at once. Then, it iterates ++ through the list of handles and pages held by the smaller of the two atoms. For each ++ handle and page referencing the smaller atom, the fusing process must: (1) lock the ++ object, and (2) update the atom pointer. ++ ++ You can see that there is a conflict of lock ordering here, so the more-complex ++ procedure should have priority, i.e., the fusing process has priority so that it is ++ guaranteed to make progress and to avoid restarts. ++ ++ This decision, however, means additional complexity for aquiring the atom lock in the ++ first place. ++ ++ The general original procedure followed in the code was: ++ ++ TXN_OBJECT *obj = ...; ++ TXN_ATOM *atom; ++ ++ spin_lock (& obj->_lock); ++ ++ atom = obj->_atom; ++ ++ if (! spin_trylock_atom (atom)) ++ { ++ spin_unlock (& obj->_lock); ++ RESTART OPERATION, THERE WAS A RACE; ++ } ++ ++ ELSE YOU HAVE BOTH ATOM AND OBJ LOCKED ++ ++ It has however been found that this wastes CPU a lot in a manner that is ++ hard to profile. So, proper refcounting was added to atoms, and new ++ standard locking sequence is like following: ++ ++ TXN_OBJECT *obj = ...; ++ TXN_ATOM *atom; ++ ++ spin_lock (& obj->_lock); ++ ++ atom = obj->_atom; ++ ++ if (! spin_trylock_atom (atom)) ++ { ++ atomic_inc (& atom->refcount); ++ spin_unlock (& obj->_lock); ++ spin_lock (&atom->_lock); ++ atomic_dec (& atom->refcount); ++ // HERE atom is locked ++ spin_unlock (&atom->_lock); ++ RESTART OPERATION, THERE WAS A RACE; ++ } ++ ++ ELSE YOU HAVE BOTH ATOM AND OBJ LOCKED ++ ++ (core of this is implemented in trylock_throttle() function) ++ ++ See the jnode_get_atom() function for a common case. ++ ++ As an additional (and important) optimization allowing to avoid restarts, ++ it is possible to re-check required pre-conditions at the HERE point in ++ code above and proceed without restarting if they are still satisfied. ++*/ ++ ++/* An atomic transaction: this is the underlying system representation ++ of a transaction, not the one seen by clients. ++ ++ Invariants involving this data-type: ++ ++ [sb-fake-allocated] ++*/ ++struct txn_atom { ++ /* The spinlock protecting the atom, held during fusion and various other state ++ changes. */ ++ spinlock_t alock; ++ ++ /* The atom's reference counter, increasing (in case of a duplication ++ of an existing reference or when we are sure that some other ++ reference exists) may be done without taking spinlock, decrementing ++ of the ref. counter requires a spinlock to be held. ++ ++ Each transaction handle counts in ->refcount. All jnodes count as ++ one reference acquired in atom_begin_andlock(), released in ++ commit_current_atom(). ++ */ ++ atomic_t refcount; ++ ++ /* The atom_id identifies the atom in persistent records such as the log. */ ++ __u32 atom_id; ++ ++ /* Flags holding any of the txn_flags enumerated values (e.g., ++ ATOM_FORCE_COMMIT). */ ++ __u32 flags; ++ ++ /* Number of open handles. */ ++ __u32 txnh_count; ++ ++ /* The number of znodes captured by this atom. Equal to the sum of lengths of the ++ dirty_nodes[level] and clean_nodes lists. */ ++ __u32 capture_count; ++ ++#if REISER4_DEBUG ++ int clean; ++ int dirty; ++ int ovrwr; ++ int wb; ++ int fq; ++#endif ++ ++ __u32 flushed; ++ ++ /* Current transaction stage. */ ++ txn_stage stage; ++ ++ /* Start time. */ ++ unsigned long start_time; ++ ++ /* The atom's delete set. It collects block numbers of the nodes ++ which were deleted during the transaction. */ ++ struct list_head delete_set; ++ ++ /* The atom's wandered_block mapping. */ ++ struct list_head wandered_map; ++ ++ /* The transaction's list of dirty captured nodes--per level. Index ++ by (level). dirty_nodes[0] is for znode-above-root */ ++ struct list_head dirty_nodes[REAL_MAX_ZTREE_HEIGHT + 1]; ++ ++ /* The transaction's list of clean captured nodes. */ ++ struct list_head clean_nodes; ++ ++ /* The atom's overwrite set */ ++ struct list_head ovrwr_nodes; ++ ++ /* nodes which are being written to disk */ ++ struct list_head writeback_nodes; ++ ++ /* list of inodes */ ++ struct list_head inodes; ++ ++ /* List of handles associated with this atom. */ ++ struct list_head txnh_list; ++ ++ /* Transaction list link: list of atoms in the transaction manager. */ ++ struct list_head atom_link; ++ ++ /* List of handles waiting FOR this atom: see 'capture_fuse_wait' comment. */ ++ struct list_head fwaitfor_list; ++ ++ /* List of this atom's handles that are waiting: see 'capture_fuse_wait' comment. */ ++ struct list_head fwaiting_list; ++ ++ /* Numbers of objects which were deleted/created in this transaction ++ thereby numbers of objects IDs which were released/deallocated. */ ++ int nr_objects_deleted; ++ int nr_objects_created; ++ /* number of blocks allocated during the transaction */ ++ __u64 nr_blocks_allocated; ++ /* All atom's flush queue objects are on this list */ ++ struct list_head flush_queues; ++#if REISER4_DEBUG ++ /* number of flush queues for this atom. */ ++ int nr_flush_queues; ++ /* Number of jnodes which were removed from atom's lists and put ++ on flush_queue */ ++ int num_queued; ++#endif ++ /* number of threads who wait for this atom to complete commit */ ++ int nr_waiters; ++ /* number of threads which do jnode_flush() over this atom */ ++ int nr_flushers; ++ /* number of flush queues which are IN_USE and jnodes from fq->prepped ++ are submitted to disk by the reiser4_write_fq() routine. */ ++ int nr_running_queues; ++ /* A counter of grabbed unformatted nodes, see a description of the ++ * reiser4 space reservation scheme at block_alloc.c */ ++ reiser4_block_nr flush_reserved; ++#if REISER4_DEBUG ++ void *committer; ++#endif ++ struct super_block *super; ++}; ++ ++#define ATOM_DIRTY_LIST(atom, level) (&(atom)->dirty_nodes[level]) ++#define ATOM_CLEAN_LIST(atom) (&(atom)->clean_nodes) ++#define ATOM_OVRWR_LIST(atom) (&(atom)->ovrwr_nodes) ++#define ATOM_WB_LIST(atom) (&(atom)->writeback_nodes) ++#define ATOM_FQ_LIST(fq) (&(fq)->prepped) ++ ++#define NODE_LIST(node) (node)->list ++#define ASSIGN_NODE_LIST(node, list) ON_DEBUG(NODE_LIST(node) = list) ++ON_DEBUG(void ++ count_jnode(txn_atom *, jnode *, atom_list old_list, ++ atom_list new_list, int check_lists)); ++ ++/* A transaction handle: the client obtains and commits this handle which is assigned by ++ the system to a txn_atom. */ ++struct txn_handle { ++ /* Spinlock protecting ->atom pointer */ ++ spinlock_t hlock; ++ ++ /* Flags for controlling commit_txnh() behavior */ ++ /* from txn_handle_flags_t */ ++ txn_handle_flags_t flags; ++ ++ /* Whether it is READ_FUSING or WRITE_FUSING. */ ++ txn_mode mode; ++ ++ /* If assigned, the atom it is part of. */ ++ txn_atom *atom; ++ ++ /* Transaction list link. Head is in txn_atom. */ ++ struct list_head txnh_link; ++}; ++ ++/* The transaction manager: one is contained in the reiser4_super_info_data */ ++struct txn_mgr { ++ /* A spinlock protecting the atom list, id_count, flush_control */ ++ spinlock_t tmgr_lock; ++ ++ /* List of atoms. */ ++ struct list_head atoms_list; ++ ++ /* Number of atoms. */ ++ int atom_count; ++ ++ /* A counter used to assign atom->atom_id values. */ ++ __u32 id_count; ++ ++ /* a mutex object for commit serialization */ ++ struct mutex commit_mutex; ++ ++ /* a list of all txnmrgs served by particular daemon. */ ++ struct list_head linkage; ++ ++ /* description of daemon for this txnmgr */ ++ ktxnmgrd_context *daemon; ++ ++ /* parameters. Adjustable through mount options. */ ++ unsigned int atom_max_size; ++ unsigned int atom_max_age; ++ unsigned int atom_min_size; ++ /* max number of concurrent flushers for one atom, 0 - unlimited. */ ++ unsigned int atom_max_flushers; ++ struct dentry *debugfs_atom_count; ++ struct dentry *debugfs_id_count; ++}; ++ ++/* FUNCTION DECLARATIONS */ ++ ++/* These are the externally (within Reiser4) visible transaction functions, therefore they ++ are prefixed with "txn_". For comments, see txnmgr.c. */ ++ ++extern int init_txnmgr_static(void); ++extern void done_txnmgr_static(void); ++ ++extern void reiser4_init_txnmgr(txn_mgr *); ++extern void reiser4_done_txnmgr(txn_mgr *); ++ ++extern int reiser4_txn_reserve(int reserved); ++ ++extern void reiser4_txn_begin(reiser4_context * context); ++extern int reiser4_txn_end(reiser4_context * context); ++ ++extern void reiser4_txn_restart(reiser4_context * context); ++extern void reiser4_txn_restart_current(void); ++ ++extern int txnmgr_force_commit_all(struct super_block *, int); ++extern int current_atom_should_commit(void); ++ ++extern jnode *find_first_dirty_jnode(txn_atom *, int); ++ ++extern int commit_some_atoms(txn_mgr *); ++extern int force_commit_atom(txn_handle *); ++extern int flush_current_atom(int, long, long *, txn_atom **, jnode *); ++ ++extern int flush_some_atom(jnode *, long *, const struct writeback_control *, int); ++ ++extern void reiser4_atom_set_stage(txn_atom * atom, txn_stage stage); ++ ++extern int same_slum_check(jnode * base, jnode * check, int alloc_check, ++ int alloc_value); ++extern void atom_dec_and_unlock(txn_atom * atom); ++ ++extern int reiser4_try_capture(jnode * node, znode_lock_mode mode, txn_capture flags); ++extern int try_capture_page_to_invalidate(struct page *pg); ++ ++extern void reiser4_uncapture_page(struct page *pg); ++extern void reiser4_uncapture_block(jnode *); ++extern void reiser4_uncapture_jnode(jnode *); ++ ++extern int reiser4_capture_inode(struct inode *); ++extern int reiser4_uncapture_inode(struct inode *); ++ ++extern txn_atom *get_current_atom_locked_nocheck(void); ++ ++#if REISER4_DEBUG ++ ++/** ++ * atom_is_protected - make sure that nobody but us can do anything with atom ++ * @atom: atom to be checked ++ * ++ * This is used to assert that atom either entered commit stages or is spin ++ * locked. ++ */ ++static inline int atom_is_protected(txn_atom *atom) ++{ ++ if (atom->stage >= ASTAGE_PRE_COMMIT) ++ return 1; ++ assert_spin_locked(&(atom->alock)); ++ return 1; ++} ++ ++#endif ++ ++/* Get the current atom and spinlock it if current atom present. May not return NULL */ ++static inline txn_atom *get_current_atom_locked(void) ++{ ++ txn_atom *atom; ++ ++ atom = get_current_atom_locked_nocheck(); ++ assert("zam-761", atom != NULL); ++ ++ return atom; ++} ++ ++extern txn_atom *jnode_get_atom(jnode *); ++ ++extern void reiser4_atom_wait_event(txn_atom *); ++extern void reiser4_atom_send_event(txn_atom *); ++ ++extern void insert_into_atom_ovrwr_list(txn_atom * atom, jnode * node); ++extern int reiser4_capture_super_block(struct super_block *s); ++int capture_bulk(jnode **, int count); ++ ++/* See the comment on the function blocknrset.c:blocknr_set_add for the ++ calling convention of these three routines. */ ++extern void blocknr_set_init(struct list_head * bset); ++extern void blocknr_set_destroy(struct list_head * bset); ++extern void blocknr_set_merge(struct list_head * from, struct list_head * into); ++extern int blocknr_set_add_extent(txn_atom * atom, ++ struct list_head * bset, ++ blocknr_set_entry ** new_bsep, ++ const reiser4_block_nr * start, ++ const reiser4_block_nr * len); ++extern int blocknr_set_add_pair(txn_atom * atom, struct list_head * bset, ++ blocknr_set_entry ** new_bsep, ++ const reiser4_block_nr * a, ++ const reiser4_block_nr * b); ++ ++typedef int (*blocknr_set_actor_f) (txn_atom *, const reiser4_block_nr *, ++ const reiser4_block_nr *, void *); ++ ++extern int blocknr_set_iterator(txn_atom * atom, struct list_head * bset, ++ blocknr_set_actor_f actor, void *data, ++ int delete); ++ ++/* flush code takes care about how to fuse flush queues */ ++extern void flush_init_atom(txn_atom * atom); ++extern void flush_fuse_queues(txn_atom * large, txn_atom * small); ++ ++static inline void spin_lock_atom(txn_atom *atom) ++{ ++ /* check that spinlocks of lower priorities are not held */ ++ assert("", (LOCK_CNT_NIL(spin_locked_txnh) && ++ LOCK_CNT_NIL(spin_locked_atom) && ++ LOCK_CNT_NIL(spin_locked_jnode) && ++ LOCK_CNT_NIL(spin_locked_zlock) && ++ LOCK_CNT_NIL(rw_locked_dk) && ++ LOCK_CNT_NIL(rw_locked_tree))); ++ ++ spin_lock(&(atom->alock)); ++ ++ LOCK_CNT_INC(spin_locked_atom); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline void spin_lock_atom_nested(txn_atom *atom) ++{ ++ assert("", (LOCK_CNT_NIL(spin_locked_txnh) && ++ LOCK_CNT_NIL(spin_locked_jnode) && ++ LOCK_CNT_NIL(spin_locked_zlock) && ++ LOCK_CNT_NIL(rw_locked_dk) && ++ LOCK_CNT_NIL(rw_locked_tree))); ++ ++ spin_lock_nested(&(atom->alock), SINGLE_DEPTH_NESTING); ++ ++ LOCK_CNT_INC(spin_locked_atom); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline int spin_trylock_atom(txn_atom *atom) ++{ ++ if (spin_trylock(&(atom->alock))) { ++ LOCK_CNT_INC(spin_locked_atom); ++ LOCK_CNT_INC(spin_locked); ++ return 1; ++ } ++ return 0; ++} ++ ++static inline void spin_unlock_atom(txn_atom *atom) ++{ ++ assert_spin_locked(&(atom->alock)); ++ assert("nikita-1375", LOCK_CNT_GTZ(spin_locked_atom)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ LOCK_CNT_DEC(spin_locked_atom); ++ LOCK_CNT_DEC(spin_locked); ++ ++ spin_unlock(&(atom->alock)); ++} ++ ++static inline void spin_lock_txnh(txn_handle *txnh) ++{ ++ /* check that spinlocks of lower priorities are not held */ ++ assert("", (LOCK_CNT_NIL(rw_locked_dk) && ++ LOCK_CNT_NIL(spin_locked_zlock) && ++ LOCK_CNT_NIL(rw_locked_tree))); ++ ++ spin_lock(&(txnh->hlock)); ++ ++ LOCK_CNT_INC(spin_locked_txnh); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline int spin_trylock_txnh(txn_handle *txnh) ++{ ++ if (spin_trylock(&(txnh->hlock))) { ++ LOCK_CNT_INC(spin_locked_txnh); ++ LOCK_CNT_INC(spin_locked); ++ return 1; ++ } ++ return 0; ++} ++ ++static inline void spin_unlock_txnh(txn_handle *txnh) ++{ ++ assert_spin_locked(&(txnh->hlock)); ++ assert("nikita-1375", LOCK_CNT_GTZ(spin_locked_txnh)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ LOCK_CNT_DEC(spin_locked_txnh); ++ LOCK_CNT_DEC(spin_locked); ++ ++ spin_unlock(&(txnh->hlock)); ++} ++ ++#define spin_ordering_pred_txnmgr(tmgr) \ ++ ( LOCK_CNT_NIL(spin_locked_atom) && \ ++ LOCK_CNT_NIL(spin_locked_txnh) && \ ++ LOCK_CNT_NIL(spin_locked_jnode) && \ ++ LOCK_CNT_NIL(rw_locked_zlock) && \ ++ LOCK_CNT_NIL(rw_locked_dk) && \ ++ LOCK_CNT_NIL(rw_locked_tree) ) ++ ++static inline void spin_lock_txnmgr(txn_mgr *mgr) ++{ ++ /* check that spinlocks of lower priorities are not held */ ++ assert("", (LOCK_CNT_NIL(spin_locked_atom) && ++ LOCK_CNT_NIL(spin_locked_txnh) && ++ LOCK_CNT_NIL(spin_locked_jnode) && ++ LOCK_CNT_NIL(spin_locked_zlock) && ++ LOCK_CNT_NIL(rw_locked_dk) && ++ LOCK_CNT_NIL(rw_locked_tree))); ++ ++ spin_lock(&(mgr->tmgr_lock)); ++ ++ LOCK_CNT_INC(spin_locked_txnmgr); ++ LOCK_CNT_INC(spin_locked); ++} ++ ++static inline int spin_trylock_txnmgr(txn_mgr *mgr) ++{ ++ if (spin_trylock(&(mgr->tmgr_lock))) { ++ LOCK_CNT_INC(spin_locked_txnmgr); ++ LOCK_CNT_INC(spin_locked); ++ return 1; ++ } ++ return 0; ++} ++ ++static inline void spin_unlock_txnmgr(txn_mgr *mgr) ++{ ++ assert_spin_locked(&(mgr->tmgr_lock)); ++ assert("nikita-1375", LOCK_CNT_GTZ(spin_locked_txnmgr)); ++ assert("nikita-1376", LOCK_CNT_GTZ(spin_locked)); ++ ++ LOCK_CNT_DEC(spin_locked_txnmgr); ++ LOCK_CNT_DEC(spin_locked); ++ ++ spin_unlock(&(mgr->tmgr_lock)); ++} ++ ++typedef enum { ++ FQ_IN_USE = 0x1 ++} flush_queue_state_t; ++ ++typedef struct flush_queue flush_queue_t; ++ ++/* This is an accumulator for jnodes prepared for writing to disk. A flush queue ++ is filled by the jnode_flush() routine, and written to disk under memory ++ pressure or at atom commit time. */ ++/* LOCKING: fq state and fq->atom are protected by guard spinlock, fq->nr_queued ++ field and fq->prepped list can be modified if atom is spin-locked and fq ++ object is "in-use" state. For read-only traversal of the fq->prepped list ++ and reading of the fq->nr_queued field it is enough to keep fq "in-use" or ++ only have atom spin-locked. */ ++struct flush_queue { ++ /* linkage element is the first in this structure to make debugging ++ easier. See field in atom struct for description of list. */ ++ struct list_head alink; ++ /* A spinlock to protect changes of fq state and fq->atom pointer */ ++ spinlock_t guard; ++ /* flush_queue state: [in_use | ready] */ ++ flush_queue_state_t state; ++ /* A list which contains queued nodes, queued nodes are removed from any ++ * atom's list and put on this ->prepped one. */ ++ struct list_head prepped; ++ /* number of submitted i/o requests */ ++ atomic_t nr_submitted; ++ /* number of i/o errors */ ++ atomic_t nr_errors; ++ /* An atom this flush queue is attached to */ ++ txn_atom *atom; ++ /* A wait queue head to wait on i/o completion */ ++ wait_queue_head_t wait; ++#if REISER4_DEBUG ++ /* A thread which took this fq in exclusive use, NULL if fq is free, ++ * used for debugging. */ ++ struct task_struct *owner; ++#endif ++}; ++ ++extern int reiser4_fq_by_atom(txn_atom *, flush_queue_t **); ++extern void reiser4_fq_put_nolock(flush_queue_t *); ++extern void reiser4_fq_put(flush_queue_t *); ++extern void reiser4_fuse_fq(txn_atom * to, txn_atom * from); ++extern void queue_jnode(flush_queue_t *, jnode *); ++ ++extern int reiser4_write_fq(flush_queue_t *, long *, int); ++extern int current_atom_finish_all_fq(void); ++extern void init_atom_fq_parts(txn_atom *); ++ ++extern reiser4_block_nr txnmgr_count_deleted_blocks(void); ++ ++extern void znode_make_dirty(znode * node); ++extern void jnode_make_dirty_locked(jnode * node); ++ ++extern int reiser4_sync_atom(txn_atom * atom); ++ ++#if REISER4_DEBUG ++extern int atom_fq_parts_are_clean(txn_atom *); ++#endif ++ ++extern void add_fq_to_bio(flush_queue_t *, struct bio *); ++extern flush_queue_t *get_fq_for_current_atom(void); ++ ++void reiser4_invalidate_list(struct list_head * head); ++ ++# endif /* __REISER4_TXNMGR_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/type_safe_hash.h linux-2.6.30/fs/reiser4/type_safe_hash.h +--- linux-2.6.30.orig/fs/reiser4/type_safe_hash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/type_safe_hash.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,320 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* A hash table class that uses hash chains (singly-linked) and is ++ parametrized to provide type safety. */ ++ ++#ifndef __REISER4_TYPE_SAFE_HASH_H__ ++#define __REISER4_TYPE_SAFE_HASH_H__ ++ ++#include "debug.h" ++ ++#include <asm/errno.h> ++/* Step 1: Use TYPE_SAFE_HASH_DECLARE() to define the TABLE and LINK objects ++ based on the object type. You need to declare the item type before ++ this definition, define it after this definition. */ ++#define TYPE_SAFE_HASH_DECLARE(PREFIX,ITEM_TYPE) \ ++ \ ++typedef struct PREFIX##_hash_table_ PREFIX##_hash_table; \ ++typedef struct PREFIX##_hash_link_ PREFIX##_hash_link; \ ++ \ ++struct PREFIX##_hash_table_ \ ++{ \ ++ ITEM_TYPE **_table; \ ++ __u32 _buckets; \ ++}; \ ++ \ ++struct PREFIX##_hash_link_ \ ++{ \ ++ ITEM_TYPE *_next; \ ++} ++ ++/* Step 2: Define the object type of the hash: give it field of type ++ PREFIX_hash_link. */ ++ ++/* Step 3: Use TYPE_SAFE_HASH_DEFINE to define the hash table interface using ++ the type and field name used in step 3. The arguments are: ++ ++ ITEM_TYPE The item type being hashed ++ KEY_TYPE The type of key being hashed ++ KEY_NAME The name of the key field within the item ++ LINK_NAME The name of the link field within the item, which you must make type PREFIX_hash_link) ++ HASH_FUNC The name of the hash function (or macro, takes const pointer to key) ++ EQ_FUNC The name of the equality function (or macro, takes const pointer to two keys) ++ ++ It implements these functions: ++ ++ prefix_hash_init Initialize the table given its size. ++ prefix_hash_insert Insert an item ++ prefix_hash_insert_index Insert an item w/ precomputed hash_index ++ prefix_hash_find Find an item by key ++ prefix_hash_find_index Find an item w/ precomputed hash_index ++ prefix_hash_remove Remove an item, returns 1 if found, 0 if not found ++ prefix_hash_remove_index Remove an item w/ precomputed hash_index ++ ++ If you'd like something to be done differently, feel free to ask me ++ for modifications. Additional features that could be added but ++ have not been: ++ ++ prefix_hash_remove_key Find and remove an item by key ++ prefix_hash_remove_key_index Find and remove an item by key w/ precomputed hash_index ++ ++ The hash_function currently receives only the key as an argument, ++ meaning it must somehow know the number of buckets. If this is a ++ problem let me know. ++ ++ This hash table uses a single-linked hash chain. This means ++ insertion is fast but deletion requires searching the chain. ++ ++ There is also the doubly-linked hash chain approach, under which ++ deletion requires no search but the code is longer and it takes two ++ pointers per item. ++ ++ The circularly-linked approach has the shortest code but requires ++ two pointers per bucket, doubling the size of the bucket array (in ++ addition to two pointers per item). ++*/ ++#define TYPE_SAFE_HASH_DEFINE(PREFIX,ITEM_TYPE,KEY_TYPE,KEY_NAME,LINK_NAME,HASH_FUNC,EQ_FUNC) \ ++ \ ++static __inline__ void \ ++PREFIX##_check_hash (PREFIX##_hash_table *table UNUSED_ARG, \ ++ __u32 hash UNUSED_ARG) \ ++{ \ ++ assert("nikita-2780", hash < table->_buckets); \ ++} \ ++ \ ++static __inline__ int \ ++PREFIX##_hash_init (PREFIX##_hash_table *hash, \ ++ __u32 buckets) \ ++{ \ ++ hash->_table = (ITEM_TYPE**) KMALLOC (sizeof (ITEM_TYPE*) * buckets); \ ++ hash->_buckets = buckets; \ ++ if (hash->_table == NULL) \ ++ { \ ++ return RETERR(-ENOMEM); \ ++ } \ ++ memset (hash->_table, 0, sizeof (ITEM_TYPE*) * buckets); \ ++ ON_DEBUG(printk(#PREFIX "_hash_table: %i buckets\n", buckets)); \ ++ return 0; \ ++} \ ++ \ ++static __inline__ void \ ++PREFIX##_hash_done (PREFIX##_hash_table *hash) \ ++{ \ ++ if (REISER4_DEBUG && hash->_table != NULL) { \ ++ __u32 i; \ ++ for (i = 0 ; i < hash->_buckets ; ++ i) \ ++ assert("nikita-2905", hash->_table[i] == NULL); \ ++ } \ ++ if (hash->_table != NULL) \ ++ KFREE (hash->_table, sizeof (ITEM_TYPE*) * hash->_buckets); \ ++ hash->_table = NULL; \ ++} \ ++ \ ++static __inline__ void \ ++PREFIX##_hash_prefetch_next (ITEM_TYPE *item) \ ++{ \ ++ prefetch(item->LINK_NAME._next); \ ++} \ ++ \ ++static __inline__ void \ ++PREFIX##_hash_prefetch_bucket (PREFIX##_hash_table *hash, \ ++ __u32 index) \ ++{ \ ++ prefetch(hash->_table[index]); \ ++} \ ++ \ ++static __inline__ ITEM_TYPE* \ ++PREFIX##_hash_find_index (PREFIX##_hash_table *hash, \ ++ __u32 hash_index, \ ++ KEY_TYPE const *find_key) \ ++{ \ ++ ITEM_TYPE *item; \ ++ \ ++ PREFIX##_check_hash(hash, hash_index); \ ++ \ ++ for (item = hash->_table[hash_index]; \ ++ item != NULL; \ ++ item = item->LINK_NAME._next) \ ++ { \ ++ prefetch(item->LINK_NAME._next); \ ++ prefetch(item->LINK_NAME._next + offsetof(ITEM_TYPE, KEY_NAME)); \ ++ if (EQ_FUNC (& item->KEY_NAME, find_key)) \ ++ { \ ++ return item; \ ++ } \ ++ } \ ++ \ ++ return NULL; \ ++} \ ++ \ ++static __inline__ ITEM_TYPE* \ ++PREFIX##_hash_find_index_lru (PREFIX##_hash_table *hash, \ ++ __u32 hash_index, \ ++ KEY_TYPE const *find_key) \ ++{ \ ++ ITEM_TYPE ** item = &hash->_table[hash_index]; \ ++ \ ++ PREFIX##_check_hash(hash, hash_index); \ ++ \ ++ while (*item != NULL) { \ ++ prefetch(&(*item)->LINK_NAME._next); \ ++ if (EQ_FUNC (&(*item)->KEY_NAME, find_key)) { \ ++ ITEM_TYPE *found; \ ++ \ ++ found = *item; \ ++ *item = found->LINK_NAME._next; \ ++ found->LINK_NAME._next = hash->_table[hash_index]; \ ++ hash->_table[hash_index] = found; \ ++ return found; \ ++ } \ ++ item = &(*item)->LINK_NAME._next; \ ++ } \ ++ return NULL; \ ++} \ ++ \ ++static __inline__ int \ ++PREFIX##_hash_remove_index (PREFIX##_hash_table *hash, \ ++ __u32 hash_index, \ ++ ITEM_TYPE *del_item) \ ++{ \ ++ ITEM_TYPE ** hash_item_p = &hash->_table[hash_index]; \ ++ \ ++ PREFIX##_check_hash(hash, hash_index); \ ++ \ ++ while (*hash_item_p != NULL) { \ ++ prefetch(&(*hash_item_p)->LINK_NAME._next); \ ++ if (*hash_item_p == del_item) { \ ++ *hash_item_p = (*hash_item_p)->LINK_NAME._next; \ ++ return 1; \ ++ } \ ++ hash_item_p = &(*hash_item_p)->LINK_NAME._next; \ ++ } \ ++ return 0; \ ++} \ ++ \ ++static __inline__ void \ ++PREFIX##_hash_insert_index (PREFIX##_hash_table *hash, \ ++ __u32 hash_index, \ ++ ITEM_TYPE *ins_item) \ ++{ \ ++ PREFIX##_check_hash(hash, hash_index); \ ++ \ ++ ins_item->LINK_NAME._next = hash->_table[hash_index]; \ ++ hash->_table[hash_index] = ins_item; \ ++} \ ++ \ ++static __inline__ void \ ++PREFIX##_hash_insert_index_rcu (PREFIX##_hash_table *hash, \ ++ __u32 hash_index, \ ++ ITEM_TYPE *ins_item) \ ++{ \ ++ PREFIX##_check_hash(hash, hash_index); \ ++ \ ++ ins_item->LINK_NAME._next = hash->_table[hash_index]; \ ++ smp_wmb(); \ ++ hash->_table[hash_index] = ins_item; \ ++} \ ++ \ ++static __inline__ ITEM_TYPE* \ ++PREFIX##_hash_find (PREFIX##_hash_table *hash, \ ++ KEY_TYPE const *find_key) \ ++{ \ ++ return PREFIX##_hash_find_index (hash, HASH_FUNC(hash, find_key), find_key); \ ++} \ ++ \ ++static __inline__ ITEM_TYPE* \ ++PREFIX##_hash_find_lru (PREFIX##_hash_table *hash, \ ++ KEY_TYPE const *find_key) \ ++{ \ ++ return PREFIX##_hash_find_index_lru (hash, HASH_FUNC(hash, find_key), find_key); \ ++} \ ++ \ ++static __inline__ int \ ++PREFIX##_hash_remove (PREFIX##_hash_table *hash, \ ++ ITEM_TYPE *del_item) \ ++{ \ ++ return PREFIX##_hash_remove_index (hash, \ ++ HASH_FUNC(hash, &del_item->KEY_NAME), del_item); \ ++} \ ++ \ ++static __inline__ int \ ++PREFIX##_hash_remove_rcu (PREFIX##_hash_table *hash, \ ++ ITEM_TYPE *del_item) \ ++{ \ ++ return PREFIX##_hash_remove (hash, del_item); \ ++} \ ++ \ ++static __inline__ void \ ++PREFIX##_hash_insert (PREFIX##_hash_table *hash, \ ++ ITEM_TYPE *ins_item) \ ++{ \ ++ return PREFIX##_hash_insert_index (hash, \ ++ HASH_FUNC(hash, &ins_item->KEY_NAME), ins_item); \ ++} \ ++ \ ++static __inline__ void \ ++PREFIX##_hash_insert_rcu (PREFIX##_hash_table *hash, \ ++ ITEM_TYPE *ins_item) \ ++{ \ ++ return PREFIX##_hash_insert_index_rcu (hash, HASH_FUNC(hash, &ins_item->KEY_NAME), \ ++ ins_item); \ ++} \ ++ \ ++static __inline__ ITEM_TYPE * \ ++PREFIX##_hash_first (PREFIX##_hash_table *hash, __u32 ind) \ ++{ \ ++ ITEM_TYPE *first; \ ++ \ ++ for (first = NULL; ind < hash->_buckets; ++ ind) { \ ++ first = hash->_table[ind]; \ ++ if (first != NULL) \ ++ break; \ ++ } \ ++ return first; \ ++} \ ++ \ ++static __inline__ ITEM_TYPE * \ ++PREFIX##_hash_next (PREFIX##_hash_table *hash, \ ++ ITEM_TYPE *item) \ ++{ \ ++ ITEM_TYPE *next; \ ++ \ ++ if (item == NULL) \ ++ return NULL; \ ++ next = item->LINK_NAME._next; \ ++ if (next == NULL) \ ++ next = PREFIX##_hash_first (hash, HASH_FUNC(hash, &item->KEY_NAME) + 1); \ ++ return next; \ ++} \ ++ \ ++typedef struct {} PREFIX##_hash_dummy ++ ++#define for_all_ht_buckets(table, head) \ ++for ((head) = &(table) -> _table[ 0 ] ; \ ++ (head) != &(table) -> _table[ (table) -> _buckets ] ; ++ (head)) ++ ++#define for_all_in_bucket(bucket, item, next, field) \ ++for ((item) = *(bucket), (next) = (item) ? (item) -> field._next : NULL ; \ ++ (item) != NULL ; \ ++ (item) = (next), (next) = (item) ? (item) -> field._next : NULL ) ++ ++#define for_all_in_htable(table, prefix, item, next) \ ++for ((item) = prefix ## _hash_first ((table), 0), \ ++ (next) = prefix ## _hash_next ((table), (item)) ; \ ++ (item) != NULL ; \ ++ (item) = (next), \ ++ (next) = prefix ## _hash_next ((table), (item))) ++ ++/* __REISER4_TYPE_SAFE_HASH_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/vfs_ops.c linux-2.6.30/fs/reiser4/vfs_ops.c +--- linux-2.6.30.orig/fs/reiser4/vfs_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/vfs_ops.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,259 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Interface to VFS. Reiser4 {super|export|dentry}_operations are defined ++ here. */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "coord.h" ++#include "plugin/item/item.h" ++#include "plugin/file/file.h" ++#include "plugin/security/perm.h" ++#include "plugin/disk_format/disk_format.h" ++#include "plugin/plugin.h" ++#include "plugin/plugin_set.h" ++#include "plugin/object.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree.h" ++#include "vfs_ops.h" ++#include "inode.h" ++#include "page_cache.h" ++#include "ktxnmgrd.h" ++#include "super.h" ++#include "reiser4.h" ++#include "entd.h" ++#include "status_flags.h" ++#include "flush.h" ++#include "dscale.h" ++ ++#include <linux/profile.h> ++#include <linux/types.h> ++#include <linux/mount.h> ++#include <linux/vfs.h> ++#include <linux/mm.h> ++#include <linux/buffer_head.h> ++#include <linux/dcache.h> ++#include <linux/list.h> ++#include <linux/pagemap.h> ++#include <linux/slab.h> ++#include <linux/seq_file.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/writeback.h> ++#include <linux/blkdev.h> ++#include <linux/quotaops.h> ++#include <linux/security.h> ++#include <linux/reboot.h> ++#include <linux/rcupdate.h> ++ ++/* update inode stat-data by calling plugin */ ++int reiser4_update_sd(struct inode *object) ++{ ++ file_plugin *fplug; ++ ++ assert("nikita-2338", object != NULL); ++ /* check for read-only file system. */ ++ if (IS_RDONLY(object)) ++ return 0; ++ ++ fplug = inode_file_plugin(object); ++ assert("nikita-2339", fplug != NULL); ++ return fplug->write_sd_by_inode(object); ++} ++ ++/* helper function: increase inode nlink count and call plugin method to save ++ updated stat-data. ++ ++ Used by link/create and during creation of dot and dotdot in mkdir ++*/ ++int reiser4_add_nlink(struct inode *object /* object to which link is added */ , ++ struct inode *parent /* parent where new entry will be */ ++ , ++ int write_sd_p /* true if stat-data has to be ++ * updated */ ) ++{ ++ file_plugin *fplug; ++ int result; ++ ++ assert("nikita-1351", object != NULL); ++ ++ fplug = inode_file_plugin(object); ++ assert("nikita-1445", fplug != NULL); ++ ++ /* ask plugin whether it can add yet another link to this ++ object */ ++ if (!fplug->can_add_link(object)) ++ return RETERR(-EMLINK); ++ ++ assert("nikita-2211", fplug->add_link != NULL); ++ /* call plugin to do actual addition of link */ ++ result = fplug->add_link(object, parent); ++ ++ /* optionally update stat data */ ++ if (result == 0 && write_sd_p) ++ result = fplug->write_sd_by_inode(object); ++ return result; ++} ++ ++/* helper function: decrease inode nlink count and call plugin method to save ++ updated stat-data. ++ ++ Used by unlink/create ++*/ ++int reiser4_del_nlink(struct inode *object /* object from which link is ++ * removed */ , ++ struct inode *parent /* parent where entry was */ , ++ int write_sd_p /* true is stat-data has to be ++ * updated */ ) ++{ ++ file_plugin *fplug; ++ int result; ++ ++ assert("nikita-1349", object != NULL); ++ ++ fplug = inode_file_plugin(object); ++ assert("nikita-1350", fplug != NULL); ++ assert("nikita-1446", object->i_nlink > 0); ++ assert("nikita-2210", fplug->rem_link != NULL); ++ ++ /* call plugin to do actual deletion of link */ ++ result = fplug->rem_link(object, parent); ++ ++ /* optionally update stat data */ ++ if (result == 0 && write_sd_p) ++ result = fplug->write_sd_by_inode(object); ++ return result; ++} ++ ++/* Release reiser4 dentry. This is d_op->d_release() method. */ ++static void reiser4_d_release(struct dentry *dentry /* dentry released */ ) ++{ ++ reiser4_free_dentry_fsdata(dentry); ++} ++ ++/* ++ * Called by reiser4_sync_inodes(), during speculative write-back (through ++ * pdflush, or balance_dirty_pages()). ++ */ ++void reiser4_writeout(struct super_block *sb, struct writeback_control *wbc) ++{ ++ long written = 0; ++ int repeats = 0; ++ int result; ++ struct address_space *mapping; ++ ++ /* ++ * Performs early flushing, trying to free some memory. If there is ++ * nothing to flush, commits some atoms. ++ */ ++ ++ /* Commit all atoms if reiser4_writepages() is called from sys_sync() or ++ sys_fsync(). */ ++ if (wbc->sync_mode != WB_SYNC_NONE) { ++ txnmgr_force_commit_all(sb, 0); ++ return; ++ } ++ ++ BUG_ON(reiser4_get_super_fake(sb) == NULL); ++ mapping = reiser4_get_super_fake(sb)->i_mapping; ++ do { ++ long nr_submitted = 0; ++ jnode *node = NULL; ++ ++ /* do not put more requests to overload write queue */ ++ if (wbc->nonblocking && ++ bdi_write_congested(mapping->backing_dev_info)) { ++ blk_run_address_space(mapping); ++ wbc->encountered_congestion = 1; ++ break; ++ } ++ repeats++; ++ BUG_ON(wbc->nr_to_write <= 0); ++ ++ if (get_current_context()->entd) { ++ entd_context *ent = get_entd_context(sb); ++ ++ if (ent->cur_request->node) ++ /* ++ * this is ent thread and it managed to capture ++ * requested page itself - start flush from ++ * that page ++ */ ++ node = jref(ent->cur_request->node); ++ } ++ ++ result = flush_some_atom(node, &nr_submitted, wbc, ++ JNODE_FLUSH_WRITE_BLOCKS); ++ if (result != 0) ++ warning("nikita-31001", "Flush failed: %i", result); ++ if (node) ++ jput(node); ++ if (!nr_submitted) ++ break; ++ ++ wbc->nr_to_write -= nr_submitted; ++ written += nr_submitted; ++ } while (wbc->nr_to_write > 0); ++} ++ ++void reiser4_throttle_write(struct inode *inode) ++{ ++ reiser4_txn_restart_current(); ++ balance_dirty_pages_ratelimited(inode->i_mapping); ++} ++ ++const char *REISER4_SUPER_MAGIC_STRING = "ReIsEr4"; ++const int REISER4_MAGIC_OFFSET = 16 * 4096; /* offset to magic string from the ++ * beginning of device */ ++ ++/* ++ * Reiser4 initialization/shutdown. ++ * ++ * Code below performs global reiser4 initialization that is done either as ++ * part of kernel initialization (when reiser4 is statically built-in), or ++ * during reiser4 module load (when compiled as module). ++ */ ++ ++void reiser4_handle_error(void) ++{ ++ struct super_block *sb = reiser4_get_current_sb(); ++ ++ if (!sb) ++ return; ++ reiser4_status_write(REISER4_STATUS_DAMAGED, 0, ++ "Filesystem error occured"); ++ switch (get_super_private(sb)->onerror) { ++ case 0: ++ reiser4_panic("foobar-42", "Filesystem error occured\n"); ++ case 1: ++ default: ++ if (sb->s_flags & MS_RDONLY) ++ return; ++ sb->s_flags |= MS_RDONLY; ++ break; ++ } ++} ++ ++struct dentry_operations reiser4_dentry_operations = { ++ .d_revalidate = NULL, ++ .d_hash = NULL, ++ .d_compare = NULL, ++ .d_delete = NULL, ++ .d_release = reiser4_d_release, ++ .d_iput = NULL, ++}; ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/vfs_ops.h linux-2.6.30/fs/reiser4/vfs_ops.h +--- linux-2.6.30.orig/fs/reiser4/vfs_ops.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/vfs_ops.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,53 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* vfs_ops.c's exported symbols */ ++ ++#if !defined( __FS_REISER4_VFS_OPS_H__ ) ++#define __FS_REISER4_VFS_OPS_H__ ++ ++#include "forward.h" ++#include "coord.h" ++#include "seal.h" ++#include "plugin/file/file.h" ++#include "super.h" ++#include "readahead.h" ++ ++#include <linux/types.h> /* for loff_t */ ++#include <linux/fs.h> /* for struct address_space */ ++#include <linux/dcache.h> /* for struct dentry */ ++#include <linux/mm.h> ++#include <linux/backing-dev.h> ++ ++/* address space operations */ ++int reiser4_writepage(struct page *, struct writeback_control *); ++int reiser4_set_page_dirty(struct page *); ++void reiser4_invalidatepage(struct page *, unsigned long offset); ++int reiser4_releasepage(struct page *, gfp_t); ++ ++extern int reiser4_update_sd(struct inode *); ++extern int reiser4_add_nlink(struct inode *, struct inode *, int); ++extern int reiser4_del_nlink(struct inode *, struct inode *, int); ++ ++extern int reiser4_start_up_io(struct page *page); ++extern void reiser4_throttle_write(struct inode *); ++extern int jnode_is_releasable(jnode *); ++ ++#define CAPTURE_APAGE_BURST (1024l) ++void reiser4_writeout(struct super_block *, struct writeback_control *); ++ ++extern void reiser4_handle_error(void); ++ ++/* __FS_REISER4_VFS_OPS_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/wander.c linux-2.6.30/fs/reiser4/wander.c +--- linux-2.6.30.orig/fs/reiser4/wander.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/wander.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1798 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Reiser4 Wandering Log */ ++ ++/* You should read http://www.namesys.com/txn-doc.html ++ ++ That describes how filesystem operations are performed as atomic ++ transactions, and how we try to arrange it so that we can write most of the ++ data only once while performing the operation atomically. ++ ++ For the purposes of this code, it is enough for it to understand that it ++ has been told a given block should be written either once, or twice (if ++ twice then once to the wandered location and once to the real location). ++ ++ This code guarantees that those blocks that are defined to be part of an ++ atom either all take effect or none of them take effect. ++ ++ The "relocate set" of nodes are submitted to write by the jnode_flush() ++ routine, and the "overwrite set" is submitted by reiser4_write_log(). ++ This is because with the overwrite set we seek to optimize writes, and ++ with the relocate set we seek to cause disk order to correlate with the ++ "parent first order" (preorder). ++ ++ reiser4_write_log() allocates and writes wandered blocks and maintains ++ additional on-disk structures of the atom as wander records (each wander ++ record occupies one block) for storing of the "wandered map" (a table which ++ contains a relation between wandered and real block numbers) and other ++ information which might be needed at transaction recovery time. ++ ++ The wander records are unidirectionally linked into a circle: each wander ++ record contains a block number of the next wander record, the last wander ++ record points to the first one. ++ ++ One wander record (named "tx head" in this file) has a format which is ++ different from the other wander records. The "tx head" has a reference to the ++ "tx head" block of the previously committed atom. Also, "tx head" contains ++ fs information (the free blocks counter, and the oid allocator state) which ++ is logged in a special way . ++ ++ There are two journal control blocks, named journal header and journal ++ footer which have fixed on-disk locations. The journal header has a ++ reference to the "tx head" block of the last committed atom. The journal ++ footer points to the "tx head" of the last flushed atom. The atom is ++ "played" when all blocks from its overwrite set are written to disk the ++ second time (i.e. written to their real locations). ++ ++ NOTE: People who know reiserfs internals and its journal structure might be ++ confused with these terms journal footer and journal header. There is a table ++ with terms of similar semantics in reiserfs (reiser3) and reiser4: ++ ++ REISER3 TERM | REISER4 TERM | DESCRIPTION ++ --------------------+-----------------------+---------------------------- ++ commit record | journal header | atomic write of this record ++ | | ends transaction commit ++ --------------------+-----------------------+---------------------------- ++ journal header | journal footer | atomic write of this record ++ | | ends post-commit writes. ++ | | After successful ++ | | writing of this journal ++ | | blocks (in reiser3) or ++ | | wandered blocks/records are ++ | | free for re-use. ++ --------------------+-----------------------+---------------------------- ++ ++ The atom commit process is the following: ++ ++ 1. The overwrite set is taken from atom's clean list, and its size is ++ counted. ++ ++ 2. The number of necessary wander records (including tx head) is calculated, ++ and the wander record blocks are allocated. ++ ++ 3. Allocate wandered blocks and populate wander records by wandered map. ++ ++ 4. submit write requests for wander records and wandered blocks. ++ ++ 5. wait until submitted write requests complete. ++ ++ 6. update journal header: change the pointer to the block number of just ++ written tx head, submit an i/o for modified journal header block and wait ++ for i/o completion. ++ ++ NOTE: The special logging for bitmap blocks and some reiser4 super block ++ fields makes processes of atom commit, flush and recovering a bit more ++ complex (see comments in the source code for details). ++ ++ The atom playing process is the following: ++ ++ 1. Write atom's overwrite set in-place. ++ ++ 2. Wait on i/o. ++ ++ 3. Update journal footer: change the pointer to block number of tx head ++ block of the atom we currently flushing, submit an i/o, wait on i/o ++ completion. ++ ++ 4. Free disk space which was used for wandered blocks and wander records. ++ ++ After the freeing of wandered blocks and wander records we have that journal ++ footer points to the on-disk structure which might be overwritten soon. ++ Neither the log writer nor the journal recovery procedure use that pointer ++ for accessing the data. When the journal recovery procedure finds the oldest ++ transaction it compares the journal footer pointer value with the "prev_tx" ++ pointer value in tx head, if values are equal the oldest not flushed ++ transaction is found. ++ ++ NOTE on disk space leakage: the information about of what blocks and how many ++ blocks are allocated for wandered blocks, wandered records is not written to ++ the disk because of special logging for bitmaps and some super blocks ++ counters. After a system crash we the reiser4 does not remember those ++ objects allocation, thus we have no such a kind of disk space leakage. ++*/ ++ ++/* Special logging of reiser4 super block fields. */ ++ ++/* There are some reiser4 super block fields (free block count and OID allocator ++ state (number of files and next free OID) which are logged separately from ++ super block to avoid unnecessary atom fusion. ++ ++ So, the reiser4 super block can be not captured by a transaction with ++ allocates/deallocates disk blocks or create/delete file objects. Moreover, ++ the reiser4 on-disk super block is not touched when such a transaction is ++ committed and flushed. Those "counters logged specially" are logged in "tx ++ head" blocks and in the journal footer block. ++ ++ A step-by-step description of special logging: ++ ++ 0. The per-atom information about deleted or created files and allocated or ++ freed blocks is collected during the transaction. The atom's ++ ->nr_objects_created and ->nr_objects_deleted are for object ++ deletion/creation tracking, the numbers of allocated and freed blocks are ++ calculated using atom's delete set and atom's capture list -- all new and ++ relocated nodes should be on atom's clean list and should have JNODE_RELOC ++ bit set. ++ ++ 1. The "logged specially" reiser4 super block fields have their "committed" ++ versions in the reiser4 in-memory super block. They get modified only at ++ atom commit time. The atom's commit thread has an exclusive access to those ++ "committed" fields because the log writer implementation supports only one ++ atom commit a time (there is a per-fs "commit" mutex). At ++ that time "committed" counters are modified using per-atom information ++ collected during the transaction. These counters are stored on disk as a ++ part of tx head block when atom is committed. ++ ++ 2. When the atom is flushed the value of the free block counter and the OID ++ allocator state get written to the journal footer block. A special journal ++ procedure (journal_recover_sb_data()) takes those values from the journal ++ footer and updates the reiser4 in-memory super block. ++ ++ NOTE: That means free block count and OID allocator state are logged ++ separately from the reiser4 super block regardless of the fact that the ++ reiser4 super block has fields to store both the free block counter and the ++ OID allocator. ++ ++ Writing the whole super block at commit time requires knowing true values of ++ all its fields without changes made by not yet committed transactions. It is ++ possible by having their "committed" version of the super block like the ++ reiser4 bitmap blocks have "committed" and "working" versions. However, ++ another scheme was implemented which stores special logged values in the ++ unused free space inside transaction head block. In my opinion it has an ++ advantage of not writing whole super block when only part of it was ++ modified. */ ++ ++#include "debug.h" ++#include "dformat.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "page_cache.h" ++#include "wander.h" ++#include "reiser4.h" ++#include "super.h" ++#include "vfs_ops.h" ++#include "writeout.h" ++#include "inode.h" ++#include "entd.h" ++ ++#include <linux/types.h> ++#include <linux/fs.h> /* for struct super_block */ ++#include <linux/mm.h> /* for struct page */ ++#include <linux/pagemap.h> ++#include <linux/bio.h> /* for struct bio */ ++#include <linux/blkdev.h> ++ ++static int write_jnodes_to_disk_extent( ++ jnode *, int, const reiser4_block_nr *, flush_queue_t *, int); ++ ++/* The commit_handle is a container for objects needed at atom commit time */ ++struct commit_handle { ++ /* A pointer to atom's list of OVRWR nodes */ ++ struct list_head *overwrite_set; ++ /* atom's overwrite set size */ ++ int overwrite_set_size; ++ /* jnodes for wander record blocks */ ++ struct list_head tx_list; ++ /* number of wander records */ ++ __u32 tx_size; ++ /* 'committed' sb counters are saved here until atom is completely ++ flushed */ ++ __u64 free_blocks; ++ __u64 nr_files; ++ __u64 next_oid; ++ /* A pointer to the atom which is being committed */ ++ txn_atom *atom; ++ /* A pointer to current super block */ ++ struct super_block *super; ++ /* The counter of modified bitmaps */ ++ reiser4_block_nr nr_bitmap; ++}; ++ ++static void init_commit_handle(struct commit_handle *ch, txn_atom *atom) ++{ ++ memset(ch, 0, sizeof(struct commit_handle)); ++ INIT_LIST_HEAD(&ch->tx_list); ++ ++ ch->atom = atom; ++ ch->super = reiser4_get_current_sb(); ++} ++ ++static void done_commit_handle(struct commit_handle *ch) ++{ ++ assert("zam-690", list_empty(&ch->tx_list)); ++} ++ ++static inline int reiser4_use_write_barrier(struct super_block * s) ++{ ++ return !reiser4_is_set(s, REISER4_NO_WRITE_BARRIER); ++} ++ ++static void disable_write_barrier(struct super_block * s) ++{ ++ notice("zam-1055", "%s does not support write barriers," ++ " using synchronous write instead.", s->s_id); ++ set_bit((int)REISER4_NO_WRITE_BARRIER, &get_super_private(s)->fs_flags); ++} ++ ++/* fill journal header block data */ ++static void format_journal_header(struct commit_handle *ch) ++{ ++ struct reiser4_super_info_data *sbinfo; ++ struct journal_header *header; ++ jnode *txhead; ++ ++ sbinfo = get_super_private(ch->super); ++ assert("zam-479", sbinfo != NULL); ++ assert("zam-480", sbinfo->journal_header != NULL); ++ ++ txhead = list_entry(ch->tx_list.next, jnode, capture_link); ++ ++ jload(sbinfo->journal_header); ++ ++ header = (struct journal_header *)jdata(sbinfo->journal_header); ++ assert("zam-484", header != NULL); ++ ++ put_unaligned(cpu_to_le64(*jnode_get_block(txhead)), ++ &header->last_committed_tx); ++ ++ jrelse(sbinfo->journal_header); ++} ++ ++/* fill journal footer block data */ ++static void format_journal_footer(struct commit_handle *ch) ++{ ++ struct reiser4_super_info_data *sbinfo; ++ struct journal_footer *footer; ++ jnode *tx_head; ++ ++ sbinfo = get_super_private(ch->super); ++ ++ tx_head = list_entry(ch->tx_list.next, jnode, capture_link); ++ ++ assert("zam-493", sbinfo != NULL); ++ assert("zam-494", sbinfo->journal_header != NULL); ++ ++ check_me("zam-691", jload(sbinfo->journal_footer) == 0); ++ ++ footer = (struct journal_footer *)jdata(sbinfo->journal_footer); ++ assert("zam-495", footer != NULL); ++ ++ put_unaligned(cpu_to_le64(*jnode_get_block(tx_head)), ++ &footer->last_flushed_tx); ++ put_unaligned(cpu_to_le64(ch->free_blocks), &footer->free_blocks); ++ ++ put_unaligned(cpu_to_le64(ch->nr_files), &footer->nr_files); ++ put_unaligned(cpu_to_le64(ch->next_oid), &footer->next_oid); ++ ++ jrelse(sbinfo->journal_footer); ++} ++ ++/* wander record capacity depends on current block size */ ++static int wander_record_capacity(const struct super_block *super) ++{ ++ return (super->s_blocksize - ++ sizeof(struct wander_record_header)) / ++ sizeof(struct wander_entry); ++} ++ ++/* Fill first wander record (tx head) in accordance with supplied given data */ ++static void format_tx_head(struct commit_handle *ch) ++{ ++ jnode *tx_head; ++ jnode *next; ++ struct tx_header *header; ++ ++ tx_head = list_entry(ch->tx_list.next, jnode, capture_link); ++ assert("zam-692", &ch->tx_list != &tx_head->capture_link); ++ ++ next = list_entry(tx_head->capture_link.next, jnode, capture_link); ++ if (&ch->tx_list == &next->capture_link) ++ next = tx_head; ++ ++ header = (struct tx_header *)jdata(tx_head); ++ ++ assert("zam-460", header != NULL); ++ assert("zam-462", ch->super->s_blocksize >= sizeof(struct tx_header)); ++ ++ memset(jdata(tx_head), 0, (size_t) ch->super->s_blocksize); ++ memcpy(jdata(tx_head), TX_HEADER_MAGIC, TX_HEADER_MAGIC_SIZE); ++ ++ put_unaligned(cpu_to_le32(ch->tx_size), &header->total); ++ put_unaligned(cpu_to_le64(get_super_private(ch->super)->last_committed_tx), ++ &header->prev_tx); ++ put_unaligned(cpu_to_le64(*jnode_get_block(next)), &header->next_block); ++ put_unaligned(cpu_to_le64(ch->free_blocks), &header->free_blocks); ++ put_unaligned(cpu_to_le64(ch->nr_files), &header->nr_files); ++ put_unaligned(cpu_to_le64(ch->next_oid), &header->next_oid); ++} ++ ++/* prepare ordinary wander record block (fill all service fields) */ ++static void ++format_wander_record(struct commit_handle *ch, jnode *node, __u32 serial) ++{ ++ struct wander_record_header *LRH; ++ jnode *next; ++ ++ assert("zam-464", node != NULL); ++ ++ LRH = (struct wander_record_header *)jdata(node); ++ next = list_entry(node->capture_link.next, jnode, capture_link); ++ ++ if (&ch->tx_list == &next->capture_link) ++ next = list_entry(ch->tx_list.next, jnode, capture_link); ++ ++ assert("zam-465", LRH != NULL); ++ assert("zam-463", ++ ch->super->s_blocksize > sizeof(struct wander_record_header)); ++ ++ memset(jdata(node), 0, (size_t) ch->super->s_blocksize); ++ memcpy(jdata(node), WANDER_RECORD_MAGIC, WANDER_RECORD_MAGIC_SIZE); ++ ++ put_unaligned(cpu_to_le32(ch->tx_size), &LRH->total); ++ put_unaligned(cpu_to_le32(serial), &LRH->serial); ++ put_unaligned(cpu_to_le64(*jnode_get_block(next)), &LRH->next_block); ++} ++ ++/* add one wandered map entry to formatted wander record */ ++static void ++store_entry(jnode * node, int index, const reiser4_block_nr * a, ++ const reiser4_block_nr * b) ++{ ++ char *data; ++ struct wander_entry *pairs; ++ ++ data = jdata(node); ++ assert("zam-451", data != NULL); ++ ++ pairs = ++ (struct wander_entry *)(data + sizeof(struct wander_record_header)); ++ ++ put_unaligned(cpu_to_le64(*a), &pairs[index].original); ++ put_unaligned(cpu_to_le64(*b), &pairs[index].wandered); ++} ++ ++/* currently, wander records contains contain only wandered map, which depend on ++ overwrite set size */ ++static void get_tx_size(struct commit_handle *ch) ++{ ++ assert("zam-440", ch->overwrite_set_size != 0); ++ assert("zam-695", ch->tx_size == 0); ++ ++ /* count all ordinary wander records ++ (<overwrite_set_size> - 1) / <wander_record_capacity> + 1 and add one ++ for tx head block */ ++ ch->tx_size = ++ (ch->overwrite_set_size - 1) / wander_record_capacity(ch->super) + ++ 2; ++} ++ ++/* A special structure for using in store_wmap_actor() for saving its state ++ between calls */ ++struct store_wmap_params { ++ jnode *cur; /* jnode of current wander record to fill */ ++ int idx; /* free element index in wander record */ ++ int capacity; /* capacity */ ++ ++#if REISER4_DEBUG ++ struct list_head *tx_list; ++#endif ++}; ++ ++/* an actor for use in blocknr_set_iterator routine which populates the list ++ of pre-formatted wander records by wandered map info */ ++static int ++store_wmap_actor(txn_atom * atom UNUSED_ARG, const reiser4_block_nr * a, ++ const reiser4_block_nr * b, void *data) ++{ ++ struct store_wmap_params *params = data; ++ ++ if (params->idx >= params->capacity) { ++ /* a new wander record should be taken from the tx_list */ ++ params->cur = list_entry(params->cur->capture_link.next, jnode, capture_link); ++ assert("zam-454", ++ params->tx_list != ¶ms->cur->capture_link); ++ ++ params->idx = 0; ++ } ++ ++ store_entry(params->cur, params->idx, a, b); ++ params->idx++; ++ ++ return 0; ++} ++ ++/* This function is called after Relocate set gets written to disk, Overwrite ++ set is written to wandered locations and all wander records are written ++ also. Updated journal header blocks contains a pointer (block number) to ++ first wander record of the just written transaction */ ++static int update_journal_header(struct commit_handle *ch, int use_barrier) ++{ ++ struct reiser4_super_info_data *sbinfo = get_super_private(ch->super); ++ jnode *jh = sbinfo->journal_header; ++ jnode *head = list_entry(ch->tx_list.next, jnode, capture_link); ++ int ret; ++ ++ format_journal_header(ch); ++ ++ ret = write_jnodes_to_disk_extent(jh, 1, jnode_get_block(jh), NULL, ++ use_barrier ? WRITEOUT_BARRIER : 0); ++ if (ret) ++ return ret; ++ ++ /* blk_run_address_space(sbinfo->fake->i_mapping); ++ * blk_run_queues(); */ ++ ++ ret = jwait_io(jh, WRITE); ++ ++ if (ret) ++ return ret; ++ ++ sbinfo->last_committed_tx = *jnode_get_block(head); ++ ++ return 0; ++} ++ ++/* This function is called after write-back is finished. We update journal ++ footer block and free blocks which were occupied by wandered blocks and ++ transaction wander records */ ++static int update_journal_footer(struct commit_handle *ch, int use_barrier) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(ch->super); ++ ++ jnode *jf = sbinfo->journal_footer; ++ ++ int ret; ++ ++ format_journal_footer(ch); ++ ++ ret = write_jnodes_to_disk_extent(jf, 1, jnode_get_block(jf), NULL, ++ use_barrier ? WRITEOUT_BARRIER : 0); ++ if (ret) ++ return ret; ++ ++ /* blk_run_address_space(sbinfo->fake->i_mapping); ++ * blk_run_queue(); */ ++ ++ ret = jwait_io(jf, WRITE); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++/* free block numbers of wander records of already written in place transaction */ ++static void dealloc_tx_list(struct commit_handle *ch) ++{ ++ while (!list_empty(&ch->tx_list)) { ++ jnode *cur = list_entry(ch->tx_list.next, jnode, capture_link); ++ list_del(&cur->capture_link); ++ ON_DEBUG(INIT_LIST_HEAD(&cur->capture_link)); ++ reiser4_dealloc_block(jnode_get_block(cur), BLOCK_NOT_COUNTED, ++ BA_FORMATTED); ++ ++ unpin_jnode_data(cur); ++ reiser4_drop_io_head(cur); ++ } ++} ++ ++/* An actor for use in block_nr_iterator() routine which frees wandered blocks ++ from atom's overwrite set. */ ++static int ++dealloc_wmap_actor(txn_atom * atom UNUSED_ARG, ++ const reiser4_block_nr * a UNUSED_ARG, ++ const reiser4_block_nr * b, void *data UNUSED_ARG) ++{ ++ ++ assert("zam-499", b != NULL); ++ assert("zam-500", *b != 0); ++ assert("zam-501", !reiser4_blocknr_is_fake(b)); ++ ++ reiser4_dealloc_block(b, BLOCK_NOT_COUNTED, BA_FORMATTED); ++ return 0; ++} ++ ++/* free wandered block locations of already written in place transaction */ ++static void dealloc_wmap(struct commit_handle *ch) ++{ ++ assert("zam-696", ch->atom != NULL); ++ ++ blocknr_set_iterator(ch->atom, &ch->atom->wandered_map, ++ dealloc_wmap_actor, NULL, 1); ++} ++ ++/* helper function for alloc wandered blocks, which refill set of block ++ numbers needed for wandered blocks */ ++static int ++get_more_wandered_blocks(int count, reiser4_block_nr * start, int *len) ++{ ++ reiser4_blocknr_hint hint; ++ int ret; ++ ++ reiser4_block_nr wide_len = count; ++ ++ /* FIXME-ZAM: A special policy needed for allocation of wandered blocks ++ ZAM-FIXME-HANS: yes, what happened to our discussion of using a fixed ++ reserved allocation area so as to get the best qualities of fixed ++ journals? */ ++ reiser4_blocknr_hint_init(&hint); ++ hint.block_stage = BLOCK_GRABBED; ++ ++ ret = reiser4_alloc_blocks(&hint, start, &wide_len, ++ BA_FORMATTED | BA_USE_DEFAULT_SEARCH_START); ++ *len = (int)wide_len; ++ ++ return ret; ++} ++ ++/* ++ * roll back changes made before issuing BIO in the case of IO error. ++ */ ++static void undo_bio(struct bio *bio) ++{ ++ int i; ++ ++ for (i = 0; i < bio->bi_vcnt; ++i) { ++ struct page *pg; ++ jnode *node; ++ ++ pg = bio->bi_io_vec[i].bv_page; ++ end_page_writeback(pg); ++ node = jprivate(pg); ++ spin_lock_jnode(node); ++ JF_CLR(node, JNODE_WRITEBACK); ++ JF_SET(node, JNODE_DIRTY); ++ spin_unlock_jnode(node); ++ } ++ bio_put(bio); ++} ++ ++/* put overwrite set back to atom's clean list */ ++static void put_overwrite_set(struct commit_handle *ch) ++{ ++ jnode *cur; ++ ++ list_for_each_entry(cur, ch->overwrite_set, capture_link) ++ jrelse_tail(cur); ++} ++ ++/* Count overwrite set size, grab disk space for wandered blocks allocation. ++ Since we have a separate list for atom's overwrite set we just scan the list, ++ count bitmap and other not leaf nodes which wandered blocks allocation we ++ have to grab space for. */ ++static int get_overwrite_set(struct commit_handle *ch) ++{ ++ int ret; ++ jnode *cur; ++ __u64 nr_not_leaves = 0; ++#if REISER4_DEBUG ++ __u64 nr_formatted_leaves = 0; ++ __u64 nr_unformatted_leaves = 0; ++#endif ++ ++ assert("zam-697", ch->overwrite_set_size == 0); ++ ++ ch->overwrite_set = ATOM_OVRWR_LIST(ch->atom); ++ cur = list_entry(ch->overwrite_set->next, jnode, capture_link); ++ ++ while (ch->overwrite_set != &cur->capture_link) { ++ jnode *next = list_entry(cur->capture_link.next, jnode, capture_link); ++ ++ /* Count bitmap locks for getting correct statistics what number ++ * of blocks were cleared by the transaction commit. */ ++ if (jnode_get_type(cur) == JNODE_BITMAP) ++ ch->nr_bitmap++; ++ ++ assert("zam-939", JF_ISSET(cur, JNODE_OVRWR) ++ || jnode_get_type(cur) == JNODE_BITMAP); ++ ++ if (jnode_is_znode(cur) && znode_above_root(JZNODE(cur))) { ++ /* we replace fake znode by another (real) ++ znode which is suggested by disk_layout ++ plugin */ ++ ++ /* FIXME: it looks like fake znode should be ++ replaced by jnode supplied by ++ disk_layout. */ ++ ++ struct super_block *s = reiser4_get_current_sb(); ++ reiser4_super_info_data *sbinfo = ++ get_current_super_private(); ++ ++ if (sbinfo->df_plug->log_super) { ++ jnode *sj = sbinfo->df_plug->log_super(s); ++ ++ assert("zam-593", sj != NULL); ++ ++ if (IS_ERR(sj)) ++ return PTR_ERR(sj); ++ ++ spin_lock_jnode(sj); ++ JF_SET(sj, JNODE_OVRWR); ++ insert_into_atom_ovrwr_list(ch->atom, sj); ++ spin_unlock_jnode(sj); ++ ++ /* jload it as the rest of overwrite set */ ++ jload_gfp(sj, reiser4_ctx_gfp_mask_get(), 0); ++ ++ ch->overwrite_set_size++; ++ } ++ spin_lock_jnode(cur); ++ reiser4_uncapture_block(cur); ++ jput(cur); ++ ++ } else { ++ int ret; ++ ch->overwrite_set_size++; ++ ret = jload_gfp(cur, reiser4_ctx_gfp_mask_get(), 0); ++ if (ret) ++ reiser4_panic("zam-783", ++ "cannot load e-flushed jnode back (ret = %d)\n", ++ ret); ++ } ++ ++ /* Count not leaves here because we have to grab disk space ++ * for wandered blocks. They were not counted as "flush ++ * reserved". Counting should be done _after_ nodes are pinned ++ * into memory by jload(). */ ++ if (!jnode_is_leaf(cur)) ++ nr_not_leaves++; ++ else { ++#if REISER4_DEBUG ++ /* at this point @cur either has JNODE_FLUSH_RESERVED ++ * or is eflushed. Locking is not strong enough to ++ * write an assertion checking for this. */ ++ if (jnode_is_znode(cur)) ++ nr_formatted_leaves++; ++ else ++ nr_unformatted_leaves++; ++#endif ++ JF_CLR(cur, JNODE_FLUSH_RESERVED); ++ } ++ ++ cur = next; ++ } ++ ++ /* Grab space for writing (wandered blocks) of not leaves found in ++ * overwrite set. */ ++ ret = reiser4_grab_space_force(nr_not_leaves, BA_RESERVED); ++ if (ret) ++ return ret; ++ ++ /* Disk space for allocation of wandered blocks of leaf nodes already ++ * reserved as "flush reserved", move it to grabbed space counter. */ ++ spin_lock_atom(ch->atom); ++ assert("zam-940", ++ nr_formatted_leaves + nr_unformatted_leaves <= ++ ch->atom->flush_reserved); ++ flush_reserved2grabbed(ch->atom, ch->atom->flush_reserved); ++ spin_unlock_atom(ch->atom); ++ ++ return ch->overwrite_set_size; ++} ++ ++/** ++ * write_jnodes_to_disk_extent - submit write request ++ * @head: ++ * @first: first jnode of the list ++ * @nr: number of jnodes on the list ++ * @block_p: ++ * @fq: ++ * @flags: used to decide whether page is to get PG_reclaim flag ++ * ++ * Submits a write request for @nr jnodes beginning from the @first, other ++ * jnodes are after the @first on the double-linked "capture" list. All jnodes ++ * will be written to the disk region of @nr blocks starting with @block_p block ++ * number. If @fq is not NULL it means that waiting for i/o completion will be ++ * done more efficiently by using flush_queue_t objects. ++ * This function is the one which writes list of jnodes in batch mode. It does ++ * all low-level things as bio construction and page states manipulation. ++ * ++ * ZAM-FIXME-HANS: brief me on why this function exists, and why bios are ++ * aggregated in this function instead of being left to the layers below ++ * ++ * FIXME: ZAM->HANS: What layer are you talking about? Can you point me to that? ++ * Why that layer needed? Why BIOs cannot be constructed here? ++ */ ++static int write_jnodes_to_disk_extent( ++ jnode *first, int nr, const reiser4_block_nr *block_p, ++ flush_queue_t *fq, int flags) ++{ ++ struct super_block *super = reiser4_get_current_sb(); ++ int write_op = ( flags & WRITEOUT_BARRIER ) ? WRITE_BARRIER : WRITE; ++ int max_blocks; ++ jnode *cur = first; ++ reiser4_block_nr block; ++ ++ assert("zam-571", first != NULL); ++ assert("zam-572", block_p != NULL); ++ assert("zam-570", nr > 0); ++ ++ block = *block_p; ++ max_blocks = min(bio_get_nr_vecs(super->s_bdev), BIO_MAX_PAGES); ++ ++ while (nr > 0) { ++ struct bio *bio; ++ int nr_blocks = min(nr, max_blocks); ++ int i; ++ int nr_used; ++ ++ bio = bio_alloc(GFP_NOIO, nr_blocks); ++ if (!bio) ++ return RETERR(-ENOMEM); ++ ++ bio->bi_bdev = super->s_bdev; ++ bio->bi_sector = block * (super->s_blocksize >> 9); ++ for (nr_used = 0, i = 0; i < nr_blocks; i++) { ++ struct page *pg; ++ ++ pg = jnode_page(cur); ++ assert("zam-573", pg != NULL); ++ ++ page_cache_get(pg); ++ ++ lock_and_wait_page_writeback(pg); ++ ++ if (!bio_add_page(bio, pg, super->s_blocksize, 0)) { ++ /* ++ * underlying device is satiated. Stop adding ++ * pages to the bio. ++ */ ++ unlock_page(pg); ++ page_cache_release(pg); ++ break; ++ } ++ ++ spin_lock_jnode(cur); ++ assert("nikita-3166", ++ pg->mapping == jnode_get_mapping(cur)); ++ assert("zam-912", !JF_ISSET(cur, JNODE_WRITEBACK)); ++#if REISER4_DEBUG ++ spin_lock(&cur->load); ++ assert("nikita-3165", !jnode_is_releasable(cur)); ++ spin_unlock(&cur->load); ++#endif ++ JF_SET(cur, JNODE_WRITEBACK); ++ JF_CLR(cur, JNODE_DIRTY); ++ ON_DEBUG(cur->written++); ++ spin_unlock_jnode(cur); ++ ++ ClearPageError(pg); ++ set_page_writeback(pg); ++ ++ if (get_current_context()->entd) { ++ /* this is ent thread */ ++ entd_context *ent = get_entd_context(super); ++ struct wbq *rq, *next; ++ ++ spin_lock(&ent->guard); ++ ++ if (pg == ent->cur_request->page) { ++ /* ++ * entd is called for this page. This ++ * request is not in th etodo list ++ */ ++ ent->cur_request->written = 1; ++ } else { ++ /* ++ * if we have written a page for which writepage ++ * is called for - move request to another list. ++ */ ++ list_for_each_entry_safe(rq, next, &ent->todo_list, link) { ++ assert("", rq->magic == WBQ_MAGIC); ++ if (pg == rq->page) { ++ /* ++ * remove request from ++ * entd's queue, but do ++ * not wake up a thread ++ * which put this ++ * request ++ */ ++ list_del_init(&rq->link); ++ ent->nr_todo_reqs --; ++ list_add_tail(&rq->link, &ent->done_list); ++ ent->nr_done_reqs ++; ++ rq->written = 1; ++ break; ++ } ++ } ++ } ++ spin_unlock(&ent->guard); ++ } ++ ++ clear_page_dirty_for_io(pg); ++ ++ unlock_page(pg); ++ ++ cur = list_entry(cur->capture_link.next, jnode, capture_link); ++ nr_used++; ++ } ++ if (nr_used > 0) { ++ assert("nikita-3453", ++ bio->bi_size == super->s_blocksize * nr_used); ++ assert("nikita-3454", bio->bi_vcnt == nr_used); ++ ++ /* Check if we are allowed to write at all */ ++ if (super->s_flags & MS_RDONLY) ++ undo_bio(bio); ++ else { ++ int not_supported; ++ ++ add_fq_to_bio(fq, bio); ++ bio_get(bio); ++ reiser4_submit_bio(write_op, bio); ++ not_supported = bio_flagged(bio, BIO_EOPNOTSUPP); ++ bio_put(bio); ++ if (not_supported) ++ return -EOPNOTSUPP; ++ } ++ ++ block += nr_used - 1; ++ update_blocknr_hint_default(super, &block); ++ block += 1; ++ } else { ++ bio_put(bio); ++ } ++ nr -= nr_used; ++ } ++ ++ return 0; ++} ++ ++/* This is a procedure which recovers a contiguous sequences of disk block ++ numbers in the given list of j-nodes and submits write requests on this ++ per-sequence basis */ ++int ++write_jnode_list(struct list_head *head, flush_queue_t *fq, ++ long *nr_submitted, int flags) ++{ ++ int ret; ++ jnode *beg = list_entry(head->next, jnode, capture_link); ++ ++ while (head != &beg->capture_link) { ++ int nr = 1; ++ jnode *cur = list_entry(beg->capture_link.next, jnode, capture_link); ++ ++ while (head != &cur->capture_link) { ++ if (*jnode_get_block(cur) != *jnode_get_block(beg) + nr) ++ break; ++ ++nr; ++ cur = list_entry(cur->capture_link.next, jnode, capture_link); ++ } ++ ++ ret = write_jnodes_to_disk_extent( ++ beg, nr, jnode_get_block(beg), fq, flags); ++ if (ret) ++ return ret; ++ ++ if (nr_submitted) ++ *nr_submitted += nr; ++ ++ beg = cur; ++ } ++ ++ return 0; ++} ++ ++/* add given wandered mapping to atom's wandered map */ ++static int ++add_region_to_wmap(jnode * cur, int len, const reiser4_block_nr * block_p) ++{ ++ int ret; ++ blocknr_set_entry *new_bsep = NULL; ++ reiser4_block_nr block; ++ ++ txn_atom *atom; ++ ++ assert("zam-568", block_p != NULL); ++ block = *block_p; ++ assert("zam-569", len > 0); ++ ++ while ((len--) > 0) { ++ do { ++ atom = get_current_atom_locked(); ++ assert("zam-536", ++ !reiser4_blocknr_is_fake(jnode_get_block(cur))); ++ ret = ++ blocknr_set_add_pair(atom, &atom->wandered_map, ++ &new_bsep, ++ jnode_get_block(cur), &block); ++ } while (ret == -E_REPEAT); ++ ++ if (ret) { ++ /* deallocate blocks which were not added to wandered ++ map */ ++ reiser4_block_nr wide_len = len; ++ ++ reiser4_dealloc_blocks(&block, &wide_len, ++ BLOCK_NOT_COUNTED, ++ BA_FORMATTED ++ /* formatted, without defer */ ); ++ ++ return ret; ++ } ++ ++ spin_unlock_atom(atom); ++ ++ cur = list_entry(cur->capture_link.next, jnode, capture_link); ++ ++block; ++ } ++ ++ return 0; ++} ++ ++/* Allocate wandered blocks for current atom's OVERWRITE SET and immediately ++ submit IO for allocated blocks. We assume that current atom is in a stage ++ when any atom fusion is impossible and atom is unlocked and it is safe. */ ++static int alloc_wandered_blocks(struct commit_handle *ch, flush_queue_t *fq) ++{ ++ reiser4_block_nr block; ++ ++ int rest; ++ int len; ++ int ret; ++ ++ jnode *cur; ++ ++ assert("zam-534", ch->overwrite_set_size > 0); ++ ++ rest = ch->overwrite_set_size; ++ ++ cur = list_entry(ch->overwrite_set->next, jnode, capture_link); ++ while (ch->overwrite_set != &cur->capture_link) { ++ assert("zam-567", JF_ISSET(cur, JNODE_OVRWR)); ++ ++ ret = get_more_wandered_blocks(rest, &block, &len); ++ if (ret) ++ return ret; ++ ++ rest -= len; ++ ++ ret = add_region_to_wmap(cur, len, &block); ++ if (ret) ++ return ret; ++ ++ ret = write_jnodes_to_disk_extent(cur, len, &block, fq, 0); ++ if (ret) ++ return ret; ++ ++ while ((len--) > 0) { ++ assert("zam-604", ++ ch->overwrite_set != &cur->capture_link); ++ cur = list_entry(cur->capture_link.next, jnode, capture_link); ++ } ++ } ++ ++ return 0; ++} ++ ++/* allocate given number of nodes over the journal area and link them into a ++ list, return pointer to the first jnode in the list */ ++static int alloc_tx(struct commit_handle *ch, flush_queue_t * fq) ++{ ++ reiser4_blocknr_hint hint; ++ reiser4_block_nr allocated = 0; ++ reiser4_block_nr first, len; ++ jnode *cur; ++ jnode *txhead; ++ int ret; ++ reiser4_context *ctx; ++ reiser4_super_info_data *sbinfo; ++ ++ assert("zam-698", ch->tx_size > 0); ++ assert("zam-699", list_empty_careful(&ch->tx_list)); ++ ++ ctx = get_current_context(); ++ sbinfo = get_super_private(ctx->super); ++ ++ while (allocated < (unsigned)ch->tx_size) { ++ len = (ch->tx_size - allocated); ++ ++ reiser4_blocknr_hint_init(&hint); ++ ++ hint.block_stage = BLOCK_GRABBED; ++ ++ /* FIXME: there should be some block allocation policy for ++ nodes which contain wander records */ ++ ++ /* We assume that disk space for wandered record blocks can be ++ * taken from reserved area. */ ++ ret = reiser4_alloc_blocks(&hint, &first, &len, ++ BA_FORMATTED | BA_RESERVED | ++ BA_USE_DEFAULT_SEARCH_START); ++ reiser4_blocknr_hint_done(&hint); ++ ++ if (ret) ++ return ret; ++ ++ allocated += len; ++ ++ /* create jnodes for all wander records */ ++ while (len--) { ++ cur = reiser4_alloc_io_head(&first); ++ ++ if (cur == NULL) { ++ ret = RETERR(-ENOMEM); ++ goto free_not_assigned; ++ } ++ ++ ret = jinit_new(cur, reiser4_ctx_gfp_mask_get()); ++ ++ if (ret != 0) { ++ jfree(cur); ++ goto free_not_assigned; ++ } ++ ++ pin_jnode_data(cur); ++ ++ list_add_tail(&cur->capture_link, &ch->tx_list); ++ ++ first++; ++ } ++ } ++ ++ { /* format a on-disk linked list of wander records */ ++ int serial = 1; ++ ++ txhead = list_entry(ch->tx_list.next, jnode, capture_link); ++ format_tx_head(ch); ++ ++ cur = list_entry(txhead->capture_link.next, jnode, capture_link); ++ while (&ch->tx_list != &cur->capture_link) { ++ format_wander_record(ch, cur, serial++); ++ cur = list_entry(cur->capture_link.next, jnode, capture_link); ++ } ++ } ++ ++ { /* Fill wander records with Wandered Set */ ++ struct store_wmap_params params; ++ txn_atom *atom; ++ ++ params.cur = list_entry(txhead->capture_link.next, jnode, capture_link); ++ ++ params.idx = 0; ++ params.capacity = ++ wander_record_capacity(reiser4_get_current_sb()); ++ ++ atom = get_current_atom_locked(); ++ blocknr_set_iterator(atom, &atom->wandered_map, ++ &store_wmap_actor, ¶ms, 0); ++ spin_unlock_atom(atom); ++ } ++ ++ { /* relse all jnodes from tx_list */ ++ cur = list_entry(ch->tx_list.next, jnode, capture_link); ++ while (&ch->tx_list != &cur->capture_link) { ++ jrelse(cur); ++ cur = list_entry(cur->capture_link.next, jnode, capture_link); ++ } ++ } ++ ++ ret = write_jnode_list(&ch->tx_list, fq, NULL, 0); ++ ++ return ret; ++ ++ free_not_assigned: ++ /* We deallocate blocks not yet assigned to jnodes on tx_list. The ++ caller takes care about invalidating of tx list */ ++ reiser4_dealloc_blocks(&first, &len, BLOCK_NOT_COUNTED, BA_FORMATTED); ++ ++ return ret; ++} ++ ++static int commit_tx(struct commit_handle *ch) ++{ ++ flush_queue_t *fq; ++ int barrier; ++ int ret; ++ ++ /* Grab more space for wandered records. */ ++ ret = reiser4_grab_space_force((__u64) (ch->tx_size), BA_RESERVED); ++ if (ret) ++ return ret; ++ ++ fq = get_fq_for_current_atom(); ++ if (IS_ERR(fq)) ++ return PTR_ERR(fq); ++ ++ spin_unlock_atom(fq->atom); ++ do { ++ ret = alloc_wandered_blocks(ch, fq); ++ if (ret) ++ break; ++ ret = alloc_tx(ch, fq); ++ if (ret) ++ break; ++ } while (0); ++ ++ reiser4_fq_put(fq); ++ if (ret) ++ return ret; ++ repeat_wo_barrier: ++ barrier = reiser4_use_write_barrier(ch->super); ++ if (!barrier) { ++ ret = current_atom_finish_all_fq(); ++ if (ret) ++ return ret; ++ } ++ ret = update_journal_header(ch, barrier); ++ if (barrier) { ++ if (ret) { ++ if (ret == -EOPNOTSUPP) { ++ disable_write_barrier(ch->super); ++ goto repeat_wo_barrier; ++ } ++ return ret; ++ } ++ ret = current_atom_finish_all_fq(); ++ } ++ return ret; ++} ++ ++static int write_tx_back(struct commit_handle * ch) ++{ ++ flush_queue_t *fq; ++ int ret; ++ int barrier; ++ ++ reiser4_post_commit_hook(); ++ fq = get_fq_for_current_atom(); ++ if (IS_ERR(fq)) ++ return PTR_ERR(fq); ++ spin_unlock_atom(fq->atom); ++ ret = write_jnode_list( ++ ch->overwrite_set, fq, NULL, WRITEOUT_FOR_PAGE_RECLAIM); ++ reiser4_fq_put(fq); ++ if (ret) ++ return ret; ++ repeat_wo_barrier: ++ barrier = reiser4_use_write_barrier(ch->super); ++ if (!barrier) { ++ ret = current_atom_finish_all_fq(); ++ if (ret) ++ return ret; ++ } ++ ret = update_journal_footer(ch, barrier); ++ if (barrier) { ++ if (ret) { ++ if (ret == -EOPNOTSUPP) { ++ disable_write_barrier(ch->super); ++ goto repeat_wo_barrier; ++ } ++ return ret; ++ } ++ ret = current_atom_finish_all_fq(); ++ } ++ if (ret) ++ return ret; ++ reiser4_post_write_back_hook(); ++ return 0; ++} ++ ++/* We assume that at this moment all captured blocks are marked as RELOC or ++ WANDER (belong to Relocate o Overwrite set), all nodes from Relocate set ++ are submitted to write. ++*/ ++ ++int reiser4_write_logs(long *nr_submitted) ++{ ++ txn_atom *atom; ++ struct super_block *super = reiser4_get_current_sb(); ++ reiser4_super_info_data *sbinfo = get_super_private(super); ++ struct commit_handle ch; ++ int ret; ++ ++ writeout_mode_enable(); ++ ++ /* block allocator may add j-nodes to the clean_list */ ++ ret = reiser4_pre_commit_hook(); ++ if (ret) ++ return ret; ++ ++ /* No locks are required if we take atom which stage >= ++ * ASTAGE_PRE_COMMIT */ ++ atom = get_current_context()->trans->atom; ++ assert("zam-965", atom != NULL); ++ ++ /* relocate set is on the atom->clean_nodes list after ++ * current_atom_complete_writes() finishes. It can be safely ++ * uncaptured after commit_mutex is locked, because any atom that ++ * captures these nodes is guaranteed to commit after current one. ++ * ++ * This can only be done after reiser4_pre_commit_hook(), because it is where ++ * early flushed jnodes with CREATED bit are transferred to the ++ * overwrite list. */ ++ reiser4_invalidate_list(ATOM_CLEAN_LIST(atom)); ++ spin_lock_atom(atom); ++ /* There might be waiters for the relocate nodes which we have ++ * released, wake them up. */ ++ reiser4_atom_send_event(atom); ++ spin_unlock_atom(atom); ++ ++ if (REISER4_DEBUG) { ++ int level; ++ ++ for (level = 0; level < REAL_MAX_ZTREE_HEIGHT + 1; ++level) ++ assert("nikita-3352", ++ list_empty_careful(ATOM_DIRTY_LIST(atom, level))); ++ } ++ ++ sbinfo->nr_files_committed += (unsigned)atom->nr_objects_created; ++ sbinfo->nr_files_committed -= (unsigned)atom->nr_objects_deleted; ++ ++ init_commit_handle(&ch, atom); ++ ++ ch.free_blocks = sbinfo->blocks_free_committed; ++ ch.nr_files = sbinfo->nr_files_committed; ++ /* ZAM-FIXME-HANS: email me what the contention level is for the super ++ * lock. */ ++ ch.next_oid = oid_next(super); ++ ++ /* count overwrite set and place it in a separate list */ ++ ret = get_overwrite_set(&ch); ++ ++ if (ret <= 0) { ++ /* It is possible that overwrite set is empty here, it means ++ all captured nodes are clean */ ++ goto up_and_ret; ++ } ++ ++ /* Inform the caller about what number of dirty pages will be ++ * submitted to disk. */ ++ *nr_submitted += ch.overwrite_set_size - ch.nr_bitmap; ++ ++ /* count all records needed for storing of the wandered set */ ++ get_tx_size(&ch); ++ ++ ret = commit_tx(&ch); ++ if (ret) ++ goto up_and_ret; ++ ++ spin_lock_atom(atom); ++ reiser4_atom_set_stage(atom, ASTAGE_POST_COMMIT); ++ spin_unlock_atom(atom); ++ ++ ret = write_tx_back(&ch); ++ reiser4_post_write_back_hook(); ++ ++ up_and_ret: ++ if (ret) { ++ /* there could be fq attached to current atom; the only way to ++ remove them is: */ ++ current_atom_finish_all_fq(); ++ } ++ ++ /* free blocks of flushed transaction */ ++ dealloc_tx_list(&ch); ++ dealloc_wmap(&ch); ++ ++ put_overwrite_set(&ch); ++ ++ done_commit_handle(&ch); ++ ++ writeout_mode_disable(); ++ ++ return ret; ++} ++ ++/* consistency checks for journal data/control blocks: header, footer, log ++ records, transactions head blocks. All functions return zero on success. */ ++ ++static int check_journal_header(const jnode * node UNUSED_ARG) ++{ ++ /* FIXME: journal header has no magic field yet. */ ++ return 0; ++} ++ ++/* wait for write completion for all jnodes from given list */ ++static int wait_on_jnode_list(struct list_head *head) ++{ ++ jnode *scan; ++ int ret = 0; ++ ++ list_for_each_entry(scan, head, capture_link) { ++ struct page *pg = jnode_page(scan); ++ ++ if (pg) { ++ if (PageWriteback(pg)) ++ wait_on_page_writeback(pg); ++ ++ if (PageError(pg)) ++ ret++; ++ } ++ } ++ ++ return ret; ++} ++ ++static int check_journal_footer(const jnode * node UNUSED_ARG) ++{ ++ /* FIXME: journal footer has no magic field yet. */ ++ return 0; ++} ++ ++static int check_tx_head(const jnode * node) ++{ ++ struct tx_header *header = (struct tx_header *)jdata(node); ++ ++ if (memcmp(&header->magic, TX_HEADER_MAGIC, TX_HEADER_MAGIC_SIZE) != 0) { ++ warning("zam-627", "tx head at block %s corrupted\n", ++ sprint_address(jnode_get_block(node))); ++ return RETERR(-EIO); ++ } ++ ++ return 0; ++} ++ ++static int check_wander_record(const jnode * node) ++{ ++ struct wander_record_header *RH = ++ (struct wander_record_header *)jdata(node); ++ ++ if (memcmp(&RH->magic, WANDER_RECORD_MAGIC, WANDER_RECORD_MAGIC_SIZE) != ++ 0) { ++ warning("zam-628", "wander record at block %s corrupted\n", ++ sprint_address(jnode_get_block(node))); ++ return RETERR(-EIO); ++ } ++ ++ return 0; ++} ++ ++/* fill commit_handler structure by everything what is needed for update_journal_footer */ ++static int restore_commit_handle(struct commit_handle *ch, jnode *tx_head) ++{ ++ struct tx_header *TXH; ++ int ret; ++ ++ ret = jload(tx_head); ++ if (ret) ++ return ret; ++ ++ TXH = (struct tx_header *)jdata(tx_head); ++ ++ ch->free_blocks = le64_to_cpu(get_unaligned(&TXH->free_blocks)); ++ ch->nr_files = le64_to_cpu(get_unaligned(&TXH->nr_files)); ++ ch->next_oid = le64_to_cpu(get_unaligned(&TXH->next_oid)); ++ ++ jrelse(tx_head); ++ ++ list_add(&tx_head->capture_link, &ch->tx_list); ++ ++ return 0; ++} ++ ++/* replay one transaction: restore and write overwrite set in place */ ++static int replay_transaction(const struct super_block *s, ++ jnode * tx_head, ++ const reiser4_block_nr * log_rec_block_p, ++ const reiser4_block_nr * end_block, ++ unsigned int nr_wander_records) ++{ ++ reiser4_block_nr log_rec_block = *log_rec_block_p; ++ struct commit_handle ch; ++ LIST_HEAD(overwrite_set); ++ jnode *log; ++ int ret; ++ ++ init_commit_handle(&ch, NULL); ++ ch.overwrite_set = &overwrite_set; ++ ++ restore_commit_handle(&ch, tx_head); ++ ++ while (log_rec_block != *end_block) { ++ struct wander_record_header *header; ++ struct wander_entry *entry; ++ ++ int i; ++ ++ if (nr_wander_records == 0) { ++ warning("zam-631", ++ "number of wander records in the linked list" ++ " greater than number stored in tx head.\n"); ++ ret = RETERR(-EIO); ++ goto free_ow_set; ++ } ++ ++ log = reiser4_alloc_io_head(&log_rec_block); ++ if (log == NULL) ++ return RETERR(-ENOMEM); ++ ++ ret = jload(log); ++ if (ret < 0) { ++ reiser4_drop_io_head(log); ++ return ret; ++ } ++ ++ ret = check_wander_record(log); ++ if (ret) { ++ jrelse(log); ++ reiser4_drop_io_head(log); ++ return ret; ++ } ++ ++ header = (struct wander_record_header *)jdata(log); ++ log_rec_block = le64_to_cpu(get_unaligned(&header->next_block)); ++ ++ entry = (struct wander_entry *)(header + 1); ++ ++ /* restore overwrite set from wander record content */ ++ for (i = 0; i < wander_record_capacity(s); i++) { ++ reiser4_block_nr block; ++ jnode *node; ++ ++ block = le64_to_cpu(get_unaligned(&entry->wandered)); ++ if (block == 0) ++ break; ++ ++ node = reiser4_alloc_io_head(&block); ++ if (node == NULL) { ++ ret = RETERR(-ENOMEM); ++ /* ++ * FIXME-VS:??? ++ */ ++ jrelse(log); ++ reiser4_drop_io_head(log); ++ goto free_ow_set; ++ } ++ ++ ret = jload(node); ++ ++ if (ret < 0) { ++ reiser4_drop_io_head(node); ++ /* ++ * FIXME-VS:??? ++ */ ++ jrelse(log); ++ reiser4_drop_io_head(log); ++ goto free_ow_set; ++ } ++ ++ block = le64_to_cpu(get_unaligned(&entry->original)); ++ ++ assert("zam-603", block != 0); ++ ++ jnode_set_block(node, &block); ++ ++ list_add_tail(&node->capture_link, ch.overwrite_set); ++ ++ ++entry; ++ } ++ ++ jrelse(log); ++ reiser4_drop_io_head(log); ++ ++ --nr_wander_records; ++ } ++ ++ if (nr_wander_records != 0) { ++ warning("zam-632", "number of wander records in the linked list" ++ " less than number stored in tx head.\n"); ++ ret = RETERR(-EIO); ++ goto free_ow_set; ++ } ++ ++ { /* write wandered set in place */ ++ write_jnode_list(ch.overwrite_set, NULL, NULL, 0); ++ ret = wait_on_jnode_list(ch.overwrite_set); ++ ++ if (ret) { ++ ret = RETERR(-EIO); ++ goto free_ow_set; ++ } ++ } ++ ++ ret = update_journal_footer(&ch, 0); ++ ++ free_ow_set: ++ ++ while (!list_empty(ch.overwrite_set)) { ++ jnode *cur = list_entry(ch.overwrite_set->next, jnode, capture_link); ++ list_del_init(&cur->capture_link); ++ jrelse(cur); ++ reiser4_drop_io_head(cur); ++ } ++ ++ list_del_init(&tx_head->capture_link); ++ ++ done_commit_handle(&ch); ++ ++ return ret; ++} ++ ++/* find oldest committed and not played transaction and play it. The transaction ++ * was committed and journal header block was updated but the blocks from the ++ * process of writing the atom's overwrite set in-place and updating of journal ++ * footer block were not completed. This function completes the process by ++ * recovering the atom's overwrite set from their wandered locations and writes ++ * them in-place and updating the journal footer. */ ++static int replay_oldest_transaction(struct super_block *s) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(s); ++ jnode *jf = sbinfo->journal_footer; ++ unsigned int total; ++ struct journal_footer *F; ++ struct tx_header *T; ++ ++ reiser4_block_nr prev_tx; ++ reiser4_block_nr last_flushed_tx; ++ reiser4_block_nr log_rec_block = 0; ++ ++ jnode *tx_head; ++ ++ int ret; ++ ++ if ((ret = jload(jf)) < 0) ++ return ret; ++ ++ F = (struct journal_footer *)jdata(jf); ++ ++ last_flushed_tx = le64_to_cpu(get_unaligned(&F->last_flushed_tx)); ++ ++ jrelse(jf); ++ ++ if (sbinfo->last_committed_tx == last_flushed_tx) { ++ /* all transactions are replayed */ ++ return 0; ++ } ++ ++ prev_tx = sbinfo->last_committed_tx; ++ ++ /* searching for oldest not flushed transaction */ ++ while (1) { ++ tx_head = reiser4_alloc_io_head(&prev_tx); ++ if (!tx_head) ++ return RETERR(-ENOMEM); ++ ++ ret = jload(tx_head); ++ if (ret < 0) { ++ reiser4_drop_io_head(tx_head); ++ return ret; ++ } ++ ++ ret = check_tx_head(tx_head); ++ if (ret) { ++ jrelse(tx_head); ++ reiser4_drop_io_head(tx_head); ++ return ret; ++ } ++ ++ T = (struct tx_header *)jdata(tx_head); ++ ++ prev_tx = le64_to_cpu(get_unaligned(&T->prev_tx)); ++ ++ if (prev_tx == last_flushed_tx) ++ break; ++ ++ jrelse(tx_head); ++ reiser4_drop_io_head(tx_head); ++ } ++ ++ total = le32_to_cpu(get_unaligned(&T->total)); ++ log_rec_block = le64_to_cpu(get_unaligned(&T->next_block)); ++ ++ pin_jnode_data(tx_head); ++ jrelse(tx_head); ++ ++ ret = ++ replay_transaction(s, tx_head, &log_rec_block, ++ jnode_get_block(tx_head), total - 1); ++ ++ unpin_jnode_data(tx_head); ++ reiser4_drop_io_head(tx_head); ++ ++ if (ret) ++ return ret; ++ return -E_REPEAT; ++} ++ ++/* The reiser4 journal current implementation was optimized to not to capture ++ super block if certain super blocks fields are modified. Currently, the set ++ is (<free block count>, <OID allocator>). These fields are logged by ++ special way which includes storing them in each transaction head block at ++ atom commit time and writing that information to journal footer block at ++ atom flush time. For getting info from journal footer block to the ++ in-memory super block there is a special function ++ reiser4_journal_recover_sb_data() which should be called after disk format ++ plugin re-reads super block after journal replaying. ++*/ ++ ++/* get the information from journal footer in-memory super block */ ++int reiser4_journal_recover_sb_data(struct super_block *s) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(s); ++ struct journal_footer *jf; ++ int ret; ++ ++ assert("zam-673", sbinfo->journal_footer != NULL); ++ ++ ret = jload(sbinfo->journal_footer); ++ if (ret != 0) ++ return ret; ++ ++ ret = check_journal_footer(sbinfo->journal_footer); ++ if (ret != 0) ++ goto out; ++ ++ jf = (struct journal_footer *)jdata(sbinfo->journal_footer); ++ ++ /* was there at least one flushed transaction? */ ++ if (jf->last_flushed_tx) { ++ ++ /* restore free block counter logged in this transaction */ ++ reiser4_set_free_blocks(s, le64_to_cpu(get_unaligned(&jf->free_blocks))); ++ ++ /* restore oid allocator state */ ++ oid_init_allocator(s, ++ le64_to_cpu(get_unaligned(&jf->nr_files)), ++ le64_to_cpu(get_unaligned(&jf->next_oid))); ++ } ++ out: ++ jrelse(sbinfo->journal_footer); ++ return ret; ++} ++ ++/* reiser4 replay journal procedure */ ++int reiser4_journal_replay(struct super_block *s) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(s); ++ jnode *jh, *jf; ++ struct journal_header *header; ++ int nr_tx_replayed = 0; ++ int ret; ++ ++ assert("zam-582", sbinfo != NULL); ++ ++ jh = sbinfo->journal_header; ++ jf = sbinfo->journal_footer; ++ ++ if (!jh || !jf) { ++ /* it is possible that disk layout does not support journal ++ structures, we just warn about this */ ++ warning("zam-583", ++ "journal control blocks were not loaded by disk layout plugin. " ++ "journal replaying is not possible.\n"); ++ return 0; ++ } ++ ++ /* Take free block count from journal footer block. The free block ++ counter value corresponds the last flushed transaction state */ ++ ret = jload(jf); ++ if (ret < 0) ++ return ret; ++ ++ ret = check_journal_footer(jf); ++ if (ret) { ++ jrelse(jf); ++ return ret; ++ } ++ ++ jrelse(jf); ++ ++ /* store last committed transaction info in reiser4 in-memory super ++ block */ ++ ret = jload(jh); ++ if (ret < 0) ++ return ret; ++ ++ ret = check_journal_header(jh); ++ if (ret) { ++ jrelse(jh); ++ return ret; ++ } ++ ++ header = (struct journal_header *)jdata(jh); ++ sbinfo->last_committed_tx = le64_to_cpu(get_unaligned(&header->last_committed_tx)); ++ ++ jrelse(jh); ++ ++ /* replay committed transactions */ ++ while ((ret = replay_oldest_transaction(s)) == -E_REPEAT) ++ nr_tx_replayed++; ++ ++ return ret; ++} ++ ++/* load journal control block (either journal header or journal footer block) */ ++static int ++load_journal_control_block(jnode ** node, const reiser4_block_nr * block) ++{ ++ int ret; ++ ++ *node = reiser4_alloc_io_head(block); ++ if (!(*node)) ++ return RETERR(-ENOMEM); ++ ++ ret = jload(*node); ++ ++ if (ret) { ++ reiser4_drop_io_head(*node); ++ *node = NULL; ++ return ret; ++ } ++ ++ pin_jnode_data(*node); ++ jrelse(*node); ++ ++ return 0; ++} ++ ++/* unload journal header or footer and free jnode */ ++static void unload_journal_control_block(jnode ** node) ++{ ++ if (*node) { ++ unpin_jnode_data(*node); ++ reiser4_drop_io_head(*node); ++ *node = NULL; ++ } ++} ++ ++/* release journal control blocks */ ++void reiser4_done_journal_info(struct super_block *s) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(s); ++ ++ assert("zam-476", sbinfo != NULL); ++ ++ unload_journal_control_block(&sbinfo->journal_header); ++ unload_journal_control_block(&sbinfo->journal_footer); ++ rcu_barrier(); ++} ++ ++/* load journal control blocks */ ++int reiser4_init_journal_info(struct super_block *s) ++{ ++ reiser4_super_info_data *sbinfo = get_super_private(s); ++ journal_location *loc; ++ int ret; ++ ++ loc = &sbinfo->jloc; ++ ++ assert("zam-651", loc != NULL); ++ assert("zam-652", loc->header != 0); ++ assert("zam-653", loc->footer != 0); ++ ++ ret = load_journal_control_block(&sbinfo->journal_header, &loc->header); ++ ++ if (ret) ++ return ret; ++ ++ ret = load_journal_control_block(&sbinfo->journal_footer, &loc->footer); ++ ++ if (ret) { ++ unload_journal_control_block(&sbinfo->journal_header); ++ } ++ ++ return ret; ++} ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/wander.h linux-2.6.30/fs/reiser4/wander.h +--- linux-2.6.30.orig/fs/reiser4/wander.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/wander.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,135 @@ ++/* Copyright 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#if !defined (__FS_REISER4_WANDER_H__) ++#define __FS_REISER4_WANDER_H__ ++ ++#include "dformat.h" ++ ++#include <linux/fs.h> /* for struct super_block */ ++ ++/* REISER4 JOURNAL ON-DISK DATA STRUCTURES */ ++ ++#define TX_HEADER_MAGIC "TxMagic4" ++#define WANDER_RECORD_MAGIC "LogMagc4" ++ ++#define TX_HEADER_MAGIC_SIZE (8) ++#define WANDER_RECORD_MAGIC_SIZE (8) ++ ++/* journal header block format */ ++struct journal_header { ++ /* last written transaction head location */ ++ d64 last_committed_tx; ++}; ++ ++typedef struct journal_location { ++ reiser4_block_nr footer; ++ reiser4_block_nr header; ++} journal_location; ++ ++/* The wander.c head comment describes usage and semantic of all these structures */ ++/* journal footer block format */ ++struct journal_footer { ++ /* last flushed transaction location. */ ++ /* This block number is no more valid after the transaction it points ++ to gets flushed, this number is used only at journal replaying time ++ for detection of the end of on-disk list of committed transactions ++ which were not flushed completely */ ++ d64 last_flushed_tx; ++ ++ /* free block counter is written in journal footer at transaction ++ flushing , not in super block because free blocks counter is logged ++ by another way than super block fields (root pointer, for ++ example). */ ++ d64 free_blocks; ++ ++ /* number of used OIDs and maximal used OID are logged separately from ++ super block */ ++ d64 nr_files; ++ d64 next_oid; ++}; ++ ++/* Each wander record (except the first one) has unified format with wander ++ record header followed by an array of log entries */ ++struct wander_record_header { ++ /* when there is no predefined location for wander records, this magic ++ string should help reiser4fsck. */ ++ char magic[WANDER_RECORD_MAGIC_SIZE]; ++ ++ /* transaction id */ ++ d64 id; ++ ++ /* total number of wander records in current transaction */ ++ d32 total; ++ ++ /* this block number in transaction */ ++ d32 serial; ++ ++ /* number of previous block in commit */ ++ d64 next_block; ++}; ++ ++/* The first wander record (transaction head) of written transaction has the ++ special format */ ++struct tx_header { ++ /* magic string makes first block in transaction different from other ++ logged blocks, it should help fsck. */ ++ char magic[TX_HEADER_MAGIC_SIZE]; ++ ++ /* transaction id */ ++ d64 id; ++ ++ /* total number of records (including this first tx head) in the ++ transaction */ ++ d32 total; ++ ++ /* align next field to 8-byte boundary; this field always is zero */ ++ d32 padding; ++ ++ /* block number of previous transaction head */ ++ d64 prev_tx; ++ ++ /* next wander record location */ ++ d64 next_block; ++ ++ /* committed versions of free blocks counter */ ++ d64 free_blocks; ++ ++ /* number of used OIDs (nr_files) and maximal used OID are logged ++ separately from super block */ ++ d64 nr_files; ++ d64 next_oid; ++}; ++ ++/* A transaction gets written to disk as a set of wander records (each wander ++ record size is fs block) */ ++ ++/* As it was told above a wander The rest of wander record is filled by these log entries, unused space filled ++ by zeroes */ ++struct wander_entry { ++ d64 original; /* block original location */ ++ d64 wandered; /* block wandered location */ ++}; ++ ++/* REISER4 JOURNAL WRITER FUNCTIONS */ ++ ++extern int reiser4_write_logs(long *); ++extern int reiser4_journal_replay(struct super_block *); ++extern int reiser4_journal_recover_sb_data(struct super_block *); ++ ++extern int reiser4_init_journal_info(struct super_block *); ++extern void reiser4_done_journal_info(struct super_block *); ++ ++extern int write_jnode_list(struct list_head *, flush_queue_t *, long *, int); ++ ++#endif /* __FS_REISER4_WANDER_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ scroll-step: 1 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/writeout.h linux-2.6.30/fs/reiser4/writeout.h +--- linux-2.6.30.orig/fs/reiser4/writeout.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/writeout.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,21 @@ ++/* Copyright 2002, 2003, 2004 by Hans Reiser, licensing governed by reiser4/README */ ++ ++#if !defined (__FS_REISER4_WRITEOUT_H__) ++ ++#define WRITEOUT_SINGLE_STREAM (0x1) ++#define WRITEOUT_FOR_PAGE_RECLAIM (0x2) ++#define WRITEOUT_BARRIER (0x4) ++ ++extern int reiser4_get_writeout_flags(void); ++ ++#endif /* __FS_REISER4_WRITEOUT_H__ */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 80 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/znode.c linux-2.6.30/fs/reiser4/znode.c +--- linux-2.6.30.orig/fs/reiser4/znode.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/znode.c 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,1029 @@ ++/* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++/* Znode manipulation functions. */ ++/* Znode is the in-memory header for a tree node. It is stored ++ separately from the node itself so that it does not get written to ++ disk. In this respect znode is like buffer head or page head. We ++ also use znodes for additional reiser4 specific purposes: ++ ++ . they are organized into tree structure which is a part of whole ++ reiser4 tree. ++ . they are used to implement node grained locking ++ . they are used to keep additional state associated with a ++ node ++ . they contain links to lists used by the transaction manager ++ ++ Znode is attached to some variable "block number" which is instance of ++ fs/reiser4/tree.h:reiser4_block_nr type. Znode can exist without ++ appropriate node being actually loaded in memory. Existence of znode itself ++ is regulated by reference count (->x_count) in it. Each time thread ++ acquires reference to znode through call to zget(), ->x_count is ++ incremented and decremented on call to zput(). Data (content of node) are ++ brought in memory through call to zload(), which also increments ->d_count ++ reference counter. zload can block waiting on IO. Call to zrelse() ++ decreases this counter. Also, ->c_count keeps track of number of child ++ znodes and prevents parent znode from being recycled until all of its ++ children are. ->c_count is decremented whenever child goes out of existence ++ (being actually recycled in zdestroy()) which can be some time after last ++ reference to this child dies if we support some form of LRU cache for ++ znodes. ++ ++*/ ++/* EVERY ZNODE'S STORY ++ ++ 1. His infancy. ++ ++ Once upon a time, the znode was born deep inside of zget() by call to ++ zalloc(). At the return from zget() znode had: ++ ++ . reference counter (x_count) of 1 ++ . assigned block number, marked as used in bitmap ++ . pointer to parent znode. Root znode parent pointer points ++ to its father: "fake" znode. This, in turn, has NULL parent pointer. ++ . hash table linkage ++ . no data loaded from disk ++ . no node plugin ++ . no sibling linkage ++ ++ 2. His childhood ++ ++ Each node is either brought into memory as a result of tree traversal, or ++ created afresh, creation of the root being a special case of the latter. In ++ either case it's inserted into sibling list. This will typically require ++ some ancillary tree traversing, but ultimately both sibling pointers will ++ exist and JNODE_LEFT_CONNECTED and JNODE_RIGHT_CONNECTED will be true in ++ zjnode.state. ++ ++ 3. His youth. ++ ++ If znode is bound to already existing node in a tree, its content is read ++ from the disk by call to zload(). At that moment, JNODE_LOADED bit is set ++ in zjnode.state and zdata() function starts to return non null for this ++ znode. zload() further calls zparse() that determines which node layout ++ this node is rendered in, and sets ->nplug on success. ++ ++ If znode is for new node just created, memory for it is allocated and ++ zinit_new() function is called to initialise data, according to selected ++ node layout. ++ ++ 4. His maturity. ++ ++ After this point, znode lingers in memory for some time. Threads can ++ acquire references to znode either by blocknr through call to zget(), or by ++ following a pointer to unallocated znode from internal item. Each time ++ reference to znode is obtained, x_count is increased. Thread can read/write ++ lock znode. Znode data can be loaded through calls to zload(), d_count will ++ be increased appropriately. If all references to znode are released ++ (x_count drops to 0), znode is not recycled immediately. Rather, it is ++ still cached in the hash table in the hope that it will be accessed ++ shortly. ++ ++ There are two ways in which znode existence can be terminated: ++ ++ . sudden death: node bound to this znode is removed from the tree ++ . overpopulation: znode is purged out of memory due to memory pressure ++ ++ 5. His death. ++ ++ Death is complex process. ++ ++ When we irrevocably commit ourselves to decision to remove node from the ++ tree, JNODE_HEARD_BANSHEE bit is set in zjnode.state of corresponding ++ znode. This is done either in ->kill_hook() of internal item or in ++ reiser4_kill_root() function when tree root is removed. ++ ++ At this moment znode still has: ++ ++ . locks held on it, necessary write ones ++ . references to it ++ . disk block assigned to it ++ . data loaded from the disk ++ . pending requests for lock ++ ++ But once JNODE_HEARD_BANSHEE bit set, last call to unlock_znode() does node ++ deletion. Node deletion includes two phases. First all ways to get ++ references to that znode (sibling and parent links and hash lookup using ++ block number stored in parent node) should be deleted -- it is done through ++ sibling_list_remove(), also we assume that nobody uses down link from ++ parent node due to its nonexistence or proper parent node locking and ++ nobody uses parent pointers from children due to absence of them. Second we ++ invalidate all pending lock requests which still are on znode's lock ++ request queue, this is done by reiser4_invalidate_lock(). Another ++ JNODE_IS_DYING znode status bit is used to invalidate pending lock requests. ++ Once it set all requesters are forced to return -EINVAL from ++ longterm_lock_znode(). Future locking attempts are not possible because all ++ ways to get references to that znode are removed already. Last, node is ++ uncaptured from transaction. ++ ++ When last reference to the dying znode is just about to be released, ++ block number for this lock is released and znode is removed from the ++ hash table. ++ ++ Now znode can be recycled. ++ ++ [it's possible to free bitmap block and remove znode from the hash ++ table when last lock is released. This will result in having ++ referenced but completely orphaned znode] ++ ++ 6. Limbo ++ ++ As have been mentioned above znodes with reference counter 0 are ++ still cached in a hash table. Once memory pressure increases they are ++ purged out of there [this requires something like LRU list for ++ efficient implementation. LRU list would also greatly simplify ++ implementation of coord cache that would in this case morph to just ++ scanning some initial segment of LRU list]. Data loaded into ++ unreferenced znode are flushed back to the durable storage if ++ necessary and memory is freed. Znodes themselves can be recycled at ++ this point too. ++ ++*/ ++ ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "coord.h" ++#include "plugin/plugin_header.h" ++#include "plugin/node/node.h" ++#include "plugin/plugin.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree.h" ++#include "tree_walk.h" ++#include "super.h" ++#include "reiser4.h" ++ ++#include <linux/pagemap.h> ++#include <linux/spinlock.h> ++#include <linux/slab.h> ++#include <linux/err.h> ++ ++static z_hash_table *get_htable(reiser4_tree *, ++ const reiser4_block_nr * const blocknr); ++static z_hash_table *znode_get_htable(const znode *); ++static void zdrop(znode *); ++ ++/* hash table support */ ++ ++/* compare two block numbers for equality. Used by hash-table macros */ ++static inline int ++blknreq(const reiser4_block_nr * b1, const reiser4_block_nr * b2) ++{ ++ assert("nikita-534", b1 != NULL); ++ assert("nikita-535", b2 != NULL); ++ ++ return *b1 == *b2; ++} ++ ++/* Hash znode by block number. Used by hash-table macros */ ++/* Audited by: umka (2002.06.11) */ ++static inline __u32 ++blknrhashfn(z_hash_table * table, const reiser4_block_nr * b) ++{ ++ assert("nikita-536", b != NULL); ++ ++ return *b & (REISER4_ZNODE_HASH_TABLE_SIZE - 1); ++} ++ ++/* The hash table definition */ ++#define KMALLOC(size) kmalloc((size), reiser4_ctx_gfp_mask_get()) ++#define KFREE(ptr, size) kfree(ptr) ++TYPE_SAFE_HASH_DEFINE(z, znode, reiser4_block_nr, zjnode.key.z, zjnode.link.z, ++ blknrhashfn, blknreq); ++#undef KFREE ++#undef KMALLOC ++ ++/* slab for znodes */ ++static struct kmem_cache *znode_cache; ++ ++int znode_shift_order; ++ ++/** ++ * init_znodes - create znode cache ++ * ++ * Initializes slab cache of znodes. It is part of reiser4 module initialization. ++ */ ++int init_znodes(void) ++{ ++ znode_cache = kmem_cache_create("znode", sizeof(znode), 0, ++ SLAB_HWCACHE_ALIGN | ++ SLAB_RECLAIM_ACCOUNT, NULL); ++ if (znode_cache == NULL) ++ return RETERR(-ENOMEM); ++ ++ for (znode_shift_order = 0; (1 << znode_shift_order) < sizeof(znode); ++ ++znode_shift_order); ++ --znode_shift_order; ++ return 0; ++} ++ ++/** ++ * done_znodes - delete znode cache ++ * ++ * This is called on reiser4 module unloading or system shutdown. ++ */ ++void done_znodes(void) ++{ ++ destroy_reiser4_cache(&znode_cache); ++} ++ ++/* call this to initialise tree of znodes */ ++int znodes_tree_init(reiser4_tree * tree /* tree to initialise znodes for */ ) ++{ ++ int result; ++ assert("umka-050", tree != NULL); ++ ++ rwlock_init(&tree->dk_lock); ++ ++ result = z_hash_init(&tree->zhash_table, REISER4_ZNODE_HASH_TABLE_SIZE); ++ if (result != 0) ++ return result; ++ result = z_hash_init(&tree->zfake_table, REISER4_ZNODE_HASH_TABLE_SIZE); ++ return result; ++} ++ ++/* free this znode */ ++void zfree(znode * node /* znode to free */ ) ++{ ++ assert("nikita-465", node != NULL); ++ assert("nikita-2120", znode_page(node) == NULL); ++ assert("nikita-2301", list_empty_careful(&node->lock.owners)); ++ assert("nikita-2302", list_empty_careful(&node->lock.requestors)); ++ assert("nikita-2663", (list_empty_careful(&ZJNODE(node)->capture_link) && ++ NODE_LIST(ZJNODE(node)) == NOT_CAPTURED)); ++ assert("nikita-3220", list_empty(&ZJNODE(node)->jnodes)); ++ assert("nikita-3293", !znode_is_right_connected(node)); ++ assert("nikita-3294", !znode_is_left_connected(node)); ++ assert("nikita-3295", node->left == NULL); ++ assert("nikita-3296", node->right == NULL); ++ ++ /* not yet phash_jnode_destroy(ZJNODE(node)); */ ++ ++ kmem_cache_free(znode_cache, node); ++} ++ ++/* call this to free tree of znodes */ ++void znodes_tree_done(reiser4_tree * tree /* tree to finish with znodes of */ ) ++{ ++ znode *node; ++ znode *next; ++ z_hash_table *ztable; ++ ++ /* scan znode hash-tables and kill all znodes, then free hash tables ++ * themselves. */ ++ ++ assert("nikita-795", tree != NULL); ++ ++ ztable = &tree->zhash_table; ++ ++ if (ztable->_table != NULL) { ++ for_all_in_htable(ztable, z, node, next) { ++ node->c_count = 0; ++ node->in_parent.node = NULL; ++ assert("nikita-2179", atomic_read(&ZJNODE(node)->x_count) == 0); ++ zdrop(node); ++ } ++ ++ z_hash_done(&tree->zhash_table); ++ } ++ ++ ztable = &tree->zfake_table; ++ ++ if (ztable->_table != NULL) { ++ for_all_in_htable(ztable, z, node, next) { ++ node->c_count = 0; ++ node->in_parent.node = NULL; ++ assert("nikita-2179", atomic_read(&ZJNODE(node)->x_count) == 0); ++ zdrop(node); ++ } ++ ++ z_hash_done(&tree->zfake_table); ++ } ++} ++ ++/* ZNODE STRUCTURES */ ++ ++/* allocate fresh znode */ ++znode *zalloc(gfp_t gfp_flag /* allocation flag */ ) ++{ ++ znode *node; ++ ++ node = kmem_cache_alloc(znode_cache, gfp_flag); ++ return node; ++} ++ ++/* Initialize fields of znode ++ @node: znode to initialize; ++ @parent: parent znode; ++ @tree: tree we are in. */ ++void zinit(znode * node, const znode * parent, reiser4_tree * tree) ++{ ++ assert("nikita-466", node != NULL); ++ assert("umka-268", current_tree != NULL); ++ ++ memset(node, 0, sizeof *node); ++ ++ assert("umka-051", tree != NULL); ++ ++ jnode_init(&node->zjnode, tree, JNODE_FORMATTED_BLOCK); ++ reiser4_init_lock(&node->lock); ++ init_parent_coord(&node->in_parent, parent); ++} ++ ++/* ++ * remove znode from indices. This is called jput() when last reference on ++ * znode is released. ++ */ ++void znode_remove(znode * node /* znode to remove */ , reiser4_tree * tree) ++{ ++ assert("nikita-2108", node != NULL); ++ assert("nikita-470", node->c_count == 0); ++ assert_rw_write_locked(&(tree->tree_lock)); ++ ++ /* remove reference to this znode from cbk cache */ ++ cbk_cache_invalidate(node, tree); ++ ++ /* update c_count of parent */ ++ if (znode_parent(node) != NULL) { ++ assert("nikita-472", znode_parent(node)->c_count > 0); ++ /* father, onto your hands I forward my spirit... */ ++ znode_parent(node)->c_count--; ++ node->in_parent.node = NULL; ++ } else { ++ /* orphaned znode?! Root? */ ++ } ++ ++ /* remove znode from hash-table */ ++ z_hash_remove_rcu(znode_get_htable(node), node); ++} ++ ++/* zdrop() -- Remove znode from the tree. ++ ++ This is called when znode is removed from the memory. */ ++static void zdrop(znode * node /* znode to finish with */ ) ++{ ++ jdrop(ZJNODE(node)); ++} ++ ++/* ++ * put znode into right place in the hash table. This is called by relocate ++ * code. ++ */ ++int znode_rehash(znode * node /* node to rehash */ , ++ const reiser4_block_nr * new_block_nr /* new block number */ ) ++{ ++ z_hash_table *oldtable; ++ z_hash_table *newtable; ++ reiser4_tree *tree; ++ ++ assert("nikita-2018", node != NULL); ++ ++ tree = znode_get_tree(node); ++ oldtable = znode_get_htable(node); ++ newtable = get_htable(tree, new_block_nr); ++ ++ write_lock_tree(tree); ++ /* remove znode from hash-table */ ++ z_hash_remove_rcu(oldtable, node); ++ ++ /* assertion no longer valid due to RCU */ ++ /* assert("nikita-2019", z_hash_find(newtable, new_block_nr) == NULL); */ ++ ++ /* update blocknr */ ++ znode_set_block(node, new_block_nr); ++ node->zjnode.key.z = *new_block_nr; ++ ++ /* insert it into hash */ ++ z_hash_insert_rcu(newtable, node); ++ write_unlock_tree(tree); ++ return 0; ++} ++ ++/* ZNODE LOOKUP, GET, PUT */ ++ ++/* zlook() - get znode with given block_nr in a hash table or return NULL ++ ++ If result is non-NULL then the znode's x_count is incremented. Internal version ++ accepts pre-computed hash index. The hash table is accessed under caller's ++ tree->hash_lock. ++*/ ++znode *zlook(reiser4_tree * tree, const reiser4_block_nr * const blocknr) ++{ ++ znode *result; ++ __u32 hash; ++ z_hash_table *htable; ++ ++ assert("jmacd-506", tree != NULL); ++ assert("jmacd-507", blocknr != NULL); ++ ++ htable = get_htable(tree, blocknr); ++ hash = blknrhashfn(htable, blocknr); ++ ++ rcu_read_lock(); ++ result = z_hash_find_index(htable, hash, blocknr); ++ ++ if (result != NULL) { ++ add_x_ref(ZJNODE(result)); ++ result = znode_rip_check(tree, result); ++ } ++ rcu_read_unlock(); ++ ++ return result; ++} ++ ++/* return hash table where znode with block @blocknr is (or should be) ++ * stored */ ++static z_hash_table *get_htable(reiser4_tree * tree, ++ const reiser4_block_nr * const blocknr) ++{ ++ z_hash_table *table; ++ if (is_disk_addr_unallocated(blocknr)) ++ table = &tree->zfake_table; ++ else ++ table = &tree->zhash_table; ++ return table; ++} ++ ++/* return hash table where znode @node is (or should be) stored */ ++static z_hash_table *znode_get_htable(const znode * node) ++{ ++ return get_htable(znode_get_tree(node), znode_get_block(node)); ++} ++ ++/* zget() - get znode from hash table, allocating it if necessary. ++ ++ First a call to zlook, locating a x-referenced znode if one ++ exists. If znode is not found, allocate new one and return. Result ++ is returned with x_count reference increased. ++ ++ LOCKS TAKEN: TREE_LOCK, ZNODE_LOCK ++ LOCK ORDERING: NONE ++*/ ++znode *zget(reiser4_tree * tree, ++ const reiser4_block_nr * const blocknr, ++ znode * parent, tree_level level, gfp_t gfp_flag) ++{ ++ znode *result; ++ __u32 hashi; ++ ++ z_hash_table *zth; ++ ++ assert("jmacd-512", tree != NULL); ++ assert("jmacd-513", blocknr != NULL); ++ assert("jmacd-514", level < REISER4_MAX_ZTREE_HEIGHT); ++ ++ zth = get_htable(tree, blocknr); ++ hashi = blknrhashfn(zth, blocknr); ++ ++ /* NOTE-NIKITA address-as-unallocated-blocknr still is not ++ implemented. */ ++ ++ z_hash_prefetch_bucket(zth, hashi); ++ ++ rcu_read_lock(); ++ /* Find a matching BLOCKNR in the hash table. If the znode is found, ++ we obtain an reference (x_count) but the znode remains unlocked. ++ Have to worry about race conditions later. */ ++ result = z_hash_find_index(zth, hashi, blocknr); ++ /* According to the current design, the hash table lock protects new ++ znode references. */ ++ if (result != NULL) { ++ add_x_ref(ZJNODE(result)); ++ /* NOTE-NIKITA it should be so, but special case during ++ creation of new root makes such assertion highly ++ complicated. */ ++ assert("nikita-2131", 1 || znode_parent(result) == parent || ++ (ZF_ISSET(result, JNODE_ORPHAN) ++ && (znode_parent(result) == NULL))); ++ result = znode_rip_check(tree, result); ++ } ++ ++ rcu_read_unlock(); ++ ++ if (!result) { ++ znode *shadow; ++ ++ result = zalloc(gfp_flag); ++ if (!result) { ++ return ERR_PTR(RETERR(-ENOMEM)); ++ } ++ ++ zinit(result, parent, tree); ++ ZJNODE(result)->blocknr = *blocknr; ++ ZJNODE(result)->key.z = *blocknr; ++ result->level = level; ++ ++ write_lock_tree(tree); ++ ++ shadow = z_hash_find_index(zth, hashi, blocknr); ++ if (unlikely(shadow != NULL && !ZF_ISSET(shadow, JNODE_RIP))) { ++ jnode_list_remove(ZJNODE(result)); ++ zfree(result); ++ result = shadow; ++ } else { ++ result->version = znode_build_version(tree); ++ z_hash_insert_index_rcu(zth, hashi, result); ++ ++ if (parent != NULL) ++ ++parent->c_count; ++ } ++ ++ add_x_ref(ZJNODE(result)); ++ ++ write_unlock_tree(tree); ++ } ++#if REISER4_DEBUG ++ if (!reiser4_blocknr_is_fake(blocknr) && *blocknr != 0) ++ reiser4_check_block(blocknr, 1); ++#endif ++ /* Check for invalid tree level, return -EIO */ ++ if (unlikely(znode_get_level(result) != level)) { ++ warning("jmacd-504", ++ "Wrong level for cached block %llu: %i expecting %i", ++ (unsigned long long)(*blocknr), znode_get_level(result), ++ level); ++ zput(result); ++ return ERR_PTR(RETERR(-EIO)); ++ } ++ ++ assert("nikita-1227", znode_invariant(result)); ++ ++ return result; ++} ++ ++/* ZNODE PLUGINS/DATA */ ++ ++/* "guess" plugin for node loaded from the disk. Plugin id of node plugin is ++ stored at the fixed offset from the beginning of the node. */ ++static node_plugin *znode_guess_plugin(const znode * node /* znode to guess ++ * plugin of */ ) ++{ ++ reiser4_tree *tree; ++ ++ assert("nikita-1053", node != NULL); ++ assert("nikita-1055", zdata(node) != NULL); ++ ++ tree = znode_get_tree(node); ++ assert("umka-053", tree != NULL); ++ ++ if (reiser4_is_set(tree->super, REISER4_ONE_NODE_PLUGIN)) { ++ return tree->nplug; ++ } else { ++ return node_plugin_by_disk_id ++ (tree, &((common_node_header *) zdata(node))->plugin_id); ++#ifdef GUESS_EXISTS ++ reiser4_plugin *plugin; ++ ++ /* NOTE-NIKITA add locking here when dynamic plugins will be ++ * implemented */ ++ for_all_plugins(REISER4_NODE_PLUGIN_TYPE, plugin) { ++ if ((plugin->u.node.guess != NULL) ++ && plugin->u.node.guess(node)) ++ return plugin; ++ } ++ warning("nikita-1057", "Cannot guess node plugin"); ++ print_znode("node", node); ++ return NULL; ++#endif ++ } ++} ++ ++/* parse node header and install ->node_plugin */ ++int zparse(znode * node /* znode to parse */ ) ++{ ++ int result; ++ ++ assert("nikita-1233", node != NULL); ++ assert("nikita-2370", zdata(node) != NULL); ++ ++ if (node->nplug == NULL) { ++ node_plugin *nplug; ++ ++ nplug = znode_guess_plugin(node); ++ if (likely(nplug != NULL)) { ++ result = nplug->parse(node); ++ if (likely(result == 0)) ++ node->nplug = nplug; ++ } else { ++ result = RETERR(-EIO); ++ } ++ } else ++ result = 0; ++ return result; ++} ++ ++/* zload with readahead */ ++int zload_ra(znode * node /* znode to load */ , ra_info_t * info) ++{ ++ int result; ++ ++ assert("nikita-484", node != NULL); ++ assert("nikita-1377", znode_invariant(node)); ++ assert("jmacd-7771", !znode_above_root(node)); ++ assert("nikita-2125", atomic_read(&ZJNODE(node)->x_count) > 0); ++ assert("nikita-3016", reiser4_schedulable()); ++ ++ if (info) ++ formatted_readahead(node, info); ++ ++ result = jload(ZJNODE(node)); ++ assert("nikita-1378", znode_invariant(node)); ++ return result; ++} ++ ++/* load content of node into memory */ ++int zload(znode * node) ++{ ++ return zload_ra(node, NULL); ++} ++ ++/* call node plugin to initialise newly allocated node. */ ++int zinit_new(znode * node /* znode to initialise */ , gfp_t gfp_flags) ++{ ++ return jinit_new(ZJNODE(node), gfp_flags); ++} ++ ++/* drop reference to node data. When last reference is dropped, data are ++ unloaded. */ ++void zrelse(znode * node /* znode to release references to */ ) ++{ ++ assert("nikita-1381", znode_invariant(node)); ++ ++ jrelse(ZJNODE(node)); ++} ++ ++/* returns free space in node */ ++unsigned znode_free_space(znode * node /* znode to query */ ) ++{ ++ assert("nikita-852", node != NULL); ++ return node_plugin_by_node(node)->free_space(node); ++} ++ ++/* left delimiting key of znode */ ++reiser4_key *znode_get_rd_key(znode * node /* znode to query */ ) ++{ ++ assert("nikita-958", node != NULL); ++ assert_rw_locked(&(znode_get_tree(node)->dk_lock)); ++ assert("nikita-3067", LOCK_CNT_GTZ(rw_locked_dk)); ++ assert("nikita-30671", node->rd_key_version != 0); ++ return &node->rd_key; ++} ++ ++/* right delimiting key of znode */ ++reiser4_key *znode_get_ld_key(znode * node /* znode to query */ ) ++{ ++ assert("nikita-974", node != NULL); ++ assert_rw_locked(&(znode_get_tree(node)->dk_lock)); ++ assert("nikita-3068", LOCK_CNT_GTZ(rw_locked_dk)); ++ assert("nikita-30681", node->ld_key_version != 0); ++ return &node->ld_key; ++} ++ ++ON_DEBUG(atomic_t delim_key_version = ATOMIC_INIT(0); ++ ) ++ ++/* update right-delimiting key of @node */ ++reiser4_key *znode_set_rd_key(znode * node, const reiser4_key * key) ++{ ++ assert("nikita-2937", node != NULL); ++ assert("nikita-2939", key != NULL); ++ assert_rw_write_locked(&(znode_get_tree(node)->dk_lock)); ++ assert("nikita-3069", LOCK_CNT_GTZ(write_locked_dk)); ++ assert("nikita-2944", ++ znode_is_any_locked(node) || ++ znode_get_level(node) != LEAF_LEVEL || ++ keyge(key, &node->rd_key) || ++ keyeq(&node->rd_key, reiser4_min_key()) || ++ ZF_ISSET(node, JNODE_HEARD_BANSHEE)); ++ ++ node->rd_key = *key; ++ ON_DEBUG(node->rd_key_version = atomic_inc_return(&delim_key_version)); ++ return &node->rd_key; ++} ++ ++/* update left-delimiting key of @node */ ++reiser4_key *znode_set_ld_key(znode * node, const reiser4_key * key) ++{ ++ assert("nikita-2940", node != NULL); ++ assert("nikita-2941", key != NULL); ++ assert_rw_write_locked(&(znode_get_tree(node)->dk_lock)); ++ assert("nikita-3070", LOCK_CNT_GTZ(write_locked_dk)); ++ assert("nikita-2943", ++ znode_is_any_locked(node) || keyeq(&node->ld_key, ++ reiser4_min_key())); ++ ++ node->ld_key = *key; ++ ON_DEBUG(node->ld_key_version = atomic_inc_return(&delim_key_version)); ++ return &node->ld_key; ++} ++ ++/* true if @key is inside key range for @node */ ++int znode_contains_key(znode * node /* znode to look in */ , ++ const reiser4_key * key /* key to look for */ ) ++{ ++ assert("nikita-1237", node != NULL); ++ assert("nikita-1238", key != NULL); ++ ++ /* left_delimiting_key <= key <= right_delimiting_key */ ++ return keyle(znode_get_ld_key(node), key) ++ && keyle(key, znode_get_rd_key(node)); ++} ++ ++/* same as znode_contains_key(), but lock dk lock */ ++int znode_contains_key_lock(znode * node /* znode to look in */ , ++ const reiser4_key * key /* key to look for */ ) ++{ ++ int result; ++ ++ assert("umka-056", node != NULL); ++ assert("umka-057", key != NULL); ++ ++ read_lock_dk(znode_get_tree(node)); ++ result = znode_contains_key(node, key); ++ read_unlock_dk(znode_get_tree(node)); ++ return result; ++} ++ ++/* get parent pointer, assuming tree is not locked */ ++znode *znode_parent_nolock(const znode * node /* child znode */ ) ++{ ++ assert("nikita-1444", node != NULL); ++ return node->in_parent.node; ++} ++ ++/* get parent pointer of znode */ ++znode *znode_parent(const znode * node /* child znode */ ) ++{ ++ assert("nikita-1226", node != NULL); ++ assert("nikita-1406", LOCK_CNT_GTZ(rw_locked_tree)); ++ return znode_parent_nolock(node); ++} ++ ++/* detect uber znode used to protect in-superblock tree root pointer */ ++int znode_above_root(const znode * node /* znode to query */ ) ++{ ++ assert("umka-059", node != NULL); ++ ++ return disk_addr_eq(&ZJNODE(node)->blocknr, &UBER_TREE_ADDR); ++} ++ ++/* check that @node is root---that its block number is recorder in the tree as ++ that of root node */ ++#if REISER4_DEBUG ++static int znode_is_true_root(const znode * node /* znode to query */ ) ++{ ++ assert("umka-060", node != NULL); ++ assert("umka-061", current_tree != NULL); ++ ++ return disk_addr_eq(znode_get_block(node), ++ &znode_get_tree(node)->root_block); ++} ++#endif ++ ++/* check that @node is root */ ++int znode_is_root(const znode * node /* znode to query */ ) ++{ ++ assert("nikita-1206", node != NULL); ++ ++ return znode_get_level(node) == znode_get_tree(node)->height; ++} ++ ++/* Returns true is @node was just created by zget() and wasn't ever loaded ++ into memory. */ ++/* NIKITA-HANS: yes */ ++int znode_just_created(const znode * node) ++{ ++ assert("nikita-2188", node != NULL); ++ return (znode_page(node) == NULL); ++} ++ ++/* obtain updated ->znode_epoch. See seal.c for description. */ ++__u64 znode_build_version(reiser4_tree * tree) ++{ ++ __u64 result; ++ ++ spin_lock(&tree->epoch_lock); ++ result = ++tree->znode_epoch; ++ spin_unlock(&tree->epoch_lock); ++ return result; ++} ++ ++void init_load_count(load_count * dh) ++{ ++ assert("nikita-2105", dh != NULL); ++ memset(dh, 0, sizeof *dh); ++} ++ ++void done_load_count(load_count * dh) ++{ ++ assert("nikita-2106", dh != NULL); ++ if (dh->node != NULL) { ++ for (; dh->d_ref > 0; --dh->d_ref) ++ zrelse(dh->node); ++ dh->node = NULL; ++ } ++} ++ ++static int incr_load_count(load_count * dh) ++{ ++ int result; ++ ++ assert("nikita-2110", dh != NULL); ++ assert("nikita-2111", dh->node != NULL); ++ ++ result = zload(dh->node); ++ if (result == 0) ++ ++dh->d_ref; ++ return result; ++} ++ ++int incr_load_count_znode(load_count * dh, znode * node) ++{ ++ assert("nikita-2107", dh != NULL); ++ assert("nikita-2158", node != NULL); ++ assert("nikita-2109", ++ ergo(dh->node != NULL, (dh->node == node) || (dh->d_ref == 0))); ++ ++ dh->node = node; ++ return incr_load_count(dh); ++} ++ ++int incr_load_count_jnode(load_count * dh, jnode * node) ++{ ++ if (jnode_is_znode(node)) { ++ return incr_load_count_znode(dh, JZNODE(node)); ++ } ++ return 0; ++} ++ ++void copy_load_count(load_count * new, load_count * old) ++{ ++ int ret = 0; ++ done_load_count(new); ++ new->node = old->node; ++ new->d_ref = 0; ++ ++ while ((new->d_ref < old->d_ref) && (ret = incr_load_count(new)) == 0) { ++ } ++ ++ assert("jmacd-87589", ret == 0); ++} ++ ++void move_load_count(load_count * new, load_count * old) ++{ ++ done_load_count(new); ++ new->node = old->node; ++ new->d_ref = old->d_ref; ++ old->node = NULL; ++ old->d_ref = 0; ++} ++ ++/* convert parent pointer into coord */ ++void parent_coord_to_coord(const parent_coord_t * pcoord, coord_t * coord) ++{ ++ assert("nikita-3204", pcoord != NULL); ++ assert("nikita-3205", coord != NULL); ++ ++ coord_init_first_unit_nocheck(coord, pcoord->node); ++ coord_set_item_pos(coord, pcoord->item_pos); ++ coord->between = AT_UNIT; ++} ++ ++/* pack coord into parent_coord_t */ ++void coord_to_parent_coord(const coord_t * coord, parent_coord_t * pcoord) ++{ ++ assert("nikita-3206", pcoord != NULL); ++ assert("nikita-3207", coord != NULL); ++ ++ pcoord->node = coord->node; ++ pcoord->item_pos = coord->item_pos; ++} ++ ++/* Initialize a parent hint pointer. (parent hint pointer is a field in znode, ++ look for comments there) */ ++void init_parent_coord(parent_coord_t * pcoord, const znode * node) ++{ ++ pcoord->node = (znode *) node; ++ pcoord->item_pos = (unsigned short)~0; ++} ++ ++#if REISER4_DEBUG ++ ++/* debugging aid: znode invariant */ ++static int znode_invariant_f(const znode * node /* znode to check */ , ++ char const **msg /* where to store error ++ * message, if any */ ) ++{ ++#define _ergo(ant, con) \ ++ ((*msg) = "{" #ant "} ergo {" #con "}", ergo((ant), (con))) ++ ++#define _equi(e1, e2) \ ++ ((*msg) = "{" #e1 "} <=> {" #e2 "}", equi((e1), (e2))) ++ ++#define _check(exp) ((*msg) = #exp, (exp)) ++ ++ return jnode_invariant_f(ZJNODE(node), msg) && ++ /* [znode-fake] invariant */ ++ /* fake znode doesn't have a parent, and */ ++ _ergo(znode_get_level(node) == 0, znode_parent(node) == NULL) && ++ /* there is another way to express this very check, and */ ++ _ergo(znode_above_root(node), znode_parent(node) == NULL) && ++ /* it has special block number, and */ ++ _ergo(znode_get_level(node) == 0, ++ disk_addr_eq(znode_get_block(node), &UBER_TREE_ADDR)) && ++ /* it is the only znode with such block number, and */ ++ _ergo(!znode_above_root(node) && znode_is_loaded(node), ++ !disk_addr_eq(znode_get_block(node), &UBER_TREE_ADDR)) && ++ /* it is parent of the tree root node */ ++ _ergo(znode_is_true_root(node), ++ znode_above_root(znode_parent(node))) && ++ /* [znode-level] invariant */ ++ /* level of parent znode is one larger than that of child, ++ except for the fake znode, and */ ++ _ergo(znode_parent(node) && !znode_above_root(znode_parent(node)), ++ znode_get_level(znode_parent(node)) == ++ znode_get_level(node) + 1) && ++ /* left neighbor is at the same level, and */ ++ _ergo(znode_is_left_connected(node) && node->left != NULL, ++ znode_get_level(node) == znode_get_level(node->left)) && ++ /* right neighbor is at the same level */ ++ _ergo(znode_is_right_connected(node) && node->right != NULL, ++ znode_get_level(node) == znode_get_level(node->right)) && ++ /* [znode-connected] invariant */ ++ _ergo(node->left != NULL, znode_is_left_connected(node)) && ++ _ergo(node->right != NULL, znode_is_right_connected(node)) && ++ _ergo(!znode_is_root(node) && node->left != NULL, ++ znode_is_right_connected(node->left) && ++ node->left->right == node) && ++ _ergo(!znode_is_root(node) && node->right != NULL, ++ znode_is_left_connected(node->right) && ++ node->right->left == node) && ++ /* [znode-c_count] invariant */ ++ /* for any znode, c_count of its parent is greater than 0 */ ++ _ergo(znode_parent(node) != NULL && ++ !znode_above_root(znode_parent(node)), ++ znode_parent(node)->c_count > 0) && ++ /* leaves don't have children */ ++ _ergo(znode_get_level(node) == LEAF_LEVEL, ++ node->c_count == 0) && ++ _check(node->zjnode.jnodes.prev != NULL) && ++ _check(node->zjnode.jnodes.next != NULL) && ++ /* orphan doesn't have a parent */ ++ _ergo(ZF_ISSET(node, JNODE_ORPHAN), znode_parent(node) == 0) && ++ /* [znode-modify] invariant */ ++ /* if znode is not write-locked, its checksum remains ++ * invariant */ ++ /* unfortunately, zlock is unordered w.r.t. jnode_lock, so we ++ * cannot check this. */ ++ /* [znode-refs] invariant */ ++ /* only referenced znode can be long-term locked */ ++ _ergo(znode_is_locked(node), ++ atomic_read(&ZJNODE(node)->x_count) != 0); ++} ++ ++/* debugging aid: check znode invariant and panic if it doesn't hold */ ++int znode_invariant(znode * node /* znode to check */ ) ++{ ++ char const *failed_msg; ++ int result; ++ ++ assert("umka-063", node != NULL); ++ assert("umka-064", current_tree != NULL); ++ ++ spin_lock_znode(node); ++ read_lock_tree(znode_get_tree(node)); ++ result = znode_invariant_f(node, &failed_msg); ++ if (!result) { ++ /* print_znode("corrupted node", node); */ ++ warning("jmacd-555", "Condition %s failed", failed_msg); ++ } ++ read_unlock_tree(znode_get_tree(node)); ++ spin_unlock_znode(node); ++ return result; ++} ++ ++/* return non-0 iff data are loaded into znode */ ++int znode_is_loaded(const znode * node /* znode to query */ ) ++{ ++ assert("nikita-497", node != NULL); ++ return jnode_is_loaded(ZJNODE(node)); ++} ++ ++unsigned long znode_times_locked(const znode * z) ++{ ++ return z->times_locked; ++} ++ ++#endif /* REISER4_DEBUG */ ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/fs/reiser4/znode.h linux-2.6.30/fs/reiser4/znode.h +--- linux-2.6.30.orig/fs/reiser4/znode.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.30/fs/reiser4/znode.h 2009-06-22 16:08:13.000000000 +0200 +@@ -0,0 +1,433 @@ ++/* Copyright 2001, 2002, 2003, 2004 by Hans Reiser, licensing governed by ++ * reiser4/README */ ++ ++/* Declaration of znode (Zam's node). See znode.c for more details. */ ++ ++#ifndef __ZNODE_H__ ++#define __ZNODE_H__ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "key.h" ++#include "coord.h" ++#include "plugin/node/node.h" ++#include "jnode.h" ++#include "lock.h" ++#include "readahead.h" ++ ++#include <linux/types.h> ++#include <linux/spinlock.h> ++#include <linux/pagemap.h> /* for PAGE_CACHE_SIZE */ ++#include <asm/atomic.h> ++ ++/* znode tracks its position within parent (internal item in a parent node, ++ * that contains znode's block number). */ ++typedef struct parent_coord { ++ znode *node; ++ pos_in_node_t item_pos; ++} parent_coord_t; ++ ++/* &znode - node in a reiser4 tree. ++ ++ NOTE-NIKITA fields in this struct have to be rearranged (later) to reduce ++ cacheline pressure. ++ ++ Locking: ++ ++ Long term: data in a disk node attached to this znode are protected ++ by long term, deadlock aware lock ->lock; ++ ++ Spin lock: the following fields are protected by the spin lock: ++ ++ ->lock ++ ++ Following fields are protected by the global tree lock: ++ ++ ->left ++ ->right ++ ->in_parent ++ ->c_count ++ ++ Following fields are protected by the global delimiting key lock (dk_lock): ++ ++ ->ld_key (to update ->ld_key long-term lock on the node is also required) ++ ->rd_key ++ ++ Following fields are protected by the long term lock: ++ ++ ->nr_items ++ ++ ->node_plugin is never changed once set. This means that after code made ++ itself sure that field is valid it can be accessed without any additional ++ locking. ++ ++ ->level is immutable. ++ ++ Invariants involving this data-type: ++ ++ [znode-fake] ++ [znode-level] ++ [znode-connected] ++ [znode-c_count] ++ [znode-refs] ++ [jnode-refs] ++ [jnode-queued] ++ [znode-modify] ++ ++ For this to be made into a clustering or NUMA filesystem, we would want to eliminate all of the global locks. ++ Suggestions for how to do that are desired.*/ ++struct znode { ++ /* Embedded jnode. */ ++ jnode zjnode; ++ ++ /* contains three subfields, node, pos_in_node, and pos_in_unit. ++ ++ pos_in_node and pos_in_unit are only hints that are cached to ++ speed up lookups during balancing. They are not required to be up to ++ date. Synched in find_child_ptr(). ++ ++ This value allows us to avoid expensive binary searches. ++ ++ in_parent->node points to the parent of this node, and is NOT a ++ hint. ++ */ ++ parent_coord_t in_parent; ++ ++ /* ++ * sibling list pointers ++ */ ++ ++ /* left-neighbor */ ++ znode *left; ++ /* right-neighbor */ ++ znode *right; ++ ++ /* long term lock on node content. This lock supports deadlock ++ detection. See lock.c ++ */ ++ zlock lock; ++ ++ /* You cannot remove from memory a node that has children in ++ memory. This is because we rely on the fact that parent of given ++ node can always be reached without blocking for io. When reading a ++ node into memory you must increase the c_count of its parent, when ++ removing it from memory you must decrease the c_count. This makes ++ the code simpler, and the cases where it is suboptimal are truly ++ obscure. ++ */ ++ int c_count; ++ ++ /* plugin of node attached to this znode. NULL if znode is not ++ loaded. */ ++ node_plugin *nplug; ++ ++ /* version of znode data. This is increased on each modification. This ++ * is necessary to implement seals (see seal.[ch]) efficiently. */ ++ __u64 version; ++ ++ /* left delimiting key. Necessary to efficiently perform ++ balancing with node-level locking. Kept in memory only. */ ++ reiser4_key ld_key; ++ /* right delimiting key. */ ++ reiser4_key rd_key; ++ ++ /* znode's tree level */ ++ __u16 level; ++ /* number of items in this node. This field is modified by node ++ * plugin. */ ++ __u16 nr_items; ++ ++#if REISER4_DEBUG ++ void *creator; ++ reiser4_key first_key; ++ unsigned long times_locked; ++ int left_version; /* when node->left was updated */ ++ int right_version; /* when node->right was updated */ ++ int ld_key_version; /* when node->ld_key was updated */ ++ int rd_key_version; /* when node->rd_key was updated */ ++#endif ++ ++} __attribute__ ((aligned(16))); ++ ++ON_DEBUG(extern atomic_t delim_key_version; ++ ) ++ ++/* In general I think these macros should not be exposed. */ ++#define znode_is_locked(node) (lock_is_locked(&node->lock)) ++#define znode_is_rlocked(node) (lock_is_rlocked(&node->lock)) ++#define znode_is_wlocked(node) (lock_is_wlocked(&node->lock)) ++#define znode_is_wlocked_once(node) (lock_is_wlocked_once(&node->lock)) ++#define znode_can_be_rlocked(node) (lock_can_be_rlocked(&node->lock)) ++#define is_lock_compatible(node, mode) (lock_mode_compatible(&node->lock, mode)) ++/* Macros for accessing the znode state. */ ++#define ZF_CLR(p,f) JF_CLR (ZJNODE(p), (f)) ++#define ZF_ISSET(p,f) JF_ISSET(ZJNODE(p), (f)) ++#define ZF_SET(p,f) JF_SET (ZJNODE(p), (f)) ++extern znode *zget(reiser4_tree * tree, const reiser4_block_nr * const block, ++ znode * parent, tree_level level, gfp_t gfp_flag); ++extern znode *zlook(reiser4_tree * tree, const reiser4_block_nr * const block); ++extern int zload(znode * node); ++extern int zload_ra(znode * node, ra_info_t * info); ++extern int zinit_new(znode * node, gfp_t gfp_flags); ++extern void zrelse(znode * node); ++extern void znode_change_parent(znode * new_parent, reiser4_block_nr * block); ++ ++/* size of data in znode */ ++static inline unsigned ++znode_size(const znode * node UNUSED_ARG /* znode to query */ ) ++{ ++ assert("nikita-1416", node != NULL); ++ return PAGE_CACHE_SIZE; ++} ++ ++extern void parent_coord_to_coord(const parent_coord_t * pcoord, ++ coord_t * coord); ++extern void coord_to_parent_coord(const coord_t * coord, ++ parent_coord_t * pcoord); ++extern void init_parent_coord(parent_coord_t * pcoord, const znode * node); ++ ++extern unsigned znode_free_space(znode * node); ++ ++extern reiser4_key *znode_get_rd_key(znode * node); ++extern reiser4_key *znode_get_ld_key(znode * node); ++ ++extern reiser4_key *znode_set_rd_key(znode * node, const reiser4_key * key); ++extern reiser4_key *znode_set_ld_key(znode * node, const reiser4_key * key); ++ ++/* `connected' state checks */ ++static inline int znode_is_right_connected(const znode * node) ++{ ++ return ZF_ISSET(node, JNODE_RIGHT_CONNECTED); ++} ++ ++static inline int znode_is_left_connected(const znode * node) ++{ ++ return ZF_ISSET(node, JNODE_LEFT_CONNECTED); ++} ++ ++static inline int znode_is_connected(const znode * node) ++{ ++ return znode_is_right_connected(node) && znode_is_left_connected(node); ++} ++ ++extern int znode_shift_order; ++extern int znode_rehash(znode * node, const reiser4_block_nr * new_block_nr); ++extern void znode_remove(znode *, reiser4_tree *); ++extern znode *znode_parent(const znode * node); ++extern znode *znode_parent_nolock(const znode * node); ++extern int znode_above_root(const znode * node); ++extern int init_znodes(void); ++extern void done_znodes(void); ++extern int znodes_tree_init(reiser4_tree * ztree); ++extern void znodes_tree_done(reiser4_tree * ztree); ++extern int znode_contains_key(znode * node, const reiser4_key * key); ++extern int znode_contains_key_lock(znode * node, const reiser4_key * key); ++extern unsigned znode_save_free_space(znode * node); ++extern unsigned znode_recover_free_space(znode * node); ++extern znode *zalloc(gfp_t gfp_flag); ++extern void zinit(znode *, const znode * parent, reiser4_tree *); ++extern int zparse(znode * node); ++ ++extern int znode_just_created(const znode * node); ++ ++extern void zfree(znode * node); ++ ++#if REISER4_DEBUG ++extern void print_znode(const char *prefix, const znode * node); ++#else ++#define print_znode( p, n ) noop ++#endif ++ ++/* Make it look like various znode functions exist instead of treating znodes as ++ jnodes in znode-specific code. */ ++#define znode_page(x) jnode_page ( ZJNODE(x) ) ++#define zdata(x) jdata ( ZJNODE(x) ) ++#define znode_get_block(x) jnode_get_block ( ZJNODE(x) ) ++#define znode_created(x) jnode_created ( ZJNODE(x) ) ++#define znode_set_created(x) jnode_set_created ( ZJNODE(x) ) ++#define znode_convertible(x) jnode_convertible (ZJNODE(x)) ++#define znode_set_convertible(x) jnode_set_convertible (ZJNODE(x)) ++ ++#define znode_is_dirty(x) jnode_is_dirty ( ZJNODE(x) ) ++#define znode_check_dirty(x) jnode_check_dirty ( ZJNODE(x) ) ++#define znode_make_clean(x) jnode_make_clean ( ZJNODE(x) ) ++#define znode_set_block(x, b) jnode_set_block ( ZJNODE(x), (b) ) ++ ++#define spin_lock_znode(x) spin_lock_jnode ( ZJNODE(x) ) ++#define spin_unlock_znode(x) spin_unlock_jnode ( ZJNODE(x) ) ++#define spin_trylock_znode(x) spin_trylock_jnode ( ZJNODE(x) ) ++#define spin_znode_is_locked(x) spin_jnode_is_locked ( ZJNODE(x) ) ++#define spin_znode_is_not_locked(x) spin_jnode_is_not_locked ( ZJNODE(x) ) ++ ++#if REISER4_DEBUG ++extern int znode_x_count_is_protected(const znode * node); ++extern int znode_invariant(znode * node); ++#endif ++ ++/* acquire reference to @node */ ++static inline znode *zref(znode * node) ++{ ++ /* change of x_count from 0 to 1 is protected by tree spin-lock */ ++ return JZNODE(jref(ZJNODE(node))); ++} ++ ++/* release reference to @node */ ++static inline void zput(znode * node) ++{ ++ assert("nikita-3564", znode_invariant(node)); ++ jput(ZJNODE(node)); ++} ++ ++/* get the level field for a znode */ ++static inline tree_level znode_get_level(const znode * node) ++{ ++ return node->level; ++} ++ ++/* get the level field for a jnode */ ++static inline tree_level jnode_get_level(const jnode * node) ++{ ++ if (jnode_is_znode(node)) ++ return znode_get_level(JZNODE(node)); ++ else ++ /* unformatted nodes are all at the LEAF_LEVEL and for ++ "semi-formatted" nodes like bitmaps, level doesn't matter. */ ++ return LEAF_LEVEL; ++} ++ ++/* true if jnode is on leaf level */ ++static inline int jnode_is_leaf(const jnode * node) ++{ ++ if (jnode_is_znode(node)) ++ return (znode_get_level(JZNODE(node)) == LEAF_LEVEL); ++ if (jnode_get_type(node) == JNODE_UNFORMATTED_BLOCK) ++ return 1; ++ return 0; ++} ++ ++/* return znode's tree */ ++static inline reiser4_tree *znode_get_tree(const znode * node) ++{ ++ assert("nikita-2692", node != NULL); ++ return jnode_get_tree(ZJNODE(node)); ++} ++ ++/* resolve race with zput */ ++static inline znode *znode_rip_check(reiser4_tree * tree, znode * node) ++{ ++ jnode *j; ++ ++ j = jnode_rip_sync(tree, ZJNODE(node)); ++ if (likely(j != NULL)) ++ node = JZNODE(j); ++ else ++ node = NULL; ++ return node; ++} ++ ++#if defined(REISER4_DEBUG) ++int znode_is_loaded(const znode * node /* znode to query */ ); ++#endif ++ ++extern __u64 znode_build_version(reiser4_tree * tree); ++ ++/* Data-handles. A data handle object manages pairing calls to zload() and zrelse(). We ++ must load the data for a node in many places. We could do this by simply calling ++ zload() everywhere, the difficulty arises when we must release the loaded data by ++ calling zrelse. In a function with many possible error/return paths, it requires extra ++ work to figure out which exit paths must call zrelse and those which do not. The data ++ handle automatically calls zrelse for every zload that it is responsible for. In that ++ sense, it acts much like a lock_handle. ++*/ ++typedef struct load_count { ++ znode *node; ++ int d_ref; ++} load_count; ++ ++extern void init_load_count(load_count * lc); /* Initialize a load_count set the current node to NULL. */ ++extern void done_load_count(load_count * dh); /* Finalize a load_count: call zrelse() if necessary */ ++extern int incr_load_count_znode(load_count * dh, znode * node); /* Set the argument znode to the current node, call zload(). */ ++extern int incr_load_count_jnode(load_count * dh, jnode * node); /* If the argument jnode is formatted, do the same as ++ * incr_load_count_znode, otherwise do nothing (unformatted nodes ++ * don't require zload/zrelse treatment). */ ++extern void move_load_count(load_count * new, load_count * old); /* Move the contents of a load_count. Old handle is released. */ ++extern void copy_load_count(load_count * new, load_count * old); /* Copy the contents of a load_count. Old handle remains held. */ ++ ++/* Variable initializers for load_count. */ ++#define INIT_LOAD_COUNT ( load_count * ){ .node = NULL, .d_ref = 0 } ++#define INIT_LOAD_COUNT_NODE( n ) ( load_count ){ .node = ( n ), .d_ref = 0 } ++/* A convenience macro for use in assertions or debug-only code, where loaded ++ data is only required to perform the debugging check. This macro ++ encapsulates an expression inside a pair of calls to zload()/zrelse(). */ ++#define WITH_DATA( node, exp ) \ ++({ \ ++ long __with_dh_result; \ ++ znode *__with_dh_node; \ ++ \ ++ __with_dh_node = ( node ); \ ++ __with_dh_result = zload( __with_dh_node ); \ ++ if( __with_dh_result == 0 ) { \ ++ __with_dh_result = ( long )( exp ); \ ++ zrelse( __with_dh_node ); \ ++ } \ ++ __with_dh_result; \ ++}) ++ ++/* Same as above, but accepts a return value in case zload fails. */ ++#define WITH_DATA_RET( node, ret, exp ) \ ++({ \ ++ int __with_dh_result; \ ++ znode *__with_dh_node; \ ++ \ ++ __with_dh_node = ( node ); \ ++ __with_dh_result = zload( __with_dh_node ); \ ++ if( __with_dh_result == 0 ) { \ ++ __with_dh_result = ( int )( exp ); \ ++ zrelse( __with_dh_node ); \ ++ } else \ ++ __with_dh_result = ( ret ); \ ++ __with_dh_result; \ ++}) ++ ++#define WITH_COORD(coord, exp) \ ++({ \ ++ coord_t *__coord; \ ++ \ ++ __coord = (coord); \ ++ coord_clear_iplug(__coord); \ ++ WITH_DATA(__coord->node, exp); \ ++}) ++ ++#if REISER4_DEBUG ++#define STORE_COUNTERS \ ++ reiser4_lock_cnt_info __entry_counters = \ ++ *reiser4_lock_counters() ++#define CHECK_COUNTERS \ ++ON_DEBUG_CONTEXT( \ ++({ \ ++ __entry_counters.x_refs = reiser4_lock_counters() -> x_refs; \ ++ __entry_counters.t_refs = reiser4_lock_counters() -> t_refs; \ ++ __entry_counters.d_refs = reiser4_lock_counters() -> d_refs; \ ++ assert("nikita-2159", \ ++ !memcmp(&__entry_counters, reiser4_lock_counters(), \ ++ sizeof __entry_counters)); \ ++}) ) ++ ++#else ++#define STORE_COUNTERS ++#define CHECK_COUNTERS noop ++#endif ++ ++/* __ZNODE_H__ */ ++#endif ++ ++/* Make Linus happy. ++ Local variables: ++ c-indentation-style: "K&R" ++ mode-name: "LC" ++ c-basic-offset: 8 ++ tab-width: 8 ++ fill-column: 120 ++ End: ++*/ +diff -urN linux-2.6.30.orig/include/linux/fs.h linux-2.6.30/include/linux/fs.h +--- linux-2.6.30.orig/include/linux/fs.h 2009-06-23 00:20:41.000000000 +0200 ++++ linux-2.6.30/include/linux/fs.h 2009-06-22 16:08:13.000000000 +0200 +@@ -1571,6 +1571,8 @@ + void (*clear_inode) (struct inode *); + void (*umount_begin) (struct super_block *); + ++ void (*sync_inodes) (struct super_block *sb, ++ struct writeback_control *wbc); + int (*show_options)(struct seq_file *, struct vfsmount *); + int (*show_stats)(struct seq_file *, struct vfsmount *); + #ifdef CONFIG_QUOTA +@@ -2067,6 +2069,7 @@ + extern void generic_sync_sb_inodes(struct super_block *sb, + struct writeback_control *wbc); + extern int write_inode_now(struct inode *, int); ++extern void generic_sync_sb_inodes(struct super_block *, struct writeback_control *); + extern int filemap_fdatawrite(struct address_space *); + extern int filemap_flush(struct address_space *); + extern int filemap_fdatawait(struct address_space *); +diff -urN linux-2.6.30.orig/include/linux/mm.h linux-2.6.30/include/linux/mm.h +--- linux-2.6.30.orig/include/linux/mm.h 2009-06-23 00:20:41.000000000 +0200 ++++ linux-2.6.30/include/linux/mm.h 2009-06-22 16:17:44.000000000 +0200 +@@ -838,6 +838,7 @@ + void account_page_dirtied(struct page *page, struct address_space *mapping); + int set_page_dirty(struct page *page); + int set_page_dirty_lock(struct page *page); ++int set_page_dirty_notag(struct page *page); + int clear_page_dirty_for_io(struct page *page); + + extern unsigned long move_page_tables(struct vm_area_struct *vma, +diff -urN linux-2.6.30.orig/mm/filemap.c linux-2.6.30/mm/filemap.c +--- linux-2.6.30.orig/mm/filemap.c 2009-06-23 00:20:41.000000000 +0200 ++++ linux-2.6.30/mm/filemap.c 2009-06-22 16:51:45.000000000 +0200 +@@ -134,6 +134,7 @@ + dec_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); + } + } ++EXPORT_SYMBOL(__remove_from_page_cache); + + void remove_from_page_cache(struct page *page) + { +@@ -146,6 +147,7 @@ + spin_unlock_irq(&mapping->tree_lock); + mem_cgroup_uncharge_cache_page(page); + } ++EXPORT_SYMBOL(remove_from_page_cache); + + static int sync_page(void *word) + { +@@ -1009,6 +1011,7 @@ + + ra->ra_pages /= 4; + } ++EXPORT_SYMBOL(find_get_pages); + + /** + * do_generic_file_read - generic file read routine +diff -urN linux-2.6.30.orig/mm/page-writeback.c linux-2.6.30/mm/page-writeback.c +--- linux-2.6.30.orig/mm/page-writeback.c 2009-06-23 00:20:41.000000000 +0200 ++++ linux-2.6.30/mm/page-writeback.c 2009-06-22 16:53:49.000000000 +0200 +@@ -1258,6 +1258,32 @@ + EXPORT_SYMBOL(__set_page_dirty_nobuffers); + + /* ++ * set_page_dirty_notag() -- similar to __set_page_dirty_nobuffers() ++ * except it doesn't tag the page dirty in the page-cache radix tree. ++ * This means that the address space using this cannot use the regular ++ * filemap ->writepages() helpers and must provide its own means of ++ * tracking and finding non-tagged dirty pages. ++ * ++ * NOTE: furthermore, this version also doesn't handle truncate races. ++ */ ++int set_page_dirty_notag(struct page *page) ++{ ++ struct address_space *mapping = page->mapping; ++ ++ if (!TestSetPageDirty(page)) { ++ unsigned long flags; ++ WARN_ON_ONCE(!PagePrivate(page) && !PageUptodate(page)); ++ local_irq_save(flags); ++ account_page_dirtied(page, mapping); ++ local_irq_restore(flags); ++ __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); ++ return 1; ++ } ++ return 0; ++} ++EXPORT_SYMBOL(set_page_dirty_notag); ++ ++/* + * When a writepage implementation decides that it doesn't want to write this + * page for some reason, it should redirty the locked page via + * redirty_page_for_writepage() and it should then unlock the page and return 0 diff --git a/pkgs/core/kernel/patches/routes-2.6.31.1-16.diff b/pkgs/core/kernel/patches/routes-2.6.31.1-16.diff new file mode 100644 index 0000000..ece47c5 --- /dev/null +++ b/pkgs/core/kernel/patches/routes-2.6.31.1-16.diff @@ -0,0 +1,1333 @@ +diff -urp v2.6.31/linux/include/linux/rtnetlink.h linux/include/linux/rtnetlink.h +--- v2.6.31/linux/include/linux/rtnetlink.h 2009-06-13 10:53:56.000000000 +0300 ++++ linux/include/linux/rtnetlink.h 2009-09-11 22:11:20.000000000 +0300 +@@ -311,6 +311,8 @@ struct rtnexthop + #define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */ + #define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */ + #define RTNH_F_ONLINK 4 /* Gateway is forced on link */ ++#define RTNH_F_SUSPECT 8 /* We don't know the real state */ ++#define RTNH_F_BADSTATE (RTNH_F_DEAD | RTNH_F_SUSPECT) + + /* Macros to handle hexthops */ + +diff -urp v2.6.31/linux/include/net/flow.h linux/include/net/flow.h +--- v2.6.31/linux/include/net/flow.h 2009-03-25 09:48:32.000000000 +0200 ++++ linux/include/net/flow.h 2009-09-11 22:12:39.000000000 +0300 +@@ -19,6 +19,8 @@ struct flowi { + struct { + __be32 daddr; + __be32 saddr; ++ __be32 lsrc; ++ __be32 gw; + __u8 tos; + __u8 scope; + } ip4_u; +@@ -43,6 +45,8 @@ struct flowi { + #define fl6_flowlabel nl_u.ip6_u.flowlabel + #define fl4_dst nl_u.ip4_u.daddr + #define fl4_src nl_u.ip4_u.saddr ++#define fl4_lsrc nl_u.ip4_u.lsrc ++#define fl4_gw nl_u.ip4_u.gw + #define fl4_tos nl_u.ip4_u.tos + #define fl4_scope nl_u.ip4_u.scope + +diff -urp v2.6.31/linux/include/net/ip_fib.h linux/include/net/ip_fib.h +--- v2.6.31/linux/include/net/ip_fib.h 2009-09-11 10:27:15.000000000 +0300 ++++ linux/include/net/ip_fib.h 2009-09-11 22:11:20.000000000 +0300 +@@ -204,6 +204,8 @@ extern int fib_lookup(struct net *n, str + extern struct fib_table *fib_new_table(struct net *net, u32 id); + extern struct fib_table *fib_get_table(struct net *net, u32 id); + ++extern int fib_result_table(struct fib_result *res); ++ + #endif /* CONFIG_IP_MULTIPLE_TABLES */ + + /* Exported by fib_frontend.c */ +@@ -273,4 +275,6 @@ static inline void fib_proc_exit(struct + } + #endif + ++extern rwlock_t fib_nhflags_lock; ++ + #endif /* _NET_FIB_H */ +diff -urp v2.6.31/linux/include/net/netfilter/nf_nat.h linux/include/net/netfilter/nf_nat.h +--- v2.6.31/linux/include/net/netfilter/nf_nat.h 2009-06-13 10:53:57.000000000 +0300 ++++ linux/include/net/netfilter/nf_nat.h 2009-09-11 22:12:39.000000000 +0300 +@@ -78,6 +78,13 @@ struct nf_conn_nat + #endif + }; + ++/* Call input routing for SNAT-ed traffic */ ++extern unsigned int ip_nat_route_input(unsigned int hooknum, ++ struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ int (*okfn)(struct sk_buff *)); ++ + /* Set up the info structure to map into this range. */ + extern unsigned int nf_nat_setup_info(struct nf_conn *ct, + const struct nf_nat_range *range, +diff -urp v2.6.31/linux/include/net/route.h linux/include/net/route.h +--- v2.6.31/linux/include/net/route.h 2009-09-11 10:27:15.000000000 +0300 ++++ linux/include/net/route.h 2009-09-11 22:12:39.000000000 +0300 +@@ -116,6 +116,7 @@ extern int __ip_route_output_key(struct + extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); + extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); + extern int ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin); ++extern int ip_route_input_lookup(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin, __be32 lsrc); + extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev); + extern void ip_rt_send_redirect(struct sk_buff *skb); + +diff -urp v2.6.31/linux/net/bridge/br_netfilter.c linux/net/bridge/br_netfilter.c +--- v2.6.31/linux/net/bridge/br_netfilter.c 2009-09-11 10:27:16.000000000 +0300 ++++ linux/net/bridge/br_netfilter.c 2009-09-11 22:13:17.000000000 +0300 +@@ -343,6 +343,9 @@ static int br_nf_pre_routing_finish(stru + struct rtable *rt; + int err; + ++ /* Old skb->dst is not expected, it is lost in all cases */ ++ skb_dst_drop(skb); ++ + if (nf_bridge->mask & BRNF_PKT_TYPE) { + skb->pkt_type = PACKET_OTHERHOST; + nf_bridge->mask ^= BRNF_PKT_TYPE; +diff -urp v2.6.31/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c +--- v2.6.31/linux/net/ipv4/fib_frontend.c 2009-09-11 10:27:17.000000000 +0300 ++++ linux/net/ipv4/fib_frontend.c 2009-09-11 22:11:20.000000000 +0300 +@@ -46,6 +46,8 @@ + + #ifndef CONFIG_IP_MULTIPLE_TABLES + ++#define FIB_RES_TABLE(r) (RT_TABLE_MAIN) ++ + static int __net_init fib4_rules_init(struct net *net) + { + struct fib_table *local_table, *main_table; +@@ -70,6 +72,8 @@ fail: + } + #else + ++#define FIB_RES_TABLE(r) (fib_result_table(r)) ++ + struct fib_table *fib_new_table(struct net *net, u32 id) + { + struct fib_table *tb; +@@ -124,7 +128,8 @@ void fib_select_default(struct net *net, + table = res->r->table; + #endif + tb = fib_get_table(net, table); +- if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) ++ if ((FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) || ++ FIB_RES_NH(*res).nh_scope == RT_SCOPE_HOST) + tb->tb_select_default(tb, flp, res); + } + +@@ -238,6 +243,9 @@ int fib_validate_source(__be32 src, __be + .tos = tos } }, + .iif = oif }; + struct fib_result res; ++ int table; ++ unsigned char prefixlen; ++ unsigned char scope; + int no_addr, rpf; + int ret; + struct net *net; +@@ -261,31 +269,35 @@ int fib_validate_source(__be32 src, __be + goto e_inval_res; + *spec_dst = FIB_RES_PREFSRC(res); + fib_combine_itag(itag, &res); +-#ifdef CONFIG_IP_ROUTE_MULTIPATH +- if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1) +-#else + if (FIB_RES_DEV(res) == dev) +-#endif + { + ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; + fib_res_put(&res); + return ret; + } ++ table = FIB_RES_TABLE(&res); ++ prefixlen = res.prefixlen; ++ scope = res.scope; + fib_res_put(&res); + if (no_addr) + goto last_resort; +- if (rpf == 1) +- goto e_inval; + fl.oif = dev->ifindex; + + ret = 0; + if (fib_lookup(net, &fl, &res) == 0) { +- if (res.type == RTN_UNICAST) { ++ if (res.type == RTN_UNICAST && ++ ((table == FIB_RES_TABLE(&res) && ++ res.prefixlen >= prefixlen && res.scope >= scope) || ++ !rpf)) { + *spec_dst = FIB_RES_PREFSRC(res); + ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; ++ fib_res_put(&res); ++ return ret; + } + fib_res_put(&res); + } ++ if (rpf == 1) ++ goto e_inval; + return ret; + + last_resort: +@@ -908,9 +920,7 @@ static int fib_inetaddr_event(struct not + switch (event) { + case NETDEV_UP: + fib_add_ifaddr(ifa); +-#ifdef CONFIG_IP_ROUTE_MULTIPATH + fib_sync_up(dev); +-#endif + rt_cache_flush(dev_net(dev), -1); + break; + case NETDEV_DOWN: +@@ -946,9 +956,7 @@ static int fib_netdev_event(struct notif + for_ifa(in_dev) { + fib_add_ifaddr(ifa); + } endfor_ifa(in_dev); +-#ifdef CONFIG_IP_ROUTE_MULTIPATH + fib_sync_up(dev); +-#endif + rt_cache_flush(dev_net(dev), -1); + break; + case NETDEV_DOWN: +diff -urp v2.6.31/linux/net/ipv4/fib_hash.c linux/net/ipv4/fib_hash.c +--- v2.6.31/linux/net/ipv4/fib_hash.c 2009-09-11 10:27:17.000000000 +0300 ++++ linux/net/ipv4/fib_hash.c 2009-09-11 22:11:20.000000000 +0300 +@@ -277,25 +277,35 @@ out: + static void + fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res) + { +- int order, last_idx; ++ int order, last_idx, last_dflt, last_nhsel; ++ struct fib_alias *first_fa = NULL; ++ struct hlist_head *head; + struct hlist_node *node; + struct fib_node *f; + struct fib_info *fi = NULL; + struct fib_info *last_resort; + struct fn_hash *t = (struct fn_hash *)tb->tb_data; +- struct fn_zone *fz = t->fn_zones[0]; ++ struct fn_zone *fz = t->fn_zones[res->prefixlen]; ++ __be32 k; + + if (fz == NULL) + return; + ++ k = fz_key(flp->fl4_dst, fz); ++ last_dflt = -2; ++ last_nhsel = 0; + last_idx = -1; + last_resort = NULL; + order = -1; + + read_lock(&fib_hash_lock); +- hlist_for_each_entry(f, node, &fz->fz_hash[0], fn_hash) { ++ head = &fz->fz_hash[fn_hash(k, fz)]; ++ hlist_for_each_entry(f, node, head, fn_hash) { + struct fib_alias *fa; + ++ if (f->fn_key != k) ++ continue; ++ + list_for_each_entry(fa, &f->fn_alias, fa_list) { + struct fib_info *next_fi = fa->fa_info; + +@@ -303,42 +313,56 @@ fn_hash_select_default(struct fib_table + fa->fa_type != RTN_UNICAST) + continue; + ++ if (fa->fa_tos && ++ fa->fa_tos != flp->fl4_tos) ++ continue; + if (next_fi->fib_priority > res->fi->fib_priority) + break; +- if (!next_fi->fib_nh[0].nh_gw || +- next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) +- continue; + fa->fa_state |= FA_S_ACCESSED; + +- if (fi == NULL) { +- if (next_fi != res->fi) +- break; +- } else if (!fib_detect_death(fi, order, &last_resort, +- &last_idx, tb->tb_default)) { ++ if (!first_fa) { ++ last_dflt = fa->fa_last_dflt; ++ first_fa = fa; ++ } ++ if (fi && !fib_detect_death(fi, order, &last_resort, ++ &last_idx, &last_dflt, &last_nhsel, flp)) { + fib_result_assign(res, fi); +- tb->tb_default = order; ++ first_fa->fa_last_dflt = order; + goto out; + } + fi = next_fi; + order++; + } ++ break; + } + + if (order <= 0 || fi == NULL) { +- tb->tb_default = -1; ++ if (fi && fi->fib_nhs > 1 && ++ fib_detect_death(fi, order, &last_resort, &last_idx, ++ &last_dflt, &last_nhsel, flp) && ++ last_resort == fi) { ++ read_lock_bh(&fib_nhflags_lock); ++ fi->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT; ++ read_unlock_bh(&fib_nhflags_lock); ++ } ++ if (first_fa) first_fa->fa_last_dflt = -1; + goto out; + } + + if (!fib_detect_death(fi, order, &last_resort, &last_idx, +- tb->tb_default)) { ++ &last_dflt, &last_nhsel, flp)) { + fib_result_assign(res, fi); +- tb->tb_default = order; ++ first_fa->fa_last_dflt = order; + goto out; + } + +- if (last_idx >= 0) ++ if (last_idx >= 0) { + fib_result_assign(res, last_resort); +- tb->tb_default = last_idx; ++ read_lock_bh(&fib_nhflags_lock); ++ last_resort->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT; ++ read_unlock_bh(&fib_nhflags_lock); ++ first_fa->fa_last_dflt = last_idx; ++ } + out: + read_unlock(&fib_hash_lock); + } +@@ -462,6 +486,7 @@ static int fn_hash_insert(struct fib_tab + write_lock_bh(&fib_hash_lock); + fi_drop = fa->fa_info; + fa->fa_info = fi; ++ fa->fa_last_dflt = -1; + fa->fa_type = cfg->fc_type; + fa->fa_scope = cfg->fc_scope; + state = fa->fa_state; +@@ -516,6 +541,7 @@ static int fn_hash_insert(struct fib_tab + new_fa->fa_type = cfg->fc_type; + new_fa->fa_scope = cfg->fc_scope; + new_fa->fa_state = 0; ++ new_fa->fa_last_dflt = -1; + + /* + * Insert new entry to the list. +diff -urp v2.6.31/linux/net/ipv4/fib_lookup.h linux/net/ipv4/fib_lookup.h +--- v2.6.31/linux/net/ipv4/fib_lookup.h 2009-09-11 10:27:17.000000000 +0300 ++++ linux/net/ipv4/fib_lookup.h 2009-09-11 22:11:20.000000000 +0300 +@@ -8,6 +8,7 @@ + struct fib_alias { + struct list_head fa_list; + struct fib_info *fa_info; ++ int fa_last_dflt; + u8 fa_tos; + u8 fa_type; + u8 fa_scope; +@@ -37,7 +38,8 @@ extern struct fib_alias *fib_find_alias( + u8 tos, u32 prio); + extern int fib_detect_death(struct fib_info *fi, int order, + struct fib_info **last_resort, +- int *last_idx, int dflt); ++ int *last_idx, int *dflt, int *last_nhsel, ++ const struct flowi *flp); + + static inline void fib_result_assign(struct fib_result *res, + struct fib_info *fi) +diff -urp v2.6.31/linux/net/ipv4/fib_rules.c linux/net/ipv4/fib_rules.c +--- v2.6.31/linux/net/ipv4/fib_rules.c 2009-09-11 10:27:17.000000000 +0300 ++++ linux/net/ipv4/fib_rules.c 2009-09-11 22:11:20.000000000 +0300 +@@ -54,6 +54,11 @@ u32 fib_rules_tclass(struct fib_result * + } + #endif + ++int fib_result_table(struct fib_result *res) ++{ ++ return res->r->table; ++} ++ + int fib_lookup(struct net *net, struct flowi *flp, struct fib_result *res) + { + struct fib_lookup_arg arg = { +diff -urp v2.6.31/linux/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c +--- v2.6.31/linux/net/ipv4/fib_semantics.c 2009-09-11 10:27:17.000000000 +0300 ++++ linux/net/ipv4/fib_semantics.c 2009-09-11 22:12:39.000000000 +0300 +@@ -50,6 +50,7 @@ static struct hlist_head *fib_info_hash; + static struct hlist_head *fib_info_laddrhash; + static unsigned int fib_hash_size; + static unsigned int fib_info_cnt; ++rwlock_t fib_nhflags_lock = RW_LOCK_UNLOCKED; + + #define DEVINDEX_HASHBITS 8 + #define DEVINDEX_HASHSIZE (1U << DEVINDEX_HASHBITS) +@@ -186,7 +187,7 @@ static __inline__ int nh_comp(const stru + #ifdef CONFIG_NET_CLS_ROUTE + nh->nh_tclassid != onh->nh_tclassid || + #endif +- ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD)) ++ ((nh->nh_flags^onh->nh_flags)&~RTNH_F_BADSTATE)) + return -1; + onh++; + } endfor_nexthops(fi); +@@ -237,7 +238,7 @@ static struct fib_info *fib_find_info(co + nfi->fib_priority == fi->fib_priority && + memcmp(nfi->fib_metrics, fi->fib_metrics, + sizeof(fi->fib_metrics)) == 0 && +- ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 && ++ ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_BADSTATE) == 0 && + (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0)) + return fi; + } +@@ -349,26 +350,70 @@ struct fib_alias *fib_find_alias(struct + } + + int fib_detect_death(struct fib_info *fi, int order, +- struct fib_info **last_resort, int *last_idx, int dflt) ++ struct fib_info **last_resort, int *last_idx, int *dflt, ++ int *last_nhsel, const struct flowi *flp) + { + struct neighbour *n; +- int state = NUD_NONE; ++ int nhsel; ++ int state; ++ struct fib_nh * nh; ++ __be32 dst; ++ int flag, dead = 1; ++ ++ /* change_nexthops(fi) { */ ++ for (nhsel = 0, nh = fi->fib_nh; nhsel < fi->fib_nhs; nh++, nhsel++) { ++ if (flp->oif && flp->oif != nh->nh_oif) ++ continue; ++ if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw && nh->nh_gw && ++ nh->nh_scope == RT_SCOPE_LINK) ++ continue; ++ if (nh->nh_flags & RTNH_F_DEAD) ++ continue; + +- n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev); +- if (n) { +- state = n->nud_state; +- neigh_release(n); +- } +- if (state == NUD_REACHABLE) +- return 0; +- if ((state&NUD_VALID) && order != dflt) +- return 0; +- if ((state&NUD_VALID) || +- (*last_idx<0 && order > dflt)) { +- *last_resort = fi; +- *last_idx = order; ++ flag = 0; ++ if (nh->nh_dev->flags & IFF_NOARP) { ++ dead = 0; ++ goto setfl; ++ } ++ ++ dst = nh->nh_gw; ++ if (!nh->nh_gw || nh->nh_scope != RT_SCOPE_LINK) ++ dst = flp->fl4_dst; ++ ++ state = NUD_NONE; ++ n = neigh_lookup(&arp_tbl, &dst, nh->nh_dev); ++ if (n) { ++ state = n->nud_state; ++ neigh_release(n); ++ } ++ if (state==NUD_REACHABLE || ++ ((state&NUD_VALID) && order != *dflt)) { ++ dead = 0; ++ goto setfl; ++ } ++ if (!(state&NUD_VALID)) ++ flag = 1; ++ if (!dead) ++ goto setfl; ++ if ((state&NUD_VALID) || ++ (*last_idx<0 && order >= *dflt)) { ++ *last_resort = fi; ++ *last_idx = order; ++ *last_nhsel = nhsel; ++ } ++ ++ setfl: ++ ++ read_lock_bh(&fib_nhflags_lock); ++ if (flag) ++ nh->nh_flags |= RTNH_F_SUSPECT; ++ else ++ nh->nh_flags &= ~RTNH_F_SUSPECT; ++ read_unlock_bh(&fib_nhflags_lock); + } +- return 1; ++ /* } endfor_nexthops(fi) */ ++ ++ return dead; + } + + #ifdef CONFIG_IP_ROUTE_MULTIPATH +@@ -540,8 +585,11 @@ static int fib_check_nh(struct fib_confi + return -EINVAL; + if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL) + return -ENODEV; +- if (!(dev->flags&IFF_UP)) +- return -ENETDOWN; ++ if (!(dev->flags&IFF_UP)) { ++ if (fi->fib_protocol != RTPROT_STATIC) ++ return -ENETDOWN; ++ nh->nh_flags |= RTNH_F_DEAD; ++ } + nh->nh_dev = dev; + dev_hold(dev); + nh->nh_scope = RT_SCOPE_LINK; +@@ -561,24 +609,48 @@ static int fib_check_nh(struct fib_confi + /* It is not necessary, but requires a bit of thinking */ + if (fl.fl4_scope < RT_SCOPE_LINK) + fl.fl4_scope = RT_SCOPE_LINK; +- if ((err = fib_lookup(net, &fl, &res)) != 0) +- return err; ++ err = fib_lookup(net, &fl, &res); + } +- err = -EINVAL; +- if (res.type != RTN_UNICAST && res.type != RTN_LOCAL) +- goto out; +- nh->nh_scope = res.scope; +- nh->nh_oif = FIB_RES_OIF(res); +- if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL) +- goto out; +- dev_hold(nh->nh_dev); +- err = -ENETDOWN; +- if (!(nh->nh_dev->flags & IFF_UP)) +- goto out; +- err = 0; ++ if (err) { ++ struct in_device *in_dev; ++ ++ if (err != -ENETUNREACH || ++ fi->fib_protocol != RTPROT_STATIC) ++ return err; ++ ++ in_dev = inetdev_by_index(net, nh->nh_oif); ++ if (in_dev == NULL || ++ in_dev->dev->flags & IFF_UP) { ++ if (in_dev) ++ in_dev_put(in_dev); ++ return err; ++ } ++ nh->nh_flags |= RTNH_F_DEAD; ++ nh->nh_scope = RT_SCOPE_LINK; ++ nh->nh_dev = in_dev->dev; ++ dev_hold(nh->nh_dev); ++ in_dev_put(in_dev); ++ } else { ++ err = -EINVAL; ++ if (res.type != RTN_UNICAST && res.type != RTN_LOCAL) ++ goto out; ++ nh->nh_scope = res.scope; ++ nh->nh_oif = FIB_RES_OIF(res); ++ if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL) ++ goto out; ++ dev_hold(nh->nh_dev); ++ if (!(nh->nh_dev->flags & IFF_UP)) { ++ if (fi->fib_protocol != RTPROT_STATIC) { ++ err = -ENETDOWN; ++ goto out; ++ } ++ nh->nh_flags |= RTNH_F_DEAD; ++ } ++ err = 0; + out: +- fib_res_put(&res); +- return err; ++ fib_res_put(&res); ++ return err; ++ } + } else { + struct in_device *in_dev; + +@@ -589,8 +661,11 @@ out: + if (in_dev == NULL) + return -ENODEV; + if (!(in_dev->dev->flags&IFF_UP)) { +- in_dev_put(in_dev); +- return -ENETDOWN; ++ if (fi->fib_protocol != RTPROT_STATIC) { ++ in_dev_put(in_dev); ++ return -ENETDOWN; ++ } ++ nh->nh_flags |= RTNH_F_DEAD; + } + nh->nh_dev = in_dev->dev; + dev_hold(nh->nh_dev); +@@ -899,8 +974,12 @@ int fib_semantic_match(struct list_head + for_nexthops(fi) { + if (nh->nh_flags&RTNH_F_DEAD) + continue; +- if (!flp->oif || flp->oif == nh->nh_oif) +- break; ++ if (flp->oif && flp->oif != nh->nh_oif) ++ continue; ++ if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw && ++ nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) ++ continue; ++ break; + } + #ifdef CONFIG_IP_ROUTE_MULTIPATH + if (nhsel < fi->fib_nhs) { +@@ -1080,18 +1159,29 @@ int fib_sync_down_dev(struct net_device + prev_fi = fi; + dead = 0; + change_nexthops(fi) { +- if (nh->nh_flags&RTNH_F_DEAD) +- dead++; +- else if (nh->nh_dev == dev && +- nh->nh_scope != scope) { +- nh->nh_flags |= RTNH_F_DEAD; ++ if (nh->nh_flags&RTNH_F_DEAD) { ++ if (fi->fib_protocol!=RTPROT_STATIC || ++ nh->nh_dev == NULL || ++ __in_dev_get_rtnl(nh->nh_dev) == NULL || ++ nh->nh_dev->flags&IFF_UP) ++ dead++; ++ } else if (nh->nh_dev == dev && ++ nh->nh_scope != scope) { ++ write_lock_bh(&fib_nhflags_lock); + #ifdef CONFIG_IP_ROUTE_MULTIPATH +- spin_lock_bh(&fib_multipath_lock); ++ spin_lock(&fib_multipath_lock); ++ nh->nh_flags |= RTNH_F_DEAD; + fi->fib_power -= nh->nh_power; + nh->nh_power = 0; +- spin_unlock_bh(&fib_multipath_lock); ++ spin_unlock(&fib_multipath_lock); ++#else ++ nh->nh_flags |= RTNH_F_DEAD; + #endif +- dead++; ++ write_unlock_bh(&fib_nhflags_lock); ++ if (fi->fib_protocol!=RTPROT_STATIC || ++ force || ++ __in_dev_get_rtnl(dev) == NULL) ++ dead++; + } + #ifdef CONFIG_IP_ROUTE_MULTIPATH + if (force > 1 && nh->nh_dev == dev) { +@@ -1109,11 +1199,8 @@ int fib_sync_down_dev(struct net_device + return ret; + } + +-#ifdef CONFIG_IP_ROUTE_MULTIPATH +- + /* +- Dead device goes up. We wake up dead nexthops. +- It takes sense only on multipath routes. ++ Dead device goes up or new address is added. We wake up dead nexthops. + */ + + int fib_sync_up(struct net_device *dev) +@@ -1123,8 +1210,10 @@ int fib_sync_up(struct net_device *dev) + struct hlist_head *head; + struct hlist_node *node; + struct fib_nh *nh; +- int ret; ++ struct fib_result res; ++ int ret, rep; + ++repeat: + if (!(dev->flags&IFF_UP)) + return 0; + +@@ -1132,6 +1221,7 @@ int fib_sync_up(struct net_device *dev) + hash = fib_devindex_hashfn(dev->ifindex); + head = &fib_info_devhash[hash]; + ret = 0; ++ rep = 0; + + hlist_for_each_entry(nh, node, head, nh_hash) { + struct fib_info *fi = nh->nh_parent; +@@ -1144,19 +1234,39 @@ int fib_sync_up(struct net_device *dev) + prev_fi = fi; + alive = 0; + change_nexthops(fi) { +- if (!(nh->nh_flags&RTNH_F_DEAD)) { +- alive++; ++ if (!(nh->nh_flags&RTNH_F_DEAD)) + continue; +- } + if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP)) + continue; + if (nh->nh_dev != dev || !__in_dev_get_rtnl(dev)) + continue; ++ if (nh->nh_gw && fi->fib_protocol == RTPROT_STATIC) { ++ struct flowi fl = { ++ .nl_u = { .ip4_u = ++ { .daddr = nh->nh_gw, ++ .scope = nh->nh_scope } }, ++ .oif = nh->nh_oif, ++ }; ++ if (fib_lookup(dev_net(dev), &fl, &res) != 0) ++ continue; ++ if (res.type != RTN_UNICAST && ++ res.type != RTN_LOCAL) { ++ fib_res_put(&res); ++ continue; ++ } ++ nh->nh_scope = res.scope; ++ fib_res_put(&res); ++ rep = 1; ++ } + alive++; ++#ifdef CONFIG_IP_ROUTE_MULTIPATH + spin_lock_bh(&fib_multipath_lock); + nh->nh_power = 0; ++#endif + nh->nh_flags &= ~RTNH_F_DEAD; ++#ifdef CONFIG_IP_ROUTE_MULTIPATH + spin_unlock_bh(&fib_multipath_lock); ++#endif + } endfor_nexthops(fi) + + if (alive > 0) { +@@ -1164,10 +1274,14 @@ int fib_sync_up(struct net_device *dev) + ret++; + } + } ++ if (rep) ++ goto repeat; + + return ret; + } + ++#ifdef CONFIG_IP_ROUTE_MULTIPATH ++ + /* + The algorithm is suboptimal, but it provides really + fair weighted route distribution. +@@ -1176,24 +1290,45 @@ int fib_sync_up(struct net_device *dev) + void fib_select_multipath(const struct flowi *flp, struct fib_result *res) + { + struct fib_info *fi = res->fi; +- int w; ++ int w, alive; + + spin_lock_bh(&fib_multipath_lock); ++ if (flp->oif) { ++ int sel = -1; ++ w = -1; ++ change_nexthops(fi) { ++ if (flp->oif != nh->nh_oif) ++ continue; ++ if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw && ++ nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) ++ continue; ++ if (!(nh->nh_flags&RTNH_F_BADSTATE)) { ++ if (nh->nh_power > w) { ++ w = nh->nh_power; ++ sel = nhsel; ++ } ++ } ++ } endfor_nexthops(fi); ++ if (sel >= 0) { ++ spin_unlock_bh(&fib_multipath_lock); ++ res->nh_sel = sel; ++ return; ++ } ++ goto last_resort; ++ } ++ ++repeat: + if (fi->fib_power <= 0) { + int power = 0; + change_nexthops(fi) { +- if (!(nh->nh_flags&RTNH_F_DEAD)) { ++ if (!(nh->nh_flags&RTNH_F_BADSTATE)) { + power += nh->nh_weight; + nh->nh_power = nh->nh_weight; + } + } endfor_nexthops(fi); + fi->fib_power = power; +- if (power <= 0) { +- spin_unlock_bh(&fib_multipath_lock); +- /* Race condition: route has just become dead. */ +- res->nh_sel = 0; +- return; +- } ++ if (power <= 0) ++ goto last_resort; + } + + +@@ -1203,20 +1338,40 @@ void fib_select_multipath(const struct f + + w = jiffies % fi->fib_power; + ++ alive = 0; + change_nexthops(fi) { +- if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) { ++ if (!(nh->nh_flags&RTNH_F_BADSTATE) && nh->nh_power) { + if ((w -= nh->nh_power) <= 0) { + nh->nh_power--; + fi->fib_power--; +- res->nh_sel = nhsel; + spin_unlock_bh(&fib_multipath_lock); ++ res->nh_sel = nhsel; + return; + } ++ alive = 1; ++ } ++ } endfor_nexthops(fi); ++ if (alive) { ++ fi->fib_power = 0; ++ goto repeat; ++ } ++ ++last_resort: ++ ++ for_nexthops(fi) { ++ if (!(nh->nh_flags&RTNH_F_DEAD)) { ++ if (flp->oif && flp->oif != nh->nh_oif) ++ continue; ++ if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw && ++ nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) ++ continue; ++ spin_unlock_bh(&fib_multipath_lock); ++ res->nh_sel = nhsel; ++ return; + } + } endfor_nexthops(fi); + + /* Race condition: route has just become dead. */ +- res->nh_sel = 0; + spin_unlock_bh(&fib_multipath_lock); + } + #endif +diff -urp v2.6.31/linux/net/ipv4/fib_trie.c linux/net/ipv4/fib_trie.c +--- v2.6.31/linux/net/ipv4/fib_trie.c 2009-09-11 10:27:17.000000000 +0300 ++++ linux/net/ipv4/fib_trie.c 2009-09-11 22:11:20.000000000 +0300 +@@ -1291,6 +1291,7 @@ static int fn_trie_insert(struct fib_tab + fi_drop = fa->fa_info; + new_fa->fa_tos = fa->fa_tos; + new_fa->fa_info = fi; ++ new_fa->fa_last_dflt = -1; + new_fa->fa_type = cfg->fc_type; + new_fa->fa_scope = cfg->fc_scope; + state = fa->fa_state; +@@ -1331,6 +1332,7 @@ static int fn_trie_insert(struct fib_tab + new_fa->fa_type = cfg->fc_type; + new_fa->fa_scope = cfg->fc_scope; + new_fa->fa_state = 0; ++ new_fa->fa_last_dflt = -1; + /* + * Insert new entry to the list. + */ +@@ -1831,24 +1833,31 @@ static void fn_trie_select_default(struc + struct fib_result *res) + { + struct trie *t = (struct trie *) tb->tb_data; +- int order, last_idx; ++ int order, last_idx, last_dflt, last_nhsel; ++ struct fib_alias *first_fa = NULL; + struct fib_info *fi = NULL; + struct fib_info *last_resort; + struct fib_alias *fa = NULL; + struct list_head *fa_head; + struct leaf *l; ++ u32 key, mask; + ++ last_dflt = -2; ++ last_nhsel = 0; + last_idx = -1; + last_resort = NULL; + order = -1; + ++ mask = inet_make_mask(res->prefixlen); ++ key = ntohl(flp->fl4_dst & mask); ++ + rcu_read_lock(); + +- l = fib_find_node(t, 0); ++ l = fib_find_node(t, key); + if (!l) + goto out; + +- fa_head = get_fa_head(l, 0); ++ fa_head = get_fa_head(l, res->prefixlen); + if (!fa_head) + goto out; + +@@ -1862,39 +1871,52 @@ static void fn_trie_select_default(struc + fa->fa_type != RTN_UNICAST) + continue; + ++ if (fa->fa_tos && ++ fa->fa_tos != flp->fl4_tos) ++ continue; + if (next_fi->fib_priority > res->fi->fib_priority) + break; +- if (!next_fi->fib_nh[0].nh_gw || +- next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) +- continue; + fa->fa_state |= FA_S_ACCESSED; + +- if (fi == NULL) { +- if (next_fi != res->fi) +- break; +- } else if (!fib_detect_death(fi, order, &last_resort, +- &last_idx, tb->tb_default)) { ++ if (!first_fa) { ++ last_dflt = fa->fa_last_dflt; ++ first_fa = fa; ++ } ++ if (fi && !fib_detect_death(fi, order, &last_resort, ++ &last_idx, &last_dflt, &last_nhsel, flp)) { + fib_result_assign(res, fi); +- tb->tb_default = order; ++ first_fa->fa_last_dflt = order; + goto out; + } + fi = next_fi; + order++; + } + if (order <= 0 || fi == NULL) { +- tb->tb_default = -1; ++ if (fi && fi->fib_nhs > 1 && ++ fib_detect_death(fi, order, &last_resort, &last_idx, ++ &last_dflt, &last_nhsel, flp) && ++ last_resort == fi) { ++ read_lock_bh(&fib_nhflags_lock); ++ fi->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT; ++ read_unlock_bh(&fib_nhflags_lock); ++ } ++ if (first_fa) first_fa->fa_last_dflt = -1; + goto out; + } + + if (!fib_detect_death(fi, order, &last_resort, &last_idx, +- tb->tb_default)) { ++ &last_dflt, &last_nhsel, flp)) { + fib_result_assign(res, fi); +- tb->tb_default = order; ++ first_fa->fa_last_dflt = order; + goto out; + } +- if (last_idx >= 0) ++ if (last_idx >= 0) { + fib_result_assign(res, last_resort); +- tb->tb_default = last_idx; ++ read_lock_bh(&fib_nhflags_lock); ++ last_resort->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT; ++ read_unlock_bh(&fib_nhflags_lock); ++ first_fa->fa_last_dflt = last_idx; ++ } + out: + rcu_read_unlock(); + } +diff -urp v2.6.31/linux/net/ipv4/netfilter/ipt_MASQUERADE.c linux/net/ipv4/netfilter/ipt_MASQUERADE.c +--- v2.6.31/linux/net/ipv4/netfilter/ipt_MASQUERADE.c 2009-09-11 10:27:17.000000000 +0300 ++++ linux/net/ipv4/netfilter/ipt_MASQUERADE.c 2009-09-11 22:14:42.000000000 +0300 +@@ -51,7 +51,7 @@ masquerade_tg(struct sk_buff *skb, const + enum ip_conntrack_info ctinfo; + struct nf_nat_range newrange; + const struct nf_nat_multi_range_compat *mr; +- const struct rtable *rt; ++ struct rtable *rt; + __be32 newsrc; + + NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING); +@@ -69,13 +69,28 @@ masquerade_tg(struct sk_buff *skb, const + return NF_ACCEPT; + + mr = par->targinfo; +- rt = skb_rtable(skb); +- newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE); +- if (!newsrc) { +- printk("MASQUERADE: %s ate my IP address\n", par->out->name); +- return NF_DROP; ++ ++ { ++ struct flowi fl = { .nl_u = { .ip4_u = ++ { .daddr = ip_hdr(skb)->daddr, ++ .tos = (RT_TOS(ip_hdr(skb)->tos) | ++ RTO_CONN), ++ .gw = skb_rtable(skb)->rt_gateway, ++ } }, ++ .mark = skb->mark, ++ .oif = par->out->ifindex }; ++ if (ip_route_output_key(dev_net(par->out), &rt, &fl) != 0) { ++ /* Funky routing can do this. */ ++ if (net_ratelimit()) ++ printk("MASQUERADE:" ++ " No route: Rusty's brain broke!\n"); ++ return NF_DROP; ++ } + } + ++ newsrc = rt->rt_src; ++ ip_rt_put(rt); ++ + nat->masq_index = par->out->ifindex; + + /* Transfer from original range. */ +diff -urp v2.6.31/linux/net/ipv4/netfilter/nf_nat_core.c linux/net/ipv4/netfilter/nf_nat_core.c +--- v2.6.31/linux/net/ipv4/netfilter/nf_nat_core.c 2009-06-13 10:53:58.000000000 +0300 ++++ linux/net/ipv4/netfilter/nf_nat_core.c 2009-09-11 22:13:59.000000000 +0300 +@@ -711,6 +711,52 @@ static struct pernet_operations nf_nat_n + .exit = nf_nat_net_exit, + }; + ++unsigned int ++ip_nat_route_input(unsigned int hooknum, ++ struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct iphdr *iph; ++ struct nf_conn *conn; ++ enum ip_conntrack_info ctinfo; ++ enum ip_conntrack_dir dir; ++ unsigned long statusbit; ++ __be32 saddr; ++ ++ if (!(conn = nf_ct_get(skb, &ctinfo))) ++ return NF_ACCEPT; ++ ++ if (!(conn->status & IPS_NAT_DONE_MASK)) ++ return NF_ACCEPT; ++ dir = CTINFO2DIR(ctinfo); ++ statusbit = IPS_SRC_NAT; ++ if (dir == IP_CT_DIR_REPLY) ++ statusbit ^= IPS_NAT_MASK; ++ if (!(conn->status & statusbit)) ++ return NF_ACCEPT; ++ ++ if (skb_dst(skb)) ++ return NF_ACCEPT; ++ ++ if (skb->len < sizeof(struct iphdr)) ++ return NF_ACCEPT; ++ ++ /* use daddr in other direction as masquerade address (lsrc) */ ++ iph = ip_hdr(skb); ++ saddr = conn->tuplehash[!dir].tuple.dst.u3.ip; ++ if (saddr == iph->saddr) ++ return NF_ACCEPT; ++ ++ if (ip_route_input_lookup(skb, iph->daddr, iph->saddr, iph->tos, ++ skb->dev, saddr)) ++ return NF_DROP; ++ ++ return NF_ACCEPT; ++} ++EXPORT_SYMBOL_GPL(ip_nat_route_input); ++ + static int __init nf_nat_init(void) + { + size_t i; +diff -urp v2.6.31/linux/net/ipv4/netfilter/nf_nat_standalone.c linux/net/ipv4/netfilter/nf_nat_standalone.c +--- v2.6.31/linux/net/ipv4/netfilter/nf_nat_standalone.c 2009-09-11 10:27:17.000000000 +0300 ++++ linux/net/ipv4/netfilter/nf_nat_standalone.c 2009-09-11 22:12:39.000000000 +0300 +@@ -255,6 +255,14 @@ static struct nf_hook_ops nf_nat_ops[] _ + .hooknum = NF_INET_PRE_ROUTING, + .priority = NF_IP_PRI_NAT_DST, + }, ++ /* Before routing, route before mangling */ ++ { ++ .hook = ip_nat_route_input, ++ .owner = THIS_MODULE, ++ .pf = PF_INET, ++ .hooknum = NF_INET_PRE_ROUTING, ++ .priority = NF_IP_PRI_LAST-1, ++ }, + /* After packet filtering, change source */ + { + .hook = nf_nat_out, +diff -urp v2.6.31/linux/net/ipv4/route.c linux/net/ipv4/route.c +--- v2.6.31/linux/net/ipv4/route.c 2009-09-11 10:27:17.000000000 +0300 ++++ linux/net/ipv4/route.c 2009-09-11 22:12:39.000000000 +0300 +@@ -695,6 +695,8 @@ static inline int compare_keys(struct fl + return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) | + (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr)) | + (fl1->mark ^ fl2->mark) | ++ ((__force u32)(fl1->nl_u.ip4_u.lsrc ^ fl2->nl_u.ip4_u.lsrc)) | ++ ((__force u32)(fl1->nl_u.ip4_u.gw ^ fl2->nl_u.ip4_u.gw)) | + (*(u16 *)&fl1->nl_u.ip4_u.tos ^ + *(u16 *)&fl2->nl_u.ip4_u.tos) | + (fl1->oif ^ fl2->oif) | +@@ -1424,6 +1426,7 @@ void ip_rt_redirect(__be32 old_gw, __be3 + + /* Gateway is different ... */ + rt->rt_gateway = new_gw; ++ if (rt->fl.fl4_gw) rt->fl.fl4_gw = new_gw; + + /* Redirect received -> path was valid */ + dst_confirm(&rth->u.dst); +@@ -1870,6 +1873,7 @@ static int ip_route_input_mc(struct sk_b + rth->fl.fl4_tos = tos; + rth->fl.mark = skb->mark; + rth->fl.fl4_src = saddr; ++ rth->fl.fl4_lsrc = 0; + rth->rt_src = saddr; + #ifdef CONFIG_NET_CLS_ROUTE + rth->u.dst.tclassid = itag; +@@ -1880,6 +1884,7 @@ static int ip_route_input_mc(struct sk_b + dev_hold(rth->u.dst.dev); + rth->idev = in_dev_get(rth->u.dst.dev); + rth->fl.oif = 0; ++ rth->fl.fl4_gw = 0; + rth->rt_gateway = daddr; + rth->rt_spec_dst= spec_dst; + rth->rt_genid = rt_genid(dev_net(dev)); +@@ -1944,7 +1949,7 @@ static int __mkroute_input(struct sk_buf + struct fib_result *res, + struct in_device *in_dev, + __be32 daddr, __be32 saddr, u32 tos, +- struct rtable **result) ++ __be32 lsrc, struct rtable **result) + { + + struct rtable *rth; +@@ -1978,6 +1983,7 @@ static int __mkroute_input(struct sk_buf + flags |= RTCF_DIRECTSRC; + + if (out_dev == in_dev && err && ++ !lsrc && + (IN_DEV_SHARED_MEDIA(out_dev) || + inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) + flags |= RTCF_DOREDIRECT; +@@ -2011,6 +2017,7 @@ static int __mkroute_input(struct sk_buf + rth->fl.mark = skb->mark; + rth->fl.fl4_src = saddr; + rth->rt_src = saddr; ++ rth->fl.fl4_lsrc = lsrc; + rth->rt_gateway = daddr; + rth->rt_iif = + rth->fl.iif = in_dev->dev->ifindex; +@@ -2018,6 +2025,7 @@ static int __mkroute_input(struct sk_buf + dev_hold(rth->u.dst.dev); + rth->idev = in_dev_get(rth->u.dst.dev); + rth->fl.oif = 0; ++ rth->fl.fl4_gw = 0; + rth->rt_spec_dst= spec_dst; + + rth->u.dst.input = ip_forward; +@@ -2038,21 +2046,23 @@ static int __mkroute_input(struct sk_buf + + static int ip_mkroute_input(struct sk_buff *skb, + struct fib_result *res, ++ struct net *net, + const struct flowi *fl, + struct in_device *in_dev, +- __be32 daddr, __be32 saddr, u32 tos) ++ __be32 daddr, __be32 saddr, u32 tos, __be32 lsrc) + { + struct rtable* rth = NULL; + int err; + unsigned hash; + ++ fib_select_default(net, fl, res); + #ifdef CONFIG_IP_ROUTE_MULTIPATH +- if (res->fi && res->fi->fib_nhs > 1 && fl->oif == 0) ++ if (res->fi && res->fi->fib_nhs > 1) + fib_select_multipath(fl, res); + #endif + + /* create a routing cache entry */ +- err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth); ++ err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, lsrc, &rth); + if (err) + return err; + +@@ -2073,18 +2083,19 @@ static int ip_mkroute_input(struct sk_bu + */ + + static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, +- u8 tos, struct net_device *dev) ++ u8 tos, struct net_device *dev, __be32 lsrc) + { + struct fib_result res; + struct in_device *in_dev = in_dev_get(dev); + struct flowi fl = { .nl_u = { .ip4_u = + { .daddr = daddr, +- .saddr = saddr, ++ .saddr = lsrc? : saddr, + .tos = tos, + .scope = RT_SCOPE_UNIVERSE, + } }, + .mark = skb->mark, +- .iif = dev->ifindex }; ++ .iif = lsrc? ++ dev_net(dev)->loopback_dev->ifindex : dev->ifindex }; + unsigned flags = 0; + u32 itag = 0; + struct rtable * rth; +@@ -2120,6 +2131,12 @@ static int ip_route_input_slow(struct sk + ipv4_is_loopback(daddr)) + goto martian_destination; + ++ if (lsrc) { ++ if (ipv4_is_multicast(lsrc) || ipv4_is_lbcast(lsrc) || ++ ipv4_is_zeronet(lsrc) || ipv4_is_loopback(lsrc)) ++ goto e_inval; ++ } ++ + /* + * Now we are ready to route packet. + */ +@@ -2129,6 +2146,8 @@ static int ip_route_input_slow(struct sk + goto no_route; + } + free_res = 1; ++ fl.iif = dev->ifindex; ++ fl.fl4_src = saddr; + + RT_CACHE_STAT_INC(in_slow_tot); + +@@ -2153,7 +2172,7 @@ static int ip_route_input_slow(struct sk + if (res.type != RTN_UNICAST) + goto martian_destination; + +- err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos); ++ err = ip_mkroute_input(skb, &res, net, &fl, in_dev, daddr, saddr, tos, lsrc); + done: + in_dev_put(in_dev); + if (free_res) +@@ -2163,6 +2182,8 @@ out: return err; + brd_input: + if (skb->protocol != htons(ETH_P_IP)) + goto e_inval; ++ if (lsrc) ++ goto e_inval; + + if (ipv4_is_zeronet(saddr)) + spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); +@@ -2204,6 +2225,7 @@ local_input: + rth->u.dst.dev = net->loopback_dev; + dev_hold(rth->u.dst.dev); + rth->idev = in_dev_get(rth->u.dst.dev); ++ rth->fl.fl4_gw = 0; + rth->rt_gateway = daddr; + rth->rt_spec_dst= spec_dst; + rth->u.dst.input= ip_local_deliver; +@@ -2254,8 +2276,9 @@ martian_source: + goto e_inval; + } + +-int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, +- u8 tos, struct net_device *dev) ++static inline int ++ip_route_input_cached(struct sk_buff *skb, __be32 daddr, __be32 saddr, ++ u8 tos, struct net_device *dev, __be32 lsrc) + { + struct rtable * rth; + unsigned hash; +@@ -2276,6 +2299,7 @@ int ip_route_input(struct sk_buff *skb, + if (((rth->fl.fl4_dst ^ daddr) | + (rth->fl.fl4_src ^ saddr) | + (rth->fl.iif ^ iif) | ++ (rth->fl.fl4_lsrc ^ lsrc) | + rth->fl.oif | + (rth->fl.fl4_tos ^ tos)) == 0 && + rth->fl.mark == skb->mark && +@@ -2324,7 +2348,19 @@ skip_cache: + rcu_read_unlock(); + return -EINVAL; + } +- return ip_route_input_slow(skb, daddr, saddr, tos, dev); ++ return ip_route_input_slow(skb, daddr, saddr, tos, dev, lsrc); ++} ++ ++int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, ++ u8 tos, struct net_device *dev) ++{ ++ return ip_route_input_cached(skb, daddr, saddr, tos, dev, 0); ++} ++ ++int ip_route_input_lookup(struct sk_buff *skb, __be32 daddr, __be32 saddr, ++ u8 tos, struct net_device *dev, __be32 lsrc) ++{ ++ return ip_route_input_cached(skb, daddr, saddr, tos, dev, lsrc); + } + + static int __mkroute_output(struct rtable **result, +@@ -2396,6 +2432,7 @@ static int __mkroute_output(struct rtabl + rth->fl.fl4_tos = tos; + rth->fl.fl4_src = oldflp->fl4_src; + rth->fl.oif = oldflp->oif; ++ rth->fl.fl4_gw = oldflp->fl4_gw; + rth->fl.mark = oldflp->mark; + rth->rt_dst = fl->fl4_dst; + rth->rt_src = fl->fl4_src; +@@ -2477,6 +2514,7 @@ static int ip_route_output_slow(struct n + struct flowi fl = { .nl_u = { .ip4_u = + { .daddr = oldflp->fl4_dst, + .saddr = oldflp->fl4_src, ++ .gw = oldflp->fl4_gw, + .tos = tos & IPTOS_RT_MASK, + .scope = ((tos & RTO_ONLINK) ? + RT_SCOPE_LINK : +@@ -2588,6 +2626,7 @@ static int ip_route_output_slow(struct n + dev_out = net->loopback_dev; + dev_hold(dev_out); + fl.oif = net->loopback_dev->ifindex; ++ fl.fl4_gw = 0; + res.type = RTN_LOCAL; + flags |= RTCF_LOCAL; + goto make_route; +@@ -2595,7 +2634,7 @@ static int ip_route_output_slow(struct n + + if (fib_lookup(net, &fl, &res)) { + res.fi = NULL; +- if (oldflp->oif) { ++ if (oldflp->oif && dev_out->flags & IFF_UP) { + /* Apparently, routing tables are wrong. Assume, + that the destination is on link. + +@@ -2635,6 +2674,7 @@ static int ip_route_output_slow(struct n + dev_out = net->loopback_dev; + dev_hold(dev_out); + fl.oif = dev_out->ifindex; ++ fl.fl4_gw = 0; + if (res.fi) + fib_info_put(res.fi); + res.fi = NULL; +@@ -2642,13 +2682,12 @@ static int ip_route_output_slow(struct n + goto make_route; + } + ++ if (res.type == RTN_UNICAST) ++ fib_select_default(net, &fl, &res); + #ifdef CONFIG_IP_ROUTE_MULTIPATH +- if (res.fi->fib_nhs > 1 && fl.oif == 0) ++ if (res.fi->fib_nhs > 1) + fib_select_multipath(&fl, &res); +- else + #endif +- if (!res.prefixlen && res.type == RTN_UNICAST && !fl.oif) +- fib_select_default(net, &fl, &res); + + if (!fl.fl4_src) + fl.fl4_src = FIB_RES_PREFSRC(res); +@@ -2689,6 +2728,7 @@ int __ip_route_output_key(struct net *ne + rth->fl.fl4_src == flp->fl4_src && + rth->fl.iif == 0 && + rth->fl.oif == flp->oif && ++ rth->fl.fl4_gw == flp->fl4_gw && + rth->fl.mark == flp->mark && + !((rth->fl.fl4_tos ^ flp->fl4_tos) & + (IPTOS_RT_MASK | RTO_ONLINK)) && +@@ -3466,3 +3506,4 @@ void __init ip_static_sysctl_init(void) + EXPORT_SYMBOL(__ip_select_ident); + EXPORT_SYMBOL(ip_route_input); + EXPORT_SYMBOL(ip_route_output_key); ++EXPORT_SYMBOL(ip_route_input_lookup); diff --git a/pkgs/core/l7-protocols/l7-protocols.nm b/pkgs/core/l7-protocols/l7-protocols.nm new file mode 100644 index 0000000..6bf061f --- /dev/null +++ b/pkgs/core/l7-protocols/l7-protocols.nm @@ -0,0 +1,53 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = l7-protocols +PKG_VER = 2007-11-22 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Firewall +PKG_URL = http://l7-filter.sourceforge.net/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Application Layer Packet Classifier for Linux. + +PKG_DEPS += + +define PKG_DESCRIPTION + L7-filter is a classifier for Linux's Netfilter that identifies packets \ + based on application layer data. It can classify packets as Kazaa, HTTP, \ + Jabber, Citrix, Bittorrent, FTP, Gnucleus, eDonkey2000, etc., regardless \ + of port. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +STAGE_BUILD = # Do nothing + +define STAGE_INSTALL + -mkdir -p $(BUILDROOT)/etc/l7-protocols + cp -Rfv $(DIR_APP)/* $(BUILDROOT)/etc/l7-protocols +endef diff --git a/pkgs/core/ldapvi/ldapvi.nm b/pkgs/core/ldapvi/ldapvi.nm new file mode 100644 index 0000000..fb988a1 --- /dev/null +++ b/pkgs/core/ldapvi/ldapvi.nm @@ -0,0 +1,55 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = ldapvi +PKG_VER = 1.7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Editors +PKG_URL = http://www.lichteblau.com/ldapvi/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = An interactive LDAP client. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += glib2 libxslt ncurses openldap openssl popt readline + +define PKG_DESCRIPTION + ldapvi is an interactive LDAP client for Unix terminals. Using it, you can \ + update LDAP entries with a text editor, which is the same as vi. Think of \ + it as vipw(1) for LDAP. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && for i in $$(find . -name "*.[ch]"); do \ + sed -e "s/getline/_&/g" -i $$i; done +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install prefix=$(BUILDROOT)/usr +endef diff --git a/pkgs/core/less/less.nm b/pkgs/core/less/less.nm new file mode 100644 index 0000000..b17d8ce --- /dev/null +++ b/pkgs/core/less/less.nm @@ -0,0 +1,49 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = less +PKG_VER = 436 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Text +PKG_URL = http://www.greenwoodsoftware.com/less/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = A text file browser similar to more, but better. + +PKG_DEPS += ncurses pcre + +define PKG_DESCRIPTION + The less utility is a text file browser that resembles more, but has \ + more capabilities. Less allows you to move backwards in the file as \ + well as forwards. Since less doesn't have to read the entire input file \ + before it starts, less starts up more quickly than text editors (for \ + example, vi). +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --with-secure --with-regex=pcre diff --git a/pkgs/core/libaal/libaal.nm b/pkgs/core/libaal/libaal.nm new file mode 100644 index 0000000..863ea45 --- /dev/null +++ b/pkgs/core/libaal/libaal.nm @@ -0,0 +1,52 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libaal +PKG_VER = 1.0.5 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Filesystems +PKG_URL = http://www.kernel.org/pub/linux/utils/fs/reiser4/libaal/ +PKG_LICENSE = GPL +PKG_SUMMARY = Reiser4's application abstraction library. + +define PKG_DESCRIPTION + This library is part of the Reiser4's filesystem support tools. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --libdir=/lib + +define STAGE_INSTALL_CMDS + rm -vf $(BUILDROOT)/lib/libaal{,-minimal}.so + -mkdir -pv $(BUILDROOT)/usr/lib + ln -svf ../../lib/libaal-1.0.so.5 $(BUILDROOT)/usr/lib/libaal-1.0.so + ln -svf libaal-1.0.so $(BUILDROOT)/usr/lib/libaal.so + ln -svf ../../lib/libaal-minimal.so.0 $(BUILDROOT)/usr/lib/libaal-minimal.so +endef diff --git a/pkgs/core/libart/libart.nm b/pkgs/core/libart/libart.nm new file mode 100644 index 0000000..2c1b47c --- /dev/null +++ b/pkgs/core/libart/libart.nm @@ -0,0 +1,44 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libart_lgpl +PKG_VER = 2.3.19 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Graphics +PKG_URL = http://www.gnome.org +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = Library of graphics routines used by libgnomecanvas. + +PKG_DEPS += + +define PKG_DESCRIPTION + Graphics routines used by the GnomeCanvas widget and some other \ + applications. libart renders vector paths and the like. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 diff --git a/pkgs/core/libart/patches/libart_lgpl-2.3.19-upstream_fix-1.patch b/pkgs/core/libart/patches/libart_lgpl-2.3.19-upstream_fix-1.patch new file mode 100644 index 0000000..68d60ed --- /dev/null +++ b/pkgs/core/libart/patches/libart_lgpl-2.3.19-upstream_fix-1.patch @@ -0,0 +1,28 @@ +Submitted By: Randy McMurchy <randy_at_linuxfromscratch_dot_org> +Date: 2007-04-09 +Initial Package Version: 2.3.19 +Upstream Status: In upstream CVS +Origin: Upstream +Description: Fixes an error during the installation of KDE-Libs + + +diff -Naur libart_lgpl-2.3.19.orig/art_misc.h libart_lgpl-2.3.19/art_misc.h +--- libart_lgpl-2.3.19.orig/art_misc.h 2007-01-01 18:59:22.000000000 -0500 ++++ libart_lgpl-2.3.19/art_misc.h 2007-03-20 23:04:52.000000000 -0400 +@@ -34,9 +34,15 @@ + #include <libart_lgpl/art_config.h> + #endif + ++#ifdef __cplusplus ++extern "C" { ++#endif + void *art_alloc(size_t size); + void art_free(void *ptr); + void *art_realloc(void *ptr, size_t size); ++#ifdef __cplusplus ++} ++#endif /* __cplusplus */ + + /* These aren't, strictly speaking, configuration macros, but they're + damn handy to have around, and may be worth playing with for + diff --git a/pkgs/core/libassuan/libassuan.nm b/pkgs/core/libassuan/libassuan.nm new file mode 100644 index 0000000..ec90824 --- /dev/null +++ b/pkgs/core/libassuan/libassuan.nm @@ -0,0 +1,53 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libassuan +PKG_VER = 1.0.5 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gnupg.org/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = GnuPG IPC library. + +PKG_BUILD_DEPS+= autoconf automake libtool +PKG_DEPS += pth + +define PKG_DESCRIPTION + The Libassuan package contains an IPC library used by some of the other \ + GnuPG related packages. Libassuan's primary use is to allow a client to \ + interact with a non-persistent server. Libassuan is not, however, limited \ + to use with GnuPG servers and clients. It was designed to be flexible \ + enough to meet the demands of many transaction based environments with \ + non-persistent servers. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && autoreconf --install +endef diff --git a/pkgs/core/libassuan/patches/libassuan-1.0.5-ac.patch b/pkgs/core/libassuan/patches/libassuan-1.0.5-ac.patch new file mode 100644 index 0000000..4385713 --- /dev/null +++ b/pkgs/core/libassuan/patches/libassuan-1.0.5-ac.patch @@ -0,0 +1,26 @@ +--- libassuan-1.0.5/configure.ac.orig 2008-05-27 08:25:59.235870000 +0200 ++++ libassuan-1.0.5/configure.ac 2008-05-27 08:36:37.868258393 +0200 +@@ -44,7 +44,10 @@ + AB_INIT + + AC_GNU_SOURCE +- ++AH_TEMPLATE([_ALL_SOURCE], [All extensions]) ++AH_TEMPLATE([_GNU_SOURCE], [GNU extensions]) ++AH_TEMPLATE([_POSIX_PTHREAD_SEMANTICS], [POSIX pthread semantics]) ++AH_TEMPLATE([_TANDEM_SOURCE], [Tandem extensions]) + + AC_SUBST(PACKAGE) + AC_SUBST(VERSION) +@@ -106,11 +109,6 @@ + have_dosish_system=no + have_w32_system=no + case "${host}" in +- *-linux*) +- if test "$GCC" = yes; then +- CFLAGS="$CFLAGS -fPIC -DPIC" +- fi +- ;; + *-mingw32*) + have_dosish_system=yes + have_w32_system=yes diff --git a/pkgs/core/libassuan/patches/libassuan-1.0.5-shared.patch b/pkgs/core/libassuan/patches/libassuan-1.0.5-shared.patch new file mode 100644 index 0000000..5491c4e --- /dev/null +++ b/pkgs/core/libassuan/patches/libassuan-1.0.5-shared.patch @@ -0,0 +1,59 @@ +--- libassuan-1.0.1/src/Makefile.am.orig 2006-11-21 19:17:18.000000000 +0100 ++++ libassuan-1.0.1/src/Makefile.am 2006-11-23 19:30:28.776620250 +0100 +@@ -25,7 +25,7 @@ + MOSTLYCLEANFILES = assuan-errors.c + + if HAVE_PTH +-libassuan_pth = libassuan-pth.a ++libassuan_pth = libassuan-pth.la + else + libassuan_pth = + endif +@@ -33,7 +33,7 @@ + bin_SCRIPTS = libassuan-config + m4datadir = $(datadir)/aclocal + m4data_DATA = libassuan.m4 +-lib_LIBRARIES = libassuan.a $(libassuan_pth) ++lib_LTLIBRARIES = libassuan.la $(libassuan_pth) + include_HEADERS = assuan.h + + +@@ -55,13 +55,13 @@ + assuan-logging.c \ + assuan-socket.c + +-libassuan_a_SOURCES = $(common_sources) assuan-io.c +-libassuan_a_LIBADD = @LIBOBJS@ ++libassuan_la_SOURCES = $(common_sources) assuan-io.c ++libassuan_la_LIBADD = @LTLIBOBJS@ + + if HAVE_PTH +-libassuan_pth_a_SOURCES = $(common_sources) assuan-io-pth.c +-libassuan_pth_a_CFLAGS = $(AM_CFLAGS) $(PTH_CFLAGS) +-libassuan_pth_a_LIBADD = @LIBOBJS@ ++libassuan_pth_la_SOURCES = $(common_sources) assuan-io-pth.c ++libassuan_pth_la_CFLAGS = $(AM_CFLAGS) $(PTH_CFLAGS) ++libassuan_pth_la_LIBADD = @LTLIBOBJS@ $(PTH_LIBS) + endif + + assuan-errors.c : assuan.h mkerrors +--- libassuan-0.6.0/configure.ac.orig 2003-08-06 10:34:42.000000000 +0200 ++++ libassuan-0.6.0/configure.ac 2003-08-10 11:56:23.735375928 +0200 +@@ -57,7 +57,7 @@ + AC_PROG_INSTALL + AC_PROG_LN_S + AC_PROG_MAKE_SET +-AC_PROG_RANLIB ++AC_PROG_LIBTOOL + #AC_ARG_PROGRAM + + if test "$GCC" = yes; then +--- libassuan-0.9.3/tests/Makefile.am.orig 2006-10-10 12:05:25.000000000 +0200 ++++ libassuan-0.9.3/tests/Makefile.am 2006-10-11 12:02:10.555971000 +0200 +@@ -37,5 +37,5 @@ + + noinst_HEADERS = common.h + noinst_PROGRAMS = $(TESTS) +-LDADD = ../src/libassuan.a $(NETLIBS) # $(GPG_ERROR_LIBS) ++LDADD = ../src/libassuan.la $(NETLIBS) # $(GPG_ERROR_LIBS) + diff --git a/pkgs/core/libcap/libcap.nm b/pkgs/core/libcap/libcap.nm new file mode 100644 index 0000000..334ccff --- /dev/null +++ b/pkgs/core/libcap/libcap.nm @@ -0,0 +1,68 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libcap +PKG_VER = 2.16 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://ftp.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/ +PKG_LICENSE = LGPL2+ +PKG_SUMMARY = Library for getting and setting POSIX.1e capabilities. + +PKG_PACKAGES += $(PKG_NAME_REAL)-devel + +define PKG_DESCRIPTION + libcap is a library for getting and setting POSIX.1e (formerly POSIX 6) \ + draft 15 capabilities. +endef + +PKG_DEPS += attr pam + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -e "s@<stdlib.h>@&\n#include <asm/types.h>@g" \ + -i progs/capsh.c + cd $(DIR_APP) && sed 's/--static//' -i.orig progs/Makefile +endef + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) CC="gcc $(CFLAGS)" +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) lib=/lib + + rm -vf $(BUILDROOT)/lib/libcap.so + -mkdir -pv $(BUILDROOT)/usr/lib + ln -svf ../../lib/libcap.so.2 $(BUILDROOT)/usr/lib/libcap.so +endef diff --git a/pkgs/core/libcap/patches/libcap-2.16-headerfix.patch b/pkgs/core/libcap/patches/libcap-2.16-headerfix.patch new file mode 100644 index 0000000..ae6eb28 --- /dev/null +++ b/pkgs/core/libcap/patches/libcap-2.16-headerfix.patch @@ -0,0 +1,12 @@ +diff -up libcap-2.16/libcap/include/sys/capability.h.incfix libcap-2.16/libcap/include/sys/capability.h +--- libcap-2.16/libcap/include/sys/capability.h.incfix 2009-03-22 17:54:02.000000000 +0100 ++++ libcap-2.16/libcap/include/sys/capability.h 2009-03-22 17:54:09.000000000 +0100 +@@ -19,7 +19,7 @@ extern "C" { + * information for the user library. + */ + +-#include <sys/types.h> ++#include <linux/types.h> + #include <stdint.h> + + /* diff --git a/pkgs/core/libdaemon/libdaemon.nm b/pkgs/core/libdaemon/libdaemon.nm new file mode 100644 index 0000000..725effa --- /dev/null +++ b/pkgs/core/libdaemon/libdaemon.nm @@ -0,0 +1,45 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libdaemon +PKG_VER = 0.13 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://0pointer.de/lennart/projects/libdaemon/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = Library for writing UNIX daemons. + +define PKG_DESCRIPTION + libdaemon is a lightweight C library which eases the writing of UNIX daemons. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --bindir=/bin \ + --mandir=/usr/share/man diff --git a/pkgs/core/libdnet/libdnet.nm b/pkgs/core/libdnet/libdnet.nm new file mode 100644 index 0000000..0768b76 --- /dev/null +++ b/pkgs/core/libdnet/libdnet.nm @@ -0,0 +1,50 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libdnet +PKG_VER = 1.12 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://code.google.com/p/libdnet/ +PKG_LICENSE = BSD +PKG_SUMMARY = Simple portable interface to lowlevel networking routines. + +define PKG_DESCRIPTION + libdnet provides a simplified, portable interface to several \ + low-level networking routines, including network address \ + manipulation, kernel arp(4) cache and route(4) table lookup and \ + manipulation, network firewalling (IP filter, ipfw, ipchains, \ + pf, ...), network interface lookup and manipulation, raw IP \ + packet and Ethernet frame, and data transmission. +endef + +PKG_TARBALL = $(THISAPP).tgz + +CONFIGURE_OPTIONS += \ + --sbindir=/sbin \ + --mandir=/usr/share diff --git a/pkgs/core/libdnet/patches/libdnet-1.12-shrext.patch b/pkgs/core/libdnet/patches/libdnet-1.12-shrext.patch new file mode 100644 index 0000000..6d8df23 --- /dev/null +++ b/pkgs/core/libdnet/patches/libdnet-1.12-shrext.patch @@ -0,0 +1,327 @@ +diff -urN libdnet-1.12/configure libdnet-1.12-patched/configure +--- libdnet-1.12/configure 2007-01-20 05:39:54.000000000 -0600 ++++ libdnet-1.12-patched/configure 2007-02-15 09:06:27.000000000 -0600 +@@ -7053,7 +7053,7 @@ + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. +- shrext=".dll" ++ shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '''s/ -lc$//'''` -link -dll${_S_}linknames=' + # The linker will automatically build a .lib file if we build a DLL. +@@ -7580,7 +7580,7 @@ + library_names_spec= + libname_spec='lib$name' + soname_spec= +-shrext=".so" ++shrext_cmds=".so" + postinstall_cmds= + postuninstall_cmds= + finish_cmds= +@@ -7693,7 +7693,7 @@ + + cygwin* | mingw* | pw32*) + version_type=windows +- shrext=".dll" ++ shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + +@@ -7761,7 +7761,7 @@ + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH +- shrext='$(test .$module = .yes && echo .so || echo .dylib)' ++ shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` +@@ -7830,7 +7830,7 @@ + need_version=no + case "$host_cpu" in + ia64*) +- shrext='.so' ++ shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH +@@ -7845,7 +7845,7 @@ + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) +- shrext='.sl' ++ shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH +@@ -7856,7 +7856,7 @@ + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) +- shrext='.sl' ++ shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH +@@ -7992,7 +7992,7 @@ + + os2*) + libname_spec='$name' +- shrext=".dll" ++ shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' +@@ -9201,7 +9201,7 @@ + libext="$libext" + + # Shared library suffix (normally ".so"). +-shrext='$shrext' ++shrext_cmds='$shrext_cmds' + + # Executable file suffix (normally ""). + exeext="$exeext" +@@ -11257,7 +11257,7 @@ + library_names_spec= + libname_spec='lib$name' + soname_spec= +-shrext=".so" ++shrext_cmds=".so" + postinstall_cmds= + postuninstall_cmds= + finish_cmds= +@@ -11370,7 +11370,7 @@ + + cygwin* | mingw* | pw32*) + version_type=windows +- shrext=".dll" ++ shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + +@@ -11438,7 +11438,7 @@ + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH +- shrext='$(test .$module = .yes && echo .so || echo .dylib)' ++ shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` +@@ -11507,7 +11507,7 @@ + need_version=no + case "$host_cpu" in + ia64*) +- shrext='.so' ++ shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH +@@ -11522,7 +11522,7 @@ + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) +- shrext='.sl' ++ shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH +@@ -11533,7 +11533,7 @@ + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) +- shrext='.sl' ++ shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH +@@ -11669,7 +11669,7 @@ + + os2*) + libname_spec='$name' +- shrext=".dll" ++ shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' +@@ -12751,7 +12751,7 @@ + libext="$libext" + + # Shared library suffix (normally ".so"). +-shrext='$shrext' ++shrext_cmds='$shrext_cmds' + + # Executable file suffix (normally ""). + exeext="$exeext" +@@ -13832,7 +13832,7 @@ + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. +- shrext=".dll" ++ shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '''s/ -lc$//'''` -link -dll${_S_}linknames=' + # The linker will automatically build a .lib file if we build a DLL. +@@ -14359,7 +14359,7 @@ + library_names_spec= + libname_spec='lib$name' + soname_spec= +-shrext=".so" ++shrext_cmds=".so" + postinstall_cmds= + postuninstall_cmds= + finish_cmds= +@@ -14472,7 +14472,7 @@ + + cygwin* | mingw* | pw32*) + version_type=windows +- shrext=".dll" ++ shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + +@@ -14540,7 +14540,7 @@ + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH +- shrext='$(test .$module = .yes && echo .so || echo .dylib)' ++ shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` +@@ -14609,7 +14609,7 @@ + need_version=no + case "$host_cpu" in + ia64*) +- shrext='.so' ++ shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH +@@ -14624,7 +14624,7 @@ + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) +- shrext='.sl' ++ shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH +@@ -14635,7 +14635,7 @@ + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) +- shrext='.sl' ++ shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH +@@ -14771,7 +14771,7 @@ + + os2*) + libname_spec='$name' +- shrext=".dll" ++ shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' +@@ -15047,7 +15047,7 @@ + libext="$libext" + + # Shared library suffix (normally ".so"). +-shrext='$shrext' ++shrext_cmds='$shrext_cmds' + + # Executable file suffix (normally ""). + exeext="$exeext" +@@ -16130,7 +16130,7 @@ + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. +- shrext=".dll" ++ shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '''s/ -lc$//'''` -link -dll${_S_}linknames=' + # The linker will automatically build a .lib file if we build a DLL. +@@ -16657,7 +16657,7 @@ + library_names_spec= + libname_spec='lib$name' + soname_spec= +-shrext=".so" ++shrext_cmds=".so" + postinstall_cmds= + postuninstall_cmds= + finish_cmds= +@@ -16770,7 +16770,7 @@ + + cygwin* | mingw* | pw32*) + version_type=windows +- shrext=".dll" ++ shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + +@@ -16838,7 +16838,7 @@ + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH +- shrext='$(test .$module = .yes && echo .so || echo .dylib)' ++ shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` +@@ -16907,7 +16907,7 @@ + need_version=no + case "$host_cpu" in + ia64*) +- shrext='.so' ++ shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH +@@ -16922,7 +16922,7 @@ + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) +- shrext='.sl' ++ shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH +@@ -16933,7 +16933,7 @@ + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) +- shrext='.sl' ++ shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH +@@ -17069,7 +17069,7 @@ + + os2*) + libname_spec='$name' +- shrext=".dll" ++ shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' +@@ -18151,7 +18151,7 @@ + libext="$libext" + + # Shared library suffix (normally ".so"). +-shrext='$shrext' ++shrext_cmds='$shrext_cmds' + + # Executable file suffix (normally ""). + exeext="$exeext" +@@ -18595,7 +18595,7 @@ + libext="$libext" + + # Shared library suffix (normally ".so"). +-shrext='$shrext' ++shrext_cmds='$shrext_cmds' + + # Executable file suffix (normally ""). + exeext="$exeext" diff --git a/pkgs/core/libevent/libevent.nm b/pkgs/core/libevent/libevent.nm new file mode 100644 index 0000000..bdea038 --- /dev/null +++ b/pkgs/core/libevent/libevent.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libevent +PKG_VER = 1.4.10 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://monkey.org/~provos/libevent/ +PKG_LICENSE = BSD +PKG_SUMMARY = Abstract asynchronous event notification library. + +define PKG_DESCRIPTION + The libevent API provides a mechanism to execute a callback \ + function when a specific event occurs on a file descriptor or \ + after a timeout has been reached. libevent is meant to replace \ + the asynchronous event loop found in event driven network \ + servers. An application just needs to call event_dispatch() and \ + can then add or remove events dynamically without having to \ + change the event loop. +endef + +PKG_TARBALL = $(THISAPP)-stable.tar.gz + +DIR_APP = $(DIR_SRC)/$(THISAPP)-stable + +CONFIGURE_OPTIONS += --mandir=/usr/share/man diff --git a/pkgs/core/libgcrypt/libgcrypt.nm b/pkgs/core/libgcrypt/libgcrypt.nm new file mode 100644 index 0000000..e6f0bdf --- /dev/null +++ b/pkgs/core/libgcrypt/libgcrypt.nm @@ -0,0 +1,54 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libgcrypt +PKG_VER = 1.4.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gnupg.org/ +PKG_LICENSE = LGPLv2.1+ +PKG_SUMMARY = A general-purpose cryptography library. + +PKG_DEPS += libgpg-error + +define PKG_DESCRIPTION + Libgcrypt is a general purpose crypto library based on the code used \ + in GNU Privacy Guard. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --libdir=/lib \ + --enable-noexecstack \ + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/usr/lib + rm -vf $(BUILDROOT)/lib/libgcrypt.so + ln -sfv ../../lib/libgcrypt.so.11 $(BUILDROOT)/usr/lib/libgcrypt.so +endef diff --git a/pkgs/core/libgpg-error/libgpg-error.nm b/pkgs/core/libgpg-error/libgpg-error.nm new file mode 100644 index 0000000..b560398 --- /dev/null +++ b/pkgs/core/libgpg-error/libgpg-error.nm @@ -0,0 +1,52 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libgpg-error +PKG_VER = 1.7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gnupg.org/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = Library for error values used by GnuPG components. + +define PKG_DESCRIPTION + This is a library that defines common error values for all GnuPG \ + components. Among these are GPG, GPGSM, GPGME, GPG-Agent, libgcrypt, \ + pinentry, SmartCard Daemon and possibly more in the future. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --libdir=/lib + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/usr/lib + rm -vf $(BUILDROOT)/lib/libgpg-error.so + ln -sfv ../../lib/libgpg-error.so.0 $(BUILDROOT)/usr/lib/libgpg-error.so +endef diff --git a/pkgs/core/libgssglue/libgssglue.nm b/pkgs/core/libgssglue/libgssglue.nm new file mode 100644 index 0000000..0f14185 --- /dev/null +++ b/pkgs/core/libgssglue/libgssglue.nm @@ -0,0 +1,43 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libgssglue +PKG_VER = 0.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.citi.umich.edu/projects/nfsv4/linux/libgssglue/ +PKG_LICENSE = BSD +PKG_SUMMARY = This library exports a gssapi interface. + +define PKG_DESCRIPTION + This library exports a gssapi interface, but doesn't implement any \ + gssapi mechanisms itself; instead it calls gssapi routines in other \ + libraries, depending on the mechanism. +endef + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/libidn/libidn.nm b/pkgs/core/libidn/libidn.nm new file mode 100644 index 0000000..869c811 --- /dev/null +++ b/pkgs/core/libidn/libidn.nm @@ -0,0 +1,65 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libidn +PKG_VER = 0.6.14 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gnu.org/software/libidn/ +PKG_LICENSE = LGPLv2+ GPLv3+ +PKG_SUMMARY = Internationalized Domain Name support library. + +define PKG_DESCRIPTION + GNU Libidn is an implementation of the Stringprep, Punycode and \ + IDNA specifications defined by the IETF Internationalized Domain \ + Names (IDN) working group, used for internationalized domain \ + names. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --libdir=/lib \ + --disable-csharp \ + --disable-static + +define STAGE_TEST + cd $(DIR_APP) && make -C tests check +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) \ + pkgconfigdir=/usr/lib/pkgconfig + + # Make multilib safe: + cd $(DIR_APP) && sed -i '/gnu compiler/d' $(BUILDROOT)/usr/include/idn-int.h + + -mkdir -pv $(BUILDROOT)/usr/lib + rm -vf $(BUILDROOT)/lib/libidn.so + ln -svf ../../lib/libidn.so.11.5.28 $(BUILDROOT)/usr/lib/libidn.so +endef diff --git a/pkgs/core/libjpeg/libjpeg.nm b/pkgs/core/libjpeg/libjpeg.nm new file mode 100644 index 0000000..2644605 --- /dev/null +++ b/pkgs/core/libjpeg/libjpeg.nm @@ -0,0 +1,48 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libjpeg +PKG_VER = 7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.ijg.org +PKG_LICENSE = IJG +PKG_SUMMARY = A library for manipulating JPEG image format files. + +define PKG_DESCRIPTION + The libjpeg package contains a library of functions for manipulating \ + JPEG images, as well as simple client programs for accessing the \ + libjpeg functions. +endef + +PKG_TARBALL = jpegsrc.v$(PKG_VER).tar.gz + +DIR_APP = /usr/src/jpeg-7 + +CONFIGURE_OPTIONS += \ + --enable-shared diff --git a/pkgs/core/libksba/libksba.nm b/pkgs/core/libksba/libksba.nm new file mode 100644 index 0000000..211fec3 --- /dev/null +++ b/pkgs/core/libksba/libksba.nm @@ -0,0 +1,44 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libksba +PKG_VER = 1.0.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gnugp.org +PKG_LICENSE = GPLv3 +PKG_SUMMARY = X.509 Library. + +PKG_DEPS += libgpg-error + +define PKG_DESCRIPTION + KSBA is a library designed to build software based on the X.509 and \ + CMS protocols. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 diff --git a/pkgs/core/libnetfilter_conntrack/libnetfilter_conntrack.nm b/pkgs/core/libnetfilter_conntrack/libnetfilter_conntrack.nm new file mode 100644 index 0000000..1540c44 --- /dev/null +++ b/pkgs/core/libnetfilter_conntrack/libnetfilter_conntrack.nm @@ -0,0 +1,46 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libnetfilter_conntrack +PKG_VER = 0.0.100 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.netfilter.org/projects/libnetfilter_conntrack/downloads.html +PKG_LICENSE = GPL +PKG_SUMMARY = libnetfilter_conntrack is a userspace library. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += libnfnetlink + +define PKG_DESCRIPTION + libnetfilter_conntrack is a library that allows user-space \ + programs to interface the kernel connection tracking table of \ + the netfilter subsystem in the Linux kernel. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 diff --git a/pkgs/core/libnetfilter_log/libnetfilter_log.nm b/pkgs/core/libnetfilter_log/libnetfilter_log.nm new file mode 100644 index 0000000..487bff8 --- /dev/null +++ b/pkgs/core/libnetfilter_log/libnetfilter_log.nm @@ -0,0 +1,47 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libnetfilter_log +PKG_VER = 0.0.16 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.netfilter.org/projects/libnetfilter_log/downloads.html +PKG_LICENSE = GPL +PKG_SUMMARY = The libnetfilter_log userspace library. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += libnfnetlink + +define PKG_DESCRIPTION + libnetfilter_log is a software library to interface with the \ + nfnetlink_log mechanism in Linux 2.6.14 and later. The library \ + enables programs to receive and process packets logged by the \ + Linux packet filter (iptables). +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 diff --git a/pkgs/core/libnetfilter_queue/libnetfilter_queue.nm b/pkgs/core/libnetfilter_queue/libnetfilter_queue.nm new file mode 100644 index 0000000..c0910fc --- /dev/null +++ b/pkgs/core/libnetfilter_queue/libnetfilter_queue.nm @@ -0,0 +1,47 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libnetfilter_queue +PKG_VER = 0.0.17 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.netfilter.org/projects/libnetfilter_queue/downloads.html +PKG_LICENSE = GPL +PKG_SUMMARY = The libnetfilter_queue userspace library. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += libnfnetlink + +define PKG_DESCRIPTION + libnetfilter_queue is a userspace library that provides an API \ + for manipulating packets that have been queued by the kernel \ + packet filter. It is is part of a system that deprecates the old \ + ip_queue/libipq mechanism. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 diff --git a/pkgs/core/libnfnetlink/libnfnetlink.nm b/pkgs/core/libnfnetlink/libnfnetlink.nm new file mode 100644 index 0000000..e306e5e --- /dev/null +++ b/pkgs/core/libnfnetlink/libnfnetlink.nm @@ -0,0 +1,45 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libnfnetlink +PKG_VER = 1.0.0 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.netfilter.org/projects/libnfnetlink/downloads.html +PKG_LICENSE = GPL +PKG_SUMMARY = A low-level library for netfilter. + +define PKG_DESCRIPTION + libnfnetlink is a low-level userspace library for \ + nfnetlink-based communication between the kernel-side netfilter \ + and the user-space world. It is therefore the fundamental layer \ + for all other nfnetlink-enabled user-space programs interfacing \ + with the netfilter subsystem of the Linux kernel. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 diff --git a/pkgs/core/libnfsidmap/libnfsidmap.nm b/pkgs/core/libnfsidmap/libnfsidmap.nm new file mode 100644 index 0000000..c587734 --- /dev/null +++ b/pkgs/core/libnfsidmap/libnfsidmap.nm @@ -0,0 +1,62 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libnfsidmap +PKG_VER = 0.21 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.citi.umich.edu/projects/nfsv4/linux/libnfsidmap/ +PKG_LICENSE = BSD +PKG_SUMMARY = Library to help mapping id's, mainly for NFSv4. + +define PKG_DESCRIPTION + libnfsidmap provides functions to map between NFSv4 names \ + (which are of the form user@domain) and local uid's and gid's. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --libdir=/lib + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/usr/lib + + mv -v $(BUILDROOT)/lib/pkgconfig $(BUILDROOT)/usr/lib/ + + rm -vf $(BUILDROOT)/lib/libnfsidmap.so + ln -svf ../../lib/libnfsidmap.so.0 \ + $(BUILDROOT)/usr/lib/libnfsidmap.so + + rm -vf $(BUILDROOT)/lib/libnfsidmap_nsswitch.so + ln -svf ../../lib/libnfsidmap_nsswitch.so.0 \ + $(BUILDROOT)/usr/lib/libnfsidmap_nsswitch.so + + rm -vf $(BUILDROOT)/lib/libnfsidmap_static.so + ln -svf ../../lib/libnfsidmap_static.so.0 \ + $(BUILDROOT)/usr/lib/libnfsidmap_static.so +endef diff --git a/pkgs/core/libnih/libnih.nm b/pkgs/core/libnih/libnih.nm new file mode 100644 index 0000000..64d3cf7 --- /dev/null +++ b/pkgs/core/libnih/libnih.nm @@ -0,0 +1,55 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libnih +PKG_VER = 1.0.1 +PKG_REL = 0 + +PKG_MAINTAINER = Stefan Schantl <stefan.schantl@ipfire.org> +PKG_GROUP = System/Base +PKG_URL = https://launchpad.net/libnih +PKG_LICENSE = GPL2+ +PKG_SUMMARY = Small library with advanced functions. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += dbus + +define PKG_DESCRIPTION + libnih is a small library for C application development containing \ + functions that, despite its name, are not implemented elsewhere in the \ + standard library set. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --libdir=/lib + +define STAGE_INSTALL_CMDS + rm -vf $(BUILDROOT)/lib/libnih{,-dbus}.so + ln -svf ../../lib/libnih.so.1 $(BUILDROOT)/usr/lib/libnih.so + ln -svf ../../lib/libnih-dbus.so.1 $(BUILDROOT)/usr/lib/libnih-dbus.so +endef diff --git a/pkgs/core/libnl/libnl.nm b/pkgs/core/libnl/libnl.nm new file mode 100644 index 0000000..46c2da7 --- /dev/null +++ b/pkgs/core/libnl/libnl.nm @@ -0,0 +1,52 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libnl +PKG_VER = 1.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Libraries +PKG_URL = http://people.suug.ch/~tgr/libnl/ +PKG_LICENSE = LGPLv2 +PKG_SUMMARY = Convenience library for kernel netlink sockets. + +define PKG_DESCRIPTION + This package contains a convenience library to simplify using the \ + Linux kernel's netlink sockets interface for network manipulation. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --libdir=/lib + +define STAGE_INSTALL_CMDS + rm -vf $(BUILDROOT)/lib/libnl.so + -mkdir -pv $(BUILDROOT)/usr/lib + ln -svf ../../lib/libnl.so.1 $(BUILDROOT)/usr/lib/libnl.so + + mv -v $(BUILDROOT)/lib/pkgconfig $(BUILDROOT)/usr/lib/pkgconfig +endef diff --git a/pkgs/core/libnl/patches/libnl-1.1-include-limits-h.patch b/pkgs/core/libnl/patches/libnl-1.1-include-limits-h.patch new file mode 100644 index 0000000..3bead16 --- /dev/null +++ b/pkgs/core/libnl/patches/libnl-1.1-include-limits-h.patch @@ -0,0 +1,11 @@ +diff -up libnl-1.1/include/netlink-local.h.limits libnl-1.1/include/netlink-local.h +--- libnl-1.1/include/netlink-local.h.limits 2008-02-22 11:31:18.000000000 -0500 ++++ libnl-1.1/include/netlink-local.h 2008-02-22 11:32:57.000000000 -0500 +@@ -22,6 +22,7 @@ + #include <time.h> + #include <stdarg.h> + #include <ctype.h> ++#include <limits.h> + #include <sys/types.h> + #include <sys/socket.h> + #include <inttypes.h> diff --git a/pkgs/core/libnl/patches/libnl-1.1-no-extern-inline.patch b/pkgs/core/libnl/patches/libnl-1.1-no-extern-inline.patch new file mode 100644 index 0000000..16a4f8f --- /dev/null +++ b/pkgs/core/libnl/patches/libnl-1.1-no-extern-inline.patch @@ -0,0 +1,57 @@ +From 84fefcadcde5d6c343db7f5c1744f6b1f070bc71 Mon Sep 17 00:00:00 2001 +From: Peter Jones <pjones@redhat.com> +Date: Thu, 14 May 2009 11:30:40 -0400 +Subject: [PATCH] Remove "inline" keyword from nl_object_priv(). + +"extern inline foo();" in a header file generates a compiler warning in +consumers of the library. Also, it doesn't make any sense whatsoever. +For this reason, and the fact that this function is not used at all in +the file in which it's defined, I have removed the "inline" keyword. +--- + doc/Doxyfile.in | 2 +- + include/netlink/object.h | 2 +- + lib/object.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in +index 0c518b7..396fcbc 100644 +--- a/doc/Doxyfile.in ++++ b/doc/Doxyfile.in +@@ -113,7 +113,7 @@ FULL_PATH_NAMES = YES + # If left blank the directory from which doxygen is run is used as the + # path to strip. + +-STRIP_FROM_PATH = ++STRIP_FROM_PATH = /home/pjones/build/BUILD/libnl-1.1 + + # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of + # the path mentioned in the documentation of a class, which tells +diff --git a/include/netlink/object.h b/include/netlink/object.h +index 751a1b3..241a2ad 100644 +--- a/include/netlink/object.h ++++ b/include/netlink/object.h +@@ -55,7 +55,7 @@ extern int nl_object_is_marked(struct nl_object *); + /* Access Functions */ + extern int nl_object_get_refcnt(struct nl_object *); + extern struct nl_cache * nl_object_get_cache(struct nl_object *); +-extern inline void * nl_object_priv(struct nl_object *); ++extern void * nl_object_priv(struct nl_object *); + + #ifdef __cplusplus + } +diff --git a/lib/object.c b/lib/object.c +index 74f6e2d..845ca1d 100644 +--- a/lib/object.c ++++ b/lib/object.c +@@ -376,7 +376,7 @@ struct nl_cache *nl_object_get_cache(struct nl_object *obj) + return obj->ce_cache; + } + +-inline void *nl_object_priv(struct nl_object *obj) ++void *nl_object_priv(struct nl_object *obj) + { + return obj; + } +-- +1.6.2.2 + diff --git a/pkgs/core/libnl/patches/libnl-1.1-permissions.patch b/pkgs/core/libnl/patches/libnl-1.1-permissions.patch new file mode 100644 index 0000000..916ec9a --- /dev/null +++ b/pkgs/core/libnl/patches/libnl-1.1-permissions.patch @@ -0,0 +1,13 @@ +--- libnl-1.0-pre5/lib/Makefile.debuginfo 2006-06-15 18:11:21.000000000 -0400 ++++ libnl-1.0-pre5/lib/Makefile 2006-06-15 18:11:28.000000000 -0400 +@@ -64,7 +64,7 @@ + + install: + mkdir -p $(DESTDIR)$(libdir)/ +- install -m 0644 $(OUT_SLIB) $(DESTDIR)$(libdir) ++ install -m 0755 $(OUT_SLIB) $(DESTDIR)$(libdir) + rm -f $(DESTDIR)$(libdir)/$(LN1_SLIB) + $(LN) -s $(OUT_SLIB) $(DESTDIR)$(libdir)/$(LN1_SLIB) + rm -f $(DESTDIR)$(libdir)/$(LN_SLIB) + $(LN) -s $(LN1_SLIB) $(DESTDIR)$(libdir)/$(LN_SLIB) + diff --git a/pkgs/core/libpcap/libpcap.nm b/pkgs/core/libpcap/libpcap.nm new file mode 100644 index 0000000..89549c9 --- /dev/null +++ b/pkgs/core/libpcap/libpcap.nm @@ -0,0 +1,56 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libpcap +PKG_VER = 1.0.0 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.tcpdump.org/ +PKG_LICENSE = BSD with advertising +PKG_SUMMARY = A system-independent interface for user-level packet capture. + +PKG_BUILD_DEPS+= bison flex + +define PKG_DESCRIPTION + Libpcap provides a portable framework for low-level network \ + monitoring. Libpcap can provide network statistics collection, \ + security monitoring and network debugging. Since almost every \ + system vendor provides a different interface for packet capture, \ + the libpcap authors created this system-independent API to ease in \ + porting and to alleviate the need for several system-dependent \ + packet capture modules in each application. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/usr/bin + cd $(DIR_APP) && make install install-shared-so DESTDIR=$(BUILDROOT) + ln -svf libpcap.so.1.0.0 $(BUILDROOT)/usr/lib/libpcap.so.1 + ln -svf libpcap.so.1 $(BUILDROOT)/usr/lib/libpcap.so +endef diff --git a/pkgs/core/libpng/libpng.nm b/pkgs/core/libpng/libpng.nm new file mode 100644 index 0000000..93d222a --- /dev/null +++ b/pkgs/core/libpng/libpng.nm @@ -0,0 +1,48 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libpng +PKG_VER = 1.2.39 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.libpng.org/pub/png/ +PKG_LICENSE = zlib +PKG_SUMMARY = A library of functions for manipulating PNG image format files. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += zlib + +define PKG_DESCRIPTION + The libpng package contains a library of functions for creating and \ + manipulating PNG (Portable Network Graphics) image format files. \ + PNG is a bit-mapped graphics format similar to the GIF format. PNG \ + was created to replace the GIF format, since GIF uses a patented \ + data compression algorithm. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 diff --git a/pkgs/core/libpng/patches/libpng-1.2.39-pngconf.patch b/pkgs/core/libpng/patches/libpng-1.2.39-pngconf.patch new file mode 100644 index 0000000..dbaadcb --- /dev/null +++ b/pkgs/core/libpng/patches/libpng-1.2.39-pngconf.patch @@ -0,0 +1,42 @@ +diff -Naur libpng-1.2.29.orig/configure.ac libpng-1.2.29/configure.ac +--- libpng-1.2.29.orig/configure.ac 2008-05-08 07:58:11.000000000 -0400 ++++ libpng-1.2.29/configure.ac 2008-05-31 20:21:12.000000000 -0400 +@@ -63,7 +63,8 @@ + AC_MSG_CHECKING( + [if assembler code in pnggccrd.c can be compiled without PNG_NO_MMX_CODE]) + AC_TRY_COMPILE( +- [#include "$srcdir/pnggccrd.c"], ++ [#define PNG_CONFIGURE_LIBPNG ++ #include "$srcdir/pnggccrd.c"], + [return 0;], + AC_MSG_RESULT(yes) + LIBPNG_NO_MMX="", +diff -Naur libpng-1.2.29.orig/pngconf.h libpng-1.2.29/pngconf.h +--- libpng-1.2.29.orig/pngconf.h 2008-05-08 07:58:03.000000000 -0400 ++++ libpng-1.2.29/pngconf.h 2008-05-31 20:21:12.000000000 -0400 +@@ -35,6 +35,25 @@ + #ifdef HAVE_CONFIG_H + #include "config.h" + #endif ++#else ++/* pngconf.h is part of the exported API. When a libpng-using application ++ includes us, PNG_CONFIGURE_LIBPNG is of course not defined as we do not have ++ libpng's config.h available in this case. This means that we do not have the ++ defines added to config.h and the commandline by libpng's ./configure . ++ ++ For all defines from config.h not having them set is not a problem, however ++ ./configure also adds -DPNG_NO_ASSEMBLER_CODE to the CFLAGS when compiling ++ on a platform on which the MMX and SSE asm code in libpng is not supported. ++ ++ We do need this define as this define is used to determine whether or not ++ to define PNG_ASSEMBLER_CODE_SUPPORTED and other assembler related defines ++ and prototypes. PNG_ASSEMBLER_CODE_SUPPORTED in turn is used by applications ++ (ImageMagick for example) to determine whether or not they can use the asm ++ functions. Thus we need to define PNG_NO_ASSEMBLER_CODE here on platforms ++ on which the MMX and SSE asm code in libpng is not supported: */ ++#ifndef __i386__ /* change this if MMX/SSE become supported on x86_64! */ ++#define PNG_NO_ASSEMBLER_CODE ++#endif + #endif + + /* diff --git a/pkgs/core/librpcsecgss/librpcsecgss.nm b/pkgs/core/librpcsecgss/librpcsecgss.nm new file mode 100644 index 0000000..5a3eddf --- /dev/null +++ b/pkgs/core/librpcsecgss/librpcsecgss.nm @@ -0,0 +1,47 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = librpcsecgss +PKG_VER = 0.18 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.citi.umich.edu/projects/nfsv4/linux/librpcsecgss/ +PKG_LICENSE = BSD +PKG_SUMMARY = A Library for secure rpc communication. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += libgssglue + +define PKG_DESCRIPTION + rpcsecgss allows secure rpc communication using the rpcsec_gss \ + protocol. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CFLAGS += -fPIC diff --git a/pkgs/core/libsoup/libsoup.nm b/pkgs/core/libsoup/libsoup.nm new file mode 100644 index 0000000..015cdc3 --- /dev/null +++ b/pkgs/core/libsoup/libsoup.nm @@ -0,0 +1,49 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libsoup +PKG_VER = 2.29.91 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://ftp.gnome.org/pub/gnome/sources/libsoup/ +PKG_LICENSE = GPL +PKG_SUMMARY = HTTP client/server library for GNOME. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += glib2 libxml2 openssl + +define PKG_DESCRIPTION + libsoup is an HTTP client/server library for GNOME. It uses GObjects \ + and the glib main loop, to integrate well with GNOME applications, \ + and also has a synchronous API, for use in threaded applications. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --without-gnome diff --git a/pkgs/core/libssh2/libssh2.nm b/pkgs/core/libssh2/libssh2.nm new file mode 100644 index 0000000..03edc25 --- /dev/null +++ b/pkgs/core/libssh2/libssh2.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libssh2 +PKG_VER = 1.2.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.libssh2.org/ +PKG_LICENSE = BSD +PKG_SUMMARY = A library implementing the SSH2 protocol. + +PKG_DEPS += openssl zlib + +define PKG_DESCRIPTION + libssh2 is a library implementing the SSH2 protocol as defined by \ + Internet Drafts: SECSH-TRANS(22), SECSH-USERAUTH(25), \ + SECSH-CONNECTION(23), SECSH-ARCH(20), SECSH-FILEXFER(06)*, \ + SECSH-DHGEX(04), and SECSH-NUMBERS(10). +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +CONFIGURE_OPTIONS += \ + --disable-static + +define STAGE_TEST + cd $(DIR_APP) && make check +endef diff --git a/pkgs/core/libtiff/libtiff.nm b/pkgs/core/libtiff/libtiff.nm new file mode 100644 index 0000000..3e74dc6 --- /dev/null +++ b/pkgs/core/libtiff/libtiff.nm @@ -0,0 +1,48 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libtiff +PKG_VER = 3.9.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.libtiff.org +PKG_LICENSE = libtiff ( own ) +PKG_SUMMARY = Library of functions for manipulating TIFF format image files. + +PKG_BUILD_DEPS+= libjpeg + +define PKG_DESCRIPTION + The libtiff package contains a library of functions for manipulating \ + TIFF (Tagged Image File Format) image format files. TIFF is a widely \ + used file format for bitmapped images. TIFF files usually end in the \ + .tif extension and they are often quite large. +endef + +PKG_TARBALL = tiff-$(PKG_VER).tar.gz + +DIR_APP = /usr/src/tiff-$(PKG_VER) diff --git a/pkgs/core/libtool/libtool.nm b/pkgs/core/libtool/libtool.nm new file mode 100644 index 0000000..9718b3a --- /dev/null +++ b/pkgs/core/libtool/libtool.nm @@ -0,0 +1,44 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libtool +PKG_VER = 2.2.6b +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gnu.org/software/libtool/ +PKG_LICENSE = GPLv2+ and LGPLv2+ and GFDL +PKG_SUMMARY = Runtime libraries for GNU Libtool Dynamic Module Loader. + +define PKG_DESCRIPTION + GNU Libtool is a set of shell scripts which automatically \ + configure UNIX and UNIX-like systems to generically build \ + shared libraries. Libtool provides a consistent, portable \ + interface which simplifies the process of using shared libraries. +endef + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/libusb-compat/libusb-compat.nm b/pkgs/core/libusb-compat/libusb-compat.nm new file mode 100644 index 0000000..8efa34c --- /dev/null +++ b/pkgs/core/libusb-compat/libusb-compat.nm @@ -0,0 +1,47 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libusb +PKG_VER = 0.1.12 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://sourceforge.net/projects/libusb/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = A library which allows userspace access to USB devices. + +PKG_BUILD_DEPS+= pkg-config + +define PKG_DESCRIPTION + This package provides a way for applications to access USB devices. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --disable-build-docs \ + --disable-static diff --git a/pkgs/core/libusb/libusb.nm b/pkgs/core/libusb/libusb.nm new file mode 100644 index 0000000..3bf8601 --- /dev/null +++ b/pkgs/core/libusb/libusb.nm @@ -0,0 +1,43 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libusb +PKG_VER = 1.0.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://sourceforge.net/projects/libusb/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = A library which allows userspace access to USB devices. + +define PKG_DESCRIPTION + This package provides a way for applications to access USB devices. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += --disable-static diff --git a/pkgs/core/libuser/libuser.nm b/pkgs/core/libuser/libuser.nm new file mode 100644 index 0000000..2b0aaa8 --- /dev/null +++ b/pkgs/core/libuser/libuser.nm @@ -0,0 +1,55 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libuser +PKG_VER = 0.56.9 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = https://fedorahosted.org/libuser/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = A user and group account administration library. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += glib2 openldap popt python + +define PKG_DESCRIPTION + The libuser library implements a standardized interface for \ + manipulating and administering user and group accounts. The \ + library uses pluggable back-ends to interface to its data sources. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc \ + --with-ldap + +define STAGE_PREPARE_CMDS + # Little hack that we don't build documentation that requires sgml2html + cd $(DIR_APP) && sed -e "s/^SUBDIRS = .*/SUBDIRS = po/" -i Makefile.in +endef diff --git a/pkgs/core/libvirt/libvirt.nm b/pkgs/core/libvirt/libvirt.nm new file mode 100644 index 0000000..960a2e2 --- /dev/null +++ b/pkgs/core/libvirt/libvirt.nm @@ -0,0 +1,49 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libvirt +PKG_VER = 0.7.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Virtualization +PKG_URL = http://www.libvirt.org/ +PKG_LICENSE = LGPLv2.1+ +PKG_SUMMARY = A library for controlling VMs. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += avahi curl cyrus-sasl gnutls libssh2 libxml2 lvm2 readline + +define PKG_DESCRIPTION + A toolkit to interact with the virtualization capabilities of recent \ + versions of Linux. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --with-qemu \ + --without-xen diff --git a/pkgs/core/libxml2/libxml2.nm b/pkgs/core/libxml2/libxml2.nm new file mode 100644 index 0000000..9d58d1f --- /dev/null +++ b/pkgs/core/libxml2/libxml2.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = libxml2 +PKG_VER = 2.7.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://xmlsoft.org/ +PKG_LICENSE = MIT +PKG_SUMMARY = Library providing XML and HTML support. + +PKG_DEPS += zlib + +define PKG_DESCRIPTION + This library allows to manipulate XML files. It includes support \ + to read, modify and write XML and HTML files. There is DTDs support \ + this includes parsing and validation even with complex DtDs, either \ + at parse time or later once the document has been modified. The output \ + can be a simple SAX stream or and in-memory DOM like representations. \ + In this case one can use the built-in XPath and XPointer implementation \ + to select subnodes or ranges. A flexible Input/Output mechanism is \ + available, with existing HTTP and FTP modules and combined to an URI \ + library. +endef + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/lighttpd/lighttpd.conf b/pkgs/core/lighttpd/lighttpd.conf new file mode 100644 index 0000000..15dc849 --- /dev/null +++ b/pkgs/core/lighttpd/lighttpd.conf @@ -0,0 +1,123 @@ +############################################################################ +# # +# This file is part of the IPFire Firewall. # +# # +# IPFire is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# IPFire is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2008 IPFire-Team <info@ipfire.org>. # +# # +############################################################################ + +server.document-root = "/srv/www/ipfire/" + +server.port = 444 + +server.username = "www" +server.groupname = "www" + +server.event-handler = "linux-sysepoll" +server.network-backend = "linux-sendfile" + +accesslog.filename = "/var/log/lighttpd/access.log" +server.errorlog = "/var/log/lighttpd/error.log" +static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" ) +server.pid-file = "/var/run/lighttpd.pid" +#server.bind = "127.0.0.1" + +index-file.names = ( + "index.html", + "index.htm", + "index.py", + "index.cgi" +) + +compress.cache-dir = "/var/cache/lighttpd/compress/" +compress.filetype = ("text/plain", "text/html") + +### SSL engine +#ssl.engine = "enable" +#ssl.pemfile = "/etc/ssl/private/server.pem" + +#auth.backend.ldap.hostnam = "localhost" +#auth.backend.ldap.base-dn = "dc=my-domain,dc=com" +#auth.backend.ldap.filter = "(uid=$)" +#auth.require = ( +# "/server-status" => +# ( +# "method" => "digest", +# "realm" => "download archiv", +# "require" => "user=jan" +# ), +# "/server-config" => +# ( +# "method" => "digest", +# "realm" => "download archiv", +# "require" => "valid-user" +# ) +#) + +server.modules = ( +# "mod_rewrite", +# "mod_redirect", +# "mod_alias", + "mod_access", +# "mod_cml", +# "mod_trigger_b4_dl", + "mod_auth", +# "mod_status", +# "mod_setenv", + "mod_fastcgi", +# "mod_proxy", +# "mod_simple_vhost", +# "mod_evhost", +# "mod_userdir", + "mod_cgi", + "mod_compress", +# "mod_ssi", +# "mod_usertrack", +# "mod_expire", +# "mod_secdownload", +# "mod_rrdtool", + "mod_accesslog" +) + +cgi.assign = ( + ".py" => "/usr/bin/python", + ".cgi" => "/usr/bin/python", +) + +mimetype.assign = ( + ".gz" => "application/x-gzip", + ".tar.gz" => "application/x-tgz", + ".tgz" => "application/x-tgz", + ".tar" => "application/x-tar", + ".zip" => "application/zip", + ".gif" => "image/gif", + ".jpg" => "image/jpeg", + ".jpeg" => "image/jpeg", + ".png" => "image/png", + ".css" => "text/css", + ".html" => "text/html", + ".htm" => "text/html", + ".js" => "text/javascript", + ".log" => "text/plain", + ".conf" => "text/plain", + ".text" => "text/plain", + ".txt" => "text/plain", + ".xml" => "text/xml", + ".bz2" => "application/x-bzip", + ".tbz" => "application/x-bzip-compressed-tar", + ".tar.bz2" => "application/x-bzip-compressed-tar" +) diff --git a/pkgs/core/lighttpd/lighttpd.init b/pkgs/core/lighttpd/lighttpd.init new file mode 100644 index 0000000..639d6e5 --- /dev/null +++ b/pkgs/core/lighttpd/lighttpd.init @@ -0,0 +1,8 @@ +description "Start lighttpd" +author "IPFire Team" + +start on started network +stop on stopping network + +exec /usr/sbin/lighttpd -f /etc/lighttpd.conf +expect daemon diff --git a/pkgs/core/lighttpd/lighttpd.nm b/pkgs/core/lighttpd/lighttpd.nm new file mode 100644 index 0000000..f533ef4 --- /dev/null +++ b/pkgs/core/lighttpd/lighttpd.nm @@ -0,0 +1,65 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = lighttpd +PKG_VER = 1.4.23 +PKG_REL = 0 + +PKG_MAINTAINER = Michael Tremer <michael.tremer@ipfire.org> +PKG_GROUP = Networking/Webservers +PKG_URL = http://www.lighttpd.net/ +PKG_LICENSE = BSD +PKG_SUMMARY = Lightning fast webserver with light system requirements. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += bzip2 gdbm openldap openssl pcre zlib + +define PKG_DESCRIPTION + Secure, fast, compliant and very flexible web-server which has been optimized \ + for high-performance environments. It has a very low memory footprint compared \ + to other webservers and takes care of cpu-load. Its advanced feature-set \ + (FastCGI, CGI, Auth, Output-Compression, URL-Rewriting and many more) make \ + it the perfect webserver-software for every server that is suffering load \ + problems. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --libdir=/usr/lib/$(PKG_NAME) \ + --with-ldap \ + --with-openssl + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/etc + cp -vf $(DIR_SOURCE)/$(PKG_NAME).conf $(BUILDROOT)/etc/$(PKG_NAME).conf + + -mkdir -pv $(BUILDROOT)/var/log/$(PKG_NAME) + touch $(BUILDROOT)/var/log/$(PKG_NAME)/{access,error}.log + chown nobody.nobody -R $(BUILDROOT)/var/log/$(PKG_NAME) + -mkdir -pv $(BUILDROOT)/var/cache/lighttpd/compress + chown nobody.nobody -Rv $(BUILDROOT)/var/cache/lighttpd/ +endef diff --git a/pkgs/core/linux-atm/linux-atm.nm b/pkgs/core/linux-atm/linux-atm.nm new file mode 100644 index 0000000..d0a6cfa --- /dev/null +++ b/pkgs/core/linux-atm/linux-atm.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = linux-atm +PKG_VER = 2.4.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Daemons +PKG_URL = http://linux-atm.sourceforge.net/ +PKG_LICENSE = BSD and GPLv2 and GPLv2+ and LGPLv2+ and MIT +PKG_SUMMARY = Tools to support ATM networking under Linux. + +PKG_BUILD_DEPS+= flex + +define PKG_DESCRIPTION + This package contains header files and libraries for development \ + using theLinux ATM API. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc \ + --mandir=/usr/share/man + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -e "s/-lfl/&_pic/g" -i src/*{,/*}/Makefile.in +endef + +# Fails +#define STAGE_TEST +# cd $(DIR_APP) && make check +#endef diff --git a/pkgs/core/linux-atm/patches/linux-atm-2.4.1-gcc-4.patch b/pkgs/core/linux-atm/patches/linux-atm-2.4.1-gcc-4.patch new file mode 100644 index 0000000..f6be9d2 --- /dev/null +++ b/pkgs/core/linux-atm/patches/linux-atm-2.4.1-gcc-4.patch @@ -0,0 +1,161 @@ +diff -Naur linux-atm-2.4.1-orig/src/ilmid/atmf_uni.c linux-atm-2.4.1/src/ilmid/atmf_uni.c +--- linux-atm-2.4.1-orig/src/ilmid/atmf_uni.c 2001-09-03 19:41:06.000000000 +0100 ++++ linux-atm-2.4.1/src/ilmid/atmf_uni.c 2005-08-13 10:22:44.000000000 +0100 +@@ -187,7 +187,7 @@ + newPrefix->name = alloc_t(AsnOid); + newPrefix->name->octs = alloc(varBindName->octetLen); + AsnOidCopy(newPrefix->name, varBindName); +- Q_INSERT_BEFORE((NetPrefixNode *) var->value, newPrefix, prefix); ++ Q_INSERT_BEFORE((*((NetPrefixNode **)&var->value)), newPrefix, prefix); + if(atmNetPrefix.octs == NULL) + { + atmNetPrefix.octetLen = varBindName->octetLen - NETPREFIX_LEN - 2; +@@ -197,7 +197,7 @@ + } + else if (varbind->value->a.simple->a.number == INVALID && cmp == AsnOidEqual) + { +- Q_REMOVE((NetPrefixNode *) var->value, prefix); ++ Q_REMOVE((*((NetPrefixNode **) &var->value)), prefix); + } + + return NOERROR; +diff -Naur linux-atm-2.4.1-orig/src/lib/sapequal.c linux-atm-2.4.1/src/lib/sapequal.c +--- linux-atm-2.4.1-orig/src/lib/sapequal.c 2001-09-03 19:41:05.000000000 +0100 ++++ linux-atm-2.4.1/src/lib/sapequal.c 2005-02-06 19:24:37.000000000 +0000 +@@ -65,6 +65,7 @@ + CHECK(l2.itu.window,a.l2.itu.window > b.l2.itu.window); + break; + default: ++ ; + } + switch (a.l3_proto) { + case ATM_L3_X25: +@@ -83,6 +84,7 @@ + if (a.l3.user != b.l3.user) return 0; + break; + default: ++ ; + } + return 1; + } +diff -Naur linux-atm-2.4.1-orig/src/maint/atmtcp.c linux-atm-2.4.1/src/maint/atmtcp.c +--- linux-atm-2.4.1-orig/src/maint/atmtcp.c 2001-09-03 19:41:06.000000000 +0100 ++++ linux-atm-2.4.1/src/maint/atmtcp.c 2005-08-13 10:22:44.000000000 +0100 +@@ -60,7 +60,7 @@ + static IN *inputs = NULL; + static fd_set in_set; + static int fds = 0; +-static int debug = 0; ++int debug = 0; + static int links = 0; + + +diff -Naur linux-atm-2.4.1-orig/src/maint/enitune.c linux-atm-2.4.1/src/maint/enitune.c +--- linux-atm-2.4.1-orig/src/maint/enitune.c 2001-09-03 19:41:06.000000000 +0100 ++++ linux-atm-2.4.1/src/maint/enitune.c 2005-02-06 19:24:37.000000000 +0000 +@@ -44,6 +44,7 @@ + if (*end || mult.rx <= 100) usage(name); + break; + default: ++ ; + } + if (argc != optind+1) usage(name); + sioc.number = strtol(argv[optind],&end,0); +diff -Naur linux-atm-2.4.1-orig/src/mpoad/p_factory.c linux-atm-2.4.1/src/mpoad/p_factory.c +--- linux-atm-2.4.1-orig/src/mpoad/p_factory.c 2001-09-03 19:41:06.000000000 +0100 ++++ linux-atm-2.4.1/src/mpoad/p_factory.c 2005-08-13 10:22:44.000000000 +0100 +@@ -31,16 +31,17 @@ + * beginning at location "addr". + */ + uint32_t sum = 0; ++ uint16_t *addr16 = addr; + + while( count > 1 ) { + /* This is the inner loop */ +- sum += * ((uint16_t *) addr)++; ++ sum += * addr16++; + count -= 2; + } + + /* Add left-over byte, if any */ + if( count > 0 ) +- sum += * (unsigned char *) addr; ++ sum += * (unsigned char *) addr16; + + /* Fold 32-bit sum to 16 bits */ + while (sum>>16) +diff -Naur linux-atm-2.4.1-orig/src/qgen/qlib.c linux-atm-2.4.1/src/qgen/qlib.c +--- linux-atm-2.4.1-orig/src/qgen/qlib.c 2001-09-03 19:41:05.000000000 +0100 ++++ linux-atm-2.4.1/src/qgen/qlib.c 2005-08-13 10:22:44.000000000 +0100 +@@ -26,8 +26,6 @@ + #include "op.h" + + +-static int debug = 0; +- + + void PREFIX(report)(int severity,const char *msg,...) + { +@@ -830,6 +828,8 @@ + + #ifdef STANDALONE + ++int debug = 0; ++ + int main(int argc,const char **argv) + { + unsigned char msg[5000]; /* should be large enough for that */ +diff -Naur linux-atm-2.4.1-orig/src/qgen/qlib.h linux-atm-2.4.1/src/qgen/qlib.h +--- linux-atm-2.4.1-orig/src/qgen/qlib.h 2001-09-03 19:41:05.000000000 +0100 ++++ linux-atm-2.4.1/src/qgen/qlib.h 2005-08-13 10:22:44.000000000 +0100 +@@ -23,7 +23,6 @@ + #define Q_FATAL -1 + + +-extern int q_dump; + extern void q_report(int severity,const char *msg,...); + + #ifdef DUMP_MODE +diff -Naur linux-atm-2.4.1-orig/src/sigd/proto.c linux-atm-2.4.1/src/sigd/proto.c +--- linux-atm-2.4.1-orig/src/sigd/proto.c 2001-09-03 19:41:06.000000000 +0100 ++++ linux-atm-2.4.1/src/sigd/proto.c 2005-02-06 19:24:37.000000000 +0000 +@@ -259,6 +259,7 @@ + break; + } + default: ++ ; + } + va_end(ap); + if ((size = q_close(&dsc)) >= 0) to_signaling(sock->sig,q_buffer,size); +@@ -288,6 +289,7 @@ + } + break; + default: ++ ; + } + va_end(ap); + } +diff -Naur linux-atm-2.4.1-orig/src/switch/debug/debug.c linux-atm-2.4.1/src/switch/debug/debug.c +--- linux-atm-2.4.1-orig/src/switch/debug/debug.c 2001-09-03 19:41:06.000000000 +0100 ++++ linux-atm-2.4.1/src/switch/debug/debug.c 2005-08-13 10:22:44.000000000 +0100 +@@ -18,7 +18,7 @@ + #define COMPONENT "FAB(debug)" + + +-#define PRV(call) ((FAB *) (call)->fab) ++#define PRV(call) (*((FAB **) &(call)->fab)) + + + typedef struct _fab { +diff -Naur linux-atm-2.4.1-orig/src/switch/tcp/tcpsw.c linux-atm-2.4.1/src/switch/tcp/tcpsw.c +--- linux-atm-2.4.1-orig/src/switch/tcp/tcpsw.c 2001-09-03 19:41:06.000000000 +0100 ++++ linux-atm-2.4.1/src/switch/tcp/tcpsw.c 2005-08-13 10:22:44.000000000 +0100 +@@ -27,7 +27,7 @@ + + #define COMPONENT "FAB(tcp)" + +-#define PRV(call) ((FAB *) (call)->fab) ++#define PRV(call) (*((FAB **) &(call)->fab)) + + #define MAX_VCI 1024 + diff --git a/pkgs/core/linux-atm/patches/linux-atm-2.4.1-nmu.patch b/pkgs/core/linux-atm/patches/linux-atm-2.4.1-nmu.patch new file mode 100644 index 0000000..ebf0a68 --- /dev/null +++ b/pkgs/core/linux-atm/patches/linux-atm-2.4.1-nmu.patch @@ -0,0 +1,98 @@ +--- linux-atm-2.4.1~/src/arpd/arp.c 2001-09-03 20:41:05.000000000 +0200 ++++ linux-atm-2.4.1/src/arpd/arp.c 2007-07-19 01:38:37.000000000 +0200 +@@ -16,6 +16,7 @@ + #include <sys/socket.h> /* for linux/if_arp.h */ + #include <netinet/in.h> /* for ntohs, etc. */ + #define _LINUX_NETDEVICE_H /* very crude hack for glibc2 */ ++#include <linux/types.h> + #include <linux/if_arp.h> + #include <linux/if_ether.h> + #include <atm.h> +diff -urNad linux-atm-2.4.1~/src/arpd/io.c linux-atm-2.4.1/src/arpd/io.c +--- linux-atm-2.4.1~/src/arpd/io.c 2001-09-03 20:41:05.000000000 +0200 ++++ linux-atm-2.4.1/src/arpd/io.c 2007-07-19 01:38:37.000000000 +0200 +@@ -19,6 +19,7 @@ + #include <net/if.h> + #include <netinet/in.h> + #include <atm.h> ++#include <linux/types.h> + #include <linux/atmclip.h> /* for CLIP_DEFAULT_IDLETIMER */ + #include <linux/atmarp.h> + #define _LINUX_NETDEVICE_H /* glibc2 */ +diff -urNad linux-atm-2.4.1~/src/arpd/itf.c linux-atm-2.4.1/src/arpd/itf.c +--- linux-atm-2.4.1~/src/arpd/itf.c 2001-09-03 20:41:05.000000000 +0200 ++++ linux-atm-2.4.1/src/arpd/itf.c 2007-07-19 01:38:37.000000000 +0200 +@@ -10,6 +10,7 @@ + #include <stdint.h> + #include <string.h> + #include <sys/types.h> ++#include <linux/types.h> + #include <linux/atmclip.h> + #include <sys/socket.h> + #define _LINUX_NETDEVICE_H /* glibc2 */ +diff -urNad linux-atm-2.4.1~/src/mpoad/io.c linux-atm-2.4.1/src/mpoad/io.c +--- linux-atm-2.4.1~/src/mpoad/io.c 2001-09-03 20:41:06.000000000 +0200 ++++ linux-atm-2.4.1/src/mpoad/io.c 2007-07-19 01:38:37.000000000 +0200 +@@ -19,6 +19,7 @@ + _syscall3(int,poll,struct pollfd *,ufds,unsigned int,nfds,int,timeout); + #endif + #include <atm.h> ++#include <linux/types.h> + #include <linux/atmioc.h> + #include <linux/atmmpc.h> + #include <sys/types.h> +diff -urNad linux-atm-2.4.1~/src/mpoad/k_interf.c linux-atm-2.4.1/src/mpoad/k_interf.c +--- linux-atm-2.4.1~/src/mpoad/k_interf.c 2001-09-03 20:41:06.000000000 +0200 ++++ linux-atm-2.4.1/src/mpoad/k_interf.c 2007-07-19 01:38:37.000000000 +0200 +@@ -9,6 +9,7 @@ + #include <sys/param.h> /* for OPEN_MAX */ + #include <stdint.h> + #include <netinet/in.h> /* for ntohl() */ ++#include <linux/types.h> + #include <linux/atmmpc.h> + #include <atm.h> + #include "k_interf.h" +diff -urNad linux-atm-2.4.1~/src/mpoad/lecs.c linux-atm-2.4.1/src/mpoad/lecs.c +--- linux-atm-2.4.1~/src/mpoad/lecs.c 2001-09-03 20:41:06.000000000 +0200 ++++ linux-atm-2.4.1/src/mpoad/lecs.c 2007-07-19 01:39:04.000000000 +0200 +@@ -11,6 +11,7 @@ + #include <errno.h> + #include <atm.h> + #include <atmsap.h> ++#include <linux/types.h> + #include <linux/atmmpc.h> /* for MPOA Device type TLV */ + #include "lecs.h" + #include "k_interf.h" +diff -urNad linux-atm-2.4.1~/src/mpoad/main.c linux-atm-2.4.1/src/mpoad/main.c +--- linux-atm-2.4.1~/src/mpoad/main.c 2001-09-03 20:41:06.000000000 +0200 ++++ linux-atm-2.4.1/src/mpoad/main.c 2007-07-19 01:38:37.000000000 +0200 +@@ -9,6 +9,7 @@ + #include <time.h> + #include <sys/ioctl.h> + #include <atm.h> ++#include <linux/types.h> + #include <linux/atmdev.h> + #include <linux/atmmpc.h> + #include <sys/socket.h> +diff -urNad linux-atm-2.4.1~/src/mpoad/p_factory.c linux-atm-2.4.1/src/mpoad/p_factory.c +--- linux-atm-2.4.1~/src/mpoad/p_factory.c 2007-07-19 01:22:42.000000000 +0200 ++++ linux-atm-2.4.1/src/mpoad/p_factory.c 2007-07-19 01:38:37.000000000 +0200 +@@ -5,6 +5,7 @@ + #include <sys/types.h> + #include <stdint.h> + #include <netinet/in.h> ++#include <linux/types.h> + #include <linux/atmmpc.h> + #include <sys/socket.h> + #include <unistd.h> +diff -urNad linux-atm-2.4.1~/src/mpoad/p_recogn.c linux-atm-2.4.1/src/mpoad/p_recogn.c +--- linux-atm-2.4.1~/src/mpoad/p_recogn.c 2001-09-03 20:41:06.000000000 +0200 ++++ linux-atm-2.4.1/src/mpoad/p_recogn.c 2007-07-19 01:39:12.000000000 +0200 +@@ -7,6 +7,7 @@ + #include <stdlib.h> + #include <sys/time.h> + #include <atm.h> ++#include <linux/types.h> + #include <linux/atmmpc.h> + #include <netinet/in.h> + #include <limits.h> /* For UINT_MAX */ diff --git a/pkgs/core/lm-sensors/lm-sensors.nm b/pkgs/core/lm-sensors/lm-sensors.nm new file mode 100644 index 0000000..fd35977 --- /dev/null +++ b/pkgs/core/lm-sensors/lm-sensors.nm @@ -0,0 +1,55 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = lm_sensors +PKG_VER = 3.0.0 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Statistics +PKG_URL = http://www.lm-sensors.org/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Hardware monitoring tools. + +PKG_BUILD_DEPS+= bison flex +PKG_DEPS += sysfsutils perl rrdtool + +define PKG_DESCRIPTION + The lm_sensors package includes a collection of modules for general SMBus \ + access and hardware monitoring. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -e "s/^PREFIX\ :=\ .*/PREFIX=/usr/g" \ + -e "s/^MACHINE\ :=\ .*/MACHINE=$(MACHINE)/g" \ + -e "s/^MANDIR.*/MANDIR=/usr/share/man/g" -i Makefile +endef + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) EXLDFLAGS= +endef diff --git a/pkgs/core/logrotate/logrotate.nm b/pkgs/core/logrotate/logrotate.nm new file mode 100644 index 0000000..7242dfa --- /dev/null +++ b/pkgs/core/logrotate/logrotate.nm @@ -0,0 +1,66 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = logrotate +PKG_VER = 3.7.7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = https://fedorahosted.org/releases/l/o/logrotate/ +PKG_LICENSE = GPL+ +PKG_SUMMARY = Rotates, compresses, removes and mails system log files. + +PKG_DEPS += coreutils gzip popt which + +define PKG_DESCRIPTION + The logrotate utility is designed to simplify the administration of \ + log files on a system which generates a lot of log files. Logrotate \ + allows for the automatic rotation compression, removal and mailing of \ + log files. Logrotate can be set to handle a log file daily, weekly, \ + monthly or when the log file gets to a certain size. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_BUILD + cd $(DIR_APP) && make RPM_OPT_FLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + cd $(DIR_APP) && make test +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install BASEDIR=/usr PREFIX=$(BUILDROOT) \ + MANDIR=/usr/share/man + + -mkdir -pv $(BUILDROOT)/var/lib + touch $(BUILDROOT)/var/lib/logrotate.status + + # Creating directory for config files + mkdir -pv $(BUILDROOT)/etc/logrotate.d +endef diff --git a/pkgs/core/logrotate/patches/logrotate-3.7.7-curdir.patch b/pkgs/core/logrotate/patches/logrotate-3.7.7-curdir.patch new file mode 100644 index 0000000..8ae8f06 --- /dev/null +++ b/pkgs/core/logrotate/patches/logrotate-3.7.7-curdir.patch @@ -0,0 +1,15 @@ +diff -up logrotate-3.7.7/config.c.curdir logrotate-3.7.7/config.c +--- logrotate-3.7.7/config.c.curdir 2008-05-09 09:28:59.000000000 +0200 ++++ logrotate-3.7.7/config.c 2008-11-20 15:35:05.000000000 +0100 +@@ -316,11 +316,6 @@ static int readConfigPath(const char *pa + DIR *dirp; + + here = open(".", O_RDONLY); +- if (here < 0) { +- message(MESS_ERROR, "cannot open current directory: %s\n", +- strerror(errno)); +- return 1; +- } + + if ((dirp = opendir(path)) == NULL) { + message(MESS_ERROR, "cannot open directory %s: %s\n", path, diff --git a/pkgs/core/logrotate/patches/logrotate-3.7.7-toolarge.patch b/pkgs/core/logrotate/patches/logrotate-3.7.7-toolarge.patch new file mode 100644 index 0000000..68027c8 --- /dev/null +++ b/pkgs/core/logrotate/patches/logrotate-3.7.7-toolarge.patch @@ -0,0 +1,17 @@ +diff -up logrotate-3.7.7/config.c.toolarge logrotate-3.7.7/config.c +--- logrotate-3.7.7/config.c.toolarge 2008-11-21 12:57:25.000000000 +0100 ++++ logrotate-3.7.7/config.c 2008-11-21 12:57:41.000000000 +0100 +@@ -530,6 +530,13 @@ static int readConfigFile(const char *co + + length = sb.st_size; + ++ if (length > 0xffffff) { ++ message(MESS_ERROR, "file %s too large, probably not a config file.\n", ++ configFile); ++ close(fd); ++ return 1; ++ } ++ + buf = alloca(length + 2); + if (!buf) { + message(MESS_ERROR, "alloca() of %d bytes failed\n", (int) length); diff --git a/pkgs/core/lsof/lsof.nm b/pkgs/core/lsof/lsof.nm new file mode 100644 index 0000000..3c87f89 --- /dev/null +++ b/pkgs/core/lsof/lsof.nm @@ -0,0 +1,56 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = lsof +PKG_VER = 4.82 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Debuggers +PKG_URL = ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof +PKG_LICENSE = zlib +PKG_SUMMARY = A utility which lists open files on a Linux/UNIX system. + +define PKG_DESCRIPTION + Lsof stands for LiSt Open Files, and it does just that: \ + it lists information about files that are open by the \ + processes running on a system. +endef + +PKG_TARBALL = $(PKG_NAME)_$(PKG_VER)_src.tar.gz + +DIR_APP = /usr/src/$(PKG_NAME)_$(PKG_VER)_src + +define STAGE_BUILD + cd $(DIR_APP) && ./Configure linux -n + cd $(DIR_APP) && make DEBUG="$(CFLAGS)" $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/usr/bin + cd $(DIR_APP) && install -m 4750 -o root -g nobody lsof $(BUILDROOT)/usr/bin +endef + diff --git a/pkgs/core/lua/lua.nm b/pkgs/core/lua/lua.nm new file mode 100644 index 0000000..3d28e18 --- /dev/null +++ b/pkgs/core/lua/lua.nm @@ -0,0 +1,71 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = lua +PKG_VER = 5.1.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Languages +PKG_URL = http://www.lua.org/ +PKG_LICENSE = MIT +PKG_SUMMARY = Powerful light-weight programming language. + +PKG_DEPS += ncurses readline + +define PKG_DESCRIPTION + Lua is a powerful light-weight programming language designed for \ + extending applications. Lua is also frequently used as a \ + general-purpose, stand-alone language. Lua is free software. \ + Lua combines simple procedural syntax with powerful data description \ + constructs based on associative arrays and extensible semantics. Lua \ + is dynamically typed, interpreted from bytecodes, and has automatic \ + memory management with garbage collection, making it ideal for \ + configuration, scripting, and rapid prototyping. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && chmod u+x autogen.sh config.guess config.sub configure \ + depcomp install-sh missing +endef + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --mandir=/usr/share/man \ + --with-readline + + cd $(DIR_APP) && sed -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ + -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' -i libtool + # hack so that only /usr/bin/lua gets linked with readline as it is the + # only one which needs this and otherwise we get License troubles + cd $(DIR_APP) && make $(PARALLELISMFLAGS) LIBS="-ldl" luac_LDADD="liblua.la -lm -ldl" + # also remove readline from lua.pc + cd $(DIR_APP) && sed -i 's/-lreadline -lncurses //g' etc/lua.pc +endef diff --git a/pkgs/core/lua/patches/lua-5.1.4-autotoolize.patch b/pkgs/core/lua/patches/lua-5.1.4-autotoolize.patch new file mode 100644 index 0000000..8aa8812 --- /dev/null +++ b/pkgs/core/lua/patches/lua-5.1.4-autotoolize.patch @@ -0,0 +1,43660 @@ +diff -urN lua-5.1.4/aclocal.m4 lua-5.1.4-autotoolize/aclocal.m4 +--- lua-5.1.4/aclocal.m4 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/aclocal.m4 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,7307 @@ ++# generated automatically by aclocal 1.9.6 -*- Autoconf -*- ++ ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, ++# 2005 Free Software Foundation, Inc. ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- ++ ++# serial 48 AC_PROG_LIBTOOL ++ ++ ++# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) ++# ----------------------------------------------------------- ++# If this macro is not defined by Autoconf, define it here. ++m4_ifdef([AC_PROVIDE_IFELSE], ++ [], ++ [m4_define([AC_PROVIDE_IFELSE], ++ [m4_ifdef([AC_PROVIDE_$1], ++ [$2], [$3])])]) ++ ++ ++# AC_PROG_LIBTOOL ++# --------------- ++AC_DEFUN([AC_PROG_LIBTOOL], ++[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl ++dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX ++dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. ++ AC_PROVIDE_IFELSE([AC_PROG_CXX], ++ [AC_LIBTOOL_CXX], ++ [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX ++ ])]) ++dnl And a similar setup for Fortran 77 support ++ AC_PROVIDE_IFELSE([AC_PROG_F77], ++ [AC_LIBTOOL_F77], ++ [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 ++])]) ++ ++dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. ++dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run ++dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. ++ AC_PROVIDE_IFELSE([AC_PROG_GCJ], ++ [AC_LIBTOOL_GCJ], ++ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], ++ [AC_LIBTOOL_GCJ], ++ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], ++ [AC_LIBTOOL_GCJ], ++ [ifdef([AC_PROG_GCJ], ++ [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) ++ ifdef([A][M_PROG_GCJ], ++ [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) ++ ifdef([LT_AC_PROG_GCJ], ++ [define([LT_AC_PROG_GCJ], ++ defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) ++])])# AC_PROG_LIBTOOL ++ ++ ++# _AC_PROG_LIBTOOL ++# ---------------- ++AC_DEFUN([_AC_PROG_LIBTOOL], ++[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl ++AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl ++AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl ++AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl ++ ++# This can be used to rebuild libtool when needed ++LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" ++ ++# Always use our own libtool. ++LIBTOOL='$(SHELL) $(top_builddir)/libtool' ++AC_SUBST(LIBTOOL)dnl ++ ++# Prevent multiple expansion ++define([AC_PROG_LIBTOOL], []) ++])# _AC_PROG_LIBTOOL ++ ++ ++# AC_LIBTOOL_SETUP ++# ---------------- ++AC_DEFUN([AC_LIBTOOL_SETUP], ++[AC_PREREQ(2.50)dnl ++AC_REQUIRE([AC_ENABLE_SHARED])dnl ++AC_REQUIRE([AC_ENABLE_STATIC])dnl ++AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl ++AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_PROG_LD])dnl ++AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl ++AC_REQUIRE([AC_PROG_NM])dnl ++ ++AC_REQUIRE([AC_PROG_LN_S])dnl ++AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl ++# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! ++AC_REQUIRE([AC_OBJEXT])dnl ++AC_REQUIRE([AC_EXEEXT])dnl ++dnl ++ ++AC_LIBTOOL_SYS_MAX_CMD_LEN ++AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE ++AC_LIBTOOL_OBJDIR ++ ++AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl ++_LT_AC_PROG_ECHO_BACKSLASH ++ ++case $host_os in ++aix3*) ++ # AIX sometimes has problems with the GCC collect2 program. For some ++ # reason, if we set the COLLECT_NAMES environment variable, the problems ++ # vanish in a puff of smoke. ++ if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++ fi ++ ;; ++esac ++ ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++Xsed='sed -e 1s/^X//' ++[sed_quote_subst='s/([\"\`$\\])/\\1/g'] ++ ++# Same as above, but do not quote variable references. ++[double_quote_subst='s/([\"\`\\])/\\1/g'] ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\$/\\\$/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/*/\*/g' ++ ++# Constants: ++rm="rm -f" ++ ++# Global variables: ++default_ofile=libtool ++can_build_shared=yes ++ ++# All known linkers require a `.a' archive for static linking (except MSVC, ++# which needs '.lib'). ++libext=a ++ltmain="$ac_aux_dir/ltmain.sh" ++ofile="$default_ofile" ++with_gnu_ld="$lt_cv_prog_gnu_ld" ++ ++AC_CHECK_TOOL(AR, ar, false) ++AC_CHECK_TOOL(RANLIB, ranlib, :) ++AC_CHECK_TOOL(STRIP, strip, :) ++ ++old_CC="$CC" ++old_CFLAGS="$CFLAGS" ++ ++# Set sane defaults for various variables ++test -z "$AR" && AR=ar ++test -z "$AR_FLAGS" && AR_FLAGS=cru ++test -z "$AS" && AS=as ++test -z "$CC" && CC=cc ++test -z "$LTCC" && LTCC=$CC ++test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS ++test -z "$DLLTOOL" && DLLTOOL=dlltool ++test -z "$LD" && LD=ld ++test -z "$LN_S" && LN_S="ln -s" ++test -z "$MAGIC_CMD" && MAGIC_CMD=file ++test -z "$NM" && NM=nm ++test -z "$SED" && SED=sed ++test -z "$OBJDUMP" && OBJDUMP=objdump ++test -z "$RANLIB" && RANLIB=: ++test -z "$STRIP" && STRIP=: ++test -z "$ac_objext" && ac_objext=o ++ ++# Determine commands to create old-style static archives. ++old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' ++old_postinstall_cmds='chmod 644 $oldlib' ++old_postuninstall_cmds= ++ ++if test -n "$RANLIB"; then ++ case $host_os in ++ openbsd*) ++ old_postinstall_cmds="$old_postinstall_cmds~$RANLIB -t $oldlib" ++ ;; ++ *) ++ old_postinstall_cmds="$old_postinstall_cmds~$RANLIB $oldlib" ++ ;; ++ esac ++ old_archive_cmds="$old_archive_cmds~$RANLIB $oldlib" ++fi ++ ++_LT_CC_BASENAME([$compiler]) ++ ++# Only perform the check for file, if the check method requires it ++case $deplibs_check_method in ++file_magic*) ++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then ++ AC_PATH_MAGIC ++ fi ++ ;; ++esac ++ ++AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) ++AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], ++enable_win32_dll=yes, enable_win32_dll=no) ++ ++AC_ARG_ENABLE([libtool-lock], ++ [AC_HELP_STRING([--disable-libtool-lock], ++ [avoid locking (might break parallel builds)])]) ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++AC_ARG_WITH([pic], ++ [AC_HELP_STRING([--with-pic], ++ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], ++ [pic_mode="$withval"], ++ [pic_mode=default]) ++test -z "$pic_mode" && pic_mode=default ++ ++# Check if we have a version mismatch between libtool.m4 and ltmain.sh. ++# ++# Note: This should be in AC_LIBTOOL_SETUP, _after_ $ltmain have been defined. ++# We also should do it _before_ AC_LIBTOOL_LANG_C_CONFIG that actually ++# calls AC_LIBTOOL_CONFIG and creates libtool. ++# ++_LT_VERSION_CHECK ++ ++# Use C for the default configuration in the libtool script ++tagname= ++AC_LIBTOOL_LANG_C_CONFIG ++_LT_AC_TAGCONFIG ++])# AC_LIBTOOL_SETUP ++ ++ ++# _LT_VERSION_CHECK ++# ----------------- ++AC_DEFUN([_LT_VERSION_CHECK], ++[AC_MSG_CHECKING([for correct ltmain.sh version]) ++if test "x$ltmain" = "x" ; then ++ AC_MSG_RESULT(no) ++ AC_MSG_ERROR([ ++ ++*** @<:@Gentoo@:>@ sanity check failed! *** ++*** $ltmain is not defined, please check the patch for consistency! *** ++]) ++fi ++gentoo_lt_version="1.5.22" ++gentoo_ltmain_version=`sed -n '/^[[ ]]*VERSION=/{s/^[[ ]]*VERSION=//;p;q;}' "$ltmain"` ++if test "x$gentoo_lt_version" != "x$gentoo_ltmain_version" ; then ++ AC_MSG_RESULT(no) ++ AC_MSG_ERROR([ ++ ++*** @<:@Gentoo@:>@ sanity check failed! *** ++*** libtool.m4 and ltmain.sh have a version mismatch! *** ++*** (libtool.m4 = $gentoo_lt_version, ltmain.sh = $gentoo_ltmain_version) *** ++ ++Please run: ++ ++ libtoolize --copy --force ++ ++if appropriate, please contact the maintainer of this ++package (or your distribution) for help. ++]) ++else ++ AC_MSG_RESULT(yes) ++fi ++])# _LT_VERSION_CHECK ++ ++ ++# _LT_AC_SYS_COMPILER ++# ------------------- ++AC_DEFUN([_LT_AC_SYS_COMPILER], ++[AC_REQUIRE([AC_PROG_CC])dnl ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++])# _LT_AC_SYS_COMPILER ++ ++ ++# _LT_CC_BASENAME(CC) ++# ------------------- ++# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. ++AC_DEFUN([_LT_CC_BASENAME], ++[for cc_temp in $1""; do ++ case $cc_temp in ++ compile | *[[\/]]compile | ccache | *[[\/]]ccache ) ;; ++ distcc | *[[\/]]distcc | purify | *[[\/]]purify ) ;; ++ -*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++]) ++ ++ ++# _LT_COMPILER_BOILERPLATE ++# ------------------------ ++# Check for compiler boilerplate output or warnings with ++# the simple compiler test code. ++AC_DEFUN([_LT_COMPILER_BOILERPLATE], ++[ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++])# _LT_COMPILER_BOILERPLATE ++ ++ ++# _LT_LINKER_BOILERPLATE ++# ---------------------- ++# Check for linker boilerplate output or warnings with ++# the simple link test code. ++AC_DEFUN([_LT_LINKER_BOILERPLATE], ++[ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++])# _LT_LINKER_BOILERPLATE ++ ++ ++# _LT_AC_SYS_LIBPATH_AIX ++# ---------------------- ++# Links a minimal program and checks the executable ++# for the system default hardcoded library path. In most cases, ++# this is /usr/lib:/lib, but when the MPI compilers are used ++# the location of the communication and MPI libs are included too. ++# If we don't find anything, use the default library path according ++# to the aix ld manual. ++AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], ++[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'`; fi],[]) ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++])# _LT_AC_SYS_LIBPATH_AIX ++ ++ ++# _LT_AC_SHELL_INIT(ARG) ++# ---------------------- ++AC_DEFUN([_LT_AC_SHELL_INIT], ++[ifdef([AC_DIVERSION_NOTICE], ++ [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], ++ [AC_DIVERT_PUSH(NOTICE)]) ++$1 ++AC_DIVERT_POP ++])# _LT_AC_SHELL_INIT ++ ++ ++# _LT_AC_PROG_ECHO_BACKSLASH ++# -------------------------- ++# Add some code to the start of the generated configure script which ++# will find an echo command which doesn't interpret backslashes. ++AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], ++[_LT_AC_SHELL_INIT([ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$ECHO" | sed 's,\\[$]\[$]0,'[$]0','` ++ ;; ++esac ++ ++echo=${ECHO-echo} ++if test "X[$]1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X[$]1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $echo works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} ++fi ++ ++if test "X[$]1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<EOF ++[$]* ++EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$ECHO"; then ++if test "X${echo_test_string+set}" != Xset; then ++# find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if (echo_test_string=`eval $cmd`) 2>/dev/null && ++ echo_test_string=`eval $cmd` && ++ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null ++ then ++ break ++ fi ++ done ++fi ++ ++if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\/\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ echo="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$echo" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ echo='print -r' ++ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} ++ else ++ # Try using printf. ++ echo='printf %s\n' ++ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ echo="$CONFIG_SHELL [$]0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ echo="$CONFIG_SHELL [$]0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do ++ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "[$]0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ echo=echo ++ fi ++ fi ++ fi ++ fi ++fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++ECHO=$echo ++if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then ++ ECHO="$CONFIG_SHELL \$[$]0 --fallback-echo" ++fi ++ ++AC_SUBST(ECHO) ++])])# _LT_AC_PROG_ECHO_BACKSLASH ++ ++ ++# _LT_AC_LOCK ++# ----------- ++AC_DEFUN([_LT_AC_LOCK], ++[AC_ARG_ENABLE([libtool-lock], ++ [AC_HELP_STRING([--disable-libtool-lock], ++ [avoid locking (might break parallel builds)])]) ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++# Some flags need to be propagated to the compiler or linker for good ++# libtool support. ++case $host in ++ia64-*-hpux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *ELF-32*) ++ HPUX_IA64_MODE="32" ++ ;; ++ *ELF-64*) ++ HPUX_IA64_MODE="64" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++*-*-irix6*) ++ # Find out which ABI we are using. ++ echo '[#]line __oline__ "configure"' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -melf32bsmip" ++ ;; ++ *N32*) ++ LD="${LD-ld} -melf32bmipn32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -melf64bmip" ++ ;; ++ esac ++ else ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -32" ++ ;; ++ *N32*) ++ LD="${LD-ld} -n32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -64" ++ ;; ++ esac ++ fi ++ fi ++ rm -rf conftest* ++ ;; ++ ++x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `/usr/bin/file conftest.o` in ++ *32-bit*) ++ case $host in ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_i386" ++ ;; ++ ppc64-*linux*|powerpc64-*linux*) ++ LD="${LD-ld} -m elf32ppclinux" ++ ;; ++ s390x-*linux*) ++ LD="${LD-ld} -m elf_s390" ++ ;; ++ sparc64-*linux*) ++ LD="${LD-ld} -m elf32_sparc" ++ ;; ++ esac ++ ;; ++ *64-bit*) ++ case $host in ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ ppc*-*linux*|powerpc*-*linux*) ++ LD="${LD-ld} -m elf64ppc" ++ ;; ++ s390*-*linux*) ++ LD="${LD-ld} -m elf64_s390" ++ ;; ++ sparc*-*linux*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++*-*-sco3.2v5*) ++ # On SCO OpenServer 5, we need -belf to get full-featured binaries. ++ SAVE_CFLAGS="$CFLAGS" ++ CFLAGS="$CFLAGS -belf" ++ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, ++ [AC_LANG_PUSH(C) ++ AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) ++ AC_LANG_POP]) ++ if test x"$lt_cv_cc_needs_belf" != x"yes"; then ++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf ++ CFLAGS="$SAVE_CFLAGS" ++ fi ++ ;; ++sparc*-*solaris*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `/usr/bin/file conftest.o` in ++ *64-bit*) ++ case $lt_cv_prog_gnu_ld in ++ yes*) LD="${LD-ld} -m elf64_sparc" ;; ++ *) LD="${LD-ld} -64" ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], ++[*-*-cygwin* | *-*-mingw* | *-*-pw32*) ++ AC_CHECK_TOOL(DLLTOOL, dlltool, false) ++ AC_CHECK_TOOL(AS, as, false) ++ AC_CHECK_TOOL(OBJDUMP, objdump, false) ++ ;; ++ ]) ++esac ++ ++need_locks="$enable_libtool_lock" ++ ++])# _LT_AC_LOCK ++ ++ ++# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, ++# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) ++# ---------------------------------------------------------------- ++# Check whether the given compiler option works ++AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], ++[AC_REQUIRE([LT_AC_PROG_SED]) ++AC_CACHE_CHECK([$1], [$2], ++ [$2=no ++ ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$3" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [[^ ]]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:__oline__: $lt_compile"" >&AS_MESSAGE_LOG_FD) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ echo "$as_me:__oline__: $? = $ac_status" >&AS_MESSAGE_LOG_FD ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ $2=yes ++ fi ++ fi ++ $rm conftest* ++]) ++ ++if test x"[$]$2" = xyes; then ++ ifelse([$5], , :, [$5]) ++else ++ ifelse([$6], , :, [$6]) ++fi ++])# AC_LIBTOOL_COMPILER_OPTION ++ ++ ++# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, ++# [ACTION-SUCCESS], [ACTION-FAILURE]) ++# ------------------------------------------------------------ ++# Check whether the given compiler option works ++AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], ++[AC_CACHE_CHECK([$1], [$2], ++ [$2=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $3" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&AS_MESSAGE_LOG_FD ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ $2=yes ++ fi ++ else ++ $2=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++]) ++ ++if test x"[$]$2" = xyes; then ++ ifelse([$4], , :, [$4]) ++else ++ ifelse([$5], , :, [$5]) ++fi ++])# AC_LIBTOOL_LINKER_OPTION ++ ++ ++# AC_LIBTOOL_SYS_MAX_CMD_LEN ++# -------------------------- ++AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], ++[# find the maximum length of command line arguments ++AC_MSG_CHECKING([the maximum length of command line arguments]) ++AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ++ i=0 ++ teststring="ABCD" ++ ++ case $build_os in ++ msdosdjgpp*) ++ # On DJGPP, this test can blow up pretty badly due to problems in libc ++ # (any single argument exceeding 2000 bytes causes a buffer overrun ++ # during glob expansion). Even if it were fixed, the result of this ++ # check would be larger than it should be. ++ lt_cv_sys_max_cmd_len=12288; # 12K is about right ++ ;; ++ ++ gnu*) ++ # Under GNU Hurd, this test is not required because there is ++ # no limit to the length of command line arguments. ++ # Libtool will interpret -1 as no limit whatsoever ++ lt_cv_sys_max_cmd_len=-1; ++ ;; ++ ++ cygwin* | mingw*) ++ # On Win9x/ME, this test blows up -- it succeeds, but takes ++ # about 5 minutes as the teststring grows exponentially. ++ # Worse, since 9x/ME are not pre-emptively multitasking, ++ # you end up with a "frozen" computer, even though with patience ++ # the test eventually succeeds (with a max line length of 256k). ++ # Instead, let's just punt: use the minimum linelength reported by ++ # all of the supported platforms: 8192 (on NT/2K/XP). ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ amigaos*) ++ # On AmigaOS with pdksh, this test takes hours, literally. ++ # So we just punt and use a minimum line length of 8192. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) ++ # This has been around since 386BSD, at least. Likely further. ++ if test -x /sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` ++ elif test -x /usr/sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` ++ else ++ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs ++ fi ++ # And add a safety zone ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len / 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len * 3` ++ ;; ++ ++ interix*) ++ # We know the value 262144 and hardcode it with a safety zone (like BSD) ++ lt_cv_sys_max_cmd_len=196608 ++ ;; ++ ++ osf*) ++ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure ++ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not ++ # nice to cause kernel panics so lets avoid the loop below. ++ # First set a reasonable default. ++ lt_cv_sys_max_cmd_len=16384 ++ # ++ if test -x /sbin/sysconfig; then ++ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in ++ *1*) lt_cv_sys_max_cmd_len=-1 ;; ++ esac ++ fi ++ ;; ++ sco3.2v5*) ++ lt_cv_sys_max_cmd_len=102400 ++ ;; ++ sysv5* | sco5v6* | sysv4.2uw2*) ++ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` ++ if test -n "$kargmax"; then ++ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` ++ else ++ lt_cv_sys_max_cmd_len=32768 ++ fi ++ ;; ++ *) ++ # If test is not a shell built-in, we'll probably end up computing a ++ # maximum length that is only half of the actual maximum length, but ++ # we can't tell. ++ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} ++ while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ ++ = "XX$teststring") >/dev/null 2>&1 && ++ new_result=`expr "X$teststring" : ".*" 2>&1` && ++ lt_cv_sys_max_cmd_len=$new_result && ++ test $i != 17 # 1/2 MB should be enough ++ do ++ i=`expr $i + 1` ++ teststring=$teststring$teststring ++ done ++ teststring= ++ # Add a significant safety factor because C++ compilers can tack on massive ++ # amounts of additional arguments before passing them to the linker. ++ # It appears as though 1/2 is a usable value. ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len / 2` ++ ;; ++ esac ++]) ++if test -n $lt_cv_sys_max_cmd_len ; then ++ AC_MSG_RESULT($lt_cv_sys_max_cmd_len) ++else ++ AC_MSG_RESULT(none) ++fi ++])# AC_LIBTOOL_SYS_MAX_CMD_LEN ++ ++ ++# _LT_AC_CHECK_DLFCN ++# ------------------ ++AC_DEFUN([_LT_AC_CHECK_DLFCN], ++[AC_CHECK_HEADERS(dlfcn.h)dnl ++])# _LT_AC_CHECK_DLFCN ++ ++ ++# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, ++# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) ++# --------------------------------------------------------------------- ++AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], ++[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl ++if test "$cross_compiling" = yes; then : ++ [$4] ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<EOF ++[#line __oline__ "configure" ++#include "confdefs.h" ++ ++#if HAVE_DLFCN_H ++#include <dlfcn.h> ++#endif ++ ++#include <stdio.h> ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++#ifdef __cplusplus ++extern "C" void exit (int); ++#endif ++ ++void fnord() { int i=42;} ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ exit (status); ++}] ++EOF ++ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) $1 ;; ++ x$lt_dlneed_uscore) $2 ;; ++ x$lt_dlunknown|x*) $3 ;; ++ esac ++ else : ++ # compilation failed ++ $3 ++ fi ++fi ++rm -fr conftest* ++])# _LT_AC_TRY_DLOPEN_SELF ++ ++ ++# AC_LIBTOOL_DLOPEN_SELF ++# ---------------------- ++AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], ++[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl ++if test "x$enable_dlopen" != xyes; then ++ enable_dlopen=unknown ++ enable_dlopen_self=unknown ++ enable_dlopen_self_static=unknown ++else ++ lt_cv_dlopen=no ++ lt_cv_dlopen_libs= ++ ++ case $host_os in ++ beos*) ++ lt_cv_dlopen="load_add_on" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ;; ++ ++ mingw* | pw32*) ++ lt_cv_dlopen="LoadLibrary" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ cygwin*) ++ lt_cv_dlopen="dlopen" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ darwin*) ++ # if libdl is installed we need to link against it ++ AC_CHECK_LIB([dl], [dlopen], ++ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ ++ lt_cv_dlopen="dyld" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ]) ++ ;; ++ ++ *) ++ AC_CHECK_FUNC([shl_load], ++ [lt_cv_dlopen="shl_load"], ++ [AC_CHECK_LIB([dld], [shl_load], ++ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], ++ [AC_CHECK_FUNC([dlopen], ++ [lt_cv_dlopen="dlopen"], ++ [AC_CHECK_LIB([dl], [dlopen], ++ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], ++ [AC_CHECK_LIB([svld], [dlopen], ++ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], ++ [AC_CHECK_LIB([dld], [dld_link], ++ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) ++ ]) ++ ]) ++ ]) ++ ]) ++ ]) ++ ;; ++ esac ++ ++ if test "x$lt_cv_dlopen" != xno; then ++ enable_dlopen=yes ++ else ++ enable_dlopen=no ++ fi ++ ++ case $lt_cv_dlopen in ++ dlopen) ++ save_CPPFLAGS="$CPPFLAGS" ++ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" ++ ++ save_LDFLAGS="$LDFLAGS" ++ wl=$lt_prog_compiler_wl eval LDFLAGS="$LDFLAGS $export_dynamic_flag_spec" ++ ++ save_LIBS="$LIBS" ++ LIBS="$lt_cv_dlopen_libs $LIBS" ++ ++ AC_CACHE_CHECK([whether a program can dlopen itself], ++ lt_cv_dlopen_self, [dnl ++ _LT_AC_TRY_DLOPEN_SELF( ++ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, ++ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ++ ]) ++ ++ if test "x$lt_cv_dlopen_self" = xyes; then ++ wl=$lt_prog_compiler_wl eval LDFLAGS="$LDFLAGS $lt_prog_compiler_static" ++ AC_CACHE_CHECK([whether a statically linked program can dlopen itself], ++ lt_cv_dlopen_self_static, [dnl ++ _LT_AC_TRY_DLOPEN_SELF( ++ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, ++ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ++ ]) ++ fi ++ ++ CPPFLAGS="$save_CPPFLAGS" ++ LDFLAGS="$save_LDFLAGS" ++ LIBS="$save_LIBS" ++ ;; ++ esac ++ ++ case $lt_cv_dlopen_self in ++ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; ++ *) enable_dlopen_self=unknown ;; ++ esac ++ ++ case $lt_cv_dlopen_self_static in ++ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; ++ *) enable_dlopen_self_static=unknown ;; ++ esac ++fi ++])# AC_LIBTOOL_DLOPEN_SELF ++ ++ ++# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) ++# --------------------------------- ++# Check to see if options -c and -o are simultaneously supported by compiler ++AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], ++[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl ++AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], ++ [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], ++ [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [[^ ]]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:__oline__: $lt_compile"" >&AS_MESSAGE_LOG_FD) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&AS_MESSAGE_LOG_FD ++ echo "$as_me:__oline__: $? = $ac_status" >&AS_MESSAGE_LOG_FD ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes ++ fi ++ fi ++ chmod u+w . 2>&AS_MESSAGE_LOG_FD ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++]) ++])# AC_LIBTOOL_PROG_CC_C_O ++ ++ ++# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) ++# ----------------------------------------- ++# Check to see if we can do hard links to lock some files if needed ++AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], ++[AC_REQUIRE([_LT_AC_LOCK])dnl ++ ++hard_links="nottested" ++if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ AC_MSG_CHECKING([if we can lock with hard links]) ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ AC_MSG_RESULT([$hard_links]) ++ if test "$hard_links" = no; then ++ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS ++ ++ ++# AC_LIBTOOL_OBJDIR ++# ----------------- ++AC_DEFUN([AC_LIBTOOL_OBJDIR], ++[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], ++[rm -f .libs 2>/dev/null ++mkdir .libs 2>/dev/null ++if test -d .libs; then ++ lt_cv_objdir=.libs ++else ++ # MS-DOS does not allow filenames that begin with a dot. ++ lt_cv_objdir=_libs ++fi ++rmdir .libs 2>/dev/null]) ++objdir=$lt_cv_objdir ++])# AC_LIBTOOL_OBJDIR ++ ++ ++# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) ++# ---------------------------------------------- ++# Check hardcoding attributes. ++AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], ++[AC_MSG_CHECKING([how to hardcode library paths into programs]) ++_LT_AC_TAGVAR(hardcode_action, $1)= ++if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ ++ test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ ++ test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && ++ test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then ++ # Linking always hardcodes the temporary library directory. ++ _LT_AC_TAGVAR(hardcode_action, $1)=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ _LT_AC_TAGVAR(hardcode_action, $1)=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ _LT_AC_TAGVAR(hardcode_action, $1)=unsupported ++fi ++AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) ++ ++if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH ++ ++ ++# AC_LIBTOOL_SYS_LIB_STRIP ++# ------------------------ ++AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], ++[striplib= ++old_striplib= ++AC_MSG_CHECKING([whether stripping libraries is possible]) ++if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then ++ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" ++ test -z "$striplib" && striplib="$STRIP --strip-unneeded" ++ AC_MSG_RESULT([yes]) ++else ++# FIXME - insert some real tests, host_os isn't really good enough ++ case $host_os in ++ darwin*) ++ if test -n "$STRIP" ; then ++ striplib="$STRIP -x" ++ AC_MSG_RESULT([yes]) ++ else ++ AC_MSG_RESULT([no]) ++fi ++ ;; ++ *) ++ AC_MSG_RESULT([no]) ++ ;; ++ esac ++fi ++])# AC_LIBTOOL_SYS_LIB_STRIP ++ ++ ++# AC_LIBTOOL_SYS_DYNAMIC_LINKER ++# ----------------------------- ++# PORTME Fill in your ld.so characteristics ++AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], ++[AC_MSG_CHECKING([dynamic linker characteristics]) ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[[01]] | aix4.[[01]].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib<name>.so ++ # instead of lib<name>.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '''s%^.*/([[^/]]*).ixlibrary$%\1%'''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[[45]]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename ${file}`~ ++ dlpath=`$SHELL 2>&1 -c '''. $dir/'''${base_file}'''i;echo $dlname'''`~ ++ dldir=$destdir/`dirname $dlpath`~ ++ test -d $dldir || mkdir -p $dldir~ ++ $install_prog $dir/$dlname $dldir/$dlname~ ++ chmod a+x $dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '''. $file; echo $dlname'''`~ ++ dlpath=$dir/$dldll~ ++ $rm $dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ ++cat $export_symbols | sed -e "s/(.*)/\1;/" >> $output_objdir/$libname.ver~ ++$echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ else ++ $archive_expsym_cmds="$archive_cmds" ++ fi ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[[123]]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ # Handle Gentoo/FreeBSD as it was Linux ++ case $host_vendor in ++ gentoo) ++ version_type=linux ;; ++ *) ++ version_type=freebsd-$objformat ;; ++ esac ++ ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ linux) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ need_lib_prefix=no ++ need_version=no ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[[01]]* | freebsdelf3.[[01]]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ ++ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", [$]2)); skip = 1; } { if (!skip) print [$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[[89]] | openbsd2.[[89]].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++AC_MSG_RESULT([$dynamic_linker]) ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++])# AC_LIBTOOL_SYS_DYNAMIC_LINKER ++ ++ ++# _LT_AC_TAGCONFIG ++# ---------------- ++AC_DEFUN([_LT_AC_TAGCONFIG], ++[AC_ARG_WITH([tags], ++ [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], ++ [include additional configurations @<:@automatic@:>@])], ++ [tagnames="$withval"]) ++ ++if test -f "$ltmain" && test -n "$tagnames"; then ++ if test ! -f "${ofile}"; then ++ AC_MSG_WARN([output file `$ofile' does not exist]) ++ fi ++ ++ if test -z "$LTCC"; then ++ eval "`$SHELL ${ofile} --config | grep '^LTCC='`" ++ if test -z "$LTCC"; then ++ AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) ++ else ++ AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) ++ fi ++ fi ++ if test -z "$LTCFLAGS"; then ++ eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" ++ fi ++ ++ # Extract list of available tagged configurations in $ofile. ++ # Note that this assumes the entire list is on one line. ++ available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=(.*$)/\1/' -e 's/"//g'` ++ ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for tagname in $tagnames; do ++ IFS="$lt_save_ifs" ++ # Check whether tagname contains only valid characters ++ case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in ++ "") ;; ++ *) AC_MSG_ERROR([invalid tag name: $tagname]) ++ ;; ++ esac ++ ++ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null ++ then ++ AC_MSG_ERROR([tag name "$tagname" already exists]) ++ fi ++ ++ # Update the list of available tags. ++ if test -n "$tagname"; then ++ echo appending configuration tag "$tagname" to $ofile ++ ++ case $tagname in ++ CXX) ++ if test -n "$CXX" && ( test "X$CXX" != "Xno" && ++ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || ++ (test "X$CXX" != "Xg++"))) ; then ++ AC_LIBTOOL_LANG_CXX_CONFIG ++ else ++ tagname="" ++ fi ++ ;; ++ ++ F77) ++ if test -n "$F77" && test "X$F77" != "Xno"; then ++ AC_LIBTOOL_LANG_F77_CONFIG ++ else ++ tagname="" ++ fi ++ ;; ++ ++ GCJ) ++ if test -n "$GCJ" && test "X$GCJ" != "Xno"; then ++ AC_LIBTOOL_LANG_GCJ_CONFIG ++ else ++ tagname="" ++ fi ++ ;; ++ ++ RC) ++ AC_LIBTOOL_LANG_RC_CONFIG ++ ;; ++ ++ *) ++ AC_MSG_ERROR([Unsupported tag name: $tagname]) ++ ;; ++ esac ++ ++ # Append the new tag name to the list of available tags. ++ if test -n "$tagname" ; then ++ available_tags="$available_tags $tagname" ++ fi ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ # Now substitute the updated list of available tags. ++ if eval "sed -e 's/^available_tags=.*$/available_tags="$available_tags"/' "$ofile" > "${ofile}T""; then ++ mv "${ofile}T" "$ofile" ++ chmod +x "$ofile" ++ else ++ rm -f "${ofile}T" ++ AC_MSG_ERROR([unable to update list of available tagged configurations.]) ++ fi ++fi ++])# _LT_AC_TAGCONFIG ++ ++ ++# AC_LIBTOOL_DLOPEN ++# ----------------- ++# enable checks for dlopen support ++AC_DEFUN([AC_LIBTOOL_DLOPEN], ++ [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) ++])# AC_LIBTOOL_DLOPEN ++ ++ ++# AC_LIBTOOL_WIN32_DLL ++# -------------------- ++# declare package support for building win32 DLLs ++AC_DEFUN([AC_LIBTOOL_WIN32_DLL], ++[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) ++])# AC_LIBTOOL_WIN32_DLL ++ ++ ++# AC_ENABLE_SHARED([DEFAULT]) ++# --------------------------- ++# implement the --enable-shared flag ++# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. ++AC_DEFUN([AC_ENABLE_SHARED], ++[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl ++AC_ARG_ENABLE([shared], ++ [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], ++ [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_shared=yes ;; ++ no) enable_shared=no ;; ++ *) ++ enable_shared=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_shared=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac], ++ [enable_shared=]AC_ENABLE_SHARED_DEFAULT) ++])# AC_ENABLE_SHARED ++ ++ ++# AC_DISABLE_SHARED ++# ----------------- ++# set the default shared flag to --disable-shared ++AC_DEFUN([AC_DISABLE_SHARED], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++AC_ENABLE_SHARED(no) ++])# AC_DISABLE_SHARED ++ ++ ++# AC_ENABLE_STATIC([DEFAULT]) ++# --------------------------- ++# implement the --enable-static flag ++# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. ++AC_DEFUN([AC_ENABLE_STATIC], ++[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl ++AC_ARG_ENABLE([static], ++ [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], ++ [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_static=yes ;; ++ no) enable_static=no ;; ++ *) ++ enable_static=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_static=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac], ++ [enable_static=]AC_ENABLE_STATIC_DEFAULT) ++])# AC_ENABLE_STATIC ++ ++ ++# AC_DISABLE_STATIC ++# ----------------- ++# set the default static flag to --disable-static ++AC_DEFUN([AC_DISABLE_STATIC], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++AC_ENABLE_STATIC(no) ++])# AC_DISABLE_STATIC ++ ++ ++# AC_ENABLE_FAST_INSTALL([DEFAULT]) ++# --------------------------------- ++# implement the --enable-fast-install flag ++# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. ++AC_DEFUN([AC_ENABLE_FAST_INSTALL], ++[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl ++AC_ARG_ENABLE([fast-install], ++ [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], ++ [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_fast_install=yes ;; ++ no) enable_fast_install=no ;; ++ *) ++ enable_fast_install=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_fast_install=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac], ++ [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) ++])# AC_ENABLE_FAST_INSTALL ++ ++ ++# AC_DISABLE_FAST_INSTALL ++# ----------------------- ++# set the default to --disable-fast-install ++AC_DEFUN([AC_DISABLE_FAST_INSTALL], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++AC_ENABLE_FAST_INSTALL(no) ++])# AC_DISABLE_FAST_INSTALL ++ ++ ++# AC_LIBTOOL_PICMODE([MODE]) ++# -------------------------- ++# implement the --with-pic flag ++# MODE is either `yes' or `no'. If omitted, it defaults to `both'. ++AC_DEFUN([AC_LIBTOOL_PICMODE], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++pic_mode=ifelse($#,1,$1,default) ++])# AC_LIBTOOL_PICMODE ++ ++ ++# AC_PROG_EGREP ++# ------------- ++# This is predefined starting with Autoconf 2.54, so this conditional ++# definition can be removed once we require Autoconf 2.54 or later. ++m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], ++[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], ++ [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 ++ then ac_cv_prog_egrep='grep -E' ++ else ac_cv_prog_egrep='egrep' ++ fi]) ++ EGREP=$ac_cv_prog_egrep ++ AC_SUBST([EGREP]) ++])]) ++ ++ ++# AC_PATH_TOOL_PREFIX ++# ------------------- ++# find a file program which can recognise shared library ++AC_DEFUN([AC_PATH_TOOL_PREFIX], ++[AC_REQUIRE([AC_PROG_EGREP])dnl ++AC_MSG_CHECKING([for $1]) ++AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, ++[case $MAGIC_CMD in ++[[\/*] | ?:[\/]*]) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++dnl $ac_dummy forces splitting on constant user-supplied paths. ++dnl POSIX.2 word splitting is done only on the output of word expansions, ++dnl not every word. This closes a longstanding sh security hole. ++ ac_dummy="ifelse([$2], , $PATH, [$2])" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/$1; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/$1" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic (.*)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd $file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <<EOF 1>&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac]) ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ AC_MSG_RESULT($MAGIC_CMD) ++else ++ AC_MSG_RESULT(no) ++fi ++])# AC_PATH_TOOL_PREFIX ++ ++ ++# AC_PATH_MAGIC ++# ------------- ++# find a file program which can recognise a shared library ++AC_DEFUN([AC_PATH_MAGIC], ++[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) ++if test -z "$lt_cv_path_MAGIC_CMD"; then ++ if test -n "$ac_tool_prefix"; then ++ AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) ++ else ++ MAGIC_CMD=: ++ fi ++fi ++])# AC_PATH_MAGIC ++ ++ ++# AC_PROG_LD ++# ---------- ++# find the pathname to the GNU or non-GNU linker ++AC_DEFUN([AC_PROG_LD], ++[AC_ARG_WITH([gnu-ld], ++ [AC_HELP_STRING([--with-gnu-ld], ++ [assume the C compiler uses GNU ld @<:@default=no@:>@])], ++ [test "$withval" = no || with_gnu_ld=yes], ++ [with_gnu_ld=no]) ++AC_REQUIRE([LT_AC_PROG_SED])dnl ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ AC_MSG_CHECKING([for ld used by $CC]) ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [[\/]]* | ?:[[\/]]*) ++ re_direlt='/[[^/]][[^/]]*/../' ++ # Canonicalize the pathname of ld ++ ac_prog=`echo $ac_prog| $SED 's%\\%/%g'` ++ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ AC_MSG_CHECKING([for GNU ld]) ++else ++ AC_MSG_CHECKING([for non-GNU ld]) ++fi ++AC_CACHE_VAL(lt_cv_path_LD, ++[if test -z "$LD"; then ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in ++ *GNU* | *'with BFD'*) ++ test "$with_gnu_ld" != no && break ++ ;; ++ *) ++ test "$with_gnu_ld" != yes && break ++ ;; ++ esac ++ fi ++ done ++ IFS="$lt_save_ifs" ++else ++ lt_cv_path_LD="$LD" # Let the user override the test with a path. ++fi]) ++LD="$lt_cv_path_LD" ++if test -n "$LD"; then ++ AC_MSG_RESULT($LD) ++else ++ AC_MSG_RESULT(no) ++fi ++test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in $PATH]) ++AC_PROG_LD_GNU ++])# AC_PROG_LD ++ ++ ++# AC_PROG_LD_GNU ++# -------------- ++AC_DEFUN([AC_PROG_LD_GNU], ++[AC_REQUIRE([AC_PROG_EGREP])dnl ++AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, ++[# I'd rather use --version here, but apparently some GNU lds only accept -v. ++case `$LD -v 2>&1 </dev/null` in ++*GNU* | *'with BFD'*) ++ lt_cv_prog_gnu_ld=yes ++ ;; ++*) ++ lt_cv_prog_gnu_ld=no ++ ;; ++esac]) ++with_gnu_ld=$lt_cv_prog_gnu_ld ++])# AC_PROG_LD_GNU ++ ++ ++# AC_PROG_LD_RELOAD_FLAG ++# ---------------------- ++# find reload flag for linker ++# -- PORTME Some linkers may need a different reload flag. ++AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], ++[AC_CACHE_CHECK([for $LD option to reload object files], ++ lt_cv_ld_reload_flag, ++ [lt_cv_ld_reload_flag='-r']) ++reload_flag=$lt_cv_ld_reload_flag ++case $reload_flag in ++"" | " "*) ;; ++*) reload_flag=" $reload_flag" ;; ++esac ++reload_cmds='$LD$reload_flag -o $output$reload_objs' ++case $host_os in ++ darwin*) ++ if test "$GCC" = yes; then ++ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' ++ else ++ reload_cmds='$LD$reload_flag -o $output$reload_objs' ++ fi ++ ;; ++esac ++])# AC_PROG_LD_RELOAD_FLAG ++ ++ ++# AC_DEPLIBS_CHECK_METHOD ++# ----------------------- ++# how to check for library dependencies ++# -- PORTME fill in with the dynamic library characteristics ++AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], ++[AC_CACHE_CHECK([how to recognise dependent libraries], ++lt_cv_deplibs_check_method, ++[lt_cv_file_magic_cmd='$MAGIC_CMD' ++lt_cv_file_magic_test_file= ++lt_cv_deplibs_check_method='unknown' ++# Need to set the preceding variable on all platforms that support ++# interlibrary dependencies. ++# 'none' -- dependencies not supported. ++# `unknown' -- same as none, but documents that we really don't know. ++# 'pass_all' -- all dependencies passed with no checks. ++# 'test_compile' -- check by making test program. ++# 'file_magic [[regex]]' -- check by looking for files in library path ++# which responds to the $file_magic_cmd with a given extended regex. ++# If you have `file' or equivalent on your system and you're not sure ++# whether `pass_all' will *always* work, you probably want this one. ++ ++case $host_os in ++aix4* | aix5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++beos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++bsdi[[45]]*) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' ++ lt_cv_file_magic_cmd='/usr/bin/file -L' ++ lt_cv_file_magic_test_file=/shlib/libc.so ++ ;; ++ ++cygwin*) ++ # func_win32_libid is a shell function defined in ltmain.sh ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ ;; ++ ++mingw* | pw32*) ++ # Base MSYS/MinGW do not provide the 'file' command needed by ++ # func_win32_libid shell function, so use a weaker test based on 'objdump'. ++ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ ;; ++ ++darwin* | rhapsody*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++freebsd* | kfreebsd*-gnu | dragonfly*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then ++ case $host_cpu in ++ i*86 ) ++ # Not sure whether the presence of OpenBSD here was a mistake. ++ # Let's accept both of them until this is cleared up. ++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ++ ;; ++ esac ++ else ++ lt_cv_deplibs_check_method=pass_all ++ fi ++ ;; ++ ++gnu*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++hpux10.20* | hpux11*) ++ lt_cv_file_magic_cmd=/usr/bin/file ++ case $host_cpu in ++ ia64*) ++ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' ++ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ++ ;; ++ hppa*64*) ++ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] ++ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ++ ;; ++ *) ++ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' ++ lt_cv_file_magic_test_file=/usr/lib/libc.sl ++ ;; ++ esac ++ ;; ++ ++interix3*) ++ # PIC code is broken on Interix 3.x, that's why |.a not |_pic.a here ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(.so|.a)$' ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $LD in ++ *-32|*"-32 ") libmagic=32-bit;; ++ *-n32|*"-n32 ") libmagic=N32;; ++ *-64|*"-64 ") libmagic=64-bit;; ++ *) libmagic=never-match;; ++ esac ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(.so.[[0-9]]+.[[0-9]]+|_pic.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(.so|_pic.a)$' ++ fi ++ ;; ++ ++newos6*) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=/usr/lib/libnls.so ++ ;; ++ ++nto-qnx*) ++ lt_cv_deplibs_check_method=unknown ++ ;; ++ ++openbsd*) ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(.so.[[0-9]]+.[[0-9]]+|.so|_pic.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(.so.[[0-9]]+.[[0-9]]+|_pic.a)$' ++ fi ++ ;; ++ ++osf3* | osf4* | osf5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++solaris*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv4 | sysv4.3*) ++ case $host_vendor in ++ motorola) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ++ ;; ++ ncr) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ sequent) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ++ ;; ++ sni) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" ++ lt_cv_file_magic_test_file=/lib/libc.so ++ ;; ++ siemens) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ pc) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ esac ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++esac ++]) ++file_magic_cmd=$lt_cv_file_magic_cmd ++deplibs_check_method=$lt_cv_deplibs_check_method ++test -z "$deplibs_check_method" && deplibs_check_method=unknown ++])# AC_DEPLIBS_CHECK_METHOD ++ ++ ++# AC_PROG_NM ++# ---------- ++# find the pathname to a BSD-compatible name lister ++AC_DEFUN([AC_PROG_NM], ++[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, ++[if test -n "$NM"; then ++ # Let the user override the test. ++ lt_cv_path_NM="$NM" ++else ++ lt_nm_to_check="${ac_tool_prefix}nm" ++ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then ++ lt_nm_to_check="$lt_nm_to_check nm" ++ fi ++ for lt_tmp_nm in $lt_nm_to_check; do ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ tmp_nm="$ac_dir/$lt_tmp_nm" ++ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then ++ # Check to see if the nm accepts a BSD-compat flag. ++ # Adding the `sed 1q' prevents false positives on HP-UX, which says: ++ # nm: unknown option "B" ignored ++ # Tru64's nm complains that /dev/null is an invalid object file ++ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in ++ */dev/null* | *'Invalid file or object type'*) ++ lt_cv_path_NM="$tmp_nm -B" ++ break ++ ;; ++ *) ++ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in ++ */dev/null*) ++ lt_cv_path_NM="$tmp_nm -p" ++ break ++ ;; ++ *) ++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but ++ continue # so that we can try to find one that supports BSD flags ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ done ++ IFS="$lt_save_ifs" ++ done ++ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm ++fi]) ++NM="$lt_cv_path_NM" ++])# AC_PROG_NM ++ ++ ++# AC_CHECK_LIBM ++# ------------- ++# check for math library ++AC_DEFUN([AC_CHECK_LIBM], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++LIBM= ++case $host in ++*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) ++ # These system don't have libm, or don't need it ++ ;; ++*-ncr-sysv4.3*) ++ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") ++ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ++ ;; ++*) ++ AC_CHECK_LIB(m, cos, LIBM="-lm") ++ ;; ++esac ++])# AC_CHECK_LIBM ++ ++ ++# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) ++# ----------------------------------- ++# sets LIBLTDL to the link flags for the libltdl convenience library and ++# LTDLINCL to the include flags for the libltdl header and adds ++# --enable-ltdl-convenience to the configure arguments. Note that ++# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, ++# it is assumed to be `libltdl'. LIBLTDL will be prefixed with ++# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' ++# (note the single quotes!). If your package is not flat and you're not ++# using automake, define top_builddir and top_srcdir appropriately in ++# the Makefiles. ++AC_DEFUN([AC_LIBLTDL_CONVENIENCE], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++ case $enable_ltdl_convenience in ++ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; ++ "") enable_ltdl_convenience=yes ++ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; ++ esac ++ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la ++ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) ++ # For backwards non-gettext consistent compatibility... ++ INCLTDL="$LTDLINCL" ++])# AC_LIBLTDL_CONVENIENCE ++ ++ ++# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) ++# ----------------------------------- ++# sets LIBLTDL to the link flags for the libltdl installable library and ++# LTDLINCL to the include flags for the libltdl header and adds ++# --enable-ltdl-install to the configure arguments. Note that ++# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, ++# and an installed libltdl is not found, it is assumed to be `libltdl'. ++# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with ++# '${top_srcdir}/' (note the single quotes!). If your package is not ++# flat and you're not using automake, define top_builddir and top_srcdir ++# appropriately in the Makefiles. ++# In the future, this macro may have to be called after AC_PROG_LIBTOOL. ++AC_DEFUN([AC_LIBLTDL_INSTALLABLE], ++[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl ++ AC_CHECK_LIB(ltdl, lt_dlinit, ++ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], ++ [if test x"$enable_ltdl_install" = xno; then ++ AC_MSG_WARN([libltdl not installed, but installation disabled]) ++ else ++ enable_ltdl_install=yes ++ fi ++ ]) ++ if test x"$enable_ltdl_install" = x"yes"; then ++ ac_configure_args="$ac_configure_args --enable-ltdl-install" ++ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la ++ LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) ++ else ++ ac_configure_args="$ac_configure_args --enable-ltdl-install=no" ++ LIBLTDL="-lltdl" ++ LTDLINCL= ++ fi ++ # For backwards non-gettext consistent compatibility... ++ INCLTDL="$LTDLINCL" ++])# AC_LIBLTDL_INSTALLABLE ++ ++ ++# AC_LIBTOOL_CXX ++# -------------- ++# enable support for C++ libraries ++AC_DEFUN([AC_LIBTOOL_CXX], ++[AC_REQUIRE([_LT_AC_LANG_CXX]) ++])# AC_LIBTOOL_CXX ++ ++ ++# _LT_AC_LANG_CXX ++# --------------- ++AC_DEFUN([_LT_AC_LANG_CXX], ++[AC_REQUIRE([AC_PROG_CXX]) ++AC_REQUIRE([_LT_AC_PROG_CXXCPP]) ++_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) ++])# _LT_AC_LANG_CXX ++ ++# _LT_AC_PROG_CXXCPP ++# ------------------ ++AC_DEFUN([_LT_AC_PROG_CXXCPP], ++[ ++AC_REQUIRE([AC_PROG_CXX]) ++if test -n "$CXX" && ( test "X$CXX" != "Xno" && ++ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || ++ (test "X$CXX" != "Xg++"))) ; then ++ AC_PROG_CXXCPP ++fi ++])# _LT_AC_PROG_CXXCPP ++ ++# AC_LIBTOOL_F77 ++# -------------- ++# enable support for Fortran 77 libraries ++AC_DEFUN([AC_LIBTOOL_F77], ++[AC_REQUIRE([_LT_AC_LANG_F77]) ++])# AC_LIBTOOL_F77 ++ ++ ++# _LT_AC_LANG_F77 ++# --------------- ++AC_DEFUN([_LT_AC_LANG_F77], ++[AC_REQUIRE([AC_PROG_F77]) ++_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) ++])# _LT_AC_LANG_F77 ++ ++ ++# AC_LIBTOOL_GCJ ++# -------------- ++# enable support for GCJ libraries ++AC_DEFUN([AC_LIBTOOL_GCJ], ++[AC_REQUIRE([_LT_AC_LANG_GCJ]) ++])# AC_LIBTOOL_GCJ ++ ++ ++# _LT_AC_LANG_GCJ ++# --------------- ++AC_DEFUN([_LT_AC_LANG_GCJ], ++[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], ++ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], ++ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], ++ [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], ++ [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], ++ [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) ++_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) ++])# _LT_AC_LANG_GCJ ++ ++ ++# AC_LIBTOOL_RC ++# ------------- ++# enable support for Windows resource files ++AC_DEFUN([AC_LIBTOOL_RC], ++[AC_REQUIRE([LT_AC_PROG_RC]) ++_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) ++])# AC_LIBTOOL_RC ++ ++ ++# AC_LIBTOOL_LANG_C_CONFIG ++# ------------------------ ++# Ensure that the configuration vars for the C compiler are ++# suitably defined. Those variables are subsequently used by ++# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. ++AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) ++AC_DEFUN([_LT_AC_LANG_C_CONFIG], ++[lt_save_CC="$CC" ++AC_LANG_PUSH(C) ++ ++# Source file extension for C test sources. ++ac_ext=c ++ ++# Object file extension for compiled C test sources. ++objext=o ++_LT_AC_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(){return(0);}\n' ++ ++_LT_AC_SYS_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) ++AC_LIBTOOL_PROG_COMPILER_PIC($1) ++AC_LIBTOOL_PROG_CC_C_O($1) ++AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) ++AC_LIBTOOL_PROG_LD_SHLIBS($1) ++AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) ++AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) ++AC_LIBTOOL_SYS_LIB_STRIP ++AC_LIBTOOL_DLOPEN_SELF ++ ++# Report which library types will actually be built ++AC_MSG_CHECKING([if libtool supports shared libraries]) ++AC_MSG_RESULT([$can_build_shared]) ++ ++AC_MSG_CHECKING([whether to build shared libraries]) ++test "$can_build_shared" = "no" && enable_shared=no ++ ++# On AIX, shared libraries and static libraries use the same namespace, and ++# are all built from PIC. ++case $host_os in ++aix3*) ++ test "$enable_shared" = yes && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~$RANLIB $lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ ++aix4* | aix5*) ++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then ++ test "$enable_shared" = yes && enable_static=no ++ fi ++ ;; ++esac ++AC_MSG_RESULT([$enable_shared]) ++ ++AC_MSG_CHECKING([whether to build static libraries]) ++# Make sure either enable_shared or enable_static is yes. ++test "$enable_shared" = yes || enable_static=yes ++AC_MSG_RESULT([$enable_static]) ++ ++AC_LIBTOOL_CONFIG($1) ++ ++AC_LANG_POP ++CC="$lt_save_CC" ++])# AC_LIBTOOL_LANG_C_CONFIG ++ ++ ++# AC_LIBTOOL_LANG_CXX_CONFIG ++# -------------------------- ++# Ensure that the configuration vars for the C compiler are ++# suitably defined. Those variables are subsequently used by ++# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. ++AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) ++AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], ++[AC_LANG_PUSH(C++) ++AC_REQUIRE([AC_PROG_CXX]) ++AC_REQUIRE([_LT_AC_PROG_CXXCPP]) ++ ++_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++_LT_AC_TAGVAR(allow_undefined_flag, $1)= ++_LT_AC_TAGVAR(always_export_symbols, $1)=no ++_LT_AC_TAGVAR(archive_expsym_cmds, $1)= ++_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= ++_LT_AC_TAGVAR(hardcode_direct, $1)=no ++_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= ++_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= ++_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= ++_LT_AC_TAGVAR(hardcode_minus_L, $1)=no ++_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++_LT_AC_TAGVAR(hardcode_automatic, $1)=no ++_LT_AC_TAGVAR(module_cmds, $1)= ++_LT_AC_TAGVAR(module_expsym_cmds, $1)= ++_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown ++_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_AC_TAGVAR(no_undefined_flag, $1)= ++_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ ++# Dependencies to place before and after the object being linked: ++_LT_AC_TAGVAR(predep_objects, $1)= ++_LT_AC_TAGVAR(postdep_objects, $1)= ++_LT_AC_TAGVAR(predeps, $1)= ++_LT_AC_TAGVAR(postdeps, $1)= ++_LT_AC_TAGVAR(compiler_lib_search_path, $1)= ++ ++# Source file extension for C++ test sources. ++ac_ext=cpp ++ ++# Object file extension for compiled C++ test sources. ++objext=o ++_LT_AC_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_AC_SYS_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_LD=$LD ++lt_save_GCC=$GCC ++GCC=$GXX ++lt_save_with_gnu_ld=$with_gnu_ld ++lt_save_path_LD=$lt_cv_path_LD ++if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then ++ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx ++else ++ $as_unset lt_cv_prog_gnu_ld ++fi ++if test -n "${lt_cv_path_LDCXX+set}"; then ++ lt_cv_path_LD=$lt_cv_path_LDCXX ++else ++ $as_unset lt_cv_path_LD ++fi ++test -z "${LDCXX+set}" || LD=$LDCXX ++CC=${CXX-"c++"} ++compiler=$CC ++_LT_AC_TAGVAR(compiler, $1)=$CC ++_LT_CC_BASENAME([$compiler]) ++ ++# We don't want -fno-exception wen compiling C++ code, so set the ++# no_builtin_flag separately ++if test "$GXX" = yes; then ++ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ++else ++ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= ++fi ++ ++if test "$GXX" = yes; then ++ # Set up default GNU C++ configuration ++ ++ AC_PROG_LD ++ ++ # Check if GNU C++ uses GNU ld as the underlying linker, since the ++ # archiving commands below assume that GNU ld is being used. ++ if test "$with_gnu_ld" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to ++ # investigate it a little bit more. (MM) ++ wlarc='${wl}' ++ ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ ++ grep 'no-whole-archive' > /dev/null; then ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ else ++ with_gnu_ld=no ++ wlarc= ++ ++ # A generic and very simple default shared library creation ++ # command for GNU C++ for the case where it uses the native ++ # linker, instead of GNU ld. If possible, this setting should ++ # overridden to take advantage of the native linker features on ++ # the platform it is being used on. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ fi ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "-L"' ++ ++else ++ GXX=no ++ with_gnu_ld=no ++ wlarc= ++fi ++ ++# PORTME: fill in a description of your system's C++ link characteristics ++AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ++_LT_AC_TAGVAR(ld_shlibs, $1)=yes ++case $host_os in ++ aix3*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ case $ld_flag in ++ *-brtl*) ++ aix_use_runtimelinking=yes ++ break ++ ;; ++ esac ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ _LT_AC_TAGVAR(archive_cmds, $1)='' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ++ if test "$GXX" = yes; then ++ case $host_os in aix4.[[012]]|aix4.[[012]].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ else ++ # We have old collect2 ++ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ _LT_AC_TAGVAR(always_export_symbols, $1)=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ _LT_AC_SYS_LIBPATH_AIX ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" ++ ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$CC"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"${wl}$exp_sym_flag:$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"${wl}$exp_sym_flag:$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ _LT_AC_SYS_LIBPATH_AIX ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ chorus*) ++ case $cc_basename in ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, ++ # as there is no search path for DLLs. ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_AC_TAGVAR(always_export_symbols, $1)=no ++ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[[012]]) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[[012]]) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ++ if test "$GXX" = yes ; then ++ lt_int_apple_cc_single_mod=no ++ output_verbose_link_cmd='echo' ++ if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then ++ lt_int_apple_cc_single_mod=yes ++ fi ++ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ fi ++ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ fi ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ freebsd[[12]]*) ++ # C++ shared libraries reported to be fairly broken before switch to ELF ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ freebsd-elf*) ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ ;; ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF ++ # conventions ++ _LT_AC_TAGVAR(ld_shlibs, $1)=yes ++ ;; ++ gnu*) ++ ;; ++ hpux9*) ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aCC*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ hpux10*|hpux11*) ++ if test $with_gnu_ld = no; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' ++ ;; ++ *) ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ ;; ++ esac ++ fi ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ *) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ;; ++ esac ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aCC*) ++ case $host_cpu in ++ hppa*64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test $with_gnu_ld = no; then ++ case $host_cpu in ++ hppa*64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ fi ++ else ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ interix3*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ ;; ++ irix5* | irix6*) ++ case $cc_basename in ++ CC*) ++ # SGI C++ ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -ar", where "CC" is the IRIX C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' ++ fi ++ fi ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ esac ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ linux*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '''s/([[^()0-9A-Za-z{}]])/\\\1/g'''`; templib=`echo $lib | $SED -e "s/${tempext}..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o $templib; mv $templib $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '''s/([[^()0-9A-Za-z{}]])/\\\1/g'''`; templib=`echo $lib | $SED -e "s/${tempext}..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o $templib ${wl}-retain-symbols-file,$export_symbols; mv $templib $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ++ ;; ++ icpc*) ++ # Intel C++ ++ with_gnu_ld=yes ++ # version 8.0 and above of icpc choke on multiply defined symbols ++ # if we add $predep_objects and $postdep_objects, however 7.1 and ++ # earlier do not add the objects themselves. ++ case `$CC -V 2>&1` in ++ *"Version 7."*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ *) # Version 8.0 or newer ++ tmp_idyn= ++ case $host_cpu in ++ ia64*) tmp_idyn=' -i_dynamic';; ++ esac ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ esac ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ++ ;; ++ pgCC*) ++ # Portland Group C++ compiler ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ ;; ++ cxx*) ++ # Compaq C++ ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' ++ ++ runpath_var=LD_RUN_PATH ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/(^.*ld.*)( .*ld .*$)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ esac ++ ;; ++ lynxos*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ m88k*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' ++ wlarc= ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ fi ++ # Workaround some broken pre-1.5 toolchains ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ++ ;; ++ openbsd2*) ++ # C++ shared libraries are fairly broken ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ openbsd*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ fi ++ output_verbose_link_cmd='echo' ++ ;; ++ osf3*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '''s/([[^()0-9A-Za-z{}]])/\\\1/g'''`; templib=`echo $lib | $SED -e "s/${tempext}..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o $templib; mv $templib $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ++ ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ cxx*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/(^.*ld.*)( .*ld.*$)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '''s/([[^()0-9A-Za-z{}]])/\\\1/g'''`; templib=`echo $lib | $SED -e "s/${tempext}..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o $templib; mv $templib $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Archives containing C++ object files must be created using ++ # the KAI C++ compiler. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ cxx*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved *' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\n" -exported_symbol "$i" >> $lib.exp; done~ ++ echo "-hidden">> $lib.exp~ ++ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ ++ $rm $lib.exp' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/(^.*ld.*)( .*ld.*$)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ psos*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ lcc*) ++ # Lucid ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ # The C++ compiler is used as linker so we must use $wl ++ # flag to pass the commands to the underlying system ++ # linker. We must also pass each convience library through ++ # to the system linker between allextract/defaultextract. ++ # The C++ compiler will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}-z ${wl}defaultextract' ++ ;; ++ esac ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ++ output_verbose_link_cmd='echo' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ ++ # The C++ compiler must be used to create the archive. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ++ ;; ++ *) ++ # GNU C++ compiler with Solaris linker ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' ++ if $CC --version | grep -v '^2.7' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "-L"" ++ else ++ # g++ 2.7 appears to require `-G' NOT `-shared' on this ++ # platform. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "-L"" ++ fi ++ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' ++ fi ++ ;; ++ esac ++ ;; ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) ++ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ # For security reasons, it is highly recommended that you always ++ # use absolute paths for naming shared libraries, and exclude the ++ # DT_RUNPATH tag from executables and libraries. But doing so ++ # requires that you compile everything twice, which is a pain. ++ # So that behaviour is only enabled if SCOABSPATH is set to a ++ # non-empty value in the environment. Most likely only useful for ++ # creating official distributions of packages. ++ # This is a hack until libtool officially supports absolute path ++ # names for shared libraries. ++ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ vxworks*) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++esac ++AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) ++test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no ++ ++_LT_AC_TAGVAR(GCC, $1)="$GXX" ++_LT_AC_TAGVAR(LD, $1)="$LD" ++ ++AC_LIBTOOL_POSTDEP_PREDEP($1) ++AC_LIBTOOL_PROG_COMPILER_PIC($1) ++AC_LIBTOOL_PROG_CC_C_O($1) ++AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) ++AC_LIBTOOL_PROG_LD_SHLIBS($1) ++AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) ++AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) ++ ++AC_LIBTOOL_CONFIG($1) ++ ++AC_LANG_POP ++CC=$lt_save_CC ++LDCXX=$LD ++LD=$lt_save_LD ++GCC=$lt_save_GCC ++with_gnu_ldcxx=$with_gnu_ld ++with_gnu_ld=$lt_save_with_gnu_ld ++lt_cv_path_LDCXX=$lt_cv_path_LD ++lt_cv_path_LD=$lt_save_path_LD ++lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld ++lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ++])# AC_LIBTOOL_LANG_CXX_CONFIG ++ ++# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) ++# ------------------------------------ ++# Figure out "hidden" library dependencies from verbose ++# compiler output when linking a shared library. ++# Parse the compiler output and extract the necessary ++# objects, libraries and library flags. ++AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ ++dnl we can't use the lt_simple_compile_test_code here, ++dnl because it contains code intended for an executable, ++dnl not a library. It's possible we should let each ++dnl tag define a new lt_????_link_test_code variable, ++dnl but it's only used here... ++ifelse([$1],[],[cat > conftest.$ac_ext <<EOF ++int a; ++void foo (void) { a = 0; } ++EOF ++],[$1],[CXX],[cat > conftest.$ac_ext <<EOF ++class Foo ++{ ++public: ++ Foo (void) { a = 0; } ++private: ++ int a; ++}; ++EOF ++],[$1],[F77],[cat > conftest.$ac_ext <<EOF ++ subroutine foo ++ implicit none ++ integer*4 a ++ a=0 ++ return ++ end ++EOF ++],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF ++public class foo { ++ private int a; ++ public void bar (void) { ++ a = 0; ++ } ++}; ++EOF ++]) ++dnl Parse the compiler output and extract the necessary ++dnl objects, libraries and library flags. ++if AC_TRY_EVAL(ac_compile); then ++ # Parse the compiler output and extract the necessary ++ # objects, libraries and library flags. ++ ++ # Sentinel used to keep track of whether or not we are before ++ # the conftest object file. ++ pre_test_object_deps_done=no ++ ++ # The `*' in the case matches for architectures that use `case' in ++ # $output_verbose_cmd can trigger glob expansion during the loop ++ # eval without this substitution. ++ output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` ++ ++ for p in `eval $output_verbose_link_cmd`; do ++ case $p in ++ ++ -L* | -R* | -l*) ++ # Some compilers place space between "-{L,R}" and the path. ++ # Remove the space. ++ if test $p = "-L" \ ++ || test $p = "-R"; then ++ prev=$p ++ continue ++ else ++ prev= ++ fi ++ ++ if test "$pre_test_object_deps_done" = no; then ++ case $p in ++ -L* | -R*) ++ # Internal compiler library paths should come after those ++ # provided the user. The postdeps already come after the ++ # user supplied libs so there is no need to process them. ++ if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then ++ _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" ++ else ++ _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" ++ fi ++ ;; ++ # The "-l" case would never come before the object being ++ # linked, so don't bother handling this case. ++ esac ++ else ++ if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then ++ _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}" ++ else ++ _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}" ++ fi ++ fi ++ ;; ++ ++ *.$objext) ++ # This assumes that the test object file only shows up ++ # once in the compiler output. ++ if test "$p" = "conftest.$objext"; then ++ pre_test_object_deps_done=yes ++ continue ++ fi ++ ++ if test "$pre_test_object_deps_done" = no; then ++ if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then ++ _LT_AC_TAGVAR(predep_objects, $1)="$p" ++ else ++ _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p" ++ fi ++ else ++ if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then ++ _LT_AC_TAGVAR(postdep_objects, $1)="$p" ++ else ++ _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p" ++ fi ++ fi ++ ;; ++ ++ *) ;; # Ignore the rest. ++ ++ esac ++ done ++ ++ # Clean up. ++ rm -f a.out a.exe ++else ++ echo "libtool.m4: error: problem compiling $1 test program" ++fi ++ ++$rm -f confest.$objext ++ ++# PORTME: override above test on systems where it is broken ++ifelse([$1],[CXX], ++[case $host_os in ++interix3*) ++ # Interix 3.5 installs completely hosed .la files for C++, so rather than ++ # hack all around it, let's just trust "g++" to DTRT. ++ _LT_AC_TAGVAR(predep_objects,$1)= ++ _LT_AC_TAGVAR(postdep_objects,$1)= ++ _LT_AC_TAGVAR(postdeps,$1)= ++ ;; ++ ++solaris*) ++ case $cc_basename in ++ CC*) ++ # Adding this requires a known-good setup of shared libraries for ++ # Sun compiler versions before 5.6, else PIC objects from an old ++ # archive will be linked into the output, leading to subtle bugs. ++ _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun' ++ ;; ++ esac ++ ;; ++esac ++]) ++ ++case " $_LT_AC_TAGVAR(postdeps, $1) " in ++*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; ++esac ++])# AC_LIBTOOL_POSTDEP_PREDEP ++ ++# AC_LIBTOOL_LANG_F77_CONFIG ++# -------------------------- ++# Ensure that the configuration vars for the C compiler are ++# suitably defined. Those variables are subsequently used by ++# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. ++AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)]) ++AC_DEFUN([_LT_AC_LANG_F77_CONFIG], ++[AC_REQUIRE([AC_PROG_F77]) ++AC_LANG_PUSH(Fortran 77) ++ ++_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++_LT_AC_TAGVAR(allow_undefined_flag, $1)= ++_LT_AC_TAGVAR(always_export_symbols, $1)=no ++_LT_AC_TAGVAR(archive_expsym_cmds, $1)= ++_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= ++_LT_AC_TAGVAR(hardcode_direct, $1)=no ++_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= ++_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= ++_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= ++_LT_AC_TAGVAR(hardcode_minus_L, $1)=no ++_LT_AC_TAGVAR(hardcode_automatic, $1)=no ++_LT_AC_TAGVAR(module_cmds, $1)= ++_LT_AC_TAGVAR(module_expsym_cmds, $1)= ++_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown ++_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_AC_TAGVAR(no_undefined_flag, $1)= ++_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ ++# Source file extension for f77 test sources. ++ac_ext=f ++ ++# Object file extension for compiled f77 test sources. ++objext=o ++_LT_AC_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code=" subroutine t\n return\n end\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code=" program t\n end\n" ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_AC_SYS_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC="$CC" ++CC=${F77-"f77"} ++compiler=$CC ++_LT_AC_TAGVAR(compiler, $1)=$CC ++_LT_CC_BASENAME([$compiler]) ++ ++AC_MSG_CHECKING([if libtool supports shared libraries]) ++AC_MSG_RESULT([$can_build_shared]) ++ ++AC_MSG_CHECKING([whether to build shared libraries]) ++test "$can_build_shared" = "no" && enable_shared=no ++ ++# On AIX, shared libraries and static libraries use the same namespace, and ++# are all built from PIC. ++case $host_os in ++aix3*) ++ test "$enable_shared" = yes && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~$RANLIB $lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++aix4* | aix5*) ++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then ++ test "$enable_shared" = yes && enable_static=no ++ fi ++ ;; ++esac ++AC_MSG_RESULT([$enable_shared]) ++ ++AC_MSG_CHECKING([whether to build static libraries]) ++# Make sure either enable_shared or enable_static is yes. ++test "$enable_shared" = yes || enable_static=yes ++AC_MSG_RESULT([$enable_static]) ++ ++_LT_AC_TAGVAR(GCC, $1)="$G77" ++_LT_AC_TAGVAR(LD, $1)="$LD" ++ ++AC_LIBTOOL_PROG_COMPILER_PIC($1) ++AC_LIBTOOL_PROG_CC_C_O($1) ++AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) ++AC_LIBTOOL_PROG_LD_SHLIBS($1) ++AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) ++AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) ++ ++AC_LIBTOOL_CONFIG($1) ++ ++AC_LANG_POP ++CC="$lt_save_CC" ++])# AC_LIBTOOL_LANG_F77_CONFIG ++ ++ ++# AC_LIBTOOL_LANG_GCJ_CONFIG ++# -------------------------- ++# Ensure that the configuration vars for the C compiler are ++# suitably defined. Those variables are subsequently used by ++# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. ++AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)]) ++AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG], ++[AC_LANG_SAVE ++ ++# Source file extension for Java test sources. ++ac_ext=java ++ ++# Object file extension for compiled Java test sources. ++objext=o ++_LT_AC_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="class foo {}\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_AC_SYS_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC="$CC" ++CC=${GCJ-"gcj"} ++compiler=$CC ++_LT_AC_TAGVAR(compiler, $1)=$CC ++_LT_CC_BASENAME([$compiler]) ++ ++# GCJ did not exist at the time GCC didn't implicitly link libc in. ++_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ ++_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++ ++AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) ++AC_LIBTOOL_PROG_COMPILER_PIC($1) ++AC_LIBTOOL_PROG_CC_C_O($1) ++AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) ++AC_LIBTOOL_PROG_LD_SHLIBS($1) ++AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) ++AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) ++ ++AC_LIBTOOL_CONFIG($1) ++ ++AC_LANG_RESTORE ++CC="$lt_save_CC" ++])# AC_LIBTOOL_LANG_GCJ_CONFIG ++ ++ ++# AC_LIBTOOL_LANG_RC_CONFIG ++# ------------------------- ++# Ensure that the configuration vars for the Windows resource compiler are ++# suitably defined. Those variables are subsequently used by ++# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. ++AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)]) ++AC_DEFUN([_LT_AC_LANG_RC_CONFIG], ++[AC_LANG_SAVE ++ ++# Source file extension for RC test sources. ++ac_ext=rc ++ ++# Object file extension for compiled RC test sources. ++objext=o ++_LT_AC_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code="$lt_simple_compile_test_code" ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_AC_SYS_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC="$CC" ++CC=${RC-"windres"} ++compiler=$CC ++_LT_AC_TAGVAR(compiler, $1)=$CC ++_LT_CC_BASENAME([$compiler]) ++_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes ++ ++AC_LIBTOOL_CONFIG($1) ++ ++AC_LANG_RESTORE ++CC="$lt_save_CC" ++])# AC_LIBTOOL_LANG_RC_CONFIG ++ ++ ++# AC_LIBTOOL_CONFIG([TAGNAME]) ++# ---------------------------- ++# If TAGNAME is not passed, then create an initial libtool script ++# with a default configuration from the untagged config vars. Otherwise ++# add code to config.status for appending the configuration named by ++# TAGNAME from the matching tagged config vars. ++AC_DEFUN([AC_LIBTOOL_CONFIG], ++[# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ _LT_AC_TAGVAR(compiler, $1) \ ++ _LT_AC_TAGVAR(CC, $1) \ ++ _LT_AC_TAGVAR(LD, $1) \ ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \ ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \ ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \ ++ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \ ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \ ++ _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \ ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \ ++ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \ ++ _LT_AC_TAGVAR(old_archive_cmds, $1) \ ++ _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \ ++ _LT_AC_TAGVAR(predep_objects, $1) \ ++ _LT_AC_TAGVAR(postdep_objects, $1) \ ++ _LT_AC_TAGVAR(predeps, $1) \ ++ _LT_AC_TAGVAR(postdeps, $1) \ ++ _LT_AC_TAGVAR(compiler_lib_search_path, $1) \ ++ _LT_AC_TAGVAR(archive_cmds, $1) \ ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1) \ ++ _LT_AC_TAGVAR(postinstall_cmds, $1) \ ++ _LT_AC_TAGVAR(postuninstall_cmds, $1) \ ++ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \ ++ _LT_AC_TAGVAR(allow_undefined_flag, $1) \ ++ _LT_AC_TAGVAR(no_undefined_flag, $1) \ ++ _LT_AC_TAGVAR(export_symbols_cmds, $1) \ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \ ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \ ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \ ++ _LT_AC_TAGVAR(hardcode_automatic, $1) \ ++ _LT_AC_TAGVAR(module_cmds, $1) \ ++ _LT_AC_TAGVAR(module_expsym_cmds, $1) \ ++ _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \ ++ _LT_AC_TAGVAR(exclude_expsyms, $1) \ ++ _LT_AC_TAGVAR(include_expsyms, $1); do ++ ++ case $var in ++ _LT_AC_TAGVAR(old_archive_cmds, $1) | \ ++ _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \ ++ _LT_AC_TAGVAR(archive_cmds, $1) | \ ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \ ++ _LT_AC_TAGVAR(module_cmds, $1) | \ ++ _LT_AC_TAGVAR(module_expsym_cmds, $1) | \ ++ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \ ++ _LT_AC_TAGVAR(export_symbols_cmds, $1) | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$double_quote_subst" -e "$sed_quote_subst" -e "$delay_variable_subst"`\"" ++ ;; ++ *) ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$sed_quote_subst"`\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'[$]0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'` ++ ;; ++ esac ++ ++ifelse([$1], [], ++ [cfgfile="${ofile}T" ++ trap "$rm "$cfgfile"; exit 1" 1 2 15 ++ $rm -f "$cfgfile" ++ AC_MSG_NOTICE([creating $ofile])], ++ [cfgfile="$ofile"]) ++ ++ cat <<__EOF__ >> "$cfgfile" ++ifelse([$1], [], ++[#! $SHELL ++ ++# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. ++# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) ++# NOTE: Changes made to this file will be lost: look at ltmain.sh. ++# ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 ++# Free Software Foundation, Inc. ++# ++# This file is part of GNU Libtool: ++# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++# A sed program that does not truncate output. ++SED=$lt_SED ++ ++# Sed that helps us avoid accidentally triggering echo(1) options like -n. ++Xsed="$SED -e 1s/^X//" ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++# The names of the tagged configurations supported by this script. ++available_tags= ++ ++# ### BEGIN LIBTOOL CONFIG], ++[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$_LT_AC_TAGVAR(GCC, $1) ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_[]_LT_AC_TAGVAR(LD, $1) ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) ++archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) ++module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode $libdir into a binary during linking. ++# This must work even if $libdir does not exist. ++hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) ++ ++# If ld is used when linking, flag to hardcode $libdir into ++# a binary during linking. This must work even if $libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=$lt_sys_lib_search_path_spec ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable $srcfile for the compiler. ++fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) ++ ++ifelse([$1],[], ++[# ### END LIBTOOL CONFIG], ++[# ### END LIBTOOL TAG CONFIG: $tagname]) ++ ++__EOF__ ++ ++ifelse([$1],[], [ ++ case $host_os in ++ aix3*) ++ cat <<\EOF >> "$cfgfile" ++ ++# AIX sometimes has problems with the GCC collect2 program. For some ++# reason, if we set the COLLECT_NAMES environment variable, the problems ++# vanish in a puff of smoke. ++if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++fi ++EOF ++ ;; ++ esac ++ ++ # We use sed instead of cat because bash on DJGPP gets confused if ++ # if finds mixed CR/LF and LF-only lines. Since sed operates in ++ # text mode, it properly converts lines to CR/LF. This bash problem ++ # is reportedly fixed, but why not run on old versions too? ++ sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) ++ ++ mv -f "$cfgfile" "$ofile" || \ ++ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") ++ chmod +x "$ofile" ++]) ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++])# AC_LIBTOOL_CONFIG ++ ++ ++# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) ++# ------------------------------------------- ++AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], ++[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl ++ ++_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= ++ ++if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ++ ++ AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], ++ lt_cv_prog_compiler_rtti_exceptions, ++ [-fno-rtti -fno-exceptions], [], ++ [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) ++fi ++])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI ++ ++ ++# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE ++# --------------------------------- ++AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], ++[AC_REQUIRE([AC_CANONICAL_HOST]) ++AC_REQUIRE([AC_PROG_NM]) ++AC_REQUIRE([AC_OBJEXT]) ++# Check for command to grab the raw symbol name followed by C symbol from nm. ++AC_MSG_CHECKING([command to parse $NM output from $compiler object]) ++AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], ++[ ++# These are sane defaults that work on at least a few old systems. ++# [They come from Ultrix. What could be older than Ultrix?!! ;)] ++ ++# Character class describing NM global symbol codes. ++symcode='[[BCDEGRST]]' ++ ++# Regexp to match symbols that can be accessed directly from C. ++sympat='([[_A-Za-z]][[_A-Za-z0-9]]*)' ++ ++# Transform an extracted symbol line into a proper C declaration ++lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* (.*)$/extern int \1;/p'" ++ ++# Transform an extracted symbol line into symbol name and symbol address ++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: ([[^ ]]*) $/ {\"\1\", (lt_ptr) 0},/p' -e 's/^$symcode ([[^ ]]*) ([[^ ]]*)$/ {"\2", (lt_ptr) &\2},/p'" ++ ++# Define system-specific variables. ++case $host_os in ++aix*) ++ symcode='[[BCDT]]' ++ ;; ++cygwin* | mingw* | pw32*) ++ symcode='[[ABCDGISTW]]' ++ ;; ++hpux*) # Its linker distinguishes data from code symbols ++ if test "$host_cpu" = ia64; then ++ symcode='[[ABCDEGRST]]' ++ fi ++ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* (.*)$/extern int \1();/p' -e 's/^$symcode* .* (.*)$/extern char \1;/p'" ++ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: ([[^ ]]*) $/ {\"\1\", (lt_ptr) 0},/p' -e 's/^$symcode* ([[^ ]]*) ([[^ ]]*)$/ {"\2", (lt_ptr) &\2},/p'" ++ ;; ++linux*) ++ if test "$host_cpu" = ia64; then ++ symcode='[[ABCDGIRSTW]]' ++ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* (.*)$/extern int \1();/p' -e 's/^$symcode* .* (.*)$/extern char \1;/p'" ++ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: ([[^ ]]*) $/ {\"\1\", (lt_ptr) 0},/p' -e 's/^$symcode* ([[^ ]]*) ([[^ ]]*)$/ {"\2", (lt_ptr) &\2},/p'" ++ fi ++ ;; ++irix* | nonstopux*) ++ symcode='[[BCDEGRST]]' ++ ;; ++osf*) ++ symcode='[[BCDEGQRST]]' ++ ;; ++solaris*) ++ symcode='[[BDRT]]' ++ ;; ++sco3.2v5*) ++ symcode='[[DT]]' ++ ;; ++sysv4.2uw2*) ++ symcode='[[DT]]' ++ ;; ++sysv5* | sco5v6* | unixware* | OpenUNIX*) ++ symcode='[[ABDT]]' ++ ;; ++sysv4) ++ symcode='[[DFNSTU]]' ++ ;; ++esac ++ ++# Handle CRLF in mingw tool chain ++opt_cr= ++case $build_os in ++mingw*) ++ opt_cr=`echo 'x{0,1}' | tr x '\015'` # option cr in regexp ++ ;; ++esac ++ ++# If we're using GNU nm, then use its standard symbol codes. ++case `$NM -V 2>&1` in ++*GNU* | *'with BFD'*) ++ symcode='[[ABCDGIRSTW]]' ;; ++esac ++ ++# Try without a prefix undercore, then with it. ++for ac_symprfx in "" "_"; do ++ ++ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. ++ symxfrm="\1 $ac_symprfx\2 \2" ++ ++ # Write the raw and C identifiers. ++ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]($symcode$symcode*)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" ++ ++ # Check to see that the pipe works correctly. ++ pipe_works=no ++ ++ rm -f conftest* ++ cat > conftest.$ac_ext <<EOF ++#ifdef __cplusplus ++extern "C" { ++#endif ++char nm_test_var; ++void nm_test_func(){} ++#ifdef __cplusplus ++} ++#endif ++int main(){nm_test_var='a';nm_test_func();return(0);} ++EOF ++ ++ if AC_TRY_EVAL(ac_compile); then ++ # Now try to grab the symbols. ++ nlist=conftest.nm ++ if AC_TRY_EVAL(NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist) && test -s "$nlist"; then ++ # Try sorting and uniquifying the output. ++ if sort "$nlist" | uniq > "$nlist"T; then ++ mv -f "$nlist"T "$nlist" ++ else ++ rm -f "$nlist"T ++ fi ++ ++ # Make sure that we snagged all the symbols we need. ++ if grep ' nm_test_var$' "$nlist" >/dev/null; then ++ if grep ' nm_test_func$' "$nlist" >/dev/null; then ++ cat <<EOF > conftest.$ac_ext ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++EOF ++ # Now generate the symbol file. ++ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' ++ ++ cat <<EOF >> conftest.$ac_ext ++#if defined (__STDC__) && __STDC__ ++# define lt_ptr_t void * ++#else ++# define lt_ptr_t char * ++# define const ++#endif ++ ++/* The mapping between symbol names and symbols. */ ++const struct { ++ const char *name; ++ lt_ptr_t address; ++} ++lt_preloaded_symbols[[]] = ++{ ++EOF ++ $SED "s/^$symcode$symcode* (.*) (.*)$/ {"\2", (lt_ptr_t) &\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext ++ cat <<\EOF >> conftest.$ac_ext ++ {0, (lt_ptr_t) 0} ++}; ++ ++#ifdef __cplusplus ++} ++#endif ++EOF ++ # Now try linking the two files. ++ mv conftest.$ac_objext conftstm.$ac_objext ++ lt_save_LIBS="$LIBS" ++ lt_save_CFLAGS="$CFLAGS" ++ LIBS="conftstm.$ac_objext" ++ CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" ++ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then ++ pipe_works=yes ++ fi ++ LIBS="$lt_save_LIBS" ++ CFLAGS="$lt_save_CFLAGS" ++ else ++ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD ++ cat conftest.$ac_ext >&5 ++ fi ++ rm -f conftest* conftst* ++ ++ # Do not use the global_symbol_pipe unless it works. ++ if test "$pipe_works" = yes; then ++ break ++ else ++ lt_cv_sys_global_symbol_pipe= ++ fi ++done ++]) ++if test -z "$lt_cv_sys_global_symbol_pipe"; then ++ lt_cv_sys_global_symbol_to_cdecl= ++fi ++if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then ++ AC_MSG_RESULT(failed) ++else ++ AC_MSG_RESULT(ok) ++fi ++]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE ++ ++ ++# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) ++# --------------------------------------- ++AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], ++[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= ++_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= ++ ++AC_MSG_CHECKING([for $compiler option to produce PIC]) ++ ifelse([$1],[CXX],[ ++ # C++ specific cases for pic, static, wl, etc. ++ if test "$GXX" = yes; then ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ ;; ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ mingw* | os2* | pw32*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ++ ;; ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ ;; ++ *djgpp*) ++ # DJGPP does not support shared libraries at all ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ ;; ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic ++ fi ++ ;; ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ else ++ case $host_os in ++ aix4* | aix5*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ else ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ chorus*) ++ case $cc_basename in ++ cxch68*) ++ # Green Hills C++ Compiler ++ # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ++ ;; ++ esac ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ ;; ++ esac ++ ;; ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ # FreeBSD uses GNU C++ ++ ;; ++ hpux9* | hpux10* | hpux11*) ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ++ if test "$host_cpu" != ia64; then ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ fi ++ ;; ++ aCC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ ;; ++ esac ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ interix*) ++ # This is c89, which is MS Visual C++ (no shared libs) ++ # Anyone wants to do a port? ++ ;; ++ irix5* | irix6* | nonstopux*) ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ # CC pic flag -KPIC is the default. ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ linux*) ++ case $cc_basename in ++ KCC*) ++ # KAI C++ Compiler ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ icpc* | ecpc*) ++ # Intel C++ ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ pgCC*) ++ # Portland Group C++ compiler. ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ cxx*) ++ # Compaq C++ ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ lynxos*) ++ ;; ++ m88k*) ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ netbsd*) ++ ;; ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ cxx*) ++ # Digital/Compaq C++ ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ psos*) ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ lcc*) ++ # Lucid ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ case $cc_basename in ++ CC*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ esac ++ ;; ++ vxworks*) ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ esac ++ fi ++], ++[ ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ ;; ++ ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ ;; ++ ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ enable_shared=no ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic ++ fi ++ ;; ++ ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ else ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ ;; ++ esac ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # PIC (with -KPIC) is the default. ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ newsos6) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ icc* | ecc*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ccc*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # All Alpha code is PIC. ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ esac ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # All OSF/1 code is PIC. ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ solaris*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ unicos*) ++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ ++ uts4*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ esac ++ fi ++]) ++AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then ++ AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], ++ _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), ++ [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], ++ [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in ++ "" | " "*) ;; ++ *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; ++ esac], ++ [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ++ ;; ++ *) ++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag="$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)" ++AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], ++ _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), ++ $lt_tmp_static_flag, ++ [], ++ [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) ++]) ++ ++ ++# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) ++# ------------------------------------ ++# See if the linker supports building shared libraries. ++AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], ++[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ++ifelse([$1],[CXX],[ ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '''s/.* //''' | sort | uniq > $export_symbols' ++ case $host_os in ++ aix4* | aix5*) ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '''{ if ((([$]2 == "T") || ([$]2 == "D") || ([$]2 == "B")) && ([substr]([$]3,1,1) != ".")) { print [$]3 } }''' | sort -u > $export_symbols' ++ else ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '''{ if ((([$]2 == "T") || ([$]2 == "D") || ([$]2 == "B")) && ([substr]([$]3,1,1) != ".")) { print [$]3 } }''' | sort -u > $export_symbols' ++ fi ++ ;; ++ pw32*) ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ++ ;; ++ cygwin* | mingw*) ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '''/^[[BCDGRS]] /s/.* ([[^ ]]*)/\1 DATA/;/^.* __nm__/s/^.* __nm__([[^ ]]*) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //''' | sort | uniq > $export_symbols' ++ ;; ++ *) ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '''s/.* //''' | sort | uniq > $export_symbols' ++ ;; ++ esac ++],[ ++ runpath_var= ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)= ++ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ _LT_AC_TAGVAR(archive_cmds, $1)= ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)= ++ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= ++ _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++ _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown ++ _LT_AC_TAGVAR(hardcode_automatic, $1)=no ++ _LT_AC_TAGVAR(module_cmds, $1)= ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)= ++ _LT_AC_TAGVAR(always_export_symbols, $1)=no ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '''s/.* //''' | sort | uniq > $export_symbols' ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ _LT_AC_TAGVAR(include_expsyms, $1)= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ extract_expsyms_cmds= ++ # Just being paranoid about ensuring that cc_basename is set. ++ _LT_CC_BASENAME([$compiler]) ++ case $host_os in ++ cygwin* | mingw* | pw32*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ _LT_AC_TAGVAR(ld_shlibs, $1)=yes ++ if test "$with_gnu_ld" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix3* | aix4* | aix5*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ cat <<EOF 1>&2 ++ ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. ++ ++EOF ++ fi ++ ;; ++ ++ amigaos*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ ++ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports ++ # that the semantics of dynamic libraries on AmigaOS, at least up ++ # to version 4, is to share data among multiple programs linked ++ # with the same dynamic library. Since this doesn't match the ++ # behavior of shared libraries on other platforms, we can't use ++ # them. ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, ++ # as there is no search path for DLLs. ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_AC_TAGVAR(always_export_symbols, $1)=no ++ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '''/^[[BCDGRS]] /s/.* ([[^ ]]*)/\1 DATA/''' | $SED -e '''/^[[AITW]] /s/.* //''' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ interix3*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ tmp_addflag= ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ esac ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test $supports_anon_versioning = yes; then ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/(.*)/\1;/" >> $output_objdir/$libname.ver~ ++ $echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | grep 'BFD 2.8' > /dev/null; then ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ cat <<EOF 1>&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++EOF ++ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,${SCOABSPATH:+${install_libdir}/}$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ++ if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then ++ runpath_var= ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_AC_TAGVAR(always_export_symbols, $1)=yes ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported ++ fi ++ ;; ++ ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '''{ if ((([$]2 == "T") || ([$]2 == "D") || ([$]2 == "B")) && ([substr]([$]3,1,1) != ".")) { print [$]3 } }''' | sort -u > $export_symbols' ++ else ++ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '''{ if ((([$]2 == "T") || ([$]2 == "D") || ([$]2 == "B")) && ([substr]([$]3,1,1) != ".")) { print [$]3 } }''' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ _LT_AC_TAGVAR(archive_cmds, $1)='' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[[012]]|aix4.[[012]].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ else ++ # We have old collect2 ++ _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ _LT_AC_TAGVAR(always_export_symbols, $1)=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ _LT_AC_SYS_LIBPATH_AIX ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$CC"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"${wl}$exp_sym_flag:$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"${wl}$exp_sym_flag:$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ _LT_AC_SYS_LIBPATH_AIX ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ # see comment about different semantics on the GNU ld section ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ bsdi[[45]]*) ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '''s/ -lc$//'''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' ++ # FIXME: Should let the user specify the lib program. ++ _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' ++ _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' ++ _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[[012]]) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[[012]]) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ if test "$GCC" = yes ; then ++ output_verbose_link_cmd='echo' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ freebsd1*) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ *) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ newsos6) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ openbsd*) ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ++ else ++ case $host_os in ++ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ ;; ++ *) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ ;; ++ ++ os2*) ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION "$libname"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved *' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}*' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ++ else ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved *' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\n" -exported_symbol "$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ ++ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ ++ solaris*) ++ _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' ++ else ++ wlarc='' ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ # The compiler driver will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl, iff we do not link with $LD. ++ # Luckily, gcc supports the same syntax we need for Sun Studio. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ case $wlarc in ++ '') ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; ++ *) ++ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}-z ${wl}defaultextract' ;; ++ esac ;; ++ esac ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes ++ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no ++ ;; ++ motorola) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ sysv4.3*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ _LT_AC_TAGVAR(ld_shlibs, $1)=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*) ++ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *) ++ _LT_AC_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ fi ++]) ++AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) ++test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in ++x|xyes) ++ # Assume -lc should be added ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $_LT_AC_TAGVAR(archive_cmds, $1) in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ AC_MSG_CHECKING([whether -lc should be explicitly linked in]) ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) ++ pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)= ++ if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2>&1 | grep " -lc " >/dev/null 2>&1) ++ then ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ++ else ++ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes ++ fi ++ _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) ++ ;; ++ esac ++ fi ++ ;; ++esac ++])# AC_LIBTOOL_PROG_LD_SHLIBS ++ ++ ++# _LT_AC_FILE_LTDLL_C ++# ------------------- ++# Be careful that the start marker always follows a newline. ++AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ ++# /* ltdll.c starts here */ ++# #define WIN32_LEAN_AND_MEAN ++# #include <windows.h> ++# #undef WIN32_LEAN_AND_MEAN ++# #include <stdio.h> ++# ++# #ifndef __CYGWIN__ ++# # ifdef __CYGWIN32__ ++# # define __CYGWIN__ __CYGWIN32__ ++# # endif ++# #endif ++# ++# #ifdef __cplusplus ++# extern "C" { ++# #endif ++# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); ++# #ifdef __cplusplus ++# } ++# #endif ++# ++# #ifdef __CYGWIN__ ++# #include <cygwin/cygwin_dll.h> ++# DECLARE_CYGWIN_DLL( DllMain ); ++# #endif ++# HINSTANCE __hDllInstance_base; ++# ++# BOOL APIENTRY ++# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) ++# { ++# __hDllInstance_base = hInst; ++# return TRUE; ++# } ++# /* ltdll.c ends here */ ++])# _LT_AC_FILE_LTDLL_C ++ ++ ++# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) ++# --------------------------------- ++AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) ++ ++ ++# old names ++AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) ++AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) ++AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) ++AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) ++AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) ++AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) ++AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) ++ ++# This is just to silence aclocal about the macro not being used ++ifelse([AC_DISABLE_FAST_INSTALL]) ++ ++AC_DEFUN([LT_AC_PROG_GCJ], ++[AC_CHECK_TOOL(GCJ, gcj, no) ++ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" ++ AC_SUBST(GCJFLAGS) ++]) ++ ++AC_DEFUN([LT_AC_PROG_RC], ++[AC_CHECK_TOOL(RC, windres, no) ++]) ++ ++# NOTE: This macro has been submitted for inclusion into # ++# GNU Autoconf as AC_PROG_SED. When it is available in # ++# a released version of Autoconf we should remove this # ++# macro and use it instead. # ++# LT_AC_PROG_SED ++# -------------- ++# Check for a fully-functional sed program, that truncates ++# as few characters as possible. Prefer GNU sed if found. ++AC_DEFUN([LT_AC_PROG_SED], ++[AC_MSG_CHECKING([for a sed that does not truncate output]) ++AC_CACHE_VAL(lt_cv_path_SED, ++[# Loop through the user's path and test for sed and gsed. ++# Then use that list of sed's as ones to test for truncation. ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for lt_ac_prog in sed gsed; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then ++ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" ++ fi ++ done ++ done ++done ++lt_ac_max=0 ++lt_ac_count=0 ++# Add /usr/xpg4/bin/sed as it is typically found on Solaris ++# along with /bin/sed that truncates output. ++for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do ++ test ! -f $lt_ac_sed && continue ++ cat /dev/null > conftest.in ++ lt_ac_count=0 ++ echo $ECHO_N "0123456789$ECHO_C" >conftest.in ++ # Check for GNU sed and select it if it is found. ++ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then ++ lt_cv_path_SED=$lt_ac_sed ++ break ++ fi ++ while true; do ++ cat conftest.in conftest.in >conftest.tmp ++ mv conftest.tmp conftest.in ++ cp conftest.in conftest.nl ++ echo >>conftest.nl ++ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break ++ cmp -s conftest.out conftest.nl || break ++ # 10000 chars as input seems more than enough ++ test $lt_ac_count -gt 10 && break ++ lt_ac_count=`expr $lt_ac_count + 1` ++ if test $lt_ac_count -gt $lt_ac_max; then ++ lt_ac_max=$lt_ac_count ++ lt_cv_path_SED=$lt_ac_sed ++ fi ++ done ++done ++]) ++SED=$lt_cv_path_SED ++AC_MSG_RESULT([$SED]) ++]) ++ ++# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_AUTOMAKE_VERSION(VERSION) ++# ---------------------------- ++# Automake X.Y traces this macro to ensure aclocal.m4 has been ++# generated from the m4 files accompanying Automake X.Y. ++AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) ++ ++# AM_SET_CURRENT_AUTOMAKE_VERSION ++# ------------------------------- ++# Call AM_AUTOMAKE_VERSION so it can be traced. ++# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. ++AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], ++ [AM_AUTOMAKE_VERSION([1.9.6])]) ++ ++# AM_AUX_DIR_EXPAND -*- Autoconf -*- ++ ++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets ++# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to ++# `$srcdir', `$srcdir/..', or `$srcdir/../..'. ++# ++# Of course, Automake must honor this variable whenever it calls a ++# tool from the auxiliary directory. The problem is that $srcdir (and ++# therefore $ac_aux_dir as well) can be either absolute or relative, ++# depending on how configure is run. This is pretty annoying, since ++# it makes $ac_aux_dir quite unusable in subdirectories: in the top ++# source directory, any form will work fine, but in subdirectories a ++# relative path needs to be adjusted first. ++# ++# $ac_aux_dir/missing ++# fails when called from a subdirectory if $ac_aux_dir is relative ++# $top_srcdir/$ac_aux_dir/missing ++# fails if $ac_aux_dir is absolute, ++# fails when called from a subdirectory in a VPATH build with ++# a relative $ac_aux_dir ++# ++# The reason of the latter failure is that $top_srcdir and $ac_aux_dir ++# are both prefixed by $srcdir. In an in-source build this is usually ++# harmless because $srcdir is `.', but things will broke when you ++# start a VPATH build or use an absolute $srcdir. ++# ++# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, ++# iff we strip the leading $srcdir from $ac_aux_dir. That would be: ++# am_aux_dir='$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*(.*)"` ++# and then we would define $MISSING as ++# MISSING="${SHELL} $am_aux_dir/missing" ++# This will work as long as MISSING is not called from configure, because ++# unfortunately $(top_srcdir) has no meaning in configure. ++# However there are other variables, like CC, which are often used in ++# configure, and could therefore not use this "fixed" $ac_aux_dir. ++# ++# Another solution, used here, is to always expand $ac_aux_dir to an ++# absolute PATH. The drawback is that using absolute paths prevent a ++# configured tree to be moved without reconfiguration. ++ ++AC_DEFUN([AM_AUX_DIR_EXPAND], ++[dnl Rely on autoconf to set up CDPATH properly. ++AC_PREREQ([2.50])dnl ++# expand $ac_aux_dir to an absolute path ++am_aux_dir=`cd $ac_aux_dir && pwd` ++]) ++ ++# AM_CONDITIONAL -*- Autoconf -*- ++ ++# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 7 ++ ++# AM_CONDITIONAL(NAME, SHELL-CONDITION) ++# ------------------------------------- ++# Define a conditional. ++AC_DEFUN([AM_CONDITIONAL], ++[AC_PREREQ(2.52)dnl ++ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], ++ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl ++AC_SUBST([$1_TRUE]) ++AC_SUBST([$1_FALSE]) ++if $2; then ++ $1_TRUE= ++ $1_FALSE='#' ++else ++ $1_TRUE='#' ++ $1_FALSE= ++fi ++AC_CONFIG_COMMANDS_PRE( ++[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then ++ AC_MSG_ERROR([[conditional "$1" was never defined. ++Usually this means the macro was only invoked conditionally.]]) ++fi])]) ++ ++ ++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 8 ++ ++# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be ++# written in clear, in which case automake, when reading aclocal.m4, ++# will think it sees a *use*, and therefore will trigger all it's ++# C support machinery. Also note that it means that autoscan, seeing ++# CC etc. in the Makefile, will ask for an AC_PROG_CC use... ++ ++ ++# _AM_DEPENDENCIES(NAME) ++# ---------------------- ++# See how the compiler implements dependency checking. ++# NAME is "CC", "CXX", "GCJ", or "OBJC". ++# We try a few techniques and use that to set a single cache variable. ++# ++# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was ++# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular ++# dependency, and given that the user is not expected to run this macro, ++# just rely on AC_PROG_CC. ++AC_DEFUN([_AM_DEPENDENCIES], ++[AC_REQUIRE([AM_SET_DEPDIR])dnl ++AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl ++AC_REQUIRE([AM_MAKE_INCLUDE])dnl ++AC_REQUIRE([AM_DEP_TRACK])dnl ++ ++ifelse([$1], CC, [depcc="$CC" am_compiler_list=], ++ [$1], CXX, [depcc="$CXX" am_compiler_list=], ++ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], ++ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], ++ [depcc="$$1" am_compiler_list=]) ++ ++AC_CACHE_CHECK([dependency style of $depcc], ++ [am_cv_$1_dependencies_compiler_type], ++[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named `D' -- because `-MD' means `put the output ++ # in D'. ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_$1_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n ['s/^#*([a-zA-Z0-9]*))$/\1/p'] < ./depcomp` ++ fi ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with ), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with ++ # Solaris 8's {/usr,}/bin/sh. ++ touch sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ case $depmode in ++ nosideeffect) ++ # after this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ none) break ;; ++ esac ++ # We check with `-c' and `-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle `-M -o', and we need to detect this. ++ if depmode=$depmode \ ++ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_$1_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_$1_dependencies_compiler_type=none ++fi ++]) ++AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) ++AM_CONDITIONAL([am__fastdep$1], [ ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ++]) ++ ++ ++# AM_SET_DEPDIR ++# ------------- ++# Choose a directory name for dependency files. ++# This macro is AC_REQUIREd in _AM_DEPENDENCIES ++AC_DEFUN([AM_SET_DEPDIR], ++[AC_REQUIRE([AM_SET_LEADING_DOT])dnl ++AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ++]) ++ ++ ++# AM_DEP_TRACK ++# ------------ ++AC_DEFUN([AM_DEP_TRACK], ++[AC_ARG_ENABLE(dependency-tracking, ++[ --disable-dependency-tracking speeds up one-time build ++ --enable-dependency-tracking do not reject slow dependency extractors]) ++if test "x$enable_dependency_tracking" != xno; then ++ am_depcomp="$ac_aux_dir/depcomp" ++ AMDEPBACKSLASH='' ++fi ++AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) ++AC_SUBST([AMDEPBACKSLASH]) ++]) ++ ++# Generate code to set up dependency tracking. -*- Autoconf -*- ++ ++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++#serial 3 ++ ++# _AM_OUTPUT_DEPENDENCY_COMMANDS ++# ------------------------------ ++AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], ++[for mf in $CONFIG_FILES; do ++ # Strip MF so we end up with the name of the file. ++ mf=`echo "$mf" | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile or not. ++ # We used to match only the files named `Makefile.in', but ++ # some people rename them; so instead we look at the file content. ++ # Grep'ing the first line is not enough: some people post-process ++ # each Makefile.in and add a new line on top of each file to say so. ++ # So let's grep whole file. ++ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then ++ dirpart=`AS_DIRNAME("$mf")` ++ else ++ continue ++ fi ++ # Extract the definition of DEPDIR, am__include, and am__quote ++ # from the Makefile without running `make'. ++ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` ++ test -z "$DEPDIR" && continue ++ am__include=`sed -n 's/^am__include = //p' < "$mf"` ++ test -z "am__include" && continue ++ am__quote=`sed -n 's/^am__quote = //p' < "$mf"` ++ # When using ansi2knr, U may be empty or an underscore; expand it ++ U=`sed -n 's/^U = //p' < "$mf"` ++ # Find all dependency output files, they are included files with ++ # $(DEPDIR) in their names. We invoke sed twice because it is the ++ # simplest approach to changing $(DEPDIR) to its actual value in the ++ # expansion. ++ for file in `sed -n " ++ s/^$am__include $am__quote(.*(DEPDIR).*)$am__quote"'$/\1/p' <"$mf" | \ ++ sed -e 's/$(DEPDIR)/'"$DEPDIR"'/g' -e 's/$U/'"$U"'/g'`; do ++ # Make sure the directory exists. ++ test -f "$dirpart/$file" && continue ++ fdir=`AS_DIRNAME(["$file"])` ++ AS_MKDIR_P([$dirpart/$fdir]) ++ # echo "creating $dirpart/$file" ++ echo '# dummy' > "$dirpart/$file" ++ done ++done ++])# _AM_OUTPUT_DEPENDENCY_COMMANDS ++ ++ ++# AM_OUTPUT_DEPENDENCY_COMMANDS ++# ----------------------------- ++# This macro should only be invoked once -- use via AC_REQUIRE. ++# ++# This code is only required when automatic dependency tracking ++# is enabled. FIXME. This creates each `.P' file that we will ++# need in order to bootstrap the dependency handling code. ++AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], ++[AC_CONFIG_COMMANDS([depfiles], ++ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], ++ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ++]) ++ ++# Do all the work for Automake. -*- Autoconf -*- ++ ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 12 ++ ++# This macro actually does too much. Some checks are only needed if ++# your package does certain things. But this isn't really a big deal. ++ ++# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) ++# AM_INIT_AUTOMAKE([OPTIONS]) ++# ----------------------------------------------- ++# The call with PACKAGE and VERSION arguments is the old style ++# call (pre autoconf-2.50), which is being phased out. PACKAGE ++# and VERSION should now be passed to AC_INIT and removed from ++# the call to AM_INIT_AUTOMAKE. ++# We support both call styles for the transition. After ++# the next Automake release, Autoconf can make the AC_INIT ++# arguments mandatory, and then we can depend on a new Autoconf ++# release and drop the old call support. ++AC_DEFUN([AM_INIT_AUTOMAKE], ++[AC_PREREQ([2.58])dnl ++dnl Autoconf wants to disallow AM_ names. We explicitly allow ++dnl the ones we care about. ++m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl ++AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl ++AC_REQUIRE([AC_PROG_INSTALL])dnl ++# test to see if srcdir already configured ++if test "`cd $srcdir && pwd`" != "`pwd`" && ++ test -f $srcdir/config.status; then ++ AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) ++fi ++ ++# test whether we have cygpath ++if test -z "$CYGPATH_W"; then ++ if (cygpath --version) >/dev/null 2>/dev/null; then ++ CYGPATH_W='cygpath -w' ++ else ++ CYGPATH_W=echo ++ fi ++fi ++AC_SUBST([CYGPATH_W]) ++ ++# Define the identity of the package. ++dnl Distinguish between old-style and new-style calls. ++m4_ifval([$2], ++[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl ++ AC_SUBST([PACKAGE], [$1])dnl ++ AC_SUBST([VERSION], [$2])], ++[_AM_SET_OPTIONS([$1])dnl ++ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl ++ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl ++ ++_AM_IF_OPTION([no-define],, ++[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) ++ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl ++ ++# Some tools Automake needs. ++AC_REQUIRE([AM_SANITY_CHECK])dnl ++AC_REQUIRE([AC_ARG_PROGRAM])dnl ++AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) ++AM_MISSING_PROG(AUTOCONF, autoconf) ++AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) ++AM_MISSING_PROG(AUTOHEADER, autoheader) ++AM_MISSING_PROG(MAKEINFO, makeinfo) ++AM_PROG_INSTALL_SH ++AM_PROG_INSTALL_STRIP ++AC_REQUIRE([AM_PROG_MKDIR_P])dnl ++# We need awk for the "check" target. The system "awk" is bad on ++# some platforms. ++AC_REQUIRE([AC_PROG_AWK])dnl ++AC_REQUIRE([AC_PROG_MAKE_SET])dnl ++AC_REQUIRE([AM_SET_LEADING_DOT])dnl ++_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], ++ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], ++ [_AM_PROG_TAR([v7])])]) ++_AM_IF_OPTION([no-dependencies],, ++[AC_PROVIDE_IFELSE([AC_PROG_CC], ++ [_AM_DEPENDENCIES(CC)], ++ [define([AC_PROG_CC], ++ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl ++AC_PROVIDE_IFELSE([AC_PROG_CXX], ++ [_AM_DEPENDENCIES(CXX)], ++ [define([AC_PROG_CXX], ++ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl ++]) ++]) ++ ++ ++# When config.status generates a header, we must update the stamp-h file. ++# This file resides in the same directory as the config header ++# that is generated. The stamp files are numbered to have different names. ++ ++# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the ++# loop where config.status creates the headers, so we can generate ++# our stamp files there. ++AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], ++[# Compute $1's index in $config_headers. ++_am_stamp_count=1 ++for _am_header in $config_headers :; do ++ case $_am_header in ++ $1 | $1:* ) ++ break ;; ++ * ) ++ _am_stamp_count=`expr $_am_stamp_count + 1` ;; ++ esac ++done ++echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) ++ ++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_PROG_INSTALL_SH ++# ------------------ ++# Define $install_sh. ++AC_DEFUN([AM_PROG_INSTALL_SH], ++[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl ++install_sh=${install_sh-"$am_aux_dir/install-sh"} ++AC_SUBST(install_sh)]) ++ ++# Copyright (C) 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 2 ++ ++# Check whether the underlying file-system supports filenames ++# with a leading dot. For instance MS-DOS doesn't. ++AC_DEFUN([AM_SET_LEADING_DOT], ++[rm -rf .tst 2>/dev/null ++mkdir .tst 2>/dev/null ++if test -d .tst; then ++ am__leading_dot=. ++else ++ am__leading_dot=_ ++fi ++rmdir .tst 2>/dev/null ++AC_SUBST([am__leading_dot])]) ++ ++# Check to see how 'make' treats includes. -*- Autoconf -*- ++ ++# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 3 ++ ++# AM_MAKE_INCLUDE() ++# ----------------- ++# Check to see how make treats includes. ++AC_DEFUN([AM_MAKE_INCLUDE], ++[am_make=${MAKE-make} ++cat > confinc << 'END' ++am__doit: ++ @echo done ++.PHONY: am__doit ++END ++# If we don't find an include directive, just comment out the code. ++AC_MSG_CHECKING([for style of include used by $am_make]) ++am__include="#" ++am__quote= ++_am_result=none ++# First try GNU make style include. ++echo "include confinc" > confmf ++# We grep out `Entering directory' and `Leaving directory' ++# messages which can occur if `w' ends up in MAKEFLAGS. ++# In particular we don't look at `^make:' because GNU make might ++# be invoked under some other name (usually "gmake"), in which ++# case it prints its new name instead of `make'. ++if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then ++ am__include=include ++ am__quote= ++ _am_result=GNU ++fi ++# Now try BSD make style include. ++if test "$am__include" = "#"; then ++ echo '.include "confinc"' > confmf ++ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then ++ am__include=.include ++ am__quote=""" ++ _am_result=BSD ++ fi ++fi ++AC_SUBST([am__include]) ++AC_SUBST([am__quote]) ++AC_MSG_RESULT([$_am_result]) ++rm -f confinc confmf ++]) ++ ++# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- ++ ++# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 4 ++ ++# AM_MISSING_PROG(NAME, PROGRAM) ++# ------------------------------ ++AC_DEFUN([AM_MISSING_PROG], ++[AC_REQUIRE([AM_MISSING_HAS_RUN]) ++$1=${$1-"${am_missing_run}$2"} ++AC_SUBST($1)]) ++ ++ ++# AM_MISSING_HAS_RUN ++# ------------------ ++# Define MISSING if not defined so far and test if it supports --run. ++# If it does, set am_missing_run to use it, otherwise, to nothing. ++AC_DEFUN([AM_MISSING_HAS_RUN], ++[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl ++test x"${MISSING+set}" = xset || MISSING="${SHELL} $am_aux_dir/missing" ++# Use eval to expand $SHELL ++if eval "$MISSING --run true"; then ++ am_missing_run="$MISSING --run " ++else ++ am_missing_run= ++ AC_MSG_WARN([`missing' script is too old or missing]) ++fi ++]) ++ ++# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_PROG_MKDIR_P ++# --------------- ++# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. ++# ++# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories ++# created by `make install' are always world readable, even if the ++# installer happens to have an overly restrictive umask (e.g. 077). ++# This was a mistake. There are at least two reasons why we must not ++# use `-m 0755': ++# - it causes special bits like SGID to be ignored, ++# - it may be too restrictive (some setups expect 775 directories). ++# ++# Do not use -m 0755 and let people choose whatever they expect by ++# setting umask. ++# ++# We cannot accept any implementation of `mkdir' that recognizes `-p'. ++# Some implementations (such as Solaris 8's) are not thread-safe: if a ++# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' ++# concurrently, both version can detect that a/ is missing, but only ++# one can create it and the other will error out. Consequently we ++# restrict ourselves to GNU make (using the --version option ensures ++# this.) ++AC_DEFUN([AM_PROG_MKDIR_P], ++[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then ++ # We used to keeping the `.' as first argument, in order to ++ # allow $(mkdir_p) to be used without argument. As in ++ # $(mkdir_p) $(somedir) ++ # where $(somedir) is conditionally defined. However this is wrong ++ # for two reasons: ++ # 1. if the package is installed by a user who cannot write `.' ++ # make install will fail, ++ # 2. the above comment should most certainly read ++ # $(mkdir_p) $(DESTDIR)$(somedir) ++ # so it does not work when $(somedir) is undefined and ++ # $(DESTDIR) is not. ++ # To support the latter case, we have to write ++ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), ++ # so the `.' trick is pointless. ++ mkdir_p='mkdir -p --' ++else ++ # On NextStep and OpenStep, the `mkdir' command does not ++ # recognize any option. It will interpret all options as ++ # directories to create, and then abort because `.' already ++ # exists. ++ for d in ./-p ./--version; ++ do ++ test -d $d && rmdir $d ++ done ++ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. ++ if test -f "$ac_aux_dir/mkinstalldirs"; then ++ mkdir_p='$(mkinstalldirs)' ++ else ++ mkdir_p='$(install_sh) -d' ++ fi ++fi ++AC_SUBST([mkdir_p])]) ++ ++# Helper functions for option handling. -*- Autoconf -*- ++ ++# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 3 ++ ++# _AM_MANGLE_OPTION(NAME) ++# ----------------------- ++AC_DEFUN([_AM_MANGLE_OPTION], ++[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) ++ ++# _AM_SET_OPTION(NAME) ++# ------------------------------ ++# Set option NAME. Presently that only means defining a flag for this option. ++AC_DEFUN([_AM_SET_OPTION], ++[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) ++ ++# _AM_SET_OPTIONS(OPTIONS) ++# ---------------------------------- ++# OPTIONS is a space-separated list of Automake options. ++AC_DEFUN([_AM_SET_OPTIONS], ++[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) ++ ++# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) ++# ------------------------------------------- ++# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. ++AC_DEFUN([_AM_IF_OPTION], ++[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) ++ ++# Check to make sure that the build environment is sane. -*- Autoconf -*- ++ ++# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 ++# Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 4 ++ ++# AM_SANITY_CHECK ++# --------------- ++AC_DEFUN([AM_SANITY_CHECK], ++[AC_MSG_CHECKING([whether build environment is sane]) ++# Just in case ++sleep 1 ++echo timestamp > conftest.file ++# Do `set' in a subshell so we don't clobber the current shell's ++# arguments. Must try -L first in case configure is actually a ++# symlink; some systems play weird games with the mod time of symlinks ++# (eg FreeBSD returns the mod time of the symlink's containing ++# directory). ++if ( ++ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` ++ if test "$[*]" = "X"; then ++ # -L didn't work. ++ set X `ls -t $srcdir/configure conftest.file` ++ fi ++ rm -f conftest.file ++ if test "$[*]" != "X $srcdir/configure conftest.file" \ ++ && test "$[*]" != "X conftest.file $srcdir/configure"; then ++ ++ # If neither matched, then we have a broken ls. This can happen ++ # if, for instance, CONFIG_SHELL is bash and it inherits a ++ # broken ls alias from the environment. This has actually ++ # happened. Such a system could not be considered "sane". ++ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken ++alias in your environment]) ++ fi ++ ++ test "$[2]" = conftest.file ++ ) ++then ++ # Ok. ++ : ++else ++ AC_MSG_ERROR([newly created file is older than distributed files! ++Check your system clock]) ++fi ++AC_MSG_RESULT(yes)]) ++ ++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# AM_PROG_INSTALL_STRIP ++# --------------------- ++# One issue with vendor `install' (even GNU) is that you can't ++# specify the program used to strip binaries. This is especially ++# annoying in cross-compiling environments, where the build's strip ++# is unlikely to handle the host's binaries. ++# Fortunately install-sh will honor a STRIPPROG variable, so we ++# always use install-sh in `make install-strip', and initialize ++# STRIPPROG with the value of the STRIP variable (set by the user). ++AC_DEFUN([AM_PROG_INSTALL_STRIP], ++[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl ++# Installed binaries are usually stripped using `strip' when the user ++# run `make install-strip'. However `strip' might not be the right ++# tool to use in cross-compilation environments, therefore Automake ++# will honor the `STRIP' environment variable to overrule this program. ++dnl Don't test for $cross_compiling = yes, because it might be `maybe'. ++if test "$cross_compiling" != no; then ++ AC_CHECK_TOOL([STRIP], [strip], :) ++fi ++INSTALL_STRIP_PROGRAM="${SHELL} $(install_sh) -c -s" ++AC_SUBST([INSTALL_STRIP_PROGRAM])]) ++ ++# Check how to create a tarball. -*- Autoconf -*- ++ ++# Copyright (C) 2004, 2005 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# serial 2 ++ ++# _AM_PROG_TAR(FORMAT) ++# -------------------- ++# Check how to create a tarball in format FORMAT. ++# FORMAT should be one of `v7', `ustar', or `pax'. ++# ++# Substitute a variable $(am__tar) that is a command ++# writing to stdout a FORMAT-tarball containing the directory ++# $tardir. ++# tardir=directory && $(am__tar) > result.tar ++# ++# Substitute a variable $(am__untar) that extract such ++# a tarball read from stdin. ++# $(am__untar) < result.tar ++AC_DEFUN([_AM_PROG_TAR], ++[# Always define AMTAR for backward compatibility. ++AM_MISSING_PROG([AMTAR], [tar]) ++m4_if([$1], [v7], ++ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], ++ [m4_case([$1], [ustar],, [pax],, ++ [m4_fatal([Unknown tar format])]) ++AC_MSG_CHECKING([how to create a $1 tar archive]) ++# Loop over all known methods to create a tar archive until one works. ++_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' ++_am_tools=${am_cv_prog_tar_$1-$_am_tools} ++# Do not fold the above two line into one, because Tru64 sh and ++# Solaris sh will not grok spaces in the rhs of `-'. ++for _am_tool in $_am_tools ++do ++ case $_am_tool in ++ gnutar) ++ for _am_tar in tar gnutar gtar; ++ do ++ AM_RUN_LOG([$_am_tar --version]) && break ++ done ++ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' ++ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' ++ am__untar="$_am_tar -xf -" ++ ;; ++ plaintar) ++ # Must skip GNU tar: if it does not support --format= it doesn't create ++ # ustar tarball either. ++ (tar --version) >/dev/null 2>&1 && continue ++ am__tar='tar chf - "$$tardir"' ++ am__tar_='tar chf - "$tardir"' ++ am__untar='tar xf -' ++ ;; ++ pax) ++ am__tar='pax -L -x $1 -w "$$tardir"' ++ am__tar_='pax -L -x $1 -w "$tardir"' ++ am__untar='pax -r' ++ ;; ++ cpio) ++ am__tar='find "$$tardir" -print | cpio -o -H $1 -L' ++ am__tar_='find "$tardir" -print | cpio -o -H $1 -L' ++ am__untar='cpio -i -H $1 -d' ++ ;; ++ none) ++ am__tar=false ++ am__tar_=false ++ am__untar=false ++ ;; ++ esac ++ ++ # If the value was cached, stop now. We just wanted to have am__tar ++ # and am__untar set. ++ test -n "${am_cv_prog_tar_$1}" && break ++ ++ # tar/untar a dummy directory, and stop if the command works ++ rm -rf conftest.dir ++ mkdir conftest.dir ++ echo GrepMe > conftest.dir/file ++ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) ++ rm -rf conftest.dir ++ if test -s conftest.tar; then ++ AM_RUN_LOG([$am__untar <conftest.tar]) ++ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break ++ fi ++done ++rm -rf conftest.dir ++ ++AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) ++AC_MSG_RESULT([$am_cv_prog_tar_$1])]) ++AC_SUBST([am__tar]) ++AC_SUBST([am__untar]) ++]) # _AM_PROG_TAR ++ +diff -urN lua-5.1.4/autogen.sh lua-5.1.4-autotoolize/autogen.sh +--- lua-5.1.4/autogen.sh 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/autogen.sh 2008-09-03 13:18:28.000000000 +0200 +@@ -0,0 +1,5 @@ ++#!/bin/sh ++ ++autoreconf -fvi ++ ++echo "Now run ./configure" +diff -urN lua-5.1.4/config.guess lua-5.1.4-autotoolize/config.guess +--- lua-5.1.4/config.guess 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/config.guess 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,1517 @@ ++#! /bin/sh ++# Attempt to guess a canonical system name. ++# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, ++# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, ++# Inc. ++ ++timestamp='2006-02-27' ++ ++# This file is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA ++# 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++ ++# Originally written by Per Bothner <per@bothner.com>. ++# Please send patches to <config-patches@gnu.org>. Submit a context ++# diff and a properly formatted ChangeLog entry. ++# ++# This script attempts to guess a canonical system name similar to ++# config.sub. If it succeeds, it prints the system name on stdout, and ++# exits with 0. Otherwise, it exits with 1. ++# ++# The plan is that this can be called by configure scripts if you ++# don't specify an explicit build system type. ++ ++me=`echo "$0" | sed -e 's,.*/,,'` ++ ++usage="\ ++Usage: $0 [OPTION] ++ ++Output the configuration name of the system `$me' is run on. ++ ++Operation modes: ++ -h, --help print this help, then exit ++ -t, --time-stamp print date of last modification, then exit ++ -v, --version print version number, then exit ++ ++Report bugs and patches to <config-patches@gnu.org>." ++ ++version="\ ++GNU config.guess ($timestamp) ++ ++Originally written by Per Bothner. ++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ++Free Software Foundation, Inc. ++ ++This is free software; see the source for copying conditions. There is NO ++warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ++ ++help=" ++Try `$me --help' for more information." ++ ++# Parse command line ++while test $# -gt 0 ; do ++ case $1 in ++ --time-stamp | --time* | -t ) ++ echo "$timestamp" ; exit ;; ++ --version | -v ) ++ echo "$version" ; exit ;; ++ --help | --h* | -h ) ++ echo "$usage"; exit ;; ++ -- ) # Stop option processing ++ shift; break ;; ++ - ) # Use stdin as input. ++ break ;; ++ -* ) ++ echo "$me: invalid option $1$help" >&2 ++ exit 1 ;; ++ * ) ++ break ;; ++ esac ++done ++ ++if test $# != 0; then ++ echo "$me: too many arguments$help" >&2 ++ exit 1 ++fi ++ ++trap 'exit 1' 1 2 15 ++ ++# CC_FOR_BUILD -- compiler used by this script. Note that the use of a ++# compiler to aid in system detection is discouraged as it requires ++# temporary files to be created and, as you can see below, it is a ++# headache to deal with in a portable fashion. ++ ++# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still ++# use `HOST_CC' if defined, but it is deprecated. ++ ++# Portable tmp directory creation inspired by the Autoconf team. ++ ++set_cc_for_build=' ++trap "exitcode=$?; (rm -f $tmpfiles 2>/dev/null; rmdir $tmp 2>/dev/null) && exit $exitcode" 0 ; ++trap "rm -f $tmpfiles 2>/dev/null; rmdir $tmp 2>/dev/null; exit 1" 1 2 13 15 ; ++: ${TMPDIR=/tmp} ; ++ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || ++ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || ++ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || ++ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; ++dummy=$tmp/dummy ; ++tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; ++case $CC_FOR_BUILD,$HOST_CC,$CC in ++ ,,) echo "int x;" > $dummy.c ; ++ for c in cc gcc c89 c99 ; do ++ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then ++ CC_FOR_BUILD="$c"; break ; ++ fi ; ++ done ; ++ if test x"$CC_FOR_BUILD" = x ; then ++ CC_FOR_BUILD=no_compiler_found ; ++ fi ++ ;; ++ ,,*) CC_FOR_BUILD=$CC ;; ++ ,*,*) CC_FOR_BUILD=$HOST_CC ;; ++esac ; set_cc_for_build= ;' ++ ++# This is needed to find uname on a Pyramid OSx when run in the BSD universe. ++# (ghazi@noc.rutgers.edu 1994-08-24) ++if (test -f /.attbin/uname) >/dev/null 2>&1 ; then ++ PATH=$PATH:/.attbin ; export PATH ++fi ++ ++UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown ++UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown ++UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown ++UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown ++ ++if [ "${UNAME_SYSTEM}" = "Linux" ] ; then ++ eval $set_cc_for_build ++ cat << EOF > $dummy.c ++ #include <features.h> ++ #ifdef __UCLIBC__ ++ # ifdef __UCLIBC_CONFIG_VERSION__ ++ LIBC=uclibc __UCLIBC_CONFIG_VERSION__ ++ # else ++ LIBC=uclibc ++ # endif ++ #else ++ LIBC=gnu ++ #endif ++EOF ++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep LIBC= | sed -e 's: ::g'` ++fi ++ ++# Note: order is significant - the case branches are not exclusive. ++ ++case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ++ *:NetBSD:*:*) ++ # NetBSD (nbsd) targets should (where applicable) match one or ++ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, ++ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently ++ # switched to ELF, *-*-netbsd* would select the old ++ # object file format. This provides both forward ++ # compatibility and a consistent mechanism for selecting the ++ # object file format. ++ # ++ # Note: NetBSD doesn't particularly care about the vendor ++ # portion of the name. We always set it to "unknown". ++ sysctl="sysctl -n hw.machine_arch" ++ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ ++ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` ++ case "${UNAME_MACHINE_ARCH}" in ++ armeb) machine=armeb-unknown ;; ++ arm*) machine=arm-unknown ;; ++ sh3el) machine=shl-unknown ;; ++ sh3eb) machine=sh-unknown ;; ++ *) machine=${UNAME_MACHINE_ARCH}-unknown ;; ++ esac ++ # The Operating System including object format, if it has switched ++ # to ELF recently, or will in the future. ++ case "${UNAME_MACHINE_ARCH}" in ++ arm*|i386|m68k|ns32k|sh3*|sparc|vax) ++ eval $set_cc_for_build ++ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ ++ | grep __ELF__ >/dev/null ++ then ++ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). ++ # Return netbsd for either. FIX? ++ os=netbsd ++ else ++ os=netbsdelf ++ fi ++ ;; ++ *) ++ os=netbsd ++ ;; ++ esac ++ # The OS release ++ # Debian GNU/NetBSD machines have a different userland, and ++ # thus, need a distinct triplet. However, they do not need ++ # kernel version information, so it can be replaced with a ++ # suitable tag, in the style of linux-gnu. ++ case "${UNAME_VERSION}" in ++ Debian*) ++ release='-gnu' ++ ;; ++ *) ++ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/./'` ++ ;; ++ esac ++ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: ++ # contains redundant information, the shorter form: ++ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. ++ echo "${machine}-${os}${release}" ++ exit ;; ++ *:OpenBSD:*:*) ++ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` ++ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} ++ exit ;; ++ *:ekkoBSD:*:*) ++ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} ++ exit ;; ++ *:SolidBSD:*:*) ++ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} ++ exit ;; ++ macppc:MirBSD:*:*) ++ echo powerppc-unknown-mirbsd${UNAME_RELEASE} ++ exit ;; ++ *:MirBSD:*:*) ++ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} ++ exit ;; ++ alpha:OSF1:*:*) ++ case $UNAME_RELEASE in ++ *4.0) ++ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ++ ;; ++ *5.*) ++ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ++ ;; ++ esac ++ # According to Compaq, /usr/sbin/psrinfo has been available on ++ # OSF/1 and Tru64 systems produced since 1995. I hope that ++ # covers most systems running today. This code pipes the CPU ++ # types through head -n 1, so we only detect the type of CPU 0. ++ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha (.*) processor.*$/\1/p' | head -n 1` ++ case "$ALPHA_CPU_TYPE" in ++ "EV4 (21064)") ++ UNAME_MACHINE="alpha" ;; ++ "EV4.5 (21064)") ++ UNAME_MACHINE="alpha" ;; ++ "LCA4 (21066/21068)") ++ UNAME_MACHINE="alpha" ;; ++ "EV5 (21164)") ++ UNAME_MACHINE="alphaev5" ;; ++ "EV5.6 (21164A)") ++ UNAME_MACHINE="alphaev56" ;; ++ "EV5.6 (21164PC)") ++ UNAME_MACHINE="alphapca56" ;; ++ "EV5.7 (21164PC)") ++ UNAME_MACHINE="alphapca57" ;; ++ "EV6 (21264)") ++ UNAME_MACHINE="alphaev6" ;; ++ "EV6.7 (21264A)") ++ UNAME_MACHINE="alphaev67" ;; ++ "EV6.8CB (21264C)") ++ UNAME_MACHINE="alphaev68" ;; ++ "EV6.8AL (21264B)") ++ UNAME_MACHINE="alphaev68" ;; ++ "EV6.8CX (21264D)") ++ UNAME_MACHINE="alphaev68" ;; ++ "EV6.9A (21264/EV69A)") ++ UNAME_MACHINE="alphaev69" ;; ++ "EV7 (21364)") ++ UNAME_MACHINE="alphaev7" ;; ++ "EV7.9 (21364A)") ++ UNAME_MACHINE="alphaev79" ;; ++ esac ++ # A Pn.n version is a patched version. ++ # A Vn.n version is a released version. ++ # A Tn.n version is a released field test version. ++ # A Xn.n version is an unreleased experimental baselevel. ++ # 1.2 uses "1.2" for uname -r. ++ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` ++ exit ;; ++ Alpha\ *:Windows_NT*:*) ++ # How do we know it's Interix rather than the generic POSIX subsystem? ++ # Should we change UNAME_MACHINE based on the output of uname instead ++ # of the specific Alpha model? ++ echo alpha-pc-interix ++ exit ;; ++ 21064:Windows_NT:50:3) ++ echo alpha-dec-winnt3.5 ++ exit ;; ++ Amiga*:UNIX_System_V:4.0:*) ++ echo m68k-unknown-sysv4 ++ exit ;; ++ *:[Aa]miga[Oo][Ss]:*:*) ++ echo ${UNAME_MACHINE}-unknown-amigaos ++ exit ;; ++ *:[Mm]orph[Oo][Ss]:*:*) ++ echo ${UNAME_MACHINE}-unknown-morphos ++ exit ;; ++ *:OS/390:*:*) ++ echo i370-ibm-openedition ++ exit ;; ++ *:z/VM:*:*) ++ echo s390-ibm-zvmoe ++ exit ;; ++ *:OS400:*:*) ++ echo powerpc-ibm-os400 ++ exit ;; ++ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) ++ echo arm-acorn-riscix${UNAME_RELEASE} ++ exit ;; ++ arm:riscos:*:*|arm:RISCOS:*:*) ++ echo arm-unknown-riscos ++ exit ;; ++ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) ++ echo hppa1.1-hitachi-hiuxmpp ++ exit ;; ++ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) ++ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. ++ if test "`(/bin/universe) 2>/dev/null`" = att ; then ++ echo pyramid-pyramid-sysv3 ++ else ++ echo pyramid-pyramid-bsd ++ fi ++ exit ;; ++ NILE*:*:*:dcosx) ++ echo pyramid-pyramid-svr4 ++ exit ;; ++ DRS?6000:unix:4.0:6*) ++ echo sparc-icl-nx6 ++ exit ;; ++ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) ++ case `/usr/bin/uname -p` in ++ sparc) echo sparc-icl-nx7; exit ;; ++ esac ;; ++ sun4H:SunOS:5.*:*) ++ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) ++ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ i86pc:SunOS:5.*:*) ++ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ sun4*:SunOS:6*:*) ++ # According to config.sub, this is the proper way to canonicalize ++ # SunOS6. Hard to guess exactly what SunOS6 will be like, but ++ # it's likely to be more like Solaris than SunOS4. ++ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ sun4*:SunOS:*:*) ++ case "`/usr/bin/arch -k`" in ++ Series*|S4*) ++ UNAME_RELEASE=`uname -v` ++ ;; ++ esac ++ # Japanese Language versions have a version number like `4.1.3-JL'. ++ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` ++ exit ;; ++ sun3*:SunOS:*:*) ++ echo m68k-sun-sunos${UNAME_RELEASE} ++ exit ;; ++ sun*:*:4.2BSD:*) ++ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` ++ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 ++ case "`/bin/arch`" in ++ sun3) ++ echo m68k-sun-sunos${UNAME_RELEASE} ++ ;; ++ sun4) ++ echo sparc-sun-sunos${UNAME_RELEASE} ++ ;; ++ esac ++ exit ;; ++ aushp:SunOS:*:*) ++ echo sparc-auspex-sunos${UNAME_RELEASE} ++ exit ;; ++ # The situation for MiNT is a little confusing. The machine name ++ # can be virtually everything (everything which is not ++ # "atarist" or "atariste" at least should have a processor ++ # > m68000). The system name ranges from "MiNT" over "FreeMiNT" ++ # to the lowercase version "mint" (or "freemint"). Finally ++ # the system name "TOS" denotes a system which is actually not ++ # MiNT. But MiNT is downward compatible to TOS, so this should ++ # be no problem. ++ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) ++ echo m68k-atari-mint${UNAME_RELEASE} ++ exit ;; ++ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) ++ echo m68k-atari-mint${UNAME_RELEASE} ++ exit ;; ++ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) ++ echo m68k-atari-mint${UNAME_RELEASE} ++ exit ;; ++ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) ++ echo m68k-milan-mint${UNAME_RELEASE} ++ exit ;; ++ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) ++ echo m68k-hades-mint${UNAME_RELEASE} ++ exit ;; ++ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) ++ echo m68k-unknown-mint${UNAME_RELEASE} ++ exit ;; ++ m68k:machten:*:*) ++ echo m68k-apple-machten${UNAME_RELEASE} ++ exit ;; ++ powerpc:machten:*:*) ++ echo powerpc-apple-machten${UNAME_RELEASE} ++ exit ;; ++ RISC*:Mach:*:*) ++ echo mips-dec-mach_bsd4.3 ++ exit ;; ++ RISC*:ULTRIX:*:*) ++ echo mips-dec-ultrix${UNAME_RELEASE} ++ exit ;; ++ VAX*:ULTRIX*:*:*) ++ echo vax-dec-ultrix${UNAME_RELEASE} ++ exit ;; ++ 2020:CLIX:*:* | 2430:CLIX:*:*) ++ echo clipper-intergraph-clix${UNAME_RELEASE} ++ exit ;; ++ mips:*:*:UMIPS | mips:*:*:RISCos) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++#ifdef __cplusplus ++#include <stdio.h> /* for printf() prototype */ ++ int main (int argc, char *argv[]) { ++#else ++ int main (argc, argv) int argc; char *argv[]; { ++#endif ++ #if defined (host_mips) && defined (MIPSEB) ++ #if defined (SYSTYPE_SYSV) ++ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); ++ #endif ++ #if defined (SYSTYPE_SVR4) ++ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); ++ #endif ++ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) ++ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); ++ #endif ++ #endif ++ exit (-1); ++ } ++EOF ++ $CC_FOR_BUILD -o $dummy $dummy.c && ++ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/([0-9]*).*/\1/p'` && ++ SYSTEM_NAME=`$dummy $dummyarg` && ++ { echo "$SYSTEM_NAME"; exit; } ++ echo mips-mips-riscos${UNAME_RELEASE} ++ exit ;; ++ Motorola:PowerMAX_OS:*:*) ++ echo powerpc-motorola-powermax ++ exit ;; ++ Motorola:*:4.3:PL8-*) ++ echo powerpc-harris-powermax ++ exit ;; ++ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) ++ echo powerpc-harris-powermax ++ exit ;; ++ Night_Hawk:Power_UNIX:*:*) ++ echo powerpc-harris-powerunix ++ exit ;; ++ m88k:CX/UX:7*:*) ++ echo m88k-harris-cxux7 ++ exit ;; ++ m88k:*:4*:R4*) ++ echo m88k-motorola-sysv4 ++ exit ;; ++ m88k:*:3*:R3*) ++ echo m88k-motorola-sysv3 ++ exit ;; ++ AViiON:dgux:*:*) ++ # DG/UX returns AViiON for all architectures ++ UNAME_PROCESSOR=`/usr/bin/uname -p` ++ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] ++ then ++ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ ++ [ ${TARGET_BINARY_INTERFACE}x = x ] ++ then ++ echo m88k-dg-dgux${UNAME_RELEASE} ++ else ++ echo m88k-dg-dguxbcs${UNAME_RELEASE} ++ fi ++ else ++ echo i586-dg-dgux${UNAME_RELEASE} ++ fi ++ exit ;; ++ M88*:DolphinOS:*:*) # DolphinOS (SVR3) ++ echo m88k-dolphin-sysv3 ++ exit ;; ++ M88*:*:R3*:*) ++ # Delta 88k system running SVR3 ++ echo m88k-motorola-sysv3 ++ exit ;; ++ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) ++ echo m88k-tektronix-sysv3 ++ exit ;; ++ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) ++ echo m68k-tektronix-bsd ++ exit ;; ++ *:IRIX*:*:*) ++ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` ++ exit ;; ++ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. ++ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id ++ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' ++ i*86:AIX:*:*) ++ echo i386-ibm-aix ++ exit ;; ++ ia64:AIX:*:*) ++ if [ -x /usr/bin/oslevel ] ; then ++ IBM_REV=`/usr/bin/oslevel` ++ else ++ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} ++ fi ++ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} ++ exit ;; ++ *:AIX:2:3) ++ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #include <sys/systemcfg.h> ++ ++ main() ++ { ++ if (!__power_pc()) ++ exit(1); ++ puts("powerpc-ibm-aix3.2.5"); ++ exit(0); ++ } ++EOF ++ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` ++ then ++ echo "$SYSTEM_NAME" ++ else ++ echo rs6000-ibm-aix3.2.5 ++ fi ++ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then ++ echo rs6000-ibm-aix3.2.4 ++ else ++ echo rs6000-ibm-aix3.2 ++ fi ++ exit ;; ++ *:AIX:*:[45]) ++ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` ++ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then ++ IBM_ARCH=rs6000 ++ else ++ IBM_ARCH=powerpc ++ fi ++ if [ -x /usr/bin/oslevel ] ; then ++ IBM_REV=`/usr/bin/oslevel` ++ else ++ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} ++ fi ++ echo ${IBM_ARCH}-ibm-aix${IBM_REV} ++ exit ;; ++ *:AIX:*:*) ++ echo rs6000-ibm-aix ++ exit ;; ++ ibmrt:4.4BSD:*|romp-ibm:BSD:*) ++ echo romp-ibm-bsd4.4 ++ exit ;; ++ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and ++ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to ++ exit ;; # report: romp-ibm BSD 4.3 ++ *:BOSX:*:*) ++ echo rs6000-bull-bosx ++ exit ;; ++ DPX/2?00:B.O.S.:*:*) ++ echo m68k-bull-sysv3 ++ exit ;; ++ 9000/[34]??:4.3bsd:1.*:*) ++ echo m68k-hp-bsd ++ exit ;; ++ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) ++ echo m68k-hp-bsd4.4 ++ exit ;; ++ 9000/[34678]??:HP-UX:*:*) ++ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` ++ case "${UNAME_MACHINE}" in ++ 9000/31? ) HP_ARCH=m68000 ;; ++ 9000/[34]?? ) HP_ARCH=m68k ;; ++ 9000/[678][0-9][0-9]) ++ if [ -x /usr/bin/getconf ]; then ++ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` ++ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` ++ case "${sc_cpu_version}" in ++ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 ++ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 ++ 532) # CPU_PA_RISC2_0 ++ case "${sc_kernel_bits}" in ++ 32) HP_ARCH="hppa2.0n" ;; ++ 64) HP_ARCH="hppa2.0w" ;; ++ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 ++ esac ;; ++ esac ++ fi ++ if [ "${HP_ARCH}" = "" ]; then ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ ++ #define _HPUX_SOURCE ++ #include <stdlib.h> ++ #include <unistd.h> ++ ++ int main () ++ { ++ #if defined(_SC_KERNEL_BITS) ++ long bits = sysconf(_SC_KERNEL_BITS); ++ #endif ++ long cpu = sysconf (_SC_CPU_VERSION); ++ ++ switch (cpu) ++ { ++ case CPU_PA_RISC1_0: puts ("hppa1.0"); break; ++ case CPU_PA_RISC1_1: puts ("hppa1.1"); break; ++ case CPU_PA_RISC2_0: ++ #if defined(_SC_KERNEL_BITS) ++ switch (bits) ++ { ++ case 64: puts ("hppa2.0w"); break; ++ case 32: puts ("hppa2.0n"); break; ++ default: puts ("hppa2.0"); break; ++ } break; ++ #else /* !defined(_SC_KERNEL_BITS) */ ++ puts ("hppa2.0"); break; ++ #endif ++ default: puts ("hppa1.0"); break; ++ } ++ exit (0); ++ } ++EOF ++ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` ++ test -z "$HP_ARCH" && HP_ARCH=hppa ++ fi ;; ++ esac ++ if [ ${HP_ARCH} = "hppa2.0w" ] ++ then ++ eval $set_cc_for_build ++ ++ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating ++ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler ++ # generating 64-bit code. GNU and HP use different nomenclature: ++ # ++ # $ CC_FOR_BUILD=cc ./config.guess ++ # => hppa2.0w-hp-hpux11.23 ++ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess ++ # => hppa64-hp-hpux11.23 ++ ++ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | ++ grep __LP64__ >/dev/null ++ then ++ HP_ARCH="hppa2.0w" ++ else ++ HP_ARCH="hppa64" ++ fi ++ fi ++ echo ${HP_ARCH}-hp-hpux${HPUX_REV} ++ exit ;; ++ ia64:HP-UX:*:*) ++ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` ++ echo ia64-hp-hpux${HPUX_REV} ++ exit ;; ++ 3050*:HI-UX:*:*) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #include <unistd.h> ++ int ++ main () ++ { ++ long cpu = sysconf (_SC_CPU_VERSION); ++ /* The order matters, because CPU_IS_HP_MC68K erroneously returns ++ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct ++ results, however. */ ++ if (CPU_IS_PA_RISC (cpu)) ++ { ++ switch (cpu) ++ { ++ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; ++ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; ++ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; ++ default: puts ("hppa-hitachi-hiuxwe2"); break; ++ } ++ } ++ else if (CPU_IS_HP_MC68K (cpu)) ++ puts ("m68k-hitachi-hiuxwe2"); ++ else puts ("unknown-hitachi-hiuxwe2"); ++ exit (0); ++ } ++EOF ++ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && ++ { echo "$SYSTEM_NAME"; exit; } ++ echo unknown-hitachi-hiuxwe2 ++ exit ;; ++ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) ++ echo hppa1.1-hp-bsd ++ exit ;; ++ 9000/8??:4.3bsd:*:*) ++ echo hppa1.0-hp-bsd ++ exit ;; ++ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) ++ echo hppa1.0-hp-mpeix ++ exit ;; ++ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) ++ echo hppa1.1-hp-osf ++ exit ;; ++ hp8??:OSF1:*:*) ++ echo hppa1.0-hp-osf ++ exit ;; ++ i*86:OSF1:*:*) ++ if [ -x /usr/sbin/sysversion ] ; then ++ echo ${UNAME_MACHINE}-unknown-osf1mk ++ else ++ echo ${UNAME_MACHINE}-unknown-osf1 ++ fi ++ exit ;; ++ parisc*:Lites*:*:*) ++ echo hppa1.1-hp-lites ++ exit ;; ++ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) ++ echo c1-convex-bsd ++ exit ;; ++ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) ++ if getsysinfo -f scalar_acc ++ then echo c32-convex-bsd ++ else echo c2-convex-bsd ++ fi ++ exit ;; ++ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) ++ echo c34-convex-bsd ++ exit ;; ++ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) ++ echo c38-convex-bsd ++ exit ;; ++ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) ++ echo c4-convex-bsd ++ exit ;; ++ CRAY*Y-MP:*:*:*) ++ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' ++ exit ;; ++ CRAY*[A-Z]90:*:*:*) ++ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ ++ | sed -e 's/CRAY.*([A-Z]90)/\1/' \ ++ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ ++ -e 's/.[^.]*$/.X/' ++ exit ;; ++ CRAY*TS:*:*:*) ++ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' ++ exit ;; ++ CRAY*T3E:*:*:*) ++ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' ++ exit ;; ++ CRAY*SV1:*:*:*) ++ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' ++ exit ;; ++ *:UNICOS/mp:*:*) ++ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/.[^.]*$/.X/' ++ exit ;; ++ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) ++ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` ++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's////'` ++ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` ++ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" ++ exit ;; ++ 5000:UNIX_System_V:4.*:*) ++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's////'` ++ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` ++ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" ++ exit ;; ++ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) ++ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} ++ exit ;; ++ sparc*:BSD/OS:*:*) ++ echo sparc-unknown-bsdi${UNAME_RELEASE} ++ exit ;; ++ *:BSD/OS:*:*) ++ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} ++ exit ;; ++ *:FreeBSD:*:*) ++ case ${UNAME_MACHINE} in ++ pc98) ++ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; ++ *) ++ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; ++ esac ++ exit ;; ++ i*:CYGWIN*:*) ++ echo ${UNAME_MACHINE}-pc-cygwin ++ exit ;; ++ i*:MINGW*:*) ++ echo ${UNAME_MACHINE}-pc-mingw32 ++ exit ;; ++ i*:MSYS_NT-*:*:*) ++ echo ${UNAME_MACHINE}-pc-mingw32 ++ exit ;; ++ i*:windows32*:*) ++ # uname -m includes "-pc" on this system. ++ echo ${UNAME_MACHINE}-mingw32 ++ exit ;; ++ i*:PW*:*) ++ echo ${UNAME_MACHINE}-pc-pw32 ++ exit ;; ++ x86:Interix*:[345]*) ++ echo i586-pc-interix${UNAME_RELEASE} ++ exit ;; ++ EM64T:Interix*:[345]*) ++ echo x86_64-unknown-interix${UNAME_RELEASE} ++ exit ;; ++ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) ++ echo i${UNAME_MACHINE}-pc-mks ++ exit ;; ++ i*:Windows_NT*:* | Pentium*:Windows_NT*:*) ++ # How do we know it's Interix rather than the generic POSIX subsystem? ++ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we ++ # UNAME_MACHINE based on the output of uname instead of i386? ++ echo i586-pc-interix ++ exit ;; ++ i*:UWIN*:*) ++ echo ${UNAME_MACHINE}-pc-uwin ++ exit ;; ++ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) ++ echo x86_64-unknown-cygwin ++ exit ;; ++ p*:CYGWIN*:*) ++ echo powerpcle-unknown-cygwin ++ exit ;; ++ prep*:SunOS:5.*:*) ++ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` ++ exit ;; ++ *:GNU:*:*) ++ # the GNU system ++ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` ++ exit ;; ++ *:GNU/*:*:*) ++ # other systems with GNU libc and userland ++ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu ++ exit ;; ++ i*86:Minix:*:*) ++ echo ${UNAME_MACHINE}-pc-minix ++ exit ;; ++ arm*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ cris:Linux:*:*) ++ echo cris-axis-linux-${LIBC} ++ exit ;; ++ crisv32:Linux:*:*) ++ echo crisv32-axis-linux-${LIBC} ++ exit ;; ++ frv:Linux:*:*) ++ echo frv-unknown-linux-${LIBC} ++ exit ;; ++ ia64:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ m32r*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ m68*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ mips:Linux:*:*) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #undef CPU ++ #undef mips ++ #undef mipsel ++ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) ++ CPU=mipsel ++ #else ++ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) ++ CPU=mips ++ #else ++ CPU= ++ #endif ++ #endif ++EOF ++ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' ++ /^CPU/{ ++ s: ::g ++ p ++ }'`" ++ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ++ ;; ++ mips64:Linux:*:*) ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #undef CPU ++ #undef mips64 ++ #undef mips64el ++ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) ++ CPU=mips64el ++ #else ++ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) ++ CPU=mips64 ++ #else ++ CPU= ++ #endif ++ #endif ++EOF ++ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' ++ /^CPU/{ ++ s: ::g ++ p ++ }'`" ++ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ++ ;; ++ or32:Linux:*:*) ++ echo or32-unknown-linux-${LIBC} ++ exit ;; ++ ppc:Linux:*:*) ++ echo powerpc-unknown-linux-${LIBC} ++ exit ;; ++ ppc64:Linux:*:*) ++ echo powerpc64-unknown-linux-${LIBC} ++ exit ;; ++ alpha:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: (.*)/\1/p' < /proc/cpuinfo` in ++ EV5) UNAME_MACHINE=alphaev5 ;; ++ EV56) UNAME_MACHINE=alphaev56 ;; ++ PCA56) UNAME_MACHINE=alphapca56 ;; ++ PCA57) UNAME_MACHINE=alphapca56 ;; ++ EV6) UNAME_MACHINE=alphaev6 ;; ++ EV67) UNAME_MACHINE=alphaev67 ;; ++ EV68*) UNAME_MACHINE=alphaev68 ;; ++ esac ++ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null ++ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ parisc:Linux:*:* | hppa:Linux:*:*) ++ # Look for CPU level ++ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in ++ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; ++ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; ++ *) echo hppa-unknown-linux-${LIBC} ;; ++ esac ++ exit ;; ++ parisc64:Linux:*:* | hppa64:Linux:*:*) ++ echo hppa64-unknown-linux-${LIBC} ++ exit ;; ++ s390:Linux:*:* | s390x:Linux:*:*) ++ echo ${UNAME_MACHINE}-ibm-linux ++ exit ;; ++ sh64*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ sh*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ sparc:Linux:*:* | sparc64:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ vax:Linux:*:*) ++ echo ${UNAME_MACHINE}-dec-linux-${LIBC} ++ exit ;; ++ x86_64:Linux:*:*) ++ echo x86_64-unknown-linux-${LIBC} ++ exit ;; ++ i*86:Linux:*:*) ++ # The BFD linker knows what the default object file format is, so ++ # first see if it will tell us. cd to the root directory to prevent ++ # problems with other programs or directories called `ld' in the path. ++ # Set LC_ALL=C to ensure ld outputs messages in English. ++ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ ++ | sed -ne '/supported targets:/!d ++ s/[ ][ ]*/ /g ++ s/.*supported targets: *// ++ s/ .*// ++ p'` ++ case "$ld_supported_targets" in ++ elf32-i386) ++ TENTATIVE="${UNAME_MACHINE}-pc-linux-${LIBC}" ++ ;; ++ a.out-i386-linux) ++ echo "${UNAME_MACHINE}-pc-linux-${LIBC}aout" ++ exit ;; ++ coff-i386) ++ echo "${UNAME_MACHINE}-pc-linux-${LIBC}coff" ++ exit ;; ++ "") ++ # Either a pre-BFD a.out linker (linux-gnuoldld) or ++ # one that does not give us useful --help. ++ echo "${UNAME_MACHINE}-pc-linux-${LIBC}oldld" ++ exit ;; ++ esac ++ # This should get integrated into the C code below, but now we hack ++ if [ "$LIBC" != "gnu" ] ; then echo "$TENTATIVE" && exit 0 ; fi ++ # Determine whether the default compiler is a.out or elf ++ eval $set_cc_for_build ++ sed 's/^ //' << EOF >$dummy.c ++ #include <features.h> ++ #ifdef __ELF__ ++ # ifdef __GLIBC__ ++ # if __GLIBC__ >= 2 ++ LIBC=gnu ++ # else ++ LIBC=gnulibc1 ++ # endif ++ # else ++ LIBC=gnulibc1 ++ # endif ++ #else ++ #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun) ++ LIBC=gnu ++ #else ++ LIBC=gnuaout ++ #endif ++ #endif ++ #ifdef __dietlibc__ ++ LIBC=dietlibc ++ #endif ++EOF ++ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' ++ /^LIBC/{ ++ s: ::g ++ p ++ }'`" ++ test x"${LIBC}" != x && { ++ echo "${UNAME_MACHINE}-pc-linux-${LIBC}" ++ exit ++ } ++ test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ++ ;; ++ i*86:DYNIX/ptx:4*:*) ++ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. ++ # earlier versions are messed up and put the nodename in both ++ # sysname and nodename. ++ echo i386-sequent-sysv4 ++ exit ;; ++ i*86:UNIX_SV:4.2MP:2.*) ++ # Unixware is an offshoot of SVR4, but it has its own version ++ # number series starting with 2... ++ # I am not positive that other SVR4 systems won't match this, ++ # I just have to hope. -- rms. ++ # Use sysv4.2uw... so that sysv4* matches it. ++ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} ++ exit ;; ++ i*86:OS/2:*:*) ++ # If we were able to find `uname', then EMX Unix compatibility ++ # is probably installed. ++ echo ${UNAME_MACHINE}-pc-os2-emx ++ exit ;; ++ i*86:XTS-300:*:STOP) ++ echo ${UNAME_MACHINE}-unknown-stop ++ exit ;; ++ i*86:atheos:*:*) ++ echo ${UNAME_MACHINE}-unknown-atheos ++ exit ;; ++ i*86:syllable:*:*) ++ echo ${UNAME_MACHINE}-pc-syllable ++ exit ;; ++ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) ++ echo i386-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ i*86:*DOS:*:*) ++ echo ${UNAME_MACHINE}-pc-msdosdjgpp ++ exit ;; ++ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) ++ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's//MP$//'` ++ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then ++ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} ++ else ++ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} ++ fi ++ exit ;; ++ i*86:*:5:[678]*) ++ # UnixWare 7.x, OpenUNIX and OpenServer 6. ++ case `/bin/uname -X | grep "^Machine"` in ++ *486*) UNAME_MACHINE=i486 ;; ++ *Pentium) UNAME_MACHINE=i586 ;; ++ *Pent*|*Celeron) UNAME_MACHINE=i686 ;; ++ esac ++ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ++ exit ;; ++ i*86:*:3.2:*) ++ if test -f /usr/options/cb.name; then ++ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` ++ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL ++ elif /bin/uname -X 2>/dev/null >/dev/null ; then ++ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` ++ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 ++ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ ++ && UNAME_MACHINE=i586 ++ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ ++ && UNAME_MACHINE=i686 ++ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ ++ && UNAME_MACHINE=i686 ++ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL ++ else ++ echo ${UNAME_MACHINE}-pc-sysv32 ++ fi ++ exit ;; ++ pc:*:*:*) ++ # Left here for compatibility: ++ # uname -m prints for DJGPP always 'pc', but it prints nothing about ++ # the processor, so we play safe by assuming i386. ++ echo i386-pc-msdosdjgpp ++ exit ;; ++ Intel:Mach:3*:*) ++ echo i386-pc-mach3 ++ exit ;; ++ paragon:*:*:*) ++ echo i860-intel-osf1 ++ exit ;; ++ i860:*:4.*:*) # i860-SVR4 ++ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then ++ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 ++ else # Add other i860-SVR4 vendors below as they are discovered. ++ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 ++ fi ++ exit ;; ++ mini*:CTIX:SYS*5:*) ++ # "miniframe" ++ echo m68010-convergent-sysv ++ exit ;; ++ mc68k:UNIX:SYSTEM5:3.51m) ++ echo m68k-convergent-sysv ++ exit ;; ++ M680?0:D-NIX:5.3:*) ++ echo m68k-diab-dnix ++ exit ;; ++ M68*:*:R3V[5678]*:*) ++ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; ++ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) ++ OS_REL='' ++ test -r /etc/.relid \ ++ && OS_REL=.`sed -n 's/[^ ]* [^ ]* ([0-9][0-9]).*/\1/p' < /etc/.relid` ++ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ ++ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } ++ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ ++ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; ++ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) ++ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ ++ && { echo i486-ncr-sysv4; exit; } ;; ++ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) ++ echo m68k-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ mc68030:UNIX_System_V:4.*:*) ++ echo m68k-atari-sysv4 ++ exit ;; ++ TSUNAMI:LynxOS:2.*:*) ++ echo sparc-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ rs6000:LynxOS:2.*:*) ++ echo rs6000-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) ++ echo powerpc-unknown-lynxos${UNAME_RELEASE} ++ exit ;; ++ SM[BE]S:UNIX_SV:*:*) ++ echo mips-dde-sysv${UNAME_RELEASE} ++ exit ;; ++ RM*:ReliantUNIX-*:*:*) ++ echo mips-sni-sysv4 ++ exit ;; ++ RM*:SINIX-*:*:*) ++ echo mips-sni-sysv4 ++ exit ;; ++ *:SINIX-*:*:*) ++ if uname -p 2>/dev/null >/dev/null ; then ++ UNAME_MACHINE=`(uname -p) 2>/dev/null` ++ echo ${UNAME_MACHINE}-sni-sysv4 ++ else ++ echo ns32k-sni-sysv ++ fi ++ exit ;; ++ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort ++ # says <Richard.M.Bartel@ccMail.Census.GOV> ++ echo i586-unisys-sysv4 ++ exit ;; ++ *:UNIX_System_V:4*:FTX*) ++ # From Gerald Hewes <hewes@openmarket.com>. ++ # How about differentiating between stratus architectures? -djm ++ echo hppa1.1-stratus-sysv4 ++ exit ;; ++ *:*:*:FTX*) ++ # From seanf@swdc.stratus.com. ++ echo i860-stratus-sysv4 ++ exit ;; ++ i*86:VOS:*:*) ++ # From Paul.Green@stratus.com. ++ echo ${UNAME_MACHINE}-stratus-vos ++ exit ;; ++ *:VOS:*:*) ++ # From Paul.Green@stratus.com. ++ echo hppa1.1-stratus-vos ++ exit ;; ++ mc68*:A/UX:*:*) ++ echo m68k-apple-aux${UNAME_RELEASE} ++ exit ;; ++ news*:NEWS-OS:6*:*) ++ echo mips-sony-newsos6 ++ exit ;; ++ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) ++ if [ -d /usr/nec ]; then ++ echo mips-nec-sysv${UNAME_RELEASE} ++ else ++ echo mips-unknown-sysv${UNAME_RELEASE} ++ fi ++ exit ;; ++ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. ++ echo powerpc-be-beos ++ exit ;; ++ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. ++ echo powerpc-apple-beos ++ exit ;; ++ BePC:BeOS:*:*) # BeOS running on Intel PC compatible. ++ echo i586-pc-beos ++ exit ;; ++ SX-4:SUPER-UX:*:*) ++ echo sx4-nec-superux${UNAME_RELEASE} ++ exit ;; ++ SX-5:SUPER-UX:*:*) ++ echo sx5-nec-superux${UNAME_RELEASE} ++ exit ;; ++ SX-6:SUPER-UX:*:*) ++ echo sx6-nec-superux${UNAME_RELEASE} ++ exit ;; ++ Power*:Rhapsody:*:*) ++ echo powerpc-apple-rhapsody${UNAME_RELEASE} ++ exit ;; ++ *:Rhapsody:*:*) ++ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} ++ exit ;; ++ *:Darwin:*:*) ++ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown ++ case $UNAME_PROCESSOR in ++ unknown) UNAME_PROCESSOR=powerpc ;; ++ esac ++ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} ++ exit ;; ++ *:procnto*:*:* | *:QNX:[0123456789]*:*) ++ UNAME_PROCESSOR=`uname -p` ++ if test "$UNAME_PROCESSOR" = "x86"; then ++ UNAME_PROCESSOR=i386 ++ UNAME_MACHINE=pc ++ fi ++ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} ++ exit ;; ++ *:QNX:*:4*) ++ echo i386-pc-qnx ++ exit ;; ++ NSE-?:NONSTOP_KERNEL:*:*) ++ echo nse-tandem-nsk${UNAME_RELEASE} ++ exit ;; ++ NSR-?:NONSTOP_KERNEL:*:*) ++ echo nsr-tandem-nsk${UNAME_RELEASE} ++ exit ;; ++ *:NonStop-UX:*:*) ++ echo mips-compaq-nonstopux ++ exit ;; ++ BS2000:POSIX*:*:*) ++ echo bs2000-siemens-sysv ++ exit ;; ++ DS/*:UNIX_System_V:*:*) ++ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} ++ exit ;; ++ *:Plan9:*:*) ++ # "uname -m" is not consistent, so use $cputype instead. 386 ++ # is converted to i386 for consistency with other x86 ++ # operating systems. ++ if test "$cputype" = "386"; then ++ UNAME_MACHINE=i386 ++ else ++ UNAME_MACHINE="$cputype" ++ fi ++ echo ${UNAME_MACHINE}-unknown-plan9 ++ exit ;; ++ *:TOPS-10:*:*) ++ echo pdp10-unknown-tops10 ++ exit ;; ++ *:TENEX:*:*) ++ echo pdp10-unknown-tenex ++ exit ;; ++ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) ++ echo pdp10-dec-tops20 ++ exit ;; ++ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) ++ echo pdp10-xkl-tops20 ++ exit ;; ++ *:TOPS-20:*:*) ++ echo pdp10-unknown-tops20 ++ exit ;; ++ *:ITS:*:*) ++ echo pdp10-unknown-its ++ exit ;; ++ SEI:*:*:SEIUX) ++ echo mips-sei-seiux${UNAME_RELEASE} ++ exit ;; ++ *:DragonFly:*:*) ++ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ++ exit ;; ++ *:*VMS:*:*) ++ UNAME_MACHINE=`(uname -p) 2>/dev/null` ++ case "${UNAME_MACHINE}" in ++ A*) echo alpha-dec-vms ; exit ;; ++ I*) echo ia64-dec-vms ; exit ;; ++ V*) echo vax-dec-vms ; exit ;; ++ esac ;; ++ *:XENIX:*:SysV) ++ echo i386-pc-xenix ++ exit ;; ++ i*86:skyos:*:*) ++ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' ++ exit ;; ++ i*86:rdos:*:*) ++ echo ${UNAME_MACHINE}-pc-rdos ++ exit ;; ++esac ++ ++#echo '(No uname command or uname output not recognized.)' 1>&2 ++#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 ++ ++eval $set_cc_for_build ++cat >$dummy.c <<EOF ++#ifdef _SEQUENT_ ++# include <sys/types.h> ++# include <sys/utsname.h> ++#endif ++main () ++{ ++#if defined (sony) ++#if defined (MIPSEB) ++ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, ++ I don't know.... */ ++ printf ("mips-sony-bsd\n"); exit (0); ++#else ++#include <sys/param.h> ++ printf ("m68k-sony-newsos%s\n", ++#ifdef NEWSOS4 ++ "4" ++#else ++ "" ++#endif ++ ); exit (0); ++#endif ++#endif ++ ++#if defined (__arm) && defined (__acorn) && defined (__unix) ++ printf ("arm-acorn-riscix\n"); exit (0); ++#endif ++ ++#if defined (hp300) && !defined (hpux) ++ printf ("m68k-hp-bsd\n"); exit (0); ++#endif ++ ++#if defined (NeXT) ++#if !defined (__ARCHITECTURE__) ++#define __ARCHITECTURE__ "m68k" ++#endif ++ int version; ++ version=`(hostinfo | sed -n 's/.*NeXT Mach ([0-9]*).*/\1/p') 2>/dev/null`; ++ if (version < 4) ++ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); ++ else ++ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); ++ exit (0); ++#endif ++ ++#if defined (MULTIMAX) || defined (n16) ++#if defined (UMAXV) ++ printf ("ns32k-encore-sysv\n"); exit (0); ++#else ++#if defined (CMU) ++ printf ("ns32k-encore-mach\n"); exit (0); ++#else ++ printf ("ns32k-encore-bsd\n"); exit (0); ++#endif ++#endif ++#endif ++ ++#if defined (__386BSD__) ++ printf ("i386-pc-bsd\n"); exit (0); ++#endif ++ ++#if defined (sequent) ++#if defined (i386) ++ printf ("i386-sequent-dynix\n"); exit (0); ++#endif ++#if defined (ns32000) ++ printf ("ns32k-sequent-dynix\n"); exit (0); ++#endif ++#endif ++ ++#if defined (_SEQUENT_) ++ struct utsname un; ++ ++ uname(&un); ++ ++ if (strncmp(un.version, "V2", 2) == 0) { ++ printf ("i386-sequent-ptx2\n"); exit (0); ++ } ++ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ ++ printf ("i386-sequent-ptx1\n"); exit (0); ++ } ++ printf ("i386-sequent-ptx\n"); exit (0); ++ ++#endif ++ ++#if defined (vax) ++# if !defined (ultrix) ++# include <sys/param.h> ++# if defined (BSD) ++# if BSD == 43 ++ printf ("vax-dec-bsd4.3\n"); exit (0); ++# else ++# if BSD == 199006 ++ printf ("vax-dec-bsd4.3reno\n"); exit (0); ++# else ++ printf ("vax-dec-bsd\n"); exit (0); ++# endif ++# endif ++# else ++ printf ("vax-dec-bsd\n"); exit (0); ++# endif ++# else ++ printf ("vax-dec-ultrix\n"); exit (0); ++# endif ++#endif ++ ++#if defined (alliant) && defined (i860) ++ printf ("i860-alliant-bsd\n"); exit (0); ++#endif ++ ++ exit (1); ++} ++EOF ++ ++$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && ++ { echo "$SYSTEM_NAME"; exit; } ++ ++# Apollos put the system type in the environment. ++ ++test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } ++ ++# Convex versions that predate uname can use getsysinfo(1) ++ ++if [ -x /usr/convex/getsysinfo ] ++then ++ case `getsysinfo -f cpu_type` in ++ c1*) ++ echo c1-convex-bsd ++ exit ;; ++ c2*) ++ if getsysinfo -f scalar_acc ++ then echo c32-convex-bsd ++ else echo c2-convex-bsd ++ fi ++ exit ;; ++ c34*) ++ echo c34-convex-bsd ++ exit ;; ++ c38*) ++ echo c38-convex-bsd ++ exit ;; ++ c4*) ++ echo c4-convex-bsd ++ exit ;; ++ esac ++fi ++ ++cat >&2 <<EOF ++$0: unable to guess system type ++ ++This script, last modified $timestamp, has failed to recognize ++the operating system you are using. It is advised that you ++download the most up to date version of the config scripts from ++ ++ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess ++and ++ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub ++ ++If the version you run ($0) is already up to date, please ++send the following data and any information you think might be ++pertinent to <config-patches@gnu.org> in order to provide the needed ++information to handle your system. ++ ++config.guess timestamp = $timestamp ++ ++uname -m = `(uname -m) 2>/dev/null || echo unknown` ++uname -r = `(uname -r) 2>/dev/null || echo unknown` ++uname -s = `(uname -s) 2>/dev/null || echo unknown` ++uname -v = `(uname -v) 2>/dev/null || echo unknown` ++ ++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` ++/bin/uname -X = `(/bin/uname -X) 2>/dev/null` ++ ++hostinfo = `(hostinfo) 2>/dev/null` ++/bin/universe = `(/bin/universe) 2>/dev/null` ++/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` ++/bin/arch = `(/bin/arch) 2>/dev/null` ++/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` ++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` ++ ++UNAME_MACHINE = ${UNAME_MACHINE} ++UNAME_RELEASE = ${UNAME_RELEASE} ++UNAME_SYSTEM = ${UNAME_SYSTEM} ++UNAME_VERSION = ${UNAME_VERSION} ++EOF ++ ++exit 1 ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "timestamp='" ++# time-stamp-format: "%:y-%02m-%02d" ++# time-stamp-end: "'" ++# End: +diff -urN lua-5.1.4/config.h.in lua-5.1.4-autotoolize/config.h.in +--- lua-5.1.4/config.h.in 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/config.h.in 2008-09-03 13:18:23.000000000 +0200 +@@ -0,0 +1,64 @@ ++/* config.h.in. Generated from configure.ac by autoheader. */ ++ ++/* Define to 1 if you have the <dlfcn.h> header file. */ ++#undef HAVE_DLFCN_H ++ ++/* Define to 1 if you have the <inttypes.h> header file. */ ++#undef HAVE_INTTYPES_H ++ ++/* Define to 1 if you have the `readline' library (-lreadline). */ ++#undef HAVE_LIBREADLINE ++ ++/* Define to 1 if you have the <memory.h> header file. */ ++#undef HAVE_MEMORY_H ++ ++/* Define to 1 if you have the <readline/history.h> header file. */ ++#undef HAVE_READLINE_HISTORY_H ++ ++/* Define to 1 if you have the <readline/readline.h> header file. */ ++#undef HAVE_READLINE_READLINE_H ++ ++/* Define to 1 if you have the <stdint.h> header file. */ ++#undef HAVE_STDINT_H ++ ++/* Define to 1 if you have the <stdlib.h> header file. */ ++#undef HAVE_STDLIB_H ++ ++/* Define to 1 if you have the <strings.h> header file. */ ++#undef HAVE_STRINGS_H ++ ++/* Define to 1 if you have the <string.h> header file. */ ++#undef HAVE_STRING_H ++ ++/* Define to 1 if you have the <sys/stat.h> header file. */ ++#undef HAVE_SYS_STAT_H ++ ++/* Define to 1 if you have the <sys/types.h> header file. */ ++#undef HAVE_SYS_TYPES_H ++ ++/* Define to 1 if you have the <unistd.h> header file. */ ++#undef HAVE_UNISTD_H ++ ++/* Name of package */ ++#undef PACKAGE ++ ++/* Define to the address where bug reports for this package should be sent. */ ++#undef PACKAGE_BUGREPORT ++ ++/* Define to the full name of this package. */ ++#undef PACKAGE_NAME ++ ++/* Define to the full name and version of this package. */ ++#undef PACKAGE_STRING ++ ++/* Define to the one symbol short name of this package. */ ++#undef PACKAGE_TARNAME ++ ++/* Define to the version of this package. */ ++#undef PACKAGE_VERSION ++ ++/* Define to 1 if you have the ANSI C header files. */ ++#undef STDC_HEADERS ++ ++/* Version number of package */ ++#undef VERSION +diff -urN lua-5.1.4/config.sub lua-5.1.4-autotoolize/config.sub +--- lua-5.1.4/config.sub 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/config.sub 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,1627 @@ ++#! /bin/sh ++# Configuration validation subroutine script. ++# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, ++# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, ++# Inc. ++ ++timestamp='2006-02-27' ++ ++# This file is (in principle) common to ALL GNU software. ++# The presence of a machine in this file suggests that SOME GNU software ++# can handle that machine. It does not imply ALL GNU software can. ++# ++# This file is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA ++# 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++ ++# Please send patches to <config-patches@gnu.org>. Submit a context ++# diff and a properly formatted ChangeLog entry. ++# ++# Configuration subroutine to validate and canonicalize a configuration type. ++# Supply the specified configuration type as an argument. ++# If it is invalid, we print an error message on stderr and exit with code 1. ++# Otherwise, we print the canonical config type on stdout and succeed. ++ ++# This file is supposed to be the same for all GNU packages ++# and recognize all the CPU types, system types and aliases ++# that are meaningful with *any* GNU software. ++# Each package is responsible for reporting which valid configurations ++# it does not support. The user should be able to distinguish ++# a failure to support a valid configuration from a meaningless ++# configuration. ++ ++# The goal of this file is to map all the various variations of a given ++# machine specification into a single specification in the form: ++# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM ++# or in some cases, the newer four-part form: ++# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM ++# It is wrong to echo any other type of specification. ++ ++me=`echo "$0" | sed -e 's,.*/,,'` ++ ++usage="\ ++Usage: $0 [OPTION] CPU-MFR-OPSYS ++ $0 [OPTION] ALIAS ++ ++Canonicalize a configuration name. ++ ++Operation modes: ++ -h, --help print this help, then exit ++ -t, --time-stamp print date of last modification, then exit ++ -v, --version print version number, then exit ++ ++Report bugs and patches to <config-patches@gnu.org>." ++ ++version="\ ++GNU config.sub ($timestamp) ++ ++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ++Free Software Foundation, Inc. ++ ++This is free software; see the source for copying conditions. There is NO ++warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ++ ++help=" ++Try `$me --help' for more information." ++ ++# Parse command line ++while test $# -gt 0 ; do ++ case $1 in ++ --time-stamp | --time* | -t ) ++ echo "$timestamp" ; exit ;; ++ --version | -v ) ++ echo "$version" ; exit ;; ++ --help | --h* | -h ) ++ echo "$usage"; exit ;; ++ -- ) # Stop option processing ++ shift; break ;; ++ - ) # Use stdin as input. ++ break ;; ++ -* ) ++ echo "$me: invalid option $1$help" ++ exit 1 ;; ++ ++ *local*) ++ # First pass through any local machine types. ++ echo $1 ++ exit ;; ++ ++ * ) ++ break ;; ++ esac ++done ++ ++case $# in ++ 0) echo "$me: missing argument$help" >&2 ++ exit 1;; ++ 1) ;; ++ *) echo "$me: too many arguments$help" >&2 ++ exit 1;; ++esac ++ ++# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). ++# Here we must recognize all the valid KERNEL-OS combinations. ++maybe_os=`echo $1 | sed 's/^(.*)-([^-]*-[^-]*)$/\2/'` ++case $maybe_os in ++ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ ++ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ ++ storm-chaos* | os2-emx* | rtmk-nova*) ++ os=-$maybe_os ++ basic_machine=`echo $1 | sed 's/^(.*)-([^-]*-[^-]*)$/\1/'` ++ ;; ++ *) ++ basic_machine=`echo $1 | sed 's/-[^-]*$//'` ++ if [ $basic_machine != $1 ] ++ then os=`echo $1 | sed 's/.*-/-/'` ++ else os=; fi ++ ;; ++esac ++ ++### Let's recognize common machines as not being operating systems so ++### that things like config.sub decstation-3100 work. We also ++### recognize some manufacturers as not being operating systems, so we ++### can provide default operating systems below. ++case $os in ++ -sun*os*) ++ # Prevent following clause from handling this invalid input. ++ ;; ++ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ ++ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ ++ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ ++ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ ++ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ ++ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ ++ -apple | -axis | -knuth | -cray) ++ os= ++ basic_machine=$1 ++ ;; ++ -sim | -cisco | -oki | -wec | -winbond) ++ os= ++ basic_machine=$1 ++ ;; ++ -scout) ++ ;; ++ -wrs) ++ os=-vxworks ++ basic_machine=$1 ++ ;; ++ -chorusos*) ++ os=-chorusos ++ basic_machine=$1 ++ ;; ++ -chorusrdb) ++ os=-chorusrdb ++ basic_machine=$1 ++ ;; ++ -hiux*) ++ os=-hiuxwe2 ++ ;; ++ -sco6) ++ os=-sco5v6 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco5) ++ os=-sco3.2v5 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco4) ++ os=-sco3.2v4 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco3.2.[4-9]*) ++ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco3.2v[4-9]*) ++ # Don't forget version if it is 3.2v4 or newer. ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco5v6*) ++ # Don't forget version if it is 3.2v4 or newer. ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -sco*) ++ os=-sco3.2v2 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -udk*) ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -isc) ++ os=-isc2.2 ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -clix*) ++ basic_machine=clipper-intergraph ++ ;; ++ -isc*) ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ++ ;; ++ -lynx*) ++ os=-lynxos ++ ;; ++ -ptx*) ++ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ++ ;; ++ -windowsnt*) ++ os=`echo $os | sed -e 's/windowsnt/winnt/'` ++ ;; ++ -psos*) ++ os=-psos ++ ;; ++ -mint | -mint[0-9]*) ++ basic_machine=m68k-atari ++ os=-mint ++ ;; ++esac ++ ++# Decode aliases for certain CPU-COMPANY combinations. ++case $basic_machine in ++ # Recognize the basic CPU types without company name. ++ # Some are omitted here because they have special meanings below. ++ 1750a | 580 \ ++ | a29k \ ++ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ ++ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ ++ | am33_2.0 \ ++ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ ++ | bfin \ ++ | c4x | clipper \ ++ | d10v | d30v | dlx | dsp16xx | dvp \ ++ | fr30 | frv \ ++ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ ++ | i370 | i860 | i960 | ia64 \ ++ | ip2k | iq2000 \ ++ | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \ ++ | mips | mipsbe | mipseb | mipsel | mipsle \ ++ | mips16 \ ++ | mips64 | mips64el \ ++ | mips64vr | mips64vrel \ ++ | mips64orion | mips64orionel \ ++ | mips64vr4100 | mips64vr4100el \ ++ | mips64vr4300 | mips64vr4300el \ ++ | mips64vr5000 | mips64vr5000el \ ++ | mips64vr5900 | mips64vr5900el \ ++ | mipsisa32 | mipsisa32el \ ++ | mipsisa32r2 | mipsisa32r2el \ ++ | mipsisa64 | mipsisa64el \ ++ | mipsisa64r2 | mipsisa64r2el \ ++ | mipsisa64sb1 | mipsisa64sb1el \ ++ | mipsisa64sr71k | mipsisa64sr71kel \ ++ | mipstx39 | mipstx39el \ ++ | mn10200 | mn10300 \ ++ | mt \ ++ | msp430 \ ++ | nios | nios2 \ ++ | ns16k | ns32k \ ++ | or32 \ ++ | pdp10 | pdp11 | pj | pjl \ ++ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ ++ | pyramid \ ++ | sh | sh[1234] | sh[24]a | sh[24]a*eb | sh[23]e | sh[34]eb | shbe | sheb | shle | sh[1234]le | sh3ele \ ++ | sh64 | sh64le \ ++ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ ++ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ ++ | strongarm \ ++ | tahoe | thumb | tic4x | tic80 | tron \ ++ | v850 | v850e \ ++ | we32k \ ++ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ ++ | z8k) ++ basic_machine=$basic_machine-unknown ++ ;; ++ m32c) ++ basic_machine=$basic_machine-unknown ++ ;; ++ m6811 | m68hc11 | m6812 | m68hc12) ++ # Motorola 68HC11/12. ++ basic_machine=$basic_machine-unknown ++ os=-none ++ ;; ++ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ++ ;; ++ ms1) ++ basic_machine=mt-unknown ++ ;; ++ ++ # We use `pc' rather than `unknown' ++ # because (1) that's what they normally are, and ++ # (2) the word "unknown" tends to confuse beginning users. ++ i*86 | x86_64) ++ basic_machine=$basic_machine-pc ++ ;; ++ # Object if more than one company name word. ++ *-*-*) ++ echo Invalid configuration `$1': machine `$basic_machine' not recognized 1>&2 ++ exit 1 ++ ;; ++ # Recognize the basic CPU types with company name. ++ 580-* \ ++ | a29k-* \ ++ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ ++ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ ++ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ ++ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ ++ | avr-* \ ++ | bfin-* | bs2000-* \ ++ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ ++ | clipper-* | craynv-* | cydra-* \ ++ | d10v-* | d30v-* | dlx-* \ ++ | elxsi-* \ ++ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ ++ | h8300-* | h8500-* \ ++ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ ++ | i*86-* | i860-* | i960-* | ia64-* \ ++ | ip2k-* | iq2000-* \ ++ | m32r-* | m32rle-* \ ++ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ ++ | m88110-* | m88k-* | maxq-* | mcore-* \ ++ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ ++ | mips16-* \ ++ | mips64-* | mips64el-* \ ++ | mips64vr-* | mips64vrel-* \ ++ | mips64orion-* | mips64orionel-* \ ++ | mips64vr4100-* | mips64vr4100el-* \ ++ | mips64vr4300-* | mips64vr4300el-* \ ++ | mips64vr5000-* | mips64vr5000el-* \ ++ | mips64vr5900-* | mips64vr5900el-* \ ++ | mipsisa32-* | mipsisa32el-* \ ++ | mipsisa32r2-* | mipsisa32r2el-* \ ++ | mipsisa64-* | mipsisa64el-* \ ++ | mipsisa64r2-* | mipsisa64r2el-* \ ++ | mipsisa64sb1-* | mipsisa64sb1el-* \ ++ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ ++ | mipstx39-* | mipstx39el-* \ ++ | mmix-* \ ++ | mt-* \ ++ | msp430-* \ ++ | nios-* | nios2-* \ ++ | none-* | np1-* | ns16k-* | ns32k-* \ ++ | orion-* \ ++ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ ++ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ ++ | pyramid-* \ ++ | romp-* | rs6000-* \ ++ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]a*eb-* | sh[23]e-* | sh[34]eb-* | shbe-* | sheb-* \ ++ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ ++ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ ++ | sparclite-* \ ++ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ ++ | tahoe-* | thumb-* \ ++ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ ++ | tron-* \ ++ | v850-* | v850e-* | vax-* \ ++ | we32k-* \ ++ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ ++ | xstormy16-* | xtensa-* \ ++ | ymp-* \ ++ | z8k-*) ++ ;; ++ m32c-*) ++ ;; ++ # Recognize the various machine names and aliases which stand ++ # for a CPU type and a company and sometimes even an OS. ++ 386bsd) ++ basic_machine=i386-unknown ++ os=-bsd ++ ;; ++ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) ++ basic_machine=m68000-att ++ ;; ++ 3b*) ++ basic_machine=we32k-att ++ ;; ++ a29khif) ++ basic_machine=a29k-amd ++ os=-udi ++ ;; ++ abacus) ++ basic_machine=abacus-unknown ++ ;; ++ adobe68k) ++ basic_machine=m68010-adobe ++ os=-scout ++ ;; ++ alliant | fx80) ++ basic_machine=fx80-alliant ++ ;; ++ altos | altos3068) ++ basic_machine=m68k-altos ++ ;; ++ am29k) ++ basic_machine=a29k-none ++ os=-bsd ++ ;; ++ amd64) ++ basic_machine=x86_64-pc ++ ;; ++ amd64-*) ++ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ amdahl) ++ basic_machine=580-amdahl ++ os=-sysv ++ ;; ++ amiga | amiga-*) ++ basic_machine=m68k-unknown ++ ;; ++ amigaos | amigados) ++ basic_machine=m68k-unknown ++ os=-amigaos ++ ;; ++ amigaunix | amix) ++ basic_machine=m68k-unknown ++ os=-sysv4 ++ ;; ++ apollo68) ++ basic_machine=m68k-apollo ++ os=-sysv ++ ;; ++ apollo68bsd) ++ basic_machine=m68k-apollo ++ os=-bsd ++ ;; ++ aux) ++ basic_machine=m68k-apple ++ os=-aux ++ ;; ++ balance) ++ basic_machine=ns32k-sequent ++ os=-dynix ++ ;; ++ c90) ++ basic_machine=c90-cray ++ os=-unicos ++ ;; ++ convex-c1) ++ basic_machine=c1-convex ++ os=-bsd ++ ;; ++ convex-c2) ++ basic_machine=c2-convex ++ os=-bsd ++ ;; ++ convex-c32) ++ basic_machine=c32-convex ++ os=-bsd ++ ;; ++ convex-c34) ++ basic_machine=c34-convex ++ os=-bsd ++ ;; ++ convex-c38) ++ basic_machine=c38-convex ++ os=-bsd ++ ;; ++ cray | j90) ++ basic_machine=j90-cray ++ os=-unicos ++ ;; ++ craynv) ++ basic_machine=craynv-cray ++ os=-unicosmp ++ ;; ++ cr16c) ++ basic_machine=cr16c-unknown ++ os=-elf ++ ;; ++ crds | unos) ++ basic_machine=m68k-crds ++ ;; ++ crisv32 | crisv32-* | etraxfs*) ++ basic_machine=crisv32-axis ++ ;; ++ cris | cris-* | etrax*) ++ basic_machine=cris-axis ++ ;; ++ crx) ++ basic_machine=crx-unknown ++ os=-elf ++ ;; ++ da30 | da30-*) ++ basic_machine=m68k-da30 ++ ;; ++ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) ++ basic_machine=mips-dec ++ ;; ++ decsystem10* | dec10*) ++ basic_machine=pdp10-dec ++ os=-tops10 ++ ;; ++ decsystem20* | dec20*) ++ basic_machine=pdp10-dec ++ os=-tops20 ++ ;; ++ delta | 3300 | motorola-3300 | motorola-delta \ ++ | 3300-motorola | delta-motorola) ++ basic_machine=m68k-motorola ++ ;; ++ delta88) ++ basic_machine=m88k-motorola ++ os=-sysv3 ++ ;; ++ djgpp) ++ basic_machine=i586-pc ++ os=-msdosdjgpp ++ ;; ++ dpx20 | dpx20-*) ++ basic_machine=rs6000-bull ++ os=-bosx ++ ;; ++ dpx2* | dpx2*-bull) ++ basic_machine=m68k-bull ++ os=-sysv3 ++ ;; ++ ebmon29k) ++ basic_machine=a29k-amd ++ os=-ebmon ++ ;; ++ elxsi) ++ basic_machine=elxsi-elxsi ++ os=-bsd ++ ;; ++ encore | umax | mmax) ++ basic_machine=ns32k-encore ++ ;; ++ es1800 | OSE68k | ose68k | ose | OSE) ++ basic_machine=m68k-ericsson ++ os=-ose ++ ;; ++ fx2800) ++ basic_machine=i860-alliant ++ ;; ++ genix) ++ basic_machine=ns32k-ns ++ ;; ++ gmicro) ++ basic_machine=tron-gmicro ++ os=-sysv ++ ;; ++ go32) ++ basic_machine=i386-pc ++ os=-go32 ++ ;; ++ h3050r* | hiux*) ++ basic_machine=hppa1.1-hitachi ++ os=-hiuxwe2 ++ ;; ++ h8300hms) ++ basic_machine=h8300-hitachi ++ os=-hms ++ ;; ++ h8300xray) ++ basic_machine=h8300-hitachi ++ os=-xray ++ ;; ++ h8500hms) ++ basic_machine=h8500-hitachi ++ os=-hms ++ ;; ++ harris) ++ basic_machine=m88k-harris ++ os=-sysv3 ++ ;; ++ hp300-*) ++ basic_machine=m68k-hp ++ ;; ++ hp300bsd) ++ basic_machine=m68k-hp ++ os=-bsd ++ ;; ++ hp300hpux) ++ basic_machine=m68k-hp ++ os=-hpux ++ ;; ++ hp3k9[0-9][0-9] | hp9[0-9][0-9]) ++ basic_machine=hppa1.0-hp ++ ;; ++ hp9k2[0-9][0-9] | hp9k31[0-9]) ++ basic_machine=m68000-hp ++ ;; ++ hp9k3[2-9][0-9]) ++ basic_machine=m68k-hp ++ ;; ++ hp9k6[0-9][0-9] | hp6[0-9][0-9]) ++ basic_machine=hppa1.0-hp ++ ;; ++ hp9k7[0-79][0-9] | hp7[0-79][0-9]) ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k78[0-9] | hp78[0-9]) ++ # FIXME: really hppa2.0-hp ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) ++ # FIXME: really hppa2.0-hp ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k8[0-9][13679] | hp8[0-9][13679]) ++ basic_machine=hppa1.1-hp ++ ;; ++ hp9k8[0-9][0-9] | hp8[0-9][0-9]) ++ basic_machine=hppa1.0-hp ++ ;; ++ hppa-next) ++ os=-nextstep3 ++ ;; ++ hppaosf) ++ basic_machine=hppa1.1-hp ++ os=-osf ++ ;; ++ hppro) ++ basic_machine=hppa1.1-hp ++ os=-proelf ++ ;; ++ i370-ibm* | ibm*) ++ basic_machine=i370-ibm ++ ;; ++# I'm not sure what "Sysv32" means. Should this be sysv3.2? ++ i*86v32) ++ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` ++ os=-sysv32 ++ ;; ++ i*86v4*) ++ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` ++ os=-sysv4 ++ ;; ++ i*86v) ++ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` ++ os=-sysv ++ ;; ++ i*86sol2) ++ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` ++ os=-solaris2 ++ ;; ++ i386mach) ++ basic_machine=i386-mach ++ os=-mach ++ ;; ++ i386-vsta | vsta) ++ basic_machine=i386-unknown ++ os=-vsta ++ ;; ++ iris | iris4d) ++ basic_machine=mips-sgi ++ case $os in ++ -irix*) ++ ;; ++ *) ++ os=-irix4 ++ ;; ++ esac ++ ;; ++ isi68 | isi) ++ basic_machine=m68k-isi ++ os=-sysv ++ ;; ++ m88k-omron*) ++ basic_machine=m88k-omron ++ ;; ++ magnum | m3230) ++ basic_machine=mips-mips ++ os=-sysv ++ ;; ++ merlin) ++ basic_machine=ns32k-utek ++ os=-sysv ++ ;; ++ mingw32) ++ basic_machine=i386-pc ++ os=-mingw32 ++ ;; ++ miniframe) ++ basic_machine=m68000-convergent ++ ;; ++ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) ++ basic_machine=m68k-atari ++ os=-mint ++ ;; ++ mipsEE* | ee | ps2) ++ basic_machine=mips64r5900el-scei ++ case $os in ++ -linux*) ++ ;; ++ *) ++ os=-elf ++ ;; ++ esac ++ ;; ++ iop) ++ basic_machine=mipsel-scei ++ os=-irx ++ ;; ++ dvp) ++ basic_machine=dvp-scei ++ os=-elf ++ ;; ++ mips3*-*) ++ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ++ ;; ++ mips3*) ++ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ++ ;; ++ monitor) ++ basic_machine=m68k-rom68k ++ os=-coff ++ ;; ++ morphos) ++ basic_machine=powerpc-unknown ++ os=-morphos ++ ;; ++ msdos) ++ basic_machine=i386-pc ++ os=-msdos ++ ;; ++ ms1-*) ++ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ++ ;; ++ mvs) ++ basic_machine=i370-ibm ++ os=-mvs ++ ;; ++ ncr3000) ++ basic_machine=i486-ncr ++ os=-sysv4 ++ ;; ++ netbsd386) ++ basic_machine=i386-unknown ++ os=-netbsd ++ ;; ++ netwinder) ++ basic_machine=armv4l-rebel ++ os=-linux ++ ;; ++ news | news700 | news800 | news900) ++ basic_machine=m68k-sony ++ os=-newsos ++ ;; ++ news1000) ++ basic_machine=m68030-sony ++ os=-newsos ++ ;; ++ news-3600 | risc-news) ++ basic_machine=mips-sony ++ os=-newsos ++ ;; ++ necv70) ++ basic_machine=v70-nec ++ os=-sysv ++ ;; ++ next | m*-next ) ++ basic_machine=m68k-next ++ case $os in ++ -nextstep* ) ++ ;; ++ -ns2*) ++ os=-nextstep2 ++ ;; ++ *) ++ os=-nextstep3 ++ ;; ++ esac ++ ;; ++ nh3000) ++ basic_machine=m68k-harris ++ os=-cxux ++ ;; ++ nh[45]000) ++ basic_machine=m88k-harris ++ os=-cxux ++ ;; ++ nindy960) ++ basic_machine=i960-intel ++ os=-nindy ++ ;; ++ mon960) ++ basic_machine=i960-intel ++ os=-mon960 ++ ;; ++ nonstopux) ++ basic_machine=mips-compaq ++ os=-nonstopux ++ ;; ++ np1) ++ basic_machine=np1-gould ++ ;; ++ nsr-tandem) ++ basic_machine=nsr-tandem ++ ;; ++ op50n-* | op60c-*) ++ basic_machine=hppa1.1-oki ++ os=-proelf ++ ;; ++ openrisc | openrisc-*) ++ basic_machine=or32-unknown ++ ;; ++ os400) ++ basic_machine=powerpc-ibm ++ os=-os400 ++ ;; ++ OSE68000 | ose68000) ++ basic_machine=m68000-ericsson ++ os=-ose ++ ;; ++ os68k) ++ basic_machine=m68k-none ++ os=-os68k ++ ;; ++ pa-hitachi) ++ basic_machine=hppa1.1-hitachi ++ os=-hiuxwe2 ++ ;; ++ paragon) ++ basic_machine=i860-intel ++ os=-osf ++ ;; ++ pbd) ++ basic_machine=sparc-tti ++ ;; ++ pbb) ++ basic_machine=m68k-tti ++ ;; ++ pc532 | pc532-*) ++ basic_machine=ns32k-pc532 ++ ;; ++ pc98) ++ basic_machine=i386-pc ++ ;; ++ pc98-*) ++ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pentium | p5 | k5 | k6 | nexgen | viac3) ++ basic_machine=i586-pc ++ ;; ++ pentiumpro | p6 | 6x86 | athlon | athlon_*) ++ basic_machine=i686-pc ++ ;; ++ pentiumii | pentium2 | pentiumiii | pentium3) ++ basic_machine=i686-pc ++ ;; ++ pentium4) ++ basic_machine=i786-pc ++ ;; ++ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) ++ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pentiumpro-* | p6-* | 6x86-* | athlon-*) ++ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) ++ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pentium4-*) ++ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ pn) ++ basic_machine=pn-gould ++ ;; ++ power) basic_machine=power-ibm ++ ;; ++ ppc) basic_machine=powerpc-unknown ++ ;; ++ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ ppcle | powerpclittle | ppc-le | powerpc-little) ++ basic_machine=powerpcle-unknown ++ ;; ++ ppcle-* | powerpclittle-*) ++ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ ppc64) basic_machine=powerpc64-unknown ++ ;; ++ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ ppc64le | powerpc64little | ppc64-le | powerpc64-little) ++ basic_machine=powerpc64le-unknown ++ ;; ++ ppc64le-* | powerpc64little-*) ++ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ;; ++ ps2) ++ basic_machine=i386-ibm ++ ;; ++ pw32) ++ basic_machine=i586-unknown ++ os=-pw32 ++ ;; ++ rdos) ++ basic_machine=i386-pc ++ os=-rdos ++ ;; ++ rom68k) ++ basic_machine=m68k-rom68k ++ os=-coff ++ ;; ++ rm[46]00) ++ basic_machine=mips-siemens ++ ;; ++ rtpc | rtpc-*) ++ basic_machine=romp-ibm ++ ;; ++ s390 | s390-*) ++ basic_machine=s390-ibm ++ ;; ++ s390x | s390x-*) ++ basic_machine=s390x-ibm ++ ;; ++ sa29200) ++ basic_machine=a29k-amd ++ os=-udi ++ ;; ++ sb1) ++ basic_machine=mipsisa64sb1-unknown ++ ;; ++ sb1el) ++ basic_machine=mipsisa64sb1el-unknown ++ ;; ++ sei) ++ basic_machine=mips-sei ++ os=-seiux ++ ;; ++ sequent) ++ basic_machine=i386-sequent ++ ;; ++ sh) ++ basic_machine=sh-hitachi ++ os=-hms ++ ;; ++ sh64) ++ basic_machine=sh64-unknown ++ ;; ++ sparclite-wrs | simso-wrs) ++ basic_machine=sparclite-wrs ++ os=-vxworks ++ ;; ++ sps7) ++ basic_machine=m68k-bull ++ os=-sysv2 ++ ;; ++ spur) ++ basic_machine=spur-unknown ++ ;; ++ st2000) ++ basic_machine=m68k-tandem ++ ;; ++ stratus) ++ basic_machine=i860-stratus ++ os=-sysv4 ++ ;; ++ sun2) ++ basic_machine=m68000-sun ++ ;; ++ sun2os3) ++ basic_machine=m68000-sun ++ os=-sunos3 ++ ;; ++ sun2os4) ++ basic_machine=m68000-sun ++ os=-sunos4 ++ ;; ++ sun3os3) ++ basic_machine=m68k-sun ++ os=-sunos3 ++ ;; ++ sun3os4) ++ basic_machine=m68k-sun ++ os=-sunos4 ++ ;; ++ sun4os3) ++ basic_machine=sparc-sun ++ os=-sunos3 ++ ;; ++ sun4os4) ++ basic_machine=sparc-sun ++ os=-sunos4 ++ ;; ++ sun4sol2) ++ basic_machine=sparc-sun ++ os=-solaris2 ++ ;; ++ sun3 | sun3-*) ++ basic_machine=m68k-sun ++ ;; ++ sun4) ++ basic_machine=sparc-sun ++ ;; ++ sun386 | sun386i | roadrunner) ++ basic_machine=i386-sun ++ ;; ++ sv1) ++ basic_machine=sv1-cray ++ os=-unicos ++ ;; ++ symmetry) ++ basic_machine=i386-sequent ++ os=-dynix ++ ;; ++ t3e) ++ basic_machine=alphaev5-cray ++ os=-unicos ++ ;; ++ t90) ++ basic_machine=t90-cray ++ os=-unicos ++ ;; ++ tic54x | c54x*) ++ basic_machine=tic54x-unknown ++ os=-coff ++ ;; ++ tic55x | c55x*) ++ basic_machine=tic55x-unknown ++ os=-coff ++ ;; ++ tic6x | c6x*) ++ basic_machine=tic6x-unknown ++ os=-coff ++ ;; ++ tx39) ++ basic_machine=mipstx39-unknown ++ ;; ++ tx39el) ++ basic_machine=mipstx39el-unknown ++ ;; ++ toad1) ++ basic_machine=pdp10-xkl ++ os=-tops20 ++ ;; ++ tower | tower-32) ++ basic_machine=m68k-ncr ++ ;; ++ tpf) ++ basic_machine=s390x-ibm ++ os=-tpf ++ ;; ++ udi29k) ++ basic_machine=a29k-amd ++ os=-udi ++ ;; ++ ultra3) ++ basic_machine=a29k-nyu ++ os=-sym1 ++ ;; ++ v810 | necv810) ++ basic_machine=v810-nec ++ os=-none ++ ;; ++ vaxv) ++ basic_machine=vax-dec ++ os=-sysv ++ ;; ++ vms) ++ basic_machine=vax-dec ++ os=-vms ++ ;; ++ vpp*|vx|vx-*) ++ basic_machine=f301-fujitsu ++ ;; ++ vxworks960) ++ basic_machine=i960-wrs ++ os=-vxworks ++ ;; ++ vxworks68) ++ basic_machine=m68k-wrs ++ os=-vxworks ++ ;; ++ vxworks29k) ++ basic_machine=a29k-wrs ++ os=-vxworks ++ ;; ++ w65*) ++ basic_machine=w65-wdc ++ os=-none ++ ;; ++ w89k-*) ++ basic_machine=hppa1.1-winbond ++ os=-proelf ++ ;; ++ xbox) ++ basic_machine=i686-pc ++ os=-mingw32 ++ ;; ++ xps | xps100) ++ basic_machine=xps100-honeywell ++ ;; ++ ymp) ++ basic_machine=ymp-cray ++ os=-unicos ++ ;; ++ z8k-*-coff) ++ basic_machine=z8k-unknown ++ os=-sim ++ ;; ++ none) ++ basic_machine=none-none ++ os=-none ++ ;; ++ ++# Here we handle the default manufacturer of certain CPU types. It is in ++# some cases the only manufacturer, in others, it is the most popular. ++ w89k) ++ basic_machine=hppa1.1-winbond ++ ;; ++ op50n) ++ basic_machine=hppa1.1-oki ++ ;; ++ op60c) ++ basic_machine=hppa1.1-oki ++ ;; ++ romp) ++ basic_machine=romp-ibm ++ ;; ++ mmix) ++ basic_machine=mmix-knuth ++ ;; ++ rs6000) ++ basic_machine=rs6000-ibm ++ ;; ++ vax) ++ basic_machine=vax-dec ++ ;; ++ pdp10) ++ # there are many clones, so DEC is not a safe bet ++ basic_machine=pdp10-unknown ++ ;; ++ pdp11) ++ basic_machine=pdp11-dec ++ ;; ++ we32k) ++ basic_machine=we32k-att ++ ;; ++ sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) ++ basic_machine=sh-unknown ++ ;; ++ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) ++ basic_machine=sparc-sun ++ ;; ++ cydra) ++ basic_machine=cydra-cydrome ++ ;; ++ orion) ++ basic_machine=orion-highlevel ++ ;; ++ orion105) ++ basic_machine=clipper-highlevel ++ ;; ++ mac | mpw | mac-mpw) ++ basic_machine=m68k-apple ++ ;; ++ pmac | pmac-mpw) ++ basic_machine=powerpc-apple ++ ;; ++ *-unknown) ++ # Make sure to match an already-canonicalized machine name. ++ ;; ++ *) ++ echo Invalid configuration `$1': machine `$basic_machine' not recognized 1>&2 ++ exit 1 ++ ;; ++esac ++ ++# Here we canonicalize certain aliases for manufacturers. ++case $basic_machine in ++ *-digital*) ++ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ++ ;; ++ *-commodore*) ++ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ++ ;; ++ *) ++ ;; ++esac ++ ++# Decode manufacturer-specific aliases for certain operating systems. ++ ++if [ x"$os" != x"" ] ++then ++case $os in ++ # First match some system type aliases ++ # that might get confused with valid system types. ++ # -solaris* is a basic system type, with this one exception. ++ -solaris1 | -solaris1.*) ++ os=`echo $os | sed -e 's|solaris1|sunos4|'` ++ ;; ++ -solaris) ++ os=-solaris2 ++ ;; ++ -svr4*) ++ os=-sysv4 ++ ;; ++ -unixware*) ++ os=-sysv4.2uw ++ ;; ++ -gnu/linux*) ++ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ++ ;; ++ # First accept the basic system types. ++ # The portable systems comes first. ++ # Each alternative MUST END IN A *, to match a version number. ++ # -sysv* is not here because it comes later, after sysvr4. ++ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ ++ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ ++ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ ++ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ ++ | -aos* \ ++ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ ++ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ ++ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ ++ | -openbsd* | -solidbsd* \ ++ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ ++ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ ++ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ ++ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ ++ | -chorusos* | -chorusrdb* \ ++ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ ++ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ ++ | -uxpv* | -beos* | -mpeix* | -udk* \ ++ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ ++ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ ++ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ ++ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ ++ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ ++ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ ++ | -skyos* | -haiku* | -rdos* | -irx*) ++ # Remember, each alternative MUST END IN *, to match a version number. ++ ;; ++ -qnx*) ++ case $basic_machine in ++ x86-* | i*86-*) ++ ;; ++ *) ++ os=-nto$os ++ ;; ++ esac ++ ;; ++ -nto-qnx*) ++ ;; ++ -nto*) ++ os=`echo $os | sed -e 's|nto|nto-qnx|'` ++ ;; ++ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ ++ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ ++ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ++ ;; ++ -mac*) ++ os=`echo $os | sed -e 's|mac|macos|'` ++ ;; ++ -linux-dietlibc) ++ os=-linux-dietlibc ++ ;; ++ -linux*) ++ os=`echo $os | sed -e 's|linux|linux-gnu|'` ++ ;; ++ -sunos5*) ++ os=`echo $os | sed -e 's|sunos5|solaris2|'` ++ ;; ++ -sunos6*) ++ os=`echo $os | sed -e 's|sunos6|solaris3|'` ++ ;; ++ -opened*) ++ os=-openedition ++ ;; ++ -os400*) ++ os=-os400 ++ ;; ++ -wince*) ++ os=-wince ++ ;; ++ -osfrose*) ++ os=-osfrose ++ ;; ++ -osf*) ++ os=-osf ++ ;; ++ -utek*) ++ os=-bsd ++ ;; ++ -dynix*) ++ os=-bsd ++ ;; ++ -acis*) ++ os=-aos ++ ;; ++ -atheos*) ++ os=-atheos ++ ;; ++ -syllable*) ++ os=-syllable ++ ;; ++ -386bsd) ++ os=-bsd ++ ;; ++ -ctix* | -uts*) ++ os=-sysv ++ ;; ++ -nova*) ++ os=-rtmk-nova ++ ;; ++ -ns2 ) ++ os=-nextstep2 ++ ;; ++ -nsk*) ++ os=-nsk ++ ;; ++ # Preserve the version number of sinix5. ++ -sinix5.*) ++ os=`echo $os | sed -e 's|sinix|sysv|'` ++ ;; ++ -sinix*) ++ os=-sysv4 ++ ;; ++ -tpf*) ++ os=-tpf ++ ;; ++ -triton*) ++ os=-sysv3 ++ ;; ++ -oss*) ++ os=-sysv3 ++ ;; ++ -svr4) ++ os=-sysv4 ++ ;; ++ -svr3) ++ os=-sysv3 ++ ;; ++ -sysvr4) ++ os=-sysv4 ++ ;; ++ # This must come after -sysvr4. ++ -sysv*) ++ ;; ++ -ose*) ++ os=-ose ++ ;; ++ -es1800*) ++ os=-ose ++ ;; ++ -xenix) ++ os=-xenix ++ ;; ++ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) ++ os=-mint ++ ;; ++ -aros*) ++ os=-aros ++ ;; ++ -kaos*) ++ os=-kaos ++ ;; ++ -zvmoe) ++ os=-zvmoe ++ ;; ++ -none) ++ ;; ++ *) ++ # Get rid of the `-' at the beginning of $os. ++ os=`echo $os | sed 's/[^-]*-//'` ++ echo Invalid configuration `$1': system `$os' not recognized 1>&2 ++ exit 1 ++ ;; ++esac ++else ++ ++# Here we handle the default operating systems that come with various machines. ++# The value should be what the vendor currently ships out the door with their ++# machine or put another way, the most popular os provided with the machine. ++ ++# Note that if you're going to try to match "-MANUFACTURER" here (say, ++# "-sun"), then you have to tell the case statement up towards the top ++# that MANUFACTURER isn't an operating system. Otherwise, code above ++# will signal an error saying that MANUFACTURER isn't an operating ++# system, and we'll never get to this point. ++ ++case $basic_machine in ++ *-acorn) ++ os=-riscix1.2 ++ ;; ++ arm*-rebel) ++ os=-linux ++ ;; ++ arm*-semi) ++ os=-aout ++ ;; ++ c4x-* | tic4x-*) ++ os=-coff ++ ;; ++ # This must come before the *-dec entry. ++ pdp10-*) ++ os=-tops20 ++ ;; ++ pdp11-*) ++ os=-none ++ ;; ++ *-dec | vax-*) ++ os=-ultrix4.2 ++ ;; ++ m68*-apollo) ++ os=-domain ++ ;; ++ i386-sun) ++ os=-sunos4.0.2 ++ ;; ++ m68000-sun) ++ os=-sunos3 ++ # This also exists in the configure program, but was not the ++ # default. ++ # os=-sunos4 ++ ;; ++ m68*-cisco) ++ os=-aout ++ ;; ++ mips*-cisco) ++ os=-elf ++ ;; ++ mips*-*) ++ os=-elf ++ ;; ++ or32-*) ++ os=-coff ++ ;; ++ *-tti) # must be before sparc entry or we get the wrong os. ++ os=-sysv3 ++ ;; ++ sparc-* | *-sun) ++ os=-sunos4.1.1 ++ ;; ++ *-be) ++ os=-beos ++ ;; ++ *-haiku) ++ os=-haiku ++ ;; ++ *-ibm) ++ os=-aix ++ ;; ++ *-knuth) ++ os=-mmixware ++ ;; ++ *-wec) ++ os=-proelf ++ ;; ++ *-winbond) ++ os=-proelf ++ ;; ++ *-oki) ++ os=-proelf ++ ;; ++ *-hp) ++ os=-hpux ++ ;; ++ *-hitachi) ++ os=-hiux ++ ;; ++ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) ++ os=-sysv ++ ;; ++ *-cbm) ++ os=-amigaos ++ ;; ++ *-dg) ++ os=-dgux ++ ;; ++ *-dolphin) ++ os=-sysv3 ++ ;; ++ m68k-ccur) ++ os=-rtu ++ ;; ++ m88k-omron*) ++ os=-luna ++ ;; ++ *-next ) ++ os=-nextstep ++ ;; ++ *-sequent) ++ os=-ptx ++ ;; ++ *-crds) ++ os=-unos ++ ;; ++ *-ns) ++ os=-genix ++ ;; ++ i370-*) ++ os=-mvs ++ ;; ++ *-next) ++ os=-nextstep3 ++ ;; ++ *-gould) ++ os=-sysv ++ ;; ++ *-highlevel) ++ os=-bsd ++ ;; ++ *-encore) ++ os=-bsd ++ ;; ++ *-sgi) ++ os=-irix ++ ;; ++ *-siemens) ++ os=-sysv4 ++ ;; ++ *-masscomp) ++ os=-rtu ++ ;; ++ f30[01]-fujitsu | f700-fujitsu) ++ os=-uxpv ++ ;; ++ *-rom68k) ++ os=-coff ++ ;; ++ *-*bug) ++ os=-coff ++ ;; ++ *-apple) ++ os=-macos ++ ;; ++ *-atari*) ++ os=-mint ++ ;; ++ *) ++ os=-none ++ ;; ++esac ++fi ++ ++# Here we handle the case where we know the os, and the CPU type, but not the ++# manufacturer. We pick the logical manufacturer. ++vendor=unknown ++case $basic_machine in ++ *-unknown) ++ case $os in ++ -riscix*) ++ vendor=acorn ++ ;; ++ -sunos*) ++ vendor=sun ++ ;; ++ -aix*) ++ vendor=ibm ++ ;; ++ -beos*) ++ vendor=be ++ ;; ++ -hpux*) ++ vendor=hp ++ ;; ++ -mpeix*) ++ vendor=hp ++ ;; ++ -hiux*) ++ vendor=hitachi ++ ;; ++ -unos*) ++ vendor=crds ++ ;; ++ -dgux*) ++ vendor=dg ++ ;; ++ -luna*) ++ vendor=omron ++ ;; ++ -genix*) ++ vendor=ns ++ ;; ++ -mvs* | -opened*) ++ vendor=ibm ++ ;; ++ -os400*) ++ vendor=ibm ++ ;; ++ -ptx*) ++ vendor=sequent ++ ;; ++ -tpf*) ++ vendor=ibm ++ ;; ++ -vxsim* | -vxworks* | -windiss*) ++ vendor=wrs ++ ;; ++ -aux*) ++ vendor=apple ++ ;; ++ -hms*) ++ vendor=hitachi ++ ;; ++ -mpw* | -macos*) ++ vendor=apple ++ ;; ++ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) ++ vendor=atari ++ ;; ++ -vos*) ++ vendor=stratus ++ ;; ++ esac ++ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ++ ;; ++esac ++ ++echo $basic_machine$os ++exit ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "timestamp='" ++# time-stamp-format: "%:y-%02m-%02d" ++# time-stamp-end: "'" ++# End: +diff -urN lua-5.1.4/configure lua-5.1.4-autotoolize/configure +--- lua-5.1.4/configure 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/configure 2008-09-03 13:18:28.000000000 +0200 +@@ -0,0 +1,20444 @@ ++#! /bin/sh ++# Guess values for system-dependent variables and create Makefiles. ++# Generated by GNU Autoconf 2.59 for Autotoolized Lua 5.1.3. ++# ++# Copyright (C) 2003 Free Software Foundation, Inc. ++# This configure script is free software; the Free Software Foundation ++# gives unlimited permission to copy, distribute and modify it. ++## --------------------- ## ++## M4sh Initialization. ## ++## --------------------- ## ++ ++# Be Bourne compatible ++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then ++ emulate sh ++ NULLCMD=: ++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '${1+"$@"}'='"$@"' ++elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then ++ set -o posix ++fi ++DUALCASE=1; export DUALCASE # for MKS sh ++ ++# Support unset when possible. ++if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then ++ as_unset=unset ++else ++ as_unset=false ++fi ++ ++ ++# Work around bugs in pre-3.0 UWIN ksh. ++$as_unset ENV MAIL MAILPATH ++PS1='$ ' ++PS2='> ' ++PS4='+ ' ++ ++# NLS nuisances. ++for as_var in \ ++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ ++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ ++ LC_TELEPHONE LC_TIME ++do ++ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then ++ eval $as_var=C; export $as_var ++ else ++ $as_unset $as_var ++ fi ++done ++ ++# Required to use basename. ++if expr a : '(a)' >/dev/null 2>&1; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then ++ as_basename=basename ++else ++ as_basename=false ++fi ++ ++ ++# Name of the executable. ++as_me=`$as_basename "$0" || ++$as_expr X/"$0" : '.*/([^/][^/]*)/*$' | \ ++ X"$0" : 'X(//)$' | \ ++ X"$0" : 'X(/)$' | \ ++ . : '(.)' 2>/dev/null || ++echo X/"$0" | ++ sed '/^.*/([^/][^/]*)/*$/{ s//\1/; q; } ++ /^X/(//)$/{ s//\1/; q; } ++ /^X/(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ ++ ++# PATH needs CR, and LINENO needs CR and PATH. ++# Avoid depending upon Character Ranges. ++as_cr_letters='abcdefghijklmnopqrstuvwxyz' ++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ++as_cr_Letters=$as_cr_letters$as_cr_LETTERS ++as_cr_digits='0123456789' ++as_cr_alnum=$as_cr_Letters$as_cr_digits ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ echo "#! /bin/sh" >conf$$.sh ++ echo "exit 0" >>conf$$.sh ++ chmod +x conf$$.sh ++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then ++ PATH_SEPARATOR=';' ++ else ++ PATH_SEPARATOR=: ++ fi ++ rm -f conf$$.sh ++fi ++ ++ ++ as_lineno_1=$LINENO ++ as_lineno_2=$LINENO ++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` ++ test "x$as_lineno_1" != "x$as_lineno_2" && ++ test "x$as_lineno_3" = "x$as_lineno_2" || { ++ # Find who we are. Look in the path if we contain no path at all ++ # relative or not. ++ case $0 in ++ *[\/]* ) as_myself=$0 ;; ++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break ++done ++ ++ ;; ++ esac ++ # We did not find ourselves, most probably we were run as `sh COMMAND' ++ # in which case we are not to be found in the path. ++ if test "x$as_myself" = x; then ++ as_myself=$0 ++ fi ++ if test ! -f "$as_myself"; then ++ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 ++ { (exit 1); exit 1; }; } ++ fi ++ case $CONFIG_SHELL in ++ '') ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for as_base in sh bash ksh sh5; do ++ case $as_dir in ++ /*) ++ if ("$as_dir/$as_base" -c ' ++ as_lineno_1=$LINENO ++ as_lineno_2=$LINENO ++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` ++ test "x$as_lineno_1" != "x$as_lineno_2" && ++ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then ++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } ++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } ++ CONFIG_SHELL=$as_dir/$as_base ++ export CONFIG_SHELL ++ exec "$CONFIG_SHELL" "$0" ${1+"$@"} ++ fi;; ++ esac ++ done ++done ++;; ++ esac ++ ++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO ++ # uniformly replaced by the line number. The first 'sed' inserts a ++ # line-number line before each line; the second 'sed' does the real ++ # work. The second script uses 'N' to pair each line-number line ++ # with the numbered line, and appends trailing '-' during ++ # substitution so that $LINENO is not a special case at line end. ++ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the ++ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) ++ sed '=' <$as_myself | ++ sed ' ++ N ++ s,$,-, ++ : loop ++ s,^(['$as_cr_digits']*)(.*)[$]LINENO([^'$as_cr_alnum'_]),\1\2\1\3, ++ t loop ++ s,-$,, ++ s,^['$as_cr_digits']*\n,, ++ ' >$as_me.lineno && ++ chmod +x $as_me.lineno || ++ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 ++ { (exit 1); exit 1; }; } ++ ++ # Don't try to exec as it changes $[0], causing all sort of problems ++ # (the dirname of $[0] is not the place where we might find the ++ # original and so on. Autoconf is especially sensible to this). ++ . ./$as_me.lineno ++ # Exit status is that of the last command. ++ exit ++} ++ ++ ++case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in ++ *c*,-n*) ECHO_N= ECHO_C=' ++' ECHO_T=' ' ;; ++ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; ++ *) ECHO_N= ECHO_C='\c' ECHO_T= ;; ++esac ++ ++if expr a : '(a)' >/dev/null 2>&1; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++rm -f conf$$ conf$$.exe conf$$.file ++echo >conf$$.file ++if ln -s conf$$.file conf$$ 2>/dev/null; then ++ # We could just check for DJGPP; but this test a) works b) is more generic ++ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). ++ if test -f conf$$.exe; then ++ # Don't use ln at all; we don't have any links ++ as_ln_s='cp -p' ++ else ++ as_ln_s='ln -s' ++ fi ++elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++else ++ as_ln_s='cp -p' ++fi ++rm -f conf$$ conf$$.exe conf$$.file ++ ++if mkdir -p . 2>/dev/null; then ++ as_mkdir_p=: ++else ++ test -d ./-p && rmdir ./-p ++ as_mkdir_p=false ++fi ++ ++as_executable_p="test -f" ++ ++# Sed expression to map a string onto a valid CPP name. ++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" ++ ++# Sed expression to map a string onto a valid variable name. ++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" ++ ++ ++# IFS ++# We need space, tab and new line, in precisely that order. ++as_nl=' ++' ++IFS=" $as_nl" ++ ++# CDPATH. ++$as_unset CDPATH ++ ++ ++ ++# Check that we are running under the correct shell. ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++case X$ECHO in ++X*--fallback-echo) ++ # Remove one level of quotation (which was required for Make). ++ ECHO=`echo "$ECHO" | sed 's,\\$\$0,'$0','` ++ ;; ++esac ++ ++echo=${ECHO-echo} ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then ++ # Yippee, $echo works! ++ : ++else ++ # Restart under the correct shell. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<EOF ++$* ++EOF ++ exit 0 ++fi ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++if test -z "$ECHO"; then ++if test "X${echo_test_string+set}" != Xset; then ++# find a string as large as possible, as long as the shell can cope with it ++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do ++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... ++ if (echo_test_string=`eval $cmd`) 2>/dev/null && ++ echo_test_string=`eval $cmd` && ++ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null ++ then ++ break ++ fi ++ done ++fi ++ ++if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ : ++else ++ # The Solaris, AIX, and Digital Unix default echo programs unquote ++ # backslashes. This makes it impossible to quote backslashes using ++ # echo "$something" | sed 's/\/\\/g' ++ # ++ # So, first we look for a working echo in the user's PATH. ++ ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for dir in $PATH /usr/ucb; do ++ IFS="$lt_save_ifs" ++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && ++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ echo="$dir/echo" ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ if test "X$echo" = Xecho; then ++ # We didn't find a better echo, so look for alternatives. ++ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # This shell has a builtin print -r that does the trick. ++ echo='print -r' ++ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && ++ test "X$CONFIG_SHELL" != X/bin/ksh; then ++ # If we have ksh, try running configure again with it. ++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} ++ export ORIGINAL_CONFIG_SHELL ++ CONFIG_SHELL=/bin/ksh ++ export CONFIG_SHELL ++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} ++ else ++ # Try using printf. ++ echo='printf %s\n' ++ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && ++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ # Cool, printf works ++ : ++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL ++ export CONFIG_SHELL ++ SHELL="$CONFIG_SHELL" ++ export SHELL ++ echo="$CONFIG_SHELL $0 --fallback-echo" ++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && ++ test "X$echo_testing_string" = 'X\t' && ++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && ++ test "X$echo_testing_string" = "X$echo_test_string"; then ++ echo="$CONFIG_SHELL $0 --fallback-echo" ++ else ++ # maybe with a smaller string... ++ prev=: ++ ++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do ++ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null ++ then ++ break ++ fi ++ prev="$cmd" ++ done ++ ++ if test "$prev" != 'sed 50q "$0"'; then ++ echo_test_string=`eval $prev` ++ export echo_test_string ++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} ++ else ++ # Oops. We lost completely, so just stick with echo. ++ echo=echo ++ fi ++ fi ++ fi ++ fi ++fi ++fi ++ ++# Copy echo and quote the copy suitably for passing to libtool from ++# the Makefile, instead of quoting the original, which is used later. ++ECHO=$echo ++if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then ++ ECHO="$CONFIG_SHELL \$$0 --fallback-echo" ++fi ++ ++ ++ ++ ++tagnames=${tagnames+${tagnames},}CXX ++ ++tagnames=${tagnames+${tagnames},}F77 ++ ++# Name of the host. ++# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, ++# so uname gets run too. ++ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` ++ ++exec 6>&1 ++ ++# ++# Initializations. ++# ++ac_default_prefix=/usr/local ++ac_config_libobj_dir=. ++cross_compiling=no ++subdirs= ++MFLAGS= ++MAKEFLAGS= ++SHELL=${CONFIG_SHELL-/bin/sh} ++ ++# Maximum number of lines to put in a shell here document. ++# This variable seems obsolete. It should probably be removed, and ++# only ac_max_sed_lines should be used. ++: ${ac_max_here_lines=38} ++ ++# Identity of this package. ++PACKAGE_NAME='Autotoolized Lua' ++PACKAGE_TARNAME='lua-at' ++PACKAGE_VERSION='5.1.3' ++PACKAGE_STRING='Autotoolized Lua 5.1.3' ++PACKAGE_BUGREPORT='' ++ ++ac_unique_file="src/lapi.c" ++# Factoring default headers for most tests. ++ac_includes_default="\ ++#include <stdio.h> ++#if HAVE_SYS_TYPES_H ++# include <sys/types.h> ++#endif ++#if HAVE_SYS_STAT_H ++# include <sys/stat.h> ++#endif ++#if STDC_HEADERS ++# include <stdlib.h> ++# include <stddef.h> ++#else ++# if HAVE_STDLIB_H ++# include <stdlib.h> ++# endif ++#endif ++#if HAVE_STRING_H ++# if !STDC_HEADERS && HAVE_MEMORY_H ++# include <memory.h> ++# endif ++# include <string.h> ++#endif ++#if HAVE_STRINGS_H ++# include <strings.h> ++#endif ++#if HAVE_INTTYPES_H ++# include <inttypes.h> ++#else ++# if HAVE_STDINT_H ++# include <stdint.h> ++# endif ++#endif ++#if HAVE_UNISTD_H ++# include <unistd.h> ++#endif" ++ ++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL READLINE_DEFS POSIX_DEFS LUA_DL_DEFS LUA_BUILD_AS_DLL_DEFS LUA_LIBS LIBOBJS LTLIBOBJS' ++ac_subst_files='' ++ ++# Initialize some variables set by options. ++ac_init_help= ++ac_init_version=false ++# The variables have the same names as the options, with ++# dashes changed to underlines. ++cache_file=/dev/null ++exec_prefix=NONE ++no_create= ++no_recursion= ++prefix=NONE ++program_prefix=NONE ++program_suffix=NONE ++program_transform_name=s,x,x, ++silent= ++site= ++srcdir= ++verbose= ++x_includes=NONE ++x_libraries=NONE ++ ++# Installation directory options. ++# These are left unexpanded so users can "make install exec_prefix=/foo" ++# and all the variables that are supposed to be based on exec_prefix ++# by default will actually change. ++# Use braces instead of parens because sh, perl, etc. also accept them. ++bindir='${exec_prefix}/bin' ++sbindir='${exec_prefix}/sbin' ++libexecdir='${exec_prefix}/libexec' ++datadir='${prefix}/share' ++sysconfdir='${prefix}/etc' ++sharedstatedir='${prefix}/com' ++localstatedir='${prefix}/var' ++libdir='${exec_prefix}/lib' ++includedir='${prefix}/include' ++oldincludedir='/usr/include' ++infodir='${prefix}/info' ++mandir='${prefix}/man' ++ ++ac_prev= ++for ac_option ++do ++ # If the previous option needs an argument, assign it. ++ if test -n "$ac_prev"; then ++ eval "$ac_prev=$ac_option" ++ ac_prev= ++ continue ++ fi ++ ++ ac_optarg=`expr "x$ac_option" : 'x[^=]*=(.*)'` ++ ++ # Accept the important Cygnus configure options, so we can diagnose typos. ++ ++ case $ac_option in ++ ++ -bindir | --bindir | --bindi | --bind | --bin | --bi) ++ ac_prev=bindir ;; ++ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) ++ bindir=$ac_optarg ;; ++ ++ -build | --build | --buil | --bui | --bu) ++ ac_prev=build_alias ;; ++ -build=* | --build=* | --buil=* | --bui=* | --bu=*) ++ build_alias=$ac_optarg ;; ++ ++ -cache-file | --cache-file | --cache-fil | --cache-fi \ ++ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ++ ac_prev=cache_file ;; ++ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ ++ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) ++ cache_file=$ac_optarg ;; ++ ++ --config-cache | -C) ++ cache_file=config.cache ;; ++ ++ -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ++ ac_prev=datadir ;; ++ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ ++ | --da=*) ++ datadir=$ac_optarg ;; ++ ++ -disable-* | --disable-*) ++ ac_feature=`expr "x$ac_option" : 'x-*disable-(.*)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid feature name: $ac_feature" >&2 ++ { (exit 1); exit 1; }; } ++ ac_feature=`echo $ac_feature | sed 's/-/_/g'` ++ eval "enable_$ac_feature=no" ;; ++ ++ -enable-* | --enable-*) ++ ac_feature=`expr "x$ac_option" : 'x-*enable-([^=]*)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid feature name: $ac_feature" >&2 ++ { (exit 1); exit 1; }; } ++ ac_feature=`echo $ac_feature | sed 's/-/_/g'` ++ case $ac_option in ++ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\''/g"`;; ++ *) ac_optarg=yes ;; ++ esac ++ eval "enable_$ac_feature='$ac_optarg'" ;; ++ ++ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ ++ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ ++ | --exec | --exe | --ex) ++ ac_prev=exec_prefix ;; ++ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ ++ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ ++ | --exec=* | --exe=* | --ex=*) ++ exec_prefix=$ac_optarg ;; ++ ++ -gas | --gas | --ga | --g) ++ # Obsolete; use --with-gas. ++ with_gas=yes ;; ++ ++ -help | --help | --hel | --he | -h) ++ ac_init_help=long ;; ++ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ++ ac_init_help=recursive ;; ++ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ++ ac_init_help=short ;; ++ ++ -host | --host | --hos | --ho) ++ ac_prev=host_alias ;; ++ -host=* | --host=* | --hos=* | --ho=*) ++ host_alias=$ac_optarg ;; ++ ++ -includedir | --includedir | --includedi | --included | --include \ ++ | --includ | --inclu | --incl | --inc) ++ ac_prev=includedir ;; ++ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ ++ | --includ=* | --inclu=* | --incl=* | --inc=*) ++ includedir=$ac_optarg ;; ++ ++ -infodir | --infodir | --infodi | --infod | --info | --inf) ++ ac_prev=infodir ;; ++ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) ++ infodir=$ac_optarg ;; ++ ++ -libdir | --libdir | --libdi | --libd) ++ ac_prev=libdir ;; ++ -libdir=* | --libdir=* | --libdi=* | --libd=*) ++ libdir=$ac_optarg ;; ++ ++ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ ++ | --libexe | --libex | --libe) ++ ac_prev=libexecdir ;; ++ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ ++ | --libexe=* | --libex=* | --libe=*) ++ libexecdir=$ac_optarg ;; ++ ++ -localstatedir | --localstatedir | --localstatedi | --localstated \ ++ | --localstate | --localstat | --localsta | --localst \ ++ | --locals | --local | --loca | --loc | --lo) ++ ac_prev=localstatedir ;; ++ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ ++ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ ++ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) ++ localstatedir=$ac_optarg ;; ++ ++ -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ++ ac_prev=mandir ;; ++ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) ++ mandir=$ac_optarg ;; ++ ++ -nfp | --nfp | --nf) ++ # Obsolete; use --without-fp. ++ with_fp=no ;; ++ ++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \ ++ | --no-cr | --no-c | -n) ++ no_create=yes ;; ++ ++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \ ++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ++ no_recursion=yes ;; ++ ++ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ ++ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ ++ | --oldin | --oldi | --old | --ol | --o) ++ ac_prev=oldincludedir ;; ++ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ ++ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ ++ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) ++ oldincludedir=$ac_optarg ;; ++ ++ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ++ ac_prev=prefix ;; ++ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) ++ prefix=$ac_optarg ;; ++ ++ -program-prefix | --program-prefix | --program-prefi | --program-pref \ ++ | --program-pre | --program-pr | --program-p) ++ ac_prev=program_prefix ;; ++ -program-prefix=* | --program-prefix=* | --program-prefi=* \ ++ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) ++ program_prefix=$ac_optarg ;; ++ ++ -program-suffix | --program-suffix | --program-suffi | --program-suff \ ++ | --program-suf | --program-su | --program-s) ++ ac_prev=program_suffix ;; ++ -program-suffix=* | --program-suffix=* | --program-suffi=* \ ++ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) ++ program_suffix=$ac_optarg ;; ++ ++ -program-transform-name | --program-transform-name \ ++ | --program-transform-nam | --program-transform-na \ ++ | --program-transform-n | --program-transform- \ ++ | --program-transform | --program-transfor \ ++ | --program-transfo | --program-transf \ ++ | --program-trans | --program-tran \ ++ | --progr-tra | --program-tr | --program-t) ++ ac_prev=program_transform_name ;; ++ -program-transform-name=* | --program-transform-name=* \ ++ | --program-transform-nam=* | --program-transform-na=* \ ++ | --program-transform-n=* | --program-transform-=* \ ++ | --program-transform=* | --program-transfor=* \ ++ | --program-transfo=* | --program-transf=* \ ++ | --program-trans=* | --program-tran=* \ ++ | --progr-tra=* | --program-tr=* | --program-t=*) ++ program_transform_name=$ac_optarg ;; ++ ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil) ++ silent=yes ;; ++ ++ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ++ ac_prev=sbindir ;; ++ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ ++ | --sbi=* | --sb=*) ++ sbindir=$ac_optarg ;; ++ ++ -sharedstatedir | --sharedstatedir | --sharedstatedi \ ++ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ ++ | --sharedst | --shareds | --shared | --share | --shar \ ++ | --sha | --sh) ++ ac_prev=sharedstatedir ;; ++ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ ++ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ ++ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ ++ | --sha=* | --sh=*) ++ sharedstatedir=$ac_optarg ;; ++ ++ -site | --site | --sit) ++ ac_prev=site ;; ++ -site=* | --site=* | --sit=*) ++ site=$ac_optarg ;; ++ ++ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ++ ac_prev=srcdir ;; ++ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ++ srcdir=$ac_optarg ;; ++ ++ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ ++ | --syscon | --sysco | --sysc | --sys | --sy) ++ ac_prev=sysconfdir ;; ++ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ ++ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) ++ sysconfdir=$ac_optarg ;; ++ ++ -target | --target | --targe | --targ | --tar | --ta | --t) ++ ac_prev=target_alias ;; ++ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) ++ target_alias=$ac_optarg ;; ++ ++ -v | -verbose | --verbose | --verbos | --verbo | --verb) ++ verbose=yes ;; ++ ++ -version | --version | --versio | --versi | --vers | -V) ++ ac_init_version=: ;; ++ ++ -with-* | --with-*) ++ ac_package=`expr "x$ac_option" : 'x-*with-([^=]*)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid package name: $ac_package" >&2 ++ { (exit 1); exit 1; }; } ++ ac_package=`echo $ac_package| sed 's/-/_/g'` ++ case $ac_option in ++ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\''/g"`;; ++ *) ac_optarg=yes ;; ++ esac ++ eval "with_$ac_package='$ac_optarg'" ;; ++ ++ -without-* | --without-*) ++ ac_package=`expr "x$ac_option" : 'x-*without-(.*)'` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid package name: $ac_package" >&2 ++ { (exit 1); exit 1; }; } ++ ac_package=`echo $ac_package | sed 's/-/_/g'` ++ eval "with_$ac_package=no" ;; ++ ++ --x) ++ # Obsolete; use --with-x. ++ with_x=yes ;; ++ ++ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ ++ | --x-incl | --x-inc | --x-in | --x-i) ++ ac_prev=x_includes ;; ++ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ ++ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) ++ x_includes=$ac_optarg ;; ++ ++ -x-libraries | --x-libraries | --x-librarie | --x-librari \ ++ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ++ ac_prev=x_libraries ;; ++ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ ++ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) ++ x_libraries=$ac_optarg ;; ++ ++ -*) { echo "$as_me: error: unrecognized option: $ac_option ++Try `$0 --help' for more information." >&2 ++ { (exit 1); exit 1; }; } ++ ;; ++ ++ *=*) ++ ac_envvar=`expr "x$ac_option" : 'x([^=]*)='` ++ # Reject names that are not valid shell variable names. ++ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && ++ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 ++ { (exit 1); exit 1; }; } ++ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\''/g"` ++ eval "$ac_envvar='$ac_optarg'" ++ export $ac_envvar ;; ++ ++ *) ++ # FIXME: should be removed in autoconf 3.0. ++ echo "$as_me: WARNING: you should use --build, --host, --target" >&2 ++ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && ++ echo "$as_me: WARNING: invalid host type: $ac_option" >&2 ++ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ++ ;; ++ ++ esac ++done ++ ++if test -n "$ac_prev"; then ++ ac_option=--`echo $ac_prev | sed 's/_/-/g'` ++ { echo "$as_me: error: missing argument to $ac_option" >&2 ++ { (exit 1); exit 1; }; } ++fi ++ ++# Be sure to have absolute paths. ++for ac_var in exec_prefix prefix ++do ++ eval ac_val=$`echo $ac_var` ++ case $ac_val in ++ [\/$]* | ?:[\/]* | NONE | '' ) ;; ++ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 ++ { (exit 1); exit 1; }; };; ++ esac ++done ++ ++# Be sure to have absolute paths. ++for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ ++ localstatedir libdir includedir oldincludedir infodir mandir ++do ++ eval ac_val=$`echo $ac_var` ++ case $ac_val in ++ [\/$]* | ?:[\/]* ) ;; ++ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 ++ { (exit 1); exit 1; }; };; ++ esac ++done ++ ++# There might be people who depend on the old broken behavior: `$host' ++# used to hold the argument of --host etc. ++# FIXME: To remove some day. ++build=$build_alias ++host=$host_alias ++target=$target_alias ++ ++# FIXME: To remove some day. ++if test "x$host_alias" != x; then ++ if test "x$build_alias" = x; then ++ cross_compiling=maybe ++ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. ++ If a cross compiler is detected then cross compile mode will be used." >&2 ++ elif test "x$build_alias" != "x$host_alias"; then ++ cross_compiling=yes ++ fi ++fi ++ ++ac_tool_prefix= ++test -n "$host_alias" && ac_tool_prefix=$host_alias- ++ ++test "$silent" = yes && exec 6>/dev/null ++ ++ ++# Find the source files, if location was not specified. ++if test -z "$srcdir"; then ++ ac_srcdir_defaulted=yes ++ # Try the directory containing this script, then its parent. ++ ac_confdir=`(dirname "$0") 2>/dev/null || ++$as_expr X"$0" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$0" : 'X(//)[^/]' | \ ++ X"$0" : 'X(//)$' | \ ++ X"$0" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$0" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ srcdir=$ac_confdir ++ if test ! -r "$srcdir/$ac_unique_file"; then ++ srcdir=.. ++ fi ++else ++ ac_srcdir_defaulted=no ++fi ++if test ! -r "$srcdir/$ac_unique_file"; then ++ if test "$ac_srcdir_defaulted" = yes; then ++ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 ++ { (exit 1); exit 1; }; } ++ else ++ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 ++ { (exit 1); exit 1; }; } ++ fi ++fi ++(cd $srcdir && test -r "./$ac_unique_file") 2>/dev/null || ++ { echo "$as_me: error: sources are in $srcdir, but `cd $srcdir' does not work" >&2 ++ { (exit 1); exit 1; }; } ++srcdir=`echo "$srcdir" | sed 's%([^\/])[\/]*$%\1%'` ++ac_env_build_alias_set=${build_alias+set} ++ac_env_build_alias_value=$build_alias ++ac_cv_env_build_alias_set=${build_alias+set} ++ac_cv_env_build_alias_value=$build_alias ++ac_env_host_alias_set=${host_alias+set} ++ac_env_host_alias_value=$host_alias ++ac_cv_env_host_alias_set=${host_alias+set} ++ac_cv_env_host_alias_value=$host_alias ++ac_env_target_alias_set=${target_alias+set} ++ac_env_target_alias_value=$target_alias ++ac_cv_env_target_alias_set=${target_alias+set} ++ac_cv_env_target_alias_value=$target_alias ++ac_env_CC_set=${CC+set} ++ac_env_CC_value=$CC ++ac_cv_env_CC_set=${CC+set} ++ac_cv_env_CC_value=$CC ++ac_env_CFLAGS_set=${CFLAGS+set} ++ac_env_CFLAGS_value=$CFLAGS ++ac_cv_env_CFLAGS_set=${CFLAGS+set} ++ac_cv_env_CFLAGS_value=$CFLAGS ++ac_env_LDFLAGS_set=${LDFLAGS+set} ++ac_env_LDFLAGS_value=$LDFLAGS ++ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ++ac_cv_env_LDFLAGS_value=$LDFLAGS ++ac_env_CPPFLAGS_set=${CPPFLAGS+set} ++ac_env_CPPFLAGS_value=$CPPFLAGS ++ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ++ac_cv_env_CPPFLAGS_value=$CPPFLAGS ++ac_env_CPP_set=${CPP+set} ++ac_env_CPP_value=$CPP ++ac_cv_env_CPP_set=${CPP+set} ++ac_cv_env_CPP_value=$CPP ++ac_env_CXX_set=${CXX+set} ++ac_env_CXX_value=$CXX ++ac_cv_env_CXX_set=${CXX+set} ++ac_cv_env_CXX_value=$CXX ++ac_env_CXXFLAGS_set=${CXXFLAGS+set} ++ac_env_CXXFLAGS_value=$CXXFLAGS ++ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} ++ac_cv_env_CXXFLAGS_value=$CXXFLAGS ++ac_env_CXXCPP_set=${CXXCPP+set} ++ac_env_CXXCPP_value=$CXXCPP ++ac_cv_env_CXXCPP_set=${CXXCPP+set} ++ac_cv_env_CXXCPP_value=$CXXCPP ++ac_env_F77_set=${F77+set} ++ac_env_F77_value=$F77 ++ac_cv_env_F77_set=${F77+set} ++ac_cv_env_F77_value=$F77 ++ac_env_FFLAGS_set=${FFLAGS+set} ++ac_env_FFLAGS_value=$FFLAGS ++ac_cv_env_FFLAGS_set=${FFLAGS+set} ++ac_cv_env_FFLAGS_value=$FFLAGS ++ ++# ++# Report the --help message. ++# ++if test "$ac_init_help" = "long"; then ++ # Omit some internal or obsolete options to make the list less imposing. ++ # This message is too long to be a string in the A/UX 3.1 sh. ++ cat <<_ACEOF ++`configure' configures Autotoolized Lua 5.1.3 to adapt to many kinds of systems. ++ ++Usage: $0 [OPTION]... [VAR=VALUE]... ++ ++To assign environment variables (e.g., CC, CFLAGS...), specify them as ++VAR=VALUE. See below for descriptions of some of the useful variables. ++ ++Defaults for the options are specified in brackets. ++ ++Configuration: ++ -h, --help display this help and exit ++ --help=short display options specific to this package ++ --help=recursive display the short help of all the included packages ++ -V, --version display version information and exit ++ -q, --quiet, --silent do not print `checking...' messages ++ --cache-file=FILE cache test results in FILE [disabled] ++ -C, --config-cache alias for `--cache-file=config.cache' ++ -n, --no-create do not create output files ++ --srcdir=DIR find the sources in DIR [configure dir or `..'] ++ ++_ACEOF ++ ++ cat <<_ACEOF ++Installation directories: ++ --prefix=PREFIX install architecture-independent files in PREFIX ++ [$ac_default_prefix] ++ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX ++ [PREFIX] ++ ++By default, `make install' will install all the files in ++`$ac_default_prefix/bin', `$ac_default_prefix/lib' etc. You can specify ++an installation prefix other than `$ac_default_prefix' using `--prefix', ++for instance `--prefix=$HOME'. ++ ++For better control, use the options below. ++ ++Fine tuning of the installation directories: ++ --bindir=DIR user executables [EPREFIX/bin] ++ --sbindir=DIR system admin executables [EPREFIX/sbin] ++ --libexecdir=DIR program executables [EPREFIX/libexec] ++ --datadir=DIR read-only architecture-independent data [PREFIX/share] ++ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] ++ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] ++ --localstatedir=DIR modifiable single-machine data [PREFIX/var] ++ --libdir=DIR object code libraries [EPREFIX/lib] ++ --includedir=DIR C header files [PREFIX/include] ++ --oldincludedir=DIR C header files for non-gcc [/usr/include] ++ --infodir=DIR info documentation [PREFIX/info] ++ --mandir=DIR man documentation [PREFIX/man] ++_ACEOF ++ ++ cat <<_ACEOF ++ ++Program names: ++ --program-prefix=PREFIX prepend PREFIX to installed program names ++ --program-suffix=SUFFIX append SUFFIX to installed program names ++ --program-transform-name=PROGRAM run sed PROGRAM on installed program names ++ ++System types: ++ --build=BUILD configure for building on BUILD [guessed] ++ --host=HOST cross-compile to build programs to run on HOST [BUILD] ++_ACEOF ++fi ++ ++if test -n "$ac_init_help"; then ++ case $ac_init_help in ++ short | recursive ) echo "Configuration of Autotoolized Lua 5.1.3:";; ++ esac ++ cat <<_ACEOF ++ ++Optional Features: ++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) ++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes] ++ --disable-dependency-tracking speeds up one-time build ++ --enable-dependency-tracking do not reject slow dependency extractors ++ --enable-shared[=PKGS] ++ build shared libraries [default=yes] ++ --enable-static[=PKGS] ++ build static libraries [default=yes] ++ --enable-fast-install[=PKGS] ++ optimize for fast installation [default=yes] ++ --disable-libtool-lock avoid locking (might break parallel builds) ++ ++Optional Packages: ++ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] ++ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) ++ --with-gnu-ld assume the C compiler uses GNU ld [default=no] ++ --with-pic try to use only PIC/non-PIC objects [default=use ++ both] ++ --with-tags[=TAGS] ++ include additional configurations [automatic] ++ --with-readline Use readline for interpreter input [default=yes] ++ ++Some influential environment variables: ++ CC C compiler command ++ CFLAGS C compiler flags ++ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a ++ nonstandard directory <lib dir> ++ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have ++ headers in a nonstandard directory <include dir> ++ CPP C preprocessor ++ CXX C++ compiler command ++ CXXFLAGS C++ compiler flags ++ CXXCPP C++ preprocessor ++ F77 Fortran 77 compiler command ++ FFLAGS Fortran 77 compiler flags ++ ++Use these variables to override the choices made by `configure' or to help ++it to find libraries and programs with nonstandard names/locations. ++ ++_ACEOF ++fi ++ ++if test "$ac_init_help" = "recursive"; then ++ # If there are subdirs, report their specific --help. ++ ac_popdir=`pwd` ++ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue ++ test -d $ac_dir || continue ++ ac_builddir=. ++ ++if test "$ac_dir" != .; then ++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^.[\/],,'` ++ # A "../" for each directory in $ac_dir_suffix. ++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\/]*,../,g'` ++else ++ ac_dir_suffix= ac_top_builddir= ++fi ++ ++case $srcdir in ++ .) # No --srcdir option. We are building in place. ++ ac_srcdir=. ++ if test -z "$ac_top_builddir"; then ++ ac_top_srcdir=. ++ else ++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` ++ fi ;; ++ [\/]* | ?:[\/]* ) # Absolute path. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ;; ++ *) # Relative path. ++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_builddir$srcdir ;; ++esac ++ ++# Do not use `cd foo && pwd` to compute absolute paths, because ++# the directories may not exist. ++case `pwd` in ++.) ac_abs_builddir="$ac_dir";; ++*) ++ case "$ac_dir" in ++ .) ac_abs_builddir=`pwd`;; ++ [\/]* | ?:[\/]* ) ac_abs_builddir="$ac_dir";; ++ *) ac_abs_builddir=`pwd`/"$ac_dir";; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_builddir=${ac_top_builddir}.;; ++*) ++ case ${ac_top_builddir}. in ++ .) ac_abs_top_builddir=$ac_abs_builddir;; ++ [\/]* | ?:[\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; ++ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_srcdir=$ac_srcdir;; ++*) ++ case $ac_srcdir in ++ .) ac_abs_srcdir=$ac_abs_builddir;; ++ [\/]* | ?:[\/]* ) ac_abs_srcdir=$ac_srcdir;; ++ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_srcdir=$ac_top_srcdir;; ++*) ++ case $ac_top_srcdir in ++ .) ac_abs_top_srcdir=$ac_abs_builddir;; ++ [\/]* | ?:[\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; ++ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; ++ esac;; ++esac ++ ++ cd $ac_dir ++ # Check for guested configure; otherwise get Cygnus style configure. ++ if test -f $ac_srcdir/configure.gnu; then ++ echo ++ $SHELL $ac_srcdir/configure.gnu --help=recursive ++ elif test -f $ac_srcdir/configure; then ++ echo ++ $SHELL $ac_srcdir/configure --help=recursive ++ elif test -f $ac_srcdir/configure.ac || ++ test -f $ac_srcdir/configure.in; then ++ echo ++ $ac_configure --help ++ else ++ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 ++ fi ++ cd $ac_popdir ++ done ++fi ++ ++test -n "$ac_init_help" && exit 0 ++if $ac_init_version; then ++ cat <<_ACEOF ++Autotoolized Lua configure 5.1.3 ++generated by GNU Autoconf 2.59 ++ ++Copyright (C) 2003 Free Software Foundation, Inc. ++This configure script is free software; the Free Software Foundation ++gives unlimited permission to copy, distribute and modify it. ++_ACEOF ++ exit 0 ++fi ++exec 5>config.log ++cat >&5 <<_ACEOF ++This file contains any messages produced by compilers while ++running configure, to aid debugging if configure makes a mistake. ++ ++It was created by Autotoolized Lua $as_me 5.1.3, which was ++generated by GNU Autoconf 2.59. Invocation command line was ++ ++ $ $0 $@ ++ ++_ACEOF ++{ ++cat <<_ASUNAME ++## --------- ## ++## Platform. ## ++## --------- ## ++ ++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` ++uname -m = `(uname -m) 2>/dev/null || echo unknown` ++uname -r = `(uname -r) 2>/dev/null || echo unknown` ++uname -s = `(uname -s) 2>/dev/null || echo unknown` ++uname -v = `(uname -v) 2>/dev/null || echo unknown` ++ ++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` ++/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` ++ ++/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` ++/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` ++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` ++hostinfo = `(hostinfo) 2>/dev/null || echo unknown` ++/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` ++/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` ++/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` ++ ++_ASUNAME ++ ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ echo "PATH: $as_dir" ++done ++ ++} >&5 ++ ++cat >&5 <<_ACEOF ++ ++ ++## ----------- ## ++## Core tests. ## ++## ----------- ## ++ ++_ACEOF ++ ++ ++# Keep a trace of the command line. ++# Strip out --no-create and --no-recursion so they do not pile up. ++# Strip out --silent because we don't want to record it for future runs. ++# Also quote any args containing shell meta-characters. ++# Make two passes to allow for proper duplicate-argument suppression. ++ac_configure_args= ++ac_configure_args0= ++ac_configure_args1= ++ac_sep= ++ac_must_keep_next=false ++for ac_pass in 1 2 ++do ++ for ac_arg ++ do ++ case $ac_arg in ++ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil) ++ continue ;; ++ *" "*|*" "*|*[[]~#$^&*(){}\|;<>?"']*) ++ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\''/g"` ;; ++ esac ++ case $ac_pass in ++ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; ++ 2) ++ ac_configure_args1="$ac_configure_args1 '$ac_arg'" ++ if test $ac_must_keep_next = true; then ++ ac_must_keep_next=false # Got value, back to normal. ++ else ++ case $ac_arg in ++ *=* | --config-cache | -C | -disable-* | --disable-* \ ++ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ ++ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ ++ | -with-* | --with-* | -without-* | --without-* | --x) ++ case "$ac_configure_args0 " in ++ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; ++ esac ++ ;; ++ -* ) ac_must_keep_next=true ;; ++ esac ++ fi ++ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" ++ # Get rid of the leading space. ++ ac_sep=" " ++ ;; ++ esac ++ done ++done ++$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } ++$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } ++ ++# When interrupted or exit'd, cleanup temporary files, and complete ++# config.log. We remove comments because anyway the quotes in there ++# would cause problems or look ugly. ++# WARNING: Be sure not to use single quotes in there, as some shells, ++# such as our DU 5.0 friend, will then `close' the trap. ++trap 'exit_status=$? ++ # Save into config.log some information that might help in debugging. ++ { ++ echo ++ ++ cat <<_ASBOX ++## ---------------- ## ++## Cache variables. ## ++## ---------------- ## ++_ASBOX ++ echo ++ # The following way of writing the cache mishandles newlines in values, ++{ ++ (set) 2>&1 | ++ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in ++ *ac_space=\ *) ++ sed -n \ ++ "s/'"'"'/'"'"'\\'"'"''"'"'/g; ++ s/^\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\)=\(.*\)/\1='"'"'\2'"'"'/p" ++ ;; ++ *) ++ sed -n \ ++ "s/^\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\)=\(.*\)/\1=\2/p" ++ ;; ++ esac; ++} ++ echo ++ ++ cat <<_ASBOX ++## ----------------- ## ++## Output variables. ## ++## ----------------- ## ++_ASBOX ++ echo ++ for ac_var in $ac_subst_vars ++ do ++ eval ac_val=$`echo $ac_var` ++ echo "$ac_var='"'"'$ac_val'"'"'" ++ done | sort ++ echo ++ ++ if test -n "$ac_subst_files"; then ++ cat <<_ASBOX ++## ------------- ## ++## Output files. ## ++## ------------- ## ++_ASBOX ++ echo ++ for ac_var in $ac_subst_files ++ do ++ eval ac_val=$`echo $ac_var` ++ echo "$ac_var='"'"'$ac_val'"'"'" ++ done | sort ++ echo ++ fi ++ ++ if test -s confdefs.h; then ++ cat <<_ASBOX ++## ----------- ## ++## confdefs.h. ## ++## ----------- ## ++_ASBOX ++ echo ++ sed "/^$/d" confdefs.h | sort ++ echo ++ fi ++ test "$ac_signal" != 0 && ++ echo "$as_me: caught signal $ac_signal" ++ echo "$as_me: exit $exit_status" ++ } >&5 ++ rm -f core *.core && ++ rm -rf conftest* confdefs* conf$$* $ac_clean_files && ++ exit $exit_status ++ ' 0 ++for ac_signal in 1 2 13 15; do ++ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal ++done ++ac_signal=0 ++ ++# confdefs.h avoids OS command line length limits that DEFS can exceed. ++rm -rf conftest* confdefs.h ++# AIX cpp loses on an empty file, so make sure it contains at least a newline. ++echo >confdefs.h ++ ++# Predefined preprocessor variables. ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_NAME "$PACKAGE_NAME" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_TARNAME "$PACKAGE_TARNAME" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_VERSION "$PACKAGE_VERSION" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_STRING "$PACKAGE_STRING" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" ++_ACEOF ++ ++ ++# Let the site file select an alternate cache file if it wants to. ++# Prefer explicitly selected file to automatically selected ones. ++if test -z "$CONFIG_SITE"; then ++ if test "x$prefix" != xNONE; then ++ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" ++ else ++ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" ++ fi ++fi ++for ac_site_file in $CONFIG_SITE; do ++ if test -r "$ac_site_file"; then ++ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 ++echo "$as_me: loading site script $ac_site_file" >&6;} ++ sed 's/^/| /' "$ac_site_file" >&5 ++ . "$ac_site_file" ++ fi ++done ++ ++if test -r "$cache_file"; then ++ # Some versions of bash will fail to source /dev/null (special ++ # files actually), so we avoid doing that. ++ if test -f "$cache_file"; then ++ { echo "$as_me:$LINENO: loading cache $cache_file" >&5 ++echo "$as_me: loading cache $cache_file" >&6;} ++ case $cache_file in ++ [\/]* | ?:[\/]* ) . $cache_file;; ++ *) . ./$cache_file;; ++ esac ++ fi ++else ++ { echo "$as_me:$LINENO: creating cache $cache_file" >&5 ++echo "$as_me: creating cache $cache_file" >&6;} ++ >$cache_file ++fi ++ ++# Check that the precious variables saved in the cache have kept the same ++# value. ++ac_cache_corrupted=false ++for ac_var in `(set) 2>&1 | ++ sed -n 's/^ac_env_([a-zA-Z_0-9]*)_set=.*/\1/p'`; do ++ eval ac_old_set=$ac_cv_env_${ac_var}_set ++ eval ac_new_set=$ac_env_${ac_var}_set ++ eval ac_old_val="$ac_cv_env_${ac_var}_value" ++ eval ac_new_val="$ac_env_${ac_var}_value" ++ case $ac_old_set,$ac_new_set in ++ set,) ++ { echo "$as_me:$LINENO: error: `$ac_var' was set to `$ac_old_val' in the previous run" >&5 ++echo "$as_me: error: `$ac_var' was set to `$ac_old_val' in the previous run" >&2;} ++ ac_cache_corrupted=: ;; ++ ,set) ++ { echo "$as_me:$LINENO: error: `$ac_var' was not set in the previous run" >&5 ++echo "$as_me: error: `$ac_var' was not set in the previous run" >&2;} ++ ac_cache_corrupted=: ;; ++ ,);; ++ *) ++ if test "x$ac_old_val" != "x$ac_new_val"; then ++ { echo "$as_me:$LINENO: error: `$ac_var' has changed since the previous run:" >&5 ++echo "$as_me: error: `$ac_var' has changed since the previous run:" >&2;} ++ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 ++echo "$as_me: former value: $ac_old_val" >&2;} ++ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 ++echo "$as_me: current value: $ac_new_val" >&2;} ++ ac_cache_corrupted=: ++ fi;; ++ esac ++ # Pass precious variables to config.status. ++ if test "$ac_new_set" = set; then ++ case $ac_new_val in ++ *" "*|*" "*|*[[]~#$^&*(){}\|;<>?"']*) ++ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\''/g"` ;; ++ *) ac_arg=$ac_var=$ac_new_val ;; ++ esac ++ case " $ac_configure_args " in ++ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. ++ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; ++ esac ++ fi ++done ++if $ac_cache_corrupted; then ++ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 ++echo "$as_me: error: changes in the environment can compromise the build" >&2;} ++ { { echo "$as_me:$LINENO: error: run `make distclean' and/or `rm $cache_file' and start over" >&5 ++echo "$as_me: error: run `make distclean' and/or `rm $cache_file' and start over" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ac_config_headers="$ac_config_headers config.h" ++ ++ ++ ++am__api_version="1.9" ++ac_aux_dir= ++for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do ++ if test -f $ac_dir/install-sh; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/install-sh -c" ++ break ++ elif test -f $ac_dir/install.sh; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/install.sh -c" ++ break ++ elif test -f $ac_dir/shtool; then ++ ac_aux_dir=$ac_dir ++ ac_install_sh="$ac_aux_dir/shtool install -c" ++ break ++ fi ++done ++if test -z "$ac_aux_dir"; then ++ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 ++echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ac_config_guess="$SHELL $ac_aux_dir/config.guess" ++ac_config_sub="$SHELL $ac_aux_dir/config.sub" ++ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. ++ ++# Find a good install program. We prefer a C program (faster), ++# so one script is as good as another. But avoid the broken or ++# incompatible versions: ++# SysV /etc/install, /usr/sbin/install ++# SunOS /usr/etc/install ++# IRIX /sbin/install ++# AIX /bin/install ++# AmigaOS /C/install, which installs bootblocks on floppy discs ++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag ++# AFS /usr/afsws/bin/install, which mishandles nonexistent args ++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" ++# OS/2's system install, which has a completely different semantic ++# ./install, which can be erroneously created by make from ./install.sh. ++echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 ++echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 ++if test -z "$INSTALL"; then ++if test "${ac_cv_path_install+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ # Account for people who put trailing slashes in PATH elements. ++case $as_dir/ in ++ ./ | .// | /cC/* | \ ++ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ++ ?:\/os2\/install\/* | ?:\/OS2\/INSTALL\/* | \ ++ /usr/ucb/* ) ;; ++ *) ++ # OSF1 and SCO ODT 3.0 have their own names for install. ++ # Don't use installbsd from OSF since it installs stuff as root ++ # by default. ++ for ac_prog in ginstall scoinst install; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then ++ if test $ac_prog = install && ++ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # AIX install. It has an incompatible calling convention. ++ : ++ elif test $ac_prog = install && ++ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then ++ # program-specific install script used by HP pwplus--don't use. ++ : ++ else ++ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" ++ break 3 ++ fi ++ fi ++ done ++ done ++ ;; ++esac ++done ++ ++ ++fi ++ if test "${ac_cv_path_install+set}" = set; then ++ INSTALL=$ac_cv_path_install ++ else ++ # As a last resort, use the slow shell script. We don't cache a ++ # path for INSTALL within a source directory, because that will ++ # break other packages using the cache if that directory is ++ # removed, or if the path is relative. ++ INSTALL=$ac_install_sh ++ fi ++fi ++echo "$as_me:$LINENO: result: $INSTALL" >&5 ++echo "${ECHO_T}$INSTALL" >&6 ++ ++# Use test -z because SunOS4 sh mishandles braces in ${var-val}. ++# It thinks the first close brace ends the variable substitution. ++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' ++ ++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' ++ ++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ++ ++echo "$as_me:$LINENO: checking whether build environment is sane" >&5 ++echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 ++# Just in case ++sleep 1 ++echo timestamp > conftest.file ++# Do `set' in a subshell so we don't clobber the current shell's ++# arguments. Must try -L first in case configure is actually a ++# symlink; some systems play weird games with the mod time of symlinks ++# (eg FreeBSD returns the mod time of the symlink's containing ++# directory). ++if ( ++ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` ++ if test "$*" = "X"; then ++ # -L didn't work. ++ set X `ls -t $srcdir/configure conftest.file` ++ fi ++ rm -f conftest.file ++ if test "$*" != "X $srcdir/configure conftest.file" \ ++ && test "$*" != "X conftest.file $srcdir/configure"; then ++ ++ # If neither matched, then we have a broken ls. This can happen ++ # if, for instance, CONFIG_SHELL is bash and it inherits a ++ # broken ls alias from the environment. This has actually ++ # happened. Such a system could not be considered "sane". ++ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken ++alias in your environment" >&5 ++echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken ++alias in your environment" >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++ ++ test "$2" = conftest.file ++ ) ++then ++ # Ok. ++ : ++else ++ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! ++Check your system clock" >&5 ++echo "$as_me: error: newly created file is older than distributed files! ++Check your system clock" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++test "$program_prefix" != NONE && ++ program_transform_name="s,^,$program_prefix,;$program_transform_name" ++# Use a double $ so make ignores it. ++test "$program_suffix" != NONE && ++ program_transform_name="s,$,$program_suffix,;$program_transform_name" ++# Double any \ or $. echo might interpret backslashes. ++# By default was `s,x,x', remove it if useless. ++cat <<_ACEOF >conftest.sed ++s/[\$]/&&/g;s/;s,x,x,$// ++_ACEOF ++program_transform_name=`echo $program_transform_name | sed -f conftest.sed` ++rm conftest.sed ++ ++# expand $ac_aux_dir to an absolute path ++am_aux_dir=`cd $ac_aux_dir && pwd` ++ ++test x"${MISSING+set}" = xset || MISSING="${SHELL} $am_aux_dir/missing" ++# Use eval to expand $SHELL ++if eval "$MISSING --run true"; then ++ am_missing_run="$MISSING --run " ++else ++ am_missing_run= ++ { echo "$as_me:$LINENO: WARNING: `missing' script is too old or missing" >&5 ++echo "$as_me: WARNING: `missing' script is too old or missing" >&2;} ++fi ++ ++if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then ++ # We used to keeping the `.' as first argument, in order to ++ # allow $(mkdir_p) to be used without argument. As in ++ # $(mkdir_p) $(somedir) ++ # where $(somedir) is conditionally defined. However this is wrong ++ # for two reasons: ++ # 1. if the package is installed by a user who cannot write `.' ++ # make install will fail, ++ # 2. the above comment should most certainly read ++ # $(mkdir_p) $(DESTDIR)$(somedir) ++ # so it does not work when $(somedir) is undefined and ++ # $(DESTDIR) is not. ++ # To support the latter case, we have to write ++ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), ++ # so the `.' trick is pointless. ++ mkdir_p='mkdir -p --' ++else ++ # On NextStep and OpenStep, the `mkdir' command does not ++ # recognize any option. It will interpret all options as ++ # directories to create, and then abort because `.' already ++ # exists. ++ for d in ./-p ./--version; ++ do ++ test -d $d && rmdir $d ++ done ++ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. ++ if test -f "$ac_aux_dir/mkinstalldirs"; then ++ mkdir_p='$(mkinstalldirs)' ++ else ++ mkdir_p='$(install_sh) -d' ++ fi ++fi ++ ++for ac_prog in gawk mawk nawk awk ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_AWK+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$AWK"; then ++ ac_cv_prog_AWK="$AWK" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_AWK="$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++AWK=$ac_cv_prog_AWK ++if test -n "$AWK"; then ++ echo "$as_me:$LINENO: result: $AWK" >&5 ++echo "${ECHO_T}$AWK" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$AWK" && break ++done ++ ++echo "$as_me:$LINENO: checking whether ${MAKE-make} sets $(MAKE)" >&5 ++echo $ECHO_N "checking whether ${MAKE-make} sets $(MAKE)... $ECHO_C" >&6 ++set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` ++if eval "test "${ac_cv_prog_make_${ac_make}_set+set}" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.make <<_ACEOF ++all: ++ @echo 'ac_maketemp="$(MAKE)"' ++_ACEOF ++# GNU make sometimes prints "make[1]: Entering...", which would confuse us. ++eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` ++if test -n "$ac_maketemp"; then ++ eval ac_cv_prog_make_${ac_make}_set=yes ++else ++ eval ac_cv_prog_make_${ac_make}_set=no ++fi ++rm -f conftest.make ++fi ++if eval "test "`echo '$ac_cv_prog_make_'${ac_make}_set`" = yes"; then ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++ SET_MAKE= ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++ SET_MAKE="MAKE=${MAKE-make}" ++fi ++ ++rm -rf .tst 2>/dev/null ++mkdir .tst 2>/dev/null ++if test -d .tst; then ++ am__leading_dot=. ++else ++ am__leading_dot=_ ++fi ++rmdir .tst 2>/dev/null ++ ++# test to see if srcdir already configured ++if test "`cd $srcdir && pwd`" != "`pwd`" && ++ test -f $srcdir/config.status; then ++ { { echo "$as_me:$LINENO: error: source directory already configured; run "make distclean" there first" >&5 ++echo "$as_me: error: source directory already configured; run "make distclean" there first" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++# test whether we have cygpath ++if test -z "$CYGPATH_W"; then ++ if (cygpath --version) >/dev/null 2>/dev/null; then ++ CYGPATH_W='cygpath -w' ++ else ++ CYGPATH_W=echo ++ fi ++fi ++ ++ ++# Define the identity of the package. ++ PACKAGE='lua-at' ++ VERSION='5.1.3' ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define PACKAGE "$PACKAGE" ++_ACEOF ++ ++ ++cat >>confdefs.h <<_ACEOF ++#define VERSION "$VERSION" ++_ACEOF ++ ++# Some tools Automake needs. ++ ++ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} ++ ++ ++AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} ++ ++ ++AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} ++ ++ ++AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} ++ ++ ++MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} ++ ++install_sh=${install_sh-"$am_aux_dir/install-sh"} ++ ++# Installed binaries are usually stripped using `strip' when the user ++# run `make install-strip'. However `strip' might not be the right ++# tool to use in cross-compilation environments, therefore Automake ++# will honor the `STRIP' environment variable to overrule this program. ++if test "$cross_compiling" != no; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. ++set dummy ${ac_tool_prefix}strip; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_STRIP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$STRIP"; then ++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_STRIP="${ac_tool_prefix}strip" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++STRIP=$ac_cv_prog_STRIP ++if test -n "$STRIP"; then ++ echo "$as_me:$LINENO: result: $STRIP" >&5 ++echo "${ECHO_T}$STRIP" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_STRIP"; then ++ ac_ct_STRIP=$STRIP ++ # Extract the first word of "strip", so it can be a program name with args. ++set dummy strip; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_STRIP"; then ++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_STRIP="strip" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" ++fi ++fi ++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP ++if test -n "$ac_ct_STRIP"; then ++ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 ++echo "${ECHO_T}$ac_ct_STRIP" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ STRIP=$ac_ct_STRIP ++else ++ STRIP="$ac_cv_prog_STRIP" ++fi ++ ++fi ++INSTALL_STRIP_PROGRAM="${SHELL} $(install_sh) -c -s" ++ ++# We need awk for the "check" target. The system "awk" is bad on ++# some platforms. ++# Always define AMTAR for backward compatibility. ++ ++AMTAR=${AMTAR-"${am_missing_run}tar"} ++ ++am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ++ ++ ++ ++ ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. ++set dummy ${ac_tool_prefix}gcc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CC="${ac_tool_prefix}gcc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_CC"; then ++ ac_ct_CC=$CC ++ # Extract the first word of "gcc", so it can be a program name with args. ++set dummy gcc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CC="gcc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++echo "${ECHO_T}$ac_ct_CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ CC=$ac_ct_CC ++else ++ CC="$ac_cv_prog_CC" ++fi ++ ++if test -z "$CC"; then ++ if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. ++set dummy ${ac_tool_prefix}cc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CC="${ac_tool_prefix}cc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_CC"; then ++ ac_ct_CC=$CC ++ # Extract the first word of "cc", so it can be a program name with args. ++set dummy cc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CC="cc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++echo "${ECHO_T}$ac_ct_CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ CC=$ac_ct_CC ++else ++ CC="$ac_cv_prog_CC" ++fi ++ ++fi ++if test -z "$CC"; then ++ # Extract the first word of "cc", so it can be a program name with args. ++set dummy cc; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++ ac_prog_rejected=no ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ++ ac_prog_rejected=yes ++ continue ++ fi ++ ac_cv_prog_CC="cc" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++if test $ac_prog_rejected = yes; then ++ # We found a bogon in the path, so make sure we never use it. ++ set dummy $ac_cv_prog_CC ++ shift ++ if test $# != 0; then ++ # We chose a different compiler from the bogus one. ++ # However, it has the same basename, so the bogon will be chosen ++ # first if we set CC to just the basename; use the full file name. ++ shift ++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" ++ fi ++fi ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$CC"; then ++ if test -n "$ac_tool_prefix"; then ++ for ac_prog in cl ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CC"; then ++ ac_cv_prog_CC="$CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CC="$ac_tool_prefix$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++CC=$ac_cv_prog_CC ++if test -n "$CC"; then ++ echo "$as_me:$LINENO: result: $CC" >&5 ++echo "${ECHO_T}$CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$CC" && break ++ done ++fi ++if test -z "$CC"; then ++ ac_ct_CC=$CC ++ for ac_prog in cl ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_CC"; then ++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CC="$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_CC=$ac_cv_prog_ac_ct_CC ++if test -n "$ac_ct_CC"; then ++ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 ++echo "${ECHO_T}$ac_ct_CC" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$ac_ct_CC" && break ++done ++ ++ CC=$ac_ct_CC ++fi ++ ++fi ++ ++ ++test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in $PATH ++See `config.log' for more details." >&5 ++echo "$as_me: error: no acceptable C compiler found in $PATH ++See `config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++ ++# Provide some information about the compiler. ++echo "$as_me:$LINENO:" \ ++ "checking for C compiler version" >&5 ++ac_compiler=`set X $ac_compile; echo $2` ++{ (eval echo "$as_me:$LINENO: "$ac_compiler --version </dev/null >&5"") >&5 ++ (eval $ac_compiler --version </dev/null >&5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: "$ac_compiler -v </dev/null >&5"") >&5 ++ (eval $ac_compiler -v </dev/null >&5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: "$ac_compiler -V </dev/null >&5"") >&5 ++ (eval $ac_compiler -V </dev/null >&5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++ ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++ac_clean_files_save=$ac_clean_files ++ac_clean_files="$ac_clean_files a.out a.exe b.out" ++# Try to create an executable without -o first, disregard a.out. ++# It will help us diagnose broken compilers, and finding out an intuition ++# of exeext. ++echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 ++echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ++ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` ++if { (eval echo "$as_me:$LINENO: "$ac_link_default"") >&5 ++ (eval $ac_link_default) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ # Find the output, starting from the most likely. This scheme is ++# not robust to junk in `.', hence go to wildcards (a.*) only as a last ++# resort. ++ ++# Be careful to initialize this variable, since it used to be cached. ++# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ++ac_cv_exeext= ++# b.out is created by i960 compilers. ++for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out ++do ++ test -f "$ac_file" || continue ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ++ ;; ++ conftest.$ac_ext ) ++ # This is the source file. ++ ;; ++ [ab].out ) ++ # We found the default executable, but exeext='' is most ++ # certainly right. ++ break;; ++ *.* ) ++ ac_cv_exeext=`expr "$ac_file" : '[^.]*(..*)'` ++ # FIXME: I believe we export ac_cv_exeext for Libtool, ++ # but it would be cool to find out if it's true. Does anybody ++ # maintain Libtool? --akim. ++ export ac_cv_exeext ++ break;; ++ * ) ++ break;; ++ esac ++done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++{ { echo "$as_me:$LINENO: error: C compiler cannot create executables ++See `config.log' for more details." >&5 ++echo "$as_me: error: C compiler cannot create executables ++See `config.log' for more details." >&2;} ++ { (exit 77); exit 77; }; } ++fi ++ ++ac_exeext=$ac_cv_exeext ++echo "$as_me:$LINENO: result: $ac_file" >&5 ++echo "${ECHO_T}$ac_file" >&6 ++ ++# Check the compiler produces executables we can run. If not, either ++# the compiler is broken, or we cross compile. ++echo "$as_me:$LINENO: checking whether the C compiler works" >&5 ++echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 ++# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 ++# If not cross compiling, check that we can run a simple program. ++if test "$cross_compiling" != yes; then ++ if { ac_try='./$ac_file' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ cross_compiling=no ++ else ++ if test "$cross_compiling" = maybe; then ++ cross_compiling=yes ++ else ++ { { echo "$as_me:$LINENO: error: cannot run C compiled programs. ++If you meant to cross compile, use `--host'. ++See `config.log' for more details." >&5 ++echo "$as_me: error: cannot run C compiled programs. ++If you meant to cross compile, use `--host'. ++See `config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++ fi ++fi ++echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++ ++rm -f a.out a.exe conftest$ac_cv_exeext b.out ++ac_clean_files=$ac_clean_files_save ++# Check the compiler produces executables we can run. If not, either ++# the compiler is broken, or we cross compile. ++echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 ++echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 ++echo "$as_me:$LINENO: result: $cross_compiling" >&5 ++echo "${ECHO_T}$cross_compiling" >&6 ++ ++echo "$as_me:$LINENO: checking for suffix of executables" >&5 ++echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ # If both `conftest.exe' and `conftest' are `present' (well, observable) ++# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will ++# work properly (i.e., refer to `conftest.exe'), while it won't with ++# `rm'. ++for ac_file in conftest.exe conftest conftest.*; do ++ test -f "$ac_file" || continue ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; ++ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*(..*)'` ++ export ac_cv_exeext ++ break;; ++ * ) break;; ++ esac ++done ++else ++ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link ++See `config.log' for more details." >&5 ++echo "$as_me: error: cannot compute suffix of executables: cannot compile and link ++See `config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++rm -f conftest$ac_cv_exeext ++echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 ++echo "${ECHO_T}$ac_cv_exeext" >&6 ++ ++rm -f conftest.$ac_ext ++EXEEXT=$ac_cv_exeext ++ac_exeext=$EXEEXT ++echo "$as_me:$LINENO: checking for suffix of object files" >&5 ++echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 ++if test "${ac_cv_objext+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.o conftest.obj ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do ++ case $ac_file in ++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; ++ *) ac_cv_objext=`expr "$ac_file" : '.*.(.*)'` ++ break;; ++ esac ++done ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile ++See `config.log' for more details." >&5 ++echo "$as_me: error: cannot compute suffix of object files: cannot compile ++See `config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++rm -f conftest.$ac_cv_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 ++echo "${ECHO_T}$ac_cv_objext" >&6 ++OBJEXT=$ac_cv_objext ++ac_objext=$OBJEXT ++echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 ++echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 ++if test "${ac_cv_c_compiler_gnu+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++#ifndef __GNUC__ ++ choke me ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_compiler_gnu=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_compiler_gnu=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_cv_c_compiler_gnu=$ac_compiler_gnu ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 ++echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 ++GCC=`test $ac_compiler_gnu = yes && echo yes` ++ac_test_CFLAGS=${CFLAGS+set} ++ac_save_CFLAGS=$CFLAGS ++CFLAGS="-g" ++echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 ++echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 ++if test "${ac_cv_prog_cc_g+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_prog_cc_g=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_prog_cc_g=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 ++echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 ++if test "$ac_test_CFLAGS" = set; then ++ CFLAGS=$ac_save_CFLAGS ++elif test $ac_cv_prog_cc_g = yes; then ++ if test "$GCC" = yes; then ++ CFLAGS="-g -O2" ++ else ++ CFLAGS="-g" ++ fi ++else ++ if test "$GCC" = yes; then ++ CFLAGS="-O2" ++ else ++ CFLAGS= ++ fi ++fi ++echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 ++echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 ++if test "${ac_cv_prog_cc_stdc+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_prog_cc_stdc=no ++ac_save_CC=$CC ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <stdarg.h> ++#include <stdio.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ ++struct buf { int x; }; ++FILE * (*rcsopen) (struct buf *, struct stat *, int); ++static char *e (p, i) ++ char **p; ++ int i; ++{ ++ return p[i]; ++} ++static char *f (char * (*g) (char **, int), char **p, ...) ++{ ++ char *s; ++ va_list v; ++ va_start (v,p); ++ s = g (p, va_arg (v,int)); ++ va_end (v); ++ return s; ++} ++ ++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has ++ function prototypes and stuff, but not '\xHH' hex character constants. ++ These don't provoke an error unfortunately, instead are silently treated ++ as 'x'. The following induces an error, until -std1 is added to get ++ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an ++ array size at least. It's necessary to write '\x00'==0 to get something ++ that's true only with -std1. */ ++int osf4_cc_array ['\x00' == 0 ? 1 : -1]; ++ ++int test (int i, double x); ++struct s1 {int (*f) (int a);}; ++struct s2 {int (*f) (double a);}; ++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); ++int argc; ++char **argv; ++int ++main () ++{ ++return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ++ ; ++ return 0; ++} ++_ACEOF ++# Don't try gcc -ansi; that turns off useful extensions and ++# breaks some systems' header files. ++# AIX -qlanglvl=ansi ++# Ultrix and OSF/1 -std1 ++# HP-UX 10.20 and later -Ae ++# HP-UX older versions -Aa -D_HPUX_SOURCE ++# SVR4 -Xc -D__EXTENSIONS__ ++for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" ++do ++ CC="$ac_save_CC $ac_arg" ++ rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_prog_cc_stdc=$ac_arg ++break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext ++done ++rm -f conftest.$ac_ext conftest.$ac_objext ++CC=$ac_save_CC ++ ++fi ++ ++case "x$ac_cv_prog_cc_stdc" in ++ x|xno) ++ echo "$as_me:$LINENO: result: none needed" >&5 ++echo "${ECHO_T}none needed" >&6 ;; ++ *) ++ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 ++echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 ++ CC="$CC $ac_cv_prog_cc_stdc" ;; ++esac ++ ++# Some people use a C++ compiler to compile C. Since we use `exit', ++# in C++ we need to declare it. In case someone uses the same compiler ++# for both compiling C and C++ we need to have the C++ compiler decide ++# the declaration of exit, since it's the most demanding environment. ++cat >conftest.$ac_ext <<_ACEOF ++#ifndef __cplusplus ++ choke me ++#endif ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ for ac_declaration in \ ++ '' \ ++ 'extern "C" void std::exit (int) throw (); using std::exit;' \ ++ 'extern "C" void std::exit (int); using std::exit;' \ ++ 'extern "C" void exit (int) throw ();' \ ++ 'extern "C" void exit (int);' \ ++ 'void exit (int);' ++do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_declaration ++#include <stdlib.h> ++int ++main () ++{ ++exit (42); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++continue ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_declaration ++int ++main () ++{ ++exit (42); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++done ++rm -f conftest* ++if test -n "$ac_declaration"; then ++ echo '#ifdef __cplusplus' >>confdefs.h ++ echo $ac_declaration >>confdefs.h ++ echo '#endif' >>confdefs.h ++fi ++ ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++DEPDIR="${am__leading_dot}deps" ++ ++ ac_config_commands="$ac_config_commands depfiles" ++ ++ ++am_make=${MAKE-make} ++cat > confinc << 'END' ++am__doit: ++ @echo done ++.PHONY: am__doit ++END ++# If we don't find an include directive, just comment out the code. ++echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 ++echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 ++am__include="#" ++am__quote= ++_am_result=none ++# First try GNU make style include. ++echo "include confinc" > confmf ++# We grep out `Entering directory' and `Leaving directory' ++# messages which can occur if `w' ends up in MAKEFLAGS. ++# In particular we don't look at `^make:' because GNU make might ++# be invoked under some other name (usually "gmake"), in which ++# case it prints its new name instead of `make'. ++if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then ++ am__include=include ++ am__quote= ++ _am_result=GNU ++fi ++# Now try BSD make style include. ++if test "$am__include" = "#"; then ++ echo '.include "confinc"' > confmf ++ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then ++ am__include=.include ++ am__quote=""" ++ _am_result=BSD ++ fi ++fi ++ ++ ++echo "$as_me:$LINENO: result: $_am_result" >&5 ++echo "${ECHO_T}$_am_result" >&6 ++rm -f confinc confmf ++ ++# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. ++if test "${enable_dependency_tracking+set}" = set; then ++ enableval="$enable_dependency_tracking" ++ ++fi; ++if test "x$enable_dependency_tracking" != xno; then ++ am_depcomp="$ac_aux_dir/depcomp" ++ AMDEPBACKSLASH='' ++fi ++ ++ ++if test "x$enable_dependency_tracking" != xno; then ++ AMDEP_TRUE= ++ AMDEP_FALSE='#' ++else ++ AMDEP_TRUE='#' ++ AMDEP_FALSE= ++fi ++ ++ ++ ++ ++depcc="$CC" am_compiler_list= ++ ++echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 ++echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 ++if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named `D' -- because `-MD' means `put the output ++ # in D'. ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_CC_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n 's/^#*([a-zA-Z0-9]*))$/\1/p' < ./depcomp` ++ fi ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with ), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with ++ # Solaris 8's {/usr,}/bin/sh. ++ touch sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ case $depmode in ++ nosideeffect) ++ # after this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ none) break ;; ++ esac ++ # We check with `-c' and `-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle `-M -o', and we need to detect this. ++ if depmode=$depmode \ ++ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_CC_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_CC_dependencies_compiler_type=none ++fi ++ ++fi ++echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 ++echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 ++CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type ++ ++ ++ ++if ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then ++ am__fastdepCC_TRUE= ++ am__fastdepCC_FALSE='#' ++else ++ am__fastdepCC_TRUE='#' ++ am__fastdepCC_FALSE= ++fi ++ ++ ++# Check whether --enable-shared or --disable-shared was given. ++if test "${enable_shared+set}" = set; then ++ enableval="$enable_shared" ++ p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_shared=yes ;; ++ no) enable_shared=no ;; ++ *) ++ enable_shared=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_shared=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_shared=yes ++fi; ++ ++# Check whether --enable-static or --disable-static was given. ++if test "${enable_static+set}" = set; then ++ enableval="$enable_static" ++ p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_static=yes ;; ++ no) enable_static=no ;; ++ *) ++ enable_static=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_static=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_static=yes ++fi; ++ ++# Check whether --enable-fast-install or --disable-fast-install was given. ++if test "${enable_fast_install+set}" = set; then ++ enableval="$enable_fast_install" ++ p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_fast_install=yes ;; ++ no) enable_fast_install=no ;; ++ *) ++ enable_fast_install=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for pkg in $enableval; do ++ IFS="$lt_save_ifs" ++ if test "X$pkg" = "X$p"; then ++ enable_fast_install=yes ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ;; ++ esac ++else ++ enable_fast_install=yes ++fi; ++ ++# Make sure we can run config.sub. ++$ac_config_sub sun4 >/dev/null 2>&1 || ++ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 ++echo "$as_me: error: cannot run $ac_config_sub" >&2;} ++ { (exit 1); exit 1; }; } ++ ++echo "$as_me:$LINENO: checking build system type" >&5 ++echo $ECHO_N "checking build system type... $ECHO_C" >&6 ++if test "${ac_cv_build+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_build_alias=$build_alias ++test -z "$ac_cv_build_alias" && ++ ac_cv_build_alias=`$ac_config_guess` ++test -z "$ac_cv_build_alias" && ++ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 ++echo "$as_me: error: cannot guess build type; you must specify one" >&2;} ++ { (exit 1); exit 1; }; } ++ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || ++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 ++echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} ++ { (exit 1); exit 1; }; } ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_build" >&5 ++echo "${ECHO_T}$ac_cv_build" >&6 ++build=$ac_cv_build ++build_cpu=`echo $ac_cv_build | sed 's/^([^-]*)-([^-]*)-(.*)$/\1/'` ++build_vendor=`echo $ac_cv_build | sed 's/^([^-]*)-([^-]*)-(.*)$/\2/'` ++build_os=`echo $ac_cv_build | sed 's/^([^-]*)-([^-]*)-(.*)$/\3/'` ++ ++ ++echo "$as_me:$LINENO: checking host system type" >&5 ++echo $ECHO_N "checking host system type... $ECHO_C" >&6 ++if test "${ac_cv_host+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_host_alias=$host_alias ++test -z "$ac_cv_host_alias" && ++ ac_cv_host_alias=$ac_cv_build_alias ++ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || ++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 ++echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} ++ { (exit 1); exit 1; }; } ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_host" >&5 ++echo "${ECHO_T}$ac_cv_host" >&6 ++host=$ac_cv_host ++host_cpu=`echo $ac_cv_host | sed 's/^([^-]*)-([^-]*)-(.*)$/\1/'` ++host_vendor=`echo $ac_cv_host | sed 's/^([^-]*)-([^-]*)-(.*)$/\2/'` ++host_os=`echo $ac_cv_host | sed 's/^([^-]*)-([^-]*)-(.*)$/\3/'` ++ ++ ++echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 ++echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 ++if test "${lt_cv_path_SED+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # Loop through the user's path and test for sed and gsed. ++# Then use that list of sed's as ones to test for truncation. ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for lt_ac_prog in sed gsed; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then ++ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" ++ fi ++ done ++ done ++done ++lt_ac_max=0 ++lt_ac_count=0 ++# Add /usr/xpg4/bin/sed as it is typically found on Solaris ++# along with /bin/sed that truncates output. ++for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do ++ test ! -f $lt_ac_sed && continue ++ cat /dev/null > conftest.in ++ lt_ac_count=0 ++ echo $ECHO_N "0123456789$ECHO_C" >conftest.in ++ # Check for GNU sed and select it if it is found. ++ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then ++ lt_cv_path_SED=$lt_ac_sed ++ break ++ fi ++ while true; do ++ cat conftest.in conftest.in >conftest.tmp ++ mv conftest.tmp conftest.in ++ cp conftest.in conftest.nl ++ echo >>conftest.nl ++ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break ++ cmp -s conftest.out conftest.nl || break ++ # 10000 chars as input seems more than enough ++ test $lt_ac_count -gt 10 && break ++ lt_ac_count=`expr $lt_ac_count + 1` ++ if test $lt_ac_count -gt $lt_ac_max; then ++ lt_ac_max=$lt_ac_count ++ lt_cv_path_SED=$lt_ac_sed ++ fi ++ done ++done ++ ++fi ++ ++SED=$lt_cv_path_SED ++echo "$as_me:$LINENO: result: $SED" >&5 ++echo "${ECHO_T}$SED" >&6 ++ ++echo "$as_me:$LINENO: checking for egrep" >&5 ++echo $ECHO_N "checking for egrep... $ECHO_C" >&6 ++if test "${ac_cv_prog_egrep+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if echo a | (grep -E '(a|b)') >/dev/null 2>&1 ++ then ac_cv_prog_egrep='grep -E' ++ else ac_cv_prog_egrep='egrep' ++ fi ++fi ++echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 ++echo "${ECHO_T}$ac_cv_prog_egrep" >&6 ++ EGREP=$ac_cv_prog_egrep ++ ++ ++ ++# Check whether --with-gnu-ld or --without-gnu-ld was given. ++if test "${with_gnu_ld+set}" = set; then ++ withval="$with_gnu_ld" ++ test "$withval" = no || with_gnu_ld=yes ++else ++ with_gnu_ld=no ++fi; ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ echo "$as_me:$LINENO: checking for ld used by $CC" >&5 ++echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [\/]* | ?:[\/]*) ++ re_direlt='/[^/][^/]*/../' ++ # Canonicalize the pathname of ld ++ ac_prog=`echo $ac_prog| $SED 's%\\%/%g'` ++ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ echo "$as_me:$LINENO: checking for GNU ld" >&5 ++echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 ++else ++ echo "$as_me:$LINENO: checking for non-GNU ld" >&5 ++echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 ++fi ++if test "${lt_cv_path_LD+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -z "$LD"; then ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in ++ *GNU* | *'with BFD'*) ++ test "$with_gnu_ld" != no && break ++ ;; ++ *) ++ test "$with_gnu_ld" != yes && break ++ ;; ++ esac ++ fi ++ done ++ IFS="$lt_save_ifs" ++else ++ lt_cv_path_LD="$LD" # Let the user override the test with a path. ++fi ++fi ++ ++LD="$lt_cv_path_LD" ++if test -n "$LD"; then ++ echo "$as_me:$LINENO: result: $LD" >&5 ++echo "${ECHO_T}$LD" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in $PATH" >&5 ++echo "$as_me: error: no acceptable ld found in $PATH" >&2;} ++ { (exit 1); exit 1; }; } ++echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 ++echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 ++if test "${lt_cv_prog_gnu_ld+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # I'd rather use --version here, but apparently some GNU lds only accept -v. ++case `$LD -v 2>&1 </dev/null` in ++*GNU* | *'with BFD'*) ++ lt_cv_prog_gnu_ld=yes ++ ;; ++*) ++ lt_cv_prog_gnu_ld=no ++ ;; ++esac ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5 ++echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 ++with_gnu_ld=$lt_cv_prog_gnu_ld ++ ++ ++echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 ++echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 ++if test "${lt_cv_ld_reload_flag+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_ld_reload_flag='-r' ++fi ++echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 ++echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 ++reload_flag=$lt_cv_ld_reload_flag ++case $reload_flag in ++"" | " "*) ;; ++*) reload_flag=" $reload_flag" ;; ++esac ++reload_cmds='$LD$reload_flag -o $output$reload_objs' ++case $host_os in ++ darwin*) ++ if test "$GCC" = yes; then ++ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' ++ else ++ reload_cmds='$LD$reload_flag -o $output$reload_objs' ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 ++echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 ++if test "${lt_cv_path_NM+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$NM"; then ++ # Let the user override the test. ++ lt_cv_path_NM="$NM" ++else ++ lt_nm_to_check="${ac_tool_prefix}nm" ++ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then ++ lt_nm_to_check="$lt_nm_to_check nm" ++ fi ++ for lt_tmp_nm in $lt_nm_to_check; do ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ tmp_nm="$ac_dir/$lt_tmp_nm" ++ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then ++ # Check to see if the nm accepts a BSD-compat flag. ++ # Adding the `sed 1q' prevents false positives on HP-UX, which says: ++ # nm: unknown option "B" ignored ++ # Tru64's nm complains that /dev/null is an invalid object file ++ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in ++ */dev/null* | *'Invalid file or object type'*) ++ lt_cv_path_NM="$tmp_nm -B" ++ break ++ ;; ++ *) ++ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in ++ */dev/null*) ++ lt_cv_path_NM="$tmp_nm -p" ++ break ++ ;; ++ *) ++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but ++ continue # so that we can try to find one that supports BSD flags ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ done ++ IFS="$lt_save_ifs" ++ done ++ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm ++fi ++fi ++echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 ++echo "${ECHO_T}$lt_cv_path_NM" >&6 ++NM="$lt_cv_path_NM" ++ ++echo "$as_me:$LINENO: checking whether ln -s works" >&5 ++echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 ++LN_S=$as_ln_s ++if test "$LN_S" = "ln -s"; then ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++else ++ echo "$as_me:$LINENO: result: no, using $LN_S" >&5 ++echo "${ECHO_T}no, using $LN_S" >&6 ++fi ++ ++echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 ++echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 ++if test "${lt_cv_deplibs_check_method+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_file_magic_cmd='$MAGIC_CMD' ++lt_cv_file_magic_test_file= ++lt_cv_deplibs_check_method='unknown' ++# Need to set the preceding variable on all platforms that support ++# interlibrary dependencies. ++# 'none' -- dependencies not supported. ++# `unknown' -- same as none, but documents that we really don't know. ++# 'pass_all' -- all dependencies passed with no checks. ++# 'test_compile' -- check by making test program. ++# 'file_magic [[regex]]' -- check by looking for files in library path ++# which responds to the $file_magic_cmd with a given extended regex. ++# If you have `file' or equivalent on your system and you're not sure ++# whether `pass_all' will *always* work, you probably want this one. ++ ++case $host_os in ++aix4* | aix5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++beos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++bsdi[45]*) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' ++ lt_cv_file_magic_cmd='/usr/bin/file -L' ++ lt_cv_file_magic_test_file=/shlib/libc.so ++ ;; ++ ++cygwin*) ++ # func_win32_libid is a shell function defined in ltmain.sh ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ ;; ++ ++mingw* | pw32*) ++ # Base MSYS/MinGW do not provide the 'file' command needed by ++ # func_win32_libid shell function, so use a weaker test based on 'objdump'. ++ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ ;; ++ ++darwin* | rhapsody*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++freebsd* | kfreebsd*-gnu | dragonfly*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then ++ case $host_cpu in ++ i*86 ) ++ # Not sure whether the presence of OpenBSD here was a mistake. ++ # Let's accept both of them until this is cleared up. ++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ++ ;; ++ esac ++ else ++ lt_cv_deplibs_check_method=pass_all ++ fi ++ ;; ++ ++gnu*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++hpux10.20* | hpux11*) ++ lt_cv_file_magic_cmd=/usr/bin/file ++ case $host_cpu in ++ ia64*) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' ++ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ++ ;; ++ hppa*64*) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' ++ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ++ ;; ++ *) ++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' ++ lt_cv_file_magic_test_file=/usr/lib/libc.sl ++ ;; ++ esac ++ ;; ++ ++interix3*) ++ # PIC code is broken on Interix 3.x, that's why |.a not |_pic.a here ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(.so|.a)$' ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $LD in ++ *-32|*"-32 ") libmagic=32-bit;; ++ *-n32|*"-n32 ") libmagic=N32;; ++ *-64|*"-64 ") libmagic=64-bit;; ++ *) libmagic=never-match;; ++ esac ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(.so.[0-9]+.[0-9]+|_pic.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(.so|_pic.a)$' ++ fi ++ ;; ++ ++newos6*) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' ++ lt_cv_file_magic_cmd=/usr/bin/file ++ lt_cv_file_magic_test_file=/usr/lib/libnls.so ++ ;; ++ ++nto-qnx*) ++ lt_cv_deplibs_check_method=unknown ++ ;; ++ ++openbsd*) ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(.so.[0-9]+.[0-9]+|.so|_pic.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(.so.[0-9]+.[0-9]+|_pic.a)$' ++ fi ++ ;; ++ ++osf3* | osf4* | osf5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++solaris*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv4 | sysv4.3*) ++ case $host_vendor in ++ motorola) ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ++ ;; ++ ncr) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ sequent) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ++ ;; ++ sni) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" ++ lt_cv_file_magic_test_file=/lib/libc.so ++ ;; ++ siemens) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ pc) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ esac ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++esac ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 ++echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 ++file_magic_cmd=$lt_cv_file_magic_cmd ++deplibs_check_method=$lt_cv_deplibs_check_method ++test -z "$deplibs_check_method" && deplibs_check_method=unknown ++ ++ ++ ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# Check whether --enable-libtool-lock or --disable-libtool-lock was given. ++if test "${enable_libtool_lock+set}" = set; then ++ enableval="$enable_libtool_lock" ++ ++fi; ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++# Some flags need to be propagated to the compiler or linker for good ++# libtool support. ++case $host in ++ia64-*-hpux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *ELF-32*) ++ HPUX_IA64_MODE="32" ++ ;; ++ *ELF-64*) ++ HPUX_IA64_MODE="64" ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++*-*-irix6*) ++ # Find out which ABI we are using. ++ echo '#line 3677 "configure"' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -melf32bsmip" ++ ;; ++ *N32*) ++ LD="${LD-ld} -melf32bmipn32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -melf64bmip" ++ ;; ++ esac ++ else ++ case `/usr/bin/file conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -32" ++ ;; ++ *N32*) ++ LD="${LD-ld} -n32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -64" ++ ;; ++ esac ++ fi ++ fi ++ rm -rf conftest* ++ ;; ++ ++x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.o` in ++ *32-bit*) ++ case $host in ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_i386" ++ ;; ++ ppc64-*linux*|powerpc64-*linux*) ++ LD="${LD-ld} -m elf32ppclinux" ++ ;; ++ s390x-*linux*) ++ LD="${LD-ld} -m elf_s390" ++ ;; ++ sparc64-*linux*) ++ LD="${LD-ld} -m elf32_sparc" ++ ;; ++ esac ++ ;; ++ *64-bit*) ++ case $host in ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ ppc*-*linux*|powerpc*-*linux*) ++ LD="${LD-ld} -m elf64ppc" ++ ;; ++ s390*-*linux*) ++ LD="${LD-ld} -m elf64_s390" ++ ;; ++ sparc*-*linux*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++*-*-sco3.2v5*) ++ # On SCO OpenServer 5, we need -belf to get full-featured binaries. ++ SAVE_CFLAGS="$CFLAGS" ++ CFLAGS="$CFLAGS -belf" ++ echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 ++echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 ++if test "${lt_cv_cc_needs_belf+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ lt_cv_cc_needs_belf=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++lt_cv_cc_needs_belf=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++ ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 ++echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 ++ if test x"$lt_cv_cc_needs_belf" != x"yes"; then ++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf ++ CFLAGS="$SAVE_CFLAGS" ++ fi ++ ;; ++sparc*-*solaris*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++ if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ case `/usr/bin/file conftest.o` in ++ *64-bit*) ++ case $lt_cv_prog_gnu_ld in ++ yes*) LD="${LD-ld} -m elf64_sparc" ;; ++ *) LD="${LD-ld} -64" ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++ ++esac ++ ++need_locks="$enable_libtool_lock" ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 ++echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 ++# On Suns, sometimes $CPP names a directory. ++if test -n "$CPP" && test -d "$CPP"; then ++ CPP= ++fi ++if test -z "$CPP"; then ++ if test "${ac_cv_prog_CPP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # Double quotes because CPP needs to be expanded ++ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" ++ do ++ ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since ++ # <limits.h> exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include <limits.h> ++#else ++# include <assert.h> ++#endif ++ Syntax error ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether non-existent headers ++ # can be detected and how. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <ac_nonexistent.h> ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ # Broken: success on invalid input. ++continue ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then ++ break ++fi ++ ++ done ++ ac_cv_prog_CPP=$CPP ++ ++fi ++ CPP=$ac_cv_prog_CPP ++else ++ ac_cv_prog_CPP=$CPP ++fi ++echo "$as_me:$LINENO: result: $CPP" >&5 ++echo "${ECHO_T}$CPP" >&6 ++ac_preproc_ok=false ++for ac_c_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since ++ # <limits.h> exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include <limits.h> ++#else ++# include <assert.h> ++#endif ++ Syntax error ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether non-existent headers ++ # can be detected and how. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <ac_nonexistent.h> ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ # Broken: success on invalid input. ++continue ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then ++ : ++else ++ { { echo "$as_me:$LINENO: error: C preprocessor "$CPP" fails sanity check ++See `config.log' for more details." >&5 ++echo "$as_me: error: C preprocessor "$CPP" fails sanity check ++See `config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++echo "$as_me:$LINENO: checking for ANSI C header files" >&5 ++echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 ++if test "${ac_cv_header_stdc+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <stdlib.h> ++#include <stdarg.h> ++#include <string.h> ++#include <float.h> ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_header_stdc=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_header_stdc=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ ++if test $ac_cv_header_stdc = yes; then ++ # SunOS 4.x string.h does not declare mem*, contrary to ANSI. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <string.h> ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "memchr" >/dev/null 2>&1; then ++ : ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <stdlib.h> ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "free" >/dev/null 2>&1; then ++ : ++else ++ ac_cv_header_stdc=no ++fi ++rm -f conftest* ++ ++fi ++ ++if test $ac_cv_header_stdc = yes; then ++ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. ++ if test "$cross_compiling" = yes; then ++ : ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <ctype.h> ++#if ((' ' & 0x0FF) == 0x020) ++# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') ++# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) ++#else ++# define ISLOWER(c) \ ++ (('a' <= (c) && (c) <= 'i') \ ++ || ('j' <= (c) && (c) <= 'r') \ ++ || ('s' <= (c) && (c) <= 'z')) ++# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) ++#endif ++ ++#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) ++int ++main () ++{ ++ int i; ++ for (i = 0; i < 256; i++) ++ if (XOR (islower (i), ISLOWER (i)) ++ || toupper (i) != TOUPPER (i)) ++ exit(2); ++ exit (0); ++} ++_ACEOF ++rm -f conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ : ++else ++ echo "$as_me: program exited with status $ac_status" >&5 ++echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++( exit $ac_status ) ++ac_cv_header_stdc=no ++fi ++rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext ++fi ++fi ++fi ++echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 ++echo "${ECHO_T}$ac_cv_header_stdc" >&6 ++if test $ac_cv_header_stdc = yes; then ++ ++cat >>confdefs.h <<_ACEOF ++#define STDC_HEADERS 1 ++_ACEOF ++ ++fi ++ ++# On IRIX 5.3, sys/types and inttypes.h are conflicting. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ ++ inttypes.h stdint.h unistd.h ++do ++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` ++echo "$as_me:$LINENO: checking for $ac_header" >&5 ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 ++if eval "test "${$as_ac_Header+set}" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++ ++#include <$ac_header> ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ eval "$as_ac_Header=yes" ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++eval "$as_ac_Header=no" ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 ++if test `eval echo '${'$as_ac_Header'}'` = yes; then ++ cat >>confdefs.h <<_ACEOF ++#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ ++ ++for ac_header in dlfcn.h ++do ++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` ++if eval "test "${$as_ac_Header+set}" = set"; then ++ echo "$as_me:$LINENO: checking for $ac_header" >&5 ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 ++if eval "test "${$as_ac_Header+set}" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++fi ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 ++else ++ # Is the header compilable? ++echo "$as_me:$LINENO: checking $ac_header usability" >&5 ++echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++#include <$ac_header> ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_header_compiler=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_header_compiler=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 ++echo "${ECHO_T}$ac_header_compiler" >&6 ++ ++# Is the header present? ++echo "$as_me:$LINENO: checking $ac_header presence" >&5 ++echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <$ac_header> ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ ac_header_preproc=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_header_preproc=no ++fi ++rm -f conftest.err conftest.$ac_ext ++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 ++echo "${ECHO_T}$ac_header_preproc" >&6 ++ ++# So? What about this header? ++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in ++ yes:no: ) ++ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 ++echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 ++echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ++ ac_header_preproc=yes ++ ;; ++ no:yes:* ) ++ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 ++echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 ++echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 ++echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: section "Present But Cannot Be Compiled"" >&5 ++echo "$as_me: WARNING: $ac_header: section "Present But Cannot Be Compiled"" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 ++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 ++echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ++ ( ++ cat <<_ASBOX ++## ------------------------------------------- ## ++## Report this to the Autotoolized Lua lists. ## ++## ------------------------------------------- ## ++_ASBOX ++ ) | ++ sed "s/^/$as_me: WARNING: /" >&2 ++ ;; ++esac ++echo "$as_me:$LINENO: checking for $ac_header" >&5 ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 ++if eval "test "${$as_ac_Header+set}" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ eval "$as_ac_Header=$ac_header_preproc" ++fi ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 ++ ++fi ++if test `eval echo '${'$as_ac_Header'}'` = yes; then ++ cat >>confdefs.h <<_ACEOF ++#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++ ++done ++ ++ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++if test -n "$ac_tool_prefix"; then ++ for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$CXX"; then ++ ac_cv_prog_CXX="$CXX" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++CXX=$ac_cv_prog_CXX ++if test -n "$CXX"; then ++ echo "$as_me:$LINENO: result: $CXX" >&5 ++echo "${ECHO_T}$CXX" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$CXX" && break ++ done ++fi ++if test -z "$CXX"; then ++ ac_ct_CXX=$CXX ++ for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_CXX"; then ++ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_CXX="$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_CXX=$ac_cv_prog_ac_ct_CXX ++if test -n "$ac_ct_CXX"; then ++ echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 ++echo "${ECHO_T}$ac_ct_CXX" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$ac_ct_CXX" && break ++done ++test -n "$ac_ct_CXX" || ac_ct_CXX="g++" ++ ++ CXX=$ac_ct_CXX ++fi ++ ++ ++# Provide some information about the compiler. ++echo "$as_me:$LINENO:" \ ++ "checking for C++ compiler version" >&5 ++ac_compiler=`set X $ac_compile; echo $2` ++{ (eval echo "$as_me:$LINENO: "$ac_compiler --version </dev/null >&5"") >&5 ++ (eval $ac_compiler --version </dev/null >&5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: "$ac_compiler -v </dev/null >&5"") >&5 ++ (eval $ac_compiler -v </dev/null >&5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: "$ac_compiler -V </dev/null >&5"") >&5 ++ (eval $ac_compiler -V </dev/null >&5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++ ++echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 ++echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 ++if test "${ac_cv_cxx_compiler_gnu+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++#ifndef __GNUC__ ++ choke me ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_compiler_gnu=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_compiler_gnu=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_cv_cxx_compiler_gnu=$ac_compiler_gnu ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 ++echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 ++GXX=`test $ac_compiler_gnu = yes && echo yes` ++ac_test_CXXFLAGS=${CXXFLAGS+set} ++ac_save_CXXFLAGS=$CXXFLAGS ++CXXFLAGS="-g" ++echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 ++echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 ++if test "${ac_cv_prog_cxx_g+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_prog_cxx_g=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_prog_cxx_g=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 ++echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 ++if test "$ac_test_CXXFLAGS" = set; then ++ CXXFLAGS=$ac_save_CXXFLAGS ++elif test $ac_cv_prog_cxx_g = yes; then ++ if test "$GXX" = yes; then ++ CXXFLAGS="-g -O2" ++ else ++ CXXFLAGS="-g" ++ fi ++else ++ if test "$GXX" = yes; then ++ CXXFLAGS="-O2" ++ else ++ CXXFLAGS= ++ fi ++fi ++for ac_declaration in \ ++ '' \ ++ 'extern "C" void std::exit (int) throw (); using std::exit;' \ ++ 'extern "C" void std::exit (int); using std::exit;' \ ++ 'extern "C" void exit (int) throw ();' \ ++ 'extern "C" void exit (int);' \ ++ 'void exit (int);' ++do ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_declaration ++#include <stdlib.h> ++int ++main () ++{ ++exit (42); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++continue ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_declaration ++int ++main () ++{ ++exit (42); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ break ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++done ++rm -f conftest* ++if test -n "$ac_declaration"; then ++ echo '#ifdef __cplusplus' >>confdefs.h ++ echo $ac_declaration >>confdefs.h ++ echo '#endif' >>confdefs.h ++fi ++ ++ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++depcc="$CXX" am_compiler_list= ++ ++echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 ++echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 ++if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then ++ # We make a subdir and do the tests there. Otherwise we can end up ++ # making bogus files that we don't know about and never remove. For ++ # instance it was reported that on HP-UX the gcc test will end up ++ # making a dummy file named `D' -- because `-MD' means `put the output ++ # in D'. ++ mkdir conftest.dir ++ # Copy depcomp to subdir because otherwise we won't find it if we're ++ # using a relative directory. ++ cp "$am_depcomp" conftest.dir ++ cd conftest.dir ++ # We will build objects and dependencies in a subdirectory because ++ # it helps to detect inapplicable dependency modes. For instance ++ # both Tru64's cc and ICC support -MD to output dependencies as a ++ # side effect of compilation, but ICC will put the dependencies in ++ # the current directory while Tru64 will put them in the object ++ # directory. ++ mkdir sub ++ ++ am_cv_CXX_dependencies_compiler_type=none ++ if test "$am_compiler_list" = ""; then ++ am_compiler_list=`sed -n 's/^#*([a-zA-Z0-9]*))$/\1/p' < ./depcomp` ++ fi ++ for depmode in $am_compiler_list; do ++ # Setup a source with many dependencies, because some compilers ++ # like to wrap large dependency lists on column 80 (with ), and ++ # we should not choose a depcomp mode which is confused by this. ++ # ++ # We need to recreate these files for each test, as the compiler may ++ # overwrite some of them when testing with obscure command lines. ++ # This happens at least with the AIX C compiler. ++ : > sub/conftest.c ++ for i in 1 2 3 4 5 6; do ++ echo '#include "conftst'$i'.h"' >> sub/conftest.c ++ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with ++ # Solaris 8's {/usr,}/bin/sh. ++ touch sub/conftst$i.h ++ done ++ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf ++ ++ case $depmode in ++ nosideeffect) ++ # after this tag, mechanisms are not by side-effect, so they'll ++ # only be used when explicitly requested ++ if test "x$enable_dependency_tracking" = xyes; then ++ continue ++ else ++ break ++ fi ++ ;; ++ none) break ;; ++ esac ++ # We check with `-c' and `-o' for the sake of the "dashmstdout" ++ # mode. It turns out that the SunPro C++ compiler does not properly ++ # handle `-M -o', and we need to detect this. ++ if depmode=$depmode \ ++ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ ++ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ ++ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ ++ >/dev/null 2>conftest.err && ++ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && ++ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then ++ # icc doesn't choke on unknown options, it will just issue warnings ++ # or remarks (even with -Werror). So we grep stderr for any message ++ # that says an option was ignored or not supported. ++ # When given -MP, icc 7.0 and 7.1 complain thusly: ++ # icc: Command line warning: ignoring option '-M'; no argument required ++ # The diagnosis changed in icc 8.0: ++ # icc: Command line remark: option '-MP' not supported ++ if (grep 'ignoring option' conftest.err || ++ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else ++ am_cv_CXX_dependencies_compiler_type=$depmode ++ break ++ fi ++ fi ++ done ++ ++ cd .. ++ rm -rf conftest.dir ++else ++ am_cv_CXX_dependencies_compiler_type=none ++fi ++ ++fi ++echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 ++echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 ++CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type ++ ++ ++ ++if ++ test "x$enable_dependency_tracking" != xno \ ++ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then ++ am__fastdepCXX_TRUE= ++ am__fastdepCXX_FALSE='#' ++else ++ am__fastdepCXX_TRUE='#' ++ am__fastdepCXX_FALSE= ++fi ++ ++ ++ ++ ++if test -n "$CXX" && ( test "X$CXX" != "Xno" && ++ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || ++ (test "X$CXX" != "Xg++"))) ; then ++ ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 ++echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 ++if test -z "$CXXCPP"; then ++ if test "${ac_cv_prog_CXXCPP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # Double quotes because CXXCPP needs to be expanded ++ for CXXCPP in "$CXX -E" "/lib/cpp" ++ do ++ ac_preproc_ok=false ++for ac_cxx_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since ++ # <limits.h> exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include <limits.h> ++#else ++# include <assert.h> ++#endif ++ Syntax error ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_cxx_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether non-existent headers ++ # can be detected and how. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <ac_nonexistent.h> ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_cxx_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ # Broken: success on invalid input. ++continue ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then ++ break ++fi ++ ++ done ++ ac_cv_prog_CXXCPP=$CXXCPP ++ ++fi ++ CXXCPP=$ac_cv_prog_CXXCPP ++else ++ ac_cv_prog_CXXCPP=$CXXCPP ++fi ++echo "$as_me:$LINENO: result: $CXXCPP" >&5 ++echo "${ECHO_T}$CXXCPP" >&6 ++ac_preproc_ok=false ++for ac_cxx_preproc_warn_flag in '' yes ++do ++ # Use a header file that comes with gcc, so configuring glibc ++ # with a fresh cross-compiler works. ++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since ++ # <limits.h> exists even on freestanding compilers. ++ # On the NeXT, cc -E runs the code through the compiler's parser, ++ # not just through cpp. "Syntax error" is here to catch this case. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#ifdef __STDC__ ++# include <limits.h> ++#else ++# include <assert.h> ++#endif ++ Syntax error ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_cxx_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ : ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Broken: fails on valid input. ++continue ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++ # OK, works on sane cases. Now check whether non-existent headers ++ # can be detected and how. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <ac_nonexistent.h> ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_cxx_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ # Broken: success on invalid input. ++continue ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ # Passes both tests. ++ac_preproc_ok=: ++break ++fi ++rm -f conftest.err conftest.$ac_ext ++ ++done ++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. ++rm -f conftest.err conftest.$ac_ext ++if $ac_preproc_ok; then ++ : ++else ++ { { echo "$as_me:$LINENO: error: C++ preprocessor "$CXXCPP" fails sanity check ++See `config.log' for more details." >&5 ++echo "$as_me: error: C++ preprocessor "$CXXCPP" fails sanity check ++See `config.log' for more details." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++fi ++ ++ ++ac_ext=f ++ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ++ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_f77_compiler_gnu ++if test -n "$ac_tool_prefix"; then ++ for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran ++ do ++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. ++set dummy $ac_tool_prefix$ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$F77"; then ++ ac_cv_prog_F77="$F77" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_F77="$ac_tool_prefix$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++F77=$ac_cv_prog_F77 ++if test -n "$F77"; then ++ echo "$as_me:$LINENO: result: $F77" >&5 ++echo "${ECHO_T}$F77" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$F77" && break ++ done ++fi ++if test -z "$F77"; then ++ ac_ct_F77=$F77 ++ for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran ++do ++ # Extract the first word of "$ac_prog", so it can be a program name with args. ++set dummy $ac_prog; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_F77"; then ++ ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_F77="$ac_prog" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++ac_ct_F77=$ac_cv_prog_ac_ct_F77 ++if test -n "$ac_ct_F77"; then ++ echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 ++echo "${ECHO_T}$ac_ct_F77" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ test -n "$ac_ct_F77" && break ++done ++ ++ F77=$ac_ct_F77 ++fi ++ ++ ++# Provide some information about the compiler. ++echo "$as_me:5276:" \ ++ "checking for Fortran 77 compiler version" >&5 ++ac_compiler=`set X $ac_compile; echo $2` ++{ (eval echo "$as_me:$LINENO: "$ac_compiler --version </dev/null >&5"") >&5 ++ (eval $ac_compiler --version </dev/null >&5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: "$ac_compiler -v </dev/null >&5"") >&5 ++ (eval $ac_compiler -v </dev/null >&5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++{ (eval echo "$as_me:$LINENO: "$ac_compiler -V </dev/null >&5"") >&5 ++ (eval $ac_compiler -V </dev/null >&5) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++rm -f a.out ++ ++# If we don't use `.F' as extension, the preprocessor is not run on the ++# input file. (Note that this only needs to work for GNU compilers.) ++ac_save_ext=$ac_ext ++ac_ext=F ++echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 ++echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6 ++if test "${ac_cv_f77_compiler_gnu+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++ program main ++#ifndef __GNUC__ ++ choke me ++#endif ++ ++ end ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_f77_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_compiler_gnu=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_compiler_gnu=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_cv_f77_compiler_gnu=$ac_compiler_gnu ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 ++echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 ++ac_ext=$ac_save_ext ++ac_test_FFLAGS=${FFLAGS+set} ++ac_save_FFLAGS=$FFLAGS ++FFLAGS= ++echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 ++echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6 ++if test "${ac_cv_prog_f77_g+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ FFLAGS=-g ++cat >conftest.$ac_ext <<_ACEOF ++ program main ++ ++ end ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_f77_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_prog_f77_g=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_prog_f77_g=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++ ++fi ++echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 ++echo "${ECHO_T}$ac_cv_prog_f77_g" >&6 ++if test "$ac_test_FFLAGS" = set; then ++ FFLAGS=$ac_save_FFLAGS ++elif test $ac_cv_prog_f77_g = yes; then ++ if test "x$ac_cv_f77_compiler_gnu" = xyes; then ++ FFLAGS="-g -O2" ++ else ++ FFLAGS="-g" ++ fi ++else ++ if test "x$ac_cv_f77_compiler_gnu" = xyes; then ++ FFLAGS="-O2" ++ else ++ FFLAGS= ++ fi ++fi ++ ++G77=`test $ac_compiler_gnu = yes && echo yes` ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++ ++# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! ++ ++# find the maximum length of command line arguments ++echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 ++echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6 ++if test "${lt_cv_sys_max_cmd_len+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ i=0 ++ teststring="ABCD" ++ ++ case $build_os in ++ msdosdjgpp*) ++ # On DJGPP, this test can blow up pretty badly due to problems in libc ++ # (any single argument exceeding 2000 bytes causes a buffer overrun ++ # during glob expansion). Even if it were fixed, the result of this ++ # check would be larger than it should be. ++ lt_cv_sys_max_cmd_len=12288; # 12K is about right ++ ;; ++ ++ gnu*) ++ # Under GNU Hurd, this test is not required because there is ++ # no limit to the length of command line arguments. ++ # Libtool will interpret -1 as no limit whatsoever ++ lt_cv_sys_max_cmd_len=-1; ++ ;; ++ ++ cygwin* | mingw*) ++ # On Win9x/ME, this test blows up -- it succeeds, but takes ++ # about 5 minutes as the teststring grows exponentially. ++ # Worse, since 9x/ME are not pre-emptively multitasking, ++ # you end up with a "frozen" computer, even though with patience ++ # the test eventually succeeds (with a max line length of 256k). ++ # Instead, let's just punt: use the minimum linelength reported by ++ # all of the supported platforms: 8192 (on NT/2K/XP). ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ amigaos*) ++ # On AmigaOS with pdksh, this test takes hours, literally. ++ # So we just punt and use a minimum line length of 8192. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) ++ # This has been around since 386BSD, at least. Likely further. ++ if test -x /sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` ++ elif test -x /usr/sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` ++ else ++ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs ++ fi ++ # And add a safety zone ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len / 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len * 3` ++ ;; ++ ++ interix*) ++ # We know the value 262144 and hardcode it with a safety zone (like BSD) ++ lt_cv_sys_max_cmd_len=196608 ++ ;; ++ ++ osf*) ++ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure ++ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not ++ # nice to cause kernel panics so lets avoid the loop below. ++ # First set a reasonable default. ++ lt_cv_sys_max_cmd_len=16384 ++ # ++ if test -x /sbin/sysconfig; then ++ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in ++ *1*) lt_cv_sys_max_cmd_len=-1 ;; ++ esac ++ fi ++ ;; ++ sco3.2v5*) ++ lt_cv_sys_max_cmd_len=102400 ++ ;; ++ sysv5* | sco5v6* | sysv4.2uw2*) ++ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` ++ if test -n "$kargmax"; then ++ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` ++ else ++ lt_cv_sys_max_cmd_len=32768 ++ fi ++ ;; ++ *) ++ # If test is not a shell built-in, we'll probably end up computing a ++ # maximum length that is only half of the actual maximum length, but ++ # we can't tell. ++ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} ++ while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ ++ = "XX$teststring") >/dev/null 2>&1 && ++ new_result=`expr "X$teststring" : ".*" 2>&1` && ++ lt_cv_sys_max_cmd_len=$new_result && ++ test $i != 17 # 1/2 MB should be enough ++ do ++ i=`expr $i + 1` ++ teststring=$teststring$teststring ++ done ++ teststring= ++ # Add a significant safety factor because C++ compilers can tack on massive ++ # amounts of additional arguments before passing them to the linker. ++ # It appears as though 1/2 is a usable value. ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len / 2` ++ ;; ++ esac ++ ++fi ++ ++if test -n $lt_cv_sys_max_cmd_len ; then ++ echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 ++echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6 ++else ++ echo "$as_me:$LINENO: result: none" >&5 ++echo "${ECHO_T}none" >&6 ++fi ++ ++ ++ ++ ++# Check for command to grab the raw symbol name followed by C symbol from nm. ++echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 ++echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6 ++if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ++# These are sane defaults that work on at least a few old systems. ++# [They come from Ultrix. What could be older than Ultrix?!! ;)] ++ ++# Character class describing NM global symbol codes. ++symcode='[BCDEGRST]' ++ ++# Regexp to match symbols that can be accessed directly from C. ++sympat='([_A-Za-z][_A-Za-z0-9]*)' ++ ++# Transform an extracted symbol line into a proper C declaration ++lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* (.*)$/extern int \1;/p'" ++ ++# Transform an extracted symbol line into symbol name and symbol address ++lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: ([^ ]*) $/ {\"\1\", (lt_ptr) 0},/p' -e 's/^$symcode ([^ ]*) ([^ ]*)$/ {"\2", (lt_ptr) &\2},/p'" ++ ++# Define system-specific variables. ++case $host_os in ++aix*) ++ symcode='[BCDT]' ++ ;; ++cygwin* | mingw* | pw32*) ++ symcode='[ABCDGISTW]' ++ ;; ++hpux*) # Its linker distinguishes data from code symbols ++ if test "$host_cpu" = ia64; then ++ symcode='[ABCDEGRST]' ++ fi ++ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* (.*)$/extern int \1();/p' -e 's/^$symcode* .* (.*)$/extern char \1;/p'" ++ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: ([^ ]*) $/ {\"\1\", (lt_ptr) 0},/p' -e 's/^$symcode* ([^ ]*) ([^ ]*)$/ {"\2", (lt_ptr) &\2},/p'" ++ ;; ++linux*) ++ if test "$host_cpu" = ia64; then ++ symcode='[ABCDGIRSTW]' ++ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* (.*)$/extern int \1();/p' -e 's/^$symcode* .* (.*)$/extern char \1;/p'" ++ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: ([^ ]*) $/ {\"\1\", (lt_ptr) 0},/p' -e 's/^$symcode* ([^ ]*) ([^ ]*)$/ {"\2", (lt_ptr) &\2},/p'" ++ fi ++ ;; ++irix* | nonstopux*) ++ symcode='[BCDEGRST]' ++ ;; ++osf*) ++ symcode='[BCDEGQRST]' ++ ;; ++solaris*) ++ symcode='[BDRT]' ++ ;; ++sco3.2v5*) ++ symcode='[DT]' ++ ;; ++sysv4.2uw2*) ++ symcode='[DT]' ++ ;; ++sysv5* | sco5v6* | unixware* | OpenUNIX*) ++ symcode='[ABDT]' ++ ;; ++sysv4) ++ symcode='[DFNSTU]' ++ ;; ++esac ++ ++# Handle CRLF in mingw tool chain ++opt_cr= ++case $build_os in ++mingw*) ++ opt_cr=`echo 'x{0,1}' | tr x '\015'` # option cr in regexp ++ ;; ++esac ++ ++# If we're using GNU nm, then use its standard symbol codes. ++case `$NM -V 2>&1` in ++*GNU* | *'with BFD'*) ++ symcode='[ABCDGIRSTW]' ;; ++esac ++ ++# Try without a prefix undercore, then with it. ++for ac_symprfx in "" "_"; do ++ ++ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. ++ symxfrm="\1 $ac_symprfx\2 \2" ++ ++ # Write the raw and C identifiers. ++ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]($symcode$symcode*)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" ++ ++ # Check to see that the pipe works correctly. ++ pipe_works=no ++ ++ rm -f conftest* ++ cat > conftest.$ac_ext <<EOF ++#ifdef __cplusplus ++extern "C" { ++#endif ++char nm_test_var; ++void nm_test_func(){} ++#ifdef __cplusplus ++} ++#endif ++int main(){nm_test_var='a';nm_test_func();return(0);} ++EOF ++ ++ if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ # Now try to grab the symbols. ++ nlist=conftest.nm ++ if { (eval echo "$as_me:$LINENO: "$NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist"") >&5 ++ (eval $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && test -s "$nlist"; then ++ # Try sorting and uniquifying the output. ++ if sort "$nlist" | uniq > "$nlist"T; then ++ mv -f "$nlist"T "$nlist" ++ else ++ rm -f "$nlist"T ++ fi ++ ++ # Make sure that we snagged all the symbols we need. ++ if grep ' nm_test_var$' "$nlist" >/dev/null; then ++ if grep ' nm_test_func$' "$nlist" >/dev/null; then ++ cat <<EOF > conftest.$ac_ext ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++EOF ++ # Now generate the symbol file. ++ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' ++ ++ cat <<EOF >> conftest.$ac_ext ++#if defined (__STDC__) && __STDC__ ++# define lt_ptr_t void * ++#else ++# define lt_ptr_t char * ++# define const ++#endif ++ ++/* The mapping between symbol names and symbols. */ ++const struct { ++ const char *name; ++ lt_ptr_t address; ++} ++lt_preloaded_symbols[] = ++{ ++EOF ++ $SED "s/^$symcode$symcode* (.*) (.*)$/ {"\2", (lt_ptr_t) &\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext ++ cat <<\EOF >> conftest.$ac_ext ++ {0, (lt_ptr_t) 0} ++}; ++ ++#ifdef __cplusplus ++} ++#endif ++EOF ++ # Now try linking the two files. ++ mv conftest.$ac_objext conftstm.$ac_objext ++ lt_save_LIBS="$LIBS" ++ lt_save_CFLAGS="$CFLAGS" ++ LIBS="conftstm.$ac_objext" ++ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" ++ if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && test -s conftest${ac_exeext}; then ++ pipe_works=yes ++ fi ++ LIBS="$lt_save_LIBS" ++ CFLAGS="$lt_save_CFLAGS" ++ else ++ echo "cannot find nm_test_func in $nlist" >&5 ++ fi ++ else ++ echo "cannot find nm_test_var in $nlist" >&5 ++ fi ++ else ++ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 ++ fi ++ else ++ echo "$progname: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++ fi ++ rm -f conftest* conftst* ++ ++ # Do not use the global_symbol_pipe unless it works. ++ if test "$pipe_works" = yes; then ++ break ++ else ++ lt_cv_sys_global_symbol_pipe= ++ fi ++done ++ ++fi ++ ++if test -z "$lt_cv_sys_global_symbol_pipe"; then ++ lt_cv_sys_global_symbol_to_cdecl= ++fi ++if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then ++ echo "$as_me:$LINENO: result: failed" >&5 ++echo "${ECHO_T}failed" >&6 ++else ++ echo "$as_me:$LINENO: result: ok" >&5 ++echo "${ECHO_T}ok" >&6 ++fi ++ ++echo "$as_me:$LINENO: checking for objdir" >&5 ++echo $ECHO_N "checking for objdir... $ECHO_C" >&6 ++if test "${lt_cv_objdir+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ rm -f .libs 2>/dev/null ++mkdir .libs 2>/dev/null ++if test -d .libs; then ++ lt_cv_objdir=.libs ++else ++ # MS-DOS does not allow filenames that begin with a dot. ++ lt_cv_objdir=_libs ++fi ++rmdir .libs 2>/dev/null ++fi ++echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 ++echo "${ECHO_T}$lt_cv_objdir" >&6 ++objdir=$lt_cv_objdir ++ ++ ++ ++ ++ ++case $host_os in ++aix3*) ++ # AIX sometimes has problems with the GCC collect2 program. For some ++ # reason, if we set the COLLECT_NAMES environment variable, the problems ++ # vanish in a puff of smoke. ++ if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++ fi ++ ;; ++esac ++ ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++Xsed='sed -e 1s/^X//' ++sed_quote_subst='s/([\"\`$\\])/\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/([\"\`\\])/\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\$/\\\$/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/*/\*/g' ++ ++# Constants: ++rm="rm -f" ++ ++# Global variables: ++default_ofile=libtool ++can_build_shared=yes ++ ++# All known linkers require a `.a' archive for static linking (except MSVC, ++# which needs '.lib'). ++libext=a ++ltmain="$ac_aux_dir/ltmain.sh" ++ofile="$default_ofile" ++with_gnu_ld="$lt_cv_prog_gnu_ld" ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ar; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_AR+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$AR"; then ++ ac_cv_prog_AR="$AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_AR="${ac_tool_prefix}ar" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++AR=$ac_cv_prog_AR ++if test -n "$AR"; then ++ echo "$as_me:$LINENO: result: $AR" >&5 ++echo "${ECHO_T}$AR" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_AR"; then ++ ac_ct_AR=$AR ++ # Extract the first word of "ar", so it can be a program name with args. ++set dummy ar; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_AR+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_AR"; then ++ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_AR="ar" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false" ++fi ++fi ++ac_ct_AR=$ac_cv_prog_ac_ct_AR ++if test -n "$ac_ct_AR"; then ++ echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 ++echo "${ECHO_T}$ac_ct_AR" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ AR=$ac_ct_AR ++else ++ AR="$ac_cv_prog_AR" ++fi ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. ++set dummy ${ac_tool_prefix}ranlib; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_RANLIB+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$RANLIB"; then ++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++RANLIB=$ac_cv_prog_RANLIB ++if test -n "$RANLIB"; then ++ echo "$as_me:$LINENO: result: $RANLIB" >&5 ++echo "${ECHO_T}$RANLIB" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_RANLIB"; then ++ ac_ct_RANLIB=$RANLIB ++ # Extract the first word of "ranlib", so it can be a program name with args. ++set dummy ranlib; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_RANLIB"; then ++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_RANLIB="ranlib" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" ++fi ++fi ++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB ++if test -n "$ac_ct_RANLIB"; then ++ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 ++echo "${ECHO_T}$ac_ct_RANLIB" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ RANLIB=$ac_ct_RANLIB ++else ++ RANLIB="$ac_cv_prog_RANLIB" ++fi ++ ++if test -n "$ac_tool_prefix"; then ++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. ++set dummy ${ac_tool_prefix}strip; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_STRIP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$STRIP"; then ++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_STRIP="${ac_tool_prefix}strip" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++fi ++fi ++STRIP=$ac_cv_prog_STRIP ++if test -n "$STRIP"; then ++ echo "$as_me:$LINENO: result: $STRIP" >&5 ++echo "${ECHO_T}$STRIP" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++fi ++if test -z "$ac_cv_prog_STRIP"; then ++ ac_ct_STRIP=$STRIP ++ # Extract the first word of "strip", so it can be a program name with args. ++set dummy strip; ac_word=$2 ++echo "$as_me:$LINENO: checking for $ac_word" >&5 ++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 ++if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -n "$ac_ct_STRIP"; then ++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. ++else ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ++ ac_cv_prog_ac_ct_STRIP="strip" ++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 ++ break 2 ++ fi ++done ++done ++ ++ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" ++fi ++fi ++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP ++if test -n "$ac_ct_STRIP"; then ++ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 ++echo "${ECHO_T}$ac_ct_STRIP" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ STRIP=$ac_ct_STRIP ++else ++ STRIP="$ac_cv_prog_STRIP" ++fi ++ ++ ++old_CC="$CC" ++old_CFLAGS="$CFLAGS" ++ ++# Set sane defaults for various variables ++test -z "$AR" && AR=ar ++test -z "$AR_FLAGS" && AR_FLAGS=cru ++test -z "$AS" && AS=as ++test -z "$CC" && CC=cc ++test -z "$LTCC" && LTCC=$CC ++test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS ++test -z "$DLLTOOL" && DLLTOOL=dlltool ++test -z "$LD" && LD=ld ++test -z "$LN_S" && LN_S="ln -s" ++test -z "$MAGIC_CMD" && MAGIC_CMD=file ++test -z "$NM" && NM=nm ++test -z "$SED" && SED=sed ++test -z "$OBJDUMP" && OBJDUMP=objdump ++test -z "$RANLIB" && RANLIB=: ++test -z "$STRIP" && STRIP=: ++test -z "$ac_objext" && ac_objext=o ++ ++# Determine commands to create old-style static archives. ++old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' ++old_postinstall_cmds='chmod 644 $oldlib' ++old_postuninstall_cmds= ++ ++if test -n "$RANLIB"; then ++ case $host_os in ++ openbsd*) ++ old_postinstall_cmds="$old_postinstall_cmds~$RANLIB -t $oldlib" ++ ;; ++ *) ++ old_postinstall_cmds="$old_postinstall_cmds~$RANLIB $oldlib" ++ ;; ++ esac ++ old_archive_cmds="$old_archive_cmds~$RANLIB $oldlib" ++fi ++ ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\/]compile | ccache | *[\/]ccache ) ;; ++ distcc | *[\/]distcc | purify | *[\/]purify ) ;; ++ -*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ ++# Only perform the check for file, if the check method requires it ++case $deplibs_check_method in ++file_magic*) ++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then ++ echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 ++echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 ++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $MAGIC_CMD in ++[\/*] | ?:[\/]*) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/${ac_tool_prefix}file; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic (.*)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd $file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <<EOF 1>&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac ++fi ++ ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 ++echo "${ECHO_T}$MAGIC_CMD" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++if test -z "$lt_cv_path_MAGIC_CMD"; then ++ if test -n "$ac_tool_prefix"; then ++ echo "$as_me:$LINENO: checking for file" >&5 ++echo $ECHO_N "checking for file... $ECHO_C" >&6 ++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ case $MAGIC_CMD in ++[\/*] | ?:[\/]*) ++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD="$MAGIC_CMD" ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" ++ for ac_dir in $ac_dummy; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f $ac_dir/file; then ++ lt_cv_path_MAGIC_CMD="$ac_dir/file" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic (.*)"` ++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++ if eval $file_magic_cmd $file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <<EOF 1>&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS="$lt_save_ifs" ++ MAGIC_CMD="$lt_save_MAGIC_CMD" ++ ;; ++esac ++fi ++ ++MAGIC_CMD="$lt_cv_path_MAGIC_CMD" ++if test -n "$MAGIC_CMD"; then ++ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 ++echo "${ECHO_T}$MAGIC_CMD" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ++ else ++ MAGIC_CMD=: ++ fi ++fi ++ ++ fi ++ ;; ++esac ++ ++enable_dlopen=no ++enable_win32_dll=no ++ ++# Check whether --enable-libtool-lock or --disable-libtool-lock was given. ++if test "${enable_libtool_lock+set}" = set; then ++ enableval="$enable_libtool_lock" ++ ++fi; ++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes ++ ++ ++# Check whether --with-pic or --without-pic was given. ++if test "${with_pic+set}" = set; then ++ withval="$with_pic" ++ pic_mode="$withval" ++else ++ pic_mode=default ++fi; ++test -z "$pic_mode" && pic_mode=default ++ ++# Check if we have a version mismatch between libtool.m4 and ltmain.sh. ++# ++# Note: This should be in AC_LIBTOOL_SETUP, _after_ $ltmain have been defined. ++# We also should do it _before_ AC_LIBTOOL_LANG_C_CONFIG that actually ++# calls AC_LIBTOOL_CONFIG and creates libtool. ++# ++echo "$as_me:$LINENO: checking for correct ltmain.sh version" >&5 ++echo $ECHO_N "checking for correct ltmain.sh version... $ECHO_C" >&6 ++if test "x$ltmain" = "x" ; then ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++ { { echo "$as_me:$LINENO: error: ++ ++*** [Gentoo] sanity check failed! *** ++*** $ltmain is not defined, please check the patch for consistency! *** ++" >&5 ++echo "$as_me: error: ++ ++*** [Gentoo] sanity check failed! *** ++*** $ltmain is not defined, please check the patch for consistency! *** ++" >&2;} ++ { (exit 1); exit 1; }; } ++fi ++gentoo_lt_version="1.5.22" ++gentoo_ltmain_version=`sed -n '/^[ ]*VERSION=/{s/^[ ]*VERSION=//;p;q;}' "$ltmain"` ++if test "x$gentoo_lt_version" != "x$gentoo_ltmain_version" ; then ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++ { { echo "$as_me:$LINENO: error: ++ ++*** [Gentoo] sanity check failed! *** ++*** libtool.m4 and ltmain.sh have a version mismatch! *** ++*** (libtool.m4 = $gentoo_lt_version, ltmain.sh = $gentoo_ltmain_version) *** ++ ++Please run: ++ ++ libtoolize --copy --force ++ ++if appropriate, please contact the maintainer of this ++package (or your distribution) for help. ++" >&5 ++echo "$as_me: error: ++ ++*** [Gentoo] sanity check failed! *** ++*** libtool.m4 and ltmain.sh have a version mismatch! *** ++*** (libtool.m4 = $gentoo_lt_version, ltmain.sh = $gentoo_ltmain_version) *** ++ ++Please run: ++ ++ libtoolize --copy --force ++ ++if appropriate, please contact the maintainer of this ++package (or your distribution) for help. ++" >&2;} ++ { (exit 1); exit 1; }; } ++else ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++fi ++ ++ ++# Use C for the default configuration in the libtool script ++tagname= ++lt_save_CC="$CC" ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ ++# Source file extension for C test sources. ++ac_ext=c ++ ++# Object file extension for compiled C test sources. ++objext=o ++objext=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(){return(0);}\n' ++ ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++ ++lt_prog_compiler_no_builtin_flag= ++ ++if test "$GCC" = yes; then ++ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 ++echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_rtti_exceptions=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="-fno-rtti -fno-exceptions" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:6400: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:6404: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_rtti_exceptions=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 ++ ++if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then ++ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" ++else ++ : ++fi ++ ++fi ++ ++lt_prog_compiler_wl= ++lt_prog_compiler_pic= ++lt_prog_compiler_static= ++ ++echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 ++echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ++ ++ if test "$GCC" = yes; then ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_static='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static='-Bstatic' ++ fi ++ ;; ++ ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic='-fno-common' ++ ;; ++ ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ lt_prog_compiler_can_build_shared=no ++ enable_shared=no ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic=-Kconform_pic ++ fi ++ ;; ++ ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ *) ++ lt_prog_compiler_pic='-fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ lt_prog_compiler_wl='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static='-Bstatic' ++ else ++ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ lt_prog_compiler_pic='-qnocommon' ++ lt_prog_compiler_wl='-Wl,' ++ ;; ++ esac ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ lt_prog_compiler_wl='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ lt_prog_compiler_static='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ lt_prog_compiler_wl='-Wl,' ++ # PIC (with -KPIC) is the default. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ newsos6) ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ icc* | ecc*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-fpic' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ccc*) ++ lt_prog_compiler_wl='-Wl,' ++ # All Alpha code is PIC. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ esac ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ lt_prog_compiler_wl='-Wl,' ++ # All OSF/1 code is PIC. ++ lt_prog_compiler_static='-non_shared' ++ ;; ++ ++ solaris*) ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ lt_prog_compiler_wl='-Qoption ld ';; ++ *) ++ lt_prog_compiler_wl='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ lt_prog_compiler_wl='-Qoption ld ' ++ lt_prog_compiler_pic='-PIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ lt_prog_compiler_pic='-Kconform_pic' ++ lt_prog_compiler_static='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_pic='-KPIC' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ unicos*) ++ lt_prog_compiler_wl='-Wl,' ++ lt_prog_compiler_can_build_shared=no ++ ;; ++ ++ uts4*) ++ lt_prog_compiler_pic='-pic' ++ lt_prog_compiler_static='-Bstatic' ++ ;; ++ ++ *) ++ lt_prog_compiler_can_build_shared=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic" >&6 ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic"; then ++ ++echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 ++echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_pic_works+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_pic_works=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:6668: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:6672: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_pic_works=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6 ++ ++if test x"$lt_prog_compiler_pic_works" = xyes; then ++ case $lt_prog_compiler_pic in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; ++ esac ++else ++ lt_prog_compiler_pic= ++ lt_prog_compiler_can_build_shared=no ++fi ++ ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic= ++ ;; ++ *) ++ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl eval lt_tmp_static_flag="$lt_prog_compiler_static" ++echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_static_works+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_static_works=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_static_works=yes ++ fi ++ else ++ lt_prog_compiler_static_works=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 ++echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 ++ ++if test x"$lt_prog_compiler_static_works" = xyes; then ++ : ++else ++ lt_prog_compiler_static= ++fi ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 ++echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_c_o+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_c_o=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:6772: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:6776: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6 ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 ++echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ echo "$as_me:$LINENO: result: $hard_links" >&5 ++echo "${ECHO_T}$hard_links" >&6 ++ if test "$hard_links" = no; then ++ { echo "$as_me:$LINENO: WARNING: `$CC' does not support `-c -o', so `make -j' may be unsafe" >&5 ++echo "$as_me: WARNING: `$CC' does not support `-c -o', so `make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ ++ runpath_var= ++ allow_undefined_flag= ++ enable_shared_with_static_runtimes=no ++ archive_cmds= ++ archive_expsym_cmds= ++ old_archive_From_new_cmds= ++ old_archive_from_expsyms_cmds= ++ export_dynamic_flag_spec= ++ whole_archive_flag_spec= ++ thread_safe_flag_spec= ++ hardcode_libdir_flag_spec= ++ hardcode_libdir_flag_spec_ld= ++ hardcode_libdir_separator= ++ hardcode_direct=no ++ hardcode_minus_L=no ++ hardcode_shlibpath_var=unsupported ++ link_all_deplibs=unknown ++ hardcode_automatic=no ++ module_cmds= ++ module_expsym_cmds= ++ always_export_symbols=no ++ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '''s/.* //''' | sort | uniq > $export_symbols' ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ include_expsyms= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ exclude_expsyms="_GLOBAL_OFFSET_TABLE_" ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ extract_expsyms_cmds= ++ # Just being paranoid about ensuring that cc_basename is set. ++ for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\/]compile | ccache | *[\/]ccache ) ;; ++ distcc | *[\/]distcc | purify | *[\/]purify ) ;; ++ -*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ case $host_os in ++ cygwin* | mingw* | pw32*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ ld_shlibs=yes ++ if test "$with_gnu_ld" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix3* | aix4* | aix5*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ ld_shlibs=no ++ cat <<EOF 1>&2 ++ ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. ++ ++EOF ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ ++ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports ++ # that the semantics of dynamic libraries on AmigaOS, at least up ++ # to version 4, is to share data among multiple programs linked ++ # with the same dynamic library. Since this doesn't match the ++ # behavior of shared libraries on other platforms, we can't use ++ # them. ++ ld_shlibs=no ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag=unsupported ++ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec='-L$libdir' ++ allow_undefined_flag=unsupported ++ always_export_symbols=no ++ enable_shared_with_static_runtimes=yes ++ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '''/^[BCDGRS] /s/.* ([^ ]*)/\1 DATA/''' | $SED -e '''/^[AITW] /s/.* //''' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ interix3*) ++ hardcode_direct=no ++ hardcode_shlibpath_var=no ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ tmp_addflag= ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ esac ++ archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/(.*)/\1;/" >> $output_objdir/$libname.ver~ ++ $echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | grep 'BFD 2.8' > /dev/null; then ++ ld_shlibs=no ++ cat <<EOF 1>&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++EOF ++ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ++ ld_shlibs=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,${SCOABSPATH:+${install_libdir}/}$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ esac ++ ++ if test "$ld_shlibs" = no; then ++ runpath_var= ++ hardcode_libdir_flag_spec= ++ export_dynamic_flag_spec= ++ whole_archive_flag_spec= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ allow_undefined_flag=unsupported ++ always_export_symbols=yes ++ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ hardcode_minus_L=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ hardcode_direct=unsupported ++ fi ++ ;; ++ ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '''{ if ((($2 == "T") || ($2 == "D") || ($2 == "B")) && (substr($3,1,1) != ".")) { print $3 } }''' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '''{ if ((($2 == "T") || ($2 == "D") || ($2 == "B")) && (substr($3,1,1) != ".")) { print $3 } }''' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds='' ++ hardcode_direct=yes ++ hardcode_libdir_separator=':' ++ link_all_deplibs=yes ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ hardcode_direct=yes ++ else ++ # We have old collect2 ++ hardcode_direct=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L=yes ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_libdir_separator= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" ++ archive_expsym_cmds="$CC"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"${wl}$exp_sym_flag:$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag="-z nodefs" ++ archive_expsym_cmds="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"${wl}$exp_sym_flag:$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag=' ${wl}-bernotok' ++ allow_undefined_flag=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec='$convenience' ++ archive_cmds_need_lc=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ # see comment about different semantics on the GNU ld section ++ ld_shlibs=no ++ ;; ++ ++ bsdi[45]*) ++ export_dynamic_flag_spec=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ hardcode_libdir_flag_spec=' ' ++ allow_undefined_flag=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '''s/ -lc$//'''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ old_archive_From_new_cmds='true' ++ # FIXME: Should let the user specify the lib program. ++ old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' ++ fix_srcfile_path='`cygpath -w "$srcfile"`' ++ enable_shared_with_static_runtimes=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ allow_undefined_flag='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[012]) ++ allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ archive_cmds_need_lc=no ++ hardcode_direct=no ++ hardcode_automatic=yes ++ hardcode_shlibpath_var=unsupported ++ whole_archive_flag_spec='' ++ link_all_deplibs=yes ++ if test "$GCC" = yes ; then ++ output_verbose_link_cmd='echo' ++ archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ ld_shlibs=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ freebsd1*) ++ ld_shlibs=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes ++ hardcode_minus_L=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ hardcode_direct=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ++ hardcode_direct=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_libdir_flag_spec_ld='+b $libdir' ++ hardcode_direct=no ++ hardcode_shlibpath_var=no ++ ;; ++ *) ++ hardcode_direct=yes ++ export_dynamic_flag_spec='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_ld='-rpath $libdir' ++ fi ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ link_all_deplibs=yes ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ newsos6) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ hardcode_shlibpath_var=no ++ ;; ++ ++ openbsd*) ++ hardcode_direct=yes ++ hardcode_shlibpath_var=no ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec='${wl}-E' ++ else ++ case $host_os in ++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) ++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-R$libdir' ++ ;; ++ *) ++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ ;; ++ ++ os2*) ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ allow_undefined_flag=unsupported ++ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION "$libname"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ allow_undefined_flag=' -expect_unresolved *' ++ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}*' ++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' ++ else ++ allow_undefined_flag=' -expect_unresolved *' ++ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\n" -exported_symbol "$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ ++ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ hardcode_libdir_flag_spec='-rpath $libdir' ++ fi ++ hardcode_libdir_separator=: ++ ;; ++ ++ solaris*) ++ no_undefined_flag=' -z text' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' ++ else ++ wlarc='' ++ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' ++ fi ++ hardcode_libdir_flag_spec='-R$libdir' ++ hardcode_shlibpath_var=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The compiler driver will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl, iff we do not link with $LD. ++ # Luckily, gcc supports the same syntax we need for Sun Studio. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ case $wlarc in ++ '') ++ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; ++ *) ++ whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}-z ${wl}defaultextract' ;; ++ esac ;; ++ esac ++ link_all_deplibs=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_direct=yes ++ hardcode_minus_L=yes ++ hardcode_shlibpath_var=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ reload_cmds='$CC -r -o $output$reload_objs' ++ hardcode_direct=no ++ ;; ++ motorola) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ sysv4.3*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var=no ++ export_dynamic_flag_spec='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ ld_shlibs=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ++ no_undefined_flag='${wl}-z,text' ++ archive_cmds_need_lc=no ++ hardcode_shlibpath_var=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ no_undefined_flag='${wl}-z,text' ++ allow_undefined_flag='${wl}-z,nodefs' ++ archive_cmds_need_lc=no ++ hardcode_shlibpath_var=no ++ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ hardcode_libdir_separator=':' ++ link_all_deplibs=yes ++ export_dynamic_flag_spec='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds='$CC -shared ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds='$CC -G ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_shlibpath_var=no ++ ;; ++ ++ *) ++ ld_shlibs=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $ld_shlibs" >&5 ++echo "${ECHO_T}$ld_shlibs" >&6 ++test "$ld_shlibs" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 ++echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl ++ pic_flag=$lt_prog_compiler_pic ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag ++ allow_undefined_flag= ++ if { (eval echo "$as_me:$LINENO: "$archive_cmds 2>&1 | grep " -lc " >/dev/null 2>&1"") >&5 ++ (eval $archive_cmds 2>&1 | grep " -lc " >/dev/null 2>&1) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++ then ++ archive_cmds_need_lc=no ++ else ++ archive_cmds_need_lc=yes ++ fi ++ allow_undefined_flag=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 ++echo "${ECHO_T}$archive_cmds_need_lc" >&6 ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 ++echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib<name>.so ++ # instead of lib<name>.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '''s%^.*/([^/]*).ixlibrary$%\1%'''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename ${file}`~ ++ dlpath=`$SHELL 2>&1 -c '''. $dir/'''${base_file}'''i;echo $dlname'''`~ ++ dldir=$destdir/`dirname $dlpath`~ ++ test -d $dldir || mkdir -p $dldir~ ++ $install_prog $dir/$dlname $dldir/$dlname~ ++ chmod a+x $dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '''. $file; echo $dlname'''`~ ++ dlpath=$dir/$dldll~ ++ $rm $dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ ++cat $export_symbols | sed -e "s/(.*)/\1;/" >> $output_objdir/$libname.ver~ ++$echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ else ++ $archive_expsym_cmds="$archive_cmds" ++ fi ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[123]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ # Handle Gentoo/FreeBSD as it was Linux ++ case $host_vendor in ++ gentoo) ++ version_type=linux ;; ++ *) ++ version_type=freebsd-$objformat ;; ++ esac ++ ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ linux) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ need_lib_prefix=no ++ need_version=no ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", $2)); skip = 1; } { if (!skip) print $0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $dynamic_linker" >&5 ++echo "${ECHO_T}$dynamic_linker" >&6 ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 ++echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 ++hardcode_action= ++if test -n "$hardcode_libdir_flag_spec" || \ ++ test -n "$runpath_var" || \ ++ test "X$hardcode_automatic" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$hardcode_direct" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && ++ test "$hardcode_minus_L" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action=unsupported ++fi ++echo "$as_me:$LINENO: result: $hardcode_action" >&5 ++echo "${ECHO_T}$hardcode_action" >&6 ++ ++if test "$hardcode_action" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++striplib= ++old_striplib= ++echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 ++echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 ++if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then ++ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" ++ test -z "$striplib" && striplib="$STRIP --strip-unneeded" ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++else ++# FIXME - insert some real tests, host_os isn't really good enough ++ case $host_os in ++ darwin*) ++ if test -n "$STRIP" ; then ++ striplib="$STRIP -x" ++ echo "$as_me:$LINENO: result: yes" >&5 ++echo "${ECHO_T}yes" >&6 ++ else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++ ;; ++ *) ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++ ;; ++ esac ++fi ++ ++if test "x$enable_dlopen" != xyes; then ++ enable_dlopen=unknown ++ enable_dlopen_self=unknown ++ enable_dlopen_self_static=unknown ++else ++ lt_cv_dlopen=no ++ lt_cv_dlopen_libs= ++ ++ case $host_os in ++ beos*) ++ lt_cv_dlopen="load_add_on" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ;; ++ ++ mingw* | pw32*) ++ lt_cv_dlopen="LoadLibrary" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ cygwin*) ++ lt_cv_dlopen="dlopen" ++ lt_cv_dlopen_libs= ++ ;; ++ ++ darwin*) ++ # if libdl is installed we need to link against it ++ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 ++echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 ++if test "${ac_cv_lib_dl_dlopen+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldl $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dlopen (); ++int ++main () ++{ ++dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_dl_dlopen=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_dl_dlopen=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 ++echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 ++if test $ac_cv_lib_dl_dlopen = yes; then ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" ++else ++ ++ lt_cv_dlopen="dyld" ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ++fi ++ ++ ;; ++ ++ *) ++ echo "$as_me:$LINENO: checking for shl_load" >&5 ++echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 ++if test "${ac_cv_func_shl_load+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load. ++ For example, HP-UX 11i <limits.h> declares gettimeofday. */ ++#define shl_load innocuous_shl_load ++ ++/* System header to define __stub macros and hopefully few prototypes, ++ which can conflict with char shl_load (); below. ++ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since ++ <limits.h> exists even on freestanding compilers. */ ++ ++#ifdef __STDC__ ++# include <limits.h> ++#else ++# include <assert.h> ++#endif ++ ++#undef shl_load ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char shl_load (); ++/* The GNU C library defines this for functions which it implements ++ to always fail with ENOSYS. Some functions are actually named ++ something starting with __ and the normal name is an alias. */ ++#if defined (__stub_shl_load) || defined (__stub___shl_load) ++choke me ++#else ++char (*f) () = shl_load; ++#endif ++#ifdef __cplusplus ++} ++#endif ++ ++int ++main () ++{ ++return f != shl_load; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_func_shl_load=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_func_shl_load=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 ++echo "${ECHO_T}$ac_cv_func_shl_load" >&6 ++if test $ac_cv_func_shl_load = yes; then ++ lt_cv_dlopen="shl_load" ++else ++ echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 ++echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 ++if test "${ac_cv_lib_dld_shl_load+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldld $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char shl_load (); ++int ++main () ++{ ++shl_load (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_dld_shl_load=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_dld_shl_load=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 ++echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 ++if test $ac_cv_lib_dld_shl_load = yes; then ++ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" ++else ++ echo "$as_me:$LINENO: checking for dlopen" >&5 ++echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 ++if test "${ac_cv_func_dlopen+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen. ++ For example, HP-UX 11i <limits.h> declares gettimeofday. */ ++#define dlopen innocuous_dlopen ++ ++/* System header to define __stub macros and hopefully few prototypes, ++ which can conflict with char dlopen (); below. ++ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since ++ <limits.h> exists even on freestanding compilers. */ ++ ++#ifdef __STDC__ ++# include <limits.h> ++#else ++# include <assert.h> ++#endif ++ ++#undef dlopen ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dlopen (); ++/* The GNU C library defines this for functions which it implements ++ to always fail with ENOSYS. Some functions are actually named ++ something starting with __ and the normal name is an alias. */ ++#if defined (__stub_dlopen) || defined (__stub___dlopen) ++choke me ++#else ++char (*f) () = dlopen; ++#endif ++#ifdef __cplusplus ++} ++#endif ++ ++int ++main () ++{ ++return f != dlopen; ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_func_dlopen=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_func_dlopen=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++fi ++echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 ++echo "${ECHO_T}$ac_cv_func_dlopen" >&6 ++if test $ac_cv_func_dlopen = yes; then ++ lt_cv_dlopen="dlopen" ++else ++ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 ++echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 ++if test "${ac_cv_lib_dl_dlopen+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldl $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dlopen (); ++int ++main () ++{ ++dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_dl_dlopen=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_dl_dlopen=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 ++echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 ++if test $ac_cv_lib_dl_dlopen = yes; then ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" ++else ++ echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 ++echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 ++if test "${ac_cv_lib_svld_dlopen+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lsvld $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dlopen (); ++int ++main () ++{ ++dlopen (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_svld_dlopen=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_svld_dlopen=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 ++echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 ++if test $ac_cv_lib_svld_dlopen = yes; then ++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" ++else ++ echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 ++echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 ++if test "${ac_cv_lib_dld_dld_link+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldld $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char dld_link (); ++int ++main () ++{ ++dld_link (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_dld_dld_link=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_dld_dld_link=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 ++echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 ++if test $ac_cv_lib_dld_dld_link = yes; then ++ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ++fi ++ ++ ;; ++ esac ++ ++ if test "x$lt_cv_dlopen" != xno; then ++ enable_dlopen=yes ++ else ++ enable_dlopen=no ++ fi ++ ++ case $lt_cv_dlopen in ++ dlopen) ++ save_CPPFLAGS="$CPPFLAGS" ++ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" ++ ++ save_LDFLAGS="$LDFLAGS" ++ wl=$lt_prog_compiler_wl eval LDFLAGS="$LDFLAGS $export_dynamic_flag_spec" ++ ++ save_LIBS="$LIBS" ++ LIBS="$lt_cv_dlopen_libs $LIBS" ++ ++ echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 ++echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 ++if test "${lt_cv_dlopen_self+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ lt_cv_dlopen_self=cross ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<EOF ++#line 9154 "configure" ++#include "confdefs.h" ++ ++#if HAVE_DLFCN_H ++#include <dlfcn.h> ++#endif ++ ++#include <stdio.h> ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++#ifdef __cplusplus ++extern "C" void exit (int); ++#endif ++ ++void fnord() { int i=42;} ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ exit (status); ++} ++EOF ++ if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&5 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; ++ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; ++ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; ++ esac ++ else : ++ # compilation failed ++ lt_cv_dlopen_self=no ++ fi ++fi ++rm -fr conftest* ++ ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 ++echo "${ECHO_T}$lt_cv_dlopen_self" >&6 ++ ++ if test "x$lt_cv_dlopen_self" = xyes; then ++ wl=$lt_prog_compiler_wl eval LDFLAGS="$LDFLAGS $lt_prog_compiler_static" ++ echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 ++echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 ++if test "${lt_cv_dlopen_self_static+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ lt_cv_dlopen_self_static=cross ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<EOF ++#line 9254 "configure" ++#include "confdefs.h" ++ ++#if HAVE_DLFCN_H ++#include <dlfcn.h> ++#endif ++ ++#include <stdio.h> ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++#ifdef __cplusplus ++extern "C" void exit (int); ++#endif ++ ++void fnord() { int i=42;} ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ exit (status); ++} ++EOF ++ if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then ++ (./conftest; exit; ) >&5 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; ++ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; ++ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; ++ esac ++ else : ++ # compilation failed ++ lt_cv_dlopen_self_static=no ++ fi ++fi ++rm -fr conftest* ++ ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 ++echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 ++ fi ++ ++ CPPFLAGS="$save_CPPFLAGS" ++ LDFLAGS="$save_LDFLAGS" ++ LIBS="$save_LIBS" ++ ;; ++ esac ++ ++ case $lt_cv_dlopen_self in ++ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; ++ *) enable_dlopen_self=unknown ;; ++ esac ++ ++ case $lt_cv_dlopen_self_static in ++ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; ++ *) enable_dlopen_self_static=unknown ;; ++ esac ++fi ++ ++ ++# Report which library types will actually be built ++echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 ++echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 ++echo "$as_me:$LINENO: result: $can_build_shared" >&5 ++echo "${ECHO_T}$can_build_shared" >&6 ++ ++echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 ++echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 ++test "$can_build_shared" = "no" && enable_shared=no ++ ++# On AIX, shared libraries and static libraries use the same namespace, and ++# are all built from PIC. ++case $host_os in ++aix3*) ++ test "$enable_shared" = yes && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~$RANLIB $lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ ++aix4* | aix5*) ++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then ++ test "$enable_shared" = yes && enable_static=no ++ fi ++ ;; ++esac ++echo "$as_me:$LINENO: result: $enable_shared" >&5 ++echo "${ECHO_T}$enable_shared" >&6 ++ ++echo "$as_me:$LINENO: checking whether to build static libraries" >&5 ++echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 ++# Make sure either enable_shared or enable_static is yes. ++test "$enable_shared" = yes || enable_static=yes ++echo "$as_me:$LINENO: result: $enable_static" >&5 ++echo "${ECHO_T}$enable_static" >&6 ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler \ ++ CC \ ++ LD \ ++ lt_prog_compiler_wl \ ++ lt_prog_compiler_pic \ ++ lt_prog_compiler_static \ ++ lt_prog_compiler_no_builtin_flag \ ++ export_dynamic_flag_spec \ ++ thread_safe_flag_spec \ ++ whole_archive_flag_spec \ ++ enable_shared_with_static_runtimes \ ++ old_archive_cmds \ ++ old_archive_from_new_cmds \ ++ predep_objects \ ++ postdep_objects \ ++ predeps \ ++ postdeps \ ++ compiler_lib_search_path \ ++ archive_cmds \ ++ archive_expsym_cmds \ ++ postinstall_cmds \ ++ postuninstall_cmds \ ++ old_archive_from_expsyms_cmds \ ++ allow_undefined_flag \ ++ no_undefined_flag \ ++ export_symbols_cmds \ ++ hardcode_libdir_flag_spec \ ++ hardcode_libdir_flag_spec_ld \ ++ hardcode_libdir_separator \ ++ hardcode_automatic \ ++ module_cmds \ ++ module_expsym_cmds \ ++ lt_cv_prog_compiler_c_o \ ++ exclude_expsyms \ ++ include_expsyms; do ++ ++ case $var in ++ old_archive_cmds | \ ++ old_archive_from_new_cmds | \ ++ archive_cmds | \ ++ archive_expsym_cmds | \ ++ module_cmds | \ ++ module_expsym_cmds | \ ++ old_archive_from_expsyms_cmds | \ ++ export_symbols_cmds | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$double_quote_subst" -e "$sed_quote_subst" -e "$delay_variable_subst"`\"" ++ ;; ++ *) ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$sed_quote_subst"`\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="${ofile}T" ++ trap "$rm "$cfgfile"; exit 1" 1 2 15 ++ $rm -f "$cfgfile" ++ { echo "$as_me:$LINENO: creating $ofile" >&5 ++echo "$as_me: creating $ofile" >&6;} ++ ++ cat <<__EOF__ >> "$cfgfile" ++#! $SHELL ++ ++# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. ++# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) ++# NOTE: Changes made to this file will be lost: look at ltmain.sh. ++# ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 ++# Free Software Foundation, Inc. ++# ++# This file is part of GNU Libtool: ++# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++# A sed program that does not truncate output. ++SED=$lt_SED ++ ++# Sed that helps us avoid accidentally triggering echo(1) options like -n. ++Xsed="$SED -e 1s/^X//" ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++# The names of the tagged configurations supported by this script. ++available_tags= ++ ++# ### BEGIN LIBTOOL CONFIG ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds ++archive_expsym_cmds=$lt_archive_expsym_cmds ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds ++module_expsym_cmds=$lt_module_expsym_cmds ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=$lt_predep_objects ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=$lt_postdep_objects ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=$lt_compiler_lib_search_path ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode $libdir into a binary during linking. ++# This must work even if $libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec ++ ++# If ld is used when linking, flag to hardcode $libdir into ++# a binary during linking. This must work even if $libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=$lt_sys_lib_search_path_spec ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable $srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms ++ ++# ### END LIBTOOL CONFIG ++ ++__EOF__ ++ ++ ++ case $host_os in ++ aix3*) ++ cat <<\EOF >> "$cfgfile" ++ ++# AIX sometimes has problems with the GCC collect2 program. For some ++# reason, if we set the COLLECT_NAMES environment variable, the problems ++# vanish in a puff of smoke. ++if test "X${COLLECT_NAMES+set}" != Xset; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++fi ++EOF ++ ;; ++ esac ++ ++ # We use sed instead of cat because bash on DJGPP gets confused if ++ # if finds mixed CR/LF and LF-only lines. Since sed operates in ++ # text mode, it properly converts lines to CR/LF. This bash problem ++ # is reportedly fixed, but why not run on old versions too? ++ sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) ++ ++ mv -f "$cfgfile" "$ofile" || \ ++ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") ++ chmod +x "$ofile" ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ ++# Check whether --with-tags or --without-tags was given. ++if test "${with_tags+set}" = set; then ++ withval="$with_tags" ++ tagnames="$withval" ++fi; ++ ++if test -f "$ltmain" && test -n "$tagnames"; then ++ if test ! -f "${ofile}"; then ++ { echo "$as_me:$LINENO: WARNING: output file `$ofile' does not exist" >&5 ++echo "$as_me: WARNING: output file `$ofile' does not exist" >&2;} ++ fi ++ ++ if test -z "$LTCC"; then ++ eval "`$SHELL ${ofile} --config | grep '^LTCC='`" ++ if test -z "$LTCC"; then ++ { echo "$as_me:$LINENO: WARNING: output file `$ofile' does not look like a libtool script" >&5 ++echo "$as_me: WARNING: output file `$ofile' does not look like a libtool script" >&2;} ++ else ++ { echo "$as_me:$LINENO: WARNING: using `LTCC=$LTCC', extracted from `$ofile'" >&5 ++echo "$as_me: WARNING: using `LTCC=$LTCC', extracted from `$ofile'" >&2;} ++ fi ++ fi ++ if test -z "$LTCFLAGS"; then ++ eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" ++ fi ++ ++ # Extract list of available tagged configurations in $ofile. ++ # Note that this assumes the entire list is on one line. ++ available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=(.*$)/\1/' -e 's/"//g'` ++ ++ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," ++ for tagname in $tagnames; do ++ IFS="$lt_save_ifs" ++ # Check whether tagname contains only valid characters ++ case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in ++ "") ;; ++ *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 ++echo "$as_me: error: invalid tag name: $tagname" >&2;} ++ { (exit 1); exit 1; }; } ++ ;; ++ esac ++ ++ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null ++ then ++ { { echo "$as_me:$LINENO: error: tag name "$tagname" already exists" >&5 ++echo "$as_me: error: tag name "$tagname" already exists" >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++ ++ # Update the list of available tags. ++ if test -n "$tagname"; then ++ echo appending configuration tag "$tagname" to $ofile ++ ++ case $tagname in ++ CXX) ++ if test -n "$CXX" && ( test "X$CXX" != "Xno" && ++ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || ++ (test "X$CXX" != "Xg++"))) ; then ++ ac_ext=cc ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++ ++ ++ ++archive_cmds_need_lc_CXX=no ++allow_undefined_flag_CXX= ++always_export_symbols_CXX=no ++archive_expsym_cmds_CXX= ++export_dynamic_flag_spec_CXX= ++hardcode_direct_CXX=no ++hardcode_libdir_flag_spec_CXX= ++hardcode_libdir_flag_spec_ld_CXX= ++hardcode_libdir_separator_CXX= ++hardcode_minus_L_CXX=no ++hardcode_shlibpath_var_CXX=unsupported ++hardcode_automatic_CXX=no ++module_cmds_CXX= ++module_expsym_cmds_CXX= ++link_all_deplibs_CXX=unknown ++old_archive_cmds_CXX=$old_archive_cmds ++no_undefined_flag_CXX= ++whole_archive_flag_spec_CXX= ++enable_shared_with_static_runtimes_CXX=no ++ ++# Dependencies to place before and after the object being linked: ++predep_objects_CXX= ++postdep_objects_CXX= ++predeps_CXX= ++postdeps_CXX= ++compiler_lib_search_path_CXX= ++ ++# Source file extension for C++ test sources. ++ac_ext=cpp ++ ++# Object file extension for compiled C++ test sources. ++objext=o ++objext_CXX=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_LD=$LD ++lt_save_GCC=$GCC ++GCC=$GXX ++lt_save_with_gnu_ld=$with_gnu_ld ++lt_save_path_LD=$lt_cv_path_LD ++if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then ++ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx ++else ++ $as_unset lt_cv_prog_gnu_ld ++fi ++if test -n "${lt_cv_path_LDCXX+set}"; then ++ lt_cv_path_LD=$lt_cv_path_LDCXX ++else ++ $as_unset lt_cv_path_LD ++fi ++test -z "${LDCXX+set}" || LD=$LDCXX ++CC=${CXX-"c++"} ++compiler=$CC ++compiler_CXX=$CC ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\/]compile | ccache | *[\/]ccache ) ;; ++ distcc | *[\/]distcc | purify | *[\/]purify ) ;; ++ -*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ ++# We don't want -fno-exception wen compiling C++ code, so set the ++# no_builtin_flag separately ++if test "$GXX" = yes; then ++ lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' ++else ++ lt_prog_compiler_no_builtin_flag_CXX= ++fi ++ ++if test "$GXX" = yes; then ++ # Set up default GNU C++ configuration ++ ++ ++# Check whether --with-gnu-ld or --without-gnu-ld was given. ++if test "${with_gnu_ld+set}" = set; then ++ withval="$with_gnu_ld" ++ test "$withval" = no || with_gnu_ld=yes ++else ++ with_gnu_ld=no ++fi; ++ac_prog=ld ++if test "$GCC" = yes; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ echo "$as_me:$LINENO: checking for ld used by $CC" >&5 ++echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [\/]* | ?:[\/]*) ++ re_direlt='/[^/][^/]*/../' ++ # Canonicalize the pathname of ld ++ ac_prog=`echo $ac_prog| $SED 's%\\%/%g'` ++ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD="$ac_prog" ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test "$with_gnu_ld" = yes; then ++ echo "$as_me:$LINENO: checking for GNU ld" >&5 ++echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 ++else ++ echo "$as_me:$LINENO: checking for non-GNU ld" >&5 ++echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 ++fi ++if test "${lt_cv_path_LD+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ if test -z "$LD"; then ++ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS="$lt_save_ifs" ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD="$ac_dir/$ac_prog" ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in ++ *GNU* | *'with BFD'*) ++ test "$with_gnu_ld" != no && break ++ ;; ++ *) ++ test "$with_gnu_ld" != yes && break ++ ;; ++ esac ++ fi ++ done ++ IFS="$lt_save_ifs" ++else ++ lt_cv_path_LD="$LD" # Let the user override the test with a path. ++fi ++fi ++ ++LD="$lt_cv_path_LD" ++if test -n "$LD"; then ++ echo "$as_me:$LINENO: result: $LD" >&5 ++echo "${ECHO_T}$LD" >&6 ++else ++ echo "$as_me:$LINENO: result: no" >&5 ++echo "${ECHO_T}no" >&6 ++fi ++test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in $PATH" >&5 ++echo "$as_me: error: no acceptable ld found in $PATH" >&2;} ++ { (exit 1); exit 1; }; } ++echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 ++echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 ++if test "${lt_cv_prog_gnu_ld+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ # I'd rather use --version here, but apparently some GNU lds only accept -v. ++case `$LD -v 2>&1 </dev/null` in ++*GNU* | *'with BFD'*) ++ lt_cv_prog_gnu_ld=yes ++ ;; ++*) ++ lt_cv_prog_gnu_ld=no ++ ;; ++esac ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5 ++echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 ++with_gnu_ld=$lt_cv_prog_gnu_ld ++ ++ ++ ++ # Check if GNU C++ uses GNU ld as the underlying linker, since the ++ # archiving commands below assume that GNU ld is being used. ++ if test "$with_gnu_ld" = yes; then ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to ++ # investigate it a little bit more. (MM) ++ wlarc='${wl}' ++ ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ ++ grep 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec_CXX= ++ fi ++ else ++ with_gnu_ld=no ++ wlarc= ++ ++ # A generic and very simple default shared library creation ++ # command for GNU C++ for the case where it uses the native ++ # linker, instead of GNU ld. If possible, this setting should ++ # overridden to take advantage of the native linker features on ++ # the platform it is being used on. ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ fi ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "-L"' ++ ++else ++ GXX=no ++ with_gnu_ld=no ++ wlarc= ++fi ++ ++# PORTME: fill in a description of your system's C++ link characteristics ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ld_shlibs_CXX=yes ++case $host_os in ++ aix3*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ case $ld_flag in ++ *-brtl*) ++ aix_use_runtimelinking=yes ++ break ++ ;; ++ esac ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds_CXX='' ++ hardcode_direct_CXX=yes ++ hardcode_libdir_separator_CXX=':' ++ link_all_deplibs_CXX=yes ++ ++ if test "$GXX" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ hardcode_direct_CXX=yes ++ else ++ # We have old collect2 ++ hardcode_direct_CXX=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L_CXX=yes ++ hardcode_libdir_flag_spec_CXX='-L$libdir' ++ hardcode_libdir_separator_CXX= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols_CXX=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag_CXX='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" ++ ++ archive_expsym_cmds_CXX="$CC"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"${wl}$exp_sym_flag:$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag_CXX="-z nodefs" ++ archive_expsym_cmds_CXX="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"${wl}$exp_sym_flag:$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_cxx_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag_CXX=' ${wl}-bernotok' ++ allow_undefined_flag_CXX=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec_CXX='$convenience' ++ archive_cmds_need_lc_CXX=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds_CXX="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag_CXX=unsupported ++ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ ++ chorus*) ++ case $cc_basename in ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec_CXX='-L$libdir' ++ allow_undefined_flag_CXX=unsupported ++ always_export_symbols_CXX=no ++ enable_shared_with_static_runtimes_CXX=yes ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[012]) ++ allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ archive_cmds_need_lc_CXX=no ++ hardcode_direct_CXX=no ++ hardcode_automatic_CXX=yes ++ hardcode_shlibpath_var_CXX=unsupported ++ whole_archive_flag_spec_CXX='' ++ link_all_deplibs_CXX=yes ++ ++ if test "$GXX" = yes ; then ++ lt_int_apple_cc_single_mod=no ++ output_verbose_link_cmd='echo' ++ if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then ++ lt_int_apple_cc_single_mod=yes ++ fi ++ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then ++ archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ else ++ archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ fi ++ module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then ++ archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ fi ++ module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ freebsd[12]*) ++ # C++ shared libraries reported to be fairly broken before switch to ELF ++ ld_shlibs_CXX=no ++ ;; ++ freebsd-elf*) ++ archive_cmds_need_lc_CXX=no ++ ;; ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF ++ # conventions ++ ld_shlibs_CXX=yes ++ ;; ++ gnu*) ++ ;; ++ hpux9*) ++ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ hardcode_direct_CXX=yes ++ hardcode_minus_L_CXX=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ aCC*) ++ archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ hpux10*|hpux11*) ++ if test $with_gnu_ld = no; then ++ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_libdir_flag_spec_ld_CXX='+b $libdir' ++ ;; ++ *) ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ ;; ++ esac ++ fi ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_direct_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ ;; ++ *) ++ hardcode_direct_CXX=yes ++ hardcode_minus_L_CXX=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ;; ++ esac ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ aCC*) ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test $with_gnu_ld = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ fi ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ interix3*) ++ hardcode_direct_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ ;; ++ irix5* | irix6*) ++ case $cc_basename in ++ CC*) ++ # SGI C++ ++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -ar", where "CC" is the IRIX C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ++ ;; ++ *) ++ if test "$GXX" = yes; then ++ if test "$with_gnu_ld" = no; then ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' ++ fi ++ fi ++ link_all_deplibs_CXX=yes ++ ;; ++ esac ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ;; ++ linux*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '''s/([^()0-9A-Za-z{}])/\\\1/g'''`; templib=`echo $lib | $SED -e "s/${tempext}..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o $templib; mv $templib $lib' ++ archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '''s/([^()0-9A-Za-z{}])/\\\1/g'''`; templib=`echo $lib | $SED -e "s/${tempext}..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o $templib ${wl}-retain-symbols-file,$export_symbols; mv $templib $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ++ ;; ++ icpc*) ++ # Intel C++ ++ with_gnu_ld=yes ++ # version 8.0 and above of icpc choke on multiply defined symbols ++ # if we add $predep_objects and $postdep_objects, however 7.1 and ++ # earlier do not add the objects themselves. ++ case `$CC -V 2>&1` in ++ *"Version 7."*) ++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ *) # Version 8.0 or newer ++ tmp_idyn= ++ case $host_cpu in ++ ia64*) tmp_idyn=' -i_dynamic';; ++ esac ++ archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ esac ++ archive_cmds_need_lc_CXX=no ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ++ ;; ++ pgCC*) ++ # Portland Group C++ compiler ++ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec_CXX='${wl}--export-dynamic' ++ whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ ;; ++ cxx*) ++ # Compaq C++ ++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' ++ ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec_CXX='-rpath $libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/(^.*ld.*)( .*ld .*$)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ esac ++ ;; ++ lynxos*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ m88k*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' ++ wlarc= ++ hardcode_libdir_flag_spec_CXX='-R$libdir' ++ hardcode_direct_CXX=yes ++ hardcode_shlibpath_var_CXX=no ++ fi ++ # Workaround some broken pre-1.5 toolchains ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ++ ;; ++ openbsd2*) ++ # C++ shared libraries are fairly broken ++ ld_shlibs_CXX=no ++ ;; ++ openbsd*) ++ hardcode_direct_CXX=yes ++ hardcode_shlibpath_var_CXX=no ++ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' ++ export_dynamic_flag_spec_CXX='${wl}-E' ++ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ fi ++ output_verbose_link_cmd='echo' ++ ;; ++ osf3*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '''s/([^()0-9A-Za-z{}])/\\\1/g'''`; templib=`echo $lib | $SED -e "s/${tempext}..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o $templib; mv $templib $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ++ ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ cxx*) ++ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}*' ++ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/(^.*ld.*)( .*ld.*$)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}*' ++ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '''s/([^()0-9A-Za-z{}])/\\\1/g'''`; templib=`echo $lib | $SED -e "s/${tempext}..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o $templib; mv $templib $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Archives containing C++ object files must be created using ++ # the KAI C++ compiler. ++ old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ cxx*) ++ allow_undefined_flag_CXX=' -expect_unresolved *' ++ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\n" -exported_symbol "$i" >> $lib.exp; done~ ++ echo "-hidden">> $lib.exp~ ++ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ ++ $rm $lib.exp' ++ ++ hardcode_libdir_flag_spec_CXX='-rpath $libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/(^.*ld.*)( .*ld.*$)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ++ ;; ++ *) ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}*' ++ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_CXX=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ fi ++ ;; ++ esac ++ ;; ++ psos*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ lcc*) ++ # Lucid ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ archive_cmds_need_lc_CXX=yes ++ no_undefined_flag_CXX=' -zdefs' ++ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ hardcode_libdir_flag_spec_CXX='-R$libdir' ++ hardcode_shlibpath_var_CXX=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The C++ compiler is used as linker so we must use $wl ++ # flag to pass the commands to the underlying system ++ # linker. We must also pass each convience library through ++ # to the system linker between allextract/defaultextract. ++ # The C++ compiler will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}-z ${wl}defaultextract' ++ ;; ++ esac ++ link_all_deplibs_CXX=yes ++ ++ output_verbose_link_cmd='echo' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ ++ # The C++ compiler must be used to create the archive. ++ old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ++ ;; ++ *) ++ # GNU C++ compiler with Solaris linker ++ if test "$GXX" = yes && test "$with_gnu_ld" = no; then ++ no_undefined_flag_CXX=' ${wl}-z ${wl}defs' ++ if $CC --version | grep -v '^2.7' > /dev/null; then ++ archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "-L"" ++ else ++ # g++ 2.7 appears to require `-G' NOT `-shared' on this ++ # platform. ++ archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' ++ archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "-L"" ++ fi ++ ++ hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' ++ fi ++ ;; ++ esac ++ ;; ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ++ no_undefined_flag_CXX='${wl}-z,text' ++ archive_cmds_need_lc_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ # For security reasons, it is highly recommended that you always ++ # use absolute paths for naming shared libraries, and exclude the ++ # DT_RUNPATH tag from executables and libraries. But doing so ++ # requires that you compile everything twice, which is a pain. ++ # So that behaviour is only enabled if SCOABSPATH is set to a ++ # non-empty value in the environment. Most likely only useful for ++ # creating official distributions of packages. ++ # This is a hack until libtool officially supports absolute path ++ # names for shared libraries. ++ no_undefined_flag_CXX='${wl}-z,text' ++ allow_undefined_flag_CXX='${wl}-z,nodefs' ++ archive_cmds_need_lc_CXX=no ++ hardcode_shlibpath_var_CXX=no ++ hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ hardcode_libdir_separator_CXX=':' ++ link_all_deplibs_CXX=yes ++ export_dynamic_flag_spec_CXX='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ archive_cmds_CXX='$CC -G ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_CXX='$CC -shared ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ esac ++ ;; ++ vxworks*) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ ld_shlibs_CXX=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 ++echo "${ECHO_T}$ld_shlibs_CXX" >&6 ++test "$ld_shlibs_CXX" = no && can_build_shared=no ++ ++GCC_CXX="$GXX" ++LD_CXX="$LD" ++ ++ ++cat > conftest.$ac_ext <<EOF ++class Foo ++{ ++public: ++ Foo (void) { a = 0; } ++private: ++ int a; ++}; ++EOF ++ ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; then ++ # Parse the compiler output and extract the necessary ++ # objects, libraries and library flags. ++ ++ # Sentinel used to keep track of whether or not we are before ++ # the conftest object file. ++ pre_test_object_deps_done=no ++ ++ # The `*' in the case matches for architectures that use `case' in ++ # $output_verbose_cmd can trigger glob expansion during the loop ++ # eval without this substitution. ++ output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` ++ ++ for p in `eval $output_verbose_link_cmd`; do ++ case $p in ++ ++ -L* | -R* | -l*) ++ # Some compilers place space between "-{L,R}" and the path. ++ # Remove the space. ++ if test $p = "-L" \ ++ || test $p = "-R"; then ++ prev=$p ++ continue ++ else ++ prev= ++ fi ++ ++ if test "$pre_test_object_deps_done" = no; then ++ case $p in ++ -L* | -R*) ++ # Internal compiler library paths should come after those ++ # provided the user. The postdeps already come after the ++ # user supplied libs so there is no need to process them. ++ if test -z "$compiler_lib_search_path_CXX"; then ++ compiler_lib_search_path_CXX="${prev}${p}" ++ else ++ compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" ++ fi ++ ;; ++ # The "-l" case would never come before the object being ++ # linked, so don't bother handling this case. ++ esac ++ else ++ if test -z "$postdeps_CXX"; then ++ postdeps_CXX="${prev}${p}" ++ else ++ postdeps_CXX="${postdeps_CXX} ${prev}${p}" ++ fi ++ fi ++ ;; ++ ++ *.$objext) ++ # This assumes that the test object file only shows up ++ # once in the compiler output. ++ if test "$p" = "conftest.$objext"; then ++ pre_test_object_deps_done=yes ++ continue ++ fi ++ ++ if test "$pre_test_object_deps_done" = no; then ++ if test -z "$predep_objects_CXX"; then ++ predep_objects_CXX="$p" ++ else ++ predep_objects_CXX="$predep_objects_CXX $p" ++ fi ++ else ++ if test -z "$postdep_objects_CXX"; then ++ postdep_objects_CXX="$p" ++ else ++ postdep_objects_CXX="$postdep_objects_CXX $p" ++ fi ++ fi ++ ;; ++ ++ *) ;; # Ignore the rest. ++ ++ esac ++ done ++ ++ # Clean up. ++ rm -f a.out a.exe ++else ++ echo "libtool.m4: error: problem compiling CXX test program" ++fi ++ ++$rm -f confest.$objext ++ ++# PORTME: override above test on systems where it is broken ++case $host_os in ++interix3*) ++ # Interix 3.5 installs completely hosed .la files for C++, so rather than ++ # hack all around it, let's just trust "g++" to DTRT. ++ predep_objects_CXX= ++ postdep_objects_CXX= ++ postdeps_CXX= ++ ;; ++ ++solaris*) ++ case $cc_basename in ++ CC*) ++ # Adding this requires a known-good setup of shared libraries for ++ # Sun compiler versions before 5.6, else PIC objects from an old ++ # archive will be linked into the output, leading to subtle bugs. ++ postdeps_CXX='-lCstd -lCrun' ++ ;; ++ esac ++ ;; ++esac ++ ++ ++case " $postdeps_CXX " in ++*" -lc "*) archive_cmds_need_lc_CXX=no ;; ++esac ++ ++lt_prog_compiler_wl_CXX= ++lt_prog_compiler_pic_CXX= ++lt_prog_compiler_static_CXX= ++ ++echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 ++echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ++ ++ # C++ specific cases for pic, static, wl, etc. ++ if test "$GXX" = yes; then ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_CXX='-Bstatic' ++ fi ++ ;; ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ mingw* | os2* | pw32*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ++ ;; ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic_CXX='-fno-common' ++ ;; ++ *djgpp*) ++ # DJGPP does not support shared libraries at all ++ lt_prog_compiler_pic_CXX= ++ ;; ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic_CXX=-Kconform_pic ++ fi ++ ;; ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ esac ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ esac ++ else ++ case $host_os in ++ aix4* | aix5*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_CXX='-Bstatic' ++ else ++ lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ chorus*) ++ case $cc_basename in ++ cxch68*) ++ # Green Hills C++ Compiler ++ # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ++ ;; ++ esac ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ lt_prog_compiler_pic_CXX='-qnocommon' ++ lt_prog_compiler_wl_CXX='-Wl,' ++ ;; ++ esac ++ ;; ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ lt_prog_compiler_pic_CXX='-KPIC' ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ lt_prog_compiler_pic_CXX='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ # FreeBSD uses GNU C++ ++ ;; ++ hpux9* | hpux10* | hpux11*) ++ case $cc_basename in ++ CC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' ++ if test "$host_cpu" != ia64; then ++ lt_prog_compiler_pic_CXX='+Z' ++ fi ++ ;; ++ aCC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX='+Z' ++ ;; ++ esac ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ interix*) ++ # This is c89, which is MS Visual C++ (no shared libs) ++ # Anyone wants to do a port? ++ ;; ++ irix5* | irix6* | nonstopux*) ++ case $cc_basename in ++ CC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_static_CXX='-non_shared' ++ # CC pic flag -KPIC is the default. ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ linux*) ++ case $cc_basename in ++ KCC*) ++ # KAI C++ Compiler ++ lt_prog_compiler_wl_CXX='--backend -Wl,' ++ lt_prog_compiler_pic_CXX='-fPIC' ++ ;; ++ icpc* | ecpc*) ++ # Intel C++ ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-static' ++ ;; ++ pgCC*) ++ # Portland Group C++ compiler. ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-fpic' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ ;; ++ cxx*) ++ # Compaq C++ ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ lt_prog_compiler_pic_CXX= ++ lt_prog_compiler_static_CXX='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ lynxos*) ++ ;; ++ m88k*) ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ lt_prog_compiler_pic_CXX='-W c,exportall' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ netbsd*) ++ ;; ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ lt_prog_compiler_wl_CXX='--backend -Wl,' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ lt_prog_compiler_pic_CXX='-pic' ++ ;; ++ cxx*) ++ # Digital/Compaq C++ ++ lt_prog_compiler_wl_CXX='-Wl,' ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ lt_prog_compiler_pic_CXX= ++ lt_prog_compiler_static_CXX='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ psos*) ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ lt_prog_compiler_wl_CXX='-Qoption ld ' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ lt_prog_compiler_pic_CXX='-PIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ lt_prog_compiler_pic_CXX='-pic' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ ;; ++ lcc*) ++ # Lucid ++ lt_prog_compiler_pic_CXX='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ lt_prog_compiler_pic_CXX='-KPIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ case $cc_basename in ++ CC*) ++ lt_prog_compiler_wl_CXX='-Wl,' ++ lt_prog_compiler_pic_CXX='-KPIC' ++ lt_prog_compiler_static_CXX='-Bstatic' ++ ;; ++ esac ++ ;; ++ vxworks*) ++ ;; ++ *) ++ lt_prog_compiler_can_build_shared_CXX=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6 ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic_CXX"; then ++ ++echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 ++echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_pic_works_CXX=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:11594: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:11598: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_pic_works_CXX=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6 ++ ++if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then ++ case $lt_prog_compiler_pic_CXX in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; ++ esac ++else ++ lt_prog_compiler_pic_CXX= ++ lt_prog_compiler_can_build_shared_CXX=no ++fi ++ ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic_CXX= ++ ;; ++ *) ++ lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag="$lt_prog_compiler_static_CXX" ++echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_static_works_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_static_works_CXX=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_static_works_CXX=yes ++ fi ++ else ++ lt_prog_compiler_static_works_CXX=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5 ++echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6 ++ ++if test x"$lt_prog_compiler_static_works_CXX" = xyes; then ++ : ++else ++ lt_prog_compiler_static_CXX= ++fi ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 ++echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_c_o_CXX=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:11698: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:11702: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o_CXX=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6 ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 ++echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ echo "$as_me:$LINENO: result: $hard_links" >&5 ++echo "${ECHO_T}$hard_links" >&6 ++ if test "$hard_links" = no; then ++ { echo "$as_me:$LINENO: WARNING: `$CC' does not support `-c -o', so `make -j' may be unsafe" >&5 ++echo "$as_me: WARNING: `$CC' does not support `-c -o', so `make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ ++ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '''s/.* //''' | sort | uniq > $export_symbols' ++ case $host_os in ++ aix4* | aix5*) ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '''{ if ((($2 == "T") || ($2 == "D") || ($2 == "B")) && (substr($3,1,1) != ".")) { print $3 } }''' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '''{ if ((($2 == "T") || ($2 == "D") || ($2 == "B")) && (substr($3,1,1) != ".")) { print $3 } }''' | sort -u > $export_symbols' ++ fi ++ ;; ++ pw32*) ++ export_symbols_cmds_CXX="$ltdll_cmds" ++ ;; ++ cygwin* | mingw*) ++ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '''/^[BCDGRS] /s/.* ([^ ]*)/\1 DATA/;/^.* __nm__/s/^.* __nm__([^ ]*) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //''' | sort | uniq > $export_symbols' ++ ;; ++ *) ++ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '''s/.* //''' | sort | uniq > $export_symbols' ++ ;; ++ esac ++ ++echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 ++echo "${ECHO_T}$ld_shlibs_CXX" >&6 ++test "$ld_shlibs_CXX" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc_CXX" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc_CXX=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds_CXX in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 ++echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl_CXX ++ pic_flag=$lt_prog_compiler_pic_CXX ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag_CXX ++ allow_undefined_flag_CXX= ++ if { (eval echo "$as_me:$LINENO: "$archive_cmds_CXX 2>&1 | grep " -lc " >/dev/null 2>&1"") >&5 ++ (eval $archive_cmds_CXX 2>&1 | grep " -lc " >/dev/null 2>&1) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++ then ++ archive_cmds_need_lc_CXX=no ++ else ++ archive_cmds_need_lc_CXX=yes ++ fi ++ allow_undefined_flag_CXX=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 ++echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6 ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 ++echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib<name>.so ++ # instead of lib<name>.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '''s%^.*/([^/]*).ixlibrary$%\1%'''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename ${file}`~ ++ dlpath=`$SHELL 2>&1 -c '''. $dir/'''${base_file}'''i;echo $dlname'''`~ ++ dldir=$destdir/`dirname $dlpath`~ ++ test -d $dldir || mkdir -p $dldir~ ++ $install_prog $dir/$dlname $dldir/$dlname~ ++ chmod a+x $dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '''. $file; echo $dlname'''`~ ++ dlpath=$dir/$dldll~ ++ $rm $dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ ++cat $export_symbols | sed -e "s/(.*)/\1;/" >> $output_objdir/$libname.ver~ ++$echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ else ++ $archive_expsym_cmds="$archive_cmds" ++ fi ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[123]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ # Handle Gentoo/FreeBSD as it was Linux ++ case $host_vendor in ++ gentoo) ++ version_type=linux ;; ++ *) ++ version_type=freebsd-$objformat ;; ++ esac ++ ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ linux) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ need_lib_prefix=no ++ need_version=no ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", $2)); skip = 1; } { if (!skip) print $0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $dynamic_linker" >&5 ++echo "${ECHO_T}$dynamic_linker" >&6 ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 ++echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 ++hardcode_action_CXX= ++if test -n "$hardcode_libdir_flag_spec_CXX" || \ ++ test -n "$runpath_var_CXX" || \ ++ test "X$hardcode_automatic_CXX" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$hardcode_direct_CXX" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && ++ test "$hardcode_minus_L_CXX" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action_CXX=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action_CXX=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action_CXX=unsupported ++fi ++echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 ++echo "${ECHO_T}$hardcode_action_CXX" >&6 ++ ++if test "$hardcode_action_CXX" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler_CXX \ ++ CC_CXX \ ++ LD_CXX \ ++ lt_prog_compiler_wl_CXX \ ++ lt_prog_compiler_pic_CXX \ ++ lt_prog_compiler_static_CXX \ ++ lt_prog_compiler_no_builtin_flag_CXX \ ++ export_dynamic_flag_spec_CXX \ ++ thread_safe_flag_spec_CXX \ ++ whole_archive_flag_spec_CXX \ ++ enable_shared_with_static_runtimes_CXX \ ++ old_archive_cmds_CXX \ ++ old_archive_from_new_cmds_CXX \ ++ predep_objects_CXX \ ++ postdep_objects_CXX \ ++ predeps_CXX \ ++ postdeps_CXX \ ++ compiler_lib_search_path_CXX \ ++ archive_cmds_CXX \ ++ archive_expsym_cmds_CXX \ ++ postinstall_cmds_CXX \ ++ postuninstall_cmds_CXX \ ++ old_archive_from_expsyms_cmds_CXX \ ++ allow_undefined_flag_CXX \ ++ no_undefined_flag_CXX \ ++ export_symbols_cmds_CXX \ ++ hardcode_libdir_flag_spec_CXX \ ++ hardcode_libdir_flag_spec_ld_CXX \ ++ hardcode_libdir_separator_CXX \ ++ hardcode_automatic_CXX \ ++ module_cmds_CXX \ ++ module_expsym_cmds_CXX \ ++ lt_cv_prog_compiler_c_o_CXX \ ++ exclude_expsyms_CXX \ ++ include_expsyms_CXX; do ++ ++ case $var in ++ old_archive_cmds_CXX | \ ++ old_archive_from_new_cmds_CXX | \ ++ archive_cmds_CXX | \ ++ archive_expsym_cmds_CXX | \ ++ module_cmds_CXX | \ ++ module_expsym_cmds_CXX | \ ++ old_archive_from_expsyms_cmds_CXX | \ ++ export_symbols_cmds_CXX | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$double_quote_subst" -e "$sed_quote_subst" -e "$delay_variable_subst"`\"" ++ ;; ++ *) ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$sed_quote_subst"`\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="$ofile" ++ ++ cat <<__EOF__ >> "$cfgfile" ++# ### BEGIN LIBTOOL TAG CONFIG: $tagname ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc_CXX ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler_CXX ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC_CXX ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD_CXX ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl_CXX ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic_CXX ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static_CXX ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds_CXX ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds_CXX ++archive_expsym_cmds=$lt_archive_expsym_cmds_CXX ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds_CXX ++module_expsym_cmds=$lt_module_expsym_cmds_CXX ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=$lt_predep_objects_CXX ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=$lt_postdep_objects_CXX ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps_CXX ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps_CXX ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=$lt_compiler_lib_search_path_CXX ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag_CXX ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag_CXX ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action_CXX ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode $libdir into a binary during linking. ++# This must work even if $libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX ++ ++# If ld is used when linking, flag to hardcode $libdir into ++# a binary during linking. This must work even if $libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct_CXX ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L_CXX ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic_CXX ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs_CXX ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=$lt_sys_lib_search_path_spec ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable $srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path_CXX" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols_CXX ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds_CXX ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms_CXX ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms_CXX ++ ++# ### END LIBTOOL TAG CONFIG: $tagname ++ ++__EOF__ ++ ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC=$lt_save_CC ++LDCXX=$LD ++LD=$lt_save_LD ++GCC=$lt_save_GCC ++with_gnu_ldcxx=$with_gnu_ld ++with_gnu_ld=$lt_save_with_gnu_ld ++lt_cv_path_LDCXX=$lt_cv_path_LD ++lt_cv_path_LD=$lt_save_path_LD ++lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld ++lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ++ ++ else ++ tagname="" ++ fi ++ ;; ++ ++ F77) ++ if test -n "$F77" && test "X$F77" != "Xno"; then ++ ++ac_ext=f ++ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ++ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_f77_compiler_gnu ++ ++ ++archive_cmds_need_lc_F77=no ++allow_undefined_flag_F77= ++always_export_symbols_F77=no ++archive_expsym_cmds_F77= ++export_dynamic_flag_spec_F77= ++hardcode_direct_F77=no ++hardcode_libdir_flag_spec_F77= ++hardcode_libdir_flag_spec_ld_F77= ++hardcode_libdir_separator_F77= ++hardcode_minus_L_F77=no ++hardcode_automatic_F77=no ++module_cmds_F77= ++module_expsym_cmds_F77= ++link_all_deplibs_F77=unknown ++old_archive_cmds_F77=$old_archive_cmds ++no_undefined_flag_F77= ++whole_archive_flag_spec_F77= ++enable_shared_with_static_runtimes_F77=no ++ ++# Source file extension for f77 test sources. ++ac_ext=f ++ ++# Object file extension for compiled f77 test sources. ++objext=o ++objext_F77=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code=" subroutine t\n return\n end\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code=" program t\n end\n" ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC="$CC" ++CC=${F77-"f77"} ++compiler=$CC ++compiler_F77=$CC ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\/]compile | ccache | *[\/]ccache ) ;; ++ distcc | *[\/]distcc | purify | *[\/]purify ) ;; ++ -*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ ++echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 ++echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 ++echo "$as_me:$LINENO: result: $can_build_shared" >&5 ++echo "${ECHO_T}$can_build_shared" >&6 ++ ++echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 ++echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 ++test "$can_build_shared" = "no" && enable_shared=no ++ ++# On AIX, shared libraries and static libraries use the same namespace, and ++# are all built from PIC. ++case $host_os in ++aix3*) ++ test "$enable_shared" = yes && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~$RANLIB $lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++aix4* | aix5*) ++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then ++ test "$enable_shared" = yes && enable_static=no ++ fi ++ ;; ++esac ++echo "$as_me:$LINENO: result: $enable_shared" >&5 ++echo "${ECHO_T}$enable_shared" >&6 ++ ++echo "$as_me:$LINENO: checking whether to build static libraries" >&5 ++echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 ++# Make sure either enable_shared or enable_static is yes. ++test "$enable_shared" = yes || enable_static=yes ++echo "$as_me:$LINENO: result: $enable_static" >&5 ++echo "${ECHO_T}$enable_static" >&6 ++ ++GCC_F77="$G77" ++LD_F77="$LD" ++ ++lt_prog_compiler_wl_F77= ++lt_prog_compiler_pic_F77= ++lt_prog_compiler_static_F77= ++ ++echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 ++echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ++ ++ if test "$GCC" = yes; then ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_static_F77='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_F77='-Bstatic' ++ fi ++ ;; ++ ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_F77='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic_F77='-fno-common' ++ ;; ++ ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ lt_prog_compiler_can_build_shared_F77=no ++ enable_shared=no ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic_F77=-Kconform_pic ++ fi ++ ;; ++ ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_F77='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ *) ++ lt_prog_compiler_pic_F77='-fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_F77='-Bstatic' ++ else ++ lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ lt_prog_compiler_pic_F77='-qnocommon' ++ lt_prog_compiler_wl_F77='-Wl,' ++ ;; ++ esac ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_F77='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_F77='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ lt_prog_compiler_static_F77='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ # PIC (with -KPIC) is the default. ++ lt_prog_compiler_static_F77='-non_shared' ++ ;; ++ ++ newsos6) ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ icc* | ecc*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_pic_F77='-fpic' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ccc*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ # All Alpha code is PIC. ++ lt_prog_compiler_static_F77='-non_shared' ++ ;; ++ esac ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ # All OSF/1 code is PIC. ++ lt_prog_compiler_static_F77='-non_shared' ++ ;; ++ ++ solaris*) ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ lt_prog_compiler_wl_F77='-Qoption ld ';; ++ *) ++ lt_prog_compiler_wl_F77='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ lt_prog_compiler_wl_F77='-Qoption ld ' ++ lt_prog_compiler_pic_F77='-PIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ lt_prog_compiler_pic_F77='-Kconform_pic' ++ lt_prog_compiler_static_F77='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_pic_F77='-KPIC' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ unicos*) ++ lt_prog_compiler_wl_F77='-Wl,' ++ lt_prog_compiler_can_build_shared_F77=no ++ ;; ++ ++ uts4*) ++ lt_prog_compiler_pic_F77='-pic' ++ lt_prog_compiler_static_F77='-Bstatic' ++ ;; ++ ++ *) ++ lt_prog_compiler_can_build_shared_F77=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6 ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic_F77"; then ++ ++echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 ++echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_pic_works_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_pic_works_F77=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic_F77" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:13305: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:13309: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_pic_works_F77=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6 ++ ++if test x"$lt_prog_compiler_pic_works_F77" = xyes; then ++ case $lt_prog_compiler_pic_F77 in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; ++ esac ++else ++ lt_prog_compiler_pic_F77= ++ lt_prog_compiler_can_build_shared_F77=no ++fi ++ ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic_F77= ++ ;; ++ *) ++ lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag="$lt_prog_compiler_static_F77" ++echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_static_works_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_static_works_F77=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_static_works_F77=yes ++ fi ++ else ++ lt_prog_compiler_static_works_F77=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5 ++echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6 ++ ++if test x"$lt_prog_compiler_static_works_F77" = xyes; then ++ : ++else ++ lt_prog_compiler_static_F77= ++fi ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 ++echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_c_o_F77=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:13409: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:13413: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o_F77=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6 ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 ++echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ echo "$as_me:$LINENO: result: $hard_links" >&5 ++echo "${ECHO_T}$hard_links" >&6 ++ if test "$hard_links" = no; then ++ { echo "$as_me:$LINENO: WARNING: `$CC' does not support `-c -o', so `make -j' may be unsafe" >&5 ++echo "$as_me: WARNING: `$CC' does not support `-c -o', so `make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ ++ runpath_var= ++ allow_undefined_flag_F77= ++ enable_shared_with_static_runtimes_F77=no ++ archive_cmds_F77= ++ archive_expsym_cmds_F77= ++ old_archive_From_new_cmds_F77= ++ old_archive_from_expsyms_cmds_F77= ++ export_dynamic_flag_spec_F77= ++ whole_archive_flag_spec_F77= ++ thread_safe_flag_spec_F77= ++ hardcode_libdir_flag_spec_F77= ++ hardcode_libdir_flag_spec_ld_F77= ++ hardcode_libdir_separator_F77= ++ hardcode_direct_F77=no ++ hardcode_minus_L_F77=no ++ hardcode_shlibpath_var_F77=unsupported ++ link_all_deplibs_F77=unknown ++ hardcode_automatic_F77=no ++ module_cmds_F77= ++ module_expsym_cmds_F77= ++ always_export_symbols_F77=no ++ export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '''s/.* //''' | sort | uniq > $export_symbols' ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ include_expsyms_F77= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ extract_expsyms_cmds= ++ # Just being paranoid about ensuring that cc_basename is set. ++ for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\/]compile | ccache | *[\/]ccache ) ;; ++ distcc | *[\/]distcc | purify | *[\/]purify ) ;; ++ -*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ case $host_os in ++ cygwin* | mingw* | pw32*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ ld_shlibs_F77=yes ++ if test "$with_gnu_ld" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec_F77='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec_F77= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix3* | aix4* | aix5*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ ld_shlibs_F77=no ++ cat <<EOF 1>&2 ++ ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. ++ ++EOF ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_minus_L_F77=yes ++ ++ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports ++ # that the semantics of dynamic libraries on AmigaOS, at least up ++ # to version 4, is to share data among multiple programs linked ++ # with the same dynamic library. Since this doesn't match the ++ # behavior of shared libraries on other platforms, we can't use ++ # them. ++ ld_shlibs_F77=no ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag_F77=unsupported ++ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ allow_undefined_flag_F77=unsupported ++ always_export_symbols_F77=no ++ enable_shared_with_static_runtimes_F77=yes ++ export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '''/^[BCDGRS] /s/.* ([^ ]*)/\1 DATA/''' | $SED -e '''/^[AITW] /s/.* //''' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ ++ interix3*) ++ hardcode_direct_F77=no ++ hardcode_shlibpath_var_F77=no ++ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_F77='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ tmp_addflag= ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ esac ++ archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/(.*)/\1;/" >> $output_objdir/$libname.ver~ ++ $echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | grep 'BFD 2.8' > /dev/null; then ++ ld_shlibs_F77=no ++ cat <<EOF 1>&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++EOF ++ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ++ ld_shlibs_F77=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,${SCOABSPATH:+${install_libdir}/}$soname -o $lib' ++ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs_F77=no ++ fi ++ ;; ++ esac ++ ++ if test "$ld_shlibs_F77" = no; then ++ runpath_var= ++ hardcode_libdir_flag_spec_F77= ++ export_dynamic_flag_spec_F77= ++ whole_archive_flag_spec_F77= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ allow_undefined_flag_F77=unsupported ++ always_export_symbols_F77=yes ++ archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ hardcode_minus_L_F77=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ hardcode_direct_F77=unsupported ++ fi ++ ;; ++ ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '''{ if ((($2 == "T") || ($2 == "D") || ($2 == "B")) && (substr($3,1,1) != ".")) { print $3 } }''' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '''{ if ((($2 == "T") || ($2 == "D") || ($2 == "B")) && (substr($3,1,1) != ".")) { print $3 } }''' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds_F77='' ++ hardcode_direct_F77=yes ++ hardcode_libdir_separator_F77=':' ++ link_all_deplibs_F77=yes ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ hardcode_direct_F77=yes ++ else ++ # We have old collect2 ++ hardcode_direct_F77=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L_F77=yes ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_libdir_separator_F77= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols_F77=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag_F77='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++ program main ++ ++ end ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_f77_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" ++ archive_expsym_cmds_F77="$CC"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"${wl}$exp_sym_flag:$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag_F77="-z nodefs" ++ archive_expsym_cmds_F77="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"${wl}$exp_sym_flag:$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++ program main ++ ++ end ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_f77_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag_F77=' ${wl}-bernotok' ++ allow_undefined_flag_F77=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec_F77='$convenience' ++ archive_cmds_need_lc_F77=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds_F77="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_minus_L_F77=yes ++ # see comment about different semantics on the GNU ld section ++ ld_shlibs_F77=no ++ ;; ++ ++ bsdi[45]*) ++ export_dynamic_flag_spec_F77=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ hardcode_libdir_flag_spec_F77=' ' ++ allow_undefined_flag_F77=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '''s/ -lc$//'''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ old_archive_From_new_cmds_F77='true' ++ # FIXME: Should let the user specify the lib program. ++ old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' ++ fix_srcfile_path_F77='`cygpath -w "$srcfile"`' ++ enable_shared_with_static_runtimes_F77=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[012]) ++ allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ archive_cmds_need_lc_F77=no ++ hardcode_direct_F77=no ++ hardcode_automatic_F77=yes ++ hardcode_shlibpath_var_F77=unsupported ++ whole_archive_flag_spec_F77='' ++ link_all_deplibs_F77=yes ++ if test "$GCC" = yes ; then ++ output_verbose_link_cmd='echo' ++ archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ ld_shlibs_F77=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ freebsd1*) ++ ld_shlibs_F77=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2*) ++ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_F77=yes ++ hardcode_minus_L_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ hardcode_direct_F77=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_F77=yes ++ export_dynamic_flag_spec_F77='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ ++ hardcode_direct_F77=yes ++ export_dynamic_flag_spec_F77='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_F77=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_libdir_flag_spec_ld_F77='+b $libdir' ++ hardcode_direct_F77=no ++ hardcode_shlibpath_var_F77=no ++ ;; ++ *) ++ hardcode_direct_F77=yes ++ export_dynamic_flag_spec_F77='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_F77=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' ++ fi ++ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ link_all_deplibs_F77=yes ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ newsos6) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_F77=yes ++ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ openbsd*) ++ hardcode_direct_F77=yes ++ hardcode_shlibpath_var_F77=no ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_F77='${wl}-E' ++ else ++ case $host_os in ++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) ++ archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ ;; ++ *) ++ archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ ;; ++ ++ os2*) ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_minus_L_F77=yes ++ allow_undefined_flag_F77=unsupported ++ archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION "$libname"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}*' ++ archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ allow_undefined_flag_F77=' -expect_unresolved *' ++ archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_F77=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}*' ++ archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' ++ else ++ allow_undefined_flag_F77=' -expect_unresolved *' ++ archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\n" -exported_symbol "$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ ++ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ hardcode_libdir_flag_spec_F77='-rpath $libdir' ++ fi ++ hardcode_libdir_separator_F77=: ++ ;; ++ ++ solaris*) ++ no_undefined_flag_F77=' -z text' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' ++ else ++ wlarc='' ++ archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' ++ fi ++ hardcode_libdir_flag_spec_F77='-R$libdir' ++ hardcode_shlibpath_var_F77=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The compiler driver will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl, iff we do not link with $LD. ++ # Luckily, gcc supports the same syntax we need for Sun Studio. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ case $wlarc in ++ '') ++ whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; ++ *) ++ whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}-z ${wl}defaultextract' ;; ++ esac ;; ++ esac ++ link_all_deplibs_F77=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_direct_F77=yes ++ hardcode_minus_L_F77=yes ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_F77=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ reload_cmds_F77='$CC -r -o $output$reload_objs' ++ hardcode_direct_F77=no ++ ;; ++ motorola) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ sysv4.3*) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var_F77=no ++ export_dynamic_flag_spec_F77='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var_F77=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ ld_shlibs_F77=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ++ no_undefined_flag_F77='${wl}-z,text' ++ archive_cmds_need_lc_F77=no ++ hardcode_shlibpath_var_F77=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ no_undefined_flag_F77='${wl}-z,text' ++ allow_undefined_flag_F77='${wl}-z,nodefs' ++ archive_cmds_need_lc_F77=no ++ hardcode_shlibpath_var_F77=no ++ hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ hardcode_libdir_separator_F77=':' ++ link_all_deplibs_F77=yes ++ export_dynamic_flag_spec_F77='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds_F77='$CC -shared ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_F77='$CC -G ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_F77='-L$libdir' ++ hardcode_shlibpath_var_F77=no ++ ;; ++ ++ *) ++ ld_shlibs_F77=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 ++echo "${ECHO_T}$ld_shlibs_F77" >&6 ++test "$ld_shlibs_F77" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc_F77" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc_F77=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds_F77 in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 ++echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl_F77 ++ pic_flag=$lt_prog_compiler_pic_F77 ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag_F77 ++ allow_undefined_flag_F77= ++ if { (eval echo "$as_me:$LINENO: "$archive_cmds_F77 2>&1 | grep " -lc " >/dev/null 2>&1"") >&5 ++ (eval $archive_cmds_F77 2>&1 | grep " -lc " >/dev/null 2>&1) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++ then ++ archive_cmds_need_lc_F77=no ++ else ++ archive_cmds_need_lc_F77=yes ++ fi ++ allow_undefined_flag_F77=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 ++echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6 ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 ++echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib<name>.so ++ # instead of lib<name>.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '''s%^.*/([^/]*).ixlibrary$%\1%'''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename ${file}`~ ++ dlpath=`$SHELL 2>&1 -c '''. $dir/'''${base_file}'''i;echo $dlname'''`~ ++ dldir=$destdir/`dirname $dlpath`~ ++ test -d $dldir || mkdir -p $dldir~ ++ $install_prog $dir/$dlname $dldir/$dlname~ ++ chmod a+x $dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '''. $file; echo $dlname'''`~ ++ dlpath=$dir/$dldll~ ++ $rm $dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ ++cat $export_symbols | sed -e "s/(.*)/\1;/" >> $output_objdir/$libname.ver~ ++$echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ else ++ $archive_expsym_cmds="$archive_cmds" ++ fi ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[123]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ # Handle Gentoo/FreeBSD as it was Linux ++ case $host_vendor in ++ gentoo) ++ version_type=linux ;; ++ *) ++ version_type=freebsd-$objformat ;; ++ esac ++ ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ linux) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ need_lib_prefix=no ++ need_version=no ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", $2)); skip = 1; } { if (!skip) print $0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $dynamic_linker" >&5 ++echo "${ECHO_T}$dynamic_linker" >&6 ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 ++echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 ++hardcode_action_F77= ++if test -n "$hardcode_libdir_flag_spec_F77" || \ ++ test -n "$runpath_var_F77" || \ ++ test "X$hardcode_automatic_F77" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$hardcode_direct_F77" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && ++ test "$hardcode_minus_L_F77" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action_F77=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action_F77=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action_F77=unsupported ++fi ++echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 ++echo "${ECHO_T}$hardcode_action_F77" >&6 ++ ++if test "$hardcode_action_F77" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler_F77 \ ++ CC_F77 \ ++ LD_F77 \ ++ lt_prog_compiler_wl_F77 \ ++ lt_prog_compiler_pic_F77 \ ++ lt_prog_compiler_static_F77 \ ++ lt_prog_compiler_no_builtin_flag_F77 \ ++ export_dynamic_flag_spec_F77 \ ++ thread_safe_flag_spec_F77 \ ++ whole_archive_flag_spec_F77 \ ++ enable_shared_with_static_runtimes_F77 \ ++ old_archive_cmds_F77 \ ++ old_archive_from_new_cmds_F77 \ ++ predep_objects_F77 \ ++ postdep_objects_F77 \ ++ predeps_F77 \ ++ postdeps_F77 \ ++ compiler_lib_search_path_F77 \ ++ archive_cmds_F77 \ ++ archive_expsym_cmds_F77 \ ++ postinstall_cmds_F77 \ ++ postuninstall_cmds_F77 \ ++ old_archive_from_expsyms_cmds_F77 \ ++ allow_undefined_flag_F77 \ ++ no_undefined_flag_F77 \ ++ export_symbols_cmds_F77 \ ++ hardcode_libdir_flag_spec_F77 \ ++ hardcode_libdir_flag_spec_ld_F77 \ ++ hardcode_libdir_separator_F77 \ ++ hardcode_automatic_F77 \ ++ module_cmds_F77 \ ++ module_expsym_cmds_F77 \ ++ lt_cv_prog_compiler_c_o_F77 \ ++ exclude_expsyms_F77 \ ++ include_expsyms_F77; do ++ ++ case $var in ++ old_archive_cmds_F77 | \ ++ old_archive_from_new_cmds_F77 | \ ++ archive_cmds_F77 | \ ++ archive_expsym_cmds_F77 | \ ++ module_cmds_F77 | \ ++ module_expsym_cmds_F77 | \ ++ old_archive_from_expsyms_cmds_F77 | \ ++ export_symbols_cmds_F77 | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$double_quote_subst" -e "$sed_quote_subst" -e "$delay_variable_subst"`\"" ++ ;; ++ *) ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$sed_quote_subst"`\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="$ofile" ++ ++ cat <<__EOF__ >> "$cfgfile" ++# ### BEGIN LIBTOOL TAG CONFIG: $tagname ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc_F77 ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler_F77 ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC_F77 ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD_F77 ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl_F77 ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic_F77 ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static_F77 ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds_F77 ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds_F77 ++archive_expsym_cmds=$lt_archive_expsym_cmds_F77 ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds_F77 ++module_expsym_cmds=$lt_module_expsym_cmds_F77 ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=$lt_predep_objects_F77 ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=$lt_postdep_objects_F77 ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps_F77 ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps_F77 ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=$lt_compiler_lib_search_path_F77 ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag_F77 ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag_F77 ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action_F77 ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode $libdir into a binary during linking. ++# This must work even if $libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 ++ ++# If ld is used when linking, flag to hardcode $libdir into ++# a binary during linking. This must work even if $libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct_F77 ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L_F77 ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic_F77 ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs_F77 ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=$lt_sys_lib_search_path_spec ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable $srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path_F77" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols_F77 ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds_F77 ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms_F77 ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms_F77 ++ ++# ### END LIBTOOL TAG CONFIG: $tagname ++ ++__EOF__ ++ ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ else ++ tagname="" ++ fi ++ ;; ++ ++ GCJ) ++ if test -n "$GCJ" && test "X$GCJ" != "Xno"; then ++ ++ ++ ++# Source file extension for Java test sources. ++ac_ext=java ++ ++# Object file extension for compiled Java test sources. ++objext=o ++objext_GCJ=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="class foo {}\n" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC="$CC" ++CC=${GCJ-"gcj"} ++compiler=$CC ++compiler_GCJ=$CC ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\/]compile | ccache | *[\/]ccache ) ;; ++ distcc | *[\/]distcc | purify | *[\/]purify ) ;; ++ -*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ ++# GCJ did not exist at the time GCC didn't implicitly link libc in. ++archive_cmds_need_lc_GCJ=no ++ ++old_archive_cmds_GCJ=$old_archive_cmds ++ ++ ++lt_prog_compiler_no_builtin_flag_GCJ= ++ ++if test "$GCC" = yes; then ++ lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 ++echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_rtti_exceptions=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="-fno-rtti -fno-exceptions" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:15649: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:15653: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_rtti_exceptions=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 ++ ++if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then ++ lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" ++else ++ : ++fi ++ ++fi ++ ++lt_prog_compiler_wl_GCJ= ++lt_prog_compiler_pic_GCJ= ++lt_prog_compiler_static_GCJ= ++ ++echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 ++echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ++ ++ if test "$GCC" = yes; then ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_static_GCJ='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ fi ++ ;; ++ ++ amigaos*) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the `-m68020' flag to GCC prevents building anything better, ++ # like `-m68040'. ++ lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ ++ beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ lt_prog_compiler_pic_GCJ='-fno-common' ++ ;; ++ ++ interix3*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ lt_prog_compiler_can_build_shared_GCJ=no ++ enable_shared=no ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ lt_prog_compiler_pic_GCJ=-Kconform_pic ++ fi ++ ;; ++ ++ hpux*) ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_GCJ='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ *) ++ lt_prog_compiler_pic_GCJ='-fPIC' ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ if test "$host_cpu" = ia64; then ++ # AIX 5 now supports IA64 processor ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ else ++ lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ darwin*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ case $cc_basename in ++ xlc*) ++ lt_prog_compiler_pic_GCJ='-qnocommon' ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ ;; ++ esac ++ ;; ++ ++ mingw* | pw32* | os2*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ lt_prog_compiler_pic_GCJ='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ # PIC (with -KPIC) is the default. ++ lt_prog_compiler_static_GCJ='-non_shared' ++ ;; ++ ++ newsos6) ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ icc* | ecc*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_pic_GCJ='-fpic' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ccc*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ # All Alpha code is PIC. ++ lt_prog_compiler_static_GCJ='-non_shared' ++ ;; ++ esac ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ # All OSF/1 code is PIC. ++ lt_prog_compiler_static_GCJ='-non_shared' ++ ;; ++ ++ solaris*) ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95*) ++ lt_prog_compiler_wl_GCJ='-Qoption ld ';; ++ *) ++ lt_prog_compiler_wl_GCJ='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ lt_prog_compiler_wl_GCJ='-Qoption ld ' ++ lt_prog_compiler_pic_GCJ='-PIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec ;then ++ lt_prog_compiler_pic_GCJ='-Kconform_pic' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_pic_GCJ='-KPIC' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ unicos*) ++ lt_prog_compiler_wl_GCJ='-Wl,' ++ lt_prog_compiler_can_build_shared_GCJ=no ++ ;; ++ ++ uts4*) ++ lt_prog_compiler_pic_GCJ='-pic' ++ lt_prog_compiler_static_GCJ='-Bstatic' ++ ;; ++ ++ *) ++ lt_prog_compiler_can_build_shared_GCJ=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6 ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$lt_prog_compiler_pic_GCJ"; then ++ ++echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 ++echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_pic_works_GCJ=no ++ ac_outfile=conftest.$ac_objext ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$lt_prog_compiler_pic_GCJ" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:15917: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&5 ++ echo "$as_me:15921: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_pic_works_GCJ=yes ++ fi ++ fi ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 ++echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6 ++ ++if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then ++ case $lt_prog_compiler_pic_GCJ in ++ "" | " "*) ;; ++ *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; ++ esac ++else ++ lt_prog_compiler_pic_GCJ= ++ lt_prog_compiler_can_build_shared_GCJ=no ++fi ++ ++fi ++case $host_os in ++ # For platforms which do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ lt_prog_compiler_pic_GCJ= ++ ;; ++ *) ++ lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" ++ ;; ++esac ++ ++# ++# Check to make sure the static flag actually works. ++# ++wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag="$lt_prog_compiler_static_GCJ" ++echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 ++echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 ++if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_prog_compiler_static_works_GCJ=no ++ save_LDFLAGS="$LDFLAGS" ++ LDFLAGS="$LDFLAGS $lt_tmp_static_flag" ++ printf "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&5 ++ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ lt_prog_compiler_static_works_GCJ=yes ++ fi ++ else ++ lt_prog_compiler_static_works_GCJ=yes ++ fi ++ fi ++ $rm conftest* ++ LDFLAGS="$save_LDFLAGS" ++ ++fi ++echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5 ++echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6 ++ ++if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then ++ : ++else ++ lt_prog_compiler_static_GCJ= ++fi ++ ++ ++echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 ++echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 ++if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ lt_cv_prog_compiler_c_o_GCJ=no ++ $rm -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}{0,1} :&$lt_compiler_flag :; t' \ ++ -e 's: [^ ]*conftest.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo ""$as_me:16021: $lt_compile"" >&5) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&5 ++ echo "$as_me:16025: $? = $ac_status" >&5 ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ lt_cv_prog_compiler_c_o_GCJ=yes ++ fi ++ fi ++ chmod u+w . 2>&5 ++ $rm conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files ++ $rm out/* && rmdir out ++ cd .. ++ rmdir conftest ++ $rm conftest* ++ ++fi ++echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 ++echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6 ++ ++ ++hard_links="nottested" ++if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then ++ # do not overwrite the value of need_locks provided by the user ++ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 ++echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 ++ hard_links=yes ++ $rm conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ echo "$as_me:$LINENO: result: $hard_links" >&5 ++echo "${ECHO_T}$hard_links" >&6 ++ if test "$hard_links" = no; then ++ { echo "$as_me:$LINENO: WARNING: `$CC' does not support `-c -o', so `make -j' may be unsafe" >&5 ++echo "$as_me: WARNING: `$CC' does not support `-c -o', so `make -j' may be unsafe" >&2;} ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++ ++echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ++echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 ++ ++ runpath_var= ++ allow_undefined_flag_GCJ= ++ enable_shared_with_static_runtimes_GCJ=no ++ archive_cmds_GCJ= ++ archive_expsym_cmds_GCJ= ++ old_archive_From_new_cmds_GCJ= ++ old_archive_from_expsyms_cmds_GCJ= ++ export_dynamic_flag_spec_GCJ= ++ whole_archive_flag_spec_GCJ= ++ thread_safe_flag_spec_GCJ= ++ hardcode_libdir_flag_spec_GCJ= ++ hardcode_libdir_flag_spec_ld_GCJ= ++ hardcode_libdir_separator_GCJ= ++ hardcode_direct_GCJ=no ++ hardcode_minus_L_GCJ=no ++ hardcode_shlibpath_var_GCJ=unsupported ++ link_all_deplibs_GCJ=unknown ++ hardcode_automatic_GCJ=no ++ module_cmds_GCJ= ++ module_expsym_cmds_GCJ= ++ always_export_symbols_GCJ=no ++ export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '''s/.* //''' | sort | uniq > $export_symbols' ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ include_expsyms_GCJ= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ` (' and `)$', so one must not match beginning or ++ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', ++ # as well as any symbol that contains `d'. ++ exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ extract_expsyms_cmds= ++ # Just being paranoid about ensuring that cc_basename is set. ++ for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\/]compile | ccache | *[\/]ccache ) ;; ++ distcc | *[\/]distcc | purify | *[\/]purify ) ;; ++ -*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++ case $host_os in ++ cygwin* | mingw* | pw32*) ++ # FIXME: the MSVC++ port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ if test "$GCC" != yes; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++) ++ with_gnu_ld=yes ++ ;; ++ openbsd*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ ld_shlibs_GCJ=yes ++ if test "$with_gnu_ld" = yes; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='${wl}' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' ++ export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then ++ whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' ++ else ++ whole_archive_flag_spec_GCJ= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix3* | aix4* | aix5*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test "$host_cpu" != ia64; then ++ ld_shlibs_GCJ=no ++ cat <<EOF 1>&2 ++ ++*** Warning: the GNU linker, at least up to release 2.9.1, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to modify your PATH ++*** so that a non-GNU linker is found, and then restart. ++ ++EOF ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_minus_L_GCJ=yes ++ ++ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports ++ # that the semantics of dynamic libraries on AmigaOS, at least up ++ # to version 4, is to share data among multiple programs linked ++ # with the same dynamic library. Since this doesn't match the ++ # behavior of shared libraries on other platforms, we can't use ++ # them. ++ ld_shlibs_GCJ=no ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ allow_undefined_flag_GCJ=unsupported ++ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, ++ # as there is no search path for DLLs. ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ allow_undefined_flag_GCJ=unsupported ++ always_export_symbols_GCJ=no ++ enable_shared_with_static_runtimes_GCJ=yes ++ export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '''/^[BCDGRS] /s/.* ([^ ]*)/\1 DATA/''' | $SED -e '''/^[AITW] /s/.* //''' | sort | uniq > $export_symbols' ++ ++ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file (1st line ++ # is EXPORTS), use it as is; otherwise, prepend... ++ archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ ++ interix3*) ++ hardcode_direct_GCJ=no ++ hardcode_shlibpath_var_GCJ=no ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 * 262144 + 1342177280` -o $lib' ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ tmp_addflag= ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers ++ whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ esac ++ archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | sed -e "s/(.*)/\1;/" >> $output_objdir/$libname.ver~ ++ $echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ fi ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | grep 'BFD 2.8' > /dev/null; then ++ ld_shlibs_GCJ=no ++ cat <<EOF 1>&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++EOF ++ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ++ ld_shlibs_GCJ=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,${SCOABSPATH:+${install_libdir}/}$soname -o $lib' ++ archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ ld_shlibs_GCJ=no ++ fi ++ ;; ++ esac ++ ++ if test "$ld_shlibs_GCJ" = no; then ++ runpath_var= ++ hardcode_libdir_flag_spec_GCJ= ++ export_dynamic_flag_spec_GCJ= ++ whole_archive_flag_spec_GCJ= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ allow_undefined_flag_GCJ=unsupported ++ always_export_symbols_GCJ=yes ++ archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ hardcode_minus_L_GCJ=yes ++ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ hardcode_direct_GCJ=unsupported ++ fi ++ ;; ++ ++ aix4* | aix5*) ++ if test "$host_cpu" = ia64; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag="" ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to AIX nm, but means don't demangle with GNU nm ++ if $NM -V 2>&1 | grep 'GNU' > /dev/null; then ++ export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '''{ if ((($2 == "T") || ($2 == "D") || ($2 == "B")) && (substr($3,1,1) != ".")) { print $3 } }''' | sort -u > $export_symbols' ++ else ++ export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '''{ if ((($2 == "T") || ($2 == "D") || ($2 == "B")) && (substr($3,1,1) != ".")) { print $3 } }''' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # need to do runtime linking. ++ case $host_os in aix4.[23]|aix4.[23].*|aix5*) ++ for ld_flag in $LDFLAGS; do ++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ archive_cmds_GCJ='' ++ hardcode_direct_GCJ=yes ++ hardcode_libdir_separator_GCJ=':' ++ link_all_deplibs_GCJ=yes ++ ++ if test "$GCC" = yes; then ++ case $host_os in aix4.[012]|aix4.[012].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`${CC} -print-prog-name=collect2` ++ if test -f "$collect2name" && \ ++ strings "$collect2name" | grep resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ hardcode_direct_GCJ=yes ++ else ++ # We have old collect2 ++ hardcode_direct_GCJ=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ hardcode_minus_L_GCJ=yes ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_libdir_separator_GCJ= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag="$shared_flag "'${wl}-G' ++ fi ++ else ++ # not using gcc ++ if test "$host_cpu" = ia64; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test "$aix_use_runtimelinking" = yes; then ++ shared_flag='${wl}-G' ++ else ++ shared_flag='${wl}-bM:SRE' ++ fi ++ fi ++ fi ++ ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ always_export_symbols_GCJ=yes ++ if test "$aix_use_runtimelinking" = yes; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ allow_undefined_flag_GCJ='-berok' ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" ++ archive_expsym_cmds_GCJ="$CC"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"${wl}$exp_sym_flag:$export_symbols $shared_flag" ++ else ++ if test "$host_cpu" = ia64; then ++ hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' ++ allow_undefined_flag_GCJ="-z nodefs" ++ archive_expsym_cmds_GCJ="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"${wl}$exp_sym_flag:$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an empty executable. ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ++aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'` ++# Check for a 64-bit object if we didn't find anything. ++if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *(.*)$/\1/; p; } ++}'`; fi ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ++ ++ hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ no_undefined_flag_GCJ=' ${wl}-bernotok' ++ allow_undefined_flag_GCJ=' ${wl}-berok' ++ # Exported symbols can be pulled into shared objects from archives ++ whole_archive_flag_spec_GCJ='$convenience' ++ archive_cmds_need_lc_GCJ=yes ++ # This is similar to how AIX traditionally builds its shared libraries. ++ archive_expsym_cmds_GCJ="$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_minus_L_GCJ=yes ++ # see comment about different semantics on the GNU ld section ++ ld_shlibs_GCJ=no ++ ;; ++ ++ bsdi[45]*) ++ export_dynamic_flag_spec_GCJ=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ hardcode_libdir_flag_spec_GCJ=' ' ++ allow_undefined_flag_GCJ=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=".dll" ++ # FIXME: Setting linknames here is a bad hack. ++ archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '''s/ -lc$//'''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ old_archive_From_new_cmds_GCJ='true' ++ # FIXME: Should let the user specify the lib program. ++ old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' ++ fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' ++ enable_shared_with_static_runtimes_GCJ=yes ++ ;; ++ ++ darwin* | rhapsody*) ++ case $host_os in ++ rhapsody* | darwin1.[012]) ++ allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' ++ ;; ++ *) # Darwin 1.3 on ++ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then ++ allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ else ++ case ${MACOSX_DEPLOYMENT_TARGET} in ++ 10.[012]) ++ allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ++ ;; ++ 10.*) ++ allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ archive_cmds_need_lc_GCJ=no ++ hardcode_direct_GCJ=no ++ hardcode_automatic_GCJ=yes ++ hardcode_shlibpath_var_GCJ=unsupported ++ whole_archive_flag_spec_GCJ='' ++ link_all_deplibs_GCJ=yes ++ if test "$GCC" = yes ; then ++ output_verbose_link_cmd='echo' ++ archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' ++ module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ else ++ case $cc_basename in ++ xlc*) ++ output_verbose_link_cmd='echo' ++ archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' ++ module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' ++ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds ++ archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^(..*),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ++ ;; ++ *) ++ ld_shlibs_GCJ=no ++ ;; ++ esac ++ fi ++ ;; ++ ++ dgux*) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ freebsd1*) ++ ld_shlibs_GCJ=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2*) ++ archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_GCJ=yes ++ hardcode_minus_L_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | kfreebsd*-gnu | dragonfly*) ++ archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ hpux9*) ++ if test "$GCC" = yes; then ++ archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ else ++ archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ++ fi ++ hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ hardcode_direct_GCJ=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_GCJ=yes ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ ;; ++ ++ hpux10*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ ++ hardcode_direct_GCJ=yes ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_GCJ=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test "$GCC" = yes -a "$with_gnu_ld" = no; then ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ fi ++ if test "$with_gnu_ld" = no; then ++ hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' ++ hardcode_direct_GCJ=no ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ *) ++ hardcode_direct_GCJ=yes ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ hardcode_minus_L_GCJ=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test "$GCC" = yes; then ++ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' ++ fi ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ link_all_deplibs_GCJ=yes ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ newsos6) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_GCJ=yes ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ openbsd*) ++ hardcode_direct_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' ++ export_dynamic_flag_spec_GCJ='${wl}-E' ++ else ++ case $host_os in ++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) ++ archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ ;; ++ *) ++ archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi ++ ;; ++ ++ os2*) ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_minus_L_GCJ=yes ++ allow_undefined_flag_GCJ=unsupported ++ archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION "$libname"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' ++ old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ++ ;; ++ ++ osf3*) ++ if test "$GCC" = yes; then ++ allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}*' ++ archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ else ++ allow_undefined_flag_GCJ=' -expect_unresolved *' ++ archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ fi ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' ++ hardcode_libdir_separator_GCJ=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test "$GCC" = yes; then ++ allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}*' ++ archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ++ hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' ++ else ++ allow_undefined_flag_GCJ=' -expect_unresolved *' ++ archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' ++ archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\n" -exported_symbol "$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ ++ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ hardcode_libdir_flag_spec_GCJ='-rpath $libdir' ++ fi ++ hardcode_libdir_separator_GCJ=: ++ ;; ++ ++ solaris*) ++ no_undefined_flag_GCJ=' -z text' ++ if test "$GCC" = yes; then ++ wlarc='${wl}' ++ archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' ++ else ++ wlarc='' ++ archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/(.*)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ ++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' ++ fi ++ hardcode_libdir_flag_spec_GCJ='-R$libdir' ++ hardcode_shlibpath_var_GCJ=no ++ case $host_os in ++ solaris2.[0-5] | solaris2.[0-5].*) ;; ++ *) ++ # The compiler driver will combine linker options so we ++ # cannot just pass the convience library names through ++ # without $wl, iff we do not link with $LD. ++ # Luckily, gcc supports the same syntax we need for Sun Studio. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ case $wlarc in ++ '') ++ whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; ++ *) ++ whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience""; do test -n "$conv" && new_convenience="$new_convenience,$conv"; done; $echo "$new_convenience"` ${wl}-z ${wl}defaultextract' ;; ++ esac ;; ++ esac ++ link_all_deplibs_GCJ=yes ++ ;; ++ ++ sunos4*) ++ if test "x$host_vendor" = xsequent; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_direct_GCJ=yes ++ hardcode_minus_L_GCJ=yes ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_GCJ=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ reload_cmds_GCJ='$CC -r -o $output$reload_objs' ++ hardcode_direct_GCJ=no ++ ;; ++ motorola) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ sysv4.3*) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var_GCJ=no ++ export_dynamic_flag_spec_GCJ='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_shlibpath_var_GCJ=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ ld_shlibs_GCJ=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ++ no_undefined_flag_GCJ='${wl}-z,text' ++ archive_cmds_need_lc_GCJ=no ++ hardcode_shlibpath_var_GCJ=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We can NOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ no_undefined_flag_GCJ='${wl}-z,text' ++ allow_undefined_flag_GCJ='${wl}-z,nodefs' ++ archive_cmds_need_lc_GCJ=no ++ hardcode_shlibpath_var_GCJ=no ++ hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' ++ hardcode_libdir_separator_GCJ=':' ++ link_all_deplibs_GCJ=yes ++ export_dynamic_flag_spec_GCJ='${wl}-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test "$GCC" = yes; then ++ archive_cmds_GCJ='$CC -shared ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ archive_cmds_GCJ='$CC -G ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ hardcode_libdir_flag_spec_GCJ='-L$libdir' ++ hardcode_shlibpath_var_GCJ=no ++ ;; ++ ++ *) ++ ld_shlibs_GCJ=no ++ ;; ++ esac ++ fi ++ ++echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 ++echo "${ECHO_T}$ld_shlibs_GCJ" >&6 ++test "$ld_shlibs_GCJ" = no && can_build_shared=no ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$archive_cmds_need_lc_GCJ" in ++x|xyes) ++ # Assume -lc should be added ++ archive_cmds_need_lc_GCJ=yes ++ ++ if test "$enable_shared" = yes && test "$GCC" = yes; then ++ case $archive_cmds_GCJ in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 ++echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 ++ $rm conftest* ++ printf "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$lt_prog_compiler_wl_GCJ ++ pic_flag=$lt_prog_compiler_pic_GCJ ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ ++ allow_undefined_flag_GCJ= ++ if { (eval echo "$as_me:$LINENO: "$archive_cmds_GCJ 2>&1 | grep " -lc " >/dev/null 2>&1"") >&5 ++ (eval $archive_cmds_GCJ 2>&1 | grep " -lc " >/dev/null 2>&1) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } ++ then ++ archive_cmds_need_lc_GCJ=no ++ else ++ archive_cmds_need_lc_GCJ=yes ++ fi ++ allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $rm conftest* ++ echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 ++echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6 ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 ++echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=".so" ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++case $host_os in ++aix3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ ++aix4* | aix5*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test "$host_cpu" = ia64; then ++ # AIX 5 supports IA64 ++ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line `#! .'. This would cause the generated library to ++ # depend on `.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[01] | aix4.[01].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ if test "$aix_use_runtimelinking" = yes; then ++ # If using run time linking (on AIX 4.2 or later) use lib<name>.so ++ # instead of lib<name>.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ else ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='${libname}${release}.a $libname.a' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ fi ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '''s%^.*/([^/]*).ixlibrary$%\1%'''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ ++beos*) ++ library_names_spec='${libname}${shared_ext}' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[45]*) ++ version_type=linux ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32*) ++ version_type=windows ++ shrext_cmds=".dll" ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$host_os in ++ yes,cygwin* | yes,mingw* | yes,pw32*) ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename ${file}`~ ++ dlpath=`$SHELL 2>&1 -c '''. $dir/'''${base_file}'''i;echo $dlname'''`~ ++ dldir=$destdir/`dirname $dlpath`~ ++ test -d $dldir || mkdir -p $dldir~ ++ $install_prog $dir/$dlname $dldir/$dlname~ ++ chmod a+x $dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '''. $file; echo $dlname'''`~ ++ dlpath=$dir/$dldll~ ++ $rm $dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ++ ;; ++ mingw*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` ++ if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then ++ # It is most probably a Windows format PATH printed by ++ # mingw gcc, but we are running on Cygwin. Gcc prints its search ++ # path with ; separators, and with drive letters. We can handle the ++ # drive letters (cygwin fileutils understands them), so leave them, ++ # especially as we might pass files found there to a mingw objdump, ++ # which wouldn't understand a cygwinified path. Ahh. ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ++ ;; ++ esac ++ ;; ++ ++ linux*) ++ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then ++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' ++ supports_anon_versioning=no ++ case `$LD -v 2>/dev/null` in ++ *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ if test $supports_anon_versioning = yes; then ++ archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ ++cat $export_symbols | sed -e "s/(.*)/\1;/" >> $output_objdir/$libname.ver~ ++$echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' ++ else ++ $archive_expsym_cmds="$archive_cmds" ++ fi ++ else ++ ld_shlibs=no ++ fi ++ ;; ++ ++ *) ++ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' ++ soname_spec='${libname}${release}${major}$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++ # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. ++ if test "$GCC" = yes; then ++ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` ++ else ++ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' ++ fi ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd1*) ++ dynamic_linker=no ++ ;; ++ ++kfreebsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++freebsd* | dragonfly*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[123]*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ # Handle Gentoo/FreeBSD as it was Linux ++ case $host_vendor in ++ gentoo) ++ version_type=linux ;; ++ *) ++ version_type=freebsd-$objformat ;; ++ esac ++ ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' ++ need_version=yes ++ ;; ++ linux) ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ need_lib_prefix=no ++ need_version=no ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[01]* | freebsdelf3.[01]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ ++ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ freebsd*) # from 4.6 on ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++gnu*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ if test "X$HPUX_IA64_MODE" = X32; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ fi ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555. ++ postinstall_cmds='chmod 555 $lib' ++ ;; ++ ++interix3*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test "$lt_cv_prog_gnu_ld" = yes; then ++ version_type=linux ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" ++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++# This must be Linux ELF. ++linux*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", $2)); skip = 1; } { if (!skip) print $0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++knetbsd*-gnu) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='GNU ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++nto-qnx*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++openbsd*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec="/usr/lib" ++ need_lib_prefix=no ++ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. ++ case $host_os in ++ openbsd3.3 | openbsd3.3.*) need_version=yes ;; ++ *) need_version=no ;; ++ esac ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ case $host_os in ++ openbsd2.[89] | openbsd2.[89].*) ++ shlibpath_overrides_runpath=no ++ ;; ++ *) ++ shlibpath_overrides_runpath=yes ++ ;; ++ esac ++ else ++ shlibpath_overrides_runpath=yes ++ fi ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ shrext_cmds=".dll" ++ need_lib_prefix=no ++ library_names_spec='$libname${shared_ext} $libname.a' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=LIBPATH ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='${libname}${release}${shared_ext}$major' ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ++ ;; ++ ++solaris*) ++ version_type=linux ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' ++ finish_cmds='PATH="$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test "$with_gnu_ld" = yes; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ export_dynamic_flag_spec='${wl}-Blargedynsym' ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec ;then ++ version_type=linux ++ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' ++ soname_spec='$libname${shared_ext}.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=freebsd-elf ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ hardcode_into_libs=yes ++ if test "$with_gnu_ld" = yes; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ shlibpath_overrides_runpath=no ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ shlibpath_overrides_runpath=yes ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++uts4*) ++ version_type=linux ++ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ++ soname_spec='${libname}${release}${shared_ext}$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++echo "$as_me:$LINENO: result: $dynamic_linker" >&5 ++echo "${ECHO_T}$dynamic_linker" >&6 ++test "$dynamic_linker" = no && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test "$GCC" = yes; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 ++echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 ++hardcode_action_GCJ= ++if test -n "$hardcode_libdir_flag_spec_GCJ" || \ ++ test -n "$runpath_var_GCJ" || \ ++ test "X$hardcode_automatic_GCJ" = "Xyes" ; then ++ ++ # We can hardcode non-existant directories. ++ if test "$hardcode_direct_GCJ" != no && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && ++ test "$hardcode_minus_L_GCJ" != no; then ++ # Linking always hardcodes the temporary library directory. ++ hardcode_action_GCJ=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ hardcode_action_GCJ=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ hardcode_action_GCJ=unsupported ++fi ++echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 ++echo "${ECHO_T}$hardcode_action_GCJ" >&6 ++ ++if test "$hardcode_action_GCJ" = relink; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test "$shlibpath_overrides_runpath" = yes || ++ test "$enable_shared" = no; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++ ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler_GCJ \ ++ CC_GCJ \ ++ LD_GCJ \ ++ lt_prog_compiler_wl_GCJ \ ++ lt_prog_compiler_pic_GCJ \ ++ lt_prog_compiler_static_GCJ \ ++ lt_prog_compiler_no_builtin_flag_GCJ \ ++ export_dynamic_flag_spec_GCJ \ ++ thread_safe_flag_spec_GCJ \ ++ whole_archive_flag_spec_GCJ \ ++ enable_shared_with_static_runtimes_GCJ \ ++ old_archive_cmds_GCJ \ ++ old_archive_from_new_cmds_GCJ \ ++ predep_objects_GCJ \ ++ postdep_objects_GCJ \ ++ predeps_GCJ \ ++ postdeps_GCJ \ ++ compiler_lib_search_path_GCJ \ ++ archive_cmds_GCJ \ ++ archive_expsym_cmds_GCJ \ ++ postinstall_cmds_GCJ \ ++ postuninstall_cmds_GCJ \ ++ old_archive_from_expsyms_cmds_GCJ \ ++ allow_undefined_flag_GCJ \ ++ no_undefined_flag_GCJ \ ++ export_symbols_cmds_GCJ \ ++ hardcode_libdir_flag_spec_GCJ \ ++ hardcode_libdir_flag_spec_ld_GCJ \ ++ hardcode_libdir_separator_GCJ \ ++ hardcode_automatic_GCJ \ ++ module_cmds_GCJ \ ++ module_expsym_cmds_GCJ \ ++ lt_cv_prog_compiler_c_o_GCJ \ ++ exclude_expsyms_GCJ \ ++ include_expsyms_GCJ; do ++ ++ case $var in ++ old_archive_cmds_GCJ | \ ++ old_archive_from_new_cmds_GCJ | \ ++ archive_cmds_GCJ | \ ++ archive_expsym_cmds_GCJ | \ ++ module_cmds_GCJ | \ ++ module_expsym_cmds_GCJ | \ ++ old_archive_from_expsyms_cmds_GCJ | \ ++ export_symbols_cmds_GCJ | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$double_quote_subst" -e "$sed_quote_subst" -e "$delay_variable_subst"`\"" ++ ;; ++ *) ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$sed_quote_subst"`\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="$ofile" ++ ++ cat <<__EOF__ >> "$cfgfile" ++# ### BEGIN LIBTOOL TAG CONFIG: $tagname ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc_GCJ ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler_GCJ ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC_GCJ ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD_GCJ ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl_GCJ ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic_GCJ ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static_GCJ ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds_GCJ ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds_GCJ ++archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds_GCJ ++module_expsym_cmds=$lt_module_expsym_cmds_GCJ ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=$lt_predep_objects_GCJ ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=$lt_postdep_objects_GCJ ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps_GCJ ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps_GCJ ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag_GCJ ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag_GCJ ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action_GCJ ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode $libdir into a binary during linking. ++# This must work even if $libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ ++ ++# If ld is used when linking, flag to hardcode $libdir into ++# a binary during linking. This must work even if $libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct_GCJ ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L_GCJ ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic_GCJ ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs_GCJ ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=$lt_sys_lib_search_path_spec ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable $srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path_GCJ" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols_GCJ ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds_GCJ ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms_GCJ ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms_GCJ ++ ++# ### END LIBTOOL TAG CONFIG: $tagname ++ ++__EOF__ ++ ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ else ++ tagname="" ++ fi ++ ;; ++ ++ RC) ++ ++ ++ ++# Source file extension for RC test sources. ++ac_ext=rc ++ ++# Object file extension for compiled RC test sources. ++objext=o ++objext_RC=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code="$lt_simple_compile_test_code" ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++ ++ ++# save warnings/boilerplate of simple test code ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ac_outfile=conftest.$ac_objext ++printf "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$rm conftest* ++ ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC="$CC" ++CC=${RC-"windres"} ++compiler=$CC ++compiler_RC=$CC ++for cc_temp in $compiler""; do ++ case $cc_temp in ++ compile | *[\/]compile | ccache | *[\/]ccache ) ;; ++ distcc | *[\/]distcc | purify | *[\/]purify ) ;; ++ -*) ;; ++ *) break;; ++ esac ++done ++cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ++ ++lt_cv_prog_compiler_c_o_RC=yes ++ ++# The else clause should only fire when bootstrapping the ++# libtool distribution, otherwise you forgot to ship ltmain.sh ++# with your package, and you will get complaints that there are ++# no rules to generate ltmain.sh. ++if test -f "$ltmain"; then ++ # See if we are running on zsh, and set the options which allow our commands through ++ # without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++ fi ++ # Now quote all the things that may contain metacharacters while being ++ # careful not to overquote the AC_SUBSTed values. We take copies of the ++ # variables and quote the copies for generation of the libtool script. ++ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ ++ SED SHELL STRIP \ ++ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ ++ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ ++ deplibs_check_method reload_flag reload_cmds need_locks \ ++ lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ ++ lt_cv_sys_global_symbol_to_c_name_address \ ++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ ++ old_postinstall_cmds old_postuninstall_cmds \ ++ compiler_RC \ ++ CC_RC \ ++ LD_RC \ ++ lt_prog_compiler_wl_RC \ ++ lt_prog_compiler_pic_RC \ ++ lt_prog_compiler_static_RC \ ++ lt_prog_compiler_no_builtin_flag_RC \ ++ export_dynamic_flag_spec_RC \ ++ thread_safe_flag_spec_RC \ ++ whole_archive_flag_spec_RC \ ++ enable_shared_with_static_runtimes_RC \ ++ old_archive_cmds_RC \ ++ old_archive_from_new_cmds_RC \ ++ predep_objects_RC \ ++ postdep_objects_RC \ ++ predeps_RC \ ++ postdeps_RC \ ++ compiler_lib_search_path_RC \ ++ archive_cmds_RC \ ++ archive_expsym_cmds_RC \ ++ postinstall_cmds_RC \ ++ postuninstall_cmds_RC \ ++ old_archive_from_expsyms_cmds_RC \ ++ allow_undefined_flag_RC \ ++ no_undefined_flag_RC \ ++ export_symbols_cmds_RC \ ++ hardcode_libdir_flag_spec_RC \ ++ hardcode_libdir_flag_spec_ld_RC \ ++ hardcode_libdir_separator_RC \ ++ hardcode_automatic_RC \ ++ module_cmds_RC \ ++ module_expsym_cmds_RC \ ++ lt_cv_prog_compiler_c_o_RC \ ++ exclude_expsyms_RC \ ++ include_expsyms_RC; do ++ ++ case $var in ++ old_archive_cmds_RC | \ ++ old_archive_from_new_cmds_RC | \ ++ archive_cmds_RC | \ ++ archive_expsym_cmds_RC | \ ++ module_cmds_RC | \ ++ module_expsym_cmds_RC | \ ++ old_archive_from_expsyms_cmds_RC | \ ++ export_symbols_cmds_RC | \ ++ extract_expsyms_cmds | reload_cmds | finish_cmds | \ ++ postinstall_cmds | postuninstall_cmds | \ ++ old_postinstall_cmds | old_postuninstall_cmds | \ ++ sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) ++ # Double-quote double-evaled strings. ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$double_quote_subst" -e "$sed_quote_subst" -e "$delay_variable_subst"`\"" ++ ;; ++ *) ++ eval "lt_$var=\"`$echo "X$$var" | $Xsed -e "$sed_quote_subst"`\"" ++ ;; ++ esac ++ done ++ ++ case $lt_echo in ++ *'$0 --fallback-echo"') ++ lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` ++ ;; ++ esac ++ ++cfgfile="$ofile" ++ ++ cat <<__EOF__ >> "$cfgfile" ++# ### BEGIN LIBTOOL TAG CONFIG: $tagname ++ ++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: ++ ++# Shell to use when invoking shell scripts. ++SHELL=$lt_SHELL ++ ++# Whether or not to build shared libraries. ++build_libtool_libs=$enable_shared ++ ++# Whether or not to build static libraries. ++build_old_libs=$enable_static ++ ++# Whether or not to add -lc for building shared libraries. ++build_libtool_need_lc=$archive_cmds_need_lc_RC ++ ++# Whether or not to disallow shared libs when runtime libs are static ++allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC ++ ++# Whether or not to optimize for fast installation. ++fast_install=$enable_fast_install ++ ++# The host system. ++host_alias=$host_alias ++host=$host ++host_os=$host_os ++ ++# The build system. ++build_alias=$build_alias ++build=$build ++build_os=$build_os ++ ++# An echo program that does not interpret backslashes. ++echo=$lt_echo ++ ++# The archiver. ++AR=$lt_AR ++AR_FLAGS=$lt_AR_FLAGS ++ ++# A C compiler. ++LTCC=$lt_LTCC ++ ++# LTCC compiler flags. ++LTCFLAGS=$lt_LTCFLAGS ++ ++# A language-specific compiler. ++CC=$lt_compiler_RC ++ ++# Is the compiler the GNU C compiler? ++with_gcc=$GCC_RC ++ ++# An ERE matcher. ++EGREP=$lt_EGREP ++ ++# The linker used to build libraries. ++LD=$lt_LD_RC ++ ++# Whether we need hard or soft links. ++LN_S=$lt_LN_S ++ ++# A BSD-compatible nm program. ++NM=$lt_NM ++ ++# A symbol stripping program ++STRIP=$lt_STRIP ++ ++# Used to examine libraries when file_magic_cmd begins "file" ++MAGIC_CMD=$MAGIC_CMD ++ ++# Used on cygwin: DLL creation program. ++DLLTOOL="$DLLTOOL" ++ ++# Used on cygwin: object dumper. ++OBJDUMP="$OBJDUMP" ++ ++# Used on cygwin: assembler. ++AS="$AS" ++ ++# The name of the directory that contains temporary libtool files. ++objdir=$objdir ++ ++# How to create reloadable object files. ++reload_flag=$lt_reload_flag ++reload_cmds=$lt_reload_cmds ++ ++# How to pass a linker flag through the compiler. ++wl=$lt_lt_prog_compiler_wl_RC ++ ++# Object file suffix (normally "o"). ++objext="$ac_objext" ++ ++# Old archive suffix (normally "a"). ++libext="$libext" ++ ++# Shared library suffix (normally ".so"). ++shrext_cmds='$shrext_cmds' ++ ++# Executable file suffix (normally ""). ++exeext="$exeext" ++ ++# Additional compiler flags for building library objects. ++pic_flag=$lt_lt_prog_compiler_pic_RC ++pic_mode=$pic_mode ++ ++# What is the maximum length of a command? ++max_cmd_len=$lt_cv_sys_max_cmd_len ++ ++# Does compiler simultaneously support -c and -o options? ++compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC ++ ++# Must we lock files when doing compilation? ++need_locks=$lt_need_locks ++ ++# Do we need the lib prefix for modules? ++need_lib_prefix=$need_lib_prefix ++ ++# Do we need a version for libraries? ++need_version=$need_version ++ ++# Whether dlopen is supported. ++dlopen_support=$enable_dlopen ++ ++# Whether dlopen of programs is supported. ++dlopen_self=$enable_dlopen_self ++ ++# Whether dlopen of statically linked programs is supported. ++dlopen_self_static=$enable_dlopen_self_static ++ ++# Compiler flag to prevent dynamic linking. ++link_static_flag=$lt_lt_prog_compiler_static_RC ++ ++# Compiler flag to turn off builtin functions. ++no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC ++ ++# Compiler flag to allow reflexive dlopens. ++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC ++ ++# Compiler flag to generate shared objects directly from archives. ++whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC ++ ++# Compiler flag to generate thread-safe objects. ++thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC ++ ++# Library versioning type. ++version_type=$version_type ++ ++# Format of library name prefix. ++libname_spec=$lt_libname_spec ++ ++# List of archive names. First name is the real one, the rest are links. ++# The last name is the one that the linker finds with -lNAME. ++library_names_spec=$lt_library_names_spec ++ ++# The coded name of the library, if different from the real name. ++soname_spec=$lt_soname_spec ++ ++# Commands used to build and install an old-style archive. ++RANLIB=$lt_RANLIB ++old_archive_cmds=$lt_old_archive_cmds_RC ++old_postinstall_cmds=$lt_old_postinstall_cmds ++old_postuninstall_cmds=$lt_old_postuninstall_cmds ++ ++# Create an old-style archive from a shared archive. ++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC ++ ++# Create a temporary old-style archive to link instead of a shared archive. ++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC ++ ++# Commands used to build and install a shared archive. ++archive_cmds=$lt_archive_cmds_RC ++archive_expsym_cmds=$lt_archive_expsym_cmds_RC ++postinstall_cmds=$lt_postinstall_cmds ++postuninstall_cmds=$lt_postuninstall_cmds ++ ++# Commands used to build a loadable module (assumed same as above if empty) ++module_cmds=$lt_module_cmds_RC ++module_expsym_cmds=$lt_module_expsym_cmds_RC ++ ++# Commands to strip libraries. ++old_striplib=$lt_old_striplib ++striplib=$lt_striplib ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predep_objects=$lt_predep_objects_RC ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdep_objects=$lt_postdep_objects_RC ++ ++# Dependencies to place before the objects being linked to create a ++# shared library. ++predeps=$lt_predeps_RC ++ ++# Dependencies to place after the objects being linked to create a ++# shared library. ++postdeps=$lt_postdeps_RC ++ ++# The library search path used internally by the compiler when linking ++# a shared library. ++compiler_lib_search_path=$lt_compiler_lib_search_path_RC ++ ++# Method to check whether dependent libraries are shared objects. ++deplibs_check_method=$lt_deplibs_check_method ++ ++# Command to use when deplibs_check_method == file_magic. ++file_magic_cmd=$lt_file_magic_cmd ++ ++# Flag that allows shared libraries with undefined symbols to be built. ++allow_undefined_flag=$lt_allow_undefined_flag_RC ++ ++# Flag that forces no undefined symbols. ++no_undefined_flag=$lt_no_undefined_flag_RC ++ ++# Commands used to finish a libtool library installation in a directory. ++finish_cmds=$lt_finish_cmds ++ ++# Same as above, but a single script fragment to be evaled but not shown. ++finish_eval=$lt_finish_eval ++ ++# Take the output of nm and produce a listing of raw symbols and C names. ++global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe ++ ++# Transform the output of nm in a proper C declaration ++global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl ++ ++# Transform the output of nm in a C name address pair ++global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address ++ ++# This is the shared library runtime path variable. ++runpath_var=$runpath_var ++ ++# This is the shared library path variable. ++shlibpath_var=$shlibpath_var ++ ++# Is shlibpath searched before the hard-coded library search path? ++shlibpath_overrides_runpath=$shlibpath_overrides_runpath ++ ++# How to hardcode a shared library path into an executable. ++hardcode_action=$hardcode_action_RC ++ ++# Whether we should hardcode library paths into libraries. ++hardcode_into_libs=$hardcode_into_libs ++ ++# Flag to hardcode $libdir into a binary during linking. ++# This must work even if $libdir does not exist. ++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC ++ ++# If ld is used when linking, flag to hardcode $libdir into ++# a binary during linking. This must work even if $libdir does ++# not exist. ++hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC ++ ++# Whether we need a single -rpath flag with a separated argument. ++hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC ++ ++# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the ++# resulting binary. ++hardcode_direct=$hardcode_direct_RC ++ ++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the ++# resulting binary. ++hardcode_minus_L=$hardcode_minus_L_RC ++ ++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into ++# the resulting binary. ++hardcode_shlibpath_var=$hardcode_shlibpath_var_RC ++ ++# Set to yes if building a shared library automatically hardcodes DIR into the library ++# and all subsequent libraries and executables linked against it. ++hardcode_automatic=$hardcode_automatic_RC ++ ++# Variables whose values should be saved in libtool wrapper scripts and ++# restored at relink time. ++variables_saved_for_relink="$variables_saved_for_relink" ++ ++# Whether libtool must link a program against all its dependency libraries. ++link_all_deplibs=$link_all_deplibs_RC ++ ++# Compile-time system search path for libraries ++sys_lib_search_path_spec=$lt_sys_lib_search_path_spec ++ ++# Run-time system search path for libraries ++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec ++ ++# Fix the shell variable $srcfile for the compiler. ++fix_srcfile_path="$fix_srcfile_path_RC" ++ ++# Set to yes if exported symbols are required. ++always_export_symbols=$always_export_symbols_RC ++ ++# The commands to list exported symbols. ++export_symbols_cmds=$lt_export_symbols_cmds_RC ++ ++# The commands to extract the exported symbol list from a shared archive. ++extract_expsyms_cmds=$lt_extract_expsyms_cmds ++ ++# Symbols that should not be listed in the preloaded symbols. ++exclude_expsyms=$lt_exclude_expsyms_RC ++ ++# Symbols that must always be exported. ++include_expsyms=$lt_include_expsyms_RC ++ ++# ### END LIBTOOL TAG CONFIG: $tagname ++ ++__EOF__ ++ ++ ++else ++ # If there is no Makefile yet, we rely on a make rule to execute ++ # `config.status --recheck' to rerun these tests and create the ++ # libtool script then. ++ ltmain_in=`echo $ltmain | sed -e 's/.sh$/.in/'` ++ if test -f "$ltmain_in"; then ++ test -f Makefile && make "$ltmain" ++ fi ++fi ++ ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++CC="$lt_save_CC" ++ ++ ;; ++ ++ *) ++ { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 ++echo "$as_me: error: Unsupported tag name: $tagname" >&2;} ++ { (exit 1); exit 1; }; } ++ ;; ++ esac ++ ++ # Append the new tag name to the list of available tags. ++ if test -n "$tagname" ; then ++ available_tags="$available_tags $tagname" ++ fi ++ fi ++ done ++ IFS="$lt_save_ifs" ++ ++ # Now substitute the updated list of available tags. ++ if eval "sed -e 's/^available_tags=.*$/available_tags="$available_tags"/' "$ofile" > "${ofile}T""; then ++ mv "${ofile}T" "$ofile" ++ chmod +x "$ofile" ++ else ++ rm -f "${ofile}T" ++ { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 ++echo "$as_me: error: unable to update list of available tagged configurations." >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++fi ++ ++ ++ ++# This can be used to rebuild libtool when needed ++LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" ++ ++# Always use our own libtool. ++LIBTOOL='$(SHELL) $(top_builddir)/libtool' ++ ++# Prevent multiple expansion ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++# Check whether --with-readline or --without-readline was given. ++if test "${with_readline+set}" = set; then ++ withval="$with_readline" ++ use_readline=$withval ++else ++ use_readline=yes ++ ++fi; ++ ++LUA_LIBS="-lm" ++ ++# Check for readline ++READLINE_DEFS="#undef LUA_USE_READLINE" ++if test "x$use_readline" == "xyes"; then ++ ++echo "$as_me:$LINENO: checking for readline in -lreadline" >&5 ++echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6 ++if test "${ac_cv_lib_readline_readline+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lreadline -lncurses $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char readline (); ++int ++main () ++{ ++readline (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_readline_readline=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_readline_readline=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5 ++echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6 ++if test $ac_cv_lib_readline_readline = yes; then ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_LIBREADLINE 1 ++_ACEOF ++ ++ LIBS="-lreadline -lncurses $LIBS" ++ ++else ++ use_readline=no ++fi ++ ++ ++ ++for ac_header in readline/readline.h readline/history.h ++do ++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` ++if eval "test "${$as_ac_Header+set}" = set"; then ++ echo "$as_me:$LINENO: checking for $ac_header" >&5 ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 ++if eval "test "${$as_ac_Header+set}" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++fi ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 ++else ++ # Is the header compilable? ++echo "$as_me:$LINENO: checking $ac_header usability" >&5 ++echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++#include <$ac_header> ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: "$ac_compile"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: "$ac_try"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_header_compiler=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_header_compiler=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 ++echo "${ECHO_T}$ac_header_compiler" >&6 ++ ++# Is the header present? ++echo "$as_me:$LINENO: checking $ac_header presence" >&5 ++echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include <$ac_header> ++_ACEOF ++if { (eval echo "$as_me:$LINENO: "$ac_cpp conftest.$ac_ext"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: $? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ ac_header_preproc=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_header_preproc=no ++fi ++rm -f conftest.err conftest.$ac_ext ++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 ++echo "${ECHO_T}$ac_header_preproc" >&6 ++ ++# So? What about this header? ++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in ++ yes:no: ) ++ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 ++echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 ++echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ++ ac_header_preproc=yes ++ ;; ++ no:yes:* ) ++ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 ++echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 ++echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 ++echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: section "Present But Cannot Be Compiled"" >&5 ++echo "$as_me: WARNING: $ac_header: section "Present But Cannot Be Compiled"" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 ++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} ++ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 ++echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ++ ( ++ cat <<_ASBOX ++## ------------------------------------------- ## ++## Report this to the Autotoolized Lua lists. ## ++## ------------------------------------------- ## ++_ASBOX ++ ) | ++ sed "s/^/$as_me: WARNING: /" >&2 ++ ;; ++esac ++echo "$as_me:$LINENO: checking for $ac_header" >&5 ++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 ++if eval "test "${$as_ac_Header+set}" = set"; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ eval "$as_ac_Header=$ac_header_preproc" ++fi ++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 ++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 ++ ++fi ++if test `eval echo '${'$as_ac_Header'}'` = yes; then ++ cat >>confdefs.h <<_ACEOF ++#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 ++_ACEOF ++ ++else ++ use_readline=no ++fi ++ ++done ++ ++ if test "x$use_readline" == "xno"; then ++ { echo "$as_me:$LINENO: WARNING: readline headers could not be found, disabling readline support" >&5 ++echo "$as_me: WARNING: readline headers could not be found, disabling readline support" >&2;} ++ else ++ READLINE_DEFS="#define LUA_USE_READLINE" ++ LUA_LIBS="$LUA_LIBS -lreadline -lncurses" ++ fi ++fi ++ ++ ++case "$host" in ++ *-mingw*) use_os=win32 ;; ++ *-darwin*) use_os=macosx ;; ++ *) use_os=posix ;; ++esac ++ ++POSIX_DEFS="#undef LUA_USE_POSIX" ++LUA_DL_DEFS="#undef LUA_USE_DLOPEN" ++LUA_BUILD_AS_DLL_DEFS="#undef LUA_BUILD_AS_DLL" ++ ++if test "x$use_os" == "xwin32"; then ++ LUA_BUILD_AS_DLL_DEFS="#define LUA_BUILD_AS_DLL" ++elif test "x$use_os" == "xmacosx"; then ++ POSIX_DEFS="#define LUA_USE_POSIX" ++ LUA_DL_DEFS="#define LUA_DL_DYLD" ++elif test "x$use_os" == "xposix"; then ++ POSIX_DEFS="#define LUA_USE_POSIX" ++ LUA_DL_DEFS="#define LUA_DL_DLOPEN" ++ LUA_LIBS="$LUA_LIBS -ldl" ++fi ++ ++ ++ ++ ++ ++ ++ ac_config_files="$ac_config_files Makefile src/Makefile src/luaconf.h.template etc/Makefile etc/lua.pc doc/Makefile test/Makefile" ++ ++cat >confcache <<_ACEOF ++# This file is a shell script that caches the results of configure ++# tests run on this system so they can be shared between configure ++# scripts and configure runs, see configure's option --config-cache. ++# It is not useful on other systems. If it contains results you don't ++# want to keep, you may remove or edit it. ++# ++# config.status only pays attention to the cache file if you give it ++# the --recheck option to rerun configure. ++# ++# `ac_cv_env_foo' variables (set or unset) will be overridden when ++# loading this file, other *unset* `ac_cv_foo' will be assigned the ++# following values. ++ ++_ACEOF ++ ++# The following way of writing the cache mishandles newlines in values, ++# but we know of no workaround that is simple, portable, and efficient. ++# So, don't put newlines in cache variables' values. ++# Ultrix sh set writes to stderr and can't be redirected directly, ++# and sets the high bit in the cache file unless we assign to the vars. ++{ ++ (set) 2>&1 | ++ case `(ac_space=' '; set | grep ac_space) 2>&1` in ++ *ac_space=\ *) ++ # `set' does not quote correctly, so add quotes (double-quote ++ # substitution turns \\ into \, and sed turns \ into ). ++ sed -n \ ++ "s/'/'\\''/g; ++ s/^\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\)=\(.*\)/\1='\2'/p" ++ ;; ++ *) ++ # `set' quotes correctly as required by POSIX, so do not add quotes. ++ sed -n \ ++ "s/^\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\)=\(.*\)/\1=\2/p" ++ ;; ++ esac; ++} | ++ sed ' ++ t clear ++ : clear ++ s/^([^=]*)=(.*[{}].*)$/test "${\1+set}" = set || &/ ++ t end ++ /^ac_cv_env/!s/^([^=]*)=(.*)$/\1=${\1=\2}/ ++ : end' >>confcache ++if diff $cache_file confcache >/dev/null 2>&1; then :; else ++ if test -w $cache_file; then ++ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" ++ cat confcache >$cache_file ++ else ++ echo "not updating unwritable cache $cache_file" ++ fi ++fi ++rm -f confcache ++ ++test "x$prefix" = xNONE && prefix=$ac_default_prefix ++# Let make expand exec_prefix. ++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' ++ ++# VPATH may cause trouble with some makes, so we remove $(srcdir), ++# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and ++# trailing colons and then remove the whole line if VPATH becomes empty ++# (actually we leave an empty line to preserve line numbers). ++if test "x$srcdir" = x.; then ++ ac_vpsub='/^[ ]*VPATH[ ]*=/{ ++s/:*$(srcdir):*/:/; ++s/:*${srcdir}:*/:/; ++s/:*@srcdir@:*/:/; ++s/^([^=]*=[ ]*):*/\1/; ++s/:*$//; ++s/^[^=]*=[ ]*$//; ++}' ++fi ++ ++DEFS=-DHAVE_CONFIG_H ++ ++ac_libobjs= ++ac_ltlibobjs= ++for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue ++ # 1. Remove the extension, and $U if already installed. ++ ac_i=`echo "$ac_i" | ++ sed 's/$U././;s/.o$//;s/.obj$//'` ++ # 2. Add them. ++ ac_libobjs="$ac_libobjs $ac_i$U.$ac_objext" ++ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' ++done ++LIBOBJS=$ac_libobjs ++ ++LTLIBOBJS=$ac_ltlibobjs ++ ++ ++if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then ++ { { echo "$as_me:$LINENO: error: conditional "AMDEP" was never defined. ++Usually this means the macro was only invoked conditionally." >&5 ++echo "$as_me: error: conditional "AMDEP" was never defined. ++Usually this means the macro was only invoked conditionally." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then ++ { { echo "$as_me:$LINENO: error: conditional "am__fastdepCC" was never defined. ++Usually this means the macro was only invoked conditionally." >&5 ++echo "$as_me: error: conditional "am__fastdepCC" was never defined. ++Usually this means the macro was only invoked conditionally." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then ++ { { echo "$as_me:$LINENO: error: conditional "am__fastdepCXX" was never defined. ++Usually this means the macro was only invoked conditionally." >&5 ++echo "$as_me: error: conditional "am__fastdepCXX" was never defined. ++Usually this means the macro was only invoked conditionally." >&2;} ++ { (exit 1); exit 1; }; } ++fi ++ ++: ${CONFIG_STATUS=./config.status} ++ac_clean_files_save=$ac_clean_files ++ac_clean_files="$ac_clean_files $CONFIG_STATUS" ++{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 ++echo "$as_me: creating $CONFIG_STATUS" >&6;} ++cat >$CONFIG_STATUS <<_ACEOF ++#! $SHELL ++# Generated by $as_me. ++# Run this file to recreate the current configuration. ++# Compiler output produced by configure, useful for debugging ++# configure, is in config.log if it exists. ++ ++debug=false ++ac_cs_recheck=false ++ac_cs_silent=false ++SHELL=${CONFIG_SHELL-$SHELL} ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++## --------------------- ## ++## M4sh Initialization. ## ++## --------------------- ## ++ ++# Be Bourne compatible ++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then ++ emulate sh ++ NULLCMD=: ++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which ++ # is contrary to our usage. Disable this feature. ++ alias -g '${1+"$@"}'='"$@"' ++elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then ++ set -o posix ++fi ++DUALCASE=1; export DUALCASE # for MKS sh ++ ++# Support unset when possible. ++if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then ++ as_unset=unset ++else ++ as_unset=false ++fi ++ ++ ++# Work around bugs in pre-3.0 UWIN ksh. ++$as_unset ENV MAIL MAILPATH ++PS1='$ ' ++PS2='> ' ++PS4='+ ' ++ ++# NLS nuisances. ++for as_var in \ ++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ ++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ ++ LC_TELEPHONE LC_TIME ++do ++ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then ++ eval $as_var=C; export $as_var ++ else ++ $as_unset $as_var ++ fi ++done ++ ++# Required to use basename. ++if expr a : '(a)' >/dev/null 2>&1; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then ++ as_basename=basename ++else ++ as_basename=false ++fi ++ ++ ++# Name of the executable. ++as_me=`$as_basename "$0" || ++$as_expr X/"$0" : '.*/([^/][^/]*)/*$' | \ ++ X"$0" : 'X(//)$' | \ ++ X"$0" : 'X(/)$' | \ ++ . : '(.)' 2>/dev/null || ++echo X/"$0" | ++ sed '/^.*/([^/][^/]*)/*$/{ s//\1/; q; } ++ /^X/(//)$/{ s//\1/; q; } ++ /^X/(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ ++ ++# PATH needs CR, and LINENO needs CR and PATH. ++# Avoid depending upon Character Ranges. ++as_cr_letters='abcdefghijklmnopqrstuvwxyz' ++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ++as_cr_Letters=$as_cr_letters$as_cr_LETTERS ++as_cr_digits='0123456789' ++as_cr_alnum=$as_cr_Letters$as_cr_digits ++ ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ echo "#! /bin/sh" >conf$$.sh ++ echo "exit 0" >>conf$$.sh ++ chmod +x conf$$.sh ++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then ++ PATH_SEPARATOR=';' ++ else ++ PATH_SEPARATOR=: ++ fi ++ rm -f conf$$.sh ++fi ++ ++ ++ as_lineno_1=$LINENO ++ as_lineno_2=$LINENO ++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` ++ test "x$as_lineno_1" != "x$as_lineno_2" && ++ test "x$as_lineno_3" = "x$as_lineno_2" || { ++ # Find who we are. Look in the path if we contain no path at all ++ # relative or not. ++ case $0 in ++ *[\/]* ) as_myself=$0 ;; ++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break ++done ++ ++ ;; ++ esac ++ # We did not find ourselves, most probably we were run as `sh COMMAND' ++ # in which case we are not to be found in the path. ++ if test "x$as_myself" = x; then ++ as_myself=$0 ++ fi ++ if test ! -f "$as_myself"; then ++ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 ++echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} ++ { (exit 1); exit 1; }; } ++ fi ++ case $CONFIG_SHELL in ++ '') ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for as_base in sh bash ksh sh5; do ++ case $as_dir in ++ /*) ++ if ("$as_dir/$as_base" -c ' ++ as_lineno_1=$LINENO ++ as_lineno_2=$LINENO ++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` ++ test "x$as_lineno_1" != "x$as_lineno_2" && ++ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then ++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } ++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } ++ CONFIG_SHELL=$as_dir/$as_base ++ export CONFIG_SHELL ++ exec "$CONFIG_SHELL" "$0" ${1+"$@"} ++ fi;; ++ esac ++ done ++done ++;; ++ esac ++ ++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO ++ # uniformly replaced by the line number. The first 'sed' inserts a ++ # line-number line before each line; the second 'sed' does the real ++ # work. The second script uses 'N' to pair each line-number line ++ # with the numbered line, and appends trailing '-' during ++ # substitution so that $LINENO is not a special case at line end. ++ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the ++ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) ++ sed '=' <$as_myself | ++ sed ' ++ N ++ s,$,-, ++ : loop ++ s,^(['$as_cr_digits']*)(.*)[$]LINENO([^'$as_cr_alnum'_]),\1\2\1\3, ++ t loop ++ s,-$,, ++ s,^['$as_cr_digits']*\n,, ++ ' >$as_me.lineno && ++ chmod +x $as_me.lineno || ++ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 ++echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} ++ { (exit 1); exit 1; }; } ++ ++ # Don't try to exec as it changes $[0], causing all sort of problems ++ # (the dirname of $[0] is not the place where we might find the ++ # original and so on. Autoconf is especially sensible to this). ++ . ./$as_me.lineno ++ # Exit status is that of the last command. ++ exit ++} ++ ++ ++case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in ++ *c*,-n*) ECHO_N= ECHO_C=' ++' ECHO_T=' ' ;; ++ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; ++ *) ECHO_N= ECHO_C='\c' ECHO_T= ;; ++esac ++ ++if expr a : '(a)' >/dev/null 2>&1; then ++ as_expr=expr ++else ++ as_expr=false ++fi ++ ++rm -f conf$$ conf$$.exe conf$$.file ++echo >conf$$.file ++if ln -s conf$$.file conf$$ 2>/dev/null; then ++ # We could just check for DJGPP; but this test a) works b) is more generic ++ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). ++ if test -f conf$$.exe; then ++ # Don't use ln at all; we don't have any links ++ as_ln_s='cp -p' ++ else ++ as_ln_s='ln -s' ++ fi ++elif ln conf$$.file conf$$ 2>/dev/null; then ++ as_ln_s=ln ++else ++ as_ln_s='cp -p' ++fi ++rm -f conf$$ conf$$.exe conf$$.file ++ ++if mkdir -p . 2>/dev/null; then ++ as_mkdir_p=: ++else ++ test -d ./-p && rmdir ./-p ++ as_mkdir_p=false ++fi ++ ++as_executable_p="test -f" ++ ++# Sed expression to map a string onto a valid CPP name. ++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" ++ ++# Sed expression to map a string onto a valid variable name. ++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" ++ ++ ++# IFS ++# We need space, tab and new line, in precisely that order. ++as_nl=' ++' ++IFS=" $as_nl" ++ ++# CDPATH. ++$as_unset CDPATH ++ ++exec 6>&1 ++ ++# Open the log real soon, to keep $[0] and so on meaningful, and to ++# report actual input values of CONFIG_FILES etc. instead of their ++# values after options handling. Logging --version etc. is OK. ++exec 5>>config.log ++{ ++ echo ++ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ++## Running $as_me. ## ++_ASBOX ++} >&5 ++cat >&5 <<_CSEOF ++ ++This file was extended by Autotoolized Lua $as_me 5.1.3, which was ++generated by GNU Autoconf 2.59. Invocation command line was ++ ++ CONFIG_FILES = $CONFIG_FILES ++ CONFIG_HEADERS = $CONFIG_HEADERS ++ CONFIG_LINKS = $CONFIG_LINKS ++ CONFIG_COMMANDS = $CONFIG_COMMANDS ++ $ $0 $@ ++ ++_CSEOF ++echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 ++echo >&5 ++_ACEOF ++ ++# Files that config.status was made for. ++if test -n "$ac_config_files"; then ++ echo "config_files="$ac_config_files"" >>$CONFIG_STATUS ++fi ++ ++if test -n "$ac_config_headers"; then ++ echo "config_headers="$ac_config_headers"" >>$CONFIG_STATUS ++fi ++ ++if test -n "$ac_config_links"; then ++ echo "config_links="$ac_config_links"" >>$CONFIG_STATUS ++fi ++ ++if test -n "$ac_config_commands"; then ++ echo "config_commands="$ac_config_commands"" >>$CONFIG_STATUS ++fi ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++ ++ac_cs_usage="\ ++`$as_me' instantiates files from templates according to the ++current configuration. ++ ++Usage: $0 [OPTIONS] [FILE]... ++ ++ -h, --help print this help, then exit ++ -V, --version print version number, then exit ++ -q, --quiet do not print progress messages ++ -d, --debug don't remove temporary files ++ --recheck update $as_me by reconfiguring in the same conditions ++ --file=FILE[:TEMPLATE] ++ instantiate the configuration file FILE ++ --header=FILE[:TEMPLATE] ++ instantiate the configuration header FILE ++ ++Configuration files: ++$config_files ++ ++Configuration headers: ++$config_headers ++ ++Configuration commands: ++$config_commands ++ ++Report bugs to <bug-autoconf@gnu.org>." ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++ac_cs_version="\ ++Autotoolized Lua config.status 5.1.3 ++configured by $0, generated by GNU Autoconf 2.59, ++ with options \"`echo "$ac_configure_args" | sed 's/[\""`$]/\\&/g'`\" ++ ++Copyright (C) 2003 Free Software Foundation, Inc. ++This config.status script is free software; the Free Software Foundation ++gives unlimited permission to copy, distribute and modify it." ++srcdir=$srcdir ++INSTALL="$INSTALL" ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++# If no file are specified by the user, then we need to provide default ++# value. By we need to know if files were specified by the user. ++ac_need_defaults=: ++while test $# != 0 ++do ++ case $1 in ++ --*=*) ++ ac_option=`expr "x$1" : 'x([^=]*)='` ++ ac_optarg=`expr "x$1" : 'x[^=]*=(.*)'` ++ ac_shift=: ++ ;; ++ -*) ++ ac_option=$1 ++ ac_optarg=$2 ++ ac_shift=shift ++ ;; ++ *) # This is not an option, so the user has probably given explicit ++ # arguments. ++ ac_option=$1 ++ ac_need_defaults=false;; ++ esac ++ ++ case $ac_option in ++ # Handling of the options. ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF ++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ++ ac_cs_recheck=: ;; ++ --version | --vers* | -V ) ++ echo "$ac_cs_version"; exit 0 ;; ++ --he | --h) ++ # Conflict between --help and --header ++ { { echo "$as_me:$LINENO: error: ambiguous option: $1 ++Try `$0 --help' for more information." >&5 ++echo "$as_me: error: ambiguous option: $1 ++Try `$0 --help' for more information." >&2;} ++ { (exit 1); exit 1; }; };; ++ --help | --hel | -h ) ++ echo "$ac_cs_usage"; exit 0 ;; ++ --debug | --d* | -d ) ++ debug=: ;; ++ --file | --fil | --fi | --f ) ++ $ac_shift ++ CONFIG_FILES="$CONFIG_FILES $ac_optarg" ++ ac_need_defaults=false;; ++ --header | --heade | --head | --hea ) ++ $ac_shift ++ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ++ ac_need_defaults=false;; ++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ ++ | -silent | --silent | --silen | --sile | --sil | --si | --s) ++ ac_cs_silent=: ;; ++ ++ # This is an error. ++ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 ++Try `$0 --help' for more information." >&5 ++echo "$as_me: error: unrecognized option: $1 ++Try `$0 --help' for more information." >&2;} ++ { (exit 1); exit 1; }; } ;; ++ ++ *) ac_config_targets="$ac_config_targets $1" ;; ++ ++ esac ++ shift ++done ++ ++ac_configure_extra_args= ++ ++if $ac_cs_silent; then ++ exec 6>/dev/null ++ ac_configure_extra_args="$ac_configure_extra_args --silent" ++fi ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF ++if $ac_cs_recheck; then ++ echo "running $SHELL $0 " $ac_configure_args $ac_configure_extra_args " --no-create --no-recursion" >&6 ++ exec $SHELL $0 $ac_configure_args $ac_configure_extra_args --no-create --no-recursion ++fi ++ ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++# ++# INIT-COMMANDS section. ++# ++ ++AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" ++ ++_ACEOF ++ ++ ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++for ac_config_target in $ac_config_targets ++do ++ case "$ac_config_target" in ++ # Handling of arguments. ++ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; ++ "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; ++ "src/luaconf.h.template" ) CONFIG_FILES="$CONFIG_FILES src/luaconf.h.template" ;; ++ "etc/Makefile" ) CONFIG_FILES="$CONFIG_FILES etc/Makefile" ;; ++ "etc/lua.pc" ) CONFIG_FILES="$CONFIG_FILES etc/lua.pc" ;; ++ "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; ++ "test/Makefile" ) CONFIG_FILES="$CONFIG_FILES test/Makefile" ;; ++ "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; ++ "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; ++ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 ++echo "$as_me: error: invalid argument: $ac_config_target" >&2;} ++ { (exit 1); exit 1; }; };; ++ esac ++done ++ ++# If the user did not use the arguments to specify the items to instantiate, ++# then the envvar interface is used. Set only those that are not. ++# We use the long form for the default assignment because of an extremely ++# bizarre bug on SunOS 4.1.3. ++if $ac_need_defaults; then ++ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files ++ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers ++ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands ++fi ++ ++# Have a temporary directory for convenience. Make it in the build tree ++# simply because there is no reason to put it here, and in addition, ++# creating and moving files from /tmp can sometimes cause problems. ++# Create a temporary directory, and hook for its removal unless debugging. ++$debug || ++{ ++ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 ++ trap '{ (exit 1); exit 1; }' 1 2 13 15 ++} ++ ++# Create a (secure) tmp directory for tmp files. ++ ++{ ++ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && ++ test -n "$tmp" && test -d "$tmp" ++} || ++{ ++ tmp=./confstat$$-$RANDOM ++ (umask 077 && mkdir $tmp) ++} || ++{ ++ echo "$me: cannot create a temporary directory in ." >&2 ++ { (exit 1); exit 1; } ++} ++ ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++ ++# ++# CONFIG_FILES section. ++# ++ ++# No need to generate the scripts if there are no CONFIG_FILES. ++# This happens for instance when ./config.status config.h ++if test -n "$CONFIG_FILES"; then ++ # Protect against being on the right side of a sed subst in config.status. ++ sed 's/,@/@@/; s/@,/@@/; s/,;t t$/@;t t/; /@;t t$/s/[\\&,]/\\&/g; ++ s/@@/,@/; s/@@/@,/; s/@;t t$/,;t t/' >$tmp/subs.sed <<\CEOF ++s,@SHELL@,$SHELL,;t t ++s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t ++s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t ++s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t ++s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t ++s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t ++s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t ++s,@exec_prefix@,$exec_prefix,;t t ++s,@prefix@,$prefix,;t t ++s,@program_transform_name@,$program_transform_name,;t t ++s,@bindir@,$bindir,;t t ++s,@sbindir@,$sbindir,;t t ++s,@libexecdir@,$libexecdir,;t t ++s,@datadir@,$datadir,;t t ++s,@sysconfdir@,$sysconfdir,;t t ++s,@sharedstatedir@,$sharedstatedir,;t t ++s,@localstatedir@,$localstatedir,;t t ++s,@libdir@,$libdir,;t t ++s,@includedir@,$includedir,;t t ++s,@oldincludedir@,$oldincludedir,;t t ++s,@infodir@,$infodir,;t t ++s,@mandir@,$mandir,;t t ++s,@build_alias@,$build_alias,;t t ++s,@host_alias@,$host_alias,;t t ++s,@target_alias@,$target_alias,;t t ++s,@DEFS@,$DEFS,;t t ++s,@ECHO_C@,$ECHO_C,;t t ++s,@ECHO_N@,$ECHO_N,;t t ++s,@ECHO_T@,$ECHO_T,;t t ++s,@LIBS@,$LIBS,;t t ++s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t ++s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t ++s,@INSTALL_DATA@,$INSTALL_DATA,;t t ++s,@CYGPATH_W@,$CYGPATH_W,;t t ++s,@PACKAGE@,$PACKAGE,;t t ++s,@VERSION@,$VERSION,;t t ++s,@ACLOCAL@,$ACLOCAL,;t t ++s,@AUTOCONF@,$AUTOCONF,;t t ++s,@AUTOMAKE@,$AUTOMAKE,;t t ++s,@AUTOHEADER@,$AUTOHEADER,;t t ++s,@MAKEINFO@,$MAKEINFO,;t t ++s,@install_sh@,$install_sh,;t t ++s,@STRIP@,$STRIP,;t t ++s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t ++s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t ++s,@mkdir_p@,$mkdir_p,;t t ++s,@AWK@,$AWK,;t t ++s,@SET_MAKE@,$SET_MAKE,;t t ++s,@am__leading_dot@,$am__leading_dot,;t t ++s,@AMTAR@,$AMTAR,;t t ++s,@am__tar@,$am__tar,;t t ++s,@am__untar@,$am__untar,;t t ++s,@CC@,$CC,;t t ++s,@CFLAGS@,$CFLAGS,;t t ++s,@LDFLAGS@,$LDFLAGS,;t t ++s,@CPPFLAGS@,$CPPFLAGS,;t t ++s,@ac_ct_CC@,$ac_ct_CC,;t t ++s,@EXEEXT@,$EXEEXT,;t t ++s,@OBJEXT@,$OBJEXT,;t t ++s,@DEPDIR@,$DEPDIR,;t t ++s,@am__include@,$am__include,;t t ++s,@am__quote@,$am__quote,;t t ++s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t ++s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t ++s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t ++s,@CCDEPMODE@,$CCDEPMODE,;t t ++s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t ++s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t ++s,@build@,$build,;t t ++s,@build_cpu@,$build_cpu,;t t ++s,@build_vendor@,$build_vendor,;t t ++s,@build_os@,$build_os,;t t ++s,@host@,$host,;t t ++s,@host_cpu@,$host_cpu,;t t ++s,@host_vendor@,$host_vendor,;t t ++s,@host_os@,$host_os,;t t ++s,@EGREP@,$EGREP,;t t ++s,@LN_S@,$LN_S,;t t ++s,@ECHO@,$ECHO,;t t ++s,@AR@,$AR,;t t ++s,@ac_ct_AR@,$ac_ct_AR,;t t ++s,@RANLIB@,$RANLIB,;t t ++s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t ++s,@CPP@,$CPP,;t t ++s,@CXX@,$CXX,;t t ++s,@CXXFLAGS@,$CXXFLAGS,;t t ++s,@ac_ct_CXX@,$ac_ct_CXX,;t t ++s,@CXXDEPMODE@,$CXXDEPMODE,;t t ++s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t ++s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t ++s,@CXXCPP@,$CXXCPP,;t t ++s,@F77@,$F77,;t t ++s,@FFLAGS@,$FFLAGS,;t t ++s,@ac_ct_F77@,$ac_ct_F77,;t t ++s,@LIBTOOL@,$LIBTOOL,;t t ++s,@READLINE_DEFS@,$READLINE_DEFS,;t t ++s,@POSIX_DEFS@,$POSIX_DEFS,;t t ++s,@LUA_DL_DEFS@,$LUA_DL_DEFS,;t t ++s,@LUA_BUILD_AS_DLL_DEFS@,$LUA_BUILD_AS_DLL_DEFS,;t t ++s,@LUA_LIBS@,$LUA_LIBS,;t t ++s,@LIBOBJS@,$LIBOBJS,;t t ++s,@LTLIBOBJS@,$LTLIBOBJS,;t t ++CEOF ++ ++_ACEOF ++ ++ cat >>$CONFIG_STATUS <<_ACEOF ++ # Split the substitutions into bite-sized pieces for seds with ++ # small command number limits, like on Digital OSF/1 and HP-UX. ++ ac_max_sed_lines=48 ++ ac_sed_frag=1 # Number of current file. ++ ac_beg=1 # First line for current file. ++ ac_end=$ac_max_sed_lines # Line after last line for current file. ++ ac_more_lines=: ++ ac_sed_cmds= ++ while $ac_more_lines; do ++ if test $ac_beg -gt 1; then ++ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag ++ else ++ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag ++ fi ++ if test ! -s $tmp/subs.frag; then ++ ac_more_lines=false ++ else ++ # The purpose of the label and of the branching condition is to ++ # speed up the sed processing (if there are no `@' at all, there ++ # is no need to browse any of the substitutions). ++ # These are the two extra sed commands mentioned above. ++ (echo ':t ++ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed ++ if test -z "$ac_sed_cmds"; then ++ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" ++ else ++ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" ++ fi ++ ac_sed_frag=`expr $ac_sed_frag + 1` ++ ac_beg=$ac_end ++ ac_end=`expr $ac_end + $ac_max_sed_lines` ++ fi ++ done ++ if test -z "$ac_sed_cmds"; then ++ ac_sed_cmds=cat ++ fi ++fi # test -n "$CONFIG_FILES" ++ ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF ++for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue ++ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". ++ case $ac_file in ++ - | *:- | *:-:* ) # input from stdin ++ cat >$tmp/stdin ++ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; ++ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; ++ * ) ac_file_in=$ac_file.in ;; ++ esac ++ ++ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ++ ac_dir=`(dirname "$ac_file") 2>/dev/null || ++$as_expr X"$ac_file" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$ac_file" : 'X(//)[^/]' | \ ++ X"$ac_file" : 'X(//)$' | \ ++ X"$ac_file" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$ac_file" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ { if $as_mkdir_p; then ++ mkdir -p "$ac_dir" ++ else ++ as_dir="$ac_dir" ++ as_dirs= ++ while test ! -d "$as_dir"; do ++ as_dirs="$as_dir $as_dirs" ++ as_dir=`(dirname "$as_dir") 2>/dev/null || ++$as_expr X"$as_dir" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$as_dir" : 'X(//)[^/]' | \ ++ X"$as_dir" : 'X(//)$' | \ ++ X"$as_dir" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$as_dir" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ done ++ test ! -n "$as_dirs" || mkdir $as_dirs ++ fi || { { echo "$as_me:$LINENO: error: cannot create directory "$ac_dir"" >&5 ++echo "$as_me: error: cannot create directory "$ac_dir"" >&2;} ++ { (exit 1); exit 1; }; }; } ++ ++ ac_builddir=. ++ ++if test "$ac_dir" != .; then ++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^.[\/],,'` ++ # A "../" for each directory in $ac_dir_suffix. ++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\/]*,../,g'` ++else ++ ac_dir_suffix= ac_top_builddir= ++fi ++ ++case $srcdir in ++ .) # No --srcdir option. We are building in place. ++ ac_srcdir=. ++ if test -z "$ac_top_builddir"; then ++ ac_top_srcdir=. ++ else ++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` ++ fi ;; ++ [\/]* | ?:[\/]* ) # Absolute path. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ;; ++ *) # Relative path. ++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_builddir$srcdir ;; ++esac ++ ++# Do not use `cd foo && pwd` to compute absolute paths, because ++# the directories may not exist. ++case `pwd` in ++.) ac_abs_builddir="$ac_dir";; ++*) ++ case "$ac_dir" in ++ .) ac_abs_builddir=`pwd`;; ++ [\/]* | ?:[\/]* ) ac_abs_builddir="$ac_dir";; ++ *) ac_abs_builddir=`pwd`/"$ac_dir";; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_builddir=${ac_top_builddir}.;; ++*) ++ case ${ac_top_builddir}. in ++ .) ac_abs_top_builddir=$ac_abs_builddir;; ++ [\/]* | ?:[\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; ++ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_srcdir=$ac_srcdir;; ++*) ++ case $ac_srcdir in ++ .) ac_abs_srcdir=$ac_abs_builddir;; ++ [\/]* | ?:[\/]* ) ac_abs_srcdir=$ac_srcdir;; ++ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_srcdir=$ac_top_srcdir;; ++*) ++ case $ac_top_srcdir in ++ .) ac_abs_top_srcdir=$ac_abs_builddir;; ++ [\/]* | ?:[\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; ++ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; ++ esac;; ++esac ++ ++ ++ case $INSTALL in ++ [\/$]* | ?:[\/]* ) ac_INSTALL=$INSTALL ;; ++ *) ac_INSTALL=$ac_top_builddir$INSTALL ;; ++ esac ++ ++ if test x"$ac_file" != x-; then ++ { echo "$as_me:$LINENO: creating $ac_file" >&5 ++echo "$as_me: creating $ac_file" >&6;} ++ rm -f "$ac_file" ++ fi ++ # Let's still pretend it is `configure' which instantiates (i.e., don't ++ # use $as_me), people would be surprised to read: ++ # /* config.h. Generated by config.status. */ ++ if test x"$ac_file" = x-; then ++ configure_input= ++ else ++ configure_input="$ac_file. " ++ fi ++ configure_input=$configure_input"Generated from `echo $ac_file_in | ++ sed 's,.*/,,'` by configure." ++ ++ # First look for the input files in the build tree, otherwise in the ++ # src tree. ++ ac_file_inputs=`IFS=: ++ for f in $ac_file_in; do ++ case $f in ++ -) echo $tmp/stdin ;; ++ [\/$]*) ++ # Absolute (can't be DOS-style, as IFS=:) ++ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 ++echo "$as_me: error: cannot find input file: $f" >&2;} ++ { (exit 1); exit 1; }; } ++ echo "$f";; ++ *) # Relative ++ if test -f "$f"; then ++ # Build tree ++ echo "$f" ++ elif test -f "$srcdir/$f"; then ++ # Source tree ++ echo "$srcdir/$f" ++ else ++ # /dev/null tree ++ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 ++echo "$as_me: error: cannot find input file: $f" >&2;} ++ { (exit 1); exit 1; }; } ++ fi;; ++ esac ++ done` || { (exit 1); exit 1; } ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF ++ sed "$ac_vpsub ++$extrasub ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF ++:t ++/@[a-zA-Z_][a-zA-Z_0-9]*@/!b ++s,@configure_input@,$configure_input,;t t ++s,@srcdir@,$ac_srcdir,;t t ++s,@abs_srcdir@,$ac_abs_srcdir,;t t ++s,@top_srcdir@,$ac_top_srcdir,;t t ++s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t ++s,@builddir@,$ac_builddir,;t t ++s,@abs_builddir@,$ac_abs_builddir,;t t ++s,@top_builddir@,$ac_top_builddir,;t t ++s,@abs_top_builddir@,$ac_abs_top_builddir,;t t ++s,@INSTALL@,$ac_INSTALL,;t t ++" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out ++ rm -f $tmp/stdin ++ if test x"$ac_file" != x-; then ++ mv $tmp/out $ac_file ++ else ++ cat $tmp/out ++ rm -f $tmp/out ++ fi ++ ++done ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF ++ ++# ++# CONFIG_HEADER section. ++# ++ ++# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where ++# NAME is the cpp macro being defined and VALUE is the value it is being given. ++# ++# ac_d sets the value in "#define NAME VALUE" lines. ++ac_dA='s,^([ ]*)#([ ]*define[ ][ ]*)' ++ac_dB='[ ].*$,\1#\2' ++ac_dC=' ' ++ac_dD=',;t' ++# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ++ac_uA='s,^([ ]*)#([ ]*)undef([ ][ ]*)' ++ac_uB='$,\1#\2define\3' ++ac_uC=' ' ++ac_uD=',;t' ++ ++for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue ++ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". ++ case $ac_file in ++ - | *:- | *:-:* ) # input from stdin ++ cat >$tmp/stdin ++ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; ++ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; ++ * ) ac_file_in=$ac_file.in ;; ++ esac ++ ++ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 ++echo "$as_me: creating $ac_file" >&6;} ++ ++ # First look for the input files in the build tree, otherwise in the ++ # src tree. ++ ac_file_inputs=`IFS=: ++ for f in $ac_file_in; do ++ case $f in ++ -) echo $tmp/stdin ;; ++ [\/$]*) ++ # Absolute (can't be DOS-style, as IFS=:) ++ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 ++echo "$as_me: error: cannot find input file: $f" >&2;} ++ { (exit 1); exit 1; }; } ++ # Do quote $f, to prevent DOS paths from being IFS'd. ++ echo "$f";; ++ *) # Relative ++ if test -f "$f"; then ++ # Build tree ++ echo "$f" ++ elif test -f "$srcdir/$f"; then ++ # Source tree ++ echo "$srcdir/$f" ++ else ++ # /dev/null tree ++ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 ++echo "$as_me: error: cannot find input file: $f" >&2;} ++ { (exit 1); exit 1; }; } ++ fi;; ++ esac ++ done` || { (exit 1); exit 1; } ++ # Remove the trailing spaces. ++ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in ++ ++_ACEOF ++ ++# Transform confdefs.h into two sed scripts, `conftest.defines' and ++# `conftest.undefs', that substitutes the proper values into ++# config.h.in to produce config.h. The first handles `#define' ++# templates, and the second `#undef' templates. ++# And first: Protect against being on the right side of a sed subst in ++# config.status. Protect against being in an unquoted here document ++# in config.status. ++rm -f conftest.defines conftest.undefs ++# Using a here document instead of a string reduces the quoting nightmare. ++# Putting comments in sed scripts is not portable. ++# ++# `end' is used to avoid that the second main sed command (meant for ++# 0-ary CPP macros) applies to n-ary macro definitions. ++# See the Autoconf documentation for `clear'. ++cat >confdef2sed.sed <<_ACEOF ++s/[\&,]/\&/g ++s,[\$`],\&,g ++t clear ++: clear ++s,^[ ]*#[ ]*define[ ][ ]*([^ (][^ (]*)(([^)]*))[ ]*(.*)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp ++t end ++s,^[ ]*#[ ]*define[ ][ ]*([^ ][^ ]*)[ ]*(.*)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp ++: end ++_ACEOF ++# If some macros were called several times there might be several times ++# the same #defines, which is useless. Nevertheless, we may not want to ++# sort them, since we want the *last* AC-DEFINE to be honored. ++uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines ++sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs ++rm -f confdef2sed.sed ++ ++# This sed command replaces #undef with comments. This is necessary, for ++# example, in the case of _POSIX_SOURCE, which is predefined and required ++# on some systems where configure will not decide to define it. ++cat >>conftest.undefs <<_ACEOF ++s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, ++_ACEOF ++ ++# Break up conftest.defines because some shells have a limit on the size ++# of here documents, and old seds have small limits too (100 cmds). ++echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS ++echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS ++echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS ++echo ' :' >>$CONFIG_STATUS ++rm -f conftest.tail ++while grep . conftest.defines >/dev/null ++do ++ # Write a limited-size here document to $tmp/defines.sed. ++ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS ++ # Speed up: don't consider the non `#define' lines. ++ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS ++ # Work around the forget-to-reset-the-flag bug. ++ echo 't clr' >>$CONFIG_STATUS ++ echo ': clr' >>$CONFIG_STATUS ++ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS ++ echo 'CEOF ++ sed -f $tmp/defines.sed $tmp/in >$tmp/out ++ rm -f $tmp/in ++ mv $tmp/out $tmp/in ++' >>$CONFIG_STATUS ++ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail ++ rm -f conftest.defines ++ mv conftest.tail conftest.defines ++done ++rm -f conftest.defines ++echo ' fi # grep' >>$CONFIG_STATUS ++echo >>$CONFIG_STATUS ++ ++# Break up conftest.undefs because some shells have a limit on the size ++# of here documents, and old seds have small limits too (100 cmds). ++echo ' # Handle all the #undef templates' >>$CONFIG_STATUS ++rm -f conftest.tail ++while grep . conftest.undefs >/dev/null ++do ++ # Write a limited-size here document to $tmp/undefs.sed. ++ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS ++ # Speed up: don't consider the non `#undef' ++ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS ++ # Work around the forget-to-reset-the-flag bug. ++ echo 't clr' >>$CONFIG_STATUS ++ echo ': clr' >>$CONFIG_STATUS ++ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS ++ echo 'CEOF ++ sed -f $tmp/undefs.sed $tmp/in >$tmp/out ++ rm -f $tmp/in ++ mv $tmp/out $tmp/in ++' >>$CONFIG_STATUS ++ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail ++ rm -f conftest.undefs ++ mv conftest.tail conftest.undefs ++done ++rm -f conftest.undefs ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++ # Let's still pretend it is `configure' which instantiates (i.e., don't ++ # use $as_me), people would be surprised to read: ++ # /* config.h. Generated by config.status. */ ++ if test x"$ac_file" = x-; then ++ echo "/* Generated by configure. */" >$tmp/config.h ++ else ++ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h ++ fi ++ cat $tmp/in >>$tmp/config.h ++ rm -f $tmp/in ++ if test x"$ac_file" != x-; then ++ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then ++ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 ++echo "$as_me: $ac_file is unchanged" >&6;} ++ else ++ ac_dir=`(dirname "$ac_file") 2>/dev/null || ++$as_expr X"$ac_file" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$ac_file" : 'X(//)[^/]' | \ ++ X"$ac_file" : 'X(//)$' | \ ++ X"$ac_file" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$ac_file" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ { if $as_mkdir_p; then ++ mkdir -p "$ac_dir" ++ else ++ as_dir="$ac_dir" ++ as_dirs= ++ while test ! -d "$as_dir"; do ++ as_dirs="$as_dir $as_dirs" ++ as_dir=`(dirname "$as_dir") 2>/dev/null || ++$as_expr X"$as_dir" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$as_dir" : 'X(//)[^/]' | \ ++ X"$as_dir" : 'X(//)$' | \ ++ X"$as_dir" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$as_dir" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ done ++ test ! -n "$as_dirs" || mkdir $as_dirs ++ fi || { { echo "$as_me:$LINENO: error: cannot create directory "$ac_dir"" >&5 ++echo "$as_me: error: cannot create directory "$ac_dir"" >&2;} ++ { (exit 1); exit 1; }; }; } ++ ++ rm -f $ac_file ++ mv $tmp/config.h $ac_file ++ fi ++ else ++ cat $tmp/config.h ++ rm -f $tmp/config.h ++ fi ++# Compute $ac_file's index in $config_headers. ++_am_stamp_count=1 ++for _am_header in $config_headers :; do ++ case $_am_header in ++ $ac_file | $ac_file:* ) ++ break ;; ++ * ) ++ _am_stamp_count=`expr $_am_stamp_count + 1` ;; ++ esac ++done ++echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || ++$as_expr X$ac_file : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X$ac_file : 'X(//)[^/]' | \ ++ X$ac_file : 'X(//)$' | \ ++ X$ac_file : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X$ac_file | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'`/stamp-h$_am_stamp_count ++done ++_ACEOF ++cat >>$CONFIG_STATUS <<_ACEOF ++ ++# ++# CONFIG_COMMANDS section. ++# ++for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue ++ ac_dest=`echo "$ac_file" | sed 's,:.*,,'` ++ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` ++ ac_dir=`(dirname "$ac_dest") 2>/dev/null || ++$as_expr X"$ac_dest" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$ac_dest" : 'X(//)[^/]' | \ ++ X"$ac_dest" : 'X(//)$' | \ ++ X"$ac_dest" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$ac_dest" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ { if $as_mkdir_p; then ++ mkdir -p "$ac_dir" ++ else ++ as_dir="$ac_dir" ++ as_dirs= ++ while test ! -d "$as_dir"; do ++ as_dirs="$as_dir $as_dirs" ++ as_dir=`(dirname "$as_dir") 2>/dev/null || ++$as_expr X"$as_dir" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$as_dir" : 'X(//)[^/]' | \ ++ X"$as_dir" : 'X(//)$' | \ ++ X"$as_dir" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$as_dir" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ done ++ test ! -n "$as_dirs" || mkdir $as_dirs ++ fi || { { echo "$as_me:$LINENO: error: cannot create directory "$ac_dir"" >&5 ++echo "$as_me: error: cannot create directory "$ac_dir"" >&2;} ++ { (exit 1); exit 1; }; }; } ++ ++ ac_builddir=. ++ ++if test "$ac_dir" != .; then ++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^.[\/],,'` ++ # A "../" for each directory in $ac_dir_suffix. ++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\/]*,../,g'` ++else ++ ac_dir_suffix= ac_top_builddir= ++fi ++ ++case $srcdir in ++ .) # No --srcdir option. We are building in place. ++ ac_srcdir=. ++ if test -z "$ac_top_builddir"; then ++ ac_top_srcdir=. ++ else ++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` ++ fi ;; ++ [\/]* | ?:[\/]* ) # Absolute path. ++ ac_srcdir=$srcdir$ac_dir_suffix; ++ ac_top_srcdir=$srcdir ;; ++ *) # Relative path. ++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ++ ac_top_srcdir=$ac_top_builddir$srcdir ;; ++esac ++ ++# Do not use `cd foo && pwd` to compute absolute paths, because ++# the directories may not exist. ++case `pwd` in ++.) ac_abs_builddir="$ac_dir";; ++*) ++ case "$ac_dir" in ++ .) ac_abs_builddir=`pwd`;; ++ [\/]* | ?:[\/]* ) ac_abs_builddir="$ac_dir";; ++ *) ac_abs_builddir=`pwd`/"$ac_dir";; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_builddir=${ac_top_builddir}.;; ++*) ++ case ${ac_top_builddir}. in ++ .) ac_abs_top_builddir=$ac_abs_builddir;; ++ [\/]* | ?:[\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; ++ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_srcdir=$ac_srcdir;; ++*) ++ case $ac_srcdir in ++ .) ac_abs_srcdir=$ac_abs_builddir;; ++ [\/]* | ?:[\/]* ) ac_abs_srcdir=$ac_srcdir;; ++ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; ++ esac;; ++esac ++case $ac_abs_builddir in ++.) ac_abs_top_srcdir=$ac_top_srcdir;; ++*) ++ case $ac_top_srcdir in ++ .) ac_abs_top_srcdir=$ac_abs_builddir;; ++ [\/]* | ?:[\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; ++ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; ++ esac;; ++esac ++ ++ ++ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 ++echo "$as_me: executing $ac_dest commands" >&6;} ++ case $ac_dest in ++ depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do ++ # Strip MF so we end up with the name of the file. ++ mf=`echo "$mf" | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile or not. ++ # We used to match only the files named `Makefile.in', but ++ # some people rename them; so instead we look at the file content. ++ # Grep'ing the first line is not enough: some people post-process ++ # each Makefile.in and add a new line on top of each file to say so. ++ # So let's grep whole file. ++ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then ++ dirpart=`(dirname "$mf") 2>/dev/null || ++$as_expr X"$mf" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$mf" : 'X(//)[^/]' | \ ++ X"$mf" : 'X(//)$' | \ ++ X"$mf" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$mf" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ else ++ continue ++ fi ++ # Extract the definition of DEPDIR, am__include, and am__quote ++ # from the Makefile without running `make'. ++ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` ++ test -z "$DEPDIR" && continue ++ am__include=`sed -n 's/^am__include = //p' < "$mf"` ++ test -z "am__include" && continue ++ am__quote=`sed -n 's/^am__quote = //p' < "$mf"` ++ # When using ansi2knr, U may be empty or an underscore; expand it ++ U=`sed -n 's/^U = //p' < "$mf"` ++ # Find all dependency output files, they are included files with ++ # $(DEPDIR) in their names. We invoke sed twice because it is the ++ # simplest approach to changing $(DEPDIR) to its actual value in the ++ # expansion. ++ for file in `sed -n " ++ s/^$am__include $am__quote(.*(DEPDIR).*)$am__quote"'$/\1/p' <"$mf" | \ ++ sed -e 's/$(DEPDIR)/'"$DEPDIR"'/g' -e 's/$U/'"$U"'/g'`; do ++ # Make sure the directory exists. ++ test -f "$dirpart/$file" && continue ++ fdir=`(dirname "$file") 2>/dev/null || ++$as_expr X"$file" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$file" : 'X(//)[^/]' | \ ++ X"$file" : 'X(//)$' | \ ++ X"$file" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$file" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ { if $as_mkdir_p; then ++ mkdir -p $dirpart/$fdir ++ else ++ as_dir=$dirpart/$fdir ++ as_dirs= ++ while test ! -d "$as_dir"; do ++ as_dirs="$as_dir $as_dirs" ++ as_dir=`(dirname "$as_dir") 2>/dev/null || ++$as_expr X"$as_dir" : 'X(.*[^/])//*[^/][^/]*/*$' | \ ++ X"$as_dir" : 'X(//)[^/]' | \ ++ X"$as_dir" : 'X(//)$' | \ ++ X"$as_dir" : 'X(/)' | \ ++ . : '(.)' 2>/dev/null || ++echo X"$as_dir" | ++ sed '/^X(.*[^/])//*[^/][^/]*/*$/{ s//\1/; q; } ++ /^X(//)[^/].*/{ s//\1/; q; } ++ /^X(//)$/{ s//\1/; q; } ++ /^X(/).*/{ s//\1/; q; } ++ s/.*/./; q'` ++ done ++ test ! -n "$as_dirs" || mkdir $as_dirs ++ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 ++echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} ++ { (exit 1); exit 1; }; }; } ++ ++ # echo "creating $dirpart/$file" ++ echo '# dummy' > "$dirpart/$file" ++ done ++done ++ ;; ++ esac ++done ++_ACEOF ++ ++cat >>$CONFIG_STATUS <<_ACEOF ++ ++{ (exit 0); exit 0; } ++_ACEOF ++chmod +x $CONFIG_STATUS ++ac_clean_files=$ac_clean_files_save ++ ++ ++# configure is writing to config.log, and then calls config.status. ++# config.status does its own redirection, appending to config.log. ++# Unfortunately, on DOS this fails, as config.log is still kept open ++# by configure, so config.status won't be able to write to it; its ++# output is simply discarded. So we exec the FD to /dev/null, ++# effectively closing config.log, so it can be properly (re)opened and ++# appended to by config.status. When coming back to configure, we ++# need to make the FD available again. ++if test "$no_create" != yes; then ++ ac_cs_success=: ++ ac_config_status_args= ++ test "$silent" = yes && ++ ac_config_status_args="$ac_config_status_args --quiet" ++ exec 5>/dev/null ++ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false ++ exec 5>>config.log ++ # Use ||, not &&, to avoid exiting from the if with $? = 1, which ++ # would make configure fail if this is the last instruction. ++ $ac_cs_success || { (exit 1); exit 1; } ++fi ++ +diff -urN lua-5.1.4/configure.ac lua-5.1.4-autotoolize/configure.ac +--- lua-5.1.4/configure.ac 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/configure.ac 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,68 @@ ++AC_PREREQ(2.59) ++AC_INIT([Autotoolized Lua], [5.1.3], [], [lua-at]) ++ ++AC_CONFIG_HEADERS([config.h]) ++AC_CONFIG_SRCDIR([src/lapi.c]) ++ ++AM_INIT_AUTOMAKE([1.9 foreign]) ++ ++AC_PROG_CC ++AC_PROG_LIBTOOL ++ ++AC_ARG_WITH( ++ [readline], ++ [AC_HELP_STRING([--with-readline], [Use readline for interpreter input [default=yes]])], ++ [use_readline=$withval], ++ [use_readline=yes] ++) ++ ++LUA_LIBS="-lm" ++ ++# Check for readline ++READLINE_DEFS="#undef LUA_USE_READLINE" ++if test "x$use_readline" == "xyes"; then ++ AC_CHECK_LIB([readline], [readline], [], [use_readline=no], [-lncurses]) ++ AC_CHECK_HEADERS([readline/readline.h readline/history.h], [], [use_readline=no]) ++ if test "x$use_readline" == "xno"; then ++ AC_MSG_WARN([readline headers could not be found, disabling readline support]) ++ else ++ READLINE_DEFS="#define LUA_USE_READLINE" ++ LUA_LIBS="$LUA_LIBS -lreadline -lncurses" ++ fi ++fi ++AC_SUBST(READLINE_DEFS) ++ ++case "$host" in ++ *-mingw*) use_os=win32 ;; ++ *-darwin*) use_os=macosx ;; ++ *) use_os=posix ;; ++esac ++ ++POSIX_DEFS="#undef LUA_USE_POSIX" ++LUA_DL_DEFS="#undef LUA_USE_DLOPEN" ++LUA_BUILD_AS_DLL_DEFS="#undef LUA_BUILD_AS_DLL" ++ ++if test "x$use_os" == "xwin32"; then ++ LUA_BUILD_AS_DLL_DEFS="#define LUA_BUILD_AS_DLL" ++elif test "x$use_os" == "xmacosx"; then ++ POSIX_DEFS="#define LUA_USE_POSIX" ++ LUA_DL_DEFS="#define LUA_DL_DYLD" ++elif test "x$use_os" == "xposix"; then ++ POSIX_DEFS="#define LUA_USE_POSIX" ++ LUA_DL_DEFS="#define LUA_DL_DLOPEN" ++ LUA_LIBS="$LUA_LIBS -ldl" ++fi ++AC_SUBST(POSIX_DEFS) ++AC_SUBST(LUA_DL_DEFS) ++AC_SUBST(LUA_BUILD_AS_DLL_DEFS) ++ ++AC_SUBST(LUA_LIBS) ++ ++AC_CONFIG_FILES([Makefile ++ src/Makefile ++ src/luaconf.h.template ++ etc/Makefile ++ etc/lua.pc ++ doc/Makefile ++ test/Makefile]) ++AC_OUTPUT +diff -urN lua-5.1.4/depcomp lua-5.1.4-autotoolize/depcomp +--- lua-5.1.4/depcomp 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/depcomp 2008-09-03 13:18:23.000000000 +0200 +@@ -0,0 +1,530 @@ ++#! /bin/sh ++# depcomp - compile a program generating dependencies as side-effects ++ ++scriptversion=2005-07-09.11 ++ ++# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2, or (at your option) ++# any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++# 02110-1301, USA. ++ ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. ++ ++case $1 in ++ '') ++ echo "$0: No command. Try `$0 --help' for more information." 1>&2 ++ exit 1; ++ ;; ++ -h | --h*) ++ cat <<\EOF ++Usage: depcomp [--help] [--version] PROGRAM [ARGS] ++ ++Run PROGRAMS ARGS to compile a file, generating dependencies ++as side-effects. ++ ++Environment variables: ++ depmode Dependency tracking mode. ++ source Source file read by `PROGRAMS ARGS'. ++ object Object file output by `PROGRAMS ARGS'. ++ DEPDIR directory where to store dependencies. ++ depfile Dependency file to output. ++ tmpdepfile Temporary file to use when outputing dependencies. ++ libtool Whether libtool is used (yes/no). ++ ++Report bugs to <bug-automake@gnu.org>. ++EOF ++ exit $? ++ ;; ++ -v | --v*) ++ echo "depcomp $scriptversion" ++ exit $? ++ ;; ++esac ++ ++if test -z "$depmode" || test -z "$source" || test -z "$object"; then ++ echo "depcomp: Variables source, object and depmode must be set" 1>&2 ++ exit 1 ++fi ++ ++# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. ++depfile=${depfile-`echo "$object" | ++ sed 's|[^\/]*$|'${DEPDIR-.deps}'/&|;s|.([^.]*)$|.P\1|;s|Pobj$|Po|'`} ++tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/.([^.]*)$/.T\1/'`} ++ ++rm -f "$tmpdepfile" ++ ++# Some modes work just like other modes, but use different flags. We ++# parameterize here, but still list the modes in the big case below, ++# to make depend.m4 easier to write. Note that we *cannot* use a case ++# here, because this file can only contain one case statement. ++if test "$depmode" = hp; then ++ # HP compiler uses -M and no extra arg. ++ gccflag=-M ++ depmode=gcc ++fi ++ ++if test "$depmode" = dashXmstdout; then ++ # This is just like dashmstdout with a different argument. ++ dashmflag=-xM ++ depmode=dashmstdout ++fi ++ ++case "$depmode" in ++gcc3) ++## gcc 3 implements dependency tracking that does exactly what ++## we want. Yay! Note: for some reason libtool 1.4 doesn't like ++## it if -MD -MP comes after the -MF stuff. Hmm. ++ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile" ++ exit $stat ++ fi ++ mv "$tmpdepfile" "$depfile" ++ ;; ++ ++gcc) ++## There are various ways to get dependency output from gcc. Here's ++## why we pick this rather obscure method: ++## - Don't want to use -MD because we'd like the dependencies to end ++## up in a subdir. Having to rename by hand is ugly. ++## (We might end up doing this anyway to support other compilers.) ++## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ++## -MM, not -M (despite what the docs say). ++## - Using -M directly means running the compiler twice (even worse ++## than renaming). ++ if test -z "$gccflag"; then ++ gccflag=-MD, ++ fi ++ "$@" -Wp,"$gccflag$tmpdepfile" ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile" ++ exit $stat ++ fi ++ rm -f "$depfile" ++ echo "$object : \" > "$depfile" ++ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ++## The second -e expression handles DOS-style file names with drive letters. ++ sed -e 's/^[^:]*: / /' \ ++ -e 's/^['$alpha']:/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ++## This next piece of magic avoids the `deleted header file' problem. ++## The problem is that when a header file which appears in a .P file ++## is deleted, the dependency causes make to die (because there is ++## typically no way to rebuild the header). We avoid this by adding ++## dummy dependencies for each header file. Too bad gcc doesn't do ++## this for us directly. ++ tr ' ' ' ++' < "$tmpdepfile" | ++## Some versions of gcc put a space before the `:'. On the theory ++## that the space means something, we add a space to the output as ++## well. ++## Some versions of the HPUX 10.20 sed can't process this invocation ++## correctly. Breaking it into two sed invocations is a workaround. ++ sed -e 's/^\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++hp) ++ # This case exists only to let depend.m4 do its work. It works by ++ # looking at the text of this script. This case will never be run, ++ # since it is checked for above. ++ exit 1 ++ ;; ++ ++sgi) ++ if test "$libtool" = yes; then ++ "$@" "-Wp,-MDupdate,$tmpdepfile" ++ else ++ "$@" -MDupdate "$tmpdepfile" ++ fi ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile" ++ exit $stat ++ fi ++ rm -f "$depfile" ++ ++ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files ++ echo "$object : \" > "$depfile" ++ ++ # Clip off the initial element (the dependent). Don't try to be ++ # clever and replace this with sed code, as IRIX sed won't handle ++ # lines with more than a fixed number of characters (4096 in ++ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; ++ # the IRIX cc adds comments like `#:fec' to the end of the ++ # dependency line. ++ tr ' ' ' ++' < "$tmpdepfile" \ ++ | sed -e 's/^.*.o://' -e 's/#.*$//' -e '/^$/ d' | \ ++ tr ' ++' ' ' >> $depfile ++ echo >> $depfile ++ ++ # The second pass generates a dummy entry for each header file. ++ tr ' ' ' ++' < "$tmpdepfile" \ ++ | sed -e 's/^.*.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ ++ >> $depfile ++ else ++ # The sourcefile does not contain any dependencies, so just ++ # store a dummy comment line, to avoid errors with the Makefile ++ # "include basename.Plo" scheme. ++ echo "#dummy" > "$depfile" ++ fi ++ rm -f "$tmpdepfile" ++ ;; ++ ++aix) ++ # The C for AIX Compiler uses -M and outputs the dependencies ++ # in a .u file. In older versions, this file always lives in the ++ # current directory. Also, the AIX compiler puts `$object:' at the ++ # start of each line; $object doesn't have directory information. ++ # Version 6 uses the directory in both cases. ++ stripped=`echo "$object" | sed 's/(.*)..*$/\1/'` ++ tmpdepfile="$stripped.u" ++ if test "$libtool" = yes; then ++ "$@" -Wc,-M ++ else ++ "$@" -M ++ fi ++ stat=$? ++ ++ if test -f "$tmpdepfile"; then : ++ else ++ stripped=`echo "$stripped" | sed 's,^.*/,,'` ++ tmpdepfile="$stripped.u" ++ fi ++ ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile" ++ exit $stat ++ fi ++ ++ if test -f "$tmpdepfile"; then ++ outname="$stripped.o" ++ # Each line is of the form `foo.o: dependent.h'. ++ # Do two passes, one to just change these to ++ # `$object: dependent.h' and one to simply `dependent.h:'. ++ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" ++ sed -e "s,^$outname: (.*)$,\1:," < "$tmpdepfile" >> "$depfile" ++ else ++ # The sourcefile does not contain any dependencies, so just ++ # store a dummy comment line, to avoid errors with the Makefile ++ # "include basename.Plo" scheme. ++ echo "#dummy" > "$depfile" ++ fi ++ rm -f "$tmpdepfile" ++ ;; ++ ++icc) ++ # Intel's C compiler understands `-MD -MF file'. However on ++ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c ++ # ICC 7.0 will fill foo.d with something like ++ # foo.o: sub/foo.c ++ # foo.o: sub/foo.h ++ # which is wrong. We want: ++ # sub/foo.o: sub/foo.c ++ # sub/foo.o: sub/foo.h ++ # sub/foo.c: ++ # sub/foo.h: ++ # ICC 7.1 will output ++ # foo.o: sub/foo.c sub/foo.h ++ # and will wrap long lines using \ : ++ # foo.o: sub/foo.c ... \ ++ # sub/foo.h ... \ ++ # ... ++ ++ "$@" -MD -MF "$tmpdepfile" ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile" ++ exit $stat ++ fi ++ rm -f "$depfile" ++ # Each line is of the form `foo.o: dependent.h', ++ # or `foo.o: dep1.h dep2.h ', or ` dep3.h dep4.h '. ++ # Do two passes, one to just change these to ++ # `$object: dependent.h' and one to simply `dependent.h:'. ++ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" ++ # Some versions of the HPUX 10.20 sed can't process this invocation ++ # correctly. Breaking it into two sed invocations is a workaround. ++ sed 's,^[^:]*: (.*)$,\1,;s/^\$//;/^$/d;/:$/d' < "$tmpdepfile" | ++ sed -e 's/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++tru64) ++ # The Tru64 compiler uses -MD to generate dependencies as a side ++ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. ++ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put ++ # dependencies in `foo.d' instead, so we check for that too. ++ # Subdirectories are respected. ++ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` ++ test "x$dir" = "x$object" && dir= ++ base=`echo "$object" | sed -e 's|^.*/||' -e 's/.o$//' -e 's/.lo$//'` ++ ++ if test "$libtool" = yes; then ++ # With Tru64 cc, shared objects can also be used to make a ++ # static library. This mecanism is used in libtool 1.4 series to ++ # handle both shared and static libraries in a single compilation. ++ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. ++ # ++ # With libtool 1.5 this exception was removed, and libtool now ++ # generates 2 separate objects for the 2 libraries. These two ++ # compilations output dependencies in in $dir.libs/$base.o.d and ++ # in $dir$base.o.d. We have to check for both files, because ++ # one of the two compilations can be disabled. We should prefer ++ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is ++ # automatically cleaned when .libs/ is deleted, while ignoring ++ # the former would cause a distcleancheck panic. ++ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 ++ tmpdepfile2=$dir$base.o.d # libtool 1.5 ++ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 ++ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 ++ "$@" -Wc,-MD ++ else ++ tmpdepfile1=$dir$base.o.d ++ tmpdepfile2=$dir$base.d ++ tmpdepfile3=$dir$base.d ++ tmpdepfile4=$dir$base.d ++ "$@" -MD ++ fi ++ ++ stat=$? ++ if test $stat -eq 0; then : ++ else ++ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" ++ exit $stat ++ fi ++ ++ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" ++ do ++ test -f "$tmpdepfile" && break ++ done ++ if test -f "$tmpdepfile"; then ++ sed -e "s,^.*.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" ++ # That's a tab and a space in the []. ++ sed -e 's,^.*.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" ++ else ++ echo "#dummy" > "$depfile" ++ fi ++ rm -f "$tmpdepfile" ++ ;; ++ ++#nosideeffect) ++ # This comment above is used by automake to tell side-effect ++ # dependency tracking mechanisms from slower ones. ++ ++dashmstdout) ++ # Important note: in order to support this mode, a compiler *must* ++ # always write the preprocessed file to stdout, regardless of -o. ++ "$@" || exit $? ++ ++ # Remove the call to Libtool. ++ if test "$libtool" = yes; then ++ while test $1 != '--mode=compile'; do ++ shift ++ done ++ shift ++ fi ++ ++ # Remove `-o $object'. ++ IFS=" " ++ for arg ++ do ++ case $arg in ++ -o) ++ shift ++ ;; ++ $object) ++ shift ++ ;; ++ *) ++ set fnord "$@" "$arg" ++ shift # fnord ++ shift # $arg ++ ;; ++ esac ++ done ++ ++ test -z "$dashmflag" && dashmflag=-M ++ # Require at least two characters before searching for `:' ++ # in the target name. This is to cope with DOS-style filenames: ++ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. ++ "$@" $dashmflag | ++ sed 's:^[ ]*[^: ][^:][^:]*:[ ]*:'"$object"': :' > "$tmpdepfile" ++ rm -f "$depfile" ++ cat < "$tmpdepfile" > "$depfile" ++ tr ' ' ' ++' < "$tmpdepfile" | \ ++## Some versions of the HPUX 10.20 sed can't process this invocation ++## correctly. Breaking it into two sed invocations is a workaround. ++ sed -e 's/^\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++dashXmstdout) ++ # This case only exists to satisfy depend.m4. It is never actually ++ # run, as this mode is specially recognized in the preamble. ++ exit 1 ++ ;; ++ ++makedepend) ++ "$@" || exit $? ++ # Remove any Libtool call ++ if test "$libtool" = yes; then ++ while test $1 != '--mode=compile'; do ++ shift ++ done ++ shift ++ fi ++ # X makedepend ++ shift ++ cleared=no ++ for arg in "$@"; do ++ case $cleared in ++ no) ++ set ""; shift ++ cleared=yes ;; ++ esac ++ case "$arg" in ++ -D*|-I*) ++ set fnord "$@" "$arg"; shift ;; ++ # Strip any option that makedepend may not understand. Remove ++ # the object too, otherwise makedepend will parse it as a source file. ++ -*|$object) ++ ;; ++ *) ++ set fnord "$@" "$arg"; shift ;; ++ esac ++ done ++ obj_suffix="`echo $object | sed 's/^.*././'`" ++ touch "$tmpdepfile" ++ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" ++ rm -f "$depfile" ++ cat < "$tmpdepfile" > "$depfile" ++ sed '1,2d' "$tmpdepfile" | tr ' ' ' ++' | \ ++## Some versions of the HPUX 10.20 sed can't process this invocation ++## correctly. Breaking it into two sed invocations is a workaround. ++ sed -e 's/^\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" "$tmpdepfile".bak ++ ;; ++ ++cpp) ++ # Important note: in order to support this mode, a compiler *must* ++ # always write the preprocessed file to stdout. ++ "$@" || exit $? ++ ++ # Remove the call to Libtool. ++ if test "$libtool" = yes; then ++ while test $1 != '--mode=compile'; do ++ shift ++ done ++ shift ++ fi ++ ++ # Remove `-o $object'. ++ IFS=" " ++ for arg ++ do ++ case $arg in ++ -o) ++ shift ++ ;; ++ $object) ++ shift ++ ;; ++ *) ++ set fnord "$@" "$arg" ++ shift # fnord ++ shift # $arg ++ ;; ++ esac ++ done ++ ++ "$@" -E | ++ sed -n -e '/^# [0-9][0-9]* "([^"]*)".*/ s:: \1 \:p' \ ++ -e '/^#line [0-9][0-9]* "([^"]*)".*/ s:: \1 \:p' | ++ sed '$ s: \$::' > "$tmpdepfile" ++ rm -f "$depfile" ++ echo "$object : \" > "$depfile" ++ cat < "$tmpdepfile" >> "$depfile" ++ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \$//;s/$/ :/' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++msvisualcpp) ++ # Important note: in order to support this mode, a compiler *must* ++ # always write the preprocessed file to stdout, regardless of -o, ++ # because we must use -o when running libtool. ++ "$@" || exit $? ++ IFS=" " ++ for arg ++ do ++ case "$arg" in ++ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") ++ set fnord "$@" ++ shift ++ shift ++ ;; ++ *) ++ set fnord "$@" "$arg" ++ shift ++ shift ++ ;; ++ esac ++ done ++ "$@" -E | ++ sed -n '/^#line [0-9][0-9]* "([^"]*)"/ s::echo "`cygpath -u \"\1\"`":p' | sort | uniq > "$tmpdepfile" ++ rm -f "$depfile" ++ echo "$object : \" > "$depfile" ++ . "$tmpdepfile" | sed 's% %\ %g' | sed -n '/^(.*)$/ s:: \1 \:p' >> "$depfile" ++ echo " " >> "$depfile" ++ . "$tmpdepfile" | sed 's% %\ %g' | sed -n '/^(.*)$/ s::\1::p' >> "$depfile" ++ rm -f "$tmpdepfile" ++ ;; ++ ++none) ++ exec "$@" ++ ;; ++ ++*) ++ echo "Unknown depmode $depmode" 1>&2 ++ exit 1 ++ ;; ++esac ++ ++exit 0 ++ ++# Local Variables: ++# mode: shell-script ++# sh-indentation: 2 ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-end: "$" ++# End: +diff -urN lua-5.1.4/doc/Makefile.am lua-5.1.4-autotoolize/doc/Makefile.am +--- lua-5.1.4/doc/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/doc/Makefile.am 2008-09-03 13:18:23.000000000 +0200 +@@ -0,0 +1,5 @@ ++man1_MANS = lua.1 luac.1 ++ ++EXTRA_DIST = \ ++ contents.html lua.1 luac.html lua.html manual.html \ ++ logo.gif luac.1 lua.css readme.html +\ Kein Zeilenumbruch am Dateiende. +diff -urN lua-5.1.4/doc/Makefile.in lua-5.1.4-autotoolize/doc/Makefile.in +--- lua-5.1.4/doc/Makefile.in 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/doc/Makefile.in 2008-09-03 13:18:23.000000000 +0200 +@@ -0,0 +1,373 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = .. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = doc ++DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++SOURCES = ++DIST_SOURCES = ++man1dir = $(mandir)/man1 ++am__installdirs = "$(DESTDIR)$(man1dir)" ++NROFF = nroff ++MANS = $(man1_MANS) ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++LUA_BUILD_AS_DLL_DEFS = @LUA_BUILD_AS_DLL_DEFS@ ++LUA_DL_DEFS = @LUA_DL_DEFS@ ++LUA_LIBS = @LUA_LIBS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++POSIX_DEFS = @POSIX_DEFS@ ++RANLIB = @RANLIB@ ++READLINE_DEFS = @READLINE_DEFS@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++man1_MANS = lua.1 luac.1 ++EXTRA_DIST = \ ++ contents.html lua.1 luac.html lua.html manual.html \ ++ logo.gif luac.1 lua.css readme.html ++ ++all: all-am ++ ++.SUFFIXES: ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --foreign doc/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++install-man1: $(man1_MANS) $(man_MANS) ++ @$(NORMAL_INSTALL) ++ test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)" ++ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ ++ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ ++ for i in $$l2; do \ ++ case "$$i" in \ ++ *.1*) list="$$list $$i" ;; \ ++ esac; \ ++ done; \ ++ for i in $$list; do \ ++ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ ++ else file=$$i; fi; \ ++ ext=`echo $$i | sed -e 's/^.*\.//'`; \ ++ case "$$ext" in \ ++ 1*) ;; \ ++ *) ext='1' ;; \ ++ esac; \ ++ inst=`echo $$i | sed -e 's/\.[0-9a-z]*$$//'`; \ ++ inst=`echo $$inst | sed -e 's/^.*///'`; \ ++ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ ++ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ ++ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \ ++ done ++uninstall-man1: ++ @$(NORMAL_UNINSTALL) ++ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ ++ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ ++ for i in $$l2; do \ ++ case "$$i" in \ ++ *.1*) list="$$list $$i" ;; \ ++ esac; \ ++ done; \ ++ for i in $$list; do \ ++ ext=`echo $$i | sed -e 's/^.*\.//'`; \ ++ case "$$ext" in \ ++ 1*) ;; \ ++ *) ext='1' ;; \ ++ esac; \ ++ inst=`echo $$i | sed -e 's/\.[0-9a-z]*$$//'`; \ ++ inst=`echo $$inst | sed -e 's/^.*///'`; \ ++ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ ++ echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \ ++ rm -f "$(DESTDIR)$(man1dir)/$$inst"; \ ++ done ++tags: TAGS ++TAGS: ++ ++ctags: CTAGS ++CTAGS: ++ ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-am ++all-am: Makefile $(MANS) ++installdirs: ++ for dir in "$(DESTDIR)$(man1dir)"; do \ ++ test -z "$$dir" || $(mkdir_p) "$$dir"; \ ++ done ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool mostlyclean-am ++ ++distclean: distclean-am ++ -rm -f Makefile ++distclean-am: clean-am distclean-generic distclean-libtool ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: install-man ++ ++install-exec-am: ++ ++install-info: install-info-am ++ ++install-man: install-man1 ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-generic mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am uninstall-man ++ ++uninstall-man: uninstall-man1 ++ ++.PHONY: all all-am check check-am clean clean-generic clean-libtool \ ++ distclean distclean-generic distclean-libtool distdir dvi \ ++ dvi-am html html-am info info-am install install-am \ ++ install-data install-data-am install-exec install-exec-am \ ++ install-info install-info-am install-man install-man1 \ ++ install-strip installcheck installcheck-am installdirs \ ++ maintainer-clean maintainer-clean-generic mostlyclean \ ++ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ ++ uninstall uninstall-am uninstall-info-am uninstall-man \ ++ uninstall-man1 ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -urN lua-5.1.4/etc/lua.pc lua-5.1.4-autotoolize/etc/lua.pc +--- lua-5.1.4/etc/lua.pc 2008-08-08 14:46:11.000000000 +0200 ++++ lua-5.1.4-autotoolize/etc/lua.pc 2008-09-03 13:24:07.000000000 +0200 +@@ -1,31 +0,0 @@ +-# lua.pc -- pkg-config data for Lua +- +-# vars from install Makefile +- +-# grep '^V=' ../Makefile +-V= 5.1 +-# grep '^R=' ../Makefile +-R= 5.1.4 +- +-# grep '^INSTALL_.*=' ../Makefile | sed 's/INSTALL_TOP/prefix/' +-prefix= /usr/local +-INSTALL_BIN= ${prefix}/bin +-INSTALL_INC= ${prefix}/include +-INSTALL_LIB= ${prefix}/lib +-INSTALL_MAN= ${prefix}/man/man1 +-INSTALL_LMOD= ${prefix}/share/lua/${V} +-INSTALL_CMOD= ${prefix}/lib/lua/${V} +- +-# canonical vars +-exec_prefix=${prefix} +-libdir=${exec_prefix}/lib +-includedir=${prefix}/include +- +-Name: Lua +-Description: An Extensible Extension Language +-Version: ${R} +-Requires: +-Libs: -L${libdir} -llua -lm +-Cflags: -I${includedir} +- +-# (end of lua.pc) +diff -urN lua-5.1.4/etc/lua.pc.in lua-5.1.4-autotoolize/etc/lua.pc.in +--- lua-5.1.4/etc/lua.pc.in 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/etc/lua.pc.in 2008-09-03 13:18:23.000000000 +0200 +@@ -0,0 +1,13 @@ ++V= 5.1 ++R= 5.1.3 ++prefix= @prefix@ ++exec_prefix=${prefix} ++libdir= @libdir@ ++includedir=${prefix}/include ++ ++Name: Lua ++Description: An Extensible Extension Language ++Version: ${R} ++Requires: ++Libs: -llua @LUA_LIBS@ ++Cflags: -I${includedir} +diff -urN lua-5.1.4/etc/Makefile lua-5.1.4-autotoolize/etc/Makefile +--- lua-5.1.4/etc/Makefile 2006-02-07 20:09:30.000000000 +0100 ++++ lua-5.1.4-autotoolize/etc/Makefile 2008-09-03 13:18:23.000000000 +0200 +@@ -1,44 +0,0 @@ +-# makefile for Lua etc +- +-TOP= .. +-LIB= $(TOP)/src +-INC= $(TOP)/src +-BIN= $(TOP)/src +-SRC= $(TOP)/src +-TST= $(TOP)/test +- +-CC= gcc +-CFLAGS= -O2 -Wall -I$(INC) $(MYCFLAGS) +-MYCFLAGS= +-MYLDFLAGS= -Wl,-E +-MYLIBS= -lm +-#MYLIBS= -lm -Wl,-E -ldl -lreadline -lhistory -lncurses +-RM= rm -f +- +-default: +- @echo 'Please choose a target: min noparser one strict clean' +- +-min: min.c +- $(CC) $(CFLAGS) $@.c -L$(LIB) -llua $(MYLIBS) +- echo 'print"Hello there!"' | ./a.out +- +-noparser: noparser.o +- $(CC) noparser.o $(SRC)/lua.o -L$(LIB) -llua $(MYLIBS) +- $(BIN)/luac $(TST)/hello.lua +- -./a.out luac.out +- -./a.out -e'a=1' +- +-one: +- $(CC) $(CFLAGS) all.c $(MYLIBS) +- ./a.out $(TST)/hello.lua +- +-strict: +- -$(BIN)/lua -e 'print(a);b=2' +- -$(BIN)/lua -lstrict -e 'print(a)' +- -$(BIN)/lua -e 'function f() b=2 end f()' +- -$(BIN)/lua -lstrict -e 'function f() b=2 end f()' +- +-clean: +- $(RM) a.out core core.* *.o luac.out +- +-.PHONY: default min noparser one strict clean +diff -urN lua-5.1.4/etc/Makefile.am lua-5.1.4-autotoolize/etc/Makefile.am +--- lua-5.1.4/etc/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/etc/Makefile.am 2008-09-03 13:18:23.000000000 +0200 +@@ -0,0 +1,8 @@ ++include_HEADERS = lua.hpp ++ ++pkgconfigdir = $(libdir)/pkgconfig ++pkgconfig_DATA = lua.pc ++ ++EXTRA_DIST = \ ++ all.c lua.ico lua.pc.in noparser.c strict.lua \ ++ luavs.bat min.c README +diff -urN lua-5.1.4/etc/Makefile.in lua-5.1.4-autotoolize/etc/Makefile.in +--- lua-5.1.4/etc/Makefile.in 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/etc/Makefile.in 2008-09-03 13:18:23.000000000 +0200 +@@ -0,0 +1,423 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = .. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = etc ++DIST_COMMON = README $(include_HEADERS) $(srcdir)/Makefile.am \ ++ $(srcdir)/Makefile.in $(srcdir)/lua.pc.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = lua.pc ++SOURCES = ++DIST_SOURCES = ++am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; ++am__vpath_adj = case $$p in \ ++ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ ++ *) f=$$p;; \ ++ esac; ++am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; ++am__installdirs = "$(DESTDIR)$(pkgconfigdir)" \ ++ "$(DESTDIR)$(includedir)" ++pkgconfigDATA_INSTALL = $(INSTALL_DATA) ++DATA = $(pkgconfig_DATA) ++includeHEADERS_INSTALL = $(INSTALL_HEADER) ++HEADERS = $(include_HEADERS) ++ETAGS = etags ++CTAGS = ctags ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++LUA_BUILD_AS_DLL_DEFS = @LUA_BUILD_AS_DLL_DEFS@ ++LUA_DL_DEFS = @LUA_DL_DEFS@ ++LUA_LIBS = @LUA_LIBS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++POSIX_DEFS = @POSIX_DEFS@ ++RANLIB = @RANLIB@ ++READLINE_DEFS = @READLINE_DEFS@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++include_HEADERS = lua.hpp ++pkgconfigdir = $(libdir)/pkgconfig ++pkgconfig_DATA = lua.pc ++EXTRA_DIST = \ ++ all.c lua.ico lua.pc.in noparser.c strict.lua \ ++ luavs.bat min.c README ++ ++all: all-am ++ ++.SUFFIXES: ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign etc/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --foreign etc/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++lua.pc: $(top_builddir)/config.status $(srcdir)/lua.pc.in ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++install-pkgconfigDATA: $(pkgconfig_DATA) ++ @$(NORMAL_INSTALL) ++ test -z "$(pkgconfigdir)" || $(mkdir_p) "$(DESTDIR)$(pkgconfigdir)" ++ @list='$(pkgconfig_DATA)'; for p in $$list; do \ ++ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ ++ f=$(am__strip_dir) \ ++ echo " $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'"; \ ++ $(pkgconfigDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdir)/$$f"; \ ++ done ++ ++uninstall-pkgconfigDATA: ++ @$(NORMAL_UNINSTALL) ++ @list='$(pkgconfig_DATA)'; for p in $$list; do \ ++ f=$(am__strip_dir) \ ++ echo " rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'"; \ ++ rm -f "$(DESTDIR)$(pkgconfigdir)/$$f"; \ ++ done ++install-includeHEADERS: $(include_HEADERS) ++ @$(NORMAL_INSTALL) ++ test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" ++ @list='$(include_HEADERS)'; for p in $$list; do \ ++ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ ++ f=$(am__strip_dir) \ ++ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ ++ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ ++ done ++ ++uninstall-includeHEADERS: ++ @$(NORMAL_UNINSTALL) ++ @list='$(include_HEADERS)'; for p in $$list; do \ ++ f=$(am__strip_dir) \ ++ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ ++ rm -f "$(DESTDIR)$(includedir)/$$f"; \ ++ done ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-am ++all-am: Makefile $(DATA) $(HEADERS) ++installdirs: ++ for dir in "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \ ++ test -z "$$dir" || $(mkdir_p) "$$dir"; \ ++ done ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool mostlyclean-am ++ ++distclean: distclean-am ++ -rm -f Makefile ++distclean-am: clean-am distclean-generic distclean-libtool \ ++ distclean-tags ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: install-includeHEADERS install-pkgconfigDATA ++ ++install-exec-am: ++ ++install-info: install-info-am ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-generic mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: uninstall-includeHEADERS uninstall-info-am \ ++ uninstall-pkgconfigDATA ++ ++.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ ++ clean-libtool ctags distclean distclean-generic \ ++ distclean-libtool distclean-tags distdir dvi dvi-am html \ ++ html-am info info-am install install-am install-data \ ++ install-data-am install-exec install-exec-am \ ++ install-includeHEADERS install-info install-info-am \ ++ install-man install-pkgconfigDATA install-strip installcheck \ ++ installcheck-am installdirs maintainer-clean \ ++ maintainer-clean-generic mostlyclean mostlyclean-generic \ ++ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ ++ uninstall-am uninstall-includeHEADERS uninstall-info-am \ ++ uninstall-pkgconfigDATA ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -urN lua-5.1.4/install-sh lua-5.1.4-autotoolize/install-sh +--- lua-5.1.4/install-sh 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/install-sh 2008-09-03 13:18:23.000000000 +0200 +@@ -0,0 +1,323 @@ ++#!/bin/sh ++# install - install a program, script, or datafile ++ ++scriptversion=2005-05-14.22 ++ ++# This originates from X11R5 (mit/util/scripts/install.sh), which was ++# later released in X11R6 (xc/config/util/install.sh) with the ++# following copyright and license. ++# ++# Copyright (C) 1994 X Consortium ++# ++# Permission is hereby granted, free of charge, to any person obtaining a copy ++# of this software and associated documentation files (the "Software"), to ++# deal in the Software without restriction, including without limitation the ++# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or ++# sell copies of the Software, and to permit persons to whom the Software is ++# furnished to do so, subject to the following conditions: ++# ++# The above copyright notice and this permission notice shall be included in ++# all copies or substantial portions of the Software. ++# ++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN ++# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- ++# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++# ++# Except as contained in this notice, the name of the X Consortium shall not ++# be used in advertising or otherwise to promote the sale, use or other deal- ++# ings in this Software without prior written authorization from the X Consor- ++# tium. ++# ++# ++# FSF changes to this file are in the public domain. ++# ++# Calling this script install-sh is preferred over install.sh, to prevent ++# `make' implicit rules from creating a file called install from it ++# when there is no Makefile. ++# ++# This script is compatible with the BSD install script, but was written ++# from scratch. It can only install one file at a time, a restriction ++# shared with many OS's install programs. ++ ++# set DOITPROG to echo to test this script ++ ++# Don't use :- since 4.3BSD and earlier shells don't like it. ++doit="${DOITPROG-}" ++ ++# put in absolute paths if you don't have them in your path; or use env. vars. ++ ++mvprog="${MVPROG-mv}" ++cpprog="${CPPROG-cp}" ++chmodprog="${CHMODPROG-chmod}" ++chownprog="${CHOWNPROG-chown}" ++chgrpprog="${CHGRPPROG-chgrp}" ++stripprog="${STRIPPROG-strip}" ++rmprog="${RMPROG-rm}" ++mkdirprog="${MKDIRPROG-mkdir}" ++ ++chmodcmd="$chmodprog 0755" ++chowncmd= ++chgrpcmd= ++stripcmd= ++rmcmd="$rmprog -f" ++mvcmd="$mvprog" ++src= ++dst= ++dir_arg= ++dstarg= ++no_target_directory= ++ ++usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE ++ or: $0 [OPTION]... SRCFILES... DIRECTORY ++ or: $0 [OPTION]... -t DIRECTORY SRCFILES... ++ or: $0 [OPTION]... -d DIRECTORIES... ++ ++In the 1st form, copy SRCFILE to DSTFILE. ++In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. ++In the 4th, create DIRECTORIES. ++ ++Options: ++-c (ignored) ++-d create directories instead of installing files. ++-g GROUP $chgrpprog installed files to GROUP. ++-m MODE $chmodprog installed files to MODE. ++-o USER $chownprog installed files to USER. ++-s $stripprog installed files. ++-t DIRECTORY install into DIRECTORY. ++-T report an error if DSTFILE is a directory. ++--help display this help and exit. ++--version display version info and exit. ++ ++Environment variables override the default commands: ++ CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG ++" ++ ++while test -n "$1"; do ++ case $1 in ++ -c) shift ++ continue;; ++ ++ -d) dir_arg=true ++ shift ++ continue;; ++ ++ -g) chgrpcmd="$chgrpprog $2" ++ shift ++ shift ++ continue;; ++ ++ --help) echo "$usage"; exit $?;; ++ ++ -m) chmodcmd="$chmodprog $2" ++ shift ++ shift ++ continue;; ++ ++ -o) chowncmd="$chownprog $2" ++ shift ++ shift ++ continue;; ++ ++ -s) stripcmd=$stripprog ++ shift ++ continue;; ++ ++ -t) dstarg=$2 ++ shift ++ shift ++ continue;; ++ ++ -T) no_target_directory=true ++ shift ++ continue;; ++ ++ --version) echo "$0 $scriptversion"; exit $?;; ++ ++ *) # When -d is used, all remaining arguments are directories to create. ++ # When -t is used, the destination is already specified. ++ test -n "$dir_arg$dstarg" && break ++ # Otherwise, the last argument is the destination. Remove it from $@. ++ for arg ++ do ++ if test -n "$dstarg"; then ++ # $@ is not empty: it contains at least $arg. ++ set fnord "$@" "$dstarg" ++ shift # fnord ++ fi ++ shift # arg ++ dstarg=$arg ++ done ++ break;; ++ esac ++done ++ ++if test -z "$1"; then ++ if test -z "$dir_arg"; then ++ echo "$0: no input file specified." >&2 ++ exit 1 ++ fi ++ # It's OK to call `install-sh -d' without argument. ++ # This can happen when creating conditional directories. ++ exit 0 ++fi ++ ++for src ++do ++ # Protect names starting with `-'. ++ case $src in ++ -*) src=./$src ;; ++ esac ++ ++ if test -n "$dir_arg"; then ++ dst=$src ++ src= ++ ++ if test -d "$dst"; then ++ mkdircmd=: ++ chmodcmd= ++ else ++ mkdircmd=$mkdirprog ++ fi ++ else ++ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command ++ # might cause directories to be created, which would be especially bad ++ # if $src (and thus $dsttmp) contains '*'. ++ if test ! -f "$src" && test ! -d "$src"; then ++ echo "$0: $src does not exist." >&2 ++ exit 1 ++ fi ++ ++ if test -z "$dstarg"; then ++ echo "$0: no destination specified." >&2 ++ exit 1 ++ fi ++ ++ dst=$dstarg ++ # Protect names starting with `-'. ++ case $dst in ++ -*) dst=./$dst ;; ++ esac ++ ++ # If destination is a directory, append the input filename; won't work ++ # if double slashes aren't ignored. ++ if test -d "$dst"; then ++ if test -n "$no_target_directory"; then ++ echo "$0: $dstarg: Is a directory" >&2 ++ exit 1 ++ fi ++ dst=$dst/`basename "$src"` ++ fi ++ fi ++ ++ # This sed command emulates the dirname command. ++ dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` ++ ++ # Make sure that the destination directory exists. ++ ++ # Skip lots of stat calls in the usual case. ++ if test ! -d "$dstdir"; then ++ defaultIFS=' ++ ' ++ IFS="${IFS-$defaultIFS}" ++ ++ oIFS=$IFS ++ # Some sh's can't handle IFS=/ for some reason. ++ IFS='%' ++ set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` ++ shift ++ IFS=$oIFS ++ ++ pathcomp= ++ ++ while test $# -ne 0 ; do ++ pathcomp=$pathcomp$1 ++ shift ++ if test ! -d "$pathcomp"; then ++ $mkdirprog "$pathcomp" ++ # mkdir can fail with a `File exist' error in case several ++ # install-sh are creating the directory concurrently. This ++ # is OK. ++ test -d "$pathcomp" || exit ++ fi ++ pathcomp=$pathcomp/ ++ done ++ fi ++ ++ if test -n "$dir_arg"; then ++ $doit $mkdircmd "$dst" \ ++ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ ++ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ ++ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ ++ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } ++ ++ else ++ dstfile=`basename "$dst"` ++ ++ # Make a couple of temp file names in the proper directory. ++ dsttmp=$dstdir/_inst.$$_ ++ rmtmp=$dstdir/_rm.$$_ ++ ++ # Trap to clean up those temp files at exit. ++ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 ++ trap '(exit $?); exit' 1 2 13 15 ++ ++ # Copy the file name to the temp name. ++ $doit $cpprog "$src" "$dsttmp" && ++ ++ # and set any options; do chmod last to preserve setuid bits. ++ # ++ # If any of these fail, we abort the whole thing. If we want to ++ # ignore errors from any of these, just make sure not to ignore ++ # errors from the above "$doit $cpprog $src $dsttmp" command. ++ # ++ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ ++ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ ++ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ ++ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && ++ ++ # Now rename the file to the real destination. ++ { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ ++ || { ++ # The rename failed, perhaps because mv can't rename something else ++ # to itself, or perhaps because mv is so ancient that it does not ++ # support -f. ++ ++ # Now remove or move aside any old file at destination location. ++ # We try this two ways since rm can't unlink itself on some ++ # systems and the destination file might be busy for other ++ # reasons. In this case, the final cleanup might fail but the new ++ # file should still install successfully. ++ { ++ if test -f "$dstdir/$dstfile"; then ++ $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ ++ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ ++ || { ++ echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 ++ (exit 1); exit 1 ++ } ++ else ++ : ++ fi ++ } && ++ ++ # Now rename the file to the real destination. ++ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" ++ } ++ } ++ fi || { (exit 1); exit 1; } ++done ++ ++# The final little trick to "correctly" pass the exit status to the exit trap. ++{ ++ (exit 0); exit 0 ++} ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-end: "$" ++# End: +diff -urN lua-5.1.4/ltmain.sh lua-5.1.4-autotoolize/ltmain.sh +--- lua-5.1.4/ltmain.sh 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/ltmain.sh 2008-09-03 13:18:23.000000000 +0200 +@@ -0,0 +1,6971 @@ ++# ltmain.sh - Provide generalized library-building support services. ++# NOTE: Changing this file will not affect anything until you rerun configure. ++# ++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++basename="s,^.*/,,g" ++ ++# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh ++# is ksh but when the shell is invoked as "sh" and the current value of ++# the _XPG environment variable is not equal to 1 (one), the special ++# positional parameter $0, within a function call, is the name of the ++# function. ++progpath="$0" ++ ++# define SED for historic ltconfig's generated by Libtool 1.3 ++test -z "$SED" && SED=sed ++ ++# The name of this program: ++progname=`echo "$progpath" | $SED $basename` ++modename="$progname" ++ ++# Global variables: ++EXIT_SUCCESS=0 ++EXIT_FAILURE=1 ++ ++PROGRAM=ltmain.sh ++PACKAGE=libtool ++VERSION=1.5.22 ++TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)" ++ ++# See if we are running on zsh, and set the options which allow our ++# commands through without removal of \ escapes. ++if test -n "${ZSH_VERSION+set}" ; then ++ setopt NO_GLOB_SUBST ++fi ++# Same for EGREP, and just to be sure, do LTCC as well ++if test "X$EGREP" = X ; then ++ EGREP=egrep ++fi ++if test "X$LTCC" = X ; then ++ LTCC=${CC-gcc} ++fi ++ ++# Check that we have a working $echo. ++if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++elif test "X$1" = X--fallback-echo; then ++ # Avoid inline document here, it may be left over ++ : ++elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then ++ # Yippee, $echo works! ++ : ++else ++ # Restart under the correct shell, and then maybe $echo will work. ++ exec $SHELL "$progpath" --no-reexec ${1+"$@"} ++fi ++ ++if test "X$1" = X--fallback-echo; then ++ # used as fallback echo ++ shift ++ cat <<EOF ++$* ++EOF ++ exit $EXIT_SUCCESS ++fi ++ ++default_mode= ++help="Try `$progname --help' for more information." ++magic="%%%MAGIC variable%%%" ++mkdir="mkdir" ++mv="mv -f" ++rm="rm -f" ++ ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++Xsed="${SED}"' -e 1s/^X//' ++sed_quote_subst='s/([\`\"$\\])/\\1/g' ++# test EBCDIC or ASCII ++case `echo X|tr X '\101'` in ++ A) # ASCII based system ++ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr ++ SP2NL='tr \040 \012' ++ NL2SP='tr \015\012 \040\040' ++ ;; ++ *) # EBCDIC based system ++ SP2NL='tr \100 \n' ++ NL2SP='tr \r\n \100\100' ++ ;; ++esac ++ ++# NLS nuisances. ++# Only set LANG and LC_ALL to C if already set. ++# These must not be set unconditionally because not all systems understand ++# e.g. LANG=C (notably SCO). ++# We save the old values to restore during execute mode. ++if test "${LC_ALL+set}" = set; then ++ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL ++fi ++if test "${LANG+set}" = set; then ++ save_LANG="$LANG"; LANG=C; export LANG ++fi ++ ++# Make sure IFS has a sensible default ++lt_nl=' ++' ++IFS=" $lt_nl" ++ ++if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then ++ $echo "$modename: not configured to build any kind of library" 1>&2 ++ $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 ++ exit $EXIT_FAILURE ++fi ++ ++# Global variables. ++mode=$default_mode ++nonopt= ++prev= ++prevopt= ++run= ++show="$echo" ++show_help= ++execute_dlfiles= ++duplicate_deps=no ++preserve_args= ++lo2o="s/\.lo$/.${objext}/" ++o2lo="s/\.${objext}$/.lo/" ++ ++if test -z "$max_cmd_len"; then ++ i=0 ++ testring="ABCD" ++ new_result= ++ ++ # If test is not a shell built-in, we'll probably end up computing a ++ # maximum length that is only half of the actual maximum length, but ++ # we can't tell. ++ while (test "X"`$SHELL $0 --fallback-echo "X$testring" 2>/dev/null` \ ++ = "XX$testring") >/dev/null 2>&1 && ++ new_result=`expr "X$testring" : ".*" 2>&1` && ++ max_cmd_len="$new_result" && ++ test "$i" != 17 # 1/2 MB should be enough ++ do ++ i=`expr $i + 1` ++ testring="$testring$testring" ++ done ++ testring= ++ # Add a significant safety factor because C++ compilers can tack on massive ++ # amounts of additional arguments before passing them to the linker. ++ # It appears as though 1/2 is a usable value. ++ max_cmd_len=`expr $max_cmd_len / 2` ++fi ++ ++##################################### ++# Shell function definitions: ++# This seems to be the best place for them ++ ++# func_mktempdir [string] ++# Make a temporary directory that won't clash with other running ++# libtool processes, and avoids race conditions if possible. If ++# given, STRING is the basename for that directory. ++func_mktempdir () ++{ ++ my_template="${TMPDIR-/tmp}/${1-$progname}" ++ ++ if test "$run" = ":"; then ++ # Return a directory name, but don't create it in dry-run mode ++ my_tmpdir="${my_template}-$$" ++ else ++ ++ # If mktemp works, use that first and foremost ++ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` ++ ++ if test ! -d "$my_tmpdir"; then ++ # Failing that, at least try and use $RANDOM to avoid a race ++ my_tmpdir="${my_template}-${RANDOM-0}$$" ++ ++ save_mktempdir_umask=`umask` ++ umask 0077 ++ $mkdir "$my_tmpdir" ++ umask $save_mktempdir_umask ++ fi ++ ++ # If we're not in dry-run mode, bomb out on failure ++ test -d "$my_tmpdir" || { ++ $echo "cannot create temporary directory `$my_tmpdir'" 1>&2 ++ exit $EXIT_FAILURE ++ } ++ fi ++ ++ $echo "X$my_tmpdir" | $Xsed ++} ++ ++ ++# func_win32_libid arg ++# return the library type of file 'arg' ++# ++# Need a lot of goo to handle *both* DLLs and import libs ++# Has to be a shell function in order to 'eat' the argument ++# that is supplied when $file_magic_command is called. ++func_win32_libid () ++{ ++ win32_libid_type="unknown" ++ win32_fileres=`file -L $1 2>/dev/null` ++ case $win32_fileres in ++ *ar\ archive\ import\ library*) # definitely import ++ win32_libid_type="x86 archive import" ++ ;; ++ *ar\ archive*) # could be an import, or static ++ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ ++ $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then ++ win32_nmres=`eval $NM -f posix -A $1 | \ ++ $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'` ++ case $win32_nmres in ++ import*) win32_libid_type="x86 archive import";; ++ *) win32_libid_type="x86 archive static";; ++ esac ++ fi ++ ;; ++ *DLL*) ++ win32_libid_type="x86 DLL" ++ ;; ++ *executable*) # but shell scripts are "executable" too... ++ case $win32_fileres in ++ *MS\ Windows\ PE\ Intel*) ++ win32_libid_type="x86 DLL" ++ ;; ++ esac ++ ;; ++ esac ++ $echo $win32_libid_type ++} ++ ++ ++# func_infer_tag arg ++# Infer tagged configuration to use if any are available and ++# if one wasn't chosen via the "--tag" command line option. ++# Only attempt this if the compiler in the base compile ++# command doesn't match the default compiler. ++# arg is usually of the form 'gcc ...' ++func_infer_tag () ++{ ++ if test -n "$available_tags" && test -z "$tagname"; then ++ CC_quoted= ++ for arg in $CC; do ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ arg=""$arg"" ++ ;; ++ esac ++ CC_quoted="$CC_quoted $arg" ++ done ++ case $@ in ++ # Blanks in the command may have been stripped by the calling shell, ++ # but not from the CC environment variable when configure was run. ++ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; ++ # Blanks at the start of $base_compile will cause this to fail ++ # if we don't check for them as well. ++ *) ++ for z in $available_tags; do ++ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then ++ # Evaluate the configuration. ++ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" ++ CC_quoted= ++ for arg in $CC; do ++ # Double-quote args containing other shell metacharacters. ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ arg=""$arg"" ++ ;; ++ esac ++ CC_quoted="$CC_quoted $arg" ++ done ++ # user sometimes does CC=<HOST>-gcc so we need to match that to 'gcc' ++ trimedcc=`echo ${CC} | $SED -e "s/${host}-//g"` ++ # and sometimes libtool has CC=<HOST>-gcc but user does CC=gcc ++ extendcc=${host}-${CC} ++ # and sometimes libtool has CC=<OLDHOST>-gcc but user has CC=<NEWHOST>-gcc ++ # (Gentoo-specific hack because we always export $CHOST) ++ mungedcc=${CHOST-${host}}-${trimedcc} ++ case "$@ " in ++ "cc "* | " cc "* | "${host}-cc "* | " ${host}-cc "*|\ ++ "gcc "* | " gcc "* | "${host}-gcc "* | " ${host}-gcc "*) ++ tagname=CC ++ break ;; ++ "$trimedcc "* | " $trimedcc "* | "`$echo $trimedcc` "* | " `$echo $trimedcc` "*|\ ++ "$extendcc "* | " $extendcc "* | "`$echo $extendcc` "* | " `$echo $extendcc` "*|\ ++ "$mungedcc "* | " $mungedcc "* | "`$echo $mungedcc` "* | " `$echo $mungedcc` "*|\ ++ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ++ # The compiler in the base compile command matches ++ # the one in the tagged configuration. ++ # Assume this is the tagged configuration we want. ++ tagname=$z ++ break ++ ;; ++ esac ++ fi ++ done ++ # If $tagname still isn't set, then no tagged configuration ++ # was found and let the user know that the "--tag" command ++ # line option must be used. ++ if test -z "$tagname"; then ++ $echo "$modename: unable to infer tagged configuration" ++ $echo "$modename: specify a tag with `--tag'" 1>&2 ++ exit $EXIT_FAILURE ++# else ++# $echo "$modename: using $tagname tagged configuration" ++ fi ++ ;; ++ esac ++ fi ++} ++ ++ ++# func_extract_an_archive dir oldlib ++func_extract_an_archive () ++{ ++ f_ex_an_ar_dir="$1"; shift ++ f_ex_an_ar_oldlib="$1" ++ ++ $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" ++ $run eval "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" || exit $? ++ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then ++ : ++ else ++ $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++} ++ ++# func_extract_archives gentop oldlib ... ++func_extract_archives () ++{ ++ my_gentop="$1"; shift ++ my_oldlibs=${1+"$@"} ++ my_oldobjs="" ++ my_xlib="" ++ my_xabs="" ++ my_xdir="" ++ my_status="" ++ ++ $show "${rm}r $my_gentop" ++ $run ${rm}r "$my_gentop" ++ $show "$mkdir $my_gentop" ++ $run $mkdir "$my_gentop" ++ my_status=$? ++ if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then ++ exit $my_status ++ fi ++ ++ for my_xlib in $my_oldlibs; do ++ # Extract the objects. ++ case $my_xlib in ++ [\/]* | [A-Za-z]:[\/]*) my_xabs="$my_xlib" ;; ++ *) my_xabs=`pwd`"/$my_xlib" ;; ++ esac ++ my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` ++ my_xdir="$my_gentop/$my_xlib" ++ ++ $show "${rm}r $my_xdir" ++ $run ${rm}r "$my_xdir" ++ $show "$mkdir $my_xdir" ++ $run $mkdir "$my_xdir" ++ exit_status=$? ++ if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then ++ exit $exit_status ++ fi ++ case $host in ++ *-darwin*) ++ $show "Extracting $my_xabs" ++ # Do not bother doing anything if just a dry run ++ if test -z "$run"; then ++ darwin_orig_dir=`pwd` ++ cd $my_xdir || exit $? ++ darwin_archive=$my_xabs ++ darwin_curdir=`pwd` ++ darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` ++ darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` ++ if test -n "$darwin_arches"; then ++ darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` ++ darwin_arch= ++ $show "$darwin_base_archive has multiple architectures $darwin_arches" ++ for darwin_arch in $darwin_arches ; do ++ mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" ++ lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" ++ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" ++ func_extract_an_archive "`pwd`" "${darwin_base_archive}" ++ cd "$darwin_curdir" ++ $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" ++ done # $darwin_arches ++ ## Okay now we have a bunch of thin objects, gotta fatten them up :) ++ darwin_filelist=`find unfat-$$ -type f -name *.o -print -o -name *.lo -print| xargs basename | sort -u | $NL2SP` ++ darwin_file= ++ darwin_files= ++ for darwin_file in $darwin_filelist; do ++ darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` ++ lipo -create -output "$darwin_file" $darwin_files ++ done # $darwin_filelist ++ ${rm}r unfat-$$ ++ cd "$darwin_orig_dir" ++ else ++ cd "$darwin_orig_dir" ++ func_extract_an_archive "$my_xdir" "$my_xabs" ++ fi # $darwin_arches ++ fi # $run ++ ;; ++ *) ++ func_extract_an_archive "$my_xdir" "$my_xabs" ++ ;; ++ esac ++ my_oldobjs="$my_oldobjs "`find $my_xdir -name *.$objext -print -o -name *.lo -print | $NL2SP` ++ done ++ func_extract_archives_result="$my_oldobjs" ++} ++# End of Shell function definitions ++##################################### ++ ++# Darwin sucks ++eval std_shrext="$shrext_cmds" ++ ++disable_libs=no ++ ++# Parse our command line options once, thoroughly. ++while test "$#" -gt 0 ++do ++ arg="$1" ++ shift ++ ++ case $arg in ++ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; ++ *) optarg= ;; ++ esac ++ ++ # If the previous option needs an argument, assign it. ++ if test -n "$prev"; then ++ case $prev in ++ execute_dlfiles) ++ execute_dlfiles="$execute_dlfiles $arg" ++ ;; ++ tag) ++ tagname="$arg" ++ preserve_args="${preserve_args}=$arg" ++ ++ # Check whether tagname contains only valid characters ++ case $tagname in ++ *[!-_A-Za-z0-9,/]*) ++ $echo "$progname: invalid tag name: $tagname" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ case $tagname in ++ CC) ++ # Don't test for the "default" C tag, as we know, it's there, but ++ # not specially marked. ++ ;; ++ *) ++ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then ++ taglist="$taglist $tagname" ++ # Evaluate the configuration. ++ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" ++ else ++ $echo "$progname: ignoring unknown tag $tagname" 1>&2 ++ fi ++ ;; ++ esac ++ ;; ++ *) ++ eval "$prev=$arg" ++ ;; ++ esac ++ ++ prev= ++ prevopt= ++ continue ++ fi ++ ++ # Have we seen a non-optional argument yet? ++ case $arg in ++ --help) ++ show_help=yes ++ ;; ++ ++ --version) ++ $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" ++ $echo ++ $echo "Copyright (C) 2005 Free Software Foundation, Inc." ++ $echo "This is free software; see the source for copying conditions. There is NO" ++ $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ++ exit $? ++ ;; ++ ++ --config) ++ ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath ++ # Now print the configurations for the tags. ++ for tagname in $taglist; do ++ ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" ++ done ++ exit $? ++ ;; ++ ++ --debug) ++ $echo "$progname: enabling shell trace mode" ++ set -x ++ preserve_args="$preserve_args $arg" ++ ;; ++ ++ --dry-run | -n) ++ run=: ++ ;; ++ ++ --features) ++ $echo "host: $host" ++ if test "$build_libtool_libs" = yes; then ++ $echo "enable shared libraries" ++ else ++ $echo "disable shared libraries" ++ fi ++ if test "$build_old_libs" = yes; then ++ $echo "enable static libraries" ++ else ++ $echo "disable static libraries" ++ fi ++ exit $? ++ ;; ++ ++ --finish) mode="finish" ;; ++ ++ --mode) prevopt="--mode" prev=mode ;; ++ --mode=*) mode="$optarg" ;; ++ ++ --preserve-dup-deps) duplicate_deps="yes" ;; ++ ++ --quiet | --silent) ++ show=: ++ preserve_args="$preserve_args $arg" ++ ;; ++ ++ --tag) ++ prevopt="--tag" ++ prev=tag ++ preserve_args="$preserve_args --tag" ++ ;; ++ --tag=*) ++ set tag "$optarg" ${1+"$@"} ++ shift ++ prev=tag ++ preserve_args="$preserve_args --tag" ++ ;; ++ ++ -dlopen) ++ prevopt="-dlopen" ++ prev=execute_dlfiles ++ ;; ++ ++ -*) ++ $echo "$modename: unrecognized option `$arg'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ ++ *) ++ nonopt="$arg" ++ break ++ ;; ++ esac ++done ++ ++if test -n "$prevopt"; then ++ $echo "$modename: option `$prevopt' requires an argument" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++fi ++ ++case $disable_libs in ++no) ++ ;; ++shared) ++ build_libtool_libs=no ++ build_old_libs=yes ++ ;; ++static) ++ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` ++ ;; ++esac ++ ++# If this variable is set in any of the actions, the command in it ++# will be execed at the end. This prevents here-documents from being ++# left over by shells. ++exec_cmd= ++ ++if test -z "$show_help"; then ++ ++ # Infer the operation mode. ++ if test -z "$mode"; then ++ $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 ++ $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 ++ case $nonopt in ++ *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) ++ mode=link ++ for arg ++ do ++ case $arg in ++ -c) ++ mode=compile ++ break ++ ;; ++ esac ++ done ++ ;; ++ *db | *dbx | *strace | *truss) ++ mode=execute ++ ;; ++ *install*|cp|mv) ++ mode=install ++ ;; ++ *rm) ++ mode=uninstall ++ ;; ++ *) ++ # If we have no mode, but dlfiles were specified, then do execute mode. ++ test -n "$execute_dlfiles" && mode=execute ++ ++ # Just use the default operation mode. ++ if test -z "$mode"; then ++ if test -n "$nonopt"; then ++ $echo "$modename: warning: cannot infer operation mode from `$nonopt'" 1>&2 ++ else ++ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 ++ fi ++ fi ++ ;; ++ esac ++ fi ++ ++ # Only execute mode is allowed to have -dlopen flags. ++ if test -n "$execute_dlfiles" && test "$mode" != execute; then ++ $echo "$modename: unrecognized option `-dlopen'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Change the help message to a mode-specific one. ++ generic_help="$help" ++ help="Try `$modename --help --mode=$mode' for more information." ++ ++ # These modes are in order of execution frequency so that they run quickly. ++ case $mode in ++ # libtool compile mode ++ compile) ++ modename="$modename: compile" ++ # Get the compilation command and the source file. ++ base_compile= ++ srcfile="$nonopt" # always keep a non-empty value in "srcfile" ++ suppress_opt=yes ++ suppress_output= ++ arg_mode=normal ++ libobj= ++ later= ++ ++ for arg ++ do ++ case $arg_mode in ++ arg ) ++ # do not "continue". Instead, add this to base_compile ++ lastarg="$arg" ++ arg_mode=normal ++ ;; ++ ++ target ) ++ libobj="$arg" ++ arg_mode=normal ++ continue ++ ;; ++ ++ normal ) ++ # Accept any command-line options. ++ case $arg in ++ -o) ++ if test -n "$libobj" ; then ++ $echo "$modename: you cannot specify `-o' more than once" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ arg_mode=target ++ continue ++ ;; ++ ++ -static | -prefer-pic | -prefer-non-pic) ++ later="$later $arg" ++ continue ++ ;; ++ ++ -no-suppress) ++ suppress_opt=no ++ continue ++ ;; ++ ++ -Xcompiler) ++ arg_mode=arg # the next one goes into the "base_compile" arg list ++ continue # The current "srcfile" will either be retained or ++ ;; # replaced later. I would guess that would be a bug. ++ ++ -Wc,*) ++ args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` ++ lastarg= ++ save_ifs="$IFS"; IFS=',' ++ for arg in $args; do ++ IFS="$save_ifs" ++ ++ # Double-quote args containing other shell metacharacters. ++ # Many Bourne shells cannot handle close brackets correctly ++ # in scan sets, so we specify it separately. ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ arg=""$arg"" ++ ;; ++ esac ++ lastarg="$lastarg $arg" ++ done ++ IFS="$save_ifs" ++ lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` ++ ++ # Add the arguments to base_compile. ++ base_compile="$base_compile $lastarg" ++ continue ++ ;; ++ ++ * ) ++ # Accept the current argument as the source file. ++ # The previous "srcfile" becomes the current argument. ++ # ++ lastarg="$srcfile" ++ srcfile="$arg" ++ ;; ++ esac # case $arg ++ ;; ++ esac # case $arg_mode ++ ++ # Aesthetically quote the previous argument. ++ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` ++ ++ case $lastarg in ++ # Double-quote args containing other shell metacharacters. ++ # Many Bourne shells cannot handle close brackets correctly ++ # in scan sets, and some SunOS ksh mistreat backslash-escaping ++ # in scan sets (worked around with variable expansion), ++ # and furthermore cannot handle '|' '&' '(' ')' in scan sets ++ # at all, so we specify them separately. ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ lastarg=""$lastarg"" ++ ;; ++ esac ++ ++ base_compile="$base_compile $lastarg" ++ done # for arg ++ ++ case $arg_mode in ++ arg) ++ $echo "$modename: you must specify an argument for -Xcompile" ++ exit $EXIT_FAILURE ++ ;; ++ target) ++ $echo "$modename: you must specify a target with `-o'" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ *) ++ # Get the name of the library object. ++ [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` ++ ;; ++ esac ++ ++ # Recognize several different file suffixes. ++ # If the user specifies -o file.o, it is replaced with file.lo ++ xform='[cCFSifmso]' ++ case $libobj in ++ *.ada) xform=ada ;; ++ *.adb) xform=adb ;; ++ *.ads) xform=ads ;; ++ *.asm) xform=asm ;; ++ *.c++) xform=c++ ;; ++ *.cc) xform=cc ;; ++ *.ii) xform=ii ;; ++ *.class) xform=class ;; ++ *.cpp) xform=cpp ;; ++ *.cxx) xform=cxx ;; ++ *.f90) xform=f90 ;; ++ *.for) xform=for ;; ++ *.java) xform=java ;; ++ esac ++ ++ libobj=`$echo "X$libobj" | $Xsed -e "s/.$xform$/.lo/"` ++ ++ case $libobj in ++ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; ++ *) ++ $echo "$modename: cannot determine name of library object from `$libobj'" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ func_infer_tag $base_compile ++ ++ for arg in $later; do ++ case $arg in ++ -static) ++ build_old_libs=yes ++ continue ++ ;; ++ ++ -prefer-pic) ++ pic_mode=yes ++ continue ++ ;; ++ ++ -prefer-non-pic) ++ pic_mode=no ++ continue ++ ;; ++ esac ++ done ++ ++ qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` ++ case $qlibobj in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ qlibobj=""$qlibobj"" ;; ++ esac ++ test "X$libobj" != "X$qlibobj" \ ++ && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ ++ && $echo "$modename: libobj name `$libobj' may not contain shell special characters." ++ objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` ++ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$obj"; then ++ xdir= ++ else ++ xdir=$xdir/ ++ fi ++ lobj=${xdir}$objdir/$objname ++ ++ if test -z "$base_compile"; then ++ $echo "$modename: you must specify a compilation command" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Delete any leftover library objects. ++ if test "$build_old_libs" = yes; then ++ removelist="$obj $lobj $libobj ${libobj}T" ++ else ++ removelist="$lobj $libobj ${libobj}T" ++ fi ++ ++ $run $rm $removelist ++ trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 ++ ++ # On Cygwin there's no "real" PIC flag so we must build both object types ++ case $host_os in ++ cygwin* | mingw* | pw32* | os2*) ++ pic_mode=default ++ ;; ++ esac ++ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then ++ # non-PIC code in shared libraries is not supported ++ pic_mode=default ++ fi ++ ++ # Calculate the filename of the output object if compiler does ++ # not support -o with -c ++ if test "$compiler_c_o" = no; then ++ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%.[^.]*$%%'`.${objext} ++ lockfile="$output_obj.lock" ++ removelist="$removelist $output_obj $lockfile" ++ trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 ++ else ++ output_obj= ++ need_locks=no ++ lockfile= ++ fi ++ ++ # Lock this critical section if it is needed ++ # We use this script file to make the link, it avoids creating a new file ++ if test "$need_locks" = yes; then ++ until $run ln "$srcfile" "$lockfile" 2>/dev/null; do ++ $show "Waiting for $lockfile to be removed" ++ sleep 2 ++ done ++ elif test "$need_locks" = warn; then ++ if test -f "$lockfile"; then ++ $echo "\ ++*** ERROR, $lockfile exists and contains: ++`cat $lockfile 2>/dev/null` ++ ++This indicates that another process is trying to use the same ++temporary object file, and libtool could not work around it because ++your compiler does not support `-c' and `-o' together. If you ++repeat this compilation, it may succeed, by chance, but you had better ++avoid parallel builds (make -j) in this platform, or get a better ++compiler." ++ ++ $run $rm $removelist ++ exit $EXIT_FAILURE ++ fi ++ $echo "$srcfile" > "$lockfile" ++ fi ++ ++ if test -n "$fix_srcfile_path"; then ++ eval srcfile="$fix_srcfile_path" ++ fi ++ qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` ++ case $qsrcfile in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ qsrcfile=""$qsrcfile"" ;; ++ esac ++ ++ $run $rm "$libobj" "${libobj}T" ++ ++ # Create a libtool object file (analogous to a ".la" file), ++ # but don't create it if we're doing a dry run. ++ test -z "$run" && cat > ${libobj}T <<EOF ++# $libobj - a libtool object file ++# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP ++# ++# Please DO NOT delete this file! ++# It is necessary for linking the library. ++ ++# Name of the PIC object. ++EOF ++ ++ # Only build a PIC object if we are building libtool libraries. ++ if test "$build_libtool_libs" = yes; then ++ # Without this assignment, base_compile gets emptied. ++ fbsd_hideous_sh_bug=$base_compile ++ ++ if test "$pic_mode" != no; then ++ command="$base_compile $qsrcfile $pic_flag" ++ else ++ # Don't build PIC code ++ command="$base_compile $qsrcfile" ++ fi ++ ++ if test ! -d "${xdir}$objdir"; then ++ $show "$mkdir ${xdir}$objdir" ++ $run $mkdir ${xdir}$objdir ++ exit_status=$? ++ if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then ++ exit $exit_status ++ fi ++ fi ++ ++ if test -z "$output_obj"; then ++ # Place PIC objects in $objdir ++ command="$command -o $lobj" ++ fi ++ ++ $run $rm "$lobj" "$output_obj" ++ ++ $show "$command" ++ if $run eval "$command"; then : ++ else ++ test -n "$output_obj" && $run $rm $removelist ++ exit $EXIT_FAILURE ++ fi ++ ++ if test "$need_locks" = warn && ++ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then ++ $echo "\ ++*** ERROR, $lockfile contains: ++`cat $lockfile 2>/dev/null` ++ ++but it should contain: ++$srcfile ++ ++This indicates that another process is trying to use the same ++temporary object file, and libtool could not work around it because ++your compiler does not support `-c' and `-o' together. If you ++repeat this compilation, it may succeed, by chance, but you had better ++avoid parallel builds (make -j) in this platform, or get a better ++compiler." ++ ++ $run $rm $removelist ++ exit $EXIT_FAILURE ++ fi ++ ++ # Just move the object if needed, then go on to compile the next one ++ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then ++ $show "$mv $output_obj $lobj" ++ if $run $mv $output_obj $lobj; then : ++ else ++ error=$? ++ $run $rm $removelist ++ exit $error ++ fi ++ fi ++ ++ # Append the name of the PIC object to the libtool object file. ++ test -z "$run" && cat >> ${libobj}T <<EOF ++pic_object='$objdir/$objname' ++ ++EOF ++ ++ # Allow error messages only from the first compilation. ++ if test "$suppress_opt" = yes; then ++ suppress_output=' >/dev/null 2>&1' ++ fi ++ else ++ # No PIC object so indicate it doesn't exist in the libtool ++ # object file. ++ test -z "$run" && cat >> ${libobj}T <<EOF ++pic_object=none ++ ++EOF ++ fi ++ ++ # Only build a position-dependent object if we build old libraries. ++ if test "$build_old_libs" = yes; then ++ if test "$pic_mode" != yes; then ++ # Don't build PIC code ++ command="$base_compile $qsrcfile" ++ else ++ command="$base_compile $qsrcfile $pic_flag" ++ fi ++ if test "$compiler_c_o" = yes; then ++ command="$command -o $obj" ++ fi ++ ++ # Suppress compiler output if we already did a PIC compilation. ++ command="$command$suppress_output" ++ $run $rm "$obj" "$output_obj" ++ $show "$command" ++ if $run eval "$command"; then : ++ else ++ $run $rm $removelist ++ exit $EXIT_FAILURE ++ fi ++ ++ if test "$need_locks" = warn && ++ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then ++ $echo "\ ++*** ERROR, $lockfile contains: ++`cat $lockfile 2>/dev/null` ++ ++but it should contain: ++$srcfile ++ ++This indicates that another process is trying to use the same ++temporary object file, and libtool could not work around it because ++your compiler does not support `-c' and `-o' together. If you ++repeat this compilation, it may succeed, by chance, but you had better ++avoid parallel builds (make -j) in this platform, or get a better ++compiler." ++ ++ $run $rm $removelist ++ exit $EXIT_FAILURE ++ fi ++ ++ # Just move the object if needed ++ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then ++ $show "$mv $output_obj $obj" ++ if $run $mv $output_obj $obj; then : ++ else ++ error=$? ++ $run $rm $removelist ++ exit $error ++ fi ++ fi ++ ++ # Append the name of the non-PIC object the libtool object file. ++ # Only append if the libtool object file exists. ++ test -z "$run" && cat >> ${libobj}T <<EOF ++# Name of the non-PIC object. ++non_pic_object='$objname' ++ ++EOF ++ else ++ # Append the name of the non-PIC object the libtool object file. ++ # Only append if the libtool object file exists. ++ test -z "$run" && cat >> ${libobj}T <<EOF ++# Name of the non-PIC object. ++non_pic_object=none ++ ++EOF ++ fi ++ ++ $run $mv "${libobj}T" "${libobj}" ++ ++ # Unlock the critical section if it was locked ++ if test "$need_locks" != no; then ++ $run $rm "$lockfile" ++ fi ++ ++ exit $EXIT_SUCCESS ++ ;; ++ ++ # libtool link mode ++ link | relink) ++ modename="$modename: link" ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) ++ # It is impossible to link a dll without this setting, and ++ # we shouldn't force the makefile maintainer to figure out ++ # which system we are compiling for in order to pass an extra ++ # flag for every libtool invocation. ++ # allow_undefined=no ++ ++ # FIXME: Unfortunately, there are problems with the above when trying ++ # to make a dll which has undefined symbols, in which case not ++ # even a static library is built. For now, we need to specify ++ # -no-undefined on the libtool link line when we can be certain ++ # that all symbols are satisfied, otherwise we get a static library. ++ allow_undefined=yes ++ ;; ++ *) ++ allow_undefined=yes ++ ;; ++ esac ++ libtool_args="$nonopt" ++ base_compile="$nonopt $@" ++ compile_command="$nonopt" ++ finalize_command="$nonopt" ++ ++ compile_rpath= ++ finalize_rpath= ++ compile_shlibpath= ++ finalize_shlibpath= ++ convenience= ++ old_convenience= ++ deplibs= ++ old_deplibs= ++ compiler_flags= ++ linker_flags= ++ dllsearchpath= ++ lib_search_path=`pwd` ++ inst_prefix_dir= ++ ++ avoid_version=no ++ dlfiles= ++ dlprefiles= ++ dlself=no ++ export_dynamic=no ++ export_symbols= ++ export_symbols_regex= ++ generated= ++ libobjs= ++ ltlibs= ++ module=no ++ no_install=no ++ objs= ++ non_pic_objects= ++ notinst_path= # paths that contain not-installed libtool libraries ++ precious_files_regex= ++ prefer_static_libs=no ++ preload=no ++ prev= ++ prevarg= ++ release= ++ rpath= ++ xrpath= ++ perm_rpath= ++ temp_rpath= ++ thread_safe=no ++ vinfo= ++ vinfo_number=no ++ ++ func_infer_tag $base_compile ++ ++ # We need to know -static, to get the right output filenames. ++ for arg ++ do ++ case $arg in ++ -all-static | -static) ++ if test "X$arg" = "X-all-static"; then ++ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then ++ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 ++ fi ++ if test -n "$link_static_flag"; then ++ dlopen_self=$dlopen_self_static ++ fi ++ prefer_static_libs=yes ++ else ++ if test -z "$pic_flag" && test -n "$link_static_flag"; then ++ dlopen_self=$dlopen_self_static ++ fi ++ prefer_static_libs=built ++ fi ++ build_libtool_libs=no ++ build_old_libs=yes ++ break ++ ;; ++ esac ++ done ++ ++ # See if our shared archives depend on static archives. ++ test -n "$old_archive_from_new_cmds" && build_old_libs=yes ++ ++ # Go through the arguments, transforming them on the way. ++ while test "$#" -gt 0; do ++ arg="$1" ++ shift ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ qarg="`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`" ### testsuite: skip nested quoting test ++ ;; ++ *) qarg=$arg ;; ++ esac ++ libtool_args="$libtool_args $qarg" ++ ++ # If the previous option needs an argument, assign it. ++ if test -n "$prev"; then ++ case $prev in ++ output) ++ compile_command="$compile_command @OUTPUT@" ++ finalize_command="$finalize_command @OUTPUT@" ++ ;; ++ esac ++ ++ case $prev in ++ dlfiles|dlprefiles) ++ if test "$preload" = no; then ++ # Add the symbol object into the linking commands. ++ compile_command="$compile_command @SYMFILE@" ++ finalize_command="$finalize_command @SYMFILE@" ++ preload=yes ++ fi ++ case $arg in ++ *.la | *.lo) ;; # We handle these cases below. ++ force) ++ if test "$dlself" = no; then ++ dlself=needless ++ export_dynamic=yes ++ fi ++ prev= ++ continue ++ ;; ++ self) ++ if test "$prev" = dlprefiles; then ++ dlself=yes ++ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then ++ dlself=yes ++ else ++ dlself=needless ++ export_dynamic=yes ++ fi ++ prev= ++ continue ++ ;; ++ *) ++ if test "$prev" = dlfiles; then ++ dlfiles="$dlfiles $arg" ++ else ++ dlprefiles="$dlprefiles $arg" ++ fi ++ prev= ++ continue ++ ;; ++ esac ++ ;; ++ expsyms) ++ export_symbols="$arg" ++ if test ! -f "$arg"; then ++ $echo "$modename: symbol file `$arg' does not exist" ++ exit $EXIT_FAILURE ++ fi ++ prev= ++ continue ++ ;; ++ expsyms_regex) ++ export_symbols_regex="$arg" ++ prev= ++ continue ++ ;; ++ inst_prefix) ++ inst_prefix_dir="$arg" ++ prev= ++ continue ++ ;; ++ precious_regex) ++ precious_files_regex="$arg" ++ prev= ++ continue ++ ;; ++ release) ++ release="-$arg" ++ prev= ++ continue ++ ;; ++ objectlist) ++ if test -f "$arg"; then ++ save_arg=$arg ++ moreargs= ++ for fil in `cat $save_arg` ++ do ++# moreargs="$moreargs $fil" ++ arg=$fil ++ # A libtool-controlled object. ++ ++ # Check to see that this really is a libtool object. ++ if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ pic_object= ++ non_pic_object= ++ ++ # Read the .lo file ++ # If there is no directory component, then add one. ++ case $arg in ++ */* | *\*) . $arg ;; ++ *) . ./$arg ;; ++ esac ++ ++ if test -z "$pic_object" || \ ++ test -z "$non_pic_object" || ++ test "$pic_object" = none && \ ++ test "$non_pic_object" = none; then ++ $echo "$modename: cannot find name of object for `$arg'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Extract subdirectory from the argument. ++ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$arg"; then ++ xdir= ++ else ++ xdir="$xdir/" ++ fi ++ ++ if test "$pic_object" != none; then ++ # Prepend the subdirectory the object is found in. ++ pic_object="$xdir$pic_object" ++ ++ if test "$prev" = dlfiles; then ++ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then ++ dlfiles="$dlfiles $pic_object" ++ prev= ++ continue ++ else ++ # If libtool objects are unsupported, then we need to preload. ++ prev=dlprefiles ++ fi ++ fi ++ ++ # CHECK ME: I think I busted this. -Ossama ++ if test "$prev" = dlprefiles; then ++ # Preload the old-style object. ++ dlprefiles="$dlprefiles $pic_object" ++ prev= ++ fi ++ ++ # A PIC object. ++ libobjs="$libobjs $pic_object" ++ arg="$pic_object" ++ fi ++ ++ # Non-PIC object. ++ if test "$non_pic_object" != none; then ++ # Prepend the subdirectory the object is found in. ++ non_pic_object="$xdir$non_pic_object" ++ ++ # A standard non-PIC object ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ if test -z "$pic_object" || test "$pic_object" = none ; then ++ arg="$non_pic_object" ++ fi ++ else ++ # If the PIC object exists, use it instead. ++ # $xdir was prepended to $pic_object above. ++ non_pic_object="$pic_object" ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ fi ++ else ++ # Only an error if not doing a dry-run. ++ if test -z "$run"; then ++ $echo "$modename: `$arg' is not a valid libtool object" 1>&2 ++ exit $EXIT_FAILURE ++ else ++ # Dry-run case. ++ ++ # Extract subdirectory from the argument. ++ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$arg"; then ++ xdir= ++ else ++ xdir="$xdir/" ++ fi ++ ++ pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` ++ non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` ++ libobjs="$libobjs $pic_object" ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ fi ++ fi ++ done ++ else ++ $echo "$modename: link input file `$save_arg' does not exist" ++ exit $EXIT_FAILURE ++ fi ++ arg=$save_arg ++ prev= ++ continue ++ ;; ++ rpath | xrpath) ++ # We need an absolute path. ++ case $arg in ++ [\/]* | [A-Za-z]:[\/]*) ;; ++ *) ++ $echo "$modename: only absolute run-paths are allowed" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ if test "$prev" = rpath; then ++ case "$rpath " in ++ *" $arg "*) ;; ++ *) rpath="$rpath $arg" ;; ++ esac ++ else ++ case "$xrpath " in ++ *" $arg "*) ;; ++ *) xrpath="$xrpath $arg" ;; ++ esac ++ fi ++ prev= ++ continue ++ ;; ++ xcompiler) ++ compiler_flags="$compiler_flags $qarg" ++ prev= ++ compile_command="$compile_command $qarg" ++ finalize_command="$finalize_command $qarg" ++ continue ++ ;; ++ xlinker) ++ linker_flags="$linker_flags $qarg" ++ compiler_flags="$compiler_flags $wl$qarg" ++ prev= ++ compile_command="$compile_command $wl$qarg" ++ finalize_command="$finalize_command $wl$qarg" ++ continue ++ ;; ++ xcclinker) ++ linker_flags="$linker_flags $qarg" ++ compiler_flags="$compiler_flags $qarg" ++ prev= ++ compile_command="$compile_command $qarg" ++ finalize_command="$finalize_command $qarg" ++ continue ++ ;; ++ shrext) ++ shrext_cmds="$arg" ++ prev= ++ continue ++ ;; ++ darwin_framework|darwin_framework_skip) ++ test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ prev= ++ continue ++ ;; ++ *) ++ eval "$prev="$arg"" ++ prev= ++ continue ++ ;; ++ esac ++ fi # test -n "$prev" ++ ++ prevarg="$arg" ++ ++ case $arg in ++ -all-static) ++ if test -n "$link_static_flag"; then ++ compile_command="$compile_command $link_static_flag" ++ finalize_command="$finalize_command $link_static_flag" ++ fi ++ continue ++ ;; ++ ++ -allow-undefined) ++ # FIXME: remove this flag sometime in the future. ++ $echo "$modename: `-allow-undefined' is deprecated because it is the default" 1>&2 ++ continue ++ ;; ++ ++ -avoid-version) ++ avoid_version=yes ++ continue ++ ;; ++ ++ -dlopen) ++ prev=dlfiles ++ continue ++ ;; ++ ++ -dlpreopen) ++ prev=dlprefiles ++ continue ++ ;; ++ ++ -export-dynamic) ++ export_dynamic=yes ++ continue ++ ;; ++ ++ -export-symbols | -export-symbols-regex) ++ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then ++ $echo "$modename: more than one -exported-symbols argument is not allowed" ++ exit $EXIT_FAILURE ++ fi ++ if test "X$arg" = "X-export-symbols"; then ++ prev=expsyms ++ else ++ prev=expsyms_regex ++ fi ++ continue ++ ;; ++ ++ -framework|-arch|-isysroot) ++ case " $CC " in ++ *" ${arg} ${1} "* | *" ${arg} ${1} "*) ++ prev=darwin_framework_skip ;; ++ *) compiler_flags="$compiler_flags $arg" ++ prev=darwin_framework ;; ++ esac ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ continue ++ ;; ++ ++ -inst-prefix-dir) ++ prev=inst_prefix ++ continue ++ ;; ++ ++ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* ++ # so, if we see these flags be careful not to treat them like -L ++ -L[A-Z][A-Z]*:*) ++ case $with_gcc/$host in ++ no/*-*-irix* | /*-*-irix*) ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ ;; ++ esac ++ continue ++ ;; ++ ++ -L*) ++ dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` ++ # We need an absolute path. ++ case $dir in ++ [\/]* | [A-Za-z]:[\/]*) ;; ++ *) ++ absdir=`cd "$dir" && pwd` ++ if test -z "$absdir"; then ++ $echo "$modename: cannot determine absolute directory name of `$dir'" 1>&2 ++ absdir="$dir" ++ notinst_path="$notinst_path $dir" ++ fi ++ dir="$absdir" ++ ;; ++ esac ++ case "$deplibs " in ++ *" -L$dir "*) ;; ++ *) ++ deplibs="$deplibs -L$dir" ++ lib_search_path="$lib_search_path $dir" ++ ;; ++ esac ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) ++ testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` ++ case :$dllsearchpath: in ++ *":$dir:"*) ;; ++ *) dllsearchpath="$dllsearchpath:$dir";; ++ esac ++ case :$dllsearchpath: in ++ *":$testbindir:"*) ;; ++ *) dllsearchpath="$dllsearchpath:$testbindir";; ++ esac ++ ;; ++ esac ++ continue ++ ;; ++ ++ -l*) ++ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) ++ # These systems don't actually have a C or math library (as such) ++ continue ++ ;; ++ *-*-os2*) ++ # These systems don't actually have a C library (as such) ++ test "X$arg" = "X-lc" && continue ++ ;; ++ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) ++ # Do not include libc due to us having libc/libc_r. ++ test "X$arg" = "X-lc" && continue ++ ;; ++ *-*-rhapsody* | *-*-darwin1.[012]) ++ # Rhapsody C and math libraries are in the System framework ++ deplibs="$deplibs -framework System" ++ continue ++ ;; ++ *-*-sco3.2v5* | *-*-sco5v6*) ++ # Causes problems with __ctype ++ test "X$arg" = "X-lc" && continue ++ ;; ++ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) ++ # Compiler inserts libc in the correct place for threads to work ++ test "X$arg" = "X-lc" && continue ++ ;; ++ esac ++ elif test "X$arg" = "X-lc_r"; then ++ case $host in ++ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) ++ # Do not include libc_r directly, use -pthread flag. ++ continue ++ ;; ++ esac ++ fi ++ deplibs="$deplibs $arg" ++ continue ++ ;; ++ ++ # Tru64 UNIX uses -model [arg] to determine the layout of C++ ++ # classes, name mangling, and exception handling. ++ -model) ++ compile_command="$compile_command $arg" ++ compiler_flags="$compiler_flags $arg" ++ finalize_command="$finalize_command $arg" ++ prev=xcompiler ++ continue ++ ;; ++ ++ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) ++ compiler_flags="$compiler_flags $arg" ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ continue ++ ;; ++ ++ -module) ++ module=yes ++ continue ++ ;; ++ ++ # -64, -mips[0-9] enable 64-bit mode on the SGI compiler ++ # -r[0-9][0-9]* specifies the processor on the SGI compiler ++ # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler ++ # +DA*, +DD* enable 64-bit mode on the HP compiler ++ # -q* pass through compiler args for the IBM compiler ++ # -m* pass through architecture-specific compiler args for GCC ++ # -m*, -t[45]*, -txscale* pass through architecture-specific ++ # compiler args for GCC ++ # -pg pass through profiling flag for GCC ++ # @file GCC response files ++ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \ ++ -t[45]*|-txscale*|@*) ++ ++ # Unknown arguments in both finalize_command and compile_command need ++ # to be aesthetically quoted because they are evaled later. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ arg=""$arg"" ++ ;; ++ esac ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ compiler_flags="$compiler_flags $arg" ++ continue ++ ;; ++ ++ -shrext) ++ prev=shrext ++ continue ++ ;; ++ ++ -no-fast-install) ++ fast_install=no ++ continue ++ ;; ++ ++ -no-install) ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) ++ # The PATH hackery in wrapper scripts is required on Windows ++ # in order for the loader to find any dlls it needs. ++ $echo "$modename: warning: `-no-install' is ignored for $host" 1>&2 ++ $echo "$modename: warning: assuming `-no-fast-install' instead" 1>&2 ++ fast_install=no ++ ;; ++ *) no_install=yes ;; ++ esac ++ continue ++ ;; ++ ++ -no-undefined) ++ allow_undefined=no ++ continue ++ ;; ++ ++ -objectlist) ++ prev=objectlist ++ continue ++ ;; ++ ++ -o) prev=output ;; ++ ++ -precious-files-regex) ++ prev=precious_regex ++ continue ++ ;; ++ ++ -release) ++ prev=release ++ continue ++ ;; ++ ++ -rpath) ++ prev=rpath ++ continue ++ ;; ++ ++ -R) ++ prev=xrpath ++ continue ++ ;; ++ ++ -R*) ++ dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` ++ # We need an absolute path. ++ case $dir in ++ [\/]* | [A-Za-z]:[\/]*) ;; ++ *) ++ $echo "$modename: only absolute run-paths are allowed" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ case "$xrpath " in ++ *" $dir "*) ;; ++ *) xrpath="$xrpath $dir" ;; ++ esac ++ continue ++ ;; ++ ++ -static) ++ # The effects of -static are defined in a previous loop. ++ # We used to do the same as -all-static on platforms that ++ # didn't have a PIC flag, but the assumption that the effects ++ # would be equivalent was wrong. It would break on at least ++ # Digital Unix and AIX. ++ continue ++ ;; ++ ++ -thread-safe) ++ thread_safe=yes ++ continue ++ ;; ++ ++ -version-info) ++ prev=vinfo ++ continue ++ ;; ++ -version-number) ++ prev=vinfo ++ vinfo_number=yes ++ continue ++ ;; ++ ++ -Wc,*) ++ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` ++ arg= ++ save_ifs="$IFS"; IFS=',' ++ for flag in $args; do ++ IFS="$save_ifs" ++ case $flag in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ flag=""$flag"" ++ ;; ++ esac ++ arg="$arg $wl$flag" ++ compiler_flags="$compiler_flags $flag" ++ done ++ IFS="$save_ifs" ++ arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ++ ;; ++ ++ -Wl,*) ++ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` ++ arg= ++ save_ifs="$IFS"; IFS=',' ++ for flag in $args; do ++ IFS="$save_ifs" ++ case $flag in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ flag=""$flag"" ++ ;; ++ esac ++ arg="$arg $wl$flag" ++ compiler_flags="$compiler_flags $wl$flag" ++ linker_flags="$linker_flags $flag" ++ done ++ IFS="$save_ifs" ++ arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ++ ;; ++ ++ -Xcompiler) ++ prev=xcompiler ++ continue ++ ;; ++ ++ -Xlinker) ++ prev=xlinker ++ continue ++ ;; ++ ++ -XCClinker) ++ prev=xcclinker ++ continue ++ ;; ++ ++ # Some other compiler flag. ++ -* | +*) ++ # Unknown arguments in both finalize_command and compile_command need ++ # to be aesthetically quoted because they are evaled later. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ arg=""$arg"" ++ ;; ++ esac ++ ;; ++ ++ *.$objext) ++ # A standard object. ++ objs="$objs $arg" ++ ;; ++ ++ *.lo) ++ # A libtool-controlled object. ++ ++ # Check to see that this really is a libtool object. ++ if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ pic_object= ++ non_pic_object= ++ ++ # Read the .lo file ++ # If there is no directory component, then add one. ++ case $arg in ++ */* | *\*) . $arg ;; ++ *) . ./$arg ;; ++ esac ++ ++ if test -z "$pic_object" || \ ++ test -z "$non_pic_object" || ++ test "$pic_object" = none && \ ++ test "$non_pic_object" = none; then ++ $echo "$modename: cannot find name of object for `$arg'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Extract subdirectory from the argument. ++ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$arg"; then ++ xdir= ++ else ++ xdir="$xdir/" ++ fi ++ ++ if test "$pic_object" != none; then ++ # Prepend the subdirectory the object is found in. ++ pic_object="$xdir$pic_object" ++ ++ if test "$prev" = dlfiles; then ++ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then ++ dlfiles="$dlfiles $pic_object" ++ prev= ++ continue ++ else ++ # If libtool objects are unsupported, then we need to preload. ++ prev=dlprefiles ++ fi ++ fi ++ ++ # CHECK ME: I think I busted this. -Ossama ++ if test "$prev" = dlprefiles; then ++ # Preload the old-style object. ++ dlprefiles="$dlprefiles $pic_object" ++ prev= ++ fi ++ ++ # A PIC object. ++ libobjs="$libobjs $pic_object" ++ arg="$pic_object" ++ fi ++ ++ # Non-PIC object. ++ if test "$non_pic_object" != none; then ++ # Prepend the subdirectory the object is found in. ++ non_pic_object="$xdir$non_pic_object" ++ ++ # A standard non-PIC object ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ if test -z "$pic_object" || test "$pic_object" = none ; then ++ arg="$non_pic_object" ++ fi ++ else ++ # If the PIC object exists, use it instead. ++ # $xdir was prepended to $pic_object above. ++ non_pic_object="$pic_object" ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ fi ++ else ++ # Only an error if not doing a dry-run. ++ if test -z "$run"; then ++ $echo "$modename: `$arg' is not a valid libtool object" 1>&2 ++ exit $EXIT_FAILURE ++ else ++ # Dry-run case. ++ ++ # Extract subdirectory from the argument. ++ xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$xdir" = "X$arg"; then ++ xdir= ++ else ++ xdir="$xdir/" ++ fi ++ ++ pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` ++ non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` ++ libobjs="$libobjs $pic_object" ++ non_pic_objects="$non_pic_objects $non_pic_object" ++ fi ++ fi ++ ;; ++ ++ *.$libext) ++ # An archive. ++ deplibs="$deplibs $arg" ++ old_deplibs="$old_deplibs $arg" ++ continue ++ ;; ++ ++ *.la) ++ # A libtool-controlled library. ++ ++ if test "$prev" = dlfiles; then ++ # This library was specified with -dlopen. ++ dlfiles="$dlfiles $arg" ++ prev= ++ elif test "$prev" = dlprefiles; then ++ # The library was specified with -dlpreopen. ++ dlprefiles="$dlprefiles $arg" ++ prev= ++ else ++ deplibs="$deplibs $arg" ++ fi ++ continue ++ ;; ++ ++ # Some other compiler argument. ++ *) ++ # Unknown arguments in both finalize_command and compile_command need ++ # to be aesthetically quoted because they are evaled later. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ arg=""$arg"" ++ ;; ++ esac ++ ;; ++ esac # arg ++ ++ # Now actually substitute the argument into the commands. ++ if test -n "$arg"; then ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ fi ++ done # argument parsing loop ++ ++ if test -n "$prev"; then ++ $echo "$modename: the `$prevarg' option requires an argument" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then ++ eval arg="$export_dynamic_flag_spec" ++ compile_command="$compile_command $arg" ++ finalize_command="$finalize_command $arg" ++ fi ++ ++ oldlibs= ++ # calculate the name of the file, without its directory ++ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` ++ libobjs_save="$libobjs" ++ ++ if test -n "$shlibpath_var"; then ++ # get the directories listed in $shlibpath_var ++ eval shlib_search_path=`$echo "X${$shlibpath_var}" | $Xsed -e 's/:/ /g'` ++ else ++ shlib_search_path= ++ fi ++ eval sys_lib_search_path="$sys_lib_search_path_spec" ++ eval sys_lib_dlsearch_path="$sys_lib_dlsearch_path_spec" ++ ++ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$output_objdir" = "X$output"; then ++ output_objdir="$objdir" ++ else ++ output_objdir="$output_objdir/$objdir" ++ fi ++ # Create the object directory. ++ if test ! -d "$output_objdir"; then ++ $show "$mkdir $output_objdir" ++ $run $mkdir $output_objdir ++ exit_status=$? ++ if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then ++ exit $exit_status ++ fi ++ fi ++ ++ # Determine the type of output ++ case $output in ++ "") ++ $echo "$modename: you must specify an output file" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ *.$libext) linkmode=oldlib ;; ++ *.lo | *.$objext) linkmode=obj ;; ++ *.la) linkmode=lib ;; ++ *) linkmode=prog ;; # Anything else should be a program. ++ esac ++ ++ case $host in ++ *cygwin* | *mingw* | *pw32*) ++ # don't eliminate duplications in $postdeps and $predeps ++ duplicate_compiler_generated_deps=yes ++ ;; ++ *) ++ duplicate_compiler_generated_deps=$duplicate_deps ++ ;; ++ esac ++ specialdeplibs= ++ ++ libs= ++ # Find all interdependent deplibs by searching for libraries ++ # that are linked more than once (e.g. -la -lb -la) ++ for deplib in $deplibs; do ++ if test "X$duplicate_deps" = "Xyes" ; then ++ case "$libs " in ++ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; ++ esac ++ fi ++ libs="$libs $deplib" ++ done ++ ++ if test "$linkmode" = lib; then ++ libs="$predeps $libs $compiler_lib_search_path $postdeps" ++ ++ # Compute libraries that are listed more than once in $predeps ++ # $postdeps and mark them as special (i.e., whose duplicates are ++ # not to be eliminated). ++ pre_post_deps= ++ if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then ++ for pre_post_dep in $predeps $postdeps; do ++ case "$pre_post_deps " in ++ *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; ++ esac ++ pre_post_deps="$pre_post_deps $pre_post_dep" ++ done ++ fi ++ pre_post_deps= ++ fi ++ ++ deplibs= ++ newdependency_libs= ++ newlib_search_path= ++ need_relink=no # whether we're linking any uninstalled libtool libraries ++ notinst_deplibs= # not-installed libtool libraries ++ case $linkmode in ++ lib) ++ passes="conv link" ++ for file in $dlfiles $dlprefiles; do ++ case $file in ++ *.la) ;; ++ *) ++ $echo "$modename: libraries can `-dlopen' only libtool libraries: $file" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ done ++ ;; ++ prog) ++ compile_deplibs= ++ finalize_deplibs= ++ alldeplibs=no ++ newdlfiles= ++ newdlprefiles= ++ passes="conv scan dlopen dlpreopen link" ++ ;; ++ *) passes="conv" ++ ;; ++ esac ++ for pass in $passes; do ++ if test "$linkmode,$pass" = "lib,link" || ++ test "$linkmode,$pass" = "prog,scan"; then ++ libs="$deplibs" ++ deplibs= ++ fi ++ if test "$linkmode" = prog; then ++ case $pass in ++ dlopen) libs="$dlfiles" ;; ++ dlpreopen) libs="$dlprefiles" ;; ++ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; ++ esac ++ fi ++ if test "$pass" = dlopen; then ++ # Collect dlpreopened libraries ++ save_deplibs="$deplibs" ++ deplibs= ++ fi ++ for deplib in $libs; do ++ lib= ++ found=no ++ case $deplib in ++ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ compiler_flags="$compiler_flags $deplib" ++ fi ++ continue ++ ;; ++ -l*) ++ if test "$linkmode" != lib && test "$linkmode" != prog; then ++ $echo "$modename: warning: `-l' is ignored for archives/objects" 1>&2 ++ continue ++ fi ++ name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` ++ for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do ++ for search_ext in .la $std_shrext .so .a; do ++ # Search the libtool library ++ lib="$searchdir/lib${name}${search_ext}" ++ if test -f "$lib"; then ++ if test "$search_ext" = ".la"; then ++ found=yes ++ else ++ found=no ++ fi ++ break 2 ++ fi ++ done ++ done ++ if test "$found" != yes; then ++ # deplib doesn't seem to be a libtool library ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" ++ fi ++ continue ++ else # deplib is a libtool library ++ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, ++ # We need to do some special things here, and not later. ++ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then ++ case " $predeps $postdeps " in ++ *" $deplib "*) ++ if (${SED} -e '2q' $lib | ++ grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ library_names= ++ old_library= ++ case $lib in ++ */* | *\*) . $lib ;; ++ *) . ./$lib ;; ++ esac ++ for l in $old_library $library_names; do ++ ll="$l" ++ done ++ if test "X$ll" = "X$old_library" ; then # only static version available ++ found=no ++ ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$ladir" = "X$lib" && ladir="." ++ lib=$ladir/$old_library ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" ++ fi ++ continue ++ fi ++ fi ++ ;; ++ *) ;; ++ esac ++ fi ++ fi ++ ;; # -l ++ -L*) ++ case $linkmode in ++ lib) ++ deplibs="$deplib $deplibs" ++ test "$pass" = conv && continue ++ newdependency_libs="$deplib $newdependency_libs" ++ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ++ ;; ++ prog) ++ if test "$pass" = conv; then ++ deplibs="$deplib $deplibs" ++ continue ++ fi ++ if test "$pass" = scan; then ++ deplibs="$deplib $deplibs" ++ else ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ fi ++ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ++ ;; ++ *) ++ $echo "$modename: warning: `-L' is ignored for archives/objects" 1>&2 ++ ;; ++ esac # linkmode ++ continue ++ ;; # -L ++ -R*) ++ if test "$pass" = link; then ++ dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` ++ # Make sure the xrpath contains only unique directories. ++ case "$xrpath " in ++ *" $dir "*) ;; ++ *) xrpath="$xrpath $dir" ;; ++ esac ++ fi ++ deplibs="$deplib $deplibs" ++ continue ++ ;; ++ *.la) lib="$deplib" ;; ++ *.$libext) ++ if test "$pass" = conv; then ++ deplibs="$deplib $deplibs" ++ continue ++ fi ++ case $linkmode in ++ lib) ++ valid_a_lib=no ++ case $deplibs_check_method in ++ match_pattern*) ++ set dummy $deplibs_check_method ++ match_pattern_regex=`expr "$deplibs_check_method" : "$2 (.*)"` ++ if eval $echo "$deplib" 2>/dev/null \ ++ | $SED 10q \ ++ | $EGREP "$match_pattern_regex" > /dev/null; then ++ valid_a_lib=yes ++ fi ++ ;; ++ pass_all) ++ valid_a_lib=yes ++ ;; ++ esac ++ if test "$valid_a_lib" != yes; then ++ $echo ++ $echo "*** Warning: Trying to link with static lib archive $deplib." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which you do not appear to have" ++ $echo "*** because the file extensions .$libext of this argument makes me believe" ++ $echo "*** that it is just a static archive that I should not used here." ++ else ++ $echo ++ $echo "*** Warning: Linking the shared library $output against the" ++ $echo "*** static library $deplib is not portable!" ++ deplibs="$deplib $deplibs" ++ fi ++ continue ++ ;; ++ prog) ++ if test "$pass" != link; then ++ deplibs="$deplib $deplibs" ++ else ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ fi ++ continue ++ ;; ++ esac # linkmode ++ ;; # *.$libext ++ *.lo | *.$objext) ++ if test "$pass" = conv; then ++ deplibs="$deplib $deplibs" ++ elif test "$linkmode" = prog; then ++ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then ++ # If there is no dlopen support or we're linking statically, ++ # we need to preload. ++ newdlprefiles="$newdlprefiles $deplib" ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ newdlfiles="$newdlfiles $deplib" ++ fi ++ fi ++ continue ++ ;; ++ %DEPLIBS%) ++ alldeplibs=yes ++ continue ++ ;; ++ esac # case $deplib ++ if test "$found" = yes || test -f "$lib"; then : ++ else ++ $echo "$modename: cannot find the library `$lib' or unhandled argument `$deplib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Check to see that this really is a libtool archive. ++ if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : ++ else ++ $echo "$modename: `$lib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$ladir" = "X$lib" && ladir="." ++ ++ dlname= ++ dlopen= ++ dlpreopen= ++ libdir= ++ library_names= ++ old_library= ++ # If the library was installed with an old release of libtool, ++ # it will not redefine variables installed, or shouldnotlink ++ installed=yes ++ shouldnotlink=no ++ avoidtemprpath= ++ ++ ++ # Read the .la file ++ case $lib in ++ */* | *\*) . $lib ;; ++ *) . ./$lib ;; ++ esac ++ ++ if test "$linkmode,$pass" = "lib,link" || ++ test "$linkmode,$pass" = "prog,scan" || ++ { test "$linkmode" != prog && test "$linkmode" != lib; }; then ++ test -n "$dlopen" && dlfiles="$dlfiles $dlopen" ++ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" ++ fi ++ ++ if test "$pass" = conv; then ++ # Only check for convenience libraries ++ deplibs="$lib $deplibs" ++ if test -z "$libdir"; then ++ if test -z "$old_library"; then ++ $echo "$modename: cannot find name of link library for `$lib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ # It is a libtool convenience library, so add in its objects. ++ convenience="$convenience $ladir/$objdir/$old_library" ++ old_convenience="$old_convenience $ladir/$objdir/$old_library" ++ tmp_libs= ++ for deplib in $dependency_libs; do ++ deplibs="$deplib $deplibs" ++ if test "X$duplicate_deps" = "Xyes" ; then ++ case "$tmp_libs " in ++ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; ++ esac ++ fi ++ tmp_libs="$tmp_libs $deplib" ++ done ++ elif test "$linkmode" != prog && test "$linkmode" != lib; then ++ $echo "$modename: `$lib' is not a convenience library" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ continue ++ fi # $pass = conv ++ ++ ++ # Get the name of the library we link against. ++ linklib= ++ for l in $old_library $library_names; do ++ linklib="$l" ++ done ++ if test -z "$linklib"; then ++ $echo "$modename: cannot find name of link library for `$lib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # This library was specified with -dlopen. ++ if test "$pass" = dlopen; then ++ if test -z "$libdir"; then ++ $echo "$modename: cannot -dlopen a convenience library: `$lib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ if test -z "$dlname" || ++ test "$dlopen_support" != yes || ++ test "$build_libtool_libs" = no; then ++ # If there is no dlname, no dlopen support or we're linking ++ # statically, we need to preload. We also need to preload any ++ # dependent libraries so libltdl's deplib preloader doesn't ++ # bomb out in the load deplibs phase. ++ dlprefiles="$dlprefiles $lib $dependency_libs" ++ else ++ newdlfiles="$newdlfiles $lib" ++ fi ++ continue ++ fi # $pass = dlopen ++ ++ # We need an absolute path. ++ case $ladir in ++ [\/]* | [A-Za-z]:[\/]*) abs_ladir="$ladir" ;; ++ *) ++ abs_ladir=`cd "$ladir" && pwd` ++ if test -z "$abs_ladir"; then ++ $echo "$modename: warning: cannot determine absolute directory name of `$ladir'" 1>&2 ++ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 ++ abs_ladir="$ladir" ++ fi ++ ;; ++ esac ++ laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` ++ ++ # Find the relevant object directory and library name. ++ if test "X$installed" = Xyes; then ++ if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then ++ $echo "$modename: warning: library `$lib' was moved." 1>&2 ++ dir="$ladir" ++ absdir="$abs_ladir" ++ libdir="$abs_ladir" ++ else ++ dir="$libdir" ++ absdir="$libdir" ++ fi ++ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes ++ else ++ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then ++ dir="$ladir" ++ absdir="$abs_ladir" ++ # Remove this search path later ++ notinst_path="$notinst_path $abs_ladir" ++ else ++ dir="$ladir/$objdir" ++ absdir="$abs_ladir/$objdir" ++ # Remove this search path later ++ notinst_path="$notinst_path $abs_ladir" ++ fi ++ fi # $installed = yes ++ name=`$echo "X$laname" | $Xsed -e 's/.la$//' -e 's/^lib//'` ++ ++ # This library was specified with -dlpreopen. ++ if test "$pass" = dlpreopen; then ++ if test -z "$libdir"; then ++ $echo "$modename: cannot -dlpreopen a convenience library: `$lib'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ # Prefer using a static library (so that no silly _DYNAMIC symbols ++ # are required to link). ++ if test -n "$old_library"; then ++ newdlprefiles="$newdlprefiles $dir/$old_library" ++ # Otherwise, use the dlname, so that lt_dlopen finds it. ++ elif test -n "$dlname"; then ++ newdlprefiles="$newdlprefiles $dir/$dlname" ++ else ++ newdlprefiles="$newdlprefiles $dir/$linklib" ++ fi ++ fi # $pass = dlpreopen ++ ++ if test -z "$libdir"; then ++ # Link the convenience library ++ if test "$linkmode" = lib; then ++ deplibs="$dir/$old_library $deplibs" ++ elif test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$dir/$old_library $compile_deplibs" ++ finalize_deplibs="$dir/$old_library $finalize_deplibs" ++ else ++ deplibs="$lib $deplibs" # used for prog,scan pass ++ fi ++ continue ++ fi ++ ++ ++ if test "$linkmode" = prog && test "$pass" != link; then ++ newlib_search_path="$newlib_search_path $ladir" ++ deplibs="$lib $deplibs" ++ ++ linkalldeplibs=no ++ if test "$link_all_deplibs" != no || test -z "$library_names" || ++ test "$build_libtool_libs" = no; then ++ linkalldeplibs=yes ++ fi ++ ++ tmp_libs= ++ for deplib in $dependency_libs; do ++ case $deplib in ++ -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test ++ esac ++ # Need to link against all dependency_libs? ++ if test "$linkalldeplibs" = yes; then ++ deplibs="$deplib $deplibs" ++ else ++ # Need to hardcode shared library paths ++ # or/and link against static libraries ++ newdependency_libs="$deplib $newdependency_libs" ++ fi ++ if test "X$duplicate_deps" = "Xyes" ; then ++ case "$tmp_libs " in ++ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; ++ esac ++ fi ++ tmp_libs="$tmp_libs $deplib" ++ done # for deplib ++ continue ++ fi # $linkmode = prog... ++ ++ if test "$linkmode,$pass" = "prog,link"; then ++ if test -n "$library_names" && ++ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then ++ # We need to hardcode the library path ++ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then ++ # Make sure the rpath contains only unique directories. ++ case "$temp_rpath " in ++ *" $dir "*) ;; ++ *" $absdir "*) ;; ++ *) temp_rpath="$temp_rpath $absdir" ;; ++ esac ++ fi ++ ++ # Hardcode the library path. ++ # Skip directories that are in the system default run-time ++ # search path. ++ case " $sys_lib_dlsearch_path " in ++ *" $absdir "*) ;; ++ *) ++ case "$compile_rpath " in ++ *" $absdir "*) ;; ++ *) compile_rpath="$compile_rpath $absdir" ++ esac ++ ;; ++ esac ++ case " $sys_lib_dlsearch_path " in ++ *" $libdir "*) ;; ++ *) ++ case "$finalize_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_rpath="$finalize_rpath $libdir" ++ esac ++ ;; ++ esac ++ fi # $linkmode,$pass = prog,link... ++ ++ if test "$alldeplibs" = yes && ++ { test "$deplibs_check_method" = pass_all || ++ { test "$build_libtool_libs" = yes && ++ test -n "$library_names"; }; }; then ++ # We only need to search for static libraries ++ continue ++ fi ++ fi ++ ++ link_static=no # Whether the deplib will be linked statically ++ use_static_libs=$prefer_static_libs ++ if test "$use_static_libs" = built && test "$installed" = yes ; then ++ use_static_libs=no ++ fi ++ if test -n "$library_names" && ++ { test "$use_static_libs" = no || test -z "$old_library"; }; then ++ if test "$installed" = no; then ++ notinst_deplibs="$notinst_deplibs $lib" ++ need_relink=yes ++ fi ++ # This is a shared library ++ ++ # Warn about portability, can't link against -module's on ++ # some systems (darwin) ++ if test "$shouldnotlink" = yes && test "$pass" = link ; then ++ $echo ++ if test "$linkmode" = prog; then ++ $echo "*** Warning: Linking the executable $output against the loadable module" ++ else ++ $echo "*** Warning: Linking the shared library $output against the loadable module" ++ fi ++ $echo "*** $linklib is not portable!" ++ fi ++ if test "$linkmode" = lib && ++ test "$hardcode_into_libs" = yes; then ++ # Hardcode the library path. ++ # Skip directories that are in the system default run-time ++ # search path. ++ case " $sys_lib_dlsearch_path " in ++ *" $absdir "*) ;; ++ *) ++ case "$compile_rpath " in ++ *" $absdir "*) ;; ++ *) compile_rpath="$compile_rpath $absdir" ++ esac ++ ;; ++ esac ++ case " $sys_lib_dlsearch_path " in ++ *" $libdir "*) ;; ++ *) ++ case "$finalize_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_rpath="$finalize_rpath $libdir" ++ esac ++ ;; ++ esac ++ fi ++ ++ if test -n "$old_archive_from_expsyms_cmds"; then ++ # figure out the soname ++ set dummy $library_names ++ realname="$2" ++ shift; shift ++ libname=`eval \$echo "$libname_spec"` ++ # use dlname if we got it. it's perfectly good, no? ++ if test -n "$dlname"; then ++ soname="$dlname" ++ elif test -n "$soname_spec"; then ++ # bleh windows ++ case $host in ++ *cygwin* | mingw*) ++ major=`expr $current - $age` ++ versuffix="-$major" ++ ;; ++ esac ++ eval soname="$soname_spec" ++ else ++ soname="$realname" ++ fi ++ ++ # Make a new name for the extract_expsyms_cmds to use ++ soroot="$soname" ++ soname=`$echo $soroot | ${SED} -e 's/^.*///'` ++ newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/.dll$//'`.a" ++ ++ # If the library has no export list, then create one now ++ if test -f "$output_objdir/$soname-def"; then : ++ else ++ $show "extracting exported symbol list from `$soname'" ++ save_ifs="$IFS"; IFS='~' ++ cmds=$extract_expsyms_cmds ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ fi ++ ++ # Create $newlib ++ if test -f "$output_objdir/$newlib"; then :; else ++ $show "generating import library for `$soname'" ++ save_ifs="$IFS"; IFS='~' ++ cmds=$old_archive_from_expsyms_cmds ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ fi ++ # make sure the library variables are pointing to the new library ++ dir=$output_objdir ++ linklib=$newlib ++ fi # test -n "$old_archive_from_expsyms_cmds" ++ ++ if test "$linkmode" = prog || test "$mode" != relink; then ++ add_shlibpath= ++ add_dir= ++ add= ++ lib_linked=yes ++ case $hardcode_action in ++ immediate | unsupported) ++ if test "$hardcode_direct" = no; then ++ add="$dir/$linklib" ++ case $host in ++ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; ++ *-*-sysv4*uw2*) add_dir="-L$dir" ;; ++ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ ++ *-*-unixware7*) add_dir="-L$dir" ;; ++ *-*-darwin* ) ++ # if the lib is a module then we can not link against ++ # it, someone is ignoring the new warnings I added ++ if /usr/bin/file -L $add 2> /dev/null | ++ $EGREP ": [^:]* bundle" >/dev/null ; then ++ $echo "** Warning, lib $linklib is a module, not a shared library" ++ if test -z "$old_library" ; then ++ $echo ++ $echo "** And there doesn't seem to be a static archive available" ++ $echo "** The link will probably fail, sorry" ++ else ++ add="$dir/$old_library" ++ fi ++ fi ++ esac ++ elif test "$hardcode_minus_L" = no; then ++ case $host in ++ *-*-sunos*) add_shlibpath="$dir" ;; ++ esac ++ add_dir="-L$dir" ++ add="-l$name" ++ elif test "$hardcode_shlibpath_var" = no; then ++ add_shlibpath="$dir" ++ add="-l$name" ++ else ++ lib_linked=no ++ fi ++ ;; ++ relink) ++ if test "$hardcode_direct" = yes; then ++ add="$dir/$linklib" ++ elif test "$hardcode_minus_L" = yes; then ++ add_dir="-L$dir" ++ # Try looking first in the location we're being installed to. ++ if test -n "$inst_prefix_dir"; then ++ case $libdir in ++ [\/]*) ++ add_dir="$add_dir -L$inst_prefix_dir$libdir" ++ ;; ++ esac ++ fi ++ add="-l$name" ++ elif test "$hardcode_shlibpath_var" = yes; then ++ add_shlibpath="$dir" ++ add="-l$name" ++ else ++ lib_linked=no ++ fi ++ ;; ++ *) lib_linked=no ;; ++ esac ++ ++ if test "$lib_linked" != yes; then ++ $echo "$modename: configuration error: unsupported hardcode properties" ++ exit $EXIT_FAILURE ++ fi ++ ++ if test -n "$add_shlibpath"; then ++ case :$compile_shlibpath: in ++ *":$add_shlibpath:"*) ;; ++ *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; ++ esac ++ fi ++ if test "$linkmode" = prog; then ++ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" ++ test -n "$add" && compile_deplibs="$add $compile_deplibs" ++ else ++ test -n "$add_dir" && deplibs="$add_dir $deplibs" ++ test -n "$add" && deplibs="$add $deplibs" ++ if test "$hardcode_direct" != yes && \ ++ test "$hardcode_minus_L" != yes && \ ++ test "$hardcode_shlibpath_var" = yes; then ++ case :$finalize_shlibpath: in ++ *":$libdir:"*) ;; ++ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; ++ esac ++ fi ++ fi ++ fi ++ ++ if test "$linkmode" = prog || test "$mode" = relink; then ++ add_shlibpath= ++ add_dir= ++ add= ++ # Finalize command for both is simple: just hardcode it. ++ if test "$hardcode_direct" = yes; then ++ add="$libdir/$linklib" ++ elif test "$hardcode_minus_L" = yes; then ++ add_dir="-L$libdir" ++ add="-l$name" ++ elif test "$hardcode_shlibpath_var" = yes; then ++ case :$finalize_shlibpath: in ++ *":$libdir:"*) ;; ++ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; ++ esac ++ add="-l$name" ++ elif test "$hardcode_automatic" = yes; then ++ if test -n "$inst_prefix_dir" && ++ test -f "$inst_prefix_dir$libdir/$linklib" ; then ++ add="$inst_prefix_dir$libdir/$linklib" ++ else ++ add="$libdir/$linklib" ++ fi ++ else ++ # We cannot seem to hardcode it, guess we'll fake it. ++ add_dir="-L$libdir" ++ # Try looking first in the location we're being installed to. ++ if test -n "$inst_prefix_dir"; then ++ case $libdir in ++ [\/]*) ++ add_dir="$add_dir -L$inst_prefix_dir$libdir" ++ ;; ++ esac ++ fi ++ add="-l$name" ++ fi ++ ++ if test "$linkmode" = prog; then ++ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" ++ test -n "$add" && finalize_deplibs="$add $finalize_deplibs" ++ else ++ test -n "$add_dir" && deplibs="$add_dir $deplibs" ++ test -n "$add" && deplibs="$add $deplibs" ++ fi ++ fi ++ elif test "$linkmode" = prog; then ++ # Here we assume that one of hardcode_direct or hardcode_minus_L ++ # is not unsupported. This is valid on all known static and ++ # shared platforms. ++ if test "$hardcode_direct" != unsupported; then ++ test -n "$old_library" && linklib="$old_library" ++ compile_deplibs="$dir/$linklib $compile_deplibs" ++ finalize_deplibs="$dir/$linklib $finalize_deplibs" ++ else ++ compile_deplibs="-l$name -L$dir $compile_deplibs" ++ finalize_deplibs="-l$name -L$dir $finalize_deplibs" ++ fi ++ elif test "$build_libtool_libs" = yes; then ++ # Not a shared library ++ if test "$deplibs_check_method" != pass_all; then ++ # We're trying link a shared library against a static one ++ # but the system doesn't support it. ++ ++ # Just print a warning and add the library to dependency_libs so ++ # that the program can be linked against the static library. ++ $echo ++ $echo "*** Warning: This system can not link to static lib archive $lib." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which you do not appear to have." ++ if test "$module" = yes; then ++ $echo "*** But as you try to build a module library, libtool will still create " ++ $echo "*** a static module, that should work as long as the dlopening application" ++ $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." ++ if test -z "$global_symbol_pipe"; then ++ $echo ++ $echo "*** However, this would only work if libtool was able to extract symbol" ++ $echo "*** lists from a program, using `nm' or equivalent, but libtool could" ++ $echo "*** not find such a program. So, this module is probably useless." ++ $echo "*** `nm' from GNU binutils and a full rebuild may help." ++ fi ++ if test "$build_old_libs" = no; then ++ build_libtool_libs=module ++ build_old_libs=yes ++ else ++ build_libtool_libs=no ++ fi ++ fi ++ else ++ deplibs="$dir/$old_library $deplibs" ++ link_static=yes ++ fi ++ fi # link shared/static library? ++ ++ if test "$linkmode" = lib; then ++ if test -n "$dependency_libs" && ++ { test "$hardcode_into_libs" != yes || ++ test "$build_old_libs" = yes || ++ test "$link_static" = yes; }; then ++ # Extract -R from dependency_libs ++ temp_deplibs= ++ for libdir in $dependency_libs; do ++ case $libdir in ++ -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` ++ case " $xrpath " in ++ *" $temp_xrpath "*) ;; ++ *) xrpath="$xrpath $temp_xrpath";; ++ esac;; ++ *) temp_deplibs="$temp_deplibs $libdir";; ++ esac ++ done ++ dependency_libs="$temp_deplibs" ++ fi ++ ++ newlib_search_path="$newlib_search_path $absdir" ++ # Link against this library ++ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" ++ # ... and its dependency_libs ++ tmp_libs= ++ for deplib in $dependency_libs; do ++ newdependency_libs="$deplib $newdependency_libs" ++ if test "X$duplicate_deps" = "Xyes" ; then ++ case "$tmp_libs " in ++ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; ++ esac ++ fi ++ tmp_libs="$tmp_libs $deplib" ++ done ++ ++ if test "$link_all_deplibs" != no; then ++ # Add the search paths of all dependency libraries ++ for deplib in $dependency_libs; do ++ case $deplib in ++ -L*) path="$deplib" ;; ++ *.la) ++ dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$dir" = "X$deplib" && dir="." ++ # We need an absolute path. ++ case $dir in ++ [\/]* | [A-Za-z]:[\/]*) absdir="$dir" ;; ++ *) ++ absdir=`cd "$dir" && pwd` ++ if test -z "$absdir"; then ++ $echo "$modename: warning: cannot determine absolute directory name of `$dir'" 1>&2 ++ absdir="$dir" ++ fi ++ ;; ++ esac ++ if grep "^installed=no" $deplib > /dev/null; then ++ path="$absdir/$objdir" ++ else ++ eval libdir=`${SED} -n -e 's/^libdir=(.*)$/\1/p' $deplib` ++ if test -z "$libdir"; then ++ $echo "$modename: `$deplib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ if test "$absdir" != "$libdir"; then ++ $echo "$modename: warning: `$deplib' seems to be moved" 1>&2 ++ fi ++ path="$absdir" ++ fi ++ depdepl= ++ case $host in ++ *-*-darwin*) ++ # we do not want to link against static libs, ++ # but need to link against shared ++ eval deplibrary_names=`${SED} -n -e 's/^library_names=(.*)$/\1/p' $deplib` ++ if test -n "$deplibrary_names" ; then ++ for tmp in $deplibrary_names ; do ++ depdepl=$tmp ++ done ++ if test -f "$path/$depdepl" ; then ++ depdepl="$path/$depdepl" ++ fi ++ # do not add paths which are already there ++ case " $newlib_search_path " in ++ *" $path "*) ;; ++ *) newlib_search_path="$newlib_search_path $path";; ++ esac ++ fi ++ path="" ++ ;; ++ *) ++ path="-L$path" ++ ;; ++ esac ++ ;; ++ -l*) ++ case $host in ++ *-*-darwin*) ++ # Again, we only want to link against shared libraries ++ eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^-l,,"` ++ for tmp in $newlib_search_path ; do ++ if test -f "$tmp/lib$tmp_libs.dylib" ; then ++ eval depdepl="$tmp/lib$tmp_libs.dylib" ++ break ++ fi ++ done ++ path="" ++ ;; ++ *) continue ;; ++ esac ++ ;; ++ *) continue ;; ++ esac ++ case " $deplibs " in ++ *" $path "*) ;; ++ *) deplibs="$path $deplibs" ;; ++ esac ++ case " $deplibs " in ++ *" $depdepl "*) ;; ++ *) deplibs="$depdepl $deplibs" ;; ++ esac ++ done ++ fi # link_all_deplibs != no ++ fi # linkmode = lib ++ done # for deplib in $libs ++ dependency_libs="$newdependency_libs" ++ if test "$pass" = dlpreopen; then ++ # Link the dlpreopened libraries before other libraries ++ for deplib in $save_deplibs; do ++ deplibs="$deplib $deplibs" ++ done ++ fi ++ if test "$pass" != dlopen; then ++ if test "$pass" != conv; then ++ # Make sure lib_search_path contains only unique directories. ++ lib_search_path= ++ for dir in $newlib_search_path; do ++ case "$lib_search_path " in ++ *" $dir "*) ;; ++ *) lib_search_path="$lib_search_path $dir" ;; ++ esac ++ done ++ newlib_search_path= ++ fi ++ ++ if test "$linkmode,$pass" != "prog,link"; then ++ vars="deplibs" ++ else ++ vars="compile_deplibs finalize_deplibs" ++ fi ++ for var in $vars dependency_libs; do ++ # Add libraries to $var in reverse order ++ eval tmp_libs="$$var" ++ new_libs= ++ for deplib in $tmp_libs; do ++ # FIXME: Pedantically, this is the right thing to do, so ++ # that some nasty dependency loop isn't accidentally ++ # broken: ++ #new_libs="$deplib $new_libs" ++ # Pragmatically, this seems to cause very few problems in ++ # practice: ++ case $deplib in ++ -L*) new_libs="$deplib $new_libs" ;; ++ -R*) ;; ++ *) ++ # And here is the reason: when a library appears more ++ # than once as an explicit dependence of a library, or ++ # is implicitly linked in more than once by the ++ # compiler, it is considered special, and multiple ++ # occurrences thereof are not removed. Compare this ++ # with having the same library being listed as a ++ # dependency of multiple other libraries: in this case, ++ # we know (pedantically, we assume) the library does not ++ # need to be listed more than once, so we keep only the ++ # last copy. This is not always right, but it is rare ++ # enough that we require users that really mean to play ++ # such unportable linking tricks to link the library ++ # using -Wl,-lname, so that libtool does not consider it ++ # for duplicate removal. ++ case " $specialdeplibs " in ++ *" $deplib "*) new_libs="$deplib $new_libs" ;; ++ *) ++ case " $new_libs " in ++ *" $deplib "*) ;; ++ *) new_libs="$deplib $new_libs" ;; ++ esac ++ ;; ++ esac ++ ;; ++ esac ++ done ++ tmp_libs= ++ for deplib in $new_libs; do ++ case $deplib in ++ -L*) ++ case " $tmp_libs " in ++ *" $deplib "*) ;; ++ *) tmp_libs="$tmp_libs $deplib" ;; ++ esac ++ ;; ++ *) tmp_libs="$tmp_libs $deplib" ;; ++ esac ++ done ++ eval $var="$tmp_libs" ++ done # for var ++ fi ++ # Last step: remove runtime libs from dependency_libs ++ # (they stay in deplibs) ++ tmp_libs= ++ for i in $dependency_libs ; do ++ case " $predeps $postdeps $compiler_lib_search_path " in ++ *" $i "*) ++ i="" ++ ;; ++ esac ++ if test -n "$i" ; then ++ tmp_libs="$tmp_libs $i" ++ fi ++ done ++ dependency_libs=$tmp_libs ++ done # for pass ++ if test "$linkmode" = prog; then ++ dlfiles="$newdlfiles" ++ dlprefiles="$newdlprefiles" ++ fi ++ ++ case $linkmode in ++ oldlib) ++ if test -n "$deplibs"; then ++ $echo "$modename: warning: `-l' and `-L' are ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then ++ $echo "$modename: warning: `-dlopen' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$rpath"; then ++ $echo "$modename: warning: `-rpath' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$xrpath"; then ++ $echo "$modename: warning: `-R' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$vinfo"; then ++ $echo "$modename: warning: `-version-info/-version-number' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$release"; then ++ $echo "$modename: warning: `-release' is ignored for archives" 1>&2 ++ fi ++ ++ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then ++ $echo "$modename: warning: `-export-symbols' is ignored for archives" 1>&2 ++ fi ++ ++ # Now set the variables for building old libraries. ++ build_libtool_libs=no ++ oldlibs="$output" ++ objs="$objs$old_deplibs" ++ ;; ++ ++ lib) ++ # Make sure we only generate libraries of the form `libNAME.la'. ++ case $outputname in ++ lib*) ++ name=`$echo "X$outputname" | $Xsed -e 's/.la$//' -e 's/^lib//'` ++ eval shared_ext="$shrext_cmds" ++ eval libname="$libname_spec" ++ ;; ++ *) ++ if test "$module" = no; then ++ $echo "$modename: libtool library `$output' must begin with `lib'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ if test "$need_lib_prefix" != no; then ++ # Add the "lib" prefix for modules if required ++ name=`$echo "X$outputname" | $Xsed -e 's/.la$//'` ++ eval shared_ext="$shrext_cmds" ++ eval libname="$libname_spec" ++ else ++ libname=`$echo "X$outputname" | $Xsed -e 's/.la$//'` ++ fi ++ ;; ++ esac ++ ++ if test -n "$objs"; then ++ if test "$deplibs_check_method" != pass_all; then ++ $echo "$modename: cannot build libtool library `$output' from non-libtool objects on this host:$objs" 2>&1 ++ exit $EXIT_FAILURE ++ else ++ $echo ++ $echo "*** Warning: Linking the shared library $output against the non-libtool" ++ $echo "*** objects $objs is not portable!" ++ libobjs="$libobjs $objs" ++ fi ++ fi ++ ++ if test "$dlself" != no; then ++ $echo "$modename: warning: `-dlopen self' is ignored for libtool libraries" 1>&2 ++ fi ++ ++ set dummy $rpath ++ if test "$#" -gt 2; then ++ $echo "$modename: warning: ignoring multiple `-rpath's for a libtool library" 1>&2 ++ fi ++ install_libdir="$2" ++ ++ oldlibs= ++ if test -z "$rpath"; then ++ if test "$build_libtool_libs" = yes; then ++ # Building a libtool convenience library. ++ # Some compilers have problems with a `.al' extension so ++ # convenience libraries should have the same extension an ++ # archive normally would. ++ oldlibs="$output_objdir/$libname.$libext $oldlibs" ++ build_libtool_libs=convenience ++ build_old_libs=yes ++ fi ++ ++ if test -n "$vinfo"; then ++ $echo "$modename: warning: `-version-info/-version-number' is ignored for convenience libraries" 1>&2 ++ fi ++ ++ if test -n "$release"; then ++ $echo "$modename: warning: `-release' is ignored for convenience libraries" 1>&2 ++ fi ++ else ++ ++ # Parse the version information argument. ++ save_ifs="$IFS"; IFS=':' ++ set dummy $vinfo 0 0 0 ++ IFS="$save_ifs" ++ ++ if test -n "$8"; then ++ $echo "$modename: too many parameters to `-version-info'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # convert absolute version numbers to libtool ages ++ # this retains compatibility with .la files and attempts ++ # to make the code below a bit more comprehensible ++ ++ case $vinfo_number in ++ yes) ++ number_major="$2" ++ number_minor="$3" ++ number_revision="$4" ++ # ++ # There are really only two kinds -- those that ++ # use the current revision as the major version ++ # and those that subtract age and use age as ++ # a minor version. But, then there is irix ++ # which has an extra 1 added just for fun ++ # ++ case $version_type in ++ darwin|linux|osf|windows) ++ current=`expr $number_major + $number_minor` ++ age="$number_minor" ++ revision="$number_revision" ++ ;; ++ freebsd-aout|freebsd-elf|sunos) ++ current="$number_major" ++ revision="$number_minor" ++ age="0" ++ ;; ++ irix|nonstopux) ++ current=`expr $number_major + $number_minor - 1` ++ age="$number_minor" ++ revision="$number_minor" ++ ;; ++ esac ++ ;; ++ no) ++ current="$2" ++ revision="$3" ++ age="$4" ++ ;; ++ esac ++ ++ # Check that each of the things are valid numbers. ++ case $current in ++ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; ++ *) ++ $echo "$modename: CURRENT `$current' must be a nonnegative integer" 1>&2 ++ $echo "$modename: `$vinfo' is not valid version information" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ case $revision in ++ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; ++ *) ++ $echo "$modename: REVISION `$revision' must be a nonnegative integer" 1>&2 ++ $echo "$modename: `$vinfo' is not valid version information" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ case $age in ++ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; ++ *) ++ $echo "$modename: AGE `$age' must be a nonnegative integer" 1>&2 ++ $echo "$modename: `$vinfo' is not valid version information" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ if test "$age" -gt "$current"; then ++ $echo "$modename: AGE `$age' is greater than the current interface number `$current'" 1>&2 ++ $echo "$modename: `$vinfo' is not valid version information" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Calculate the version variables. ++ major= ++ versuffix= ++ verstring= ++ case $version_type in ++ none) ;; ++ ++ darwin) ++ # Like Linux, but with the current version available in ++ # verstring for coding it into the library header ++ major=.`expr $current - $age` ++ versuffix="$major.$age.$revision" ++ # Darwin ld doesn't like 0 for these options... ++ minor_current=`expr $current + 1` ++ verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" ++ ;; ++ ++ freebsd-aout) ++ major=".$current" ++ versuffix=".$current.$revision"; ++ ;; ++ ++ freebsd-elf) ++ major=".$current" ++ versuffix=".$current"; ++ ;; ++ ++ irix | nonstopux) ++ major=`expr $current - $age + 1` ++ ++ case $version_type in ++ nonstopux) verstring_prefix=nonstopux ;; ++ *) verstring_prefix=sgi ;; ++ esac ++ verstring="$verstring_prefix$major.$revision" ++ ++ # Add in all the interfaces that we are compatible with. ++ loop=$revision ++ while test "$loop" -ne 0; do ++ iface=`expr $revision - $loop` ++ loop=`expr $loop - 1` ++ verstring="$verstring_prefix$major.$iface:$verstring" ++ done ++ ++ # Before this point, $major must not contain `.'. ++ major=.$major ++ versuffix="$major.$revision" ++ ;; ++ ++ linux) ++ major=.`expr $current - $age` ++ versuffix="$major.$age.$revision" ++ ;; ++ ++ osf) ++ major=.`expr $current - $age` ++ versuffix=".$current.$age.$revision" ++ verstring="$current.$age.$revision" ++ ++ # Add in all the interfaces that we are compatible with. ++ loop=$age ++ while test "$loop" -ne 0; do ++ iface=`expr $current - $loop` ++ loop=`expr $loop - 1` ++ verstring="$verstring:${iface}.0" ++ done ++ ++ # Make executables depend on our current version. ++ verstring="$verstring:${current}.0" ++ ;; ++ ++ sunos) ++ major=".$current" ++ versuffix=".$current.$revision" ++ ;; ++ ++ windows) ++ # Use '-' rather than '.', since we only want one ++ # extension on DOS 8.3 filesystems. ++ major=`expr $current - $age` ++ versuffix="-$major" ++ ;; ++ ++ *) ++ $echo "$modename: unknown library version type `$version_type'" 1>&2 ++ $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ # Clear the version info if we defaulted, and they specified a release. ++ if test -z "$vinfo" && test -n "$release"; then ++ major= ++ case $version_type in ++ darwin) ++ # we can't check for "0.0" in archive_cmds due to quoting ++ # problems, so we reset it completely ++ verstring= ++ ;; ++ *) ++ verstring="0.0" ++ ;; ++ esac ++ if test "$need_version" = no; then ++ versuffix= ++ else ++ versuffix=".0.0" ++ fi ++ fi ++ ++ # Remove version info from name if versioning should be avoided ++ if test "$avoid_version" = yes && test "$need_version" = no; then ++ major= ++ versuffix= ++ verstring="" ++ fi ++ ++ # Check to see if the archive will have undefined symbols. ++ if test "$allow_undefined" = yes; then ++ if test "$allow_undefined_flag" = unsupported; then ++ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 ++ build_libtool_libs=no ++ build_old_libs=yes ++ fi ++ else ++ # Don't allow undefined symbols. ++ allow_undefined_flag="$no_undefined_flag" ++ fi ++ fi ++ ++ if test "$mode" != relink; then ++ # Remove our outputs, but don't remove object files since they ++ # may have been created when compiling PIC objects. ++ removelist= ++ tempremovelist=`$echo "$output_objdir/*"` ++ for p in $tempremovelist; do ++ case $p in ++ *.$objext) ++ ;; ++ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) ++ if test "X$precious_files_regex" != "X"; then ++ if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 ++ then ++ continue ++ fi ++ fi ++ removelist="$removelist $p" ++ ;; ++ *) ;; ++ esac ++ done ++ if test -n "$removelist"; then ++ $show "${rm}r $removelist" ++ $run ${rm}r $removelist ++ fi ++ fi ++ ++ # Now set the variables for building old libraries. ++ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then ++ oldlibs="$oldlibs $output_objdir/$libname.$libext" ++ ++ # Transform .lo files to .o files. ++ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/.'${libext}'$/d' -e "$lo2o" | $NL2SP` ++ fi ++ ++ # Eliminate all temporary directories. ++ for path in $notinst_path; do ++ lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` ++ deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` ++ dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` ++ done ++ ++ if test -n "$xrpath"; then ++ # If the user specified any rpath flags, then add them. ++ temp_xrpath= ++ for libdir in $xrpath; do ++ temp_xrpath="$temp_xrpath -R$libdir" ++ case "$finalize_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_rpath="$finalize_rpath $libdir" ;; ++ esac ++ done ++ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then ++ dependency_libs="$temp_xrpath $dependency_libs" ++ fi ++ fi ++ ++ # Make sure dlfiles contains only unique files that won't be dlpreopened ++ old_dlfiles="$dlfiles" ++ dlfiles= ++ for lib in $old_dlfiles; do ++ case " $dlprefiles $dlfiles " in ++ *" $lib "*) ;; ++ *) dlfiles="$dlfiles $lib" ;; ++ esac ++ done ++ ++ # Make sure dlprefiles contains only unique files ++ old_dlprefiles="$dlprefiles" ++ dlprefiles= ++ for lib in $old_dlprefiles; do ++ case "$dlprefiles " in ++ *" $lib "*) ;; ++ *) dlprefiles="$dlprefiles $lib" ;; ++ esac ++ done ++ ++ if test "$build_libtool_libs" = yes; then ++ if test -n "$rpath"; then ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) ++ # these systems don't actually have a c library (as such)! ++ ;; ++ *-*-rhapsody* | *-*-darwin1.[012]) ++ # Rhapsody C library is in the System framework ++ deplibs="$deplibs -framework System" ++ ;; ++ *-*-netbsd*) ++ # Don't link with libc until the a.out ld.so is fixed. ++ ;; ++ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) ++ # Do not include libc due to us having libc/libc_r. ++ ;; ++ *-*-sco3.2v5* | *-*-sco5v6*) ++ # Causes problems with __ctype ++ ;; ++ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) ++ # Compiler inserts libc in the correct place for threads to work ++ ;; ++ *) ++ # Add libc to deplibs on all other systems if necessary. ++ if test "$build_libtool_need_lc" = "yes"; then ++ deplibs="$deplibs -lc" ++ fi ++ ;; ++ esac ++ fi ++ ++ # Transform deplibs into only deplibs that can be linked in shared. ++ name_save=$name ++ libname_save=$libname ++ release_save=$release ++ versuffix_save=$versuffix ++ major_save=$major ++ # I'm not sure if I'm treating the release correctly. I think ++ # release should show up in the -l (ie -lgmp5) so we don't want to ++ # add it in twice. Is that correct? ++ release="" ++ versuffix="" ++ major="" ++ newdeplibs= ++ droppeddeps=no ++ case $deplibs_check_method in ++ pass_all) ++ # Don't check for shared/static. Everything works. ++ # This might be a little naive. We might want to check ++ # whether the library exists or not. But this is on ++ # osf3 & osf4 and I'm not really sure... Just ++ # implementing what was already the behavior. ++ newdeplibs=$deplibs ++ ;; ++ test_compile) ++ # This code stresses the "libraries are programs" paradigm to its ++ # limits. Maybe even breaks it. We compile a program, linking it ++ # against the deplibs as a proxy for the library. Then we can check ++ # whether they linked in statically or dynamically with ldd. ++ $rm conftest.c ++ cat > conftest.c <<EOF ++ int main() { return 0; } ++EOF ++ $rm conftest ++ $LTCC $LTCFLAGS -o conftest conftest.c $deplibs ++ if test "$?" -eq 0 ; then ++ ldd_output=`ldd conftest` ++ for i in $deplibs; do ++ name=`expr $i : '-l(.*)'` ++ # If $name is empty we are operating on a -L argument. ++ if test "$name" != "" && test "$name" -ne "0"; then ++ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then ++ case " $predeps $postdeps " in ++ *" $i "*) ++ newdeplibs="$newdeplibs $i" ++ i="" ++ ;; ++ esac ++ fi ++ if test -n "$i" ; then ++ libname=`eval \$echo "$libname_spec"` ++ deplib_matches=`eval \$echo "$library_names_spec"` ++ set dummy $deplib_matches ++ deplib_match=$2 ++ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then ++ newdeplibs="$newdeplibs $i" ++ else ++ droppeddeps=yes ++ $echo ++ $echo "*** Warning: dynamic linker does not accept needed library $i." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which I believe you do not have" ++ $echo "*** because a test_compile did reveal that the linker did not use it for" ++ $echo "*** its dynamic dependency list that programs get resolved with at runtime." ++ fi ++ fi ++ else ++ newdeplibs="$newdeplibs $i" ++ fi ++ done ++ else ++ # Error occurred in the first compile. Let's try to salvage ++ # the situation: Compile a separate program for each library. ++ for i in $deplibs; do ++ name=`expr $i : '-l(.*)'` ++ # If $name is empty we are operating on a -L argument. ++ if test "$name" != "" && test "$name" != "0"; then ++ $rm conftest ++ $LTCC $LTCFLAGS -o conftest conftest.c $i ++ # Did it work? ++ if test "$?" -eq 0 ; then ++ ldd_output=`ldd conftest` ++ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then ++ case " $predeps $postdeps " in ++ *" $i "*) ++ newdeplibs="$newdeplibs $i" ++ i="" ++ ;; ++ esac ++ fi ++ if test -n "$i" ; then ++ libname=`eval \$echo "$libname_spec"` ++ deplib_matches=`eval \$echo "$library_names_spec"` ++ set dummy $deplib_matches ++ deplib_match=$2 ++ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then ++ newdeplibs="$newdeplibs $i" ++ else ++ droppeddeps=yes ++ $echo ++ $echo "*** Warning: dynamic linker does not accept needed library $i." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which you do not appear to have" ++ $echo "*** because a test_compile did reveal that the linker did not use this one" ++ $echo "*** as a dynamic dependency that programs can get resolved with at runtime." ++ fi ++ fi ++ else ++ droppeddeps=yes ++ $echo ++ $echo "*** Warning! Library $i is needed by this library but I was not able to" ++ $echo "*** make it link in! You will probably need to install it or some" ++ $echo "*** library that it depends on before this library will be fully" ++ $echo "*** functional. Installing it before continuing would be even better." ++ fi ++ else ++ newdeplibs="$newdeplibs $i" ++ fi ++ done ++ fi ++ ;; ++ file_magic*) ++ set dummy $deplibs_check_method ++ file_magic_regex=`expr "$deplibs_check_method" : "$2 (.*)"` ++ for a_deplib in $deplibs; do ++ name=`expr $a_deplib : '-l(.*)'` ++ # If $name is empty we are operating on a -L argument. ++ if test "$name" != "" && test "$name" != "0"; then ++ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then ++ case " $predeps $postdeps " in ++ *" $a_deplib "*) ++ newdeplibs="$newdeplibs $a_deplib" ++ a_deplib="" ++ ;; ++ esac ++ fi ++ if test -n "$a_deplib" ; then ++ libname=`eval \$echo "$libname_spec"` ++ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do ++ potential_libs=`ls $i/$libname[.-]* 2>/dev/null` ++ for potent_lib in $potential_libs; do ++ # Follow soft links. ++ if ls -lLd "$potent_lib" 2>/dev/null \ ++ | grep " -> " >/dev/null; then ++ continue ++ fi ++ # The statement above tries to avoid entering an ++ # endless loop below, in case of cyclic links. ++ # We might still enter an endless loop, since a link ++ # loop can be closed while we follow links, ++ # but so what? ++ potlib="$potent_lib" ++ while test -h "$potlib" 2>/dev/null; do ++ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` ++ case $potliblink in ++ [\/]* | [A-Za-z]:[\/]*) potlib="$potliblink";; ++ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; ++ esac ++ done ++ # It is ok to link against an archive when ++ # building a shared library. ++ if $AR -t $potlib > /dev/null 2>&1; then ++ newdeplibs="$newdeplibs $a_deplib" ++ a_deplib="" ++ break 2 ++ fi ++ if eval $file_magic_cmd "$potlib" 2>/dev/null \ ++ | ${SED} 10q \ ++ | $EGREP "$file_magic_regex" > /dev/null; then ++ newdeplibs="$newdeplibs $a_deplib" ++ a_deplib="" ++ break 2 ++ fi ++ done ++ done ++ fi ++ if test -n "$a_deplib" ; then ++ droppeddeps=yes ++ $echo ++ $echo "*** Warning: linker path does not have real file for library $a_deplib." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which you do not appear to have" ++ $echo "*** because I did check the linker path looking for a file starting" ++ if test -z "$potlib" ; then ++ $echo "*** with $libname but no candidates were found. (...for file magic test)" ++ else ++ $echo "*** with $libname and none of the candidates passed a file format test" ++ $echo "*** using a file magic. Last file checked: $potlib" ++ fi ++ fi ++ else ++ # Add a -L argument. ++ newdeplibs="$newdeplibs $a_deplib" ++ fi ++ done # Gone through all deplibs. ++ ;; ++ match_pattern*) ++ set dummy $deplibs_check_method ++ match_pattern_regex=`expr "$deplibs_check_method" : "$2 (.*)"` ++ for a_deplib in $deplibs; do ++ name=`expr $a_deplib : '-l(.*)'` ++ # If $name is empty we are operating on a -L argument. ++ if test -n "$name" && test "$name" != "0"; then ++ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then ++ case " $predeps $postdeps " in ++ *" $a_deplib "*) ++ newdeplibs="$newdeplibs $a_deplib" ++ a_deplib="" ++ ;; ++ esac ++ fi ++ if test -n "$a_deplib" ; then ++ libname=`eval \$echo "$libname_spec"` ++ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do ++ potential_libs=`ls $i/$libname[.-]* 2>/dev/null` ++ for potent_lib in $potential_libs; do ++ potlib="$potent_lib" # see symlink-check above in file_magic test ++ if eval $echo "$potent_lib" 2>/dev/null \ ++ | ${SED} 10q \ ++ | $EGREP "$match_pattern_regex" > /dev/null; then ++ newdeplibs="$newdeplibs $a_deplib" ++ a_deplib="" ++ break 2 ++ fi ++ done ++ done ++ fi ++ if test -n "$a_deplib" ; then ++ droppeddeps=yes ++ $echo ++ $echo "*** Warning: linker path does not have real file for library $a_deplib." ++ $echo "*** I have the capability to make that library automatically link in when" ++ $echo "*** you link to this library. But I can only do this if you have a" ++ $echo "*** shared version of the library, which you do not appear to have" ++ $echo "*** because I did check the linker path looking for a file starting" ++ if test -z "$potlib" ; then ++ $echo "*** with $libname but no candidates were found. (...for regex pattern test)" ++ else ++ $echo "*** with $libname and none of the candidates passed a file format test" ++ $echo "*** using a regex pattern. Last file checked: $potlib" ++ fi ++ fi ++ else ++ # Add a -L argument. ++ newdeplibs="$newdeplibs $a_deplib" ++ fi ++ done # Gone through all deplibs. ++ ;; ++ none | unknown | *) ++ newdeplibs="" ++ tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ ++ -e 's/ -[LR][^ ]*//g'` ++ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then ++ for i in $predeps $postdeps ; do ++ # can't use Xsed below, because $i might contain '/' ++ tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` ++ done ++ fi ++ if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ ++ | grep . >/dev/null; then ++ $echo ++ if test "X$deplibs_check_method" = "Xnone"; then ++ $echo "*** Warning: inter-library dependencies are not supported in this platform." ++ else ++ $echo "*** Warning: inter-library dependencies are not known to be supported." ++ fi ++ $echo "*** All declared inter-library dependencies are being dropped." ++ droppeddeps=yes ++ fi ++ ;; ++ esac ++ versuffix=$versuffix_save ++ major=$major_save ++ release=$release_save ++ libname=$libname_save ++ name=$name_save ++ ++ case $host in ++ *-*-rhapsody* | *-*-darwin1.[012]) ++ # On Rhapsody replace the C library is the System framework ++ newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` ++ ;; ++ esac ++ ++ if test "$droppeddeps" = yes; then ++ if test "$module" = yes; then ++ $echo ++ $echo "*** Warning: libtool could not satisfy all declared inter-library" ++ $echo "*** dependencies of module $libname. Therefore, libtool will create" ++ $echo "*** a static module, that should work as long as the dlopening" ++ $echo "*** application is linked with the -dlopen flag." ++ if test -z "$global_symbol_pipe"; then ++ $echo ++ $echo "*** However, this would only work if libtool was able to extract symbol" ++ $echo "*** lists from a program, using `nm' or equivalent, but libtool could" ++ $echo "*** not find such a program. So, this module is probably useless." ++ $echo "*** `nm' from GNU binutils and a full rebuild may help." ++ fi ++ if test "$build_old_libs" = no; then ++ oldlibs="$output_objdir/$libname.$libext" ++ build_libtool_libs=module ++ build_old_libs=yes ++ else ++ build_libtool_libs=no ++ fi ++ else ++ $echo "*** The inter-library dependencies that have been dropped here will be" ++ $echo "*** automatically added whenever a program is linked with this library" ++ $echo "*** or is declared to -dlopen it." ++ ++ if test "$allow_undefined" = no; then ++ $echo ++ $echo "*** Since this library must not contain undefined symbols," ++ $echo "*** because either the platform does not support them or" ++ $echo "*** it was explicitly requested with -no-undefined," ++ $echo "*** libtool will only create a static version of it." ++ if test "$build_old_libs" = no; then ++ oldlibs="$output_objdir/$libname.$libext" ++ build_libtool_libs=module ++ build_old_libs=yes ++ else ++ build_libtool_libs=no ++ fi ++ fi ++ fi ++ fi ++ # Done checking deplibs! ++ deplibs=$newdeplibs ++ fi ++ ++ ++ # move library search paths that coincide with paths to not yet ++ # installed libraries to the beginning of the library search list ++ new_libs= ++ for path in $notinst_path; do ++ case " $new_libs " in ++ *" -L$path/$objdir "*) ;; ++ *) ++ case " $deplibs " in ++ *" -L$path/$objdir "*) ++ new_libs="$new_libs -L$path/$objdir" ;; ++ esac ++ ;; ++ esac ++ done ++ for deplib in $deplibs; do ++ case $deplib in ++ -L*) ++ case " $new_libs " in ++ *" $deplib "*) ;; ++ *) new_libs="$new_libs $deplib" ;; ++ esac ++ ;; ++ *) new_libs="$new_libs $deplib" ;; ++ esac ++ done ++ deplibs="$new_libs" ++ ++ ++ # All the library-specific variables (install_libdir is set above). ++ library_names= ++ old_library= ++ dlname= ++ ++ # Test again, we may have decided not to build it any more ++ if test "$build_libtool_libs" = yes; then ++ if test "$hardcode_into_libs" = yes; then ++ # Hardcode the library paths ++ hardcode_libdirs= ++ dep_rpath= ++ rpath="$finalize_rpath" ++ test "$mode" != relink && rpath="$compile_rpath$rpath" ++ for libdir in $rpath; do ++ if test -n "$hardcode_libdir_flag_spec"; then ++ if test -n "$hardcode_libdir_separator"; then ++ if test -z "$hardcode_libdirs"; then ++ hardcode_libdirs="$libdir" ++ else ++ # Just accumulate the unique libdirs. ++ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in ++ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ++ ;; ++ *) ++ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ++ ;; ++ esac ++ fi ++ else ++ eval flag="$hardcode_libdir_flag_spec" ++ dep_rpath="$dep_rpath $flag" ++ fi ++ elif test -n "$runpath_var"; then ++ case "$perm_rpath " in ++ *" $libdir "*) ;; ++ *) perm_rpath="$perm_rpath $libdir" ;; ++ esac ++ fi ++ done ++ # Substitute the hardcoded libdirs into the rpath. ++ if test -n "$hardcode_libdir_separator" && ++ test -n "$hardcode_libdirs"; then ++ libdir="$hardcode_libdirs" ++ if test -n "$hardcode_libdir_flag_spec_ld"; then ++ eval dep_rpath="$hardcode_libdir_flag_spec_ld" ++ else ++ eval dep_rpath="$hardcode_libdir_flag_spec" ++ fi ++ fi ++ if test -n "$runpath_var" && test -n "$perm_rpath"; then ++ # We should set the runpath_var. ++ rpath= ++ for dir in $perm_rpath; do ++ rpath="$rpath$dir:" ++ done ++ eval "$runpath_var='$rpath$$runpath_var'; export $runpath_var" ++ fi ++ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" ++ fi ++ ++ shlibpath="$finalize_shlibpath" ++ test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" ++ if test -n "$shlibpath"; then ++ eval "$shlibpath_var='$shlibpath$$shlibpath_var'; export $shlibpath_var" ++ fi ++ ++ # Get the real and link names of the library. ++ eval shared_ext="$shrext_cmds" ++ eval library_names="$library_names_spec" ++ set dummy $library_names ++ realname="$2" ++ shift; shift ++ ++ if test -n "$soname_spec"; then ++ eval soname="$soname_spec" ++ else ++ soname="$realname" ++ fi ++ if test -z "$dlname"; then ++ dlname=$soname ++ fi ++ ++ lib="$output_objdir/$realname" ++ linknames= ++ for link ++ do ++ linknames="$linknames $link" ++ done ++ ++ # Use standard objects if they are pic ++ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` ++ ++ # Prepare the list of exported symbols ++ if test -z "$export_symbols"; then ++ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then ++ $show "generating symbol list for `$libname.la'" ++ export_symbols="$output_objdir/$libname.exp" ++ $run $rm $export_symbols ++ cmds=$export_symbols_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ if len=`expr "X$cmd" : ".*"` && ++ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ skipped_export=false ++ else ++ # The command line is too long to execute in one step. ++ $show "using reloadable object file for export list..." ++ skipped_export=: ++ # Break out early, otherwise skipped_export may be ++ # set to false by a later but shorter cmd. ++ break ++ fi ++ done ++ IFS="$save_ifs" ++ if test -n "$export_symbols_regex"; then ++ $show "$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"" ++ $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' ++ $show "$mv "${export_symbols}T" "$export_symbols"" ++ $run eval '$mv "${export_symbols}T" "$export_symbols"' ++ fi ++ fi ++ fi ++ ++ if test -n "$export_symbols" && test -n "$include_expsyms"; then ++ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' ++ fi ++ ++ tmp_deplibs= ++ for test_deplib in $deplibs; do ++ case " $convenience " in ++ *" $test_deplib "*) ;; ++ *) ++ tmp_deplibs="$tmp_deplibs $test_deplib" ++ ;; ++ esac ++ done ++ deplibs="$tmp_deplibs" ++ ++ if test -n "$convenience"; then ++ if test -n "$whole_archive_flag_spec"; then ++ save_libobjs=$libobjs ++ eval libobjs="$libobjs $whole_archive_flag_spec" ++ else ++ gentop="$output_objdir/${outputname}x" ++ generated="$generated $gentop" ++ ++ func_extract_archives $gentop $convenience ++ libobjs="$libobjs $func_extract_archives_result" ++ fi ++ fi ++ ++ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then ++ eval flag="$thread_safe_flag_spec" ++ linker_flags="$linker_flags $flag" ++ fi ++ ++ # Make a backup of the uninstalled library when relinking ++ if test "$mode" = relink; then ++ $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? ++ fi ++ ++ # Do each of the archive commands. ++ if test "$module" = yes && test -n "$module_cmds" ; then ++ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then ++ eval test_cmds="$module_expsym_cmds" ++ cmds=$module_expsym_cmds ++ else ++ eval test_cmds="$module_cmds" ++ cmds=$module_cmds ++ fi ++ else ++ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then ++ eval test_cmds="$archive_expsym_cmds" ++ cmds=$archive_expsym_cmds ++ else ++ eval test_cmds="$archive_cmds" ++ cmds=$archive_cmds ++ fi ++ fi ++ ++ if test "X$skipped_export" != "X:" && ++ len=`expr "X$test_cmds" : ".*" 2>/dev/null` && ++ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then ++ : ++ else ++ # The command line is too long to link in one step, link piecewise. ++ $echo "creating reloadable object files..." ++ ++ # Save the value of $output and $libobjs because we want to ++ # use them later. If we have whole_archive_flag_spec, we ++ # want to use save_libobjs as it was before ++ # whole_archive_flag_spec was expanded, because we can't ++ # assume the linker understands whole_archive_flag_spec. ++ # This may have to be revisited, in case too many ++ # convenience libraries get linked in and end up exceeding ++ # the spec. ++ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then ++ save_libobjs=$libobjs ++ fi ++ save_output=$output ++ output_la=`$echo "X$output" | $Xsed -e "$basename"` ++ ++ # Clear the reloadable object creation command queue and ++ # initialize k to one. ++ test_cmds= ++ concat_cmds= ++ objlist= ++ delfiles= ++ last_robj= ++ k=1 ++ output=$output_objdir/$output_la-${k}.$objext ++ # Loop over the list of objects to be linked. ++ for obj in $save_libobjs ++ do ++ eval test_cmds="$reload_cmds $objlist $last_robj" ++ if test "X$objlist" = X || ++ { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && ++ test "$len" -le "$max_cmd_len"; }; then ++ objlist="$objlist $obj" ++ else ++ # The command $test_cmds is almost too long, add a ++ # command to the queue. ++ if test "$k" -eq 1 ; then ++ # The first file doesn't have a previous command to add. ++ eval concat_cmds="$reload_cmds $objlist $last_robj" ++ else ++ # All subsequent reloadable object files will link in ++ # the last one created. ++ eval concat_cmds="$concat_cmds~$reload_cmds $objlist $last_robj" ++ fi ++ last_robj=$output_objdir/$output_la-${k}.$objext ++ k=`expr $k + 1` ++ output=$output_objdir/$output_la-${k}.$objext ++ objlist=$obj ++ len=1 ++ fi ++ done ++ # Handle the remaining objects by creating one last ++ # reloadable object file. All subsequent reloadable object ++ # files will link in the last one created. ++ test -z "$concat_cmds" || concat_cmds=$concat_cmds~ ++ eval concat_cmds="${concat_cmds}$reload_cmds $objlist $last_robj" ++ ++ if ${skipped_export-false}; then ++ $show "generating symbol list for `$libname.la'" ++ export_symbols="$output_objdir/$libname.exp" ++ $run $rm $export_symbols ++ libobjs=$output ++ # Append the command to create the export file. ++ eval concat_cmds="$concat_cmds~$export_symbols_cmds" ++ fi ++ ++ # Set up a command to remove the reloadable object files ++ # after they are used. ++ i=0 ++ while test "$i" -lt "$k" ++ do ++ i=`expr $i + 1` ++ delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" ++ done ++ ++ $echo "creating a temporary reloadable object file: $output" ++ ++ # Loop through the commands generated above and execute them. ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $concat_cmds; do ++ IFS="$save_ifs" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ ++ libobjs=$output ++ # Restore the value of output. ++ output=$save_output ++ ++ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then ++ eval libobjs="$libobjs $whole_archive_flag_spec" ++ fi ++ # Expand the library linking commands again to reset the ++ # value of $libobjs for piecewise linking. ++ ++ # Do each of the archive commands. ++ if test "$module" = yes && test -n "$module_cmds" ; then ++ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then ++ cmds=$module_expsym_cmds ++ else ++ cmds=$module_cmds ++ fi ++ else ++ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then ++ cmds=$archive_expsym_cmds ++ else ++ cmds=$archive_cmds ++ fi ++ fi ++ ++ # Append the command to remove the reloadable object files ++ # to the just-reset $cmds. ++ eval cmds="$cmds~$rm $delfiles" ++ fi ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" || { ++ lt_exit=$? ++ ++ # Restore the uninstalled library and exit ++ if test "$mode" = relink; then ++ $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' ++ fi ++ ++ exit $lt_exit ++ } ++ done ++ IFS="$save_ifs" ++ ++ # Restore the uninstalled library and exit ++ if test "$mode" = relink; then ++ $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? ++ ++ if test -n "$convenience"; then ++ if test -z "$whole_archive_flag_spec"; then ++ $show "${rm}r $gentop" ++ $run ${rm}r "$gentop" ++ fi ++ fi ++ ++ exit $EXIT_SUCCESS ++ fi ++ ++ # Create links to the real library. ++ for linkname in $linknames; do ++ if test "$realname" != "$linkname"; then ++ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" ++ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? ++ fi ++ done ++ ++ # If -module or -export-dynamic was specified, set the dlname. ++ if test "$module" = yes || test "$export_dynamic" = yes; then ++ # On all known operating systems, these are identical. ++ dlname="$soname" ++ fi ++ fi ++ ;; ++ ++ obj) ++ if test -n "$deplibs"; then ++ $echo "$modename: warning: `-l' and `-L' are ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then ++ $echo "$modename: warning: `-dlopen' is ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$rpath"; then ++ $echo "$modename: warning: `-rpath' is ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$xrpath"; then ++ $echo "$modename: warning: `-R' is ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$vinfo"; then ++ $echo "$modename: warning: `-version-info' is ignored for objects" 1>&2 ++ fi ++ ++ if test -n "$release"; then ++ $echo "$modename: warning: `-release' is ignored for objects" 1>&2 ++ fi ++ ++ case $output in ++ *.lo) ++ if test -n "$objs$old_deplibs"; then ++ $echo "$modename: cannot build library object `$output' from non-libtool objects" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ libobj="$output" ++ obj=`$echo "X$output" | $Xsed -e "$lo2o"` ++ ;; ++ *) ++ libobj= ++ obj="$output" ++ ;; ++ esac ++ ++ # Delete the old objects. ++ $run $rm $obj $libobj ++ ++ # Objects from convenience libraries. This assumes ++ # single-version convenience libraries. Whenever we create ++ # different ones for PIC/non-PIC, this we'll have to duplicate ++ # the extraction. ++ reload_conv_objs= ++ gentop= ++ # reload_cmds runs $LD directly, so let us get rid of ++ # -Wl from whole_archive_flag_spec ++ wl= ++ ++ if test -n "$convenience"; then ++ if test -n "$whole_archive_flag_spec"; then ++ eval reload_conv_objs="$reload_objs $whole_archive_flag_spec" ++ else ++ gentop="$output_objdir/${obj}x" ++ generated="$generated $gentop" ++ ++ func_extract_archives $gentop $convenience ++ reload_conv_objs="$reload_objs $func_extract_archives_result" ++ fi ++ fi ++ ++ # Create the old-style object. ++ reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/.'${libext}$'/d' -e '/.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test ++ ++ output="$obj" ++ cmds=$reload_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ ++ # Exit if we aren't doing a library object file. ++ if test -z "$libobj"; then ++ if test -n "$gentop"; then ++ $show "${rm}r $gentop" ++ $run ${rm}r $gentop ++ fi ++ ++ exit $EXIT_SUCCESS ++ fi ++ ++ if test "$build_libtool_libs" != yes; then ++ if test -n "$gentop"; then ++ $show "${rm}r $gentop" ++ $run ${rm}r $gentop ++ fi ++ ++ # Create an invalid libtool object if no PIC, so that we don't ++ # accidentally link it into a program. ++ # $show "echo timestamp > $libobj" ++ # $run eval "echo timestamp > $libobj" || exit $? ++ exit $EXIT_SUCCESS ++ fi ++ ++ if test -n "$pic_flag" || test "$pic_mode" != default; then ++ # Only do commands if we really have different PIC objects. ++ reload_objs="$libobjs $reload_conv_objs" ++ output="$libobj" ++ cmds=$reload_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ fi ++ ++ if test -n "$gentop"; then ++ $show "${rm}r $gentop" ++ $run ${rm}r $gentop ++ fi ++ ++ exit $EXIT_SUCCESS ++ ;; ++ ++ prog) ++ case $host in ++ *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; ++ esac ++ if test -n "$vinfo"; then ++ $echo "$modename: warning: `-version-info' is ignored for programs" 1>&2 ++ fi ++ ++ if test -n "$release"; then ++ $echo "$modename: warning: `-release' is ignored for programs" 1>&2 ++ fi ++ ++ if test "$preload" = yes; then ++ if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && ++ test "$dlopen_self_static" = unknown; then ++ $echo "$modename: warning: `AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." ++ fi ++ fi ++ ++ case $host in ++ *-*-rhapsody* | *-*-darwin1.[012]) ++ # On Rhapsody replace the C library is the System framework ++ compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` ++ finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` ++ ;; ++ esac ++ ++ case $host in ++ *darwin*) ++ # Don't allow lazy linking, it breaks C++ global constructors ++ if test "$tagname" = CXX ; then ++ compile_command="$compile_command ${wl}-bind_at_load" ++ finalize_command="$finalize_command ${wl}-bind_at_load" ++ fi ++ ;; ++ esac ++ ++ ++ # move library search paths that coincide with paths to not yet ++ # installed libraries to the beginning of the library search list ++ new_libs= ++ for path in $notinst_path; do ++ case " $new_libs " in ++ *" -L$path/$objdir "*) ;; ++ *) ++ case " $compile_deplibs " in ++ *" -L$path/$objdir "*) ++ new_libs="$new_libs -L$path/$objdir" ;; ++ esac ++ ;; ++ esac ++ done ++ for deplib in $compile_deplibs; do ++ case $deplib in ++ -L*) ++ case " $new_libs " in ++ *" $deplib "*) ;; ++ *) new_libs="$new_libs $deplib" ;; ++ esac ++ ;; ++ *) new_libs="$new_libs $deplib" ;; ++ esac ++ done ++ compile_deplibs="$new_libs" ++ ++ ++ compile_command="$compile_command $compile_deplibs" ++ finalize_command="$finalize_command $finalize_deplibs" ++ ++ if test -n "$rpath$xrpath"; then ++ # If the user specified any rpath flags, then add them. ++ for libdir in $rpath $xrpath; do ++ # This is the magic to use -rpath. ++ case "$finalize_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_rpath="$finalize_rpath $libdir" ;; ++ esac ++ done ++ fi ++ ++ # Now hardcode the library paths ++ rpath= ++ hardcode_libdirs= ++ for libdir in $compile_rpath $finalize_rpath; do ++ if test -n "$hardcode_libdir_flag_spec"; then ++ if test -n "$hardcode_libdir_separator"; then ++ if test -z "$hardcode_libdirs"; then ++ hardcode_libdirs="$libdir" ++ else ++ # Just accumulate the unique libdirs. ++ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in ++ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ++ ;; ++ *) ++ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ++ ;; ++ esac ++ fi ++ else ++ eval flag="$hardcode_libdir_flag_spec" ++ rpath="$rpath $flag" ++ fi ++ elif test -n "$runpath_var"; then ++ case "$perm_rpath " in ++ *" $libdir "*) ;; ++ *) perm_rpath="$perm_rpath $libdir" ;; ++ esac ++ fi ++ case $host in ++ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) ++ testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` ++ case :$dllsearchpath: in ++ *":$libdir:"*) ;; ++ *) dllsearchpath="$dllsearchpath:$libdir";; ++ esac ++ case :$dllsearchpath: in ++ *":$testbindir:"*) ;; ++ *) dllsearchpath="$dllsearchpath:$testbindir";; ++ esac ++ ;; ++ esac ++ done ++ # Substitute the hardcoded libdirs into the rpath. ++ if test -n "$hardcode_libdir_separator" && ++ test -n "$hardcode_libdirs"; then ++ libdir="$hardcode_libdirs" ++ eval rpath=" $hardcode_libdir_flag_spec" ++ fi ++ compile_rpath="$rpath" ++ ++ rpath= ++ hardcode_libdirs= ++ for libdir in $finalize_rpath; do ++ if test -n "$hardcode_libdir_flag_spec"; then ++ if test -n "$hardcode_libdir_separator"; then ++ if test -z "$hardcode_libdirs"; then ++ hardcode_libdirs="$libdir" ++ else ++ # Just accumulate the unique libdirs. ++ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in ++ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ++ ;; ++ *) ++ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ++ ;; ++ esac ++ fi ++ else ++ eval flag="$hardcode_libdir_flag_spec" ++ rpath="$rpath $flag" ++ fi ++ elif test -n "$runpath_var"; then ++ case "$finalize_perm_rpath " in ++ *" $libdir "*) ;; ++ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; ++ esac ++ fi ++ done ++ # Substitute the hardcoded libdirs into the rpath. ++ if test -n "$hardcode_libdir_separator" && ++ test -n "$hardcode_libdirs"; then ++ libdir="$hardcode_libdirs" ++ eval rpath=" $hardcode_libdir_flag_spec" ++ fi ++ finalize_rpath="$rpath" ++ ++ if test -n "$libobjs" && test "$build_old_libs" = yes; then ++ # Transform all the library objects into standard objects. ++ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` ++ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` ++ fi ++ ++ dlsyms= ++ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then ++ if test -n "$NM" && test -n "$global_symbol_pipe"; then ++ dlsyms="${outputname}S.c" ++ else ++ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 ++ fi ++ fi ++ ++ if test -n "$dlsyms"; then ++ case $dlsyms in ++ "") ;; ++ *.c) ++ # Discover the nlist of each of the dlfiles. ++ nlist="$output_objdir/${outputname}.nm" ++ ++ $show "$rm $nlist ${nlist}S ${nlist}T" ++ $run $rm "$nlist" "${nlist}S" "${nlist}T" ++ ++ # Parse the name list into a source file. ++ $show "creating $output_objdir/$dlsyms" ++ ++ test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ ++/* $dlsyms - symbol resolution table for `$outputname' dlsym emulation. */ ++/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* Prevent the only kind of declaration conflicts we can make. */ ++#define lt_preloaded_symbols some_other_symbol ++ ++/* External symbol declarations for the compiler. */\ ++" ++ ++ if test "$dlself" = yes; then ++ $show "generating symbol list for `$output'" ++ ++ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" ++ ++ # Add our own program objects to the symbol list. ++ progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` ++ for arg in $progfiles; do ++ $show "extracting global C symbols from `$arg'" ++ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" ++ done ++ ++ if test -n "$exclude_expsyms"; then ++ $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' ++ $run eval '$mv "$nlist"T "$nlist"' ++ fi ++ ++ if test -n "$export_symbols_regex"; then ++ $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' ++ $run eval '$mv "$nlist"T "$nlist"' ++ fi ++ ++ # Prepare the list of exported symbols ++ if test -z "$export_symbols"; then ++ export_symbols="$output_objdir/$outputname.exp" ++ $run $rm $export_symbols ++ $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* (.*)$/\1/p' "'< "$nlist" > "$export_symbols"' ++ case $host in ++ *cygwin* | *mingw* ) ++ $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' ++ $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ++ ;; ++ esac ++ else ++ $run eval "${SED} -e 's/([].[*^$])/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' ++ $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' ++ $run eval 'mv "$nlist"T "$nlist"' ++ case $host in ++ *cygwin* | *mingw* ) ++ $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' ++ $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ++ ;; ++ esac ++ fi ++ fi ++ ++ for arg in $dlprefiles; do ++ $show "extracting global C symbols from `$arg'" ++ name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` ++ $run eval '$echo ": $name " >> "$nlist"' ++ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" ++ done ++ ++ if test -z "$run"; then ++ # Make sure we have at least an empty file. ++ test -f "$nlist" || : > "$nlist" ++ ++ if test -n "$exclude_expsyms"; then ++ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T ++ $mv "$nlist"T "$nlist" ++ fi ++ ++ # Try sorting and uniquifying the output. ++ if grep -v "^: " < "$nlist" | ++ if sort -k 3 </dev/null >/dev/null 2>&1; then ++ sort -k 3 ++ else ++ sort +2 ++ fi | ++ uniq > "$nlist"S; then ++ : ++ else ++ grep -v "^: " < "$nlist" > "$nlist"S ++ fi ++ ++ if test -f "$nlist"S; then ++ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' ++ else ++ $echo '/* NONE */' >> "$output_objdir/$dlsyms" ++ fi ++ ++ $echo >> "$output_objdir/$dlsyms" "\ ++ ++#undef lt_preloaded_symbols ++ ++#if defined (__STDC__) && __STDC__ ++# define lt_ptr void * ++#else ++# define lt_ptr char * ++# define const ++#endif ++ ++/* The mapping between symbol names and symbols. */ ++" ++ ++ case $host in ++ *cygwin* | *mingw* ) ++ $echo >> "$output_objdir/$dlsyms" "\ ++/* DATA imports from DLLs on WIN32 can't be const, because ++ runtime relocations are performed -- see ld's documentation ++ on pseudo-relocs */ ++struct { ++" ++ ;; ++ * ) ++ $echo >> "$output_objdir/$dlsyms" "\ ++const struct { ++" ++ ;; ++ esac ++ ++ ++ $echo >> "$output_objdir/$dlsyms" "\ ++ const char *name; ++ lt_ptr address; ++} ++lt_preloaded_symbols[] = ++{\ ++" ++ ++ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" ++ ++ $echo >> "$output_objdir/$dlsyms" "\ ++ {0, (lt_ptr) 0} ++}; ++ ++/* This works around a problem in FreeBSD linker */ ++#ifdef FREEBSD_WORKAROUND ++static const void *lt_preloaded_setup() { ++ return lt_preloaded_symbols; ++} ++#endif ++ ++#ifdef __cplusplus ++} ++#endif\ ++" ++ fi ++ ++ pic_flag_for_symtable= ++ case $host in ++ # compiling the symbol table file with pic_flag works around ++ # a FreeBSD bug that causes programs to crash when -lm is ++ # linked before any other PIC object. But we must not use ++ # pic_flag when linking with -static. The problem exists in ++ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. ++ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) ++ case "$compile_command " in ++ *" -static "*) ;; ++ *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; ++ esac;; ++ *-*-hpux*) ++ case "$compile_command " in ++ *" -static "*) ;; ++ *) pic_flag_for_symtable=" $pic_flag";; ++ esac ++ esac ++ ++ # Now compile the dynamic symbol file. ++ $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")" ++ $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? ++ ++ # Clean up the generated files. ++ $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" ++ $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" ++ ++ # Transform the symbol file into the correct name. ++ case $host in ++ *cygwin* | *mingw* ) ++ if test -f "$output_objdir/${outputname}.def" ; then ++ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"` ++ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"` ++ else ++ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ++ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ++ fi ++ ;; ++ * ) ++ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ++ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ++ ;; ++ esac ++ ;; ++ *) ++ $echo "$modename: unknown suffix for `$dlsyms'" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ else ++ # We keep going just in case the user didn't refer to ++ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe ++ # really was required. ++ ++ # Nullify the symbol file. ++ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` ++ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` ++ fi ++ ++ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then ++ # Replace the output file specification. ++ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` ++ link_command="$compile_command$compile_rpath" ++ ++ # We have no uninstalled library dependencies, so finalize right now. ++ $show "$link_command" ++ $run eval "$link_command" ++ exit_status=$? ++ ++ # Delete the generated files. ++ if test -n "$dlsyms"; then ++ $show "$rm $output_objdir/${outputname}S.${objext}" ++ $run $rm "$output_objdir/${outputname}S.${objext}" ++ fi ++ ++ exit $exit_status ++ fi ++ ++ if test -n "$shlibpath_var"; then ++ # We should set the shlibpath_var ++ rpath= ++ for dir in $temp_rpath; do ++ case $dir in ++ [\/]* | [A-Za-z]:[\/]*) ++ # Absolute path. ++ rpath="$rpath$dir:" ++ ;; ++ *) ++ # Relative path: add a thisdir entry. ++ rpath="$rpath$thisdir/$dir:" ++ ;; ++ esac ++ done ++ temp_rpath="$rpath" ++ fi ++ ++ if test -n "$compile_shlibpath$finalize_shlibpath"; then ++ compile_command="$shlibpath_var="$compile_shlibpath$finalize_shlibpath$$shlibpath_var" $compile_command" ++ fi ++ if test -n "$finalize_shlibpath"; then ++ finalize_command="$shlibpath_var="$finalize_shlibpath$$shlibpath_var" $finalize_command" ++ fi ++ ++ compile_var= ++ finalize_var= ++ if test -n "$runpath_var"; then ++ if test -n "$perm_rpath"; then ++ # We should set the runpath_var. ++ rpath= ++ for dir in $perm_rpath; do ++ rpath="$rpath$dir:" ++ done ++ compile_var="$runpath_var="$rpath$$runpath_var" " ++ fi ++ if test -n "$finalize_perm_rpath"; then ++ # We should set the runpath_var. ++ rpath= ++ for dir in $finalize_perm_rpath; do ++ rpath="$rpath$dir:" ++ done ++ finalize_var="$runpath_var="$rpath$$runpath_var" " ++ fi ++ fi ++ ++ if test "$no_install" = yes; then ++ # We don't need to create a wrapper script. ++ link_command="$compile_var$compile_command$compile_rpath" ++ # Replace the output file specification. ++ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` ++ # Delete the old output file. ++ $run $rm $output ++ # Link the executable and exit ++ $show "$link_command" ++ $run eval "$link_command" || exit $? ++ exit $EXIT_SUCCESS ++ fi ++ ++ if test "$hardcode_action" = relink; then ++ # Fast installation is not supported ++ link_command="$compile_var$compile_command$compile_rpath" ++ relink_command="$finalize_var$finalize_command$finalize_rpath" ++ ++ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 ++ $echo "$modename: `$output' will be relinked during installation" 1>&2 ++ else ++ if test "$fast_install" != no; then ++ link_command="$finalize_var$compile_command$finalize_rpath" ++ if test "$fast_install" = yes; then ++ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%$progdir/$file%g'` ++ else ++ # fast_install is set to needless ++ relink_command= ++ fi ++ else ++ link_command="$compile_var$compile_command$compile_rpath" ++ relink_command="$finalize_var$finalize_command$finalize_rpath" ++ fi ++ fi ++ ++ # Replace the output file specification. ++ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` ++ ++ # Delete the old output files. ++ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname ++ ++ $show "$link_command" ++ $run eval "$link_command" || exit $? ++ ++ # Now create the wrapper script. ++ $show "creating $output" ++ ++ # Quote the relink command for shipping. ++ if test -n "$relink_command"; then ++ # Preserve any variables that may affect compiler behavior ++ for var in $variables_saved_for_relink; do ++ if eval test -z "${$var+set}"; then ++ relink_command="{ test -z "${$var+set}" || unset $var || { $var=; export $var; }; }; $relink_command" ++ elif eval var_value=$$var; test -z "$var_value"; then ++ relink_command="$var=; export $var; $relink_command" ++ else ++ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` ++ relink_command="$var="$var_value"; export $var; $relink_command" ++ fi ++ done ++ relink_command="(cd `pwd`; $relink_command)" ++ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` ++ fi ++ ++ # Quote $echo for shipping. ++ if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then ++ case $progpath in ++ [\/]* | [A-Za-z]:[\/]*) qecho="$SHELL $progpath --fallback-echo";; ++ *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; ++ esac ++ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` ++ else ++ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` ++ fi ++ ++ # Only actually do things if our run command is non-null. ++ if test -z "$run"; then ++ # win32 will think the script is a binary if it has ++ # a .exe suffix, so we strip it off here. ++ case $output in ++ *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; ++ esac ++ # test for cygwin because mv fails w/o .exe extensions ++ case $host in ++ *cygwin*) ++ exeext=.exe ++ outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; ++ *) exeext= ;; ++ esac ++ case $host in ++ *cygwin* | *mingw* ) ++ output_name=`basename $output` ++ output_path=`dirname $output` ++ cwrappersource="$output_path/$objdir/lt-$output_name.c" ++ cwrapper="$output_path/$output_name.exe" ++ $rm $cwrappersource $cwrapper ++ trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 ++ ++ cat > $cwrappersource <<EOF ++ ++/* $cwrappersource - temporary wrapper executable for $objdir/$outputname ++ Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP ++ ++ The $output program cannot be directly executed until all the libtool ++ libraries that it depends on are installed. ++ ++ This wrapper executable should never be moved out of the build directory. ++ If it is, it will not operate correctly. ++ ++ Currently, it simply execs the wrapper *script* "/bin/sh $output", ++ but could eventually absorb all of the scripts functionality and ++ exec $objdir/$outputname directly. ++*/ ++EOF ++ cat >> $cwrappersource<<"EOF" ++#include <stdio.h> ++#include <stdlib.h> ++#include <unistd.h> ++#include <malloc.h> ++#include <stdarg.h> ++#include <assert.h> ++#include <string.h> ++#include <ctype.h> ++#include <sys/stat.h> ++ ++#if defined(PATH_MAX) ++# define LT_PATHMAX PATH_MAX ++#elif defined(MAXPATHLEN) ++# define LT_PATHMAX MAXPATHLEN ++#else ++# define LT_PATHMAX 1024 ++#endif ++ ++#ifndef DIR_SEPARATOR ++# define DIR_SEPARATOR '/' ++# define PATH_SEPARATOR ':' ++#endif ++ ++#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ ++ defined (__OS2__) ++# define HAVE_DOS_BASED_FILE_SYSTEM ++# ifndef DIR_SEPARATOR_2 ++# define DIR_SEPARATOR_2 '\' ++# endif ++# ifndef PATH_SEPARATOR_2 ++# define PATH_SEPARATOR_2 ';' ++# endif ++#endif ++ ++#ifndef DIR_SEPARATOR_2 ++# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) ++#else /* DIR_SEPARATOR_2 */ ++# define IS_DIR_SEPARATOR(ch) \ ++ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) ++#endif /* DIR_SEPARATOR_2 */ ++ ++#ifndef PATH_SEPARATOR_2 ++# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) ++#else /* PATH_SEPARATOR_2 */ ++# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) ++#endif /* PATH_SEPARATOR_2 */ ++ ++#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) ++#define XFREE(stale) do { \ ++ if (stale) { free ((void *) stale); stale = 0; } \ ++} while (0) ++ ++/* -DDEBUG is fairly common in CFLAGS. */ ++#undef DEBUG ++#if defined DEBUGWRAPPER ++# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) ++#else ++# define DEBUG(format, ...) ++#endif ++ ++const char *program_name = NULL; ++ ++void * xmalloc (size_t num); ++char * xstrdup (const char *string); ++const char * base_name (const char *name); ++char * find_executable(const char *wrapper); ++int check_executable(const char *path); ++char * strendzap(char *str, const char *pat); ++void lt_fatal (const char *message, ...); ++ ++int ++main (int argc, char *argv[]) ++{ ++ char **newargz; ++ int i; ++ ++ program_name = (char *) xstrdup (base_name (argv[0])); ++ DEBUG("(main) argv[0] : %s\n",argv[0]); ++ DEBUG("(main) program_name : %s\n",program_name); ++ newargz = XMALLOC(char *, argc+2); ++EOF ++ ++ cat >> $cwrappersource <<EOF ++ newargz[0] = (char *) xstrdup("$SHELL"); ++EOF ++ ++ cat >> $cwrappersource <<"EOF" ++ newargz[1] = find_executable(argv[0]); ++ if (newargz[1] == NULL) ++ lt_fatal("Couldn't find %s", argv[0]); ++ DEBUG("(main) found exe at : %s\n",newargz[1]); ++ /* we know the script has the same name, without the .exe */ ++ /* so make sure newargz[1] doesn't end in .exe */ ++ strendzap(newargz[1],".exe"); ++ for (i = 1; i < argc; i++) ++ newargz[i+1] = xstrdup(argv[i]); ++ newargz[argc+1] = NULL; ++ ++ for (i=0; i<argc+1; i++) ++ { ++ DEBUG("(main) newargz[%d] : %s\n",i,newargz[i]); ++ ; ++ } ++ ++EOF ++ ++ case $host_os in ++ mingw*) ++ cat >> $cwrappersource <<EOF ++ execv("$SHELL",(char const **)newargz); ++EOF ++ ;; ++ *) ++ cat >> $cwrappersource <<EOF ++ execv("$SHELL",newargz); ++EOF ++ ;; ++ esac ++ ++ cat >> $cwrappersource <<"EOF" ++ return 127; ++} ++ ++void * ++xmalloc (size_t num) ++{ ++ void * p = (void *) malloc (num); ++ if (!p) ++ lt_fatal ("Memory exhausted"); ++ ++ return p; ++} ++ ++char * ++xstrdup (const char *string) ++{ ++ return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL ++; ++} ++ ++const char * ++base_name (const char *name) ++{ ++ const char *base; ++ ++#if defined (HAVE_DOS_BASED_FILE_SYSTEM) ++ /* Skip over the disk name in MSDOS pathnames. */ ++ if (isalpha ((unsigned char)name[0]) && name[1] == ':') ++ name += 2; ++#endif ++ ++ for (base = name; *name; name++) ++ if (IS_DIR_SEPARATOR (*name)) ++ base = name + 1; ++ return base; ++} ++ ++int ++check_executable(const char * path) ++{ ++ struct stat st; ++ ++ DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); ++ if ((!path) || (!*path)) ++ return 0; ++ ++ if ((stat (path, &st) >= 0) && ++ ( ++ /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ ++#if defined (S_IXOTH) ++ ((st.st_mode & S_IXOTH) == S_IXOTH) || ++#endif ++#if defined (S_IXGRP) ++ ((st.st_mode & S_IXGRP) == S_IXGRP) || ++#endif ++ ((st.st_mode & S_IXUSR) == S_IXUSR)) ++ ) ++ return 1; ++ else ++ return 0; ++} ++ ++/* Searches for the full path of the wrapper. Returns ++ newly allocated full path name if found, NULL otherwise */ ++char * ++find_executable (const char* wrapper) ++{ ++ int has_slash = 0; ++ const char* p; ++ const char* p_next; ++ /* static buffer for getcwd */ ++ char tmp[LT_PATHMAX + 1]; ++ int tmp_len; ++ char* concat_name; ++ ++ DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); ++ ++ if ((wrapper == NULL) || (*wrapper == '\0')) ++ return NULL; ++ ++ /* Absolute path? */ ++#if defined (HAVE_DOS_BASED_FILE_SYSTEM) ++ if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') ++ { ++ concat_name = xstrdup (wrapper); ++ if (check_executable(concat_name)) ++ return concat_name; ++ XFREE(concat_name); ++ } ++ else ++ { ++#endif ++ if (IS_DIR_SEPARATOR (wrapper[0])) ++ { ++ concat_name = xstrdup (wrapper); ++ if (check_executable(concat_name)) ++ return concat_name; ++ XFREE(concat_name); ++ } ++#if defined (HAVE_DOS_BASED_FILE_SYSTEM) ++ } ++#endif ++ ++ for (p = wrapper; *p; p++) ++ if (*p == '/') ++ { ++ has_slash = 1; ++ break; ++ } ++ if (!has_slash) ++ { ++ /* no slashes; search PATH */ ++ const char* path = getenv ("PATH"); ++ if (path != NULL) ++ { ++ for (p = path; *p; p = p_next) ++ { ++ const char* q; ++ size_t p_len; ++ for (q = p; *q; q++) ++ if (IS_PATH_SEPARATOR(*q)) ++ break; ++ p_len = q - p; ++ p_next = (*q == '\0' ? q : q + 1); ++ if (p_len == 0) ++ { ++ /* empty path: current directory */ ++ if (getcwd (tmp, LT_PATHMAX) == NULL) ++ lt_fatal ("getcwd failed"); ++ tmp_len = strlen(tmp); ++ concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); ++ memcpy (concat_name, tmp, tmp_len); ++ concat_name[tmp_len] = '/'; ++ strcpy (concat_name + tmp_len + 1, wrapper); ++ } ++ else ++ { ++ concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); ++ memcpy (concat_name, p, p_len); ++ concat_name[p_len] = '/'; ++ strcpy (concat_name + p_len + 1, wrapper); ++ } ++ if (check_executable(concat_name)) ++ return concat_name; ++ XFREE(concat_name); ++ } ++ } ++ /* not found in PATH; assume curdir */ ++ } ++ /* Relative path | not found in path: prepend cwd */ ++ if (getcwd (tmp, LT_PATHMAX) == NULL) ++ lt_fatal ("getcwd failed"); ++ tmp_len = strlen(tmp); ++ concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); ++ memcpy (concat_name, tmp, tmp_len); ++ concat_name[tmp_len] = '/'; ++ strcpy (concat_name + tmp_len + 1, wrapper); ++ ++ if (check_executable(concat_name)) ++ return concat_name; ++ XFREE(concat_name); ++ return NULL; ++} ++ ++char * ++strendzap(char *str, const char *pat) ++{ ++ size_t len, patlen; ++ ++ assert(str != NULL); ++ assert(pat != NULL); ++ ++ len = strlen(str); ++ patlen = strlen(pat); ++ ++ if (patlen <= len) ++ { ++ str += len - patlen; ++ if (strcmp(str, pat) == 0) ++ *str = '\0'; ++ } ++ return str; ++} ++ ++static void ++lt_error_core (int exit_status, const char * mode, ++ const char * message, va_list ap) ++{ ++ fprintf (stderr, "%s: %s: ", program_name, mode); ++ vfprintf (stderr, message, ap); ++ fprintf (stderr, ".\n"); ++ ++ if (exit_status >= 0) ++ exit (exit_status); ++} ++ ++void ++lt_fatal (const char *message, ...) ++{ ++ va_list ap; ++ va_start (ap, message); ++ lt_error_core (EXIT_FAILURE, "FATAL", message, ap); ++ va_end (ap); ++} ++EOF ++ # we should really use a build-platform specific compiler ++ # here, but OTOH, the wrappers (shell script and this C one) ++ # are only useful if you want to execute the "real" binary. ++ # Since the "real" binary is built for $host, then this ++ # wrapper might as well be built for $host, too. ++ $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource ++ ;; ++ esac ++ $rm $output ++ trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 ++ ++ $echo > $output "\ ++#! $SHELL ++ ++# $output - temporary wrapper script for $objdir/$outputname ++# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP ++# ++# The $output program cannot be directly executed until all the libtool ++# libraries that it depends on are installed. ++# ++# This wrapper script should never be moved out of the build directory. ++# If it is, it will not operate correctly. ++ ++# Sed substitution that helps us do robust quoting. It backslashifies ++# metacharacters that are still active within double-quoted strings. ++Xsed='${SED} -e 1s/^X//' ++sed_quote_subst='$sed_quote_subst' ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++relink_command="$relink_command" ++ ++# This environment variable determines our operation mode. ++if test "$libtool_install_magic" = "$magic"; then ++ # install mode needs the following variable: ++ notinst_deplibs='$notinst_deplibs' ++else ++ # When we are sourced in execute mode, $file and $echo are already set. ++ if test "$libtool_execute_magic" != "$magic"; then ++ echo="$qecho" ++ file="$0" ++ # Make sure echo works. ++ if test "X$1" = X--no-reexec; then ++ # Discard the --no-reexec flag, and continue. ++ shift ++ elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then ++ # Yippee, $echo works! ++ : ++ else ++ # Restart under the correct shell, and then maybe $echo will work. ++ exec $SHELL "$0" --no-reexec ${1+"$@"} ++ fi ++ fi\ ++" ++ $echo >> $output "\ ++ ++ # Find the directory that this script lives in. ++ thisdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` ++ test "x$thisdir" = "x$file" && thisdir=. ++ ++ # Follow symbolic links until we get to the real thisdir. ++ file=`ls -ld "$file" | ${SED} -n 's/.*-> //p'` ++ while test -n "$file"; do ++ destdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` ++ ++ # If there was a directory component, then change thisdir. ++ if test "x$destdir" != "x$file"; then ++ case "$destdir" in ++ [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;; ++ *) thisdir="$thisdir/$destdir" ;; ++ esac ++ fi ++ ++ file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ file=`ls -ld "$thisdir/$file" | ${SED} -n 's/.*-> //p'` ++ done ++ ++ # Try to get the absolute directory name. ++ absdir=`cd "$thisdir" && pwd` ++ test -n "$absdir" && thisdir="$absdir" ++" ++ ++ if test "$fast_install" = yes; then ++ $echo >> $output "\ ++ program=lt-'$outputname'$exeext ++ progdir="$thisdir/$objdir" ++ ++ if test ! -f "$progdir/$program" || \ ++ { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | ${SED} 1q`; \ ++ test "X$file" != "X$progdir/$program"; }; then ++ ++ file="$$-$program" ++ ++ if test ! -d "$progdir"; then ++ $mkdir "$progdir" ++ else ++ $rm "$progdir/$file" ++ fi" ++ ++ $echo >> $output "\ ++ ++ # relink executable if necessary ++ if test -n "$relink_command"; then ++ if relink_command_output=`eval $relink_command 2>&1`; then : ++ else ++ $echo "$relink_command_output" >&2 ++ $rm "$progdir/$file" ++ exit $EXIT_FAILURE ++ fi ++ fi ++ ++ $mv "$progdir/$file" "$progdir/$program" 2>/dev/null || ++ { $rm "$progdir/$program"; ++ $mv "$progdir/$file" "$progdir/$program"; } ++ $rm "$progdir/$file" ++ fi" ++ else ++ $echo >> $output "\ ++ program='$outputname' ++ progdir="$thisdir/$objdir" ++" ++ fi ++ ++ $echo >> $output "\ ++ ++ if test -f "$progdir/$program"; then" ++ ++ # Export our shlibpath_var if we have one. ++ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then ++ $echo >> $output "\ ++ # Add our own library path to $shlibpath_var ++ $shlibpath_var="$temp_rpath$$shlibpath_var" ++ ++ # Some systems cannot cope with colon-terminated $shlibpath_var ++ # The second colon is a workaround for a bug in BeOS R4 sed ++ $shlibpath_var=`$echo "X$$shlibpath_var" | $Xsed -e 's/::*$//'` ++ ++ export $shlibpath_var ++" ++ fi ++ ++ # fixup the dll searchpath if we need to. ++ if test -n "$dllsearchpath"; then ++ $echo >> $output "\ ++ # Add the dll search path components to the executable PATH ++ PATH=$dllsearchpath:$PATH ++" ++ fi ++ ++ $echo >> $output "\ ++ if test "$libtool_execute_magic" != "$magic"; then ++ # Run the actual program with our arguments. ++ ++ # Make sure env LD_LIBRARY_PATH does not mess us up ++ if test -n "${LD_LIBRARY_PATH+set}"; then ++ export LD_LIBRARY_PATH=$progdir:$LD_LIBRARY_PATH ++ fi ++" ++ case $host in ++ # Backslashes separate directories on plain windows ++ *-*-mingw | *-*-os2*) ++ $echo >> $output "\ ++ exec "$progdir\\$program" ${1+"$@"} ++" ++ ;; ++ ++ *) ++ $echo >> $output "\ ++ exec "$progdir/$program" ${1+"$@"} ++" ++ ;; ++ esac ++ $echo >> $output "\ ++ $echo "$0: cannot exec $program ${1+"$@"}" ++ exit $EXIT_FAILURE ++ fi ++ else ++ # The program doesn't exist. ++ $echo "$0: error: \`$progdir/$program' does not exist" 1>&2 ++ $echo "This script is just a wrapper for $program." 1>&2 ++ $echo "See the $PACKAGE documentation for more information." 1>&2 ++ exit $EXIT_FAILURE ++ fi ++fi\ ++" ++ chmod +x $output ++ fi ++ exit $EXIT_SUCCESS ++ ;; ++ esac ++ ++ # See if we need to build an old-fashioned archive. ++ for oldlib in $oldlibs; do ++ ++ if test "$build_libtool_libs" = convenience; then ++ oldobjs="$libobjs_save" ++ addlibs="$convenience" ++ build_libtool_libs=no ++ else ++ if test "$build_libtool_libs" = module; then ++ oldobjs="$libobjs_save" ++ build_libtool_libs=no ++ else ++ oldobjs="$old_deplibs $non_pic_objects" ++ fi ++ addlibs="$old_convenience" ++ fi ++ ++ if test -n "$addlibs"; then ++ gentop="$output_objdir/${outputname}x" ++ generated="$generated $gentop" ++ ++ func_extract_archives $gentop $addlibs ++ oldobjs="$oldobjs $func_extract_archives_result" ++ fi ++ ++ # Do each command in the archive commands. ++ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then ++ cmds=$old_archive_from_new_cmds ++ else ++ # POSIX demands no paths to be encoded in archives. We have ++ # to avoid creating archives with duplicate basenames if we ++ # might have to extract them afterwards, e.g., when creating a ++ # static archive out of a convenience library, or when linking ++ # the entirety of a libtool archive into another (currently ++ # not supported by libtool). ++ if (for obj in $oldobjs ++ do ++ $echo "X$obj" | $Xsed -e 's%^.*/%%' ++ done | sort | sort -uc >/dev/null 2>&1); then ++ : ++ else ++ $echo "copying selected object files to avoid basename conflicts..." ++ ++ if test -z "$gentop"; then ++ gentop="$output_objdir/${outputname}x" ++ generated="$generated $gentop" ++ ++ $show "${rm}r $gentop" ++ $run ${rm}r "$gentop" ++ $show "$mkdir $gentop" ++ $run $mkdir "$gentop" ++ exit_status=$? ++ if test "$exit_status" -ne 0 && test ! -d "$gentop"; then ++ exit $exit_status ++ fi ++ fi ++ ++ save_oldobjs=$oldobjs ++ oldobjs= ++ counter=1 ++ for obj in $save_oldobjs ++ do ++ objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` ++ case " $oldobjs " in ++ " ") oldobjs=$obj ;; ++ *[\ /]"$objbase "*) ++ while :; do ++ # Make sure we don't pick an alternate name that also ++ # overlaps. ++ newobj=lt$counter-$objbase ++ counter=`expr $counter + 1` ++ case " $oldobjs " in ++ *[\ /]"$newobj "*) ;; ++ *) if test ! -f "$gentop/$newobj"; then break; fi ;; ++ esac ++ done ++ $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" ++ $run ln "$obj" "$gentop/$newobj" || ++ $run cp "$obj" "$gentop/$newobj" ++ oldobjs="$oldobjs $gentop/$newobj" ++ ;; ++ *) oldobjs="$oldobjs $obj" ;; ++ esac ++ done ++ fi ++ ++ eval cmds="$old_archive_cmds" ++ ++ if len=`expr "X$cmds" : ".*"` && ++ test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then ++ cmds=$old_archive_cmds ++ else ++ # the command line is too long to link in one step, link in parts ++ $echo "using piecewise archive linking..." ++ save_RANLIB=$RANLIB ++ RANLIB=: ++ objlist= ++ concat_cmds= ++ save_oldobjs=$oldobjs ++ ++ # Is there a better way of finding the last object in the list? ++ for obj in $save_oldobjs ++ do ++ last_oldobj=$obj ++ done ++ for obj in $save_oldobjs ++ do ++ oldobjs="$objlist $obj" ++ objlist="$objlist $obj" ++ eval test_cmds="$old_archive_cmds" ++ if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && ++ test "$len" -le "$max_cmd_len"; then ++ : ++ else ++ # the above command should be used before it gets too long ++ oldobjs=$objlist ++ if test "$obj" = "$last_oldobj" ; then ++ RANLIB=$save_RANLIB ++ fi ++ test -z "$concat_cmds" || concat_cmds=$concat_cmds~ ++ eval concat_cmds="${concat_cmds}$old_archive_cmds" ++ objlist= ++ fi ++ done ++ RANLIB=$save_RANLIB ++ oldobjs=$objlist ++ if test "X$oldobjs" = "X" ; then ++ eval cmds="$concat_cmds" ++ else ++ eval cmds="$concat_cmds~$old_archive_cmds" ++ fi ++ fi ++ fi ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ eval cmd="$cmd" ++ IFS="$save_ifs" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ done ++ ++ if test -n "$generated"; then ++ $show "${rm}r$generated" ++ $run ${rm}r$generated ++ fi ++ ++ # Now create the libtool archive. ++ case $output in ++ *.la) ++ old_library= ++ test "$build_old_libs" = yes && old_library="$libname.$libext" ++ $show "creating $output" ++ ++ # Preserve any variables that may affect compiler behavior ++ for var in $variables_saved_for_relink; do ++ if eval test -z "${$var+set}"; then ++ relink_command="{ test -z "${$var+set}" || unset $var || { $var=; export $var; }; }; $relink_command" ++ elif eval var_value=$$var; test -z "$var_value"; then ++ relink_command="$var=; export $var; $relink_command" ++ else ++ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` ++ relink_command="$var="$var_value"; export $var; $relink_command" ++ fi ++ done ++ # Quote the link command for shipping. ++ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" ++ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` ++ if test "$hardcode_automatic" = yes ; then ++ relink_command= ++ fi ++ ++ ++ # Only create the output if not a dry run. ++ if test -z "$run"; then ++ for installed in no yes; do ++ if test "$installed" = yes; then ++ if test -z "$install_libdir"; then ++ break ++ fi ++ output="$output_objdir/$outputname"i ++ # Replace all uninstalled libtool libraries with the installed ones ++ newdependency_libs= ++ for deplib in $dependency_libs; do ++ case $deplib in ++ *.la) ++ name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` ++ eval libdir=`${SED} -n -e 's/^libdir=(.*)$/\1/p' $deplib` ++ if test -z "$libdir"; then ++ $echo "$modename: `$deplib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ if test "X$EGREP" = X ; then ++ EGREP=egrep ++ fi ++ # We do not want portage's install root ($D) present. Check only for ++ # this if the .la is being installed. ++ if test "$installed" = yes && test "$D"; then ++ eval mynewdependency_lib=`echo "$libdir/$name" |sed -e "s:$D:/:g" -e 's:/+:/:g'` ++ else ++ mynewdependency_lib="$libdir/$name" ++ fi ++ # Do not add duplicates ++ if test "$mynewdependency_lib"; then ++ my_little_ninja_foo_1=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"` ++ if test -z "$my_little_ninja_foo_1"; then ++ newdependency_libs="$newdependency_libs $mynewdependency_lib" ++ fi ++ fi ++ ;; ++ *) ++ if test "$installed" = yes; then ++ # Rather use S=WORKDIR if our version of portage supports it. ++ # This is because some ebuild (gcc) do not use $S as buildroot. ++ if test "$PWORKDIR"; then ++ S="$PWORKDIR" ++ fi ++ # We do not want portage's build root ($S) present. ++ my_little_ninja_foo_2=`echo $deplib |$EGREP -e "$S"` ++ # We do not want portage's install root ($D) present. ++ my_little_ninja_foo_3=`echo $deplib |$EGREP -e "$D"` ++ if test -n "$my_little_ninja_foo_2" && test "$S"; then ++ mynewdependency_lib="" ++ elif test -n "$my_little_ninja_foo_3" && test "$D"; then ++ eval mynewdependency_lib=`echo "$deplib" |sed -e "s:$D:/:g" -e 's:/+:/:g'` ++ else ++ mynewdependency_lib="$deplib" ++ fi ++ else ++ mynewdependency_lib="$deplib" ++ fi ++ # Do not add duplicates ++ if test "$mynewdependency_lib"; then ++ my_little_ninja_foo_4=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"` ++ if test -z "$my_little_ninja_foo_4"; then ++ newdependency_libs="$newdependency_libs $mynewdependency_lib" ++ fi ++ fi ++ ;; ++ esac ++ done ++ dependency_libs="$newdependency_libs" ++ newdlfiles= ++ for lib in $dlfiles; do ++ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` ++ eval libdir=`${SED} -n -e 's/^libdir=(.*)$/\1/p' $lib` ++ if test -z "$libdir"; then ++ $echo "$modename: `$lib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ newdlfiles="$newdlfiles $libdir/$name" ++ done ++ dlfiles="$newdlfiles" ++ newdlprefiles= ++ for lib in $dlprefiles; do ++ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` ++ eval libdir=`${SED} -n -e 's/^libdir=(.*)$/\1/p' $lib` ++ if test -z "$libdir"; then ++ $echo "$modename: `$lib' is not a valid libtool archive" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ newdlprefiles="$newdlprefiles $libdir/$name" ++ done ++ dlprefiles="$newdlprefiles" ++ else ++ newdlfiles= ++ for lib in $dlfiles; do ++ case $lib in ++ [\/]* | [A-Za-z]:[\/]*) abs="$lib" ;; ++ *) abs=`pwd`"/$lib" ;; ++ esac ++ newdlfiles="$newdlfiles $abs" ++ done ++ dlfiles="$newdlfiles" ++ newdlprefiles= ++ for lib in $dlprefiles; do ++ case $lib in ++ [\/]* | [A-Za-z]:[\/]*) abs="$lib" ;; ++ *) abs=`pwd`"/$lib" ;; ++ esac ++ newdlprefiles="$newdlprefiles $abs" ++ done ++ dlprefiles="$newdlprefiles" ++ fi ++ $rm $output ++ # place dlname in correct position for cygwin ++ tdlname=$dlname ++ case $host,$output,$installed,$module,$dlname in ++ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; ++ esac ++ # Do not add duplicates ++ if test "$installed" = yes && test "$D"; then ++ install_libdir=`echo "$install_libdir" |sed -e "s:$D:/:g" -e 's:/+:/:g'` ++ fi ++ $echo > $output "\ ++# $outputname - a libtool library file ++# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP ++# ++# Please DO NOT delete this file! ++# It is necessary for linking the library. ++ ++# The name that we can dlopen(3). ++dlname='$tdlname' ++ ++# Names of this library. ++library_names='$library_names' ++ ++# The name of the static archive. ++old_library='$old_library' ++ ++# Libraries that this one depends upon. ++dependency_libs='$dependency_libs' ++ ++# Version information for $libname. ++current=$current ++age=$age ++revision=$revision ++ ++# Is this an already installed library? ++installed=$installed ++ ++# Should we warn about portability when linking against -modules? ++shouldnotlink=$module ++ ++# Files to dlopen/dlpreopen ++dlopen='$dlfiles' ++dlpreopen='$dlprefiles' ++ ++# Directory that this library needs to be installed in: ++libdir='$install_libdir'" ++ if test "$installed" = no && test "$need_relink" = yes; then ++ $echo >> $output "\ ++relink_command="$relink_command"" ++ fi ++ done ++ fi ++ ++ # Do a symbolic link so that the libtool archive can be found in ++ # LD_LIBRARY_PATH before the program is installed. ++ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" ++ $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? ++ ;; ++ esac ++ exit $EXIT_SUCCESS ++ ;; ++ ++ # libtool install mode ++ install) ++ modename="$modename: install" ++ ++ # There may be an optional sh(1) argument at the beginning of ++ # install_prog (especially on Windows NT). ++ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || ++ # Allow the use of GNU shtool's install command. ++ $echo "X$nonopt" | grep shtool > /dev/null; then ++ # Aesthetically quote it. ++ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ arg=""$arg"" ++ ;; ++ esac ++ install_prog="$arg " ++ arg="$1" ++ shift ++ else ++ install_prog= ++ arg=$nonopt ++ fi ++ ++ # The real first argument should be the name of the installation program. ++ # Aesthetically quote it. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ arg=""$arg"" ++ ;; ++ esac ++ install_prog="$install_prog$arg" ++ ++ # We need to accept at least all the BSD install flags. ++ dest= ++ files= ++ opts= ++ prev= ++ install_type= ++ isdir=no ++ stripme= ++ for arg ++ do ++ if test -n "$dest"; then ++ files="$files $dest" ++ dest=$arg ++ continue ++ fi ++ ++ case $arg in ++ -d) isdir=yes ;; ++ -f) ++ case " $install_prog " in ++ *[\\ /]cp\ *) ;; ++ *) prev=$arg ;; ++ esac ++ ;; ++ -g | -m | -o) prev=$arg ;; ++ -s) ++ stripme=" -s" ++ continue ++ ;; ++ -*) ++ ;; ++ *) ++ # If the previous option needed an argument, then skip it. ++ if test -n "$prev"; then ++ prev= ++ else ++ dest=$arg ++ continue ++ fi ++ ;; ++ esac ++ ++ # Aesthetically quote the argument. ++ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` ++ case $arg in ++ *[[~#^&*(){}|;<>?'\ \ ]*|*]*|"") ++ arg=""$arg"" ++ ;; ++ esac ++ install_prog="$install_prog $arg" ++ done ++ ++ if test -z "$install_prog"; then ++ $echo "$modename: you must specify an install program" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ if test -n "$prev"; then ++ $echo "$modename: the `$prev' option requires an argument" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ if test -z "$files"; then ++ if test -z "$dest"; then ++ $echo "$modename: no file or destination specified" 1>&2 ++ else ++ $echo "$modename: you must specify a destination" 1>&2 ++ fi ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Strip any trailing slash from the destination. ++ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` ++ ++ # Check to see that the destination is a directory. ++ test -d "$dest" && isdir=yes ++ if test "$isdir" = yes; then ++ destdir="$dest" ++ destname= ++ else ++ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$destdir" = "X$dest" && destdir=. ++ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` ++ ++ # Not a directory, so check to see that there is only one file specified. ++ set dummy $files ++ if test "$#" -gt 2; then ++ $echo "$modename: `$dest' is not a directory" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ fi ++ case $destdir in ++ [\/]* | [A-Za-z]:[\/]*) ;; ++ *) ++ for file in $files; do ++ case $file in ++ *.lo) ;; ++ *) ++ $echo "$modename: `$destdir' must be an absolute directory name" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ done ++ ;; ++ esac ++ ++ # This variable tells wrapper scripts just to set variables rather ++ # than running their programs. ++ libtool_install_magic="$magic" ++ ++ staticlibs= ++ future_libdirs= ++ current_libdirs= ++ for file in $files; do ++ ++ # Do each installation. ++ case $file in ++ *.$libext) ++ # Do the static libraries later. ++ staticlibs="$staticlibs $file" ++ ;; ++ ++ *.la) ++ # Check to see that this really is a libtool archive. ++ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : ++ else ++ $echo "$modename: `$file' is not a valid libtool archive" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ library_names= ++ old_library= ++ relink_command= ++ # If there is no directory component, then add one. ++ case $file in ++ */* | *\*) . $file ;; ++ *) . ./$file ;; ++ esac ++ ++ # Add the libdir to current_libdirs if it is the destination. ++ if test "X$destdir" = "X$libdir"; then ++ case "$current_libdirs " in ++ *" $libdir "*) ;; ++ *) current_libdirs="$current_libdirs $libdir" ;; ++ esac ++ else ++ # Note the libdir as a future libdir. ++ case "$future_libdirs " in ++ *" $libdir "*) ;; ++ *) future_libdirs="$future_libdirs $libdir" ;; ++ esac ++ fi ++ ++ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ ++ test "X$dir" = "X$file/" && dir= ++ dir="$dir$objdir" ++ ++ if test -n "$relink_command"; then ++ # Determine the prefix the user has applied to our future dir. ++ inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir$%%"` ++ ++ # Don't allow the user to place us outside of our expected ++ # location b/c this prevents finding dependent libraries that ++ # are installed to the same prefix. ++ # At present, this check doesn't affect windows .dll's that ++ # are installed into $libdir/../bin (currently, that works fine) ++ # but it's something to keep an eye on. ++ if test "$inst_prefix_dir" = "$destdir"; then ++ $echo "$modename: error: cannot install `$file' to a directory not ending in $libdir" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ if test -n "$inst_prefix_dir"; then ++ # Stick the inst_prefix_dir data into the link command. ++ relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` ++ else ++ relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` ++ fi ++ ++ $echo "$modename: warning: relinking `$file'" 1>&2 ++ $show "$relink_command" ++ if $run eval "$relink_command"; then : ++ else ++ $echo "$modename: error: relink `$file' with the above command before installing it" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ fi ++ ++ # See the names of the shared library. ++ set dummy $library_names ++ if test -n "$2"; then ++ realname="$2" ++ shift ++ shift ++ ++ srcname="$realname" ++ test -n "$relink_command" && srcname="$realname"T ++ ++ # Install the shared library and build the symlinks. ++ $show "$install_prog $dir/$srcname $destdir/$realname" ++ $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? ++ if test -n "$stripme" && test -n "$striplib"; then ++ $show "$striplib $destdir/$realname" ++ $run eval "$striplib $destdir/$realname" || exit $? ++ fi ++ ++ if test "$#" -gt 0; then ++ # Delete the old symlinks, and create new ones. ++ # Try `ln -sf' first, because the `ln' binary might depend on ++ # the symlink we replace! Solaris /bin/ln does not understand -f, ++ # so we also need to try rm && ln -s. ++ for linkname ++ do ++ if test "$linkname" != "$realname"; then ++ $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" ++ $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" ++ fi ++ done ++ fi ++ ++ # Do each command in the postinstall commands. ++ lib="$destdir/$realname" ++ cmds=$postinstall_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" || { ++ lt_exit=$? ++ ++ # Restore the uninstalled library and exit ++ if test "$mode" = relink; then ++ $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' ++ fi ++ ++ exit $lt_exit ++ } ++ done ++ IFS="$save_ifs" ++ fi ++ ++ # Install the pseudo-library for information purposes. ++ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ instname="$dir/$name"i ++ $show "$install_prog $instname $destdir/$name" ++ $run eval "$install_prog $instname $destdir/$name" || exit $? ++ ++ # Maybe install the static library, too. ++ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ++ ;; ++ ++ *.lo) ++ # Install (i.e. copy) a libtool object. ++ ++ # Figure out destination file name, if it wasn't already specified. ++ if test -n "$destname"; then ++ destfile="$destdir/$destname" ++ else ++ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ destfile="$destdir/$destfile" ++ fi ++ ++ # Deduce the name of the destination old-style object file. ++ case $destfile in ++ *.lo) ++ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` ++ ;; ++ *.$objext) ++ staticdest="$destfile" ++ destfile= ++ ;; ++ *) ++ $echo "$modename: cannot copy a libtool object to `$destfile'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ # Install the libtool object if requested. ++ if test -n "$destfile"; then ++ $show "$install_prog $file $destfile" ++ $run eval "$install_prog $file $destfile" || exit $? ++ fi ++ ++ # Install the old object if enabled. ++ if test "$build_old_libs" = yes; then ++ # Deduce the name of the old-style object file. ++ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` ++ ++ $show "$install_prog $staticobj $staticdest" ++ $run eval "$install_prog $staticobj $staticdest" || exit $? ++ fi ++ exit $EXIT_SUCCESS ++ ;; ++ ++ *) ++ # Figure out destination file name, if it wasn't already specified. ++ if test -n "$destname"; then ++ destfile="$destdir/$destname" ++ else ++ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ destfile="$destdir/$destfile" ++ fi ++ ++ # If the file is missing, and there is a .exe on the end, strip it ++ # because it is most likely a libtool script we actually want to ++ # install ++ stripped_ext="" ++ case $file in ++ *.exe) ++ if test ! -f "$file"; then ++ file=`$echo $file|${SED} 's,.exe$,,'` ++ stripped_ext=".exe" ++ fi ++ ;; ++ esac ++ ++ # Do a test to see if this is really a libtool program. ++ case $host in ++ *cygwin*|*mingw*) ++ wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` ++ ;; ++ *) ++ wrapper=$file ++ ;; ++ esac ++ if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then ++ notinst_deplibs= ++ relink_command= ++ ++ # Note that it is not necessary on cygwin/mingw to append a dot to ++ # foo even if both foo and FILE.exe exist: automatic-append-.exe ++ # behavior happens only for exec(3), not for open(2)! Also, sourcing ++ # `FILE.' does not work on cygwin managed mounts. ++ # ++ # If there is no directory component, then add one. ++ case $wrapper in ++ */* | *\*) . ${wrapper} ;; ++ *) . ./${wrapper} ;; ++ esac ++ ++ # Check the variables that should have been set. ++ if test -z "$notinst_deplibs"; then ++ $echo "$modename: invalid libtool wrapper script `$wrapper'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ finalize=yes ++ for lib in $notinst_deplibs; do ++ # Check to see that each library is installed. ++ libdir= ++ if test -f "$lib"; then ++ # If there is no directory component, then add one. ++ case $lib in ++ */* | *\*) . $lib ;; ++ *) . ./$lib ;; ++ esac ++ fi ++ libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test ++ if test -n "$libdir" && test ! -f "$libfile"; then ++ $echo "$modename: warning: `$lib' has not been installed in `$libdir'" 1>&2 ++ finalize=no ++ fi ++ done ++ ++ relink_command= ++ # Note that it is not necessary on cygwin/mingw to append a dot to ++ # foo even if both foo and FILE.exe exist: automatic-append-.exe ++ # behavior happens only for exec(3), not for open(2)! Also, sourcing ++ # `FILE.' does not work on cygwin managed mounts. ++ # ++ # If there is no directory component, then add one. ++ case $wrapper in ++ */* | *\*) . ${wrapper} ;; ++ *) . ./${wrapper} ;; ++ esac ++ ++ outputname= ++ if test "$fast_install" = no && test -n "$relink_command"; then ++ if test "$finalize" = yes && test -z "$run"; then ++ tmpdir=`func_mktempdir` ++ file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` ++ outputname="$tmpdir/$file" ++ # Replace the output file specification. ++ relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` ++ ++ $show "$relink_command" ++ if $run eval "$relink_command"; then : ++ else ++ $echo "$modename: error: relink `$file' with the above command before installing it" 1>&2 ++ ${rm}r "$tmpdir" ++ continue ++ fi ++ file="$outputname" ++ else ++ $echo "$modename: warning: cannot relink `$file'" 1>&2 ++ fi ++ else ++ # Install the binary that we compiled earlier. ++ file=`$echo "X$file$stripped_ext" | $Xsed -e "s%([^/]*)$%$objdir/\1%"` ++ fi ++ fi ++ ++ # remove .exe since cygwin /usr/bin/install will append another ++ # one anyway ++ case $install_prog,$host in ++ */usr/bin/install*,*cygwin*) ++ case $file:$destfile in ++ *.exe:*.exe) ++ # this is ok ++ ;; ++ *.exe:*) ++ destfile=$destfile.exe ++ ;; ++ *:*.exe) ++ destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` ++ ;; ++ esac ++ ;; ++ esac ++ $show "$install_prog$stripme $file $destfile" ++ $run eval "$install_prog$stripme $file $destfile" || exit $? ++ test -n "$outputname" && ${rm}r "$tmpdir" ++ ;; ++ esac ++ done ++ ++ for file in $staticlibs; do ++ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ ++ # Set up the ranlib parameters. ++ oldlib="$destdir/$name" ++ ++ $show "$install_prog $file $oldlib" ++ $run eval "$install_prog $file $oldlib" || exit $? ++ ++ if test -n "$stripme" && test -n "$old_striplib"; then ++ $show "$old_striplib $oldlib" ++ $run eval "$old_striplib $oldlib" || exit $? ++ fi ++ ++ # Do each command in the postinstall commands. ++ cmds=$old_postinstall_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" || exit $? ++ done ++ IFS="$save_ifs" ++ done ++ ++ if test -n "$future_libdirs"; then ++ $echo "$modename: warning: remember to run `$progname --finish$future_libdirs'" 1>&2 ++ fi ++ ++ if test -n "$current_libdirs"; then ++ # Maybe just do a dry run. ++ test -n "$run" && current_libdirs=" -n$current_libdirs" ++ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' ++ else ++ exit $EXIT_SUCCESS ++ fi ++ ;; ++ ++ # libtool finish mode ++ finish) ++ modename="$modename: finish" ++ libdirs="$nonopt" ++ admincmds= ++ ++ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then ++ for dir ++ do ++ libdirs="$libdirs $dir" ++ done ++ ++ for libdir in $libdirs; do ++ if test -n "$finish_cmds"; then ++ # Do each command in the finish commands. ++ cmds=$finish_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" || admincmds="$admincmds ++ $cmd" ++ done ++ IFS="$save_ifs" ++ fi ++ if test -n "$finish_eval"; then ++ # Do the single finish_eval. ++ eval cmds="$finish_eval" ++ $run eval "$cmds" || admincmds="$admincmds ++ $cmds" ++ fi ++ done ++ fi ++ ++ # Exit here if they wanted silent mode. ++ test "$show" = : && exit $EXIT_SUCCESS ++ ++ $echo "X----------------------------------------------------------------------" | $Xsed ++ $echo "Libraries have been installed in:" ++ for libdir in $libdirs; do ++ $echo " $libdir" ++ done ++ $echo ++ $echo "If you ever happen to want to link against installed libraries" ++ $echo "in a given directory, LIBDIR, you must either use libtool, and" ++ $echo "specify the full pathname of the library, or use the `-LLIBDIR'" ++ $echo "flag during linking and do at least one of the following:" ++ if test -n "$shlibpath_var"; then ++ $echo " - add LIBDIR to the `$shlibpath_var' environment variable" ++ $echo " during execution" ++ fi ++ if test -n "$runpath_var"; then ++ $echo " - add LIBDIR to the `$runpath_var' environment variable" ++ $echo " during linking" ++ fi ++ if test -n "$hardcode_libdir_flag_spec"; then ++ libdir=LIBDIR ++ eval flag="$hardcode_libdir_flag_spec" ++ ++ $echo " - use the `$flag' linker flag" ++ fi ++ if test -n "$admincmds"; then ++ $echo " - have your system administrator run these commands:$admincmds" ++ fi ++ if test -f /etc/ld.so.conf; then ++ $echo " - have your system administrator add LIBDIR to `/etc/ld.so.conf'" ++ fi ++ $echo ++ $echo "See any operating system documentation about shared libraries for" ++ $echo "more information, such as the ld(1) and ld.so(8) manual pages." ++ $echo "X----------------------------------------------------------------------" | $Xsed ++ exit $EXIT_SUCCESS ++ ;; ++ ++ # libtool execute mode ++ execute) ++ modename="$modename: execute" ++ ++ # The first argument is the command name. ++ cmd="$nonopt" ++ if test -z "$cmd"; then ++ $echo "$modename: you must specify a COMMAND" 1>&2 ++ $echo "$help" ++ exit $EXIT_FAILURE ++ fi ++ ++ # Handle -dlopen flags immediately. ++ for file in $execute_dlfiles; do ++ if test ! -f "$file"; then ++ $echo "$modename: `$file' is not a file" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ dir= ++ case $file in ++ *.la) ++ # Check to see that this really is a libtool archive. ++ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : ++ else ++ $echo "$modename: `$lib' is not a valid libtool archive" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ # Read the libtool library. ++ dlname= ++ library_names= ++ ++ # If there is no directory component, then add one. ++ case $file in ++ */* | *\*) . $file ;; ++ *) . ./$file ;; ++ esac ++ ++ # Skip this library if it cannot be dlopened. ++ if test -z "$dlname"; then ++ # Warn if it was a shared library. ++ test -n "$library_names" && $echo "$modename: warning: `$file' was not linked with `-export-dynamic'" ++ continue ++ fi ++ ++ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$dir" = "X$file" && dir=. ++ ++ if test -f "$dir/$objdir/$dlname"; then ++ dir="$dir/$objdir" ++ else ++ $echo "$modename: cannot find `$dlname' in `$dir' or `$dir/$objdir'" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ;; ++ ++ *.lo) ++ # Just add the directory containing the .lo file. ++ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` ++ test "X$dir" = "X$file" && dir=. ++ ;; ++ ++ *) ++ $echo "$modename: warning `-dlopen' is ignored for non-libtool libraries and objects" 1>&2 ++ continue ++ ;; ++ esac ++ ++ # Get the absolute pathname. ++ absdir=`cd "$dir" && pwd` ++ test -n "$absdir" && dir="$absdir" ++ ++ # Now add the directory to shlibpath_var. ++ if eval "test -z "$$shlibpath_var""; then ++ eval "$shlibpath_var="$dir"" ++ else ++ eval "$shlibpath_var="$dir:$$shlibpath_var"" ++ fi ++ done ++ ++ # This variable tells wrapper scripts just to set shlibpath_var ++ # rather than running their programs. ++ libtool_execute_magic="$magic" ++ ++ # Check if any of the arguments is a wrapper script. ++ args= ++ for file ++ do ++ case $file in ++ -*) ;; ++ *) ++ # Do a test to see if this is really a libtool program. ++ if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ # If there is no directory component, then add one. ++ case $file in ++ */* | *\*) . $file ;; ++ *) . ./$file ;; ++ esac ++ ++ # Transform arg to wrapped name. ++ file="$progdir/$program" ++ fi ++ ;; ++ esac ++ # Quote arguments (to preserve shell metacharacters). ++ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` ++ args="$args "$file"" ++ done ++ ++ if test -z "$run"; then ++ if test -n "$shlibpath_var"; then ++ # Export the shlibpath_var. ++ eval "export $shlibpath_var" ++ fi ++ ++ # Restore saved environment variables ++ if test "${save_LC_ALL+set}" = set; then ++ LC_ALL="$save_LC_ALL"; export LC_ALL ++ fi ++ if test "${save_LANG+set}" = set; then ++ LANG="$save_LANG"; export LANG ++ fi ++ ++ # Now prepare to actually exec the command. ++ exec_cmd="$cmd$args" ++ else ++ # Display what would be done. ++ if test -n "$shlibpath_var"; then ++ eval "$echo "$shlibpath_var=$$shlibpath_var"" ++ $echo "export $shlibpath_var" ++ fi ++ $echo "$cmd$args" ++ exit $EXIT_SUCCESS ++ fi ++ ;; ++ ++ # libtool clean and uninstall mode ++ clean | uninstall) ++ modename="$modename: $mode" ++ rm="$nonopt" ++ files= ++ rmforce= ++ exit_status=0 ++ ++ # This variable tells wrapper scripts just to set variables rather ++ # than running their programs. ++ libtool_install_magic="$magic" ++ ++ for arg ++ do ++ case $arg in ++ -f) rm="$rm $arg"; rmforce=yes ;; ++ -*) rm="$rm $arg" ;; ++ *) files="$files $arg" ;; ++ esac ++ done ++ ++ if test -z "$rm"; then ++ $echo "$modename: you must specify an RM program" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++ ++ rmdirs= ++ ++ origobjdir="$objdir" ++ for file in $files; do ++ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` ++ if test "X$dir" = "X$file"; then ++ dir=. ++ objdir="$origobjdir" ++ else ++ objdir="$dir/$origobjdir" ++ fi ++ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` ++ test "$mode" = uninstall && objdir="$dir" ++ ++ # Remember objdir for removal later, being careful to avoid duplicates ++ if test "$mode" = clean; then ++ case " $rmdirs " in ++ *" $objdir "*) ;; ++ *) rmdirs="$rmdirs $objdir" ;; ++ esac ++ fi ++ ++ # Don't error if the file doesn't exist and rm -f was used. ++ if (test -L "$file") >/dev/null 2>&1 \ ++ || (test -h "$file") >/dev/null 2>&1 \ ++ || test -f "$file"; then ++ : ++ elif test -d "$file"; then ++ exit_status=1 ++ continue ++ elif test "$rmforce" = yes; then ++ continue ++ fi ++ ++ rmfiles="$file" ++ ++ case $name in ++ *.la) ++ # Possibly a libtool archive, so verify it. ++ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ . $dir/$name ++ ++ # Delete the libtool libraries and symlinks. ++ for n in $library_names; do ++ rmfiles="$rmfiles $objdir/$n" ++ done ++ test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" ++ ++ case "$mode" in ++ clean) ++ case " $library_names " in ++ # " " in the beginning catches empty $dlname ++ *" $dlname "*) ;; ++ *) rmfiles="$rmfiles $objdir/$dlname" ;; ++ esac ++ test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" ++ ;; ++ uninstall) ++ if test -n "$library_names"; then ++ # Do each command in the postuninstall commands. ++ cmds=$postuninstall_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" ++ if test "$?" -ne 0 && test "$rmforce" != yes; then ++ exit_status=1 ++ fi ++ done ++ IFS="$save_ifs" ++ fi ++ ++ if test -n "$old_library"; then ++ # Do each command in the old_postuninstall commands. ++ cmds=$old_postuninstall_cmds ++ save_ifs="$IFS"; IFS='~' ++ for cmd in $cmds; do ++ IFS="$save_ifs" ++ eval cmd="$cmd" ++ $show "$cmd" ++ $run eval "$cmd" ++ if test "$?" -ne 0 && test "$rmforce" != yes; then ++ exit_status=1 ++ fi ++ done ++ IFS="$save_ifs" ++ fi ++ # FIXME: should reinstall the best remaining shared library. ++ ;; ++ esac ++ fi ++ ;; ++ ++ *.lo) ++ # Possibly a libtool object, so verify it. ++ if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ ++ # Read the .lo file ++ . $dir/$name ++ ++ # Add PIC object to the list of files to remove. ++ if test -n "$pic_object" \ ++ && test "$pic_object" != none; then ++ rmfiles="$rmfiles $dir/$pic_object" ++ fi ++ ++ # Add non-PIC object to the list of files to remove. ++ if test -n "$non_pic_object" \ ++ && test "$non_pic_object" != none; then ++ rmfiles="$rmfiles $dir/$non_pic_object" ++ fi ++ fi ++ ;; ++ ++ *) ++ if test "$mode" = clean ; then ++ noexename=$name ++ case $file in ++ *.exe) ++ file=`$echo $file|${SED} 's,.exe$,,'` ++ noexename=`$echo $name|${SED} 's,.exe$,,'` ++ # $file with .exe has already been added to rmfiles, ++ # add $file without .exe ++ rmfiles="$rmfiles $file" ++ ;; ++ esac ++ # Do a test to see if this is a libtool program. ++ if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then ++ relink_command= ++ . $dir/$noexename ++ ++ # note $name still contains .exe if it was in $file originally ++ # as does the version of $file that was added into $rmfiles ++ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" ++ if test "$fast_install" = yes && test -n "$relink_command"; then ++ rmfiles="$rmfiles $objdir/lt-$name" ++ fi ++ if test "X$noexename" != "X$name" ; then ++ rmfiles="$rmfiles $objdir/lt-${noexename}.c" ++ fi ++ fi ++ fi ++ ;; ++ esac ++ $show "$rm $rmfiles" ++ $run $rm $rmfiles || exit_status=1 ++ done ++ objdir="$origobjdir" ++ ++ # Try to remove the ${objdir}s in the directories where we deleted files ++ for dir in $rmdirs; do ++ if test -d "$dir"; then ++ $show "rmdir $dir" ++ $run rmdir $dir >/dev/null 2>&1 ++ fi ++ done ++ ++ exit $exit_status ++ ;; ++ ++ "") ++ $echo "$modename: you must specify a MODE" 1>&2 ++ $echo "$generic_help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++ esac ++ ++ if test -z "$exec_cmd"; then ++ $echo "$modename: invalid operation mode `$mode'" 1>&2 ++ $echo "$generic_help" 1>&2 ++ exit $EXIT_FAILURE ++ fi ++fi # test -z "$show_help" ++ ++if test -n "$exec_cmd"; then ++ eval exec $exec_cmd ++ exit $EXIT_FAILURE ++fi ++ ++# We need to display help for each of the modes. ++case $mode in ++"") $echo \ ++"Usage: $modename [OPTION]... [MODE-ARG]... ++ ++Provide generalized library-building support services. ++ ++ --config show all configuration variables ++ --debug enable verbose shell tracing ++-n, --dry-run display commands without modifying any files ++ --features display basic configuration information and exit ++ --finish same as `--mode=finish' ++ --help display this help message and exit ++ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] ++ --quiet same as `--silent' ++ --silent don't print informational messages ++ --tag=TAG use configuration variables from tag TAG ++ --version print version information ++ ++MODE must be one of the following: ++ ++ clean remove files from the build directory ++ compile compile a source file into a libtool object ++ execute automatically set library path, then run a program ++ finish complete the installation of libtool libraries ++ install install libraries or executables ++ link create a library or an executable ++ uninstall remove libraries from an installed directory ++ ++MODE-ARGS vary depending on the MODE. Try `$modename --help --mode=MODE' for ++a more detailed description of MODE. ++ ++Report bugs to <bug-libtool@gnu.org>." ++ exit $EXIT_SUCCESS ++ ;; ++ ++clean) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... ++ ++Remove files from the build directory. ++ ++RM is the name of the program to use to delete files associated with each FILE ++(typically `/bin/rm'). RM-OPTIONS are options (such as `-f') to be passed ++to RM. ++ ++If FILE is a libtool library, object or program, all the files associated ++with it are deleted. Otherwise, only FILE itself is deleted using RM." ++ ;; ++ ++compile) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE ++ ++Compile a source file into a libtool library object. ++ ++This mode accepts the following additional options: ++ ++ -o OUTPUT-FILE set the output file name to OUTPUT-FILE ++ -prefer-pic try to building PIC objects only ++ -prefer-non-pic try to building non-PIC objects only ++ -static always build a `.o' file suitable for static linking ++ ++COMPILE-COMMAND is a command to be used in creating a `standard' object file ++from the given SOURCEFILE. ++ ++The output file name is determined by removing the directory component from ++SOURCEFILE, then substituting the C source code suffix `.c' with the ++library object suffix, `.lo'." ++ ;; ++ ++execute) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... ++ ++Automatically set library path, then run a program. ++ ++This mode accepts the following additional options: ++ ++ -dlopen FILE add the directory containing FILE to the library path ++ ++This mode sets the library path environment variable according to `-dlopen' ++flags. ++ ++If any of the ARGS are libtool executable wrappers, then they are translated ++into their corresponding uninstalled binary, and any of their required library ++directories are added to the library path. ++ ++Then, COMMAND is executed, with ARGS as arguments." ++ ;; ++ ++finish) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... ++ ++Complete the installation of libtool libraries. ++ ++Each LIBDIR is a directory that contains libtool libraries. ++ ++The commands that this mode executes may require superuser privileges. Use ++the `--dry-run' option if you just want to see what would be executed." ++ ;; ++ ++install) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... ++ ++Install executables or libraries. ++ ++INSTALL-COMMAND is the installation command. The first component should be ++either the `install' or `cp' program. ++ ++The rest of the components are interpreted as arguments to that command (only ++BSD-compatible install options are recognized)." ++ ;; ++ ++link) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... ++ ++Link object files or libraries together to form another library, or to ++create an executable program. ++ ++LINK-COMMAND is a command using the C compiler that you would use to create ++a program from several object files. ++ ++The following components of LINK-COMMAND are treated specially: ++ ++ -all-static do not do any dynamic linking at all ++ -avoid-version do not add a version suffix if possible ++ -dlopen FILE `-dlpreopen' FILE if it cannot be dlopened at runtime ++ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols ++ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) ++ -export-symbols SYMFILE ++ try to export only the symbols listed in SYMFILE ++ -export-symbols-regex REGEX ++ try to export only the symbols matching REGEX ++ -LLIBDIR search LIBDIR for required installed libraries ++ -lNAME OUTPUT-FILE requires the installed library libNAME ++ -module build a library that can dlopened ++ -no-fast-install disable the fast-install mode ++ -no-install link a not-installable executable ++ -no-undefined declare that a library does not refer to external symbols ++ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects ++ -objectlist FILE Use a list of object files found in FILE to specify objects ++ -precious-files-regex REGEX ++ don't remove output files matching REGEX ++ -release RELEASE specify package release information ++ -rpath LIBDIR the created library will eventually be installed in LIBDIR ++ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries ++ -static do not do any dynamic linking of libtool libraries ++ -version-info CURRENT[:REVISION[:AGE]] ++ specify library version info [each variable defaults to 0] ++ ++All other options (arguments beginning with `-') are ignored. ++ ++Every other argument is treated as a filename. Files ending in `.la' are ++treated as uninstalled libtool libraries, other files are standard or library ++object files. ++ ++If the OUTPUT-FILE ends in `.la', then a libtool library is created, ++only library objects (`.lo' files) may be specified, and `-rpath' is ++required, except when creating a convenience library. ++ ++If OUTPUT-FILE ends in `.a' or `.lib', then a standard library is created ++using `ar' and `ranlib', or on Windows using `lib'. ++ ++If OUTPUT-FILE ends in `.lo' or `.${objext}', then a reloadable object file ++is created, otherwise an executable program is created." ++ ;; ++ ++uninstall) ++ $echo \ ++"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... ++ ++Remove libraries from an installation directory. ++ ++RM is the name of the program to use to delete files associated with each FILE ++(typically `/bin/rm'). RM-OPTIONS are options (such as `-f') to be passed ++to RM. ++ ++If FILE is a libtool library, all the files associated with it are deleted. ++Otherwise, only FILE itself is deleted using RM." ++ ;; ++ ++*) ++ $echo "$modename: invalid operation mode `$mode'" 1>&2 ++ $echo "$help" 1>&2 ++ exit $EXIT_FAILURE ++ ;; ++esac ++ ++$echo ++$echo "Try `$modename --help' for more information about other modes." ++ ++exit $? ++ ++# The TAGs below are defined such that we never get into a situation ++# in which we disable both kinds of libraries. Given conflicting ++# choices, we go for a static library, that is the most portable, ++# since we can't tell whether shared libraries were disabled because ++# the user asked for that or because the platform doesn't support ++# them. This is particularly important on AIX, because we don't ++# support having both static and shared libraries enabled at the same ++# time on that platform, so we default to a shared-only configuration. ++# If a disable-shared tag is given, we'll fallback to a static-only ++# configuration. But we'll never go from static-only to shared-only. ++ ++# ### BEGIN LIBTOOL TAG CONFIG: disable-shared ++disable_libs=shared ++# ### END LIBTOOL TAG CONFIG: disable-shared ++ ++# ### BEGIN LIBTOOL TAG CONFIG: disable-static ++disable_libs=static ++# ### END LIBTOOL TAG CONFIG: disable-static ++ ++# Local Variables: ++# mode:shell-script ++# sh-indentation:2 ++# End: +diff -urN lua-5.1.4/Makefile lua-5.1.4-autotoolize/Makefile +--- lua-5.1.4/Makefile 2008-08-12 02:40:48.000000000 +0200 ++++ lua-5.1.4-autotoolize/Makefile 2008-09-03 13:24:40.000000000 +0200 +@@ -1,128 +0,0 @@ +-# makefile for installing Lua +-# see INSTALL for installation instructions +-# see src/Makefile and src/luaconf.h for further customization +- +-# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= +- +-# Your platform. See PLATS for possible values. +-PLAT= none +- +-# Where to install. The installation starts in the src and doc directories, +-# so take care if INSTALL_TOP is not an absolute path. +-INSTALL_TOP= /usr/local +-INSTALL_BIN= $(INSTALL_TOP)/bin +-INSTALL_INC= $(INSTALL_TOP)/include +-INSTALL_LIB= $(INSTALL_TOP)/lib +-INSTALL_MAN= $(INSTALL_TOP)/man/man1 +-# +-# You probably want to make INSTALL_LMOD and INSTALL_CMOD consistent with +-# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h (and also with etc/lua.pc). +-INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V +-INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V +- +-# How to install. If your install program does not support "-p", then you +-# may have to run ranlib on the installed liblua.a (do "make ranlib"). +-INSTALL= install -p +-INSTALL_EXEC= $(INSTALL) -m 0755 +-INSTALL_DATA= $(INSTALL) -m 0644 +-# +-# If you don't have install you can use cp instead. +-# INSTALL= cp -p +-# INSTALL_EXEC= $(INSTALL) +-# INSTALL_DATA= $(INSTALL) +- +-# Utilities. +-MKDIR= mkdir -p +-RANLIB= ranlib +- +-# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= +- +-# Convenience platforms targets. +-PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris +- +-# What to install. +-TO_BIN= lua luac +-TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp +-TO_LIB= liblua.a +-TO_MAN= lua.1 luac.1 +- +-# Lua version and release. +-V= 5.1 +-R= 5.1.4 +- +-all: $(PLAT) +- +-$(PLATS) clean: +- cd src && $(MAKE) $@ +- +-test: dummy +- src/lua test/hello.lua +- +-install: dummy +- cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) +- cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) +- cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) +- cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) +- cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) +- +-ranlib: +- cd src && cd $(INSTALL_LIB) && $(RANLIB) $(TO_LIB) +- +-local: +- $(MAKE) install INSTALL_TOP=.. +- +-none: +- @echo "Please do" +- @echo " make PLATFORM" +- @echo "where PLATFORM is one of these:" +- @echo " $(PLATS)" +- @echo "See INSTALL for complete instructions." +- +-# make may get confused with test/ and INSTALL in a case-insensitive OS +-dummy: +- +-# echo config parameters +-echo: +- @echo "" +- @echo "These are the parameters currently set in src/Makefile to build Lua $R:" +- @echo "" +- @cd src && $(MAKE) -s echo +- @echo "" +- @echo "These are the parameters currently set in Makefile to install Lua $R:" +- @echo "" +- @echo "PLAT = $(PLAT)" +- @echo "INSTALL_TOP = $(INSTALL_TOP)" +- @echo "INSTALL_BIN = $(INSTALL_BIN)" +- @echo "INSTALL_INC = $(INSTALL_INC)" +- @echo "INSTALL_LIB = $(INSTALL_LIB)" +- @echo "INSTALL_MAN = $(INSTALL_MAN)" +- @echo "INSTALL_LMOD = $(INSTALL_LMOD)" +- @echo "INSTALL_CMOD = $(INSTALL_CMOD)" +- @echo "INSTALL_EXEC = $(INSTALL_EXEC)" +- @echo "INSTALL_DATA = $(INSTALL_DATA)" +- @echo "" +- @echo "See also src/luaconf.h ." +- @echo "" +- +-# echo private config parameters +-pecho: +- @echo "V = $(V)" +- @echo "R = $(R)" +- @echo "TO_BIN = $(TO_BIN)" +- @echo "TO_INC = $(TO_INC)" +- @echo "TO_LIB = $(TO_LIB)" +- @echo "TO_MAN = $(TO_MAN)" +- +-# echo config parameters as Lua code +-# uncomment the last sed expression if you want nil instead of empty strings +-lecho: +- @echo "-- installation parameters for Lua $R" +- @echo "VERSION = '$V'" +- @echo "RELEASE = '$R'" +- @$(MAKE) echo | grep = | sed -e 's/= /= "/' -e 's/$$/"/' #-e 's/""/nil/' +- @echo "-- EOF" +- +-# list targets that do not create files (but not all makes understand .PHONY) +-.PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho +- +-# (end of Makefile) +diff -urN lua-5.1.4/Makefile.am lua-5.1.4-autotoolize/Makefile.am +--- lua-5.1.4/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/Makefile.am 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,3 @@ ++SUBDIRS = src doc etc test ++ ++EXTRA_DIST = autogen.sh COPYRIGHT HISTORY INSTALL MANIFEST README +diff -urN lua-5.1.4/Makefile.in lua-5.1.4-autotoolize/Makefile.in +--- lua-5.1.4/Makefile.in 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/Makefile.in 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,614 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = . ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ ++ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ ++ $(top_srcdir)/configure INSTALL config.guess config.sub \ ++ depcomp install-sh ltmain.sh missing ++subdir = . ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ ++ configure.lineno configure.status.lineno ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = config.h ++CONFIG_CLEAN_FILES = ++SOURCES = ++DIST_SOURCES = ++RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ ++ html-recursive info-recursive install-data-recursive \ ++ install-exec-recursive install-info-recursive \ ++ install-recursive installcheck-recursive installdirs-recursive \ ++ pdf-recursive ps-recursive uninstall-info-recursive \ ++ uninstall-recursive ++ETAGS = etags ++CTAGS = ctags ++DIST_SUBDIRS = $(SUBDIRS) ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++distdir = $(PACKAGE)-$(VERSION) ++top_distdir = $(distdir) ++am__remove_distdir = \ ++ { test ! -d $(distdir) \ ++ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ ++ && rm -fr $(distdir); }; } ++DIST_ARCHIVES = $(distdir).tar.gz ++GZIP_ENV = --best ++distuninstallcheck_listfiles = find . -type f -print ++distcleancheck_listfiles = find . -type f -print ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++LUA_BUILD_AS_DLL_DEFS = @LUA_BUILD_AS_DLL_DEFS@ ++LUA_DL_DEFS = @LUA_DL_DEFS@ ++LUA_LIBS = @LUA_LIBS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++POSIX_DEFS = @POSIX_DEFS@ ++RANLIB = @RANLIB@ ++READLINE_DEFS = @READLINE_DEFS@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++SUBDIRS = src doc etc test ++EXTRA_DIST = autogen.sh COPYRIGHT HISTORY INSTALL MANIFEST README ++all: config.h ++ $(MAKE) $(AM_MAKEFLAGS) all-recursive ++ ++.SUFFIXES: ++am--refresh: ++ @: ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ ++ cd $(srcdir) && $(AUTOMAKE) --foreign \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --foreign Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ echo ' $(SHELL) ./config.status'; \ ++ $(SHELL) ./config.status;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ $(SHELL) ./config.status --recheck ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(srcdir) && $(AUTOCONF) ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) ++ ++config.h: stamp-h1 ++ @if test ! -f $@; then \ ++ rm -f stamp-h1; \ ++ $(MAKE) stamp-h1; \ ++ else :; fi ++ ++stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status ++ @rm -f stamp-h1 ++ cd $(top_builddir) && $(SHELL) ./config.status config.h ++$(srcdir)/config.h.in: $(am__configure_deps) ++ cd $(top_srcdir) && $(AUTOHEADER) ++ rm -f stamp-h1 ++ touch $@ ++ ++distclean-hdr: ++ -rm -f config.h stamp-h1 ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++ ++# This directory's subdirectories are mostly independent; you can cd ++# into them and run `make' without going through this Makefile. ++# To change the values of `make' variables: instead of editing Makefiles, ++# (1) if the variable is set in `config.status', edit `config.status' ++# (which will cause the Makefiles to be regenerated when you run `make'); ++# (2) otherwise, pass the desired values on the `make' command line. ++$(RECURSIVE_TARGETS): ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ dot_seen=yes; \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done; \ ++ if test "$$dot_seen" = "no"; then \ ++ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ ++ fi; test -z "$$fail" ++ ++mostlyclean-recursive clean-recursive distclean-recursive \ ++maintainer-clean-recursive: ++ @failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ case "$@" in \ ++ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ ++ *) list='$(SUBDIRS)' ;; \ ++ esac; \ ++ rev=''; for subdir in $$list; do \ ++ if test "$$subdir" = "."; then :; else \ ++ rev="$$subdir $$rev"; \ ++ fi; \ ++ done; \ ++ rev="$$rev ."; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ for subdir in $$rev; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done && test -z "$$fail" ++tags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ ++ done ++ctags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ ++ done ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ ++ include_option=--etags-include; \ ++ empty_fix=.; \ ++ else \ ++ include_option=--include; \ ++ empty_fix=; \ ++ fi; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test ! -f $$subdir/TAGS || \ ++ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ ++ fi; \ ++ done; \ ++ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ $(am__remove_distdir) ++ mkdir $(distdir) ++ $(mkdir_p) $(distdir)/etc $(distdir)/src ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test -d "$(distdir)/$$subdir" \ ++ || $(mkdir_p) "$(distdir)/$$subdir" \ ++ || exit 1; \ ++ distdir=`$(am__cd) $(distdir) && pwd`; \ ++ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ ++ (cd $$subdir && \ ++ $(MAKE) $(AM_MAKEFLAGS) \ ++ top_distdir="$$top_distdir" \ ++ distdir="$$distdir/$$subdir" \ ++ distdir) \ ++ || exit 1; \ ++ fi; \ ++ done ++ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} ; -o \ ++ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} ; -o \ ++ ! -type d ! -perm -400 -exec chmod a+r {} ; -o \ ++ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} ; \ ++ || chmod -R a+r $(distdir) ++dist-gzip: distdir ++ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz ++ $(am__remove_distdir) ++ ++dist-bzip2: distdir ++ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 ++ $(am__remove_distdir) ++ ++dist-tarZ: distdir ++ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z ++ $(am__remove_distdir) ++ ++dist-shar: distdir ++ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz ++ $(am__remove_distdir) ++ ++dist-zip: distdir ++ -rm -f $(distdir).zip ++ zip -rq $(distdir).zip $(distdir) ++ $(am__remove_distdir) ++ ++dist dist-all: distdir ++ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz ++ $(am__remove_distdir) ++ ++# This target untars the dist file and tries a VPATH configuration. Then ++# it guarantees that the distribution is self-contained by making another ++# tarfile. ++distcheck: dist ++ case '$(DIST_ARCHIVES)' in \ ++ *.tar.gz*) \ ++ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ ++ *.tar.bz2*) \ ++ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ ++ *.tar.Z*) \ ++ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ ++ *.shar.gz*) \ ++ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ ++ *.zip*) \ ++ unzip $(distdir).zip ;;\ ++ esac ++ chmod -R a-w $(distdir); chmod a+w $(distdir) ++ mkdir $(distdir)/_build ++ mkdir $(distdir)/_inst ++ chmod a-w $(distdir) ++ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\/]:[\/],/,'` \ ++ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ ++ && cd $(distdir)/_build \ ++ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ ++ $(DISTCHECK_CONFIGURE_FLAGS) \ ++ && $(MAKE) $(AM_MAKEFLAGS) \ ++ && $(MAKE) $(AM_MAKEFLAGS) dvi \ ++ && $(MAKE) $(AM_MAKEFLAGS) check \ ++ && $(MAKE) $(AM_MAKEFLAGS) install \ ++ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ ++ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ ++ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ ++ distuninstallcheck \ ++ && chmod -R a-w "$$dc_install_base" \ ++ && ({ \ ++ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ ++ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ ++ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ ++ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ ++ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ ++ } || { rm -rf "$$dc_destdir"; exit 1; }) \ ++ && rm -rf "$$dc_destdir" \ ++ && $(MAKE) $(AM_MAKEFLAGS) dist \ ++ && rm -rf $(DIST_ARCHIVES) \ ++ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck ++ $(am__remove_distdir) ++ @(echo "$(distdir) archives ready for distribution: "; \ ++ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ ++ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' ++distuninstallcheck: ++ @cd $(distuninstallcheck_dir) \ ++ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ ++ || { echo "ERROR: files left after uninstall:" ; \ ++ if test -n "$(DESTDIR)"; then \ ++ echo " (check DESTDIR support)"; \ ++ fi ; \ ++ $(distuninstallcheck_listfiles) ; \ ++ exit 1; } >&2 ++distcleancheck: distclean ++ @if test '$(srcdir)' = . ; then \ ++ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ ++ exit 1 ; \ ++ fi ++ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ ++ || { echo "ERROR: files left in build directory after distclean:" ; \ ++ $(distcleancheck_listfiles) ; \ ++ exit 1; } >&2 ++check-am: all-am ++check: check-recursive ++all-am: Makefile config.h ++installdirs: installdirs-recursive ++installdirs-am: ++install: install-recursive ++install-exec: install-exec-recursive ++install-data: install-data-recursive ++uninstall: uninstall-recursive ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-recursive ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-recursive ++ ++clean-am: clean-generic clean-libtool mostlyclean-am ++ ++distclean: distclean-recursive ++ -rm -f $(am__CONFIG_DISTCLEAN_FILES) ++ -rm -f Makefile ++distclean-am: clean-am distclean-generic distclean-hdr \ ++ distclean-libtool distclean-tags ++ ++dvi: dvi-recursive ++ ++dvi-am: ++ ++html: html-recursive ++ ++info: info-recursive ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: ++ ++install-info: install-info-recursive ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-recursive ++ -rm -f $(am__CONFIG_DISTCLEAN_FILES) ++ -rm -rf $(top_srcdir)/autom4te.cache ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-recursive ++ ++mostlyclean-am: mostlyclean-generic mostlyclean-libtool ++ ++pdf: pdf-recursive ++ ++pdf-am: ++ ++ps: ps-recursive ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am ++ ++uninstall-info: uninstall-info-recursive ++ ++.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ ++ check-am clean clean-generic clean-libtool clean-recursive \ ++ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ ++ dist-shar dist-tarZ dist-zip distcheck distclean \ ++ distclean-generic distclean-hdr distclean-libtool \ ++ distclean-recursive distclean-tags distcleancheck distdir \ ++ distuninstallcheck dvi dvi-am html html-am info info-am \ ++ install install-am install-data install-data-am install-exec \ ++ install-exec-am install-info install-info-am install-man \ ++ install-strip installcheck installcheck-am installdirs \ ++ installdirs-am maintainer-clean maintainer-clean-generic \ ++ maintainer-clean-recursive mostlyclean mostlyclean-generic \ ++ mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \ ++ tags tags-recursive uninstall uninstall-am uninstall-info-am ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -urN lua-5.1.4/missing lua-5.1.4-autotoolize/missing +--- lua-5.1.4/missing 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/missing 2008-09-03 13:18:32.000000000 +0200 +@@ -0,0 +1,360 @@ ++#! /bin/sh ++# Common stub for a few missing GNU programs while installing. ++ ++scriptversion=2005-06-08.21 ++ ++# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 ++# Free Software Foundation, Inc. ++# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2, or (at your option) ++# any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++# 02110-1301, USA. ++ ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program that contains a ++# configuration script generated by Autoconf, you may include it under ++# the same distribution terms that you use for the rest of that program. ++ ++if test $# -eq 0; then ++ echo 1>&2 "Try `$0 --help' for more information" ++ exit 1 ++fi ++ ++run=: ++ ++# In the cases where this matters, `missing' is being run in the ++# srcdir already. ++if test -f configure.ac; then ++ configure_ac=configure.ac ++else ++ configure_ac=configure.in ++fi ++ ++msg="missing on your system" ++ ++case "$1" in ++--run) ++ # Try to run requested program, and just exit if it succeeds. ++ run= ++ shift ++ "$@" && exit 0 ++ # Exit code 63 means version mismatch. This often happens ++ # when the user try to use an ancient version of a tool on ++ # a file that requires a minimum version. In this case we ++ # we should proceed has if the program had been absent, or ++ # if --run hadn't been passed. ++ if test $? = 63; then ++ run=: ++ msg="probably too old" ++ fi ++ ;; ++ ++ -h|--h|--he|--hel|--help) ++ echo "\ ++$0 [OPTION]... PROGRAM [ARGUMENT]... ++ ++Handle `PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an ++error status if there is no known handling for PROGRAM. ++ ++Options: ++ -h, --help display this help and exit ++ -v, --version output version information and exit ++ --run try to run the given command, and emulate it if it fails ++ ++Supported PROGRAM values: ++ aclocal touch file `aclocal.m4' ++ autoconf touch file `configure' ++ autoheader touch file `config.h.in' ++ automake touch all `Makefile.in' files ++ bison create `y.tab.[ch]', if possible, from existing .[ch] ++ flex create `lex.yy.c', if possible, from existing .c ++ help2man touch the output file ++ lex create `lex.yy.c', if possible, from existing .c ++ makeinfo touch the output file ++ tar try tar, gnutar, gtar, then tar without non-portable flags ++ yacc create `y.tab.[ch]', if possible, from existing .[ch] ++ ++Send bug reports to <bug-automake@gnu.org>." ++ exit $? ++ ;; ++ ++ -v|--v|--ve|--ver|--vers|--versi|--versio|--version) ++ echo "missing $scriptversion (GNU Automake)" ++ exit $? ++ ;; ++ ++ -*) ++ echo 1>&2 "$0: Unknown `$1' option" ++ echo 1>&2 "Try `$0 --help' for more information" ++ exit 1 ++ ;; ++ ++esac ++ ++# Now exit if we have it, but it failed. Also exit now if we ++# don't have it and --version was passed (most likely to detect ++# the program). ++case "$1" in ++ lex|yacc) ++ # Not GNU programs, they don't have --version. ++ ;; ++ ++ tar) ++ if test -n "$run"; then ++ echo 1>&2 "ERROR: `tar' requires --run" ++ exit 1 ++ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then ++ exit 1 ++ fi ++ ;; ++ ++ *) ++ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then ++ # We have it, but it failed. ++ exit 1 ++ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then ++ # Could not run --version or --help. This is probably someone ++ # running `$TOOL --version' or `$TOOL --help' to check whether ++ # $TOOL exists and not knowing $TOOL uses missing. ++ exit 1 ++ fi ++ ;; ++esac ++ ++# If it does not exist, or fails to run (possibly an outdated version), ++# try to emulate it. ++case "$1" in ++ aclocal*) ++ echo 1>&2 "\ ++WARNING: `$1' is $msg. You should only need it if ++ you modified `acinclude.m4' or `${configure_ac}'. You might want ++ to install the `Automake' and `Perl' packages. Grab them from ++ any GNU archive site." ++ touch aclocal.m4 ++ ;; ++ ++ autoconf) ++ echo 1>&2 "\ ++WARNING: `$1' is $msg. You should only need it if ++ you modified `${configure_ac}'. You might want to install the ++ `Autoconf' and `GNU m4' packages. Grab them from any GNU ++ archive site." ++ touch configure ++ ;; ++ ++ autoheader) ++ echo 1>&2 "\ ++WARNING: `$1' is $msg. You should only need it if ++ you modified `acconfig.h' or `${configure_ac}'. You might want ++ to install the `Autoconf' and `GNU m4' packages. Grab them ++ from any GNU archive site." ++ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(([^)]*)).*/\1/p' ${configure_ac}` ++ test -z "$files" && files="config.h" ++ touch_files= ++ for f in $files; do ++ case "$f" in ++ *:*) touch_files="$touch_files "`echo "$f" | ++ sed -e 's/^[^:]*://' -e 's/:.*//'`;; ++ *) touch_files="$touch_files $f.in";; ++ esac ++ done ++ touch $touch_files ++ ;; ++ ++ automake*) ++ echo 1>&2 "\ ++WARNING: `$1' is $msg. You should only need it if ++ you modified `Makefile.am', `acinclude.m4' or `${configure_ac}'. ++ You might want to install the `Automake' and `Perl' packages. ++ Grab them from any GNU archive site." ++ find . -type f -name Makefile.am -print | ++ sed 's/.am$/.in/' | ++ while read f; do touch "$f"; done ++ ;; ++ ++ autom4te) ++ echo 1>&2 "\ ++WARNING: `$1' is needed, but is $msg. ++ You might have modified some files without having the ++ proper tools for further handling them. ++ You can get `$1' as part of `Autoconf' from any GNU ++ archive site." ++ ++ file=`echo "$*" | sed -n 's/.*--output[ =]*([^ ]*).*/\1/p'` ++ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*([^ ]*).*/\1/p'` ++ if test -f "$file"; then ++ touch $file ++ else ++ test -z "$file" || exec >$file ++ echo "#! /bin/sh" ++ echo "# Created by GNU Automake missing as a replacement of" ++ echo "# $ $@" ++ echo "exit 0" ++ chmod +x $file ++ exit 1 ++ fi ++ ;; ++ ++ bison|yacc) ++ echo 1>&2 "\ ++WARNING: `$1' $msg. You should only need it if ++ you modified a `.y' file. You may need the `Bison' package ++ in order for those modifications to take effect. You can get ++ `Bison' from any GNU archive site." ++ rm -f y.tab.c y.tab.h ++ if [ $# -ne 1 ]; then ++ eval LASTARG="${$#}" ++ case "$LASTARG" in ++ *.y) ++ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` ++ if [ -f "$SRCFILE" ]; then ++ cp "$SRCFILE" y.tab.c ++ fi ++ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` ++ if [ -f "$SRCFILE" ]; then ++ cp "$SRCFILE" y.tab.h ++ fi ++ ;; ++ esac ++ fi ++ if [ ! -f y.tab.h ]; then ++ echo >y.tab.h ++ fi ++ if [ ! -f y.tab.c ]; then ++ echo 'main() { return 0; }' >y.tab.c ++ fi ++ ;; ++ ++ lex|flex) ++ echo 1>&2 "\ ++WARNING: `$1' is $msg. You should only need it if ++ you modified a `.l' file. You may need the `Flex' package ++ in order for those modifications to take effect. You can get ++ `Flex' from any GNU archive site." ++ rm -f lex.yy.c ++ if [ $# -ne 1 ]; then ++ eval LASTARG="${$#}" ++ case "$LASTARG" in ++ *.l) ++ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` ++ if [ -f "$SRCFILE" ]; then ++ cp "$SRCFILE" lex.yy.c ++ fi ++ ;; ++ esac ++ fi ++ if [ ! -f lex.yy.c ]; then ++ echo 'main() { return 0; }' >lex.yy.c ++ fi ++ ;; ++ ++ help2man) ++ echo 1>&2 "\ ++WARNING: `$1' is $msg. You should only need it if ++ you modified a dependency of a manual page. You may need the ++ `Help2man' package in order for those modifications to take ++ effect. You can get `Help2man' from any GNU archive site." ++ ++ file=`echo "$*" | sed -n 's/.*-o ([^ ]*).*/\1/p'` ++ if test -z "$file"; then ++ file=`echo "$*" | sed -n 's/.*--output=([^ ]*).*/\1/p'` ++ fi ++ if [ -f "$file" ]; then ++ touch $file ++ else ++ test -z "$file" || exec >$file ++ echo ".ab help2man is required to generate this page" ++ exit 1 ++ fi ++ ;; ++ ++ makeinfo) ++ echo 1>&2 "\ ++WARNING: `$1' is $msg. You should only need it if ++ you modified a `.texi' or `.texinfo' file, or any other file ++ indirectly affecting the aspect of the manual. The spurious ++ call might also be the consequence of using a buggy `make' (AIX, ++ DU, IRIX). You might want to install the `Texinfo' package or ++ the `GNU make' package. Grab either from any GNU archive site." ++ # The file to touch is that specified with -o ... ++ file=`echo "$*" | sed -n 's/.*-o ([^ ]*).*/\1/p'` ++ if test -z "$file"; then ++ # ... or it is the one specified with @setfilename ... ++ infile=`echo "$*" | sed 's/.* ([^ ]*) *$/\1/'` ++ file=`sed -n '/^@setfilename/ { s/.* ([^ ]*) *$/\1/; p; q; }' $infile` ++ # ... or it is derived from the source name (dir/f.texi becomes f.info) ++ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info ++ fi ++ # If the file does not exist, the user really needs makeinfo; ++ # let's fail without touching anything. ++ test -f $file || exit 1 ++ touch $file ++ ;; ++ ++ tar) ++ shift ++ ++ # We have already tried tar in the generic part. ++ # Look for gnutar/gtar before invocation to avoid ugly error ++ # messages. ++ if (gnutar --version > /dev/null 2>&1); then ++ gnutar "$@" && exit 0 ++ fi ++ if (gtar --version > /dev/null 2>&1); then ++ gtar "$@" && exit 0 ++ fi ++ firstarg="$1" ++ if shift; then ++ case "$firstarg" in ++ *o*) ++ firstarg=`echo "$firstarg" | sed s/o//` ++ tar "$firstarg" "$@" && exit 0 ++ ;; ++ esac ++ case "$firstarg" in ++ *h*) ++ firstarg=`echo "$firstarg" | sed s/h//` ++ tar "$firstarg" "$@" && exit 0 ++ ;; ++ esac ++ fi ++ ++ echo 1>&2 "\ ++WARNING: I can't seem to be able to run `tar' with the given arguments. ++ You may want to install GNU tar or Free paxutils, or check the ++ command line arguments." ++ exit 1 ++ ;; ++ ++ *) ++ echo 1>&2 "\ ++WARNING: `$1' is needed, and is $msg. ++ You might have modified some files without having the ++ proper tools for further handling them. Check the `README' file, ++ it often tells you about the needed prerequisites for installing ++ this package. You may also peek at any GNU archive site, in case ++ some other package would contain this missing `$1' program." ++ exit 1 ++ ;; ++esac ++ ++exit 0 ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-end: "$" ++# End: +diff -urN lua-5.1.4/src/luaconf.h lua-5.1.4-autotoolize/src/luaconf.h +--- lua-5.1.4/src/luaconf.h 2008-02-11 17:25:08.000000000 +0100 ++++ lua-5.1.4-autotoolize/src/luaconf.h 2008-09-03 13:25:45.000000000 +0200 +@@ -1,763 +0,0 @@ +-/* +-** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ +-** Configuration file for Lua +-** See Copyright Notice in lua.h +-*/ +- +- +-#ifndef lconfig_h +-#define lconfig_h +- +-#include <limits.h> +-#include <stddef.h> +- +- +-/* +-** ================================================================== +-** Search for "@@" to find all configurable definitions. +-** =================================================================== +-*/ +- +- +-/* +-@@ LUA_ANSI controls the use of non-ansi features. +-** CHANGE it (define it) if you want Lua to avoid the use of any +-** non-ansi feature or library. +-*/ +-#if defined(__STRICT_ANSI__) +-#define LUA_ANSI +-#endif +- +- +-#if !defined(LUA_ANSI) && defined(_WIN32) +-#define LUA_WIN +-#endif +- +-#if defined(LUA_USE_LINUX) +-#define LUA_USE_POSIX +-#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +-#define LUA_USE_READLINE /* needs some extra libraries */ +-#endif +- +-#if defined(LUA_USE_MACOSX) +-#define LUA_USE_POSIX +-#define LUA_DL_DYLD /* does not need extra library */ +-#endif +- +- +- +-/* +-@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +-@* Interfaces Extension (XSI). +-** CHANGE it (define it) if your system is XSI compatible. +-*/ +-#if defined(LUA_USE_POSIX) +-#define LUA_USE_MKSTEMP +-#define LUA_USE_ISATTY +-#define LUA_USE_POPEN +-#define LUA_USE_ULONGJMP +-#endif +- +- +-/* +-@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +-@* Lua check to set its paths. +-@@ LUA_INIT is the name of the environment variable that Lua +-@* checks for initialization code. +-** CHANGE them if you want different names. +-*/ +-#define LUA_PATH "LUA_PATH" +-#define LUA_CPATH "LUA_CPATH" +-#define LUA_INIT "LUA_INIT" +- +- +-/* +-@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +-@* Lua libraries. +-@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +-@* C libraries. +-** CHANGE them if your machine has a non-conventional directory +-** hierarchy or if you want to install your libraries in +-** non-conventional directories. +-*/ +-#if defined(_WIN32) +-/* +-** In Windows, any exclamation mark ('!') in the path is replaced by the +-** path of the directory of the executable file of the current process. +-*/ +-#define LUA_LDIR "!\lua\" +-#define LUA_CDIR "!\" +-#define LUA_PATH_DEFAULT \ +- ".\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\init.lua;" \ +- LUA_CDIR"?.lua;" LUA_CDIR"?\init.lua" +-#define LUA_CPATH_DEFAULT \ +- ".\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" +- +-#else +-#define LUA_ROOT "/usr/local/" +-#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +-#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +-#define LUA_PATH_DEFAULT \ +- "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ +- LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +-#define LUA_CPATH_DEFAULT \ +- "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" +-#endif +- +- +-/* +-@@ LUA_DIRSEP is the directory separator (for submodules). +-** CHANGE it if your machine does not use "/" as the directory separator +-** and is not Windows. (On Windows Lua automatically uses "".) +-*/ +-#if defined(_WIN32) +-#define LUA_DIRSEP "\" +-#else +-#define LUA_DIRSEP "/" +-#endif +- +- +-/* +-@@ LUA_PATHSEP is the character that separates templates in a path. +-@@ LUA_PATH_MARK is the string that marks the substitution points in a +-@* template. +-@@ LUA_EXECDIR in a Windows path is replaced by the executable's +-@* directory. +-@@ LUA_IGMARK is a mark to ignore all before it when bulding the +-@* luaopen_ function name. +-** CHANGE them if for some reason your system cannot use those +-** characters. (E.g., if one of those characters is a common character +-** in file/directory names.) Probably you do not need to change them. +-*/ +-#define LUA_PATHSEP ";" +-#define LUA_PATH_MARK "?" +-#define LUA_EXECDIR "!" +-#define LUA_IGMARK "-" +- +- +-/* +-@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +-** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +-** machines, ptrdiff_t gives a good choice between int or long.) +-*/ +-#define LUA_INTEGER ptrdiff_t +- +- +-/* +-@@ LUA_API is a mark for all core API functions. +-@@ LUALIB_API is a mark for all standard library functions. +-** CHANGE them if you need to define those functions in some special way. +-** For instance, if you want to create one Windows DLL with the core and +-** the libraries, you may want to use the following definition (define +-** LUA_BUILD_AS_DLL to get it). +-*/ +-#if defined(LUA_BUILD_AS_DLL) +- +-#if defined(LUA_CORE) || defined(LUA_LIB) +-#define LUA_API __declspec(dllexport) +-#else +-#define LUA_API __declspec(dllimport) +-#endif +- +-#else +- +-#define LUA_API extern +- +-#endif +- +-/* more often than not the libs go together with the core */ +-#define LUALIB_API LUA_API +- +- +-/* +-@@ LUAI_FUNC is a mark for all extern functions that are not to be +-@* exported to outside modules. +-@@ LUAI_DATA is a mark for all extern (const) variables that are not to +-@* be exported to outside modules. +-** CHANGE them if you need to mark them in some special way. Elf/gcc +-** (versions 3.2 and later) mark them as "hidden" to optimize access +-** when Lua is compiled as a shared library. +-*/ +-#if defined(luaall_c) +-#define LUAI_FUNC static +-#define LUAI_DATA /* empty */ +- +-#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ +- defined(__ELF__) +-#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +-#define LUAI_DATA LUAI_FUNC +- +-#else +-#define LUAI_FUNC extern +-#define LUAI_DATA extern +-#endif +- +- +- +-/* +-@@ LUA_QL describes how error messages quote program elements. +-** CHANGE it if you want a different appearance. +-*/ +-#define LUA_QL(x) "'" x "'" +-#define LUA_QS LUA_QL("%s") +- +- +-/* +-@@ LUA_IDSIZE gives the maximum size for the description of the source +-@* of a function in debug information. +-** CHANGE it if you want a different size. +-*/ +-#define LUA_IDSIZE 60 +- +- +-/* +-** {================================================================== +-** Stand-alone configuration +-** =================================================================== +-*/ +- +-#if defined(lua_c) || defined(luaall_c) +- +-/* +-@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +-@* is, whether we're running lua interactively). +-** CHANGE it if you have a better definition for non-POSIX/non-Windows +-** systems. +-*/ +-#if defined(LUA_USE_ISATTY) +-#include <unistd.h> +-#define lua_stdin_is_tty() isatty(0) +-#elif defined(LUA_WIN) +-#include <io.h> +-#include <stdio.h> +-#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +-#else +-#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +-#endif +- +- +-/* +-@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +-@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +-** CHANGE them if you want different prompts. (You can also change the +-** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +-*/ +-#define LUA_PROMPT "> " +-#define LUA_PROMPT2 ">> " +- +- +-/* +-@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +-** CHANGE it if your stand-alone interpreter has a different name and +-** your system is not able to detect that name automatically. +-*/ +-#define LUA_PROGNAME "lua" +- +- +-/* +-@@ LUA_MAXINPUT is the maximum length for an input line in the +-@* stand-alone interpreter. +-** CHANGE it if you need longer lines. +-*/ +-#define LUA_MAXINPUT 512 +- +- +-/* +-@@ lua_readline defines how to show a prompt and then read a line from +-@* the standard input. +-@@ lua_saveline defines how to "save" a read line in a "history". +-@@ lua_freeline defines how to free a line read by lua_readline. +-** CHANGE them if you want to improve this functionality (e.g., by using +-** GNU readline and history facilities). +-*/ +-#if defined(LUA_USE_READLINE) +-#include <stdio.h> +-#include <readline/readline.h> +-#include <readline/history.h> +-#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +-#define lua_saveline(L,idx) \ +- if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ +- add_history(lua_tostring(L, idx)); /* add it to history */ +-#define lua_freeline(L,b) ((void)L, free(b)) +-#else +-#define lua_readline(L,b,p) \ +- ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ +- fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +-#define lua_saveline(L,idx) { (void)L; (void)idx; } +-#define lua_freeline(L,b) { (void)L; (void)b; } +-#endif +- +-#endif +- +-/* }================================================================== */ +- +- +-/* +-@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +-@* as a percentage. +-** CHANGE it if you want the GC to run faster or slower (higher values +-** mean larger pauses which mean slower collection.) You can also change +-** this value dynamically. +-*/ +-#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ +- +- +-/* +-@@ LUAI_GCMUL defines the default speed of garbage collection relative to +-@* memory allocation as a percentage. +-** CHANGE it if you want to change the granularity of the garbage +-** collection. (Higher values mean coarser collections. 0 represents +-** infinity, where each step performs a full collection.) You can also +-** change this value dynamically. +-*/ +-#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ +- +- +- +-/* +-@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +-** CHANGE it (define it) if you want exact compatibility with the +-** behavior of setn/getn in Lua 5.0. +-*/ +-#undef LUA_COMPAT_GETN +- +-/* +-@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +-** CHANGE it to undefined as soon as you do not need a global 'loadlib' +-** function (the function is still available as 'package.loadlib'). +-*/ +-#undef LUA_COMPAT_LOADLIB +- +-/* +-@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +-** CHANGE it to undefined as soon as your programs use only '...' to +-** access vararg parameters (instead of the old 'arg' table). +-*/ +-#define LUA_COMPAT_VARARG +- +-/* +-@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +-** CHANGE it to undefined as soon as your programs use 'math.fmod' or +-** the new '%' operator instead of 'math.mod'. +-*/ +-#define LUA_COMPAT_MOD +- +-/* +-@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +-@* facility. +-** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +-** off the advisory error when nesting [[...]]. +-*/ +-#define LUA_COMPAT_LSTR 1 +- +-/* +-@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +-** CHANGE it to undefined as soon as you rename 'string.gfind' to +-** 'string.gmatch'. +-*/ +-#define LUA_COMPAT_GFIND +- +-/* +-@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +-@* behavior. +-** CHANGE it to undefined as soon as you replace to 'luaL_register' +-** your uses of 'luaL_openlib' +-*/ +-#define LUA_COMPAT_OPENLIB +- +- +- +-/* +-@@ luai_apicheck is the assert macro used by the Lua-C API. +-** CHANGE luai_apicheck if you want Lua to perform some checks in the +-** parameters it gets from API calls. This may slow down the interpreter +-** a bit, but may be quite useful when debugging C code that interfaces +-** with Lua. A useful redefinition is to use assert.h. +-*/ +-#if defined(LUA_USE_APICHECK) +-#include <assert.h> +-#define luai_apicheck(L,o) { (void)L; assert(o); } +-#else +-#define luai_apicheck(L,o) { (void)L; } +-#endif +- +- +-/* +-@@ LUAI_BITSINT defines the number of bits in an int. +-** CHANGE here if Lua cannot automatically detect the number of bits of +-** your machine. Probably you do not need to change this. +-*/ +-/* avoid overflows in comparison */ +-#if INT_MAX-20 < 32760 +-#define LUAI_BITSINT 16 +-#elif INT_MAX > 2147483640L +-/* int has at least 32 bits */ +-#define LUAI_BITSINT 32 +-#else +-#error "you must define LUA_BITSINT with number of bits in an integer" +-#endif +- +- +-/* +-@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +-@@ LUAI_INT32 is an signed integer with at least 32 bits. +-@@ LUAI_UMEM is an unsigned integer big enough to count the total +-@* memory used by Lua. +-@@ LUAI_MEM is a signed integer big enough to count the total memory +-@* used by Lua. +-** CHANGE here if for some weird reason the default definitions are not +-** good enough for your machine. (The definitions in the 'else' +-** part always works, but may waste space on machines with 64-bit +-** longs.) Probably you do not need to change this. +-*/ +-#if LUAI_BITSINT >= 32 +-#define LUAI_UINT32 unsigned int +-#define LUAI_INT32 int +-#define LUAI_MAXINT32 INT_MAX +-#define LUAI_UMEM size_t +-#define LUAI_MEM ptrdiff_t +-#else +-/* 16-bit ints */ +-#define LUAI_UINT32 unsigned long +-#define LUAI_INT32 long +-#define LUAI_MAXINT32 LONG_MAX +-#define LUAI_UMEM unsigned long +-#define LUAI_MEM long +-#endif +- +- +-/* +-@@ LUAI_MAXCALLS limits the number of nested calls. +-** CHANGE it if you need really deep recursive calls. This limit is +-** arbitrary; its only purpose is to stop infinite recursion before +-** exhausting memory. +-*/ +-#define LUAI_MAXCALLS 20000 +- +- +-/* +-@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +-@* can use. +-** CHANGE it if you need lots of (Lua) stack space for your C +-** functions. This limit is arbitrary; its only purpose is to stop C +-** functions to consume unlimited stack space. (must be smaller than +-** -LUA_REGISTRYINDEX) +-*/ +-#define LUAI_MAXCSTACK 8000 +- +- +- +-/* +-** {================================================================== +-** CHANGE (to smaller values) the following definitions if your system +-** has a small C stack. (Or you may want to change them to larger +-** values if your system has a large C stack and these limits are +-** too rigid for you.) Some of these constants control the size of +-** stack-allocated arrays used by the compiler or the interpreter, while +-** others limit the maximum number of recursive calls that the compiler +-** or the interpreter can perform. Values too large may cause a C stack +-** overflow for some forms of deep constructs. +-** =================================================================== +-*/ +- +- +-/* +-@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +-@* syntactical nested non-terminals in a program. +-*/ +-#define LUAI_MAXCCALLS 200 +- +- +-/* +-@@ LUAI_MAXVARS is the maximum number of local variables per function +-@* (must be smaller than 250). +-*/ +-#define LUAI_MAXVARS 200 +- +- +-/* +-@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +-@* (must be smaller than 250). +-*/ +-#define LUAI_MAXUPVALUES 60 +- +- +-/* +-@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +-*/ +-#define LUAL_BUFFERSIZE BUFSIZ +- +-/* }================================================================== */ +- +- +- +- +-/* +-** {================================================================== +-@@ LUA_NUMBER is the type of numbers in Lua. +-** CHANGE the following definitions only if you want to build Lua +-** with a number type different from double. You may also need to +-** change lua_number2int & lua_number2integer. +-** =================================================================== +-*/ +- +-#define LUA_NUMBER_DOUBLE +-#define LUA_NUMBER double +- +-/* +-@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +-@* over a number. +-*/ +-#define LUAI_UACNUMBER double +- +- +-/* +-@@ LUA_NUMBER_SCAN is the format for reading numbers. +-@@ LUA_NUMBER_FMT is the format for writing numbers. +-@@ lua_number2str converts a number to a string. +-@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +-@@ lua_str2number converts a string to a number. +-*/ +-#define LUA_NUMBER_SCAN "%lf" +-#define LUA_NUMBER_FMT "%.14g" +-#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +-#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +-#define lua_str2number(s,p) strtod((s), (p)) +- +- +-/* +-@@ The luai_num* macros define the primitive operations over numbers. +-*/ +-#if defined(LUA_CORE) +-#include <math.h> +-#define luai_numadd(a,b) ((a)+(b)) +-#define luai_numsub(a,b) ((a)-(b)) +-#define luai_nummul(a,b) ((a)*(b)) +-#define luai_numdiv(a,b) ((a)/(b)) +-#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +-#define luai_numpow(a,b) (pow(a,b)) +-#define luai_numunm(a) (-(a)) +-#define luai_numeq(a,b) ((a)==(b)) +-#define luai_numlt(a,b) ((a)<(b)) +-#define luai_numle(a,b) ((a)<=(b)) +-#define luai_numisnan(a) (!luai_numeq((a), (a))) +-#endif +- +- +-/* +-@@ lua_number2int is a macro to convert lua_Number to int. +-@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +-** CHANGE them if you know a faster way to convert a lua_Number to +-** int (with any rounding method and without throwing errors) in your +-** system. In Pentium machines, a naive typecast from double to int +-** in C is extremely slow, so any alternative is worth trying. +-*/ +- +-/* On a Pentium, resort to a trick */ +-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ +- (defined(__i386) || defined (_M_IX86) || defined(__i386__)) +- +-/* On a Microsoft compiler, use assembler */ +-#if defined(_MSC_VER) +- +-#define lua_number2int(i,d) __asm fld d __asm fistp i +-#define lua_number2integer(i,n) lua_number2int(i, n) +- +-/* the next trick should work on any Pentium, but sometimes clashes +- with a DirectX idiosyncrasy */ +-#else +- +-union luai_Cast { double l_d; long l_l; }; +-#define lua_number2int(i,d) \ +- { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +-#define lua_number2integer(i,n) lua_number2int(i, n) +- +-#endif +- +- +-/* this option always works, but may be slow */ +-#else +-#define lua_number2int(i,d) ((i)=(int)(d)) +-#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) +- +-#endif +- +-/* }================================================================== */ +- +- +-/* +-@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +-** CHANGE it if your system requires alignments larger than double. (For +-** instance, if your system supports long doubles and they must be +-** aligned in 16-byte boundaries, then you should add long double in the +-** union.) Probably you do not need to change this. +-*/ +-#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } +- +- +-/* +-@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +-** CHANGE them if you prefer to use longjmp/setjmp even with C++ +-** or if want/don't to use _longjmp/_setjmp instead of regular +-** longjmp/setjmp. By default, Lua handles errors with exceptions when +-** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +-** and with longjmp/setjmp otherwise. +-*/ +-#if defined(__cplusplus) +-/* C++ exceptions */ +-#define LUAI_THROW(L,c) throw(c) +-#define LUAI_TRY(L,c,a) try { a } catch(...) \ +- { if ((c)->status == 0) (c)->status = -1; } +-#define luai_jmpbuf int /* dummy variable */ +- +-#elif defined(LUA_USE_ULONGJMP) +-/* in Unix, try _longjmp/_setjmp (more efficient) */ +-#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +-#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +-#define luai_jmpbuf jmp_buf +- +-#else +-/* default handling with long jumps */ +-#define LUAI_THROW(L,c) longjmp((c)->b, 1) +-#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +-#define luai_jmpbuf jmp_buf +- +-#endif +- +- +-/* +-@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +-@* can do during pattern-matching. +-** CHANGE it if you need more captures. This limit is arbitrary. +-*/ +-#define LUA_MAXCAPTURES 32 +- +- +-/* +-@@ lua_tmpnam is the function that the OS library uses to create a +-@* temporary name. +-@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +-** CHANGE them if you have an alternative to tmpnam (which is considered +-** insecure) or if you want the original tmpnam anyway. By default, Lua +-** uses tmpnam except when POSIX is available, where it uses mkstemp. +-*/ +-#if defined(loslib_c) || defined(luaall_c) +- +-#if defined(LUA_USE_MKSTEMP) +-#include <unistd.h> +-#define LUA_TMPNAMBUFSIZE 32 +-#define lua_tmpnam(b,e) { \ +- strcpy(b, "/tmp/lua_XXXXXX"); \ +- e = mkstemp(b); \ +- if (e != -1) close(e); \ +- e = (e == -1); } +- +-#else +-#define LUA_TMPNAMBUFSIZE L_tmpnam +-#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +-#endif +- +-#endif +- +- +-/* +-@@ lua_popen spawns a new process connected to the current one through +-@* the file streams. +-** CHANGE it if you have a way to implement it in your system. +-*/ +-#if defined(LUA_USE_POPEN) +- +-#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +-#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) +- +-#elif defined(LUA_WIN) +- +-#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +-#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) +- +-#else +- +-#define lua_popen(L,c,m) ((void)((void)c, m), \ +- luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +-#define lua_pclose(L,file) ((void)((void)L, file), 0) +- +-#endif +- +-/* +-@@ LUA_DL_* define which dynamic-library system Lua should use. +-** CHANGE here if Lua has problems choosing the appropriate +-** dynamic-library system for your platform (either Windows' DLL, Mac's +-** dyld, or Unix's dlopen). If your system is some kind of Unix, there +-** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +-** it. To use dlopen you also need to adapt the src/Makefile (probably +-** adding -ldl to the linker options), so Lua does not select it +-** automatically. (When you change the makefile to add -ldl, you must +-** also add -DLUA_USE_DLOPEN.) +-** If you do not want any kind of dynamic library, undefine all these +-** options. +-** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +-*/ +-#if defined(LUA_USE_DLOPEN) +-#define LUA_DL_DLOPEN +-#endif +- +-#if defined(LUA_WIN) +-#define LUA_DL_DLL +-#endif +- +- +-/* +-@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +-@* (the data goes just *before* the lua_State pointer). +-** CHANGE (define) this if you really need that. This value must be +-** a multiple of the maximum alignment required for your machine. +-*/ +-#define LUAI_EXTRASPACE 0 +- +- +-/* +-@@ luai_userstate* allow user-specific actions on threads. +-** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +-** extra when a thread is created/deleted/resumed/yielded. +-*/ +-#define luai_userstateopen(L) ((void)L) +-#define luai_userstateclose(L) ((void)L) +-#define luai_userstatethread(L,L1) ((void)L) +-#define luai_userstatefree(L) ((void)L) +-#define luai_userstateresume(L,n) ((void)L) +-#define luai_userstateyield(L,n) ((void)L) +- +- +-/* +-@@ LUA_INTFRMLEN is the length modifier for integer conversions +-@* in 'string.format'. +-@@ LUA_INTFRM_T is the integer type correspoding to the previous length +-@* modifier. +-** CHANGE them if your system supports long long or does not support long. +-*/ +- +-#if defined(LUA_USELONGLONG) +- +-#define LUA_INTFRMLEN "ll" +-#define LUA_INTFRM_T long long +- +-#else +- +-#define LUA_INTFRMLEN "l" +-#define LUA_INTFRM_T long +- +-#endif +- +- +- +-/* =================================================================== */ +- +-/* +-** Local configuration. You can use this space to add your redefinitions +-** without modifying the main part of the file. +-*/ +- +- +- +-#endif +- +diff -urN lua-5.1.4/src/luaconf.h.template.in lua-5.1.4-autotoolize/src/luaconf.h.template.in +--- lua-5.1.4/src/luaconf.h.template.in 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/src/luaconf.h.template.in 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,754 @@ ++/* ++** $Id: luaconf.h,v 1.81 2006/02/10 17:44:06 roberto Exp $ ++** Configuration file for Lua ++** See Copyright Notice in lua.h ++*/ ++ ++ ++#ifndef lconfig_h ++#define lconfig_h ++ ++#include <limits.h> ++#include <stddef.h> ++ ++/* ++** ================= ++** Autotoolification ++** ================= ++*/ ++ ++/** autotools-patch **/ ++@POSIX_DEFS@ ++@LUA_DL_DEFS@ ++@LUA_BUILD_AS_DLL_DEFS@ ++@READLINE_DEFS@ ++/** autotools-patch **/ ++ ++ ++/* ++** ================================================================== ++** Search for "@@" to find all configurable definitions. ++** =================================================================== ++*/ ++ ++ ++/* ++@@ LUA_ANSI controls the use of non-ansi features. ++** CHANGE it (define it) if you want Lua to avoid the use of any ++** non-ansi feature or library. ++*/ ++#if defined(__STRICT_ANSI__) ++#define LUA_ANSI ++#endif ++ ++ ++#if !defined(LUA_ANSI) && defined(_WIN32) ++#define LUA_WIN ++#endif ++ ++ ++/* ++@@ LUA_USE_POSIX includes all functionallity listed as X/Open System ++@* Interfaces Extension (XSI). ++** CHANGE it (define it) if your system is XSI compatible. ++*/ ++#if defined(LUA_USE_POSIX) ++#define LUA_USE_MKSTEMP ++#define LUA_USE_ISATTY ++#define LUA_USE_POPEN ++#define LUA_USE_ULONGJMP ++#endif ++ ++ ++/* ++@@ LUA_PATH and LUA_CPATH are the names of the environment variables that ++@* Lua check to set its paths. ++@@ LUA_INIT is the name of the environment variable that Lua ++@* checks for initialization code. ++** CHANGE them if you want different names. ++*/ ++#define LUA_PATH "LUA_PATH" ++#define LUA_CPATH "LUA_CPATH" ++#define LUA_INIT "LUA_INIT" ++ ++ ++/* ++@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for ++@* Lua libraries. ++@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for ++@* C libraries. ++** CHANGE them if your machine has a non-conventional directory ++** hierarchy or if you want to install your libraries in ++** non-conventional directories. ++*/ ++#if defined(_WIN32) ++/* ++** In Windows, any exclamation mark ('!') in the path is replaced by the ++** path of the directory of the executable file of the current process. ++*/ ++#define LUA_LDIR "!\lua\" ++#define LUA_CDIR "!\" ++#define LUA_PATH_DEFAULT \ ++ ".\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\init.lua;" \ ++ LUA_CDIR"?.lua;" LUA_CDIR"?\init.lua" ++#define LUA_CPATH_DEFAULT \ ++ ".\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" ++ ++#else ++ ++/** autotools-patch **/ ++#define LUA_LDIR "%lua_datadir%/lua/5.1/" ++#if defined __alpha__ || defined __ia64__ || defined __powerpc64__ || \ ++ defined __s390x__ || defined __sparc64__ || defined __x86_64__ ++#define LUA_CDIR "/usr/lib64/lua/5.1/" ++#else ++#define LUA_CDIR "/usr/lib/lua/5.1/" ++#endif ++/** autotools-patch **/ ++ ++#define LUA_PATH_DEFAULT \ ++ "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ ++ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" ++#define LUA_CPATH_DEFAULT \ ++ "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" ++#endif ++ ++ ++/* ++@@ LUA_DIRSEP is the directory separator (for submodules). ++** CHANGE it if your machine does not use "/" as the directory separator ++** and is not Windows. (On Windows Lua automatically uses "".) ++*/ ++#if defined(_WIN32) ++#define LUA_DIRSEP "\" ++#else ++#define LUA_DIRSEP "/" ++#endif ++ ++ ++/* ++@@ LUA_PATHSEP is the character that separates templates in a path. ++@@ LUA_PATH_MARK is the string that marks the substitution points in a ++@* template. ++@@ LUA_EXECDIR in a Windows path is replaced by the executable's ++@* directory. ++@@ LUA_IGMARK is a mark to ignore all before it when bulding the ++@* luaopen_ function name. ++** CHANGE them if for some reason your system cannot use those ++** characters. (E.g., if one of those characters is a common character ++** in file/directory names.) Probably you do not need to change them. ++*/ ++#define LUA_PATHSEP ";" ++#define LUA_PATH_MARK "?" ++#define LUA_EXECDIR "!" ++#define LUA_IGMARK "-" ++ ++ ++/* ++@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. ++** CHANGE that if ptrdiff_t is not adequate on your machine. (On most ++** machines, ptrdiff_t gives a good choice between int or long.) ++*/ ++#define LUA_INTEGER ptrdiff_t ++ ++ ++/* ++@@ LUA_API is a mark for all core API functions. ++@@ LUALIB_API is a mark for all standard library functions. ++** CHANGE them if you need to define those functions in some special way. ++** For instance, if you want to create one Windows DLL with the core and ++** the libraries, you may want to use the following definition (define ++** LUA_BUILD_AS_DLL to get it). ++*/ ++#if defined(LUA_BUILD_AS_DLL) ++ ++#if defined(LUA_CORE) || defined(LUA_LIB) ++#define LUA_API __declspec(dllexport) ++#else ++#define LUA_API __declspec(dllimport) ++#endif ++ ++#else ++ ++#define LUA_API extern ++ ++#endif ++ ++/* more often than not the libs go together with the core */ ++#define LUALIB_API LUA_API ++ ++ ++/* ++@@ LUAI_FUNC is a mark for all extern functions that are not to be ++@* exported to outside modules. ++@@ LUAI_DATA is a mark for all extern (const) variables that are not to ++@* be exported to outside modules. ++** CHANGE them if you need to mark them in some special way. Elf/gcc ++** (versions 3.2 and later) mark them as "hidden" to optimize access ++** when Lua is compiled as a shared library. ++*/ ++#if defined(luaall_c) ++#define LUAI_FUNC static ++#define LUAI_DATA /* empty */ ++ ++#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ ++ defined(__ELF__) ++#define LUAI_FUNC __attribute__((visibility("hidden"))) extern ++#define LUAI_DATA LUAI_FUNC ++ ++#else ++#define LUAI_FUNC extern ++#define LUAI_DATA extern ++#endif ++ ++ ++ ++/* ++@@ LUA_QL describes how error messages quote program elements. ++** CHANGE it if you want a different appearance. ++*/ ++#define LUA_QL(x) "'" x "'" ++#define LUA_QS LUA_QL("%s") ++ ++ ++/* ++@@ LUA_IDSIZE gives the maximum size for the description of the source ++@* of a function in debug information. ++** CHANGE it if you want a different size. ++*/ ++#define LUA_IDSIZE 60 ++ ++ ++/* ++** {================================================================== ++** Stand-alone configuration ++** =================================================================== ++*/ ++ ++#if defined(lua_c) || defined(luaall_c) ++ ++/* ++@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that ++@* is, whether we're running lua interactively). ++** CHANGE it if you have a better definition for non-POSIX/non-Windows ++** systems. ++*/ ++#if defined(LUA_USE_ISATTY) ++#include <unistd.h> ++#define lua_stdin_is_tty() isatty(0) ++#elif defined(LUA_WIN) ++#include <io.h> ++#include <stdio.h> ++#define lua_stdin_is_tty() _isatty(_fileno(stdin)) ++#else ++#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ ++#endif ++ ++ ++/* ++@@ LUA_PROMPT is the default prompt used by stand-alone Lua. ++@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. ++** CHANGE them if you want different prompts. (You can also change the ++** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) ++*/ ++#define LUA_PROMPT "> " ++#define LUA_PROMPT2 ">> " ++ ++ ++/* ++@@ LUA_PROGNAME is the default name for the stand-alone Lua program. ++** CHANGE it if your stand-alone interpreter has a different name and ++** your system is not able to detect that name automatically. ++*/ ++#define LUA_PROGNAME "lua" ++ ++ ++/* ++@@ LUA_MAXINPUT is the maximum length for an input line in the ++@* stand-alone interpreter. ++** CHANGE it if you need longer lines. ++*/ ++#define LUA_MAXINPUT 512 ++ ++ ++/* ++@@ lua_readline defines how to show a prompt and then read a line from ++@* the standard input. ++@@ lua_saveline defines how to "save" a read line in a "history". ++@@ lua_freeline defines how to free a line read by lua_readline. ++** CHANGE them if you want to improve this functionality (e.g., by using ++** GNU readline and history facilities). ++*/ ++#if defined(LUA_USE_READLINE) ++#include <stdio.h> ++#include <readline/readline.h> ++#include <readline/history.h> ++#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) ++#define lua_saveline(L,idx) \ ++ if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ ++ add_history(lua_tostring(L, idx)); /* add it to history */ ++#define lua_freeline(L,b) ((void)L, free(b)) ++#else ++#define lua_readline(L,b,p) \ ++ ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ ++ fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ ++#define lua_saveline(L,idx) { (void)L; (void)idx; } ++#define lua_freeline(L,b) { (void)L; (void)b; } ++#endif ++ ++#endif ++ ++/* }================================================================== */ ++ ++ ++/* ++@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles ++@* as a percentage. ++** CHANGE it if you want the GC to run faster or slower (higher values ++** mean larger pauses which mean slower collection.) You can also change ++** this value dynamically. ++*/ ++#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ ++ ++ ++/* ++@@ LUAI_GCMUL defines the default speed of garbage collection relative to ++@* memory allocation as a percentage. ++** CHANGE it if you want to change the granularity of the garbage ++** collection. (Higher values mean coarser collections. 0 represents ++** infinity, where each step performs a full collection.) You can also ++** change this value dynamically. ++*/ ++#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ ++ ++ ++ ++/* ++@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. ++** CHANGE it (define it) if you want exact compatibility with the ++** behavior of setn/getn in Lua 5.0. ++*/ ++#undef LUA_COMPAT_GETN ++ ++/* ++@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. ++** CHANGE it to undefined as soon as you do not need a global 'loadlib' ++** function (the function is still available as 'package.loadlib'). ++*/ ++#undef LUA_COMPAT_LOADLIB ++ ++/* ++@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. ++** CHANGE it to undefined as soon as your programs use only '...' to ++** access vararg parameters (instead of the old 'arg' table). ++*/ ++#define LUA_COMPAT_VARARG ++ ++/* ++@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. ++** CHANGE it to undefined as soon as your programs use 'math.fmod' or ++** the new '%' operator instead of 'math.mod'. ++*/ ++#define LUA_COMPAT_MOD ++ ++/* ++@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting ++@* facility. ++** CHANGE it to 2 if you want the old behaviour, or undefine it to turn ++** off the advisory error when nesting [[...]]. ++*/ ++#define LUA_COMPAT_LSTR 1 ++ ++/* ++@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. ++** CHANGE it to undefined as soon as you rename 'string.gfind' to ++** 'string.gmatch'. ++*/ ++#define LUA_COMPAT_GFIND ++ ++/* ++@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' ++@* behavior. ++** CHANGE it to undefined as soon as you replace to 'luaL_registry' ++** your uses of 'luaL_openlib' ++*/ ++#define LUA_COMPAT_OPENLIB ++ ++ ++ ++/* ++@@ luai_apicheck is the assert macro used by the Lua-C API. ++** CHANGE luai_apicheck if you want Lua to perform some checks in the ++** parameters it gets from API calls. This may slow down the interpreter ++** a bit, but may be quite useful when debugging C code that interfaces ++** with Lua. A useful redefinition is to use assert.h. ++*/ ++#if defined(LUA_USE_APICHECK) ++#include <assert.h> ++#define luai_apicheck(L,o) { (void)L; assert(o); } ++#else ++#define luai_apicheck(L,o) { (void)L; } ++#endif ++ ++ ++/* ++@@ LUAI_BITSINT defines the number of bits in an int. ++** CHANGE here if Lua cannot automatically detect the number of bits of ++** your machine. Probably you do not need to change this. ++*/ ++/* avoid overflows in comparison */ ++#if INT_MAX-20 < 32760 ++#define LUAI_BITSINT 16 ++#elif INT_MAX > 2147483640L ++/* int has at least 32 bits */ ++#define LUAI_BITSINT 32 ++#else ++#error "you must define LUA_BITSINT with number of bits in an integer" ++#endif ++ ++ ++/* ++@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. ++@@ LUAI_INT32 is an signed integer with at least 32 bits. ++@@ LUAI_UMEM is an unsigned integer big enough to count the total ++@* memory used by Lua. ++@@ LUAI_MEM is a signed integer big enough to count the total memory ++@* used by Lua. ++** CHANGE here if for some weird reason the default definitions are not ++** good enough for your machine. (The definitions in the 'else' ++** part always works, but may waste space on machines with 64-bit ++** longs.) Probably you do not need to change this. ++*/ ++#if LUAI_BITSINT >= 32 ++#define LUAI_UINT32 unsigned int ++#define LUAI_INT32 int ++#define LUAI_MAXINT32 INT_MAX ++#define LUAI_UMEM size_t ++#define LUAI_MEM ptrdiff_t ++#else ++/* 16-bit ints */ ++#define LUAI_UINT32 unsigned long ++#define LUAI_INT32 long ++#define LUAI_MAXINT32 LONG_MAX ++#define LUAI_UMEM unsigned long ++#define LUAI_MEM long ++#endif ++ ++ ++/* ++@@ LUAI_MAXCALLS limits the number of nested calls. ++** CHANGE it if you need really deep recursive calls. This limit is ++** arbitrary; its only purpose is to stop infinite recursion before ++** exhausting memory. ++*/ ++#define LUAI_MAXCALLS 20000 ++ ++ ++/* ++@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function ++@* can use. ++** CHANGE it if you need lots of (Lua) stack space for your C ++** functions. This limit is arbitrary; its only purpose is to stop C ++** functions to consume unlimited stack space. ++*/ ++#define LUAI_MCS_AUX ((int)(INT_MAX / (4*sizeof(LUA_NUMBER)))) ++#define LUAI_MAXCSTACK (LUAI_MCS_AUX > SHRT_MAX ? SHRT_MAX : LUAI_MCS_AUX) ++ ++ ++ ++/* ++** {================================================================== ++** CHANGE (to smaller values) the following definitions if your system ++** has a small C stack. (Or you may want to change them to larger ++** values if your system has a large C stack and these limits are ++** too rigid for you.) Some of these constants control the size of ++** stack-allocated arrays used by the compiler or the interpreter, while ++** others limit the maximum number of recursive calls that the compiler ++** or the interpreter can perform. Values too large may cause a C stack ++** overflow for some forms of deep constructs. ++** =================================================================== ++*/ ++ ++ ++/* ++@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and ++@* syntactical nested non-terminals in a program. ++*/ ++#define LUAI_MAXCCALLS 200 ++ ++ ++/* ++@@ LUAI_MAXVARS is the maximum number of local variables per function ++@* (must be smaller than 250). ++*/ ++#define LUAI_MAXVARS 200 ++ ++ ++/* ++@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function ++@* (must be smaller than 250). ++*/ ++#define LUAI_MAXUPVALUES 60 ++ ++ ++/* ++@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. ++*/ ++#define LUAL_BUFFERSIZE BUFSIZ ++ ++/* }================================================================== */ ++ ++ ++ ++ ++/* ++** {================================================================== ++@@ LUA_NUMBER is the type of numbers in Lua. ++** CHANGE the following definitions only if you want to build Lua ++** with a number type different from double. You may also need to ++** change lua_number2int & lua_number2integer. ++** =================================================================== ++*/ ++ ++#define LUA_NUMBER_DOUBLE ++#define LUA_NUMBER double ++ ++/* ++@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' ++@* over a number. ++*/ ++#define LUAI_UACNUMBER double ++ ++ ++/* ++@@ LUA_NUMBER_SCAN is the format for reading numbers. ++@@ LUA_NUMBER_FMT is the format for writing numbers. ++@@ lua_number2str converts a number to a string. ++@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. ++@@ lua_str2number converts a string to a number. ++*/ ++#define LUA_NUMBER_SCAN "%lf" ++#define LUA_NUMBER_FMT "%.14g" ++#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) ++#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ ++#define lua_str2number(s,p) strtod((s), (p)) ++ ++ ++/* ++@@ The luai_num* macros define the primitive operations over numbers. ++*/ ++#if defined(LUA_CORE) ++#include <math.h> ++#define luai_numadd(a,b) ((a)+(b)) ++#define luai_numsub(a,b) ((a)-(b)) ++#define luai_nummul(a,b) ((a)*(b)) ++#define luai_numdiv(a,b) ((a)/(b)) ++#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) ++#define luai_numpow(a,b) (pow(a,b)) ++#define luai_numunm(a) (-(a)) ++#define luai_numeq(a,b) ((a)==(b)) ++#define luai_numlt(a,b) ((a)<(b)) ++#define luai_numle(a,b) ((a)<=(b)) ++#define luai_numisnan(a) (!luai_numeq((a), (a))) ++#endif ++ ++ ++/* ++@@ lua_number2int is a macro to convert lua_Number to int. ++@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. ++** CHANGE them if you know a faster way to convert a lua_Number to ++** int (with any rounding method and without throwing errors) in your ++** system. In Pentium machines, a naive typecast from double to int ++** in C is extremely slow, so any alternative is worth trying. ++*/ ++ ++/* On a Pentium, resort to a trick */ ++#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ ++ (defined(__i386) || defined (_M_IX86) || defined(__i386__)) ++union luai_Cast { double l_d; long l_l; }; ++#define lua_number2int(i,d) \ ++ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } ++#define lua_number2integer(i,n) lua_number2int(i, n) ++ ++/* this option always works, but may be slow */ ++#else ++#define lua_number2int(i,d) ((i)=(int)(d)) ++#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) ++ ++#endif ++ ++/* }================================================================== */ ++ ++ ++/* ++@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. ++** CHANGE it if your system requires alignments larger than double. (For ++** instance, if your system supports long doubles and they must be ++** aligned in 16-byte boundaries, then you should add long double in the ++** union.) Probably you do not need to change this. ++*/ ++#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } ++ ++ ++/* ++@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. ++** CHANGE them if you prefer to use longjmp/setjmp even with C++ ++** or if want/don't to use _longjmp/_setjmp instead of regular ++** longjmp/setjmp. By default, Lua handles errors with exceptions when ++** compiling as C++ code, with _longjmp/_setjmp when asked to use them, ++** and with longjmp/setjmp otherwise. ++*/ ++#if defined(__cplusplus) ++/* C++ exceptions */ ++#define LUAI_THROW(L,c) throw(c) ++#define LUAI_TRY(L,c,a) try { a } catch(...) \ ++ { if ((c)->status == 0) (c)->status = -1; } ++#define luai_jmpbuf int /* dummy variable */ ++ ++#elif defined(LUA_USE_ULONGJMP) ++/* in Unix, try _longjmp/_setjmp (more efficient) */ ++#define LUAI_THROW(L,c) _longjmp((c)->b, 1) ++#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } ++#define luai_jmpbuf jmp_buf ++ ++#else ++/* default handling with long jumps */ ++#define LUAI_THROW(L,c) longjmp((c)->b, 1) ++#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } ++#define luai_jmpbuf jmp_buf ++ ++#endif ++ ++ ++/* ++@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern ++@* can do during pattern-matching. ++** CHANGE it if you need more captures. This limit is arbitrary. ++*/ ++#define LUA_MAXCAPTURES 32 ++ ++ ++/* ++@@ lua_tmpnam is the function that the OS library uses to create a ++@* temporary name. ++@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. ++** CHANGE them if you have an alternative to tmpnam (which is considered ++** insecure) or if you want the original tmpnam anyway. By default, Lua ++** uses tmpnam except when POSIX is available, where it uses mkstemp. ++*/ ++#if defined(loslib_c) || defined(luaall_c) ++ ++#if defined(LUA_USE_MKSTEMP) ++#include <unistd.h> ++#define LUA_TMPNAMBUFSIZE 32 ++#define lua_tmpnam(b,e) { \ ++ strcpy(b, "/tmp/lua_XXXXXX"); \ ++ e = mkstemp(b); \ ++ if (e != -1) close(e); \ ++ e = (e == -1); } ++ ++#else ++#define LUA_TMPNAMBUFSIZE L_tmpnam ++#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } ++#endif ++ ++#endif ++ ++ ++/* ++@@ lua_popen spawns a new process connected to the current one through ++@* the file streams. ++** CHANGE it if you have a way to implement it in your system. ++*/ ++#if defined(LUA_USE_POPEN) ++ ++#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) ++#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) ++ ++#elif defined(LUA_WIN) ++ ++#define lua_popen(L,c,m) ((void)L, _popen(c,m)) ++#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) ++ ++#else ++ ++#define lua_popen(L,c,m) ((void)((void)c, m), \ ++ luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) ++#define lua_pclose(L,file) ((void)((void)L, file), 0) ++ ++#endif ++ ++/* ++@@ LUA_DL_* define which dynamic-library system Lua should use. ++** CHANGE here if Lua has problems choosing the appropriate ++** dynamic-library system for your platform (either Windows' DLL, Mac's ++** dyld, or Unix's dlopen). If your system is some kind of Unix, there ++** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for ++** it. To use dlopen you also need to adapt the src/Makefile (probably ++** adding -ldl to the linker options), so Lua does not select it ++** automatically. (When you change the makefile to add -ldl, you must ++** also add -DLUA_USE_DLOPEN.) ++** If you do not want any kind of dynamic library, undefine all these ++** options. ++** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. ++*/ ++#if defined(LUA_WIN) ++#define LUA_DL_DLL ++#endif ++ ++ ++/* ++@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State ++@* (the data goes just *before* the lua_State pointer). ++** CHANGE (define) this if you really need that. This value must be ++** a multiple of the maximum alignment required for your machine. ++*/ ++#define LUAI_EXTRASPACE 0 ++ ++ ++/* ++@@ luai_userstate* allow user-specific actions on threads. ++** CHANGE them if you defined LUAI_EXTRASPACE and need to do something ++** extra when a thread is created/deleted/resumed/yielded. ++*/ ++#define luai_userstateopen(L) ((void)L) ++#define luai_userstateclose(L) ((void)L) ++#define luai_userstatethread(L,L1) ((void)L) ++#define luai_userstatefree(L) ((void)L) ++#define luai_userstateresume(L,n) ((void)L) ++#define luai_userstateyield(L,n) ((void)L) ++ ++ ++/* ++@@ LUA_INTFRMLEN is the length modifier for integer conversions ++@* in 'string.format'. ++@@ LUA_INTFRM_T is the integer type correspoding to the previous length ++@* modifier. ++** CHANGE them if your system supports long long or does not support long. ++*/ ++ ++#if defined(LUA_USELONGLONG) ++ ++#define LUA_INTFRMLEN "ll" ++#define LUA_INTFRM_T long long ++ ++#else ++ ++#define LUA_INTFRMLEN "l" ++#define LUA_INTFRM_T long ++ ++#endif ++ ++ ++ ++/* =================================================================== */ ++ ++/* ++** Local configuration. You can use this space to add your redefinitions ++** without modifying the main part of the file. ++*/ ++ ++ ++ ++#endif ++ +diff -urN lua-5.1.4/src/Makefile lua-5.1.4-autotoolize/src/Makefile +--- lua-5.1.4/src/Makefile 2008-01-19 20:37:58.000000000 +0100 ++++ lua-5.1.4-autotoolize/src/Makefile 2008-09-03 13:18:32.000000000 +0200 +@@ -1,182 +0,0 @@ +-# makefile for building Lua +-# see ../INSTALL for installation instructions +-# see ../Makefile and luaconf.h for further customization +- +-# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= +- +-# Your platform. See PLATS for possible values. +-PLAT= none +- +-CC= gcc +-CFLAGS= -O2 -Wall $(MYCFLAGS) +-AR= ar rcu +-RANLIB= ranlib +-RM= rm -f +-LIBS= -lm $(MYLIBS) +- +-MYCFLAGS= +-MYLDFLAGS= +-MYLIBS= +- +-# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= +- +-PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris +- +-LUA_A= liblua.a +-CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ +- lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ +- lundump.o lvm.o lzio.o +-LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ +- lstrlib.o loadlib.o linit.o +- +-LUA_T= lua +-LUA_O= lua.o +- +-LUAC_T= luac +-LUAC_O= luac.o print.o +- +-ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) +-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +-ALL_A= $(LUA_A) +- +-default: $(PLAT) +- +-all: $(ALL_T) +- +-o: $(ALL_O) +- +-a: $(ALL_A) +- +-$(LUA_A): $(CORE_O) $(LIB_O) +- $(AR) $@ $? +- $(RANLIB) $@ +- +-$(LUA_T): $(LUA_O) $(LUA_A) +- $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) +- +-$(LUAC_T): $(LUAC_O) $(LUA_A) +- $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) +- +-clean: +- $(RM) $(ALL_T) $(ALL_O) +- +-depend: +- @$(CC) $(CFLAGS) -MM l*.c print.c +- +-echo: +- @echo "PLAT = $(PLAT)" +- @echo "CC = $(CC)" +- @echo "CFLAGS = $(CFLAGS)" +- @echo "AR = $(AR)" +- @echo "RANLIB = $(RANLIB)" +- @echo "RM = $(RM)" +- @echo "MYCFLAGS = $(MYCFLAGS)" +- @echo "MYLDFLAGS = $(MYLDFLAGS)" +- @echo "MYLIBS = $(MYLIBS)" +- +-# convenience targets for popular platforms +- +-none: +- @echo "Please choose a platform:" +- @echo " $(PLATS)" +- +-aix: +- $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" +- +-ansi: +- $(MAKE) all MYCFLAGS=-DLUA_ANSI +- +-bsd: +- $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" +- +-freebsd: +- $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" +- +-generic: +- $(MAKE) all MYCFLAGS= +- +-linux: +- $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" +- +-macosx: +- $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" +-# use this on Mac OS X 10.3- +-# $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX +- +-mingw: +- $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ +- "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ +- "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe +- $(MAKE) "LUAC_T=luac.exe" luac.exe +- +-posix: +- $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX +- +-solaris: +- $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" +- +-# list targets that do not create files (but not all makes understand .PHONY) +-.PHONY: all $(PLATS) default o a clean depend echo none +- +-# DO NOT DELETE +- +-lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \ +- lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \ +- lundump.h lvm.h +-lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h +-lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h +-lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ +- lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ +- ltable.h +-ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h +-ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \ +- llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ +- lfunc.h lstring.h lgc.h ltable.h lvm.h +-ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ +- lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h \ +- ltable.h lundump.h lvm.h +-ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ +- lzio.h lmem.h lundump.h +-lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ +- lstate.h ltm.h lzio.h +-lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ +- lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h +-linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h +-liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h +-llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ +- lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h +-lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h +-lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ +- ltm.h lzio.h lmem.h ldo.h +-loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h +-lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ +- ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h +-lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h +-loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h +-lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ +- lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ +- lfunc.h lstring.h lgc.h ltable.h +-lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ +- ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h +-lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ +- ltm.h lzio.h lstring.h lgc.h +-lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h +-ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ +- ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h +-ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h +-ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ +- lmem.h lstring.h lgc.h ltable.h +-lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h +-luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ +- lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \ +- lundump.h +-lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ +- llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h +-lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ +- lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h +-lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ +- lzio.h +-print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ +- ltm.h lzio.h lmem.h lopcodes.h lundump.h +- +-# (end of Makefile) +diff -urN lua-5.1.4/src/Makefile.am lua-5.1.4-autotoolize/src/Makefile.am +--- lua-5.1.4/src/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/src/Makefile.am 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,45 @@ ++AM_CFLAGS = -Wall ++ ++include_HEADERS = lua.h lualib.h lauxlib.h ++nodist_include_HEADERS = luaconf.h ++ ++lib_LTLIBRARIES = liblua.la ++liblua_la_LDFLAGS = -release 5.1 ++liblua_la_SOURCES = \ ++ lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c \ ++ lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c \ ++ lundump.c lvm.c lzio.c \ ++ lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c ltablib.c \ ++ lstrlib.c loadlib.c linit.c \ ++ lapi.h ldebug.h lgc.h lmem.h lparser.h ltable.h lzio.h ldo.h llex.h \ ++ lobject.h lstate.h ltm.h lundump.h lcode.h lfunc.h llimits.h lopcodes.h \ ++ lstring.h lvm.h ++ ++bin_PROGRAMS = lua luac ++ ++lua_SOURCES = lua.c ++lua_LDADD = liblua.la @LUA_LIBS@ ++lua_DEPENDENCIES = liblua.la ++ ++luac_SOURCES = luac.c print.c ++luac_LDADD = liblua.la @LUA_LIBS@ ++luac_DEPENDENCIES = liblua.la ++ ++# luac must be linked statically because it uses functions that ++# don't get exported to the shared object ++luac_LDFLAGS = -static ++ ++EXTRA_DIST = luaconf.h.template.in ++BUILT_SOURCES = luaconf.h ++CLEANFILES = luaconf.h ++ ++readline_defs = @READLINE_DEFS@ ++ ++edit = sed \ ++ -e 's,%lua_datadir%,$(datadir),g' \ ++ -e 's,%lua_libdir%,$(libdir),g' ++ ++luaconf.h : $(srcdir)/luaconf.h.template ++ rm -f luaconf.h luaconf.h.tmp ++ $(edit) $(srcdir)/luaconf.h.template > luaconf.h.tmp ++ mv luaconf.h.tmp luaconf.h +diff -urN lua-5.1.4/src/Makefile.in lua-5.1.4-autotoolize/src/Makefile.in +--- lua-5.1.4/src/Makefile.in 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/src/Makefile.in 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,621 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++ ++ ++ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = .. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++bin_PROGRAMS = lua$(EXEEXT) luac$(EXEEXT) ++subdir = src ++DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ ++ $(srcdir)/Makefile.in $(srcdir)/luaconf.h.template.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = luaconf.h.template ++am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; ++am__vpath_adj = case $$p in \ ++ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ ++ *) f=$$p;; \ ++ esac; ++am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; ++am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ ++ "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)" ++libLTLIBRARIES_INSTALL = $(INSTALL) ++LTLIBRARIES = $(lib_LTLIBRARIES) ++liblua_la_LIBADD = ++am_liblua_la_OBJECTS = lapi.lo lcode.lo ldebug.lo ldo.lo ldump.lo \ ++ lfunc.lo lgc.lo llex.lo lmem.lo lobject.lo lopcodes.lo \ ++ lparser.lo lstate.lo lstring.lo ltable.lo ltm.lo lundump.lo \ ++ lvm.lo lzio.lo lauxlib.lo lbaselib.lo ldblib.lo liolib.lo \ ++ lmathlib.lo loslib.lo ltablib.lo lstrlib.lo loadlib.lo \ ++ linit.lo ++liblua_la_OBJECTS = $(am_liblua_la_OBJECTS) ++binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) ++PROGRAMS = $(bin_PROGRAMS) ++am_lua_OBJECTS = lua.$(OBJEXT) ++lua_OBJECTS = $(am_lua_OBJECTS) ++am_luac_OBJECTS = luac.$(OBJEXT) print.$(OBJEXT) ++luac_OBJECTS = $(am_luac_OBJECTS) ++DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) ++depcomp = $(SHELL) $(top_srcdir)/depcomp ++am__depfiles_maybe = depfiles ++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ ++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) ++LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ ++ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ ++ $(AM_CFLAGS) $(CFLAGS) ++CCLD = $(CC) ++LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ ++ $(AM_LDFLAGS) $(LDFLAGS) -o $@ ++SOURCES = $(liblua_la_SOURCES) $(lua_SOURCES) $(luac_SOURCES) ++DIST_SOURCES = $(liblua_la_SOURCES) $(lua_SOURCES) $(luac_SOURCES) ++includeHEADERS_INSTALL = $(INSTALL_HEADER) ++nodist_includeHEADERS_INSTALL = $(INSTALL_HEADER) ++HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) ++ETAGS = etags ++CTAGS = ctags ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++LUA_BUILD_AS_DLL_DEFS = @LUA_BUILD_AS_DLL_DEFS@ ++LUA_DL_DEFS = @LUA_DL_DEFS@ ++LUA_LIBS = @LUA_LIBS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++POSIX_DEFS = @POSIX_DEFS@ ++RANLIB = @RANLIB@ ++READLINE_DEFS = @READLINE_DEFS@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++AM_CFLAGS = -Wall ++include_HEADERS = lua.h lualib.h lauxlib.h ++nodist_include_HEADERS = luaconf.h ++lib_LTLIBRARIES = liblua.la ++liblua_la_LDFLAGS = -release 5.1 ++liblua_la_SOURCES = \ ++ lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c \ ++ lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c \ ++ lundump.c lvm.c lzio.c \ ++ lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c ltablib.c \ ++ lstrlib.c loadlib.c linit.c \ ++ lapi.h ldebug.h lgc.h lmem.h lparser.h ltable.h lzio.h ldo.h llex.h \ ++ lobject.h lstate.h ltm.h lundump.h lcode.h lfunc.h llimits.h lopcodes.h \ ++ lstring.h lvm.h ++ ++lua_SOURCES = lua.c ++lua_LDADD = liblua.la @LUA_LIBS@ ++lua_DEPENDENCIES = liblua.la ++luac_SOURCES = luac.c print.c ++luac_LDADD = liblua.la @LUA_LIBS@ ++luac_DEPENDENCIES = liblua.la ++ ++# luac must be linked statically because it uses functions that ++# don't get exported to the shared object ++luac_LDFLAGS = -static ++EXTRA_DIST = luaconf.h.template.in ++BUILT_SOURCES = luaconf.h ++CLEANFILES = luaconf.h ++readline_defs = @READLINE_DEFS@ ++edit = sed \ ++ -e 's,%lua_datadir%,$(datadir),g' \ ++ -e 's,%lua_libdir%,$(libdir),g' ++ ++all: $(BUILT_SOURCES) ++ $(MAKE) $(AM_MAKEFLAGS) all-am ++ ++.SUFFIXES: ++.SUFFIXES: .c .lo .o .obj ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --foreign src/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++luaconf.h.template: $(top_builddir)/config.status $(srcdir)/luaconf.h.template.in ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ ++install-libLTLIBRARIES: $(lib_LTLIBRARIES) ++ @$(NORMAL_INSTALL) ++ test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" ++ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ ++ if test -f $$p; then \ ++ f=$(am__strip_dir) \ ++ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ ++ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ ++ else :; fi; \ ++ done ++ ++uninstall-libLTLIBRARIES: ++ @$(NORMAL_UNINSTALL) ++ @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ ++ p=$(am__strip_dir) \ ++ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ ++ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ ++ done ++ ++clean-libLTLIBRARIES: ++ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) ++ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ ++ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ ++ test "$$dir" != "$$p" || dir=.; \ ++ echo "rm -f "$${dir}/so_locations""; \ ++ rm -f "$${dir}/so_locations"; \ ++ done ++liblua.la: $(liblua_la_OBJECTS) $(liblua_la_DEPENDENCIES) ++ $(LINK) -rpath $(libdir) $(liblua_la_LDFLAGS) $(liblua_la_OBJECTS) $(liblua_la_LIBADD) $(LIBS) ++install-binPROGRAMS: $(bin_PROGRAMS) ++ @$(NORMAL_INSTALL) ++ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" ++ @list='$(bin_PROGRAMS)'; for p in $$list; do \ ++ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ ++ if test -f $$p \ ++ || test -f $$p1 \ ++ ; then \ ++ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ ++ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ ++ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ ++ else :; fi; \ ++ done ++ ++uninstall-binPROGRAMS: ++ @$(NORMAL_UNINSTALL) ++ @list='$(bin_PROGRAMS)'; for p in $$list; do \ ++ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ ++ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ ++ rm -f "$(DESTDIR)$(bindir)/$$f"; \ ++ done ++ ++clean-binPROGRAMS: ++ @list='$(bin_PROGRAMS)'; for p in $$list; do \ ++ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ ++ echo " rm -f $$p $$f"; \ ++ rm -f $$p $$f ; \ ++ done ++lua$(EXEEXT): $(lua_OBJECTS) $(lua_DEPENDENCIES) ++ @rm -f lua$(EXEEXT) ++ $(LINK) $(lua_LDFLAGS) $(lua_OBJECTS) $(lua_LDADD) $(LIBS) ++luac$(EXEEXT): $(luac_OBJECTS) $(luac_DEPENDENCIES) ++ @rm -f luac$(EXEEXT) ++ $(LINK) $(luac_LDFLAGS) $(luac_OBJECTS) $(luac_LDADD) $(LIBS) ++ ++mostlyclean-compile: ++ -rm -f *.$(OBJEXT) ++ ++distclean-compile: ++ -rm -f *.tab.c ++ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lapi.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lauxlib.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lbaselib.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lcode.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldblib.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldebug.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldo.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldump.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lfunc.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lgc.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linit.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liolib.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/llex.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmathlib.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmem.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loadlib.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lobject.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lopcodes.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loslib.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lparser.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstate.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstring.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstrlib.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ltable.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ltablib.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ltm.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lua.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/luac.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lundump.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lvm.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzio.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Po@am__quote@ ++ ++.c.o: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c $< ++ ++.c.obj: ++@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` ++ ++.c.lo: ++@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ ++@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ ++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ ++@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++install-includeHEADERS: $(include_HEADERS) ++ @$(NORMAL_INSTALL) ++ test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" ++ @list='$(include_HEADERS)'; for p in $$list; do \ ++ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ ++ f=$(am__strip_dir) \ ++ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ ++ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ ++ done ++ ++uninstall-includeHEADERS: ++ @$(NORMAL_UNINSTALL) ++ @list='$(include_HEADERS)'; for p in $$list; do \ ++ f=$(am__strip_dir) \ ++ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ ++ rm -f "$(DESTDIR)$(includedir)/$$f"; \ ++ done ++install-nodist_includeHEADERS: $(nodist_include_HEADERS) ++ @$(NORMAL_INSTALL) ++ test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" ++ @list='$(nodist_include_HEADERS)'; for p in $$list; do \ ++ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ ++ f=$(am__strip_dir) \ ++ echo " $(nodist_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ ++ $(nodist_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ ++ done ++ ++uninstall-nodist_includeHEADERS: ++ @$(NORMAL_UNINSTALL) ++ @list='$(nodist_include_HEADERS)'; for p in $$list; do \ ++ f=$(am__strip_dir) \ ++ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ ++ rm -f "$(DESTDIR)$(includedir)/$$f"; \ ++ done ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$tags $$unique; \ ++ fi ++ctags: CTAGS ++CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ tags=; \ ++ here=`pwd`; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) ' { files[$$0] = 1; } \ ++ END { for (i in files) print i; }'`; \ ++ test -z "$(CTAGS_ARGS)$$tags$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$tags $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && cd $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) $$here ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: $(BUILT_SOURCES) ++ $(MAKE) $(AM_MAKEFLAGS) check-am ++all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) ++install-binPROGRAMS: install-libLTLIBRARIES ++ ++installdirs: ++ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ ++ test -z "$$dir" || $(mkdir_p) "$$dir"; \ ++ done ++install: $(BUILT_SOURCES) ++ $(MAKE) $(AM_MAKEFLAGS) install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) ++clean: clean-am ++ ++clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ ++ clean-libtool mostlyclean-am ++ ++distclean: distclean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++distclean-am: clean-am distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: install-includeHEADERS install-nodist_includeHEADERS ++ ++install-exec-am: install-binPROGRAMS install-libLTLIBRARIES ++ ++install-info: install-info-am ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -rf ./$(DEPDIR) ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-compile mostlyclean-generic \ ++ mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ ++ uninstall-info-am uninstall-libLTLIBRARIES \ ++ uninstall-nodist_includeHEADERS ++ ++.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ ++ clean-generic clean-libLTLIBRARIES clean-libtool ctags \ ++ distclean distclean-compile distclean-generic \ ++ distclean-libtool distclean-tags distdir dvi dvi-am html \ ++ html-am info info-am install install-am install-binPROGRAMS \ ++ install-data install-data-am install-exec install-exec-am \ ++ install-includeHEADERS install-info install-info-am \ ++ install-libLTLIBRARIES install-man \ ++ install-nodist_includeHEADERS install-strip installcheck \ ++ installcheck-am installdirs maintainer-clean \ ++ maintainer-clean-generic mostlyclean mostlyclean-compile \ ++ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ ++ tags uninstall uninstall-am uninstall-binPROGRAMS \ ++ uninstall-includeHEADERS uninstall-info-am \ ++ uninstall-libLTLIBRARIES uninstall-nodist_includeHEADERS ++ ++ ++luaconf.h : $(srcdir)/luaconf.h.template ++ rm -f luaconf.h luaconf.h.tmp ++ $(edit) $(srcdir)/luaconf.h.template > luaconf.h.tmp ++ mv luaconf.h.tmp luaconf.h ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff -urN lua-5.1.4/test/Makefile.am lua-5.1.4-autotoolize/test/Makefile.am +--- lua-5.1.4/test/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/test/Makefile.am 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,5 @@ ++EXTRA_DIST = \ ++ bisect.lua env.lua fib.lua life.lua printf.lua \ ++ sieve.lua trace-calls.lua cf.lua factorial.lua globals.lua \ ++ luac.lua README sort.lua trace-globals.lua echo.lua \ ++ fibfor.lua hello.lua readonly.lua table.lua xd.lua +diff -urN lua-5.1.4/test/Makefile.in lua-5.1.4-autotoolize/test/Makefile.in +--- lua-5.1.4/test/Makefile.in 1970-01-01 01:00:00.000000000 +0100 ++++ lua-5.1.4-autotoolize/test/Makefile.in 2008-09-03 13:18:37.000000000 +0200 +@@ -0,0 +1,319 @@ ++# Makefile.in generated by automake 1.9.6 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005 Free Software Foundation, Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++top_builddir = .. ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++INSTALL = @INSTALL@ ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = test ++DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++SOURCES = ++DIST_SOURCES = ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMDEP_FALSE = @AMDEP_FALSE@ ++AMDEP_TRUE = @AMDEP_TRUE@ ++AMTAR = @AMTAR@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH_W = @CYGPATH_W@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++ECHO = @ECHO@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++F77 = @F77@ ++FFLAGS = @FFLAGS@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++LDFLAGS = @LDFLAGS@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++LUA_BUILD_AS_DLL_DEFS = @LUA_BUILD_AS_DLL_DEFS@ ++LUA_DL_DEFS = @LUA_DL_DEFS@ ++LUA_LIBS = @LUA_LIBS@ ++MAKEINFO = @MAKEINFO@ ++OBJEXT = @OBJEXT@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++POSIX_DEFS = @POSIX_DEFS@ ++RANLIB = @RANLIB@ ++READLINE_DEFS = @READLINE_DEFS@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++STRIP = @STRIP@ ++VERSION = @VERSION@ ++ac_ct_AR = @ac_ct_AR@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_F77 = @ac_ct_F77@ ++ac_ct_RANLIB = @ac_ct_RANLIB@ ++ac_ct_STRIP = @ac_ct_STRIP@ ++am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ ++am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ ++am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ ++am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++datadir = @datadir@ ++exec_prefix = @exec_prefix@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++localstatedir = @localstatedir@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++prefix = @prefix@ ++program_transform_name = @program_transform_name@ ++sbindir = @sbindir@ ++sharedstatedir = @sharedstatedir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++EXTRA_DIST = \ ++ bisect.lua env.lua fib.lua life.lua printf.lua \ ++ sieve.lua trace-calls.lua cf.lua factorial.lua globals.lua \ ++ luac.lua README sort.lua trace-globals.lua echo.lua \ ++ fibfor.lua hello.lua readonly.lua table.lua xd.lua ++ ++all: all-am ++ ++.SUFFIXES: ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ ++ && exit 0; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \ ++ cd $(top_srcdir) && \ ++ $(AUTOMAKE) --foreign test/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++distclean-libtool: ++ -rm -f libtool ++uninstall-info-am: ++tags: TAGS ++TAGS: ++ ++ctags: CTAGS ++CTAGS: ++ ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ ++ list='$(DISTFILES)'; for file in $$list; do \ ++ case $$file in \ ++ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ ++ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ ++ esac; \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test "$$dir" != "$$file" && test "$$dir" != "."; then \ ++ dir="/$$dir"; \ ++ $(mkdir_p) "$(distdir)$$dir"; \ ++ else \ ++ dir=''; \ ++ fi; \ ++ if test -d $$d/$$file; then \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ ++ fi; \ ++ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ ++ else \ ++ test -f $(distdir)/$$file \ ++ || cp -p $$d/$$file $(distdir)/$$file \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-am ++all-am: Makefile ++installdirs: ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool mostlyclean-am ++ ++distclean: distclean-am ++ -rm -f Makefile ++distclean-am: clean-am distclean-generic distclean-libtool ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: ++ ++install-exec-am: ++ ++install-info: install-info-am ++ ++install-man: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-generic mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: uninstall-info-am ++ ++.PHONY: all all-am check check-am clean clean-generic clean-libtool \ ++ distclean distclean-generic distclean-libtool distdir dvi \ ++ dvi-am html html-am info info-am install install-am \ ++ install-data install-data-am install-exec install-exec-am \ ++ install-info install-info-am install-man install-strip \ ++ installcheck installcheck-am installdirs maintainer-clean \ ++ maintainer-clean-generic mostlyclean mostlyclean-generic \ ++ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ ++ uninstall-info-am ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: diff --git a/pkgs/core/lvm2/lvm2.nm b/pkgs/core/lvm2/lvm2.nm new file mode 100644 index 0000000..578eaeb --- /dev/null +++ b/pkgs/core/lvm2/lvm2.nm @@ -0,0 +1,65 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = LVM2 +PKG_VER = 2.02.54 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://sources.redhat.com/lvm2/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = Userland logical volume management tools. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += module-init-tools ncurses readline + +define PKG_DESCRIPTION + LVM2 includes all of the support for handling read/write operations on \ + physical volumes (hard disks, RAID-Systems, magneto optical, etc., \ + multiple devices (MD), see mdadd(8) or even loop devices, see \ + losetup(8)), creating volume groups (kind of virtual disks) from one \ + or more physical volumes and creating one or more logical volumes \ + (kind of logical partitions) in volume groups. +endef + +PKG_TARBALL = $(THISAPP).tgz + +THISAPP = $(PKG_NAME).$(PKG_VER) + +CONFIGURE_OPTIONS += \ + --bindir=/bin \ + --sbindir=/sbin \ + --exec-prefix=/ \ + --libdir=/lib \ + --enable-pkgconfig + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/usr/lib + rm -vf $(BUILDROOT)/lib/libdevmapper.so + ln -svf libdevmapper.so.1.02 $(BUILDROOT)/lib/libdevmapper.so.1 + ln -svf ../../lib/libdevmapper.so.1 $(BUILDROOT)/usr/lib/libdevmapper.so +endef diff --git a/pkgs/core/lzo/lzo.nm b/pkgs/core/lzo/lzo.nm new file mode 100644 index 0000000..2d6e082 --- /dev/null +++ b/pkgs/core/lzo/lzo.nm @@ -0,0 +1,49 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = lzo +PKG_VER = 2.03 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Compression +PKG_URL = http://www.oberhumer.com/opensource/lzo/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Data compression library with very fast (de)compression. + +PKG_DEPS += zlib + +define PKG_DESCRIPTION + LZO is a portable lossless data compression library written in ANSI C. \ + It offers pretty fast compression and very fast decompression. \ + Decompression requires no memory. In addition there are slower \ + compression levels achieving a quite competitive compression ratio \ + while still decompressing at this very high speed. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += --disable-static --enable-shared diff --git a/pkgs/core/m4/m4.nm b/pkgs/core/m4/m4.nm new file mode 100644 index 0000000..0f1d59e --- /dev/null +++ b/pkgs/core/m4/m4.nm @@ -0,0 +1,67 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = m4 +PKG_VER = 1.4.11 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/Text +PKG_URL = http://www.gnu.org/software/m4/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = The GNU macro processor. + +define PKG_DESCRIPTION + A GNU implementation of the traditional UNIX macro processor. M4 is \ + useful for writing text files which can be logically parsed, and is \ + used by many programs as part of their build process. M4 has \ + built-in functions for including files, running shell commands, \ + doing arithmetic, etc. The autoconf program needs m4 for generating \ + configure scripts, but not for running configure scripts. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + # We need -D_GNU_SOURCE because this version of M4 has a bug in gnulib (or + # possibly autoconf) that doesn't recognise that we have asprintf() in libc. + cd $(DIR_APP) && \ + CPPFLAGS="-D_GNU_SOURCE" \ + gl_cv_func_printf_directive_n=no \ + ./configure \ + --prefix=/usr + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +# fails +#define STAGE_TEST +# cd $(DIR_APP) && make check +#endef diff --git a/pkgs/core/make/make.nm b/pkgs/core/make/make.nm new file mode 100644 index 0000000..ae13c72 --- /dev/null +++ b/pkgs/core/make/make.nm @@ -0,0 +1,54 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = make +PKG_VER = 3.81 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/make/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A GNU tool which simplifies the build process for users. + +define PKG_DESCRIPTION + A GNU tool for controlling the generation of executables and other \ + non-source files of a program from the program's source files. Make \ + allows users to build and install packages without any significant \ + knowledge about the details of the build process. The details about \ + how the program should be built are provided for make in the program's \ + makefile. +endef + +PKG_BUILD_DEPS:= $(filter-out make,$(PKG_BUILD_DEPS)) + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += --mandir=/usr/share + +define STAGE_TEST + cd $(DIR_APP) && make check +endef diff --git a/pkgs/core/man-db/man-db.nm b/pkgs/core/man-db/man-db.nm new file mode 100644 index 0000000..ef54f25 --- /dev/null +++ b/pkgs/core/man-db/man-db.nm @@ -0,0 +1,64 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = man-db +PKG_VER = 2.5.6 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Documentation +PKG_URL = http://bzr.savannah.gnu.org/r/man-db/ +PKG_LICENSE = GPL +PKG_SUMMARY = man-db is an on-line manual database. + +PKG_DEPS += db groff + +define PKG_DESCRIPTION + man-db is an implementation of the standard Unix documentation \ + system accessed using the man command. It uses a Berkeley DB database \ + in place of the traditional flat-text whatis databases. man-db is \ + used by several popular GNU/Linux distributions. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --libexecdir=/usr/lib \ + --sysconfdir=/etc \ + --disable-setuid \ + --with-browser=/usr/bin/lynx \ + --with-col=/usr/bin/col \ + --with-vgrind=/usr/bin/vgrind \ + --with-grap=/usr/bin/grap + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -i -e '%\t/usr/man%d' -e '%\t/usr/local/man%d' \ + src/man_db.conf.in +endef diff --git a/pkgs/core/man-pages/man-pages.nm b/pkgs/core/man-pages/man-pages.nm new file mode 100644 index 0000000..c0ad3a6 --- /dev/null +++ b/pkgs/core/man-pages/man-pages.nm @@ -0,0 +1,46 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = man-pages +PKG_VER = 3.23 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Documentation +PKG_URL = http://www.kernel.org/pub/linux/docs/manpages/ +PKG_LICENSE = GPLv2+ and GPL+ and BSD and MIT and Copyright only and IEEE +PKG_SUMMARY = Man (manual) pages from the Linux Documentation Project. + +PKG_DEPS += man-db + +define PKG_DESCRIPTION + A large collection of man pages (documentation) from the Linux \ + Documentation Project (LDP). +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +STAGE_BUILD = # Do nothing diff --git a/pkgs/core/mc/mc.nm b/pkgs/core/mc/mc.nm new file mode 100644 index 0000000..4672a09 --- /dev/null +++ b/pkgs/core/mc/mc.nm @@ -0,0 +1,60 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = mc +PKG_VER = 4.6.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/System +PKG_URL = http://www.ibiblio.org/mc/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = User-friendly text console file manager and visual shell. + +PKG_BUILD_DEPS+= autoconf automake +PKG_DEPS += e2fsprogs glib2 samba slang + +define PKG_DESCRIPTION + Midnight Commander is a visual shell much like a file manager, only \ + with many more features. It is a text mode application, but it also \ + includes mouse support. Midnight Commander's best features are its \ + ability to FTP, view tar and zip files, and to poke into RPMs for \ + specific files. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --libexecdir=/usr/lib \ + --enable-charset + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && AUTOPOINT=true autoreconf -f -v -i +endef + +define STAGE_INSTALL_CMDS + chmod 1755 $(BUILDROOT)/usr/lib/mc/cons.saver +endef diff --git a/pkgs/core/mc/patches/mc-4.6.2-utf8.patch b/pkgs/core/mc/patches/mc-4.6.2-utf8.patch new file mode 100644 index 0000000..66472af --- /dev/null +++ b/pkgs/core/mc/patches/mc-4.6.2-utf8.patch @@ -0,0 +1,7017 @@ +diff --git a/acinclude.m4 b/acinclude.m4 +index f4c0e3b..f7f4fd4 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -399,14 +399,14 @@ AC_DEFUN([MC_WITH_SLANG], [ + fi + + dnl Unless external S-Lang was requested, reject S-Lang with UTF-8 hacks +- if test x$with_screen = xslang; then +- : +- m4_if([$1], strict, , +- [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], +- [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ +-it's not fully supported yet]) +- with_screen=mcslang])]) +- fi ++dnl if test x$with_screen = xslang; then ++dnl : ++dnl m4_if([$1], strict, , ++dnl [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], ++dnl [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ ++dnl it's not fully supported yet]) ++dnl with_screen=mcslang])]) ++dnl fi + + if test x$with_screen = xslang; then + AC_DEFINE(HAVE_SYSTEM_SLANG, 1, +diff --git a/edit/edit-widget.h b/edit/edit-widget.h +index ab55764..fd51aaa 100644 +--- a/edit/edit-widget.h ++++ b/edit/edit-widget.h +@@ -30,6 +30,11 @@ typedef struct edit_key_map_type { + long command; + } edit_key_map_type; + ++struct action { ++ mc_wchar_t ch; ++ long flags; ++}; ++ + struct WEdit { + Widget widget; + +@@ -42,8 +47,17 @@ struct WEdit { + /* dynamic buffers and cursor position for editor: */ + long curs1; /* position of the cursor from the beginning of the file. */ + long curs2; /* position from the end of the file */ ++#ifndef UTF8 + unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ + unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ ++#else /* UTF8 */ ++ mc_wchar_t *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ ++ mc_wchar_t *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ ++ ++ unsigned char charbuf[MB_LEN_MAX]; ++ int charpoint; ++#endif /* UTF8 */ ++ + + /* search variables */ + long search_start; /* First character to start searching from */ +@@ -87,7 +101,7 @@ struct WEdit { + + /* undo stack and pointers */ + unsigned long stack_pointer; +- long *undo_stack; ++ struct action *undo_stack; + unsigned long stack_size; + unsigned long stack_size_mask; + unsigned long stack_bottom; +diff --git a/edit/edit.c b/edit/edit.c +index bec84d7..8df473b 100644 +--- a/edit/edit.c ++++ b/edit/edit.c +@@ -105,7 +105,11 @@ char *option_backup_ext = NULL; + + static void user_menu (WEdit *edit); + ++#ifndef UTF8 + int edit_get_byte (WEdit * edit, long byte_index) ++#else ++mc_wchar_t edit_get_byte (WEdit * edit, long byte_index) ++#endif + { + unsigned long p; + if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) +@@ -134,7 +138,7 @@ edit_init_buffers (WEdit *edit) + + edit->curs1 = 0; + edit->curs2 = 0; +- edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + } + + /* +@@ -159,7 +163,7 @@ edit_load_file_fast (WEdit *edit, const char *filename) + } + + if (!edit->buffers2[buf2]) +- edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + + mc_read (file, + (char *) edit->buffers2[buf2] + EDIT_BUF_SIZE - +@@ -169,7 +173,7 @@ edit_load_file_fast (WEdit *edit, const char *filename) + for (buf = buf2 - 1; buf >= 0; buf--) { + /* edit->buffers2[0] is already allocated */ + if (!edit->buffers2[buf]) +- edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE); + } + +@@ -242,9 +246,44 @@ edit_insert_stream (WEdit * edit, FILE * f) + { + int c; + long i = 0; +- while ((c = fgetc (f)) >= 0) { ++#ifndef UTF8 ++ while ((c = fgetc (f)) != EOF) { + edit_insert (edit, c); + i++; ++#else /* UTF8 */ ++ unsigned char buf[MB_LEN_MAX]; ++ int charpos = 0; ++ mbstate_t mbs; ++ ++ while ((c = fgetc (f)) != EOF) { ++ mc_wchar_t wc; ++ int size; ++ int j; ++ ++ buf[charpos++] = c; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ size = mbrtowc(&wc, (char *)buf, charpos, &mbs); ++ ++ if (size == -2) ++ continue; /* incomplete */ ++ ++ else if (size >= 0) { ++ edit_insert (edit, wc); ++ i++; ++ charpos = 0; ++ continue; ++ } ++ else { ++ ++ /* invalid */ ++#ifdef __STDC_ISO_10646__ ++ for (j=0; j<charpos; j++) ++ edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[j]); ++#endif ++ charpos = 0; ++ } ++#endif /* UTF8 */ + } + return i; + } +@@ -252,9 +291,32 @@ edit_insert_stream (WEdit * edit, FILE * f) + long edit_write_stream (WEdit * edit, FILE * f) + { + long i; ++#ifndef UTF8 + for (i = 0; i < edit->last_byte; i++) + if (fputc (edit_get_byte (edit, i), f) < 0) + break; ++#else /* UTF8 */ ++ for (i = 0; i < edit->last_byte; i++) { ++ mc_wchar_t wc = edit_get_byte (edit, i); ++ int res; ++ char tmpbuf[MB_LEN_MAX]; ++ mbstate_t mbs; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++#ifdef __STDC_ISO_10646__ ++ if (wc >= BINARY_CHAR_OFFSET && wc < (BINARY_CHAR_OFFSET + 256)) { ++ res = 1; ++ tmpbuf[0] = (char) (wc - BINARY_CHAR_OFFSET); ++ } else ++#endif ++ res = wcrtomb(tmpbuf, wc, &mbs); ++ if (res > 0) { ++ if (fwrite(tmpbuf, res, 1, f) != 1) ++ break; ++ } ++ } ++#endif /* UTF8 */ + return i; + } + +@@ -293,12 +355,46 @@ edit_insert_file (WEdit *edit, const char *filename) + int i, file, blocklen; + long current = edit->curs1; + unsigned char *buf; ++#ifdef UTF8 ++ mbstate_t mbs; ++ int bufstart = 0; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++#endif /* UTF8 */ + if ((file = mc_open (filename, O_RDONLY | O_BINARY)) == -1) + return 0; + buf = g_malloc (TEMP_BUF_LEN); ++#ifndef UTF8 + while ((blocklen = mc_read (file, (char *) buf, TEMP_BUF_LEN)) > 0) { + for (i = 0; i < blocklen; i++) + edit_insert (edit, buf[i]); ++#else /* UTF8 */ ++ while ((blocklen = mc_read (file, (char *) buf + bufstart, TEMP_BUF_LEN - bufstart)) > 0) { ++ blocklen += bufstart; ++ bufstart = 0; ++ for (i = 0; i < blocklen; ) { ++ mc_wchar_t wc; ++ int j; ++ int size = mbrtowc(&wc, (char *)buf + i, blocklen - i, &mbs); ++ if (size == -2) { /*incomplete char*/ ++ bufstart = blocklen - i; ++ memcpy(buf, buf+i, bufstart); ++ i = blocklen; ++ memset (&mbs, 0, sizeof (mbs)); ++ } ++ else if (size <= 0) { ++#ifdef __STDC_ISO_10646__ ++ edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[i]); ++#endif ++ memset (&mbs, 0, sizeof (mbs)); ++ i++; /* skip broken char */ ++ } ++ else { ++ edit_insert (edit, wc); ++ i+=size; ++ } ++ } ++#endif /* UTF8 */ + } + edit_cursor_move (edit, current - edit->curs1); + g_free (buf); +@@ -388,7 +484,11 @@ cleanup: + static int + edit_load_file (WEdit *edit) + { ++#ifndef UTF8 + int fast_load = 1; ++#else /* UTF8 */ ++ int fast_load = 0; /* can't be used with multibyte characters */ ++#endif /* UTF8 */ + + /* Cannot do fast load if a filter is used */ + if (edit_find_filter (edit->filename) >= 0) +@@ -454,6 +554,7 @@ edit_load_position (WEdit *edit) + edit->prev_col = column; + edit_move_to_prev_col (edit, edit_bol (edit, edit->curs1)); + edit_move_display (edit, line - (edit->num_widget_lines / 2)); ++ edit->charpoint = 0; + } + + /* Save cursor position in the file */ +@@ -537,7 +638,7 @@ edit_init (WEdit *edit, int lines, int columns, const char *filename, + edit_set_filename (edit, filename); + edit->stack_size = START_STACK_SIZE; + edit->stack_size_mask = START_STACK_SIZE - 1; +- edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (long)); ++ edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (struct action)); + if (edit_load_file (edit)) { + /* edit_load_file already gives an error message */ + if (to_free) +@@ -692,14 +793,23 @@ void edit_push_action (WEdit * edit, long c,...) + { + unsigned long sp = edit->stack_pointer; + unsigned long spm1; +- long *t; ++ ++ struct action *t; ++ mc_wchar_t ch = 0; ++ ++ if (c == CHAR_INSERT || c == CHAR_INSERT_AHEAD) { ++ va_list ap; ++ va_start (ap, c); ++ ch = va_arg (ap, mc_wint_t); ++ va_end (ap); ++ } + + /* first enlarge the stack if necessary */ + if (sp > edit->stack_size - 10) { /* say */ + if (option_max_undo < 256) + option_max_undo = 256; + if (edit->stack_size < (unsigned long) option_max_undo) { +- t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (long)); ++ t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (struct action)); + if (t) { + edit->undo_stack = t; + edit->stack_size <<= 1; +@@ -714,7 +824,7 @@ void edit_push_action (WEdit * edit, long c,...) + #ifdef FAST_MOVE_CURSOR + if (c == CURS_LEFT_LOTS || c == CURS_RIGHT_LOTS) { + va_list ap; +- edit->undo_stack[sp] = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; ++ edit->undo_stack[sp].flags = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; + edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; + va_start (ap, c); + c = -(va_arg (ap, int)); +@@ -725,12 +835,14 @@ void edit_push_action (WEdit * edit, long c,...) + && spm1 != edit->stack_bottom + && ((sp - 2) & edit->stack_size_mask) != edit->stack_bottom) { + int d; +- if (edit->undo_stack[spm1] < 0) { +- d = edit->undo_stack[(sp - 2) & edit->stack_size_mask]; +- if (d == c) { +- if (edit->undo_stack[spm1] > -1000000000) { ++ mc_wchar_t d_ch; ++ if (edit->undo_stack[spm1].flags < 0) { ++ d = edit->undo_stack[(sp - 2) & edit->stack_size_mask].flags; ++ d_ch = edit->undo_stack[(sp - 2) & edit->stack_size_mask].ch; ++ if (d == c && d_ch == ch) { ++ if (edit->undo_stack[spm1].flags > -1000000000) { + if (c < KEY_PRESS) /* --> no need to push multiple do-nothings */ +- edit->undo_stack[spm1]--; ++ edit->undo_stack[spm1].flags--; + return; + } + } +@@ -738,19 +850,20 @@ void edit_push_action (WEdit * edit, long c,...) + #ifndef NO_STACK_CURSMOVE_ANIHILATION + else if ((c == CURS_LEFT && d == CURS_RIGHT) + || (c == CURS_RIGHT && d == CURS_LEFT)) { /* a left then a right anihilate each other */ +- if (edit->undo_stack[spm1] == -2) ++ if (edit->undo_stack[spm1].flags == -2) + edit->stack_pointer = spm1; + else +- edit->undo_stack[spm1]++; ++ edit->undo_stack[spm1].flags++; + return; + } + #endif + } else { +- d = edit->undo_stack[spm1]; +- if (d == c) { ++ d = edit->undo_stack[spm1].flags; ++ d_ch = edit->undo_stack[spm1].ch; ++ if (d == c && d_ch == ch) { + if (c >= KEY_PRESS) + return; /* --> no need to push multiple do-nothings */ +- edit->undo_stack[sp] = -2; ++ edit->undo_stack[sp].flags = -2; + goto check_bottom; + } + #ifndef NO_STACK_CURSMOVE_ANIHILATION +@@ -762,7 +875,9 @@ void edit_push_action (WEdit * edit, long c,...) + #endif + } + } +- edit->undo_stack[sp] = c; ++ edit->undo_stack[sp].flags = c; ++ edit->undo_stack[sp].ch = ch; ++ + check_bottom: + + edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; +@@ -775,10 +890,10 @@ void edit_push_action (WEdit * edit, long c,...) + (((unsigned long) c + 1) & edit->stack_size_mask) == edit->stack_bottom) + do { + edit->stack_bottom = (edit->stack_bottom + 1) & edit->stack_size_mask; +- } while (edit->undo_stack[edit->stack_bottom] < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); ++ } while (edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); + + /*If a single key produced enough pushes to wrap all the way round then we would notice that the [stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */ +- if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom] < KEY_PRESS) ++ if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS) + edit->stack_bottom = edit->stack_pointer = 0; + } + +@@ -787,30 +902,30 @@ void edit_push_action (WEdit * edit, long c,...) + then the file should be as it was when he loaded up. Then set edit->modified to 0. + */ + static long +-pop_action (WEdit * edit) ++pop_action (WEdit * edit, struct action *c) + { +- long c; + unsigned long sp = edit->stack_pointer; + if (sp == edit->stack_bottom) { +- return STACK_BOTTOM; ++ c->flags = STACK_BOTTOM; ++ return c->flags; + } + sp = (sp - 1) & edit->stack_size_mask; +- if ((c = edit->undo_stack[sp]) >= 0) { +-/* edit->undo_stack[sp] = '@'; */ ++ *c = edit->undo_stack[sp]; ++ if (edit->undo_stack[sp].flags >= 0) { + edit->stack_pointer = (edit->stack_pointer - 1) & edit->stack_size_mask; +- return c; ++ return c->flags; + } + if (sp == edit->stack_bottom) { + return STACK_BOTTOM; + } +- c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; +- if (edit->undo_stack[sp] == -2) { +-/* edit->undo_stack[sp] = '@'; */ ++ *c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; ++ ++ if (edit->undo_stack[sp].flags == -2) { + edit->stack_pointer = sp; + } else +- edit->undo_stack[sp]++; ++ edit->undo_stack[sp].flags++; + +- return c; ++ return c->flags; + } + + /* is called whenever a modification is made by one of the four routines below */ +@@ -831,7 +946,7 @@ static inline void edit_modification (WEdit * edit) + */ + + void +-edit_insert (WEdit *edit, int c) ++edit_insert (WEdit *edit, mc_wchar_t c) + { + /* check if file has grown to large */ + if (edit->last_byte >= SIZE_LIMIT) +@@ -869,12 +984,11 @@ edit_insert (WEdit *edit, int c) + /* add a new buffer if we've reached the end of the last one */ + if (!(edit->curs1 & M_EDIT_BUF_SIZE)) + edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = +- g_malloc (EDIT_BUF_SIZE); ++ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + + /* perform the insertion */ +- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit-> +- curs1 & M_EDIT_BUF_SIZE] +- = (unsigned char) c; ++ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] ++ [edit->curs1 & M_EDIT_BUF_SIZE] = c; + + /* update file length */ + edit->last_byte++; +@@ -885,7 +999,7 @@ edit_insert (WEdit *edit, int c) + + + /* same as edit_insert and move left */ +-void edit_insert_ahead (WEdit * edit, int c) ++void edit_insert_ahead (WEdit * edit, mc_wchar_t c) + { + if (edit->last_byte >= SIZE_LIMIT) + return; +@@ -908,7 +1022,7 @@ void edit_insert_ahead (WEdit * edit, int c) + edit->last_get_rule += (edit->last_get_rule >= edit->curs1); + + if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) +- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; + + edit->last_byte++; +@@ -918,7 +1032,7 @@ void edit_insert_ahead (WEdit * edit, int c) + + int edit_delete (WEdit * edit) + { +- int p; ++ mc_wint_t p; + if (!edit->curs2) + return 0; + +@@ -942,7 +1056,7 @@ int edit_delete (WEdit * edit) + edit->total_lines--; + edit->force |= REDRAW_AFTER_CURSOR; + } +- edit_push_action (edit, p + 256); ++ edit_push_action (edit, CHAR_INSERT_AHEAD, p); + if (edit->curs1 < edit->start_display) { + edit->start_display--; + if (p == '\n') +@@ -956,7 +1070,7 @@ int edit_delete (WEdit * edit) + static int + edit_backspace (WEdit * edit) + { +- int p; ++ mc_wint_t p; + if (!edit->curs1) + return 0; + +@@ -980,7 +1094,7 @@ edit_backspace (WEdit * edit) + edit->total_lines--; + edit->force |= REDRAW_AFTER_CURSOR; + } +- edit_push_action (edit, p); ++ edit_push_action (edit, CHAR_INSERT, p); + + if (edit->curs1 < edit->start_display) { + edit->start_display--; +@@ -993,10 +1107,18 @@ edit_backspace (WEdit * edit) + + #ifdef FAST_MOVE_CURSOR + +-static void memqcpy (WEdit * edit, unsigned char *dest, unsigned char *src, int n) ++static void memqcpy (WEdit * edit, mc_wchar_t *dest, mc_wchar_t *src, int n) + { + unsigned long next; ++#ifndef UTF8 + while ((next = (unsigned long) memccpy (dest, src, '\n', n))) { ++#else /* UTF8 */ ++ while (n) { ++ next = 0; ++ while (next < n && src[next]!='\n') next++; ++ if (next < n) next++; ++ wmemcpy (dest, src, next) ++#endif /* UTF8 */ + edit->curs_line--; + next -= (unsigned long) dest; + n -= next; +@@ -1009,7 +1131,7 @@ int + edit_move_backward_lots (WEdit *edit, long increment) + { + int r, s, t; +- unsigned char *p; ++ mc_wchar_t *p; + + if (increment > edit->curs1) + increment = edit->curs1; +@@ -1049,7 +1171,7 @@ edit_move_backward_lots (WEdit *edit, long increment) + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; + else + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = +- g_malloc (EDIT_BUF_SIZE); ++ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + } else { + g_free (p); + } +@@ -1087,7 +1209,7 @@ edit_move_backward_lots (WEdit *edit, long increment) + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; + else + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = +- g_malloc (EDIT_BUF_SIZE); ++ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + } else { + g_free (p); + } +@@ -1120,7 +1242,7 @@ void edit_cursor_move (WEdit * edit, long increment) + + c = edit_get_byte (edit, edit->curs1 - 1); + if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) +- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; + edit->curs2++; + c = edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE][(edit->curs1 - 1) & M_EDIT_BUF_SIZE]; +@@ -1144,7 +1266,7 @@ void edit_cursor_move (WEdit * edit, long increment) + + c = edit_get_byte (edit, edit->curs1); + if (!(edit->curs1 & M_EDIT_BUF_SIZE)) +- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->curs1 & M_EDIT_BUF_SIZE] = c; + edit->curs1++; + c = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1]; +@@ -1249,7 +1371,7 @@ long edit_move_forward3 (WEdit * edit, long current, int cols, long upto) + q = edit->last_byte + 2; + + for (col = 0, p = current; p < q; p++) { +- int c; ++ mc_wchar_t c; + if (cols != -10) { + if (col == cols) + return p; +@@ -1267,7 +1389,7 @@ long edit_move_forward3 (WEdit * edit, long current, int cols, long upto) + } else if (c < 32 || c == 127) + col += 2; /* Caret notation for control characters */ + else +- col++; ++ col += wcwidth(c); + } + return col; + } +@@ -1400,12 +1522,16 @@ static int + is_blank (WEdit *edit, long offset) + { + long s, f; +- int c; ++ mc_wchar_t c; + s = edit_bol (edit, offset); + f = edit_eol (edit, offset) - 1; + while (s <= f) { + c = edit_get_byte (edit, s++); ++#ifndef UTF8 + if (!isspace (c)) ++#else ++ if (!iswspace (c)) ++#endif /* UTF8 */ + return 0; + } + return 1; +@@ -1660,6 +1786,7 @@ my_type_of (int c) + return 2; + return 0x80000000UL; + } ++#ifndef UTF8 + if (isupper (c)) + c = 'A'; + else if (islower (c)) +@@ -1670,6 +1797,18 @@ my_type_of (int c) + c = '0'; + else if (isspace (c)) + c = ' '; ++#else ++ if (iswupper (c)) ++ c = 'A'; ++ else if (iswlower (c)) ++ c = 'a'; ++ else if (iswalpha (c)) ++ c = 'a'; ++ else if (iswdigit (c)) ++ c = '0'; ++ else if (iswspace (c)) ++ c = ' '; ++#endif /* UTF8 */ + q = strchr (option_chars_move_whole_word, c); + if (!q) + return 0xFFFFFFFFUL; +@@ -1694,10 +1833,18 @@ edit_left_word_move (WEdit *edit, int s) + c2 = edit_get_byte (edit, edit->curs1); + if (!(my_type_of (c1) & my_type_of (c2))) + break; ++#ifndef UTF8 + if (isspace (c1) && !isspace (c2)) ++#else ++ if (iswspace (c1) && !iswspace (c2)) ++#endif /* UTF8 */ + break; + if (s) ++#ifndef UTF8 + if (!isspace (c1) && isspace (c2)) ++#else ++ if (!iswspace (c1) && iswspace (c2)) ++#endif /* UTF8 */ + break; + } + } +@@ -1720,10 +1867,18 @@ edit_right_word_move (WEdit *edit, int s) + c2 = edit_get_byte (edit, edit->curs1); + if (!(my_type_of (c1) & my_type_of (c2))) + break; ++#ifndef UTF8 + if (isspace (c1) && !isspace (c2)) ++#else ++ if (iswspace (c1) && !iswspace (c2)) ++#endif /* UTF8 */ + break; + if (s) ++#ifndef UTF8 + if (!isspace (c1) && isspace (c2)) ++#else ++ if (!iswspace (c1) && iswspace (c2)) ++#endif /* UTF8 */ + break; + } + } +@@ -1743,7 +1898,11 @@ static void edit_right_delete_word (WEdit * edit) + break; + c1 = edit_delete (edit); + c2 = edit_get_byte (edit, edit->curs1); ++#ifndef UTF8 + if ((isspace (c1) == 0) != (isspace (c2) == 0)) ++#else ++ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) ++#endif /* UTF8 */ + break; + if (!(my_type_of (c1) & my_type_of (c2))) + break; +@@ -1758,7 +1917,11 @@ static void edit_left_delete_word (WEdit * edit) + break; + c1 = edit_backspace (edit); + c2 = edit_get_byte (edit, edit->curs1 - 1); ++#ifndef UTF8 + if ((isspace (c1) == 0) != (isspace (c2) == 0)) ++#else ++ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) ++#endif /* UTF8 */ + break; + if (!(my_type_of (c1) & my_type_of (c2))) + break; +@@ -1772,13 +1935,13 @@ static void edit_left_delete_word (WEdit * edit) + static void + edit_do_undo (WEdit * edit) + { +- long ac; ++ struct action ac; + long count = 0; + + edit->stack_disable = 1; /* don't record undo's onto undo stack! */ + +- while ((ac = pop_action (edit)) < KEY_PRESS) { +- switch ((int) ac) { ++ while (pop_action (edit, &ac) < KEY_PRESS) { ++ switch ((int) ac.flags) { + case STACK_BOTTOM: + goto done_undo; + case CURS_RIGHT: +@@ -1799,31 +1962,33 @@ edit_do_undo (WEdit * edit) + case COLUMN_OFF: + column_highlighting = 0; + break; ++ case CHAR_INSERT: ++ edit_insert (edit, ac.ch); ++ break; ++ case CHAR_INSERT_AHEAD: ++ edit_insert_ahead (edit, ac.ch); ++ break; + } +- if (ac >= 256 && ac < 512) +- edit_insert_ahead (edit, ac - 256); +- if (ac >= 0 && ac < 256) +- edit_insert (edit, ac); + +- if (ac >= MARK_1 - 2 && ac < MARK_2 - 2) { +- edit->mark1 = ac - MARK_1; ++ if (ac.flags >= MARK_1 - 2 && ac.flags < MARK_2 - 2) { ++ edit->mark1 = ac.flags - MARK_1; + edit->column1 = edit_move_forward3 (edit, edit_bol (edit, edit->mark1), 0, edit->mark1); +- } else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) { +- edit->mark2 = ac - MARK_2; ++ } else if (ac.flags >= MARK_2 - 2 && ac.flags < KEY_PRESS) { ++ edit->mark2 = ac.flags - MARK_2; + edit->column2 = edit_move_forward3 (edit, edit_bol (edit, edit->mark2), 0, edit->mark2); + } + if (count++) + edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */ + } + +- if (edit->start_display > ac - KEY_PRESS) { +- edit->start_line -= edit_count_lines (edit, ac - KEY_PRESS, edit->start_display); ++ if (edit->start_display > ac.flags - KEY_PRESS) { ++ edit->start_line -= edit_count_lines (edit, ac.flags - KEY_PRESS, edit->start_display); + edit->force |= REDRAW_PAGE; +- } else if (edit->start_display < ac - KEY_PRESS) { +- edit->start_line += edit_count_lines (edit, edit->start_display, ac - KEY_PRESS); ++ } else if (edit->start_display < ac.flags - KEY_PRESS) { ++ edit->start_line += edit_count_lines (edit, edit->start_display, ac.flags - KEY_PRESS); + edit->force |= REDRAW_PAGE; + } +- edit->start_display = ac - KEY_PRESS; /* see push and pop above */ ++ edit->start_display = ac.flags - KEY_PRESS; /* see push and pop above */ + edit_update_curs_row (edit); + + done_undo:; +@@ -2103,7 +2268,7 @@ static void edit_goto_matching_bracket (WEdit *edit) + * passed as -1. Commands are executed, and char_for_insertion is + * inserted at the cursor. + */ +-void edit_execute_key_command (WEdit *edit, int command, int char_for_insertion) ++void edit_execute_key_command (WEdit *edit, int command, mc_wint_t char_for_insertion) + { + if (command == CK_Begin_Record_Macro) { + edit->macro_i = 0; +@@ -2138,7 +2303,7 @@ static const char * const shell_cmd[] = SHELL_COMMANDS_i; + all of them. It also does not check for the Undo command. + */ + void +-edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) ++edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion) + { + edit->force |= REDRAW_LINE; + +@@ -2171,7 +2336,7 @@ edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) + } + + /* An ordinary key press */ +- if (char_for_insertion >= 0) { ++ if (char_for_insertion != (mc_wint_t) -1) { + if (edit->overwrite) { + if (edit_get_byte (edit, edit->curs1) != '\n') + edit_delete (edit); +diff --git a/edit/edit.h b/edit/edit.h +index 4a1c39b..672bf3d 100644 +--- a/edit/edit.h ++++ b/edit/edit.h +@@ -25,6 +25,27 @@ + + #include <stdio.h> + ++#include "src/tty.h" ++ ++#ifdef UTF8 ++#include <wchar.h> ++#include <wctype.h> ++ ++#define mc_wchar_t wchar_t ++#define mc_wint_t wint_t ++ ++#else ++ ++#define mc_wchar_t unsigned char ++#define mc_wint_t int ++ ++#endif ++ ++ ++/* unicode private use area */ ++#define BINARY_CHAR_OFFSET 0xFFE00 ++ ++ + #define N_menus 5 + + #define SEARCH_DIALOG_OPTION_NO_SCANF (1 << 0) +@@ -86,6 +107,8 @@ + #define START_STACK_SIZE 32 + + /* Some codes that may be pushed onto or returned from the undo stack */ ++#define CHAR_INSERT 65 ++#define CHAR_INSERT_AHEAD 66 + #define CURS_LEFT 601 + #define CURS_RIGHT 602 + #define DELCHAR 603 +@@ -105,7 +128,7 @@ + + struct macro { + short command; +- short ch; ++ mc_wchar_t ch; + }; + + struct WEdit; +@@ -120,8 +143,12 @@ void edit_reload_menu (void); + void menu_save_mode_cmd (void); + int edit_raw_key_query (const char *heading, const char *query, int cancel); + int edit_file (const char *_file, int line); +-int edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch); ++int edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch); ++#ifndef UTF8 + int edit_get_byte (WEdit * edit, long byte_index); ++#else /* UTF8 */ ++mc_wchar_t edit_get_byte (WEdit * edit, long byte_index); ++#endif /* UTF8 */ + int edit_count_lines (WEdit * edit, long current, int upto); + long edit_move_forward (WEdit * edit, long current, int lines, long upto); + long edit_move_forward3 (WEdit * edit, long current, int cols, long upto); +@@ -148,11 +175,11 @@ int edit_block_delete_cmd (WEdit * edit); + void edit_delete_line (WEdit * edit); + + int edit_delete (WEdit * edit); +-void edit_insert (WEdit * edit, int c); ++void edit_insert (WEdit * edit, mc_wchar_t c); + void edit_cursor_move (WEdit * edit, long increment); + void edit_push_action (WEdit * edit, long c, ...); + void edit_push_key_press (WEdit * edit); +-void edit_insert_ahead (WEdit * edit, int c); ++void edit_insert_ahead (WEdit * edit, mc_wchar_t c); + long edit_write_stream (WEdit * edit, FILE * f); + char *edit_get_write_filter (const char *writename, const char *filename); + int edit_save_confirm_cmd (WEdit * edit); +@@ -183,7 +210,7 @@ void edit_goto_cmd (WEdit * edit); + int eval_marks (WEdit * edit, long *start_mark, long *end_mark); + void edit_status (WEdit * edit); + void edit_execute_key_command (WEdit *edit, int command, +- int char_for_insertion); ++ mc_wint_t char_for_insertion); + void edit_update_screen (WEdit * edit); + int edit_print_string (WEdit * e, const char *s); + void edit_move_to_line (WEdit * e, long line); +@@ -233,7 +260,7 @@ void edit_mail_dialog (WEdit *edit); + void format_paragraph (WEdit *edit, int force); + + /* either command or char_for_insertion must be passed as -1 */ +-void edit_execute_cmd (WEdit *edit, int command, int char_for_insertion); ++void edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion); + + #define get_sys_error(s) (s) + +diff --git a/edit/editcmd.c b/edit/editcmd.c +index d223c35..b85d9cd 100644 +--- a/edit/editcmd.c ++++ b/edit/editcmd.c +@@ -60,7 +60,7 @@ + #include "../src/selcodepage.h" + + struct selection { +- unsigned char * text; ++ mc_wchar_t *text; + int len; + }; + +@@ -83,21 +83,16 @@ int edit_confirm_save = 1; + #define MAX_REPL_LEN 1024 + + static int edit_save_cmd (WEdit *edit); +-static unsigned char *edit_get_block (WEdit *edit, long start, ++static mc_wchar_t *edit_get_block (WEdit *edit, long start, + long finish, int *l); + +-static inline int my_lower_case (int c) ++static inline mc_wchar_t my_lower_case (mc_wchar_t c) + { ++#ifndef UTF8 + return tolower(c & 0xFF); +-} +- +-static const char * +-strcasechr (const char *s, int c) +-{ +- for (c = my_lower_case (c); my_lower_case ((int) *s) != c; ++s) +- if (*s == '\0') +- return 0; +- return s; ++#else ++ return towlower(c); ++#endif + } + + #ifndef HAVE_MEMMOVE +@@ -123,11 +118,11 @@ static void *memmove (void *dest, const void *src, size_t n) + #endif /* !HAVE_MEMMOVE */ + + /* #define itoa MY_itoa <---- this line is now in edit.h */ +-static char * ++static mc_wchar_t * + MY_itoa (int i) + { +- static char t[14]; +- char *s = t + 13; ++ static mc_wchar_t t[14]; ++ mc_wchar_t *s = t + 13; + int j = i; + *s-- = 0; + do { +@@ -212,6 +207,48 @@ void edit_refresh_cmd (WEdit * edit) + doupdate(); + } + ++#ifdef UTF8 ++ ++static size_t ++wchar_write(int fd, mc_wchar_t *buf, size_t len) ++{ ++ char *tmpbuf = g_malloc(len + MB_LEN_MAX); ++ mbstate_t mbs; ++ size_t i; ++ size_t outlen = 0; ++ size_t res; ++ ++ for (i = 0; i < len; i++) { ++ if (outlen >= len) { ++ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) { ++ g_free(tmpbuf); ++ return -1; ++ } ++ outlen = 0; ++ } ++ memset (&mbs, 0, sizeof (mbs)); ++#ifdef __STDC_ISO_10646__ ++ if (buf[i] >= BINARY_CHAR_OFFSET && buf[i] < (BINARY_CHAR_OFFSET + 256)) { ++ res = 1; ++ tmpbuf[outlen] = (char) (buf[i] - BINARY_CHAR_OFFSET); ++ ++ } else ++#endif ++ res = wcrtomb(tmpbuf + outlen, buf[i], &mbs); ++ if (res > 0) { ++ outlen += res; ++ } ++ } ++ if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) { ++ g_free(tmpbuf); ++ return -1; ++ } ++ g_free(tmpbuf); ++ return len; ++} ++ ++#endif /* UTF8 */ ++ + /* If 0 (quick save) then a) create/truncate <filename> file, + b) save to <filename>; + if 1 (safe save) then a) save to <tempnam>, +@@ -359,32 +396,48 @@ edit_save_file (WEdit *edit, const char *filename) + buf = 0; + filelen = edit->last_byte; + while (buf <= (edit->curs1 >> S_EDIT_BUF_SIZE) - 1) { ++#ifndef UTF8 + if (mc_write (fd, (char *) edit->buffers1[buf], EDIT_BUF_SIZE) ++#else /* UTF8 */ ++ if (wchar_write (fd, edit->buffers1[buf], EDIT_BUF_SIZE) ++#endif /* UTF8 */ + != EDIT_BUF_SIZE) { + mc_close (fd); + goto error_save; + } + buf++; + } ++#ifndef UTF8 + if (mc_write + (fd, (char *) edit->buffers1[buf], ++#else /* UTF8 */ ++ if (wchar_write ++ (fd, edit->buffers1[buf], ++#endif /* UTF8 */ + edit->curs1 & M_EDIT_BUF_SIZE) != + (edit->curs1 & M_EDIT_BUF_SIZE)) { + filelen = -1; + } else if (edit->curs2) { + edit->curs2--; + buf = (edit->curs2 >> S_EDIT_BUF_SIZE); +- if (mc_write +- (fd, +- (char *) edit->buffers2[buf] + EDIT_BUF_SIZE - ++#ifndef UTF8 ++ if (mc_write(fd, (char *) edit->buffers2[buf] + EDIT_BUF_SIZE - ++#else /* UTF8 */ ++ if (wchar_write(fd, edit->buffers2[buf] + EDIT_BUF_SIZE - ++#endif /* UTF8 */ + (edit->curs2 & M_EDIT_BUF_SIZE) - 1, + 1 + (edit->curs2 & M_EDIT_BUF_SIZE)) != + 1 + (edit->curs2 & M_EDIT_BUF_SIZE)) { + filelen = -1; + } else { + while (--buf >= 0) { ++#ifndef UTF8 + if (mc_write + (fd, (char *) edit->buffers2[buf], ++#else /* UTF8 */ ++ if (wchar_write ++ (fd, edit->buffers2[buf], ++#endif /* UTF8 */ + EDIT_BUF_SIZE) != EDIT_BUF_SIZE) { + filelen = -1; + break; +@@ -705,13 +758,21 @@ edit_delete_macro (WEdit * edit, int k) + if (!n || n == EOF) + break; + n = 0; ++#ifndef UTF8 + while (fscanf (f, "%hd %hd, ", ¯o[n].command, ¯o[n].ch)) ++#else /* UTF8 */ ++ while (fscanf (f, "%hd %lu, ", ¯o[n].command, ¯o[n].ch)) ++#endif /* UTF8 */ + n++; + fscanf (f, ";\n"); + if (s != k) { + fprintf (g, ("key '%d 0': "), s); + for (i = 0; i < n; i++) ++#ifndef UTF8 + fprintf (g, "%hd %hd, ", macro[i].command, macro[i].ch); ++#else /* UTF8 */ ++ fprintf (g, "%hd %lu, ", macro[i].command, macro[i].ch); ++#endif /* UTF8 */ + fprintf (g, ";\n"); + } + } +@@ -744,7 +805,11 @@ int edit_save_macro_cmd (WEdit * edit, struct macro macro[], int n) + if (f) { + fprintf (f, ("key '%d 0': "), s); + for (i = 0; i < n; i++) ++#ifndef UTF8 + fprintf (f, "%hd %hd, ", macro[i].command, macro[i].ch); ++#else /* UTF8 */ ++ fprintf (f, "%hd %lu, ", macro[i].command, macro[i].ch); ++#endif /* UTF8 */ + fprintf (f, ";\n"); + fclose (f); + if (saved_macros_loaded) { +@@ -794,10 +859,18 @@ int edit_load_macro_cmd (WEdit * edit, struct macro macro[], int *n, int k) + saved_macro[i++] = s; + if (!found) { + *n = 0; ++#ifndef UTF8 + while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %hd, ", ¯o[*n].command, ¯o[*n].ch)) ++#else /* UTF8 */ ++ while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %lu, ", ¯o[*n].command, ¯o[*n].ch)) ++#endif /* UTF8 */ + (*n)++; + } else { ++#ifndef UTF8 + while (2 == fscanf (f, "%hd %hd, ", &dummy.command, &dummy.ch)); ++#else /* UTF8 */ ++ while (2 == fscanf (f, "%hd %lu, ", &dummy.command, &dummy.ch)); ++#endif /* UTF8 */ + } + fscanf (f, ";\n"); + if (s == k) +@@ -945,7 +1018,7 @@ int eval_marks (WEdit * edit, long *start_mark, long *end_mark) + #define space_width 1 + + static void +-edit_insert_column_of_text (WEdit * edit, unsigned char *data, int size, int width) ++edit_insert_column_of_text (WEdit * edit, mc_wchar_t *data, int size, int width) + { + long cursor; + int i, col; +@@ -993,7 +1066,7 @@ edit_block_copy_cmd (WEdit *edit) + { + long start_mark, end_mark, current = edit->curs1; + int size; +- unsigned char *copy_buf; ++ mc_wchar_t *copy_buf; + + edit_update_curs_col (edit); + if (eval_marks (edit, &start_mark, &end_mark)) +@@ -1033,7 +1106,7 @@ edit_block_move_cmd (WEdit *edit) + { + long count; + long current; +- unsigned char *copy_buf; ++ mc_wchar_t *copy_buf; + long start_mark, end_mark; + int deleted = 0; + int x = 0; +@@ -1094,7 +1167,7 @@ edit_block_move_cmd (WEdit *edit) + edit_push_action (edit, COLUMN_ON); + column_highlighting = 0; + } else { +- copy_buf = g_malloc (end_mark - start_mark); ++ copy_buf = g_malloc ((end_mark - start_mark) * sizeof(mc_wchar_t)); + edit_cursor_move (edit, start_mark - edit->curs1); + edit_scroll_screen_over_cursor (edit); + count = start_mark; +@@ -1433,7 +1506,11 @@ static long sargs[NUM_REPL_ARGS][256 / sizeof (long)]; + /* This function is a modification of mc-3.2.10/src/view.c:regexp_view_search() */ + /* returns -3 on error in pattern, -1 on not found, found_len = 0 if either */ + static int ++#ifndef UTF8 + string_regexp_search (char *pattern, char *string, int match_type, ++#else /* UTF8 */ ++string_regexp_search (char *pattern, mc_wchar_t *wstring, int match_type, ++#endif /* UTF8 */ + int match_bol, int icase, int *found_len, void *d) + { + static regex_t r; +@@ -1442,6 +1519,11 @@ string_regexp_search (char *pattern, char *string, int match_type, + regmatch_t *pmatch; + static regmatch_t s[1]; + ++#ifdef UTF8 ++ char *string; ++ int i; ++#endif /* UTF8 */ ++ + pmatch = (regmatch_t *) d; + if (!pmatch) + pmatch = s; +@@ -1462,13 +1544,51 @@ string_regexp_search (char *pattern, char *string, int match_type, + old_type = match_type; + old_icase = icase; + } ++ ++#ifdef UTF8 ++ string = wchar_to_mbstr(wstring); ++ if (string == NULL) ++ return -1; ++#endif /* UTF8 */ ++ + if (regexec + (&r, string, d ? NUM_REPL_ARGS : 1, pmatch, + ((match_bol + || match_type != match_normal) ? 0 : REG_NOTBOL)) != 0) { + *found_len = 0; ++ ++#ifdef UTF8 ++ g_free(string); ++#endif /* UTF8 */ ++ + return -1; + } ++ ++#ifdef UTF8 ++ for (i = 0; i < (d ? NUM_REPL_ARGS : 1); i++) { ++ char tmp; ++ int new_o; ++ ++ if (pmatch[i].rm_so < 0) ++ continue; ++ tmp = string[pmatch[i].rm_so]; ++ string[pmatch[i].rm_so] = 0; ++ new_o = mbstrlen(string); ++ string[pmatch[i].rm_so] = tmp; ++ pmatch[i].rm_so = new_o; ++ ++ if (pmatch[i].rm_eo < 0) ++ continue; ++ tmp = string[pmatch[i].rm_eo]; ++ string[pmatch[i].rm_eo] = 0; ++ new_o = mbstrlen(string); ++ string[pmatch[i].rm_eo] = tmp; ++ pmatch[i].rm_eo = new_o; ++ } ++ ++ g_free(string); ++#endif /* UTF8 */ ++ + *found_len = pmatch[0].rm_eo - pmatch[0].rm_so; + return (pmatch[0].rm_so); + } +@@ -1476,13 +1596,29 @@ string_regexp_search (char *pattern, char *string, int match_type, + /* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this + (and the above) routines to work properly - paul */ + ++#ifndef UTF8 + typedef int (*edit_getbyte_fn) (WEdit *, long); ++#else /* UTF8 */ ++typedef mc_wchar_t (*edit_getbyte_fn) (WEdit *, long); ++#endif /* UTF8 */ + + static long ++#ifndef UTF8 + edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d) ++#else /* UTF8 */ ++edit_find_string (long start, unsigned char *exp_mb, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d) ++#endif /* UTF8 */ + { + long p, q = 0; +- long l = strlen ((char *) exp), f = 0; ++ long f = 0; ++ ++#ifndef UTF8 ++ long l = strlen ((char *) exp); ++#else /* UTF8 */ ++ mc_wchar_t *exp = mbstr_to_wchar((char *)exp_mb); ++ mc_wchar_t *exp_backup = exp; ++ long l = wcslen(exp); ++#endif /* UTF8 */ + int n = 0; + + for (p = 0; p < l; p++) /* count conversions... */ +@@ -1491,19 +1627,22 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit + n++; + + if (replace_scanf || replace_regexp) { +- int c; +- unsigned char *buf; +- unsigned char mbuf[MAX_REPL_LEN * 2 + 3]; ++ mc_wint_t c; ++ mc_wchar_t *buf; ++ mc_wchar_t mbuf[MAX_REPL_LEN * 2 + 3]; + + replace_scanf = (!replace_regexp); /* can't have both */ + + buf = mbuf; + + if (replace_scanf) { +- unsigned char e[MAX_REPL_LEN]; +- if (n >= NUM_REPL_ARGS) +- return -3; +- ++ mc_wchar_t e[MAX_REPL_LEN]; ++ if (n >= NUM_REPL_ARGS) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ ++ return -3; ++ } + if (replace_case) { + for (p = start; p < last_byte && p < start + MAX_REPL_LEN; p++) + buf[p - start] = (*get_byte) (data, p); +@@ -1517,20 +1656,36 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit + } + + buf[(q = p - start)] = 0; ++#ifndef UTF8 + strcpy ((char *) e, (char *) exp); + strcat ((char *) e, "%n"); ++#else /* UTF8 */ ++ wcscpy (e, exp); ++ wcscat (e, L"%n"); ++#endif /* UTF8 */ + exp = e; + + while (q) { + *((int *) sargs[n]) = 0; /* --> here was the problem - now fixed: good */ ++#ifndef UTF8 + if (n == sscanf ((char *) buf, (char *) exp, SCANF_ARGS)) { ++#else /* UTF8 */ ++ if (n == swscanf (buf, exp, SCANF_ARGS)) { ++#endif /* UTF8 */ + if (*((int *) sargs[n])) { + *len = *((int *) sargs[n]); ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return start; + } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + if (q + start < last_byte) { + if (replace_case) { + buf[q] = (*get_byte) (data, q + start); +@@ -1544,7 +1699,11 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit + start++; + buf++; /* move the window along */ + if (buf == mbuf + MAX_REPL_LEN) { /* the window is about to go past the end of array, so... */ ++#ifndef UTF8 + memmove (mbuf, buf, strlen ((char *) buf) + 1); /* reset it */ ++#else /* UTF8 */ ++ wmemmove (mbuf, buf, (wcslen (buf) + 1)); /* reset it */ ++#endif /* UTF8 */ + buf = mbuf; + } + q--; +@@ -1571,10 +1730,16 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit + + buf = mbuf; + while (q) { ++#ifndef UTF8 + found_start = string_regexp_search ((char *) exp, (char *) buf, match_normal, match_bol, !replace_case, len, d); +- ++#else /* UTF8 */ ++ found_start = string_regexp_search ((char *) exp_mb, buf, match_normal, match_bol, !replace_case, len, d); ++#endif /* UTF8 */ + if (found_start <= -2) { /* regcomp/regexec error */ + *len = 0; ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return -3; + } + else if (found_start == -1) /* not found: try next line */ +@@ -1585,15 +1750,27 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit + match_bol = 0; + continue; + } +- else /* found */ ++ else { /* found */ ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return (start + offset - q + found_start); ++ } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + + if (buf[q - 1] != '\n') { /* incomplete line: try to recover */ + buf = mbuf + MAX_REPL_LEN / 2; ++#ifndef UTF8 + q = strlen ((const char *) buf); ++#else /* UTF8 */ ++ q = wcslen (buf); ++#endif /* UTF8 */ + memmove (mbuf, buf, q); + p = start + q; + move_win = 1; +@@ -1603,36 +1780,59 @@ edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit + } + } + } else { ++#ifndef UTF8 + *len = strlen ((const char *) exp); ++#else /* UTF8 */ ++ *len = wcslen (exp); ++#endif /* UTF8 */ + if (replace_case) { + for (p = start; p <= last_byte - l; p++) { +- if ((*get_byte) (data, p) == (unsigned char)exp[0]) { /* check if first char matches */ ++ if ((*get_byte) (data, p) == exp[0]) { /* check if first char matches */ + for (f = 0, q = 0; q < l && f < 1; q++) +- if ((*get_byte) (data, q + p) != (unsigned char)exp[q]) ++ if ((*get_byte) (data, q + p) != exp[q]) + f = 1; +- if (f == 0) ++ if (f == 0) { ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return p; ++ } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free(exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + } + } else { + for (p = 0; exp[p] != 0; p++) + exp[p] = my_lower_case (exp[p]); + + for (p = start; p <= last_byte - l; p++) { +- if (my_lower_case ((*get_byte) (data, p)) == (unsigned char)exp[0]) { ++ if (my_lower_case ((*get_byte) (data, p)) == exp[0]) { + for (f = 0, q = 0; q < l && f < 1; q++) +- if (my_lower_case ((*get_byte) (data, q + p)) != (unsigned char)exp[q]) ++ if (my_lower_case ((*get_byte) (data, q + p)) != exp[q]) + f = 1; +- if (f == 0) ++ if (f == 0) { ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return p; ++ } + } +- if (once_only) ++ if (once_only) { ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return -2; ++ } + } + } + } ++#ifdef UTF8 ++ g_free (exp_backup); ++#endif /* UTF8 */ + return -2; + } + +@@ -1646,9 +1846,14 @@ edit_find_forwards (long search_start, unsigned char *exp, int *len, long last_b + + while ((p = edit_find_string (p, exp, len, last_byte, get_byte, data, once_only, d)) >= 0) { + if (replace_whole) { ++#ifndef UTF8 + /*If the bordering chars are not in option_whole_chars_search then word is whole */ + if (!strcasechr (option_whole_chars_search, (*get_byte) (data, p - 1)) + && !strcasechr (option_whole_chars_search, (*get_byte) (data, p + *len))) ++#else /* UTF8 */ ++ if (!iswalnum((*get_byte) (data, p - 1)) ++ && !iswalnum((*get_byte) (data, p + *len))) ++#endif /* UTF8 */ + return p; + if (once_only) + return -2; +@@ -1680,6 +1885,7 @@ edit_find (long search_start, unsigned char *exp, int *len, long last_byte, edit + + #define is_digit(x) ((x) >= '0' && (x) <= '9') + ++#ifndef UTF8 + #define snprint(v) { \ + *p1++ = *p++; \ + *p1 = '\0'; \ +@@ -1687,33 +1893,48 @@ edit_find (long search_start, unsigned char *exp, int *len, long last_byte, edit + if (n >= (size_t) (e - s)) goto nospc; \ + s += n; \ + } ++#else /* UTF8 */ ++#define snprint(v) { \ ++ *p1++ = *p++; \ ++ *p1 = '\0'; \ ++ n = swprintf(s, e-s, q1,v); \ ++ if (n >= (size_t) (e - s)) goto nospc; \ ++ s += n; \ ++ } ++#endif /* UTF8 */ + + /* this function uses the sprintf command to do a vprintf */ + /* it takes pointers to arguments instead of the arguments themselves */ + /* The return value is the number of bytes written excluding '\0' + if successfull, -1 if the resulting string would be too long and + -2 if the format string is errorneous. */ +-static int snprintf_p (char *str, size_t size, const char *fmt,...) +- __attribute__ ((format (printf, 3, 4))); +- +-static int snprintf_p (char *str, size_t size, const char *fmt,...) ++static int snprintf_p (mc_wchar_t *str, size_t size, const mc_wchar_t *fmt,...) + { + va_list ap; + size_t n; +- const char *q, *p; +- char *s = str, *e = str + size; +- char q1[40]; +- char *p1; ++ const mc_wchar_t *q, *p; ++ mc_wchar_t *s = str, *e = str + size; ++ mc_wchar_t q1[40]; ++ ++ mc_wchar_t *p1; + int nargs = 0; + + va_start (ap, fmt); + p = q = fmt; + ++#ifndef UTF8 + while ((p = strchr (p, '%'))) { ++#else /* UTF8 */ ++ while ((p = wcschr (p, L'%'))) { ++#endif /* UTF8 */ + n = p - q; + if (n >= (size_t) (e - s)) + goto nospc; ++#ifndef UTF8 + memcpy (s, q, n); /* copy stuff between format specifiers */ ++#else /* UTF8 */ ++ wmemcpy (s, q, n); /* copy stuff between format specifiers */ ++#endif /* UTF8 */ + s += n; + q = p; + p1 = q1; +@@ -1741,45 +1962,78 @@ static int snprintf_p (char *str, size_t size, const char *fmt,...) + *p1++ = *p++; + if (*p == '*') { + p++; ++#ifndef UTF8 + strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */ + p1 += strlen (p1); ++#else /* UTF8 */ ++ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace field width with a number */ ++ p1 += wcslen (p1); ++#endif /* UTF8 */ + } else { +- while (is_digit (*p) && p1 < q1 + 20) ++#ifndef UTF8 ++ while (is_digit (*p) ++#else /* UTF8 */ ++ while (iswdigit (*p) ++#endif /* UTF8 */ ++ && p1 < q1 + 20) + *p1++ = *p++; ++#ifndef UTF8 + if (is_digit (*p)) ++#else /* UTF8 */ ++ if (iswdigit (*p)) ++#endif /* UTF8 */ + goto err; + } + if (*p == '.') + *p1++ = *p++; + if (*p == '*') { + p++; ++#ifndef UTF8 + strcpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */ + p1 += strlen (p1); ++#else /* UTF8 */ ++ wcscpy (p1, MY_itoa (*va_arg (ap, int *))); /* replace precision with a number */ ++ p1 += wcslen (p1); ++#endif /* UTF8 */ + } else { +- while (is_digit (*p) && p1 < q1 + 32) ++#ifndef UTF8 ++ while (is_digit (*p) ++#else /* UTF8 */ ++ while (iswdigit (*p) ++#endif /* UTF8 */ ++ && p1 < q1 + 32) + *p1++ = *p++; ++#ifndef UTF8 + if (is_digit (*p)) ++#else /* UTF8 */ ++ if (iswdigit (*p)) ++#endif /* UTF8 */ + goto err; + } + /* flags done, now get argument */ + if (*p == 's') { ++#ifndef UTF8 + snprint (va_arg (ap, char *)); ++#else /* UTF8 */ ++ *p1++ = 'l'; ++ snprint (va_arg (ap, mc_wchar_t *)); ++#endif /* UTF8 */ + } else if (*p == 'h') { +- if (strchr ("diouxX", *p)) ++ if (*p < 128 && strchr ("diouxX", *p)) + snprint (*va_arg (ap, short *)); + } else if (*p == 'l') { + *p1++ = *p++; +- if (strchr ("diouxX", *p)) ++ if (*p < 128 && strchr ("diouxX", *p)) + snprint (*va_arg (ap, long *)); +- } else if (strchr ("cdiouxX", *p)) { ++ } else if (*p < 128 && strchr ("cdiouxX", *p)) { + snprint (*va_arg (ap, int *)); + } else if (*p == 'L') { + *p1++ = *p++; +- if (strchr ("EefgG", *p)) ++ if (*p < 128 && strchr ("EefgG", *p)) + snprint (*va_arg (ap, double *)); /* should be long double */ +- } else if (strchr ("EefgG", *p)) { ++ } else if (*p < 128 && strchr ("EefgG", *p)) { + snprint (*va_arg (ap, double *)); +- } else if (strchr ("DOU", *p)) { ++ } else if (*p < 128 && strchr ("DOU", *p)) { + snprint (*va_arg (ap, long *)); + } else if (*p == 'p') { + snprint (*va_arg (ap, void **)); +@@ -1788,10 +2042,17 @@ static int snprintf_p (char *str, size_t size, const char *fmt,...) + q = p; + } + va_end (ap); ++#ifndef UTF8 + n = strlen (q); + if (n >= (size_t) (e - s)) + return -1; + memcpy (s, q, n + 1); ++#else /* UTF8 */ ++ n = wcslen (q); ++ if (n >= (size_t) (e - s)) ++ return -1; ++ wmemcpy (s, q, n + 1); ++#endif /* UTF8 */ + return s + n - str; + nospc: + va_end (ap); +@@ -1970,8 +2231,11 @@ edit_replace_cmd (WEdit *edit, int again) + } + } + if (replace_yes) { /* delete then insert new */ ++#ifdef UTF8 ++ mc_wchar_t *winput2 = mbstr_to_wchar(input2); ++#endif /* UTF8 */ + if (replace_scanf) { +- char repl_str[MAX_REPL_LEN + 2]; ++ mc_wchar_t repl_str[MAX_REPL_LEN + 2]; + int ret = 0; + + /* we need to fill in sargs just like with scanf */ +@@ -1980,17 +2244,25 @@ edit_replace_cmd (WEdit *edit, int again) + for (k = 1; + k < NUM_REPL_ARGS && pmatch[k].rm_eo >= 0; + k++) { ++#ifndef UTF8 + unsigned char *t; ++#else /* UTF8 */ ++ mc_wchar_t *t; ++#endif + + if (pmatch[k].rm_eo - pmatch[k].rm_so > 255) { + ret = -1; + break; + } ++#ifndef UTF8 + t = (unsigned char *) &sargs[k - 1][0]; ++#else /* UTF8 */ ++ t = (mc_wchar_t *) &sargs[k - 1][0]; ++#endif /* UTF8 */ + for (j = 0; + j < pmatch[k].rm_eo - pmatch[k].rm_so + && j < 255; j++, t++) +- *t = (unsigned char) edit_get_byte (edit, ++ *t = edit_get_byte (edit, + edit-> + search_start + - +@@ -2008,14 +2280,23 @@ edit_replace_cmd (WEdit *edit, int again) + } + if (!ret) + ret = ++#ifndef UTF8 + snprintf_p (repl_str, MAX_REPL_LEN + 2, input2, ++#else /* UTF8 */ ++ snprintf_p (repl_str, MAX_REPL_LEN + 2, winput2, ++#endif /* UTF8 */ + PRINTF_ARGS); + if (ret >= 0) { + times_replaced++; + while (i--) + edit_delete (edit); ++#ifndef UTF8 + while (repl_str[++i]) + edit_insert (edit, repl_str[i]); ++#else /* UTF8 */ ++ while (winput2[++i]) ++ edit_insert (edit, winput2[i]); ++#endif /* UTF8 */ + } else { + edit_error_dialog (_(" Replace "), + ret == +@@ -2029,10 +2310,18 @@ edit_replace_cmd (WEdit *edit, int again) + times_replaced++; + while (i--) + edit_delete (edit); ++#ifndef UTF8 + while (input2[++i]) + edit_insert (edit, input2[i]); ++#else /* UTF8 */ ++ while (winput2[++i]) ++ edit_insert (edit, winput2[i]); ++#endif /* UTF8 */ + } + edit->found_len = i; ++#ifdef UTF8 ++ g_free (winput2); ++#endif /* UTF8 */ + } + /* so that we don't find the same string again */ + if (replace_backwards) { +@@ -2205,16 +2494,17 @@ edit_ok_to_exit (WEdit *edit) + #define TEMP_BUF_LEN 1024 + + /* Return a null terminated length of text. Result must be g_free'd */ +-static unsigned char * ++static mc_wchar_t * + edit_get_block (WEdit *edit, long start, long finish, int *l) + { +- unsigned char *s, *r; +- r = s = g_malloc (finish - start + 1); ++ mc_wchar_t *s, *r; ++ r = s = g_malloc ((finish - start + 1) * sizeof(mc_wchar_t)); + if (column_highlighting) { + *l = 0; + /* copy from buffer, excluding chars that are out of the column 'margins' */ + while (start < finish) { +- int c, x; ++ mc_wchar_t c; ++ int x; + x = edit_move_forward3 (edit, edit_bol (edit, start), 0, + start); + c = edit_get_byte (edit, start); +@@ -2247,11 +2537,15 @@ edit_save_block (WEdit * edit, const char *filename, long start, + return 0; + + if (column_highlighting) { +- unsigned char *block, *p; ++ mc_wchar_t *block, *p; + int r; + p = block = edit_get_block (edit, start, finish, &len); + while (len) { ++#ifndef UTF8 + r = mc_write (file, p, len); ++#else /* UTF8 */ ++ r = wchar_write (file, p, len); ++#endif /* UTF8 */ + if (r < 0) + break; + p += r; +@@ -2259,15 +2553,19 @@ edit_save_block (WEdit * edit, const char *filename, long start, + } + g_free (block); + } else { +- unsigned char *buf; ++ mc_wchar_t *buf; + int i = start, end; + len = finish - start; +- buf = g_malloc (TEMP_BUF_LEN); ++ buf = g_malloc (TEMP_BUF_LEN * sizeof(mc_wchar_t)); + while (start != finish) { + end = min (finish, start + TEMP_BUF_LEN); + for (; i < end; i++) + buf[i - start] = edit_get_byte (edit, i); ++#ifndef UTF8 + len -= mc_write (file, (char *) buf, end - start); ++#else /* UTF8 */ ++ len -= wchar_write (file, buf, end - start); ++#endif /* UTF8 */ + start = end; + } + g_free (buf); +@@ -2609,17 +2907,20 @@ edit_block_process_cmd (WEdit *edit, const char *shell_cmd, int block) + + /* prints at the cursor */ + /* returns the number of chars printed */ ++#ifndef UTF8 + int edit_print_string (WEdit * e, const char *s) ++#else /* UTF8 */ ++int edit_print_wstring (WEdit * e, mc_wchar_t *s) ++#endif /* UTF8 */ + { + int i = 0; + while (s[i]) +- edit_execute_cmd (e, -1, (unsigned char) s[i++]); ++ edit_execute_cmd (e, -1, s[i++]); + e->force |= REDRAW_COMPLETELY; + edit_update_screen (e); + return i; + } + +- + static void pipe_mail (WEdit *edit, char *to, char *subject, char *cc) + { + FILE *p = 0; +@@ -2713,15 +3014,20 @@ void edit_mail_dialog (WEdit * edit) + /* find first character of current word */ + static int edit_find_word_start (WEdit *edit, long *word_start, int *word_len) + { +- int i, c, last; ++ int i; ++ mc_wint_t c, last; + + /* return if at begin of file */ + if (edit->curs1 <= 0) + return 0; + +- c = (unsigned char) edit_get_byte (edit, edit->curs1 - 1); ++ c = edit_get_byte (edit, edit->curs1 - 1); + /* return if not at end or in word */ ++#ifndef UTF8 + if (isspace (c) || !(isalnum (c) || c == '_')) ++#else /* UTF8 */ ++ if (iswspace (c) || !(iswalnum (c) || c == '_')) ++#endif /* UTF8 */ + return 0; + + /* search start of word to be completed */ +@@ -2731,11 +3037,19 @@ static int edit_find_word_start (WEdit *edit, long *word_start, int *word_len) + return 0; + + last = c; +- c = (unsigned char) edit_get_byte (edit, edit->curs1 - i); ++ c = edit_get_byte (edit, edit->curs1 - i); + ++#ifndef UTF8 + if (!(isalnum (c) || c == '_')) { ++#else /* UTF8 */ ++ if (!(iswalnum (c) || c == '_')) { ++#endif /* UTF8 */ + /* return if word starts with digit */ ++#ifndef UTF8 + if (isdigit (last)) ++#else /* UTF8 */ ++ if (iswdigit (last)) ++#endif /* UTF8 */ + return 0; + + *word_start = edit->curs1 - (i - 1); /* start found */ +@@ -2768,7 +3082,7 @@ edit_collect_completions (WEdit *edit, long start, int word_len, + int *num) + { + int len, max_len = 0, i, skip; +- unsigned char *bufpos; ++ mc_wchar_t *bufpos; + + /* collect max MAX_WORD_COMPLETIONS completions */ + while (*num < MAX_WORD_COMPLETIONS) { +@@ -2787,11 +3101,16 @@ edit_collect_completions (WEdit *edit, long start, int word_len, + buffers1[start >> S_EDIT_BUF_SIZE][start & M_EDIT_BUF_SIZE]; + skip = 0; + for (i = 0; i < *num; i++) { ++#ifndef UTF8 + if (strncmp + ((char *) &compl[i].text[word_len], +- (char *) &bufpos[word_len], max (len, +- compl[i].len) - +- word_len) == 0) { ++ (char *) &bufpos[word_len], ++#else /* UTF8 */ ++ if (wcsncmp ++ ((wchar_t *) &compl[i].text[word_len], ++ (wchar_t *) &bufpos[word_len], ++#endif /* UTF8 */ ++ max (len, compl[i].len) - word_len) == 0) { + skip = 1; + break; /* skip it, already added */ + } +@@ -2799,7 +3118,7 @@ edit_collect_completions (WEdit *edit, long start, int word_len, + if (skip) + continue; + +- compl[*num].text = g_malloc (len + 1); ++ compl[*num].text = g_malloc ((len + 1) * sizeof(mc_wchar_t)); + compl[*num].len = len; + for (i = 0; i < len; i++) + compl[*num].text[i] = *(bufpos + i); +@@ -2813,6 +3132,18 @@ edit_collect_completions (WEdit *edit, long start, int word_len, + return max_len; + } + ++#ifdef UTF8 ++int edit_print_string (WEdit * e, const char *s) ++{ ++ int i; ++ mc_wchar_t *ws = mbstr_to_wchar(s); ++ i = edit_print_wstring (e, ws); ++ g_free(ws); ++ return i; ++} ++ ++#endif /* UTF8 */ ++ + + /* let the user select its preferred completion */ + static void +@@ -2825,6 +3156,9 @@ edit_completion_dialog (WEdit * edit, int max_len, int word_len, + WListbox *compl_list; + int compl_dlg_h; /* completion dialog height */ + int compl_dlg_w; /* completion dialog width */ ++#ifdef UTF8 ++ char *mbtext; ++#endif /* UTF8 */ + + /* calculate the dialog metrics */ + compl_dlg_h = num_compl + 2; +@@ -2860,9 +3194,18 @@ edit_completion_dialog (WEdit * edit, int max_len, int word_len, + add_widget (compl_dlg, compl_list); + + /* fill the listbox with the completions */ ++#ifndef UTF8 + for (i = 0; i < num_compl; i++) + listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0, + (char *) compl[i].text, NULL); ++#else /* UTF8 */ ++ for (i = 0; i < num_compl; i++) { ++ mbtext = wchar_to_mbstr(compl[i].text); ++ listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0, ++ mbtext, NULL); ++ g_free(mbtext); ++ } ++#endif /* UTF8 */ + + /* pop up the dialog */ + run_dlg (compl_dlg); +@@ -2870,9 +3213,17 @@ edit_completion_dialog (WEdit * edit, int max_len, int word_len, + /* apply the choosen completion */ + if (compl_dlg->ret_value == B_ENTER) { + listbox_get_current (compl_list, &curr, NULL); +- if (curr) ++ if (curr){ ++#ifndef UTF8 + for (curr += word_len; *curr; curr++) + edit_insert (edit, *curr); ++#else /* UTF8 */ ++ mc_wchar_t *wc, *wccurr = mbstr_to_wchar(curr); ++ for (wc = wccurr + word_len; *wc; wc++) ++ edit_insert (edit, *wc); ++ g_free(wccurr); ++#endif /* UTF8 */ ++ } + } + + /* destroy dialog before return */ +@@ -2889,8 +3240,9 @@ edit_complete_word_cmd (WEdit *edit) + { + int word_len = 0, i, num_compl = 0, max_len; + long word_start = 0; +- unsigned char *bufpos; +- char *match_expr; ++ mc_wchar_t *bufpos; ++ mc_wchar_t *match_expr; ++ char *mbmatch_expr; + struct selection compl[MAX_WORD_COMPLETIONS]; /* completions */ + + /* don't want to disturb another search */ +@@ -2907,16 +3259,32 @@ edit_complete_word_cmd (WEdit *edit) + /* prepare match expression */ + bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE] + [word_start & M_EDIT_BUF_SIZE]; ++ ++ match_expr = g_malloc((word_len + 14) * sizeof(mc_wchar_t)); ++#ifndef UTF8 + match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos); ++#else /* UTF8 */ ++ wcsncpy (match_expr, bufpos, word_len); ++ match_expr[word_len] = '\0'; ++ wcscat (match_expr, L"[a-zA-Z_0-9]+"); ++#endif /* UTF8 */ + + /* init search: backward, regexp, whole word, case sensitive */ + edit_set_search_parameters (0, 1, 1, 1, 1); + + /* collect the possible completions */ + /* start search from curs1 down to begin of file */ ++#ifndef UTF8 + max_len = + edit_collect_completions (edit, word_start, word_len, match_expr, + (struct selection *) &compl, &num_compl); ++#else /* UTF8 */ ++ mbmatch_expr = wchar_to_mbstr(match_expr); ++ max_len = ++ edit_collect_completions (edit, word_start, word_len, mbmatch_expr, ++ (struct selection *) &compl, &num_compl); ++ g_free(mbmatch_expr); ++#endif /* UTF8 */ + + if (num_compl > 0) { + /* insert completed word if there is only one match */ +@@ -2951,7 +3319,7 @@ void + edit_select_codepage_cmd (WEdit *edit) + { + #ifdef HAVE_CHARSET +- do_select_codepage (); ++ do_select_codepage (_(" Choose codepage ")); + edit->force = REDRAW_COMPLETELY; + edit_refresh_cmd (edit); + #endif +diff --git a/edit/editdraw.c b/edit/editdraw.c +index 86ea3f9..654f0b3 100644 +--- a/edit/editdraw.c ++++ b/edit/editdraw.c +@@ -71,11 +71,26 @@ static void status_string (WEdit * edit, char *s, int w) + * as decimal and as hex. + */ + if (edit->curs1 < edit->last_byte) { +- unsigned char cur_byte = edit_get_byte (edit, edit->curs1); ++ mc_wchar_t cur_byte = edit_get_byte (edit, edit->curs1); ++ mc_wchar_t cur_byte2 = cur_byte; ++#ifndef UTF8 + g_snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X", + is_printable (cur_byte) ? cur_byte : '.', +- (int) cur_byte, +- (unsigned) cur_byte); ++#else /* UTF8 */ ++ /* In 8-bit locales show the byte itself instead of its Unicode value */ ++ if (MB_CUR_MAX == 1) { ++ unsigned char cur_8bit_byte; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ if (wcrtomb(&cur_8bit_byte, cur_byte, &mbs) == 1) { ++ cur_byte = cur_8bit_byte; ++ } ++ } ++ g_snprintf (byte_str, sizeof(byte_str), "%lc %3d 0x%02X", ++ iswprint(cur_byte2) ? cur_byte2 : '.', ++#endif /* UTF8 */ ++ (int) cur_byte, ++ (unsigned) cur_byte); + } else { + strcpy (byte_str, "<EOF>"); + } +@@ -207,11 +222,16 @@ void edit_scroll_screen_over_cursor (WEdit * edit) + #define lowlevel_set_color(x) attrset(MY_COLOR_PAIR(color)) + #endif + ++struct line_s { ++ mc_wchar_t ch; ++ unsigned int style; ++}; ++ + static void + print_to_widget (WEdit *edit, long row, int start_col, int start_col_real, +- long end_col, unsigned int line[]) ++ long end_col, struct line_s line[]) + { +- unsigned int *p; ++ struct line_s *p; + + int x = start_col_real + EDIT_TEXT_HORIZONTAL_OFFSET; + int x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET; +@@ -225,9 +245,9 @@ print_to_widget (WEdit *edit, long row, int start_col, int start_col_real, + edit_move (x1 + FONT_OFFSET_X, y + FONT_OFFSET_Y); + p = line; + +- while (*p) { ++ while (p->ch) { + int style; +- int textchar; ++ mc_wchar_t textchar; + int color; + + if (cols_to_skip) { +@@ -236,9 +256,9 @@ print_to_widget (WEdit *edit, long row, int start_col, int start_col_real, + continue; + } + +- style = *p & 0xFF00; +- textchar = *p & 0xFF; +- color = *p >> 16; ++ style = p->style & 0xFF00; ++ textchar = p->ch; ++ color = p->style >> 16; + + if (style & MOD_ABNORMAL) { + /* Non-printable - use black background */ +@@ -267,8 +287,11 @@ print_to_widget (WEdit *edit, long row, int start_col, int start_col_real, + lowlevel_set_color (color); + } + } +- ++#ifdef UTF8 ++ SLsmg_write_nwchars(&textchar, 1); ++#else + addch (textchar); ++#endif + p++; + } + } +@@ -280,11 +303,11 @@ static void + edit_draw_this_line (WEdit *edit, long b, long row, long start_col, + long end_col) + { +- static unsigned int line[MAX_LINE_LEN]; +- unsigned int *p = line; ++ struct line_s line[MAX_LINE_LEN]; ++ struct line_s *p = line; + long m1 = 0, m2 = 0, q, c1, c2; + int col, start_col_real; +- unsigned int c; ++ mc_wint_t c; + int color; + int i; + +@@ -309,62 +332,88 @@ edit_draw_this_line (WEdit *edit, long b, long row, long start_col, + } + + while (col <= end_col - edit->start_col) { +- *p = 0; ++ p->ch = 0; ++ p->style = 0; + if (q == edit->curs1) +- *p |= MOD_CURSOR; ++ p->style |= MOD_CURSOR; + if (q >= m1 && q < m2) { + if (column_highlighting) { + int x; + x = edit_move_forward3 (edit, b, 0, q); + if (x >= c1 && x < c2) +- *p |= MOD_MARKED; ++ p->style |= MOD_MARKED; + } else +- *p |= MOD_MARKED; ++ p->style |= MOD_MARKED; + } + if (q == edit->bracket) +- *p |= MOD_BOLD; ++ p->style |= MOD_BOLD; + if (q >= edit->found_start + && q < edit->found_start + edit->found_len) +- *p |= MOD_BOLD; ++ p->style |= MOD_BOLD; + c = edit_get_byte (edit, q); + /* we don't use bg for mc - fg contains both */ + edit_get_syntax_color (edit, q, &color); +- *p |= color << 16; ++ p->style |= color << 16; + switch (c) { + case '\n': + col = end_col - edit->start_col + 1; /* quit */ +- *(p++) |= ' '; ++ p->ch = ' '; ++ p++; + break; + case '\t': + i = TAB_SIZE - ((int) col % TAB_SIZE); + col += i; + if (use_colors && visible_tabs) { +- c = (*p & ~MOD_CURSOR) | MOD_WHITESPACE; ++ c = (p->style & ~MOD_CURSOR) | MOD_WHITESPACE; + if (i > 2) { +- *(p++) |= '<' | MOD_WHITESPACE; +- while (--i > 1) +- *(p++) = c | '-'; +- *(p++) = c | '>'; ++ p->ch = '<'; ++ p->style |= MOD_WHITESPACE; ++ p++; ++ while (--i > 1) { ++ p->ch = '-'; ++ p->style = c; ++ p++; ++ } ++ p->ch = '>'; ++ p->style = c; ++ p++; + } else if (i > 1) { +- *(p++) |= '<' | MOD_WHITESPACE; +- *(p++) = c | '>'; +- } else +- *(p++) |= '>' | MOD_WHITESPACE; ++ p->ch = '<'; ++ p->style |= MOD_WHITESPACE; ++ p++; ++ p->ch = '>'; ++ p->style = c; ++ p++; ++ } else { ++ p->ch = '>'; ++ p->style |= MOD_WHITESPACE; ++ p++; ++ } + } else if (use_colors && visible_tws && q >= tws) { +- *p |= '.' | MOD_WHITESPACE; +- c = *(p++) & ~MOD_CURSOR; +- while (--i) +- *(p++) = c; ++ p->ch = '.'; ++ p->style |= MOD_WHITESPACE; ++ c = p->style & ~MOD_CURSOR; ++ p++; ++ while (--i) { ++ p->ch = '.'; ++ p->style = c; ++ p++; ++ } + } else { +- *p |= ' '; +- c = *(p++) & ~MOD_CURSOR; +- while (--i) +- *(p++) = c; ++ p->ch = ' '; ++ c = p->style & ~MOD_CURSOR; ++ p++; ++ while (--i) { ++ p->ch = ' '; p->style = c; ++ p++; ++ } + } + break; + case ' ': + if (use_colors && visible_tws && q >= tws) { +- *(p++) |= '.' | MOD_WHITESPACE; ++ p->ch = '.'; ++ p->style |= MOD_WHITESPACE; ++ p++; + col++; + break; + } +@@ -374,22 +423,47 @@ edit_draw_this_line (WEdit *edit, long b, long row, long start_col, + + /* Caret notation for control characters */ + if (c < 32) { +- *(p++) = '^' | MOD_ABNORMAL; +- *(p++) = (c + 0x40) | MOD_ABNORMAL; ++ p->ch = '^'; ++ p->style = MOD_ABNORMAL; ++ p++; ++ p->ch = c + 0x40; ++ p->style = MOD_ABNORMAL; + col += 2; + break; + } + if (c == 127) { +- *(p++) = '^' | MOD_ABNORMAL; +- *(p++) = '?' | MOD_ABNORMAL; ++ p->ch = '^'; ++ p->style = MOD_ABNORMAL; ++ p++; ++ p->ch = '?'; ++ p->style = MOD_ABNORMAL; ++ p++; + col += 2; + break; + } + +- if (is_printable (c)) { +- *(p++) |= c; ++#ifndef UTF8 ++ if (is_printable (c) ++#else /* UTF8 */ ++ if (iswprint (c) ++#ifdef __STDC_ISO_10646__ ++ && (c < BINARY_CHAR_OFFSET || c >= (BINARY_CHAR_OFFSET + 256)) ++#endif ++#endif /* UTF8 */ ++ ) { ++ p->ch = c; ++ p++; ++ ++#ifdef UTF8 ++ i = wcwidth(c); ++ if (i > 1) { ++ col += i - 1; ++ } ++#endif /* UTF8 */ + } else { +- *(p++) = '.' | MOD_ABNORMAL; ++ p->ch = '.'; ++ p->style = MOD_ABNORMAL; ++ p++; + } + col++; + break; +@@ -400,7 +474,7 @@ edit_draw_this_line (WEdit *edit, long b, long row, long start_col, + } else { + start_col_real = start_col = 0; + } +- *p = 0; ++ p->ch = 0; + + print_to_widget (edit, row, start_col, start_col_real, end_col, line); + } +diff --git a/edit/editkeys.c b/edit/editkeys.c +index 2cc6add..111d377 100644 +--- a/edit/editkeys.c ++++ b/edit/editkeys.c +@@ -183,10 +183,10 @@ static const edit_key_map_type common_key_map[] = { + * 'command' is one of the editor commands from editcmddef.h. + */ + int +-edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch) ++edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch) + { + int command = CK_Insert_Char; +- int char_for_insertion = -1; ++ mc_wint_t char_for_insertion = -1; + int i = 0; + int extmod = 0; + const edit_key_map_type *key_map = NULL; +@@ -243,9 +243,30 @@ edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch) + /* an ordinary insertable character */ + if (x_key < 256 && !extmod) { + int c = convert_from_input_c (x_key); ++#ifdef UTF8 ++ mbstate_t mbs; ++ int res; ++ mc_wchar_t wc; + ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ if (edit->charpoint >= MB_CUR_MAX) edit->charpoint = 0; ++ ++ edit->charbuf[edit->charpoint++] = c; ++ ++ res = mbrtowc(&wc, (char *)edit->charbuf, edit->charpoint, &mbs); ++ if (res < 0) { ++ if (res != -2) edit->charpoint = 0; /* broken multibyte char, skip */ ++ return 0; ++ } ++ edit->charpoint = 0; ++ ++ if (iswprint (wc)) { ++ char_for_insertion = wc; ++#else + if (is_printable (c)) { + char_for_insertion = c; ++#endif /* UTF8 */ + goto fin; + } + } +@@ -284,7 +305,7 @@ edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch) + *cmd = command; + *ch = char_for_insertion; + +- if (command == CK_Insert_Char && char_for_insertion == -1) { ++ if (command == CK_Insert_Char && char_for_insertion == (mc_wint_t)-1) { + /* unchanged, key has no function here */ + return 0; + } +diff --git a/edit/editwidget.c b/edit/editwidget.c +index 8ae8cf0..286a844 100644 +--- a/edit/editwidget.c ++++ b/edit/editwidget.c +@@ -333,7 +333,8 @@ edit_callback (Widget *w, widget_msg_t msg, int parm) + + case WIDGET_KEY: + { +- int cmd, ch; ++ int cmd; ++ mc_wint_t ch; + + /* The user may override the access-keys for the menu bar. */ + if (edit_translate_key (e, parm, &cmd, &ch)) { +diff --git a/edit/wordproc.c b/edit/wordproc.c +index fc16136..25a534e 100644 +--- a/edit/wordproc.c ++++ b/edit/wordproc.c +@@ -40,7 +40,12 @@ + + #define tab_width option_tab_spacing + ++#ifndef UTF8 + #define NO_FORMAT_CHARS_START "-+*\,.;:&>" ++#else /* UTF8 */ ++#define NO_FORMAT_CHARS_START L"-+*\,.;:&>" ++#endif /* UTF8 */ ++ + #define FONT_MEAN_WIDTH 1 + + static long +@@ -57,14 +62,21 @@ line_start (WEdit *edit, long line) + p = edit_move_forward (edit, p, line - l, 0); + + p = edit_bol (edit, p); ++ ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ ++ + p++; + return p; + } + + static int bad_line_start (WEdit * edit, long p) + { +- int c; ++ mc_wint_t c; ++ + c = edit_get_byte (edit, p); + if (c == '.') { /* `...' is acceptable */ + if (edit_get_byte (edit, p + 1) == '.') +@@ -78,7 +90,13 @@ static int bad_line_start (WEdit * edit, long p) + return 0; /* `---' is acceptable */ + return 1; + } ++ ++#ifndef UTF8 + if (strchr (NO_FORMAT_CHARS_START, c)) ++#else /* UTF8 */ ++ if (wcschr (NO_FORMAT_CHARS_START, c)) ++#endif /* UTF8 */ ++ + return 1; + return 0; + } +@@ -131,33 +149,37 @@ end_paragraph (WEdit *edit, int force) + i - edit->curs_line, 0)); + } + +-static unsigned char * ++static mc_wchar_t * + get_paragraph (WEdit *edit, long p, long q, int indent, int *size) + { +- unsigned char *s, *t; ++ mc_wchar_t *s, *t; + #if 0 +- t = g_malloc ((q - p) + 2 * (q - p) / option_word_wrap_line_length + +- 10); ++ t = g_malloc (((q - p) + 2 * (q - p) / option_word_wrap_line_length + ++ 10) * sizeof(mc_wchar_t)); + #else +- t = g_malloc (2 * (q - p) + 100); ++ t = g_malloc ((2 * (q - p) + 100) * sizeof(mc_wchar_t)); + #endif + if (!t) + return 0; + for (s = t; p < q; p++, s++) { + if (indent) + if (edit_get_byte (edit, p - 1) == '\n') ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ + p++; + *s = edit_get_byte (edit, p); + } +- *size = (unsigned long) s - (unsigned long) t; ++ *size = s - t; + t[*size] = '\n'; + return t; + } + +-static void strip_newlines (unsigned char *t, int size) ++static void strip_newlines (mc_wchar_t *t, int size) + { +- unsigned char *p = t; ++ mc_wchar_t *p = t; + while (size--) { + *p = *p == '\n' ? ' ' : *p; + p++; +@@ -174,7 +196,7 @@ static inline int next_tab_pos (int x) + { + return x += tab_width - x % tab_width; + } +-static int line_pixel_length (unsigned char *t, long b, int l) ++static int line_pixel_length (mc_wchar_t *t, long b, int l) + { + int x = 0, c, xn = 0; + for (;;) { +@@ -198,7 +220,7 @@ static int line_pixel_length (unsigned char *t, long b, int l) + } + + static int +-next_word_start (unsigned char *t, int q, int size) ++next_word_start (mc_wchar_t *t, int q, int size) + { + int i; + int saw_ws = 0; +@@ -222,7 +244,7 @@ next_word_start (unsigned char *t, int q, int size) + + /* find the start of a word */ + static int +-word_start (unsigned char *t, int q, int size) ++word_start (mc_wchar_t *t, int q, int size) + { + int i = q; + if (t[q] == ' ' || t[q] == '\t') +@@ -241,7 +263,7 @@ word_start (unsigned char *t, int q, int size) + } + + /* replaces ' ' with '\n' to properly format a paragraph */ +-static void format_this (unsigned char *t, int size, int indent) ++static void format_this (mc_wchar_t *t, int size, int indent) + { + int q = 0, ww; + strip_newlines (t, size); +@@ -269,7 +291,7 @@ static void format_this (unsigned char *t, int size, int indent) + } + } + +-static void replace_at (WEdit * edit, long q, int c) ++static void replace_at (WEdit * edit, long q, mc_wint_t c) + { + edit_cursor_move (edit, q - edit->curs1); + edit_delete (edit); +@@ -278,18 +300,27 @@ static void replace_at (WEdit * edit, long q, int c) + + /* replaces a block of text */ + static void +-put_paragraph (WEdit * edit, unsigned char *t, long p, int indent, int size) ++put_paragraph (WEdit * edit, mc_wchar_t *t, long p, int indent, int size) + { + long cursor; +- int i, c = 0; ++ int i; ++ mc_wchar_t c = 0; + cursor = edit->curs1; + if (indent) ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ + p++; + for (i = 0; i < size; i++, p++) { + if (i && indent) { + if (t[i - 1] == '\n' && c == '\n') { ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ + p++; + } else if (t[i - 1] == '\n') { + long curs; +@@ -301,7 +332,11 @@ put_paragraph (WEdit * edit, unsigned char *t, long p, int indent, int size) + p = edit->curs1; + } else if (c == '\n') { + edit_cursor_move (edit, p - edit->curs1); ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) { ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) { ++#endif /* UTF8 */ + edit_delete (edit); + if (cursor > edit->curs1) + cursor--; +@@ -334,7 +369,7 @@ format_paragraph (WEdit *edit, int force) + { + long p, q; + int size; +- unsigned char *t; ++ mc_wchar_t *t; + int indent = 0; + if (option_word_wrap_line_length < 2) + return; +@@ -348,13 +383,21 @@ format_paragraph (WEdit *edit, int force) + return; + if (!force) { + int i; ++#ifndef UTF8 + if (strchr (NO_FORMAT_CHARS_START, *t)) { ++#else /* UTF8 */ ++ if (wcschr (NO_FORMAT_CHARS_START, *t)) { ++#endif /* UTF8 */ + g_free (t); + return; + } + for (i = 0; i < size - 1; i++) { + if (t[i] == '\n') { ++#ifndef UTF8 + if (strchr (NO_FORMAT_CHARS_START "\t ", t[i + 1])) { ++#else /* UTF8 */ ++ if (wcschr (NO_FORMAT_CHARS_START "\t", t[i + 1])) { ++#endif /* UTF8 */ + g_free (t); + return; + } +diff --git a/po/ru.po b/po/ru.po +index 5ee11d0..76c3a6b 100644 +--- a/po/ru.po ++++ b/po/ru.po +@@ -3650,5 +3650,30 @@ msgstr " + #~ " ÔÅÐÅÒØ ÈÒÁÎÑÔÓÑ × ËÁÔÁÌÏÇÅ ~/.mc, ÓÔÁÒÙÅ \n" + #~ " ÆÁÊÌÙ ÓÅÊÞÁÓ ÔÕÄÁ ÐÅÒÅÍÅÝÅÎÙ\n" + +-#~ msgid "%s bytes in %d files" +-#~ msgstr "%s ÂÁÊÔ × %d ÆÁÊÌÁÈ" ++#: messages for recode patch ++msgid "Panel &codepage" ++msgstr "ëÏÄÉÒÏ×ËÁ ÐÁÎÅÌÉ" ++ ++msgid " Choose codepage " ++msgstr " ÷ÙÂÅÒÉÔÅ ËÏÄÉÒÏ×ËÕ" ++ ++msgid " Choose panel codepage " ++msgstr " ÷ÙÂÅÒÉÔÅ ËÏÄÉÒÏ×ËÕ ÐÁÎÅÌÉ " ++ ++msgid " Choose default FTP codepage " ++msgstr " ÷ÙÂÅÒÉÔÅ ËÏÄÉÒÏ×ËÕ FTP ÐÏ ÕÍÏÌÞÁÎÉÀ " ++ ++msgid "FTP default codepage:" ++msgstr "ëÏÄÉÒÏ×ËÁ FTP ÐÏ ÕÍÏÌÞÁÎÉÀ:" ++ ++msgid "Recode file names:" ++msgstr "ðÅÒÅËÏÄÉÒÏ×ÁÔØ ÉÍÅÎÁ:" ++ ++msgid "Recoding works only with COPY/MOVE operation" ++msgstr "ðÅÒÅËÏÄÉÒÏ×ËÁ ÒÁÂÏÔÁÅÔ ÔÏÌØËÏ ÄÌÑ ÏÐÅÒÁÃÉÊ ËÏÐÉÒÏ×ÁÎÉÑ/ÐÅÒÅÍÅÝÅÎÉÑ" ++ ++msgid " Choose "FROM" codepage for COPY/MOVE operaion " ++msgstr" ÷ÙÂÅÒÉÔÅ ÎÁÞÁÌØÎÕÀ ËÏÄÉÒÏ×ËÕ ÄÌÑ ÏÐÅÒÁÃÉÉ ËÏÐÉÒÏ×ÁÎÉÑ/ÐÅÒÅÍÅÝÅÎÉÑ " ++ ++msgid " Choose "TO" codepage for COPY/MOVE operaion " ++msgstr" ÷ÙÂÅÒÉÔÅ ËÏÎÅÞÎÕÀ ËÏÄÉÒÏ×ËÕ ÄÌÑ ÏÐÅÒÁÃÉÉ ËÏÐÉÒÏ×ÁÎÉÑ/ÐÅÒÅÍÅÝÅÎÉÑ " +diff --git a/src/Makefile.am b/src/Makefile.am +index d43b198..90bd1b1 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -41,7 +41,8 @@ endif + mc_LDADD = $(EDITLIB) $(SLANGLIB) $(VFSLIB) \ + $(INTLLIBS) $(GLIB_LIBS) $(MCLIBS) $(LIBICONV) + +-CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h ++CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h \ ++ recode.c recode.h + + SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \ + chmod.c chmod.h chown.c chown.h cmd.c cmd.h color.c color.h \ +@@ -58,7 +59,7 @@ SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \ + menu.c menu.h mountlist.c mountlist.h mouse.c mouse.h myslang.h \ + option.c option.h panel.h panelize.c panelize.h poptalloca.h \ + popt.c poptconfig.c popt.h popthelp.c poptint.h poptparse.c \ +- profile.c profile.h regex.c rxvt.c screen.c setup.c setup.h \ ++ profile.c profile.h regex.c rxvt.c screen.c screen.h setup.c setup.h \ + slint.c subshell.c subshell.h textconf.c textconf.h \ + tree.c tree.h treestore.c treestore.h timefmt.h tty.c tty.h user.c \ + user.h util.c util.h utilunix.c view.c view.h vfsdummy.h widget.c \ +diff --git a/src/achown.c b/src/achown.c +index 72ddcad..f1f3024 100644 +--- a/src/achown.c ++++ b/src/achown.c +@@ -585,6 +585,12 @@ init_chown_advanced (void) + b_att[2] = button_new (XTRACT (6)); + b_user = button_new (XTRACT (5)); + b_group = button_new (XTRACT (4)); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1); ++ b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1); ++ } ++#endif + + add_widget (ch_dlg, b_group); + add_widget (ch_dlg, b_user); +diff --git a/src/boxes.c b/src/boxes.c +index 0ff72d4..82a0e1b 100644 +--- a/src/boxes.c ++++ b/src/boxes.c +@@ -53,6 +53,7 @@ + #ifdef HAVE_CHARSET + #include "charsets.h" + #include "selcodepage.h" ++#include "recode.h" + #endif + + #ifdef USE_NETCODE +@@ -154,23 +155,23 @@ display_init (int radio_sel, char *init_text, int _check_status, + display_title = _(display_title); + for (i = 0; i < LIST_TYPES; i++) { + displays[i] = _(displays[i]); +- if ((l = strlen (displays[i])) > maxlen) ++ if ((l = mbstrlen (displays[i])) > maxlen) + maxlen = l; + } + +- i = strlen (ok_button) + 5; +- l = strlen (cancel_button) + 3; ++ i = mbstrlen (ok_button) + 5; ++ l = mbstrlen (cancel_button) + 3; + l = max (i, l); + + i = maxlen + l + 16; + if (i > DISPLAY_X) + DISPLAY_X = i; + +- i = strlen (user_mini_status) + 13; ++ i = mbstrlen (user_mini_status) + 13; + if (i > DISPLAY_X) + DISPLAY_X = i; + +- i = strlen (display_title) + 10; ++ i = mbstrlen (display_title) + 10; + if (i > DISPLAY_X) + DISPLAY_X = i; + +@@ -290,20 +291,20 @@ sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first) + int maxlen = 0; + for (i = SORT_TYPES - 1; i >= 0; i--) { + sort_orders_names[i] = _(sort_orders[i].sort_name); +- r = strlen (sort_orders_names[i]); ++ r = mbstrlen (sort_orders_names[i]); + if (r > maxlen) + maxlen = r; + } + + check_pos = maxlen + 9; + +- r = strlen (reverse_label) + 4; +- i = strlen (case_label) + 4; ++ r = mbstrlen (reverse_label) + 4; ++ i = mbstrlen (case_label) + 4; + if (i > r) + r = i; + +- l = strlen (ok_button) + 6; +- i = strlen (cancel_button) + 4; ++ l = mbstrlen (ok_button) + 6; ++ i = mbstrlen (cancel_button) + 4; + if (i > l) + l = i; + +@@ -312,7 +313,7 @@ sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first) + if (i > SORT_X) + SORT_X = i; + +- i = strlen (sort_title) + 6; ++ i = mbstrlen (sort_title) + 6; + if (i > SORT_X) + SORT_X = i; + +@@ -413,7 +414,7 @@ confirm_box (void) + while (i--) + { + conf_widgets [i].text = _(conf_widgets [i].text); +- l1 = strlen (conf_widgets [i].text) + 3; ++ l1 = mbstrlen (conf_widgets [i].text) + 3; + if (l1 > maxlen) + maxlen = l1; + } +@@ -428,8 +429,8 @@ confirm_box (void) + * And this for the case when buttons with some space to the right + * do not fit within 2/6 + */ +- l1 = strlen (conf_widgets [0].text) + 3; +- i = strlen (conf_widgets [1].text) + 5; ++ l1 = mbstrlen (conf_widgets [0].text) + 3; ++ i = mbstrlen (conf_widgets [1].text) + 5; + if (i > l1) + l1 = i; + +@@ -459,8 +460,8 @@ confirm_box (void) + } + } + +-#define DISPY 11 +-#define DISPX 46 ++#define DISPY 13 ++#define DISPX 35 + + + #ifndef HAVE_CHARSET +@@ -502,11 +503,11 @@ display_bits_box (void) + { + display_widgets [i].text = _(display_widgets[i].text); + display_bits_str [i] = _(display_bits_str [i]); +- l1 = strlen (display_bits_str [i]); ++ l1 = mbstrlen (display_bits_str [i]); + if (l1 > maxlen) + maxlen = l1; + } +- l1 = strlen (display_widgets [2].text); ++ l1 = mbstrlen (display_widgets [2].text); + if (l1 > maxlen) + maxlen = l1; + +@@ -514,8 +515,8 @@ display_bits_box (void) + display_bits.xlen = (maxlen + 5) * 6 / 4; + + /* See above confirm_box */ +- l1 = strlen (display_widgets [0].text) + 3; +- i = strlen (display_widgets [1].text) + 5; ++ l1 = mbstrlen (display_widgets [0].text) + 3; ++ i = mbstrlen (display_widgets [1].text) + 5; + if (i > l1) + l1 = i; + +@@ -556,23 +557,58 @@ display_bits_box (void) + + + static int new_display_codepage; ++static int new_ftp_codepage; + +-static WLabel *cplabel; + static WCheck *inpcheck; + ++static WButton *cpbutton; ++static WButton *cpbutton_ftp; ++ + static int + sel_charset_button (int action) + { + const char *cpname; + char buf[64]; +- new_display_codepage = select_charset (new_display_codepage, 1); ++ new_display_codepage = select_charset (new_display_codepage, 1, _(" Choose input codepage ")); + cpname = (new_display_codepage < 0) + ? _("Other 8 bit") + : codepages[new_display_codepage].name; + + /* avoid strange bug with label repainting */ +- g_snprintf (buf, sizeof (buf), "%-27s", cpname); +- label_set_text (cplabel, buf); ++ sprintf( buf, "%s", cpname ); ++ button_set_text (cpbutton, buf); ++ ++ if(new_display_codepage<0) new_ftp_codepage=-1; ++ cpname = (new_ftp_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_ftp_codepage ].name; ++ sprintf( buf, "%s", cpname ); ++ button_set_text (cpbutton_ftp, buf); ++ ++ return 0; ++} ++ ++static int sel_charset_button_ftp(int action) { ++ char *cpname, buf[64]; ++ if(new_display_codepage>0) { ++ new_ftp_codepage = select_charset(new_ftp_codepage, 0, _(" Choose default FTP codepage ")); ++ cpname = (new_display_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_display_codepage ].name; ++ sprintf( buf, "%s", cpname ); ++ button_set_text( cpbutton, buf ); ++ cpname = (new_ftp_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_ftp_codepage ].name; ++ sprintf( buf, "%s", cpname ); ++ button_set_text( cpbutton_ftp, buf ); ++ } ++ else { ++ message( 1, _(" Warning "), ++ _("To use this feature select your codepage in\n" ++ "Setup / Display Bits dialog!\n" ++ "Do not forget to save options." )); ++ } + return 0; + } + +@@ -594,9 +630,6 @@ init_disp_bits_box (void) + cpname = (new_display_codepage < 0) + ? _("Other 8 bit") + : codepages[new_display_codepage].name; +- cplabel = label_new (4, 4, cpname); +- add_widget (dbits_dlg, cplabel); +- + add_widget (dbits_dlg, + button_new (DISPY - 3, DISPX / 2 + 3, B_CANCEL, + NORMAL_BUTTON, _("&Cancel"), 0)); +@@ -605,13 +638,30 @@ init_disp_bits_box (void) + 0)); + + inpcheck = +- check_new (6, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input")); ++ check_new (8, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input")); + add_widget (dbits_dlg, inpcheck); + +- cpname = _("&Select"); +- add_widget (dbits_dlg, +- button_new (4, DISPX - 8 - strlen (cpname), B_USER, +- NORMAL_BUTTON, cpname, sel_charset_button)); ++ ++ add_widget( dbits_dlg, label_new( 5, 4, _("FTP default codepage:"))); ++ if(n_codepages>0) { ++ cpname = (new_display_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_display_codepage ].name; ++ } ++ else cpname= _("Other 8 bit"); ++ cpbutton=button_new(4, 5, B_USER, ++ NORMAL_BUTTON, cpname, sel_charset_button); ++ ++ if(n_codepages>0) { ++ cpname = (new_ftp_codepage < 0) ++ ? _("Other 8 bit") ++ : codepages[ new_ftp_codepage ].name; ++ } ++ else cpname= _("Other 8 bit"); ++ cpbutton_ftp=button_new(6, 5, B_USER, ++ NORMAL_BUTTON, cpname, sel_charset_button_ftp); ++ add_widget( dbits_dlg, cpbutton_ftp); ++ add_widget (dbits_dlg, cpbutton); + + return dbits_dlg; + } +@@ -621,6 +671,7 @@ display_bits_box (void) + { + Dlg_head *dbits_dlg; + new_display_codepage = display_codepage; ++ new_ftp_codepage = ftp_codepage; + + application_keypad_mode (); + dbits_dlg = init_disp_bits_box (); +@@ -641,6 +692,17 @@ display_bits_box (void) + && display_codepage != 1) ? 128 : 160; + #endif + use_8th_bit_as_meta = !(inpcheck->state & C_BOOL); ++ ++ ftp_codepage=new_ftp_codepage; ++ if(display_codepage<=0) { ++ panel_reset_codepage(left_panel); ++ paint_dir(left_panel); ++ display_mini_info(left_panel); ++ panel_reset_codepage(right_panel); ++ paint_dir(right_panel); ++ display_mini_info(right_panel); ++ } ++ + } + destroy_dlg (dbits_dlg); + repaint_screen (); +@@ -821,7 +883,7 @@ cd_dialog (void) + quick_widgets [1].y_divisions = + quick_widgets [0].y_divisions = Quick_input.ylen = 5; + +- len = strlen (quick_widgets [1].text); ++ len = mbstrlen (quick_widgets [1].text); + + quick_widgets [0].relative_x = + quick_widgets [1].relative_x + len + 1; +@@ -980,7 +1042,7 @@ jobs_cmd (void) + { + job_buttons [i].name = _(job_buttons [i].name); + +- len = strlen (job_buttons [i].name) + 4; ++ len = mbstrlen (job_buttons [i].name) + 4; + JOBS_X = max (JOBS_X, startx + len + 3); + + job_buttons [i].xpos = startx; +@@ -989,7 +1051,7 @@ jobs_cmd (void) + + /* Last button - Ok a.k.a. Cancel :) */ + job_buttons [n_buttons - 1].xpos = +- JOBS_X - strlen (job_buttons [n_buttons - 1].name) - 7; ++ JOBS_X - mbstrlen (job_buttons [n_buttons - 1].name) - 7; + + i18n_flag = 1; + } +@@ -1047,7 +1109,7 @@ vfs_smb_get_authinfo (const char *host, const char *share, const char *domain, + + while (i--) + { +- l1 = strlen (labs [i] = _(labs [i])); ++ l1 = mbstrlen (labs [i] = _(labs [i])); + if (l1 > maxlen) + maxlen = l1; + } +@@ -1057,7 +1119,7 @@ vfs_smb_get_authinfo (const char *host, const char *share, const char *domain, + + for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; ) + { +- l1 += strlen (buts [i] = _(buts [i])); ++ l1 += mbstrlen (buts [i] = _(buts [i])); + } + l1 += 15; + if (l1 > dialog_x) +@@ -1066,7 +1128,7 @@ vfs_smb_get_authinfo (const char *host, const char *share, const char *domain, + ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */ + istart = dialog_x - 3 - ilen; + +- b2 = dialog_x - (strlen(buts[1]) + 6); ++ b2 = dialog_x - (mbstrlen(buts[1]) + 6); + + i18n_flag = 1; + } +diff --git a/src/charsets.c b/src/charsets.c +index f2e69e0..bac7b3b 100644 +--- a/src/charsets.c ++++ b/src/charsets.c +@@ -123,8 +123,6 @@ free_codepages_list (void) + } + } + +-#define OTHER_8BIT "Other_8_bit" +- + const char * + get_codepage_id (int n) + { +@@ -143,7 +141,7 @@ get_codepage_index (const char *id) + return -1; + } + +-static char ++char + translate_character (iconv_t cd, char c) + { + char outbuf[4], *obuf; +diff --git a/src/charsets.h b/src/charsets.h +index b701d5a..0698dc2 100644 +--- a/src/charsets.h ++++ b/src/charsets.h +@@ -6,6 +6,7 @@ + #define UNKNCHAR '\001' + + #define CHARSETS_INDEX "mc.charsets" ++#define OTHER_8BIT "Other_8_bit" + + extern int n_codepages; + +@@ -19,6 +20,10 @@ struct codepage_desc { + + extern struct codepage_desc *codepages; + ++#include <iconv.h> ++extern char translate_character(iconv_t cd, char c); ++extern char errbuf[255]; ++ + const char *get_codepage_id (int n); + int get_codepage_index (const char *id); + int load_codepages_list (void); +diff --git a/src/cmd.c b/src/cmd.c +index f82165c..e24d563 100644 +--- a/src/cmd.c ++++ b/src/cmd.c +@@ -73,6 +73,10 @@ + # include "../edit/edit.h" + #endif + ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif ++ + /* If set and you don't have subshell support,then C-o will give you a shell */ + int output_starts_shell = 0; + +@@ -353,6 +357,9 @@ void + mkdir_cmd (void) + { + char *dir, *absdir; ++#ifdef HAVE_CHARSET ++ char *recoded_dir; ++#endif + + dir = + input_expand_dialog (_("Create a new Directory"), +@@ -363,8 +370,16 @@ mkdir_cmd (void) + + if (dir[0] == '/' || dir[0] == '~') + absdir = g_strdup (dir); +- else ++ else { ++#ifdef HAVE_CHARSET ++ recoded_dir=g_strdup(dir); ++ my_translate_string(dir,strlen(dir), recoded_dir,current_panel->tr_table_input); ++ absdir = mhl_str_dir_plus_file (current_panel->cwd, recoded_dir); ++ g_free(recoded_dir); ++#else + absdir = mhl_str_dir_plus_file (current_panel->cwd, dir); ++#endif ++ } + + save_cwds_stat (); + if (my_mkdir (absdir, 0777) == 0) { +diff --git a/src/dialog.c b/src/dialog.c +index f8467b9..43d117f 100644 +--- a/src/dialog.c ++++ b/src/dialog.c +@@ -167,7 +167,7 @@ common_dialog_repaint (struct Dlg_head *h) + + if (h->title) { + attrset (DLG_HOT_NORMALC (h)); +- dlg_move (h, space, (h->cols - strlen (h->title)) / 2); ++ dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2); + addstr (h->title); + } + } +diff --git a/src/file.c b/src/file.c +index 6400e3e..056aa11 100644 +--- a/src/file.c ++++ b/src/file.c +@@ -79,6 +79,9 @@ + #include "../vfs/vfs-impl.h" + + /* }}} */ ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif + + /* Hack: the vfs code should not rely on this */ + #define WITH_FULL_PATHS 1 +@@ -167,15 +170,20 @@ static const char * + do_transform_source (FileOpContext *ctx, const char *source) + { + size_t j, k, l, len; +- const char *fnsource = x_basename (source); ++ char *fnsource = g_strdup (x_basename (source)); + int next_reg; + enum CaseConvs case_conv = NO_CONV; + static char fntarget[MC_MAXPATHLEN]; + ++#ifdef UTF8 ++ fix_utf8(fnsource); ++#endif ++ + len = strlen (fnsource); + j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs); + if (j != len) { + transform_error = FILE_SKIP; ++ g_free (fnsource); + return NULL; + } + for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) { +@@ -225,6 +233,7 @@ do_transform_source (FileOpContext *ctx, const char *source) + || ctx->regs.start[next_reg] < 0) { + message (1, MSG_ERROR, _(" Invalid target mask ")); + transform_error = FILE_ABORT; ++ g_free(fnsource); + return NULL; + } + for (l = (size_t) ctx->regs.start[next_reg]; +@@ -239,6 +248,7 @@ do_transform_source (FileOpContext *ctx, const char *source) + } + } + fntarget[k] = 0; ++ g_free(fnsource); + return fntarget; + } + +@@ -922,7 +932,12 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *d, int toplevel, + } + /* Dive into subdir if exists */ + if (toplevel && ctx->dive_into_subdirs) { ++#ifdef HAVE_CHARSET ++ /*FIXME: Use here somehow mhl_str_dir_plus_file */ ++ dest_dir = concat_dir_and_recoded_fname(d, x_basename (s), ctx); ++#else + dest_dir = mhl_str_dir_plus_file (d, x_basename (s)); ++#endif + } else { + dest_dir = g_strdup (d); + goto dont_mkdir; +@@ -972,7 +987,11 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *d, int toplevel, + + (*ctx->stat_func) (path, &buf); + if (S_ISDIR (buf.st_mode)) { ++#ifdef HAVE_CHARSET ++ mdpath = concat_dir_and_recoded_fname(dest_dir, next->d_name, ctx); ++#else + mdpath = mhl_str_dir_plus_file (dest_dir, next->d_name); ++#endif + /* + * From here, we just intend to recursively copy subdirs, not + * the double functionality of copying different when the target +@@ -983,7 +1002,11 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *d, int toplevel, + parent_dirs, progress_count, progress_bytes); + g_free (mdpath); + } else { ++#ifdef HAVE_CHARSET ++ dest_file=concat_dir_and_recoded_fname(dest_dir, x_basename(path),ctx); ++#else + dest_file = mhl_str_dir_plus_file (dest_dir, x_basename (path)); ++#endif + return_status = copy_file_file (ctx, path, dest_file, 1, + progress_count, progress_bytes, 0); + g_free (dest_file); +@@ -1173,7 +1196,12 @@ move_dir_dir (FileOpContext *ctx, const char *s, const char *d, + destdir = g_strdup (d); + move_over = 1; + } else ++#ifdef HAVE_CHARSET ++ destdir = concat_dir_and_recoded_fname(d, x_basename (s), ctx); ++#else + destdir = mhl_str_dir_plus_file (d, x_basename (s)); ++#endif ++ + + if (sbuf.st_dev == dbuf.st_dev && sbuf.st_ino == dbuf.st_ino) { + int msize = COLS - 36; +@@ -1700,13 +1728,13 @@ panel_operate_generate_prompt (const WPanel *panel, const int operation, + *dp = '\0'; + + if (single_source) { +- i = fmd_xlen - strlen (format_string) - 4; ++ i = fmd_xlen - mbstrlen (format_string) - 4; + g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, + name_trunc (single_source, i)); + } else { + g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, + panel->marked); +- i = strlen (cmd_buf) + 6 - fmd_xlen; ++ i = mbstrlen (cmd_buf) + 6 - fmd_xlen; + if (i > 0) { + fmd_xlen += i; + fmd_init_i18n (TRUE); /* to recalculate positions of child widgets */ +@@ -1901,7 +1929,12 @@ panel_operate (void *source_panel, FileOperation operation, + if (temp == NULL) { + value = transform_error; + } else { ++#ifdef HAVE_CHARSET ++ char *temp2 = concat_dir_and_recoded_fname (dest, temp, ctx); ++#else + char *temp2 = mhl_str_dir_plus_file (dest, temp); ++#endif ++ + g_free (dest); + dest = temp2; + temp = NULL; +@@ -1995,7 +2028,12 @@ panel_operate (void *source_panel, FileOperation operation, + if (temp == NULL) + value = transform_error; + else { ++#ifdef HAVE_CHARSET ++ char *temp2 = concat_dir_and_recoded_fname(dest, temp, ctx); ++#else + char *temp2 = mhl_str_dir_plus_file (dest, temp); ++#endif ++ + + source_with_path = mhl_shell_unescape_buf(source_with_path); + temp2 = mhl_shell_unescape_buf(temp2); +diff --git a/src/filegui.c b/src/filegui.c +index 441adb7..e9920d0 100644 +--- a/src/filegui.c ++++ b/src/filegui.c +@@ -66,6 +66,11 @@ + #include "filegui.h" + #include "key.h" /* get_event */ + #include "util.h" /* strip_password() */ ++#include "tty.h" ++ ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif + + /* }}} */ + +@@ -564,8 +569,8 @@ init_replace (FileOpContext *ctx, enum OperationMode mode) + * longest of "Overwrite..." labels + * (assume "Target date..." are short enough) + */ +- l1 = max (strlen (rd_widgets[6].text), +- strlen (rd_widgets[11].text)); ++ l1 = max (mbstrlen (rd_widgets[6].text), ++ mbstrlen (rd_widgets[11].text)); + + /* longest of button rows */ + i = sizeof (rd_widgets) / sizeof (rd_widgets[0]); +@@ -576,7 +581,7 @@ init_replace (FileOpContext *ctx, enum OperationMode mode) + l2 = max (l2, l); + l = 0; + } +- l += strlen (rd_widgets[i].text) + 4; ++ l += mbstrlen (rd_widgets[i].text) + 4; + } + } + l2 = max (l2, l); /* last row */ +@@ -594,12 +599,12 @@ init_replace (FileOpContext *ctx, enum OperationMode mode) + l = l1; + } + rd_widgets[i].xpos = l; +- l += strlen (rd_widgets[i].text) + 4; ++ l += mbstrlen (rd_widgets[i].text) + 4; + } + } + /* Abort button is centered */ + rd_widgets[1].xpos = +- (rd_xlen - strlen (rd_widgets[1].text) - 3) / 2; ++ (rd_xlen - mbstrlen (rd_widgets[1].text) - 3) / 2; + } + #endif /* ENABLE_NLS */ + +@@ -618,7 +623,7 @@ init_replace (FileOpContext *ctx, enum OperationMode mode) + + ADD_RD_LABEL (ui, 0, + name_trunc (ui->replace_filename, +- rd_trunc - strlen (rd_widgets[0].text)), 0); ++ rd_trunc - mbstrlen (rd_widgets[0].text)), 0); + ADD_RD_BUTTON (1); + + ADD_RD_BUTTON (2); +@@ -721,57 +726,79 @@ file_progress_real_query_replace (FileOpContext *ctx, + } + } + ++#ifdef HAVE_CHARSET ++#define FMDY 15 ++#else + #define FMDY 13 ++#endif ++ + #define FMD_XLEN 64 + extern int fmd_xlen; + static QuickWidget fmd_widgets[] = { + +-#define FMCB0 FMDC +-#define FMCB12 0 +-#define FMCB11 1 +- /* follow symlinks and preserve Attributes must be the first */ +- {quick_checkbox, 3, 64, 8, FMDY, N_("preserve &Attributes"), 9, 0, +- 0 /* &op_preserve */ , 0, NULL}, +- {quick_checkbox, 3, 64, 7, FMDY, N_("follow &Links"), 7, 0, +- 0 /* &file_mask_op_follow_links */ , 0, NULL}, +- {quick_label, 3, 64, 5, FMDY, N_("to:"), 0, 0, 0, 0, NULL}, +- {quick_checkbox, 37, 64, 4, FMDY, N_("&Using shell patterns"), 0, 0, +- 0 /* &source_easy_patterns */ , 0, NULL}, +- {quick_input, 3, 64, 3, FMDY, "", 58, +- 0, 0, 0, "input-def"}, +-#define FMDI1 4 +-#define FMDI2 5 +-#define FMDC 3 +- {quick_input, 3, 64, 6, FMDY, "", 58, 0, +- 0, 0, "input2"}, +-#define FMDI0 6 +- {quick_label, 3, 64, 2, FMDY, "", 0, 0, 0, 0, NULL}, +-#define FMBRGT 7 +- {quick_button, 42, 64, 9, FMDY, N_("&Cancel"), 0, B_CANCEL, 0, 0, +- NULL}, +-#undef SKIP ++#ifdef HAVE_CHARSET ++ #define Y_OK 12 ++#else ++ #define Y_OK 9 ++#endif ++ + #ifdef WITH_BACKGROUND +-# define SKIP 5 +-# define FMCB21 11 +-# define FMCB22 10 +-# define FMBLFT 9 +-# define FMBMID 8 +- {quick_button, 25, 64, 9, FMDY, N_("&Background"), 0, B_USER, 0, 0, +- NULL}, +-#else /* WITH_BACKGROUND */ +-# define SKIP 4 +-# define FMCB21 10 +-# define FMCB22 9 +-# define FMBLFT 8 +-# undef FMBMID ++ #define ADD 0 ++#else ++ #define ADD -1 + #endif +- {quick_button, 14, 64, 9, FMDY, N_("&OK"), 0, B_ENTER, 0, 0, NULL}, +- {quick_checkbox, 42, 64, 8, FMDY, N_("&Stable Symlinks"), 0, 0, +- 0 /* &file_mask_stable_symlinks */ , 0, NULL}, +- {quick_checkbox, 31, 64, 7, FMDY, N_("&Dive into subdir if exists"), 0, +- 0, +- 0 /* &dive_into_subdirs */ , 0, NULL}, +- NULL_QuickWidget ++ ++ #define FM_STAB_SYM 0 ++ #define FM_DIVE_INTO_SUBDIR 1 ++ #define FM_PRES_ATTR 2 ++ #define FM_FOLLOW_LINKS 3 ++ #define FM_DST_INPUT 4 ++ #define FM_DST_TITLE 5 ++ #define FM_USING_SHELL_PATT 6 ++ #define FM_SRC_INPUT 7 ++ #define FM_SRC_TITLE 8 ++ #define FM_CANCEL 9 ++#ifdef WITH_BACKGROUND ++ #define FM_BKGND 10 ++#endif ++ #define FM_OK 11+ADD ++#ifdef HAVE_CHARSET ++ #define FM_TO_CODEPAGE 12+ADD ++ #define FM_FROM_CODEPAGE 13+ADD ++ #define FM_RECODE_TITLE 14+ADD ++ #define FM_RECODE_ARROW 15+ADD ++#endif // HAVE_CHARSET ++ ++ ++#ifdef HAVE_CHARSET ++ #define SKIP 10 ++ #define B_FROM B_USER+1 ++ #define B_TO B_USER+2 ++#else ++ #define SKIP 10 ++#endif ++ ++ {quick_checkbox, 42,64, 8, FMDY, N_("&Stable Symlinks"),0,0,0,0,"stab-sym"}, ++ {quick_checkbox, 31,64, 7, FMDY, N_("&Dive into subdir if exists"),0,0,0,0,"dive"}, ++ {quick_checkbox, 3, 64, 8, FMDY, N_("preserve &Attributes"),9,0,0,0,"preserve"}, ++ {quick_checkbox, 3, 64, 7, FMDY, N_("follow &Links"),7,0,0,0,"follow"}, ++ {quick_input, 3, 64, 6, FMDY, "", 58, 0, 0, 0, "input2"}, ++ {quick_label, 3, 64, 5, FMDY, N_("to:"), 0, 0, 0, 0, "to"}, ++ {quick_checkbox, 37,64, 4, FMDY, N_("&Using shell patterns"),0,0, 0,0,"us-sh"}, ++ {quick_input, 3, 64, 3, FMDY, "", 58, 0, 0, 0, "input-def"}, ++ {quick_label, 3, 64, 2, FMDY, "", 0, 0, 0, 0, "ql"}, ++ {quick_button, 42,64, Y_OK, FMDY, N_("&Cancel"), 0, B_CANCEL, 0,0, "cancel"}, ++#ifdef WITH_BACKGROUND ++ {quick_button, 25,64, Y_OK, FMDY, N_("&Background"), 0, B_USER, 0,0, "back"}, ++#endif ++ {quick_button, 14,64, Y_OK, FMDY, N_("&OK"), 0, B_ENTER, 0, 0, "ok"}, ++#ifdef HAVE_CHARSET ++ {quick_button, 46,64, 10, FMDY,"to codepage", 0, B_TO, 0, 0, "ql"}, ++ {quick_button, 25,64, 10, FMDY, "from codepage", 0, B_FROM, 0, 0, "ql"}, ++ {quick_label, 3, 64, 10, FMDY, N_("Recode file names:"), 0, 0, 0, 0, "ql"}, ++ {quick_label, 42,64, 10, FMDY, "->", 0, 0, 0, 0, "ql"}, ++#endif ++ {0} + }; + + static int +@@ -805,48 +832,48 @@ fmd_init_i18n (int force) + if (fmd_widgets[i].text[0] != '\0') + fmd_widgets[i].text = _(fmd_widgets[i].text); + +- len = strlen (fmd_widgets[FMCB11].text) +- + strlen (fmd_widgets[FMCB21].text) + 15; ++ len = mbstrlen (fmd_widgets[FM_FOLLOW_LINKS].text) ++ + mbstrlen (fmd_widgets[FM_DIVE_INTO_SUBDIR].text) + 15; + fmd_xlen = max (fmd_xlen, len); + +- len = strlen (fmd_widgets[FMCB12].text) +- + strlen (fmd_widgets[FMCB22].text) + 15; ++ len = mbstrlen (fmd_widgets[FM_PRES_ATTR].text) ++ + mbstrlen (fmd_widgets[FM_STAB_SYM].text) + 15; + fmd_xlen = max (fmd_xlen, len); + +- len = strlen (fmd_widgets[FMBRGT].text) +- + strlen (fmd_widgets[FMBLFT].text) + 11; ++ len = mbstrlen (fmd_widgets[FM_CANCEL].text) ++ + mbstrlen (fmd_widgets[FM_OK].text) + 11; + +-#ifdef FMBMID +- len += strlen (fmd_widgets[FMBMID].text) + 6; ++#ifdef FM_BKGND ++ len += mbstrlen (fmd_widgets[FM_BKGND].text) + 6; + #endif + + fmd_xlen = max (fmd_xlen, len + 4); + + len = (fmd_xlen - (len + 6)) / 2; +- i = fmd_widgets[FMBLFT].relative_x = len + 3; +- i += strlen (fmd_widgets[FMBLFT].text) + 8; ++ i = fmd_widgets[FM_OK].relative_x = len + 3; ++ i += mbstrlen (fmd_widgets[FM_OK].text) + 8; + +-#ifdef FMBMID +- fmd_widgets[FMBMID].relative_x = i; +- i += strlen (fmd_widgets[FMBMID].text) + 6; ++#ifdef FM_BKGND ++ fmd_widgets[FM_BKGND].relative_x = i; ++ i += mbstrlen (fmd_widgets[FM_BKGND].text) + 6; + #endif + +- fmd_widgets[FMBRGT].relative_x = i; ++ fmd_widgets[FM_CANCEL].relative_x = i; + + #define chkbox_xpos(i) \ +- fmd_widgets [i].relative_x = fmd_xlen - strlen (fmd_widgets [i].text) - 6 ++ fmd_widgets [i].relative_x = fmd_xlen - mbstrlen (fmd_widgets [i].text) - 6 + +- chkbox_xpos (FMCB0); +- chkbox_xpos (FMCB21); +- chkbox_xpos (FMCB22); ++ chkbox_xpos (FM_USING_SHELL_PATT); ++ chkbox_xpos (FM_DIVE_INTO_SUBDIR); ++ chkbox_xpos (FM_STAB_SYM); + + if (fmd_xlen != FMD_XLEN) { + i = sizeof (fmd_widgets) / sizeof (fmd_widgets[0]) - 1; + while (i--) + fmd_widgets[i].x_divisions = fmd_xlen; + +- fmd_widgets[FMDI1].hotkey_pos = +- fmd_widgets[FMDI2].hotkey_pos = fmd_xlen - 6; ++ fmd_widgets[FM_SRC_INPUT].hotkey_pos = ++ fmd_widgets[FM_DST_INPUT].hotkey_pos = fmd_xlen - 6; + } + #undef chkbox_xpos + +@@ -856,7 +883,7 @@ fmd_init_i18n (int force) + + char * + file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, +- const char *def_text, int only_one, int *do_background) ++ const char *def_text_orig, int only_one, int *do_background) + { + int source_easy_patterns = easy_patterns; + char *source_mask, *orig_mask, *dest_dir, *tmpdest; +@@ -865,20 +892,32 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, + struct stat buf; + int val; + QuickDialog Quick_input; +- ++ char *def_text; ++#ifdef HAVE_CHARSET ++ char *errmsg; ++#endif + g_return_val_if_fail (ctx != NULL, NULL); ++ ++ def_text = g_strdup(def_text_orig); ++ + #if 0 + message (1, __FUNCTION__, "text = `%s' \n def_text = `%s'", text, + def_text); + #endif ++ ++#ifdef UTF8 ++ fix_utf8(def_text); ++#endif ++ + fmd_init_i18n (FALSE); + + /* Set up the result pointers */ + +- fmd_widgets[FMCB12].result = &ctx->op_preserve; +- fmd_widgets[FMCB11].result = &ctx->follow_links; +- fmd_widgets[FMCB22].result = &ctx->stable_symlinks; +- fmd_widgets[FMCB21].result = &ctx->dive_into_subdirs; ++ fmd_widgets[FM_PRES_ATTR].result = &ctx->op_preserve; ++ fmd_widgets[FM_FOLLOW_LINKS].result = &ctx->follow_links; ++ fmd_widgets[FM_STAB_SYM].result = &ctx->stable_symlinks; ++ fmd_widgets[FM_DIVE_INTO_SUBDIR].result = &ctx->dive_into_subdirs; ++ + + /* filter out a possible password from def_text */ + def_text_secure = strip_password (g_strdup (def_text), 1); +@@ -886,8 +925,9 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, + /* Create the dialog */ + + ctx->stable_symlinks = 0; +- fmd_widgets[FMDC].result = &source_easy_patterns; +- fmd_widgets[FMDI1].text = easy_patterns ? "*" : "^\(.*\)$"; ++ fmd_widgets[FM_USING_SHELL_PATT].result = &source_easy_patterns; ++ fmd_widgets[FM_SRC_INPUT].text = easy_patterns ? "*" : "^\(.*\)$"; ++ + Quick_input.xlen = fmd_xlen; + Quick_input.xpos = -1; + Quick_input.title = op_names[operation]; +@@ -895,19 +935,37 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, + Quick_input.ylen = FMDY; + Quick_input.i18n = 1; + Quick_input.widgets = fmd_widgets; +- fmd_widgets[FMDI0].text = text; +- fmd_widgets[FMDI2].text = def_text_secure; +- fmd_widgets[FMDI2].str_result = &dest_dir; +- fmd_widgets[FMDI1].str_result = &source_mask; ++ fmd_widgets[FM_SRC_TITLE].text = text; ++ fmd_widgets[FM_DST_INPUT].text = def_text_secure; ++ fmd_widgets[FM_DST_INPUT].str_result = &dest_dir; ++ fmd_widgets[FM_SRC_INPUT].str_result = &source_mask; + + *do_background = 0; ++ ++#ifdef HAVE_CHARSET ++ ctx->from_codepage=current_panel->src_codepage; ++ ctx->to_codepage=left_panel->src_codepage; ++ if (left_panel) { ++ ctx->to_codepage=left_panel->src_codepage; ++ if( (current_panel==left_panel) && right_panel ) ctx->to_codepage=right_panel->src_codepage; ++ } ++#endif ++ + ask_file_mask: + ++#ifdef HAVE_CHARSET ++ if(operation!=OP_COPY && operation!=OP_MOVE) { ++ ctx->from_codepage=-1; ++ ctx->to_codepage=-1; ++ } ++ fmd_widgets[FM_FROM_CODEPAGE].text=get_codepage_id(ctx->from_codepage); ++ fmd_widgets[FM_TO_CODEPAGE].text=get_codepage_id(ctx->to_codepage); ++#endif ++ + if ((val = quick_dialog_skip (&Quick_input, SKIP)) == B_CANCEL) { + g_free (def_text_secure); + return 0; + } +- g_free (def_text_secure); + + if (ctx->follow_links) + ctx->stat_func = mc_stat; +@@ -929,6 +987,8 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, + orig_mask = source_mask; + if (!dest_dir || !*dest_dir) { + g_free (source_mask); ++ g_free (def_text_secure); ++ g_free(def_text); + return dest_dir; + } + if (source_easy_patterns) { +@@ -982,5 +1042,48 @@ file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, + } + if (val == B_USER) + *do_background = 1; ++#ifdef HAVE_CHARSET ++ if(val == B_FROM) { ++ if(operation==OP_COPY || operation==OP_MOVE) { ++ if(display_codepage<=0) { ++ message( 1, _(" Warning "), ++ _("To use this feature select your codepage in\n" ++ "Setup / Display Bits dialog!\n" ++ "Do not forget to save options." )); ++ goto ask_file_mask; ++ } ++ ctx->from_codepage=select_charset(ctx->from_codepage,0, ++ _(" Choose "FROM" codepage for COPY/MOVE operaion ")); ++ } ++ else ++ message(1,"Warning",_("Recoding works only with COPY or MOVE operation")); ++ goto ask_file_mask; ++ } ++ if(val == B_TO) { ++ if(operation==OP_COPY || operation==OP_MOVE) { ++ if(display_codepage<=0) { ++ message( 1, _(" Warning "), ++ _("To use this feature select your codepage in\n" ++ "Setup / Display Bits dialog!\n" ++ "Do not forget to save options." )); ++ goto ask_file_mask; ++ } ++ ctx->to_codepage=select_charset(ctx->to_codepage,0, ++ _(" Choose "TO" codepage for COPY/MOVE operaion ")); ++ } ++ else ++ message(1,"Warning",_("Recoding works only with COPY or MOVE operation")); ++ goto ask_file_mask; ++ } ++ ++ errmsg=my_init_tt(ctx->to_codepage,ctx->from_codepage,ctx->tr_table); ++ if(errmsg) { ++ my_reset_tt(ctx->tr_table,256); ++ message( 1, MSG_ERROR, "%s", errmsg); ++ } ++#endif ++ ++ g_free(def_text_secure); ++ g_free(def_text); + return dest_dir; + } +diff --git a/src/fileopctx.c b/src/fileopctx.c +index ad02cf4..904b7f8 100644 +--- a/src/fileopctx.c ++++ b/src/fileopctx.c +@@ -26,8 +26,12 @@ + #include <unistd.h> + + #include "global.h" +-#include "fileopctx.h" + ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif ++ ++#include "fileopctx.h" + + /** + * file_op_context_new: +@@ -54,6 +58,12 @@ file_op_context_new (FileOperation op) + ctx->umask_kill = 0777777; + ctx->erase_at_end = TRUE; + ++#ifdef HAVE_CHARSET ++ ctx->from_codepage=-1; ++ ctx->to_codepage=-1; ++ my_reset_tt(ctx->tr_table,256); ++#endif ++ + return ctx; + } + +diff --git a/src/fileopctx.h b/src/fileopctx.h +index d2de6a9..339ab42 100644 +--- a/src/fileopctx.h ++++ b/src/fileopctx.h +@@ -108,6 +108,14 @@ typedef struct FileOpContext { + /* User interface data goes here */ + + void *ui; ++ ++#ifdef HAVE_CHARSET ++ /* Recode data */ ++ int from_codepage, to_codepage; ++ unsigned char tr_table[256]; ++ unsigned char recode_buf[MC_MAXPATHLEN]; ++#endif ++ + } FileOpContext; + + +diff --git a/src/find.c b/src/find.c +index 9ff1ef7..daa1d5b 100644 +--- a/src/find.c ++++ b/src/find.c +@@ -219,7 +219,7 @@ find_parameters (char **start_dir, char **pattern, char **content) + int l1, maxlen = 0; + + while (i--) { +- l1 = strlen (labs[i] = _(labs[i])); ++ l1 = mbstrlen (labs[i] = _(labs[i])); + if (l1 > maxlen) + maxlen = l1; + } +@@ -228,7 +228,7 @@ find_parameters (char **start_dir, char **pattern, char **content) + FIND_X = i; + + for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) { +- l1 += strlen (buts[i] = _(buts[i])); ++ l1 += mbstrlen (buts[i] = _(buts[i])); + } + l1 += 21; + if (l1 > FIND_X) +@@ -237,8 +237,8 @@ find_parameters (char **start_dir, char **pattern, char **content) + ilen = FIND_X - 7 - maxlen; /* for the case of very long buttons :) */ + istart = FIND_X - 3 - ilen; + +- b1 = b0 + strlen (buts[0]) + 7; +- b2 = FIND_X - (strlen (buts[2]) + 6); ++ b1 = b0 + mbstrlen (buts[0]) + 7; ++ b2 = FIND_X - (mbstrlen (buts[2]) + 6); + + i18n_flag = 1; + case_label = _(case_label); +@@ -865,7 +865,7 @@ setup_gui (void) + if (!i18n_flag) { + register int i = sizeof (fbuts) / sizeof (fbuts[0]); + while (i--) +- fbuts[i].len = strlen (fbuts[i].text = _(fbuts[i].text)) + 3; ++ fbuts[i].len = mbstrlen (fbuts[i].text = _(fbuts[i].text)) + 3; + fbuts[2].len += 2; /* DEFPUSH_BUTTON */ + i18n_flag = 1; + } +@@ -1030,7 +1030,7 @@ find_file (char *start_dir, char *pattern, char *content, char **dirname, + + if (!next_free) /* first turn i.e clean old list */ + panel_clean_dir (current_panel); +- list->list[next_free].fnamelen = strlen (name); ++ list->list[next_free].fnamelen = mbstrlen (name); + list->list[next_free].fname = name; + list->list[next_free].f.marked = 0; + list->list[next_free].f.link_to_dir = link_to_dir; +diff --git a/src/help.c b/src/help.c +index 3261cbb..2f5bdac 100644 +--- a/src/help.c ++++ b/src/help.c +@@ -416,10 +416,28 @@ static void help_show (Dlg_head *h, const char *paint_start) + #ifndef HAVE_SLANG + addch (acs_map [c]); + #else ++#if defined(UTF8) && SLANG_VERSION < 20000 ++ SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]); ++#else + SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c); ++#endif /* UTF8 */ + #endif ++ } else { ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ int len; ++ mbstate_t mbs; ++ wchar_t wc; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs); ++ if (len <= 0) len = 1; /* skip broken multibyte chars */ ++ ++ SLsmg_write_nwchars(&wc, 1); ++ p += len - 1; + } else ++#endif + addch (c); ++ } + col++; + break; + } +@@ -772,6 +790,12 @@ interactive_display (const char *filename, const char *node) + message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile, + unix_error_string (errno)); + } ++ else ++ { ++ char *conv = utf8_to_local(data); ++ g_free(data); ++ data = conv; ++ } + + if (!filename) + g_free (hlpfile); +diff --git a/src/hotlist.c b/src/hotlist.c +index 737c9c1..74f9568 100644 +--- a/src/hotlist.c ++++ b/src/hotlist.c +@@ -566,7 +566,7 @@ init_i18n_stuff(int list_type, int cols) + + row = hotlist_but [i].y; + ++count [row]; +- len [row] += strlen (hotlist_but [i].text) + 5; ++ len [row] += mbstrlen (hotlist_but [i].text) + 5; + if (hotlist_but [i].flags == DEFPUSH_BUTTON) + len [row] += 2; + } +@@ -591,12 +591,12 @@ init_i18n_stuff(int list_type, int cols) + /* not first int the row */ + if (!strcmp (hotlist_but [i].text, cancel_but)) + hotlist_but [i].x = +- cols - strlen (hotlist_but [i].text) - 13; ++ cols - mbstrlen (hotlist_but [i].text) - 13; + else + hotlist_but [i].x = cur_x [row]; + } + +- cur_x [row] += strlen (hotlist_but [i].text) + 2 ++ cur_x [row] += mbstrlen (hotlist_but [i].text) + 2 + + (hotlist_but [i].flags == DEFPUSH_BUTTON ? 5 : 3); + } + } +@@ -837,7 +837,7 @@ static void add_widgets_i18n(QuickWidget* qw, int len) + for (i = 0; i < 3; i++) + { + qw [i].text = _(qw [i].text); +- l[i] = strlen (qw [i].text) + 3; ++ l[i] = mbstrlen (qw [i].text) + 3; + } + space = (len - 4 - l[0] - l[1] - l[2]) / 4; + +@@ -886,7 +886,7 @@ add_new_entry_input (const char *header, const char *text1, const char *text2, + + msglen(text1, &lines1, &cols1); + msglen(text2, &lines2, &cols2); +- len = max ((int) strlen (header), cols1); ++ len = max ((int) mbstrlen (header), cols1); + len = max (len, cols2) + 4; + len = max (len, 64); + +@@ -982,7 +982,7 @@ add_new_group_input (const char *header, const char *label, char **result) + #endif /* ENABLE_NLS */ + + msglen (label, &lines, &cols); +- len = max ((int) strlen (header), cols) + 4; ++ len = max ((int) mbstrlen (header), cols) + 4; + len = max (len, 64); + + #ifdef ENABLE_NLS +@@ -1038,7 +1038,7 @@ void add2hotlist_cmd (void) + { + char *prompt, *label; + const char *cp = _("Label for "%s":"); +- int l = strlen (cp); ++ int l = mbstrlen (cp); + char *label_string = g_strdup (current_panel->cwd); + + strip_password (label_string, 1); +diff --git a/src/layout.c b/src/layout.c +index 9f3616f..c759348 100644 +--- a/src/layout.c ++++ b/src/layout.c +@@ -367,36 +367,36 @@ init_layout (void) + + while (i--) { + s_split_direction[i] = _(s_split_direction[i]); +- l1 = strlen (s_split_direction[i]) + 7; ++ l1 = mbstrlen (s_split_direction[i]) + 7; + if (l1 > first_width) + first_width = l1; + } + + for (i = 0; i <= 8; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (l1 > first_width) + first_width = l1; + } + +- l1 = strlen (title1) + 1; ++ l1 = mbstrlen (title1) + 1; + if (l1 > first_width) + first_width = l1; + +- l1 = strlen (title2) + 1; ++ l1 = mbstrlen (title2) + 1; + if (l1 > first_width) + first_width = l1; + + +- second_width = strlen (title3) + 1; ++ second_width = mbstrlen (title3) + 1; + for (i = 0; i < 6; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (l1 > second_width) + second_width = l1; + } + if (console_flag) { +- l1 = strlen (output_lines_label) + 13; ++ l1 = mbstrlen (output_lines_label) + 13; + if (l1 > second_width) + second_width = l1; + } +@@ -410,14 +410,14 @@ init_layout (void) + * + * Now the last thing to do - properly space buttons... + */ +- l1 = 11 + strlen (ok_button) /* 14 - all brackets and inner space */ +- +strlen (save_button) /* notice: it is 3 char less because */ +- +strlen (cancel_button); /* of '&' char in button text */ ++ l1 = 11 + mbstrlen (ok_button) /* 14 - all brackets and inner space */ ++ +mbstrlen (save_button) /* notice: it is 3 char less because */ ++ +mbstrlen (cancel_button); /* of '&' char in button text */ + + i = (first_width + second_width - l1) / 4; + b1 = 5 + i; +- b2 = b1 + strlen (ok_button) + i + 6; +- b3 = b2 + strlen (save_button) + i + 4; ++ b2 = b1 + mbstrlen (ok_button) + i + 6; ++ b3 = b2 + mbstrlen (save_button) + i + 4; + + i18n_layt_flag = 1; + } +@@ -681,7 +681,7 @@ setup_panels (void) + panel_do_cols (0); + panel_do_cols (1); + +- promptl = strlen (prompt); ++ promptl = mbstrlen (prompt); + + widget_set_size (&the_menubar->widget, 0, 0, 1, COLS); + +diff --git a/src/learn.c b/src/learn.c +index dff560c..cc6ec93 100644 +--- a/src/learn.c ++++ b/src/learn.c +@@ -238,7 +238,7 @@ init_learn (void) + learn_but[0].x = 78 / 2 + 4; + + learn_but[1].text = _(learn_but[1].text); +- learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9); ++ learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9); + + learn_title = _(learn_title); + i18n_flag = 1; +diff --git a/src/main.c b/src/main.c +index db26945..edf6a03 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -82,6 +82,7 @@ + + #ifdef HAVE_CHARSET + #include "charsets.h" ++#include "recode.h" + #endif /* HAVE_CHARSET */ + + #ifdef USE_VFS +@@ -98,6 +99,7 @@ + /* The structures for the panels */ + WPanel *left_panel = NULL; + WPanel *right_panel = NULL; ++WPanel* ret_panel=NULL; + + /* The pointer to the tree */ + WTree *the_tree = NULL; +@@ -276,6 +278,9 @@ int midnight_shutdown = 0; + /* The user's shell */ + const char *shell = NULL; + ++/* Is the LANG UTF-8 ? */ ++gboolean is_utf8 = FALSE; ++ + /* mc_home: The home of MC */ + char *mc_home = NULL; + +@@ -587,6 +592,7 @@ _do_panel_cd (WPanel *panel, const char *new_dir, enum cd_enum cd_type) + } + directory = *new_dir ? new_dir : home_dir; + ++ ret_panel=panel; + if (mc_chdir (directory) == -1) { + strcpy (panel->cwd, olddir); + g_free (olddir); +@@ -706,7 +712,7 @@ load_prompt (int fd, void *unused) + int prompt_len; + + tmp_prompt = strip_ctrl_codes (subshell_prompt); +- prompt_len = strlen (tmp_prompt); ++ prompt_len = mbstrlen (tmp_prompt); + + /* Check for prompts too big */ + if (COLS > 8 && prompt_len > COLS - 8) { +@@ -808,6 +814,10 @@ static menu_entry LeftMenu[] = { + {' ', N_("&Quick view C-x q"), 'Q', quick_view_cmd}, + {' ', N_("&Info C-x i"), 'I', info_cmd}, + {' ', N_("&Tree"), 'T', tree_cmd}, ++#ifdef HAVE_CHARSET ++ {' ', "", ' ', 0}, ++ {' ', N_("Panel &codepage"), 'C', fnc_l_cmd}, ++#endif + {' ', "", ' ', 0}, + {' ', N_("&Sort order..."), 'S', sort_cmd}, + {' ', "", ' ', 0}, +@@ -832,6 +842,10 @@ static menu_entry RightMenu[] = { + {' ', N_("&Quick view C-x q"), 'Q', quick_view_cmd}, + {' ', N_("&Info C-x i"), 'I', info_cmd}, + {' ', N_("&Tree"), 'T', tree_cmd}, ++#ifdef HAVE_CHARSET ++ {' ', "", ' ', 0}, ++ {' ', N_("Panel &codepage"), 'C', fnc_r_cmd}, ++#endif + {' ', "", ' ', 0}, + {' ', N_("&Sort order..."), 'S', sort_cmd}, + {' ', "", ' ', 0}, +@@ -1614,7 +1628,11 @@ update_xterm_title_path (void) + if (xterm_flag && xterm_title) { + p = s = g_strdup (strip_home_and_password (current_panel->cwd)); + do { ++#ifndef UTF8 + if (!is_printable ((unsigned char) *s)) ++#else /* UTF8 */ ++ if (*(unsigned char *)s < ' ') ++#endif /* UTF8 */ + *s = '?'; + } while (*++s); + if (!alternate_plus_minus) +@@ -2122,6 +2140,16 @@ handle_args (int argc, char *argv[]) + int + main (int argc, char *argv[]) + { ++ /* Check whether we have UTF-8 locale */ ++ char *lang = getenv("LANG"); ++ size_t len = 0; ++ ++ if ( lang ) ++ len = strlen(lang); ++ ++ if ( len >= 5 && !strcasecmp(&lang[len-5],"UTF-8") ) ++ is_utf8 = TRUE; ++ + /* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */ + setlocale (LC_ALL, ""); + bindtextdomain ("mc", LOCALEDIR); +diff --git a/src/main.h b/src/main.h +index 3f3c695..fca81e7 100644 +--- a/src/main.h ++++ b/src/main.h +@@ -69,6 +69,7 @@ extern int alternate_plus_minus; + extern int only_leading_plus_minus; + extern int output_starts_shell; + extern int midnight_shutdown; ++extern gboolean is_utf8; + extern char cmd_buf [512]; + extern const char *shell; + +diff --git a/src/menu.c b/src/menu.c +index f291071..862eea8 100644 +--- a/src/menu.c ++++ b/src/menu.c +@@ -23,6 +23,7 @@ + #include <string.h> + + #include <sys/types.h> ++#include <wchar.h> + + #include "global.h" + #include "tty.h" +@@ -54,35 +55,95 @@ create_menu (const char *name, menu_entry *entries, int count, const char *help_ + { + Menu *menu; + const char *cp; ++ int wlen = 0; ++ mbstate_t s; + + menu = (Menu *) g_malloc (sizeof (*menu)); + menu->count = count; + menu->max_entry_len = 20; + menu->entries = entries; ++ menu->name = g_strdup (name); ++ menu_scan_hotkey (menu); ++#ifdef UTF8 ++ menu->wentries = NULL; ++ menu->wname = NULL; ++ if (SLsmg_Is_Unicode) { ++ const char *str = menu->name; ++ memset (&s, 0, sizeof (s)); ++ wlen = mbsrtowcs (NULL, &str, -1, &s); ++ if (wlen > 0) ++ ++wlen; ++ else { ++ wlen = 0; ++ memset (&s, 0, sizeof (s)); ++ } ++ } ++#endif + + if (entries != (menu_entry*) NULL) { + register menu_entry* mp; + for (mp = entries; count--; mp++) { + if (mp->text[0] != '\0') { ++ int len; + #ifdef ENABLE_NLS + mp->text = _(mp->text); + #endif /* ENABLE_NLS */ + cp = strchr (mp->text,'&'); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ len = mbstrlen(mp->text) + 1; ++ wlen += len; ++ menu->max_entry_len = max (len - 1, menu->max_entry_len); ++ } else ++#endif ++ len = strlen (mp->text); + + if (cp != NULL && *(cp+1) != '\0') { + mp->hot_key = tolower ((unsigned char) *(cp+1)); +- menu->max_entry_len = max ((int) (strlen (mp->text) - 1), +- menu->max_entry_len); ++ menu->max_entry_len = max (len - 1, menu->max_entry_len); + } else { +- menu->max_entry_len = max ((int) strlen (mp->text), +- menu->max_entry_len); ++ menu->max_entry_len = max (len, menu->max_entry_len); + } + } + } + } + +- menu->name = g_strdup (name); +- menu_scan_hotkey(menu); ++#ifdef UTF8 ++ if (wlen) { ++ wchar_t *wp; ++ const char *str; ++ int len; ++ ++ menu->wentries = (wchar_t **) ++ g_malloc (sizeof (wchar_t *) * menu->count ++ + wlen * sizeof (wchar_t)); ++ wp = (wchar_t *) (menu->wentries + menu->count); ++ str = menu->name; ++ len = mbsrtowcs (wp, &str, wlen, &s); ++ if (len > 0) { ++ menu->wname = wp; ++ wlen -= len + 1; ++ wp += len + 1; ++ } else ++ memset (&s, 0, sizeof (s)); ++ if (menu->entries != NULL) ++ for (count = 0; count < menu->count; ++count) ++ if (menu->entries[count].text[0] != '\0') { ++ str = menu->entries[count].text; ++ menu->wentries[count] = wp; ++ len = mbsrtowcs (wp, &str, wlen, &s); ++ if (len > 0) { ++ wlen -= len + 1; ++ wp += len + 1; ++ } else { ++ memset (&s, 0, sizeof (s)); ++ *wp++ = L'\0'; ++ --wlen; ++ } ++ } ++ } ++#endif ++ + menu->start_x = 0; + menu->help_node = g_strdup (help_node); + return menu; +@@ -113,8 +174,26 @@ static void menubar_paint_idx (WMenu *menubar, int idx, int color) + const char *text; + + addch((unsigned char)menu->entries [idx].first_letter); +- for (text = menu->entries [idx].text; *text; text++) +- { ++#ifdef UTF8 ++ if (menu->wentries) { ++ wchar_t *wtext, *wp; ++ ++ for (wtext = wp = menu->wentries [idx]; *wtext; wtext++) { ++ if (*wtext == L'&') { ++ if (wtext > wp) ++ SLsmg_write_nwchars (wp, wtext - wp); ++ attrset (color == MENU_SELECTED_COLOR ? ++ MENU_HOTSEL_COLOR : MENU_HOT_COLOR); ++ SLsmg_write_nwchars (++wtext, 1); ++ attrset (color); ++ wp = wtext + 1; ++ } ++ } ++ if (wtext > wp) ++ SLsmg_write_nwchars (wp, wtext - wp); ++ } else ++#endif ++ for (text = menu->entries [idx].text; *text; text++) { + if (*text != '&') + addch(*text); + else { +@@ -123,7 +202,7 @@ static void menubar_paint_idx (WMenu *menubar, int idx, int color) + addch(*(++text)); + attrset(color); + } +- } ++ } + } + widget_move (&menubar->widget, y, x + 1); + } +@@ -169,6 +248,12 @@ static void menubar_draw (WMenu *menubar) + if (menubar->active) + attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR); + widget_move (&menubar->widget, 0, menubar->menu [i]->start_x); ++#ifdef UTF8 ++ if (menubar->menu [i]->wname) ++ SLsmg_write_nwchars (menubar->menu [i]->wname, ++ wcslen (menubar->menu [i]->wname)); ++ else ++#endif + tty_printf ("%s", menubar->menu [i]->name); + } + +@@ -494,7 +579,13 @@ menubar_arrange(WMenu* menubar) + + for (i = 0; i < items; i++) + { +- int len = strlen(menubar->menu[i]->name); ++ int len; ++#ifdef UTF8 ++ if (menubar->menu[i]->wname) ++ len = wcslen (menubar->menu[i]->wname); ++ else ++#endif ++ len = strlen(menubar->menu[i]->name); + menubar->menu[i]->start_x = start_x; + start_x += len + gap; + } +@@ -507,7 +598,13 @@ menubar_arrange(WMenu* menubar) + for (i = 0; i < items; i++) + { + /* preserve length here, to be used below */ +- gap -= (menubar->menu[i]->start_x = strlen(menubar->menu[i]->name)); ++#ifdef UTF8 ++ if (menubar->menu[i]->wname) ++ menubar->menu[i]->start_x = wcslen (menubar->menu[i]->wname); ++ else ++#endif ++ menubar->menu[i]->start_x = strlen (menubar->menu[i]->name); ++ gap -= menubar->menu[i]->start_x; + } + + gap /= (items - 1); +@@ -531,6 +628,9 @@ menubar_arrange(WMenu* menubar) + void + destroy_menu (Menu *menu) + { ++#ifdef UTF8 ++ g_free (menu->wentries); ++#endif + g_free (menu->name); + g_free (menu->help_node); + g_free (menu); +diff --git a/src/menu.h b/src/menu.h +index e3e043e..8f52351 100644 +--- a/src/menu.h ++++ b/src/menu.h +@@ -21,6 +21,8 @@ typedef struct Menu { + menu_entry *entries; + int start_x; /* position relative to menubar start */ + char *help_node; ++ wchar_t **wentries; ++ wchar_t *wname; + } Menu; + + extern int menubar_visible; +diff --git a/src/myslang.h b/src/myslang.h +index 17057e7..774b310 100644 +--- a/src/myslang.h ++++ b/src/myslang.h +@@ -11,6 +11,16 @@ + #endif /* HAVE_SLANG_SLANG_H */ + #endif + ++#if SLANG_VERSION >= 20000 ++#define UTF8 1 ++#define SLsmg_Is_Unicode SLsmg_is_utf8_mode() ++void SLsmg_write_nwchars(wchar_t *s, size_t n); ++#endif ++ ++#ifdef UTF8 ++# include <wchar.h> ++#endif ++ + enum { + KEY_BACKSPACE = 400, + KEY_END, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, +diff --git a/src/option.c b/src/option.c +index 2898266..b22c5f2 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -124,12 +124,12 @@ init_configure (void) + title2 = _(" Pause after run... "); + title3 = _(" Other options "); + +- first_width = strlen (title1) + 1; +- second_width = strlen (title3) + 1; ++ first_width = mbstrlen (title1) + 1; ++ second_width = mbstrlen (title3) + 1; + + for (i = 0; check_options[i].text; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (i >= OTHER_OPTIONS) { + if (l1 > first_width) + first_width = l1; +@@ -142,23 +142,23 @@ init_configure (void) + i = PAUSE_OPTIONS; + while (i--) { + pause_options[i] = _(pause_options[i]); +- l1 = strlen (pause_options[i]) + 7; ++ l1 = mbstrlen (pause_options[i]) + 7; + if (l1 > first_width) + first_width = l1; + } + +- l1 = strlen (title2) + 1; ++ l1 = mbstrlen (title2) + 1; + if (l1 > first_width) + first_width = l1; + +- l1 = 11 + strlen (ok_button) +- + strlen (save_button) +- + strlen (cancel_button); ++ l1 = 11 + mbstrlen (ok_button) ++ + mbstrlen (save_button) ++ + mbstrlen (cancel_button); + + i = (first_width + second_width - l1) / 4; + b1 = 5 + i; +- b2 = b1 + strlen (ok_button) + i + 6; +- b3 = b2 + strlen (save_button) + i + 4; ++ b2 = b1 + mbstrlen (ok_button) + i + 6; ++ b3 = b2 + mbstrlen (save_button) + i + 4; + + i18n_config_flag = 1; + } +diff --git a/src/panel.h b/src/panel.h +index 844f359..05ec163 100644 +--- a/src/panel.h ++++ b/src/panel.h +@@ -72,6 +72,19 @@ typedef struct WPanel { + + int searching; + char search_buffer [256]; ++ ++#ifdef HAVE_CHARSET ++ int src_codepage; ++ unsigned char tr_table[256], tr_table_input[256]; ++#endif ++ ++#ifdef USE_VFS ++ #ifdef HAVE_CHARSET ++ int ret_codepage; ++ #endif ++ int is_return; ++ char retdir[MC_MAXPATHLEN]; ++#endif + } WPanel; + + WPanel *panel_new (const char *panel_name); +@@ -97,6 +110,7 @@ int set_panel_formats (WPanel *p); + extern WPanel *left_panel; + extern WPanel *right_panel; + extern WPanel *current_panel; ++extern WPanel* ret_panel; + + void try_to_select (WPanel *panel, const char *name); + +diff --git a/src/panelize.c b/src/panelize.c +index ef80619..d932241 100644 +--- a/src/panelize.c ++++ b/src/panelize.c +@@ -129,7 +129,7 @@ init_panelize (void) + i = sizeof (panelize_but) / sizeof (panelize_but[0]); + while (i--) { + panelize_but[i].text = _(panelize_but[i].text); +- maxlen += strlen (panelize_but[i].text) + 5; ++ maxlen += mbstrlen (panelize_but[i].text) + 5; + } + maxlen += 10; + +@@ -138,11 +138,11 @@ init_panelize (void) + panelize_cols = max (panelize_cols, maxlen); + + panelize_but[2].x = +- panelize_but[3].x + strlen (panelize_but[3].text) + 7; ++ panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7; + panelize_but[1].x = +- panelize_but[2].x + strlen (panelize_but[2].text) + 5; ++ panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5; + panelize_but[0].x = +- panelize_cols - strlen (panelize_but[0].text) - 8 - BX; ++ panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX; + + #endif /* ENABLE_NLS */ + +diff --git a/src/recode.c b/src/recode.c +new file mode 100644 +index 0000000..b485dfc +--- /dev/null ++++ b/src/recode.c +@@ -0,0 +1,153 @@ ++#include "recode.h" ++#ifdef HAVE_CHARSET ++ ++char *lang; ++char lang_codepage_name[256]; ++int lang_codepage; ++ ++int ftp_codepage=-1; ++ ++// recode buffer for displaying file names ++unsigned char recode_buf[MC_MAXPATHLEN]; ++ ++WPanel* recode_panel; ++ ++//--- get codepage from $LANG ++void get_locale_codepage() { ++ char* a; ++ char* b; ++ int len; ++ ++ lang=getenv("LANG"); ++ if(!lang) { ++ strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT)); ++ lang_codepage=-1; ++ return; ++ } ++ ++ a=strchr(lang,'.'); ++ if(!a) { ++ strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT)); ++ lang_codepage=-1; ++ return; ++ } ++ ++a; ++ ++ b=strchr(lang,'@'); ++ if(!b) b=lang+strlen(lang); ++ ++ len=b-a; ++ if(len>=sizeof(lang_codepage_name)) len=sizeof(lang_codepage_name)-1; ++ ++ memcpy(lang_codepage_name,a, len); ++ lang_codepage_name[len]='\0'; ++ lang_codepage=get_codepage_index(lang_codepage_name); ++ if(lang_codepage<0) strncpy(lang_codepage_name,OTHER_8BIT, sizeof(OTHER_8BIT)); ++} ++ ++//--- reset translation table ++void my_reset_tt(unsigned char *table,int n) { ++ int i; ++ for(i=0;i<n;i++) table[i]=i; ++} ++ ++//--- reset panel codepage ++void panel_reset_codepage(WPanel *p) { ++ p->src_codepage=-1; ++ my_reset_tt(p->tr_table,256); ++ my_reset_tt(p->tr_table_input,256); ++} ++ ++//--- Initialize translation table ++// i need this function because init_translation_table from ++// charsets.c fills only fixed translation tables conv_displ and conv_input ++//--- ++char* my_init_tt( int from, int to, unsigned char *table) { ++ int i; ++ iconv_t cd; ++ char *cpfrom, *cpto; ++ ++ if(from < 0 || to < 0 || from == to) { ++ my_reset_tt(table,256); ++ return NULL; ++ } ++ my_reset_tt(table,128); ++ cpfrom=codepages[from ].id; ++ cpto=codepages[to].id; ++ cd=iconv_open(cpfrom, cpto); ++ if(cd==(iconv_t)-1) { ++ snprintf(errbuf, 255, _("Cannot translate from %s to %s"), cpfrom, cpto); ++ return errbuf; ++ } ++ for(i=128; i<=255; ++i) table[i] = translate_character(cd, i); ++ iconv_close(cd); ++ return NULL; ++} ++ ++//--- Translate string from one codepage to another ++void my_translate_string(unsigned char *s1,int l1, unsigned char *s2, unsigned char *table) { ++ int i=0; ++ if(!s1) return; ++ while(i<l1) { ++ s2[i]=table[s1[i]]; ++ i++; ++ } ++ s2[i]=0; ++} ++ ++//--- Recode filename and concat in to dir ++char* concat_dir_and_recoded_fname(const char *dir, const char *fname, FileOpContext *ctx) { ++ int i = strlen (dir); ++ ++ my_translate_string((unsigned char*)fname,strlen(fname),ctx->recode_buf,ctx->tr_table); ++ if (dir [i-1] == PATH_SEP) ++ return g_strconcat (dir, ctx->recode_buf, NULL); ++ else ++ return g_strconcat (dir, PATH_SEP_STR, ctx->recode_buf, NULL); ++ return 0; ++} ++ ++ ++//--- Internal handler for "Panel codepage" ++static void fnc_cmd(WPanel *p) { ++ char *errmsg; ++ if(display_codepage > 0) { ++ p->src_codepage=select_charset(p->src_codepage, 0, _(" Choose panel codepage ")); ++ errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg); ++ } ++ errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input); ++ if (errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ paint_dir(p); ++ show_dir(p); ++ display_mini_info(p); ++ } ++ else { ++ message( 1, _(" Warning "), ++ _("To use this feature select your codepage in\n" ++ "Setup / Display Bits dialog!\n" ++ "Do not forget to save options." )); ++ } ++} ++ ++//--- Menu handlers for "Panel codepage" for left and right panel menu ++ ++void fnc_l_cmd() { ++ fnc_cmd(left_panel); ++} ++ ++void fnc_r_cmd() { ++ fnc_cmd(right_panel); ++} ++ ++//--- screen handler for "Panel codepage" ++void fnc_c_cmd(WPanel *panel) { ++ fnc_cmd(current_panel); ++} ++ ++#endif //HAVE_CHARSET +diff --git a/src/recode.h b/src/recode.h +new file mode 100644 +index 0000000..8e817ea +--- /dev/null ++++ b/src/recode.h +@@ -0,0 +1,48 @@ ++#ifndef __RECODE_H__ ++#define __RECODE_H__ ++#include <config.h> ++#ifdef HAVE_CHARSET ++ ++#include <stdio.h> ++#include <locale.h> ++#include <iconv.h> ++ ++#include "global.h" ++#include "wtools.h" ++#include "panel.h" ++#include "charsets.h" ++#include "selcodepage.h" ++#include "screen.h" ++#include "main.h" ++#include "fileopctx.h" ++ ++extern char *lang; ++extern char lang_codepage_name[256]; ++extern int lang_codepage; ++ ++extern int ftp_codepage; ++ ++// recode buffer for displaying file names ++extern unsigned char recode_buf[MC_MAXPATHLEN]; ++extern WPanel* recode_panel; ++ ++//--- get codepage from $LANG ++extern void get_locale_codepage(); ++ ++//--- reset translation table ++extern void my_reset_tt(unsigned char *table,int n); ++//--- reset panel codepage ++extern void panel_reset_codepage(WPanel *p); ++//--- Initialize translation table ++extern char* my_init_tt( int from, int to, unsigned char *table); ++//--- Translate string from one codepage to another ++extern void my_translate_string(unsigned char *s1,int l1, unsigned char *s2, unsigned char *table); ++//--- Recode filename and concat in to dir ++extern char* concat_dir_and_recoded_fname(const char *dir, const char *fname, FileOpContext *ctx); ++//--- handlers for "Panel codepage" ++extern void fnc_l_cmd(); ++extern void fnc_r_cmd(); ++extern void fnc_c_cmd(WPanel *panel); ++ ++#endif // HAVE_CHARSET ++#endif //__RECODE_H__ +diff --git a/src/screen.c b/src/screen.c +index 6c3821b..1f938bc 100644 +--- a/src/screen.c ++++ b/src/screen.c +@@ -52,6 +52,10 @@ + #include "main.h" /* the_menubar */ + #include "unixcompat.h" + ++#ifdef HAVE_CHARSET ++#include "recode.h" ++#endif ++ + #define ELEMENTS(arr) ( sizeof(arr) / sizeof((arr)[0]) ) + + #define J_LEFT 1 +@@ -173,21 +177,64 @@ add_permission_string (char *dest, int width, file_entry *fe, int attr, int colo + static const char * + string_file_name (file_entry *fe, int len) + { +- static char buffer [MC_MAXPATHLEN + 1]; + size_t i; ++ char* filename; + +- for (i = 0; i < sizeof(buffer) - 1; i++) { +- char c; ++#ifdef UTF8 ++ static char buffer [BUF_SMALL * 4]; ++ mbstate_t s; ++ int mbmax = MB_CUR_MAX; ++ const char *str = fe->fname; + +- c = fe->fname[i]; ++ memset (&s, 0, sizeof (s)); ++#else ++ static char buffer [BUF_SMALL]; ++#endif + +- if (!c) +- break; ++#ifdef HAVE_CHARSET ++ my_translate_string(fe->fname,fe->fnamelen, recode_buf, recode_panel->tr_table); ++ filename= recode_buf; ++#else ++ filename=fe->fname; ++#endif + +- if (!is_printable(c)) +- c = '?'; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ for (i = 0; i < sizeof (buffer) - 1; i++) { ++ wchar_t wc; ++ int len; + +- buffer[i] = c; ++ len = mbrtowc (&wc, str, mbmax, &s); ++ if (!len) ++ break; ++ if (len < 0) { ++ memset (&s, 0, sizeof (s)); ++ buffer[i] = '?'; ++ str++; ++ continue; ++ } ++ if (!is_printable (wc)) { ++ buffer[i] = '?'; ++ str++; ++ continue; ++ } ++ if (i >= sizeof (buffer) - len) ++ break; ++ memcpy (buffer + i, str, len); ++ i += len - 1; ++ str += len; ++ } else ++#endif ++ for (i = 0; i < sizeof(buffer) - 1; i++) { ++ char c; ++ ++ c = filename[i]; ++ ++ if (!c) break; ++ ++ if (!is_printable(c)) c = '?'; ++ ++ buffer[i] = c; + } + + buffer[i] = 0; +@@ -452,42 +499,6 @@ static struct { + { "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL }, + }; + +-static char * +-to_buffer (char *dest, int just_mode, int len, const char *txt) +-{ +- int txtlen = strlen (txt); +- int still, over; +- +- /* Fill buffer with spaces */ +- memset (dest, ' ', len); +- +- still = (over=(txtlen > len)) ? (txtlen - len) : (len - txtlen); +- +- switch (HIDE_FIT(just_mode)){ +- case J_LEFT: +- still = 0; +- break; +- case J_CENTER: +- still /= 2; +- break; +- case J_RIGHT: +- default: +- break; +- } +- +- if (over){ +- if (IS_FIT(just_mode)) +- strcpy (dest, name_trunc(txt, len)); +- else +- strncpy (dest, txt+still, len); +- } else +- strncpy (dest+still, txt, txtlen); +- +- dest[len] = '\0'; +- +- return (dest + len); +-} +- + static int + file_compute_color (int attr, file_entry *fe) + { +@@ -541,14 +552,18 @@ file_compute_color (int attr, file_entry *fe) + + /* Formats the file number file_index of panel in the buffer dest */ + static void +-format_file (char *dest, int limit, WPanel *panel, int file_index, int width, int attr, int isstatus) ++format_file (WPanel *panel, int file_index, int width, int attr, int isstatus) + { + int color, length, empty_line; + const char *txt; +- char *old_pos; +- char *cdest = dest; + format_e *format, *home; + file_entry *fe; ++#ifdef UTF8 ++ char buffer[BUF_MEDIUM * sizeof (wchar_t)]; ++#else ++ char buffer[BUF_MEDIUM]; ++#endif ++ int txtwidth = 0; + + length = 0; + empty_line = (file_index >= panel->count); +@@ -566,34 +581,137 @@ format_file (char *dest, int limit, WPanel *panel, int file_index, int width, in + break; + + if (format->string_fn){ +- int len; ++ int len, still, over, perm, txtlen, wide; + + if (empty_line) + txt = " "; + else + txt = (*format->string_fn)(fe, format->field_len); + +- old_pos = cdest; +- + len = format->field_len; + if (len + length > width) + len = width - length; +- if (len + (cdest - dest) > limit) +- len = limit - (cdest - dest); ++ if (len >= BUF_MEDIUM) ++ len = BUF_MEDIUM - 1; + if (len <= 0) + break; +- cdest = to_buffer (cdest, format->just_mode, len, txt); +- length += len; + +- attrset (color); ++ perm = 0; ++ if (permission_mode) { ++ if (!strcmp(format->id, "perm")) ++ perm = 1; ++ else if (!strcmp(format->id, "mode")) ++ perm = 2; ++ } + +- if (permission_mode && !strcmp(format->id, "perm")) +- add_permission_string (old_pos, format->field_len, fe, attr, color, 0); +- else if (permission_mode && !strcmp(format->id, "mode")) +- add_permission_string (old_pos, format->field_len, fe, attr, color, 1); +- else +- addstr (old_pos); ++ wide = 0; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode && !empty_line && !perm) { ++ mbstate_t s; ++ const char *str = txt; ++ ++ memset (&s, 0, sizeof (s)); ++ txtlen = mbsrtowcs ((wchar_t *) buffer, &str, ++ sizeof (buffer) / sizeof (wchar_t), &s); ++ if (txtlen < 0) { ++ txt = " "; ++ txtlen = 1; ++ } else { ++ wide = 1; ++ txtwidth = wcswidth((wchar_t*)buffer, txtlen); ++ } ++ } else ++#endif ++ { ++ txtlen = mbstrlen (txt); ++ txtwidth = txtlen; ++ } ++ ++ over = txtwidth > len; ++ still = over ? txtlen - len : len - txtlen; ++ ++ switch (HIDE_FIT(format->just_mode)) { ++ case J_LEFT: ++ still = 0; ++ break; ++ case J_CENTER: ++ still /= 2; ++ break; ++ case J_RIGHT: ++ default: ++ break; ++ } ++ ++ attrset (color); ++ ++ if (wide) { ++#ifdef UTF8 ++ if (over) { ++ if (IS_FIT (format->just_mode)) { ++ int n1 = 0; ++ int width1 = 0; ++ int n2 = 0; ++ int width2 = 0; ++ int len1 = len / 2; ++ int len2; ++ ++ while (1) { ++ int w = wcwidth(((wchar_t *) buffer)[n1]); ++ if (width1 + w <= len1) { ++ width1 += w; ++ n1++; ++ } ++ else ++ break; ++ } ++ len2 = len - width1 - 1; ++ ++ while (1) { ++ int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]); ++ if (width2 + w <= len2) { ++ width2 += w; ++ n2++; ++ } ++ else ++ break; ++ } ++ ++ ++ SLsmg_write_nwchars ((wchar_t *) buffer, n1); ++ SLsmg_write_nwchars (L"~", 1); ++ printw ("%*s", len - width1 - width2 - 1, ""); ++ SLsmg_write_nwchars (((wchar_t *) buffer) ++ + txtlen - n2, n2); ++ } else ++ SLsmg_write_nwchars ((wchar_t *) buffer + still, len); ++ } else { ++ printw ("%*s", still, ""); ++ SLsmg_write_nwchars ((wchar_t *) buffer, txtlen); ++ printw ("%*s", len - txtwidth - still, ""); ++ } ++#endif ++ } else { ++ if (over) { ++ if (IS_FIT (format->just_mode)) ++ strcpy (buffer, name_trunc(txt, len)); ++ else ++ memcpy (buffer, txt + still, len); ++ } else { ++ memset (buffer, ' ', still); ++ memcpy (buffer + still, txt, txtlen); ++ memset (buffer + still + txtlen, ' ', ++ len - txtlen - still); ++ } ++ buffer[len] = '\0'; ++ ++ if (perm) ++ add_permission_string (buffer, format->field_len, fe, ++ attr, color, perm - 1); ++ else ++ addstr (buffer); ++ } + ++ length += len; + } else { + if (attr == SELECTED || attr == MARKED_SELECTED) + attrset (SELECTED_COLOR); +@@ -616,7 +734,10 @@ repaint_file (WPanel *panel, int file_index, int mv, int attr, int isstatus) + { + int second_column = 0; + int width, offset; +- char buffer [BUF_MEDIUM]; ++ ++#ifdef HAVE_CHARSET ++ recode_panel=panel; ++#endif + + offset = 0; + if (!isstatus && panel->split){ +@@ -645,7 +766,7 @@ repaint_file (WPanel *panel, int file_index, int mv, int attr, int isstatus) + widget_move (&panel->widget, file_index - panel->top_file + 2, 1); + } + +- format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus); ++ format_file (panel, file_index, width, attr, isstatus); + + if (!isstatus && panel->split){ + if (second_column) +@@ -657,7 +778,7 @@ repaint_file (WPanel *panel, int file_index, int mv, int attr, int isstatus) + } + } + +-static void ++void + display_mini_info (WPanel *panel) + { + if (!show_mini_info) +@@ -694,7 +815,7 @@ display_mini_info (WPanel *panel) + ngettext("%s in %d file", "%s in %d files", panel->marked), + b_bytes, panel->marked); + +- if ((int) strlen (buffer) > cols-2){ ++ if ((int) mbstrlen (buffer) > cols-2){ + buffer [cols] = 0; + p += 2; + } else +@@ -727,7 +848,7 @@ display_mini_info (WPanel *panel) + return; + } + +-static void ++void + paint_dir (WPanel *panel) + { + int i; +@@ -765,7 +886,7 @@ mini_info_separator (WPanel *panel) + #endif /* !HAVE_SLANG */ + } + +-static void ++void + show_dir (WPanel *panel) + { + char *tmp; +@@ -785,6 +906,9 @@ show_dir (WPanel *panel) + } + #endif /* HAVE_SLANG */ + ++ vscrollbar (panel->widget, panel->widget.lines, panel->widget.cols-1, 2, 2, ++ panel->selected, panel->count, TRUE); ++ + if (panel->active) + attrset (REVERSE_COLOR); + +@@ -794,8 +918,15 @@ show_dir (WPanel *panel) + tmp = g_malloc (panel->widget.cols + 1); + tmp[panel->widget.cols] = '\0'; + ++#ifdef HAVE_CHARSET ++ my_translate_string(panel->cwd,strlen(panel->cwd),recode_buf, panel->tr_table); ++ trim (strip_home_and_password (recode_buf), tmp, ++ min (max (panel->widget.cols - 7, 0), panel->widget.cols) ); ++ #else + trim (strip_home_and_password (panel->cwd), tmp, + max (panel->widget.cols - 9, 0)); ++#endif ++ + addstr (tmp); + g_free (tmp); + +@@ -1008,6 +1139,17 @@ panel_new (const char *panel_name) + mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2); + strcpy (panel->lwd, "."); + ++#ifdef HAVE_CHARSET ++ panel_reset_codepage(panel); ++#endif ++ ++#ifdef USE_VFS ++ panel->is_return=0; ++ #ifdef HAVE_CHARSET ++ panel->ret_codepage=-1; ++ #endif ++#endif ++ + panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL); + panel->dir_history = history_get (panel->hist_name); + directory_history_add (panel, panel->cwd); +@@ -1107,6 +1249,12 @@ paint_frame (WPanel *panel) + int side, width; + + const char *txt; ++#ifdef UTF8 ++ char buffer[30 * sizeof (wchar_t)]; ++ mbstate_t s; ++ ++ memset (&s, 0, sizeof (s)); ++#endif + if (!panel->split) + adjust_top_file (panel); + +@@ -1131,16 +1279,38 @@ paint_frame (WPanel *panel) + if (format->string_fn){ + txt = format->title; + +- header_len = strlen (txt); ++ attrset (MARKED_COLOR); ++ width -= format->field_len; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ const char *str = txt; ++ header_len = mbsrtowcs ((wchar_t *) buffer, &str, ++ sizeof (buffer) / sizeof (wchar_t), ++ &s); ++ if (header_len < 0) { ++ memset (&s, 0, sizeof (s)); ++ printw ("%*s", format->field_len, ""); ++ continue; ++ } ++ if (header_len > format->field_len) ++ header_len = format->field_len; ++ spaces = (format->field_len - header_len) / 2; ++ extra = (format->field_len - header_len) % 2; ++ printw ("%*s", spaces, ""); ++ SLsmg_write_nwchars ((wchar_t *) buffer, header_len); ++ printw ("%*s", spaces + extra, ""); ++ continue; ++ } ++#endif ++ ++ header_len = mbstrlen (txt); + if (header_len > format->field_len) + header_len = format->field_len; + +- attrset (MARKED_COLOR); + spaces = (format->field_len - header_len) / 2; + extra = (format->field_len - header_len) % 2; + tty_printf ("%*s%.*s%*s", spaces, "", + header_len, txt, spaces+extra, ""); +- width -= 2 * spaces + extra + header_len; + } else { + attrset (NORMAL_COLOR); + one_vline (); +@@ -1358,7 +1528,7 @@ use_display_format (WPanel *panel, const char *format, char **error, int isstatu + panel->dirty = 1; + + /* Status needn't to be split */ +- usable_columns = ((panel->widget.cols-2)/((isstatus) ++ usable_columns = ((panel->widget.cols-3)/((isstatus) + ? 1 + : (panel->split+1))) - (!isstatus && panel->split); + +@@ -1897,11 +2067,24 @@ do_search (WPanel *panel, int c_code) + int i; + int wrapped = 0; + int found; ++ int prevpos, pos; ++ int j; ++ mbstate_t mbs; + + l = strlen (panel->search_buffer); + if (c_code == KEY_BACKSPACE) { +- if (l) +- panel->search_buffer[--l] = '\0'; ++ if (l) { ++ prevpos = pos = 0; ++ memset (&mbs, 0, sizeof (mbs)); ++ while (pos < l) { ++ prevpos = pos; ++ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); ++ if (j <= 0) break; ++ pos += j; ++ } ++ --l; ++ panel->search_buffer[prevpos] = 0; ++ } + } else { + if (c_code && l < sizeof (panel->search_buffer)) { + panel->search_buffer[l] = c_code; +@@ -1910,6 +2093,14 @@ do_search (WPanel *panel, int c_code) + } + } + ++ prevpos = pos = 0; ++ memset (&mbs, 0, sizeof (mbs)); ++ while (pos < l) { ++ prevpos = pos; ++ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); ++ if (j <= 0) break; ++ pos += j; ++ } + found = 0; + for (i = panel->selected; !wrapped || i != panel->selected; i++) { + if (i >= panel->count) { +@@ -1920,9 +2111,9 @@ do_search (WPanel *panel, int c_code) + } + if (panel-> + case_sensitive +- ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, l) ++ ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, pos) + == 0) : (g_strncasecmp (panel->dir.list[i].fname, +- panel->search_buffer, l) == 0)) { ++ panel->search_buffer, pos) == 0)) { + unselect_item (panel); + panel->selected = i; + select_item (panel); +@@ -1931,7 +2122,7 @@ do_search (WPanel *panel, int c_code) + } + } + if (!found) +- panel->search_buffer[--l] = 0; ++ panel->search_buffer[prevpos] = 0; + + paint_panel (panel); + } +@@ -2160,7 +2351,12 @@ static const panel_key_map panel_keymap [] = { + { XCTRL('n'), move_down }, /* C-n like emacs */ + { XCTRL('s'), start_search }, /* C-s like emacs */ + { ALT('s'), start_search }, /* M-s not like emacs */ ++#ifndef HAVE_CHARSET + { XCTRL('t'), mark_file }, ++#endif ++#ifdef HAVE_CHARSET ++ { XCTRL('t'), mark_file }, /* was 'fnc_c_cmd' */ ++#endif + { ALT('o'), chdir_other_panel }, + { ALT('i'), sync_other_panel }, + { ALT('l'), chdir_to_readlink }, +diff --git a/src/screen.h b/src/screen.h +new file mode 100644 +index 0000000..4efb525 +--- /dev/null ++++ b/src/screen.h +@@ -0,0 +1,11 @@ ++#ifndef __SCREEN_H__ ++#define __SCREEN_H__ ++#include <config.h> ++ ++#include "global.h" ++ ++extern void paint_dir (WPanel *panel); ++extern void display_mini_info (WPanel *panel); ++extern void show_dir(WPanel *panel); ++#endif //__SCREEN_H__ ++ +diff --git a/src/selcodepage.c b/src/selcodepage.c +index 3e9ec63..dabed0e 100644 +--- a/src/selcodepage.c ++++ b/src/selcodepage.c +@@ -45,14 +45,16 @@ get_hotkey (int n) + } + + int +-select_charset (int current_charset, int seldisplay) ++select_charset (int current_charset, int seldisplay, const char *title) + { ++ int new_charset; ++ + int i, menu_lines = n_codepages + 1; + char buffer[255]; + + /* Create listbox */ + Listbox *listbox = create_listbox_window (ENTRY_LEN + 2, menu_lines, +- _(" Choose input codepage "), ++ title, + "[Codepages Translation]"); + + if (!seldisplay) +@@ -82,20 +84,26 @@ select_charset (int current_charset, int seldisplay) + + i = run_listbox (listbox); + +- return (seldisplay) ? ((i >= n_codepages) ? -1 : i) +- : (i - 1); ++ if(i==-1) ++ i = (seldisplay) ++ ? ((current_charset < 0) ? n_codepages : current_charset) ++ : (current_charset + 1); ++ ++ new_charset =(seldisplay) ? ( (i >= n_codepages) ? -1 : i ) : ( i-1 ); ++ new_charset = (new_charset==-2) ? current_charset:new_charset; ++ return new_charset; + } + + /* Helper functions for codepages support */ + + + int +-do_select_codepage (void) ++do_select_codepage (const char *title) + { + const char *errmsg; + + if (display_codepage > 0) { +- source_codepage = select_charset (source_codepage, 0); ++ source_codepage = select_charset (source_codepage, 0, title); + errmsg = + init_translation_table (source_codepage, display_codepage); + if (errmsg) { +diff --git a/src/selcodepage.h b/src/selcodepage.h +index 06fbd77..f7f16de 100644 +--- a/src/selcodepage.h ++++ b/src/selcodepage.h +@@ -2,8 +2,8 @@ + #define MC_SELCODEPAGE_H + + #ifdef HAVE_CHARSET +-int select_charset (int current_charset, int seldisplay); +-int do_select_codepage (void); ++int select_charset (int current_charset, int seldisplay, const char *title); ++int do_select_codepage (const char *title); + #endif /* HAVE_CHARSET */ + + #endif +diff --git a/src/setup.c b/src/setup.c +index 67dec4a..4c78e5b 100644 +--- a/src/setup.c ++++ b/src/setup.c +@@ -50,6 +50,8 @@ + + #ifdef HAVE_CHARSET + #include "charsets.h" ++#include"recode.h" ++#include "wtools.h" + #endif + + #ifdef USE_NETCODE +@@ -273,6 +275,11 @@ panel_save_setup (struct WPanel *panel, const char *section) + g_snprintf (buffer, sizeof (buffer), "%d", panel->user_mini_status); + save_string (section, "user_mini_status", buffer, + profile_name); ++ ++#ifdef HAVE_CHARSET ++ // save panel codepage ++ save_string(section, "panel_display_codepage", get_codepage_id(panel->src_codepage), profile_name); ++#endif + } + + void +@@ -375,6 +382,7 @@ save_setup (void) + #ifdef HAVE_CHARSET + save_string( "Misc", "display_codepage", + get_codepage_id( display_codepage ), profile_name ); ++ save_string( "Misc", "ftp_codepage", get_codepage_id(ftp_codepage), profile_name); + #endif /* HAVE_CHARSET */ + + g_free (profile); +@@ -425,6 +433,31 @@ panel_load_setup (WPanel *panel, const char *section) + panel->user_mini_status = + load_int (section, "user_mini_status", 0); + ++#ifdef HAVE_CHARSET ++//--- Loading panel codepage ++ panel_reset_codepage(panel); ++ if(load_codepages_list()>0) { ++ char cpname[128]; ++ char *errmsg; ++ ++ ++ if(display_codepage>=0) { ++ load_string(section, "panel_display_codepage", "", cpname, sizeof(cpname)); ++ if(cpname[0]!='\0') panel->src_codepage = get_codepage_index(cpname); ++ } ++ ++ errmsg=my_init_tt(display_codepage,panel->src_codepage,panel->tr_table); ++ if(errmsg) { ++ panel_reset_codepage(panel); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ errmsg=my_init_tt(panel->src_codepage,display_codepage,panel->tr_table_input); ++ if(errmsg) { ++ panel_reset_codepage(panel); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ } ++#endif + } + + static void +@@ -574,10 +607,16 @@ load_setup (void) + #ifdef HAVE_CHARSET + if ( load_codepages_list() > 0 ) { + char cpname[128]; +- load_string( "Misc", "display_codepage", "", +- cpname, sizeof(cpname) ); +- if ( cpname[0] != '\0' ) +- display_codepage = get_codepage_index( cpname ); ++ get_locale_codepage(); ++ load_string("Misc", "display_codepage", "", cpname, sizeof(cpname)); ++ if(cpname[0] != '\0') display_codepage=get_codepage_index(cpname); ++ else display_codepage=lang_codepage; ++ ++ ftp_codepage=-1; ++ if(display_codepage >= 0) { ++ load_string( "Misc", "ftp_codepage", "", cpname, sizeof(cpname)); ++ if(cpname[0] != '\0') ftp_codepage=get_codepage_index(cpname); ++ } + } + + init_translation_table( source_codepage, display_codepage ); +diff --git a/src/slint.c b/src/slint.c +index c30fac1..88557ac 100644 +--- a/src/slint.c ++++ b/src/slint.c +@@ -142,7 +142,9 @@ void + slang_init (void) + { + SLtt_get_terminfo (); +- ++#if SLANG_VERSION >= 20000 ++ SLutf8_enable (-1); ++#endif + /* + * If the terminal in not in terminfo but begins with a well-known + * string such as "linux" or "xterm" S-Lang will go on, but the +diff --git a/src/timefmt.h b/src/timefmt.h +index 2b8d52f..2cf4a38 100644 +--- a/src/timefmt.h ++++ b/src/timefmt.h +@@ -19,7 +19,7 @@ + } \ + else \ + { \ +- strftime(buffer, bufsize, fmt, whentm); \ ++ strftime(buffer, bufsize -1, fmt, whentm); \ + } \ + } \ + +diff --git a/src/tty.c b/src/tty.c +index a71c6cc..961132b 100644 +--- a/src/tty.c ++++ b/src/tty.c +@@ -134,10 +134,12 @@ tty_print_char(int c) + * defined or not. Congratulations! At least, they left the API call + * for SLsmg_write_nchars as it has always been. + */ +- char ch; + +- ch = c; +- SLsmg_write_nchars(&ch, 1); ++ /* The above comment is a nonsense, SLsmg_write_char(c) works pretty ++ * good for me. So please don't mess with Red Hat people. ++ * Jindrich Novy (jnovy@redhat.com) ++ */ ++ SLsmg_write_nwchars(&c, 1); + #else + addch(c); + #endif +diff --git a/src/tty.h b/src/tty.h +index 85d286b..d27e639 100644 +--- a/src/tty.h ++++ b/src/tty.h +@@ -8,6 +8,8 @@ + of ifdefs in the other files small. + */ + ++#include <glib.h> /* gboolean is used here */ ++ + #ifdef HAVE_SLANG + # include "myslang.h" + #endif +diff --git a/src/util.c b/src/util.c +index 35658b0..5f87b57 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -34,10 +34,14 @@ + #include <sys/types.h> + #include <sys/stat.h> + #include <unistd.h> ++#include <iconv.h> ++#include <langinfo.h> ++#include <errno.h> + + #include <mhl/escape.h> + #include <mhl/string.h> + ++#include "tty.h" + #include "global.h" + #include "profile.h" + #include "main.h" /* mc_home */ +@@ -50,9 +54,39 @@ + #include "charsets.h" + #endif + ++#ifdef UTF8 ++#include <wctype.h> ++#endif ++ + static const char app_text [] = "Midnight-Commander"; + int easy_patterns = 1; + ++#if SLANG_VERSION >= 20000 ++void SLsmg_write_nwchars(wchar_t *s, size_t n) ++{ ++ if (SLsmg_is_utf8_mode()) { /* slang can handle it directly */ ++ while(n-- && *s) ++ SLsmg_write_char(*s++); ++ } ++ else { /* convert wchars back to 8bit encoding */ ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ while (n-- && *s) { ++ char buf[MB_LEN_MAX + 1]; /* should use 1 char, but to be sure */ ++ if (*s < 0x80) { ++ SLsmg_write_char(*s++); /* ASCII */ ++ } ++ else { ++ if (wcrtomb(buf, *s++, &mbs) == 1) ++ SLsmg_write_char((wchar_t)(buf[0])); ++ else ++ SLsmg_write_char('?'); /* should not happen */ ++ } ++ } ++ } ++} ++#endif ++ + extern void str_replace(char *s, char from, char to) + { + for (; *s != '\0'; s++) { +@@ -83,9 +117,106 @@ is_8bit_printable (unsigned char c) + return (c > 31 && c != 127 && c != 155); + } + ++size_t ++mbstrlen (const char *str) ++{ ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ size_t width = 0; ++ ++ for (; *str; str++) { ++ wchar_t c; ++ size_t len; ++ ++ len = mbrtowc (&c, str, MB_CUR_MAX, NULL); ++ ++ if (len == (size_t)(-1) || len == (size_t)(-2)) break; ++ ++ if (len > 0) { ++ int wcsize = wcwidth(c); ++ width += wcsize > 0 ? wcsize : 0; ++ str += len-1; ++ } ++ } ++ ++ return width; ++ } else ++#endif ++ return strlen (str); ++} ++ ++#ifdef UTF8 ++ ++void ++fix_utf8(char *str) ++{ ++ mbstate_t mbs; ++ ++ char *p = str; ++ ++ while (*p) { ++ int len; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrlen(p, MB_CUR_MAX, &mbs); ++ if (len == -1) { ++ *p = '?'; ++ p++; ++ } else if (len > 0) { ++ p += len; ++ } else { ++ p++; ++ } ++ } ++} ++#endif ++ ++ ++ ++#ifdef UTF8 ++wchar_t * ++mbstr_to_wchar (const char *str) ++{ ++ int len = mbstrlen(str); ++ wchar_t *buf = g_malloc((len+1) * sizeof(wchar_t)); ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ mbsrtowcs (buf, &str, len, &mbs); ++ buf[len] = 0; ++ return buf; ++} ++ ++char * ++wchar_to_mbstr (const wchar_t *wstr) ++{ ++ mbstate_t mbs; ++ const wchar_t *wstr2; ++ char * string; ++ int len; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ wstr2 = wstr; ++ len = wcsrtombs(NULL, &wstr2, 0, &mbs); ++ if (len <= 0) ++ return NULL; ++ ++ string = g_malloc(len + 1); ++ ++ wstr2 = wstr; ++ wcsrtombs(string, &wstr2, len, &mbs); ++ string[len] = 0; ++ return string; ++} ++#endif ++ ++ ++ + int + is_printable (int c) + { ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ return iswprint (c); ++#endif + c &= 0xff; + + #ifdef HAVE_CHARSET +@@ -103,7 +234,7 @@ is_printable (int c) + #endif /* !HAVE_CHARSET */ + } + +-/* Calculates the message dimensions (lines and columns) */ ++/* Calculates the message dimension in columns and lines. */ + void + msglen (const char *text, int *lines, int *columns) + { +@@ -116,8 +247,21 @@ msglen (const char *text, int *lines, int *columns) + nlines++; + colindex = 0; + } else { ++#ifndef UTF8 + colindex++; + if (colindex > ncolumns) ++#else /* UTF8 */ ++ size_t len; ++ wchar_t c; ++ ++ len = mbrtowc (&c, text, MB_CUR_MAX, NULL); ++ if (len > 0 && len != (size_t)(-1) && len != (size_t)(-2)) { ++ int wcsize = wcwidth(c); ++ colindex += wcsize > 0 ? wcsize-1 : -1; ++ text += len-1; ++ } ++ if (++colindex > ncolumns) ++#endif /* UTF8 */ + ncolumns = colindex; + } + } +@@ -211,7 +355,24 @@ name_quote (const char *s, int quote_percent) + *d++ = '\'; + break; + } ++#ifndef UTF8 + *d = *s; ++#else /* UTF8 */ ++ { ++ mbstate_t mbs; ++ int len; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrlen(s, MB_CUR_MAX, &mbs); ++ if (len > 0) { ++ while (len-- > 1) ++ *d++ = *s++; ++ *d = *s; ++ } else { ++ *d = '?'; ++ } ++ ++ } ++#endif /* UTF8 */ + } + *d = '\0'; + return ret; +@@ -233,25 +394,90 @@ const char * + name_trunc (const char *txt, int trunc_len) + { + static char x[MC_MAXPATHLEN + MC_MAXPATHLEN]; +- int txt_len; ++ int txt_len, first, skip; + char *p; ++ const char *str; + + if ((size_t) trunc_len > sizeof (x) - 1) { + trunc_len = sizeof (x) - 1; + } +- txt_len = strlen (txt); +- if (txt_len <= trunc_len) { +- strcpy (x, txt); +- } else { +- int y = (trunc_len / 2) + (trunc_len % 2); +- strncpy (x, txt, y); +- strncpy (x + y, txt + txt_len - (trunc_len / 2), trunc_len / 2); +- x[y] = '~'; ++ txt_len = mbstrlen (txt); ++ first = 0; ++ skip = 0; ++ if (txt_len > trunc_len) { ++ first = trunc_len / 2; ++ skip = txt_len - trunc_len + 1; + } +- x[trunc_len] = 0; +- for (p = x; *p; p++) +- if (!is_printable (*p)) +- *p = '?'; ++ ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ mbstate_t s; ++ int mbmax; ++ ++ str = txt; ++ memset (&s, 0, sizeof (s)); ++ mbmax = MB_CUR_MAX; ++ p = x; ++ while (p < x + sizeof (x) - 1 && trunc_len) { ++ wchar_t wc; ++ int len; ++ ++ len = mbrtowc (&wc, str, mbmax, &s); ++ if (!len) ++ break; ++ if (len < 0) { ++ memset (&s, 0, sizeof (s)); ++ *p = '?'; ++ len = 1; ++ str++; ++ } else if (!is_printable (wc)) { ++ *p = '?'; ++ str += len; ++ len = 1; ++ } else if (p >= x + sizeof (x) - len) ++ break; ++ else { ++ memcpy (p, str, len); ++ str += len; ++ } ++ if (first) { ++ --trunc_len; ++ --first; ++ p += len; ++ if (!first && p < x + sizeof (x) - 1 && trunc_len) { ++ *p++ = '~'; ++ --trunc_len; ++ } ++ } else if (skip) ++ --skip; ++ else { ++ --trunc_len; ++ p += len; ++ } ++ } ++ } else ++#endif ++ { ++ str = txt; ++ p = x; ++ while (p < x + sizeof (x) - 1) { ++ if (*str == '\0') ++ break; ++ else if (!is_printable (*str)) ++ *p++ = '?'; ++ else ++ *p++ = *str; ++ ++str; ++ if (first) { ++ --first; ++ if (!first) { ++ *p++ = '~'; ++ str += skip; ++ } ++ } ++ } ++ } ++ *p = '\0'; + return x; + } + +@@ -683,11 +909,66 @@ load_file (const char *filename) + } + + char * ++utf8_to_local(char *str) ++{ ++ iconv_t cd; ++ size_t buflen; ++ char *output; ++ int retry = 1; ++ ++ if (!str) ++ return 0; ++ ++ buflen = strlen(str); ++ ++ cd = iconv_open (nl_langinfo(CODESET), "UTF-8"); ++ if (cd == (iconv_t) -1) { ++ return g_strdup(str); ++ } ++ ++ output = g_malloc(buflen + 1); ++ ++ while (retry) ++ { ++ char *wrptr = output; ++ char *inptr = str; ++ size_t insize = buflen; ++ size_t avail = buflen; ++ size_t nconv; ++ ++ nconv = iconv (cd, &inptr, &insize, &wrptr, &avail); ++ if (nconv == (size_t) -1) ++ { ++ if (errno == E2BIG) ++ { ++ buflen *= 2; ++ g_free(output); ++ output = g_malloc(buflen + 1); ++ } ++ else ++ { ++ g_free(output); ++ return g_strdup(str); ++ } ++ } ++ else { ++ retry = 0; ++ *wrptr = 0; ++ } ++ } ++ ++ iconv_close (cd); ++ ++ return output; ++} ++ ++char * + load_mc_home_file (const char *filename, char **allocated_filename) + { + char *hintfile_base, *hintfile; + char *lang; + char *data; ++ char *conv_data; + + hintfile_base = mhl_str_dir_plus_file (mc_home, filename); + lang = guess_message_value (); +@@ -720,7 +1001,10 @@ load_mc_home_file (const char *filename, char **allocated_filename) + else + g_free (hintfile); + +- return data; ++ conv_data = utf8_to_local(data); ++ g_free(data); ++ ++ return conv_data; + } + + /* Check strftime() results. Some systems (i.e. Solaris) have different +@@ -736,10 +1020,12 @@ i18n_checktimelength (void) + // huh, localtime() doesnt seem to work ... falling back to "(invalid)" + length = strlen(INVALID_TIME_TEXT); + } else { +- char buf [MAX_I18NTIMELENGTH + 1]; ++ char buf [4* MAX_I18NTIMELENGTH + 1]; + size_t a, b; +- a = strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), lt); +- b = strftime (buf, sizeof(buf)-1, _("%b %e %Y"), lt); ++ strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), lt); ++ a = mbstrlen(buf); ++ strftime (buf, sizeof(buf)-1, _("%b %e %Y"), lt); ++ b = mbstrlen(buf); + length = max (a, b); + } + +@@ -753,15 +1039,12 @@ i18n_checktimelength (void) + const char * + file_date (time_t when) + { +- static char timebuf [MAX_I18NTIMELENGTH + 1]; ++ static char timebuf [4 * MAX_I18NTIMELENGTH + 1]; + time_t current_time = time ((time_t) 0); +- static size_t i18n_timelength = 0; + static const char *fmtyear, *fmttime; + const char *fmt; + +- if (i18n_timelength == 0){ +- i18n_timelength = i18n_checktimelength() + 1; +- ++ if ( fmtyear == NULL ) { + /* strftime() format string for old dates */ + fmtyear = _("%b %e %Y"); + /* strftime() format string for recent dates */ +@@ -781,7 +1064,7 @@ file_date (time_t when) + else + fmt = fmttime; + +- FMT_LOCALTIME(timebuf, i18n_timelength, fmt, when); ++ FMT_LOCALTIME(timebuf, sizeof(timebuf), fmt, when); + + return timebuf; + } +@@ -912,10 +1195,27 @@ strip_ctrl_codes (char *s) + r++; + continue; + } +- ++#ifndef UTF8 + if (is_printable(*r)) + *w++ = *r; + ++r; ++#else /* UTF8 */ ++ { ++ mbstate_t mbs; ++ int len; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrlen(r, MB_CUR_MAX, &mbs); ++ ++ if (len > 0 && (unsigned char)*r >= ' ') ++ while (len--) ++ *w++ = *r++; ++ else { ++ if (len == -1) ++ *w++ = '?'; ++ r++; ++ } ++ } ++#endif /* UTF8 */ + } + *w = 0; + return s; +diff --git a/src/util.h b/src/util.h +index 0cf2099..82edcde 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -102,6 +102,13 @@ void init_uid_gid_cache (void); + char *get_group (int); + char *get_owner (int); + ++void fix_utf8(char *str); ++size_t mbstrlen (const char *); ++wchar_t *mbstr_to_wchar (const char *); ++char *wchar_to_mbstr (const wchar_t *); ++char *utf8_to_local(char *str); ++ ++ + #define MAX_I18NTIMELENGTH 14 + #define MIN_I18NTIMELENGTH 10 + #define STD_I18NTIMELENGTH 12 +diff --git a/src/view.c b/src/view.c +index 8465301..8bc1792 100644 +--- a/src/view.c ++++ b/src/view.c +@@ -44,6 +44,10 @@ + #include <sys/stat.h> + #include <unistd.h> + ++#ifdef UTF8 ++#include <wctype.h> ++#endif /* UTF8 */ ++ + #include "global.h" + #include "tty.h" + #include "cmd.h" /* For view_other_cmd */ +@@ -1643,7 +1647,7 @@ view_display_status (WView *view) + hline (' ', width); + + file_label = _("File: %s"); +- file_label_width = strlen (file_label) - 2; ++ file_label_width = mbstrlen (file_label) - 2; + file_name = view->filename ? view->filename + : view->command ? view->command + : ""; +@@ -1911,6 +1915,12 @@ view_display_text (WView * view) + offset_type from; + int c; + struct hexedit_change_node *curr = view->change_list; ++#ifdef UTF8 ++ mbstate_t mbs; ++ char mbbuf[MB_LEN_MAX]; ++ int mblen; ++ wchar_t wc; ++#endif /* UTF8 */ + + view_display_clean (view); + view_display_ruler (view); +@@ -1923,8 +1933,37 @@ view_display_text (WView * view) + + tty_setcolor (NORMAL_COLOR); + for (row = 0, col = 0; row < height && (c = get_byte (view, from)) != -1; from++) { +- ++#ifndef UTF8 + if (view->text_nroff_mode && c == '\b') { ++#else /* UTF8 */ ++ mblen = 1; ++ mbbuf[0] = convert_to_display_c (c); ++ ++ while (mblen < MB_LEN_MAX) { ++ int res; ++ memset (&mbs, 0, sizeof (mbs)); ++ res = mbrtowc (&wc, mbbuf, mblen, &mbs); ++ if (res <= 0 && res != -2) { ++ wc = '.'; ++ mblen = 1; ++ break; ++ } ++ if (res == mblen) ++ break; ++ ++ mbbuf[mblen] = convert_to_display_c (get_byte (view, from + mblen)); ++ mblen++; ++ } ++ ++ if (mblen == MB_LEN_MAX) { ++ wc = '.'; ++ mblen = 1; ++ } ++ ++ from += mblen - 1; ++ ++ if (view->text_nroff_mode && wc == '\b') { ++#endif /* UTF8 */ + int c_prev; + int c_next; + +@@ -1989,10 +2028,17 @@ view_display_text (WView * view) + if (col >= view->dpy_text_column + && col - view->dpy_text_column < width) { + widget_move (view, top + row, left + (col - view->dpy_text_column)); ++#ifndef UTF8 + c = convert_to_display_c (c); + if (!is_printable (c)) + c = '.'; + tty_print_char (c); ++#else ++ wc = convert_to_display_c (wc); ++ if (!iswprint (wc)) ++ wc = '.'; ++ tty_print_char (wc); ++#endif + } + col++; + tty_setcolor (NORMAL_COLOR); +@@ -3187,7 +3233,7 @@ view_handle_key (WView *view, int c) + + #ifdef HAVE_CHARSET + case XCTRL ('t'): +- do_select_codepage (); ++ do_select_codepage (_(" Choose codepage ")); + view->dirty++; + view_update (view); + return MSG_HANDLED; +diff --git a/src/widget.c b/src/widget.c +index f85cc2a..635441d 100644 +--- a/src/widget.c ++++ b/src/widget.c +@@ -38,6 +38,9 @@ + + #include "global.h" + #include "tty.h" ++#ifdef UTF8 ++#include <wctype.h> ++#endif /* UTF8 */ + #include "color.h" + #include "mouse.h" + #include "dialog.h" +@@ -183,6 +186,11 @@ button_callback (Widget *w, widget_msg_t msg, int parm) + if (b->hotpos >= 0) { + widget_selectcolor (w, b->selected, TRUE); + widget_move (w, 0, b->hotpos + off); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ SLsmg_write_nwchars (&b->hotwc, 1); ++ else ++#endif + addch ((unsigned char) b->text[b->hotpos]); + } + return MSG_HANDLED; +@@ -216,7 +224,7 @@ button_event (Gpm_Event *event, void *data) + static int + button_len (const char *text, unsigned int flags) + { +- int ret = strlen (text); ++ int ret = mbstrlen (text); + switch (flags){ + case DEFPUSH_BUTTON: + ret += 6; +@@ -239,14 +247,36 @@ button_len (const char *text, unsigned int flags) + * the button text is g_malloc()ed, we can safely change and shorten it. + */ + static void +-button_scan_hotkey (WButton *b) ++scan_hotkey (char *text, int *hotposp, int *hotkeyp, wchar_t *hotwcp) + { +- char *cp = strchr (b->text, '&'); ++ char *cp = strchr (text, '&'); + + if (cp != NULL && cp[1] != '\0') { +- g_strlcpy (cp, cp + 1, strlen (cp)); +- b->hotkey = tolower ((unsigned char) *cp); +- b->hotpos = cp - b->text; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ mbstate_t s; ++ int len; ++ ++ *cp = '\0'; ++ memset (&s, 0, sizeof (s)); ++ len = mbrtowc (hotwcp, cp + 1, MB_CUR_MAX, &s); ++ if (len > 0) { ++ *hotposp = mbstrlen (text); ++ if (*hotposp < 0) { ++ *hotposp = -1; ++ } else { ++ /* FIXME */ ++ *hotkeyp = tolower (*hotwcp); ++ } ++ } ++ } else ++#endif ++ { ++ *hotkeyp = tolower (cp[1]); ++ *hotposp = cp - text; ++ } ++ ++ memmove (cp, cp + 1, strlen (cp + 1) + 1); + } + } + +@@ -267,8 +297,9 @@ button_new (int y, int x, int action, int flags, const char *text, + widget_want_hotkey (b->widget, 1); + b->hotkey = 0; + b->hotpos = -1; ++ b->hotwc = L'\0'; + +- button_scan_hotkey(b); ++ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); + return b; + } + +@@ -281,14 +312,13 @@ button_get_text (WButton *b) + void + button_set_text (WButton *b, const char *text) + { +- g_free (b->text); ++ g_free (b->text); + b->text = g_strdup (text); + b->widget.cols = button_len (text, b->flags); +- button_scan_hotkey(b); ++ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); + dlg_redraw (b->widget.parent); + } + +- + /* Radio button widget */ + static int radio_event (Gpm_Event *event, void *); + +@@ -363,14 +393,35 @@ radio_callback (Widget *w, widget_msg_t msg, int parm) + widget_move (&r->widget, i, 0); + + tty_printf ("(%c) ", (r->sel == i) ? '*' : ' '); +- for (cp = r->texts[i]; *cp; cp++) { +- if (*cp == '&') { +- widget_selectcolor (w, focused, TRUE); ++ cp = strchr (r->texts[i], '&'); ++ if (cp != NULL) { ++#ifdef UTF8 ++ mbstate_t s; ++ wchar_t wc; ++ int len; ++#endif ++ tty_printf ("%.*s", (int) ((char *) cp - r->texts[i]), ++ r->texts[i]); ++ widget_selectcolor (w, focused, TRUE); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ memset (&s, 0, sizeof (s)); ++ len = mbrtowc (&wc, cp + 1, MB_CUR_MAX, &s); ++ ++cp; ++ if (len > 0) { ++ tty_printf ("%.*s", len, cp); ++ cp += len; ++ } ++ } else ++#endif ++ { + addch (*++cp); +- widget_selectcolor (w, focused, FALSE); +- } else +- addch (*cp); +- } ++ ++cp; ++ } ++ widget_selectcolor (w, focused, FALSE); ++ } else ++ cp = r->texts[i]; ++ addstr ((char *) cp); + } + return MSG_HANDLED; + +@@ -409,7 +460,7 @@ radio_new (int y, int x, int count, const char **texts) + /* Compute the longest string */ + max = 0; + for (i = 0; i < count; i++){ +- m = strlen (texts [i]); ++ m = mbstrlen (texts [i]); + if (m > max) + max = m; + } +@@ -469,6 +520,11 @@ check_callback (Widget *w, widget_msg_t msg, int parm) + if (c->hotpos >= 0) { + widget_selectcolor (w, msg == WIDGET_FOCUS, TRUE); + widget_move (&c->widget, 0, +c->hotpos + 4); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ SLsmg_write_nwchars (&c->hotwc, 1); ++ else ++#endif + addch ((unsigned char) c->text[c->hotpos]); + } + return MSG_HANDLED; +@@ -506,35 +562,20 @@ WCheck * + check_new (int y, int x, int state, const char *text) + { + WCheck *c = g_new (WCheck, 1); +- const char *s; +- char *t; +- +- init_widget (&c->widget, y, x, 1, strlen (text), ++ ++ init_widget (&c->widget, y, x, 1, mbstrlen (text), + check_callback, check_event); + c->state = state ? C_BOOL : 0; + c->text = g_strdup (text); + c->hotkey = 0; + c->hotpos = -1; ++ c->hotwc = L'\0'; + widget_want_hotkey (c->widget, 1); + +- /* Scan for the hotkey */ +- for (s = text, t = c->text; *s; s++, t++){ +- if (*s != '&'){ +- *t = *s; +- continue; +- } +- s++; +- if (*s){ +- c->hotkey = tolower ((unsigned char) *s); +- c->hotpos = t - c->text; +- } +- *t = *s; +- } +- *t = 0; ++ scan_hotkey (c->text, &c->hotpos, &c->hotkey, &c->hotwc); + return c; + } + +- + /* Label widget */ + + static cb_ret_t +@@ -573,7 +614,7 @@ label_callback (Widget *w, widget_msg_t msg, int parm) + } + widget_move (&l->widget, y, 0); + tty_printf ("%s", p); +- xlen = l->widget.cols - strlen (p); ++ xlen = l->widget.cols - mbstrlen (p); + if (xlen > 0) + tty_printf ("%*s", xlen, " "); + if (!q) +@@ -607,7 +648,7 @@ label_set_text (WLabel *label, const char *text) + if (text){ + label->text = g_strdup (text); + if (label->auto_adjust_cols) { +- newcols = strlen (text); ++ newcols = mbstrlen (text); + if (newcols > label->widget.cols) + label->widget.cols = newcols; + } +@@ -631,7 +672,7 @@ label_new (int y, int x, const char *text) + if (!text || strchr(text, '\n')) + width = 1; + else +- width = strlen (text); ++ width = mbstrlen (text); + + l = g_new (WLabel, 1); + init_widget (&l->widget, y, x, 1, width, label_callback, NULL); +@@ -779,13 +820,69 @@ static void draw_history_button (WInput * in) + /* Pointer to killed data */ + static char *kill_buffer = 0; + ++#ifdef UTF8 ++static int ++charpos(WInput *in, int idx) ++{ ++ int i, pos, l, len; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ i = 0; ++ pos = 0; ++ len = strlen(in->buffer); ++ ++ while (in->buffer[pos]) { ++ if (i == idx) ++ return pos; ++ l = mbrlen(in->buffer + pos, len - pos, &mbs); ++ if (l <= 0) ++ return pos; ++ pos+=l; ++ i++; ++ }; ++ return pos; ++} ++ ++static int ++charcolumn(WInput *in, int idx) ++{ ++ int i, pos, l, width, len; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ i = 0; ++ pos = 0; width = 0; ++ len = strlen(in->buffer); ++ ++ while (in->buffer[pos]) { ++ wchar_t wc; ++ if (i == idx) ++ return width; ++ l = mbrtowc(&wc, in->buffer + pos, len - pos, &mbs); ++ if (l <= 0) ++ return width; ++ pos += l; width += wcwidth(wc); ++ i++; ++ }; ++ return width; ++} ++#else ++#define charpos(in, idx) (idx) ++#define charcolumn(in, idx) (idx) ++#endif /* UTF8 */ ++ + void + update_input (WInput *in, int clear_first) + { + int has_history = 0; + int i, j; +- unsigned char c; +- int buf_len = strlen (in->buffer); ++ int buf_len = mbstrlen (in->buffer); ++#ifndef UTF8 ++ unsigned char c; ++#else /* UTF8 */ ++ wchar_t c; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++#endif /* UTF8 */ + + if (should_show_history_button (in)) + has_history = HISTORY_BUTTON_WIDTH; +@@ -795,7 +892,7 @@ update_input (WInput *in, int clear_first) + + /* Make the point visible */ + if ((in->point < in->first_shown) || +- (in->point >= in->first_shown+in->field_len - has_history)){ ++ (charcolumn(in, in->point) >= charcolumn(in, in->first_shown) + in->field_len - has_history)){ + in->first_shown = in->point - (in->field_len / 3); + if (in->first_shown < 0) + in->first_shown = 0; +@@ -815,14 +912,29 @@ update_input (WInput *in, int clear_first) + addch (' '); + widget_move (&in->widget, 0, 0); + ++#ifndef UTF8 + for (i = 0, j = in->first_shown; i < in->field_len - has_history && in->buffer [j]; i++){ + c = in->buffer [j++]; + c = is_printable (c) ? c : '.'; ++#else /* UTF8 */ ++ for (i = 0, j = in->first_shown; (i < in->field_len - has_history) && (j < buf_len); i++,j++){ ++ char * chp = in->buffer + charpos(in,j); ++ size_t res = mbrtowc(&c, chp, strlen(chp), &mbs); ++ c = (res && iswprint (c)) ? 0 : '.'; ++#endif /* UTF8 */ + if (in->is_password) + c = '*'; ++#ifndef UTF8 + addch (c); ++#else /* UTF8 */ ++ if (c) { ++ addch (c); ++ } ++ else ++ SLsmg_write_nchars (chp, res); ++#endif /* UTF8 */ + } +- widget_move (&in->widget, 0, in->point - in->first_shown); ++ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); + + if (clear_first) + in->first = 0; +@@ -975,7 +1087,7 @@ char * + show_hist (GList *history, int widget_x, int widget_y) + { + GList *hi, *z; +- size_t maxlen = strlen (i18n_htitle ()), i, count = 0; ++ size_t maxlen = mbstrlen (i18n_htitle ()), i, count = 0; + int x, y, w, h; + char *q, *r = 0; + Dlg_head *query_dlg; +@@ -988,7 +1100,7 @@ show_hist (GList *history, int widget_x, int widget_y) + z = g_list_first (history); + hi = z; + while (hi) { +- if ((i = strlen ((char *) hi->data)) > maxlen) ++ if ((i = mbstrlen ((char *) hi->data)) > maxlen) + maxlen = i; + count++; + hi = g_list_next (hi); +@@ -1158,35 +1270,83 @@ new_input (WInput *in) + in->need_push = 1; + in->buffer [0] = 0; + in->point = 0; ++ in->charpoint = 0; + in->mark = 0; + free_completions (in); + update_input (in, 0); + } + ++static void ++move_buffer_backward (WInput *in, int point) ++{ ++ int i, pos, len; ++ int str_len = mbstrlen (in->buffer); ++ if (point >= str_len) return; ++ ++ pos = charpos(in,point); ++ len = charpos(in,point + 1) - pos; ++ ++ for (i = pos; in->buffer [i + len - 1]; i++) ++ in->buffer [i] = in->buffer [i + len]; ++} ++ + static cb_ret_t + insert_char (WInput *in, int c_code) + { + size_t i; ++#ifdef UTF8 ++ mbstate_t mbs; ++ int res; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++#else ++ in->charpoint = 0; ++#endif /* UTF8 */ + + if (c_code == -1) + return MSG_NOT_HANDLED; + ++#ifdef UTF8 ++ if (in->charpoint >= MB_CUR_MAX) return 1; ++ ++ in->charbuf[in->charpoint++] = c_code; ++ ++ res = mbrlen((char *)in->charbuf, in->charpoint, &mbs); ++ if (res < 0) { ++ if (res != -2) in->charpoint = 0; /* broken multibyte char, skip */ ++ return 1; ++ } ++ ++#endif /* UTF8 */ + in->need_push = 1; +- if (strlen (in->buffer)+1 == (size_t) in->current_max_len){ ++ if (strlen (in->buffer) + 1 + in->charpoint >= (size_t) in->current_max_len){ + /* Expand the buffer */ +- char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len); ++ char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len + in->charpoint); + if (narea){ + in->buffer = narea; +- in->current_max_len += in->field_len; ++ in->current_max_len += in->field_len + in->charpoint; + } + } ++#ifndef UTF8 + if (strlen (in->buffer)+1 < (size_t) in->current_max_len){ + size_t l = strlen (&in->buffer [in->point]); + for (i = l+1; i > 0; i--) + in->buffer [in->point+i] = in->buffer [in->point+i-1]; + in->buffer [in->point] = c_code; ++#else /* UTF8 */ ++ if (strlen (in->buffer) + in->charpoint < in->current_max_len){ ++ size_t ins_point = charpos(in,in->point); /* bytes from begin */ ++ /* move chars */ ++ size_t rest_bytes = strlen (in->buffer + ins_point); ++ ++ for (i = rest_bytes + 1; i > 0; i--) ++ in->buffer [ins_point + i + in->charpoint - 1] = in->buffer [ins_point + i - 1]; ++ ++ memcpy(in->buffer + ins_point, in->charbuf, in->charpoint); ++#endif /* UTF8 */ + in->point++; + } ++ in->charpoint = 0; + return MSG_HANDLED; + } + +@@ -1194,12 +1354,14 @@ static void + beginning_of_line (WInput *in) + { + in->point = 0; ++ in->charpoint = 0; + } + + static void + end_of_line (WInput *in) + { +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); ++ in->charpoint = 0; + } + + static void +@@ -1207,18 +1369,21 @@ backward_char (WInput *in) + { + if (in->point) + in->point--; ++ in->charpoint = 0; + } + + static void + forward_char (WInput *in) + { +- if (in->buffer [in->point]) ++ if (in->buffer [charpos(in,in->point)]) + in->point++; ++ in->charpoint = 0; + } + + static void + forward_word (WInput * in) + { ++#ifndef UTF8 + char *p = in->buffer + in->point; + + while (*p +@@ -1228,11 +1393,39 @@ forward_word (WInput * in) + while (*p && isalnum ((unsigned char) *p)) + p++; + in->point = p - in->buffer; ++#else /* UTF8 */ ++ mbstate_t mbs; ++ int len = mbstrlen (in->buffer); ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ while (in->point < len) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (res <= 0 || !(iswspace (c) || iswpunct (c))) ++ break; ++ in->point++; ++ } ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ while (in->point < len) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (res <= 0 || !iswalnum (c)) ++ break; ++ in->point++; ++ } ++ ++ in->charpoint = 0; ++#endif /* UTF8 */ + } + + static void + backward_word (WInput *in) + { ++#ifndef UTF8 + char *p = in->buffer + in->point; + + while (p - 1 > in->buffer - 1 && (isspace ((unsigned char) *(p - 1)) +@@ -1242,6 +1435,32 @@ backward_word (WInput *in) + while (p - 1 > in->buffer - 1 && isalnum ((unsigned char) *(p - 1))) + p--; + in->point = p - in->buffer; ++#else /* UTF8 */ ++ mbstate_t mbs; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ while (in->point > 0) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (*p && (res <= 0 || !(iswspace (c) || iswpunct (c)))) ++ break; ++ in->point--; ++ } ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ while (in->point > 0) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (*p && (res <= 0 || !iswalnum (c))) ++ break; ++ in->point--; ++ } ++ ++ in->charpoint = 0; ++#endif /* UTF8 */ + } + + static void +@@ -1270,12 +1489,12 @@ key_ctrl_right (WInput *in) + static void + backward_delete (WInput *in) + { +- int i; + + if (!in->point) + return; +- for (i = in->point; in->buffer [i-1]; i++) +- in->buffer [i-1] = in->buffer [i]; ++ ++ move_buffer_backward(in, in->point - 1); ++ in->charpoint = 0; + in->need_push = 1; + in->point--; + } +@@ -1283,10 +1502,8 @@ backward_delete (WInput *in) + static void + delete_char (WInput *in) + { +- int i; +- +- for (i = in->point; in->buffer [i]; i++) +- in->buffer [i] = in->buffer [i+1]; ++ move_buffer_backward(in, in->point); ++ in->charpoint = 0; + in->need_push = 1; + } + +@@ -1301,6 +1518,9 @@ copy_region (WInput *in, int x_first, int x_last) + + g_free (kill_buffer); + ++ first=charpos(in,first); ++ last=charpos(in,last); ++ + kill_buffer = g_strndup(in->buffer+first,last-first); + } + +@@ -1309,11 +1529,13 @@ delete_region (WInput *in, int x_first, int x_last) + { + int first = min (x_first, x_last); + int last = max (x_first, x_last); +- size_t len = strlen (&in->buffer [last]) + 1; ++ size_t len; + + in->point = first; + in->mark = first; +- memmove (&in->buffer [first], &in->buffer [last], len); ++ len = strlen (&in->buffer [charpos(in,last)]) + 1; ++ memmove (&in->buffer [charpos(in,first)], &in->buffer [charpos(in,last)], len); ++ in->charpoint = 0; + in->need_push = 1; + } + +@@ -1330,6 +1552,8 @@ kill_word (WInput *in) + copy_region (in, old_point, new_point); + delete_region (in, old_point, new_point); + in->need_push = 1; ++ in->charpoint = 0; ++ in->charpoint = 0; + } + + static void +@@ -1373,16 +1597,20 @@ yank (WInput *in) + + if (!kill_buffer) + return; ++ in->charpoint = 0; + for (p = kill_buffer; *p; p++) + insert_char (in, *p); ++ in->charpoint = 0; + } + + static void + kill_line (WInput *in) + { ++ int chp = charpos(in,in->point); + g_free (kill_buffer); +- kill_buffer = g_strdup (&in->buffer [in->point]); +- in->buffer [in->point] = 0; ++ kill_buffer = g_strdup (&in->buffer [chp]); ++ in->buffer [chp] = 0; ++ in->charpoint = 0; + } + + void +@@ -1392,9 +1620,10 @@ assign_text (WInput *in, const char *text) + g_free (in->buffer); + in->buffer = g_strdup (text); /* was in->buffer->text */ + in->current_max_len = strlen (in->buffer) + 1; +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); + in->mark = 0; + in->need_push = 1; ++ in->charpoint = 0; + } + + static void +@@ -1521,6 +1750,7 @@ port_region_marked_for_delete (WInput *in) + *in->buffer = 0; + in->point = 0; + in->first = 0; ++ in->charpoint = 0; + } + + cb_ret_t +@@ -1549,7 +1779,11 @@ handle_char (WInput *in, int c_code) + } + } + if (!input_map [i].fn){ ++#ifndef UTF8 + if (c_code > 255 || !is_printable (c_code)) ++#else /* UTF8 */ ++ if (c_code > 255) ++#endif /* UTF8 */ + return MSG_NOT_HANDLED; + if (in->first){ + port_region_marked_for_delete (in); +@@ -1582,6 +1816,9 @@ input_set_point (WInput *in, int pos) + if (pos != in->point) + free_completions (in); + in->point = pos; ++#ifdef UTF8 ++ in->charpoint = 0; ++#endif /* UTF8 */ + update_input (in, 1); + } + +@@ -1622,7 +1859,7 @@ input_callback (Widget *w, widget_msg_t msg, int parm) + return MSG_HANDLED; + + case WIDGET_CURSOR: +- widget_move (&in->widget, 0, in->point - in->first_shown); ++ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); + return MSG_HANDLED; + + case WIDGET_DESTROY: +@@ -1646,7 +1883,7 @@ input_event (Gpm_Event * event, void *data) + && should_show_history_button (in)) { + do_show_hist (in); + } else { +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); + if (event->x - in->first_shown - 1 < in->point) + in->point = event->x - in->first_shown - 1; + if (in->point < 0) +@@ -1701,56 +1938,91 @@ input_new (int y, int x, int color, int len, const char *def_text, + in->is_password = 0; + + strcpy (in->buffer, def_text); +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); ++ in->charpoint = 0; + return in; + } + +- +-/* Listbox widget */ ++/* Vertical scrollbar widget */ + +-/* Should draw the scrollbar, but currently draws only +- * indications that there is more information +- */ +-static int listbox_cdiff (WLEntry *s, WLEntry *e); +- +-static void +-listbox_drawscroll (WListbox *l) ++void ++vscrollbar (Widget widget, int height, int width, int tpad, int bpad, ++ int selected, int count, gboolean color) + { + int line; +- int i, top; +- int max_line = l->height-1; +- ++ int i; ++ + /* Are we at the top? */ +- widget_move (&l->widget, 0, l->width); +- if (l->list == l->top) +- one_vline (); ++ widget_move (&widget, tpad, width); ++#ifndef UTF8 ++ if (!selected) ++ one_vline (); ++ else ++ addch ('^'); ++#else ++ if (color) attrset (MARKED_COLOR); ++ if (is_utf8) ++ SLsmg_write_string("âŽ"); + else +- addch ('^'); ++ addch ('^'); ++ if (color) attrset (NORMAL_COLOR); ++#endif + + /* Are we at the bottom? */ +- widget_move (&l->widget, max_line, l->width); +- top = listbox_cdiff (l->list, l->top); +- if ((top + l->height == l->count) || l->height >= l->count) +- one_vline (); ++ widget_move (&widget, height-1-bpad, width); ++#ifndef UTF8 ++ if (selected == count-1) ++ one_vline (); ++ else ++ addch ('v'); ++#else ++ if (color) attrset (MARKED_COLOR); ++ if (is_utf8) ++ SLsmg_write_string("âŸ"); + else +- addch ('v'); ++ addch('v'); ++ if (color) attrset (NORMAL_COLOR); ++#endif + + /* Now draw the nice relative pointer */ +- if (l->count) +- line = 1+ ((l->pos * (l->height-2)) / l->count); ++ if (count > 1) ++ line = tpad + 1 + ((selected * (height-3-tpad-bpad)) / (count-1)); + else +- line = 0; +- +- for (i = 1; i < max_line; i++){ +- widget_move (&l->widget, i, l->width); +- if (i != line) +- one_vline (); +- else +- addch ('*'); ++ line = 0; ++ ++ for (i = tpad + 1; i < height-1-bpad; i++){ ++ widget_move (&widget, i, width); ++ if (i != line) ++#ifndef UTF8 ++ one_vline (); ++ else ++ addch ('*'); ++#else ++ if (is_utf8) ++ SLsmg_write_string("â"); ++ else ++ one_vline(); ++ else { ++ if (color) attrset (MARKED_COLOR); ++ if (is_utf8) ++ SLsmg_write_string("â"); ++ else ++ addch('*'); ++ if (color) attrset (NORMAL_COLOR); ++ } ++#endif + } + } +- +-static void ++ ++ ++/* Listbox widget */ ++ ++/* Should draw the scrollbar, but currently draws only ++ * indications that there is more information ++ */ ++static int listbox_cdiff (WLEntry *s, WLEntry *e); ++ ++void + listbox_draw (WListbox *l, int focused) + { + WLEntry *e; +@@ -1791,7 +2063,7 @@ listbox_draw (WListbox *l, int focused) + if (!l->scrollbar) + return; + attrset (normalc); +- listbox_drawscroll (l); ++ vscrollbar (l->widget, l->height, l->width, 0, 0, l->pos, l->count, FALSE); + } + + /* Returns the number of items between s and e, +diff --git a/src/widget.h b/src/widget.h +index 8c6f781..d1d91f2 100644 +--- a/src/widget.h ++++ b/src/widget.h +@@ -39,6 +39,7 @@ typedef struct WButton { + char *text; /* text of button */ + int hotkey; /* hot KEY */ + int hotpos; /* offset hot KEY char in text */ ++ wchar_t hotwc; + bcback callback; /* Callback function */ + } WButton; + +@@ -59,6 +60,7 @@ typedef struct WCheck { + char *text; /* text of check button */ + int hotkey; /* hot KEY */ + int hotpos; /* offset hot KEY char in text */ ++ wchar_t hotwc; + } WCheck; + + typedef struct WGauge { +@@ -74,16 +76,20 @@ char *show_hist (GList *history, int widget_y, int widget_x); + + typedef struct { + Widget widget; +- int point; /* cursor position in the input line */ +- int mark; /* The mark position */ +- int first_shown; /* Index of the first shown character */ +- int current_max_len; /* Maximum length of input line */ +- int field_len; /* Length of the editing field */ ++ int point; /* cursor position in the input line (mb chars) */ ++ int mark; /* The mark position (mb chars) */ ++ int first_shown; /* Index of the first shown character (mb chars) */ ++ int current_max_len; /* Maximum length of input line (bytes) */ ++ int field_len; /* Length of the editing field (mb chars) */ + int color; /* color used */ + int first; /* Is first keystroke? */ + int disable_update; /* Do we want to skip updates? */ + int is_password; /* Is this a password input line? */ + char *buffer; /* pointer to editing buffer */ ++#ifdef UTF8 ++ char charbuf[MB_LEN_MAX]; ++#endif /* UTF8 */ ++ int charpoint; + GList *history; /* The history */ + int need_push; /* need to push the current Input on hist? */ + char **completions; /* Possible completions array */ +@@ -181,6 +187,10 @@ void button_set_text (WButton *b, const char *text); + /* Listbox manager */ + WLEntry *listbox_get_data (WListbox *l, int pos); + ++/* Vertical scrollbar */ ++void vscrollbar (Widget widget, int height, int width, int tpad, int bpad, ++ int selected, int count, gboolean color); ++ + /* search text int listbox entries */ + WLEntry *listbox_search_text (WListbox *l, const char *text); + void listbox_select_entry (WListbox *l, WLEntry *dest); +diff --git a/src/wtools.c b/src/wtools.c +index ba317e9..a6eaffa 100644 +--- a/src/wtools.c ++++ b/src/wtools.c +@@ -49,11 +49,11 @@ create_listbox_window (int cols, int lines, const char *title, const char *help) + /* Adjust sizes */ + lines = (lines > LINES - 6) ? LINES - 6 : lines; + +- if (title && (cols < (len = strlen (title) + 2))) ++ if (title && (cols < (len = mbstrlen (title) + 2))) + cols = len; + + /* no &, but 4 spaces around button for brackets and such */ +- if (cols < (len = strlen (cancel_string) + 3)) ++ if (cols < (len = mbstrlen (cancel_string) + 3)) + cols = len; + + cols = cols > COLS - 6 ? COLS - 6 : cols; +@@ -124,7 +124,7 @@ query_dialog (const char *header, const char *text, int flags, int count, ...) + va_start (ap, count); + for (i = 0; i < count; i++) { + char *cp = va_arg (ap, char *); +- win_len += strlen (cp) + 6; ++ win_len += mbstrlen (cp) + 6; + if (strchr (cp, '&') != NULL) + win_len--; + } +@@ -133,7 +133,7 @@ query_dialog (const char *header, const char *text, int flags, int count, ...) + + /* count coordinates */ + msglen (text, &lines, &cols); +- cols = 6 + max (win_len, max ((int) strlen (header), cols)); ++ cols = 6 + max (win_len, max ((int) mbstrlen (header), cols)); + lines += 4 + (count > 0 ? 2 : 0); + xpos = COLS / 2 - cols / 2; + ypos = LINES / 3 - (lines - 3) / 2; +@@ -148,7 +148,7 @@ query_dialog (const char *header, const char *text, int flags, int count, ...) + va_start (ap, count); + for (i = 0; i < count; i++) { + cur_name = va_arg (ap, char *); +- xpos = strlen (cur_name) + 6; ++ xpos = mbstrlen (cur_name) + 6; + if (strchr (cur_name, '&') != NULL) + xpos--; + +@@ -467,7 +467,7 @@ fg_input_dialog_help (const char *header, const char *text, const char *help, + } + + msglen (text, &lines, &cols); +- len = max ((int) strlen (header), cols) + 4; ++ len = max ((int) mbstrlen (header), cols) + 4; + len = max (len, 64); + + /* The special value of def_text is used to identify password boxes +@@ -489,7 +489,7 @@ fg_input_dialog_help (const char *header, const char *text, const char *help, + quick_widgets[1].text = _(quick_widgets[1].text); + quick_widgets[0].relative_x = len / 2 + 4; + quick_widgets[1].relative_x = +- len / 2 - (strlen (quick_widgets[1].text) + 9); ++ len / 2 - (mbstrlen (quick_widgets[1].text) + 9); + quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len; + #endif /* ENABLE_NLS */ + +diff --git a/vfs/vfs.c b/vfs/vfs.c +index 39fdc73..1658eaa 100644 +--- a/vfs/vfs.c ++++ b/vfs/vfs.c +@@ -56,6 +56,11 @@ + #include "smbfs.h" + #include "local.h" + ++#include "../src/panel.h" ++#ifdef HAVE_CHARSET ++#include "../src/recode.h" ++#endif ++ + /* They keep track of the current directory */ + static struct vfs_class *current_vfs; + static char *current_dir; +@@ -688,8 +693,66 @@ mc_chdir (const char *path) + vfsid old_vfsid; + int result; + ++#ifdef HAVE_CHARSET ++ char* errmsg; ++#endif ++ WPanel* p=ret_panel; ++ + new_dir = vfs_canon (path); + new_vfs = vfs_get_class (new_dir); ++ old_vfsid = vfs_getid (current_vfs, current_dir); ++ old_vfs = current_vfs; ++ ++ if(p) { ++ ++ // Change from localfs to ftpfs ++ ret_panel=NULL; ++ if( (strcmp(old_vfs->name,"localfs")==0) && ++ (strcmp(new_vfs->name,"ftpfs")==0)){ ++ p->is_return=1; ++ strncpy(p->retdir,current_dir, MC_MAXPATHLEN); ++#ifdef HAVE_CHARSET ++ p->ret_codepage=p->src_codepage; ++ p->src_codepage=ftp_codepage; ++ errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++#endif ++ } ++ ++ // Change from ftpfs to localfs ++ if( (strcmp(old_vfs->name,"ftpfs")==0) && ++ (strcmp(new_vfs->name,"localfs")==0) && ++ p->is_return){ ++ p->is_return=0; ++ g_free(new_dir); ++ new_dir = vfs_canon (p->retdir); ++ new_vfs = vfs_get_class (new_dir); ++#ifdef HAVE_CHARSET ++ p->src_codepage=p->ret_codepage; ++ errmsg=my_init_tt(display_codepage,p->src_codepage,p->tr_table); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++ errmsg=my_init_tt(p->src_codepage,display_codepage,p->tr_table_input); ++ if(errmsg) { ++ panel_reset_codepage(p); ++ message( 1, MSG_ERROR, "%s", errmsg ); ++ } ++#endif ++ } ++ } ++ ++ ++ + if (!new_vfs->chdir) { + g_free (new_dir); + return -1; +@@ -703,9 +766,6 @@ mc_chdir (const char *path) + return -1; + } + +- old_vfsid = vfs_getid (current_vfs, current_dir); +- old_vfs = current_vfs; +- + /* Actually change directory */ + g_free (current_dir); + current_dir = new_dir; diff --git a/pkgs/core/mdadm/mdadm.nm b/pkgs/core/mdadm/mdadm.nm new file mode 100644 index 0000000..2792e7b --- /dev/null +++ b/pkgs/core/mdadm/mdadm.nm @@ -0,0 +1,65 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = mdadm +PKG_VER = 3.0-devel2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://www.kernel.org/pub/linux/utils/raid/mdadm/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = The mdadm program controls Linux md devices (software RAID arrays). + +PKG_BUILD_DEPS+= groff + +define PKG_DESCRIPTION + The mdadm program is used to create, manage, and monitor Linux MD (software \ + RAID) devices. As such, it provides similar functionality to the raidtools \ + package. However, mdadm is a single program, and it can perform \ + almost all functions without a configuration file, though a configuration \ + file can be used to help with some common tasks. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CFLAGS += -fno-strict-aliasing + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -e "s/^INSTALL = .*/INSTALL = install/" -i Makefile +endef + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) CXFLAGS="$(CFLAGS)" \ + SYSCONFDIR="/etc" MDASSEMBLE_AUTO=1 +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install BINDIR=/sbin DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/var/run/mdadm + chmod 700 $(BUILDROOT)/var/run/mdadm +endef diff --git a/pkgs/core/mdadm/patches/mdadm-3.0-devel2-warn.patch b/pkgs/core/mdadm/patches/mdadm-3.0-devel2-warn.patch new file mode 100644 index 0000000..b472010 --- /dev/null +++ b/pkgs/core/mdadm/patches/mdadm-3.0-devel2-warn.patch @@ -0,0 +1,24 @@ +--- mdadm-3.0-devel2/mdopen.c.warn 2009-02-12 09:13:54.000000000 -0500 ++++ mdadm-3.0-devel2/mdopen.c 2009-02-12 09:34:15.000000000 -0500 +@@ -88,8 +88,9 @@ void make_parts(char *dev, int cnt) + if (chmod(name, stb2.st_mode & 07777)) + perror("chmod"); + } else { +- snprintf(sym, 10000, "%s%s%d", orig, odig?"p":"", i); +- symlink(sym, name); ++ snprintf(sym, 1024, "%s%s%d", orig, odig?"p":"", i); ++ if (symlink(sym, name)) ++ perror("symlink"); + } + stat(name, &stb2); + add_dev(name, &stb2, 0, NULL); +@@ -357,7 +358,8 @@ int create_mddev(char *dev, char *name, + strcpy(chosen, devname); + } + } else +- symlink(devname, chosen); ++ if (symlink(devname, chosen)) ++ perror("symlink"); + if (use_mdp && strcmp(chosen, devname) != 0) + make_parts(chosen, parts); + } diff --git a/pkgs/core/memtest86+/memtest86+.nm b/pkgs/core/memtest86+/memtest86+.nm new file mode 100644 index 0000000..e6f4b74 --- /dev/null +++ b/pkgs/core/memtest86+/memtest86+.nm @@ -0,0 +1,56 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = memtest86+ +PKG_VER = 4.00 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://www.memtest.org/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = Stand-alone memory tester for x86 and x86-64 computers. + +define PKG_DESCRIPTION + Memtest86+ is a thorough stand-alone memory test for x86 and x86-64 \ + architecture computers. BIOS based memory tests are only a quick \ + check and often miss many of the failures that are detected by \ + Memtest86+. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CFLAGS += -fno-builtin -ffreestanding + +define STAGE_BUILD + cd $(DIR_APP) && make CC="gcc -fno-stack-protector -fno-PIE" \ + CFLAGS="$(CFLAGS)" memtest.bin $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/boot + cd $(DIR_APP) && cp -vf memtest.bin $(BUILDROOT)/boot/memtest86+ +endef diff --git a/pkgs/core/mkinitramfs/mkinitramfs.nm b/pkgs/core/mkinitramfs/mkinitramfs.nm new file mode 100644 index 0000000..044791b --- /dev/null +++ b/pkgs/core/mkinitramfs/mkinitramfs.nm @@ -0,0 +1,59 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = mkinitramfs +PKG_VER = 0.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Boot +PKG_URL = +PKG_LICENSE = GPL +PKG_SUMMARY = A tool to create initramfs images. + +define PKG_DESCRIPTION + mkinitramfs is intended to create the ultimate initramfs image. +endef + +PKG_TARBALL = + +############################################################################### +# Installation Details +############################################################################### + +STAGE_PREPARE = # Do nothing +STAGE_BUILD = # Do nothing + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/sbin + -mkdir -pv $(BUILDROOT)/usr/lib/mkinitramfs + + install -m 755 $(DIR_SOURCE)/src/lsinitramfs $(BUILDROOT)/sbin/lsinitramfs + install -m 755 $(DIR_SOURCE)/src/mkinitramfs $(BUILDROOT)/sbin/mkinitramfs + install -m 755 $(DIR_SOURCE)/src/mkliveramfs $(BUILDROOT)/sbin/mkliveramfs + install -m 644 $(DIR_SOURCE)/src/functions \ + $(BUILDROOT)/usr/lib/mkinitramfs/functions +endef diff --git a/pkgs/core/mkinitramfs/src/functions b/pkgs/core/mkinitramfs/src/functions new file mode 100644 index 0000000..1c00e13 --- /dev/null +++ b/pkgs/core/mkinitramfs/src/functions @@ -0,0 +1,852 @@ +#!/bin/bash +HEADER="\ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### +" + +## GLOBAL VARIABLES ARE UPPERCASE +## LOCAL VARIABLES ARE LOWERCASE + +VERBOSE= +FORCE= +TARGET= +KERNEL=$(uname -r) +MODULES= + +TMPDIR=$(mktemp -d) + +# Check if we are root +if [ $UID != 0 ]; then + error "$0 must be run as root." + exit 1 +fi + +# Usage +function usage() { + echo "$0 [--help] [-f] [-v] <out-initrd-image> <kernel-version>" + echo " [--with=<module>]" + echo + echo "example: $0 /boot/myinitramfs.img `uname -r`" +} + +# Setting verbose mode +function set_verbose() { + case "$1" in + yes|y|on|1) + VERBOSE=-v + ;; + no|n|off|0) + VERBOSE= + ;; + esac +} + +# Returns if verbose is on or not +function is_verbose() { + [ -n "$VERBOSE" ] && return 0 + return 1 +} + +# Like is_verbose but prints +# the content of $VERBOSE +function get_verbose() { + echo "$VERBOSE" + is_verbose +} + +# Prints text if verbose is on +function vecho() { + is_verbose && echo "$@" +} + +# Prints error if verbose is on +function error() { + vecho "$@" >&2 +} + +function compress() { + cd - >/dev/null + IMAGE=$(mktemp) + vecho "[TASK] Compressing image $TARGET..." + (cd $TMPDIR && find . | cpio -H newc --quiet -o >| $IMAGE) || exit 1 + gzip -c9 $IMAGE > $TARGET +} + +function findone() { + find "$@" | awk '{ print $1; exit; }' +} + +function findall() { + find "$@" +} + +qpushd() { + pushd "$1" >/dev/null 2>&1 +} + +qpopd() { + popd >/dev/null 2>&1 +} + +function read_link() { + READLINK=$(readlink $1) + if grep -q "^/" <<< $READLINK; then + echo $READLINK + else + echo "$(dirname $1)/$READLINK" + fi +} + +function get_dso_deps() { + local bin="$1" + shift + + declare -a FILES + declare -a NAMES + + local LDSO="/lib/ld-linux.so.2" + + declare -i n=0 + while read NAME I0 FILE ADDR I1 ; do + [ "$FILE" == "not" ] && FILE="$FILE $ADDR" + [ "$NAME" == "not" ] && NAME="$NAME $I0" + NAMES[$n]="$NAME" + FILES[$n]="$FILE" + let n++ + done << EOF + $(LD_TRACE_PRELINKING=1 LD_WARN= LD_TRACE_LOADED_OBJECTS=1 \ + $LDSO $bin 2>/dev/null) +EOF + + [ ${#FILES[*]} -eq 0 ] && return 1 + + # we don't want the name of the binary in the list + if [ "${FILES[0]}" == "$bin" ]; then + FILES[0]="" + NAMES[0]="" + [ ${#FILES[*]} -eq 1 ] && return 1 + fi + + declare -i n=0 + while [ $n -lt ${#FILES[*]} ]; do + local FILE="${FILES[$n]}" + local NAME="${NAMES[$n]}" + if [ "$FILE" == "not found" -o "$NAME" == "not found" ]; then + cat 1>&2 <<EOF +There are missing files on your system. The dynamic object $bin +requires ${NAMES[$n]} n order to properly function. mkinitramfs cannot continue. +EOF + return 1 + fi + case "$FILE" in + /lib*) + TLIBDIR=`echo "$FILE" | sed 's,(/lib[^/]*)/.*$,\1,'` + BASE=`basename "$FILE"` + if [ -f "$TLIBDIR/$BASE" ]; then + FILE="$TLIBDIR/$BASE" + fi + FILES[$n]="$FILE" + ;; + esac + let n++ + done + echo "${FILES[@]}" +} + +function install() { + local file dest + for file in $@; do + local msg="[FILE]" + + ## Check if this is an absolute path + if [ "$(basename $file)" = "$file" ]; then + file=$(which $file) + fi + + # Destination file + dest="$TMPDIR$file" + [ -e "$dest" ] && continue + + mkdir -p "$(dirname $dest)" 2>/dev/null + + local old_indent=$INDENT + INDENT=" $INDENT" + + [ "${file%%.ko}" != "${file}" ] && msg="[KMOD]" + [ -L "$file" ] && msg="[SYML]" + #vecho "$msg$INDENT$file -> $dest" + vecho "$msg$INDENT$file" + + # Check if $file is a symlink + if [ -L "$file" ]; then + install $(read_link $file) + fi + + if [ "${file%%.ko}" != "${file}" ]; then + for i in $(moduledep $file); do + [ "$(locatemodule $i)" = "$file" ] && continue + installmodule $i + done + fi + + cp -ld $file $dest + + # Check if file is a script file + if [ "$(dd if=$file bs=2 count=1 2>/dev/null)" = "#!" ]; then + install $(head -n 1 $file | cut -c3-) + # Check if file is a kernel module + elif [ "${file%%.ko}" != "${file}" ]; then + local firmware + for firmware in $(modinfo -F firmware $file 2>/dev/null); do + firmware="/lib/firmware/$firmware" + [ -e "$firmware" ] && install $firmware + done + else + for dep in $(get_dso_deps "$file"); do + install $dep + done + fi + + INDENT=$old_indent + done +} + +# find module dependencies +function moduledep() { + local deps mpargs + if [ "$1" == "--ignore-install" ]; then + mpargs="$mpargs --ignore-install" + shift + fi + local module=$(basename ${1%%.ko}) + modprobe $mpargs --set-version $KERNEL --show-depends $module 2>/dev/null | \ + awk '/^insmod / { print gensub(".*/","","g",$2) }' | \ + while read foo; do \ + [ "${foo%%.ko}" != "$1" ] && \ + echo -n "${foo%%.ko} "; \ + done +} + +# XXX May be, we can drop this... +# This loops to make sure it resolves dependencies of dependencies of... +function resolvemoduledeps () { + local dep + local deps + local module + local newmodules + local modules=$@ + + before=0; after=1 + while [ $before != $after ]; do + newmodules= + before=$(wc -c <<< $modules) + for module in $modules; do + deps=$(moduledep $module) + is_verbose && echo "Module $module depends on: $deps" + newmodules="$newmodules $module $deps" + done + modules=$(for i in $newmodules; do echo $i; done | sort -u) + after=$(wc -c <<< $modules) + done + echo $modules +} + +function locatemodule() { + local mpargs="" + if [ "$1" == "--ignore-install" ]; then + mpargs="$mpargs --ignore-install" + shift + fi + local path=$(modprobe $mpargs --set-version $KERNEL --show-depends $1 2>/dev/null | \ + awk '/^insmod / { print $2; }' | tail -n 1) + [ -n "$path" -a -f "$path" ] && echo $path +} + +function installmodule() { + local module + local load + for module in $@; do + [ "$module" = "--load" ] && load=1 + module=$(locatemodule $module) + [ -z "$module" ] && continue + + install $module + done + if [ "$load" = "1" ]; then + for module in $@; do + [ "$module" = "--load" ] && continue + cat >> $TMPDIR/sbin/real-init <<EOF +vecho "Loading module $i..." +modprobe $i +EOF + done + fi +} + +resolve_device_name() { + if [[ "$1" =~ ^/dev ]]; then + echo $1 + else + findfs $1 + fi +} + +function finalize() { + qpopd + + # Adding modules + installmodule $MODULES + + # Build module deps file so we can use modprobe + vecho "[TASK] Running depmod..." + depmod -a -b "$TMPDIR" $KERNEL + + # ldconfig + install /etc/ld.so.conf + [ -d "/etc/ld.so.conf.d" ] && \ + for i in $(find /etc/ld.so.conf.d -type f); do + install $i + done + vecho "[TASK] Running ldconfig..." + ldconfig -r $TMPDIR + + # Compressing + compress + rm -rf $TMPDIR 2>/dev/null +} + +# resolve a device node to its major:minor numbers in decimal or hex +function get_numeric_dev() { + ( fmt="%d:%d" + if [ "$1" == "hex" ]; then + fmt="%x:%x" + fi + ls -lH "$2" | awk '{ sub(/,/, "", $5); printf("'"$fmt"'", $5, $6); }' + ) 2>/dev/null +} + +function resolve_device_name() { + if [[ "$1" =~ ^/dev ]]; then + echo $1 + else + findfs $1 + fi +} + +function finddevnoinsys() { + majmin="$1" + if [ -n "$majmin" ]; then + dev=$(for x in /sys/block/* ; do find $x/ -name dev ; done | while read device ; do \ + echo "$majmin" | cmp -s $device && echo $device ; done) + if [ -n "$dev" ]; then + dev=${dev%%/dev} + dev=${dev%%/} + echo "$dev" + return 0 + fi + fi + return 1 +} + +findblockdevinsys() { + devname=$(resolve_device_name "$1") + if [[ "$devname" =~ ^/sys/block/ ]]; then + echo "$devname" + fi + majmin=$(get_numeric_dev dec $devname) + finddevnoinsys "$majmin" +} + +findstoragedriverinsys () { + while [ ! -L device ]; do + for slave in $(ls -d slaves/* 2>/dev/null) ; do + slavename=${slave##*/} + case " $slavestried " in + *" $slavename "*) + continue + ;; + *) + slavestried="$slavestried $slavename" + qpushd $slave + findstoragedriverinsys + qpopd + ;; + esac + done + [ "$PWD" = "/sys" ] && return + cd .. + done + cd $(read_link ./device) + if echo $PWD | grep -q /virtio-pci/ ; then + installmodule --load virtio_pci + fi + while [ "$PWD" != "/sys/devices" ]; do + deps= + if [ -f modalias ]; then + installmodule --load $(cat modalias) + fi + + [ -z "$deps" -a -L driver/module ] && \ + deps=$(basename $(read_link driver/module)) + installmodule --load $deps + cd .. + done +} + +function findstoragedriver() { + for device in $@; do + case " $handleddevices " in + *" $device "*) + continue ;; + *) handleddevices="$handleddevices $device" ;; + esac + vecho "[INFO] Looking for driver for device $device" + if [[ "$device" =~ ^/sys ]]; then + device=${device##*/} + fi + sysfs="" + device=$(echo "$device" | sed 's,/,!,g') + if [ -d /sys/block/$device/ ]; then + sysfs="/sys/block/$device" + else + sysfs=$(for x in /sys/block/*; do findone $x/ -type d -name $device; done) + fi + [ -z "$sysfs" ] && return + qpushd $sysfs + findstoragedriverinsys + qpopd + done +} + +# Main +while [ $# -gt 0 ] ; do + case $1 in + --help) + usage + exit 0 + ;; + -f|--force) + FORCE=yes + ;; + -v|--verbose) + set_verbose on + ;; + --with=*) + MODULES="$MODULES ${1#--with=*}" + ;; + --with-net) + WITH_NET=1 + ;; + *) + if [ -z "$target" ] ; then + target=$1 + elif [ -z "$kernel" ] ; then + kernel=$1 + else + echo "Unknown option or parameter "$1"" + usage + exit 1 + fi + ;; + esac + + shift +done + +TARGET=${target-$TARGET} +KERNEL=${kernel-$KERNEL} + +if [ -z "$TARGET" ]; then + usage + exit 1 +fi + +[[ "$TARGET" =~ "^/" ]] && TARGET="$PWD/$TARGET" + +if [ -z "$FORCE" ] && [ -e "$TARGET" ]; then + echo "Image $TARGET already exists. Use -f to overwrite" + exit 1 +fi + +# Changing to our dir, where we do our actions in +qpushd $TMPDIR || exit 1 + +# Make directory structure +mkdir -p bin sbin dev sys proc sysroot \ + etc/udev/rules.d lib/udev/rules.d + +# Install some essential binaries +install bash blkid chmod cat cut dmesg env find grep head ip kbd_mode \ + kill killall5 less ln \ + ls lsmod mkdir mknod modprobe mount mountpoint openvt pidof ps rm sed \ + setfont sh sleep switch_root udevadm udevd umount \ + /lib/udev/console_init + +# Copy modprobe.conf and friends over +[ -e /etc/modprobe.conf ] && install /etc/modprobe.conf +for f in $(find /etc/modprobe.d -type f); do + install $f +done + +# Install an empty fstab +touch $TMPDIR/etc/fstab + +# terminfo bits make things work better if you fall into interactive mode +[ -d "/usr/lib/terminfo" ] && \ + for f in $(find /usr/lib/terminfo -type f); do + install $f + done + +# Add localization +if [ -e "/etc/sysconfig/console" ]; then + install /etc/sysconfig/console + . /etc/sysconfig/console +fi +[ -z "$FONT" ] && FONT="LatArCyrHeb-16" +for i in /lib/kbd/consolefonts/$FONT.*; do + mkdir -p $TMPDIR/$(dirname $i) 2>/dev/null || true + cp -f $i $TMPDIR/$i + case "$i" in + *.gz) + gzip -fd $TMPDIR/$i + ;; + *.bz2) + bzip2 -fd $TMPDIR/$i + ;; + esac +done + +cat > init <<'EOF' +#!/bin/sh + +# Mounting directories +mount -t proc proc /proc +mount -t sysfs /sys /sys +mount -t tmpfs -o mode=0755 udev /dev + +# Silencing kernel +echo > /proc/sys/kernel/printk "1 4 1 7" + +# Adding important dev nodes +mknod /dev/console c 5 1 +mknod /dev/null c 1 3 +mknod /dev/kmsg c 1 11 +mknod /dev/ptmx c 5 2 +mknod /dev/fb c 29 0 +mknod /dev/systty c 4 0 + +# XXX really we need to openvt too, in case someting changes the +# color palette and then changes vts on fbcon before gettys start. +# (yay, fbcon bugs!) +for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 ; do + mknod /dev/tty$i c 4 $i +done + +for i in 0 1 2 3 ; do + mknod /dev/ttyS$i c 4 $(($i + 64)) +done + +mkdir -m 1777 /dev/shm +ln -s /proc/self/fd /dev/fd +ln -s fd/0 /dev/stdin +ln -s fd/1 /dev/stdout +ln -s fd/2 /dev/stderr + +mkdir /dev/pts +mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts + +exec sbin/real-init +EOF +chmod 755 init + +# Write out real-init +touch sbin/real-init; chmod 755 sbin/real-init +cat > sbin/real-init <<'EOF' +#!/bin/bash +$HEADER + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin +export TERM=linux + +init="/sbin/init" +VERBOSE=-v + +READONLY=0 +SHELL=0 +ESHELL=0 + +function emergency_shell() +{ + echo "Bug in initramfs /init detected. Dropping to a shell. Good luck!" + echo + bash +} +trap "emergency_shell" 0 2 + +# exit immediately if a command fails +set -e + +# Setting verbose mode +function set_verbose() { + case "$1" in + yes|y|on|1) + VERBOSE=-v + ;; + no|n|off|0) + VERBOSE= + ;; + esac +} + +# Returns if verbose is on or not +function is_verbose() { + [ -n "$VERBOSE" ] && return 0 + return 1 +} + +# Like is_verbose but prints +# the content of $VERBOSE +function get_verbose() { + echo "$VERBOSE" + is_verbose +} + +# Prints text if verbose is on +function vecho() { + if is_verbose; then echo "$@"; fi +} + +# Prints error if verbose is on +function error() { + vecho "$@" >&2 +} + +/lib/udev/console_init tty0 + +# Disable hotplugging +echo "" > /proc/sys/kernel/hotplug + +# Parse kernel commandline options +for o in $(cat /proc/cmdline) ; do + case $o in + init=*) + init=${o#init=} + ;; + ro) + READONLY=1 + ;; + rw) + READONLY=0 + ;; + quiet) + set_verbose no + ;; + shell) + SHELL=1 + ;; + eshell) + ESHELL=1 + ;; + blacklist=*) + echo "blacklist ${o#blacklist=}" >> /etc/modprobe.conf + ;; + *) + m=$(echo $o |cut -s -d . -f 1) + opt=$(echo $o |cut -s -d . -f 2-) + if [ -z "$m" -o -z "$opt" ]; then + continue + fi + p=$(echo $opt |cut -s -d = -f 1) + v=$(echo $opt |cut -s -d = -f 2-) + if [ -z "$p" -o -z "$v" ]; then + continue + fi + echo "options $m $p=$v" >> /etc/modprobe.conf + ;; + esac +done + +vecho "kernel commandline: $(cat /proc/cmdline)" +EOF + +if [ "${WITH_NET}" = "1" ]; then + MODULES="$MODULES af_packet" + for module in /lib/modules/$KERNEL/kernel/drivers/net/{,*/}*; do + MODULES="$MODULES $(basename ${module/.ko})" + done + + install arping curl dhclient ip ping sha1sum /etc/nsswitch.conf \ + /usr/lib/libnsl.so /usr/lib/libnss_{dns,files}.so + touch etc/hosts + mkdir -p $TMPDIR/var/lib/dhclient 2>/dev/null + + cat > sbin/dhclient-script <<'EOF' +#!/bin/sh + +PATH=/usr/sbin:/sbin:/usr/bin:/bin + +function ip_encode() { + IFS=. + + local int=0 + for field in $1; do + int=$(( $(( $int << 8 )) | $field )) + done + + echo $int + unset IFS +} + +function mask_to_cidr() { + local mask + mask=$(ip_encode $1) + local cidr + cidr=0 + local x + x=$(( 128 << 24 )) # 0x80000000 + + while [ $(( $x & $mask )) -ne 0 ]; do + [ $mask -eq $x ] && mask=0 || mask=$(( $mask << 1 )) + cidr=$(($cidr + 1)) + done + + if [ $(( $mask & 2147483647 )) -ne 0 ]; then # 2147483647 = 0x7fffffff + echo "Invalid net mask: $1" >&2 + else + echo $cidr + fi +} + +function ip_in_subnet() { + local netmask + netmask=$(_netmask $2) + [ $(( $(ip_encode $1) & $netmask)) = $(( $(ip_encode ${2%/*}) & $netmask )) ] +} + +function _netmask() { + local vlsm + vlsm=${1#*/} + [ $vlsm -eq 0 ] && echo 0 || echo $(( -1 << $(( 32 - $vlsm )) )) +} + +dhconfig() { + if [ -n "${old_ip_address}" ] && + [ ! "${old_ip_address}" = "${new_ip_address}" ]; then + # IP address changed. Bringing down the interface will delete all + # routes, and clear the ARP cache. + ip -family inet addr flush dev ${interface} >/dev/null 2>&1 + ip -family inet link set dev ${interface} down + fi + + if [ "${reason}" = "BOUND" ] || [ "${reason}" = "REBOOT" ] || + [ ! "${old_ip_address}" = "${new_ip_address}" ] || + [ ! "${old_subnet_mask}" = "${new_subnet_mask}" ] || + [ ! "${old_network_number}" = "${new_network_number}" ] || + [ ! "${old_broadcast_address}" = "${new_broadcast_address}" ] || + [ ! "${old_routers}" = "${new_routers}" ] || + [ ! "${old_interface_mtu}" = "${new_interface_mtu}" ]; then + ip -family inet addr add ${new_ip_address}/${new_prefix} \ + broadcast ${new_broadcast_address} dev ${interface} + + if [ -n "${new_interface_mtu}" ]; then + ip link set ${interface} mtu ${new_interface_mtu} + fi + + for router in ${new_routers}; do + if ! ip_in_subnet ${router} ${new_ip_address}/${new_prefix}; then + continue + fi + ip route replace default via ${router} + break + done + fi + + if [ "${reason}" = "RENEW" ] && \ + [ "${new_domain_name}" = "${old_domain_name}" ] && \ + [ "${new_domain_name_servers}" = "${old_domain_name_servers}" ]; then + return + fi + + if [ -n "${new_domain_name}" ] || [ -n "${new_domain_name_servers}" ] || \ + [ -n "${new_domain_search}" ]; then + + echo "; generated by $0" > /etc/resolv.conf + + if [ -n "${new_domain_search}" ]; then + echo "search ${new_domain_search//\032/ }" >> /etc/resolv.conf + elif [ -n "${new_domain_name}" ]; then + echo "search ${new_domain_name//\032/ }" >> /etc/resolv.conf + fi + + for nameserver in ${new_domain_name_servers} ; do + echo "nameserver ${nameserver}" >> /etc/resolv.conf + done + fi + + if [ -n "${new_host_name}" ]; then + hostname ${new_host_name} + fi +} + +new_prefix=$(mask_to_cidr ${new_subnet_mask}) + +case "${reason}" in + MEDIUM) + exit 0 + ;; + + PREINIT) + ip -family inet addr flush dev ${interface} >/dev/null 2>&1 + ip -family inet link set ${interface} up + exit 0 + ;; + + ARPCHECK|ARPSEND) + if [ -z "${new_ip_address}" ] || [ -z "${interface}" ] || \ + arping -q -f -c 2 -w 3 -D -I ${interface} ${new_ip_address}; then + exit 0 + else + exit 1 + fi + ;; + + BOUND|RENEW|REBIND|REBOOT) + dhconfig + exit 0 + ;; + + EXPIRE|FAIL|RELEASE|STOP) + if [ -n "${old_ip_address}" ]; then + # Shut down interface, which will delete routes and clear arp cache. + ip -family inet addr flush dev ${interface} >/dev/null 2>&1 + ip -family inet link set ${interface} down + fi + exit 0 + ;; + + *) + echo "Unhandled state: ${reason}" >&2 + exit 1 + ;; +esac + +EOF + chmod 755 sbin/dhclient-script +fi diff --git a/pkgs/core/mkinitramfs/src/lsinitramfs b/pkgs/core/mkinitramfs/src/lsinitramfs new file mode 100644 index 0000000..154b675 --- /dev/null +++ b/pkgs/core/mkinitramfs/src/lsinitramfs @@ -0,0 +1,32 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +[[ $# -eq 1 ]] || { echo "Usage: $(basename $0) <initrd file>" ; exit 1 ; } +[[ -f $1 ]] || { echo "$1 does not exist" ; exit 1 ; } + +echo "$1:" +echo "========================================================================" +zcat $1 | cpio --extract --verbose --quiet --list +echo "========================================================================" +zcat $1 | cpio --extract --verbose --quiet --to-stdout init +echo "========================================================================" +zcat $1 | cpio --extract --verbose --quiet --to-stdout sbin/real-init +echo "========================================================================" diff --git a/pkgs/core/mkinitramfs/src/mkinitramfs b/pkgs/core/mkinitramfs/src/mkinitramfs new file mode 100644 index 0000000..1925ace --- /dev/null +++ b/pkgs/core/mkinitramfs/src/mkinitramfs @@ -0,0 +1,101 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +. /usr/lib/mkinitramfs/functions + +# Add usb support +MODULES="$MODULES ehci-hcd ohci-hcd uhci-hcd" + +# Get rootfs and options +rootdev=$(awk '/^[ \t]*[^#]/ { if ($2 == "/") { print $1; }}' /etc/fstab) +rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $3; }}' /etc/fstab) +rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; }}' /etc/fstab) +[ -z "$rootopts" ] && rootopts="defaults" + +installmodule --load $rootfs + +if [[ "$rootdev" =~ "^(UUID=|LABEL=)" ]]; then + rootdev=$(resolve_device_name "$rootdev") +fi + +rootopts=$(echo $rootopts | sed -e 's/^r[ow],//' -e 's/,_netdev//' \ + -e 's/_netdev//' -e 's/,r[ow],$//' -e 's/,r[ow],/,/' \ + -e 's/^r[ow]$/defaults/' -e 's/$/,ro/') +physdev=$(findblockdevinsys "$rootdev") +physdev=${physdev##*/dev/} +if [ -n "$physdev" ]; then + vecho "[INFO] Found root device $physdev for $rootdev" +else + physdev="$rootdev" +fi + +if [ -n "$physdev" -a "$physdev" != "$rootdev" ]; then + findstoragedriver ${physdev##/dev/} +fi + +findstoragedriver ${rootdev##/dev/} + +cat >> sbin/real-init <<EOF + +#rootdev=$rootdev +#rootfstype=$rootfs +#rootopts=$rootopts +EOF + +cat >> sbin/real-init <<'EOF' + +# Users can override rootfs target on the kernel commandline +for o in $(cat /proc/cmdline); do + case $o in + root=*) + rootdev=${o#root=} + ;; + rootflags=*) + rootflags=${o#rootflags=} + ;; + rootfstype=*) + rootfstype=${o#rootfstype=} + ;; + esac +done + +vecho "Starting udevd..." +udevd --daemon + +vecho "Creating devices..." +udevadm trigger +udevadm settle + +vecho "Mounting root filesystem $rootdev..." +[ -n "$rootopts" ] && rootopts="-o $rootopts" +[ -n "$rootfstype" ] && rootopts="-t $rootfstype $rootopts" +mount $rootdev /sysroot $rootopts + +kill $(pidof udevd) + +vecho "Switching to new root and running init..." +exec switch_root /sysroot /sbin/init + +echo exec switchroot failed... +bash +EOF + +finalize diff --git a/pkgs/core/mkinitramfs/src/mkliveramfs b/pkgs/core/mkinitramfs/src/mkliveramfs new file mode 100644 index 0000000..beebc7e --- /dev/null +++ b/pkgs/core/mkinitramfs/src/mkliveramfs @@ -0,0 +1,382 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +. /usr/lib/mkinitramfs/functions + +# Modules needed by the live system +MODULES="$MODULES aufs squashfs loop vfat ehci-hcd ohci-hcd uhci-hcd usb-storage" + +# Add all storage modules +for module in /lib/modules/$KERNEL/kernel/drivers/{ata,message/fusion,pcmcia,scsi{,/*}}/*; do + MODULES="$MODULES $(basename ${module/.ko})" +done + +# Creating folders +mkdir -p mnt/{source,tmpfs,overlayfs,squashfs} + +cat >> sbin/real-init <<'EOF' + +netdevice=eth0 + +# Users can override rootfs target on the kernel commandline +for o in $(cat /proc/cmdline); do + case $o in + root=*) + root=${o#root=} + ;; + rootflags=*) + rootflags=${o#rootflags=} + ;; + rootfstype=*) + rootfstype=${o#rootfstype=} + ;; + net=*) + net=${o#net=} + ;; + netdevice=*) + netdevice=${o#netdevice=} + ;; + gateway=*) + gateway=${o#gateway=} + ;; + dns=*) + dns="$dns ${o#dns=}" + ;; + esac +done + +# generate udev rules to generate /dev/root symlink +if [ -z $root ] ; then + root=/dev/something +else + case $root in + /dev/disk/by-label/*) + type="block" + LABEL=${root#/dev/disk/by-label/} + echo "SUBSYSTEM=="block", PROGRAM="/sbin/blkid -s LABEL -o value %N", RESULT=="$LABEL", SYMLINK+="root"" > /etc/udev/rules.d/00-label.rules + if is_verbose; then + echo "Added udev rule 00-label.rules:" + cat /etc/udev/rules.d/00-label.rules + fi + type="block" + ;; + CDLABEL=*) + CDLABEL=${root#CDLABEL=} + echo "KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", ATTRS{media}=="cdrom", PROGRAM="/sbin/blkid -s LABEL -o value %N", RESULT=="$CDLABEL", SYMLINK+="root"" > /etc/udev/rules.d/00-cdlabel.rules + echo "KERNEL=="sr[0-9]", PROGRAM="/sbin/blkid -s LABEL -o value %N", RESULT=="$CDLABEL", SYMLINK+="root"" >> /etc/udev/rules.d/00-cdlabel.rules + echo "KERNEL=="scd[0-9]", PROGRAM="/sbin/blkid -s LABEL -o value %N", RESULT=="$CDLABEL", SYMLINK+="root"" >> /etc/udev/rules.d/00-cdlabel.rules + echo "KERNEL=="pcd[0-9]", PROGRAM="/sbin/blkid -s LABEL -o value %N", RESULT=="$CDLABEL", SYMLINK+="root"" >> /etc/udev/rules.d/00-cdlabel.rules + if is_verbose; then + echo "Added udev rule 00-cdlabel.rules:" + cat /etc/udev/rules.d/00-cdlabel.rules + fi + type="block" + ;; + LABEL=*) + LABEL=${root#LABEL=} + echo "SUBSYSTEM=="block", PROGRAM="/sbin/blkid -s LABEL -o value %N", RESULT=="$LABEL", SYMLINK+="root"" > /etc/udev/rules.d/00-label.rules + if is_verbose; then + echo "Added udev rule 00-label.rules:" + cat /etc/udev/rules.d/00-label.rules + fi + type="block" + ;; + /dev/disk/by-id/*) + UUID=${root#/dev/disk/by-id/} + echo "SUBSYSTEM=="block", PROGRAM="/sbin/blkid -s UUID -o value %N", RESULT=="$UUID", SYMLINK+="root"" > /etc/udev/rules.d/01-uuid.rules + if is_verbose; then + echo "Added udev rule 01-uuid.rules:" + cat /etc/udev/rules.d/01-uuid.rules + fi + type="block" + ;; + UUID=*) + UUID=${root#UUID=} + echo "SUBSYSTEM=="block", PROGRAM="/sbin/blkid -s UUID -o value %N", RESULT=="$UUID", SYMLINK+="root"" > /etc/udev/rules.d/01-uuid.rules + if is_verbose; then + echo "Added udev rule 01-uuid.rules:" + cat /etc/udev/rules.d/01-uuid.rules + fi + type="block" + ;; + http://*|https://*|ftp*://*|ftps://*|scp://*|sftp://*) + thingtofetch="${root}" + type="download" + + # When doing http(s) transfers, compress the data + if [ "${thingtofetch:0:4}" = "http" ]; then + curloptions="--compressed" + fi + ;; + /dev/*) + ln -s $root /dev/root + type="block" + ;; + *) + thingtomount=$root + ;; + esac +fi + +if [ "$type" = "block" ]; then + thingtomount=/dev/root + +elif [ "$type" = "download" ]; then + rootflags="loop" + thingtomount=/${thingtofetch##*/} + + # If no network configuration was given, + # we'll try dhcp + if [ -z "${net}" ]; then + net="dhcp" + fi +fi + +echo "udev_log="error"" >> /etc/udev/udev.conf + +# rules for loading modules +echo -n "ACTION=="add", SUBSYSTEM=="?*", ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $" >> /etc/udev/rules.d/10-modprobe.rules +echo "env{MODALIAS}"" >> /etc/udev/rules.d/10-modprobe.rules +echo "ACTION=="add", SUBSYSTEM=="scsi_device" RUN+="/sbin/modprobe sg"" >> /etc/udev/rules.d/10-modprobe.rules +echo "ACTION=="add", SUBSYSTEM=="scsi_device", SYSFS{type}=="0|7|14", RUN+="/sbin/modprobe sd_mod"" >> /etc/udev/rules.d/10-modprobe.rules +echo "ACTION=="add", SUBSYSTEM=="scsi_device", SYSFS{type}=="[45]", RUN+="/sbin/modprobe sr_mod"" >> /etc/udev/rules.d/10-modprobe.rules +echo "SUBSYSTEM=="mmc", RUN+="/sbin/modprobe mmc_block"" >> /etc/udev/rules.d/10-modprobe.rules + +if [ "${type}" = "block" ]; then + # FIXME: hack since sr_mod seems to fail to get loaded sometimes (#239657) + modprobe sr_mod +fi + +modprobe loop max_loop=16 + +vecho "Starting udevd..." +udevd --daemon + +vecho "Creating devices..." +udevadm trigger + +if [ "${type}" = "download" ]; then + # Wait 30 seconds for network to appear. + COUNTDOWN=30 + while [ "x$COUNTDOWN" != "x0" ] ; do + is_verbose && echo -n "." + + if ip link show $netdevice &>/dev/null; then + COUNTDOWN=0 + continue + fi + + COUNTDOWN=$(($COUNTDOWN - 1)) + sleep 1 + done + vecho # Blank line + + ip link set $netdevice up + if [ "$net" = "dhcp" ]; then + vecho "Getting an IP address by DHCP..." + dhclient $(get_verbose) $netdevice + else + vecho "Setting IP address $net..." + ip addr add $net dev $netdevice + fi + if [ -n "$gateway" ]; then + vecho "Setting default gateway $gateway..." + ip route add default via $gateway + fi + if [ -n "$dns" ]; then + vecho "Setting up dns server $dns..." + echo "nameserver $dns" > /etc/resolv.conf + fi + if [ -n "$gateway" ]; then + vecho "Pinging gateway $gateway..." + if ! ping -c3 -w10 $gateway &>/dev/null; then + echo "This box does not seem to have a connection" + echo "to the default gateway $gateway." + echo "You may fix this now and continue then:" + echo + bash + fi + fi +fi + +if [ "$type" = "download" ]; then + curloptions="${curloptions} --connect-timeout 30 --output ${thingtomount}" + #curloptions="${curloptions} --write-out="Fetched %{url_effective} in %{time_total}s (%{speed_download} bytes/s)."" + + vecho "Running donwload..." + vecho " $thingtofetch" + + curl ${curloptions} ${thingtofetch} + + if [ "$?" != "0" ]; then + echo "An error occured when fetching ${thingtomount}:" + echo " Command: ${curl} ${thingtofetch}" + echo + echo "You now get a shell to download the file manually." + echo "Exit to continue booting." + echo + bash + fi +fi + +if [ "$SHELL" == "1" ] ; then + echo "Shell requested on kernel commandline. Exit to continue booting." + echo + bash +fi + +if [ "${type}" = "block" ]; then + # Wait 90 seconds for $thingtomount to appear. + COUNTDOWN=90 + while [ "x$COUNTDOWN" != "x0" ] ; do + is_verbose && echo -n "." + + if [ -e $thingtomount ]; then + COUNTDOWN=0 + continue + fi + # this is kind of lame, but we could have had a situation + # where we were unable to read the volume id. so trigger + # another run through the block devs + if [ "x$COUNTDOWN" = "x30" ]; then + udevadm trigger --subsystem-match=block + fi + + COUNTDOWN=$(($COUNTDOWN - 1)) + sleep 1 + done + vecho # Blank line +fi + +if [ ! -e $thingtomount ] ; then + echo + echo "--------------------------------------" + echo "WARNING: Cannot find root file system!" + echo "--------------------------------------" + echo + echo "Create symlink $thingtomount and then exit this shell to continue" + echo "the boot sequence." + echo + bash +fi + +if is_verbose; then + vecho "Mounting $thingtomount..." + ls -lh $thingtomount +fi + +if [ "x$READONLY" == "x1" ] ; then + rootflags="$rootflags,ro" +else + rootflags="$rootflags,rw" +fi + +if [ -n $rootflags ]; then + mountoptions=" -o$rootflags" +fi + +[ -n "$rootfstype" ] && rootfstype="-t $rootfstype" + +mount -n $rootfstype $mountoptions $thingtomount /mnt/source + +if [ "$?" != "0" ]; then + echo "---------------------------------" + echo "WARNING: Cannot mount rootfs!" + echo "---------------------------------" + echo + echo "Dropping to a shell. " + echo "Mount /mnt/source and exit shell to continue. Good luck!" + echo + bash +fi + +mount -n -t tmpfs none /mnt/tmpfs +aufsmountoptions="br:/mnt/tmpfs=rw" + +count=0 +for overlay in $(find /mnt/source -name "*.overlay" 2>/dev/null); do + vecho "Setting up overlay ${overlay}..." + mkdir -p /mnt/overlay${count} 2>/dev/null + mount -n -t squashfs -o loop,ro ${overlay} /mnt/overlay${count} + aufsmountoptions="$aufsmountoptions:/mnt/overlay${count}=rr" + count=$((${count} + 1)) +done + +count=0 +for sfs in $(find /mnt/source -name "*.sfs" 2>/dev/null); do + vecho "Setting up squashed fs ${sfs}..." + mount -n -t squashfs -o loop,ro ${sfs} /mnt/squashfs + aufsmountoptions="$aufsmountoptions:/mnt/squashfs=rr" + break +done + +mount -t aufs -o $aufsmountoptions none /sysroot + +for i in $(cd /mnt; ls); do + mountpoint /mnt/$i >/dev/null || continue + mkdir -p /sysroot/mnt/$i || : + mount --move /mnt/$i /sysroot/mnt/$i +done + +# Shutting down network +if [ "${type}" = "download" ]; then + if [ "${net}" = "dhcp" ]; then + kill $(pidof dhclient) + else + ip address flush dev ${netdevice} + fi + ip link set ${netdevice} down + ip route flush table main +fi + +if [ "$ESHELL" == "1" ]; then + echo "Shell requested on kernel commandline." + echo "Rootfs is mounted ro on /sysroot. Exit to continue booting." + echo + bash +fi + +if [ -x /sysroot$init ]; then + # Leave initramfs and transition to rootfs + kill $(pidof udevd) + vecho "Transfering control to $init" + + exec switch_root /sysroot ${init} + echo "---------------------------------" + echo "WARNING: Error switching to real rootfs!" + echo "---------------------------------" + echo + echo "Dropping to a shell. Good luck!" + echo + bash +else + echo "---------------------------------------------------------" + echo "WARNING: Requested $init binary does not exist on rootfs." + echo "---------------------------------------------------------" + echo + echo "Dropping to a shell. Good luck!" + echo + bash +fi + +EOF + +finalize diff --git a/pkgs/core/module-init-tools/modprobe.d/blacklist.conf b/pkgs/core/module-init-tools/modprobe.d/blacklist.conf new file mode 100644 index 0000000..b393b22 --- /dev/null +++ b/pkgs/core/module-init-tools/modprobe.d/blacklist.conf @@ -0,0 +1,38 @@ +# +# Listing a module here prevents the hotplug scripts from loading it. +# Usually that'd be so that some other driver will bind it instead, +# no matter which driver happens to get probed first. Sometimes user +# mode tools can also control driver binding. +# +# Syntax: driver name alone (without any spaces) on a line. Other +# lines are ignored. +# + +# watchdog drivers +blacklist i8xx_tco + +# framebuffer drivers +blacklist aty128fb +blacklist atyfb +blacklist radeonfb +blacklist i810fb +blacklist cirrusfb +blacklist intelfb +blacklist kyrofb +blacklist i2c-matroxfb +blacklist hgafb +blacklist nvidiafb +blacklist rivafb +blacklist savagefb +blacklist sisfb +blacklist sstfb +blacklist neofb +blacklist tridentfb +blacklist tdfxfb +blacklist virgefb +blacklist vga16fb + +# ISDN - see bugs 154799, 159068 +blacklist hisax +blacklist hisax_fcpcipnp + diff --git a/pkgs/core/module-init-tools/modprobe.d/modprobe.conf b/pkgs/core/module-init-tools/modprobe.d/modprobe.conf new file mode 100644 index 0000000..2f053cc --- /dev/null +++ b/pkgs/core/module-init-tools/modprobe.d/modprobe.conf @@ -0,0 +1,167 @@ +# default modutils aliases +alias binfmt-204 binfmt_aout +alias binfmt-263 binfmt_aout +alias binfmt-264 binfmt_aout +alias binfmt-267 binfmt_aout +alias binfmt-387 binfmt_aout +alias block-major-1-* rd +alias block-major-3-* ide-probe-mod +alias block-major-8-* sd_mod +alias block-major-9-* md +alias block-major-11-* sr_mod +alias block-major-13-* xd +alias block-major-15-* cdu31a +alias block-major-16-* gscd +alias block-major-17-* optcd +alias block-major-18-* sjcd +alias block-major-20-* mcdx +alias block-major-22-* ide-probe-mod +alias block-major-23-* mcd +alias block-major-24-* sonycd535 +alias block-major-25-* sbpcd +alias block-major-26-* sbpcd +alias block-major-27-* sbpcd +alias block-major-29-* aztcd +alias block-major-32-* cm206 +alias block-major-33-* ide-probe-mod +alias block-major-34-* ide-probe-mod +alias block-major-37-* ide-tape +alias block-major-44-* ftl +alias block-major-46-* pcd +alias block-major-47-* pf +alias block-major-56-* ide-probe-mod +alias block-major-57-* ide-probe-mod +alias block-major-88-* ide-probe-mod +alias block-major-89-* ide-probe-mod +alias block-major-90-* ide-probe-mod +alias block-major-91-* ide-probe-mod +alias block-major-93-* nftl +alias block-major-113-* viocd +alias char-major-4-* serial +alias char-major-5-* serial +alias char-major-9-* st +alias char-major-10-2 msbusmouse +alias char-major-10-3 atixlmouse +alias char-major-10-135 rtc +alias char-major-10-139 openprom +alias char-major-10-157 applicom +alias char-major-10-175 agpgart +alias char-major-10-250 hci_vhci +alias char-major-13-* input +alias char-major-13-0 joydev +alias char-major-13-32 mousedev +alias char-major-19-* cyclades +alias char-major-20-* cyclades +alias char-major-22-* pcxx +alias char-major-23-* pcxx +alias char-major-27-* zftape +alias char-major-34-* scc +alias char-major-35-* tclmidi +alias char-major-36-* netlink +alias char-major-48-* riscom8 +alias char-major-49-* riscom8 +alias char-major-57-* esp +alias char-major-58-* esp +alias char-major-63-* kdebug +alias char-major-90-* mtdchar +alias char-major-96-* pt +alias char-major-97-* pg +alias char-major-107-* 3dfx +alias char-major-109-* lvm-mod +alias char-major-188-* usbserial +alias char-major-200-* vxspec +alias char-major-206-* osst +alias char-major-216-* rfcomm +alias dos msdos +alias dummy0 dummy +alias dummy1 dummy +alias iso9660 isofs +alias net-pf-1 unix +alias net-pf-2 ipv4 +alias net-pf-17 af_packet +alias netalias-2 ip_alias +alias irlan0 irlan +alias irda-dongle-0 tekram +alias irda-dongle-1 esi +alias irda-dongle-2 actisys +alias irda-dongle-3 actisys +alias irda-dongle-4 girbil +alias irda-dongle-5 litelink +alias irda-dongle-6 airport +alias irda-dongle-7 old_belkin +alias plip0 plip +alias plip1 plip +alias tunl0 ipip +alias cipcb0 cipcb +alias cipcb1 cipcb +alias cipcb2 cipcb +alias cipcb3 cipcb +alias slip0 slip +alias slip1 slip +alias tty-ldisc-1 slip +alias tty-ldisc-3 ppp_async +alias tty-ldisc-11 irtty-sir +alias tty-ldisc-14 ppp_synctty +alias tty-ldisc-15 hci_uart +alias ppp-compress-18 ppp_mppe +install ppp-compress-21 /bin/true +alias ppp-compress-24 ppp_deflate +alias ppp-compress-26 ppp_deflate +alias parport_lowlevel parport_pc +alias usbdevfs usbcore +alias xfrm-type-2-50 esp4 +alias xfrm-type-2-51 ah4 +alias xfrm-type-2-108 ipcomp +alias xfrm-type-10-50 esp6 +alias xfrm-type-10-51 ah6 +alias xfrm-type-10-108 ipcomp6 +alias cipher_null crypto_null +alias digest_null crypto_null +alias compress_null crypto_null +alias sha384 sha512 +install binfmt-0000 /bin/true +install binfmt_misc /sbin/modprobe --first-time --ignore-install binfmt_misc && { /bin/mount -t binfmt_misc none /proc/sys/fs/binfmt_misc > /dev/null 2>&1 || :; } +install nfsd /sbin/modprobe --first-time --ignore-install nfsd && { /bin/mount -t nfsd nfsd /proc/fs/nfsd > /dev/null 2>&1 || :; } +install sunrpc /sbin/modprobe --first-time --ignore-install sunrpc && { /bin/mount -t rpc_pipefs sunrpc /var/lib/nfs/rpc_pipefs > /dev/null 2>&1 || :; } +install char-major-10 /bin/true +install char-major-10-1 /bin/true +install dummy0 /sbin/modprobe -o dummy0 --ignore-install dummy +install dummy1 /sbin/modprobe -o dummy1 --ignore-install dummy +install net-pf-19 /bin/true +install net-pf-3 /bin/true +install net-pf-6 /bin/true +install ov518_decomp { /sbin/modprobe ov511; } ; /sbin/modprobe --first-time --ignore-install ov518_decomp +install scsi_hostadapter /bin/true +install usbmouse /sbin/modprobe --first-time --ignore-install usbmouse && { /sbin/modprobe hid; /bin/true; } +remove binfmt_misc { /bin/umount /proc/sys/fs/binfmt_misc > /dev/null 2>&1 || :; } ; /sbin/modprobe -r --first-time --ignore-remove binfmt_misc +remove ov518_decomp /sbin/modprobe -r --first-time --ignore-remove ov518_decomp && { /sbin/modprobe -r ov511; /bin/true; } +remove usbmouse { /sbin/modprobe -r hid; } ; /sbin/modprobe -r --first-time --ignore-remove usbmouse +remove sunrpc { /bin/umount /var/lib/nfs/rpc_pipefs > /dev/null 2>&1 || :; } ; /sbin/modprobe -r --ignore-remove sunrpc +remove nfsd { /bin/umount /proc/fs/nfsd > /dev/null 2>&1 || :; } ; /sbin/modprobe -r --first-time --ignore-remove nfsd + + +alias usb-uhci uhci-hcd +alias usb-ohci ohci-hcd +alias uhci uhci-hcd + +alias char-major-116-* snd +alias sound-service-*-0 snd-mixer-oss +alias sound-service-*-1 snd-seq-oss +alias sound-service-*-3 snd-pcm-oss +alias sound-service-*-8 snd-seq-oss +alias sound-service-*-12 snd-pcm-oss + +install sound-slot-* /sbin/modprobe snd-card-${MODPROBE_MODULE##sound[_-]slot[_-]} + +install snd-pcm /sbin/modprobe --ignore-install snd-pcm && /sbin/modprobe snd-pcm-oss && /sbin/modprobe snd-seq-device && /sbin/modprobe snd-seq-oss + +alias nfs4 nfs +alias rpc_pipefs sunrpc +alias rpc_svc_gss_pipefs sunrpc + +install eth1394 /bin/true + +install snd-emu10k1 /sbin/modprobe --ignore-install snd-emu10k1 && /sbin/modprobe snd-emu10k1-synth + +alias gre0 ip_gre +alias char-major-89-* i2c-dev diff --git a/pkgs/core/module-init-tools/module-init-tools.nm b/pkgs/core/module-init-tools/module-init-tools.nm new file mode 100644 index 0000000..921b37f --- /dev/null +++ b/pkgs/core/module-init-tools/module-init-tools.nm @@ -0,0 +1,65 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = module-init-tools +PKG_VER = 3.7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://ftp.kernel.org/pub/linux/utils/kernel/module-init-tools/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Kernel module management utilities. + +PKG_BUILD_DEPS+= autoconf automake +PKG_DEPS += zlib + +define PKG_DESCRIPTION + The module-init-tools package includes various programs needed \ + for automatic loading and unloading of modules under 2.6 and \ + later kernels, as well as other module management programs. \ + Device drivers and filesystems are two examples of loaded and \ + unloaded modules. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CFLAGS += -DCONFIG_NO_BACKWARDS_COMPAT=1 + +export DOCBOOKTOMAN=true + +CONFIGURE_OPTIONS = \ + --prefix=/ \ + --mandir=/usr/share/man + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && autoconf --force +endef + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/etc/modprobe.d + cp -av $(DIR_SOURCE)/modprobe.d/* $(BUILDROOT)/etc/modprobe.d/ +endef diff --git a/pkgs/core/module-init-tools/patches/module-init-tools-3.7-nostatic-1.patch b/pkgs/core/module-init-tools/patches/module-init-tools-3.7-nostatic-1.patch new file mode 100644 index 0000000..562aba0 --- /dev/null +++ b/pkgs/core/module-init-tools/patches/module-init-tools-3.7-nostatic-1.patch @@ -0,0 +1,100 @@ +diff -Nur module-init-tools-3.7-vanilla//Makefile.in module-init-tools-3.7/Makefile.in +--- module-init-tools-3.7-vanilla//Makefile.in 2009-04-09 00:00:26.000000000 +0200 ++++ module-init-tools-3.7/Makefile.in 2009-04-23 13:27:13.000000000 +0200 +@@ -35,7 +35,7 @@ + host_triplet = @host@ + target_triplet = @target@ + sbin_PROGRAMS = insmod$(EXEEXT) modprobe$(EXEEXT) rmmod$(EXEEXT) \ +- depmod$(EXEEXT) modinfo$(EXEEXT) insmod.static$(EXEEXT) ++ depmod$(EXEEXT) modinfo$(EXEEXT) + bin_PROGRAMS = lsmod$(EXEEXT) + noinst_PROGRAMS = modindex$(EXEEXT) + subdir = . +@@ -69,11 +69,6 @@ + insmod_OBJECTS = $(am_insmod_OBJECTS) + insmod_LDADD = $(LDADD) + insmod_DEPENDENCIES = +-am_insmod_static_OBJECTS = insmod.$(OBJEXT) +-insmod_static_OBJECTS = $(am_insmod_static_OBJECTS) +-insmod_static_DEPENDENCIES = +-insmod_static_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ +- $(insmod_static_LDFLAGS) $(LDFLAGS) -o $@ + am_lsmod_OBJECTS = lsmod.$(OBJEXT) util.$(OBJEXT) logging.$(OBJEXT) + lsmod_OBJECTS = $(am_lsmod_OBJECTS) + lsmod_LDADD = $(LDADD) +@@ -108,15 +103,13 @@ + CCLD = $(CC) + LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + SOURCES = $(depmod_SOURCES) $(EXTRA_depmod_SOURCES) $(insmod_SOURCES) \ +- $(EXTRA_insmod_SOURCES) $(insmod_static_SOURCES) \ +- $(EXTRA_insmod_static_SOURCES) $(lsmod_SOURCES) \ ++ $(EXTRA_insmod_SOURCES) $(lsmod_SOURCES) \ + $(EXTRA_lsmod_SOURCES) $(modindex_SOURCES) $(modinfo_SOURCES) \ + $(EXTRA_modinfo_SOURCES) $(modprobe_SOURCES) \ + $(EXTRA_modprobe_SOURCES) $(rmmod_SOURCES) \ + $(EXTRA_rmmod_SOURCES) + DIST_SOURCES = $(depmod_SOURCES) $(EXTRA_depmod_SOURCES) \ + $(insmod_SOURCES) $(EXTRA_insmod_SOURCES) \ +- $(insmod_static_SOURCES) $(EXTRA_insmod_static_SOURCES) \ + $(lsmod_SOURCES) $(EXTRA_lsmod_SOURCES) $(modindex_SOURCES) \ + $(modinfo_SOURCES) $(EXTRA_modinfo_SOURCES) \ + $(modprobe_SOURCES) $(EXTRA_modprobe_SOURCES) $(rmmod_SOURCES) \ +@@ -245,15 +238,10 @@ + depmod_SOURCES = depmod.c util.c logging.c index.c moduleops.c tables.c zlibsupport.c config_filter.c util.h depmod.h logging.h index.h moduleops.h tables.h list.h testing.h zlibsupport.h config_filter.h + modinfo_SOURCES = modinfo.c util.c logging.c zlibsupport.c util.h testing.h zlibsupport.h + modindex_SOURCES = modindex.c util.c logging.c index.c util.h logging.h index.h +-insmod_static_SOURCES = insmod.c +-insmod_static_LDFLAGS = -static +-# We don't want the $(zlib_flags) here: that makes a dynamic executable +-insmod_static_LDADD = + EXTRA_insmod_SOURCES = + EXTRA_lsmod_SOURCES = + EXTRA_modprobe_SOURCES = + EXTRA_rmmod_SOURCES = +-EXTRA_insmod_static_SOURCES = + EXTRA_depmod_SOURCES = moduleops_core.c + EXTRA_modinfo_SOURCES = + MAN5 = modprobe.conf.5 modules.dep.5 depmod.conf.5 +@@ -357,9 +345,6 @@ + insmod$(EXEEXT): $(insmod_OBJECTS) $(insmod_DEPENDENCIES) + @rm -f insmod$(EXEEXT) + $(LINK) $(insmod_OBJECTS) $(insmod_LDADD) $(LIBS) +-insmod.static$(EXEEXT): $(insmod_static_OBJECTS) $(insmod_static_DEPENDENCIES) +- @rm -f insmod.static$(EXEEXT) +- $(insmod_static_LINK) $(insmod_static_OBJECTS) $(insmod_static_LDADD) $(LIBS) + lsmod$(EXEEXT): $(lsmod_OBJECTS) $(lsmod_DEPENDENCIES) + @rm -f lsmod$(EXEEXT) + $(LINK) $(lsmod_OBJECTS) $(lsmod_LDADD) $(LIBS) +diff -Nur module-init-tools-3.7-vanilla//configure module-init-tools-3.7/configure +--- module-init-tools-3.7-vanilla//configure 2009-04-09 00:00:09.000000000 +0200 ++++ module-init-tools-3.7/configure 2009-04-23 13:23:39.000000000 +0200 +@@ -2571,8 +2571,6 @@ + + + +-# If zlib is required, libz must be linked static, modprobe is in +-# /sbin, libz is in /usr/lib and may not be available when it is run. + # Check whether --enable-zlib was given. + if test "${enable_zlib+set}" = set; then + enableval=$enable_zlib; if test "$enableval" = "yes"; then +@@ -2580,7 +2578,7 @@ + #define CONFIG_USE_ZLIB 1 + _ACEOF + +- zlib_flags="-Wl,-Bstatic -lz -Wl,-Bdynamic" ++ zlib_flags="-lz" + fi + fi + +diff -Nur module-init-tools-3.7-vanilla//configure.ac module-init-tools-3.7/configure.ac +--- module-init-tools-3.7-vanilla//configure.ac 2009-04-08 23:54:15.000000000 +0200 ++++ module-init-tools-3.7/configure.ac 2009-04-23 13:23:39.000000000 +0200 +@@ -14,7 +14,7 @@ + [ --enable-zlib Handle gzipped modules], + [if test "$enableval" = "yes"; then + AC_DEFINE(CONFIG_USE_ZLIB) +- zlib_flags="-Wl,-Bstatic -lz -Wl,-Bdynamic" ++ zlib_flags="-lz" + fi]) + + AC_PROG_CC diff --git a/pkgs/core/mpfr/mpfr.nm b/pkgs/core/mpfr/mpfr.nm new file mode 100644 index 0000000..bca905d --- /dev/null +++ b/pkgs/core/mpfr/mpfr.nm @@ -0,0 +1,74 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = mpfr +PKG_VER = 2.4.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.mpfr.org/ +PKG_LICENSE = LGPLv2+ and GPLv2+ and GFDL +PKG_SUMMARY = A C library for multiple-precision floating-point computations. + +PKG_BUILD_DEPS:= $(filter-out gcc,$(PKG_BUILD_DEPS)) +PKG_DEPS += gmp + +define PKG_DESCRIPTION + The MPFR library is a C library for multiple-precision floating-point \ + computations with "correct rounding". The MPFR is efficient and \ + also has a well-defined semantics. It copies the good ideas from the \ + ANSI/IEEE-754 standard for double-precision floating-point arithmetic \ + (53-bit mantissa). MPFR is based on the GMP multiple-precision \ + library. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +ifeq "$(MACHINE)" "x86_64" + ABI = 64 +else + ABI = 32 +endif + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + mpfr_cv_working_tls=yes \ + ./configure \ + --prefix=/usr \ + --enable-thread-safe \ + --disable-static + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_TEST + cd $(DIR_APP) && make check +endef diff --git a/pkgs/core/nano/nano.nm b/pkgs/core/nano/nano.nm new file mode 100644 index 0000000..1e2ff6b --- /dev/null +++ b/pkgs/core/nano/nano.nm @@ -0,0 +1,58 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = nano +PKG_VER = 2.2.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Application/Editors +PKG_URL = http://www.nano-editor.org/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A small text editor. + +PKG_BUILD_DEPS+= groff +PKG_DEPS += ncurses + +define PKG_DESCRIPTION + GNU nano is a small and friendly text editor. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### +CONFIGURE_OPTIONS += \ + --bindir=/bin \ + --sysconfdir=/etc/nano \ + --enable-color \ + --enable-multibuffer \ + --enable-nanorc + +define STAGE_INSTALL_CMDS + cd $(DIR_APP) && install -v -m644 -D doc/nanorc.sample $(BUILDROOT)/etc/nano/nanorc.sample +endef diff --git a/pkgs/core/nasm/nasm.nm b/pkgs/core/nasm/nasm.nm new file mode 100644 index 0000000..5ce2bbc --- /dev/null +++ b/pkgs/core/nasm/nasm.nm @@ -0,0 +1,49 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = nasm +PKG_VER = 2.02 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Languages +PKG_URL = http://nasm.sourceforge.net/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = A portable x86 assembler which uses Intel-like syntax. + +define PKG_DESCRIPTION + NASM is the Netwide Assembler, a free portable assembler for the \ + Intel 80x86 microprocessor series, using primarily the traditional \ + Intel instruction mnemonics and syntax. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CFLAGS += -fno-stack-protector + +define STAGE_INSTALL + cd $(DIR_APP) && make install INSTALLROOT=$(BUILDROOT) +endef diff --git a/pkgs/core/ncurses/ncurses.nm b/pkgs/core/ncurses/ncurses.nm new file mode 100644 index 0000000..10d00db --- /dev/null +++ b/pkgs/core/ncurses/ncurses.nm @@ -0,0 +1,81 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = ncurses +PKG_VER = 5.7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://invisible-island.net/ncurses/ncurses.html +PKG_LICENSE = MIT +PKG_SUMMARY = Ncurses support utilities. + +PKG_PACKAGES += $(PKG_NAME_REAL)-devel + +define PKG_DESCRIPTION + The curses library routines are a terminal-independent method of \ + updating character screens with reasonable optimization. The ncurses \ + (new curses) library is a freely distributable replacement for the \ + discontinued 4.4 BSD classic curses library. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --mandir=/usr/share/man \ + --with-shared \ + --without-debug \ + --enable-widec \ + --disable-static \ + --enable-symlinks \ + --disable-root-environ + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/lib + mv -v $(BUILDROOT)/usr/lib/libncursesw.so.5* $(BUILDROOT)/lib + ln -sfv ../../lib/libncursesw.so.5 $(BUILDROOT)/usr/lib/libncursesw.so + for lib in curses ncurses form panel menu; do \ + rm -vf $(BUILDROOT)/usr/lib/lib$${lib}.so ; \ + echo "INPUT(-l$${lib}w)" >$(BUILDROOT)/usr/lib/lib$${lib}.so ; \ + done + + rm -vf $(BUILDROOT)/usr/lib/libcursesw.so + echo "INPUT(-lncursesw)" >$(BUILDROOT)/usr/lib/libcursesw.so + ln -sfv libncurses.so $(BUILDROOT)/usr/lib/libcurses.so +endef diff --git a/pkgs/core/net-snmp/net-snmp.nm b/pkgs/core/net-snmp/net-snmp.nm new file mode 100644 index 0000000..239058d --- /dev/null +++ b/pkgs/core/net-snmp/net-snmp.nm @@ -0,0 +1,64 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = net-snmp +PKG_VER = 5.4.2.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Daemons +PKG_URL = http://net-snmp.sourceforge.net +PKG_LICENSE = BSD +PKG_SUMMARY = Simple Network Management Protocol Daemon. + +PKG_DEPS += perl + +define PKG_DESCRIPTION + Simple Network Management Protocol (SNMP) is a widely used protocol \ + for monitoring the health and welfare of network equipment (eg. routers), \ + computer equipment and even devices like UPSs. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +PARALLELISMFLAGS = # No parallel build + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc \ + --libdir=/usr/lib \ + --mandir=/usr/share/man \ + --with-default-snmp-version=2 \ + --with-sys-contact=root@ \ + --with-sys-location=localhost \ + --with-logfile=/var/log/snmpd.log \ + --with-persistent-directory=/var/net-snmp \ + --without-perl-modules \ + --disable-embedded-perl + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/etc + install -v -m644 $(DIR_APP)/python/netsnmp/tests/snmpd.conf $(BUILDROOT)/etc/snmpd.conf +endef diff --git a/pkgs/core/network/network.init b/pkgs/core/network/network.init new file mode 100644 index 0000000..06a96ef --- /dev/null +++ b/pkgs/core/network/network.init @@ -0,0 +1,13 @@ +description "Control the networking" +author "IPFire Team" + +start on stopped mountfs +stop on starting shutdown + +pre-start script + network start +end script + +post-stop script + network stop +end script diff --git a/pkgs/core/network/network.nm b/pkgs/core/network/network.nm new file mode 100644 index 0000000..161923c --- /dev/null +++ b/pkgs/core/network/network.nm @@ -0,0 +1,63 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = network +PKG_VER = +PKG_REL = 0 + +PKG_MAINTAINER = Michael Tremer <michael.tremer@ipfire.org> +PKG_GROUP = Networking/Tools +PKG_URL = http://www.ipfire.org/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = The IPFire Networking Scripts. + +PKG_DEPS += dhcp iproute2 ppp sqlite vlan + +define PKG_DESCRIPTION + This script installs the IPFire Networking Scripts. +endef + +DIR_APP = $(DIR_SOURCE)/src + +PKG_TARBALL = + +STAGE_PREPARE = # Do nothing +STAGE_BUILD = # Do nothing + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/etc/ppp + -mkdir -pv $(BUILDROOT)/lib/network + -mkdir -pv $(BUILDROOT)/sbin + -mkdir -pv $(BUILDROOT)/var/log/network + + install -m 755 -v $(DIR_APP)/network $(BUILDROOT)/sbin + + cp -rfv $(DIR_APP)/{hooks,hook-header,functions*,zone} $(BUILDROOT)/lib/network/ + + install -m 755 -v $(DIR_APP)/ppp/ip-updown $(BUILDROOT)/etc/ppp + ln -svf ip-updown $(BUILDROOT)/etc/ppp/ip-up + ln -svf ip-updown $(BUILDROOT)/etc/ppp/ip-down +endef diff --git a/pkgs/core/network/src/functions b/pkgs/core/network/src/functions new file mode 100644 index 0000000..773463a --- /dev/null +++ b/pkgs/core/network/src/functions @@ -0,0 +1,676 @@ +#!/bin/sh +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +HOME_DIR=${HOME_DIR-/lib/network} +CONFIG_DIR=/etc/network +HOOKS_DIR=${HOME_DIR}/hooks +LOG_DIR=/var/log/network + +CONNECTIONS_FILE=/var/log/network/connections.db + +CONFIG_ZONES=${CONFIG_DIR}/zones +CONFIG_PORTS=${CONFIG_DIR}/ports +CONFIG_HOOKS=${CONFIG_DIR}/hooks +CONFIG_PPP=${CONFIG_DIR}/ppp +CONFIG_UUIDS=${CONFIG_DIR}/uuids + +# Create config directories +for dir in ${CONFIG_ZONES} ${CONFIG_PORTS} ${CONFIG_HOOKS} ${CONFIG_PPP} ${CONFIG_UUIDS}; do + [ -d "${dir}" ] && continue + mkdir -p "${dir}" +done + +COMMON_DEVICE=port+ + +EXIT_OK=0 +EXIT_ERROR=1 +EXIT_CONF_ERROR=2 + +VALID_ZONES="blue green orange red grey" + +[ -n "${DEBUG}" ] || DEBUG= +[ -n "${VERBOSE}" ] || VERBOSE= + +function is_mac() { + [[ $1 =~ ^[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]$ ]] +} + +function is_uuid() { + local string=${1} + + # Length must be 37 characters + if [ ${#string} -eq 36 ] \ + && [ "${string:8:1}" = "-" ] \ + && [ "${string:13:1}" = "-" ] \ + && [ "${string:18:1}" = "-" ] \ + && [ "${string:23:1}" = "-" ]; then + return ${EXIT_OK} + fi + return ${EXIT_ERROR} +} + +function get_device_by_mac() { + local mac=${1} + local device + + for device in /sys/class/net/*; do + [ -d "${device}" ] || continue + if [ "$(cat $device/address)" = "$mac" ]; then + device=${device##*/} + # Skip virtual devices + if [ -e "/proc/net/vlan/$device" ]; then + continue + fi + # Skip zones + if zone_exists ${device}; then + continue + fi + echo ${device} + return 0 + fi + done + return 1 +} + +function get_device_by_mac_and_vid() { + local mac=$1 + local vid=$2 + + local i + local VID + local DEVICE + if [ -e "/proc/net/vlan/config" ]; then + grep '|' /proc/net/vlan/config | sed "s/|//g" | \ + while read DEVICE VID PARENT; do + if [ "${vid}" = "${VID}" ] && [ "$(macify ${PARENT})" = "${mac}" ]; then + echo "${DEVICE}" + return 0 + fi + done + fi + return 1 +} + +function get_device() { + if [ ${#@} -gt 1 ]; then + get_device_by_mac_and_vid $@ + else + get_device_by_mac $@ + fi +} + +function get_mac_by_device() { + local device + device=$1 + if [ -d "/sys/class/net/$device" ]; then + cat /sys/class/net/$device/address + return 0 + fi + return 1 +} + +function get_mac() { + get_mac_by_device $@ +} + +function devicify() { + local device=${1} + local mac + + [ -n "${device}" ] || return 1 + + if is_mac ${device}; then + mac=${device} + device=$(get_device_by_mac ${device}) + fi + if [ -n "${device}" ]; then + echo ${device} + return 0 + else + echo "devicify: Could not find device of $@" >&2 + return 1 + fi +} + +function macify() { + local input=${1} + local mac + + if is_mac ${input}; then + mac=${input} + else + mac=$(get_mac_by_device ${input}) + fi + echo ${mac} +} + +function device_exists() { + [ -n "${1}" ] || return ${EXIT_ERROR} + local device=$(devicify ${1}) + [ -n "${device}" ] || return ${EXIT_ERROR} + ip link show ${device} &>/dev/null +} + +function device_is_bonding() { + [ -d "/sys/class/net/${1}/bonding" ] +} + +function device_is_bonded() { + local dev + for dev in /sys/class/net/*; do + # Skip crappy files + [ -d "${dev}" ] || continue + + # Continue if not a bonding device + device_is_bonding "${dev##*/}" || continue + + if grep -q "<${1}>" ${dev}/bonding/slaves; then + return 0 + fi + done + return 1 +} + +function device_is_bridge() { + [ -d "/sys/class/net/${1}/bridge" ] +} + +function device_is_up() { + ip link show $(devicify ${1}) 2>/dev/null | grep -qE "<.*UP.*>" +} + +function device_is_vlan() { + if [ ! -e "/proc/net/vlan/config" ]; then + return 1 + fi + grep -q "^${1}" /proc/net/vlan/config +} + +function device_is_ppp() { + # XXX need something better + [ "${1:0:3}" = "ppp" ] +} + +function device_is_loopback() { + local device=$(devicify ${1}) + [ "${device}" = "lo" ] +} + +function device_is_real() { + local device=${1} + + device_is_loopback ${device} && \ + return ${EXIT_ERROR} + + device_is_bonding ${device} && \ + return ${EXIT_ERROR} + + device_is_bridge ${device} && \ + return ${EXIT_ERROR} + + device_is_ppp ${device} && \ + return ${EXIT_ERROR} + + device_is_vlan ${device} && \ + return ${EXIT_ERROR} + + return ${EXIT_OK} +} + +function device_type() { + local device=$(devicify ${1}) + + if device_is_vlan ${device}; then + echo "vlan" + + elif device_is_bonding ${device}; then + echo "bonding" + + elif device_is_bridge ${device}; then + echo "bridge" + + elif device_is_ppp ${device}; then + echo "ppp" + + elif device_is_loopback ${device}; then + echo "loopback" + + elif device_is_real ${device}; then + echo "real" + + else + echo "unknown" + fi +} + +function device_has_vlans() { + if [ ! -e "/proc/net/vlan/config" ]; then + return 1 + fi + grep -q "${1}$" /proc/net/vlan/config +} + +function device_has_carrier() { + local device=$(devicify ${1}) + [ "$(</sys/class/net/${device}/carrier)" = "1" ] +} + +function device_get_free() { + local destination=${1} + + # Replace + by a valid number + if grep -q "+$" <<<${destination}; then + local number=0 + destination=$(sed -e "s/+//" <<<$destination) + while [ "${number}" -le "100" ]; do + if ! device_exists "${destination}${number}"; then + destination="${destination}${number}" + break + fi + number=$(($number + 1)) + done + fi + echo "${destination}" +} + +function device_rename() { + local source=$1 + local destination=$(device_get_free ${2}) + + # Check if devices exists + if ! device_exists ${source} || device_exists ${destination}; then + return 4 + fi + + local up + if device_is_up ${source}; then + ip link set ${source} down + up=1 + fi + + ip link set ${source} name ${destination} + + if [ "${up}" = "1" ]; then + ip link set ${destination} up + fi +} + +function hook_exists() { + [ -x "${HOOKS_DIR}/${1}" ] +} + +function port_exists() { + device_exists $@ +} + +function port_is_up() { + port_exists $@ && device_is_up $@ +} + +function zone_exists() { + [ -e "$CONFIG_ZONES/${1}" ] +} + +function zone_is_up() { + zone_exists $@ && device_is_up $@ +} + +function zone_is_forwarding() { + local seconds=45 + local zone=${1} + + local device + while [ ${seconds} -gt 0 ]; do + for device in /sys/class/net/${zone}/brif/*; do + [ -e "${device}/state" ] || continue + if [ "$(<${device}/state)" = "3" ]; then + return ${EXIT_OK} + fi + done + sleep 1 + seconds=$((${seconds} - 1)) + done + return ${EXIT_ERROR} +} + +function bridge_devices() { + local bridge=$1 + [ -z "${bridge}" ] && return 2 + brctl show | grep "^${bridge}" | awk '{ print $NF }' | grep -v "^interfaces$" +} + +function zone_add_port() { + local zone=${1} + local port=${2} + + brctl addif ${zone} ${port} +} + +function zone_del_port() { + local zone=${1} + local port=${2} + + brctl delif ${zone} ${port} +} + +function zone_list() { + local zone + for zone in $(find ${CONFIG_ZONES}/* 2>/dev/null); do + [ -d "${zone}" ] && echo ${zone} + done +} + +function zone_is_red() { + local zone=${1} + [ "${zone#red}" != "${zone}" ] +} + +function _run_hooks() { + local action + local type + + while [ $# -gt 0 ]; do + case "${1}" in + --type=*) + type=${1#--type=} + ;; + *) + action="${1}" + shift; break + ;; + esac + shift + done + + local dir=${1}; shift + local failed + local hook + local hooks + + if [ -z "${action}" ] || [ -z "${dir}" ]; then + echo "Not enough parameters given." >&2 + return 1 + fi + + for hook in $(find ${dir}); do + # Skip dirs + [ -d "${hook}" ] && continue + + ( + . ${hook} + # Skip hooks that are not of the given type + if [ -n "${type}" ] && [ "$(hook_type ${HOOK})" != "${type}" ]; then + continue + fi + if [ -n "${HOOK}" ]; then + hook_run ${HOOK} --config=${hook} $@ ${action} + RET=$? + else + echo -e "${FAILURE}Unable to process ${hook}. Either" + echo -e "${FAILURE}the HOOK variable was not set," + echo -e "${FAILURE}or the specified hook cannot be executed." + message="" + log_failure_msg + fi + exit ${RET} + ) || failed=1 + done + + return ${failed} +} + +function hooks_run_all() { + _run_hooks $@ +} + +function hooks_run_ports() { + _run_hooks --type="port" $@ +} + +function hooks_run_zones() { + _run_hooks --type="zone" $@ +} + +function hook_type() { + local hook=${1} + ( + eval $(${HOOKS_DIR}/${hook} info) + echo "${HOOK_TYPE}" + ) +} + +function hook_list() { + local type=${1} + local hook + for hook in ${HOOKS_DIR}/*; do + hook=${hook##*/} + + [[ ${hook} =~ helper$ ]] && continue + + if [ -n "${type}" ] && [ "$(hook_type ${hook})" != "${type}" ]; then + continue + fi + echo "${hook}" + done +} + +function config_get_hook() { + local config=${1} + if [ ! -e "${config}" ]; then + log_failure_msg "Config file "${config}" does not exist." + return ${EXIT_ERROR} + fi + ( . ${config}; echo ${HOOK} ) +} + +function hook_run() { + local hook=${1} + shift + + if ! hook_exists ${hook}; then + log_failure_msg "Hook ${hook} cannot be found or is not executeable." + return ${EXIT_ERROR} + fi + [ -n "${DEBUG}" ] && echo "Running hook: ${hook} $@" + DEBUG=${DEBUG} VERBOSE=${VERBOSE} ${HOOKS_DIR}/${hook} $@ + return $? +} + +function hook_run_multiple() { + local zone + local config + local hook + local hook_type2 + local type + + while [ "$#" -gt "0" ]; do + case "${1}" in + --type=*) + type=${1#--type=} + ;; + *) + zone=${1} + break + ;; + esac + shift + done + + if ! zone_exists ${zone}; then + return ${EXIT_ERROR} + fi + + for config in $(find ${CONFIG_ZONES}/${zone} 2>/dev/null); do + hook=$(config_get_hook ${config}) + if [ -n "${type}" ]; then + hook_type2=$(hook_type ${hook}) + if [ "${type}" != "${hook_type2}" ]; then + continue + fi + fi + hook_run ${hook} $@ + done +} + +function zone_run() { + local zone=${1} + shift + + if ! zone_exists ${zone}; then + log_failure_msg "Zone ${zone} does not exist." + exit ${EXIT_ERROR} + fi + decho "Running zone: ${zone} $@" + DEBUG=${DEBUG} VERBOSE=${VERBOSE} ${HOME_DIR}/zone --zone=${zone} $@ +} + +function zone_valid_name() { + local zone=${1} + local match + + local i + for i in ${VALID_ZONES}; do + match="${match}|${i}[0-9]{1,5}" + done + [[ ${zone} =~ ${match:1:${#match}} ]] +} + +function isset() { + local key=${1} + [ -n "${!key}" ] && return + if [[ ${key} =~ port|zone ]]; then + echo "ERROR: The --${key} flag is not set." >&2 + else + echo "ERROR: The "${key}" variable is not set properly." >&2 + fi + return 1 +} + +# Test if device is attached to the given bridge +function zone_has_device_attached () { + local zone=${1} + local device=${2} + + [ -d "/sys/class/net/${zone}/brif/${device}" ] +} + +function device_has_ipv4() { + local device=${1} + local ip=${2} + ip addr show ${device} | grep inet | fgrep -q ${ip} +} + +function check_config() { + local failed + local i + + for i in $@; do + isset ${i} || failed=1 + done + if [ "${failed}" = "1" ]; then + echo "Exiting..." + exit ${EXIT_ERROR} + fi +} + +function mac_generate() { + local mac="00" + while [ "${#mac}" -lt 15 ]; do + mac="${mac}:$(cut -c 1-2 /proc/sys/kernel/random/uuid)" + done + echo "${mac}" +} + +function connection() { + local action + + local dns + local interface + local iplocal + local ipremote + local name + local status + local weight + local zone + + while [ $# -gt 0 ]; do + case "${1}" in + --up) + action="up" + ;; + --down) + action="down" + ;; + --starting) + action="starting" + ;; + --stopping) + action="stopping" + ;; + --name=*) + name=${1#--name=} + ;; + --zone=*) + zone=${1#--zone=} + zone_is_red ${zone} || return 0 + ;; + --interface=*) + interface=${1#--interface=} + ;; + --iplocal=*) + iplocal=${1#--iplocal=} + ;; + --ipremote=*) + ipremote=${1#--ipremote=} + ;; + --weight=*) + weight=${1#--weight=} + ;; + --dns=*) + dns=${1#--dns=} + ;; + esac + shift + done + + if [ ! -e "${CONNECTIONS_FILE}" ]; then + sqlite3 -batch ${CONNECTIONS_FILE} <<EOF +CREATE TABLE connections(name, zone, interface, iplocal, ipremote, weight, dns, status); +EOF + fi + + if [ -z "${zone}" ]; then + return 2 + fi + + status=${action} + + sqlite3 -batch ${CONNECTIONS_FILE} <<EOF +DELETE FROM connections WHERE zone = '${zone}'; +INSERT INTO connections(name, zone, interface, iplocal, ipremote, weight, dns, status) + VALUES('${name}', '${zone}', '${interface}', '${iplocal}', '${ipremote}', '${weight}', '${dns}', '${status}'); +EOF + +} + +function uuid() { + cat /proc/sys/kernel/random/uuid +} diff --git a/pkgs/core/network/src/functions.ppp b/pkgs/core/network/src/functions.ppp new file mode 100644 index 0000000..7598f0b --- /dev/null +++ b/pkgs/core/network/src/functions.ppp @@ -0,0 +1,110 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +RED_RUN=/var/run/network/red +PPP_SECRETS=/etc/ppp/secrets + +function ppp_pre_up() { + # Load the ppp_generic module if not already done + grep -q ^ppp_generic /proc/modules || modprobe ppp_generic + + connection --starting --zone=${zone} +} + +function ppp_post_up() { + : #connection --up --zone=${zone} +} + +function ppp_pre_down() { + connection --stopping --zone=${zone} +} + +function ppp_post_down() { + : #connection --down --zone=${zone} +} + +function ppp_secret() { + local USER=${1} + local SECRET=${2} + local a + local secret + local user + + # Updateing secret file + > ${PPP_SECRETS}.tmp + while read user a secret; do + if [ "'${USER}'" != "${user}" ]; then + echo "${user} ${a} ${secret}" >> ${PPP_SECRETS}.tmp + fi + done < ${PPP_SECRETS} + echo "'${USER}' * '${SECRET}'" >> ${PPP_SECRETS}.tmp + cat ${PPP_SECRETS}.tmp > ${PPP_SECRETS} + rm -f ${PPP_SECRETS}.tmp +} + +function ppp_stat() { + local name=${1} + local time=${2} + local rcvd=${3} + local sent=${4} + + local file="${LOG_DIR}/ppp_${name}.db" + if ! [ -e "${file}" ]; then + sqlite3 -batch ${file} <<EOF +CREATE TABLE connections(date, duration, rcvd, sent); +EOF + fi + ppp_stat_init ${file} + + sqlite3 -batch ${file} <<EOF +INSERT INTO connections(date, duration, rcvd, sent) VALUES('$(date -u '+%s')', '${time}', '${rcvd}', '${sent}'); +EOF +} + +function ppp_linkname_get() { + local config=${1} + ( + . ${config} + echo "${LINKNAME}" + ) +} + +function red_defaultroute_update() { + local command="ip route replace default" + + for uplink in ${RED_RUN}/*; do + [ -d "${uplink}" ] || continue + + # Skip if no gateway given + [ -e "${uplink}/gateway" ] || continue + + command="${command} nexthop via $(<${uplink}/gateway)" + if [ -e "${uplink}/weight" ]; then + command="${command} weight $(<${uplink}/weight)" + fi + done + $command + ip route flush cache +} + +function red_dns_update() { + : # XXX todo +} diff --git a/pkgs/core/network/src/hook-header b/pkgs/core/network/src/hook-header new file mode 100644 index 0000000..b2693b8 --- /dev/null +++ b/pkgs/core/network/src/hook-header @@ -0,0 +1,38 @@ +#!/bin/sh + +. /etc/init/functions +. /lib/network/functions + +INDENT=" " + +HOOK_PRIO=100 + +# Parse the command line +action= +port= +zone= + +while [ $# -gt 0 ]; do + case "${1}" in + --zone=*) + zone=${1#--zone=} + ;; + --config=*) + . ${1#--config=} + ;; + --port=*) + port=${1#--port=} + ;; + -*) + log_failure_msg "Unrecognized option: ${1}" + exit ${EXIT_ERROR} + ;; + *) + action=${1} + shift + break + ;; + esac + shift +done + diff --git a/pkgs/core/network/src/hooks/README b/pkgs/core/network/src/hooks/README new file mode 100644 index 0000000..09ca230 --- /dev/null +++ b/pkgs/core/network/src/hooks/README @@ -0,0 +1,86 @@ +HOOKS README + +A hook is file that can configure a specific network connection (e.g. ethernet) +or protocol (e.g. ipv4-static). + +They are expandable and standalone. Means, when you call a file, you will +run it and pass some options and an action to it. + + /lib/network/hooks/HOOOK [options] <action> [options to action] + +There are two types of hooks: + zone + These hooks applies to a zone and does configuration on it. + Mainly, it configures the IP protocol or something else. + + port + These hooks add ports to zones. + +DEFINES: + So, to know what type of hook this is, we have to define some variables + in the header of the file. + + HOOK_NAME + The name of the hook. This is normally the file name. + + HOOK_TYPE + zone or port. See section above. + + +INLCUDES: + These files get included in the header. + + /lib/lsb/init-functions + For pretty messages + + /lib/network/functions + Our networking funktions. + + +OPTIONS: + Options have at least to be for zone file: + + --config=CONFIG + Includes the given config file CONFIG. + If there is an error when loading the config file or the parameters are + wrong or invalid, the script will pass an error with code ${EXIT_CONF_ERROR}! + + --port=PORT + Takes a port (either as device (eth0) or as mac (00:11:22:33:44:55)). + + --zone=ZONE + Takes the name of a zone. + + +ACTION: + Actions that always have to be defined: + help + Gives the user a short help how to use the command and its arguments. + + info + Gives some information about the hook (mainly for internal use of the scripts). + See below. + + status + Gives information if the hook is active or not. + + config + This is the command that creates the configuration for each hook. + It will accept some more arguments in the command line + and return either ${EXIT_OK} or ${EXIT_ERROR}. + + Actions that have to be defined for a zone hook: + pre-up + This gets runned before the zone gets up. + + pre-down. + This is runned before the zone is set down. + + post-up + After setting up the zone, this command will be executed. + + post-down + After the zone has vanished, this part of the script is called. + + All these actions will return ${EXIT_OK} when everything went fine. + If not, they will return ${EXIT_ERROR}. diff --git a/pkgs/core/network/src/hooks/bonding b/pkgs/core/network/src/hooks/bonding new file mode 100755 index 0000000..03f0a70 --- /dev/null +++ b/pkgs/core/network/src/hooks/bonding @@ -0,0 +1,177 @@ +#!/bin/sh +######################################################################## +# Begin $NETWORK_DEVICES/services/bonding +# +# Description : Bonding Script +# +# Authors : Michael Tremer - michael.tremer@ipfire.org +# +# Version : 00.00 +# +# Notes : This script adds bonding support. +# +######################################################################## + +. /lib/network/hook-header + +HOOK_NAME=bonding +HOOK_TYPE=port +HOOK_PRIO=50 + +DEFAULT_MODE= + +function port_name() { + echo "${zone}t+" +} + +case "${action}" in + help) + ;; + + info) + echo "HOOK_NAME=${HOOK_NAME}" + echo "HOOK_TYPE=${HOOK_TYPE}" + ;; + + pre-up) + if ! grep -q ^bonding /proc/modules; then + modprobe bonding + echo "-bond0" > /sys/class/net/bonding_masters + fi + + if device_exists ${MAC}; then + device=$(devicify ${MAC}) + if ! device_is_bonding ${device}; then + log_failure_msg "Device "${device}" is up, but not a bonding device." + exit ${EXIT_ERR} + fi + exit ${EXIT_OK} + fi + + device=$(device_get_free $(port_name)) + echo "+${device}" > /sys/class/net/bonding_masters + ip link set ${device} address ${MAC} + + [ -n "${MODE}" ] && \ + echo "${MODE}" > /sys/class/net/${device}/bonding/mode + + echo "${MIIMON-100}" > /sys/class/net/${device}/bonding/miimon + + for slave in ${SLAVES}; do + if device_exists ${slave}; then + if device_is_up ${slave}; then + log_warning_msg "Cannot enslave device "${slave}"." + continue + fi + device_rename "$(devicify ${slave})" "${device}s+" + echo "+$(devicify ${slave})" > /sys/class/net/${device}/bonding/slaves + else + log_warning_msg "Device ${slave} does not exist." + fi + done + + ip link set ${device} up + + log_success_msg "Setting up trunk ${MAC}..." + ;; + + post-up) + device=$(devicify ${MAC}) + if ! zone_has_device_attached ${zone} ${device}; then + zone_add_port ${zone} ${device} + fi + ;; + + pre-down) + device=$(devicify ${MAC}) + if zone_has_device_attached ${zone} ${device}; then + zone_del_port ${zone} ${device} + fi + ;; + + post-down) + device=$(devicify ${MAC}) + if port_is_up ${device}; then + MESSAGE="Pulling down trunk ${MAC}..." + ip link set ${device} down + evaluate_retval + echo "-${device}" > /sys/class/net/bonding_masters + fi + ;; + + add) + MAC=$(mac_generate) + MODE=${DEFAULT_MODE} + + while [ $# -gt 0 ]; do + case "${1}" in + --mac=*) + MAC=${1#--mac=} + ;; + --mode=*) + MODE=${1#--mode=} + ;; + *) + SLAVES="${SLAVES} $(macify ${1})" + ;; + esac + shift + done + + UUID=$(uuid) + cat <<EOF > ${CONFIG_UUIDS}/${UUID} +HOOK="${HOOK_NAME}" +MAC="${MAC}" +MODE="${MODE}" +SLAVES="$(echo ${SLAVES})" +EOF + ln -sf ${CONFIG_UUIDS}/${UUID} \ + ${CONFIG_ZONES}/${zone}/${HOOK_NAME}-${UUID} + + log_success_msg "Configuration successfully saved!" + echo " MAC address : ${MAC}" + echo " Mode : ${MODE}" + echo " Slaves : $(echo ${SLAVES})" + ;; + + rem) + ;; + + status) + DEVICE=$(devicify ${MAC}) + echo -e "# ${CLR_BOLD_CYN}Trunk ${DEVICE} (${MAC})${NORMAL}" + if device_is_up ${MAC}; then + echo -e "# State: ${CLR_BOLD_GRN}up${NORMAL}" + echo "#" + for slave in $(</sys/class/net/${DEVICE}/bonding/slaves); do + echo -e "# ${CLR_BOLD_CYN}Slave port ${slave}${NORMAL}" + + echo -n "# State: " + if device_is_up ${slave}; then + echo -e "${CLR_BOLD_GRN}up${NORMAL}" + else + echo -e "${CLR_BOLD_RED}down${NORMAL}" + fi + + echo -n "# Link : " + if device_has_carrier ${slave}; then + echo -e "${CLR_BOLD_GRN}yes${NORMAL}" + else + echo -e "${CLR_BOLD_RED}no${NORMAL}" + fi + done + else + echo -e "# State: ${CLR_BOLD_RED}down${NORMAL}" + fi + + device_is_up ${MAC} + exit ${?} + ;; + + *) + echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach|status}" + exit 1 + ;; +esac + +# End $NETWORK_DEVICES/services/bonding diff --git a/pkgs/core/network/src/hooks/ethernet b/pkgs/core/network/src/hooks/ethernet new file mode 100755 index 0000000..e6e364f --- /dev/null +++ b/pkgs/core/network/src/hooks/ethernet @@ -0,0 +1,137 @@ +#!/bin/sh +######################################################################## +# Begin $NETWORK_DEVICES/services/ethernet +# +# Description : Ethernet Script +# +# Authors : Michael Tremer - michael.tremer@ipfire.org +# +# Version : 00.00 +# +# Notes : This script adds ethernet support. +# +######################################################################## + +. /lib/network/hook-header + +HOOK_NAME=ethernet +HOOK_TYPE=port + +function port_name() { + echo ${zone}p+ +} + +case "${action}" in + help) + echo -e "${BOLD}Hook (${HOOK_NAME}) help:" + echo + echo -e " ${BOLD}Summary:${NORMAL}" + echo " The ethernet-hook controls connection via ethernet." + echo " You will need this to access your local lan." + echo + echo -e " ${BOLD}Usage:${NORMAL}" + #echo " --config=<FILE>" + #echo " Includes a config file." + #echo " Example: --config=/etc/sysconfig/network/green0/port-00:11:22:33:44:55" + #echo " --port=<MAC or Name>" + #echo " Passes the port to the script." + #echo " Example: --port=port0 or --port=00:11:22:33:44:55" + #echo " --zone=<zone>" + #echo " Passes the zone to the script." + #echo " Example: --zone=green0" + #echo + #echo -e " ${BOLD}Commands:${NORMAL}" + #echo + echo " This hook only needs the name of the network device" + echo " that should be attached to the zone." + echo " The device identifier can either be a mac address or" + echo " a device name." + echo + echo " Example: network zone addport green0 ethernet port0" + echo " network zone addport green0 ethernet 00:11:22:33:44:55" + echo + ;; + + info) + echo "HOOK_NAME=${HOOK_NAME}" + echo "HOOK_TYPE=${HOOK_TYPE}" + ;; + + pre-up) + device_is_up ${MAC} || ip link set $(devicify ${MAC}) up + ;; + + post-up) + if zone_has_device_attached ${zone} $(get_device ${MAC}); then + # Device is already attached to the bridge + exit ${EXIT_OK} + fi + message="Attaching ethernet port ${MAC}..." + device_rename $(get_device ${MAC}) $(port_name) + zone_add_port ${zone} $(get_device_by_mac ${MAC}) + evaluate_retval + ;; + + pre-down) + if zone_has_device_attached ${zone} $(get_device ${MAC}); then + message="Detatching ethernet port ${MAC}..." + zone_del_port ${zone} $(get_device_by_mac ${MAC}) + device_rename $(get_device_by_mac ${MAC}) ${COMMON_DEVICE} + evaluate_retval + fi + ;; + + post-down) + ## Possibly pull down the device (if there are no more vlan devices up...) + ;; + + add) + ### XXX error handling + + for dev in $@; do + MAC=$(macify ${dev}) + UUID=$(uuid) + cat <<EOF > ${CONFIG_UUIDS}/${UUID} +HOOK="${HOOK_NAME}" +MAC="${MAC}" +EOF + ln -sf ${CONFIG_UUIDS}/${UUID} \ + ${CONFIG_ZONES}/${zone}/${HOOK_NAME}-${UUID} + + log_success_msg "Configuration successfully saved!" + echo " Device : $(devicify ${MAC})" + echo " MAC address : ${MAC}" + done + ;; + + rem) + # XXX to be done + ;; + + status) + echo -e "# ${CLR_BOLD_CYN}Ethernet port $(devicify ${MAC}) (${MAC})${NORMAL}" + echo -n "# State: " + if device_is_up ${MAC}; then + echo -e "${CLR_BOLD_GRN}up${NORMAL}" + else + echo -e "${CLR_BOLD_RED}down${NORMAL}" + fi + echo -n "# Link : " + if device_has_carrier ${MAC}; then + echo -e "${CLR_BOLD_GRN}yes${NORMAL}" + else + echo -e "${CLR_BOLD_RED}no${NORMAL}" + fi + echo "#" + + device_is_up ${MAC} + exit ${?} + ;; + + *) + echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach|status}" + exit 1 + ;; +esac + +# End $NETWORK_DEVICES/services/ethernet diff --git a/pkgs/core/network/src/hooks/ipv4-dhcp b/pkgs/core/network/src/hooks/ipv4-dhcp new file mode 100755 index 0000000..43c4419 --- /dev/null +++ b/pkgs/core/network/src/hooks/ipv4-dhcp @@ -0,0 +1,84 @@ +#!/bin/sh + +. /lib/network/hook-header + +HOOK_NAME="ipv4-dhcp" +HOOK_TYPE="zone" + +MESSAGE="DHCP Daemon..." +EXECUTEABLE="/sbin/dhclient" + +case "${action}" in + help) + ;; + + info) + echo "HOOK_NAME=$HOOK_NAME" + echo "HOOK_TYPE=$HOOK_TYPE" + ;; + + status) + check_config zone + pidfile="/var/run/dhclient_${zone}.pid" + pidofproc -p ${pidfile} ${EXECUTEABLE} &>/dev/null + exit $? + ;; + + pre-up) + ;; + + post-up) + check_config zone + pidfile="/var/run/dhclient_${zone}.pid" + if [ -e "${pidfile}" ]; then + kill $(<${pidfile}) &>/dev/null + sleep 1 + fi + ${EXECUTEABLE} -pf ${pidfile} ${zone} + evaluate_retval start + ;; + + pre-down) + check_config zone + pidfile="/var/run/dhclient_${zone}.pid" + killproc -p ${pidfile} ${EXECUTEABLE} + evaluate_retval stop + ;; + + post-down) + ;; + + add) + while [ $# -gt 0 ]; do + case "$1" in + --hostname=*) + HOSTNAME=${1#--hostname=} + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac + shift + done + cat <<EOF >${CONFIG_ZONES}/${zone}/ipv4-dhcp +HOOK="${HOOK_NAME}" +HOSTNAME="${HOSTNAME}" +EOF + [ "$?" = "0" ] && exit ${EXIT_OK} || exit ${EXIT_ERROR} + ;; + + rem) + ;; + + discover) + exit ${EXIT_ERROR} + ;; + + *) + echo "Usage: ${0} {config|pre-up|post-up|pre-down|post-down|status} [interface]" + exit ${EXIT_ERROR} + ;; +esac + +# End $NETWORK_DEVICES/services/ipv4-dhcp diff --git a/pkgs/core/network/src/hooks/ipv4-static b/pkgs/core/network/src/hooks/ipv4-static new file mode 100755 index 0000000..34af557 --- /dev/null +++ b/pkgs/core/network/src/hooks/ipv4-static @@ -0,0 +1,169 @@ +#!/bin/sh +######################################################################## +# Begin $NETWORK_DEVICES/services/ipv4-static +# +# Description : IPV4 Static Boot Script +# +# Authors : Nathan Coulson - nathan@linuxfromscratch.org +# Kevin P. Fleming - kpfleming@linuxfromscratch.org +# +# Version : 00.00 +# +# Notes : +# +######################################################################## + +. /lib/network/hook-header + +HOOK_NAME="ipv4-static" +HOOK_TYPE="zone" + +function check_config() { + args= + if [ -z "${IP}" ]; then + log_failure_msg "IP variable missing, cannot continue." + exit ${EXIT_CONF_ERROR} + fi + + if [ -z "${PREFIX}" -a -z "${PEER}" ]; then + log_warning_msg "PREFIX variable missing, assuming 24." + PREFIX=24 + args="${args} ${IP}/${PREFIX}" + elif [ -n "${PREFIX}" -a -n "${PEER}" ]; then + log_failure_msg "PREFIX and PEER both specified, cannot continue." + exit ${EXIT_CONF_ERROR} + elif [ -n "${PREFIX}" ]; then + args="${args} ${IP}/${PREFIX}" + elif [ -n "${PEER}" ]; then + args="${args} ${IP} peer ${PEER}" + fi + + if [ -n "${BROADCAST}" ]; then + args="${args} broadcast ${BROADCAST}" + fi + + if [ -n "${SOURCE}" ]; then + args="${args} src ${SOURCE}" + fi +} + +case "${action}" in + help) + ;; + + info) + echo "HOOK_NAME=$HOOK_NAME" + echo "HOOK_TYPE=$HOOK_TYPE" + ;; + + status) + check_config + echo -e "# ${CLR_BOLD_CYN}IPv4 static: ${IP}/${PREFIX}${NORMAL}" + if [ -n "${GATEWAY}" ]; then + echo "# Gateway: ${GATEWAY}" + echo -n "# Reachable: " + if ping -c1 -w1 -I ${zone} ${GATEWAY} &>/dev/null; then + echo -e "${CLR_BOLD_GRN}yes${NORMAL}" + else + echo -e "${CLR_BOLD_RED}no${NORMAL}" + fi + fi + ip addr show ${zone} | grep "inet " | fgrep -q "${IP}/${PREFIX}" + exit ${?} + ;; + + pre-up) + ;; + + post-up) + check_config + if ! device_has_ipv4 ${zone} ${IP}; then + MESSAGE="Adding IPv4 address ${IP} to zone ${zone} interface..." + ip addr add ${args} dev ${zone} + evaluate_retval + fi + + if [ -n "${GATEWAY}" ]; then + if ip route | grep -q default; then + log_warning_msg "Gateway already setup; skipping." ${WARNING} + else + MESSAGE="Setting up default gateway..." + ip route add default via ${GATEWAY} dev ${zone} + evaluate_retval + fi + fi + ;; + + pre-down) + check_config + if [ -n "${GATEWAY}" ]; then + MESSAGE="Removing default gateway..." + ip route del default + evaluate_retval + fi + + if device_has_ipv4 ${zone} ${IP}; then + MESSAGE="Removing IPv4 address ${IP} from zone ${zone}..." + ip addr del ${args} dev ${zone} + evaluate_retval + fi + ;; + + post-down) + ;; + + add) + while [ $# -gt 0 ]; do + case "$1" in + --ip=*) + IP=${1#--ip=} + ;; + --prefix=*) + PREFIX=${1#--prefix=} + ;; + --peer=*) + PEER=${1#--peer=} + ;; + --broadcast=*) + BROADCAST=${1#--broadcast=} + ;; + --source=*) + SOURCE=${1#--source=} + ;; + --gateway=*) + GATEWAY=${1#--gateway=} + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac + shift + done + #check_config + cat <<EOF >${CONFIG_ZONES}/${zone}/ipv4-static_$IP +HOOK="${HOOK_NAME}" +IP="${IP}" +PREFIX="${PREFIX}" +PEER="${PEER}" +BROADCAST="${BROADCAST}" +SOURCE="${SOURCE}" +GATEWAY="${GATEWAY}" +EOF + [ "$?" = "0" ] && exit ${EXIT_OK} || exit ${EXIT_ERROR} + ;; + + rem) + ;; + + discover) + exit ${EXIT_ERROR} + ;; + + *) + echo "Usage: ${0} {config|pre-up|post-up|pre-down|post-down|status} [interface]" + exit ${EXIT_ERROR} + ;; +esac + +# End $NETWORK_DEVICES/services/ipv4-static diff --git a/pkgs/core/network/src/hooks/ipv4-static-route b/pkgs/core/network/src/hooks/ipv4-static-route new file mode 100755 index 0000000..9e38986 --- /dev/null +++ b/pkgs/core/network/src/hooks/ipv4-static-route @@ -0,0 +1,141 @@ +#!/bin/sh +######################################################################## +# Begin $NETWORK_DEVICES/services/ipv4-static-route +# +# Description : IPV4 Static Route Script +# +# Authors : Kevin P. Fleming - kpfleming@linuxfromscratch.org +# +# Version : 00.00 +# +# Notes : +# +######################################################################## + +. /lib/network/hook-header + +HOOK_NAME=ipv4-static-route +HOOK_TYPE=zone + +function check_config() { + args= + case "${TYPE}" in + ""|network) + need_ip=1 + need_gateway=1 + ;; + + default) + need_gateway=1 + args="${args} default" + desc="default" + ;; + + host) + need_ip=1 + ;; + + unreachable) + need_ip=1 + args="${args} unreachable" + desc="unreachable" + ;; + + *) + log_failure_msg "Unknown route type (${TYPE}) in ${CONFIG}, cannot continue." + exit ${EXIT_CONF_ERROR} + ;; + esac + + if [ -n "${need_ip}" ]; then + if [ -z "${IP}" ]; then + log_failure_msg "IP variable missing from ${CONFIG}, cannot continue." + exit ${EXIT_CONF_ERROR} + fi + + if [ -z "${PREFIX}" ]; then + log_failure_msg "PREFIX variable missing from ${CONFIG}, cannot continue." + exit ${EXIT_CONF_ERROR} + fi + + args="${args} ${IP}/${PREFIX}" + desc="${desc}${IP}/${PREFIX}" + fi + + if [ -n "${need_gateway}" ]; then + if [ -z "${GATEWAY}" ]; then + log_failure_msg "GATEWAY variable missing from ${CONFIG}, cannot continue." + exit ${EXIT_CONF_ERROR} + fi + args="${args} via ${GATEWAY}" + fi +} + +case "${action}" in + add) + while [ $# -gt 0 ]; do + case "${1}" in + --ip=*) + IP=${1#--ip=} + ;; + --gateway=*) + GATEWAY=${1#--gateway=} + ;; + --prefix=*) + PREFIX=${1#--prefix=} + ;; + --type=*) + TYPE=${1#--type=} + ;; + esac + shift + done + check_config + cat <<EOF >${CONFIG_ZONES}/${zone}/${HOOK_NAME}_${IP-${GATEWAY}} +HOOK="${HOOK_NAME}" +IP="${IP}" +GATEWAY="${GATEWAY}" +PREFIX="${PREFIX}" +TYPE="${TYPE}" +EOF + [ "$?" = "0" ] && exit ${EXIT_OK} || exit ${EXIT_ERROR} + ;; + + help) + ;; + + info) + echo "HOOK_NAME=${HOOK_NAME}" + echo "HOOK_TYPE=${HOOK_TYPE}" + ;; + + pre-up) + ;; + + post-up) + boot_mesg "Adding '${desc}' route to zone ${zone}..." + ip route add ${args} dev ${zone} + evaluate_retval + ;; + + pre-down) + boot_mesg "Removing '${desc}' route from zone ${zone}..." + ip route del ${args} dev ${zone} + evaluate_retval + ;; + + post-down) + ;; + + discover) + + exit ${EXIT_ERROR} + ;; + + *) + echo "Usage: ${0} [interface] {up|down}" + exit 1 + ;; +esac + +# End $NETWORK_DEVICES/services/ipv4-static-route diff --git a/pkgs/core/network/src/hooks/mtu b/pkgs/core/network/src/hooks/mtu new file mode 100755 index 0000000..707345a --- /dev/null +++ b/pkgs/core/network/src/hooks/mtu @@ -0,0 +1,85 @@ +#!/bin/sh +######################################################################## +# Begin $NETWORK_DEVICES/services/mtu +# +# Description : Sets MTU per interface +# +# Authors : Nathan Coulson - nathan@linuxfromscratch.org +# Jim Gifford - jim@linuxfromscratch.org +# +# Version : 00.00 +# +# Notes : This sets the maximum amount of bytes that can be +# transmitted within a packet. By default, this +# value is set to 1500. +# +######################################################################## + +. /lib/network/hook-header + +HOOK_NAME=mtu +HOOK_TYPE=zone + +DEFAULT_MTU=1500 + +function usage() { + echo "Usage: ${0} {pre-up|post-up|pre-down|post-down|config} [interface]" +} + +case "${action}" in + help) + ;; + + info) + echo "HOOK_NAME=$HOOK_NAME" + echo "HOOK_TYPE=$HOOK_TYPE" + ;; + + status) + check_config zone MTU + mtu=$(cat /sys/class/net/${zone}/mtu 2>/dev/null) + [ "$MTU" = "$mtu" ] + exit $? + ;; + + pre-up) + ;; + + post-up) + check_config zone MTU + message="Setting the MTU for ${zone} to ${MTU}..." + echo "${MTU}" > "/sys/class/net/${zone}/mtu" + evaluate_retval standard + ;; + + pre-down) + check_config zone MTU + message="Resetting MTU for ${zone} to 1500..." + echo ${DEFAULT_MTU} > "/sys/class/net/${zone}/mtu" + evaluate_retval standard + ;; + + post-down) + ;; + + config) + MTU=$1 + check_config zone MTU + cat << EOF >> ${CONFIG_ZONES}/${zone}/${HOOK_NAME} +HOOK="${HOOK_NAME}" +MTU="${MTU}" +EOF + exit $? + ;; + + discover) + exit ${EXIT_ERROR} + ;; + + *) + usage + exit 1 + ;; +esac + +# End $NETWORK_DEVICES/services/mtu diff --git a/pkgs/core/network/src/hooks/pppoe b/pkgs/core/network/src/hooks/pppoe new file mode 100755 index 0000000..d27a517 --- /dev/null +++ b/pkgs/core/network/src/hooks/pppoe @@ -0,0 +1,191 @@ +#!/bin/sh +######################################################################## +# Begin $NETWORK_DEVICES/services/ipv4-static +# +# Description : IPV4 Static Boot Script +# +# Authors : Nathan Coulson - nathan@linuxfromscratch.org +# Kevin P. Fleming - kpfleming@linuxfromscratch.org +# +# Version : 00.00 +# +# Notes : +# +######################################################################## + +. /lib/network/hook-header +. /lib/network/functions.ppp + +HOOK_NAME="pppoe" +HOOK_TYPE="zone" + +PPPOE_PLUGIN=rp-pppoe.so + +case "${action}" in + help) + ;; + + info) + echo "HOOK_NAME=$HOOK_NAME" + echo "HOOK_TYPE=$HOOK_TYPE" + ;; + + status) + echo -e "# ${CLR_BOLD_CYN}PPPoE: ${NAME}${NORMAL}" + echo -n "# pppd's PID: " + pid=$(head -n1 /var/run/ppp-${NAME}.pid 2>/dev/null) + if [ -n "${pid}" ] && [ -d "/proc/${pid}" ]; then + echo -e "${CLR_BOLD_GRN}${pid}${NORMAL}" + exit ${EXIT_OK} + else + echo -e "${CLR_BOLD_RED}${pid-off}${NORMAL}" + exit ${EXIT_OK} + fi + ;; + + pre-up) + ppp_pre_up + + check_config NAME + # Creating necessary files + [ -d "${RED_RUN}/${NAME}" ] || mkdir -p ${RED_RUN}/${NAME} + + ppp_secret "${USER}" "${SECRET}" + + cat <<EOF >${RED_RUN}/${NAME}/options +# Naming options +name ${NAME} +linkname ${NAME} + +plugin ${PPPOE_PLUGIN} ${zone} + +# User configuration +user ${USER} + +$([ "${PEERDNS}" = "1" ] && echo "usepeerdns") +$([ "${DEFAULTROUTE}" = "1" ] && echo "defaultroute") + +noauth +$([ -n "${AUTH}" ] && echo "require-${AUTH}") + +noipdefault + +# Maximum transmission/receive unit +mtu ${MTU} +mru ${MTU} + +# Disable the compression +noaccomp nodeflate nopcomp novj novjccomp nobsdcomp + +debug +EOF + ;; + + post-up) + check_config zone NAME + MESSAGE="Starting PPP Daemon on interface ${zone}..." + if zone_is_forwarding ${zone}; then + pppd file ${RED_RUN}/${NAME}/options >/dev/null + evaluate_retval + else + log_failure_msg "Zone ${zone} is not forwaring any traffic..." + exit ${EXIT_ERROR} + fi + + ppp_post_up + ;; + + pre-down) + ppp_pre_down + + MESSAGE="Stopping PPP Daemon on interface ${zone}..." + pid=$(head -n1 /var/run/ppp-${NAME}.pid 2>/dev/null) + if [ -n "${pid}" ]; then + kill ${pid} &>/dev/null + evaluate_retval + fi + ;; + + post-down) + ppp_post_down + ;; + + add) + # A pregenerated connection name + NAME=$(</proc/sys/kernel/random/uuid) + DEFAULTROUTE=1 + PEERDNS=1 + MTU=1492 + + while [ $# -gt 0 ]; do + case "$1" in + --user=*) + USER=${1#--user=} + ;; + --secret=*) + SECRET=${1#--secret=} + ;; + --name=*) + NAME=${1#--name=} + ;; + --mtu=*) + MTU=${1#--mtu=} + ;; + --no-defaultroute) + DEFAULTROUTE=0 + ;; + --no-dns) + PEERDNS=0 + ;; + --auth=*) + AUTH=${1#--auth=} + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac + shift + done + + UUID=$(uuid) + cat <<EOF >${CONFIG_UUIDS}/${UUID} +HOOK="${HOOK_NAME}" +USER="${USER}" +SECRET="${SECRET}" +NAME="${NAME}" +MTU="${MTU}" +DEFAULTROUTE="${DEFAULTROUTE}" +PEERDNS="${PEERDNS}" +AUTH="${AUTH}" +EOF + + ln -sf ${CONFIG_UUIDS}/${UUID} \ + ${CONFIG_ZONES}/${zone}/${HOOK_NAME}-${UUID} + + exit ${EXIT_OK} + ;; + + discover) + output=$(pppoe-discovery -I ${zone} \ + -U $(</proc/sys/kernel/random/uuid) 2>&1) + if grep -q "Timeout" <<<${output}; then + echo "${HOOK_NAME}: FAILED" + exit ${EXIT_ERROR} + else + echo "${HOOK_NAME}: OK" + echo "${output}" | while read line; do + [ "${line:0:1}" = "A" ] || continue + echo "${HOOK_NAME}: ${line}" + done + exit ${EXIT_OK} + fi + ;; + + *) + echo "Usage: ${0} {config|pre-up|post-up|pre-down|post-down|status} [interface]" + exit ${EXIT_ERROR} + ;; +esac + +# End $NETWORK_DEVICES/services/ipv4-static diff --git a/pkgs/core/network/src/hooks/pppoe.helper b/pkgs/core/network/src/hooks/pppoe.helper new file mode 100755 index 0000000..693ba3d --- /dev/null +++ b/pkgs/core/network/src/hooks/pppoe.helper @@ -0,0 +1,73 @@ +#!/bin/bash + +. /lib/network/functions +. /lib/network/functions.ppp + +while [ $# -gt 0 ]; do + case "${1}" in + --config=*) + . ${1#--config=} + ;; + *) + action=${1} + break + ;; + esac + shift +done + +zone=${DEVICE} + +DIR=${RED_RUN}/${LINKNAME} + +case "${action}" in + ip-up) + mkdir -p ${DIR} 2>/dev/null + + echo "${IPREMOTE}" > ${DIR}/remote-ip-address + echo "${IPLOCAL}" > ${DIR}/local-ip-address + + # Update firewall with new IP address(es) + + # Prepare main routing table + ip route add ${IPREMOTE}/32 dev ${IFNAME} src ${IPLOCAL} + + # Configure our own routing table + ip route add table ${zone} default via ${IPREMOTE} dev ${IFNAME} + + if [ "${DEFAULTROUTE}" = "1" ]; then + ln -sf remote-ip-address ${DIR}/gateway + [ -n "${WEIGHT}" ] && \ + echo "${WEIGHT}" > ${DIR}/weight + + red_defaultroute_update + fi + + if [ "${PEERDNS}" = "1" ]; then + echo "${DNS1}" > ${DIR}/dns + if [ -n "${DNS2}" ] && [ "${DNS1}" != "${DNS2}" ]; then + echo "${DNS2}" > ${DIR}/dns + fi + red_dns_update + fi + ;; + + ip-down) + # Flush firewall + + if [ "${DEFAULTROUTE}" = "1" ]; then + : + fi + + ip route flush table ${zone} + + if [ "${PEERDNS}" = "1" ]; then + : + fi + + # Save statistics + ppp_stat "${NAME}" "${CONNECT_TIME}" "${BYTES_RCVD}" "${BYTES_SENT}" + ;; +esac + +exit 0 diff --git a/pkgs/core/network/src/hooks/stp b/pkgs/core/network/src/hooks/stp new file mode 100755 index 0000000..9e1c465 --- /dev/null +++ b/pkgs/core/network/src/hooks/stp @@ -0,0 +1,97 @@ +#!/bin/sh +######################################################################## +# Begin $NETWORK_DEVICES/services/stp +# +# Description : Spanning Tree Protocol Script +# +# Authors : Michael Tremer - michael.tremer@ipfire.org +# +# Version : 00.00 +# +# Notes : This script adds stp support to a bridge. +# +######################################################################## + +. /lib/network/hook-header + +HOOK_NAME=stp +HOOK_TYPE=zone + +case "${action}" in + help) + ;; + + info) + echo "HOOK_NAME=$HOOK_NAME" + echo "HOOK_TYPE=$HOOK_TYPE" + ;; + + pre-up) + ;; + + post-up) + MESSAGE="Enabling Spanning Tree Protocol on zone ${zone}..." + brctl stp ${zone} on + evaluate_retval + ;; + + pre-down) + MESSAGE="Disabling Spanning Tree Protocol on zone ${zone}..." + brctl stp ${zone} off + evaluate_retval + ;; + + post-down) + ;; + + add) + shift 2 + while [ $# -gt 0 ]; do + case "$1" in + --ageing=*) + AGEING=${1#--ageing=} + ;; + --priority=*) + PRIORITY=${1#--priority=} + ;; + --delay=*) + DELAY=${1#--delay=} + ;; + --hello=*) + HELLO=${1#--hello=} + ;; + --maxage=*) + MAXAGE=${1#--maxage=} + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac + shift + done + cat <<EOF >${CONFIG_ZONES}/${zone}/${HOOK_NAME} +HOOK="${HOOK_NAME}" +AGEING="${AGEING}" +PRIORITY="${PRIORITY}" +DELAY="${DELAY}" +HELLO="${HELLO}" +MAXAGE="${MAXAGE}" +EOF + exit $? + ;; + + rem) + ;; + + discover) + exit ${EXIT_ERROR} + ;; + + *) + echo "Usage: ${0} {pre-up|post-up|pre-down|post-down|config} [interface]" + exit 1 + ;; +esac + +# End $NETWORK_DEVICES/services/stp diff --git a/pkgs/core/network/src/hooks/vlan b/pkgs/core/network/src/hooks/vlan new file mode 100755 index 0000000..e4d99e6 --- /dev/null +++ b/pkgs/core/network/src/hooks/vlan @@ -0,0 +1,120 @@ +#!/bin/sh +######################################################################## +# Begin $NETWORK_DEVICES/services/vlan +# +# Description : VLAN Script +# +# Authors : Michael Tremer - michael.tremer@ipfire.org +# +# Version : 00.00 +# +# Notes : This script adds vlan support. +# +######################################################################## + +. /lib/network/hook-header + +HOOK_NAME=vlan +HOOK_TYPE=port + +function port_name() { + echo "${zone}v${ID}" +} + +case "${action}" in + help) + ;; + + info) + echo "HOOK_NAME=${HOOK_NAME}" + echo "HOOK_TYPE=${HOOK_TYPE}" + ;; + + pre-up) + # Load the kernel module + grep -q ^8021q /proc/modules || modprobe 8021q + + if ! port_is_up $(port_name); then + MESSAGE="Adding VLAN ${ID} to port ${MAC}..." + + if ! device_is_up $(devicify ${MAC}); then + ip link set $(devicify ${MAC}) up + fi + vconfig add $(devicify ${MAC}) ${ID} >/dev/null + evaluate_retval + + device_rename $(get_device_by_mac_and_vid ${MAC} ${ID}) $(port_name) + ip link set $(port_name) up + + ebtables -t broute -A BROUTING -p 802_1Q --vlan-id=${ID} -j DROP + fi + ;; + + post-up) + if ! zone_has_device_attached ${zone} $(port_name); then + zone_add_port ${zone} $(get_device ${MAC} ${ID}) + fi + ;; + + pre-down) + if zone_has_device_attached ${zone} $(port_name); then + zone_del_port ${zone} $(get_device_by_mac_and_vid ${MAC} ${ID}) + fi + ;; + + post-down) + if port_is_up $(port_name); then + MESSAGE="Removing VLAN ${ID} from port ${MAC}..." + + vconfig rem $(get_device_by_mac_and_vid ${MAC} ${ID}) >/dev/null + evaluate_retval + + ebtables -t broute -D BROUTING -p 802_1Q --vlan-id=${ID} -j DROP + fi + ;; + + add) + MAC=$(macify ${1}) + ID=${2} # Must be integer between 1 and 4096 + + UUID=$(uuid) + cat <<EOF > ${CONFIG_UUIDS}/${UUID} +HOOK="${HOOK_NAME}" +ID="${ID}" +MAC="${MAC}" +EOF + ln -sf ${CONFIG_UUIDS}/${UUID} \ + ${CONFIG_ZONES}/${zone}/${HOOK_NAME}-${UUID} + + log_success_msg "Configuration successfully saved!" + echo " Device : $(devicify ${MAC})" + echo " MAC address : ${MAC}" + echo " VLAN tag : ${ID}" + ;; + + rem) + # XXX to be done + ;; + + status) + echo -e "# ${CLR_BOLD_CYN}VLAN port $(port_name)${NORMAL}" + echo -n "# State: " + if device_is_up $(port_name); then + echo -e "${CLR_BOLD_GRN}up${NORMAL}" + RET=${EXIT_OK} + else + echo -e "${CLR_BOLD_RED}down${NORMAL}" + RET=${EXIT_ERROR} + fi + echo "# ID : ${ID}" + echo "#" + exit ${RET} + ;; + + *) + echo "Usage: ${0} [interface] {up|down|add|remove|attach|detach|status}" + exit 1 + ;; +esac + +# End $NETWORK_DEVICES/services/vlan diff --git a/pkgs/core/network/src/network b/pkgs/core/network/src/network new file mode 100644 index 0000000..2bcbbe1 --- /dev/null +++ b/pkgs/core/network/src/network @@ -0,0 +1,615 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +BOLD="\033[1;39m" +NORMAL="\033[0;39m" +ERROR="\033[1;31m" + +. /etc/init/functions + +if [ -e "/lib/network/functions" ]; then + . /lib/network/functions +elif [ -e "lib/functions" ]; then + HOME_DIR="lib" + . lib/functions +else + echo "Cannot find functions library. Exiting." >&2 + exit 1 +fi + +function usage() { + echo -e "${BOLD}Usage $0${NORMAL}:\n" + case "$1" in + main|"") + echo "This script will help you configuring your network." + echo + echo "You should know that there are three different things:" + echo + echo " hook: A script to control connections and protocols." + echo " port: A physical connection to somewhere." + echo " zone: A group of ports." + echo + echo " $0 [global flags] <hook|port|zone> ... or" + echo " $0 [global flags] <cmd line options...>" + echo + echo -e "${BOLD}Global flags:${NORMAL}" + echo " --verbose -v - Turn on verbose mode." + echo " --debug -d - Turn on debug mode." + echo + echo -e "${BOLD}Command line options:${NORMAL}" + echo " help - Prints this help message." + echo " start - Starts the whole network." + echo " stop - Stops the whole network." + echo " restart - Restarts the whole network." + echo " reload - Reloads the whole network." + echo + echo " hook - Run "$0 hook help" for more information." + echo " port - Run "$0 port help" for more information." + echo " zone - Run "$0 zone help" for more information." + echo + ;; + hook*) + echo -e "${BOLD}Hook configuration:${NORMAL}" + echo + echo " ${0} [global options] hook <command>" + echo + echo -e "${BOLD}1st level commands:${NORMAL}" + echo -e " ${BOLD}list:${NORMAL}" + echo " Returns a list of all available hooks." + echo + echo + echo " ${0} [global options] hook <hook> <command>" + echo + echo -e "${BOLD}2nd level commands:${NORMAL}" + echo -e " ${BOLD}help:${NORMAL}" + echo " Displays some help about the given hook." + echo + echo " Example: $0 hook ethernet help" + echo + ;; + port) + echo -e "${BOLD}Port Configuration:${NORMAL}" + echo + echo " $0 [global options] port <command> ..." + echo + echo -e "${BOLD}Commands:${NORMAL}" + echo -e " ${BOLD}show:${NORMAL}" + echo " Displays information about a given port." + echo + echo " Requires a "port"." + echo " Example: $0 port show 00:11:22:33:44:55" + echo " $0 port show port0" + echo + ;; + zone) + echo -e "${BOLD}Zone Configuration:${NORMAL}" + echo + echo " $0 [global options] zone <command> ..." + echo + echo -e "${BOLD}Commands:${NORMAL}" + echo -e " ${BOLD}show:${NORMAL}" + echo " Displays information about a given zone." + echo + echo " Requires a "zone"." + echo " Example: $0 zone show green0" + echo + echo -e " ${BOLD}add:${NORMAL}" + echo " Adds a new zone." + echo + echo " Requires a "zone"." + echo " Example: $0 zone add green0" + echo + echo -e " ${BOLD}del:${NORMAL}" + echo " Deletes a zone." + echo + echo " Requires a "zone"." + echo " Example: $0 zone del green0" + echo + echo -e " ${BOLD}addport:${NORMAL}" + echo " Adds a port to a zone." + echo + echo " Requires a "zone" and "port"." + echo " Example: $0 zone addport green0 port0" + echo + echo " You may also pass a hook and its parameters:" + echo " $0 zone addport green0 port0 vlan 10" + echo + echo -e " ${BOLD}delport:${NORMAL}" + echo " Deletes a port from a zone." + echo + echo " Requires a "zone" and "port"." + echo " Example: $0 zone delport green0" + echo + echo " You may also pass a hook and its parameters:" + echo " $0 zone delport green0 port0 vlan 10" + echo + esac + _exit ${2-1} +} + +function debug() { + if [ -n "$1" ]; then + DEBUG=$1 + verbose $1 + return + else + if [ "$DEBUG" = "1" ]; then + return 0 + else + return 1 + fi + fi +} + +function verbose() { + if [ -n "$1" ]; then + VERBOSE=$1 + return + else + if [ "$VERBOSE" = "1" ]; then + return 0 + else + return 1 + fi + fi +} + +function decho() { + debug && echo -e "${ERROR}$@${NORMAL}" >&2 +} + +function vecho() { + verbose && echo -e "$@" >&2 +} + +function error() { + echo -e "${ERROR}ERROR${NORMAL}: $@" >&2 + _exit 1 +} + +function _exit() { + local code + local reload + + while [ $# -gt 0 ]; do + case "$1" in + --reload) + reload=1 + ;; + [0-9]*) + code=$1 + ;; + *) + error "Unrecognized argument: $1" + ;; + esac + shift + done + + if [ "${reload}" = "1" ]; then + # Reloading network to apply changes immediately + vecho "Reloading network settings..." + cmd $0 reload + + # Reload firewall, too + firewall=$(which firewall 2>/dev/null) + if [ -n "${firewall}" ]; then + vecho "Reloading firewall..." + cmd ${firewall} reload + fi + fi + + decho "Exiting with code ${code}." + exit ${code} +} + +function cmd() { + decho "Running command: $@" + if debug; then + DEBUG=${DEBUG} VERBOSE=${VERBOSE} $@ + else + DEBUG=${DEBUG} VERBOSE=${VERBOSE} $@ >/dev/null + fi +} + +function size() { + local size=${1} + + local units + units[0]="Bytes " + units[1]="kBytes" + units[2]="MBytes" + units[3]="GBytes" + units[4]="TBytes" + + local count=${#units} + while [ ${count} -gt 0 ]; do + if [ ${size} -lt 1024 ]; then + break + fi + size=$((${size} / 1024)) + count=$((${count} - 1)) + done + printf "%4d %s\n" "${size}" "${units[$((${#units} - ${count}))]}" +} + +function port_show() { + local port + if [ $# -eq 0 ]; then + for port in /sys/class/net/*; do + port=${port##*/} + device_is_real ${port} || continue + port_show ${port} + done + return + fi + + port=$(devicify $1) + + echo "##################################################" + echo "#" + echo -e "# Port ${CLR_BOLD_BLU}${port}${NORMAL}" + echo "# ------------------------------------------------" + + echo -n "# State: " + if device_is_up ${port}; then + echo -e "${CLR_BOLD_GRN}up${NORMAL}" + else + echo -e "${CLR_BOLD_RED}down${NORMAL}" + fi + + echo -n "# Link : " + if device_has_carrier ${port}; then + echo -e "${CLR_BOLD_GRN}yes${NORMAL}" + else + echo -e "${CLR_BOLD_RED}no${NORMAL}" + fi + + if device_is_up ${port}; then + echo "#" + echo "# Statistics:" + echo -n "# RX: $(size $(</sys/class/net/${port}/statistics/rx_bytes))" + echo " ($(</sys/class/net/${port}/statistics/rx_packets) packets)" + echo -n "# TX: $(size $(</sys/class/net/${port}/statistics/tx_bytes))" + echo " ($(</sys/class/net/${port}/statistics/tx_packets) packets)" + fi + + echo "#" +} + +function port_raw() { + local port + if [ $# -eq 0 ]; then + for port in /sys/class/net/*; do + port=${port##*/} + device_is_real ${port} || continue + port_raw ${port} + done + return + fi + + port=$(devicify $1) + + cat <<EOF +[${port}] +type=$(device_type ${port}) +mac=$(macify ${port}) +carrier=$(device_has_carrier ${port} && echo "1" || echo "0") +up=$(device_is_up ${port} && echo "1" || echo "0") + +EOF +} + +function port_add() { + local zone=${1} + local hook=${2} + shift 2 + + if ! zone_exists ${zone}; then + error "Zone ${BOLD}${zone}${NORMAL} does not exist." + return 1 + fi + + mkdir -p ${CONFIG_PORTS}/${port} 2>/dev/null + if hook_exists ${hook}; then + /lib/network/hooks/${hook} --zone=${zone} add $@ + RET=$? + if [ "$RET" -eq "0" ]; then + vecho "Successfully added port to ${BOLD}${zone}${NORMAL}." + else + error "Hook ${BOLD}${hook}${NORMAL} exited with $RET." + return $RET + fi + else + error "Hook ${BOLD}${hook}${NORMAL} does not exist or is not executeable." + return 1 + fi +} + +function port_del() { + local config + local hook + local uuid + + local zone=${1} + shift + + if is_uuid ${1}; then + uuid=${1} + config="${CONFIG_UUIDS}/${uuid}" + + if [ -e "${config}" ]; then + hook=$(config_get_hook ${config}) + else + error "Given config file does not exist: ${config}." + return 1 + fi + fi + + hook_run --config=${config} pre-down + hook_run --config=${config} post-down + hook_run --config=${config} rem +} + +function zone_discover() { + local zone=${1} + + for hook in $(hook_list zone); do + hook_run ${hook} --zone=${zone} discover + done +} + +function zone_show() { + local zone + zone=$1 + + if [ -z "$zone" ]; then + for zone in ${CONFIG_ZONES}/*; do + zone_show $(basename $zone) + done + return + fi + + if ! zone_exists ${zone}; then + error "Zone ${BOLD}${zone}${NORMAL} does not exist." + return 2 + fi + + echo "##################################################" + echo "#" + echo -e "# Zone ${CLR_BOLD_BLU}${zone}${NORMAL}" + echo "# ------------------------------------------------" + + # Up or down? + if zone_is_up ${zone}; then + echo -e "# Status: ${CLR_BOLD_GRN}up${NORMAL}" + else + echo -e "# Status: ${CLR_BOLD_RED}down${NORMAL}" + fi + echo "#" + + # Ports + echo -e "# ${CLR_BOLD_BLU}Ports:${NORMAL}" + hooks_run_ports status ${CONFIG_ZONES}/${zone} --zone=${zone} + + echo "#" + echo -e "# ${CLR_BOLD_BLU}Zone configurations:${NORMAL}" + hooks_run_zones status ${CONFIG_ZONES}/${zone} --zone=${zone} + echo "#" + +} + +function zone_raw() { + local zone + if [ $# -eq 0 ]; then + for zone in $(zone_list); do + zone_raw ${zone##*/} + done + return + fi + + zone=${1} + +cat <<EOF +[${zone}] +up=$(zone_is_up ${zone} && echo "1" || echo "0") + +EOF +} + +function zone_add() { + local zone=$1 + + if zone_exists ${zone}; then + error "Zone ${BOLD}${zone}${NORMAL} already exists." + return 1 + fi + + if ! zone_valid_name ${zone}; then + error "The given zone name is not valid." + return 1 + fi + + mkdir -p ${CONFIG_ZONES}/${zone} + vecho "Successfully added zone ${BOLD}${zone}${NORMAL}." +} + +function zone_del() { + local zone=$1 + + if ! zone_exists ${zone}; then + error "Zone ${BOLD}${zone}${NORMAL} does not exist." + return 1 + fi + + cmd /lib/network/zone --zone=${zone} down + rm -rf ${CONFIG_ZONES}/${zone} + vecho "Successfully removed zone ${BOLD}${zone}${NORMAL}." +} + +# See what to do +while [ "$#" -gt 0 ]; do + arg=$1 + shift + + case "$arg" in + --debug|-d) + debug 1 + decho "Debug mode enabled." + ;; + --verbose|-v) + verbose 1 + vecho "${BOLD}Verbose mode enabled.${NORMAL}" + ;; + help|-h|--help) + usage main 0 + ;; + start|stop|reload) + action=${arg} + for zone in $(zone_list); do + zone=${zone##*/} + decho "Running command: ${HOME_DIR}/zone --zone=${zone} ${action}" + DEBUG=${DEBUG} VERBOSE=${VERBOSE} ${HOME_DIR}/zone --zone=${zone} ${action} + done + _exit $? + ;; + restart) + DEBUG=${DEBUG} VERBOSE=${VERBOSE} $0 stop $@ + sleep 1 + DEBUG=${DEBUG} VERBOSE=${VERBOSE} $0 start $@ + _exit $? + ;; + hook|hooks) + case "$1" in + list) + hook_list + _exit $? + ;; + *) + if hook_exists ${1}; then + hook=${1} + else + usage hook + fi + esac + shift + case "$1" in + help|info) + if hook_exists ${hook}; then + hook_run ${hook} ${1} + _exit $? + else + error "Hook ${hook} does not exist or is not executeable." + _exit 1 + fi + ;; + *) + usage hook + ;; + esac + ;; + p*) + arg=$1 + shift + case "$arg" in + help) + usage port 0 + ;; + show) + port_show $@ + _exit $? + ;; + _raw) + port_raw $@ + _exit $? + ;; + esac + ;; + z*) + arg=$1 + shift + case "$arg" in + add) + zone_add $@ + _exit --reload $? + ;; + addport) + port_add $@ + _exit --reload $? + ;; + config) + zone=$1; hook=$2; shift 2 + if [ -z "${zone}" ] || [ -z "${hook}" ]; then + usage config + fi + hook_run ${hook} --zone=${zone} add $@ + _exit --reload $? + ;; + del) + zone_del $@ + _exit --reload $? + ;; + delport) + port_del $@ + _exit --reload $? + ;; + discover) + zone_discover $@ + _exit $? + ;; + help) + usage zone 0 + ;; + list) + zone_list + _exit $? + ;; + show) + zone_show $@ + _exit $? + ;; + start|stop) + zone=$1; shift + zone_run --zone=${zone} ${arg} $@ + ;; + _raw) + zone_raw $@ + _exit $? + ;; + esac + ;; + show) + arg=${1} + shift + case "${arg}" in + ports) + port_show $@ + _exit 0 + ;; + esac + ;; + -*) + error "Option "$arg" is not known." + ;; + esac +done + +usage main diff --git a/pkgs/core/network/src/ppp/ip-updown b/pkgs/core/network/src/ppp/ip-updown new file mode 100644 index 0000000..24f60d3 --- /dev/null +++ b/pkgs/core/network/src/ppp/ip-updown @@ -0,0 +1,41 @@ +#!/bin/sh +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +umask 022 +export PATH=/usr/sbin:/sbin:/usr/bin:/bin + +. /lib/network/functions +. /lib/network/functions.ppp + +for config in ${CONFIG_ZONES}/${DEVICE}/*; do + if [ "$(ppp_linkname_get ${config})" = "${LINKNAME}" ]; then + CONFIG=${config} + . ${CONFIG} + break + fi +done + +if [ -n "${HOOK}" ] && [ -x "${HOOKS_DIR}/${HOOK}.helper" ]; then + exec ${HOOKS_DIR}/${HOOK}.helper --config=${CONFIG} \ + $(basename $0) $@ +fi + +exit ${EXIT_ERROR} diff --git a/pkgs/core/network/src/zone b/pkgs/core/network/src/zone new file mode 100755 index 0000000..0f5b355 --- /dev/null +++ b/pkgs/core/network/src/zone @@ -0,0 +1,93 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +. /etc/init/functions +. /lib/network/functions + +while [ "$#" -gt "0" ]; do + case "${1}" in + --zone=*) + zone=${1#--zone=} + ;; + *) + action=${1} + break + ;; + esac + shift +done + +if [ -z "${zone}" ] || [ -z "${action}" ]; then + log_failure_msg "Wrong number of arguments." + exit ${EXIT_ERROR} +fi + +if ! zone_exists ${zone}; then + echo "Zone ${zone} does not exist." + exit ${EXIT_ERROR} +fi + +case "$action" in + start|up|reload) + message="Bringing up zone ${zone}..." + + hooks_run_all pre-up ${CONFIG_ZONES}/${zone} --zone=${zone} + + if ! zone_is_up ${zone}; then + # Create and bring up the zone + brctl addbr ${zone} || failed=1 + brctl stp ${zone} on || failed=1 + brctl setfd ${zone} 0 || failed=1 + ip link set ${zone} up || failed=1 + (exit ${failed}) + evaluate_retval standard + fi + + # First bring up the ports to be able to start something like + # a dhcp client that needs a running interface. + hooks_run_ports post-up ${CONFIG_ZONES}/${zone} --zone=${zone} + hooks_run_zones post-up ${CONFIG_ZONES}/${zone} --zone=${zone} + ;; + + stop|down) + message="Bringing down zone ${zone}..." + + if zone_is_up ${zone}; then + hooks_run_zones pre-down ${CONFIG_ZONES}/${zone} --zone=${zone} + hooks_run_ports pre-down ${CONFIG_ZONES}/${zone} --zone=${zone} + + # Bring down the zone and delete it + ip link set ${zone} down || failed=1 + brctl delbr ${zone} || failed=1 + (exit ${failed}) + evaluate_retval standard + + hooks_run_all post-down ${CONFIG_ZONES}/${zone} --zone=${zone} + else + log_warning_msg ${message} + log_warning_msg "Zone ${zone} does not exist." + fi + ;; + + *) + exit 1 + ;; +esac diff --git a/pkgs/core/newt/newt.nm b/pkgs/core/newt/newt.nm new file mode 100644 index 0000000..624a500 --- /dev/null +++ b/pkgs/core/newt/newt.nm @@ -0,0 +1,62 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = newt +PKG_VER = 0.52.10 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = https://fedorahosted.org/releases/n/e/newt/ +PKG_LICENSE = LGPLv2 +PKG_SUMMARY = A library for text mode user interfaces. + +PKG_DEPS += popt python slang + +define PKG_DESCRIPTION + Newt is a programming library for color text mode, widget based user \ + interfaces. Newt can be used to add stacked windows, entry widgets, \ + checkboxes, radio buttons, labels, plain text fields, scrollbars, \ + etc., to text mode user interfaces. This package also contains the \ + shared library needed by programs built with newt, as well as a \ + /usr/bin/dialog replacement called whiptail. Newt is based on the \ + slang library. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --without-gpm-support \ + --without-tcl + +define STAGE_PREPARE_CMDS + # make install searches for /usr/bin/install + cd $(DIR_APP) && sed -e "s/^INSTALL=.*/INSTALL = install -c/" -i po/Makefile +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install instroot=$(BUILDROOT) +endef diff --git a/pkgs/core/nfs-utils/nfs-utils.nm b/pkgs/core/nfs-utils/nfs-utils.nm new file mode 100644 index 0000000..ddf9a57 --- /dev/null +++ b/pkgs/core/nfs-utils/nfs-utils.nm @@ -0,0 +1,62 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = nfs-utils +PKG_VER = 1.2.2 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://nfs.sourceforge.net/ +PKG_LICENSE = MIT and GPLv2 and GPLv2+ +PKG_SUMMARY = NFS utilities and supporting clients and daemons for the NFS server. + +PKG_DEPS += libevent libnfsidmap libgssglue libcap util-linux-ng + +define PKG_DESCRIPTION + The nfs-utils package provides a daemon for the kernel NFS server \ + and related tools, which provides a much higher level of performance \ + than the traditional Linux NFS server used by most users. This \ + package also contains the showmount program. Showmount queries the \ + mount daemon on a remote host for information about the NFS server \ + on the remote host. For example, showmount can display the clients \ + which are mounted on that host. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --mandir=/usr/share/man \ + --sysconfdir=/etc \ + --without-tcp-wrappers \ + --disable-static \ + --enable-tirpc=no \ + --enable-nfsv3 \ + --enable-nfsv4 \ + --with-krb5=no \ + --disable-gss \ + --with-rpcgen=internal \ + --enable-mount diff --git a/pkgs/core/nmap/nmap.nm b/pkgs/core/nmap/nmap.nm new file mode 100644 index 0000000..c4f54c0 --- /dev/null +++ b/pkgs/core/nmap/nmap.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = nmap +PKG_VER = 5.00 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Sniffer +PKG_URL = http://nmap.org/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Network exploration tool and security scanner. + +PKG_DEPS += libdnet libpcap lua openssl pcre + +define PKG_DESCRIPTION + Nmap is a utility for network exploration or security auditing. \ + It supports ping scanning, many port scanning techniques, and \ + TCP/IP fingerprinting. Nmap also offers flexible target and port \ + specification, decoy scanning, determination of TCP sequence \ + predictability characteristics, reverse-identd scanning, and more. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --without-nmapfe \ + --without-zenmap diff --git a/pkgs/core/nmap/patches/nmap-5.00-mktemp.patch b/pkgs/core/nmap/patches/nmap-5.00-mktemp.patch new file mode 100644 index 0000000..68baffe --- /dev/null +++ b/pkgs/core/nmap/patches/nmap-5.00-mktemp.patch @@ -0,0 +1,23 @@ +--- nmap-4.03/shtool.mktemp 2006-05-10 13:09:34.000000000 +0200 ++++ nmap-4.03/shtool 2006-05-10 13:13:58.000000000 +0200 +@@ -579,15 +579,11 @@ + else + tmpdir="/tmp" + fi +- tmpdir="$tmpdir/.shtool.$$" +- ( umask 077 +- rm -rf "$tmpdir" >/dev/null 2>&1 || true +- mkdir "$tmpdir" >/dev/null 2>&1 +- if [ $? -ne 0 ]; then +- echo "$msgprefix:Error: failed to create temporary directory `$tmpdir'" 1>&2 +- exit 1 +- fi +- ) ++ tmpdir=`mktemp -p $tmpdir -d` ++ if [ $? -ne 0 ]; then ++ echo "$msgprefix:Error: failed to create temporary directory `$tmpdir'" 1>&2 ++ exit 1 ++ fi + + # create (implicitly) secure temporary file + tmpfile="$tmpdir/shtool.tmp" diff --git a/pkgs/core/noip/noip.nm b/pkgs/core/noip/noip.nm new file mode 100644 index 0000000..79da999 --- /dev/null +++ b/pkgs/core/noip/noip.nm @@ -0,0 +1,53 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = noip +PKG_VER = 2.1.7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Daemons +PKG_URL = http://www.no-ip.com +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = A dynamic DNS update client. + +define PKG_DESCRIPTION + Keep your current IP address in sync with your No-IP host or domain \ + with this Dynamic Update Client (DUC). The client continually checks \ + for IP address changes in the background and automatically updates \ + the DNS at No-IP whenever it changes. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) PREFIX=/usr CONFDIR=/etc +endef + +define STAGE_INSTALL + -mkdir -pv $(BUILDROOT)/usr/bin + cd $(DIR_APP) && cp noip2 $(BUILDROOT)/usr/bin/noip2 +endef diff --git a/pkgs/core/nss_ldap/nss_ldap.nm b/pkgs/core/nss_ldap/nss_ldap.nm new file mode 100644 index 0000000..0e1e895 --- /dev/null +++ b/pkgs/core/nss_ldap/nss_ldap.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = nss_ldap +PKG_VER = 262 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://www.padl.com/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = NSS library and PAM module for LDAP. + +PKG_DEPS += openldap + +define PKG_DESCRIPTION + This package includes two LDAP access clients: nss_ldap and \ + pam_ldap. Nss_ldap is a set of C library extensions that allow \ + X.500 and LDAP directory servers to be used as a primary source \ + of aliases, ethers, groups, hosts, networks, protocol, users, \ + RPCs, services, and shadow passwords. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc \ + --mandir=/usr/share/man \ + --with-ldap=openldap \ + --enable-schema-mapping + +define STAGE_INSTALL_CMDS + mv -vf $(BUILDROOT)/usr/lib/libnss_ldap.so.* $(BUILDROOT)/usr/lib/libnss_ldap.so +endef diff --git a/pkgs/core/ntp/ntp.conf b/pkgs/core/ntp/ntp.conf new file mode 100644 index 0000000..4b89e83 --- /dev/null +++ b/pkgs/core/ntp/ntp.conf @@ -0,0 +1,4 @@ +restrict default nomodify noquery +restrict 127.0.0.1 +server pool.ntp.org +driftfile /etc/ntp/drift diff --git a/pkgs/core/ntp/ntp.init b/pkgs/core/ntp/ntp.init new file mode 100644 index 0000000..7484749 --- /dev/null +++ b/pkgs/core/ntp/ntp.init @@ -0,0 +1,9 @@ +description "Start system time daemon" +author "IPFire Team" + +start on started network +stop on stopping network + +exec /usr/sbin/ntpd -4 -c /etc/ntp.conf +expect daemon +respawn diff --git a/pkgs/core/ntp/ntp.nm b/pkgs/core/ntp/ntp.nm new file mode 100644 index 0000000..f509353 --- /dev/null +++ b/pkgs/core/ntp/ntp.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = ntp +PKG_VER = 4.2.4p7 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Daemons +PKG_URL = http://www.ntp.org/ +PKG_LICENSE = MIT, BSD and GPLv2 +PKG_SUMMARY = The NTP daemon and utilities. + +PKG_DEPS += openssl readline + +define PKG_DESCRIPTION + The Network Time Protocol (NTP) is used to synchronize a computer's \ + time with another reference time source. This package includes ntpd \ + and utilities used to query and configure the ntpd daemon. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CFLAGS += -DMOD_NANO + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc \ + --mandir=/usr/share/man \ + --with-binsubdir=sbin + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/etc + cp -vf $(DIR_SOURCE)/ntp.conf $(BUILDROOT)/etc/ntp.conf +endef diff --git a/pkgs/core/openldap/openldap.init b/pkgs/core/openldap/openldap.init new file mode 100644 index 0000000..5e23e8f --- /dev/null +++ b/pkgs/core/openldap/openldap.init @@ -0,0 +1,9 @@ +description "Starts OpenLDAP slapd daemon" +author "IPFire Team" + +start on started mountfs +stop on starting shutdown + +exec /usr/sbin/slapd +expect fork +respawn diff --git a/pkgs/core/openldap/openldap.nm b/pkgs/core/openldap/openldap.nm new file mode 100644 index 0000000..67e7e35 --- /dev/null +++ b/pkgs/core/openldap/openldap.nm @@ -0,0 +1,90 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = openldap +PKG_VER = 2.4.21 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Daemons +PKG_URL = http://www.openldap.org/ +PKG_LICENSE = OpenLDAP +PKG_SUMMARY = LDAP support libraries. + +PKG_BUILD_DEPS+= libtool groff +PKG_DEPS += db cyrus-sasl openssl pth + +define PKG_DESCRIPTION + OpenLDAP is an open source suite of LDAP (Lightweight Directory Access \ + Protocol) applications and development tools. LDAP is a set of \ + protocols for accessing directory services over the Internet, similar \ + to the way DNS information is propagated over the Internet. The \ + openldap package contains configuration files, libraries, and \ + documentation for OpenLDAP. +endef + +PKG_TARBALL = $(THISAPP).tgz + +############################################################################### +# Installation Details +############################################################################### +CONFIGURE_OPTIONS += \ + --libexecdir=/usr/lib \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --with-threads=posix \ + --disable-debug \ + --disable-perl \ + --enable-dynamic \ + --enable-crypt \ + --enable-modules \ + --enable-rlookups \ + --enable-backends=mod \ + --enable-overlays=mod \ + --enable-sql=no \ + --enable-ndb=no \ + --disable-static + +# Doens't seem to work in chroot. +#define STAGE_TEST +# cd $(DIR_APP) && make check +#endef + +define STAGE_INSTALL_CMDS + mv -v $(BUILDROOT)/usr/lib/slapd $(BUILDROOT)/usr/sbin/slapd + rm -rvf $(BUILDROOT)/var/openldap-data + + for LINK in lber ldap ldap_r; do \ + chmod -v 0755 $(BUILDROOT)/usr/lib/$$(readlink $(BUILDROOT)/usr/lib/lib$${LINK}.so); \ + done + + # Install configuration + -mkdir -pv $(BUILDROOT)/etc/$(PKG_NAME) + cp -vf $(DIR_SOURCE)/slapd.conf $(BUILDROOT)/etc/$(PKG_NAME)/slapd.conf + + -mkdir -pv $(BUILDROOT)/var/lib/ldap + chmod 700 -Rv $(BUILDROOT)/var/lib/ldap +endef diff --git a/pkgs/core/openldap/patches/openldap-2.4.17-disable_sys_err.patch b/pkgs/core/openldap/patches/openldap-2.4.17-disable_sys_err.patch new file mode 100644 index 0000000..c1ab72d --- /dev/null +++ b/pkgs/core/openldap/patches/openldap-2.4.17-disable_sys_err.patch @@ -0,0 +1,17 @@ +diff -Naur openldap-2.4.16.org/include/ac/errno.h openldap-2.4.16/include/ac/errno.h +--- openldap-2.4.16.org/include/ac/errno.h 2009-01-22 01:00:52.000000000 +0100 ++++ openldap-2.4.16/include/ac/errno.h 2009-04-28 13:48:01.000000000 +0200 +@@ -36,12 +36,7 @@ + #undef _AC_ERRNO_UNKNOWN + #define _AC_ERRNO_UNKNOWN "unknown error" + +-#ifdef HAVE_SYS_ERRLIST +- /* this is thread safe */ +-# define STRERROR(e) ( (e) > -1 && (e) < sys_nerr \ +- ? sys_errlist[(e)] : _AC_ERRNO_UNKNOWN ) +- +-#elif defined( HAVE_STRERROR ) ++#if defined( HAVE_STRERROR ) + /* this may not be thread safe */ + /* and, yes, some implementations of strerror may return NULL */ + # define STRERROR(e) ( strerror(e) \ diff --git a/pkgs/core/openldap/slapd.conf b/pkgs/core/openldap/slapd.conf new file mode 100644 index 0000000..cfb95d0 --- /dev/null +++ b/pkgs/core/openldap/slapd.conf @@ -0,0 +1,59 @@ +# _ ___ _ +# (_) / __|_) +# _ ____ | |__ _ ____ ____ +# | | _ | __) |/ ___) _ ) +# | | | | | | | | | ( (/ / +# |_| ||_/|_| |_|_| ____) +# |_| +# +# OpenLDAP configuration +# +# www.ipfire.org - Licensed under the GPLv3 +# + +include /etc/openldap/schema/core.schema +include /etc/openldap/schema/cosine.schema +include /etc/openldap/schema/inetorgperson.schema +include /etc/openldap/schema/nis.schema + +pidfile /var/run/slapd.pid +argsfile /var/run/slapd.args + +loglevel 2048 + +####################################################################### +# Load modules +####################################################################### + +moduleload back_hdb.so + +####################################################################### +# ACL +####################################################################### + +access to attrs=userPassword,userPKCS12 + by self write + by * auth +access to attrs=shadowLastChange + by self write + by * read +access to * + by * read + +####################################################################### +# BDB database definitions +####################################################################### + +database hdb +suffix "dc=my-domain,dc=com" +rootdn "cn=Manager,dc=my-domain,dc=com" +rootpw secret + +directory /var/lib/ldap + +# Indices to maintain for this database +index objectClass eq,pres +index ou,cn,mail,surname,givenname eq,pres,sub +index uidNumber,gidNumber,loginShell eq,pres +index uid,memberUid eq,pres,sub +index nisMapName,nisMapEntry eq,pres,sub diff --git a/pkgs/core/openlldp/openlldp.init b/pkgs/core/openlldp/openlldp.init new file mode 100644 index 0000000..3e3114f --- /dev/null +++ b/pkgs/core/openlldp/openlldp.init @@ -0,0 +1,8 @@ +description "Starts the OpenLLDP Daemon" +author "IPFire Team" + +start on started network +stop on stopping network + +exec /usr/sbin/lldpd +respawn diff --git a/pkgs/core/openlldp/openlldp.nm b/pkgs/core/openlldp/openlldp.nm new file mode 100644 index 0000000..ff43180 --- /dev/null +++ b/pkgs/core/openlldp/openlldp.nm @@ -0,0 +1,42 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = openlldp +PKG_VER = 0.3alpha +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/Tools +PKG_URL = http://openlldp.sourceforge.net/ +PKG_LICENSE = GPL +PKG_SUMMARY = Utilities for the Link Layer Discovery Protocol. + +define PKG_DESCRIPTION + The OpenLLDP project aims to provide a comprehensive implementation of \ + the IEEE standard 802.1AB Link Layer Discovery Protocol. +endef + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/openssh/openssh.init b/pkgs/core/openssh/openssh.init new file mode 100644 index 0000000..9c1538c --- /dev/null +++ b/pkgs/core/openssh/openssh.init @@ -0,0 +1,15 @@ +description "OpenSSH Server" +author "IPFire Team" + +start on started network +stop on stopping network + +pre-start script + for algo in dsa rsa; do + [ -e "/etc/ssh/ssh_host_${algo}_key" ] && continue + /usr/bin/ssh-keygen -q -t ${algo} -N "" -f /etc/ssh/ssh_host_${algo}_key + done +end script + +exec /usr/sbin/sshd -D +respawn diff --git a/pkgs/core/openssh/openssh.nm b/pkgs/core/openssh/openssh.nm new file mode 100644 index 0000000..5505653 --- /dev/null +++ b/pkgs/core/openssh/openssh.nm @@ -0,0 +1,63 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = openssh +PKG_VER = 5.3p1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Application/Internet +PKG_URL = http://www.openssh.com/portable.html +PKG_LICENSE = MIT +PKG_SUMMARY = An open source implementation of SSH protocol versions 1 and 2. + +PKG_DEPS += openssl pam + +define PKG_DESCRIPTION + SH (Secure SHell) is a program for logging into and executing \ + commands on a remote machine. SSH is intended to replace rlogin and \ + rsh, and to provide secure encrypted communications between two \ + untrusted hosts over an insecure network. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc/ssh \ + --datadir=/usr/share/sshd \ + --libexecdir=/usr/lib/openssh \ + --with-md5-passwords \ + --with-privsep-path=/var/lib/sshd \ + --with-pam + +define STAGE_INSTALL_CMDS + -mkdir -pv $(BUILDROOT)/etc/ssh + cp -vf $(DIR_SOURCE)/sshd_config $(BUILDROOT)/etc/ssh/sshd_config +endef diff --git a/pkgs/core/openssh/sshd.pam b/pkgs/core/openssh/sshd.pam new file mode 100644 index 0000000..ba632dd --- /dev/null +++ b/pkgs/core/openssh/sshd.pam @@ -0,0 +1,9 @@ +#%PAM-1.0 +auth include system-auth + +account required pam_nologin.so +account include system-auth + +password include system-auth + +session include system-auth diff --git a/pkgs/core/openssh/sshd_config b/pkgs/core/openssh/sshd_config new file mode 100644 index 0000000..a44be8c --- /dev/null +++ b/pkgs/core/openssh/sshd_config @@ -0,0 +1,117 @@ +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options change a +# default value. + +Port 222 +#AddressFamily any +#ListenAddress 0.0.0.0 +#ListenAddress :: + +# Disable legacy (protocol version 1) support in the server for new +# installations. In future the default will change to require explicit +# activation of protocol 1 +Protocol 2 + +# HostKey for protocol version 1 +#HostKey /etc/ssh/ssh_host_key +# HostKeys for protocol version 2 +#HostKey /etc/ssh/ssh_host_rsa_key +#HostKey /etc/ssh/ssh_host_dsa_key + +# Lifetime and size of ephemeral version 1 server key +#KeyRegenerationInterval 1h +#ServerKeyBits 1024 + +# Logging +# obsoletes QuietMode and FascistLogging +#SyslogFacility AUTH +#LogLevel INFO + +# Authentication: + +LoginGraceTime 30s +#PermitRootLogin yes +#StrictModes yes +#MaxAuthTries 6 +#MaxSessions 10 + +RSAAuthentication yes +PubkeyAuthentication yes +#AuthorizedKeysFile .ssh/authorized_keys + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +#RhostsRSAAuthentication no +# similar for protocol version 2 +#HostbasedAuthentication no +# Change to yes if you don't trust ~/.ssh/known_hosts for +# RhostsRSAAuthentication and HostbasedAuthentication +IgnoreUserKnownHosts yes +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes + +# To disable tunneled clear text passwords, change to no here! +PasswordAuthentication yes +#PermitEmptyPasswords no + +# Change to no to disable s/key passwords +ChallengeResponseAuthentication yes + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM yes + +#AllowAgentForwarding yes +AllowTcpForwarding yes +#GatewayPorts no +X11Forwarding no +#X11DisplayOffset 10 +#X11UseLocalhost yes +#PrintMotd yes +#PrintLastLog yes +#TCPKeepAlive yes +#UseLogin no +#UsePrivilegeSeparation yes +#PermitUserEnvironment no +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS yes +#PidFile /var/run/sshd.pid +MaxStartups 5 +#PermitTunnel no +#ChrootDirectory none + +# no default banner path +#Banner none + +# override default of no subsystems +Subsystem sftp /usr/lib/openssh/sftp-server + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# ForceCommand cvs server diff --git a/pkgs/core/openssl/openssl.cnf b/pkgs/core/openssl/openssl.cnf new file mode 100644 index 0000000..4194765 --- /dev/null +++ b/pkgs/core/openssl/openssl.cnf @@ -0,0 +1,94 @@ +HOME = . +RANDFILE = /var/tmp/.rnd +oid_section = new_oids + +[ new_oids ] + +[ ca ] +default_ca = IPFire + +[ IPFire ] +dir = /var/ipfire +certs = $dir/certs +crl_dir = $dir/crls +database = $dir/certs/index.txt +new_certs_dir = $dir/certs +certificate = $dir/ca/cacert.pem +serial = $dir/certs/serial +crl = $dir/crls/cacrl.pem +private_key = $dir/private/cakey.pem +RANDFILE = $dir/tmp/.rand +x509_extensions = usr_cert +default_days = 999999 +default_crl_days= 30 +default_md = md5 +preserve = no +policy = policy_match +email_in_dn = no + +[ policy_match ] +countryName = optional +stateOrProvinceName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +default_bits = 1024 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca +string_mask = nombstr + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = DE +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = + +localityName = Locality Name (eg, city) +#localityName_default = + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = IPFire + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (eg, your name or your server's hostname) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 40 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 +unstructuredName = An optional company name + +[ usr_cert ] +basicConstraints=CA:FALSE +nsComment = "OpenSSL Generated Certificate" +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always +basicConstraints = CA:true + +[ crl_ext ] +authorityKeyIdentifier=keyid:always,issuer:always + +[ engine ] +default = openssl diff --git a/pkgs/core/openssl/openssl.nm b/pkgs/core/openssl/openssl.nm new file mode 100644 index 0000000..95c1e3c --- /dev/null +++ b/pkgs/core/openssl/openssl.nm @@ -0,0 +1,122 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = openssl +PKG_VER = 0.9.8k +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.openssl.org/ +PKG_LICENSE = OpenSSL +PKG_SUMMARY = A general purpose cryptography library with TLS implementation. + +PKG_BUILD_DEPS+= bc perl +PKG_DEPS += gnutls zlib + +define PKG_DESCRIPTION + The OpenSSL toolkit provides support for secure communications between \ + machines. OpenSSL includes a certificate management tool and shared \ + libraries which provide various cryptographic algorithms and protocols. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +ifneq "$(MACHINE)" "i686" + SSL_ARCH = no-asm 386 # 386 implies no-sse2 +endif + +# These arches do support sse2. +#ifneq "$(TARGET)" "via-c7" +#ifneq "$(TARGET)" "atom" +#ifneq "$(TARGET)" "core2duo" +# SSL_ARCH += no-sse2 +#endif +#endif +#endif + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -e 's/-O3 -fomit-frame-pointer/$(CFLAGS)/' -i Configure + + cd $(DIR_APP) && sed -e 's/__OpenBSD__/__linux__/' -e 's/arandom/urandom/' \ + -i crypto/rand/randfile.c + + cd $(DIR_APP) && sed -e 's/__OpenBSD__/__linux__/' -i crypto/rand/rand_unix.c + + cd $(DIR_APP) && find crypto/ -name Makefile -exec \ + sed 's/^ASFLAGS=/&-Wa,--noexecstack /' -i {} ; +endef + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./Configure \ + --prefix=/usr \ + --openssldir=/etc/pki/tls \ + --enginesdir=/usr/lib/openssl/engines \ + linux-elf $(SSL_ARCH) \ + shared \ + zlib-dynamic \ + enable-camellia \ + enable-seed \ + enable-tlsext \ + enable-rfc3779 \ + no-idea \ + no-mdc2 \ + no-rc5 \ + no-ec \ + no-ecdh \ + no-ecdsa \ + -DSSL_FORBID_ENULL + + # Build. + cd $(DIR_APP) && make all build-shared #$(PARALLELISMFLAGS) + + # Generate hashes for the included certs. + cd $(DIR_APP) && make rehash build-shared +endef + +define STAGE_TEST + cd $(DIR_APP) && make test +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install build-shared INSTALL_PREFIX=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/usr/lib/openssl + mv -v $(BUILDROOT)/usr/lib/engines $(BUILDROOT)/usr/lib/openssl + + -mkdir -pv $(BUILDROOT)/etc/pki/CA/private + chmod -v 700 -R $(BUILDROOT)/etc/pki/CA + + -mkdir -pv $(BUILDROOT)/etc/pki/tls + install -m 0644 $(DIR_SOURCE)/openssl.cnf $(BUILDROOT)/etc/pki/tls + cd $(DIR_APP) && cp -v -r certs $(BUILDROOT)/etc/pki/tls +endef + diff --git a/pkgs/core/openssl/patches/openssl-0.9.8k-enginesdir.patch b/pkgs/core/openssl/patches/openssl-0.9.8k-enginesdir.patch new file mode 100644 index 0000000..0c33b74 --- /dev/null +++ b/pkgs/core/openssl/patches/openssl-0.9.8k-enginesdir.patch @@ -0,0 +1,39 @@ +--- openssl-0.9.8a/Configure.enginesdir 2005-11-04 15:06:37.000000000 +0100 ++++ openssl-0.9.8a/Configure 2005-11-07 14:15:12.000000000 +0100 +@@ -560,6 +560,7 @@ + + my $prefix=""; + my $openssldir=""; ++my $enginesdir=""; + my $exe_ext=""; + my $install_prefix=""; + my $no_threads=0; +@@ -739,6 +740,10 @@ + { + $openssldir=$1; + } ++ elsif (/^--enginesdir=(.*)$/) ++ { ++ $enginesdir=$1; ++ } + elsif (/^--install.prefix=(.*)$/) + { + $install_prefix=$1; +@@ -923,7 +928,7 @@ + + $openssldir=$prefix . "/ssl" if $openssldir eq ""; + $openssldir=$prefix . "/" . $openssldir if $openssldir !~ /(^/|^[a-zA-Z]:[\/])/; +- ++$enginesdir="$prefix/lib/engines" if $enginesdir eq ""; + + print "IsMK1MF=$IsMK1MF\n"; + +@@ -1430,7 +1435,7 @@ + if (/^#define\s+OPENSSLDIR/) + { print OUT "#define OPENSSLDIR "$openssldir"\n"; } + elsif (/^#define\s+ENGINESDIR/) +- { print OUT "#define ENGINESDIR "$prefix/lib/engines"\n"; } ++ { print OUT "#define ENGINESDIR "$enginesdir"\n"; } + elsif (/^#((define)|(undef))\s+OPENSSL_EXPORT_VAR_AS_FUNCTION/) + { printf OUT "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION\n" + if $export_var_as_fn; diff --git a/pkgs/core/openssl/patches/openssl-0.9.8k-fix_manpages-1.patch b/pkgs/core/openssl/patches/openssl-0.9.8k-fix_manpages-1.patch new file mode 100644 index 0000000..69189c9 --- /dev/null +++ b/pkgs/core/openssl/patches/openssl-0.9.8k-fix_manpages-1.patch @@ -0,0 +1,1888 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> +Date: 2005-11-13 +Initial Package Version: 0.9.8a +Upstream Status: Submitted upstream +Origin: Anderson Lizardo +Description: This patch fixes conflicts between man pages + installed by OpenSSL and those found on other + packages (particulary Shadow, Perl, and + Man-pages). It also fixes syntax errors on some + POD files that generates slightly broken man + pages. + +$LastChangedBy: igor $ +$Date: 2005-04-03 16:54:23 -0600 (Sun, 03 Apr 2005) $ + +diff -Naur openssl-0.9.8a.orig/FAQ openssl-0.9.8a/FAQ +--- openssl-0.9.8a.orig/FAQ 2005-10-11 10:16:06.000000000 +0000 ++++ openssl-0.9.8a/FAQ 2005-11-14 03:59:59.000000000 +0000 +@@ -680,7 +680,7 @@ + + Multi-threaded applications must provide two callback functions to + OpenSSL by calling CRYPTO_set_locking_callback() and +-CRYPTO_set_id_callback(). This is described in the threads(3) ++CRYPTO_set_id_callback(). This is described in the openssl_threads(3) + manpage. + + * I've compiled a program under Windows and it crashes: why? +diff -Naur openssl-0.9.8a.orig/crypto/rand/md_rand.c openssl-0.9.8a/crypto/rand/md_rand.c +--- openssl-0.9.8a.orig/crypto/rand/md_rand.c 2005-04-07 22:53:35.000000000 +0000 ++++ openssl-0.9.8a/crypto/rand/md_rand.c 2005-11-14 03:59:59.000000000 +0000 +@@ -196,7 +196,7 @@ + int do_not_lock; + + /* +- * (Based on the rand(3) manpage) ++ * (Based on the openssl_rand(3) manpage) + * + * The input is chopped up into units of 20 bytes (or less for + * the last block). Each of these blocks is run through the hash +@@ -351,7 +351,7 @@ + num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2); + + /* +- * (Based on the rand(3) manpage:) ++ * (Based on the openssl_rand(3) manpage) + * + * For each group of 10 bytes (or less), we do the following: + * +diff -Naur openssl-0.9.8a.orig/doc/apps/openssl-passwd.pod openssl-0.9.8a/doc/apps/openssl-passwd.pod +--- openssl-0.9.8a.orig/doc/apps/openssl-passwd.pod 1970-01-01 00:00:00.000000000 +0000 ++++ openssl-0.9.8a/doc/apps/openssl-passwd.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -0,0 +1,82 @@ ++=pod ++ ++=head1 NAME ++ ++openssl-passwd - compute password hashes ++ ++=head1 SYNOPSIS ++ ++B<openssl passwd> ++[B<-crypt>] ++[B<-1>] ++[B<-apr1>] ++[B<-salt> I<string>] ++[B<-in> I<file>] ++[B<-stdin>] ++[B<-noverify>] ++[B<-quiet>] ++[B<-table>] ++{I<password>} ++ ++=head1 DESCRIPTION ++ ++The B<passwd> command computes the hash of a password typed at ++run-time or the hash of each password in a list. The password list is ++taken from the named file for option B<-in file>, from stdin for ++option B<-stdin>, or from the command line, or from the terminal otherwise. ++The Unix standard algorithm B<crypt> and the MD5-based BSD password ++algorithm B<1> and its Apache variant B<apr1> are available. ++ ++=head1 OPTIONS ++ ++=over 4 ++ ++=item B<-crypt> ++ ++Use the B<crypt> algorithm (default). ++ ++=item B<-1> ++ ++Use the MD5 based BSD password algorithm B<1>. ++ ++=item B<-apr1> ++ ++Use the B<apr1> algorithm (Apache variant of the BSD algorithm). ++ ++=item B<-salt> I<string> ++ ++Use the specified salt. ++When reading a password from the terminal, this implies B<-noverify>. ++ ++=item B<-in> I<file> ++ ++Read passwords from I<file>. ++ ++=item B<-stdin> ++ ++Read passwords from B<stdin>. ++ ++=item B<-noverify> ++ ++Don't verify when reading a password from the terminal. ++ ++=item B<-quiet> ++ ++Don't output warnings when passwords given at the command line are truncated. ++ ++=item B<-table> ++ ++In the output list, prepend the cleartext password and a TAB character ++to each password hash. ++ ++=back ++ ++=head1 EXAMPLES ++ ++B<openssl passwd -crypt -salt xx password> prints B<xxj31ZMTZzkVA>. ++ ++B<openssl passwd -1 -salt xxxxxxxx password> prints B<$1$xxxxxxxx$UYCIxa628.9qXjpQCjM4a.>. ++ ++B<openssl passwd -apr1 -salt xxxxxxxx password> prints B<$apr1$xxxxxxxx$dxHfLAsjHkDRmG83UXe8K0>. ++ ++=cut +diff -Naur openssl-0.9.8a.orig/doc/apps/openssl.pod openssl-0.9.8a/doc/apps/openssl.pod +--- openssl-0.9.8a.orig/doc/apps/openssl.pod 2004-01-04 18:59:14.000000000 +0000 ++++ openssl-0.9.8a/doc/apps/openssl.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -125,7 +125,7 @@ + + Online Certificate Status Protocol utility. + +-=item L<B<passwd>|passwd(1)> ++=item L<B<passwd>|openssl-passwd(1)> + + Generation of hashed passwords. + +@@ -325,7 +325,7 @@ + L<dhparam(1)|dhparam(1)>, L<dsa(1)|dsa(1)>, L<dsaparam(1)|dsaparam(1)>, + L<enc(1)|enc(1)>, L<gendsa(1)|gendsa(1)>, + L<genrsa(1)|genrsa(1)>, L<nseq(1)|nseq(1)>, L<openssl(1)|openssl(1)>, +-L<passwd(1)|passwd(1)>, ++L<openssl-passwd(1)|openssl-passwd(1)>, + L<pkcs12(1)|pkcs12(1)>, L<pkcs7(1)|pkcs7(1)>, L<pkcs8(1)|pkcs8(1)>, + L<rand(1)|rand(1)>, L<req(1)|req(1)>, L<rsa(1)|rsa(1)>, + L<rsautl(1)|rsautl(1)>, L<s_client(1)|s_client(1)>, +diff -Naur openssl-0.9.8a.orig/doc/apps/passwd.pod openssl-0.9.8a/doc/apps/passwd.pod +--- openssl-0.9.8a.orig/doc/apps/passwd.pod 2002-10-04 12:59:00.000000000 +0000 ++++ openssl-0.9.8a/doc/apps/passwd.pod 1970-01-01 00:00:00.000000000 +0000 +@@ -1,82 +0,0 @@ +-=pod +- +-=head1 NAME +- +-passwd - compute password hashes +- +-=head1 SYNOPSIS +- +-B<openssl passwd> +-[B<-crypt>] +-[B<-1>] +-[B<-apr1>] +-[B<-salt> I<string>] +-[B<-in> I<file>] +-[B<-stdin>] +-[B<-noverify>] +-[B<-quiet>] +-[B<-table>] +-{I<password>} +- +-=head1 DESCRIPTION +- +-The B<passwd> command computes the hash of a password typed at +-run-time or the hash of each password in a list. The password list is +-taken from the named file for option B<-in file>, from stdin for +-option B<-stdin>, or from the command line, or from the terminal otherwise. +-The Unix standard algorithm B<crypt> and the MD5-based BSD password +-algorithm B<1> and its Apache variant B<apr1> are available. +- +-=head1 OPTIONS +- +-=over 4 +- +-=item B<-crypt> +- +-Use the B<crypt> algorithm (default). +- +-=item B<-1> +- +-Use the MD5 based BSD password algorithm B<1>. +- +-=item B<-apr1> +- +-Use the B<apr1> algorithm (Apache variant of the BSD algorithm). +- +-=item B<-salt> I<string> +- +-Use the specified salt. +-When reading a password from the terminal, this implies B<-noverify>. +- +-=item B<-in> I<file> +- +-Read passwords from I<file>. +- +-=item B<-stdin> +- +-Read passwords from B<stdin>. +- +-=item B<-noverify> +- +-Don't verify when reading a password from the terminal. +- +-=item B<-quiet> +- +-Don't output warnings when passwords given at the command line are truncated. +- +-=item B<-table> +- +-In the output list, prepend the cleartext password and a TAB character +-to each password hash. +- +-=back +- +-=head1 EXAMPLES +- +-B<openssl passwd -crypt -salt xx password> prints B<xxj31ZMTZzkVA>. +- +-B<openssl passwd -1 -salt xxxxxxxx password> prints B<$1$xxxxxxxx$UYCIxa628.9qXjpQCjM4a.>. +- +-B<openssl passwd -apr1 -salt xxxxxxxx password> prints B<$apr1$xxxxxxxx$dxHfLAsjHkDRmG83UXe8K0>. +- +-=cut +diff -Naur openssl-0.9.8a.orig/doc/crypto/BN_generate_prime.pod openssl-0.9.8a/doc/crypto/BN_generate_prime.pod +--- openssl-0.9.8a.orig/doc/crypto/BN_generate_prime.pod 2003-01-13 13:18:22.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/BN_generate_prime.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -90,7 +90,7 @@ + + =head1 SEE ALSO + +-L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)> ++L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/BN_rand.pod openssl-0.9.8a/doc/crypto/BN_rand.pod +--- openssl-0.9.8a.orig/doc/crypto/BN_rand.pod 2002-09-25 13:33:26.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/BN_rand.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -45,7 +45,7 @@ + + =head1 SEE ALSO + +-L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, ++L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<RAND_add(3)|RAND_add(3)>, L<RAND_bytes(3)|RAND_bytes(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/CONF_modules_free.pod openssl-0.9.8a/doc/crypto/CONF_modules_free.pod +--- openssl-0.9.8a.orig/doc/crypto/CONF_modules_free.pod 2004-03-02 13:31:32.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/CONF_modules_free.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -37,7 +37,7 @@ + =head1 SEE ALSO + + L<conf(5)|conf(5)>, L<OPENSSL_config(3)|OPENSSL_config(3)>, +-L<CONF_modules_load_file(3), CONF_modules_load_file(3)> ++L<CONF_modules_load_file(3)|CONF_modules_load_file(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/CONF_modules_load_file.pod openssl-0.9.8a/doc/crypto/CONF_modules_load_file.pod +--- openssl-0.9.8a.orig/doc/crypto/CONF_modules_load_file.pod 2004-03-02 13:31:32.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/CONF_modules_load_file.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -51,7 +51,7 @@ + =head1 SEE ALSO + + L<conf(5)|conf(5)>, L<OPENSSL_config(3)|OPENSSL_config(3)>, +-L<CONF_free(3), CONF_free(3)>, L<err(3),err(3)> ++L<CONF_free(3)|CONF_free(3)>, L<openssl_err(3)|openssl_err(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/DH_generate_key.pod openssl-0.9.8a/doc/crypto/DH_generate_key.pod +--- openssl-0.9.8a.orig/doc/crypto/DH_generate_key.pod 2002-09-25 13:33:27.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/DH_generate_key.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -40,7 +40,7 @@ + + =head1 SEE ALSO + +-L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, L<DH_size(3)|DH_size(3)> ++L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)>, L<DH_size(3)|DH_size(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/DH_generate_parameters.pod openssl-0.9.8a/doc/crypto/DH_generate_parameters.pod +--- openssl-0.9.8a.orig/doc/crypto/DH_generate_parameters.pod 2002-09-25 13:33:27.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/DH_generate_parameters.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -59,7 +59,7 @@ + + =head1 SEE ALSO + +-L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, ++L<dh(3)|dh(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<DH_free(3)|DH_free(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/DSA_do_sign.pod openssl-0.9.8a/doc/crypto/DSA_do_sign.pod +--- openssl-0.9.8a.orig/doc/crypto/DSA_do_sign.pod 2002-09-25 13:33:27.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/DSA_do_sign.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -36,7 +36,7 @@ + + =head1 SEE ALSO + +-L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, ++L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<DSA_SIG_new(3)|DSA_SIG_new(3)>, + L<DSA_sign(3)|DSA_sign(3)> + +diff -Naur openssl-0.9.8a.orig/doc/crypto/DSA_generate_key.pod openssl-0.9.8a/doc/crypto/DSA_generate_key.pod +--- openssl-0.9.8a.orig/doc/crypto/DSA_generate_key.pod 2002-09-25 13:33:27.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/DSA_generate_key.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -24,7 +24,7 @@ + + =head1 SEE ALSO + +-L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, ++L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<DSA_generate_parameters(3)|DSA_generate_parameters(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/DSA_generate_parameters.pod openssl-0.9.8a/doc/crypto/DSA_generate_parameters.pod +--- openssl-0.9.8a.orig/doc/crypto/DSA_generate_parameters.pod 2002-09-25 13:33:27.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/DSA_generate_parameters.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -90,7 +90,7 @@ + + =head1 SEE ALSO + +-L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, ++L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<DSA_free(3)|DSA_free(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/DSA_sign.pod openssl-0.9.8a/doc/crypto/DSA_sign.pod +--- openssl-0.9.8a.orig/doc/crypto/DSA_sign.pod 2002-09-25 13:33:27.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/DSA_sign.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -55,7 +55,7 @@ + + =head1 SEE ALSO + +-L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, ++L<dsa(3)|dsa(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<DSA_do_sign(3)|DSA_do_sign(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/ERR_GET_LIB.pod openssl-0.9.8a/doc/crypto/ERR_GET_LIB.pod +--- openssl-0.9.8a.orig/doc/crypto/ERR_GET_LIB.pod 2000-02-01 01:36:58.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/ERR_GET_LIB.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -41,7 +41,7 @@ + + =head1 SEE ALSO + +-L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)> ++L<openssl_err(3)|openssl_err(3)>, L<ERR_get_error(3)|ERR_get_error(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/ERR_clear_error.pod openssl-0.9.8a/doc/crypto/ERR_clear_error.pod +--- openssl-0.9.8a.orig/doc/crypto/ERR_clear_error.pod 2000-02-01 01:36:58.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/ERR_clear_error.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -20,7 +20,7 @@ + + =head1 SEE ALSO + +-L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)> ++L<openssl_err(3)|openssl_err(3)>, L<ERR_get_error(3)|ERR_get_error(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/ERR_error_string.pod openssl-0.9.8a/doc/crypto/ERR_error_string.pod +--- openssl-0.9.8a.orig/doc/crypto/ERR_error_string.pod 2004-11-14 15:11:37.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/ERR_error_string.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -60,7 +60,7 @@ + + =head1 SEE ALSO + +-L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, ++L<openssl_err(3)|openssl_err(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, + L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>, + L<SSL_load_error_strings(3)|SSL_load_error_strings(3)> + L<ERR_print_errors(3)|ERR_print_errors(3)> +diff -Naur openssl-0.9.8a.orig/doc/crypto/ERR_get_error.pod openssl-0.9.8a/doc/crypto/ERR_get_error.pod +--- openssl-0.9.8a.orig/doc/crypto/ERR_get_error.pod 2002-11-29 14:21:54.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/ERR_get_error.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -61,7 +61,7 @@ + + =head1 SEE ALSO + +-L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>, ++L<openssl_err(3)|openssl_err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>, + L<ERR_GET_LIB(3)|ERR_GET_LIB(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/ERR_load_crypto_strings.pod openssl-0.9.8a/doc/crypto/ERR_load_crypto_strings.pod +--- openssl-0.9.8a.orig/doc/crypto/ERR_load_crypto_strings.pod 2000-02-24 11:55:08.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/ERR_load_crypto_strings.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -35,7 +35,7 @@ + + =head1 SEE ALSO + +-L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)> ++L<openssl_err(3)|openssl_err(3)>, L<ERR_error_string(3)|ERR_error_string(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/ERR_load_strings.pod openssl-0.9.8a/doc/crypto/ERR_load_strings.pod +--- openssl-0.9.8a.orig/doc/crypto/ERR_load_strings.pod 2000-02-24 11:55:08.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/ERR_load_strings.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -43,7 +43,7 @@ + + =head1 SEE ALSO + +-L<err(3)|err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)> ++L<openssl_err(3)|openssl_err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/ERR_print_errors.pod openssl-0.9.8a/doc/crypto/ERR_print_errors.pod +--- openssl-0.9.8a.orig/doc/crypto/ERR_print_errors.pod 2000-02-01 01:36:59.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/ERR_print_errors.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -38,7 +38,7 @@ + + =head1 SEE ALSO + +-L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>, ++L<openssl_err(3)|openssl_err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>, + L<ERR_get_error(3)|ERR_get_error(3)>, + L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>, + L<SSL_load_error_strings(3)|SSL_load_error_strings(3)> +diff -Naur openssl-0.9.8a.orig/doc/crypto/ERR_put_error.pod openssl-0.9.8a/doc/crypto/ERR_put_error.pod +--- openssl-0.9.8a.orig/doc/crypto/ERR_put_error.pod 2000-02-24 11:55:08.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/ERR_put_error.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -34,7 +34,7 @@ + + =head1 SEE ALSO + +-L<err(3)|err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)> ++L<openssl_err(3)|openssl_err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/ERR_remove_state.pod openssl-0.9.8a/doc/crypto/ERR_remove_state.pod +--- openssl-0.9.8a.orig/doc/crypto/ERR_remove_state.pod 2000-05-19 07:54:42.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/ERR_remove_state.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -25,7 +25,7 @@ + + =head1 SEE ALSO + +-L<err(3)|err(3)> ++L<openssl_err(3)|openssl_err(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/EVP_BytesToKey.pod openssl-0.9.8a/doc/crypto/EVP_BytesToKey.pod +--- openssl-0.9.8a.orig/doc/crypto/EVP_BytesToKey.pod 2004-11-25 17:47:30.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/EVP_BytesToKey.pod 2005-11-14 04:00:45.000000000 +0000 +@@ -59,7 +59,7 @@ + + =head1 SEE ALSO + +-L<evp(3)|evp(3)>, L<rand(3)|rand(3)>, ++L<evp(3)|evp(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/EVP_OpenInit.pod openssl-0.9.8a/doc/crypto/EVP_OpenInit.pod +--- openssl-0.9.8a.orig/doc/crypto/EVP_OpenInit.pod 2000-09-23 07:16:14.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/EVP_OpenInit.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -54,7 +54,7 @@ + + =head1 SEE ALSO + +-L<evp(3)|evp(3)>, L<rand(3)|rand(3)>, ++L<evp(3)|evp(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>, + L<EVP_SealInit(3)|EVP_SealInit(3)> + +diff -Naur openssl-0.9.8a.orig/doc/crypto/EVP_SealInit.pod openssl-0.9.8a/doc/crypto/EVP_SealInit.pod +--- openssl-0.9.8a.orig/doc/crypto/EVP_SealInit.pod 2005-03-29 17:50:08.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/EVP_SealInit.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -74,7 +74,7 @@ + + =head1 SEE ALSO + +-L<evp(3)|evp(3)>, L<rand(3)|rand(3)>, ++L<evp(3)|evp(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>, + L<EVP_OpenInit(3)|EVP_OpenInit(3)> + +diff -Naur openssl-0.9.8a.orig/doc/crypto/EVP_SignInit.pod openssl-0.9.8a/doc/crypto/EVP_SignInit.pod +--- openssl-0.9.8a.orig/doc/crypto/EVP_SignInit.pod 2005-03-22 17:55:33.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/EVP_SignInit.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -80,7 +80,7 @@ + =head1 SEE ALSO + + L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>, +-L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>, ++L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<openssl_err(3)|openssl_err(3)>, + L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, + L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>, + L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)> +diff -Naur openssl-0.9.8a.orig/doc/crypto/EVP_VerifyInit.pod openssl-0.9.8a/doc/crypto/EVP_VerifyInit.pod +--- openssl-0.9.8a.orig/doc/crypto/EVP_VerifyInit.pod 2002-07-10 19:35:46.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/EVP_VerifyInit.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -71,7 +71,7 @@ + + L<evp(3)|evp(3)>, + L<EVP_SignInit(3)|EVP_SignInit(3)>, +-L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>, ++L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<openssl_err(3)|openssl_err(3)>, + L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, + L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>, + L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)> +diff -Naur openssl-0.9.8a.orig/doc/crypto/OPENSSL_config.pod openssl-0.9.8a/doc/crypto/OPENSSL_config.pod +--- openssl-0.9.8a.orig/doc/crypto/OPENSSL_config.pod 2005-06-02 23:17:38.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/OPENSSL_config.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -73,7 +73,7 @@ + =head1 SEE ALSO + + L<conf(5)|conf(5)>, L<CONF_load_modules_file(3)|CONF_load_modules_file(3)>, +-L<CONF_modules_free(3),CONF_modules_free(3)> ++L<CONF_modules_free(3)|CONF_modules_free(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/RAND_add.pod openssl-0.9.8a/doc/crypto/RAND_add.pod +--- openssl-0.9.8a.orig/doc/crypto/RAND_add.pod 2000-03-22 15:30:03.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RAND_add.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -65,7 +65,7 @@ + + =head1 SEE ALSO + +-L<rand(3)|rand(3)>, L<RAND_egd(3)|RAND_egd(3)>, ++L<openssl_rand(3)|openssl_rand(3)>, L<RAND_egd(3)|RAND_egd(3)>, + L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/RAND_bytes.pod openssl-0.9.8a/doc/crypto/RAND_bytes.pod +--- openssl-0.9.8a.orig/doc/crypto/RAND_bytes.pod 2002-09-25 13:33:27.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RAND_bytes.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -35,7 +35,7 @@ + + =head1 SEE ALSO + +-L<rand(3)|rand(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, ++L<openssl_rand(3)|openssl_rand(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, + L<RAND_add(3)|RAND_add(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/RAND_cleanup.pod openssl-0.9.8a/doc/crypto/RAND_cleanup.pod +--- openssl-0.9.8a.orig/doc/crypto/RAND_cleanup.pod 2000-01-27 01:25:06.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RAND_cleanup.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -20,7 +20,7 @@ + + =head1 SEE ALSO + +-L<rand(3)|rand(3)> ++L<openssl_rand(3)|openssl_rand(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/RAND_egd.pod openssl-0.9.8a/doc/crypto/RAND_egd.pod +--- openssl-0.9.8a.orig/doc/crypto/RAND_egd.pod 2001-02-10 19:10:36.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RAND_egd.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -69,7 +69,7 @@ + + =head1 SEE ALSO + +-L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>, ++L<openssl_rand(3)|openssl_rand(3)>, L<RAND_add(3)|RAND_add(3)>, + L<RAND_cleanup(3)|RAND_cleanup(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/RAND_load_file.pod openssl-0.9.8a/doc/crypto/RAND_load_file.pod +--- openssl-0.9.8a.orig/doc/crypto/RAND_load_file.pod 2001-03-21 15:25:56.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RAND_load_file.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -43,7 +43,7 @@ + + =head1 SEE ALSO + +-L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)> ++L<openssl_rand(3)|openssl_rand(3)>, L<RAND_add(3)|RAND_add(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/RAND_set_rand_method.pod openssl-0.9.8a/doc/crypto/RAND_set_rand_method.pod +--- openssl-0.9.8a.orig/doc/crypto/RAND_set_rand_method.pod 2002-08-05 16:27:01.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RAND_set_rand_method.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -67,7 +67,7 @@ + + =head1 SEE ALSO + +-L<rand(3)|rand(3)>, L<engine(3)|engine(3)> ++L<openssl_rand(3)|openssl_rand(3)>, L<engine(3)|engine(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/RSA_blinding_on.pod openssl-0.9.8a/doc/crypto/RSA_blinding_on.pod +--- openssl-0.9.8a.orig/doc/crypto/RSA_blinding_on.pod 2000-02-24 11:55:10.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RSA_blinding_on.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -34,7 +34,7 @@ + + =head1 SEE ALSO + +-L<rsa(3)|rsa(3)>, L<rand(3)|rand(3)> ++L<rsa(3)|rsa(3)>, L<openssl_rand(3)|openssl_rand(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/RSA_generate_key.pod openssl-0.9.8a/doc/crypto/RSA_generate_key.pod +--- openssl-0.9.8a.orig/doc/crypto/RSA_generate_key.pod 2002-09-25 13:33:27.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RSA_generate_key.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -59,7 +59,7 @@ + + =head1 SEE ALSO + +-L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, ++L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)>, L<rsa(3)|rsa(3)>, + L<RSA_free(3)|RSA_free(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/RSA_public_encrypt.pod openssl-0.9.8a/doc/crypto/RSA_public_encrypt.pod +--- openssl-0.9.8a.orig/doc/crypto/RSA_public_encrypt.pod 2004-03-23 21:01:34.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RSA_public_encrypt.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -73,7 +73,7 @@ + + =head1 SEE ALSO + +-L<ERR_get_error(3)|ERR_get_error(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, ++L<ERR_get_error(3)|ERR_get_error(3)>, L<openssl_rand(3)|openssl_rand(3)>, L<rsa(3)|rsa(3)>, + L<RSA_size(3)|RSA_size(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod openssl-0.9.8a/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod +--- openssl-0.9.8a.orig/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod 2002-09-25 13:33:28.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/RSA_sign_ASN1_OCTET_STRING.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -48,7 +48,7 @@ + =head1 SEE ALSO + + L<ERR_get_error(3)|ERR_get_error(3)>, L<objects(3)|objects(3)>, +-L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, L<RSA_sign(3)|RSA_sign(3)>, ++L<openssl_rand(3)|openssl_rand(3)>, L<rsa(3)|rsa(3)>, L<RSA_sign(3)|RSA_sign(3)>, + L<RSA_verify(3)|RSA_verify(3)> + + =head1 HISTORY +diff -Naur openssl-0.9.8a.orig/doc/crypto/X509_NAME_ENTRY_get_object.pod openssl-0.9.8a/doc/crypto/X509_NAME_ENTRY_get_object.pod +--- openssl-0.9.8a.orig/doc/crypto/X509_NAME_ENTRY_get_object.pod 2005-03-30 11:50:14.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/X509_NAME_ENTRY_get_object.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -63,7 +63,7 @@ + =head1 SEE ALSO + + L<ERR_get_error(3)|ERR_get_error(3)>, L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>, +-L<OBJ_nid2obj(3),OBJ_nid2obj(3)> ++L<OBJ_nid2obj(3)|OBJ_nid2obj(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/bn.pod openssl-0.9.8a/doc/crypto/bn.pod +--- openssl-0.9.8a.orig/doc/crypto/bn.pod 2005-04-29 15:07:34.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/bn.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -167,7 +167,7 @@ + =head1 SEE ALSO + + L<bn_internal(3)|bn_internal(3)>, +-L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, ++L<dh(3)|dh(3)>, L<openssl_err(3)|openssl_err(3)>, L<openssl_rand(3)|openssl_rand(3)>, L<rsa(3)|rsa(3)>, + L<BN_new(3)|BN_new(3)>, L<BN_CTX_new(3)|BN_CTX_new(3)>, + L<BN_copy(3)|BN_copy(3)>, L<BN_swap(3)|BN_swap(3)>, L<BN_num_bytes(3)|BN_num_bytes(3)>, + L<BN_add(3)|BN_add(3)>, L<BN_add_word(3)|BN_add_word(3)>, +diff -Naur openssl-0.9.8a.orig/doc/crypto/crypto.pod openssl-0.9.8a/doc/crypto/crypto.pod +--- openssl-0.9.8a.orig/doc/crypto/crypto.pod 2002-10-06 12:59:25.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/crypto.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -46,7 +46,7 @@ + + =item AUXILIARY FUNCTIONS + +-L<err(3)|err(3)>, L<threads(3)|threads(3)>, L<rand(3)|rand(3)>, ++L<openssl_err(3)|openssl_err(3)>, L<openssl_threads(3)|openssl_threads(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<OPENSSL_VERSION_NUMBER(3)|OPENSSL_VERSION_NUMBER(3)> + + =item INPUT/OUTPUT, DATA ENCODING +diff -Naur openssl-0.9.8a.orig/doc/crypto/des.pod openssl-0.9.8a/doc/crypto/des.pod +--- openssl-0.9.8a.orig/doc/crypto/des.pod 2003-10-01 15:02:45.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/des.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -115,7 +115,7 @@ + the key; it is used to speed the encryption process. + + DES_random_key() generates a random key. The PRNG must be seeded +-prior to using this function (see L<rand(3)|rand(3)>). If the PRNG ++prior to using this function (see L<openssl_rand(3)|openssl_rand(3)>). If the PRNG + could not generate a secure key, 0 is returned. + + Before a DES key can be used, it must be converted into the +@@ -317,7 +317,7 @@ + + =head1 SEE ALSO + +-crypt(3), L<des_modes(7)|des_modes(7)>, L<evp(3)|evp(3)>, L<rand(3)|rand(3)> ++crypt(3), L<des_modes(7)|des_modes(7)>, L<evp(3)|evp(3)>, L<openssl_rand(3)|openssl_rand(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/crypto/dh.pod openssl-0.9.8a/doc/crypto/dh.pod +--- openssl-0.9.8a.orig/doc/crypto/dh.pod 2002-08-05 16:27:01.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/dh.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -67,8 +67,8 @@ + + =head1 SEE ALSO + +-L<dhparam(1)|dhparam(1)>, L<bn(3)|bn(3)>, L<dsa(3)|dsa(3)>, L<err(3)|err(3)>, +-L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, L<engine(3)|engine(3)>, ++L<dhparam(1)|dhparam(1)>, L<bn(3)|bn(3)>, L<dsa(3)|dsa(3)>, L<openssl_err(3)|openssl_err(3)>, ++L<openssl_rand(3)|openssl_rand(3)>, L<rsa(3)|rsa(3)>, L<engine(3)|engine(3)>, + L<DH_set_method(3)|DH_set_method(3)>, L<DH_new(3)|DH_new(3)>, + L<DH_get_ex_new_index(3)|DH_get_ex_new_index(3)>, + L<DH_generate_parameters(3)|DH_generate_parameters(3)>, +diff -Naur openssl-0.9.8a.orig/doc/crypto/dsa.pod openssl-0.9.8a/doc/crypto/dsa.pod +--- openssl-0.9.8a.orig/doc/crypto/dsa.pod 2002-08-05 16:27:01.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/dsa.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -100,7 +100,7 @@ + + =head1 SEE ALSO + +-L<bn(3)|bn(3)>, L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, ++L<bn(3)|bn(3)>, L<dh(3)|dh(3)>, L<openssl_err(3)|openssl_err(3)>, L<openssl_rand(3)|openssl_rand(3)>, + L<rsa(3)|rsa(3)>, L<sha(3)|sha(3)>, L<engine(3)|engine(3)>, + L<DSA_new(3)|DSA_new(3)>, + L<DSA_size(3)|DSA_size(3)>, +diff -Naur openssl-0.9.8a.orig/doc/crypto/engine.pod openssl-0.9.8a/doc/crypto/engine.pod +--- openssl-0.9.8a.orig/doc/crypto/engine.pod 2004-06-17 23:40:14.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/engine.pod 2005-11-14 04:01:19.000000000 +0000 +@@ -594,6 +594,6 @@ + + =head1 SEE ALSO + +-L<rsa(3)|rsa(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rand(3)|rand(3)> ++L<rsa(3)|rsa(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<openssl_rand(3)|openssl_rand(3)> + + =cut +diff -Naur openssl-0.9.8a.orig/doc/crypto/err.pod openssl-0.9.8a/doc/crypto/err.pod +--- openssl-0.9.8a.orig/doc/crypto/err.pod 2002-07-10 19:35:46.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/err.pod 1970-01-01 00:00:00.000000000 +0000 +@@ -1,187 +0,0 @@ +-=pod +- +-=head1 NAME +- +-err - error codes +- +-=head1 SYNOPSIS +- +- #include <openssl/err.h> +- +- unsigned long ERR_get_error(void); +- unsigned long ERR_peek_error(void); +- unsigned long ERR_get_error_line(const char **file, int *line); +- unsigned long ERR_peek_error_line(const char **file, int *line); +- unsigned long ERR_get_error_line_data(const char **file, int *line, +- const char **data, int *flags); +- unsigned long ERR_peek_error_line_data(const char **file, int *line, +- const char **data, int *flags); +- +- int ERR_GET_LIB(unsigned long e); +- int ERR_GET_FUNC(unsigned long e); +- int ERR_GET_REASON(unsigned long e); +- +- void ERR_clear_error(void); +- +- char *ERR_error_string(unsigned long e, char *buf); +- const char *ERR_lib_error_string(unsigned long e); +- const char *ERR_func_error_string(unsigned long e); +- const char *ERR_reason_error_string(unsigned long e); +- +- void ERR_print_errors(BIO *bp); +- void ERR_print_errors_fp(FILE *fp); +- +- void ERR_load_crypto_strings(void); +- void ERR_free_strings(void); +- +- void ERR_remove_state(unsigned long pid); +- +- void ERR_put_error(int lib, int func, int reason, const char *file, +- int line); +- void ERR_add_error_data(int num, ...); +- +- void ERR_load_strings(int lib,ERR_STRING_DATA str[]); +- unsigned long ERR_PACK(int lib, int func, int reason); +- int ERR_get_next_error_library(void); +- +-=head1 DESCRIPTION +- +-When a call to the OpenSSL library fails, this is usually signalled +-by the return value, and an error code is stored in an error queue +-associated with the current thread. The B<err> library provides +-functions to obtain these error codes and textual error messages. +- +-The L<ERR_get_error(3)|ERR_get_error(3)> manpage describes how to +-access error codes. +- +-Error codes contain information about where the error occurred, and +-what went wrong. L<ERR_GET_LIB(3)|ERR_GET_LIB(3)> describes how to +-extract this information. A method to obtain human-readable error +-messages is described in L<ERR_error_string(3)|ERR_error_string(3)>. +- +-L<ERR_clear_error(3)|ERR_clear_error(3)> can be used to clear the +-error queue. +- +-Note that L<ERR_remove_state(3)|ERR_remove_state(3)> should be used to +-avoid memory leaks when threads are terminated. +- +-=head1 ADDING NEW ERROR CODES TO OPENSSL +- +-See L<ERR_put_error(3)> if you want to record error codes in the +-OpenSSL error system from within your application. +- +-The remainder of this section is of interest only if you want to add +-new error codes to OpenSSL or add error codes from external libraries. +- +-=head2 Reporting errors +- +-Each sub-library has a specific macro XXXerr() that is used to report +-errors. Its first argument is a function code B<XXX_F_...>, the second +-argument is a reason code B<XXX_R_...>. Function codes are derived +-from the function names; reason codes consist of textual error +-descriptions. For example, the function ssl23_read() reports a +-"handshake failure" as follows: +- +- SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE); +- +-Function and reason codes should consist of upper case characters, +-numbers and underscores only. The error file generation script translates +-function codes into function names by looking in the header files +-for an appropriate function name, if none is found it just uses +-the capitalized form such as "SSL23_READ" in the above example. +- +-The trailing section of a reason code (after the "_R_") is translated +-into lower case and underscores changed to spaces. +- +-When you are using new function or reason codes, run B<make errors>. +-The necessary B<#define>s will then automatically be added to the +-sub-library's header file. +- +-Although a library will normally report errors using its own specific +-XXXerr macro, another library's macro can be used. This is normally +-only done when a library wants to include ASN1 code which must use +-the ASN1err() macro. +- +-=head2 Adding new libraries +- +-When adding a new sub-library to OpenSSL, assign it a library number +-B<ERR_LIB_XXX>, define a macro XXXerr() (both in B<err.h>), add its +-name to B<ERR_str_libraries[]> (in B<crypto/err/err.c>), and add +-C<ERR_load_XXX_strings()> to the ERR_load_crypto_strings() function +-(in B<crypto/err/err_all.c>). Finally, add an entry +- +- L XXX xxx.h xxx_err.c +- +-to B<crypto/err/openssl.ec>, and add B<xxx_err.c> to the Makefile. +-Running B<make errors> will then generate a file B<xxx_err.c>, and +-add all error codes used in the library to B<xxx.h>. +- +-Additionally the library include file must have a certain form. +-Typically it will initially look like this: +- +- #ifndef HEADER_XXX_H +- #define HEADER_XXX_H +- +- #ifdef __cplusplus +- extern "C" { +- #endif +- +- /* Include files */ +- +- #include <openssl/bio.h> +- #include <openssl/x509.h> +- +- /* Macros, structures and function prototypes */ +- +- +- /* BEGIN ERROR CODES */ +- +-The B<BEGIN ERROR CODES> sequence is used by the error code +-generation script as the point to place new error codes, any text +-after this point will be overwritten when B<make errors> is run. +-The closing #endif etc will be automatically added by the script. +- +-The generated C error code file B<xxx_err.c> will load the header +-files B<stdio.h>, B<openssl/err.h> and B<openssl/xxx.h> so the +-header file must load any additional header files containing any +-definitions it uses. +- +-=head1 USING ERROR CODES IN EXTERNAL LIBRARIES +- +-It is also possible to use OpenSSL's error code scheme in external +-libraries. The library needs to load its own codes and call the OpenSSL +-error code insertion script B<mkerr.pl> explicitly to add codes to +-the header file and generate the C error code file. This will normally +-be done if the external library needs to generate new ASN1 structures +-but it can also be used to add more general purpose error code handling. +- +-TBA more details +- +-=head1 INTERNALS +- +-The error queues are stored in a hash table with one B<ERR_STATE> +-entry for each pid. ERR_get_state() returns the current thread's +-B<ERR_STATE>. An B<ERR_STATE> can hold up to B<ERR_NUM_ERRORS> error +-codes. When more error codes are added, the old ones are overwritten, +-on the assumption that the most recent errors are most important. +- +-Error strings are also stored in hash table. The hash tables can +-be obtained by calling ERR_get_err_state_table(void) and +-ERR_get_string_table(void) respectively. +- +-=head1 SEE ALSO +- +-L<CRYPTO_set_id_callback(3)|CRYPTO_set_id_callback(3)>, +-L<CRYPTO_set_locking_callback(3)|CRYPTO_set_locking_callback(3)>, +-L<ERR_get_error(3)|ERR_get_error(3)>, +-L<ERR_GET_LIB(3)|ERR_GET_LIB(3)>, +-L<ERR_clear_error(3)|ERR_clear_error(3)>, +-L<ERR_error_string(3)|ERR_error_string(3)>, +-L<ERR_print_errors(3)|ERR_print_errors(3)>, +-L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>, +-L<ERR_remove_state(3)|ERR_remove_state(3)>, +-L<ERR_put_error(3)|ERR_put_error(3)>, +-L<ERR_load_strings(3)|ERR_load_strings(3)>, +-L<SSL_get_error(3)|SSL_get_error(3)> +- +-=cut +diff -Naur openssl-0.9.8a.orig/doc/crypto/openssl_err.pod openssl-0.9.8a/doc/crypto/openssl_err.pod +--- openssl-0.9.8a.orig/doc/crypto/openssl_err.pod 1970-01-01 00:00:00.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/openssl_err.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -0,0 +1,187 @@ ++=pod ++ ++=head1 NAME ++ ++openssl_err - error codes ++ ++=head1 SYNOPSIS ++ ++ #include <openssl/err.h> ++ ++ unsigned long ERR_get_error(void); ++ unsigned long ERR_peek_error(void); ++ unsigned long ERR_get_error_line(const char **file, int *line); ++ unsigned long ERR_peek_error_line(const char **file, int *line); ++ unsigned long ERR_get_error_line_data(const char **file, int *line, ++ const char **data, int *flags); ++ unsigned long ERR_peek_error_line_data(const char **file, int *line, ++ const char **data, int *flags); ++ ++ int ERR_GET_LIB(unsigned long e); ++ int ERR_GET_FUNC(unsigned long e); ++ int ERR_GET_REASON(unsigned long e); ++ ++ void ERR_clear_error(void); ++ ++ char *ERR_error_string(unsigned long e, char *buf); ++ const char *ERR_lib_error_string(unsigned long e); ++ const char *ERR_func_error_string(unsigned long e); ++ const char *ERR_reason_error_string(unsigned long e); ++ ++ void ERR_print_errors(BIO *bp); ++ void ERR_print_errors_fp(FILE *fp); ++ ++ void ERR_load_crypto_strings(void); ++ void ERR_free_strings(void); ++ ++ void ERR_remove_state(unsigned long pid); ++ ++ void ERR_put_error(int lib, int func, int reason, const char *file, ++ int line); ++ void ERR_add_error_data(int num, ...); ++ ++ void ERR_load_strings(int lib,ERR_STRING_DATA str[]); ++ unsigned long ERR_PACK(int lib, int func, int reason); ++ int ERR_get_next_error_library(void); ++ ++=head1 DESCRIPTION ++ ++When a call to the OpenSSL library fails, this is usually signalled ++by the return value, and an error code is stored in an error queue ++associated with the current thread. The B<err> library provides ++functions to obtain these error codes and textual error messages. ++ ++The L<ERR_get_error(3)|ERR_get_error(3)> manpage describes how to ++access error codes. ++ ++Error codes contain information about where the error occurred, and ++what went wrong. L<ERR_GET_LIB(3)|ERR_GET_LIB(3)> describes how to ++extract this information. A method to obtain human-readable error ++messages is described in L<ERR_error_string(3)|ERR_error_string(3)>. ++ ++L<ERR_clear_error(3)|ERR_clear_error(3)> can be used to clear the ++error queue. ++ ++Note that L<ERR_remove_state(3)|ERR_remove_state(3)> should be used to ++avoid memory leaks when threads are terminated. ++ ++=head1 ADDING NEW ERROR CODES TO OPENSSL ++ ++See L<ERR_put_error(3)> if you want to record error codes in the ++OpenSSL error system from within your application. ++ ++The remainder of this section is of interest only if you want to add ++new error codes to OpenSSL or add error codes from external libraries. ++ ++=head2 Reporting errors ++ ++Each sub-library has a specific macro XXXerr() that is used to report ++errors. Its first argument is a function code B<XXX_F_...>, the second ++argument is a reason code B<XXX_R_...>. Function codes are derived ++from the function names; reason codes consist of textual error ++descriptions. For example, the function ssl23_read() reports a ++"handshake failure" as follows: ++ ++ SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE); ++ ++Function and reason codes should consist of upper case characters, ++numbers and underscores only. The error file generation script translates ++function codes into function names by looking in the header files ++for an appropriate function name, if none is found it just uses ++the capitalized form such as "SSL23_READ" in the above example. ++ ++The trailing section of a reason code (after the "_R_") is translated ++into lower case and underscores changed to spaces. ++ ++When you are using new function or reason codes, run B<make errors>. ++The necessary B<#define>s will then automatically be added to the ++sub-library's header file. ++ ++Although a library will normally report errors using its own specific ++XXXerr macro, another library's macro can be used. This is normally ++only done when a library wants to include ASN1 code which must use ++the ASN1err() macro. ++ ++=head2 Adding new libraries ++ ++When adding a new sub-library to OpenSSL, assign it a library number ++B<ERR_LIB_XXX>, define a macro XXXerr() (both in B<err.h>), add its ++name to B<ERR_str_libraries[]> (in B<crypto/err/err.c>), and add ++C<ERR_load_XXX_strings()> to the ERR_load_crypto_strings() function ++(in B<crypto/err/err_all.c>). Finally, add an entry ++ ++ L XXX xxx.h xxx_err.c ++ ++to B<crypto/err/openssl.ec>, and add B<xxx_err.c> to the Makefile. ++Running B<make errors> will then generate a file B<xxx_err.c>, and ++add all error codes used in the library to B<xxx.h>. ++ ++Additionally the library include file must have a certain form. ++Typically it will initially look like this: ++ ++ #ifndef HEADER_XXX_H ++ #define HEADER_XXX_H ++ ++ #ifdef __cplusplus ++ extern "C" { ++ #endif ++ ++ /* Include files */ ++ ++ #include <openssl/bio.h> ++ #include <openssl/x509.h> ++ ++ /* Macros, structures and function prototypes */ ++ ++ ++ /* BEGIN ERROR CODES */ ++ ++The B<BEGIN ERROR CODES> sequence is used by the error code ++generation script as the point to place new error codes, any text ++after this point will be overwritten when B<make errors> is run. ++The closing #endif etc will be automatically added by the script. ++ ++The generated C error code file B<xxx_err.c> will load the header ++files B<stdio.h>, B<openssl/err.h> and B<openssl/xxx.h> so the ++header file must load any additional header files containing any ++definitions it uses. ++ ++=head1 USING ERROR CODES IN EXTERNAL LIBRARIES ++ ++It is also possible to use OpenSSL's error code scheme in external ++libraries. The library needs to load its own codes and call the OpenSSL ++error code insertion script B<mkerr.pl> explicitly to add codes to ++the header file and generate the C error code file. This will normally ++be done if the external library needs to generate new ASN1 structures ++but it can also be used to add more general purpose error code handling. ++ ++TBA more details ++ ++=head1 INTERNALS ++ ++The error queues are stored in a hash table with one B<ERR_STATE> ++entry for each pid. ERR_get_state() returns the current thread's ++B<ERR_STATE>. An B<ERR_STATE> can hold up to B<ERR_NUM_ERRORS> error ++codes. When more error codes are added, the old ones are overwritten, ++on the assumption that the most recent errors are most important. ++ ++Error strings are also stored in hash table. The hash tables can ++be obtained by calling ERR_get_err_state_table(void) and ++ERR_get_string_table(void) respectively. ++ ++=head1 SEE ALSO ++ ++L<CRYPTO_set_id_callback(3)|CRYPTO_set_id_callback(3)>, ++L<CRYPTO_set_locking_callback(3)|CRYPTO_set_locking_callback(3)>, ++L<ERR_get_error(3)|ERR_get_error(3)>, ++L<ERR_GET_LIB(3)|ERR_GET_LIB(3)>, ++L<ERR_clear_error(3)|ERR_clear_error(3)>, ++L<ERR_error_string(3)|ERR_error_string(3)>, ++L<ERR_print_errors(3)|ERR_print_errors(3)>, ++L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>, ++L<ERR_remove_state(3)|ERR_remove_state(3)>, ++L<ERR_put_error(3)|ERR_put_error(3)>, ++L<ERR_load_strings(3)|ERR_load_strings(3)>, ++L<SSL_get_error(3)|SSL_get_error(3)> ++ ++=cut +diff -Naur openssl-0.9.8a.orig/doc/crypto/openssl_rand.pod openssl-0.9.8a/doc/crypto/openssl_rand.pod +--- openssl-0.9.8a.orig/doc/crypto/openssl_rand.pod 1970-01-01 00:00:00.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/openssl_rand.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -0,0 +1,175 @@ ++=pod ++ ++=head1 NAME ++ ++openssl_rand - pseudo-random number generator ++ ++=head1 SYNOPSIS ++ ++ #include <openssl/rand.h> ++ ++ int RAND_set_rand_engine(ENGINE *engine); ++ ++ int RAND_bytes(unsigned char *buf, int num); ++ int RAND_pseudo_bytes(unsigned char *buf, int num); ++ ++ void RAND_seed(const void *buf, int num); ++ void RAND_add(const void *buf, int num, int entropy); ++ int RAND_status(void); ++ ++ int RAND_load_file(const char *file, long max_bytes); ++ int RAND_write_file(const char *file); ++ const char *RAND_file_name(char *file, size_t num); ++ ++ int RAND_egd(const char *path); ++ ++ void RAND_set_rand_method(const RAND_METHOD *meth); ++ const RAND_METHOD *RAND_get_rand_method(void); ++ RAND_METHOD *RAND_SSLeay(void); ++ ++ void RAND_cleanup(void); ++ ++ /* For Win32 only */ ++ void RAND_screen(void); ++ int RAND_event(UINT, WPARAM, LPARAM); ++ ++=head1 DESCRIPTION ++ ++Since the introduction of the ENGINE API, the recommended way of controlling ++default implementations is by using the ENGINE API functions. The default ++B<RAND_METHOD>, as set by RAND_set_rand_method() and returned by ++RAND_get_rand_method(), is only used if no ENGINE has been set as the default ++"rand" implementation. Hence, these two functions are no longer the recommened ++way to control defaults. ++ ++If an alternative B<RAND_METHOD> implementation is being used (either set ++directly or as provided by an ENGINE module), then it is entirely responsible ++for the generation and management of a cryptographically secure PRNG stream. The ++mechanisms described below relate solely to the software PRNG implementation ++built in to OpenSSL and used by default. ++ ++These functions implement a cryptographically secure pseudo-random ++number generator (PRNG). It is used by other library functions for ++example to generate random keys, and applications can use it when they ++need randomness. ++ ++A cryptographic PRNG must be seeded with unpredictable data such as ++mouse movements or keys pressed at random by the user. This is ++described in L<RAND_add(3)|RAND_add(3)>. Its state can be saved in a seed file ++(see L<RAND_load_file(3)|RAND_load_file(3)>) to avoid having to go through the ++seeding process whenever the application is started. ++ ++L<RAND_bytes(3)|RAND_bytes(3)> describes how to obtain random data from the ++PRNG. ++ ++=head1 INTERNALS ++ ++The RAND_SSLeay() method implements a PRNG based on a cryptographic ++hash function. ++ ++The following description of its design is based on the SSLeay ++documentation: ++ ++First up I will state the things I believe I need for a good RNG. ++ ++=over 4 ++ ++=item 1 ++ ++A good hashing algorithm to mix things up and to convert the RNG 'state' ++to random numbers. ++ ++=item 2 ++ ++An initial source of random 'state'. ++ ++=item 3 ++ ++The state should be very large. If the RNG is being used to generate ++4096 bit RSA keys, 2 2048 bit random strings are required (at a minimum). ++If your RNG state only has 128 bits, you are obviously limiting the ++search space to 128 bits, not 2048. I'm probably getting a little ++carried away on this last point but it does indicate that it may not be ++a bad idea to keep quite a lot of RNG state. It should be easier to ++break a cipher than guess the RNG seed data. ++ ++=item 4 ++ ++Any RNG seed data should influence all subsequent random numbers ++generated. This implies that any random seed data entered will have ++an influence on all subsequent random numbers generated. ++ ++=item 5 ++ ++When using data to seed the RNG state, the data used should not be ++extractable from the RNG state. I believe this should be a ++requirement because one possible source of 'secret' semi random ++data would be a private key or a password. This data must ++not be disclosed by either subsequent random numbers or a ++'core' dump left by a program crash. ++ ++=item 6 ++ ++Given the same initial 'state', 2 systems should deviate in their RNG state ++(and hence the random numbers generated) over time if at all possible. ++ ++=item 7 ++ ++Given the random number output stream, it should not be possible to determine ++the RNG state or the next random number. ++ ++=back ++ ++The algorithm is as follows. ++ ++There is global state made up of a 1023 byte buffer (the 'state'), a ++working hash value ('md'), and a counter ('count'). ++ ++Whenever seed data is added, it is inserted into the 'state' as ++follows. ++ ++The input is chopped up into units of 20 bytes (or less for ++the last block). Each of these blocks is run through the hash ++function as follows: The data passed to the hash function ++is the current 'md', the same number of bytes from the 'state' ++(the location determined by in incremented looping index) as ++the current 'block', the new key data 'block', and 'count' ++(which is incremented after each use). ++The result of this is kept in 'md' and also xored into the ++'state' at the same locations that were used as input into the ++hash function. I ++believe this system addresses points 1 (hash function; currently ++SHA-1), 3 (the 'state'), 4 (via the 'md'), 5 (by the use of a hash ++function and xor). ++ ++When bytes are extracted from the RNG, the following process is used. ++For each group of 10 bytes (or less), we do the following: ++ ++Input into the hash function the local 'md' (which is initialized from ++the global 'md' before any bytes are generated), the bytes that are to ++be overwritten by the random bytes, and bytes from the 'state' ++(incrementing looping index). From this digest output (which is kept ++in 'md'), the top (up to) 10 bytes are returned to the caller and the ++bottom 10 bytes are xored into the 'state'. ++ ++Finally, after we have finished 'num' random bytes for the caller, ++'count' (which is incremented) and the local and global 'md' are fed ++into the hash function and the results are kept in the global 'md'. ++ ++I believe the above addressed points 1 (use of SHA-1), 6 (by hashing ++into the 'state' the 'old' data from the caller that is about to be ++overwritten) and 7 (by not using the 10 bytes given to the caller to ++update the 'state', but they are used to update 'md'). ++ ++So of the points raised, only 2 is not addressed (but see ++L<RAND_add(3)|RAND_add(3)>). ++ ++=head1 SEE ALSO ++ ++L<BN_rand(3)|BN_rand(3)>, L<RAND_add(3)|RAND_add(3)>, ++L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_egd(3)|RAND_egd(3)>, ++L<RAND_bytes(3)|RAND_bytes(3)>, ++L<RAND_set_rand_method(3)|RAND_set_rand_method(3)>, ++L<RAND_cleanup(3)|RAND_cleanup(3)> ++ ++=cut +diff -Naur openssl-0.9.8a.orig/doc/crypto/openssl_threads.pod openssl-0.9.8a/doc/crypto/openssl_threads.pod +--- openssl-0.9.8a.orig/doc/crypto/openssl_threads.pod 1970-01-01 00:00:00.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/openssl_threads.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -0,0 +1,175 @@ ++=pod ++ ++=head1 NAME ++ ++CRYPTO_set_locking_callback, CRYPTO_set_id_callback, CRYPTO_num_locks, ++CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback, ++CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid, ++CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support ++ ++=head1 SYNOPSIS ++ ++ #include <openssl/crypto.h> ++ ++ void CRYPTO_set_locking_callback(void (*locking_function)(int mode, ++ int n, const char *file, int line)); ++ ++ void CRYPTO_set_id_callback(unsigned long (*id_function)(void)); ++ ++ int CRYPTO_num_locks(void); ++ ++ ++ /* struct CRYPTO_dynlock_value needs to be defined by the user */ ++ struct CRYPTO_dynlock_value; ++ ++ void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value * ++ (*dyn_create_function)(char *file, int line)); ++ void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function) ++ (int mode, struct CRYPTO_dynlock_value *l, ++ const char *file, int line)); ++ void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function) ++ (struct CRYPTO_dynlock_value *l, const char *file, int line)); ++ ++ int CRYPTO_get_new_dynlockid(void); ++ ++ void CRYPTO_destroy_dynlockid(int i); ++ ++ void CRYPTO_lock(int mode, int n, const char *file, int line); ++ ++ #define CRYPTO_w_lock(type) \ ++ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) ++ #define CRYPTO_w_unlock(type) \ ++ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) ++ #define CRYPTO_r_lock(type) \ ++ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) ++ #define CRYPTO_r_unlock(type) \ ++ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) ++ #define CRYPTO_add(addr,amount,type) \ ++ CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) ++ ++=head1 DESCRIPTION ++ ++OpenSSL can safely be used in multi-threaded applications provided ++that at least two callback functions are set. ++ ++locking_function(int mode, int n, const char *file, int line) is ++needed to perform locking on shared data structures. ++(Note that OpenSSL uses a number of global data structures that ++will be implicitly shared whenever multiple threads use OpenSSL.) ++Multi-threaded applications will crash at random if it is not set. ++ ++locking_function() must be able to handle up to CRYPTO_num_locks() ++different mutex locks. It sets the B<n>-th lock if B<mode> & ++B<CRYPTO_LOCK>, and releases it otherwise. ++ ++B<file> and B<line> are the file number of the function setting the ++lock. They can be useful for debugging. ++ ++id_function(void) is a function that returns a thread ID, for example ++pthread_self() if it returns an integer (see NOTES below). It isn't ++needed on Windows nor on platforms where getpid() returns a different ++ID for each thread (see NOTES below). ++ ++Additionally, OpenSSL supports dynamic locks, and sometimes, some parts ++of OpenSSL need it for better performance. To enable this, the following ++is required: ++ ++=over 4 ++ ++=item * ++Three additional callback function, dyn_create_function, dyn_lock_function ++and dyn_destroy_function. ++ ++=item * ++A structure defined with the data that each lock needs to handle. ++ ++=back ++ ++struct CRYPTO_dynlock_value has to be defined to contain whatever structure ++is needed to handle locks. ++ ++dyn_create_function(const char *file, int line) is needed to create a ++lock. Multi-threaded applications might crash at random if it is not set. ++ ++dyn_lock_function(int mode, CRYPTO_dynlock *l, const char *file, int line) ++is needed to perform locking off dynamic lock numbered n. Multi-threaded ++applications might crash at random if it is not set. ++ ++dyn_destroy_function(CRYPTO_dynlock *l, const char *file, int line) is ++needed to destroy the lock l. Multi-threaded applications might crash at ++random if it is not set. ++ ++CRYPTO_get_new_dynlockid() is used to create locks. It will call ++dyn_create_function for the actual creation. ++ ++CRYPTO_destroy_dynlockid() is used to destroy locks. It will call ++dyn_destroy_function for the actual destruction. ++ ++CRYPTO_lock() is used to lock and unlock the locks. mode is a bitfield ++describing what should be done with the lock. n is the number of the ++lock as returned from CRYPTO_get_new_dynlockid(). mode can be combined ++from the following values. These values are pairwise exclusive, with ++undefined behaviour if misused (for example, CRYPTO_READ and CRYPTO_WRITE ++should not be used together): ++ ++ CRYPTO_LOCK 0x01 ++ CRYPTO_UNLOCK 0x02 ++ CRYPTO_READ 0x04 ++ CRYPTO_WRITE 0x08 ++ ++=head1 RETURN VALUES ++ ++CRYPTO_num_locks() returns the required number of locks. ++ ++CRYPTO_get_new_dynlockid() returns the index to the newly created lock. ++ ++The other functions return no values. ++ ++=head1 NOTES ++ ++You can find out if OpenSSL was configured with thread support: ++ ++ #define OPENSSL_THREAD_DEFINES ++ #include <openssl/opensslconf.h> ++ #if defined(OPENSSL_THREADS) ++ // thread support enabled ++ #else ++ // no thread support ++ #endif ++ ++Also, dynamic locks are currently not used internally by OpenSSL, but ++may do so in the future. ++ ++Defining id_function(void) has it's own issues. Generally speaking, ++pthread_self() should be used, even on platforms where getpid() gives ++different answers in each thread, since that may depend on the machine ++the program is run on, not the machine where the program is being ++compiled. For instance, Red Hat 8 Linux and earlier used ++LinuxThreads, whose getpid() returns a different value for each ++thread. Red Hat 9 Linux and later use NPTL, which is ++Posix-conformant, and has a getpid() that returns the same value for ++all threads in a process. A program compiled on Red Hat 8 and run on ++Red Hat 9 will therefore see getpid() returning the same value for ++all threads. ++ ++There is still the issue of platforms where pthread_self() returns ++something other than an integer. This is a bit unusual, and this ++manual has no cookbook solution for that case. ++ ++=head1 EXAMPLES ++ ++B<crypto/threads/mttest.c> shows examples of the callback functions on ++Solaris, Irix and Win32. ++ ++=head1 HISTORY ++ ++CRYPTO_set_locking_callback() and CRYPTO_set_id_callback() are ++available in all versions of SSLeay and OpenSSL. ++CRYPTO_num_locks() was added in OpenSSL 0.9.4. ++All functions dealing with dynamic locks were added in OpenSSL 0.9.5b-dev. ++ ++=head1 SEE ALSO ++ ++L<crypto(3)|crypto(3)> ++ ++=cut +diff -Naur openssl-0.9.8a.orig/doc/crypto/rand.pod openssl-0.9.8a/doc/crypto/rand.pod +--- openssl-0.9.8a.orig/doc/crypto/rand.pod 2002-08-05 16:27:01.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/rand.pod 1970-01-01 00:00:00.000000000 +0000 +@@ -1,175 +0,0 @@ +-=pod +- +-=head1 NAME +- +-rand - pseudo-random number generator +- +-=head1 SYNOPSIS +- +- #include <openssl/rand.h> +- +- int RAND_set_rand_engine(ENGINE *engine); +- +- int RAND_bytes(unsigned char *buf, int num); +- int RAND_pseudo_bytes(unsigned char *buf, int num); +- +- void RAND_seed(const void *buf, int num); +- void RAND_add(const void *buf, int num, int entropy); +- int RAND_status(void); +- +- int RAND_load_file(const char *file, long max_bytes); +- int RAND_write_file(const char *file); +- const char *RAND_file_name(char *file, size_t num); +- +- int RAND_egd(const char *path); +- +- void RAND_set_rand_method(const RAND_METHOD *meth); +- const RAND_METHOD *RAND_get_rand_method(void); +- RAND_METHOD *RAND_SSLeay(void); +- +- void RAND_cleanup(void); +- +- /* For Win32 only */ +- void RAND_screen(void); +- int RAND_event(UINT, WPARAM, LPARAM); +- +-=head1 DESCRIPTION +- +-Since the introduction of the ENGINE API, the recommended way of controlling +-default implementations is by using the ENGINE API functions. The default +-B<RAND_METHOD>, as set by RAND_set_rand_method() and returned by +-RAND_get_rand_method(), is only used if no ENGINE has been set as the default +-"rand" implementation. Hence, these two functions are no longer the recommened +-way to control defaults. +- +-If an alternative B<RAND_METHOD> implementation is being used (either set +-directly or as provided by an ENGINE module), then it is entirely responsible +-for the generation and management of a cryptographically secure PRNG stream. The +-mechanisms described below relate solely to the software PRNG implementation +-built in to OpenSSL and used by default. +- +-These functions implement a cryptographically secure pseudo-random +-number generator (PRNG). It is used by other library functions for +-example to generate random keys, and applications can use it when they +-need randomness. +- +-A cryptographic PRNG must be seeded with unpredictable data such as +-mouse movements or keys pressed at random by the user. This is +-described in L<RAND_add(3)|RAND_add(3)>. Its state can be saved in a seed file +-(see L<RAND_load_file(3)|RAND_load_file(3)>) to avoid having to go through the +-seeding process whenever the application is started. +- +-L<RAND_bytes(3)|RAND_bytes(3)> describes how to obtain random data from the +-PRNG. +- +-=head1 INTERNALS +- +-The RAND_SSLeay() method implements a PRNG based on a cryptographic +-hash function. +- +-The following description of its design is based on the SSLeay +-documentation: +- +-First up I will state the things I believe I need for a good RNG. +- +-=over 4 +- +-=item 1 +- +-A good hashing algorithm to mix things up and to convert the RNG 'state' +-to random numbers. +- +-=item 2 +- +-An initial source of random 'state'. +- +-=item 3 +- +-The state should be very large. If the RNG is being used to generate +-4096 bit RSA keys, 2 2048 bit random strings are required (at a minimum). +-If your RNG state only has 128 bits, you are obviously limiting the +-search space to 128 bits, not 2048. I'm probably getting a little +-carried away on this last point but it does indicate that it may not be +-a bad idea to keep quite a lot of RNG state. It should be easier to +-break a cipher than guess the RNG seed data. +- +-=item 4 +- +-Any RNG seed data should influence all subsequent random numbers +-generated. This implies that any random seed data entered will have +-an influence on all subsequent random numbers generated. +- +-=item 5 +- +-When using data to seed the RNG state, the data used should not be +-extractable from the RNG state. I believe this should be a +-requirement because one possible source of 'secret' semi random +-data would be a private key or a password. This data must +-not be disclosed by either subsequent random numbers or a +-'core' dump left by a program crash. +- +-=item 6 +- +-Given the same initial 'state', 2 systems should deviate in their RNG state +-(and hence the random numbers generated) over time if at all possible. +- +-=item 7 +- +-Given the random number output stream, it should not be possible to determine +-the RNG state or the next random number. +- +-=back +- +-The algorithm is as follows. +- +-There is global state made up of a 1023 byte buffer (the 'state'), a +-working hash value ('md'), and a counter ('count'). +- +-Whenever seed data is added, it is inserted into the 'state' as +-follows. +- +-The input is chopped up into units of 20 bytes (or less for +-the last block). Each of these blocks is run through the hash +-function as follows: The data passed to the hash function +-is the current 'md', the same number of bytes from the 'state' +-(the location determined by in incremented looping index) as +-the current 'block', the new key data 'block', and 'count' +-(which is incremented after each use). +-The result of this is kept in 'md' and also xored into the +-'state' at the same locations that were used as input into the +-hash function. I +-believe this system addresses points 1 (hash function; currently +-SHA-1), 3 (the 'state'), 4 (via the 'md'), 5 (by the use of a hash +-function and xor). +- +-When bytes are extracted from the RNG, the following process is used. +-For each group of 10 bytes (or less), we do the following: +- +-Input into the hash function the local 'md' (which is initialized from +-the global 'md' before any bytes are generated), the bytes that are to +-be overwritten by the random bytes, and bytes from the 'state' +-(incrementing looping index). From this digest output (which is kept +-in 'md'), the top (up to) 10 bytes are returned to the caller and the +-bottom 10 bytes are xored into the 'state'. +- +-Finally, after we have finished 'num' random bytes for the caller, +-'count' (which is incremented) and the local and global 'md' are fed +-into the hash function and the results are kept in the global 'md'. +- +-I believe the above addressed points 1 (use of SHA-1), 6 (by hashing +-into the 'state' the 'old' data from the caller that is about to be +-overwritten) and 7 (by not using the 10 bytes given to the caller to +-update the 'state', but they are used to update 'md'). +- +-So of the points raised, only 2 is not addressed (but see +-L<RAND_add(3)|RAND_add(3)>). +- +-=head1 SEE ALSO +- +-L<BN_rand(3)|BN_rand(3)>, L<RAND_add(3)|RAND_add(3)>, +-L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_egd(3)|RAND_egd(3)>, +-L<RAND_bytes(3)|RAND_bytes(3)>, +-L<RAND_set_rand_method(3)|RAND_set_rand_method(3)>, +-L<RAND_cleanup(3)|RAND_cleanup(3)> +- +-=cut +diff -Naur openssl-0.9.8a.orig/doc/crypto/rsa.pod openssl-0.9.8a/doc/crypto/rsa.pod +--- openssl-0.9.8a.orig/doc/crypto/rsa.pod 2002-08-04 21:08:36.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/rsa.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -108,7 +108,7 @@ + =head1 SEE ALSO + + L<rsa(1)|rsa(1)>, L<bn(3)|bn(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, +-L<rand(3)|rand(3)>, L<engine(3)|engine(3)>, L<RSA_new(3)|RSA_new(3)>, ++L<openssl_rand(3)|openssl_rand(3)>, L<engine(3)|engine(3)>, L<RSA_new(3)|RSA_new(3)>, + L<RSA_public_encrypt(3)|RSA_public_encrypt(3)>, + L<RSA_sign(3)|RSA_sign(3)>, L<RSA_size(3)|RSA_size(3)>, + L<RSA_generate_key(3)|RSA_generate_key(3)>, +diff -Naur openssl-0.9.8a.orig/doc/crypto/threads.pod openssl-0.9.8a/doc/crypto/threads.pod +--- openssl-0.9.8a.orig/doc/crypto/threads.pod 2005-06-18 05:52:23.000000000 +0000 ++++ openssl-0.9.8a/doc/crypto/threads.pod 1970-01-01 00:00:00.000000000 +0000 +@@ -1,175 +0,0 @@ +-=pod +- +-=head1 NAME +- +-CRYPTO_set_locking_callback, CRYPTO_set_id_callback, CRYPTO_num_locks, +-CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback, +-CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid, +-CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support +- +-=head1 SYNOPSIS +- +- #include <openssl/crypto.h> +- +- void CRYPTO_set_locking_callback(void (*locking_function)(int mode, +- int n, const char *file, int line)); +- +- void CRYPTO_set_id_callback(unsigned long (*id_function)(void)); +- +- int CRYPTO_num_locks(void); +- +- +- /* struct CRYPTO_dynlock_value needs to be defined by the user */ +- struct CRYPTO_dynlock_value; +- +- void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value * +- (*dyn_create_function)(char *file, int line)); +- void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function) +- (int mode, struct CRYPTO_dynlock_value *l, +- const char *file, int line)); +- void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function) +- (struct CRYPTO_dynlock_value *l, const char *file, int line)); +- +- int CRYPTO_get_new_dynlockid(void); +- +- void CRYPTO_destroy_dynlockid(int i); +- +- void CRYPTO_lock(int mode, int n, const char *file, int line); +- +- #define CRYPTO_w_lock(type) \ +- CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +- #define CRYPTO_w_unlock(type) \ +- CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +- #define CRYPTO_r_lock(type) \ +- CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) +- #define CRYPTO_r_unlock(type) \ +- CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) +- #define CRYPTO_add(addr,amount,type) \ +- CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) +- +-=head1 DESCRIPTION +- +-OpenSSL can safely be used in multi-threaded applications provided +-that at least two callback functions are set. +- +-locking_function(int mode, int n, const char *file, int line) is +-needed to perform locking on shared data structures. +-(Note that OpenSSL uses a number of global data structures that +-will be implicitly shared whenever multiple threads use OpenSSL.) +-Multi-threaded applications will crash at random if it is not set. +- +-locking_function() must be able to handle up to CRYPTO_num_locks() +-different mutex locks. It sets the B<n>-th lock if B<mode> & +-B<CRYPTO_LOCK>, and releases it otherwise. +- +-B<file> and B<line> are the file number of the function setting the +-lock. They can be useful for debugging. +- +-id_function(void) is a function that returns a thread ID, for example +-pthread_self() if it returns an integer (see NOTES below). It isn't +-needed on Windows nor on platforms where getpid() returns a different +-ID for each thread (see NOTES below). +- +-Additionally, OpenSSL supports dynamic locks, and sometimes, some parts +-of OpenSSL need it for better performance. To enable this, the following +-is required: +- +-=over 4 +- +-=item * +-Three additional callback function, dyn_create_function, dyn_lock_function +-and dyn_destroy_function. +- +-=item * +-A structure defined with the data that each lock needs to handle. +- +-=back +- +-struct CRYPTO_dynlock_value has to be defined to contain whatever structure +-is needed to handle locks. +- +-dyn_create_function(const char *file, int line) is needed to create a +-lock. Multi-threaded applications might crash at random if it is not set. +- +-dyn_lock_function(int mode, CRYPTO_dynlock *l, const char *file, int line) +-is needed to perform locking off dynamic lock numbered n. Multi-threaded +-applications might crash at random if it is not set. +- +-dyn_destroy_function(CRYPTO_dynlock *l, const char *file, int line) is +-needed to destroy the lock l. Multi-threaded applications might crash at +-random if it is not set. +- +-CRYPTO_get_new_dynlockid() is used to create locks. It will call +-dyn_create_function for the actual creation. +- +-CRYPTO_destroy_dynlockid() is used to destroy locks. It will call +-dyn_destroy_function for the actual destruction. +- +-CRYPTO_lock() is used to lock and unlock the locks. mode is a bitfield +-describing what should be done with the lock. n is the number of the +-lock as returned from CRYPTO_get_new_dynlockid(). mode can be combined +-from the following values. These values are pairwise exclusive, with +-undefined behaviour if misused (for example, CRYPTO_READ and CRYPTO_WRITE +-should not be used together): +- +- CRYPTO_LOCK 0x01 +- CRYPTO_UNLOCK 0x02 +- CRYPTO_READ 0x04 +- CRYPTO_WRITE 0x08 +- +-=head1 RETURN VALUES +- +-CRYPTO_num_locks() returns the required number of locks. +- +-CRYPTO_get_new_dynlockid() returns the index to the newly created lock. +- +-The other functions return no values. +- +-=head1 NOTES +- +-You can find out if OpenSSL was configured with thread support: +- +- #define OPENSSL_THREAD_DEFINES +- #include <openssl/opensslconf.h> +- #if defined(OPENSSL_THREADS) +- // thread support enabled +- #else +- // no thread support +- #endif +- +-Also, dynamic locks are currently not used internally by OpenSSL, but +-may do so in the future. +- +-Defining id_function(void) has it's own issues. Generally speaking, +-pthread_self() should be used, even on platforms where getpid() gives +-different answers in each thread, since that may depend on the machine +-the program is run on, not the machine where the program is being +-compiled. For instance, Red Hat 8 Linux and earlier used +-LinuxThreads, whose getpid() returns a different value for each +-thread. Red Hat 9 Linux and later use NPTL, which is +-Posix-conformant, and has a getpid() that returns the same value for +-all threads in a process. A program compiled on Red Hat 8 and run on +-Red Hat 9 will therefore see getpid() returning the same value for +-all threads. +- +-There is still the issue of platforms where pthread_self() returns +-something other than an integer. This is a bit unusual, and this +-manual has no cookbook solution for that case. +- +-=head1 EXAMPLES +- +-B<crypto/threads/mttest.c> shows examples of the callback functions on +-Solaris, Irix and Win32. +- +-=head1 HISTORY +- +-CRYPTO_set_locking_callback() and CRYPTO_set_id_callback() are +-available in all versions of SSLeay and OpenSSL. +-CRYPTO_num_locks() was added in OpenSSL 0.9.4. +-All functions dealing with dynamic locks were added in OpenSSL 0.9.5b-dev. +- +-=head1 SEE ALSO +- +-L<crypto(3)|crypto(3)> +- +-=cut +diff -Naur openssl-0.9.8a.orig/doc/ssl/SSL_get_error.pod openssl-0.9.8a/doc/ssl/SSL_get_error.pod +--- openssl-0.9.8a.orig/doc/ssl/SSL_get_error.pod 2005-03-30 11:50:14.000000000 +0000 ++++ openssl-0.9.8a/doc/ssl/SSL_get_error.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -105,7 +105,7 @@ + + =head1 SEE ALSO + +-L<ssl(3)|ssl(3)>, L<err(3)|err(3)> ++L<ssl(3)|ssl(3)>, L<openssl_err(3)|openssl_err(3)> + + =head1 HISTORY + +diff -Naur openssl-0.9.8a.orig/doc/ssl/SSL_want.pod openssl-0.9.8a/doc/ssl/SSL_want.pod +--- openssl-0.9.8a.orig/doc/ssl/SSL_want.pod 2005-03-30 11:50:14.000000000 +0000 ++++ openssl-0.9.8a/doc/ssl/SSL_want.pod 2005-11-14 03:59:59.000000000 +0000 +@@ -72,6 +72,6 @@ + + =head1 SEE ALSO + +-L<ssl(3)|ssl(3)>, L<err(3)|err(3)>, L<SSL_get_error(3)|SSL_get_error(3)> ++L<ssl(3)|ssl(3)>, L<openssl_err(3)|openssl_err(3)>, L<SSL_get_error(3)|SSL_get_error(3)> + + =cut diff --git a/pkgs/core/openssl/patches/openssl-0.9.8k-no-rpath.patch b/pkgs/core/openssl/patches/openssl-0.9.8k-no-rpath.patch new file mode 100644 index 0000000..8f8fb91 --- /dev/null +++ b/pkgs/core/openssl/patches/openssl-0.9.8k-no-rpath.patch @@ -0,0 +1,11 @@ +--- openssl-0.9.8a/Makefile.shared.no-rpath 2005-06-23 22:47:54.000000000 +0200 ++++ openssl-0.9.8a/Makefile.shared 2005-11-16 22:35:37.000000000 +0100 +@@ -153,7 +153,7 @@ + NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \ + SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX" + +-DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)" ++DO_GNU_APP=LDFLAGS="$(CFLAGS)" + + #This is rather special. It's a special target with which one can link + #applications without bothering with any features that have anything to diff --git a/pkgs/core/openvpn/openvpn.nm b/pkgs/core/openvpn/openvpn.nm new file mode 100644 index 0000000..5325dff --- /dev/null +++ b/pkgs/core/openvpn/openvpn.nm @@ -0,0 +1,72 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = openvpn +PKG_VER = 2.1_rc20 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/VPN +PKG_URL = http://openvpn.net/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = A full-featured SSL VPN solution. + +PKG_DEPS += iproute2 lzo openssl pam + +define PKG_DESCRIPTION + OpenVPN is a robust and highly flexible tunneling application that uses all \ + of the encryption, authentication, and certification features of the \ + OpenSSL library to securely tunnel IP networks over a single UDP or TCP \ + port. It can use the Marcus Franz Xaver Johannes Oberhumer's LZO library \ + for compression. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +PLUGINS = auth-pam down-root + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --enable-pthread \ + --enable-password-save \ + --enable-iproute2 + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) + cd $(DIR_APP) && for plugin in $(PLUGINS); do \ + make -C plugin/$$plugin; \ + done +endef + +define STAGE_INSTALL_CMDS + mkdir -pv $(BUILDROOT)/usr/lib/$(PKG_NAME)/plugin/lib + cd $(DIR_APP) && for plugin in $(PLUGINS); do \ + install -m 0755 plugin/$$plugin/openvpn-$$plugin.so \ + $(BUILDROOT)/usr/lib/$(PKG_NAME)/plugin/lib/openvpn-$$plugin.so; \ + done + -mkdir -pv $(BUILDROOT)/var/run/$(PKG_NAME) +endef diff --git a/pkgs/core/pakfire/pakfire.nm b/pkgs/core/pakfire/pakfire.nm new file mode 100644 index 0000000..097662a --- /dev/null +++ b/pkgs/core/pakfire/pakfire.nm @@ -0,0 +1,52 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pakfire +PKG_VER = 0.9 +PKG_REL = 0 + +PKG_MAINTAINER = Michael Tremer <michael.tremer@ipfire.org> +PKG_GROUP = System/Packaging +PKG_URL = http://www.ipfire.org/ +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = Package installer/updater. + +PKG_DEPS += cpio python python-urlgrabber system-release xz + +define PKG_DESCRIPTION + Pakfire optains package lists from the mirrors and can install and update \ + packages. +endef + +DIR_APP = $(DIR_SOURCE)/src + +define STAGE_BUILD + cd $(DIR_APP) && make VERSION="$(PKG_VER)" $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL_CMDS + cd $(DIR_APP) && make clean +endef diff --git a/pkgs/core/pakfire/src/Makefile b/pkgs/core/pakfire/src/Makefile new file mode 100644 index 0000000..d493db3 --- /dev/null +++ b/pkgs/core/pakfire/src/Makefile @@ -0,0 +1,20 @@ + +SUBSTITUDE = sed -e "s/@VERSION@/$(VERSION)/g" + +PYTHON_MAJ = "2.6" +PYTHON_DIR = $(DESTDIR)/usr/lib/python$(PYTHON_MAJ)/site-packages/pakfire + +all: pakfire + +pakfire: pakfire.in + $(SUBSTITUDE) pakfire.in > pakfire + +clean: + rm -vf pakfire python/*.py[co] + +install: pakfire + -mkdir -pv $(DESTDIR)/usr/bin + install -v -m 755 pakfire $(DESTDIR)/usr/bin + -mkdir -pv $(PYTHON_DIR) + cp -vf python/*.py $(PYTHON_DIR)/ + -mkdir -pv $(DESTDIR)/etc/pakfire.repos.d $(DESTDIR)/var/cache/pakfire diff --git a/pkgs/core/pakfire/src/decompressor b/pkgs/core/pakfire/src/decompressor new file mode 100755 index 0000000..667d0c6 --- /dev/null +++ b/pkgs/core/pakfire/src/decompressor @@ -0,0 +1,60 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +FILES= +ROOT=/ + +while [ $# -gt 0 ]; do + case "$1" in + --root=*) + ROOT=${1#--root=} + ;; + *.ipk) + file=$1 + [ ${file:0:1} != / ] && file="$(pwd)/$file" + if [ -e "$file" ]; then + FILES="$FILES $file" + else + echo "File does not exist: $file" >&2 + #exit 1 + fi + ;; + esac + shift +done + +if [ "$ROOT" != "/" ]; then + [ -d "$ROOT" ] || mkdir -p $ROOT + cd $ROOT + if [ "$(pwd)" != "$ROOT" ]; then + echo "Could not change to root: $ROOT" >&2 + exit 1 + fi +fi + +# Sort all packages +FILES=$(for i in $FILES; do echo $i; done | sort -u) + +for file in $FILES; do + echo "Extracting $file..." + cpio --extract --quiet -H newc --to-stdout data.img < $file | \ + tar --extract --xz -C ${ROOT} +done diff --git a/pkgs/core/pakfire/src/functions b/pkgs/core/pakfire/src/functions new file mode 100755 index 0000000..cd25d5d --- /dev/null +++ b/pkgs/core/pakfire/src/functions @@ -0,0 +1,96 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +function pkg_get_file() { + cpio --extract --quiet --to-stdout $1 < $2 +} + +function pkg_info() { + pkg_get_file info $1 +} + +function pkg_info_get() { + ( eval "$(pkg_info $2)" + echo ${!1} ) +} + +function pkg_data() { + pkg_get_file data.img $1 +} + +function pkg_control() { + pkg_get_file control $1 +} + +function pkg_verify() { + local pak=$1 + ( + eval $(pkg_info $pak | grep ^PKG_DATA_SHA1) + if [ "$(pkg_data $pak | sha1sum | awk '{ print $1 }')" = "$PKG_DATA_SHA1" ]; then + exit 0 + else + exit 1 + fi + ) + return $? +} + +### package properties + +function pkg_description() { + pkg_info_get PKG_DESCRIPTION $1 +} + +function pkg_deps() { + pkg_info_get PKG_DEPS $1 +} + +function pkg_group() { + pkg_info_get PKG_GROUP $1 +} + +function pkg_hash() { + sha1sum $1 | awk '{ print $1 }' +} + +function pkg_license() { + pkg_info_get PKG_LICENSE $1 +} + +function pkg_maintainer() { + pkg_info_get PKG_MAINTAINER $1 +} + +function pkg_name() { + pkg_info_get PKG_NAME $1 +} + +function pkg_release() { + pkg_info_get PKG_REL $1 +} + +function pkg_summary() { + pkg_info_get PKG_SUMMARY $1 +} + +function pkg_version() { + pkg_info_get PKG_VER $1 +} diff --git a/pkgs/core/pakfire/src/index b/pkgs/core/pakfire/src/index new file mode 100755 index 0000000..cd22f3f --- /dev/null +++ b/pkgs/core/pakfire/src/index @@ -0,0 +1,117 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +. functions + +db_fields="name version release group maintainer license summary description deps hash" +for field in $db_fields; do + if [ -n "${fields}" ]; then + fields="${fields}, '${field}'" + else + fields="'${field}'" + fi +done + + +function db() { + if [ -z "${database}" ]; then + echo "Database is not defined." + exit 1 + fi + #echo "SQL: $@" + sqlite3 ${database} "$@" +} + +while [ "$#" -gt "0" ]; do + case "$1" in + --database=*) + database=${1#--database=} + ;; + --force|-f) + FORCE=1 + ;; + *.ipk) + packages="${packages} ${1}" + ;; + *) + echo "Unrecognized option: "${1}"." + ;; + esac + shift +done + +if [ -e "${database}" ]; then + echo "Database "${database}" does already exist." + if [ "$FORCE" = "1" ]; then + > ${database} + else + exit 1 + fi +fi + +echo "Collecting available packages..." +available=$(for package in ${packages}; do + echo $(pkg_name $package) +done | sort -u) + +printf " There are %4d packages available.\n\n" $(echo "${available}" | wc -w) + +echo "Checking dependency tree..." +for package in ${packages}; do + #echo " ${package##*/}" + for dep in $(pkg_deps ${package}); do + okay= + for avail in ${available}; do + if [ "${dep}" = "${avail}" ]; then + okay=1 + break + fi + done + if [ "${okay}" != "1" ]; then + echo "Dependency "${dep}" of "${package##*/}" could not be resolved." + [ "${FORCE}" = "1" ] || exit 1 + fi + done +done + +echo "Creating database..." +db "CREATE TABLE packages($fields);" + +echo "Writing packages to database..." +for package in ${packages}; do + echo " ${package##*/}" + args= + IFS=$", " + for field in $db_fields; do + if [ -n "${args}" ]; then + args="${args}, "$(pkg_$field ${package})"" + else + args=""$(pkg_$field ${package})"" + fi + done + unset IFS + + db "INSERT INTO packages VALUES($args);" +done + +db "CREATE TABLE info(key, value);" +db "INSERT INTO info(key, value) VALUES('date', '$(date -u)');" +db "INSERT INTO info(key, value) VALUES('host', '$(cat /proc/sys/kernel/hostname)');" diff --git a/pkgs/core/pakfire/src/pakfire.in b/pkgs/core/pakfire/src/pakfire.in new file mode 100644 index 0000000..c861c33 --- /dev/null +++ b/pkgs/core/pakfire/src/pakfire.in @@ -0,0 +1,61 @@ +#!/usr/bin/python + +import sys + +from optparse import OptionParser + +import pakfire +from pakfire.package import Package +from pakfire.transactionset import Transactionset + +__version__ = "@VERSION@" + +op = OptionParser(usage="%prog [options] <action> ...", version="%prog " + __version__) +op.add_option("-r", "--root", dest="root", metavar="DIR") +op.add_option("-v", "--verbose", dest="verbose", + action="store_true", default=False, + help="Be verbose.") +op.add_option("-y", "--yes", dest="allyes", + action="store_true", default=False, + help="Answer all questions with "yes".") +op.add_option("--nogpgcheck", dest="gpgcheck", + action="store_false", default=True, + help="Omit gpg check (unsafe).") + +def usage(exit=1): + op.print_help() + sys.exit(exit) + +def parse_options(): + (options, args) = op.parse_args() + + # When no command was given + if not args: + usage() + + # The first argument is the action + action = args.pop(0) + if not action in ["install", "remove", "info", "provides",]: + op.error(""%s" is not a valid action." % action) + + if not args: + op.error("Action "%s" needs at least one argument.") + + return (action, options, args) + +(action, options, args) = parse_options() + +pakfire = pakfire.Pakfire() + +if action == "install": + pakfire.ts = Transactionset() + for a in args: + p = Package(a) + pakfire.ts.addPackage(p) + + pakfire.ts.run() + +elif action == "info": + for a in args: + p = Package(a) + print p.print_info() diff --git a/pkgs/core/pakfire/src/python/__init__.py b/pkgs/core/pakfire/src/python/__init__.py new file mode 100644 index 0000000..3e7012f --- /dev/null +++ b/pkgs/core/pakfire/src/python/__init__.py @@ -0,0 +1,11 @@ +#!/usr/bin/python + +from repo import Repositories +from transactionset import Transactionset + +class Pakfire(object): + repos = Repositories() + ts = Transactionset() + + def __init__(self): + pass diff --git a/pkgs/core/pakfire/src/python/db.py b/pkgs/core/pakfire/src/python/db.py new file mode 100644 index 0000000..d20ce57 --- /dev/null +++ b/pkgs/core/pakfire/src/python/db.py @@ -0,0 +1,52 @@ + + +from pysqlite2 import dbapi2 as sqlite + +DATABASE_PATH = "." + +class Database(object): + def __init__(self, filename): + self.filename = filename + + self.connection = sqlite.connect(self.filename) + + def add(self, table): + c = self.cursor + c.executescript("CREATE TABLE IF NOT EXISTS %s(id, key, value);" % table) + c.close() + + def commit(self): + self.connection.commit() + + def destroy(self, table): + c = self.cursor + c.execute("DELETE FROM %s" % table) + c.close() + self.commit() + + def get(self, table, id, key): + ret = None + c = self.cursor + c.execute("SELECT value FROM %s WHERE id='%s' AND key='%s';" % \ + (table, id, key,)) + try: + ret = c.fetchone()[0] + except TypeError: + pass + c.close() + return ret + + def set(self, table, id, key, value): + c = self.cursor + if not self.get(id, key): + c.execute("INSERT INTO %s(id, key, value) VALUES('%s', '%s', '%s');" \ + % (table, id, key, value,)) + else: + c.execute("UPDATE %s SET value='%s' WHERE id='%s' AND key='%s';" \ + % (table, value, id, key,)) + c.close() + self.commit() + + @property + def cursor(self): + return self.connection.cursor() diff --git a/pkgs/core/pakfire/src/python/io.py b/pkgs/core/pakfire/src/python/io.py new file mode 100644 index 0000000..6f06caa --- /dev/null +++ b/pkgs/core/pakfire/src/python/io.py @@ -0,0 +1,262 @@ +#!/usr/bin/python + +import grp +import os +import pwd +import stat +import time + +def ftype(mode): + if stat.S_ISBLK(mode): + return "b" + elif stat.S_ISCHR(mode): + return "c" + elif stat.S_ISDIR(mode): + return "d" + elif stat.S_ISREG(mode): + return "-" + elif stat.S_ISFIFO(mode): + return "p" + elif stat.S_ISLINK(mode): + return "l" + elif stat.S_ISSOCK(mode): + return "s" + return "?" + +def rwx(mode): + ret = "" + if mode & stat.S_IRUSR: + ret += "r" + else: + ret += "-" + + if mode & stat.S_IWUSR: + ret += "w" + else: + ret += "-" + + if mode & stat.S_IXUSR: + ret += "x" + else: + ret += "-" + + return ret + +def fmode(mode): + ret = ftype(mode) + ret += rwx((mode & 0700) << 0) + ret += rwx((mode & 0070) << 3) + ret += rwx((mode & 0007) << 6) + return ret + +class CpioError(Exception): + pass + + +class CpioEntry(object): + def __init__(self, hdr, archive, offset): + self.archive = archive + self.hdr = hdr + + self.offset = offset + 110 + self.namesize + self.offset += (4 - (self.offset % 4)) % 4 + self.current = 0 + + self.closed = False + + if len(self.hdr) < 110: + raise CpioError("Header too short.") + + if not self.hdr.startswith("070701") and not self.hdr.startswith("070702"): + raise CpioError("Invalid header: %s" % self.hdr[:6]) + + def close(self): + self.closed = True + + def flush(self): + pass # noop + + def read(self, size=None): + """Read data from the entry. + + Keyword arguments: + size -- Number of bytes to read (default: whole entry) + """ + if self.closed: + raise ValueError("Read operation on closed file.") + + self.archive.file.seek(self.offset + self.current, os.SEEK_SET) + + if size and size < self.size - self.current: + ret = self.archive.file.read(size) + else: + ret = self.archive.file.read(self.size - self.current) + self.current += len(ret) + return ret + + def seek(self, offset, whence=0): + """Move to new position within an entry. + + Keyword arguments: + offset -- Byte count + whence -- Describes how offset is used. + 0: From beginning of file + 1: Forwards from current position + 2: Backwards from current position + Other values are ignored. + """ + if self.closed: + raise ValueError("Seek operation on closed file.") + + if whence == os.SEEK_SET: + self.current = offset + elif whence == os.SEEK_REL: + self.current += offset + elif whence == os.SEEK_END: + self.current -= offset + + self.current = min(max(0, self.current), self.size) + + def tell(self): + """Get current position within an entry""" + if self.closed: + raise ValueError("Tell operation on closed file.") + return self.current + + def __repr__(self): + return "<CpioEntry %s 0x%s>" % (self.name, self.checksum,) + + @property + def checksum(self): + return int(self.hdr[102:110], 16) + + @property + def devmajor(self): + return int(self.hdr[62:70], 16) + + @property + def devminor(self): + return int(self.hdr[70:78], 16) + + @property + def gid(self): + return int(self.hdr[30:38], 16) + + @property + def inode(self): + return int(self.hdr[6:14], 16) + + @property + def mode(self): + return int(self.hdr[14:22], 16) + + @property + def mtime(self): + return int(self.hdr[46:54], 16) + + @property + def name(self): + end = 110 + self.namesize - 1 + return self.hdr[110:end] + + @property + def namesize(self): + return int(self.hdr[94:102], 16) + + @property + def nlinks(self): + return int(self.hdr[38:46], 16) + + @property + def rdevmajor(self): + return int(self.hdr[78:86], 16) + + @property + def rdevminor(self): + return int(self.hdr[86:94], 16) + + @property + def size(self): + return int(self.hdr[54:62], 16) + + @property + def uid(self): + return int(self.hdr[22:30], 16) + + +class CpioArchive(object): + _entries = [] + file = None + + def __init__(self, filename): + + self.filename = filename + self.file = open(self.filename, "r") + self.__readfile() + + self.closed = False + + def close(self): + if self.closed: + return + self.closed = True + + self.file.close() + + def __readfile(self): + if not self.file: + raise CpioError("File was not yet opened.") + + self._entries = [] + sposition = self.file.tell() + hdr = self.file.read(110) + while hdr: + namelen = int(hdr[94:102], 16) # Length of the name + hdr += self.file.read(namelen) + ce = CpioEntry(hdr, self, sposition) + if ce.name == "TRAILER!!!": + return + self._entries.append(ce) + + self.file.seek((4 - (self.file.tell()-sposition) % 4) % 4, os.SEEK_CUR) + self.file.seek(ce.size, os.SEEK_CUR) + self.file.seek((4 - (self.file.tell()-sposition) % 4) % 4, os.SEEK_CUR) + + sposition = self.file.tell() + hdr = self.file.read(110) + else: + raise CpioError("Premature end of headers.") + + @property + def entries(self): + return sorted(self._entries) + + @property + def size(self): + return os.path.getsize(self.filename) + + def ls(self): + for x in self.entries: + print x.name + + def ll(self): + for x in self.entries: + print "%s %s %s %s %9d %s %s" % \ + (fmode(x.mode), + x.nlinks, + pwd.getpwuid(x.uid)[0], + grp.getgrgid(x.gid)[0], + x.size, + time.strftime("%Y-%m-%d %H:%M", time.localtime(x.mtime)), + x.name,) + + def get(self, item): + for x in self.entries: + if x.name == item: + return x + raise KeyError("No such file or directory.") + + def __getitem__(self, item): + x = self.get(item) + x.seek(0) + return x.read() diff --git a/pkgs/core/pakfire/src/python/package.py b/pkgs/core/pakfire/src/python/package.py new file mode 100644 index 0000000..1f80b24 --- /dev/null +++ b/pkgs/core/pakfire/src/python/package.py @@ -0,0 +1,150 @@ +#!/usr/bin/python + +import hashlib +import os +import subprocess + +import io + +class Package(object): + _info = {} + + def __init__(self, archive): + self.archive = io.CpioArchive(archive) + + def check(self): + print "Checking package %s..." % self.name + return self.verify() + + def extract(self, root="/"): + if not os.path.exists(root): + os.makedirs(root) + + lzma = subprocess.Popen(["lzma", "-dc"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE,) + + cpio = subprocess.Popen(["cpio", + "--quiet", + "--extract", + "--unconditional", + "--make-directories", + "--no-absolute-filenames",], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=root) + + BUF = 1024 + file = self.archive["data.img"] + + # Decompress in one big swoop. + lzma.stdin.write(file) + lzma.stdin.close() + + lzmaerr = lzma.stderr.read() + if lzmaerr: + raise Exception("Decompression error: %s" % lzmaerr) + + while True: + buf = lzma.stdout.read(BUF) + if not buf: + break + cpio.stdin.write(buf) + lzma.stdout.close() + + cpioerr = cpio.stderr.read() + if cpioerr: + raise Exception("Archiving error: %s" % cpioerr) + + def install(self, root="/"): + print "Installing %s..." % self.name + self.extract(root) + + def print_info(self): + ret = "" + info = (("Name", self.name), + ("Version", self.version), + ("Arch", self.arch), + ("Release", self.release), + ("Size", self.size), + ("Summary", self.summary), + ("URL", self.url), + ("License", self.license), + ("Description", self.description)) + + for (key, value) in info: + ret += "%-12s: %s\n" % (key, value,) + + if self.verify: + ret += "%-12s: %s\n" % ("Signature", "OK") + else: + ret += "%-12s: %s\n" % ("Signature", "Broken") + + return ret + + def verify(self): + hash = hashlib.sha1(self.archive["data.img"]).hexdigest() + if hash == self.sha1: + return True + return False + + @property + def arch(self): + return self.info.get("PKG_ARCH", None) + + @property + def deps(self): + return self.info.get("PKG_DEPS", None) + + @property + def description(self): + return self.info.get("PKG_DESC", None) + + @property + def group(self): + return self.info.get("PKG_GROUP", None) + + @property + def license(self): + return self.info.get("PKG_LICENSE", None) + + @property + def name(self): + return self.info.get("PKG_NAME", None) + + @property + def info(self): + if not self._info: + self._info = {} + for line in self.archive["info"].split("\n"): + if not line or line.startswith("#"): + continue + (key, value) = line.split("=") + self._info[key] = value.strip(""") + return self._info + + @property + def release(self): + return self.info.get("PKG_REL", None) + + @property + def sha1(self): + return self.info.get("PKG_DATA_SHA1", None) + + @property + def size(self): + return self.archive.size + + @property + def summary(self): + return self.info.get("PKG_SUMMARY", None) + + @property + def url(self): + return self.info.get("PKG_URL", None) + + @property + def version(self): + return self.info.get("PKG_VER", None) diff --git a/pkgs/core/pakfire/src/python/repo.py b/pkgs/core/pakfire/src/python/repo.py new file mode 100644 index 0000000..f7f9c3b --- /dev/null +++ b/pkgs/core/pakfire/src/python/repo.py @@ -0,0 +1,88 @@ + +import os +import ConfigParser as configparser +import urlgrabber + +import db as database +from servers import Servers + +REPOS_PATH = "/etc/pakfire.repos.d" + +class Repositories(object): + _repositories = [] + + def __init__(self): + for file in os.listdir(REPOS_PATH): + if not file.endswith(".repo"): + continue + cp = configparser.ConfigParser() + cp.read(os.path.join(REPOS_PATH, file)) + for section in cp.sections(): + self._repositories.append(Repository(section, cp.items(section))) + + @property + def all(self): + return sorted(self._repositories) + + @property + def enabled(self): + ret = [] + for r in self._repositories: + if r.enabled: + ret.append(r) + return ret + + @property + def repositories(self): + return self.enabled + +class Repository(object): + def __init__(self, name, items=None): + self.name = name + + if items: + config = {} + for (key, value) in items: + config[key] = value + self.config = config + + self.db = database.Database("%s.db" % self.name) + self.servers = Servers(self.db) + + def __cmp__(self, other): + return cmp(self.name, other.name) + + def __str__(self): + return self.name + + def __repr__(self): + return "<Repository %s>" % self.name + + def update_mirrorlist(self, mirrorlist=None): + if not mirrorlist: + mirrorlist = self.mirrorlist + f = urlgrabber.urlopen(mirrorlist) + for line in f.readlines(): + self.servers.add(line) + f.close() + + @property + def enabled(self): + value = self.config.get("enabled") + if value == "1": + return True + return False + + @property + def gpgkey(self): + return self.config.get("gpgkey", None) + + @property + def mirrorlist(self): + return self.config.get("mirrorlist", None) + + +if __name__ == "__main__": + rs = Repositories() + for r in rs.repositories: + r.update_mirrorlist() diff --git a/pkgs/core/pakfire/src/python/servers.py b/pkgs/core/pakfire/src/python/servers.py new file mode 100644 index 0000000..32a83cd --- /dev/null +++ b/pkgs/core/pakfire/src/python/servers.py @@ -0,0 +1,88 @@ + +import random +import urlparse +import uuid + +SERVER_DEFAULT_PROTOCOL = "http" +SERVER_DEFAULT_PORT = "80" +SERVER_DEFAULT_PATH = "" + +class Servers(object): + table = "servers" + + def __init__(self, db): + self.db = db + self.db.add(self.table) + + def add(self, url): + p = urlparse.urlparse(url) + for server in self.all: + if str(server) == url: + return + server = Server(self.db) + (server.protocol, server.hostname, server.port, server.path) = \ + (p.scheme, p.hostname, p.port, p.path) + + @property + def all(self): + ret = [] + c = self.db.cursor + c.execute("SELECT DISTINCT id FROM %s" % self.table) + for id in c.fetchall(): + s = Server(self.db, id) + ret.append(s) + return sorted(ret) + + @property + def random(self): + return random.choice(self.all) + + +class Server(object): + table = Servers.table + + def __init__(self, db, id=None): + self.db = db + + if not id: + id = str(uuid.uuid4()) + self.id = "%s" % id + + def __str__(self): + return urlparse.urlunparse((self.protocol, \ + "%s:%s" % (self.hostname, self.port), self.path, None, None, None)) + + def __repr__(self): + return "<Server %s>" % self.id + + def _getHostname(self): + return self.db.get(self.table, self.id, "hostname") + + def _setHostname(self, hostname): + return self.db.set(self.table, self.id, "hostname", hostname) + + hostname = property(_getHostname, _setHostname) + + def _getProtocol(self): + return self.db.get(self.table, self.id, "protocol") or SERVER_DEFAULT_PROTOCOL + + def _setProtocol(self, protocol): + return self.db.set(self.table, self.id, "protocol", protocol) + + protocol = property(_getProtocol, _setProtocol) + + def _getPort(self): + return self.db.get(self.table, self.id, "port") or SERVER_DEFAULT_PORT + + def _setPort(self, port): + return self.db.set(self.table, self.id, "port", port) + + port = property(_getPort, _setPort) + + def _getPath(self): + return self.db.get(self.table, self.id, "path") or SERVER_DEFAULT_PATH + + def _setPath(self, path): + return self.db.set(self.table, self.id, "path", path) + + path = property(_getPath, _setPath) diff --git a/pkgs/core/pakfire/src/python/transactionset.py b/pkgs/core/pakfire/src/python/transactionset.py new file mode 100644 index 0000000..ed40bc3 --- /dev/null +++ b/pkgs/core/pakfire/src/python/transactionset.py @@ -0,0 +1,35 @@ + + +class Transactionset(object): + _packages = [] + + def __init__(self): + pass + + def addPackage(self, package): + self._packages.append(package) + + def check(self): + print "Checking Transactionset..." + for package in self.packages: + if not package.check(): + return False + return True + + def install(self, root="/"): + for package in self.packages: + package.install(root) + + def resolveDeps(self): + pass + + def run(self, root="/"): + print "Running transactionset..." + if self.check(): + self.install(root) + else: + print "Error, when verifying the packages..." + + @property + def packages(self): + return sorted(self._packages) diff --git a/pkgs/core/pam/login.defs b/pkgs/core/pam/login.defs new file mode 100644 index 0000000..b7f0ae1 --- /dev/null +++ b/pkgs/core/pam/login.defs @@ -0,0 +1,56 @@ +# *REQUIRED* +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define both, MAIL_DIR takes precedence. +# QMAIL_DIR is for Qmail +# +#QMAIL_DIR Maildir +MAIL_DIR /var/spool/mail +#MAIL_FILE .mail + +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_MIN_LEN Minimum acceptable password length. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 99999 +PASS_MIN_DAYS 0 +PASS_MIN_LEN 5 +PASS_WARN_AGE 7 + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 100 +GID_MAX 60000 + +# +# If defined, this command is run when removing a user. +# It should remove any at/cron/print jobs etc. owned by +# the user to be removed (passed as the first argument). +# +#USERDEL_CMD /usr/sbin/userdel_local + +# +# If useradd should create home directories for users by default +# On RH systems, we do. This option is overridden with the -m flag on +# useradd command line. +# +CREATE_HOME yes + +# The permission mask is initialized to this value. If not specified, +# the permission mask will be initialized to 022. +UMASK 077 + +# This enables userdel to remove user groups if no members exist. +# +USERGROUPS_ENAB yes + +DICTPATH /lib/cracklib/pw_dict diff --git a/pkgs/core/pam/pam.d/other b/pkgs/core/pam/pam.d/other new file mode 100644 index 0000000..c286c82 --- /dev/null +++ b/pkgs/core/pam/pam.d/other @@ -0,0 +1,5 @@ +#%PAM-1.0 +auth required pam_deny.so +account required pam_deny.so +password required pam_deny.so +session required pam_deny.so diff --git a/pkgs/core/pam/pam.d/system-auth b/pkgs/core/pam/pam.d/system-auth new file mode 100644 index 0000000..0fa221b --- /dev/null +++ b/pkgs/core/pam/pam.d/system-auth @@ -0,0 +1,23 @@ +#%PAM-1.0 +auth required pam_env.so +auth sufficient pam_unix.so nullok try_first_pass +auth requisite pam_succeed_if.so uid >= 500 quiet +auth sufficient pam_ldap.so use_first_pass +auth required pam_deny.so + +account required pam_unix.so broken_shadow +account sufficient pam_localuser.so +account sufficient pam_succeed_if.so uid < 500 quiet +account [default=bad success=ok user_unknown=ignore] pam_ldap.so +account required pam_permit.so + +password requisite pam_cracklib.so try_first_pass retry=3 +password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok +password sufficient pam_ldap.so use_authtok +password required pam_deny.so + +session optional pam_keyinit.so revoke +session required pam_limits.so +session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid +session required pam_unix.so +session optional pam_ldap.so diff --git a/pkgs/core/pam/pam.nm b/pkgs/core/pam/pam.nm new file mode 100644 index 0000000..e2c92fc --- /dev/null +++ b/pkgs/core/pam/pam.nm @@ -0,0 +1,83 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = Linux-PAM +PKG_VER = 1.1.0 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://www.us.kernel.org/pub/linux/libs/pam/index.html +PKG_LICENSE = BSD and GPLv2+ and BSD with advertising +PKG_SUMMARY = An extensible library which provides authentication for applications. + +PKG_BUILD_DEPS+= bison flex +PKG_DEPS += cracklib + +define PKG_DESCRIPTION + PAM (Pluggable Authentication Modules) is a system security tool that \ + allows system administrators to set authentication policy without \ + having to recompile programs that handle authentication. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --libdir=/lib \ + --sbindir=/lib/security \ + --enable-securedir=/lib/security \ + --docdir=/usr/share/doc/Linux-PAM-$(PKG_VER) \ + --enable-read-both-confs + + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/sbin + chmod -v 4755 $(BUILDROOT)/lib/security/unix_chkpwd + mv -v $(BUILDROOT)/lib/security/pam_tally $(BUILDROOT)/sbin + + -mkdir -pv $(BUILDROOT)/usr/lib + for LINK in libpam{,c,_misc}.so; do \ + ln -v -sf ../../lib/$$(readlink $(BUILDROOT)/lib/$${LINK}) \ + $(BUILDROOT)/usr/lib/$${LINK} && \ + rm -v $(BUILDROOT)/lib/$${LINK}; \ + done + + #useradd -D -b /home + #sed -i 's/yes/no/' $(BUILDROOT)/etc/default/useradd + -mkdir -pv $(BUILDROOT)/etc/security + install -v -m644 $(DIR_SOURCE)/pam_env.conf $(BUILDROOT)/etc/security/pam_env.conf + cp -vf $(DIR_SOURCE)/{login.defs,securetty} $(BUILDROOT)/etc +endef diff --git a/pkgs/core/pam/pam_env.conf b/pkgs/core/pam/pam_env.conf new file mode 100644 index 0000000..b691004 --- /dev/null +++ b/pkgs/core/pam/pam_env.conf @@ -0,0 +1,74 @@ +# +# This is the configuration file for pam_env, a PAM module to load in +# a configurable list of environment variables for a +# +# The original idea for this came from Andrew G. Morgan ... +#<quote> +# Mmm. Perhaps you might like to write a pam_env module that reads a +# default environment from a file? I can see that as REALLY +# useful... Note it would be an "auth" module that returns PAM_IGNORE +# for the auth part and sets the environment returning PAM_SUCCESS in +# the setcred function... +#</quote> +# +# What I wanted was the REMOTEHOST variable set, purely for selfish +# reasons, and AGM didn't want it added to the SimpleApps login +# program (which is where I added the patch). So, my first concern is +# that variable, from there there are numerous others that might/would +# be useful to be set: NNTPSERVER, LESS, PATH, PAGER, MANPAGER ..... +# +# Of course, these are a different kind of variable than REMOTEHOST in +# that they are things that are likely to be configured by +# administrators rather than set by logging in, how to treat them both +# in the same config file? +# +# Here is my idea: +# +# Each line starts with the variable name, there are then two possible +# options for each variable DEFAULT and OVERRIDE. +# DEFAULT allows and administrator to set the value of the +# variable to some default value, if none is supplied then the empty +# string is assumed. The OVERRIDE option tells pam_env that it should +# enter in its value (overriding the default value) if there is one +# to use. OVERRIDE is not used, "" is assumed and no override will be +# done. +# +# VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]] +# +# (Possibly non-existent) environment variables may be used in values +# using the ${string} syntax and (possibly non-existent) PAM_ITEMs may +# be used in values using the @{string} syntax. Both the $ and @ +# characters can be backslash escaped to be used as literal values +# values can be delimited with "", escaped " not supported. +# Note that many environment variables that you would like to use +# may not be set by the time the module is called. +# For example, HOME is used below several times, but +# many PAM applications don't make it available by the time you need it. +# +# +# First, some special variables +# +# Set the REMOTEHOST variable for any hosts that are remote, default +# to "localhost" rather than not being set at all +#REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST} +# +# Set the DISPLAY variable if it seems reasonable +#DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY} +# +# +# Now some simple variables +# +#PAGER DEFAULT=less +#MANPAGER DEFAULT=less +#LESS DEFAULT="M q e h15 z23 b80" +#NNTPSERVER DEFAULT=localhost +#PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\ +#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11 +# +# silly examples of escaped variables, just to show how they work. +# +#DOLLAR DEFAULT=$ +#DOLLARDOLLAR DEFAULT= OVERRIDE=$${DOLLAR} +#DOLLARPLUS DEFAULT=${REMOTEHOST}${REMOTEHOST} +#ATSIGN DEFAULT="" OVERRIDE=@ +PATH DEFAULT=/bin:/usr/bin OVERRIDE=${PATH} diff --git a/pkgs/core/pam/patches/Linux-PAM-1.1.0-no-yywrap-1.patch b/pkgs/core/pam/patches/Linux-PAM-1.1.0-no-yywrap-1.patch new file mode 100644 index 0000000..62a4851 --- /dev/null +++ b/pkgs/core/pam/patches/Linux-PAM-1.1.0-no-yywrap-1.patch @@ -0,0 +1,28 @@ +diff -urN Linux-PAM-0.99.6.3/conf/pam_conv1/pam_conv_l.c Linux-PAM-0.99.6.3.new/conf/pam_conv1/pam_conv_l.c +--- Linux-PAM-0.99.6.3/conf/pam_conv1/pam_conv_l.c 2006-09-06 11:29:19.000000000 +0200 ++++ Linux-PAM-0.99.6.3.new/conf/pam_conv1/pam_conv_l.c 2007-01-10 23:19:05.000000000 +0100 +@@ -494,7 +494,9 @@ + #ifdef __cplusplus + extern "C" int yywrap (void ); + #else +-extern int yywrap (void ); ++int yywrap (void ) { ++ return 1; ++} + #endif + #endif + +diff -urN Linux-PAM-0.99.6.3/doc/specs/parse_l.c Linux-PAM-0.99.6.3.new/doc/specs/parse_l.c +--- Linux-PAM-0.99.6.3/doc/specs/parse_l.c 2006-09-06 11:29:19.000000000 +0200 ++++ Linux-PAM-0.99.6.3.new/doc/specs/parse_l.c 2007-01-10 23:21:55.000000000 +0100 +@@ -480,7 +480,9 @@ + #ifdef __cplusplus + extern "C" int yywrap (void ); + #else +-extern int yywrap (void ); ++int yywrap (void ) { ++ return 1; ++} + #endif + #endif + diff --git a/pkgs/core/pam/securetty b/pkgs/core/pam/securetty new file mode 100644 index 0000000..f176d04 --- /dev/null +++ b/pkgs/core/pam/securetty @@ -0,0 +1,22 @@ +tty1 +tty2 +tty3 +tty4 +tty5 +tty6 +ttyp0 +ttyp1 +ttyp2 +ttyp3 +ttyp4 +ttyp5 +ttyp6 +ttyp7 +ttyp8 +ttyp9 +ttypa +ttypb +ttypc +ttypd +ttype +ttypf diff --git a/pkgs/core/pam_ldap/pam_ldap.nm b/pkgs/core/pam_ldap/pam_ldap.nm new file mode 100644 index 0000000..d754694 --- /dev/null +++ b/pkgs/core/pam_ldap/pam_ldap.nm @@ -0,0 +1,49 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pam_ldap +PKG_VER = 184 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://www.padl.com/OSS/pam_ldap.html +PKG_LICENSE = GPL and LGPL +PKG_SUMMARY = A pam/ldap module that supports password changes. + +PKG_DEPS += openldap + +define PKG_DESCRIPTION + The pam_ldap module provides the means for Solaris and Linux servers \ + and workstations to authenticate against LDAP directories, and to \ + change their passwords in the directory. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --libdir=/lib \ + --mandir=/usr/share/man diff --git a/pkgs/core/pango/pango.nm b/pkgs/core/pango/pango.nm new file mode 100644 index 0000000..61c2898 --- /dev/null +++ b/pkgs/core/pango/pango.nm @@ -0,0 +1,48 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pango +PKG_VER = 1.27.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.pango.org/ +PKG_LICENSE = LGPLv2+ +PKG_SUMMARY = System for layout and rendering of internationalized text. + +PKG_BUILD_DEPS+= pkg-config +PKG_DEPS += cairo fontconfig glib2 + +define PKG_DESCRIPTION + Pango is a library for laying out and rendering of text, with an \ + emphasis on internationalization. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc diff --git a/pkgs/core/parted/parted.nm b/pkgs/core/parted/parted.nm new file mode 100644 index 0000000..6ad8631 --- /dev/null +++ b/pkgs/core/parted/parted.nm @@ -0,0 +1,46 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = parted +PKG_VER = 2.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/System +PKG_URL = http://www.gnu.org/software/parted +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = The GNU disk partition manipulation program. + +PKG_DEPS += lvm2 readline util-linux-ng + +define PKG_DESCRIPTION + The GNU Parted program allows you to create, destroy, resize, move, \ + and copy hard disk partitions. Parted can be used for creating space \ + for new operating systems, reorganizing disk usage, and copying data \ + to new hard disks. +endef + +PKG_TARBALL = $(THISAPP).tar.gz diff --git a/pkgs/core/parted/patches/parted-2.1-blkid_topology_get_physical_sector_size.patch b/pkgs/core/parted/patches/parted-2.1-blkid_topology_get_physical_sector_size.patch new file mode 100644 index 0000000..c0d9c9f --- /dev/null +++ b/pkgs/core/parted/patches/parted-2.1-blkid_topology_get_physical_sector_size.patch @@ -0,0 +1,30 @@ +From 503c54ef274a923dcac337361936062b37a0ac1a Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Mon, 11 Jan 2010 11:46:36 +0100 +Subject: [PATCH parted 1/3] linux: use blkid_topology_get_physical_sector_size + +The official 2.17 release of util-linux-ng, has added a function to +get the physical sector size, use that instead of getting the +minimum io size. +* libparted/arch/linux.c(_device_set_sector_size): use +blkid_topology_get_physical_sector_size. +--- + libparted/arch/linux.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c +index aefe788..bf33059 100644 +--- a/libparted/arch/linux.c ++++ b/libparted/arch/linux.c +@@ -668,7 +668,7 @@ _device_set_sector_size (PedDevice* dev) + dev->path, strerror (errno), PED_SECTOR_SIZE_DEFAULT); + } else { + dev->phys_sector_size = +- blkid_topology_get_minimum_io_size( ++ blkid_topology_get_physical_sector_size( + arch_specific->topology); + } + #endif +-- +1.6.5.2 + diff --git a/pkgs/core/parted/patches/parted-2.1-dasd-NULL-dereference-rh563419.patch b/pkgs/core/parted/patches/parted-2.1-dasd-NULL-dereference-rh563419.patch new file mode 100644 index 0000000..477b7ae --- /dev/null +++ b/pkgs/core/parted/patches/parted-2.1-dasd-NULL-dereference-rh563419.patch @@ -0,0 +1,26 @@ +From 122bc980e27334d0f6243b74fffc8d2cefe0eb5c Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Wed, 10 Feb 2010 14:11:14 +0100 +Subject: [PATCH parted] dasd: Fix NULL pointer dereference in dasd_read + +* libparted/labels/dasd.c (dasd_read): Fix NULL ptr dereference. +--- + libparted/labels/dasd.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c +index 4b5840b..516d189 100644 +--- a/libparted/labels/dasd.c ++++ b/libparted/labels/dasd.c +@@ -399,7 +399,7 @@ dasd_read (PedDisk* disk) + + if (strncmp(PART_TYPE_SWAP, str, 6) == 0) { + fs = ped_file_system_probe(&part->geom); +- if (is_linux_swap(fs->name)) { ++ if (fs && is_linux_swap(fs->name)) { + dasd_data->system = PARTITION_LINUX_SWAP; + PDEBUG; + } +-- +1.6.6 + diff --git a/pkgs/core/parted/patches/parted-2.1-default-alignment.patch b/pkgs/core/parted/patches/parted-2.1-default-alignment.patch new file mode 100644 index 0000000..80cd47a --- /dev/null +++ b/pkgs/core/parted/patches/parted-2.1-default-alignment.patch @@ -0,0 +1,842 @@ +From 6c4c8464c704b645ddeccce4c4931b8e9d11c3a8 Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Fri, 29 Jan 2010 10:58:17 +0100 +Subject: [PATCH parted 1/7] linux: Fixup phys_sector_size setting + +1) Use the logical sector size as physical sector size instead of 512 + when not compiled with libblkid support, this fixes problems + with logical sector size > physical sector size. +2) blkid_topology_get_physical_sector_size() can return 0 when it could + not determine the physical sector size, handle this. +* libparted/arch/linux.c (_device_set_sector_size): Fixup +phys_sector_size setting. +--- + libparted/arch/linux.c | 17 +++++++++++------ + 2 files changed, 14 insertions(+), 6 deletions(-) + +diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c +index f3b54f0..4b7b9f5 100644 +--- a/libparted/arch/linux.c ++++ b/libparted/arch/linux.c +@@ -654,22 +654,27 @@ _device_set_sector_size (PedDevice* dev) + dev->path, strerror (errno), PED_SECTOR_SIZE_DEFAULT); + } else { + dev->sector_size = (long long)sector_size; ++ dev->phys_sector_size = dev->sector_size; + } + + #if USE_BLKID + get_blkid_topology(arch_specific); + if (!arch_specific->topology) { +- ped_exception_throw ( +- PED_EXCEPTION_WARNING, +- PED_EXCEPTION_OK, +- _("Could not determine minimum io size for %s: %s.\n" +- "Using the default size (%lld)."), +- dev->path, strerror (errno), PED_SECTOR_SIZE_DEFAULT); ++ dev->phys_sector_size = 0; + } else { + dev->phys_sector_size = + blkid_topology_get_physical_sector_size( + arch_specific->topology); + } ++ if (dev->phys_sector_size == 0) { ++ ped_exception_throw ( ++ PED_EXCEPTION_WARNING, ++ PED_EXCEPTION_OK, ++ _("Could not determine physical sector size for %s.\n" ++ "Using the logical sector size (%lld)."), ++ dev->path, dev->sector_size); ++ dev->phys_sector_size = dev->sector_size; ++ } + #endif + + #if defined __s390__ || defined __s390x__ +-- +1.6.6 + +From 4bb123a121b54d758f87fc6c38d8edab4ddc6d6b Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Fri, 29 Jan 2010 19:55:10 +0100 +Subject: [PATCH parted 2/7] libparted: Give device_get_*_alignment sane defaults + +When the topology info is incomplete or non existent, return something +more sensible then NULL (which ends up being interpreted as +PedAlignmentAny in most cases). The default minimum alignment aligns to +physical sector size, the default optimal alignment is 1 MiB, which is +what vista and windows 7 do. +* libparted/device.c (device_get_*_alignment): Add default aligments. +--- + libparted/device.c | 30 ++++++++++++++++++++++++++---- + 2 files changed, 33 insertions(+), 4 deletions(-) + +diff --git a/libparted/device.c b/libparted/device.c +index dda8d74..0f36a03 100644 +--- a/libparted/device.c ++++ b/libparted/device.c +@@ -501,10 +501,16 @@ ped_device_get_optimal_aligned_constraint(const PedDevice *dev) + PedAlignment* + ped_device_get_minimum_alignment(const PedDevice *dev) + { ++ PedAlignment *align = NULL; ++ + if (ped_architecture->dev_ops->get_minimum_alignment) +- return ped_architecture->dev_ops->get_minimum_alignment(dev); ++ align = ped_architecture->dev_ops->get_minimum_alignment(dev); ++ ++ if (align == NULL) ++ align = ped_alignment_new(0, ++ dev->phys_sector_size / dev->sector_size); + +- return NULL; /* ped_alignment_none */ ++ return align; + } + + /** +@@ -521,10 +527,26 @@ ped_device_get_minimum_alignment(const PedDevice *dev) + PedAlignment* + ped_device_get_optimum_alignment(const PedDevice *dev) + { ++ PedAlignment *align = NULL; ++ + if (ped_architecture->dev_ops->get_optimum_alignment) +- return ped_architecture->dev_ops->get_optimum_alignment(dev); ++ align = ped_architecture->dev_ops->get_optimum_alignment(dev); ++ ++ /* If the arch specific code could not give as an alignment ++ return a default value based on the type of device. */ ++ if (align == NULL) { ++ switch (dev->type) { ++ case PED_DEVICE_DASD: ++ align = ped_device_get_minimum_alignment(dev); ++ break; ++ default: ++ /* Align to a grain of 1MiB (like vista / win7) */ ++ align = ped_alignment_new(0, ++ 1048576 / dev->sector_size); ++ } ++ } + +- return NULL; /* ped_alignment_none */ ++ return align; + } + + /** @} */ +-- +1.6.6 + +From 82f42a9e059a8f5dea46090889914041204ebe36 Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Fri, 29 Jan 2010 19:59:06 +0100 +Subject: [PATCH parted 3/7] linux: handle incomplete topology information + +The topology information returned by libblkid is not always complete +(as the kernel does not always have complete information). +This patch makes the linux_get_*_alignment() alignment functions handle +this. The algorithm used for linux_get_optimum_alignment is: +1) Always use the reported aligment offset as offset +2a)If optimal io size is present in the topology info use that as grain +2b)If optimal io size is not present in topology info and aligment + offset is 0 and minimum io size is a power of 2, use the device.c + default optimal alignment (grain 1MiB). +2c)If not 2a and 2b, use the minimum io size, or if that is not defined + the physical sector size as grain (iow the minimum alignment). +The algorithm used for linux_get_minimum_alignment is: +1) Always use the reported aligment offset as offset +2) Use the minimum io size, or if that is not defined the physical + sector size as grain. +* libparted/arch/linux.c (linux_get_*_alignment): handle incomplete +topology information. +--- + libparted/arch/linux.c | 25 +++++++++++++++++++++---- + 1 files changed, 21 insertions(+), 4 deletions(-) + +diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c +index 4b7b9f5..a083028 100644 +--- a/libparted/arch/linux.c ++++ b/libparted/arch/linux.c +@@ -2564,9 +2564,14 @@ PedAlignment* + linux_get_minimum_alignment(const PedDevice *dev) + { + blkid_topology tp = LINUX_SPECIFIC(dev)->topology; ++ if (!tp) ++ return NULL; + +- if (!tp || blkid_topology_get_minimum_io_size(tp) == 0) +- return NULL; /* ped_alignment_none */ ++ if (blkid_topology_get_minimum_io_size(tp) == 0) ++ return ped_alignment_new( ++ blkid_topology_get_alignment_offset(tp) / ++ dev->sector_size, ++ dev->phys_sector_size / dev->sector_size); + + return ped_alignment_new( + blkid_topology_get_alignment_offset(tp) / dev->sector_size, +@@ -2577,9 +2582,21 @@ PedAlignment* + linux_get_optimum_alignment(const PedDevice *dev) + { + blkid_topology tp = LINUX_SPECIFIC(dev)->topology; ++ if (!tp) ++ return NULL; ++ ++ /* If optimal_io_size is 0 _and_ alignment_offset is 0 _and_ ++ minimum_io_size is a power of 2 then go with the device.c default */ ++ unsigned long minimum_io_size = blkid_topology_get_minimum_io_size(tp); ++ if (blkid_topology_get_optimal_io_size(tp) == 0 && ++ blkid_topology_get_alignment_offset(tp) == 0 && ++ (minimum_io_size & (minimum_io_size - 1)) == 0) ++ return NULL; + +- if (!tp || blkid_topology_get_optimal_io_size(tp) == 0) +- return NULL; /* ped_alignment_none */ ++ /* If optimal_io_size is 0 and we don't meet the other criteria ++ for using the device.c default, return the minimum alignment. */ ++ if (blkid_topology_get_optimal_io_size(tp) == 0) ++ return linux_get_minimum_alignment(dev); + + return ped_alignment_new( + blkid_topology_get_alignment_offset(tp) / dev->sector_size, +-- +1.6.6 + +From 4be1b004ad2c576fc093ca5227e22bb78b35f1fd Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Fri, 29 Jan 2010 23:28:13 +0100 +Subject: [PATCH parted 4/7] parted: Honor --align option also in mkpartfs, resize and print cmds + +parted/parted.c (do_mkpartfs,do_print,do_resize): honor --align +--- + parted/parted.c | 26 +++++++++++++++++++++++++- + 1 files changed, 25 insertions(+), 1 deletions(-) + +diff --git a/parted/parted.c b/parted/parted.c +index c4d1779..5ba8bbf 100644 +--- a/parted/parted.c ++++ b/parted/parted.c +@@ -949,6 +949,11 @@ do_mkpartfs (PedDevice** dev) + if (!disk) + goto error; + ++ if (ped_disk_is_flag_available(disk, PED_DISK_CYLINDER_ALIGNMENT)) ++ if (!ped_disk_set_flag(disk, PED_DISK_CYLINDER_ALIGNMENT, ++ alignment == ALIGNMENT_CYLINDER)) ++ goto error_destroy_disk; ++ + if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)) { + part_type = PED_PARTITION_NORMAL; + } else { +@@ -989,7 +994,14 @@ do_mkpartfs (PedDevice** dev) + range_end); + PED_ASSERT (user_constraint != NULL, return 0); + +- dev_constraint = ped_device_get_constraint (*dev); ++ if (alignment == ALIGNMENT_OPTIMAL) ++ dev_constraint = ++ ped_device_get_optimal_aligned_constraint(*dev); ++ else if (alignment == ALIGNMENT_MINIMAL) ++ dev_constraint = ++ ped_device_get_minimal_aligned_constraint(*dev); ++ else ++ dev_constraint = ped_device_get_constraint(*dev); + PED_ASSERT (dev_constraint != NULL, return 0); + + final_constraint = ped_constraint_intersect (user_constraint, +@@ -1353,6 +1365,11 @@ do_print (PedDevice** dev) + if (!disk) + goto error; + ++ if (ped_disk_is_flag_available(disk, PED_DISK_CYLINDER_ALIGNMENT)) ++ if (!ped_disk_set_flag(disk, PED_DISK_CYLINDER_ALIGNMENT, ++ alignment == ALIGNMENT_CYLINDER)) ++ goto error_destroy_disk; ++ + peek_word = command_line_peek_word (); + if (peek_word) { + if (strncmp (peek_word, "devices", 7) == 0) { +@@ -1697,6 +1697,7 @@ do_print (PedDevice** dev) + + return 1; + ++error_destroy_disk: + ped_disk_destroy (disk); + error: + return 0; +@@ -1862,6 +1881,11 @@ do_resize (PedDevice** dev) + if (!disk) + goto error; + ++ if (ped_disk_is_flag_available(disk, PED_DISK_CYLINDER_ALIGNMENT)) ++ if (!ped_disk_set_flag(disk, PED_DISK_CYLINDER_ALIGNMENT, ++ alignment == ALIGNMENT_CYLINDER)) ++ goto error_destroy_disk; ++ + if (!command_line_get_partition (_("Partition number?"), disk, &part)) + goto error_destroy_disk; + if (part->type != PED_PARTITION_EXTENDED) { +-- +1.6.6 + +From 950bfc92b1a67c8baa8c7cfab04103bd38a2d24b Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Fri, 29 Jan 2010 22:51:30 +0100 +Subject: [PATCH parted 5/7] parted: change warnings when initial constrained mkpart fails + +In do_mkpart we first try to create a partition using a constraint +derived from the user input intersected with the devices alignment +needs. And if that fails we try again without any constraint. + +However the warning given when this happens only takes into account +the user not getting what he asked for, while the alignment might be +a problem too (or even the only problem). So this patch adds a check +to see if the user really did not get what he asked before giving that +warning, and adds a new check + warning to see if the created partition +is properly aligned. +*parted/parted.c (do_mkpart,do_mkpartfs): change warnings when initial +constrained mkpart fails. +--- + parted/parted.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 files changed, 52 insertions(+), 7 deletions(-) + +diff --git a/parted/parted.c b/parted/parted.c +index 5ba8bbf..3ce356f 100644 +--- a/parted/parted.c ++++ b/parted/parted.c +@@ -178,6 +178,8 @@ static TimerContext timer_context; + + static int _print_list (); + static void _done (PedDevice* dev); ++static bool partition_align_check (PedDisk const *disk, ++ PedPartition const *part, enum AlignmentType a_type); + + static void + _timer_handler (PedTimer* timer, void* context) +@@ -833,7 +835,12 @@ do_mkpart (PedDevice** dev) + bool added_ok = ped_disk_add_partition (disk, part, + constraint_any); + ped_constraint_destroy (constraint_any); +- if (added_ok) { ++ ++ if (!added_ok) ++ goto error_remove_part; ++ ++ if (!ped_geometry_test_sector_inside(range_start, part->geom.start) || ++ !ped_geometry_test_sector_inside(range_end, part->geom.end)) { + start_usr = ped_unit_format (*dev, start); + end_usr = ped_unit_format (*dev, end); + start_sol = ped_unit_format (*dev, part->geom.start); +@@ -867,8 +874,23 @@ do_mkpart (PedDevice** dev) + /* undo partition addition */ + goto error_remove_part; + } +- } else { +- goto error_remove_part; ++ } ++ ++ if ((alignment == ALIGNMENT_OPTIMAL && ++ !partition_align_check(disk, part, PA_OPTIMUM)) || ++ (alignment == ALIGNMENT_MINIMAL && ++ !partition_align_check(disk, part, PA_MINIMUM))) { ++ if (ped_exception_throw( ++ PED_EXCEPTION_WARNING, ++ (opt_script_mode ++ ? PED_EXCEPTION_OK ++ : PED_EXCEPTION_IGNORE_CANCEL), ++ _("The resulting partition is not properly " ++ "aligned for best performance.")) == ++ PED_EXCEPTION_CANCEL) { ++ /* undo partition addition */ ++ goto error_remove_part; ++ } + } + } else { + ped_exception_leave_all(); +@@ -1018,8 +1040,16 @@ do_mkpartfs (PedDevice** dev) + if (!added_ok) { + ped_exception_leave_all(); + +- if (ped_disk_add_partition (disk, part, +- ped_constraint_any (*dev))) { ++ PedConstraint *constraint_any = ped_constraint_any (*dev); ++ bool added_ok = ped_disk_add_partition (disk, part, ++ constraint_any); ++ ped_constraint_destroy (constraint_any); ++ ++ if (!added_ok) ++ goto error_remove_part; ++ ++ if (!ped_geometry_test_sector_inside(range_start, part->geom.start) || ++ !ped_geometry_test_sector_inside(range_end, part->geom.end)) { + start_usr = ped_unit_format (*dev, start); + end_usr = ped_unit_format (*dev, end); + start_sol = ped_unit_format (*dev, part->geom.start); +@@ -1048,8 +1078,23 @@ do_mkpartfs (PedDevice** dev) + /* undo partition addition */ + goto error_remove_part; + } +- } else { +- goto error_remove_part; ++ } ++ ++ if ((alignment == ALIGNMENT_OPTIMAL && ++ !partition_align_check(disk, part, PA_OPTIMUM)) || ++ (alignment == ALIGNMENT_MINIMAL && ++ !partition_align_check(disk, part, PA_MINIMUM))) { ++ if (ped_exception_throw( ++ PED_EXCEPTION_WARNING, ++ (opt_script_mode ++ ? PED_EXCEPTION_OK ++ : PED_EXCEPTION_IGNORE_CANCEL), ++ _("The resulting partition is not properly " ++ "aligned for best performance.")) == ++ PED_EXCEPTION_CANCEL) { ++ /* undo partition addition */ ++ goto error_remove_part; ++ } + } + } else { + ped_exception_leave_all(); +-- +1.6.6 + +From 6c2db872647816b84a5efc8c8995a019d47f89a9 Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Sat, 30 Jan 2010 17:46:23 +0100 +Subject: [PATCH parted 6/7] Makefiles: Fix check-other-sector_sizes + +Atleast on my system check-other-sector_sizes was actually just testing +512 bytes sectors 4 times. This fixes this. +* Makefile.am: Fix check-other-sector_sizes +--- + Makefile.am | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 0e80967..d5a32ef 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -1415,7 +1415,7 @@ MAINTAINERCLEANFILES += \ + + .PHONY: ss-1024 ss-2048 ss-4096 + ss-1024 ss-2048 ss-4096: +- PARTED_SECTOR_SIZE=$(ss-,,$@) $(MAKE) check-recursive ++ PARTED_SECTOR_SIZE=$(subst ss-,,$@) $(MAKE) check-recursive + + # Run the regression test suite with different settings, + # to ensure it works with simulated partition sizes > 512. +-- +1.6.6 + +From 6ba62ce27f84c5c931d021f4be4af0cce011bdbf Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Fri, 29 Jan 2010 20:30:18 +0100 +Subject: [PATCH parted 7/7] parted: Change default alignment to optimal + +parted/parted.c: change --align default value to optimal +tests/*.sh: adjust for alignment changes where necessary +--- + parted/parted.c | 2 +- + tests/t0220-gpt-msftres.sh | 4 ++-- + tests/t0280-gpt-corrupt.sh | 6 +++--- + tests/t2100-mkswap.sh | 14 +++++++------- + tests/t2200-dos-label-recog.sh | 11 ++++++----- + tests/t2300-dos-label-extended-bootcode.sh | 12 ++++++------ + tests/t3000-resize-fs.sh | 4 ++-- + tests/t4100-dvh-partition-limits.sh | 4 +++- + tests/t4100-msdos-partition-limits.sh | 22 +++++----------------- + tests/t4100-msdos-starting-sector.sh | 10 +++++----- + tests/t5000-tags.sh | 6 +++--- + tests/t8000-loop.sh | 1 + + tests/t9021-maxima.sh | 3 ++- + 14 files changed, 49 insertions(+), 53 deletions(-) + +diff --git a/parted/parted.c b/parted/parted.c +index 3ce356f..e35ce6a 100644 +--- a/parted/parted.c ++++ b/parted/parted.c +@@ -133,7 +133,7 @@ int pretend_input_tty = 0; + int opt_machine_mode = 0; + int disk_is_modified = 0; + int is_toggle_mode = 0; +-int alignment = ALIGNMENT_CYLINDER; ++int alignment = ALIGNMENT_OPTIMAL; + + static const char* number_msg = N_( + "NUMBER is the partition number used by Linux. On MS-DOS disk labels, the " +diff --git a/tests/t0220-gpt-msftres.sh b/tests/t0220-gpt-msftres.sh +index 8ef885f..bbc415b 100755 +--- a/tests/t0220-gpt-msftres.sh ++++ b/tests/t0220-gpt-msftres.sh +@@ -35,8 +35,8 @@ NTFS + reiserfs + ' + +-start=200 +-part_size=100 ++start=2048 ++part_size=2048 + n_types=$(echo "$fs_types"|wc -w) + + # Create a "disk" with enough room for one partition per FS type, +diff --git a/tests/t0280-gpt-corrupt.sh b/tests/t0280-gpt-corrupt.sh +index 28c9035..5c48116 100755 +--- a/tests/t0280-gpt-corrupt.sh ++++ b/tests/t0280-gpt-corrupt.sh +@@ -43,7 +43,7 @@ poke() + dev=loop-file + + ss=$sector_size_ +-n_sectors=200 ++n_sectors=5000 + + fail=0 + dd if=/dev/null of=$dev bs=$ss seek=$n_sectors || fail=1 +@@ -62,7 +62,7 @@ printf "BYT;\n$dev:${n_sectors}s:file:$sector_size_:$sector_size_:gpt:;\n" \ + compare exp out || fail=1 + + # create a partition +-parted -s $dev mkpart sw linux-swap 60s 100s > empty 2>&1 || fail=1 ++parted -s $dev mkpart sw linux-swap 2048s 4095s > empty 2>&1 || fail=1 + compare /dev/null empty || fail=1 + + # We're going to change the name of the first partition, +@@ -123,7 +123,7 @@ compare exp err || fail=1 + parted -m -s $dev u s print > out 2>&1 || fail=1 + + # check for expected output +-printf "BYT;\nfile\n1:60s:100s:41s::foo:;\n" > exp || fail=1 ++printf "BYT;\nfile\n1:2048s:4095s:2048s::foo:;\n" > exp || fail=1 + sed "s/.*gpt:;/file/" out > k && mv k out || fail=1 + compare exp out || fail=1 + +diff --git a/tests/t2100-mkswap.sh b/tests/t2100-mkswap.sh +index 1462e5d..1e4c444 100755 +--- a/tests/t2100-mkswap.sh ++++ b/tests/t2100-mkswap.sh +@@ -27,7 +27,7 @@ require_512_byte_sector_size_ + # table, ensure that the proper file system type (0x82) is used. + # Some releases, e.g. parted-1.8.8 would mistakenly use 0x83. + ###################################################################### +-N=1M ++N=2M + dev=loop-file + dev2=loop-file-2 + test_expect_success \ +@@ -41,7 +41,7 @@ test_expect_success 'expect no output' 'compare out /dev/null' + + test_expect_success \ + 'create a partition' \ +- 'parted -s $dev mkpart primary 0 1 > out 2>&1' ++ 'parted -s $dev mkpart primary 2048s 4095s > out 2>&1' + test_expect_success 'expect no output' 'compare out /dev/null' + + test_expect_success \ +@@ -66,7 +66,7 @@ test_expect_success 'expect no output' 'compare out /dev/null' + + test_expect_success \ + 'create another partition' \ +- 'parted -s $dev2 mkpart primary 0 1 > out 2>&1' ++ 'parted -s $dev2 mkpart primary 2048s 4095s > out 2>&1' + test_expect_success 'expect no output' 'compare out /dev/null' + + test_expect_success \ +@@ -74,13 +74,13 @@ test_expect_success \ + 'parted -s $dev2 mkfs 1 "linux-swap(v1)" > out 2>&1' + test_expect_success 'expect no output' 'compare out /dev/null' + +-# partition starts at offset 16384; swap UUID is 1036 bytes in ++# partition starts at offset 1048576; swap UUID is 1036 bytes in + test_expect_success \ + 'extract UUID 1' \ +- 'od -t x1 -An -j17420 -N16 $dev > uuid1' ++ 'od -t x1 -An -j1049612 -N16 $dev > uuid1' + test_expect_success \ + 'extract UUID 2' \ +- 'od -t x1 -An -j17420 -N16 $dev2 > uuid2' ++ 'od -t x1 -An -j1049612 -N16 $dev2 > uuid2' + test_expect_failure \ + 'two linux-swap file systems have different UUIDs' \ + 'compare uuid1 uuid2' +@@ -92,7 +92,7 @@ test_expect_success 'expect no output' 'compare out /dev/null' + + test_expect_success \ + 'extract new UUID 2' \ +- 'od -t x1 -An -j17420 -N16 $dev2 > uuid2-new' ++ 'od -t x1 -An -j1049612 -N16 $dev2 > uuid2-new' + test_expect_success \ + 'check preserves linux-swap UUID' \ + 'compare uuid2 uuid2-new' +diff --git a/tests/t2200-dos-label-recog.sh b/tests/t2200-dos-label-recog.sh +index 1254226..92e6d42 100755 +--- a/tests/t2200-dos-label-recog.sh ++++ b/tests/t2200-dos-label-recog.sh +@@ -25,11 +25,12 @@ test_description='improved MSDOS partition-table recognition' + # parted 1.8.8.1.29 and earlier would fail to recognize a DOS + # partition table. + ###################################################################### +-N=10M ++ss=$sector_size_ ++N=8192 + dev=loop-file + test_expect_success \ + 'create a file to simulate the underlying device' \ +- 'dd if=/dev/null of=$dev bs=1 seek=$N 2> /dev/null' ++ 'dd if=/dev/null of=$dev bs=$ss seek=$N 2> /dev/null' + + test_expect_success \ + 'label the test disk' \ +@@ -39,8 +40,8 @@ test_expect_success 'expect no output' 'compare out /dev/null' + test_expect_success \ + 'create two partition' \ + ' +- parted -s $dev mkpart primary 1s 40s > out 2>&1 && +- parted -s $dev mkpart primary 41s 80s >> out 2>&1 ++ parted -s $dev mkpart primary 2048s 4095s > out 2>&1 && ++ parted -s $dev mkpart primary 4096s 8191s >> out 2>&1 + + ' + test_expect_success 'expect no output' 'compare out /dev/null' +@@ -54,7 +55,7 @@ test_expect_success \ + ' + parted -m -s $dev unit s p > out && + tail -2 out > k && mv k out && +- printf "1:1s:40s:40s:::;\n2:41s:80s:40s:::;\n" > exp ++ printf "1:2048s:4095s:2048s:::;\n2:4096s:8191s:4096s:::;\n" > exp + + ' + test_expect_success 'expect two partitions' 'compare out exp' +diff --git a/tests/t2300-dos-label-extended-bootcode.sh b/tests/t2300-dos-label-extended-bootcode.sh +index 6f2b219..73fa45b 100755 +--- a/tests/t2300-dos-label-extended-bootcode.sh ++++ b/tests/t2300-dos-label-extended-bootcode.sh +@@ -27,7 +27,7 @@ bootcode_size=446 + + test_expect_success \ + 'Create the test file' \ +- 'dd if=/dev/zero of=$dev bs=1024c count=100 >/dev/null 2>&1' ++ 'dd if=/dev/zero of=$dev bs=1M count=4 >/dev/null 2>&1' + + test_expect_success \ + 'Create msdos label' \ +@@ -36,23 +36,23 @@ test_expect_success 'Expect no output' 'compare out /dev/null' + + test_expect_success \ + 'Create extended partition' \ +- 'parted -s $dev mkpart extended 32s 127s > out 2>&1' ++ 'parted -s $dev mkpart extended 2048s 8191s > out 2>&1' + test_expect_success 'Expect no output' 'compare out /dev/null' + + test_expect_success \ + 'Create logical partition' \ +- 'parted -s $dev mkpart logical 64s 127s > out 2>&1' ++ 'parted -s $dev mkpart logical 4096s 8191s > out 2>&1' + test_expect_success 'Expect no output' 'compare out /dev/null' + + test_expect_success \ + 'Install fake bootcode' \ + 'printf %0${bootcode_size}d 0 > in && +- dd if=in of=$dev bs=1c seek=16384 count=$bootcode_size \ ++ dd if=in of=$dev bs=1c seek=1M count=$bootcode_size \ + conv=notrunc > /dev/null 2>&1' + + test_expect_success \ + 'Save fake bootcode for later comparison' \ +- 'dd if=$dev of=before bs=1 skip=16384 count=$bootcode_size > /dev/null 2>&1' ++ 'dd if=$dev of=before bs=1 skip=1M count=$bootcode_size > /dev/null 2>&1' + + test_expect_success \ + 'Do something to the label' \ +@@ -61,7 +61,7 @@ test_expect_success 'Expect no output' 'compare out /dev/null' + + test_expect_success \ + 'Extract the bootcode for comparison' \ +- 'dd if=$dev of=after bs=1 skip=16384 count=$bootcode_size > /dev/null 2>&1' ++ 'dd if=$dev of=after bs=1 skip=1M count=$bootcode_size > /dev/null 2>&1' + + test_expect_success \ + 'Expect bootcode has not changed' \ +diff --git a/tests/t3000-resize-fs.sh b/tests/t3000-resize-fs.sh +index 2abc71b..d6af67d 100755 +--- a/tests/t3000-resize-fs.sh ++++ b/tests/t3000-resize-fs.sh +@@ -64,8 +64,8 @@ for fs_type in hfs+ fat32; do + + # create an empty $fs_type partition, cylinder aligned, size > 256 MB + parted -s $dev mkpart primary $fs_type $start $default_end > out 2>&1 || fail=1 +- # expect no output +- compare out /dev/null || fail=1 ++ echo "Warning: The resulting partition is not properly aligned for best performance." > exp ++ compare out exp || fail=1 + + # print partition table + parted -m -s $dev u s p > out 2>&1 || fail=1 +diff --git a/tests/t4100-dvh-partition-limits.sh b/tests/t4100-dvh-partition-limits.sh +index 01e3078..17b1530 100755 +--- a/tests/t4100-dvh-partition-limits.sh ++++ b/tests/t4100-dvh-partition-limits.sh +@@ -33,11 +33,13 @@ fs=fs_file + mp=`pwd`/mount-point + n=4096 + ++# We must use -f otherwise newer mkfs.xfs fail with: ++# mkfs.xfs: probe of test.img failed, cannot detect existing filesystem. + test_expect_success \ + 'create an XFS file system' \ + ' + dd if=/dev/zero of=$fs bs=1MB count=2 seek=20 && +- mkfs.xfs -q $fs && ++ mkfs.xfs -f -q $fs && + mkdir "$mp" + + ' +diff --git a/tests/t4100-msdos-partition-limits.sh b/tests/t4100-msdos-partition-limits.sh +index 0c5b404..b9f168a 100755 +--- a/tests/t4100-msdos-partition-limits.sh ++++ b/tests/t4100-msdos-partition-limits.sh +@@ -33,11 +33,13 @@ fs=fs_file + mp=`pwd`/mount-point + n=4096 + ++# We must use -f otherwise newer mkfs.xfs fail with: ++# mkfs.xfs: probe of test.img failed, cannot detect existing filesystem. + test_expect_success \ + 'create an XFS file system' \ + ' + dd if=/dev/zero of=$fs bs=1MB count=2 seek=20 && +- mkfs.xfs -q $fs && ++ mkfs.xfs -f -q $fs && + mkdir "$mp" + + ' +@@ -102,27 +104,13 @@ test_expect_success \ + 'check for new diagnostic' \ + 'bad_part_length 4294967296 > exp && diff -u err exp' + +-# FIXME: investigate this. +-# Unexpectedly to me, both of these failed with this same diagnostic: +-# +-# Error: partition length of 4294967296 sectors exceeds the \ +-# DOS-partition-table-imposed maximum of 2^32-1" > exp && +-# +-# I expected the one below to fail with a length of _4294967297_. +-# Debugging, I see that _check_partition *does* detect this, +-# but the diagnostic doesn't get displayed because of the wonders +-# of parted's exception mechanism. +- + test_expect_failure \ + "$table_type: a partition length of 2^32+1 sectors provokes failure." \ + 'do_mkpart $n $(echo $n+2^32|bc) > err 2>&1' + +-# FIXME: odd that we asked for 2^32+1, yet the diagnostic says 2^32 +-# FIXME: Probably due to constraints. +-# FIXME: For now, just accept the current output. + test_expect_success \ + 'check for new diagnostic' \ +- 'bad_part_length 4294967296 > exp && diff -u err exp' ++ 'bad_part_length 4294967297 > exp && diff -u err exp' + + # ========================================================= + # Now consider partition starting sector numbers. +@@ -164,7 +152,7 @@ test_expect_failure \ + 'do_mkpart_start_and_len $(echo 2^32+1|bc) 1000 > err 2>&1' + test_expect_success \ + 'check for new diagnostic' \ +- 'bad_start_sector 4294967296 > exp && diff -u err exp' ++ 'bad_start_sector 4294967297 > exp && diff -u err exp' + + done + +diff --git a/tests/t4100-msdos-starting-sector.sh b/tests/t4100-msdos-starting-sector.sh +index 7761e75..3d0233b 100755 +--- a/tests/t4100-msdos-starting-sector.sh ++++ b/tests/t4100-msdos-starting-sector.sh +@@ -27,7 +27,7 @@ ss=$sector_size_ + # consistent in the use of metadata padding for msdos labels. + ###################################################################### + +-N=200 # number of sectors ++N=4096 # number of sectors + dev=loop-file + test_expect_success \ + 'create a file to simulate the underlying device' \ +@@ -43,7 +43,7 @@ fail=0 + cat <<EOF > exp || fail=1 + BYT; + path:${N}s:file:$ss:$ss:msdos:; +-1:32s:127s:96s:free; ++1:32s:4095s:4064s:free; + EOF + + test_expect_success 'create expected output file' 'test $fail = 0' +@@ -62,15 +62,15 @@ fail=0 + cat <<EOF > exp || fail=1 + BYT; + path:${N}s:file:$ss:$ss:msdos:; +-1:32s:50s:19s:free; +-1:51s:199s:149s:::; ++1:32s:2047s:2016s:free; ++1:2048s:4095s:2048s:::; + EOF + + test_expect_success 'create expected output file' 'test $fail = 0' + + test_expect_success \ + 'create a partition at the end of the label' \ +- 'parted -s $dev mkpart primary 51s 199s' ++ 'parted -s $dev mkpart primary 2048s 4095s' + + test_expect_success \ + 'display output of label with partition' \ +diff --git a/tests/t5000-tags.sh b/tests/t5000-tags.sh +index d1e9533..9b0a1cc 100755 +--- a/tests/t5000-tags.sh ++++ b/tests/t5000-tags.sh +@@ -22,10 +22,10 @@ test_description="test bios_grub flag in gpt labels" + ss=$sector_size_ + + dev=loop-file +-N=300 # number of sectors ++N=4200 # number of sectors + +-part_sectors=128 +-start_sector=60 ++part_sectors=2048 ++start_sector=2048 + end_sector=$(expr $start_sector + $part_sectors - 1) + + test_expect_success \ +diff --git a/tests/t8000-loop.sh b/tests/t8000-loop.sh +index 313e3b8..cba3454 100755 +--- a/tests/t8000-loop.sh ++++ b/tests/t8000-loop.sh +@@ -25,6 +25,7 @@ fi + . $srcdir/t-lib.sh + + require_root_ ++lvm_init_root_dir_ + + d1= f1= + cleanup_() +diff --git a/tests/t9021-maxima.sh b/tests/t9021-maxima.sh +index 999a696..c8316bc 100755 +--- a/tests/t9021-maxima.sh ++++ b/tests/t9021-maxima.sh +@@ -25,6 +25,7 @@ fi + . $srcdir/t-lib.sh + + fail=0 ++ss=$sector_size_ + dev=dev-file + PATH="..:$PATH" + export PATH +@@ -33,7 +34,7 @@ export PATH + for t in msdos gpt dvh sun mac bsd amiga loop pc98; do + echo $t + rm -f $dev +- dd if=/dev/zero of=$dev bs=512 count=1 seek=10000 || { fail=1; continue; } ++ dd if=/dev/zero of=$dev bs=$ss count=1 seek=10000 || { fail=1; continue; } + parted -s $dev mklabel $t || { fail=1; continue; } + + #case $t in pc98) sleep 999d;; esac +-- +1.6.6 + diff --git a/pkgs/core/parted/patches/parted-2.1-gpt-clobber-pmbr-rh563211.patch b/pkgs/core/parted/patches/parted-2.1-gpt-clobber-pmbr-rh563211.patch new file mode 100644 index 0000000..2c3e030 --- /dev/null +++ b/pkgs/core/parted/patches/parted-2.1-gpt-clobber-pmbr-rh563211.patch @@ -0,0 +1,146 @@ +From 28be933ce317f954be1e39a50d8f42197d6e3c15 Mon Sep 17 00:00:00 2001 +From: Jim Meyering <meyering@redhat.com> +Date: Sun, 7 Feb 2010 20:31:11 +0100 +Subject: [PATCH parted 01/10] gpt: read-only operation could clobber MBR part of hybrid GPT+MBR table + +* libparted/labels/gpt.c (gpt_read): Fix a bug introduced by me in +commit 7f753b1b, "gpt: rewrite GPT header-reading code". +Set write_back=0 in one more code path. +* tests/Makefile.am (TESTS): Add t0205-gpt-list-clobbers-pmbr.sh. +* tests/t0205-gpt-list-clobbers-pmbr.sh: New test. +Reported by aix27249 in +http://parted.alioth.debian.org/cgi-bin/trac.cgi/ticket/250 +--- + libparted/labels/gpt.c | 10 ++++-- + tests/Makefile.am | 1 + + tests/t0205-gpt-list-clobbers-pmbr.sh | 59 +++++++++++++++++++++++++++++++++ + 4 files changed, 72 insertions(+), 3 deletions(-) + create mode 100644 tests/t0205-gpt-list-clobbers-pmbr.sh + +diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c +index 9d9876c..ea96a3b 100644 +--- a/libparted/labels/gpt.c ++++ b/libparted/labels/gpt.c +@@ -4,7 +4,7 @@ + original version by Matt Domsch <Matt_Domsch@dell.com> + Disclaimed into the Public Domain + +- Portions Copyright (C) 2001-2003, 2005-2009 Free Software Foundation, Inc. ++ Portions Copyright (C) 2001-2003, 2005-2010 Free Software Foundation, Inc. + + EFI GUID Partition Table handling + Per Intel EFI Specification v1.02 +@@ -932,9 +932,9 @@ gpt_read (PedDisk *disk) + if (primary_gpt && backup_gpt) + { + /* Both are valid. */ ++#ifndef DISCOVER_ONLY + if (PED_LE64_TO_CPU (primary_gpt->AlternateLBA) < disk->dev->length - 1) + { +-#ifndef DISCOVER_ONLY + switch (ped_exception_throw + (PED_EXCEPTION_ERROR, + (PED_EXCEPTION_FIX | PED_EXCEPTION_CANCEL +@@ -954,8 +954,12 @@ gpt_read (PedDisk *disk) + write_back = 0; + break; + } +-#endif /* !DISCOVER_ONLY */ + } ++ else ++ { ++ write_back = 0; ++ } ++#endif /* !DISCOVER_ONLY */ + gpt = primary_gpt; + pth_free (backup_gpt); + } +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 7bfb22e..38922f6 100644 +--- a/tests/Makefile.in ++++ b/tests/Makefile.in +@@ -9,6 +9,7 @@ TESTS = \ + t0200-gpt.sh \ + t0201-gpt.sh \ + t0202-gpt-pmbr.sh \ ++ t0205-gpt-list-clobbers-pmbr.sh \ + t0220-gpt-msftres.sh \ + t0250-gpt.sh \ + t0280-gpt-corrupt.sh \ +@@ -1261,6 +1261,8 @@ t0201-gpt.sh.log: t0201-gpt.sh + @p='t0201-gpt.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) + t0202-gpt-pmbr.sh.log: t0202-gpt-pmbr.sh + @p='t0202-gpt-pmbr.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) ++t0205-gpt-list-clobbers-pmbr.sh.log: t0205-gpt-list-clobbers-pmbr.sh ++ @p='t0205-gpt-list-clobbers-pmbr.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) + t0220-gpt-msftres.sh.log: t0220-gpt-msftres.sh + @p='t0220-gpt-msftres.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) + t0250-gpt.sh.log: t0250-gpt.sh +diff --git a/tests/t0205-gpt-list-clobbers-pmbr.sh b/tests/t0205-gpt-list-clobbers-pmbr.sh +new file mode 100644 +index 0000000..979a15e +--- /dev/null ++++ b/tests/t0205-gpt-list-clobbers-pmbr.sh +@@ -0,0 +1,59 @@ ++#!/bin/sh ++# Ensure that printing a GPT partition table does not modify the pMBR. ++# Due to a bug in parted-2.1, "parted /dev/... print" would do just that. ++# Not a problem for most, but if you have a hybrid, e.g., gptsync'd ++# GPT/MBR table, merely listing the table with Parted-2.1 would clobber ++# the MBR part. ++ ++# Copyright (C) 2010 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see <http://www.gnu.org/licenses/>. ++ ++if test "$VERBOSE" = yes; then ++ set -x ++ parted --version ++fi ++ ++: ${srcdir=.} ++. $srcdir/t-lib.sh ++ ++fail=0 ++ ++ss=$sector_size_ ++n_sectors=400 ++dev=dev-file ++ ++dd if=/dev/null of=$dev bs=$ss seek=$n_sectors || fail=1 ++parted -s $dev mklabel gpt || fail=1 ++parted -s $dev mkpart p1 101s 150s || fail=1 ++parted -s $dev mkpart p2 151s 200s || fail=1 ++parted -s $dev mkpart p3 201s 250s || fail=1 ++ ++parted -m -s $dev u s p || fail=1 ++ ++# Write non-NUL bytes all over the MBR, so we're likely to see any change. ++# However, be careful to leave the type of the first partition, 0xEE, ++# as well as the final two magic bytes. ++printf '%0450d\xee%059d\x55\xaa' 0 0 | dd of=$dev count=1 conv=notrunc || fail=1 ++ ++dd if=$dev of=before count=1 || fail=1 ++ ++chmod a-w $dev ++parted -m -s $dev u s p || fail=1 ++ ++dd if=$dev of=after count=1 || fail=1 ++ ++cmp before after || fail=1 ++ ++Exit $fail +-- +1.6.6 + diff --git a/pkgs/core/parted/patches/parted-2.1-mem-leak-fixes-rh556012.patch b/pkgs/core/parted/patches/parted-2.1-mem-leak-fixes-rh556012.patch new file mode 100644 index 0000000..01129ae --- /dev/null +++ b/pkgs/core/parted/patches/parted-2.1-mem-leak-fixes-rh556012.patch @@ -0,0 +1,158 @@ +From 358c9846a014247605d8da47b6917cac1344de00 Mon Sep 17 00:00:00 2001 +From: Jim Meyering <meyering@redhat.com> +Date: Fri, 15 Jan 2010 20:14:38 +0100 +Subject: [PATCH] dos: don't leak a constraint upon partition-add failure + +* libparted/labels/dos.c (read_table): Free constraint upon failure. +--- + libparted/labels/dos.c | 9 +++++---- + 1 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/libparted/labels/dos.c b/libparted/labels/dos.c +index 6b8d6cb..339acf4 100644 +--- a/libparted/labels/dos.c ++++ b/libparted/labels/dos.c +@@ -873,7 +873,6 @@ read_table (PedDisk* disk, PedSector sector, int is_extended_table) + PedPartition* part; + PedPartitionType type; + PedSector lba_offset; +- PedConstraint* constraint_exact; + + PED_ASSERT (disk != NULL, return 0); + PED_ASSERT (disk->dev != NULL, return 0); +@@ -944,10 +943,12 @@ read_table (PedDisk* disk, PedSector sector, int is_extended_table) + if (type != PED_PARTITION_EXTENDED) + part->fs_type = ped_file_system_probe (&part->geom); + +- constraint_exact = ped_constraint_exact (&part->geom); +- if (!ped_disk_add_partition (disk, part, constraint_exact)) +- goto error; ++ PedConstraint *constraint_exact ++ = ped_constraint_exact (&part->geom); ++ bool ok = ped_disk_add_partition (disk, part, constraint_exact); + ped_constraint_destroy (constraint_exact); ++ if (!ok) ++ goto error; + + /* non-nested extended partition */ + if (part->type == PED_PARTITION_EXTENDED) { +-- +1.6.3.3 + +From d0cec198183be0b9989e4bc729c2930c7cdfe545 Mon Sep 17 00:00:00 2001 +From: Jim Meyering <meyering@redhat.com> +Date: Fri, 15 Jan 2010 19:53:36 +0100 +Subject: [PATCH] gpt: don't leak a constraint upon partition-add failure + +* libparted/labels/gpt.c (gpt_read): Free constraint upon failure. +--- + libparted/labels/gpt.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c +index 76537fd..9d9876c 100644 +--- a/libparted/labels/gpt.c ++++ b/libparted/labels/gpt.c +@@ -1020,7 +1020,6 @@ gpt_read (PedDisk *disk) + GuidPartitionEntry_t *pte + = (GuidPartitionEntry_t *) ((char *) ptes + i * p_ent_size); + PedPartition *part; +- PedConstraint *constraint_exact; + + if (!guid_cmp (pte->PartitionTypeGuid, UNUSED_ENTRY_GUID)) + continue; +@@ -1032,9 +1031,10 @@ gpt_read (PedDisk *disk) + part->fs_type = ped_file_system_probe (&part->geom); + part->num = i + 1; + +- constraint_exact = ped_constraint_exact (&part->geom); ++ PedConstraint *constraint_exact = ped_constraint_exact (&part->geom); + if (!ped_disk_add_partition (disk, part, constraint_exact)) + { ++ ped_constraint_destroy (constraint_exact); + ped_partition_destroy (part); + goto error_delete_all; + } +-- +1.6.3.3 + +From 952e4919befce199b096fd1bbde93ef7902239d3 Mon Sep 17 00:00:00 2001 +From: Jim Meyering <meyering@redhat.com> +Date: Fri, 15 Jan 2010 19:34:00 +0100 +Subject: [PATCH] gpt: do not leak a GPT header on an error path + +* libparted/labels/gpt.c (gpt_write): Avoid a leak by freeing the +header buffer after pth_get_raw call where it's used, but before +checking whether that pth_get_raw call succeeded. +Avoid another leak in identical just 10 lines down. +Add "FIXME: caution..." comments to warn about the duplication. +--- + libparted/labels/gpt.c | 12 ++++++++---- + 1 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c +index fe1f300..76537fd 100644 +--- a/libparted/labels/gpt.c ++++ b/libparted/labels/gpt.c +@@ -1208,11 +1208,13 @@ gpt_write (const PedDisk *disk) + goto error_free_ptes; + + /* Write PTH and PTEs */ ++ /* FIXME: Caution: this code is nearly identical to what's just below. */ + if (_generate_header (disk, 0, ptes_crc, &gpt) != 0) + goto error_free_ptes; +- if ((pth_raw = pth_get_raw (disk->dev, gpt)) == NULL) +- goto error_free_ptes; ++ pth_raw = pth_get_raw (disk->dev, gpt); + pth_free (gpt); ++ if (pth_raw == NULL) ++ goto error_free_ptes; + int write_ok = ped_device_write (disk->dev, pth_raw, 1, 1); + free (pth_raw); + if (!write_ok) +@@ -1222,11 +1224,13 @@ gpt_write (const PedDisk *disk) + goto error_free_ptes; + + /* Write Alternate PTH & PTEs */ ++ /* FIXME: Caution: this code is nearly identical to what's just above. */ + if (_generate_header (disk, 1, ptes_crc, &gpt) != 0) + goto error_free_ptes; +- if ((pth_raw = pth_get_raw (disk->dev, gpt)) == NULL) +- goto error_free_ptes; ++ pth_raw = pth_get_raw (disk->dev, gpt); + pth_free (gpt); ++ if (pth_raw == NULL) ++ goto error_free_ptes; + write_ok = ped_device_write (disk->dev, pth_raw, disk->dev->length - 1, 1); + free (pth_raw); + if (!write_ok) +-- +1.6.3.3 + +From 19b072592a7a551a861c200be58aef04a7546fb9 Mon Sep 17 00:00:00 2001 +From: Jim Meyering <meyering@redhat.com> +Date: Fri, 15 Jan 2010 18:56:37 +0100 +Subject: [PATCH] libparted: avoid double-free on an OOM failure path + +* libparted/disk.c (ped_disk_check): Don't double-free "fs_size". +--- + libparted/disk.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/libparted/disk.c b/libparted/disk.c +index c14d005..2d27b7c 100644 +--- a/libparted/disk.c ++++ b/libparted/disk.c +@@ -632,7 +632,9 @@ ped_disk_check (const PedDisk* disk) + walk->num, part_size, fs_size); + + free (part_size); ++ + free (fs_size); ++ fs_size = NULL; + + if (choice != PED_EXCEPTION_IGNORE) + return 0; +-- +1.6.3.3 + diff --git a/pkgs/core/parted/patches/parted-2.1-needs_clobber-rh566181.patch b/pkgs/core/parted/patches/parted-2.1-needs_clobber-rh566181.patch new file mode 100644 index 0000000..50be7c5 --- /dev/null +++ b/pkgs/core/parted/patches/parted-2.1-needs_clobber-rh566181.patch @@ -0,0 +1,30 @@ +From 38fe6955c11a8bbcdda050401f46abe25dced000 Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Thu, 18 Feb 2010 14:24:32 +0100 +Subject: [PATCH parted] libparted: copy needs_clobber value in ped_disk_duplicate() + +Most duplicate disk_ops use ped_disk_new_fresh, which sets needs_clobber +to 1. This would lead to clobbering the disk when committing a duplicate +disk even when the original disk was not made with ped_disk_new_fresh. +* libparted/disk.c (ped_disk_duplicate): copy needs_clobber value. +--- + libparted/disk.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/libparted/disk.c b/libparted/disk.c +index b819d59..fc5ef17 100644 +--- a/libparted/disk.c ++++ b/libparted/disk.c +@@ -276,6 +276,9 @@ ped_disk_duplicate (const PedDisk* old_disk) + } + if (!_disk_pop_update_mode (new_disk)) + goto error_destroy_new_disk; ++ ++ new_disk->needs_clobber = old_disk->needs_clobber; ++ + return new_disk; + + error_destroy_new_disk: +-- +1.7.0 + diff --git a/pkgs/core/passwd/passwd.nm b/pkgs/core/passwd/passwd.nm new file mode 100644 index 0000000..4bb782d --- /dev/null +++ b/pkgs/core/passwd/passwd.nm @@ -0,0 +1,60 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = passwd +PKG_VER = 0.76 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://fedorahosted.org/passwd +PKG_LICENSE = BSD +PKG_SUMMARY = An utility for setting or changing passwords using PAM. + +PKG_DEPS += glib2 libuser pam + +define PKG_DESCRIPTION + This package contains a system utility (passwd) which sets \ + or changes passwords, using PAM (Pluggable Authentication \ + Modules) library. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && \ + ./configure \ + --prefix=/usr \ + --without-selinux \ + --without-audit \ + --disable-static + + cd $(DIR_APP) && make DEBUG= RPM_OPT_FLAGS="$(CFLAGS)" $(PARALLELISMFLAGS) +endef diff --git a/pkgs/core/patch/patch.nm b/pkgs/core/patch/patch.nm new file mode 100644 index 0000000..a1e0a98 --- /dev/null +++ b/pkgs/core/patch/patch.nm @@ -0,0 +1,53 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = patch +PKG_VER = 2.6.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://www.gnu.org/software/patch/patch.html +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Utility for modifying/upgrading files. + +define PKG_DESCRIPTION + The patch program applies diff files to originals. The diff \ + command is used to compare an original to a changed file.\ + Diff lists the changes made to the file. A person who has \ + the original file can then use the patch command with the \ + diff file to add the changes to their original file. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define STAGE_TEST + cd $(DIR_APP) && make check +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install prefix=$(BUILDROOT)/usr +endef diff --git a/pkgs/core/patch/patches/patch-2.6.1-test_fix-1.patch b/pkgs/core/patch/patches/patch-2.6.1-test_fix-1.patch new file mode 100644 index 0000000..d80f766 --- /dev/null +++ b/pkgs/core/patch/patches/patch-2.6.1-test_fix-1.patch @@ -0,0 +1,28 @@ +Submitted by: Matt Burgess <matthew at linuxfromscratch.org> +Date: 2010-01-03 +Initial Package Version: 2.6.1 +Upstream Status: Submitted +Origin: Matt Burgess +Description: Prevents a test from failing when ed is not available. + +diff -Naur patch-2.6.1.orig/tests/crlf-handling patch-2.6.1/tests/crlf-handling +--- patch-2.6.1.orig/tests/crlf-handling 2009-12-30 12:56:30.000000000 +0000 ++++ patch-2.6.1/tests/crlf-handling 2010-01-03 11:06:00.340849916 +0000 +@@ -89,10 +89,14 @@ + + # -------------------------------------------------------------- + +-diff -e a b > ab.diff +-cp a c +-check 'patch c < ab.diff' <<EOF ++if ! have_ed ; then ++ echo "The ed utility is not available; skipping ed related tests" ++else ++ diff -e a b > ab.diff ++ cp a c ++ check 'patch c < ab.diff' <<EOF + EOF ++fi + + check 'cat -A c' <<EOF + 1b^M$ diff --git a/pkgs/core/pax-utils/pax-utils.nm b/pkgs/core/pax-utils/pax-utils.nm new file mode 100644 index 0000000..06fcd20 --- /dev/null +++ b/pkgs/core/pax-utils/pax-utils.nm @@ -0,0 +1,51 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pax-utils +PKG_VER = 0.1.19 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Security/Tools +PKG_URL = http://www.gentoo.org/proj/en/hardened/pax-utils.xml +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Utilities for checking PaX features. + +PKG_DEPS += libcap + +define PKG_DESCRIPTION + This package contains several utilities for checking PaX features. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" USE_CAP=yes $(PARALLELISMFLAGS) +endef diff --git a/pkgs/core/paxctl/paxctl.nm b/pkgs/core/paxctl/paxctl.nm new file mode 100644 index 0000000..de3ce8c --- /dev/null +++ b/pkgs/core/paxctl/paxctl.nm @@ -0,0 +1,52 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = paxctl +PKG_VER = 0.5 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Applications/System +PKG_URL = http://pax.grsecurity.net/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = Application to control PaX flags. + +PKG_DEPS += m4 + +define PKG_DESCRIPTION + paxctl may be used to control PaX flags on a per-binary basis. PaX \ + is a set of kernel security patches to enhance a system's security. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_BUILD + cd $(DIR_APP) && make $(PARALLELISMFLAGS) CFLAGS="$(CFLAGS)" +endef diff --git a/pkgs/core/paxtest/paxtest.nm b/pkgs/core/paxtest/paxtest.nm new file mode 100644 index 0000000..dd7c392 --- /dev/null +++ b/pkgs/core/paxtest/paxtest.nm @@ -0,0 +1,56 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = paxtest +PKG_VER = 0.9.7-pre4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Security/Tools +PKG_URL = http://pax.grsecurity.org/ +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = Utilities for testing PaX configuration. + +define PKG_DESCRIPTION + This package contains several files for checking the PaX configuration \ + and checks if it all works correctly. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define QUALITY_AGENT_WHITELIST_EXECSTACK + /usr/lib/paxtest +endef + +define STAGE_BUILD + cd $(DIR_APP) && make -f Makefile.generic RUNDIR=/usr/lib/paxtest \ + $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make -f Makefile.generic install DESTDIR=$(BUILDROOT) \ + RUNDIR=/usr/lib/paxtest BINDIR=/usr/bin +endef diff --git a/pkgs/core/pciutils/pciutils.nm b/pkgs/core/pciutils/pciutils.nm new file mode 100644 index 0000000..0a27064 --- /dev/null +++ b/pkgs/core/pciutils/pciutils.nm @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pciutils +PKG_VER = 3.1.4 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Base +PKG_URL = http://atrey.karlin.mff.cuni.cz/~mj/pciutils.shtml +PKG_LICENSE = GPLv2+ +PKG_SUMMARY = PCI bus related utilities. + +define PKG_DESCRIPTION + The pciutils package contains various utilities for inspecting \ + and setting devices connected to the PCI bus. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +define STAGE_BUILD + cd $(DIR_APP) && make SHARED=yes OPT="$(CFLAGS)" PREFIX=/usr ZLIB=no $(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make SHARED=yes PREFIX=/usr install DESTDIR=$(BUILDROOT) \ + MANDIR=/usr/share/man + + -mkdir -pv $(BUILDROOT)/usr/include/pci + install -v -m 644 $(DIR_APP)/lib/*.h $(BUILDROOT)/usr/include/pci + + -mkdir -pv $(BUILDROOT)/usr/lib + ln -svf libpci.so.3 $(BUILDROOT)/usr/lib/libpci.so +endef diff --git a/pkgs/core/pcre/pcre.nm b/pkgs/core/pcre/pcre.nm new file mode 100644 index 0000000..4edc01d --- /dev/null +++ b/pkgs/core/pcre/pcre.nm @@ -0,0 +1,63 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pcre +PKG_VER = 7.9 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.pcre.org/ +PKG_LICENSE = BSD +PKG_SUMMARY = Perl-compatible regular expression library. + +PKG_DEPS += bzip2 readline zlib + +define PKG_DESCRIPTION + Perl-compatible regular expression library. PCRE has its own native \ + API, but a set of "wrapper" functions that are based on the POSIX \ + API are also supplied in the library libpcreposix. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +CONFIGURE_OPTIONS += --docdir=/usr/share/doc/pcre-$(PKG_VER) \ + --enable-utf8 \ + --enable-pcregrep-libz \ + --enable-pcregrep-libbz2 \ + --enable-unicode-properties + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) + + -mkdir -pv $(BUILDROOT)/{,usr/}lib + mv -v $(BUILDROOT)/usr/lib/libpcre.so.* $(BUILDROOT)/lib/ + ln -v -sf ../../lib/libpcre.so.0 $(BUILDROOT)/usr/lib/libpcre.so +endef diff --git a/pkgs/core/pdns-recursor/pdns-recursor.init b/pkgs/core/pdns-recursor/pdns-recursor.init new file mode 100644 index 0000000..aaf1737 --- /dev/null +++ b/pkgs/core/pdns-recursor/pdns-recursor.init @@ -0,0 +1,9 @@ +description "Control the powerdns recursor" +author "IPFire Team" + +start on starting network +stop on stopped network + +exec /usr/sbin/pdns_recursor +expect fork +respawn diff --git a/pkgs/core/pdns-recursor/pdns-recursor.nm b/pkgs/core/pdns-recursor/pdns-recursor.nm new file mode 100644 index 0000000..1ce372f --- /dev/null +++ b/pkgs/core/pdns-recursor/pdns-recursor.nm @@ -0,0 +1,53 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pdns-recursor +PKG_VER = 3.1.7.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/DNS +PKG_URL = http://powerdns.com/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = A modern, advanced and high performance recursing nameserver. + +PKG_DEPS += boost lua + +define PKG_DESCRIPTION + PowerDNS Recursor is a non authoritative/recursing DNS server. Use this \ + package if you need a dns cache for your network. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +define STAGE_BUILD + cd $(DIR_APP) && LUA=1 LUA_CPPFLAGS_CONFIG= LUA_LIBS_CONFIG=-llua \ + make OPTFLAGS="$(CFLAGS)" PROFILEFLAGS=-fprofile-use #$(PARALLELISMFLAGS) +endef + +define STAGE_INSTALL_CMDS + rm -rf $(BUILDROOT)/etc/init.d +endef diff --git a/pkgs/core/pdns/patches/pdns-2.9.22-gcc44-fixes.patch b/pkgs/core/pdns/patches/pdns-2.9.22-gcc44-fixes.patch new file mode 100644 index 0000000..cba5412 --- /dev/null +++ b/pkgs/core/pdns/patches/pdns-2.9.22-gcc44-fixes.patch @@ -0,0 +1,11 @@ +diff -up pdns-2.9.22/pdns/misc.hh.orig pdns-2.9.22/pdns/misc.hh +--- pdns-2.9.22/pdns/misc.hh.orig 2009-02-26 17:09:41.000000000 +0100 ++++ pdns-2.9.22/pdns/misc.hh 2009-02-26 17:09:54.000000000 +0100 +@@ -20,6 +20,7 @@ + #define MISC_HH + #include <stdint.h> + #include <cstring> ++#include <cstdio> + + #if 0 + #include <iostream> diff --git a/pkgs/core/pdns/pdns.nm b/pkgs/core/pdns/pdns.nm new file mode 100644 index 0000000..4839b69 --- /dev/null +++ b/pkgs/core/pdns/pdns.nm @@ -0,0 +1,54 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pdns +PKG_VER = 2.9.22 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Networking/DNS +PKG_URL = http://powerdns.com/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = A modern, advanced and high performance authoritative-only nameserver. + +PKG_DEPS += boost openldap sqlite zlib + +define PKG_DESCRIPTION + The PowerDNS Nameserver is a modern, advanced and high performance \ + authoritative-only nameserver. It is written from scratch and conforms \ + to all relevant DNS standards documents. \ + Furthermore, PowerDNS interfaces with almost any database. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +export CPPFLAGS = -DLDAP_DEPRECATED + +CONFIGURE_OPTIONS += \ + --sysconfdir=/etc/pdns \ + --libdir=/usr/lib/powerdns \ + --with-modules="" \ + --with-dynmodules="pipe geo ldap gsqlite3" diff --git a/pkgs/core/perl-xml-parser/perl-xml-parser.nm b/pkgs/core/perl-xml-parser/perl-xml-parser.nm new file mode 100644 index 0000000..e1b5d20 --- /dev/null +++ b/pkgs/core/perl-xml-parser/perl-xml-parser.nm @@ -0,0 +1,55 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = XML-Parser +PKG_VER = 2.36 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Libraries +PKG_URL = http://search.cpan.org/dist/XML-Parser/ +PKG_LICENSE = GPL+ or Artistic +PKG_SUMMARY = Perl module for parsing XML files. + +PKG_DEPS += expat perl + +define PKG_DESCRIPTION + This module provides ways to parse XML documents. It is built on \ + top of XML::Parser::Expat, which is a lower level interface to \ + James Clark's expat library. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +# XXX has to be removed +define QUALITY_AGENT_WHITELIST_RPATH + /usr/lib/perl5/site_perl/*/auto/XML/Parser/Expat/Expat.so +endef + +define STAGE_BUILD + cd $(DIR_APP) && perl Makefile.PL + cd $(DIR_APP) && make $(PARALLELISMFLAGS) +endef diff --git a/pkgs/core/perl/patches/perl-5.10.1-utf8-1.patch b/pkgs/core/perl/patches/perl-5.10.1-utf8-1.patch new file mode 100644 index 0000000..bc9580f --- /dev/null +++ b/pkgs/core/perl/patches/perl-5.10.1-utf8-1.patch @@ -0,0 +1,167 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2010-02-24 +Initial Package Version: 5.10.1 +Upstream Status: From upstream +Origin: Git +http://perl5.git.perl.org/perl.git/patch/0abd0d78a73da1c4d13b1c700526b7e5d03b32d4 +Description: Bug fix for invalid utf-8 characters causing Perl to crash. + +http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3626 + +From 0abd0d78a73da1c4d13b1c700526b7e5d03b32d4 Mon Sep 17 00:00:00 2001 +From: Yves Orton <demerphq@gmail.com> +Date: Sun, 25 Oct 2009 20:37:08 +0100 +Subject: [PATCH] disable non-unicode case insensitive trie matching + +Also revert 8902bb05b18c9858efa90229ca1ee42b17277554 as it merely +masked one symptom of the deeper problems. + +Also fixes RT #69973, which was a segfault which was exposed by +8902bb05, see the ticket for further details. + +http://rt.perl.org/rt3//Public/Bug/Display.html?id=69973 + +At the code of this is the problem that in unicode matching a bunch +of code points have case folding rules beyond just A-Z/a-z. Since +the case folding rules are decided at runtime by the string, we cant +use the same TRIE tables for both unicode/non-unicode matching. + +Until this is reconciled or some other solution is found case insensitive +matching only gets the TRIE optimisation when the pattern is uniocde. + +From CaseFolding.txt: + +00B5; C; 03BC; # MICRO SIGN +00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE +00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE +00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE +00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS +00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE +00C6; C; 00E6; # LATIN CAPITAL LETTER AE +00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA +00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE +00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE +00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS +00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE +00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE +00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS +00D0; C; 00F0; # LATIN CAPITAL LETTER ETH +00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE +00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE +00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE +00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE +00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS +00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE +00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE +00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE +00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS +00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE +00DE; C; 00FE; # LATIN CAPITAL LETTER THORN +00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S +--- + ext/re/t/regop.t | 12 ++++++------ + regcomp.c | 17 +++++++++++------ + regexec.c | 9 ++------- + 3 files changed, 19 insertions(+), 19 deletions(-) + +diff --git a/ext/re/t/regop.t b/ext/re/t/regop.t +index 9118bf6..46e6ec0 100644 +--- a/ext/re/t/regop.t ++++ b/ext/re/t/regop.t +@@ -231,12 +231,12 @@ anchored "ABC" at 0 + #Freeing REx: "(\.COM|\.EXE|\.BAT|\.CMD|\.VBS|\.VBE|\.JS|\.JSE|\."...... + %MATCHED% + floating ""$ at 3..4 (checking floating) +-1:1[1] 3:2[1] 5:2[64] 45:83[1] 47:84[1] 48:85[0] +-stclass EXACTF <.> minlen 3 +-Found floating substr ""$ at offset 30... +-Does not contradict STCLASS... +-Guessed: match at offset 26 +-Matching stclass EXACTF <.> against ".exe" ++#1:1[1] 3:2[1] 5:2[64] 45:83[1] 47:84[1] 48:85[0] ++#stclass EXACTF <.> minlen 3 ++#Found floating substr ""$ at offset 30... ++#Does not contradict STCLASS... ++#Guessed: match at offset 26 ++#Matching stclass EXACTF <.> against ".exe" + --- + #Compiling REx "[q]" + #size 12 nodes Got 100 bytes for offset annotations. +diff --git a/regcomp.c b/regcomp.c +index 6e9fa26..eb5f12f 100644 +--- a/regcomp.c ++++ b/regcomp.c +@@ -2833,13 +2833,18 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, + } + } else { + /* +- Currently we assume that the trie can handle unicode and ascii +- matches fold cased matches. If this proves true then the following +- define will prevent tries in this situation. +- +- #define TRIE_TYPE_IS_SAFE (UTF || optype==EXACT) +-*/ ++ Currently we do not believe that the trie logic can ++ handle case insensitive matching properly when the ++ pattern is not unicode (thus forcing unicode semantics). ++ ++ If/when this is fixed the following define can be swapped ++ in below to fully enable trie logic. ++ + #define TRIE_TYPE_IS_SAFE 1 ++ ++*/ ++#define TRIE_TYPE_IS_SAFE (UTF || optype==EXACT) ++ + if ( last && TRIE_TYPE_IS_SAFE ) { + make_trie( pRExC_state, + startbranch, first, cur, tail, count, +diff --git a/regexec.c b/regexec.c +index 402ede3..ec09c28 100644 +--- a/regexec.c ++++ b/regexec.c +@@ -1105,16 +1105,15 @@ Perl_re_intuit_start(pTHX_ REGEXP * const rx, SV *sv, char *strpos, + + #define REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc, uscan, len, \ + uvc, charid, foldlen, foldbuf, uniflags) STMT_START { \ +- UV uvc_unfolded = 0; \ + switch (trie_type) { \ + case trie_utf8_fold: \ + if ( foldlen>0 ) { \ +- uvc_unfolded = uvc = utf8n_to_uvuni( uscan, UTF8_MAXLEN, &len, uniflags ); \ ++ uvc = utf8n_to_uvuni( uscan, UTF8_MAXLEN, &len, uniflags ); \ + foldlen -= len; \ + uscan += len; \ + len=0; \ + } else { \ +- uvc_unfolded = uvc = utf8n_to_uvuni( (U8*)uc, UTF8_MAXLEN, &len, uniflags ); \ ++ uvc = utf8n_to_uvuni( (U8*)uc, UTF8_MAXLEN, &len, uniflags ); \ + uvc = to_uni_fold( uvc, foldbuf, &foldlen ); \ + foldlen -= UNISKIP( uvc ); \ + uscan = foldbuf + UNISKIP( uvc ); \ +@@ -1140,7 +1139,6 @@ uvc, charid, foldlen, foldbuf, uniflags) STMT_START { \ + uvc = (UV)*uc; \ + len = 1; \ + } \ +- \ + if (uvc < 256) { \ + charid = trie->charmap[ uvc ]; \ + } \ +@@ -1153,9 +1151,6 @@ uvc, charid, foldlen, foldbuf, uniflags) STMT_START { \ + charid = (U16)SvIV(*svpp); \ + } \ + } \ +- if (!charid && trie_type == trie_utf8_fold && !UTF) { \ +- charid = trie->charmap[uvc_unfolded]; \ +- } \ + } STMT_END + + #define REXEC_FBC_EXACTISH_CHECK(CoNd) \ +-- +1.6.5.2.74.g610f9.dirty + diff --git a/pkgs/core/perl/perl.nm b/pkgs/core/perl/perl.nm new file mode 100644 index 0000000..4a3c525 --- /dev/null +++ b/pkgs/core/perl/perl.nm @@ -0,0 +1,77 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = perl +PKG_VER = 5.10.1 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Languages +PKG_URL = http://www.perl.org/ +PKG_LICENSE = GPL+ or Artistic and GPLv2+ or Artistic +PKG_SUMMARY = Practical Extraction and Report Language. + +PKG_DEPS += zlib + +define PKG_DESCRIPTION + Perl is a high-level programming language with roots in C, sed, awk \ + and shell scripting. Perl is good at handling processes and files, \ + and is especially good at handling text. Perl's hallmarks are \ + practicality and efficiency. While it is used to do a lot of \ + different things, Perl's most common applications are system \ + administration utilities and web programming. A large proportion of \ + the CGI scripts on the web are written in Perl. You need the perl \ + package installed on your system so that your system can handle Perl \ + scripts. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +define QUALITY_AGENT_WHITELIST_RPATH + /usr/lib/perl*/auto/Time/HiRes/HiRes.so + /usr/lib/perl*/auto/Compress/Raw/Zlib/Zlib.so +endef + +############################################################################### +# Installation Details +############################################################################### + +define STAGE_PREPARE_CMDS + cd $(DIR_APP) && sed -i 's/command /command[ -]/' makedepend.SH +endef + +define STAGE_BUILD + cd $(DIR_APP) && sed -i -e "s|BUILD_ZLIB\s*= True|BUILD_ZLIB = False|" \ + -e "s|INCLUDE\s*= ./zlib-src|INCLUDE = /usr/include|" \ + -e "s|LIB\s*= ./zlib-src|LIB = /usr/lib|" \ + ext/Compress-Raw-Zlib/config.in + + cd $(DIR_APP) && ./configure.gnu --prefix=/usr \ + -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 \ + -Dpager="/usr/bin/less -isR" + + cd $(DIR_APP) && make #$(PARALLELISMFLAGS) +endef diff --git a/pkgs/core/pinentry/pinentry.nm b/pkgs/core/pinentry/pinentry.nm new file mode 100644 index 0000000..0e79f6e --- /dev/null +++ b/pkgs/core/pinentry/pinentry.nm @@ -0,0 +1,53 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pinentry +PKG_VER = 0.7.6 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://www.gnupg.org +PKG_LICENSE = GPLv2 +PKG_SUMMARY = Collection of simple PIN or passphrase entry dialogs. + +PKG_DEPS += libgpg-error ncurses + +define PKG_DESCRIPTION + Pinentry is a collection of simple PIN or passphrase entry dialogs which \ + utilize the Assuan protocol as described by the aegypten project; see \ + http://www.gnupg.org/aegypten/ for details. This package contains the \ + curses (text) based version of the PIN entry dialog. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +CONFIGURE_OPTIONS += \ + --enable-pin-entry-curses \ + --enable-fallback-curses \ + --disable-pinentry-gtk \ + --disable-pinentry-gtk2 \ + --disable-pinentry-qt diff --git a/pkgs/core/pixman/pixman.nm b/pkgs/core/pixman/pixman.nm new file mode 100644 index 0000000..a54c30b --- /dev/null +++ b/pkgs/core/pixman/pixman.nm @@ -0,0 +1,54 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pixman +PKG_VER = 0.15.18 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Libraries +PKG_URL = http://xorg.freedesktop.org/archive/individual/lib/ +PKG_LICENSE = MIT +PKG_SUMMARY = Pixel manipulation library. + +PKG_BUILD_DEPS+= pkg-config + +define PKG_DESCRIPTION + Pixman is a pixel manipulation library for X and cairo. +endef + +PKG_TARBALL = $(THISAPP).tar.bz2 + +# XXX double check this later on +ifeq "$(TARGET)" "via-c7" + CONFIGURE_OPTIONS += --enable-mmx #--enable-sse2 +else +ifeq "$(TARGET)" "atom" + CONFIGURE_OPTIONS += --enable-mmx --enable-sse2 +else + CONFIGURE_OPTIONS += --disable-mmx --disable-sse2 +endif +endif diff --git a/pkgs/core/pkg-config/pkg-config.nm b/pkgs/core/pkg-config/pkg-config.nm new file mode 100644 index 0000000..a2dcaee --- /dev/null +++ b/pkgs/core/pkg-config/pkg-config.nm @@ -0,0 +1,50 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pkg-config +PKG_VER = 0.22 +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = Development/Tools +PKG_URL = http://pkg-config.freedesktop.org/ +PKG_LICENSE = GPLv2 +PKG_SUMMARY = A tool for determining compilation options. + +PKG_DEPS += m4 + +define PKG_DESCRIPTION + The pkgconfig tool determines compilation options. For each required \ + library, it reads the configuration file and outputs the necessary \ + compiler and linker flags. +endef + +PKG_TARBALL = $(THISAPP).tar.gz + +# fails +#define STAGE_TEST +# cd $(DIR_APP) && make check +#endef diff --git a/pkgs/core/pomona/pomona.nm b/pkgs/core/pomona/pomona.nm new file mode 100644 index 0000000..b5635b9 --- /dev/null +++ b/pkgs/core/pomona/pomona.nm @@ -0,0 +1,64 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include $(PKGROOT)/Include + +PKG_NAME = pomona +PKG_VER = +PKG_REL = 0 + +PKG_MAINTAINER = +PKG_GROUP = System/Installer +PKG_URL = http://www.ipfire.org +PKG_LICENSE = GPLv3+ +PKG_SUMMARY = The IPFire 3.x installer. + +PKG_BUILD_DEPS+= pychecker +PKG_DEPS += e2fsprogs parted pciutils popt \ + pyfire python python-dbus python-parted + +define PKG_DESCRIPTION + Pomona is the installer for IPFire 3.x. +endef + +DIR_APP = src + +define STAGE_PREPARE + cd $(DIR_APP) && make clean + #cd $(DIR_APP) && make -C po update-po +endef + +define STAGE_BUILD + cd $(DIR_APP) && make +endef + +define STAGE_TEST + cd $(DIR_APP) && make test +endef + +define STAGE_INSTALL + cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) \ + NAME=$(NAME) SNAME=$(SNAME) VERSION=$(VERSION) KVER=$(KVER) + cd $(DIR_APP) && make clean +endef diff --git a/pkgs/core/pomona/src/Makefile b/pkgs/core/pomona/src/Makefile new file mode 100644 index 0000000..ab6f497 --- /dev/null +++ b/pkgs/core/pomona/src/Makefile @@ -0,0 +1,57 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +include Makefile.inc + +SUBDIRS = isys po + +all: lang-names subdirs + +lang-names: lang-table + PYTHONPATH="./src/:." LANG=en_US.UTF-8 \ + ./scripts/getlangnames.py > lang-names.tmp + mv lang-names.tmp lang-names + +install: all + -mkdir -p $(PYTHONLIBDIR) + [ -d "$(PYTHONLIBDIR)" ] + for d in $(SUBDIRS); do \ + make DESTDIR=`cd $(DESTDIR); pwd` -C $$d install; \ + [ $$? = 0 ] || exit 1; \ + done + cp -vf *.py lang-{table,names} $(PYTHONLIBDIR) + sed -e "s/VERSION/$(VERSION)/g" \ + -e "s/SNAME/$(SNAME)/g" \ + -e "s/PNAME/$(PNAME)/g" \ + -e "s/NAME/$(NAME)/g" \ + -e "s/KVER/$(KVER)/g" \ + -i $(PYTHONLIBDIR)/constants.py + -mkdir -p $(DESTDIR)/sbin + install -m 755 $(PSNAME) $(DESTDIR)/sbin/$(PSNAME) + +test: + ./runpychecker.sh + +clean: + rm -vf *.o *.so *.pyc *.pyo lang-names{,.tmp} + for d in $(SUBDIRS); do make -C $$d clean; done + +subdirs: + for d in $(SUBDIRS); do make -C $$d; [ $$? = 0 ] || exit 1; done diff --git a/pkgs/core/pomona/src/Makefile.inc b/pkgs/core/pomona/src/Makefile.inc new file mode 100644 index 0000000..998fae8 --- /dev/null +++ b/pkgs/core/pomona/src/Makefile.inc @@ -0,0 +1,36 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +## Name of this program +# +PNAME = Pomona +PSNAME = pomona + +DESTDIR=$(INSTALLER_DIR) + +INSTALL = install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALLNLSDIR = $(DESTDIR)/usr/share/locale + +PYTHONLIBDIR = $(DESTDIR)/usr/lib/$(PSNAME) +PYTHONINCLUDE= /usr/include/python2.6/ + +CC = $(CROSS)gcc diff --git a/pkgs/core/pomona/src/autopart.py b/pkgs/core/pomona/src/autopart.py new file mode 100644 index 0000000..0dcb89e --- /dev/null +++ b/pkgs/core/pomona/src/autopart.py @@ -0,0 +1,1609 @@ +# +# autopart.py - auto partitioning logic +# +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Jeremy Katz <katzj@redhat.com> +# + +import parted +import copy +import string, sys +import fsset +import lvm +import logging +from pomona_log import logger, logFile +import cryptodev +import partedUtils +import partRequests +from constants import * +from errors import * + +import iutil +import isys + +log = logging.getLogger("pomona") + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + + +PARTITION_FAIL = -1 +PARTITION_SUCCESS = 0 + +BOOT_NOT_EXT2 = -1 +BOOTEFI_NOT_VFAT = -2 +BOOTALPHA_NOT_BSD = -3 +BOOTALPHA_NO_RESERVED_SPACE = -4 +BOOTIPSERIES_TOO_HIGH = -5 + +DEBUG_LVM_GROW = 0 + +# Add another logger for the LVM debugging, since there's a lot of that. +# Set DEBUG_LVM_GROW if you want to spew all this information to the log +# file. Otherwise it'll get ignored. +logger.addLogger ("pomona.lvm", minLevel=logging.DEBUG) +lvmLog = logging.getLogger("pomona.lvm") + +if DEBUG_LVM_GROW: + logger.addFileHandler (logFile, lvmLog, minLevel=logging.DEBUG) +else: + lvmLog.setLevel (logging.CRITICAL) + logger.addFileHandler (logFile, lvmLog, minLevel=logging.CRITICAL) + +# check that our "boot" partitions meet necessary constraints unless +# the request has its ignore flag set +def bootRequestCheck(req, diskset): + if not req.device or req.ignoreBootConstraints: + return PARTITION_SUCCESS + part = partedUtils.get_partition_by_name(diskset.disks, req.device) + if not part: + return PARTITION_SUCCESS + + return PARTITION_SUCCESS + +# Alpha requires a BSD partition to boot. Since we can be called after: +# +# - We re-attached an existing /boot partition (existing dev.drive) +# - We create a new one from a designated disk (no dev.drive) +# - We auto-create a new one from a designated set of disks (dev.drive +# is a list) +# +# it's simpler to get disk the partition belong to through dev.device +# Some other tests pertaining to a partition where /boot resides are: +# +# - There has to be at least 1 MB free at the begining of the disk +# (or so says the aboot manual.) + +def bootAlphaCheckRequirements(part): + disk = part.disk + + # Disklabel check + if not disk.type.name == "bsd": + return BOOTALPHA_NOT_BSD + + # The first free space should start at the begining of the drive + # and span for a megabyte or more. + free = disk.next_partition() + while free: + if free.type & parted.PARTITION_FREESPACE: + break + free = disk.next_partition(free) + if (not free or free.geom.start != 1L or + partedUtils.getPartSizeMB(free) < 1): + return BOOTALPHA_NO_RESERVED_SPACE + + return PARTITION_SUCCESS + + +def printNewRequestsCyl(diskset, newRequest): + for req in newRequest.requests: + if req.type != REQUEST_NEW: + continue + + part = partedUtils.get_partition_by_name(diskset.disks, req.device) +## print(req) +## print("Start Cyl:%s End Cyl: %s" % (partedUtils.start_sector_to_cyl(part.geom.dev, part.geom.start), +## partedUtils.end_sector_to_cyl(part.geom.dev, part.geom.end))) + +def printFreespaceitem(part): + return partedUtils.get_partition_name(part), part.geom.start, part.geom.end, partedUtils.getPartSizeMB(part) + +def printFreespace(free): + print("Free Space Summary:") + for drive in free.keys(): + print("On drive ", drive) + for part in free[drive]: + print("Freespace:", printFreespaceitem(part)) + + +def findFreespace(diskset): + free = {} + for drive in diskset.disks.keys(): + disk = diskset.disks[drive] + free[drive] = [] + part = disk.next_partition() + while part: + if part.type & parted.PARTITION_FREESPACE: + free[drive].append(part) + part = disk.next_partition(part) + return free + + +def bestPartType(disk, request): + numPrimary = len(partedUtils.get_primary_partitions(disk)) + maxPrimary = disk.max_primary_partition_count + if numPrimary == maxPrimary: + raise PartitioningError, "Unable to create additional primary partitions on /dev/%s" % (disk.dev.path[5:]) + if request.primary: + return parted.PARTITION_PRIMARY + if ((numPrimary == (maxPrimary - 1)) and + not disk.extended_partition and + disk.type.check_feature(parted.DISK_TYPE_EXTENDED)): + return parted.PARTITION_EXTENDED + return parted.PARTITION_PRIMARY + +class partlist: + def __init__(self): + self.parts = [] + + def __str__(self): + retval = "" + for p in self.parts: + retval = retval + "\t%s %s %s\n" % (partedUtils.get_partition_name(p), partedUtils.get_partition_file_system_type(p), partedUtils.getPartSizeMB(p)) + + return retval + + def reset(self): + dellist = [] + for part in self.parts: + dellist.append(part) + + for part in dellist: + self.parts.remove(part) + del part + + self.parts = [] + +def getMinimumSector(disk): + if disk.type.name == 'sun': + start = long(disk.dev.sectors * disk.dev.heads) + start /= long(1024 / disk.dev.sector_size) + return start + 1 + return 0L + +# first step of partitioning voodoo +# partitions with a specific start and end cylinder requested are +# placed where they were asked to go +def fitConstrained(diskset, requests, primOnly=0, newParts = None): + for request in requests.requests: + if request.type != REQUEST_NEW: + continue + if request.device: + continue + if primOnly and not request.primary and not requests.isBootable(request): + continue + if request.drive and (request.start != None): + if not request.end and not request.size: + raise PartitioningError, "Tried to create constrained partition without size or end" + + fsType = request.fstype.getPartedFileSystemType() + disk = diskset.disks[request.drive[0]] + if not disk: # this shouldn't happen + raise PartitioningError, "Selected to put partition on non-existent disk!" + + startSec = partedUtils.start_cyl_to_sector(disk.dev, request.start) + + if request.end: + endCyl = request.end + elif request.size: + endCyl = partedUtils.end_sector_to_cyl(disk.dev, ((1024L * 1024L * request.size) / disk.dev.sector_size) + startSec) + + endSec = partedUtils.end_cyl_to_sector(disk.dev, endCyl) + + if endSec > disk.dev.length: + raise PartitioningError, "Unable to create partition which extends beyond the end of the disk." + + # XXX need to check overlaps properly here + minSec = getMinimumSector(disk) + if startSec < minSec: + startSec = minSec + + if disk.type.check_feature(parted.DISK_TYPE_EXTENDED) and disk.extended_partition: + + if (disk.extended_partition.geom.start < startSec) and (disk.extended_partition.geom.end >= endSec): + partType = parted.PARTITION_LOGICAL + if request.primary: # they've required a primary and we can't do it + raise PartitioningError, "Cannot create another primary partition for %s." % request.mountpoint + # check to make sure we can still create more logical parts + if (len(partedUtils.get_logical_partitions(disk)) == + partedUtils.get_max_logical_partitions(disk)): + raise PartitioningError, "Cannot create another logical partition for %s." % request.mountpoint + else: + partType = parted.PARTITION_PRIMARY + else: + # XXX need a better way to do primary vs logical stuff + ret = bestPartType(disk, request) + + if ret == parted.PARTITION_PRIMARY: + partType = parted.PARTITION_PRIMARY + elif ret == parted.PARTITION_EXTENDED: + newp = disk.partition_new(parted.PARTITION_EXTENDED, None, startSec, endSec) + constraint = disk.dev.constraint_any() + disk.add_partition(newp, constraint) + disk.maximize_partition (newp, constraint) + newParts.parts.append(newp) + requests.nextUniqueID = requests.nextUniqueID + 1 + partType = parted.PARTITION_LOGICAL + else: # shouldn't get here + raise PartitioningError, "Impossible partition type to create" + newp = disk.partition_new (partType, fsType, startSec, endSec) + constraint = disk.dev.constraint_any () + try: + disk.add_partition (newp, constraint) + + except parted.error, msg: + raise PartitioningError, str(msg) + for flag in request.fstype.getPartedPartitionFlags(): + if not newp.is_flag_available(flag): + disk.delete_partition(newp) + raise PartitioningError, ("requested FileSystemType needs " + "a flag that is not available.") + newp.set_flag(flag, 1) + request.device = fsset.PartedPartitionDevice(newp).getDevice() + request.currentDrive = request.drive[0] + newParts.parts.append(newp) + +# get the list of the "best" drives to try to use... +# if currentdrive is set, use that, else use the drive list, or use +# all the drives +def getDriveList(request, diskset): + if request.currentDrive: + drives = request.currentDrive + elif request.drive: + drives = request.drive + else: + drives = diskset.disks.keys() + + if not type(drives) == type([]): + drives = [ drives ] + + drives.sort(isys.compareDrives) + + return drives + + +# fit partitions of a specific size with or without a specific disk +# into the freespace +def fitSized(diskset, requests, primOnly = 0, newParts = None): + todo = {} + + for request in requests.requests: + if request.type != REQUEST_NEW: + continue + if request.device: + continue + if primOnly and not request.primary and not requests.isBootable(request): + continue + if request.size == 0 and request.requestSize == 0: + request.requestSize = 1 + if requests.isBootable(request): + drives = getDriveList(request, diskset) + numDrives = 0 # allocate bootable requests first + else: + drives = getDriveList(request, diskset) + numDrives = len(drives) + if not todo.has_key(numDrives): + todo[numDrives] = [ request ] + else: + todo[numDrives].append(request) + + number = todo.keys() + number.sort() + free = findFreespace(diskset) + + for num in number: + for request in todo[num]: +# print("\nInserting ->", request) + if requests.isBootable(request): + isBoot = 1 + else: + isBoot = 0 + + largestPart = (0, None) + drives = getDriveList(request, diskset) + lvmLog.debug("Trying drives to find best free space out of %s" %(free,)) + for drive in drives: + # this request is bootable and we've found a large enough + # partition already, so we don't need to keep trying other + # drives. this keeps us on the first possible drive + if isBoot and largestPart[1]: + break +## print("Trying drive", drive) + disk = diskset.disks[drive] + numPrimary = len(partedUtils.get_primary_partitions(disk)) + numLogical = len(partedUtils.get_logical_partitions(disk)) + + # if there is an extended partition add it in + if disk.extended_partition: + numPrimary = numPrimary + 1 + + maxPrimary = disk.max_primary_partition_count + maxLogical = partedUtils.get_max_logical_partitions(disk) + + for part in free[drive]: + # if this is a free space outside extended partition + # make sure we have free primary partition slots + if not part.type & parted.PARTITION_LOGICAL: + if numPrimary == maxPrimary: + continue + else: + if numLogical == maxLogical: + continue + + lvmLog.debug( "Trying partition %s" % (printFreespaceitem(part),)) + partSize = partedUtils.getPartSizeMB(part) + # figure out what the request size will be given the + # geometry (#130885) + requestSectors = long((request.requestSize * 1024L * 1024L) / part.disk.dev.sector_size) - 1 + requestSizeMB = long((requestSectors * part.disk.dev.sector_size) / 1024L / 1024L) + lvmLog.debug("partSize %s request %s" % (partSize, request.requestSize)) + if partSize >= requestSizeMB and partSize > largestPart[0]: + if not request.primary or (not part.type & parted.PARTITION_LOGICAL): + largestPart = (partSize, part) + if isBoot: + break + + if not largestPart[1]: + # if the request has a size of zero, it can be allowed to not + # exist without any problems + if request.size > 0: + raise PartitioningError, "Not enough space left to create partition for %s" % request.mountpoint + else: + request.device = None + request.currentDrive = None + continue +# raise PartitioningError, "Can't fulfill request for partition: \n%s" %(request) + + lvmLog.debug("largestPart is %s" % (largestPart,)) + freespace = largestPart[1] + freeStartSec = freespace.geom.start + freeEndSec = freespace.geom.end + + dev = freespace.geom.dev + disk = freespace.disk + + startSec = freeStartSec + + endSec = startSec + long(((request.requestSize * 1024L * 1024L) / disk.dev.sector_size)) - 1 + + if endSec > freeEndSec: + endSec = freeEndSec + if startSec < freeStartSec: + startSec = freeStartSec + + if freespace.type & parted.PARTITION_LOGICAL: + partType = parted.PARTITION_LOGICAL + else: + # XXX need a better way to do primary vs logical stuff + ret = bestPartType(disk, request) + + if ret == parted.PARTITION_PRIMARY: + partType = parted.PARTITION_PRIMARY + elif ret == parted.PARTITION_EXTENDED: + newp = disk.partition_new(parted.PARTITION_EXTENDED, None, startSec, endSec) + constraint = dev.constraint_any() + disk.add_partition(newp, constraint) + disk.maximize_partition (newp, constraint) + newParts.parts.append(newp) + requests.nextUniqueID = requests.nextUniqueID + 1 + partType = parted.PARTITION_LOGICAL + + # now need to update freespace since adding extended + # took some space + found = 0 + part = disk.next_partition() + while part: + if part.type & parted.PARTITION_FREESPACE: + if part.geom.start > freeStartSec and part.geom.end <= freeEndSec: + found = 1 + freeStartSec = part.geom.start + freeEndSec = part.geom.end + break + + part = disk.next_partition(part) + + if not found: + raise PartitioningError, "Could not find free space after making new extended partition" + + startSec = freeStartSec + endSec = startSec + long(((request.requestSize * 1024L * 1024L) / disk.dev.sector_size)) - 1 + + if endSec > freeEndSec: + endSec = freeEndSec + if startSec < freeStartSec: + startSec = freeStartSec + + else: # shouldn't get here + raise PartitioningError, "Impossible partition to create" + + fsType = request.fstype.getPartedFileSystemType() + lvmLog.debug("creating newp with start=%s, end=%s, len=%s" % (startSec, endSec, endSec - startSec)) + newp = disk.partition_new (partType, fsType, startSec, endSec) + constraint = dev.constraint_any () + + try: + disk.add_partition (newp, constraint) + except parted.error, msg: + raise PartitioningError, str(msg) + for flag in request.fstype.getPartedPartitionFlags(): + if not newp.is_flag_available(flag): + disk.delete_partition(newp) + raise PartitioningError, ("requested FileSystemType needs " + "a flag that is not available.") + newp.set_flag(flag, 1) + + request.device = fsset.PartedPartitionDevice(newp).getDevice() + drive = newp.geom.dev.path[5:] + request.currentDrive = drive + newParts.parts.append(newp) + free = findFreespace(diskset) + +# grow logical partitions +# +# do this ONLY after all other requests have been allocated +# we just go through and adjust the size for the logical +# volumes w/o rerunning process partitions +# +def growLogicalVolumes(diskset, requests): + + if requests is None or diskset is None: + return + + # iterate over each volume group, grow logical volumes in each + for vgreq in requests.requests: + if vgreq.type != REQUEST_VG: + continue + + lvmLog.info("In growLogicalVolumes, considering VG %s", vgreq) + lvreqs = requests.getLVMLVForVG(vgreq) + + if lvreqs is None or len(lvreqs) < 1: + lvmLog.info("Apparently it had no logical volume requests, skipping.") + continue + + # come up with list of logvol that are growable + growreqs = [] + for lvreq in lvreqs: + if lvreq.grow: + growreqs.append(lvreq) + + # bail if none defined + if len(growreqs) < 1: + lvmLog.info("No growable logical volumes defined in VG %s.", vgreq) + continue + + lvmLog.info("VG %s has these growable logical volumes: %s", vgreq.volumeGroupName, reduce(lambda x,y: x + [y.uniqueID], growreqs, [])) + + # get remaining free space + if DEBUG_LVM_GROW: + vgfree = lvm.getVGFreeSpace(vgreq, requests, diskset) + lvmLog.debug("Free space in VG after initial partition formation = %s", (vgfree,)) + + # store size we are starting at + initsize = {} + cursize = {} + for req in growreqs: + size = req.getActualSize(requests, diskset) + size = lvm.clampPVSize(size, vgreq.pesize) + initsize[req.logicalVolumeName] = size + cursize[req.logicalVolumeName] = size + if req.maxSizeMB: + req.maxSizeMB = lvm.clampPVSize(req.maxSizeMB, vgreq.pesize) + lvmLog.debug("init sizes for %s: %s",req.logicalVolumeName, size) + + # now dolly out free space to all growing LVs + bailcount = 0 + while 1: + nochange = 1 + completed = [] + for req in growreqs: + lvmLog.debug("considering %s, start size = %s",req.logicalVolumeName, req.getStartSize()) + + # get remaining free space + vgfree = lvm.getVGFreeSpace(vgreq, requests, diskset) + + lvmLog.debug("Free space in VG = %s",vgfree) + + # compute fraction of remaining requests this + # particular request represents + totsize = 0.0 + for otherreq in growreqs: + if otherreq in completed: + continue + + lvmLog.debug("adding in %s %s %s", otherreq.logicalVolumeName, otherreq.getStartSize(), otherreq.maxSizeMB) + + size = otherreq.getActualSize(requests, diskset) + if otherreq.maxSizeMB: + if size < otherreq.maxSizeMB: + totsize = totsize + otherreq.getStartSize() + else: + lvmLog.debug("%s is now at %s, and passed maxsize of %s", otherreq.logicalVolumeName, size, otherreq.maxSizeMB) + else: + totsize = totsize + otherreq.getStartSize() + + lvmLog.debug("totsize -> %s",totsize) + + # if totsize is zero we have no growable reqs left + if totsize == 0: + break + + fraction = float(req.getStartSize())/float(totsize) + + newsize = lvm.clampPVSize(vgfree*fraction, vgreq.pesize) + newsize += cursize[req.logicalVolumeName] + + if req.maxSizeMB: + newsize = min(newsize, req.maxSizeMB) + + req.size = newsize + if req.size != cursize[req.logicalVolumeName]: + nochange = 0 + + cursize[req.logicalVolumeName] = req.size + + lvmLog.debug("Name, size, cursize, vgfree, fraction = %s %s %s %s %s", req.logicalVolumeName, req.size, cursize[req.logicalVolumeName], vgfree, fraction) + + completed.append(req) + + if nochange: + lvmLog.info("In growLogicalVolumes, no changes in size so breaking") + break + + bailcount = bailcount + 1 + if bailcount > 10: + lvmLog.info("In growLogicalVolumes, bailing after 10 interations.") + break + +# grow partitions +def growParts(diskset, requests, newParts): + + # returns free space segments for each drive IN SECTORS + def getFreeSpace(diskset): + free = findFreespace(diskset) + freeSize = {} + largestFree = {} + + # find out the amount of free space on each drive + for key in free.keys(): + if len(free[key]) == 0: + del free[key] + continue + freeSize[key] = 0 + largestFree[key] = 0 + for part in free[key]: + sz = partedUtils.getPartSize(part) + freeSize[key] += sz + if sz > largestFree[key]: + largestFree[key] = sz + + return (free, freeSize, largestFree) + + #### + # start of growParts + #### + newRequest = requests.copy() + +## print("new requests") +## printNewRequestsCyl(diskset, requests) +## print("orig requests") +## printNewRequestsCyl(diskset, newRequest) +## print("\n\n\n") + + (free, freeSize, largestFree) = getFreeSpace(diskset) + + # find growable partitions + growable = {} + growSize = {} + origSize = {} + for request in newRequest.requests: + if request.type != REQUEST_NEW or not request.grow: + continue + + origSize[request.uniqueID] = request.requestSize + if not growable.has_key(request.currentDrive): + growable[request.currentDrive] = [ request ] + else: + growable[request.currentDrive].append(request) + + # there aren't any drives with growable partitions, this is easy! + if not growable.keys(): + return + +## print("new requests before looping") +## printNewRequestsCyl(diskset, requests) +## print("\n\n\n") + + # loop over all drives, grow all growable partitions one at a time + grownList = [] + for drive in growable.keys(): + # no free space on this drive, so can't grow any of its parts + if not free.has_key(drive): + continue + + # process each request + # grow all growable partitions on this drive until all can grow no more + donegrowing = 0 + outer_iter = 0 + lastFreeSize = None + while not donegrowing and outer_iter < 20: + # if less than one sector left, we're done +# if drive not in freeSize.keys() or freeSize[drive] == lastFreeSize: + if drive not in freeSize.keys(): +# print("leaving outer loop because no more space on %s\n\n" % drive) + break +## print("\nAt start:") +## print(drive,freeSize.keys()) +## print(freeSize[drive], lastFreeSize) +## print("\n") + +## print(diskset.diskState()) + + + outer_iter = outer_iter + 1 + donegrowing = 1 + + # pull out list of requests we want to grow on this drive + growList = growable[drive] + + sector_size = diskset.disks[drive].dev.sector_size + cylsectors = diskset.disks[drive].dev.sectors*diskset.disks[drive].dev.heads + + # sort in order of request size, consider biggest first + n = 0 + while n < len(growList): + for request in growList: + if request.size < growList[n].size: + tmp = growList[n] + index = growList.index(request) + growList[n] = request + growList[index] = tmp + n = n + 1 + + # recalculate the total size of growable requests for this drive + # NOTE - we add up the ORIGINAL requested sizes, not grown sizes + growSize[drive] = 0 + for request in growList: + if request.uniqueID in grownList: + continue + growSize[drive] = growSize[drive] + origSize[request.uniqueID] + + thisFreeSize = getFreeSpace(diskset)[1] + # loop over requests for this drive + for request in growList: + # skip if we've finished growing this request + if request.uniqueID in grownList: + continue + + if drive not in freeSize.keys(): + donegrowing = 1 +# print("leaving inner loop because no more space on %s\n\n" % drive) + break + +## print("\nprocessing ID",request.uniqueID, request.mountpoint) +## print("growSize, freeSize = ",growSize[drive], freeSize[drive]) + + donegrowing = 0 + + # get amount of space actually used by current allocation + part = partedUtils.get_partition_by_name(diskset.disks, request.device) + startSize = partedUtils.getPartSize(part) + + # compute fraction of freespace which to give to this + # request. Weight by original request size + percent = origSize[request.uniqueID] / (growSize[drive] * 1.0) + growby = long(percent * thisFreeSize[drive]) + if growby < cylsectors: + growby = cylsectors; + maxsect = startSize + growby + +## print(request) +## print("percent, growby, maxsect, free", percent, growby, maxsect,freeSize[drive], startSize, lastFreeSize) +## print("max is ", maxsect) + + imposedMax = 0 + if request.maxSizeMB: + # round down a cylinder, see comment below + tmpint = request.maxSizeMB*1024.0*1024.0/sector_size + tmpint = long(tmpint / cylsectors) + maxUserSize = tmpint * cylsectors + if maxsect > maxUserSize: + maxsect = long(maxUserSize) + imposedMax = 1 + + else: + # XXX HACK enforce silent limit for swap otherwise it + # can grow up to 2TB! + if request.fstype.name == "swap": + (xxxint, tmpint) = iutil.swapSuggestion(quiet=1) + + # convert to sectors + tmpint = tmpint*1024*1024/sector_size + tmpint = long(tmpint / cylsectors) + maxsugswap = tmpint * cylsectors + userstartsize = origSize[request.uniqueID]*1024*1024/sector_size + if maxsugswap >= userstartsize: + maxsect = maxsugswap + imposedMax = 1 + lvmLog.warning("Enforced max swap size of %s based on suggested max swap", maxsect) + + + # round max fs limit down a cylinder, helps when growing + # so we don't end up with a free cylinder at end if + # maxlimit fell between cylinder boundaries + tmpint = request.fstype.getMaxSizeMB()*1024.0*1024.0/sector_size + tmpint = long(tmpint / cylsectors) + maxFSSize = tmpint * cylsectors + if maxsect > maxFSSize: + maxsect = long(maxFSSize) + imposedMax = 1 + + maxfree = largestFree[drive] + if maxsect > maxfree + startSize: + maxsect = long(maxfree) + startSize + imposedMax = 1 + +# print("freesize, max, maxfree = ",freeSize[drive],maxsect, maxfree) +# print("freeSizeMB, maxMB = ", freeSize[drive] * sector_size/(1024.0 * 1024.0), maxsect * sector_size/(1024.0*1024.0), largestFree[drive] * sector_size/(1024.0*1024.0)) +# print("startsize = ", startSize) + + min = startSize + max = maxsect + diff = max - min + cur = max - (diff / 2) + lastDiff = 0 + + # binary search +## print("start min, max, cur, diffs = ",min,max,cur,diff,lastDiff) + inner_iter = 0 + ret = PARTITION_SUCCESS # request succeeded with initial size + while (max != min) and (lastDiff != diff) and (inner_iter < 2000): +## printNewRequestsCyl(diskset, newRequest) + + # XXX need to request in sectors preferably, more accurate +## print("trying cur=%s" % cur) + request.requestSize = (cur*sector_size)/1024.0/1024.0 + + # try adding + try: + processPartitioning(diskset, newRequest, newParts) + min = cur + except PartitioningError, msg: + ret = PARTITION_FAIL + max = cur +## print("!!!!!!!!!!! processPartitioning failed - %s" % msg) + + lastDiff = diff + diff = max - min + +# print(min, max, diff, cylsectors) +# print(diskset.diskState()) + + cur = max - (diff / 2) + + inner_iter = inner_iter + 1 +# print("sizes at end of loop - cur: %s min:%s max:%s diff:%s lastDiff:%s" % (cur,min,max,diff,lastDiff)) + +# freeSize[drive] = freeSize[drive] - (min - startSize) +# print("shrinking freeSize to ",freeSize[drive], lastFreeSize) +# if freeSize[drive] < 0: +# print("freesize < 0!") +# freeSize[drive] = 0 + + # we could have failed on the last try, in which case we + # should go back to the smaller size + if ret == PARTITION_FAIL: +# print("growing finally failed at size", min) + request.requestSize = min*sector_size/1024.0/1024.0 + processPartitioning(diskset, newRequest, newParts) + +# print("end min, max, cur, diffs = ",min,max,cur,diff,lastDiff) +# print("%s took %s loops" % (request.mountpoint, inner_iter)) + lastFreeSize = freeSize[drive] + (free, freeSize, largestFree) = getFreeSpace(diskset) +# print(Freespace(free)) + + if ret == PARTITION_FAIL or (max == maxsect and imposedMax): +# print("putting ",request.uniqueID,request.mountpoint," in grownList") + grownList.append(request.uniqueID) + growSize[drive] = growSize[drive] - origSize[request.uniqueID] + if growSize[drive] < 0: +# print("growsize < 0!") + growSize[drive] = 0 + +def setPreexistParts(diskset, requests): + for request in requests: + if request.type != REQUEST_PREEXIST: + continue + if not diskset.disks.has_key(request.drive): + lvmLog.info("pre-existing partition on non-native disk %s, ignoring" %(request.drive,)) + continue + disk = diskset.disks[request.drive] + part = disk.next_partition() + while part: + if part.geom.start == request.start and part.geom.end == request.end: + if partedUtils.isEfiSystemPartition(part) and \ + request.fstype.name == "vfat": + request.fstype = fsset.fileSystemTypeGet("efi") + # if the partition is being resized, we do that now + if request.targetSize is not None: + startSec = part.geom.start + endSec = part.geom.start + long(((request.targetSize * 1024L * 1024L) / disk.dev.sector_size)) - 1 + + try: + g = part.geom.duplicate() + g.set_end(endSec) + constraint = g.constraint_exact() + part.set_geometry(constraint, startSec, endSec) + except parted.error, msg: + log.error("error setting geometry for partition %s: %s" %(partedUtils.get_partition_name(part), msg)) + raise PartitioningError, _("Error resizing partition %s.\n\n%s") %(partedUtils.get_partition_name(part), msg) + + if startSec != part.geom.start: + raise PartitioningError, _("Start of partition %s was moved when resizing") %(partedUtils.get_partition_name(part),) + + request.device = partedUtils.get_partition_name(part) + if request.fstype: + if request.fstype.getName() != request.origfstype.getName(): + if part.is_flag_available(parted.PARTITION_RAID): + if request.fstype.getName() == "software RAID": + part.set_flag(parted.PARTITION_RAID, 1) + else: + part.set_flag(parted.PARTITION_RAID, 0) + if part.is_flag_available(parted.PARTITION_LVM): + if request.fstype.getName() == "physical volume (LVM)": + part.set_flag(parted.PARTITION_LVM, 1) + else: + part.set_flag(parted.PARTITION_LVM, 0) + + partedUtils.set_partition_file_system_type(part, request.fstype) + + break + part = disk.next_partition(part) + +def deletePart(diskset, delete): + disk = diskset.disks[delete.drive] + part = disk.next_partition() + while part: + if part.geom.start == delete.start and part.geom.end == delete.end: + disk.delete_partition(part) + return + part = disk.next_partition(part) + +def processPartitioning(diskset, requests, newParts): + # collect a hash of all the devices that we have created extended + # partitions on. When we remove these extended partitions the logicals + # (all of which we created) will be destroyed along with it. + extendeds = {} + + for part in newParts.parts: + if part.type == parted.PARTITION_EXTENDED: + extendeds[part.geom.dev.path] = None + + # Go through the list again and check for each logical partition we have. + # If we created the extended partition on the same device as the logical + # partition, remove it from out list, as it will be cleaned up for us + # when the extended partition gets removed. + dellist = [] + for part in newParts.parts: + if (part.type & parted.PARTITION_LOGICAL + and extendeds.has_key(part.geom.dev.path)): + dellist.append(part) + + for part in dellist: + newParts.parts.remove(part) + + # Finally, remove all of the partitions we added in the last try from + # the disks. We'll start again from there. + for part in newParts.parts: + part.disk.delete_partition(part) + + newParts.reset() + + for request in requests.requests: + if request.type == REQUEST_NEW: + request.device = None + + setPreexistParts(diskset, requests.requests) + + # sort requests by size + requests.sortRequests() + + # partitioning algorithm in simplistic terms + # + # we want to allocate partitions such that the most specifically + # spelled out partitions get what they want first in order to ensure + # they don't get preempted. first conflict found returns an error + # which must be handled by the caller by saying that the partition + # add is impossible (XXX can we get an impossible situation after delete?) + # + # potentially confusing terms + # type == primary vs logical + # + # order to allocate: + # start and end cylinders given (note that start + size & !grow is equivalent) + # drive, partnum + # drive, type + # drive + # priority partition (/boot or /) + # size + + # run through with primary only constraints first + try: + fitConstrained(diskset, requests, 1, newParts) + except PartitioningError, msg: + raise PartitioningError, _("Could not allocate cylinder-based partitions as primary partitions.\n") + str(msg) + + try: + fitSized(diskset, requests, 1, newParts) + except PartitioningError, msg: + raise PartitioningError, _("Could not allocate partitions as primary partitions.\n") + str(msg) + + try: + fitConstrained(diskset, requests, 0, newParts) + except PartitioningError, msg: + raise PartitioningError, _("Could not allocate cylinder-based partitions.\n") + str(msg) + + # Don't need to handle the exception here since we leave the message alone. + fitSized(diskset, requests, 0, newParts) + + for request in requests.requests: + # set the unique identifier for raid and lvm devices + if request.type == REQUEST_RAID and not request.device: + request.device = str(request.uniqueID) + if request.type == REQUEST_VG and not request.device: + request.device = str(request.uniqueID) + # anything better we can use for the logical volume? + if request.type == REQUEST_LV and not request.device: + request.device = str(request.uniqueID) + + if not request.device: + raise PartitioningError, "Unsatisfied partition request\n%s" % request + + # get the sizes for raid devices, vgs, and logical volumes + for request in requests.requests: + if request.type == REQUEST_RAID: + request.size = request.getActualSize(requests, diskset) + elif request.type == REQUEST_VG: + request.size = request.getActualSize(requests, diskset) + elif request.type == REQUEST_LV: + if request.grow: + request.setSize(request.getStartSize()) + else: + request.size = request.getActualSize(requests, diskset) + elif request.preexist: + # we need to keep track of the max size of preexisting partitions + # FIXME: we should also get the max size for LVs at some point + part = partedUtils.get_partition_by_name(diskset.disks, request.device) + request.maxResizeSize = partedUtils.getMaxAvailPartSizeMB(part) + +## print("disk layout after everything is done") +## print(diskset.diskState()) + +def doPartitioning(diskset, requests, doRefresh = 1): + for request in requests.requests: + request.requestSize = request.size + request.currentDrive = None + + if doRefresh: + diskset.refreshDevices() + # XXX - handle delete requests + for delete in requests.deletes: + if isinstance(delete, partRequests.DeleteSpec): + deletePart(diskset, delete) + # FIXME: do we need to do anything with other types of deletes?? + + newParts = partlist() + + try: + processPartitioning(diskset, requests, newParts) + except PartitioningError, msg: + raise PartitioningError, "Partitioning failed: %s" % msg + + growParts(diskset, requests, newParts) + + newParts.reset() + + for req in requests.getBootableRequest() or []: + ret = bootRequestCheck(req, diskset) + if ret == BOOTALPHA_NOT_BSD: + raise PartitioningWarning, _("Boot partition %s doesn't belong to a BSD disk label. SRM won't be able to boot from this partition. Use a partition belonging to a BSD disk label or change this device disk label to BSD.") %(req.mountpoint,) + elif ret == BOOTALPHA_NO_RESERVED_SPACE: + raise PartitioningWarning, _("Boot partition %s doesn't belong to a disk with enough free space at its beginning for the bootloader to live on. Make sure that there's at least 5MB of free space at the beginning of the disk that contains /boot") %(req.mountpoint,) + elif ret == BOOTEFI_NOT_VFAT: + raise PartitioningError, _("Boot partition %s isn't a VFAT partition. EFI won't be able to boot from this partition.") %(req.mountpoint,) + elif ret == BOOTIPSERIES_TOO_HIGH: + raise PartitioningError, _("The boot partition must entirely be in the first 4GB of the disk. OpenFirmware won't be able to boot this installation.") + elif req == BOOT_NOT_EXT2: + raise PartitioningError, _("Boot partition %s is not a Linux filesystem, such as ext3. The system won't be able to boot from this partition.") %(req.mountpoint,) + elif ret != PARTITION_SUCCESS: + # more specific message? + raise PartitioningWarning, _("Boot partition %s may not meet booting constraints for your architecture.") %(req.mountpoint,) + + # now grow the logical partitions + growLogicalVolumes(diskset, requests) + + # make sure our logical volumes still fit + # + # XXXX should make all this used lvm.getVGFreeSpace() and + # lvm.getVGUsedSpace() at some point + # + + vgused = {} + for request in requests.requests: + if request.type == REQUEST_LV: + size = int(request.getActualSize(requests, diskset, True)) + if vgused.has_key(request.volumeGroup): + vgused[request.volumeGroup] = (vgused[request.volumeGroup] + + size) + else: + vgused[request.volumeGroup] = size + + for vg in vgused.keys(): + request = requests.getRequestByID(vg) + lvmLog.info("Used size vs. available for vg %s: %s %s", request.volumeGroupName, vgused[vg], request.getActualSize(requests, diskset)) + if vgused[vg] > request.getActualSize(requests, diskset): + raise PartitioningError, _("Adding this partition would not " + "leave enough disk space for already " + "allocated logical volumes in " + "%s." % (request.volumeGroupName)) + +# given clearpart specification execute it +# probably want to reset diskset and partition request lists before calling +# this the first time +def doClearPartAction(pomona, partitions, diskset): + type = partitions.autoClearPartType + cleardrives = partitions.autoClearPartDrives + initAll = partitions.reinitializeDisks + + if type == CLEARPART_TYPE_ALL: + linuxOnly = 0 + elif type == CLEARPART_TYPE_NONE: + return + else: + raise ValueError, "Invalid clear part type in doClearPartAction" + + drives = diskset.disks.keys() + drives.sort() + + for drive in drives: + # skip drives not in clear drive list + if (cleardrives and len(cleardrives) > 0 and not drive in cleardrives) or \ + drive in diskset.skippedDisks: + continue + disk = diskset.disks[drive] + part = disk.next_partition() + while part: + if (not part.is_active() or (part.type == parted.PARTITION_EXTENDED) or + (part.disk.type.name == "mac" and part.num == 1 and part.get_name() == "Apple")): + part = disk.next_partition(part) + continue + if part.fs_type: + ptype = partedUtils.get_partition_file_system_type(part) + else: + ptype = None + # we want to do the clearing if + # 1) clearAll is set + # 2) there's a fsystem on the partition and it's a "native" fs + # 3) there's not fsystem but the numeric id of partition is native + # 4) the ptable doesn't support numeric ids, but it appears to be + # a RAID or LVM device (#107319) + # 5) the drive contains protected partitions and initAll is set + if ((linuxOnly == 0) or (ptype and ptype.isLinuxNativeFS()) or + (initAll and + partedUtils.hasProtectedPartitions(drive, pomona)) or + (not ptype and + partedUtils.isLinuxNativeByNumtype(part.native_type)) or + ((part.native_type == -1) and # the ptable doesn't have types + ((part.is_flag_available(parted.PARTITION_RAID) and part.get_flag(parted.PARTITION_RAID)) or # this is a RAID + (part.is_flag_available(parted.PARTITION_LVM) and part.get_flag(parted.PARTITION_LVM)) # or an LVM + ))): + old = partitions.getRequestByDeviceName(partedUtils.get_partition_name(part)) + if old.getProtected(): + part = disk.next_partition(part) + continue + + partitions.deleteDependentRequests(old) + partitions.removeRequest(old) + + drive = partedUtils.get_partition_drive(part) + delete = partRequests.DeleteSpec(drive, part.geom.start, + part.geom.end) + partitions.addDelete(delete) + + part = disk.next_partition(part) + + # set the diskset up + try: + doPartitioning(diskset, partitions, doRefresh = 1) + except PartitioningError: # if we get an error here, it isn't overly relevant + pass + + for drive in drives: + if (cleardrives and len(cleardrives) > 0 and not drive in cleardrives) or \ + drive in diskset.skippedDisks: + continue + + disk = diskset.disks[drive] + ext = disk.extended_partition + # if the extended is empty, blow it away + if ext and len(partedUtils.get_logical_partitions(disk)) == 0: + delete = partRequests.DeleteSpec(drive, ext.geom.start, + ext.geom.end) + old = partitions.getRequestByDeviceName(partedUtils.get_partition_name(ext)) + partitions.removeRequest(old) + partitions.addDelete(delete) + deletePart(diskset, delete) + continue + +def doAutoPartition(pomona): + diskset = pomona.id.diskset + partitions = pomona.id.partitions + + if pomona.dir == DISPATCH_BACK: + diskset.refreshDevices() + partitions.setFromDisk(diskset) + partitions.setProtected(pomona.dispatch) + partitions.autoPartitionRequests = [] + return + + # if no auto partition info in instclass we bail + if len(partitions.autoPartitionRequests) < 1: + #return DISPATCH_NOOP + # XXX if we noop, then we fail later steps... let's just make it + # the workstation default. should instead just never get here + # if no autopart info + pomona.setDefaultPartitioning(partitions, doClear = 0) + + # reset drive and request info to original state + # XXX only do this if we're dirty +## id.diskset.refreshDevices() +## id.partrequests = PartitionRequests(id.diskset) + doClearPartAction(pomona, partitions, diskset) + + # XXX clearpartdrives is overloaded as drives we want to use for linux + drives = [] + initial_free = findFreespace(diskset) + initial_free_keys = initial_free.keys() + + if partitions.autoClearPartDrives: + for drive in filter (lambda d: d in initial_free_keys, partitions.autoClearPartDrives): + free = 0 + for f in initial_free[drive]: + size = f.geom.end - f.geom.start + # don't count any partition smaller than 1M + if (size > 2048): + free += size + for req in partitions.deletes: + if isinstance(req, partRequests.DeleteSpec) and req.drive == drive: + size = req.end - req.start + # don't count any partition smaller than 1M + if (size > 2048): + free += size + + # If there's less than 10M free, forget it. + if free > 20480: + drives.append(drive) + del initial_free + + for request in partitions.autoPartitionRequests: + if (isinstance(request, partRequests.PartitionSpec) and + request.device): + # get the preexisting partition they want to use + req = partitions.getRequestByDeviceName(request.device) + if not req or not req.type or req.type != REQUEST_PREEXIST: + pomona.intf.messageWindow(_("Requested Partition Does Not Exist"), + _("Unable to locate partition %s to use " + "for %s.\n\n" + "Press 'OK' to exit the installer.") + % (request.device, request.mountpoint), + custom_icon='error') + sys.exit(0) + + # now go through and set things from the request to the + # preexisting partition's request... ladeda + if request.mountpoint: + req.mountpoint = request.mountpoint + if request.uniqueID: # for raid to work + req.uniqueID = request.uniqueID + if request.fsopts: + req.fsopts = request.fsopts + if not request.format: + req.format = 0 + else: + req.format = 1 + req.fstype = request.fstype + # XXX whee! lots of cut and paste code lies below + elif (isinstance(request, partRequests.RaidRequestSpec) and + request.preexist == 1): + req = partitions.getRequestByDeviceName(request.device) + if not req or req.preexist == 0: + pomona.intf.messageWindow(_("Requested Raid Device Does Not Exist"), + _("Unable to locate raid device %s to use " + "for %s.\n\n" + "Press 'OK' to exit the installer.") + % (request.device, + request.mountpoint), + custom_icon='error') + sys.exit(0) + + # now go through and set things from the request to the + # preexisting partition's request... ladeda + if request.mountpoint: + req.mountpoint = request.mountpoint + if request.uniqueID: # for raid to work + req.uniqueID = request.uniqueID + if request.fsopts: + req.fsopts = request.fsopts + if not request.format: + req.format = 0 + else: + req.format = 1 + req.fstype = request.fstype + # XXX not copying the raid bits because they should be handled + # automagically (actually, people probably aren't specifying them) + + elif (isinstance(request, partRequests.VolumeGroupRequestSpec) and + request.preexist == 1): + # get the preexisting partition they want to use + req = partitions.getRequestByVolumeGroupName(request.volumeGroupName) + if not req or req.preexist == 0 or req.format == 1: + pomona.intf.messageWindow(_("Requested Volume Group Does Not Exist"), + _("Unable to locate volume group %s to use " + "for %s.\n\n" + "Press 'OK' to exit the installer.") + % (request.volumeGroupName, + request.mountpoint), + custom_icon='error') + sys.exit(0) + + oldid = None + # now go through and set things from the request to the + # preexisting partition's request... ladeda + if request.physicalVolumes: + req.physicalVolumes = request.physicalVolumes + if request.pesize: + req.pesize = request.pesize + if request.uniqueID: # for raid to work + oldid = req.uniqueID + req.uniqueID = request.uniqueID + if request.fsopts: + req.fsopts = request.fsopts + if not request.format: + req.format = 0 + else: + req.format = 1 + + # we also need to go through and remap everything which we + # previously found to our new id. yay! + if oldid is not None: + for lv in partitions.getLVMLVForVGID(oldid): + lv.volumeGroup = req.uniqueID + + + elif (isinstance(request, partRequests.LogicalVolumeRequestSpec) and + request.preexist == 1): + # get the preexisting partition they want to use + req = partitions.getRequestByLogicalVolumeName(request.logicalVolumeName) + if not req or req.preexist == 0: + pomona.intf.messageWindow(_("Requested Logical Volume Does Not Exist"), + _("Unable to locate logical volume %s to use " + "for %s.\n\n" + "Press 'OK' to exit the installer.") + % (request.logicalVolumeName, + request.mountpoint), + custom_icon='error') + sys.exit(0) + + # now go through and set things from the request to the + # preexisting partition's request... ladeda + if request.volumeGroup: + req.volumeGroup = request.volumeGroup + if request.mountpoint: + req.mountpoint = request.mountpoint + if request.uniqueID: # for raid to work + req.uniqueID = request.uniqueID + if request.fsopts: + req.fsopts = request.fsopts + if not request.format: + req.format = 0 + else: + req.format = 1 + req.fstype = request.fstype + else: + req = copy.copy(request) + + if req.type == REQUEST_NEW and not req.drive: + req.drive = drives + + # this is kind of a hack, but if we're doing autopart encryption + # and the request is a PV, encrypt it + if partitions.autoEncrypt and req.type == REQUEST_NEW and \ + isinstance(req.fstype, fsset.lvmPhysicalVolumeDummyFileSystem): + req.encryption = cryptodev.LUKSDevice(passphrase=partitions.encryptionPassphrase, format=1) + + # if this is a multidrive request, we need to create one per drive + if req.type == REQUEST_NEW and req.multidrive: + if not req.drive: + req.drive = diskset.disks.keys() + + for drive in req.drive: + r = copy.copy(req) + r.encryption = copy.deepcopy(req.encryption) + r.drive = [ drive ] + partitions.addRequest(r) + continue + + if (isinstance(req, partRequests.VolumeGroupRequestSpec)): + # if the number of physical volumes requested is zero, then + # add _all_ physical volumes we can find + if ((len(req.physicalVolumes) == 0) + or (not req.physicalVolumes)): + req.physicalVolumes = [] + for r in partitions.requests: + if isinstance(r.fstype, + fsset.lvmPhysicalVolumeDummyFileSystem): + valid = 0 + if ((not partitions.autoClearPartDrives) or + len(partitions.autoClearPartDrives) == 0): + valid = 1 + else: + if not isinstance(r, partRequests.RaidRequestSpec): + for d in r.drive: + if d in partitions.autoClearPartDrives: + valid = 1 + break + + if not isinstance(r, partRequests.RaidRequestSpec): + if not r.multidrive: + valid = 0 + + if valid: + req.physicalVolumes.append(r.uniqueID) + # FIXME: this is a hack so that autopartition'd vgs + # can have a unique name + if req.autoname == 1 and req.volumeGroupName == "lvm": + n = lvm.createSuggestedVGName(partitions, pomona.id.network) + req.volumeGroupName = n + + if (isinstance(req, partRequests.LogicalVolumeRequestSpec)): + # if the volgroup is set to a string, we probably need + # to find that volgroup and use it's id + if type(req.volumeGroup) == type(""): + r = None + if req.volumeGroup == "lvm": + for p in partitions.requests: + if isinstance(p, partRequests.VolumeGroupRequestSpec) and p.autoname == 1: + r = p + break + else: + r = partitions.getRequestByVolumeGroupName(req.volumeGroup) + if r is not None: + req.volumeGroup = r.uniqueID + else: + raise RuntimeError, "Unable to find the volume group for logical volume %s" %(req.logicalVolumeName,) + + partitions.addRequest(req) + + # Remove all preexisting VG requests that reference nonexistant PV + # requests. These VGs should only be present on installs where we're + # using preexisting partitions that already have LVM information. We + # need to do the same thing for preexisting RAID requests, as well. + removeReqs = [] + + for req in partitions.requests: + if isinstance(req, partRequests.VolumeGroupRequestSpec): + lst = req.physicalVolumes + elif isinstance(req, partRequests.RaidRequestSpec): + lst = req.raidmembers + else: + continue + + if len(filter (lambda id: partitions.getRequestByID(id) != None, lst)) == 0: + removeReqs.append(req) + + for req in removeReqs: + partitions.removeRequest(req) + + removeReqs = [] + + # Now that we've removed bad VGs, remove all LVs that would have + # resided on those VGs. + for req in filter (lambda r: isinstance(r, partRequests.LogicalVolumeRequestSpec), partitions.requests): + if partitions.getRequestByID(req.volumeGroup) == None: + removeReqs.append(req) + + for req in removeReqs: + partitions.removeRequest(req) + + # sanity checks for the auto partitioning requests; mostly only useful + # for kickstart as our installclass defaults SHOULD be sane + for req in partitions.requests: + errors = req.sanityCheckRequest(partitions) + if errors: + pomona.intf.messageWindow(_("Automatic Partitioning Errors"), + _("The following errors occurred with your " + "partitioning:\n\n%s\n\n" + "Press 'OK' to exit the installer.") % + (errors,), custom_icon='error') + sys.exit(0) + + try: + doPartitioning(diskset, partitions, doRefresh = 0) + except PartitioningWarning, msg: + pomona.intf.messageWindow(_("Warnings During Automatic Partitioning"), + _("Following warnings occurred during automatic " + "partitioning:\n\n%s") % (msg,), + custom_icon='warning') + except PartitioningError, msg: + # restore drives to original state + diskset.refreshDevices() + partitions.setFromDisk(diskset) + partitions.setProtected(pomona.dispatch) + pomona.dispatch.skipStep("partition", skip = 0) + pomona.intf.messageWindow(_("Error Partitioning"), + _("Could not allocate requested partitions: \n\n" + "%s.") % (msg,), custom_icon='error') + + # now do a full check of the requests + (errors, warnings) = partitions.sanityCheckAllRequests(diskset) + if warnings: + for warning in warnings: + lvmLog.warning(warning) + if errors: + errortxt = string.join(errors, '\n') + extra = _("\n\nPress 'OK' to choose a different partitioning option.") + + pomona.intf.messageWindow(_("Automatic Partitioning Errors"), + _("The following errors occurred with your " + "partitioning:\n\n%s\n\n" + "This can happen if there is not enough " + "space on your hard drive(s) for the " + "installation. %s") + % (errortxt, extra), + custom_icon='error') + return DISPATCH_BACK + +def autoCreatePartitionRequests(autoreq): + """Return a list of requests created with a shorthand notation. + + Mainly used by installclasses; make a list of tuples of the form + (mntpt, fstype, minsize, maxsize, grow, format, asvol) + mntpt = None for non-mountable, otherwise is mount point + fstype = None to use default, otherwise a string + minsize = smallest size + maxsize = max size, or None means no max + grow = 0 or 1, should partition be grown + format = 0 or 1, whether to format + asvol = 0 or 1, whether or not it should be a logical volume (ignored) + """ + + requests = [] + for (mntpt, fstype, minsize, maxsize, grow, format, asvol) in autoreq: + if fstype: + ptype = fsset.fileSystemTypeGet(fstype) + else: + ptype = fsset.fileSystemTypeGetDefault() + + newrequest = partRequests.PartitionSpec(ptype, + mountpoint = mntpt, + size = minsize, + maxSizeMB = maxsize, + grow = grow, + format = format) + + requests.append(newrequest) + + return requests + +def autoCreateLVMPartitionRequests(autoreq): + """Return a list of requests created with a shorthand notation using LVM. + + Mainly used by installclasses; make a list of tuples of the form + (mntpt, fstype, minsize, maxsize, grow, format) + mntpt = None for non-mountable, otherwise is mount point + fstype = None to use default, otherwise a string + minsize = smallest size + maxsize = max size, or None means no max + grow = 0 or 1, should partition be grown + format = 0 or 1, whether to format + asvol = 0 or 1, whether or not it should be a logical volume + """ + + requests = [] + nr = partRequests.PartitionSpec(fsset.fileSystemTypeGet("physical volume (LVM)"), + mountpoint = None, + size = 0, + maxSizeMB = None, + grow = 1, + format = 1, + multidrive = 1) + + requests.append(nr) + nr = partRequests.VolumeGroupRequestSpec(fstype = None, + vgname = "lvm", + physvols = [], + format = 1) + nr.autoname = 1 + requests.append(nr) + + volnum = 0 + for (mntpt, fstype, minsize, maxsize, grow, format, asvol) in autoreq: + if fstype: + ptype = fsset.fileSystemTypeGet(fstype) + else: + ptype = fsset.fileSystemTypeGetDefault() + + if not asvol: + newrequest = partRequests.PartitionSpec(ptype, + mountpoint = mntpt, + size = minsize, + maxSizeMB = maxsize, + grow = grow, + format = format) + else: + newrequest = partRequests.LogicalVolumeRequestSpec(ptype, + mountpoint = mntpt, + size = minsize, + maxSizeMB = maxsize, + grow = grow, + format = format, + lvname = "LogVol%02d" %(volnum,), + volgroup = "lvm") + volnum += 1 + + + requests.append(newrequest) + + return requests + +def getAutopartitionBoot(): + """Return the proper shorthand for the boot dir (arch dependent).""" + return [ ("/boot", None, 200, None, 0, 1, 0) ] + + +# XXX hack but these are common strings to TUI and GUI +PARTMETHOD_TYPE_DESCR_TEXT = N_("Automatic Partitioning sets partitions " + "based on the selected installation type. " + "You also " + "can customize the partitions once they " + "have been created.\n\n" + "The manual disk partitioning tool, Disk Druid, " + "allows you " + "to create partitions in an interactive " + "environment. You can set the file system " + "types, mount points, partition sizes, and more.") + +AUTOPART_DISK_CHOICE_DESCR_TEXT = N_("Before automatic partitioning can be " + "set up by the installation program, you " + "must choose how to use the space on " + "your hard drives.") + +CLEARPART_TYPE_ALL_DESCR_TEXT = N_("Remove all partitions on this system") +CLEARPART_TYPE_LINUX_DESCR_TEXT = N_("Remove all Linux partitions on this system") +CLEARPART_TYPE_NONE_DESCR_TEXT = N_("Keep all partitions and use existing free space") diff --git a/pkgs/core/pomona/src/backend.py b/pkgs/core/pomona/src/backend.py new file mode 100644 index 0000000..325fbe8 --- /dev/null +++ b/pkgs/core/pomona/src/backend.py @@ -0,0 +1,127 @@ +# +# backend.py: Interface for installation backends +# +# Paul Nasrat <pnasrat@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# +# Copyright (c) 2005 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# general public license. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import shutil +import iutil +import os, sys +import logging +from constants import * + +import packages + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +from flags import flags +log = logging.getLogger("pomona") + +class PomonaBackend: + def __init__(self, instPath): + """Abstract backend class all backends should inherit from this + @param instPath: root path for the installation to occur""" + + self.instPath = instPath + self.modeText = "" + + # some backends may have a special case for rootfs formatting + self.skipFormatRoot = False + + def doPreSelection(self, intf, id, instPath): + pass + + def doPostSelection(self, pomona): + pass + + def doPreInstall(self, pomona): + pass + + def doPostInstall(self, pomona): + sys.stdout.flush() + + def doInstall(self, pomona): + log.warning("doInstall not implemented for backend!") + pass + + def postAction(self, pomona): + pass + + def kernelVersionList(self): + return [] + + def doInitialSetup(self, pomona): + pass + + def doRepoSetup(self, pomona): + log.warning("doRepoSetup not implemented for backend!") + pass + + def groupExists(self, group): + log.warning("groupExists not implemented for backend!") + pass + + def selectGroup(self, group, *args): + log.warning("selectGroup not implemented for backend!") + pass + + def deselectGroup(self, group, *args): + log.warning("deselectGroup not implemented for backend!") + pass + + def packageExists(self, pkg): + log.warning("packageExists not implemented for backend!") + pass + + def selectPackage(self, pkg, *args): + log.warning("selectPackage not implemented for backend!") + pass + + def deselectPackage(self, pkg, *args): + log.warning("deselectPackage not implemented for backend!") + pass + + def getDefaultGroups(self, pomona): + log.warning("getDefaultGroups not implemented for backend!") + pass + + def writeConfiguration(self): + log.warning("writeConfig not implemented for backend!") + pass + + def getRequiredMedia(self): + log.warning("getRequiredMedia not implmented for backend!") + pass + +def doRepoSetup(pomona): + pomona.backend.doInitialSetup(pomona) + if pomona.backend.doRepoSetup(pomona) == DISPATCH_BACK: + return DISPATCH_BACK + +def doPostSelection(pomona): + return pomona.backend.doPostSelection(pomona) + +def doPreInstall(pomona): + pomona.backend.doPreInstall(pomona) + +def doPostInstall(pomona): + pomona.backend.doPostInstall(pomona) + +def doInstall(pomona): + pomona.backend.doInstall(pomona) + +def writeConfiguration(pomona): + log.info("Writing main configuration") + pomona.id.write(pomona) + pomona.backend.writeConfiguration() diff --git a/pkgs/core/pomona/src/bootloader.py b/pkgs/core/pomona/src/bootloader.py new file mode 100644 index 0000000..755b3eb --- /dev/null +++ b/pkgs/core/pomona/src/bootloader.py @@ -0,0 +1,740 @@ +# +# bootloader.py: pomona bootloader shims +# +# Erik Troan <ewt@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# +# Copyright 2001-2006 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# general public license. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import isys +import partedUtils +import os +import sys +import iutil +import string +import crypt +import random +import shutil +import struct +from copy import copy +from flags import flags +from constants import * + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +import logging +log = logging.getLogger("pomona") + +from fsset import * + +import pyfire.executil + +dosFilesystems = ('FAT', 'fat16', 'fat32', 'ntfs', 'hpfs') + +def doesDualBoot(): + return 1 + +def checkForBootBlock(device): + fd = os.open(device, os.O_RDONLY) + buf = os.read(fd, 512) + os.close(fd) + if len(buf) >= 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaa55,): + return True + return False + +# takes a line like #boot=/dev/hda and returns /dev/hda +# also handles cases like quoted versions and other nonsense +def getBootDevString(line): + dev = string.split(line, '=')[1] + dev = string.strip(dev) + dev = string.replace(dev, '"', '') + dev = string.replace(dev, "'", "") + return dev + +# hack and a half +# there's no guarantee that data is written to the disk and grub +# reads both the filesystem and the disk. suck. +def syncDataToDisk(dev, mntpt, instRoot = "/"): + isys.sync() + isys.sync() + isys.sync() + +class BootyNoKernelWarning(Exception): + pass + +class KernelArguments: + + def get(self): + return self.args + + def set(self, args): + self.args = args + + def chandevget(self): + return self.cargs + + def chandevset(self, args): + self.cargs = args + + def append(self, args): + if self.args: + # don't duplicate the addition of an argument (#128492) + if self.args.find(args) != -1: + return + self.args = self.args + " " + self.args = self.args + "%s" % (args,) + + + def __init__(self): + newArgs = [] + # look for kernel arguments we know should be preserved and add them + ourargs = ["speakup_synth=", "apic", "noapic", "apm=", "ide=nodma", + "noht", "acpi=", "video=", "pci="] + f = open("/proc/cmdline") + cmdline = f.read()[:-1] + f.close() + cmdlineargs = cmdline.split(" ") + for arg in cmdlineargs: + for check in ourargs: + if arg.startswith(check): + newArgs.append(arg) + + self.args = " ".join(newArgs) + +class BootImages: + """A collection to keep track of boot images available on the system. + Examples would be: + ('linux', 'Red Hat Linux', 'ext2'), + ('Other', 'Other', 'fat32'), ... + """ + def __init__(self): + self.default = None + self.images = {} + + def getImages(self): + """returns dictionary of (label, longlabel, devtype) pairs + indexed by device""" + # return a copy so users can modify it w/o affecting us + return copy(self.images) + + def setImageLabel(self, dev, label, setLong = 0): + orig = self.images[dev] + if setLong: + self.images[dev] = (orig[0], label, orig[2]) + else: + self.images[dev] = (label, orig[1], orig[2]) + + def setDefault(self, default): + # default is a device + self.default = default + + def getDefault(self): + return self.default + + # XXX this has internal pomona-ish knowledge. ick + def setup(self, diskSet, fsset): + devices = {} + devs = self.availableBootDevices(diskSet, fsset) + for (dev, type) in devs: + devices[dev] = 1 + + # These partitions have disappeared + for dev in self.images.keys(): + if not devices.has_key(dev): + del self.images[dev] + + # These have appeared + for (dev, type) in devs: + if not self.images.has_key(dev): + if type in dosFilesystems and doesDualBoot(): + self.images[dev] = ("Other", "Other", type) + else: + self.images[dev] = (None, None, type) + + if not self.images.has_key(self.default): + entry = fsset.getEntryByMountPoint('/') + self.default = entry.device.getDevice() + (label, longlabel, type) = self.images[self.default] + if not label: + self.images[self.default] = ("linux", getProductName(), type) + + # XXX more internal pomona knowledge + def availableBootDevices(self, diskSet, fsset): + devs = [] + foundDos = 0 + for (dev, type) in diskSet.partitionTypes(): + if type in dosFilesystems and not foundDos and doesDualBoot(): + import isys + import partedUtils + + part = partedUtils.get_partition_by_name(diskSet.disks, dev) + if part.native_type not in partedUtils.dosPartitionTypes: + continue + + try: + bootable = checkForBootBlock(dev) + devs.append((dev, type)) + foundDos = 1 + except Exception, e: + #log("exception checking %s: %s" %(dev, e)) + pass + elif ((type == 'ntfs' or type =='hpfs') and not foundDos and doesDualBoot()): + devs.append((dev, type)) + # maybe questionable, but the first ntfs or fat is likely to + # be the correct one to boot with XP using ntfs + foundDos = 1 + + slash = fsset.getEntryByMountPoint('/') + if not slash or not slash.device or not slash.fsystem: + raise ValueError,("Trying to pick boot devices but do not have a " + "sane root partition. Aborting install.") + devs.append((slash.device.getDevice(), slash.fsystem.getName())) + + devs.sort() + return devs + +class bootloaderInfo: + def useGrub(self): + return self.useGrubVal + + def setForceLBA(self, val): + pass + + def setPassword(self, val, isCrypted = 1): + pass + + def getPassword(self): + pass + + def getDevice(self): + return self.device + + def setDevice(self, device): + self.device = device + + (dev, part) = getDiskPart(device) + if part is None: + self.defaultDevice = "mbr" + else: + self.defaultDevice = "partition" + + def createDriveList(self): + # create a drive list that we can use for drive mappings + # XXX has pomona internals knowledge + import isys + drives = isys.hardDriveDict().keys() + drives.sort(isys.compareDrives) + + # now filter out all of the drives without media present + drives = filter(lambda x: isys.mediaPresent(x), drives) + + return drives + + def updateDriveList(self, sortedList=[]): + self._drivelist = self.createDriveList() + + # If we're given a sort order, make sure the drives listed in it + # are put at the head of the drivelist in that order. All other + # drives follow behind in whatever order they're found. + if sortedList != []: + revSortedList = sortedList + revSortedList.reverse() + + for i in revSortedList: + try: + ele = self._drivelist.pop(self._drivelist.index(i)) + self._drivelist.insert(0, ele) + except: + pass + + def _getDriveList(self): + if self._drivelist is not None: + return self._drivelist + self.updateDriveList() + return self._drivelist + + def _setDriveList(self, val): + self._drivelist = val + drivelist = property(_getDriveList, _setDriveList) + + def __init__(self): + self.args = KernelArguments() + self.images = BootImages() + self.device = None + self.defaultDevice = None # XXX hack, used by kickstart + self.useGrubVal = 0 # only used on x86 + self.configfile = None + self.kernelLocation = "/boot/" + self.forceLBA32 = 0 + self.password = None + self.pure = None + self.above1024 = 0 + self._drivelist = None + +class x86BootloaderInfo(bootloaderInfo): + def setPassword(self, val, isCrypted = 1): + if not val: + self.password = val + self.pure = val + return + + if isCrypted and self.useGrubVal == 0: + #log("requested crypted password with lilo; ignoring") + self.pure = None + return + elif isCrypted: + self.password = val + self.pure = None + else: + salt = "$1$" + saltLen = 8 + + saltchars = string.letters + string.digits + './' + for i in range(saltLen): + salt += random.choice(saltchars) + + self.password = crypt.crypt(val, salt) + self.pure = val + + def getPassword (self): + return self.pure + + def setForceLBA(self, val): + self.forceLBA32 = val + + def getPhysicalDevices(self, device): + # This finds a list of devices on which the given device name resides. + # Accepted values for "device" are physical disks ("hda"), + # and real partitions on physical disks ("hda1"). + # + return [device] + + def writeGrub(self, instRoot, fsset, bl, kernelList, chainList, + defaultDev): + + images = bl.images.getImages() + rootDev = fsset.getEntryByMountPoint("/").device.getDevice() + + if not os.path.isdir(instRoot + '/boot/grub/'): + os.mkdir(instRoot + '/boot/grub', 0755) + + cf = '/boot/grub/grub.conf' + self.perms = 0600 + if os.access (instRoot + cf, os.R_OK): + self.perms = os.stat(instRoot + cf)[0] & 0777 + os.rename(instRoot + cf, instRoot + cf + '.backup') + + grubTarget = bl.getDevice() + target = "mbr" + if (grubTarget.startswith('rd/') or grubTarget.startswith('ida/') or + grubTarget.startswith('cciss/') or + grubTarget.startswith('sx8/') or + grubTarget.startswith('mapper/')): + if grubTarget[-1].isdigit(): + if grubTarget[-2] == 'p' or \ + (grubTarget[-2].isdigit() and grubTarget[-3] == 'p'): + type = "partition" + elif grubTarget[-1].isdigit() and not grubTarget.startswith('md'): + target = "partition" + + f = open(instRoot + cf, "w+") + + f.write("# grub.conf generated by pomona\n") + f.write("#\n") + + bootDev = fsset.getEntryByMountPoint("/boot") + grubPath = "/grub" + cfPath = "/" + if not bootDev: + bootDev = fsset.getEntryByMountPoint("/") + grubPath = "/boot/grub" + cfPath = "/boot/" + f.write("# NOTICE: You do not have a /boot partition. " + "This means that\n") + f.write("# all kernel and initrd paths are relative " + "to /, eg.\n") + else: + f.write("# NOTICE: You have a /boot partition. This means " + "that\n") + f.write("# all kernel and initrd paths are relative " + "to /boot/, eg.\n") + + bootDevs = self.getPhysicalDevices(bootDev.device.getDevice()) + bootDev = bootDev.device.getDevice() + + f.write('# root %s\n' % self.grubbyPartitionName(bootDevs[0])) + f.write("# kernel %svmlinuz-version ro " + "root=/dev/%s\n" % (cfPath, rootDev)) + f.write("# initrd %sinitramfs-version.img\n" % (cfPath)) + f.write("#boot=/dev/%s\n" % (grubTarget)) + + # keep track of which devices are used for the device.map + usedDevs = {} + + # get the default image to boot... first kernel image here + default = 0 + + f.write('default=%s\n' % (default)) + + # get the default timeout + timeout = 5 + f.write('timeout=%d\n' %(timeout,)) + + # we only want splashimage if they're not using a serial console + if os.access("%s/boot/grub/splash.xpm.gz" %(instRoot,), os.R_OK): + f.write('splashimage=%s%sgrub/splash.xpm.gz\n' + % (self.grubbyPartitionName(bootDevs[0]), cfPath)) + f.write("hiddenmenu\n") + + for dev in self.getPhysicalDevices(grubTarget): + usedDevs[dev] = 1 + + if self.password: + f.write('password --md5 %s\n' % (self.password)) + + for (kernelName, kernelVersion, kernelTag, kernelDesc) in kernelList: + kernelFile = "%s%skernel%s" % (cfPath, sname, kernelTag,) + + initrd = "/boot/initramfs-%s%s.img" % (kernelVersion, kernelTag,) + + f.write('title %s (%s - %s)\n' % (name, kernelDesc, kernelVersion)) + f.write('\troot %s\n' % self.grubbyPartitionName(bootDevs[0])) + + realroot = getRootDevName(initrd, fsset, rootDev, instRoot) + realroot = " root=%s" %(realroot,) + + f.write('\tkernel %s ro%s' % (kernelFile, realroot)) + self.args.append("quiet") + if self.args.get(): + f.write(' %s' % self.args.get()) + f.write('\n') + + if os.access (instRoot + initrd, os.R_OK): + # initrd is built in backend.postInstall + f.write('\tinitrd %sinitramfs-%s%s.img\n' % (cfPath, kernelVersion, kernelTag,)) + + for (label, longlabel, device) in chainList: + if ((not longlabel) or (longlabel == "")): + continue + f.write('title %s\n' % (longlabel)) + f.write('\trootnoverify %s\n' % self.grubbyPartitionName(device)) +# f.write('\tmakeactive\n') + f.write('\tchainloader +1') + f.write('\n') + usedDevs[device] = 1 + + f.close() + os.chmod(instRoot + "/boot/grub/grub.conf", self.perms) + + try: + # make symlink for /etc/grub.conf (config files belong in /etc) + if os.access (instRoot + "/etc/grub.conf", os.R_OK): + os.rename(instRoot + "/etc/grub.conf", instRoot + "/etc/grub.conf.backup") + os.symlink("../boot/grub/grub.conf", instRoot + "/etc/grub.conf") + except: + pass + + for dev in self.getPhysicalDevices(rootDev) + bootDevs: + usedDevs[dev] = 1 + + if os.access(instRoot + "/boot/grub/device.map", os.R_OK): + os.rename(instRoot + "/boot/grub/device.map", instRoot + "/boot/grub/device.map.backup") + + f = open(instRoot + "/boot/grub/device.map", "w+") + f.write("# this device map was generated by pomona\n") + devs = usedDevs.keys() + usedDevs = {} + for dev in devs: + drive = getDiskPart(dev)[0] + if usedDevs.has_key(drive): + continue + usedDevs[drive] = 1 + devs = usedDevs.keys() + devs.sort() + for drive in devs: + # XXX hack city. If they're not the sort of thing that'll + # be in the device map, they shouldn't still be in the list. + if not drive.startswith('md'): + f.write("(%s) /dev/%s\n" % (self.grubbyDiskName(drive), drive)) + f.close() + + args = "--stage2=/boot/grub/stage2 " + if self.forceLBA32: + args = "%s--force-lba " % (args,) + + sysconf = '/etc/sysconfig/grub' + if os.access (instRoot + sysconf, os.R_OK): + self.perms = os.stat(instRoot + sysconf)[0] & 0777 + os.rename(instRoot + sysconf, instRoot + sysconf + '.backup') + # if it's an absolute symlink, just get it out of our way + elif (os.path.islink(instRoot + sysconf) and + os.readlink(instRoot + sysconf)[0] == '/'): + os.rename(instRoot + sysconf, instRoot + sysconf + '.backup') + f = open(instRoot + sysconf, 'w+') + f.write("boot=/dev/%s\n" %(grubTarget,)) + # XXX forcelba never gets read back... + if self.forceLBA32: + f.write("forcelba=1\n") + else: + f.write("forcelba=0\n") + f.close() + + cmds = [] + for bootDev in bootDevs: + gtPart = self.getMatchingPart(bootDev, grubTarget) + gtDisk = self.grubbyPartitionName(getDiskPart(gtPart)[0]) + bPart = self.grubbyPartitionName(bootDev) + cmd = "root %s\n" % (bPart,) + + stage1Target = gtDisk + if target == "partition": + stage1Target = self.grubbyPartitionName(gtPart) + + cmd += "install %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ + (args, grubPath, stage1Target, grubPath, bPart, grubPath) + cmds.append(cmd) + + log.info("GRUB commands:") + for cmd in cmds: + log.info("\t%s\n", cmd) + + if cfPath == "/": + syncDataToDisk(bootDev, "/boot", instRoot) + else: + syncDataToDisk(bootDev, "/", instRoot) + + # copy the stage files over into /boot + pyfire.executil.execWithRedirect("/usr/sbin/grub-install", + ["/usr/sbin/grub-install", "--just-copy"], + stdout = "/dev/tty5", stderr = "/dev/tty5", + root = instRoot) + + # really install the bootloader + for cmd in cmds: + p = os.pipe() + os.write(p[1], cmd + '\n') + os.close(p[1]) + import time + + # FIXME: hack to try to make sure everything is written + # to the disk + if cfPath == "/": + syncDataToDisk(bootDev, "/boot", instRoot) + else: + syncDataToDisk(bootDev, "/", instRoot) + + pyfire.executil.execWithRedirect("/usr/sbin/grub" , + [ "grub", "--batch", "--no-floppy", + "--device-map=/boot/grub/device.map" ], + stdin = p[0], + stdout = "/dev/tty5", stderr = "/dev/tty5", + root = instRoot) + os.close(p[0]) + + return "" + + def getMatchingPart(self, bootDev, target): + bootName, bootPartNum = getDiskPart(bootDev) + devices = self.getPhysicalDevices(target) + for device in devices: + name, partNum = getDiskPart(device) + if name == bootName: + return device + return devices[0] + + def grubbyDiskName(self, name): + return "hd%d" % self.drivelist.index(name) + + def grubbyPartitionName(self, dev): + (name, partNum) = getDiskPart(dev) + if partNum != None: + return "(%s,%d)" % (self.grubbyDiskName(name), partNum) + else: + return "(%s)" %(self.grubbyDiskName(name)) + + def write(self, instRoot, fsset, bl, kernelList, chainList, defaultDev, intf): + out = self.writeGrub(instRoot, fsset, bl, kernelList, chainList, defaultDev) + + def getArgList(self): + args = [] + + if self.forceLBA32: + args.append("--lba32") + if self.password: + args.append("--md5pass=%s" %(self.password)) + + # XXX add location of bootloader here too + + return args + + def __init__(self): + bootloaderInfo.__init__(self) + self.useGrubVal = 1 + self.kernelLocation = "/boot/" + self.configfile = "/etc/lilo.conf" + self.password = None + self.pure = None + +############### +# end of boot loader objects... these are just some utility functions used + +# return (disk, partition number) eg ('hda', 1) +def getDiskPart(dev): + cut = len(dev) + if (dev.startswith('rd/') or dev.startswith('ida/') or + dev.startswith('cciss/') or dev.startswith('sx8/') or + dev.startswith('mapper/')): + if dev[-2] == 'p': + cut = -1 + elif dev[-3] == 'p': + cut = -2 + else: + if dev[-2] in string.digits: + cut = -2 + elif dev[-1] in string.digits: + cut = -1 + + name = dev[:cut] + + # hack off the trailing 'p' from /dev/cciss/*, for example + if name[-1] == 'p': + for letter in name: + if letter not in string.letters and letter != "/": + name = name[:-1] + break + + if cut < 0: + partNum = int(dev[cut:]) - 1 + else: + partNum = None + + return (name, partNum) + +# hackery to determine if we should do root=LABEL=/ or whatnot +# as usual, knows too much about pomona +def getRootDevName(initrd, fsset, rootDev, instRoot): + if not os.access(instRoot + initrd, os.R_OK): + return "/dev/%s" % (rootDev,) + try: + rootEntry = fsset.getEntryByMountPoint("/") + if rootEntry.getUuid() is not None: + return "UUID=%s" %(rootEntry.getUuid(),) + elif rootEntry.getLabel() is not None and rootEntry.device.doLabel is not None: + return "LABEL=%s" %(rootEntry.getLabel(),) + return "/dev/%s" %(rootDev,) + except: + return "/dev/%s" %(rootDev,) + +# returns a product name to use for the boot loader string +def getProductName(): + # XXX Check /etc/ipfire-release here... + return "IPFire Linux" + +def bootloaderSetupChoices(pomona): + if pomona.dir == DISPATCH_BACK: + return + pomona.id.bootloader.updateDriveList() + + choices = pomona.id.fsset.bootloaderChoices(pomona.id.diskset, pomona.id.bootloader) + + pomona.id.bootloader.images.setup(pomona.id.diskset, pomona.id.fsset) + + if pomona.id.bootloader.defaultDevice != None and choices: + keys = choices.keys() + # there are only two possible things that can be in the keys + # mbr and boot. boot is ALWAYS present. so if the dev isn't + # listed, it was mbr and we should nicely fall back to boot + if pomona.id.bootloader.defaultDevice not in keys: + log.warning("MBR not suitable as boot device; installing to partition") + pomona.id.bootloader.defaultDevice = "boot" + pomona.id.bootloader.setDevice(choices[pomona.id.bootloader.defaultDevice][0]) + elif choices and choices.has_key("mbr"): + pomona.id.bootloader.setDevice(choices["mbr"][0]) + elif choices and choices.has_key("boot"): + pomona.id.bootloader.setDevice(choices["boot"][0]) + + bootDev = pomona.id.fsset.getEntryByMountPoint("/") + if not bootDev: + bootDev = pomona.id.fsset.getEntryByMountPoint("/boot") + part = partedUtils.get_partition_by_name(pomona.id.diskset.disks, + bootDev.device.getDevice()) + if part and partedUtils.end_sector_to_cyl(part.geom.dev, part.geom.end) >= 1024: + pomona.id.bootloader.above1024 = 1 + +def writeBootloader(pomona): + def dosync(): + isys.sync() + isys.sync() + isys.sync() + + if pomona.id.bootloader.defaultDevice == -1: + log.error("No default boot device set") + return + + w = pomona.intf.waitWindow(_("Bootloader"), _("Installing bootloader...")) + + kernelList = [] + otherList = [] + root = pomona.id.fsset.getEntryByMountPoint('/') + if root: + rootDev = root.device.getDevice() + else: + rootDev = None + defaultDev = pomona.id.bootloader.images.getDefault() + + kernelLabel = None + kernelLongLabel = None + + for (dev, (label, longlabel, type)) in pomona.id.bootloader.images.getImages().items(): + if (dev == rootDev) or (rootDev is None and kernelLabel is None): + kernelLabel = label + kernelLongLabel = longlabel + elif dev == defaultDev: + otherList = [(label, longlabel, dev)] + otherList + else: + otherList.append((label, longlabel, dev)) + + if kernelLabel is None: + log.error("unable to find default image, bailing") + + defkern = None + for (kernelName, kernelVersion, kernelTag, kernelDesc) in pomona.backend.kernelVersionList(pomona): + if not defkern: + defkern = "%s%s" % (kernelName, kernelTag) + + if kernelTag == "-smp" and isys.smpAvailable(): + defkern = "%s%s" % (kernelName, kernelTag) + + kernelList.append((kernelName, kernelVersion, kernelTag, kernelDesc)) + + f = open(pomona.rootPath + "/etc/sysconfig/kernel", "w+") + f.write("# DEFAULTKERNEL specifies the default kernel package type\n") + f.write("DEFAULTKERNEL=%s\n" %(defkern,)) + f.close() + + dosync() + try: + pomona.id.bootloader.write(pomona.rootPath, pomona.id.fsset, pomona.id.bootloader, + kernelList, otherList, defaultDev, pomona.intf) + w.pop() + except BootyNoKernelWarning: + w.pop() + if pomona.intf: + pomona.intf.messageWindow(_("Warning"), + _("No kernel packages were installed on your " + "system. Your boot loader configuration " + "will not be changed.")) + dosync() + +# return instance of the appropriate bootloader for our arch +def getBootloader(): + return x86BootloaderInfo() diff --git a/pkgs/core/pomona/src/console.py b/pkgs/core/pomona/src/console.py new file mode 100644 index 0000000..ed0bc59 --- /dev/null +++ b/pkgs/core/pomona/src/console.py @@ -0,0 +1,173 @@ +#!/usr/bin/python + +import os +import string +import locale +import gettext + +import pyfire.executil as executil +from pyfire.config import ConfigFile +import keyboard_models + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) +N_ = lambda x: x + +# Converts a single language into a "language search path". For example, +# de_DE.utf8@euro would become "de_DE.utf8@eueo de_DE.utf8 de_DE de" +def expandLangs(astring): + langs = [astring] + charset = None + # remove charset ... + if '.' in astring: + langs.append(string.split(astring, '.')[0]) + + if '@' in astring: + charset = string.split(astring, '@')[1] + + # also add 2 character language code ... + if len(astring) > 2: + if charset: + langs.append("%s@%s" %(astring[:2], charset)) + + langs.append(astring[:2]) + + return langs + +class Console(ConfigFile): + def __init__(self, filename): + ConfigFile.__init__(self, filename) + + # default to us and unicode enabled + self.info["KEYMAP"] = "us" + self.info["UNICODE"] = "yes" + + self._mods = keyboard_models.KeyboardModels() + + self.nativeLangNames = {} + self.locales = {} + + if os.environ.has_key("LANG"): + self.lang = self.fixLang(os.environ["LANG"]) + else: + self.lang = "en_US.UTF-8" + + # nick -> (name, short name, font, keyboard, timezone) mapping + search = ( '../lang-table', 'lang-table', '/usr/lib/pomona/lang-table', '/etc/lang-table') + for path in search: + if os.access(path, os.R_OK): + f = open(path, "r") + break + + for line in f.readlines(): + string.strip(line) + l = string.split(line, '\t') + + # throw out invalid lines + if len(l) < 6: + continue + + self.locales[l[3]] = (l[0], l[1], l[2], l[4], string.strip(l[5])) + self.nativeLangNames[l[0]] = _(l[0]) + + f.close() + + def availableLangs(self): + return self.nativeLangNames.keys() + + def setKeymap(self, keymap): + self.info["KEYMAP"] = keymap + + def getKeymap(self): + return self.info["KEYMAP"] + + def getDefaultKeymap(self): + return self.locales[self.canonLangNick(self.lang)][3] + + def getDefaultFont(self, nick): + return self.locales[self.canonLangNick(nick)][2] + + def getDefaultTimeZone(self): + return self.locales[self.canonLangNick(self.lang)][4] + + def _getKeyboardModels(self): + return self._mods.get_models() + + modelDict = property(_getKeyboardModels) + + def getKeymapName(self): + kbd = self.modelDict[self.getKeymap()] + if not kbd: + return "" + (name, layout, model, variant, options) = kbd + return name + + # Convert what might be a shortened form of a language's nick (en or + # en_US, for example) into the full version (en_US.UTF-8). If we + # don't find it, return our default of en_US.UTF-8. + def canonLangNick(self, nick): + for key in self.locales.keys(): + if nick in expandLangs(key): + return key + return "en_US.UTF-8" + + def getNickByName(self, name): + for k in self.locales.keys(): + row = self.locales[k] + if row[0] == name: + return k + + def fixLang(self, langToFix): + ret = None + for lang in self.locales.keys(): + if lang == langToFix: + (a, b, font, c, d) = self.locales[lang] + if font == "none": + ret = "en_US.UTF-8" + self.targetLang = lang + + if ret is None: + ret = langToFix + + return ret + + def getNativeLangName(self, lang): + return self.nativeLangNames[lang] + + def getLangNameByNick(self, nick): + return self.locales[self.canonLangNick(nick)][0] + + def getCurrentLangSearchList(self): + return expandLangs(self.lang) + ['C'] + + def setLanguage(self, nick): + self.info['LANG'] = os.environ["LANG"] = \ + self.lang = self.fixLang(self.canonLangNick(nick)) + os.environ["LC_NUMERIC"] = 'C' + + if self.locales[self.lang][2] == "none": + self.info['FONT'] = None + else: + self.info['FONT'] = self.locales[self.lang][2] + + try: + locale.setlocale(locale.LC_ALL, "") + except locale.Error: + pass + + def activate(self): + console_kbd = self.getKeymap() + if not console_kbd: + return + + # Call loadkeys to change the console keymap + if os.access("/bin/loadkeys", os.X_OK): + command = "/bin/loadkeys" + elif os.access("/usr/bin/loadkeys", os.X_OK): + command = "/usr/bin/loadkeys" + else: + command = "/bin/loadkeys" + argv = [ command, console_kbd ] + + if os.access(argv[0], os.X_OK) == 1: + executil.execWithRedirect(argv[0], argv, stdout="/dev/tty5", stderr="/dev/tty5") diff --git a/pkgs/core/pomona/src/constants.py b/pkgs/core/pomona/src/constants.py new file mode 100644 index 0000000..c8ac4f9 --- /dev/null +++ b/pkgs/core/pomona/src/constants.py @@ -0,0 +1,113 @@ +#!/usr/bin/python + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) +N_ = lambda x: x + +version = "VERSION" +name = "NAME v%s" % version +sname = "SNAME" +iname = "PNAME" +bugurl = "http://bugtracker.ipfire.org/" +wikiurl = "http://wiki.ipfire.org/" +kernelVersion = "KVER" + +HARDDISK_PATH = "/mnt/target" +SOURCE_PATH = "/mnt/source" +INFO_FILE = ".%sinfo" % (sname,) +IMAGE_FILE = "%s-%s.sfs" % (sname, version) +IMAGE_FILE_LS = "%s-%s.ls" % (sname, version) + +REQUIRED_FILES = (IMAGE_FILE,) + +DISPATCH_BACK = -1 +DISPATCH_FORWARD = 1 +DISPATCH_NOOP = None + +CLEARPART_TYPE_ALL = 0 +CLEARPART_TYPE_NONE = -1 + +CB_UNDEF = -1 +CB_START = 0 +CB_STOP = 1 +CB_WAIT = 2 +CB_PROGRESS = 3 + +INSTALL_OK = 0 +INSTALL_BACK = -1 +INSTALL_NOOP = -2 + +# different types of partition requests +# REQUEST_PREEXIST is a placeholder for a pre-existing partition on the system +# REQUEST_NEW is a request for a partition which will be automatically +# created based on various constraints on size, drive, etc +# REQUEST_RAID is a request for a raid device +# REQUEST_PROTECTED is a preexisting partition which can't change +# (harddrive install, harddrive with the isos on it) +# +REQUEST_PREEXIST = 1 +REQUEST_NEW = 2 +REQUEST_RAID = 4 +REQUEST_PROTECTED = 8 +REQUEST_VG = 16 # volume group +REQUEST_LV = 32 # logical volume + +# XXX this is made up and used by the size spinner; should just be set with +# a callback +MAX_PART_SIZE = 1024*1024*1024 + +lvmErrorOutput = "/tmp/lvmout" + +exceptionText = _("An unhandled exception has occurred. This " + "is most likely a bug. Please save a copy of " + "the detailed exception and file a bug report") +if not bugurl: + # this string will be combined with "An unhandled exception"... + # the leading space is not a typo. + exceptionText += _(" with the provider of this software.") +else: + # this string will be combined with "An unhandled exception"... + # the leading space is not a typo. + exceptionText += _(" against pomona at %s") %(bugurl,) + +class Translator: + """A simple class to facilitate on-the-fly translation for newt buttons""" + def __init__(self, button, check): + self.button = button + self.check = check + + def __getitem__(self, which): + if which == 0: + return _(self.button) + elif which == 1: + return self.check + raise IndexError + + def __len__(self): + return 2 + +TEXT_OK_STR = N_("OK") +TEXT_OK_CHECK = "ok" +TEXT_OK_BUTTON = Translator(TEXT_OK_STR, TEXT_OK_CHECK) + +TEXT_CANCEL_STR = N_("Cancel") +TEXT_CANCEL_CHECK = "cancel" +TEXT_CANCEL_BUTTON = Translator(TEXT_CANCEL_STR, TEXT_CANCEL_CHECK) + +TEXT_BACK_STR = N_("Back") +TEXT_BACK_CHECK = "back" +TEXT_BACK_BUTTON = Translator(TEXT_BACK_STR, TEXT_BACK_CHECK) + +TEXT_YES_STR = N_("Yes") +TEXT_YES_CHECK = "yes" +TEXT_YES_BUTTON = Translator(TEXT_YES_STR, TEXT_YES_CHECK) + +TEXT_NO_STR = N_("No") +TEXT_NO_CHECK = "no" +TEXT_NO_BUTTON = Translator(TEXT_NO_STR, TEXT_NO_CHECK) + +TEXT_EDIT_STR = N_("Edit") +TEXT_EDIT_CHECK = "edit" +TEXT_EDIT_BUTTON = Translator(TEXT_EDIT_STR, TEXT_EDIT_CHECK) + +TEXT_F12_CHECK = "F12" diff --git a/pkgs/core/pomona/src/cryptodev.py b/pkgs/core/pomona/src/cryptodev.py new file mode 100644 index 0000000..0efe94a --- /dev/null +++ b/pkgs/core/pomona/src/cryptodev.py @@ -0,0 +1,252 @@ +# +# cryptodev.py +# +# Copyright (C) 2007 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Dave Lehman <dlehman@redhat.com> +# + +import os +import iutil + +import logging +log = logging.getLogger("pomona") + +def isLuks(device): + if not device.startswith("/"): + device = "/dev/" + device + rc = iutil.execWithRedirect("cryptsetup", + ["isLuks", device], + stdout = "/dev/null", + stderr = "/dev/null", + searchPath = 1) + if rc: + return False + else: + return True + +def luksUUID(device): + if not device.startswith("/"): + device = "/dev/" + device + + if not isLuks(device): + return None + + uuid = iutil.execWithCapture("cryptsetup", ["luksUUID", device]) + uuid = uuid.strip() + return uuid + +class LUKSDevice: + """LUKSDevice represents an encrypted block device using LUKS/dm-crypt. + It requires an underlying block device and a passphrase to become + functional.""" + def __init__(self, device=None, passphrase=None, format=0): + self._device = None + self.passphrase = "" + self.name = "" + self.uuid = None + self.nameLocked = False + self.format = format + self.preexist = not format + self.packages = ["cryptsetup-luks"] + self.scheme = "LUKS" + + self.setDevice(device) + self.setPassphrase(passphrase) + if self.getUUID(): + name = "%s-%s" % (self.scheme.lower(), self.uuid) + self.setName(name, lock=True) + + def getScheme(self): + """Returns the name of the encryption scheme used by the device.""" + return self.scheme + + def setDevice(self, device): + if self._device == device: + return + + self._device = device + if device is not None: + # this will be temporary, but may be useful for debugging + name = "%s-%s" % (self.scheme.lower(), + os.path.basename(device)) + self.setName(name) + + def getDevice(self, encrypted=0): + if encrypted: + dev = self._device + else: + dev = "mapper/%s" % (self.name,) + + return dev + + def getUUID(self): + if self.format: + # self.format means we're going to reformat but haven't yet + # so we shouldn't act like there's anything worth seeing there + return + + if not self.uuid: + self.uuid = luksUUID(self.getDevice(encrypted=1)) + + return self.uuid + + def setName(self, name, lock=False): + """Set the name of the mapped device, eg: 'dmcrypt-sda3'""" + if self.name == name: + return + + if self.name and not self.getStatus(): + raise RuntimeError, "Cannot rename an active mapping." + + if self.nameLocked: + log.debug("Failed to change locked mapping name: %s" % + (self.name,)) + return + + self.name = name + if lock and name: + # don't allow anyone to lock the name as "" or None + self.nameLocked = True + + def setPassphrase(self, passphrase): + """Set the (plaintext) passphrase used to access the device.""" + self.passphrase = passphrase + + def crypttab(self): + """Return a crypttab formatted line describing this mapping.""" + format = "%-23s %-15s %s\n" + line = format % (self.name, + "UUID=%s" % (self.getUUID(),), + "none") + return line + + def getStatus(self): + """0 means active, 1 means inactive (or non-existent)""" + if not self.name: + return 1 + + rc = iutil.execWithRedirect("cryptsetup", + ["status", self.name], + stdout = "/dev/null", + stderr = "/dev/null", + searchPath = 1) + return rc + + def formatDevice(self): + """Write a LUKS header onto the device.""" + if not self.format: + return + + if not self.getStatus(): + log.debug("refusing to format active mapping %s" % (self.name,)) + return 1 + + if not self.passphrase: + raise RuntimeError, "Cannot create mapping without a passphrase." + + device = self.getDevice(encrypted=1) + if not device: + raise ValueError, "Cannot open mapping without a device." + + log.info("formatting %s as %s" % (device, self.getScheme())) + p = os.pipe() + os.write(p[1], "%s\n" % (self.passphrase,)) + os.close(p[1]) + + rc = iutil.execWithRedirect("cryptsetup", + ["-q", "luksFormat", + "/dev/%s" % (device,)], + stdin = p[0], + stdout = "/dev/null", + stderr = "/dev/tty5", + searchPath = 1) + self.format = 0 + return rc + + def openDevice(self): + if not self.getStatus(): + # already mapped + return 0 + + if not self.passphrase: + raise RuntimeError, "Cannot create mapping without a passphrase." + + device = self.getDevice(encrypted=1) + if not device: + raise ValueError, "Cannot open mapping without a device." + + uuid = self.getUUID() + if not uuid: + raise RuntimeError, "Device has no UUID." + + self.setName("%s-%s" % (self.scheme.lower(), uuid), lock=True) + + log.info("mapping %s device %s to %s" % (self.getScheme(), + device, + self.name)) + + p = os.pipe() + os.write(p[1], "%s\n" % (self.passphrase,)) + os.close(p[1]) + + rc = iutil.execWithRedirect("cryptsetup", + ["luksOpen", + "/dev/%s" % (device,), + self.name], + stdin = p[0], + stdout = "/dev/null", + stderr = "/dev/tty5", + searchPath = 1) + return rc + + def closeDevice(self): + if self.getStatus(): + # not mapped + return 0 + + log.info("unmapping %s device %s" % (self.getScheme(), self.name)) + rc = iutil.execWithRedirect("cryptsetup", + ["luksClose", self.name], + stdout = "/dev/null", + stderr = "/dev/tty5", + searchPath = 1) + return rc + + def addPassphrase(self, newpass): + if not newpass: + return 1 + + if newpass == self.passphrase: + return 0 + + p = os.pipe() + os.write(p[1], "%s\n%s" % (self.passphrase, newpass)) + os.close(p[1]) + + device = self.getDevice(encrypted=1) + log.info("adding new passphrase to %s device %s" % (self.getScheme(), + device)) + rc = iutil.execWithRedirect("cryptsetup", + ["-q", + "luksAddKey", + "/dev/%s" % (device,)], + stdin = p[0], + stdout = "/dev/null", + stderr = "/dev/tty5", + searchPath = 1) + + return rc diff --git a/pkgs/core/pomona/src/dispatch.py b/pkgs/core/pomona/src/dispatch.py new file mode 100644 index 0000000..c231719 --- /dev/null +++ b/pkgs/core/pomona/src/dispatch.py @@ -0,0 +1,206 @@ +# +# dispatch.py: install/upgrade master flow control +# +# Erik Troan <ewt@redhat.com> +# +# Copyright 2001-2006 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# general public license. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import string +from types import * +from constants import * +from autopart import doAutoPartition +from bootloader import writeBootloader, bootloaderSetupChoices +from packages import turnOnFilesystems, betaNagScreen, setupTimezone +from partitioning import partitionObjectsInitialize, partitioningComplete + +from packages import doMigrateFilesystems +from packages import doPostAction +from packages import copyPomonaLogs + +from flags import flags + +#from backend import doPostSelection, doRepoSetup +from backend import doPreInstall, doPostInstall, doInstall +from backend import writeConfiguration + +import logging +log = logging.getLogger("pomona") + +# +# items are one of +# +# ( name ) +# ( name, Function ) +# +# in the second case, the function is called directly from the dispatcher + +# All install steps take the pomona object as their sole argument. This +# gets passed in when we call the function. +installSteps = [ + ("welcome", ), + ("betanag", betaNagScreen, ), + ("language", ), + ("keyboard", ), + ("partitionobjinit", partitionObjectsInitialize, ), + ("parttype", ), + ("autopartitionexecute", doAutoPartition, ), + ("partition", ), + ("partitiondone", partitioningComplete, ), + ("bootloadersetup", bootloaderSetupChoices, ), + ("bootloader", ), + ("bootloaderadvanced", ), + ("network", ), + ("timezone", ), + ("accounts", ), + #("reposetup", doRepoSetup, ), + #("tasksel", ), + #("group-selection", ), + #("postselection", doPostSelection, ), + ("confirminstall", ), + ("install", ), + ("migratefilesystems", doMigrateFilesystems, ), + ("enablefilesystems", turnOnFilesystems, ), + ("setuptime", setupTimezone, ), + ("preinstallconfig", doPreInstall, ), + ("installpackages", doInstall, ), + ("postinstallconfig", doPostInstall, ), + ("writeconfig", writeConfiguration, ), + ("instbootloader", writeBootloader, ), + ("copylogs", copyPomonaLogs, ), + #("postscripts", runPostScripts, ), + ("dopostaction", doPostAction, ), + ("complete", ), + ] + +class Dispatcher: + def gotoPrev(self): + self._setDir(DISPATCH_BACK) + self.moveStep() + + def gotoNext(self): + self._setDir(DISPATCH_FORWARD) + self.moveStep() + + def canGoBack(self): + # begin with the step before this one. If all steps are skipped, + # we can not go backwards from this screen + i = self.step - 1 + while i >= self.firstStep: + if not self.stepIsDirect(i) and not self.skipSteps.has_key(installSteps[i][0]): + return True + i = i - 1 + return False + + def setStepList(self, *steps): + # only remove non-permanently skipped steps from our skip list + for step, state in self.skipSteps.items(): + if state == 1: + del self.skipSteps[step] + + stepExists = {} + for step in installSteps: + name = step[0] + if not name in steps: + self.skipSteps[name] = 1 + + stepExists[name] = 1 + + for name in steps: + if not stepExists.has_key(name): + log.warning("step %s does not exist", name) + + def stepInSkipList(self, step): + if type(step) == type(1): + step = installSteps[step][0] + return self.skipSteps.has_key(step) + + def skipStep(self, stepToSkip, skip = 1, permanent = 0): + for step in installSteps: + name = step[0] + if name == stepToSkip: + if skip: + if permanent: + self.skipSteps[name] = 2 + elif not self.skipSteps.has_key(name): + self.skipSteps[name] = 1 + elif self.skipSteps.has_key(name): + # if marked as permanent then dont change + if self.skipSteps[name] != 2: + del self.skipSteps[name] + return + log.warning("step %s does not exist", stepToSkip) + + def stepIsDirect(self, step): + """Takes a step number""" + if len(installSteps[step]) == 2: + return True + else: + return False + + def moveStep(self): + if self.step == None: + self.step = self.firstStep + else: + self.step = self.step + self._getDir() + + if self.step >= len(installSteps): + return None + + while self.step >= self.firstStep and self.step < len(installSteps) \ + and (self.stepInSkipList(self.step) or self.stepIsDirect(self.step)): + if self.stepIsDirect(self.step) and not self.stepInSkipList(self.step): + (stepName, stepFunc) = installSteps[self.step] + log.info("moving (%d) to step %s" % (self._getDir(), stepName)) + rc = stepFunc(self.pomona) + if rc in [DISPATCH_BACK, DISPATCH_FORWARD]: + self._setDir(rc) + # if anything else, leave self.dir alone + + self.step = self.step + self._getDir() + if self.step == len(installSteps): + return None + + if (self.step < 0): + # pick the first step not in the skip list + self.step = 0 + while self.skipSteps.has_key(installSteps[self.step][0]): + self.step = self.step + 1 + elif self.step >= len(installSteps): + self.step = len(installSteps) - 1 + while self.skipSteps.has_key(installSteps[self.step][0]): + self.step = self.step - 1 + log.info("moving (%d) to step %s" % (self._getDir(), installSteps[self.step][0])) + + def currentStep(self): + if self.step == None: + self.gotoNext() + elif self.step >= len(installSteps): + return (None, None) + + stepInfo = installSteps[self.step] + step = stepInfo[0] + + return (step, self.pomona) + + def __init__(self, pomona): + self.pomona = pomona + self.pomona.dir = DISPATCH_FORWARD + self.step = None + self.skipSteps = {} + self.firstStep = 0 + + def _getDir(self): + return self.pomona.dir + + def _setDir(self, dir): + self.pomona.dir = dir + + dir = property(_getDir,_setDir) diff --git a/pkgs/core/pomona/src/dmraid.py b/pkgs/core/pomona/src/dmraid.py new file mode 100644 index 0000000..5cee469 --- /dev/null +++ b/pkgs/core/pomona/src/dmraid.py @@ -0,0 +1,302 @@ +# +# dmraid.py - dmraid probing control +# +# Copyright (C) 2005 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Peter Jones <pjones@redhat.com> +# + +"""DMRaid probing control.""" +# XXX dmraid and md raid should be abstracted from the same thing. -pj +# XXX dmraid and lvm should use a common control mechanism (such as block.dm) +# for device-mapper. -pj + +import sys +import string +import block +import partedUtils +import raid +from flags import flags + +import logging +from pomona_log import logger, logFile + +logger.addLogger ("pomona.dmraid", minLevel=logging.DEBUG) +log = logging.getLogger("pomona.dmraid") +logger.addFileHandler (logFile, log) + +import isys + +# these arches can have their /boot on DMRAID and not have their +# boot loader blow up +# XXX This needs to be functional so it can test if drives sit on particular +# controlers. -pj +dmraidBootArches = [ "i386", "x86_64" ] + +dmNameUpdates = {} + +class DmDriveCache: + def __init__(self): + self.cache = {} + + def _addMapDevs(self, name, devs, obj): + isys.cachedDrives["mapper/" + name] = obj + log.debug("adding %s to isys cache" % ("mapper/" + name,)) + for dev in devs: + disk = dev.split('/')[-1] + if isys.cachedDrives.has_key(disk): + self.cache.setdefault(obj.name, {}) + self.cache[obj.name][obj.name] = obj + log.debug("adding %s to dm cache" % (disk,)) + self.cache[obj.name][disk] = isys.cachedDrives[disk] + log.debug("removing %s from isys cache" % (disk,)) + del isys.cachedDrives[disk] + + def add(self, obj): + if isinstance(obj, block.MultiPath): + return self._addMapDevs(obj.name, obj.bdevs, obj) + else: + members = [] + for m in obj.members: + if isinstance(m, block.RaidDev): + members.append(m.rd.device.path) + return self._addMapDevs(obj.name, members, obj) + + def remove(self, name): + objname = "mapper/" + name + if isys.cachedDrives.has_key(objname): + obj = isys.cachedDrives[objname] + log.debug("removing %s from isys cache" % (objname,)) + del isys.cachedDrives[objname] + if self.cache.has_key(obj.name): + del self.cache[obj.name][obj.name] + for k,v in self.cache[obj.name].items(): + log.debug("adding %s to isys cache" % (name,)) + isys.cachedDrives[k] = v + log.debug("removing %s from dm cache" % (obj,)) + del self.cache[obj.name] + + def rename(self, obj, newname): + oldname = 'mapper/' + obj.name + if isys.cachedDrives.has_key(oldname): + dmNameUpdates[obj.name] = newname + self.remove(oldname) + # XXX why doesn't setting the property work? + obj.set_name(newname) + self.add(obj) + + def __contains__(self, name): + return self.cache.has_key(name) + +cacheDrives = DmDriveCache() + +class DegradedRaidWarning(Warning): + def __init__(self, *args): + self.args = args + def __str__(self): + return self.args and ('%s' % self.args[0]) or repr(self) + +def scanForRaid(drives, degradedOk=False): + """Scans for dmraid devices on drives. + + drives is a list of device names. + Returns a list of (raidSet, parentRaidSet, devices, level, totalDisks) + tuples. + """ + + log.debug("scanning for dmraid on drives %s" % (drives,)) + + probeDrives = [] + for d in drives: + probeDrives.append("/dev/%s" % (d,)) + + dmsets = [] + def nonDegraded(rs): + log.debug("got raidset %s (%s)" % (rs, string.join(rs.member_devpaths))) + log.debug(" valid: %s found_devs: %s total_devs: %s" % (rs.valid, rs.rs.found_devs, rs.rs.total_devs)) + + if not rs.valid and not degradedOk: + log.warning("raid %s (%s) is degraded" % (rs, rs.name)) + #raise DegradedRaidWarning, rs + return False + return True + + raidsets = filter(nonDegraded, block.getRaidSets(probeDrives) or []) + def updateName(rs): + if dmNameUpdates.has_key(rs.name): + rs.set_name(dmNameUpdates[rs.name]) + cacheDrives.add(rs) + return rs + + return reduce(lambda x,y: x + [updateName(y),], raidsets, []) + +def renameRaidSet(rs, name): + cacheDrives.rename(rs, name) + +def startAllRaid(driveList): + """Do a raid start on raid devices.""" + + if not flags.dmraid: + return [] + log.debug("starting all dmraids on drives %s" % (driveList,)) + + try: + dmList = scanForRaid(driveList) + except Exception, e: + log.error("error scanning dmraid, disabling: %s" %(e,)) + flags.dmraid = 0 + dmList = [] + + newDmList = [] + for rs in dmList: + rs.prefix = '/dev/mapper/' + log.debug("starting raid %s with mknod=True" % (rs,)) + try: + rs.activate(mknod=True) + newDmList.append(rs) + except Exception, e: + log.error("Activating raid %s failed: " % (rs.rs,)) + log.error(" table: %s" % (rs.rs.table,)) + log.error(" exception: %s" % (e,)) + try: + rs.deactivate() + del rs + except: + pass + + return newDmList + +def stopAllRaid(dmList): + """Do a raid stop on each of the raid device tuples given.""" + + if not flags.dmraid: + return + log.debug("stopping all dmraids") + for rs in dmList: + log.debug("stopping raid %s" % (rs,)) + if rs.name in cacheDrives: + cacheDrives.remove(rs.name) + + rs.deactivate() + #block.removeDeviceMap(map) + +def isRaid6(raidlevel): + """Return whether raidlevel is a valid descriptor of RAID6.""" + return False + +def isRaid5(raidlevel): + """Return whether raidlevel is a valid descriptor of RAID5.""" + return False + +def isRaid1(raidlevel): + """Return whether raidlevel is a valid descriptor of RAID1.""" + return raid.isRaid1(raidlevel) + +def isRaid0(raidlevel): + """Return whether raidlevel is a valid descriptor of RAID1.""" + return raid.isRaid0(raidlevel) + +def get_raid_min_members(raidlevel): + """Return the minimum number of raid members required for raid level""" + return raid.get_raid_min_members(raidlevel) + +def get_raid_max_spares(raidlevel, nummembers): + """Return the maximum number of raid spares for raidlevel.""" + return raid.get_raid_max_spares(raidlevel, nummembers) + +def register_raid_device(dmname, newdevices, newlevel, newnumActive): + """Register a new RAID device in the dmlist.""" + raise NotImplementedError + +def lookup_raid_device(dmname): + """Return the requested RAID device information.""" + for rs, parent, devices, level, nrDisks, totalDisks in \ + partedUtils.DiskSet.dmList: + if dmname == rs.name: + return (rs.name, devices, level, totalDisks) + raise KeyError, "dm device not found" + +def scanForMPath(drives): + log.debug("scanning for multipath on drives %s" % (drives,)) + mpaths = [] + + probeDrives = [] + for d in drives: + probeDrives.append("/dev/%s" % (d,)) + + import block as _block + + log.debug("loading bdevid modules from: '%s'" % (_block.getBdevidPath(),)) + + _block.load("scsi") + mpaths = _block.getMPaths(probeDrives) + log.debug("mpaths: %s" % (mpaths,)) + + def updateName(mp): + if dmNameUpdates.has_key(mp.name): + mp.set_name(dmNameUpdates[mp.name]) + cacheDrives.add(mp) + return mp + + return reduce(lambda x,y: x + [updateName(y),], mpaths, []) + +def renameMPath(mpath, name): + cacheDrives.rename(mpath, name) + +def startMPath(mpath): + if flags.mpath == 0: + return + mpath.prefix = '/dev/mapper/' + log.debug("starting mpath %s with mknod=True" % (mpath,)) + mpath.activate(mknod=True) + +def startAllMPath(driveList): + """Start all of the MPaths of the specified drives.""" + + if not flags.mpath: + return [] + log.debug("starting all mpaths on drives %s" % (driveList,)) + + try: + mpList = scanForMPath(driveList) + except Exception, e: + log.error("error scanning mpaths, disabling: %s" %(e,)) + flags.mpath = 0 + mpList = [] + + for mp in mpList: + startMPath(mp) + return mpList + +def stopMPath(mp): + if flags.mpath == 0: + return + + log.debug("stopping mpath %s" % (mp,)) + if mp.name in cacheDrives: + cacheDrives.remove(mp.name) + + mp.deactivate() + #block.removeDeviceMap(map) + +def stopAllMPath(mpList): + """Do a mpath stop on each of the mpath device tuples given.""" + + if not flags.mpath: + return + log.debug("stopping all mpaths") + for mp in mpList: + stopMPath(mp) diff --git a/pkgs/core/pomona/src/errors.py b/pkgs/core/pomona/src/errors.py new file mode 100644 index 0000000..6708b1d --- /dev/null +++ b/pkgs/core/pomona/src/errors.py @@ -0,0 +1,159 @@ +# +# errors.py: exception classes used throughout pomona +# +# Copyright (C) 2002, 2007, 2008 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Peter Jones <pjones@redhat.com> +# Chris Lumens <clumens@redhat.com> +# Matt Wilson <msw@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# Mike Fulbright <msf@redhat.com> +# + +import string +import os +from constants import lvmErrorOutput + +"""Exceptions for use in lvm operations.""" + +class LvmError(Exception): + """An error occurred with lvm.""" + def __init__(self, command, name=None): + self.command = command + self.name = name + self.log = self.getLvmOutput() + + def getLvmOutput(self): + if not os.access(lvmErrorOutput, os.R_OK): + return "" + f = open(lvmErrorOutput, "r") + lines = reduce(lambda x,y: x + [string.strip(y),], f.readlines(), []) + lines = string.join(reduce(lambda x,y: x + [" %s" % (y,)], \ + lines, []), "\n") + return lines + + def __str__(self): + s = "" + if not self.name is None: + s = " for device %s" % (self.name,) + return "%s failed%s\nLog:\n%s" % (self.command, s, self.log) + +class LVCreateError(LvmError): + def __init__(self, vgname, lvname, size): + self.vgname = vgname + self.lvname = lvname + self.size = size + self.log = self.getLvmOutput() + + def __str__(self): + return "lvcreate of %d Megabyte lv "%s" on vg "%s" failed\n" \ + "Log:\n%s" % ( \ + self.size, self.lvname, self.vgname, self.log) + +class LVRemoveError(LvmError): + def __init__(self, vgname, lvname): + self.vgname = vgname + self.lvname = lvname + self.log = self.getLvmOutput() + + def __str__(self): + return "lvremove of lv "%s" from vg "%s" failed\nLog:\n%s" % ( \ + self.lvname, self.vgname, self.log) + +class LVResizeError(LvmError): + def __init__(self, vgname, lvname): + self.vgname = vgname + self.lvname = lvname + self.log = self.getLvmOutput() + + def __str__(self): + return "lvresize of lv "%s" from vg "%s" failed\nLog:\n%s" % ( \ + self.lvname, self.vgname, self.log) + +class VGCreateError(LvmError): + def __init__(self, vgname, PESize, nodes): + self.vgname = vgname + self.PESize = PESize + self.nodes = nodes + self.log = self.getLvmOutput() + + def __str__(self): + nodes = string.join(self.nodes, ' ') + return "vgcreate failed creating vg "%s" (PESize=%dkB) on PVs: %s\n" \ + "Log:\n%s" % ( \ + self.vgname, self.PESize, nodes, self.log) + +class VGRemoveError(LvmError): + def __init__(self, vgname): + self.vgname = vgname + self.log = self.getLvmOutput() + + def __str__(self): + return "vgremove of vg "%s" failed\nLog:\n%s" % ( \ + self.vgname, self.log) + +class PVRemoveError(LvmError): + def __init__(self, pvname): + self.pvname = pvname + self.log = self.getLvmOutput() + + def __str__(self): + return "pvremove of pv "%s" failed\nLog:\n%s" % ( \ + self.pvname, self.log) + +class PVCreateError(LvmError): + def __init__(self, pvname): + self.pvname = pvname + self.log = self.getLvmOutput() + + def __str__(self): + return "pvcreate of pv "%s" failed\nLog:\n%s" % ( \ + self.pvname, self.log) + +"""Exceptions for use in partitioning.""" + +class PartitioningError(Exception): + """A critical error which must be resolved to continue the installation.""" + def __init__(self, message=""): + self.message = str(message) + + def __str__ (self): + return self.message + +class PartitioningWarning(Exception): + """A warning which may be ignored and still complete the installation.""" + def __init__(self, message=""): + self.message = str(message) + + def __str__ (self): + return self.message + +class LabelError(Exception): + """The device could not be labeled.""" + def __init__(self, message=""): + self.message = str(message) + + def __str__(self): + return self.message + +"""Exceptions for use in package selection.""" + +class NoSuchGroup(Exception): + def __init__ (self, value): + self.value = value + + def __str__ (self): + return self.value diff --git a/pkgs/core/pomona/src/exception.py b/pkgs/core/pomona/src/exception.py new file mode 100644 index 0000000..3a018a8 --- /dev/null +++ b/pkgs/core/pomona/src/exception.py @@ -0,0 +1,169 @@ + +import bdb +import os, sys, signal, types +from cPickle import Pickler +from string import joinfields +import traceback + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +import logging +log = logging.getLogger("pomona") + +dumpHash = {} + +def dumpClass(instance, fd, level=0, parentkey="", skipList=[]): + # protect from loops + try: + if not dumpHash.has_key(instance): + dumpHash[instance] = None + else: + fd.write("Already dumped\n") + return + except TypeError: + fd.write("Cannot dump object\n") + return + + if (instance.__class__.__dict__.has_key("__str__") or + instance.__class__.__dict__.has_key("__repr__")): + fd.write("%s\n" % (instance,)) + return + fd.write("%s instance, containing members:\n" % + (instance.__class__.__name__)) + pad = ' ' * ((level) * 2) + + for key, value in instance.__dict__.items(): + if parentkey != "": + curkey = parentkey + "." + key + else: + curkey = key + + # Don't dump objects that are in our skip list, though ones that are + # None are probably okay. + if eval("instance.%s is not None" % key) and \ + eval("id(instance.%s)" % key) in skipList: + continue + + if type(value) == types.ListType: + fd.write("%s%s: [" % (pad, curkey)) + first = 1 + for item in value: + if not first: + fd.write(", ") + else: + first = 0 + if type(item) == types.InstanceType: + dumpClass(item, fd, level + 1, skipList=skipList) + else: + fd.write("%s" % (item,)) + fd.write("]\n") + elif type(value) == types.DictType: + fd.write("%s%s: {" % (pad, curkey)) + first = 1 + for k, v in value.items(): + if not first: + fd.write(", ") + else: + first = 0 + if type(k) == types.StringType: + fd.write("'%s': " % (k,)) + else: + fd.write("%s: " % (k,)) + if type(v) == types.InstanceType: + dumpClass(v, fd, level + 1, parentkey = curkey, skipList=skipList) + else: + fd.write("%s" % (v,)) + fd.write("}\n") + elif type(value) == types.InstanceType: + fd.write("%s%s: " % (pad, curkey)) + dumpClass(value, fd, level + 1, parentkey=curkey, skipList=skipList) + else: + fd.write("%s%s: %s\n" % (pad, curkey, value)) + +def dumpException(out, text, tb, pomona): + skipList = [] + idSkipList = [] + + # Catch attributes that do not exist at the time we do the exception dump + # and ignore them. + for k in skipList: + try: + eval("idSkipList.append(id(%s))" % k) + except: + pass + + p = Pickler(out) + + out.write(text) + + trace = tb + if trace is not None: + while trace.tb_next: + trace = trace.tb_next + frame = trace.tb_frame + out.write("\nLocal variables in innermost frame:\n") + try: + for (key, value) in frame.f_locals.items(): + out.write("%s: %s\n" % (key, value)) + except: + pass + + try: + out.write("\n\n") + dumpClass(pomona, out, skipList=idSkipList) + except: + out.write("\nException occurred during state dump:\n") + traceback.print_exc(None, out) + + for file in ("/root/syslog", "/root/pomona.log", "/root/install.log"): + try: + f = open(file, 'r') + line = "\n\n%s:\n" % (file,) + while line: + out.write(line) + line = f.readline() + f.close() + except IOError: + pass + except: + out.write("\nException occurred during %s file copy:\n" % (file,)) + traceback.print_exc(None, out) + +# Reverse the order that tracebacks are printed so people will hopefully quit +# giving us the least useful part of the exception in bug reports. +def formatException(type, value, tb): + lst = traceback.format_tb(tb) + lst.reverse() + lst.insert(0, 'Traceback (most recent call first):\n') + lst.extend(traceback.format_exception_only(type, value)) + return lst + +def handleException(pomona, (type, value, tb)): + if isinstance(value, bdb.BdbQuit): + sys.exit(1) + + # restore original exception handler + sys.excepthook = sys.__excepthook__ + + # get traceback information + list = formatException(type, value, tb) + text = joinfields(list, "") + + # save to local storage first + out = open("/tmp/instdump.txt", "w") + dumpException(out, text, tb, pomona) + out.close() + + win = pomona.intf.exceptionWindow(text, "/tmp/instdump.txt") + if not win: + pomona.intf.__del__() + os.kill(os.getpid(), signal.SIGKILL) + + while 1: + win.run() + rc = win.getrc() + + if rc == 0: + pomona.intf.__del__() + os.kill(os.getpid(), signal.SIGKILL) diff --git a/pkgs/core/pomona/src/flags.py b/pkgs/core/pomona/src/flags.py new file mode 100644 index 0000000..69b3768 --- /dev/null +++ b/pkgs/core/pomona/src/flags.py @@ -0,0 +1,67 @@ +# +# flags.py: global pomona flags +# +# Copyright 2001 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# library public license. +# +# You should have received a copy of the GNU Library Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import os +import shlex +from constants import * + +# A lot of effort, but it only allows a limited set of flags to be referenced +class Flags: + def __getattr__(self, attr): + if self.__dict__['flags'].has_key(attr): + return self.__dict__['flags'][attr] + raise AttributeError, attr + + def __setattr__(self, attr, val): + if self.__dict__['flags'].has_key(attr): + self.__dict__['flags'][attr] = val + else: + raise AttributeError, attr + + def createCmdlineDict(self): + cmdlineDict = {} + cmdline = open("/proc/cmdline", "r").read() + lst = shlex.split(cmdline) + + for i in lst: + try: + (key, val) = i.split("=", 1) + except: + key = i + val = True + + cmdlineDict[key] = val + + return cmdlineDict + + def __init__(self): + self.__dict__['flags'] = {} + self.__dict__['flags']['expert'] = 0 + self.__dict__['flags']['debug'] = 0 + self.__dict__['flags']['cmdline'] = self.createCmdlineDict() + self.__dict__['flags']['network'] = False + self.__dict__['flags']['mpath'] = 1 + self.__dict__['flags']['dmraid'] = 1 + + for line in os.popen("tty"): + line = line.strip() + if line.startswith("/dev/tty"): + self.__dict__['flags']['virtpconsole'] = False + else: + self.__dict__['flags']['virtpconsole'] = True + + if self.__dict__['flags']['cmdline'].has_key("debug"): + self.__dict__['flags']['debug'] = self.__dict__['flags']['cmdline']['debug'] + +global flags +flags = Flags() diff --git a/pkgs/core/pomona/src/fsset.py b/pkgs/core/pomona/src/fsset.py new file mode 100644 index 0000000..dcc80f3 --- /dev/null +++ b/pkgs/core/pomona/src/fsset.py @@ -0,0 +1,2876 @@ +# +# fsset.py: filesystem management +# +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Matt Wilson <msw@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# + +import math +import string +import isys +import iutil +import os +import resource +import posix +import stat +import errno +import parted +import sys +import struct +import partitions +import partedUtils +import raid +import lvm +import time +import types +from flags import flags +from constants import * + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +import logging +log = logging.getLogger("pomona") + +class SuspendError(Exception): + pass + +class OldSwapError(Exception): + pass + +class ResizeError(Exception): + pass + +defaultMountPoints = ['/', '/boot', '/home', '/tmp', '/usr', '/var', '/usr/local', '/opt'] + +fileSystemTypes = {} + +def fileSystemTypeGetDefault(): + if fileSystemTypeGet('ext4').isSupported(): + return fileSystemTypeGet('ext4') + elif fileSystemTypeGet('ext3').isSupported(): + return fileSystemTypeGet('ext3') + elif fileSystemTypeGet('ext2').isSupported(): + return fileSystemTypeGet('ext2') + else: + raise ValueError, "You have neither ext4, ext3 or ext2 support in your kernel!" + + +def fileSystemTypeGet(key): + return fileSystemTypes[key] + +def fileSystemTypeRegister(klass): + fileSystemTypes[klass.getName()] = klass + +def fileSystemTypeGetTypes(): + return fileSystemTypes.copy() + +def getUsableLinuxFs(): + rc = [] + for fsType in fileSystemTypes.keys(): + if fileSystemTypes[fsType].isMountable() and \ + fileSystemTypes[fsType].isLinuxNativeFS(): + rc.append(fsType) + + # make sure the default is first in the list, kind of ugly + default = fileSystemTypeGetDefault() + defaultName = default.getName() + if defaultName in rc: + del rc[rc.index(defaultName)] + rc.insert(0, defaultName) + return rc + +def devify(device): + if device in ["proc", "devpts", "sysfs", "tmpfs"] or device.find(":") != -1: + return device + elif device == "sys": + return "sysfs" + elif device == "shm": + return "tmpfs" + elif device == "spufs": + return "spufs" + elif device != "none" and device[0] != '/': + return "/dev/" + device + else: + return device + +class FileSystemType: + kernelFilesystems = {} + lostAndFoundContext = None + + def __init__(self): + self.deviceArguments = {} + self.formattable = 0 + self.checked = 0 + self.name = "" + self.linuxnativefs = 0 + self.partedFileSystemType = None + self.partedPartitionFlags = [] + self.maxSizeMB = 8 * 1024 * 1024 + self.supported = -1 + self.defaultOptions = "defaults" + self.migratetofs = None + self.extraFormatArgs = [] + self.maxLabelChars = 16 + self.packages = [] + self.needProgram = [] + self.resizable = False + self.supportsFsProfiles = False + self.fsProfileSpecifier = None + self.fsprofile = None + self.bootable = False + + def createLabel(self, mountpoint, maxLabelChars, kslabel = None): + # If a label was specified in the kickstart file, return that as the + # label. + if kslabel: + return kslabel + + if len(mountpoint) > maxLabelChars: + return mountpoint[0:maxLabelChars] + else: + return mountpoint + + def isBootable(self): + return self.bootable + + def isResizable(self): + return self.resizable + def resize(self, entry, size, progress, chroot='/'): + pass + def getMinimumSize(self, device): + log.warning("Unable to determinine minimal size for %s", device) + return 1 + + def isKernelFS(self): + """Returns True if this is an in-kernel pseudo-filesystem.""" + return False + + def mount(self, device, mountpoint, readOnly=0, bindMount=0, + instroot=""): + if not self.isMountable(): + return + iutil.mkdirChain("%s/%s" %(instroot, mountpoint)) + log.debug("mounting %s on %s/%s as %s" %(device, instroot, + mountpoint, self.getMountName())) + isys.mount(device, "%s/%s" %(instroot, mountpoint), + fstype = self.getMountName(), + readOnly = readOnly, bindMount = bindMount, + options = self.defaultOptions) + + def umount(self, device, path): + isys.umount(path, removeDir = 0) + + def getName(self, quoted = 0): + """Return the name of the filesystem. Set quoted to 1 if this + should be quoted (ie, it's not for display).""" + if quoted: + if self.name.find(" ") != -1: + return ""%s"" %(self.name,) + return self.name + + def getMountName(self, quoted = 0): + return self.getName(quoted) + + def getNeededPackages(self): + return self.packages + + def registerDeviceArgumentFunction(self, klass, function): + self.deviceArguments[klass] = function + + def formatDevice(self, entry, progress, chroot='/'): + if self.isFormattable(): + raise RuntimeError, "formatDevice method not defined" + + def migrateFileSystem(self, device, message, chroot='/'): + if self.isMigratable(): + raise RuntimeError, "migrateFileSystem method not defined" + + def labelDevice(self, entry, chroot): + pass + + def clobberDevice(self, entry, chroot): + pass + + def isFormattable(self): + return self.formattable + + def isLinuxNativeFS(self): + return self.linuxnativefs + + def setFsProfile(self, fsprofile=None): + if not self.supportsFsProfiles: + raise RuntimeError, "%s does not support profiles" % (self,) + self.fsprofile = fsprofile + + def getFsProfileArgs(self): + if not self.supportsFsProfiles: + raise RuntimeError, "%s does not support profiles" % (self,) + args = None + if self.fsprofile: + args = [] + if self.fsProfileSpecifier: + args.extend(self.fsProfileSpecifier) + args.extend(self.fsprofile) + return args + + def readProcFilesystems(self): + f = open("/proc/filesystems", 'r') + if not f: + pass + lines = f.readlines() + for line in lines: + fields = string.split(line) + if fields[0] == "nodev": + fsystem = fields[1] + else: + fsystem = fields[0] + FileSystemType.kernelFilesystems[fsystem] = None + + def isMountable(self): + if not FileSystemType.kernelFilesystems: + self.readProcFilesystems() + + return FileSystemType.kernelFilesystems.has_key(self.getMountName()) or self.getName() == "auto" + + def isSupported(self): + # check to ensure we have the binaries they need + for p in self.needProgram: + if len(filter(lambda d: os.path.exists("%s/%s" %(d, p)), + os.environ["PATH"].split(":"))) == 0: + return False + + if self.supported == -1: + return self.isMountable() + return self.supported + + def isChecked(self): + return self.checked + + def getDeviceArgs(self, device): + deviceArgsFunction = self.deviceArguments.get(device.__class__) + if not deviceArgsFunction: + return [] + return deviceArgsFunction(device) + + def getPartedFileSystemType(self): + return self.partedFileSystemType + + def getPartedPartitionFlags(self): + return self.partedPartitionFlags + + # note that this returns the maximum size of a filesystem in megabytes + def getMaxSizeMB(self): + return self.maxSizeMB + + def getDefaultOptions(self, mountpoint): + return self.defaultOptions + + def getMigratableFSTargets(self): + retval = [] + if not self.migratetofs: + return retval + + for fs in self.migratetofs: + if fileSystemTypeGet(fs).isSupported(): + retval.append(fs) + + return retval + + def isMigratable(self): + if len(self.getMigratableFSTargets()) > 0: + return 1 + else: + return 0 + + +class reiserfsFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("reiserfs") + self.formattable = 1 + self.checked = 1 + self.linuxnativefs = 1 + self.bootable = True + # this is totally, 100% unsupported. Boot with "linux reiserfs" + # at the boot: prompt will let you make new reiserfs filesystems + # in the installer. Bugs filed when you use this will be closed + # WONTFIX. + if flags.cmdline.has_key("reiserfs"): + self.supported = -1 + else: + self.supported = 0 + + self.name = "reiserfs" + self.packages = [ "reiserfs-utils" ] + self.needProgram = [ "mkreiserfs", "reiserfstune" ] + + self.maxSizeMB = 8 * 1024 * 1024 + + def formatDevice(self, entry, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + + p = os.pipe() + os.write(p[1], "y\n") + os.close(p[1]) + + rc = iutil.execWithRedirect("mkreiserfs", + [devicePath], + stdin = p[0], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + + if rc: + raise SystemError + + def labelDevice(self, entry, chroot): + devicePath = entry.device.setupDevice(chroot) + label = self.createLabel(entry.mountpoint, self.maxLabelChars, + kslabel = entry.label) + rc = iutil.execWithRedirect("reiserfstune", + ["--label", label, devicePath], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + if rc: + raise SystemError + entry.setLabel(label) + +fileSystemTypeRegister(reiserfsFileSystem()) + +class xfsFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("xfs") + self.formattable = 1 + self.checked = 1 + self.linuxnativefs = 1 + self.name = "xfs" + self.maxSizeMB = 16 * 1024 * 1024 + self.maxLabelChars = 12 + self.supported = -1 + if not os.path.exists("/sbin/mkfs.xfs") and not os.path.exists("/usr/sbin/mkfs.xfs"): + self.supported = 0 + + self.packages = [ "xfsprogs" ] + self.needProgram = [ "mkfs.xfs", "xfs_admin" ] + + def formatDevice(self, entry, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + + rc = iutil.execWithRedirect("mkfs.xfs", ["-f", devicePath], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + + if rc: + raise SystemError + + def labelDevice(self, entry, chroot): + devicePath = entry.device.setupDevice(chroot) + label = self.createLabel(entry.mountpoint, self.maxLabelChars, + kslabel = entry.label) + rc = iutil.execWithRedirect("xfs_admin", + ["-L", label, devicePath], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + if rc: + raise SystemError + entry.setLabel(label) + +fileSystemTypeRegister(xfsFileSystem()) + +class jfsFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("jfs") + self.formattable = 1 + self.checked = 1 + self.linuxnativefs = 1 + self.maxLabelChars = 16 + self.bootable = True + # this is totally, 100% unsupported. Boot with "linux jfs" + # at the boot: prompt will let you make new reiserfs filesystems + # in the installer. Bugs filed when you use this will be closed + # WONTFIX. + if flags.cmdline.has_key("jfs"): + self.supported = -1 + else: + self.supported = 0 + + self.name = "jfs" + self.packages = [ "jfsutils" ] + self.needProgram = [ "mkfs.jfs", "jfs_tune" ] + + self.maxSizeMB = 8 * 1024 * 1024 + + def labelDevice(self, entry, chroot): + devicePath = entry.device.setupDevice(chroot) + label = self.createLabel(entry.mountpoint, self.maxLabelChars, + kslabel = entry.label) + rc = iutil.execWithRedirect("jfs_tune", + ["-L", label, devicePath], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + if rc: + raise SystemError + entry.setLabel(label) + + def formatDevice(self, entry, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + + rc = iutil.execWithRedirect("mkfs.jfs", + ["-q", devicePath], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + + if rc: + raise SystemError + +fileSystemTypeRegister(jfsFileSystem()) + +class extFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = None + self.formattable = 1 + self.checked = 1 + self.linuxnativefs = 1 + self.maxSizeMB = 8 * 1024 * 1024 + self.packages = [ "e2fsprogs" ] + self.supportsFsProfiles = True + self.fsProfileSpecifier = "-T" + self.resizable = True + self.bootable = True + + def resize(self, entry, size, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + + log.info("checking %s prior to resize" %(devicePath,)) + w = None + if progress: + w = progress(_("Checking"), + _("Checking filesystem on %s...") %(devicePath), + 100, pulse = True) + + rc = iutil.execWithPulseProgress("e2fsck", ["-f", "-p", "-C", "0", devicePath], + stdout="/tmp/resize.out", + stderr="/tmp/resize.out", + progress = w) + if rc >= 4: + raise ResizeError, ("Check of %s failed" %(devicePath,), devicePath) + if progress: + w.pop() + w = progress(_("Resizing"), + _("Resizing filesystem on %s...") %(devicePath), + 100, pulse = True) + + log.info("resizing %s" %(devicePath,)) + rc = iutil.execWithPulseProgress("resize2fs", + ["-p", devicePath, "%sM" %(size,)], + stdout="/tmp/resize.out", + stderr="/tmp/resize.out", + progress = w) + if progress: + w.pop() + if rc: + raise ResizeError, ("Resize of %s failed" %(devicePath,), devicePath) + + def getMinimumSize(self, device): + """Return the minimum filesystem size in megabytes""" + devicePath = "/dev/%s" % (device,) + + # FIXME: it'd be nice if we didn't have to parse this out ourselves + buf = iutil.execWithCapture("dumpe2fs", + ["-h", devicePath], + stderr = "/dev/tty5") + blocks = free = bs = 0 + for l in buf.split("\n"): + if l.startswith("Free blocks"): + try: + free = l.split()[2] + free = int(free) + except Exception, e: + log.warning("error determining free blocks on %s: %s" %(devicePath, e)) + free = 0 + elif l.startswith("Block size"): + try: + bs = l.split()[2] + bs = int(bs) + except Exception, e: + log.warning("error determining block size of %s: %s" %(devicePath, e)) + bs = 0 + elif l.startswith("Block count"): + try: + blocks = l.split()[2] + blocks = int(blocks) + except Exception, e: + log.warning("error determining block count of %s: %s" %(devicePath, e)) + blocks = 0 + + if free == 0 or bs == 0: + log.warning("Unable to determinine minimal size for %s", devicePath) + return 1 + + used = math.ceil((blocks - free) * bs / 1024.0 / 1024.0) + log.info("used size of %s is %s" %(devicePath, used)) + # FIXME: should we bump this beyond the absolute minimum? + return used + + def labelDevice(self, entry, chroot): + devicePath = entry.device.setupDevice(chroot) + label = self.createLabel(entry.mountpoint, self.maxLabelChars, + kslabel = entry.label) + + rc = iutil.execWithRedirect("e2label", + [devicePath, label], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + if rc: + raise SystemError + entry.setLabel(label) + + def formatDevice(self, entry, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + devArgs = self.getDeviceArgs(entry.device) + args = [ "mke2fs", devicePath ] + + fsProfileArgs = self.getFsProfileArgs() + if fsProfileArgs: + args.extend(fsProfileArgs) + args.extend(devArgs) + args.extend(self.extraFormatArgs) + + log.info("Format command: %s\n" % str(args)) + + rc = ext2FormatFilesystem(args, "/dev/tty5", + progress, + entry.mountpoint) + if rc: + raise SystemError + + def clobberDevice(self, entry, chroot): + device = entry.device.setupDevice(chroot) + isys.ext2Clobber(device) + + # this is only for ext3 filesystems, but migration is a method + # of the ext2 fstype, so it needs to be here. FIXME should be moved + def setExt3Options(self, entry, message, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + + # if no journal, don't turn off the fsck + if not isys.ext2HasJournal(devicePath): + return + + rc = iutil.execWithRedirect("tune2fs", + ["-c0", "-i0", + "-ouser_xattr,acl", devicePath], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + +class ext2FileSystem(extFileSystem): + def __init__(self): + extFileSystem.__init__(self) + self.name = "ext2" + self.partedFileSystemType = parted.file_system_type_get("ext2") + self.migratetofs = ['ext3'] + + def migrateFileSystem(self, entry, message, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + + if not entry.fsystem or not entry.origfsystem: + raise RuntimeError, ("Trying to migrate fs w/o fsystem or " + "origfsystem set") + if entry.fsystem.getName() != "ext3": + raise RuntimeError, ("Trying to migrate ext2 to something other " + "than ext3") + + # if journal already exists skip + if isys.ext2HasJournal(devicePath): + log.info("Skipping migration of %s, has a journal already.\n" % devicePath) + return + + rc = iutil.execWithRedirect("tune2fs", + ["-j", devicePath ], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + + if rc: + raise SystemError + + # XXX this should never happen, but appears to have done + # so several times based on reports in bugzilla. + # At least we can avoid leaving them with a system which won't boot + if not isys.ext2HasJournal(devicePath): + log.warning("Migration of %s attempted but no journal exists after " + "running tune2fs.\n" % (devicePath)) + if message: + rc = message(_("Error"), + _("An error occurred migrating %s to ext3. It is " + "possible to continue without migrating this " + "file system if desired.\n\n" + "Would you like to continue without migrating %s?") + % (devicePath, devicePath), type = "yesno") + if rc == 0: + sys.exit(0) + entry.fsystem = entry.origfsystem + else: + extFileSystem.setExt3Options(self, entry, message, chroot) + + +fileSystemTypeRegister(ext2FileSystem()) + +class ext3FileSystem(extFileSystem): + def __init__(self): + extFileSystem.__init__(self) + self.name = "ext3" + self.extraFormatArgs = [ "-t", "ext3" ] + self.partedFileSystemType = parted.file_system_type_get("ext3") + if flags.cmdline.has_key("ext4"): + self.migratetofs = ['ext4dev'] + + def formatDevice(self, entry, progress, chroot='/'): + extFileSystem.formatDevice(self, entry, progress, chroot) + extFileSystem.setExt3Options(self, entry, progress, chroot) + + def migrateFileSystem(self, entry, message, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + + if not entry.fsystem or not entry.origfsystem: + raise RuntimeError, ("Trying to migrate fs w/o fsystem or " + "origfsystem set") + if entry.fsystem.getName() != "ext4dev": + raise RuntimeError, ("Trying to migrate ext3 to something other " + "than ext4") + + # This is only needed as long as ext4 is actually "ext4dev" + rc = iutil.execWithRedirect("tune2fs", + ["-E", "test_fs", devicePath ], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + if rc: + raise SystemError + +fileSystemTypeRegister(ext3FileSystem()) + +class ext4FileSystem(extFileSystem): + def __init__(self): + extFileSystem.__init__(self) + self.name = "ext4" + self.partedFileSystemType = parted.file_system_type_get("ext3") + self.extraFormatArgs = [ "-t", "ext4" ] + self.bootable = False + + def formatDevice(self, entry, progress, chroot='/'): + extFileSystem.formatDevice(self, entry, progress, chroot) + extFileSystem.setExt3Options(self, entry, progress, chroot) + +fileSystemTypeRegister(ext4FileSystem()) + +class btrfsFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.formattable = 1 + self.checked = 1 + self.linuxnativefs = 1 + self.bootable = False + self.maxLabelChars = 256 + + self.name = "btrfs" + self.packages = [ "btrfs-progs" ] + self.needProgram = [ "mkfs.btrfs", "btrfsctl" ] + + # Bigger, really, depending on machine + self.maxSizeMB = 16 * 1024 * 1024 + + # We'll sneakily label it here, too. + def formatDevice(self, entry, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + label = self.createLabel(entry.mountpoint, self.maxLabelChars, + kslabel = entry.label) + + rc = iutil.execWithRedirect("mkfs.btrfs", ["-L", label, devicePath], + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + + if rc: + raise SystemError + entry.setLabel(label) + + def labelDevice(self, entry, chroot): + # We did this on the initial format; no standalone labeler yet + pass + + def resize(self, entry, size, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + log.info("resizing %s" %(devicePath,)) + + w = None + if progress: + w = progress(_("Resizing"), + _("Resizing filesystem on %s...") %(devicePath), + 100, pulse = True) + + rc = iutil.execWithPulseProgress("btrfsctl", + ["-r", "%sM" %(size,), devicePath], + stdout="/tmp/resize.out", + stderr="/tmp/resize.out", + progress = w) + if progress: + w.pop() + if rc: + raise ResizeError, ("Resize of %s failed: %s" %(devicePath, rc), devicePath) + + +fileSystemTypeRegister(btrfsFileSystem()) + +class raidMemberDummyFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("ext2") + self.partedPartitionFlags = [ parted.PARTITION_RAID ] + self.formattable = 1 + self.checked = 0 + self.linuxnativefs = 1 + self.name = "software RAID" + self.maxSizeMB = 8 * 1024 * 1024 + self.supported = 1 + + if len(raid.availRaidLevels) == 0: + self.supported = 0 + + self.packages = [ "mdadm" ] + + def formatDevice(self, entry, progress, chroot='/'): + # mkraid did all we need to format this partition... + pass + +fileSystemTypeRegister(raidMemberDummyFileSystem()) + +class lvmPhysicalVolumeDummyFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("ext2") + self.partedPartitionFlags = [ parted.PARTITION_LVM ] + self.formattable = 1 + self.checked = 0 + self.linuxnativefs = 1 + self.name = "physical volume (LVM)" + self.maxSizeMB = 8 * 1024 * 1024 + self.supported = 1 + self.packages = [ "lvm2" ] + + def isMountable(self): + return 0 + + def formatDevice(self, entry, progress, chroot='/'): + # already done by the pvcreate during volume creation + pass + +fileSystemTypeRegister(lvmPhysicalVolumeDummyFileSystem()) + +class lvmVolumeGroupDummyFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("ext2") + self.formattable = 1 + self.checked = 0 + self.linuxnativefs = 0 + self.name = "volume group (LVM)" + self.supported = 0 + self.maxSizeMB = 8 * 1024 * 1024 + self.packages = [ "lvm2" ] + + def isMountable(self): + return 0 + + def formatDevice(self, entry, progress, chroot='/'): + # the vgcreate already did this + pass + +fileSystemTypeRegister(lvmVolumeGroupDummyFileSystem()) + +class swapFileSystem(FileSystemType): + enabledSwaps = {} + + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("linux-swap") + self.formattable = 1 + self.name = "swap" + self.maxSizeMB = 8 * 1024 * 1024 + self.linuxnativefs = 1 + self.supported = 1 + self.maxLabelChars = 15 + + def mount(self, device, mountpoint, readOnly=0, bindMount=0, + instroot = None): + pagesize = resource.getpagesize() + buf = None + if pagesize > 2048: + num = pagesize + else: + num = 2048 + try: + fd = os.open(device, os.O_RDONLY) + buf = os.read(fd, num) + except: + pass + finally: + try: + os.close(fd) + except: + pass + + if buf is not None and len(buf) == pagesize: + sig = buf[pagesize - 10:] + if sig == 'SWAP-SPACE': + raise OldSwapError + if sig == 'S1SUSPEND\x00' or sig == 'S2SUSPEND\x00': + raise SuspendError + + isys.swapon (device) + + def umount(self, device, path): + # unfortunately, turning off swap is bad. + raise RuntimeError, "unable to turn off swap" + + def formatDevice(self, entry, progress, chroot='/'): + file = entry.device.setupDevice(chroot) + rc = iutil.execWithRedirect ("mkswap", + ['-v1', file], + stdout = "/dev/tty5", + stderr = "/dev/tty5", + searchPath = 1) + if rc: + raise SystemError + + def labelDevice(self, entry, chroot): + file = entry.device.setupDevice(chroot) + devName = entry.device.getDevice() + # we'll keep the SWAP-* naming for all devs but Compaq SMART2 + # nodes (#176074) + if devName[0:6] == "cciss/": + swapLabel = "SW-%s" % (devName) + elif devName.startswith("mapper/"): + swapLabel = "SWAP-%s" % (devName[7:],) + else: + swapLabel = "SWAP-%s" % (devName) + label = self.createLabel(swapLabel, self.maxLabelChars) + rc = iutil.execWithRedirect ("mkswap", + ['-v1', "-L", label, file], + stdout = "/dev/tty5", + stderr = "/dev/tty5", + searchPath = 1) + if rc: + raise SystemError + entry.setLabel(label) + + def clobberDevice(self, entry, chroot): + pagesize = resource.getpagesize() + dev = entry.device.setupDevice(chroot) + try: + fd = os.open(dev, os.O_RDWR) + buf = "\0x00" * pagesize + os.write(fd, buf) + except: + pass + finally: + try: + os.close(fd) + except: + pass + +fileSystemTypeRegister(swapFileSystem()) + +class FATFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("fat32") + self.formattable = 1 + self.checked = 0 + self.maxSizeMB = 1024 * 1024 + self.name = "vfat" + self.packages = [ "dosfstools" ] + self.defaultOptions = "umask=0077,shortname=winnt" + + def formatDevice(self, entry, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + devArgs = self.getDeviceArgs(entry.device) + args = [ devicePath ] + args.extend(devArgs) + + rc = iutil.execWithRedirect("mkdosfs", args, + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + if rc: + raise SystemError + + def labelDevice(self, entry, chroot): + devicePath = entry.device.setupDevice(chroot) + label = self.createLabel(entry.mountpoint, self.maxLabelChars, + kslabel = entry.label) + + rc = iutil.execWithRedirect("dosfslabel", + [devicePath, label], + stdout = "/dev/tty5", + stderr = "/dev/tty5", + searchPath = 1) + if rc: + msg = iutil.execWithCapture("dosfslabel", [devicePath], + stderr="/dev/tty5") + raise SystemError, "dosfslabel failed on device %s: %s" % (devicePath, msg) + + newLabel = iutil.execWithCapture("dosfslabel", [devicePath], + stderr = "/dev/tty5") + newLabel = newLabel.strip() + if label != newLabel: + raise SystemError, "dosfslabel failed on device %s" % (devicePath,) + entry.setLabel(label) + +fileSystemTypeRegister(FATFileSystem()) + +class NTFSFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("ntfs") + self.formattable = 0 + self.checked = 0 + self.name = "ntfs" + if len(filter(lambda d: os.path.exists("%s/ntfsresize" %(d,)), + os.environ["PATH"].split(":"))) > 0: + self.resizable = True + + def resize(self, entry, size, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + log.info("resizing %s to %sM" %(devicePath, size)) + w = None + if progress: + w = progress(_("Resizing"), + _("Resizing filesystem on %s...") %(devicePath), + 100, pulse = True) + + p = os.pipe() + os.write(p[1], "y\n") + os.close(p[1]) + + # FIXME: we should call ntfsresize -c to ensure that we can resize + # before starting the operation + + rc = iutil.execWithPulseProgress("ntfsresize", ["-v", + "-s", "%sM" %(size,), + devicePath], + stdin = p[0], + stdout = "/tmp/resize.out", + stderr = "/tmp/resize.out", + progress = w) + if progress: + w.pop() + if rc: + raise ResizeError, ("Resize of %s failed" %(devicePath,), devicePath) + + def getMinimumSize(self, device): + """Return the minimum filesystem size in megabytes""" + devicePath = "/dev/%s" % (device,) + + buf = iutil.execWithCapture("ntfsresize", ["-m", devicePath], + stderr = "/dev/tty5") + for l in buf.split("\n"): + if not l.startswith("Minsize"): + continue + try: + min = l.split(":")[1].strip() + return int(min) + 250 + except Exception, e: + log.warning("Unable to parse output for minimum size on %s: %s" %(device, e)) + + log.warning("Unable to discover minimum size of filesystem on %s" %(device,)) + return 1 + + +fileSystemTypeRegister(NTFSFileSystem()) + +class hfsFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("hfs") + self.formattable = 1 + self.checked = 0 + self.name = "hfs" + self.supported = 0 + self.needProgram = [ "hformat" ] + + def isMountable(self): + return 0 + + def formatDevice(self, entry, progress, chroot='/'): + devicePath = entry.device.setupDevice(chroot) + devArgs = self.getDeviceArgs(entry.device) + args = [ devicePath ] + args.extend(devArgs) + + rc = iutil.execWithRedirect("hformat", args, + stdout = "/dev/tty5", + stderr = "/dev/tty5", searchPath = 1) + if rc: + raise SystemError + +fileSystemTypeRegister(hfsFileSystem()) + +class HfsPlusFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.partedFileSystemType = parted.file_system_type_get("hfs+") + self.formattable = 0 + self.checked = 0 + self.name = "hfs+" + +fileSystemTypeRegister(HfsPlusFileSystem()) + +class networkFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.formattable = 0 + self.checked = 0 + self.name = "nfs" + + def isMountable(self): + return 0 + +fileSystemTypeRegister(networkFileSystem()) + +class nfsv4FileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.formattable = 0 + self.checked = 0 + self.name = "nfs4" + + def isMountable(self): + return 0 + +fileSystemTypeRegister(nfsv4FileSystem()) + +class ForeignFileSystem(FileSystemType): + def __init__(self): + FileSystemType.__init__(self) + self.formattable = 0 + self.checked = 0 + self.name = "foreign" + + def formatDevice(self, entry, progress, chroot='/'): + return + +fileSystemTypeRegister(ForeignFileSystem()) + +class PseudoFileSystem(FileSystemType): + def __init__(self, name): + FileSystemType.__init__(self) + self.formattable = 0 + self.checked = 0 + self.name = name + self.supported = 0 + + def isKernelFS(self): + return True + +class SpuFileSystem(PseudoFileSystem): + def __init__(self): + PseudoFileSystem.__init__(self, "spufs") + +fileSystemTypeRegister(SpuFileSystem()) + +class ProcFileSystem(PseudoFileSystem): + def __init__(self): + PseudoFileSystem.__init__(self, "proc") + +fileSystemTypeRegister(ProcFileSystem()) + +class SysfsFileSystem(PseudoFileSystem): + def __init__(self): + PseudoFileSystem.__init__(self, "sysfs") + +fileSystemTypeRegister(SysfsFileSystem()) + +class DevptsFileSystem(PseudoFileSystem): + def __init__(self): + PseudoFileSystem.__init__(self, "devpts") + self.defaultOptions = "gid=5,mode=620" + + def isMountable(self): + return 0 + +fileSystemTypeRegister(DevptsFileSystem()) + +class DevshmFileSystem(PseudoFileSystem): + def __init__(self): + PseudoFileSystem.__init__(self, "tmpfs") + + def isMountable(self): + return 0 + +fileSystemTypeRegister(DevshmFileSystem()) + +class AutoFileSystem(PseudoFileSystem): + def __init__(self): + PseudoFileSystem.__init__(self, "auto") + + def mount(self, device, mountpoint, readOnly=0, bindMount=0, + instroot = None): + errNum = 0 + errMsg = "cannot mount auto filesystem on %s of this type" % device + + if not self.isMountable(): + return + iutil.mkdirChain("%s/%s" %(instroot, mountpoint)) + + fs = isys.readFSType(device) + if fs is not None: + try: + isys.mount (device, mountpoint, fstype = fs, readOnly = + readOnly, bindMount = bindMount) + return + except SystemError, (num, msg): + errNum = num + errMsg = msg + + raise SystemError (errNum, errMsg) + + def umount(self, device, path): + isys.umount(path, removeDir = 0) + +fileSystemTypeRegister(AutoFileSystem()) + +class BindFileSystem(PseudoFileSystem): + def __init__(self): + PseudoFileSystem.__init__(self, "bind") + + def isMountable(self): + return 1 + +fileSystemTypeRegister(BindFileSystem()) + +class FileSystemSet: + def __init__(self): + self.messageWindow = None + self.progressWindow = None + self.waitWindow = None + self.mountcount = 0 + self.migratedfs = 0 + self.reset() + self.volumesCreated = 0 + + def isActive(self): + return self.mountcount != 0 + + def registerMessageWindow(self, method): + self.messageWindow = method + + def registerProgressWindow(self, method): + self.progressWindow = method + + def registerWaitWindow(self, method): + self.waitWindow = method + + def reset (self): + self.entries = [] + proc = FileSystemSetEntry(Device(device="proc"), '/proc', + fileSystemTypeGet("proc")) + self.add(proc) + sys = FileSystemSetEntry(Device(device="sys"), '/sys', + fileSystemTypeGet("sysfs")) + self.add(sys) + pts = FileSystemSetEntry(Device(device="devpts"), '/dev/pts', + fileSystemTypeGet("devpts"), "gid=5,mode=620") + self.add(pts) + shm = FileSystemSetEntry(Device(device="shm"), '/dev/shm', + fileSystemTypeGet("tmpfs")) + self.add(shm) + + def verify (self): + for entry in self.entries: + if type(entry.__dict__) != type({}): + raise RuntimeError, "fsset internals inconsistent" + + def add (self, newEntry): + # Should object A be sorted after object B? Take mountpoints and + # device names into account so bind mounts are sorted correctly. + def comesAfter (a, b): + mntA = a.mountpoint + mntB = b.mountpoint + devA = a.device.getDevice() + devB = b.device.getDevice() + + if not mntB: + return False + if mntA and mntA != mntB and mntA.startswith(mntB): + return True + if devA and devA != mntB and devA.startswith(mntB): + return True + return False + + def samePseudo (a, b): + return isinstance(a.fsystem, PseudoFileSystem) and isinstance (b.fsystem, PseudoFileSystem) and \ + not isinstance (a.fsystem, BindFileSystem) and not isinstance (b.fsystem, BindFileSystem) and \ + a.fsystem.getName() == b.fsystem.getName() + + def sameEntry (a, b): + return a.device.getDevice() == b.device.getDevice() and a.mountpoint == b.mountpoint + + # Remove preexisting duplicate entries - pseudo filesystems are + # duplicate if they have the same filesystem type as an existing one. + # Otherwise, they have to have the same device and mount point + # (required to check for bind mounts). + for existing in self.entries: + if samePseudo (newEntry, existing) or sameEntry (newEntry, existing): + self.remove(existing) + + # XXX debuggin' +## log.info ("fsset at %s\n" +## "adding entry for %s\n" +## "entry object %s, class __dict__ is %s", +## self, entry.mountpoint, entry, +## isys.printObject(entry.__dict__)) + + insertAt = 0 + + # Special case for /. + if newEntry.mountpoint == "/": + self.entries.insert(insertAt, newEntry) + return + + # doesn't matter where these get added, so just put them at the end + if not newEntry.mountpoint or not newEntry.mountpoint.startswith("/") or self.entries == []: + self.entries.append(newEntry) + return + + for entry in self.entries: + if comesAfter(newEntry, entry): + insertAt = self.entries.index(entry)+1 + + self.entries.insert(insertAt, newEntry) + + def remove (self, entry): + self.entries.remove(entry) + + def getEntryByMountPoint(self, mount): + for entry in self.entries: + if entry.mountpoint == mount: + return entry + return None + + def getEntryByDeviceName(self, dev): + for entry in self.entries: + if entry.device.getDevice() == dev: + return entry + + # getDevice() will return the mapped device if using LUKS + if entry.device.device == dev: + return entry + + return None + + def copy (self): + new = FileSystemSet() + for entry in self.entries: + new.add (entry) + return new + + def fstab (self): + format = "%-23s %-23s %-7s %-15s %d %d\n" + fstab = """ +# +# /etc/fstab +# Created by pomona on %s +# +# Accessible filesystems, by reference, are maintained under '/dev/disk' +# See man pages fstab(5), findfs(8), mount(8) and/or vol_id(8) for more info +# +""" % time.asctime() + + for entry in self.entries: + if entry.mountpoint: + if entry.getUuid() and entry.device.doLabel is not None: + device = "UUID=%s" %(entry.getUuid(),) + elif entry.getLabel() and entry.device.doLabel is not None: + device = "LABEL=%s" % (entry.getLabel(),) + else: + device = devify(entry.device.getDevice()) + fstab = fstab + entry.device.getComment() + fstab = fstab + format % (device, entry.mountpoint, + entry.fsystem.getMountName(), + entry.getOptions(), entry.fsck, + entry.order) + return fstab + + def mtab (self): + format = "%s %s %s %s 0 0\n" + mtab = "" + for entry in self.entries: + if not entry.isMounted(): + continue + if entry.mountpoint: + # swap doesn't end up in the mtab + if entry.fsystem.getName() == "swap": + continue + options = entry.getOptions() + if options: + options = "rw," + options + else: + options = "rw" + mtab = mtab + format % (devify(entry.device.getDevice()), + entry.mountpoint, + entry.fsystem.getName(), + options) + return mtab + + def raidtab(self): + # set up raidtab... + raidtab = "" + for entry in self.entries: + if entry.device.getName() == "RAIDDevice": + raidtab = raidtab + entry.device.raidTab() + + return raidtab + + def mdadmConf(self): + """Make the mdadm.conf file with mdadm command. + + This creates a conf file with active arrays. In other words + the arrays that we don't want included must be inactive. + """ + activeArrays = iutil.execWithCapture("mdadm", ["--detail", "--scan"]) + if len(activeArrays) == 0: + return + + cf = """ +# mdadm.conf written out by pomona +DEVICE partitions +MAILADDR root + +%s +""" % activeArrays + return cf + + def crypttab(self): + """set up /etc/crypttab""" + crypttab = "" + for entry in self.entries: + if entry.device.crypto: + crypttab += entry.device.crypto.crypttab() + + return crypttab + + def write (self, prefix): + f = open (prefix + "/etc/fstab", "w") + f.write (self.fstab()) + f.close () + + cf = self.mdadmConf() + + if cf: + f = open (prefix + "/etc/mdadm.conf", "w") + f.write (cf) + f.close () + + crypttab = self.crypttab() + if crypttab: + f = open(prefix + "/etc/crypttab", "w") + f.write(crypttab) + f.close() + + # touch mtab + open (prefix + "/etc/mtab", "w+") + f.close () + + def mkDevRoot(self, instPath): + root = self.getEntryByMountPoint("/") + dev = "%s/dev/%s" % (instPath, root.device.getDevice()) + if not os.path.exists("%s/dev/root" %(instPath,)) and os.path.exists(dev): + rdev = os.stat(dev).st_rdev + os.mknod("%s/dev/root" % (instPath,), stat.S_IFBLK | 0600, rdev) + + # return the "boot" device + def getBootDev(self): + mntDict = {} + bootDev = None + for entry in self.entries: + mntDict[entry.mountpoint] = entry.device + + # FIXME: this ppc stuff feels kind of crufty -- the abstraction + # here needs a little bit of work + if mntDict.has_key("/boot"): + bootDev = mntDict['/boot'] + elif mntDict.has_key("/"): + bootDev = mntDict['/'] + + return bootDev + + def bootloaderChoices(self, diskSet, bl): + ret = {} + bootDev = self.getBootDev() + + if bootDev is None: + log.warning("no boot device set") + return ret + + if bootDev.getName() == "RAIDDevice": + ret['boot'] = (bootDev.device, N_("RAID Device")) + return ret + + ret['boot'] = (bootDev.device, N_("First sector of boot partition")) + ret['mbr'] = (bl.drivelist[0], N_("Master Boot Record (MBR)")) + return ret + + # set active partition on disks + # if an active partition is set, leave it alone; if none set + # set either our boot partition or the first partition on the drive active + def setActive(self, diskset): + dev = self.getBootDev() + + if dev is None: + return + + bootDev = dev.device + + if dev.getName() != "RAIDDevice": + part = partedUtils.get_partition_by_name(diskset.disks, bootDev) + drive = partedUtils.get_partition_drive(part) + + for drive in diskset.disks.keys(): + foundActive = 0 + bootPart = None + if partedUtils.hasGptLabel(diskset, drive): + continue + disk = diskset.disks[drive] + part = disk.next_partition() + while part: + if not part.is_active(): + part = disk.next_partition(part) + continue + + if not part.is_flag_available(parted.PARTITION_BOOT): + foundActive = 1 + part = None + continue + + if part.get_flag(parted.PARTITION_BOOT): + foundActive = 1 + part = None + continue + + if not bootPart: + bootPart = part + + if partedUtils.get_partition_name(part) == bootDev: + bootPart = part + + part = disk.next_partition(part) + + if bootPart and not foundActive: + bootPart.set_flag(parted.PARTITION_BOOT, 1) + + if bootPart: + del bootPart + + def resizeFilesystems (self, diskset, chroot = '/', shrink = False, grow = False): + todo = [] + for entry in self.entries: + if not entry.fsystem or not entry.fsystem.isResizable(): + continue + if entry.fsystem.isFormattable() and entry.getFormat(): + continue + if entry.resizeTargetSize is None: + continue + if shrink and not (entry.resizeTargetSize < entry.resizeOrigSize): + continue + if grow and not (entry.resizeTargetSize > entry.resizeOrigSize): + continue + todo.append(entry) + if len(todo) == 0: + return + + # we have to have lvm activated to be able to do resizes of LVs + lvmActive = lvm.vgcheckactive() + devicesActive = diskset.devicesOpen + + if not devicesActive: + # should this not be diskset.openDevices() ? + diskset.startMPath() + diskset.startDmRaid() + diskset.startMdRaid() + + if not lvmActive: + lvm.vgscan() + lvm.vgactivate() + + for entry in todo: + entry.fsystem.resize(entry, entry.resizeTargetSize, + self.progressWindow, chroot) + if not lvmActive: + lvm.vgdeactivate() + + if not devicesActive: + # should this not be diskset.closeDevices() ? + diskset.stopMPath() + diskset.stopDmRaid() + diskset.stopMdRaid() + + def shrinkFilesystems (self, diskset, chroot): + self.resizeFilesystems(diskset, chroot, shrink = True) + def growFilesystems (self, diskset, chroot): + self.resizeFilesystems(diskset, chroot, grow = True) + + def formatSwap (self, chroot, forceFormat=False): + formatted = [] + notformatted = [] + + for entry in self.entries: + if (not entry.fsystem or not entry.fsystem.getName() == "swap" or + entry.isMounted()): + continue + if not entry.getFormat(): + if not forceFormat: + notformatted.append(entry) + continue + try: + self.formatEntry(entry, chroot) + formatted.append(entry) + except SystemError: + if self.messageWindow: + self.messageWindow(_("Error"), + _("An error occurred trying to " + "initialize swap on device %s. This " + "problem is serious, and the install " + "cannot continue.\n\n" + "Press <Enter> to exit the installer.") + % (entry.device.getDevice(),)) + sys.exit(0) + + for entry in formatted: + try: + self.labelEntry(entry, chroot) + except SystemError: + # should be OK, fall back to by device + pass + + # find if there's a label on the ones we're not formatting + for entry in notformatted: + dev = entry.device.getDevice() + if not dev or dev == "none": + continue + try: + label = isys.readFSLabel(dev) + except: + continue + if label: + entry.setLabel(label) + + def turnOnSwap (self, chroot, upgrading=False): + def swapErrorDialog (msg, format_button_text, entry): + buttons = [_("Skip"), format_button_text, _("_Exit installer")] + ret = self.messageWindow(_("Error"), msg, type="custom", + custom_buttons=buttons, + custom_icon="warning") + if ret == 0: + self.entries.remove(entry) + elif ret == 1: + self.formatEntry(entry, chroot) + entry.mount(chroot) + self.mountcount = self.mountcount + 1 + else: + sys.exit(0) + + for entry in self.entries: + if (entry.fsystem and entry.fsystem.getName() == "swap" + and not entry.isMounted()): + try: + entry.mount(chroot) + self.mountcount = self.mountcount + 1 + except OldSwapError: + if self.messageWindow: + msg = _("The swap device:\n\n /dev/%s\n\n" + "is a version 0 Linux swap partition. If you " + "want to use this device, you must reformat as " + "a version 1 Linux swap partition. If you skip " + "it, the installer will ignore it during the " + "installation.") % (entry.device.getDevice()) + + swapErrorDialog(msg, _("Reformat"), entry) + except SuspendError: + if self.messageWindow: + if upgrading: + msg = _("The swap device:\n\n /dev/%s\n\n" + "in your /etc/fstab file is currently in " + "use as a software suspend partition, " + "which means your system is hibernating. " + "To perform an upgrade, please shut down " + "your system rather than hibernating it.") \ + % (entry.device.getDevice()) + else: + msg = _("The swap device:\n\n /dev/%s\n\n" + "in your /etc/fstab file is currently in " + "use as a software suspend partition, " + "which means your system is hibernating. " + "If you are performing a new install, " + "make sure the installer is set " + "to format all swap partitions.") \ + % (entry.device.getDevice()) + + # choose your own adventure swap partitions... + msg = msg + _("\n\nChoose Skip if you want the " + "installer to ignore this partition during " + "the upgrade. Choose Format to reformat " + "the partition as swap space.") + + swapErrorDialog(msg, _("Format"), entry) + else: + sys.exit(0) + except SystemError, (num, msg): + if self.messageWindow: + if upgrading and not entry.getLabel(): + err = _("Error enabling swap device %s: %s\n\n" + "Devices in /etc/fstab should be specified " + "by label, not by device name.\n\nPress " + "OK to exit the installer.") % (entry.device.getDevice(), msg) + elif upgrading: + err = _("Error enabling swap device %s: %s\n\n" + "The /etc/fstab on your upgrade partition " + "does not reference a valid swap " + "partition.\n\nPress OK to exit the " + "installer") % (entry.device.getDevice(), msg) + else: + err = _("Error enabling swap device %s: %s\n\n" + "This most likely means this swap " + "partition has not been initialized.\n\n" + "Press OK to exit the installer.") % (entry.device.getDevice(), msg) + + self.messageWindow(_("Error"), err) + sys.exit(0) + + def labelEntry(self, entry, chroot, ignoreExisting = False): + label = entry.device.getLabel() + if label and not ignoreExisting: + entry.setLabel(label) + entry.device.doLabel = 1 + + if entry.device.doLabel is not None: + entry.fsystem.labelDevice(entry, chroot) + + def formatEntry(self, entry, chroot): + if entry.mountpoint: + log.info("formatting %s as %s" %(entry.mountpoint, entry.fsystem.name)) + entry.fsystem.clobberDevice(entry, chroot) + entry.fsystem.formatDevice(entry, self.progressWindow, chroot) + + def getMigratableEntries(self): + retval = [] + for entry in self.entries: + if entry.origfsystem and entry.origfsystem.isMigratable(): + retval.append(entry) + + return retval + + def formattablePartitions(self): + list = [] + for entry in self.entries: + if entry.fsystem.isFormattable(): + list.append (entry) + return list + + def createLogicalVolumes (self, chroot='/'): + vgs = {} + # first set up the volume groups + for entry in self.entries: + if entry.fsystem.name == "volume group (LVM)": + entry.device.setupDevice(chroot) + vgs[entry.device.name] = entry.device + + # then set up the logical volumes + for entry in self.entries: + if isinstance(entry.device, LogicalVolumeDevice): + vg = None + if vgs.has_key(entry.device.vgname): + vg = vgs[entry.device.vgname] + entry.device.setupDevice(chroot, vgdevice = vg) + self.volumesCreated = 1 + + + def makeFilesystems (self, chroot='/', skiprootfs=False): + formatted = [] + notformatted = [] + for entry in self.entries: + if (not entry.fsystem.isFormattable() or not entry.getFormat() + or entry.isMounted()): + notformatted.append(entry) + continue + # FIXME: this is a bit of a hack, but works + if (skiprootfs and entry.mountpoint == '/'): + formatted.append(entry) + continue + try: + self.formatEntry(entry, chroot) + formatted.append(entry) + except SystemError: + if self.messageWindow: + self.messageWindow(_("Error"), + _("An error occurred trying to " + "format %s. This problem is " + "serious, and the install cannot " + "continue.\n\n" + "Press <Enter> to exit the installer.") + % (entry.device.getDevice(),)) + sys.exit(0) + + for entry in formatted: + try: + self.labelEntry(entry, chroot) + except SystemError: + # should be OK, we'll still use the device name to mount. + pass + + # go through and have labels for the ones we don't format + for entry in notformatted: + dev = entry.device.getDevice() + if not dev or dev == "none": + continue + if not entry.mountpoint or entry.mountpoint == "swap": + continue + try: + label = isys.readFSLabel(dev) + except: + continue + if label: + entry.setLabel(label) + else: + self.labelEntry(entry, chroot) + + def haveMigratedFilesystems(self): + return self.migratedfs + + def migrateFilesystems (self, pomona): + if self.migratedfs: + return + + for entry in self.entries: + if not entry.origfsystem: + continue + + if not entry.origfsystem.isMigratable() or not entry.getMigrate(): + continue + try: + entry.origfsystem.migrateFileSystem(entry, self.messageWindow, + pomona.rootPath) + except SystemError: + if self.messageWindow: + self.messageWindow(_("Error"), + _("An error occurred trying to " + "migrate %s. This problem is " + "serious, and the install cannot " + "continue.\n\n" + "Press <Enter> to exit the installer.") + % (entry.device.getDevice(),)) + sys.exit(0) + + # we need to unmount and remount so that we're mounted as the + # new fstype as we want to use the new filesystem type during + # the upgrade for ext3->ext4 migrations + if self.isActive(): + self.umountFilesystems(pomona.rootPath, swapoff = False) + self.mountFilesystems(pomona) + + self.migratedfs = 1 + + def mountFilesystems(self, pomona, raiseErrors = 0, readOnly = 0, skiprootfs = 0): + protected = pomona.id.partitions.protectedPartitions() + + for entry in self.entries: + # Don't try to mount a protected partition, since it will already + # have been mounted as the installation source. + if protected and entry.device.getDevice() in protected and os.path.ismount("/mnt/isodir"): + continue + + if not entry.fsystem.isMountable() or (skiprootfs and entry.mountpoint == '/'): + continue + + try: + log.info("trying to mount %s on %s" %(entry.device.setupDevice(), entry.mountpoint,)) + entry.mount(pomona.rootPath, readOnly = readOnly) + self.mountcount = self.mountcount + 1 + except OSError, (num, msg): + if self.messageWindow: + if num == errno.EEXIST: + self.messageWindow(_("Invalid mount point"), + _("An error occurred when trying " + "to create %s. Some element of " + "this path is not a directory. " + "This is a fatal error and the " + "install cannot continue.\n\n" + "Press <Enter> to exit the " + "installer.") % (entry.mountpoint,)) + else: + self.messageWindow(_("Invalid mount point"), + _("An error occurred when trying " + "to create %s: %s. This is " + "a fatal error and the install " + "cannot continue.\n\n" + "Press <Enter> to exit the " + "installer.") % (entry.mountpoint, + msg)) + log.error("OSError: (%d) %s" % (num, msg) ) + sys.exit(0) + except SystemError, (num, msg): + if raiseErrors: + raise SystemError, (num, msg) + if self.messageWindow: + if not entry.fsystem.isLinuxNativeFS(): + ret = self.messageWindow(_("Unable to mount filesystem"), + _("An error occurred mounting " + "device %s as %s. You may " + "continue installation, but " + "there may be problems.") % + (entry.device.getDevice(), + entry.mountpoint), + type="custom", custom_icon="warning", + custom_buttons=[_("_Exit installer"), + _("_Continue")]) + + if ret == 0: + sys.exit(0) + else: + continue + else: + if pomona.id.getUpgrade() and not (entry.getLabel() or entry.getUuid()): + errStr = _("Error mounting device %s as %s: " + "%s\n\n" + "Devices in /etc/fstab should be specified " + "by label or UUID, not by device name." + "\n\n" + "Press OK to exit the installer.") % (entry.device.getDevice(), entry.mountpoint, msg) + else: + errStr = _("Error mounting device %s as %s: " + "%s\n\n" + "Press OK to exit the installer.") % (entry.device.getDevice(), entry.mountpoint, msg) + + self.messageWindow(_("Error"), errStr) + + log.error("SystemError: (%d) %s" % (num, msg) ) + sys.exit(0) + + self.makeLVMNodes(pomona.rootPath) + + def makeLVMNodes(self, instPath, trylvm1 = 0): + # XXX hack to make the device node exist for the root fs if + # it's a logical volume so that mkinitrd can create the initrd. + root = self.getEntryByMountPoint("/") + if not root: + if self.messageWindow: + self.messageWindow(_("Error"), + _("Error finding / entry.\n\n" + "This is most likely means that " + "your fstab is incorrect." + "\n\n" + "Press OK to exit the installer.")) + sys.exit(0) + + rootlvm1 = 0 + if trylvm1: + dev = root.device.getDevice() + # lvm1 major is 58 + if os.access("%s/dev/%s" %(instPath, dev), os.R_OK) and posix.major(os.stat("%s/dev/%s" %(instPath, dev)).st_rdev) == 58: + rootlvm1 = 1 + + if isinstance(root.device, LogicalVolumeDevice) or rootlvm1: + # now make sure all of the device nodes exist. *sigh* + rc = lvm.vgmknodes() + + rootDev = "/dev/%s" % (root.device.getDevice(),) + rootdir = instPath + os.path.dirname(rootDev) + if not os.path.isdir(rootdir): + os.makedirs(rootdir) + + if root.device.crypto is None: + dmdev = "/dev/mapper/" + root.device.getDevice().replace("-","--").replace("/", "-") + else: + dmdev = "/dev/" + root.device.getDevice() + + if os.path.exists(instPath + dmdev): + os.unlink(instPath + dmdev) + if not os.path.isdir(os.path.dirname(instPath + dmdev)): + os.makedirs(os.path.dirname(instPath + dmdev)) + iutil.copyDeviceNode(dmdev, instPath + dmdev) + + # unlink existing so that we dtrt on upgrades + if os.path.exists(instPath + rootDev) and not root.device.crypto: + os.unlink(instPath + rootDev) + if not os.path.isdir(rootdir): + os.makedirs(rootdir) + + if root.device.crypto is None: + os.symlink(dmdev, instPath + rootDev) + + if not os.path.isdir("%s/etc/lvm" %(instPath,)): + os.makedirs("%s/etc/lvm" %(instPath,)) + + def filesystemSpace(self, chroot='/'): + space = [] + for entry in self.entries: + if not entry.isMounted(): + continue + # we can't put swap files on swap partitions; that's nonsense + if entry.mountpoint == "swap": + continue + path = "%s/%s" % (chroot, entry.mountpoint) + try: + space.append((entry.mountpoint, isys.pathSpaceAvailable(path))) + except SystemError: + log.error("failed to get space available in filesystemSpace() for %s" %(entry.mountpoint,)) + + def spaceSort(a, b): + (m1, s1) = a + (m2, s2) = b + + if (s1 > s2): + return -1 + elif s1 < s2: + return 1 + + return 0 + + space.sort(spaceSort) + return space + + def hasDirtyFilesystems(self, mountpoint): + ret = [] + + for entry in self.entries: + # XXX - multifsify, virtualize isdirty per fstype + if entry.fsystem.getName() != "ext2": continue + if entry.getFormat(): continue + if isinstance(entry.device.getDevice(), BindMountDevice): continue + + try: + if isys.ext2IsDirty(entry.device.getDevice()): + log.info("%s is a dirty ext2 partition" % entry.device.getDevice()) + ret.append(entry.device.getDevice()) + except Exception, e: + log.error("got an exception checking %s for being dirty, hoping it's not" %(entry.device.getDevice(),)) + + return ret + + def umountFilesystems(self, instPath, ignoreErrors = 0, swapoff = True): + # Unmount things bind mounted into the instPath here because they're + # not tracked by self.entries. + if os.path.ismount("%s/dev" % instPath): + isys.umount("%s/dev" % instPath, removeDir=0) + + # take a slice so we don't modify self.entries + reverse = self.entries[:] + reverse.reverse() + + for entry in reverse: + if entry.mountpoint == "swap" and not swapoff: + continue + entry.umount(instPath) + entry.device.cleanupDevice(instPath) + +class FileSystemSetEntry: + def __init__ (self, device, mountpoint, + fsystem=None, options=None, + origfsystem=None, migrate=0, + order=-1, fsck=-1, format=0, + fsprofile=None): + if not fsystem: + fsystem = fileSystemTypeGet("ext2") + self.device = device + self.mountpoint = mountpoint + self.fsystem = fsystem + self.origfsystem = origfsystem + self.migrate = migrate + self.resizeTargetSize = None + self.resizeOrigSize = None + self.options = options + self.mountcount = 0 + self.label = None + if fsck == -1: + self.fsck = fsystem.isChecked() + else: + self.fsck = fsck + if order == -1: + if mountpoint == '/': + self.order = 1 + elif self.fsck: + self.order = 2 + else: + self.order = 0 + else: + self.order = order + if format and not fsystem.isFormattable(): + raise RuntimeError, ("file system type %s is not formattable, " + "but has been added to fsset with format " + "flag on" % fsystem.getName()) + self.format = format + self.fsprofile = fsprofile + + def mount(self, chroot='/', devPrefix='/dev', readOnly = 0): + device = self.device.setupDevice(chroot, devPrefix=devPrefix) + + self.fsystem.mount(device, "%s" % (self.mountpoint,), + readOnly = readOnly, + bindMount = isinstance(self.device, + BindMountDevice), + instroot = chroot) + + self.mountcount = self.mountcount + 1 + + def umount(self, chroot='/'): + if self.mountcount > 0: + try: + self.fsystem.umount(self.device, "%s/%s" % (chroot, + self.mountpoint)) + self.mountcount = self.mountcount - 1 + except RuntimeError: + pass + + def setFileSystemType(self, fstype): + self.fsystem = fstype + + def getMountPoint(self): + return self.mountpoint + + def getOptions(self): + options = self.options + if not options: + options = self.fsystem.getDefaultOptions(self.mountpoint) + return options + self.device.getDeviceOptions() + + def setFormat (self, state): + if self.migrate and state: + raise ValueError, "Trying to set format bit on when migrate is set!" + self.format = state + + def getFormat (self): + return self.format + + def setMigrate (self, state): + if self.format and state: + raise ValueError, "Trying to set migrate bit on when format is set!" + + self.migrate = state + + def getMigrate (self): + return self.migrate + + def setResizeTarget (self, targetsize, size): + if not self.fsystem.isResizable() and targetsize is not None: + raise ValueError, "Can't set a resize target for a non-resizable filesystem" + self.resizeTargetSize = targetsize + self.resizeOrigSize = size + + def getResizeTarget (self): + return self.resizeTargetSize + + def isMounted (self): + return self.mountcount > 0 + + def getLabel (self): + return self.label + + def getUuid (self): + return isys.readFSUuid(self.device.getDevice()) + + def setLabel (self, label): + self.label = label + + def __str__(self): + if not self.mountpoint: + mntpt = "None" + else: + mntpt = self.mountpoint + + str = ("fsentry -- device: %(device)s mountpoint: %(mountpoint)s\n" + " fsystem: %(fsystem)s format: %(format)s\n" + " ismounted: %(mounted)s options: '%(options)s'\n" + " label: %(label)s fsprofile: %(fsprofile)s\n"% + {"device": self.device.getDevice(), "mountpoint": mntpt, + "fsystem": self.fsystem.getName(), "format": self.format, + "mounted": self.mountcount, "options": self.getOptions(), + "label": self.label, "fsprofile": self.fsprofile}) + return str + + +class Device: + def __init__(self, device = "none", encryption=None): + self.device = device + self.label = None + self.isSetup = 0 + self.doLabel = 1 + self.deviceOptions = "" + if encryption: + self.crypto = encryption + # mount by device since the name is based only on UUID + self.doLabel = None + if device not in ("none", None): + self.crypto.setDevice(device) + else: + self.crypto = None + + def getComment (self): + return "" + + def getDevice (self, asBoot = 0): + if self.crypto: + return self.crypto.getDevice() + else: + return self.device + + def setupDevice (self, chroot='/', devPrefix='/dev/'): + return self.device + + def cleanupDevice (self, chroot, devPrefix='/dev/'): + if self.crypto: + self.crypto.closeDevice() + + def solidify (self): + pass + + def getName(self): + return self.__class__.__name__ + + def getLabel(self): + try: + return isys.readFSLabel(self.setupDevice()) + except: + return "" + + def setAsNetdev(self): + """Ensure we're set up so that _netdev is in our device options.""" + if "_netdev" not in self.deviceOptions: + self.deviceOptions += ",_netdev" + + def isNetdev(self): + """Check to see if we're set as a netdev""" + if "_netdev" in self.deviceOptions: + return True + return False + + def getDeviceOptions(self): + return self.deviceOptions + +class DevDevice(Device): + """Device with a device node rooted in /dev that we just always use + the pre-created device node for.""" + def __init__(self, dev): + Device.__init__(self, device=dev) + + def getDevice(self, asBoot = 0): + return self.device + + def setupDevice(self, chroot='/', devPrefix='/dev'): + #We use precreated device but we have to make sure that the device exists + path = '/dev/%s' % (self.getDevice(),) + return path + +class RAIDDevice(Device): + # XXX usedMajors does not take in account any EXISTING md device + # on the system for installs. We need to examine all partitions + # to investigate which minors are really available. + usedMajors = {} + + # members is a list of Device based instances that will be + # a part of this raid device + def __init__(self, level, members, minor=-1, spares=0, existing=0, + chunksize = 64, encryption=None): + Device.__init__(self, encryption=encryption) + self.level = level + self.members = members + self.spares = spares + self.numDisks = len(members) - spares + self.isSetup = existing + self.doLabel = None + if chunksize is not None: + self.chunksize = chunksize + else: + self.chunksize = 256 + + if len(members) < spares: + raise RuntimeError, ("you requested more spare devices " + "than online devices!") + + if level == 5: + if self.numDisks < 3: + raise RuntimeError, "RAID 5 requires at least 3 online members" + + # there are 32 major md devices, 0...31 + if minor == -1 or minor is None: + for I in range(32): + if not RAIDDevice.usedMajors.has_key(I): + minor = I + break + + if minor == -1: + raise RuntimeError, ("Unable to allocate minor number for " + "raid device") + + RAIDDevice.usedMajors[minor] = None + self.device = "md" + str(minor) + self.minor = minor + + if self.crypto: + self.crypto.setDevice(self.device) + + # make sure the list of raid members is sorted + self.members.sort(cmp=lambda x,y: cmp(x.getDevice(),y.getDevice())) + + def __del__ (self): + del RAIDDevice.usedMajors[self.minor] + + def ext2Args (self): + if self.level == 5: + return [ '-R', 'stride=%d' % ((self.numDisks - 1) * 16) ] + elif self.level == 0: + return [ '-R', 'stride=%d' % (self.numDisks * 16) ] + return [] + + def mdadmLine (self, devPrefix="/dev"): + levels = { 0: "raid0", + 1: "raid1", + 4: "raid5", + 5: "raid5", + 6: "raid6", + 10: "raid10" } + + # If we can't find the device for some reason, revert to old behavior. + try: + (dev, devices, level, numActive) = raid.lookup_raid_device (self.device) + except KeyError: + devices = [] + + # First loop over all the devices that make up the RAID trying to read + # the superblock off each. If we read a superblock, return a line that + # can go into the mdadm.conf. If we fail, fall back to the old method + # of using the super-minor. + for d in devices: + try: + (major, minor, uuid, level, nrDisks, totalDisks, mdMinor) = \ + isys.raidsb(d) + return "ARRAY %s/%s level=%s num-devices=%d uuid=%s\n" \ + %(devPrefix, self.device, levels[level], nrDisks, uuid) + except ValueError: + pass + + return "ARRAY %s/%s super-minor=%s\n" %(devPrefix, self.device, + self.minor) + + def raidTab (self, devPrefix='/dev'): + entry = "" + entry = entry + "raiddev %s/%s\n" % (devPrefix, + self.device,) + entry = entry + "raid-level %d\n" % (self.level,) + entry = entry + "nr-raid-disks %d\n" % (self.numDisks,) + entry = entry + "chunk-size %s\n" %(self.chunksize,) + entry = entry + "persistent-superblock 1\n" + entry = entry + "nr-spare-disks %d\n" % (self.spares,) + i = 0 + for device in [m.getDevice() for m in self.members[:self.numDisks]]: + entry = entry + " device %s/%s\n" % (devPrefix, + device) + entry = entry + " raid-disk %d\n" % (i,) + i = i + 1 + i = 0 + for device in [m.getDevice() for m in self.members[self.numDisks:]]: + entry = entry + " device %s/%s\n" % (devPrefix, + device) + entry = entry + " spare-disk %d\n" % (i,) + i = i + 1 + return entry + + def setupDevice (self, chroot="/", devPrefix='/dev'): + if not self.isSetup: + memberDevs = [] + for pd in self.members: + memberDevs.append(pd.setupDevice(chroot, devPrefix=devPrefix)) + if pd.isNetdev(): self.setAsNetdev() + + args = ["--create", "/dev/%s" %(self.device,), + "--run", "--chunk=%s" %(self.chunksize,), + "--level=%s" %(self.level,), + "--raid-devices=%s" %(self.numDisks,)] + + if self.spares > 0: + args.append("--spare-devices=%s" %(self.spares,),) + + args.extend(memberDevs) + log.info("going to run: %s" %(["mdadm"] + args,)) + iutil.execWithRedirect ("mdadm", args, + stderr="/dev/tty5", stdout="/dev/tty5", + searchPath = 1) + raid.register_raid_device(self.device, + [m.getDevice() for m in self.members], + self.level, self.numDisks) + self.isSetup = 1 + else: + isys.raidstart(self.device, self.members[0].getDevice()) + + if self.crypto: + self.crypto.formatDevice() + self.crypto.openDevice() + node = "%s/%s" % (devPrefix, self.crypto.getDevice()) + else: + node = "%s/%s" % (devPrefix, self.device) + + return node + + def getDevice (self, asBoot = 0): + if not asBoot and self.crypto: + return self.crypto.getDevice() + elif not asBoot: + return self.device + else: + return self.members[0].getDevice(asBoot=asBoot) + + def solidify(self): + return + +ext2 = fileSystemTypeGet("ext2") +ext2.registerDeviceArgumentFunction(RAIDDevice, RAIDDevice.ext2Args) + +class VolumeGroupDevice(Device): + def __init__(self, name, physvols, pesize = 32768, existing = 0): + """Creates a VolumeGroupDevice. + + name is the name of the volume group + physvols is a list of Device objects which are the physical volumes + pesize is the size of physical extents in kilobytes + existing is whether this vg previously existed. + """ + + Device.__init__(self) + self.physicalVolumes = physvols + self.isSetup = existing + self.name = name + self.device = name + self.isSetup = existing + + self.physicalextentsize = pesize + + def setupDevice (self, chroot="/", devPrefix='/dev/'): + nodes = [] + for volume in self.physicalVolumes: + # XXX the lvm tools are broken and will only work for /dev + node = volume.setupDevice(chroot, devPrefix="/dev") + if volume.isNetdev(): self.setAsNetdev() + + # XXX I should check if the pv is set up somehow so that we + # can have preexisting vgs and add new pvs to them. + if not self.isSetup: + lvm.pvcreate(node) + nodes.append(node) + + if not self.isSetup: + lvm.vgcreate(self.name, self.physicalextentsize, nodes) + self.isSetup = 1 + else: + lvm.vgscan() + lvm.vgactivate() + + return "/dev/%s" % (self.name,) + + def solidify(self): + return + +class LogicalVolumeDevice(Device): + # note that size is in megabytes! + def __init__(self, vgname, size, lvname, vg, existing = 0, encryption=None): + Device.__init__(self, encryption=encryption) + self.vgname = vgname + self.size = size + self.name = lvname + self.isSetup = 0 + self.isSetup = existing + self.doLabel = None + self.vg = vg + + # these are attributes we might want to expose. or maybe not. + # self.chunksize + # self.stripes + # self.stripesize + # self.extents + # self.readaheadsectors + + def setupDevice(self, chroot="/", devPrefix='/dev', vgdevice = None): + if self.crypto: + self.crypto.setDevice("mapper/%s-%s" % (self.vgname, self.name)) + + if not self.isSetup: + lvm.lvcreate(self.name, self.vgname, self.size) + self.isSetup = 1 + + if vgdevice and vgdevice.isNetdev(): + self.setAsNetdev() + + if self.crypto: + self.crypto.formatDevice() + self.crypto.openDevice() + + return "/dev/%s" % (self.getDevice(),) + + def getDevice(self, asBoot = 0): + if self.crypto and not asBoot: + device = self.crypto.getDevice() + else: + device = "%s/%s" % (self.vgname, self.name) + + return device + + def solidify(self): + return + + +class PartitionDevice(Device): + def __init__(self, partition, encryption=None): + if type(partition) != types.StringType: + raise ValueError, "partition must be a string" + Device.__init__(self, device=partition, encryption=encryption) + + (disk, pnum) = getDiskPart(partition) + + def getDevice(self, asBoot = 0): + if self.crypto and not asBoot: + return self.crypto.getDevice() + else: + return self.device + + def setupDevice(self, chroot="/", devPrefix='/dev'): + path = '%s/%s' % (devPrefix, self.device) + if self.crypto: + self.crypto.formatDevice() + self.crypto.openDevice() + path = "%s/%s" % (devPrefix, self.crypto.getDevice()) + return path + +class PartedPartitionDevice(PartitionDevice): + def __init__(self, partition): + Device.__init__(self) + self.device = None + self.partition = partition + + def getDevice(self, asBoot = 0): + if not self.partition: + return self.device + + return partedUtils.get_partition_name(self.partition) + + def solidify(self): + # drop reference on the parted partition object and note + # the current minor number allocation + self.device = self.getDevice() + self.partition = None + +class BindMountDevice(Device): + def __init__(self, directory): + Device.__init__(self) + self.device = directory + + def setupDevice(self, chroot="/", devPrefix="/tmp"): + return chroot + self.device + +class SwapFileDevice(Device): + def __init__(self, file): + Device.__init__(self) + self.device = file + self.size = 0 + + def setSize (self, size): + self.size = size + + def setupDevice (self, chroot="/", devPrefix='/dev'): + file = os.path.normpath(chroot + self.getDevice()) + if not os.access(file, os.R_OK): + if self.size: + # make sure the permissions are set properly + fd = os.open(file, os.O_CREAT, 0600) + os.close(fd) + isys.ddfile(file, self.size, None) + else: + raise SystemError, (0, "swap file creation necessary, but " + "required size is unknown.") + return file + +# This is a device that describes a swap file that is sitting on +# the loopback filesystem host for partitionless installs. +# The piggypath is the place where the loopback file host filesystem +# will be mounted +class PiggybackSwapFileDevice(SwapFileDevice): + def __init__(self, piggypath, file): + SwapFileDevice.__init__(self, file) + self.piggypath = piggypath + + def setupDevice(self, chroot="/", devPrefix='/dev'): + return SwapFileDevice.setupDevice(self, self.piggypath, devPrefix) + +class LoopbackDevice(Device): + def __init__(self, hostPartition, hostFs): + Device.__init__(self) + self.host = "/dev/" + hostPartition + self.hostfs = hostFs + self.device = "loop1" + + def setupDevice(self, chroot="/", devPrefix='/dev/'): + if not self.isSetup: + isys.mount(self.host[5:], "/mnt/loophost", fstype = "vfat") + self.device = allocateLoopback("/mnt/loophost/redhat.img") + if not self.device: + raise SystemError, "Unable to allocate loopback device" + self.isSetup = 1 + path = '%s/%s' % (devPrefix, self.getDevice()) + else: + path = '%s/%s' % (devPrefix, self.getDevice()) + path = os.path.normpath(path) + return path + + def getComment (self): + return "# LOOP1: %s %s /redhat.img\n" % (self.host, self.hostfs) + +def makeDevice(dev): + cryptoDev = partitions.lookup_cryptodev(dev) + if cryptoDev and cryptoDev.getDevice() == dev: + dev = cryptoDev.getDevice(encrypted=True) + + if dev.startswith('md'): + try: + (mdname, devices, level, numActive) = raid.lookup_raid_device(dev) + # convert devices to Device instances and sort out encryption + devList = [] + for dev in devices: + cryptoMem = partitions.lookup_cryptodev(dev) + if cryptoMem and cryptoMem.getDevice() == dev: + dev = cryptoMem.getDevice(encrypted=True) + + devList.append(PartitionDevice(dev, encryption=cryptoMem)) + + device = RAIDDevice(level, devList, + minor=int(mdname[2:]), + spares=len(devices) - numActive, + existing=1, encryption=cryptoDev) + except KeyError: + device = PartitionDevice(dev, encryption=cryptoDev) + else: + device = PartitionDevice(dev, encryption=cryptoDev) + return device + +# XXX fix RAID +def readFstab(pomona): + def createMapping(dict): + mapping = {} + dupes = [] + + for device, info in dict.items(): + if not mapping.has_key(info): + mapping[info] = device + elif not info in dupes: + dupes.append(info) + + return (mapping, dupes) + + def showError(label, intf): + if intf: + intf.messageWindow(_("Duplicate Labels"), + _("Multiple devices on your system are " + "labelled %s. Labels across devices must be " + "unique for your system to function " + "properly.\n\n" + "Please fix this problem and restart the " + "installation process.") %(label,), + type="custom", custom_icon="error", + custom_buttons=[_("_Exit installer")]) + sys.exit(0) + else: + log.warning("Duplicate labels for %s, but no intf so trying " + "to continue" %(label,)) + + path = pomona.rootPath + '/etc/fstab' + intf = pomona.intf + fsset = FileSystemSet() + + # first, we look at all the disks on the systems and get any ext2/3 + # labels off of the filesystem. + # temporary, to get the labels + diskset = partedUtils.DiskSet(pomona) + diskset.openDevices() + labels = diskset.getInfo() + uuids = diskset.getInfo(readFn=lambda d: isys.readFSUuid(d)) + + (labelToDevice, labelDupes) = createMapping(labels) + (uuidToDevice, uuidDupes) = createMapping(uuids) + + loopIndex = {} + + f = open (path, "r") + lines = f.readlines () + f.close() + + for line in lines: + fields = string.split (line) + + if not fields: continue + + if line[0] == "#": + # skip all comments + continue + + # all valid fstab entries have 6 fields; if the last two are missing + # they are assumed to be zero per fstab(5) + if len(fields) < 4: + continue + elif len(fields) == 4: + fields.append(0) + fields.append(0) + elif len(fields) == 5: + fields.append(0) + elif len(fields) > 6: + continue + if string.find(fields[3], "noauto") != -1: continue + + # shenanigans to handle ext3,ext2 format in fstab + fstotry = fields[2] + if fstotry.find(","): + fstotry = fstotry.split(",") + else: + fstotry = [ fstotry ] + fsystem = None + for fs in fstotry: + # if we don't support mounting the filesystem, continue + if not fileSystemTypes.has_key(fs): + continue + fsystem = fileSystemTypeGet(fs) + break + # "none" is valid as an fs type for bind mounts (#151458) + if fsystem is None and (string.find(fields[3], "bind") == -1): + continue + + label = None + if fields[0] == "none": + device = Device() + elif ((string.find(fields[3], "bind") != -1) and + fields[0].startswith("/")): + # it's a bind mount, they're Weird (tm) + device = BindMountDevice(fields[0]) + fsystem = fileSystemTypeGet("bind") + elif len(fields) >= 6 and fields[0].startswith('LABEL='): + label = fields[0][6:] + if label in labelDupes: + showError(label, intf) + + if labelToDevice.has_key(label): + device = makeDevice(labelToDevice[label]) + else: + log.warning ("fstab file has LABEL=%s, but this label " + "could not be found on any file system", label) + # bad luck, skip this entry. + continue + elif len(fields) >= 6 and fields[0].startswith('UUID='): + uuid = fields[0][5:] + if uuid in uuidDupes: + showError(uuid, intf) + + if uuidToDevice.has_key(uuid): + device = makeDevice(uuidToDevice[uuid]) + else: + log.warning ("fstab file has UUID=%s, but this UUID" + "could not be found on any file system", uuid) + # bad luck, skip this entry. + continue + elif fields[2] == "swap" and not fields[0].startswith('/dev/'): + # swap files + file = fields[0] + + if file.startswith('/initrd/loopfs/'): + file = file[14:] + device = PiggybackSwapFileDevice("/mnt/loophost", file) + else: + device = SwapFileDevice(file) + elif fields[0].startswith('/dev/loop'): + # look up this loop device in the index to find the + # partition that houses the filesystem image + # XXX currently we assume /dev/loop1 + if loopIndex.has_key(device): + (dev, fs) = loopIndex[device] + device = LoopbackDevice(dev, fs) + elif fields[0].startswith('/dev/'): + # Older installs may have lines starting with things like /dev/proc + # so watch out for that on upgrade. + if fsystem is not None and isinstance(fsystem, PseudoFileSystem): + device = Device(device = fields[0][5:]) + else: + device = makeDevice(fields[0][5:]) + else: + device = Device(device = fields[0]) + + # if they have a filesystem being mounted as auto, we need + # to sniff around a bit to figure out what it might be + # if we fail at all, though, just ignore it + if fsystem == "auto" and device.getDevice() != "none": + try: + tmp = partedUtils.sniffFilesystemType("/dev/%s" %(device.setupDevice(),)) + if tmp is not None: + fsystem = tmp + except: + pass + + entry = FileSystemSetEntry(device, fields[1], fsystem, fields[3], + origfsystem=fsystem) + if label: + entry.setLabel(label) + fsset.add(entry) + return fsset + +def allocateLoopback(file): + found = 1 + for i in range(8): + path = "/dev/loop%d" % (i,) + try: + isys.losetup(path, file) + found = 1 + except SystemError: + continue + break + if found: + return path + return None + +def ext2FormatFilesystem(argList, messageFile, windowCreator, mntpoint): + if windowCreator: + w = windowCreator(_("Formatting"), + _("Formatting %s file system...") % (mntpoint,), 100) + else: + w = None + + fd = os.open(messageFile, os.O_RDWR | os.O_CREAT | os.O_APPEND) + p = os.pipe() + childpid = os.fork() + if not childpid: + os.close(p[0]) + os.dup2(p[1], 1) + os.dup2(fd, 2) + os.close(p[1]) + os.close(fd) + + env = os.environ + configs = [ "/tmp/updates/mke2fs.conf", + "/etc/mke2fs.conf", + ] + for config in configs: + if os.access(config, os.R_OK): + env['MKE2FS_CONFIG'] = config + break + + os.execvpe(argList[0], argList, env) + log.critical("failed to exec %s", argList) + os._exit(1) + + os.close(p[1]) + + # ignoring SIGCHLD would be cleaner then ignoring EINTR, but + # we can't use signal() in this thread? + + s = 'a' + while s and s != '\b': + try: + s = os.read(p[0], 1) + except OSError, args: + (num, str) = args + if (num != 4): + raise IOError, args + + os.write(fd, s) + + num = '' + while s: + try: + s = os.read(p[0], 1) + os.write(fd, s) + + if s != '\b': + try: + num = num + s + except: + pass + else: + if num and len(num): + l = string.split(num, '/') + try: + val = (int(l[0]) * 100) / int(l[1]) + except (IndexError, TypeError): + pass + else: + w and w.set(val) + num = '' + except OSError, args: + (errno, str) = args + if (errno != 4): + raise IOError, args + + try: + (pid, status) = os.waitpid(childpid, 0) + except OSError, (num, msg): + log.critical("exception from waitpid while formatting: %s %s" %(num, msg)) + status = None + os.close(fd) + + w and w.pop() + + # *shrug* no clue why this would happen, but hope that things are fine + if status is None: + return 0 + + if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0): + return 0 + + return 1 + +# copy and paste job from booty/bootloaderInfo.py... +def getDiskPart(dev): + cut = len(dev) + if (dev.startswith('rd/') or dev.startswith('ida/') or + dev.startswith('cciss/') or dev.startswith('sx8/') or + dev.startswith('mapper/') or dev.startswith('mmcblk')): + if dev[-2] == 'p': + cut = -1 + elif dev[-3] == 'p': + cut = -2 + else: + if dev[-2] in string.digits: + cut = -2 + elif dev[-1] in string.digits: + cut = -1 + + name = dev[:cut] + + # hack off the trailing 'p' from /dev/cciss/*, for example + if name[-1] == 'p': + for letter in name: + if letter not in string.letters and letter != "/": + name = name[:-1] + break + + if cut < 0: + partNum = int(dev[cut:]) - 1 + else: + partNum = None + + return (name, partNum) diff --git a/pkgs/core/pomona/src/installer.py b/pkgs/core/pomona/src/installer.py new file mode 100644 index 0000000..89230eb --- /dev/null +++ b/pkgs/core/pomona/src/installer.py @@ -0,0 +1,291 @@ +#!/usr/bin/python +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +import os +import sys +import re +import signal +import warnings +from optparse import OptionParser + +import isys +import users +import iutil +import dispatch +from flags import flags +from constants import * + +from tui import InstallInterface +from pakfireinstall import PakfireBackend +from instdata import InstallData +from autopart import getAutopartitionBoot, autoCreatePartitionRequests + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +# Make sure messages sent through python's warnings module get logged. +def PomonaShowWarning(message, category, filename, lineno, file=sys.stderr): + log.warning("%s" % warnings.formatwarning(message, category, filename, lineno)) + +warnings.showwarning = PomonaShowWarning + +def parseOptions(): + + op = OptionParser() + + # Method of operation + op.add_option("-d", "--debug", dest="debug", action="store_true", default=False) + op.add_option("--expert", action="store_true", default=False) + op.add_option("-t", "--test", action="store_true", default=False) + + op.add_option("-m", "--method", default=None) + + # Language + op.add_option("--keymap") + op.add_option("--kbdtype") + op.add_option("--lang") + + # Obvious + op.add_option("--loglevel") + op.add_option("--syslog") + + return op.parse_args() + +def setupLoggingFromOpts(opts): + if opts.loglevel and logLevelMap.has_key(opts.loglevel): + log.setHandlersLevel(logLevelMap[opts.loglevel]) + + if opts.syslog: + if opts.syslog.find(":") != -1: + (host, port) = opts.syslog.split(":") + logger.addSysLogHandler(log, host, port=int(port)) + else: + logger.addSysLogHandler(log, opts.syslog) + +def checkMemory(): + if iutil.memInstalled() < isys.MIN_RAM: + from snack import SnackScreen, ButtonChoiceWindow + + screen = SnackScreen() + ButtonChoiceWindow(screen, _("Fatal Error"), + _("You do not have enough RAM to install %s " + "on this machine.\n" + "\n" + "Press <return> to reboot your system.\n") + % (name,), buttons = (_("OK"),)) + screen.finish() + sys.exit(0) + +class Pomona: + def __init__(self): + self.intf = None + self.id = None + self.rootPath = HARDDISK_PATH + self.dispatch = dispatch.Dispatcher(self) + + self.backend = PakfireBackend(self.rootPath) + + def setDefaultPartitioning(self, partitions, clear = CLEARPART_TYPE_ALL, doClear = 1): + autorequests = [ ("/", None, 1024, None, 1, 1, 1) ] + + bootreq = getAutopartitionBoot() + if bootreq: + autorequests.extend(bootreq) + + (minswap, maxswap) = iutil.swapSuggestion() + autorequests.append((None, "swap", minswap, maxswap, 1, 1, 1)) + + if doClear: + partitions.autoClearPartType = clear + partitions.autoClearPartDrives = [] + + partitions.autoPartitionRequests = autoCreatePartitionRequests(autorequests) + + def setZeroMbr(self, zeroMbr): + self.id.partitions.zeroMbr = zeroMbr + + def setKeyboard(self, kb): + self.id.console.setKeymap(kb) + + def setTimezoneInfo(self, timezone, asUtc = 0, asArc = 0): + self.id.timezone.setTimezoneInfo(timezone, asUtc, asArc) + + def setLanguage(self, lang): + self.id.console.setLanguage(lang) + +if __name__ == "__main__": + pomona = Pomona() + + # Set up logging + import logging + from pomona_log import logger, logLevelMap + + log = logging.getLogger("pomona") + stdoutLog = logging.getLogger("pomona.stdout") + if os.access("/dev/tty3", os.W_OK): + logger.addFileHandler("/dev/tty3", log) + + log.info("pomona called with cmdline = %s" %(sys.argv,)) + + # Set up environment + if not os.environ.has_key("LANG"): + os.environ["LANG"] = "en_US.UTF-8" + os.environ['HOME'] = '/tmp' + os.environ['LC_NUMERIC'] = 'C' + + signal.signal(signal.SIGINT, signal.SIG_DFL) + signal.signal(signal.SIGSEGV, isys.handleSegv) + + # Reading command line options + (opts, args) = parseOptions() + + setupLoggingFromOpts(opts) + + if opts.expert: + flags.expert = 1 + + if opts.test: + flags.test = 1 + + if opts.debug: + flags.debug = True + import pdb + pdb.set_trace() + + log.info (_("Starting text installation...")) + + checkMemory() + + pomona.intf = InstallInterface() + + pomona.id = InstallData(pomona) + pomona.id.reset(pomona) + pomona.setDefaultPartitioning(pomona.id.partitions, CLEARPART_TYPE_ALL) + + if flags.expert: + pomona.dispatch.setStepList( + "language", + "keyboard", + "welcome", + "betanag", + "installtype", + "partitionobjinit", + "parttype", + "autopartitionexecute", + "partition", + "partitiondone", + "bootloadersetup", + "bootloader", + "networkdevicecheck", + "network", + "timezone", + "accounts", + "reposetup", + "basepkgsel", + "tasksel", + "postselection", + "confirminstall", + "install", + "enablefilesystems", + "migratefilesystems", + "setuptime", + "preinstallconfig", + "installpackages", + "postinstallconfig", + "writeconfig", + "firstboot", + "instbootloader", + "dopostaction", + "postscripts", + "writexconfig", + "writeksconfig", + "writeregkey", + "methodcomplete", + "copylogs", + "setfilecon", + "complete" + ) + else: + pomona.dispatch.setStepList( + "language", + "keyboard", + "welcome", + "betanag", + "installtype", + "partitionobjinit", + "parttype", + "autopartitionexecute", + "partition", + "partitiondone", + "bootloadersetup", + "bootloader", + "networkdevicecheck", + "network", + "timezone", + "accounts", + "reposetup", + "basepkgsel", + "tasksel", + "postselection", + "confirminstall", + "install", + "enablefilesystems", + "migratefilesystems", + "setuptime", + "preinstallconfig", + "installpackages", + "postinstallconfig", + "writeconfig", + "firstboot", + "instbootloader", + "dopostaction", + "postscripts", + "writexconfig", + "writeksconfig", + "writeregkey", + "methodcomplete", + "copylogs", + "setfilecon", + "complete" + ) + + users.createLuserConf(pomona.rootPath) + + if opts.lang: + pomona.dispatch.skipStep("language", permanent = 1) + pomona.setLanguage(opts.lang) + pomona.id.timezone.setTimezoneInfo(pomona.id.console.getDefaultTimeZone()) + + if opts.keymap: + pomona.dispatch.skipStep("keyboard", permanent = 1) + pomona.setKeyboard(opts.keymap) + + from exception import handleException + sys.excepthook = lambda type, value, tb, pomona=pomona: handleException(pomona, (type, value, tb)) + + try: + pomona.intf.run(pomona) + except SystemExit, code: + pomona.intf.shutdown() + except: + handleException(pomona, sys.exc_info()) + + del pomona.intf diff --git a/pkgs/core/pomona/src/instdata.py b/pkgs/core/pomona/src/instdata.py new file mode 100644 index 0000000..d1762e7 --- /dev/null +++ b/pkgs/core/pomona/src/instdata.py @@ -0,0 +1,65 @@ +# +# instdata.py - central store for all configuration data needed to install +# +# Erik Troan <ewt@redhat.com> +# +# Copyright 2001-2002 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# library public license. +# +# You should have received a copy of the GNU Library Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import os +import string +import console +import network +import timezone +import fsset +import bootloader +import partitions +import partedUtils +import users +from flags import * +from constants import * + +import logging +log = logging.getLogger("pomona") + +# Collector class for all data related to an install. + +class InstallData: + def reset(self, pomona): + # Reset everything except the console settings (language, keyboard) + + self.network = network.Network(pomona.rootPath + "/etc/sysconfig/network") + self.timezone = timezone.Timezone() + self.timezone.setTimezoneInfo(self.console.getDefaultTimeZone()) + self.users = None + self.rootPassword = { "password": "" } + self.fsset.reset() + self.diskset = partedUtils.DiskSet(pomona) + self.partitions = partitions.Partitions(pomona) + self.bootloader = bootloader.getBootloader() + self.rootParts = None + + def setInstallProgressClass(self, c): + self.instProgress = c + + def write(self, pomona): + self.console.write() + self.timezone.write(pomona.rootPath) + self.network.write() + + self.users = users.Users() + + # User should already exist, just without a password. + self.users.setRootPassword(self.rootPassword["password"], algo="sha512") + + def __init__(self, pomona): + self.console = console.Console(pomona.rootPath + "/etc/sysconfig/console") + self.fsset = fsset.FileSystemSet() + self.reset(pomona) diff --git a/pkgs/core/pomona/src/isys/Makefile b/pkgs/core/pomona/src/isys/Makefile new file mode 100644 index 0000000..e462c0f --- /dev/null +++ b/pkgs/core/pomona/src/isys/Makefile @@ -0,0 +1,61 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +# # +############################################################################### + +include ../Makefile.inc + +CFLAGS += -I$(PYTHONINCLUDE) -I/usr/include -I.. -I. + +OBJECTS = devices.o imount.o smp.o linkdetect.o \ + lang.o isofs.o vio.o eddsupport.o str.o \ + wireless.o ethtool.o + +SOBJECTS = $(patsubst %.o,%.lo,$(OBJECTS)) +SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) isys.c +LOADLIBES = -lpci -lpopt -lext2fs -lz -lpci -lblkid +PYMODULES = _isys.so + +all: depend $(PYMODULES) libisys.a + +%.lo: %.c + $(CC) -c $(CFLAGS) -fPIC -o $@ $< + +_isys.so: isys.lo $(SOBJECTS) + $(CC) -shared -g -fPIC -o $@ isys.lo $(SOBJECTS) $(LOADLIBES) $(LDFLAGS) + +libisys.a: libisys.a($(OBJECTS)) + +filtertest: filtertest.o libisys.a + +clean: + rm -f *.o *.so *.lo *.a *.pyc $(TARGET) $(SOBJECTS) + rm -f $(OBJECTS) + rm -f depend + +install: all + -mkdir -p $(PYTHONLIBDIR) + install -s $(PYMODULES) $(PYTHONLIBDIR) + install -m 644 isys.py $(PYTHONLIBDIR) + +depend: + $(CPP) -M $(CFLAGS) $(SOURCES) > depend + +ifeq (depend,$(wildcard depend)) +include depend +endif diff --git a/pkgs/core/pomona/src/isys/devices.c b/pkgs/core/pomona/src/isys/devices.c new file mode 100644 index 0000000..69a0020 --- /dev/null +++ b/pkgs/core/pomona/src/isys/devices.c @@ -0,0 +1,171 @@ +/* + * devices.c - various hardware probing functionality + * + * Copyright (C) 2007 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Bill Nottingham <notting@redhat.com> + */ + +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> + +#include "devices.h" + +/* for 'disks', to filter out weird stuff */ +#define MINIMUM_INTERESTING_SIZE 32*1024 /* 32MB */ + +/* from genhd.h, kernel side */ +#define GENHD_FL_REMOVABLE 1 +#define GENHD_FL_DRIVERFS 2 +#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4 +#define GENHD_FL_CD 8 +#define GENHD_FL_UP 16 +#define GENHD_FL_SUPPRESS_PARTITION_INFO 32 +#define GENHD_FL_FAIL 64 + + +struct device **getDevices(enum deviceType type) { + struct device **ret = NULL; + struct device *new; + int numdevices = 0; + int rc; + + if (type & (DEVICE_DISK | DEVICE_CDROM)) { + DIR *dir; + struct dirent *ent; + + dir = opendir("/sys/block"); + + if (!dir) goto storagedone; + + while ((ent = readdir(dir))) { + char path[64]; + char buf[64]; + int fd, caps, devtype; + + snprintf(path, 64, "/sys/block/%s/capability", ent->d_name); + fd = open(path, O_RDONLY); + if (fd == -1) + continue; + if (read(fd, buf, 64) <= 0) { + close(fd); + continue; + } + close(fd); + caps = strtol(buf, NULL, 16); + if (caps & GENHD_FL_CD) + devtype = DEVICE_CDROM; + else + devtype = DEVICE_DISK; + if (!(devtype & type)) + continue; + + if (devtype == DEVICE_DISK && !(caps & GENHD_FL_REMOVABLE)) { + int size; + + snprintf(path, 64, "/sys/block/%s/size", ent->d_name); + fd = open(path, O_RDONLY); + if (fd == -1) + continue; + if (read(fd, buf, 64) <= 0) { + close(fd); + continue; + } + close(fd); + size = atoi(buf); + if (size < MINIMUM_INTERESTING_SIZE) + continue; + } + + new = calloc(1, sizeof(struct device)); + new->device = strdup(ent->d_name); + /* FIXME */ + rc = asprintf(&new->description,"Storage device %s",new->device); + new->type = devtype; + if (caps & GENHD_FL_REMOVABLE) { + new->priv.removable = 1; + } + ret = realloc(ret, (numdevices+2) * sizeof(struct device)); + ret[numdevices] = new; + ret[numdevices+1] = NULL; + numdevices++; + } + } +storagedone: + + if (type & DEVICE_NETWORK) { + DIR *dir; + struct dirent *ent; + + dir = opendir("/sys/class/net"); + + if (!dir) goto netdone; + + while ((ent = readdir(dir))) { + char path[64]; + int fd, type; + char buf[64]; + + snprintf(path, 64, "/sys/class/net/%s/type", ent->d_name); + fd = open(path, O_RDONLY); + if (fd == -1) + continue; + if (read(fd, buf, 64) <= 0) { + close(fd); + continue; + } + close(fd); + type = atoi(buf); + if (type != 1) + continue; + + new = calloc(1, sizeof(struct device)); + new->device = strdup(ent->d_name); + /* FIXME */ + snprintf(path, 64, "/sys/class/net/%s/address", ent->d_name); + fd = open(path, O_RDONLY); + if (fd != -1) { + if (read(fd, buf, 64) > 0) { + int i; + for (i = (strlen(buf)-1); isspace(buf[i]); i--) buf[i] = '\0'; + new->priv.hwaddr = strdup(buf); + } + } + + if (new->priv.hwaddr) + rc = asprintf(&new->description, "Ethernet device %s - %s", + new->device, new->priv.hwaddr); + else + rc = asprintf(&new->description, "Ethernet device %s", new->device); + + ret = realloc(ret, (numdevices+2) * sizeof(struct device)); + ret[numdevices] = new; + ret[numdevices+1] = NULL; + numdevices++; + } + } +netdone: + return ret; +} + diff --git a/pkgs/core/pomona/src/isys/devices.h b/pkgs/core/pomona/src/isys/devices.h new file mode 100644 index 0000000..9428a77 --- /dev/null +++ b/pkgs/core/pomona/src/isys/devices.h @@ -0,0 +1,42 @@ +/* + * devices.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DEVICES_H +#define DEVICES_H + +enum deviceType { + DEVICE_ANY = ~0, + DEVICE_NETWORK = (1 << 0), + DEVICE_DISK = (1 << 1), + DEVICE_CDROM = (1 << 2) +}; + +struct device { + char *device; + char *description; + enum deviceType type; + union { + char *hwaddr; + int removable; + } priv; +}; + +struct device **getDevices(enum deviceType type); + +#endif diff --git a/pkgs/core/pomona/src/isys/eddsupport.c b/pkgs/core/pomona/src/isys/eddsupport.c new file mode 100644 index 0000000..9fb38af --- /dev/null +++ b/pkgs/core/pomona/src/isys/eddsupport.c @@ -0,0 +1,319 @@ +/* + * eddsupport.c - handling of mapping disk drives in Linux to disk drives + * according to the BIOS using the edd kernel module + * + * Copyright (C) 2004 Dell, Inc. All rights reserved. + * Copyright (C) 2004 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Rezwanul_Kabir@Dell.com + * Jeremy Katz <katzj@redhat.com> + */ + +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/reboot.h> +#include <sys/types.h> +#include <linux/types.h> + + +#include "eddsupport.h" +#include "devices.h" +#include "isys.h" + +#define EDD_DIR "/sys/firmware/edd" +#define SIG_FILE "mbr_signature" +#define MBRSIG_OFFSET 0x1b8 + +#define HASH_TABLE_SIZE 17 + + +struct diskMapEntry{ + uint32_t key; + char *diskname; + struct diskMapEntry *next; +}; + +struct diskMapTable { + struct diskMapEntry **table; + int tableSize; +}; + +static struct diskMapTable *mbrSigToName = NULL; +static int diskHashInit = 0; + + + +static struct diskMapTable* initializeHashTable(int); +static int insertHashItem(struct diskMapTable *, struct diskMapEntry *); +static struct diskMapEntry* lookupHashItem(struct diskMapTable *, uint32_t); +static int addToHashTable(struct diskMapTable *, uint32_t , char *); +static struct device ** createDiskList(); +static int mapBiosDisks(struct device ** , const char *); +static int readDiskSig(char *, uint32_t *); +static int readMbrSig(char *, uint32_t *); + +/* This is the top level function that creates a disk list present in the + * system, checks to see if unique signatures exist on the disks at offset + * 0x1b8. If a unique signature exists then it will map BIOS disks to their + * corresponding hd/sd device names. Otherwise, we'll avoid mapping drives. + */ + +int probeBiosDisks() { + struct device ** devices = NULL; + + devices = createDiskList(); + if(!devices){ +#ifdef STANDALONE + fprintf(stderr, "No disks!\n"); +#endif + return -1; + } + + if(!mapBiosDisks(devices, EDD_DIR)){ +#ifdef STANDALONE + fprintf(stderr, "WARNING: couldn't map BIOS disks\n"); +#endif + return -1; + } + return 0; +} + + +static struct device ** createDiskList(){ + return getDevices (DEVICE_DISK); +} + +static int readDiskSig(char *device, uint32_t *disksig) { + int fd, rc; + + fd = open(device, O_RDONLY); + if (fd < 0) { +#ifdef STANDALONE + fprintf(stderr, "Error opening device %s: %s\n ", device, + strerror(errno)); +#endif + return -errno; + } + + rc = lseek(fd, MBRSIG_OFFSET, SEEK_SET); + if (rc < 0){ + close(fd); + +#ifdef STANDALONE + fprintf(stderr, "Error seeking to MBRSIG_OFFSET in %s: %s\n", + device, strerror(errno)); +#endif + return -1; + } + + rc = read(fd, disksig, sizeof(uint32_t)); + if (rc < sizeof(uint32_t)) { + close(fd); + +#ifdef STANDALONE + fprintf(stderr, "Failed to read signature from %s\n", device); +#endif + return -1; + } + + close(fd); + return 0; +} + +static int mapBiosDisks(struct device** devices,const char *path) { + DIR *dirHandle; + struct dirent *entry; + char * sigFileName; + uint32_t mbrSig, biosNum, currentSig; + struct device **currentDev, **foundDisk; + int i, rc, ret; + + dirHandle = opendir(path); + if(!dirHandle){ +#ifdef STANDALONE + fprintf(stderr, "Failed to open directory %s: %s\n", path, + strerror(errno)); +#endif + return 0; + } + + mbrSigToName = initializeHashTable(HASH_TABLE_SIZE); + if(!mbrSigToName){ +#ifdef STANDALONE + fprintf(stderr, "Error initializing mbrSigToName table\n"); +#endif + closedir(dirHandle); + return 0; + } + + while ((entry = readdir(dirHandle)) != NULL) { + if(!strncmp(entry->d_name,".",1) || !strncmp(entry->d_name,"..",2)) { + continue; + } + ret = sscanf((entry->d_name+9), "%x", &biosNum); + + sigFileName = malloc(strlen(path) + strlen(entry->d_name) + 20); + sprintf(sigFileName, "%s/%s/%s", path, entry->d_name, SIG_FILE); + if (readMbrSig(sigFileName, &mbrSig) == 0) { + for (currentDev = devices, i = 0, foundDisk=NULL; + (*currentDev) != NULL && i<2; + currentDev++) { + if (!(*currentDev)->device) + continue; + + if ((rc=readDiskSig((*currentDev)->device, ¤tSig)) < 0) { + if (rc == -ENOMEDIUM) + continue; + closedir(dirHandle); + return 0; + } + + if (mbrSig == currentSig) { + foundDisk=currentDev; + i++; + } + } + + if (i==1) { + if(!addToHashTable(mbrSigToName, (uint32_t)biosNum, + (*foundDisk)->device)) { + closedir(dirHandle); + return 0; + } + } + } + } + closedir(dirHandle); + return 1; +} + + +static int readMbrSig(char *filename, uint32_t *int_sig){ + FILE* fh; + + fh = fopen(filename,"r"); + if(fh == NULL) { +#ifdef STANDALONE + fprintf(stderr, "Error opening mbr_signature file %s: %s\n", filename, + strerror(errno)); +#endif + return -1; + } + fseek(fh, 0, SEEK_SET); + if (fscanf(fh, "%x", int_sig) != 1) { +#ifdef STANDALONE + fprintf(stderr, "Error reading %s\n", filename); +#endif + fclose(fh); + return -1; + } + + fclose(fh); + return 0; +} + + +static struct diskMapTable* initializeHashTable(int size) { + struct diskMapTable *hashTable; + + hashTable = malloc(sizeof(struct diskMapTable)); + hashTable->tableSize = size; + hashTable->table = malloc(sizeof(struct diskMapEntry *) * size); + memset(hashTable->table,0,(sizeof(struct diskMapEntry *) * size)); + return hashTable; +} + + +static int insertHashItem(struct diskMapTable *hashTable, + struct diskMapEntry *hashItem) { + int index; + + index = (hashItem->key) % (hashTable->tableSize); + + if(hashTable->table[index] == NULL){ + hashTable->table[index] = hashItem; + return index; + } else { + hashItem->next = hashTable->table[index]; + hashTable->table[index] = hashItem; + return index; + } +} + + +static struct diskMapEntry * lookupHashItem(struct diskMapTable *hashTable, + uint32_t itemKey) { + int index; + struct diskMapEntry *hashItem; + + index = itemKey % (hashTable->tableSize); + for (hashItem = hashTable->table[index]; + (hashItem != NULL) && (hashItem->key != itemKey); + hashItem = hashItem->next) { + ; + } + return hashItem; +} + + +static int addToHashTable(struct diskMapTable *hashTable, + uint32_t itemKey, char *diskName) { + int index; + struct diskMapEntry *diskSigToNameEntry; + + diskSigToNameEntry = malloc(sizeof(struct diskMapEntry)); + diskSigToNameEntry->next = NULL; + diskSigToNameEntry->key = itemKey; + diskSigToNameEntry->diskname = diskName; + + if ((index = insertHashItem(hashTable, diskSigToNameEntry)) < 0){ +#ifdef STANDALONE + fprintf(stderr, "Unable to insert item\n"); +#endif + return 0; + } else { + return 1; + } +} + + +char * getBiosDisk(char *biosStr) { + uint32_t biosNum; + struct diskMapEntry * disk; + int ret; + + if (diskHashInit == 0) { + probeBiosDisks(); + diskHashInit = 1; + } + + if (mbrSigToName == NULL) + return NULL; + + ret = sscanf(biosStr,"%x",&biosNum); + disk = lookupHashItem(mbrSigToName, biosNum); + if (disk) return disk->diskname; + + return NULL; +} diff --git a/pkgs/core/pomona/src/isys/eddsupport.h b/pkgs/core/pomona/src/isys/eddsupport.h new file mode 100644 index 0000000..77fc4c4 --- /dev/null +++ b/pkgs/core/pomona/src/isys/eddsupport.h @@ -0,0 +1,28 @@ +/* + * eddsupport.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef EDDSUPPORT_H +#define EDDSUPPORT_H + +int probeBiosDisks(); +char* getBiosDisk(char *); + +#endif + + diff --git a/pkgs/core/pomona/src/isys/ethtool.c b/pkgs/core/pomona/src/isys/ethtool.c new file mode 100644 index 0000000..42a06dc --- /dev/null +++ b/pkgs/core/pomona/src/isys/ethtool.c @@ -0,0 +1,94 @@ +/* + * ethtool.c - setting of basic ethtool options + * + * Copyright (C) 2003 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Jeremy Katz <katzj@redhat.com> + */ + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <net/if.h> + +#include <linux/sockios.h> +#include "net.h" + +static int set_intf_up(struct ifreq ifr, int sock) { + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { + return (-1); + } + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { + fprintf(stderr, "failed to bring up interface %s: %s", ifr.ifr_name, + strerror(errno)); + return -1; + } + return (0); +} + +int setEthtoolSettings(char * dev, ethtool_speed speed, + ethtool_duplex duplex) { + int sock, err; + struct ethtool_cmd ecmd; + struct ifreq ifr; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("Unable to create socket"); + return -1; + } + + /* Setup our control structures. */ + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, dev); + + if (set_intf_up(ifr, sock) == -1) { + fprintf(stderr, "unable to bring up interface %s: %s", dev, + strerror(errno)); + return -1; + } + + ecmd.cmd = ETHTOOL_GSET; + ifr.ifr_data = (caddr_t)&ecmd; + err = ioctl(sock, SIOCETHTOOL, &ifr); + if (err < 0) { + perror("Unable to get settings via ethtool. Not setting"); + return -1; + } + + if (speed != ETHTOOL_SPEED_UNSPEC) + ecmd.speed = speed; + if (duplex != ETHTOOL_DUPLEX_UNSPEC) + ecmd.duplex = duplex; + if ((duplex != ETHTOOL_DUPLEX_UNSPEC) || (speed != ETHTOOL_SPEED_UNSPEC)) + ecmd.autoneg = AUTONEG_DISABLE; + + ecmd.cmd = ETHTOOL_SSET; + ifr.ifr_data = (caddr_t)&ecmd; + err = ioctl(sock, SIOCETHTOOL, &ifr); + if (err < 0) { + // perror("Unable to set settings via ethtool. Not setting"); + return -1; + } + + return 0; +} diff --git a/pkgs/core/pomona/src/isys/imount.c b/pkgs/core/pomona/src/isys/imount.c new file mode 100644 index 0000000..ec5ad5e --- /dev/null +++ b/pkgs/core/pomona/src/isys/imount.c @@ -0,0 +1,227 @@ +/* + * imount.c + * + * Copyright (C) 2007, 2008 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include "imount.h" +#include "sundries.h" + +#define _(foo) foo + +static int mkdirIfNone(char * directory); + +static int readFD(int fd, char **buf) { + char *p; + size_t size = 4096; + int s, filesize = 0; + + *buf = calloc(4096, sizeof (char)); + if (*buf == NULL) + abort(); + + do { + p = &(*buf)[filesize]; + s = read(fd, p, 4096); + if (s < 0) + break; + + filesize += s; + if (s == 0) + break; + + size += s; + *buf = realloc(*buf, size); + if (*buf == NULL) + abort(); + } while (1); + + if (filesize == 0 && s < 0) { + free(*buf); + *buf = NULL; + return -1; + } + + return filesize; +} + +int doPwMount(char *dev, char *where, char *fs, char *options, char **err) { + int rc, child, status, pipefd[2]; + char *opts = NULL, *device; + + if (mkdirChain(where)) + return IMOUNT_ERR_ERRNO; + + if (strstr(fs, "nfs")) { + if (options) { + if (asprintf(&opts, "%s,nolock", options) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } else { + opts = strdup("nolock"); + } + device = strdup(dev); + } else { + if ((options && strstr(options, "bind") == NULL) && + strncmp(dev, "LABEL=", 6) && strncmp(dev, "UUID=", 5) && + *dev != '/') { + if (asprintf(&device, "/dev/%s", dev) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } else { + device = strdup(dev); + } + if (options) + opts = strdup(options); + } + + if (pipe(pipefd)) + return IMOUNT_ERR_ERRNO; + + if (!(child = fork())) { + int fd; + + close(pipefd[0]); + + /* Close stdin entirely, redirect stdout to tty5, and redirect stderr + * to a pipe so we can put error messages into exceptions. We'll + * only use these messages should mount also return an error code. + */ + fd = open("/dev/tty5", O_RDONLY); + close(STDIN_FILENO); + dup2(fd, STDIN_FILENO); + close(fd); + + fd = open("/dev/tty5", O_WRONLY); + close(STDOUT_FILENO); + dup2(fd, STDOUT_FILENO); + + dup2(pipefd[1], STDERR_FILENO); + + if (opts) { + fprintf(stdout, "Running... /bin/mount -n -t %s -o %s %s %s\n", + fs, opts, device, where); + rc = execl("/bin/mount", + "/bin/mount", "-n", "-t", fs, "-o", opts, device, where, NULL); + exit(1); + } + else { + fprintf(stdout, "Running... /bin/mount -n -t %s %s %s\n", + fs, device, where); + rc = execl("/bin/mount", "/bin/mount", "-n", "-t", fs, device, where, NULL); + exit(1); + } + } + + close(pipefd[1]); + + if (err != NULL) + rc = readFD(pipefd[0], err); + + close(pipefd[0]); + waitpid(child, &status, 0); + + free(opts); + free(device); + if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) + return IMOUNT_ERR_OTHER; + + return 0; +} + +int doMultiMount(char *dev, char *where, char **fstypes, char *options, char **err) { + int retval = 0, i; + + for (i = 0; fstypes[i]; i++) { + /* If we made a previous call to mount and it returned an error message, + * get rid of it now. We only want to preserve the error from the last + * fstype. + */ + if (err && *err && **err) { + free(*err); + *err = NULL; + } + + retval = doPwMount(dev, where, fstypes[i], options, err); + if (!retval) + return retval; + } + + return retval; +} + +int mkdirChain(char * origChain) { + char * chain; + char * chptr; + + chain = alloca(strlen(origChain) + 1); + strcpy(chain, origChain); + chptr = chain; + + while ((chptr = strchr(chptr, '/'))) { + *chptr = '\0'; + if (mkdirIfNone(chain)) { + *chptr = '/'; + return IMOUNT_ERR_ERRNO; + } + + *chptr = '/'; + chptr++; + } + + if (mkdirIfNone(chain)) + return IMOUNT_ERR_ERRNO; + + return 0; +} + +static int mkdirIfNone(char * directory) { + int rc, mkerr; + char * chptr; + + /* If the file exists it *better* be a directory -- I'm not going to + actually check or anything */ + if (!access(directory, X_OK)) return 0; + + /* if the path is '/' we get ENOFILE not found" from mkdir, rather + then EEXIST which is weird */ + for (chptr = directory; *chptr; chptr++) + if (*chptr != '/') break; + if (!*chptr) return 0; + + rc = mkdir(directory, 0755); + mkerr = errno; + + if (!rc || mkerr == EEXIST) return 0; + + return IMOUNT_ERR_ERRNO; +} diff --git a/pkgs/core/pomona/src/isys/imount.h b/pkgs/core/pomona/src/isys/imount.h new file mode 100644 index 0000000..56f6dea --- /dev/null +++ b/pkgs/core/pomona/src/isys/imount.h @@ -0,0 +1,36 @@ +/* + * imount.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef H_IMOUNT +#define H_IMOUNT + +#define IMOUNT_ERR_ERRNO 1 +#define IMOUNT_ERR_OTHER 2 + +#include <sys/mount.h> /* for umount() */ + +#define IMOUNT_RDONLY 1 +#define IMOUNT_BIND 2 +#define IMOUNT_REMOUNT 4 + +int doPwMount(char *dev, char *where, char *fs, char *options, char **err); +int doMultiMount(char *dev, char *where, char **fstypes, char *options, char **err); +int mkdirChain(char * origChain); + +#endif diff --git a/pkgs/core/pomona/src/isys/isofs.c b/pkgs/core/pomona/src/isys/isofs.c new file mode 100644 index 0000000..c444dce --- /dev/null +++ b/pkgs/core/pomona/src/isys/isofs.c @@ -0,0 +1,55 @@ +/* + * isofs.c + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +#define BLOCK_SIZE 2048 + +/* returns 1 if file is an ISO, 0 otherwise */ +int fileIsIso(const char * file) { + int blkNum; + char magic[5]; + int fd; + + fd = open(file, O_RDONLY); + if (fd < 0) + return 0; + + for (blkNum = 16; blkNum < 100; blkNum++) { + if (lseek(fd, blkNum * BLOCK_SIZE + 1, SEEK_SET) < 0) { + close(fd); + return 0; + } + + if (read(fd, magic, sizeof(magic)) != sizeof(magic)) { + close(fd); + return 0; + } + + if (!strncmp(magic, "CD001", 5)) { + close(fd); + return 1; + } + } + + close(fd); + return 0; +} diff --git a/pkgs/core/pomona/src/isys/isys.c b/pkgs/core/pomona/src/isys/isys.c new file mode 100644 index 0000000..f56e713 --- /dev/null +++ b/pkgs/core/pomona/src/isys/isys.c @@ -0,0 +1,769 @@ +/* + * isys.c + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <Python.h> + +#include <stdio.h> +#include <dirent.h> +#include <errno.h> +#define u32 __u32 +#include <ext2fs/ext2fs.h> +#include <fcntl.h> +#include <popt.h> +/* Need to tell loop.h what the actual dev_t type is. */ +#undef dev_t +#define dev_t unsigned short +#include <linux/loop.h> +#undef dev_t +#define dev_t dev_t +#include <sys/ioctl.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> +#include <sys/time.h> +#include <sys/utsname.h> +#include <sys/vfs.h> +#include <unistd.h> +#include <resolv.h> +#include <scsi/scsi.h> +#include <scsi/scsi_ioctl.h> +#include <sys/vt.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <linux/fb.h> +#include <libintl.h> +#ifdef USESELINUX +#include <selinux/selinux.h> +#endif +#include <libgen.h> +#include <linux/major.h> +#include <linux/raid/md_u.h> +#include <linux/raid/md_p.h> +#include <signal.h> +#include <execinfo.h> + +#include <blkid/blkid.h> + +#include "isys.h" +#include "imount.h" +#include "smp.h" +#include "lang.h" +#include "eddsupport.h" +#include "imount.h" + +#ifndef CDROMEJECT +#define CDROMEJECT 0x5309 +#endif + +static PyObject * doMount(PyObject * s, PyObject * args); +static PyObject * doUMount(PyObject * s, PyObject * args); +static PyObject * smpAvailable(PyObject * s, PyObject * args); +static PyObject * htAvailable(PyObject * s, PyObject * args); +static PyObject * doSwapon(PyObject * s, PyObject * args); +static PyObject * doSwapoff(PyObject * s, PyObject * args); +static PyObject * doLoSetup(PyObject * s, PyObject * args); +static PyObject * doUnLoSetup(PyObject * s, PyObject * args); +static PyObject * doLoChangeFd(PyObject * s, PyObject * args); +static PyObject * doDdFile(PyObject * s, PyObject * args); +static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args); +static PyObject * doGetRaidSuperblock(PyObject * s, PyObject * args); +static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args); +static PyObject * doDevSpaceFree(PyObject * s, PyObject * args); +static PyObject * doResetResolv(PyObject * s, PyObject * args); +static PyObject * doLoadKeymap(PyObject * s, PyObject * args); +static PyObject * doClobberExt2 (PyObject * s, PyObject * args); +static PyObject * doReadE2fsLabel(PyObject * s, PyObject * args); +static PyObject * doExt2Dirty(PyObject * s, PyObject * args); +static PyObject * doExt2HasJournal(PyObject * s, PyObject * args); +static PyObject * doEjectCdrom(PyObject * s, PyObject * args); +static PyObject * doVtActivate(PyObject * s, PyObject * args); +static PyObject * doisPseudoTTY(PyObject * s, PyObject * args); +static PyObject * doisVioConsole(PyObject * s); +static PyObject * doSync(PyObject * s, PyObject * args); +static PyObject * doisIsoImage(PyObject * s, PyObject * args); +static PyObject * getFramebufferInfo(PyObject * s, PyObject * args); +static PyObject * printObject(PyObject * s, PyObject * args); +static PyObject * doProbeBiosDisks(PyObject * s, PyObject * args); +static PyObject * doGetBiosDisk(PyObject * s, PyObject * args); +static PyObject * doSegvHandler(PyObject *s, PyObject *args); +static PyObject * doGetBlkidData(PyObject * s, PyObject * args); +static PyObject * doGetDeviceByToken(PyObject *s, PyObject *args); + +static PyMethodDef isysModuleMethods[] = { + { "ejectcdrom", (PyCFunction) doEjectCdrom, METH_VARARGS, NULL }, + { "e2dirty", (PyCFunction) doExt2Dirty, METH_VARARGS, NULL }, + { "e2hasjournal", (PyCFunction) doExt2HasJournal, METH_VARARGS, NULL }, + { "e2fslabel", (PyCFunction) doReadE2fsLabel, METH_VARARGS, NULL }, + { "e2fsclobber", (PyCFunction) doClobberExt2, METH_VARARGS, NULL }, + { "devSpaceFree", (PyCFunction) doDevSpaceFree, METH_VARARGS, NULL }, + { "getraidsb", (PyCFunction) doGetRaidSuperblock, METH_VARARGS, NULL }, + { "wiperaidsb", (PyCFunction) doWipeRaidSuperblock, METH_VARARGS, NULL }, + { "getraidchunk", (PyCFunction) doGetRaidChunkSize, METH_VARARGS, NULL }, + { "lochangefd", (PyCFunction) doLoChangeFd, METH_VARARGS, NULL }, + { "losetup", (PyCFunction) doLoSetup, METH_VARARGS, NULL }, + { "unlosetup", (PyCFunction) doUnLoSetup, METH_VARARGS, NULL }, + { "ddfile", (PyCFunction) doDdFile, METH_VARARGS, NULL }, + { "mount", (PyCFunction) doMount, METH_VARARGS, NULL }, + { "smpavailable", (PyCFunction) smpAvailable, METH_VARARGS, NULL }, + { "htavailable", (PyCFunction) htAvailable, METH_VARARGS, NULL }, + { "umount", (PyCFunction) doUMount, METH_VARARGS, NULL }, + { "resetresolv", (PyCFunction) doResetResolv, METH_VARARGS, NULL }, + { "swapon", (PyCFunction) doSwapon, METH_VARARGS, NULL }, + { "swapoff", (PyCFunction) doSwapoff, METH_VARARGS, NULL }, + { "loadKeymap", (PyCFunction) doLoadKeymap, METH_VARARGS, NULL }, + { "vtActivate", (PyCFunction) doVtActivate, METH_VARARGS, NULL}, + { "isPseudoTTY", (PyCFunction) doisPseudoTTY, METH_VARARGS, NULL}, + { "isVioConsole", (PyCFunction) doisVioConsole, METH_NOARGS, NULL}, + { "sync", (PyCFunction) doSync, METH_VARARGS, NULL}, + { "isisoimage", (PyCFunction) doisIsoImage, METH_VARARGS, NULL}, + { "fbinfo", (PyCFunction) getFramebufferInfo, METH_VARARGS, NULL}, + { "printObject", (PyCFunction) printObject, METH_VARARGS, NULL}, + { "biosDiskProbe", (PyCFunction) doProbeBiosDisks, METH_VARARGS,NULL}, + { "getbiosdisk",(PyCFunction) doGetBiosDisk, METH_VARARGS,NULL}, + { "handleSegv", (PyCFunction) doSegvHandler, METH_VARARGS, NULL }, + { "getblkid", (PyCFunction) doGetBlkidData, METH_VARARGS, NULL }, + { "getdevicebytoken", (PyCFunction) doGetDeviceByToken, METH_VARARGS, NULL }, + { NULL, NULL, 0, NULL } +} ; + +static PyObject * doDdFile(PyObject * s, PyObject * args) { + int fd; + int megs; + char * ptr; + int i; + + if (!PyArg_ParseTuple(args, "ii", &fd, &megs)) return NULL; + + ptr = calloc(1024 * 256, 1); + + while (megs--) { + for (i = 0; i < 4; i++) { + if (write(fd, ptr, 1024 * 256) != 1024 * 256) { + PyErr_SetFromErrno(PyExc_SystemError); + free(ptr); + return NULL; + } + sync(); + } + } + + free(ptr); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doUnLoSetup(PyObject * s, PyObject * args) { + int loopfd; + + if (!PyArg_ParseTuple(args, "i", &loopfd)) return NULL; + if (ioctl(loopfd, LOOP_CLR_FD, 0)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* XXX - msw */ +#ifndef LOOP_CHANGE_FD +#define LOOP_CHANGE_FD 0x4C06 +#endif + +static PyObject * doLoChangeFd(PyObject * s, PyObject * args) { + int loopfd; + int targfd; + + if (!PyArg_ParseTuple(args, "ii", &loopfd, &targfd)) + return NULL; + if (ioctl(loopfd, LOOP_CHANGE_FD, targfd)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doLoSetup(PyObject * s, PyObject * args) { + int loopfd; + int targfd; + struct loop_info loopInfo; + char * loopName; + + if (!PyArg_ParseTuple(args, "iis", &loopfd, &targfd, &loopName)) + return NULL; + if (ioctl(loopfd, LOOP_SET_FD, targfd)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + memset(&loopInfo, 0, sizeof(loopInfo)); + strncpy(loopInfo.lo_name, basename(loopName), 63); + + if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doUMount(PyObject * s, PyObject * args) { + char * fs; + + if (!PyArg_ParseTuple(args, "s", &fs)) return NULL; + + if (umount(fs)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doMount(PyObject * s, PyObject * args) { + char *err = NULL, *fs, *device, *mntpoint, *flags = NULL; + int rc; + + if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint, + &flags)) return NULL; + + rc = doPwMount(device, mntpoint, fs, flags, &err); + if (rc == IMOUNT_ERR_ERRNO) + PyErr_SetFromErrno(PyExc_SystemError); + else if (rc) { + PyObject *tuple = PyTuple_New(2); + + PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); + PyTuple_SetItem(tuple, 1, PyString_FromString(err)); + PyErr_SetObject(PyExc_SystemError, tuple); + } + + if (rc) return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +#define BOOT_SIGNATURE 0xaa55 /* boot signature */ +#define BOOT_SIG_OFFSET 510 /* boot signature offset */ + +int swapoff(const char * path); +int swapon(const char * path, int priorty); + +static PyObject * doSwapoff (PyObject * s, PyObject * args) { + char * path; + + if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + + if (swapoff (path)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doSwapon (PyObject * s, PyObject * args) { + char * path; + + if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + + if (swapon (path, 0)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * smpAvailable(PyObject * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "")) return NULL; + + return Py_BuildValue("i", detectSMP()); +} + +static PyObject * htAvailable(PyObject * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "")) return NULL; + + return Py_BuildValue("i", detectHT()); +} + +void init_isys(void) { + PyObject * m, * d; + + m = Py_InitModule("_isys", isysModuleMethods); + d = PyModule_GetDict(m); + + PyDict_SetItemString(d, "MIN_RAM", PyInt_FromLong(MIN_RAM)); + PyDict_SetItemString(d, "EARLY_SWAP_RAM", PyInt_FromLong(EARLY_SWAP_RAM)); +} + +static PyObject * doResetResolv(PyObject * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "")) { + return NULL; + } + + /* reinit the resolver so DNS changes take affect */ + res_init(); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args) { + int fd; + unsigned long size; + struct mdp_super_t * sb; + + if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + + if (ioctl(fd, BLKGETSIZE, &size)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + /* put the size in 1k blocks */ + size >>= 1; + + if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + sb = malloc(sizeof(mdp_super_t)); + sb = memset(sb, '\0', sizeof(mdp_super_t)); + + if (write(fd, sb, sizeof(sb)) != sizeof(sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + return Py_None; +} + +static PyObject * doGetRaidSuperblock(PyObject * s, PyObject * args) { + int fd; + unsigned long size; + mdp_super_t sb; + char uuid[36]; + + if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + + if (ioctl(fd, BLKGETSIZE, &size)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + /* put the size in 1k blocks */ + size >>= 1; + + if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + if (sb.md_magic != MD_SB_MAGIC) { + PyErr_SetString(PyExc_ValueError, "bad md magic on device"); + return NULL; + } + + sprintf(uuid, "%08x:%08x:%08x:%08x", sb.set_uuid0, sb.set_uuid1, + sb.set_uuid2, sb.set_uuid3); + + return Py_BuildValue("(iisiiii)", sb.major_version, sb.minor_version, + uuid, sb.level, sb.nr_disks, sb.raid_disks, + sb.md_minor); +} + +static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args) { + int fd; + unsigned long size; + mdp_super_t sb; + + if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + + if (ioctl(fd, BLKGETSIZE, &size)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + /* put the size in 1k blocks */ + size >>= 1; + + if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + if (sb.md_magic != MD_SB_MAGIC) { + PyErr_SetString(PyExc_ValueError, "bad md magic on device"); + return NULL; + } + + return Py_BuildValue("i", sb.chunk_size / 1024); +} + +static int get_bits(unsigned long long v) { + int b = 0; + + if ( v & 0xffffffff00000000LLU ) { b += 32; v >>= 32; } + if ( v & 0xffff0000LLU ) { b += 16; v >>= 16; } + if ( v & 0xff00LLU ) { b += 8; v >>= 8; } + if ( v & 0xf0LLU ) { b += 4; v >>= 4; } + if ( v & 0xcLLU ) { b += 2; v >>= 2; } + if ( v & 0x2LLU ) b++; + + return v ? b + 1 : b; +} + +static PyObject * doDevSpaceFree(PyObject * s, PyObject * args) { + char * path; + struct statfs sb; + unsigned long long size; + + if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + + if (statfs(path, &sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + /* Calculate a saturated addition to prevent oveflow. */ + if ( get_bits(sb.f_bfree) + get_bits(sb.f_bsize) <= 64 ) + size = (unsigned long long)sb.f_bfree * sb.f_bsize; + else + size = ~0LLU; + + return PyLong_FromUnsignedLongLong(size>>20); +} + +static PyObject * doLoadKeymap (PyObject * s, PyObject * args) { + char * keymap; + int ret; + + if (!PyArg_ParseTuple(args, "s", &keymap)) return NULL; + + ret = isysLoadKeymap (keymap); + if (ret) { + errno = -ret; + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doClobberExt2 (PyObject * s, PyObject * args) { + char * device; + ext2_filsys fsys; + struct ext2_super_block sb; + int rc; + + if (!PyArg_ParseTuple(args, "s", &device)) return NULL; + + rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, &fsys); + + if (rc) { + Py_INCREF(Py_None); + return Py_None; + } + + memset(&sb, 0, sizeof(struct ext2_super_block)); + rc = ext2fs_initialize (device, 0, &sb, unix_io_manager, &fsys); + if (rc) { + Py_INCREF(Py_None); + return Py_None; + } + + ext2fs_close(fsys); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doReadE2fsLabel(PyObject * s, PyObject * args) { + char * device; + ext2_filsys fsys; + char buf[50]; + int rc; + + if (!PyArg_ParseTuple(args, "s", &device)) return NULL; + + rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, + &fsys); + if (rc) { + Py_INCREF(Py_None); + return Py_None; + } + + memset(buf, 0, sizeof(buf)); + strncpy(buf, fsys->super->s_volume_name, + sizeof(fsys->super->s_volume_name)); + + ext2fs_close(fsys); + + return Py_BuildValue("s", buf); +} + +static PyObject * doExt2Dirty(PyObject * s, PyObject * args) { + char * device; + ext2_filsys fsys; + int rc; + int clean; + + if (!PyArg_ParseTuple(args, "s", &device)) return NULL; + + rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, + &fsys); + if (rc) { + Py_INCREF(Py_None); + return Py_None; + } + + clean = fsys->super->s_state & EXT2_VALID_FS; + + ext2fs_close(fsys); + + return Py_BuildValue("i", !clean); +} +static PyObject * doExt2HasJournal(PyObject * s, PyObject * args) { + char * device; + ext2_filsys fsys; + int rc; + int hasjournal; + + if (!PyArg_ParseTuple(args, "s", &device)) return NULL; + rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, + &fsys); + if (rc) { + Py_INCREF(Py_None); + return Py_None; + } + + hasjournal = fsys->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL; + + ext2fs_close(fsys); + + return Py_BuildValue("i", hasjournal); +} + +static PyObject * doEjectCdrom(PyObject * s, PyObject * args) { + int fd; + + if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + + if (ioctl(fd, CDROMEJECT, 1)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doVtActivate(PyObject * s, PyObject * args) { + int vtnum; + + if (!PyArg_ParseTuple(args, "i", &vtnum)) return NULL; + + if (ioctl(0, VT_ACTIVATE, vtnum)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doisPseudoTTY(PyObject * s, PyObject * args) { + int fd; + struct stat sb; + + if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + fstat(fd, &sb); + + /* XXX close enough for now */ + return Py_BuildValue("i", ((major(sb.st_rdev) >= 136) && (major(sb.st_rdev) <= 143))); +} + +static PyObject * doisVioConsole(PyObject * s) { + return Py_BuildValue("i", isVioConsole()); +} + +static PyObject * doSync(PyObject * s, PyObject * args) { + int fd; + + if (!PyArg_ParseTuple(args, "", &fd)) return NULL; + sync(); + + Py_INCREF(Py_None); + return Py_None; +} + +int fileIsIso(const char * file); + +static PyObject * doisIsoImage(PyObject * s, PyObject * args) { + char * fn; + int rc; + + if (!PyArg_ParseTuple(args, "s", &fn)) return NULL; + + rc = fileIsIso(fn); + + return Py_BuildValue("i", rc); +} + +static PyObject * getFramebufferInfo(PyObject * s, PyObject * args) { + int fd; + struct fb_var_screeninfo fb; + + fd = open("/dev/fb0", O_RDONLY); + if (fd == -1) { + Py_INCREF(Py_None); + return Py_None; + } + + if (ioctl(fd, FBIOGET_VSCREENINFO, &fb)) { + close(fd); + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + close(fd); + + return Py_BuildValue("(iii)", fb.xres, fb.yres, fb.bits_per_pixel); +} + +static PyObject * printObject (PyObject * o, PyObject * args) { + PyObject * obj; + char buf[256]; + + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + + snprintf(buf, 256, "<%s object at %lx>", obj->ob_type->tp_name, + (long) obj); + + return PyString_FromString(buf); +} + +static PyObject * doProbeBiosDisks(PyObject * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "")) return NULL; + + + return Py_BuildValue("i", probeBiosDisks()); +} + +static PyObject * doGetBiosDisk(PyObject * s, PyObject * args) { + char *mbr_sig; + char *diskname; + + if (!PyArg_ParseTuple(args, "s", &mbr_sig)) return NULL; + + if ((diskname = getBiosDisk(mbr_sig))) + return Py_BuildValue("s", diskname); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doSegvHandler(PyObject *s, PyObject *args) { + void *array[20]; + size_t size; + char **strings; + size_t i; + + signal(SIGSEGV, SIG_DFL); /* back to default */ + + size = backtrace (array, 20); + strings = backtrace_symbols (array, size); + + printf ("Anaconda received SIGSEGV!. Backtrace:\n"); + for (i = 0; i < size; i++) + printf ("%s\n", strings[i]); + + free (strings); + exit(1); +} + +static PyObject *doGetDeviceByToken(PyObject *s, PyObject *args) { + blkid_cache cache; + char *token, *value, *dev; + + if (!PyArg_ParseTuple(args, "ss", &token, &value)) return NULL; + + blkid_get_cache(&cache, NULL); + + dev = blkid_get_devname(cache, token, value); + if (dev == NULL) { + Py_INCREF(Py_None); + return Py_None; + } else { + return Py_BuildValue("s", dev); + } +} + +static PyObject * doGetBlkidData(PyObject * s, PyObject * args) { + char * dev, * key; + blkid_cache cache; + blkid_dev bdev = NULL; + blkid_tag_iterate titer; + const char * type, * data; + + if (!PyArg_ParseTuple(args, "ss", &dev, &key)) return NULL; + + blkid_get_cache(&cache, NULL); + + bdev = blkid_get_dev(cache, dev, BLKID_DEV_NORMAL); + if (bdev == NULL) + goto out; + titer = blkid_tag_iterate_begin(bdev); + while (blkid_tag_next(titer, &type, &data) >= 0) { + if (!strcmp(type, key)) { + blkid_tag_iterate_end(titer); + return Py_BuildValue("s", data); + } + } + blkid_tag_iterate_end(titer); + + out: + Py_INCREF(Py_None); + return Py_None; +} + +/* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/pkgs/core/pomona/src/isys/isys.h b/pkgs/core/pomona/src/isys/isys.h new file mode 100644 index 0000000..9f6a2bb --- /dev/null +++ b/pkgs/core/pomona/src/isys/isys.h @@ -0,0 +1,35 @@ +/* + * isys.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef H_ISYS +#define H_ISYS + +#define MIN_RAM 32000 +#define EARLY_SWAP_RAM 64000 + +int insmod(char * modName, char * path, char ** args); +int rmmod(char * modName); + +/* returns 0 for true, !0 for false */ +int fileIsIso(const char * file); + +/* returns 1 if on an iSeries vio console, 0 otherwise */ +int isVioConsole(void); + +#endif diff --git a/pkgs/core/pomona/src/isys/isys.py b/pkgs/core/pomona/src/isys/isys.py new file mode 100644 index 0000000..7104c6c --- /dev/null +++ b/pkgs/core/pomona/src/isys/isys.py @@ -0,0 +1,710 @@ +# +# isys.py - installer utility functions and glue for C module +# +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Matt Wilson <msw@redhat.com> +# Erik Troan <ewt@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# + +import _isys +import string +import os +import os.path +import socket +import stat +import posix +import sys +import iutil +import warnings +import resource +import re +import struct +import pyfire.hal + +import logging +log = logging.getLogger("pomona") +import warnings + +mountCount = {} +raidCount = {} + +MIN_RAM = _isys.MIN_RAM +EARLY_SWAP_RAM = _isys.EARLY_SWAP_RAM + +## Get the amount of free space available under a directory path. +# @param path The directory path to check. +# @return The amount of free space available, in +def pathSpaceAvailable(path): + return _isys.devSpaceFree(path) + + +mdadmOutput = "/tmp/mdadmout" + +## An error occured when running mdadm. +class MdadmError(Exception): + ## The constructor. + # @param args The arguments passed to the mdadm command. + # @param name The the name of the RAID device used in the mdadm command. + def __init__(self, args, name=None): + self.args = args + self.name = name + self.log = self.getCmdOutput() + + ## Get the output of the last mdadm command run. + # @return The formatted output of the mdadm command which caused an error. + def getCmdOutput(self): + f = open(mdadmOutput, "r") + lines = reduce(lambda x,y: x + [string.strip(y),], f.readlines(), []) + lines = string.join(reduce(lambda x,y: x + [" %s" % (y,)], \ + lines, []), "\n") + return lines + + def __str__(self): + s = "" + if not self.name is None: + s = " for device %s" % (self.name,) + command = "mdadm " + string.join(self.args, " ") + return "'%s' failed%s\nLog:\n%s" % (command, s, self.log) + +def _mdadm(*args): + try: + lines = iutil.execWithCapture("mdadm", args, stderr = mdadmOutput) + lines = string.split(lines, '\n') + lines = reduce(lambda x,y: x + [y.strip(),], lines, []) + return lines + except: + raise MdadmError, args + +def _getRaidInfo(drive): + log.info("mdadm -E %s" % (drive,)) + try: + lines = _mdadm("-E", drive) + except MdadmError: + ei = sys.exc_info() + ei[1].name = drive + raise ei[0], ei[1], ei[2] + + info = { + 'major': "-1", + 'minor': "-1", + 'uuid' : "", + 'level': -1, + 'nrDisks': -1, + 'totalDisks': -1, + 'mdMinor': -1, + } + + for line in lines: + vals = string.split(string.strip(line), ' : ') + if len(vals) != 2: + continue + if vals[0] == "Version": + vals = string.split(vals[1], ".") + info['major'] = vals[0] + info['minor'] = vals[1] + elif vals[0] == "UUID": + info['uuid'] = vals[1] + elif vals[0] == "Raid Level": + info['level'] = int(vals[1][4:]) + elif vals[0] == "Raid Devices": + info['nrDisks'] = int(vals[1]) + elif vals[0] == "Total Devices": + info['totalDisks'] = int(vals[1]) + elif vals[0] == "Preferred Minor": + info['mdMinor'] = int(vals[1]) + else: + continue + + if info['uuid'] == "": + raise ValueError, info + + return info + +def _stopRaid(mdDevice): + log.info("mdadm --stop %s" % (mdDevice,)) + try: + _mdadm("--stop", mdDevice) + except MdadmError: + ei = sys.exc_info() + ei[1].name = mdDevice + raise ei[0], ei[1], ei[2] + +def raidstop(mdDevice): + log.info("stopping raid device %s" %(mdDevice,)) + if raidCount.has_key (mdDevice): + if raidCount[mdDevice] > 1: + raidCount[mdDevice] = raidCount[mdDevice] - 1 + return + del raidCount[mdDevice] + + devInode = "/dev/%s" % mdDevice + + try: + _stopRaid(devInode) + except: + pass + +def _startRaid(mdDevice, mdMinor, uuid): + log.info("mdadm -A --uuid=%s --super-minor=%s %s" % (uuid, mdMinor, mdDevice)) + try: + _mdadm("-A", "--uuid=%s" % (uuid,), "--super-minor=%s" % (mdMinor,), \ + mdDevice) + except MdadmError: + ei = sys.exc_info() + ei[1].name = mdDevice + raise ei[0], ei[1], ei[2] + +def raidstart(mdDevice, aMember): + log.info("starting raid device %s" %(mdDevice,)) + if raidCount.has_key(mdDevice) and raidCount[mdDevice]: + raidCount[mdDevice] = raidCount[mdDevice] + 1 + return + + raidCount[mdDevice] = 1 + + mdInode = "/dev/%s" % mdDevice + mbrInode = "/dev/%s" % aMember + + if os.path.exists(mdInode): + minor = os.minor(os.stat(mdInode).st_rdev) + else: + minor = int(mdDevice[2:]) + try: + info = _getRaidInfo(mbrInode) + if info.has_key('mdMinor'): + minor = info['mdMinor'] + _startRaid(mdInode, minor, info['uuid']) + except: + pass + +## Remove the superblock from a RAID device. +# @param device The complete path to the RAID device name to wipe. +def wipeRaidSB(device): + try: + fd = os.open(device, os.O_WRONLY) + except OSError, e: + log.warning("error wiping raid device superblock for %s: %s", device, e) + return + + try: + _isys.wiperaidsb(fd) + finally: + os.close(fd) + return + +## Get the raw superblock from a RAID device. +# @param The basename of a RAID device to check. This device node does not +# need to exist to begin with. +# @return A RAID superblock in its raw on-disk format. +def raidsb(mdDevice): + return raidsbFromDevice("/dev/%s" % mdDevice) + +## Get the superblock from a RAID device. +# @param The full path to a RAID device name to check. This device node must +# already exist. +# @return A tuple of the contents of the RAID superblock, or ValueError on +# error. +def raidsbFromDevice(device): + try: + info = _getRaidInfo(device) + return (info['major'], info['minor'], info['uuid'], info['level'], + info['nrDisks'], info['totalDisks'], info['mdMinor']) + except: + raise ValueError + +def getRaidChunkFromDevice(device): + fd = os.open(device, os.O_RDONLY) + rc = 64 + try: + rc = _isys.getraidchunk(fd) + finally: + os.close(fd) + return rc + +## Set up an already existing device node to be used as a loopback device. +# @param device The full path to a device node to set up as a loopback device. +# @param file The file to mount as loopback on device. +# @param readOnly Should this loopback device be used read-only? +def losetup(device, file, readOnly = 0): + if readOnly: + mode = os.O_RDONLY + else: + mode = os.O_RDWR + targ = os.open(file, mode) + loop = os.open(device, mode) + try: + _isys.losetup(loop, targ, file) + finally: + os.close(loop) + os.close(targ) + +def lochangefd(device, file): + loop = os.open(device, os.O_RDONLY) + targ = os.open(file, os.O_RDONLY) + try: + _isys.lochangefd(loop, targ) + finally: + os.close(loop) + os.close(targ) + +## Disable a previously setup loopback device. +# @param device The full path to an existing loopback device node. +def unlosetup(device): + loop = os.open(device, os.O_RDONLY) + try: + _isys.unlosetup(loop) + finally: + os.close(loop) + +def ddfile(file, megs, pw = None): + buf = '\x00' * (1024 * 256) + + fd = os.open(file, os.O_RDWR | os.O_CREAT) + + total = megs * 4 # we write out 1/4 of a meg each time through + + if pw: + (fn, title, text) = pw + win = fn(title, text, total - 1) + + for n in range(total): + os.write(fd, buf) + if pw: + win.set(n) + + if pw: + win.pop() + + os.close(fd) + +## Mount a filesystem, similar to the mount system call. +# @param device The device to mount. If bindMount is 1, this should be an +# already mounted directory. Otherwise, it should be a device +# name. +# @param location The path to mount device on. +# @param fstype The filesystem type on device. This can be disk filesystems +# such as vfat or ext3, or pseudo filesystems such as proc or +# selinuxfs. +# @param readOnly Should this filesystem be mounted readonly? +# @param bindMount Is this a bind mount? (see the mount(8) man page) +# @param remount Are we mounting an already mounted filesystem? +# @return The return value from the mount system call. +def mount(device, location, fstype = "ext2", readOnly = 0, bindMount = 0, remount = 0, options = "defaults"): + flags = None + location = os.path.normpath(location) + opts = string.split(options) + + # We don't need to create device nodes for devices that start with '/' + # (like '/usbdevfs') and also some special fake devices like 'proc'. + # First try to make a device node and if that fails, assume we can + # mount without making a device node. If that still fails, the caller + # will have to deal with the exception. + # We note whether or not we created a node so we can clean up later. + + if mountCount.has_key(location) and mountCount[location] > 0: + mountCount[location] = mountCount[location] + 1 + return + + if readOnly or bindMount or remount: + if readOnly: + opts.append("ro") + if bindMount: + opts.append("bind") + if remount: + opts.append("remount") + + flags = ",".join(opts) + + log.debug("isys.py:mount()- going to mount %s on %s with options %s" %(device, location, flags)) + rc = _isys.mount(fstype, device, location, flags) + + if not rc: + mountCount[location] = 1 + + return rc + +## Unmount a filesystem, similar to the umount system call. +# @param what The directory to be unmounted. This does not need to be the +# absolute path. +# @param removeDir Should the mount point be removed after being unmounted? +# @return The return value from the umount system call. +def umount(what, removeDir = 1): + what = os.path.normpath(what) + + if not os.path.isdir(what): + raise ValueError, "isys.umount() can only umount by mount point" + + if mountCount.has_key(what) and mountCount[what] > 1: + mountCount[what] = mountCount[what] - 1 + return + + rc = _isys.umount(what) + + if removeDir and os.path.isdir(what): + os.rmdir(what) + + if not rc and mountCount.has_key(what): + del mountCount[what] + + return rc + +## Get the SMP status of the system. +# @return True if this is an SMP system, False otherwise. +def smpAvailable(): + return _isys.smpavailable() + +htavailable = _isys.htavailable + +## Disable swap. +# @param path The full path of the swap device to disable. +def swapoff(path): + return _isys.swapoff (path) + +## Enable swap. +# @param path The full path of the swap device to enable. +def swapon(path): + return _isys.swapon (path) + +## Load a keyboard layout for text mode installs. +# @param keymap The keyboard layout to load. This must be one of the values +# from rhpl.KeyboardModels. +def loadKeymap(keymap): + return _isys.loadKeymap (keymap) + +cachedDrives = None + +## Clear the drive dict cache. +# This method clears the drive dict cache. If the drive state changes (by +# loading and unloading modules, attaching removable devices, etc.) then this +# function must be called before any of the *DriveDict or *DriveList functions. +# If not, those functions will return information that does not reflect the +# current machine state. +def flushDriveDict(): + global cachedDrives + cachedDrives = None + +def driveDict(klassArg): + import parted + global cachedDrives + if cachedDrives is None: + new = {} + for dev in pyfire.hal.get_devices_by_type("storage"): + if dev['device'] is None: # none devices make no sense + continue + + device = dev['device'].replace('/dev/','') + # we can't actually use the sg devices, so ignore them + if device.startswith("sg"): + log.info("ignoring sg device %s" %(device,)) + continue + + # we can't actually use the st devices, so ignore them + if device.startswith("st"): + log.info("ignoring st device %s" %(device,)) + continue + + # we want to ignore md devices as they're not hard disks in our pov + if device.startswith("md"): + continue + + if dev['storage.drive_type'] != 'disk': + new[device] = dev + continue + try: + if not mediaPresent(device): + new[device] = dev + continue + + if device.startswith("sd"): + peddev = parted.PedDevice.get(dev['device']) + model = peddev.model + + del peddev + new[device] = dev + except Exception, e: + log.debug("exception checking disk blacklist on %s: %s" % \ + (device, e)) + cachedDrives = new + + ret = {} + for key,dev in cachedDrives.items(): + if dev['storage.drive_type'] == klassArg: + ret[key] = dev + return ret + +## Get all the hard drives attached to the system. +# This method queries the drive dict cache for all hard drives. If the cache +# is empty, this will cause all disk devices to be probed. If the status of +# the devices has changed, flushDriveDict must be called first. +# +# @see flushDriveDict +# @see driveDict +# @return A dict of all the hard drive descriptions, keyed on device name. +def hardDriveDict(): + ret = {} + dict = driveDict("disk") + for item in dict.keys(): + try: + ret[item] = dict[item]['description'] + except AttributeError: + ret[item] = "" + return ret + +## Get all the removable drives attached to the system. +# This method queries the drive dict cache for all removable drives. If the cache +# is empty, this will cause all disk devices to be probed. If the status of +# the devices has changed, flushDriveDict must be run called first. +# +# @see flushDriveDict +# @see driveDict +# @return A dict of all the removable drive descriptions, keyed on device name. +def removableDriveDict(): + ret = {} + dict = driveDict("disk") + for item in dict.keys(): + if dict[item]['storage.removable'] != 0: + try: + ret[item] = dict[item]['description'] + except AttributeError: + ret[item] = "" + return ret + +## Get all CD/DVD drives attached to the system. +# This method queries the drive dict cache for all hard drives. If the cache +# is empty, this will cause all disk devices to be probed. If the status of +# the devices has changed, flushDriveDict must be called first. +# +# @see flushDriveDict +# @see driveDict +# @return A sorted list of all the CD/DVD drives, without any leading /dev/. +def cdromList(): + list = driveDict("cdrom").keys() + list.sort() + return list + +## Get all tape drives attached to the system. +# This method queries the drive dict cache for all hard drives. If the cache +# is empty, this will cause all disk devices to be probed. If the status of +# the devices has changed, flushDriveDict must be called first. +# +# @see flushDriveDict +# @see driveDict +# @return A sorted list of all the tape drives, without any leading /dev/. +def tapeDriveList(): + list = driveDict("tape").keys() + list.sort() + return list + +## Calculate the broadcast address of a network. +# @param ip An IPv4 address as a string. +# @param nm A corresponding netmask as a string. +# @return A tuple of network address and broadcast address strings. +def inet_calcNetBroad(ip, nm): + (ipaddr,) = struct.unpack('I', socket.inet_pton(socket.AF_INET, ip)) + ipaddr = socket.ntohl(ipaddr) + + (nmaddr,) = struct.unpack('I', socket.inet_pton(socket.AF_INET, nm)) + nmaddr = socket.ntohl(nmaddr) + + netaddr = ipaddr & nmaddr + bcaddr = netaddr | (~nmaddr) + + nw = socket.inet_ntop(socket.AF_INET, struct.pack('!I', netaddr)) + bc = socket.inet_ntop(socket.AF_INET, struct.pack('!I', bcaddr)) + + return (nw, bc) + +def doProbeBiosDisks(): + return _isys.biosDiskProbe() + +def doGetBiosDisk(mbrSig): + return _isys.getbiosdisk(mbrSig) + +biosdisks = {} +for d in range(80, 80 + 15): + disk = doGetBiosDisk("%d" %(d,)) + #print "biosdisk of %s is %s" %(d, disk) + if disk is not None: + biosdisks[disk] = d + +def compareDrives(first, second): + if biosdisks.has_key(first) and biosdisks.has_key(second): + one = biosdisks[first] + two = biosdisks[second] + if (one < two): + return -1 + elif (one > two): + return 1 + + if first.startswith("hd"): + type1 = 0 + elif first.startswith("sd"): + type1 = 1 + elif (first.startswith("vd") or first.startswith("xvd")): + type1 = -1 + else: + type1 = 2 + + if second.startswith("hd"): + type2 = 0 + elif second.startswith("sd"): + type2 = 1 + elif (second.startswith("vd") or second.startswith("xvd")): + type2 = -1 + else: + type2 = 2 + + if (type1 < type2): + return -1 + elif (type1 > type2): + return 1 + else: + len1 = len(first) + len2 = len(second) + + if (len1 < len2): + return -1 + elif (len1 > len2): + return 1 + else: + if (first < second): + return -1 + elif (first > second): + return 1 + + return 0 + +def readFSUuid(device): + if not os.path.exists(device): + device = "/dev/%s" % device + + label = _isys.getblkid(device, "UUID") + return label + +def readFSLabel(device): + if not os.path.exists(device): + device = "/dev/%s" % device + + label = _isys.getblkid(device, "LABEL") + return label + +def readFSType(device): + if not os.path.exists(device): + device = "/dev/%s" % device + + fstype = _isys.getblkid(device, "TYPE") + if fstype is None: + # FIXME: libblkid doesn't show physical volumes as having a filesystem + # so let's sniff for that.(#409321) + try: + fd = os.open(device, os.O_RDONLY) + buf = os.read(fd, 2048) + except: + return fstype + finally: + try: + os.close(fd) + except: + pass + + + if fstype == "ext4": + return "ext4dev" + return fstype + +def ext2Clobber(device): + _isys.e2fsclobber(device) + +def ext2IsDirty(device): + label = _isys.e2dirty(device) + return label + +def ext2HasJournal(device): + hasjournal = _isys.e2hasjournal(device); + return hasjournal + +def ejectCdrom(device): + fd = os.open(device, os.O_RDONLY|os.O_NONBLOCK) + + # this is a best effort + try: + _isys.ejectcdrom(fd) + except SystemError, e: + log.warning("error ejecting cdrom (%s): %s" %(device, e)) + pass + + os.close(fd) + +def driveUsesModule(device, modules): + """Returns true if a drive is using a prticular module. Only works + for SCSI devices right now.""" + + if not isinstance(modules, ().__class__) and not \ + isinstance(modules, [].__class__): + modules = [modules] + + if device[:2] == "hd": + return False + rc = False + if os.access("/tmp/scsidisks", os.R_OK): + sdlist=open("/tmp/scsidisks", "r") + sdlines = sdlist.readlines() + sdlist.close() + for l in sdlines: + try: + # each line has format of: <device> <module> + (sddev, sdmod) = string.split(l) + + if sddev == device: + if sdmod in modules: + rc = True + break + except: + pass + return rc + +## Check if a removable media drive (CD, USB key, etc.) has media present. +# @param device The basename of the device node. +# @return True if media is present in device, False otherwise. +def mediaPresent(device): + try: + fd = os.open("/dev/%s" % device, os.O_RDONLY) + except OSError, (errno, strerror): + # error 123 = No medium found + if errno == 123: + return False + else: + return True + else: + os.close(fd) + return True + +def vtActivate(num): + _isys.vtActivate (num) + +def isPsudoTTY(fd): + return _isys.isPseudoTTY(fd) + +## Flush filesystem buffers. +def sync(): + return _isys.sync () + +handleSegv = _isys.handleSegv +printObject = _isys.printObject +isVioConsole = _isys.isVioConsole diff --git a/pkgs/core/pomona/src/isys/lang.c b/pkgs/core/pomona/src/isys/lang.c new file mode 100644 index 0000000..e16bf3a --- /dev/null +++ b/pkgs/core/pomona/src/isys/lang.c @@ -0,0 +1,209 @@ +/* + * lang.c + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <alloca.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <linux/keyboard.h> +#ifdef NR_KEYS +#undef NR_KEYS +#define NR_KEYS 128 +#endif + +#include "linux/kd.h" + +#include "cpio.h" +#include "isys.h" +#include "lang.h" +#include "stubs.h" + +int isysLoadFont(void) { + unsigned char font[65536]; + struct console_font_op cfo; + unsigned short map[E_TABSZ]; + struct unimapdesc d; + struct unimapinit u; + struct unipair desc[2048]; + gzFile stream; + int rc; + +#if defined (__s390__) || defined (__s390x__) + return 0; +#endif + stream = gunzip_open("/etc/screenfont.gz"); + if (!stream) + return -EACCES; + + gunzip_read(stream, &cfo, sizeof(cfo)); + gunzip_read(stream, font, sizeof(font)); + gunzip_read(stream, map, sizeof(map)); + gunzip_read(stream, &d.entry_ct, sizeof(d.entry_ct)); + d.entries = desc; + gunzip_read(stream, desc, d.entry_ct * sizeof(desc[0])); + gunzip_close(stream); + + cfo.data = font; + cfo.op = KD_FONT_OP_SET; + + rc = ioctl(1, KDFONTOP, &cfo); + if (rc) return rc; + rc = ioctl(1, PIO_UNIMAPCLR, &u); + if (rc) return rc; + rc = ioctl(1, PIO_UNIMAP, &d); + if (rc) return rc; + rc = ioctl(1, PIO_UNISCRNMAP, map); + if (rc) return rc; + /* activate the font map */ + fprintf(stderr, "\033(K"); + return 0; +} + +int isysSetUnicodeKeymap(void) { + int console; + +#if defined (__s390__) || defined (__s390x__) + return 0; +#endif + console = open("/dev/console", O_RDWR); + if (console < 0) + return -EACCES; + + /* place keyboard in unicode mode */ + ioctl(console, KDSKBMODE, K_UNICODE); + close(console); + return 0; +} + +/* the file pointer must be at the beginning of the section already! */ +int loadKeymap(gzFile stream) { + int console; + int kmap, key; + struct kbentry entry; + int keymaps[MAX_NR_KEYMAPS]; + int count = 0; + unsigned int magic; + short keymap[NR_KEYS]; + struct stat sb; + +#if defined (__s390__) || defined (__s390x__) + return 0; +#endif + if (isVioConsole()) + return 0; + if (!access("/proc/xen", R_OK)) /* xen can't load keymaps */ + return 0; + + /* assume that if we're already on a pty loading a keymap is silly */ + fstat(0, &sb); + if (major(sb.st_rdev) == 3 || major(sb.st_rdev) == 136) + return 0; + + if (gunzip_read(stream, &magic, sizeof(magic)) != sizeof(magic)) + return -EIO; + + if (magic != KMAP_MAGIC) return -EINVAL; + + if (gunzip_read(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps)) + return -EINVAL; + + console = open("/dev/console", O_RDWR); + if (console < 0) + return -EACCES; + + for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { + if (!keymaps[kmap]) continue; + + if (gunzip_read(stream, keymap, sizeof(keymap)) != sizeof(keymap)) { + close(console); + return -EIO; + } + + count++; + for (key = 0; key < NR_KEYS; key++) { + entry.kb_index = key; + entry.kb_table = kmap; + entry.kb_value = keymap[key]; + if (KTYP(entry.kb_value) != KT_SPEC) { + if (ioctl(console, KDSKBENT, &entry)) { + int ret = errno; + close(console); + return ret; + } + } + } + } + close(console); + return 0; +} + +int isysLoadKeymap(char * keymap) { + int num = -1; + int rc; + gzFile f; + struct kmapHeader hdr; + struct kmapInfo * infoTable; + char buf[16384]; /* I hope this is big enough */ + int i; + + f = gunzip_open("/etc/keymaps.gz"); + if (!f) return -EACCES; + + if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) { + gunzip_close(f); + return -EINVAL; + } + + i = hdr.numEntries * sizeof(*infoTable); + infoTable = alloca(i); + if (gunzip_read(f, infoTable, i) != i) { + gunzip_close(f); + return -EIO; + } + + for (i = 0; i < hdr.numEntries; i++) + if (!strcmp(infoTable[i].name, keymap)) { + num = i; + break; + } + + if (num == -1) { + gunzip_close(f); + return -ENOENT; + } + + for (i = 0; i < num; i++) { + if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) { + gunzip_close(f); + return -EIO; + } + } + + rc = loadKeymap(f); + + gunzip_close(f); + + return rc; +} diff --git a/pkgs/core/pomona/src/isys/lang.h b/pkgs/core/pomona/src/isys/lang.h new file mode 100644 index 0000000..8632bc6 --- /dev/null +++ b/pkgs/core/pomona/src/isys/lang.h @@ -0,0 +1,44 @@ +/* + * lang.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ISYS_LANG_H +#define ISYS_LANG_H + +#include "stubs.h" + +/* define ask johnsonm@redhat.com where this came from */ +#define KMAP_MAGIC 0x8B39C07F +#define KMAP_NAMELEN 40 /* including '\0' */ + +struct kmapHeader { + int magic; + int numEntries; +}; + +struct kmapInfo { + int size; + char name[KMAP_NAMELEN]; +}; + +int loadKeymap(gzFile stream); +int isysLoadFont(void); +int isysLoadKeymap(char * keymap); +int isysSetUnicodeKeymap(void); + +#endif diff --git a/pkgs/core/pomona/src/isys/linkdetect.c b/pkgs/core/pomona/src/isys/linkdetect.c new file mode 100644 index 0000000..1f2fbd6 --- /dev/null +++ b/pkgs/core/pomona/src/isys/linkdetect.c @@ -0,0 +1,180 @@ +/* + * linkdetect.c - simple link detection + * + * pulls code from mii-tool.c in net-toools and ethtool so + * that we can do everything that jgarzik says we should check + * + * Copyright (C) 2002, 2003 Red Hat, Inc. All rights reserved. + * Portions Copyright (C) 2000 David A. Hinds -- dhinds@pcmcia.sourceforge.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Jeremy Katz <katzj@redhat.com> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +#include <sys/socket.h> +#include <sys/types.h> +#include <net/if.h> + +#include <linux/sockios.h> +#include <linux/mii.h> +#include <linux/ethtool.h> +#include "net.h" + +static struct ifreq ifr; + +static int mdio_read(int skfd, int location) +{ + void *data = &ifr.ifr_data; + struct mii_ioctl_data *mii = data; + mii->reg_num = location; + if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { +#ifdef STANDALONE + fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); +#endif + return -1; + } + return mii->val_out; +} + +/* we don't need writing right now */ +#if 0 +static void mdio_write(int skfd, int location, int value) +{ + struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data; + mii->reg_num = location; + mii->val_in = value; + if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) { +#ifdef STANDALONE + fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); +#endif + } +} +#endif + + + +static int get_mii_link_status(int sock) { + int i, mii_val[32]; + + if (ioctl(sock, SIOCGMIIPHY, &ifr) < 0) { + if (errno != ENODEV) +#ifdef STANDALONE + fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n", + ifr.ifr_name, strerror(errno)); +#endif + return -1; + } + + /* Some bits in the BMSR are latched, but we can't rely on being + the only reader, so only the current values are meaningful */ + mdio_read(sock, MII_BMSR); + for (i = 0; i < 8; i++) + mii_val[i] = mdio_read(sock, i); + + if (mii_val[MII_BMCR] == 0xffff) { +#ifdef STANDALONE + fprintf(stderr, " No MII transceiver present!.\n"); +#endif + return -1; + } + + if (mii_val[MII_BMSR] & BMSR_LSTATUS) + return 1; + else + return 0; +} + +static int get_ethtool_link_status(int sock) { + struct ethtool_value edata; + int rc; + + edata.cmd = ETHTOOL_GLINK; + ifr.ifr_data = (caddr_t)&edata; + rc = ioctl(sock, SIOCETHTOOL, &ifr); + if (rc == 0) { + return edata.data; + } else if (errno != EOPNOTSUPP) { +#ifdef STANDALONE + fprintf(stderr, "Cannot get link status (%d): %s\n", errno, strerror(errno)); +#endif + } + + return -1; +} + + + +int get_link_status(char * devname) { + int sock, rc; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { +#ifdef STANDALONE + fprintf(stderr, "Error creating socket: %s\n", strerror(errno)); +#endif + return -1; + } + + /* Setup our control structures. */ + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, devname); + + /* check for link with both ethtool and mii registers. ethtool is + * supposed to be the One True Way (tm), but it seems to not work + * with much yet :/ */ + + rc = get_ethtool_link_status(sock); +#ifdef STANDALONE + printf("ethtool link status of %s is: %d\n", devname, rc); +#endif + if (rc == 1) { + close(sock); + return 1; + } + + rc = get_mii_link_status(sock); +#ifdef STANDALONE + printf("MII link status of %s is: %d\n", devname, rc); +#endif + if (rc == 1) { + close(sock); + return 1; + } + + return 0; +} + +#ifdef STANDALONE +/* hooray for stupid test programs! */ +int main(int argc, char **argv) { + char * dev; + + if (argc >= 2) + dev = argv[1]; + else + dev = strdup("eth0"); + + printf("link status of %s is %d\n", dev, get_link_status(dev)); + return 0; +} +#endif diff --git a/pkgs/core/pomona/src/isys/net.h b/pkgs/core/pomona/src/isys/net.h new file mode 100644 index 0000000..7843286 --- /dev/null +++ b/pkgs/core/pomona/src/isys/net.h @@ -0,0 +1,58 @@ +/* + * net.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ISYSNET_H +#define ISYSNET_H + +#include <linux/types.h> +#include <linux/ethtool.h> + +/* type definitions so that the kernel-ish includes can be shared */ +#ifndef uint8_t +# define uint8_t unsigned char +#endif +#ifndef uint16_t +# define uint16_t unsigned short int +#endif +#ifndef uint32_t +# define uint32_t unsigned int +#endif +#ifndef uint64_t +# define uint64_t unsigned long long int +#endif +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +/* returns 1 for link, 0 for no link, -1 for unknown */ +int get_link_status(char *ifname); + +typedef enum ethtool_speed_t { ETHTOOL_SPEED_UNSPEC = -1, + ETHTOOL_SPEED_10 = SPEED_10, + ETHTOOL_SPEED_100 = SPEED_100, + ETHTOOL_SPEED_1000 = SPEED_1000 } ethtool_speed; +typedef enum ethtool_duplex_t { ETHTOOL_DUPLEX_UNSPEC = -1, + ETHTOOL_DUPLEX_HALF = DUPLEX_HALF, + ETHTOOL_DUPLEX_FULL = DUPLEX_FULL } ethtool_duplex; + +/* set ethtool settings */ +int setEthtoolSettings(char * dev, ethtool_speed speed, ethtool_duplex duplex); + +#endif diff --git a/pkgs/core/pomona/src/isys/smp.c b/pkgs/core/pomona/src/isys/smp.c new file mode 100644 index 0000000..7fee3db --- /dev/null +++ b/pkgs/core/pomona/src/isys/smp.c @@ -0,0 +1,488 @@ +/* + * smp.c + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* +[_Anarchy_(alan@lightning.swansea.uk.linux.org)] you should do one check + though - if the board seems to be SMP and the CPU in /proc/cpuinfo is non + intel dont install an SMP kernel - thats a dual pentium board with a cyrix + or similar single cpu in it +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <string.h> +#include <errno.h> +#include <stdint.h> +#include <sys/types.h> + +/* + * Copyright (c) 1996, by Steve Passe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the developer may NOT be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +/* + * mptable.c + */ + +#define VMAJOR 2 +#define VMINOR 0 +#define VDELTA 12 + +/* + * this will cause the raw mp table to be dumped to /tmp/mpdump + * +#define RAW_DUMP + */ + +#define MP_SIG 0x5f504d5f /* _MP_ */ +#define EXTENDED_PROCESSING_READY +#define OEM_PROCESSING_READY_NOT + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> + +#define LINUX 1 +#if LINUX +typedef uint32_t vm_offset_t; +#else +#include <machine/types.h> +#endif + +/* EBDA is @ 40:0e in real-mode terms */ +#define EBDA_POINTER 0x040e /* location of EBDA pointer */ + +/* CMOS 'top of mem' is @ 40:13 in real-mode terms */ +#define TOPOFMEM_POINTER 0x0413 /* BIOS: base memory size */ + +#define DEFAULT_TOPOFMEM 0xa0000 + +#define BIOS_BASE 0xf0000 +#define BIOS_BASE2 0xe0000 +#define BIOS_SIZE 0x10000 +#define ONE_KBYTE 1024 + +#define GROPE_AREA1 0x80000 +#define GROPE_AREA2 0x90000 +#define GROPE_SIZE 0x10000 + +/* MP Floating Pointer Structure */ +typedef struct MPFPS { + char signature[ 4 ]; + int32_t pap; + u_char length; + u_char spec_rev; + u_char checksum; + u_char mpfb1; + u_char mpfb2; + u_char mpfb3; + u_char mpfb4; + u_char mpfb5; +} mpfps_t; + +/* MP Configuration Table Header */ +typedef struct MPCTH { + char signature[ 4 ]; + uint16_t base_table_length; + u_char spec_rev; + u_char checksum; + char oem_id[ 8 ]; + char product_id[ 12 ]; + int32_t oem_table_pointer; + uint16_t oem_table_size; + uint16_t entry_count; + int32_t apic_address; + uint16_t extended_table_length; + u_char extended_table_checksum; + u_char reserved; +} mpcth_t; + +typedef struct PROCENTRY { + u_char type; + u_char apicID; + u_char apicVersion; + u_char cpuFlags; + uint32_t cpuSignature; + uint32_t featureFlags; + uint32_t reserved1; + uint32_t reserved2; +} ProcEntry; + +#define PROCENTRY_FLAG_EN 0x01 + +static int seekEntry( vm_offset_t addr ); +static void apic_probe( vm_offset_t* paddr, int* where ); +static void readEntry( void* entry, int size ); + +/* global data */ +static int pfd; /* physical /dev/mem fd */ +static int verbose = 0; +static int grope = 0; + +static int readType() { + u_char type; + + if ( read( pfd, &type, sizeof( u_char ) ) != sizeof( u_char ) ) { +/* perror( "type read" ); */ +/* fprintf( stderr, "\npfd: %d", pfd ); */ +/* fflush( stderr ); */ +/* exit( 1 ); */ + return -1; + } + + if ( lseek( pfd, -1, SEEK_CUR ) < 0 ) { +/* perror( "type seek" ); */ +/* exit( 1 ); */ + return -1; + } + + return (int)type; +} + +#define MODE_SMP_CHECK 1 + +static int groupForSMP(int mode) { + vm_offset_t paddr; + int where; + mpfps_t mpfps; + int rc = 0; + int ncpus = 0; + + /* open physical memory for access to MP structures */ + if ( (pfd = open( "/dev/mem", O_RDONLY )) < 0 ) { + return 0; + } + + /* probe for MP structures */ + apic_probe( &paddr, &where ); + if ( where <= 0 ) + return 0; + + if (seekEntry( paddr )) + return 0; + readEntry( &mpfps, sizeof( mpfps_t ) ); + + if (mpfps.mpfb1) + /* old style */ + rc = 1; + else { + /* go to the config table */ + mpcth_t cth; + int count, i; + + paddr = (vm_offset_t) mpfps.pap; + if (seekEntry( paddr )) + return 0; + readEntry( &cth, sizeof( cth ) ); + /* if we don't have any entries, the kernel sure + won't be able to set up mp. Needs at least one entry + for smp kernel */ + if (cth.entry_count <= 1) { + close (pfd); + return 0; + } + + count = cth.entry_count; + for (i = 0; i < count; i++) { + if ( readType() == 0 ) { + ProcEntry entry; + readEntry( &entry, sizeof( entry ) ); + if (entry.cpuFlags & PROCENTRY_FLAG_EN) + ncpus++; + } + } + if (ncpus > 1) + rc = 1; + } + + close (pfd); + return rc; +} + +/* + * set PHYSICAL address of MP floating pointer structure + */ +#define NEXT(X) ((X) += 4) +static void +apic_probe( vm_offset_t* paddr, int* where ) { + /* + * c rewrite of apic_probe() by Jack F. Vogel + */ + + unsigned int x; + uint16_t segment; + vm_offset_t target; + uint32_t buffer[ BIOS_SIZE / sizeof( int32_t ) ]; + + if ( verbose ) + printf( "\n" ); + + /* search Extended Bios Data Area, if present */ + if ( verbose ) + printf( " looking for EBDA pointer @ 0x%04x, ", EBDA_POINTER ); + if (seekEntry( (vm_offset_t)EBDA_POINTER )) { + *where = 0; + *paddr = (vm_offset_t)0; + return; + } + readEntry( &segment, 2 ); + if ( segment ) { /* search EBDA */ + target = (vm_offset_t)segment << 4; + if ( verbose ) + printf( "found, searching EBDA @ 0x%08x\n", target ); + if (seekEntry( target )) { + *where = 0; + *paddr = (vm_offset_t)0; + return; + } + readEntry( buffer, ONE_KBYTE ); + + for ( x = 0; x < ONE_KBYTE / sizeof ( uint32_t ); NEXT(x) ) { + if ( buffer[ x ] == MP_SIG ) { + *where = 1; + *paddr = (x * sizeof( uint32_t )) + target; + return; + } + } + + } + else { + if ( verbose ) + printf( "NOT found\n" ); + } + + /* read CMOS for real top of mem */ + if (seekEntry( (vm_offset_t)TOPOFMEM_POINTER )) { + *where = 0; + *paddr = (vm_offset_t)0; + return; + } + readEntry( &segment, 2 ); + --segment; /* less ONE_KBYTE */ + target = segment * 1024; + if ( verbose ) + printf( " searching CMOS 'top of mem' @ 0x%08x (%dK)\n", + target, segment ); + seekEntry( target ); + readEntry( buffer, ONE_KBYTE ); + + for ( x = 0; x < ONE_KBYTE / sizeof ( uint32_t ); NEXT(x) ) { + if ( buffer[ x ] == MP_SIG ) { + *where = 2; + *paddr = (x * sizeof( uint32_t )) + target; + return; + } + } + + /* we don't necessarily believe CMOS, check base of the last 1K of 640K */ + if ( target != (DEFAULT_TOPOFMEM - 1024)) { + target = (DEFAULT_TOPOFMEM - 1024); + if ( verbose ) + printf( " searching default 'top of mem' @ 0x%08x (%dK)\n", + target, (target / 1024) ); + seekEntry( target ); + readEntry( buffer, ONE_KBYTE ); + + for ( x = 0; x < ONE_KBYTE / sizeof ( uint32_t ); NEXT(x) ) { + if ( buffer[ x ] == MP_SIG ) { + *where = 3; + *paddr = (x * sizeof( uint32_t )) + target; + return; + } + } + } + + /* search the BIOS */ + if ( verbose ) + printf( " searching BIOS @ 0x%08x\n", BIOS_BASE ); + seekEntry( BIOS_BASE ); + readEntry( buffer, BIOS_SIZE ); + + for ( x = 0; x < BIOS_SIZE / sizeof( uint32_t ); NEXT(x) ) { + if ( buffer[ x ] == MP_SIG ) { + *where = 4; + *paddr = (x * sizeof( uint32_t )) + BIOS_BASE; + return; + } + } + + /* search the extended BIOS */ + if ( verbose ) + printf( " searching extended BIOS @ 0x%08x\n", BIOS_BASE2 ); + seekEntry( BIOS_BASE2 ); + readEntry( buffer, BIOS_SIZE ); + + for ( x = 0; x < BIOS_SIZE / sizeof( uint32_t ); NEXT(x) ) { + if ( buffer[ x ] == MP_SIG ) { + *where = 5; + *paddr = (x * sizeof( uint32_t )) + BIOS_BASE2; + return; + } + } + + if ( grope ) { + /* search additional memory */ + target = GROPE_AREA1; + if ( verbose ) + printf( " groping memory @ 0x%08x\n", target ); + seekEntry( target ); + readEntry( buffer, GROPE_SIZE ); + + for ( x = 0; x < GROPE_SIZE / sizeof( uint32_t ); NEXT(x) ) { + if ( buffer[ x ] == MP_SIG ) { + *where = 6; + *paddr = (x * sizeof( uint32_t )) + GROPE_AREA1; + return; + } + } + + target = GROPE_AREA2; + if ( verbose ) + printf( " groping memory @ 0x%08x\n", target ); + seekEntry( target ); + readEntry( buffer, GROPE_SIZE ); + + for ( x = 0; x < GROPE_SIZE / sizeof( uint32_t ); NEXT(x) ) { + if ( buffer[ x ] == MP_SIG ) { + *where = 7; + *paddr = (x * sizeof( uint32_t )) + GROPE_AREA2; + return; + } + } + } + + *where = 0; + *paddr = (vm_offset_t)0; +} + +/* + * + */ +static int seekEntry( vm_offset_t addr ) { + if ( lseek( pfd, (off_t)addr, SEEK_SET ) < 0 ) { + return 1; + } + return 0; +} + +/* + * + */ +static void readEntry( void* entry, int size ) { + if ( read( pfd, entry, size ) != size ) { + return; + perror( "readEntry" ); + exit( 1 ); + } +} + +static int intelDetectSMP(void) { + return groupForSMP(MODE_SMP_CHECK); +} + +/* ---- end mptable mess ---- */ + +static inline unsigned int cpuid_ebx(int op) { + unsigned int eax, ebx; + + __asm__("pushl %%ebx; cpuid; movl %%ebx,%1; popl %%ebx" + : "=a" (eax), "=g" (ebx) + : "0" (op) + : "cx", "dx"); + return ebx; +} + +/* XXX: rewrite using /proc/cpuinfo info if it there. Only fall + back to inline asm if it is not */ +int detectHT(void) { + FILE *f; + int htflag = 0; + uint32_t ebx = 0; + int smp_num_siblings = 0; + + f = fopen("/proc/cpuinfo", "r"); + if (f) { + char buff[1024]; + + while (fgets (buff, 1024, f) != NULL) { + if (!strncmp (buff, "flags\t\t:", 8)) { + if (strstr(buff, " ht ") || + /* buff includes \n, so back up 4 bytes from the end + and check there too to catch the end case */ + !strncmp(buff + strlen(buff) - 4, " ht", 3)) { + htflag = 1; + } + break; + } + } + fclose(f); + } + if (!htflag) + return 0; + + ebx = cpuid_ebx(1); + smp_num_siblings = (ebx & 0xff0000) >> 16; + + if (smp_num_siblings >= 2) + return 1; + return 0; +} + +int detectSMP(void) +{ + static int isSMP = -1; + + if (isSMP != -1) + return isSMP; + +#if defined (__i386__) + return isSMP = intelDetectSMP(); +#else + #error unknown architecture +#endif +} diff --git a/pkgs/core/pomona/src/isys/smp.h b/pkgs/core/pomona/src/isys/smp.h new file mode 100644 index 0000000..651fa33 --- /dev/null +++ b/pkgs/core/pomona/src/isys/smp.h @@ -0,0 +1,26 @@ +/* + * smp.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SMP_H +#define SMP_H + +int detectSMP(void); +int detectHT(void); + +#endif /* SMP_H */ diff --git a/pkgs/core/pomona/src/isys/str.c b/pkgs/core/pomona/src/isys/str.c new file mode 100644 index 0000000..cf05473 --- /dev/null +++ b/pkgs/core/pomona/src/isys/str.c @@ -0,0 +1,125 @@ +/* + * str.c - String helper functions that don't need string.h or ctype.h + * + * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): David Cantrell <dcantrell@redhat.com> + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "str.h" + +/** + * Called by str2upper() or str2lower() to do the actual work. + * + * @param str String to convert. + * @param lower Lower bound for the character range (e.g., a - z). + * @param upper Upper bound for the character range (e.g., a - z). + * @param shift Shift value (32 for lowercase, -32 for uppercase). + * @return Pointer to str. + */ +char *str2case(char *str, char lower, char upper, int shift) { + char *tmp; + + if (str == NULL) + return NULL; + + /* man ascii(7) */ + tmp = str; + while (*tmp != '\0') { + if (*tmp >= lower && *tmp <= upper) + *tmp += shift; + + tmp++; + } + + return str; +} + +/** + * Convert given string to uppercase. Modifies the argument in the caller's + * stack. If you must ask simply "why?" for this function, it's so we don't + * need toupper() and the same for loop all over the place. + * + * LIMITATIONS: Only deals with ASCII character set. + * + * @param str String to convert to uppercase. + * @return Pointer to str. + */ +char *str2upper(char *str) { + return str2case(str, 'a', 'z', -32); +} + +/** + * Convert given string to lowercase. Modifies the argument in the caller's + * stack. If you must ask simply "why?" for this function, it's so we don't + * need tolower() and the same for loop all over the place. + * + * LIMITATIONS: Only deals with ASCII character set. + * + * @param str String to convert to lowercase. + * @return Pointer to str. + */ +char *str2lower(char *str) { + return str2case(str, 'A', 'Z', 32); +} + +/** + * Pretty much an exact copy of index(3) from the C library. + * @param str String to scan. + * @param ch Character to scan for. + * @return Position of ch in str, NULL if not found. + */ +char *strindex(char *str, int ch) { + if (str == NULL) + return NULL; + + do { + if (*str == ch) + return str; + else + str++; + } while (*str != '\0'); + + return NULL; +} + +/** + * Return number of occurrences of a character in a string. + * @param str String to scan. + * @param ch Character to scan for. + * @return Number of occurrences of ch in str. + */ +int strcount(char *str, int ch) { + int retval = 0; + char *tmp = str; + + if (tmp == NULL) + return retval; + + do { + if ((tmp = strindex(tmp, ch)) != NULL) { + tmp++; + retval++; + } + } while (tmp != NULL); + + return retval; +} + +/* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/pkgs/core/pomona/src/isys/str.h b/pkgs/core/pomona/src/isys/str.h new file mode 100644 index 0000000..d296021 --- /dev/null +++ b/pkgs/core/pomona/src/isys/str.h @@ -0,0 +1,29 @@ +/* + * str.c - String helper functions, the header file + * + * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): David Cantrell <dcantrell@redhat.com> + */ + +/* Function prototypes */ +char *str2case(char *str, char lower, char upper, int shift); +char *str2upper(char *str); +char *str2lower(char *str); +int strcount(char *str, int ch); +char *strindex(char *str, int ch); + +/* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/pkgs/core/pomona/src/isys/stubs.h b/pkgs/core/pomona/src/isys/stubs.h new file mode 100644 index 0000000..ddf5c8d --- /dev/null +++ b/pkgs/core/pomona/src/isys/stubs.h @@ -0,0 +1,44 @@ +/* + * stubs.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* we use gzlib when linked against dietlibc, but otherwise, we should use + zlib. it would make more sense to do the defines in the other direction, + but that causes symbol wackiness because both gunzip_open and gzip_open in + gzlib are gzopen from zlib +*/ + +#ifndef ISYS_STUB +#define ISYS_STUB + +#ifndef GZLIB +#include <zlib.h> + +#define gunzip_open(x) gzopen(x, "r") +#define gunzip_dopen gzdopen(x, "r") +#define gunzip_close gzclose +#define gunzip_read gzread +#define gzip_write gzwrite +#define gzip_open(x, y, z) gzopen(x, "w") + +#else +#include "gzlib/gzlib.h" + +#endif + +#endif diff --git a/pkgs/core/pomona/src/isys/sundries.h b/pkgs/core/pomona/src/isys/sundries.h new file mode 100644 index 0000000..1fb67b8 --- /dev/null +++ b/pkgs/core/pomona/src/isys/sundries.h @@ -0,0 +1,88 @@ +/* + * sundries.h: Support function prototypes. Functions are in sundries.c. + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <sys/types.h> +#include <fcntl.h> +#include <limits.h> +#include <signal.h> +#include <stdarg.h> +#include <stdlib.h> +#if !defined(bool_t) && !defined(__GLIBC__) +#include <rpc/types.h> +#endif + +extern int mount_quiet; +extern int verbose; +extern int sloppy; + +#define streq(s, t) (strcmp ((s), (t)) == 0) + + +/* String list data structure. */ +typedef struct string_list +{ + char *hd; + struct string_list *tl; +} *string_list; + +#define car(p) ((p) -> hd) +#define cdr(p) ((p) -> tl) + +string_list cons (char *a, const string_list); + +/* Functions in sundries.c that are used in mount.c and umount.c */ +void block_signals (int how); +char *canonicalize (const char *path); +char *realpath (const char *path, char *resolved_path); +void error (const char *fmt, ...); +int matching_type (const char *type, string_list types); +string_list parse_list (char *strings); +void *xmalloc (size_t size); +char *xstrdup (const char *s); +char *xstrndup (const char *s, int n); +char *xstrconcat2 (const char *, const char *); +char *xstrconcat3 (const char *, const char *, const char *); +char *xstrconcat4 (const char *, const char *, const char *, const char *); + +/* Here is some serious cruft. */ +#ifdef __GNUC__ +#if __GNUC__ > 2 || (defined(__GNUC_MINOR__) && __GNUC__ == 2 && __GNUC_MINOR__ >= 5) +void die (int errcode, const char *fmt, ...) __attribute__ ((noreturn)); +#else /* GNUC < 2.5 */ +void volatile die (int errcode, const char *fmt, ...); +#endif /* GNUC < 2.5 */ +#else /* !__GNUC__ */ +void die (int errcode, const char *fmt, ...); +#endif /* !__GNUC__ */ + +#ifdef HAVE_NFS +int nfsmount (const char *spec, const char *node, int *flags, + char **orig_opts, char **opt_args, int running_bg); +#endif + +/* exit status - bits below are ORed */ +#define EX_USAGE 1 /* incorrect invocation or permission */ +#define EX_SYSERR 2 /* out of memory, cannot fork, ... */ +#define EX_SOFTWARE 4 /* internal mount bug or wrong version */ +#define EX_USER 8 /* user interrupt */ +#define EX_FILEIO 16 /* problems writing, locking, ... mtab/fstab */ +#define EX_FAIL 32 /* mount failure */ +#define EX_SOMEOK 64 /* some mount succeeded */ + +#define EX_BG 256 /* retry in background (internal only) */ diff --git a/pkgs/core/pomona/src/isys/vio.c b/pkgs/core/pomona/src/isys/vio.c new file mode 100644 index 0000000..55f497f --- /dev/null +++ b/pkgs/core/pomona/src/isys/vio.c @@ -0,0 +1,106 @@ +/* + * vio.c - probing for vio devices on the iSeries (viocd and viodasd) + * + * Copyright (C) 2003 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Jeremy Katz <katzj@redhat.com> + */ + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#if defined(__powerpc__) +static int readFD (int fd, char **buf) +{ + char *p; + size_t size = 4096; + int s, filesize; + + *buf = malloc (size); + if (*buf == 0) + return -1; + + filesize = 0; + do { + p = &(*buf) [filesize]; + s = read (fd, p, 4096); + if (s < 0) + break; + filesize += s; + if (s == 0) + break; + size += 4096; + *buf = realloc (*buf, size); + } while (1); + + if (filesize == 0 && s < 0) { + free (*buf); + *buf = NULL; + return -1; + } + + return filesize; +} +#endif + +int isVioConsole(void) { +#if !defined(__powerpc__) + return 0; +#else + int fd, i; + char *buf, *start; + char driver[50], device[50]; + static int isviocons = -1; + + if (isviocons != -1) + return isviocons; + + fd = open("/proc/tty/drivers", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "failed to open /proc/tty/drivers!\n"); + return 0; + } + i = readFD(fd, &buf); + if (i < 1) { + close(fd); + fprintf(stderr, "error reading /proc/tty/drivers!\n"); + return 0; + } + close(fd); + buf[i] = '\0'; + + isviocons = 0; + start = buf; + while (start && *start) { + if (sscanf(start, "%s %s", (char *) &driver, (char *) &device) == 2) { + if (!strcmp(driver, "vioconsole") && !strcmp(device, "/dev/tty")) { + isviocons = 1; + break; + } + } + start = strchr(start, '\n'); + if (start) + start++; + } + free(buf); + return isviocons; +#endif +} diff --git a/pkgs/core/pomona/src/isys/wireless.c b/pkgs/core/pomona/src/isys/wireless.c new file mode 100644 index 0000000..ed43d97 --- /dev/null +++ b/pkgs/core/pomona/src/isys/wireless.c @@ -0,0 +1,279 @@ +/* + * wireless.c - wireless card manipulation + * Some portions from wireless_tools + * copyright (c) 1997-2003 Jean Tourrilhes <jt@hpl.hp.com> + * + * Copyright (C) 2004 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Jeremy Katz <katzj@redhat.com> + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#include <sys/socket.h> +#include <sys/types.h> + +#include <linux/types.h> +#include <linux/if.h> +#include <linux/wireless.h> + +static struct iwreq get_wreq(char * ifname) { + struct iwreq wreq; + + memset(&wreq, 0, sizeof(wreq)); + strncpy(wreq.ifr_name, ifname, IFNAMSIZ); + return wreq; +} + +static int get_socket() { + int sock; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { +#ifdef STANDALONE + fprintf(stderr, "Error creating socket: %s\n", strerror(errno)); +#endif + return -1; + } + + return sock; +} + +int is_wireless_interface(char * ifname) { + int sock = get_socket(); + struct iwreq wreq = get_wreq(ifname); + + int rc = ioctl(sock, SIOCGIWNAME, &wreq); + close(sock); + + if (rc < 0) { + return 0; + } + + return 1; +} + +/* set the essid for ifname to essid. if essid is NULL, do automatically */ +int set_essid(char * ifname, char * essid) { + int sock; + struct iwreq wreq; + + memset(&wreq, 0, sizeof (wreq)); + + if (strlen(essid) > IW_ESSID_MAX_SIZE) { + fprintf(stderr, "essid too long\n"); + return -1; + } + + sock = get_socket(); + wreq = get_wreq(ifname); + + if (essid) { + wreq.u.essid.flags = 1; + wreq.u.essid.pointer = (caddr_t) essid; + wreq.u.essid.length = strlen(essid) + 1; + } else { + wreq.u.essid.flags = 0; + wreq.u.essid.pointer = (caddr_t) NULL; + wreq.u.essid.length = 0; + } + + int rc = ioctl(sock, SIOCSIWESSID, &wreq); + close(sock); + + if (rc < 0) { + fprintf(stderr, "failed to set essid: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +char * get_essid(char * ifname) { + int sock; + struct iwreq wreq; + + memset(&wreq, 0, sizeof (wreq)); + + sock = get_socket(); + wreq = get_wreq(ifname); + + wreq.u.essid.pointer = (caddr_t) malloc(IW_ESSID_MAX_SIZE + 1); + wreq.u.essid.length = IW_ESSID_MAX_SIZE + 1; + wreq.u.essid.flags = 0; + int rc = ioctl(sock, SIOCGIWESSID, &wreq); + close(sock); + + if (rc < 0) { + fprintf(stderr, "failed to get essid for %s: %s\n", ifname, + strerror(errno)); + return NULL; + } + + return wreq.u.essid.pointer; +} + +/* based off iw_in_key from wireless-tools/iwlib.c */ +static int parse_wep_key(char * in, unsigned char * key) { + int len = 0; + + if (!strncmp(in, "s:", 2)) { + /* the key is a string */ + len = strlen(in + 2); + memmove(key, in + 2, len); + } else { + char *buff, *hex, *out, *p; + + /* hexadecimal digits, straight from iwlib.c */ + buff = malloc(IW_ENCODING_TOKEN_MAX + strlen(in) + 1); + if(buff == NULL) { + fprintf(stderr, "Malloc failed (string too long ?)\n"); + return(-1); + } + /* Preserve original buffers (both in & out) */ + hex = buff + IW_ENCODING_TOKEN_MAX; + strcpy(hex, in); + out = buff; + /* Parse */ + p = strtok(hex, "-:;.,"); + while((p != (char *) NULL) && (len < IW_ENCODING_TOKEN_MAX)) { + int temph, templ, count, l; + + /* Get each char separatly (and not by two) so that we don't + * get confused by 'enc' (=> '0E'+'0C') and similar */ + count = sscanf(p, "%1X%1X", &temph, &templ); + if(count < 1) + return(-1); /* Error -> non-hex char */ + /* Fixup odd strings such as '123' is '01'+'23' and not '12'+'03'*/ + l = strlen(p); + if(l % 2) + count = 1; + /* Put back two chars as one byte */ + if(count == 2) + templ |= temph << 4; + else + templ = temph; + out[len++] = (unsigned char) (templ & 0xFF); + /* Check where to get next char from */ + if(l > count) /* Token not finished yet */ + p += count; + else + p = strtok((char *) NULL, "-:;.,"); + } + memcpy(key, out, len); + free(buff); + } + + return len; +} + +int set_wep_key(char * ifname, char * key) { + int sock; + struct iwreq wreq; + unsigned char thekey[IW_ENCODING_TOKEN_MAX]; + + if (strlen(key) > IW_ENCODING_TOKEN_MAX) { + fprintf(stderr, "wep key too long\n"); + return -1; + } + + sock = get_socket(); + wreq = get_wreq(ifname); + + if (key) { + int len = parse_wep_key(key, thekey); + if (len > 0) { + wreq.u.data.flags = IW_ENCODE_ENABLED; + wreq.u.data.length = len; + wreq.u.data.pointer = (caddr_t) thekey; + } + } else { + wreq.u.data.flags = IW_ENCODE_DISABLED; + wreq.u.data.pointer = (caddr_t) NULL; + wreq.u.data.length = 0; + } + + int rc = ioctl(sock, SIOCSIWENCODE, &wreq); + close(sock); + + if (rc < 0) { + fprintf(stderr, "failed to set wep key: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +enum { MODE_AUTO, MODE_ADHOC, MODE_MANAGED, MODE_MASTER, MODE_REPEATER, + MODE_SECONDARY, MODE_MONITOR }; + +int set_managed(char * ifname) { + int sock = get_socket(); + struct iwreq wreq = get_wreq(ifname); + + wreq.u.mode = MODE_MANAGED; + int rc = ioctl(sock, SIOCSIWMODE, &wreq); + close(sock); + + if (rc < 0) { + fprintf(stderr, "failed to set managed mode: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +#ifdef STANDALONE +int main(int argc, char **argv) { + if (argc < 4) { + fprintf(stderr, "Usage: %s [interface] [essid] [key]\n", argv[0]); + exit(1); + } + + if (!is_wireless_interface(argv[1])) { + fprintf(stderr, "%s isn't a wireless interface!\n", argv[1]); + exit(2); + } + + /* if (set_essid(argv[1], NULL) < 0) { + fprintf(stderr, "Unable to set essid to %s\n", argv[2]); + exit(3); + } + exit(0);*/ + + if (set_essid(argv[1], argv[2]) < 0) { + fprintf(stderr, "Unable to set essid to %s\n", argv[2]); + exit(3); + } + + /* if (set_wep_key(argv[1], NULL) < 0) { + fprintf(stderr, "Unable to set wepkey to %s\n", argv[2]); + exit(4); + } + exit(0);*/ + + if (set_wep_key(argv[1], argv[3]) < 0) { + fprintf(stderr, "Unable to set wepkey to %s\n", argv[2]); + exit(4); + } + + return 0; +} +#endif diff --git a/pkgs/core/pomona/src/isys/wireless.h b/pkgs/core/pomona/src/isys/wireless.h new file mode 100644 index 0000000..82cb4d4 --- /dev/null +++ b/pkgs/core/pomona/src/isys/wireless.h @@ -0,0 +1,29 @@ +/* + * wireless.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef WIRELESS_H +#define WIRELESS_H + +int is_wireless_interface(char * ifname); +int set_essid(char * ifname, char * essid); +char * get_essid(char * ifname); +int set_wep_key(char * ifname, char * key); +int set_managed(char * ifname); + +#endif diff --git a/pkgs/core/pomona/src/iutil.py b/pkgs/core/pomona/src/iutil.py new file mode 100644 index 0000000..569ea8d --- /dev/null +++ b/pkgs/core/pomona/src/iutil.py @@ -0,0 +1,333 @@ +# +# iutil.py - generic install utility functions +# +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 +# Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Erik Troan <ewt@redhat.com> +# + +import os, string, stat +import os.path +from errno import * +import warnings +import subprocess +from flags import flags + +import logging +log = logging.getLogger("pomona") + +## Run an external program and redirect the output to a file. +# @param command The command to run. +# @param argv A list of arguments. +# @param stdin The file descriptor to read stdin from. +# @param stdout The file descriptor to redirect stdout to. +# @param stderr The file descriptor to redirect stderr to. +# @param searchPath Should command be searched for in $PATH? +# @param root The directory to chroot to before running command. +# @return The return code of command. +def execWithRedirect(command, argv, stdin = 0, stdout = 1, stderr = 2, + searchPath = 0, root = '/'): + def chroot (): + os.chroot(root) + + if not searchPath and not os.access (command, os.X_OK): + raise RuntimeError, command + " can not be run" + + argv = list(argv) + if type(stdin) == type("string"): + if os.access(stdin, os.R_OK): + stdin = open(stdin) + else: + stdin = 0 + if type(stdout) == type("string"): + stdout = open(stdout, "w") + if type(stderr) == type("string"): + stderr = open(stderr, "w") + + if stdout is not None and type(stdout) != int: + stdout.write("Running... %s\n" %([command] + argv,)) + + try: + proc = subprocess.Popen([command] + argv, stdin=stdin, stdout=stdout, + stderr=stderr, preexec_fn=chroot, cwd=root) + ret = proc.wait() + except OSError, (errno, msg): + errstr = "Error running %s: %s" % (command, msg) + log.error (errstr) + raise RuntimeError, errstr + + return ret + +## Run an external program and capture standard out. +# @param command The command to run. +# @param argv A list of arguments. +# @param stdin The file descriptor to read stdin from. +# @param stderr The file descriptor to redirect stderr to. +# @param root The directory to chroot to before running command. +# @return The output of command from stdout. +def execWithCapture(command, argv, stdin = 0, stderr = 2, root='/'): + def chroot(): + os.chroot(root) + + argv = list(argv) + if type(stdin) == type("string"): + if os.access(stdin, os.R_OK): + stdin = open(stdin) + else: + stdin = 0 + if type(stderr) == type("string"): + stderr = open(stderr, "w") + + try: + pipe = subprocess.Popen([command] + argv, stdin=stdin, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + preexec_fn=chroot, cwd=root) + except OSError, (errno, msg): + log.error ("Error running " + command + ": " + msg) + raise RuntimeError, "Error running " + command + ": " + msg + + rc = pipe.stdout.read() + pipe.wait() + return rc + +def execWithPulseProgress(command, argv, stdin = 0, stdout = 1, stderr = 2, + progress = None, root = '/'): + def chroot(): + os.chroot(root) + + argv = list(argv) + if type(stdin) == type("string"): + if os.access(stdin, os.R_OK): + stdin = open(stdin) + else: + stdin = 0 + if type(stdout) == type("string"): + stdout = open(stdout, "w") + if type(stderr) == type("string"): + stderr = open(stderr, "w") + if stdout is not None and type(stdout) != int: + stdout.write("Running... %s\n" %([command] + argv,)) + + p = os.pipe() + childpid = os.fork() + if not childpid: + os.close(p[0]) + os.dup2(p[1], 1) + os.dup2(stderr.fileno(), 2) + os.dup2(stdin, 0) + os.close(stdin) + os.close(p[1]) + stderr.close() + + os.execvp(command, [command] + argv) + os._exit(1) + + os.close(p[1]) + + while 1: + try: + s = os.read(p[0], 1) + except OSError, args: + (num, str) = args + if (num != 4): + raise IOError, args + + stdout.write(s) + if progress: progress.pulse() + + if len(s) < 1: + break + + try: + (pid, status) = os.waitpid(childpid, 0) + except OSError, (num, msg): + log.critical("exception from waitpid: %s %s" %(num, msg)) + + progress and progress.pop() + + # *shrug* no clue why this would happen, but hope that things are fine + if status is None: + return 0 + + if os.WIFEXITED(status): + return os.WEXITSTATUS(status) + + return 1 + +## Run a shell. +def execConsole(): + try: + proc = subprocess.Popen(["/bin/sh"]) + proc.wait() + except OSError, (errno, msg): + raise RuntimeError, "Error running /bin/sh: " + msg + +## Get the size of a directory and all its subdirectories. +# @param dir The name of the directory to find the size of. +# @return The size of the directory in kilobytes. +def getDirSize(dir): + def getSubdirSize(dir): + # returns size in bytes + mydev = os.lstat(dir)[stat.ST_DEV] + + dsize = 0 + for f in os.listdir(dir): + curpath = '%s/%s' % (dir, f) + sinfo = os.lstat(curpath) + if stat.S_ISDIR(sinfo[stat.ST_MODE]): + if mydev == sinfo[stat.ST_DEV]: + dsize += getSubdirSize(curpath) + elif stat.S_ISREG(sinfo[stat.ST_MODE]): + dsize += sinfo[stat.ST_SIZE] + else: + pass + + return dsize + return getSubdirSize(dir)/1024 + +## Get the amount of RAM not used by /tmp. +# @return The amount of available memory in kilobytes. +def memAvailable(): + tram = memInstalled() + + ramused = getDirSize("/tmp") + return tram - ramused + +## Get the amount of RAM installed in the machine. +# @return The amount of installed memory in kilobytes. +def memInstalled(): + f = open("/proc/meminfo", "r") + lines = f.readlines() + f.close() + + for l in lines: + if l.startswith("MemTotal:"): + fields = string.split(l) + mem = fields[1] + break + + return int(mem) + +## Suggest the size of the swap partition that will be created. +# @param quiet Should size information be logged? +# @return A tuple of the minimum and maximum swap size, in megabytes. +def swapSuggestion(quiet=0): + mem = memInstalled()/1024 + mem = ((mem/16)+1)*16 + if not quiet: + log.info("Detected %sM of memory", mem) + + if mem <= 256: + minswap = 256 + maxswap = 512 + else: + if mem > 2000: + minswap = 1000 + maxswap = 2000 + mem + else: + minswap = mem + maxswap = 2*mem + + if not quiet: + log.info("Swap attempt of %sM to %sM", minswap, maxswap) + + return (minswap, maxswap) + +## Create a directory path. Don't fail if the directory already exists. +# @param dir The directory path to create. +def mkdirChain(dir): + try: + os.makedirs(dir, 0755) + except OSError, (errno, msg): + try: + if errno == EEXIST and stat.S_ISDIR(os.stat(dir).st_mode): + return + except: + pass + + log.error("could not create directory %s: %s" % (dir, msg)) + +## Get the total amount of swap memory. +# @return The total amount of swap memory in kilobytes, or 0 if unknown. +def swapAmount(): + f = open("/proc/meminfo", "r") + lines = f.readlines() + f.close() + + for l in lines: + if l.startswith("SwapTotal:"): + fields = string.split(l) + return int(fields[1]) + return 0 + +## Copy a device node. +# Copies a device node by looking at the device type, major and minor device +# numbers, and doing a mknod on the new device name. +# +# @param src The name of the source device node. +# @param dest The name of the new device node to create. +def copyDeviceNode(src, dest): + filestat = os.lstat(src) + mode = filestat[stat.ST_MODE] + if stat.S_ISBLK(mode): + type = stat.S_IFBLK + elif stat.S_ISCHR(mode): + type = stat.S_IFCHR + else: + # XXX should we just fallback to copying normally? + raise RuntimeError, "Tried to copy %s which isn't a device node" % (src,) + + os.mknod(dest, mode | type, filestat.st_rdev) + +# Architecture checking functions + +def isX86(bits=None): + arch = os.uname()[4] + + # x86 platforms include: + # i*86 + # athlon* + # x86_64 + # amd* + # ia32e + if bits is None: + if (arch.startswith('i') and arch.endswith('86')) or \ + arch.startswith('athlon') or arch.startswith('amd') or \ + arch == 'x86_64' or arch == 'ia32e': + return True + elif bits == 32: + if arch.startswith('i') and arch.endswith('86'): + return True + elif bits == 64: + if arch.startswith('athlon') or arch.startswith('amd') or \ + arch == 'x86_64' or arch == 'ia32e': + return True + + return False + +def getArch(): + if isX86(bits=32): + return 'i386' + elif isX86(bits=64): + return 'x86_64' + else: + return os.uname()[4] + +def isConsoleOnVirtualTerminal(): + # XXX PJFIX is there some way to ask the kernel this instead? + return not flags.serial diff --git a/pkgs/core/pomona/src/keyboard_models.py b/pkgs/core/pomona/src/keyboard_models.py new file mode 100644 index 0000000..76c0e41 --- /dev/null +++ b/pkgs/core/pomona/src/keyboard_models.py @@ -0,0 +1,259 @@ +#!/usr/bin/python -tt +# +# keyboard_models.py - keyboard model list +# +# Brent Fox <bfox@redhat.com> +# Mike Fulbright <msf@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# +# Copyright 2002-2007 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) +N_ = lambda x: x + +def gkn(str): + idx = str.find("|") + if idx == -1: + return str + return str[idx + 1:] + +class KeyboardModels: + def get_models(self): + return self.modelDict + + def __init__(self): + # NOTE: to add a keyboard model to this dict, copy the comment + # above all of them, and then the key should be the console layout + # name. val is [N_('keyboard|Keyboard Name'), xlayout, kbmodel, + # variant, options] + self._modelDict = { + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ar-azerty' : [N_('keyboard|Arabic (azerty)'), 'us,ara', 'pc105', 'azerty', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ar-azerty-digits' : [N_('keyboard|Arabic (azerty/digits)'), 'us,ara', 'pc105', 'azerty_digits', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ar-digits' : [N_('keyboard|Arabic (digits)'), 'us,ara', 'pc105', 'digits', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ar-qwerty' : [N_('keyboard|Arabic (qwerty)'), 'us,ara', 'pc105', 'qwerty', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ar-qwerty-digits' : [N_('keyboard|Arabic (qwerty/digits)'), 'us,ara', 'pc105', 'qwerty_digits', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'be-latin1' : [N_('keyboard|Belgian (be-latin1)'), 'be', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ben' : [N_('keyboard|Bengali (Inscript)'), 'us,in', 'pc105', 'ben', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ben-probhat' : [N_('keyboard|Bengali (Probhat)'), 'us,in', 'pc105', 'ben_probhat', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'bg_bds-utf8' : [N_('keyboard|Bulgarian'), 'us,bg', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'bg_pho-utf8' : [N_('keyboard|Bulgarian (Phonetic)'), 'us,bg', 'pc105', ',phonetic', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'br-abnt2' : [N_('keyboard|Brazilian (ABNT2)'), 'br', 'abnt2', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'cf' : [N_('keyboard|French Canadian'), 'ca(fr)', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'croat' : [N_('keyboard|Croatian'), 'hr', 'pc105', '', '' ], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'cz-us-qwertz' : [N_('keyboard|Czech'), 'us,cz', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'cz-lat2' : [N_('keyboard|Czech (qwerty)'), 'cz', 'pc105', 'qwerty', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'de' : [N_('keyboard|German'), 'de', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'de-latin1' : [N_('keyboard|German (latin1)'), 'de', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'de-latin1-nodeadkeys' : [N_('keyboard|German (latin1 w/ no deadkeys)'), 'de', 'pc105', 'nodeadkeys', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'dev' : [N_('keyboard|Devanagari (Inscript)'), 'us,dev', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'dvorak' : [N_('keyboard|Dvorak'), 'us', 'pc105', 'dvorak', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'dk' : [N_('keyboard|Danish'), 'dk', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'dk-latin1' : [N_('keyboard|Danish (latin1)'), 'dk', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'es' : [N_('keyboard|Spanish'), 'es', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'et' : [N_('keyboard|Estonian'), 'ee', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'fi' : [N_('keyboard|Finnish'), 'fi', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'fi-latin1' : [N_('keyboard|Finnish (latin1)'), 'fi', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'fr' : [N_('keyboard|French'), 'fr', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'fr-latin9' : [N_('keyboard|French (latin9)'), 'fr', 'pc105', 'latin9', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'fr-latin1' : [N_('keyboard|French (latin1)'), 'fr', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'fr-pc' : [N_('keyboard|French (pc)'), 'fr', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'fr_CH' : [N_('keyboard|Swiss French'), 'fr_CH', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'fr_CH-latin1' : [N_('keyboard|Swiss French (latin1)'), 'ch', 'pc105', 'fr', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'gr' : [N_('keyboard|Greek'), 'us,gr', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'guj' : [N_('keyboard|Gujarati (Inscript)'), 'us,in', 'pc105', 'guj', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'gur' : [N_('keyboard|Punjabi (Inscript)'), 'us,gur', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'hu' : [N_('keyboard|Hungarian'), 'hu', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'hu101' : [N_('keyboard|Hungarian (101 key)'), 'hu', 'pc105', 'qwerty', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'is-latin1' : [N_('keyboard|Icelandic'), 'is', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'it' : [N_('keyboard|Italian'), 'it', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'it-ibm' : [N_('keyboard|Italian (IBM)'), 'it', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'it2' : [N_('keyboard|Italian (it2)'), 'it', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'jp106' : [N_('keyboard|Japanese'), 'jp', 'jp106', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ko' : [N_('keyboard|Korean'), 'kr', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'la-latin1' : [N_('keyboard|Latin American'), 'latam', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'mk-utf' : [N_('keyboard|Macedonian'), 'us,mkd', 'pc105', '','grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'nl' : [N_('keyboard|Dutch'), 'nl', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'no' : [N_('keyboard|Norwegian'), 'no', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'pl2' : [N_('keyboard|Polish'), 'pl', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'pt-latin1' : [N_('keyboard|Portuguese'), 'pt', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ro_win' : [N_('keyboard|Romanian'), 'ro', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ru' : [N_('keyboard|Russian'), 'us,ru', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'sr-cy' : [N_('keyboard|Serbian'), 'cs', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'sr-latin' : [N_('keyboard|Serbian (latin)'), 'cs', 'pc105', 'latin', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'sv-latin1' : [N_('keyboard|Swedish'), 'se', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'sg' : [N_('keyboard|Swiss German'), 'ch', 'pc105', 'de_nodeadkeys', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'sg-latin1' : [N_('keyboard|Swiss German (latin1)'), 'ch', 'pc105', 'de_nodeadkeys', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'sk-qwerty' : [N_('keyboard|Slovak (qwerty)'), 'sk', 'pc105', '', 'qwerty'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'slovene' : [N_('keyboard|Slovenian'), 'si', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'tml-inscript' : [N_('keyboard|Tamil (Inscript)'), 'us,in', 'pc105', 'tam', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'tml-uni' : [N_('keyboard|Tamil (Typewriter)'), 'us,in', 'pc105', 'tam_TAB', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'trq' : [N_('keyboard|Turkish'), 'tr', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'uk' : [N_('keyboard|United Kingdom'), 'gb', 'pc105', '', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'ua-utf' : [N_('keyboard|Ukrainian'), 'us,ua', 'pc105', '', 'grp:shifts_toggle,grp_led:scroll'], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'us-acentos' : [N_('keyboard|U.S. International'), 'us', 'pc105', 'intl', ''], + # Translators: the word before the bar is just context and + # doesn't need to be translated. Only after will be translated. + 'us' : [N_('keyboard|U.S. English'), 'us+inet', 'pc105', '', ''], + } + + def _get_models(self): + ret = {} + for (key, item) in self._modelDict.items(): + ret[key] = [gkn(_(item[0])), item[1], item[2], item[3], item[4]] + return ret + + modelDict = property(_get_models) + +def get_supported_models(): + models = KeyboardModels() + maps = models.modelDict.keys() + maps.sort() + for map in maps: + print map + +if __name__ == "__main__": + get_supported_models() diff --git a/pkgs/core/pomona/src/lang-table b/pkgs/core/pomona/src/lang-table new file mode 100644 index 0000000..a4f15fd --- /dev/null +++ b/pkgs/core/pomona/src/lang-table @@ -0,0 +1,3 @@ +English en LatArCyrHeb-16 en_US.UTF-8 us America/New_York +German de LatArCyrHeb-16 de_DE.UTF-8 de-latin1-nodeadkeys Europe/Berlin +Danish da LatArCyrHeb-16 da_DK.UTF-8 dk Europe/Copenhagen diff --git a/pkgs/core/pomona/src/lvm.py b/pkgs/core/pomona/src/lvm.py new file mode 100644 index 0000000..e5b2fd9 --- /dev/null +++ b/pkgs/core/pomona/src/lvm.py @@ -0,0 +1,613 @@ +# +# lvm.py - lvm probing control +# +# Copyright (C) 2002 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Jeremy Katz <katzj@redhat.com> +# + +import os +import sys +import iutil +import string +import math +import isys +import re + +from flags import flags + +import logging +log = logging.getLogger("pomona") + +from constants import * + +MAX_LV_SLOTS=256 + +lvmDevicePresent = 0 + +from errors import * + +def has_lvm(): + global lvmDevicePresent + + if not (os.access("/usr/sbin/lvm", os.X_OK) or + os.access("/sbin/lvm", os.X_OK)): + return + + f = open("/proc/devices", "r") + lines = f.readlines() + f.close() + + for line in lines: + try: + (dev, name) = line[:-1].split(' ', 2) + except: + continue + if name == "device-mapper": + lvmDevicePresent = 1 + break + return lvmDevicePresent +# now check to see if lvm is available +has_lvm() + +if lvmDevicePresent == 1: + log.info("LVM is enabled.") +else: + log.info("LVM is disabled.") + +def lvmExec(*args): + try: + return iutil.execWithRedirect("lvm", args, stdout = lvmErrorOutput, + stderr = lvmErrorOutput, searchPath = 1) + except Exception, e: + log.error("error running lvm command: %s" %(e,)) + raise LvmError, args[0] + +def lvmCapture(*args): + try: + lvmout = iutil.execWithCapture("lvm", args, stderr = lvmErrorOutput) + lines = [] + for line in lvmout.split("\n"): + lines.append(line.strip().split(':')) + return lines + except Exception, e: + log.error("error running lvm command: %s" %(e,)) + raise LvmError, args[0] + +def vgscan(): + """Runs vgscan.""" + global lvmDevicePresent + + if lvmDevicePresent == 0: + return + + rc = lvmExec("vgscan", "-v") + if rc: + log.error("running vgscan failed: %s" %(rc,)) +# lvmDevicePresent = 0 + +def vgmknodes(volgroup=None): + # now make the device nodes + args = ["vgmknodes", "-v"] + if volgroup: + args.append(volgroup) + rc = lvmExec(*args) + if rc: + log.error("running vgmknodes failed: %s" %(rc,)) +# lvmDevicePresent = 0 + +def vgcheckactive(volgroup = None): + """Check if volume groups are active + + volgroup - optional parameter to inquire about a specific volume group. + """ + global lvmDevicePresent + if lvmDevicePresent == 0: + return False + + args = ["lvs", "--noheadings", "--units", "b", "--nosuffix", + "--separator", ":", "--options", "vg_name,lv_name,attr"] + for line in lvmCapture(*args): + try: + (vg, lv, attr) = line + except: + continue + + log.info("lv %s/%s, attr is %s" %(vg, lv, attr)) + if attr.find("a") == -1: + continue + + if volgroup is None or volgroup == vg: + return True + + return False + +def vgactivate(volgroup = None): + """Activate volume groups by running vgchange -ay. + + volgroup - optional single volume group to activate + """ + global lvmDevicePresent + if lvmDevicePresent == 0: + return + + args = ["vgchange", "-ay", "-v"] + if volgroup: + args.append(volgroup) + rc = lvmExec(*args) + if rc: + log.error("running vgchange failed: %s" %(rc,)) +# lvmDevicePresent = 0 + vgmknodes(volgroup) + +def vgdeactivate(volgroup = None): + """Deactivate volume groups by running vgchange -an. + + volgroup - optional single volume group to deactivate + """ + global lvmDevicePresent + if lvmDevicePresent == 0: + return + + args = ["vgchange", "-an", "-v"] + if volgroup: + args.append(volgroup) + rc = lvmExec(*args) + if rc: + log.error("running vgchange failed: %s" %(rc,)) +# lvmDevicePresent = 0 + +def lvcreate(lvname, vgname, size): + """Creates a new logical volume. + + lvname - name of logical volume to create. + vgname - name of volume group lv will be in. + size - size of lv, in megabytes. + """ + global lvmDevicePresent + if lvmDevicePresent == 0: + return + writeForceConf() + vgscan() + + args = ["lvcreate", "-v", "-L", "%dM" %(size,), "-n", lvname, "-An", vgname] + try: + rc = lvmExec(*args) + except: + rc = 1 + if rc: + raise LVCreateError(vgname, lvname, size) + unlinkConf() + +def lvremove(lvname, vgname): + """Removes a logical volume. + + lvname - name of logical volume to remove. + vgname - name of volume group lv is in. + """ + global lvmDevicePresent + if lvmDevicePresent == 0: + return + + args = ["lvremove", "-f", "-v"] + dev = "/dev/%s/%s" %(vgname, lvname) + args.append(dev) + + try: + rc = lvmExec(*args) + except: + rc = 1 + if rc: + raise LVRemoveError(vgname, lvname) + +def lvresize(lvname, vgname, size): + global lvmDevicePresent + if lvmDevicePresent == 0: + return + + args = ["lvresize", "-An", "-L", "%dM" %(size,), "-v", "--force", + "/dev/%s/%s" %(vgname, lvname,)] + + try: + rc = lvmExec(*args) + except: + rc = 1 + if rc: + raise LVResizeError(vgname, lvname) + + +def vgcreate(vgname, PESize, nodes): + """Creates a new volume group." + + vgname - name of volume group to create. + PESize - Physical Extent size, in kilobytes. + nodes - LVM Physical Volumes on which to put the new VG. + """ + global lvmDevicePresent + if lvmDevicePresent == 0: + return + + # rescan now that we've recreated pvs. ugh. + writeForceConf() + vgscan() + + args = ["vgcreate", "-v", "-An", "-s", "%sk" % (PESize,), vgname ] + args.extend(nodes) + + try: + rc = lvmExec(*args) + except: + rc = 1 + if rc: + raise VGCreateError(vgname, PESize, nodes) + unlinkConf() + +def vgremove(vgname): + """Removes a volume group. Deactivates the volume group first + + vgname - name of volume group. + """ + global lvmDevicePresent + if lvmDevicePresent == 0: + return + + # find the Physical Volumes which make up this Volume Group, so we + # can prune and recreate them. + pvs = [] + for pv in pvlist(): + if pv[1] == vgname: + pvs.append(pv[0]) + + # we'll try to deactivate... if it fails, we'll probably fail on + # the removal too... but it's worth a shot + try: + vgdeactivate(vgname) + except: + pass + + args = ["vgremove", "-v", vgname] + + log.info(string.join(args, ' ')) + try: + rc = lvmExec(*args) + except: + rc = 1 + if rc: + raise VGRemoveError, vgname + + # now iterate all the PVs we've just freed up, so we reclaim the metadata + # space. This is an LVM bug, AFAICS. + for pvname in pvs: + args = ["pvremove", "-ff", "-y", "-v", pvname] + + log.info(string.join(args, ' ')) + try: + rc = lvmExec(*args) + except: + rc = 1 + if rc: + raise PVRemoveError, pvname + + args = ["pvcreate", "-ff", "-y", "-v", pvname] + + log.info(string.join(args, ' ')) + try: + rc = lvmExec(*args) + except: + rc = 1 + if rc: + raise PVCreateError, pvname + wipeOtherMetadataFromPV(pvname) + +def pvcreate(node): + """Initializes a new Physical Volume." + + node - path to device node on which to create the new PV." + """ + global lvmDevicePresent + if lvmDevicePresent == 0: + return + + # rescan now that we've recreated pvs. ugh. + writeForceConf() + + args = ["pvcreate", "-ff", "-y", "-v", node ] + + try: + rc = lvmExec(*args) + except: + rc = 1 + if rc: + raise PVCreateError, node + unlinkConf() + wipeOtherMetadataFromPV(node) + +def lvlist(): + global lvmDevicePresent + if lvmDevicePresent == 0: + return [] + + lvs = [] + # field names for "options" are in LVM2.2.01.01/lib/report/columns.h + args = ["lvdisplay", "-C", "--noheadings", "--units", "b", + "--nosuffix", "--separator", ":", "--options", + "vg_name,lv_name,lv_size,origin" + ] + lvscanout = iutil.execWithCapture("lvm", args, stderr = "/dev/tty6") + for line in lvmCapture(*args): + try: + (vg, lv, size, origin) = line + size = long(math.floor(long(size) / (1024 * 1024))) + if origin == '': + origin = None + except: + continue + + logmsg = "lv is %s/%s, size of %s" % (vg, lv, size) + if origin: + logmsg += ", snapshot from %s" % (origin,) + log.info(logmsg) + lvs.append( (vg, lv, size, origin) ) + + return lvs + +def pvlist(): + global lvmDevicePresent + if lvmDevicePresent == 0: + return [] + + pvs = [] + args = ["pvdisplay", "-C", "--noheadings", "--units", "b", + "--nosuffix", "--separator", ":", "--options", + "pv_name,vg_name,dev_size" + ] + for line in lvmCapture(*args): + try: + (dev, vg, size) = line + size = long(math.floor(long(size) / (1024 * 1024))) + except: + continue + + if dev.startswith("/dev/dm-"): + from block import dm + try: + sb = os.stat(dev) + (major, minor) = (os.major(sb.st_rdev), os.minor(sb.st_rdev)) + for map in dm.maps(): + if map.dev.major == major and map.dev.minor == minor: + dev = "/dev/mapper/%s" % map.name + break + except: + pass + + log.info("pv is %s in vg %s, size is %s" %(dev, vg, size)) + pvs.append( (dev, vg, size) ) + + return pvs + +def vglist(): + global lvmDevicePresent + if lvmDevicePresent == 0: + return [] + + vgs = [] + args = ["vgdisplay", "-C", "--noheadings", "--units", "b", + "--nosuffix", "--separator", ":", "--options", + "vg_name,vg_size,vg_extent_size,vg_free" + ] + for line in lvmCapture(*args): + try: + (vg, size, pesize, free) = line + size = long(math.floor(long(size) / (1024 * 1024))) + pesize = long(pesize)/1024 + free = math.floor(long(free) / (1024 * 1024)) + except: + continue + log.info("vg %s, size is %s, pesize is %s" %(vg, size, pesize)) + vgs.append( (vg, size, pesize, free) ) + return vgs + +def partialvgs(): + global lvmDevicePresent + if lvmDevicePresent == 0: + return [] + + vgs = [] + args = ["vgdisplay", "-C", "-P", "--noheadings", "--units", "b", + "--nosuffix", "--separator", ":"] + for line in lvmCapture(*args): + try: + (vg, numpv, numlv, numsn, attr, size, free) = line + except: + continue + if attr.find("p") != -1: + log.info("vg %s, attr is %s" %(vg, attr)) + vgs.append(vg) + + return vgs + +# FIXME: this is a hack. we really need to have a --force option. +def unlinkConf(): + lvmroot = "/etc/lvm" + if os.path.exists("%s/lvm.conf" %(lvmroot,)): + os.unlink("%s/lvm.conf" %(lvmroot,)) + +def writeForceConf(): + """Write out an /etc/lvm/lvm.conf that doesn't do much (any?) filtering""" + + lvmroot = "/etc/lvm" + try: + os.unlink("/etc/lvm/.cache") + except: + pass + if not os.path.isdir(lvmroot): + os.mkdir(lvmroot) + + unlinkConf() + + f = open("%s/lvm.conf" %(lvmroot,), "w+") + f.write(""" +# anaconda hacked lvm.conf to avoid filtering breaking things +devices { + sysfs_scan = 0 + md_component_detection = 1 +} +""") + +# FIXME: another hack. we need to wipe the raid metadata since pvcreate +# doesn't +def wipeOtherMetadataFromPV(node): + try: + isys.wipeRaidSB(node) + except Exception, e: + log.critical("error wiping raidsb from %s: %s", node, e) + + + +def getPossiblePhysicalExtents(floor=0): + """Returns a list of integers representing the possible values for + the physical extent of a volume group. Value is in KB. + + floor - size (in KB) of smallest PE we care about. + """ + + possiblePE = [] + curpe = 8 + while curpe <= 16384*1024: + if curpe >= floor: + possiblePE.append(curpe) + curpe = curpe * 2 + + return possiblePE + +def clampLVSizeRequest(size, pe, roundup=0): + """Given a size and a PE, returns the actual size of logical volumne. + + size - size (in MB) of logical volume request + pe - PE size (in KB) + roundup - round sizes up or not + """ + + if roundup: + func = math.ceil + else: + func = math.floor + return (long(func((size*1024L)/pe))*pe)/1024 + +def clampPVSize(pvsize, pesize): + """Given a PV size and a PE, returns the usable space of the PV. + Takes into account both overhead of the physical volume and 'clamping' + to the PE size. + + pvsize - size (in MB) of PV request + pesize - PE size (in KB) + """ + + # we want Kbytes as a float for our math + pvsize *= 1024.0 + return long((math.floor(pvsize / pesize) * pesize) / 1024) + +def getMaxLVSize(pe): + """Given a PE size in KB, returns maximum size (in MB) of a logical volume. + + pe - PE size in KB + """ + # LVM2, size limited by number of sectors + return (16*1024*1024) #Max is 16TiB + +def safeLvmName(str): + tmp = string.strip(str) + tmp = tmp.replace("/", "_") + tmp = re.sub("[^0-9a-zA-Z._]", "", str) + tmp = tmp.lstrip("_") + + return tmp + +def createSuggestedVGName(partitions, network): + """Given list of partition requests, come up with a reasonable VG name + + partitions - list of requests + """ + + # try to create a volume group name incorporating the hostname + hn = network.hostname + if hn is not None and hn != '': + if hn == 'localhost' or hn == 'localhost.localdomain': + vgtemplate = "VolGroup" + elif hn.find('.') != -1: + hn = safeLvmName(hn) + vgtemplate = "vg_%s" % (hn.split('.')[0].lower(),) + else: + hn = safeLvmName(hn) + vgtemplate = "vg_%s" % (hn.lower(),) + else: + vgtemplate = "VolGroup" + + if not partitions.isVolumeGroupNameInUse(vgtemplate): + return vgtemplate + else: + i = 0 + while 1: + tmpname = "%s%02d" % (vgtemplate, i,) + if not partitions.isVolumeGroupNameInUse(tmpname): + break + + i += 1 + if i > 99: + tmpname = "" + + return tmpname + +def createSuggestedLVName(logreqs): + """Given list of LV requests, come up with a reasonable LV name + + partitions - list of LV requests for this VG + """ + + i = 0 + + lnames = [] + for lv in logreqs: + lnames.append(lv.logicalVolumeName) + + while 1: + tmpname = "LogVol%02d" % (i,) + if (logreqs is None) or (tmpname not in lnames): + break + + i += 1 + if i > 99: + tmpname = "" + + return tmpname + +def getVGUsedSpace(vgreq, requests, diskset): + vgused = 0 + for request in requests.requests: + if request.type == REQUEST_LV and request.volumeGroup == vgreq.uniqueID: + size = int(request.getActualSize(requests, diskset)) + vgused = vgused + size + + + return vgused + +def getVGFreeSpace(vgreq, requests, diskset): + used = getVGUsedSpace(vgreq, requests, diskset) + log.debug("used space is %s" % (used,)) + + total = vgreq.getActualSize(requests, diskset) + log.debug("actual space is %s" % (total,)) + return total - used diff --git a/pkgs/core/pomona/src/network.py b/pkgs/core/pomona/src/network.py new file mode 100644 index 0000000..5f5cce1 --- /dev/null +++ b/pkgs/core/pomona/src/network.py @@ -0,0 +1,65 @@ +#!/usr/bin/python + +import socket +import string + +import pyfire.net + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +def networkDeviceCheck(pomona): + devs = pomona.id.network.available() + if not devs: + pomona.dispatch.skipStep("network") + +class Network(pyfire.net.Network): + def __init__(self, filename): + pyfire.net.Network.__init__(self) + + self.settings = pyfire.net.NetworkSettings(filename) + +class IPError(Exception): + pass + +class IPMissing(Exception): + pass + +# sanity check an IP string. +def sanityCheckIPString(ip_string): + if ip_string.strip() == "": + raise IPMissing, _("IP address is missing.") + + if ip_string.find(':') == -1 and ip_string.find('.') > 0: + family = socket.AF_INET + errstr = _("IPv4 addresses must contain four numbers between 0 and 255, separated by periods.") + elif ip_string.find(':') > 0 and ip_string.find('.') == -1: + family = socket.AF_INET6 + errstr = _("'%s' is not a valid IPv6 address.") % ip_string + else: + raise IPError, _("'%s' is an invalid IP address.") % ip_string + + try: + socket.inet_pton(family, ip_string) + except socket.error: + raise IPError, errstr + +def sanityCheckHostname(hostname): + if len(hostname) < 1: + return None + + if len(hostname) > 255: + return _("Hostname must be 255 or fewer characters in length.") + + validStart = string.ascii_letters + string.digits + validAll = validStart + ".-" + + if string.find(validStart, hostname[0]) == -1: + return _("Hostname must start with a valid character in the ranges " + "'a-z', 'A-Z', or '0-9'") + + for i in range(1, len(hostname)): + if string.find(validAll, hostname[i]) == -1: + return _("Hostnames can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.'") + + return None diff --git a/pkgs/core/pomona/src/packages.py b/pkgs/core/pomona/src/packages.py new file mode 100644 index 0000000..27dac7e --- /dev/null +++ b/pkgs/core/pomona/src/packages.py @@ -0,0 +1,195 @@ +# +# packages.py: package management - mainly package installation +# +# Erik Troan <ewt@redhat.com> +# Matt Wilson <msw@redhat.com> +# Michael Fulbright <msf@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# +# Copyright 2001-2006 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# library public license. +# +# You should have received a copy of the GNU Library Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import iutil +import isys +import os +import sys +import fsset +import shutil +import time +import lvm +from flags import flags +from constants import * + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +import logging +log = logging.getLogger("pomona") + +def doPostAction(pomona): + pomona.backend.postAction(pomona) + +def copyPomonaLogs(pomona): + log.info("Copying pomona logs") + for (fn, dest) in (("/root/pomona.log", "pomona.log"), + ("/tmp/syslog", "pomona.syslog")): + if os.access(fn, os.R_OK): + try: + shutil.copyfile(fn, "%s/var/log/%s" %(pomona.rootPath, dest)) + os.chmod("%s/var/log/%s" %(pomona.rootPath, dest), 0600) + except: + pass + +def doMigrateFilesystems(pomona): + if pomona.dir == DISPATCH_BACK: + return DISPATCH_NOOP + + if pomona.id.fsset.haveMigratedFilesystems(): + return DISPATCH_NOOP + + pomona.id.fsset.migrateFilesystems (pomona) + +def turnOnFilesystems(pomona): + def handleResizeError(e, dev): + if os.path.exists("/tmp/resize.out"): + details = open("/tmp/resize.out", "r").read() + else: + details = "%s" %(e,) + pomona.intf.detailedMessageWindow(_("Resizing Failed"), + _("There was an error encountered " + "resizing the device %s.") %(dev,), + details, + type = "custom", + custom_buttons = [_("_Exit installer")]) + sys.exit(1) + + if pomona.dir == DISPATCH_BACK: + log.info("unmounting filesystems") + pomona.id.fsset.umountFilesystems(pomona.rootPath) + return + + if not pomona.id.fsset.isActive(): + # turn off any swaps that we didn't turn on + # needed for live installs + iutil.execWithRedirect("swapoff", ["-a"], + stdout = "/dev/tty5", stderr="/dev/tty5", + searchPath = 1) + pomona.id.partitions.doMetaDeletes(pomona.id.diskset) + pomona.id.fsset.setActive(pomona.id.diskset) + try: + pomona.id.fsset.shrinkFilesystems(pomona.id.diskset, pomona.rootPath) + except fsset.ResizeError, (e, dev): + handleResizeError(e, dev) + + if not pomona.id.fsset.isActive(): + pomona.id.diskset.savePartitions() + # this is somewhat lame, but we seem to be racing with + # device node creation sometimes. so wait for device nodes + # to settle + w = pomona.intf.waitWindow(_("Activating"), _("Activating new partitions. Please wait...")) + time.sleep(1) + rc = iutil.execWithRedirect("/sbin/udevadm", [ "settle" ], + stdout = "/dev/tty5", + stderr = "/dev/tty5", + searchPath = 1) + w.pop() + + pomona.id.partitions.doEncryptionRetrofits() + + try: + pomona.id.partitions.doMetaResizes(pomona.id.diskset) + except lvm.LVResizeError, e: + handleResizeError("%s" %(e,), "%s/%s" %(e.vgname, e.lvname)) + + try: + pomona.id.fsset.growFilesystems(pomona.id.diskset, pomona.rootPath) + except fsset.ResizeError, (e, dev): + handleResizeError(e, dev) + + if not pomona.id.fsset.volumesCreated: + try: + pomona.id.fsset.createLogicalVolumes(pomona.rootPath) + except SystemError, e: + log.error("createLogicalVolumes failed with %s", str(e)) + pomona.intf.messageWindow(_("LVM operation failed"), + str(e)+"\n\n"+_("The installer will now exit..."), + type="custom", custom_icon="error", custom_buttons=[_("_Reboot")]) + sys.exit(0) + + pomona.id.fsset.formatSwap(pomona.rootPath) + pomona.id.fsset.turnOnSwap(pomona.rootPath) + pomona.id.fsset.makeFilesystems(pomona.rootPath, + pomona.backend.skipFormatRoot) + pomona.id.fsset.mountFilesystems(pomona,0,0, + pomona.backend.skipFormatRoot) + +def setupTimezone(pomona): + # we don't need this on going backwards + if pomona.dir == DISPATCH_BACK: + return + + os.environ["TZ"] = pomona.id.timezone.tz + tzfile = "/usr/share/zoneinfo/" + pomona.id.timezone.tz + if not os.access(tzfile, os.R_OK): + log.error("unable to set timezone") + else: + try: + shutil.copyfile(tzfile, "/etc/localtime") + except OSError, (errno, msg): + log.error("Error copying timezone (from %s): %s" %(tzfile, msg)) + + args = [ "--hctosys" ] + if pomona.id.timezone.utc: + args.append("-u") + + try: + iutil.execWithRedirect("/usr/sbin/hwclock", args, stdin = None, + stdout = "/dev/tty5", stderr = "/dev/tty5") + except RuntimeError: + log.error("Failed to set clock") + +def betaNagScreen(pomona): + if pomona.dir == DISPATCH_BACK: + return DISPATCH_NOOP + + ### Check if we run a pre-release version + if not version.find("alpha") and \ + not version.find("beta") and \ + not version.find("rc"): + return DISPATCH_NOOP + + while 1: + rc = pomona.intf.messageWindow( _("Warning! This is pre-release software!"), + _("Thank you for downloading this " + "pre-release of %s.\n\n" + "This is not a final " + "release and is not intended for use " + "on production systems. The purpose of " + "this release is to collect feedback " + "from testers, and it is not suitable " + "for day to day usage.\n\n" + "To report feedback, please visit:\n\n" + " %s\n\n" + "and file a report against '%s'.\n") + % (name, bugurl, name), + type="custom", custom_icon="warning", + custom_buttons=[_("_Exit"), _("_Install anyway")]) + + if not rc: + msg = _("Your system will now be rebooted...") + buttons = [_("_Back"), _("_Reboot")] + rc = pomona.intf.messageWindow(_("Rebooting System"), + msg, + type="custom", custom_icon="warning", + custom_buttons=buttons) + if rc: + sys.exit(0) + else: + break diff --git a/pkgs/core/pomona/src/pakfireinstall.py b/pkgs/core/pomona/src/pakfireinstall.py new file mode 100644 index 0000000..ada57f0 --- /dev/null +++ b/pkgs/core/pomona/src/pakfireinstall.py @@ -0,0 +1,265 @@ +# +# Copyright (c) 2005-2007 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# general public license. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import sys +import os +import os.path +import shutil +import warnings +import locale +import signal +import subprocess +import time + +import urlgrabber.progress +import urlgrabber.grabber +from urlgrabber.grabber import URLGrabber, URLGrabError +from backend import PomonaBackend +from constants import * + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +import logging +log = logging.getLogger("pomona") + +import urlparse +urlparse.uses_fragment.append('media') + +import iutil +import isys +import pyfire + +def size_string(size): + def number_format(s): + return locale.format("%s", s, 1) + + if size > 1024 * 1024: + size = size / (1024*1024) + return _("%s MB") %(number_format(size),) + elif size > 1024: + size = size / 1024 + return _("%s KB") %(number_format(size),) + else: + if size == 1: + return _("%s Byte") %(number_format(size),) + else: + return _("%s Bytes") %(number_format(size),) + +class PomonaCallback: + def __init__(self, pomona): + self.messageWindow = pomona.intf.messageWindow + self.waitWindow = pomona.intf.waitWindow + self.progress = pomona.id.instProgress + self.progressWindow = pomona.intf.progressWindow + + self.initWindow = None + + self.lastprogress = 0 + self.incr = 20 + + self.text = "" + + self.window = None + self.windowType = None + + def setSize(self, totalSize): + self.totalSize = totalSize + self.doneSize = 0 + self.lastprogress = 0 + self.incr = totalSize / 100 + + def callback(self, what, amount=0, title=None, text=None): + # first time here means we should pop the window telling + # user to wait until we get here + if self.initWindow is not None: + self.initWindow.pop() + self.initWindow = None + + if what == CB_START: + if self.totalSize == 0: + self.window = self.waitWindow(title, text, width=55) + self.text = text + self.windowType = "wait" + else: + self.window = self.progressWindow(title, text, self.totalSize) + self.windowType = "progress" + + elif what == CB_STOP: + self.window.pop() + + elif what == CB_PROGRESS: + if self.windowType == "progress": + if amount > self.lastprogress + self.incr: + self.window.set(amount) + self.lastprogress = amount + elif self.windowType == "wait": + self.window.set_text(self.text + " " + amount) + +class PomonaPakfire: + def __init__(self, pomona): + self.pomona = pomona + + def run(self, cb, intf, id): + self.extractFiles(cb, intf, id) + + def extractFiles(self, cb, intf, id): + filename = os.path.join(SOURCE_PATH, IMAGE_FILE) + filename_ls = os.path.join(SOURCE_PATH, IMAGE_FILE_LS) + + # XXX Temporarily disabled + #fd = open(filename_ls, 'r') + filesize = 1000 + #while fd.readline(): + # filesize += 1 + #fd.close() + cb.setSize(filesize) + + filesize = int(os.path.getsize(filename)) + log.info("Source file %s has size of %dKB" % (filename, filesize / 1024,)) + + command = "unsquashfs -n -i -f -d %s %s 2>/dev/tty5" % (HARDDISK_PATH, filename,) + + extractor = subprocess.Popen(command, shell=True, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE) + + cb.callback(CB_START, title=_("Base system"), text=_("Installing base system...")) + + buf = extractor.stdout.readline() + tot = 0 + while buf != "": + tot += 1 + cb.callback(CB_PROGRESS, amount=tot) + buf = extractor.stdout.readline() + + cb.callback(CB_STOP) + +class PakfireBackend(PomonaBackend): + def __init__(self, instPath): + PomonaBackend.__init__(self, instPath) + + def selectBestKernel(self): + """Find the best kernel package which is available and select it.""" + pass ## XXX todo? + + def selectFSPackages(self, fsset, diskset): + for entry in fsset.entries: + map(self.selectPackage, entry.fsystem.getNeededPackages()) + + def doPostSelection(self, pomona): + pass + + def doPreInstall(self, pomona): + if pomona.dir == DISPATCH_BACK: + return DISPATCH_BACK + + self.pompak = PomonaPakfire(pomona) + + def doInstall(self, pomona): + log.info("Preparing to install files") + + cb = PomonaCallback(pomona) + + cb.initWindow = pomona.intf.waitWindow(_("Install Starting"), + _("Starting install process. This may take several minutes...")) + time.sleep(2) + + self.pompak.run(cb, pomona.intf, pomona.id) + + if cb.initWindow is not None: + cb.initWindow.pop() + + pomona.id.instProgress = None + + def doPostInstall(self, pomona): + w = pomona.intf.waitWindow(_("Post Install"), + _("Performing post install configuration...")) + + # we need to have a /dev after install and now that udev is + # handling /dev, it gets to be more fun. so just bind mount the + # installer /dev + isys.mount("/dev", "%s/dev" %(pomona.rootPath,), bindMount = 1) + + # write out the fstab + pomona.id.fsset.write(pomona.rootPath) + # rootpath mode doesn't have this file around + if os.access("/tmp/modprobe.conf", os.R_OK): + shutil.copyfile("/tmp/modprobe.conf", + pomona.rootPath + "/etc/modprobe.conf") + + ### XXX pomona.id.network.write(pomona.rootPath) + + for (kernelName, kernelVersion, kernelTag, kernelDesc) in self.kernelVersionList(pomona): + initrd = "/boot/initramfs-%s%s.img" % (kernelVersion, kernelTag,) + log.info("mkinitramfs: creating %s" % initrd) + pyfire.executil.execWithRedirect("/sbin/mkinitramfs", + ["/sbin/mkinitramfs", "-v", "-f", "%s" % initrd, + "%s%s" % (kernelVersion, kernelTag,), ], + stdout = "/dev/tty5", stderr = "/dev/tty5", + root = pomona.rootPath) + + PomonaBackend.doPostInstall(self, pomona) + w.pop() + + def kernelVersionList(self, pomona): + kernelVersions = [] + + tag2desc = { "-smp" : _("Symmetric multiprocessing"), + "-xen" : _("Xen guest"), } + + kernelName = "%skernel-%s" % (sname, kernelVersion) + + for kernelTag in [ "", "-smp", "-xen", ]: + filename = "%s%s" % (kernelName, kernelTag) + if os.access(pomona.rootPath + "/boot/" + filename, os.R_OK): + if not kernelTag == "": + kernelDesc = tag2desc[kernelTag] + else: + kernelDesc = _("Normal Boot") + kernelVersions.append((kernelName, kernelVersion, kernelTag, kernelDesc)) + + return kernelVersions + +class PakfireProgress: + def __init__(self, intf, text, total): + window = intf.progressWindow(_("Installation Progress"), text, total, 0.01) + self.window = window + + self.current = 0 + self.incr = 1 + self.total = total + self.popped = False + + def set_incr(self, incr): + self.incr = incr + + def progressbar(self, current, total, name=None): + if not self.popped: + self.window.set(float(current)/total * self.incr + self.current) + else: + warnings.warn("PakfireProgress.progressbar called when popped", + RuntimeWarning, stacklevel=2) + + def pop(self): + self.window.pop() + self.popped = True + + def next_task(self, current = None): + if current: + self.current = current + else: + self.current += self.incr + if not self.popped: + self.window.set(self.current) + else: + warnings.warn("PakfireProgress.set called when popped", + RuntimeWarning, stacklevel=2) diff --git a/pkgs/core/pomona/src/partErrors.py b/pkgs/core/pomona/src/partErrors.py new file mode 100644 index 0000000..0c3f461 --- /dev/null +++ b/pkgs/core/pomona/src/partErrors.py @@ -0,0 +1,33 @@ +# +# partErrors.py: partitioning error exceptions +# +# Matt Wilson <msw@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# Mike Fulbright <msf@redhat.com> +# +# Copyright 2002 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# library public license. +# +# You should have received a copy of the GNU Library Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +"""Exceptions for use in partitioning.""" + +class PartitioningError(Exception): + """A critical error which must be resolved to continue the installation.""" + def __init__ (self, value): + self.value = value + + def __str__ (self): + return self.value + +class PartitioningWarning(Exception): + """A warning which may be ignored and still complete the installation.""" + def __init__ (self, value): + self.value = value + + def __str__ (self): + return self.value diff --git a/pkgs/core/pomona/src/partIntfHelpers.py b/pkgs/core/pomona/src/partIntfHelpers.py new file mode 100644 index 0000000..2d2833f --- /dev/null +++ b/pkgs/core/pomona/src/partIntfHelpers.py @@ -0,0 +1,547 @@ +# +# partIntfHelpers.py: partitioning interface helper functions +# +# Copyright (C) 2002 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Matt Wilson <msw@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# Mike Fulbright <msf@redhat.com> +# Harald Hoyer <harald@redhat.de> +# + +"""Helper functions shared between partitioning interfaces.""" + +import string +from constants import * +import partedUtils +import parted +import fsset +import iutil +import partRequests + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +def sanityCheckVolumeGroupName(volname): + """Make sure that the volume group name doesn't contain invalid chars.""" + badNames = ['lvm', 'root', '.', '..' ] + + if not volname: + return _("Please enter a volume group name.") + + # ripped the value for this out of linux/include/lvm.h + if len(volname) > 128: + return _("Volume Group Names must be less than 128 characters") + + if volname in badNames: + return _("Error - the volume group name %s is not valid." % (volname,)) + + for i in range(0, len(volname)): + rc = string.find(string.letters + string.digits + '.' + '_', volname[i]) + if rc == -1: + return _("Error - the volume group name contains illegal " + "characters or spaces. Acceptable characters " + "are letters, digits, '.' or '_'.") + return None + +def sanityCheckLogicalVolumeName(logvolname): + """Make sure that the logical volume name doesn't contain invalid chars.""" + badNames = ['group', '.', '..' ] + + if not logvolname: + return _("Please enter a logical volume name.") + + # ripped the value for this out of linux/include/lvm.h + if len(logvolname) > 128: + return _("Logical Volume Names must be less than 128 characters") + + + if logvolname in badNames: + return _("Error - the logical volume name %s is not " + "valid." % (logvolname,)) + + for i in range(0, len(logvolname)): + rc = string.find(string.letters + string.digits + '.' + '_', logvolname[i]) + if rc == -1: + return _("Error - the logical volume name contains illegal " + "characters or spaces. Acceptable characters " + "are letters, digits, '.' or '_'.") + return None + +def sanityCheckMountPoint(mntpt, fstype, preexisting, format): + """Sanity check that the mountpoint is valid. + + mntpt is the mountpoint being used. + fstype is the file system being used on the request. + preexisting is whether the request was preexisting (request.preexist) + format is whether the request is being formatted or not + """ + if mntpt: + passed = 1 + if not mntpt: + passed = 0 + else: + if mntpt[0] != '/' or (len(mntpt) > 1 and mntpt[-1:] == '/'): + passed = 0 + elif mntpt.find(' ') > -1: + passed = 0 + + if not passed: + return _("The mount point %s is invalid. Mount points must start " + "with '/' and cannot end with '/', and must contain " + "printable characters and no spaces." % mntpt) + else: + return None + else: + if (fstype and fstype.isMountable() and (not preexisting or format)): + return _("Please specify a mount point for this partition.") + else: + # its an existing partition so don't force a mount point + return None + +def isNotChangable(request, requestlist): + if request: + if requestlist.isRaidMember(request): + parentreq = requestlist.getRaidMemberParent(request) + if parentreq.raidminor is not None: + return _("This partition is part of " + "the RAID device /dev/md%s.") % (parentreq.raidminor,) + else: + return _("This partition is part of a RAID device.") + + if requestlist.isLVMVolumeGroupMember(request): + parentreq = requestlist.getLVMVolumeGroupMemberParent(request) + if parentreq.volumeGroupName is not None: + return _("This partition is part of the " + "LVM volume group '%s'.") % (parentreq.volumeGroupName,) + else: + return _("This partition is part of a LVM volume group.") + + return None + + +def doDeletePartitionByRequest(intf, requestlist, partition, + confirm=1, quiet=0): + """Delete a partition from the request list. + + intf is the interface + requestlist is the list of requests + partition is either the part object or the uniqueID if not a part + """ + + if partition == None: + intf.messageWindow(_("Unable To Delete"), + _("You must first select a partition to delete."), + custom_icon="error") + return 0 + + if type(partition) == type("RAID"): + device = partition + elif partition.type & parted.PARTITION_FREESPACE: + intf.messageWindow(_("Unable To Delete"), + _("You cannot delete free space."), + custom_icon="error") + return 0 + elif partition.type & parted.PARTITION_PROTECTED: + # LDL formatted DASDs always have one partition, you'd have to reformat the + # DASD in CDL mode to get rid of it + intf.messageWindow(_("Unable To Delete"), + _("You cannot delete a partition of a LDL formatted DASD."), + custom_icon="error") + return 0 + else: + device = partedUtils.get_partition_name(partition) + + ret = requestlist.containsImmutablePart(partition) + if ret: + if not quiet: + intf.messageWindow(_("Unable To Delete"), + _("You cannot delete this " + "partition, as it is an extended partition " + "which contains %s") %(ret), + custom_icon="error") + return 0 + + # see if device is in our partition requests, remove + if type(partition) == type("RAID"): + request = requestlist.getRequestByID(device) + else: + request = requestlist.getRequestByDeviceName(device) + + if request: + state = isNotChangable(request, requestlist) + + # If the partition is protected, we also can't delete it so specify a + # reason why. + if state is None and request.getProtected(): + state = _("This partition is holding the data for the hard " + "drive install.") + + if state: + if not quiet: + intf.messageWindow(_("Unable To Delete"), + _("You cannot delete this partition:\n\n") + state, + custom_icon="error") + return 0 + + if confirm and not confirmDeleteRequest(intf, request): + return 0 + + if request.getPreExisting(): + if isinstance(request, partRequests.PartitionSpec): + # get the drive + drive = partedUtils.get_partition_drive(partition) + + if partition.type & parted.PARTITION_EXTENDED: + requestlist.deleteAllLogicalPartitions(partition) + + delete = partRequests.DeleteSpec(drive, partition.geom.start, + partition.geom.end) + requestlist.addDelete(delete) + elif isinstance(request, partRequests.LogicalVolumeRequestSpec): + vgreq = requestlist.getRequestByID(request.volumeGroup) + delete = partRequests.DeleteLogicalVolumeSpec(request.logicalVolumeName, + vgreq.volumeGroupName) + requestlist.addDelete(delete) + elif isinstance(request, partRequests.VolumeGroupRequestSpec): + delete = partRequests.DeleteVolumeGroupSpec(request.volumeGroupName) + requestlist.addDelete(delete) + # FIXME: do we need to do anything with preexisting raids? + + # now remove the request + requestlist.deleteDependentRequests(request) + requestlist.removeRequest(request) + else: # is this a extended partition we made? + if partition.type & parted.PARTITION_EXTENDED: + requestlist.deleteAllLogicalPartitions(partition) + else: + #raise ValueError, "Deleting a non-existent partition" + return 0 + + del partition + return 1 + +def doDeletePartitionsByDevice(intf, requestlist, diskset, device, + confirm=1, quiet=0): + """ Remove all partitions currently on device """ + if confirm: + rc = intf.messageWindow(_("Confirm Delete"), + _("You are about to delete all partitions on " + "the device '/dev/%s'.") % (device,), + type="custom", custom_icon="warning", + custom_buttons=[_("Cancel"), _("_Delete")]) + + if not rc: + return + + requests = requestlist.getRequestsByDevice(diskset, device) + if not requests: + return + + # get list of unique IDs of these requests + reqIDs = [] + for req in requests: + part = partedUtils.get_partition_by_name(diskset.disks, req.device) + if part.type & parted.PARTITION_FREESPACE or part.type & parted.PARTITION_METADATA or part.type & parted.PARTITION_PROTECTED: + continue + reqIDs.append(req.uniqueID) + + # now go thru and try to delete the unique IDs + for id in reqIDs: + try: + req = requestlist.getRequestByID(id) + if req is None: + continue + part = partedUtils.get_partition_by_name(diskset.disks, req.device) + rc = doDeletePartitionByRequest(intf, requestlist, part, + confirm=0, quiet=1) + if not rc: + pass + except: + pass + + # see which partitions are left + notdeleted = [] + left_requests = requestlist.getRequestsByDevice(diskset, device) + if left_requests: + # get list of unique IDs of these requests + leftIDs = [] + for req in left_requests: + part = partedUtils.get_partition_by_name(diskset.disks, req.device) + if part.type & parted.PARTITION_FREESPACE or part.type & parted.PARTITION_METADATA or part.type & parted.PARTITION_PROTECTED: + continue + leftIDs.append(req.uniqueID) + + for id in leftIDs: + req = requestlist.getRequestByID(id) + notdeleted.append(req) + + + # see if we need to report any failures - some were because we removed + # an extended partition which contained other members of our delete list + outlist = "" + for req in notdeleted: + newreq = requestlist.getRequestByID(req.uniqueID) + if newreq: + outlist = outlist + "\t/dev/%s\n" % (newreq.device,) + + if outlist != "" and not quiet: + intf.messageWindow(_("Notice"), + _("The following partitions were not deleted " + "because they are in use:\n\n%s") % outlist, + custom_icon="warning") + + return 1 + + +def doEditPartitionByRequest(intf, requestlist, part): + """Edit a partition from the request list. + + intf is the interface + requestlist is the list of requests + partition is either the part object or the uniqueID if not a part + """ + + if part == None: + intf.messageWindow(_("Unable To Edit"), + _("You must select a partition to edit"), custom_icon="error") + + return (None, None) + + if type(part) == type("RAID"): + + # see if device is in our partition requests, remove + request = requestlist.getRequestByID(int(part)) + + if request: + state = isNotChangable(request, requestlist) + if state is not None: + intf.messageWindow(_("Unable To Edit"), _("You cannot edit this partition:\n\n") + state, + custom_icon="error") + return (None, None) + + if request.type == REQUEST_RAID: + return ("RAID", request) + elif request.type == REQUEST_VG: + return ("LVMVG", request) + elif request.type == REQUEST_LV: + return ("LVMLV", request) + else: + return (None, None) + elif part.type & parted.PARTITION_FREESPACE: + request = partRequests.PartitionSpec(fsset.fileSystemTypeGetDefault(), + start = partedUtils.start_sector_to_cyl(part.geom.dev, + part.geom.start), + end = partedUtils.end_sector_to_cyl(part.geom.dev, + part.geom.end), + drive = [ partedUtils.get_partition_drive(part) ]) + + return ("NEW", request) + elif part.type & parted.PARTITION_EXTENDED: + return (None, None) + + ret = requestlist.containsImmutablePart(part) + if ret: + intf.messageWindow(_("Unable To Edit"), + _("You cannot edit this " + "partition, as it is an extended partition " + "which contains %s") %(ret), custom_icon="error") + return (None, None) + + name = partedUtils.get_partition_name(part) + request = requestlist.getRequestByDeviceName(name) + if request: + state = isNotChangable(request, requestlist) + if state is not None: + intf.messageWindow(_("Unable To Edit"), + _("You cannot edit this partition:\n\n") + state, custom_icon="error") + return (None, None) + + return ("PARTITION", request) + else: # shouldn't ever happen + raise ValueError, ("Trying to edit non-existent partition %s" + % (partedUtils.get_partition_name(part))) + + +def checkForSwapNoMatch(anaconda): + """Check for any partitions of type 0x82 which don't have a swap fs.""" + for request in anaconda.id.partitions.requests: + if not request.device or not request.fstype: + continue + + part = partedUtils.get_partition_by_name(anaconda.id.diskset.disks, + request.device) + if (part and (not part.type & parted.PARTITION_FREESPACE) + and (part.native_type == 0x82) + and (request.fstype and request.fstype.getName() != "swap") + and (not request.format)): + rc = anaconda.intf.messageWindow(_("Format as Swap?"), + _("/dev/%s has a partition type of 0x82 " + "(Linux swap) but does not appear to " + "be formatted as a Linux swap " + "partition.\n\n" + "Would you like to format this " + "partition as a swap partition?") + % (request.device), type = "yesno", + custom_icon="question") + if rc == 1: + request.format = 1 + request.fstype = fsset.fileSystemTypeGet("swap") + if request.fstype.getName() == "software RAID": + part.set_flag(parted.PARTITION_RAID, 1) + else: + part.set_flag(parted.PARTITION_RAID, 0) + + partedUtils.set_partition_file_system_type(part, + request.fstype) + +def mustHaveSelectedDrive(intf): + txt =_("You need to select at least one hard drive to install %s.") % (name,) + intf.messageWindow(_("Error"), txt, custom_icon="error") + +def queryNoFormatPreExisting(intf): + """Ensure the user wants to use a partition without formatting.""" + txt = _("You have chosen to use a pre-existing " + "partition for this installation without formatting it. " + "We recommend that you format this partition " + "to make sure files from a previous operating system installation " + "do not cause problems with this installation of Linux. " + "However, if this partition contains files that you need " + "to keep, such as home directories, then " + "continue without formatting this partition.") + rc = intf.messageWindow(_("Format?"), txt, type = "custom", custom_buttons=[_("_Modify Partition"), _("Do _Not Format")], custom_icon="warning") + return rc + +def partitionSanityErrors(intf, errors): + """Errors were found sanity checking. Tell the user they must fix.""" + rc = 1 + if errors: + errorstr = string.join(errors, "\n\n") + rc = intf.messageWindow(_("Error with Partitioning"), + _("The following critical errors exist " + "with your requested partitioning " + "scheme. " + "These errors must be corrected prior " + "to continuing with your install of " + "%s.\n\n%s") %(name, errorstr), + custom_icon="error") + return rc + +def partitionSanityWarnings(intf, warnings): + """Sanity check found warnings. Make sure the user wants to continue.""" + rc = 1 + if warnings: + warningstr = string.join(warnings, "\n\n") + rc = intf.messageWindow(_("Partitioning Warning"), + _("The following warnings exist with " + "your requested partition scheme.\n\n%s" + "\n\nWould you like to continue with " + "your requested partitioning " + "scheme?") % (warningstr), + type="yesno", custom_icon="warning") + return rc + + +def partitionPreExistFormatWarnings(intf, warnings): + """Double check that preexistings being formatted are fine.""" + rc = 1 + if warnings: + + labelstr1 = _("The following pre-existing partitions have been " + "selected to be formatted, destroying all data.") + + labelstr2 = _("Select 'Yes' to continue and format these " + "partitions, or 'No' to go back and change these " + "settings.") + commentstr = "" + for (dev, type, mntpt) in warnings: + commentstr = commentstr + "/dev/%s %s %s\n" % (dev,type,mntpt) + rc = intf.messageWindow(_("Format Warning"), "%s\n\n%s\n\n%s" % + (labelstr1, labelstr2, commentstr), + type="yesno", custom_icon="warning") + return rc + +def getPreExistFormatWarnings(partitions, diskset): + """Return a list of preexisting partitions being formatted.""" + + devs = [] + for request in partitions.requests: + if request.getPreExisting() == 1: + devs.append(request.uniqueID) + + devs.sort() + + rc = [] + for dev in devs: + request = partitions.getRequestByID(dev) + if request.format: + if request.fstype.isMountable(): + mntpt = request.mountpoint + else: + mntpt = "" + + if isinstance(request, partRequests.PartitionSpec): + dev = request.device + elif isinstance(request, partRequests.RaidRequestSpec): + dev = "md%s" %(request.raidminor,) + elif isinstance(request, partRequests.VolumeGroupRequestSpec): + dev = request.volumeGroupName + elif isinstance(request, partRequests.LogicalVolumeRequestSpec): + vgreq = partitions.getRequestByID(request.volumeGroup) + dev = "%s/%s" %(vgreq.volumeGroupName, + request.logicalVolumeName) + + rc.append((dev, request.fstype.getName(), mntpt)) + + if len(rc) == 0: + return None + else: + return rc + +def confirmDeleteRequest(intf, request): + """Confirm the deletion of a request.""" + if not request: + return + + if request.type == REQUEST_VG: + errmsg = (_("You are about to delete the volume group "%s"." + "\n\nALL logical volumes in this volume group " + "will be lost!") % (request.volumeGroupName,)) + elif request.type == REQUEST_LV: + errmsg = (_("You are about to delete the logical volume "%s".") + % (request.logicalVolumeName,)) + elif request.type == REQUEST_RAID: + errmsg = _("You are about to delete a RAID device.") + else: + if request.device: + errmsg = _("You are about to delete the /dev/%s partition.") % (request.device,) + else: + # XXX can this ever happen? + errmsg = _("The partition you selected will be deleted.") + + rc = intf.messageWindow(_("Confirm Delete"), errmsg, type="custom", + custom_buttons=[_("Cancel"), _("_Delete")], + custom_icon="question") + + return rc + +def confirmResetPartitionState(intf): + """Confirm reset of partitioning to that present on the system.""" + rc = intf.messageWindow(_("Confirm Reset"), + _("Are you sure you want to reset the " + "partition table to its original state?"), + type="yesno", custom_icon="question") + return rc diff --git a/pkgs/core/pomona/src/partRequests.py b/pkgs/core/pomona/src/partRequests.py new file mode 100644 index 0000000..25f70b7 --- /dev/null +++ b/pkgs/core/pomona/src/partRequests.py @@ -0,0 +1,1038 @@ +# +# partRequests.py: partition request objects and management thereof +# +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Matt Wilson <msw@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# Mike Fulbright <msf@redhat.com> +# Harald Hoyer <harald@redhat.de> +# + +"""Partition request objects and management thereof.""" + +import parted +import iutil +import string +import os, sys, math + +from constants import * + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +import fsset +import raid +import lvm +import partedUtils +import partIntfHelpers + +import logging +log = logging.getLogger("pomona") + +class DeleteSpec: + """Defines a preexisting partition which is intended to be removed.""" + + def __init__(self, drive, start, end): + """Initializes a DeleteSpec. + + drive is the text form of the drive + start is the start sector of the deleted partition + end is the end sector of the deleted partition + """ + + self.drive = drive + self.start = start + self.end = end + + def __str__(self): + return "drive: %s start: %s end: %s" %(self.drive, self.start, + self.end) + +class DeleteLogicalVolumeSpec: + """Defines a preexisting logical volume which is intended to be removed.""" + + def __init__(self, name, vg): + """Initializes a DeleteLogicalVolumeSpec. + + name is the name of the lv + vg is the name of the volume group + """ + + self.name = name + self.vg = vg + self.deleted = 0 + + def __str__(self): + return "lvname: %s vgname: %s" %(self.name, self.vg) + + def beenDeleted(self): + return self.deleted + + def setDeleted(self, val): + self.deleted = val + +class DeleteVolumeGroupSpec: + """Defines a preexisting volume group which is intended to be removed.""" + + def __init__(self, name): + """Initializes a DeleteVolumeGroupSpec + + name is the name of the volume group + """ + + self.name = name + self.deleted = 0 + + def __str__(self): + return "vgname: %s" %(self.name,) + + def beenDeleted(self): + return self.deleted + + def setDeleted(self, val): + self.deleted = val + +class DeleteRAIDSpec: + """Defines a preexisting RAID device which is intended to be removed.""" + + def __init__(self, minor): + """Initializes a DeleteRAIDSpec. + + minor is the minor of the RAID device being removed + """ + + self.minor = minor + + def __str__(self): + return "minor: %s" %(self.minor,) + +class RequestSpec: + """Generic Request specification.""" + def __init__(self, fstype, size = None, mountpoint = None, format = None, + preexist = 0, fslabel = None, + migrate = None, origfstype = None, + fsprofile = None): + """Create a generic RequestSpec. + + This should probably never be externally used. + """ + + self.fstype = fstype + self.mountpoint = mountpoint + self.size = size + self.format = format + + self.migrate = migrate + self.origfstype = origfstype + self.fslabel = fslabel + self.fsopts = None + self.fsprofile = fsprofile + + self.device = None + """what we currently think the device is""" + + self.uniqueID = None + """uniqueID is an integer and *MUST* be unique.""" + + self.ignoreBootConstraints = 0 + """Booting constraints should be ignored for this request.""" + + self.preexist = preexist + """Did this partition exist before we started playing with things?""" + + self.protected = 0 + """Is this partitiion 'protected', ie does it contain install media.""" + + self.dev = None + """A Device() as defined in fsset.py to correspond to this request.""" + + self.encryption = None + """An optional LUKSDevice() describing block device encryption.""" + + self.targetSize = None + """Size to resize to""" + + self.resizable = False + """Is this a request that can be resized?""" + + def __str__(self): + if self.fstype: + fsname = self.fstype.getName() + else: + fsname = "None" + + str = ("Generic Request -- mountpoint: %(mount)s uniqueID: %(id)s\n" + " type: %(fstype)s format: %(format)s\n" + " device: %(dev)s migrate: %(migrate)s fslabel: %(fslabel)s\n" + " options: '%(fsopts)s'" + " fsprofile: %(fsprofile)s" % + {"mount": self.mountpoint, "id": self.uniqueID, + "fstype": fsname, "format": self.format, + "dev": self.device, "migrate": self.migrate, + "fslabel": self.fslabel, + "fsopts": self.fsopts, "fsprofile": self.fsprofile}) + return str + + def getActualSize(self, partitions, diskset): + """Return the actual size allocated for the request in megabytes.""" + + sys.stderr.write("WARNING: Abstract RequestSpec.getActualSize() called\n") + import traceback + traceback.print_stack() + + def getDevice(self, partitions): + """Return a device to solidify.""" + + sys.stderr.write("WARNING: Abstract RequestSpec.getDevice() called\n") + import traceback + traceback.print_stack() + + def isResizable(self, partitions): + if self.isEncrypted(partitions): # FIXME: can't resize crypted devs yet + return False + return self.resizable and self.fstype is not None and self.fstype.isResizable() + + def isEncrypted(self, partitions, parentOnly = False): + if self.encryption: + return True + return False + + def toEntry(self, partitions): + """Turn a request into a fsset entry and return the entry.""" + device = self.getDevice(partitions) + + # pin down our partitions so that we can reread the table + device.solidify() + + if self.fstype.getName() == "swap": + mountpoint = "swap" + else: + mountpoint = self.mountpoint + + entry = fsset.FileSystemSetEntry(device, mountpoint, self.fstype, + origfsystem=self.origfstype, + options=self.fsopts, + fsprofile=self.fsprofile) + if self.format: + entry.setFormat(self.format) + + if self.migrate: + entry.setMigrate(self.migrate) + + if self.fslabel: + entry.setLabel(self.fslabel) + + if self.targetSize and self.fstype.isResizable(): + entry.setResizeTarget(self.targetSize, self.size) + + return entry + + def setProtected(self, val): + """Set the protected value for this partition.""" + self.protected = val + + def getProtected(self): + """Return the protected value for this partition.""" + return self.protected + + def getPreExisting(self): + """Return whether the partition existed before we started playing.""" + return self.preexist + + def doMountPointLinuxFSChecks(self): + """Return an error string if the mountpoint is not valid for Linux FS.""" + mustbeonroot = ('/bin','/dev','/sbin','/etc','/lib','/root', + '/mnt', 'lost+found', '/proc') + mustbeonlinuxfs = ('/', '/boot', '/var', '/tmp', '/usr', '/home', + '/usr/share', '/usr/lib' ) + + # these are symlinks so you cant make them mount points + otherexcept = ('/var/mail', '/usr/bin/X11', '/usr/lib/X11', '/usr/tmp') + + if not self.mountpoint: + return None + + if self.fstype is None: + return None + + if self.fstype.isMountable(): + if self.mountpoint in mustbeonroot: + return _("This mount point is invalid. The %s directory must " + "be on the / file system.") % (self.mountpoint,) + elif self.mountpoint in otherexcept: + return _("The mount point %s cannot be used. It must " + "be a symbolic link for proper system " + "operation. Please select a different " + "mount point.") % (self.mountpoint,) + + return None + + if not self.fstype.isLinuxNativeFS(): + if self.mountpoint in mustbeonlinuxfs: + return _("This mount point must be on a linux file system.") + + return None + + # requestSkipList is a list of uids for requests to ignore when + # looking for a conflict on the mount point name. Used in lvm + # editting code in disk druid, for example. + def isMountPointInUse(self, partitions, requestSkipList=None): + """Return whether my mountpoint is in use by another request.""" + mntpt = self.mountpoint + if not mntpt: + return None + + if partitions and partitions.requests: + for request in partitions.requests: + if requestSkipList is not None and request.uniqueID in requestSkipList: + continue + + if request.mountpoint == mntpt: + if (not self.uniqueID or + request.uniqueID != self.uniqueID): + return _("The mount point "%s" is already in use, " + "please choose a different mount point." + %(mntpt)) + return None + + def doSizeSanityCheck(self): + """Sanity check that the size of the request is sane.""" + if not self.fstype: + return None + + if not self.format: + return None + + if self.size and self.size > self.fstype.getMaxSizeMB(): + return (_("The size of the %s partition (%10.2f MB) " + "exceeds the maximum size of %10.2f MB.") + % (self.fstype.getName(), self.size, + self.fstype.getMaxSizeMB())) + + return None + + # set skipMntPtExistCheck to non-zero if you want to handle this + # check yourself. Used in lvm volume group editting code, for example. + def sanityCheckRequest(self, partitions, skipMntPtExistCheck=0): + """Run the basic sanity checks on the request.""" + # see if mount point is valid if its a new partition request + mntpt = self.mountpoint + fstype = self.fstype + preexist = self.preexist + format = self.format + + rc = self.doSizeSanityCheck() + if rc: + return rc + + rc = partIntfHelpers.sanityCheckMountPoint(mntpt, fstype, preexist, format) + if rc: + return rc + + if not skipMntPtExistCheck: + rc = self.isMountPointInUse(partitions) + if rc: + return rc + + rc = self.doMountPointLinuxFSChecks() + if rc: + return rc + + return None + + + def formatByDefault(self): + """Return whether or not the request should be formatted by default.""" + def inExceptionList(mntpt): + exceptlist = ['/home', '/usr/local', '/opt', '/var/www'] + for q in exceptlist: + if os.path.commonprefix([mntpt, q]) == q: + return 1 + return 0 + + # check first to see if its a Linux filesystem or not + formatlist = ['/boot', '/var', '/tmp', '/usr'] + + if not self.fstype: + return 0 + + if not self.fstype.isLinuxNativeFS(): + return 0 + + if self.fstype.isMountable(): + mntpt = self.mountpoint + if mntpt == "/": + return 1 + + if mntpt in formatlist: + return 1 + + for p in formatlist: + if os.path.commonprefix([mntpt, p]) == p: + if inExceptionList(mntpt): + return 0 + else: + return 1 + + return 0 + else: + if self.fstype.getName() == "swap": + return 1 + + # be safe for anything else and default to off + return 0 + + +# XXX preexistings store start/end as sectors, new store as cylinders. ICK +class PartitionSpec(RequestSpec): + """Object to define a requested partition.""" + + # XXX eep, still a few too many options but a lot better + def __init__(self, fstype, size = None, mountpoint = None, + preexist = 0, migrate = None, grow = 0, maxSizeMB = None, + start = None, end = None, drive = None, primary = None, + format = None, multidrive = None, + fslabel = None, fsprofile=None): + """Create a new PartitionSpec object. + + fstype is the fsset filesystem type. + size is the requested size (in megabytes). + mountpoint is the mountpoint. + grow is whether or not the partition is growable. + maxSizeMB is the maximum size of the partition in megabytes. + start is the starting cylinder/sector (new/preexist). + end is the ending cylinder/sector (new/preexist). + drive is the drive the partition goes on. + primary is whether or not the partition should be forced as primary. + format is whether or not the partition should be formatted. + preexist is whether this partition is preexisting. + migrate is whether or not the partition should be migrated. + multidrive specifies if this is a request that should be replicated + across _all_ of the drives in drive + fslabel is the label to give to the filesystem. + fsprofile is the usage profile for the filesystem. + """ + + # if it's preexisting, the original fstype should be set + if preexist == 1: + origfs = fstype + else: + origfs = None + + RequestSpec.__init__(self, fstype = fstype, size = size, + mountpoint = mountpoint, format = format, + preexist = preexist, migrate = None, + origfstype = origfs, + fslabel = fslabel, fsprofile = fsprofile) + self.type = REQUEST_NEW + + self.grow = grow + self.maxSizeMB = maxSizeMB + self.requestSize = size + self.start = start + self.end = end + + self.drive = drive + self.primary = primary + self.multidrive = multidrive + + # should be able to map this from the device =\ + self.currentDrive = None + """Drive that this request will currently end up on.""" + + + def __str__(self): + if self.fstype: + fsname = self.fstype.getName() + else: + fsname = "None" + + if self.origfstype: + oldfs = self.origfstype.getName() + else: + oldfs = "None" + + if self.preexist == 0: + pre = "New" + else: + pre = "Existing" + + if self.encryption is None: + crypto = "None" + else: + crypto = self.encryption.getScheme() + + str = ("%(n)s Part Request -- mountpoint: %(mount)s uniqueID: %(id)s\n" + " type: %(fstype)s format: %(format)s \n" + " device: %(dev)s drive: %(drive)s primary: %(primary)s\n" + " size: %(size)s grow: %(grow)s maxsize: %(max)s\n" + " start: %(start)s end: %(end)s migrate: %(migrate)s " + " fslabel: %(fslabel)s origfstype: %(origfs)s\n" + " options: '%(fsopts)s'\n" + " fsprofile: %(fsprofile)s encryption: %(encryption)s" % + {"n": pre, "mount": self.mountpoint, "id": self.uniqueID, + "fstype": fsname, "format": self.format, "dev": self.device, + "drive": self.drive, "primary": self.primary, + "size": self.size, "grow": self.grow, "max": self.maxSizeMB, + "start": self.start, "end": self.end, + "migrate": self.migrate, "fslabel": self.fslabel, + "origfs": oldfs, + "fsopts": self.fsopts, "fsprofile": self.fsprofile, + "encryption": crypto}) + return str + + + def getDevice(self, partitions): + """Return a device to solidify.""" + if self.dev: + return self.dev + + self.dev = fsset.PartitionDevice(self.device, + encryption = self.encryption) + + return self.dev + + def getActualSize(self, partitions, diskset): + """Return the actual size allocated for the request in megabytes.""" + part = partedUtils.get_partition_by_name(diskset.disks, self.device) + if not part: + # XXX kickstart might still call this before allocating the partitions + raise RuntimeError, "Checking the size of a partition which hasn't been allocated yet" + return partedUtils.getPartSizeMB(part) + + def doSizeSanityCheck(self): + """Sanity check that the size of the partition is sane.""" + if not self.fstype: + return None + if not self.format: + return None + ret = RequestSpec.doSizeSanityCheck(self) + if ret is not None: + return ret + + if (self.size and self.maxSizeMB + and (self.size > self.maxSizeMB)): + return (_("The size of the requested partition (size = %s MB) " + "exceeds the maximum size of %s MB.") + % (self.size, self.maxSizeMB)) + + if self.size and self.size < 0: + return _("The size of the requested partition is " + "negative! (size = %s MB)") % (self.size) + + if self.start and self.start < 1: + return _("Partitions can't start below the first cylinder.") + + if self.end and self.end < 1: + return _("Partitions can't end on a negative cylinder.") + + return None + +class NewPartitionSpec(PartitionSpec): + """Object to define a NEW requested partition.""" + + # XXX eep, still a few too many options but a lot better + def __init__(self, fstype, size = None, mountpoint = None, + grow = 0, maxSizeMB = None, + start = None, end = None, + drive = None, primary = None, format = None): + """Create a new NewPartitionSpec object. + + fstype is the fsset filesystem type. + size is the requested size (in megabytes). + mountpoint is the mountpoint. + grow is whether or not the partition is growable. + maxSizeMB is the maximum size of the partition in megabytes. + start is the starting cylinder. + end is the ending cylinder. + drive is the drive the partition goes on. + primary is whether or not the partition should be forced as primary. + format is whether or not the partition should be formatted. + """ + + PartitionSpec.__init__(self, fstype = fstype, size = size, + mountpoint = mountpoint, grow = grow, + maxSizeMB = maxSizeMB, start = start, + end = end, drive = drive, primary = primary, + format = format, preexist = 0) + self.type = REQUEST_NEW + +class PreexistingPartitionSpec(PartitionSpec): + """Request to represent partitions which already existed.""" + + def __init__(self, fstype, size = None, start = None, end = None, + drive = None, format = None, migrate = None, + mountpoint = None): + """Create a new PreexistingPartitionSpec object. + + fstype is the fsset filesystem type. + size is the size (in megabytes). + start is the starting sector. + end is the ending sector. + drive is the drive which the partition is on. + format is whether or not the partition should be formatted. + migrate is whether or not the partition fs should be migrated. + mountpoint is the mountpoint. + """ + + PartitionSpec.__init__(self, fstype = fstype, size = size, + start = start, end = end, drive = drive, + format = format, migrate = migrate, + mountpoint = mountpoint, preexist = 1) + self.type = REQUEST_PREEXIST + self.resizable = True + + self.maxResizeSize = None + """Maximum size of this partition request""" + + def getMaximumResizeMB(self, partitions): + if self.maxResizeSize is not None: + return self.maxResizeSize + log.warning("%s doesn't have a max size set" %(self.device,)) + return MAX_PART_SIZE + + def getMinimumResizeMB(self, partitions): + return self.fstype.getMinimumSize(self.device) + +class RaidRequestSpec(RequestSpec): + """Request to represent RAID devices.""" + + def __init__(self, fstype, format = None, mountpoint = None, + raidlevel = None, raidmembers = None, + raidspares = None, raidminor = None, fslabel = None, + preexist = 0, chunksize = None, + fsprofile = None): + """Create a new RaidRequestSpec object. + + fstype is the fsset filesystem type. + format is whether or not the partition should be formatted. + mountpoint is the mountpoint. + raidlevel is the raidlevel (as 'RAID0', 'RAID1', 'RAID5'). + chunksize is the chunksize which should be used. + raidmembers is list of ids corresponding to the members of the RAID. + raidspares is the number of spares to setup. + raidminor is the minor of the device which should be used. + fslabel is the label of the filesystem. + fsprofile is the usage profile for the filesystem. + """ + + # if it's preexisting, the original fstype should be set + if preexist == 1: + origfs = fstype + else: + origfs = None + + RequestSpec.__init__(self, fstype = fstype, format = format, + mountpoint = mountpoint, preexist = preexist, + origfstype = origfs, + fslabel=fslabel, fsprofile=fsprofile) + self.type = REQUEST_RAID + + + self.raidlevel = raidlevel + self.raidmembers = raidmembers + self.raidspares = raidspares + self.raidminor = raidminor + self.chunksize = chunksize + + def __str__(self): + if self.fstype: + fsname = self.fstype.getName() + else: + fsname = "None" + raidmem = [] + if self.raidmembers: + for i in self.raidmembers: + raidmem.append(i) + + if self.encryption is None: + crypto = "None" + else: + crypto = self.encryption.getScheme() + + str = ("RAID Request -- mountpoint: %(mount)s uniqueID: %(id)s\n" + " type: %(fstype)s format: %(format)s\n" + " raidlevel: %(level)s raidspares: %(spares)s\n" + " raidmembers: %(members)s fsprofile: %(fsprofile)s\n" + " encryption: %(encryption)s" % + {"mount": self.mountpoint, "id": self.uniqueID, + "fstype": fsname, "format": self.format, + "level": self.raidlevel, "spares": self.raidspares, + "members": self.raidmembers, "fsprofile": self.fsprofile, + "encryption": crypto + }) + return str + + def getDevice(self, partitions): + """Return a device which can be solidified.""" + # Alway return a new device for minor changing + raidmems = [] + for member in self.raidmembers: + request = partitions.getRequestByID(member) + raidmems.append(request.getDevice(partitions)) + self.dev = fsset.RAIDDevice(int(self.raidlevel[4:]), + raidmems, minor = self.raidminor, + spares = self.raidspares, + existing = self.preexist, + chunksize = self.chunksize, + encryption = self.encryption) + return self.dev + + def isEncrypted(self, partitions, parentOnly = False): + if RequestSpec.isEncrypted(self, partitions) is True: + return True + if parentOnly: + return False + for member in self.raidmembers: + if partitions.getRequestByID(member).isEncrypted(partitions): + return True + return False + + def getActualSize(self, partitions, diskset): + """Return the actual size allocated for the request in megabytes.""" + + # this seems like a check which should never fail... + if not self.raidmembers or not self.raidlevel: + return 0 + nummembers = len(self.raidmembers) - self.raidspares + smallest = None + sum = 0 + for member in self.raidmembers: + req = partitions.getRequestByID(member) + partsize = req.getActualSize(partitions, diskset) + + if raid.isRaid0(self.raidlevel): + sum = sum + partsize + else: + if not smallest: + smallest = partsize + elif partsize < smallest: + smallest = partsize + + if raid.isRaid0(self.raidlevel): + return sum + elif raid.isRaid1(self.raidlevel): + return smallest + elif raid.isRaid5(self.raidlevel): + return (nummembers-1) * smallest + elif raid.isRaid6(self.raidlevel): + return (nummembers-2) * smallest + elif raid.isRaid10(self.raidlevel): + return (nummembers/2) * smallest + else: + raise ValueError, "Invalid raidlevel in RaidRequest.getActualSize" + + + # do RAID specific sanity checks; this is an internal function + def sanityCheckRaid(self, partitions): + if not self.raidmembers or not self.raidlevel: + return _("No members in RAID request, or not RAID " + "level specified.") + + minmembers = raid.get_raid_min_members(self.raidlevel) + if len(self.raidmembers) < minmembers: + return _("A RAID device of type %s " + "requires at least %s members.") % (self.raidlevel, + minmembers) + + if len(self.raidmembers) > 27: + return "RAID devices are limited to 27 members." + + if self.raidspares: + if (len(self.raidmembers) - self.raidspares) < minmembers: + return _("This RAID device can have a maximum of %s spares. " + "To have more spares you will need to add members to " + "the RAID device.") % (len(self.raidmembers) + - minmembers ) + return None + + def sanityCheckRequest(self, partitions): + """Run the basic sanity checks on the request.""" + rc = self.sanityCheckRaid(partitions) + if rc: + return rc + + return RequestSpec.sanityCheckRequest(self, partitions) + +class VolumeGroupRequestSpec(RequestSpec): + """Request to represent volume group devices.""" + + def __init__(self, fstype =None, format = None, + vgname = None, physvols = None, + pesize = 32768, preexist = 0, + preexist_size = 0): + """Create a new VolumeGroupRequestSpec object. + + fstype is the fsset filesystem type. + format is whether or not the volume group should be created. + vgname is the name of the volume group. + physvols is a list of the ids for the physical volumes in the vg. + pesize is the size of a physical extent in kilobytes. + preexist is whether the volume group is preexisting. + preexist_size is the size of a preexisting VG read from /proc + (note that this is unclamped) + """ + + if not fstype: + fstype = fsset.fileSystemTypeGet("volume group (LVM)") + RequestSpec.__init__(self, fstype = fstype, format = format) + self.type = REQUEST_VG + + self.volumeGroupName = vgname + self.physicalVolumes = physvols + self.pesize = pesize + self.preexist = preexist + self.free = 0 + + # FIXME: this is a hack so that we can set the vg name automagically + # with autopartitioning to not conflict with existing vgs + self.autoname = 0 + + if preexist and preexist_size: + self.preexist_size = preexist_size + else: + self.preexist_size = None + + def __str__(self): + physvols = [] + if self.physicalVolumes: + for i in self.physicalVolumes: + physvols.append(i) + + str = ("VG Request -- name: %(vgname)s uniqueID: %(id)s\n" + " format: %(format)s pesize: %(pesize)s \n" + " physvols: %(physvol)s" % + {"vgname": self.volumeGroupName, "id": self.uniqueID, + "format": self.format, "physvol": physvols, + "pesize": self.pesize}) + return str + + def getDevice(self, partitions): + """Return a device which can be solidified.""" + if self.dev: + # FIXME: this warning can probably be removed post-beta + log.warning("getting self.dev more than once for %s" %(self,)) + return self.dev + + pvs = [] + for pv in self.physicalVolumes: + r = partitions.getRequestByID(pv) + # a size of zero implies we did autopartitioning of + # pvs everywhere we could + if (r.size > 0) or (r.device is not None): + pvs.append(r.getDevice(partitions)) + self.dev = fsset.VolumeGroupDevice(self.volumeGroupName, pvs, + self.pesize, + existing = self.preexist) + return self.dev + + def isEncrypted(self, partitions, parentOnly = False): + if RequestSpec.isEncrypted(self, partitions) is True: + return True + if parentOnly: + return False + for pvid in self.physicalVolumes: + pv = partitions.getRequestByID(pvid) + if pv.isEncrypted(partitions): + return True + return False + + def getActualSize(self, partitions, diskset): + """Return the actual size allocated for the request in megabytes.""" + + # if we have a preexisting size, use it + if self.preexist and self.preexist_size: + totalspace = lvm.clampPVSize(self.preexist_size, self.pesize) + else: + totalspace = 0 + for pvid in self.physicalVolumes: + pvreq = partitions.getRequestByID(pvid) + size = pvreq.getActualSize(partitions, diskset) + #log.info("size for pv %s is %s" % (pvid, size)) + size = lvm.clampPVSize(size, self.pesize) - (self.pesize/1024) + #log.info(" clamped size is %s" % (size,)) + totalspace = totalspace + size + + return totalspace + +class PartialVolumeGroupSpec: + """Request to represent partial volume group devices.""" + # note, these are just used as placeholders so we don't collide on names + + def __init__(self, vgname = None): + """Create a new PartialVolumeGroupSpec object. + + vgname is the name of the volume group. + """ + + self.volumeGroupName = vgname + + def __str__(self): + str = ("Partial VG Request -- name: %(vgname)s" % + {"vgname": self.volumeGroupName}) + return str + +class LogicalVolumeRequestSpec(RequestSpec): + """Request to represent logical volume devices.""" + + def __init__(self, fstype, format = None, mountpoint = None, + size = None, volgroup = None, lvname = None, + preexist = 0, percent = None, grow=0, maxSizeMB=0, + fslabel = None, fsprofile = None): + """Create a new VolumeGroupRequestSpec object. + + fstype is the fsset filesystem type. + format is whether or not the volume group should be created. + mountpoint is the mountpoint for the request. + size is the size of the request in MB. + volgroup is the request ID of the volume group. + lvname is the name of the logical volume. + preexist is whether the logical volume previously existed or not. + percent is the percentage of the volume group's space this should use. + grow is whether or not to use free space remaining. + maxSizeMB is max size to grow to. + fslabel is the label of the filesystem on the logical volume. + fsprofile is the usage profile for the filesystem. + """ + + # if it's preexisting, the original fstype should be set + if preexist == 1: + origfs = fstype + else: + origfs = None + + RequestSpec.__init__(self, fstype = fstype, format = format, + mountpoint = mountpoint, size = size, + preexist = preexist, origfstype = origfs, + fslabel = fslabel, fsprofile = fsprofile) + + self.type = REQUEST_LV + + self.logicalVolumeName = lvname + self.volumeGroup = volgroup + self.percent = percent + self.grow = grow + self.maxSizeMB = maxSizeMB + self.startSize = size + + self.minResizeSize = None + self.resizable = True + + if not percent and not size and not preexist: + raise RuntimeError, "Error with Volume Group:Logical Volume %s:%s - Logical Volume must specify either percentage of vgsize or size" % (volgroup, lvname) + + if percent and grow: + raise RuntimeError, "Error with Volume Group:Logical Volume %s:%s - Logical Volume cannot grow if percentage given" % (volgroup, lvname) + + def __str__(self): + if self.fstype: + fsname = self.fstype.getName() + else: + fsname = "None" + + if self.size is not None: + size = self.size + else: + size = "%s percent" %(self.percent,) + + if self.encryption is None: + crypto = "None" + else: + crypto = self.encryption.getScheme() + + str = ("LV Request -- mountpoint: %(mount)s uniqueID: %(id)s\n" + " type: %(fstype)s format: %(format)s\n" + " size: %(size)s lvname: %(lvname)s volgroup: %(vgid)s\n" + " options: '%(fsopts)s' fsprofile: %(fsprofile)s" + " encryption: '%(crypto)s'" % + {"mount": self.mountpoint, "id": self.uniqueID, + "fstype": fsname, "format": self.format, + "lvname": self.logicalVolumeName, "vgid": self.volumeGroup, + "size": size, "crypto": crypto, + "fsopts": self.fsopts, "fsprofile": self.fsprofile}) + return str + + def getDevice(self, partitions): + """Return a device which can be solidified.""" + vg = partitions.getRequestByID(self.volumeGroup) + vgname = vg.volumeGroupName + self.dev = fsset.LogicalVolumeDevice(vgname, self.size, + self.logicalVolumeName, + vg = vg, + existing = self.preexist, + encryption = self.encryption) + return self.dev + + def isEncrypted(self, partitions, parentOnly = False): + if RequestSpec.isEncrypted(self, partitions) is True: + return True + if parentOnly: + return False + vg = partitions.getRequestByID(self.volumeGroup) + if vg.isEncrypted(partitions): + return True + return False + + def getActualSize(self, partitions = None, diskset = None, target = False): + """Return the actual size allocated for the request in megabytes.""" + if self.percent: + if partitions is None or diskset is None: + raise RuntimeError, "trying to get a percentage lv size on resize path" + vgreq = partitions.getRequestByID(self.volumeGroup) + vgsize = vgreq.getActualSize(partitions, diskset) + lvsize = int(self.percent * 0.01 * vgsize) + #lvsize = lvm.clampLVSizeRequest(lvsize, vgreq.pesize) + return lvsize + # FIXME: the target bit here is a bit of a hack... + elif self.targetSize is not None and target: + return self.targetSize + else: + return self.size + + def getStartSize(self): + """Return the starting size allocated for the request in megabytes.""" + return self.startSize + + def setSize(self, size): + """Set the size (in MB) of request (does not clamp to PE however) + + size - size in MB + """ + if self.percent: + self.percent = None + + self.size = size + + def sanityCheckRequest(self, partitions, skipMntPtExistCheck=0, pesize=32768): + """Run the basic sanity checks on the request.""" + if not self.grow and not self.percent and self.size*1024 < pesize: + return _("Logical volume size must be larger than the volume " + "group's physical extent size.") + + return RequestSpec.sanityCheckRequest(self, partitions, skipMntPtExistCheck) + + def getMaximumResizeMB(self, partitions): + vg = partitions.getRequestByID(self.volumeGroup) + print("max is", self.getActualSize(), vg.free, self.getActualSize() + vg.free) + return self.getActualSize() + vg.free + + def getMinimumResizeMB(self, partitions): + if self.minResizeSize is None: + log.warning("don't know the minimum size of %s" %(self.logicalVolumeName,)) + return 1 + return self.minResizeSize diff --git a/pkgs/core/pomona/src/partedUtils.py b/pkgs/core/pomona/src/partedUtils.py new file mode 100644 index 0000000..62e542e --- /dev/null +++ b/pkgs/core/pomona/src/partedUtils.py @@ -0,0 +1,1189 @@ +# +# partedUtils.py: helper functions for use with parted objects +# +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Matt Wilson <msw@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# Mike Fulbright <msf@redhat.com> +# Karsten Hopp <karsten@redhat.com> +# + +"""Helper functions for use when dealing with parted objects.""" + +import parted +import math +import os, sys, string, struct, resource + +import exception +import fsset +import iutil, isys +import raid +import dmraid +import block +import lvm +import inspect +from flags import flags +from errors import * +from constants import * + +import logging +log = logging.getLogger("pomona") + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +fsTypes = {} + +fs_type = parted.file_system_type_get_next () +while fs_type: + fsTypes[fs_type.name] = fs_type + fs_type = parted.file_system_type_get_next (fs_type) + + + +def get_flags (part): + """Retrieve a list of strings representing the flags on the partition.""" + string="" + if not part.is_active (): + return string + first=1 + flag = parted.partition_flag_next (0) + while flag: + if part.get_flag (flag): + string = string + parted.partition_flag_get_name (flag) + if first: + first = 0 + else: + string = string + ", " + flag = parted.partition_flag_next (flag) + return string + +def start_sector_to_cyl(device, sector): + """Return the closest cylinder (round down) to sector on device.""" + return int(math.floor((float(sector) + / (device.heads * device.sectors)) + 1)) + +def end_sector_to_cyl(device, sector): + """Return the closest cylinder (round up) to sector on device.""" + return int(math.ceil(float((sector + 1)) + / (device.heads * device.sectors))) + +def start_cyl_to_sector(device, cyl): + "Return the sector corresponding to cylinder as a starting cylinder." + return long((cyl - 1) * (device.heads * device.sectors)) + +def end_cyl_to_sector(device, cyl): + "Return the sector corresponding to cylinder as a ending cylinder." + return long(((cyl) * (device.heads * device.sectors)) - 1) + +def getPartSize(partition): + """Return the size of partition in sectors.""" + return partition.geom.length + +def getPartSizeMB(partition): + """Return the size of partition in megabytes.""" + return (partition.geom.length * partition.geom.dev.sector_size + / 1024.0 / 1024.0) + +def getDeviceSizeMB(dev): + """Return the size of dev in megabytes.""" + return (float(dev.heads * dev.cylinders * dev.sectors) / (1024 * 1024) + * dev.sector_size) + +def getMaxAvailPartSizeMB(part): + """Return the maximum size this partition can grow to by looking + at contiguous freespace partitions.""" + + disk = part.disk + maxlen = part.geom.length + + # let's look at the next partition(s) and if they're freespace, + # they can add to our maximum size. + np = disk.next_partition(part) + while np: + if np.type & parted.PARTITION_FREESPACE: + maxlen += np.geom.length + else: + break + np = disk.next_partition(np) + return math.floor(maxlen * part.geom.dev.sector_size / 1024.0 / 1024.0) + +def get_partition_by_name(disks, partname): + """Return the parted part object associated with partname. + + Arguments: + disks -- Dictionary of diskname->PedDisk objects + partname -- Name of partition to find + + Return: + PedPartition object with name partname. None if no such partition. + """ + for diskname in disks.keys(): + disk = disks[diskname] + part = disk.next_partition() + while part: + if get_partition_name(part) == partname: + return part + + part = disk.next_partition(part) + + return None + +def get_partition_name(partition): + """Return the device name for the PedPartition partition.""" + if (partition.geom.dev.type == parted.DEVICE_DAC960 + or partition.geom.dev.type == parted.DEVICE_CPQARRAY): + return "%sp%d" % (partition.geom.dev.path[5:], + partition.num) + if (parted.__dict__.has_key("DEVICE_SX8") and + partition.geom.dev.type == parted.DEVICE_SX8): + return "%sp%d" % (partition.geom.dev.path[5:], + partition.num) + + drive = partition.geom.dev.path[5:] + if (drive.startswith("cciss") or drive.startswith("ida") or + drive.startswith("rd") or drive.startswith("sx8") or + drive.startswith("mapper") or drive.startswith("mmcblk")): + sep = "p" + else: + sep = "" + return "%s%s%d" % (partition.geom.dev.path[5:], sep, partition.num) + + +def get_partition_file_system_type(part): + """Return the file system type of the PedPartition part. + + Arguments: + part -- PedPartition object + + Return: + Filesystem object (as defined in fsset.py) + """ + if part.fs_type is None and part.native_type == 0x41: + ptype = fsset.fileSystemTypeGet("PPC PReP Boot") + elif part.fs_type == None: + return None + elif (part.get_flag(parted.PARTITION_BOOT) == 1 and + getPartSizeMB(part) <= 1 and part.fs_type.name == "hfs"): + ptype = fsset.fileSystemTypeGet("Apple Bootstrap") + elif part.fs_type.name == "linux-swap": + ptype = fsset.fileSystemTypeGet("swap") + elif isEfiSystemPartition(part): + ptype = fsset.fileSystemTypeGet("efi") + elif isEfiSystemPartition(part): + ptype = fsset.fileSystemTypeGet("efi") + elif part.fs_type.name in ("fat16", "fat32"): + ptype = fsset.fileSystemTypeGet("vfat") + else: + try: + ptype = fsset.fileSystemTypeGet(part.fs_type.name) + except: + ptype = fsset.fileSystemTypeGet("foreign") + + return ptype + + +def set_partition_file_system_type(part, fstype): + """Set partition type of part to PedFileSystemType implied by fstype.""" + if fstype == None: + return + try: + for flag in fstype.getPartedPartitionFlags(): + if not part.is_flag_available(flag): + raise PartitioningError, ("requested FileSystemType needs " + "a flag that is not available.") + part.set_flag(flag, 1) + if isEfiSystemPartition(part): + part.set_system(parted.file_system_type_get("fat32")) + else: + part.set_system(fstype.getPartedFileSystemType()) + except: + print("Failed to set partition type to ",fstype.getName()) + pass + +def get_partition_drive(partition): + """Return the device name for disk that PedPartition partition is on.""" + return "%s" %(partition.geom.dev.path[5:]) + +def get_max_logical_partitions(disk): + if not disk.type.check_feature(parted.DISK_TYPE_EXTENDED): + return 0 + dev = disk.dev.path[5:] + for key in max_logical_partition_count.keys(): + if dev.startswith(key): + return max_logical_partition_count[key] + # FIXME: if we don't know about it, should we pretend it can't have + # logicals? probably safer to just use something reasonable + return 11 + +def map_foreign_to_fsname(type): + """Return the partition type associated with the numeric type.""" + if type in allPartitionTypesDict.keys(): + return allPartitionTypesDict[type] + else: + return _("Foreign") + +def filter_partitions(disk, func): + rc = [] + part = disk.next_partition () + while part: + if func(part): + rc.append(part) + part = disk.next_partition (part) + + return rc + +def get_all_partitions(disk): + """Return a list of all PedPartition objects on disk.""" + func = lambda part: part.is_active() + return filter_partitions(disk, func) + +def get_logical_partitions(disk): + """Return a list of logical PedPartition objects on disk.""" + func = lambda part: (part.is_active() + and part.type & parted.PARTITION_LOGICAL) + return filter_partitions(disk, func) + +def get_primary_partitions(disk): + """Return a list of primary PedPartition objects on disk.""" + func = lambda part: part.type == parted.PARTITION_PRIMARY + return filter_partitions(disk, func) + +def get_raid_partitions(disk): + """Return a list of RAID-type PedPartition objects on disk.""" + func = lambda part: (part.is_active() + and part.get_flag(parted.PARTITION_RAID) == 1) + return filter_partitions(disk, func) + +def get_lvm_partitions(disk): + """Return a list of physical volume-type PedPartition objects on disk.""" + func = lambda part: (part.is_active() + and part.get_flag(parted.PARTITION_LVM) == 1) + return filter_partitions(disk, func) + + +def getDefaultDiskType(): + """Get the default partition table type for this architecture.""" + return parted.disk_type_get("msdos") + +def hasGptLabel(diskset, device): + disk = diskset.disks[device] + return disk.type.name == "gpt" + +def isEfiSystemPartition(part): + if not part.is_active(): + return False + return (part.disk.type.name == "gpt" and + part.get_name() == "EFI System Partition" and + part.get_flag(parted.PARTITION_BOOT) == 1 and + part.fs_type.name in ("fat16", "fat32") and + isys.readFSLabel(get_partition_name(part)) != "pomona") + +archLabels = {'i386': ['msdos', 'gpt'], + 's390': ['dasd', 'msdos'], + 'alpha': ['bsd', 'msdos'], + 'sparc': ['sun'], + 'ia64': ['msdos', 'gpt'], + 'ppc': ['msdos', 'mac', 'amiga', 'gpt'], + 'x86_64': ['msdos', 'gpt']} + +def labelDisk(deviceFile, forceLabelType=None): + dev = parted.PedDevice.get(deviceFile) + label = getDefaultDiskType() + + if not forceLabelType is None: + label = forceLabelType + else: + if label.name == 'msdos' and \ + dev.length > (2L**41) / dev.sector_size and \ + 'gpt' in archLabels[iutil.getArch()]: + label = parted.disk_type_get('gpt') + + disk = dev.disk_new_fresh(label) + disk.commit() + return disk + +def checkDiskLabel(disk, intf): + """Check that the disk label on disk is valid for this machine type.""" + arch = iutil.getArch() + if arch in archLabels.keys(): + pass + else: + if disk.type.name == "msdos": + return 0 + + if intf: + rc = intf.messageWindow(_("Warning"), + _("/dev/%s currently has a %s partition " + "layout. To use this drive for " + "the installation of %s, it must be " + "re-initialized, causing the loss of " + "ALL DATA on this drive.\n\n" + "Would you like to re-initialize this " + "drive?") + %(disk.dev.path[5:], disk.type.name, + name), type="custom", + custom_buttons = [ _("_Ignore drive"), + _("_Re-initialize drive") ], + custom_icon="question") + + if rc == 0: + return 1 + else: + return -1 + else: + return 1 + +def hasProtectedPartitions(drive, pomona): + rc = False + if pomona is None: + return rc + + try: + for protected in pomona.id.partitions.protectedPartitions(): + if protected.startswith(drive): + part = protected[len(drive):] + if part[0] == "p": + part = part[1:] + if part.isdigit(): + rc = True + break + except: + pass + + return rc + +# attempt to associate a parted filesystem type on a partition that +# didn't probe as one type or another. +def validateFsType(part): + # we only care about primary and logical partitions + if not part.type in (parted.PARTITION_PRIMARY, + parted.PARTITION_LOGICAL): + return + # if the partition already has a type, no need to search + if part.fs_type: + return + + # first fsystem to probe wins, so sort the types into a preferred + # order. + fsnames = fsTypes.keys() + goodTypes = ['ext3', 'ext2'] + badTypes = ['linux-swap',] + for fstype in goodTypes: + fsnames.remove(fstype) + fsnames = goodTypes + fsnames + for fstype in badTypes: + fsnames.remove(fstype) + fsnames.extend(badTypes) + + # now check each type, and set the partition system accordingly. + for fsname in fsnames: + fstype = fsTypes[fsname] + if fstype.probe_specific(part.geom) != None: + # XXX verify that this will not modify system type + # in the case where a user does not modify partitions + part.set_system(fstype) + return + +def isLinuxNativeByNumtype(numtype): + """Check if the type is a 'Linux native' filesystem.""" + linuxtypes = [0x82, 0x83, 0x8e, 0xfd] + + for t in linuxtypes: + if int(numtype) == t: + return 1 + + return 0 + +def sniffFilesystemType(device): + """Sniff to determine the type of fs on device. + + device - name of device to sniff. + """ + return isys.readFSType(device) + +def getReleaseString(mountpoint): + if os.access(mountpoint + "/etc/redhat-release", os.R_OK): + f = open(mountpoint + "/etc/redhat-release", "r") + try: + lines = f.readlines() + except IOError: + try: + f.close() + except: + pass + return "" + f.close() + # return the first line with the newline at the end stripped + if len(lines) == 0: + return "" + relstr = string.strip(lines[0][:-1]) + + # get the release name and version + # assumes that form is something + # like "Red Hat Linux release 6.2 (Zoot)" + if relstr.find("release") != -1: + try: + idx = relstr.find("release") + prod = relstr[:idx - 1] + + ver = "" + for a in relstr[idx + 8:]: + if a in string.digits + ".": + ver = ver + a + else: + break + + relstr = prod + " " + ver + except: + pass # don't worry, just use the relstr as we have it + return relstr + return "" + +class DiskSet: + """The disks in the system.""" + + skippedDisks = [] + mdList = [] + exclusiveDisks = [] + + dmList = None + mpList = None + + def __init__ (self, pomona): + self.disks = {} + self.initializedDisks = {} + self.onlyPrimary = None + self.pomona = pomona + self.devicesOpen = False + + def onlyPrimaryParts(self): + for disk in self.disks.values(): + if disk.type.check_feature(parted.DISK_TYPE_EXTENDED): + return 0 + + return 1 + + def startMPath(self): + """Start all of the dm multipath devices associated with the DiskSet.""" + + if not DiskSet.mpList is None and DiskSet.mpList.__len__() > 0: + return + + log.debug("starting mpaths") + log.debug("self.driveList(): %s" % (self.driveList(),)) + log.debug("DiskSet.skippedDisks: %s" % (DiskSet.skippedDisks,)) + driveList = filter(lambda x: x not in DiskSet.skippedDisks, + self.driveList()) + log.debug("DiskSet.skippedDisks: %s" % (DiskSet.skippedDisks,)) + + mpList = dmraid.startAllMPath(driveList) + DiskSet.mpList = mpList + log.debug("done starting mpaths. Drivelist: %s" % \ + (self.driveList(),)) + + def renameMPath(self, mp, name): + dmraid.renameMPath(mp, name) + + def stopMPath(self): + """Stop all of the mpath devices associated with the DiskSet.""" + + if DiskSet.mpList: + dmraid.stopAllMPath(DiskSet.mpList) + DiskSet.mpList = None + + def startDmRaid(self): + """Start all of the dmraid devices associated with the DiskSet.""" + + if not DiskSet.dmList is None: + return + + log.debug("starting dmraids") + log.debug("self.driveList(): %s" % (self.driveList(),)) + log.debug("DiskSet.skippedDisks: %s" % (DiskSet.skippedDisks,)) + driveList = filter(lambda x: x not in DiskSet.skippedDisks, + self.driveList()) + log.debug("DiskSet.skippedDisks: %s" % (DiskSet.skippedDisks,)) + + dmList = dmraid.startAllRaid(driveList) + DiskSet.dmList = dmList + log.debug("done starting dmraids. Drivelist: %s" % \ + (self.driveList(),)) + + def renameDmRaid(self, rs, name): + dmraid.renameRaidSet(rs, name) + + def stopDmRaid(self): + """Stop all of the dmraid devices associated with the DiskSet.""" + + if DiskSet.dmList: + dmraid.stopAllRaid(DiskSet.dmList) + DiskSet.dmList = None + + def startMdRaid(self): + """Start all of the md raid devices associated with the DiskSet.""" + + testList = [] + testList.extend(DiskSet.skippedDisks) + + for mp in DiskSet.mpList or []: + for m in mp.members: + disk = m.split('/')[-1] + testList.append(disk) + + for rs in DiskSet.dmList or []: + for m in rs.members: + if isinstance(m, block.RaidDev): + disk = m.rd.device.path.split('/')[-1] + testList.append(disk) + + driveList = filter(lambda x: x not in testList, self.driveList()) + DiskSet.mdList.extend(raid.startAllRaid(driveList)) + + def stopMdRaid(self): + """Stop all of the md raid devices associated with the DiskSet.""" + + raid.stopAllRaid(DiskSet.mdList) + + while DiskSet.mdList: + DiskSet.mdList.pop() + + def getInfo(self, readFn=lambda d: isys.readFSLabel(d)): + """Return a dict keyed on device name, storing some sort of data + about each device. This is typially going to be labels or UUIDs, + as required by readFstab. + """ + ret = {} + + encryptedDevices = self.pomona.id.partitions.encryptedDevices + + for drive in self.driveList(): + # Don't read labels from drives we cleared using clearpart, as + # we don't actually remove the existing filesystems so those + # labels will still be present (#209291). + if drive in DiskSet.skippedDisks: + continue + + # ignoredisk takes precedence over clearpart (#186438). + if DiskSet.exclusiveDisks != [] and \ + drive not in DiskSet.exclusiveDisks: + continue + + disk = self.disks[drive] + func = lambda part: (part.is_active() and + not (part.get_flag(parted.PARTITION_RAID) + or part.get_flag(parted.PARTITION_LVM))) + parts = filter_partitions(disk, func) + for part in parts: + node = get_partition_name(part) + crypto = encryptedDevices.get(node) + if crypto and not crypto.openDevice(): + node = crypto.getDevice() + + val = readFn(node) + if val: + ret[node] = val + + if crypto: + crypto.closeDevice() + + # not doing this right now, because we should _always_ have a + # partition table of some kind on dmraid. + #if False: + # for rs in DiskSet.dmList or [] + DiskSet.mpList or []: + # label = isys.readFSLabel(rs.name) + # if label: + # labels[rs.name] = label + + for dev, devices, level, numActive in DiskSet.mdList: + crypto = encryptedDevices.get(dev) + if crypto and not crypto.openDevice(): + dev = crypto.getDevice() + + val = readFn(dev) + if val: + ret[dev] = val + + if crypto: + crypto.closeDevice() + + active = lvm.vgcheckactive() + if not active: + lvm.vgscan() + lvm.vgactivate() + + for (vg, lv, size, lvorigin) in lvm.lvlist(): + if lvorigin: + continue + node = "%s/%s" % (vg, lv) + crypto = encryptedDevices.get(node) + if crypto and not crypto.openDevice(): + node = crypto.getDevice() + + val = readFn("/dev/" + node) + if val: + ret[node] = val + + if crypto: + crypto.closeDevice() + + if not active: + lvm.vgdeactivate() + + return ret + + def findExistingRootPartitions(self, upgradeany = 0): + """Return a list of all of the partitions which look like a root fs.""" + rootparts = [] + + self.startMPath() + self.startDmRaid() + self.startMdRaid() + + for dev, crypto in self.pomona.id.partitions.encryptedDevices.items(): + # FIXME: order these so LVM and RAID always work on the first try + if crypto.openDevice(): + log.error("failed to open encrypted device %s" % (dev,)) + + if flags.cmdline.has_key("upgradeany"): + upgradeany = 1 + + for dev, devices, level, numActive in self.mdList: + (errno, msg) = (None, None) + found = 0 + theDev = dev + crypto = self.pomona.id.partitions.encryptedDevices.get(dev) + if crypto and not crypto.openDevice(): + theDev = "/dev/%s" % (crypto.getDevice(),) + elif crypto: + log.error("failed to open encrypted device %s" % dev) + + fs = isys.readFSType(theDev) + if fs is not None: + try: + isys.mount(theDev, self.pomona.rootPath, fs, readOnly = 1) + found = 1 + except SystemError: + pass + + isys.umount(self.pomona.rootPath) + + # now, look for candidate lvm roots + lvm.vgscan() + lvm.vgactivate() + + for dev, crypto in self.pomona.id.partitions.encryptedDevices.items(): + # FIXME: order these so LVM and RAID always work on the first try + if crypto.openDevice(): + log.error("failed to open encrypted device %s" % (dev,)) + + for (vg, lv, size, lvorigin) in lvm.lvlist(): + if lvorigin: + continue + dev = "/dev/%s/%s" %(vg, lv) + found = 0 + theDev = dev + node = "%s/%s" % (vg, lv) + dmnode = "mapper/%s-%s" % (vg, lv) + crypto = self.pomona.id.partitions.encryptedDevices.get(dmnode) + if crypto and not crypto.openDevice(): + theDev = "/dev/%s" % (crypto.getDevice(),) + elif crypto: + log.error("failed to open encrypted device %s" % dev) + + fs = isys.readFSType(theDev) + if fs is not None: + try: + isys.mount(theDev, self.pomona.rootPath, fs, readOnly = 1) + found = 1 + except SystemError: + pass + + lvm.vgdeactivate() + + # don't stop raid until after we've looked for lvm on top of it + self.stopMdRaid() + + drives = self.disks.keys() + drives.sort() + + protected = self.pomona.id.partitions.protectedPartitions() + + for drive in drives: + disk = self.disks[drive] + part = disk.next_partition () + while part: + node = get_partition_name(part) + crypto = self.pomona.id.partitions.encryptedDevices.get(node) + if (part.is_active() + and (part.get_flag(parted.PARTITION_RAID) + or part.get_flag(parted.PARTITION_LVM))): + part = disk.next_partition(part) + continue + elif part.fs_type or crypto: + theDev = node + if part.fs_type: + fstype = part.fs_type.name + else: + fstype = None + + # parted doesn't tell ext4 from ext3 + if fstype == "ext3": + fstype = isys.readFSType(theDev) + + if crypto and not crypto.openDevice(): + theDev = crypto.getDevice() + fstype = isys.readFSType("/dev/%s" % theDev) + elif crypto: + log.error("failed to open encrypted device %s" % node) + + if not fstype or fstype not in fsset.getUsableLinuxFs(): + part = disk.next_partition(part) + continue + + try: + isys.mount("/dev/%s" % (theDev,), + self.pomona.rootPath, fstype) + checkRoot = self.pomona.rootPath + except SystemError: + part = disk.next_partition(part) + continue + + part = disk.next_partition(part) + return rootparts + + def driveList (self): + """Return the list of drives on the system.""" + drives = isys.hardDriveDict().keys() + drives.sort (isys.compareDrives) + return drives + + def drivesByName (self): + """Return a dictionary of the drives on the system.""" + return isys.hardDriveDict() + + def savePartitions (self): + """Write the partition tables out to the disks.""" + for disk in self.disks.values(): + if disk.dev.path[5:].startswith("sd") and disk.get_last_partition_num() > 15: + log.debug("not saving partition table of disk with > 15 partitions") + del disk + continue + + log.info("disk.commit() for %s" % (disk.dev.path,)) + try: + disk.commit() + except: + # if this fails, remove the disk so we don't use it later + # Basically if we get here, badness has happened and we want + # to prevent tracebacks from ruining the day any more. + del disk + continue + + del disk + self.refreshDevices() + + def _addDisk(self, drive, disk): + log.debug("adding drive %s to disk list" % (drive,)) + self.initializedDisks[drive] = True + self.disks[drive] = disk + + def _removeDisk(self, drive, addSkip=True): + msg = "removing drive %s from disk lists" % (drive,) + if addSkip: + msg += "; adding to skip list" + log.debug(msg) + + if self.disks.has_key(drive): + del self.disks[drive] + if addSkip: + if self.initializedDisks.has_key(drive): + del self.initializedDisks[drive] + DiskSet.skippedDisks.append(drive) + + def refreshDevices (self): + """Reread the state of the disks as they are on disk.""" + self.closeDevices() + self.disks = {} + self.openDevices() + + def closeDevices (self): + """Close all of the disks which are open.""" + self.stopDmRaid() + self.stopMPath() + for disk in self.disks.keys(): + #self.disks[disk].close() + del self.disks[disk] + self.devicesOpen = False + + def isDisciplineFBA (self, drive): + drive = drive.replace('/dev/', '') + + if drive.startswith("dasd"): + discipline = "/sys/block/%s/device/discipline" % (drive,) + if os.path.isfile(discipline): + try: + fp = open(discipline, "r") + lines = fp.readlines() + fp.close() + + if len(lines) == 1: + if lines[0].strip() == "FBA": + return True + except: + log.error("failed to check discipline of %s" % (drive,)) + pass + + return False + + def _askForLabelPermission(self, intf, drive, clearDevs, initAll, ks): + rc = 0 + if (ks and (drive in clearDevs) and initAll) or \ + self.isDisciplineFBA(drive): + rc = 1 + elif intf: + deviceFile = "/dev/" + drive + dev = parted.PedDevice.get(deviceFile) + + msg = _("The partition table on device %s (%s %-0.f MB) was unreadable.\n\n" + "To create new partitions it must be initialized, " + "causing the loss of ALL DATA on this drive.\n\n" + "This operation will override any previous " + "installation choices about which drives to " + "ignore.\n\n" + "Would you like to initialize this drive, " + "erasing ALL DATA?") % (drive, dev.model, getDeviceSizeMB (dev),) + + rc = intf.messageWindow(_("Warning"), msg, type="yesno") + + if rc != 0: + return True + + self._removeDisk(drive) + return False + + def _labelDevice(self, drive): + log.info("Reinitializing label for drive %s" % (drive,)) + + deviceFile = "/dev/" + drive + + try: + try: + disk = labelDisk(deviceFile) + except parted.error, msg: + log.error("parted error: %s" % (msg,)) + raise + except: + (type, value, tb) = sys.exc_info() + lines = exception.formatException(type, value, tb) + for line in lines: + log.error(line) + self._removeDisk(drive) + raise LabelError, drive + + self._addDisk(drive, disk) + return disk, deviceFile + + def openDevices (self): + """Open the disks on the system and skip unopenable devices.""" + + if self.disks: + return + self.startMPath() + self.startDmRaid() + + intf = self.pomona.intf + zeroMbr = self.pomona.id.partitions.zeroMbr + + for drive in self.driveList(): + # ignoredisk takes precedence over clearpart (#186438). + if drive in DiskSet.skippedDisks: + continue + + if DiskSet.exclusiveDisks != [] and \ + drive not in DiskSet.exclusiveDisks: + continue + + if not isys.mediaPresent(drive): + DiskSet.skippedDisks.append(drive) + continue + + disk = None + dev = None + + if self.initializedDisks.has_key(drive): + if not self.disks.has_key(drive): + try: + dev = parted.PedDevice.get("/dev/%s" % (drive,)) + disk = parted.PedDisk.new(dev) + self._addDisk(drive, disk) + except parted.error, msg: + self._removeDisk(drive) + continue + + ks = False + clearDevs = [] + initAll = False + + if initAll and ((clearDevs is None) or (len(clearDevs) == 0) \ + or (drive in clearDevs)) and \ + not hasProtectedPartitions(drive, self.pomona): + try: + disk, dev = self._labelDevice(drive) + except: + continue + + try: + if not dev: + dev = parted.PedDevice.get("/dev/%s" % (drive,)) + disk = None + except parted.error, msg: + log.debug("parted error: %s" % (msg,)) + self._removeDisk(drive, disk) + continue + + try: + if not disk: + disk = parted.PedDisk.new(dev) + self._addDisk(drive, disk) + except parted.error, msg: + recreate = 0 + if zeroMbr: + log.error("zeroMBR was set and invalid partition table " + "found on %s" % (dev.path[5:])) + recreate = 1 + else: + if not self._askForLabelPermission(intf, drive, clearDevs, + initAll, ks): + continue + + recreate = 1 + + if recreate == 1: + try: + disk, dev = self._labelDevice(drive) + except: + continue + + filter_partitions(disk, validateFsType) + + # check for more than 15 partitions (libata limit) + if drive.startswith('sd') and disk.get_last_partition_num() > 15: + str = _("The drive /dev/%s has more than 15 partitions on it. " + "The SCSI subsystem in the Linux kernel does not " + "allow for more than 15 partitons at this time. You " + "will not be able to make changes to the partitioning " + "of this disk or use any partitions beyond /dev/%s15 " + "in %s") % (drive, drive, name) + + rc = intf.messageWindow(_("Warning"), str, + type="custom", + custom_buttons = [_("_Reboot"), + _("_Continue")], + custom_icon="warning") + if rc == 0: + sys.exit(0) + + # check that their partition table is valid for their architecture + ret = checkDiskLabel(disk, intf) + if ret == 1: + self._removeDisk(drive) + elif ret == -1: + try: + disk, dev = self._labelDevice(drive) + except: + pass + self.devicesOpen = True + + def partitionTypes (self): + """Return list of (partition, partition type) tuples for all parts.""" + rc = [] + drives = self.disks.keys() + drives.sort() + + for drive in drives: + disk = self.disks[drive] + part = disk.next_partition () + while part: + if part.type in (parted.PARTITION_PRIMARY, + parted.PARTITION_LOGICAL): + device = get_partition_name(part) + if part.fs_type: + ptype = part.fs_type.name + else: + ptype = None + rc.append((device, ptype)) + part = disk.next_partition (part) + + return rc + + def diskState (self): + """Print out current disk state. DEBUG.""" + rc = "" + for disk in self.disks.values(): + rc = rc + ("%s: %s length %ld, maximum " + "primary partitions: %d\n" % + (disk.dev.path, + disk.dev.model, + disk.dev.length, + disk.max_primary_partition_count)) + + part = disk.next_partition() + if part: + rc = rc + ("Device Type Filesystem Start " + "End Length Flags\n") + rc = rc + ("------ ---- ---------- ----- " + "--- ------ -----\n") + while part: + if not part.type & parted.PARTITION_METADATA: + device = "" + fs_type_name = "" + if part.num > 0: + device = get_partition_name(part) + if part.fs_type: + fs_type_name = part.fs_type.name + partFlags = get_flags (part) + rc = rc + ("%-9s %-12s %-12s %-10ld %-10ld %-10ld %7s\n" + % (device, part.type_name, fs_type_name, + part.geom.start, part.geom.end, part.geom.length, + partFlags)) + part = disk.next_partition(part) + return rc + + def checkNoDisks(self): + """Check that there are valid disk devices.""" + if len(self.disks.keys()) == 0: + self.pomona.intf.messageWindow(_("No Drives Found"), + _("An error has occurred - no valid devices were " + "found on which to create new file systems. " + "Please check your hardware for the cause " + "of this problem.")) + return True + return False + + + def exceptionDisks(self, pomona, probe=True): + if probe: + isys.flushDriveDict() + self.refreshDevices() + + drives = [] + for d in isys.removableDriveDict().items(): + func = lambda p: p.is_active() and not p.get_flag(parted.PARTITION_RAID) and not p.get_flag(parted.PARTITION_LVM) and p.fs_type.name in ["ext3", "ext2", "fat16", "fat32"] + + disk = self.disks[d[0]] + parts = filter_partitions(disk, func) + + if len(parts) == 0: + drives.append(d) + else: + for part in parts: + name = "%s%s" % (part.disk.dev.path, part.num) + drives.append((os.path.basename(name), d[1])) + + return drives + +# XXX is this all of the possibilities? +dosPartitionTypes = [ 1, 6, 7, 11, 12, 14, 15 ] + +# master list of partition types +allPartitionTypesDict = { + 0 : "Empty", + 1: "DOS 12-bit FAT", + 2: "XENIX root", + 3: "XENIX usr", + 4: "DOS 16-bit <32M", + 5: "Extended", + 6: "DOS 16-bit >=32M", + 7: "NTFS/HPFS", + 8: "AIX", + 9: "AIX bootable", + 10: "OS/2 Boot Manager", + 0xb: "Win95 FAT32", + 0xc: "Win95 FAT32", + 0xe: "Win95 FAT16", + 0xf: "Win95 Ext'd", + 0x10: "OPUS", + 0x11: "Hidden FAT12", + 0x12: "Compaq Setup", + 0x14: "Hidden FAT16 <32M", + 0x16: "Hidden FAT16", + 0x17: "Hidden HPFS/NTFS", + 0x18: "AST SmartSleep", + 0x1b: "Hidden Win95 FAT32", + 0x1c: "Hidden Win95 FAT32 (LBA)", + 0x1e: "Hidden Win95 FAT16 (LBA)", + 0x24: "NEC_DOS", + 0x39: "Plan 9", + 0x40: "Venix 80286", + 0x41: "PPC_PReP Boot", + 0x42: "SFS", + 0x4d: "QNX4.x", + 0x4e: "QNX4.x 2nd part", + 0x4f: "QNX4.x 2nd part", + 0x51: "Novell?", + 0x52: "Microport", + 0x63: "GNU HURD", + 0x64: "Novell Netware 286", + 0x65: "Novell Netware 386", + 0x75: "PC/IX", + 0x80: "Old MINIX", + 0x81: "Linux/MINIX", + 0x82: "Linux swap", + 0x83: "Linux native", + 0x84: "OS/2 hidden C:", + 0x85: "Linux Extended", + 0x86: "NTFS volume set", + 0x87: "NTFS volume set", + 0x8e: "Linux LVM", + 0x93: "Amoeba", + 0x94: "Amoeba BBT", + 0x9f: "BSD/OS", + 0xa0: "IBM Thinkpad hibernation", + 0xa5: "BSD/386", + 0xa6: "OpenBSD", + 0xb7: "BSDI fs", + 0xb8: "BSDI swap", + 0xbf: "Solaris", + 0xc7: "Syrinx", + 0xdb: "CP/M", + 0xde: "Dell Utility", + 0xe1: "DOS access", + 0xe3: "DOS R/O", + 0xeb: "BEOS", + 0xee: "EFI GPT", + 0xef: "EFI (FAT-12/16/32)", + 0xf2: "DOS secondary", + 0xfd: "Linux RAID", + 0xff: "BBT" + } + +max_logical_partition_count = { + "hd": 59, + "sd": 11, + "ataraid/": 11, + "rd/": 3, + "cciss/": 11, + "i2o/": 11, + "iseries/vd": 3, + "ida/": 11, + "sx8/": 11, + "xvd": 11, + "vd": 11, + "mmcblk": 5 +} diff --git a/pkgs/core/pomona/src/partitioning.py b/pkgs/core/pomona/src/partitioning.py new file mode 100644 index 0000000..dc4fa50 --- /dev/null +++ b/pkgs/core/pomona/src/partitioning.py @@ -0,0 +1,79 @@ +# +# partitioning.py: partitioning and other disk management +# +# Matt Wilson <msw@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# Mike Fulbright <msf@redhat.com> +# Harald Hoyer <harald@redhat.de> +# +# Copyright 2001-2003 Red Hat, Inc. +# +# This software may be freely redistributed under the terms of the GNU +# library public license. +# +# You should have received a copy of the GNU Library Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import isys +import sys +import iutil +from constants import * +from flags import flags +from partErrors import * + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +def partitionObjectsInitialize(pomona): + # read in drive info + pomona.id.diskset.refreshDevices() + pomona.id.partitions.setFromDisk(pomona.id.diskset) + +def partitioningComplete(pomona): + if pomona.dir == DISPATCH_BACK and pomona.id.fsset.isActive(): + rc = pomona.intf.messageWindow(_("Installation cannot continue."), + _("The partitioning options you have chosen " + "have already been activated. You can " + "no longer return to the disk editing " + "screen. Would you like to continue " + "with the installation process?"), + type = "yesno") + if rc == 0: + sys.exit(0) + return DISPATCH_FORWARD + + pomona.id.partitions.sortRequests() + pomona.id.fsset.reset() + for request in pomona.id.partitions.requests: + # XXX improve sanity checking + if (not request.fstype or (request.fstype.isMountable() + and not request.mountpoint)): + continue + + entry = request.toEntry(pomona.id.partitions) + if entry: + pomona.id.fsset.add(entry) + else: + raise RuntimeError, ("Managed to not get an entry back from " + "request.toEntry") + + if iutil.memAvailable() > isys.EARLY_SWAP_RAM: + return + + rc = pomona.intf.messageWindow(_("Low Memory"), + _("As you don't have much memory in this " + "machine, we need to turn on swap space " + "immediately. To do this we'll have to " + "write your new partition table to the disk " + "immediately. Is that OK?"), "yesno") + + if rc: + pomona.id.diskset.clearDevices() + pomona.id.fsset.setActive(pomona.id.diskset) + pomona.id.diskset.savePartitions() + pomona.id.fsset.formatSwap(pomona.rootPath) + pomona.id.fsset.turnOnSwap(pomona.rootPath) + + return diff --git a/pkgs/core/pomona/src/partitions.py b/pkgs/core/pomona/src/partitions.py new file mode 100644 index 0000000..6eae948 --- /dev/null +++ b/pkgs/core/pomona/src/partitions.py @@ -0,0 +1,1672 @@ +# +# partitions.py: partition object containing partitioning info +# +# Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Matt Wilson <msw@redhat.com> +# Jeremy Katz <katzj@redhat.com> +# Mike Fulbright <msf@redhat.com> +# Harald Hoyer <harald@redhat.de> +# + +"""Overarching partition object.""" + +import parted +import iutil +import isys +import string +import os +import sys + +from constants import * +from flags import flags +from errors import * + +import fsset +import raid +import lvm +import partedUtils +import partRequests +import cryptodev + +import gettext +_ = lambda x: gettext.ldgettext("pomona", x) + +import logging +log = logging.getLogger("pomona") + +# dispatch.py helper function +def partitionObjectsInitialize(pomona): + # shut down all dm devices + pomona.id.diskset.closeDevices() + pomona.id.diskset.stopMdRaid() + + # clean slate about drives + isys.flushDriveDict() + + if pomona.dir == DISPATCH_BACK: + return + + # pull in the new iscsi drive + isys.flushDriveDict() + + # read in drive info + pomona.id.diskset.refreshDevices() + + pomona.id.partitions.setFromDisk(pomona.id.diskset) + pomona.id.partitions.setProtected(pomona.dispatch) + +# dispatch.py helper function +def partitioningComplete(pomona): + if pomona.dir == DISPATCH_BACK and pomona.id.fsset.isActive(): + rc = pomona.intf.messageWindow(_("Installation cannot continue."), + _("The partitioning options you have chosen " + "have already been activated. You can " + "no longer return to the disk editing " + "screen. Would you like to continue " + "with the installation process?"), + type = "yesno") + if rc == 0: + sys.exit(0) + return DISPATCH_FORWARD + + pomona.id.partitions.sortRequests() + pomona.id.fsset.reset() + undoEncryption = False + partitions = pomona.id.partitions + preexist = partitions.hasPreexistingCryptoDev() + for request in pomona.id.partitions.requests: + # XXX improve sanity checking + if (not request.fstype or (request.fstype.isMountable() + and not request.mountpoint)): + continue + + if request.encryption and request.encryption.format: + if pomona.isKickstart and request.passphrase: + # they set a passphrase for this device explicitly + pass + elif partitions.encryptionPassphrase: + request.encryption.setPassphrase(partitions.encryptionPassphrase) + elif undoEncryption: + request.encryption = None + if request.dev: + request.dev.crypto = None + else: + while True: + (passphrase, retrofit) = pomona.intf.getLuksPassphrase(preexist=preexist) + if passphrase: + request.encryption.setPassphrase(passphrase) + partitions.encryptionPassphrase = passphrase + partitions.retrofitPassphrase = retrofit + break + else: + rc = pomona.intf.messageWindow(_("Encrypt device?"), + _("You specified block device encryption " + "should be enabled, but you have not " + "supplied a passphrase. If you do not " + "go back and provide a passphrase, " + "block device encryption will be " + "disabled."), + type="custom", + custom_buttons=[_("Back"), _("Continue")], + default=0) + if rc == 1: + log.info("user elected to not encrypt any devices.") + request.encryption = None + if request.dev: + request.dev.encryption = None + undoEncryption = True + partitions.autoEncrypt = False + break + + entry = request.toEntry(pomona.id.partitions) + if entry: + pomona.id.fsset.add (entry) + else: + raise RuntimeError, ("Managed to not get an entry back from " + "request.toEntry") + + if pomona.isKickstart: + return + + rc = pomona.intf.messageWindow(_("Writing partitioning to disk"), + _("The partitioning options you have selected " + "will now be written to disk. Any " + "data on deleted or reformatted partitions " + "will be lost."), + type = "custom", custom_icon="warning", + custom_buttons=[_("Go _back"), + _("_Write changes to disk")], + default = 0) + if rc == 0: + return DISPATCH_BACK + +def lookup_cryptodev(device): + for encryptedDev, cdev in Partitions.encryptedDevices.items(): + mappedDev = cdev.getDevice() + if device == encryptedDev or device == mappedDev: + return cdev + +class Partitions: + """Defines all of the partition requests and delete requests.""" + encryptedDevices = {} + + def __init__ (self, pomona, readDisks=False): + """Initializes a Partitions object. + + Can pass in the diskset if it already exists. + """ + self.pomona = pomona + + self.requests = [] + """A list of RequestSpec objects for all partitions.""" + + self.deletes = [] + """A list of DeleteSpec objects for partitions to be deleted.""" + + self.autoPartitionRequests = [] + """A list of RequestSpec objects for autopartitioning. + These are setup by the installclass and folded into self.requests + by auto partitioning.""" + + self.autoClearPartType = CLEARPART_TYPE_NONE + """What type of partitions should be cleared?""" + + self.autoClearPartDrives = None + """Drives to clear partitions on (note that None is equiv to all).""" + + self.nextUniqueID = 1 + """Internal counter. Don't touch unless you're smarter than me.""" + + self.reinitializeDisks = 0 + """Should the disk label be reset on all disks?""" + + self.zeroMbr = 0 + """Should the mbr be zero'd?""" + + self.protected = [] + """A list of partitions that are the installation source for hard + drive or livecd installs. Partitions on this list may not be + formatted.""" + + self.autoEncrypt = False + + self.encryptionPassphrase = "" + self.retrofitPassphrase = False + + # partition method to be used. not to be touched externally + self.useAutopartitioning = 1 + self.useFdisk = 0 + + if readDisks: + self.pomona.id.diskset.refreshDevices() + self.setFromDisk(self.pomona.id.diskset) + + def protectedPartitions(self): + return self.protected + + def hasPreexistingCryptoDev(self): + rc = False + for request in self.requests: + if request.encryption and request.encryption.format == 0: + rc = True + break + + return rc + + def getCryptoDev(self, device): + log.info("going to get passphrase for encrypted device %s" % device) + luksDev = self.encryptedDevices.get(device) + if luksDev: + log.debug("passphrase for device %s already known" % device) + return luksDev + + intf = self.pomona.intf + luksDev = cryptodev.LUKSDevice(device) + if self.encryptionPassphrase: + luksDev.setPassphrase(self.encryptionPassphrase) + if not luksDev.openDevice(): + self.encryptedDevices[device] = luksDev + return luksDev + else: + luksDev.setPassphrase("") + + if intf is None: + return + + buttons = [_("Back"), _("Continue")] + devname = os.path.basename(device) + while True: + (passphrase, isglobal) = intf.passphraseEntryWindow(devname) + if not passphrase: + rc = intf.messageWindow(_("Confirm"), + _("Are you sure you want to skip " + "entering a passphrase for device " + "%s?\n\n" + "If you skip this step the " + "device's contents will not " + "be available during " + "installation.") % devname, + type = "custom", + default = 0, + custom_buttons = buttons) + if rc == 0: + continue + else: + log.info("skipping passphrase for %s" % (device,)) + break + + luksDev.setPassphrase(passphrase) + rc = luksDev.openDevice() + if rc: + luksDev.setPassphrase("") + continue + else: + self.encryptedDevices[device] = luksDev + if isglobal: + self.encryptionPassphrase = passphrase + break + + return self.encryptedDevices.get(device) + + def getEncryptedDevices(self, diskset): + """ find and obtain passphrase for any encrypted devices """ + drives = diskset.disks.keys() + drives.sort() + for drive in drives: + if diskset.pomona.isKickstart and \ + ((self.autoClearPartType != CLEARPART_TYPE_NONE and \ + (not self.autoClearPartDrives or \ + drive in self.autoClearPartDrives)) or \ + drive in diskset.skippedDisks): + continue + + disk = diskset.disks[drive] + part = disk.next_partition() + while part: + if part.type & parted.PARTITION_METADATA: + part = disk.next_partition(part) + continue + + device = partedUtils.get_partition_name(part) + fs = partedUtils.sniffFilesystemType("/dev/%s" % (device,)) + if fs and fs.endswith("raid"): + part = disk.next_partition(part) + continue + + if cryptodev.isLuks("/dev/%s" % device): + self.getCryptoDev(device) + + part = disk.next_partition(part) + + diskset.startMPath() + diskset.startDmRaid() + diskset.startMdRaid() + mdList = diskset.mdList + for raidDev in mdList: + (theDev, devices, level, numActive) = raidDev + if cryptodev.isLuks("/dev/%s" % theDev): + self.getCryptoDev(theDev) + + lvm.writeForceConf() + # now to read in pre-existing LVM stuff + lvm.vgscan() + lvm.vgactivate() + + for (vg, size, pesize, vgfree) in lvm.vglist(): + for (lvvg, lv, size, lvorigin) in lvm.lvlist(): + if lvorigin: + continue + if lvvg != vg: + continue + + theDev = "/dev/mapper/%s-%s" %(vg, lv) + if cryptodev.isLuks(theDev): + self.getCryptoDev("mapper/%s-%s" % (vg, lv)) + + lvm.vgdeactivate() + diskset.stopMdRaid() + for luksDev in self.encryptedDevices.values(): + luksDev.closeDevice() + # try again now that encryption mappings are closed + lvm.vgdeactivate() + diskset.stopMdRaid() + for luksDev in self.encryptedDevices.values(): + luksDev.closeDevice() + + # We shouldn't have any further need for the global passphrase + # except for new device creation, in which case we want to give + # the user a chance to establish a new global passphrase. + self.encryptionPassphrase = "" + + def setFromDisk(self, diskset): + """Clear the delete list and set self.requests to reflect disk.""" + self.deletes = [] + self.requests = [] + labels = diskset.getInfo() + drives = diskset.disks.keys() + drives.sort() + for drive in drives: + disk = diskset.disks[drive] + part = disk.next_partition() + while part: + if part.type & parted.PARTITION_METADATA: + part = disk.next_partition(part) + continue + + format = None + if part.type & parted.PARTITION_FREESPACE: + ptype = None + elif part.type & parted.PARTITION_EXTENDED: + ptype = None + elif part.get_flag(parted.PARTITION_RAID) == 1: + ptype = fsset.fileSystemTypeGet("software RAID") + elif part.get_flag(parted.PARTITION_LVM) == 1: + ptype = fsset.fileSystemTypeGet("physical volume (LVM)") + else: + ptype = partedUtils.get_partition_file_system_type(part) + + # FIXME: we don't handle ptype being None very well, so + # just say it's foreign. Should probably fix None + # handling instead some day. + if ptype is None: + ptype = fsset.fileSystemTypeGet("foreign") + + device = partedUtils.get_partition_name(part) + luksDev = self.encryptedDevices.get(device) + if luksDev and not luksDev.openDevice(): + mappedDev = luksDev.getDevice() + fsname = partedUtils.sniffFilesystemType("/dev/%s" % mappedDev) + try: + ptype = fsset.fileSystemTypeGet(fsname) + except: + ptype = fsset.fileSystemTypeGet("foreign") + + start = part.geom.start + end = part.geom.end + size = partedUtils.getPartSizeMB(part) + drive = partedUtils.get_partition_drive(part) + + spec = partRequests.PreexistingPartitionSpec(ptype, + size = size, + start = start, + end = end, + drive = drive, + format = format) + spec.device = fsset.PartedPartitionDevice(part).getDevice() + spec.encryption = luksDev + spec.maxResizeSize = partedUtils.getMaxAvailPartSizeMB(part) + + # set label if makes sense + if ptype and ptype.isMountable(): + if spec.device in labels.keys(): + if labels[spec.device] and len(labels[spec.device])>0: + spec.fslabel = labels[spec.device] + elif luksDev and not luksDev.getStatus() and mappedDev in labels.keys(): + if labels[mappedDev] and len(labels[mappedDev])>0: + spec.fslabel = labels[mappedDev] + self.addRequest(spec) + part = disk.next_partition(part) + + # now we need to read in all pre-existing RAID stuff + diskset.startMPath() + diskset.startDmRaid() + diskset.startMdRaid() + mdList = diskset.mdList + for raidDev in mdList: + (theDev, devices, level, numActive) = raidDev + level = "RAID%s" %(level,) + + if level not in raid.availRaidLevels: + log.warning("raid level %s not supported, skipping %s" %(level, + theDev)) + continue + + try: + chunk = isys.getRaidChunkFromDevice("/dev/%s" %(devices[0],)) + except Exception, e: + log.error("couldn't get chunksize of %s: %s" %(theDev, e)) + chunk = None + + # is minor always mdN ? + minor = int(theDev[2:]) + raidvols = [] + for dev in devices: + req = self.getRequestByDeviceName(dev) + if not req: + log.error("RAID device %s using non-existent partition %s" + %(theDev, dev)) + continue + raidvols.append(req.uniqueID) + + + luksDev = self.encryptedDevices.get(theDev) + if luksDev and not luksDev.openDevice(): + device = luksDev.getDevice() + else: + device = theDev + + fs = partedUtils.sniffFilesystemType("/dev/%s" %(device,)) + try: + fsystem = fsset.fileSystemTypeGet(fs) + except: + fsystem = fsset.fileSystemTypeGet("foreign") + + try: + fslabel = isys.readFSLabel(device) + except: + fslabel = None + + mnt = None + format = 0 + + spares = len(devices) - numActive + spec = partRequests.RaidRequestSpec(fsystem, format = format, + raidlevel = level, + raidmembers = raidvols, + raidminor = minor, + raidspares = spares, + mountpoint = mnt, + preexist = 1, + chunksize = chunk, + fslabel = fslabel) + spec.size = spec.getActualSize(self, diskset) + spec.encryption = luksDev + self.addRequest(spec) + + lvm.writeForceConf() + # now to read in pre-existing LVM stuff + lvm.vgscan() + lvm.vgactivate() + + pvs = lvm.pvlist() + for (vg, size, pesize, vgfree) in lvm.vglist(): + try: + preexist_size = float(size) + except: + log.error("preexisting size for %s not a valid integer, ignoring" %(vg,)) + preexist_size = None + + pvids = [] + for (dev, pvvg, size) in pvs: + if vg != pvvg: + continue + req = self.getRequestByDeviceName(dev[5:]) + if not req: + log.error("Volume group %s using non-existent partition %s" + %(vg, dev)) + continue + pvids.append(req.uniqueID) + spec = partRequests.VolumeGroupRequestSpec(format = 0, + vgname = vg, + physvols = pvids, + pesize = pesize, + preexist = 1, + preexist_size = preexist_size) + spec.free = vgfree + vgid = self.addRequest(spec) + + for (lvvg, lv, size, lvorigin) in lvm.lvlist(): + if lvorigin: + continue + if lvvg != vg: + continue + + # size is number of bytes, we want size in megs + lvsize = float(size) + + theDev = "/dev/%s/%s" %(vg, lv) + + luksDev = self.encryptedDevices.get("mapper/%s-%s" % (vg, lv)) + if luksDev and not luksDev.openDevice(): + device = luksDev.getDevice() + else: + device = theDev + + fs = partedUtils.sniffFilesystemType(device) + fslabel = None + + try: + fsystem = fsset.fileSystemTypeGet(fs) + except: + fsystem = fsset.fileSystemTypeGet("foreign") + + try: + fslabel = isys.readFSLabel(device) + except: + fslabel = None + + mnt = None + format = 0 + + spec = partRequests.LogicalVolumeRequestSpec(fsystem, + format = format, size = lvsize, volgroup = vgid, + lvname = lv, mountpoint = mnt, fslabel = fslabel, + preexist = 1) + if fsystem.isResizable(): + spec.minResizeSize = fsystem.getMinimumSize("%s/%s" %(vg, lv)) + spec.encryption = luksDev + self.addRequest(spec) + + for vg in lvm.partialvgs(): + spec = partRequests.PartialVolumeGroupSpec(vgname = vg) + self.addDelete(spec) + + lvm.vgdeactivate() + diskset.stopMdRaid() + for luksDev in self.encryptedDevices.values(): + luksDev.closeDevice() + + # try again now that encryption mappings are closed + lvm.vgdeactivate() + diskset.stopMdRaid() + for luksDev in self.encryptedDevices.values(): + luksDev.closeDevice() + + def addRequest (self, request): + """Add a new request to the list.""" + if not request.uniqueID: + request.uniqueID = self.nextUniqueID + self.nextUniqueID = self.nextUniqueID + 1 + self.requests.append(request) + self.requests.sort() + + return request.uniqueID + + def addDelete (self, delete): + """Add a new DeleteSpec to the list.""" + self.deletes.append(delete) + self.deletes.sort() + + def removeRequest (self, request): + """Remove a request from the list.""" + self.requests.remove(request) + + def getRequestByMountPoint(self, mount): + """Find and return the request with the given mountpoint.""" + for request in self.requests: + if request.mountpoint == mount: + return request + + for request in self.requests: + if request.type == REQUEST_LV and request.mountpoint == mount: + return request + return None + + def getRequestByDeviceName(self, device): + """Find and return the request with the given device name.""" + if device is None: + return None + + for request in self.requests: + if request.type == REQUEST_RAID and request.raidminor is not None: + tmp = "md%d" % (request.raidminor,) + if tmp == device: + return request + elif request.device == device: + return request + elif request.encryption: + deviceUUID = cryptodev.luksUUID("/dev/" + device) + cryptoDev = request.encryption.getDevice() + cryptoUUID = request.encryption.getUUID() + if cryptoDev == device or \ + (cryptoUUID and cryptoUUID == deviceUUID): + return request + return None + + + def getRequestsByDevice(self, diskset, device): + """Find and return the requests on a given device (like 'hda').""" + if device is None: + return None + + drives = diskset.disks.keys() + if device not in drives: + return None + + rc = [] + disk = diskset.disks[device] + part = disk.next_partition() + while part: + dev = partedUtils.get_partition_name(part) + request = self.getRequestByDeviceName(dev) + + if request: + rc.append(request) + part = disk.next_partition(part) + + if len(rc) > 0: + return rc + else: + return None + + def getRequestByVolumeGroupName(self, volname): + """Find and return the request with the given volume group name.""" + if volname is None: + return None + + for request in self.requests: + if (request.type == REQUEST_VG and + request.volumeGroupName == volname): + return request + return None + + def getRequestByLogicalVolumeName(self, lvname): + """Find and return the request with the given logical volume name.""" + if lvname is None: + return None + for request in self.requests: + if (request.type == REQUEST_LV and + request.logicalVolumeName == lvname): + return request + return None + + def getRequestByID(self, id): + """Find and return the request with the given unique ID. + + Note that if id is a string, it will be converted to an int for you. + """ + if type(id) == type("a string"): + id = int(id) + for request in self.requests: + if request.uniqueID == id: + return request + return None + + def getRaidRequests(self): + """Find and return a list of all of the RAID requests.""" + retval = [] + for request in self.requests: + if request.type == REQUEST_RAID: + retval.append(request) + + return retval + + def getRaidDevices(self): + """Find and return a list of all of the requests for use in RAID.""" + raidRequests = [] + for request in self.requests: + if isinstance(request, partRequests.RaidRequestSpec): + raidRequests.append(request) + + return raidRequests + + def getAvailableRaidMinors(self): + """Find and return a list of all of the unused minors for use in RAID.""" + raidMinors = range(0,32) + for request in self.requests: + if isinstance(request, partRequests.RaidRequestSpec) and request.raidminor in raidMinors: + raidMinors.remove(request.raidminor) + + return raidMinors + + + def getAvailRaidPartitions(self, request, diskset): + """Return a list of tuples of RAID partitions which can be used. + + Return value is (part, size, used) where used is 0 if not, + 1 if so, 2 if used for *this* request. + """ + rc = [] + drives = diskset.disks.keys() + raiddevs = self.getRaidDevices() + drives.sort() + for drive in drives: + disk = diskset.disks[drive] + for part in partedUtils.get_raid_partitions(disk): + partname = partedUtils.get_partition_name(part) + used = 0 + for raid in raiddevs: + if raid.raidmembers: + for raidmem in raid.raidmembers: + tmpreq = self.getRequestByID(raidmem) + if (partname == tmpreq.device): + if raid.uniqueID == request.uniqueID: + used = 2 + else: + used = 1 + break + if used: + break + size = partedUtils.getPartSizeMB(part) + + if not used: + rc.append((partname, size, 0)) + elif used == 2: + rc.append((partname, size, 1)) + + return rc + + def getRaidMemberParent(self, request): + """Return RAID device request containing this request.""" + raiddev = self.getRaidRequests() + if not raiddev or not request.device: + return None + for dev in raiddev: + if not dev.raidmembers: + continue + for member in dev.raidmembers: + if request.device == self.getRequestByID(member).device: + return dev + return None + + def isRaidMember(self, request): + """Return whether or not the request is being used in a RAID device.""" + if self.getRaidMemberParent(request) is not None: + return 1 + else: + return 0 + + def getLVMLVForVGID(self, vgid): + """Find and return a list of all the LVs associated with a VG id.""" + retval = [] + for request in self.requests: + if request.type == REQUEST_LV: + if request.volumeGroup == vgid: + retval.append(request) + return retval + + def getLVMLVForVG(self, vgrequest): + """Find and return a list of all of the LVs in the VG.""" + vgid = vgrequest.uniqueID + return self.getLVMLVForVGID(vgid) + + def getLVMRequests(self): + """Return a dictionary of all of the LVM bits. + + The dictionary returned is of the form vgname: [ lvrequests ] + """ + retval = {} + for request in self.requests: + if request.type == REQUEST_VG: + retval[request.volumeGroupName] = self.getLVMLVForVG(request) + + return retval + + def getPartialLVMRequests(self): + """Return a list of all of the partial volume groups names.""" + retval = [] + for request in self.deletes: + if isinstance(request, partRequests.PartialVolumeGroupSpec): + retval.append(request.volumeGroupName) + + return retval + + def getLVMVGRequests(self): + """Find and return a list of all of the volume groups.""" + retval = [] + for request in self.requests: + if request.type == REQUEST_VG: + retval.append(request) + + return retval + + def getLVMLVRequests(self): + """Find and return a list of all of the logical volumes.""" + retval = [] + for request in self.requests: + if request.type == REQUEST_LV: + retval.append(request) + + return retval + + def getAvailLVMPartitions(self, request, diskset): + """Return a list of tuples of PV partitions which can be used. + + Return value is (part, size, used) where used is 0 if not, + 1 if so, 2 if used for *this* request. + """ + rc = [] + drives = diskset.disks.keys() + drives.sort() + volgroups = self.getLVMVGRequests() + pvlist = lvm.pvlist() + for drive in drives: + disk = diskset.disks[drive] + for part in partedUtils.get_lvm_partitions(disk): + partname = partedUtils.get_partition_name(part) + partrequest = self.getRequestByDeviceName(partname) + used = 0 + for volgroup in volgroups: + if volgroup.physicalVolumes: + if partrequest.uniqueID in volgroup.physicalVolumes: + if (request and request.uniqueID and + volgroup.uniqueID == request.uniqueID): + used = 2 + else: + used = 1 + + if used: + break + size = None + for pvpart, pvvg, pvsize in pvlist: + if pvpart == "/dev/%s" % (partname,): + size = pvsize + if size is None: + # if we get here, there's no PV data in the partition, + # so clamp the partition's size to 64M + size = partedUtils.getPartSizeMB(part) + size = lvm.clampPVSize(size, 65536) + + if used == 0: + rc.append((partrequest.uniqueID, size, 0)) + elif used == 2: + rc.append((partrequest.uniqueID, size, 1)) + + # now find available RAID devices + raiddev = self.getRaidRequests() + if raiddev: + raidcounter = 0 + for dev in raiddev: + used = 0 + + if dev.fstype is None: + continue + if dev.fstype.getName() != "physical volume (LVM)": + continue + + for volgroup in volgroups: + if volgroup.physicalVolumes: + if dev.uniqueID in volgroup.physicalVolumes: + if (request and request.uniqueID and + volgroup.uniqueID == request.uniqueID): + used = 2 + else: + used = 1 + + if used: + break + + size = dev.getActualSize(self, diskset) + + if used == 0: + rc.append((dev.uniqueID, size, 0)) + elif used == 2: + rc.append((dev.uniqueID, size, 1)) + + raidcounter = raidcounter + 1 + return rc + + def getLVMVolumeGroupMemberParent(self, request): + """Return parent volume group of a physical volume""" + volgroups = self.getLVMVGRequests() + if not volgroups: + return None + + for volgroup in volgroups: + if volgroup.physicalVolumes: + if request.uniqueID in volgroup.physicalVolumes: + return volgroup + + return None + + def isLVMVolumeGroupMember(self, request): + """Return whether or not the request is being used in an LVM device.""" + if self.getLVMVolumeGroupMemberParent(request) is None: + return 0 + else: + return 1 + + def isVolumeGroupNameInUse(self, vgname): + """Return whether or not the requested volume group name is in use.""" + if not vgname: + return None + + lvmrequests = self.getLVMRequests() + if lvmrequests: + if vgname in lvmrequests.keys(): + return 1 + + lvmrequests = self.getPartialLVMRequests() + if lvmrequests: + if vgname in lvmrequests: + return 1 + + return 0 + + def getBootableRequest(self): + """Return the name of the current 'boot' mount point.""" + bootreq = self.getRequestByMountPoint("/boot") + if not bootreq: + bootreq = self.getRequestByMountPoint("/") + + if bootreq: + return [ bootreq ] + return None + + def getBootableMountpoints(self): + """Return a list of bootable valid mountpoints for this arch.""" + # FIXME: should be somewhere else, preferably some sort of arch object + return [ "/boot", "/" ] + + def isBootable(self, request): + """Returns if the request should be considered a 'bootable' request. + + This basically means that it should be sorted to the beginning of + the drive to avoid cylinder problems in most cases. + """ + bootreqs = self.getBootableRequest() + if not bootreqs: + return 0 + + for bootreq in bootreqs: + if bootreq == request: + return 1 + + if bootreq.type == REQUEST_RAID and \ + request.uniqueID in bootreq.raidmembers: + return 1 + + return 0 + + def sortRequests(self): + """Resort the requests into allocation order.""" + n = 0 + while n < len(self.requests): + # Ignore LVM Volume Group and Logical Volume requests, + # since these are not related to allocating disk partitions + if (self.requests[n].type == REQUEST_VG or self.requests[n].type == REQUEST_LV): + n = n + 1 + continue + + for request in self.requests: + # Ignore LVM Volume Group and Logical Volume requests, + # since these are not related to allocating disk partitions + if (request.type == REQUEST_VG or request.type == REQUEST_LV): + continue + # for raid requests, the only thing that matters for sorting + # is the raid device since ordering by size is mostly + # irrelevant. this also keeps things more consistent + elif (request.type == REQUEST_RAID or + self.requests[n].type == REQUEST_RAID): + if (request.type == self.requests[n].type and + (self.requests[n].raidminor != None) and + ((request.raidminor is None) or + request.raidminor > self.requests[n].raidminor)): + tmp = self.requests[n] + index = self.requests.index(request) + self.requests[n] = request + self.requests[index] = tmp + # for sized requests, we want the larger ones first + elif (request.size and self.requests[n].size and + (request.size < self.requests[n].size)): + tmp = self.requests[n] + index = self.requests.index(request) + self.requests[n] = request + self.requests[index] = tmp + # for cylinder-based, sort by order on the drive + elif (request.start and self.requests[n].start and + (request.drive == self.requests[n].drive) and + (request.type == self.requests[n].type) and + (request.start > self.requests[n].start)): + tmp = self.requests[n] + index = self.requests.index(request) + self.requests[n] = request + self.requests[index] = tmp + # finally just use when they defined the partition so + # there's no randomness thrown in + elif (request.size and self.requests[n].size and + (request.size == self.requests[n].size) and + (request.uniqueID < self.requests[n].uniqueID)): + tmp = self.requests[n] + index = self.requests.index(request) + self.requests[n] = request + self.requests[index] = tmp + n = n + 1 + + tmp = self.getBootableRequest() + + boot = [] + if tmp: + for req in tmp: + # if raid, we want all of the contents of the bootable raid + if req.type == REQUEST_RAID: + for member in req.raidmembers: + boot.append(self.getRequestByID(member)) + else: + boot.append(req) + + # remove the bootables from the request + for bootable in boot: + self.requests.pop(self.requests.index(bootable)) + + # move to the front of the list + boot.extend(self.requests) + self.requests = boot + + def sanityCheckAllRequests(self, diskset, baseChecks = 0): + """Do a sanity check of all of the requests. + + This function is called at the end of partitioning so that we + can make sure you don't have anything silly (like no /, a really + small /, etc). Returns (errors, warnings) where each is a list + of strings or None if there are none. + If baseChecks is set, the basic sanity tests which the UI runs prior to + accepting a partition will be run on the requests as well. + """ + checkSizes = [('/usr', 250), ('/tmp', 50), ('/var', 384), + ('/home', 100), ('/boot', 75)] + warnings = [] + errors = [] + + slash = self.getRequestByMountPoint('/') + if not slash: + errors.append(_("You have not defined a root partition (/), " + "which is required for installation of %s " + "to continue.") % (name,)) + + if slash and slash.getActualSize(self, diskset) < 250: + warnings.append(_("Your root partition is less than 250 " + "megabytes which is usually too small to " + "install %s.") % (name,)) + + def getBaseReqs(reqs): + n = 0 + while not reduce(lambda x,y: x and (y.type not in [REQUEST_RAID, REQUEST_LV]), + reqs, True) \ + and len(reqs) > n: + req = reqs[n] + if req.type == REQUEST_RAID: + for id in req.raidmembers: + reqs.append(self.getRequestByID(id)) + del reqs[n] + continue + elif req.type == REQUEST_LV: + del reqs[n] + continue + n += 1 + return reqs + + for (mount, size) in checkSizes: + req = self.getRequestByMountPoint(mount) + if not req: + continue + if req.getActualSize(self, diskset) < size: + warnings.append(_("Your %s partition is less than %s " + "megabytes which is lower than recommended " + "for a normal %s install.") + %(mount, size, name)) + + foundSwap = 0 + swapSize = 0 + usesUSB = False + usesFireWire = False + + for request in self.requests: + if request.fstype and request.fstype.getName() == "swap": + foundSwap = foundSwap + 1 + swapSize = swapSize + request.getActualSize(self, diskset) + if baseChecks: + rc = request.doSizeSanityCheck() + if rc: + warnings.append(rc) + rc = request.doMountPointLinuxFSChecks() + if rc: + errors.append(rc) + if isinstance(request, partRequests.RaidRequestSpec): + rc = request.sanityCheckRaid(self) + if rc: + errors.append(rc) + if not hasattr(request,'drive'): + continue + for x in request.drive or []: + if isys.driveUsesModule(x, ["usb-storage", "ub"]): + usesUSB = True + elif isys.driveUsesModule(x, ["sbp2", "firewire-sbp2"]): + usesFireWire = True + + if usesUSB: + warnings.append(_("Installing on a USB device. This may " + "or may not produce a working system.")) + if usesFireWire: + warnings.append(_("Installing on a FireWire device. This may " + "or may not produce a working system.")) + + bootreqs = self.getBootableRequest() + if bootreqs: + for bootreq in bootreqs: + if not bootreq: + continue + if (isinstance(bootreq, partRequests.RaidRequestSpec) and + not raid.isRaid1(bootreq.raidlevel)): + errors.append(_("Bootable partitions can only be on RAID1 " + "devices.")) + + # can't have bootable partition on LV + if (isinstance(bootreq, partRequests.LogicalVolumeRequestSpec)): + errors.append(_("Bootable partitions cannot be on a " + "logical volume.")) + + # most arches can't have boot on RAID + if (isinstance(bootreq, partRequests.RaidRequestSpec) and + iutil.getArch() not in raid.raidBootArches): + errors.append(_("Bootable partitions cannot be on a RAID " + "device.")) + + # Lots of filesystems types don't support /boot. + if (bootreq.fstype and not bootreq.fstype.isBootable()): + errors.append(_("Bootable partitions cannot be on an %s " + "filesystem.")%(bootreq.fstype.getName(),)) + + # vfat /boot is insane. + if (bootreq.mountpoint and bootreq.mountpoint == "/" and + bootreq.fstype and bootreq.fstype.getName() == "vfat"): + errors.append(_("Bootable partitions cannot be on an %s " + "filesystem.")%(bootreq.fstype.getName(),)) + + if (bootreq.isEncrypted(self)): + errors.append(_("Bootable partitions cannot be on an " + "encrypted block device")) + + if foundSwap == 0: + warnings.append(_("You have not specified a swap partition. " + "Although not strictly required in all cases, " + "it will significantly improve performance for " + "most installations.")) + + # XXX number of swaps not exported from kernel and could change + if foundSwap >= 32: + warnings.append(_("You have specified more than 32 swap devices. " + "The kernel for %s only supports 32 " + "swap devices.") % (name,)) + + mem = iutil.memInstalled() + rem = mem % 16384 + if rem: + mem = mem + (16384 - rem) + mem = mem / 1024 + + if foundSwap and (swapSize < (mem - 8)) and (mem < 1024): + warnings.append(_("You have allocated less swap space (%dM) than " + "available RAM (%dM) on your system. This " + "could negatively impact performance.") + %(swapSize, mem)) + + if warnings == []: + warnings = None + if errors == []: + errors = None + + return (errors, warnings) + + def setProtected(self, dispatch): + """Set any partitions which should be protected to be so.""" + for device in self.protectedPartitions(): + log.info("%s is a protected partition" % (device)) + request = self.getRequestByDeviceName(device) + if request is not None: + request.setProtected(1) + else: + log.info("no request, probably a removable drive") + + def copy (self): + """Deep copy the object.""" + new = Partitions(self.pomona) + for request in self.requests: + new.addRequest(request) + for delete in self.deletes: + new.addDelete(delete) + new.autoPartitionRequests = self.autoPartitionRequests + new.autoClearPartType = self.autoClearPartType + new.autoClearPartDrives = self.autoClearPartDrives + new.nextUniqueID = self.nextUniqueID + new.useAutopartitioning = self.useAutopartitioning + new.useFdisk = self.useFdisk + new.reinitializeDisks = self.reinitializeDisks + new.protected = self.protected + return new + + def getClearPart(self): + """Get the kickstart directive related to the clearpart being used.""" + clearpartargs = [] + if self.autoClearPartType == CLEARPART_TYPE_ALL: + clearpartargs.append('--all') + else: + return None + + if self.reinitializeDisks: + clearpartargs.append('--initlabel') + + if self.autoClearPartDrives: + drives = string.join(self.autoClearPartDrives, ',') + clearpartargs.append('--drives=%s' % (drives)) + + return "#clearpart %s\n" %(string.join(clearpartargs)) + + def writeKS(self, f): + """Write out the partitioning information in kickstart format.""" + f.write("# The following is the partition information you requested\n") + f.write("# Note that any partitions you deleted are not expressed\n") + f.write("# here so unless you clear all partitions first, this is\n") + f.write("# not guaranteed to work\n") + clearpart = self.getClearPart() + if clearpart: + f.write(clearpart) + + # lots of passes here -- parts, raid, volgroup, logvol + # XXX what do we do with deleted partitions? + for request in self.requests: + args = [] + if request.type == REQUEST_RAID: + continue + + # no fstype, no deal (same with foreigns) + if not request.fstype or request.fstype.getName() == "foreign": + continue + + # first argument is mountpoint, which can also be swap or + # the unique RAID identifier. I hate kickstart partitioning + # syntax. a lot. too many special cases + if request.fstype.getName() == "swap": + args.append("swap") + elif request.fstype.getName() == "software RAID": + # since we guarantee that uniqueIDs are ints now... + args.append("raid.%s" % (request.uniqueID)) + elif request.fstype.getName() == "physical volume (LVM)": + # see above about uniqueIDs being ints + args.append("pv.%s" % (request.uniqueID)) + elif request.fstype.getName() == "PPC PReP Boot": + args.extend(["prepboot", "--fstype", ""PPC PReP Boot""]) + elif request.fstype.getName() == "Apple Bootstrap": + args.extend(["appleboot", "--fstype", ""Apple Bootstrap""]) + elif request.mountpoint: + args.extend([request.mountpoint, "--fstype", + request.fstype.getName(quoted = 1)]) + else: + continue + + # generic options + if not request.format: + args.append("--noformat") + + # device encryption + if request.encryption: + args.append("--encrypted") + + # preexisting only + if request.type == REQUEST_PREEXIST and request.device: + args.append("--onpart") + args.append(request.device) + # we have a billion ways to specify new partitions + elif request.type == REQUEST_NEW: + if request.size: + args.append("--size=%s" % (int(request.size),)) + if request.size == 0: + args.append("--size=0") + if request.grow: + args.append("--grow") + if request.start: + args.append("--start=%s" % (request.start)) + if request.end: + args.append("--end=%s" % (request.end)) + if request.maxSizeMB: + args.append("--maxsize=%s" % (request.maxSizeMB)) + if request.drive: + args.append("--ondisk=%s" % (request.drive[0])) + if request.primary: + args.append("--asprimary") + else: # how the hell did we get this? + continue + + f.write("#part %s\n" % (string.join(args))) + + + for request in self.requests: + args = [] + if request.type != REQUEST_RAID: + continue + + # no fstype, no deal (same with foreigns) + if not request.fstype or request.fstype.getName() == "foreign": + continue + + # also require a raidlevel and raidmembers for raid + if (request.raidlevel == None) or not request.raidmembers: + continue + + # first argument is mountpoint, which can also be swap + if request.fstype.getName() == "swap": + args.append("swap") + elif request.fstype.getName() == "physical volume (LVM)": + # see above about uniqueIDs being ints + args.append("pv.%s" % (request.uniqueID)) + elif request.mountpoint: + args.append(request.mountpoint) + else: + continue + + # generic options + if not request.format: + args.append("--noformat") + if request.preexist: + args.append("--useexisting") + if request.fstype: + args.extend(["--fstype", request.fstype.getName(quoted = 1)]) + + # device encryption + if request.encryption: + args.append("--encrypted") + + args.append("--level=%s" % (request.raidlevel)) + args.append("--device=md%s" % (request.raidminor)) + + if request.raidspares: + args.append("--spares=%s" % (request.raidspares)) + + # silly raid member syntax + raidmems = [] + for member in request.raidmembers: + if (type(member) != type("")) or (member[0:5] != "raid."): + raidmems.append("raid.%s" % (member)) + else: + raidmems.append(member) + args.append("%s" % (string.join(raidmems))) + + f.write("#raid %s\n" % (string.join(args))) + + for request in self.requests: + args = [] + if request.type != REQUEST_VG: + continue + + args.append(request.volumeGroupName) + + # generic options + if not request.format: + args.append("--noformat") + if request.preexist: + args.append("--useexisting") + + args.append("--pesize=%s" %(request.pesize,)) + + # silly pv syntax + pvs = [] + for member in request.physicalVolumes: + if (type(member) != type("")) or not member.startswith("pv."): + pvs.append("pv.%s" % (member)) + else: + pvs.append(member) + args.append("%s" % (string.join(pvs))) + + f.write("#volgroup %s\n" % (string.join(args))) + + for request in self.requests: + args = [] + if request.type != REQUEST_LV: + continue + + # no fstype, no deal (same with foreigns) + if not request.fstype or request.fstype.getName() == "foreign": + continue + + # require a vg name and an lv name + if (request.logicalVolumeName is None or + request.volumeGroup is None): + continue + + # first argument is mountpoint, which can also be swap + if request.fstype.getName() == "swap": + args.append("swap") + elif request.mountpoint: + args.append(request.mountpoint) + else: + continue + + # generic options + if not request.format: + args.append("--noformat") + if request.preexist: + args.append("--useexisting") + if request.fstype: + args.extend(["--fstype", request.fstype.getName(quoted = 1)]) + + # device encryption + if request.encryption: + args.append("--encrypted") + + vg = self.getRequestByID(request.volumeGroup) + if vg is None: + continue + + args.extend(["--name=%s" %(request.logicalVolumeName,), + "--vgname=%s" %(vg.volumeGroupName,)]) + + if request.grow: + if request.startSize: + args.append("--size=%s" % (int(request.startSize),)) + else: + # shouldnt happen + continue + + args.append("--grow") + if request.maxSizeMB and int(request.maxSizeMB) > 0: + args.append("--maxsize=%s" % (request.maxSizeMB,)) + else: + if request.percent: + args.append("--percent=%s" %(request.percent,)) + elif request.size: + args.append("--size=%s" %(int(request.size),)) + else: + continue + + f.write("#logvol %s\n" % (string.join(args))) + + def deleteAllLogicalPartitions(self, part): + """Add delete specs for all logical partitions in part.""" + for partition in partedUtils.get_logical_partitions(part.disk): + partName = partedUtils.get_partition_name(partition) + request = self.getRequestByDeviceName(partName) + self.removeRequest(request) + if request.preexist: + drive = partedUtils.get_partition_drive(partition) + delete = partRequests.DeleteSpec(drive, partition.geom.start, + partition.geom.end) + self.addDelete(delete) + + def containsImmutablePart(self, part): + """Returns whether the partition contains parts we can't delete.""" + if not part or (type(part) == type("RAID")) or (type(part) == type(1)): + return None + + if not part.type & parted.PARTITION_EXTENDED: + return None + + disk = part.disk + while part: + if not part.is_active(): + part = disk.next_partition(part) + continue + + device = partedUtils.get_partition_name(part) + request = self.getRequestByDeviceName(device) + + if request: + if request.getProtected(): + return _("the partition in use by the installer.") + + if self.isRaidMember(request): + return _("a partition which is a member of a RAID array.") + + if self.isLVMVolumeGroupMember(request): + return _("a partition which is a member of a LVM Volume Group.") + + part = disk.next_partition(part) + return None + + + def doMetaDeletes(self, diskset): + """Does the removal of all of the non-physical volumes in the delete list.""" + + # have to have lvm on, which requires raid to be started + diskset.startMPath() + diskset.startDmRaid() + diskset.startMdRaid() + for luksDev in self.encryptedDevices.values(): + luksDev.openDevice() + lvm.vgactivate() + + snapshots = {} + for (lvvg, lv, size, lvorigin) in lvm.lvlist(): + snapshots.setdefault(lv, []) + if lvorigin: + snapshots.setdefault(lvorigin, []) + snapshots[lvorigin].append((lv, lvvg)) + + lvm_parent_deletes = [] + tmp = {} + def addSnap(name, vg): + snaps = snapshots[name] + for snap, snapvg in snaps: + addSnap(snap, snapvg) + if not tmp.has_key((name, vg)): + tmp[(name, vg)] = 1 + lvm_parent_deletes.append((name,vg)) + + # now, go through and delete logical volumes + for delete in self.deletes: + if isinstance(delete, partRequests.DeleteLogicalVolumeSpec): + if not delete.beenDeleted(): + addSnap(delete.name, delete.vg) + delete.setDeleted(1) + + for name,vg in lvm_parent_deletes: + log.info("removing lv %s" % (name,)) + key = "mapper/%s-%s" % (vg, name) + if key in self.encryptedDevices.keys(): + self.encryptedDevices[key].closeDevice() + del self.encryptedDevices[key] + lvm.lvremove(name, vg) + + # now, go through and delete volume groups + for delete in self.deletes: + if isinstance(delete, partRequests.DeleteVolumeGroupSpec): + if not delete.beenDeleted(): + lvm.vgremove(delete.name) + delete.setDeleted(1) + + lvm.vgdeactivate() + + # now, remove obsolete cryptodev instances + for (device, luksDev) in self.encryptedDevices.items(): + luksDev.closeDevice() + found = 0 + for req in self.requests: + if req.encryption == luksDev: + found = 1 + + if not found: + del self.encryptedDevices[device] + + diskset.stopMdRaid() + + def doMetaResizes(self, diskset): + """Does resizing of non-physical volumes.""" + + # have to have lvm on, which requires raid to be started + devicesActive = diskset.devicesOpen + if not devicesActive: + # should this not be diskset.openDevices() ? + diskset.startMPath() + diskset.startDmRaid() + diskset.startMdRaid() + + for luksDev in self.encryptedDevices.values(): + luksDev.openDevice() + lvm.vgactivate() + + # we only support resizing LVM of these types of things currently + for lv in self.getLVMLVRequests(): + if not lv.preexist: + continue + if lv.targetSize is None: + continue + + vg = self.getRequestByID(lv.volumeGroup) + if vg is None: + continue + + lvm.lvresize(lv.logicalVolumeName, vg.volumeGroupName, + lv.targetSize) + + lvm.vgdeactivate() + for luksDev in self.encryptedDevices.values(): + luksDev.closeDevice() + + if not devicesActive: + # should this not be diskset.closeDevices() ? + diskset.stopMdRaid() + diskset.stopDmRaid() + diskset.stopMPath() + + def doEncryptionRetrofits(self): + if not self.retrofitPassphrase or not self.encryptionPassphrase: + return + + for request in self.requests: + if not request.encryption: + continue + + # XXX this will only work before the new LUKS devices are created + # since the format flag gets unset when they are formatted + if request.encryption.format: + continue + + if request.encryption.addPassphrase(self.encryptionPassphrase): + log.error("failed to add new passphrase to existing device %s" % (request.encryption.getDevice(encrypted=1),)) + + def deleteDependentRequests(self, request): + """Handle deletion of this request and all requests which depend on it. + + eg, delete all logical volumes from a volume group, all volume groups + which depend on the raid device. + + Side effects: removes all dependent requests from self.requests + adds needed dependent deletes to self.deletes + """ + + toRemove = [] + id = request.uniqueID + for req in self.requests: + if isinstance(req, partRequests.RaidRequestSpec): + if id in req.raidmembers: + toRemove.append(req) + # XXX do we need to do anything special with preexisting raids? + elif isinstance(req, partRequests.VolumeGroupRequestSpec): + if id in req.physicalVolumes: + toRemove.append(req) + if req.getPreExisting(): + delete = partRequests.DeleteVolumeGroupSpec(req.volumeGroupName) + self.addDelete(delete) + elif isinstance(req, partRequests.LogicalVolumeRequestSpec): + if id == req.volumeGroup: + toRemove.append(req) + tmp = self.getRequestByID(req.volumeGroup) + if not tmp: + log.error("Unable to find the vg for %s" + % (req.logicalVolumeName,)) + vgname = req.volumeGroup + else: + vgname = tmp.volumeGroupName + + if req.getPreExisting(): + delete = partRequests.DeleteLogicalVolumeSpec(req.logicalVolumeName, + vgname) + self.addDelete(delete) + + for req in toRemove: + self.deleteDependentRequests(req) + self.removeRequest(req) diff --git a/pkgs/core/pomona/src/po/Makefile b/pkgs/core/pomona/src/po/Makefile new file mode 100644 index 0000000..a1ee8b0 --- /dev/null +++ b/pkgs/core/pomona/src/po/Makefile @@ -0,0 +1,58 @@ + +include ../Makefile.inc + +POTFILES = ../*.py +NONPOTFILES = ../lang-table + +POS = $(wildcard *.po) +FMTCATALOGS = $(patsubst %.po,%.mo,$(POS)) + +MSGMERGE = msgmerge -v + +all: $(FMTCATALOGS) report + +$(PSNAME).pot: $(POTFILES) $(NONPOTFILES) + xgettext --from-code=UTF-8 --default-domain=$(PSNAME) \ + --keyword=_ --keyword=N_ $(POTFILES) + cat ../lang-table | cut -f1 | while read line; do echo -e "\n#. generated from lang-table\nmsgid "$$line"\nmsgstr """; done >> $(PSNAME).po + if cmp -s $(PSNAME).po $(PSNAME).pot; then \ + rm -f $(PSNAME).po; \ + else \ + mv $(PSNAME).po $(PSNAME).pot; \ + fi + +refresh-po: + for cat in $(POS); do \ + lang=`basename $$cat .po`; \ + if $(MSGMERGE) $$lang.po $(PSNAME).pot > $$lang.pot ; then \ + mv -f $$lang.pot $$lang.po ; \ + echo "$(MSGMERGE) of $$lang succeeded" ; \ + else \ + echo "$(MSGMERGE) of $$lang failed" ; \ + rm -f $$lang.pot ; \ + fi \ + done + +update-po: $(PSNAME).pot refresh-po + +install: all + mkdir -p $(INSTALLNLSDIR) + for n in $(FMTCATALOGS); do \ + l=`basename $$n .mo`; \ + $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l; \ + $(INSTALL) -m 755 -d $(INSTALLNLSDIR)/$$l/LC_MESSAGES; \ + $(INSTALL) -m 644 $$n \ + $(INSTALLNLSDIR)/$$l/LC_MESSAGES/$(PSNAME).mo; \ + done + +%.mo: %.po + msgfmt --check -o $@ $< + +report: + @for cat in $(POS); do \ + echo -n "$$cat: "; \ + msgfmt -v --statistics -o /dev/null $$cat; \ + done + +clean: + rm -f *.mo missing diff --git a/pkgs/core/pomona/src/po/da.po b/pkgs/core/pomona/src/po/da.po new file mode 100644 index 0000000..49920d7 --- /dev/null +++ b/pkgs/core/pomona/src/po/da.po @@ -0,0 +1,2422 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-01-29 01:02+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: Henrik Bro Larsen <hbrolarsen@aktinet.de>\n" +"Language-Team: <da@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../autopart.py:751 +#, python-format +msgid "" +"Could not allocate cylinder-based partitions as primary partitions.\n" +"\n" +"%s" +msgstr "" +"Kunne ikke allokere cylinder-baserede partitioner som primÊre partitioner.\n" +"\n" +"%s" + +#: ../autopart.py:756 +#, python-format +msgid "" +"Could not allocate partitions as primary partitions.\n" +"\n" +"%s" +msgstr "" +"Kunne ikke allokere partitioner som primÊre partitioner.\n" +"\n" +"%s" + +#: ../autopart.py:761 +#, python-format +msgid "" +"Could not allocate cylinder-based partitions.\n" +"\n" +"%s" +msgstr "" +"Kunne ikke allokere cylinder-baserede partitioner.\n" +"\n" +"%s" + +#: ../autopart.py:800 +#, python-format +msgid "" +"Boot partition %s doesn't belong to a BSD disk label. SRM won't be able to " +"boot from this partition. Use a partition belonging to a BSD disk label or " +"change this device disk label to BSD." +msgstr "" +"Opstartspartitionen %s tilhÞrer ikke en BSD-disk-etikette. SRM vil ikke " +"kunne starte fra denne partition. Brug en partition som tilhÞrer en BSD-disk-" +"etikette eller Êndr denne enhedsdisk-etikette til BSD." + +#: ../autopart.py:802 +#, python-format +msgid "" +"Boot partition %s doesn't belong to a disk with enough free space at its " +"beginning for the bootloader to live on. Make sure that there's at least 5MB " +"of free space at the beginning of the disk that contains /boot" +msgstr "" +"Startpartitionen %s tilhÞrer ikke en disk med tilstrÊkkeligt meget ledigt " +"plads ved dets begyndelse som startprogrammet kan vÊre pÃ¥. Forsikr dig om at " +"der findes 5 MB ledigt plads ved begyndelsen af disken som indeholder /boot" + +#: ../autopart.py:804 +#, python-format +msgid "" +"Boot partition %s isn't a VFAT partition. EFI won't be able to boot from " +"this partition." +msgstr "" +"Startpartitionen %s er ikke en VFAT-partition. EFI vil ikke kunne starte fra " +"denne partition." + +#: ../autopart.py:806 +msgid "" +"The boot partition must entirely be in the first 4GB of the disk. " +"OpenFirmware won't be able to boot this installation." +msgstr "" +"Startpartitionen skal vÊre placeret fuldtud inden for de fÞrste 4 GB pÃ¥ " +"disken. OpenFirmware vil ikke kunne opstarte denne installation." + +#: ../autopart.py:813 +#, python-format +msgid "" +"Boot partition %s may not meet booting constraints for your architecture." +msgstr "" +"Opstartspartition %s opfylder muligvis ikke opstartsbegrÊnsningene for din " +"maskinarkitektur. " + +#: ../autopart.py:951 +msgid "Requested Partition Does Not Exist" +msgstr "Forespurgt partition eksisterer ikke" + +#: ../autopart.py:952 +#, python-format +msgid "" +"Unable to locate partition %s to use for %s.\n" +"\n" +"Press 'OK' to reboot your system." +msgstr "" +"Kan ikke finde partition %s som skal bruges til %s.\n" +"\n" +"Tryk O.k. for at genstarte systemet." + +#: ../autopart.py:997 ../autopart.py:1029 +msgid "Automatic Partitioning Errors" +msgstr "Fejl ved automatisk partitionering" + +#: ../autopart.py:998 +#, python-format +msgid "" +"The following errors occurred with your partitioning:\n" +"\n" +"%s\n" +"\n" +"Press 'OK' to reboot your system." +msgstr "" +"FÞlgende fejl opstod under din partitionering:\n" +"\n" +"%s\n" +"\n" +"Tryk O.k. for at genstarte systemet." + +#: ../autopart.py:1007 +msgid "Warnings During Automatic Partitioning" +msgstr "Advarsler under automatisk partitionering" + +#: ../autopart.py:1008 +#, python-format +msgid "" +"Following warnings occurred during automatic partitioning:\n" +"\n" +"%s" +msgstr "" +"FÞlgende advarsler opstod under automatisk partitionering:\n" +"\n" +"%s" + +#: ../autopart.py:1016 ../tui_partition.py:177 +msgid "Error Partitioning" +msgstr "Fejl under partitionering" + +#: ../autopart.py:1017 +#, python-format +msgid "" +"Could not allocate requested partitions: \n" +"\n" +"%s." +msgstr "" +"Kunne ikke allokere forespurgte partitioner: \n" +"\n" +"%s." + +#: ../autopart.py:1027 +msgid "" +"\n" +"\n" +"Press 'OK' to choose a different partitioning option." +msgstr "" +"\n" +"\n" +"Tryk 'O.k.' for at vÊlge en anden partitioneringsoption." + +#: ../autopart.py:1030 +#, python-format +msgid "" +"The following errors occurred with your partitioning:\n" +"\n" +"%s\n" +"\n" +"This can happen if there is not enough space on your hard drive(s) for the " +"installation. %s" +msgstr "" +"De fÞlgende fejl opstod med din partitionering:\n" +"\n" +"%s\n" +"\n" +"Dette kan ske hvis der ikke findes tilstrÊkkeligt med plads til " +"installationen pÃ¥ dine diske. %s" + +#: ../autopart.py:1105 ../bootloader.py:745 ../partedUtils.py:230 +#: ../partedUtils.py:531 ../partedUtils.py:568 ../tui_bootloader.py:119 +#: ../tui_bootloader.py:439 ../tui_partition.py:182 +msgid "Warning" +msgstr "Advarsel" + +#: ../autopart.py:1126 +msgid "" +"Automatic Partitioning sets partitions based on the selected installation " +"type. You also can customize the partitions once they have been created.\n" +"\n" +"The manual disk partitioning tool, Disk Druid, allows you to create " +"partitions in an interactive environment. You can set the file system types, " +"mount points, partition sizes, and more." +msgstr "" +"Automatisk partitionering opsÊtter partitioner baseret pÃ¥ den valgte " +"installationstype. Du kan ogsÃ¥ tilpasse partitionerne efter at de er blevet " +"oprettet.\n" +"\n" +"VÊrktÞjet for manuel partitionering, Disk Druid, lader dig opsÊtte dine " +"partitioner i et interaktivt miljÞ. Du kan sÊtte filsystemtyper, " +"monteringspunkter, stÞrrelse pÃ¥ partitioner med mere." + +#: ../autopart.py:1137 +msgid "" +"Before automatic partitioning can be set up by the installation program, you " +"must choose how to use the space on your hard drives." +msgstr "" +"FÞr automatisk partitionering kan sÊttes op af installationsprogrammet skal " +"du vÊlge hvordan pladsen pÃ¥ harddiskene skal bruges." + +#: ../autopart.py:1142 +msgid "Remove all partitions on this system" +msgstr "Fjern alle partitioner pÃ¥ dette system" + +#: ../autopart.py:1144 +#, python-format +msgid "" +"You have chosen to remove all partitions (ALL DATA) on the following drives:%" +"s\n" +"Are you sure you want to do this?" +msgstr "" +"Du har valgt at fjerne alle partitioner (ALLE DATA) pÃ¥ de fÞlgende drev:%s\n" +"Er du sikker pÃ¥ at du vil gÞre dette?" + +#: ../bootloader.py:696 +msgid "Bootloader" +msgstr "OpstartsindlÊser" + +#: ../bootloader.py:696 +msgid "Installing bootloader..." +msgstr "Installerer bootloader..." + +#: ../bootloader.py:746 +msgid "" +"No kernel packages were installed on your system. Your boot loader " +"configuration will not be changed." +msgstr "" +"Ingen kernel pakker blev installeret pÃ¥ dit system. Konfigurationen af din " +"boot loader vil ikke blive Êndret." + +#: ../constants.py:41 +#, python-format +msgid "" +"An unhandled exception has occurred. This is most likely a bug. Please " +"save a copy of the detailed exception and file a bug report against pomona " +"at %s" +msgstr "" +"En ubehandlet hÊndelse er sket. Dette er sandsynligvis en fejl. Kopiér den " +"fulde tekst fra denne undtagelse, og udfyld sÃ¥ en fejlrapport om pomona pÃ¥ %s" + +#: ../constants.py:83 ../installer.py:93 ../tui_confirm.py:28 +#: ../tui_network.py:65 ../tui_network.py:74 ../tui.py:224 ../tui.py:390 +msgid "OK" +msgstr "O.k." + +#: ../constants.py:87 ../partIntfHelpers.py:150 ../partIntfHelpers.py:392 +#: ../tui_bootloader.py:194 ../tui.py:103 ../tui.py:104 ../tui.py:393 +msgid "Cancel" +msgstr "Annullér" + +#: ../constants.py:91 ../tui_confirm.py:28 ../tui_confirm.py:30 +msgid "Back" +msgstr "Tilbage" + +#: ../constants.py:95 ../tui_bootloader.py:67 ../tui.py:388 +msgid "Yes" +msgstr "Ja" + +#: ../constants.py:99 ../tui_bootloader.py:67 ../tui.py:389 +msgid "No" +msgstr "Nej" + +#: ../constants.py:103 ../tui_bootloader.py:270 ../tui_partition.py:849 +msgid "Edit" +msgstr "Redigér" + +#: ../fsset.py:422 +msgid "Checking" +msgstr "" + +#: ../fsset.py:423 +#, fuzzy, python-format +msgid "Checking filesystem on %s..." +msgstr "Kontrollerer for dÃ¥rlige blokke pÃ¥ /dev/%s..." + +#: ../fsset.py:434 +msgid "Resizing" +msgstr "" + +#: ../fsset.py:435 +#, fuzzy, python-format +msgid "Resizing filesystem on %s..." +msgstr "Formaterer %s-filsystem..." + +#: ../fsset.py:578 ../fsset.py:1112 ../fsset.py:1143 ../fsset.py:1205 +#: ../fsset.py:1216 ../fsset.py:1270 ../fsset.py:1281 ../fsset.py:1303 +#: ../fsset.py:1352 ../fsset.py:1433 ../partIntfHelpers.py:289 +msgid "Error" +msgstr "Fejl" + +#: ../fsset.py:579 +#, python-format +msgid "" +"An error occurred migrating %s to ext3. It is possible to continue without " +"migrating this file system if desired.\n" +"\n" +"Would you like to continue without migrating %s?" +msgstr "" +"En fejl opstod under migrering af %s til ext3. Det er muligt at fortsÊtte om " +"Þnsket uden at migrere filsystemet.\n" +"\n" +"Ãnsker du at fortsÊtte uden at migrere %s?" + +#: ../fsset.py:1046 +msgid "First sector of boot partition" +msgstr "FÞrste sektor pÃ¥ opstartspartitionen" + +#: ../fsset.py:1047 +msgid "Master Boot Record (MBR)" +msgstr "Master Boot Record (MBR)" + +#: ../fsset.py:1113 +#, python-format +msgid "" +"An error occurred trying to initialize swap on device %s. This problem is " +"serious, and the install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" +"En fejl opstod under forsÞg pÃ¥ at initiere swap pÃ¥ enhed %s. Dette problem " +"er alvorligt, og installationen kan ikke fortsÊtte.\n" +"\n" +"Tryk <Enter> for at starte systemet igen." + +#: ../fsset.py:1142 +msgid "Skip" +msgstr "Overspring" + +#: ../fsset.py:1142 ../tui_complete.py:40 +msgid "Reboot" +msgstr "Genstart" + +#: ../fsset.py:1163 +#, python-format +msgid "" +"The swap device:\n" +"\n" +" /dev/%s\n" +"\n" +"is a version 0 Linux swap partition. If you want to use this device, you " +"must reformat as a version 1 Linux swap partition. If you skip it, the " +"installer will ignore it during the installation." +msgstr "" +"Swapenheden:\n" +"\n" +" /dev/%s\n" +"\n" +"er en Linuxswappartition af typen version 0. Hvis du vil bruge denne enhed " +"skal du omformatere den til en Linuxswappartition af typen version 1. Hvis " +"du springer over det vil installationsprogrammet overspringe det under " +"installationen." + +#: ../fsset.py:1170 +msgid "Reformat" +msgstr "Omformatér" + +#: ../fsset.py:1174 +#, python-format +msgid "" +"The swap device:\n" +"\n" +" /dev/%s\n" +"\n" +"in your /etc/fstab file is currently in use as a software suspend partition, " +"which means your system is hibernating. To perform an upgrade, please shut " +"down your system rather than hibernating it." +msgstr "" +"Swapenheden:\n" +"\n" +" /dev/%s\n" +"\n" +"i din /etc/fstab-fil bruges i Þjeblikket som en partition for " +"programsuspendering, hvilket betyder at dit system er i hviletilstand. For " +"at lave en opgradering bÞr du lukke dit system ned i stedet for at sÊtte det " +"i hviletilstand." + +#: ../fsset.py:1182 +#, python-format +msgid "" +"The swap device:\n" +"\n" +" /dev/%s\n" +"\n" +"in your /etc/fstab file is currently in use as a software suspend partition, " +"which means your system is hibernating. If you are performing a new install, " +"make sure the installer is set to format all swap partitions." +msgstr "" +"Swapenheden:\n" +"\n" +" /dev/%s\n" +"\n" +"i din /etc/fstab-fil bruges i Þjeblikket som en partition for " +"programsuspendering, det vil sige at dit system er i hviletilstand. Hvis du " +"er i gang med en ny installation bÞr du se til at installationsprogrammet er " +"sat op til at formatere alle swappartitioner." + +#: ../fsset.py:1192 +msgid "" +"\n" +"\n" +"Choose Skip if you want the installer to ignore this partition during the " +"upgrade. Choose Format to reformat the partition as swap space. Choose " +"Reboot to restart the system." +msgstr "" +"\n" +"\n" +"VÊlg overspring hvis du Þnsker at installationsprogrammet skal ignorere " +"denne partition under opgraderingen. VÊlg Formatér for at genformatere " +"partitionen som swapplads. VÊlg Genstart for at genstarte systemet." + +#: ../fsset.py:1198 +msgid "Format" +msgstr "Formatér" + +#: ../fsset.py:1206 +#, python-format +msgid "" +"Error enabling swap device %s: %s\n" +"\n" +"The /etc/fstab on your upgrade partition does not reference a valid swap " +"partition.\n" +"\n" +"Press OK to reboot your system." +msgstr "" +"Fejl under aktivering af swap-enhed %s: %s\n" +"\n" +"Filen /etc/fstab pÃ¥ din opgraderingspartition henviser ikke til en gyldig " +"swap-partition.\n" +"\n" +"Tryk O.k. for at genstarte systemet." + +#: ../fsset.py:1217 +#, python-format +msgid "" +"Error enabling swap device %s: %s\n" +"\n" +"This most likely means this swap partition has not been initialized.\n" +"\n" +"Press OK to reboot your system." +msgstr "" +"Fejl under aktivering af swap-enhed %s: %s\n" +"\n" +"Dette betyder sandsynligvis at swap-partitionen ikke er initieret.\n" +"\n" +"Tryk O.k. for at genstarte systemet." + +#: ../fsset.py:1271 +#, python-format +msgid "" +"Bad blocks have been detected on device /dev/%s. We do not recommend you use " +"this device.\n" +"\n" +"Press <Enter> to reboot your system" +msgstr "" +"Der er fundet dÃ¥rlige blokke pÃ¥ enhed /dev/%s. Vi anbefaler ikke at du " +"bruger denne enhed.\n" +"\n" +"Tryk <Enter> for genstarte systemet." + +#: ../fsset.py:1282 +#, python-format +msgid "" +"An error occurred searching for bad blocks on %s. This problem is serious, " +"and the install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" +"En fejl opstod under sÞgning efter dÃ¥rlige blokke pÃ¥ %s. Dette problem er " +"alvorligt, og installationen kan ikke fortsÊtte.\n" +"\n" +"Tryk <Enter> for at genstarte systemet." + +#: ../fsset.py:1304 +#, python-format +msgid "" +"An error occurred trying to format %s. This problem is serious, and the " +"install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" +"Der opstod en fejl ved forsÞg pÃ¥ formatering af %s. Dette problem er sÃ¥ " +"alvorligt, at installationen ikke kan fortsÊtte.\n" +"\n" +"Tryk pÃ¥ return for at genstarte systemet." + +#: ../fsset.py:1353 +#, python-format +msgid "" +"An error occurred trying to migrate %s. This problem is serious, and the " +"install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" +"Der opstod en fejl ved migrering af %s. Dette problem er sÃ¥ alvorligt, at " +"installationen ikke kan fortsÊtte.\n" +"\n" +"Tryk pÃ¥ return for at genstarte systemet." + +#: ../fsset.py:1380 ../fsset.py:1389 +msgid "Invalid mount point" +msgstr "Ugyldigt monteringspunkt" + +#: ../fsset.py:1381 +#, python-format +msgid "" +"An error occurred when trying to create %s. Some element of this path is " +"not a directory. This is a fatal error and the install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" +"Der opstod en fejl ved forsÞg pÃ¥ oprettelse af %s. Elementer af denne sti er " +"ikke et katalog. Dette problem er sÃ¥ alvorligt, at installationen ikke kan " +"fortsÊtte.\n" +"\n" +"Tryk pÃ¥ return for at genstarte systemet." + +#: ../fsset.py:1390 +#, python-format +msgid "" +"An error occurred when trying to create %s: %s. This is a fatal error and " +"the install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" +"Der opstod en fejl ved forsÞg pÃ¥ oprettelse af %s: %s. Dette problem er sÃ¥ " +"alvorligt, at installationen ikke kan fortsÊtte.\n" +"\n" +"Tryk pÃ¥ return for at genstarte systemet." + +#: ../fsset.py:1403 +msgid "Unable to mount filesystem" +msgstr "Kan ikke montere filsystem" + +#: ../fsset.py:1404 +#, python-format +msgid "" +"An error occurred mounting device %s as %s. You may continue installation, " +"but there may be problems." +msgstr "" +"Et fejl skete ved montering af enhed %s som %s. Du kan fortsÊtte " +"installationen men det kan opstÃ¥ problemer." + +#: ../fsset.py:1411 ../fsset.py:1820 ../fsset.py:1827 ../packages.py:131 +#: ../partedUtils.py:578 ../tui_confirm.py:37 +msgid "_Reboot" +msgstr "_Genstart" + +#: ../fsset.py:1411 ../partedUtils.py:578 +msgid "_Continue" +msgstr "_FortsÊt" + +#: ../fsset.py:1419 +#, python-format +msgid "" +"Error mounting device %s as %s: %s\n" +"\n" +"Devices in /etc/fstab should be specified by label, not by device name.\n" +"\n" +"Press OK to reboot your system." +msgstr "" +"Fejl ved montering af enhed %s som %s: %s\n" +"\n" +"Enheder i /etc/fstab bÞr angives ved label, ikke ved enhedsnavn.\n" +"\n" +"Tryk O.k. for at genstarte, dit system." + +#: ../fsset.py:1426 +#, python-format +msgid "" +"Error mounting device %s as %s: %s\n" +"\n" +"This most likely means this partition has not been formatted.\n" +"\n" +"Press OK to reboot your system." +msgstr "" +"Fejl ved montering af enhed %s som %s: %s\n" +"\n" +"Dette betyder hÞjst sandsynligt at denne partition ikke er blevet " +"formateret.\n" +"\n" +"Tryk O.k. for at genstarte dit system." + +#: ../fsset.py:1812 +msgid "Duplicate Labels" +msgstr "Doppelte etiketter" + +#: ../fsset.py:1813 +#, python-format +msgid "" +"Multiple devices on your system are labelled %s. Labels across devices must " +"be unique for your system to function properly.\n" +"\n" +"Please fix this problem and restart the installation process." +msgstr "" +"Flere enheder pÃ¥ dit system er benÊvnt %s. Etiketter skal vÊre unikke for " +"hver enhed pÃ¥ dit system for at fungere rigtigt.\n" +"\n" +"Ret dette problem og genstart installationsprocessen." + +#: ../fsset.py:1822 +msgid "Invalid Label" +msgstr "Ugyldig etikette" + +#: ../fsset.py:1823 +#, python-format +msgid "" +"An invalid label was found on device %s. Please fix this problem and " +"restart the installation process." +msgstr "" +"En ugyldig etikette blev fundet pÃ¥ enhed %s. Ret dette problem og genstart " +"installationsprocessen." + +#: ../fsset.py:2049 +msgid "Formatting" +msgstr "Formaterer" + +#: ../fsset.py:2050 +#, python-format +msgid "Formatting %s file system..." +msgstr "Formaterer %s-filsystem..." + +#: ../installer.py:88 +msgid "Fatal Error" +msgstr "Alvorlig fejl" + +#: ../installer.py:89 +#, python-format +msgid "" +"You do not have enough RAM to install %s on this machine.\n" +"\n" +"Press <return> to reboot your system.\n" +msgstr "" +"Du har ikke RAM nok til at installere %s pÃ¥ denne maskine.\n" +"Tast <return> for at genstarte systemet.\n" + +#: ../installer.py:173 +msgid "Starting text installation..." +msgstr "Starter text-baseret installation..." + +#: ../keyboard_models.py:48 +msgid "keyboard|Arabic (azerty)" +msgstr "tastatur|Arabisk (azerty)" + +#: ../keyboard_models.py:51 +msgid "keyboard|Arabic (azerty/digits)" +msgstr "tastatur|Arabisk (azerty/numerisk tastatur)" + +#: ../keyboard_models.py:54 +msgid "keyboard|Arabic (digits)" +msgstr "tastatur|Arabisk (numerisk tastatur)" + +#: ../keyboard_models.py:57 +msgid "keyboard|Arabic (qwerty)" +msgstr "tastatur|Arabisk (qwerty)" + +#: ../keyboard_models.py:60 +msgid "keyboard|Arabic (qwerty/digits)" +msgstr "tastatur|arabisk (qwerty/numerisk tastatur)" + +#: ../keyboard_models.py:63 +msgid "keyboard|Belgian (be-latin1)" +msgstr "tastatur|Belgisk (be-latin1)" + +#: ../keyboard_models.py:66 +msgid "keyboard|Bengali (Inscript)" +msgstr "tastatur|Bengalsk (Inscript)" + +#: ../keyboard_models.py:69 +msgid "keyboard|Bengali (Probhat)" +msgstr "tastatur|Bengalsk (Probhat)" + +#: ../keyboard_models.py:72 +msgid "keyboard|Bulgarian" +msgstr "tastatur|Bulgarsk" + +#: ../keyboard_models.py:75 +msgid "keyboard|Bulgarian (Phonetic)" +msgstr "tastatur|Bulgarsk (phonetisk)" + +#: ../keyboard_models.py:78 +msgid "keyboard|Brazilian (ABNT2)" +msgstr "tastatur|Brasiliansk (ABNT2)" + +#: ../keyboard_models.py:81 +msgid "keyboard|French Canadian" +msgstr "tastatur|fransk kanadisk" + +#: ../keyboard_models.py:84 +msgid "keyboard|Croatian" +msgstr "tastatur|Kroatisk" + +#: ../keyboard_models.py:87 +msgid "keyboard|Czech" +msgstr "tastatur|Tjekkisk" + +#: ../keyboard_models.py:90 +msgid "keyboard|Czech (qwerty)" +msgstr "tastatur|Tjekkisk (qwerty)" + +#: ../keyboard_models.py:93 +msgid "keyboard|German" +msgstr "tastatur|Tysk" + +#: ../keyboard_models.py:96 +msgid "keyboard|German (latin1)" +msgstr "tastatur|Tysk (latin1)" + +#: ../keyboard_models.py:99 +msgid "keyboard|German (latin1 w/ no deadkeys)" +msgstr "tastatur|Tysk (latin1 uden dÞde taster)" + +#: ../keyboard_models.py:102 +msgid "keyboard|Devanagari (Inscript)" +msgstr "tastatur|Devanagarisk (Inscript)" + +#: ../keyboard_models.py:105 +msgid "keyboard|Dvorak" +msgstr "tastatur|Dvorak" + +#: ../keyboard_models.py:108 +msgid "keyboard|Danish" +msgstr "tastatur|Dansk" + +#: ../keyboard_models.py:111 +msgid "keyboard|Danish (latin1)" +msgstr "tastatur|Dansk (latin1)" + +#: ../keyboard_models.py:114 +msgid "keyboard|Spanish" +msgstr "tastatur|Spansk" + +#: ../keyboard_models.py:117 +msgid "keyboard|Estonian" +msgstr "tastatur|Estisk" + +#: ../keyboard_models.py:120 +msgid "keyboard|Finnish" +msgstr "tastatur|Finsk" + +#: ../keyboard_models.py:123 +msgid "keyboard|Finnish (latin1)" +msgstr "tastatur|Finsk (latin1)" + +#: ../keyboard_models.py:126 +msgid "keyboard|French" +msgstr "tastatur|Fransk" + +#: ../keyboard_models.py:129 +msgid "keyboard|French (latin9)" +msgstr "tastatur|Fransk (latin9)" + +#: ../keyboard_models.py:132 +msgid "keyboard|French (latin1)" +msgstr "tastatur|Fransk (latin1)" + +#: ../keyboard_models.py:135 +msgid "keyboard|French (pc)" +msgstr "tastatur|Fransk (pc)" + +#: ../keyboard_models.py:138 +msgid "keyboard|Swiss French" +msgstr "tastatur|Svejtsisk-fransk" + +#: ../keyboard_models.py:141 +msgid "keyboard|Swiss French (latin1)" +msgstr "tastatur|Svejtsisk-fransk (latin1)" + +#: ../keyboard_models.py:144 +msgid "keyboard|Greek" +msgstr "tastatur|grÊsk" + +#: ../keyboard_models.py:147 +#, fuzzy +msgid "keyboard|Gujarati (Inscript)" +msgstr "tastatur|Punjabi (Inscript)" + +#: ../keyboard_models.py:150 +msgid "keyboard|Punjabi (Inscript)" +msgstr "tastatur|Punjabi (Inscript)" + +#: ../keyboard_models.py:153 +msgid "keyboard|Hungarian" +msgstr "tastatur|Ungarsk" + +#: ../keyboard_models.py:156 +msgid "keyboard|Hungarian (101 key)" +msgstr "tastatur|Ungarsk (101 taster)" + +#: ../keyboard_models.py:159 +msgid "keyboard|Icelandic" +msgstr "tastatur|Islandsk" + +#: ../keyboard_models.py:162 +msgid "keyboard|Italian" +msgstr "tastatur|Italiensk" + +#: ../keyboard_models.py:165 +msgid "keyboard|Italian (IBM)" +msgstr "tastatur|Italiensk (IBM)" + +#: ../keyboard_models.py:168 +msgid "keyboard|Italian (it2)" +msgstr "tastatur|Italiensk (it2)" + +#: ../keyboard_models.py:171 +msgid "keyboard|Japanese" +msgstr "tastatur|Japansk" + +#: ../keyboard_models.py:174 +msgid "keyboard|Korean" +msgstr "tastatur|Koreansk" + +#: ../keyboard_models.py:177 +msgid "keyboard|Latin American" +msgstr "tastatur|latinamerika" + +#: ../keyboard_models.py:180 +msgid "keyboard|Macedonian" +msgstr "tastatur|Makedonsk" + +#: ../keyboard_models.py:183 +msgid "keyboard|Dutch" +msgstr "tastatur|Hollandsk" + +#: ../keyboard_models.py:186 +msgid "keyboard|Norwegian" +msgstr "tastatur|Norsk" + +#: ../keyboard_models.py:189 +msgid "keyboard|Polish" +msgstr "tastatur|Polsk" + +#: ../keyboard_models.py:192 +msgid "keyboard|Portuguese" +msgstr "tastatur|Portugisisk" + +#: ../keyboard_models.py:195 +msgid "keyboard|Romanian" +msgstr "tastatur|RumÊnsk" + +#: ../keyboard_models.py:198 +msgid "keyboard|Russian" +msgstr "tastatur|Russisk" + +#: ../keyboard_models.py:201 +msgid "keyboard|Serbian" +msgstr "tastatur|Serbisk" + +#: ../keyboard_models.py:204 +msgid "keyboard|Serbian (latin)" +msgstr "tastatur|Serbisk (Latinsk)" + +#: ../keyboard_models.py:207 +msgid "keyboard|Swedish" +msgstr "tastatur|Svensk" + +#: ../keyboard_models.py:210 +msgid "keyboard|Swiss German" +msgstr "tastatur|Svejtsisk-tysk" + +#: ../keyboard_models.py:213 +msgid "keyboard|Swiss German (latin1)" +msgstr "tastatur|Svejtsisk-tysk (latin1)" + +#: ../keyboard_models.py:216 +msgid "keyboard|Slovak (qwerty)" +msgstr "tastatur|Slovakisk (qwerty)" + +#: ../keyboard_models.py:219 +msgid "keyboard|Slovenian" +msgstr "tastatur||Slovensk" + +#: ../keyboard_models.py:222 +msgid "keyboard|Tamil (Inscript)" +msgstr "tastatur|Tamilsk (Inscript)" + +#: ../keyboard_models.py:225 +msgid "keyboard|Tamil (Typewriter)" +msgstr "tastatur|tamil (typewriter)" + +#: ../keyboard_models.py:228 +msgid "keyboard|Turkish" +msgstr "tastatur|tyrkisk" + +#: ../keyboard_models.py:231 +msgid "keyboard|United Kingdom" +msgstr "tastatur|United Kingdom" + +#: ../keyboard_models.py:234 +msgid "keyboard|Ukrainian" +msgstr "tastatur|Ukrainsk" + +#: ../keyboard_models.py:237 +msgid "keyboard|U.S. International" +msgstr "tastatur|U.S. international" + +#: ../keyboard_models.py:240 +msgid "keyboard|U.S. English" +msgstr "tastatur|U.S. Engelsk" + +#: ../network.py:31 +msgid "IP address is missing." +msgstr "" + +#: ../network.py:35 +msgid "" +"IPv4 addresses must contain four numbers between 0 and 255, separated by " +"periods." +msgstr "" + +#: ../network.py:38 +#, python-format +msgid "'%s' is not a valid IPv6 address." +msgstr "" + +#: ../network.py:40 +#, python-format +msgid "'%s' is an invalid IP address." +msgstr "" + +#: ../network.py:52 +msgid "Hostname must be 255 or fewer characters in length." +msgstr "" + +#: ../network.py:58 +msgid "" +"Hostname must start with a valid character in the ranges 'a-z', 'A-Z', or '0-" +"9'" +msgstr "" + +#: ../network.py:63 +msgid "" +"Hostnames can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.'" +msgstr "" + +#: ../packages.py:113 +msgid "Warning! This is pre-release software!" +msgstr "Advarsel! Dette er ikke fÊrdigaftestet programmel!" + +#: ../packages.py:114 +#, python-format +msgid "" +"Thank you for downloading this pre-release of %s.\n" +"\n" +"This is not a final release and is not intended for use on production " +"systems. The purpose of this release is to collect feedback from testers, " +"and it is not suitable for day to day usage.\n" +"\n" +"To report feedback, please visit:\n" +"\n" +" %s\n" +"\n" +"and file a report against '%s'.\n" +msgstr "" +"Tak for at du har hentet denne tidlige udgave af %s.\n" +"\n" +"Dette er ikke den endelige udgave og den er ikke ment til brug pÃ¥ systemer i " +"produktion. FormÃ¥let med denne udgave er at indsamle tilbagemeldinger fra " +"testere, og den er ikke velegnet til daglig brug.\n" +"\n" +"For at indsende tilbagemeldinger skal du besÞge:\n" +"\n" +" %s\n" +"\n" +"og udfylde en fejlrapport om '%s'.\n" + +#: ../packages.py:127 +msgid "_Exit" +msgstr "_Afslut" + +#: ../packages.py:127 +msgid "_Install anyway" +msgstr "_Installér alligevel" + +#: ../packages.py:130 +msgid "Your system will now be rebooted..." +msgstr "Dit system vil nu blive genstartet.." + +#: ../packages.py:131 ../tui_confirm.py:37 +msgid "_Back" +msgstr "_Tilbage" + +#: ../packages.py:132 +msgid "Rebooting System" +msgstr "Genstarter system" + +#: ../pakfireinstall.py:47 +#, python-format +msgid "%s MB" +msgstr "%s MB" + +#: ../pakfireinstall.py:50 +#, python-format +msgid "%s KB" +msgstr "%s kB" + +#: ../pakfireinstall.py:53 +#, python-format +msgid "%s Byte" +msgstr "%s byte" + +#: ../pakfireinstall.py:55 +#, python-format +msgid "%s Bytes" +msgstr "%s byte" + +#: ../pakfireinstall.py:134 +msgid "Base system" +msgstr "Basis system" + +#: ../pakfireinstall.py:134 +msgid "Installing base system..." +msgstr "Installerer basis systemet..." + +#: ../pakfireinstall.py:171 +msgid "Install Starting" +msgstr "Installationen starter" + +#: ../pakfireinstall.py:172 +msgid "Starting install process. This may take several minutes..." +msgstr "Starter installationsproces. Dette kan tage op til flere minutter..." + +#: ../pakfireinstall.py:183 +msgid "Post Install" +msgstr "Efter installation" + +#: ../pakfireinstall.py:184 +msgid "Performing post install configuration..." +msgstr "Konfigurerer systemet efter installation..." + +#: ../pakfireinstall.py:215 +msgid "Symmetric multiprocessing" +msgstr "Symmetrisk multiprocessing" + +#: ../pakfireinstall.py:216 +msgid "Xen guest" +msgstr "Xen gÊst" + +#: ../pakfireinstall.py:226 +msgid "Normal Boot" +msgstr "Normal opstart" + +#: ../pakfireinstall.py:233 +msgid "Installation Progress" +msgstr "Installationsfremskridt" + +#: ../partedUtils.py:191 ../tui_partition.py:408 +msgid "Foreign" +msgstr "Fremmed" + +#: ../partedUtils.py:231 +#, python-format +msgid "" +"/dev/%s currently has a %s partition layout. To use this drive for the " +"installation of %s, it must be re-initialized, causing the loss of ALL DATA " +"on this drive.\n" +"\n" +"Would you like to re-initialize this drive?" +msgstr "" +"/dev/%s har i Þjeblikket et %s partitions layout. For at bruge dette " +"diskdrev til installationen af %s, skal den fÞrst re-initialiseres, hvilket " +"medfÞrer tab af ALLE DATA pÃ¥ dette diskdrev.\n" +"\n" +"Ãnsker du at re-initiere dette diskdrev?" + +#: ../partedUtils.py:239 +msgid "_Ignore drive" +msgstr "Ignorér drev" + +#: ../partedUtils.py:240 +msgid "_Re-initialize drive" +msgstr "_Re-initialisér diskdrev" + +#: ../partedUtils.py:532 +#, python-format +msgid "" +"The partition table on device %s was unreadable. To create new partitions it " +"must be initialized, causing the loss of ALL DATA on this drive.\n" +"\n" +"This operation will override any previous installation choices about which " +"drives to ignore.\n" +"\n" +"Would you like to initialize this drive, erasing ALL DATA?" +msgstr "" +"Partitionstabellen pÃ¥ enhed %s er ulÊselig. For at oprette nye partitioner " +"skal den initieres, hvilket vil ÞdelÊgge ALLE DATA pÃ¥ denne enhed.\n" +"\n" +"Denne handling vil tilsidesÊtte alle tidligere valg under installationen om " +"hvilke enheder der skal ignoreres.\n" +"\n" +"Vil du initiere denne enhed og fjerne ALLE DATA?" + +#: ../partedUtils.py:569 +#, python-format +msgid "" +"The drive /dev/%s has more than 15 partitions on it. The SCSI subsystem in " +"the Linux kernel does not allow for more than 15 partitons at this time. " +"You will not be able to make changes to the partitioning of this disk or use " +"any partitions beyond /dev/%s15 in %s" +msgstr "" +"Diskdrevet /dev/%s indeholder mere end 15 partitioner. SCSI-undersystemet i " +"Linux-kernen tillader i Þjeblikket ikke mere end 15 partitoner. Du vil " +"ikke kunne lave Êndringer af partitioneringen af dette diskdrev eller bruge " +"nogen partitioner ud over /dev/%s15 i %s" + +#: ../partedUtils.py:659 +msgid "No Drives Found" +msgstr "Ingen drev fundet" + +#: ../partedUtils.py:660 +msgid "" +"An error has occurred - no valid devices were found on which to create new " +"file systems. Please check your hardware for the cause of this problem." +msgstr "" +"En fejl er opstÃ¥et - ingen gyldige enheder blev fundet pÃ¥ hvilke nye " +"filsystemer kunne oprettes. Tjek venligst din maskine for at finde grunden " +"til dette problem." + +#: ../partIntfHelpers.py:50 +#, python-format +msgid "" +"The mount point %s is invalid. Mount points must start with '/' and cannot " +"end with '/', and must contain printable characters and no spaces." +msgstr "" +"Monteringspunktet %s er ugyldigt. Monteringspunkter skal begynde med '/', " +"kan ikke slutte med '/', og skal indeholde udskrivbare tegn og ingen blanke." + +#: ../partIntfHelpers.py:57 +msgid "Please specify a mount point for this partition." +msgstr "Specificér et monteringspunkt for denne partition." + +#: ../partIntfHelpers.py:74 ../partIntfHelpers.py:80 ../partIntfHelpers.py:90 +#: ../partIntfHelpers.py:111 +msgid "Unable To Delete" +msgstr "Kan ikke fjerne" + +#: ../partIntfHelpers.py:75 +msgid "You must first select a partition to delete." +msgstr "Du skal fÞrst vÊlge en partition som skal fjernes." + +#: ../partIntfHelpers.py:81 +msgid "You cannot delete free space." +msgstr "Du kan ikke fjerne ledig plads." + +#: ../partIntfHelpers.py:91 +#, python-format +msgid "" +"You cannot delete this partition, as it is an extended partition which " +"contains %s" +msgstr "" +"Du kan ikke slette denne partition, da den er en udvidet partition som " +"indeholder %s" + +#: ../partIntfHelpers.py:106 +msgid "This partition is holding the data for the hard drive install." +msgstr "Denne partition indeholder data for harddiskinstallationen." + +#: ../partIntfHelpers.py:112 +msgid "" +"You cannot delete this partition:\n" +"\n" +msgstr "" +"Du kan ikke slette denne partition:\n" +"\n" + +#: ../partIntfHelpers.py:146 ../partIntfHelpers.py:391 +msgid "Confirm Delete" +msgstr "BekrÊft sletning" + +#: ../partIntfHelpers.py:147 +#, python-format +msgid "You are about to delete all partitions on the device '/dev/%s'." +msgstr "Du er i fÊrd med at slette alle partitioner pÃ¥ enheden /dev/%s." + +#: ../partIntfHelpers.py:150 ../partIntfHelpers.py:392 +msgid "_Delete" +msgstr "_Slet" + +#: ../partIntfHelpers.py:206 +msgid "Notice" +msgstr "BemÊrk" + +#: ../partIntfHelpers.py:207 +#, python-format +msgid "" +"The following partitions were not deleted because they are in use:\n" +"\n" +"%s" +msgstr "" +"FÞlgende partitioner blev ikke fjernet da de er i brug:\n" +"\n" +"%s" + +#: ../partIntfHelpers.py:222 ../partIntfHelpers.py:238 +#: ../partIntfHelpers.py:249 +msgid "Unable To Edit" +msgstr "Kan ikke redigere" + +#: ../partIntfHelpers.py:223 +msgid "You must select a partition to edit" +msgstr "Du skal vÊlge en partition for redigering" + +#: ../partIntfHelpers.py:239 +#, python-format +msgid "" +"You cannot edit this partition, as it is an extended partition which " +"contains %s" +msgstr "" +"Du kan ikke redigere denne partition, da den er en udvidet partition som " +"indeholder %s" + +#: ../partIntfHelpers.py:250 +msgid "" +"You cannot edit this partition:\n" +"\n" +msgstr "" +"Du kan ikke redigere denne partition:\n" +"\n" + +#: ../partIntfHelpers.py:272 +msgid "Format as Swap?" +msgstr "Formatér som swap?" + +#: ../partIntfHelpers.py:273 +#, python-format +msgid "" +"/dev/%s has a partition type of 0x82 (Linux swap) but does not appear to be " +"formatted as a Linux swap partition.\n" +"\n" +"Would you like to format this partition as a swap partition?" +msgstr "" +"/dev/%s har partitionstype 0x82 (Linux swap), men ser ikke ud til at vÊre " +"formateret som en swappartition.\n" +"\n" +"Ãnsker du at formatere denne partition som en swappartition?" + +#: ../partIntfHelpers.py:288 +#, python-format +msgid "You need to select at least one hard drive to install %s." +msgstr "Du skal vÊlge mindst et drev, som du skal installere %s pÃ¥." + +#: ../partIntfHelpers.py:293 +msgid "" +"You have chosen to use a pre-existing partition for this installation " +"without formatting it. We recommend that you format this partition to make " +"sure files from a previous operating system installation do not cause " +"problems with this installation of Linux. However, if this partition " +"contains files that you need to keep, such as home directories, then " +"continue without formatting this partition." +msgstr "" +"Du har valgt at bruge en allerede eksisterende partition for denne " +"installation uden at formatere den. Vi anbefaler at du formaterer denne " +"partition for at forsikre dig om at filer fra en tidligere " +"operativsystemsinstallation ikke forÃ¥rsager problemer med denne installation " +"af Linux. Hvis denne partition indeholder filer som du vil beholde, som fx " +"hjemmekataloger, bÞr du dog fortsÊtte uden at formatere denne partition." + +#: ../partIntfHelpers.py:301 +msgid "Format?" +msgstr "Formatér?" + +#: ../partIntfHelpers.py:302 +msgid "_Modify Partition" +msgstr "_Ãndre partition" + +#: ../partIntfHelpers.py:302 +msgid "Do _Not Format" +msgstr "Formater _ikke" + +#: ../partIntfHelpers.py:311 +msgid "Error with Partitioning" +msgstr "Fejl under partitionering" + +#: ../partIntfHelpers.py:312 +#, python-format +msgid "" +"The following critical errors exist with your requested partitioning scheme. " +"These errors must be corrected prior to continuing with your install of %s.\n" +"\n" +"%s" +msgstr "" +"FÞlgende kritiske fejl opstod med dit forespurgte partitionsskema. Disse " +"fejl skal der rettes op pÃ¥ fÞr du fortsÊtter med installationen af %s.\n" +"\n" +"%s" + +#: ../partIntfHelpers.py:326 +msgid "Partitioning Warning" +msgstr "Advarsel fra partitionering" + +#: ../partIntfHelpers.py:327 +#, python-format +msgid "" +"The following warnings exist with your requested partition scheme.\n" +"\n" +"%s\n" +"\n" +"Would you like to continue with your requested partitioning scheme?" +msgstr "" +"FÞlgende advarsler opstod med dit partitioneringsoplÊg.\n" +"\n" +"%s\n" +"\n" +"Vil du fortsÊtte med det forespurgte partitioneringsoplÊg?" + +#: ../partIntfHelpers.py:340 +msgid "" +"The following pre-existing partitions have been selected to be formatted, " +"destroying all data." +msgstr "" +"Disse eksisterende partitioner er mÊrket for formatering, som vil ÞdelÊgge " +"alle data." + +#: ../partIntfHelpers.py:342 +msgid "" +"Select 'Yes' to continue and format these partitions, or 'No' to go back and " +"change these settings." +msgstr "" +"VÊlg 'Ja' for at fortsÊtte med formatering af disse partitioner, eller 'Nej' " +"for at gÃ¥ tilbage og Êndre disse indstillinger." + +#: ../partIntfHelpers.py:348 +msgid "Format Warning" +msgstr "Formateringsadvarsel" + +#: ../partIntfHelpers.py:387 +#, python-format +msgid "You are about to delete the /dev/%s partition." +msgstr "Du er i fÊrd med at slette partitionen /dev/%s." + +#: ../partIntfHelpers.py:389 +msgid "The partition you selected will be deleted." +msgstr "Partitionen du markerede vil blive fjernet." + +#: ../partIntfHelpers.py:398 +msgid "Confirm Reset" +msgstr "BekrÊft nulstilling" + +#: ../partIntfHelpers.py:399 +msgid "" +"Are you sure you want to reset the partition table to its original state?" +msgstr "" +"Er du sikker pÃ¥ at du vil nulstille partitionstabellen til oprindelig " +"tilstand?" + +#: ../partitioning.py:36 +msgid "Installation cannot continue." +msgstr "Installation kan ikke fortsÊtte." + +#: ../partitioning.py:37 +msgid "" +"The partitioning options you have chosen have already been activated. You " +"can no longer return to the disk editing screen. Would you like to continue " +"with the installation process?" +msgstr "" +"Partitionerings optionerne du har valgt er allerede aktiveret. Du vil ikke " +"kunne gÃ¥ tilbage til skÊrmen for redigering af diske. Vil du fortsÊtte " +"installationsprocessen?" + +#: ../partitioning.py:65 +msgid "Low Memory" +msgstr "Lav hukommelse" + +#: ../partitioning.py:66 +msgid "" +"As you don't have much memory in this machine, we need to turn on swap space " +"immediately. To do this we'll have to write your new partition table to the " +"disk immediately. Is that OK?" +msgstr "" +"Da du ikke har ret megen hukommelse pÃ¥ denne maskine, bliver vi nÞdt til at " +"starte swap med det samme. For at gÞre det er vi nÞdt at skrive den nye " +"partitionstabel pÃ¥ disken. Er det i orden?" + +#: ../partitions.py:311 +#, python-format +msgid "" +"You have not defined a root partition (/), which is required for " +"installation of %s to continue." +msgstr "" +"Du har ikke defineret en rod-partition (/). Dette skal gÞres fÞr " +"installationen af %s kan fortsÊtte." + +#: ../partitions.py:316 +#, python-format +msgid "" +"Your root partition is less than 250 megabytes which is usually too small to " +"install %s." +msgstr "" +"Din rod-partition er mindre end 250 megabyte og dette er normalt for lidt " +"til at installere %s." + +#: ../partitions.py:333 +msgid "" +"Your boot partition isn't on one of the first four partitions and thus won't " +"be bootable." +msgstr "" +"Din opstarts-partition er ikke en af de fire fÞrste partitioner og vil " +"derfor ikke vÊre startbar." + +#: ../partitions.py:342 +#, python-format +msgid "" +"Your %s partition is less than %s megabytes which is lower than recommended " +"for a normal %s install." +msgstr "" +"Din %s-partition er mindre end %s megabyte og dette er lavere end anbefalet " +"for en almindelig installation af %s." + +#: ../partitions.py:374 +msgid "" +"Installing on a USB device. This may or may not produce a working system." +msgstr "" +"Installerer pÃ¥ en USB-enhed. Dette kan give et fungerende system, men det er " +"ikke sikkert." + +#: ../partitions.py:378 +msgid "" +"Installing on a FireWire device. This may or may not produce a working " +"system." +msgstr "" +"Installerer pÃ¥ en FireWire-enhed. Dette kan give et fungerende system, men " +"det er ikke sikkert." + +#: ../partitions.py:391 +msgid "" +"You have not specified a swap partition. Although not strictly required in " +"all cases, it will significantly improve performance for most installations." +msgstr "" +"Du har ikke specificeret en swap-partition. Selv om det ikke er et strengt " +"krav om dette i alle tilfÊlle, sÃ¥ vil det Þge ydelsen for de fleste " +"installationer." + +#: ../partitions.py:398 +#, python-format +msgid "" +"You have specified more than 32 swap devices. The kernel for %s only " +"supports 32 swap devices." +msgstr "" + +#: ../partitions.py:409 +#, python-format +msgid "" +"You have allocated less swap space (%dM) than available RAM (%dM) on your " +"system. This could negatively impact performance." +msgstr "" +"Du har allokeret mindre swap-omrÃ¥de (%dM) end tilgÊngelig RAM (%dM) i dit " +"system. Dette kan have negativ indvirkning pÃ¥ ydelsen." + +#: ../partitions.py:485 +msgid "the partition in use by the installer." +msgstr "partitionen er i brug af installationsprogrammet." + +#: ../partRequests.py:182 +#, python-format +msgid "" +"This mount point is invalid. The %s directory must be on the / file system." +msgstr "" +"Dette monteringspunkt er ugyldigt. Kataloget %s skal ligge pÃ¥ rodfilsystemet." + +#: ../partRequests.py:185 +#, python-format +msgid "" +"The mount point %s cannot be used. It must be a symbolic link for proper " +"system operation. Please select a different mount point." +msgstr "" +"Monteringspunktet %s kan ikke bruges. Det skal vÊre et symbolsk link for at " +"systemet kan fungere korrekt. VÊlg et andet monteringspunkt." + +#: ../partRequests.py:192 +msgid "This mount point must be on a linux file system." +msgstr "Dette monteringspunkt skal vÊre pÃ¥ et linux-filsystem." + +#: ../partRequests.py:212 +#, python-format +msgid "" +"The mount point "%s" is already in use, please choose a different mount " +"point." +msgstr "" +"Monteringspunktet "%s" er allerede i brug. VÊlg venligst et andet " +"monteringspunkt." + +#: ../partRequests.py:226 +#, python-format +msgid "" +"The size of the %s partition (%10.2f MB) exceeds the maximum size of %10.2f " +"MB." +msgstr "" +"StÞrrelsen pÃ¥ %s-partitionen (%10.2f Mb) overskrider maksimal stÞrrelse pÃ¥ %" +"10.2f Mb." + +#: ../partRequests.py:414 +#, python-format +msgid "" +"The size of the requested partition (size = %s MB) exceeds the maximum size " +"of %s MB." +msgstr "" +"StÞrrelsen pÃ¥ forespurgt partition (stÞrrelse = %s MB) overskrider maksimal " +"stÞrrelse pÃ¥ %s Mb. " + +#: ../partRequests.py:419 +#, python-format +msgid "The size of the requested partition is negative! (size = %s MB)" +msgstr "StÞrrelsen pÃ¥ forespurgte partition er negativ! (stÞrrelse = %s Mb)" + +#: ../partRequests.py:423 +msgid "Partitions can't start below the first cylinder." +msgstr "Partitioner kan ikke starte fÞr fÞrste cylinder." + +#: ../partRequests.py:426 +msgid "Partitions can't end on a negative cylinder." +msgstr "Partitioner kan ikke slutte pÃ¥ en negativ cylinder." + +#: ../tui_bootloader.py:27 +msgid "Which boot loader would you like to use?" +msgstr "Hvilken boot loader Þnsker du at bruge?" + +#: ../tui_bootloader.py:37 +msgid "Use GRUB Boot Loader" +msgstr "Brug GRUB opstartsindlÊser" + +#: ../tui_bootloader.py:38 +msgid "No Boot Loader" +msgstr "Ingen boot loader" + +#: ../tui_bootloader.py:41 ../tui_bootloader.py:103 ../tui_bootloader.py:161 +#: ../tui_bootloader.py:278 ../tui_bootloader.py:383 +msgid "Boot Loader Configuration" +msgstr "Konfiguration af boot loader" + +#: ../tui_bootloader.py:58 +msgid "Skip Boot Loader" +msgstr "Overspring boot loader" + +#: ../tui_bootloader.py:59 +msgid "" +"You have elected not to install any boot loader, which is not recommended " +"unless you have an advanced need. Booting your system into Linux directly " +"from the hard drive almost always requires a boot loader.\n" +"\n" +"Are you sure you want to skip boot loader installation?" +msgstr "" +"Du har valgt ikke at installere nogen boot loader, hvilket ikke er " +"anbefalet, medmindre du har avancerede behov. En boot loader er nÊsten altid " +"pÃ¥krÊvet for at genstarte dit system med Linux direkte fra harddisken.\n" +"\n" +"Er du sikker pÃ¥, at du vil springe installationen af boot loaderen over?" + +#: ../tui_bootloader.py:88 +msgid "" +"A few systems need to pass special options to the kernel at boot time to " +"function properly. If you need to pass boot options to the kernel, enter " +"them now. If you don't need any or aren't sure, leave this blank." +msgstr "" +"Nogle fÃ¥ systemer har brug for angive sÊrlige parametre til kernen under " +"opstarten for at systemet kan fungere ordentligt. Hvis du har brug for at " +"overfÞre opstartsparametre til kernen, sÃ¥ indtast dem nu. Hvis du ikke " +"behÞver det eller er i tvivl, sÃ¥ lad dette felt stÃ¥ tomt." + +#: ../tui_bootloader.py:97 +msgid "Force use of LBA32 (not normally required)" +msgstr "Tvungen brug af LBA32 (ikke nÞdvendig normalt)" + +#: ../tui_bootloader.py:120 +msgid "" +"If LBA32 is not supported by your system's BIOS, forcing its use can prevent " +"your machine from booting.\n" +"\n" +"Would you like to continue and force LBA32 mode?" +msgstr "" +"Hvis LBA32 ikke er understÞttet af BIOS, kan gennemtvingning af brug af " +"dette forhindre at maskinen starter op.\n" +"\n" +"Vil du fortsÊtte med tvungen brug af LBA32-tilstand?" + +#: ../tui_bootloader.py:162 +msgid "Where do you want to install the boot loader?" +msgstr "Hvor vil du installere boot loaderen?" + +#: ../tui_bootloader.py:188 ../tui_bootloader.py:255 ../tui_partition.py:844 +msgid "Device" +msgstr "Enhed" + +#: ../tui_bootloader.py:189 ../tui_bootloader.py:255 +msgid "Boot label" +msgstr "Opstartsnavn" + +#: ../tui_bootloader.py:193 +msgid "Clear" +msgstr "Ryd" + +#: ../tui_bootloader.py:201 +#, fuzzy +msgid "Edit Boot Label" +msgstr "ugyldigt opstartsnavn" + +#: ../tui_bootloader.py:219 ../tui_bootloader.py:224 +msgid "Invalid Boot Label" +msgstr "ugyldigt opstartsnavn" + +#: ../tui_bootloader.py:220 +msgid "Boot label may not be empty." +msgstr "Opstartsnavn mÃ¥ ikke vÊre tomt." + +#: ../tui_bootloader.py:225 +msgid "Boot label contains illegal characters." +msgstr "Opstartsnavn indeholder ugyldige tegn." + +#: ../tui_bootloader.py:255 +msgid "Default" +msgstr "Standard" + +#: ../tui_bootloader.py:273 +#, python-format +msgid "" +"The boot manager %s uses can boot other operating systems as well. Please " +"tell me what partitions you would like to be able to boot and what label you " +"want to use for each of them." +msgstr "" +"Opstartsprogrammet, som bruges af %s, kan ogsÃ¥ starte andre " +"operativsystemer. Angiv hvilke partitioner du gerne vil kunne starte samt " +"hvilket navn du vil bruge for hvert af dem." + +#: ../tui_bootloader.py:286 +msgid "" +" <Space> select | <F2> select default | <F4> delete | <F12> next screen>" +msgstr "<Mellemrum> vÊlg | <F2> vÊlg standard | <F4> slet | <F12> nÊste skÊrm>" + +#: ../tui_bootloader.py:335 +msgid "Cannot Delete" +msgstr "Kan ikke slette" + +#: ../tui_bootloader.py:336 +#, python-format +msgid "" +"This boot target cannot be deleted because it is for the %s system you are " +"about to install." +msgstr "" +"Dette opstartsmÃ¥l kan ikke fjernes da det er beregnet til det %s-system du " +"er ved at installere." + +#: ../tui_bootloader.py:378 +msgid "" +"A boot loader password prevents users from passing arbitrary options to the " +"kernel. For highest security, you should set a password, but a password is " +"not necessary for more casual users." +msgstr "" +"En adgangskode for boot loaderen hindrer brugere i at give tilfÊldige " +"optioner til kernen. For at fÃ¥ hÞjest mulig sikkerhed bÞr du sÊtte en " +"adgangskode, men dette er ikke nÞdvendig for brugere med mindre krav til " +"sikkerhed." + +#: ../tui_bootloader.py:386 +msgid "Use a GRUB Password" +msgstr "Brug adgangskode for GRUB" + +#: ../tui_bootloader.py:399 +msgid "Boot Loader Password:" +msgstr "Adgangskode for boot loaderen:" + +#: ../tui_bootloader.py:400 +msgid "Confirm:" +msgstr "BekrÊft:" + +#: ../tui_bootloader.py:429 +msgid "Passwords Do Not Match" +msgstr "Adgangskoder er ikke ens." + +#: ../tui_bootloader.py:430 +msgid "Passwords do not match" +msgstr "Adgangskoder er ikke ens." + +#: ../tui_bootloader.py:434 +msgid "Password Too Short" +msgstr "Adgangskoden er for kort." + +#: ../tui_bootloader.py:435 +msgid "Boot loader password is too short" +msgstr "Boot loader adgangskoden er for kort." + +#: ../tui_bootloader.py:440 +msgid "" +"Your boot loader password is shorter than six characters. We recommend a " +"longer boot loader password.\n" +"\n" +"Would you like to continue with this password?" +msgstr "" +"Adgangskoden for boot loaderen er kortere end seks tegn. Vi anbefaler en " +"lÊngere adgangskode for boot loaderen.\n" +"\n" +"Vil du fortsÊtte med denne adgangskode?" + +#: ../tui_complete.py:25 +msgid "" +"Press <Enter> to end the installation process.\n" +"\n" +msgstr "" +"Tryk <enter> for at afslutte installationsprocessen.\n" +"\n" + +#: ../tui_complete.py:26 +msgid "<Enter> to exit" +msgstr "<Enter> for at afslutte" + +#: ../tui_complete.py:30 +#, python-format +msgid "" +"Congratulations, your %s installation is complete.\n" +"\n" +"%s%s" +msgstr "" +"Tillykke, din installation af %s er fÊrdig.\n" +"\n" +"%s%s" + +#: ../tui_complete.py:33 +#, python-format +msgid "" +"For information on errata (updates and bug fixes), visit %s.\n" +"\n" +"Information on using your system is available in the %s wiki at %s." +msgstr "" +"For information om errata (opdateringer og fejlrettelser), besÞg %s.\n" +"\n" +"Information om brug af systemet er tilgÊngelig i %s wiki pÃ¥ %s." + +#: ../tui_complete.py:39 +msgid "Complete" +msgstr "FÊrdig" + +#: ../tui_confirm.py:23 +msgid "Installation to begin" +msgstr "Installation begynder" + +#: ../tui_confirm.py:24 +msgid "" +"Now, we got all information we need for installation. If there is something " +"you want change you can still go back. If not choose OK to start." +msgstr "" +"Nu har vi alle informationerne vi har brug for installationen. Hvis der er " +"noget du vil Êndre kan du stadigvÊk gÃ¥ tilbage. Hvis ikke sÃ¥ klick OK for at " +"starte." + +#: ../tui_confirm.py:34 +msgid "Reboot?" +msgstr "Genstart?" + +#: ../tui_confirm.py:35 +msgid "The system will be rebooted now." +msgstr "Systemet vil nu blive genstartet." + +#: ../tui_keyboard.py:36 +msgid "Keyboard Selection" +msgstr "Tastaturvalg" + +#: ../tui_keyboard.py:37 +msgid "Which model keyboard is attached to this computer?" +msgstr "Hvilken tastaturtype er forbundet til denne maskine?" + +#: ../tui_language.py:39 +msgid "Language Selection" +msgstr "Sprogvalg" + +#: ../tui_language.py:40 +msgid "What language would you like to use during the installation process?" +msgstr "Hvilket sprog Þnsker du at benytte under installationsprocessen?" + +#: ../tui_network.py:39 +#, fuzzy +msgid "Hostname" +msgstr "VÊrtsnavn" + +#: ../tui_network.py:42 +msgid "" +"Please name this computer. The hostname identifies the computer on a " +"network." +msgstr "" + +#: ../tui_network.py:63 ../tui_network.py:70 +#, fuzzy +msgid "Invalid Hostname" +msgstr "ugyldigt opstartsnavn" + +#: ../tui_network.py:64 +msgid "You have not specified a hostname." +msgstr "" + +#: ../tui_network.py:71 +#, python-format +msgid "" +"The hostname "%s" is not valid for the following reason:\n" +"\n" +"%s" +msgstr "" + +#: ../tui_partition.py:41 +msgid "Must specify a value" +msgstr "VÊrdi skal specificeres" + +#: ../tui_partition.py:44 +msgid "Requested value is not an integer" +msgstr "Forespurgt vÊrdi er ikke et heltal" + +#: ../tui_partition.py:46 +msgid "Requested value is too large" +msgstr "Forespurgt vÊrdi er for stor" + +#: ../tui_partition.py:95 ../tui_partition.py:132 +msgid "Free space" +msgstr "Ledig plads" + +#: ../tui_partition.py:97 +msgid "Extended" +msgstr "Udvidet" + +#: ../tui_partition.py:111 +msgid "None" +msgstr "Intet" + +#: ../tui_partition.py:178 +#, python-format +msgid "Could not allocate requested partitions: %s." +msgstr "Kunne ikke allokere forespurgte partitioner: %s." + +#: ../tui_partition.py:182 +#, python-format +msgid "Warning: %s" +msgstr "Advarsel: %s" + +#: ../tui_partition.py:183 +msgid "Modify Partition" +msgstr "Ãndre partition" + +#: ../tui_partition.py:183 +msgid "Add anyway" +msgstr "TilfÞj alligevel" + +#: ../tui_partition.py:201 ../tui_partition.py:203 ../tui_partition.py:205 +#: ../tui_partition.py:230 +msgid "<Not Applicable>" +msgstr "<Ikke brugbar>" + +#: ../tui_partition.py:220 +msgid "Mount Point:" +msgstr "Monteringspunkt:" + +#: ../tui_partition.py:239 +msgid "File System type:" +msgstr "Filsystemtype:" + +#: ../tui_partition.py:270 +msgid "Allowable Drives:" +msgstr "Tilladte drev:" + +#: ../tui_partition.py:292 ../tui_partition.py:371 ../tui_partition.py:419 +msgid "Size (MB):" +msgstr "StÞrrelse (Mb):" + +#: ../tui_partition.py:324 +msgid "Fixed Size:" +msgstr "Fast stÞrrelse:" + +#: ../tui_partition.py:326 +msgid "Fill maximum size of (MB):" +msgstr "Fyld maksimal stÞrrelse pÃ¥ (Mb):" + +#: ../tui_partition.py:330 +msgid "Fill all available space:" +msgstr "Fyld al tilgÊngelig plads:" + +#: ../tui_partition.py:351 +msgid "Start Cylinder:" +msgstr "Startcylinder:" + +#: ../tui_partition.py:364 +msgid "End Cylinder:" +msgstr "Slutcylinder:" + +#: ../tui_partition.py:386 +msgid "Number of spares?" +msgstr "Antal reservediske?" + +#: ../tui_partition.py:400 +msgid "File System Type:" +msgstr "Filsystemtype:" + +#: ../tui_partition.py:413 +msgid "File System Label:" +msgstr "Filsystemetiket:" + +#: ../tui_partition.py:424 +msgid "File System Option:" +msgstr "Alternativ for filsystem:" + +#: ../tui_partition.py:427 ../tui_partition.py:652 +#, python-format +msgid "Format as %s" +msgstr "Formatér som %s" + +#: ../tui_partition.py:429 ../tui_partition.py:654 +#, python-format +msgid "Migrate to %s" +msgstr "Migrér til %s" + +#: ../tui_partition.py:431 ../tui_partition.py:656 +msgid "Leave unchanged" +msgstr "Forlad uforandret" + +#: ../tui_partition.py:446 ../tui_partition.py:629 +msgid "File System Options" +msgstr "Filsystemsvalgmuligheder" + +#: ../tui_partition.py:449 +msgid "" +"Please choose how you would like to prepare the file system on this " +"partition." +msgstr "" +"Venligst vÊlg hvordan du Þnsker at forberede filsystemet pÃ¥ denne partition." + +#: ../tui_partition.py:457 ../tui_partition.py:607 +msgid "Check for bad blocks" +msgstr "Se efter beskadigede blokke" + +#: ../tui_partition.py:461 +msgid "Leave unchanged (preserve data)" +msgstr "Forlad uforandret (behold data)" + +#: ../tui_partition.py:470 +msgid "Format as:" +msgstr "Formatér som:" + +#: ../tui_partition.py:489 +msgid "Migrate to:" +msgstr "Migrér til:" + +#: ../tui_partition.py:559 +msgid "Add Partition" +msgstr "TilfÞj partition" + +#: ../tui_partition.py:601 +msgid "Force to be a primary partition" +msgstr "Tving til at vÊre en primÊrpartition" + +#: ../tui_partition.py:684 ../tui_partition.py:738 +msgid "Invalid Entry for Partition Size" +msgstr "Ugyldig vÊrdi for partitionsstÞrrelse" + +#: ../tui_partition.py:696 +msgid "Invalid Entry for Maximum Size" +msgstr "Ugyldig opfÞring for maksimum stÞrrelse" + +#: ../tui_partition.py:716 +msgid "Invalid Entry for Starting Cylinder" +msgstr "Ugyldig vÊrdi for startcylinder" + +#: ../tui_partition.py:730 +msgid "Invalid Entry for End Cylinder" +msgstr "Ugyldig vÊrdi for slutcylinder" + +#: ../tui_partition.py:748 ../tui_partition.py:769 +msgid "Error With Request" +msgstr "Fejl med forespÞrgsel" + +#: ../tui_partition.py:838 +msgid "Partitioning" +msgstr "Partitionering" + +#: ../tui_partition.py:844 +msgid "Start" +msgstr "Start" + +#: ../tui_partition.py:844 +msgid "End" +msgstr "Slut" + +#: ../tui_partition.py:844 +msgid "Size" +msgstr "StÞrrelse" + +#: ../tui_partition.py:844 +msgid "Type" +msgstr "Type" + +#: ../tui_partition.py:844 +msgid "Mount Point" +msgstr "Monteringspunkt" + +#: ../tui_partition.py:848 +msgid "New" +msgstr "Ny" + +#: ../tui_partition.py:850 +msgid "Delete" +msgstr "Slet" + +#: ../tui_partition.py:853 +msgid "" +" F1-Help F2-New F3-Edit F4-Delete F5-Reset F12-OK " +msgstr "" +" F1-HjÊlp F2-Ny F3-Redigér F4-Fjern F5-Nulstil F12-O.k. " + +#: ../tui_partition.py:883 +msgid "No Root Partition" +msgstr "Ingen rodpartition" + +#: ../tui_partition.py:884 +msgid "Installation requires a / partition." +msgstr "Installationen krÊver en / partition." + +#: ../tui_partition.py:923 +msgid "Partitioning Type" +msgstr "Partitionstype" + +#: ../tui_partition.py:925 +msgid "" +"Installation requires partitioning of your hard drive. The default layout " +"is reasonable for most users. You can either choose to use this or create " +"your own." +msgstr "" +"Installation krÊver partitionering af din disk. Standard-opdelingen er " +"fornuftig for de fleste brugere. Du kan enten vÊlge denne, eller lave din " +"egen opdeling. " + +#: ../tui_partition.py:932 +msgid "Remove all partitions on selected drives and create default layout" +msgstr "" +"Fjern alle partitioner pÃ¥ valgte partitioner og opret standardudlÊgning" + +#: ../tui_partition.py:933 +msgid "Create custom layout" +msgstr "Opret selvdefineret layout" + +#: ../tui_partition.py:947 +msgid "Which drive(s) do you want to use for this installation?" +msgstr "Hvilke drev vil du bruge til denne installation?" + +#: ../tui_partition.py:960 +msgid "<Space>,<+>,<-> selection | <F2> Add drive | <F12> next screen" +msgstr "" +"<Mellemrum>,<+>,<-> valg | <F1> TilfÞj drev | <F12> nÊste skÊrm" + +#: ../tui_partition.py:1029 +msgid "Review Partition Layout" +msgstr "Vis igen de partitioner som oprettes" + +#: ../tui_partition.py:1030 +msgid "Review and modify partitioning layout?" +msgstr "Vis igen (og Êndr om det behÞves) de partitioner som oprettes?" + +#: ../tui_progress.py:52 +msgid "File Installation" +msgstr "Fil-installation" + +#: ../tui.py:118 +msgid "Exception Occurred" +msgstr "Undtagelse hÊndte" + +#: ../tui.py:189 +msgid "Error!" +msgstr "Fejl!" + +#: ../tui.py:190 +#, python-format +msgid "" +"An error occurred when attempting to load an pomona interface component.\n" +"\n" +"className = %s\n" +"\n" +"Error: %s" +msgstr "" +"Et fejl skete ved forsÞg at indlÊse en pomona interface komponent.\n" +"\n" +"className = %s\n" +"\n" +"Error: %s" + +#: ../tui.py:195 ../tui.py:197 +msgid "Exit" +msgstr "Afslut" + +#: ../tui.py:195 ../tui.py:391 +msgid "Retry" +msgstr "PrÞv igen" + +#: ../tui.py:220 +msgid "Cancelled" +msgstr "Annulleret" + +#: ../tui.py:221 +msgid "I can't go to the previous step from here. You will have to try again." +msgstr "Jeg kan ikke gÃ¥ til forrige trin herfra. Du skal prÞve igen." + +#: ../tui.py:235 +#, python-format +msgid "Welcome to %s" +msgstr "Velkommen til %s" + +#: ../tui.py:238 +msgid "" +" <F1> for help | <Tab> between elements | <Space> selects | <F12> next screen" +msgstr "" +" <F1> for hjÊlp | <Tab> imellem punkter | <Mellemrum> vÊlg | <F12> nÊste side" + +#: ../tui.py:240 +msgid "" +" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next " +"screen" +msgstr "" +" <Tab>/<Alt-Tab> imellem punkter | <Mellemrum> vÊlger | <F12> nÊste side" + +#: ../tui.py:285 +msgid "Help not available" +msgstr "Ingen hjÊlp tilgÊngelig" + +#: ../tui.py:286 +msgid "No help is available for this step of the install." +msgstr "Ingen hjÊlp er tilgÊngelig for dette trin af installationen." + +#: ../tui.py:387 +msgid "Fix" +msgstr "Reparér" + +#: ../tui.py:392 +msgid "Ignore" +msgstr "Ignorér" + +#: ../tui_timezone.py:63 +msgid "In which time zone are you located?" +msgstr "Hvilken tidszone befinder du dig i?" + +#: ../tui_timezone.py:78 +msgid "System clock uses UTC" +msgstr "System-ur bruger UTC" + +#: ../tui_timezone.py:81 +msgid "Time Zone Selection" +msgstr "Tidszone valg" + +#: ../tui_userauth.py:29 +msgid "Root Password" +msgstr "'root'-adgangskode" + +#: ../tui_userauth.py:31 +#, fuzzy +msgid "" +"Pick a root password. You must type it twice to ensure you know it and do " +"not make a typing mistake. Remember that the root password isa critical part " +"of system security!" +msgstr "" +"VÊlg en 'root'-adgangskode. Du skal skrive den to gange for at sikre at du " +"ved hvad det er og ikke fÃ¥r tastet forkert. Husk at 'root'-adgangskoden er " +"en afgÞrende del af systemets sikkerhed!" + +#: ../tui_userauth.py:41 +msgid "Password:" +msgstr "Adgangskode:" + +#: ../tui_userauth.py:42 +msgid "Password (confirm):" +msgstr "Adgangskode (bekrÊft):" + +#: ../tui_userauth.py:59 +msgid "Password Length" +msgstr "AdgangskodelÊngde" + +#: ../tui_userauth.py:60 +msgid "The root password must be at least 6 characters long." +msgstr "'root'-adgangskoden skal vÊre pÃ¥ mindst 6 tegn." + +#: ../tui_userauth.py:63 +msgid "Password Mismatch" +msgstr "Adgangskode stemmer ikke" + +#: ../tui_userauth.py:64 +msgid "The passwords you entered were different. Please try again." +msgstr "De to adgangskoder du indtastede var ikke ens. PrÞv igen." + +#: ../tui_userauth.py:67 +msgid "Error with Password" +msgstr "Fejl med adgangskode" + +#: ../tui_userauth.py:68 +msgid "" +"Requested password contains non-ASCII characters, which are not allowed." +msgstr "" +"Den udbedte adgangskode indeholder ikke-ascii tegn som ikke er tilladt." + +#: ../tui_welcome.py:12 +#, python-format +msgid "%s" +msgstr "%s" + +#: ../tui_welcome.py:13 +#, python-format +msgid "" +"Welcome to %s!\n" +"\n" +msgstr "" +"Velkommen til %s!\n" +"\n" + +#. generated from lang-table +msgid "English" +msgstr "Engelsk" + +#. generated from lang-table +msgid "German" +msgstr "Tysk" + +#. generated from lang-table +msgid "Danish" +msgstr "Dansk" + +#~ msgid "Checking for Bad Blocks" +#~ msgstr "Kontrollerer for dÃ¥rlige blokke" + +#~ msgid "" +#~ "An error occurred unmounting the disc. Please make sure you're not " +#~ "accessing the disk from the shell on tty2 and then click OK to retry." +#~ msgstr "" +#~ "En fejl skete ved afmontering af cd-en. Forsikr dig venligst om at du " +#~ "ikke bruger %s fra skallen, og klik sÃ¥ O.k. for at prÞve igen." + +#~ msgid "" +#~ "The file %s cannot be opened. This is due to a missing file or perhaps a " +#~ "corrupt package. Please verify your installation images and that you " +#~ "have all the required media.\n" +#~ "\n" +#~ "If you reboot, your system will be left in an inconsistent state that " +#~ "will likely require reinstallation.\n" +#~ "\n" +#~ msgstr "" +#~ "Filen %s kan ikke Ã¥bnes. Dette beror pÃ¥ en manglende fil eller mÃ¥ske en " +#~ "beskadiget pakke. Kontrollér dine installationsmedier og at du har alle " +#~ "de nÞdvendige medier.\n" +#~ "\n" +#~ "Hvis du genstarter vil dit system vÊre i en inkonsistent tilstand, som " +#~ "sandsynligvis vil krÊve geninstallation.\n" +#~ "\n" + +#, fuzzy +#~ msgid "Probing CDROM" +#~ msgstr "Forkert cd-rom" + +#~ msgid "Searching for a valid disc on /dev/%s..." +#~ msgstr "Kontrollerer for dÃ¥rlige blokke pÃ¥ /dev/%s..." + +#~ msgid "Wrong CDROM" +#~ msgstr "Forkert cd-rom" + +#~ msgid "That's not the correct %s CDROM in /dev/%s." +#~ msgstr "Dette er ikke den korrekte %s-cd-rom pÃ¥ /dev/%s." + +#~ msgid "Insert CDROM" +#~ msgstr "skift cd-rom" + +#~ msgid "Please insert the %s disc to continue." +#~ msgstr "IndsÊt venligst %s disk for at fortsÊtte." + +#~ msgid "Install on System" +#~ msgstr "Installér pÃ¥ system" + +#~ msgid "IPFire" +#~ msgstr "IPFire" + +#~ msgid "Disk Partitioning Setup" +#~ msgstr "OpsÊtning af diskpartitioner" + +#~ msgid "Autopartition" +#~ msgstr "Auto-partition" + +#~ msgid "Disk Druid" +#~ msgstr "Diskdruid" + +#~ msgid "Missing ISO 9660 Image" +#~ msgstr "Mangler ISO 9660-image" + +#~ msgid "" +#~ "The installer has tried to mount image #%s, but cannot find it on the " +#~ "hard drive.\n" +#~ "\n" +#~ "Please copy this image to the drive and click Retry. Click Reboot to " +#~ "abort the installation." +#~ msgstr "" +#~ "Installeringsprogrammet har forsÞgt at montere image #%s, men kan ikke " +#~ "finde det pÃ¥ disken.\n" +#~ "\n" +#~ "Kopiér venligst dette image til drevet og klik forsÞg igen. Klik genstart " +#~ "for at afbryde installationen." + +#~ msgid "Re_try" +#~ msgstr "_PrÞv igen" + +#~ msgid "Couldn't Mount ISO Source" +#~ msgstr "Kunne ikke montere ISO-kilde" + +#~ msgid "" +#~ "An error occurred mounting the source device %s. This may happen if your " +#~ "ISO images are located on an advanced storage device like LVM or RAID, or " +#~ "if there was a problem mounting a partition. Click reboot to abort the " +#~ "installation." +#~ msgstr "" +#~ "Der skete en fejl ved montering af kildeenheden %s. Dette kan ske hvis " +#~ "dine ISO-image ligger pÃ¥ et avancerede lagringsmedier som LVM eller RAID, " +#~ "eller hvis der var et problem med at montere en partition. Klik genstart " +#~ "for at afbryde installationen. " + +#~ msgid "Source Type" +#~ msgstr "Kildetype:" + +#~ msgid "" +#~ "In installation you have to choose a source for the installation files. " +#~ "Mostly you will choose the disc here, but you are also able to install by " +#~ "HTTP, FTP hard disk or usb-key." +#~ msgstr "" +#~ "I installationen skal du vÊlge en kilde for installationsfilerne. Typisk " +#~ "vil du vÊlge en harddisk, men du vil ogsÃ¥ kunne installere fra HTTP, FTP " +#~ "harddisk eller usb-nÞgle." + +#~ msgid "Install Disc" +#~ msgstr "Installationsdisk" + +#~ msgid "Internet Source" +#~ msgstr "Internet kilde" + +#~ msgid "External Drive" +#~ msgstr "Eksternt drev" + +#~ msgid "No CDROM found" +#~ msgstr "Ingen Cd fundet" + +#~ msgid "" +#~ "You choosed to install from an installtion disc, but there was no cdrom " +#~ "drive found on the system. Please choose another installation method." +#~ msgstr "" +#~ "Du valgte at installere fra installations-disken, men der blev ikke " +#~ "fundet noget cdrom-drev pÃ¥ dette system. VÊlg en anden " +#~ "installationsmethode." + +#~ msgid "Source URL" +#~ msgstr "Kilde URL:" + +#~ msgid "" +#~ "Enter a host you get the files from.You also must enter a path where the " +#~ "installer finds the files in." +#~ msgstr "" +#~ "Angiv en host som du modtager filerne fra. Du skal ogsÃ¥ angive en sti " +#~ "hvor instalationsprogrammet kan finde filerne." + +#~ msgid "Path:" +#~ msgstr "Sti:" + +#~ msgid "Wrong Protocol" +#~ msgstr "Forkert protokol" + +#~ msgid "" +#~ "You entered a protocol that is not supported by Pomona. There are only " +#~ "http:// and ftp:// available." +#~ msgstr "" +#~ "Du har angivet et protokol som ikke er understÞttet af Pomona. Der stÃ¥r " +#~ "kun http:// og ftp:// til rÃ¥dighed." + +#~ msgid "Syntax Error" +#~ msgstr "Syntaksfejl" + +#~ msgid "The path of the URL must end with a /." +#~ msgstr "Stien af denne URL skal afslutte med et /." + +#~ msgid "" +#~ "When we tested your given URL there was an error.\n" +#~ "\n" +#~ "%s" +#~ msgstr "" +#~ "Der opstod en fejl da vi testede din angivne URL.\n" +#~ "\n" +#~ "%s" + +#~ msgid "Downloading" +#~ msgstr "IndlÊser" + +#~ msgid "Connecting..." +#~ msgstr "Tilslutter..." + +#~ msgid "Retrieving %s" +#~ msgstr "Modtager %s" + +#~ msgid "" +#~ "The file %s cannot be opened. This is due to a missing file or perhaps a " +#~ "corrupt package. Please verify your mirror contains all required " +#~ "packages, and try using a different one.\n" +#~ "\n" +#~ "If you reboot, your system will be left in an inconsistent state that " +#~ "will likely require reinstallation.\n" +#~ "\n" +#~ msgstr "" +#~ "Filen %s kan ikke Ã¥bnes. Dette beror pÃ¥ en manglende fil eller mÃ¥ske en " +#~ "beskadiget pakke. Kontrollér at din mirror indeholder alle de nÞdvendige " +#~ "pakker, eller prÞv at bruge en anden mirror.\n" +#~ "\n" +#~ "Hvis du genstarter vil dit system vÊre i en inkonsistent tilstand, som " +#~ "sandsynligvis vil krÊve geninstallation.\n" +#~ "\n" + +#~ msgid "" +#~ "An error occurred unmounting the disc. Please make sure you're not " +#~ "accessing %s from the shell on tty2 and then click OK to retry." +#~ msgstr "" +#~ "En fejl skete ved afmontering af cd-en. Forsikr dig venligst om at du " +#~ "ikke bruger %s fra skallen, og klik sÃ¥ O.k. for at prÞve igen." diff --git a/pkgs/core/pomona/src/po/de.po b/pkgs/core/pomona/src/po/de.po new file mode 100644 index 0000000..c03b398 --- /dev/null +++ b/pkgs/core/pomona/src/po/de.po @@ -0,0 +1,2177 @@ +# German translation of Pomona +# Copyright (C) 2007 The IPFire Team +# This file is distributed under the same license as IPFire. +# Michael Tremer <michael.tremer@ipfire.org>, 2007. +# +msgid "" +msgstr "" +"Project-Id-Version: Pomona\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-01-29 01:02+0100\n" +"PO-Revision-Date: 2009-01-29 01:26+0100\n" +"Last-Translator: Michael Tremer <michael.tremer@ipfire.org>\n" +"Language-Team: German\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../autopart.py:751 +#, python-format +msgid "" +"Could not allocate cylinder-based partitions as primary partitions.\n" +"\n" +"%s" +msgstr "" + +#: ../autopart.py:756 +#, python-format +msgid "" +"Could not allocate partitions as primary partitions.\n" +"\n" +"%s" +msgstr "" + +#: ../autopart.py:761 +#, python-format +msgid "" +"Could not allocate cylinder-based partitions.\n" +"\n" +"%s" +msgstr "" + +#: ../autopart.py:800 +#, python-format +msgid "" +"Boot partition %s doesn't belong to a BSD disk label. SRM won't be able to " +"boot from this partition. Use a partition belonging to a BSD disk label or " +"change this device disk label to BSD." +msgstr "" + +#: ../autopart.py:802 +#, python-format +msgid "" +"Boot partition %s doesn't belong to a disk with enough free space at its " +"beginning for the bootloader to live on. Make sure that there's at least 5MB " +"of free space at the beginning of the disk that contains /boot" +msgstr "" + +#: ../autopart.py:804 +#, python-format +msgid "" +"Boot partition %s isn't a VFAT partition. EFI won't be able to boot from " +"this partition." +msgstr "" + +#: ../autopart.py:806 +msgid "" +"The boot partition must entirely be in the first 4GB of the disk. " +"OpenFirmware won't be able to boot this installation." +msgstr "" + +#: ../autopart.py:813 +#, python-format +msgid "" +"Boot partition %s may not meet booting constraints for your architecture." +msgstr "" + +#: ../autopart.py:951 +msgid "Requested Partition Does Not Exist" +msgstr "Die angegebene Partition existiert nicht" + +#: ../autopart.py:952 +#, python-format +msgid "" +"Unable to locate partition %s to use for %s.\n" +"\n" +"Press 'OK' to reboot your system." +msgstr "" + +#: ../autopart.py:997 ../autopart.py:1029 +msgid "Automatic Partitioning Errors" +msgstr "" + +#: ../autopart.py:998 +#, python-format +msgid "" +"The following errors occurred with your partitioning:\n" +"\n" +"%s\n" +"\n" +"Press 'OK' to reboot your system." +msgstr "" + +#: ../autopart.py:1007 +msgid "Warnings During Automatic Partitioning" +msgstr "" + +#: ../autopart.py:1008 +#, python-format +msgid "" +"Following warnings occurred during automatic partitioning:\n" +"\n" +"%s" +msgstr "" + +#: ../autopart.py:1016 ../tui_partition.py:177 +msgid "Error Partitioning" +msgstr "Partitionierungsfehler" + +#: ../autopart.py:1017 +#, python-format +msgid "" +"Could not allocate requested partitions: \n" +"\n" +"%s." +msgstr "" + +#: ../autopart.py:1027 +msgid "" +"\n" +"\n" +"Press 'OK' to choose a different partitioning option." +msgstr "" +"\n" +"\n" +"DrÃŒcken Sie 'OK' um eine andere Partitionierungsoption zu wÀhlen." + +#: ../autopart.py:1030 +#, python-format +msgid "" +"The following errors occurred with your partitioning:\n" +"\n" +"%s\n" +"\n" +"This can happen if there is not enough space on your hard drive(s) for the " +"installation. %s" +msgstr "" + +#: ../autopart.py:1105 ../bootloader.py:745 ../partedUtils.py:230 +#: ../partedUtils.py:531 ../partedUtils.py:568 ../tui_bootloader.py:119 +#: ../tui_bootloader.py:439 ../tui_partition.py:182 +msgid "Warning" +msgstr "Warnung" + +#: ../autopart.py:1126 +msgid "" +"Automatic Partitioning sets partitions based on the selected installation " +"type. You also can customize the partitions once they have been created.\n" +"\n" +"The manual disk partitioning tool, Disk Druid, allows you to create " +"partitions in an interactive environment. You can set the file system types, " +"mount points, partition sizes, and more." +msgstr "" + +#: ../autopart.py:1137 +msgid "" +"Before automatic partitioning can be set up by the installation program, you " +"must choose how to use the space on your hard drives." +msgstr "" + +#: ../autopart.py:1142 +msgid "Remove all partitions on this system" +msgstr "Entferne alle Partitionen auf diesem System" + +#: ../autopart.py:1144 +#, python-format +msgid "" +"You have chosen to remove all partitions (ALL DATA) on the following drives:%" +"s\n" +"Are you sure you want to do this?" +msgstr "" +"Sie haben sich entschlossen alle Partitionen (einschlieÃlich aller Daten) " +"auf den folgenden DatentrÀgern zu entfernen: %s\n" +"Sind Sie sich sicher?" + +#: ../bootloader.py:696 +msgid "Bootloader" +msgstr "Bootloader" + +#: ../bootloader.py:696 +msgid "Installing bootloader..." +msgstr "Installiere Bootloader..." + +#: ../bootloader.py:746 +msgid "" +"No kernel packages were installed on your system. Your boot loader " +"configuration will not be changed." +msgstr "" + +#: ../constants.py:41 +#, python-format +msgid "" +"An unhandled exception has occurred. This is most likely a bug. Please " +"save a copy of the detailed exception and file a bug report against pomona " +"at %s" +msgstr "" +"Ein unerwarteter Fehler ist aufgetreten. Meistens handelt es sich um einen " +"Bug, wenn Sie diese Meldung sehen. Bitte sichern Sie eine detaillierte Kopie " +"dieses Fehlers und senden Sie diese an den Bugtracker %s." + +#: ../constants.py:83 ../installer.py:93 ../tui_confirm.py:28 +#: ../tui_network.py:65 ../tui_network.py:74 ../tui.py:224 ../tui.py:390 +msgid "OK" +msgstr "OK" + +#: ../constants.py:87 ../partIntfHelpers.py:150 ../partIntfHelpers.py:392 +#: ../tui_bootloader.py:194 ../tui.py:103 ../tui.py:104 ../tui.py:393 +msgid "Cancel" +msgstr "Abbrechen" + +#: ../constants.py:91 ../tui_confirm.py:28 ../tui_confirm.py:30 +msgid "Back" +msgstr "ZurÃŒck" + +#: ../constants.py:95 ../tui_bootloader.py:67 ../tui.py:388 +msgid "Yes" +msgstr "Ja" + +#: ../constants.py:99 ../tui_bootloader.py:67 ../tui.py:389 +msgid "No" +msgstr "Nein" + +#: ../constants.py:103 ../tui_bootloader.py:270 ../tui_partition.py:849 +msgid "Edit" +msgstr "Bearbeiten" + +#: ../fsset.py:422 +msgid "Checking" +msgstr "ÃberprÃŒfe" + +#: ../fsset.py:423 +#, python-format +msgid "Checking filesystem on %s..." +msgstr "Untersuche Dateisystem %s..." + +#: ../fsset.py:434 +msgid "Resizing" +msgstr "" + +#: ../fsset.py:435 +#, python-format +msgid "Resizing filesystem on %s..." +msgstr "VerÀndere DateisystemgröÃe auf %s..." + +#: ../fsset.py:578 ../fsset.py:1112 ../fsset.py:1143 ../fsset.py:1205 +#: ../fsset.py:1216 ../fsset.py:1270 ../fsset.py:1281 ../fsset.py:1303 +#: ../fsset.py:1352 ../fsset.py:1433 ../partIntfHelpers.py:289 +msgid "Error" +msgstr "Fehler" + +#: ../fsset.py:579 +#, python-format +msgid "" +"An error occurred migrating %s to ext3. It is possible to continue without " +"migrating this file system if desired.\n" +"\n" +"Would you like to continue without migrating %s?" +msgstr "" +"Bei der Migration von %s zu ext3 trat ein Fehler auf. Es ist möglich " +"fortzufahren ohne die Migration zu vollziehen.\n" +"\n" +"Möchten Sie ohne Migration von %s fortfahren?" + +#: ../fsset.py:1046 +msgid "First sector of boot partition" +msgstr "Erster Sektor der Boot-Partition" + +#: ../fsset.py:1047 +msgid "Master Boot Record (MBR)" +msgstr "Boot-Sektor (MBR)" + +#: ../fsset.py:1113 +#, python-format +msgid "" +"An error occurred trying to initialize swap on device %s. This problem is " +"serious, and the install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" + +#: ../fsset.py:1142 +msgid "Skip" +msgstr "Ãberspringen" + +#: ../fsset.py:1142 ../tui_complete.py:40 +msgid "Reboot" +msgstr "Neustarten" + +#: ../fsset.py:1163 +#, python-format +msgid "" +"The swap device:\n" +"\n" +" /dev/%s\n" +"\n" +"is a version 0 Linux swap partition. If you want to use this device, you " +"must reformat as a version 1 Linux swap partition. If you skip it, the " +"installer will ignore it during the installation." +msgstr "" + +#: ../fsset.py:1170 +msgid "Reformat" +msgstr "Neu formatieren" + +#: ../fsset.py:1174 +#, python-format +msgid "" +"The swap device:\n" +"\n" +" /dev/%s\n" +"\n" +"in your /etc/fstab file is currently in use as a software suspend partition, " +"which means your system is hibernating. To perform an upgrade, please shut " +"down your system rather than hibernating it." +msgstr "" + +#: ../fsset.py:1182 +#, python-format +msgid "" +"The swap device:\n" +"\n" +" /dev/%s\n" +"\n" +"in your /etc/fstab file is currently in use as a software suspend partition, " +"which means your system is hibernating. If you are performing a new install, " +"make sure the installer is set to format all swap partitions." +msgstr "" + +#: ../fsset.py:1192 +msgid "" +"\n" +"\n" +"Choose Skip if you want the installer to ignore this partition during the " +"upgrade. Choose Format to reformat the partition as swap space. Choose " +"Reboot to restart the system." +msgstr "" + +#: ../fsset.py:1198 +msgid "Format" +msgstr "Formatieren" + +#: ../fsset.py:1206 +#, python-format +msgid "" +"Error enabling swap device %s: %s\n" +"\n" +"The /etc/fstab on your upgrade partition does not reference a valid swap " +"partition.\n" +"\n" +"Press OK to reboot your system." +msgstr "" + +#: ../fsset.py:1217 +#, python-format +msgid "" +"Error enabling swap device %s: %s\n" +"\n" +"This most likely means this swap partition has not been initialized.\n" +"\n" +"Press OK to reboot your system." +msgstr "" + +#: ../fsset.py:1271 +#, python-format +msgid "" +"Bad blocks have been detected on device /dev/%s. We do not recommend you use " +"this device.\n" +"\n" +"Press <Enter> to reboot your system" +msgstr "" + +#: ../fsset.py:1282 +#, python-format +msgid "" +"An error occurred searching for bad blocks on %s. This problem is serious, " +"and the install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" + +#: ../fsset.py:1304 +#, python-format +msgid "" +"An error occurred trying to format %s. This problem is serious, and the " +"install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" + +#: ../fsset.py:1353 +#, python-format +msgid "" +"An error occurred trying to migrate %s. This problem is serious, and the " +"install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" + +#: ../fsset.py:1380 ../fsset.py:1389 +msgid "Invalid mount point" +msgstr "UngÃŒltiger Mount-Point" + +#: ../fsset.py:1381 +#, python-format +msgid "" +"An error occurred when trying to create %s. Some element of this path is " +"not a directory. This is a fatal error and the install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" + +#: ../fsset.py:1390 +#, python-format +msgid "" +"An error occurred when trying to create %s: %s. This is a fatal error and " +"the install cannot continue.\n" +"\n" +"Press <Enter> to reboot your system." +msgstr "" + +#: ../fsset.py:1403 +msgid "Unable to mount filesystem" +msgstr "Konnte das Dateisystem nicht mounten" + +#: ../fsset.py:1404 +#, python-format +msgid "" +"An error occurred mounting device %s as %s. You may continue installation, " +"but there may be problems." +msgstr "" + +#: ../fsset.py:1411 ../fsset.py:1820 ../fsset.py:1827 ../packages.py:131 +#: ../partedUtils.py:578 ../tui_confirm.py:37 +msgid "_Reboot" +msgstr "_Neustart" + +#: ../fsset.py:1411 ../partedUtils.py:578 +msgid "_Continue" +msgstr "_Fortfahren" + +#: ../fsset.py:1419 +#, python-format +msgid "" +"Error mounting device %s as %s: %s\n" +"\n" +"Devices in /etc/fstab should be specified by label, not by device name.\n" +"\n" +"Press OK to reboot your system." +msgstr "" + +#: ../fsset.py:1426 +#, python-format +msgid "" +"Error mounting device %s as %s: %s\n" +"\n" +"This most likely means this partition has not been formatted.\n" +"\n" +"Press OK to reboot your system." +msgstr "" + +#: ../fsset.py:1812 +msgid "Duplicate Labels" +msgstr "Doppelte Labels" + +#: ../fsset.py:1813 +#, python-format +msgid "" +"Multiple devices on your system are labelled %s. Labels across devices must " +"be unique for your system to function properly.\n" +"\n" +"Please fix this problem and restart the installation process." +msgstr "" + +#: ../fsset.py:1822 +msgid "Invalid Label" +msgstr "UngÃŒltiges Label" + +#: ../fsset.py:1823 +#, python-format +msgid "" +"An invalid label was found on device %s. Please fix this problem and " +"restart the installation process." +msgstr "" + +#: ../fsset.py:2049 +msgid "Formatting" +msgstr "Formatiere" + +#: ../fsset.py:2050 +#, python-format +msgid "Formatting %s file system..." +msgstr "Formatiere %s..." + +#: ../installer.py:88 +msgid "Fatal Error" +msgstr "Fehler" + +#: ../installer.py:89 +#, python-format +msgid "" +"You do not have enough RAM to install %s on this machine.\n" +"\n" +"Press <return> to reboot your system.\n" +msgstr "" +"Sie haben nicht genug Arbeitsspeicher um %s auf diesem System zu " +"installieren.\n" +"\n" +"DrÃŒcken Sie <Neustart> um das System neu zu starten.\n" + +#: ../installer.py:173 +msgid "Starting text installation..." +msgstr "Starte Textinstallation..." + +#: ../keyboard_models.py:48 +msgid "keyboard|Arabic (azerty)" +msgstr "" + +#: ../keyboard_models.py:51 +msgid "keyboard|Arabic (azerty/digits)" +msgstr "" + +#: ../keyboard_models.py:54 +msgid "keyboard|Arabic (digits)" +msgstr "" + +#: ../keyboard_models.py:57 +msgid "keyboard|Arabic (qwerty)" +msgstr "" + +#: ../keyboard_models.py:60 +msgid "keyboard|Arabic (qwerty/digits)" +msgstr "" + +#: ../keyboard_models.py:63 +msgid "keyboard|Belgian (be-latin1)" +msgstr "" + +#: ../keyboard_models.py:66 +msgid "keyboard|Bengali (Inscript)" +msgstr "" + +#: ../keyboard_models.py:69 +msgid "keyboard|Bengali (Probhat)" +msgstr "" + +#: ../keyboard_models.py:72 +msgid "keyboard|Bulgarian" +msgstr "" + +#: ../keyboard_models.py:75 +msgid "keyboard|Bulgarian (Phonetic)" +msgstr "" + +#: ../keyboard_models.py:78 +msgid "keyboard|Brazilian (ABNT2)" +msgstr "" + +#: ../keyboard_models.py:81 +msgid "keyboard|French Canadian" +msgstr "" + +#: ../keyboard_models.py:84 +msgid "keyboard|Croatian" +msgstr "" + +#: ../keyboard_models.py:87 +msgid "keyboard|Czech" +msgstr "" + +#: ../keyboard_models.py:90 +msgid "keyboard|Czech (qwerty)" +msgstr "" + +#: ../keyboard_models.py:93 +msgid "keyboard|German" +msgstr "" + +#: ../keyboard_models.py:96 +msgid "keyboard|German (latin1)" +msgstr "" + +#: ../keyboard_models.py:99 +msgid "keyboard|German (latin1 w/ no deadkeys)" +msgstr "" + +#: ../keyboard_models.py:102 +msgid "keyboard|Devanagari (Inscript)" +msgstr "" + +#: ../keyboard_models.py:105 +msgid "keyboard|Dvorak" +msgstr "" + +#: ../keyboard_models.py:108 +msgid "keyboard|Danish" +msgstr "" + +#: ../keyboard_models.py:111 +msgid "keyboard|Danish (latin1)" +msgstr "" + +#: ../keyboard_models.py:114 +msgid "keyboard|Spanish" +msgstr "" + +#: ../keyboard_models.py:117 +msgid "keyboard|Estonian" +msgstr "" + +#: ../keyboard_models.py:120 +msgid "keyboard|Finnish" +msgstr "" + +#: ../keyboard_models.py:123 +msgid "keyboard|Finnish (latin1)" +msgstr "" + +#: ../keyboard_models.py:126 +msgid "keyboard|French" +msgstr "" + +#: ../keyboard_models.py:129 +msgid "keyboard|French (latin9)" +msgstr "" + +#: ../keyboard_models.py:132 +msgid "keyboard|French (latin1)" +msgstr "" + +#: ../keyboard_models.py:135 +msgid "keyboard|French (pc)" +msgstr "" + +#: ../keyboard_models.py:138 +msgid "keyboard|Swiss French" +msgstr "" + +#: ../keyboard_models.py:141 +msgid "keyboard|Swiss French (latin1)" +msgstr "" + +#: ../keyboard_models.py:144 +msgid "keyboard|Greek" +msgstr "" + +#: ../keyboard_models.py:147 +msgid "keyboard|Gujarati (Inscript)" +msgstr "" + +#: ../keyboard_models.py:150 +msgid "keyboard|Punjabi (Inscript)" +msgstr "" + +#: ../keyboard_models.py:153 +msgid "keyboard|Hungarian" +msgstr "" + +#: ../keyboard_models.py:156 +msgid "keyboard|Hungarian (101 key)" +msgstr "" + +#: ../keyboard_models.py:159 +msgid "keyboard|Icelandic" +msgstr "" + +#: ../keyboard_models.py:162 +msgid "keyboard|Italian" +msgstr "" + +#: ../keyboard_models.py:165 +msgid "keyboard|Italian (IBM)" +msgstr "" + +#: ../keyboard_models.py:168 +msgid "keyboard|Italian (it2)" +msgstr "" + +#: ../keyboard_models.py:171 +msgid "keyboard|Japanese" +msgstr "" + +#: ../keyboard_models.py:174 +msgid "keyboard|Korean" +msgstr "" + +#: ../keyboard_models.py:177 +msgid "keyboard|Latin American" +msgstr "" + +#: ../keyboard_models.py:180 +msgid "keyboard|Macedonian" +msgstr "" + +#: ../keyboard_models.py:183 +msgid "keyboard|Dutch" +msgstr "" + +#: ../keyboard_models.py:186 +msgid "keyboard|Norwegian" +msgstr "" + +#: ../keyboard_models.py:189 +msgid "keyboard|Polish" +msgstr "" + +#: ../keyboard_models.py:192 +msgid "keyboard|Portuguese" +msgstr "" + +#: ../keyboard_models.py:195 +msgid "keyboard|Romanian" +msgstr "" + +#: ../keyboard_models.py:198 +msgid "keyboard|Russian" +msgstr "" + +#: ../keyboard_models.py:201 +msgid "keyboard|Serbian" +msgstr "" + +#: ../keyboard_models.py:204 +msgid "keyboard|Serbian (latin)" +msgstr "" + +#: ../keyboard_models.py:207 +msgid "keyboard|Swedish" +msgstr "" + +#: ../keyboard_models.py:210 +msgid "keyboard|Swiss German" +msgstr "" + +#: ../keyboard_models.py:213 +msgid "keyboard|Swiss German (latin1)" +msgstr "" + +#: ../keyboard_models.py:216 +msgid "keyboard|Slovak (qwerty)" +msgstr "" + +#: ../keyboard_models.py:219 +msgid "keyboard|Slovenian" +msgstr "" + +#: ../keyboard_models.py:222 +msgid "keyboard|Tamil (Inscript)" +msgstr "" + +#: ../keyboard_models.py:225 +msgid "keyboard|Tamil (Typewriter)" +msgstr "" + +#: ../keyboard_models.py:228 +msgid "keyboard|Turkish" +msgstr "" + +#: ../keyboard_models.py:231 +msgid "keyboard|United Kingdom" +msgstr "" + +#: ../keyboard_models.py:234 +msgid "keyboard|Ukrainian" +msgstr "" + +#: ../keyboard_models.py:237 +msgid "keyboard|U.S. International" +msgstr "" + +#: ../keyboard_models.py:240 +msgid "keyboard|U.S. English" +msgstr "" + +#: ../network.py:31 +msgid "IP address is missing." +msgstr "IP-Adresse fehlt." + +#: ../network.py:35 +msgid "" +"IPv4 addresses must contain four numbers between 0 and 255, separated by " +"periods." +msgstr "" +"IPv4-Adressen mÃŒssen vier Oktets mit Zahlen zwischen 0 und 255 enthalten. " +"Getrennt von Punkten." + +#: ../network.py:38 +#, python-format +msgid "'%s' is not a valid IPv6 address." +msgstr "'%s' ist keine gÃŒltige IPv6-Adresse." + +#: ../network.py:40 +#, python-format +msgid "'%s' is an invalid IP address." +msgstr "'%s' ist eine ungÃŒltige IP-Adresse." + +#: ../network.py:52 +msgid "Hostname must be 255 or fewer characters in length." +msgstr "Hostname muss 255 oder weniger Zeichen enthalten." + +#: ../network.py:58 +msgid "" +"Hostname must start with a valid character in the ranges 'a-z', 'A-Z', or '0-" +"9'" +msgstr "" +"Der Hostname muss mit mit einem gÃŒltigen Zeichen beginnen. Das sind 'a-z', " +"'A-Z' oder '0-9'." + +#: ../network.py:63 +msgid "" +"Hostnames can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.'" +msgstr "" + +#: ../packages.py:113 +msgid "Warning! This is pre-release software!" +msgstr "Warnung! Dies ist noch nicht veröffentlichte Software!" + +#: ../packages.py:114 +#, python-format +msgid "" +"Thank you for downloading this pre-release of %s.\n" +"\n" +"This is not a final release and is not intended for use on production " +"systems. The purpose of this release is to collect feedback from testers, " +"and it is not suitable for day to day usage.\n" +"\n" +"To report feedback, please visit:\n" +"\n" +" %s\n" +"\n" +"and file a report against '%s'.\n" +msgstr "" +"Danke, fÃŒr das probieren dieser noch nicht veröffentlichten Version von %s.\n" +"\n" +"Diese Software ist noch kein finales Release und nicht fÃŒr den produktiven " +"Einsatz gedacht. Der Zweck liegt darin Fehler zu finden und Feedback von " +"Testern zu bekommen.\n" +"\n" +"Um Feedback zu geben besuchen Sie\n" +"\n" +" %s\n" +"\n" +"und senden einen Report ÃŒber '%s'.\n" + +#: ../packages.py:127 +msgid "_Exit" +msgstr "Ende" + +#: ../packages.py:127 +msgid "_Install anyway" +msgstr "_Trotzdem installieren" + +#: ../packages.py:130 +msgid "Your system will now be rebooted..." +msgstr "Ihr System wird jetzt neu gestartet..." + +#: ../packages.py:131 ../tui_confirm.py:37 +msgid "_Back" +msgstr "ZurÃŒck" + +#: ../packages.py:132 +msgid "Rebooting System" +msgstr "Starte das System neu" + +#: ../pakfireinstall.py:47 +#, python-format +msgid "%s MB" +msgstr "%s MB" + +#: ../pakfireinstall.py:50 +#, python-format +msgid "%s KB" +msgstr "%s KB" + +#: ../pakfireinstall.py:53 +#, python-format +msgid "%s Byte" +msgstr "%s Byte" + +#: ../pakfireinstall.py:55 +#, python-format +msgid "%s Bytes" +msgstr "%s Bytes" + +#: ../pakfireinstall.py:134 +msgid "Base system" +msgstr "Grundsystem" + +#: ../pakfireinstall.py:134 +msgid "Installing base system..." +msgstr "Installiere Basissystem..." + +#: ../pakfireinstall.py:171 +msgid "Install Starting" +msgstr "Starte Installation" + +#: ../pakfireinstall.py:172 +msgid "Starting install process. This may take several minutes..." +msgstr "" +"Der Installationsprozess wird gestartet. Haben Sie einen Augenblick Geduld..." + +#: ../pakfireinstall.py:183 +msgid "Post Install" +msgstr "" + +#: ../pakfireinstall.py:184 +msgid "Performing post install configuration..." +msgstr "" + +#: ../pakfireinstall.py:215 +msgid "Symmetric multiprocessing" +msgstr "" + +#: ../pakfireinstall.py:216 +msgid "Xen guest" +msgstr "Xen-Gast" + +#: ../pakfireinstall.py:226 +msgid "Normal Boot" +msgstr "Normaler Boot" + +#: ../pakfireinstall.py:233 +msgid "Installation Progress" +msgstr "Installationsprozess" + +#: ../partedUtils.py:191 ../tui_partition.py:408 +msgid "Foreign" +msgstr "" + +#: ../partedUtils.py:231 +#, python-format +msgid "" +"/dev/%s currently has a %s partition layout. To use this drive for the " +"installation of %s, it must be re-initialized, causing the loss of ALL DATA " +"on this drive.\n" +"\n" +"Would you like to re-initialize this drive?" +msgstr "" +"/dev/%s hat momentan ein %s Partitionslayout. Um dieses Laufwerk fÃŒr eine %s-" +"Installation zu nutzen muss es reinitialisiert werden, was ALLE DATEN auf " +"diesem Laufwerk vernichten wird.\n" +"\n" +"Möchten Sie das Laufwerk reinitialisieren?" + +#: ../partedUtils.py:239 +msgid "_Ignore drive" +msgstr "_Ignoriere Laufwerk" + +#: ../partedUtils.py:240 +msgid "_Re-initialize drive" +msgstr "_Reinitialisiere Laufwerk" + +#: ../partedUtils.py:532 +#, python-format +msgid "" +"The partition table on device %s was unreadable. To create new partitions it " +"must be initialized, causing the loss of ALL DATA on this drive.\n" +"\n" +"This operation will override any previous installation choices about which " +"drives to ignore.\n" +"\n" +"Would you like to initialize this drive, erasing ALL DATA?" +msgstr "" +"Die Partitionstabelle auf %s war nicht lesbar. Um neue Partitionen zu " +"erstellen muss diese initialisiert werden, was ALLE DATEN auf diesem " +"Laufwerk vernichten wird.\n" +"\n" +"Diese Operation wird alle vorhergegangen Entscheidungen ÃŒber auszulassende " +"Laufwerke verwerfen.\n" +"\n" +"Möchten Sie dieses Laufwerk initialisieren, was ALLE DATEN vernichten wird?" + +#: ../partedUtils.py:569 +#, python-format +msgid "" +"The drive /dev/%s has more than 15 partitions on it. The SCSI subsystem in " +"the Linux kernel does not allow for more than 15 partitons at this time. " +"You will not be able to make changes to the partitioning of this disk or use " +"any partitions beyond /dev/%s15 in %s" +msgstr "" +"Das Laufwerk /dev/%s hat mehr als 15 Partitionen. Das SCSI-Subsystem des " +"Linux-Kernel erlaubt im Augenblick nicht mehr als 15 Partitionen. Sie werden " +"keine PartitionsÀnderungen vornehmen und auf keine Partitionen nach /dev/%" +"s15 auf %s zugreifen können." + +#: ../partedUtils.py:659 +msgid "No Drives Found" +msgstr "Keine Laufwerke gefunden" + +#: ../partedUtils.py:660 +msgid "" +"An error has occurred - no valid devices were found on which to create new " +"file systems. Please check your hardware for the cause of this problem." +msgstr "" +"Ein Fehler trat auf. - Es wurden keine Laufwerke gefunden, auf welche das " +"Dateisystem erstellt werden könnte. Bitte ÃŒberprÃŒfen Sie ihre Hardware fÃŒr " +"die Ursache des Problems." + +#: ../partIntfHelpers.py:50 +#, python-format +msgid "" +"The mount point %s is invalid. Mount points must start with '/' and cannot " +"end with '/', and must contain printable characters and no spaces." +msgstr "" +"Der EinhÀngepunkt %s ist ungÃŒltig. EinhÀngepunkte mÃŒssen mit einem '/' " +"beginnen und dÃŒrfen nicht mit einem '/' enden. Ebenso dÃŒrfen sie nur " +"druckbare Zeichen enthalten, jedoch keine Leerzeichen." + +#: ../partIntfHelpers.py:57 +msgid "Please specify a mount point for this partition." +msgstr "Geben Sie einen EinhÀngepunkt fÃŒr diese Partition an." + +#: ../partIntfHelpers.py:74 ../partIntfHelpers.py:80 ../partIntfHelpers.py:90 +#: ../partIntfHelpers.py:111 +msgid "Unable To Delete" +msgstr "" + +#: ../partIntfHelpers.py:75 +msgid "You must first select a partition to delete." +msgstr "Sie mÃŒssen zuerste eine Partition auswÀhlen um diese zu entfernen." + +#: ../partIntfHelpers.py:81 +msgid "You cannot delete free space." +msgstr "Sie können keinen freien Platz löschen." + +#: ../partIntfHelpers.py:91 +#, python-format +msgid "" +"You cannot delete this partition, as it is an extended partition which " +"contains %s" +msgstr "" +"Sie können diese Partition nicht löschen, da sie eine erweiterte Partition " +"ist, welche %s enthÀlt." + +#: ../partIntfHelpers.py:106 +msgid "This partition is holding the data for the hard drive install." +msgstr "Diese Partition beinhaltet die Daten fÃŒr die Festplatten-Installation." + +#: ../partIntfHelpers.py:112 +msgid "" +"You cannot delete this partition:\n" +"\n" +msgstr "" +"Sie können diese Partition nicht löschen:\n" +"\n" + +#: ../partIntfHelpers.py:146 ../partIntfHelpers.py:391 +msgid "Confirm Delete" +msgstr "Löschen bestÀtigen" + +#: ../partIntfHelpers.py:147 +#, python-format +msgid "You are about to delete all partitions on the device '/dev/%s'." +msgstr "" +"Sie sind im Begriff alle Partitionen auf dem Laufwerk '/dev/%s' zu löschen." + +#: ../partIntfHelpers.py:150 ../partIntfHelpers.py:392 +msgid "_Delete" +msgstr "_Löschen" + +#: ../partIntfHelpers.py:206 +msgid "Notice" +msgstr "Hinweis" + +#: ../partIntfHelpers.py:207 +#, python-format +msgid "" +"The following partitions were not deleted because they are in use:\n" +"\n" +"%s" +msgstr "" +"Die folgenden Partitionen wurden nicht entfert, weil sie in Verwendung " +"sind:\n" +"\n" +"%s" + +#: ../partIntfHelpers.py:222 ../partIntfHelpers.py:238 +#: ../partIntfHelpers.py:249 +msgid "Unable To Edit" +msgstr "" + +#: ../partIntfHelpers.py:223 +msgid "You must select a partition to edit" +msgstr "Sie mÃŒssen eine Partition auswÀhlen um diese zu editieren" + +#: ../partIntfHelpers.py:239 +#, python-format +msgid "" +"You cannot edit this partition, as it is an extended partition which " +"contains %s" +msgstr "" + +#: ../partIntfHelpers.py:250 +msgid "" +"You cannot edit this partition:\n" +"\n" +msgstr "" + +#: ../partIntfHelpers.py:272 +msgid "Format as Swap?" +msgstr "Als Swap formatieren?" + +#: ../partIntfHelpers.py:273 +#, python-format +msgid "" +"/dev/%s has a partition type of 0x82 (Linux swap) but does not appear to be " +"formatted as a Linux swap partition.\n" +"\n" +"Would you like to format this partition as a swap partition?" +msgstr "" + +#: ../partIntfHelpers.py:288 +#, python-format +msgid "You need to select at least one hard drive to install %s." +msgstr "" + +#: ../partIntfHelpers.py:293 +msgid "" +"You have chosen to use a pre-existing partition for this installation " +"without formatting it. We recommend that you format this partition to make " +"sure files from a previous operating system installation do not cause " +"problems with this installation of Linux. However, if this partition " +"contains files that you need to keep, such as home directories, then " +"continue without formatting this partition." +msgstr "" + +#: ../partIntfHelpers.py:301 +msgid "Format?" +msgstr "Formatieren?" + +#: ../partIntfHelpers.py:302 +msgid "_Modify Partition" +msgstr "_Bearbeite Partition" + +#: ../partIntfHelpers.py:302 +msgid "Do _Not Format" +msgstr "_Nicht formatieren" + +#: ../partIntfHelpers.py:311 +msgid "Error with Partitioning" +msgstr "" + +#: ../partIntfHelpers.py:312 +#, python-format +msgid "" +"The following critical errors exist with your requested partitioning scheme. " +"These errors must be corrected prior to continuing with your install of %s.\n" +"\n" +"%s" +msgstr "" + +#: ../partIntfHelpers.py:326 +msgid "Partitioning Warning" +msgstr "Partitionierungswarnung" + +#: ../partIntfHelpers.py:327 +#, python-format +msgid "" +"The following warnings exist with your requested partition scheme.\n" +"\n" +"%s\n" +"\n" +"Would you like to continue with your requested partitioning scheme?" +msgstr "" + +#: ../partIntfHelpers.py:340 +msgid "" +"The following pre-existing partitions have been selected to be formatted, " +"destroying all data." +msgstr "" + +#: ../partIntfHelpers.py:342 +msgid "" +"Select 'Yes' to continue and format these partitions, or 'No' to go back and " +"change these settings." +msgstr "" + +#: ../partIntfHelpers.py:348 +msgid "Format Warning" +msgstr "Formatierungswarnung" + +#: ../partIntfHelpers.py:387 +#, python-format +msgid "You are about to delete the /dev/%s partition." +msgstr "Sie sind dabei die Partition /dev/%s zu löschen." + +#: ../partIntfHelpers.py:389 +msgid "The partition you selected will be deleted." +msgstr "Die ausgewÀhlte Partition wird gelöscht." + +#: ../partIntfHelpers.py:398 +msgid "Confirm Reset" +msgstr "" + +#: ../partIntfHelpers.py:399 +msgid "" +"Are you sure you want to reset the partition table to its original state?" +msgstr "" + +#: ../partitioning.py:36 +msgid "Installation cannot continue." +msgstr "" + +#: ../partitioning.py:37 +msgid "" +"The partitioning options you have chosen have already been activated. You " +"can no longer return to the disk editing screen. Would you like to continue " +"with the installation process?" +msgstr "" + +#: ../partitioning.py:65 +msgid "Low Memory" +msgstr "Wenig Arbeitsspeicher" + +#: ../partitioning.py:66 +msgid "" +"As you don't have much memory in this machine, we need to turn on swap space " +"immediately. To do this we'll have to write your new partition table to the " +"disk immediately. Is that OK?" +msgstr "" +"Da sich in dem System nicht ausreichend Arbeitsspeicher befindet ist es " +"nötig den Swap sofort zu aktivieren. Dazu muss die neue Partitionstabelle " +"jetzt geschrieben werden. Ist das OK?" + +#: ../partitions.py:311 +#, python-format +msgid "" +"You have not defined a root partition (/), which is required for " +"installation of %s to continue." +msgstr "" +"Sie haben keine Root-Partition (/) angegeben, welche jedoch fÃŒr die " +"Installation von %s notwendig ist." + +#: ../partitions.py:316 +#, python-format +msgid "" +"Your root partition is less than 250 megabytes which is usually too small to " +"install %s." +msgstr "" + +#: ../partitions.py:333 +msgid "" +"Your boot partition isn't on one of the first four partitions and thus won't " +"be bootable." +msgstr "" +"Ihre Boot-Partition ist nicht eine der ersten vier Partitionen auf dem " +"DatentrÀger und wird daher nicht bootbar sein." + +#: ../partitions.py:342 +#, python-format +msgid "" +"Your %s partition is less than %s megabytes which is lower than recommended " +"for a normal %s install." +msgstr "" +"Ihre %s-Partition ist kleiner als %s Megabytes, was fÃŒr eine normale " +"Installation von %s nicht empfohlen ist." + +#: ../partitions.py:374 +msgid "" +"Installing on a USB device. This may or may not produce a working system." +msgstr "" +"Sie installieren auf einem USB-Laufwerk, was kein funktionierendes System " +"produzieren könnte." + +#: ../partitions.py:378 +msgid "" +"Installing on a FireWire device. This may or may not produce a working " +"system." +msgstr "" +"Sie installieren auf einem Firewire-Laufwerk, was kein funktionierendes " +"System produzieren könnte." + +#: ../partitions.py:391 +msgid "" +"You have not specified a swap partition. Although not strictly required in " +"all cases, it will significantly improve performance for most installations." +msgstr "Sie haben keine Swap-Partition angelegt." + +#: ../partitions.py:398 +#, python-format +msgid "" +"You have specified more than 32 swap devices. The kernel for %s only " +"supports 32 swap devices." +msgstr "" + +#: ../partitions.py:409 +#, python-format +msgid "" +"You have allocated less swap space (%dM) than available RAM (%dM) on your " +"system. This could negatively impact performance." +msgstr "" + +#: ../partitions.py:485 +msgid "the partition in use by the installer." +msgstr "" + +#: ../partRequests.py:182 +#, python-format +msgid "" +"This mount point is invalid. The %s directory must be on the / file system." +msgstr "" + +#: ../partRequests.py:185 +#, python-format +msgid "" +"The mount point %s cannot be used. It must be a symbolic link for proper " +"system operation. Please select a different mount point." +msgstr "" + +#: ../partRequests.py:192 +msgid "This mount point must be on a linux file system." +msgstr "" + +#: ../partRequests.py:212 +#, python-format +msgid "" +"The mount point "%s" is already in use, please choose a different mount " +"point." +msgstr "" + +#: ../partRequests.py:226 +#, python-format +msgid "" +"The size of the %s partition (%10.2f MB) exceeds the maximum size of %10.2f " +"MB." +msgstr "" + +#: ../partRequests.py:414 +#, python-format +msgid "" +"The size of the requested partition (size = %s MB) exceeds the maximum size " +"of %s MB." +msgstr "" + +#: ../partRequests.py:419 +#, python-format +msgid "The size of the requested partition is negative! (size = %s MB)" +msgstr "" + +#: ../partRequests.py:423 +msgid "Partitions can't start below the first cylinder." +msgstr "" + +#: ../partRequests.py:426 +msgid "Partitions can't end on a negative cylinder." +msgstr "" + +#: ../tui_bootloader.py:27 +msgid "Which boot loader would you like to use?" +msgstr "" + +#: ../tui_bootloader.py:37 +msgid "Use GRUB Boot Loader" +msgstr "" + +#: ../tui_bootloader.py:38 +msgid "No Boot Loader" +msgstr "" + +#: ../tui_bootloader.py:41 ../tui_bootloader.py:103 ../tui_bootloader.py:161 +#: ../tui_bootloader.py:278 ../tui_bootloader.py:383 +msgid "Boot Loader Configuration" +msgstr "" + +#: ../tui_bootloader.py:58 +msgid "Skip Boot Loader" +msgstr "" + +#: ../tui_bootloader.py:59 +msgid "" +"You have elected not to install any boot loader, which is not recommended " +"unless you have an advanced need. Booting your system into Linux directly " +"from the hard drive almost always requires a boot loader.\n" +"\n" +"Are you sure you want to skip boot loader installation?" +msgstr "" + +#: ../tui_bootloader.py:88 +msgid "" +"A few systems need to pass special options to the kernel at boot time to " +"function properly. If you need to pass boot options to the kernel, enter " +"them now. If you don't need any or aren't sure, leave this blank." +msgstr "" + +#: ../tui_bootloader.py:97 +msgid "Force use of LBA32 (not normally required)" +msgstr "" + +#: ../tui_bootloader.py:120 +msgid "" +"If LBA32 is not supported by your system's BIOS, forcing its use can prevent " +"your machine from booting.\n" +"\n" +"Would you like to continue and force LBA32 mode?" +msgstr "" + +#: ../tui_bootloader.py:162 +msgid "Where do you want to install the boot loader?" +msgstr "Wo möchten Sie den Bootloader installieren?" + +#: ../tui_bootloader.py:188 ../tui_bootloader.py:255 ../tui_partition.py:844 +msgid "Device" +msgstr "Partition" + +#: ../tui_bootloader.py:189 ../tui_bootloader.py:255 +msgid "Boot label" +msgstr "" + +#: ../tui_bootloader.py:193 +msgid "Clear" +msgstr "" + +#: ../tui_bootloader.py:201 +msgid "Edit Boot Label" +msgstr "" + +#: ../tui_bootloader.py:219 ../tui_bootloader.py:224 +msgid "Invalid Boot Label" +msgstr "UngÃŒltiges Label" + +#: ../tui_bootloader.py:220 +msgid "Boot label may not be empty." +msgstr "" + +#: ../tui_bootloader.py:225 +msgid "Boot label contains illegal characters." +msgstr "" + +#: ../tui_bootloader.py:255 +msgid "Default" +msgstr "Standard" + +#: ../tui_bootloader.py:273 +#, python-format +msgid "" +"The boot manager %s uses can boot other operating systems as well. Please " +"tell me what partitions you would like to be able to boot and what label you " +"want to use for each of them." +msgstr "" + +#: ../tui_bootloader.py:286 +msgid "" +" <Space> select | <F2> select default | <F4> delete | <F12> next screen>" +msgstr "<Leertaste>,<+>,<-> Auswahl | <F2> Laufwerk hinzufÃŒgen | <F12> Weiter" + +#: ../tui_bootloader.py:335 +msgid "Cannot Delete" +msgstr "Kann nicht löschen" + +#: ../tui_bootloader.py:336 +#, python-format +msgid "" +"This boot target cannot be deleted because it is for the %s system you are " +"about to install." +msgstr "" + +#: ../tui_bootloader.py:378 +msgid "" +"A boot loader password prevents users from passing arbitrary options to the " +"kernel. For highest security, you should set a password, but a password is " +"not necessary for more casual users." +msgstr "" + +#: ../tui_bootloader.py:386 +msgid "Use a GRUB Password" +msgstr "Benutze ein GRUB-Passwort" + +#: ../tui_bootloader.py:399 +msgid "Boot Loader Password:" +msgstr "Bootloader-Passwort:" + +#: ../tui_bootloader.py:400 +msgid "Confirm:" +msgstr "BestÀtigen:" + +#: ../tui_bootloader.py:429 +msgid "Passwords Do Not Match" +msgstr "Passwörter stimmen nicht ÃŒberein" + +#: ../tui_bootloader.py:430 +msgid "Passwords do not match" +msgstr "Die Passwörter stimmen nicht ÃŒberein" + +#: ../tui_bootloader.py:434 +msgid "Password Too Short" +msgstr "Das Passwort ist zu kurz" + +#: ../tui_bootloader.py:435 +msgid "Boot loader password is too short" +msgstr "Das Bootloader-Passwort ist zu kurz" + +#: ../tui_bootloader.py:440 +msgid "" +"Your boot loader password is shorter than six characters. We recommend a " +"longer boot loader password.\n" +"\n" +"Would you like to continue with this password?" +msgstr "" +"Ihr Bootloader-Passwort ist kÃŒrzer als 6 Zeichen. Wir empfehlen einen " +"lÀngeren SchlÃŒssel zu nehmen.\n" +"\n" +"Möchten Sie trotzdem mit dem eingegebenen Passwort fortfahren?" + +#: ../tui_complete.py:25 +msgid "" +"Press <Enter> to end the installation process.\n" +"\n" +msgstr "" +"DrÃŒcken Sie <Enter> um den Installationprozess zu beenden.\n" +"\n" + +#: ../tui_complete.py:26 +msgid "<Enter> to exit" +msgstr "<Enter> zum Beenden" + +#: ../tui_complete.py:30 +#, python-format +msgid "" +"Congratulations, your %s installation is complete.\n" +"\n" +"%s%s" +msgstr "" +"Herzlichen GlÃŒckwunsch, die Installation von %s wurde erfolgreich beendet.\n" +"\n" +"%s%s" + +#: ../tui_complete.py:33 +#, python-format +msgid "" +"For information on errata (updates and bug fixes), visit %s.\n" +"\n" +"Information on using your system is available in the %s wiki at %s." +msgstr "" +"FÃŒr weitere Informationen ÃŒber Bugfixes besuchen Sie %s.\n" +"\n" +"Informationen ÃŒber das System erhalten Sie im %s-Wiki auf %s." + +#: ../tui_complete.py:39 +msgid "Complete" +msgstr "Fertig" + +#: ../tui_confirm.py:23 +msgid "Installation to begin" +msgstr "" + +#: ../tui_confirm.py:24 +msgid "" +"Now, we got all information we need for installation. If there is something " +"you want change you can still go back. If not choose OK to start." +msgstr "" + +#: ../tui_confirm.py:34 +msgid "Reboot?" +msgstr "Neustarten?" + +#: ../tui_confirm.py:35 +msgid "The system will be rebooted now." +msgstr "Ihr System wird jetzt neu gestartet." + +#: ../tui_keyboard.py:36 +msgid "Keyboard Selection" +msgstr "Tastaturauswahl" + +#: ../tui_keyboard.py:37 +msgid "Which model keyboard is attached to this computer?" +msgstr "Welches Tastaturmodell ist an den Computer angeschlossen?" + +#: ../tui_language.py:39 +msgid "Language Selection" +msgstr "Sprachauswahl" + +#: ../tui_language.py:40 +msgid "What language would you like to use during the installation process?" +msgstr "Welche Sprache möchten Sie fÃŒr den Installationsprozess nutzen?" + +#: ../tui_network.py:39 +msgid "Hostname" +msgstr "Hostname" + +#: ../tui_network.py:42 +msgid "" +"Please name this computer. The hostname identifies the computer on a " +"network." +msgstr "" + +#: ../tui_network.py:63 ../tui_network.py:70 +msgid "Invalid Hostname" +msgstr "UngÃŒltiger Hostname" + +#: ../tui_network.py:64 +msgid "You have not specified a hostname." +msgstr "Sie haben keinen Hostnamen eingegeben." + +#: ../tui_network.py:71 +#, python-format +msgid "" +"The hostname "%s" is not valid for the following reason:\n" +"\n" +"%s" +msgstr "" + +#: ../tui_partition.py:41 +msgid "Must specify a value" +msgstr "Bitte geben Sie einen Wert ein" + +#: ../tui_partition.py:44 +msgid "Requested value is not an integer" +msgstr "Der eingegebene Wert ist kein Integer" + +#: ../tui_partition.py:46 +msgid "Requested value is too large" +msgstr "Der eingegebene Wert ist zu groÃ" + +#: ../tui_partition.py:95 ../tui_partition.py:132 +msgid "Free space" +msgstr "Freier Platz" + +#: ../tui_partition.py:97 +msgid "Extended" +msgstr "Erweitert" + +#: ../tui_partition.py:111 +msgid "None" +msgstr "Keins" + +#: ../tui_partition.py:178 +#, python-format +msgid "Could not allocate requested partitions: %s." +msgstr "Konnte die Partition nicht finden: %s." + +#: ../tui_partition.py:182 +#, python-format +msgid "Warning: %s" +msgstr "Warnung: %s" + +#: ../tui_partition.py:183 +msgid "Modify Partition" +msgstr "Partition bearbeiten" + +#: ../tui_partition.py:183 +msgid "Add anyway" +msgstr "Trotzdem hinzufÃŒgen" + +#: ../tui_partition.py:201 ../tui_partition.py:203 ../tui_partition.py:205 +#: ../tui_partition.py:230 +msgid "<Not Applicable>" +msgstr "<Nicht verfÃŒgbar>" + +#: ../tui_partition.py:220 +msgid "Mount Point:" +msgstr "EinhÀngepunkt:" + +#: ../tui_partition.py:239 +msgid "File System type:" +msgstr "Dateisystem-Typ:" + +#: ../tui_partition.py:270 +msgid "Allowable Drives:" +msgstr "" + +#: ../tui_partition.py:292 ../tui_partition.py:371 ../tui_partition.py:419 +msgid "Size (MB):" +msgstr "GröÃe (MB):" + +#: ../tui_partition.py:324 +msgid "Fixed Size:" +msgstr "Feste GröÃe:" + +#: ../tui_partition.py:326 +msgid "Fill maximum size of (MB):" +msgstr "Maximale GröÃe in MB:" + +#: ../tui_partition.py:330 +msgid "Fill all available space:" +msgstr "VerfÃŒgbaren Speicherplatz ausfÃŒllen:" + +#: ../tui_partition.py:351 +msgid "Start Cylinder:" +msgstr "Startzylinder:" + +#: ../tui_partition.py:364 +msgid "End Cylinder:" +msgstr "Endzylinder:" + +#: ../tui_partition.py:386 +msgid "Number of spares?" +msgstr "" + +#: ../tui_partition.py:400 +msgid "File System Type:" +msgstr "Dateisystem:" + +#: ../tui_partition.py:413 +msgid "File System Label:" +msgstr "Dateisystemlabel:" + +#: ../tui_partition.py:424 +msgid "File System Option:" +msgstr "Dateisystemoption:" + +#: ../tui_partition.py:427 ../tui_partition.py:652 +#, python-format +msgid "Format as %s" +msgstr "Formatieren als %s" + +#: ../tui_partition.py:429 ../tui_partition.py:654 +#, python-format +msgid "Migrate to %s" +msgstr "Migrieren zu %s" + +#: ../tui_partition.py:431 ../tui_partition.py:656 +msgid "Leave unchanged" +msgstr "Beibehalten" + +#: ../tui_partition.py:446 ../tui_partition.py:629 +msgid "File System Options" +msgstr "Dateisystemoptionen" + +#: ../tui_partition.py:449 +msgid "" +"Please choose how you would like to prepare the file system on this " +"partition." +msgstr "" +"Bitte wÀhlen Sie, wie sie das Dateisystem fÃŒr diese Partition vorbereiten " +"wollen." + +#: ../tui_partition.py:457 ../tui_partition.py:607 +msgid "Check for bad blocks" +msgstr "Untersuche nach defekten Blöcken" + +#: ../tui_partition.py:461 +msgid "Leave unchanged (preserve data)" +msgstr "Beibehalten (erhÀlt die Daten)" + +#: ../tui_partition.py:470 +msgid "Format as:" +msgstr "Formatieren als:" + +#: ../tui_partition.py:489 +msgid "Migrate to:" +msgstr "Migrieren nach:" + +#: ../tui_partition.py:559 +msgid "Add Partition" +msgstr "Partition hinzufÃŒgen" + +#: ../tui_partition.py:601 +msgid "Force to be a primary partition" +msgstr "Erzwinge primÀre Partition" + +#: ../tui_partition.py:684 ../tui_partition.py:738 +msgid "Invalid Entry for Partition Size" +msgstr "UngÃŒltige Eingabe fÃŒr die PartitionsgröÃe" + +#: ../tui_partition.py:696 +msgid "Invalid Entry for Maximum Size" +msgstr "UngÃŒltige Eingabe fÃŒr die maximale GröÃe" + +#: ../tui_partition.py:716 +msgid "Invalid Entry for Starting Cylinder" +msgstr "UngÃŒltige Eingabe fÃŒr den Startzylinder" + +#: ../tui_partition.py:730 +msgid "Invalid Entry for End Cylinder" +msgstr "UngÃŒltige Eingabe fÃŒr den Endzylinder" + +#: ../tui_partition.py:748 ../tui_partition.py:769 +msgid "Error With Request" +msgstr "Fehler im Request" + +#: ../tui_partition.py:838 +msgid "Partitioning" +msgstr "Partitionierung" + +#: ../tui_partition.py:844 +msgid "Start" +msgstr "Startsektor" + +#: ../tui_partition.py:844 +msgid "End" +msgstr "Endsektor" + +#: ../tui_partition.py:844 +msgid "Size" +msgstr "GröÃe" + +#: ../tui_partition.py:844 +msgid "Type" +msgstr "Typ" + +#: ../tui_partition.py:844 +msgid "Mount Point" +msgstr "Mount-Point" + +#: ../tui_partition.py:848 +msgid "New" +msgstr "Neu" + +#: ../tui_partition.py:850 +msgid "Delete" +msgstr "Löschen" + +#: ../tui_partition.py:853 +msgid "" +" F1-Help F2-New F3-Edit F4-Delete F5-Reset F12-OK " +msgstr " F1-Hilfe F2-Neu F3-Bearbeiten F4-Löschen F5-ZurÃŒcksetzen F12-OK" + +#: ../tui_partition.py:883 +msgid "No Root Partition" +msgstr "Keine Root-Partition" + +#: ../tui_partition.py:884 +msgid "Installation requires a / partition." +msgstr "Die Installation erfordert die Konfiguration einer /-Partition." + +#: ../tui_partition.py:923 +msgid "Partitioning Type" +msgstr "Partitionstyp" + +#: ../tui_partition.py:925 +msgid "" +"Installation requires partitioning of your hard drive. The default layout " +"is reasonable for most users. You can either choose to use this or create " +"your own." +msgstr "" +"FÃŒr die Installation ist es nötig die Festplatten passend zu partitionieren. " +"Das Standardlayout genÃŒgt fÃŒr die meisten Nutzer. Experten können eigene " +"Anpassungen vornehmen." + +#: ../tui_partition.py:932 +msgid "Remove all partitions on selected drives and create default layout" +msgstr "Alle Partitionen löschen und Standardlayout erstellen" + +#: ../tui_partition.py:933 +msgid "Create custom layout" +msgstr "Benutzerdefiniertes Layout erstellen" + +#: ../tui_partition.py:947 +msgid "Which drive(s) do you want to use for this installation?" +msgstr "Welche(s) Laufwerk(e) möchten Sie fÃŒr die Installation nutzen?" + +#: ../tui_partition.py:960 +msgid "<Space>,<+>,<-> selection | <F2> Add drive | <F12> next screen" +msgstr "<Leertaste>,<+>,<-> Auswahl | <F2> Laufwerk hinzufÃŒgen | <F12> Weiter" + +#: ../tui_partition.py:1029 +msgid "Review Partition Layout" +msgstr "Ansicht des Partitionslayout" + +#: ../tui_partition.py:1030 +msgid "Review and modify partitioning layout?" +msgstr "Möchten Sie das Partitionslayout ansehen oder bearbeiten?"